for client and tree, and by name and content for buffer.
-/* $OpenBSD: mode-tree.c,v 1.2 2017/06/04 15:36:33 nicm Exp $ */
+/* $OpenBSD: mode-tree.c,v 1.3 2017/06/07 14:37:30 nicm Exp $ */
/*
* Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com>
TAILQ_HEAD(mode_tree_list, mode_tree_item);
struct mode_tree_data {
+ int dead;
+ u_int references;
+
struct window_pane *wp;
void *modedata;
void (*buildcb)(void *, u_int, uint64_t *);
struct screen *(*drawcb)(void *, void *, u_int, u_int);
+ int (*searchcb)(void*, void *, const char *);
struct mode_tree_list children;
struct mode_tree_list saved;
u_int current;
struct screen screen;
+
+ char *ss;
};
struct mode_tree_item {
}
}
+static void
+mode_tree_set_current(struct mode_tree_data *mtd, uint64_t tag)
+{
+ u_int i;
+
+ for (i = 0; i < mtd->line_size; i++) {
+ if (mtd->line_list[i].item->tag == tag)
+ break;
+ }
+ if (i != mtd->line_size) {
+ mtd->current = i;
+ if (mtd->current > mtd->height - 1)
+ mtd->offset = 1 + mtd->current - mtd->height;
+ else
+ mtd->offset = 0;
+ } else {
+ mtd->current = 0;
+ mtd->offset = 0;
+ }
+}
+
void
mode_tree_up(struct mode_tree_data *mtd, int wrap)
{
struct mode_tree_data *
mode_tree_start(struct window_pane *wp, void (*buildcb)(void *, u_int,
uint64_t *), struct screen *(*drawcb)(void *, void *, u_int, u_int),
- void *modedata, const char **sort_list, u_int sort_size, struct screen **s)
+ int (*searchcb)(void *, void *, const char *), void *modedata,
+ const char **sort_list, u_int sort_size, struct screen **s)
{
struct mode_tree_data *mtd;
mtd = xcalloc(1, sizeof *mtd);
+ mtd->references = 1;
+
mtd->wp = wp;
mtd->modedata = modedata;
mtd->buildcb = buildcb;
mtd->drawcb = drawcb;
+ mtd->searchcb = searchcb;
TAILQ_INIT(&mtd->children);
{
struct screen *s = &mtd->screen;
uint64_t tag;
- u_int i;
if (mtd->line_list != NULL)
tag = mtd->line_list[mtd->current].item->tag;
mode_tree_clear_lines(mtd);
mode_tree_build_lines(mtd, &mtd->children, 0);
- for (i = 0; i < mtd->line_size; i++) {
- if (mtd->line_list[i].item->tag == tag)
- break;
- }
- if (i != mtd->line_size)
- mtd->current = i;
- else {
- mtd->current = 0;
- mtd->offset = 0;
- }
+ mode_tree_set_current(mtd, tag);
mtd->width = screen_size_x(s);
mtd->height = (screen_size_y(s) / 3) * 2;
mtd->height = screen_size_y(s);
}
+static void
+mode_tree_remove_ref(struct mode_tree_data *mtd)
+{
+ if (--mtd->references == 0)
+ free(mtd);
+}
+
void
mode_tree_free(struct mode_tree_data *mtd)
{
mode_tree_free_items(&mtd->children);
mode_tree_clear_lines(mtd);
screen_free(&mtd->screen);
- free(mtd);
+
+ mtd->dead = 1;
+ mode_tree_remove_ref(mtd);
}
void
screen_write_stop(&ctx);
}
+static struct mode_tree_item *
+mode_tree_search_for(struct mode_tree_data *mtd)
+{
+ struct mode_tree_item *mti, *last, *next;
+
+ if (mtd->ss == NULL)
+ return (NULL);
+
+ mti = last = mtd->line_list[mtd->current].item;
+ for (;;) {
+ if (!TAILQ_EMPTY(&mti->children))
+ mti = TAILQ_FIRST(&mti->children);
+ else if ((next = TAILQ_NEXT(mti, entry)) != NULL)
+ mti = next;
+ else {
+ for (;;) {
+ mti = mti->parent;
+ if (mti == NULL)
+ break;
+ if ((next = TAILQ_NEXT(mti, entry)) != NULL) {
+ mti = next;
+ break;
+ }
+ }
+ }
+ if (mti == NULL)
+ mti = TAILQ_FIRST(&mtd->children);
+ if (mti == last)
+ break;
+
+ if (mtd->searchcb == NULL) {
+ if (strstr(mti->name, mtd->ss) != NULL)
+ return (mti);
+ continue;
+ }
+ if (mtd->searchcb(mtd->modedata, mti->itemdata, mtd->ss))
+ return (mti);
+ }
+ return (NULL);
+}
+
+static void
+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 (mti == NULL)
+ return;
+ tag = mti->tag;
+
+ loop = mti->parent;
+ while (loop != NULL) {
+ loop->expanded = 1;
+ loop = loop->parent;
+ }
+ mode_tree_build(mtd);
+
+ mode_tree_set_current(mtd, tag);
+ mode_tree_draw(mtd);
+}
+
+static int
+mode_tree_search_callback(__unused struct client *c, void *data, const char *s,
+ __unused int done)
+{
+ struct mode_tree_data *mtd = data;
+
+ if (mtd->dead)
+ return (0);
+
+ free(mtd->ss);
+ if (*s == '\0') {
+ mtd->ss = NULL;
+ return (0);
+ }
+ mtd->ss = xstrdup(s);
+ mode_tree_search_set(mtd);
+
+ return (0);
+}
+
+static void
+mode_tree_search_free(void *data)
+{
+ mode_tree_remove_ref(data);
+}
+
int
-mode_tree_key(struct mode_tree_data *mtd, key_code *key, struct mouse_event *m)
+mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
+ struct mouse_event *m)
{
struct mode_tree_line *line;
struct mode_tree_item *current, *parent;
mode_tree_build(mtd);
}
break;
+ case '\023': /* C-s */
+ mtd->references++;
+ status_prompt_set(c, "(search) ", "",
+ mode_tree_search_callback, mode_tree_search_free, mtd,
+ PROMPT_NOFORMAT);
+ break;
+ case 'n':
+ mode_tree_search_set(mtd);
+ break;
}
return (0);
}
-.\" $OpenBSD: tmux.1,v 1.558 2017/06/04 08:25:57 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.559 2017/06/07 14:37:30 nicm Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
.\"
.\" 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 2017 $
+.Dd $Mdocdate: June 7 2017 $
.Dt TMUX 1
.Os
.Sh NAME
.It Li "Enter" Ta "Choose selected client"
.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 "t" Ta "Toggle if client is tagged"
.It Li "T" Ta "Tag no clients"
.It Li "C-t" Ta "Tag all clients"
.It Li "Enter" Ta "Choose selected item"
.It Li "Up" Ta "Select previous item"
.It Li "Down" Ta "Select next item"
+.It Li "C-s" Ta "Search by name"
+.It Li "n" Ta "Repeat last search"
.It Li "t" Ta "Toggle if item is tagged"
.It Li "T" Ta "Tag no items"
.It Li "C-t" Ta "Tag all items"
.It Li "Enter" Ta "Choose selected buffer"
.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 "t" Ta "Toggle if buffer is tagged"
.It Li "T" Ta "Tag no buffers"
.It Li "C-t" Ta "Tag all buffers"
-/* $OpenBSD: tmux.h,v 1.781 2017/06/04 09:02:36 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.782 2017/06/07 14:37:30 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
void mode_tree_down(struct mode_tree_data *, int);
struct mode_tree_data *mode_tree_start(struct window_pane *,
void (*)(void *, u_int, uint64_t *), struct screen *(*)(void *,
- void *, u_int, u_int), void *, const char **, u_int,
- struct screen **);
+ 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);
const char *, int);
void mode_tree_remove(struct mode_tree_data *, struct mode_tree_item *);
void mode_tree_draw(struct mode_tree_data *);
-int mode_tree_key(struct mode_tree_data *, key_code *,
+int mode_tree_key(struct mode_tree_data *, struct client *, key_code *,
struct mouse_event *);
void mode_tree_run_command(struct client *, struct cmd_find_state *,
const char *, const char *);
-/* $OpenBSD: window-buffer.c,v 1.3 2017/05/31 17:56:48 nicm Exp $ */
+/* $OpenBSD: window-buffer.c,v 1.4 2017/06/07 14:37:30 nicm Exp $ */
/*
* Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com>
return (&s);
}
+static int
+window_buffer_search(__unused void *modedata, void *itemdata, const char *ss)
+{
+ struct window_buffer_itemdata *item = itemdata;
+ struct paste_buffer *pb;
+ const char *bufdata;
+ size_t bufsize;
+
+ if ((pb = paste_get_name(item->name)) == NULL)
+ return (0);
+ if (strstr(item->name, ss) != NULL)
+ return (0);
+ bufdata = paste_buffer_data(pb, &bufsize);
+ return (memmem(bufdata, bufsize, ss, strlen(ss)) != NULL);
+}
+
static struct screen *
window_buffer_init(struct window_pane *wp, __unused struct cmd_find_state *fs,
struct args *args)
data->command = xstrdup(args->argv[0]);
data->data = mode_tree_start(wp, window_buffer_build,
- window_buffer_draw, data, window_buffer_sort_list,
- nitems(window_buffer_sort_list), &s);
+ window_buffer_draw, window_buffer_search, data,
+ window_buffer_sort_list, nitems(window_buffer_sort_list), &s);
mode_tree_build(data->data);
mode_tree_draw(data->data);
* Enter = paste buffer
*/
- finished = mode_tree_key(data->data, &key, m);
+ finished = mode_tree_key(data->data, c, &key, m);
switch (key) {
case 'd':
item = mode_tree_get_current(data->data);
-/* $OpenBSD: window-client.c,v 1.2 2017/05/31 15:27:57 nicm Exp $ */
+/* $OpenBSD: window-client.c,v 1.3 2017/06/07 14:37:30 nicm Exp $ */
/*
* Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com>
data->command = xstrdup(args->argv[0]);
data->data = mode_tree_start(wp, window_client_build,
- window_client_draw, data, window_client_sort_list,
+ window_client_draw, NULL, data, window_client_sort_list,
nitems(window_client_sort_list), &s);
mode_tree_build(data->data);
* Enter = detach client
*/
- finished = mode_tree_key(data->data, &key, m);
+ finished = mode_tree_key(data->data, c, &key, m);
switch (key) {
case 'd':
case 'x':
-/* $OpenBSD: window-tree.c,v 1.2 2017/06/06 15:07:35 nicm Exp $ */
+/* $OpenBSD: window-tree.c,v 1.3 2017/06/07 14:37:30 nicm Exp $ */
/*
* Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com>
return (&s);
}
+static int
+window_tree_search(__unused void *modedata, void *itemdata, const char *ss)
+{
+ struct window_tree_itemdata *item = itemdata;
+ struct session *s;
+ struct winlink *wl;
+ struct window_pane *wp;
+ const char *cmd;
+
+ window_tree_pull_item(item, &s, &wl, &wp);
+
+ switch (item->type) {
+ case WINDOW_TREE_NONE:
+ return (0);
+ case WINDOW_TREE_SESSION:
+ if (s == NULL)
+ return (0);
+ return (strstr(s->name, ss) != NULL);
+ case WINDOW_TREE_WINDOW:
+ if (s == NULL || wl == NULL)
+ return (0);
+ return (strstr(wl->window->name, ss) != NULL);
+ case WINDOW_TREE_PANE:
+ if (s == NULL || wl == NULL || wp == NULL)
+ break;
+ cmd = get_proc_name(wp->fd, wp->tty);
+ if (cmd == NULL || *cmd == '\0')
+ return (0);
+ return (strstr(cmd, ss) != NULL);
+ }
+ return (0);
+}
+
static struct screen *
window_tree_init(struct window_pane *wp, struct cmd_find_state *fs,
struct args *args)
else
data->command = xstrdup(args->argv[0]);
- data->data = mode_tree_start(wp, window_tree_build,
- window_tree_draw, data, window_tree_sort_list,
+ data->data = mode_tree_start(wp, window_tree_build, window_tree_draw,
+ window_tree_search, data, window_tree_sort_list,
nitems(window_tree_sort_list), &s);
mode_tree_build(data->data);
* f = enter filter
*/
- finished = mode_tree_key(data->data, &key, m);
+ finished = mode_tree_key(data->data, c, &key, m);
switch (key) {
case 'f':
data->references++;