aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2019-06-23 00:40:44 +1200
committerTom Ryder <tom@sanctum.geek.nz>2019-06-23 00:42:49 +1200
commit182b9687b435553419b769be60324dd41fda3bd8 (patch)
tree485b1a84e4dc7597a54cb288e16600bb25d967ed
parentGet normal mode map specifically for cancel (diff)
downloadvim-paste-insert-182b9687b435553419b769be60324dd41fda3bd8.tar.gz
vim-paste-insert-182b9687b435553419b769be60324dd41fda3bd8.zip
More sophisticated map caching
This is surprisingly hard.
-rw-r--r--autoload/paste_insert.vim63
-rw-r--r--doc/paste_insert.txt7
2 files changed, 55 insertions, 15 deletions
diff --git a/autoload/paste_insert.vim b/autoload/paste_insert.vim
index c135f9d..92fdc54 100644
--- a/autoload/paste_insert.vim
+++ b/autoload/paste_insert.vim
@@ -49,19 +49,45 @@ 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:maparg = {}
+let s:maps = {}
+
+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'
function! s:Start() abort
for key in s:cancel
- let s:maparg[key] = maparg(key, 'n')
- let command = join([
- \ 'nnoremap'
- \,key
- \,':<C-U>doautocmd paste_insert User Cancel<CR>'
- \])
- execute command
+ let maps = []
+ try
+ let map = s:MapArg(key, 'n')
+ if !empty(map)
+ call add(maps, s:MapArg(key, 'n'))
+ endif
+ execute 'nunmap <buffer> '.key
+ let map = s:MapArg(key, 'n')
+ if !empty(map)
+ call add(maps, s:MapArg(key, 'n'))
+ endif
+ execute 'nunmap '.key
+ catch
+ endtry
+ if len(maps) == 2
+ let maps[0]['buffer'] = 1
+ endif
+ let s:maps[key] = maps
+ execute 'nnoremap '.key
+ \.' :<C-U>doautocmd paste_insert User Cancel<CR>'
endfor
set paste
endfunction
@@ -70,12 +96,19 @@ endfunction
function! s:Stop() abort
set nopaste
for key in s:cancel
- let command = join(
- \ s:maparg[key] !=# ''
- \ ? ['nnoremap', key, s:maparg[key]]
- \ : ['nunmap', key]
- \)
- execute command
- unlet s:maparg[key]
+ execute 'nunmap '.key
+ for map in reverse(s:maps[key])
+ let command = !has_key(map, 'noremap') || map['noremap']
+ \ ? ['nnoremap']
+ \ : ['nmap']
+ for flag in ['buffer', 'expr', 'nowait', 'silent']
+ if has_key(map, flag) && map[flag]
+ call add(command, '<'.flag.'>')
+ endif
+ endfor
+ call extend(command, [key, map['rhs']])
+ execute join(command)
+ endfor
+ unlet s:maps[key]
endfor
endfunction
diff --git a/doc/paste_insert.txt b/doc/paste_insert.txt
index ff17437..7286c15 100644
--- a/doc/paste_insert.txt
+++ b/doc/paste_insert.txt
@@ -32,6 +32,13 @@ Set `g:paste_insert_cancel` to a |List| of the keys you want to cancel the
pending paste in normal mode. This defaults to `['<C-C>', '<Esc>']`, 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 back
+afterwards. This works well in versions of Vim 7.3.032 or newer, but before
+that patch, recursive maps and flags like <expr> or <silent> are broken,
+although <buffer> should still work. Either pick keys that you don't map, or
+even better--upgrade your Vim!
+
AUTHOR *paste_insert-author*
Written and maintained by Tom Ryder <tom@sanctum.geek.nz>.