Undo a change to next/previous session that got mixed in prematurely.
[tmux-openbsd.git] / cmd-find-window.c
blob482d9243cad588e92748a9ba2286dc1fb28d05f6
1 /* $OpenBSD$ */
3 /*
4 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/types.h>
21 #include <fnmatch.h>
22 #include <string.h>
24 #include "tmux.h"
27 * Find window containing text.
30 int cmd_find_window_exec(struct cmd *, struct cmd_ctx *);
32 void cmd_find_window_callback(void *, int);
33 void cmd_find_window_free(void *);
35 const struct cmd_entry cmd_find_window_entry = {
36 "find-window", "findw",
37 CMD_TARGET_WINDOW_USAGE " match-string",
38 CMD_ARG1, "",
39 cmd_target_init,
40 cmd_target_parse,
41 cmd_find_window_exec,
42 cmd_target_free,
43 cmd_target_print
46 struct cmd_find_window_data {
47 struct session *session;
50 int
51 cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
53 struct cmd_target_data *data = self->data;
54 struct cmd_find_window_data *cdata;
55 struct session *s;
56 struct winlink *wl, *wm;
57 struct window *w;
58 struct window_pane *wp;
59 ARRAY_DECL(, u_int) list_idx;
60 ARRAY_DECL(, char *) list_ctx;
61 char *sres, *sctx, *searchstr;
62 u_int i, line;
64 if (ctx->curclient == NULL) {
65 ctx->error(ctx, "must be run interactively");
66 return (-1);
68 s = ctx->curclient->session;
70 if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
71 return (-1);
73 ARRAY_INIT(&list_idx);
74 ARRAY_INIT(&list_ctx);
76 xasprintf(&searchstr, "*%s*", data->arg);
77 RB_FOREACH(wm, winlinks, &s->windows) {
78 i = 0;
79 TAILQ_FOREACH(wp, &wm->window->panes, entry) {
80 i++;
82 if (fnmatch(searchstr, wm->window->name, 0) == 0)
83 sctx = xstrdup("");
84 else {
85 sres = window_pane_search(wp, data->arg, &line);
86 if (sres == NULL &&
87 fnmatch(searchstr, wp->base.title, 0) != 0)
88 continue;
90 if (sres == NULL) {
91 xasprintf(&sctx,
92 "pane %u title: \"%s\"", i - 1,
93 wp->base.title);
94 } else {
95 xasprintf(&sctx,
96 "pane %u line %u: \"%s\"", i - 1,
97 line + 1, sres);
98 xfree(sres);
102 ARRAY_ADD(&list_idx, wm->idx);
103 ARRAY_ADD(&list_ctx, sctx);
106 xfree(searchstr);
108 if (ARRAY_LENGTH(&list_idx) == 0) {
109 ctx->error(ctx, "no windows matching: %s", data->arg);
110 ARRAY_FREE(&list_idx);
111 ARRAY_FREE(&list_ctx);
112 return (-1);
115 if (ARRAY_LENGTH(&list_idx) == 1) {
116 if (session_select(s, ARRAY_FIRST(&list_idx)) == 0)
117 server_redraw_session(s);
118 recalculate_sizes();
119 goto out;
122 if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
123 goto out;
125 for (i = 0; i < ARRAY_LENGTH(&list_idx); i++) {
126 wm = winlink_find_by_index(
127 &s->windows, ARRAY_ITEM(&list_idx, i));
128 w = wm->window;
130 sctx = ARRAY_ITEM(&list_ctx, i);
131 window_choose_add(wl->window->active,
132 wm->idx, "%3d: %s [%ux%u] (%u panes) %s", wm->idx, w->name,
133 w->sx, w->sy, window_count_panes(w), sctx);
134 xfree(sctx);
137 cdata = xmalloc(sizeof *cdata);
138 cdata->session = s;
139 cdata->session->references++;
141 window_choose_ready(wl->window->active,
142 0, cmd_find_window_callback, cmd_find_window_free, cdata);
144 out:
145 ARRAY_FREE(&list_idx);
146 ARRAY_FREE(&list_ctx);
148 return (0);
151 void
152 cmd_find_window_callback(void *data, int idx)
154 struct cmd_find_window_data *cdata = data;
155 struct session *s = cdata->session;
157 if (idx == -1)
158 return;
159 if (!session_alive(s))
160 return;
162 if (session_select(s, idx) == 0) {
163 server_redraw_session(s);
164 recalculate_sizes();
168 void
169 cmd_find_window_free(void *data)
171 struct cmd_find_window_data *cdata = data;
173 cdata->session->references--;
174 xfree(cdata);