To: vim_dev@googlegroups.com Subject: Patch 8.2.2796 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.2796 Problem: Vim9: redir to variable does not accept an index. Solution: Make the index work. Files: src/vim9compile.c, src/testdir/test_vim9_cmd.vim *** ../vim-8.2.2795/src/vim9compile.c 2021-04-21 12:19:31.163014769 +0200 --- src/vim9compile.c 2021-04-21 13:13:18.254925202 +0200 *************** *** 134,143 **** typedef struct { assign_dest_T lhs_dest; // type of destination ! char_u *lhs_name; // allocated name including // "[expr]" or ".name". size_t lhs_varlen; // length of the variable without // "[expr]" or ".name" char_u *lhs_dest_end; // end of the destination, including // "[expr]" or ".name". --- 134,147 ---- typedef struct { assign_dest_T lhs_dest; // type of destination ! char_u *lhs_name; // allocated name excluding the last // "[expr]" or ".name". size_t lhs_varlen; // length of the variable without // "[expr]" or ".name" + char_u *lhs_whole; // allocated name including the last + // "[expr]" or ".name" for :redir + size_t lhs_varlen_total; // length of the variable including + // any "[expr]" or ".name" char_u *lhs_dest_end; // end of the destination, including // "[expr]" or ".name". *************** *** 5845,5850 **** --- 5849,5855 ---- // compute the length of the destination without "[expr]" or ".name" lhs->lhs_varlen = var_end - var_start; + lhs->lhs_varlen_total = lhs->lhs_varlen; lhs->lhs_name = vim_strnsave(var_start, lhs->lhs_varlen); if (lhs->lhs_name == NULL) return FAIL; *************** *** 6073,6079 **** --- 6078,6087 ---- { p = skip_index(after); if (*p != '[' && *p != '.') + { + lhs->lhs_varlen_total = p - var_start; break; + } after = p; } if (after > var_start + lhs->lhs_varlen) *************** *** 8592,8608 **** compile_redir(char_u *line, exarg_T *eap, cctx_T *cctx) { char_u *arg = eap->arg; ! if (cctx->ctx_redir_lhs.lhs_name != NULL) { if (STRNCMP(arg, "END", 3) == 0) { ! if (cctx->ctx_redir_lhs.lhs_append) { ! if (compile_load_lhs(&cctx->ctx_redir_lhs, ! cctx->ctx_redir_lhs.lhs_name, NULL, cctx) == FAIL) return NULL; ! if (cctx->ctx_redir_lhs.lhs_has_index) emsg("redir with index not implemented yet"); } --- 8600,8616 ---- compile_redir(char_u *line, exarg_T *eap, cctx_T *cctx) { char_u *arg = eap->arg; + lhs_T *lhs = &cctx->ctx_redir_lhs; ! if (lhs->lhs_name != NULL) { if (STRNCMP(arg, "END", 3) == 0) { ! if (lhs->lhs_append) { ! if (compile_load_lhs(lhs, lhs->lhs_name, NULL, cctx) == FAIL) return NULL; ! if (lhs->lhs_has_index) emsg("redir with index not implemented yet"); } *************** *** 8610,8622 **** // in the variable. generate_instr_type(cctx, ISN_REDIREND, &t_string); ! if (cctx->ctx_redir_lhs.lhs_append) generate_instr_drop(cctx, ISN_CONCAT, 1); ! if (generate_store_lhs(cctx, &cctx->ctx_redir_lhs, -1) == FAIL) return NULL; ! VIM_CLEAR(cctx->ctx_redir_lhs.lhs_name); return arg + 3; } emsg(_(e_cannot_nest_redir)); --- 8618,8639 ---- // in the variable. generate_instr_type(cctx, ISN_REDIREND, &t_string); ! if (lhs->lhs_append) generate_instr_drop(cctx, ISN_CONCAT, 1); ! if (lhs->lhs_has_index) ! { ! // Use the info in "lhs" to store the value at the index in the ! // list or dict. ! if (compile_assign_unlet(lhs->lhs_whole, lhs, TRUE, ! &t_string, cctx) == FAIL) ! return NULL; ! } ! else if (generate_store_lhs(cctx, lhs, -1) == FAIL) return NULL; ! VIM_CLEAR(lhs->lhs_name); ! VIM_CLEAR(lhs->lhs_whole); return arg + 3; } emsg(_(e_cannot_nest_redir)); *************** *** 8625,8631 **** if (arg[0] == '=' && arg[1] == '>') { ! int append = FALSE; // redirect to a variable is compiled arg += 2; --- 8642,8648 ---- if (arg[0] == '=' && arg[1] == '>') { ! int append = FALSE; // redirect to a variable is compiled arg += 2; *************** *** 8636,8648 **** } arg = skipwhite(arg); ! if (compile_assign_lhs(arg, &cctx->ctx_redir_lhs, CMD_redir, FALSE, FALSE, 1, cctx) == FAIL) return NULL; generate_instr(cctx, ISN_REDIRSTART); ! cctx->ctx_redir_lhs.lhs_append = append; ! return arg + cctx->ctx_redir_lhs.lhs_varlen; } // other redirects are handled like at script level --- 8653,8671 ---- } arg = skipwhite(arg); ! if (compile_assign_lhs(arg, lhs, CMD_redir, FALSE, FALSE, 1, cctx) == FAIL) return NULL; generate_instr(cctx, ISN_REDIRSTART); ! lhs->lhs_append = append; ! if (lhs->lhs_has_index) ! { ! lhs->lhs_whole = vim_strnsave(arg, lhs->lhs_varlen_total); ! if (lhs->lhs_whole == NULL) ! return NULL; ! } ! return arg + lhs->lhs_varlen_total; } // other redirects are handled like at script level *************** *** 9335,9340 **** --- 9358,9364 ---- ret = FAIL; } vim_free(cctx.ctx_redir_lhs.lhs_name); + vim_free(cctx.ctx_redir_lhs.lhs_whole); } current_sctx = save_current_sctx; *** ../vim-8.2.2795/src/testdir/test_vim9_cmd.vim 2021-04-20 21:10:44.818613886 +0200 --- src/testdir/test_vim9_cmd.vim 2021-04-21 13:31:46.431763561 +0200 *************** *** 1212,1221 **** --- 1212,1246 ---- redir END assert_equal("\nsomething\nmore", result) + var d: dict + redir => d.redir + echo 'dict' + redir END + assert_equal({redir: "\ndict"}, d) + + var l = ['a', 'b', 'c'] + redir => l[1] + echo 'list' + redir END + assert_equal(['a', "\nlist", 'c'], l) + + var dl = {l: ['x']} + redir => dl.l[0] + echo 'dict-list' + redir END + assert_equal({l: ["\ndict-list"]}, dl) + var lines =<< trim END redir => notexist END CheckDefFailure(lines, 'E1089:') + + lines =<< trim END + var ls = 'asdf' + redir => ls[1] + redir END + END + CheckDefFailure(lines, 'E1141:') enddef *** ../vim-8.2.2795/src/version.c 2021-04-21 12:19:31.163014769 +0200 --- src/version.c 2021-04-21 14:21:51.184060473 +0200 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 2796, /**/ -- hundred-and-one symptoms of being an internet addict: 135. You cut classes or miss work so you can stay home and browse the web. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///