diff --git a/README.md b/README.md index 380a3b4..9585c49 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,7 @@ Commands | `Commits` | Git commits (requires [fugitive.vim][f]) | | `BCommits` | Git commits for the current buffer | | `Commands` | Commands | +| `Maps` | Normal mode mappings | | `Helptags` | Help tags [1](#helptags) | - Most commands support `CTRL-T` / `CTRL-X` / `CTRL-V` key @@ -103,6 +104,10 @@ Mappings | Mapping | Description | | --- | --- | +| `(fzf-maps-n)` | Normal mode mappings | +| `(fzf-maps-i)` | Insert mode mappings | +| `(fzf-maps-x)` | Visual mode mappings | +| `(fzf-maps-o)` | Operator-pending mappings | | `(fzf-complete-word)` | `cat /usr/share/dict/words` | | `(fzf-complete-path)` | Path completion using `find` (file + dir) | | `(fzf-complete-file)` | File completion using `find` | @@ -113,6 +118,12 @@ Mappings ### Usage ```vim +" Mapping selecting mappings +nmap (fzf-maps-n) +xmap (fzf-maps-x) +omap (fzf-maps-o) + +" Insert mode completion imap (fzf-complete-word) imap (fzf-complete-path) imap (fzf-complete-file-ag) diff --git a/autoload/fzf/vim.vim b/autoload/fzf/vim.vim index 8afddad..5c030fc 100644 --- a/autoload/fzf/vim.vim +++ b/autoload/fzf/vim.vim @@ -711,6 +711,55 @@ function! fzf#vim#buffer_commits(...) return s:commits(1, a:000) endfunction +" ------------------------------------------------------------------ +" fzf#vim#maps(mode, opts[with count and op]) +" ------------------------------------------------------------------ +function! s:align_pairs(list) + let maxlen = 0 + let pairs = [] + for elem in a:list + let match = matchlist(elem, '^\(\S*\)\s*\(.*\)$') + let [_, k, v] = match[0:2] + let maxlen = max([maxlen, len(k)]) + call add(pairs, [k, v]) + endfor + return map(pairs, "printf('%-'.maxlen.'s', v:val[0]).' '.v:val[1]") +endfunction + +function! s:highlight_keys(str) + return substitute( + \ substitute(a:str, '<[^ >]\+>', "\x1b[33m\\0\x1b[m", 'g'), + \ "\x1b[33m\x1b[m", "\x1b[34m\x1b[m", 'g') +endfunction + +function! s:key_sink(line) + let key = matchstr(a:line, '^\S*') + redraw + call feedkeys(s:map_gv.s:map_cnt.s:map_reg.s:map_op. + \ substitute(key, '<[^ >]\+>', '\=eval("\"\\".submatch(0)."\"")', 'g')) +endfunction + +" To avoid conflict with other plugins also using feedkeys (peekaboo) +noremap (-fzf-vim-dq) " + +function! fzf#vim#maps(mode, ...) + let s:map_gv = a:mode == 'x' ? 'gv' : '' + let s:map_cnt = v:count == 0 ? '' : v:count + let s:map_reg = empty(v:register) ? '' : ("\(-fzf-vim-dq)".v:register) + let s:map_op = a:mode == 'o' ? v:operator : '' + redir => cout + silent execute a:mode.'map' + redir END + let list = map(split(cout, "\n"), 'v:val[3:]') + let aligned = s:align_pairs(map(split(cout, "\n"), 'v:val[3:]')) + let sorted = sort(aligned) + let colored = map(sorted, 's:highlight_keys(v:val)') + call s:fzf({ + \ 'source': colored, + \ 'sink': function('s:key_sink'), + \ 'options': '--ansi --no-hscroll --nth 1,..'}, a:000) +endfunction + " ---------------------------------------------------------------------------- " fzf#vim#complete - completion helper " ---------------------------------------------------------------------------- diff --git a/doc/fzf-vim.txt b/doc/fzf-vim.txt index 3a346bb..d5bc06a 100644 --- a/doc/fzf-vim.txt +++ b/doc/fzf-vim.txt @@ -92,6 +92,7 @@ COMMANDS *fzf-vim-commands* `Commits` | Git commits (requires {fugitive.vim}{7}) `BCommits` | Git commits for the current buffer `Commands` | Commands + `Maps` | Normal mode mappings `Helptags` | Help tags [1] -----------------+--------------------------------------------------------------------- @@ -135,6 +136,10 @@ MAPPINGS *fzf-vim-mappings* ---------------------------------+------------------------------------------ Mapping | Description ~ ---------------------------------+------------------------------------------ + (fzf-maps-n) | Normal mode mappings + (fzf-maps-i) | Insert mode mappings + (fzf-maps-x) | Visual mode mappings + (fzf-maps-o) | Operator-pending mappings (fzf-complete-word) | `cat /usr/share/dict/words` (fzf-complete-path) | Path completion using `find` (file + dir) (fzf-complete-file) | File completion using `find` @@ -147,6 +152,12 @@ MAPPINGS *fzf-vim-mappings* < Usage >_____________________________________________________________________~ *fzf-vim-usage* > + " Mapping selecting mappings + nmap (fzf-maps-n) + xmap (fzf-maps-x) + omap (fzf-maps-o) + + " Insert mode completion imap (fzf-complete-word) imap (fzf-complete-path) imap (fzf-complete-file-ag) diff --git a/plugin/fzf.vim b/plugin/fzf.vim index ca0dc2b..64ce688 100644 --- a/plugin/fzf.vim +++ b/plugin/fzf.vim @@ -58,6 +58,7 @@ call s:defs([ \'command! -bang Windows call fzf#vim#windows(s:w(0))', \'command! -bang Commits call fzf#vim#commits(s:w(0))', \'command! -bang BCommits call fzf#vim#buffer_commits(s:w(0))', +\'command! -bang Maps call fzf#vim#maps("n", s:w(0))', \'command! -bang -nargs=* History call s:history(, 0)']) function! s:history(arg, bang) @@ -112,6 +113,11 @@ inoremap (fzf-complete-file-ag) fzf#vim#complete#path("ag -l -g inoremap (fzf-complete-line) fzf#vim#complete#line() inoremap (fzf-complete-buffer-line) fzf#vim#complete#buffer_line() +nnoremap (fzf-maps-n) :call fzf#vim#maps('n', w(0)) +inoremap (fzf-maps-i) :call fzf#vim#maps('i', w(0)) +xnoremap (fzf-maps-x) :call fzf#vim#maps('x', w(0)) +onoremap (fzf-maps-o) :call fzf#vim#maps('o', w(0)) + let &cpo = s:cpo_save unlet s:cpo_save