diff --git a/CHANGES b/CHANGES index cc219150..8f080ec2 100644 --- a/CHANGES +++ b/CHANGES @@ -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 * 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 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: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms diff --git a/cmd-find-window.c b/cmd-find-window.c index a3a4a51b..fd0d9c60 100644 --- a/cmd-find-window.c +++ b/cmd-find-window.c @@ -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 @@ -29,7 +29,6 @@ int cmd_find_window_exec(struct cmd *, struct cmd_ctx *); 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 = { "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) sctx = xstrdup(""); else { - sres = cmd_find_window_search(wp, data->arg); + sres = window_pane_search(wp, data->arg); if (sres == NULL && strstr(wp->base.title, data->arg) == NULL) continue; @@ -159,46 +158,3 @@ cmd_find_window_callback(void *data, int idx) } 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); -} diff --git a/cmd-set-window-option.c b/cmd-set-window-option.c index 750c4d22..488bdfb1 100644 --- a/cmd-set-window-option.c +++ b/cmd-set-window-option.c @@ -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 @@ -67,6 +67,7 @@ const struct set_option_entry set_window_option_table[NSETWINDOWOPTION] = { { "mode-fg", SET_OPTION_COLOUR, 0, 0, NULL }, { "mode-keys", SET_OPTION_CHOICE, 0, 0, set_option_mode_keys_list }, { "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 }, { "utf8", SET_OPTION_FLAG, 0, 0, NULL }, { "window-status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL }, diff --git a/examples/tmux.vim b/examples/tmux.vim index 5e132393..169af940 100644 --- a/examples/tmux.vim +++ b/examples/tmux.vim @@ -1,7 +1,7 @@ " Vim syntax file " Language: tmux(1) configuration file " Maintainer: Tiago Cunha -" Last Change: $Date: 2009-04-27 14:44:14 $ +" Last Change: $Date: 2009-05-19 13:32:55 $ if version < 600 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 xterm-keys mode-attr window-status-attr syn keyword tmuxOptsSetw window-status-bg window-status-fg automatic-rename +syn keyword tmuxOptsSetw monitor-content syn keyword tmuxTodo FIXME NOTE TODO XXX contained diff --git a/server.c b/server.c index 7b243b57..b5308578 100644 --- a/server.c +++ b/server.c @@ -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 @@ -53,7 +53,13 @@ void server_fill_clients(struct pollfd **); void server_handle_clients(struct pollfd **); struct client *server_accept_client(int); 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_check_window(struct window *); void server_check_redraw(struct client *); @@ -878,13 +884,12 @@ void server_handle_window(struct window *w, struct window_pane *wp) { struct session *s; - struct client *c; - u_int i, j; - int action, update; + u_int i; + int update; window_pane_parse(wp); - if (!(w->flags & WINDOW_BELL) && !(w->flags & WINDOW_ACTIVITY)) + if ((w->flags & (WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_CONTENT)) == 0) return; update = 0; @@ -893,45 +898,86 @@ server_handle_window(struct window *w, struct window_pane *wp) if (s == NULL || !session_has(s, w)) continue; - if (w->flags & WINDOW_BELL && - !session_alert_has_window(s, w, WINDOW_BELL)) { - 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 (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; - } + update += server_check_window_bell(s, w, wp); + update += server_check_window_activity(s, w); + update += server_check_window_content(s, w, wp); } if (update) 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.. */ diff --git a/session.c b/session.c index 21eb8148..0a004677 100644 --- a/session.c +++ b/session.c @@ -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 @@ -266,6 +266,8 @@ session_next_activity(struct session *s, struct winlink *wl) break; if (session_alert_has(s, wl, WINDOW_ACTIVITY)) break; + if (session_alert_has(s, wl, WINDOW_CONTENT)) + break; wl = winlink_next(&s->windows, wl); } return (wl); @@ -305,6 +307,8 @@ session_previous_activity(struct session *s, struct winlink *wl) break; if (session_alert_has(s, wl, WINDOW_ACTIVITY)) break; + if (session_alert_has(s, wl, WINDOW_CONTENT)) + break; wl = winlink_previous(&s->windows, wl); } return (wl); diff --git a/status.c b/status.c index c89c0f00..da1bf83d 100644 --- a/status.c +++ b/status.c @@ -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 @@ -184,6 +184,8 @@ draw: larrow = -1; else if (session_alert_has(s, wl, WINDOW_BELL)) larrow = -1; + else if (session_alert_has(s, wl, WINDOW_CONTENT)) + larrow = -1; } for (ptr = text; *ptr != '\0'; ptr++) { @@ -197,6 +199,8 @@ draw: rarrow = -1; else if (session_alert_has(s, wl, WINDOW_BELL)) rarrow = -1; + else if (session_alert_has(s, wl, WINDOW_CONTENT)) + rarrow = -1; } 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)) { flag = '!'; 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); diff --git a/tmux.1 b/tmux.1 index 26958238..7ebc5625 100644 --- a/tmux.1 +++ b/tmux.1 @@ -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 .\" @@ -1156,6 +1156,11 @@ Key bindings default to emacs. .Xc Monitor for activity in the window. 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 .Op Ic on | Ic off .Xc diff --git a/tmux.c b/tmux.c index d96eedf0..67231221 100644 --- a/tmux.c +++ b/tmux.c @@ -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 @@ -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-keys", MODEKEY_EMACS); 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, "window-status-attr", 0); options_set_number(&global_window_options, "window-status-bg", 8); diff --git a/tmux.h b/tmux.h index fd518163..6e1f7ef7 100644 --- a/tmux.h +++ b/tmux.h @@ -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 @@ -701,6 +701,7 @@ struct window { #define WINDOW_BELL 0x1 #define WINDOW_HIDDEN 0x2 #define WINDOW_ACTIVITY 0x4 +#define WINDOW_CONTENT 0x6 #define WINDOW_REDRAW 0x8 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_window_option_table[]; #define NSETOPTION 24 -#define NSETWINDOWOPTION 18 +#define NSETWINDOWOPTION 19 #ifndef HAVE_STRTONUM /* 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_mouse(struct window_pane *, struct client *, u_char, u_char, u_char); +char *window_pane_search(struct window_pane *, const char *); /* layout.c */ const char * layout_name(struct window *); diff --git a/window.c b/window.c index 4836f0cb..4ebdf04b 100644 --- a/window.c +++ b/window.c @@ -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 @@ -594,3 +594,46 @@ window_pane_mouse( } else 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); +}