On 01-Jun-2012 18:52, Bram Moolenaar wrote:
> Ingo Karkat wrote:
>
>> :startinsert should work like typing "i" in Normal mode (according to
>> the help). I found a small discrepancy while developing a custom
>> mapping:
>>
>> vim -N -u NONE
>> ifoo<Esc>
>> :echo string(@.) getpos("'[") getpos("']")
>> 'foo' [0, 1, 1, 0] [0, 1, 4, 0]
>> i<Esc>
>> :echo string(@.) getpos("'[") getpos("']")
>> '' [0, 1, 3, 0] [0, 1, 3, 0]
>> :quit!
>>
>> Contrast with:
>>
>> vim -N -u NONE
>> :startinsert
>> foo<Esc>
>> :echo string(@.) getpos("'[") getpos("']")
>> 'foo' [0, 1, 1, 0] [0, 1, 4, 0]
>> :startinsert
>> <Esc>
>> :echo string(@.) getpos("'[") getpos("']")
>> 'foo' [0, 1, 1, 0] [0, 1, 4, 0]
>> :quit!
>>
>> Note how neither register . nor the change marks are updated when using
>> :startinsert and no insertion took place (i.e. input mode was immediately
>> left
>> via <Esc>).
>>
>> Reproducible on Vim 7.3.000 (Windows 7, x86 and x64) as well as the latest
>> 7.3.535 (big version, Linux/x86).
>
> Well, why does the difference matter?
>From a mapping, I set up an autocmd that triggers on InsertLeave, then start
inserting. In the autocmd, I check for actual text entry by comparing register .
with its previous contents. For those interested, I'm attaching the full mapping
at the end.
> It won't be easy to change.
Well, in my case, I was able to work around this by switching from :startinsert
inside the function to appending "i" to the mapping that triggers the function.
But it took me half an hour to realize this is due to the bug, which is
frustrating. And other uses may not be so lucky, after all, :startinsert is
there for a reason.
-- regards, ingo
- %<----------------------- snip - cut here ----------------------- %<-
"|g~| Switch case of the character under the cursor, then
" enter insert mode. Useful to turn "fooBar" into
" "tempFooBar" and then use /\<fooBar\> searches to
" iteratively repeat this. Also faster than
" :%s/\<fooBar\>/temp\u&/gc. And it even works with
" deletion = insertion of ^H^H^H^H.
function! s:SwitchCaseAndPrepend()
normal! g~l
" We cannot install repetition already; inserting further increments
" b:changedtick. Instead, do this when inserting is done.
augroup SwitchCaseAndPrepend
" Detect an empty insert and skip the no-op insert in that case.
autocmd! InsertLeave <buffer> silent! call repeat#set(
\ empty(@.) ?
\ "\<Plug>(SwitchCaseWithoutPrependRepeat)" :
\ "\<Plug>(SwitchCaseAndPrependRepeat)")
\ | autocmd! SwitchCaseAndPrepend
augroup END
endfunction
function! s:SwitchCaseAndPrependRepeat()
execute "normal! g~li\<C-@>"
silent! call repeat#set("\<Plug>(SwitchCaseAndPrependRepeat)")
endfunction
" The case switch repeats naturally.
nnoremap <silent> <Plug>(SwitchCaseWithoutPrependRepeat) g~l
" Use the previously inserted text on repetition.
nnoremap <silent> <Plug>(SwitchCaseAndPrependRepeat) :<C-U>call
<SID>SwitchCaseAndPrependRepeat()<CR>
" XXX: Do not use :startinsert, it doesn't clear ". when insertion is aborted
" immediately (in Vim 7.3).
nnoremap <silent> g~ :<C-U>call <SID>SwitchCaseAndPrepend()<CR>i
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php