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

Reply via email to