From 9585a93c306d9309f6c86074d271772627e2b714 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sun, 23 Jun 2019 23:36:07 +1200 Subject: 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. --- autoload/paste_insert.vim | 139 +++++----------------------------------------- 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', ['', '']) - -" 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', ['', '']) -" 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 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 '.key - - " Since we got here, the `:nunmap ` 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, + \ ':doautocmd paste_insert User Cancel']) + 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 - \.' :doautocmd paste_insert User Cancel' 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. `['', '']` 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 or -won't be restored correctly, although 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 . -- cgit v1.2.3 From cb1f32c1bdd661a64ec6775cf4e5c98777309d4b Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sun, 23 Jun 2019 23:37:12 +1200 Subject: Bump VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 0d91a54..1d0ba9e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.0 +0.4.0 -- cgit v1.2.3