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>
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",
38 CMD_TARGET_WINDOW_USAGE
" match-string",
45 struct cmd_find_window_data
{
46 struct session
*session
;
50 cmd_find_window_exec(struct cmd
*self
, struct cmd_ctx
*ctx
)
52 struct args
*args
= self
->args
;
53 struct cmd_find_window_data
*cdata
;
55 struct winlink
*wl
, *wm
;
57 struct window_pane
*wp
;
58 ARRAY_DECL(, u_int
) list_idx
;
59 ARRAY_DECL(, char *) list_ctx
;
60 char *str
, *sres
, *sctx
, *searchstr
;
63 if (ctx
->curclient
== NULL
) {
64 ctx
->error(ctx
, "must be run interactively");
67 s
= ctx
->curclient
->session
;
69 if ((wl
= cmd_find_window(ctx
, args_get(args
, 't'), NULL
)) == NULL
)
74 ARRAY_INIT(&list_idx
);
75 ARRAY_INIT(&list_ctx
);
77 xasprintf(&searchstr
, "*%s*", str
);
78 RB_FOREACH(wm
, winlinks
, &s
->windows
) {
80 TAILQ_FOREACH(wp
, &wm
->window
->panes
, entry
) {
83 if (fnmatch(searchstr
, wm
->window
->name
, 0) == 0)
86 sres
= window_pane_search(wp
, str
, &line
);
88 fnmatch(searchstr
, wp
->base
.title
, 0) != 0)
93 "pane %u title: \"%s\"", i
- 1,
97 "pane %u line %u: \"%s\"", i
- 1,
103 ARRAY_ADD(&list_idx
, wm
->idx
);
104 ARRAY_ADD(&list_ctx
, sctx
);
109 if (ARRAY_LENGTH(&list_idx
) == 0) {
110 ctx
->error(ctx
, "no windows matching: %s", str
);
111 ARRAY_FREE(&list_idx
);
112 ARRAY_FREE(&list_ctx
);
116 if (ARRAY_LENGTH(&list_idx
) == 1) {
117 if (session_select(s
, ARRAY_FIRST(&list_idx
)) == 0)
118 server_redraw_session(s
);
123 if (window_pane_set_mode(wl
->window
->active
, &window_choose_mode
) != 0)
126 for (i
= 0; i
< ARRAY_LENGTH(&list_idx
); i
++) {
127 wm
= winlink_find_by_index(
128 &s
->windows
, ARRAY_ITEM(&list_idx
, i
));
131 sctx
= ARRAY_ITEM(&list_ctx
, i
);
132 window_choose_add(wl
->window
->active
,
133 wm
->idx
, "%3d: %s [%ux%u] (%u panes) %s", wm
->idx
, w
->name
,
134 w
->sx
, w
->sy
, window_count_panes(w
), sctx
);
138 cdata
= xmalloc(sizeof *cdata
);
140 cdata
->session
->references
++;
142 window_choose_ready(wl
->window
->active
,
143 0, cmd_find_window_callback
, cmd_find_window_free
, cdata
);
146 ARRAY_FREE(&list_idx
);
147 ARRAY_FREE(&list_ctx
);
153 cmd_find_window_callback(void *data
, int idx
)
155 struct cmd_find_window_data
*cdata
= data
;
156 struct session
*s
= cdata
->session
;
160 if (!session_alive(s
))
163 if (session_select(s
, idx
) == 0) {
164 server_redraw_session(s
);
170 cmd_find_window_free(void *data
)
172 struct cmd_find_window_data
*cdata
= data
;
174 cdata
->session
->references
--;