]> granicus.if.org Git - vim/commitdiff
patch 8.2.4934: string interpolation fails when not evaluating v8.2.4934
authorBram Moolenaar <Bram@vim.org>
Tue, 10 May 2022 17:11:43 +0000 (18:11 +0100)
committerBram Moolenaar <Bram@vim.org>
Tue, 10 May 2022 17:11:43 +0000 (18:11 +0100)
Problem:    String interpolation fails when not evaluating.
Solution:   Skip the expression when not evaluating. (closes #10398)

src/evalvars.c
src/proto/evalvars.pro
src/testdir/test_vim9_expr.vim
src/typval.c
src/version.c

index d8ee2160842f71950d05282b1cfb5b70df0bced4..e83c50dff2996f0ddeebed831c31d263f4c3371d 100644 (file)
@@ -605,10 +605,11 @@ list_script_vars(int *first)
 /*
  * Evaluate one Vim expression {expr} in string "p" and append the
  * resulting string to "gap".  "p" points to the opening "{".
+ * When "evaluate" is FALSE only skip over the expression.
  * Return a pointer to the character after "}", NULL for an error.
  */
     char_u *
-eval_one_expr_in_str(char_u *p, garray_T *gap)
+eval_one_expr_in_str(char_u *p, garray_T *gap, int evaluate)
 {
     char_u     *block_start = skipwhite(p + 1);  // skip the opening {
     char_u     *block_end = block_start;
@@ -627,13 +628,16 @@ eval_one_expr_in_str(char_u *p, garray_T *gap)
        semsg(_(e_missing_close_curly_str), p);
        return NULL;
     }
-    *block_end = NUL;
-    expr_val = eval_to_string(block_start, TRUE);
-    *block_end = '}';
-    if (expr_val == NULL)
-       return NULL;
-    ga_concat(gap, expr_val);
-    vim_free(expr_val);
+    if (evaluate)
+    {
+       *block_end = NUL;
+       expr_val = eval_to_string(block_start, TRUE);
+       *block_end = '}';
+       if (expr_val == NULL)
+           return NULL;
+       ga_concat(gap, expr_val);
+       vim_free(expr_val);
+    }
 
     return block_end + 1;
 }
@@ -691,7 +695,7 @@ eval_all_expr_in_str(char_u *str)
        }
 
        // Evaluate the expression and append the result.
-       p = eval_one_expr_in_str(p, &ga);
+       p = eval_one_expr_in_str(p, &ga, TRUE);
        if (p == NULL)
        {
            ga_clear(&ga);
index ce794351dd64282405b4ca963591243e4c83745b..4683c15ffa55923d667b0ceee7c2051fa4110cc1 100644 (file)
@@ -13,7 +13,7 @@ list_T *eval_spell_expr(char_u *badword, char_u *expr);
 int get_spellword(list_T *list, char_u **pp);
 void prepare_vimvar(int idx, typval_T *save_tv);
 void restore_vimvar(int idx, typval_T *save_tv);
-char_u *eval_one_expr_in_str(char_u *p, garray_T *gap);
+char_u *eval_one_expr_in_str(char_u *p, garray_T *gap, int evaluate);
 char_u *eval_all_expr_in_str(char_u *str);
 list_T *heredoc_get(exarg_T *eap, char_u *cmd, int script_get, int vim9compile);
 void ex_var(exarg_T *eap);
index 202bb58e696f5261f8189ae1c2792e4940385b64..bbe39d1b4d9e5416fcf472a51bbde6ff82acd8a7 100644 (file)
@@ -2156,6 +2156,13 @@ def Test_expr8_string()
               ->split($'x{x}x')
               ->map((_, v: string) => v =~ 'bar')
   assert_equal([false, true, false], vl)
+
+  # interpolated string in a lambda
+  lines =<< trim END
+      assert_equal(['gnome-256color', 'xterm-256color'], ['gnome', 'xterm']
+              ->map((_, term: string) => $'{term}-256color'))
+  END
+  v9.CheckDefAndScriptSuccess(lines)
 enddef
 
 def Test_expr8_vimvar()
index 09dc474935c09ccbe102095d65c4c9176c415c68..a266330622c8233c0e1fa6aa711d3a2428576c90 100644 (file)
@@ -2363,7 +2363,7 @@ eval_interp_string(char_u **arg, typval_T *rettv, int evaluate)
            ++*arg;
            break;
        }
-       p = eval_one_expr_in_str(*arg, &ga);
+       p = eval_one_expr_in_str(*arg, &ga, evaluate);
        if (p == NULL)
        {
            ret = FAIL;
index cffc7035774e31e24b0dee31f11fcaf675dd106c..80f631bdc37d61b4a2c6e92e9aecd54db83406b8 100644 (file)
@@ -746,6 +746,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4934,
 /**/
     4933,
 /**/