Patch 8.2.3710

8 views
Skip to first unread message

Bram Moolenaar

unread,
Dec 1, 2021, 4:27:56 AM12/1/21
to vim...@googlegroups.com

Patch 8.2.3710
Problem: Vim9: backtick expression expanded for :global.
Solution: Check the following command.
Files: runtime/doc/vim9.txt, src/vim9compile.c,
src/testdir/test_vim9_cmd.vim


*** ../vim-8.2.3709/runtime/doc/vim9.txt 2021-11-30 16:14:44.052582170 +0000
--- runtime/doc/vim9.txt 2021-12-01 09:03:35.134951769 +0000
***************
*** 1025,1060 ****
function scope. Instead, use a lambda: >
def MapList(): list<string>
var list = ['aa', 'bb', 'cc', 'dd']
! return range(1, 2)->map(( _, v) => list[v])
enddef

! The same is true for commands that are not compiled, such as `:global`.
! For these the backtick expansion can be used. Example: >
def Replace()
! var newText = 'blah'
! g/pattern/s/^/`=newText`/
enddef

Closures defined in a loop will share the same context. For example: >
var flist: list<func>
! for i in range(10)
var inloop = i
flist[i] = () => inloop
endfor

The "inloop" variable will exist only once, all closures put in the list refer
! to the same instance, which in the end will have the value 9. This is
! efficient. If you do want a separate context for each closure call a function
! to define it: >
! def GetFunc(i: number): func
! var inloop = i
! return () => inloop
enddef

var flist: list<func>
! for i in range(10)
! flist[i] = GetFunc(i)
endfor

==============================================================================

--- 1128,1167 ----
function scope. Instead, use a lambda: >
def MapList(): list<string>
var list = ['aa', 'bb', 'cc', 'dd']
! return range(1, 2)->map((_, v) => list[v])
enddef

! For commands that are not compiled, such as `:edit`, backtick expansion can be
! used and it can use the local scope. Example: >
def Replace()
! var fname = 'blah.txt'
! edit `=fname`
enddef

Closures defined in a loop will share the same context. For example: >
var flist: list<func>
! for i in range(5)
var inloop = i
flist[i] = () => inloop
endfor
+ echo range(5)->map((i, _) => flist[i]())
+ # Result: [4, 4, 4, 4, 4]

The "inloop" variable will exist only once, all closures put in the list refer
! to the same instance, which in the end will have the value 4. This is
! efficient, also when looping many times. If you do want a separate context
! for each closure call a function to define it: >
! def GetClosure(i: number): func
! var infunc = i
! return () => infunc
enddef

var flist: list<func>
! for i in range(5)
! flist[i] = GetClosure(i)
endfor
+ echo range(5)->map((i, _) => flist[i]())
+ # Result: [0, 1, 2, 3, 4]

==============================================================================

*** ../vim-8.2.3709/src/vim9compile.c 2021-11-30 21:58:15.628436358 +0000
--- src/vim9compile.c 2021-12-01 09:20:02.280670246 +0000
***************
*** 9070,9075 ****
--- 9070,9076 ----
int has_expr = FALSE;
char_u *nextcmd = (char_u *)"";
char_u *tofree = NULL;
+ char_u *cmd_arg = NULL;

if (cctx->ctx_skip == SKIP_YES)
goto theend;
***************
*** 9172,9191 ****

p = skip_regexp_ex(eap->arg + 1, delim, TRUE, NULL, NULL, NULL);
if (*p == delim)
! {
! eap->arg = p + 1;
! has_expr = TRUE;
! }
}

if (eap->cmdidx == CMD_folddoopen || eap->cmdidx == CMD_folddoclosed)
{
exarg_T nea;

CLEAR_FIELD(nea);
! nea.cmd = eap->arg;
p = find_ex_command(&nea, NULL, lookup_scriptitem, NULL);
! if (nea.cmdidx <= CMD_SIZE)
{
has_expr = excmd_get_argt(nea.cmdidx) & (EX_XFILE | EX_EXPAND);
if (has_expr)
--- 9173,9192 ----

p = skip_regexp_ex(eap->arg + 1, delim, TRUE, NULL, NULL, NULL);
if (*p == delim)
! cmd_arg = p + 1;
}

if (eap->cmdidx == CMD_folddoopen || eap->cmdidx == CMD_folddoclosed)
+ cmd_arg = eap->arg;
+
+ if (cmd_arg != NULL)
{
exarg_T nea;

CLEAR_FIELD(nea);
! nea.cmd = cmd_arg;
p = find_ex_command(&nea, NULL, lookup_scriptitem, NULL);
! if (nea.cmdidx < CMD_SIZE)
{
has_expr = excmd_get_argt(nea.cmdidx) & (EX_XFILE | EX_EXPAND);
if (has_expr)
*** ../vim-8.2.3709/src/testdir/test_vim9_cmd.vim 2021-11-30 21:58:15.628436358 +0000
--- src/testdir/test_vim9_cmd.vim 2021-12-01 09:09:40.538225555 +0000
***************
*** 183,193 ****
enddef

def Test_global_backtick_expansion()
new
! setline(1, 'xx')
! var name = 'foobar'
! g/^xx/s/.*/`=name`
! assert_equal('foobar', getline(1))
bwipe!
enddef

--- 183,200 ----
enddef

def Test_global_backtick_expansion()
+ var name = 'xxx'
new
! setline(1, ['one', 'two', 'three'])
! set nomod
! g/two/edit `=name`
! assert_equal('xxx', bufname())
! bwipe!
!
! new
! setline(1, ['one', 'two', 'three'])
! g/two/s/^/`=name`/
! assert_equal('`=name`two', getline(2))
bwipe!
enddef

*** ../vim-8.2.3709/src/version.c 2021-11-30 21:58:15.628436358 +0000
--- src/version.c 2021-12-01 09:25:25.971792629 +0000
***************
*** 755,756 ****
--- 755,758 ----
{ /* Add new patch number below this line */
+ /**/
+ 3710,
/**/

--
ARTHUR: I've said I'm sorry about the old woman, but from the behind you
looked ...
DENNIS: What I object to is that you automatically treat me like an inferior...
ARTHUR: Well ... I AM king.
"Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

/// Bram Moolenaar -- Br...@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 ///
Reply all
Reply to author
Forward
0 new messages