Created
December 19, 2008 03:11
-
-
Save anonymous/37858 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" 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