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);
34 const struct cmd_entry cmd_find_window_entry
= {
35 "find-window", "findw",
36 CMD_TARGET_WINDOW_USAGE
" match-string",
45 struct cmd_find_window_data
{
50 cmd_find_window_exec(struct cmd
*self
, struct cmd_ctx
*ctx
)
52 struct cmd_target_data
*data
= self
->data
;
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 *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
, data
->target
, NULL
)) == NULL
)
72 ARRAY_INIT(&list_idx
);
73 ARRAY_INIT(&list_ctx
);
75 xasprintf(&searchstr
, "*%s*", data
->arg
);
76 RB_FOREACH(wm
, winlinks
, &s
->windows
) {
78 TAILQ_FOREACH(wp
, &wm
->window
->panes
, entry
) {
81 if (fnmatch(searchstr
, wm
->window
->name
, 0) == 0)
84 sres
= window_pane_search(wp
, data
->arg
, &line
);
86 fnmatch(searchstr
, wp
->base
.title
, 0) != 0)
91 "pane %u title: \"%s\"", i
- 1,
95 "pane %u line %u: \"%s\"", i
- 1,
101 ARRAY_ADD(&list_idx
, wm
->idx
);
102 ARRAY_ADD(&list_ctx
, sctx
);
107 if (ARRAY_LENGTH(&list_idx
) == 0) {
108 ctx
->error(ctx
, "no windows matching: %s", data
->arg
);
109 ARRAY_FREE(&list_idx
);
110 ARRAY_FREE(&list_ctx
);
114 if (ARRAY_LENGTH(&list_idx
) == 1) {
115 if (session_select(s
, ARRAY_FIRST(&list_idx
)) == 0)
116 server_redraw_session(s
);
121 if (window_pane_set_mode(wl
->window
->active
, &window_choose_mode
) != 0)
124 for (i
= 0; i
< ARRAY_LENGTH(&list_idx
); i
++) {
125 wm
= winlink_find_by_index(
126 &s
->windows
, ARRAY_ITEM(&list_idx
, i
));
129 sctx
= ARRAY_ITEM(&list_ctx
, i
);
130 window_choose_add(wl
->window
->active
,
131 wm
->idx
, "%3d: %s [%ux%u] (%u panes) %s", wm
->idx
, w
->name
,
132 w
->sx
, w
->sy
, window_count_panes(w
), sctx
);
136 cdata
= xmalloc(sizeof *cdata
);
137 if (session_index(s
, &cdata
->session
) != 0)
138 fatalx("session not found");
141 wl
->window
->active
, 0, cmd_find_window_callback
, xfree
, cdata
);
144 ARRAY_FREE(&list_idx
);
145 ARRAY_FREE(&list_ctx
);
151 cmd_find_window_callback(void *data
, int idx
)
153 struct cmd_find_window_data
*cdata
= data
;
156 if (idx
!= -1 && cdata
->session
<= ARRAY_LENGTH(&sessions
) - 1) {
157 s
= ARRAY_ITEM(&sessions
, cdata
->session
);
158 if (s
!= NULL
&& session_select(s
, idx
) == 0)
159 server_redraw_session(s
);