fix: Switch erlang to oscarh/vimerl (it doesnt use plugin dir)

This commit is contained in:
Adam Stankiewicz
2013-09-17 02:02:37 +02:00
parent 78cd7e48cb
commit 0fcd056648
9 changed files with 920 additions and 488 deletions

View File

@@ -1,219 +0,0 @@
" Vim omni completion file
" Language: Erlang
" Author: Oscar Hellström <oscar@oscarh.net>
" Contributors: kTT (http://github.com/kTT)
" Ricardo Catalinas Jiménez <jimenezrick@gmail.com>
" Eduardo Lopez (http://github.com/tapichu)
" Zhihui Jiao (http://github.com/onlychoice)
" License: Vim license
" Version: 2012/11/26
if !exists('g:erlang_completion_cache')
let g:erlang_completion_cache = 1
endif
" Completion program path
let s:erlang_complete_file = expand('<sfile>:p:h') . '/erlang_complete.erl'
" Modules cache used to speed up the completion
let s:modules_cache = {}
" File cache for persistence between Vim sessions
if filewritable(expand('<sfile>:p:h')) == 2
let s:file_cache = expand('<sfile>:p:h') . '/vimerl_cache'
else
let s:file_cache = '/tmp/vimerl_cache'
endif
" Patterns for completions
let s:erlang_local_func_beg = '\(\<[0-9A-Za-z_-]*\|\s*\)$'
let s:erlang_external_func_beg = '\<[0-9A-Za-z_-]\+:[0-9A-Za-z_-]*$'
let s:erlang_blank_line = '^\s*\(%.*\)\?$'
" Main function for completion
function erlang_complete#Complete(findstart, base)
let lnum = line('.')
let column = col('.')
let line = strpart(getline('.'), 0, column - 1)
" 1) Check if the char to the left of us are part of a function call
"
" Nothing interesting is written at the char just before the cursor
" This means _anything_ could be started here
" In this case, keyword completion should probably be used,
" for now we'll only try and complete local functions.
"
" TODO: Examine if we can stare Identifiers end complete on them
" Is this worth it? Is /completion/ of a "blank" wanted? Can we consider
" `(' interesting and check if we are in a function call etc.?
if line[column - 2] !~ '[0-9A-Za-z:_-]'
if a:findstart
return column
else
return s:ErlangFindLocalFunc(a:base)
endif
endif
" 2) Function in external module
if line =~ s:erlang_external_func_beg
let delimiter = match(line, ':[0-9A-Za-z_-]*$') + 1
if a:findstart
return delimiter
else
let module = matchstr(line[:-2], '\<\k*\>$')
return s:ErlangFindExternalFunc(module, a:base)
endif
endif
" 3) Local function
if line =~ s:erlang_local_func_beg
let funcstart = match(line, ':\@<![0-9A-Za-z_-]*$')
if a:findstart
return funcstart
else
return s:ErlangFindLocalFunc(a:base)
endif
endif
" 4) Unhandled situation
if a:findstart
return -1
else
return []
endif
endfunction
" Find the next non-blank line
function s:ErlangFindNextNonBlank(lnum)
let lnum = nextnonblank(a:lnum + 1)
let line = getline(lnum)
while line =~ s:erlang_blank_line && 0 != lnum
let lnum = nextnonblank(lnum + 1)
let line = getline(lnum)
endwhile
return lnum
endfunction
" Find external function names
function s:ErlangFindExternalFunc(module, base)
" If the module is cached, load its functions
if has_key(s:modules_cache, a:module)
for field_cache in get(s:modules_cache, a:module)
if match(field_cache.word, a:base) == 0
call complete_add(field_cache)
endif
endfor
return []
endif
let functions = system(s:erlang_complete_file . ' ' . a:module)
for function_spec in split(functions, '\n')
if match(function_spec, a:base) == 0
let function_name = matchstr(function_spec, a:base . '\w*')
let field = {'word': function_name . '(', 'abbr': function_spec,
\ 'kind': 'f', 'dup': 1}
call complete_add(field)
" Populate the cache only when iterating over all the
" module functions (i.e. no prefix for the completion)
if g:erlang_completion_cache && a:base == ''
if !has_key(s:modules_cache, a:module)
let s:modules_cache[a:module] = [field]
else
let fields_cache = get(s:modules_cache, a:module)
let s:modules_cache[a:module] = add(fields_cache, field)
endif
endif
" The user entered some text, so stop the completion
if complete_check()
" The module couldn't be entirely cached
if has_key(s:modules_cache, a:module)
call remove(s:modules_cache, a:module)
endif
break
endif
endif
endfor
call s:ErlangWriteCache(a:module)
return []
endfunction
" Find local function names
function s:ErlangFindLocalFunc(base)
" Begin at line 1
let lnum = s:ErlangFindNextNonBlank(1)
if "" == a:base
let base = '\w' " Used to match against word symbol
else
let base = a:base
endif
while 0 != lnum && !complete_check()
let line = getline(lnum)
let function_name = matchstr(line, '^' . base . '[0-9A-Za-z_-]\+(\@=')
if function_name != ""
call complete_add({'word': function_name, 'kind': 'f'})
endif
let lnum = s:ErlangFindNextNonBlank(lnum)
endwhile
return []
endfunction
function s:ErlangLoadCache()
if filereadable(s:file_cache)
for line in readfile(s:file_cache)
let cache_entry = eval(line)
" cache_entry is a dict with just one key with the
" module name and the function list we are going to
" add to the memory cache as the value of this key
for mod_name in keys(cache_entry)
let func_list = get(cache_entry, mod_name)
let s:modules_cache[mod_name] = func_list
endfor
endfor
endif
endfunction
function s:ErlangWriteCache(module)
" Write all the module functions to the cache file
if has_key(s:modules_cache, a:module)
let func_list = get(s:modules_cache, a:module)
if len(func_list) > 0
let cache_entry = {a:module : func_list}
execute 'redir >>' . s:file_cache
silent echon cache_entry
silent echon "\n"
redir END
endif
endif
endfunction
function s:ErlangPurgeCache(...)
for mod_name in a:000
if has_key(s:modules_cache, mod_name)
call remove(s:modules_cache, mod_name)
endif
endfor
" Delete the old cache file
call delete(s:file_cache)
" Write a new one
for mod_name in keys(s:modules_cache)
call s:ErlangWriteCache(mod_name)
endfor
endfunction
" Load the file cache when this script is autoloaded
call s:ErlangLoadCache()
" Command for removing modules from the cache
command -nargs=+ ErlangPurgeCache silent call s:ErlangPurgeCache(<f-args>)

