diff --git a/format.c b/format.c index 98fc55d2..da939f04 100644 --- a/format.c +++ b/format.c @@ -34,9 +34,10 @@ * string. */ -int format_replace(struct format_tree *, const char *, size_t, char **, - size_t *, size_t *); -void format_window_pane_tabs(struct format_tree *, struct window_pane *); +int format_replace(struct format_tree *, const char *, size_t, char **, + size_t *, size_t *); +char *format_get_command(struct window_pane *); +void format_window_pane_tabs(struct format_tree *, struct window_pane *); /* Format key-value replacement entry. */ RB_GENERATE(format_tree, format_entry, entry, format_cmp); @@ -348,6 +349,21 @@ format_expand(struct format_tree *ft, const char *fmt) return (buf); } +/* Get command name for format. */ +char * +format_get_command(struct window_pane *wp) +{ + char *cmd; + + cmd = osdep_get_name(wp->fd, wp->tty); + if (cmd == NULL || *cmd == '\0') { + cmd = wp->cmd; + if (cmd == NULL || *cmd == '\0') + cmd = wp->shell; + } + return (parse_window_name(cmd)); +} + /* Set default format keys for a session. */ void format_session(struct format_tree *ft, struct session *s) @@ -427,25 +443,38 @@ format_client(struct format_tree *ft, struct client *c) format_add(ft, "client_last_session", "%s", s->name); } +/* Set default format keys for a window. */ +void +format_window(struct format_tree *ft, struct window *w) +{ + char *layout; + + layout = layout_dump(w); + + format_add(ft, "window_id", "@%u", w->id); + format_add(ft, "window_name", "%s", w->name); + format_add(ft, "window_width", "%u", w->sx); + format_add(ft, "window_height", "%u", w->sy); + format_add(ft, "window_layout", "%s", layout); + format_add(ft, "window_panes", "%u", window_count_panes(w)); + + free(layout); +} + /* Set default format keys for a winlink. */ void format_winlink(struct format_tree *ft, struct session *s, struct winlink *wl) { struct window *w = wl->window; - char *layout, *flags; + char *flags; - layout = layout_dump(w); flags = window_printable_flags(s, wl); - format_add(ft, "window_id", "@%u", w->id); + format_window(ft, w); + format_add(ft, "window_index", "%d", wl->idx); - format_add(ft, "window_name", "%s", w->name); - format_add(ft, "window_width", "%u", w->sx); - format_add(ft, "window_height", "%u", w->sy); format_add(ft, "window_flags", "%s", flags); - format_add(ft, "window_layout", "%s", layout); format_add(ft, "window_active", "%d", wl == s->curw); - format_add(ft, "window_panes", "%u", window_count_panes(w)); format_add(ft, "window_bell_flag", "%u", !!(wl->flags & WINLINK_BELL)); @@ -456,8 +485,8 @@ format_winlink(struct format_tree *ft, struct session *s, struct winlink *wl) format_add(ft, "window_silence_flag", "%u", !!(wl->flags & WINLINK_SILENCE)); + free(flags); - free(layout); } /* Add window pane tabs. */ @@ -527,7 +556,7 @@ format_window_pane(struct format_tree *ft, struct window_pane *wp) format_add(ft, "pane_start_path", "%s", wp->cwd); if ((cwd = osdep_get_cwd(wp->fd)) != NULL) format_add(ft, "pane_current_path", "%s", cwd); - if ((cmd = osdep_get_name(wp->fd, wp->tty)) != NULL) { + if ((cmd = format_get_command(wp)) != NULL) { format_add(ft, "pane_current_command", "%s", cmd); free(cmd); } diff --git a/names.c b/names.c index f536d2fc..7c02961c 100644 --- a/names.c +++ b/names.c @@ -22,12 +22,10 @@ #include #include #include -#include #include "tmux.h" void window_name_callback(unused int, unused short, void *); -char *parse_window_name(const char *); void queue_window_name(struct window *w) @@ -47,7 +45,7 @@ void window_name_callback(unused int fd, unused short events, void *data) { struct window *w = data; - char *name, *wname; + char *name; if (w->active == NULL) return; @@ -59,49 +57,39 @@ window_name_callback(unused int fd, unused short events, void *data) } queue_window_name(w); - if (w->active->screen != &w->active->base) - name = NULL; - else - name = osdep_get_name(w->active->fd, w->active->tty); - if (name == NULL) - wname = default_window_name(w); - else { - /* - * If tmux is using the default command, it will be a login - * shell and argv[0] may have a - prefix. Remove this if it is - * present. Ick. - */ - if (w->active->cmd != NULL && *w->active->cmd == '\0' && - name != NULL && name[0] == '-' && name[1] != '\0') - wname = parse_window_name(name + 1); - else - wname = parse_window_name(name); - free(name); - } - - if (w->active->fd == -1) { - xasprintf(&name, "%s[dead]", wname); - free(wname); - wname = name; - } - - if (strcmp(wname, w->name)) { - window_set_name(w, wname); + name = format_window_name(w); + if (strcmp(name, w->name) != 0) { + window_set_name(w, name); server_status_window(w); } - free(wname); + free(name); } char * default_window_name(struct window *w) { - if (w->active->screen != &w->active->base) - return (xstrdup("[tmux]")); if (w->active->cmd != NULL && *w->active->cmd != '\0') return (parse_window_name(w->active->cmd)); return (parse_window_name(w->active->shell)); } +char * +format_window_name(struct window *w) +{ + struct format_tree *ft; + char *fmt, *name; + + ft = format_create(); + format_window(ft, w); + format_window_pane(ft, w->active); + + fmt = options_get_string(&w->options, "automatic-rename-format"); + name = format_expand(ft, fmt); + + format_free(ft); + return (name); +} + char * parse_window_name(const char *in) { @@ -111,7 +99,7 @@ parse_window_name(const char *in) if (strncmp(name, "exec ", (sizeof "exec ") - 1) == 0) name = name + (sizeof "exec ") - 1; - while (*name == ' ') + while (*name == ' ' || *name == '-') name++; if ((ptr = strchr(name, ' ')) != NULL) *ptr = '\0'; diff --git a/options-table.c b/options-table.c index 0b86ef7c..f6a15472 100644 --- a/options-table.c +++ b/options-table.c @@ -481,6 +481,11 @@ const struct options_table_entry window_options_table[] = { .default_num = 1 }, + { .name = "automatic-rename-format", + .type = OPTIONS_TABLE_STRING, + .default_str = "#{?pane_in_mode,[tmux],#{pane_current_command}}#{?pane_dead,[dead],}" + }, + { .name = "c0-change-trigger", .type = OPTIONS_TABLE_NUMBER, .default_num = 250, diff --git a/tmux.1 b/tmux.1 index 19ae4a9b..c93f4d97 100644 --- a/tmux.1 +++ b/tmux.1 @@ -2710,8 +2710,8 @@ The default is on. Control automatic window renaming. When this setting is enabled, .Nm -will attempt - on supported platforms - to rename the window to reflect the -command currently running in it. +will rename the window automatically using the format specified by +.Ic automatic-rename-format . This flag is automatically disabled for an individual window when a name is specified at creation with .Ic new-window @@ -2725,6 +2725,13 @@ It may be switched off globally with: set-window-option -g automatic-rename off .Ed .Pp +.It Ic automatic-rename-format Ar format +The format (see +.Sx FORMATS ) +used when the +.Ic automatic-rename +option is enabled. +.Pp .It Ic c0-change-interval Ar interval .It Ic c0-change-trigger Ar trigger These two options configure a simple form of rate limiting for a pane. diff --git a/tmux.h b/tmux.h index 1cb5cd8e..6ab9861b 100644 --- a/tmux.h +++ b/tmux.h @@ -1549,16 +1549,19 @@ int format_cmp(struct format_entry *, struct format_entry *); RB_PROTOTYPE(format_tree, format_entry, entry, format_cmp); struct format_tree *format_create(void); void format_free(struct format_tree *); -void printflike3 format_add( - struct format_tree *, const char *, const char *, ...); +void printflike3 format_add(struct format_tree *, const char *, const char *, + ...); const char *format_find(struct format_tree *, const char *); char *format_expand(struct format_tree *, const char *); void format_session(struct format_tree *, struct session *); void format_client(struct format_tree *, struct client *); -void format_winlink( - struct format_tree *, struct session *, struct winlink *); -void format_window_pane(struct format_tree *, struct window_pane *); -void format_paste_buffer(struct format_tree *, struct paste_buffer *); +void format_window(struct format_tree *, struct window *); +void format_winlink(struct format_tree *, struct session *, + struct winlink *); +void format_window_pane(struct format_tree *, + struct window_pane *); +void format_paste_buffer(struct format_tree *, + struct paste_buffer *); /* mode-key.c */ extern const struct mode_key_table mode_key_tables[]; @@ -2272,8 +2275,10 @@ void window_choose_collapse_all(struct window_pane *); void window_choose_set_current(struct window_pane *, u_int); /* names.c */ -void queue_window_name(struct window *); -char *default_window_name(struct window *); +void queue_window_name(struct window *); +char *default_window_name(struct window *); +char *format_window_name(struct window *); +char *parse_window_name(const char *); /* signal.c */ void set_signals(void(*)(int, short, void *));