diff --git a/include/tig/keys.h b/include/tig/keys.h index 493e58d1a..06158284d 100644 --- a/include/tig/keys.h +++ b/include/tig/keys.h @@ -90,10 +90,11 @@ struct run_request { struct keymap *keymap; struct run_request_flags flags; const char **argv; + char *help; }; struct run_request *get_run_request(enum request request); -enum status_code add_run_request(struct keymap *keymap, const struct key key[], size_t keys, const char **argv); +enum status_code add_run_request(struct keymap *keymap, const struct key key[], size_t keys, const char **argv, const char *help); enum status_code parse_run_request_flags(struct run_request_flags *flags, const char **argv); const char *format_run_request_flags(const struct run_request *req); diff --git a/src/help.c b/src/help.c index 1b90cfcc7..d6d6a537a 100644 --- a/src/help.c +++ b/src/help.c @@ -62,6 +62,7 @@ help_draw(struct view *view, struct line *line, unsigned int lineno) return true; sep = " "; } + if (req->help) draw_text(view, LINE_DEFAULT, req->help); } else { const struct request_info *req_info = help->data.req_info; diff --git a/src/keys.c b/src/keys.c index a1c82ef55..c746e9168 100644 --- a/src/keys.c +++ b/src/keys.c @@ -486,7 +486,7 @@ parse_run_request_flags(struct run_request_flags *flags, const char **argv) enum status_code add_run_request(struct keymap *keymap, const struct key key[], - size_t keys, const char **argv) + size_t keys, const char **argv, const char *help) { struct run_request *req; struct run_request_flags flags = {0}; @@ -505,6 +505,12 @@ add_run_request(struct keymap *keymap, const struct key key[], req->flags = flags; req->keymap = keymap; + /* If there is help text, then dupe it into the run_request struct */ + req->help = NULL; + if (help) + if ((req->help = strdup(help)) == NULL) + return ERROR_OUT_OF_MEMORY; + return add_keybinding(keymap, REQ_RUN_REQUESTS + run_requests, key, keys); } diff --git a/src/options.c b/src/options.c index a4e254741..8b95b1971 100644 --- a/src/options.c +++ b/src/options.c @@ -789,6 +789,11 @@ option_set_command(int argc, const char *argv[]) } /* Wants: mode request key */ +/* Assuming the bind option is 'bind keymap key !command parameters # comments', + * the calling convention for the function is as follows: + * argv[0] will contain the trimmed comment text string (optional) + * argv[n] where n > 0 will contain command and parameters + */ static enum status_code option_bind_command(int argc, const char *argv[]) { @@ -798,6 +803,12 @@ option_bind_command(int argc, const char *argv[]) struct keymap *keymap; const char *key_arg; + /* Cache the help text */ + const char *help = argv[0]; + + /* Shift argv list by one position */ + argv++; argc--; + if (argc < 3) return error("Invalid key binding: bind keymap key action"); @@ -870,7 +881,7 @@ option_bind_command(int argc, const char *argv[]) const char *toggle[] = { ":toggle", mapped, arg, NULL}; const char *other[] = { mapped, NULL }; const char **prompt = *mapped == ':' ? other : toggle; - enum status_code code = add_run_request(keymap, key, keys, prompt); + enum status_code code = add_run_request(keymap, key, keys, prompt, NULL); if (code == SUCCESS) code = error("%s has been replaced by `%s%s%s%s'", @@ -882,7 +893,7 @@ option_bind_command(int argc, const char *argv[]) } if (request == REQ_UNKNOWN) - return add_run_request(keymap, key, keys, argv + 2); + return add_run_request(keymap, key, keys, argv + 2, help); return add_keybinding(keymap, request, key, keys); } @@ -957,12 +968,19 @@ read_option(char *opt, size_t optlen, char *value, size_t valuelen, void *data) const char *argv[SIZEOF_ARG]; int argc = 0; - if (len < valuelen) { + bool have_comments = len < valuelen; + if (have_comments) { valuelen = len; value[valuelen] = 0; } - if (!argv_from_string(argv, &argc, value)) + /* If handling a bind option, then add any trimmed comment text to head of the argv list */ + if (!strcmp(opt, "bind")) { + argv[0] = have_comments ? string_trim(value + len + 1) : NULL; + argc++; + } + + if (!argv_from_string(argv, &argc, value )) status = error("Too many option arguments for %s", opt); else status = set_option(opt, argc, argv); @@ -1324,14 +1342,14 @@ set_remote_branch(const char *name, const char *value, size_t valuelen) static void set_repo_config_option(char *name, char *value, enum status_code (*cmd)(int, const char **)) { - const char *argv[SIZEOF_ARG] = { name, "=" }; - int argc = 1 + (cmd == option_set_command); - enum status_code code; - - if (!argv_from_string(argv, &argc, value)) - code = error("Too many arguments"); - else - code = cmd(argc, argv); + const char *argv[SIZEOF_ARG]; int argc; + if (cmd == option_set_command ) { argv[0] = name; argv[1] = "="; argc = 2; } + else if (cmd == option_bind_command) { argv[0] = ""; argv[1] = name; argc = 2; } + else { argv[0] = name; argc = 1; } + + enum status_code code = !argv_from_string(argv, &argc, value) + ? error("Too many arguments") + : cmd(argc, argv); if (code != SUCCESS) warn("Option 'tig.%s': %s", name, get_status_message(code));