161
autoload/erlangcomplete.vim Normal file
View File

@@ -0,0 +1,161 @@
" ------------------------------------------------------------------------------
" Vim omni-completion script
" Author: Oscar Hellström
" Email: oscar@oscarh.net
" Version: 2010-08-10
" Contributors: kTT (http://github.com/kTT)
" Ricardo Catalinas Jiménez <jimenezrick@gmail.com>
" ------------------------------------------------------------------------------
" Patterns for completions {{{1
let s:erlangLocalFuncBeg = '\(\<[0-9A-Za-z_-]*\|\s*\)$'
let s:erlangExternalFuncBeg = '\<[0-9A-Za-z_-]\+:[0-9A-Za-z_-]*$'
let s:ErlangBlankLine = '^\s*\(%.*\)\?$'
let s:erlangCompletionPath = expand('<sfile>:p:h') . '/erlang_completion.erl'
if !exists('g:erlangCompletionGrep')
let g:erlangCompletionGrep = 'grep'
endif
if !exists('g:erlangManSuffix')
let g:erlangManSuffix = ''
endif
if !exists('g:erlangManPath')
let g:erlangManPath = '/usr/lib/erlang/man'
endif
if !exists('g:erlangCompletionDisplayDoc')
let g:erlangCompletionDisplayDoc = 1
endif
" Main function for completion {{{1
function! erlangcomplete#Complete(findstart, base)
" 0) Init {{{2
let lnum = line('.')
let column = col('.')
let line = strpart(getline('.'), 0, column - 1)
" 1) First, check if completion is impossible {{{2
if line =~ '[^~\\]%'
return -1
endif
"echo "line[col - 1]:" . line[column - 1] . " line[col - 2]:" . line[column - 2] . "\n" . line . "\n"
" 2) Check if the char to the left of us are part of a function call {{{2
"
" Nothing interesting is written at the char just before the cursor
" This means _anything_ could be started here
" In this case, keyword completion should probably be used,
" for now we'll only try and complete local functions.
" TODO: Examine if we can stare Identifiers end complete on them
" Is this worth it? Is /completion/ of a "blank" wanted? Can we consider (
" interesting and check if we are in a function call etc.?
if line[column - 2] !~ '[0-9A-Za-z:_-]'
if a:findstart
return column
else
return s:erlangFindLocalFunc(a:base)
endif
endif
" 3) Function in external module {{{2
if line =~ s:erlangExternalFuncBeg
let delimiter = match(line, ':[0-9A-Za-z_-]*$') + 1
if a:findstart
return delimiter
else
let module = matchstr(line[:-2], '\<\k*\>$')
return s:erlangFindExternalFunc(module, a:base)
endif
endif
" 4) Local function {{{2
if line =~ s:erlangLocalFuncBeg
let funcstart = match(line, ':\@<![0-9A-Za-z_-]*$')
if a:findstart
return funcstart
else
return s:erlangFindLocalFunc(a:base)
endif
endif
" 5) Unhandled situation {{{2
if a:findstart
return -1
else
return []
endif
endfunction
" Auxiliary functions for completion {{{1
" Find the next non-blank line {{{2
function s:erlangFindNextNonBlank(lnum)
let lnum = nextnonblank(a:lnum + 1)
let line = getline(lnum)
while line =~ s:ErlangBlankLine && 0 != lnum
let lnum = nextnonblank(lnum + 1)
let line = getline(lnum)
endwhile
return lnum
endfunction
" vim: foldmethod=marker:
" Find external function names {{{2
function s:erlangFindExternalFunc(module, base)
" If it's a local module, try to compile it
if filereadable(a:module . '.erl') && !filereadable(a:module . '.beam')
silent execute '!erlc' a:module . '.erl' '>/dev/null' '2>/dev/null'
redraw!
endif
let functions = system(s:erlangCompletionPath . ' ' . a:module)
for element in sort(split(functions, '\n'))
if match(element, a:base) == 0
let function_name = matchstr(element, a:base . '\w\+')
let number_of_args = matchstr(element, '\d\+', len(function_name))
let number_of_comma = max([number_of_args - 1, 0])
let file_path = g:erlangManPath . '/man?/' . a:module . '\.?' . g:erlangManSuffix
" [:-2] cutting some weird characters at the end
" becouse grep doesn't support multilines, we have to filter
" first by .B and next by looking via function name
" if someone have better idea, please change it
let description = ''
" Don't look man pages if the module is present in the current directory
if g:erlangCompletionDisplayDoc != 0 && !filereadable(a:module . '.erl')
let system_command = g:erlangCompletionGrep . ' -A 1 "\.B" ' . file_path . ' | grep -EZo "\<' .
\ function_name . '\>\((\w+, ){' . number_of_comma . '}[^),]*\) -> .*"'
let description = system(system_command)
let description = description[:-2]
endif
if description == ''
let description = element " if function doesn't have description e.g. lists:rmerge, put rmerge/2 instead
endif
let field = {'word': function_name . '(', 'abbr': description, 'kind': 'f', 'dup': 1} " always duplicate functions
call complete_add(field)
endif
endfor
return []
endfunction
" Find local function names {{{2
function s:erlangFindLocalFunc(base)
" begin at line 1
let lnum = s:erlangFindNextNonBlank(1)
if "" == a:base
let base = '\w' " used to match against word symbol
else
let base = a:base
endif
while 0 != lnum && !complete_check()
let line = getline(lnum)
let function_name = matchstr(line, '^' . base . '[0-9A-Za-z_-]\+(\@=')
if function_name != ""
call complete_add(function_name)
endif
let lnum = s:erlangFindNextNonBlank(lnum)
endwhile
return []
endfunction