diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2019-06-23 23:36:07 +1200 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2019-06-23 23:36:07 +1200 |
commit | 9585a93c306d9309f6c86074d271772627e2b714 (patch) | |
tree | 1d0198a308dff449eb259288c4038a42a8a0c421 | |
parent | Merge branch 'release/v0.3.0' into develop (diff) | |
download | vim-paste-insert-9585a93c306d9309f6c86074d271772627e2b714.tar.gz vim-paste-insert-9585a93c306d9309f6c86074d271772627e2b714.zip |
Remove the complex remapping attempt
It's more straightforward and probably less buggy just to rely on the
user to set keys they haven't mapped. The defaults are sensible enough.
-rw-r--r-- | autoload/paste_insert.vim | 139 | ||||
-rw-r--r-- | doc/paste_insert.txt | 22 |
2 files changed, 23 insertions, 138 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 diff --git a/doc/paste_insert.txt b/doc/paste_insert.txt index d9b2bb2..68f1ef9 100644 --- a/doc/paste_insert.txt +++ b/doc/paste_insert.txt @@ -2,13 +2,14 @@ DESCRIPTION *paste_insert* -This small plugin provides a simple "one shot paste" method, with a command or -mapping to prefix opening an insert, with the 'paste' option automatically set -after the insert ends, to avoid the annoyances caused by forgetting to do so. +This plugin implements a method for setting paste mode with the 'paste' option +for only the duration of the next insert operation, to avoid the hassle of +forgetting to unset the option after inserting. It includes a timeout if insert mode isn't entered within 'updatetime' seconds, or if the user navigates away from the buffer or window. It can also -be cancelled with keys in normal mode, by default CTRL-C or Escape. +be cancelled in normal mode with CTRL-C or Escape. These keys can be changed +if they are already mapped or otherwise unsuitable. REQUIREMENTS *paste_insert-requirements* @@ -38,10 +39,9 @@ Set `g:paste_insert_cancel` to a |List| of the special codes for keys you want to cancel the pending paste in normal mode. `['<C-C>', '<Esc>']` is the default, for CTRL-C and Escape. -The plugin will overwrite any existing normal mode maps for these keys during -the normal mode phase of the operation, but will try to restore them -afterwards. If you don't want your mappings touched at all, set this to the -empty list, and the plugin will leave them alone. +The plugin will complain on starting a paste operation if either of the keys +are already mapped, globally or locally, so pick keys you never remap, or set +this option to a blank |List| `[]` to disable it. CAVEATS *paste_insert-caveats* @@ -51,12 +51,6 @@ with CTRL-C, the |InsertLeave| event doesn't fire, and you'll still be in window should fix it. Friends don't let friends use CTRL-C to break insert mode! -The map restoration for your chosen cancel keys works well in Vim v7.3.032 or -newer, but before that patch, recursive maps and flags like <expr> or <silent> -won't be restored correctly, although <buffer> should still work. If it's -mangling your mappings and you don't want to change keys, your only option is -to upgrade Vim. - AUTHOR *paste_insert-author* Written and maintained by Tom Ryder <tom@sanctum.geek.nz>. |