Annotation of src/usr.bin/tmux/cmd-find-window.c, Revision 1.8
1.8 ! nicm 1: /* $OpenBSD: cmd-find-window.c,v 1.7 2010/12/20 00:03:55 nicm Exp $ */
1.1 nicm 2:
3: /*
4: * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
5: *
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.
9: *
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.
17: */
18:
19: #include <sys/types.h>
20:
1.2 nicm 21: #include <fnmatch.h>
1.1 nicm 22: #include <string.h>
23:
24: #include "tmux.h"
25:
26: /*
27: * Find window containing text.
28: */
29:
30: int cmd_find_window_exec(struct cmd *, struct cmd_ctx *);
31:
32: void cmd_find_window_callback(void *, int);
1.7 nicm 33: void cmd_find_window_free(void *);
1.1 nicm 34:
35: const struct cmd_entry cmd_find_window_entry = {
36: "find-window", "findw",
1.8 ! nicm 37: "t:", 1, 1,
1.1 nicm 38: CMD_TARGET_WINDOW_USAGE " match-string",
1.8 ! nicm 39: 0,
! 40: NULL,
! 41: NULL,
! 42: cmd_find_window_exec
1.1 nicm 43: };
44:
45: struct cmd_find_window_data {
1.7 nicm 46: struct session *session;
1.1 nicm 47: };
48:
49: int
50: cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
51: {
1.8 ! nicm 52: struct args *args = self->args;
1.1 nicm 53: struct cmd_find_window_data *cdata;
54: struct session *s;
55: struct winlink *wl, *wm;
56: struct window *w;
57: struct window_pane *wp;
58: ARRAY_DECL(, u_int) list_idx;
59: ARRAY_DECL(, char *) list_ctx;
1.8 ! nicm 60: char *str, *sres, *sctx, *searchstr;
1.2 nicm 61: u_int i, line;
1.1 nicm 62:
63: if (ctx->curclient == NULL) {
64: ctx->error(ctx, "must be run interactively");
65: return (-1);
66: }
67: s = ctx->curclient->session;
68:
1.8 ! nicm 69: if ((wl = cmd_find_window(ctx, args_get(args, 't'), NULL)) == NULL)
1.1 nicm 70: return (-1);
71:
1.8 ! nicm 72: str = args->argv[0];
! 73:
1.1 nicm 74: ARRAY_INIT(&list_idx);
75: ARRAY_INIT(&list_ctx);
76:
1.8 ! nicm 77: xasprintf(&searchstr, "*%s*", str);
1.1 nicm 78: RB_FOREACH(wm, winlinks, &s->windows) {
79: i = 0;
80: TAILQ_FOREACH(wp, &wm->window->panes, entry) {
81: i++;
82:
1.2 nicm 83: if (fnmatch(searchstr, wm->window->name, 0) == 0)
1.1 nicm 84: sctx = xstrdup("");
85: else {
1.8 ! nicm 86: sres = window_pane_search(wp, str, &line);
1.1 nicm 87: if (sres == NULL &&
1.2 nicm 88: fnmatch(searchstr, wp->base.title, 0) != 0)
1.1 nicm 89: continue;
90:
91: if (sres == NULL) {
92: xasprintf(&sctx,
93: "pane %u title: \"%s\"", i - 1,
94: wp->base.title);
95: } else {
1.2 nicm 96: xasprintf(&sctx,
97: "pane %u line %u: \"%s\"", i - 1,
98: line + 1, sres);
1.1 nicm 99: xfree(sres);
100: }
101: }
102:
103: ARRAY_ADD(&list_idx, wm->idx);
104: ARRAY_ADD(&list_ctx, sctx);
105: }
106: }
1.2 nicm 107: xfree(searchstr);
1.1 nicm 108:
109: if (ARRAY_LENGTH(&list_idx) == 0) {
1.8 ! nicm 110: ctx->error(ctx, "no windows matching: %s", str);
1.1 nicm 111: ARRAY_FREE(&list_idx);
112: ARRAY_FREE(&list_ctx);
113: return (-1);
114: }
115:
116: if (ARRAY_LENGTH(&list_idx) == 1) {
117: if (session_select(s, ARRAY_FIRST(&list_idx)) == 0)
118: server_redraw_session(s);
119: recalculate_sizes();
120: goto out;
121: }
122:
123: if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
124: goto out;
125:
126: for (i = 0; i < ARRAY_LENGTH(&list_idx); i++) {
127: wm = winlink_find_by_index(
128: &s->windows, ARRAY_ITEM(&list_idx, i));
129: w = wm->window;
130:
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);
135: xfree(sctx);
136: }
137:
138: cdata = xmalloc(sizeof *cdata);
1.7 nicm 139: cdata->session = s;
140: cdata->session->references++;
1.1 nicm 141:
1.7 nicm 142: window_choose_ready(wl->window->active,
143: 0, cmd_find_window_callback, cmd_find_window_free, cdata);
1.1 nicm 144:
145: out:
146: ARRAY_FREE(&list_idx);
147: ARRAY_FREE(&list_ctx);
148:
149: return (0);
150: }
151:
152: void
153: cmd_find_window_callback(void *data, int idx)
154: {
155: struct cmd_find_window_data *cdata = data;
1.7 nicm 156: struct session *s = cdata->session;
157:
158: if (idx == -1)
159: return;
160: if (!session_alive(s))
161: return;
1.1 nicm 162:
1.7 nicm 163: if (session_select(s, idx) == 0) {
164: server_redraw_session(s);
1.1 nicm 165: recalculate_sizes();
166: }
1.7 nicm 167: }
168:
169: void
170: cmd_find_window_free(void *data)
171: {
172: struct cmd_find_window_data *cdata = data;
173:
174: cdata->session->references--;
175: xfree(cdata);
1.1 nicm 176: }