Add "pipe" variants of the "copy-pipe" commands which do not copy, from
authornicm <nicm@openbsd.org>
Mon, 8 Feb 2021 14:46:53 +0000 (14:46 +0000)
committernicm <nicm@openbsd.org>
Mon, 8 Feb 2021 14:46:53 +0000 (14:46 +0000)
Christian Zangl.

usr.bin/tmux/tmux.1
usr.bin/tmux/window-copy.c

index 34470b0..0303c56 100644 (file)
@@ -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 <nicholas.marriott@gmail.com>
 .\"
@@ -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 [<command>] [<prefix>]" Ta "" Ta ""
+.It Li "pipe-no-clear [<command>] [<prefix>]" Ta "" Ta ""
+.It Li "pipe-and-cancel [<command>] [<prefix>]" 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
index bf7138a..0238f64 100644 (file)
@@ -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 <nicholas.marriott@gmail.com>
@@ -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);
 }