summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd-set-hook.c19
-rw-r--r--notify.c22
-rw-r--r--server-client.c18
-rw-r--r--tmux.120
-rw-r--r--tmux.h1
5 files changed, 60 insertions, 20 deletions
diff --git a/cmd-set-hook.c b/cmd-set-hook.c
index d0cd98db..b04e6335 100644
--- a/cmd-set-hook.c
+++ b/cmd-set-hook.c
@@ -33,8 +33,8 @@ const struct cmd_entry cmd_set_hook_entry = {
.name = "set-hook",
.alias = NULL,
- .args = { "gt:u", 1, 2 },
- .usage = "[-gu] " CMD_TARGET_SESSION_USAGE " hook-name [command]",
+ .args = { "gRt:u", 1, 2 },
+ .usage = "[-gRu] " CMD_TARGET_SESSION_USAGE " hook-name [command]",
.target = { 't', CMD_FIND_SESSION, CMD_FIND_CANFAIL },
@@ -101,18 +101,21 @@ cmd_set_hook_exec(struct cmd *self, struct cmdq_item *item)
else
cmd = args->argv[1];
+ if (cmd != NULL && (args_has(args, 'R') || args_has(args, 'u'))) {
+ cmdq_error(item, "no command allowed");
+ return (CMD_RETURN_ERROR);
+ }
+ if (args_has(args, 'R')) {
+ notify_hook(item, name);
+ return (CMD_RETURN_NORMAL);
+ }
if (args_has(args, 'u')) {
- if (cmd != NULL) {
- cmdq_error(item, "command passed to unset hook: %s",
- name);
- return (CMD_RETURN_ERROR);
- }
hooks_remove(hooks, name);
return (CMD_RETURN_NORMAL);
}
if (cmd == NULL) {
- cmdq_error(item, "no command to set hook: %s", name);
+ cmdq_error(item, "no command given");
return (CMD_RETURN_ERROR);
}
cmdlist = cmd_string_parse(cmd, NULL, 0, &cause);
diff --git a/notify.c b/notify.c
index 05b9d842..adef3d4e 100644
--- a/notify.c
+++ b/notify.c
@@ -35,7 +35,7 @@ struct notify_entry {
};
static void
-notify_hook(struct cmdq_item *item, struct notify_entry *ne)
+notify_hook1(struct cmdq_item *item, struct notify_entry *ne)
{
struct cmd_find_state fs;
struct hook *hook;
@@ -101,7 +101,7 @@ notify_callback(struct cmdq_item *item, void *data)
if (strcmp(ne->name, "session-window-changed") == 0)
control_notify_session_window_changed(ne->session);
- notify_hook(item, ne);
+ notify_hook1(item, ne);
if (ne->client != NULL)
server_client_unref(ne->client);
@@ -154,6 +154,24 @@ notify_add(const char *name, struct cmd_find_state *fs, struct client *c,
}
void
+notify_hook(struct cmdq_item *item, const char *name)
+{
+ struct notify_entry ne;
+
+ memset(&ne, 0, sizeof ne);
+
+ ne.name = name;
+ cmd_find_copy_state(&ne.fs, &item->target);
+
+ ne.client = item->client;
+ ne.session = item->target.s;
+ ne.window = item->target.w;
+ ne.pane = item->target.wp->id;
+
+ notify_hook1(item, &ne);
+}
+
+void
notify_input(struct window_pane *wp, struct evbuffer *input)
{
struct client *c;
diff --git a/server-client.c b/server-client.c
index dc84770a..94a024b0 100644
--- a/server-client.c
+++ b/server-client.c
@@ -1158,10 +1158,6 @@ server_client_check_focus(struct window_pane *wp)
push = wp->flags & PANE_FOCUSPUSH;
wp->flags &= ~PANE_FOCUSPUSH;
- /* If we don't care about focus, forget it. */
- if (!(wp->base.mode & MODE_FOCUSON))
- return;
-
/* If we're not the active pane in our window, we're not focused. */
if (wp->window->active != wp)
goto not_focused;
@@ -1185,14 +1181,20 @@ server_client_check_focus(struct window_pane *wp)
}
not_focused:
- if (push || (wp->flags & PANE_FOCUSED))
- bufferevent_write(wp->event, "\033[O", 3);
+ if (push || (wp->flags & PANE_FOCUSED)) {
+ if (wp->base.mode & MODE_FOCUSON)
+ bufferevent_write(wp->event, "\033[O", 3);
+ notify_pane("pane-focus-out", wp);
+ }
wp->flags &= ~PANE_FOCUSED;
return;
focused:
- if (push || !(wp->flags & PANE_FOCUSED))
- bufferevent_write(wp->event, "\033[I", 3);
+ if (push || !(wp->flags & PANE_FOCUSED)) {
+ if (wp->base.mode & MODE_FOCUSON)
+ bufferevent_write(wp->event, "\033[I", 3);
+ notify_pane("pane-focus-in", wp);
+ }
wp->flags |= PANE_FOCUSED;
}
diff --git a/tmux.1 b/tmux.1
index 7126e98f..a3830f8e 100644
--- a/tmux.1
+++ b/tmux.1
@@ -3427,6 +3427,14 @@ Run when the program running in a pane exits, but
is on so the pane has not closed.
.It pane-exited
Run when the program running in a pane exits.
+.It pane-focus-in
+Run when the focus enters a pane, if the
+.Ic focus-events
+option is on.
+.It pane-focus-out
+Run when the focus exits a pane, if the
+.Ic focus-events
+option is on.
.It pane-set-clipboard
Run when the terminal clipboard is set using the
.Xr xterm 1
@@ -3448,12 +3456,14 @@ Run when a window is unlinked from a session.
Hooks are managed with these commands:
.Bl -tag -width Ds
.It Xo Ic set-hook
-.Op Fl gu
+.Op Fl gRu
.Op Fl t Ar target-session
.Ar hook-name
.Ar command
.Xc
-Sets (or with
+Without
+.Fl R ,
+sets (or with
.Fl u
unsets) hook
.Ar hook-name
@@ -3469,6 +3479,12 @@ hooks (for
with
.Fl t ) .
Like options, session hooks inherit from the global ones.
+.Pp
+With
+.Fl R ,
+run
+.Ar hook-name
+immediately.
.It Xo Ic show-hooks
.Op Fl g
.Op Fl t Ar target-session
diff --git a/tmux.h b/tmux.h
index 01020400..52e61dad 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1598,6 +1598,7 @@ void printflike(4, 5) hooks_insert(struct hooks *, struct cmdq_item *,
struct cmd_find_state *, const char *, ...);
/* notify.c */
+void notify_hook(struct cmdq_item *, const char *);
void notify_input(struct window_pane *, struct evbuffer *);
void notify_client(const char *, struct client *);
void notify_session(const char *, struct session *);