From 1d95ab0f90e3c53555199582404cff07a8d496f5 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 8 Feb 2021 14:46:53 +0000 Subject: [PATCH] Add "pipe" variants of the "copy-pipe" commands which do not copy, from Christian Zangl. --- usr.bin/tmux/tmux.1 | 11 ++++-- usr.bin/tmux/window-copy.c | 79 ++++++++++++++++++++++++++++++++++---- 2 files changed, 80 insertions(+), 10 deletions(-) diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index 34470b05d79..0303c568144 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.819 2021/02/06 13:02:52 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.820 2021/02/08 14:46:53 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: February 6 2021 $ +.Dd $Mdocdate: February 8 2021 $ .Dt TMUX 1 .Os .Sh NAME @@ -1653,6 +1653,9 @@ The following commands are supported in copy mode: .It Li "page-down" Ta "C-f" Ta "PageDown" .It Li "page-down-and-cancel" Ta "" Ta "" .It Li "page-up" Ta "C-b" Ta "PageUp" +.It Li "pipe [] []" Ta "" Ta "" +.It Li "pipe-no-clear [] []" Ta "" Ta "" +.It Li "pipe-and-cancel [] []" Ta "" Ta "" .It Li "previous-matching-bracket" Ta "" Ta "M-C-b" .It Li "previous-paragraph" Ta "{" Ta "M-{" .It Li "previous-space" Ta "B" Ta "" @@ -1708,7 +1711,9 @@ so buffers are named .Ql buffer1 and so on). Pipe commands take a command argument which is the command to which the -copied text is piped. +selected text is piped. +.Ql copy-pipe +variants also copy the selection. The .Ql -and-cancel variants of some commands exit copy mode after they have completed (for copy diff --git a/usr.bin/tmux/window-copy.c b/usr.bin/tmux/window-copy.c index bf7138a8099..0238f648dbf 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.313 2021/01/22 10:24:52 nicm Exp $ */ +/* $OpenBSD: window-copy.c,v 1.314 2021/02/08 14:46:53 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -92,6 +92,8 @@ 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); +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 *); static void window_copy_copy_selection(struct window_mode_entry *, @@ -1874,6 +1876,44 @@ window_copy_cmd_copy_pipe_and_cancel(struct window_copy_cmd_state *cs) return (WINDOW_COPY_CMD_CANCEL); } +static enum window_copy_cmd_action +window_copy_cmd_pipe_no_clear(struct window_copy_cmd_state *cs) +{ + struct window_mode_entry *wme = cs->wme; + struct client *c = cs->c; + struct session *s = cs->s; + struct winlink *wl = cs->wl; + struct window_pane *wp = wme->wp; + char *command = NULL; + + if (s != NULL && cs->args->argc > 1 && *cs->args->argv[1] != '\0') + command = format_single(NULL, cs->args->argv[1], c, s, wl, wp); + window_copy_pipe(wme, s, command); + free(command); + + return (WINDOW_COPY_CMD_NOTHING); +} + +static enum window_copy_cmd_action +window_copy_cmd_pipe(struct window_copy_cmd_state *cs) +{ + struct window_mode_entry *wme = cs->wme; + + window_copy_cmd_pipe_no_clear(cs); + window_copy_clear_selection(wme); + return (WINDOW_COPY_CMD_REDRAW); +} + +static enum window_copy_cmd_action +window_copy_cmd_pipe_and_cancel(struct window_copy_cmd_state *cs) +{ + struct window_mode_entry *wme = cs->wme; + + window_copy_cmd_pipe_no_clear(cs); + window_copy_clear_selection(wme); + return (WINDOW_COPY_CMD_CANCEL); +} + static enum window_copy_cmd_action window_copy_cmd_goto_line(struct window_copy_cmd_state *cs) { @@ -2267,6 +2307,12 @@ static const struct { window_copy_cmd_page_down_and_cancel }, { "page-up", 0, 0, WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, window_copy_cmd_page_up }, + { "pipe-no-clear", 0, 1, WINDOW_COPY_CMD_CLEAR_NEVER, + window_copy_cmd_pipe_no_clear }, + { "pipe", 0, 1, WINDOW_COPY_CMD_CLEAR_ALWAYS, + window_copy_cmd_pipe }, + { "pipe-and-cancel", 0, 1, WINDOW_COPY_CMD_CLEAR_ALWAYS, + window_copy_cmd_pipe_and_cancel }, { "previous-matching-bracket", 0, 0, WINDOW_COPY_CMD_CLEAR_ALWAYS, window_copy_cmd_previous_matching_bracket }, { "previous-paragraph", 0, 0, WINDOW_COPY_CMD_CLEAR_EMACS_ONLY, @@ -3840,22 +3886,41 @@ window_copy_copy_buffer(struct window_mode_entry *wme, const char *prefix, paste_add(prefix, buf, len); } -static void -window_copy_copy_pipe(struct window_mode_entry *wme, struct session *s, - const char *prefix, const char *cmd) +static void * +window_copy_pipe_run(struct window_mode_entry *wme, struct session *s, + const char *cmd, size_t *len) { void *buf; - size_t len; struct job *job; - buf = window_copy_get_selection(wme, &len); + buf = window_copy_get_selection(wme, len); if (cmd == NULL || *cmd == '\0') cmd = options_get_string(global_options, "copy-command"); if (cmd != NULL && *cmd != '\0') { job = job_run(cmd, s, NULL, NULL, NULL, NULL, NULL, JOB_NOWAIT, -1, -1); - bufferevent_write(job_get_event(job), buf, len); + bufferevent_write(job_get_event(job), buf, *len); } + return (buf); +} + +static void +window_copy_pipe(struct window_mode_entry *wme, struct session *s, + const char *cmd) +{ + size_t len; + + window_copy_pipe_run(wme, s, cmd, &len); +} + +static void +window_copy_copy_pipe(struct window_mode_entry *wme, struct session *s, + const char *prefix, const char *cmd) +{ + 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); } -- 2.20.1