"=============================================================================
" FILE: handler.vim
" AUTHOR: Shougo Matsushita <Shougo.Matsu@gmail.com>
" License: MIT license {{{
" Permission is hereby granted, free of charge, to any person obtaining
" a copy of this software and associated documentation files (the
" "Software"), to deal in the Software without restriction, including
" without limitation the rights to use, copy, modify, merge, publish,
" distribute, sublicense, and/or sell copies of the Software, and to
" permit persons to whom the Software is furnished to do so, subject to
" the following conditions:
"
" The above copyright notice and this permission notice shall be included
" in all copies or substantial portions of the Software.
"
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
" IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
" }}}
"=============================================================================
let s:save_cpo = &cpo
set cpo&vim
function! neocomplete#handler#_on_moved_i() abort "{{{
let neocomplete = neocomplete#get_current_neocomplete()
if neocomplete.linenr != line('.')
call neocomplete#helper#clear_result()
endif
let neocomplete.linenr = line('.')
call s:close_preview_window()
endfunction"}}}
function! neocomplete#handler#_on_insert_enter() abort "{{{
if !neocomplete#is_enabled()
return
endif
let neocomplete = neocomplete#get_current_neocomplete()
if neocomplete.linenr != line('.')
call neocomplete#helper#clear_result()
endif
let neocomplete.linenr = line('.')
if &l:foldmethod ==# 'expr' && foldlevel('.') != 0
foldopen
endif
endfunction"}}}
function! neocomplete#handler#_on_insert_leave() abort "{{{
call neocomplete#helper#clear_result()
call s:close_preview_window()
call s:make_cache_current_line()
let neocomplete = neocomplete#get_current_neocomplete()
let neocomplete.cur_text = ''
endfunction"}}}
function! neocomplete#handler#_on_complete_done() abort "{{{
let neocomplete = neocomplete#get_current_neocomplete()
if neocomplete.event !=# 'mapping'
\ && !s:is_delimiter() && !get(neocomplete, 'refresh', 0)
call neocomplete#mappings#close_popup()
endif
" Use v:completed_item feature.
if !exists('v:completed_item') || empty(v:completed_item)
return
endif
let complete_str = v:completed_item.word
if complete_str == ''
return
endif
let frequencies = neocomplete#variables#get_frequencies()
if !has_key(frequencies, complete_str)
let frequencies[complete_str] = 20
else
let frequencies[complete_str] += 20
endif
endfunction"}}}
function! neocomplete#handler#_on_insert_char_pre() abort "{{{
let neocomplete = neocomplete#get_current_neocomplete()
let neocomplete.skip_next_complete = 0
if pumvisible() && g:neocomplete#enable_refresh_always
" Auto refresh
call feedkeys("\<Plug>(neocomplete_auto_refresh)")
endif
if neocomplete#is_cache_disabled()
return
endif
if neocomplete.old_char != ' ' && v:char == ' ' && v:count == 0
call s:make_cache_current_line()
endif
let neocomplete.old_char = v:char
endfunction"}}}
function! neocomplete#handler#_on_text_changed() abort "{{{
if neocomplete#is_cache_disabled()
return
endif
if getline('.') == ''
call s:make_cache_current_line()
endif
if !neocomplete#util#is_text_changed()
call s:indent_current_line()
endif
endfunction"}}}
function! s:complete_delay(timer) abort "{{{
let event = s:timer.event
unlet! s:timer
return s:do_auto_complete(event)
endfunction"}}}
function! neocomplete#handler#_do_auto_complete(event) abort "{{{
if s:check_in_do_auto_complete(a:event)
return
endif
if g:neocomplete#auto_complete_delay > 0 && has('timers')
if exists('s:timer')
call timer_stop(s:timer.id)
endif
if a:event !=# 'Manual'
let s:timer = { 'event': a:event }
let s:timer.id = timer_start(
\ g:neocomplete#auto_complete_delay,
\ function('s:complete_delay'))
return
endif
endif
return s:do_auto_complete(a:event)
endfunction"}}}
function! s:do_auto_complete(event) abort "{{{
let neocomplete = neocomplete#get_current_neocomplete()
if s:check_in_do_auto_complete(a:event)
return
endif
let neocomplete.skipped = 0
let neocomplete.event = a:event
call neocomplete#helper#clear_result()
" Set context filetype.
call neocomplete#context_filetype#set()
let cur_text = neocomplete#get_cur_text(1)
let complete_pos = -1
call neocomplete#print_debug('cur_text = ' . cur_text)
try
" Prevent infinity loop.
if s:is_skip_auto_complete(cur_text)
call neocomplete#print_debug('Skipped.')
return
endif
let complete_pos = s:check_force_omni(cur_text)
if complete_pos >= 0
return
endif
" Check multibyte input or eskk or spaces.
if cur_text =~ '^\s*$'
\ || (!neocomplete#is_eskk_enabled()
\ && neocomplete#is_multibyte_input(cur_text))
call neocomplete#print_debug('Skipped.')
return
endif
try
let neocomplete.is_auto_complete = 1
" Do prefetch.
let neocomplete.complete_sources =
\ neocomplete#complete#_get_results(cur_text)
finally
let neocomplete.is_auto_complete = 0
endtry
if empty(neocomplete.complete_sources)
call s:check_fallback(cur_text)
return
endif
" Start auto complete.
call s:complete_key(
\ "\<Plug>(neocomplete_start_auto_complete)")
finally
call neocomplete#complete#_set_previous_position(cur_text, complete_pos)
endtry
endfunction"}}}
function! s:check_in_do_auto_complete(event) abort "{{{
if neocomplete#is_locked()
return 1
endif
" Detect completefunc.
if &l:completefunc != '' && &l:buftype =~ 'nofile'
return 1
endif
let neocomplete = neocomplete#get_current_neocomplete()
" Detect foldmethod.
if (&l:foldmethod ==# 'expr' || &l:foldmethod ==# 'syntax')
\ && !neocomplete.detected_foldmethod
\ && a:event !=# 'InsertEnter'
let neocomplete.detected_foldmethod = 1
call neocomplete#print_error(
\ printf('foldmethod = "%s" is detected.', &foldmethod))
redir => foldmethod
verbose setlocal foldmethod?
redir END
for msg in split(substitute(foldmethod, '\t', '', 'g'), "\n")
call neocomplete#print_error(msg)
endfor
call neocomplete#print_error(
\ 'You should disable it or install FastFold plugin.')
endif
endfunction"}}}
function! s:is_skip_auto_complete(cur_text) abort "{{{
let neocomplete = neocomplete#get_current_neocomplete()
if (g:neocomplete#lock_iminsert && &l:iminsert)
\ || (&l:formatoptions =~# '[tca]' && &l:textwidth > 0
\ && strdisplaywidth(a:cur_text) >= &l:textwidth)
let neocomplete.skip_next_complete = 0
return 1
endif
let skip = neocomplete.skip_next_complete
if !skip || s:is_delimiter()
return 0
endif
let neocomplete.skip_next_complete = 0
return skip
endfunction"}}}
function! s:close_preview_window() abort "{{{
if g:neocomplete#enable_auto_close_preview
\ && bufname('%') !=# '[Command Line]'
\ && winnr('$') != 1 && !&l:previewwindow
\ && !neocomplete#is_cache_disabled()
" Close preview window.
pclose!
endif
endfunction"}}}
function! s:make_cache_current_line() abort "{{{
let neocomplete = neocomplete#get_current_neocomplete()
if neocomplete#helper#is_enabled_source('buffer',
\ neocomplete.context_filetype)
" Caching current cache line.
call neocomplete#sources#buffer#make_cache_current_line()
endif
if neocomplete#helper#is_enabled_source('member',
\ neocomplete.context_filetype)
" Caching current cache line.
call neocomplete#sources#member#make_cache_current_line()
endif
endfunction"}}}
function! s:check_force_omni(cur_text) abort "{{{
let cur_text = a:cur_text
let complete_pos = neocomplete#helper#get_force_omni_complete_pos(cur_text)
if complete_pos >= 0
\ && !neocomplete#complete#_check_previous_position(
\ cur_text, complete_pos)
call s:complete_key("\<Plug>(neocomplete_start_omni_complete)")
endif
return complete_pos
endfunction"}}}
function! s:check_fallback(cur_text) abort "{{{
let cur_text = a:cur_text
let complete_pos = match(cur_text, '\h\w*$')
let neocomplete = neocomplete#get_current_neocomplete()
if empty(g:neocomplete#fallback_mappings)
\ || len(matchstr(cur_text, '\h\w*$'))
\ < g:neocomplete#auto_completion_start_length
\ || neocomplete.skip_next_complete
\ || neocomplete#complete#_check_previous_position(
\ cur_text, complete_pos)
return
endif
let key = ''
for i in range(0, len(g:neocomplete#fallback_mappings)-1)
let key .= '<C-r>=neocomplete#mappings#fallback(' . i . ')<CR>'
endfor
execute 'inoremap <silent> <Plug>(neocomplete_fallback)' key
" Fallback
call s:complete_key("\<Plug>(neocomplete_fallback)")
endfunction"}}}
function! s:complete_key(key) abort "{{{
call neocomplete#helper#complete_configure()
call feedkeys(a:key)
endfunction"}}}
function! s:indent_current_line() abort "{{{
" indent line matched by indentkeys
let neocomplete = neocomplete#get_current_neocomplete()
let cur_text = matchstr(getline('.'), '^.*\%'.col('.').'c')
if neocomplete.indent_text == matchstr(getline('.'), '\S.*$')
return
endif
for word in filter(map(split(&l:indentkeys, ','),
\ "v:val =~ '^<.*>$' ? matchstr(v:val, '^<\\zs.*\\ze>$')
\ : matchstr(v:val, ':\\|e\\|=\\zs.*')"),
\ "v:val != ''")
if word ==# 'e'
let word = 'else'
endif
let lastpos = len(cur_text)-len(word)
if lastpos >= 0 && strridx(cur_text, word) == lastpos
call neocomplete#helper#indent_current_line()
let neocomplete.indent_text = matchstr(getline('.'), '\S.*$')
break
endif
endfor
endfunction"}}}
function! s:is_delimiter() abort "{{{
" Check delimiter pattern.
let is_delimiter = 0
let filetype = neocomplete#get_context_filetype()
let cur_text = neocomplete#get_cur_text(1)
for delimiter in ['/', '.'] +
\ get(g:neocomplete#delimiter_patterns, filetype, [])
if stridx(cur_text, delimiter,
\ len(cur_text) - len(delimiter)) >= 0
let is_delimiter = 1
break
endif
endfor
return is_delimiter
endfunction"}}}
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: foldmethod=marker