Modify to use vital-over for commandline of find motion

Add buffer completion, paste and mapping feature
This commit is contained in:
haya14busa 2014-01-30 15:31:25 +09:00
parent c9d0d18190
commit b368309fb3
15 changed files with 417 additions and 498 deletions

View File

@ -1,7 +1,7 @@
" EasyMotion - Vim motions on speed! " EasyMotion - Vim motions on speed!
" "
" Author: haya14busa <hayabusa1419@gmail.com> " Author: haya14busa <hayabusa1419@gmail.com>
" Last Change: 27 Jan 2014. " Last Change: 29 Jan 2014.
" Source: https://github.com/haya14busa/vim-easymotion " Source: https://github.com/haya14busa/vim-easymotion
" "
" Original Author: Kim Silkebækken <kim.silkebaekken+vim@gmail.com> " 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 " Check that we have an input char
if empty(input) if empty(input)
redraw | return '' return ''
endif endif
let re = s:convertRegep(input) let re = s:convertRegep(input)

View File

@ -2,7 +2,7 @@
" FILE: autoload/EasyMotion/command_line.vim " FILE: autoload/EasyMotion/command_line.vim
" AUTHOR: haya14busa " AUTHOR: haya14busa
" Reference: https://github.com/osyo-manga/vim-over " Reference: https://github.com/osyo-manga/vim-over
" Last Change: 26 Jan 2014. " Last Change: 01 Feb 2014.
" License: MIT license {{{ " License: MIT license {{{
" Permission is hereby granted, free of charge, to any person obtaining " Permission is hereby granted, free of charge, to any person obtaining
" a copy of this software and associated documentation files (the " a copy of this software and associated documentation files (the
@ -30,102 +30,101 @@ let s:save_cpo = &cpo
set cpo&vim set cpo&vim
" }}} " }}}
" Autocmd: {{{ " CommandLine:
augroup plugin-easymotion-dummy let s:cmdline = vital#of("easymotion").import("Over.Commandline")
autocmd! let s:search = s:cmdline.make_plain("/")
augroup END let s:search.highlights.prompt = "Question"
let s:cache_command = {} " Add Module: {{{
function! s:doautocmd_user(command) "{{{ call s:search.connect(s:cmdline.module_delete())
if !has_key(s:cache_command, a:command) call s:search.connect(s:cmdline.module_cursor_move())
execute "autocmd plugin-easymotion-dummy" call s:search.connect(s:cmdline.module_paste())
\ . " User " . a:command." silent! execute ''" 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") let s:module = {
" :helpgrep 7.4.438 \ "name" : "EasyMotion",
let s:cache_command[a:command] = "doautocmd <nomodeline> User " . a:command \}
else function! s:module.on_char_pre(cmdline)
let s:cache_command[a:command] = "doautocmd User " . a:command 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 endif
endif endfunction
call s:search.connect(s:module)
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
"}}} "}}}
" Activate: " CommandLine Keymap: {{{
function! s:init() "{{{ let s:default_key_mapping = {
" Cursor \ "\<C-d>" : "<Over>(buffer-complete)",
let hl_cursor = EasyMotion#command_line#hl_cursor_off() \ "\<Tab>" : "<Over>(em-scroll-f)",
if !hlexists("EasyMotionCommandLineCursor") \ "\<S-Tab>" : "<Over>(em-scroll-b)",
execute "highlight EasyMotionCommandLineCursor " . hl_cursor . " term=underline gui=underline" \ "\<C-o>" : "<Over>(em-jumpback)",
endif \ "\<C-z>" : "<Over>(em-openallfold)",
" Save cursor visible \}
let s:old_t_ve = &t_ve function! EasyMotion#command_line#keymaps() "{{{
set t_ve= return extend(deepcopy(s:default_key_mapping),
\ g:EasyMotion_command_line_key_mappings)
endfunction "}}} endfunction "}}}
function! s:finish() "{{{ function! s:search.keymappings() "{{{
" Cursor return EasyMotion#command_line#keymaps()
call EasyMotion#command_line#hl_cursor_on()
let &t_ve = s:old_t_ve
endfunction "}}} endfunction "}}}
"}}}
function! EasyMotion#command_line#hl_cursor_off() "{{{ " Event: {{{
if exists("s:old_hi_cursor") function! s:search.on_enter() "{{{
return s:old_hi_cursor if s:num_strokes == -1
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
call EasyMotion#highlight#delete_highlight() call EasyMotion#highlight#delete_highlight()
let shade_hl_re = '\_.*' let shade_hl_re = '\_.*'
call EasyMotion#highlight#add_highlight(shade_hl_re, g:EasyMotion_hl_group_shade) call EasyMotion#highlight#add_highlight(shade_hl_re, g:EasyMotion_hl_group_shade)
call EasyMotion#highlight#add_highlight('\%#', g:EasyMotion_hl_inc_cursor) call EasyMotion#highlight#add_highlight('\%#', g:EasyMotion_hl_inc_cursor)
endif endif
endfunction "}}} endfunction "}}}
function! s:after_input() "{{{ function! s:search.on_leave() "{{{
call EasyMotion#highlight#delete_highlight() call EasyMotion#highlight#delete_highlight(g:EasyMotion_hl_inc_search)
endfunction "}}} 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: " Main:
function! EasyMotion#command_line#GetInput(num_strokes, prev, direction) "{{{ function! EasyMotion#command_line#GetInput(num_strokes, prev, direction) "{{{
call s:doautocmd_user("EasyMotionCmdLineEnter") let s:num_strokes = a:num_strokes
let previous_input = a:prev
let s:save_direction = a:direction == 1 ? 'b' : ''
let s:direction = s:save_direction
" CommandLine: Input string and cursor position let s:search.prompt = s:getPromptMessage(a:num_strokes)
let s:command_line = s:string_with_pos('')
let prompt = s:getPromptMessage(a:num_strokes)
" Screen: cursor position, first and last line " Screen: cursor position, first and last line
let s:orig_pos = getpos('.') 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:orig_line_end = getpos('w$')
let s:save_orig_pos = deepcopy(s:orig_pos) 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 input = s:search.get()
let s:search_cnt = 0 if input == '' && ! s:search.exit_code()
return a:prev
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 else
call s:command_line.input(s:char) return input
endif 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 ' '
else
echon a:pstr.pos_word()
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 "}}} endfunction "}}}
" Helper: " Helper:
function! s:InputPrompt(message, input) "{{{
redraw
echohl Question | echon a:message | echohl None
echon a:input
endfunction "}}}
function! s:Cancell() " {{{ function! s:Cancell() " {{{
call s:after_input() call EasyMotion#highlight#delete_highlight()
keepjumps call setpos('.', s:save_orig_pos) keepjumps call setpos('.', s:save_orig_pos)
redraw
echo 'EasyMotion: Cancelled' echo 'EasyMotion: Cancelled'
return '' return ''
endfunction " }}} endfunction " }}}
@ -455,6 +171,7 @@ endfunction "}}}
function! s:off_screen_search(re) "{{{ function! s:off_screen_search(re) "{{{
" First: search within visible screen range " First: search within visible screen range
call s:adjust_screen() call s:adjust_screen()
" Error occur when '\zs' without '!'
silent! let pos = searchpos(a:re, s:direction . 'n', s:orig_line_end[1]) silent! let pos = searchpos(a:re, s:direction . 'n', s:orig_line_end[1])
if pos != [0, 0] if pos != [0, 0]
" Restore cursor posision " Restore cursor posision
@ -497,18 +214,14 @@ function! s:scroll(direction) "{{{
let s:orig_line_end = getpos('w$') let s:orig_line_end = getpos('w$')
let s:direction = a:direction == 0 ? '' : 'b' let s:direction = a:direction == 0 ? '' : 'b'
endfunction "}}} endfunction "}}}
function! s:search_histories() "{{{
return map(range(&history), 'histget("search", v:val * -1)')
endfunction "}}}
function! s:inc_highlight(re) "{{{ function! s:inc_highlight(re) "{{{
call EasyMotion#highlight#delete_highlight('EasyMotionIncSearch') call EasyMotion#highlight#delete_highlight(g:EasyMotion_hl_inc_search)
if s:command_line.length() > 0 if s:search.line.length() > 0
" Error occur when '\zs' without '!'
silent! call EasyMotion#highlight#add_highlight(a:re, g:EasyMotion_hl_inc_search) silent! call EasyMotion#highlight#add_highlight(a:re, g:EasyMotion_hl_inc_search)
endif endif
endfunction "}}} endfunction "}}}
" Restore 'cpoptions' {{{ " Restore 'cpoptions' {{{
let &cpo = s:save_cpo let &cpo = s:save_cpo
unlet s:save_cpo unlet s:save_cpo

View File

@ -12,6 +12,9 @@ let s:modules = [
\ "History", \ "History",
\ "Incsearch", \ "Incsearch",
\ "BufferComplete", \ "BufferComplete",
\ "Cancel",
\ "Enter",
\ "NoInsert",
\] \]
let s:modules_snake = [ let s:modules_snake = [
@ -23,6 +26,9 @@ let s:modules_snake = [
\ "history", \ "history",
\ "incsearch", \ "incsearch",
\ "buffer_complete", \ "buffer_complete",
\ "cancel",
\ "enter",
\ "no_insert",
\] \]
@ -39,6 +45,32 @@ function! s:_vital_depends()
endfunction 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 = { let s:base = {
\ "prompt" : "> ", \ "prompt" : "> ",
@ -47,10 +79,12 @@ let s:base = {
\ "char" : "", \ "char" : "",
\ "input" : "", \ "input" : "",
\ "wait_key" : "", \ "wait_key" : "",
\ "exit" : 0,
\ }, \ },
\ "highlights" : { \ "highlights" : {
\ "Cursor" : "OverCommandLineDefaultCursor", \ "prompt" : "NONE",
\ "CursorInsert" : "OverCommandLineDefaultCursorInsert" \ "cursor" : "OverCommandLineDefaultCursor",
\ "cursor_insert" : "OverCommandLineDefaultCursorInsert"
\ }, \ },
\ "modules" : {}, \ "modules" : {},
\ "keys" : { \ "keys" : {
@ -131,12 +165,18 @@ function! s:base.backward()
endfunction endfunction
function! s:base.connect(module) function! s:base.connect(module, ...)
let self.modules[a:module.name] = a:module let name = get(a:, 1, a:module.name)
let self.modules[name] = a:module
endfunction endfunction
for s:_ in ["enter", "leave", "char", "charpre", "executepre", "execute", "cancel"] 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([ execute join([
\ "function! s:base._on_" . s:_ . "()", \ "function! s:base._on_" . s:_ . "()",
\ " call map(copy(self.modules), 'has_key(v:val, \"on_" . s:_ . "\") ? v:val.on_" . s:_ . "(self) : 0')", \ " call map(copy(self.modules), 'has_key(v:val, \"on_" . s:_ . "\") ? v:val.on_" . s:_ . "(self) : 0')",
@ -145,7 +185,6 @@ for s:_ in ["enter", "leave", "char", "charpre", "executepre", "execute", "cance
\ ], "\n") \ ], "\n")
execute "function! s:base.on_" . s:_ . "()" execute "function! s:base.on_" . s:_ . "()"
endfunction endfunction
endfor endfor
unlet s:_ unlet s:_
@ -157,94 +196,41 @@ function! s:base.keymappings()
endfunction endfunction
function! s:make(prompt)
let result = deepcopy(s:base)
let result.prompt = a:prompt
return result
endfunction
function! s:make_simple(prompt)
let result = s:make(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())
return result
endfunction
function! s:_echo_cmdline(cmdline)
redraw
echon a:cmdline.prompt . a:cmdline.backward()
if empty(a:cmdline.line.pos_word())
execute "echohl" a:cmdline.highlights.Cursor
echon ' '
else
execute "echohl" a:cmdline.highlights.CursorInsert
echon a:cmdline.line.pos_word()
endif
echohl NONE
echon a:cmdline.forward()
endfunction
function! s:base.execute() function! s:base.execute()
execute self.getline() execute self.getline()
endfunction endfunction
function! s:base.exit(...) function! s:base.exit(...)
let self.variables.exit = get(a:, 1, 0) let self.variables.exit = 1
let self.variables.exit_code = get(a:, 1, 0)
endfunction endfunction
function! s:base.is_exit() function! s:base.cancel()
return has_key(self.variables, "exit") call self.exit(1)
call self._on_cancel()
endfunction
function! s:base.exit_code()
return self.variables.exit_code
endfunction endfunction
function! s:base.start(...) function! s:base.start(...)
let result = call(self.get, a:000, self) let exit_code = call(self._main, a:000, self)
if result == "" if exit_code == 0
return
endif
call self._execute() call self._execute()
endif
endfunction endfunction
function! s:base.get(...) function! s:base.get(...)
try let exit_code = call(self._main, a:000, self)
call self._init() if exit_code == 0
let self.line = deepcopy(s:_string_with_pos(get(a:, 1, "")))
call self._on_enter()
call self._inputkey()
while !self.is_input(self.keys.quit)
if self.is_input(self.keys.enter)
return self.getline() return self.getline()
else
call self.insert(self.variables.input)
endif endif
call self._on_char()
if self.is_exit()
call s:_redraw()
return ""
endif
call self._inputkey()
endwhile
call self._on_cancel()
call s:_redraw()
catch
echohl ErrorMsg | echo v:throwpoint . " " . v:exception | echohl None
finally
call self._finish()
call self._on_leave()
endtry
return "" return ""
endfunction endfunction
@ -253,6 +239,8 @@ function! s:base._init()
let self.variables.wait_key = "" let self.variables.wait_key = ""
let self.variables.char = "" let self.variables.char = ""
let self.variables.input = "" let self.variables.input = ""
let self.variables.exit = 0
let self.variables.exit_code = 1
let hl_cursor = s:_hl_cursor_off() let hl_cursor = s:_hl_cursor_off()
if !hlexists("OverCommandLineDefaultCursor") if !hlexists("OverCommandLineDefaultCursor")
execute "highlight OverCommandLineDefaultCursor " . hl_cursor execute "highlight OverCommandLineDefaultCursor " . hl_cursor
@ -266,30 +254,74 @@ endfunction
function! s:base._execute() function! s:base._execute()
call self._on_executepre() call s:_redraw()
call self._on_execute_pre()
try try
call self.execute() call self.execute()
catch catch
echohl ErrorMsg echohl ErrorMsg
echo matchstr(v:exception, 'Vim\((\w*)\)\?:\zs.*\ze') echo matchstr(v:exception, 'Vim\((\w*)\)\?:\zs.*\ze')
echohl None echohl None
call self._on_execute_failed()
finally finally
call self._on_execute() call self._on_execute()
endtry endtry
endfunction 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() function! s:base._finish()
cal s:_hl_cursor_on() cal s:_hl_cursor_on()
let &t_ve = s:old_t_ve let &t_ve = s:old_t_ve
endfunction endfunction
function! s:base._inputkey() function! s:_echo_cmdline(cmdline)
call s:_echo_cmdline(self) call s:_redraw()
let self.variables.char = s:_getchar() execute "echohl" a:cmdline.highlights.prompt
call self.setchar(self.variables.char) echon a:cmdline.prompt
call self._on_charpre() 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 endfunction
@ -303,8 +335,9 @@ for s:i in range(len(s:modules_snake))
endfor endfor
unlet s:i unlet s:i
function! s:module_no_insert_special_chars()
return s:NoInsert.make_special_chars()
endfunction
function! s:_redraw() function! s:_redraw()
@ -333,9 +366,15 @@ function! s:_hl_cursor_off()
endif endif
let s:old_hi_cursor = "cterm=reverse" let s:old_hi_cursor = "cterm=reverse"
if hlexists("Cursor") if hlexists("Cursor")
let save_verbose = &verbose
let &verbose = 0
try
redir => cursor redir => cursor
silent highlight Cursor silent highlight Cursor
redir END redir END
finally
let &verbose = save_verbose
endtry
let hl = substitute(matchstr(cursor, 'xxx \zs.*'), '[ \t\n]\+\|cleared', ' ', 'g') let hl = substitute(matchstr(cursor, 'xxx \zs.*'), '[ \t\n]\+\|cleared', ' ', 'g')
if !empty(substitute(hl, '\s', '', 'g')) if !empty(substitute(hl, '\s', '', 'g'))
let s:old_hi_cursor = hl let s:old_hi_cursor = hl

View File

@ -97,8 +97,8 @@ function! s:_finish()
endfunction endfunction
function! s:module.on_charpre(cmdline) function! s:module.on_char_pre(cmdline)
if a:cmdline.is_input("\<Tab>") if a:cmdline.is_input("<Over>(buffer-complete)")
if self.complete(a:cmdline) == -1 if self.complete(a:cmdline) == -1
call s:_finish() call s:_finish()
call a:cmdline.setchar('') call a:cmdline.setchar('')
@ -106,14 +106,14 @@ function! s:module.on_charpre(cmdline)
endif endif
call a:cmdline.setchar('') call a:cmdline.setchar('')
call a:cmdline.wait_keyinput_on("Completion") call a:cmdline.wait_keyinput_on("Completion")
elseif a:cmdline.is_input("\<Tab>", "Completion") elseif a:cmdline.is_input("<Over>(buffer-complete)", "Completion")
\ || a:cmdline.is_input("\<C-f>", "Completion") \ || a:cmdline.is_input("\<Right>", "Completion")
call a:cmdline.setchar('') call a:cmdline.setchar('')
let s:count += 1 let s:count += 1
if s:count >= len(s:complete_list) if s:count >= len(s:complete_list)
let s:count = 0 let s:count = 0
endif endif
elseif a:cmdline.is_input("\<C-b>", "Completion") elseif a:cmdline.is_input("\<Left>", "Completion")
call a:cmdline.setchar('') call a:cmdline.setchar('')
let s:count -= 1 let s:count -= 1
if s:count < 0 if s:count < 0
@ -121,7 +121,7 @@ function! s:module.on_charpre(cmdline)
endif endif
else else
if a:cmdline.wait_keyinput_off("Completion") if a:cmdline.wait_keyinput_off("Completion")
call a:cmdline._on_charpre() call a:cmdline._on_char_pre()
endif endif
call s:_finish() call s:_finish()
return return

View File

@ -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

View File

@ -6,20 +6,19 @@ set cpo&vim
let s:module = { let s:module = {
\ "name" : "CursorMove" \ "name" : "CursorMove"
\} \}
function! s:module.on_charpre(cmdline) function! s:module.on_char_pre(cmdline)
if a:cmdline.is_input("\<C-f>") if a:cmdline.is_input("\<Right>")
call a:cmdline.line.next() call a:cmdline.line.next()
call a:cmdline.setchar('') call a:cmdline.setchar('')
elseif a:cmdline.is_input("\<C-b>") elseif a:cmdline.is_input("\<Left>")
call a:cmdline.line.prev() call a:cmdline.line.prev()
call a:cmdline.setchar('') call a:cmdline.setchar('')
elseif a:cmdline.is_input("\<C-d>") elseif a:cmdline.is_input("\<C-b>")
call a:cmdline.line.remove_pos() \ || a:cmdline.is_input("\<Home>")
call a:cmdline.setchar('')
elseif a:cmdline.is_input("\<C-a>")
call a:cmdline.setline(0) call a:cmdline.setline(0)
call a:cmdline.setchar('') call a:cmdline.setchar('')
elseif a:cmdline.is_input("\<C-e>") elseif a:cmdline.is_input("\<C-e>")
\ || a:cmdline.is_input("\<End>")
call a:cmdline.setline(a:cmdline.line.length()) call a:cmdline.setline(a:cmdline.line.length())
call a:cmdline.setchar('') call a:cmdline.setchar('')
endif endif

View File

@ -6,13 +6,14 @@ set cpo&vim
let s:module = { let s:module = {
\ "name" : "Delete", \ "name" : "Delete",
\} \}
function! s:module.on_charpre(cmdline) function! s:module.on_char_pre(cmdline)
if a:cmdline.is_input("\<C-h>") if a:cmdline.is_input("\<C-h>")
if a:cmdline.line.length() == 0 \ || a:cmdline.is_input("\<BS>")
call a:cmdline.exit()
endif
call a:cmdline.line.remove_prev() call a:cmdline.line.remove_prev()
call a:cmdline.setchar('') 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>") elseif a:cmdline.is_input("\<C-w>")
let backward = matchstr(a:cmdline.backward(), '^\zs.\{-}\ze\(\(\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(backward . a:cmdline.line.pos_word() . a:cmdline.forward())

View File

@ -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

View File

@ -17,8 +17,8 @@ function! s:module.enter(...)
let s:count = 0 let s:count = 0
endfunction endfunction
function! s:module.on_charpre(cmdline) function! s:module.on_char_pre(cmdline)
if !a:cmdline.is_input("\<C-p>") && !a:cmdline.is_input("\<C-n>") if !a:cmdline.is_input("\<Up>") && !a:cmdline.is_input("\<Down>")
let s:cmdhist = [] let s:cmdhist = []
let s:count = 0 let s:count = 0
return return
@ -29,10 +29,10 @@ function! s:module.on_charpre(cmdline)
endif endif
endif endif
call a:cmdline.setchar("") call a:cmdline.setchar("")
if a:cmdline.is_input("\<C-n>") if a:cmdline.is_input("\<Down>")
let s:count = max([s:count - 1, 0]) let s:count = max([s:count - 1, 0])
endif endif
if a:cmdline.is_input("\<C-p>") if a:cmdline.is_input("\<Up>")
let s:count = min([s:count + 1, len(s:cmdhist)]) let s:count = min([s:count + 1, len(s:cmdhist)])
endif endif
call a:cmdline.setline(get(s:cmdhist, s:count, a:cmdline.getline())) call a:cmdline.setline(get(s:cmdhist, s:count, a:cmdline.getline()))

View File

@ -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

View File

@ -6,8 +6,9 @@ set cpo&vim
let s:module = { let s:module = {
\ "name" : "Paste" \ "name" : "Paste"
\} \}
function! s:module.on_charpre(cmdline)
if a:cmdline.is_input("\<C-v>") function! s:module.on_char_pre(cmdline)
if a:cmdline.is_input("<Over>(paste)")
call a:cmdline.insert(@*) call a:cmdline.insert(@*)
call a:cmdline.setchar('') call a:cmdline.setchar('')
endif endif

View File

@ -6,23 +6,23 @@ set cpo&vim
let s:module = { let s:module = {
\ "name" : "Scroll" \ "name" : "Scroll"
\} \}
function! s:module.on_charpre(cmdline) function! s:module.on_char_pre(cmdline)
if a:cmdline.is_input("\<Plug>(over-cmdline-scroll-y)") if a:cmdline.is_input("<Over>(scroll-y)")
execute "normal! \<C-y>" execute "normal! \<C-y>"
call a:cmdline.setchar('') call a:cmdline.setchar('')
elseif a:cmdline.is_input("\<Plug>(over-cmdline-scroll-u)") elseif a:cmdline.is_input("<Over>(scroll-u)")
execute "normal! \<C-u>" execute "normal! \<C-u>"
call a:cmdline.setchar('') call a:cmdline.setchar('')
elseif a:cmdline.is_input("\<Plug>(over-cmdline-scroll-f)") elseif a:cmdline.is_input("<Over>(scroll-f)")
execute "normal! \<C-f>" execute "normal! \<C-f>"
call a:cmdline.setchar('') call a:cmdline.setchar('')
elseif a:cmdline.is_input("\<Plug>(over-cmdline-scroll-e)") elseif a:cmdline.is_input("<Over>(scroll-e)")
execute "normal! \<C-e>" execute "normal! \<C-e>"
call a:cmdline.setchar('') call a:cmdline.setchar('')
elseif a:cmdline.is_input("\<Plug>(over-cmdline-scroll-d)") elseif a:cmdline.is_input("<Over>(scroll-d)")
execute "normal! \<C-d>" execute "normal! \<C-d>"
call a:cmdline.setchar('') call a:cmdline.setchar('')
elseif a:cmdline.is_input("\<Plug>(over-cmdline-scroll-b)") elseif a:cmdline.is_input("<Over>(scroll-b)")
execute "normal! \<C-b>" execute "normal! \<C-b>"
call a:cmdline.setchar('') call a:cmdline.setchar('')
endif endif

View File

@ -1,4 +1,4 @@
easymotion easymotion
8c1ba73 2b8ba7f
Over.Commandline Over.Commandline

View File

@ -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-sl2)* *<Plug>(easymotion-fl2)* *<Plug>(easymotion-Fl2)*
*<Plug>(easymotion-tl2)* *<Plug>(easymotion-Tl2)* *<Plug>(easymotion-bd-tl2)* *<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* 2.3 Special mappings *easymotion-special-mappings*

View File

@ -416,6 +416,21 @@ if g:EasyMotion_do_mapping == 1 || g:EasyMotion_do_special_mapping == 1
" }}} " }}}
endif "}}} 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' {{{ " == Restore 'cpoptions' {{{
let &cpo = s:save_cpo let &cpo = s:save_cpo
unlet s:save_cpo unlet s:save_cpo