vim-patch:8.2.2612: col('.') may get outdated column value

Problem:    col('.') may get outdated column value.
Solution:   Add a note to the help how to make this work and add a test for
            it. (closes vim/vim#7971)
18b7d86d7f
This commit is contained in:
Andy K. Massimino 2021-03-29 19:39:28 -04:00
parent aa6adacd77
commit b4aea3d1c8
2 changed files with 38 additions and 0 deletions

View File

@ -224,6 +224,20 @@ text before the cursor and start omni completion when some condition is met.
For abbreviations |v:char| is set to the character that was typed to trigger For abbreviations |v:char| is set to the character that was typed to trigger
the abbreviation. You can use this to decide how to expand the {lhs}. You the abbreviation. You can use this to decide how to expand the {lhs}. You
should not either insert or change the v:char. should not either insert or change the v:char.
Also, keep in mind that the expression may be evaluated when looking for
typeahead, before the previous command has been executed. For example: >
func StoreColumn()
let g:column = col('.')
return 'x'
endfunc
nnoremap <expr> x StoreColumn()
nmap ! f!x
You will notice that g:column has the value from before executing "fx",
because "z" is evaluated before "fx" is executed.
This can be solved by inserting <Ignore> before the character that is
expression-mapped: >
nmap ! f!<Ignore>x
Be very careful about side effects! The expression is evaluated while Be very careful about side effects! The expression is evaluated while
obtaining characters, you may very well make the command dysfunctional. obtaining characters, you may very well make the command dysfunctional.

View File

@ -427,6 +427,30 @@ func Test_error_in_map_expr()
exe buf .. 'bwipe!' exe buf .. 'bwipe!'
endfunc endfunc
func Test_expr_map_gets_cursor()
new
call setline(1, ['one', 'some w!rd'])
func StoreColumn()
let g:exprLine = line('.')
let g:exprCol = col('.')
return 'x'
endfunc
nnoremap <expr> x StoreColumn()
2
nmap ! f!<Ignore>x
call feedkeys("!", 'xt')
call assert_equal('some wrd', getline(2))
call assert_equal(2, g:exprLine)
call assert_equal(7, g:exprCol)
bwipe!
unlet g:exprLine
unlet g:exprCol
delfunc ExprMapped
nunmap x
nunmap !
endfunc
" Test for mapping errors " Test for mapping errors
func Test_map_error() func Test_map_error()
call assert_fails('unmap', 'E474:') call assert_fails('unmap', 'E474:')