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