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
[email protected]
https://lists.sourceforge.net/lists/listinfo/tmux-users