vim-easymotion/autoload/vital/_easymotion/Over/Commandline/Base.vim

521 lines
11 KiB
VimL
Raw Normal View History

2014-01-29 00:29:23 -05:00
scriptencoding utf-8
let s:save_cpo = &cpo
set cpo&vim
function! s:_vital_loaded(V)
let s:V = a:V
2014-02-09 07:21:26 -05:00
let s:String = s:V.import("Over.String")
let s:Signals = s:V.import("Over.Signals")
2014-11-23 12:07:19 -05:00
let s:Input = s:V.import("Over.Input")
2014-02-11 23:31:44 -05:00
let s:Module = s:V.import("Over.Commandline.Modules")
2014-02-09 07:21:26 -05:00
let s:base.variables.modules = s:Signals.make()
function! s:base.variables.modules.get_slot(val)
return a:val.slot.module
endfunction
2014-01-29 00:29:23 -05:00
endfunction
function! s:_vital_depends()
2014-02-09 07:21:26 -05:00
return [
\ "Over.String",
\ "Over.Signals",
2014-11-23 12:07:19 -05:00
\ "Over.Input",
2014-02-11 23:31:44 -05:00
\ "Over.Commandline.Modules",
\ ]
2014-02-04 23:32:29 -05:00
endfunction
2014-02-11 23:31:44 -05:00
function! s:make(...)
let result = deepcopy(s:base)
call result.set_prompt(get(a:, 1, ":"))
2014-02-09 07:21:26 -05:00
call result.connect(result, "_")
return result
endfunction
2014-02-11 23:31:44 -05:00
function! s:make_plain()
2014-08-27 21:22:57 -04:00
return deepcopy(s:base)
endfunction
2014-01-29 00:29:23 -05:00
let s:base = {
\ "line" : {},
\ "variables" : {
\ "prompt" : "",
2014-01-29 00:29:23 -05:00
\ "char" : "",
\ "input" : "",
2014-02-04 23:32:29 -05:00
\ "tap_key" : "",
\ "exit" : 0,
2014-02-04 23:32:29 -05:00
\ "keymapping" : {},
\ "suffix" : "",
2014-01-29 00:29:23 -05:00
\ },
\ "highlights" : {
\ "prompt" : "NONE",
2014-02-11 23:31:44 -05:00
\ "cursor" : "VitalOverCommandLineCursor",
\ "cursor_on" : "VitalOverCommandLineCursorOn",
\ "cursor_insert" : "VitalOverCommandLineOnCursor",
2014-01-29 00:29:23 -05:00
\ },
\}
2014-02-10 01:21:05 -05:00
if exists("s:Signals")
let s:base.variables.modules = s:Signals.make()
function! s:base.variables.modules.get_slot(val)
return a:val.slot.module
endfunction
endif
2014-01-29 00:29:23 -05:00
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
2014-02-11 23:31:44 -05:00
function! s:base.setchar(char, ...)
" 1 の場合は既に設定されていても上書きする
" 0 の場合は既に設定されていれば上書きしない
let overwrite = get(a:, 1, 1)
if overwrite || self.variables.input == self.char()
let self.variables.input = a:char
endif
2014-01-29 00:29:23 -05:00
endfunction
function! s:base.getpos()
return self.line.pos()
endfunction
function! s:base.setpos(pos)
2014-02-04 23:32:29 -05:00
return self.line.set_pos(a:pos)
2014-01-29 00:29:23 -05:00
endfunction
2014-02-04 23:32:29 -05:00
function! s:base.tap_keyinput(key)
let self.variables.tap_key = a:key
2014-01-29 00:29:23 -05:00
endfunction
2014-02-04 23:32:29 -05:00
function! s:base.untap_keyinput(key)
if self.variables.tap_key == a:key
let self.variables.tap_key = ""
2014-01-29 00:29:23 -05:00
return 1
endif
endfunction
2014-02-04 23:32:29 -05:00
function! s:base.get_tap_key()
return self.variables.tap_key
2014-01-29 00:29:23 -05:00
endfunction
function! s:base.is_input(key, ...)
let prekey = get(a:, 1, "")
2014-02-04 23:32:29 -05:00
return self.get_tap_key() == prekey
\ && self.char() == a:key
2014-02-06 09:04:12 -05:00
" \ && self.char() == (prekey . a:key)
2014-02-06 05:08:14 -05:00
endfunction
function! s:base.input_key()
return self.variables.input_key
2014-01-29 00:29:23 -05:00
endfunction
function! s:base.set_prompt(prompt)
let self.variables.prompt = a:prompt
endfunction
function! s:base.get_prompt()
return self.variables.prompt
endfunction
function! s:base.set_suffix(str)
let self.variables.suffix = a:str
endfunction
function! s:base.get_suffix()
return self.variables.suffix
endfunction
2014-01-29 00:29:23 -05:00
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
2014-11-23 12:07:19 -05:00
function! s:base.backward_word(...)
let pat = get(a:, 1, '\k\+\s*\|.')
return matchstr(self.backward(), '\%(' . pat . '\)$')
endfunction
function! s:base.connect(module, ...)
2014-02-04 23:32:29 -05:00
if type(a:module) == type("")
2014-02-11 23:31:44 -05:00
return call(self.connect, [s:Module.make(a:module)] + a:000, self)
endif
if empty(a:module)
return
2014-02-04 23:32:29 -05:00
endif
2014-02-09 07:21:26 -05:00
let name = a:0 > 0 ? a:1 : a:module.name
let slot = self.variables.modules.find_first_by("get(v:val.slot, 'name', '') == " . string(name))
if empty(slot)
call self.variables.modules.connect({ "name" : name, "module" : a:module })
else
let slot.slot.module = a:module
endif
" let self.variables.modules[name] = a:module
2014-01-29 00:29:23 -05:00
endfunction
function! s:base.disconnect(name)
2014-02-09 07:21:26 -05:00
return self.variables.modules.disconnect_by(
\ "get(v:val.slot, 'name', '') == " . string(a:name)
\ )
" unlet self.variables.modules[a:name]
endfunction
2014-02-11 23:31:44 -05:00
function! s:base.get_module(name)
let slot = self.variables.modules.find_first_by("get(v:val.slot, 'name', '') == " . string(a:name))
return empty(slot) ? {} : slot.slot.module
endfunction
2014-02-09 07:21:26 -05:00
function! s:base.callevent(event)
call self.variables.modules.sort_by("has_key(v:val.slot.module, 'priority') ? v:val.slot.module.priority('" . a:event . "') : 0")
return self.variables.modules.call(a:event, [self])
" call map(filter(copy(self.variables.modules), "has_key(v:val, a:event)"), "v:val." . a:event . "(self)")
endfunction
2014-01-29 00:29:23 -05:00
2014-02-04 23:32:29 -05:00
function! s:base.cmap(lhs, rhs)
let self.variables.keymapping[a:lhs] = a:rhs
endfunction
function! s:base.cnoremap(lhs, rhs)
let self.variables.keymapping[a:lhs] = {
\ "key" : a:rhs,
\ "noremap" : 1,
\ }
endfunction
function! s:base.cunmap(lhs)
unlet self.variables.keymapping[a:lhs]
endfunction
function! s:base.keymapping()
2014-01-29 00:29:23 -05:00
return {}
endfunction
2014-02-11 23:31:44 -05:00
function! s:base.execute(...)
let command = get(a:, 1, self.getline())
call self._execute(command)
" execute self.getline()
2014-01-29 00:29:23 -05:00
endfunction
2014-02-23 23:43:16 -05:00
function! s:base.draw()
call self.callevent("on_draw_pre")
call self.callevent("on_draw")
endfunction
2014-01-29 00:29:23 -05:00
function! s:base.exit(...)
let self.variables.exit = 1
let self.variables.exit_code = get(a:, 1, 0)
2014-01-29 00:29:23 -05:00
endfunction
2014-06-06 12:35:19 -04:00
function! s:base.enable_keymapping()
let self.variables.enable_keymapping = 1
endfunction
function! s:base.disable_keymapping()
let self.variables.enable_keymapping = 0
endfunction
function! s:base.is_enable_keymapping()
return self.variables.enable_keymapping
endfunction
2014-02-06 05:08:14 -05:00
" function! s:base.cancel()
" call self.exit(1)
" call self._on_cancel()
" endfunction
function! s:base.exit_code()
return self.variables.exit_code
2014-01-29 00:29:23 -05:00
endfunction
2014-02-04 23:32:29 -05:00
function! s:base.hl_cursor_on()
2014-02-10 01:21:05 -05:00
if exists("self.variables.old_guicursor")
2014-02-11 00:17:04 -05:00
set guicursor&
2014-02-10 01:21:05 -05:00
let &guicursor = self.variables.old_guicursor
unlet self.variables.old_guicursor
2014-02-04 23:32:29 -05:00
endif
2014-02-10 01:21:05 -05:00
2014-02-04 23:32:29 -05:00
if exists("self.variables.old_t_ve")
let &t_ve = self.variables.old_t_ve
unlet self.variables.old_t_ve
endif
endfunction
function! s:base.hl_cursor_off()
2014-02-10 01:21:05 -05:00
if exists("self.variables.old_t_ve")
return
2014-02-04 23:32:29 -05:00
endif
2014-02-11 23:31:44 -05:00
2014-02-10 01:21:05 -05:00
let self.variables.old_guicursor = &guicursor
2014-02-11 23:31:44 -05:00
set guicursor=n:block-NONE
2014-02-04 23:32:29 -05:00
let self.variables.old_t_ve = &t_ve
set t_ve=
endfunction
2014-01-29 00:29:23 -05:00
function! s:base.start(...)
let exit_code = call(self._main, a:000, self)
2014-02-11 23:31:44 -05:00
return exit_code
endfunction
function! s:base.__empty(...)
2014-01-29 00:29:23 -05:00
endfunction
function! s:base.get(...)
2014-02-11 23:31:44 -05:00
let Old_execute = self.execute
let self.execute = self.__empty
try
2014-11-23 12:07:19 -05:00
let exit_code = call(self.start, a:000, self)
2014-02-11 23:31:44 -05:00
if exit_code == 0
return self.getline()
endif
finally
let self.execute = Old_execute
endtry
2014-01-29 00:29:23 -05:00
return ""
endfunction
2014-11-23 12:07:19 -05:00
function! s:base.input_key_stack()
return self.variables.input_key_stack
endfunction
function! s:base.input_key_stack_string()
return join(self.variables.input_key_stack, "")
endfunction
function! s:base.set_input_key_stack(stack)
let self.variables.input_key_stack = a:stack
return self.variables.input_key_stack
endfunction
function! s:base._init_variables()
2014-02-04 23:32:29 -05:00
let self.variables.tap_key = ""
2014-01-29 00:29:23 -05:00
let self.variables.char = ""
let self.variables.input = ""
let self.variables.exit = 0
let self.variables.exit_code = 1
2014-06-06 12:35:19 -04:00
let self.variables.enable_keymapping = 1
2014-11-23 12:07:19 -05:00
let self.variables.input_key_stack = []
let self.line = deepcopy(s:String.make())
endfunction
function! s:base._init()
call self._init_variables()
2014-02-10 01:21:05 -05:00
call self.hl_cursor_off()
2014-02-11 23:31:44 -05:00
if !hlexists(self.highlights.cursor)
execute "highlight link " . self.highlights.cursor . " Cursor"
2014-02-10 01:21:05 -05:00
endif
2014-02-11 23:31:44 -05:00
if !hlexists(self.highlights.cursor_on)
execute "highlight link " . self.highlights.cursor_on . " " . self.highlights.cursor
2014-01-29 00:29:23 -05:00
endif
2014-02-11 23:31:44 -05:00
if !hlexists(self.highlights.cursor_insert)
execute "highlight " . self.highlights.cursor_insert . " cterm=underline term=underline gui=underline"
2014-01-29 00:29:23 -05:00
endif
endfunction
2014-02-11 23:31:44 -05:00
function! s:base._execute(command)
2014-02-09 07:21:26 -05:00
call self.callevent("on_execute_pre")
2014-01-29 00:29:23 -05:00
try
2014-02-11 23:31:44 -05:00
execute a:command
2014-01-29 00:29:23 -05:00
catch
echohl ErrorMsg
echom matchstr(v:exception, 'Vim\((\w*)\)\?:\zs.*\ze')
2014-01-29 00:29:23 -05:00
echohl None
2014-02-09 07:21:26 -05:00
call self.callevent("on_execute_failed")
2014-01-29 00:29:23 -05:00
finally
2014-02-09 07:21:26 -05:00
call self.callevent("on_execute")
2014-01-29 00:29:23 -05:00
endtry
endfunction
2014-11-23 12:07:19 -05:00
function! s:base._input_char(char)
let char = a:char
let self.variables.input_key = char
let self.variables.char = char
call self.setchar(self.variables.char)
call self.callevent("on_char_pre")
call self.insert(self.variables.input)
call self.callevent("on_char")
endfunction
2014-06-06 12:35:19 -04:00
function! s:base._input(input, ...)
let self.variables.input_key = a:input
if self.is_enable_keymapping()
let key = s:_unmap(self._get_keymapping(), a:input)
else
let key = a:input
endif
2014-11-23 12:07:19 -05:00
if key == ""
return
endif
2014-06-06 12:35:19 -04:00
2014-11-23 12:07:19 -05:00
call self.set_input_key_stack(s:String.split_by_keys(key))
while !(empty(self.input_key_stack()) || self._is_exit())
call self._input_char(remove(self.input_key_stack(), 0))
endwhile
endfunction
function! s:base._update()
" call self.callevent("on_update")
" if !getchar(1)
" continue
" endif
"
" call self._input(s:getchar(0))
" call self.draw()
call self.callevent("on_update")
call self._input(s:Input.getchar())
if self._is_exit()
return -1
endif
call self.draw()
2014-06-06 12:35:19 -04:00
endfunction
function! s:base._main(...)
try
call self._init()
2014-02-09 07:21:26 -05:00
call self.callevent("on_enter")
2014-11-23 12:07:19 -05:00
call self._input(get(a:, 1, ""))
2014-06-06 12:35:19 -04:00
call self.draw()
while !self._is_exit()
2014-02-23 23:43:16 -05:00
try
2014-11-23 12:07:19 -05:00
if self._update()
2014-08-27 21:22:57 -04:00
break
endif
2014-02-23 23:43:16 -05:00
catch
call self.callevent("on_exception")
endtry
endwhile
catch
echohl ErrorMsg | echom v:throwpoint . " " . v:exception | echohl None
2014-02-23 23:43:16 -05:00
let self.variables.exit_code = -1
finally
call self._finish()
2014-02-09 07:21:26 -05:00
call self.callevent("on_leave")
endtry
return self.exit_code()
endfunction
2014-01-29 00:29:23 -05:00
function! s:base._finish()
2014-02-04 23:32:29 -05:00
call self.hl_cursor_on()
2014-01-29 00:29:23 -05:00
endfunction
function! s:base._is_exit()
return self.variables.exit
2014-01-29 00:29:23 -05:00
endfunction
2014-02-04 23:32:29 -05:00
function! s:_as_key_config(config)
let base = {
\ "noremap" : 0,
\ "lock" : 0,
\ }
return type(a:config) == type({}) ? extend(base, a:config)
\ : extend(base, {
\ "key" : a:config,
\ })
2014-01-29 00:29:23 -05:00
endfunction
2014-02-04 23:32:29 -05:00
function! s:_unmap(mapping, key)
2014-11-23 12:07:19 -05:00
let keys = s:String.split_by_keys(a:key)
2014-06-06 12:35:19 -04:00
if len(keys) > 1
return join(map(keys, 's:_unmap(a:mapping, v:val)'), '')
endif
2014-02-04 23:32:29 -05:00
if !has_key(a:mapping, a:key)
return a:key
endif
let rhs = s:_as_key_config(a:mapping[a:key])
let next = s:_as_key_config(get(a:mapping, rhs.key, {}))
if rhs.noremap && next.lock == 0
return rhs.key
2014-01-29 00:29:23 -05:00
endif
2014-02-04 23:32:29 -05:00
return s:_unmap(a:mapping, rhs.key)
2014-01-29 00:29:23 -05:00
endfunction
2014-02-04 23:32:29 -05:00
function! s:base._get_keymapping()
let result = {}
2014-02-09 07:21:26 -05:00
" for module in values(self.variables.modules)
for module in self.variables.modules.slots()
2014-02-04 23:32:29 -05:00
if has_key(module, "keymapping")
2014-02-09 07:21:26 -05:00
if module isnot self
call extend(result, module.keymapping(self))
endif
2014-01-29 00:29:23 -05:00
endif
2014-02-04 23:32:29 -05:00
endfor
return extend(extend(result, self.variables.keymapping), self.keymapping())
2014-01-29 00:29:23 -05:00
endfunction
let &cpo = s:save_cpo
unlet s:save_cpo