From 068b8b03ad06abf1082e288ed7496970cccd7678 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 15 Jun 2016 08:54:11 +0000 Subject: [PATCH 1/2] Add -F to list-commands. --- cmd-list-keys.c | 53 +++++++++++++++++++++++++++++++++++-------------- tmux.1 | 7 ++++++- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/cmd-list-keys.c b/cmd-list-keys.c index c3ace8de..06f0e8c5 100644 --- a/cmd-list-keys.c +++ b/cmd-list-keys.c @@ -27,10 +27,10 @@ * List key bindings. */ -enum cmd_retval cmd_list_keys_exec(struct cmd *, struct cmd_q *); +static enum cmd_retval cmd_list_keys_exec(struct cmd *, struct cmd_q *); -enum cmd_retval cmd_list_keys_table(struct cmd *, struct cmd_q *); -enum cmd_retval cmd_list_keys_commands(struct cmd_q *); +static enum cmd_retval cmd_list_keys_table(struct cmd *, struct cmd_q *); +static enum cmd_retval cmd_list_keys_commands(struct cmd *, struct cmd_q *); const struct cmd_entry cmd_list_keys_entry = { .name = "list-keys", @@ -47,14 +47,14 @@ const struct cmd_entry cmd_list_commands_entry = { .name = "list-commands", .alias = "lscm", - .args = { "", 0, 0 }, - .usage = "", + .args = { "F:", 0, 0 }, + .usage = "[-F format]", .flags = CMD_STARTSERVER, .exec = cmd_list_keys_exec }; -enum cmd_retval +static enum cmd_retval cmd_list_keys_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; @@ -65,7 +65,7 @@ cmd_list_keys_exec(struct cmd *self, struct cmd_q *cmdq) int repeat, width, tablewidth, keywidth; if (self->entry == &cmd_list_commands_entry) - return (cmd_list_keys_commands(cmdq)); + return (cmd_list_keys_commands(self, cmdq)); if (args_has(args, 't')) return (cmd_list_keys_table(self, cmdq)); @@ -131,7 +131,7 @@ cmd_list_keys_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_NORMAL); } -enum cmd_retval +static enum cmd_retval cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; @@ -180,21 +180,44 @@ cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_NORMAL); } -enum cmd_retval -cmd_list_keys_commands(struct cmd_q *cmdq) +static enum cmd_retval +cmd_list_keys_commands(struct cmd *self, struct cmd_q *cmdq) { + struct args *args = self->args; const struct cmd_entry **entryp; const struct cmd_entry *entry; + struct format_tree *ft; + const char *template; + char *line; + + if ((template = args_get(args, 'F')) == NULL) { + template = "#{command_list_name}" + "#{?command_list_alias, (#{command_list_alias}),} " + "#{command_list_usage}"; + } + + ft = format_create(cmdq, 0); + format_defaults(ft, NULL, NULL, NULL, NULL); for (entryp = cmd_table; *entryp != NULL; entryp++) { entry = *entryp; - if (entry->alias == NULL) { - cmdq_print(cmdq, "%s %s", entry->name, entry->usage); - continue; + + format_add(ft, "command_list_name", "%s", entry->name); + if (entry->alias != NULL) { + format_add(ft, "command_list_alias", "%s", + entry->alias); } - cmdq_print(cmdq, "%s (%s) %s", entry->name, entry->alias, - entry->usage); + if (entry->alias != NULL) { + format_add(ft, "command_list_usage", "%s", + entry->usage); + } + + line = format_expand(ft, template); + if (*line != '\0') + cmdq_print(cmdq, "%s", line); + free(line); } + format_free(ft); return (CMD_RETURN_NORMAL); } diff --git a/tmux.1 b/tmux.1 index 513eb61c..06c11bdd 100644 --- a/tmux.1 +++ b/tmux.1 @@ -773,7 +773,9 @@ section. If .Ar target-session is specified, list only clients connected to that session. -.It Ic list-commands +.It Xo Ic list-commands +.Op Fl F Ar format +.Xc .D1 (alias: Ic lscm ) List the syntax of all commands supported by .Nm . @@ -3492,6 +3494,9 @@ The following variables are available, where appropriate: .It Li "client_width" Ta "" Ta "Width of client" .It Li "command_hooked" Ta "" Ta "Name of command hooked, if any" .It Li "command_name" Ta "" Ta "Name of command in use, if any" +.It Li "command_list_name" Ta "" Ta "Command name if listing commands" +.It Li "command_list_alias" Ta "" Ta "Command alias if listing commands" +.It Li "command_list_usage" Ta "" Ta "Command usage if listing commands" .It Li "cursor_flag" Ta "" Ta "Pane cursor flag" .It Li "cursor_x" Ta "" Ta "Cursor X position in pane" .It Li "cursor_y" Ta "" Ta "Cursor Y position in pane" From bee3e3e28d04a237b1013b1dd3d36cddcd326891 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 15 Jun 2016 09:13:46 +0000 Subject: [PATCH 2/2] Copy mode needs to keep the original grid intact so it can copy from it if needed, so it disables reading from the pane. This can be problem with some programs. So make tmux automatically exit all modes after 180 seconds of inactivity and if there is pending output. --- tmux.h | 3 +++ window.c | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/tmux.h b/tmux.h index b8d1a1f5..b84530f2 100644 --- a/tmux.h +++ b/tmux.h @@ -823,6 +823,7 @@ struct window_mode { void (*key)(struct window_pane *, struct client *, struct session *, key_code, struct mouse_event *); }; +#define WINDOW_MODE_TIMEOUT 180 /* Structures for choose mode. */ struct window_choose_data { @@ -905,6 +906,8 @@ struct window_pane { const struct window_mode *mode; void *modedata; + struct event modetimer; + time_t modelast; TAILQ_ENTRY(window_pane) entry; RB_ENTRY(window_pane) tree_entry; diff --git a/window.c b/window.c index a252629d..bba8e3b1 100644 --- a/window.c +++ b/window.c @@ -17,6 +17,7 @@ */ #include +#include #include #include @@ -1046,15 +1047,38 @@ window_pane_alternate_off(struct window_pane *wp, struct grid_cell *gc, wp->flags |= PANE_REDRAW; } +static void +window_pane_mode_timer(__unused int fd, __unused short events, void *arg) +{ + struct window_pane *wp = arg; + struct timeval tv = { .tv_sec = 10 }; + int n = 0; + + evtimer_del(&wp->modetimer); + evtimer_add(&wp->modetimer, &tv); + + log_debug("%%%u in mode: last=%ld", wp->id, (long)wp->modelast); + + if (wp->modelast < time(NULL) - WINDOW_MODE_TIMEOUT) { + if (ioctl(wp->fd, FIONREAD, &n) == -1 || n > 0) + window_pane_reset_mode(wp); + } +} + int window_pane_set_mode(struct window_pane *wp, const struct window_mode *mode) { struct screen *s; + struct timeval tv = { .tv_sec = 10 }; if (wp->mode != NULL) return (1); wp->mode = mode; + wp->modelast = time(NULL); + evtimer_set(&wp->modetimer, window_pane_mode_timer, wp); + evtimer_add(&wp->modetimer, &tv); + if ((s = wp->mode->init(wp)) != NULL) wp->screen = s; wp->flags |= (PANE_REDRAW|PANE_CHANGED); @@ -1069,6 +1093,8 @@ window_pane_reset_mode(struct window_pane *wp) if (wp->mode == NULL) return; + evtimer_del(&wp->modetimer); + wp->mode->free(wp); wp->mode = NULL; @@ -1088,6 +1114,7 @@ window_pane_key(struct window_pane *wp, struct client *c, struct session *s, return; if (wp->mode != NULL) { + wp->modelast = time(NULL); if (wp->mode->key != NULL) wp->mode->key(wp, c, s, key, m); return;