Annotation of src/usr.bin/tmux/cmd-find-window.c, Revision 1.7
1.7 ! nicm 1: /* $OpenBSD: cmd-find-window.c,v 1.6 2009/11/13 19:53:29 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",
37: CMD_TARGET_WINDOW_USAGE " match-string",
1.6 nicm 38: CMD_ARG1, "",
1.1 nicm 39: cmd_target_init,
40: cmd_target_parse,
41: cmd_find_window_exec,
42: cmd_target_free,
43: cmd_target_print
44: };
45:
46: struct cmd_find_window_data {
1.7 ! nicm 47: struct session *session;
1.1 nicm 48: };
49:
50: int
51: cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
52: {
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;
1.2 nicm 61: char *sres, *sctx, *searchstr;
62: u_int i, line;
1.1 nicm 63:
64: if (ctx->curclient == NULL) {
65: ctx->error(ctx, "must be run interactively");
66: return (-1);
67: }
68: s = ctx->curclient->session;
69:
70: if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
71: return (-1);
72:
73: ARRAY_INIT(&list_idx);
74: ARRAY_INIT(&list_ctx);
75:
1.2 nicm 76: xasprintf(&searchstr, "*%s*", data->arg);
1.1 nicm 77: RB_FOREACH(wm, winlinks, &s->windows) {
78: i = 0;
79: TAILQ_FOREACH(wp, &wm->window->panes, entry) {
80: i++;
81:
1.2 nicm 82: if (fnmatch(searchstr, wm->window->name, 0) == 0)
1.1 nicm 83: sctx = xstrdup("");
84: else {
1.2 nicm 85: sres = window_pane_search(wp, data->arg, &line);
1.1 nicm 86: if (sres == NULL &&
1.2 nicm 87: fnmatch(searchstr, wp->base.title, 0) != 0)
1.1 nicm 88: continue;
89:
90: if (sres == NULL) {
91: xasprintf(&sctx,
92: "pane %u title: \"%s\"", i - 1,
93: wp->base.title);
94: } else {
1.2 nicm 95: xasprintf(&sctx,
96: "pane %u line %u: \"%s\"", i - 1,
97: line + 1, sres);
1.1 nicm 98: xfree(sres);
99: }
100: }
101:
102: ARRAY_ADD(&list_idx, wm->idx);
103: ARRAY_ADD(&list_ctx, sctx);
104: }
105: }
1.2 nicm 106: xfree(searchstr);
1.1 nicm 107:
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);
113: }
114:
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;
120: }
121:
122: if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
123: goto out;
124:
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;
129:
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);
135: }
136:
137: cdata = xmalloc(sizeof *cdata);
1.7 ! nicm 138: cdata->session = s;
! 139: cdata->session->references++;
1.1 nicm 140:
1.7 ! nicm 141: window_choose_ready(wl->window->active,
! 142: 0, cmd_find_window_callback, cmd_find_window_free, cdata);
1.1 nicm 143:
144: out:
145: ARRAY_FREE(&list_idx);
146: ARRAY_FREE(&list_ctx);
147:
148: return (0);
149: }
150:
151: void
152: cmd_find_window_callback(void *data, int idx)
153: {
154: struct cmd_find_window_data *cdata = data;
1.7 ! nicm 155: struct session *s = cdata->session;
! 156:
! 157: if (idx == -1)
! 158: return;
! 159: if (!session_alive(s))
! 160: return;
1.1 nicm 161:
1.7 ! nicm 162: if (session_select(s, idx) == 0) {
! 163: server_redraw_session(s);
1.1 nicm 164: recalculate_sizes();
165: }
1.7 ! nicm 166: }
! 167:
! 168: void
! 169: cmd_find_window_free(void *data)
! 170: {
! 171: struct cmd_find_window_data *cdata = data;
! 172:
! 173: cdata->session->references--;
! 174: xfree(cdata);
1.1 nicm 175: }