- New window option monitor-content to search for a string in a window, and

highlight the status line if it matches.
- To make this possible, the function cmd_find_window_search from
  cmd-find-window.c had to be moved to window.c and renamed window_pane_search.
- While there use three new functions in server.c to check for bell, activity,
  and content, to avoid too much nesting.
This commit is contained in:
Tiago Cunha 2009-05-19 13:32:55 +00:00
parent a385f75792
commit 80af85a102
11 changed files with 168 additions and 97 deletions

View File

@ -1,3 +1,8 @@
19 May 2009
* New window option: monitor-content. Searches for a string in a window and if
it matches, highlight the status line.
18 May 2009 18 May 2009
* main-horizontal layout and main-pane-height option to match vertical. * main-horizontal layout and main-pane-height option to match vertical.
@ -1270,7 +1275,7 @@
(including mutt, emacs). No status bar yet and no key remapping or other (including mutt, emacs). No status bar yet and no key remapping or other
customisation. customisation.
$Id: CHANGES,v 1.292 2009-05-18 22:17:24 nicm Exp $ $Id: CHANGES,v 1.293 2009-05-19 13:32:55 tcunha Exp $
LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr
LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms

View File

@ -1,4 +1,4 @@
/* $Id: cmd-find-window.c,v 1.7 2009-05-04 17:58:26 nicm Exp $ */ /* $Id: cmd-find-window.c,v 1.8 2009-05-19 13:32:55 tcunha Exp $ */
/* /*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@ -29,7 +29,6 @@
int cmd_find_window_exec(struct cmd *, struct cmd_ctx *); int cmd_find_window_exec(struct cmd *, struct cmd_ctx *);
void cmd_find_window_callback(void *, int); void cmd_find_window_callback(void *, int);
char *cmd_find_window_search(struct window_pane *, const char *);
const struct cmd_entry cmd_find_window_entry = { const struct cmd_entry cmd_find_window_entry = {
"find-window", "findw", "find-window", "findw",
@ -82,7 +81,7 @@ cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if (strstr(wm->window->name, data->arg) != NULL) if (strstr(wm->window->name, data->arg) != NULL)
sctx = xstrdup(""); sctx = xstrdup("");
else { else {
sres = cmd_find_window_search(wp, data->arg); sres = window_pane_search(wp, data->arg);
if (sres == NULL && if (sres == NULL &&
strstr(wp->base.title, data->arg) == NULL) strstr(wp->base.title, data->arg) == NULL)
continue; continue;
@ -159,46 +158,3 @@ cmd_find_window_callback(void *data, int idx)
} }
xfree(cdata); xfree(cdata);
} }
char *
cmd_find_window_search(struct window_pane *wp, const char *searchstr)
{
const struct grid_cell *gc;
const struct grid_utf8 *gu;
char *buf, *s;
size_t off;
u_int i, j, k;
buf = xmalloc(1);
for (j = 0; j < screen_size_y(&wp->base); j++) {
off = 0;
for (i = 0; i < screen_size_x(&wp->base); i++) {
gc = grid_view_peek_cell(wp->base.grid, i, j);
if (gc->flags & GRID_FLAG_UTF8) {
gu = grid_view_peek_utf8(wp->base.grid, i, j);
buf = xrealloc(buf, 1, off + 8);
for (k = 0; k < UTF8_SIZE; k++) {
if (gu->data[k] == 0xff)
break;
buf[off++] = gu->data[k];
}
} else {
buf = xrealloc(buf, 1, off + 1);
buf[off++] = gc->data;
}
}
while (off > 0 && buf[off - 1] == ' ')
off--;
buf[off] = '\0';
if ((s = strstr(buf, searchstr)) != NULL) {
s = section_string(buf, off, s - buf, 40);
xfree(buf);
return (s);
}
}
xfree(buf);
return (NULL);
}

View File

@ -1,4 +1,4 @@
/* $Id: cmd-set-window-option.c,v 1.25 2009-05-18 21:55:53 nicm Exp $ */ /* $Id: cmd-set-window-option.c,v 1.26 2009-05-19 13:32:55 tcunha Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@ -67,6 +67,7 @@ const struct set_option_entry set_window_option_table[NSETWINDOWOPTION] = {
{ "mode-fg", SET_OPTION_COLOUR, 0, 0, NULL }, { "mode-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-keys", SET_OPTION_CHOICE, 0, 0, set_option_mode_keys_list }, { "mode-keys", SET_OPTION_CHOICE, 0, 0, set_option_mode_keys_list },
{ "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL }, { "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-content", SET_OPTION_STRING, 0, 0, NULL },
{ "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL }, { "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
{ "utf8", SET_OPTION_FLAG, 0, 0, NULL }, { "utf8", SET_OPTION_FLAG, 0, 0, NULL },
{ "window-status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL }, { "window-status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },

View File

@ -1,7 +1,7 @@
" Vim syntax file " Vim syntax file
" Language: tmux(1) configuration file " Language: tmux(1) configuration file
" Maintainer: Tiago Cunha <me@tiagocunha.org> " Maintainer: Tiago Cunha <me@tiagocunha.org>
" Last Change: $Date: 2009-04-27 14:44:14 $ " Last Change: $Date: 2009-05-19 13:32:55 $
if version < 600 if version < 600
syntax clear syntax clear
@ -50,6 +50,7 @@ syn keyword tmuxOptsSetw force-height remain-on-exit uft8 mode-fg mode-bg
syn keyword tmuxOptsSetw mode-keys clock-mode-colour clock-mode-style syn keyword tmuxOptsSetw mode-keys clock-mode-colour clock-mode-style
syn keyword tmuxOptsSetw xterm-keys mode-attr window-status-attr syn keyword tmuxOptsSetw xterm-keys mode-attr window-status-attr
syn keyword tmuxOptsSetw window-status-bg window-status-fg automatic-rename syn keyword tmuxOptsSetw window-status-bg window-status-fg automatic-rename
syn keyword tmuxOptsSetw monitor-content
syn keyword tmuxTodo FIXME NOTE TODO XXX contained syn keyword tmuxTodo FIXME NOTE TODO XXX contained

128
server.c
View File

@ -1,4 +1,4 @@
/* $Id: server.c,v 1.144 2009-05-19 08:48:49 nicm Exp $ */ /* $Id: server.c,v 1.145 2009-05-19 13:32:55 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -53,7 +53,13 @@ void server_fill_clients(struct pollfd **);
void server_handle_clients(struct pollfd **); void server_handle_clients(struct pollfd **);
struct client *server_accept_client(int); struct client *server_accept_client(int);
void server_handle_client(struct client *); void server_handle_client(struct client *);
void server_handle_window(struct window *, struct window_pane *wp); void server_handle_window(struct window *, struct window_pane *);
int server_check_window_bell(struct session *, struct window *,
struct window_pane *);
int server_check_window_activity(struct session *,
struct window *);
int server_check_window_content(struct session *, struct window *,
struct window_pane *);
void server_lost_client(struct client *); void server_lost_client(struct client *);
void server_check_window(struct window *); void server_check_window(struct window *);
void server_check_redraw(struct client *); void server_check_redraw(struct client *);
@ -878,13 +884,12 @@ void
server_handle_window(struct window *w, struct window_pane *wp) server_handle_window(struct window *w, struct window_pane *wp)
{ {
struct session *s; struct session *s;
struct client *c; u_int i;
u_int i, j; int update;
int action, update;
window_pane_parse(wp); window_pane_parse(wp);
if (!(w->flags & WINDOW_BELL) && !(w->flags & WINDOW_ACTIVITY)) if ((w->flags & (WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_CONTENT)) == 0)
return; return;
update = 0; update = 0;
@ -893,45 +898,86 @@ server_handle_window(struct window *w, struct window_pane *wp)
if (s == NULL || !session_has(s, w)) if (s == NULL || !session_has(s, w))
continue; continue;
if (w->flags & WINDOW_BELL && update += server_check_window_bell(s, w, wp);
!session_alert_has_window(s, w, WINDOW_BELL)) { update += server_check_window_activity(s, w);
session_alert_add(s, w, WINDOW_BELL); update += server_check_window_content(s, w, wp);
action = options_get_number(&s->options, "bell-action");
switch (action) {
case BELL_ANY:
if (s->flags & SESSION_UNATTACHED)
break;
for (j = 0; j < ARRAY_LENGTH(&clients); j++) {
c = ARRAY_ITEM(&clients, j);
if (c != NULL && c->session == s)
tty_putcode(&c->tty, TTYC_BEL);
}
break;
case BELL_CURRENT:
if (w->active != wp)
break;
for (j = 0; j < ARRAY_LENGTH(&clients); j++) {
c = ARRAY_ITEM(&clients, j);
if (c != NULL && c->session == s)
tty_putcode(&c->tty, TTYC_BEL);
}
break;
}
update = 1;
}
if (options_get_number(&w->options, "monitor-activity") &&
(w->flags & WINDOW_ACTIVITY) &&
!session_alert_has_window(s, w, WINDOW_ACTIVITY)) {
session_alert_add(s, w, WINDOW_ACTIVITY);
update = 1;
}
} }
if (update) if (update)
server_status_window(w); server_status_window(w);
w->flags &= ~(WINDOW_BELL|WINDOW_ACTIVITY); w->flags &= ~(WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_CONTENT);
}
int
server_check_window_bell(
struct session *s, struct window *w, struct window_pane *wp)
{
struct client *c;
u_int i;
int action;
if (!(w->flags & WINDOW_BELL))
return (0);
if (session_alert_has_window(s, w, WINDOW_BELL))
return (0);
session_alert_add(s, w, WINDOW_BELL);
action = options_get_number(&s->options, "bell-action");
switch (action) {
case BELL_ANY:
if (s->flags & SESSION_UNATTACHED)
break;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && c->session == s)
tty_putcode(&c->tty, TTYC_BEL);
}
break;
case BELL_CURRENT:
if (w->active != wp)
break;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && c->session == s)
tty_putcode(&c->tty, TTYC_BEL);
}
break;
}
return (1);
}
int
server_check_window_activity(struct session *s, struct window *w)
{
if (!(w->flags & WINDOW_ACTIVITY))
return (0);
if (!options_get_number(&w->options, "monitor-activity"))
return (0);
if (session_alert_has_window(s, w, WINDOW_ACTIVITY))
return (0);
session_alert_add(s, w, WINDOW_ACTIVITY);
return (1);
}
int
server_check_window_content(
struct session *s, struct window *w, struct window_pane *wp)
{
char *found, *ptr;
if (!(w->flags & WINDOW_CONTENT))
return (0);
if ((ptr = options_get_string(&w->options, "monitor-content")) == NULL)
return (0);
if (*ptr == '\0')
return (0);
if (session_alert_has_window(s, w, WINDOW_CONTENT))
return (0);
if ((found = window_pane_search(wp, ptr)) == NULL)
return (0);
session_alert_add(s, w, WINDOW_CONTENT);
xfree(found);
return (1);
} }
/* Check if window still exists.. */ /* Check if window still exists.. */

