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 u_int
cmd_find_window_match_flags(struct args
*);
33 void cmd_find_window_callback(void *, int);
34 void cmd_find_window_free(void *);
36 /* Flags for determining matching behavior. */
37 #define CMD_FIND_WINDOW_BY_TITLE 0x1
38 #define CMD_FIND_WINDOW_BY_CONTENT 0x2
39 #define CMD_FIND_WINDOW_BY_NAME 0x4
41 #define CMD_FIND_WINDOW_ALL \
42 (CMD_FIND_WINDOW_BY_TITLE | \
43 CMD_FIND_WINDOW_BY_CONTENT | \
44 CMD_FIND_WINDOW_BY_NAME)
47 const struct cmd_entry cmd_find_window_entry
= {
48 "find-window", "findw",
50 "[-CNT] " CMD_TARGET_WINDOW_USAGE
" match-string",
57 struct cmd_find_window_data
{
58 struct session
*session
;
62 cmd_find_window_match_flags(struct args
*args
)
64 u_int match_flags
= 0;
66 /* Turn on flags based on the options. */
67 if (args_has(args
, 'T'))
68 match_flags
|= CMD_FIND_WINDOW_BY_TITLE
;
69 if (args_has(args
, 'C'))
70 match_flags
|= CMD_FIND_WINDOW_BY_CONTENT
;
71 if (args_has(args
, 'N'))
72 match_flags
|= CMD_FIND_WINDOW_BY_NAME
;
74 /* If none of the flags were set, default to matching anything. */
76 match_flags
= CMD_FIND_WINDOW_ALL
;
82 cmd_find_window_exec(struct cmd
*self
, struct cmd_ctx
*ctx
)
84 struct args
*args
= self
->args
;
85 struct cmd_find_window_data
*cdata
;
87 struct winlink
*wl
, *wm
;
89 struct window_pane
*wp
;
90 ARRAY_DECL(, u_int
) list_idx
;
91 ARRAY_DECL(, char *) list_ctx
;
92 char *str
, *sres
, *sctx
, *searchstr
;
93 u_int i
, line
, match_flags
;
95 if (ctx
->curclient
== NULL
) {
96 ctx
->error(ctx
, "must be run interactively");
99 s
= ctx
->curclient
->session
;
101 if ((wl
= cmd_find_window(ctx
, args_get(args
, 't'), NULL
)) == NULL
)
104 match_flags
= cmd_find_window_match_flags(args
);
107 ARRAY_INIT(&list_idx
);
108 ARRAY_INIT(&list_ctx
);
110 xasprintf(&searchstr
, "*%s*", str
);
111 RB_FOREACH(wm
, winlinks
, &s
->windows
) {
113 TAILQ_FOREACH(wp
, &wm
->window
->panes
, entry
) {
116 if ((match_flags
& CMD_FIND_WINDOW_BY_NAME
) &&
117 fnmatch(searchstr
, wm
->window
->name
, 0) == 0)
121 if (match_flags
& CMD_FIND_WINDOW_BY_CONTENT
) {
122 sres
= window_pane_search(
127 (!(match_flags
& CMD_FIND_WINDOW_BY_TITLE
) ||
128 fnmatch(searchstr
, wp
->base
.title
, 0) != 0))
133 "pane %u title: \"%s\"", i
- 1,
137 "pane %u line %u: \"%s\"", i
- 1,
143 ARRAY_ADD(&list_idx
, wm
->idx
);
144 ARRAY_ADD(&list_ctx
, sctx
);
150 if (ARRAY_LENGTH(&list_idx
) == 0) {
151 ctx
->error(ctx
, "no windows matching: %s", str
);
152 ARRAY_FREE(&list_idx
);
153 ARRAY_FREE(&list_ctx
);
157 if (ARRAY_LENGTH(&list_idx
) == 1) {
158 if (session_select(s
, ARRAY_FIRST(&list_idx
)) == 0)
159 server_redraw_session(s
);
164 if (window_pane_set_mode(wl
->window
->active
, &window_choose_mode
) != 0)
167 for (i
= 0; i
< ARRAY_LENGTH(&list_idx
); i
++) {
168 wm
= winlink_find_by_index(
169 &s
->windows
, ARRAY_ITEM(&list_idx
, i
));
172 sctx
= ARRAY_ITEM(&list_ctx
, i
);
173 window_choose_add(wl
->window
->active
,
174 wm
->idx
, "%3d: %s [%ux%u] (%u panes) %s", wm
->idx
, w
->name
,
175 w
->sx
, w
->sy
, window_count_panes(w
), sctx
);
179 cdata
= xmalloc(sizeof *cdata
);
181 cdata
->session
->references
++;
183 window_choose_ready(wl
->window
->active
,
184 0, cmd_find_window_callback
, cmd_find_window_free
, cdata
);
187 ARRAY_FREE(&list_idx
);
188 ARRAY_FREE(&list_ctx
);
194 cmd_find_window_callback(void *data
, int idx
)
196 struct cmd_find_window_data
*cdata
= data
;
197 struct session
*s
= cdata
->session
;
201 if (!session_alive(s
))
204 if (session_select(s
, idx
) == 0) {
205 server_redraw_session(s
);
211 cmd_find_window_free(void *data
)
213 struct cmd_find_window_data
*cdata
= data
;
215 cdata
->session
->references
--;