Fix command prompt not to always append argument but only if there has
authornicm <nicm@openbsd.org>
Wed, 15 Mar 2023 08:15:39 +0000 (08:15 +0000)
committernicm <nicm@openbsd.org>
Wed, 15 Mar 2023 08:15:39 +0000 (08:15 +0000)
actually been expansion. GitHub issue 3493.

usr.bin/tmux/arguments.c
usr.bin/tmux/cmd-command-prompt.c
usr.bin/tmux/cmd-parse.y

index cffb693..3c17330 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: arguments.c,v 1.58 2023/01/08 23:34:46 nicm Exp $ */
+/* $OpenBSD: arguments.c,v 1.59 2023/03/15 08:15:39 nicm Exp $ */
 
 /*
  * Copyright (c) 2010 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -98,6 +98,22 @@ args_copy_value(struct args_value *to, struct args_value *from)
        }
 }
 
+/* Type to string. */
+static const char *
+args_type_to_string (enum args_type type)
+{
+       switch (type)
+       {
+       case ARGS_NONE:
+               return "NONE";
+       case ARGS_STRING:
+               return "STRING";
+       case ARGS_COMMANDS:
+               return "COMMANDS";
+       }
+       return "INVALID";
+}
+
 /* Get value as string. */
 static const char *
 args_value_as_string(struct args_value *value)
@@ -250,8 +266,8 @@ args_parse(const struct args_parse *parse, struct args_value *values,
                        value = &values[i];
 
                        s = args_value_as_string(value);
-                       log_debug("%s: %u = %s (type %d)", __func__, i, s,
-                           value->type);
+                       log_debug("%s: %u = %s (type %s)", __func__, i, s,
+                           args_type_to_string (value->type));
 
                        if (parse->cb != NULL) {
                                type = parse->cb(args, args->count, cause);
@@ -796,6 +812,8 @@ args_make_commands(struct args_command_state *state, int argc, char **argv,
        }
 
        cmd = xstrdup(state->cmd);
+       log_debug("%s: %s", __func__, cmd);
+       cmd_log_argv(argc, argv, __func__);
        for (i = 0; i < argc; i++) {
                new_cmd = cmd_template_replace(cmd, argv[i], i + 1);
                log_debug("%s: %%%u %s: %s", __func__, i + 1, argv[i], new_cmd);
index 68faef7..95e11eb 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-command-prompt.c,v 1.65 2022/05/30 12:55:25 nicm Exp $ */
+/* $OpenBSD: cmd-command-prompt.c,v 1.66 2023/03/15 08:15:39 nicm Exp $ */
 
 /*
  * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -179,10 +179,10 @@ cmd_command_prompt_callback(struct client *c, void *data, const char *s,
 
        if (s == NULL)
                goto out;
+
        if (done) {
                if (cdata->flags & PROMPT_INCREMENTAL)
                        goto out;
-
                cmd_append_argv(&cdata->argc, &cdata->argv, s);
                if (++cdata->current != cdata->count) {
                        prompt = &cdata->prompts[cdata->current];
@@ -193,8 +193,11 @@ cmd_command_prompt_callback(struct client *c, void *data, const char *s,
 
        argc = cdata->argc;
        argv = cmd_copy_argv(cdata->argc, cdata->argv);
-       cmd_append_argv(&argc, &argv, s);
+       if (!done)
+               cmd_append_argv(&argc, &argv, s);
+
        if (done) {
+               cmd_free_argv(cdata->argc, cdata->argv);
                cdata->argc = argc;
                cdata->argv = cmd_copy_argv(argc, argv);
        }
index abfc53c..8140b5b 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-parse.y,v 1.49 2022/10/25 09:12:05 nicm Exp $ */
+/* $OpenBSD: cmd-parse.y,v 1.50 2023/03/15 08:15:39 nicm Exp $ */
 
 /*
  * Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1615,13 +1615,24 @@ yylex_token(int ch)
 
        for (;;) {
                /* EOF or \n are always the end of the token. */
-               if (ch == EOF || (state == NONE && ch == '\n'))
+               if (ch == EOF) {
+                       log_debug("%s: end at EOF", __func__);
+                       break;
+               }
+               if (state == NONE && ch == '\n') {
+                       log_debug("%s: end at EOL", __func__);
                        break;
+               }
 
                /* Whitespace or ; or } ends a token unless inside quotes. */
-               if ((ch == ' ' || ch == '\t' || ch == ';' || ch == '}') &&
-                   state == NONE)
+               if (state == NONE && (ch == ' ' || ch == '\t')) {
+                       log_debug("%s: end at WS", __func__);
                        break;
+               }
+               if (state == NONE && (ch == ';' || ch == '}')) {
+                       log_debug("%s: end at %c", __func__, ch);
+                       break;
+               }
 
                /*
                 * Spaces and comments inside quotes after \n are removed but