Skip to content

Instantly share code, notes, and snippets.

@DeaR
Last active December 17, 2015 05:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DeaR/5558981 to your computer and use it in GitHub Desktop.
Save DeaR/5558981 to your computer and use it in GitHub Desktop.
Sorted, Collected, Fix to <M-...>.
" Sorted, Collected, Fix to <M-...>.
"
" Maintainer: DeaR <nayuri@kuonn.mydns.jp>
" Last Change: 13-Aug-2013.
" License: MIT License {{{
" Copyright (c) 2013 DeaR <nayuri@kuonn.mydns.jp>
"
" Permission is hereby granted, free of charge, to any person obtaining a
" copy of this software and associated documentation files (the
" "Software"), to deal in the Software without restriction, including
" without limitation the rights to use, copy, modify, merge, publish,
" distribute, sublicense, and/or sell copies of the Software, and to permit
" persons to whom the Software is furnished to do so, subject to the
" following conditions:
"
" The above copyright notice and this permission notice shall be included
" in all copies or substantial portions of the Software.
"
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
" IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
" OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
" THE USE OR OTHER DEALINGS IN THE SOFTWARE.
" }}}
if exists('g:loaded_maplist')
finish
endif
let g:loaded_maplist = 1
let s:save_cpo = &cpo
set cpo&vim
" n ]] *@m':call search('^\s*fu\%[nction]\>', "W")<CR>
" ^^^
let g:maplist_mode_length =
\ get(g:, 'maplist_mode_length', 3)
" n ]] *@m':call search('^\s*fu\%[nction]\>', "W")<CR>
" ^^^^^^^^^^^
let g:maplist_lhs_length =
\ get(g:, 'maplist_lhs_length', get(g:, 'maplist_key_length', 11))
" n ]] *@m':call search('^\s*fu\%[nction]\>', "W")<CR>
" ^
let g:maplist_remap_length =
\ get(g:, 'maplist_remap_length', get(g:, 'maplist_noremap_length', 1))
" n ]] *@m':call search('^\s*fu\%[nction]\>', "W")<CR>
" ^
let g:maplist_local_length =
\ get(g:, 'maplist_local_length', 1)
function! s:merge(mode, lhs, remap, local, rhs, dest)
let dest = a:dest
for m in dest
if m.rhs == a:rhs && m.local == a:local && m.remap == a:remap
let mode = m.mode . a:mode
if mode =~ 'n' && mode =~ 'v' && mode =~ 'o'
let m.mode = ''
elseif mode =~ 'i' && mode =~ 'c' && mode !~ 'l'
let m.mode ='!'
else
let m.mode = ''
for mm in ['n', 'v', 'x', 's', 'o', 'i', 'c', 'l']
if mode =~ mm
let m.mode .= mm
endif
endfor
endif
return dest
endif
endfor
return add(dest, {
\ 'mode' : a:mode,
\ 'lhs' : a:lhs,
\ 'remap' : a:remap,
\ 'local' : a:local,
\ 'rhs' : a:rhs})
endfunction
function! s:compare(i1, i2)
let c1 = a:i1.mode[0]
let c2 = a:i2.mode[0]
for m in ['n', 'v', 'x', 's', 'o', 'i', 'c', 'l']
if c1 == m
return -1
elseif c2 == m
return 1
endif
endfor
return 0
endfunction
function! s:echon(msg)
let msg = a:msg
let start = 0
let idx = match(msg, '<[SCMAD]-.[^>]*>\|<[^>]\+>')
while idx >= 0
if idx > 0
echon strpart(msg, 0, idx)
endif
let end = matchend(msg, '<[SCMAD]-.[^>]*>\|<[^>]\+>')
echohl SpecialKey
echon strpart(msg, idx, end - idx)
echohl None
let msg = strpart(msg, end)
let idx = match(msg, '<[SCMAD]-.[^>]*>\|<[^>]\+>')
endwhile
echon msg
endfunction
function! s:maplist(cmd)
let save_opt = [&magic, &ignorecase]
set magic noignorecase
try
redir => out
silent execute a:cmd
redir END
let gmaps = {}
let lmaps = {}
for line in split(out, '\n')
let matches = matchlist(line, '^\(...\)\(\S\+\)\s\+\([ *&]\)\([ @]\)\(.*\)$')
let [mode, lhs, remap, local, rhs] =
\ [matches[1], matches[2], matches[3], matches[4], matches[5]]
let mode = substitute(mode, ' ', '', 'g')
let idx = copy(lhs)
" <xxx>
let matches = matchlist(idx, '\(.*\)\(<[^>]\+>\)\(.*\)')
while matches != []
execute 'let c = "\' . escape(matches[2], '\') . '"'
let idx = matches[1] . c . matches[3]
let matches = matchlist(idx, '\(.*\)\(<[^>]\+>\)\(.*\)')
endwhile
" <M-xxx>
for i in range(0xa1, 0xfe)
let lhs = substitute(lhs, nr2char(i), "<M-" . escape(nr2char(i - 0x80), '\') . ">", 'g')
endfor
" Others
let lhs = substitute(lhs, "\<M-Nul>", "<M-Nul>", 'g')
let lhs = substitute(lhs, "\<M-Tab>", "<M-Tab>", 'g')
let lhs = substitute(lhs, "\<M-NL>", "<M-NL>", 'g')
let lhs = substitute(lhs, "\<M-CR>", "<M-CR>", 'g')
" let lhs = substitute(lhs, "\<M-Esc>", "<M-Esc>", 'g')
let lhs = substitute(lhs, "\<M-\\>", " <M-\\\\>", 'g')
" let lhs = substitute(lhs, "\<M-C-Space>", "<M-C-Space>", 'g')
for i in range(0x81, 0x9f)
if i != 0x89 && i != 0x8a && i != 0x8d && i != 0x9b && i != 0x9c
let lhs = substitute(lhs, nr2char(i), "<M-C-" . escape(nr2char(i - 0x40), '\') . ">", 'g')
endif
endfor
let maps = local =~ '@' ? lmaps : gmaps
if has_key(maps, idx)
let maps[idx] = s:merge(mode, lhs, remap, local, rhs, maps[idx])
else
let maps[idx] = [{
\ 'mode' : mode,
\ 'lhs' : lhs,
\ 'remap' : remap,
\ 'local' : local,
\ 'rhs' : rhs}]
endif
endfor
for maps in [lmaps, gmaps]
for lhs in sort(keys(maps))
for m in sort(maps[lhs], 's:compare')
echon printf('%-' . g:maplist_mode_length . 's', m.mode)
call s:echon(m.lhs)
echon printf('%' . (len(m.lhs) > g:maplist_lhs_length ? 0 : g:maplist_lhs_length - len(m.lhs)) . 's', ' ')
echohl SpecialKey
echon printf('%-' . g:maplist_remap_length . 's', m.remap)
echohl None
echon printf('%-' . g:maplist_local_length . 's', m.local)
call s:echon(m.rhs)
echo ''
endfor
endfor
endfor
finally
let [&magic, &ignorecase] = save_opt
endtry
endfunction
command! -bar -bang MapList
\ call s:maplist('map<bang>')
command! -bar NMapList
\ call s:maplist('nmap')
command! -bar VMapList
\ call s:maplist('vmap')
command! -bar XMapList
\ call s:maplist('xmap')
command! -bar SMapList
\ call s:maplist('smap')
command! -bar OMapList
\ call s:maplist('omap')
command! -bar IMapList
\ call s:maplist('imap')
command! -bar CMapList
\ call s:maplist('cmap')
command! -bar LMapList
\ call s:maplist('lmap')
let &cpo = s:save_cpo
unlet s:save_cpo
@DeaR
Copy link
Author

DeaR commented May 11, 2013

<Plug>``<SNR> 等もちゃんとsort
複数モードで同一 {rhs} は纏める
<M-...> の形式で出力

@DeaR
Copy link
Author

DeaR commented May 11, 2013

長い :map-<expr> がなければ(関数化しる)

" 3のままだとnoxとかnosの時にくっついちゃう
let g:maplist_mode_length = 4
" 環境に合わせて適当に大きな数字
let g:maplist_key_length  = 20
" 1文字開ける
let g:maplist_local_length = 2

とかしとくと見やすいかも

@DeaR
Copy link
Author

DeaR commented May 11, 2013

既知の不具合
:mapの時点で<Nul>Xとして表示されてるせいでXとして扱ってしまう
上に同じく<M-Nul>も駄目
<M-Esc>はうまく置換されない~~(しかしながらキー的に要らない)~~
<M-C-Space><C- >として表示されてるせいでsplitしてしまい駄目

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment