The branch, hooks has been updated
       via  940a4d033f7173c06d48960cecf7ae95468c07ce (commit)
      from  49aba762dd836d9400ef306eeab555c40a501ce6 (commit)

- Log -----------------------------------------------------------------
commit 940a4d033f7173c06d48960cecf7ae95468c07ce
Author: Thomas Adam <[email protected]>
Commit: Thomas Adam <[email protected]>

    Introduce alerts for hooks
    
    This further builds on alerts with hooks.  A struct alert is created
    whenever an alert is found to have a hook.  In it, are the session and the
    winlinks for that alert.
    
    When the hook command is run, the state is checked in the usual way, but
    this time, when looking up the session, window and pane, preference is given
    to those items having an alert.
    
    This allows hooked commands on bell events to fire on the correct session.
    Since alerts operate outside of the usual way commands make it to tmux (they
    can happen at any time), this seems like a sane approach.
    
    Making alerts an inherent property of the session might be an idea for the
    future.
---
 cmd.c           |   86 ++++++++++++++++++++++++++++++++++++++++++++++++-------
 server-window.c |   42 +++++++++++++++++++++++++-
 tmux.h          |    6 +++-
 3 files changed, 120 insertions(+), 14 deletions(-)

diff --git a/cmd.c b/cmd.c
index d41cf8d..3feeb47 100644
--- a/cmd.c
+++ b/cmd.c
@@ -35,6 +35,7 @@ int            cmd_find_index(struct cmd_q *, const char *,
                     struct session **);
 struct winlink *cmd_find_pane(struct cmd_q *, const char *, struct session **,
                     struct window_pane **);
+int             cmd_has_session_alert(struct session *, struct alert **);
 
 const struct cmd_entry *cmd_table[] = {
        &cmd_attach_session_entry,
@@ -470,14 +471,18 @@ complete_everything:
                if (state->tflag.s == NULL) {
                        if (flags & CMD_PREP_CANFAIL)
                                return (0);
+
                        cmdq_error(cmdq, "no current session");
                        return (-1);
                }
        }
        if (state->tflag.wl == NULL)
-               state->tflag.wl = state->tflag.s->curw;
-       if (state->tflag.wp == NULL)
-               state->tflag.wp = state->tflag.wl->window->active;
+               state->tflag.wl = cmd_find_window(cmdq, tflag, &state->tflag.s);
+       if (state->tflag.wp == NULL) {
+               state->tflag.wl = cmd_find_pane(cmdq, tflag, &state->tflag.s,
+                   &state->tflag.wp);
+       }
+
        return (0);
 }
 
@@ -577,8 +582,10 @@ complete_everything:
        if (state->sflag.s == NULL) {
                if (state->c != NULL)
                        state->sflag.s = state->c->session;
+
                if (state->sflag.s == NULL)
                        state->sflag.s = cmd_current_session(cmdq, prefer);
+
                if (state->sflag.s == NULL) {
                        if (flags & CMD_PREP_CANFAIL)
                                return (0);
@@ -586,10 +593,14 @@ complete_everything:
                        return (-1);
                }
        }
-       if (state->sflag.wl == NULL)
-               state->sflag.wl = state->sflag.s->curw;
-       if (state->sflag.wp == NULL)
-               state->sflag.wp = state->sflag.wl->window->active;
+       if (state->sflag.wl == NULL) {
+               state->sflag.wl = cmd_find_pane(cmdq, sflag, &state->sflag.s,
+                   &state->sflag.wp);
+       }
+       if (state->sflag.wp == NULL) {
+               state->sflag.wl = cmd_find_pane(cmdq, sflag, &state->sflag.s,
+                   &state->sflag.wp);
+       }
        return (0);
 }
 
@@ -664,6 +675,21 @@ cmd_print(struct cmd *cmd, char *buf, size_t len)
        return (off);
 }
 
+int
+cmd_has_session_alert(struct session *s, struct alert **al)
+{
+       struct alert    *al1;
+
+       RB_FOREACH(al1, alerts, &alerts) {
+               if (al1->s == s) {
+                       if (al != NULL)
+                               *al = al1;
+                       return (1);
+               }
+       }
+       return (0);
+}
+
 /*
  * Figure out the current session. Use: 1) the current session, if the command
  * context has one; 2) the most recently used session containing the pty of the
@@ -682,9 +708,19 @@ cmd_current_session(struct cmd_q *cmdq, int 
prefer_unattached)
        const char              *path;
        int                      found;
 
-       if (c != NULL && c->session != NULL)
+       /* If there's no alerts present, and there's a current session, return
+        * that.
+        */
+       if (RB_EMPTY(&alerts) && c != NULL && c->session != NULL)
                return (c->session);
 
