From 4c12ac9fb80f8f8d2096ba2463b448e9865b70cd Mon Sep 17 00:00:00 2001 From: nicm <nicm> Date: Mon, 27 Jan 2025 09:16:05 +0000 Subject: [PATCH] Make list-commands command show only one command if an argument is given, from Ilya Grigoriev in GitHub issue 4352. --- cmd-list-keys.c | 68 +++++++++++++++++++++++++++++-------------------- cmd.c | 2 +- tmux.h | 1 + 3 files changed, 43 insertions(+), 28 deletions(-) diff --git a/cmd-list-keys.c b/cmd-list-keys.c index 395b147c..b5050f09 100644 --- a/cmd-list-keys.c +++ b/cmd-list-keys.c @@ -91,7 +91,7 @@ cmd_list_keys_print_notes(struct cmdq_item *item, struct args *args, struct key_binding *bd; const char *key; char *tmp, *note; - int found = 0; + int found = 0; table = key_bindings_get_table(tablename, 0); if (table == NULL) @@ -321,6 +321,31 @@ out: return (CMD_RETURN_NORMAL); } +static void +cmd_list_single_command(const struct cmd_entry *entry, struct format_tree *ft, + const char *template, struct cmdq_item *item) +{ + const char *s; + char *line; + + format_add(ft, "command_list_name", "%s", entry->name); + if (entry->alias != NULL) + s = entry->alias; + else + s = ""; + format_add(ft, "command_list_alias", "%s", s); + if (entry->usage != NULL) + s = entry->usage; + else + s = ""; + format_add(ft, "command_list_usage", "%s", s); + + line = format_expand(ft, template); + if (*line != '\0') + cmdq_print(item, "%s", line); + free(line); +} + static enum cmd_retval cmd_list_keys_commands(struct cmd *self, struct cmdq_item *item) { @@ -328,8 +353,8 @@ cmd_list_keys_commands(struct cmd *self, struct cmdq_item *item) const struct cmd_entry **entryp; const struct cmd_entry *entry; struct format_tree *ft; - const char *template, *s, *command; - char *line; + const char *template, *command; + char *cause; if ((template = args_get(args, 'F')) == NULL) { template = "#{command_list_name}" @@ -341,30 +366,19 @@ cmd_list_keys_commands(struct cmd *self, struct cmdq_item *item) format_defaults(ft, NULL, NULL, NULL, NULL); command = args_string(args, 0); - for (entryp = cmd_table; *entryp != NULL; entryp++) { - entry = *entryp; - if (command != NULL && - (strcmp(entry->name, command) != 0 && - (entry->alias == NULL || - strcmp(entry->alias, command) != 0))) - continue; - - format_add(ft, "command_list_name", "%s", entry->name); - if (entry->alias != NULL) - s = entry->alias; - else - s = ""; - format_add(ft, "command_list_alias", "%s", s); - if (entry->usage != NULL) - s = entry->usage; - else - s = ""; - format_add(ft, "command_list_usage", "%s", s); - - line = format_expand(ft, template); - if (*line != '\0') - cmdq_print(item, "%s", line); - free(line); + if (command == NULL) { + for (entryp = cmd_table; *entryp != NULL; entryp++) + cmd_list_single_command(*entryp, ft, template, item); + } else { + entry = cmd_find(command, &cause); + if (entry != NULL) + cmd_list_single_command(entry, ft, template, item); + else { + cmdq_error(item, "%s", cause); + free(cause); + format_free(ft); + return (CMD_RETURN_ERROR); + } } format_free(ft); diff --git a/cmd.c b/cmd.c index 9e2ce036..64f63c92 100644 --- a/cmd.c +++ b/cmd.c @@ -445,7 +445,7 @@ cmd_get_alias(const char *name) } /* Look up a command entry by name. */ -static const struct cmd_entry * +const struct cmd_entry * cmd_find(const char *name, char **cause) { const struct cmd_entry **loop, *entry, *found = NULL; diff --git a/tmux.h b/tmux.h index 558bc009..1b6d889a 100644 --- a/tmux.h +++ b/tmux.h @@ -2597,6 +2597,7 @@ int cmd_find_from_nothing(struct cmd_find_state *, int); /* cmd.c */ extern const struct cmd_entry *cmd_table[]; +const struct cmd_entry *cmd_find(const char *, char **); void printflike(3, 4) cmd_log_argv(int, char **, const char *, ...); void cmd_prepend_argv(int *, char ***, const char *); void cmd_append_argv(int *, char ***, const char *);