From ecf90ed7d78255057a3c58be0cb9ce82fd7e2f57 Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 4 Oct 2024 07:03:08 +0000 Subject: [PATCH] Rework of copy mode commands ("send-keys -X") to parse the arguments so that flags may be detected propertly rather than just looking for strings ("-O" and so on). Also add -C and -P flags to the copy commands: -C prevents the commands from sending the text to the clipboard and -P prevents them from adding the text as a paste buffer. Note some of the default key bindings change to add "--" and any similar custom key bindings using "send-keys -X" may need a similar change. GitHub issue 4153. --- usr.bin/tmux/key-bindings.c | 36 +-- usr.bin/tmux/tmux.1 | 28 ++- usr.bin/tmux/window-copy.c | 457 ++++++++++++++++-------------------- 3 files changed, 245 insertions(+), 276 deletions(-) diff --git a/usr.bin/tmux/key-bindings.c b/usr.bin/tmux/key-bindings.c index c900084c726..5f14aa3748f 100644 --- a/usr.bin/tmux/key-bindings.c +++ b/usr.bin/tmux/key-bindings.c @@ -1,4 +1,4 @@ -/* $OpenBSD: key-bindings.c,v 1.149 2024/08/21 05:03:13 nicm Exp $ */ +/* $OpenBSD: key-bindings.c,v 1.150 2024/10/04 07:03:08 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -49,7 +49,7 @@ " '#{?#{m/r:(copy|view)-mode,#{pane_mode}},Go To Top,}' '<' {send -X history-top}" \ " '#{?#{m/r:(copy|view)-mode,#{pane_mode}},Go To Bottom,}' '>' {send -X history-bottom}" \ " ''" \ - " '#{?mouse_word,Search For #[underscore]#{=/9/...:mouse_word},}' 'C-r' {if -F '#{?#{m/r:(copy|view)-mode,#{pane_mode}},0,1}' 'copy-mode -t='; send -Xt= search-backward \"#{q:mouse_word}\"}" \ + " '#{?mouse_word,Search For #[underscore]#{=/9/...:mouse_word},}' 'C-r' {if -F '#{?#{m/r:(copy|view)-mode,#{pane_mode}},0,1}' 'copy-mode -t='; send -Xt= search-backward -- \"#{q:mouse_word}\"}" \ " '#{?mouse_word,Type #[underscore]#{=/9/...:mouse_word},}' 'C-y' {copy-mode -q; send-keys -l -- \"#{q:mouse_word}\"}" \ " '#{?mouse_word,Copy #[underscore]#{=/9/...:mouse_word},}' 'c' {copy-mode -q; set-buffer -- \"#{q:mouse_word}\"}" \ " '#{?mouse_line,Copy Line,}' 'l' {copy-mode -q; set-buffer -- \"#{q:mouse_line}\"}" \ @@ -489,26 +489,26 @@ key_bindings_init(void) "bind -Tcopy-mode C-k { send -X copy-pipe-end-of-line-and-cancel }", "bind -Tcopy-mode C-n { send -X cursor-down }", "bind -Tcopy-mode C-p { send -X cursor-up }", - "bind -Tcopy-mode C-r { command-prompt -T search -ip'(search up)' -I'#{pane_search_string}' { send -X search-backward-incremental '%%' } }", - "bind -Tcopy-mode C-s { command-prompt -T search -ip'(search down)' -I'#{pane_search_string}' { send -X search-forward-incremental '%%' } }", + "bind -Tcopy-mode C-r { command-prompt -T search -ip'(search up)' -I'#{pane_search_string}' { send -X search-backward-incremental -- '%%' } }", + "bind -Tcopy-mode C-s { command-prompt -T search -ip'(search down)' -I'#{pane_search_string}' { send -X search-forward-incremental -- '%%' } }", "bind -Tcopy-mode C-v { send -X page-down }", "bind -Tcopy-mode C-w { send -X copy-pipe-and-cancel }", "bind -Tcopy-mode Escape { send -X cancel }", "bind -Tcopy-mode Space { send -X page-down }", "bind -Tcopy-mode , { send -X jump-reverse }", "bind -Tcopy-mode \\; { send -X jump-again }", - "bind -Tcopy-mode F { command-prompt -1p'(jump backward)' { send -X jump-backward '%%' } }", + "bind -Tcopy-mode F { command-prompt -1p'(jump backward)' { send -X jump-backward -- '%%' } }", "bind -Tcopy-mode N { send -X search-reverse }", "bind -Tcopy-mode P { send -X toggle-position }", "bind -Tcopy-mode R { send -X rectangle-toggle }", - "bind -Tcopy-mode T { command-prompt -1p'(jump to backward)' { send -X jump-to-backward '%%' } }", + "bind -Tcopy-mode T { command-prompt -1p'(jump to backward)' { send -X jump-to-backward -- '%%' } }", "bind -Tcopy-mode X { send -X set-mark }", - "bind -Tcopy-mode f { command-prompt -1p'(jump forward)' { send -X jump-forward '%%' } }", - "bind -Tcopy-mode g { command-prompt -p'(goto line)' { send -X goto-line '%%' } }", + "bind -Tcopy-mode f { command-prompt -1p'(jump forward)' { send -X jump-forward -- '%%' } }", + "bind -Tcopy-mode g { command-prompt -p'(goto line)' { send -X goto-line -- '%%' } }", "bind -Tcopy-mode n { send -X search-again }", "bind -Tcopy-mode q { send -X cancel }", "bind -Tcopy-mode r { send -X refresh-from-pane }", - "bind -Tcopy-mode t { command-prompt -1p'(jump to forward)' { send -X jump-to-forward '%%' } }", + "bind -Tcopy-mode t { command-prompt -1p'(jump to forward)' { send -X jump-to-forward -- '%%' } }", "bind -Tcopy-mode Home { send -X start-of-line }", "bind -Tcopy-mode End { send -X end-of-line }", "bind -Tcopy-mode MouseDown1Pane select-pane", @@ -553,8 +553,8 @@ key_bindings_init(void) "bind -Tcopy-mode C-Down { send -X scroll-down }", /* Copy mode (vi) keys. */ - "bind -Tcopy-mode-vi '#' { send -FX search-backward '#{copy_cursor_word}' }", - "bind -Tcopy-mode-vi * { send -FX search-forward '#{copy_cursor_word}' }", + "bind -Tcopy-mode-vi '#' { send -FX search-backward -- '#{copy_cursor_word}' }", + "bind -Tcopy-mode-vi * { send -FX search-forward -- '#{copy_cursor_word}' }", "bind -Tcopy-mode-vi C-c { send -X cancel }", "bind -Tcopy-mode-vi C-d { send -X halfpage-down }", "bind -Tcopy-mode-vi C-e { send -X scroll-down }", @@ -570,7 +570,7 @@ key_bindings_init(void) "bind -Tcopy-mode-vi Space { send -X begin-selection }", "bind -Tcopy-mode-vi '$' { send -X end-of-line }", "bind -Tcopy-mode-vi , { send -X jump-reverse }", - "bind -Tcopy-mode-vi / { command-prompt -T search -p'(search down)' { send -X search-forward '%%' } }", + "bind -Tcopy-mode-vi / { command-prompt -T search -p'(search down)' { send -X search-forward -- '%%' } }", "bind -Tcopy-mode-vi 0 { send -X start-of-line }", "bind -Tcopy-mode-vi 1 { command-prompt -Np'(repeat)' -I1 { send -N '%%' } }", "bind -Tcopy-mode-vi 2 { command-prompt -Np'(repeat)' -I2 { send -N '%%' } }", @@ -581,14 +581,14 @@ key_bindings_init(void) "bind -Tcopy-mode-vi 7 { command-prompt -Np'(repeat)' -I7 { send -N '%%' } }", "bind -Tcopy-mode-vi 8 { command-prompt -Np'(repeat)' -I8 { send -N '%%' } }", "bind -Tcopy-mode-vi 9 { command-prompt -Np'(repeat)' -I9 { send -N '%%' } }", - "bind -Tcopy-mode-vi : { command-prompt -p'(goto line)' { send -X goto-line '%%' } }", + "bind -Tcopy-mode-vi : { command-prompt -p'(goto line)' { send -X goto-line -- '%%' } }", "bind -Tcopy-mode-vi \\; { send -X jump-again }", - "bind -Tcopy-mode-vi ? { command-prompt -T search -p'(search up)' { send -X search-backward '%%' } }", + "bind -Tcopy-mode-vi ? { command-prompt -T search -p'(search up)' { send -X search-backward -- '%%' } }", "bind -Tcopy-mode-vi A { send -X append-selection-and-cancel }", "bind -Tcopy-mode-vi B { send -X previous-space }", "bind -Tcopy-mode-vi D { send -X copy-pipe-end-of-line-and-cancel }", "bind -Tcopy-mode-vi E { send -X next-space-end }", - "bind -Tcopy-mode-vi F { command-prompt -1p'(jump backward)' { send -X jump-backward '%%' } }", + "bind -Tcopy-mode-vi F { command-prompt -1p'(jump backward)' { send -X jump-backward -- '%%' } }", "bind -Tcopy-mode-vi G { send -X history-bottom }", "bind -Tcopy-mode-vi H { send -X top-line }", "bind -Tcopy-mode-vi J { send -X scroll-down }", @@ -597,14 +597,14 @@ key_bindings_init(void) "bind -Tcopy-mode-vi M { send -X middle-line }", "bind -Tcopy-mode-vi N { send -X search-reverse }", "bind -Tcopy-mode-vi P { send -X toggle-position }", - "bind -Tcopy-mode-vi T { command-prompt -1p'(jump to backward)' { send -X jump-to-backward '%%' } }", + "bind -Tcopy-mode-vi T { command-prompt -1p'(jump to backward)' { send -X jump-to-backward -- '%%' } }", "bind -Tcopy-mode-vi V { send -X select-line }", "bind -Tcopy-mode-vi W { send -X next-space }", "bind -Tcopy-mode-vi X { send -X set-mark }", "bind -Tcopy-mode-vi ^ { send -X back-to-indentation }", "bind -Tcopy-mode-vi b { send -X previous-word }", "bind -Tcopy-mode-vi e { send -X next-word-end }", - "bind -Tcopy-mode-vi f { command-prompt -1p'(jump forward)' { send -X jump-forward '%%' } }", + "bind -Tcopy-mode-vi f { command-prompt -1p'(jump forward)' { send -X jump-forward -- '%%' } }", "bind -Tcopy-mode-vi g { send -X history-top }", "bind -Tcopy-mode-vi h { send -X cursor-left }", "bind -Tcopy-mode-vi j { send -X cursor-down }", @@ -615,7 +615,7 @@ key_bindings_init(void) "bind -Tcopy-mode-vi o { send -X other-end }", "bind -Tcopy-mode-vi q { send -X cancel }", "bind -Tcopy-mode-vi r { send -X refresh-from-pane }", - "bind -Tcopy-mode-vi t { command-prompt -1p'(jump to forward)' { send -X jump-to-forward '%%' } }", + "bind -Tcopy-mode-vi t { command-prompt -1p'(jump to forward)' { send -X jump-to-forward -- '%%' } }", "bind -Tcopy-mode-vi v { send -X rectangle-toggle }", "bind -Tcopy-mode-vi w { send -X next-word }", "bind -Tcopy-mode-vi '{' { send -X previous-paragraph }", diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index 418621a9f76..8538ca6af33 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.958 2024/10/01 10:10:29 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.959 2024/10/04 07:03:08 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -14,7 +14,7 @@ .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: October 1 2024 $ +.Dd $Mdocdate: October 4 2024 $ .Dt TMUX 1 .Os .Sh NAME @@ -1801,6 +1801,7 @@ Exit copy mode. Clear the current selection. .It Xo .Ic copy-end-of-line +.Op Fl CP .Op Ar prefix .Xc Copy from the cursor position to the end of the line. @@ -1808,11 +1809,13 @@ Copy from the cursor position to the end of the line. is used to name the new paste buffer. .It Xo .Ic copy-end-of-line-and-cancel +.Op Fl CP .Op Ar prefix .Xc Copy from the cursor position and exit copy mode. .It Xo .Ic copy-pipe-end-of-line +.Op Fl CP .Op Ar command .Op Ar prefix .Xc @@ -1822,6 +1825,7 @@ Copy from the cursor position to the end of the line and pipe the text to is used to name the new paste buffer. .It Xo .Ic copy-pipe-end-of-line-and-cancel +.Op Fl CP .Op Ar command .Op Ar prefix .Xc @@ -1830,16 +1834,19 @@ Same as but also exit copy mode. .It Xo .Ic copy-line +.Op Fl CP .Op Ar prefix .Xc Copy the entire line. .It Xo .Ic copy-line-and-cancel +.Op Fl CP .Op Ar prefix .Xc Copy the entire line and exit copy mode. .It Xo .Ic copy-pipe-line +.Op Fl CP .Op Ar command .Op Ar prefix .Xc @@ -1849,6 +1856,7 @@ Copy the entire line and pipe the text to is used to name the new paste buffer. .It Xo .Ic copy-pipe-line-and-cancel +.Op Fl CP .Op Ar command .Op Ar prefix .Xc @@ -1857,6 +1865,7 @@ Same as but also exit copy mode. .It Xo .Ic copy-pipe +.Op Fl CP .Op Ar command .Op Ar prefix .Xc @@ -1866,6 +1875,7 @@ Copy the selection, clear it and pipe its text to is used to name the new paste buffer. .It Xo .Ic copy-pipe-no-clear +.Op Fl CP .Op Ar command .Op Ar prefix .Xc @@ -1874,6 +1884,7 @@ Same as but do not clear the selection. .It Xo .Ic copy-pipe-and-cancel +.Op Fl CP .Op Ar command .Op Ar prefix .Xc @@ -1882,11 +1893,13 @@ Same as but also exit copy mode. .It Xo .Ic copy-selection +.Op Fl CP .Op Ar prefix .Xc Copies the current selection. .It Xo .Ic copy-selection-no-clear +.Op Fl CP .Op Ar prefix .Xc Same as @@ -1894,6 +1907,7 @@ Same as but do not clear the selection. .It Xo .Ic copy-selection-and-cancel +.Op Fl CP .Op Ar prefix (vi: Enter) (emacs: M-w) @@ -2341,6 +2355,16 @@ variants of some commands exit copy mode after they have completed (for copy commands) or when the cursor reaches the bottom (for scrolling commands). .Ql -no-clear variants do not clear the selection. +All the copy commands can take the +.Fl C +and +.Fl P +flags. +The +.Fl C +flag suppresses setting the terminal clipboard when copying, while the +.Fl P +flag suppresses adding a paste buffer with the text. .Pp The next and previous word keys skip over whitespace and treat consecutive runs of either word separators or other letters as words. diff --git a/usr.bin/tmux/window-copy.c b/usr.bin/tmux/window-copy.c index 1e45db5935c..c06d1f14da1 100644 --- a/usr.bin/tmux/window-copy.c +++ b/usr.bin/tmux/window-copy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window-copy.c,v 1.354 2024/10/01 08:01:19 nicm Exp $ */ +/* $OpenBSD: window-copy.c,v 1.355 2024/10/04 07:03:08 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -94,13 +94,14 @@ static int window_copy_update_selection(struct window_mode_entry *, int, static void window_copy_synchronize_cursor(struct window_mode_entry *, int); static void *window_copy_get_selection(struct window_mode_entry *, size_t *); static void window_copy_copy_buffer(struct window_mode_entry *, - const char *, void *, size_t); + const char *, void *, size_t, int, int); static void window_copy_pipe(struct window_mode_entry *, struct session *, const char *); static void window_copy_copy_pipe(struct window_mode_entry *, - struct session *, const char *, const char *); + struct session *, const char *, const char *, + int, int); static void window_copy_copy_selection(struct window_mode_entry *, - const char *); + const char *, int, int); static void window_copy_append_selection(struct window_mode_entry *); static void window_copy_clear_selection(struct window_mode_entry *); static void window_copy_copy_line(struct window_mode_entry *, char **, @@ -132,7 +133,7 @@ static void window_copy_cursor_previous_word_pos(struct window_mode_entry *, static void window_copy_cursor_previous_word(struct window_mode_entry *, const char *, int); static void window_copy_cursor_prompt(struct window_mode_entry *, int, - const char *); + int); static void window_copy_scroll_up(struct window_mode_entry *, u_int); static void window_copy_scroll_down(struct window_mode_entry *, u_int); static void window_copy_rectangle_set(struct window_mode_entry *, int); @@ -198,6 +199,7 @@ enum window_copy_cmd_clear { struct window_copy_cmd_state { struct window_mode_entry *wme; struct args *args; + struct args *wargs; struct mouse_event *m; struct client *c; @@ -921,7 +923,7 @@ window_copy_expand_search_string(struct window_copy_cmd_state *cs) { struct window_mode_entry *wme = cs->wme; struct window_copy_mode_data *data = wme->data; - const char *ss = args_string(cs->args, 1); + const char *ss = args_string(cs->wargs, 0); char *expanded; if (ss == NULL || *ss == '\0') @@ -1043,21 +1045,23 @@ window_copy_do_copy_end_of_line(struct window_copy_cmd_state *cs, int pipe, struct session *s = cs->s; struct winlink *wl = cs->wl; struct window_pane *wp = wme->wp; - u_int count = args_count(cs->args); + u_int count = args_count(cs->wargs); u_int np = wme->prefix, ocx, ocy, ooy; struct window_copy_mode_data *data = wme->data; char *prefix = NULL, *command = NULL; - const char *arg1 = args_string(cs->args, 1); - const char *arg2 = args_string(cs->args, 2); + const char *arg0 = args_string(cs->wargs, 0); + const char *arg1 = args_string(cs->wargs, 1); + int set_paste = !args_has(cs->wargs, 'P'); + int set_clip = !args_has(cs->wargs, 'C'); if (pipe) { - if (count == 3) - prefix = format_single(NULL, arg2, c, s, wl, wp); - if (s != NULL && count > 1 && *arg1 != '\0') - command = format_single(NULL, arg1, c, s, wl, wp); - } else { if (count == 2) prefix = format_single(NULL, arg1, c, s, wl, wp); + if (s != NULL && count > 0 && *arg0 != '\0') + command = format_single(NULL, arg0, c, s, wl, wp); + } else { + if (count == 1) + prefix = format_single(NULL, arg0, c, s, wl, wp); } ocx = data->cx; @@ -1071,9 +1075,11 @@ window_copy_do_copy_end_of_line(struct window_copy_cmd_state *cs, int pipe, if (s != NULL) { if (pipe) - window_copy_copy_pipe(wme, s, prefix, command); + window_copy_copy_pipe(wme, s, prefix, command, + set_paste, set_clip); else - window_copy_copy_selection(wme, prefix); + window_copy_copy_selection(wme, prefix, + set_paste, set_clip); if (cancel) { free(prefix); @@ -1126,20 +1132,22 @@ window_copy_do_copy_line(struct window_copy_cmd_state *cs, int pipe, int cancel) struct winlink *wl = cs->wl; struct window_pane *wp = wme->wp; struct window_copy_mode_data *data = wme->data; - u_int count = args_count(cs->args); + u_int count = args_count(cs->wargs); u_int np = wme->prefix, ocx, ocy, ooy; char *prefix = NULL, *command = NULL; - const char *arg1 = args_string(cs->args, 1); - const char *arg2 = args_string(cs->args, 2); + const char *arg0 = args_string(cs->wargs, 0); + const char *arg1 = args_string(cs->wargs, 1); + int set_paste = !args_has(cs->wargs, 'P'); + int set_clip = !args_has(cs->wargs, 'C'); if (pipe) { - if (count == 3) - prefix = format_single(NULL, arg2, c, s, wl, wp); - if (s != NULL && count > 1 && *arg1 != '\0') - command = format_single(NULL, arg1, c, s, wl, wp); - } else { if (count == 2) prefix = format_single(NULL, arg1, c, s, wl, wp); + if (s != NULL && count > 0 && *arg0 != '\0') + command = format_single(NULL, arg0, c, s, wl, wp); + } else { + if (count == 1) + prefix = format_single(NULL, arg0, c, s, wl, wp); } ocx = data->cx; @@ -1155,9 +1163,11 @@ window_copy_do_copy_line(struct window_copy_cmd_state *cs, int pipe, int cancel) if (s != NULL) { if (pipe) - window_copy_copy_pipe(wme, s, prefix, command); + window_copy_copy_pipe(wme, s, prefix, command, + set_paste, set_clip); else - window_copy_copy_selection(wme, prefix); + window_copy_copy_selection(wme, prefix, + set_paste, set_clip); if (cancel) { free(prefix); @@ -1209,13 +1219,15 @@ window_copy_cmd_copy_selection_no_clear(struct window_copy_cmd_state *cs) struct winlink *wl = cs->wl; struct window_pane *wp = wme->wp; char *prefix = NULL; - const char *arg1 = args_string(cs->args, 1); + const char *arg0 = args_string(cs->wargs, 0); + int set_paste = !args_has(cs->wargs, 'P'); + int set_clip = !args_has(cs->wargs, 'C'); - if (arg1 != NULL) - prefix = format_single(NULL, arg1, c, s, wl, wp); + if (arg0 != NULL) + prefix = format_single(NULL, arg0, c, s, wl, wp); if (s != NULL) - window_copy_copy_selection(wme, prefix); + window_copy_copy_selection(wme, prefix, set_paste, set_clip); free(prefix); return (WINDOW_COPY_CMD_NOTHING); @@ -2116,15 +2128,18 @@ window_copy_cmd_copy_pipe_no_clear(struct window_copy_cmd_state *cs) struct winlink *wl = cs->wl; struct window_pane *wp = wme->wp; char *command = NULL, *prefix = NULL; - const char *arg1 = args_string(cs->args, 1); - const char *arg2 = args_string(cs->args, 2); + const char *arg0 = args_string(cs->wargs, 0); + const char *arg1 = args_string(cs->wargs, 1); + int set_paste = !args_has(cs->wargs, 'P'); + int set_clip = !args_has(cs->wargs, 'C'); - if (arg2 != NULL) - prefix = format_single(NULL, arg2, c, s, wl, wp); + if (arg1 != NULL) + prefix = format_single(NULL, arg1, c, s, wl, wp); - if (s != NULL && arg1 != NULL && *arg1 != '\0') - command = format_single(NULL, arg1, c, s, wl, wp); - window_copy_copy_pipe(wme, s, prefix, command); + if (s != NULL && arg0 != NULL && *arg0 != '\0') + command = format_single(NULL, arg0, c, s, wl, wp); + window_copy_copy_pipe(wme, s, prefix, command, + set_paste, set_clip); free(command); free(prefix); @@ -2160,10 +2175,10 @@ window_copy_cmd_pipe_no_clear(struct window_copy_cmd_state *cs) struct winlink *wl = cs->wl; struct window_pane *wp = wme->wp; char *command = NULL; - const char *arg1 = args_string(cs->args, 1); + const char *arg0 = args_string(cs->wargs, 0); - if (s != NULL && arg1 != NULL && *arg1 != '\0') - command = format_single(NULL, arg1, c, s, wl, wp); + if (s != NULL && arg0 != NULL && *arg0 != '\0') + command = format_single(NULL, arg0, c, s, wl, wp); window_copy_pipe(wme, s, command); free(command); @@ -2194,10 +2209,10 @@ static enum window_copy_cmd_action window_copy_cmd_goto_line(struct window_copy_cmd_state *cs) { struct window_mode_entry *wme = cs->wme; - const char *arg1 = args_string(cs->args, 1); + const char *arg0 = args_string(cs->wargs, 0); - if (*arg1 != '\0') - window_copy_goto_line(wme, arg1); + if (*arg0 != '\0') + window_copy_goto_line(wme, arg0); return (WINDOW_COPY_CMD_NOTHING); } @@ -2207,12 +2222,12 @@ window_copy_cmd_jump_backward(struct window_copy_cmd_state *cs) struct window_mode_entry *wme = cs->wme; struct window_copy_mode_data *data = wme->data; u_int np = wme->prefix; - const char *arg1 = args_string(cs->args, 1); + const char *arg0 = args_string(cs->wargs, 0); - if (*arg1 != '\0') { + if (*arg0 != '\0') { data->jumptype = WINDOW_COPY_JUMPBACKWARD; free(data->jumpchar); - data->jumpchar = utf8_fromcstr(arg1); + data->jumpchar = utf8_fromcstr(arg0); for (; np != 0; np--) window_copy_cursor_jump_back(wme); } @@ -2225,12 +2240,12 @@ window_copy_cmd_jump_forward(struct window_copy_cmd_state *cs) struct window_mode_entry *wme = cs->wme; struct window_copy_mode_data *data = wme->data; u_int np = wme->prefix; - const char *arg1 = args_string(cs->args, 1); + const char *arg0 = args_string(cs->wargs, 0); - if (*arg1 != '\0') { + if (*arg0 != '\0') { data->jumptype = WINDOW_COPY_JUMPFORWARD; free(data->jumpchar); - data->jumpchar = utf8_fromcstr(arg1); + data->jumpchar = utf8_fromcstr(arg0); for (; np != 0; np--) window_copy_cursor_jump(wme); } @@ -2243,12 +2258,12 @@ window_copy_cmd_jump_to_backward(struct window_copy_cmd_state *cs) struct window_mode_entry *wme = cs->wme; struct window_copy_mode_data *data = wme->data; u_int np = wme->prefix; - const char *arg1 = args_string(cs->args, 1); + const char *arg0 = args_string(cs->wargs, 0); - if (*arg1 != '\0') { + if (*arg0 != '\0') { data->jumptype = WINDOW_COPY_JUMPTOBACKWARD; free(data->jumpchar); - data->jumpchar = utf8_fromcstr(arg1); + data->jumpchar = utf8_fromcstr(arg0); for (; np != 0; np--) window_copy_cursor_jump_to_back(wme); } @@ -2261,12 +2276,12 @@ window_copy_cmd_jump_to_forward(struct window_copy_cmd_state *cs) struct window_mode_entry *wme = cs->wme; struct window_copy_mode_data *data = wme->data; u_int np = wme->prefix; - const char *arg1 = args_string(cs->args, 1); + const char *arg0 = args_string(cs->wargs, 0); - if (*arg1 != '\0') { + if (*arg0 != '\0') { data->jumptype = WINDOW_COPY_JUMPTOFORWARD; free(data->jumpchar); - data->jumpchar = utf8_fromcstr(arg1); + data->jumpchar = utf8_fromcstr(arg0); for (; np != 0; np--) window_copy_cursor_jump_to(wme); } @@ -2286,9 +2301,8 @@ static enum window_copy_cmd_action window_copy_cmd_next_prompt(struct window_copy_cmd_state *cs) { struct window_mode_entry *wme = cs->wme; - const char *arg1 = args_string(cs->args, 1); - window_copy_cursor_prompt(wme, 1, arg1); + window_copy_cursor_prompt(wme, 1, args_has(cs->wargs, 'o')); return (WINDOW_COPY_CMD_NOTHING); } @@ -2296,9 +2310,8 @@ static enum window_copy_cmd_action window_copy_cmd_previous_prompt(struct window_copy_cmd_state *cs) { struct window_mode_entry *wme = cs->wme; - const char *arg1 = args_string(cs->args, 1); - window_copy_cursor_prompt(wme, 0, arg1); + window_copy_cursor_prompt(wme, 0, args_has(cs->wargs, 'o')); return (WINDOW_COPY_CMD_NOTHING); } @@ -2387,27 +2400,27 @@ window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs) { struct window_mode_entry *wme = cs->wme; struct window_copy_mode_data *data = wme->data; - const char *arg1 = args_string(cs->args, 1); + const char *arg0 = args_string(cs->wargs, 0); const char *ss = data->searchstr; char prefix; enum window_copy_cmd_action action = WINDOW_COPY_CMD_NOTHING; data->timeout = 0; - log_debug("%s: %s", __func__, arg1); + log_debug("%s: %s", __func__, arg0); - prefix = *arg1++; + prefix = *arg0++; if (data->searchx == -1 || data->searchy == -1) { data->searchx = data->cx; data->searchy = data->cy; data->searcho = data->oy; - } else if (ss != NULL && strcmp(arg1, ss) != 0) { + } else if (ss != NULL && strcmp(arg0, ss) != 0) { data->cx = data->searchx; data->cy = data->searchy; data->oy = data->searcho; action = WINDOW_COPY_CMD_REDRAW; } - if (*arg1 == '\0') { + if (*arg0 == '\0') { window_copy_clear_marks(wme); return (WINDOW_COPY_CMD_REDRAW); } @@ -2417,7 +2430,7 @@ window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs) data->searchtype = WINDOW_COPY_SEARCHUP; data->searchregex = 0; free(data->searchstr); - data->searchstr = xstrdup(arg1); + data->searchstr = xstrdup(arg0); if (!window_copy_search_up(wme, 0)) { window_copy_clear_marks(wme); return (WINDOW_COPY_CMD_REDRAW); @@ -2427,7 +2440,7 @@ window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs) data->searchtype = WINDOW_COPY_SEARCHDOWN; data->searchregex = 0; free(data->searchstr); - data->searchstr = xstrdup(arg1); + data->searchstr = xstrdup(arg0); if (!window_copy_search_down(wme, 0)) { window_copy_clear_marks(wme); return (WINDOW_COPY_CMD_REDRAW); @@ -2442,27 +2455,27 @@ window_copy_cmd_search_forward_incremental(struct window_copy_cmd_state *cs) { struct window_mode_entry *wme = cs->wme; struct window_copy_mode_data *data = wme->data; - const char *arg1 = args_string(cs->args, 1); + const char *arg0 = args_string(cs->wargs, 0); const char *ss = data->searchstr; char prefix; enum window_copy_cmd_action action = WINDOW_COPY_CMD_NOTHING; data->timeout = 0; - log_debug("%s: %s", __func__, arg1); + log_debug("%s: %s", __func__, arg0); - prefix = *arg1++; + prefix = *arg0++; if (data->searchx == -1 || data->searchy == -1) { data->searchx = data->cx; data->searchy = data->cy; data->searcho = data->oy; - } else if (ss != NULL && strcmp(arg1, ss) != 0) { + } else if (ss != NULL && strcmp(arg0, ss) != 0) { data->cx = data->searchx; data->cy = data->searchy; data->oy = data->searcho; action = WINDOW_COPY_CMD_REDRAW; } - if (*arg1 == '\0') { + if (*arg0 == '\0') { window_copy_clear_marks(wme); return (WINDOW_COPY_CMD_REDRAW); } @@ -2472,7 +2485,7 @@ window_copy_cmd_search_forward_incremental(struct window_copy_cmd_state *cs) data->searchtype = WINDOW_COPY_SEARCHDOWN; data->searchregex = 0; free(data->searchstr); - data->searchstr = xstrdup(arg1); + data->searchstr = xstrdup(arg0); if (!window_copy_search_down(wme, 0)) { window_copy_clear_marks(wme); return (WINDOW_COPY_CMD_REDRAW); @@ -2482,7 +2495,7 @@ window_copy_cmd_search_forward_incremental(struct window_copy_cmd_state *cs) data->searchtype = WINDOW_COPY_SEARCHUP; data->searchregex = 0; free(data->searchstr); - data->searchstr = xstrdup(arg1); + data->searchstr = xstrdup(arg0); if (!window_copy_search_up(wme, 0)) { window_copy_clear_marks(wme); return (WINDOW_COPY_CMD_REDRAW); @@ -2514,516 +2527,432 @@ static const struct { const char *command; u_int minargs; u_int maxargs; + struct args_parse args; enum window_copy_cmd_clear clear; enum window_copy_cmd_action (*f)(struct window_copy_cmd_state *); } window_copy_cmd_table[] = { { .command = "append-selection", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_append_selection }, { .command = "append-selection-and-cancel", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_append_selection_and_cancel }, { .command = "back-to-indentation", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_back_to_indentation }, { .command = "begin-selection", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_begin_selection }, { .command = "bottom-line", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_bottom_line }, { .command = "cancel", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_cancel }, { .command = "clear-selection", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_clear_selection }, { .command = "copy-end-of-line", - .minargs = 0, - .maxargs = 1, + .args = { "CP", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_end_of_line }, { .command = "copy-end-of-line-and-cancel", - .minargs = 0, - .maxargs = 1, + .args = { "CP", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_end_of_line_and_cancel }, { .command = "copy-pipe-end-of-line", - .minargs = 0, - .maxargs = 2, + .args = { "CP", 0, 2, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_pipe_end_of_line }, { .command = "copy-pipe-end-of-line-and-cancel", - .minargs = 0, - .maxargs = 2, + .args = { "CP", 0, 2, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_pipe_end_of_line_and_cancel }, { .command = "copy-line", - .minargs = 0, - .maxargs = 1, + .args = { "CP", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_line }, { .command = "copy-line-and-cancel", - .minargs = 0, - .maxargs = 1, + .args = { "CP", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_line_and_cancel }, { .command = "copy-pipe-line", - .minargs = 0, - .maxargs = 2, + .args = { "CP", 0, 2, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_pipe_line }, { .command = "copy-pipe-line-and-cancel", - .minargs = 0, - .maxargs = 2, + .args = { "CP", 0, 2, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_pipe_line_and_cancel }, { .command = "copy-pipe-no-clear", - .minargs = 0, - .maxargs = 2, + .args = { "CP", 0, 2, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_NEVER, .f = window_copy_cmd_copy_pipe_no_clear }, { .command = "copy-pipe", - .minargs = 0, - .maxargs = 2, + .args = { "CP", 0, 2, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_pipe }, { .command = "copy-pipe-and-cancel", - .minargs = 0, - .maxargs = 2, + .args = { "CP", 0, 2, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_pipe_and_cancel }, { .command = "copy-selection-no-clear", - .minargs = 0, - .maxargs = 1, + .args = { "CP", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_NEVER, .f = window_copy_cmd_copy_selection_no_clear }, { .command = "copy-selection", - .minargs = 0, - .maxargs = 1, + .args = { "CP", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_selection }, { .command = "copy-selection-and-cancel", - .minargs = 0, - .maxargs = 1, + .args = { "CP", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_copy_selection_and_cancel }, { .command = "cursor-down", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_cursor_down }, { .command = "cursor-down-and-cancel", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_cursor_down_and_cancel }, { .command = "cursor-left", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_cursor_left }, { .command = "cursor-right", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_cursor_right }, { .command = "cursor-up", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_cursor_up }, { .command = "end-of-line", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_end_of_line }, { .command = "goto-line", - .minargs = 1, - .maxargs = 1, + .args = { "", 1, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_goto_line }, { .command = "halfpage-down", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_halfpage_down }, { .command = "halfpage-down-and-cancel", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_halfpage_down_and_cancel }, { .command = "halfpage-up", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_halfpage_up }, { .command = "history-bottom", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_history_bottom }, { .command = "history-top", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_history_top }, { .command = "jump-again", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_jump_again }, { .command = "jump-backward", - .minargs = 1, - .maxargs = 1, + .args = { "", 1, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_jump_backward }, { .command = "jump-forward", - .minargs = 1, - .maxargs = 1, + .args = { "", 1, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_jump_forward }, { .command = "jump-reverse", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_jump_reverse }, { .command = "jump-to-backward", - .minargs = 1, - .maxargs = 1, + .args = { "", 1, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_jump_to_backward }, { .command = "jump-to-forward", - .minargs = 1, - .maxargs = 1, + .args = { "", 1, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_jump_to_forward }, { .command = "jump-to-mark", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_jump_to_mark }, { .command = "next-prompt", - .minargs = 0, - .maxargs = 1, + .args = { "o", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_next_prompt }, { .command = "previous-prompt", - .minargs = 0, - .maxargs = 1, + .args = { "o", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_previous_prompt }, { .command = "middle-line", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_middle_line }, { .command = "next-matching-bracket", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_next_matching_bracket }, { .command = "next-paragraph", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_next_paragraph }, { .command = "next-space", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_next_space }, { .command = "next-space-end", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_next_space_end }, { .command = "next-word", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_next_word }, { .command = "next-word-end", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_next_word_end }, { .command = "other-end", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_other_end }, { .command = "page-down", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_page_down }, { .command = "page-down-and-cancel", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_page_down_and_cancel }, { .command = "page-up", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_page_up }, { .command = "pipe-no-clear", - .minargs = 0, - .maxargs = 1, + .args = { "", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_NEVER, .f = window_copy_cmd_pipe_no_clear }, { .command = "pipe", - .minargs = 0, - .maxargs = 1, + .args = { "", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_pipe }, { .command = "pipe-and-cancel", - .minargs = 0, - .maxargs = 1, + .args = { "", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_pipe_and_cancel }, { .command = "previous-matching-bracket", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_previous_matching_bracket }, { .command = "previous-paragraph", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_previous_paragraph }, { .command = "previous-space", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_previous_space }, { .command = "previous-word", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_previous_word }, { .command = "rectangle-on", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_rectangle_on }, { .command = "rectangle-off", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_rectangle_off }, { .command = "rectangle-toggle", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_rectangle_toggle }, { .command = "refresh-from-pane", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_refresh_from_pane }, { .command = "scroll-bottom", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_scroll_bottom }, { .command = "scroll-down", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_scroll_down }, { .command = "scroll-down-and-cancel", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_scroll_down_and_cancel }, { .command = "scroll-middle", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_scroll_middle }, { .command = "scroll-top", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_scroll_top }, { .command = "scroll-up", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_scroll_up }, { .command = "search-again", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_search_again }, { .command = "search-backward", - .minargs = 0, - .maxargs = 1, + .args = { "", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_search_backward }, { .command = "search-backward-text", - .minargs = 0, - .maxargs = 1, + .args = { "", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_search_backward_text }, { .command = "search-backward-incremental", - .minargs = 1, - .maxargs = 1, + .args = { "", 1, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_search_backward_incremental }, { .command = "search-forward", - .minargs = 0, - .maxargs = 1, + .args = { "", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_search_forward }, { .command = "search-forward-text", - .minargs = 0, - .maxargs = 1, + .args = { "", 0, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_search_forward_text }, { .command = "search-forward-incremental", - .minargs = 1, - .maxargs = 1, + .args = { "", 1, 1, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_search_forward_incremental }, { .command = "search-reverse", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_search_reverse }, { .command = "select-line", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_select_line }, { .command = "select-word", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_select_word }, { .command = "set-mark", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_set_mark }, { .command = "start-of-line", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_start_of_line }, { .command = "stop-selection", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_stop_selection }, { .command = "toggle-position", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_NEVER, .f = window_copy_cmd_toggle_position }, { .command = "top-line", - .minargs = 0, - .maxargs = 0, + .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, .f = window_copy_cmd_top_line } @@ -3035,12 +2964,14 @@ window_copy_command(struct window_mode_entry *wme, struct client *c, struct mouse_event *m) { struct window_copy_mode_data *data = wme->data; + struct window_pane *wp = wme->wp; struct window_copy_cmd_state cs; enum window_copy_cmd_action action; enum window_copy_cmd_clear clear = WINDOW_COPY_CMD_CLEAR_NEVER; const char *command; u_int i, count = args_count(args); int keys; + char *error = NULL; if (count == 0) return; @@ -3051,6 +2982,7 @@ window_copy_command(struct window_mode_entry *wme, struct client *c, cs.wme = wme; cs.args = args; + cs.wargs = NULL; cs.m = m; cs.c = c; @@ -3060,17 +2992,26 @@ window_copy_command(struct window_mode_entry *wme, struct client *c, action = WINDOW_COPY_CMD_NOTHING; for (i = 0; i < nitems(window_copy_cmd_table); i++) { if (strcmp(window_copy_cmd_table[i].command, command) == 0) { - if (count - 1 < window_copy_cmd_table[i].minargs || - count - 1 > window_copy_cmd_table[i].maxargs) + cs.wargs = args_parse(&window_copy_cmd_table[i].args, + args_values(args), count, &error); + + if (error != NULL) { + free(error); + error = NULL; + } + if (cs.wargs == NULL) break; + clear = window_copy_cmd_table[i].clear; action = window_copy_cmd_table[i].f(&cs); + args_free(cs.wargs); + cs.wargs = NULL; break; } } if (strncmp(command, "search-", 7) != 0 && data->searchmark != NULL) { - keys = options_get_number(wme->wp->window->options, "mode-keys"); + keys = options_get_number(wp->window->options, "mode-keys"); if (clear == WINDOW_COPY_CMD_CLEAR_EMACS_ONLY && keys == MODEKEY_VI) clear = WINDOW_COPY_CMD_CLEAR_NEVER; @@ -3084,7 +3025,7 @@ window_copy_command(struct window_mode_entry *wme, struct client *c, wme->prefix = 1; if (action == WINDOW_COPY_CMD_CANCEL) - window_pane_reset_mode(wme->wp); + window_pane_reset_mode(wp); else if (action == WINDOW_COPY_CMD_REDRAW) window_copy_redraw_screen(wme); } @@ -4727,19 +4668,20 @@ window_copy_get_selection(struct window_mode_entry *wme, size_t *len) static void window_copy_copy_buffer(struct window_mode_entry *wme, const char *prefix, - void *buf, size_t len) + void *buf, size_t len, int set_paste, int set_clip) { struct window_pane *wp = wme->wp; struct screen_write_ctx ctx; - if (options_get_number(global_options, "set-clipboard") != 0) { + if (set_clip && options_get_number(global_options, "set-clipboard") != 0) { screen_write_start_pane(&ctx, wp, NULL); screen_write_setselection(&ctx, "", buf, len); screen_write_stop(&ctx); notify_pane("pane-set-clipboard", wp); } - paste_add(prefix, buf, len); + if (set_paste) + paste_add(prefix, buf, len); } static void * @@ -4771,25 +4713,28 @@ window_copy_pipe(struct window_mode_entry *wme, struct session *s, static void window_copy_copy_pipe(struct window_mode_entry *wme, struct session *s, - const char *prefix, const char *cmd) + const char *prefix, const char *cmd, int set_paste, int set_clip) { void *buf; size_t len; buf = window_copy_pipe_run(wme, s, cmd, &len); if (buf != NULL) - window_copy_copy_buffer(wme, prefix, buf, len); + window_copy_copy_buffer(wme, prefix, buf, len, set_paste, + set_clip); } static void -window_copy_copy_selection(struct window_mode_entry *wme, const char *prefix) +window_copy_copy_selection(struct window_mode_entry *wme, const char *prefix, + int set_paste, int set_clip) { char *buf; size_t len; buf = window_copy_get_selection(wme, &len); if (buf != NULL) - window_copy_copy_buffer(wme, prefix, buf, len); + window_copy_copy_buffer(wme, prefix, buf, len, set_paste, + set_clip); } static void @@ -5436,7 +5381,7 @@ window_copy_cursor_previous_word(struct window_mode_entry *wme, static void window_copy_cursor_prompt(struct window_mode_entry *wme, int direction, - const char *args) + int start_output) { struct window_copy_mode_data *data = wme->data; struct screen *s = data->backing; @@ -5445,7 +5390,7 @@ window_copy_cursor_prompt(struct window_mode_entry *wme, int direction, u_int line = gd->hsize - data->oy + data->cy; int add, line_flag; - if (args != NULL && strcmp(args, "-o") == 0) + if (start_output) line_flag = GRID_LINE_START_OUTPUT; else line_flag = GRID_LINE_START_PROMPT; -- 2.20.1