From 126d364abe2e8c063efa5a888de6997ca05641fc Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 24 Jan 2017 19:59:19 +0000 Subject: [PATCH] server-info can become an alias rather than a command. --- cmd-show-messages.c | 15 ++-------- cmd.c | 70 +++++++++++++++++++++++++++++++++++++++++---- options-table.c | 10 +++++++ 3 files changed, 77 insertions(+), 18 deletions(-) diff --git a/cmd-show-messages.c b/cmd-show-messages.c index 57c83881..bc9fc0db 100644 --- a/cmd-show-messages.c +++ b/cmd-show-messages.c @@ -45,17 +45,6 @@ const struct cmd_entry cmd_show_messages_entry = { .exec = cmd_show_messages_exec }; -const struct cmd_entry cmd_server_info_entry = { - .name = "server-info", - .alias = "info", - - .args = { "", 0, 0 }, - .usage = "", - - .flags = CMD_AFTERHOOK, - .exec = cmd_show_messages_exec -}; - static int cmd_show_messages_terminals(struct cmdq_item *, int); static int cmd_show_messages_jobs(struct cmdq_item *, int); @@ -109,11 +98,11 @@ cmd_show_messages_exec(struct cmd *self, struct cmdq_item *item) int done, blank; done = blank = 0; - if (args_has(args, 'T') || self->entry == &cmd_server_info_entry) { + if (args_has(args, 'T')) { blank = cmd_show_messages_terminals(item, blank); done = 1; } - if (args_has(args, 'J') || self->entry == &cmd_server_info_entry) { + if (args_has(args, 'J')) { cmd_show_messages_jobs(item, blank); done = 1; } diff --git a/cmd.c b/cmd.c index 9119f7ac..751be910 100644 --- a/cmd.c +++ b/cmd.c @@ -93,7 +93,6 @@ extern const struct cmd_entry cmd_select_pane_entry; extern const struct cmd_entry cmd_select_window_entry; extern const struct cmd_entry cmd_send_keys_entry; extern const struct cmd_entry cmd_send_prefix_entry; -extern const struct cmd_entry cmd_server_info_entry; extern const struct cmd_entry cmd_set_buffer_entry; extern const struct cmd_entry cmd_set_environment_entry; extern const struct cmd_entry cmd_set_hook_entry; @@ -182,7 +181,6 @@ const struct cmd_entry *cmd_table[] = { &cmd_select_window_entry, &cmd_send_keys_entry, &cmd_send_prefix_entry, - &cmd_server_info_entry, &cmd_set_buffer_entry, &cmd_set_environment_entry, &cmd_set_hook_entry, @@ -308,21 +306,74 @@ cmd_stringify_argv(int argc, char **argv) return (buf); } +static int +cmd_try_alias(int *argc, char ***argv) +{ + struct options_entry *o; + int old_argc = *argc, new_argc; + char **old_argv = *argv, **new_argv; + u_int size, idx; + int i; + size_t wanted; + const char *s, *cp = NULL; + + o = options_get_only(global_options, "command-alias"); + if (o == NULL || options_array_size(o, &size) == -1 || size == 0) + return (-1); + + wanted = strlen(old_argv[0]); + for (idx = 0; idx < size; idx++) { + s = options_array_get(o, idx); + if (s == NULL) + continue; + + cp = strchr(s, '='); + if (cp == NULL || (size_t)(cp - s) != wanted) + continue; + if (strncmp(old_argv[0], s, wanted) == 0) + break; + } + if (idx == size) + return (-1); + + if (cmd_string_split(cp + 1, &new_argc, &new_argv) != 0) + return (-1); + + *argc = new_argc + old_argc - 1; + *argv = xcalloc((*argc) + 1, sizeof **argv); + + for (i = 0; i < new_argc; i++) + (*argv)[i] = xstrdup(new_argv[i]); + for (i = 1; i < old_argc; i++) + (*argv)[new_argc + i - 1] = xstrdup(old_argv[i]); + + log_debug("alias: %s=%s", old_argv[0], cp + 1); + for (i = 0; i < *argc; i++) + log_debug("alias: argv[%d] = %s", i, (*argv)[i]); + + cmd_free_argv(new_argc, new_argv); + return (0); +} + struct cmd * cmd_parse(int argc, char **argv, const char *file, u_int line, char **cause) { + const char *name; const struct cmd_entry **entryp, *entry; struct cmd *cmd; struct args *args; char s[BUFSIZ]; - int ambiguous = 0; + int ambiguous, allocated = 0; *cause = NULL; if (argc == 0) { xasprintf(cause, "no command"); return (NULL); } + name = argv[0]; +retry: + ambiguous = 0; entry = NULL; for (entryp = cmd_table; *entryp != NULL; entryp++) { if ((*entryp)->alias != NULL && @@ -342,10 +393,17 @@ cmd_parse(int argc, char **argv, const char *file, u_int line, char **cause) if (strcmp(entry->name, argv[0]) == 0) break; } + if ((ambiguous || entry == NULL) && + server_proc != NULL && + !allocated && + cmd_try_alias(&argc, &argv) == 0) { + allocated = 1; + goto retry; + } if (ambiguous) goto ambiguous; if (entry == NULL) { - xasprintf(cause, "unknown command: %s", argv[0]); + xasprintf(cause, "unknown command: %s", name); return (NULL); } @@ -365,6 +423,8 @@ cmd_parse(int argc, char **argv, const char *file, u_int line, char **cause) cmd->file = xstrdup(file); cmd->line = line; + if (allocated) + cmd_free_argv(argc, argv); return (cmd); ambiguous: @@ -378,7 +438,7 @@ ambiguous: break; } s[strlen(s) - 2] = '\0'; - xasprintf(cause, "ambiguous command: %s, could be: %s", argv[0], s); + xasprintf(cause, "ambiguous command: %s, could be: %s", name, s); return (NULL); usage: diff --git a/options-table.c b/options-table.c index b9559070..48e2f2c8 100644 --- a/options-table.c +++ b/options-table.c @@ -65,6 +65,16 @@ const struct options_table_entry options_table[] = { .default_num = 20 }, + { .name = "command-alias", + .type = OPTIONS_TABLE_ARRAY, + .scope = OPTIONS_TABLE_SERVER, + .default_str = "split-pane=split-window," + "splitp=split-window," + "server-info=show-messages -JT," + "info=show-messages -JT", + .separator = "," + }, + { .name = "default-terminal", .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_SERVER,