Extend filters (f key) to buffer and client mode and add -f flag to
authornicm <nicm@openbsd.org>
Fri, 9 Jun 2017 16:01:39 +0000 (16:01 +0000)
committernicm <nicm@openbsd.org>
Fri, 9 Jun 2017 16:01:39 +0000 (16:01 +0000)
specify to command.

usr.bin/tmux/cmd-choose-tree.c
usr.bin/tmux/mode-tree.c
usr.bin/tmux/tmux.1
usr.bin/tmux/tmux.h
usr.bin/tmux/window-buffer.c
usr.bin/tmux/window-client.c
usr.bin/tmux/window-tree.c

index a8268ff..124e51c 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-choose-tree.c,v 1.36 2017/06/09 15:29:15 nicm Exp $ */
+/* $OpenBSD: cmd-choose-tree.c,v 1.37 2017/06/09 16:01:39 nicm Exp $ */
 
 /*
  * Copyright (c) 2012 Thomas Adam <thomas@xteddy.org>
@@ -30,8 +30,8 @@ const struct cmd_entry cmd_choose_tree_entry = {
        .name = "choose-tree",
        .alias = NULL,
 
-       .args = { "O:st:w", 0, 1 },
-       .usage = "[-sw] [-O sort-order] " CMD_TARGET_PANE_USAGE,
+       .args = { "f:O:st:w", 0, 1 },
+       .usage = "[-sw] [-f filter] [-O sort-order] " CMD_TARGET_PANE_USAGE,
 
        .target = { 't', CMD_FIND_PANE, 0 },
 
@@ -43,8 +43,8 @@ const struct cmd_entry cmd_choose_client_entry = {
        .name = "choose-client",
        .alias = NULL,
 
-       .args = { "O:t:", 0, 1 },
-       .usage = "[-O sort-order] " CMD_TARGET_PANE_USAGE,
+       .args = { "f:O:t:", 0, 1 },
+       .usage = "[-f filter] [-O sort-order] " CMD_TARGET_PANE_USAGE,
 
        .target = { 't', CMD_FIND_PANE, 0 },
 
@@ -56,8 +56,8 @@ const struct cmd_entry cmd_choose_buffer_entry = {
        .name = "choose-buffer",
        .alias = NULL,
 
-       .args = { "O:t:", 0, 1 },
-       .usage = "[-O sort-order] " CMD_TARGET_PANE_USAGE,
+       .args = { "f:O:t:", 0, 1 },
+       .usage = "[-f filter] [-O sort-order] " CMD_TARGET_PANE_USAGE,
 
        .target = { 't', CMD_FIND_PANE, 0 },
 
index b9ffe63..85077c6 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: mode-tree.c,v 1.5 2017/06/09 15:29:15 nicm Exp $ */
+/* $OpenBSD: mode-tree.c,v 1.6 2017/06/09 16:01:39 nicm Exp $ */
 
 /*
  * Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -39,7 +39,8 @@ struct mode_tree_data {
        u_int                     sort_size;
        u_int                     sort_type;
 
-       void                     (*buildcb)(void *, u_int, uint64_t *);
+       void                     (*buildcb)(void *, u_int, uint64_t *,
+                                    const char *);
        struct screen           *(*drawcb)(void *, void *, u_int, u_int);
        int                      (*searchcb)(void*, void *, const char *);
 
@@ -59,7 +60,8 @@ struct mode_tree_data {
 
        struct screen             screen;
 
-       char                     *ss;
+       char                     *search;
+       char                     *filter;
 };
 
 struct mode_tree_item {
@@ -274,7 +276,7 @@ mode_tree_each_tagged(struct mode_tree_data *mtd, void (*cb)(void *, void *,
 
 struct mode_tree_data *
 mode_tree_start(struct window_pane *wp, struct args *args,
-    void (*buildcb)(void *, u_int, uint64_t *),
+    void (*buildcb)(void *, u_int, uint64_t *, const char *),
     struct screen *(*drawcb)(void *, void *, u_int, u_int),
     int (*searchcb)(void *, void *, const char *), void *modedata,
     const char **sort_list, u_int sort_size, struct screen **s)
@@ -301,6 +303,11 @@ mode_tree_start(struct window_pane *wp, struct args *args,
                }
        }
 
+       if (args_has(args, 'f'))
+               mtd->filter = xstrdup(args_get(args, 'f'));
+       else
+               mtd->filter = NULL;
+
        mtd->buildcb = buildcb;
        mtd->drawcb = drawcb;
        mtd->searchcb = searchcb;
@@ -328,7 +335,9 @@ mode_tree_build(struct mode_tree_data *mtd)
        TAILQ_CONCAT(&mtd->saved, &mtd->children, entry);
        TAILQ_INIT(&mtd->children);
 
-       mtd->buildcb(mtd->modedata, mtd->sort_type, &tag);
+       mtd->buildcb(mtd->modedata, mtd->sort_type, &tag, mtd->filter);
+       if (TAILQ_EMPTY(&mtd->children))
+               mtd->buildcb(mtd->modedata, mtd->sort_type, &tag, NULL);
 
        mode_tree_free_items(&mtd->saved);
        TAILQ_INIT(&mtd->saved);
@@ -362,6 +371,9 @@ mode_tree_free(struct mode_tree_data *mtd)
        mode_tree_clear_lines(mtd);
        screen_free(&mtd->screen);
 
+       free(mtd->search);
+       free(mtd->filter);
+
        mtd->dead = 1;
        mode_tree_remove_ref(mtd);
 }
@@ -575,7 +587,7 @@ mode_tree_search_for(struct mode_tree_data *mtd)
 {
        struct mode_tree_item   *mti, *last, *next;
 
-       if (mtd->ss == NULL)
+       if (mtd->search == NULL)
                return (NULL);
 
        mti = last = mtd->line_list[mtd->current].item;
@@ -601,11 +613,11 @@ mode_tree_search_for(struct mode_tree_data *mtd)
                        break;
 
                if (mtd->searchcb == NULL) {
-                       if (strstr(mti->name, mtd->ss) != NULL)
+                       if (strstr(mti->name, mtd->search) != NULL)
                                return (mti);
                        continue;
                }
-               if (mtd->searchcb(mtd->modedata, mti->itemdata, mtd->ss))
+               if (mtd->searchcb(mtd->modedata, mti->itemdata, mtd->search))
                        return (mti);
        }
        return (NULL);
@@ -627,10 +639,11 @@ mode_tree_search_set(struct mode_tree_data *mtd)
                loop->expanded = 1;
                loop = loop->parent;
        }
-       mode_tree_build(mtd);
 
+       mode_tree_build(mtd);
        mode_tree_set_current(mtd, tag);
        mode_tree_draw(mtd);
+       mtd->wp->flags |= PANE_REDRAW;
 }
 
 static int
@@ -642,12 +655,12 @@ mode_tree_search_callback(__unused struct client *c, void *data, const char *s,
        if (mtd->dead)
                return (0);
 
-       free(mtd->ss);
-       if (*s == '\0') {
-               mtd->ss = NULL;
+       free(mtd->search);
+       if (s == NULL || *s == '\0') {
+               mtd->search = NULL;
                return (0);
        }
-       mtd->ss = xstrdup(s);
+       mtd->search = xstrdup(s);
        mode_tree_search_set(mtd);
 
        return (0);
@@ -659,6 +672,35 @@ mode_tree_search_free(void *data)
        mode_tree_remove_ref(data);
 }
 
+static int
+mode_tree_filter_callback(__unused struct client *c, void *data, const char *s,
+    __unused int done)
+{
+       struct mode_tree_data   *mtd = data;
+
+       if (mtd->dead)
+               return (0);
+
+       if (mtd->filter != NULL)
+               free(mtd->filter);
+       if (s == NULL || *s == '\0')
+               mtd->filter = NULL;
+       else
+               mtd->filter = xstrdup(s);
+
+       mode_tree_build(mtd);
+       mode_tree_draw(mtd);
+       mtd->wp->flags |= PANE_REDRAW;
+
+       return (0);
+}
+
+static void
+mode_tree_filter_free(void *data)
+{
+       mode_tree_remove_ref(data);
+}
+
 int
 mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
     struct mouse_event *m)
@@ -812,6 +854,12 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
        case 'n':
                mode_tree_search_set(mtd);
                break;
+       case 'f':
+               mtd->references++;
+               status_prompt_set(c, "(filter) ", mtd->filter,
+                   mode_tree_filter_callback, mode_tree_filter_free, mtd,
+                   PROMPT_NOFORMAT);
+               break;
        }
        return (0);
 }
index 310640a..f10db6d 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tmux.1,v 1.561 2017/06/09 15:29:15 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.562 2017/06/09 16:01:39 nicm Exp $
 .\"
 .\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
 .\"
@@ -1354,6 +1354,7 @@ the end of the visible pane.
 The default is to capture only the visible contents of the pane.
 .It Xo
 .Ic choose-client
+.Op Fl f Ar filter
 .Op Fl O Ar sort-order
 .Op Fl t Ar target-pane
 .Op Ar template
@@ -1377,6 +1378,7 @@ The following keys may be used in client mode:
 .It Li "X" Ta "Detach and HUP tagged clients"
 .It Li "z" Ta "Suspend selected client"
 .It Li "Z" Ta "Suspend tagged clients"
+.It Li "f" Ta "Enter a format to filter items"
 .It Li "O" Ta "Change sort order"
 .It Li "q" Ta "Exit mode"
 .El
@@ -1397,10 +1399,13 @@ specifies the initial sort order: one of
 .Ql creation ,
 or
 .Ql activity .
+.Fl f
+specifies an initial filter.
 This command works only if at least one client is attached.
 .It Xo
 .Ic choose-tree
 .Op Fl sw
+.Op Fl f Ar filter
 .Op Fl O Ar sort-order
 .Op Fl t Ar target-pane
 .Op Ar template
@@ -1443,6 +1448,8 @@ specifies the initial sort order: one of
 .Ql name ,
 or
 .Ql time .
+.Fl f
+specifies an initial filter.
 This command works only if at least one client is attached.
 .It Xo
 .Ic display-panes
@@ -3972,6 +3979,7 @@ The buffer commands are as follows:
 .Bl -tag -width Ds
 .It Xo
 .Ic choose-buffer
+.Op Fl f Ar filter
 .Op Fl O Ar sort-order
 .Op Fl t Ar target-pane
 .Op Ar template
@@ -3991,6 +3999,7 @@ The following keys may be used in buffer mode:
 .It Li "C-t" Ta "Tag all buffers"
 .It Li "d" Ta "Delete selected buffer"
 .It Li "D" Ta "Delete tagged buffers"
+.It Li "f" Ta "Enter a format to filter items"
 .It Li "O" Ta "Change sort order"
 .It Li "q" Ta "Exit mode"
 .El
@@ -4010,6 +4019,8 @@ specifies the initial sort order: one of
 .Ql name
 or
 .Ql size .
+.Fl f
+specifies an initial filter.
 This command works only if at least one client is attached.
 .It Ic clear-history Op Fl t Ar target-pane
 .D1 (alias: Ic clearhist )
index 00b1ad9..dacca80 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.784 2017/06/09 15:29:15 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.785 2017/06/09 16:01:39 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -2202,9 +2202,10 @@ void      mode_tree_each_tagged(struct mode_tree_data *, void (*)(void *, void *,
 void    mode_tree_up(struct mode_tree_data *, int);
 void    mode_tree_down(struct mode_tree_data *, int);
 struct mode_tree_data *mode_tree_start(struct window_pane *, struct args *,
-            void (*)(void *, u_int, uint64_t *), struct screen *(*)(void *,
-            void *, u_int, u_int), int (*)(void *, void *, const char *),
-            void *, const char **, u_int, struct screen **);
+            void (*)(void *, u_int, uint64_t *, const char *),
+            struct screen *(*)(void *, void *, u_int, u_int),
+            int (*)(void *, void *, const char *), void *, const char **,
+            u_int, struct screen **);
 void    mode_tree_build(struct mode_tree_data *);
 void    mode_tree_free(struct mode_tree_data *);
 void    mode_tree_resize(struct mode_tree_data *, u_int, u_int);
index 12995e6..8aab9f0 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: window-buffer.c,v 1.7 2017/06/09 15:29:15 nicm Exp $ */
+/* $OpenBSD: window-buffer.c,v 1.8 2017/06/09 16:01:39 nicm Exp $ */
 
 /*
  * Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -125,14 +125,15 @@ window_buffer_cmp_size(const void *a0, const void *b0)
 }
 
 static void
-window_buffer_build(void *modedata, u_int sort_type, __unused uint64_t *tag)
+window_buffer_build(void *modedata, u_int sort_type, __unused uint64_t *tag,
+    const char *filter)
 {
        struct window_buffer_modedata   *data = modedata;
        struct window_buffer_itemdata   *item;
        u_int                            i;
        struct paste_buffer             *pb;
-       char                            *tim;
-       char                            *text;
+       char                            *tim, *text, *cp;
+       struct format_tree              *ft;
 
        for (i = 0; i < data->item_size; i++)
                window_buffer_free_item(data->item_list[i]);
@@ -167,6 +168,22 @@ window_buffer_build(void *modedata, u_int sort_type, __unused uint64_t *tag)
        for (i = 0; i < data->item_size; i++) {
                item = data->item_list[i];
 
+               if (filter != NULL) {
+                       pb = paste_get_name(item->name);
+                       if (pb == NULL)
+                               continue;
+                       ft = format_create(NULL, NULL, FORMAT_NONE, 0);
+                       format_defaults_paste_buffer(ft, pb);
+                       cp = format_expand(ft, filter);
+                       if (!format_true(cp)) {
+                               free(cp);
+                               format_free(ft);
+                               continue;
+                       }
+                       free(cp);
+                       format_free(ft);
+               }
+
                tim = ctime(&item->created);
                *strchr(tim, '\n') = '\0';
 
index e3feb40..25d2f38 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: window-client.c,v 1.5 2017/06/09 15:29:15 nicm Exp $ */
+/* $OpenBSD: window-client.c,v 1.6 2017/06/09 16:01:39 nicm Exp $ */
 
 /*
  * Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -141,14 +141,14 @@ window_client_cmp_activity_time(const void *a0, const void *b0)
 }
 
 static void
-window_client_build(void *modedata, u_int sort_type, __unused uint64_t *tag)
+window_client_build(void *modedata, u_int sort_type, __unused uint64_t *tag,
+    const char *filter)
 {
        struct window_client_modedata   *data = modedata;
        struct window_client_itemdata   *item;
        u_int                            i;
        struct client                   *c;
-       char                            *tim;
-       char                            *text;
+       char                            *tim, *text, *cp;
 
        for (i = 0; i < data->item_size; i++)
                window_client_free_item(data->item_list[i]);
@@ -189,6 +189,15 @@ window_client_build(void *modedata, u_int sort_type, __unused uint64_t *tag)
                item = data->item_list[i];
                c = item->c;
 
+               if (filter != NULL) {
+                       cp = format_single(NULL, filter, c, NULL, NULL, NULL);
+                       if (!format_true(cp)) {
+                               free(cp);
+                               continue;
+                       }
+                       free(cp);
+               }
+
                tim = ctime(&c->activity_time.tv_sec);
                *strchr(tim, '\n') = '\0';
 
index aed2e49..3f1f6d1 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: window-tree.c,v 1.4 2017/06/09 15:29:15 nicm Exp $ */
+/* $OpenBSD: window-tree.c,v 1.5 2017/06/09 16:01:39 nicm Exp $ */
 
 /*
  * Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -81,8 +81,6 @@ struct window_tree_modedata {
        struct client                    *client;
        const char                       *entered;
 
-       char                             *filter;
-
        struct cmd_find_state             fs;
        enum window_tree_type             type;
 };
@@ -227,7 +225,7 @@ window_tree_build_pane(struct session *s, struct winlink *wl,
 
 static int
 window_tree_build_window(struct session *s, struct winlink *wl, void* modedata,
-    u_int sort_type, struct mode_tree_item *parent, int no_filter)
+    u_int sort_type, struct mode_tree_item *parent, const char *filter)
 {
        struct window_tree_modedata     *data = modedata;
        struct window_tree_itemdata     *item;
@@ -261,8 +259,8 @@ window_tree_build_window(struct session *s, struct winlink *wl, void* modedata,
        l = NULL;
        n = 0;
        TAILQ_FOREACH(wp, &wl->window->panes, entry) {
-               if (!no_filter && data->filter != NULL) {
-                       cp = format_single(NULL, data->filter, NULL, s, wl, wp);
+               if (filter != NULL) {
+                       cp = format_single(NULL, filter, NULL, s, wl, wp);
                        if (!format_true(cp)) {
                                free(cp);
                                continue;
@@ -298,7 +296,7 @@ window_tree_build_window(struct session *s, struct winlink *wl, void* modedata,
 
 static void
 window_tree_build_session(struct session *s, void* modedata,
-    u_int sort_type, int no_filter)
+    u_int sort_type, const char *filter)
 {
        struct window_tree_modedata     *data = modedata;
        struct window_tree_itemdata     *item;
@@ -349,7 +347,7 @@ window_tree_build_session(struct session *s, void* modedata,
        empty = 0;
        for (i = 0; i < n; i++) {
                if (!window_tree_build_window(s, l[i], modedata, sort_type, mti,
-                   no_filter))
+                   filter))
                        empty++;
        }
        if (empty == n) {
@@ -361,14 +359,13 @@ window_tree_build_session(struct session *s, void* modedata,
 }
 
 static void
-window_tree_build(void *modedata, u_int sort_type, uint64_t *tag)
+window_tree_build(void *modedata, u_int sort_type, uint64_t *tag,
+    const char *filter)
 {
        struct window_tree_modedata     *data = modedata;
        struct session                  *s, **l;
        u_int                            n, i;
-       int                              no_filter = 0;
 
-restart:
        for (i = 0; i < data->item_size; i++)
                window_tree_free_item(data->item_list[i]);
        free(data->item_list);
@@ -393,14 +390,9 @@ restart:
        }
 
        for (i = 0; i < n; i++)
-               window_tree_build_session(l[i], modedata, sort_type, no_filter);
+               window_tree_build_session(l[i], modedata, sort_type, filter);
        free(l);
 
-       if (!no_filter && data->item_size == 0) {
-               no_filter = 1;
-               goto restart;
-       }
-
        switch (data->type) {
        case WINDOW_TREE_NONE:
                break;
@@ -493,11 +485,6 @@ window_tree_init(struct window_pane *wp, struct cmd_find_state *fs,
        data->wp = wp;
        data->references = 1;
 
-       if (args_has(args, 'f'))
-               data->filter = xstrdup(args_get(args, 'f'));
-       else
-               data->filter = NULL;
-
        if (args == NULL || args->argc == 0)
                data->command = xstrdup(WINDOW_TREE_DEFAULT_COMMAND);
        else
@@ -529,8 +516,6 @@ window_tree_destroy(struct window_tree_modedata *data)
                window_tree_free_item(data->item_list[i]);
        free(data->item_list);
 
-       free(data->filter);
-
        free(data->command);
        free(data);
 }
@@ -653,37 +638,6 @@ window_tree_command_free(void *modedata)
        window_tree_destroy(data);
 }
 
-static int
-window_tree_filter_callback(__unused struct client *c, void *modedata,
-    const char *s, __unused int done)
-{
-       struct window_tree_modedata     *data = modedata;
-
-       if (data->dead)
-               return (0);
-
-       if (data->filter != NULL)
-               free(data->filter);
-       if (s == NULL || *s == '\0')
-               data->filter = NULL;
-       else
-               data->filter = xstrdup(s);
-
-       mode_tree_build(data->data);
-       mode_tree_draw(data->data);
-       data->wp->flags |= PANE_REDRAW;
-
-       return (0);
-}
-
-static void
-window_tree_filter_free(void *modedata)
-{
-       struct window_tree_modedata     *data = modedata;
-
-       window_tree_destroy(data);
-}
-
 static void
 window_tree_key(struct window_pane *wp, struct client *c,
     __unused struct session *s, key_code key, struct mouse_event *m)
@@ -695,26 +649,8 @@ window_tree_key(struct window_pane *wp, struct client *c,
        int                              finished;
        u_int                            tagged;
 
-       /*
-        * t = toggle tag
-        * T = tag none
-        * C-t = tag all
-        * q = exit
-        * O = change sort order
-        *
-        * Enter = select item
-        * : = enter command
-        * f = enter filter
-        */
-
        finished = mode_tree_key(data->data, c, &key, m);
        switch (key) {
-       case 'f':
-               data->references++;
-               status_prompt_set(c, "(filter) ", data->filter,
-                   window_tree_filter_callback, window_tree_filter_free, data,
-                   PROMPT_NOFORMAT);
-               break;
        case ':':
                tagged = mode_tree_count_tagged(data->data);
                if (tagged != 0)