View File

@ -1,4 +1,4 @@
/* $Id: session.c,v 1.56 2009-05-04 17:58:27 nicm Exp $ */ /* $Id: session.c,v 1.57 2009-05-19 13:32:55 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -266,6 +266,8 @@ session_next_activity(struct session *s, struct winlink *wl)
break; break;
if (session_alert_has(s, wl, WINDOW_ACTIVITY)) if (session_alert_has(s, wl, WINDOW_ACTIVITY))
break; break;
if (session_alert_has(s, wl, WINDOW_CONTENT))
break;
wl = winlink_next(&s->windows, wl); wl = winlink_next(&s->windows, wl);
} }
return (wl); return (wl);
@ -305,6 +307,8 @@ session_previous_activity(struct session *s, struct winlink *wl)
break; break;
if (session_alert_has(s, wl, WINDOW_ACTIVITY)) if (session_alert_has(s, wl, WINDOW_ACTIVITY))
break; break;
if (session_alert_has(s, wl, WINDOW_CONTENT))
break;
wl = winlink_previous(&s->windows, wl); wl = winlink_previous(&s->windows, wl);
} }
return (wl); return (wl);

View File

@ -1,4 +1,4 @@
/* $Id: status.c,v 1.81 2009-05-17 18:15:40 nicm Exp $ */ /* $Id: status.c,v 1.82 2009-05-19 13:32:55 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -184,6 +184,8 @@ draw:
larrow = -1; larrow = -1;
else if (session_alert_has(s, wl, WINDOW_BELL)) else if (session_alert_has(s, wl, WINDOW_BELL))
larrow = -1; larrow = -1;
else if (session_alert_has(s, wl, WINDOW_CONTENT))
larrow = -1;
} }
for (ptr = text; *ptr != '\0'; ptr++) { for (ptr = text; *ptr != '\0'; ptr++) {
@ -197,6 +199,8 @@ draw:
rarrow = -1; rarrow = -1;
else if (session_alert_has(s, wl, WINDOW_BELL)) else if (session_alert_has(s, wl, WINDOW_BELL))
rarrow = -1; rarrow = -1;
else if (session_alert_has(s, wl, WINDOW_CONTENT))
rarrow = -1;
} }
if (offset < start + width) { if (offset < start + width) {
@ -470,6 +474,9 @@ status_print(struct session *s, struct winlink *wl, struct grid_cell *gc)
} else if (session_alert_has(s, wl, WINDOW_BELL)) { } else if (session_alert_has(s, wl, WINDOW_BELL)) {
flag = '!'; flag = '!';
gc->attr ^= GRID_ATTR_REVERSE; gc->attr ^= GRID_ATTR_REVERSE;
} else if (session_alert_has(s, wl, WINDOW_CONTENT)) {
flag = '+';
gc->attr ^= GRID_ATTR_REVERSE;
} }
xasprintf(&text, "%d:%s%c", wl->idx, wl->window->name, flag); xasprintf(&text, "%d:%s%c", wl->idx, wl->window->name, flag);

7
tmux.1
View File

@ -1,4 +1,4 @@
.\" $Id: tmux.1,v 1.96 2009-05-18 21:58:40 nicm Exp $ .\" $Id: tmux.1,v 1.97 2009-05-19 13:32:55 tcunha Exp $
.\" .\"
.\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> .\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
.\" .\"
@ -1156,6 +1156,11 @@ Key bindings default to emacs.
.Xc .Xc
Monitor for activity in the window. Monitor for activity in the window.
Windows with activity are highlighted in the status line. Windows with activity are highlighted in the status line.
.It Xo Ic monitor-content Ar match-string
.Xc
Monitor content in the window. When
.Ar match-string
appears in the window, it is highlighted in the status line.
.It Xo Ic remain-on-exit .It Xo Ic remain-on-exit
.Op Ic on | Ic off .Op Ic on | Ic off
.Xc .Xc

3
tmux.c
View File

@ -1,4 +1,4 @@
/* $Id: tmux.c,v 1.119 2009-05-18 22:17:24 nicm Exp $ */ /* $Id: tmux.c,v 1.120 2009-05-19 13:32:55 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -328,6 +328,7 @@ main(int argc, char **argv)
options_set_number(&global_window_options, "mode-fg", 0); options_set_number(&global_window_options, "mode-fg", 0);
options_set_number(&global_window_options, "mode-keys", MODEKEY_EMACS); options_set_number(&global_window_options, "mode-keys", MODEKEY_EMACS);
options_set_number(&global_window_options, "monitor-activity", 0); options_set_number(&global_window_options, "monitor-activity", 0);
options_set_string(&global_window_options, "monitor-content", "%s", "");
options_set_number(&global_window_options, "utf8", 0); options_set_number(&global_window_options, "utf8", 0);
options_set_number(&global_window_options, "window-status-attr", 0); options_set_number(&global_window_options, "window-status-attr", 0);
options_set_number(&global_window_options, "window-status-bg", 8); options_set_number(&global_window_options, "window-status-bg", 8);

6
tmux.h
View File

@ -1,4 +1,4 @@
/* $Id: tmux.h,v 1.323 2009-05-18 21:55:53 nicm Exp $ */ /* $Id: tmux.h,v 1.324 2009-05-19 13:32:55 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -701,6 +701,7 @@ struct window {
#define WINDOW_BELL 0x1 #define WINDOW_BELL 0x1
#define WINDOW_HIDDEN 0x2 #define WINDOW_HIDDEN 0x2
#define WINDOW_ACTIVITY 0x4 #define WINDOW_ACTIVITY 0x4
#define WINDOW_CONTENT 0x6
#define WINDOW_REDRAW 0x8 #define WINDOW_REDRAW 0x8
struct options options; struct options options;
@ -1001,7 +1002,7 @@ struct set_option_entry {
extern const struct set_option_entry set_option_table[]; extern const struct set_option_entry set_option_table[];
extern const struct set_option_entry set_window_option_table[]; extern const struct set_option_entry set_window_option_table[];
#define NSETOPTION 24 #define NSETOPTION 24
#define NSETWINDOWOPTION 18 #define NSETWINDOWOPTION 19
#ifndef HAVE_STRTONUM #ifndef HAVE_STRTONUM
/* strtonum.c */ /* strtonum.c */
@ -1564,6 +1565,7 @@ void window_pane_parse(struct window_pane *);
void window_pane_key(struct window_pane *, struct client *, int); void window_pane_key(struct window_pane *, struct client *, int);
void window_pane_mouse(struct window_pane *, void window_pane_mouse(struct window_pane *,
struct client *, u_char, u_char, u_char); struct client *, u_char, u_char, u_char);
char *window_pane_search(struct window_pane *, const char *);
/* layout.c */ /* layout.c */
const char * layout_name(struct window *); const char * layout_name(struct window *);

