Add N to search backwards in tree modes, from Fadi Afani in GitHub issue
authornicm <nicm@openbsd.org>
Fri, 24 May 2024 12:39:06 +0000 (12:39 +0000)
committernicm <nicm@openbsd.org>
Fri, 24 May 2024 12:39:06 +0000 (12:39 +0000)
3982.

usr.bin/tmux/mode-tree.c
usr.bin/tmux/tmux.1

index c1f3b5f..49fe2b7 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: mode-tree.c,v 1.66 2023/08/15 07:01:47 nicm Exp $ */
+/* $OpenBSD: mode-tree.c,v 1.67 2024/05/24 12:39:06 nicm Exp $ */
 
 /*
  * Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com>
 
 #include "tmux.h"
 
+enum mode_tree_search_dir {
+       MODE_TREE_SEARCH_FORWARD,
+       MODE_TREE_SEARCH_BACKWARD
+};
+
 struct mode_tree_item;
 TAILQ_HEAD(mode_tree_list, mode_tree_item);
 
@@ -68,6 +73,7 @@ struct mode_tree_data {
        char                     *search;
        char                     *filter;
        int                       no_matches;
+       enum mode_tree_search_dir search_dir;
 };
 
 struct mode_tree_item {
@@ -786,7 +792,49 @@ done:
 }
 
 static struct mode_tree_item *
-mode_tree_search_for(struct mode_tree_data *mtd)
+mode_tree_search_backward(struct mode_tree_data *mtd)
+{
+    struct mode_tree_item      *mti, *last, *prev;
+
+    if (mtd->search == NULL)
+           return (NULL);
+
+    mti = last = mtd->line_list[mtd->current].item;
+    for (;;) {
+        if ((prev = TAILQ_PREV(mti, mode_tree_list, entry)) != NULL) {
+               /* Point to the last child in the previous subtree. */
+               while (!TAILQ_EMPTY(&prev->children))
+                       prev = TAILQ_LAST(&prev->children, mode_tree_list);
+               mti = prev;
+        } else {
+               /* If prev is NULL, jump to the parent. */
+               mti = mti->parent;
+        }
+
+       if (mti == NULL) {
+               /* Point to the last child in the last root subtree. */
+               prev = TAILQ_LAST(&mtd->children, mode_tree_list);
+               while (!TAILQ_EMPTY(&prev->children))
+                       prev = TAILQ_LAST(&prev->children, mode_tree_list);
+               mti = prev;
+       }
+       if (mti == last)
+               break;
+
+       if (mtd->searchcb == NULL) {
+               if (strstr(mti->name, mtd->search) != NULL)
+                       return (mti);
+               continue;
+       }
+       if (mtd->searchcb(mtd->modedata, mti->itemdata, mtd->search))
+               return (mti);
+    }
+    return (NULL);
+}
+
+
+static struct mode_tree_item *
+mode_tree_search_forward(struct mode_tree_data *mtd)
 {
        struct mode_tree_item   *mti, *last, *next;
 
@@ -832,7 +880,10 @@ mode_tree_search_set(struct mode_tree_data *mtd)
        struct mode_tree_item   *mti, *loop;
        uint64_t                 tag;
 
-       mti = mode_tree_search_for(mtd);
+       if (mtd->search_dir == MODE_TREE_SEARCH_FORWARD)
+               mti = mode_tree_search_forward(mtd);
+       else
+               mti = mode_tree_search_backward(mtd);
        if (mti == NULL)
                return;
        tag = mti->tag;
@@ -1165,6 +1216,11 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
                    PROMPT_NOFORMAT, PROMPT_TYPE_SEARCH);
                break;
        case 'n':
+               mtd->search_dir = MODE_TREE_SEARCH_FORWARD;
+               mode_tree_search_set(mtd);
+               break;
+       case 'N':
+               mtd->search_dir = MODE_TREE_SEARCH_BACKWARD;
                mode_tree_search_set(mtd);
                break;
        case 'f':
index aa61246..2185dc7 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tmux.1,v 1.944 2024/05/14 09:32:37 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.945 2024/05/24 12:39:06 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: May 14 2024 $
+.Dd $Mdocdate: May 24 2024 $
 .Dt TMUX 1
 .Os
 .Sh NAME
@@ -2295,7 +2295,8 @@ The following keys may be used in client mode:
 .It Li "Up" Ta "Select previous client"
 .It Li "Down" Ta "Select next client"
 .It Li "C-s" Ta "Search by name"
-.It Li "n" Ta "Repeat last search"
+.It Li "n" Ta "Repeat last search forwards"
+.It Li "N" Ta "Repeat last search backwards"
 .It Li "t" Ta "Toggle if client is tagged"
 .It Li "T" Ta "Tag no clients"
 .It Li "C-t" Ta "Tag all clients"
@@ -2382,7 +2383,8 @@ The following keys may be used in tree mode:
 .It Li "C-s" Ta "Search by name"
 .It Li "m" Ta "Set the marked pane"
 .It Li "M" Ta "Clear the marked pane"
-.It Li "n" Ta "Repeat last search"
+.It Li "n" Ta "Repeat last search forwards"
+.It Li "N" Ta "Repeat last search backwards"
 .It Li "t" Ta "Toggle if item is tagged"
 .It Li "T" Ta "Tag no items"
 .It Li "C-t" Ta "Tag all items"
@@ -2460,7 +2462,8 @@ The following keys may be used in customize mode:
 .It Li "u" Ta "Unset an option (set to default value if global) or unbind a key"
 .It Li "U" Ta "Unset tagged options and unbind tagged keys"
 .It Li "C-s" Ta "Search by name"
-.It Li "n" Ta "Repeat last search"
+.It Li "n" Ta "Repeat last search forwards"
+.It Li "N" Ta "Repeat last search backwards"
 .It Li "t" Ta "Toggle if item is tagged"
 .It Li "T" Ta "Tag no items"
 .It Li "C-t" Ta "Tag all items"
@@ -6467,7 +6470,8 @@ The following keys may be used in buffer mode:
 .It Li "Up" Ta "Select previous buffer"
 .It Li "Down" Ta "Select next buffer"
 .It Li "C-s" Ta "Search by name or content"
-.It Li "n" Ta "Repeat last search"
+.It Li "n" Ta "Repeat last search forwards"
+.It Li "N" Ta "Repeat last search backwards"
 .It Li "t" Ta "Toggle if buffer is tagged"
 .It Li "T" Ta "Tag no buffers"
 .It Li "C-t" Ta "Tag all buffers"