"=============================================================================
" autocomplpop.vim - Automatically open the popup menu for completion.
"=============================================================================
"
" Author: Takeshi Nishida
" Version: 2.3.1, for Vim 7.1
" Licence: MIT Licence
" URL: https://www.vim8.org/scripts/script.php?script_id=1879
"
" GetLatestVimScripts: 1879 1 :AutoInstall: autocomplpop.vim
"
"=============================================================================
" DOCUMENT: (Japanese: http://vim.g.hatena.ne.jp/keyword/autocomplpop.vim)
"
" Description: ---------------------------------------------------------- {{{1
" Install this plugin and your vim comes to automatically opens the popup
" menu for completion when you enter characters or move the cursor in Insert
" mode.
"
" Installation: --------------------------------------------------------- {{{1
" Drop this file in your plugin directory.
"
" Usage: ---------------------------------------------------------------- {{{1
" If this plugin has been installed, the auto-popup is enabled at startup by
" default.
"
" Which completion method is used depends on the text before the cursor. The
" default behavior is as follows:
"
" 1. The keyword completion is attempted if the text before the cursor
" consists of two keyword character.
" 2. The keyword completion is attempted in Scheme file if the text before
" the cursor consists of "(" + a keyword character.
" 3. The filename completion is attempted if the text before the cursor
" consists of a filename character + a path separator + 0 or more
" filename characters.
" 4. The omni completion is attempted in Ruby file if the text before the
" cursor consists of "." or "::". (Ruby interface is required.)
" 5. The omni completion is attempted in Python file if the text before
" the cursor consists of ".". (Python interface is required.)
" 6. The omni completion is attempted in HTML/XHTML file if the text
" before the cursor consists of "<" or "'), '\d\+_')
endfunction
"-----------------------------------------------------------------------------
function! s:GetPopupFeeder()
return s:PopupFeeder
endfunction
"-----------------------------------------------------------------------------
function! s:Enable()
" NOTE: CursorMovedI is not triggered while the pupup menu is visible. And
" it will be triggered when pupup menu is disappeared.
augroup AutoComplPopGlobalAutoCommand
autocmd InsertEnter * let s:PopupFeeder.last_pos = [] | unlet s:PopupFeeder.last_pos
autocmd InsertLeave * call s:PopupFeeder.finish()
autocmd CursorMovedI * call s:PopupFeeder.feed()
augroup END
nnoremap i i=GetPopupFeeder().feed()
nnoremap R R=GetPopupFeeder().feed()
endfunction
"-----------------------------------------------------------------------------
function! s:Disable()
autocmd! AutoComplPopGlobalAutoCommand
nunmap i
nunmap R
endfunction
" OBJECT: PopupFeeder: ================================================== {{{1
let s:PopupFeeder = { 'behavs' : [], 'lock_count' : 0 }
"-----------------------------------------------------------------------------
function! s:PopupFeeder.feed()
if self.lock_count > 0 || &paste
return ''
endif
let cursor_moved = self.check_cursor_and_update()
if exists('self.behavs[0]') && self.behavs[0].repeat
let self.behavs = (self.behavs[0].repeat ? [ self.behavs[0] ] : [])
elseif cursor_moved
let self.behavs = copy(exists('g:AutoComplPop_Behavior[&filetype]') ? g:AutoComplPop_Behavior[&filetype]
\ : g:AutoComplPop_Behavior['*'])
else
let self.behavs = []
endif
let cur_text = strpart(getline('.'), 0, col('.') - 1)
call filter(self.behavs, 'cur_text =~ v:val.pattern && cur_text !~ v:val.excluded')
if empty(self.behavs)
call self.finish()
return ''
endif
" In case of dividing words by symbols while popup menu is visible,
" popup is not available unless input or try popup once.
" (E.g. "for(int", "ab==cd") So duplicates first completion.
call insert(self.behavs, self.behavs[0])
call s:OptionManager.set('completeopt', 'menuone' . (g:AutoComplPop_CompleteoptPreview ? ',preview' : ''))
call s:OptionManager.set('complete', g:AutoComplPop_CompleteOption)
call s:OptionManager.set('ignorecase', g:AutoComplPop_IgnoreCaseOption)
call s:OptionManager.set('lazyredraw', 1)
" use for silence instead of =
call feedkeys(self.behavs[0].command . "\AutocomplpopOnPopupPost", 'm')
return '' " for =
endfunction
"-----------------------------------------------------------------------------
function! s:PopupFeeder.finish()
let self.behavs = []
call s:OptionManager.restore_all()
endfunction
"-----------------------------------------------------------------------------
function! s:PopupFeeder.lock()
let self.lock_count += 1
endfunction
"-----------------------------------------------------------------------------
function! s:PopupFeeder.unlock()
let self.lock_count -= 1
if self.lock_count < 0
let self.lock_count = 0
throw "autocomplpop.vim: not locked"
endif
endfunction
"-----------------------------------------------------------------------------
function! s:PopupFeeder.check_cursor_and_update()
let prev_pos = (exists('self.last_pos') ? self.last_pos : [-1, -1, -1, -1])
let self.last_pos = getpos('.')
if has('multi_byte_ime')
return (prev_pos[1] != self.last_pos[1] || prev_pos[2] + 1 == self.last_pos[2] ||
\ prev_pos[2] > self.last_pos[2])
else
return (prev_pos != self.last_pos)
endif
endfunction
"-----------------------------------------------------------------------------
function! s:PopupFeeder.on_popup_post()
if pumvisible()
" a command to restore to original text and select the first match
return "\\"
elseif exists('self.behavs[1]')
call remove(self.behavs, 0)
return printf("\%s\=%sGetPopupFeeder().on_popup_post()\",
\ self.behavs[0].command, s:GetSidPrefix())
else
call self.finish()
return "\"
endif
endfunction
" OBJECT: OptionManager: sets or restores temporary options ============= {{{1
let s:OptionManager = { 'originals' : {} }
"-----------------------------------------------------------------------------
function! s:OptionManager.set(name, value)
call extend(self.originals, { a:name : eval('&' . a:name) }, 'keep')
execute printf('let &%s = a:value', a:name)
endfunction
"-----------------------------------------------------------------------------
function! s:OptionManager.restore_all()
for [name, value] in items(self.originals)
execute printf('let &%s = value', name)
endfor
let self.originals = {}
endfunction
" }}}1
" INITIALIZATION: GLOBAL OPTIONS: ======================================= {{{1
"...........................................................................
if !exists('g:AutoComplPop_NotEnableAtStartup')
let g:AutoComplPop_NotEnableAtStartup = 0
endif
".........................................................................
if !exists('g:AutoComplPop_IgnoreCaseOption')
let g:AutoComplPop_IgnoreCaseOption = 0
endif
".........................................................................
if !exists('g:AutoComplPop_CompleteOption')
let g:AutoComplPop_CompleteOption = '.,w,b,k'
endif
".........................................................................
if !exists('g:AutoComplPop_CompleteoptPreview')
let g:AutoComplPop_CompleteoptPreview = 0
endif
".........................................................................
if !exists('g:AutoComplPop_Behavior')
let g:AutoComplPop_Behavior = {}
endif
call extend(g:AutoComplPop_Behavior, {
\ '*' : [
\ {
\ 'command' : "\",
\ 'pattern' : '\k\k$',
\ 'excluded' : '^$',
\ 'repeat' : 0,
\ },
\ {
\ 'command' : "\\",
\ 'pattern' : (has('win32') || has('win64') ? '\f[/\\]\f*$' : '\f[/]\f*$'),
\ 'excluded' : '[*/\\][/\\]\f*$\|[^[:print:]]\f*$',
\ 'repeat' : 1,
\ },
\ ],
\ 'ruby' : [
\ {
\ 'command' : "\",
\ 'pattern' : '\k\k$',
\ 'excluded' : '^$',
\ 'repeat' : 0,
\ },
\ {
\ 'command' : "\\",
\ 'pattern' : (has('win32') || has('win64') ? '\f[/\\]\f*$' : '\f[/]\f*$'),
\ 'excluded' : '[*/\\][/\\]\f*$\|[^[:print:]]\f*$',
\ 'repeat' : 1,
\ },
\ {
\ 'command' : "\\",
\ 'pattern' : '\([^. \t]\.\|^:\|\W:\)$',
\ 'excluded' : (has('ruby') ? '^$' : '.*'),
\ 'repeat' : 0,
\ },
\ ],
\ 'python' : [
\ {
\ 'command' : "\",
\ 'pattern' : '\k\k$',
\ 'excluded' : '^$',
\ 'repeat' : 0,
\ },
\ {
\ 'command' : "\\",
\ 'pattern' : (has('win32') || has('win64') ? '\f[/\\]\f*$' : '\f[/]\f*$'),
\ 'excluded' : '[*/\\][/\\]\f*$\|[^[:print:]]\f*$',
\ 'repeat' : 1,
\ },
\ {
\ 'command' : "\\",
\ 'pattern' : '\k\.$',
\ 'excluded' : (has('python') ? '^$' : '.*'),
\ 'repeat' : 0,
\ },
\ ],
\ 'html' : [
\ {
\ 'command' : "\",
\ 'pattern' : '\k\k$',
\ 'excluded' : '^$',
\ 'repeat' : 0,
\ },
\ {
\ 'command' : "\\",
\ 'pattern' : (has('win32') || has('win64') ? '\f[/\\]\f*$' : '\f[/]\f*$'),
\ 'excluded' : '[*/\\][/\\]\f*$\|[^[:print:]]\f*$',
\ 'repeat' : 1,
\ },
\ {
\ 'command' : "\\",
\ 'pattern' : '\(<\k*\|<\/\k*\|<[^>]* \)$',
\ 'excluded' : '^$',
\ 'repeat' : 1,
\ },
\ ],
\ 'xhtml' : [
\ {
\ 'command' : "\",
\ 'pattern' : '\k\k$',
\ 'excluded' : '^$',
\ 'repeat' : 0,
\ },
\ {
\ 'command' : "\\",
\ 'pattern' : (has('win32') || has('win64') ? '\f[/\\]\f*$' : '\f[/]\f*$'),
\ 'excluded' : '[*/\\][/\\]\f*$\|[^[:print:]]\f*$',
\ 'repeat' : 1,
\ },
\ {
\ 'command' : "\\",
\ 'pattern' : '\(<\k*\|<\/\k*\|<[^>]* \)$',
\ 'excluded' : '^$',
\ 'repeat' : 1,
\ },
\ ],
\ 'css' : [
\ {
\ 'command' : "\",
\ 'pattern' : '\k\k$',
\ 'excluded' : '^$',
\ 'repeat' : 0,
\ },
\ {
\ 'command' : "\\",
\ 'pattern' : (has('win32') || has('win64') ? '\f[/\\]\f*$' : '\f[/]\f*$'),
\ 'excluded' : '[*/\\][/\\]\f*$\|[^[:print:]]\f*$',
\ 'repeat' : 1,
\ },
\ {
\ 'command' : "\\",
\ 'pattern' : '[:@!]\s*\k*$\|\(^\|[;{]\)\s\+\k\+$',
\ 'excluded' : '^$',
\ 'repeat' : 1,
\ },
\ ],
\ 'scheme' : [
\ {
\ 'command' : "\",
\ 'pattern' : '\k\k$',
\ 'excluded' : '^$',
\ 'repeat' : 0,
\ },
\ {
\ 'command' : "\",
\ 'pattern' : '(\k$',
\ 'excluded' : '^$',
\ 'repeat' : 0,
\ },
\ {
\ 'command' : "\\",
\ 'pattern' : (has('win32') || has('win64') ? '\f[/\\]\f*$' : '\f[/]\f*$'),
\ 'excluded' : '[*/\\][/\\]\f*$\|[^[:print:]]\f*$',
\ 'repeat' : 1,
\ },
\ ],
\ } ,'keep')
" INITIALIZATION: COMMANDS, AUTOCOMMANDS, MAPPINGS, ETC.: =============== {{{1
command! -bar -narg=0 AutoComplPopEnable call s:Enable()
command! -bar -narg=0 AutoComplPopDisable call s:Disable()
command! -bar -narg=0 AutoComplPopLock call s:PopupFeeder.lock()
command! -bar -narg=0 AutoComplPopUnlock call s:PopupFeeder.unlock()
inoremap AutocomplpopOnPopupPost GetPopupFeeder().on_popup_post()
if !g:AutoComplPop_NotEnableAtStartup
AutoComplPopEnable
endif
" }}}1
"=============================================================================
" vim: set fdm=marker: