diff --git a/cfg.c b/cfg.c index eb46bd94..5e3e47e9 100644 --- a/cfg.c +++ b/cfg.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -78,8 +79,8 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes) { FILE *f; u_int n; - char *buf, *line, *cause; - size_t len, newlen; + char *buf, *copy, *line, *cause; + size_t len, oldlen; struct cmd_list *cmdlist; struct cmd_ctx ctx; enum cmd_retval retval; @@ -95,21 +96,23 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes) line = NULL; retval = CMD_RETURN_NORMAL; while ((buf = fgetln(f, &len))) { + /* Trim \n. */ if (buf[len - 1] == '\n') len--; + log_debug ("%s: %s", path, buf); /* Current line is the continuation of the previous one. */ if (line != NULL) { - newlen = strlen(line) + len + 1; - line = xrealloc(line, 1, newlen); + oldlen = strlen(line); + line = xrealloc(line, 1, oldlen + len + 1); } else { - newlen = len + 1; - line = xmalloc(newlen); - *line = '\0'; + oldlen = 0; + line = xmalloc(len + 1); } /* Append current line to the previous. */ - strlcat(line, buf, newlen); + memcpy(line + oldlen, buf, len); + line[oldlen + len] = '\0'; n++; /* Continuation: get next line? */ @@ -121,18 +124,25 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes) if (len > 1 && line[len - 2] != '\\') continue; } - buf = line; + copy = line; line = NULL; + /* Skip empty lines. */ + buf = copy; + while (isspace((u_char)*buf)) + buf++; + if (*buf == '\0') + continue; + if (cmd_string_parse(buf, &cmdlist, &cause) != 0) { - free(buf); + free(copy); if (cause == NULL) continue; cfg_add_cause(causes, "%s: %u: %s", path, n, cause); free(cause); continue; } - free(buf); + free(copy); if (cmdlist == NULL) continue; diff --git a/cmd-capture-pane.c b/cmd-capture-pane.c index a94c7177..adb827bb 100644 --- a/cmd-capture-pane.c +++ b/cmd-capture-pane.c @@ -32,7 +32,8 @@ enum cmd_retval cmd_capture_pane_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_capture_pane_entry = { "capture-pane", "capturep", "b:E:S:t:", 0, 0, - "[-b buffer-index] [-E end-line] [-S start-line] [-t target-pane]", + "[-b buffer-index] [-E end-line] [-S start-line] " + CMD_TARGET_PANE_USAGE, 0, NULL, NULL, diff --git a/cmd-choose-tree.c b/cmd-choose-tree.c index e8da7a42..4432ff7e 100644 --- a/cmd-choose-tree.c +++ b/cmd-choose-tree.c @@ -39,8 +39,8 @@ void cmd_choose_tree_free(struct window_choose_data *); const struct cmd_entry cmd_choose_tree_entry = { "choose-tree", NULL, - "S:W:swb:c:t:", 0, 1, - "[-sw] [-b session-template] [-c window template] [-S format] " \ + "S:W:swub:c:t:", 0, 1, + "[-swu] [-b session-template] [-c window template] [-S format] " \ "[-W format] " CMD_TARGET_WINDOW_USAGE, 0, NULL, @@ -232,6 +232,9 @@ windows_only: window_choose_ready(wl->window->active, cur_win, cmd_choose_tree_callback, cmd_choose_tree_free); + if (args_has(args, 'u')) + window_choose_expand_all(wl->window->active); + return (CMD_RETURN_NORMAL); } diff --git a/cmd-display-message.c b/cmd-display-message.c index e31c110f..244c557c 100644 --- a/cmd-display-message.c +++ b/cmd-display-message.c @@ -32,7 +32,8 @@ enum cmd_retval cmd_display_message_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_display_message_entry = { "display-message", "display", "c:pt:F:", 0, 1, - "[-p] [-c target-client] [-t target-pane] [-F format] [message]", + "[-p] [-c target-client] [-F format] " CMD_TARGET_PANE_USAGE + " [message]", 0, NULL, NULL, diff --git a/cmd-list-panes.c b/cmd-list-panes.c index 0934645f..4ce25a44 100644 --- a/cmd-list-panes.c +++ b/cmd-list-panes.c @@ -38,7 +38,7 @@ void cmd_list_panes_window(struct cmd *, const struct cmd_entry cmd_list_panes_entry = { "list-panes", "lsp", "asF:t:", 0, 0, - "[-as] [-F format] [-t target]", + "[-as] [-F format] " CMD_TARGET_WINDOW_USAGE, 0, NULL, NULL, diff --git a/cmd-new-session.c b/cmd-new-session.c index 93cf945a..bb4cdcac 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -36,8 +36,8 @@ enum cmd_retval cmd_new_session_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_new_session_entry = { "new-session", "new", "dn:s:t:x:y:", 0, 1, - "[-d] [-n window-name] [-s session-name] [-t target-session] " - "[-x width] [-y height] [command]", + "[-d] [-n window-name] [-s session-name] " CMD_TARGET_SESSION_USAGE + " [-x width] [-y height] [command]", CMD_STARTSERVER|CMD_CANTNEST|CMD_SENDENVIRON, NULL, cmd_new_session_check, diff --git a/cmd-new-window.c b/cmd-new-window.c index f8a76120..d8c576af 100644 --- a/cmd-new-window.c +++ b/cmd-new-window.c @@ -32,7 +32,7 @@ const struct cmd_entry cmd_new_window_entry = { "new-window", "neww", "ac:dF:kn:Pt:", 0, 1, "[-adkP] [-c start-directory] [-F format] [-n window-name] " - "[-t target-window] [command]", + CMD_TARGET_WINDOW_USAGE " [command]", 0, NULL, NULL, diff --git a/cmd-paste-buffer.c b/cmd-paste-buffer.c index 4718d85a..05bee5c7 100644 --- a/cmd-paste-buffer.c +++ b/cmd-paste-buffer.c @@ -35,7 +35,7 @@ void cmd_paste_buffer_filter(struct window_pane *, const struct cmd_entry cmd_paste_buffer_entry = { "paste-buffer", "pasteb", "db:prs:t:", 0, 0, - "[-dpr] [-s separator] [-b buffer-index] [-t target-pane]", + "[-dpr] [-s separator] [-b buffer-index] " CMD_TARGET_PANE_USAGE, 0, NULL, NULL, diff --git a/cmd-select-window.c b/cmd-select-window.c index 5d87e59a..aecb5b5a 100644 --- a/cmd-select-window.c +++ b/cmd-select-window.c @@ -31,8 +31,8 @@ enum cmd_retval cmd_select_window_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_select_window_entry = { "select-window", "selectw", - "lnpt:", 0, 0, - "[-lnp] " CMD_TARGET_WINDOW_USAGE, + "lnpTt:", 0, 0, + "[-lnpT] " CMD_TARGET_WINDOW_USAGE, 0, cmd_select_window_key_binding, NULL, @@ -130,7 +130,17 @@ cmd_select_window_exec(struct cmd *self, struct cmd_ctx *ctx) if (wl == NULL) return (CMD_RETURN_ERROR); - if (session_select(s, wl->idx) == 0) + /* + * If -T and select-window is invoked on same window as + * current, switch to previous window. + */ + if (args_has(self->args, 'T') && wl == s->curw) { + if (session_last(s) != 0) { + ctx->error(ctx, "no last window"); + return (-1); + } + server_redraw_session(s); + } else if (session_select(s, wl->idx) == 0) server_redraw_session(s); } recalculate_sizes(); diff --git a/cmd-send-keys.c b/cmd-send-keys.c index ec1007b1..e19ca3b0 100644 --- a/cmd-send-keys.c +++ b/cmd-send-keys.c @@ -32,7 +32,7 @@ enum cmd_retval cmd_send_keys_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_send_keys_entry = { "send-keys", "send", "lRt:", 0, -1, - "[-lR] [-t target-pane] key ...", + "[-lR] " CMD_TARGET_PANE_USAGE " key ...", 0, NULL, NULL, diff --git a/cmd-split-window.c b/cmd-split-window.c index b40b574b..cac8095e 100644 --- a/cmd-split-window.c +++ b/cmd-split-window.c @@ -34,7 +34,7 @@ const struct cmd_entry cmd_split_window_entry = { "split-window", "splitw", "c:dF:l:hp:Pt:v", 0, 1, "[-dhvP] [-c start-directory] [-F format] [-p percentage|-l size] " - "[-t target-pane] [command]", + CMD_TARGET_PANE_USAGE " [command]", 0, cmd_split_window_key_binding, NULL, diff --git a/cmd.c b/cmd.c index 79ac3386..775e1213 100644 --- a/cmd.c +++ b/cmd.c @@ -862,6 +862,10 @@ cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp) wl = s->curw; else if (winptr[0] == '!' && winptr[1] == '\0') wl = TAILQ_FIRST(&s->lastw); + else if (winptr[0] == '^' && winptr[1] == '\0') + wl = RB_MIN(winlinks, &s->windows); + else if (winptr[0] == '$' && winptr[1] == '\0') + wl = RB_MAX(winlinks, &s->windows); else if (winptr[0] == '+' || winptr[0] == '-') wl = cmd_find_window_offset(winptr, s, &ambiguous); else diff --git a/osdep-openbsd.c b/osdep-openbsd.c index 9eee984f..7be38a91 100644 --- a/osdep-openbsd.c +++ b/osdep-openbsd.c @@ -17,6 +17,7 @@ */ #include +#include #include #include diff --git a/tmux.1 b/tmux.1 index 499a924d..bd560444 100644 --- a/tmux.1 +++ b/tmux.1 @@ -412,11 +412,15 @@ otherwise the current window in is chosen. The special character .Ql \&! -uses the last (previously current) window, or +uses the last (previously current) window, +.Ql ^ +selects the highest numbered window, +.Ql $ +selects the lowest numbered window, and .Ql + and .Ql - -are the next window or the previous window by number. +select the next window or the previous window by number. When the argument does not contain a colon, .Nm first attempts to parse it as window; if that fails, an attempt is made to @@ -1130,6 +1134,7 @@ This command works only from inside .Ic choose-tree .Op Fl s .Op Fl w +.Op Fl u .Op Fl b Ar session-template .Op Fl c Ar window-template .Op Fl S Ar format @@ -1155,6 +1160,9 @@ If .Fl w is given, will show windows. If +.Fl u +is given, the tree is uncollapsed by default. +If .Fl b is given, will override the default session command. Note that @@ -1643,7 +1651,7 @@ is the same as using the .Ic last-pane command. .It Xo Ic select-window -.Op Fl lnp +.Op Fl lnpT .Op Fl t Ar target-window .Xc .D1 (alias: Ic selectw ) @@ -1659,6 +1667,11 @@ are equivalent to the and .Ic previous-window commands. +If +.Fl T +is given and the selected window is already the current window, +the command behaves like +.Ic last-window . .It Xo Ic split-window .Op Fl dhvP .Op Fl c Ar start-directory diff --git a/tmux.h b/tmux.h index 960d1307..ae98801a 100644 --- a/tmux.h +++ b/tmux.h @@ -2239,6 +2239,7 @@ struct window_choose_data *window_choose_add_session(struct window_pane *, struct window_choose_data *window_choose_add_item(struct window_pane *, struct cmd_ctx *, struct winlink *, const char *, char *, u_int); +void window_choose_expand_all(struct window_pane *); /* names.c */ void queue_window_name(struct window *); diff --git a/window-choose.c b/window-choose.c index 5bcca17c..df8cb3df 100644 --- a/window-choose.c +++ b/window-choose.c @@ -43,7 +43,6 @@ void window_choose_scroll_down(struct window_pane *); void window_choose_collapse(struct window_pane *, struct session *); void window_choose_expand(struct window_pane *, struct session *, u_int); void window_choose_collapse_all(struct window_pane *); -void window_choose_expand_all(struct window_pane *); enum window_choose_input_type { WINDOW_CHOOSE_NORMAL = -1, @@ -118,7 +117,6 @@ window_choose_ready(struct window_pane *wp, u_int cur, ARRAY_CONCAT(&data->old_list, &data->list); window_choose_collapse_all(wp); - window_choose_redraw_screen(wp); } struct screen *