Extend display-message to work for control clients. GitHub issue 3449.

This commit is contained in:
nicm 2023-02-05 21:15:32 +00:00
parent f10854cfc5
commit 93b1b78150
5 changed files with 84 additions and 67 deletions

View File

@ -68,9 +68,10 @@ cmd_display_message_exec(struct cmd *self, struct cmdq_item *item)
struct window_pane *wp = target->wp; struct window_pane *wp = target->wp;
const char *template; const char *template;
char *msg, *cause; char *msg, *cause;
int delay = -1, flags; int delay = -1, flags, Nflag = args_has(args, 'N');
struct format_tree *ft; struct format_tree *ft;
u_int count = args_count(args); u_int count = args_count(args);
struct evbuffer *evb;
if (args_has(args, 'I')) { if (args_has(args, 'I')) {
if (wp == NULL) if (wp == NULL)
@ -141,10 +142,15 @@ cmd_display_message_exec(struct cmd *self, struct cmdq_item *item)
cmdq_error(item, "%s", msg); cmdq_error(item, "%s", msg);
else if (args_has(args, 'p')) else if (args_has(args, 'p'))
cmdq_print(item, "%s", msg); cmdq_print(item, "%s", msg);
else if (tc != NULL) { else if (tc != NULL && (tc->flags & CLIENT_CONTROL)) {
status_message_set(tc, delay, 0, args_has(args, 'N'), "%s", evb = evbuffer_new();
msg); if (evb == NULL)
} fatalx("out of memory");
evbuffer_add_printf(evb, "%%message %s", msg);
server_client_print(tc, 0, evb);
evbuffer_free(evb);
} else if (tc != NULL)
status_message_set(tc, delay, 0, Nflag, "%s", msg);
free(msg); free(msg);
format_free(ft); format_free(ft);

View File

@ -826,68 +826,7 @@ cmdq_guard(struct cmdq_item *item, const char *guard, int flags)
void void
cmdq_print_data(struct cmdq_item *item, int parse, struct evbuffer *evb) cmdq_print_data(struct cmdq_item *item, int parse, struct evbuffer *evb)
{ {
struct client *c = item->client; server_client_print(item->client, parse, evb);
void *data = EVBUFFER_DATA(evb);
size_t size = EVBUFFER_LENGTH(evb);
struct window_pane *wp;
struct window_mode_entry *wme;
char *sanitized, *msg, *line;
if (!parse) {
utf8_stravisx(&msg, data, size,
VIS_OCTAL|VIS_CSTYLE|VIS_NOSLASH);
log_debug("%s: %s", __func__, msg);
} else {
msg = EVBUFFER_DATA(evb);
if (msg[size - 1] != '\0')
evbuffer_add(evb, "", 1);
}
if (c == NULL)
goto out;
if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
if (~c->flags & CLIENT_UTF8) {
sanitized = utf8_sanitize(msg);
if (c->flags & CLIENT_CONTROL)
control_write(c, "%s", sanitized);
else
file_print(c, "%s\n", sanitized);
free(sanitized);
} else {
if (c->flags & CLIENT_CONTROL)
control_write(c, "%s", msg);
else
file_print(c, "%s\n", msg);
}
goto out;
}
wp = server_client_get_pane(c);
wme = TAILQ_FIRST(&wp->modes);
if (wme == NULL || wme->mode != &window_view_mode)
window_pane_set_mode(wp, NULL, &window_view_mode, NULL, NULL);
if (parse) {
do {
line = evbuffer_readln(evb, NULL, EVBUFFER_EOL_LF);
if (line != NULL) {
window_copy_add(wp, 1, "%s", line);
free(line);
}
} while (line != NULL);
size = EVBUFFER_LENGTH(evb);
if (size != 0) {
line = EVBUFFER_DATA(evb);
window_copy_add(wp, 1, "%.*s", (int)size, line);
}
} else
window_copy_add(wp, 0, "%s", msg);
out:
if (!parse)
free(msg);
} }
/* Show message from command. */ /* Show message from command. */

View File

@ -29,6 +29,7 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <vis.h>
#include "tmux.h" #include "tmux.h"
@ -3239,3 +3240,69 @@ server_client_remove_pane(struct window_pane *wp)
} }
} }
} }
/* Print to a client. */
void
server_client_print(struct client *c, int parse, struct evbuffer *evb)
{
void *data = EVBUFFER_DATA(evb);
size_t size = EVBUFFER_LENGTH(evb);
struct window_pane *wp;
struct window_mode_entry *wme;
char *sanitized, *msg, *line;
if (!parse) {
utf8_stravisx(&msg, data, size,
VIS_OCTAL|VIS_CSTYLE|VIS_NOSLASH);
log_debug("%s: %s", __func__, msg);
} else {
msg = EVBUFFER_DATA(evb);
if (msg[size - 1] != '\0')
evbuffer_add(evb, "", 1);
}
if (c == NULL)
goto out;
if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
if (~c->flags & CLIENT_UTF8) {
sanitized = utf8_sanitize(msg);
if (c->flags & CLIENT_CONTROL)
control_write(c, "%s", sanitized);
else
file_print(c, "%s\n", sanitized);
free(sanitized);
} else {
if (c->flags & CLIENT_CONTROL)
control_write(c, "%s", msg);
else
file_print(c, "%s\n", msg);
}
goto out;
}
wp = server_client_get_pane(c);
wme = TAILQ_FIRST(&wp->modes);
if (wme == NULL || wme->mode != &window_view_mode)
window_pane_set_mode(wp, NULL, &window_view_mode, NULL, NULL);
if (parse) {
do {
line = evbuffer_readln(evb, NULL, EVBUFFER_EOL_LF);
if (line != NULL) {
window_copy_add(wp, 1, "%s", line);
free(line);
}
} while (line != NULL);
size = EVBUFFER_LENGTH(evb);
if (size != 0) {
line = EVBUFFER_DATA(evb);
window_copy_add(wp, 1, "%.*s", (int)size, line);
}
} else
window_copy_add(wp, 0, "%s", msg);
out:
if (!parse)
free(msg);
}

4
tmux.1
View File

@ -6627,6 +6627,10 @@ The window's visible layout is
.Ar window-visible-layout .Ar window-visible-layout
and the window flags are and the window flags are
.Ar window-flags . .Ar window-flags .
.It Ic %message Ar message
A message sent with the
.Ic display-message
command.
.It Ic %output Ar pane-id Ar value .It Ic %output Ar pane-id Ar value
A window pane produced output. A window pane produced output.
.Ar value .Ar value

1
tmux.h
View File

@ -2678,6 +2678,7 @@ struct client_window *server_client_add_client_window(struct client *, u_int);
struct window_pane *server_client_get_pane(struct client *); struct window_pane *server_client_get_pane(struct client *);
void server_client_set_pane(struct client *, struct window_pane *); void server_client_set_pane(struct client *, struct window_pane *);
void server_client_remove_pane(struct window_pane *); void server_client_remove_pane(struct window_pane *);
void server_client_print(struct client *, int, struct evbuffer *);
/* server-fn.c */ /* server-fn.c */
void server_redraw_client(struct client *); void server_redraw_client(struct client *);