1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-01-24 09:40:06 +08:00
SpaceVim/bundle/unite.vim/autoload/unite/start.vim
2020-06-13 14:06:35 +08:00

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