diff options
Diffstat (limited to 'autoload')
-rw-r--r-- | autoload/paste_insert.vim | 139 |
1 files changed, 15 insertions, 124 deletions
diff --git a/autoload/paste_insert.vim b/autoload/paste_insert.vim index fe9e482..946e09a 100644 --- a/autoload/paste_insert.vim +++ b/autoload/paste_insert.vim @@ -5,9 +5,9 @@ function! paste_insert#() abort augroup paste_insert autocmd! - " Set up the paste and tell the user + " Set up the paste autocmd User Start - \ call s:Start() | echo 'Paste ready' + \ call s:Start() " When starting insert mode, add completion hook for when we leave autocmd InsertEnter * @@ -22,16 +22,6 @@ function! paste_insert#() abort autocmd BufLeave,WinLeave * \ doautocmd paste_insert User Abort - " Exit condition reporting - autocmd User Abort - \ echo 'Paste aborted' - autocmd User Cancel - \ echo 'Paste cancelled' - autocmd User Complete - \ echo 'Paste completed' - autocmd User Timeout - \ echo 'Paste timeout' - " End the paste and clear the events table autocmd User Abort,Cancel,Complete,Timeout \ call s:Stop() | autocmd! paste_insert @@ -43,125 +33,26 @@ function! paste_insert#() abort endfunction -" Keys that cancel the pending paste in normal mode, defaults to Ctrl-C and -" Escape -let s:cancel = get(g:, 'paste_insert_cancel', ['<C-C>', '<Esc>']) - -" Cache for the prior functions of those keys, in case the user has already -" mapped them -let s:maps = {} +" Keys that cancel a pending paste in normal mode +let s:cancel_keys = get(g:, 'paste_insert_cancel_keys', ['<C-C>', '<Esc>']) -" Function to abstract over shortcomings in Vim older than 7.3.032 in yielding -" incomplete map information; return as much as we can in the same structure -" as Vim after this patchlevel does with the {dict} parameter TRUE; -" unfortunately, this is just the mapping's right hand side. We should be -" able to figure out the <buffer> flag too, but that's it. The documentation -" for this plugin points out this unfortunate caveat, and suggests -" a workaround. -" -function! s:MapArg(key, mode) abort - if v:version > 703 || v:version == 703 && has('patch-32') - return maparg(a:key, a:mode, 0, 1) - else - let rhs = maparg(a:key, a:mode) - if rhs ==# '' - return {} - else - return { 'rhs': rhs } - endif - endif -endfunction - -" Start the paste: save each cancel key's prior function, remap it, set -" 'paste' +" Start the paste: remap any cancel keys, set 'paste' function! s:Start() abort - - " Collect and remove existing mappings for this key, replacing with a global - " map that cancels the pending paste operation - " - for key in s:cancel - let maps = [] - - " We might need to stop partway through this - try - - " Collect first mapping, perhaps a buffer-local mapping, since maparg() - " yields those first - let map = s:MapArg(key, 'n') - if !empty(map) - call add(maps, s:MapArg(key, 'n')) - endif - execute 'nunmap <buffer> '.key - - " Since we got here, the `:nunmap <buffer>` command must have worked, - " and there might be one more global map to collect - let map = s:MapArg(key, 'n') - if !empty(map) - call add(maps, s:MapArg(key, 'n')) - endif - execute 'nunmap '.key - - catch /^Vim\%((\a\+)\)\=:E31:/ " No such mapping - " Ignore it - endtry - - " If we collected two mappings, the first one must have been buffer-local, - " and Vim before 7.3.032 won't have told us that, so we'll flag it now - " - if len(maps) == 2 && !has_key(maps[0], 'buffer') - let maps[0]['buffer'] = 1 + for key in s:cancel_keys + if maparg(key, 'n') ==# '' + execute join(['nnoremap', key, + \ ':<C-U>doautocmd paste_insert User Cancel<CR>']) + else + echoerr key.' already mapped in normal mode, refusing to remap' endif - - " Add the collected maps to this key's cache - let s:maps[key] = maps - - " Set up our map to cancel the pending paste - execute 'nnoremap '.key - \.' :<C-U>doautocmd paste_insert User Cancel<CR>' endfor - - " Let's go! - set paste - + set paste paste? endfunction " Stop the paste: unset 'paste', restore prior function of cancel key function! s:Stop() abort - - " Let's stop! - set nopaste - - " Now we need to remove our temporary maps, and restore the user's - for key in s:cancel - - " Start by getting read of our map; there should now be none at all - execute 'nunmap '.key - - " Iterate through any cached maps for this key - for map in reverse(s:maps[key]) - - " Start building the command to restore the mapping; assume this is - " a nonrecursive map unless flagged otherwise - let command = !has_key(map, 'noremap') || map['noremap'] - \ ? ['nnoremap'] - \ : ['nmap'] - - " Restore any flags for the mapping as we know them - for flag in ['buffer', 'expr', 'nowait', 'silent'] - if has_key(map, flag) && map[flag] - call add(command, '<'.flag.'>') - endif - endfor - - " Add the key and right hand - call extend(command, [key, map['rhs']]) - execute join(command) - - endfor - - " Clear the map cache for this key, now that we've restored them - unlet s:maps[key] - + set nopaste paste? + for key in s:cancel_keys + execute join(['nunmap', key]) endfor - endfunction |