+       /* Check all sessions for alerts, and for any one found, use that. */
+       RB_FOREACH(s, sessions, &sessions) {
+               if (cmd_has_session_alert(s, NULL)) {
+                       return (s);
+               }
+       }
+
        /*
         * If the name of the calling client's pty is known, build a list of
         * the sessions that contain it and if any choose either the first or
@@ -1194,6 +1230,7 @@ cmd_find_window(struct cmd_q *cmdq, const char *arg, 
struct session **sp)
 {
        struct session  *s;
        struct winlink  *wl;
+       struct alert    *al;
        const char      *winptr;
        char            *sessptr = NULL;
        int              ambiguous = 0;
@@ -1211,6 +1248,13 @@ cmd_find_window(struct cmd_q *cmdq, const char *arg, 
struct session **sp)
        if (arg == NULL) {
                if (sp != NULL)
                        *sp = s;
+               if (cmd_has_session_alert(s, &al)) {
+                       RB_FOREACH(wl, winlinks, &s->windows) {
+                               if (wl->flags & al->flag) {
+                                       return (wl);
+                               }
+                       }
+               }
                return (s->curw);
        }
 
@@ -1489,6 +1533,7 @@ cmd_find_pane(struct cmd_q *cmdq,
 {
        struct session  *s;
        struct winlink  *wl;
+       struct alert    *al;
        const char      *period, *errstr;
        char            *winptr, *paneptr;
        u_int            idx;
@@ -1501,10 +1546,29 @@ cmd_find_pane(struct cmd_q *cmdq,
        if (sp != NULL)
                *sp = s;
 
-       /* A NULL argument means the current session, window and pane. */
+       /*
+        * A NULL argument means the current session, window and pane, if the
+        * session doesn't have any alerts associated with it though.
+        */
        if (arg == NULL) {
-               *wpp = s->curw->window->active;
-               return (s->curw);
+               if (!cmd_has_session_alert(s, &al))
+                       return (s->curw);
+               else {
+                       /*
+                        * The session has an alert associated with it.  Find
+                        * the matching winlink in its list for the alert
+                        * type, and return that instead.
+                        */
+                       RB_FOREACH(wl, winlinks, &al->windows) {
+                               if (wl->flags & al->flag) {
+                                       *wpp = wl->window->active;
+                                       return (wl);
+                               }
+                       }
+                       /* No alert found, use the current window and pane. */
+                       *wpp = s->curw->window->active;
+                       return (s->curw);
+               }
        }
 
        /* Lookup as pane id. */
diff --git a/server-window.c b/server-window.c
index d5e29fe..2f108cd 100644
--- a/server-window.c
+++ b/server-window.c
@@ -48,7 +48,27 @@ const struct window_flag_hook         
window_flag_hook_names[] = {
 int
 alert_cmp(struct alert *a1, struct alert *a2)
 {
-       return (strcmp(a1->s->name, a2->s->name));
+       return strcmp(a1->name, a2->name);
+}
+
+struct alert *
+alert_new(void)
+{
+       struct alert    *al;
+
+       al = xcalloc(1, sizeof *al);
+       return (al);
+}
+
+void
+alert_free(struct alert *al)
+{
+       struct winlink  *wl,* wl1;
+
+       RB_REMOVE(alerts, &alerts, al);
+       RB_FOREACH_SAFE(wl, winlinks, &al->windows, wl1)
+               winlink_remove(&al->windows, wl);
+       free(al);
 }
 
 /* Window functions that need to happen every loop. */
@@ -85,12 +105,16 @@ void
 server_window_run_hooks(struct session *s, struct winlink *wl)
 {
        struct hooks    *hooks;
+       struct alert    *al, al_find;
+       struct winlink  *wl_new;
        const char      *hook_name = NULL;
        u_int            i;
+       int              flag;
 
        for (i = 0; i < nitems(window_flag_hook_names); i++) {
                if (wl->flags & window_flag_hook_names[i].flag) {
                        hook_name = window_flag_hook_names[i].name;
+                       flag = window_flag_hook_names[i].flag;
                        break;
                }
        }
@@ -98,8 +122,22 @@ server_window_run_hooks(struct session *s, struct winlink 
*wl)
        if (hook_name == NULL)
                return;
 
-       hooks = s == NULL ? &global_hooks : &s->hooks;
+       al_find.name = hook_name;
+       if ((al = RB_FIND(alerts, &alerts, &al_find)) == NULL) {
+               al = alert_new();
+               al->name = hook_name;
+               al->flag = flag;
+               al->s = s;
+               RB_INIT(&al->windows);
+       }
+       wl_new = winlink_add(&al->windows, wl->idx);
+       winlink_set_window(wl_new, wl->window);
+       wl_new->flags |= wl->flags & WINLINK_ALERTFLAGS;
+       RB_INSERT(alerts, &alerts, al);
+
+       hooks = &s->hooks;
        cmdq_hooks_run(hooks, NULL, hook_name, NULL);
+       alert_free(al);
 }
 
 
diff --git a/tmux.h b/tmux.h
index ad98fd5..c998d72 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1087,6 +1087,8 @@ ARRAY_DECL(sessionslist, struct session *);
 
 /* Alert information. */
 struct alert {
+       const char      *name;
+       int              flag;
        struct session  *s;
        struct winlinks  windows;
        RB_ENTRY(alert)  entry;
@@ -1952,7 +1954,9 @@ void       server_client_loop(void);
 /* server-window.c */
 extern struct alerts alerts;
 RB_PROTOTYPE(alerts, alert, entry, alert_cmp);
-int     alert_cmp(struct alert *, struct alert *);
+int             alert_cmp(struct alert *, struct alert *);
+struct alert   *alert_new(void);
+void            alert_free(struct alert *);
 void    server_window_loop(void);
 
 /* server-fn.c */


-----------------------------------------------------------------------

Summary of changes:
 cmd.c           |   86 ++++++++++++++++++++++++++++++++++++++++++++++++-------
 server-window.c |   42 +++++++++++++++++++++++++-
 tmux.h          |    6 +++-
 3 files changed, 120 insertions(+), 14 deletions(-)


hooks/post-receive
-- 
tmux

------------------------------------------------------------------------------
BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT
Develop your own process in accordance with the BPMN 2 standard
Learn Process modeling best practices with Bonita BPM through live exercises
http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual- event?utm_
source=Sourceforge_BPM_Camp_5_6_15&utm_medium=email&utm_campaign=VA_SF
_______________________________________________
tmux-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tmux-cvs

Reply via email to