Map some characters in the extended ASCII range

Rewrite the mapping functions and add basic support for typing accented
characters with press-and-hold type modifier keys and with keyboards
that include accented characters on their own keys.

Note that using dead keys is not possible due to the required small
timeoutlen (0).
This commit is contained in:
Kien N 2012-08-23 13:28:23 +07:00
parent b7cb2f539d
commit 1c05a664b1

View File

@ -154,22 +154,6 @@ let s:fpats = {
\ '^\S\\?$': '\\?', \ '^\S\\?$': '\\?',
\ } \ }
" Specials
let s:prtunmaps = [
\ 'PrtBS()',
\ 'PrtDelete()',
\ 'PrtDeleteWord()',
\ 'PrtClear()',
\ 'PrtCurStart()',
\ 'PrtCurEnd()',
\ 'PrtCurLeft()',
\ 'PrtCurRight()',
\ 'PrtHistory(-1)',
\ 'PrtHistory(1)',
\ 'PrtInsert("c")',
\ 'PrtInsert()',
\ ]
" Keypad " Keypad
let s:kprange = { let s:kprange = {
\ 'Plus': '+', \ 'Plus': '+',
@ -235,7 +219,8 @@ fu! s:Open()
cal s:execextvar('enter') cal s:execextvar('enter')
sil! exe 'keepa' ( s:mwbottom ? 'bo' : 'to' ) '1new ControlP' sil! exe 'keepa' ( s:mwbottom ? 'bo' : 'to' ) '1new ControlP'
cal s:buffunc(1) cal s:buffunc(1)
let [s:bufnr, s:prompt, s:winw] = [bufnr('%'), ['', '', ''], winwidth(0)] let [s:bufnr, s:winw] = [bufnr('%'), winwidth(0)]
let [s:focus, s:prompt] = [1, ['', '', '']]
abc <buffer> abc <buffer>
if !exists('s:hstry') if !exists('s:hstry')
let hst = filereadable(s:gethistloc()[1]) ? s:gethistdata() : [''] let hst = filereadable(s:gethistloc()[1]) ? s:gethistdata() : ['']
@ -517,7 +502,7 @@ fu! s:ForceUpdate()
sil! cal s:Update(join(prt, '')) sil! cal s:Update(join(prt, ''))
endf endf
fu! s:BuildPrompt(upd, ...) fu! s:BuildPrompt(upd)
let base = ( s:regexp ? 'r' : '>' ).( s:byfname ? 'd' : '>' ).'> ' let base = ( s:regexp ? 'r' : '>' ).( s:byfname ? 'd' : '>' ).'> '
let [estr, prt] = ['"\', copy(s:prompt)] let [estr, prt] = ['"\', copy(s:prompt)]
cal map(prt, 'escape(v:val, estr)') cal map(prt, 'escape(v:val, estr)')
@ -529,9 +514,9 @@ fu! s:BuildPrompt(upd, ...)
en en
sil! cal ctrlp#statusline() sil! cal ctrlp#statusline()
" Toggling " Toggling
let [hiactive, hicursor, base] = a:0 && !a:1 let [hiactive, hicursor, base] = s:focus
\ ? ['CtrlPPrtBase', 'CtrlPPrtBase', tr(base, '>', '-')] \ ? ['CtrlPPrtText', 'CtrlPPrtCursor', base]
\ : ['CtrlPPrtText', 'CtrlPPrtCursor', base] \ : ['CtrlPPrtBase', 'CtrlPPrtBase', tr(base, '>', '-')]
let hibase = 'CtrlPPrtBase' let hibase = 'CtrlPPrtBase'
" Build it " Build it
redr redr
@ -540,7 +525,7 @@ fu! s:BuildPrompt(upd, ...)
\ | echoh' hicursor '| echon "'.prt[1].'" \ | echoh' hicursor '| echon "'.prt[1].'"
\ | echoh' hiactive '| echon "'.prt[2].'" | echoh None' \ | echoh' hiactive '| echon "'.prt[2].'" | echoh None'
" Append the cursor at the end " Append the cursor at the end
if empty(prt[1]) && !( a:0 && !a:1 ) if empty(prt[1]) && s:focus
exe 'echoh' hibase '| echon "_" | echoh None' exe 'echoh' hibase '| echon "_" | echoh None'
en en
endf endf
@ -560,6 +545,7 @@ endf
" ** Prt Actions {{{1 " ** Prt Actions {{{1
" Editing {{{2 " Editing {{{2
fu! s:PrtClear() fu! s:PrtClear()
if !s:focus | retu | en
unl! s:hstgot unl! s:hstgot
let [s:prompt, s:matches] = [['', '', ''], 1] let [s:prompt, s:matches] = [['', '', ''], 1]
cal s:BuildPrompt(1) cal s:BuildPrompt(1)
@ -574,12 +560,14 @@ fu! s:PrtAdd(char)
endf endf
fu! s:PrtBS() fu! s:PrtBS()
if !s:focus | retu | en
unl! s:hstgot unl! s:hstgot
let [s:prompt[0], s:matches] = [substitute(s:prompt[0], '.$', '', ''), 1] let [s:prompt[0], s:matches] = [substitute(s:prompt[0], '.$', '', ''), 1]
cal s:BuildPrompt(1) cal s:BuildPrompt(1)
endf endf
fu! s:PrtDelete() fu! s:PrtDelete()
if !s:focus | retu | en
unl! s:hstgot unl! s:hstgot
let [prt, s:matches] = [s:prompt, 1] let [prt, s:matches] = [s:prompt, 1]
let prt[1] = matchstr(prt[2], '^.') let prt[1] = matchstr(prt[2], '^.')
@ -588,6 +576,7 @@ fu! s:PrtDelete()
endf endf
fu! s:PrtDeleteWord() fu! s:PrtDeleteWord()
if !s:focus | retu | en
unl! s:hstgot unl! s:hstgot
let [str, s:matches] = [s:prompt[0], 1] let [str, s:matches] = [s:prompt[0], 1]
let str = str =~ '\W\w\+$' ? matchstr(str, '^.\+\W\ze\w\+$') let str = str =~ '\W\w\+$' ? matchstr(str, '^.\+\W\ze\w\+$')
@ -599,6 +588,7 @@ fu! s:PrtDeleteWord()
endf endf
fu! s:PrtInsert(...) fu! s:PrtInsert(...)
if !s:focus | retu | en
let type = !a:0 ? '' : a:1 let type = !a:0 ? '' : a:1
if !a:0 if !a:0
let type = s:insertstr() let type = s:insertstr()
@ -621,6 +611,7 @@ fu! s:PrtInsert(...)
endf endf
fu! s:PrtExpandDir() fu! s:PrtExpandDir()
if !s:focus | retu | en
let str = s:prompt[0] let str = s:prompt[0]
if str =~ '\v^\@(cd|lc[hd]?|chd)\s.+' && s:spi if str =~ '\v^\@(cd|lc[hd]?|chd)\s.+' && s:spi
let hasat = split(str, '\v^\@(cd|lc[hd]?|chd)\s*\zs') let hasat = split(str, '\v^\@(cd|lc[hd]?|chd)\s*\zs')
@ -642,6 +633,7 @@ fu! s:PrtExpandDir()
endf endf
" Movement {{{2 " Movement {{{2
fu! s:PrtCurLeft() fu! s:PrtCurLeft()
if !s:focus | retu | en
let prt = s:prompt let prt = s:prompt
if !empty(prt[0]) if !empty(prt[0])
let s:prompt = [substitute(prt[0], '.$', '', ''), matchstr(prt[0], '.$'), let s:prompt = [substitute(prt[0], '.$', '', ''), matchstr(prt[0], '.$'),
@ -651,6 +643,7 @@ fu! s:PrtCurLeft()
endf endf
fu! s:PrtCurRight() fu! s:PrtCurRight()
if !s:focus | retu | en
let prt = s:prompt let prt = s:prompt
let s:prompt = [prt[0] . prt[1], matchstr(prt[2], '^.'), let s:prompt = [prt[0] . prt[1], matchstr(prt[2], '^.'),
\ substitute(prt[2], '^.', '', '')] \ substitute(prt[2], '^.', '', '')]
@ -658,12 +651,14 @@ fu! s:PrtCurRight()
endf endf
fu! s:PrtCurStart() fu! s:PrtCurStart()
if !s:focus | retu | en
let str = join(s:prompt, '') let str = join(s:prompt, '')
let s:prompt = ['', matchstr(str, '^.'), substitute(str, '^.', '', '')] let s:prompt = ['', matchstr(str, '^.'), substitute(str, '^.', '', '')]
cal s:BuildPrompt(0) cal s:BuildPrompt(0)
endf endf
fu! s:PrtCurEnd() fu! s:PrtCurEnd()
if !s:focus | retu | en
let s:prompt = [join(s:prompt, ''), '', ''] let s:prompt = [join(s:prompt, ''), '', '']
cal s:BuildPrompt(0) cal s:BuildPrompt(0)
endf endf
@ -673,33 +668,38 @@ fu! s:PrtSelectMove(dir)
let dirs = {'t': 'gg','b': 'G','j': 'j','k': 'k','u': wht.'k','d': wht.'j'} let dirs = {'t': 'gg','b': 'G','j': 'j','k': 'k','u': wht.'k','d': wht.'j'}
exe 'keepj norm!' dirs[a:dir] exe 'keepj norm!' dirs[a:dir]
if s:nolim != 1 | let s:cline = line('.') | en if s:nolim != 1 | let s:cline = line('.') | en
if line('$') > winheight(0) | cal s:BuildPrompt(0, s:Focus()) | en if line('$') > winheight(0) | cal s:BuildPrompt(0) | en
endf endf
fu! s:PrtSelectJump(char, ...) fu! s:PrtSelectJump(char)
let lines = copy(s:lines) let lines = copy(s:lines)
if a:0 if s:byfname
cal map(lines, 'split(v:val, ''[\/]\ze[^\/]\+$'')[-1]') cal map(lines, 'split(v:val, ''[\/]\ze[^\/]\+$'')[-1]')
en en
" Cycle through matches, use s:jmpchr to store last jump " Cycle through matches, use s:jmpchr to store last jump
let chr = escape(a:char, '.~') let chr = escape(matchstr(a:char, '^.'), '.~')
if match(lines, '\c^'.chr) >= 0 let smartcs = &scs && chr =~ '\u' ? '\C' : ''
if match(lines, smartcs.'^'.chr) >= 0
" If not exists or does but not for the same char " If not exists or does but not for the same char
let pos = match(lines, '\c^'.chr) let pos = match(lines, smartcs.'^'.chr)
if !exists('s:jmpchr') || ( exists('s:jmpchr') && s:jmpchr[0] != chr ) if !exists('s:jmpchr') || ( exists('s:jmpchr') && s:jmpchr[0] != chr )
let [jmpln, s:jmpchr] = [pos, [chr, pos]] let [jmpln, s:jmpchr] = [pos, [chr, pos]]
elsei exists('s:jmpchr') && s:jmpchr[0] == chr elsei exists('s:jmpchr') && s:jmpchr[0] == chr
" Start of lines " Start of lines
if s:jmpchr[1] == -1 | let s:jmpchr[1] = pos | en if s:jmpchr[1] == -1 | let s:jmpchr[1] = pos | en
let npos = match(lines, '\c^'.chr, s:jmpchr[1] + 1) let npos = match(lines, smartcs.'^'.chr, s:jmpchr[1] + 1)
let [jmpln, s:jmpchr] = [npos == -1 ? pos : npos, [chr, npos]] let [jmpln, s:jmpchr] = [npos == -1 ? pos : npos, [chr, npos]]
en en
keepj exe jmpln + 1 keepj exe jmpln + 1
if s:nolim != 1 | let s:cline = line('.') | en if s:nolim != 1 | let s:cline = line('.') | en
if line('$') > winheight(0) | cal s:BuildPrompt(0, s:Focus()) | en if line('$') > winheight(0) | cal s:BuildPrompt(0) | en
en en
endf endf
" Misc {{{2 " Misc {{{2
fu! s:PrtFocusMap(char)
cal call(( s:focus ? 's:PrtAdd' : 's:PrtSelectJump' ), [a:char])
endf
fu! s:PrtClearCache() fu! s:PrtClearCache()
if s:itemtype == 0 if s:itemtype == 0
cal ctrlp#clr() cal ctrlp#clr()
@ -736,7 +736,7 @@ fu! s:PrtExit()
endf endf
fu! s:PrtHistory(...) fu! s:PrtHistory(...)
if !s:maxhst | retu | en if !s:focus || !s:maxhst | retu | en
let [str, hst, s:matches] = [join(s:prompt, ''), s:hstry, 1] let [str, hst, s:matches] = [join(s:prompt, ''), s:hstry, 1]
" Save to history if not saved before " Save to history if not saved before
let [hst[0], hslen] = [exists('s:hstgot') ? hst[0] : str, len(hst)] let [hst[0], hslen] = [exists('s:hstgot') ? hst[0] : str, len(hst)]
@ -749,55 +749,48 @@ fu! s:PrtHistory(...)
unl s:force unl s:force
endf endf
"}}}1 "}}}1
" * MapKeys() {{{1 " * Mappings {{{1
fu! s:MapKeys(...) fu! s:MapNorms()
" Normal keys if exists('s:nmapped') && s:nmapped == s:bufnr | retu | en
let pfunc = a:0 && !a:1 ? 'PrtSelectJump' : 'PrtAdd' let pcmd = "nn \<buffer> \<silent> \<k%s> :\<c-u>cal \<SID>%s(\"%s\")\<cr>"
let dojmp = s:byfname && a:0 && !a:1 ? ', 1' : ''
let pcmd = "nn \<buffer> \<silent> \<k%s> :\<c-u>cal \<SID>%s(\"%s\"%s)\<cr>"
let cmd = substitute(pcmd, 'k%s', 'char-%d', '') let cmd = substitute(pcmd, 'k%s', 'char-%d', '')
for each in range(32, 126) let pfunc = 'PrtFocusMap'
exe printf(cmd, each, pfunc, escape(nr2char(each), '"|\'), dojmp) let ranges = [32, 33, 125, 126] + range(35, 91) + range(93, 123)
\ + range(128, 255)
for each in [34, 92, 124]
exe printf(cmd, each, pfunc, escape(nr2char(each), '"|\'))
endfo
for each in ranges
exe printf(cmd, each, pfunc, nr2char(each))
endfo endfo
for each in range(0, 9) for each in range(0, 9)
exe printf(pcmd, each, pfunc, each, dojmp) exe printf(pcmd, each, pfunc, each)
endfo endfo
for [ke, va] in items(s:kprange) for [ke, va] in items(s:kprange)
exe printf(pcmd, ke, pfunc, va, dojmp) exe printf(pcmd, ke, pfunc, va)
endfo endfo
" Special keys let s:nmapped = s:bufnr
if a:0 < 2
cal call('s:MapSpecs', a:0 && !a:1 ? [1] : [])
en
endf endf
fu! s:MapSpecs(...) fu! s:MapSpecs()
" Correct arrow keys in terminal if !( exists('s:smapped') && s:smapped == s:bufnr )
if ( has('termresponse') && v:termresponse =~ "\<ESC>" ) " Correct arrow keys in terminal
\ || &term =~? '\vxterm|<k?vt|gnome|screen|linux|ansi' if ( has('termresponse') && v:termresponse =~ "\<ESC>" )
for each in ['\A <up>','\B <down>','\C <right>','\D <left>'] \ || &term =~? '\vxterm|<k?vt|gnome|screen|linux|ansi'
exe s:lcmap.' <esc>['.each for each in ['\A <up>','\B <down>','\C <right>','\D <left>']
endfo exe s:lcmap.' <esc>['.each
en endfo
if a:0 en
for ke in s:prtunmaps | for kp in s:prtmaps[ke]
exe s:lcmap kp '<Nop>'
endfo | endfo
el
for [ke, va] in items(s:prtmaps) | for kp in va
exe s:lcmap kp ':<c-u>cal <SID>'.ke.'<cr>'
endfo | endfo
en en
for [ke, va] in items(s:prtmaps) | for kp in va
exe s:lcmap kp ':<c-u>cal <SID>'.ke.'<cr>'
endfo | endfo
let s:smapped = s:bufnr
endf endf
" * Toggling {{{1 " * Toggling {{{1
fu! s:Focus()
retu !exists('s:focus') ? 1 : s:focus
endf
fu! s:ToggleFocus() fu! s:ToggleFocus()
let s:focus = !exists('s:focus') || s:focus ? 0 : 1 let s:focus = s:focus ? 0 : 1
cal s:MapKeys(s:focus) cal s:BuildPrompt(0)
cal s:BuildPrompt(0, s:focus)
endf endf
fu! s:ToggleRegex() fu! s:ToggleRegex()
@ -809,7 +802,6 @@ fu! s:ToggleByFname()
if s:ispath if s:ispath
let s:byfname = s:byfname ? 0 : 1 let s:byfname = s:byfname ? 0 : 1
let s:mfunc = s:mfunc() let s:mfunc = s:mfunc()
cal s:MapKeys(s:Focus(), 1)
cal s:PrtSwitcher() cal s:PrtSwitcher()
en en
endf endf
@ -824,7 +816,7 @@ endf
fu! s:PrtSwitcher() fu! s:PrtSwitcher()
let [s:force, s:matches] = [1, 1] let [s:force, s:matches] = [1, 1]
cal s:BuildPrompt(1, s:Focus()) cal s:BuildPrompt(1)
unl s:force unl s:force
endf endf
" - SetWD() {{{1 " - SetWD() {{{1
@ -1204,7 +1196,7 @@ fu! ctrlp#statusline()
let nxt = tps[s:walker(max, s:itemtype, 1)][1] let nxt = tps[s:walker(max, s:itemtype, 1)][1]
let prv = tps[s:walker(max, s:itemtype, -1)][1] let prv = tps[s:walker(max, s:itemtype, -1)][1]
let s:ctype = tps[s:itemtype][0] let s:ctype = tps[s:itemtype][0]
let focus = s:Focus() ? 'prt' : 'win' let focus = s:focus ? 'prt' : 'win'
let byfname = s:byfname ? 'file' : 'path' let byfname = s:byfname ? 'file' : 'path'
let marked = s:opmul != '0' ? let marked = s:opmul != '0' ?
\ exists('s:marked') ? ' <'.s:dismrk().'>' : ' <->' : '' \ exists('s:marked') ? ' <'.s:dismrk().'>' : ' <->' : ''
@ -1943,7 +1935,8 @@ fu! ctrlp#init(type, ...)
cal ctrlp#reset() cal ctrlp#reset()
noa cal s:Open() noa cal s:Open()
cal s:SetWD(a:0 ? a:1 : {}) cal s:SetWD(a:0 ? a:1 : {})
cal s:MapKeys() cal s:MapNorms()
cal s:MapSpecs()
cal ctrlp#syntax() cal ctrlp#syntax()
cal ctrlp#setlines(s:settype(a:type)) cal ctrlp#setlines(s:settype(a:type))
cal s:SetDefTxt() cal s:SetDefTxt()