From d79e52f98748e3c04b7dfbe287378fcb9058d005 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 15 Aug 2022 09:10:34 +0000 Subject: [PATCH] Notify when a paste buffer is deleted, GitHub issue 3302 from George Nachman. --- usr.bin/tmux/control-notify.c | 15 ++++++++++++++- usr.bin/tmux/notify.c | 31 +++++++++++++++++++++++-------- usr.bin/tmux/paste.c | 13 ++++++++++++- usr.bin/tmux/tmux.1 | 6 +++++- usr.bin/tmux/tmux.h | 4 +++- 5 files changed, 57 insertions(+), 12 deletions(-) diff --git a/usr.bin/tmux/control-notify.c b/usr.bin/tmux/control-notify.c index 8cef39ae072..3eab6d97a46 100644 --- a/usr.bin/tmux/control-notify.c +++ b/usr.bin/tmux/control-notify.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control-notify.c,v 1.29 2021/03/16 09:14:58 nicm Exp $ */ +/* $OpenBSD: control-notify.c,v 1.30 2022/08/15 09:10:34 nicm Exp $ */ /* * Copyright (c) 2012 Nicholas Marriott @@ -234,3 +234,16 @@ control_notify_session_window_changed(struct session *s) s->curw->window->id); } } + +void +control_notify_paste_buffer_changed(const char *name) +{ + struct client *c; + + TAILQ_FOREACH(c, &clients, entry) { + if (!CONTROL_SHOULD_NOTIFY_CLIENT(c)) + continue; + + control_write(c, "%%paste-changed %s", name); + } +} diff --git a/usr.bin/tmux/notify.c b/usr.bin/tmux/notify.c index cdb5fef6e44..18cee5c4f3f 100644 --- a/usr.bin/tmux/notify.c +++ b/usr.bin/tmux/notify.c @@ -1,4 +1,4 @@ -/* $OpenBSD: notify.c,v 1.41 2022/05/30 12:55:25 nicm Exp $ */ +/* $OpenBSD: notify.c,v 1.42 2022/08/15 09:10:34 nicm Exp $ */ /* * Copyright (c) 2012 George Nachman @@ -33,6 +33,7 @@ struct notify_entry { struct session *session; struct window *window; int pane; + const char *pbname; }; static struct cmdq_item * @@ -150,6 +151,8 @@ notify_callback(struct cmdq_item *item, void *data) control_notify_session_closed(ne->session); if (strcmp(ne->name, "session-window-changed") == 0) control_notify_session_window_changed(ne->session); + if (strcmp(ne->name, "paste-buffer-changed") == 0) + control_notify_paste_buffer_changed(ne->pbname); notify_insert_hook(item, ne); @@ -165,6 +168,7 @@ notify_callback(struct cmdq_item *item, void *data) format_free(ne->formats); free((void *)ne->name); + free((void *)ne->pbname); free(ne); return (CMD_RETURN_NORMAL); @@ -172,7 +176,8 @@ notify_callback(struct cmdq_item *item, void *data) static void notify_add(const char *name, struct cmd_find_state *fs, struct client *c, - struct session *s, struct window *w, struct window_pane *wp) + struct session *s, struct window *w, struct window_pane *wp, + const char *pbname) { struct notify_entry *ne; struct cmdq_item *item; @@ -188,6 +193,7 @@ notify_add(const char *name, struct cmd_find_state *fs, struct client *c, ne->session = s; ne->window = w; ne->pane = (wp != NULL ? wp->id : -1); + ne->pbname = (pbname != NULL ? xstrdup(pbname) : NULL); ne->formats = format_create(NULL, NULL, 0, FORMAT_NOJOBS); format_add(ne->formats, "hook", "%s", name); @@ -249,7 +255,7 @@ notify_client(const char *name, struct client *c) struct cmd_find_state fs; cmd_find_from_client(&fs, c, 0); - notify_add(name, &fs, c, NULL, NULL, NULL); + notify_add(name, &fs, c, NULL, NULL, NULL, NULL); } void @@ -261,7 +267,7 @@ notify_session(const char *name, struct session *s) cmd_find_from_session(&fs, s, 0); else cmd_find_from_nothing(&fs, 0); - notify_add(name, &fs, NULL, s, NULL, NULL); + notify_add(name, &fs, NULL, s, NULL, NULL, NULL); } void @@ -270,7 +276,7 @@ notify_winlink(const char *name, struct winlink *wl) struct cmd_find_state fs; cmd_find_from_winlink(&fs, wl, 0); - notify_add(name, &fs, NULL, wl->session, wl->window, NULL); + notify_add(name, &fs, NULL, wl->session, wl->window, NULL, NULL); } void @@ -279,7 +285,7 @@ notify_session_window(const char *name, struct session *s, struct window *w) struct cmd_find_state fs; cmd_find_from_session_window(&fs, s, w, 0); - notify_add(name, &fs, NULL, s, w, NULL); + notify_add(name, &fs, NULL, s, w, NULL, NULL); } void @@ -288,7 +294,7 @@ notify_window(const char *name, struct window *w) struct cmd_find_state fs; cmd_find_from_window(&fs, w, 0); - notify_add(name, &fs, NULL, NULL, w, NULL); + notify_add(name, &fs, NULL, NULL, w, NULL, NULL); } void @@ -297,5 +303,14 @@ notify_pane(const char *name, struct window_pane *wp) struct cmd_find_state fs; cmd_find_from_pane(&fs, wp, 0); - notify_add(name, &fs, NULL, NULL, NULL, wp); + notify_add(name, &fs, NULL, NULL, NULL, wp, NULL); +} + +void +notify_paste_buffer(const char *pbname) +{ + struct cmd_find_state fs; + + cmd_find_clear_state(&fs, 0); + notify_add("paste-buffer-changed", &fs, NULL, NULL, NULL, NULL, pbname); } diff --git a/usr.bin/tmux/paste.c b/usr.bin/tmux/paste.c index e23e97aedb3..f50549cd233 100644 --- a/usr.bin/tmux/paste.c +++ b/usr.bin/tmux/paste.c @@ -1,4 +1,4 @@ -/* $OpenBSD: paste.c,v 1.43 2022/06/04 07:42:07 nicm Exp $ */ +/* $OpenBSD: paste.c,v 1.44 2022/08/15 09:10:34 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -151,6 +151,8 @@ paste_get_name(const char *name) void paste_free(struct paste_buffer *pb) { + notify_paste_buffer(pb->name); + RB_REMOVE(paste_name_tree, &paste_by_name, pb); RB_REMOVE(paste_time_tree, &paste_by_time, pb); if (pb->automatic) @@ -207,6 +209,8 @@ paste_add(const char *prefix, char *data, size_t size) pb->order = paste_next_order++; RB_INSERT(paste_name_tree, &paste_by_name, pb); RB_INSERT(paste_time_tree, &paste_by_time, pb); + + notify_paste_buffer(pb->name); } /* Rename a paste buffer. */ @@ -254,6 +258,9 @@ paste_rename(const char *oldname, const char *newname, char **cause) RB_INSERT(paste_name_tree, &paste_by_name, pb); + notify_paste_buffer(oldname); + notify_paste_buffer(newname); + return (0); } @@ -302,6 +309,8 @@ paste_set(char *data, size_t size, const char *name, char **cause) RB_INSERT(paste_name_tree, &paste_by_name, pb); RB_INSERT(paste_time_tree, &paste_by_time, pb); + notify_paste_buffer(name); + return (0); } @@ -312,6 +321,8 @@ paste_replace(struct paste_buffer *pb, char *data, size_t size) free(pb->data); pb->data = data; pb->size = size; + + notify_paste_buffer(pb->name); } /* Convert start of buffer into a nice string. */ diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index 38ea1241e02..e668225ccdf 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.898 2022/08/15 08:54:03 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.899 2022/08/15 09:10:34 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -6596,6 +6596,10 @@ escapes non-printable characters and backslash as octal \\xxx. The pane with ID .Ar pane-id has changed mode. +.It Ic %paste-buffer-changed Ar name +Paste buffer +.Ar name +has been changed. .It Ic %pause Ar pane-id The pane has been paused (if the .Ar pause-after diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 81b208db68e..6e53865b3ac 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1180 2022/08/15 08:54:03 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1181 2022/08/15 09:10:34 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -2154,6 +2154,7 @@ void notify_winlink(const char *, struct winlink *); void notify_session_window(const char *, struct session *, struct window *); void notify_window(const char *, struct window *); void notify_pane(const char *, struct window_pane *); +void notify_paste_buffer(const char *); /* options.c */ struct options *options_create(struct options *); @@ -3174,6 +3175,7 @@ void control_notify_session_renamed(struct session *); void control_notify_session_created(struct session *); void control_notify_session_closed(struct session *); void control_notify_session_window_changed(struct session *); +void control_notify_paste_buffer_changed(const char *); /* session.c */ extern struct sessions sessions; -- 2.20.1