Merge branch 'feature/vital-over' into master
This commit is contained in:
commit
f5fd47968e
@ -1,7 +1,7 @@
|
||||
" EasyMotion - Vim motions on speed!
|
||||
"
|
||||
" Author: haya14busa <hayabusa1419@gmail.com>
|
||||
" Last Change: 01 Feb 2014.
|
||||
" Last Change: 02 Feb 2014.
|
||||
" Source: https://github.com/haya14busa/vim-easymotion
|
||||
"
|
||||
" Original Author: Kim Silkebækken <kim.silkebaekken+vim@gmail.com>
|
||||
@ -575,7 +575,7 @@ function! s:findMotion(num_strokes, direction) "{{{
|
||||
|
||||
" Check that we have an input char
|
||||
if empty(input)
|
||||
redraw | return ''
|
||||
return ''
|
||||
endif
|
||||
|
||||
let re = s:convertRegep(input)
|
||||
|
@ -2,7 +2,7 @@
|
||||
" FILE: autoload/EasyMotion/command_line.vim
|
||||
" AUTHOR: haya14busa
|
||||
" Reference: https://github.com/osyo-manga/vim-over
|
||||
" Last Change: 26 Jan 2014.
|
||||
" Last Change: 01 Feb 2014.
|
||||
" License: MIT license {{{
|
||||
" Permission is hereby granted, free of charge, to any person obtaining
|
||||
" a copy of this software and associated documentation files (the
|
||||
@ -30,102 +30,101 @@ let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
" }}}
|
||||
|
||||
" Autocmd: {{{
|
||||
augroup plugin-easymotion-dummy
|
||||
autocmd!
|
||||
augroup END
|
||||
" CommandLine:
|
||||
let s:cmdline = vital#of("easymotion").import("Over.Commandline")
|
||||
let s:search = s:cmdline.make_plain("/")
|
||||
let s:search.highlights.prompt = "Question"
|
||||
|
||||
let s:cache_command = {}
|
||||
function! s:doautocmd_user(command) "{{{
|
||||
if !has_key(s:cache_command, a:command)
|
||||
execute "autocmd plugin-easymotion-dummy"
|
||||
\ . " User " . a:command." silent! execute ''"
|
||||
" Add Module: {{{
|
||||
call s:search.connect(s:cmdline.module_delete())
|
||||
call s:search.connect(s:cmdline.module_cursor_move())
|
||||
call s:search.connect(s:cmdline.module_paste())
|
||||
call s:search.connect(s:cmdline.module_buffer_complete())
|
||||
call s:search.connect(s:cmdline.module_history("/"))
|
||||
call s:search.connect(s:cmdline.module_no_insert_special_chars())
|
||||
|
||||
if v:version > 703 || v:version == 703 && has("patch438")
|
||||
" :helpgrep 7.4.438
|
||||
let s:cache_command[a:command] = "doautocmd <nomodeline> User " . a:command
|
||||
else
|
||||
let s:cache_command[a:command] = "doautocmd User " . a:command
|
||||
endif
|
||||
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
|
||||
|
||||
execute s:cache_command[a:command]
|
||||
endfunction "}}}
|
||||
|
||||
augroup easymotion-cmdline
|
||||
autocmd!
|
||||
autocmd User EasyMotionCmdLineEnter call s:init()
|
||||
autocmd User EasyMotionCmdLineLeave call s:finish()
|
||||
augroup END
|
||||
endfunction
|
||||
call s:search.connect(s:module)
|
||||
"}}}
|
||||
|
||||
" Activate:
|
||||
function! s:init() "{{{
|
||||
" Cursor
|
||||
let hl_cursor = EasyMotion#command_line#hl_cursor_off()
|
||||
if !hlexists("EasyMotionCommandLineCursor")
|
||||
execute "highlight EasyMotionCommandLineCursor " . hl_cursor . " term=underline gui=underline"
|
||||
endif
|
||||
" Save cursor visible
|
||||
let s:old_t_ve = &t_ve
|
||||
set t_ve=
|
||||
" CommandLine Keymap: {{{
|
||||
let s:default_key_mapping = {
|
||||
\ "\<C-d>" : "<Over>(buffer-complete)",
|
||||
\ "\<Tab>" : "<Over>(em-scroll-f)",
|
||||
\ "\<S-Tab>" : "<Over>(em-scroll-b)",
|
||||
\ "\<C-o>" : "<Over>(em-jumpback)",
|
||||
\ "\<C-z>" : "<Over>(em-openallfold)",
|
||||
\}
|
||||
function! EasyMotion#command_line#keymaps() "{{{
|
||||
return extend(deepcopy(s:default_key_mapping),
|
||||
\ g:EasyMotion_command_line_key_mappings)
|
||||
endfunction "}}}
|
||||
function! s:finish() "{{{
|
||||
" Cursor
|
||||
call EasyMotion#command_line#hl_cursor_on()
|
||||
let &t_ve = s:old_t_ve
|
||||
function! s:search.keymappings() "{{{
|
||||
return EasyMotion#command_line#keymaps()
|
||||
endfunction "}}}
|
||||
"}}}
|
||||
|
||||
function! EasyMotion#command_line#hl_cursor_off() "{{{
|
||||
if exists("s:old_hi_cursor")
|
||||
return s:old_hi_cursor
|
||||
endif
|
||||
let s:old_hi_cursor = 'cterm=reverse'
|
||||
if hlexists('Cursor')
|
||||
redir => cursor
|
||||
silent highlight Cursor
|
||||
redir END
|
||||
let hl = substitute(matchstr(cursor, 'xxx \zs.*'), '[ \t\n]\+\|cleared', ' ', 'g')
|
||||
if mode(1) == 'ce'
|
||||
" TODO: this section exists only for vim-vspec test...
|
||||
let hl = substitute(hl, '\sLast\sset\sfrom.*', '', '')
|
||||
endif
|
||||
if !empty(substitute(hl, '\s', '', 'g'))
|
||||
let s:old_hi_cursor = hl
|
||||
endif
|
||||
highlight Cursor NONE
|
||||
endif
|
||||
return s:old_hi_cursor
|
||||
endfunction "}}}
|
||||
function! EasyMotion#command_line#hl_cursor_on() "{{{
|
||||
if exists('s:old_hi_cursor')
|
||||
silent execute 'highlight Cursor ' . s:old_hi_cursor
|
||||
unlet s:old_hi_cursor
|
||||
endif
|
||||
endfunction "}}}
|
||||
|
||||
function! s:before_input(num_strokes) "{{{
|
||||
if a:num_strokes == -1 && g:EasyMotion_inc_highlight
|
||||
" Event: {{{
|
||||
function! s:search.on_enter() "{{{
|
||||
if s:num_strokes == -1
|
||||
call EasyMotion#highlight#delete_highlight()
|
||||
let shade_hl_re = '\_.*'
|
||||
call EasyMotion#highlight#add_highlight(shade_hl_re, g:EasyMotion_hl_group_shade)
|
||||
call EasyMotion#highlight#add_highlight('\%#', g:EasyMotion_hl_inc_cursor)
|
||||
endif
|
||||
endfunction "}}}
|
||||
function! s:after_input() "{{{
|
||||
call EasyMotion#highlight#delete_highlight()
|
||||
function! s:search.on_leave() "{{{
|
||||
call EasyMotion#highlight#delete_highlight(g:EasyMotion_hl_inc_search)
|
||||
endfunction "}}}
|
||||
function! s:search.on_char() "{{{
|
||||
if s:num_strokes == -1
|
||||
let re = s:search.getline()
|
||||
if g:EasyMotion_inc_highlight
|
||||
let case_flag = EasyMotion#helper#should_use_smartcase(re) ?
|
||||
\ '\c' : '\C'
|
||||
let re .= case_flag
|
||||
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 "}}}
|
||||
function! s:search.on_cancel() "{{{
|
||||
call s:Cancell()
|
||||
call s:search.setline('')
|
||||
endfunction "}}}
|
||||
"}}}
|
||||
|
||||
" Main:
|
||||
function! EasyMotion#command_line#GetInput(num_strokes, prev, direction) "{{{
|
||||
call s:doautocmd_user("EasyMotionCmdLineEnter")
|
||||
let previous_input = a:prev
|
||||
let s:save_direction = a:direction == 1 ? 'b' : ''
|
||||
let s:direction = s:save_direction
|
||||
let s:num_strokes = a:num_strokes
|
||||
|
||||
" CommandLine: Input string and cursor position
|
||||
let s:command_line = s:string_with_pos('')
|
||||
let prompt = s:getPromptMessage(a:num_strokes)
|
||||
let s:search.prompt = s:getPromptMessage(a:num_strokes)
|
||||
|
||||
" Screen: cursor position, first and last line
|
||||
let s:orig_pos = getpos('.')
|
||||
@ -133,305 +132,22 @@ function! EasyMotion#command_line#GetInput(num_strokes, prev, direction) "{{{
|
||||
let s:orig_line_end = getpos('w$')
|
||||
let s:save_orig_pos = deepcopy(s:orig_pos)
|
||||
|
||||
call s:before_input(a:num_strokes)
|
||||
" Direction:
|
||||
let s:direction = a:direction == 1 ? 'b' : ''
|
||||
let s:save_direction = deepcopy(s:direction)
|
||||
|
||||
let s:search_hist = []
|
||||
let s:search_cnt = 0
|
||||
|
||||
try
|
||||
while s:command_line.length() < a:num_strokes ||
|
||||
\ a:num_strokes == -1
|
||||
if g:EasyMotion_show_prompt
|
||||
call s:echo_cmdline(prompt, s:command_line)
|
||||
endif
|
||||
|
||||
let c = getchar()
|
||||
let s:char = type(c) == type(0) ? nr2char(c) : c
|
||||
|
||||
if EasyMotion#command_line#is_input("\<Esc>") ||
|
||||
\ EasyMotion#command_line#is_input("\<C-c>")
|
||||
" Cancel if Escape key pressed
|
||||
call s:Cancell()
|
||||
call s:command_line.set('')
|
||||
break
|
||||
elseif EasyMotion#command_line#is_input("\<CR>")
|
||||
if s:command_line.length() == 0
|
||||
call s:command_line.set(previous_input)
|
||||
break
|
||||
endif
|
||||
break
|
||||
elseif EasyMotion#command_line#is_input("\<C-j>")
|
||||
break
|
||||
elseif EasyMotion#command_line#is_input("\<C-h>")
|
||||
" Delete one character
|
||||
if s:command_line.length() == 0
|
||||
call s:Cancell() | break
|
||||
endif
|
||||
call s:command_line.remove_prev()
|
||||
elseif EasyMotion#command_line#is_input("\<C-d>")
|
||||
" Delete one character
|
||||
if s:command_line.length() == 0
|
||||
call s:Cancell() | break
|
||||
endif
|
||||
call s:command_line.remove_pos()
|
||||
elseif EasyMotion#command_line#is_input("\<C-u>")
|
||||
" Delete all
|
||||
if s:command_line.length() == 0
|
||||
call s:Cancell() | break
|
||||
endif
|
||||
call s:command_line.set(s:command_line.pos_word() .
|
||||
\ s:command_line.forward()) "string
|
||||
call s:command_line.set(0) " cursor
|
||||
elseif EasyMotion#command_line#is_input("\<C-w>")
|
||||
" Delete word
|
||||
let backward = matchstr(s:command_line.backward(),
|
||||
\ '\v^\zs.\{-}\ze((\w*)|(.))$')
|
||||
call s:command_line.set(backward . s:command_line.pos_word() . s:command_line.forward())
|
||||
call s:command_line.set(strchars(backward))
|
||||
elseif EasyMotion#command_line#is_input("\<C-p>") ||
|
||||
\ EasyMotion#command_line#is_input("\<C-n>")
|
||||
" History
|
||||
if s:search_cnt == 0 && empty(s:search_hist)
|
||||
let cmdline = '^' . EasyMotion#command_line#getline()
|
||||
let s:search_hist = filter(s:search_histories(), 'v:val =~ cmdline')
|
||||
endif
|
||||
if EasyMotion#command_line#is_input("\<C-n>")
|
||||
let s:search_cnt = max([s:search_cnt - 1, 0])
|
||||
endif
|
||||
if EasyMotion#command_line#is_input("\<C-p>")
|
||||
let s:search_cnt = min([s:search_cnt + 1, len(s:search_hist)])
|
||||
endif
|
||||
call EasyMotion#command_line#setline(
|
||||
\ get(s:search_hist, s:search_cnt,
|
||||
\ EasyMotion#command_line#getline()))
|
||||
elseif EasyMotion#command_line#is_input("\<Tab>")
|
||||
call s:scroll(0)
|
||||
elseif EasyMotion#command_line#is_input("\<S-Tab>")
|
||||
call s:scroll(1)
|
||||
elseif EasyMotion#command_line#is_input("\<C-o>")
|
||||
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
|
||||
elseif EasyMotion#command_line#is_input("\<C-z>")
|
||||
" TODO: better solution
|
||||
normal! zR
|
||||
elseif EasyMotion#command_line#is_input("\<C-f>")
|
||||
call s:command_line.next()
|
||||
elseif EasyMotion#command_line#is_input("\<C-b>")
|
||||
call s:command_line.prev()
|
||||
elseif EasyMotion#command_line#is_input("\<C-a>")
|
||||
call s:command_line.set(0)
|
||||
elseif EasyMotion#command_line#is_input("\<C-e>")
|
||||
call s:command_line.set(s:command_line.length())
|
||||
elseif char2nr(s:char) == 128 || char2nr(s:char) < 27
|
||||
" Do nothing for special key
|
||||
continue
|
||||
else
|
||||
call s:command_line.input(s:char)
|
||||
endif
|
||||
|
||||
" Incremental routine {{{
|
||||
if a:num_strokes == -1
|
||||
let re = s:command_line.str()
|
||||
let case_flag = EasyMotion#helper#should_use_smartcase(re) ?
|
||||
\ '\c' : '\C'
|
||||
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 "}}}
|
||||
endif
|
||||
"}}}
|
||||
endwhile
|
||||
finally
|
||||
call s:after_input()
|
||||
call s:doautocmd_user("EasyMotionCmdLineLeave")
|
||||
endtry
|
||||
return s:command_line.str()
|
||||
endfunction "}}}
|
||||
function! EasyMotion#command_line#char() "{{{
|
||||
return s:char
|
||||
endfunction "}}}
|
||||
function! EasyMotion#command_line#is_input(key) "{{{
|
||||
return EasyMotion#command_line#keymap(EasyMotion#command_line#char()) == a:key
|
||||
endfunction "}}}
|
||||
function! EasyMotion#command_line#keymap(key) "{{{
|
||||
return get(extend(deepcopy(s:default_key_mapping), g:EasyMotion_command_line_key_mappings), a:key, a:key)
|
||||
endfunction "}}}
|
||||
" Default_key_mapping: {{{
|
||||
let s:default_key_mapping = {
|
||||
\ "\<Right>" : "\<C-f>",
|
||||
\ "\<Left>" : "\<C-b>",
|
||||
\ "\<Up>" : "\<C-p>",
|
||||
\ "\<Down>" : "\<C-n>",
|
||||
\ "\<BS>" : "\<C-h>",
|
||||
\ "\<Del>" : "\<C-d>",
|
||||
\ "\<Home>" : "\<C-a>",
|
||||
\ "\<End>" : "\<C-e>",
|
||||
\}
|
||||
"}}}
|
||||
|
||||
" CommandLine:
|
||||
function! s:echo_cmdline(prompt, pstr) "{{{
|
||||
" pstr -> cursor pos & string
|
||||
redraw
|
||||
echohl Question | echon a:prompt | echohl NONE
|
||||
echon a:pstr.backward()
|
||||
|
||||
echohl EasyMotionCommandLineCursor
|
||||
if empty(a:pstr.pos_word())
|
||||
echon ' '
|
||||
let input = s:search.get()
|
||||
if input == '' && ! s:search.exit_code()
|
||||
return a:prev
|
||||
else
|
||||
echon a:pstr.pos_word()
|
||||
return input
|
||||
endif
|
||||
echohl NONE
|
||||
|
||||
echon a:pstr.forward()
|
||||
endfunction "}}}
|
||||
function! s:string_with_pos(...) "{{{
|
||||
" string with cursor position
|
||||
" emulate cursor using list
|
||||
|
||||
let default = get(a:, 1, '') " placeholder
|
||||
let self = {} " OOP
|
||||
|
||||
" NOTE: {{{
|
||||
" 'V!m!s{cursor}hment'
|
||||
" self.list = ['V', '!', 'm', '!', 's', 'h', 'm', 'e', 'n', 't']
|
||||
" 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9
|
||||
" self.col = 5 -> cursor
|
||||
" self.length() = 10
|
||||
" self.backward() = 'V!m!s'
|
||||
" self.pos_word() = 'h'
|
||||
" self.forward() = 'ment'
|
||||
" self.str() = 'V!m!s{cursor}hment'
|
||||
"}}}
|
||||
|
||||
" Set: {{{
|
||||
function! self.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! self.set_str(str)
|
||||
" set string
|
||||
let self.list = split(a:str, '\zs')
|
||||
let self.col = EasyMotion#helper#strchars(a:str)
|
||||
return self
|
||||
endfunction
|
||||
|
||||
function! self.set_pos(pos)
|
||||
" set cursor position
|
||||
let self.col = s:clamp(a:pos, 0, self.length())
|
||||
return self
|
||||
endfunction
|
||||
"}}}
|
||||
|
||||
" Get Input: {{{
|
||||
function! self.str()
|
||||
" to string
|
||||
return join(self.list, '')
|
||||
endfunction
|
||||
|
||||
function! self.backward()
|
||||
" get string backward from cursor pos
|
||||
return self.col > 0 ? join(self.list[ : self.col-1], '') : ''
|
||||
endfunction
|
||||
|
||||
function! self.forward()
|
||||
" get string forward from cursor pos
|
||||
return join(self.list[self.col+1 : ], '')
|
||||
endfunction
|
||||
|
||||
function! self.pos_word()
|
||||
" get cursor position character (word)
|
||||
return get(self.list, self.col, '')
|
||||
endfunction
|
||||
"}}}
|
||||
|
||||
" Input: {{{
|
||||
function! self.input(str)
|
||||
call extend(self.list, split(a:str, '\zs'), self.col)
|
||||
let self.col += len(split(a:str, '\zs'))
|
||||
return self
|
||||
endfunction
|
||||
"}}}
|
||||
|
||||
" Move Cursor: {{{
|
||||
function! self.next()
|
||||
return self.set_pos(self.col + 1)
|
||||
endfunction
|
||||
|
||||
function! self.prev()
|
||||
return self.set_pos(self.col - 1)
|
||||
endfunction
|
||||
"}}}
|
||||
|
||||
" Remove: {{{
|
||||
function! self.remove(index)
|
||||
" Remove character
|
||||
if a:index < 0 || self.length() <= a:index
|
||||
return self
|
||||
endif
|
||||
unlet self.list[a:index]
|
||||
if a:index < self.col
|
||||
call self.set(self.col - 1)
|
||||
endif
|
||||
return self
|
||||
endfunction
|
||||
|
||||
function! self.remove_pos()
|
||||
return self.remove(self.col)
|
||||
endfunction
|
||||
|
||||
function! self.remove_prev()
|
||||
return self.remove(self.col - 1)
|
||||
endfunction
|
||||
|
||||
function! self.remove_next()
|
||||
return self.remove(self.col + 1)
|
||||
endfunction
|
||||
"}}}
|
||||
|
||||
" Helper: {{{
|
||||
function! self.pos()
|
||||
" describe cursor position as column number
|
||||
return self.col
|
||||
endfunction
|
||||
|
||||
function! self.length()
|
||||
return len(self.list)
|
||||
endfunction
|
||||
"}}}
|
||||
|
||||
call self.set(default)
|
||||
return self
|
||||
endfunction "}}}
|
||||
function! s:clamp(value, min, max) "{{{
|
||||
return min([max([a:value, a:min]), a:max])
|
||||
endfunction "}}}
|
||||
function! EasyMotion#command_line#getline() "{{{
|
||||
return s:command_line.str()
|
||||
endfunction "}}}
|
||||
function! EasyMotion#command_line#setline(line) "{{{
|
||||
call s:command_line.set(a:line)
|
||||
endfunction "}}}
|
||||
|
||||
" Helper:
|
||||
function! s:InputPrompt(message, input) "{{{
|
||||
redraw
|
||||
echohl Question | echon a:message | echohl None
|
||||
echon a:input
|
||||
endfunction "}}}
|
||||
function! s:Cancell() " {{{
|
||||
call s:after_input()
|
||||
call EasyMotion#highlight#delete_highlight()
|
||||
keepjumps call setpos('.', s:save_orig_pos)
|
||||
redraw
|
||||
echo 'EasyMotion: Cancelled'
|
||||
return ''
|
||||
endfunction " }}}
|
||||
@ -455,6 +171,7 @@ 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
|
||||
@ -497,18 +214,14 @@ function! s:scroll(direction) "{{{
|
||||
let s:orig_line_end = getpos('w$')
|
||||
let s:direction = a:direction == 0 ? '' : 'b'
|
||||
endfunction "}}}
|
||||
function! s:search_histories() "{{{
|
||||
return map(range(&history), 'histget("search", v:val * -1)')
|
||||
endfunction "}}}
|
||||
function! s:inc_highlight(re) "{{{
|
||||
call EasyMotion#highlight#delete_highlight('EasyMotionIncSearch')
|
||||
if s:command_line.length() > 0
|
||||
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
|
||||
|
12
autoload/vital.vim
Normal file
12
autoload/vital.vim
Normal file
@ -0,0 +1,12 @@
|
||||
function! vital#of(name)
|
||||
let files = globpath(&runtimepath, 'autoload/vital/' . a:name . '.vital')
|
||||
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
|
203
autoload/vital/_easymotion.vim
Normal file
203
autoload/vital/_easymotion.vim
Normal file
@ -0,0 +1,203 @@
|
||||
let s:self_version = expand('<sfile>:t:r')
|
||||
|
||||
" Note: The extra argument to globpath() was added in Patch 7.2.051.
|
||||
let s:globpath_third_arg = v:version > 702 || v:version == 702 && has('patch51')
|
||||
|
||||
let s:loaded = {}
|
||||
|
||||
function! s:import(name, ...)
|
||||
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 = s:_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
|
||||
|
||||
function! s:load(...) 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
|
||||
while 1 <= len(target)
|
||||
let ns = remove(target, 0)
|
||||
if !has_key(dict, ns)
|
||||
let dict[ns] = {}
|
||||
endif
|
||||
if type(dict[ns]) == type({})
|
||||
let dict = dict[ns]
|
||||
else
|
||||
unlet dict
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
|
||||
if exists('dict')
|
||||
call extend(dict, s:_import(name))
|
||||
endif
|
||||
unlet arg
|
||||
endfor
|
||||
return self
|
||||
endfunction
|
||||
|
||||
function! s:unload()
|
||||
let s:loaded = {}
|
||||
endfunction
|
||||
|
||||
function! s:_import(name)
|
||||
if type(a:name) == type(0)
|
||||
return s:_build_module(a:name)
|
||||
endif
|
||||
let path = s:_get_module_path(a:name)
|
||||
if path ==# ''
|
||||
throw 'vital: module not found: ' . a:name
|
||||
endif
|
||||
let sid = get(s:_scripts(), path, 0)
|
||||
if !sid
|
||||
try
|
||||
execute 'source' fnameescape(path)
|
||||
catch /^Vim\%((\a\+)\)\?:E484/
|
||||
throw 'vital: module not found: ' . a:name
|
||||
catch /^Vim\%((\a\+)\)\?:E127/
|
||||
" Ignore.
|
||||
endtry
|
||||
|
||||
let sid = s:_scripts()[path]
|
||||
endif
|
||||
return s:_build_module(sid)
|
||||
endfunction
|
||||
|
||||
function! s:_get_module_path(name)
|
||||
if s:_is_absolute_path(a:name) && filereadable(a:name)
|
||||
return s:_unify_path(a:name)
|
||||
endif
|
||||
if a:name ==# ''
|
||||
let tailpath = printf('autoload/vital/%s.vim', s:self_version)
|
||||
elseif a:name =~# '\v^\u\w*%(\.\u\w*)*$'
|
||||
let target = '/' . substitute(a:name, '\W\+', '/', 'g')
|
||||
let tailpath = printf('autoload/vital/%s%s.vim', s:self_version, target)
|
||||
else
|
||||
throw 'vital: Invalid module name: ' . a:name
|
||||
endif
|
||||
|
||||
if s:globpath_third_arg
|
||||
let paths = split(globpath(&runtimepath, tailpath, 1), "\n")
|
||||
else
|
||||
let paths = split(globpath(&runtimepath, tailpath), "\n")
|
||||
endif
|
||||
call filter(paths, 'filereadable(v:val)')
|
||||
return s:_unify_path(get(paths, 0, ''))
|
||||
endfunction
|
||||
|
||||
function! s:_scripts()
|
||||
let scripts = {}
|
||||
for line in filter(split(s:_redir('scriptnames'), "\n"),
|
||||
\ 'stridx(v:val, s:self_version) > 0')
|
||||
let list = matchlist(line, '^\s*\(\d\+\):\s\+\(.\+\)\s*$')
|
||||
if !empty(list)
|
||||
let scripts[s:_unify_path(list[2])] = list[1] - 0
|
||||
endif
|
||||
endfor
|
||||
return scripts
|
||||
endfunction
|
||||
|
||||
if filereadable(expand('<sfile>:r') . '.VIM')
|
||||
function! s:_unify_path(path)
|
||||
" 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.
|
||||
return tolower(fnamemodify(resolve(fnamemodify(
|
||||
\ a:path, ':p:gs?[\\/]\+?/?')), ':~'))
|
||||
endfunction
|
||||
else
|
||||
function! s:_unify_path(path)
|
||||
return resolve(fnamemodify(a:path, ':p:gs?[\\/]\+?/?'))
|
||||
endfunction
|
||||
endif
|
||||
|
||||
" Copy from System.Filepath
|
||||
if has('win16') || has('win32') || has('win64')
|
||||
function! s:_is_absolute_path(path)
|
||||
return a:path =~? '^[a-z]:[/\\]'
|
||||
endfunction
|
||||
else
|
||||
function! s:_is_absolute_path(path)
|
||||
return a:path[0] ==# '/'
|
||||
endfunction
|
||||
endif
|
||||
|
||||
function! s:_build_module(sid)
|
||||
if has_key(s:loaded, a:sid)
|
||||
return copy(s:loaded[a:sid])
|
||||
endif
|
||||
let functions = s:_get_functions(a:sid)
|
||||
|
||||
let prefix = '<SNR>' . a:sid . '_'
|
||||
let module = {}
|
||||
for func in functions
|
||||
let module[func] = function(prefix . func)
|
||||
endfor
|
||||
if has_key(module, '_vital_loaded')
|
||||
let V = vital#{s:self_version}#new()
|
||||
if has_key(module, '_vital_depends')
|
||||
call call(V.load, module._vital_depends(), V)
|
||||
endif
|
||||
try
|
||||
call module._vital_loaded(V)
|
||||
catch
|
||||
" FIXME: Show an error message for debug.
|
||||
endtry
|
||||
endif
|
||||
if !get(g:, 'vital_debug', 0)
|
||||
call filter(module, 'v:key =~# "^\\a"')
|
||||
endif
|
||||
let s:loaded[a:sid] = module
|
||||
return copy(module)
|
||||
endfunction
|
||||
|
||||
if exists('+regexpengine')
|
||||
function! s:_get_functions(sid)
|
||||
let funcs = s:_redir(printf("function /\\%%#=2^\<SNR>%d_", a:sid))
|
||||
let map_pat = '<SNR>' . a:sid . '_\zs\w\+'
|
||||
return map(split(funcs, "\n"), 'matchstr(v:val, map_pat)')
|
||||
endfunction
|
||||
else
|
||||
function! s:_get_functions(sid)
|
||||
let prefix = '<SNR>' . a:sid . '_'
|
||||
let funcs = s:_redir('function')
|
||||
let filter_pat = '^\s*function ' . prefix
|
||||
let map_pat = prefix . '\zs\w\+'
|
||||
return map(filter(split(funcs, "\n"),
|
||||
\ 'stridx(v:val, prefix) > 0 && v:val =~# filter_pat'),
|
||||
\ 'matchstr(v:val, map_pat)')
|
||||
endfunction
|
||||
endif
|
||||
|
||||
function! s:_redir(cmd)
|
||||
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
|
||||
|
||||
function! vital#{s:self_version}#new()
|
||||
return s:_import('')
|
||||
endfunction
|
482
autoload/vital/_easymotion/Over/Commandline.vim
Normal file
482
autoload/vital/_easymotion/Over/Commandline.vim
Normal file
@ -0,0 +1,482 @@
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
let s:modules = [
|
||||
\ "Scroll",
|
||||
\ "CursorMove",
|
||||
\ "Delete",
|
||||
\ "Paste",
|
||||
\ "HistAdd",
|
||||
\ "History",
|
||||
\ "Incsearch",
|
||||
\ "BufferComplete",
|
||||
\ "Cancel",
|
||||
\ "Enter",
|
||||
\ "NoInsert",
|
||||
\]
|
||||
|
||||
let s:modules_snake = [
|
||||
\ "scroll",
|
||||
\ "cursor_move",
|
||||
\ "delete",
|
||||
\ "paste",
|
||||
\ "histadd",
|
||||
\ "history",
|
||||
\ "incsearch",
|
||||
\ "buffer_complete",
|
||||
\ "cancel",
|
||||
\ "enter",
|
||||
\ "no_insert",
|
||||
\]
|
||||
|
||||
|
||||
function! s:_vital_loaded(V)
|
||||
let s:V = a:V
|
||||
for module in s:modules
|
||||
let s:{module} = s:V.import('Over.Commandline.Modules.' . module)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_vital_depends()
|
||||
return map(copy(s:modules), "'Over.Commandline.Modules.' . v:val")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make_plain(prompt)
|
||||
let result = deepcopy(s:base)
|
||||
let result.prompt = a:prompt
|
||||
call result.connect(s:module_cancel())
|
||||
call result.connect(s:module_enter())
|
||||
return result
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make_simple(prompt)
|
||||
let result = s:make_plain(a:prompt)
|
||||
call result.connect(s:module_scroll())
|
||||
call result.connect(s:module_delete())
|
||||
call result.connect(s:module_cursor_move())
|
||||
call result.connect(s:module_histadd())
|
||||
call result.connect(s:module_history())
|
||||
call result.connect(s:module_buffer_complete())
|
||||
call result.connect(s:module_no_insert_special_chars())
|
||||
return result
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make(prompt)
|
||||
return s:make_simple(a:prompt)
|
||||
endfunction
|
||||
|
||||
|
||||
let s:base = {
|
||||
\ "prompt" : "> ",
|
||||
\ "line" : {},
|
||||
\ "variables" : {
|
||||
\ "char" : "",
|
||||
\ "input" : "",
|
||||
\ "wait_key" : "",
|
||||
\ "exit" : 0,
|
||||
\ },
|
||||
\ "highlights" : {
|
||||
\ "prompt" : "NONE",
|
||||
\ "cursor" : "OverCommandLineDefaultCursor",
|
||||
\ "cursor_insert" : "OverCommandLineDefaultCursorInsert"
|
||||
\ },
|
||||
\ "modules" : {},
|
||||
\ "keys" : {
|
||||
\ "quit" : "\<Esc>",
|
||||
\ "enter" : "\<CR>",
|
||||
\ }
|
||||
\}
|
||||
|
||||
|
||||
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)
|
||||
let self.variables.input = a:char
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.getpos()
|
||||
return self.line.pos()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.setpos(pos)
|
||||
return self.line.set_pos(pos)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.wait_keyinput_on(key)
|
||||
let self.variables.wait_key = a:key
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.wait_keyinput_off(key)
|
||||
if self.variables.wait_key == a:key
|
||||
let self.variables.wait_key = ""
|
||||
return 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.get_wait_keyinput()
|
||||
return self.variables.wait_key
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.is_input(key, ...)
|
||||
let prekey = get(a:, 1, "")
|
||||
return self.get_wait_keyinput() == prekey
|
||||
\ && get(self.keymappings(), self.char(), self.char()) == a:key
|
||||
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.connect(module, ...)
|
||||
let name = get(a:, 1, a:module.name)
|
||||
let self.modules[name] = a:module
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.disconnect(name)
|
||||
unlet self.modules[a:name] = a:module
|
||||
endfunction
|
||||
|
||||
|
||||
for s:_ in ["enter", "leave", "char", "char_pre", "execute_pre", "execute_failed", "execute", "cancel"]
|
||||
execute join([
|
||||
\ "function! s:base._on_" . s:_ . "()",
|
||||
\ " call map(copy(self.modules), 'has_key(v:val, \"on_" . s:_ . "\") ? v:val.on_" . s:_ . "(self) : 0')",
|
||||
\ " call self.on_" . s:_ . "()",
|
||||
\ "endfunction",
|
||||
\ ], "\n")
|
||||
|
||||
execute "function! s:base.on_" . s:_ . "()"
|
||||
endfunction
|
||||
endfor
|
||||
unlet s:_
|
||||
|
||||
|
||||
" Overridable
|
||||
function! s:base.keymappings()
|
||||
return {}
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.execute()
|
||||
execute self.getline()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.exit(...)
|
||||
let self.variables.exit = 1
|
||||
let self.variables.exit_code = get(a:, 1, 0)
|
||||
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.start(...)
|
||||
let exit_code = call(self._main, a:000, self)
|
||||
if exit_code == 0
|
||||
call self._execute()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base.get(...)
|
||||
let exit_code = call(self._main, a:000, self)
|
||||
if exit_code == 0
|
||||
return self.getline()
|
||||
endif
|
||||
return ""
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base._init()
|
||||
let self.variables.wait_key = ""
|
||||
let self.variables.char = ""
|
||||
let self.variables.input = ""
|
||||
let self.variables.exit = 0
|
||||
let self.variables.exit_code = 1
|
||||
let hl_cursor = s:_hl_cursor_off()
|
||||
if !hlexists("OverCommandLineDefaultCursor")
|
||||
execute "highlight OverCommandLineDefaultCursor " . hl_cursor
|
||||
endif
|
||||
if !hlexists("OverCommandLineDefaultCursorInsert")
|
||||
execute "highlight OverCommandLineDefaultCursorInsert " . hl_cursor . " term=underline gui=underline"
|
||||
endif
|
||||
let s:old_t_ve = &t_ve
|
||||
set t_ve=
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base._execute()
|
||||
call s:_redraw()
|
||||
call self._on_execute_pre()
|
||||
try
|
||||
call self.execute()
|
||||
catch
|
||||
echohl ErrorMsg
|
||||
echo matchstr(v:exception, 'Vim\((\w*)\)\?:\zs.*\ze')
|
||||
echohl None
|
||||
call self._on_execute_failed()
|
||||
finally
|
||||
call self._on_execute()
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base._main(...)
|
||||
try
|
||||
call self._init()
|
||||
let self.line = deepcopy(s:_string_with_pos(get(a:, 1, "")))
|
||||
call self._on_enter()
|
||||
|
||||
while !self._is_exit()
|
||||
call s:_echo_cmdline(self)
|
||||
|
||||
let self.variables.char = s:_getchar()
|
||||
call self.setchar(self.variables.char)
|
||||
|
||||
call self._on_char_pre()
|
||||
call self.insert(self.variables.input)
|
||||
call self._on_char()
|
||||
endwhile
|
||||
catch
|
||||
echohl ErrorMsg | echo v:throwpoint . " " . v:exception | echohl None
|
||||
finally
|
||||
call self._finish()
|
||||
call self._on_leave()
|
||||
call s:_redraw()
|
||||
endtry
|
||||
return self.exit_code()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base._finish()
|
||||
cal s:_hl_cursor_on()
|
||||
let &t_ve = s:old_t_ve
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_echo_cmdline(cmdline)
|
||||
call s:_redraw()
|
||||
execute "echohl" a:cmdline.highlights.prompt
|
||||
echon a:cmdline.prompt
|
||||
echohl NONE
|
||||
echon a:cmdline.backward()
|
||||
if empty(a:cmdline.line.pos_word())
|
||||
execute "echohl" a:cmdline.highlights.cursor
|
||||
echon ' '
|
||||
else
|
||||
execute "echohl" a:cmdline.highlights.cursor_insert
|
||||
echon a:cmdline.line.pos_word()
|
||||
endif
|
||||
echohl NONE
|
||||
echon a:cmdline.forward()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:base._is_exit()
|
||||
return self.variables.exit
|
||||
endfunction
|
||||
|
||||
|
||||
|
||||
for s:i in range(len(s:modules_snake))
|
||||
execute join([
|
||||
\ "function! s:module_" . s:modules_snake[s:i] . "(...)",
|
||||
\ " return call(s:" . s:modules[s:i] . ".make, a:000, s:" . s:modules[s:i] . ")",
|
||||
\ "endfunction",
|
||||
\ ], "\n")
|
||||
endfor
|
||||
unlet s:i
|
||||
|
||||
function! s:module_no_insert_special_chars()
|
||||
return s:NoInsert.make_special_chars()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_redraw()
|
||||
redraw
|
||||
echo ""
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_getchar()
|
||||
let char = getchar()
|
||||
return type(char) == type(0) ? nr2char(char) : char
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_hl_cursor_on()
|
||||
if exists("s:old_hi_cursor")
|
||||
execute "highlight Cursor " . s:old_hi_cursor
|
||||
unlet s:old_hi_cursor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_hl_cursor_off()
|
||||
if exists("s:old_hi_cursor")
|
||||
return s:old_hi_cursor
|
||||
endif
|
||||
let s:old_hi_cursor = "cterm=reverse"
|
||||
if hlexists("Cursor")
|
||||
let save_verbose = &verbose
|
||||
let &verbose = 0
|
||||
try
|
||||
redir => cursor
|
||||
silent highlight Cursor
|
||||
redir END
|
||||
finally
|
||||
let &verbose = save_verbose
|
||||
endtry
|
||||
let hl = substitute(matchstr(cursor, 'xxx \zs.*'), '[ \t\n]\+\|cleared', ' ', 'g')
|
||||
if !empty(substitute(hl, '\s', '', 'g'))
|
||||
let s:old_hi_cursor = hl
|
||||
endif
|
||||
highlight Cursor NONE
|
||||
endif
|
||||
return s:old_hi_cursor
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_clamp(x, max, min)
|
||||
return min([max([a:x, a:max]), a:min])
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:_string_with_pos(...)
|
||||
let default = get(a:, 1, "")
|
||||
let self = {}
|
||||
|
||||
function! self.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! self.str()
|
||||
return join(self.list, "")
|
||||
endfunction
|
||||
|
||||
function! self.set_pos(pos)
|
||||
let self.col = s:_clamp(a:pos, 0, self.length())
|
||||
return self
|
||||
endfunction
|
||||
|
||||
function! self.backward()
|
||||
return self.col > 0 ? join(self.list[ : self.col-1], '') : ""
|
||||
endfunction
|
||||
|
||||
function! self.forward()
|
||||
return join(self.list[self.col+1 : ], '')
|
||||
endfunction
|
||||
|
||||
function! self.pos_word()
|
||||
return get(self.list, self.col, "")
|
||||
endfunction
|
||||
|
||||
function! self.set_str(str)
|
||||
let self.list = split(a:str, '\zs')
|
||||
let self.col = strchars(a:str)
|
||||
return self
|
||||
endfunction
|
||||
|
||||
function! self.pos()
|
||||
return self.col
|
||||
endfunction
|
||||
|
||||
function! self.input(str)
|
||||
call extend(self.list, split(a:str, '\zs'), self.col)
|
||||
let self.col += len(split(a:str, '\zs'))
|
||||
return self
|
||||
endfunction
|
||||
|
||||
function! self.length()
|
||||
return len(self.list)
|
||||
endfunction
|
||||
|
||||
function! self.next()
|
||||
return self.set_pos(self.col + 1)
|
||||
endfunction
|
||||
|
||||
function! self.prev()
|
||||
return self.set_pos(self.col - 1)
|
||||
endfunction
|
||||
|
||||
function! self.remove(index)
|
||||
if a:index < 0 || self.length() <= a:index
|
||||
return self
|
||||
endif
|
||||
unlet self.list[a:index]
|
||||
if a:index < self.col
|
||||
call self.set(self.col - 1)
|
||||
endif
|
||||
return self
|
||||
endfunction
|
||||
|
||||
function! self.remove_pos()
|
||||
return self.remove(self.col)
|
||||
endfunction
|
||||
|
||||
function! self.remove_prev()
|
||||
return self.remove(self.col - 1)
|
||||
endfunction
|
||||
|
||||
function! self.remove_next()
|
||||
return self.remove(self.col + 1)
|
||||
endfunction
|
||||
|
||||
call self.set(default)
|
||||
return self
|
||||
endfunction
|
||||
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,149 @@
|
||||
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)
|
||||
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
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if a:cmdline.is_input("<Over>(buffer-complete)")
|
||||
if self.complete(a:cmdline) == -1
|
||||
call s:_finish()
|
||||
call a:cmdline.setchar('')
|
||||
return
|
||||
endif
|
||||
call a:cmdline.setchar('')
|
||||
call a:cmdline.wait_keyinput_on("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("\<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.wait_keyinput_off("Completion")
|
||||
call a:cmdline._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)
|
||||
endif
|
||||
if len(s:complete_list) == 1
|
||||
call a:cmdline.wait_keyinput_off("Completion")
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_leave(cmdline)
|
||||
unlet! s:complete
|
||||
endfunction
|
||||
|
||||
function! s:make()
|
||||
return deepcopy(s:module)
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,26 @@
|
||||
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>")
|
||||
\ ||(a:cmdline.is_input("\<BS>") && a:cmdline.line.length() == 0)
|
||||
\ ||(a:cmdline.is_input("\<C-h>") && a:cmdline.line.length() == 0)
|
||||
call a:cmdline.cancel()
|
||||
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,34 @@
|
||||
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('')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make()
|
||||
return deepcopy(s:module)
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,36 @@
|
||||
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>")
|
||||
call a:cmdline.line.remove_prev()
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("\<Del>")
|
||||
call a:cmdline.line.remove_pos()
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("\<C-w>")
|
||||
let backward = matchstr(a:cmdline.backward(), '^\zs.\{-}\ze\(\(\w*\)\|\(.\)\)$')
|
||||
call a:cmdline.setline(backward . a:cmdline.line.pos_word() . 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_word() . 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,25 @@
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "Enter"
|
||||
\}
|
||||
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if a:cmdline.is_input("\<CR>")
|
||||
\ || a:cmdline.is_input("\<NL>")
|
||||
\ || a:cmdline.is_input("\<C-j>")
|
||||
call a:cmdline.exit(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,23 @@
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "HistAdd",
|
||||
\ "mode" : "cmd"
|
||||
\}
|
||||
|
||||
function! s:module.on_leave(cmdline)
|
||||
call histadd(self.mode, 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,48 @@
|
||||
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(&history), 'histget(self.mode, v:val * -1)')
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.enter(...)
|
||||
let s:cmdhist = []
|
||||
let s:count = 0
|
||||
endfunction
|
||||
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if !a:cmdline.is_input("\<Up>") && !a:cmdline.is_input("\<Down>")
|
||||
let s:cmdhist = []
|
||||
let s:count = 0
|
||||
return
|
||||
else
|
||||
if s:count == 0 && empty(s:cmdhist)
|
||||
let cmdline = '^' . a:cmdline.getline()
|
||||
let s:cmdhist = filter(self.histories(), 'v:val =~ cmdline')
|
||||
endif
|
||||
endif
|
||||
call a:cmdline.setchar("")
|
||||
if a:cmdline.is_input("\<Down>")
|
||||
let s:count = max([s:count - 1, 0])
|
||||
endif
|
||||
if a:cmdline.is_input("\<Up>")
|
||||
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,67 @@
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "Incsearch",
|
||||
\ "highlights" : {
|
||||
\ "incserach" : "IncSearch"
|
||||
\ },
|
||||
\ "pattern" : "",
|
||||
\ "search_flag" : "",
|
||||
\ "mode" : "",
|
||||
\}
|
||||
|
||||
|
||||
function! s:module.search_hl_off()
|
||||
if exists("self.search_hl_id")
|
||||
call matchdelete(self.search_hl_id)
|
||||
unlet self.search_hl_id
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.search_hl_on(pattern)
|
||||
call self.search_hl_off()
|
||||
let self.search_hl_id = matchadd(self.highlights.incserach, a:pattern)
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_enter(...)
|
||||
let self.old_pos = getpos(".")
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_leave(...)
|
||||
call setpos(".", self.old_pos)
|
||||
call self.search_hl_off()
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_char(cmdline)
|
||||
call self.search_hl_off()
|
||||
let line = a:cmdline.getline()
|
||||
let result = get(matchlist(line, self.pattern), 1, "")
|
||||
if result != ""
|
||||
let pos = searchpos(result, self.search_flag)
|
||||
if pos == [0, 0]
|
||||
return
|
||||
endif
|
||||
call self.search_hl_on('\%' . pos[0] . 'l' . (&ignorecase ? '\c' : "") . result)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:make(...)
|
||||
let module = deepcopy(s:module)
|
||||
let module.mode = get(a:, 1, "/")
|
||||
let module.pattern = get(a:, 2, '^\(.\+\)')
|
||||
let module.search_flag = get(a:, 3, 'c')
|
||||
return module
|
||||
endfunction
|
||||
|
||||
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
@ -0,0 +1,40 @@
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "NoInsert",
|
||||
\ "chars" : []
|
||||
\}
|
||||
|
||||
|
||||
function! s:module.is_insert(char)
|
||||
return index(self.chars, a:char) >= 0
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if self.is_insert(a:cmdline.char())
|
||||
call a:cmdline.setchar("")
|
||||
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_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,24 @@
|
||||
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)")
|
||||
call a:cmdline.insert(@*)
|
||||
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,37 @@
|
||||
scriptencoding utf-8
|
||||
let s:save_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
|
||||
let s:module = {
|
||||
\ "name" : "Scroll"
|
||||
\}
|
||||
function! s:module.on_char_pre(cmdline)
|
||||
if a:cmdline.is_input("<Over>(scroll-y)")
|
||||
execute "normal! \<C-y>"
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("<Over>(scroll-u)")
|
||||
execute "normal! \<C-u>"
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("<Over>(scroll-f)")
|
||||
execute "normal! \<C-f>"
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("<Over>(scroll-e)")
|
||||
execute "normal! \<C-e>"
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("<Over>(scroll-d)")
|
||||
execute "normal! \<C-d>"
|
||||
call a:cmdline.setchar('')
|
||||
elseif a:cmdline.is_input("<Over>(scroll-b)")
|
||||
execute "normal! \<C-b>"
|
||||
call a:cmdline.setchar('')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
||||
function! s:make()
|
||||
return deepcopy(s:module)
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
4
autoload/vital/easymotion.vital
Normal file
4
autoload/vital/easymotion.vital
Normal file
@ -0,0 +1,4 @@
|
||||
easymotion
|
||||
2b8ba7f
|
||||
|
||||
Over.Commandline
|
@ -1,4 +1,4 @@
|
||||
*easymotion.txt* Version 2.0 Last change:26 Jan 2014.
|
||||
*easymotion.txt* Version 2.0 Last change:02 Feb 2014.
|
||||
|
||||
|
||||
______ __ ___ __ _
|
||||
@ -501,7 +501,67 @@ All Find motion (s,f,F,t,T,sl,fl,Fl,tl,Tl) support this feature!
|
||||
*<Plug>(easymotion-sl2)* *<Plug>(easymotion-fl2)* *<Plug>(easymotion-Fl2)*
|
||||
*<Plug>(easymotion-tl2)* *<Plug>(easymotion-Tl2)* *<Plug>(easymotion-bd-tl2)*
|
||||
|
||||
But |EasyMotion| is good at simple and fast motion with one or two character.
|
||||
Find Motion Command Line~
|
||||
*easymotion-command-line*
|
||||
EasyMotion has own command line for find motions, especially for 'n' key
|
||||
motion(e.g. |<Plug>(easymotoin-sn)|). This command line is inspired by
|
||||
over.vim and actually uses the library of over.vim command line.
|
||||
over.vim can be downloaded here:
|
||||
|
||||
https://github.com/osyo-manga/vim-over
|
||||
|
||||
Note: These settings are experimental. They could be changed in the near
|
||||
future.
|
||||
|
||||
Default Command Line Mappings~
|
||||
Most default mappings work same as default command line mapping of Vim.
|
||||
See |cmdline.txt|
|
||||
|
||||
Key Mappings | Details
|
||||
----------------------- |----------------------------------------------
|
||||
<CR> | Execute EasyMotion.
|
||||
<ESC> or <C-c> | Cancel
|
||||
<Right> | Cursor right
|
||||
<Left> | Cursor left
|
||||
<Home> or <C-b> | cursor to beginning of command-line
|
||||
<End> or <C-e> | cursor to end of command-line
|
||||
<BS> or <C-h> | Delete one character
|
||||
<C-w> | Delete the word before the cursor
|
||||
<C-u> | Delete all entered characters before the cursor
|
||||
<Up> | Recall older (previous) search from history
|
||||
<Down> | Recall more recent (next) search from history
|
||||
------------------------|---------------------------------------
|
||||
<Over>(paste) | Paste yanked text to the command line
|
||||
| Default: <C-v>
|
||||
<Over>(buffer-complete) | Completion of buffer text Default: <C-d>
|
||||
*<Over>(em-scroll-f)* | Scroll window forward & jump to the next match
|
||||
| Default: <Tab>
|
||||
*<Over>(em-scroll-b)* | Scroll window backward & jump to previous match
|
||||
| Default: <S-Tab>
|
||||
*<Over>(em-jumpback)* | Jump back original cursor position like <C-o>
|
||||
| Default: <C-o>
|
||||
*<Over>(em-openallfold)* | Open all fold
|
||||
| Default: <C-z>
|
||||
|
||||
Customize Command Line Mappings~
|
||||
*EMCommandLineNoremap*
|
||||
|
||||
You can use |EMCommandLineNoremap| to customize find motion command line
|
||||
key mappings by vimrc. This mapping is always no recursive mapping, so
|
||||
you should map to not <Tab> but <Over>(em-scroll-f).
|
||||
|
||||
Example:
|
||||
>
|
||||
" EM is short for EasyMotion
|
||||
EMCommandLineNoremap <C-;> <CR>
|
||||
EMCommandLineNoremap <C-f> <Right>
|
||||
EMCommandLineNoremap <C-b> <Left>
|
||||
EMCommandLineNoremap <C-a> <Home>
|
||||
EMCommandLineNoremap <C-l> <Over>(buffer-complete)
|
||||
<
|
||||
Note(again): These settings, especially about keymappings are
|
||||
__EXPERIMENTAL__. They could be changed in the near future. However, it
|
||||
works well and so useful, so I release it.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
2.3 Special mappings *easymotion-special-mappings*
|
||||
|
@ -416,6 +416,21 @@ if g:EasyMotion_do_mapping == 1 || g:EasyMotion_do_special_mapping == 1
|
||||
" }}}
|
||||
endif "}}}
|
||||
|
||||
" == CommandLine Mapping {{{
|
||||
function! s:key_mapping(lhs, rhs)
|
||||
let g:EasyMotion_command_line_key_mappings[a:lhs] = a:rhs
|
||||
endfunction
|
||||
|
||||
function! s:as_keymapping(key)
|
||||
execute 'let result = "' . substitute(a:key, '\(<.\{-}>\)', '\\\1', 'g') . '"'
|
||||
return result
|
||||
endfunction
|
||||
|
||||
command! -nargs=*
|
||||
\ EMCommandLineNoremap
|
||||
\ call call("s:key_mapping", map([<f-args>], "s:as_keymapping(v:val)"))
|
||||
"}}}
|
||||
|
||||
" == Restore 'cpoptions' {{{
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
Loading…
Reference in New Issue
Block a user