mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-01-24 09:40:06 +08:00
563 lines
16 KiB
VimL
563 lines
16 KiB
VimL
"=============================================================================
|
|
" FILE: start.vim
|
|
" AUTHOR: Shougo Matsushita <Shougo.Matsu@gmail.com>
|
|
" License: MIT license
|
|
"=============================================================================
|
|
|
|
let s:save_cpo = &cpo
|
|
set cpo&vim
|
|
|
|
function! unite#start#standard(sources, ...) abort "{{{
|
|
" Check command line window.
|
|
if unite#util#is_cmdwin()
|
|
call unite#print_error(
|
|
\ 'Command line buffer is detected! '.
|
|
\ 'Please close command line buffer.')
|
|
return
|
|
endif
|
|
|
|
let context = get(a:000, 0, {})
|
|
let context = unite#init#_context(context,
|
|
\ unite#helper#get_source_names(a:sources))
|
|
|
|
if context.resume
|
|
" Check resume buffer.
|
|
let resume_bufnr = s:get_resume_buffer(context.buffer_name)
|
|
if resume_bufnr > 0 &&
|
|
\ getbufvar(resume_bufnr, 'unite').source_names ==#
|
|
\ unite#helper#get_source_names(a:sources)
|
|
return unite#start#resume(context.buffer_name, get(a:000, 0, {}))
|
|
endif
|
|
endif
|
|
|
|
call unite#variables#enable_current_unite()
|
|
|
|
if context.toggle "{{{
|
|
if unite#view#_close(context.buffer_name)
|
|
return
|
|
endif
|
|
endif"}}}
|
|
|
|
if empty(a:sources)
|
|
echohl Comment
|
|
call unite#view#_redraw_echo(
|
|
\ '[unite.vim] interactive mode: Please input source name')
|
|
echohl None
|
|
endif
|
|
|
|
try
|
|
call unite#init#_current_unite(a:sources, context)
|
|
catch /^unite.vim: Invalid /
|
|
call unite#print_error(v:exception)
|
|
return
|
|
endtry
|
|
|
|
" Caching.
|
|
let current_unite = unite#variables#current_unite()
|
|
let current_unite.last_input = context.input
|
|
let current_unite.input = context.input
|
|
let current_unite.last_path = context.path
|
|
call unite#candidates#_recache(context.input, context.is_redraw)
|
|
|
|
if !context.buffer
|
|
call unite#variables#disable_current_unite()
|
|
return
|
|
endif
|
|
|
|
if !current_unite.is_async &&
|
|
\ (context.force_immediately
|
|
\ || context.immediately || !context.empty) "{{{
|
|
let candidates = unite#candidates#gather()
|
|
|
|
if empty(candidates)
|
|
" Ignore.
|
|
call unite#view#_print_warning(
|
|
\ 'unite buffer "'
|
|
\ . current_unite.buffer_name.'" candidates are empty')
|
|
call unite#variables#disable_current_unite()
|
|
return
|
|
elseif (context.immediately && len(candidates) == 1)
|
|
\ || context.force_immediately
|
|
" Immediately action.
|
|
call unite#action#do(
|
|
\ context.default_action, [candidates[0]])
|
|
call unite#variables#disable_current_unite()
|
|
return
|
|
endif
|
|
endif"}}}
|
|
|
|
call unite#init#_unite_buffer()
|
|
|
|
call unite#variables#disable_current_unite()
|
|
|
|
setlocal modifiable
|
|
|
|
if context.force_redraw
|
|
call unite#force_redraw()
|
|
else
|
|
call unite#view#_redraw_candidates()
|
|
endif
|
|
|
|
call unite#handlers#_on_bufwin_enter(bufnr('%'))
|
|
|
|
call unite#view#_init_cursor()
|
|
endfunction"}}}
|
|
|
|
function! unite#start#script(sources, ...) abort "{{{
|
|
" Start unite from script.
|
|
|
|
let context = get(a:000, 0, {})
|
|
|
|
let context.script = 1
|
|
|
|
return &filetype == 'unite' ?
|
|
\ unite#start#temporary(a:sources, context) :
|
|
\ unite#start#standard(a:sources, context)
|
|
endfunction"}}}
|
|
|
|
function! unite#start#temporary(sources, ...) abort "{{{
|
|
" Get current context.
|
|
let old_context = unite#get_context()
|
|
let unite = unite#get_current_unite()
|
|
|
|
if !empty(unite) && !empty(old_context)
|
|
let context = deepcopy(old_context)
|
|
let context.unite__old_buffer_info = insert(context.unite__old_buffer_info, {
|
|
\ 'buffer_name' : unite.buffer_name,
|
|
\ 'pos' : getpos('.'),
|
|
\ 'profile_name' : unite.profile_name,
|
|
\ })
|
|
|
|
if unite.context.unite__is_manual
|
|
call unite#sources#history_unite#add(unite)
|
|
endif
|
|
else
|
|
let context = {}
|
|
let context = unite#init#_context(context,
|
|
\ unite#helper#get_source_names(a:sources))
|
|
let context.unite__old_buffer_info = []
|
|
endif
|
|
|
|
let context.input = ''
|
|
let context.path = ''
|
|
|
|
let new_context = get(a:000, 0, {})
|
|
|
|
" Overwrite context.
|
|
let context = extend(context, new_context)
|
|
|
|
let context.temporary = 1
|
|
let context.unite__direct_switch = 1
|
|
let context.auto_preview = 0
|
|
let context.auto_highlight = 0
|
|
let context.unite__is_vimfiler = 0
|
|
let context.unite__old_winwidth = 0
|
|
let context.unite__old_winheight = 0
|
|
let context.unite__is_resize = 0
|
|
let context.quick_match = 0
|
|
let context.resume = 0
|
|
let context.force_redraw = 0
|
|
|
|
if context.script
|
|
" Set buffer-name automatically.
|
|
let context.buffer_name =
|
|
\ join(unite#helper#get_source_names(a:sources))
|
|
endif
|
|
|
|
let buffer_name = get(a:000, 1,
|
|
\ substitute(context.buffer_name, '-\d\+$', '', '')
|
|
\ . '-' . len(context.unite__old_buffer_info))
|
|
|
|
let context.buffer_name = buffer_name
|
|
|
|
let unite_save = unite#get_current_unite()
|
|
|
|
let cwd = getcwd()
|
|
|
|
call unite#start#standard(a:sources, context)
|
|
|
|
" Overwrite unite.
|
|
let unite = unite#get_current_unite()
|
|
let unite.prev_bufnr = unite_save.prev_bufnr
|
|
let unite.prev_winnr = unite_save.prev_winnr
|
|
let unite.args = a:sources
|
|
if has_key(unite, 'update_time_save')
|
|
let unite.update_time_save = unite_save.update_time_save
|
|
endif
|
|
let unite.winnr = unite_save.winnr
|
|
let unite.has_preview_window = unite_save.has_preview_window
|
|
let unite.prev_winsaveview = unite_save.prev_winsaveview
|
|
let unite.win_rest_cmd = unite_save.win_rest_cmd
|
|
|
|
" Restore current directory.
|
|
execute 'lcd' fnameescape(cwd)
|
|
endfunction"}}}
|
|
|
|
function! unite#start#vimfiler_check_filetype(sources, ...) abort "{{{
|
|
let context = get(a:000, 0, {})
|
|
let context = unite#init#_context(context,
|
|
\ unite#helper#get_source_names(a:sources))
|
|
let context.unite__is_vimfiler = 1
|
|
let context.unite__is_interactive = 0
|
|
if !has_key(context, 'vimfiler__is_dummy')
|
|
let context.vimfiler__is_dummy = 0
|
|
endif
|
|
|
|
try
|
|
call unite#init#_current_unite(a:sources, context)
|
|
catch /^unite.vim: Invalid /
|
|
return []
|
|
endtry
|
|
|
|
for source in filter(copy(unite#loaded_sources_list()),
|
|
\ "has_key(v:val, 'vimfiler_check_filetype')")
|
|
let ret = source.vimfiler_check_filetype(source.args, context)
|
|
if empty(ret)
|
|
continue
|
|
endif
|
|
|
|
let [type, info] = ret
|
|
if type ==# 'file'
|
|
call unite#init#_candidates_source([info[1]], source.name)
|
|
elseif type ==# 'directory'
|
|
" nop
|
|
elseif type ==# 'error'
|
|
call unite#print_error(info)
|
|
return []
|
|
else
|
|
call unite#print_error('Invalid filetype : ' . type)
|
|
endif
|
|
|
|
return [type, info]
|
|
endfor
|
|
|
|
" Not found.
|
|
return []
|
|
endfunction"}}}
|
|
|
|
function! unite#start#get_candidates(sources, ...) abort "{{{
|
|
let unite_save = unite#get_current_unite()
|
|
|
|
try
|
|
let context = get(a:000, 0, {})
|
|
let context = unite#init#_context(context,
|
|
\ unite#helper#get_source_names(a:sources))
|
|
let context.buffer = 0
|
|
let context.unite__is_interactive = 0
|
|
|
|
" Finalize.
|
|
let candidates = s:get_candidates(a:sources, context)
|
|
|
|
" Call finalize functions.
|
|
call unite#helper#call_hook(unite#loaded_sources_list(), 'on_close')
|
|
let unite = unite#get_current_unite()
|
|
let unite.is_finalized = 1
|
|
finally
|
|
call unite#set_current_unite(unite_save)
|
|
endtry
|
|
|
|
return candidates
|
|
endfunction"}}}
|
|
|
|
function! unite#start#get_vimfiler_candidates(sources, ...) abort "{{{
|
|
let unite_save = unite#get_current_unite()
|
|
|
|
try
|
|
let context = get(a:000, 0, {})
|
|
let context = unite#init#_context(context,
|
|
\ unite#helper#get_source_names(a:sources))
|
|
let context.unite__not_buffer = 1
|
|
let context.unite__is_vimfiler = 1
|
|
let context.unite__is_interactive = 0
|
|
if !has_key(context, 'vimfiler__is_dummy')
|
|
let context.vimfiler__is_dummy = 0
|
|
endif
|
|
|
|
let candidates = s:get_candidates(a:sources, context)
|
|
|
|
" Converts utf-8-mac to the current encoding.
|
|
if unite#util#is_mac() && has('iconv')
|
|
for item in filter(copy(candidates),
|
|
\ "v:val.action__path =~# '[^\\x00-\\x7f]'")
|
|
let item.action__path = unite#util#iconv(
|
|
\ item.action__path, 'utf-8-mac', &encoding)
|
|
let item.word = unite#util#iconv(item.word, 'utf-8-mac', &encoding)
|
|
let item.abbr = unite#util#iconv(item.abbr, 'utf-8-mac', &encoding)
|
|
let item.vimfiler__filename = unite#util#iconv(
|
|
\ item.vimfiler__filename, 'utf-8-mac', &encoding)
|
|
let item.vimfiler__abbr = unite#util#iconv(
|
|
\ item.vimfiler__abbr, 'utf-8-mac', &encoding)
|
|
endfor
|
|
endif
|
|
finally
|
|
call unite#set_current_unite(unite_save)
|
|
endtry
|
|
|
|
return candidates
|
|
endfunction"}}}
|
|
|
|
function! unite#start#resume(buffer_name, ...) abort "{{{
|
|
" Check command line window.
|
|
if unite#util#is_cmdwin()
|
|
call unite#print_error(
|
|
\ 'Command line buffer is detected! '.
|
|
\ 'Please close command line buffer.')
|
|
return
|
|
endif
|
|
|
|
let bufnr = s:get_unite_buffer(a:buffer_name)
|
|
if bufnr < 0
|
|
return
|
|
endif
|
|
|
|
let context = getbufvar(bufnr, 'unite').context
|
|
|
|
let prev_bufnr = bufnr('%')
|
|
let winnr = winnr()
|
|
let prev_winsaveview = winsaveview()
|
|
let win_rest_cmd = context.unite__direct_switch ||
|
|
\ unite#helper#get_unite_winnr(context.buffer_name) > 0 ?
|
|
\ '' : winrestcmd()
|
|
|
|
let new_context = get(a:000, 0, {})
|
|
" Generic no.
|
|
for option in map(filter(items(new_context),
|
|
\ "stridx(v:val[0], 'no_') == 0 && v:val[1]"), "v:val[0]")
|
|
let new_context[option[3:]] = 0
|
|
endfor
|
|
call extend(context, new_context)
|
|
|
|
call unite#view#_switch_unite_buffer(context.buffer_name, context)
|
|
|
|
" Set parameters.
|
|
let unite = b:unite
|
|
let unite.winnr = winnr
|
|
let unite.prev_bufnr = prev_bufnr
|
|
let unite.prev_winnr = winnr
|
|
let unite.prev_winsaveview = prev_winsaveview
|
|
if !context.unite__direct_switch
|
|
let unite.win_rest_cmd = win_rest_cmd
|
|
endif
|
|
let unite.access_time = localtime()
|
|
let unite.context = context
|
|
let unite.is_finalized = 0
|
|
let unite.preview_candidate = {}
|
|
let unite.highlight_candidate = {}
|
|
let unite.context.resume = 1
|
|
let unite.context.buffer_name =
|
|
\ (a:buffer_name == '' ? 'default' : a:buffer_name)
|
|
if context.winwidth != 0
|
|
let unite.context.unite__old_winwidth = 0
|
|
endif
|
|
if context.winheight != 0
|
|
let unite.context.unite__old_winheight = 0
|
|
endif
|
|
|
|
call unite#set_current_unite(unite)
|
|
|
|
if context.force_redraw
|
|
call unite#force_redraw()
|
|
endif
|
|
|
|
if has_key(new_context, 'input')
|
|
call unite#mappings#narrowing(new_context.input)
|
|
call unite#redraw()
|
|
endif
|
|
|
|
call unite#view#_resize_window()
|
|
call unite#view#_init_cursor()
|
|
endfunction"}}}
|
|
|
|
function! unite#start#resume_from_temporary(context) abort "{{{
|
|
if empty(a:context.unite__old_buffer_info)
|
|
return
|
|
endif
|
|
|
|
call unite#handlers#_on_buf_unload(a:context.buffer_name)
|
|
|
|
let unite_save = unite#get_current_unite()
|
|
|
|
" Resume unite buffer.
|
|
let buffer_info = a:context.unite__old_buffer_info[0]
|
|
call unite#start#resume(buffer_info.buffer_name,
|
|
\ {'unite__direct_switch' : 1})
|
|
let a:context.unite__old_buffer_info = a:context.unite__old_buffer_info[1:]
|
|
|
|
" Overwrite unite.
|
|
let unite = unite#get_current_unite()
|
|
let unite.prev_bufnr = unite_save.prev_bufnr
|
|
let unite.prev_winnr = unite_save.prev_winnr
|
|
|
|
" Restore the previous position
|
|
call setpos('.', buffer_info.pos)
|
|
if line('.') == unite.prompt_linenr && unite.context.start_insert
|
|
startinsert!
|
|
endif
|
|
|
|
call unite#redraw()
|
|
endfunction"}}}
|
|
|
|
function! unite#start#complete(sources, ...) abort "{{{
|
|
let sources = type(a:sources) == type('') ?
|
|
\ [a:sources] : a:sources
|
|
let context = {
|
|
\ 'col' : col('.'), 'complete' : 1,
|
|
\ 'direction' : 'rightbelow',
|
|
\ 'buffer_name' : 'completion',
|
|
\ 'profile_name' : 'completion',
|
|
\ 'here' : 1,
|
|
\ }
|
|
call extend(context, get(a:000, 0, {}))
|
|
|
|
return printf("\<C-o>:\<C-u>call unite#start(%s, %s)\<CR>",
|
|
\ string(sources), string(context))
|
|
endfunction "}}}
|
|
|
|
function! unite#start#_pos(buffer_name, direction, count) abort "{{{
|
|
let bufnr = s:get_unite_buffer(a:buffer_name)
|
|
if bufnr < 0
|
|
return
|
|
endif
|
|
|
|
let unite = getbufvar(bufnr, 'unite')
|
|
|
|
let next =
|
|
\ (a:direction ==# 'first') ? 0 :
|
|
\ (a:direction ==# 'last') ? len(unite.candidates)-1 :
|
|
\ (a:direction ==# 'next') ? unite.candidate_cursor+a:count :
|
|
\ unite.candidate_cursor-a:count
|
|
if next < 0 || next >= len(unite.candidates)
|
|
" Ignore.
|
|
call unite#view#_print_error('No more items')
|
|
return
|
|
endif
|
|
|
|
let candidate = unite.candidates[next]
|
|
|
|
" Immediately action.
|
|
silent call unite#action#do_candidates(
|
|
\ unite.context.default_action, [candidate],
|
|
\ unite.context, unite.sources)
|
|
|
|
let unite.candidate_cursor = next
|
|
|
|
call unite#view#_redraw_echo(printf('[%d/%d] %s',
|
|
\ unite.candidate_cursor+1, len(unite.candidates),
|
|
\ get(candidate, 'abbr', candidate.word)))
|
|
|
|
let winnr = unite#helper#get_unite_winnr(unite.context.buffer_name)
|
|
if winnr < 0
|
|
return
|
|
endif
|
|
|
|
" Move cursor
|
|
let prev_winnr = winnr()
|
|
try
|
|
execute winnr . 'wincmd w'
|
|
call cursor(unite#helper#get_current_candidate_linenr(next), 0)
|
|
call unite#view#_set_cursor_line()
|
|
call unite#view#_save_position()
|
|
finally
|
|
execute prev_winnr . 'wincmd w'
|
|
endtry
|
|
endfunction"}}}
|
|
|
|
function! unite#start#_do_command(cmd)
|
|
let bufnr = s:get_unite_buffer('')
|
|
if bufnr < 0
|
|
return
|
|
endif
|
|
|
|
let unite = getbufvar(bufnr, 'unite')
|
|
if empty(unite.candidates)
|
|
return
|
|
endif
|
|
|
|
" The step by step is done backwards because, if the command happens to
|
|
" include or exclude lines in the file, the remaining candidates don't have
|
|
" its position changed when the default action is applied.
|
|
|
|
silent! UniteLast
|
|
silent! execute a:cmd
|
|
while unite.candidate_cursor > 0
|
|
silent! UnitePrevious
|
|
silent! execute a:cmd
|
|
endwhile
|
|
endfunction
|
|
|
|
function! s:get_candidates(sources, context) abort "{{{
|
|
try
|
|
let current_unite = unite#init#_current_unite(a:sources, a:context)
|
|
catch /^unite.vim: Invalid /
|
|
return []
|
|
endtry
|
|
|
|
" Caching.
|
|
let current_unite.last_input = a:context.input
|
|
let current_unite.input = a:context.input
|
|
let current_unite.last_path = a:context.path
|
|
call unite#set_current_unite(current_unite)
|
|
call unite#set_context(a:context)
|
|
|
|
call unite#variables#enable_current_unite()
|
|
|
|
call unite#candidates#_recache(a:context.input, a:context.is_redraw)
|
|
|
|
let candidates = []
|
|
for source in current_unite.sources
|
|
if !empty(source.unite__candidates)
|
|
let candidates += source.unite__candidates
|
|
endif
|
|
endfor
|
|
|
|
return candidates
|
|
endfunction"}}}
|
|
|
|
function! s:get_unite_buffer(buffer_name) abort "{{{
|
|
if a:buffer_name == ''
|
|
" Use last unite buffer.
|
|
if !exists('t:unite') ||
|
|
\ !bufexists(t:unite.last_unite_bufnr)
|
|
call unite#util#print_error('No unite buffer.')
|
|
return -1
|
|
endif
|
|
|
|
let bufnr = t:unite.last_unite_bufnr
|
|
else
|
|
let bufnr = s:get_resume_buffer(a:buffer_name)
|
|
endif
|
|
|
|
if bufnr > 0 && type(getbufvar(bufnr, 'unite')) != type({})
|
|
" Unite buffer is released.
|
|
call unite#util#print_error(
|
|
\ printf('Invalid unite buffer(%d) is detected.', bufnr))
|
|
return -1
|
|
endif
|
|
|
|
return bufnr
|
|
endfunction"}}}
|
|
function! s:get_resume_buffer(buffer_name) abort "{{{
|
|
let buffer_name = a:buffer_name
|
|
if buffer_name !~ '@\d\+$'
|
|
" Add postfix.
|
|
let prefix = '[unite] - '
|
|
let prefix .= buffer_name
|
|
let buffer_name .= unite#helper#get_postfix(prefix, 0)
|
|
endif
|
|
|
|
let buffer_dict = {}
|
|
for unite in map(filter(range(1, bufnr('$')),
|
|
\ "getbufvar(v:val, '&filetype') ==# 'unite' &&
|
|
\ type(getbufvar(v:val, 'unite')) == type({})"),
|
|
\ "getbufvar(v:val, 'unite')")
|
|
let buffer_dict[unite.buffer_name] = unite.bufnr
|
|
endfor
|
|
|
|
return get(buffer_dict, buffer_name, -1)
|
|
endfunction"}}}
|
|
|
|
let &cpo = s:save_cpo
|
|
unlet s:save_cpo
|
|
|
|
" vim: foldmethod=marker
|