Skip to content

Instantly share code, notes, and snippets.

Created December 19, 2008 03:11
Show Gist options
  • Save anonymous/37858 to your computer and use it in GitHub Desktop.
Save anonymous/37858 to your computer and use it in GitHub Desktop.
" FILE: altautocomplpop.vim
" AUTHOR: Shougo Matsushita <Shougo.Matsu@gmail.com>
" Last Modified: 19 Dec 2008
" Usage: Just source this file.
" LICENSE: No Warranties. Use at your own risk. Add stuff to taste.
" If you like this script type :help uganda<Enter>
" If you want to show appreciation to the author, please
" visit the UDAVUM KARANGAL website http://www.udavumkarangal.org/
" NOTES: Written to work with vim-7.0
if exists('g:loaded_altautocomplpop') || v:version < 700
finish
endif
let g:loaded_altautocomplpop = 1
let s:disable_altautocomplpop = 1
let s:AltAutoComplPop = {}
command! -nargs=0 AltAutoComplPopEnable call s:AltAutoComplPop.Enable()
command! -nargs=0 AltAutoComplPopDisable call s:AltAutoComplPop.Disable()
command! -nargs=0 AltAutoComplPopToggle call s:AltAutoComplPop.Toggle()
function! s:AltAutoComplPop.Complete()
if pumvisible() || &paste
return
endif
" Prevent multiplex call
if s:complete_lock
return
endif
" Get cursor word
let l:cur = col('.') - 1
let l:cur_text = strpart(getline('.'), 0, l:cur)
" Prevent infinity loop
if l:cur_text == s:old_text
return
endif
let s:old_text = l:cur_text
" Not complete multi byte character
if char2nr(l:cur_text[l:cur-1]) >= 0x80
return
endif
let l:pattern = '\k\{'. g:AltAutoComplPop_StartCharLength .',}$'
let l:cur_keyword_pos = match(l:cur_text, l:pattern)
if l:cur_keyword_pos < 0
return
endif
" Save options
let s:ignorecase_save = &l:ignorecase
" Extract complete words
let &l:ignorecase = g:AltAutoComplPop_IgnoreCase
let l:cur_keyword_str = matchstr(l:cur_text, l:pattern)
let s:complete_words = s:AltAutoComplPop.ExtractComplete(l:cur_keyword_str)
" Prevent filcker
if empty(s:complete_words)
return
endif
" Lock
let s:complete_lock = 1
" Original complete
let &completefunc = 'g:AltAutoComplPop_AutoCompleteFunc'
let s:cur_keyword_pos = l:cur_keyword_pos
call feedkeys("\<C-x>\<C-u>\<C-p>", 'n')
endfunction
function! g:AltAutoComplPop_AutoCompleteFunc(findstart, base)
if a:findstart
return s:cur_keyword_pos
endif
" Prevent multiplex call
if !s:complete_lock
return []
endif
" Restore options
let &completefunc = 'g:AltAutoComplPop_ManualCompleteFunc'
let &l:ignorecase = s:ignorecase_save
" Unlock
let s:complete_lock = 0
return s:complete_words
endfunction
function! g:AltAutoComplPop_ManualCompleteFunc(findstart, base)
if a:findstart
" Get cursor word
let l:cur = col('.') - 1
let l:cur_text = strpart(getline('.'), 0, l:cur)
" Prevent infinity loop
if l:cur_text == s:old_text
return
endif
let s:old_text = l:cur_text
" Not complete multi byte character
if char2nr(l:cur_text[l:cur-1]) >= 0x80
return -1
endif
let l:cur_keyword_pos = match(l:cur_text, '\k\+$')
return l:cur_keyword_pos
endif
" Save options
let l:ignorecase_save = &l:ignorecase
let &l:ignorecase = g:AltAutoComplPop_IgnoreCase
let l:complete_words = s:AltAutoComplPop.ExtractComplete(a:base)
" Restore options
let &l:ignorecase = l:ignorecase_save
return l:complete_words
endfunction
function! s:CompareRank(i1, i2)
return a:i1.rank == a:i2.rank ? 0 : a:i1.rank < a:i2.rank ? 1 : -1
endfunction
function! s:CompareWords(i1, i2)
return a:i1.word == a:i2.word ? 0 : a:i1.word > a:i2.word ? 1 : -1
endfunction
function! s:AltAutoComplPop.ExtractComplete(cur_keyword_str)
" Keyword filter
if g:AltAutoComplPop_PartialMatch
" Partial match
let l:pattern = 'v:val.word =~ "' . a:cur_keyword_str . '"'
else
" Normal match
let l:pattern = 'v:val.word =~ "^' . a:cur_keyword_str . '"'
endif
let l:current_buf = bufnr('%')
let l:cache_keyword_filtered = filter(values(s:cache_keyword_buffer[l:current_buf]), l:pattern)
let l:cache_keyword_buffer_filtered = []
for key in keys(s:cache_keyword_buffer)
if key != l:current_buf
call extend(l:cache_keyword_buffer_filtered, filter(values(s:cache_keyword_buffer[key]), l:pattern))
endif
endfor
if !g:AltAutoComplPop_FirstCurrentBufferWords
" Append lists
call extend(l:cache_keyword_buffer_filtered, l:cache_keyword_filtered)
let l:cache_keyword_filtered = []
endif
" Sort
if g:AltAutoComplPop_AlphabeticalOrder
" AlphabeticalOrder
let l:cache_keyword_sorted = sort(l:cache_keyword_filtered, 's:CompareWords')
let l:cache_keyword_buffer_sorted = sort(l:cache_keyword_buffer_filtered, 's:CompareWords')
else
" RankOrder
let l:cache_keyword_sorted = sort(l:cache_keyword_filtered, 's:CompareRank')
let l:cache_keyword_buffer_sorted = sort(l:cache_keyword_buffer_filtered, 's:CompareRank')
endif
" Append lists
let l:ret = extend(l:cache_keyword_sorted, l:cache_keyword_buffer_sorted)
" Trunk too many item
return l:ret[:g:AltAutoComplPop_MaxList-1]
endfunction
function! s:AltAutoComplPop.Caching(bufnumber)
let l:cache_keyword = {}
let l:buflines = getbufline(a:bufnumber, 1, '$')
let l:max_line = len(l:buflines)
let l:line_num = 0
if g:AltAutoComplPop_DrawWordsRank
let l:menu_pattern = '%.' . g:AltAutoComplPop_MaxFilenameWidth . 's %d '
else
let l:menu_pattern = '%.' . g:AltAutoComplPop_MaxFilenameWidth . 's '
endif
let l:abbr_pattern = '%.' . g:AltAutoComplPop_MaxKeywordWidth . 's'
while l:line_num < l:max_line
let l:line = buflines[l:line_num]
let l:match_num = 0
let l:match_str = matchstr(l:line, '\k\+')
while !empty(match_str)
let l:match_num += len(l:match_str)
" Check dup
if has_key(l:cache_keyword, l:match_str)
let l:cache_keyword[l:match_str].rank += 1
if g:AltAutoComplPop_DrawWordsRank
let l:cache_keyword[l:match_str].menu = printf(l:menu_pattern, fnamemodify(bufname(a:bufnumber), ':t'), l:cache_keyword[l:match_str].rank)
endif
else
if g:AltAutoComplPop_DrawWordsRank
let l:menu = printf(l:menu_pattern, fnamemodify(bufname(a:bufnumber), ':t'), 1)
else
let l:menu = printf(l:menu_pattern, fnamemodify(bufname(a:bufnumber), ':t'))
endif
" Append list
let l:cache_keyword[l:match_str] = {'word' : l:match_str, 'abbr' : printf(l:abbr_pattern, l:match_str), 'menu' : l:menu, 'rank' : 1, 'dup' : 0}
endif
" Next match
let l:match_str = matchstr(l:line, '\k\+', l:match_num)
endwhile
let l:line_num += 1
endwhile
return l:cache_keyword
endfunction
function! s:AltAutoComplPop.CachingCurrentBuffer()
let l:current_buf = bufnr('%')
let s:cache_keyword_buffer[l:current_buf] = s:AltAutoComplPop.Caching(bufnr('%'))
endfunction
function! s:AltAutoComplPop.CachingBuffer()
let l:bufnumber = 1
let l:max_buf = bufnr('$')
" Check new buffer
while l:bufnumber <= l:max_buf
if bufloaded(l:bufnumber) && !has_key(s:cache_keyword_buffer, l:bufnumber)
let s:cache_keyword_buffer[l:bufnumber] = s:AltAutoComplPop.Caching(l:bufnumber)
endif
let l:bufnumber += 1
endwhile
" Check deleted buffer
for key in keys(s:cache_keyword_buffer)
if !bufloaded(str2nr(key))
" Remove item
call remove(s:cache_keyword_buffer, key)
endif
endfor
endfunction
function! s:AltAutoComplPop.Enable()
augroup AltAutoComplPop
autocmd!
autocmd BufWinEnter * call s:AltAutoComplPop.CachingBuffer()
autocmd BufWritePost * call s:AltAutoComplPop.CachingCurrentBuffer()
"autocmd InsertEnter * call s:AltAutoComplPop.CachingCurrentBuffer()
autocmd CursorMovedI * call s:AltAutoComplPop.Complete()
augroup END
" Initialize
let s:complete_lock = 0
let s:old_text = ''
let s:cache_keyword_buffer = {}
" Save options
let s:completefunc_save = &completefunc
" Set completefunc
let &completefunc = 'g:AltAutoComplPop_ManualCompleteFunc'
" Initialize cache
call s:AltAutoComplPop.CachingBuffer()
endfunction
function! s:AltAutoComplPop.Disable()
" Restore options
let &completefunc = s:completefunc_save
augroup AltAutoComplPop
autocmd!
augroup END
endfunction
function! s:AltAutoComplPop.Toggle()
if s:disable_altautocomplpop
let s:disable_altautocomplpop = 0
call s:AltAutoComplPop.Enable()
else
let s:disable_altautocomplpop = 1
call s:AltAutoComplPop.Disable()
endif
endfunction
" Global variable definition
if !exists('g:AltAutoComplPop_MaxList')
let g:AltAutoComplPop_MaxList = 150
endif
if !exists('g:AltAutoComplPop_MaxKeywordWidth')
let g:AltAutoComplPop_MaxKeywordWidth = 50
endif
if !exists('g:AltAutoComplPop_MaxFilenameWidth')
let g:AltAutoComplPop_MaxFilenameWidth = 20
endif
if !exists('g:AltAutoComplPop_PartialMatch')
let g:AltAutoComplPop_PartialMatch = 1
endif
if !exists('g:AltAutoComplPop_StartCharLength')
let g:AltAutoComplPop_StartCharLength = 2
endif
if !exists('g:AltAutoComplPop_IgnoreCase')
let g:AltAutoComplPop_IgnoreCase = 1
endif
if exists('g:AltAutoComplPop_EnableAtStartup') && g:AltAutoComplPop_EnableAtStartup
" Enable startup
call s:AltAutoComplPop.Enable()
endif
if !exists('g:AltAutoComplPop_DrawWordsRank')
let g:AltAutoComplPop_DrawWordsRank = 1
endif
if !exists('g:AltAutoComplPop_AlphabeticalOrder')
let g:AltAutoComplPop_AlphabeticalOrder = 0
endif
if !exists('g:AltAutoComplPop_FirstCurrentBufferWords')
let g:AltAutoComplPop_FirstCurrentBufferWords = 1
endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment