From a1fc8f8b23bf6371877ff93e123b735d2c7d596d Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 9 Apr 2020 15:35:27 +0000 Subject: [PATCH 01/10] More style nits. --- format-draw.c | 2 +- format.c | 4 ++-- tmux.c | 2 +- window-tree.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/format-draw.c b/format-draw.c index 85248aa6..3ac33ce4 100644 --- a/format-draw.c +++ b/format-draw.c @@ -804,7 +804,7 @@ format_width(const char *expanded) if (cp[0] == '#' && cp[1] == '[') { end = format_skip(cp + 2, "]"); if (end == NULL) - return 0; + return (0); cp = end + 1; } else if ((more = utf8_open(&ud, *cp)) == UTF8_MORE) { while (*++cp != '\0' && more == UTF8_MORE) diff --git a/format.c b/format.c index 24710f15..efbf5c62 100644 --- a/format.c +++ b/format.c @@ -1617,7 +1617,7 @@ format_build_modifiers(struct format_tree *ft, const char **s, u_int *count) return (NULL); } *s = cp + 1; - return list; + return (list); } /* Match against an fnmatch(3) pattern or regular expression. */ @@ -1909,7 +1909,7 @@ format_replace_expression(struct format_modifier *mexp, struct format_tree *ft, free(right); free(left); - return value; + return (value); fail: free(right); diff --git a/tmux.c b/tmux.c index 2055a894..eac8c12f 100644 --- a/tmux.c +++ b/tmux.c @@ -224,7 +224,7 @@ getversion(void) fatalx("uname failed"); xasprintf(&version, "openbsd-%s", u.release); } - return version; + return (version); } int diff --git a/window-tree.c b/window-tree.c index 4d5b4a1e..d32358a5 100644 --- a/window-tree.c +++ b/window-tree.c @@ -833,7 +833,7 @@ window_tree_search(__unused void *modedata, void *itemdata, const char *ss) return (0); retval = (strstr(cmd, ss) != NULL); free(cmd); - return retval; + return (retval); } return (0); } From c0602f357d7b48ab830f93b446cb1830c5df7a0f Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 10 Apr 2020 07:44:26 +0000 Subject: [PATCH 02/10] Now that copy mode copies the pane content rather than keeping a reference to it, it isn't necessary that the pane in copy mode is the same as the one copying from. Add a -s flag to copy-mode to specify a different pane for the source content. This means it is possible to view two places in a pane's history at the same time in different panes, or copy from a pane's history into an editor or shell in the same pane. From Anindya Mukherjee. --- cfg.c | 2 +- cmd-choose-tree.c | 2 +- cmd-copy-mode.c | 15 ++++++++++----- cmd-find-window.c | 3 ++- cmd-queue.c | 6 ++++-- cmd-run-shell.c | 2 +- tmux.1 | 6 ++++++ tmux.h | 5 +++-- window-copy.c | 49 ++++++++++++++++++++++++++--------------------- window.c | 6 ++++-- 10 files changed, 59 insertions(+), 37 deletions(-) diff --git a/cfg.c b/cfg.c index 92c87225..6740bce4 100644 --- a/cfg.c +++ b/cfg.c @@ -284,7 +284,7 @@ cfg_show_causes(struct session *s) wme = TAILQ_FIRST(&wp->modes); if (wme == NULL || wme->mode != &window_view_mode) - window_pane_set_mode(wp, &window_view_mode, NULL, NULL); + window_pane_set_mode(wp, NULL, &window_view_mode, NULL, NULL); for (i = 0; i < cfg_ncauses; i++) { window_copy_add(wp, "%s", cfg_causes[i]); free(cfg_causes[i]); diff --git a/cmd-choose-tree.c b/cmd-choose-tree.c index 8178ec9f..e4cc754e 100644 --- a/cmd-choose-tree.c +++ b/cmd-choose-tree.c @@ -86,6 +86,6 @@ cmd_choose_tree_exec(struct cmd *self, struct cmdq_item *item) } else mode = &window_tree_mode; - window_pane_set_mode(wp, mode, &item->target, args); + window_pane_set_mode(wp, NULL, mode, &item->target, args); return (CMD_RETURN_NORMAL); } diff --git a/cmd-copy-mode.c b/cmd-copy-mode.c index bdb8245e..5ce7a2c4 100644 --- a/cmd-copy-mode.c +++ b/cmd-copy-mode.c @@ -30,9 +30,10 @@ const struct cmd_entry cmd_copy_mode_entry = { .name = "copy-mode", .alias = NULL, - .args = { "eHMt:uq", 0, 0 }, - .usage = "[-eHMuq] " CMD_TARGET_PANE_USAGE, + .args = { "eHMs:t:uq", 0, 0 }, + .usage = "[-eHMuq] [-s src-pane] " CMD_TARGET_PANE_USAGE, + .source = { 's', CMD_FIND_PANE, 0 }, .target = { 't', CMD_FIND_PANE, 0 }, .flags = CMD_AFTERHOOK, @@ -59,7 +60,7 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item) struct cmdq_shared *shared = item->shared; struct client *c = item->client; struct session *s; - struct window_pane *wp = item->target.wp; + struct window_pane *wp = item->target.wp, *swp; if (args_has(args, 'q')) { window_pane_reset_mode_all(wp); @@ -74,11 +75,15 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item) } if (self->entry == &cmd_clock_mode_entry) { - window_pane_set_mode(wp, &window_clock_mode, NULL, NULL); + window_pane_set_mode(wp, NULL, &window_clock_mode, NULL, NULL); return (CMD_RETURN_NORMAL); } - if (!window_pane_set_mode(wp, &window_copy_mode, NULL, args)) { + if (args_has(args, 's')) + swp = item->source.wp; + else + swp = wp; + if (!window_pane_set_mode(wp, swp, &window_copy_mode, NULL, args)) { if (args_has(args, 'M')) window_copy_start_drag(c, &shared->mouse); } diff --git a/cmd-find-window.c b/cmd-find-window.c index c29878b5..774c0bb9 100644 --- a/cmd-find-window.c +++ b/cmd-find-window.c @@ -116,7 +116,8 @@ cmd_find_window_exec(struct cmd *self, struct cmdq_item *item) args_set(new_args, 'Z', NULL); args_set(new_args, 'f', filter); - window_pane_set_mode(wp, &window_tree_mode, &item->target, new_args); + window_pane_set_mode(wp, NULL, &window_tree_mode, &item->target, + new_args); args_free(new_args); free(filter); diff --git a/cmd-queue.c b/cmd-queue.c index a9e1dd3a..42e7d31b 100644 --- a/cmd-queue.c +++ b/cmd-queue.c @@ -511,8 +511,10 @@ cmdq_print(struct cmdq_item *item, const char *fmt, ...) } else { wp = c->session->curw->window->active; wme = TAILQ_FIRST(&wp->modes); - if (wme == NULL || wme->mode != &window_view_mode) - window_pane_set_mode(wp, &window_view_mode, NULL, NULL); + if (wme == NULL || wme->mode != &window_view_mode) { + window_pane_set_mode(wp, NULL, &window_view_mode, NULL, + NULL); + } window_copy_add(wp, "%s", msg); } diff --git a/cmd-run-shell.c b/cmd-run-shell.c index a57beb83..7ce6d55a 100644 --- a/cmd-run-shell.c +++ b/cmd-run-shell.c @@ -82,7 +82,7 @@ cmd_run_shell_print(struct job *job, const char *msg) wme = TAILQ_FIRST(&wp->modes); if (wme == NULL || wme->mode != &window_view_mode) - window_pane_set_mode(wp, &window_view_mode, NULL, NULL); + window_pane_set_mode(wp, NULL, &window_view_mode, NULL, NULL); window_copy_add(wp, "%s", msg); } diff --git a/tmux.1 b/tmux.1 index d17c19e9..5098895c 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1608,6 +1608,7 @@ command is: .Bl -tag -width Ds .It Xo Ic copy-mode .Op Fl eHMqu +.Op Fl s Ar src-pane .Op Fl t Ar target-pane .Xc Enter copy mode. @@ -1621,6 +1622,11 @@ begins a mouse drag (only valid if bound to a mouse key binding, see hides the position indicator in the top right. .Fl q cancels copy mode and any other modes. +.Fl s +copies from +.Ar src-pane +instead of +.Ar target-pane. .Pp .Fl e specifies that scrolling to the bottom of the history (to the visible screen) diff --git a/tmux.h b/tmux.h index e66cbb39..5cc192fe 100644 --- a/tmux.h +++ b/tmux.h @@ -848,6 +848,7 @@ struct window_mode { /* Active window mode. */ struct window_mode_entry { struct window_pane *wp; + struct window_pane *swp; const struct window_mode *mode; void *data; @@ -2537,8 +2538,8 @@ void window_pane_unset_palette(struct window_pane *, u_int); void window_pane_reset_palette(struct window_pane *); int window_pane_get_palette(struct window_pane *, int); int window_pane_set_mode(struct window_pane *, - const struct window_mode *, struct cmd_find_state *, - struct args *); + struct window_pane *, const struct window_mode *, + struct cmd_find_state *, struct args *); void window_pane_reset_mode(struct window_pane *); void window_pane_reset_mode_all(struct window_pane *); int window_pane_key(struct window_pane *, struct client *, diff --git a/window-copy.c b/window-copy.c index 14f7a284..995dc35c 100644 --- a/window-copy.c +++ b/window-copy.c @@ -130,7 +130,7 @@ static void window_copy_rectangle_toggle(struct window_mode_entry *); static void window_copy_move_mouse(struct mouse_event *); static void window_copy_drag_update(struct client *, struct mouse_event *); static void window_copy_drag_release(struct client *, struct mouse_event *); -static struct screen* window_copy_clone_screen(struct screen *src); +static struct screen* window_copy_clone_screen(struct screen *, struct screen*); const struct window_mode window_copy_mode = { .name = "copy-mode", @@ -299,21 +299,29 @@ window_copy_scroll_timer(__unused int fd, __unused short events, void *arg) } static struct screen * -window_copy_clone_screen(struct screen *src) +window_copy_clone_screen(struct screen *src, struct screen *hint) { struct screen *dst; struct screen_write_ctx ctx; + u_int dy, sy; dst = xcalloc(1, sizeof *dst); - screen_init(dst, screen_size_x(src), - screen_hsize(src) + screen_size_y(src), src->grid->hlimit); - grid_duplicate_lines(dst->grid, 0, src->grid, 0, - screen_hsize(src) + screen_size_y(src)); - dst->grid->sy = screen_size_y(src); - dst->grid->hsize = screen_hsize(src); + + sy = screen_hsize(src) + screen_size_y(src); + if (screen_size_y(hint) > sy) + dy = screen_size_y(hint); + else + dy = sy; + screen_init(dst, screen_size_x(src), dy, src->grid->hlimit); + + grid_duplicate_lines(dst->grid, 0, src->grid, 0, sy); + if (screen_size_y(hint) < sy) { + dst->grid->sy = screen_size_y(hint); + dst->grid->hsize = sy - screen_size_y(hint); + } screen_write_start(&ctx, NULL, dst); - screen_write_cursormove(&ctx, src->cx, src->cy, 0); + screen_write_cursormove(&ctx, 0, dst->grid->sy - 1, 0); screen_write_stop(&ctx); return (dst); @@ -361,14 +369,14 @@ static struct screen * window_copy_init(struct window_mode_entry *wme, __unused struct cmd_find_state *fs, struct args *args) { - struct window_pane *wp = wme->wp; + struct window_pane *wp = wme->swp; struct window_copy_mode_data *data; struct screen_write_ctx ctx; u_int i; data = window_copy_common_init(wme); - data->backing = window_copy_clone_screen(&wp->base); + data->backing = window_copy_clone_screen(&wp->base, &data->screen); data->cx = data->backing->cx; data->cy = data->backing->cy; @@ -2001,7 +2009,7 @@ static enum window_copy_cmd_action window_copy_cmd_refresh_from_pane(struct window_copy_cmd_state *cs) { struct window_mode_entry *wme = cs->wme; - struct window_pane *wp = wme->wp; + struct window_pane *wp = wme->swp; struct window_copy_mode_data *data = wme->data; if (data->viewmode) @@ -2009,7 +2017,7 @@ window_copy_cmd_refresh_from_pane(struct window_copy_cmd_state *cs) screen_free(data->backing); free(data->backing); - data->backing = window_copy_clone_screen(&wp->base); + data->backing = window_copy_clone_screen(&wp->base, &data->screen); return (WINDOW_COPY_CMD_REDRAW); } @@ -2964,6 +2972,7 @@ window_copy_write_line(struct window_mode_entry *wme, struct grid_cell gc; char hdr[512]; size_t size = 0; + u_int hsize = screen_hsize(data->backing); style_apply(&gc, oo, "mode-style"); gc.flags |= GRID_FLAG_NOPALETTE; @@ -2972,23 +2981,20 @@ window_copy_write_line(struct window_mode_entry *wme, if (data->searchmark == NULL) { if (data->timeout) { size = xsnprintf(hdr, sizeof hdr, - "(timed out) [%u/%u]", data->oy, - screen_hsize(data->backing)); + "(timed out) [%u/%u]", data->oy, hsize); } else { size = xsnprintf(hdr, sizeof hdr, - "[%u/%u]", data->oy, - screen_hsize(data->backing)); + "[%u/%u]", data->oy, hsize); } } else { if (data->searchthis == -1) { size = xsnprintf(hdr, sizeof hdr, "(%u results) [%d/%u]", data->searchcount, - data->oy, screen_hsize(data->backing)); + data->oy, hsize); } else { size = xsnprintf(hdr, sizeof hdr, "(%u/%u results) [%d/%u]", data->searchthis, - data->searchcount, data->oy, - screen_hsize(data->backing)); + data->searchcount, data->oy, hsize); } } if (size > screen_size_x(s)) @@ -3000,8 +3006,7 @@ window_copy_write_line(struct window_mode_entry *wme, if (size < screen_size_x(s)) { screen_write_cursormove(ctx, 0, py, 0); - screen_write_copy(ctx, data->backing, 0, - (screen_hsize(data->backing) - data->oy) + py, + screen_write_copy(ctx, data->backing, 0, hsize - data->oy + py, screen_size_x(s) - size, 1, data->searchmark, &gc); } diff --git a/window.c b/window.c index 2169ede2..38e31810 100644 --- a/window.c +++ b/window.c @@ -1067,8 +1067,9 @@ window_pane_get_palette(struct window_pane *wp, int c) } int -window_pane_set_mode(struct window_pane *wp, const struct window_mode *mode, - struct cmd_find_state *fs, struct args *args) +window_pane_set_mode(struct window_pane *wp, struct window_pane *swp, + const struct window_mode *mode, struct cmd_find_state *fs, + struct args *args) { struct window_mode_entry *wme; @@ -1085,6 +1086,7 @@ window_pane_set_mode(struct window_pane *wp, const struct window_mode *mode, } else { wme = xcalloc(1, sizeof *wme); wme->wp = wp; + wme->swp = swp; wme->mode = mode; wme->prefix = 1; TAILQ_INSERT_HEAD(&wp->modes, wme, entry); From 1c433f135436664e3a369edbc43cb5cd057a8ae4 Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 10 Apr 2020 20:53:54 +0000 Subject: [PATCH 03/10] Remove unused define, also a man fix from jmc. --- tmux.1 | 2 +- tmux.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tmux.1 b/tmux.1 index 5098895c..64164f09 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1626,7 +1626,7 @@ cancels copy mode and any other modes. copies from .Ar src-pane instead of -.Ar target-pane. +.Ar target-pane . .Pp .Fl e specifies that scrolling to the bottom of the history (to the visible screen) diff --git a/tmux.h b/tmux.h index 5cc192fe..8f8640bf 100644 --- a/tmux.h +++ b/tmux.h @@ -843,7 +843,6 @@ struct window_mode { void (*formats)(struct window_mode_entry *, struct format_tree *); }; -#define WINDOW_MODE_TIMEOUT 180 /* Active window mode. */ struct window_mode_entry { From 70534cfde68d7f9002a26e8e23d767b05967f31e Mon Sep 17 00:00:00 2001 From: nicm Date: Sun, 12 Apr 2020 08:13:41 +0000 Subject: [PATCH 04/10] Clarify a couple of style options. --- tmux.1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tmux.1 b/tmux.1 index 64164f09..0f3204b6 100644 --- a/tmux.1 +++ b/tmux.1 @@ -3318,6 +3318,9 @@ with .Fl np . .It Ic message-command-style Ar style Set status line message command style. +This is used for the command prompt with +.Xr vi 1 +keys when in command mode. For how to specify .Ar style , see the @@ -3325,6 +3328,7 @@ see the section. .It Ic message-style Ar style Set status line message style. +This is used for messages and for the command prompt. For how to specify .Ar style , see the From 756591b4ca28089879ef785bde3a6fb30e9f5943 Mon Sep 17 00:00:00 2001 From: nicm Date: Sun, 12 Apr 2020 08:36:18 +0000 Subject: [PATCH 05/10] Add a -f filter argument to the list commands like choose-tree. --- cmd-list-buffers.c | 24 +++++++++++++++++------- cmd-list-panes.c | 24 +++++++++++++++++------- cmd-list-sessions.c | 24 +++++++++++++++++------- cmd-list-windows.c | 24 +++++++++++++++++------- tmux.1 | 36 +++++++++++++++++++++++++++--------- 5 files changed, 95 insertions(+), 37 deletions(-) diff --git a/cmd-list-buffers.c b/cmd-list-buffers.c index 0457a62d..2da8a518 100644 --- a/cmd-list-buffers.c +++ b/cmd-list-buffers.c @@ -36,8 +36,8 @@ const struct cmd_entry cmd_list_buffers_entry = { .name = "list-buffers", .alias = "lsb", - .args = { "F:", 0, 0 }, - .usage = "[-F format]", + .args = { "F:f:", 0, 0 }, + .usage = "[-F format] [-f filter]", .flags = CMD_AFTERHOOK, .exec = cmd_list_buffers_exec @@ -49,20 +49,30 @@ cmd_list_buffers_exec(struct cmd *self, struct cmdq_item *item) struct args *args = self->args; struct paste_buffer *pb; struct format_tree *ft; - char *line; - const char *template; + const char *template, *filter; + char *line, *expanded; + int flag; if ((template = args_get(args, 'F')) == NULL) template = LIST_BUFFERS_TEMPLATE; + filter = args_get(args, 'f'); pb = NULL; while ((pb = paste_walk(pb)) != NULL) { ft = format_create(item->client, item, FORMAT_NONE, 0); format_defaults_paste_buffer(ft, pb); - line = format_expand(ft, template); - cmdq_print(item, "%s", line); - free(line); + if (filter != NULL) { + expanded = format_expand(ft, filter); + flag = format_true(expanded); + free(expanded); + } else + flag = 1; + if (flag) { + line = format_expand(ft, template); + cmdq_print(item, "%s", line); + free(line); + } format_free(ft); } diff --git a/cmd-list-panes.c b/cmd-list-panes.c index 7f6994bd..10789460 100644 --- a/cmd-list-panes.c +++ b/cmd-list-panes.c @@ -38,8 +38,8 @@ const struct cmd_entry cmd_list_panes_entry = { .name = "list-panes", .alias = "lsp", - .args = { "asF:t:", 0, 0 }, - .usage = "[-as] [-F format] " CMD_TARGET_WINDOW_USAGE, + .args = { "asF:f:t:", 0, 0 }, + .usage = "[-as] [-F format] [-f filter] " CMD_TARGET_WINDOW_USAGE, .target = { 't', CMD_FIND_WINDOW, 0 }, @@ -91,8 +91,9 @@ cmd_list_panes_window(struct cmd *self, struct session *s, struct winlink *wl, struct window_pane *wp; u_int n; struct format_tree *ft; - const char *template; - char *line; + const char *template, *filter; + char *line, *expanded; + int flag; template = args_get(args, 'F'); if (template == NULL) { @@ -120,6 +121,7 @@ cmd_list_panes_window(struct cmd *self, struct session *s, struct winlink *wl, break; } } + filter = args_get(args, 'f'); n = 0; TAILQ_FOREACH(wp, &wl->window->panes, entry) { @@ -127,9 +129,17 @@ cmd_list_panes_window(struct cmd *self, struct session *s, struct winlink *wl, format_add(ft, "line", "%u", n); format_defaults(ft, NULL, s, wl, wp); - line = format_expand(ft, template); - cmdq_print(item, "%s", line); - free(line); + if (filter != NULL) { + expanded = format_expand(ft, filter); + flag = format_true(expanded); + free(expanded); + } else + flag = 1; + if (flag) { + line = format_expand(ft, template); + cmdq_print(item, "%s", line); + free(line); + } format_free(ft); n++; diff --git a/cmd-list-sessions.c b/cmd-list-sessions.c index 72ff47e8..36d6dd78 100644 --- a/cmd-list-sessions.c +++ b/cmd-list-sessions.c @@ -42,8 +42,8 @@ const struct cmd_entry cmd_list_sessions_entry = { .name = "list-sessions", .alias = "ls", - .args = { "F:", 0, 0 }, - .usage = "[-F format]", + .args = { "F:f:", 0, 0 }, + .usage = "[-F format] [-f filter]", .flags = CMD_AFTERHOOK, .exec = cmd_list_sessions_exec @@ -56,11 +56,13 @@ cmd_list_sessions_exec(struct cmd *self, struct cmdq_item *item) struct session *s; u_int n; struct format_tree *ft; - const char *template; - char *line; + const char *template, *filter; + char *line, *expanded; + int flag; if ((template = args_get(args, 'F')) == NULL) template = LIST_SESSIONS_TEMPLATE; + filter = args_get(args, 'f'); n = 0; RB_FOREACH(s, sessions, &sessions) { @@ -68,9 +70,17 @@ cmd_list_sessions_exec(struct cmd *self, struct cmdq_item *item) format_add(ft, "line", "%u", n); format_defaults(ft, NULL, s, NULL, NULL); - line = format_expand(ft, template); - cmdq_print(item, "%s", line); - free(line); + if (filter != NULL) { + expanded = format_expand(ft, filter); + flag = format_true(expanded); + free(expanded); + } else + flag = 1; + if (flag) { + line = format_expand(ft, template); + cmdq_print(item, "%s", line); + free(line); + } format_free(ft); n++; diff --git a/cmd-list-windows.c b/cmd-list-windows.c index 46ee6f0c..32b7b8f5 100644 --- a/cmd-list-windows.c +++ b/cmd-list-windows.c @@ -49,8 +49,8 @@ const struct cmd_entry cmd_list_windows_entry = { .name = "list-windows", .alias = "lsw", - .args = { "F:at:", 0, 0 }, - .usage = "[-a] [-F format] " CMD_TARGET_SESSION_USAGE, + .args = { "F:f:at:", 0, 0 }, + .usage = "[-a] [-F format] [-f filter] " CMD_TARGET_SESSION_USAGE, .target = { 't', CMD_FIND_SESSION, 0 }, @@ -88,8 +88,9 @@ cmd_list_windows_session(struct cmd *self, struct session *s, struct winlink *wl; u_int n; struct format_tree *ft; - const char *template; - char *line; + const char *template, *filter; + char *line, *expanded; + int flag; template = args_get(args, 'F'); if (template == NULL) { @@ -102,6 +103,7 @@ cmd_list_windows_session(struct cmd *self, struct session *s, break; } } + filter = args_get(args, 'f'); n = 0; RB_FOREACH(wl, winlinks, &s->windows) { @@ -109,9 +111,17 @@ cmd_list_windows_session(struct cmd *self, struct session *s, format_add(ft, "line", "%u", n); format_defaults(ft, NULL, s, wl, NULL); - line = format_expand(ft, template); - cmdq_print(item, "%s", line); - free(line); + if (filter != NULL) { + expanded = format_expand(ft, filter); + flag = format_true(expanded); + free(expanded); + } else + flag = 1; + if (flag) { + line = format_expand(ft, template); + cmdq_print(item, "%s", line); + free(line); + } format_free(ft); n++; diff --git a/tmux.1 b/tmux.1 index 0f3204b6..be62588f 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1055,12 +1055,18 @@ List the syntax of .Ar command or - if omitted - of all commands supported by .Nm . -.It Ic list-sessions Op Fl F Ar format +.It Xo Ic list-sessions +.Op Fl F Ar format +.Op Fl f Ar filter +.Xc .D1 (alias: Ic ls ) List all sessions managed by the server. -For the meaning of the .Fl F -flag, see the +specifies the format of each line and +.Fl f +a filter. +Only sessions for which the filter is true are shown. +See the .Sx FORMATS section. .It Ic lock-client Op Fl t Ar target-client @@ -2062,6 +2068,7 @@ is given, the newly linked window is not selected. .It Xo Ic list-panes .Op Fl as .Op Fl F Ar format +.Op Fl f Ar filter .Op Fl t Ar target .Xc .D1 (alias: Ic lsp ) @@ -2078,14 +2085,18 @@ is a session (or the current session). If neither is given, .Ar target is a window (or the current window). -For the meaning of the .Fl F -flag, see the +specifies the format of each line and +.Fl f +a filter. +Only panes for which the filter is true are shown. +See the .Sx FORMATS section. .It Xo Ic list-windows .Op Fl a .Op Fl F Ar format +.Op Fl f Ar filter .Op Fl t Ar target-session .Xc .D1 (alias: Ic lsw ) @@ -2094,9 +2105,12 @@ If is given, list all windows on the server. Otherwise, list windows in the current session or in .Ar target-session . -For the meaning of the .Fl F -flag, see the +specifies the format of each line and +.Fl f +a filter. +Only windows for which the filter is true are shown. +See the .Sx FORMATS section. .It Xo Ic move-pane @@ -5261,12 +5275,16 @@ Delete the buffer named or the most recently added automatically named buffer if not specified. .It Xo Ic list-buffers .Op Fl F Ar format +.Op Fl f Ar filter .Xc .D1 (alias: Ic lsb ) List the global buffers. -For the meaning of the .Fl F -flag, see the +specifies the format of each line and +.Fl f +a filter. +Only buffers for which the filter is true are shown. +See the .Sx FORMATS section. .It Xo Ic load-buffer From de6b30a51ca2acf77831de2a71c465a07e95df19 Mon Sep 17 00:00:00 2001 From: nicm Date: Sun, 12 Apr 2020 20:16:36 +0000 Subject: [PATCH 07/10] Mention RGB, pointed out by Jody Frankowski. --- tmux.1 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tmux.1 b/tmux.1 index be62588f..956a3911 100644 --- a/tmux.1 +++ b/tmux.1 @@ -5470,7 +5470,7 @@ The server crashed or otherwise exited without telling the client the reason. understands some unofficial extensions to .Xr terminfo 5 : .Bl -tag -width Ds -.It Em Cs , Cr +.It Em \&Cs , Cr Set the cursor colour. The first takes a single string argument and is used to set the colour; the second takes no arguments and restores the default cursor colour. @@ -5534,6 +5534,11 @@ capabilities to the .Nm .Xr terminfo 5 entry). +.Pp +This is equivalent to the +.Em RGB +.Xr terminfo 5 +capability. .It Em \&Ms Store the current buffer in the host terminal's selection (clipboard). See the From ad38ef6ff43b5794f09911c1ae72f44bb6f0869f Mon Sep 17 00:00:00 2001 From: nicm Date: Sun, 12 Apr 2020 20:54:28 +0000 Subject: [PATCH 08/10] Print empty arguments properly. --- arguments.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arguments.c b/arguments.c index e573249a..5b882ea1 100644 --- a/arguments.c +++ b/arguments.c @@ -216,8 +216,10 @@ args_escape(const char *s) char *escaped, *result; int flags; - if (*s == '\0') - return (xstrdup(s)); + if (*s == '\0') { + xasprintf(&result, "''"); + return (result); + } if (s[0] != ' ' && (strchr(quoted, s[0]) != NULL || s[0] == '~') && s[1] == '\0') { From 9cbe9675ea8a8efb01dcc5f267e6d5853b2cd58f Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 13 Apr 2020 07:25:33 +0000 Subject: [PATCH 09/10] Change so that the appropriate hooks for windows and panes belong to pane/window options rather than all being session options. This is useful for example to create a pane that is automatically closed on some condition. From Anindya Mukherjee. --- cmd-set-option.c | 6 +++--- cmd-show-options.c | 6 +++--- notify.c | 8 ++++++++ options-table.c | 42 ++++++++++++++++++++++++++++++------------ tmux.1 | 29 ++++++++++------------------- 5 files changed, 54 insertions(+), 37 deletions(-) diff --git a/cmd-set-option.c b/cmd-set-option.c index 2709dcdc..d466093e 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -69,10 +69,10 @@ const struct cmd_entry cmd_set_hook_entry = { .name = "set-hook", .alias = NULL, - .args = { "agRt:u", 1, 2 }, - .usage = "[-agRu] " CMD_TARGET_SESSION_USAGE " hook [command]", + .args = { "agpRt:uw", 1, 2 }, + .usage = "[-agpRuw] " CMD_TARGET_PANE_USAGE " hook [command]", - .target = { 't', CMD_FIND_SESSION, CMD_FIND_CANFAIL }, + .target = { 't', CMD_FIND_PANE, CMD_FIND_CANFAIL }, .flags = CMD_AFTERHOOK, .exec = cmd_set_option_exec diff --git a/cmd-show-options.c b/cmd-show-options.c index b5c5f59d..fe3cddc5 100644 --- a/cmd-show-options.c +++ b/cmd-show-options.c @@ -65,10 +65,10 @@ const struct cmd_entry cmd_show_hooks_entry = { .name = "show-hooks", .alias = NULL, - .args = { "gt:", 0, 1 }, - .usage = "[-g] " CMD_TARGET_SESSION_USAGE, + .args = { "gpt:w", 0, 1 }, + .usage = "[-gpw] " CMD_TARGET_PANE_USAGE, - .target = { 't', CMD_FIND_SESSION, 0 }, + .target = { 't', CMD_FIND_PANE, CMD_FIND_CANFAIL }, .flags = CMD_AFTERHOOK, .exec = cmd_show_options_exec diff --git a/notify.c b/notify.c index c91a4399..772b3e1f 100644 --- a/notify.c +++ b/notify.c @@ -76,6 +76,14 @@ notify_insert_hook(struct cmdq_item *item, struct notify_entry *ne) else oo = fs.s->options; o = options_get(oo, ne->name); + if (o == NULL && fs.wp != NULL) { + oo = fs.wp->options; + o = options_get(oo, ne->name); + } + if (o == NULL && fs.wl != NULL) { + oo = fs.wl->window->options; + o = options_get(oo, ne->name); + } if (o == NULL) return; diff --git a/options-table.c b/options-table.c index d8612ff2..33ee4402 100644 --- a/options-table.c +++ b/options-table.c @@ -140,7 +140,7 @@ static const char *options_table_status_format_default[] = { OPTIONS_TABLE_STATUS_FORMAT1, OPTIONS_TABLE_STATUS_FORMAT2, NULL }; -/* Helper for hook options. */ +/* Helpers for hook options. */ #define OPTIONS_TABLE_HOOK(hook_name, default_value) \ { .name = hook_name, \ .type = OPTIONS_TABLE_COMMAND, \ @@ -150,6 +150,24 @@ static const char *options_table_status_format_default[] = { .separator = "" \ } +#define OPTIONS_TABLE_PANE_HOOK(hook_name, default_value) \ + { .name = hook_name, \ + .type = OPTIONS_TABLE_COMMAND, \ + .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE, \ + .flags = OPTIONS_TABLE_IS_ARRAY|OPTIONS_TABLE_IS_HOOK, \ + .default_str = default_value, \ + .separator = "" \ + } + +#define OPTIONS_TABLE_WINDOW_HOOK(hook_name, default_value) \ + { .name = hook_name, \ + .type = OPTIONS_TABLE_COMMAND, \ + .scope = OPTIONS_TABLE_WINDOW, \ + .flags = OPTIONS_TABLE_IS_ARRAY|OPTIONS_TABLE_IS_HOOK, \ + .default_str = default_value, \ + .separator = "" \ + } + /* Top-level options. */ const struct options_table_entry options_table[] = { /* Server options. */ @@ -851,21 +869,21 @@ const struct options_table_entry options_table[] = { OPTIONS_TABLE_HOOK("client-detached", ""), OPTIONS_TABLE_HOOK("client-resized", ""), OPTIONS_TABLE_HOOK("client-session-changed", ""), - OPTIONS_TABLE_HOOK("pane-died", ""), - OPTIONS_TABLE_HOOK("pane-exited", ""), - OPTIONS_TABLE_HOOK("pane-focus-in", ""), - OPTIONS_TABLE_HOOK("pane-focus-out", ""), - OPTIONS_TABLE_HOOK("pane-mode-changed", ""), - OPTIONS_TABLE_HOOK("pane-set-clipboard", ""), + OPTIONS_TABLE_PANE_HOOK("pane-died", ""), + OPTIONS_TABLE_PANE_HOOK("pane-exited", ""), + OPTIONS_TABLE_PANE_HOOK("pane-focus-in", ""), + OPTIONS_TABLE_PANE_HOOK("pane-focus-out", ""), + OPTIONS_TABLE_PANE_HOOK("pane-mode-changed", ""), + OPTIONS_TABLE_PANE_HOOK("pane-set-clipboard", ""), OPTIONS_TABLE_HOOK("session-closed", ""), OPTIONS_TABLE_HOOK("session-created", ""), OPTIONS_TABLE_HOOK("session-renamed", ""), OPTIONS_TABLE_HOOK("session-window-changed", ""), - OPTIONS_TABLE_HOOK("window-layout-changed", ""), - OPTIONS_TABLE_HOOK("window-linked", ""), - OPTIONS_TABLE_HOOK("window-pane-changed", ""), - OPTIONS_TABLE_HOOK("window-renamed", ""), - OPTIONS_TABLE_HOOK("window-unlinked", ""), + OPTIONS_TABLE_WINDOW_HOOK("window-layout-changed", ""), + OPTIONS_TABLE_WINDOW_HOOK("window-linked", ""), + OPTIONS_TABLE_WINDOW_HOOK("window-pane-changed", ""), + OPTIONS_TABLE_WINDOW_HOOK("window-renamed", ""), + OPTIONS_TABLE_WINDOW_HOOK("window-unlinked", ""), { .name = NULL } }; diff --git a/tmux.1 b/tmux.1 index 956a3911..81a5c613 100644 --- a/tmux.1 +++ b/tmux.1 @@ -3897,6 +3897,7 @@ hook and there are a number of hooks not associated with commands. .Pp Hooks are stored as array options, members of the array are executed in order when the hook is triggered. +Like options different hooks may be global or belong to a session, window or pane. Hooks may be configured with the .Ic set-hook or @@ -3989,8 +3990,8 @@ Run when a window is unlinked from a session. Hooks are managed with these commands: .Bl -tag -width Ds .It Xo Ic set-hook -.Op Fl agRu -.Op Fl t Ar target-session +.Op Fl agpRuw +.Op Fl t Ar target-pane .Ar hook-name .Ar command .Xc @@ -4002,18 +4003,8 @@ unsets) hook .Ar hook-name to .Ar command . -If -.Fl g -is given, -.Em hook-name -is added to the global list of hooks, otherwise it is added to the session -hooks (for -.Ar target-session -with -.Fl t ) . -.Fl a -appends to a hook. -Like options, session hooks inherit from the global ones. +The flags are the same as for +.Ic set-option . .Pp With .Fl R , @@ -4021,12 +4012,12 @@ run .Ar hook-name immediately. .It Xo Ic show-hooks -.Op Fl g -.Op Fl t Ar target-session +.Op Fl gpw +.Op Fl t Ar target-pane .Xc -Shows the global list of hooks with -.Fl g , -otherwise the session hooks. +Shows hooks. +The flags are the same as for +.Ic show-options . .El .Sh MOUSE SUPPORT If the From c20eb0c0ae3347c768894a6355adfd7ebae6f2f3 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 13 Apr 2020 08:26:27 +0000 Subject: [PATCH 10/10] Make struct cmd local to cmd.c and move it out of tmux.h. --- client.c | 7 +-- cmd-attach-session.c | 2 +- cmd-bind-key.c | 2 +- cmd-break-pane.c | 4 +- cmd-capture-pane.c | 4 +- cmd-choose-tree.c | 6 +- cmd-command-prompt.c | 2 +- cmd-confirm-before.c | 2 +- cmd-copy-mode.c | 6 +- cmd-detach-client.c | 4 +- cmd-display-menu.c | 4 +- cmd-display-message.c | 6 +- cmd-display-panes.c | 2 +- cmd-find-window.c | 2 +- cmd-if-shell.c | 14 ++--- cmd-join-pane.c | 4 +- cmd-kill-pane.c | 3 +- cmd-kill-server.c | 2 +- cmd-kill-session.c | 2 +- cmd-kill-window.c | 6 +- cmd-list-buffers.c | 2 +- cmd-list-clients.c | 2 +- cmd-list-keys.c | 6 +- cmd-list-panes.c | 4 +- cmd-list-sessions.c | 2 +- cmd-list-windows.c | 4 +- cmd-load-buffer.c | 2 +- cmd-lock-server.c | 6 +- cmd-move-window.c | 12 ++-- cmd-new-session.c | 4 +- cmd-new-window.c | 2 +- cmd-paste-buffer.c | 2 +- cmd-pipe-pane.c | 8 +-- cmd-queue.c | 33 ++++++----- cmd-refresh-client.c | 2 +- cmd-rename-session.c | 2 +- cmd-rename-window.c | 2 +- cmd-resize-pane.c | 2 +- cmd-resize-window.c | 2 +- cmd-respawn-pane.c | 2 +- cmd-respawn-window.c | 2 +- cmd-rotate-window.c | 5 +- cmd-run-shell.c | 2 +- cmd-save-buffer.c | 6 +- cmd-select-layout.c | 6 +- cmd-select-pane.c | 33 +++++------ cmd-select-window.c | 17 +++--- cmd-send-keys.c | 4 +- cmd-set-buffer.c | 4 +- cmd-set-environment.c | 8 +-- cmd-set-option.c | 8 +-- cmd-show-environment.c | 8 +-- cmd-show-messages.c | 2 +- cmd-show-options.c | 20 ++++--- cmd-source-file.c | 2 +- cmd-split-window.c | 2 +- cmd-swap-pane.c | 2 +- cmd-swap-window.c | 3 +- cmd-switch-client.c | 4 +- cmd-unbind-key.c | 44 +------------- cmd-wait-for.c | 2 +- cmd.c | 127 ++++++++++++++++++++++++++++++++++++++--- format.c | 6 +- key-bindings.c | 10 +--- tmux.h | 49 +++++++--------- 65 files changed, 314 insertions(+), 247 deletions(-) diff --git a/client.c b/client.c index 5aae8d0d..c1d6e1b5 100644 --- a/client.c +++ b/client.c @@ -236,7 +236,6 @@ int client_main(struct event_base *base, int argc, char **argv, int flags) { struct cmd_parse_result *pr; - struct cmd *cmd; struct msg_command *data; int fd, i; const char *ttynam, *cwd; @@ -265,10 +264,8 @@ client_main(struct event_base *base, int argc, char **argv, int flags) */ pr = cmd_parse_from_arguments(argc, argv, NULL); if (pr->status == CMD_PARSE_SUCCESS) { - TAILQ_FOREACH(cmd, &pr->cmdlist->list, qentry) { - if (cmd->entry->flags & CMD_STARTSERVER) - flags |= CLIENT_STARTSERVER; - } + if (cmd_list_any_have(pr->cmdlist, CMD_STARTSERVER)) + flags |= CLIENT_STARTSERVER; cmd_list_free(pr->cmdlist); } else free(pr->error); diff --git a/cmd-attach-session.c b/cmd-attach-session.c index 477d3517..23a321bd 100644 --- a/cmd-attach-session.c +++ b/cmd-attach-session.c @@ -177,7 +177,7 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag, static enum cmd_retval cmd_attach_session_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); return (cmd_attach_session(item, args_get(args, 't'), args_has(args, 'd'), args_has(args, 'x'), args_has(args, 'r'), diff --git a/cmd-bind-key.c b/cmd-bind-key.c index bc6a3d40..dcb56c06 100644 --- a/cmd-bind-key.c +++ b/cmd-bind-key.c @@ -44,7 +44,7 @@ const struct cmd_entry cmd_bind_key_entry = { static enum cmd_retval cmd_bind_key_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); key_code key; const char *tablename, *note; struct cmd_parse_result *pr; diff --git a/cmd-break-pane.c b/cmd-break-pane.c index 6c638103..b4997f91 100644 --- a/cmd-break-pane.c +++ b/cmd-break-pane.c @@ -48,7 +48,7 @@ const struct cmd_entry cmd_break_pane_entry = { static enum cmd_retval cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct cmd_find_state *current = &item->shared->current; struct client *c = cmd_find_client(item, NULL, 1); struct winlink *wl = item->source.wl; @@ -98,7 +98,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item) if (idx == -1) idx = -1 - options_get_number(dst_s->options, "base-index"); wl = session_attach(dst_s, w, idx, &cause); /* can't fail */ - if (!args_has(self->args, 'd')) { + if (!args_has(args, 'd')) { session_select(dst_s, wl->idx); cmd_find_from_session(current, dst_s, 0); } diff --git a/cmd-capture-pane.c b/cmd-capture-pane.c index ad6755ba..3510142e 100644 --- a/cmd-capture-pane.c +++ b/cmd-capture-pane.c @@ -192,14 +192,14 @@ cmd_capture_pane_history(struct args *args, struct cmdq_item *item, static enum cmd_retval cmd_capture_pane_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct client *c = item->client; struct window_pane *wp = item->target.wp; char *buf, *cause; const char *bufname; size_t len; - if (self->entry == &cmd_clear_history_entry) { + if (cmd_get_entry(self) == &cmd_clear_history_entry) { window_pane_reset_mode_all(wp); grid_clear_history(wp->base.grid); return (CMD_RETURN_NORMAL); diff --git a/cmd-choose-tree.c b/cmd-choose-tree.c index e4cc754e..8b667ec5 100644 --- a/cmd-choose-tree.c +++ b/cmd-choose-tree.c @@ -71,15 +71,15 @@ const struct cmd_entry cmd_choose_buffer_entry = { static enum cmd_retval cmd_choose_tree_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct window_pane *wp = item->target.wp; const struct window_mode *mode; - if (self->entry == &cmd_choose_buffer_entry) { + if (cmd_get_entry(self) == &cmd_choose_buffer_entry) { if (paste_get_top(NULL) == NULL) return (CMD_RETURN_NORMAL); mode = &window_buffer_mode; - } else if (self->entry == &cmd_choose_client_entry) { + } else if (cmd_get_entry(self) == &cmd_choose_client_entry) { if (server_client_how_many() == 0) return (CMD_RETURN_NORMAL); mode = &window_client_mode; diff --git a/cmd-command-prompt.c b/cmd-command-prompt.c index 9f0ea19f..31a1ae78 100644 --- a/cmd-command-prompt.c +++ b/cmd-command-prompt.c @@ -64,7 +64,7 @@ struct cmd_command_prompt_cdata { static enum cmd_retval cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); const char *inputs, *prompts; struct cmd_command_prompt_cdata *cdata; struct client *c; diff --git a/cmd-confirm-before.c b/cmd-confirm-before.c index be21a78b..419efda5 100644 --- a/cmd-confirm-before.c +++ b/cmd-confirm-before.c @@ -53,7 +53,7 @@ struct cmd_confirm_before_data { static enum cmd_retval cmd_confirm_before_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct cmd_confirm_before_data *cdata; struct client *c; char *cmd, *copy, *new_prompt, *ptr; diff --git a/cmd-copy-mode.c b/cmd-copy-mode.c index 5ce7a2c4..3b20689c 100644 --- a/cmd-copy-mode.c +++ b/cmd-copy-mode.c @@ -56,7 +56,7 @@ const struct cmd_entry cmd_clock_mode_entry = { static enum cmd_retval cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct cmdq_shared *shared = item->shared; struct client *c = item->client; struct session *s; @@ -74,7 +74,7 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item) return (CMD_RETURN_NORMAL); } - if (self->entry == &cmd_clock_mode_entry) { + if (cmd_get_entry(self) == &cmd_clock_mode_entry) { window_pane_set_mode(wp, NULL, &window_clock_mode, NULL, NULL); return (CMD_RETURN_NORMAL); } @@ -87,7 +87,7 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item) if (args_has(args, 'M')) window_copy_start_drag(c, &shared->mouse); } - if (args_has(self->args, 'u')) + if (args_has(args, 'u')) window_copy_pageup(wp, 0); return (CMD_RETURN_NORMAL); diff --git a/cmd-detach-client.c b/cmd-detach-client.c index 85b9a4ed..34682459 100644 --- a/cmd-detach-client.c +++ b/cmd-detach-client.c @@ -57,7 +57,7 @@ const struct cmd_entry cmd_suspend_client_entry = { static enum cmd_retval cmd_detach_client_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct client *c, *cloop; struct session *s; enum msgtype msgtype; @@ -66,7 +66,7 @@ cmd_detach_client_exec(struct cmd *self, struct cmdq_item *item) if ((c = cmd_find_client(item, args_get(args, 't'), 0)) == NULL) return (CMD_RETURN_ERROR); - if (self->entry == &cmd_suspend_client_entry) { + if (cmd_get_entry(self) == &cmd_suspend_client_entry) { server_client_suspend(c); return (CMD_RETURN_NORMAL); } diff --git a/cmd-display-menu.c b/cmd-display-menu.c index b4db7331..74637ceb 100644 --- a/cmd-display-menu.c +++ b/cmd-display-menu.c @@ -171,7 +171,7 @@ cmd_display_menu_get_position(struct client *c, struct cmdq_item *item, static enum cmd_retval cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct client *c; struct session *s = item->target.s; struct winlink *wl = item->target.wl; @@ -239,7 +239,7 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item) static enum cmd_retval cmd_display_popup_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct client *c; struct cmd_find_state *fs = &item->target; const char *value, *cmd = NULL, **lines = NULL; diff --git a/cmd-display-message.c b/cmd-display-message.c index 4d9bccb6..d4d4ad25 100644 --- a/cmd-display-message.c +++ b/cmd-display-message.c @@ -60,7 +60,7 @@ cmd_display_message_each(const char *key, const char *value, void *arg) static enum cmd_retval cmd_display_message_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct client *c, *target_c; struct session *s = item->target.s; struct winlink *wl = item->target.wl; @@ -101,7 +101,7 @@ cmd_display_message_exec(struct cmd *self, struct cmdq_item *item) target_c = c; else target_c = cmd_find_best_client(s); - if (args_has(self->args, 'v')) + if (args_has(args, 'v')) flags = FORMAT_VERBOSE; else flags = 0; @@ -114,7 +114,7 @@ cmd_display_message_exec(struct cmd *self, struct cmdq_item *item) } msg = format_expand_time(ft, template); - if (args_has(self->args, 'p')) + if (args_has(args, 'p')) cmdq_print(item, "%s", msg); else if (c != NULL) status_message_set(c, "%s", msg); diff --git a/cmd-display-panes.c b/cmd-display-panes.c index d8d351c2..41fe50da 100644 --- a/cmd-display-panes.c +++ b/cmd-display-panes.c @@ -239,7 +239,7 @@ cmd_display_panes_key(struct client *c, struct key_event *event) static enum cmd_retval cmd_display_panes_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct client *c; struct session *s; u_int delay; diff --git a/cmd-find-window.c b/cmd-find-window.c index 774c0bb9..798754d1 100644 --- a/cmd-find-window.c +++ b/cmd-find-window.c @@ -44,7 +44,7 @@ const struct cmd_entry cmd_find_window_entry = { static enum cmd_retval cmd_find_window_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args, *new_args; + struct args *args = cmd_get_args(self), *new_args; struct window_pane *wp = item->target.wp; const char *s = args->argv[0]; char *filter, *argv = { NULL }; diff --git a/cmd-if-shell.c b/cmd-if-shell.c index b008241d..a678cf40 100644 --- a/cmd-if-shell.c +++ b/cmd-if-shell.c @@ -62,10 +62,11 @@ struct cmd_if_shell_data { static enum cmd_retval cmd_if_shell_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct mouse_event *m = &item->shared->mouse; struct cmd_if_shell_data *cdata; char *shellcmd, *cmd; + const char *file; struct cmdq_item *new_item; struct cmd_find_state *fs = &item->target; struct client *c = cmd_find_client(item, NULL, 1); @@ -88,9 +89,7 @@ cmd_if_shell_exec(struct cmd *self, struct cmdq_item *item) return (CMD_RETURN_NORMAL); memset(&pi, 0, sizeof pi); - if (self->file != NULL) - pi.file = self->file; - pi.line = self->line; + cmd_get_source(self, &pi.file, &pi.line); pi.item = item; pi.c = c; cmd_find_copy_state(&pi.fs, fs); @@ -134,10 +133,9 @@ cmd_if_shell_exec(struct cmd *self, struct cmdq_item *item) cdata->item = NULL; memset(&cdata->input, 0, sizeof cdata->input); - if (self->file != NULL) - cdata->input.file = xstrdup(self->file); - cdata->input.line = self->line; - cdata->input.item = cdata->item; + cmd_get_source(self, &file, &cdata->input.line); + if (file != NULL) + cdata->input.file = xstrdup(file); cdata->input.c = c; if (cdata->input.c != NULL) cdata->input.c->references++; diff --git a/cmd-join-pane.c b/cmd-join-pane.c index 108eab3a..2d26d82b 100644 --- a/cmd-join-pane.c +++ b/cmd-join-pane.c @@ -63,7 +63,7 @@ const struct cmd_entry cmd_move_pane_entry = { static enum cmd_retval cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct cmd_find_state *current = &item->shared->current; struct session *dst_s; struct winlink *src_wl, *dst_wl; @@ -75,7 +75,7 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item) enum layout_type type; struct layout_cell *lc; - if (self->entry == &cmd_join_pane_entry) + if (cmd_get_entry(self) == &cmd_join_pane_entry) not_same_window = 1; else not_same_window = 0; diff --git a/cmd-kill-pane.c b/cmd-kill-pane.c index f0aacb2a..301b9fa6 100644 --- a/cmd-kill-pane.c +++ b/cmd-kill-pane.c @@ -44,10 +44,11 @@ const struct cmd_entry cmd_kill_pane_entry = { static enum cmd_retval cmd_kill_pane_exec(struct cmd *self, struct cmdq_item *item) { + struct args *args = cmd_get_args(self); struct winlink *wl = item->target.wl; struct window_pane *loopwp, *tmpwp, *wp = item->target.wp; - if (args_has(self->args, 'a')) { + if (args_has(args, 'a')) { server_unzoom_window(wl->window); TAILQ_FOREACH_SAFE(loopwp, &wl->window->panes, entry, tmpwp) { if (loopwp == wp) diff --git a/cmd-kill-server.c b/cmd-kill-server.c index d7eba692..76bcf267 100644 --- a/cmd-kill-server.c +++ b/cmd-kill-server.c @@ -54,7 +54,7 @@ const struct cmd_entry cmd_start_server_entry = { static enum cmd_retval cmd_kill_server_exec(struct cmd *self, __unused struct cmdq_item *item) { - if (self->entry == &cmd_kill_server_entry) + if (cmd_get_entry(self) == &cmd_kill_server_entry) kill(getpid(), SIGTERM); return (CMD_RETURN_NORMAL); diff --git a/cmd-kill-session.c b/cmd-kill-session.c index dcef8097..978d1b9c 100644 --- a/cmd-kill-session.c +++ b/cmd-kill-session.c @@ -45,7 +45,7 @@ const struct cmd_entry cmd_kill_session_entry = { static enum cmd_retval cmd_kill_session_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct session *s, *sloop, *stmp; struct winlink *wl; diff --git a/cmd-kill-window.c b/cmd-kill-window.c index 50df83ee..c788ff38 100644 --- a/cmd-kill-window.c +++ b/cmd-kill-window.c @@ -55,13 +55,13 @@ const struct cmd_entry cmd_unlink_window_entry = { static enum cmd_retval cmd_kill_window_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct winlink *wl = item->target.wl, *wl2, *wl3; struct window *w = wl->window; struct session *s = item->target.s; - if (self->entry == &cmd_unlink_window_entry) { - if (!args_has(self->args, 'k') && !session_is_linked(s, w)) { + if (cmd_get_entry(self) == &cmd_unlink_window_entry) { + if (!args_has(args, 'k') && !session_is_linked(s, w)) { cmdq_error(item, "window only linked to one session"); return (CMD_RETURN_ERROR); } diff --git a/cmd-list-buffers.c b/cmd-list-buffers.c index 2da8a518..784289d8 100644 --- a/cmd-list-buffers.c +++ b/cmd-list-buffers.c @@ -46,7 +46,7 @@ const struct cmd_entry cmd_list_buffers_entry = { static enum cmd_retval cmd_list_buffers_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct paste_buffer *pb; struct format_tree *ft; const char *template, *filter; diff --git a/cmd-list-clients.c b/cmd-list-clients.c index 9fab8f84..9cec5199 100644 --- a/cmd-list-clients.c +++ b/cmd-list-clients.c @@ -51,7 +51,7 @@ const struct cmd_entry cmd_list_clients_entry = { static enum cmd_retval cmd_list_clients_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct client *c; struct session *s; struct format_tree *ft; diff --git a/cmd-list-keys.c b/cmd-list-keys.c index e1ec4d3c..d6c261d8 100644 --- a/cmd-list-keys.c +++ b/cmd-list-keys.c @@ -144,7 +144,7 @@ cmd_list_keys_get_prefix(struct args *args, key_code *prefix) static enum cmd_retval cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct key_table *table; struct key_binding *bd; const char *tablename, *r; @@ -153,7 +153,7 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item) int repeat, width, tablewidth, keywidth, found = 0; size_t tmpsize, tmpused, cplen; - if (self->entry == &cmd_list_commands_entry) + if (cmd_get_entry(self) == &cmd_list_commands_entry) return (cmd_list_keys_commands(self, item)); if (args->argc != 0) { @@ -313,7 +313,7 @@ out: static enum cmd_retval cmd_list_keys_commands(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); const struct cmd_entry **entryp; const struct cmd_entry *entry; struct format_tree *ft; diff --git a/cmd-list-panes.c b/cmd-list-panes.c index 10789460..ac97558e 100644 --- a/cmd-list-panes.c +++ b/cmd-list-panes.c @@ -50,7 +50,7 @@ const struct cmd_entry cmd_list_panes_entry = { static enum cmd_retval cmd_list_panes_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct session *s = item->target.s; struct winlink *wl = item->target.wl; @@ -87,7 +87,7 @@ static void cmd_list_panes_window(struct cmd *self, struct session *s, struct winlink *wl, struct cmdq_item *item, int type) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct window_pane *wp; u_int n; struct format_tree *ft; diff --git a/cmd-list-sessions.c b/cmd-list-sessions.c index 36d6dd78..1c6e1e9c 100644 --- a/cmd-list-sessions.c +++ b/cmd-list-sessions.c @@ -52,7 +52,7 @@ const struct cmd_entry cmd_list_sessions_entry = { static enum cmd_retval cmd_list_sessions_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct session *s; u_int n; struct format_tree *ft; diff --git a/cmd-list-windows.c b/cmd-list-windows.c index 32b7b8f5..905e9eaf 100644 --- a/cmd-list-windows.c +++ b/cmd-list-windows.c @@ -61,7 +61,7 @@ const struct cmd_entry cmd_list_windows_entry = { static enum cmd_retval cmd_list_windows_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); if (args_has(args, 'a')) cmd_list_windows_server(self, item); @@ -84,7 +84,7 @@ static void cmd_list_windows_session(struct cmd *self, struct session *s, struct cmdq_item *item, int type) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct winlink *wl; u_int n; struct format_tree *ft; diff --git a/cmd-load-buffer.c b/cmd-load-buffer.c index 5e930126..588623f7 100644 --- a/cmd-load-buffer.c +++ b/cmd-load-buffer.c @@ -83,7 +83,7 @@ cmd_load_buffer_done(__unused struct client *c, const char *path, int error, static enum cmd_retval cmd_load_buffer_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct cmd_load_buffer_data *cdata; struct client *c = cmd_find_client(item, NULL, 1); struct session *s = item->target.s; diff --git a/cmd-lock-server.c b/cmd-lock-server.c index 524fa451..937fb126 100644 --- a/cmd-lock-server.c +++ b/cmd-lock-server.c @@ -64,12 +64,12 @@ const struct cmd_entry cmd_lock_client_entry = { static enum cmd_retval cmd_lock_server_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct client *c; - if (self->entry == &cmd_lock_server_entry) + if (cmd_get_entry(self) == &cmd_lock_server_entry) server_lock(); - else if (self->entry == &cmd_lock_session_entry) + else if (cmd_get_entry(self) == &cmd_lock_session_entry) server_lock_session(item->target.s); else { if ((c = cmd_find_client(item, args_get(args, 't'), 0)) == NULL) diff --git a/cmd-move-window.c b/cmd-move-window.c index cb64d1e0..aaeb12b0 100644 --- a/cmd-move-window.c +++ b/cmd-move-window.c @@ -59,7 +59,7 @@ const struct cmd_entry cmd_link_window_entry = { static enum cmd_retval cmd_move_window_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); const char *tflag = args_get(args, 't'); struct session *src; struct session *dst; @@ -86,11 +86,11 @@ cmd_move_window_exec(struct cmd *self, struct cmdq_item *item) wl = item->source.wl; idx = item->target.idx; - kflag = args_has(self->args, 'k'); - dflag = args_has(self->args, 'd'); - sflag = args_has(self->args, 's'); + kflag = args_has(args, 'k'); + dflag = args_has(args, 'd'); + sflag = args_has(args, 's'); - if (args_has(self->args, 'a')) { + if (args_has(args, 'a')) { if ((idx = winlink_shuffle_up(dst, dst->curw)) == -1) return (CMD_RETURN_ERROR); } @@ -101,7 +101,7 @@ cmd_move_window_exec(struct cmd *self, struct cmdq_item *item) free(cause); return (CMD_RETURN_ERROR); } - if (self->entry == &cmd_move_window_entry) + if (cmd_get_entry(self) == &cmd_move_window_entry) server_unlink_window(src, wl); /* diff --git a/cmd-new-session.c b/cmd-new-session.c index 725448fd..73193e96 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -66,7 +66,7 @@ const struct cmd_entry cmd_has_session_entry = { static enum cmd_retval cmd_new_session_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct client *c = item->client; struct session *s, *as, *groupwith; struct environ *env; @@ -81,7 +81,7 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item) enum cmd_retval retval; struct cmd_find_state fs; - if (self->entry == &cmd_has_session_entry) { + if (cmd_get_entry(self) == &cmd_has_session_entry) { /* * cmd_find_target() will fail if the session cannot be found, * so always return success here. diff --git a/cmd-new-window.c b/cmd-new-window.c index 033d208a..5f1c11cb 100644 --- a/cmd-new-window.c +++ b/cmd-new-window.c @@ -51,7 +51,7 @@ const struct cmd_entry cmd_new_window_entry = { static enum cmd_retval cmd_new_window_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct cmd_find_state *current = &item->shared->current; struct spawn_context sc; struct client *c = cmd_find_client(item, NULL, 1); diff --git a/cmd-paste-buffer.c b/cmd-paste-buffer.c index baad707a..c79da012 100644 --- a/cmd-paste-buffer.c +++ b/cmd-paste-buffer.c @@ -47,7 +47,7 @@ const struct cmd_entry cmd_paste_buffer_entry = { static enum cmd_retval cmd_paste_buffer_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct window_pane *wp = item->target.wp; struct paste_buffer *pb; const char *sepstr, *bufname, *bufdata, *bufend, *line; diff --git a/cmd-pipe-pane.c b/cmd-pipe-pane.c index 084eafe5..2e898dbc 100644 --- a/cmd-pipe-pane.c +++ b/cmd-pipe-pane.c @@ -56,7 +56,7 @@ const struct cmd_entry cmd_pipe_pane_entry = { static enum cmd_retval cmd_pipe_pane_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct client *c = cmd_find_client(item, NULL, 1); struct window_pane *wp = item->target.wp; struct session *s = item->target.s; @@ -89,13 +89,13 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmdq_item *item) * * bind ^p pipep -o 'cat >>~/output' */ - if (args_has(self->args, 'o') && old_fd != -1) + if (args_has(args, 'o') && old_fd != -1) return (CMD_RETURN_NORMAL); /* What do we want to do? Neither -I or -O is -O. */ - if (args_has(self->args, 'I')) { + if (args_has(args, 'I')) { in = 1; - out = args_has(self->args, 'O'); + out = args_has(args, 'O'); } else { in = 0; out = 1; diff --git a/cmd-queue.c b/cmd-queue.c index 42e7d31b..892bd03b 100644 --- a/cmd-queue.c +++ b/cmd-queue.c @@ -209,11 +209,13 @@ cmdq_get_command(struct cmd_list *cmdlist, struct cmd_find_state *current, { struct cmdq_item *item, *first = NULL, *last = NULL; struct cmd *cmd; + const struct cmd_entry *entry; struct cmdq_shared *shared = NULL; - u_int group = 0; + u_int group, last_group = 0; - TAILQ_FOREACH(cmd, &cmdlist->list, qentry) { - if (cmd->group != group) { + cmd = cmd_list_first(cmdlist, &group); + while (cmd != NULL) { + if (group != last_group) { shared = xcalloc(1, sizeof *shared); if (current != NULL) cmd_find_copy_state(&shared->current, current); @@ -221,14 +223,15 @@ cmdq_get_command(struct cmd_list *cmdlist, struct cmd_find_state *current, cmd_find_clear_state(&shared->current, 0); if (m != NULL) memcpy(&shared->mouse, m, sizeof shared->mouse); - group = cmd->group; + last_group = group; } + entry = cmd_get_entry(cmd); item = xcalloc(1, sizeof *item); - xasprintf(&item->name, "[%s/%p]", cmd->entry->name, item); + xasprintf(&item->name, "[%s/%p]", entry->name, item); item->type = CMDQ_COMMAND; - item->group = cmd->group; + item->group = group; item->flags = flags; item->shared = shared; @@ -245,6 +248,8 @@ cmdq_get_command(struct cmd_list *cmdlist, struct cmd_find_state *current, if (last != NULL) last->next = item; last = item; + + cmd = cmd_list_next(cmd, &group); } return (first); } @@ -261,7 +266,7 @@ cmdq_find_flag(struct cmdq_item *item, struct cmd_find_state *fs, return (CMD_RETURN_NORMAL); } - value = args_get(item->cmd->args, flag->flag); + value = args_get(cmd_get_args(item->cmd), flag->flag); if (cmd_find_target(fs, item, value, flag->type, flag->flags) != 0) { cmd_find_clear_state(fs, 0); return (CMD_RETURN_ERROR); @@ -277,7 +282,7 @@ cmdq_fire_command(struct cmdq_item *item) const char *name = cmdq_name(c); struct cmdq_shared *shared = item->shared; struct cmd *cmd = item->cmd; - const struct cmd_entry *entry = cmd->entry; + const struct cmd_entry *entry = cmd_get_entry(cmd); enum cmd_retval retval; struct cmd_find_state *fsp, fs; int flags; @@ -528,8 +533,9 @@ cmdq_error(struct cmdq_item *item, const char *fmt, ...) struct client *c = item->client; struct cmd *cmd = item->cmd; va_list ap; - char *msg; - char *tmp; + char *msg, *tmp; + const char *file; + u_int line; va_start(ap, fmt); xvasprintf(&msg, fmt, ap); @@ -537,9 +543,10 @@ cmdq_error(struct cmdq_item *item, const char *fmt, ...) log_debug("%s: %s", __func__, msg); - if (c == NULL) - cfg_add_cause("%s:%u: %s", cmd->file, cmd->line, msg); - else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) { + if (c == NULL) { + cmd_get_source(cmd, &file, &line); + cfg_add_cause("%s:%u: %s", file, line, msg); + } else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) { if (~c->flags & CLIENT_UTF8) { tmp = msg; msg = utf8_sanitize(tmp); diff --git a/cmd-refresh-client.c b/cmd-refresh-client.c index b4c5e844..1becaaae 100644 --- a/cmd-refresh-client.c +++ b/cmd-refresh-client.c @@ -45,7 +45,7 @@ const struct cmd_entry cmd_refresh_client_entry = { static enum cmd_retval cmd_refresh_client_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct client *c; struct tty *tty; struct window *w; diff --git a/cmd-rename-session.c b/cmd-rename-session.c index 8385434a..67acb016 100644 --- a/cmd-rename-session.c +++ b/cmd-rename-session.c @@ -46,7 +46,7 @@ const struct cmd_entry cmd_rename_session_entry = { static enum cmd_retval cmd_rename_session_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct client *c = cmd_find_client(item, NULL, 1); struct session *s = item->target.s; char *newname; diff --git a/cmd-rename-window.c b/cmd-rename-window.c index 4d2ebb75..0f28c665 100644 --- a/cmd-rename-window.c +++ b/cmd-rename-window.c @@ -45,7 +45,7 @@ const struct cmd_entry cmd_rename_window_entry = { static enum cmd_retval cmd_rename_window_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct client *c = cmd_find_client(item, NULL, 1); struct session *s = item->target.s; struct winlink *wl = item->target.wl; diff --git a/cmd-resize-pane.c b/cmd-resize-pane.c index fd303cc1..7b9eaf88 100644 --- a/cmd-resize-pane.c +++ b/cmd-resize-pane.c @@ -49,7 +49,7 @@ const struct cmd_entry cmd_resize_pane_entry = { static enum cmd_retval cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct cmdq_shared *shared = item->shared; struct window_pane *wp = item->target.wp; struct winlink *wl = item->target.wl; diff --git a/cmd-resize-window.c b/cmd-resize-window.c index 9cc74e82..6ac2d235 100644 --- a/cmd-resize-window.c +++ b/cmd-resize-window.c @@ -46,7 +46,7 @@ const struct cmd_entry cmd_resize_window_entry = { static enum cmd_retval cmd_resize_window_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct winlink *wl = item->target.wl; struct window *w = wl->window; struct session *s = item->target.s; diff --git a/cmd-respawn-pane.c b/cmd-respawn-pane.c index 55544f93..3d4686f2 100644 --- a/cmd-respawn-pane.c +++ b/cmd-respawn-pane.c @@ -47,7 +47,7 @@ const struct cmd_entry cmd_respawn_pane_entry = { static enum cmd_retval cmd_respawn_pane_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct spawn_context sc; struct session *s = item->target.s; struct winlink *wl = item->target.wl; diff --git a/cmd-respawn-window.c b/cmd-respawn-window.c index 5f44db12..91269ff5 100644 --- a/cmd-respawn-window.c +++ b/cmd-respawn-window.c @@ -47,7 +47,7 @@ const struct cmd_entry cmd_respawn_window_entry = { static enum cmd_retval cmd_respawn_window_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct spawn_context sc; struct session *s = item->target.s; struct winlink *wl = item->target.wl; diff --git a/cmd-rotate-window.c b/cmd-rotate-window.c index cc661163..eaba2faf 100644 --- a/cmd-rotate-window.c +++ b/cmd-rotate-window.c @@ -43,6 +43,7 @@ const struct cmd_entry cmd_rotate_window_entry = { static enum cmd_retval cmd_rotate_window_exec(struct cmd *self, struct cmdq_item *item) { + struct args *args = cmd_get_args(self); struct cmd_find_state *current = &item->shared->current; struct winlink *wl = item->target.wl; struct window *w = wl->window; @@ -50,9 +51,9 @@ cmd_rotate_window_exec(struct cmd *self, struct cmdq_item *item) struct layout_cell *lc; u_int sx, sy, xoff, yoff; - window_push_zoom(w, args_has(self->args, 'Z')); + window_push_zoom(w, args_has(args, 'Z')); - if (args_has(self->args, 'D')) { + if (args_has(args, 'D')) { wp = TAILQ_LAST(&w->panes, window_panes); TAILQ_REMOVE(&w->panes, wp, entry); TAILQ_INSERT_HEAD(&w->panes, wp, entry); diff --git a/cmd-run-shell.c b/cmd-run-shell.c index 7ce6d55a..b828576a 100644 --- a/cmd-run-shell.c +++ b/cmd-run-shell.c @@ -89,7 +89,7 @@ cmd_run_shell_print(struct job *job, const char *msg) static enum cmd_retval cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct cmd_run_shell_data *cdata; struct client *c = cmd_find_client(item, NULL, 1); struct session *s = item->target.s; diff --git a/cmd-save-buffer.c b/cmd-save-buffer.c index 6830e5fc..f96e9849 100644 --- a/cmd-save-buffer.c +++ b/cmd-save-buffer.c @@ -73,7 +73,7 @@ cmd_save_buffer_done(__unused struct client *c, const char *path, int error, static enum cmd_retval cmd_save_buffer_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct client *c = cmd_find_client(item, NULL, 1); struct session *s = item->target.s; struct winlink *wl = item->target.wl; @@ -98,11 +98,11 @@ cmd_save_buffer_exec(struct cmd *self, struct cmdq_item *item) } bufdata = paste_buffer_data(pb, &bufsize); - if (self->entry == &cmd_show_buffer_entry) + if (cmd_get_entry(self) == &cmd_show_buffer_entry) path = xstrdup("-"); else path = format_single(item, args->argv[0], c, s, wl, wp); - if (args_has(self->args, 'a')) + if (args_has(args, 'a')) flags = O_APPEND; else flags = 0; diff --git a/cmd-select-layout.c b/cmd-select-layout.c index 775d32c5..b51ab4c1 100644 --- a/cmd-select-layout.c +++ b/cmd-select-layout.c @@ -71,7 +71,7 @@ const struct cmd_entry cmd_previous_layout_entry = { static enum cmd_retval cmd_select_layout_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct winlink *wl = item->target.wl; struct window *w = wl->window; struct window_pane *wp = item->target.wp; @@ -81,10 +81,10 @@ cmd_select_layout_exec(struct cmd *self, struct cmdq_item *item) server_unzoom_window(w); - next = self->entry == &cmd_next_layout_entry; + next = (cmd_get_entry(self) == &cmd_next_layout_entry); if (args_has(args, 'n')) next = 1; - previous = self->entry == &cmd_previous_layout_entry; + previous = (cmd_get_entry(self) == &cmd_previous_layout_entry); if (args_has(args, 'p')) previous = 1; diff --git a/cmd-select-pane.c b/cmd-select-pane.c index c63c7e61..376bf62e 100644 --- a/cmd-select-pane.c +++ b/cmd-select-pane.c @@ -83,7 +83,8 @@ cmd_select_pane_redraw(struct window *w) static enum cmd_retval cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); + const struct cmd_entry *entry = cmd_get_entry(self); struct cmd_find_state *current = &item->shared->current; struct client *c = cmd_find_client(item, NULL, 1); struct winlink *wl = item->target.wl; @@ -95,7 +96,7 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item) struct style *sy; struct options_entry *o; - if (self->entry == &cmd_last_pane_entry || args_has(args, 'l')) { + if (entry == &cmd_last_pane_entry || args_has(args, 'l')) { lastwp = w->last; if (lastwp == NULL && window_count_panes(w) == 2) { lastwp = TAILQ_PREV(w->active, window_panes, entry); @@ -106,12 +107,12 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item) cmdq_error(item, "no last pane"); return (CMD_RETURN_ERROR); } - if (args_has(self->args, 'e')) + if (args_has(args, 'e')) lastwp->flags &= ~PANE_INPUTOFF; - else if (args_has(self->args, 'd')) + else if (args_has(args, 'd')) lastwp->flags |= PANE_INPUTOFF; else { - if (window_push_zoom(w, args_has(self->args, 'Z'))) + if (window_push_zoom(w, args_has(args, 'Z'))) server_redraw_window(w); window_redraw_active_switch(w, lastwp); if (window_set_active_pane(w, lastwp, 1)) { @@ -146,7 +147,7 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item) return (CMD_RETURN_NORMAL); } - if (args_has(self->args, 'P') || args_has(self->args, 'g')) { + if (args_has(args, 'P') || args_has(args, 'g')) { if ((style = args_get(args, 'P')) != NULL) { o = options_set_style(wp->options, "window-style", 0, style); @@ -158,26 +159,26 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item) style); wp->flags |= (PANE_REDRAW|PANE_STYLECHANGED); } - if (args_has(self->args, 'g')) { + if (args_has(args, 'g')) { sy = options_get_style(wp->options, "window-style"); cmdq_print(item, "%s", style_tostring(sy)); } return (CMD_RETURN_NORMAL); } - if (args_has(self->args, 'L')) { + if (args_has(args, 'L')) { window_push_zoom(w, 1); wp = window_pane_find_left(wp); window_pop_zoom(w); - } else if (args_has(self->args, 'R')) { + } else if (args_has(args, 'R')) { window_push_zoom(w, 1); wp = window_pane_find_right(wp); window_pop_zoom(w); - } else if (args_has(self->args, 'U')) { + } else if (args_has(args, 'U')) { window_push_zoom(w, 1); wp = window_pane_find_up(wp); window_pop_zoom(w); - } else if (args_has(self->args, 'D')) { + } else if (args_has(args, 'D')) { window_push_zoom(w, 1); wp = window_pane_find_down(wp); window_pop_zoom(w); @@ -185,17 +186,17 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item) if (wp == NULL) return (CMD_RETURN_NORMAL); - if (args_has(self->args, 'e')) { + if (args_has(args, 'e')) { wp->flags &= ~PANE_INPUTOFF; return (CMD_RETURN_NORMAL); } - if (args_has(self->args, 'd')) { + if (args_has(args, 'd')) { wp->flags |= PANE_INPUTOFF; return (CMD_RETURN_NORMAL); } - if (args_has(self->args, 'T')) { - pane_title = format_single(item, args_get(self->args, 'T'), + if (args_has(args, 'T')) { + pane_title = format_single(item, args_get(args, 'T'), c, s, wl, wp); if (screen_set_title(&wp->base, pane_title)) server_status_window(wp->window); @@ -205,7 +206,7 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item) if (wp == w->active) return (CMD_RETURN_NORMAL); - if (window_push_zoom(w, args_has(self->args, 'Z'))) + if (window_push_zoom(w, args_has(args, 'Z'))) server_redraw_window(w); window_redraw_active_switch(w, wp); if (window_set_active_pane(w, wp, 1)) { diff --git a/cmd-select-window.c b/cmd-select-window.c index 54965e89..3d8d02de 100644 --- a/cmd-select-window.c +++ b/cmd-select-window.c @@ -84,23 +84,24 @@ const struct cmd_entry cmd_last_window_entry = { static enum cmd_retval cmd_select_window_exec(struct cmd *self, struct cmdq_item *item) { + struct args *args = cmd_get_args(self); struct cmd_find_state *current = &item->shared->current; struct winlink *wl = item->target.wl; struct session *s = item->target.s; int next, previous, last, activity; - next = self->entry == &cmd_next_window_entry; - if (args_has(self->args, 'n')) + next = (cmd_get_entry(self) == &cmd_next_window_entry); + if (args_has(args, 'n')) next = 1; - previous = self->entry == &cmd_previous_window_entry; - if (args_has(self->args, 'p')) + previous = (cmd_get_entry(self) == &cmd_previous_window_entry); + if (args_has(args, 'p')) previous = 1; - last = self->entry == &cmd_last_window_entry; - if (args_has(self->args, 'l')) + last = (cmd_get_entry(self) == &cmd_last_window_entry); + if (args_has(args, 'l')) last = 1; if (next || previous || last) { - activity = args_has(self->args, 'a'); + activity = args_has(args, 'a'); if (next) { if (session_next(s, activity) != 0) { cmdq_error(item, "no next window"); @@ -125,7 +126,7 @@ cmd_select_window_exec(struct cmd *self, struct cmdq_item *item) * 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 (args_has(args, 'T') && wl == s->curw) { if (session_last(s) != 0) { cmdq_error(item, "no last window"); return (-1); diff --git a/cmd-send-keys.c b/cmd-send-keys.c index 15967b0c..84996723 100644 --- a/cmd-send-keys.c +++ b/cmd-send-keys.c @@ -131,7 +131,7 @@ cmd_send_keys_inject_string(struct client *c, struct cmd_find_state *fs, static enum cmd_retval cmd_send_keys_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct client *c = cmd_find_client(item, NULL, 1); struct cmd_find_state *fs = &item->target; struct window_pane *wp = item->target.wp; @@ -181,7 +181,7 @@ cmd_send_keys_exec(struct cmd *self, struct cmdq_item *item) return (CMD_RETURN_NORMAL); } - if (self->entry == &cmd_send_prefix_entry) { + if (cmd_get_entry(self) == &cmd_send_prefix_entry) { if (args_has(args, '2')) key = options_get_number(s->options, "prefix2"); else diff --git a/cmd-set-buffer.c b/cmd-set-buffer.c index 96fdf450..0f3fffce 100644 --- a/cmd-set-buffer.c +++ b/cmd-set-buffer.c @@ -54,7 +54,7 @@ const struct cmd_entry cmd_delete_buffer_entry = { static enum cmd_retval cmd_set_buffer_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct paste_buffer *pb; char *bufdata, *cause; const char *bufname, *olddata; @@ -66,7 +66,7 @@ cmd_set_buffer_exec(struct cmd *self, struct cmdq_item *item) else pb = paste_get_name(bufname); - if (self->entry == &cmd_delete_buffer_entry) { + if (cmd_get_entry(self) == &cmd_delete_buffer_entry) { if (pb == NULL) pb = paste_get_top(&bufname); if (pb == NULL) { diff --git a/cmd-set-environment.c b/cmd-set-environment.c index 248f734a..72e40ded 100644 --- a/cmd-set-environment.c +++ b/cmd-set-environment.c @@ -46,7 +46,7 @@ const struct cmd_entry cmd_set_environment_entry = { static enum cmd_retval cmd_set_environment_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct environ *env; const char *name, *value, *target; @@ -65,7 +65,7 @@ cmd_set_environment_exec(struct cmd *self, struct cmdq_item *item) else value = args->argv[1]; - if (args_has(self->args, 'g')) + if (args_has(args, 'g')) env = global_environ; else { if (item->target.s == NULL) { @@ -79,13 +79,13 @@ cmd_set_environment_exec(struct cmd *self, struct cmdq_item *item) env = item->target.s->environ; } - if (args_has(self->args, 'u')) { + if (args_has(args, 'u')) { if (value != NULL) { cmdq_error(item, "can't specify a value with -u"); return (CMD_RETURN_ERROR); } environ_unset(env, name); - } else if (args_has(self->args, 'r')) { + } else if (args_has(args, 'r')) { if (value != NULL) { cmdq_error(item, "can't specify a value with -r"); return (CMD_RETURN_ERROR); diff --git a/cmd-set-option.c b/cmd-set-option.c index d466093e..041f109b 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -81,7 +81,7 @@ const struct cmd_entry cmd_set_hook_entry = { static enum cmd_retval cmd_set_option_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); int append = args_has(args, 'a'); struct cmd_find_state *fs = &item->target; struct client *c, *loop; @@ -96,14 +96,14 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item) int scope; struct style *sy; - window = (self->entry == &cmd_set_window_option_entry); + window = (cmd_get_entry(self) == &cmd_set_window_option_entry); /* Expand argument. */ c = cmd_find_client(item, NULL, 1); argument = format_single(item, args->argv[0], c, s, wl, NULL); /* If set-hook -R, fire the hook straight away. */ - if (self->entry == &cmd_set_hook_entry && args_has(args, 'R')) { + if (cmd_get_entry(self) == &cmd_set_hook_entry && args_has(args, 'R')) { notify_hook(item, argument); free(argument); return (CMD_RETURN_NORMAL); @@ -288,7 +288,7 @@ cmd_set_option_set(struct cmd *self, struct cmdq_item *item, struct options *oo, struct options_entry *parent, const char *value) { const struct options_table_entry *oe; - struct args *args = self->args; + struct args *args = cmd_get_args(self); int append = args_has(args, 'a'); struct options_entry *o; long long number; diff --git a/cmd-show-environment.c b/cmd-show-environment.c index 0d2f7dd9..be6209dd 100644 --- a/cmd-show-environment.c +++ b/cmd-show-environment.c @@ -69,7 +69,7 @@ static void cmd_show_environment_print(struct cmd *self, struct cmdq_item *item, struct environ_entry *envent) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); char *escaped; if (!args_has(args, 'h') && (envent->flags & ENVIRON_HIDDEN)) @@ -77,7 +77,7 @@ cmd_show_environment_print(struct cmd *self, struct cmdq_item *item, if (args_has(args, 'h') && (~envent->flags & ENVIRON_HIDDEN)) return; - if (!args_has(self->args, 's')) { + if (!args_has(args, 's')) { if (envent->value != NULL) cmdq_print(item, "%s=%s", envent->name, envent->value); else @@ -97,7 +97,7 @@ cmd_show_environment_print(struct cmd *self, struct cmdq_item *item, static enum cmd_retval cmd_show_environment_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct environ *env; struct environ_entry *envent; const char *target; @@ -109,7 +109,7 @@ cmd_show_environment_exec(struct cmd *self, struct cmdq_item *item) } } - if (args_has(self->args, 'g')) + if (args_has(args, 'g')) env = global_environ; else { if (item->target.s == NULL) { diff --git a/cmd-show-messages.c b/cmd-show-messages.c index e4b51fa8..cedf1093 100644 --- a/cmd-show-messages.c +++ b/cmd-show-messages.c @@ -69,7 +69,7 @@ cmd_show_messages_terminals(struct cmdq_item *item, int blank) static enum cmd_retval cmd_show_messages_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct client *c; struct message_entry *msg; char *tim; diff --git a/cmd-show-options.c b/cmd-show-options.c index fe3cddc5..c1f9fd56 100644 --- a/cmd-show-options.c +++ b/cmd-show-options.c @@ -77,7 +77,7 @@ const struct cmd_entry cmd_show_hooks_entry = { static enum cmd_retval cmd_show_options_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct cmd_find_state *fs = &item->target; struct client *c = cmd_find_client(item, NULL, 1); struct session *s = item->target.s; @@ -87,7 +87,7 @@ cmd_show_options_exec(struct cmd *self, struct cmdq_item *item) int window, idx, ambiguous, parent, scope; struct options_entry *o; - window = (self->entry == &cmd_show_window_options_entry); + window = (cmd_get_entry(self) == &cmd_show_window_options_entry); if (args->argc == 0) { scope = options_scope_from_flags(args, window, fs, &oo, &cause); @@ -143,6 +143,7 @@ static void cmd_show_options_print(struct cmd *self, struct cmdq_item *item, struct options_entry *o, int idx, int parent) { + struct args *args = cmd_get_args(self); struct options_array_item *a; const char *name = options_name(o); char *value, *tmp = NULL, *escaped; @@ -154,7 +155,7 @@ cmd_show_options_print(struct cmd *self, struct cmdq_item *item, if (options_isarray(o)) { a = options_array_first(o); if (a == NULL) { - if (!args_has(self->args, 'v')) + if (!args_has(args, 'v')) cmdq_print(item, "%s", name); return; } @@ -169,7 +170,7 @@ cmd_show_options_print(struct cmd *self, struct cmdq_item *item, } value = options_tostring(o, idx, 0); - if (args_has(self->args, 'v')) + if (args_has(args, 'v')) cmdq_print(item, "%s", value); else if (options_isstring(o)) { escaped = args_escape(value); @@ -193,6 +194,7 @@ static enum cmd_retval cmd_show_options_all(struct cmd *self, struct cmdq_item *item, int scope, struct options *oo) { + struct args *args = cmd_get_args(self); const struct options_table_entry *oe; struct options_entry *o; struct options_array_item *a; @@ -210,16 +212,16 @@ cmd_show_options_all(struct cmd *self, struct cmdq_item *item, int scope, if (~oe->scope & scope) continue; - if ((self->entry != &cmd_show_hooks_entry && - !args_has(self->args, 'H') && + if ((cmd_get_entry(self) != &cmd_show_hooks_entry && + !args_has(args, 'H') && (oe->flags & OPTIONS_TABLE_IS_HOOK)) || - (self->entry == &cmd_show_hooks_entry && + (cmd_get_entry(self) == &cmd_show_hooks_entry && (~oe->flags & OPTIONS_TABLE_IS_HOOK))) continue; o = options_get_only(oo, oe->name); if (o == NULL) { - if (!args_has(self->args, 'A')) + if (!args_has(args, 'A')) continue; o = options_get(oo, oe->name); if (o == NULL) @@ -231,7 +233,7 @@ cmd_show_options_all(struct cmd *self, struct cmdq_item *item, int scope, if (!options_isarray(o)) cmd_show_options_print(self, item, o, -1, parent); else if ((a = options_array_first(o)) == NULL) { - if (!args_has(self->args, 'v')) { + if (!args_has(args, 'v')) { name = options_name(o); if (parent) cmdq_print(item, "%s*", name); diff --git a/cmd-source-file.c b/cmd-source-file.c index 46dc6d94..50571874 100644 --- a/cmd-source-file.c +++ b/cmd-source-file.c @@ -123,7 +123,7 @@ cmd_source_file_add(struct cmd_source_file_data *cdata, const char *path) static enum cmd_retval cmd_source_file_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct cmd_source_file_data *cdata; struct client *c = item->client; enum cmd_retval retval = CMD_RETURN_NORMAL; diff --git a/cmd-split-window.c b/cmd-split-window.c index c1c8be25..6a9210a7 100644 --- a/cmd-split-window.c +++ b/cmd-split-window.c @@ -53,7 +53,7 @@ const struct cmd_entry cmd_split_window_entry = { static enum cmd_retval cmd_split_window_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct cmd_find_state *current = &item->shared->current; struct spawn_context sc; struct client *c = cmd_find_client(item, NULL, 1); diff --git a/cmd-swap-pane.c b/cmd-swap-pane.c index 3e0e6e60..60be63dc 100644 --- a/cmd-swap-pane.c +++ b/cmd-swap-pane.c @@ -45,7 +45,7 @@ const struct cmd_entry cmd_swap_pane_entry = { static enum cmd_retval cmd_swap_pane_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); struct window *src_w, *dst_w; struct window_pane *tmp_wp, *src_wp, *dst_wp; struct layout_cell *src_lc, *dst_lc; diff --git a/cmd-swap-window.c b/cmd-swap-window.c index 0c15479d..9ed1e8f1 100644 --- a/cmd-swap-window.c +++ b/cmd-swap-window.c @@ -45,6 +45,7 @@ const struct cmd_entry cmd_swap_window_entry = { static enum cmd_retval cmd_swap_window_exec(struct cmd *self, struct cmdq_item *item) { + struct args *args = cmd_get_args(self); struct session *src, *dst; struct session_group *sg_src, *sg_dst; struct winlink *wl_src, *wl_dst; @@ -77,7 +78,7 @@ cmd_swap_window_exec(struct cmd *self, struct cmdq_item *item) wl_src->window = w_dst; TAILQ_INSERT_TAIL(&w_dst->winlinks, wl_src, wentry); - if (args_has(self->args, 'd')) { + if (args_has(args, 'd')) { session_select(dst, wl_dst->idx); if (src != dst) session_select(src, wl_src->idx); diff --git a/cmd-switch-client.c b/cmd-switch-client.c index cf84c319..def61a73 100644 --- a/cmd-switch-client.c +++ b/cmd-switch-client.c @@ -47,7 +47,7 @@ const struct cmd_entry cmd_switch_client_entry = { static enum cmd_retval cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); const char *tflag = args_get(args, 't'); enum cmd_find_type type; int flags; @@ -115,7 +115,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item) return (CMD_RETURN_NORMAL); if (wl != NULL && wp != NULL) { w = wl->window; - if (window_push_zoom(w, args_has(self->args, 'Z'))) + if (window_push_zoom(w, args_has(args, 'Z'))) server_redraw_window(w); window_redraw_active_switch(w, wp); window_set_active_pane(w, wp, 1); diff --git a/cmd-unbind-key.c b/cmd-unbind-key.c index 69141346..4b9f39a6 100644 --- a/cmd-unbind-key.c +++ b/cmd-unbind-key.c @@ -28,15 +28,12 @@ static enum cmd_retval cmd_unbind_key_exec(struct cmd *, struct cmdq_item *); -static enum cmd_retval cmd_unbind_key_mode_table(struct cmd *, - struct cmdq_item *, key_code); - const struct cmd_entry cmd_unbind_key_entry = { .name = "unbind-key", .alias = "unbind", - .args = { "ant:T:", 0, 1 }, - .usage = "[-an] [-t mode-table] [-T key-table] key", + .args = { "anT:", 0, 1 }, + .usage = "[-an] [-T key-table] key", .flags = CMD_AFTERHOOK, .exec = cmd_unbind_key_exec @@ -45,7 +42,7 @@ const struct cmd_entry cmd_unbind_key_entry = { static enum cmd_retval cmd_unbind_key_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); key_code key; const char *tablename; @@ -67,9 +64,6 @@ cmd_unbind_key_exec(struct cmd *self, struct cmdq_item *item) key = KEYC_UNKNOWN; } - if (args_has(args, 't')) - return (cmd_unbind_key_mode_table(self, item, key)); - if (key == KEYC_UNKNOWN) { tablename = args_get(args, 'T'); if (tablename == NULL) { @@ -98,35 +92,3 @@ cmd_unbind_key_exec(struct cmd *self, struct cmdq_item *item) key_bindings_remove(tablename, key); return (CMD_RETURN_NORMAL); } - -static enum cmd_retval -cmd_unbind_key_mode_table(struct cmd *self, struct cmdq_item *item, - key_code key) -{ - struct args *args = self->args; - const char *tablename; - const struct mode_key_table *mtab; - struct mode_key_binding *mbind, mtmp; - - tablename = args_get(args, 't'); - if ((mtab = mode_key_findtable(tablename)) == NULL) { - cmdq_error(item, "unknown key table: %s", tablename); - return (CMD_RETURN_ERROR); - } - - if (key == KEYC_UNKNOWN) { - while (!RB_EMPTY(mtab->tree)) { - mbind = RB_ROOT(mtab->tree); - RB_REMOVE(mode_key_tree, mtab->tree, mbind); - free(mbind); - } - return (CMD_RETURN_NORMAL); - } - - mtmp.key = key; - if ((mbind = RB_FIND(mode_key_tree, mtab->tree, &mtmp)) != NULL) { - RB_REMOVE(mode_key_tree, mtab->tree, mbind); - free(mbind); - } - return (CMD_RETURN_NORMAL); -} diff --git a/cmd-wait-for.c b/cmd-wait-for.c index 4f438a7f..a5803ca5 100644 --- a/cmd-wait-for.c +++ b/cmd-wait-for.c @@ -120,7 +120,7 @@ cmd_wait_for_remove(struct wait_channel *wc) static enum cmd_retval cmd_wait_for_exec(struct cmd *self, struct cmdq_item *item) { - struct args *args = self->args; + struct args *args = cmd_get_args(self); const char *name = args->argv[0]; struct wait_channel *wc, wc0; diff --git a/cmd.c b/cmd.c index 52cf5af1..d0a8c267 100644 --- a/cmd.c +++ b/cmd.c @@ -207,8 +207,27 @@ const struct cmd_entry *cmd_table[] = { NULL }; +/* Instance of a command. */ +struct cmd { + const struct cmd_entry *entry; + struct args *args; + u_int group; + + char *file; + u_int line; + + char *alias; + int argc; + char **argv; + + TAILQ_ENTRY(cmd) qentry; +}; +TAILQ_HEAD(cmds, cmd); + +/* Next group number for new command list. */ static u_int cmd_list_next_group = 1; +/* Log an argument vector. */ void printflike(3, 4) cmd_log_argv(int argc, char **argv, const char *fmt, ...) { @@ -225,6 +244,7 @@ cmd_log_argv(int argc, char **argv, const char *fmt, ...) free(prefix); } +/* Prepend to an argument vector. */ void cmd_prepend_argv(int *argc, char ***argv, char *arg) { @@ -241,6 +261,7 @@ cmd_prepend_argv(int *argc, char ***argv, char *arg) (*argc)++; } +/* Append to an argument vector. */ void cmd_append_argv(int *argc, char ***argv, char *arg) { @@ -248,6 +269,7 @@ cmd_append_argv(int *argc, char ***argv, char *arg) (*argv)[(*argc)++] = xstrdup(arg); } +/* Pack an argument vector up into a buffer. */ int cmd_pack_argv(int argc, char **argv, char *buf, size_t len) { @@ -270,6 +292,7 @@ cmd_pack_argv(int argc, char **argv, char *buf, size_t len) return (0); } +/* Unpack an argument vector from a packed buffer. */ int cmd_unpack_argv(char *buf, size_t len, int argc, char ***argv) { @@ -298,6 +321,7 @@ cmd_unpack_argv(char *buf, size_t len, int argc, char ***argv) return (0); } +/* Copy an argument vector, ensuring it is terminated by NULL. */ char ** cmd_copy_argv(int argc, char **argv) { @@ -314,6 +338,7 @@ cmd_copy_argv(int argc, char **argv) return (new_argv); } +/* Free an argument vector. */ void cmd_free_argv(int argc, char **argv) { @@ -326,6 +351,7 @@ cmd_free_argv(int argc, char **argv) free(argv); } +/* Convert argument vector to a string. */ char * cmd_stringify_argv(int argc, char **argv) { @@ -352,6 +378,31 @@ cmd_stringify_argv(int argc, char **argv) return (buf); } +/* Get entry for command. */ +const struct cmd_entry * +cmd_get_entry(struct cmd *cmd) +{ + return (cmd->entry); +} + +/* Get arguments for command. */ +struct args * +cmd_get_args(struct cmd *cmd) +{ + return (cmd->args); +} + +/* Get file and line for command. */ +void +cmd_get_source(struct cmd *cmd, const char **file, u_int *line) +{ + if (file != NULL) + *file = cmd->file; + if (line != NULL) + *line = cmd->line; +} + +/* Look for an alias for a command. */ char * cmd_get_alias(const char *name) { @@ -382,6 +433,7 @@ cmd_get_alias(const char *name) return (NULL); } +/* Look up a command entry by name. */ static const struct cmd_entry * cmd_find(const char *name, char **cause) { @@ -431,6 +483,7 @@ ambiguous: return (NULL); } +/* Parse a single command from an argument vector. */ struct cmd * cmd_parse(int argc, char **argv, const char *file, u_int line, char **cause) { @@ -479,6 +532,7 @@ usage: return (NULL); } +/* Free a command. */ void cmd_free(struct cmd *cmd) { @@ -491,6 +545,7 @@ cmd_free(struct cmd *cmd) free(cmd); } +/* Get a command as a string. */ char * cmd_print(struct cmd *cmd) { @@ -506,6 +561,7 @@ cmd_print(struct cmd *cmd) return (out); } +/* Create a new command list. */ struct cmd_list * cmd_list_new(void) { @@ -514,29 +570,33 @@ cmd_list_new(void) cmdlist = xcalloc(1, sizeof *cmdlist); cmdlist->references = 1; cmdlist->group = cmd_list_next_group++; - TAILQ_INIT(&cmdlist->list); + cmdlist->list = xcalloc(1, sizeof *cmdlist->list); + TAILQ_INIT(cmdlist->list); return (cmdlist); } +/* Append a command to a command list. */ void cmd_list_append(struct cmd_list *cmdlist, struct cmd *cmd) { cmd->group = cmdlist->group; - TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry); + TAILQ_INSERT_TAIL(cmdlist->list, cmd, qentry); } +/* Move all commands from one command list to another */ void cmd_list_move(struct cmd_list *cmdlist, struct cmd_list *from) { struct cmd *cmd, *cmd1; - TAILQ_FOREACH_SAFE(cmd, &from->list, qentry, cmd1) { - TAILQ_REMOVE(&from->list, cmd, qentry); - TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry); + TAILQ_FOREACH_SAFE(cmd, from->list, qentry, cmd1) { + TAILQ_REMOVE(from->list, cmd, qentry); + TAILQ_INSERT_TAIL(cmdlist->list, cmd, qentry); } cmdlist->group = cmd_list_next_group++; } +/* Free a command list. */ void cmd_list_free(struct cmd_list *cmdlist) { @@ -545,14 +605,15 @@ cmd_list_free(struct cmd_list *cmdlist) if (--cmdlist->references != 0) return; - TAILQ_FOREACH_SAFE(cmd, &cmdlist->list, qentry, cmd1) { - TAILQ_REMOVE(&cmdlist->list, cmd, qentry); + TAILQ_FOREACH_SAFE(cmd, cmdlist->list, qentry, cmd1) { + TAILQ_REMOVE(cmdlist->list, cmd, qentry); cmd_free(cmd); } - + free(cmdlist->list); free(cmdlist); } +/* Get a command list as a string. */ char * cmd_list_print(struct cmd_list *cmdlist, int escaped) { @@ -563,7 +624,7 @@ cmd_list_print(struct cmd_list *cmdlist, int escaped) len = 1; buf = xcalloc(1, len); - TAILQ_FOREACH(cmd, &cmdlist->list, qentry) { + TAILQ_FOREACH(cmd, cmdlist->list, qentry) { this = cmd_print(cmd); len += strlen(this) + 4; @@ -583,6 +644,54 @@ cmd_list_print(struct cmd_list *cmdlist, int escaped) return (buf); } +/* Get first command in list. */ +struct cmd * +cmd_list_first(struct cmd_list *cmdlist, u_int *group) +{ + struct cmd *cmd; + + cmd = TAILQ_FIRST(cmdlist->list); + if (cmd != NULL && group != NULL) + *group = cmd->group; + return (cmd); +} + +/* Get next command in list. */ +struct cmd * +cmd_list_next(struct cmd *cmd, u_int *group) +{ + cmd = TAILQ_NEXT(cmd, qentry); + if (cmd != NULL && group != NULL) + *group = cmd->group; + return (cmd); +} + +/* Do all of the commands in this command list have this flag? */ +int +cmd_list_all_have(struct cmd_list *cmdlist, int flag) +{ + struct cmd *cmd; + + TAILQ_FOREACH(cmd, cmdlist->list, qentry) { + if (~cmd->entry->flags & flag) + return (0); + } + return (1); +} + +/* Do any of the commands in this command list have this flag? */ +int +cmd_list_any_have(struct cmd_list *cmdlist, int flag) +{ + struct cmd *cmd; + + TAILQ_FOREACH(cmd, cmdlist->list, qentry) { + if (cmd->entry->flags & flag) + return (1); + } + return (0); +} + /* Adjust current mouse position for a pane. */ int cmd_mouse_at(struct window_pane *wp, struct mouse_event *m, u_int *xp, diff --git a/format.c b/format.c index efbf5c62..2d8522c9 100644 --- a/format.c +++ b/format.c @@ -1128,8 +1128,10 @@ format_create_add_item(struct format_tree *ft, struct cmdq_item *item) struct window_pane *wp; u_int x, y; - if (item->cmd != NULL) - format_add(ft, "command", "%s", item->cmd->entry->name); + if (item->cmd != NULL) { + format_add(ft, "command", "%s", + cmd_get_entry (item->cmd)->name); + } if (item->shared == NULL) return; diff --git a/key-bindings.c b/key-bindings.c index 3c6f8ff6..b76589ce 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -537,19 +537,13 @@ struct cmdq_item * key_bindings_dispatch(struct key_binding *bd, struct cmdq_item *item, struct client *c, struct mouse_event *m, struct cmd_find_state *fs) { - struct cmd *cmd; struct cmdq_item *new_item; int readonly; if (c == NULL || (~c->flags & CLIENT_READONLY)) readonly = 1; - else { - readonly = 1; - TAILQ_FOREACH(cmd, &bd->cmdlist->list, qentry) { - if (~cmd->entry->flags & CMD_READONLY) - readonly = 0; - } - } + else + readonly = cmd_list_all_have(bd->cmdlist, CMD_READONLY); if (!readonly) new_item = cmdq_get_callback(key_bindings_read_only, NULL); else { diff --git a/tmux.h b/tmux.h index 8f8640bf..539309da 100644 --- a/tmux.h +++ b/tmux.h @@ -39,9 +39,11 @@ extern char **environ; struct args; struct args_value; struct client; +struct cmd; struct cmd_find_state; struct cmdq_item; struct cmdq_list; +struct cmds; struct environ; struct format_job_tree; struct format_tree; @@ -50,8 +52,8 @@ struct job; struct mode_tree_data; struct mouse_event; struct options; -struct options_entry; struct options_array_item; +struct options_entry; struct session; struct tmuxpeer; struct tmuxproc; @@ -1335,27 +1337,11 @@ struct cmd_find_state { #define CMD_FIND_EXACT_WINDOW 0x20 #define CMD_FIND_CANFAIL 0x40 -/* Command and list of commands. */ -struct cmd { - const struct cmd_entry *entry; - struct args *args; - u_int group; - - char *file; - u_int line; - - char *alias; - int argc; - char **argv; - - TAILQ_ENTRY(cmd) qentry; -}; -TAILQ_HEAD(cmds, cmd); - +/* List of commands. */ struct cmd_list { - int references; - u_int group; - struct cmds list; + int references; + u_int group; + struct cmds *list; }; /* Command return values. */ @@ -2102,6 +2088,7 @@ int cmd_find_from_mouse(struct cmd_find_state *, int cmd_find_from_nothing(struct cmd_find_state *, int); /* cmd.c */ +extern const struct cmd_entry *cmd_table[]; void printflike(3, 4) cmd_log_argv(int, char **, const char *, ...); void cmd_prepend_argv(int *, char ***, char *); void cmd_append_argv(int *, char ***, char *); @@ -2111,16 +2098,27 @@ char **cmd_copy_argv(int, char **); void cmd_free_argv(int, char **); char *cmd_stringify_argv(int, char **); char *cmd_get_alias(const char *); +const struct cmd_entry *cmd_get_entry(struct cmd *); +struct args *cmd_get_args(struct cmd *); +void cmd_get_source(struct cmd *, const char **, u_int *); struct cmd *cmd_parse(int, char **, const char *, u_int, char **); void cmd_free(struct cmd *); char *cmd_print(struct cmd *); +struct cmd_list *cmd_list_new(void); +void cmd_list_append(struct cmd_list *, struct cmd *); +void cmd_list_move(struct cmd_list *, struct cmd_list *); +void cmd_list_free(struct cmd_list *); +char *cmd_list_print(struct cmd_list *, int); +struct cmd *cmd_list_first(struct cmd_list *, u_int *); +struct cmd *cmd_list_next(struct cmd *, u_int *); +int cmd_list_all_have(struct cmd_list *, int); +int cmd_list_any_have(struct cmd_list *, int); int cmd_mouse_at(struct window_pane *, struct mouse_event *, u_int *, u_int *, int); struct winlink *cmd_mouse_window(struct mouse_event *, struct session **); struct window_pane *cmd_mouse_pane(struct mouse_event *, struct session **, struct winlink **); char *cmd_template_replace(const char *, const char *, int); -extern const struct cmd_entry *cmd_table[]; /* cmd-attach-session.c */ enum cmd_retval cmd_attach_session(struct cmdq_item *, const char *, int, int, @@ -2136,13 +2134,6 @@ struct cmd_parse_result *cmd_parse_from_buffer(const void *, size_t, struct cmd_parse_result *cmd_parse_from_arguments(int, char **, struct cmd_parse_input *); -/* cmd-list.c */ -struct cmd_list *cmd_list_new(void); -void cmd_list_append(struct cmd_list *, struct cmd *); -void cmd_list_move(struct cmd_list *, struct cmd_list *); -void cmd_list_free(struct cmd_list *); -char *cmd_list_print(struct cmd_list *, int); - /* cmd-queue.c */ struct cmdq_item *cmdq_get_command(struct cmd_list *, struct cmd_find_state *, struct mouse_event *, int);