Make it so that if a window or session target is prefixed with an =,
authornicm <nicm@openbsd.org>
Fri, 5 Jun 2015 08:14:16 +0000 (08:14 +0000)
committernicm <nicm@openbsd.org>
Fri, 5 Jun 2015 08:14:16 +0000 (08:14 +0000)
only an exact name or index match is accepted, no special character,
prefix match, or fnmatch.

usr.bin/tmux/cmd-find.c
usr.bin/tmux/key-bindings.c
usr.bin/tmux/tmux.1

index dcfda1c..bdb91d3 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-find.c,v 1.8 2015/06/04 11:43:51 nicm Exp $ */
+/* $OpenBSD: cmd-find.c,v 1.9 2015/06/05 08:14:16 nicm Exp $ */
 
 /*
  * Copyright (c) 2015 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,6 +30,8 @@
 #define CMD_FIND_QUIET 0x2
 #define CMD_FIND_WINDOW_INDEX 0x4
 #define CMD_FIND_DEFAULT_MARKED 0x8
+#define CMD_FIND_EXACT_SESSION 0x10
+#define CMD_FIND_EXACT_WINDOW 0x20
 
 enum cmd_find_type {
        CMD_FIND_PANE,
@@ -381,6 +383,10 @@ cmd_find_get_session(struct cmd_find_state *fs, const char *session)
        if (fs->s != NULL)
                return (0);
 
+       /* Stop now if exact only. */
+       if (fs->flags & CMD_FIND_EXACT_SESSION)
+               return (-1);
+
        /* Otherwise look for prefix. */
        s = NULL;
        RB_FOREACH(s_loop, sessions, &sessions) {
@@ -455,10 +461,11 @@ cmd_find_get_window_with_session(struct cmd_find_state *fs, const char *window)
 {
        struct winlink  *wl;
        const char      *errstr;
-       int              idx, n;
+       int              idx, n, exact;
        struct session  *s;
 
        log_debug("%s: %s", __func__, window);
+       exact = (fs->flags & CMD_FIND_EXACT_WINDOW);
 
        /* Check for window ids starting with @. */
        if (*window == '@') {
@@ -469,7 +476,7 @@ cmd_find_get_window_with_session(struct cmd_find_state *fs, const char *window)
        }
 
        /* Try as an offset. */
-       if (window[0] == '+' || window[0] == '-') {
+       if (!exact && window[0] == '+' || window[0] == '-') {
                if (window[1] != '\0')
                        n = strtonum(window + 1, 1, INT_MAX, NULL);
                else
@@ -499,43 +506,47 @@ cmd_find_get_window_with_session(struct cmd_find_state *fs, const char *window)
        }
 
        /* Try special characters. */
-       if (strcmp(window, "!") == 0) {
-               fs->wl = TAILQ_FIRST(&fs->s->lastw);
-               if (fs->wl == NULL)
-                       return (-1);
-               fs->idx = fs->wl->idx;
-               fs->w = fs->wl->window;
-               return (0);
-       } else if (strcmp(window, "^") == 0) {
-               fs->wl = RB_MIN(winlinks, &fs->s->windows);
-               if (fs->wl == NULL)
-                       return (-1);
-               fs->idx = fs->wl->idx;
-               fs->w = fs->wl->window;
-               return (0);
-       } else if (strcmp(window, "$") == 0) {
-               fs->wl = RB_MAX(winlinks, &fs->s->windows);
-               if (fs->wl == NULL)
-                       return (-1);
-               fs->idx = fs->wl->idx;
-               fs->w = fs->wl->window;
-               return (0);
-       }
-
-       /* First see if this is a valid window index in this session. */
-       idx = strtonum(window, 0, INT_MAX, &errstr);
-       if (errstr == NULL) {
-               if (fs->flags & CMD_FIND_WINDOW_INDEX) {
-                       fs->idx = idx;
+       if (!exact) {
+               if (strcmp(window, "!") == 0) {
+                       fs->wl = TAILQ_FIRST(&fs->s->lastw);
+                       if (fs->wl == NULL)
+                               return (-1);
+                       fs->idx = fs->wl->idx;
+                       fs->w = fs->wl->window;
                        return (0);
-               }
-               fs->wl = winlink_find_by_index(&fs->s->windows, idx);
-               if (fs->wl != NULL) {
+               } else if (strcmp(window, "^") == 0) {
+                       fs->wl = RB_MIN(winlinks, &fs->s->windows);
+                       if (fs->wl == NULL)
+                               return (-1);
+                       fs->idx = fs->wl->idx;
+                       fs->w = fs->wl->window;
+                       return (0);
+               } else if (strcmp(window, "$") == 0) {
+                       fs->wl = RB_MAX(winlinks, &fs->s->windows);
+                       if (fs->wl == NULL)
+                               return (-1);
+                       fs->idx = fs->wl->idx;
                        fs->w = fs->wl->window;
                        return (0);
                }
        }
 
+       /* First see if this is a valid window index in this session. */
+       if (window[0] != '+' && window[0] != '-') {
+               idx = strtonum(window, 0, INT_MAX, &errstr);
+               if (errstr == NULL) {
+                       if (fs->flags & CMD_FIND_WINDOW_INDEX) {
+                               fs->idx = idx;
+                               return (0);
+                       }
+                       fs->wl = winlink_find_by_index(&fs->s->windows, idx);
+                       if (fs->wl != NULL) {
+                               fs->w = fs->wl->window;
+                               return (0);
+                       }
+               }
+       }
+
        /* Look for exact matches, error if more than one. */
        fs->wl = NULL;
        RB_FOREACH(wl, winlinks, &fs->s->windows) {
@@ -551,6 +562,11 @@ cmd_find_get_window_with_session(struct cmd_find_state *fs, const char *window)
                return (0);
        }
 
+
+       /* Stop now if exact only. */
+       if (exact)
+               return (-1);
+
        /* Try as the start of a window name, error if multiple. */
        fs->wl = NULL;
        RB_FOREACH(wl, winlinks, &fs->s->windows) {
@@ -868,6 +884,16 @@ cmd_find_target(struct cmd_q *cmdq, const char *target, enum cmd_find_type type,
                }
        }
 
+       /* Set exact match flags. */
+       if (session != NULL && *session == '=') {
+               session++;
+               fs.flags |= CMD_FIND_EXACT_SESSION;
+       }
+       if (window != NULL && *window == '=') {
+               window++;
+               fs.flags |= CMD_FIND_EXACT_WINDOW;
+       }
+
        /* Empty is the same as NULL. */
        if (session != NULL && *session == '\0')
                session = NULL;
index bcee036..2605e1a 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: key-bindings.c,v 1.49 2015/06/04 11:43:51 nicm Exp $ */
+/* $OpenBSD: key-bindings.c,v 1.50 2015/06/05 08:14:16 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -161,16 +161,16 @@ key_bindings_init(void)
                "bind , command-prompt -I'#W' \"rename-window '%%'\"",
                "bind - delete-buffer",
                "bind . command-prompt \"move-window -t '%%'\"",
-               "bind 0 select-window -t:0",
-               "bind 1 select-window -t:1",
-               "bind 2 select-window -t:2",
-               "bind 3 select-window -t:3",
-               "bind 4 select-window -t:4",
-               "bind 5 select-window -t:5",
-               "bind 6 select-window -t:6",
-               "bind 7 select-window -t:7",
-               "bind 8 select-window -t:8",
-               "bind 9 select-window -t:9",
+               "bind 0 select-window -t:=0",
+               "bind 1 select-window -t:=1",
+               "bind 2 select-window -t:=2",
+               "bind 3 select-window -t:=3",
+               "bind 4 select-window -t:=4",
+               "bind 5 select-window -t:=5",
+               "bind 6 select-window -t:=6",
+               "bind 7 select-window -t:=7",
+               "bind 8 select-window -t:=8",
+               "bind 9 select-window -t:=9",
                "bind : command-prompt",
                "bind \\; last-pane",
                "bind = choose-buffer",
index 7cff52f..9414db5 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tmux.1,v 1.434 2015/06/04 20:34:22 jmc Exp $
+.\" $OpenBSD: tmux.1,v 1.435 2015/06/05 08:14:16 nicm Exp $
 .\"
 .\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 .\"
@@ -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: June 4 2015 $
+.Dd $Mdocdate: June 5 2015 $
 .Dt TMUX 1
 .Os
 .Sh NAME
@@ -404,6 +404,14 @@ An
 pattern which is matched against the session name.
 .El
 .Pp
+If the session name is prefixed with a
+.Ql = : ,
+only an exact match is accepted (so
+.Ql =mysess
+will only match exactly
+.Ql mysess ,
+not
+.Ql mysession ) .
 If a single session is found, it is used as the target session; multiple matches
 produce an error.
 If a session is omitted, the current session is used if available; if no
@@ -440,6 +448,9 @@ As an
 pattern matched against the window name.
 .El
 .Pp
+Like sessions, a
+.Ql =
+prefix will do an exact match only.
 An empty window name specifies the next unused index if appropriate (for
 example the
 .Ic new-window