View File

@ -1,4 +1,4 @@
/* $Id: window.c,v 1.77 2009-05-18 21:01:38 nicm Exp $ */ /* $Id: window.c,v 1.78 2009-05-19 13:32:55 tcunha Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -594,3 +594,46 @@ window_pane_mouse(
} else } else
input_mouse(wp, b, x, y); input_mouse(wp, b, x, y);
} }
char *
window_pane_search(struct window_pane *wp, const char *searchstr)
{
const struct grid_cell *gc;
const struct grid_utf8 *gu;
char *buf, *s;
size_t off;
u_int i, j, k;
buf = xmalloc(1);
for (j = 0; j < screen_size_y(&wp->base); j++) {
off = 0;
for (i = 0; i < screen_size_x(&wp->base); i++) {
gc = grid_view_peek_cell(wp->base.grid, i, j);
if (gc->flags & GRID_FLAG_UTF8) {
gu = grid_view_peek_utf8(wp->base.grid, i, j);
buf = xrealloc(buf, 1, off + 8);
for (k = 0; k < UTF8_SIZE; k++) {
if (gu->data[k] == 0xff)
break;
buf[off++] = gu->data[k];
}
} else {
buf = xrealloc(buf, 1, off + 1);
buf[off++] = gc->data;
}
}
while (off > 0 && buf[off - 1] == ' ')
off--;
buf[off] = '\0';
if ((s = strstr(buf, searchstr)) != NULL) {
s = section_string(buf, off, s - buf, 40);
xfree(buf);
return (s);
}
}
xfree(buf);
return (NULL);
}