Change message log to be per server rather than per client and include every

command that is run.
This commit is contained in:
Nicholas Marriott 2020-05-06 13:43:22 +01:00
parent c80fc6bf9e
commit 7a95e9bf7e
9 changed files with 92 additions and 76 deletions

View File

@ -534,6 +534,27 @@ cmdq_find_flag(struct cmdq_item *item, struct cmd_find_state *fs,
return (CMD_RETURN_NORMAL);
}
/* Add message with command. */
static void
cmdq_add_message(struct cmdq_item *item)
{
struct client *c = item->client;
struct cmdq_state *state = item->state;
const char *name = c->name, *key;
char *tmp;
tmp = cmd_print(item->cmd);
if (c != NULL) {
if (c->session != NULL && state->event.key != KEYC_NONE) {
key = key_string_lookup_key(state->event.key);
server_add_message("%s key %s: %s", name, key, tmp);
} else
server_add_message("%s command: %s", name, tmp);
} else
server_add_message("command: %s", tmp);
free(tmp);
}
/* Fire command on command queue. */
static enum cmd_retval
cmdq_fire_command(struct cmdq_item *item)
@ -549,6 +570,8 @@ cmdq_fire_command(struct cmdq_item *item)
int flags, quiet = 0;
char *tmp;
if (cfg_finished)
cmdq_add_message(item);
if (log_get_level() > 1) {
tmp = cmd_print(cmd);
log_debug("%s %s: (%u) %s", __func__, name, item->group, tmp);
@ -819,6 +842,7 @@ cmdq_error(struct cmdq_item *item, const char *fmt, ...)
cmd_get_source(cmd, &file, &line);
cfg_add_cause("%s:%u: %s", file, line, msg);
} else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
server_add_message("%s message: %s", c->name, msg);
if (~c->flags & CLIENT_UTF8) {
tmp = msg;
msg = utf8_sanitize(tmp);

View File

@ -18,16 +18,19 @@
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "tmux.h"
/*
* Show client message log.
* Show message log.
*/
#define SHOW_MESSAGES_TEMPLATE \
"#{t/p:message_time}: #{message_text}"
static enum cmd_retval cmd_show_messages_exec(struct cmd *,
struct cmdq_item *);
@ -71,10 +74,10 @@ static enum cmd_retval
cmd_show_messages_exec(struct cmd *self, struct cmdq_item *item)
{
struct args *args = cmd_get_args(self);
struct client *tc = cmdq_get_target_client(item);
struct message_entry *msg;
char *tim;
char *s;
int done, blank;
struct format_tree *ft;
done = blank = 0;
if (args_has(args, 'T')) {
@ -88,11 +91,17 @@ cmd_show_messages_exec(struct cmd *self, struct cmdq_item *item)
if (done)
return (CMD_RETURN_NORMAL);
TAILQ_FOREACH(msg, &tc->message_log, entry) {
tim = ctime(&msg->msg_time);
*strchr(tim, '\n') = '\0';
cmdq_print(item, "%s %s", tim, msg->msg);
ft = format_create_from_target(item);
TAILQ_FOREACH_REVERSE(msg, &message_log, message_list, entry) {
format_add(ft, "message_text", "%s", msg->msg);
format_add(ft, "message_number", "%u", msg->msg_num);
format_add_tv(ft, "message_time", &msg->msg_time);
s = format_expand(ft, SHOW_MESSAGES_TEMPLATE);
cmdq_print(item, "%s", s);
free(s);
}
format_free(ft);
return (CMD_RETURN_NORMAL);
}

View File

@ -46,8 +46,6 @@ static void format_job_timer(int, short, void *);
static char *format_find(struct format_tree *, const char *, int);
static void format_add_cb(struct format_tree *, const char *, format_cb);
static void format_add_tv(struct format_tree *, const char *,
struct timeval *);
static int format_replace(struct format_tree *, const char *, size_t,
char **, size_t *, size_t *);
static void format_defaults_session(struct format_tree *,
@ -1260,7 +1258,7 @@ format_add(struct format_tree *ft, const char *key, const char *fmt, ...)
}
/* Add a key and time. */
static void
void
format_add_tv(struct format_tree *ft, const char *key, struct timeval *tv)
{
struct format_entry *fe, *fe_now;

View File

@ -252,7 +252,7 @@ const struct options_table_entry options_table[] = {
.scope = OPTIONS_TABLE_SERVER,
.minimum = 0,
.maximum = INT_MAX,
.default_num = 100
.default_num = 1000
},
{ .name = "set-clipboard",

View File

@ -211,23 +211,12 @@ server_client_create(int fd)
c->queue = cmdq_new();
c->tty.fd = -1;
c->title = NULL;
c->session = NULL;
c->last_session = NULL;
c->tty.sx = 80;
c->tty.sy = 24;
status_init(c);
c->message_string = NULL;
TAILQ_INIT(&c->message_log);
c->prompt_string = NULL;
c->prompt_buffer = NULL;
c->prompt_index = 0;
RB_INIT(&c->files);
c->flags |= CLIENT_FOCUSED;
@ -270,7 +259,6 @@ server_client_open(struct client *c, char **cause)
void
server_client_lost(struct client *c)
{
struct message_entry *msg, *msg1;
struct client_file *cf;
c->flags |= CLIENT_DEAD;
@ -311,11 +299,6 @@ server_client_lost(struct client *c)
free(c->message_string);
if (event_initialized(&c->message_timer))
evtimer_del(&c->message_timer);
TAILQ_FOREACH_SAFE(msg, &c->message_log, entry, msg1) {
free(msg->msg);
TAILQ_REMOVE(&c->message_log, msg, entry);
free(msg);
}
free(c->prompt_saved);
free(c->prompt_string);
@ -1126,6 +1109,7 @@ server_client_key_callback(struct cmdq_item *item, void *data)
c->tty.mouse_drag_update(c, m);
goto out;
}
event->key = key;
}
/* Find affected pane. */
@ -2206,37 +2190,6 @@ server_client_dispatch_read_done(struct client *c, struct imsg *imsg)
file_fire_done(cf);
}
/* Add to client message log. */
void
server_client_add_message(struct client *c, const char *fmt, ...)
{
struct message_entry *msg, *msg1;
char *s;
va_list ap;
u_int limit;
va_start(ap, fmt);
xvasprintf(&s, fmt, ap);
va_end(ap);
log_debug("message %s (client %p)", s, c);
msg = xcalloc(1, sizeof *msg);
msg->msg_time = time(NULL);
msg->msg_num = c->message_next++;
msg->msg = s;
TAILQ_INSERT_TAIL(&c->message_log, msg, entry);
limit = options_get_number(global_options, "message-limit");
TAILQ_FOREACH_SAFE(msg, &c->message_log, entry, msg1) {
if (msg->msg_num + limit >= c->message_next)
break;
free(msg->msg);
TAILQ_REMOVE(&c->message_log, msg, entry);
free(msg);
}
}
/* Get client working directory. */
const char *
server_client_get_cwd(struct client *c, struct session *s)

View File

@ -50,6 +50,9 @@ static struct event server_ev_accept;
struct cmd_find_state marked_pane;
static u_int message_next;
struct message_list message_log;
static int server_loop(void);
static void server_send_exit(void);
static void server_accept(int, short, void *);
@ -194,6 +197,7 @@ server_start(struct tmuxproc *client, int flags, struct event_base *base,
TAILQ_INIT(&clients);
RB_INIT(&sessions);
key_bindings_init();
TAILQ_INIT(&message_log);
gettimeofday(&start_time, NULL);
@ -482,3 +486,34 @@ server_child_stopped(pid_t pid, int status)
}
job_check_died(pid, status);
}
/* Add to message log. */
void
server_add_message(const char *fmt, ...)
{
struct message_entry *msg, *msg1;
char *s;
va_list ap;
u_int limit;
va_start(ap, fmt);
xvasprintf(&s, fmt, ap);
va_end(ap);
log_debug("message: %s", s);
msg = xcalloc(1, sizeof *msg);
gettimeofday(&msg->msg_time, NULL);
msg->msg_num = message_next++;
msg->msg = s;
TAILQ_INSERT_TAIL(&message_log, msg, entry);
limit = options_get_number(global_options, "message-limit");
TAILQ_FOREACH_SAFE(msg, &message_log, entry, msg1) {
if (msg->msg_num + limit >= message_next)
break;
free(msg->msg);
TAILQ_REMOVE(&message_log, msg, entry);
free(msg);
}
}

View File

@ -436,7 +436,7 @@ status_message_set(struct client *c, const char *fmt, ...)
xvasprintf(&c->message_string, fmt, ap);
va_end(ap);
server_client_add_message(c, "%s", c->message_string);
server_add_message("%s message: %s", c->name, c->message_string);
delay = options_get_number(c->session->options, "display-time");
if (delay > 0) {

9
tmux.1
View File

@ -1311,15 +1311,10 @@ Rename the session to
.Op Fl t Ar target-client
.Xc
.D1 (alias: Ic showmsgs )
Show client messages or server information.
Any messages displayed on the status line are saved in a per-client message
log, up to a maximum of the limit set by the
Show server messages or information.
Messages are stored, up to a maximum of the limit set by the
.Ar message-limit
server option.
With
.Fl t ,
display the log for
.Ar target-client .
.Fl J
and
.Fl T

18
tmux.h
View File

@ -1343,11 +1343,13 @@ struct tty_ctx {
/* Saved message entry. */
struct message_entry {
char *msg;
u_int msg_num;
time_t msg_time;
TAILQ_ENTRY(message_entry) entry;
char *msg;
u_int msg_num;
struct timeval msg_time;
TAILQ_ENTRY(message_entry) entry;
};
TAILQ_HEAD(message_list, message_entry);
/* Parsed arguments structures. */
struct args_entry;
@ -1605,8 +1607,6 @@ struct client {
char *message_string;
struct event message_timer;
u_int message_next;
TAILQ_HEAD(, message_entry) message_log;
char *prompt_string;
struct utf8_data *prompt_buffer;
@ -1848,6 +1848,8 @@ void format_free(struct format_tree *);
void format_merge(struct format_tree *, struct format_tree *);
void printflike(3, 4) format_add(struct format_tree *, const char *,
const char *, ...);
void format_add_tv(struct format_tree *, const char *,
struct timeval *);
void format_each(struct format_tree *, void (*)(const char *,
const char *, void *), void *);
char *format_expand_time(struct format_tree *, const char *);
@ -2271,6 +2273,7 @@ void file_push(struct client_file *);
extern struct tmuxproc *server_proc;
extern struct clients clients;
extern struct cmd_find_state marked_pane;
extern struct message_list message_log;
void server_set_marked(struct session *, struct winlink *,
struct window_pane *);
void server_clear_marked(void);
@ -2280,6 +2283,7 @@ int server_check_marked(void);
int server_start(struct tmuxproc *, int, struct event_base *, int, char *);
void server_update_socket(void);
void server_add_accept(int);
void printflike(1, 2) server_add_message(const char *, ...);
/* server-client.c */
u_int server_client_how_many(void);
@ -2301,8 +2305,6 @@ void server_client_exec(struct client *, const char *);
void server_client_loop(void);
void server_client_push_stdout(struct client *);
void server_client_push_stderr(struct client *);
void printflike(2, 3) server_client_add_message(struct client *, const char *,
...);
const char *server_client_get_cwd(struct client *, struct session *);
void server_client_set_flags(struct client *, const char *);
const char *server_client_get_flags(struct client *);