summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2020-01-27 08:53:14 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2020-01-27 08:53:14 +0000
commitc43527a32cf0e7b4b63c25d17e0dee0aa2d554ac (patch)
treea63a8060fb5a2c472431c732d22006a0a38c0c80 /usr.bin
parent1cc38d9abc126197bae007533ca822b78de26390 (diff)
Add support for adding a note to a key binding (with bind-key -N) and
use this to add descriptions to the default key bindings. A new -N flag to list-keys shows key bindings with notes rather than the default bind-key command used to create them. Change the default ? binding to use this to show a readable summary of keys. Also extend command-prompt to return the name of the key pressed and add a default binding (/) to show the note for the next key pressed Suggested by Alex Tremblay in GitHub issue 2000.
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/tmux/cmd-bind-key.c14
-rw-r--r--usr.bin/tmux/cmd-command-prompt.c8
-rw-r--r--usr.bin/tmux/cmd-list-keys.c152
-rw-r--r--usr.bin/tmux/key-bindings.c170
-rw-r--r--usr.bin/tmux/status.c10
-rw-r--r--usr.bin/tmux/tmux.152
-rw-r--r--usr.bin/tmux/tmux.h7
7 files changed, 300 insertions, 113 deletions
diff --git a/usr.bin/tmux/cmd-bind-key.c b/usr.bin/tmux/cmd-bind-key.c
index e5c6ca2878b..136d260c5e4 100644
--- a/usr.bin/tmux/cmd-bind-key.c
+++ b/usr.bin/tmux/cmd-bind-key.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-bind-key.c,v 1.34 2019/05/27 12:16:27 nicm Exp $ */
+/* $OpenBSD: cmd-bind-key.c,v 1.35 2020/01/27 08:53:13 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -33,8 +33,8 @@ const struct cmd_entry cmd_bind_key_entry = {
.name = "bind-key",
.alias = "bind",
- .args = { "cnrT:", 2, -1 },
- .usage = "[-cnr] [-T key-table] key "
+ .args = { "cnrN:T:", 2, -1 },
+ .usage = "[-cnr] [-T key-table] [-N note] key "
"command [arguments]",
.flags = CMD_AFTERHOOK,
@@ -46,10 +46,10 @@ cmd_bind_key_exec(struct cmd *self, struct cmdq_item *item)
{
struct args *args = self->args;
key_code key;
- const char *tablename;
+ const char *tablename, *note;
struct cmd_parse_result *pr;
char **argv = args->argv;
- int argc = args->argc;
+ int argc = args->argc, repeat;
key = key_string_lookup_string(argv[0]);
if (key == KEYC_NONE || key == KEYC_UNKNOWN) {
@@ -63,6 +63,7 @@ cmd_bind_key_exec(struct cmd *self, struct cmdq_item *item)
tablename = "root";
else
tablename = "prefix";
+ repeat = args_has(args, 'r');
if (argc == 2)
pr = cmd_parse_from_string(argv[1], NULL);
@@ -79,6 +80,7 @@ cmd_bind_key_exec(struct cmd *self, struct cmdq_item *item)
case CMD_PARSE_SUCCESS:
break;
}
- key_bindings_add(tablename, key, args_has(args, 'r'), pr->cmdlist);
+ note = args_get(args, 'N');
+ key_bindings_add(tablename, key, note, repeat, pr->cmdlist);
return (CMD_RETURN_NORMAL);
}
diff --git a/usr.bin/tmux/cmd-command-prompt.c b/usr.bin/tmux/cmd-command-prompt.c
index f297195b509..92486be0e17 100644
--- a/usr.bin/tmux/cmd-command-prompt.c
+++ b/usr.bin/tmux/cmd-command-prompt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-command-prompt.c,v 1.46 2019/05/23 11:13:30 nicm Exp $ */
+/* $OpenBSD: cmd-command-prompt.c,v 1.47 2020/01/27 08:53:13 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -40,8 +40,8 @@ const struct cmd_entry cmd_command_prompt_entry = {
.name = "command-prompt",
.alias = NULL,
- .args = { "1iI:Np:t:", 0, 1 },
- .usage = "[-1Ni] [-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " "
+ .args = { "1kiI:Np:t:", 0, 1 },
+ .usage = "[-1kiN] [-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " "
"[template]",
.flags = 0,
@@ -122,6 +122,8 @@ cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item)
cdata->flags |= PROMPT_NUMERIC;
else if (args_has(args, 'i'))
cdata->flags |= PROMPT_INCREMENTAL;
+ else if (args_has(args, 'k'))
+ cdata->flags |= PROMPT_KEY;
status_prompt_set(c, prompt, input, cmd_command_prompt_callback,
cmd_command_prompt_free, cdata, cdata->flags);
free(prompt);
diff --git a/usr.bin/tmux/cmd-list-keys.c b/usr.bin/tmux/cmd-list-keys.c
index 53e53a4eba6..f3a70c71776 100644
--- a/usr.bin/tmux/cmd-list-keys.c
+++ b/usr.bin/tmux/cmd-list-keys.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-list-keys.c,v 1.49 2019/10/14 09:16:48 nicm Exp $ */
+/* $OpenBSD: cmd-list-keys.c,v 1.50 2020/01/27 08:53:13 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -36,8 +36,8 @@ const struct cmd_entry cmd_list_keys_entry = {
.name = "list-keys",
.alias = "lsk",
- .args = { "T:", 0, 0 },
- .usage = "[-T key-table]",
+ .args = { "1NP:T:", 0, 1 },
+ .usage = "[-1N] [-P prefix-string] [-T key-table] [key]",
.flags = CMD_STARTSERVER|CMD_AFTERHOOK,
.exec = cmd_list_keys_exec
@@ -54,6 +54,88 @@ const struct cmd_entry cmd_list_commands_entry = {
.exec = cmd_list_keys_exec
};
+static u_int
+cmd_list_keys_get_width(const char *tablename, key_code only)
+{
+ struct key_table *table;
+ struct key_binding *bd;
+ u_int width, keywidth = 0;
+
+ table = key_bindings_get_table(tablename, 0);
+ if (table == NULL)
+ return (0);
+ bd = key_bindings_first(table);
+ while (bd != NULL) {
+ if ((only != KEYC_UNKNOWN && bd->key != only) ||
+ KEYC_IS_MOUSE(bd->key) ||
+ bd->note == NULL) {
+ bd = key_bindings_next(table, bd);
+ continue;
+ }
+ width = utf8_cstrwidth(key_string_lookup_key(bd->key));
+ if (width > keywidth)
+ keywidth = width;
+
+ bd = key_bindings_next(table, bd);
+ }
+ return (keywidth);
+}
+
+static int
+cmd_list_keys_print_notes(struct cmdq_item *item, struct args *args,
+ const char *tablename, u_int keywidth, key_code only, const char *prefix)
+{
+ struct client *c = cmd_find_client(item, NULL, 1);
+ struct key_table *table;
+ struct key_binding *bd;
+ const char *key;
+ char *tmp;
+ int found = 0;
+
+ table = key_bindings_get_table(tablename, 0);
+ if (table == NULL)
+ return (0);
+ bd = key_bindings_first(table);
+ while (bd != NULL) {
+ if ((only != KEYC_UNKNOWN && bd->key != only) ||
+ KEYC_IS_MOUSE(bd->key) ||
+ bd->note == NULL) {
+ bd = key_bindings_next(table, bd);
+ continue;
+ }
+ found = 1;
+ key = key_string_lookup_key(bd->key);
+
+ tmp = utf8_padcstr(key, keywidth + 1);
+ if (args_has(args, '1') && c != NULL)
+ status_message_set(c, "%s%s%s", prefix, tmp, bd->note);
+ else
+ cmdq_print(item, "%s%s%s", prefix, tmp, bd->note);
+ free(tmp);
+
+ if (args_has(args, '1'))
+ break;
+ bd = key_bindings_next(table, bd);
+ }
+ return (found);
+}
+
+static char *
+cmd_list_keys_get_prefix(struct args *args, key_code *prefix)
+{
+ char *s;
+
+ *prefix = options_get_number(global_s_options, "prefix");
+ if (!args_has(args, 'P')) {
+ if (*prefix != KEYC_NONE)
+ xasprintf(&s, "%s ", key_string_lookup_key(*prefix));
+ else
+ s = xstrdup("");
+ } else
+ s = xstrdup(args_get(args, 'P'));
+ return (s);
+}
+
static enum cmd_retval
cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
{
@@ -61,19 +143,63 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
struct key_table *table;
struct key_binding *bd;
const char *tablename, *r;
- char *key, *cp, *tmp;
- int repeat, width, tablewidth, keywidth;
+ char *key, *cp, *tmp, *start, *empty;
+ key_code prefix, only = KEYC_UNKNOWN;
+ int repeat, width, tablewidth, keywidth, found = 0;
size_t tmpsize, tmpused, cplen;
if (self->entry == &cmd_list_commands_entry)
return (cmd_list_keys_commands(self, item));
+ if (args->argc != 0) {
+ only = key_string_lookup_string(args->argv[0]);
+ if (only == KEYC_UNKNOWN) {
+ cmdq_error(item, "invalid key: %s", args->argv[0]);
+ return (CMD_RETURN_ERROR);
+ }
+ }
+
tablename = args_get(args, 'T');
if (tablename != NULL && key_bindings_get_table(tablename, 0) == NULL) {
cmdq_error(item, "table %s doesn't exist", tablename);
return (CMD_RETURN_ERROR);
}
+ if (args_has(args, 'N')) {
+ if (tablename == NULL) {
+ start = cmd_list_keys_get_prefix(args, &prefix);
+ keywidth = cmd_list_keys_get_width("root", only);
+ if (prefix != KEYC_NONE) {
+ width = cmd_list_keys_get_width("prefix", only);
+ if (width == 0)
+ prefix = KEYC_NONE;
+ else if (width > keywidth)
+ keywidth = width;
+ }
+ empty = utf8_padcstr("", utf8_cstrwidth(start));
+
+ found = cmd_list_keys_print_notes(item, args, "root",
+ keywidth, only, empty);
+ if (prefix != KEYC_NONE) {
+ if (cmd_list_keys_print_notes(item, args,
+ "prefix", keywidth, only, start))
+ found = 1;
+ }
+ free(empty);
+ } else {
+ if (args_has(args, 'P'))
+ start = xstrdup(args_get(args, 'P'));
+ else
+ start = xstrdup("");
+ keywidth = cmd_list_keys_get_width(tablename, only);
+ found = cmd_list_keys_print_notes(item, args, tablename,
+ keywidth, only, start);
+
+ }
+ free(start);
+ goto out;
+ }
+
repeat = 0;
tablewidth = keywidth = 0;
table = key_bindings_first_table ();
@@ -84,6 +210,10 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
}
bd = key_bindings_first(table);
while (bd != NULL) {
+ if (only != KEYC_UNKNOWN && bd->key != only) {
+ bd = key_bindings_next(table, bd);
+ continue;
+ }
key = args_escape(key_string_lookup_key(bd->key));
if (bd->flags & KEY_BINDING_REPEAT)
@@ -113,6 +243,11 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
}
bd = key_bindings_first(table);
while (bd != NULL) {
+ if (only != KEYC_UNKNOWN && bd->key != only) {
+ bd = key_bindings_next(table, bd);
+ continue;
+ }
+ found = 1;
key = args_escape(key_string_lookup_key(bd->key));
if (!repeat)
@@ -162,13 +297,18 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
free(tmp);
+out:
+ if (only != KEYC_UNKNOWN && !found) {
+ cmdq_error(item, "unknown key: %s", args->argv[0]);
+ return (CMD_RETURN_ERROR);
+ }
return (CMD_RETURN_NORMAL);
}
static enum cmd_retval
cmd_list_keys_commands(struct cmd *self, struct cmdq_item *item)
{
- struct args *args = self->args;
+ struct args *args = self->args;
const struct cmd_entry **entryp;
const struct cmd_entry *entry;
struct format_tree *ft;
diff --git a/usr.bin/tmux/key-bindings.c b/usr.bin/tmux/key-bindings.c
index 4514e971f95..4ff38ccf0a9 100644
--- a/usr.bin/tmux/key-bindings.c
+++ b/usr.bin/tmux/key-bindings.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: key-bindings.c,v 1.106 2020/01/05 20:39:25 nicm Exp $ */
+/* $OpenBSD: key-bindings.c,v 1.107 2020/01/27 08:53:13 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -90,6 +90,7 @@ key_bindings_free(struct key_table *table, struct key_binding *bd)
{
RB_REMOVE(key_bindings, &table->key_bindings, bd);
cmd_list_free(bd->cmdlist);
+ free((void *)bd->note);
free(bd);
}
@@ -163,7 +164,7 @@ key_bindings_next(__unused struct key_table *table, struct key_binding *bd)
}
void
-key_bindings_add(const char *name, key_code key, int repeat,
+key_bindings_add(const char *name, key_code key, const char *note, int repeat,
struct cmd_list *cmdlist)
{
struct key_table *table;
@@ -177,6 +178,8 @@ key_bindings_add(const char *name, key_code key, int repeat,
bd = xcalloc(1, sizeof *bd);
bd->key = key;
+ if (note != NULL)
+ bd->note = xstrdup(note);
RB_INSERT(key_bindings, &table->key_bindings, bd);
if (repeat)
@@ -226,87 +229,88 @@ void
key_bindings_init(void)
{
static const char *defaults[] = {
- "bind C-b send-prefix",
- "bind C-o rotate-window",
- "bind C-z suspend-client",
- "bind Space next-layout",
- "bind ! break-pane",
- "bind '\"' split-window",
- "bind '#' list-buffers",
- "bind '$' command-prompt -I'#S' \"rename-session -- '%%'\"",
- "bind % split-window -h",
- "bind & confirm-before -p\"kill-window #W? (y/n)\" kill-window",
- "bind \"'\" command-prompt -pindex \"select-window -t ':%%'\"",
- "bind ( switch-client -p",
- "bind ) switch-client -n",
- "bind , command-prompt -I'#W' \"rename-window -- '%%'\"",
- "bind - delete-buffer",
- "bind . command-prompt \"move-window -t '%%'\"",
- "bind 0 select-window -t:=0",
- "bind 1 select-window -t:=1",
- "bind 2 select-window -t:=2",
- "bind 3 select-window -t:=3",
- "bind 4 select-window -t:=4",
- "bind 5 select-window -t:=5",
- "bind 6 select-window -t:=6",
- "bind 7 select-window -t:=7",
- "bind 8 select-window -t:=8",
- "bind 9 select-window -t:=9",
- "bind : command-prompt",
- "bind \\; last-pane",
- "bind = choose-buffer -Z",
- "bind ? list-keys",
- "bind D choose-client -Z",
- "bind E select-layout -E",
- "bind L switch-client -l",
- "bind M select-pane -M",
- "bind [ copy-mode",
- "bind ] paste-buffer",
- "bind c new-window",
- "bind d detach-client",
- "bind f command-prompt \"find-window -Z -- '%%'\"",
- "bind i display-message",
- "bind l last-window",
- "bind m select-pane -m",
- "bind n next-window",
- "bind o select-pane -t:.+",
- "bind p previous-window",
- "bind q display-panes",
- "bind r refresh-client",
- "bind s choose-tree -Zs",
- "bind t clock-mode",
- "bind w choose-tree -Zw",
- "bind x confirm-before -p\"kill-pane #P? (y/n)\" kill-pane",
- "bind z resize-pane -Z",
- "bind '{' swap-pane -U",
- "bind '}' swap-pane -D",
- "bind '~' show-messages",
- "bind PPage copy-mode -u",
- "bind -r Up select-pane -U",
- "bind -r Down select-pane -D",
- "bind -r Left select-pane -L",
- "bind -r Right select-pane -R",
- "bind M-1 select-layout even-horizontal",
- "bind M-2 select-layout even-vertical",
- "bind M-3 select-layout main-horizontal",
- "bind M-4 select-layout main-vertical",
- "bind M-5 select-layout tiled",
- "bind M-n next-window -a",
- "bind M-o rotate-window -D",
- "bind M-p previous-window -a",
- "bind -r S-Up refresh-client -U 10",
- "bind -r S-Down refresh-client -D 10",
- "bind -r S-Left refresh-client -L 10",
- "bind -r S-Right refresh-client -R 10",
- "bind -r DC refresh-client -c",
- "bind -r M-Up resize-pane -U 5",
- "bind -r M-Down resize-pane -D 5",
- "bind -r M-Left resize-pane -L 5",
- "bind -r M-Right resize-pane -R 5",
- "bind -r C-Up resize-pane -U",
- "bind -r C-Down resize-pane -D",
- "bind -r C-Left resize-pane -L",
- "bind -r C-Right resize-pane -R",
+ "bind -N 'Send the prefix key' C-b send-prefix",
+ "bind -N 'Rotate through the panes' C-o rotate-window",
+ "bind -N 'Suspend the current client' C-z suspend-client",
+ "bind -N 'Select next layout' Space next-layout",
+ "bind -N 'Break pane to a new window' ! break-pane",
+ "bind -N 'Split window vertically' '\"' split-window",
+ "bind -N 'List all paste buffers' '#' list-buffers",
+ "bind -N 'Rename current session' '$' command-prompt -I'#S' \"rename-session -- '%%'\"",
+ "bind -N 'Split window horizontally' % split-window -h",
+ "bind -N 'Kill current window' & confirm-before -p\"kill-window #W? (y/n)\" kill-window",
+ "bind -N 'Prompt for window index to select' \"'\" command-prompt -pindex \"select-window -t ':%%'\"",
+ "bind -N 'Switch to previous client' ( switch-client -p",
+ "bind -N 'Switch to next client' ) switch-client -n",
+ "bind -N 'Rename current window' , command-prompt -I'#W' \"rename-window -- '%%'\"",
+ "bind -N 'Delete the most recent paste buffer' - delete-buffer",
+ "bind -N 'Move the current window' . command-prompt \"move-window -t '%%'\"",
+ "bind -N 'Describe key binding' '/' command-prompt -kpkey 'list-keys -1N \"%%%\"'",
+ "bind -N 'Select window 0' 0 select-window -t:=0",
+ "bind -N 'Select window 1' 1 select-window -t:=1",
+ "bind -N 'Select window 2' 2 select-window -t:=2",
+ "bind -N 'Select window 3' 3 select-window -t:=3",
+ "bind -N 'Select window 4' 4 select-window -t:=4",
+ "bind -N 'Select window 5' 5 select-window -t:=5",
+ "bind -N 'Select window 6' 6 select-window -t:=6",
+ "bind -N 'Select window 7' 7 select-window -t:=7",
+ "bind -N 'Select window 8' 8 select-window -t:=8",
+ "bind -N 'Select window 9' 9 select-window -t:=9",
+ "bind -N 'Prompt for a command' : command-prompt",
+ "bind -N 'Move to the previously active pane' \\; last-pane",
+ "bind -N 'Choose a paste buffer from a list' = choose-buffer -Z",
+ "bind -N 'List key bindings' ? list-keys -N",
+ "bind -N 'Choose a client from a list' D choose-client -Z",
+ "bind -N 'Spread panes out evenly' E select-layout -E",
+ "bind -N 'Switch to the last client' L switch-client -l",
+ "bind -N 'Clear the marked pane' M select-pane -M",
+ "bind -N 'Enter copy mode' [ copy-mode",
+ "bind -N 'Paste the most recent paste buffer' ] paste-buffer",
+ "bind -N 'Create a new window' c new-window",
+ "bind -N 'Detach the current client' d detach-client",
+ "bind -N 'Search for a pane' f command-prompt \"find-window -Z -- '%%'\"",
+ "bind -N 'Display window information' i display-message",
+ "bind -N 'Select the previously current window' l last-window",
+ "bind -N 'Toggle the marked pane' m select-pane -m",
+ "bind -N 'Select the next window' n next-window",
+ "bind -N 'Select the next pane' o select-pane -t:.+",
+ "bind -N 'Select the previous pane' p previous-window",
+ "bind -N 'Display pane numbers' q display-panes",
+ "bind -N 'Redraw the current client' r refresh-client",
+ "bind -N 'Choose a session from a list' s choose-tree -Zs",
+ "bind -N 'Show a clock' t clock-mode",
+ "bind -N 'Choose a window from a list' w choose-tree -Zw",
+ "bind -N 'Kill the active pane' x confirm-before -p\"kill-pane #P? (y/n)\" kill-pane",
+ "bind -N 'Zoom the active pane' z resize-pane -Z",
+ "bind -N 'Swap the active pane with the pane above' '{' swap-pane -U",
+ "bind -N 'Swap the active pane with the pane below' '}' swap-pane -D",
+ "bind -N 'Show messages' '~' show-messages",
+ "bind -N 'Enter copy mode and scroll up' PPage copy-mode -u",
+ "bind -N 'Select the pane above the active pane' -r Up select-pane -U",
+ "bind -N 'Select the pane below the active pane' -r Down select-pane -D",
+ "bind -N 'Select the pane to the left of the active pane' -r Left select-pane -L",
+ "bind -N 'Select the pane to the right of the active pane' -r Right select-pane -R",
+ "bind -N 'Set the even-horizontal layout' M-1 select-layout even-horizontal",
+ "bind -N 'Set the even-vertical layout' M-2 select-layout even-vertical",
+ "bind -N 'Set the main-horizontal layout' M-3 select-layout main-horizontal",
+ "bind -N 'Set the main-vertical layout' M-4 select-layout main-vertical",
+ "bind -N 'Select the tiled layout' M-5 select-layout tiled",
+ "bind -N 'Select the next window with an alert' M-n next-window -a",
+ "bind -N 'Rotate through the panes in reverse' M-o rotate-window -D",
+ "bind -N 'Select the previous window with an alert' M-p previous-window -a",
+ "bind -N 'Move the visible part of the window up' -r S-Up refresh-client -U 10",
+ "bind -N 'Move the visible part of the window down' -r S-Down refresh-client -D 10",
+ "bind -N 'Move the visible part of the window left' -r S-Left refresh-client -L 10",
+ "bind -N 'Move the visible part of the window right' -r S-Right refresh-client -R 10",
+ "bind -N 'Reset so the visible part of the window follows the cursor' -r DC refresh-client -c",
+ "bind -N 'Resize the pane up by 5' -r M-Up resize-pane -U 5",
+ "bind -N 'Resize the pane down by 5' -r M-Down resize-pane -D 5",
+ "bind -N 'Resize the pane left by 5' -r M-Left resize-pane -L 5",
+ "bind -N 'Resize the pane right by 5' -r M-Right resize-pane -R 5",
+ "bind -N 'Resize the pane up' -r C-Up resize-pane -U",
+ "bind -N 'Resize the pane down' -r C-Down resize-pane -D",
+ "bind -N 'Resize the pane left' -r C-Left resize-pane -L",
+ "bind -N 'Resize the pane right' -r C-Right resize-pane -R",
"bind -n MouseDown1Pane select-pane -t=\\; send-keys -M",
"bind -n MouseDrag1Border resize-pane -M",
diff --git a/usr.bin/tmux/status.c b/usr.bin/tmux/status.c
index 151f7310159..5e11958f7b6 100644
--- a/usr.bin/tmux/status.c
+++ b/usr.bin/tmux/status.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: status.c,v 1.200 2019/05/28 18:53:36 nicm Exp $ */
+/* $OpenBSD: status.c,v 1.201 2020/01/27 08:53:13 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -915,11 +915,17 @@ status_prompt_key(struct client *c, key_code key)
{
struct options *oo = c->session->options;
char *s, *cp, word[64], prefix = '=';
- const char *histstr, *ws = NULL;
+ const char *histstr, *ws = NULL, *keystring;
size_t size, n, off, idx, used;
struct utf8_data tmp, *first, *last, *ud;
int keys;
+ if (c->prompt_flags & PROMPT_KEY) {
+ keystring = key_string_lookup_key(key);
+ c->prompt_inputcb(c, c->prompt_data, keystring, 1);
+ status_prompt_clear(c);
+ return (0);
+ }
size = utf8_strlen(c->prompt_buffer);
if (c->prompt_flags & PROMPT_NUMERIC) {
diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1
index 1114dfb0348..e3c80d7acd7 100644
--- a/usr.bin/tmux/tmux.1
+++ b/usr.bin/tmux/tmux.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tmux.1,v 1.705 2020/01/25 16:40:32 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.706 2020/01/27 08:53:13 nicm Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
.\"
@@ -14,7 +14,7 @@
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: January 25 2020 $
+.Dd $Mdocdate: January 27 2020 $
.Dt TMUX 1
.Os
.Sh NAME
@@ -551,7 +551,7 @@ Braces may be enclosed inside braces, for example:
.Bd -literal -offset indent
bind x if-shell "true" {
if-shell "true" {
- display "true!"
+ display "true!"
}
}
.Ed
@@ -1335,7 +1335,8 @@ is used,
option will not be applied.
.Pp
.Fl T
-sets the client's key table; the next key from the client will be interpreted from
+sets the client's key table; the next key from the client will be interpreted
+from
.Ar key-table .
This may be used to configure multiple prefix keys, or to bind commands to
sequences of keys.
@@ -2613,6 +2614,7 @@ Commands related to key bindings are as follows:
.Bl -tag -width Ds
.It Xo Ic bind-key
.Op Fl nr
+.Op Fl N Ar note
.Op Fl T Ar key-table
.Ar key Ar command Op Ar arguments
.Xc
@@ -2660,22 +2662,46 @@ The
flag indicates this key may repeat, see the
.Ic repeat-time
option.
+.Fl N
+attaches a note to the key (shown with
+.Ic list-keys
+.Fl N ) .
.Pp
To view the default bindings and possible commands, see the
.Ic list-keys
command.
.It Xo Ic list-keys
-.Op Fl T Ar key-table
+.Op Fl 1N
+.Op Fl P Ar prefix-string Fl T Ar key-table
+.Op key
.Xc
.D1 (alias: Ic lsk )
List all key bindings.
-Without
-.Fl T
-all key tables are printed.
+By default this shows all keys or any bindings for
+.Ar key
+in the syntax of the
+.Ic bind-key
+command.
+.Fl N
+instead show keys and attached notes, i
+.Ar key-table
+if given or in the
+.Em root
+and
+.Em prefix
+key tables by default.
+.Fl P
+specifies a prefix to print before each key.
With
+.Fl 1
+only the first matching key and note is shown.
+.Pp
+Without
+.Fl N ,
.Fl T
-only
-.Ar key-table .
+prints only keys in
+.Ar key-table ,
+otherwise all key tables are printed.
.It Xo Ic send-keys
.Op Fl FHlMRX
.Op Fl N Ar repeat-count
@@ -4693,7 +4719,7 @@ session option.
Commands related to the status line are as follows:
.Bl -tag -width Ds
.It Xo Ic command-prompt
-.Op Fl 1Ni
+.Op Fl 1ikN
.Op Fl I Ar inputs
.Op Fl p Ar prompts
.Op Fl t Ar target-client
@@ -4743,6 +4769,10 @@ but any quotation marks are escaped.
.Fl 1
makes the prompt only accept one key press, in this case the resulting input
is a single character.
+.Fl k
+is like
+.Fl 1
+but the key press is translated to a key name.
.Fl N
makes the prompt only accept numeric key presses.
.Fl i
diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h
index 578e5d748c5..d86ccad0feb 100644
--- a/usr.bin/tmux/tmux.h
+++ b/usr.bin/tmux/tmux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.948 2020/01/13 11:59:21 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.949 2020/01/27 08:53:13 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1609,6 +1609,7 @@ struct client {
#define PROMPT_NUMERIC 0x2
#define PROMPT_INCREMENTAL 0x4
#define PROMPT_NOFORMAT 0x8
+#define PROMPT_KEY 0x10
int prompt_flags;
struct session *session;
@@ -1636,6 +1637,7 @@ TAILQ_HEAD(clients, client);
struct key_binding {
key_code key;
struct cmd_list *cmdlist;
+ const char *note;
int flags;
#define KEY_BINDING_REPEAT 0x1
@@ -2147,7 +2149,8 @@ void key_bindings_unref_table(struct key_table *);
struct key_binding *key_bindings_get(struct key_table *, key_code);
struct key_binding *key_bindings_first(struct key_table *);
struct key_binding *key_bindings_next(struct key_table *, struct key_binding *);
-void key_bindings_add(const char *, key_code, int, struct cmd_list *);
+void key_bindings_add(const char *, key_code, const char *, int,
+ struct cmd_list *);
void key_bindings_remove(const char *, key_code);
void key_bindings_remove_table(const char *);
void key_bindings_init(void);