"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " autocomplpop.vim - Automatically open the popup menu for completion. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " " Author: Takeshi Nishida " Version: 2.2, for Vim 7.1 " Licence: MIT Licence " URL: https://www.vim8.org/scripts/script.php?script_id=1879 " """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " 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 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) " 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 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " 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, \ }, \ ], \ '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, \ }, \ ], \ '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, \ }, \ ], \ } ,'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: