I tend to have a lot of windows with long-ish processes running in them, and wanted a way to see their status at a glance. Specifically:
1) When a command completes the window status shows that it passed or failed, and the indicator disappears when I visit the window. 2) When a command starts, the window status gets a 'sticky' indicator showing that something is running. I can visit the window to see how a command is progressing, then when I switch to another window the running status stays. I was sort of able to do (1) using the alert and monitor-content indicators. I would use the return code of the finished command with my prompt command to echo a BEL char if it failed (causing the alert indicator), or the monitor-content would see my unlikely-to-appear prompt (causing that indicator). This worked okay, but sometimes processes would send a BEL and falsely trigger the done-and-failed indication, and the monitor-content indicator has the known behavior that some output causes the window to be rescanned and a previous prompt would falsely trigger the done-and-passed indication. I couldn't figure out a way to do (2). And so this patch. It does the simplest possible thing that would work: I copied the behavior of the alert indicator and check for certain low-number ASCII codes and change the indicator accordingly. Then I use the pre-command and post-command variables of my shell to send the appropriate ASCII codes. This works with zsh and tcsh (which I'm forced to use at work -- yeah yeah I know), and I have seen ways you could get the same behavior with bash. This is probably a rather naive approach; suggestions of a better way to do it are welcome. A cool extension of this would be allowing the user to add any number of regular/sticky indicators of their choosing. --- input.c | 11 +++++++++++ options-table.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ server-window.c | 42 +++++++++++++++++++++++++++++++++++++++++- status.c | 32 ++++++++++++++++++++++++++++++++ tmux.h | 9 ++++++++- window.c | 6 ++++++ 6 files changed, 143 insertions(+), 2 deletions(-) diff --git a/input.c b/input.c index 960a0e6..e165771 100644 --- a/input.c +++ b/input.c @@ -971,6 +971,17 @@ input_c0_dispatch(struct input_ctx *ictx) case '\017': /* SI */ ictx->cell.attr &= ~GRID_ATTR_CHARSET; break; + + case '\006': /* ACK */ + wp->window->flags |= WINDOW_PROC_PASS; + break; + case '\025': /* NAK */ + wp->window->flags |= WINDOW_PROC_FAIL; + break; + case '\026': /* SYN */ + wp->window->flags |= WINDOW_PROC_RUNNING; + break; + default: log_debug("%s: unknown '%c'", __func__, ictx->ch); break; diff --git a/options-table.c b/options-table.c index 8ce838a..8e06927 100644 --- a/options-table.c +++ b/options-table.c @@ -655,6 +655,51 @@ const struct options_table_entry window_options_table[] = { .default_num = 8 }, + { .name = "window-status-proc-pass-attr", + .type = OPTIONS_TABLE_ATTRIBUTES, + .default_num = GRID_ATTR_REVERSE + }, + + { .name = "window-status-proc-pass-bg", + .type = OPTIONS_TABLE_COLOUR, + .default_num = 8 + }, + + { .name = "window-status-proc-pass-fg", + .type = OPTIONS_TABLE_COLOUR, + .default_num = 8 + }, + + { .name = "window-status-proc-fail-attr", + .type = OPTIONS_TABLE_ATTRIBUTES, + .default_num = GRID_ATTR_REVERSE + }, + + { .name = "window-status-proc-fail-bg", + .type = OPTIONS_TABLE_COLOUR, + .default_num = 8 + }, + + { .name = "window-status-proc-fail-fg", + .type = OPTIONS_TABLE_COLOUR, + .default_num = 8 + }, + + { .name = "window-status-proc-running-attr", + .type = OPTIONS_TABLE_ATTRIBUTES, + .default_num = GRID_ATTR_REVERSE + }, + + { .name = "window-status-proc-running-bg", + .type = OPTIONS_TABLE_COLOUR, + .default_num = 8 + }, + + { .name = "window-status-proc-running-fg", + .type = OPTIONS_TABLE_COLOUR, + .default_num = 8 + }, + { .name = "window-status-attr", .type = OPTIONS_TABLE_ATTRIBUTES, .default_num = 0 diff --git a/server-window.c b/server-window.c index fce6439..97b3bbf 100644 --- a/server-window.c +++ b/server-window.c @@ -29,6 +29,7 @@ int server_window_check_activity(struct session *, struct winlink *); int server_window_check_silence(struct session *, struct winlink *); int server_window_check_content( struct session *, struct winlink *, struct window_pane *); +int server_window_check_proc(struct session *, struct winlink *); void ring_bell(struct session *); /* Window functions that need to happen every loop. */ @@ -53,7 +54,8 @@ server_window_loop(void) if (server_window_check_bell(s, wl) || server_window_check_activity(s, wl) || - server_window_check_silence(s, wl)) + server_window_check_silence(s, wl) || + server_window_check_proc(s, wl)) server_status_session(s); TAILQ_FOREACH(wp, &w->panes, entry) server_window_check_content(s, wl, wp); @@ -233,6 +235,44 @@ server_window_check_content( return (1); } +/* Check process state flags of window. */ +int +server_window_check_proc(struct session *s, struct winlink *wl) +{ + struct window *w = wl->window; + u_int modified = 0; + + if (w->flags & WINDOW_PROC_PASS && !(wl->flags & WINLINK_PROC_PASS)) { + if (s->curw != wl || s->flags & SESSION_UNATTACHED) + wl->flags |= WINLINK_PROC_PASS; + modified = 1; + } + + if (w->flags & WINDOW_PROC_FAIL && !(wl->flags & WINLINK_PROC_FAIL)) { + if (s->curw != wl || s->flags & SESSION_UNATTACHED) + wl->flags |= WINLINK_PROC_FAIL; + modified = 1; + } + + if (w->flags & WINDOW_PROC_RUNNING && !(wl->flags & WINLINK_PROC_RUNNING)) { + if (s->curw != wl || s->flags & SESSION_UNATTACHED) + wl->flags |= WINLINK_PROC_RUNNING; + modified = 1; + } + + if (s->flags & SESSION_UNATTACHED) + return (0); + if (w->flags & (WINDOW_PROC_PASS | WINDOW_PROC_FAIL)) { + w->flags &= ~WINDOW_PROC_RUNNING; + } + if (s->curw->window == wl->window) { + w->flags &= ~WINDOW_PROC_PASS; + w->flags &= ~WINDOW_PROC_FAIL; + } + + return (modified); +} + /* Ring terminal bell. */ void ring_bell(struct session *s) diff --git a/status.c b/status.c index e841d80..c5d253b 100644 --- a/status.c +++ b/status.c @@ -738,6 +738,38 @@ status_print( gc->attr = attr; } + if (wl->flags & WINLINK_PROC_PASS) { + fg = options_get_number(oo, "window-status-proc-pass-fg"); + if (fg != 8) + colour_set_fg(gc, fg); + bg = options_get_number(oo, "window-status-proc-pass-bg"); + if (bg != 8) + colour_set_bg(gc, bg); + attr = options_get_number(oo, "window-status-proc-pass-attr"); + if (attr != 0) + gc->attr = attr; + } else if (wl->flags & WINLINK_PROC_FAIL) { + fg = options_get_number(oo, "window-status-proc-fail-fg"); + if (fg != 8) + colour_set_fg(gc, fg); + bg = options_get_number(oo, "window-status-proc-fail-bg"); + if (bg != 8) + colour_set_bg(gc, bg); + attr = options_get_number(oo, "window-status-proc-fail-attr"); + if (attr != 0) + gc->attr = attr; + } else if ((wl->flags & WINLINK_PROC_RUNNING) && (wl != s->curw)) { + fg = options_get_number(oo, "window-status-proc-running-fg"); + if (fg != 8) + colour_set_fg(gc, fg); + bg = options_get_number(oo, "window-status-proc-running-bg"); + if (bg != 8) + colour_set_bg(gc, bg); + attr = options_get_number(oo, "window-status-proc-running-attr"); + if (attr != 0) + gc->attr = attr; + } + text = status_replace(c, NULL, wl, NULL, fmt, t, 1); return (text); } diff --git a/tmux.h b/tmux.h index faab3fe..02cbc49 100644 --- a/tmux.h +++ b/tmux.h @@ -1001,6 +1001,9 @@ struct window { #define WINDOW_ACTIVITY 0x2 #define WINDOW_REDRAW 0x4 #define WINDOW_SILENCE 0x8 +#define WINDOW_PROC_RUNNING 0x10 +#define WINDOW_PROC_PASS 0x20 +#define WINDOW_PROC_FAIL 0x40 struct options options; @@ -1022,8 +1025,12 @@ struct winlink { #define WINLINK_ACTIVITY 0x2 #define WINLINK_CONTENT 0x4 #define WINLINK_SILENCE 0x8 +#define WINLINK_PROC_RUNNING 0x10 +#define WINLINK_PROC_PASS 0x20 +#define WINLINK_PROC_FAIL 0x40 + #define WINLINK_ALERTFLAGS \ - (WINLINK_BELL|WINLINK_ACTIVITY|WINLINK_CONTENT|WINLINK_SILENCE) + (WINLINK_BELL|WINLINK_ACTIVITY|WINLINK_CONTENT|WINLINK_SILENCE|WINLINK_PROC_RUNNING|WINLINK_PROC_PASS|WINLINK_PROC_FAIL) RB_ENTRY(winlink) entry; TAILQ_ENTRY(winlink) sentry; diff --git a/window.c b/window.c index 5cdc504..71557b6 100644 --- a/window.c +++ b/window.c @@ -582,6 +582,12 @@ window_printable_flags(struct session *s, struct winlink *wl) flags[pos++] = '+'; if (wl->flags & WINLINK_SILENCE) flags[pos++] = '~'; + if (wl->flags & WINLINK_PROC_PASS) + flags[pos++] = '$'; + if (wl->flags & WINLINK_PROC_FAIL) + flags[pos++] = '%'; + if (wl->flags & WINLINK_PROC_RUNNING) + flags[pos++] = '&'; if (wl == s->curw) flags[pos++] = '*'; if (wl == TAILQ_FIRST(&s->lastw)) -- 1.7.8 ------------------------------------------------------------------------------ LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial Remotely access PCs and mobile devices and provide instant support Improve your efficiency, and focus on delivering more value-add services Discover what IT Professionals Know. Rescue delivers http://p.sf.net/sfu/logmein_12329d2d _______________________________________________ tmux-users mailing list tmux-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tmux-users