Fixed vim and zsh
This commit is contained in:
1629
vim/plugins/vim-easymotion/autoload/EasyMotion.vim
Normal file
1629
vim/plugins/vim-easymotion/autoload/EasyMotion.vim
Normal file
File diff suppressed because it is too large
Load Diff
117
vim/plugins/vim-easymotion/autoload/EasyMotion/cmigemo.vim
Normal file
117
vim/plugins/vim-easymotion/autoload/EasyMotion/cmigemo.vim
Normal file
@ -0,0 +1,117 @@
|
||||
"=============================================================================
|
||||
" FILE: autoload/EasyMotion/cmigemo.vim
|
||||
" AUTHOR: haya14busa
|
||||
" License: MIT license {{{
|
||||
" 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.
|
||||
" }}}
|
||||
"=============================================================================
|
||||
scriptencoding utf-8
|
||||
" Saving 'cpoptions' {{{
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
" }}}
|
||||
|
||||
function! s:has_vimproc() "{{{
|
||||
if !exists('s:exists_vimproc')
|
||||
try
|
||||
silent call vimproc#version()
|
||||
let s:exists_vimproc = 1
|
||||
catch
|
||||
let s:exists_vimproc = 0
|
||||
endtry
|
||||
endif
|
||||
|
||||
return s:exists_vimproc
|
||||
endfunction "}}}
|
||||
|
||||
function! EasyMotion#cmigemo#system(...) "{{{
|
||||
return call(s:has_vimproc() ? 'vimproc#system' : 'system', a:000)
|
||||
endfunction "}}}
|
||||
|
||||
function! s:SearchDict2(name) "{{{
|
||||
let path = $VIM . ',' . &runtimepath
|
||||
let dict = globpath(path, "dict/".a:name)
|
||||
if dict == ''
|
||||
let dict = globpath(path, a:name)
|
||||
endif
|
||||
if dict == ''
|
||||
for path in [
|
||||
\ '/usr/local/share/migemo/',
|
||||
\ '/usr/local/share/cmigemo/',
|
||||
\ '/usr/local/share/',
|
||||
\ '/usr/share/cmigemo/',
|
||||
\ '/usr/share/',
|
||||
\ ]
|
||||
let path = path . a:name
|
||||
if filereadable(path)
|
||||
let dict = path
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
let dict = matchstr(dict, "^[^\<NL>]*")
|
||||
return dict
|
||||
endfunction "}}}
|
||||
|
||||
function! s:SearchDict() "{{{
|
||||
for path in [
|
||||
\ 'migemo/'.&encoding.'/migemo-dict',
|
||||
\ &encoding.'/migemo-dict',
|
||||
\ 'migemo-dict',
|
||||
\ ]
|
||||
let dict = s:SearchDict2(path)
|
||||
if dict != ''
|
||||
return dict
|
||||
endif
|
||||
endfor
|
||||
echoerr 'a dictionary for migemo is not found'
|
||||
echoerr 'your encoding is '.&encoding
|
||||
endfunction "}}}
|
||||
|
||||
function! EasyMotion#cmigemo#getMigemoPattern(input) "{{{
|
||||
if !exists('s:migemodict')
|
||||
let s:migemodict = s:SearchDict()
|
||||
endif
|
||||
|
||||
if has('migemo')
|
||||
" Use migemo().
|
||||
if &migemodict !=# ''
|
||||
return migemo(a:input)
|
||||
endif
|
||||
let &migemodict = s:migemodict
|
||||
try
|
||||
return migemo(a:input)
|
||||
finally
|
||||
let &migemodict = ''
|
||||
endtry
|
||||
elseif executable('cmigemo')
|
||||
" Use cmigemo.
|
||||
return EasyMotion#cmigemo#system('cmigemo -v -w "'.a:input.'" -d "'.s:migemodict.'"')
|
||||
else
|
||||
" Not supported
|
||||
return a:input
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
" Restore 'cpoptions' {{{
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
" }}}
|
||||
" vim: fdm=marker:et:ts=4:sw=4:sts=4
|
283
vim/plugins/vim-easymotion/autoload/EasyMotion/command_line.vim
Normal file
283
vim/plugins/vim-easymotion/autoload/EasyMotion/command_line.vim
Normal file
@ -0,0 +1,283 @@
|
||||
"=============================================================================
|
||||
" FILE: autoload/EasyMotion/command_line.vim
|
||||
" AUTHOR: haya14busa
|
||||
" Reference: https://github.com/osyo-manga/vim-over
|
||||
" License: MIT license {{{
|
||||
" 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.
|
||||
" }}}
|
||||
"=============================================================================
|
||||
scriptencoding utf-8
|
||||
" Saving 'cpoptions' {{{
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
" }}}
|
||||
|
||||
" CommandLine:
|
||||
let s:V = vital#easymotion#new()
|
||||
let s:cmdline = s:V.import('Over.Commandline.Base')
|
||||
let s:modules = s:V.import("Over.Commandline.Modules")
|
||||
let s:search = s:cmdline.make()
|
||||
let s:search.highlights.prompt = 'Question'
|
||||
|
||||
" Add Module: {{{
|
||||
call s:search.connect('Exit')
|
||||
call s:search.connect('Cancel')
|
||||
call s:search.connect('Redraw')
|
||||
call s:search.connect('DrawCommandline')
|
||||
call s:search.connect('Delete')
|
||||
call s:search.connect('CursorMove')
|
||||
call s:search.connect('Paste')
|
||||
call s:search.connect('BufferComplete')
|
||||
call s:search.connect('InsertRegister')
|
||||
call s:search.connect('ExceptionExit')
|
||||
call s:search.connect(s:modules.get('ExceptionMessage').make('EasyMotion: ', 'echom'))
|
||||
call s:search.connect(s:modules.get('History').make('/'))
|
||||
call s:search.connect(s:modules.get('NoInsert').make_special_chars())
|
||||
call s:search.connect(s:modules.get('KeyMapping').make_emacs())
|
||||
call s:search.connect(s:modules.get('Doautocmd').make('EMCommandLine'))
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "EasyMotion",
|
||||
\}
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if a:cmdline.is_input("<Over>(em-scroll-f)")
|
||||
call s:scroll(0)
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("<Over>(em-scroll-b)")
|
||||
call s:scroll(1)
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("<Over>(em-jumpback)")
|
||||
keepjumps call setpos('.', s:save_orig_pos)
|
||||
let s:orig_pos = s:save_orig_pos
|
||||
let s:orig_line_start = getpos('w0')
|
||||
let s:orig_line_end = getpos('w$')
|
||||
let s:direction = s:save_direction
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("<Over>(em-openallfold)")
|
||||
" TODO: better solution
|
||||
normal! zR
|
||||
call a:cmdline.setchar('')
|
||||
endif
|
||||
endfunction
|
||||
call s:search.connect(s:module)
|
||||
"}}}
|
||||
|
||||
" CommandLine Keymap: {{{
|
||||
" .keymapping() won't be remapped by user defined KeyMappings.
|
||||
function! s:search.keymapping() "{{{
|
||||
return {
|
||||
\ "\<CR>" : {
|
||||
\ "key" : "<Over>(exit)",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ }
|
||||
endfunction "}}}
|
||||
|
||||
call s:search.cnoremap("\<C-l>", '<Over>(buffer-complete)')
|
||||
call s:search.cnoremap("\<Tab>", '<Over>(em-scroll-f)')
|
||||
call s:search.cnoremap("\<S-Tab>", '<Over>(em-scroll-b)')
|
||||
call s:search.cnoremap("\<C-o>", '<Over>(em-jumpback)')
|
||||
call s:search.cnoremap("\<C-z>", '<Over>(em-openallfold)')
|
||||
|
||||
" Fins Motion CommandLine Mapping Command: {{{
|
||||
function! EasyMotion#command_line#cmap(args)
|
||||
let lhs = s:as_keymapping(a:args[0])
|
||||
let rhs = s:as_keymapping(a:args[1])
|
||||
call s:search.cmap(lhs, rhs)
|
||||
endfunction
|
||||
function! EasyMotion#command_line#cnoremap(args)
|
||||
let lhs = s:as_keymapping(a:args[0])
|
||||
let rhs = s:as_keymapping(a:args[1])
|
||||
call s:search.cnoremap(lhs, rhs)
|
||||
endfunction
|
||||
function! EasyMotion#command_line#cunmap(lhs)
|
||||
let lhs = s:as_keymapping(a:lhs)
|
||||
call s:search.cunmap(lhs)
|
||||
endfunction
|
||||
function! s:as_keymapping(key)
|
||||
execute 'let result = "' . substitute(a:key, '\(<.\{-}>\)', '\\\1', 'g') . '"'
|
||||
return result
|
||||
endfunction
|
||||
"}}}
|
||||
"}}}
|
||||
|
||||
" Event: {{{
|
||||
function! s:search.on_enter(cmdline) "{{{
|
||||
if s:num_strokes == -1
|
||||
call EasyMotion#highlight#delete_highlight()
|
||||
call EasyMotion#helper#VarReset('&scrolloff', 0)
|
||||
if g:EasyMotion_do_shade
|
||||
call EasyMotion#highlight#add_highlight('\_.*',
|
||||
\ g:EasyMotion_hl_group_shade)
|
||||
endif
|
||||
endif
|
||||
if g:EasyMotion_cursor_highlight
|
||||
call EasyMotion#highlight#add_highlight('\%#',
|
||||
\ g:EasyMotion_hl_inc_cursor)
|
||||
endif
|
||||
endfunction "}}}
|
||||
function! s:search.on_leave(cmdline) "{{{
|
||||
if s:num_strokes == -1
|
||||
call EasyMotion#highlight#delete_highlight(g:EasyMotion_hl_inc_search)
|
||||
if g:EasyMotion_do_shade
|
||||
call EasyMotion#highlight#delete_highlight(g:EasyMotion_hl_group_shade)
|
||||
endif
|
||||
endif
|
||||
if g:EasyMotion_cursor_highlight
|
||||
call EasyMotion#highlight#delete_highlight(g:EasyMotion_hl_inc_cursor)
|
||||
endif
|
||||
endfunction "}}}
|
||||
function! s:search.on_char(cmdline) "{{{
|
||||
if s:num_strokes == -1
|
||||
let re = s:search.getline()
|
||||
if EasyMotion#helper#should_case_sensitive(re, 1)
|
||||
let case_flag = '\c'
|
||||
else
|
||||
let case_flag = '\C'
|
||||
endif
|
||||
let re .= case_flag
|
||||
if g:EasyMotion_inc_highlight
|
||||
call s:inc_highlight(re)
|
||||
endif
|
||||
if g:EasyMotion_off_screen_search
|
||||
call s:off_screen_search(re)
|
||||
endif
|
||||
elseif s:search.line.length() >= s:num_strokes
|
||||
call s:search.exit()
|
||||
endif
|
||||
endfunction "}}}
|
||||
"}}}
|
||||
|
||||
" Main:
|
||||
function! EasyMotion#command_line#GetInput(num_strokes, prev, direction) "{{{
|
||||
let s:num_strokes = a:num_strokes
|
||||
|
||||
let s:prompt_base = s:getPromptMessage(a:num_strokes)
|
||||
call s:search.set_prompt(s:prompt_base)
|
||||
|
||||
" Screen: cursor position, first and last line
|
||||
let s:orig_pos = getpos('.')
|
||||
let s:orig_line_start = getpos('w0')
|
||||
let s:orig_line_end = getpos('w$')
|
||||
let s:save_orig_pos = deepcopy(s:orig_pos)
|
||||
|
||||
" Direction:
|
||||
let s:direction = a:direction == 1 ? 'b' : ''
|
||||
let s:save_direction = deepcopy(s:direction)
|
||||
|
||||
let input = s:search.get()
|
||||
if input == '' && ! s:search.exit_code()
|
||||
return a:prev
|
||||
elseif s:search.exit_code() == 1 || s:search.exit_code() == -1
|
||||
call s:Cancell()
|
||||
return ''
|
||||
else
|
||||
return input
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
" Helper:
|
||||
function! s:Cancell() " {{{
|
||||
call EasyMotion#highlight#delete_highlight()
|
||||
call EasyMotion#helper#VarReset('&scrolloff')
|
||||
keepjumps call setpos('.', s:save_orig_pos)
|
||||
if g:EasyMotion_verbose
|
||||
echo 'EasyMotion: Cancelled'
|
||||
endif
|
||||
return ''
|
||||
endfunction " }}}
|
||||
function! s:getPromptMessage(num_strokes) "{{{
|
||||
if a:num_strokes == 1
|
||||
let prompt = substitute(
|
||||
\ substitute(g:EasyMotion_prompt,'{n}', a:num_strokes, 'g'),
|
||||
\ '(s)', '', 'g')
|
||||
elseif a:num_strokes == -1
|
||||
let prompt = substitute(
|
||||
\ substitute(g:EasyMotion_prompt, '{n}\s\{0,1}', '', 'g'),
|
||||
\ '(s)', 's', 'g')
|
||||
else
|
||||
let prompt = substitute(
|
||||
\ substitute(g:EasyMotion_prompt,'{n}', a:num_strokes, 'g'),
|
||||
\ '(s)', 's', 'g')
|
||||
endif
|
||||
return prompt
|
||||
endfunction "}}}
|
||||
|
||||
function! s:off_screen_search(re) "{{{
|
||||
" First: search within visible screen range
|
||||
call s:adjust_screen()
|
||||
" Error occur when '\zs' without '!'
|
||||
silent! let pos = searchpos(a:re, s:direction . 'n', s:orig_line_end[1])
|
||||
if pos != [0, 0]
|
||||
" Restore cursor posision
|
||||
keepjumps call setpos('.', s:orig_pos)
|
||||
else
|
||||
" Second: if there were no much, search off screen
|
||||
silent! let pos = searchpos(a:re, s:direction)
|
||||
if pos != [0, 0]
|
||||
" Match
|
||||
keepjumps call setpos('.', pos)
|
||||
" Move cursor
|
||||
if s:save_direction != 'b'
|
||||
normal! zzH0
|
||||
else
|
||||
normal! zzL0
|
||||
endif
|
||||
else
|
||||
" No much
|
||||
call s:adjust_screen()
|
||||
keepjumps call setpos('.', s:orig_pos)
|
||||
endif
|
||||
endif
|
||||
" redraw
|
||||
endfunction "}}}
|
||||
function! s:adjust_screen() "{{{
|
||||
if s:save_direction != 'b'
|
||||
" Forward
|
||||
keepjumps call setpos('.', s:orig_line_start)
|
||||
normal! zt
|
||||
else
|
||||
" Backward
|
||||
keepjumps call setpos('.', s:orig_line_end)
|
||||
normal! zb
|
||||
endif
|
||||
endfunction "}}}
|
||||
function! s:scroll(direction) "{{{
|
||||
" direction: 0 -> forward, 1 -> backward
|
||||
exec a:direction == 0 ? "normal! \<C-f>" : "normal! \<C-b>"
|
||||
let s:orig_pos = getpos('.')
|
||||
let s:orig_line_start = getpos('w0')
|
||||
let s:orig_line_end = getpos('w$')
|
||||
let s:direction = a:direction == 0 ? '' : 'b'
|
||||
endfunction "}}}
|
||||
function! s:inc_highlight(re) "{{{
|
||||
call EasyMotion#highlight#delete_highlight(g:EasyMotion_hl_inc_search)
|
||||
if s:search.line.length() > 0
|
||||
" Error occur when '\zs' without '!'
|
||||
silent! call EasyMotion#highlight#add_highlight(a:re, g:EasyMotion_hl_inc_search)
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
" Restore 'cpoptions' {{{
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
" }}}
|
||||
" vim: fdm=marker:et:ts=4:sw=4:sts=4
|
185
vim/plugins/vim-easymotion/autoload/EasyMotion/helper.vim
Normal file
185
vim/plugins/vim-easymotion/autoload/EasyMotion/helper.vim
Normal file
@ -0,0 +1,185 @@
|
||||
"=============================================================================
|
||||
" FILE: autoload/EasyMotion/helper.vim
|
||||
" AUTHOR: haya14busa
|
||||
" License: MIT license {{{
|
||||
" 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.
|
||||
" }}}
|
||||
"=============================================================================
|
||||
scriptencoding utf-8
|
||||
" Saving 'cpoptions' {{{
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
" }}}
|
||||
|
||||
function! EasyMotion#helper#mode(flag) "{{{
|
||||
return mode(a:flag) == "\<C-v>" ? "C-v" : mode(a:flag)
|
||||
endfunction "}}}
|
||||
|
||||
function! EasyMotion#helper#get_char_by_coord(coord) "{{{
|
||||
" @param coord: [lnum, col] or [bufnum, lnum, col, off]
|
||||
if len(a:coord) == 4
|
||||
let [line_num, col_num] = [a:coord[1], a:coord[2]]
|
||||
else
|
||||
let [line_num, col_num] = a:coord
|
||||
endif
|
||||
let target_col_regexp = '\%' . (col_num) . 'c.'
|
||||
return matchstr(getline(line_num), target_col_regexp)
|
||||
endfunction "}}}
|
||||
|
||||
function! EasyMotion#helper#is_greater_coords(coords1, coords2) "{{{
|
||||
" [line_num, col_num] < [line_num, col_num]
|
||||
"
|
||||
" coords1 < coords2 : return 1
|
||||
" coords1 > coords2 : return -1
|
||||
" coords1 == coords2 : return 0
|
||||
if a:coords1 == a:coords2 | return 0 | endif
|
||||
|
||||
if a:coords1[0] < a:coords2[0]
|
||||
return 1
|
||||
elseif a:coords1[0] > a:coords2[0]
|
||||
return -1
|
||||
endif
|
||||
|
||||
" Same line
|
||||
if a:coords1[1] < a:coords2[1]
|
||||
return 1
|
||||
elseif a:coords1[1] > a:coords2[1]
|
||||
return -1
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
function! EasyMotion#helper#is_folded(line) "{{{
|
||||
" Return false if g:EasyMotion_skipfoldedline == 1
|
||||
" and line is start of folded lines
|
||||
let _foldclosed = foldclosed(a:line)
|
||||
return _foldclosed != -1 &&
|
||||
\ (g:EasyMotion_skipfoldedline == 1 || a:line != _foldclosed)
|
||||
endfunction "}}}
|
||||
function! EasyMotion#helper#should_case_sensitive(input, is_search) "{{{
|
||||
if !a:is_search
|
||||
if g:EasyMotion_smartcase == 0
|
||||
return 0
|
||||
else
|
||||
" return 1 if input didn't match uppercase letter
|
||||
return match(a:input, '\u') == -1
|
||||
endif
|
||||
endif
|
||||
|
||||
if (g:EasyMotion_smartcase == 1 && match(a:input, '\u') == -1) ||
|
||||
\ (&ignorecase && &smartcase && match(a:input, '\u') == -1) ||
|
||||
\ (&ignorecase && !&smartcase)
|
||||
return 1
|
||||
endif
|
||||
return 0
|
||||
endfunction "}}}
|
||||
function! EasyMotion#helper#silent_feedkeys(expr, name, ...) "{{{
|
||||
" Ref:
|
||||
" https://github.com/osyo-manga/vim-over/blob/d51b028c29661d4a5f5b79438ad6d69266753711/autoload/over.vim#L6
|
||||
let mode = get(a:, 1, "m")
|
||||
let name = "easymotion-" . a:name
|
||||
let map = printf("<Plug>(%s)", name)
|
||||
if mode == "n"
|
||||
let command = "nnoremap"
|
||||
else
|
||||
let command = "nmap"
|
||||
endif
|
||||
execute command "<silent>" map printf("%s:nunmap %s<CR>", a:expr, map)
|
||||
if mode(1) !=# 'ce'
|
||||
" FIXME: mode(1) !=# 'ce' exists only for the test
|
||||
" :h feedkeys() doesn't work while runnning a test script
|
||||
" https://github.com/kana/vim-vspec/issues/27
|
||||
call feedkeys(printf("\<Plug>(%s)", name))
|
||||
endif
|
||||
endfunction "}}}
|
||||
function! EasyMotion#helper#VarReset(var, ...) "{{{
|
||||
if ! exists('s:var_reset')
|
||||
let s:var_reset = {}
|
||||
endif
|
||||
|
||||
if a:0 == 0 && has_key(s:var_reset, a:var)
|
||||
" Reset var to original value
|
||||
" setbufvar( or bufname): '' or '%' can be used for the current buffer
|
||||
call setbufvar('%', a:var, s:var_reset[a:var])
|
||||
elseif a:0 == 1
|
||||
" Save original value and set new var value
|
||||
|
||||
let new_value = a:0 == 1 ? a:1 : ''
|
||||
|
||||
" Store original value
|
||||
let s:var_reset[a:var] = getbufvar("", a:var)
|
||||
|
||||
" Set new var value
|
||||
call setbufvar('%', a:var, new_value)
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
" Migemo {{{
|
||||
function! EasyMotion#helper#load_migemo_dict() "{{{
|
||||
let enc = &l:encoding
|
||||
if enc ==# 'utf-8'
|
||||
return EasyMotion#migemo#utf8#load_dict()
|
||||
elseif enc ==# 'cp932'
|
||||
return EasyMotion#migemo#cp932#load_dict()
|
||||
elseif enc ==# 'euc-jp'
|
||||
return EasyMotion#migemo#eucjp#load_dict()
|
||||
else
|
||||
let g:EasyMotion_use_migemo = 0
|
||||
throw "Error: ".enc." is not supported. Migemo is made disabled."
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
" EasyMotion#helper#strchars() {{{
|
||||
if exists('*strchars')
|
||||
function! EasyMotion#helper#strchars(str)
|
||||
return strchars(a:str)
|
||||
endfunction
|
||||
else
|
||||
function! EasyMotion#helper#strchars(str)
|
||||
return strlen(substitute(a:str, ".", "x", "g"))
|
||||
endfunction
|
||||
endif "}}}
|
||||
function! EasyMotion#helper#include_multibyte_char(str) "{{{
|
||||
return strlen(a:str) != EasyMotion#helper#strchars(a:str)
|
||||
endfunction "}}}
|
||||
|
||||
function! EasyMotion#helper#vcol(expr) abort
|
||||
let col_num = col(a:expr)
|
||||
let line = getline(a:expr)
|
||||
let before_line = col_num > 2 ? line[: col_num - 2]
|
||||
\ : col_num is# 2 ? line[0]
|
||||
\ : ''
|
||||
let vcol_num = 1
|
||||
for c in split(before_line, '\zs')
|
||||
let vcol_num += c is# "\t" ? s:_virtual_tab2spacelen(vcol_num) : len(c)
|
||||
endfor
|
||||
return vcol_num
|
||||
endfunction
|
||||
|
||||
function! s:_virtual_tab2spacelen(col_num) abort
|
||||
return &tabstop - ((a:col_num - 1) % &tabstop)
|
||||
endfunction
|
||||
|
||||
"}}}
|
||||
|
||||
" Restore 'cpoptions' {{{
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
" }}}
|
||||
" vim: fdm=marker:et:ts=4:sw=4:sts=4
|
251
vim/plugins/vim-easymotion/autoload/EasyMotion/highlight.vim
Normal file
251
vim/plugins/vim-easymotion/autoload/EasyMotion/highlight.vim
Normal file
@ -0,0 +1,251 @@
|
||||
"=============================================================================
|
||||
" FILE: highlight.vim
|
||||
" AUTHOR: haya14busa
|
||||
" Reference: https://github.com/t9md/vim-smalls
|
||||
" License: MIT license {{{
|
||||
" 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.
|
||||
" }}}
|
||||
"=============================================================================
|
||||
scriptencoding utf-8
|
||||
" Saving 'cpoptions' {{{
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
" }}}
|
||||
|
||||
function! EasyMotion#highlight#load()
|
||||
"load
|
||||
endfunction
|
||||
|
||||
" -- Default highlighting ---------------- {{{
|
||||
let g:EasyMotion_hl_group_target = get(g:,
|
||||
\ 'EasyMotion_hl_group_target', 'EasyMotionTarget')
|
||||
let g:EasyMotion_hl2_first_group_target = get(g:,
|
||||
\ 'EasyMotion_hl2_first_group_target', 'EasyMotionTarget2First')
|
||||
let g:EasyMotion_hl2_second_group_target = get(g:,
|
||||
\ 'EasyMotion_hl2_second_group_target', 'EasyMotionTarget2Second')
|
||||
let g:EasyMotion_hl_group_shade = get(g:,
|
||||
\ 'EasyMotion_hl_group_shade', 'EasyMotionShade')
|
||||
|
||||
let g:EasyMotion_hl_inc_search = get(g:,
|
||||
\ 'EasyMotion_hl_inc_search', 'EasyMotionIncSearch')
|
||||
let g:EasyMotion_hl_inc_cursor = get(g:,
|
||||
\ 'EasyMotion_hl_inc_cursor', 'EasyMotionIncCursor')
|
||||
let g:EasyMotion_hl_move = get(g:,
|
||||
\ 'EasyMotion_hl_move', 'EasyMotionMoveHL')
|
||||
|
||||
let s:target_hl_defaults = {
|
||||
\ 'gui' : ['NONE', '#ff0000' , 'bold']
|
||||
\ , 'cterm256': ['NONE', '196' , 'bold']
|
||||
\ , 'cterm' : ['NONE', 'red' , 'bold']
|
||||
\ }
|
||||
|
||||
let s:target_hl2_first_defaults = {
|
||||
\ 'gui' : ['NONE', '#ffb400' , 'bold']
|
||||
\ , 'cterm256': ['NONE', '11' , 'bold']
|
||||
\ , 'cterm' : ['NONE', 'yellow' , 'bold']
|
||||
\ }
|
||||
|
||||
let s:target_hl2_second_defaults = {
|
||||
\ 'gui' : ['NONE', '#b98300' , 'bold']
|
||||
\ , 'cterm256': ['NONE', '3' , 'bold']
|
||||
\ , 'cterm' : ['NONE', 'yellow' , 'bold']
|
||||
\ }
|
||||
|
||||
let s:shade_hl_defaults = {
|
||||
\ 'gui' : ['NONE', '#777777' , 'NONE']
|
||||
\ , 'cterm256': ['NONE', '242' , 'NONE']
|
||||
\ , 'cterm' : ['NONE', 'grey' , 'NONE']
|
||||
\ }
|
||||
|
||||
let s:shade_hl_line_defaults = {
|
||||
\ 'gui' : ['red' , '#FFFFFF' , 'NONE']
|
||||
\ , 'cterm256': ['red' , '242' , 'NONE']
|
||||
\ , 'cterm' : ['red' , 'grey' , 'NONE']
|
||||
\ }
|
||||
|
||||
let s:target_hl_inc = {
|
||||
\ 'gui' : ['NONE', '#7fbf00' , 'bold']
|
||||
\ , 'cterm256': ['NONE', '40' , 'bold']
|
||||
\ , 'cterm' : ['NONE', 'green' , 'bold']
|
||||
\ }
|
||||
let s:target_hl_inc_cursor = {
|
||||
\ 'gui' : ['#ACDBDA', '#121813' , 'bold']
|
||||
\ , 'cterm256': ['cyan' , '232' , 'bold']
|
||||
\ , 'cterm' : ['cyan' , 'black' , 'bold']
|
||||
\ }
|
||||
let s:target_hl_move = {
|
||||
\ 'gui' : ['#7fbf00', '#121813' , 'bold']
|
||||
\ , 'cterm256': ['green' , '15' , 'bold']
|
||||
\ , 'cterm' : ['green' , 'white' , 'bold']
|
||||
\ }
|
||||
" }}}
|
||||
function! EasyMotion#highlight#InitHL(group, colors) " {{{
|
||||
let group_default = a:group . 'Default'
|
||||
|
||||
" Prepare highlighting variables
|
||||
let guihl = printf('guibg=%s guifg=%s gui=%s', a:colors.gui[0], a:colors.gui[1], a:colors.gui[2])
|
||||
let ctermhl = &t_Co == 256
|
||||
\ ? printf('ctermbg=%s ctermfg=%s cterm=%s', a:colors.cterm256[0], a:colors.cterm256[1], a:colors.cterm256[2])
|
||||
\ : printf('ctermbg=%s ctermfg=%s cterm=%s', a:colors.cterm[0], a:colors.cterm[1], a:colors.cterm[2])
|
||||
|
||||
" Create default highlighting group
|
||||
execute printf('hi default %s %s %s', group_default, guihl, ctermhl)
|
||||
|
||||
" Check if the hl group exists
|
||||
if hlexists(a:group)
|
||||
redir => hlstatus | exec 'silent hi ' . a:group | redir END
|
||||
|
||||
" Return if the group isn't cleared
|
||||
if hlstatus !~ 'cleared'
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
||||
" No colors are defined for this group, link to defaults
|
||||
execute printf('hi default link %s %s', a:group, group_default)
|
||||
endfunction " }}}
|
||||
function! EasyMotion#highlight#init() "{{{
|
||||
call EasyMotion#highlight#InitHL(g:EasyMotion_hl_group_target, s:target_hl_defaults)
|
||||
call EasyMotion#highlight#InitHL(g:EasyMotion_hl2_first_group_target, s:target_hl2_first_defaults)
|
||||
call EasyMotion#highlight#InitHL(g:EasyMotion_hl2_second_group_target, s:target_hl2_second_defaults)
|
||||
call EasyMotion#highlight#InitHL(g:EasyMotion_hl_group_shade, s:shade_hl_defaults)
|
||||
call EasyMotion#highlight#InitHL(g:EasyMotion_hl_inc_search, s:target_hl_inc)
|
||||
call EasyMotion#highlight#InitHL(g:EasyMotion_hl_inc_cursor, s:target_hl_inc_cursor)
|
||||
call EasyMotion#highlight#InitHL(g:EasyMotion_hl_move, s:target_hl_move)
|
||||
if exists(':CSApprox') == 2 && g:EasyMotion_force_csapprox
|
||||
"TODO: better solution or remove completly
|
||||
CSApprox!
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
" Reset highlighting after loading a new color scheme {{{
|
||||
augroup EasyMotionInitHL
|
||||
autocmd!
|
||||
autocmd ColorScheme * call EasyMotion#highlight#init()
|
||||
augroup end
|
||||
" }}}
|
||||
|
||||
call EasyMotion#highlight#init()
|
||||
" Init: {{{
|
||||
let s:h = {}
|
||||
let s:h.ids = {}
|
||||
let s:priorities = {
|
||||
\ g:EasyMotion_hl_group_target : 100,
|
||||
\ g:EasyMotion_hl2_first_group_target : 100,
|
||||
\ g:EasyMotion_hl2_second_group_target : 100,
|
||||
\ g:EasyMotion_hl_group_shade : 0,
|
||||
\ g:EasyMotion_hl_inc_search : 1,
|
||||
\ g:EasyMotion_hl_inc_cursor : 2,
|
||||
\ g:EasyMotion_hl_move : 0,
|
||||
\ }
|
||||
for s:group in keys(s:priorities)
|
||||
let s:h.ids[s:group] = []
|
||||
endfor
|
||||
unlet s:group
|
||||
"}}}
|
||||
|
||||
function! EasyMotion#highlight#delete_highlight(...) "{{{
|
||||
let groups = !empty(a:000) ? a:000 : keys(s:priorities)
|
||||
for group in groups
|
||||
for id in s:h.ids[group]
|
||||
silent! call matchdelete(id)
|
||||
endfor
|
||||
let s:h.ids[group] = []
|
||||
endfor
|
||||
endfunction "}}}
|
||||
function! EasyMotion#highlight#add_highlight(re, group) "{{{
|
||||
call add(s:h.ids[a:group], matchadd(a:group, a:re, s:priorities[a:group]))
|
||||
endfunction "}}}
|
||||
function! EasyMotion#highlight#add_pos_highlight(line_num, col_num, group) "{{{
|
||||
call add(s:h.ids[a:group], matchaddpos(a:group, [[a:line_num, a:col_num]], s:priorities[a:group]))
|
||||
endfunction "}}}
|
||||
function! EasyMotion#highlight#attach_autocmd() "{{{
|
||||
" Reference: https://github.com/justinmk/vim-sneak
|
||||
augroup plugin-easymotion
|
||||
autocmd!
|
||||
autocmd InsertEnter,WinLeave,BufLeave <buffer>
|
||||
\ silent! call EasyMotion#highlight#delete_highlight()
|
||||
\ | autocmd! plugin-easymotion * <buffer>
|
||||
autocmd CursorMoved <buffer>
|
||||
\ autocmd plugin-easymotion CursorMoved <buffer>
|
||||
\ silent! call EasyMotion#highlight#delete_highlight()
|
||||
\ | autocmd! plugin-easymotion * <buffer>
|
||||
augroup END
|
||||
endfunction "}}}
|
||||
function! EasyMotion#highlight#add_color_group(new_groups) "{{{
|
||||
let s:priorities = extend(deepcopy(s:priorities), a:new_groups)
|
||||
for group in keys(a:new_groups)
|
||||
let s:h.ids[group] = []
|
||||
endfor
|
||||
endfunction "}}}
|
||||
|
||||
function! EasyMotion#highlight#capture(hlname) "{{{
|
||||
" Based On: https://github.com/t9md/vim-ezbar
|
||||
" https://github.com/osyo-manga/vital-over
|
||||
let hlname = a:hlname
|
||||
if !hlexists(hlname)
|
||||
return
|
||||
endif
|
||||
while 1
|
||||
let save_verbose = &verbose
|
||||
let &verbose = 0
|
||||
try
|
||||
redir => HL_SAVE
|
||||
execute 'silent! highlight ' . hlname
|
||||
redir END
|
||||
finally
|
||||
let &verbose = save_verbose
|
||||
endtry
|
||||
if !empty(matchstr(HL_SAVE, 'xxx cleared$'))
|
||||
return ''
|
||||
endif
|
||||
" follow highlight link
|
||||
let ml = matchlist(HL_SAVE, 'links to \zs.*')
|
||||
if !empty(ml)
|
||||
let hlname = ml[0]
|
||||
continue
|
||||
endif
|
||||
break
|
||||
endwhile
|
||||
let HL_SAVE = substitute(matchstr(HL_SAVE, 'xxx \zs.*'),
|
||||
\ '[ \t\n]\+', ' ', 'g')
|
||||
return [hlname, HL_SAVE]
|
||||
endfunction "}}}
|
||||
function! EasyMotion#highlight#turn_off(hl) "{{{
|
||||
if type(a:hl) != type([])
|
||||
return
|
||||
endif
|
||||
execute 'highlight ' . a:hl[0] . ' NONE'
|
||||
endfunction "}}}
|
||||
function! EasyMotion#highlight#turn_on(hl) "{{{
|
||||
if type(a:hl) != type([])
|
||||
return
|
||||
endif
|
||||
execute 'highlight ' . a:hl[0] . ' ' . a:hl[1]
|
||||
endfunction "}}}
|
||||
|
||||
" Restore 'cpoptions' {{{
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
" }}}
|
||||
" __END__ {{{
|
||||
" vim: expandtab softtabstop=4 shiftwidth=4
|
||||
" vim: foldmethod=marker
|
||||
" }}}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
27
vim/plugins/vim-easymotion/autoload/EasyMotion/overwin.vim
Normal file
27
vim/plugins/vim-easymotion/autoload/EasyMotion/overwin.vim
Normal file
@ -0,0 +1,27 @@
|
||||
let s:V = vital#easymotion#new()
|
||||
let s:HitAHintMotion = s:V.import('HitAHint.Motion')
|
||||
|
||||
call EasyMotion#init()
|
||||
|
||||
function! EasyMotion#overwin#move(pattern) abort
|
||||
return s:HitAHintMotion.move(a:pattern, {
|
||||
\ 'keys': g:EasyMotion_keys,
|
||||
\ 'use_upper': g:EasyMotion_use_upper,
|
||||
\ 'highlight': {
|
||||
\ 'shade': g:EasyMotion_hl_group_shade,
|
||||
\ 'target': g:EasyMotion_hl_group_target,
|
||||
\ },
|
||||
\ 'jump_first_target_keys':
|
||||
\ (g:EasyMotion_enter_jump_first ? ["\<CR>"] : []) +
|
||||
\ (g:EasyMotion_space_jump_first ? ["\<Space>"] : []),
|
||||
\ 'do_shade': g:EasyMotion_do_shade,
|
||||
\ })
|
||||
endfunction
|
||||
|
||||
function! EasyMotion#overwin#line() abort
|
||||
return EasyMotion#overwin#move('^')
|
||||
endfunction
|
||||
|
||||
function! EasyMotion#overwin#w() abort
|
||||
return EasyMotion#overwin#move('\(\<.\|^$\)')
|
||||
endfunction
|
@ -0,0 +1,24 @@
|
||||
" Saving 'cpoptions' {{{
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
" }}}
|
||||
"
|
||||
let EasyMotion#sticky_table#us = {
|
||||
\',' : '<', '.' : '>', '/' : '?',
|
||||
\'1' : '!', '2' : '@', '3' : '#', '4' : '$', '5' : '%',
|
||||
\'6' : '^', '7' : '&', '8' : '*', '9' : '(', '0' : ')', '-' : '_', '=' : '+',
|
||||
\';' : ':', '[' : '{', ']' : '}', '`' : '~', "'" : "\"", '\' : '|',
|
||||
\}
|
||||
|
||||
let EasyMotion#sticky_table#jp = {
|
||||
\',' : '<', '.' : '>', '/' : '?',
|
||||
\'1' : '!', '2' : '"', '3' : '#', '4' : '$', '5' : '%',
|
||||
\'6' : '&', '7' : "'", '8' : '(', '9' : ')', '0' : '_', '-' : '=', '^' : '~',
|
||||
\';' : '+', ':' : '*', '[' : '{', ']' : '}', '@' : '`', '\' : '|',
|
||||
\}
|
||||
|
||||
" Restore 'cpoptions' {{{
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
" }}}
|
||||
" vim: fdm=marker:et:ts=4:sw=4:sts=4
|
12
vim/plugins/vim-easymotion/autoload/vital.vim
Normal file
12
vim/plugins/vim-easymotion/autoload/vital.vim
Normal file
@ -0,0 +1,12 @@
|
||||
function! vital#of(name) abort
|
||||
let files = globpath(&runtimepath, 'autoload/vital/' . a:name . '.vital', 1)
|
||||
let file = split(files, "\n")
|
||||
if empty(file)
|
||||
throw 'vital: version file not found: ' . a:name
|
||||
endif
|
||||
let ver = readfile(file[0], 'b')
|
||||
if empty(ver)
|
||||
throw 'vital: invalid version file: ' . a:name
|
||||
endif
|
||||
return vital#_{substitute(ver[0], '\W', '', 'g')}#new()
|
||||
endfunction
|
@ -0,0 +1,5 @@
|
||||
let s:_plugin_name = expand('<sfile>:t:r')
|
||||
|
||||
function! vital#{s:_plugin_name}#new() abort
|
||||
return vital#{s:_plugin_name[1:]}#new()
|
||||
endfunction
|
@ -0,0 +1,116 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Data#Dict#import() abort
|
||||
return map({'pick': '', 'clear': '', 'max_by': '', 'foldl': '', 'swap': '', 'omit': '', 'min_by': '', 'foldr': '', 'make_index': '', 'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Data#Dict#import() abort', printf("return map({'pick': '', 'clear': '', 'max_by': '', 'foldl': '', 'swap': '', 'omit': '', 'min_by': '', 'foldr': '', 'make_index': '', 'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
" Utilities for dictionary.
|
||||
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" Makes a dict from keys and values
|
||||
function! s:make(keys, values, ...) abort
|
||||
let dict = {}
|
||||
let fill = a:0 ? a:1 : 0
|
||||
for i in range(len(a:keys))
|
||||
let key = type(a:keys[i]) == type('') ? a:keys[i] : string(a:keys[i])
|
||||
if key ==# ''
|
||||
throw "vital: Data.Dict: Can't use an empty string for key."
|
||||
endif
|
||||
let dict[key] = get(a:values, i, fill)
|
||||
endfor
|
||||
return dict
|
||||
endfunction
|
||||
|
||||
" Swaps keys and values
|
||||
function! s:swap(dict) abort
|
||||
return s:make(values(a:dict), keys(a:dict))
|
||||
endfunction
|
||||
|
||||
" Makes a index dict from a list
|
||||
function! s:make_index(list, ...) abort
|
||||
let value = a:0 ? a:1 : 1
|
||||
return s:make(a:list, [], value)
|
||||
endfunction
|
||||
|
||||
function! s:pick(dict, keys) abort
|
||||
let new_dict = {}
|
||||
for key in a:keys
|
||||
if has_key(a:dict, key)
|
||||
let new_dict[key] = a:dict[key]
|
||||
endif
|
||||
endfor
|
||||
return new_dict
|
||||
endfunction
|
||||
|
||||
function! s:omit(dict, keys) abort
|
||||
let new_dict = copy(a:dict)
|
||||
for key in a:keys
|
||||
if has_key(a:dict, key)
|
||||
call remove(new_dict, key)
|
||||
endif
|
||||
endfor
|
||||
return new_dict
|
||||
endfunction
|
||||
|
||||
function! s:clear(dict) abort
|
||||
for key in keys(a:dict)
|
||||
call remove(a:dict, key)
|
||||
endfor
|
||||
return a:dict
|
||||
endfunction
|
||||
|
||||
function! s:_max_by(dict, expr) abort
|
||||
let dict = s:swap(map(copy(a:dict), a:expr))
|
||||
let key = dict[max(keys(dict))]
|
||||
return [key, a:dict[key]]
|
||||
endfunction
|
||||
|
||||
function! s:max_by(dict, expr) abort
|
||||
if empty(a:dict)
|
||||
throw 'vital: Data.Dict: Empty dictionary'
|
||||
endif
|
||||
return s:_max_by(a:dict, a:expr)
|
||||
endfunction
|
||||
|
||||
function! s:min_by(dict, expr) abort
|
||||
if empty(a:dict)
|
||||
throw 'vital: Data.Dict: Empty dictionary'
|
||||
endif
|
||||
return s:_max_by(a:dict, '-(' . a:expr . ')')
|
||||
endfunction
|
||||
|
||||
function! s:_foldl(f, init, xs) abort
|
||||
let memo = a:init
|
||||
for [k, v] in a:xs
|
||||
let expr = substitute(a:f, 'v:key', string(k), 'g')
|
||||
let expr = substitute(expr, 'v:val', string(v), 'g')
|
||||
let expr = substitute(expr, 'v:memo', string(memo), 'g')
|
||||
unlet memo
|
||||
let memo = eval(expr)
|
||||
endfor
|
||||
return memo
|
||||
endfunction
|
||||
|
||||
function! s:foldl(f, init, dict) abort
|
||||
return s:_foldl(a:f, a:init, items(a:dict))
|
||||
endfunction
|
||||
|
||||
function! s:foldr(f, init, dict) abort
|
||||
return s:_foldl(a:f, a:init, reverse(items(a:dict)))
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
||||
" vim:set et ts=2 sts=2 sw=2 tw=0:
|
@ -0,0 +1,457 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Data#List#import() abort
|
||||
return map({'combinations': '', 'and': '', 'sort_by': '', 'foldr1': '', 'sort': '', 'flatten': '', 'has_index': '', 'find_indices': '', 'any': '', 'unshift': '', 'span': '', 'pop': '', 'binary_search': '', 'uniq_by': '', 'or': '', 'all': '', 'zip': '', 'find_last_index': '', 'find': '', 'partition': '', 'map_accum': '', 'permutations': '', 'break': '', 'max_by': '', 'foldl': '', 'foldr': '', 'find_index': '', 'group_by': '', 'take_while': '', 'conj': '', 'push': '', 'char_range': '', 'cons': '', 'foldl1': '', 'intersect': '', 'concat': '', 'shift': '', 'clear': '', 'has_common_items': '', 'product': '', 'zip_fill': '', 'uniq': '', 'has': '', 'min_by': '', 'with_index': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Data#List#import() abort', printf("return map({'combinations': '', 'and': '', 'sort_by': '', 'foldr1': '', 'sort': '', 'flatten': '', 'has_index': '', 'find_indices': '', 'any': '', 'unshift': '', 'span': '', 'pop': '', 'binary_search': '', 'uniq_by': '', 'or': '', 'all': '', 'zip': '', 'find_last_index': '', 'find': '', 'partition': '', 'map_accum': '', 'permutations': '', 'break': '', 'max_by': '', 'foldl': '', 'foldr': '', 'find_index': '', 'group_by': '', 'take_while': '', 'conj': '', 'push': '', 'char_range': '', 'cons': '', 'foldl1': '', 'intersect': '', 'concat': '', 'shift': '', 'clear': '', 'has_common_items': '', 'product': '', 'zip_fill': '', 'uniq': '', 'has': '', 'min_by': '', 'with_index': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
" Utilities for list.
|
||||
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
function! s:pop(list) abort
|
||||
return remove(a:list, -1)
|
||||
endfunction
|
||||
|
||||
function! s:push(list, val) abort
|
||||
call add(a:list, a:val)
|
||||
return a:list
|
||||
endfunction
|
||||
|
||||
function! s:shift(list) abort
|
||||
return remove(a:list, 0)
|
||||
endfunction
|
||||
|
||||
function! s:unshift(list, val) abort
|
||||
return insert(a:list, a:val)
|
||||
endfunction
|
||||
|
||||
function! s:cons(x, xs) abort
|
||||
return [a:x] + a:xs
|
||||
endfunction
|
||||
|
||||
function! s:conj(xs, x) abort
|
||||
return a:xs + [a:x]
|
||||
endfunction
|
||||
|
||||
" Removes duplicates from a list.
|
||||
function! s:uniq(list) abort
|
||||
return s:uniq_by(a:list, 'v:val')
|
||||
endfunction
|
||||
|
||||
" Removes duplicates from a list.
|
||||
function! s:uniq_by(list, f) abort
|
||||
let list = map(copy(a:list), printf('[v:val, %s]', a:f))
|
||||
let i = 0
|
||||
let seen = {}
|
||||
while i < len(list)
|
||||
let key = string(list[i][1])
|
||||
if has_key(seen, key)
|
||||
call remove(list, i)
|
||||
else
|
||||
let seen[key] = 1
|
||||
let i += 1
|
||||
endif
|
||||
endwhile
|
||||
return map(list, 'v:val[0]')
|
||||
endfunction
|
||||
|
||||
function! s:clear(list) abort
|
||||
if !empty(a:list)
|
||||
unlet! a:list[0 : len(a:list) - 1]
|
||||
endif
|
||||
return a:list
|
||||
endfunction
|
||||
|
||||
" Concatenates a list of lists.
|
||||
" XXX: Should we verify the input?
|
||||
function! s:concat(list) abort
|
||||
let memo = []
|
||||
for Value in a:list
|
||||
let memo += Value
|
||||
endfor
|
||||
return memo
|
||||
endfunction
|
||||
|
||||
" Take each elements from lists to a new list.
|
||||
function! s:flatten(list, ...) abort
|
||||
let limit = a:0 > 0 ? a:1 : -1
|
||||
let memo = []
|
||||
if limit == 0
|
||||
return a:list
|
||||
endif
|
||||
let limit -= 1
|
||||
for Value in a:list
|
||||
let memo +=
|
||||
\ type(Value) == type([]) ?
|
||||
\ s:flatten(Value, limit) :
|
||||
\ [Value]
|
||||
unlet! Value
|
||||
endfor
|
||||
return memo
|
||||
endfunction
|
||||
|
||||
" Sorts a list with expression to compare each two values.
|
||||
" a:a and a:b can be used in {expr}.
|
||||
function! s:sort(list, expr) abort
|
||||
if type(a:expr) == type(function('function'))
|
||||
return sort(a:list, a:expr)
|
||||
endif
|
||||
let s:expr = a:expr
|
||||
return sort(a:list, 's:_compare')
|
||||
endfunction
|
||||
|
||||
function! s:_compare(a, b) abort
|
||||
return eval(s:expr)
|
||||
endfunction
|
||||
|
||||
" Sorts a list using a set of keys generated by mapping the values in the list
|
||||
" through the given expr.
|
||||
" v:val is used in {expr}
|
||||
function! s:sort_by(list, expr) abort
|
||||
let pairs = map(a:list, printf('[v:val, %s]', a:expr))
|
||||
return map(s:sort(pairs,
|
||||
\ 'a:a[1] ==# a:b[1] ? 0 : a:a[1] ># a:b[1] ? 1 : -1'), 'v:val[0]')
|
||||
endfunction
|
||||
|
||||
" Returns a maximum value in {list} through given {expr}.
|
||||
" Returns 0 if {list} is empty.
|
||||
" v:val is used in {expr}
|
||||
function! s:max_by(list, expr) abort
|
||||
if empty(a:list)
|
||||
return 0
|
||||
endif
|
||||
let list = map(copy(a:list), a:expr)
|
||||
return a:list[index(list, max(list))]
|
||||
endfunction
|
||||
|
||||
" Returns a minimum value in {list} through given {expr}.
|
||||
" Returns 0 if {list} is empty.
|
||||
" v:val is used in {expr}
|
||||
" FIXME: -0x80000000 == 0x80000000
|
||||
function! s:min_by(list, expr) abort
|
||||
return s:max_by(a:list, '-(' . a:expr . ')')
|
||||
endfunction
|
||||
|
||||
" Returns List of character sequence between [a:from, a:to]
|
||||
" e.g.: s:char_range('a', 'c') returns ['a', 'b', 'c']
|
||||
function! s:char_range(from, to) abort
|
||||
return map(
|
||||
\ range(char2nr(a:from), char2nr(a:to)),
|
||||
\ 'nr2char(v:val)'
|
||||
\)
|
||||
endfunction
|
||||
|
||||
" Returns true if a:list has a:value.
|
||||
" Returns false otherwise.
|
||||
function! s:has(list, value) abort
|
||||
return index(a:list, a:value) isnot -1
|
||||
endfunction
|
||||
|
||||
" Returns true if a:list[a:index] exists.
|
||||
" Returns false otherwise.
|
||||
" NOTE: Returns false when a:index is negative number.
|
||||
function! s:has_index(list, index) abort
|
||||
" Return true when negative index?
|
||||
" let index = a:index >= 0 ? a:index : len(a:list) + a:index
|
||||
return 0 <= a:index && a:index < len(a:list)
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Data.List.span
|
||||
function! s:span(f, xs) abort
|
||||
let border = len(a:xs)
|
||||
for i in range(len(a:xs))
|
||||
if !eval(substitute(a:f, 'v:val', string(a:xs[i]), 'g'))
|
||||
let border = i
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
return border == 0 ? [[], copy(a:xs)] : [a:xs[: border - 1], a:xs[border :]]
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Data.List.break
|
||||
function! s:break(f, xs) abort
|
||||
return s:span(printf('!(%s)', a:f), a:xs)
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Data.List.takeWhile
|
||||
function! s:take_while(f, xs) abort
|
||||
return s:span(a:f, a:xs)[0]
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Data.List.partition
|
||||
function! s:partition(f, xs) abort
|
||||
return [filter(copy(a:xs), a:f), filter(copy(a:xs), '!(' . a:f . ')')]
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Prelude.all
|
||||
function! s:all(f, xs) abort
|
||||
return !s:any(printf('!(%s)', a:f), a:xs)
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Prelude.any
|
||||
function! s:any(f, xs) abort
|
||||
return !empty(filter(map(copy(a:xs), a:f), 'v:val'))
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Prelude.and
|
||||
function! s:and(xs) abort
|
||||
return s:all('v:val', a:xs)
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Prelude.or
|
||||
function! s:or(xs) abort
|
||||
return s:any('v:val', a:xs)
|
||||
endfunction
|
||||
|
||||
function! s:map_accum(expr, xs, init) abort
|
||||
let memo = []
|
||||
let init = a:init
|
||||
for x in a:xs
|
||||
let expr = substitute(a:expr, 'v:memo', init, 'g')
|
||||
let expr = substitute(expr, 'v:val', x, 'g')
|
||||
let [tmp, init] = eval(expr)
|
||||
call add(memo, tmp)
|
||||
endfor
|
||||
return memo
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Prelude.foldl
|
||||
function! s:foldl(f, init, xs) abort
|
||||
let memo = a:init
|
||||
for x in a:xs
|
||||
let expr = substitute(a:f, 'v:val', string(x), 'g')
|
||||
let expr = substitute(expr, 'v:memo', string(memo), 'g')
|
||||
unlet memo
|
||||
let memo = eval(expr)
|
||||
endfor
|
||||
return memo
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Prelude.foldl1
|
||||
function! s:foldl1(f, xs) abort
|
||||
if len(a:xs) == 0
|
||||
throw 'vital: Data.List: foldl1'
|
||||
endif
|
||||
return s:foldl(a:f, a:xs[0], a:xs[1:])
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Prelude.foldr
|
||||
function! s:foldr(f, init, xs) abort
|
||||
return s:foldl(a:f, a:init, reverse(copy(a:xs)))
|
||||
endfunction
|
||||
|
||||
" similar to Haskell's Prelude.fold11
|
||||
function! s:foldr1(f, xs) abort
|
||||
if len(a:xs) == 0
|
||||
throw 'vital: Data.List: foldr1'
|
||||
endif
|
||||
return s:foldr(a:f, a:xs[-1], a:xs[0:-2])
|
||||
endfunction
|
||||
|
||||
" similar to python's zip()
|
||||
function! s:zip(...) abort
|
||||
return map(range(min(map(copy(a:000), 'len(v:val)'))), "map(copy(a:000), 'v:val['.v:val.']')")
|
||||
endfunction
|
||||
|
||||
" similar to zip(), but goes until the longer one.
|
||||
function! s:zip_fill(xs, ys, filler) abort
|
||||
if empty(a:xs) && empty(a:ys)
|
||||
return []
|
||||
elseif empty(a:ys)
|
||||
return s:cons([a:xs[0], a:filler], s:zip_fill(a:xs[1 :], [], a:filler))
|
||||
elseif empty(a:xs)
|
||||
return s:cons([a:filler, a:ys[0]], s:zip_fill([], a:ys[1 :], a:filler))
|
||||
else
|
||||
return s:cons([a:xs[0], a:ys[0]], s:zip_fill(a:xs[1 :], a:ys[1: ], a:filler))
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Inspired by Ruby's with_index method.
|
||||
function! s:with_index(list, ...) abort
|
||||
let base = a:0 > 0 ? a:1 : 0
|
||||
return map(copy(a:list), '[v:val, v:key + base]')
|
||||
endfunction
|
||||
|
||||
" similar to Ruby's detect or Haskell's find.
|
||||
function! s:find(list, default, f) abort
|
||||
for x in a:list
|
||||
if eval(substitute(a:f, 'v:val', string(x), 'g'))
|
||||
return x
|
||||
endif
|
||||
endfor
|
||||
return a:default
|
||||
endfunction
|
||||
|
||||
" Returns the index of the first element which satisfies the given expr.
|
||||
function! s:find_index(xs, f, ...) abort
|
||||
let len = len(a:xs)
|
||||
let start = a:0 > 0 ? (a:1 < 0 ? len + a:1 : a:1) : 0
|
||||
let default = a:0 > 1 ? a:2 : -1
|
||||
if start >=# len || start < 0
|
||||
return default
|
||||
endif
|
||||
for i in range(start, len - 1)
|
||||
if eval(substitute(a:f, 'v:val', string(a:xs[i]), 'g'))
|
||||
return i
|
||||
endif
|
||||
endfor
|
||||
return default
|
||||
endfunction
|
||||
|
||||
" Returns the index of the last element which satisfies the given expr.
|
||||
function! s:find_last_index(xs, f, ...) abort
|
||||
let len = len(a:xs)
|
||||
let start = a:0 > 0 ? (a:1 < 0 ? len + a:1 : a:1) : len - 1
|
||||
let default = a:0 > 1 ? a:2 : -1
|
||||
if start >=# len || start < 0
|
||||
return default
|
||||
endif
|
||||
for i in range(start, 0, -1)
|
||||
if eval(substitute(a:f, 'v:val', string(a:xs[i]), 'g'))
|
||||
return i
|
||||
endif
|
||||
endfor
|
||||
return default
|
||||
endfunction
|
||||
|
||||
" Similar to find_index but returns the list of indices satisfying the given expr.
|
||||
function! s:find_indices(xs, f, ...) abort
|
||||
let len = len(a:xs)
|
||||
let start = a:0 > 0 ? (a:1 < 0 ? len + a:1 : a:1) : 0
|
||||
let result = []
|
||||
if start >=# len || start < 0
|
||||
return result
|
||||
endif
|
||||
for i in range(start, len - 1)
|
||||
if eval(substitute(a:f, 'v:val', string(a:xs[i]), 'g'))
|
||||
call add(result, i)
|
||||
endif
|
||||
endfor
|
||||
return result
|
||||
endfunction
|
||||
|
||||
" Return non-zero if a:list1 and a:list2 have any common item(s).
|
||||
" Return zero otherwise.
|
||||
function! s:has_common_items(list1, list2) abort
|
||||
return !empty(filter(copy(a:list1), 'index(a:list2, v:val) isnot -1'))
|
||||
endfunction
|
||||
|
||||
function! s:intersect(list1, list2) abort
|
||||
let items = []
|
||||
" for funcref
|
||||
for X in a:list1
|
||||
if index(a:list2, X) != -1 && index(items, X) == -1
|
||||
let items += [X]
|
||||
endif
|
||||
endfor
|
||||
return items
|
||||
endfunction
|
||||
|
||||
" similar to Ruby's group_by.
|
||||
function! s:group_by(xs, f) abort
|
||||
let result = {}
|
||||
let list = map(copy(a:xs), printf('[v:val, %s]', a:f))
|
||||
for x in list
|
||||
let Val = x[0]
|
||||
let key = type(x[1]) !=# type('') ? string(x[1]) : x[1]
|
||||
if has_key(result, key)
|
||||
call add(result[key], Val)
|
||||
else
|
||||
let result[key] = [Val]
|
||||
endif
|
||||
unlet Val
|
||||
endfor
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! s:_default_compare(a, b) abort
|
||||
return a:a <# a:b ? -1 : a:a ># a:b ? 1 : 0
|
||||
endfunction
|
||||
|
||||
function! s:binary_search(list, value, ...) abort
|
||||
let Predicate = a:0 >= 1 ? a:1 : 's:_default_compare'
|
||||
let dic = a:0 >= 2 ? a:2 : {}
|
||||
let start = 0
|
||||
let end = len(a:list) - 1
|
||||
|
||||
while 1
|
||||
if start > end
|
||||
return -1
|
||||
endif
|
||||
|
||||
let middle = (start + end) / 2
|
||||
|
||||
let compared = call(Predicate, [a:value, a:list[middle]], dic)
|
||||
|
||||
if compared < 0
|
||||
let end = middle - 1
|
||||
elseif compared > 0
|
||||
let start = middle + 1
|
||||
else
|
||||
return middle
|
||||
endif
|
||||
endwhile
|
||||
endfunction
|
||||
|
||||
function! s:product(lists) abort
|
||||
let result = [[]]
|
||||
for pool in a:lists
|
||||
let tmp = []
|
||||
for x in result
|
||||
let tmp += map(copy(pool), 'x + [v:val]')
|
||||
endfor
|
||||
let result = tmp
|
||||
endfor
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! s:permutations(list, ...) abort
|
||||
if a:0 > 1
|
||||
throw 'vital: Data.List: too many arguments'
|
||||
endif
|
||||
let r = a:0 == 1 ? a:1 : len(a:list)
|
||||
if r > len(a:list)
|
||||
return []
|
||||
elseif r < 0
|
||||
throw 'vital: Data.List: {r} must be non-negative integer'
|
||||
endif
|
||||
let n = len(a:list)
|
||||
let result = []
|
||||
for indices in s:product(map(range(r), 'range(n)'))
|
||||
if len(s:uniq(indices)) == r
|
||||
call add(result, map(indices, 'a:list[v:val]'))
|
||||
endif
|
||||
endfor
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! s:combinations(list, r) abort
|
||||
if a:r > len(a:list)
|
||||
return []
|
||||
elseif a:r < 0
|
||||
throw 'vital: Data:List: {r} must be non-negative integer'
|
||||
endif
|
||||
let n = len(a:list)
|
||||
let result = []
|
||||
for indices in s:permutations(range(n), a:r)
|
||||
if s:sort(copy(indices), 'a:a - a:b') == indices
|
||||
call add(result, map(indices, 'a:list[v:val]'))
|
||||
endif
|
||||
endfor
|
||||
return result
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
||||
" vim:set et ts=2 sts=2 sw=2 tw=0:
|
@ -0,0 +1,284 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Data#Set#import() abort
|
||||
return map({'set': '', 'frozenset': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Data#Set#import() abort', printf("return map({'set': '', 'frozenset': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
let s:TRUE = !0
|
||||
let s:FALSE = 0
|
||||
|
||||
function! s:set(...) abort
|
||||
return call(s:set._new, a:000, s:set)
|
||||
endfunction
|
||||
|
||||
function! s:frozenset(...) abort
|
||||
return call(s:frozenset._new, a:000, s:frozenset)
|
||||
endfunction
|
||||
|
||||
function! s:_hash_func(x) abort
|
||||
return a:x
|
||||
endfunction
|
||||
|
||||
let s:_base_set = {
|
||||
\ '_is_set' : s:TRUE,
|
||||
\ '_data' : {},
|
||||
\ '_hash_func' : function('s:_hash_func')
|
||||
\ }
|
||||
|
||||
function! s:_base_set._new(...) abort
|
||||
let obj = deepcopy(self)
|
||||
let xs = get(a:, 1, [])
|
||||
let obj._hash_func = get(a:, 2, obj._hash_func)
|
||||
call obj._set_data(xs)
|
||||
return obj
|
||||
endfunction
|
||||
|
||||
"" Return the union of two sets as a new set.
|
||||
" (I.e. all elements that are in either set.)
|
||||
function! s:_base_set.union(t) abort
|
||||
let r = deepcopy(self)
|
||||
call r._update(a:t)
|
||||
return r
|
||||
endfunction
|
||||
let s:_base_set.or = s:_base_set.union
|
||||
|
||||
"" Return the intersection of two sets as a new set.
|
||||
" (I.e. all elements that are in both sets.)
|
||||
function! s:_base_set.intersection(t) abort
|
||||
let t = self._to_set(a:t)
|
||||
let [little, big] = self.len() <= t.len() ? [self, t] : [t, self]
|
||||
return self._new(filter(copy(big.to_list()), 'little.in(v:val)'))
|
||||
endfunction
|
||||
let s:_base_set.and = s:_base_set.intersection
|
||||
|
||||
"" Return the symmetric difference of two sets as a new set.
|
||||
" (I.e. all elements that are in exactly one of the sets.)
|
||||
function! s:_base_set.symmetric_difference(t) abort
|
||||
let t = self._to_set(a:t)
|
||||
return self._new(filter(copy(self.to_list()), '!t.in(v:val)')
|
||||
\ + filter(copy(t.to_list()), '!self.in(v:val)'))
|
||||
endfunction
|
||||
let s:_base_set.xor = s:_base_set.symmetric_difference
|
||||
|
||||
"" Return the difference of two sets as a new Set.
|
||||
function! s:_base_set.difference(t) abort
|
||||
let t = self._to_set(a:t)
|
||||
return self._new(filter(copy(self.to_list()), '!t.in(v:val)'))
|
||||
endfunction
|
||||
let s:_base_set.sub = s:_base_set.difference
|
||||
|
||||
"" Report whether another set contains this set.
|
||||
function! s:_base_set.issubset(t) abort
|
||||
let t = self._to_set(a:t)
|
||||
return self.len() > t.len() ? s:FALSE
|
||||
\ : empty(filter(copy(self.to_list()), '!t.in(v:val)'))
|
||||
endfunction
|
||||
|
||||
"" Report whether this set contains another set.
|
||||
function! s:_base_set.issuperset(t) abort
|
||||
let t = self._to_set(a:t)
|
||||
return self.len() < t.len() ? s:FALSE
|
||||
\ : empty(filter(copy(t.to_list()), '!self.in(v:val)'))
|
||||
endfunction
|
||||
|
||||
" less than equal & greater than equal
|
||||
let s:_base_set.le = s:_base_set.issubset
|
||||
let s:_base_set.ge = s:_base_set.issuperset
|
||||
|
||||
" less than
|
||||
function! s:_base_set.lt(t) abort
|
||||
let t = self._to_set(a:t)
|
||||
return self.len() < t.len() && self.issubset(t)
|
||||
endfunction
|
||||
|
||||
" greater than
|
||||
function! s:_base_set.gt(t) abort
|
||||
let t = self._to_set(a:t)
|
||||
return self.len() > t.len() && self.issuperset(t)
|
||||
endfunction
|
||||
|
||||
function! s:_base_set.len() abort
|
||||
return len(self._data)
|
||||
endfunction
|
||||
|
||||
function! s:_base_set.to_list() abort
|
||||
return values(self._data)
|
||||
endfunction
|
||||
|
||||
function! s:_base_set._update(xs) abort
|
||||
for X in (s:_is_set(a:xs) ? a:xs.to_list() : a:xs)
|
||||
call self._add(X)
|
||||
unlet X
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:_base_set._add(x) abort
|
||||
let key = self._hash(a:x)
|
||||
if !has_key(self._data, key)
|
||||
let self._data[key] = a:x
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Report whether an element is a member of a set.
|
||||
function! s:_base_set.in(x) abort
|
||||
return has_key(self._data, self._hash(a:x))
|
||||
endfunction
|
||||
|
||||
function! s:_base_set._to_set(x) abort
|
||||
return s:_is_set(a:x) ? a:x : self._new(a:x)
|
||||
endfunction
|
||||
|
||||
function! s:_base_set._clear() abort
|
||||
let self._data = {}
|
||||
endfunction
|
||||
|
||||
function! s:_base_set._set_data(xs) abort
|
||||
call self._clear()
|
||||
call self._update(a:xs)
|
||||
endfunction
|
||||
|
||||
function! s:_base_set._hash(x) abort
|
||||
return string(self._hash_func(a:x))
|
||||
endfunction
|
||||
|
||||
" frozenset: Immutable set class.
|
||||
|
||||
let s:frozenset = deepcopy(s:_base_set)
|
||||
|
||||
" Set: Mutable set class.
|
||||
|
||||
let s:set = deepcopy(s:_base_set)
|
||||
|
||||
" Update a set with the union of itself and another.
|
||||
function! s:set.update(iterable) abort
|
||||
call self._update(a:iterable)
|
||||
endfunction
|
||||
|
||||
" Update a set with the union of itself and another.
|
||||
function! s:set.ior(t) abort
|
||||
call self.update(a:t)
|
||||
return self
|
||||
endfunction
|
||||
|
||||
" Update a set with the intersection of itself and another.
|
||||
function! s:set.intersection_update(t) abort
|
||||
let r = self.and(a:t).to_list()
|
||||
call self.clear()
|
||||
call self.update(r)
|
||||
endfunction
|
||||
|
||||
" Update a set with the intersection of itself and another.
|
||||
function! s:set.iand(t) abort
|
||||
call self.intersection_update(a:t)
|
||||
return self
|
||||
endfunction
|
||||
|
||||
" Update a set with the symmetric difference of itself and another.
|
||||
function! s:set.symmetric_difference_update(t) abort
|
||||
let t = self._to_set(a:t)
|
||||
if self is t
|
||||
call self.clear()
|
||||
return
|
||||
endif
|
||||
for X in t.to_list()
|
||||
if self.in(X)
|
||||
call self.remove(X)
|
||||
else
|
||||
call self._add(X)
|
||||
endif
|
||||
unlet X
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" Update a set with the symmetric difference of itself and another.
|
||||
function! s:set.ixor(t) abort
|
||||
call self.symmetric_difference_update(a:t)
|
||||
return self
|
||||
endfunction
|
||||
|
||||
" Remove all elements of another set from this set.
|
||||
function! s:set.difference_update(t) abort
|
||||
let t = self._to_set(a:t)
|
||||
if self is t
|
||||
call self.clear()
|
||||
return
|
||||
endif
|
||||
for X in filter(t.to_list(), 'self.in(v:val)')
|
||||
call self.remove(X)
|
||||
unlet X
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" Remove all elements of another set from this set.
|
||||
function! s:set.isub(t) abort
|
||||
call self.difference_update(a:t)
|
||||
return self
|
||||
endfunction
|
||||
|
||||
" Remove all elements from this set.
|
||||
function! s:set.clear() abort
|
||||
call self._clear()
|
||||
endfunction
|
||||
|
||||
"" Add an element to a set.
|
||||
" This has no effect if the element is already present.
|
||||
function! s:set.add(x) abort
|
||||
return self._add(a:x)
|
||||
endfunction
|
||||
|
||||
"" Remove an element from a set; it must be a member.
|
||||
" If the element is not a member, throw Exception.
|
||||
function! s:set.remove(e) abort
|
||||
try
|
||||
unlet self._data[self._hash(a:e)]
|
||||
catch /^Vim\%((\a\+)\)\?:E716/
|
||||
call s:_throw('the element is not a member')
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
"" Remove an element from a set if it is a member.
|
||||
" If the element is not a member, do nothing.
|
||||
function! s:set.discard(e) abort
|
||||
try
|
||||
call self.remove(a:e)
|
||||
catch /vital: Data.Set: the element is not a member/
|
||||
" Do nothing
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" Remove and return an arbitrary set element.
|
||||
function! s:set.pop() abort
|
||||
try
|
||||
let k = keys(self._data)[0]
|
||||
catch /^Vim\%((\a\+)\)\?:E684/
|
||||
call s:_throw('set is empty')
|
||||
endtry
|
||||
let v = self._data[k]
|
||||
unlet self._data[k]
|
||||
return v
|
||||
endfunction
|
||||
|
||||
" Helper:
|
||||
|
||||
function! s:_is_set(x) abort
|
||||
return type(a:x) is type({}) && get(a:x, '_is_set', s:FALSE)
|
||||
endfunction
|
||||
|
||||
function! s:_throw(message) abort
|
||||
throw 'vital: Data.Set: ' . a:message
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,126 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#HitAHint#Hint#import() abort
|
||||
return map({'create': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#HitAHint#Hint#import() abort', printf("return map({'create': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
" function() wrapper
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
let s:_function = function('function')
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
let s:_s = '<SNR>' . s:_SID() . '_'
|
||||
function! s:_function(fstr) abort
|
||||
return function(substitute(a:fstr, 's:', s:_s, 'g'))
|
||||
endfunction
|
||||
endif
|
||||
|
||||
function! s:_assert(...) abort
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! s:_vital_loaded(V) abort
|
||||
if a:V.exists('Vim.PowerAssert')
|
||||
let s:assert = a:V.import('Vim.PowerAssert').assert
|
||||
else
|
||||
let s:assert = s:_function('s:_assert')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" TERMS:
|
||||
" key: A character to generate hint. e.g. a,b,c,d,e,f,...
|
||||
" hint: A hint is a combination of keys. e.g. a,b,ab,abc,..
|
||||
|
||||
" s:create() assigns keys to each targets and generate hint dict.
|
||||
" Example:
|
||||
" let targets = [1, 2, 3, 4, 5, 6]
|
||||
" echo s:label(targets, ['a', 'b', 'c'])
|
||||
" " => {
|
||||
" 'a': 1,
|
||||
" 'b': {
|
||||
" 'a': 2,
|
||||
" 'b': 3
|
||||
" },
|
||||
" 'c': {
|
||||
" 'a': 4,
|
||||
" 'b': 5,
|
||||
" 'c': 6
|
||||
" }
|
||||
" }
|
||||
" Hint-to-target:
|
||||
" a -> 1
|
||||
" ba -> 2
|
||||
" bb -> 3
|
||||
" ca -> 4
|
||||
" cb -> 5
|
||||
" cc -> 6
|
||||
" @param {list<T>} targets
|
||||
" @param {list<string>} keys each key should be uniq
|
||||
" @return Tree{string: (T|Tree)}
|
||||
function! s:create(targets, keys) abort
|
||||
exe s:assert('len(a:keys) > 1')
|
||||
let groups = {}
|
||||
let keys_count = reverse(s:_keys_count(len(a:targets), len(a:keys)))
|
||||
|
||||
let target_idx = 0
|
||||
let key_idx = 0
|
||||
for key_count in keys_count
|
||||
if key_count > 1
|
||||
" We need to create a subgroup
|
||||
" Recurse one level deeper
|
||||
let sub_targets = a:targets[target_idx : target_idx + key_count - 1]
|
||||
let groups[a:keys[key_idx]] = s:create(sub_targets, a:keys)
|
||||
elseif key_count == 1
|
||||
" Assign single target key_idx
|
||||
let groups[a:keys[key_idx]] = a:targets[target_idx]
|
||||
else
|
||||
" No target
|
||||
continue
|
||||
endif
|
||||
let key_idx += 1
|
||||
let target_idx += key_count
|
||||
endfor
|
||||
return groups
|
||||
endfunction
|
||||
|
||||
" s:_keys_count() generates list which represents how many targets to be
|
||||
" assigned to the key.
|
||||
" If the count > 1, use tree recursively.
|
||||
" Example:
|
||||
" echo s:_keys_count(5, 3)
|
||||
" " => [3, 1, 1]
|
||||
" echo s:_keys_count(8, 3)
|
||||
" " => [3, 3, 2]
|
||||
" @param {number} target_len
|
||||
" @param {number} keys_len
|
||||
function! s:_keys_count(targets_len, keys_len) abort
|
||||
exe s:assert('a:keys_len > 1')
|
||||
let _keys_count = repeat([0], a:keys_len)
|
||||
let is_first_level = 1
|
||||
let targets_left_cnt = a:targets_len
|
||||
while targets_left_cnt > 0
|
||||
let cnt_to_add = is_first_level ? 1 : a:keys_len - 1
|
||||
for i in range(a:keys_len)
|
||||
let _keys_count[i] += cnt_to_add
|
||||
let targets_left_cnt -= cnt_to_add
|
||||
if targets_left_cnt <= 0
|
||||
let _keys_count[i] += targets_left_cnt
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
let is_first_level = 0
|
||||
endwhile
|
||||
exe s:assert('len(_keys_count) is# a:keys_len')
|
||||
return _keys_count
|
||||
endfunction
|
@ -0,0 +1,806 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#HitAHint#Motion#import() abort
|
||||
return map({'deepextend': '', 'gather_poses': '', 'tab2spacelen': '', 'move_f': '', 'setline': '', '_vital_depends': '', 'wincall': '', 'move': '', 'move_to_winpos': '', 'pos2hint_to_line2col2hint': '', 'gather_visible_matched_poses': '', 'move_to_win': '', 'throw': '', 'has_patch': '', 'win2pos2hint_to_w2l2c2h': '', 'move_f2': '', 'new_overwin': '', 'create_win2pos2hint': '', 'pos2poskey': '', 'winnr2poses_to_list': '', 'poskey2pos': '', 'is_in_fold': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#HitAHint#Motion#import() abort', printf("return map({'deepextend': '', 'gather_poses': '', 'tab2spacelen': '', 'move_f': '', 'setline': '', '_vital_depends': '', 'wincall': '', 'move': '', 'move_to_winpos': '', 'pos2hint_to_line2col2hint': '', 'gather_visible_matched_poses': '', 'move_to_win': '', 'throw': '', 'has_patch': '', 'win2pos2hint_to_w2l2c2h': '', 'move_f2': '', 'new_overwin': '', 'create_win2pos2hint': '', 'pos2poskey': '', 'winnr2poses_to_list': '', 'poskey2pos': '', 'is_in_fold': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
function! s:_vital_loaded(V) abort
|
||||
let s:Hint = a:V.import('HitAHint.Hint')
|
||||
let s:PHighlight = a:V.import('Palette.Highlight')
|
||||
let s:Buffer = a:V.import('Vim.Buffer')
|
||||
let s:Prelude = a:V.import('Prelude')
|
||||
let s:Set = a:V.import('Data.Set')
|
||||
let s:Input = a:V.import('Over.Input')
|
||||
endfunction
|
||||
|
||||
function! s:_vital_depends() abort
|
||||
return [
|
||||
\ 'HitAHint.Hint',
|
||||
\ 'Palette.Highlight',
|
||||
\ 'Vim.Buffer',
|
||||
\ 'Prelude',
|
||||
\ 'Data.Set',
|
||||
\ 'Over.Input',
|
||||
\ ]
|
||||
endfunction
|
||||
|
||||
let s:TRUE = !0
|
||||
let s:FALSE = 0
|
||||
let s:DIRECTION = {'forward': 0, 'backward': 1}
|
||||
|
||||
" Check Vim version
|
||||
function! s:has_patch(major, minor, patch) abort
|
||||
let l:version = (a:major * 100 + a:minor)
|
||||
return has('patch-' . a:major . '.' . a:minor . '.' . a:patch) ||
|
||||
\ (v:version > l:version) ||
|
||||
\ (v:version == l:version && 'patch' . a:patch)
|
||||
endfunction
|
||||
|
||||
" matchadd('Conceal', {pattern}, {priority}, -1, {'conceal': {char}}}) can
|
||||
" highlight pattern and conceal target correctly even if the target is keyword
|
||||
" characters.
|
||||
" - http://ftp.vim.org/vim/patches/7.4/7.4.792
|
||||
" - https://groups.google.com/forum/#!searchin/vim_dev/matchadd$20conceal/vim_dev/8bKa98GhHdk/VOzIBhd1m8YJ
|
||||
let s:can_preserve_syntax = s:has_patch(7, 4, 792)
|
||||
|
||||
" s:move() moves cursor over/accross window with Hit-A-Hint feature like
|
||||
" vim-easymotion
|
||||
" @param {dict} config
|
||||
function! s:move(pattern, ...) abort
|
||||
let o = s:new_overwin(get(a:, 1, {}))
|
||||
return o.pattern(a:pattern)
|
||||
endfunction
|
||||
|
||||
function! s:move_f(...) abort
|
||||
echo 'Target: '
|
||||
let c = s:Input.getchar()
|
||||
return s:move(c, get(a:, 1, {}))
|
||||
endfunction
|
||||
|
||||
function! s:move_f2() abort
|
||||
echo 'Target: '
|
||||
let c = s:Input.getchar()
|
||||
redraw
|
||||
echo 'Target: ' . c
|
||||
let c2 = s:Input.getchar()
|
||||
return s:move(s:Prelude.escape_pattern(c . c2), get(a:, 1, {}))
|
||||
endfunction
|
||||
|
||||
|
||||
let s:overwin = {
|
||||
\ 'config': {
|
||||
\ 'keys': 'asdghklqwertyuiopzxcvbnmfj;',
|
||||
\ 'use_upper': s:FALSE,
|
||||
\ 'auto_land': s:TRUE,
|
||||
\ 'highlight': {
|
||||
\ 'shade': 'HitAHintShade',
|
||||
\ 'target': 'HitAHintTarget',
|
||||
\ 'cursor': 'HitAHintCursor',
|
||||
\ },
|
||||
\ 'jump_first_target_keys': [],
|
||||
\ 'do_shade': s:TRUE,
|
||||
\ }
|
||||
\ }
|
||||
|
||||
function! s:_init_hl() abort
|
||||
highlight default HitAHintShade ctermfg=242 guifg=#777777
|
||||
highlight default HitAHintTarget ctermfg=81 guifg=#66D9EF
|
||||
" Cursor highlight doesn't exist for some environment with some
|
||||
" colorscheme ref:#275
|
||||
" e.g.
|
||||
" - :colorscheme default
|
||||
" - :colorscheme hybrid
|
||||
if hlexists('Cursor')
|
||||
highlight default link HitAHintCursor Cursor
|
||||
else
|
||||
highlight default HitAHintCursor term=reverse cterm=reverse gui=reverse
|
||||
endif
|
||||
endfunction
|
||||
|
||||
call s:_init_hl()
|
||||
|
||||
augroup vital-hit-a-hint-motion-default-highlight
|
||||
autocmd!
|
||||
autocmd ColorScheme * call s:_init_hl()
|
||||
augroup END
|
||||
|
||||
|
||||
function! s:new_overwin(...) abort
|
||||
let o = deepcopy(s:overwin)
|
||||
call s:deepextend(o.config, get(a:, 1, {}))
|
||||
return o
|
||||
endfunction
|
||||
|
||||
function! s:overwin.pattern(pattern) abort
|
||||
let winpos = self.select_winpos(self.gather_poses_overwin(a:pattern), self.config.keys)
|
||||
if winpos is# -1
|
||||
else
|
||||
call s:move_to_winpos(winpos)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" @param {{winnr: [lnum, cnum]}}
|
||||
function! s:move_to_winpos(winpos) abort
|
||||
let [winnr_str, pos] = a:winpos
|
||||
let winnr = str2nr(winnr_str)
|
||||
let is_win_moved = !(winnr is# winnr())
|
||||
if is_win_moved
|
||||
if exists('#WinLeave')
|
||||
silent doautocmd WinLeave
|
||||
endif
|
||||
call s:move_to_win(winnr)
|
||||
else
|
||||
normal! m`
|
||||
endif
|
||||
call cursor(pos)
|
||||
if is_win_moved && exists('#WinEnter')
|
||||
silent doautocmd WinEnter
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:overwin.select_winpos(winnr2poses, keys) abort
|
||||
let wposes = s:winnr2poses_to_list(a:winnr2poses)
|
||||
if self.config.auto_land && len(wposes) is# 1
|
||||
return wposes[0]
|
||||
endif
|
||||
call self.set_options()
|
||||
try
|
||||
return self.choose_prompt(s:Hint.create(wposes, a:keys))
|
||||
finally
|
||||
call self.restore_options()
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:overwin.set_options() abort
|
||||
" s:move_to_win() takes long time if 'foldmethod' == 'syntax' or 'expr'
|
||||
let self.save_foldmethod = {}
|
||||
for winnr in range(1, winnr('$'))
|
||||
let self.save_foldmethod[winnr] = getwinvar(winnr, '&foldmethod')
|
||||
call setwinvar(winnr, '&foldmethod', 'manual')
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:overwin.restore_options() abort
|
||||
for winnr in range(1, winnr('$'))
|
||||
call setwinvar(winnr, '&foldmethod', self.save_foldmethod[winnr])
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" s:wpos_to_hint() returns dict whose key is position with window and whose
|
||||
" value is the hints.
|
||||
" @param Tree{string: ((winnr, (number,number))|Tree)} hint_dict
|
||||
" @return {{winnr: {string: list<char>}}} poskey to hint for each window
|
||||
" e.g.
|
||||
" {
|
||||
" '1': {
|
||||
" '00168:00004': ['b', 'c', 'b'],
|
||||
" '00174:00001': ['b', 'c', 'a'],
|
||||
" '00188:00004': ['b', 'b'],
|
||||
" '00190:00001': ['b', 'a'],
|
||||
" '00191:00016': ['a', 'c'],
|
||||
" '00192:00004': ['a', 'b'],
|
||||
" '00195:00035': ['a', 'a']
|
||||
" },
|
||||
" '3': {
|
||||
" '00168:00004': ['c', 'c', 'c'],
|
||||
" '00174:00001': ['c', 'c', 'b'],
|
||||
" '00188:00004': ['c', 'c', 'a'],
|
||||
" '00190:00001': ['c', 'b'],
|
||||
" '00191:00016': ['c', 'a'],
|
||||
" '00192:00004': ['b', 'c', 'c']
|
||||
" }
|
||||
" }
|
||||
function! s:create_win2pos2hint(hint_dict) abort
|
||||
return s:_create_win2pos2hint({}, a:hint_dict)
|
||||
endfunction
|
||||
|
||||
function! s:_create_win2pos2hint(dict, hint_dict, ...) abort
|
||||
let prefix = get(a:, 1, [])
|
||||
for [hint, v] in items(a:hint_dict)
|
||||
if type(v) is# type({})
|
||||
call s:_create_win2pos2hint(a:dict, v, prefix + [hint])
|
||||
else
|
||||
let [winnr, pos] = v
|
||||
let a:dict[winnr] = get(a:dict, winnr, {})
|
||||
let a:dict[winnr][s:pos2poskey(pos)] = prefix + [hint]
|
||||
endif
|
||||
unlet v
|
||||
endfor
|
||||
return a:dict
|
||||
endfunction
|
||||
|
||||
" s:pos2poskey() convertes pos to poskey to use pos as dictionary keys and
|
||||
" sort pos correctly.
|
||||
" @param {(number,number)} pos
|
||||
" @return string
|
||||
" e.g. [1, 1] -> '00001:00001'
|
||||
function! s:pos2poskey(pos) abort
|
||||
return join(map(copy(a:pos), "printf('%05d', v:val)"), ':')
|
||||
endfunction
|
||||
|
||||
" s:poskey2pos() convertes poskey to pos.
|
||||
" @param {string} poskey e.g. '00001:00001'
|
||||
" @return {(number,number)}
|
||||
" e.g. '00001:00001' -> [1, 1]
|
||||
function! s:poskey2pos(poskey) abort
|
||||
return map(split(a:poskey, ':'), 'str2nr(v:val)')
|
||||
endfunction
|
||||
|
||||
function! s:overwin.choose_prompt(hint_dict) abort
|
||||
if empty(a:hint_dict)
|
||||
redraw
|
||||
echo 'No target'
|
||||
return -1
|
||||
endif
|
||||
let hinter = s:Hinter.new(a:hint_dict, self.config)
|
||||
try
|
||||
call hinter.before()
|
||||
call hinter.show_hint()
|
||||
redraw
|
||||
echo 'Target key: '
|
||||
let c = s:Input.getchar()
|
||||
if self.config.use_upper
|
||||
let c = toupper(c)
|
||||
endif
|
||||
catch
|
||||
echo v:throwpoint . ':' . v:exception
|
||||
return -1
|
||||
finally
|
||||
call hinter.after()
|
||||
endtry
|
||||
|
||||
" Jump to first target if target key is in config.jump_first_target_keys.
|
||||
if index(self.config.jump_first_target_keys, c) isnot# -1
|
||||
let c = split(self.config.keys, '\zs')[0]
|
||||
endif
|
||||
|
||||
if has_key(a:hint_dict, c)
|
||||
let target = a:hint_dict[c]
|
||||
return type(target) is# type({}) ? self.choose_prompt(target) : target
|
||||
else
|
||||
redraw
|
||||
echo 'Invalid target: ' . c
|
||||
return -1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Hinter show hints accross window.
|
||||
" save_lines: {{winnr: {lnum: string}}}
|
||||
" w2l2c2h: winnr to lnum to col num to hints. col2hints is tuple because we
|
||||
" need sorted col to hints pair.
|
||||
" save_syntax: {{winnr: &syntax}}
|
||||
" {{winnr: {lnum: list<(cnum, list<char>)>}}}
|
||||
let s:Hinter = {
|
||||
\ 'save_lines': {},
|
||||
\ 'w2l2c2h': {},
|
||||
\ 'winnrs': [],
|
||||
\ 'save_syntax': {},
|
||||
\ 'save_conceallevel': {},
|
||||
\ 'save_concealcursor': {},
|
||||
\ 'save_modified': {},
|
||||
\ 'save_modifiable': {},
|
||||
\ 'save_readonly': {},
|
||||
\ 'save_undo': {},
|
||||
\ 'highlight_ids': {},
|
||||
\ }
|
||||
|
||||
function! s:Hinter.new(hint_dict, config) abort
|
||||
let s = deepcopy(self)
|
||||
let s.config = a:config
|
||||
call s.init(a:hint_dict)
|
||||
return s
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.init(hint_dict) abort
|
||||
let win2pos2hint = s:create_win2pos2hint(a:hint_dict)
|
||||
let self.winnrs = sort(map(keys(win2pos2hint), 'str2nr(v:val)'))
|
||||
let self.win2pos2hint = win2pos2hint
|
||||
let self.w2l2c2h = s:win2pos2hint_to_w2l2c2h(win2pos2hint)
|
||||
let self.hl_target_ids = {}
|
||||
for winnr in self.winnrs
|
||||
let self.hl_target_ids[winnr] = []
|
||||
endfor
|
||||
call self._save_lines()
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.before() abort
|
||||
let self.highlight_id_cursor = matchadd(self.config.highlight.cursor, '\%#', 101)
|
||||
call self.save_options()
|
||||
call self.disable_conceal_in_other_win()
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.after() abort
|
||||
call matchdelete(self.highlight_id_cursor)
|
||||
call self.restore_env()
|
||||
call self.restore_conceal_in_other_win()
|
||||
endfunction
|
||||
|
||||
function! s:Hinter._save_lines() abort
|
||||
let nr = winnr()
|
||||
try
|
||||
for [winnr, pos2hint] in items(self.win2pos2hint)
|
||||
call s:move_to_win(winnr)
|
||||
let lnums = map(copy(keys(pos2hint)), 's:poskey2pos(v:val)[0]')
|
||||
let self.save_lines[winnr] = get(self.save_lines, winnr, {})
|
||||
for lnum in lnums
|
||||
let self.save_lines[winnr][lnum] = getline(lnum)
|
||||
endfor
|
||||
endfor
|
||||
finally
|
||||
call s:move_to_win(nr)
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.restore_lines_for_win(winnr) abort
|
||||
let lnum2line = self.save_lines[a:winnr]
|
||||
for [lnum, line] in items(lnum2line)
|
||||
call s:setline(lnum, line)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.save_options() abort
|
||||
for winnr in self.winnrs
|
||||
let self.save_syntax[winnr] = getwinvar(winnr, '&syntax')
|
||||
let self.save_conceallevel[winnr] = getwinvar(winnr, '&conceallevel')
|
||||
let self.save_concealcursor[winnr] = getwinvar(winnr, '&concealcursor')
|
||||
let self.save_modified[winnr] = getwinvar(winnr, '&modified')
|
||||
let self.save_modifiable[winnr] = getwinvar(winnr, '&modifiable')
|
||||
let self.save_readonly[winnr] = getwinvar(winnr, '&readonly')
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.restore_options() abort
|
||||
for winnr in self.winnrs
|
||||
call setwinvar(winnr, '&conceallevel', self.save_conceallevel[winnr])
|
||||
call setwinvar(winnr, '&concealcursor', self.save_concealcursor[winnr])
|
||||
call setwinvar(winnr, '&modified', self.save_modified[winnr])
|
||||
call setwinvar(winnr, '&modifiable', self.save_modifiable[winnr])
|
||||
call setwinvar(winnr, '&readonly', self.save_readonly[winnr])
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.modify_env_for_win(winnr) abort
|
||||
let self.save_conceal = s:PHighlight.get('Conceal')
|
||||
let self.save_undo[a:winnr] = s:undo_lock.save()
|
||||
|
||||
setlocal modifiable
|
||||
setlocal noreadonly
|
||||
|
||||
if !s:can_preserve_syntax
|
||||
ownsyntax overwin
|
||||
endif
|
||||
|
||||
setlocal conceallevel=2
|
||||
setlocal concealcursor=ncv
|
||||
|
||||
let self.highlight_ids[a:winnr] = get(self.highlight_ids, a:winnr, [])
|
||||
if self.config.do_shade
|
||||
if !s:can_preserve_syntax
|
||||
syntax clear
|
||||
endif
|
||||
let self.highlight_ids[a:winnr] += [matchadd(self.config.highlight.shade, '\_.*', 100)]
|
||||
endif
|
||||
|
||||
" XXX: other plugins specific handling
|
||||
if getbufvar('%', 'indentLine_enabled', 0)
|
||||
silent! syntax clear IndentLine
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.restore_env() abort
|
||||
call s:PHighlight.set('Conceal', self.save_conceal)
|
||||
let nr = winnr()
|
||||
try
|
||||
for winnr in self.winnrs
|
||||
call s:move_to_win(winnr)
|
||||
call self.restore_lines_for_win(winnr)
|
||||
call self.remove_hints(winnr)
|
||||
|
||||
if !s:can_preserve_syntax && self.config.do_shade
|
||||
let &syntax = self.save_syntax[winnr]
|
||||
endif
|
||||
|
||||
call self.save_undo[winnr].restore()
|
||||
|
||||
for id in self.highlight_ids[winnr]
|
||||
call matchdelete(id)
|
||||
endfor
|
||||
|
||||
" XXX: other plugins specific handling
|
||||
if getbufvar('%', 'indentLine_enabled', 0) && exists(':IndentLinesEnable') is# 2
|
||||
call setbufvar('%', 'indentLine_enabled', 0)
|
||||
:IndentLinesEnable
|
||||
endif
|
||||
endfor
|
||||
catch
|
||||
call s:throw(v:throwpoint . ' ' . v:exception)
|
||||
finally
|
||||
call s:move_to_win(nr)
|
||||
endtry
|
||||
|
||||
call self.restore_options()
|
||||
endfunction
|
||||
|
||||
let s:undo_lock = {}
|
||||
|
||||
function! s:undo_lock.save() abort
|
||||
let undo = deepcopy(self)
|
||||
call undo._save()
|
||||
return undo
|
||||
endfunction
|
||||
|
||||
function! s:undo_lock._save() abort
|
||||
if undotree().seq_last == 0
|
||||
" if there are no undo history, disable undo feature by setting
|
||||
" 'undolevels' to -1 and restore it.
|
||||
let self.save_undolevels = &l:undolevels
|
||||
let &l:undolevels = -1
|
||||
elseif !s:Buffer.is_cmdwin()
|
||||
" command line window doesn't support :wundo.
|
||||
let self.undofile = tempname()
|
||||
execute 'wundo!' self.undofile
|
||||
else
|
||||
let self.is_cmdwin = s:TRUE
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:undo_lock.restore() abort
|
||||
if has_key(self, 'save_undolevels')
|
||||
let &l:undolevels = self.save_undolevels
|
||||
endif
|
||||
if has_key(self, 'undofile') && filereadable(self.undofile)
|
||||
silent execute 'rundo' self.undofile
|
||||
call delete(self.undofile)
|
||||
endif
|
||||
if has_key(self, 'is_cmdwin')
|
||||
" XXX: it breaks undo history. AFAIK, there are no way to save and restore
|
||||
" undo history in commandline window.
|
||||
call self.undobreak()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:undo_lock.undobreak() abort
|
||||
let old_undolevels = &l:undolevels
|
||||
setlocal undolevels=-1
|
||||
keepjumps call setline('.', getline('.'))
|
||||
let &l:undolevels = old_undolevels
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.disable_conceal_in_other_win() abort
|
||||
let allwinnrs = s:Set.set(range(1, winnr('$')))
|
||||
let other_winnrs = allwinnrs.sub(self.winnrs).to_list()
|
||||
for w in other_winnrs
|
||||
if 'help' !=# getwinvar(w, '&buftype')
|
||||
call setwinvar(w, 'overwin_save_conceallevel', getwinvar(w, '&conceallevel'))
|
||||
call setwinvar(w, '&conceallevel', 0)
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.restore_conceal_in_other_win() abort
|
||||
let allwinnrs = s:Set.set(range(1, winnr('$')))
|
||||
let other_winnrs = allwinnrs.sub(self.winnrs).to_list()
|
||||
for w in other_winnrs
|
||||
if 'help' !=# getwinvar(w, '&buftype')
|
||||
call setwinvar(w, '&conceallevel', getwinvar(w, 'overwin_save_conceallevel'))
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" ._pos2hint_to_line2col2hint() converts pos2hint to line2col2hint dict whose
|
||||
" key is line number and whose value is list of tuple of col number to hint.
|
||||
" line2col2hint is for show hint with replacing line by line.
|
||||
" col should be sorted.
|
||||
" @param {{string: list<char>}} pos2hint
|
||||
" @return {number: [(number, list<char>)]}
|
||||
function! s:Hinter._pos2hint_to_line2col2hint(pos2hint) abort
|
||||
let line2col2hint = {}
|
||||
let poskeys = sort(keys(a:pos2hint))
|
||||
for poskey in poskeys
|
||||
let [lnum, cnum] = s:poskey2pos(poskey)
|
||||
let line2col2hint[lnum] = get(line2col2hint, lnum, [])
|
||||
let line2col2hint[lnum] += [[cnum, a:pos2hint[poskey]]]
|
||||
endfor
|
||||
return line2col2hint
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.show_hint() abort
|
||||
let nr = winnr()
|
||||
try
|
||||
for winnr in self.winnrs
|
||||
call s:move_to_win(winnr)
|
||||
call self._show_hint_for_win(winnr)
|
||||
endfor
|
||||
finally
|
||||
call s:move_to_win(nr)
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:Hinter._show_hint_for_win(winnr) abort
|
||||
call self.modify_env_for_win(a:winnr)
|
||||
|
||||
let hints = []
|
||||
for [lnum, col2hint] in items(self.w2l2c2h[a:winnr])
|
||||
let hints += self._show_hint_for_line(a:winnr, lnum, col2hint)
|
||||
endfor
|
||||
" Restore syntax and show hints after replacing all lines for performance.
|
||||
if !s:can_preserve_syntax && !self.config.do_shade
|
||||
let &l:syntax = self.save_syntax[a:winnr]
|
||||
endif
|
||||
execute 'highlight! link Conceal' self.config.highlight.target
|
||||
for [lnum, cnum, char] in hints
|
||||
call self.show_hint_pos(lnum, cnum, char, a:winnr)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:Hinter._show_hint_for_line(winnr, lnum, col2hint) abort
|
||||
let hints = [] " [lnum, cnum, char]
|
||||
let line = self.save_lines[a:winnr][a:lnum]
|
||||
let col_offset = 0
|
||||
let prev_cnum = -1
|
||||
let next_offset = 0
|
||||
for [cnum, hint] in a:col2hint
|
||||
let col_num = cnum + col_offset
|
||||
|
||||
let is_consecutive = cnum is# prev_cnum + 1
|
||||
if !is_consecutive
|
||||
let col_num += next_offset
|
||||
endif
|
||||
let save_next_offset = next_offset
|
||||
|
||||
let [line, offset, next_offset] = self._replace_line_for_hint(col_num, line, hint)
|
||||
|
||||
if is_consecutive
|
||||
let col_offset += save_next_offset
|
||||
endif
|
||||
let col_offset += offset
|
||||
|
||||
let hints = [[a:lnum, col_num, hint[0]]] + hints
|
||||
if len(hint) > 1
|
||||
let hints = [[a:lnum, col_num + 1, hint[1]]] + hints
|
||||
endif
|
||||
|
||||
let prev_cnum = cnum
|
||||
endfor
|
||||
call s:setline(a:lnum, line)
|
||||
return hints
|
||||
endfunction
|
||||
|
||||
" ._replace_line_for_hint() replaces line to show hints.
|
||||
" - It appends space if the line is empty
|
||||
" - It replaces <Tab> to space if the target character is <Tab>
|
||||
" - It replaces next target character if it's <Tab> and len(hint) > 1
|
||||
" Replacing line changes col number, so it returns offset of col number.
|
||||
" As for replaceing next target character, the timing to calculate offset
|
||||
" depends on the col number of next hint in the same line, so it returns
|
||||
" `next_offset` instead of returning offset all at once.
|
||||
" @return {(string, number, number)} (line, offset, next_offset)
|
||||
function! s:Hinter._replace_line_for_hint(col_num, line, hint) abort
|
||||
let line = a:line
|
||||
let col_num = a:col_num
|
||||
let do_replace_target = !(self.config.do_shade || s:can_preserve_syntax)
|
||||
let target = matchstr(line, '\%' . col_num .'c.')
|
||||
" Append one space for empty line or match at end of line
|
||||
if target is# ''
|
||||
let hintwidth = strdisplaywidth(join(a:hint[:1], ''))
|
||||
let char = do_replace_target ? ' ' : '.'
|
||||
let line .= repeat(char, hintwidth)
|
||||
return [line, hintwidth, 0]
|
||||
endif
|
||||
|
||||
let offset = 0
|
||||
if target is# "\t"
|
||||
let [line, offset] = self._replace_tab_target(col_num, line)
|
||||
elseif strdisplaywidth(target) > 1
|
||||
let line = self._replace_text_to_space(line, col_num, strdisplaywidth(target))
|
||||
let offset = strdisplaywidth(target) - len(target)
|
||||
else
|
||||
if do_replace_target
|
||||
" The priority of :syn-cchar is always under the priority of keywords.
|
||||
" So, Hit-A-Hint replaces targets character with '.'.
|
||||
let space = '.'
|
||||
let line = substitute(line, '\%' . col_num . 'c.', space, '')
|
||||
let offset = len(space) - len(target)
|
||||
endif
|
||||
endif
|
||||
|
||||
let next_offset = 0
|
||||
if len(a:hint) > 1 && target isnot# "\t"
|
||||
" pass [' '] as hint to stop recursion.
|
||||
let [line, next_offset, _] = self._replace_line_for_hint(col_num + offset + 1, line, [' '])
|
||||
endif
|
||||
return [line, offset, next_offset]
|
||||
endfunction
|
||||
|
||||
" @return {(line, offset)}
|
||||
function! s:Hinter._replace_tab_target(col_num, line) abort
|
||||
let space_len = s:tab2spacelen(a:line, a:col_num)
|
||||
let line = self._replace_text_to_space(a:line, a:col_num, space_len)
|
||||
return [line, space_len - 1]
|
||||
endfunction
|
||||
|
||||
function! s:Hinter._replace_text_to_space(line, col_num, len) abort
|
||||
let target = printf('\%%%dc.', a:col_num)
|
||||
let line = substitute(a:line, target, repeat(' ', a:len), '')
|
||||
return line
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.show_hint_pos(lnum, cnum, char, winnr) abort
|
||||
let p = '\%'. a:lnum . 'l\%'. a:cnum . 'c.'
|
||||
if s:can_preserve_syntax
|
||||
let self.hl_target_ids[a:winnr] += [matchadd('Conceal', p, 101, -1, {'conceal': a:char})]
|
||||
else
|
||||
exec "syntax match HitAHintTarget '". p . "' contains=NONE containedin=.* conceal cchar=". a:char
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:Hinter.remove_hints(winnr) abort
|
||||
if s:can_preserve_syntax
|
||||
for id in self.hl_target_ids[a:winnr]
|
||||
call matchdelete(id)
|
||||
endfor
|
||||
else
|
||||
" Clear syntax defined by Hit-A-Hint motion before restoring syntax.
|
||||
syntax clear HitAHintTarget
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" @param {number} col_num col_num is 1 origin like col()
|
||||
function! s:tab2spacelen(line, col_num) abort
|
||||
let before_line = a:col_num > 2 ? a:line[: a:col_num - 2]
|
||||
\ : a:col_num is# 2 ? a:line[0]
|
||||
\ : ''
|
||||
let vcol_num = 1
|
||||
for c in split(before_line, '\zs')
|
||||
let vcol_num += c is# "\t" ? s:_virtual_tab2spacelen(vcol_num) : len(c)
|
||||
endfor
|
||||
return s:_virtual_tab2spacelen(vcol_num)
|
||||
endfunction
|
||||
|
||||
function! s:_virtual_tab2spacelen(col_num) abort
|
||||
return &tabstop - ((a:col_num - 1) % &tabstop)
|
||||
endfunction
|
||||
|
||||
function! s:win2pos2hint_to_w2l2c2h(win2pos2hint) abort
|
||||
let w2l2c2h = {}
|
||||
for [winnr, pos2hint] in items(a:win2pos2hint)
|
||||
let w2l2c2h[winnr] = s:pos2hint_to_line2col2hint(pos2hint)
|
||||
endfor
|
||||
return w2l2c2h
|
||||
endfunction
|
||||
|
||||
" s:pos2hint_to_line2col2hint() converts pos2hint to line2col2hint dict whose
|
||||
" key is line number and whose value is list of tuple of col number to hint.
|
||||
" line2col2hint is for show hint with replacing line by line.
|
||||
" col should be sorted.
|
||||
" @param {{string: list<char>}} pos2hint
|
||||
" @return {number: [(number, list<char>)]}
|
||||
function! s:pos2hint_to_line2col2hint(pos2hint) abort
|
||||
let line2col2hint = {}
|
||||
let poskeys = sort(keys(a:pos2hint))
|
||||
for poskey in poskeys
|
||||
let [lnum, cnum] = s:poskey2pos(poskey)
|
||||
let line2col2hint[lnum] = get(line2col2hint, lnum, [])
|
||||
let line2col2hint[lnum] += [[cnum, a:pos2hint[poskey]]]
|
||||
endfor
|
||||
return line2col2hint
|
||||
endfunction
|
||||
|
||||
" @param {number} winnr
|
||||
function! s:move_to_win(winnr) abort
|
||||
if a:winnr !=# winnr()
|
||||
execute 'noautocmd' a:winnr . 'wincmd w'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" @param {regex} pattern
|
||||
" @return {{winnr: list<list<(number,number))>}}
|
||||
function! s:overwin.gather_poses_overwin(pattern) abort
|
||||
return s:wincall(function('s:gather_poses'), [a:pattern])
|
||||
endfunction
|
||||
|
||||
" s:gather_poses() aggregates patterm matched positions in visible current
|
||||
" window for both direction excluding poses in fold.
|
||||
" @return {{list<list<(number,number))>}}
|
||||
function! s:gather_poses(pattern) abort
|
||||
let f = s:gather_visible_matched_poses(a:pattern, s:DIRECTION.forward, s:TRUE)
|
||||
let b = s:gather_visible_matched_poses(a:pattern, s:DIRECTION.backward, s:FALSE)
|
||||
return filter(f + b, '!s:is_in_fold(v:val[0])')
|
||||
endfunction
|
||||
|
||||
" s:gather_visible_matched_poses() aggregates pattern matched positions in visible current
|
||||
" window.
|
||||
" @param {regex} pattern
|
||||
" @param {enum<DIRECTION>} direction see s:DIRECTION
|
||||
" @param {bool} allow_cursor_pos_match
|
||||
" @return {list<list<(number,number)>>} positions
|
||||
function! s:gather_visible_matched_poses(pattern, direction, allow_cursor_pos_match) abort
|
||||
let stop_line = line(a:direction is# s:DIRECTION.forward ? 'w$' : 'w0')
|
||||
let search_flag = (a:direction is# s:DIRECTION.forward ? '' : 'b')
|
||||
let c_flag = a:allow_cursor_pos_match ? 'c' : ''
|
||||
let view = winsaveview()
|
||||
let poses = []
|
||||
keepjumps let pos = searchpos(a:pattern, c_flag . search_flag, stop_line)
|
||||
while pos != [0, 0]
|
||||
let poses += [pos]
|
||||
keepjumps let pos = searchpos(a:pattern, search_flag, stop_line)
|
||||
endwhile
|
||||
call winrestview(view)
|
||||
return poses
|
||||
endfunction
|
||||
|
||||
" @param {{winnr: list<list<(number,number))>}} winnr2poses
|
||||
" @param {number?} first_winnr the top winnr poses in returned list
|
||||
" @return {list<{list<(winnr, (number,number))}>}
|
||||
function! s:winnr2poses_to_list(winnr2poses, ...) abort
|
||||
let first_winnr = get(a:, 1, winnr())
|
||||
let first_winnr_poses = []
|
||||
let other_poses = []
|
||||
for [winnr_str, poses] in items(a:winnr2poses)
|
||||
let winnr = str2nr(winnr_str)
|
||||
if winnr is# first_winnr
|
||||
let first_winnr_poses = map(copy(poses), '[winnr, v:val]')
|
||||
else
|
||||
let other_poses += map(copy(poses), '[winnr, v:val]')
|
||||
endif
|
||||
endfor
|
||||
return first_winnr_poses + other_poses
|
||||
endfunction
|
||||
|
||||
" @param {number} lnum line number
|
||||
function! s:is_in_fold(lnum) abort
|
||||
return foldclosed(a:lnum) != -1
|
||||
endfunction
|
||||
|
||||
" @param {funcref} func
|
||||
" @param {arglist} list<S>
|
||||
" @param {dict?} dict for :h call()
|
||||
" @return {{winnr: <T>}}
|
||||
function! s:wincall(func, arglist, ...) abort
|
||||
let dict = get(a:, 1, {})
|
||||
let r = {}
|
||||
let start_winnr = winnr()
|
||||
let r[start_winnr] = call(a:func, a:arglist, dict)
|
||||
if s:Buffer.is_cmdwin()
|
||||
return r
|
||||
endif
|
||||
noautocmd wincmd w
|
||||
while winnr() isnot# start_winnr
|
||||
let r[winnr()] = call(a:func, a:arglist, dict)
|
||||
noautocmd wincmd w
|
||||
endwhile
|
||||
return r
|
||||
endfunction
|
||||
|
||||
" deepextend (nest: 1)
|
||||
function! s:deepextend(expr1, expr2) abort
|
||||
let expr2 = copy(a:expr2)
|
||||
for [k, V] in items(a:expr1)
|
||||
if (type(V) is type({}) || type(V) is type([])) && has_key(expr2, k)
|
||||
let a:expr1[k] = extend(a:expr1[k], expr2[k])
|
||||
unlet expr2[k]
|
||||
endif
|
||||
unlet V
|
||||
endfor
|
||||
return extend(a:expr1, expr2)
|
||||
endfunction
|
||||
|
||||
function! s:setline(lnum, text) abort
|
||||
if getline(a:lnum) isnot# a:text
|
||||
call setline(a:lnum, a:text)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:throw(message) abort
|
||||
throw 'vital: HitAHint.Motion: ' . a:message
|
||||
endfunction
|
||||
|
@ -0,0 +1,606 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Base#import() abort
|
||||
return map({'_vital_depends': '', 'make_plain': '', 'is_input_waiting': '', 'make': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Base#import() abort', printf("return map({'_vital_depends': '', 'make_plain': '', 'is_input_waiting': '', 'make': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
function! s:_vital_loaded(V)
|
||||
let s:V = a:V
|
||||
let s:String = s:V.import("Over.String")
|
||||
let s:Signals = s:V.import("Over.Signals")
|
||||
let s:Input = s:V.import("Over.Input")
|
||||
let s:Keymapping = s:V.import("Over.Keymapping")
|
||||
let s:Module = s:V.import("Over.Commandline.Modules")
|
||||
let s:base.variables.modules = s:Signals.make()
|
||||
function! s:base.variables.modules.get_slot(val)
|
||||
return a:val.slot.module
|
||||
endfunction
|
||||
|
||||
let s:Highlight = s:V.import("Palette.Highlight")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_vital_depends()
|
||||
return [
|
||||
\ "Over.String",
|
||||
\ "Over.Signals",
|
||||
\ "Over.Input",
|
||||
\ "Over.Keymapping",
|
||||
\ "Over.Commandline.Modules",
|
||||
\ "Palette.Highlight",
|
||||
\ ]
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make(...)
|
||||
let result = deepcopy(s:base)
|
||||
call result.set_prompt(get(a:, 1, ":"))
|
||||
call result.connect(result, "_")
|
||||
return result
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make_plain()
|
||||
return deepcopy(s:base)
|
||||
endfunction
|
||||
|
||||
|
||||
let s:base = {
|
||||
\ "line" : {},
|
||||
\ "variables" : {
|
||||
\ "prompt" : "",
|
||||
\ "char" : "",
|
||||
\ "input" : "",
|
||||
\ "tap_key" : "",
|
||||
\ "exit" : 0,
|
||||
\ "keymapping" : {},
|
||||
\ "suffix" : "",
|
||||
\ "is_setted" : 0,
|
||||
\ },
|
||||
\ "highlights" : {
|
||||
\ "prompt" : "NONE",
|
||||
\ "cursor" : "VitalOverCommandLineCursor",
|
||||
\ "cursor_on" : "VitalOverCommandLineCursorOn",
|
||||
\ "cursor_insert" : "VitalOverCommandLineOnCursor",
|
||||
\ },
|
||||
\}
|
||||
|
||||
if exists("s:Signals")
|
||||
let s:base.variables.modules = s:Signals.make()
|
||||
function! s:base.variables.modules.get_slot(val)
|
||||
return a:val.slot.module
|
||||
endfunction
|
||||
endif
|
||||
|
||||
|
||||
function! s:base.getline()
|
||||
return self.line.str()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.setline(line)
|
||||
return self.line.set(a:line)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.char()
|
||||
return self.variables.char
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.setchar(char, ...)
|
||||
" 1 の場合は既に設定されていても上書きする
|
||||
" 0 の場合は既に設定されていれば上書きしない
|
||||
let overwrite = get(a:, 1, 1)
|
||||
if overwrite || self.variables.is_setted == 0
|
||||
let self.variables.input = a:char
|
||||
let self.variables.is_setted = 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.getpos()
|
||||
return self.line.pos()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.setpos(pos)
|
||||
return self.line.set_pos(a:pos)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.tap_keyinput(key)
|
||||
let self.variables.tap_key = a:key
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.untap_keyinput(key)
|
||||
if self.variables.tap_key == a:key
|
||||
let self.variables.tap_key = ""
|
||||
return 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.get_tap_key()
|
||||
return self.variables.tap_key
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.is_input(key, ...)
|
||||
let prekey = get(a:, 1, "")
|
||||
return self.get_tap_key() ==# prekey
|
||||
\ && self.char() ==# a:key
|
||||
" \ && self.char() == (prekey . a:key)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.input_key()
|
||||
return self.variables.input_key
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.set_prompt(prompt)
|
||||
let self.variables.prompt = a:prompt
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.get_prompt()
|
||||
return self.variables.prompt
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.set_suffix(str)
|
||||
let self.variables.suffix = a:str
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.get_suffix()
|
||||
return self.variables.suffix
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.insert(word, ...)
|
||||
if a:0
|
||||
call self.line.set(a:1)
|
||||
endif
|
||||
call self.line.input(a:word)
|
||||
endfunction
|
||||
|
||||
function! s:base.forward()
|
||||
return self.line.forward()
|
||||
endfunction
|
||||
|
||||
function! s:base.backward()
|
||||
return self.line.backward()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.backward_word(...)
|
||||
let pat = get(a:, 1, '\k\+\s*\|.')
|
||||
return matchstr(self.backward(), '\%(' . pat . '\)$')
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.connect(module, ...)
|
||||
if type(a:module) == type("")
|
||||
return call(self.connect, [s:Module.make(a:module)] + a:000, self)
|
||||
endif
|
||||
if empty(a:module)
|
||||
return
|
||||
endif
|
||||
let name = a:0 > 0 ? a:1 : a:module.name
|
||||
let slot = self.variables.modules.find_first_by("get(v:val.slot, 'name', '') == " . string(name))
|
||||
if empty(slot)
|
||||
call self.variables.modules.connect({ "name" : name, "module" : a:module })
|
||||
else
|
||||
let slot.slot.module = a:module
|
||||
endif
|
||||
" let self.variables.modules[name] = a:module
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.disconnect(name)
|
||||
return self.variables.modules.disconnect_by(
|
||||
\ "get(v:val.slot, 'name', '') == " . string(a:name)
|
||||
\ )
|
||||
" unlet self.variables.modules[a:name]
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.get_module(name)
|
||||
let slot = self.variables.modules.find_first_by("get(v:val.slot, 'name', '') == " . string(a:name))
|
||||
return empty(slot) ? {} : slot.slot.module
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.callevent(event)
|
||||
call self.variables.modules.sort_by("has_key(v:val.slot.module, 'priority') ? v:val.slot.module.priority('" . a:event . "') : 0")
|
||||
return self.variables.modules.call(a:event, [self])
|
||||
" call map(filter(copy(self.variables.modules), "has_key(v:val, a:event)"), "v:val." . a:event . "(self)")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.cmap(lhs, rhs)
|
||||
let self.variables.keymapping[a:lhs] = a:rhs
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.cnoremap(lhs, rhs)
|
||||
let key = s:Keymapping.as_key_config(a:rhs)
|
||||
let key.noremap = 1
|
||||
let self.variables.keymapping[a:lhs] = key
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.cunmap(lhs)
|
||||
unlet self.variables.keymapping[a:lhs]
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.keymapping()
|
||||
return self.__keymapping__()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__keymapping__()
|
||||
return {}
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.execute(...)
|
||||
let command = get(a:, 1, self.getline())
|
||||
call self.__execute(command)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.draw()
|
||||
call self.callevent("on_draw_pre")
|
||||
call self.callevent("on_draw")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.exit(...)
|
||||
let self.variables.exit = 1
|
||||
let self.variables.exit_code = get(a:, 1, 0)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.enable_keymapping()
|
||||
let self.variables.enable_keymapping = 1
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.disable_keymapping()
|
||||
let self.variables.enable_keymapping = 0
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.is_enable_keymapping()
|
||||
return self.variables.enable_keymapping
|
||||
endfunction
|
||||
|
||||
" function! s:base.cancel()
|
||||
" call self.exit(1)
|
||||
" call self.__on_cancel()
|
||||
" endfunction
|
||||
|
||||
|
||||
function! s:base.exit_code()
|
||||
return self.variables.exit_code
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.hl_cursor_on()
|
||||
if exists("self.variables.old_guicursor")
|
||||
set guicursor&
|
||||
let &guicursor = self.variables.old_guicursor
|
||||
unlet self.variables.old_guicursor
|
||||
endif
|
||||
|
||||
if exists("self.variables.old_t_ve")
|
||||
let &t_ve = self.variables.old_t_ve
|
||||
unlet self.variables.old_t_ve
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.hl_cursor_off()
|
||||
if exists("self.variables.old_t_ve")
|
||||
return
|
||||
endif
|
||||
|
||||
let self.variables.old_guicursor = &guicursor
|
||||
set guicursor=n:block-NONE
|
||||
let self.variables.old_t_ve = &t_ve
|
||||
set t_ve=
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.start(...)
|
||||
let exit_code = call(self.__main, a:000, self)
|
||||
return exit_code
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__empty(...)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.get(...)
|
||||
let Old_execute = self.execute
|
||||
let self.execute = self.__empty
|
||||
try
|
||||
let exit_code = call(self.start, a:000, self)
|
||||
if exit_code == 0
|
||||
return self.getline()
|
||||
endif
|
||||
finally
|
||||
let self.execute = Old_execute
|
||||
endtry
|
||||
return ""
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.input_key_stack()
|
||||
return self.variables.input_key_stack
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.input_key_stack_string()
|
||||
return join(self.variables.input_key_stack, "")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.set_input_key_stack(stack)
|
||||
let self.variables.input_key_stack = a:stack
|
||||
return self.variables.input_key_stack
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.input_key_stack_pop()
|
||||
return remove(self.input_key_stack(), 0)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.getchar(...)
|
||||
if empty(self.input_key_stack())
|
||||
return call(s:Input.getchar, a:000, s:Input)
|
||||
endif
|
||||
return self.input_key_stack_pop()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__init_variables()
|
||||
let self.variables.tap_key = ""
|
||||
let self.variables.char = ""
|
||||
let self.variables.input = ""
|
||||
let self.variables.exit = 0
|
||||
let self.variables.exit_code = 1
|
||||
let self.variables.enable_keymapping = 1
|
||||
let self.variables.input_key_stack = []
|
||||
let self.line = deepcopy(s:String.make())
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_is_valid_highlight(name)
|
||||
let highlight = s:Highlight.get(a:name)
|
||||
if empty(highlight)
|
||||
return 0
|
||||
endif
|
||||
|
||||
if has("gui_running")
|
||||
\ && (has_key(highlight, "guifg") || has_key(highlight, "guibg"))
|
||||
return 1
|
||||
elseif (has_key(highlight, "ctermfg") || has_key(highlight, "ctermbg"))
|
||||
return 1
|
||||
endif
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__init()
|
||||
call self.__init_variables()
|
||||
call self.hl_cursor_off()
|
||||
if !hlexists(self.highlights.cursor)
|
||||
if s:_is_valid_highlight("Cursor")
|
||||
execute "highlight link " . self.highlights.cursor . " Cursor"
|
||||
else
|
||||
" Workaround by CUI Vim Cursor Highlight
|
||||
" issues #92
|
||||
" https://github.com/osyo-manga/vital-over/issues/92
|
||||
execute "highlight " . self.highlights.cursor . " term=reverse cterm=reverse gui=reverse"
|
||||
endif
|
||||
endif
|
||||
if !hlexists(self.highlights.cursor_on)
|
||||
execute "highlight link " . self.highlights.cursor_on . " " . self.highlights.cursor
|
||||
endif
|
||||
if !hlexists(self.highlights.cursor_insert)
|
||||
execute "highlight " . self.highlights.cursor_insert . " cterm=underline term=underline gui=underline"
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__execute(command)
|
||||
call self.callevent("on_execute_pre")
|
||||
try
|
||||
call self.__execute__(a:command)
|
||||
catch
|
||||
echohl ErrorMsg
|
||||
echom matchstr(v:exception, 'Vim\((\w*)\)\?:\zs.*\ze')
|
||||
echohl None
|
||||
call self.callevent("on_execute_failed")
|
||||
finally
|
||||
call self.callevent("on_execute")
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__execute__(cmd)
|
||||
execute a:cmd
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__input_char(char)
|
||||
let char = a:char
|
||||
let self.variables.input_key = char
|
||||
let self.variables.char = char
|
||||
call self.setchar(self.variables.char)
|
||||
let self.variables.is_setted = 0
|
||||
call self.callevent("on_char_pre")
|
||||
call self.insert(self.variables.input)
|
||||
call self.callevent("on_char")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__input(input, ...)
|
||||
if a:input == ""
|
||||
return
|
||||
endif
|
||||
|
||||
let self.variables.input_key = a:input
|
||||
if a:0 == 0
|
||||
let keymapping = self.__get_keymapping()
|
||||
else
|
||||
let keymapping = a:1
|
||||
endif
|
||||
if self.is_enable_keymapping()
|
||||
let key = s:Keymapping.unmapping(keymapping, a:input)
|
||||
else
|
||||
let key = a:input
|
||||
endif
|
||||
if key == ""
|
||||
return
|
||||
endif
|
||||
|
||||
call self.set_input_key_stack(s:String.split_by_keys(key))
|
||||
while !(empty(self.input_key_stack()) || self.is_exit())
|
||||
call self.__input_char(self.input_key_stack_pop())
|
||||
endwhile
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:is_input_waiting(keymapping, input)
|
||||
let num = len(filter(copy(a:keymapping), 'stridx(v:key, a:input) == 0'))
|
||||
return num > 1 || (num == 1 && !has_key(a:keymapping, a:input))
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__inputting()
|
||||
if !self.is_enable_keymapping()
|
||||
return self.__input(s:Input.getchar())
|
||||
endif
|
||||
|
||||
let input = s:Input.getchar()
|
||||
let old_line = self.getline()
|
||||
let old_pos = self.getpos()
|
||||
let keymapping = self.__get_keymapping()
|
||||
try
|
||||
let t = reltime()
|
||||
while s:is_input_waiting(keymapping, input)
|
||||
\ && str2nr(reltimestr(reltime(t))) * 1000 < &timeoutlen
|
||||
call self.setline(old_line)
|
||||
call self.insert(input)
|
||||
call self.setpos(old_pos)
|
||||
call self.draw()
|
||||
let input .= s:Input.getchar(0)
|
||||
endwhile
|
||||
finally
|
||||
call self.setline(old_line)
|
||||
call self.setpos(old_pos)
|
||||
endtry
|
||||
call self.__input(input, keymapping)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__update()
|
||||
" call self.callevent("on_update")
|
||||
" if !getchar(1)
|
||||
" continue
|
||||
" endif
|
||||
"
|
||||
" call self.__input(s:getchar(0))
|
||||
" call self.draw()
|
||||
|
||||
call self.callevent("on_update")
|
||||
call self.__inputting()
|
||||
" call self.__input(s:Input.getchar())
|
||||
if self.is_exit()
|
||||
return -1
|
||||
endif
|
||||
call self.draw()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__main(...)
|
||||
try
|
||||
call self.__init()
|
||||
call self.callevent("on_enter")
|
||||
|
||||
call self.__input(get(a:, 1, ""))
|
||||
call self.draw()
|
||||
while !self.is_exit()
|
||||
try
|
||||
if self.__update()
|
||||
break
|
||||
endif
|
||||
catch
|
||||
call self.callevent("on_exception")
|
||||
endtry
|
||||
endwhile
|
||||
catch
|
||||
echohl ErrorMsg | echom v:throwpoint . " " . v:exception | echohl None
|
||||
let self.variables.exit_code = -1
|
||||
finally
|
||||
call self.__finish()
|
||||
call self.callevent("on_leave")
|
||||
endtry
|
||||
return self.exit_code()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__finish()
|
||||
call self.hl_cursor_on()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__is_exit()
|
||||
return self.is_exit()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.is_exit()
|
||||
return self.variables.exit
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.__get_keymapping()
|
||||
let result = {}
|
||||
" for module in values(self.variables.modules)
|
||||
for module in self.variables.modules.slots()
|
||||
if has_key(module, "keymapping")
|
||||
if module isnot self
|
||||
call extend(result, module.keymapping(self))
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
return extend(extend(result, self.variables.keymapping), self.keymapping())
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,42 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#import() abort
|
||||
return map({'get': '', 'make': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#import() abort', printf("return map({'get': '', 'make': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
function! s:_vital_loaded(V)
|
||||
let s:V = a:V
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:get(name)
|
||||
if exists("s:" . a:name)
|
||||
return s:{a:name}
|
||||
endif
|
||||
let s:{a:name} = s:V.import('Over.Commandline.Modules.' . a:name)
|
||||
return s:{a:name}
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make(name, ...)
|
||||
let module = s:get(a:name)
|
||||
return call(module.make, a:000, module)
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,179 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#BufferComplete#import() abort
|
||||
return map({'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#BufferComplete#import() abort', printf("return map({'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
function! s:_uniq(list)
|
||||
let dict = {}
|
||||
for _ in a:list
|
||||
let dict[_] = 0
|
||||
endfor
|
||||
return keys(dict)
|
||||
endfunction
|
||||
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "BufferComplete",
|
||||
\}
|
||||
|
||||
|
||||
function! s:_buffer_complete()
|
||||
return sort(s:_uniq(filter(split(join(getline(1, '$')), '\W'), '!empty(v:val)')), 1)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_parse_line(line)
|
||||
let keyword = matchstr(a:line, '\zs\w\+\ze$')
|
||||
let pos = strchars(a:line) - strchars(keyword)
|
||||
return [pos, keyword]
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_as_statusline(list, count)
|
||||
if empty(a:list)
|
||||
return
|
||||
endif
|
||||
let hl_none = "%#StatusLine#"
|
||||
let hl_select = "%#StatusLineNC#"
|
||||
let tail = " > "
|
||||
let result = a:list[0]
|
||||
let pos = 0
|
||||
for i in range(1, len(a:list)-1)
|
||||
if strdisplaywidth(result . " " . a:list[i]) > &columns - len(tail)
|
||||
if a:count < i
|
||||
break
|
||||
else
|
||||
let pos = -i
|
||||
endif
|
||||
let result = a:list[i]
|
||||
else
|
||||
let result .= (" " . a:list[i])
|
||||
endif
|
||||
if a:count == i
|
||||
let pos = pos + i
|
||||
endif
|
||||
endfor
|
||||
return join(map(split(result, " "), 'v:key == pos ? hl_select . v:val . hl_none : v:val'))
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.get_complete_words()
|
||||
return s:_buffer_complete()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.complete(cmdline)
|
||||
call s:_finish()
|
||||
let s:old_statusline = &statusline
|
||||
|
||||
let backward = a:cmdline.backward()
|
||||
let [pos, keyword] = s:_parse_line(backward)
|
||||
|
||||
if !exists("s:complete")
|
||||
let s:complete = self.get_complete_words()
|
||||
endif
|
||||
let s:complete_list = filter(copy(s:complete), 'v:val =~ ''^''.keyword')
|
||||
if empty(s:complete_list)
|
||||
return -1
|
||||
endif
|
||||
|
||||
if pos == 0
|
||||
let backward = ""
|
||||
else
|
||||
let backward = join(split(backward, '\zs')[ : pos-1 ], "")
|
||||
endif
|
||||
let s:line = backward . a:cmdline.forward()
|
||||
let s:pos = pos
|
||||
call a:cmdline.setline(s:line)
|
||||
|
||||
let s:count = 0
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_finish()
|
||||
if exists("s:old_statusline")
|
||||
let &statusline = s:old_statusline
|
||||
unlet s:old_statusline
|
||||
redrawstatus
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if a:cmdline.is_input("<Over>(buffer-complete)")
|
||||
\ || a:cmdline.is_input("<Over>(buffer-complete-prev)")
|
||||
if self.complete(a:cmdline) == -1
|
||||
call s:_finish()
|
||||
call a:cmdline.setchar('')
|
||||
return
|
||||
endif
|
||||
if a:cmdline.is_input("<Over>(buffer-complete-prev)")
|
||||
let s:count = len(s:complete_list) - 1
|
||||
endif
|
||||
call a:cmdline.setchar('')
|
||||
call a:cmdline.tap_keyinput("Completion")
|
||||
" elseif a:cmdline.is_input("\<Tab>", "Completion")
|
||||
elseif a:cmdline.is_input("<Over>(buffer-complete)", "Completion")
|
||||
\ || a:cmdline.is_input("\<Right>", "Completion")
|
||||
call a:cmdline.setchar('')
|
||||
let s:count += 1
|
||||
if s:count >= len(s:complete_list)
|
||||
let s:count = 0
|
||||
endif
|
||||
elseif a:cmdline.is_input("<Over>(buffer-complete-prev)", "Completion")
|
||||
\ || a:cmdline.is_input("\<Left>", "Completion")
|
||||
call a:cmdline.setchar('')
|
||||
let s:count -= 1
|
||||
if s:count < 0
|
||||
let s:count = len(s:complete_list) - 1
|
||||
endif
|
||||
else
|
||||
if a:cmdline.untap_keyinput("Completion")
|
||||
call a:cmdline.callevent("on_char_pre")
|
||||
endif
|
||||
call s:_finish()
|
||||
return
|
||||
endif
|
||||
call a:cmdline.setline(s:line)
|
||||
call a:cmdline.insert(s:complete_list[s:count], s:pos)
|
||||
if len(s:complete_list) > 1
|
||||
let &statusline = s:_as_statusline(s:complete_list, s:count)
|
||||
redrawstatus
|
||||
endif
|
||||
if len(s:complete_list) == 1
|
||||
call a:cmdline.untap_keyinput("Completion")
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_draw_pre(...)
|
||||
" redrawstatus
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_leave(cmdline)
|
||||
call s:_finish()
|
||||
unlet! s:complete
|
||||
endfunction
|
||||
|
||||
function! s:make()
|
||||
return deepcopy(s:module)
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,40 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#Cancel#import() abort
|
||||
return map({'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#Cancel#import() abort', printf("return map({'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "Cancel"
|
||||
\}
|
||||
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if a:cmdline.is_input("\<Esc>")
|
||||
\ || a:cmdline.is_input("\<C-c>")
|
||||
" call a:cmdline.cancel()
|
||||
call a:cmdline.exit(1)
|
||||
call a:cmdline.setchar("")
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make()
|
||||
return deepcopy(s:module)
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,58 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#CursorMove#import() abort
|
||||
return map({'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#CursorMove#import() abort', printf("return map({'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "CursorMove"
|
||||
\}
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if a:cmdline.is_input("\<Right>")
|
||||
call a:cmdline.line.next()
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("\<Left>")
|
||||
call a:cmdline.line.prev()
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("\<C-b>")
|
||||
\ || a:cmdline.is_input("\<Home>")
|
||||
call a:cmdline.setline(0)
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("\<C-e>")
|
||||
\ || a:cmdline.is_input("\<End>")
|
||||
call a:cmdline.setline(a:cmdline.line.length())
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("\<C-Left>")
|
||||
\ || a:cmdline.is_input("\<S-Left>")
|
||||
call a:cmdline.setline(strridx(a:cmdline.backward()[:-2], ' ') + 1)
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("\<C-Right>")
|
||||
\ || a:cmdline.is_input("\<S-Right>")
|
||||
let p = stridx(a:cmdline.forward()[1:], ' ')
|
||||
call a:cmdline.setline(p != -1 ? a:cmdline.line.pos() + p + 2 : a:cmdline.line.length())
|
||||
call a:cmdline.setchar('')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make()
|
||||
return deepcopy(s:module)
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,56 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#Delete#import() abort
|
||||
return map({'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#Delete#import() abort', printf("return map({'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "Delete",
|
||||
\}
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if a:cmdline.is_input("\<C-h>")
|
||||
\ || a:cmdline.is_input("\<BS>")
|
||||
if a:cmdline.line.length() == 0
|
||||
return a:cmdline.exit(1)
|
||||
else
|
||||
call a:cmdline.line.remove_prev()
|
||||
call a:cmdline.setchar('')
|
||||
endif
|
||||
elseif a:cmdline.is_input("\<Del>")
|
||||
call a:cmdline.line.remove_pos()
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("\<C-w>")
|
||||
let word = a:cmdline.backward_word()
|
||||
let backward = a:cmdline.backward()[ : -strlen(word)-1 ]
|
||||
call a:cmdline.setline(backward . a:cmdline.line.pos_char() . a:cmdline.forward())
|
||||
call a:cmdline.setline(strchars(backward))
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("\<C-u>")
|
||||
call a:cmdline.setline(a:cmdline.line.pos_char() . a:cmdline.forward())
|
||||
call a:cmdline.setline(0)
|
||||
call a:cmdline.setchar('')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make()
|
||||
return deepcopy(s:module)
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,121 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#Doautocmd#import() abort
|
||||
return map({'_vital_depends': '', 'doautocmd_user': '', 'get_cmdline': '', 'make': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#Doautocmd#import() abort', printf("return map({'_vital_depends': '', 'doautocmd_user': '', 'get_cmdline': '', 'make': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
function! s:_vital_loaded(V)
|
||||
let s:V = a:V
|
||||
let s:E = s:V.import("Over.Exception")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_vital_depends()
|
||||
return [
|
||||
\ "Over.Exception",
|
||||
\ ]
|
||||
endfunction
|
||||
|
||||
|
||||
let s:cache_command = {}
|
||||
function! s:doautocmd_user(prefix, command)
|
||||
let group = a:prefix . "-vital-over-commandline-doautocmd-dummy"
|
||||
if !has_key(s:cache_command, a:prefix)
|
||||
let s:cache_command[a:prefix] = {}
|
||||
endif
|
||||
|
||||
if !has_key(s:cache_command[a:prefix], a:command)
|
||||
execute "autocmd " . group
|
||||
\ . " User " . a:command." silent! execute ''"
|
||||
|
||||
if v:version > 703 || v:version == 703 && has("patch438")
|
||||
let s:cache_command[a:prefix][a:command] = "doautocmd <nomodeline> User " . a:command
|
||||
else
|
||||
let s:cache_command[a:prefix][a:command] = "doautocmd User " . a:command
|
||||
endif
|
||||
endif
|
||||
|
||||
execute s:cache_command[a:prefix][a:command]
|
||||
endfunction
|
||||
|
||||
|
||||
let s:hooks = [
|
||||
\ "enter",
|
||||
\ "leave",
|
||||
\ "char",
|
||||
\ "char_pre",
|
||||
\ "draw",
|
||||
\ "draw_pre",
|
||||
\ "execute_pre",
|
||||
\ "execute_failed",
|
||||
\ "execute",
|
||||
\ "exception",
|
||||
\]
|
||||
|
||||
let s:hooks_camel = [
|
||||
\ "Enter",
|
||||
\ "Leave",
|
||||
\ "Char",
|
||||
\ "CharPre",
|
||||
\ "Draw",
|
||||
\ "DrawPre",
|
||||
\ "ExecutePre",
|
||||
\ "ExecuteFailed",
|
||||
\ "Execute",
|
||||
\ "Exception",
|
||||
\]
|
||||
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "Doautocmd",
|
||||
\}
|
||||
|
||||
|
||||
for s:i in range(len(s:hooks))
|
||||
execute join([
|
||||
\ "function! s:module.on_" . s:hooks[s:i] . "(cmdline, ...)",
|
||||
\ " let s:cmdline = a:cmdline",
|
||||
\ " call s:doautocmd_user(self.prefix, self.prefix . " . string(s:hooks_camel[s:i]) . ")",
|
||||
\ "endfunction",
|
||||
\ ], "\n")
|
||||
endfor
|
||||
|
||||
|
||||
function! s:get_cmdline()
|
||||
if !exists("s:cmdline")
|
||||
execute s:E.throw_cmd("Undefined cmdline object.", "Over.Commandline.Modules.Doautocmd")
|
||||
endif
|
||||
return s:cmdline
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make(prefix)
|
||||
if has_key(s:cache_command, a:prefix)
|
||||
unlet! s:cache_command[a:prefix]
|
||||
endif
|
||||
execute "augroup " a:prefix . "-vital-over-commandline-doautocmd-dummy"
|
||||
autocmd!
|
||||
augroup END
|
||||
|
||||
let module = deepcopy(s:module)
|
||||
let module.prefix = a:prefix
|
||||
return module
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,155 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#DrawCommandline#import() abort
|
||||
return map({'suffix': '', 'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#DrawCommandline#import() abort', printf("return map({'suffix': '', 'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "DrawCommandline"
|
||||
\}
|
||||
|
||||
let s:cmdheight = {}
|
||||
|
||||
function! s:cmdheight.save()
|
||||
if has_key(self, "value")
|
||||
return
|
||||
endif
|
||||
let self.value = &cmdheight
|
||||
endfunction
|
||||
|
||||
function! s:cmdheight.restore()
|
||||
if has_key(self, "value")
|
||||
let &cmdheight = self.value
|
||||
unlet self.value
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:cmdheight.get()
|
||||
return self.value
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:suffix(left, suffix)
|
||||
let left_len = strdisplaywidth(a:left)
|
||||
let len = &columns - left_len % &columns
|
||||
let len = len + (&columns * (strdisplaywidth(a:suffix) > (len - 1))) - 1
|
||||
return repeat(" ", len - strdisplaywidth(a:suffix)) . a:suffix
|
||||
" return printf("%" . len . "S", a:suffix)
|
||||
endfunction
|
||||
|
||||
|
||||
let s:old_width = 0
|
||||
function! s:_redraw(cmdline)
|
||||
let left = a:cmdline.get_prompt() . a:cmdline.getline() . (empty(a:cmdline.line.pos_char()) ? " " : "")
|
||||
let width = len(left) + 1
|
||||
|
||||
if a:cmdline.get_suffix() != ""
|
||||
let width += len(s:suffix(left, a:cmdline.get_suffix())) - 1
|
||||
endif
|
||||
|
||||
if &columns >= width && &columns <= s:old_width && s:old_width >= width
|
||||
redraw
|
||||
normal! :
|
||||
elseif &columns <= width
|
||||
normal! :
|
||||
else
|
||||
redraw
|
||||
endif
|
||||
let s:old_width = width
|
||||
|
||||
call s:cmdheight.save()
|
||||
let height = max([(width - 1) / (&columns) + 1, s:cmdheight.get()])
|
||||
if height > &cmdheight || &cmdheight > height
|
||||
let &cmdheight = height
|
||||
redraw
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_as_echon(str)
|
||||
return "echon " . strtrans(string(a:str))
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_draw_pre(cmdline)
|
||||
if empty(a:cmdline.line.pos_char())
|
||||
let cursor = "echohl " . a:cmdline.highlights.cursor . " | echon ' '"
|
||||
else
|
||||
let cursor = "echohl " . a:cmdline.highlights.cursor_on . " | " . s:_as_echon(a:cmdline.line.pos_char())
|
||||
endif
|
||||
let suffix = ""
|
||||
if a:cmdline.get_suffix() != ""
|
||||
let suffix = s:_as_echon(s:suffix(a:cmdline.get_prompt() . a:cmdline.getline() . repeat(" ", empty(a:cmdline.line.pos_char())), a:cmdline.get_suffix()))
|
||||
endif
|
||||
let self.draw_command = join([
|
||||
\ "echohl " . a:cmdline.highlights.prompt,
|
||||
\ s:_as_echon(a:cmdline.get_prompt()),
|
||||
\ "echohl NONE",
|
||||
\ s:_as_echon(a:cmdline.backward()),
|
||||
\ cursor,
|
||||
\ "echohl NONE",
|
||||
\ s:_as_echon(a:cmdline.forward()),
|
||||
\ suffix,
|
||||
\ ], " | ")
|
||||
|
||||
call s:_redraw(a:cmdline)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_echon(expr)
|
||||
echon strtrans(a:expr)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_draw(cmdline)
|
||||
execute self.draw_command
|
||||
" execute "echohl" a:cmdline.highlights.prompt
|
||||
" call s:echon(a:cmdline.get_prompt())
|
||||
" echohl NONE
|
||||
" call s:echon(a:cmdline.backward())
|
||||
" if empty(a:cmdline.line.pos_char())
|
||||
" execute "echohl" a:cmdline.highlights.cursor
|
||||
" call s:echon(' ')
|
||||
" else
|
||||
" execute "echohl" a:cmdline.highlights.cursor_on
|
||||
" call s:echon(a:cmdline.line.pos_char())
|
||||
" endif
|
||||
" echohl NONE
|
||||
" call s:echon(a:cmdline.forward())
|
||||
" if a:cmdline.get_suffix() != ""
|
||||
" call s:echon(s:suffix(a:cmdline.get_prompt() . a:cmdline.getline() . repeat(" ", empty(a:cmdline.line.pos_char())), a:cmdline.get_suffix()))
|
||||
" endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_execute_pre(...)
|
||||
call s:cmdheight.restore()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_leave(...)
|
||||
call s:cmdheight.restore()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make()
|
||||
return deepcopy(s:module)
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,37 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#ExceptionExit#import() abort
|
||||
return map({'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#ExceptionExit#import() abort', printf("return map({'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "ExceptionExit",
|
||||
\}
|
||||
|
||||
|
||||
function! s:module.on_exception(cmdline)
|
||||
call a:cmdline.exit(-1)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make(...)
|
||||
let result = deepcopy(s:module)
|
||||
let result.exit_code = get(a:, 1, 0)
|
||||
return result
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,66 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#ExceptionMessage#import() abort
|
||||
return map({'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#ExceptionMessage#import() abort', printf("return map({'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
let s:vname = expand("<sfile>:h:h:h:h:t")
|
||||
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "ExceptionMessage",
|
||||
\}
|
||||
|
||||
|
||||
function! s:module.on_exception(cmdline)
|
||||
let self.exception = v:exception
|
||||
let self.throwpoint = v:throwpoint
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_draw_pre(cmdline)
|
||||
if has_key(self, "exception")
|
||||
call self.message(a:cmdline)
|
||||
unlet self.exception
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:module.message(...)
|
||||
echohl ErrorMsg
|
||||
execute self.command string(self.prefix . " : " . self.throwpoint . " " . self.exception)
|
||||
echohl None
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_leave(cmdline)
|
||||
if has_key(self, "exception")
|
||||
call self.message(a:cmdline)
|
||||
unlet self.exception
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make(...)
|
||||
let result = deepcopy(s:module)
|
||||
let result.prefix = get(a:, 1, "vital-over(".s:vname.") Exception")
|
||||
let result.command = get(a:, 2, "echom")
|
||||
return result
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,40 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#Exit#import() abort
|
||||
return map({'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#Exit#import() abort', printf("return map({'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "Exit",
|
||||
\ "exit_code" : 0
|
||||
\}
|
||||
|
||||
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if a:cmdline.is_input("<Over>(exit)")
|
||||
call a:cmdline.setchar("")
|
||||
call a:cmdline.exit(self.exit_code)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make()
|
||||
return deepcopy(s:module)
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,75 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#History#import() abort
|
||||
return map({'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#History#import() abort', printf("return map({'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "History",
|
||||
\ "mode" : "cmd",
|
||||
\}
|
||||
|
||||
function! s:module.histories()
|
||||
return map(range(1, &history), 'histget(self.mode, v:val * -1)')
|
||||
endfunction
|
||||
|
||||
function! s:_should_match_cmdline(cmdline)
|
||||
return a:cmdline.is_input("\<Up>")
|
||||
\ || a:cmdline.is_input("\<Down>")
|
||||
endfunction
|
||||
|
||||
function! s:_reset()
|
||||
let s:cmdhist = []
|
||||
let s:count = 0
|
||||
let s:is_match_mode = 0 " <Up>/<Down>: true, <C-n>/<C-p>: false
|
||||
endfunction
|
||||
|
||||
function! s:module.on_enter(...)
|
||||
call s:_reset()
|
||||
endfunction
|
||||
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if !a:cmdline.is_input("\<Up>") && !a:cmdline.is_input("\<Down>")
|
||||
\ && !a:cmdline.is_input("\<C-p>") && !a:cmdline.is_input("\<C-n>")
|
||||
call s:_reset()
|
||||
return
|
||||
else
|
||||
if s:count == 0 && empty(s:cmdhist)
|
||||
\ || s:is_match_mode != s:_should_match_cmdline(a:cmdline)
|
||||
let cmdline = '^' . a:cmdline.getline()
|
||||
let s:is_match_mode = s:_should_match_cmdline(a:cmdline)
|
||||
let s:cmdhist = [a:cmdline.getline()] + (s:is_match_mode ?
|
||||
\ filter(self.histories(), 'v:val =~ cmdline') : self.histories())
|
||||
endif
|
||||
endif
|
||||
call a:cmdline.setchar("")
|
||||
if a:cmdline.is_input("\<Down>") || a:cmdline.is_input("\<C-n>")
|
||||
let s:count = max([s:count - 1, 0])
|
||||
endif
|
||||
if a:cmdline.is_input("\<Up>") || a:cmdline.is_input("\<C-p>")
|
||||
let s:count = min([s:count + 1, len(s:cmdhist)])
|
||||
endif
|
||||
call a:cmdline.setline(get(s:cmdhist, s:count, a:cmdline.getline()))
|
||||
endfunction
|
||||
|
||||
function! s:make(...)
|
||||
let module = deepcopy(s:module)
|
||||
let module.mode = get(a:, 1, "cmd")
|
||||
return module
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,164 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#InsertRegister#import() abort
|
||||
return map({'_vital_depends': '', 'to_string': '', 'input': '', 'get_cmdline_cword': '', 'make': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#InsertRegister#import() abort', printf("return map({'_vital_depends': '', 'to_string': '', 'input': '', 'get_cmdline_cword': '', 'make': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
function! s:_vital_loaded(V)
|
||||
let s:V = a:V
|
||||
let s:String = s:V.import("Over.String")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_vital_depends()
|
||||
return [
|
||||
\ "Over.String",
|
||||
\ ]
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:to_string(expr)
|
||||
return type(a:expr) == type("") ? a:expr : string(a:expr)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:input(cmdline)
|
||||
let CR_index = index(a:cmdline.input_key_stack(), "\<CR>")
|
||||
if CR_index != -1
|
||||
let input = a:cmdline.input_key_stack_string()
|
||||
let input = input[ : CR_index-1]
|
||||
call a:cmdline.set_input_key_stack(a:cmdline.input_key_stack()[CR_index+1 : ])
|
||||
return eval(input)
|
||||
endif
|
||||
|
||||
let input_text = ""
|
||||
if !empty(a:cmdline.input_key_stack())
|
||||
let input_text = a:cmdline.input_key_stack_string()
|
||||
call a:cmdline.set_input_key_stack([])
|
||||
endif
|
||||
|
||||
call a:cmdline.hl_cursor_on()
|
||||
try
|
||||
redraw
|
||||
let input = input("=", input_text, "expression")
|
||||
if !empty(input)
|
||||
let input = s:to_string(eval(input))
|
||||
endif
|
||||
catch
|
||||
return ""
|
||||
finally
|
||||
call a:cmdline.hl_cursor_off()
|
||||
endtry
|
||||
return input
|
||||
endfunction
|
||||
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "InsertRegister"
|
||||
\}
|
||||
|
||||
|
||||
|
||||
function! s:module.reset()
|
||||
let self.cword = expand("<cword>")
|
||||
let self.cWORD = expand("<cWORD>")
|
||||
let self.cfile = expand("<cfile>")
|
||||
endfunction
|
||||
|
||||
function! s:module.on_enter(...)
|
||||
call self.reset()
|
||||
" let self.prefix_key = ""
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:get_cmdline_cword(backward, cword)
|
||||
" let backward = matchstr(a:backward, '.\{-}\zs\k\+$')
|
||||
let backward = a:backward
|
||||
if &incsearch == 0 || a:cword == "" || a:backward == "" || s:String.index(a:cword, backward) != 0
|
||||
return a:cword
|
||||
endif
|
||||
return a:cword[len(backward) : ]
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if a:cmdline.is_input("\<C-r>")
|
||||
call a:cmdline.setchar('"')
|
||||
let self.prefix_key = a:cmdline.input_key()
|
||||
let self.old_line = a:cmdline.getline()
|
||||
let self.old_pos = a:cmdline.getpos()
|
||||
return
|
||||
elseif exists("self.prefix_key")
|
||||
\ && a:cmdline.get_tap_key() == self.prefix_key
|
||||
call a:cmdline.setline(self.old_line)
|
||||
call a:cmdline.setpos(self.old_pos)
|
||||
let char = a:cmdline.input_key()
|
||||
if char =~ '^[0-9a-zA-z.%#:/"\-*+]$'
|
||||
let register = tr(getreg(char), "\n", "\r")
|
||||
call a:cmdline.setchar(register)
|
||||
elseif char == "="
|
||||
call a:cmdline.setchar(s:input(a:cmdline))
|
||||
elseif char == "\<C-w>"
|
||||
call a:cmdline.setchar(s:get_cmdline_cword(a:cmdline.backward_word(), self.cword))
|
||||
elseif char == "\<C-a>"
|
||||
call a:cmdline.setchar(self.cWORD)
|
||||
elseif char == "\<C-f>"
|
||||
call a:cmdline.setchar(self.cfile)
|
||||
elseif char == "\<C-r>"
|
||||
call a:cmdline.setchar('"')
|
||||
else
|
||||
call a:cmdline.setchar("")
|
||||
endif
|
||||
" elseif a:cmdline.is_input('=', self.prefix_key)
|
||||
" call a:cmdline.setchar(s:input(a:cmdline))
|
||||
" elseif a:cmdline.is_input("\<C-w>", self.prefix_key)
|
||||
" call a:cmdline.setchar(self.cword)
|
||||
" elseif a:cmdline.is_input("\<C-a>", self.prefix_key)
|
||||
" call a:cmdline.setchar(self.cWORD)
|
||||
" elseif a:cmdline.is_input("\<C-f>", self.prefix_key)
|
||||
" call a:cmdline.setchar(self.cfile)
|
||||
" elseif a:cmdline.is_input("\<C-r>", self.prefix_key)
|
||||
" call a:cmdline.setchar('"')
|
||||
" else
|
||||
" call a:cmdline.setchar("")
|
||||
" endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_char(cmdline)
|
||||
if a:cmdline.is_input("\<C-r>")
|
||||
call a:cmdline.tap_keyinput(self.prefix_key)
|
||||
call a:cmdline.disable_keymapping()
|
||||
call a:cmdline.setpos(a:cmdline.getpos()-1)
|
||||
else
|
||||
if exists("self.prefix_key")
|
||||
call a:cmdline.untap_keyinput(self.prefix_key)
|
||||
call a:cmdline.enable_keymapping()
|
||||
unlet! self.prefix_key
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
|
||||
function! s:make()
|
||||
return deepcopy(s:module)
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,139 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#KeyMapping#import() abort
|
||||
return map({'_vital_depends': '', 'make_emacs': '', 'make_vim_cmdline_mapping': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#KeyMapping#import() abort', printf("return map({'_vital_depends': '', 'make_emacs': '', 'make_vim_cmdline_mapping': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
function! s:_vital_loaded(V)
|
||||
let s:Keymapping = a:V.import("Palette.Keymapping")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_vital_depends()
|
||||
return [
|
||||
\ "Palette.Keymapping",
|
||||
\ ]
|
||||
endfunction
|
||||
|
||||
|
||||
let s:emacs = {
|
||||
\ "name" : "KeyMapping_emacs_like"
|
||||
\}
|
||||
|
||||
function! s:emacs.keymapping(cmdline)
|
||||
return {
|
||||
\ "\<C-f>" : {
|
||||
\ "key" : "\<Right>",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ "\<C-b>" : {
|
||||
\ "key" : "\<Left>",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ "\<C-n>" : {
|
||||
\ "key" : "\<Down>",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ "\<C-p>" : {
|
||||
\ "key" : "\<Up>",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ "\<C-a>" : {
|
||||
\ "key" : "\<Home>",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ "\<C-e>" : {
|
||||
\ "key" : "\<End>",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ "\<C-d>" : {
|
||||
\ "key" : "\<Del>",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ "\<A-d>" : {
|
||||
\ "key" : "\<C-w>",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ "\<A-b>" : {
|
||||
\ "key" : "\<S-Left>",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ "\<A-f>" : {
|
||||
\ "key" : "\<S-Right>",
|
||||
\ "noremap" : 1,
|
||||
\ "lock" : 1,
|
||||
\ },
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make_emacs()
|
||||
return deepcopy(s:emacs)
|
||||
endfunction
|
||||
|
||||
|
||||
let s:vim_cmdline_mapping = {
|
||||
\ "name" : "KeyMapping_vim_cmdline_mapping",
|
||||
\ "_cmaps" : {}
|
||||
\}
|
||||
|
||||
function! s:_convert_sid(rhs, sid) abort
|
||||
return substitute(a:rhs, '<SID>', '<SNR>' . a:sid . '_', 'g')
|
||||
endfunction
|
||||
|
||||
function! s:_auto_cmap()
|
||||
let cmaps = {}
|
||||
let cmap_info = s:Keymapping.rhs_key_list("c", 0, 1)
|
||||
" vital-over currently doesn't support <buffer> mappings
|
||||
for c in filter(cmap_info, "v:val['buffer'] ==# 0")
|
||||
let cmaps[s:Keymapping.escape_special_key(c['lhs'])] = {
|
||||
\ 'noremap' : c['noremap'],
|
||||
\ 'key' : s:Keymapping.escape_special_key(s:_convert_sid(c['rhs'], c['sid'])),
|
||||
\ 'expr' : s:Keymapping.escape_special_key(c['expr']),
|
||||
\ }
|
||||
endfor
|
||||
return cmaps
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:vim_cmdline_mapping.on_enter(cmdline)
|
||||
let self._cmaps = s:_auto_cmap()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:vim_cmdline_mapping.keymapping(cmdline)
|
||||
return self._cmaps
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make_vim_cmdline_mapping()
|
||||
return deepcopy(s:vim_cmdline_mapping)
|
||||
endfunction
|
||||
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,55 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#NoInsert#import() abort
|
||||
return map({'make_special_chars': '', 'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#NoInsert#import() abort', printf("return map({'make_special_chars': '', 'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "NoInsert",
|
||||
\ "chars" : []
|
||||
\}
|
||||
|
||||
|
||||
function! s:module.is_no_insert(char)
|
||||
return index(self.chars, a:char) >= 0
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if self.is_no_insert(a:cmdline.char())
|
||||
call a:cmdline.setchar("", 0)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make(chars)
|
||||
let module = deepcopy(s:module)
|
||||
let module.chars = type(a:chars) == type([]) ? a:chars : [a:chars]
|
||||
return module
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make_special_chars()
|
||||
let module = s:make([])
|
||||
function! module.is_no_insert(char)
|
||||
return char2nr(a:char) == 128 || char2nr(a:char) < 27
|
||||
endfunction
|
||||
return module
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,40 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#Paste#import() abort
|
||||
return map({'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#Paste#import() abort', printf("return map({'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "Paste"
|
||||
\}
|
||||
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if a:cmdline.is_input("<Over>(paste)")
|
||||
let register = v:register == "" ? '"' : v:register
|
||||
call a:cmdline.insert(tr(getreg("*"), "\n", "\r"))
|
||||
call a:cmdline.setchar('')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make()
|
||||
return deepcopy(s:module)
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,72 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Commandline#Modules#Redraw#import() abort
|
||||
return map({'make': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Commandline#Modules#Redraw#import() abort', printf("return map({'make': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "Redraw",
|
||||
\}
|
||||
|
||||
function! s:module.on_execute_pre(cmdline)
|
||||
call self.redraw(a:cmdline)
|
||||
endfunction
|
||||
|
||||
function! s:module.on_enter(...)
|
||||
let self.is_execute = 0
|
||||
endfunction
|
||||
|
||||
function! s:module.on_execute(...)
|
||||
let self.is_execute = 1
|
||||
endfunction
|
||||
|
||||
function! s:module.on_execute_failed(...)
|
||||
let self.is_execute = 0
|
||||
endfunction
|
||||
|
||||
function! s:module.on_leave(cmdline)
|
||||
if self.is_execute == 0 && a:cmdline.exit_code() != -1
|
||||
call self.redraw(a:cmdline)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
" function! s:module.on_draw_pre(cmdline)
|
||||
" call self.redraw(a:cmdline)
|
||||
" endfunction
|
||||
|
||||
|
||||
function! s:module.redraw(cmdline)
|
||||
redraw
|
||||
" Workaround for the :set cedit=<C-c>
|
||||
" https://github.com/osyo-manga/vital-over/issues/52
|
||||
" https://github.com/Lokaltog/vim-easymotion/issues/177#issuecomment-53663431
|
||||
if &cedit != "<C-c>"
|
||||
\ ||(v:version > 704 || v:version == 704 && has("patch441"))
|
||||
normal! :
|
||||
else
|
||||
execute "normal! :\<Esc>"
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:make()
|
||||
return deepcopy(s:module)
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,46 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Exception#import() abort
|
||||
return map({'throw': '', 'throw_cmd': '', 'set_prefix': '', 'error': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Exception#import() abort', printf("return map({'throw': '', 'throw_cmd': '', 'set_prefix': '', 'error': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
let s:vname = expand("<sfile>:h:h:t")
|
||||
let s:prefix = printf("vital-over(%s) Exception", s:vname)
|
||||
|
||||
function! s:set_prefix(prefix)
|
||||
let s:prefix = a:prefix
|
||||
endfunction
|
||||
|
||||
function! s:throw_cmd(exp, where)
|
||||
return 'throw ' . string(s:prefix . " : " . a:exp . " in " . a:where)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:throw(exp, where)
|
||||
execute s:throw_cmd(a:exp, a:where)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:error(text, where)
|
||||
echohl ErrorMsg
|
||||
echom s:prefix . " : " . a:text . " in " . a:where
|
||||
echohl None
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,40 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Input#import() abort
|
||||
return map({'getchar': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Input#import() abort', printf("return map({'getchar': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
function! s:getchar(...)
|
||||
let mode = get(a:, 1, 0)
|
||||
while 1
|
||||
" Workaround for https://github.com/osyo-manga/vital-over/issues/53
|
||||
try
|
||||
let char = call("getchar", a:000)
|
||||
catch /^Vim:Interrupt$/
|
||||
let char = 3 " <C-c>
|
||||
endtry
|
||||
" Workaround for the <expr> mappings
|
||||
if string(char) !=# "\x80\xfd`"
|
||||
return mode == 1 ? !!char
|
||||
\ : type(char) == type(0) ? nr2char(char) : char
|
||||
endif
|
||||
endwhile
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,95 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Keymapping#import() abort
|
||||
return map({'_vital_depends': '', 'unmapping': '', 'as_key_config': '', 'match_key': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Keymapping#import() abort', printf("return map({'_vital_depends': '', 'unmapping': '', 'as_key_config': '', 'match_key': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
|
||||
function! s:_vital_loaded(V)
|
||||
let s:V = a:V
|
||||
let s:String = s:V.import("Over.String")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_vital_depends()
|
||||
return [
|
||||
\ "Over.String",
|
||||
\ ]
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:as_key_config(config)
|
||||
let base = {
|
||||
\ "noremap" : 0,
|
||||
\ "lock" : 0,
|
||||
\ "expr" : 0,
|
||||
\ }
|
||||
return type(a:config) == type({}) ? extend(base, a:config)
|
||||
\ : extend(base, {
|
||||
\ "key" : a:config,
|
||||
\ })
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:match_key(keymapping, key)
|
||||
let keys = sort(keys(a:keymapping))
|
||||
return get(filter(keys, 'stridx(a:key, v:val) == 0'), -1, '')
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_safe_eval(expr, ...)
|
||||
call extend(l:, get(a:, 1, {}))
|
||||
let result = get(a:, 2, "")
|
||||
try
|
||||
let result = eval(a:expr)
|
||||
catch
|
||||
echohl ErrorMsg | echom v:exception | echohl None
|
||||
endtry
|
||||
return result
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_get_key(conf)
|
||||
" call extend(l:, a:conf)
|
||||
let self = a:conf
|
||||
return get(a:conf, "expr", 0) ? s:_safe_eval(a:conf.key, l:) : a:conf.key
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:unmapping(keymapping, key, ...)
|
||||
let is_locking = get(a:, 1, 0)
|
||||
let key = s:match_key(a:keymapping, a:key)
|
||||
if key == ""
|
||||
return s:String.length(a:key) <= 1 ? a:key : s:unmapping(a:keymapping, a:key[0], is_locking) . s:unmapping(a:keymapping, a:key[1:], is_locking)
|
||||
endif
|
||||
|
||||
let map_conf = s:as_key_config(a:keymapping[key])
|
||||
|
||||
let next_input = s:unmapping(a:keymapping, a:key[len(key) : ], is_locking)
|
||||
if map_conf.lock == 0 && is_locking
|
||||
return key . next_input
|
||||
elseif map_conf.lock
|
||||
return s:unmapping(a:keymapping, s:_get_key(map_conf), is_locking) . next_input
|
||||
else
|
||||
return s:unmapping(a:keymapping, s:_get_key(map_conf), map_conf.noremap) . next_input
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,119 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#Signals#import() abort
|
||||
return map({'_vital_depends': '', 'call': '', 'make': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#Signals#import() abort', printf("return map({'_vital_depends': '', 'call': '', 'make': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
function! s:_vital_loaded(V)
|
||||
let s:V = a:V
|
||||
let s:L = s:V.import("Data.List")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_vital_depends()
|
||||
return ["Data.List"]
|
||||
endfunction
|
||||
|
||||
|
||||
let s:base = {
|
||||
\ "variables" : {
|
||||
\ "slots" : [],
|
||||
\ "counter" : 0,
|
||||
\ }
|
||||
\}
|
||||
|
||||
|
||||
function! s:base.connect(slot)
|
||||
let self.variables.counter += 1
|
||||
let slot = { "id" : self.variables.counter, "slot" : a:slot }
|
||||
call add(self.variables.slots, slot)
|
||||
return slot
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.disconnect(slot)
|
||||
if empty(a:slot)
|
||||
return -1
|
||||
endif
|
||||
for i in range(len(self.variables.slots))
|
||||
if self.variables.slots[i].id == a:slot.id
|
||||
unlet self.variables.slots[i]
|
||||
return
|
||||
endif
|
||||
endfor
|
||||
return -1
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.disconnect_by(expr)
|
||||
return self.disconnect(self.find_first_by(a:expr))
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:call(list, func, ...)
|
||||
let args = get(a:, 1, [])
|
||||
let def = get(a:, 2, 0)
|
||||
return map(copy(a:list), "has_key(v:val, a:func) ? call(v:val.".a:func.", args, v:val) : def")
|
||||
endfunction
|
||||
|
||||
function! s:base.call(func, ...)
|
||||
return call("s:call", [self.slots(), a:func] + a:000)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.find_by(expr)
|
||||
return filter(copy(self.variables.slots), a:expr)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.find_first_by(expr)
|
||||
return get(self.find_by(a:expr), 0, {})
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.sort_by(expr)
|
||||
let self.variables.slots = s:L.sort_by(self.variables.slots, a:expr)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.get_slot(val)
|
||||
return a:val.slot
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.slots()
|
||||
return map(copy(self.variables.slots), "self.get_slot(v:val)")
|
||||
endfunction
|
||||
|
||||
|
||||
" function! s:base.dict()
|
||||
" let result = {}
|
||||
" for _ in self.variables.slots
|
||||
" let result[_.id] = _.value
|
||||
" endfor
|
||||
" return result
|
||||
" endfunction
|
||||
|
||||
|
||||
function! s:make()
|
||||
let result = deepcopy(s:base)
|
||||
return result
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,164 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Over#String#import() abort
|
||||
return map({'_vital_depends': '', 'length': '', 'index': '', 'split_by_keys': '', 'make': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Over#String#import() abort', printf("return map({'_vital_depends': '', 'length': '', 'index': '', 'split_by_keys': '', 'make': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
function! s:_vital_loaded(V)
|
||||
let s:V = a:V
|
||||
let s:List = s:V.import("Data.List")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_vital_depends()
|
||||
return [
|
||||
\ "Data.List",
|
||||
\ ]
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_clamp(x, max, min)
|
||||
return min([max([a:x, a:max]), a:min])
|
||||
endfunction
|
||||
|
||||
|
||||
let s:base = {}
|
||||
|
||||
function! s:base.set(item)
|
||||
return type(a:item) == type("") ? self.set_str(a:item)
|
||||
\ : type(a:item) == type(0) ? self.set_pos(a:item)
|
||||
\ : self
|
||||
endfunction
|
||||
|
||||
function! s:base.str()
|
||||
return join(self.list, "")
|
||||
endfunction
|
||||
|
||||
function! s:base.set_pos(pos)
|
||||
let self.col = s:_clamp(a:pos, 0, self.length())
|
||||
return self
|
||||
endfunction
|
||||
|
||||
function! s:base.backward()
|
||||
return self.col > 0 ? join(self.list[ : self.col-1], '') : ""
|
||||
endfunction
|
||||
|
||||
function! s:base.forward()
|
||||
return join(self.list[self.col+1 : ], '')
|
||||
endfunction
|
||||
|
||||
function! s:base.pos_char()
|
||||
return get(self.list, self.col, "")
|
||||
endfunction
|
||||
|
||||
function! s:base.set_str(str)
|
||||
let self.list = split(a:str, '\zs')
|
||||
let self.col = strchars(a:str)
|
||||
return self
|
||||
endfunction
|
||||
|
||||
function! s:base.pos()
|
||||
return self.col
|
||||
endfunction
|
||||
|
||||
function! s:base.input(str)
|
||||
call extend(self.list, split(a:str, '\zs'), self.col)
|
||||
let self.col += len(split(a:str, '\zs'))
|
||||
return self
|
||||
endfunction
|
||||
|
||||
function! s:base.length()
|
||||
return len(self.list)
|
||||
endfunction
|
||||
|
||||
function! s:base.next()
|
||||
return self.set_pos(self.col + 1)
|
||||
endfunction
|
||||
|
||||
function! s:base.prev()
|
||||
return self.set_pos(self.col - 1)
|
||||
endfunction
|
||||
|
||||
function! s:base.remove(index)
|
||||
if a:index < 0 || self.length() <= a:index
|
||||
return ""
|
||||
endif
|
||||
let result = self.list[a:index]
|
||||
unlet self.list[a:index]
|
||||
if a:index < self.col
|
||||
call self.set(self.col - 1)
|
||||
endif
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! s:base.remove_pos()
|
||||
return self.remove(self.col)
|
||||
endfunction
|
||||
|
||||
function! s:base.remove_prev()
|
||||
return self.remove(self.col - 1)
|
||||
endfunction
|
||||
|
||||
function! s:base.remove_next()
|
||||
return self.remove(self.col + 1)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make(...)
|
||||
let default = get(a:, 1, "")
|
||||
let result = deepcopy(s:base)
|
||||
call result.set(default)
|
||||
return result
|
||||
endfunction
|
||||
|
||||
" NOTE: old regexpengine has a bug with string which contains binary
|
||||
" :echo "\x80" =~ "\\%#=1\x80" | " => 0
|
||||
" But it matches correctly with :h /collection
|
||||
" :echo "\x80" =~ "\\%#=1[\x80]" | " => 1
|
||||
" http://lingr.com/room/vim/archives/2015/02/13#message-21261450
|
||||
let s:_engine = exists("+regexpengine") ? '\%#=2' : ''
|
||||
" \<A-]> => Û\xfdQ
|
||||
" \<A-@> => À\xfeX
|
||||
let s:_regex = exists("+regexpengine")
|
||||
\ ? "\\%(Û\xfdQ\\|À\xfeX\\|\x80\xfc.\\%(\x80..\\|.\\)\\|\x80..\\|.\\)\\zs"
|
||||
\ : "\\%(Û[\xfd]Q\\|À[\xfe]X\\|[\x80][\xfc].\\%([\x80]..\\|.\\)\\|[\x80]..\\|.\\)\\zs"
|
||||
function! s:_split_keystring(str, ...)
|
||||
return split(a:str, s:_engine . '\m\%(' . get(a:, 1, '') . s:_regex . '\)')
|
||||
endfunction
|
||||
|
||||
function! s:split_by_keys(str)
|
||||
return s:_split_keystring(a:str, "\\%(\<Plug>\\|<Over>\\)(.\\{-})\\zs\\|")
|
||||
endfunction
|
||||
|
||||
function! s:index(haystack, needle, ...)
|
||||
let start = get(a:, 1, 0)
|
||||
let ignorecase = get(a:, 2, &ignorecase)
|
||||
if ignorecase
|
||||
return stridx(tolower(a:haystack), tolower(a:needle), start)
|
||||
else
|
||||
return stridx(a:haystack, a:needle, start)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:length(str)
|
||||
return len(s:split_by_keys(a:str))
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,74 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Palette#Capture#import() abort
|
||||
return map({'extend': '', 'command': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Palette#Capture#import() abort', printf("return map({'extend': '', 'command': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
let s:verbosefiles = []
|
||||
|
||||
function! s:_verbosefile_push(file)
|
||||
call add(s:verbosefiles, &verbosefile)
|
||||
let &verbosefile = a:file
|
||||
return a:file
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_verbosefile_pop()
|
||||
let filename = &verbosefile
|
||||
let &verbosefile = get(s:verbosefiles, -1)
|
||||
call remove(s:verbosefiles, -1)
|
||||
return filename
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_reset()
|
||||
let s:verbosefiles = []
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:extend(dict, src)
|
||||
for [key, value] in items(a:src)
|
||||
let a:dict[key] = value
|
||||
unlet value
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:command(cmd, ...)
|
||||
" Workaround : Vim 7.3.xxx in Travis and Ubuntu
|
||||
" https://github.com/osyo-manga/vital-palette/issues/5
|
||||
" call extend(l:, get(a:, 1, {}))
|
||||
if a:0 > 0
|
||||
call s:extend(l:, a:1)
|
||||
endif
|
||||
|
||||
call s:_verbosefile_push(tempname())
|
||||
try
|
||||
redir =>result
|
||||
silent execute a:cmd
|
||||
finally
|
||||
redir END
|
||||
endtry
|
||||
call s:_verbosefile_pop()
|
||||
" let result = substitute(result, "<SRN>", "\<SNR>", "g")
|
||||
" let result = substitute(result, "<SID>", "\<SID>", "g")
|
||||
return result
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,133 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Palette#Highlight#import() abort
|
||||
return map({'capture': '', '_vital_depends': '', 'parse': '', 'group_list': '', 'set': '', 'parse_to_name': '', 'links_to': '', 'get': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Palette#Highlight#import() abort', printf("return map({'capture': '', '_vital_depends': '', 'parse': '', 'group_list': '', 'set': '', 'parse_to_name': '', 'links_to': '', 'get': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
function! s:_vital_loaded(V)
|
||||
let s:V = a:V
|
||||
let s:Message = s:V.import("Vim.Message")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_vital_depends()
|
||||
return [
|
||||
\ "Vim.Message",
|
||||
\ ]
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_execute(cmd)
|
||||
execute a:cmd
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:capture(name)
|
||||
if hlexists(a:name) == 0
|
||||
return ""
|
||||
endif
|
||||
return s:Message.capture("highlight " . a:name)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:links_to(highlight)
|
||||
return matchstr(a:highlight, '^\S\+\s\+xxx links to \zs.*\ze$')
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:parse_to_name(highlight)
|
||||
return matchstr(a:highlight, '^\zs\w\+\ze')
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:parse(highlight)
|
||||
let highlight = a:highlight
|
||||
|
||||
if highlight !~# '^\w\+\s\+xxx\s'
|
||||
return {}
|
||||
endif
|
||||
|
||||
let name = s:parse_to_name(a:highlight)
|
||||
let result = { "_name" : name }
|
||||
|
||||
if highlight =~# '^\w\+\s\+xxx cleared'
|
||||
let result.cleared = 1
|
||||
return result
|
||||
endif
|
||||
|
||||
let link = s:links_to(highlight)
|
||||
if link != ""
|
||||
let result.link = link
|
||||
return result
|
||||
endif
|
||||
|
||||
let attrs = [
|
||||
\ "term",
|
||||
\ "cterm",
|
||||
\ "ctermfg",
|
||||
\ "ctermbg",
|
||||
\ "gui",
|
||||
\ "font",
|
||||
\ "guifg",
|
||||
\ "guibg",
|
||||
\ "guisp",
|
||||
\ ]
|
||||
for attr in attrs
|
||||
let item = matchstr(highlight, '\s' . attr . '=\zs#\?\w\+\ze')
|
||||
if item != ""
|
||||
let result[attr] = item
|
||||
endif
|
||||
endfor
|
||||
return result
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:get(name, ...)
|
||||
if !hlexists(a:name)
|
||||
return {}
|
||||
endif
|
||||
let result = s:parse(substitute(s:capture(a:name), "\n", "", "g"))
|
||||
if has_key(result, "link") && get(a:, 1, 0)
|
||||
return s:get(result.link, get(a:, 1, 0))
|
||||
else
|
||||
return result
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:set(name, config)
|
||||
if type(a:config) == type("")
|
||||
return s:set(a:config, s:get(a:config))
|
||||
endif
|
||||
if has_key(a:config, "cleared")
|
||||
return s:_execute("highlight clear " . a:name)
|
||||
endif
|
||||
if has_key(a:config, "link")
|
||||
return s:_execute("highlight link " . a:name . " " . a:config.link)
|
||||
endif
|
||||
return s:_execute("highlight " . a:name . " " . join(map(items(filter(a:config, "v:key !=# '_name'")), "v:val[0] . '=' . v:val[1]"), " "))
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:group_list()
|
||||
let highlights = split(s:Message.capture("highlight"), "\n")
|
||||
return filter(map(highlights, "s:parse_to_name(v:val)"), "v:val != ''")
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,121 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Palette#Keymapping#import() abort
|
||||
return map({'capture': '', '_vital_depends': '', 'escape_special_key': '', 'rhs_key_list': '', 'parse_lhs_list': '', 'lhs_key_list': '', 'capture_list': '', 'parse_lhs': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Palette#Keymapping#import() abort', printf("return map({'capture': '', '_vital_depends': '', 'escape_special_key': '', 'rhs_key_list': '', 'parse_lhs_list': '', 'lhs_key_list': '', 'capture_list': '', 'parse_lhs': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
let s:modep = "[nvoicsxl]"
|
||||
|
||||
|
||||
function! s:_vital_loaded(V)
|
||||
let s:V = a:V
|
||||
let s:Capture = s:V.import("Palette.Capture")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_vital_depends()
|
||||
return [
|
||||
\ "Palette.Capture",
|
||||
\ ]
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_capture(mode)
|
||||
let cmd = "map"
|
||||
if a:mode ==# "!"
|
||||
let cmd = cmd . "!"
|
||||
elseif a:mode =~# "[nvoicsxl]"
|
||||
let cmd = a:mode . cmd
|
||||
endif
|
||||
return s:Capture.command(cmd)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:capture(...)
|
||||
let mode = get(a:, 1, "")
|
||||
let modes = split(mode, '\zs')
|
||||
return join(map(modes, "s:_capture(v:val)"), "\n")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_keymapping(str)
|
||||
return a:str =~ '^[!nvoicsxl]\s'
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:capture_list(...)
|
||||
let mode = get(a:, 1, "")
|
||||
return filter(split(s:capture(mode), "\n"), "s:_keymapping(v:val)")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:escape_special_key(key)
|
||||
" Workaround : <C-?> https://github.com/osyo-manga/vital-palette/issues/5
|
||||
if a:key ==# "<^?>"
|
||||
return "\<C-?>"
|
||||
endif
|
||||
execute 'let result = "' . substitute(escape(a:key, '\"'), '\(<.\{-}>\)', '\\\1', 'g') . '"'
|
||||
return result
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:parse_lhs(text, ...)
|
||||
let mode = get(a:, 1, '[!nvoicsxl]')
|
||||
" NOTE: :map! Surpport : https://github.com/osyo-manga/vital-palette/issues/4
|
||||
if get(a:, 1, "") =~# '[!ci]'
|
||||
let mode = '[!ci]'
|
||||
endif
|
||||
return matchstr(a:text, mode . '\{1,3\}\s*\zs\S\{-}\ze\s\+')
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:parse_lhs_list(...)
|
||||
let mode = get(a:, 1, "")
|
||||
return map(s:capture_list(mode), "s:parse_lhs(v:val, mode)")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:lhs_key_list(...)
|
||||
let mode = get(a:, 1, "")
|
||||
return map(s:parse_lhs_list(mode), "s:escape_special_key(v:val)")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_maparg(name, mode, abbr, dict)
|
||||
" Workaround : <C-?> https://github.com/osyo-manga/vital-palette/issues/5
|
||||
if a:name ==# "<^?>"
|
||||
return maparg("\<C-?>", a:mode, a:abbr, a:dict)
|
||||
endif
|
||||
return maparg(a:name, a:mode, a:abbr, a:dict)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:rhs_key_list(...)
|
||||
let mode = get(a:, 1, "")
|
||||
let abbr = get(a:, 2, 0)
|
||||
let dict = get(a:, 3, 0)
|
||||
|
||||
let result = []
|
||||
for m in split(mode, '\zs')
|
||||
let result += map(s:parse_lhs_list(m), "s:_maparg(v:val, m, abbr, dict)")
|
||||
endfor
|
||||
return filter(result, "empty(v:val) == 0")
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,430 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Prelude#import() abort
|
||||
return map({'escape_pattern': '', 'is_funcref': '', 'path2directory': '', 'wcswidth': '', 'is_string': '', 'input_helper': '', 'is_number': '', 'is_cygwin': '', 'path2project_directory': '', 'strwidthpart_reverse': '', 'input_safe': '', 'is_list': '', 'truncate_skipping': '', 'glob': '', 'truncate': '', 'is_dict': '', 'set_default': '', 'is_numeric': '', 'getchar_safe': '', 'substitute_path_separator': '', 'is_mac': '', 'strwidthpart': '', 'getchar': '', 'is_unix': '', 'is_windows': '', 'globpath': '', 'escape_file_searching': '', 'is_float': '', 'smart_execute_command': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Prelude#import() abort', printf("return map({'escape_pattern': '', 'is_funcref': '', 'path2directory': '', 'wcswidth': '', 'is_string': '', 'input_helper': '', 'is_number': '', 'is_cygwin': '', 'path2project_directory': '', 'strwidthpart_reverse': '', 'input_safe': '', 'is_list': '', 'truncate_skipping': '', 'glob': '', 'truncate': '', 'is_dict': '', 'set_default': '', 'is_numeric': '', 'getchar_safe': '', 'substitute_path_separator': '', 'is_mac': '', 'strwidthpart': '', 'getchar': '', 'is_unix': '', 'is_windows': '', 'globpath': '', 'escape_file_searching': '', 'is_float': '', 'smart_execute_command': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
if v:version > 703 ||
|
||||
\ (v:version == 703 && has('patch465'))
|
||||
function! s:glob(expr) abort
|
||||
return glob(a:expr, 1, 1)
|
||||
endfunction
|
||||
else
|
||||
function! s:glob(expr) abort
|
||||
return split(glob(a:expr, 1), '\n')
|
||||
endfunction
|
||||
endif
|
||||
|
||||
if v:version > 704 ||
|
||||
\ (v:version == 704 && has('patch279'))
|
||||
function! s:globpath(path, expr) abort
|
||||
return globpath(a:path, a:expr, 1, 1)
|
||||
endfunction
|
||||
else
|
||||
function! s:globpath(path, expr) abort
|
||||
return split(globpath(a:path, a:expr, 1), '\n')
|
||||
endfunction
|
||||
endif
|
||||
|
||||
" Wrapper functions for type().
|
||||
" NOTE: __TYPE_FLOAT = -1 when -float.
|
||||
" this doesn't match to anything.
|
||||
if has('patch-7.4.2071')
|
||||
let [
|
||||
\ s:__TYPE_NUMBER,
|
||||
\ s:__TYPE_STRING,
|
||||
\ s:__TYPE_FUNCREF,
|
||||
\ s:__TYPE_LIST,
|
||||
\ s:__TYPE_DICT,
|
||||
\ s:__TYPE_FLOAT] = [
|
||||
\ v:t_number,
|
||||
\ v:t_string,
|
||||
\ v:t_func,
|
||||
\ v:t_list,
|
||||
\ v:t_dict,
|
||||
\ v:t_float]
|
||||
else
|
||||
let [
|
||||
\ s:__TYPE_NUMBER,
|
||||
\ s:__TYPE_STRING,
|
||||
\ s:__TYPE_FUNCREF,
|
||||
\ s:__TYPE_LIST,
|
||||
\ s:__TYPE_DICT,
|
||||
\ s:__TYPE_FLOAT] = [
|
||||
\ type(3),
|
||||
\ type(''),
|
||||
\ type(function('tr')),
|
||||
\ type([]),
|
||||
\ type({}),
|
||||
\ has('float') ? type(str2float('0')) : -1]
|
||||
endif
|
||||
|
||||
" Number or Float
|
||||
function! s:is_numeric(Value) abort
|
||||
let _ = type(a:Value)
|
||||
return _ ==# s:__TYPE_NUMBER
|
||||
\ || _ ==# s:__TYPE_FLOAT
|
||||
endfunction
|
||||
|
||||
" Number
|
||||
function! s:is_number(Value) abort
|
||||
return type(a:Value) ==# s:__TYPE_NUMBER
|
||||
endfunction
|
||||
|
||||
" String
|
||||
function! s:is_string(Value) abort
|
||||
return type(a:Value) ==# s:__TYPE_STRING
|
||||
endfunction
|
||||
|
||||
" Funcref
|
||||
function! s:is_funcref(Value) abort
|
||||
return type(a:Value) ==# s:__TYPE_FUNCREF
|
||||
endfunction
|
||||
|
||||
" List
|
||||
function! s:is_list(Value) abort
|
||||
return type(a:Value) ==# s:__TYPE_LIST
|
||||
endfunction
|
||||
|
||||
" Dictionary
|
||||
function! s:is_dict(Value) abort
|
||||
return type(a:Value) ==# s:__TYPE_DICT
|
||||
endfunction
|
||||
|
||||
" Float
|
||||
function! s:is_float(Value) abort
|
||||
return type(a:Value) ==# s:__TYPE_FLOAT
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:truncate_skipping(str, max, footer_width, separator) abort
|
||||
call s:_warn_deprecated('truncate_skipping', 'Data.String.truncate_skipping')
|
||||
|
||||
let width = s:wcswidth(a:str)
|
||||
if width <= a:max
|
||||
let ret = a:str
|
||||
else
|
||||
let header_width = a:max - s:wcswidth(a:separator) - a:footer_width
|
||||
let ret = s:strwidthpart(a:str, header_width) . a:separator
|
||||
\ . s:strwidthpart_reverse(a:str, a:footer_width)
|
||||
endif
|
||||
|
||||
return s:truncate(ret, a:max)
|
||||
endfunction
|
||||
|
||||
function! s:truncate(str, width) abort
|
||||
" Original function is from mattn.
|
||||
" http://github.com/mattn/googlereader-vim/tree/master
|
||||
|
||||
call s:_warn_deprecated('truncate', 'Data.String.truncate')
|
||||
|
||||
if a:str =~# '^[\x00-\x7f]*$'
|
||||
return len(a:str) < a:width ?
|
||||
\ printf('%-'.a:width.'s', a:str) : strpart(a:str, 0, a:width)
|
||||
endif
|
||||
|
||||
let ret = a:str
|
||||
let width = s:wcswidth(a:str)
|
||||
if width > a:width
|
||||
let ret = s:strwidthpart(ret, a:width)
|
||||
let width = s:wcswidth(ret)
|
||||
endif
|
||||
|
||||
if width < a:width
|
||||
let ret .= repeat(' ', a:width - width)
|
||||
endif
|
||||
|
||||
return ret
|
||||
endfunction
|
||||
|
||||
function! s:strwidthpart(str, width) abort
|
||||
call s:_warn_deprecated('strwidthpart', 'Data.String.strwidthpart')
|
||||
|
||||
if a:width <= 0
|
||||
return ''
|
||||
endif
|
||||
let ret = a:str
|
||||
let width = s:wcswidth(a:str)
|
||||
while width > a:width
|
||||
let char = matchstr(ret, '.$')
|
||||
let ret = ret[: -1 - len(char)]
|
||||
let width -= s:wcswidth(char)
|
||||
endwhile
|
||||
|
||||
return ret
|
||||
endfunction
|
||||
function! s:strwidthpart_reverse(str, width) abort
|
||||
call s:_warn_deprecated('strwidthpart_reverse', 'Data.String.strwidthpart_reverse')
|
||||
|
||||
if a:width <= 0
|
||||
return ''
|
||||
endif
|
||||
let ret = a:str
|
||||
let width = s:wcswidth(a:str)
|
||||
while width > a:width
|
||||
let char = matchstr(ret, '^.')
|
||||
let ret = ret[len(char) :]
|
||||
let width -= s:wcswidth(char)
|
||||
endwhile
|
||||
|
||||
return ret
|
||||
endfunction
|
||||
|
||||
if v:version >= 703
|
||||
" Use builtin function.
|
||||
function! s:wcswidth(str) abort
|
||||
call s:_warn_deprecated('wcswidth', 'Data.String.wcswidth')
|
||||
return strwidth(a:str)
|
||||
endfunction
|
||||
else
|
||||
function! s:wcswidth(str) abort
|
||||
call s:_warn_deprecated('wcswidth', 'Data.String.wcswidth')
|
||||
|
||||
if a:str =~# '^[\x00-\x7f]*$'
|
||||
return strlen(a:str)
|
||||
end
|
||||
|
||||
let mx_first = '^\(.\)'
|
||||
let str = a:str
|
||||
let width = 0
|
||||
while 1
|
||||
let ucs = char2nr(substitute(str, mx_first, '\1', ''))
|
||||
if ucs == 0
|
||||
break
|
||||
endif
|
||||
let width += s:_wcwidth(ucs)
|
||||
let str = substitute(str, mx_first, '', '')
|
||||
endwhile
|
||||
return width
|
||||
endfunction
|
||||
|
||||
" UTF-8 only.
|
||||
function! s:_wcwidth(ucs) abort
|
||||
let ucs = a:ucs
|
||||
if (ucs >= 0x1100
|
||||
\ && (ucs <= 0x115f
|
||||
\ || ucs == 0x2329
|
||||
\ || ucs == 0x232a
|
||||
\ || (ucs >= 0x2e80 && ucs <= 0xa4cf
|
||||
\ && ucs != 0x303f)
|
||||
\ || (ucs >= 0xac00 && ucs <= 0xd7a3)
|
||||
\ || (ucs >= 0xf900 && ucs <= 0xfaff)
|
||||
\ || (ucs >= 0xfe30 && ucs <= 0xfe6f)
|
||||
\ || (ucs >= 0xff00 && ucs <= 0xff60)
|
||||
\ || (ucs >= 0xffe0 && ucs <= 0xffe6)
|
||||
\ || (ucs >= 0x20000 && ucs <= 0x2fffd)
|
||||
\ || (ucs >= 0x30000 && ucs <= 0x3fffd)
|
||||
\ ))
|
||||
return 2
|
||||
endif
|
||||
return 1
|
||||
endfunction
|
||||
endif
|
||||
|
||||
let s:is_windows = has('win16') || has('win32') || has('win64') || has('win95')
|
||||
let s:is_cygwin = has('win32unix')
|
||||
let s:is_mac = !s:is_windows && !s:is_cygwin
|
||||
\ && (has('mac') || has('macunix') || has('gui_macvim') ||
|
||||
\ (!isdirectory('/proc') && executable('sw_vers')))
|
||||
let s:is_unix = has('unix')
|
||||
|
||||
function! s:is_windows() abort
|
||||
return s:is_windows
|
||||
endfunction
|
||||
|
||||
function! s:is_cygwin() abort
|
||||
return s:is_cygwin
|
||||
endfunction
|
||||
|
||||
function! s:is_mac() abort
|
||||
return s:is_mac
|
||||
endfunction
|
||||
|
||||
function! s:is_unix() abort
|
||||
return s:is_unix
|
||||
endfunction
|
||||
|
||||
function! s:_warn_deprecated(name, alternative) abort
|
||||
try
|
||||
echohl Error
|
||||
echomsg 'Prelude.' . a:name . ' is deprecated! Please use ' . a:alternative . ' instead.'
|
||||
finally
|
||||
echohl None
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:smart_execute_command(action, word) abort
|
||||
execute a:action . ' ' . (a:word ==# '' ? '' : '`=a:word`')
|
||||
endfunction
|
||||
|
||||
function! s:escape_file_searching(buffer_name) abort
|
||||
return escape(a:buffer_name, '*[]?{}, ')
|
||||
endfunction
|
||||
|
||||
function! s:escape_pattern(str) abort
|
||||
call s:_warn_deprecated(
|
||||
\ 'escape_pattern',
|
||||
\ 'Data.String.escape_pattern',
|
||||
\)
|
||||
return escape(a:str, '~"\.^$[]*')
|
||||
endfunction
|
||||
|
||||
function! s:getchar(...) abort
|
||||
let c = call('getchar', a:000)
|
||||
return type(c) == type(0) ? nr2char(c) : c
|
||||
endfunction
|
||||
|
||||
function! s:getchar_safe(...) abort
|
||||
let c = s:input_helper('getchar', a:000)
|
||||
return type(c) == type('') ? c : nr2char(c)
|
||||
endfunction
|
||||
|
||||
function! s:input_safe(...) abort
|
||||
return s:input_helper('input', a:000)
|
||||
endfunction
|
||||
|
||||
function! s:input_helper(funcname, args) abort
|
||||
let success = 0
|
||||
if inputsave() !=# success
|
||||
throw 'vital: Prelude: inputsave() failed'
|
||||
endif
|
||||
try
|
||||
return call(a:funcname, a:args)
|
||||
finally
|
||||
if inputrestore() !=# success
|
||||
throw 'vital: Prelude: inputrestore() failed'
|
||||
endif
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:set_default(var, val) abort
|
||||
if !exists(a:var) || type({a:var}) != type(a:val)
|
||||
let {a:var} = a:val
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:substitute_path_separator(path) abort
|
||||
return s:is_windows ? substitute(a:path, '\\', '/', 'g') : a:path
|
||||
endfunction
|
||||
|
||||
function! s:path2directory(path) abort
|
||||
return s:substitute_path_separator(isdirectory(a:path) ? a:path : fnamemodify(a:path, ':p:h'))
|
||||
endfunction
|
||||
|
||||
function! s:_path2project_directory_git(path) abort
|
||||
let parent = a:path
|
||||
|
||||
while 1
|
||||
let path = parent . '/.git'
|
||||
if isdirectory(path) || filereadable(path)
|
||||
return parent
|
||||
endif
|
||||
let next = fnamemodify(parent, ':h')
|
||||
if next == parent
|
||||
return ''
|
||||
endif
|
||||
let parent = next
|
||||
endwhile
|
||||
endfunction
|
||||
|
||||
function! s:_path2project_directory_svn(path) abort
|
||||
let search_directory = a:path
|
||||
let directory = ''
|
||||
|
||||
let find_directory = s:escape_file_searching(search_directory)
|
||||
let d = finddir('.svn', find_directory . ';')
|
||||
if d ==# ''
|
||||
return ''
|
||||
endif
|
||||
|
||||
let directory = fnamemodify(d, ':p:h:h')
|
||||
|
||||
" Search parent directories.
|
||||
let parent_directory = s:path2directory(
|
||||
\ fnamemodify(directory, ':h'))
|
||||
|
||||
if parent_directory !=# ''
|
||||
let d = finddir('.svn', parent_directory . ';')
|
||||
if d !=# ''
|
||||
let directory = s:_path2project_directory_svn(parent_directory)
|
||||
endif
|
||||
endif
|
||||
return directory
|
||||
endfunction
|
||||
|
||||
function! s:_path2project_directory_others(vcs, path) abort
|
||||
let vcs = a:vcs
|
||||
let search_directory = a:path
|
||||
|
||||
let find_directory = s:escape_file_searching(search_directory)
|
||||
let d = finddir(vcs, find_directory . ';')
|
||||
if d ==# ''
|
||||
return ''
|
||||
endif
|
||||
return fnamemodify(d, ':p:h:h')
|
||||
endfunction
|
||||
|
||||
function! s:path2project_directory(path, ...) abort
|
||||
let is_allow_empty = get(a:000, 0, 0)
|
||||
let search_directory = s:path2directory(a:path)
|
||||
let directory = ''
|
||||
|
||||
" Search VCS directory.
|
||||
for vcs in ['.git', '.bzr', '.hg', '.svn']
|
||||
if vcs ==# '.git'
|
||||
let directory = s:_path2project_directory_git(search_directory)
|
||||
elseif vcs ==# '.svn'
|
||||
let directory = s:_path2project_directory_svn(search_directory)
|
||||
else
|
||||
let directory = s:_path2project_directory_others(vcs, search_directory)
|
||||
endif
|
||||
if directory !=# ''
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
|
||||
" Search project file.
|
||||
if directory ==# ''
|
||||
for d in ['build.xml', 'prj.el', '.project', 'pom.xml', 'package.json',
|
||||
\ 'Makefile', 'configure', 'Rakefile', 'NAnt.build',
|
||||
\ 'P4CONFIG', 'tags', 'gtags']
|
||||
let d = findfile(d, s:escape_file_searching(search_directory) . ';')
|
||||
if d !=# ''
|
||||
let directory = fnamemodify(d, ':p:h')
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
if directory ==# ''
|
||||
" Search /src/ directory.
|
||||
let base = s:substitute_path_separator(search_directory)
|
||||
if base =~# '/src/'
|
||||
let directory = base[: strridx(base, '/src/') + 3]
|
||||
endif
|
||||
endif
|
||||
|
||||
if directory ==# '' && !is_allow_empty
|
||||
" Use original path.
|
||||
let directory = search_directory
|
||||
endif
|
||||
|
||||
return s:substitute_path_separator(directory)
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
||||
" vim:set et ts=2 sts=2 sw=2 tw=0:
|
@ -0,0 +1,187 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Vim#Buffer#import() abort
|
||||
return map({'parse_cmdarg': '', '_vital_depends': '', 'read_content': '', 'get_selected_text': '', 'is_cmdwin': '', 'edit_content': '', 'open': '', 'get_last_selected': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Vim#Buffer#import() abort', printf("return map({'parse_cmdarg': '', '_vital_depends': '', 'read_content': '', 'get_selected_text': '', 'is_cmdwin': '', 'edit_content': '', 'open': '', 'get_last_selected': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
function! s:_vital_loaded(V) abort
|
||||
let s:V = a:V
|
||||
let s:P = s:V.import('Prelude')
|
||||
let s:G = s:V.import('Vim.Guard')
|
||||
endfunction
|
||||
|
||||
function! s:_vital_depends() abort
|
||||
return ['Prelude', 'Vim.Guard']
|
||||
endfunction
|
||||
|
||||
if exists('*getcmdwintype')
|
||||
function! s:is_cmdwin() abort
|
||||
return getcmdwintype() !=# ''
|
||||
endfunction
|
||||
else
|
||||
function! s:is_cmdwin() abort
|
||||
return bufname('%') ==# '[Command Line]'
|
||||
endfunction
|
||||
endif
|
||||
|
||||
function! s:open(buffer, opener) abort
|
||||
let save_wildignore = &wildignore
|
||||
let &wildignore = ''
|
||||
try
|
||||
if s:P.is_funcref(a:opener)
|
||||
let loaded = !bufloaded(a:buffer)
|
||||
call a:opener(a:buffer)
|
||||
elseif a:buffer is 0 || a:buffer is# ''
|
||||
let loaded = 1
|
||||
silent execute a:opener
|
||||
enew
|
||||
else
|
||||
let loaded = !bufloaded(a:buffer)
|
||||
if s:P.is_string(a:buffer)
|
||||
execute a:opener '`=a:buffer`'
|
||||
elseif s:P.is_number(a:buffer)
|
||||
silent execute a:opener
|
||||
execute a:buffer 'buffer'
|
||||
else
|
||||
throw 'vital: Vim.Buffer: Unknown opener type.'
|
||||
endif
|
||||
endif
|
||||
finally
|
||||
let &wildignore = save_wildignore
|
||||
endtry
|
||||
return loaded
|
||||
endfunction
|
||||
|
||||
function! s:get_selected_text(...) abort
|
||||
echohl WarningMsg
|
||||
echom "[WARN] s:get_selected_text() is deprecated. Use 's:get_last_selected()'."
|
||||
echohl None
|
||||
return call('s:get_last_selected', a:000)
|
||||
endfunction
|
||||
|
||||
" Get the last selected text in visual mode
|
||||
" without using |gv| to avoid |textlock|.
|
||||
" NOTE:
|
||||
" * This function uses |gv| only when using |CTRL-V|
|
||||
" because |gv| is the only way to get selected text
|
||||
" when using <C-v>$ .
|
||||
" Please see #192 for the details.
|
||||
" * If you don't care about |textlock|,
|
||||
" you can use simple version of this function.
|
||||
" https://github.com/vim-jp/vital.vim/commit/39aae80f3839fdbeebd838ff14d87327a6b889a9
|
||||
function! s:get_last_selected() abort
|
||||
if visualmode() ==# "\<C-v>"
|
||||
let save = getreg('"', 1)
|
||||
let save_type = getregtype('"')
|
||||
try
|
||||
normal! gv""y
|
||||
return @"
|
||||
finally
|
||||
call setreg('"', save, save_type)
|
||||
endtry
|
||||
else
|
||||
let [begin, end] = [getpos("'<"), getpos("'>")]
|
||||
let lastchar = matchstr(getline(end[1])[end[2]-1 :], '.')
|
||||
if begin[1] ==# end[1]
|
||||
let lines = [getline(begin[1])[begin[2]-1 : end[2]-2]]
|
||||
else
|
||||
let lines = [getline(begin[1])[begin[2]-1 :]]
|
||||
\ + (end[1] - begin[1] <# 2 ? [] : getline(begin[1]+1, end[1]-1))
|
||||
\ + [getline(end[1])[: end[2]-2]]
|
||||
endif
|
||||
return join(lines, "\n") . lastchar . (visualmode() ==# 'V' ? "\n" : '')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:read_content(content, ...) abort
|
||||
let options = extend({
|
||||
\ 'tempfile': '',
|
||||
\ 'fileformat': '',
|
||||
\ 'encoding': '',
|
||||
\ 'binary': 0,
|
||||
\ 'nobinary': 0,
|
||||
\ 'bad': '',
|
||||
\ 'edit': 0,
|
||||
\ 'line': '',
|
||||
\}, get(a:000, 0, {}))
|
||||
let tempfile = empty(options.tempfile) ? tempname() : options.tempfile
|
||||
let optnames = [
|
||||
\ empty(options.fileformat) ? '' : '++ff=' . options.fileformat,
|
||||
\ empty(options.encoding) ? '' : '++enc=' . options.encoding,
|
||||
\ empty(options.binary) ? '' : '++bin',
|
||||
\ empty(options.nobinary) ? '' : '++nobin',
|
||||
\ empty(options.bad) ? '' : '++bad=' . options.bad,
|
||||
\ empty(options.edit) ? '' : '++edit',
|
||||
\]
|
||||
let optname = join(filter(optnames, '!empty(v:val)'))
|
||||
try
|
||||
call writefile(a:content, tempfile)
|
||||
execute printf('keepalt keepjumps %sread %s%s',
|
||||
\ options.line,
|
||||
\ empty(optname) ? '' : optname . ' ',
|
||||
\ fnameescape(tempfile),
|
||||
\)
|
||||
finally
|
||||
call delete(tempfile)
|
||||
execute 'bwipeout!' tempfile
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:edit_content(content, ...) abort
|
||||
let options = extend({
|
||||
\ 'edit': 1,
|
||||
\}, get(a:000, 0, {}))
|
||||
let guard = s:G.store(['&l:modifiable'])
|
||||
let saved_view = winsaveview()
|
||||
try
|
||||
let &l:modifiable=1
|
||||
silent keepjumps %delete _
|
||||
silent call s:read_content(a:content, options)
|
||||
silent keepjumps 1delete _
|
||||
finally
|
||||
keepjump call winrestview(saved_view)
|
||||
call guard.restore()
|
||||
endtry
|
||||
setlocal nomodified
|
||||
endfunction
|
||||
|
||||
function! s:parse_cmdarg(...) abort
|
||||
let cmdarg = get(a:000, 0, v:cmdarg)
|
||||
let options = {}
|
||||
if cmdarg =~# '++enc='
|
||||
let options.encoding = matchstr(cmdarg, '++enc=\zs[^ ]\+\ze')
|
||||
endif
|
||||
if cmdarg =~# '++ff='
|
||||
let options.fileformat = matchstr(cmdarg, '++ff=\zs[^ ]\+\ze')
|
||||
endif
|
||||
if cmdarg =~# '++bad='
|
||||
let options.bad = matchstr(cmdarg, '++bad=\zs[^ ]\+\ze')
|
||||
endif
|
||||
if cmdarg =~# '++bin'
|
||||
let options.binary = 1
|
||||
endif
|
||||
if cmdarg =~# '++nobin'
|
||||
let options.nobinary = 1
|
||||
endif
|
||||
if cmdarg =~# '++edit'
|
||||
let options.edit = 1
|
||||
endif
|
||||
return options
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
||||
" vim:set et ts=2 sts=2 sw=2 tw=0:
|
@ -0,0 +1,240 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Vim#Guard#import() abort
|
||||
return map({'_vital_depends': '', '_vital_created': '', 'store': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Vim#Guard#import() abort', printf("return map({'_vital_depends': '', '_vital_created': '', 'store': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" Use a Funcref as a special term _UNDEFINED
|
||||
function! s:_undefined() abort
|
||||
return 'undefined'
|
||||
endfunction
|
||||
let s:_UNDEFINED = function('s:_undefined')
|
||||
|
||||
function! s:_vital_loaded(V) abort
|
||||
let s:V = a:V
|
||||
let s:Prelude = s:V.import('Prelude')
|
||||
let s:List = s:V.import('Data.List')
|
||||
let s:Dict = s:V.import('Data.Dict')
|
||||
endfunction
|
||||
function! s:_vital_depends() abort
|
||||
return ['Prelude', 'Data.List', 'Data.Dict']
|
||||
endfunction
|
||||
function! s:_vital_created(module) abort
|
||||
" define constant variables
|
||||
if !exists('s:const')
|
||||
let s:const = {}
|
||||
let s:const.is_local_variable_supported =
|
||||
\ v:version > 703 || (v:version == 703 && has('patch560'))
|
||||
" NOTE:
|
||||
" The third argument is available from 7.4.242 but it had bug and that
|
||||
" bug was fixed from 7.4.513
|
||||
let s:const.is_third_argument_of_getreg_supported = has('patch-7.4.513')
|
||||
lockvar s:const
|
||||
endif
|
||||
call extend(a:module, s:const)
|
||||
endfunction
|
||||
function! s:_throw(msg) abort
|
||||
throw printf('vital: Vim.Guard: %s', a:msg)
|
||||
endfunction
|
||||
|
||||
let s:option = {}
|
||||
function! s:_new_option(name) abort
|
||||
if a:name !~# '^&'
|
||||
call s:_throw(printf(
|
||||
\'An option name "%s" requires to be started from "&"', a:name
|
||||
\))
|
||||
elseif !exists(a:name)
|
||||
call s:_throw(printf(
|
||||
\'An option name "%s" does not exist', a:name
|
||||
\))
|
||||
endif
|
||||
let option = copy(s:option)
|
||||
let option.name = a:name
|
||||
let option.value = eval(a:name)
|
||||
return option
|
||||
endfunction
|
||||
function! s:option.restore() abort
|
||||
execute printf('let %s = %s', self.name, string(self.value))
|
||||
endfunction
|
||||
|
||||
let s:register = {}
|
||||
function! s:_new_register(name) abort
|
||||
if len(a:name) != 2
|
||||
call s:_throw(printf(
|
||||
\'A register name "%s" requires to be "@" + a single character', a:name
|
||||
\))
|
||||
elseif a:name !~# '^@'
|
||||
call s:_throw(printf(
|
||||
\'A register name "%s" requires to be started from "@"', a:name
|
||||
\))
|
||||
elseif a:name =~# '^@[:.%]$'
|
||||
call s:_throw(printf(
|
||||
\'A register name "%s" is read only', a:name
|
||||
\))
|
||||
elseif a:name !~# '^@[@0-9a-zA-Z#=*+~_/-]$'
|
||||
call s:_throw(printf(
|
||||
\'A register name "%s" does not exist. See ":help let-register"', a:name
|
||||
\))
|
||||
endif
|
||||
let name = a:name ==# '@@' ? '' : a:name[1]
|
||||
let register = copy(s:register)
|
||||
let register.name = name
|
||||
if s:const.is_third_argument_of_getreg_supported
|
||||
let register.value = getreg(name, 1, 1)
|
||||
else
|
||||
let register.value = getreg(name, 1)
|
||||
endif
|
||||
let register.type = getregtype(name)
|
||||
return register
|
||||
endfunction
|
||||
function! s:register.restore() abort
|
||||
" https://github.com/vim/vim/commit/5a50c2255c447838d08d3b4895a3be3a41cd8eda
|
||||
if has('patch-7.4.243') || self.name !=# '='
|
||||
call setreg(self.name, self.value, self.type)
|
||||
else
|
||||
let @= = self.value
|
||||
endif
|
||||
endfunction
|
||||
|
||||
let s:environment = {}
|
||||
function! s:_new_environment(name) abort
|
||||
if a:name !~# '^\$'
|
||||
call s:_throw(printf(
|
||||
\'An environment variable name "%s" requires to be started from "$"', a:name
|
||||
\))
|
||||
elseif !exists(a:name)
|
||||
call s:_throw(printf(
|
||||
\'An environment variable name "%s" does not exist. While Vim cannot unlet environment variable, it requires to exist', a:name
|
||||
\))
|
||||
endif
|
||||
let environment = copy(s:environment)
|
||||
let environment.name = a:name
|
||||
let environment.value = eval(a:name)
|
||||
return environment
|
||||
endfunction
|
||||
function! s:environment.restore() abort
|
||||
execute printf('let %s = %s', self.name, string(self.value))
|
||||
endfunction
|
||||
|
||||
let s:variable = {}
|
||||
function! s:_new_variable(name, ...) abort
|
||||
if a:0 == 0
|
||||
let m = matchlist(a:name, '^\([bwtg]:\)\(.*\)$')
|
||||
if empty(m)
|
||||
call s:_throw(printf(
|
||||
\ join([
|
||||
\ 'An variable name "%s" requires to start from b:, w:, t:, or g:',
|
||||
\ 'while no {namespace} is specified',
|
||||
\ ]),
|
||||
\ a:name,
|
||||
\))
|
||||
endif
|
||||
let [prefix, name] = m[1 : 2]
|
||||
let namespace = eval(prefix)
|
||||
else
|
||||
let name = a:name
|
||||
let namespace = a:1
|
||||
endif
|
||||
let variable = copy(s:variable)
|
||||
let variable.name = name
|
||||
let variable.value = get(namespace, name, s:_UNDEFINED)
|
||||
let variable.value =
|
||||
\ type(variable.value) == type({}) || type(variable.value) == type([])
|
||||
\ ? deepcopy(variable.value)
|
||||
\ : variable.value
|
||||
let variable._namespace = namespace
|
||||
return variable
|
||||
endfunction
|
||||
function! s:variable.restore() abort
|
||||
" unlet the variable to prevent variable type mis-match in case
|
||||
silent! unlet! self._namespace[self.name]
|
||||
if type(self.value) == type(s:_UNDEFINED) && self.value == s:_UNDEFINED
|
||||
" do nothing, leave the variable as undefined
|
||||
else
|
||||
let self._namespace[self.name] = self.value
|
||||
endif
|
||||
endfunction
|
||||
|
||||
let s:instance = {}
|
||||
function! s:_new_instance(instance, ...) abort
|
||||
let shallow = get(a:000, 0, 0)
|
||||
if !s:Prelude.is_list(a:instance) && !s:Prelude.is_dict(a:instance)
|
||||
call s:_throw(printf(
|
||||
\'An instance "%s" requires to be List or Dictionary', string(a:instance)
|
||||
\))
|
||||
endif
|
||||
let instance = copy(s:instance)
|
||||
let instance.instance = a:instance
|
||||
let instance.values = shallow ? copy(a:instance) : deepcopy(a:instance)
|
||||
return instance
|
||||
endfunction
|
||||
function! s:instance.restore() abort
|
||||
if s:Prelude.is_list(self.instance)
|
||||
call s:List.clear(self.instance)
|
||||
else
|
||||
call s:Dict.clear(self.instance)
|
||||
endif
|
||||
call extend(self.instance, self.values)
|
||||
endfunction
|
||||
|
||||
let s:guard = {}
|
||||
function! s:store(targets) abort
|
||||
let resources = []
|
||||
for meta in a:targets
|
||||
if s:Prelude.is_list(meta)
|
||||
if len(meta) == 1
|
||||
call add(resources, s:_new_instance(meta[0]))
|
||||
elseif len(meta) == 2
|
||||
if s:Prelude.is_string(meta[0])
|
||||
call add(resources, call('s:_new_variable', meta))
|
||||
else
|
||||
call add(resources, call('s:_new_instance', meta))
|
||||
endif
|
||||
else
|
||||
call s:_throw('List assignment requires one or two elements')
|
||||
endif
|
||||
elseif type(meta) == type('')
|
||||
if meta =~# '^[bwtgls]:'
|
||||
" Note:
|
||||
" To improve an error message, handle l:XXX or s:XXX as well
|
||||
call add(resources, s:_new_variable(meta))
|
||||
elseif meta =~# '^&'
|
||||
call add(resources, s:_new_option(meta))
|
||||
elseif meta =~# '^@'
|
||||
call add(resources, s:_new_register(meta))
|
||||
elseif meta =~# '^\$'
|
||||
call add(resources, s:_new_environment(meta))
|
||||
else
|
||||
call s:_throw(printf(
|
||||
\ 'Unknown value "%s" was specified',
|
||||
\ meta
|
||||
\))
|
||||
endif
|
||||
endif
|
||||
unlet meta
|
||||
endfor
|
||||
let guard = copy(s:guard)
|
||||
let guard._resources = resources
|
||||
return guard
|
||||
endfunction
|
||||
function! s:guard.restore() abort
|
||||
for resource in self._resources
|
||||
call resource.restore()
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet! s:save_cpo
|
||||
" vim:set et ts=2 sts=2 sw=2 tw=0 fdm=marker:
|
@ -0,0 +1,80 @@
|
||||
" ___vital___
|
||||
" NOTE: lines between '" ___vital___' is generated by :Vitalize.
|
||||
" Do not mofidify the code nor insert new lines before '" ___vital___'
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! vital#_easymotion#Vim#Message#import() abort
|
||||
return map({'capture': '', 'echomsg': '', 'echo': '', 'warn': '', 'get_hit_enter_max_length': '', 'error': ''}, 'function("s:" . v:key)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
execute join(['function! vital#_easymotion#Vim#Message#import() abort', printf("return map({'capture': '', 'echomsg': '', 'echo': '', 'warn': '', 'get_hit_enter_max_length': '', 'error': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
|
||||
delfunction s:_SID
|
||||
endif
|
||||
" ___vital___
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
|
||||
function! s:echo(hl, msg) abort
|
||||
execute 'echohl' a:hl
|
||||
try
|
||||
echo a:msg
|
||||
finally
|
||||
echohl None
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:echomsg(hl, msg) abort
|
||||
execute 'echohl' a:hl
|
||||
try
|
||||
for m in split(a:msg, "\n")
|
||||
echomsg m
|
||||
endfor
|
||||
finally
|
||||
echohl None
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:error(msg) abort
|
||||
call s:echomsg('ErrorMsg', a:msg)
|
||||
endfunction
|
||||
|
||||
function! s:warn(msg) abort
|
||||
call s:echomsg('WarningMsg', a:msg)
|
||||
endfunction
|
||||
|
||||
function! s:capture(command) abort
|
||||
try
|
||||
redir => out
|
||||
silent execute a:command
|
||||
finally
|
||||
redir END
|
||||
endtry
|
||||
return out
|
||||
endfunction
|
||||
|
||||
" * Get max length of |hit-enter|.
|
||||
" If a string length of a message is greater than the max length,
|
||||
" Vim waits for user input according to |hit-enter|.
|
||||
" XXX: Those fixed values may be different between different OSes?
|
||||
" Currently tested on only Windows.
|
||||
function! s:get_hit_enter_max_length() abort
|
||||
let maxlen = &columns * &cmdheight - 1
|
||||
if &ruler
|
||||
" TODO
|
||||
endif
|
||||
if &showcmd
|
||||
let maxlen -= 11
|
||||
endif
|
||||
return maxlen
|
||||
endfunction
|
||||
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
||||
" vim:set et ts=2 sts=2 sw=2 tw=0:
|
339
vim/plugins/vim-easymotion/autoload/vital/easymotion.vim
Normal file
339
vim/plugins/vim-easymotion/autoload/vital/easymotion.vim
Normal file
@ -0,0 +1,339 @@
|
||||
let s:plugin_name = expand('<sfile>:t:r')
|
||||
let s:vital_base_dir = expand('<sfile>:h')
|
||||
let s:project_root = expand('<sfile>:h:h:h')
|
||||
let s:is_vital_vim = s:plugin_name is# 'vital'
|
||||
|
||||
let s:loaded = {}
|
||||
let s:cache_sid = {}
|
||||
|
||||
" function() wrapper
|
||||
if v:version > 703 || v:version == 703 && has('patch1170')
|
||||
function! s:_function(fstr) abort
|
||||
return function(a:fstr)
|
||||
endfunction
|
||||
else
|
||||
function! s:_SID() abort
|
||||
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
|
||||
endfunction
|
||||
let s:_s = '<SNR>' . s:_SID() . '_'
|
||||
function! s:_function(fstr) abort
|
||||
return function(substitute(a:fstr, 's:', s:_s, 'g'))
|
||||
endfunction
|
||||
endif
|
||||
|
||||
function! vital#{s:plugin_name}#new() abort
|
||||
return s:new(s:plugin_name)
|
||||
endfunction
|
||||
|
||||
function! vital#{s:plugin_name}#import(...) abort
|
||||
if !exists('s:V')
|
||||
let s:V = s:new(s:plugin_name)
|
||||
endif
|
||||
return call(s:V.import, a:000, s:V)
|
||||
endfunction
|
||||
|
||||
let s:Vital = {}
|
||||
|
||||
function! s:new(plugin_name) abort
|
||||
let base = deepcopy(s:Vital)
|
||||
let base._plugin_name = a:plugin_name
|
||||
return base
|
||||
endfunction
|
||||
|
||||
function! s:vital_files() abort
|
||||
if !exists('s:vital_files')
|
||||
let s:vital_files = map(
|
||||
\ s:is_vital_vim ? s:_global_vital_files() : s:_self_vital_files(),
|
||||
\ 'fnamemodify(v:val, ":p:gs?[\\\\/]?/?")')
|
||||
endif
|
||||
return copy(s:vital_files)
|
||||
endfunction
|
||||
let s:Vital.vital_files = s:_function('s:vital_files')
|
||||
|
||||
function! s:import(name, ...) abort dict
|
||||
let target = {}
|
||||
let functions = []
|
||||
for a in a:000
|
||||
if type(a) == type({})
|
||||
let target = a
|
||||
elseif type(a) == type([])
|
||||
let functions = a
|
||||
endif
|
||||
unlet a
|
||||
endfor
|
||||
let module = self._import(a:name)
|
||||
if empty(functions)
|
||||
call extend(target, module, 'keep')
|
||||
else
|
||||
for f in functions
|
||||
if has_key(module, f) && !has_key(target, f)
|
||||
let target[f] = module[f]
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
return target
|
||||
endfunction
|
||||
let s:Vital.import = s:_function('s:import')
|
||||
|
||||
function! s:load(...) abort dict
|
||||
for arg in a:000
|
||||
let [name; as] = type(arg) == type([]) ? arg[: 1] : [arg, arg]
|
||||
let target = split(join(as, ''), '\W\+')
|
||||
let dict = self
|
||||
let dict_type = type({})
|
||||
while !empty(target)
|
||||
let ns = remove(target, 0)
|
||||
if !has_key(dict, ns)
|
||||
let dict[ns] = {}
|
||||
endif
|
||||
if type(dict[ns]) == dict_type
|
||||
let dict = dict[ns]
|
||||
else
|
||||
unlet dict
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
if exists('dict')
|
||||
call extend(dict, self._import(name))
|
||||
endif
|
||||
unlet arg
|
||||
endfor
|
||||
return self
|
||||
endfunction
|
||||
let s:Vital.load = s:_function('s:load')
|
||||
|
||||
function! s:unload() abort dict
|
||||
let s:loaded = {}
|
||||
let s:cache_sid = {}
|
||||
unlet! s:vital_files
|
||||
endfunction
|
||||
let s:Vital.unload = s:_function('s:unload')
|
||||
|
||||
function! s:exists(name) abort dict
|
||||
if a:name !~# '\v^\u\w*%(\.\u\w*)*$'
|
||||
throw 'vital: Invalid module name: ' . a:name
|
||||
endif
|
||||
return s:_module_path(a:name) isnot# ''
|
||||
endfunction
|
||||
let s:Vital.exists = s:_function('s:exists')
|
||||
|
||||
function! s:search(pattern) abort dict
|
||||
let paths = s:_extract_files(a:pattern, self.vital_files())
|
||||
let modules = sort(map(paths, 's:_file2module(v:val)'))
|
||||
return s:_uniq(modules)
|
||||
endfunction
|
||||
let s:Vital.search = s:_function('s:search')
|
||||
|
||||
function! s:plugin_name() abort dict
|
||||
return self._plugin_name
|
||||
endfunction
|
||||
let s:Vital.plugin_name = s:_function('s:plugin_name')
|
||||
|
||||
function! s:_self_vital_files() abort
|
||||
let builtin = printf('%s/__%s__/', s:vital_base_dir, s:plugin_name)
|
||||
let installed = printf('%s/_%s/', s:vital_base_dir, s:plugin_name)
|
||||
let base = builtin . ',' . installed
|
||||
return split(globpath(base, '**/*.vim', 1), "\n")
|
||||
endfunction
|
||||
|
||||
function! s:_global_vital_files() abort
|
||||
let pattern = 'autoload/vital/__*__/**/*.vim'
|
||||
return split(globpath(&runtimepath, pattern, 1), "\n")
|
||||
endfunction
|
||||
|
||||
function! s:_extract_files(pattern, files) abort
|
||||
let tr = {'.': '/', '*': '[^/]*', '**': '.*'}
|
||||
let target = substitute(a:pattern, '\.\|\*\*\?', '\=tr[submatch(0)]', 'g')
|
||||
let regexp = printf('autoload/vital/[^/]\+/%s.vim$', target)
|
||||
return filter(a:files, 'v:val =~# regexp')
|
||||
endfunction
|
||||
|
||||
function! s:_file2module(file) abort
|
||||
let filename = fnamemodify(a:file, ':p:gs?[\\/]?/?')
|
||||
let tail = matchstr(filename, 'autoload/vital/_\w\+/\zs.*\ze\.vim$')
|
||||
return join(split(tail, '[\\/]\+'), '.')
|
||||
endfunction
|
||||
|
||||
" @param {string} name e.g. Data.List
|
||||
function! s:_import(name) abort dict
|
||||
if has_key(s:loaded, a:name)
|
||||
return copy(s:loaded[a:name])
|
||||
endif
|
||||
let module = self._get_module(a:name)
|
||||
if has_key(module, '_vital_created')
|
||||
call module._vital_created(module)
|
||||
endif
|
||||
let export_module = filter(copy(module), 'v:key =~# "^\\a"')
|
||||
" Cache module before calling module.vital_loaded() to avoid cyclic
|
||||
" dependences but remove the cache if module._vital_loaded() fails.
|
||||
" let s:loaded[a:name] = export_module
|
||||
let s:loaded[a:name] = export_module
|
||||
if has_key(module, '_vital_loaded')
|
||||
try
|
||||
call module._vital_loaded(vital#{s:plugin_name}#new())
|
||||
catch
|
||||
unlet s:loaded[a:name]
|
||||
throw 'vital: fail to call ._vital_loaded(): ' . v:exception
|
||||
endtry
|
||||
endif
|
||||
return copy(s:loaded[a:name])
|
||||
endfunction
|
||||
let s:Vital._import = s:_function('s:_import')
|
||||
|
||||
" s:_get_module() returns module object wihch has all script local functions.
|
||||
function! s:_get_module(name) abort dict
|
||||
let funcname = s:_import_func_name(self.plugin_name(), a:name)
|
||||
if s:_exists_autoload_func_with_source(funcname)
|
||||
return call(funcname, [])
|
||||
else
|
||||
return s:_get_builtin_module(a:name)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:_get_builtin_module(name) abort
|
||||
return s:sid2sfuncs(s:_module_sid(a:name))
|
||||
endfunction
|
||||
|
||||
if s:is_vital_vim
|
||||
" For vital.vim, we can use s:_get_builtin_module directly
|
||||
let s:Vital._get_module = s:_function('s:_get_builtin_module')
|
||||
else
|
||||
let s:Vital._get_module = s:_function('s:_get_module')
|
||||
endif
|
||||
|
||||
function! s:_import_func_name(plugin_name, module_name) abort
|
||||
return printf('vital#_%s#%s#import', a:plugin_name, s:_dot_to_sharp(a:module_name))
|
||||
endfunction
|
||||
|
||||
function! s:_module_sid(name) abort
|
||||
let path = s:_module_path(a:name)
|
||||
if !filereadable(path)
|
||||
throw 'vital: module not found: ' . a:name
|
||||
endif
|
||||
let vital_dir = s:is_vital_vim ? '__\w\+__' : printf('_\{1,2}%s\%%(__\)\?', s:plugin_name)
|
||||
let base = join([vital_dir, ''], '[/\\]\+')
|
||||
let p = base . substitute('' . a:name, '\.', '[/\\\\]\\+', 'g')
|
||||
let sid = s:_sid(path, p)
|
||||
if !sid
|
||||
call s:_source(path)
|
||||
let sid = s:_sid(path, p)
|
||||
if !sid
|
||||
throw printf('vital: cannot get <SID> from path: %s', path)
|
||||
endif
|
||||
endif
|
||||
return sid
|
||||
endfunction
|
||||
|
||||
function! s:_module_path(name) abort
|
||||
return get(s:_extract_files(a:name, s:vital_files()), 0, '')
|
||||
endfunction
|
||||
|
||||
function! s:_module_sid_base_dir() abort
|
||||
return s:is_vital_vim ? &rtp : s:project_root
|
||||
endfunction
|
||||
|
||||
function! s:_dot_to_sharp(name) abort
|
||||
return substitute(a:name, '\.', '#', 'g')
|
||||
endfunction
|
||||
|
||||
" It will sources autoload file if a given func is not already defined.
|
||||
function! s:_exists_autoload_func_with_source(funcname) abort
|
||||
if exists('*' . a:funcname)
|
||||
" Return true if a given func is already defined
|
||||
return 1
|
||||
endif
|
||||
" source a file which may include a given func definition and try again.
|
||||
let path = 'autoload/' . substitute(substitute(a:funcname, '#[^#]*$', '.vim', ''), '#', '/', 'g')
|
||||
call s:_runtime(path)
|
||||
return exists('*' . a:funcname)
|
||||
endfunction
|
||||
|
||||
function! s:_runtime(path) abort
|
||||
execute 'runtime' fnameescape(a:path)
|
||||
endfunction
|
||||
|
||||
function! s:_source(path) abort
|
||||
execute 'source' fnameescape(a:path)
|
||||
endfunction
|
||||
|
||||
" @vimlint(EVL102, 1, l:_)
|
||||
" @vimlint(EVL102, 1, l:__)
|
||||
function! s:_sid(path, filter_pattern) abort
|
||||
let unified_path = s:_unify_path(a:path)
|
||||
if has_key(s:cache_sid, unified_path)
|
||||
return s:cache_sid[unified_path]
|
||||
endif
|
||||
for line in filter(split(s:_redir(':scriptnames'), "\n"), 'v:val =~# a:filter_pattern')
|
||||
let [_, sid, path; __] = matchlist(line, '^\s*\(\d\+\):\s\+\(.\+\)\s*$')
|
||||
if s:_unify_path(path) is# unified_path
|
||||
let s:cache_sid[unified_path] = sid
|
||||
return s:cache_sid[unified_path]
|
||||
endif
|
||||
endfor
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! s:_redir(cmd) abort
|
||||
let [save_verbose, save_verbosefile] = [&verbose, &verbosefile]
|
||||
set verbose=0 verbosefile=
|
||||
redir => res
|
||||
silent! execute a:cmd
|
||||
redir END
|
||||
let [&verbose, &verbosefile] = [save_verbose, save_verbosefile]
|
||||
return res
|
||||
endfunction
|
||||
|
||||
if filereadable(expand('<sfile>:r') . '.VIM') " is case-insensitive or not
|
||||
let s:_unify_path_cache = {}
|
||||
" resolve() is slow, so we cache results.
|
||||
" Note: On windows, vim can't expand path names from 8.3 formats.
|
||||
" So if getting full path via <sfile> and $HOME was set as 8.3 format,
|
||||
" vital load duplicated scripts. Below's :~ avoid this issue.
|
||||
function! s:_unify_path(path) abort
|
||||
if has_key(s:_unify_path_cache, a:path)
|
||||
return s:_unify_path_cache[a:path]
|
||||
endif
|
||||
let value = tolower(fnamemodify(resolve(fnamemodify(
|
||||
\ a:path, ':p')), ':~:gs?[\\/]?/?'))
|
||||
let s:_unify_path_cache[a:path] = value
|
||||
return value
|
||||
endfunction
|
||||
else
|
||||
function! s:_unify_path(path) abort
|
||||
return resolve(fnamemodify(a:path, ':p:gs?[\\/]?/?'))
|
||||
endfunction
|
||||
endif
|
||||
|
||||
" copied and modified from Vim.ScriptLocal
|
||||
let s:SNR = join(map(range(len("\<SNR>")), '"[\\x" . printf("%0x", char2nr("\<SNR>"[v:val])) . "]"'), '')
|
||||
function! s:sid2sfuncs(sid) abort
|
||||
let fs = split(s:_redir(printf(':function /^%s%s_', s:SNR, a:sid)), "\n")
|
||||
let r = {}
|
||||
let pattern = printf('\m^function\s<SNR>%d_\zs\w\{-}\ze(', a:sid)
|
||||
for fname in map(fs, 'matchstr(v:val, pattern)')
|
||||
let r[fname] = function(s:_sfuncname(a:sid, fname))
|
||||
endfor
|
||||
return r
|
||||
endfunction
|
||||
|
||||
"" Return funcname of script local functions with SID
|
||||
function! s:_sfuncname(sid, funcname) abort
|
||||
return printf('<SNR>%s_%s', a:sid, a:funcname)
|
||||
endfunction
|
||||
|
||||
if exists('*uniq')
|
||||
function! s:_uniq(list) abort
|
||||
return uniq(a:list)
|
||||
endfunction
|
||||
else
|
||||
function! s:_uniq(list) abort
|
||||
let i = len(a:list) - 1
|
||||
while 0 < i
|
||||
if a:list[i] ==# a:list[i - 1]
|
||||
call remove(a:list, i)
|
||||
endif
|
||||
let i -= 1
|
||||
endwhile
|
||||
return a:list
|
||||
endfunction
|
||||
endif
|
20
vim/plugins/vim-easymotion/autoload/vital/easymotion.vital
Normal file
20
vim/plugins/vim-easymotion/autoload/vital/easymotion.vital
Normal file
@ -0,0 +1,20 @@
|
||||
easymotion
|
||||
882de6964d10595e839ccbcc0fb20b7ff14e43cb
|
||||
|
||||
Over.Commandline.Base
|
||||
Over.Commandline.Modules.Cancel
|
||||
Over.Commandline.Modules.BufferComplete
|
||||
Over.Commandline.Modules.Paste
|
||||
Over.Commandline.Modules.KeyMapping
|
||||
Over.Commandline.Modules.Doautocmd
|
||||
Over.Commandline.Modules.CursorMove
|
||||
Over.Commandline.Modules.Delete
|
||||
Over.Commandline.Modules.Redraw
|
||||
Over.Commandline.Modules.InsertRegister
|
||||
Over.Commandline.Modules.History
|
||||
Over.Commandline.Modules.NoInsert
|
||||
Over.Commandline.Modules.Exit
|
||||
Over.Commandline.Modules.DrawCommandline
|
||||
Over.Commandline.Modules.ExceptionMessage
|
||||
Over.Commandline.Modules.ExceptionExit
|
||||
HitAHint.Motion
|
Reference in New Issue
Block a user