diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | autoload/erlang_complete.vim | 219 | ||||
-rw-r--r-- | autoload/erlangcomplete.vim | 161 | ||||
-rwxr-xr-x | build | 2 | ||||
-rw-r--r-- | compiler/erlang.vim | 153 | ||||
-rw-r--r-- | ftplugin/erlang.vim | 200 | ||||
-rw-r--r-- | ftplugin/erlang_refactor.vim | 295 | ||||
-rw-r--r-- | indent/erlang.vim | 235 | ||||
-rw-r--r-- | syntax/erlang.vim | 163 |
9 files changed, 931 insertions, 499 deletions
@@ -35,7 +35,7 @@ Optionally download one of the [releases](https://github.com/sheerun/vim-polyglo - [csv](https://github.com/chrisbra/csv.vim) (syntax, ftplugin, ftdetect) - [cucumber](https://github.com/tpope/vim-cucumber) (syntax, indent, compiler, ftplugin, ftdetect) - [elixir](https://github.com/elixir-lang/vim-elixir) (syntax, indent, compiler, ftplugin, ftdetect) -- [erlang](https://github.com/jimenezrick/vimerl) (syntax, indent, compiler, autoload, ftplugin) +- [erlang](https://github.com/oscarh/vimerl) (syntax, indent, compiler, autoload, ftplugin) - [git](https://github.com/tpope/vim-git) (syntax, indent, ftplugin, ftdetect) - [go](https://github.com/jnwhiteh/vim-golang) (syntax, indent, autoload, ftplugin, ftdetect) - [haml](https://github.com/tpope/vim-haml) (syntax, indent, compiler, ftplugin, ftdetect) diff --git a/autoload/erlang_complete.vim b/autoload/erlang_complete.vim deleted file mode 100644 index 9d108fbc..00000000 --- a/autoload/erlang_complete.vim +++ /dev/null @@ -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>) diff --git a/autoload/erlangcomplete.vim b/autoload/erlangcomplete.vim new file mode 100644 index 00000000..3e4208e8 --- /dev/null +++ b/autoload/erlangcomplete.vim @@ -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 + @@ -75,7 +75,7 @@ PACKS=" csv:chrisbra/csv.vim cucumber:tpope/vim-cucumber elixir:elixir-lang/vim-elixir - erlang:jimenezrick/vimerl + erlang:oscarh/vimerl git:tpope/vim-git go:jnwhiteh/vim-golang haml:tpope/vim-haml diff --git a/compiler/erlang.vim b/compiler/erlang.vim index da88b856..6ab7526f 100644 --- a/compiler/erlang.vim +++ b/compiler/erlang.vim @@ -1,111 +1,80 @@ -" Vim compiler file -" Language: Erlang -" Author: Pawel 'kTT' Salata <rockplayer.pl@gmail.com> -" Contributors: Ricardo Catalinas Jiménez <jimenezrick@gmail.com> -" License: Vim license -" Version: 2013/03/06 +" Erlang compiler file +" Language: Erlang +" Maintainer: Pawel 'kTT' Salata <rockplayer.pl@gmail.com> +" URL: http://ktototaki.info -if exists("current_compiler") || v:version < 703 - finish -else - let current_compiler = "erlang" +if exists("current_compiler") + finish endif - -let b:error_list = {} -let b:is_showing_msg = 0 -let b:next_sign_id = 1 +let current_compiler = "erlang" if exists(":CompilerSet") != 2 - command -nargs=* CompilerSet setlocal <args> + command -nargs=* CompilerSet setlocal <args> endif -CompilerSet makeprg=make -CompilerSet errorformat=%f:%l:\ %tarning:\ %m,%f:%l:\ %m - -" Only define functions and script scope variables once -if exists("*s:ShowErrors") - finish +if !exists('g:erlangCheckFile') + let g:erlangCheckFile = "~/.vim/compiler/erlang_check_file.erl" endif -if !exists("g:erlang_show_errors") - let g:erlang_show_errors = 1 +if !exists('g:erlangHighlightErrors') + let g:erlangHighlightErrors = 0 endif -let s:erlang_check_file = expand("<sfile>:p:h") . "/erlang_check.erl" -let s:autocmds_defined = 0 - -sign define ErlangError text=>> texthl=Error -sign define ErlangWarning text=>> texthl=Todo - -command ErlangDisableShowErrors silent call s:DisableShowErrors() -command ErlangEnableShowErrors silent call s:EnableShowErrors() +let b:error_list = {} +let b:is_showing_msg = 0 -function s:ShowErrors() - setlocal shellpipe=> - if match(getline(1), "#!.*escript") != -1 - setlocal makeprg=escript\ -s\ % - else - execute "setlocal makeprg=" . s:erlang_check_file . "\\ \%" - endif - silent make! - for error in getqflist() - let item = {} - let item["lnum"] = error.lnum - let item["text"] = error.text - let b:error_list[error.lnum] = item - let type = error.type == "W" ? "ErlangWarning" : "ErlangError" - execute "sign place" b:next_sign_id "line=" . item.lnum "name=" . type "file=" . expand("%:p") - let b:next_sign_id += 1 - endfor - setlocal shellpipe& - setlocal makeprg=make +function! HighlightErlangErrors() + if match(getline(1), "#!.*escript") != -1 + setlocal makeprg=escript\ -s\ % + else + execute "setlocal makeprg=" . g:erlangCheckFile . "\\ \%" + endif + silent make! + call s:clear_matches() + for error in getqflist() + let item = {} + let item['lnum'] = error.lnum + let item['msg'] = error.text + let b:error_list[error.lnum] = item + call matchadd('SpellBad', "\\%" . error.lnum . "l") + endfor + if len(getqflist()) + redraw! + endif + call s:show_msg() + setlocal makeprg=erlc\ % endfunction -function s:ShowErrorMsg() - let pos = getpos(".") - if has_key(b:error_list, pos[1]) - let item = get(b:error_list, pos[1]) - echo item.text - let b:is_showing_msg = 1 - else - if b:is_showing_msg - echo - let b:is_showing_msg = 0 - endif - endif +function! s:show_msg() + let pos = getpos(".") + if has_key(b:error_list, pos[1]) + let item = get(b:error_list, pos[1]) + echo item.msg + let b:is_showing_msg = 1 + else + if exists("b:is_showing_msg") && b:is_showing_msg == 1 + echo + let b:is_showing_msg = 0 + endif + endif endf -function s:ClearErrors() - sign unplace * - let b:error_list = {} - let b:next_sign_id = 1 - if b:is_showing_msg - echo - let b:is_showing_msg = 0 - endif -endfunction - -function s:EnableShowErrors() - if !s:autocmds_defined - augroup vimerl - autocmd! - autocmd BufWritePre *.erl call s:ClearErrors() - autocmd BufWritePost *.erl call s:ShowErrors() - autocmd CursorHold *.erl call s:ShowErrorMsg() - autocmd CursorMoved *.erl call s:ShowErrorMsg() - augroup END - let s:autocmds_defined = 1 - endif +function! s:clear_matches() + call clearmatches() + let b:error_list = {} + if exists("b:is_showing_msg") && b:is_showing_msg == 1 + echo + let b:is_showing_msg = 0 + endif endfunction -function s:DisableShowErrors() - sign unplace * - augroup vimerl - autocmd! - augroup END - let s:autocmds_defined = 0 -endfunction +CompilerSet makeprg=erlc\ % +CompilerSet errorformat=%f:%l:\ %tarning:\ %m,%E%f:%l:\ %m -if g:erlang_show_errors - call s:EnableShowErrors() +if g:erlangHighlightErrors + autocmd BufLeave *.erl call s:clear_matches() + autocmd BufEnter *.erl call s:clear_matches() + autocmd BufWritePost *.erl call HighlightErlangErrors() + autocmd CursorHold *.erl call s:show_msg() + autocmd CursorMoved *.erl call s:show_msg() endif diff --git a/ftplugin/erlang.vim b/ftplugin/erlang.vim index 49b64ebb..f75f47ae 100644 --- a/ftplugin/erlang.vim +++ b/ftplugin/erlang.vim @@ -1,85 +1,151 @@ " Vim ftplugin file -" Language: Erlang -" Author: Oscar Hellström <oscar@oscarh.net> -" Contributors: Ricardo Catalinas Jiménez <jimenezrick@gmail.com> -" Eduardo Lopez (http://github.com/tapichu) -" License: Vim license -" Version: 2012/11/25 - -if exists('b:did_ftplugin') +" Language: Erlang +" Maintainer: Oscar Hellström <oscar@oscarh.net> +" URL: http://personal.oscarh.net +" Contributor: Ricardo Catalinas Jiménez <jimenezrick@gmail.com> +" Version: 2010-09-03 +" ------------------------------------------------------------------------------ +" Usage: +" +" To enable folding put in your vimrc: +" set foldenable +" +" Folding will make only one fold for a complete function, even though it has +" more than one function head and body. +" +" To change this behaviour put in your vimrc file: +" let g:erlangFoldSplitFunction=1 +" +" ------------------------------------------------------------------------------ +" Plugin init +if exists("b:did_ftplugin") finish -else - let b:did_ftplugin = 1 endif -if exists('s:did_function_definitions') +" Don't load any other +let b:did_ftplugin=1 + +if exists('s:doneFunctionDefinitions') call s:SetErlangOptions() finish -else - let s:did_function_definitions = 1 -endif - -if !exists('g:erlang_keywordprg') - let g:erlang_keywordprg = 'erl -man' -endif - -if !exists('g:erlang_folding') - let g:erlang_folding = 0 endif -let s:erlang_fun_begin = '^\(\a\w*\|[''][^'']*['']\)(.*$' -let s:erlang_fun_end = '^[^%]*\.\s*\(%.*\)\?$' +let s:doneFunctionDefinitions=1 +" Local settings function s:SetErlangOptions() compiler erlang if version >= 700 - setlocal omnifunc=erlang_complete#Complete - endif - - if g:erlang_folding - setlocal foldmethod=expr - setlocal foldexpr=GetErlangFold(v:lnum) - setlocal foldtext=ErlangFoldText() - endif - - setlocal comments=:%%%,:%%,:% - setlocal commentstring=%%s - setlocal formatoptions+=ro - setlocal suffixesadd=.erl - let libs = substitute(system('which erl'), '/bin/erl', '/lib/erlang/lib/**/src/', '') - execute 'setlocal path+=' . libs - let &l:keywordprg = g:erlang_keywordprg -endfunction - -function GetErlangFold(lnum) - let lnum = a:lnum - let line = getline(lnum) - - if line =~ s:erlang_fun_end - return '<1' - endif - - if line =~ s:erlang_fun_begin && foldlevel(lnum - 1) == 1 - return '1' - endif - - if line =~ s:erlang_fun_begin - return '>1' + setlocal omnifunc=erlangcomplete#Complete endif - return '=' + setlocal foldmethod=expr + setlocal foldexpr=GetErlangFold(v:lnum) + setlocal foldtext=ErlangFoldText() endfunction -function ErlangFoldText() - let line = getline(v:foldstart) - let foldlen = v:foldend - v:foldstart + 1 - let lines = ' ' . foldlen . ' lines: ' . substitute(line, "[ \t]*", '', '') - if foldlen < 10 - let lines = ' ' . lines - endif - let retval = '+' . v:folddashes . lines - - return retval -endfunction +" Define folding functions +if !exists("*GetErlangFold") + " Folding params + let s:ErlangFunBegin = '^\a\w*(.*$' + let s:ErlangFunEnd = '^[^%]*\.\s*\(%.*\)\?$' + let s:ErlangBlankLine = '^\s*\(%.*\)\?$' + + " Auxiliary fold functions + function s:GetNextNonBlank(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 + + function s:GetFunName(str) + return matchstr(a:str, '^\a\w*(\@=') + endfunction + + function s:GetFunArgs(str, lnum) + let str = a:str + let lnum = a:lnum + while str !~ '->\s*\(%.*\)\?$' + let lnum = s:GetNextNonBlank(lnum) + if 0 == lnum " EOF + return "" + endif + let str .= getline(lnum) + endwhile + return matchstr(str, + \ '\(^(\s*\)\@<=.*\(\s*)\(\s\+when\s\+.*\)\?\s\+->\s*\(%.*\)\?$\)\@=') + endfunction + + function s:CountFunArgs(arguments) + let pos = 0 + let ac = 0 " arg count + let arguments = a:arguments + + " Change list / tuples into just one A(rgument) + let erlangTuple = '{\([A-Za-z_,|=\-\[\]]\|\s\)*}' + let erlangList = '\[\([A-Za-z_,|=\-{}]\|\s\)*\]' + + " FIXME: Use searchpair? + while arguments =~ erlangTuple + let arguments = substitute(arguments, erlangTuple, "A", "g") + endwhile + " FIXME: Use searchpair? + while arguments =~ erlangList + let arguments = substitute(arguments, erlangList, "A", "g") + endwhile + + let len = strlen(arguments) + while pos < len && pos > -1 + let ac += 1 + let pos = matchend(arguments, ',\s*', pos) + endwhile + return ac + endfunction + + " Main fold function + function GetErlangFold(lnum) + let lnum = a:lnum + let line = getline(lnum) + + if line =~ s:ErlangFunEnd + return '<1' + endif + + if line =~ s:ErlangFunBegin && foldlevel(lnum - 1) == 1 + if exists("g:erlangFoldSplitFunction") && g:erlangFoldSplitFunction + return '>1' + else + return '1' + endif + endif + + if line =~ s:ErlangFunBegin + return '>1' + endif + + return '=' + endfunction + + " Erlang fold description (foldtext function) + function ErlangFoldText() + let foldlen = v:foldend - v:foldstart + if 1 < foldlen + let lines = "lines" + else + let lines = "line" + endif + let line = getline(v:foldstart) + let name = s:GetFunName(line) + let arguments = s:GetFunArgs(strpart(line, strlen(name)), v:foldstart) + let argcount = s:CountFunArgs(arguments) + let retval = "+" . v:folddashes . " " . name . "/" . argcount + let retval .= " (" . foldlen . " " . lines . ")" + return retval + endfunction +endif call s:SetErlangOptions() diff --git a/ftplugin/erlang_refactor.vim b/ftplugin/erlang_refactor.vim new file mode 100644 index 00000000..f809db9b --- /dev/null +++ b/ftplugin/erlang_refactor.vim @@ -0,0 +1,295 @@ +" Erlang refactor file +" Language: Erlang +" Maintainer: Pawel 'kTT' Salata <rockplayer.pl@gmail.com> +" URL: http://ktototaki.info + +if exists("b:did_ftplugin_erlang") + finish +endif + +" Don't load any other +let b:did_ftplugin_erlang=1 + +if !exists('g:erlangRefactoring') || g:erlangRefactoring == 0 + finish +endif + +if !exists('g:erlangWranglerPath') + let g:erlangWranglerPath = '/usr/share/wrangler/' +endif + +if glob(g:erlangWranglerPath) == "" + call confirm("Wrong path to wrangler dir") + finish +endif + +autocmd VimLeavePre * call StopWranglerServer() + +let s:erlangServerName = "wrangler_vim" + +" Starting background erlang session with wrangler on +function! StartWranglerServer() + let wranglerEbinDir = g:erlangWranglerPath . "/ebin" + let command = "erl_call -s -sname " . s:erlangServerName . " -x 'erl -pa " . wranglerEbinDir . "'" + call system(command) + call s:send_rpc('application', 'start', '[wrangler_app]') +endfunction + +" Stopping erlang session +function! StopWranglerServer() + echo s:send_rpc('erlang', 'halt', '') +endfunction + +" Sending rpc call to erlang session +function! s:send_rpc(module, fun, args) + let command = "erl_call -sname " . s:erlangServerName . " -a '" . a:module . " " . a:fun . " " . a:args . "'" + let result = system(command) + if match(result, 'erl_call: failed to connect to node .*') != -1 + call StartWranglerServer() + return system(command) + endif + return result +endfunction + +function! ErlangUndo() + echo s:send_rpc("wrangler_undo_server", "undo", "[]") + :e! +endfunction + +function! s:trim(text) + return substitute(a:text, "^\\s\\+\\|\\s\\+$", "", "g") +endfunction + +function! s:get_msg(result, tuple_start) + let msg_begin = '{' . a:tuple_start . ',' + let matching_start = match(a:result, msg_begin) + if matching_start != -1 + return s:trim(matchstr(a:result, '[^}]*', matching_start + strlen(msg_begin))) + endif + return "" +endfunction + +" Check if there is an error in result +function! s:check_for_error(result) + let msg = s:get_msg(a:result, 'ok') + if msg != "" + return [0, msg] + endif + let msg = s:get_msg(a:result, 'warning') + if msg != "" + return [1, msg] + endif + let msg = s:get_msg(a:result, 'error') + if msg != "" + return [2, msg] + endif + return [-1, ""] +endfunction + +" Sending apply changes to file +function! s:send_confirm() + let choice = confirm("What do you want?", "&Preview\n&Confirm\nCa&ncel", 0) + if choice == 1 + echo "TODO: Display preview :)" + elseif choice == 2 + let module = 'wrangler_preview_server' + let fun = 'commit' + let args = '[]' + return s:send_rpc(module, fun, args) + else + let module = 'wrangler_preview_server' + let fun = 'abort' + let args = '[]' + return s:send_rpc(module, fun, args) + echo "Canceled" + endif +endfunction + +" Manually send confirm, for testing purpose only +function! SendConfirm() + echo s:send_confirm() +endfunction + +" Format and send function extracton call +function! s:call_extract(start_line, start_col, end_line, end_col, name) + let file = expand("%:p") + let module = 'wrangler' + let fun = 'fun_extraction' + let args = '["' . file . '", {' . a:start_line . ', ' . a:start_col . '}, {' . a:end_line . ', ' . a:end_col . '}, "' . a:name . '", ' . &sw . ']' + let result = s:send_rpc(module, fun, args) + let [error_code, msg] = s:check_for_error(result) + if error_code != 0 + call confirm(msg) + return 0 + endif + echo "This files will be changed: " . matchstr(msg, "[^]]*", 1) + echo s:send_confirm() + return 1 +endfunction + +function! ErlangExtractFunction(mode) range + silent w! + let name = inputdialog("New function name: ") + if name != "" + if a:mode == "v" + let start_pos = getpos("'<") + let start_line = start_pos[1] + let start_col = start_pos[2] + + let end_pos = getpos("'>") + let end_line = end_pos[1] + let end_col = end_pos[2] + elseif a:mode == "n" + let pos = getpos(".") + let start_line = pos[1] + let start_col = pos[2] + let end_line = pos[1] + let end_col = pos[2] + else + echo "Mode not supported." + return + endif + if s:call_extract(start_line, start_col, end_line, end_col, name) + let temp = &autoread + set autoread + :e + if temp == 0 + set noautoread + endif + endif + else + echo "Empty function name. Ignoring." + endif +endfunction +nmap <A-r>e :call ErlangExtractFunction("n")<ENTER> +vmap <A-r>e :call ErlangExtractFunction("v")<ENTER> + +function! s:call_rename(mode, line, col, name, search_path) + let file = expand("%:p") + let module = 'wrangler' + let fun = 'rename_' . a:mode + let args = '["' . file .'", ' + if a:mode != "mod" + let args = args . a:line . ', ' . a:col . ', ' + endif + let args = args . '"' . a:name . '", ["' . a:search_path . '"], ' . &sw . ']' + let result = s:send_rpc(module, fun, args) + let [error_code, msg] = s:check_for_error(result) + if error_code != 0 + call confirm(msg) + return 0 + endif + echo "This files will be changed: " . matchstr(msg, "[^]]*", 1) + echo s:send_confirm() + return 1 +endfunction + +function! ErlangRename(mode) + silent w! + if a:mode == "mod" + let name = inputdialog('Rename module to: ') + else + let name = inputdialog('Rename "' . expand("<cword>") . '" to: ') + endif + if name != "" + let search_path = expand("%:p:h") + "let search_path = inputdialog('Search path: ', expand("%:p:h")) + let pos = getpos(".") + let line = pos[1] + let col = pos[2] + let current_filename = expand("%") + let current_filepath = expand("%:p") + let new_filename = name . '.erl' + if s:call_rename(a:mode, line, col, name, search_path) + if a:mode == "mod" + execute ':bd ' . current_filename + execute ':e ' . new_filename + silent execute '!mv ' . current_filepath . ' ' . current_filepath . '.bak' + redraw! + else + let temp = &autoread + set autoread + :e + if temp == 0 + set noautoread + endif + endif + endif + else + echo "Empty name. Ignoring." + endif +endfunction + +function! ErlangRenameFunction() + call ErlangRename("fun") +endfunction +map <A-r>f :call ErlangRenameFunction()<ENTER> + +function! ErlangRenameVariable() + call ErlangRename("var") +endfunction +map <A-r>v :call ErlangRenameVariable()<ENTER> + +function! ErlangRenameModule() + call ErlangRename("mod") +endfunction +map <A-r>m :call ErlangRenameModule()<ENTER> + +function! ErlangRenameProcess() + call ErlangRename("process") +endfunction +map <A-r>p :call ErlangRenameProcess()<ENTER> + +function! s:call_tuple_fun_args(start_line, start_col, end_line, end_col, search_path) + let file = expand("%:p") + let module = 'wrangler' + let fun = 'tuple_funpar' + let args = '["' . file . '", {' . a:start_line . ', ' . a:start_col . '}, {' . a:end_line . ', ' . a:end_col . '}, ["' . a:search_path . '"], ' . &sw . ']' + let result = s:send_rpc(module, fun, args) + if s:check_for_error(result) + return 0 + endif + call s:send_confirm() + return 1 +endfunction + +function! ErlangTupleFunArgs(mode) + silent w! + let search_path = expand("%:p:h") + "let search_path = inputdialog('Search path: ', expand("%:p:h")) + if a:mode == "v" + let start_pos = getpos("'<") + let start_line = start_pos[1] + let start_col = start_pos[2] + + let end_pos = getpos("'>") + let end_line = end_pos[1] + let end_col = end_pos[2] + if s:call_tuple_fun_args(start_line, start_col, end_line, end_col, search_path) + let temp = &autoread + set autoread + :e + if temp == 0 + set noautoread + endif + endif + elseif a:mode == "n" + let pos = getpos(".") + let line = pos[1] + let col = pos[2] + if s:call_tuple_fun_args(line, col, line, col, search_path) + let temp = &autoread + set autoread + :e + if temp == 0 + set noautoread + endif + endif + else + echo "Mode not supported." + endif +endfunction +nmap <A-r>t :call ErlangTupleFunArgs("n")<ENTER> +vmap <A-r>t :call ErlangTupleFunArgs("v")<ENTER> + +" vim: set foldmethod=marker: diff --git a/indent/erlang.vim b/indent/erlang.vim index 370a8810..61833f74 100644 --- a/indent/erlang.vim +++ b/indent/erlang.vim @@ -1,58 +1,207 @@ " Vim indent file -" Language: Erlang -" Author: Ricardo Catalinas Jiménez <jimenezrick@gmail.com> -" License: Vim license -" Version: 2013/09/11 +" Language: Erlang +" Maintainer: Csaba Hoch <csaba.hoch@gmail.com> +" Contributor: Edwin Fine <efine145_nospam01 at usa dot net> +" Contributor: Pawel 'kTT' Salata <rockplayer.pl@gmail.com> +" Last Change: 2010 Aug 30 -if !exists('g:erlang_force_use_vimerl_indent') - let g:erlang_force_use_vimerl_indent = 0 -endif - -if exists('b:did_indent') || (v:version >= 704 && !g:erlang_force_use_vimerl_indent) - finish -else - let b:did_indent = 1 +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish endif +let b:did_indent = 1 setlocal indentexpr=ErlangIndent() -setlocal indentkeys=!^F,o,O,=),=},=],=>>,=of,=catch,=after,=end +setlocal indentkeys+==after,=end,=catch,=),=],=} -if exists('*ErlangIndent') - finish +" Only define the functions once. +if exists("*ErlangIndent") + finish endif -let s:erlang_indent_file = expand('<sfile>:p:h') . '/erlang_indent.erl' -if filewritable(expand('<sfile>:p:h')) == 2 - let s:in_fifo = expand('<sfile>:p:h') . '/vimerl_in_fifo.' . getpid() - let s:out_fifo = expand('<sfile>:p:h') . '/vimerl_out_fifo.' . getpid() -else - let s:in_fifo = '/tmp/vimerl_in_fifo.' . getpid() - let s:out_fifo = '/tmp/vimerl_out_fifo.' . getpid() -endif +" The function go through the whole line, analyses it and sets the indentation +" (ind variable). +" l: the number of the line to be examined. +function s:ErlangIndentAfterLine(l) + let i = 0 " the index of the current character in the line + let length = strlen(a:l) " the length of the line + let ind = 0 " how much should be the difference between the indentation of + " the current line and the indentation of the next line? + " e.g. +1: the indentation of the next line should be equal to + " the indentation of the current line plus one shiftwidth + let lastFun = 0 " the last token was a 'fun' + let lastReceive = 0 " the last token was a 'receive'; needed for 'after' + let lastHashMark = 0 " the last token was a 'hashmark' + + " ignore type annotation lines + if a:l =~# '^\s*-type' + return 0 + endif + + while 0<= i && i < length -execute 'silent !mkfifo' s:in_fifo -execute 'silent !mkfifo' s:out_fifo -execute 'silent !' . s:erlang_indent_file s:out_fifo s:in_fifo '&' + " m: the next value of the i + if a:l[i] == '%' + break + elseif a:l[i] == '"' + let m = matchend(a:l,'"\%([^"\\]\|\\.\)*"',i) + let lastReceive = 0 + elseif a:l[i] == "'" + let m = matchend(a:l,"'[^']*'",i) + let lastReceive = 0 + elseif a:l[i] =~# "[a-z]" + let m = matchend(a:l,".[[:alnum:]_]*",i) + if lastFun + let ind = ind - 1 + let lastFun = 0 + let lastReceive = 0 + elseif a:l[(i):(m-1)] =~# '^\%(case\|if\|try\)$' + let ind = ind + 1 + elseif a:l[(i):(m-1)] =~# '^receive$' + let ind = ind + 1 + let lastReceive = 1 + elseif a:l[(i):(m-1)] =~# '^begin$' + let ind = ind + 2 + let lastReceive = 0 + elseif a:l[(i):(m-1)] =~# '^end$' + let ind = ind - 2 + let lastReceive = 0 + elseif a:l[(i):(m-1)] =~# '^after$' + if lastReceive == 0 + let ind = ind - 1 + else + let ind = ind + 0 + endif + let lastReceive = 0 + elseif a:l[(i):(m-1)] =~# '^fun$' + let ind = ind + 1 + let lastFun = 1 + let lastReceive = 0 + endif + elseif a:l[i] =~# "[A-Z_]" + let m = matchend(a:l,".[[:alnum:]_]*",i) + let lastReceive = 0 + elseif a:l[i] == '$' + let m = i+2 + let lastReceive = 0 + elseif a:l[i] == "." && (i+1>=length || a:l[i+1]!~ "[0-9]") + let m = i+1 + if lastHashMark + let lastHashMark = 0 + else + let ind = ind - 1 + endif + let lastReceive = 0 + elseif a:l[i] == '-' && (i+1<length && a:l[i+1]=='>') + let m = i+2 + let ind = ind + 1 + let lastReceive = 0 + elseif a:l[i] == ';' && a:l[(i):(length)] !~# '.*->.*' + let m = i+1 + let ind = ind - 1 + let lastReceive = 0 + elseif a:l[i] == '#' + let m = i+1 + let lastHashMark = 1 + elseif a:l[i] =~# '[({[]' + let m = i+1 + let ind = ind + 1 + let lastFun = 0 + let lastReceive = 0 + let lastHashMark = 0 + elseif a:l[i] =~# '[)}\]]' + let m = i+1 + let ind = ind - 1 + let lastReceive = 0 + else + let m = i+1 + endif -autocmd VimLeave * call <SID>StopIndenter() + let i = m + + endwhile + + return ind + +endfunction -function s:StopIndenter() - call writefile([], s:out_fifo) - call delete(s:in_fifo) - call delete(s:out_fifo) +function s:FindPrevNonBlankNonComment(lnum) + let lnum = prevnonblank(a:lnum) + let line = getline(lnum) + " continue to search above if the current line begins with a '%' + while line =~# '^\s*%.*$' + let lnum = prevnonblank(lnum - 1) + if 0 == lnum + return 0 + endif + let line = getline(lnum) + endwhile + return lnum endfunction function ErlangIndent() - if v:lnum == 1 - return 0 - else - call writefile([v:lnum] + getline(1, v:lnum), s:out_fifo) - let indent = split(readfile(s:in_fifo)[0]) - - if len(indent) == 1 || !&expandtab - return indent[0] * &shiftwidth - else - return indent[1] - endif - endif + + " Find a non-blank line above the current line. + let lnum = prevnonblank(v:lnum - 1) + + " Hit the start of the file, use zero indent. + if lnum == 0 + return 0 + endif + + let prevline = getline(lnum) + let currline = getline(v:lnum) + + let ind = indent(lnum) + &sw * s:ErlangIndentAfterLine(prevline) + + " special cases: + if prevline =~# '^\s*\%(after\|end\)\>' + let ind = ind + 2*&sw + endif + if currline =~# '^\s*end\>' + let ind = ind - 2*&sw + endif + if currline =~# '^\s*after\>' + let plnum = s:FindPrevNonBlankNonComment(v:lnum-1) + if getline(plnum) =~# '^[^%]*\<receive\>\s*\%(%.*\)\=$' + let ind = ind - 1*&sw + " If the 'receive' is not in the same line as the 'after' + else + let ind = ind - 2*&sw + endif + endif + if prevline =~# '^\s*[)}\]]' + let ind = ind + 1*&sw + endif + if currline =~# '^\s*[)}\]]' + let ind = ind - 1*&sw + endif + if prevline =~# '^\s*\%(catch\)\s*\%(%\|$\)' + let ind = ind + 1*&sw + endif + if currline =~# '^\s*\%(catch\)\s*\%(%\|$\)' + let ind = ind - 1*&sw + endif + + if ind<0 + let ind = 0 + endif + return ind + endfunction + +" TODO: +" +" f() -> +" x("foo +" bar") +" , +" bad_indent. +" +" fun +" init/0, +" bad_indent +" +" #rec +" .field, +" bad_indent diff --git a/syntax/erlang.vim b/syntax/erlang.vim index 4b683edc..8b6ad624 100644 --- a/syntax/erlang.vim +++ b/syntax/erlang.vim @@ -1,35 +1,40 @@ " Vim syntax file -" Language: Erlang -" Author: Oscar Hellström <oscar@oscarh.net> (http://oscar.hellstrom.st) -" Contributors: Ricardo Catalinas Jiménez <jimenezrick@gmail.com> -" License: Vim license -" Version: 2012/05/07 - -if exists("b:current_syntax") - finish -else - let b:current_syntax = "erlang" -endif - -if !exists("g:erlang_highlight_bif") - let g:erlang_highlight_bif = 1 +" Language: Erlang +" Maintainer: Oscar Hellström <oscar@oscarh.net> +" URL: http://oscar.hellstrom.st +" Version: 2010-08-09 +" ------------------------------------------------------------------------------ +" {{{1 +" Options: +" +" Erlang BIFs +" g:erlangHighlightBif - highlight erlang built in functions (default: off) +" +" }}} +" ----------------------------------------------------------------------------- + +" Setup {{{1 +" For version 5.x: Clear all syntax items +" For version 6.x: Quit when a syntax file was already loaded +if version < 600 + syntax clear +elseif exists("b:current_syntax") + finish endif " Erlang is case sensitive syn case match -" Match groups +" Match groups {{{1 syn match erlangStringModifier /\\./ contained -syn match erlangStringModifier /\~\%(-\?[0-9*]\+\)\?\%(\.[0-9*]*\%(\..\?t\?\)\?\)\?\%(\~\|c\|f\|e\|g\|s\|w\|p\|W\|P\|B\|X\|#\|b\|x\|+\|n\|i\)/ contained +syn match erlangStringModifier /\~\%(-\?[0-9*]\+\)\?\%(\.[0-9*]\+\..\?\)\?\%(c\|f\|e\|g\|s\|w\|p\|W\|P\|B\|X\|#\|b\|+\|n\|i\)/ contained syn match erlangModifier /\$\\\?./ syn match erlangInteger /\<\%([0-9]\+#[0-9a-fA-F]\+\|[0-9]\+\)\>/ syn match erlangFloat /\<[0-9]\+\.[0-9]\+\%(e-\?[0-9]\+\)\?\>/ syn keyword erlangTodo TODO FIXME XXX contained -syn match erlangComment /%.*$/ contains=@Spell,erlangTodo,erlangAnnotation -syn match erlangAnnotation /\%(%\s\)\@<=@\%(author\|clear\|copyright\|deprecated\|doc\|docfile\|end\|equiv\|headerfile\|hidden\|private\|reference\|see\|since\|spec\|throws\|title\|todo\|TODO\|type\|version\)/ contained -syn match erlangAnnotation /`[^']\+'/ contained +syn match erlangComment /%.*$/ contains=@Spell,erlangTodo syn keyword erlangKeyword band bor bnot bsl bsr bxor div rem xor syn keyword erlangKeyword try catch begin receive after cond fun let query @@ -42,9 +47,9 @@ syn keyword erlangBoolean true false syn keyword erlangGuard is_list is_alive is_atom is_binary is_bitstring is_boolean is_tuple is_number is_integer is_float is_function is_constant is_pid is_port is_reference is_record is_process_alive -syn match erlangOperator /\/\|*\|+\|-\|++\|--/ -syn match erlangOperator /->\|<-\|||\||\|!\|=/ -syn match erlangOperator /=:=\|==\|\/=\|=\/=\|<\|>\|=<\|>=/ +syn match erlangOperator /\/\|*\|+\|-\|++\|--/ +syn match erlangOperator /->\|<-\|||\||\|!\|=/ +syn match erlangOperator /=:=\|==\|\/=\|=\/=\|<\|>\|=<\|>=/ syn keyword erlangOperator div rem syn region erlangString start=/"/ end=/"/ skip=/\\/ contains=@Spell,erlangStringModifier @@ -58,69 +63,75 @@ syn match erlangRecord /#\w\+/ syn match erlangTuple /{\|}/ syn match erlangList /\[\|\]/ -syn match erlangAttribute /^-\%(vsn\|author\|copyright\|compile\|deprecated\|module\|export\|import\|behaviour\|behavior\|export_type\|ignore_xref\|on_load\|mode\)\s*(\@=/ + syn match erlangAttribute /^-\%(vsn\|author\|copyright\|compile\|deprecated\|module\|export\|import\|behaviour\|export_type\|ignore_xref\) *(\@=/ syn match erlangInclude /^-include\%(_lib\)\?\s*(\@=/ syn match erlangRecordDef /^-record\s*(\@=/ syn match erlangDefine /^-\%(define\|undef\)\s*(\@=/ syn match erlangPreCondit /^-\%(ifdef\|ifndef\|else\|endif\)\%(\s*(\@=\)\?/ -syn match erlangType /^-\%(spec\|type\|opaque\|callback\)[( ]\@=/ +syn match erlangType /^-\%(spec\|type\)[( ]\@=/ syn match erlangMacro /\%(-define(\)\@<=\w\+/ -syn match erlangMacro /?\??\w\+/ +syn match erlangMacro /?\w\+/ syn match erlangBitType /\%(\/\|-\)\@<=\%(bits\|bitstring\|binary\|integer\|float\|unit\)\>/ syn match erlangBitSize /:\@<=[0-9]\+/ -syn match erlangBinary /<<\|>>/ - -" BIFs -syn match erlangBIF /\%([^:0-9A-Za-z_]\|\<erlang:\|^\)\@<=\%(abs\|apply\|atom_to_binary\|atom_to_list\|binary_part\|binary_to_atom\|binary_to_existing_atom\|binary_to_list\|binary_to_term\|bit_size\|bitstring_to_list\|byte_size\|check_process_code\|date\|delete_module\|demonitor\|disconnect_node\|element\|erase\|error\|exit\|float\|float_to_list\|garbage_collect\|get\|get_keys\|group_leader\|halt\|hd\|integer_to_list\|iolist_size\|iolist_to_binary\|is_alive\|is_atom\|is_binary\|is_bitstring\|is_boolean\|is_float\|is_function\|is_integer\|is_list\|is_number\|is_pid\|is_port\|is_process_alive\|is_record\|is_reference\|is_tuple\|length\|link\|list_to_atom\|list_to_binary\|list_to_bitstring\|list_to_existing_atom\|list_to_float\|list_to_integer\|list_to_pid\|list_to_tuple\|load_module\|make_ref\|max\|min\|module_loaded\|monitor\|monitor_node\|node\|nodes\|now\|open_port\|pid_to_list\|port_close\|port_command\|port_connect\|port_control\|pre_loaded\|processes\|process_flag\|process_info\|purge_module\|put\|register\|registered\|round\|self\|setelement\|size\|spawn\|spawn_link\|spawn_monitor\|spawn_opt\|split_binary\|statistics\|term_to_binary\|throw\|time\|tl\|trunc\|tuple_size\|tuple_to_list\|unlink\|unregister\|whereis\)\%((\|\/[0-9]\)\@=/ -syn match erlangBIF /\%(\<erlang:\)\@<=\%(append_element\|bump_reductions\|cancel_timer\|decode_packet\|display\|function_exported\|fun_info\|fun_to_list\|get_cookie\|get_stacktrace\|hash\|is_builtin\|loaded\|load_nif\|localtime\|localtime_to_universaltime\|make_tuple\|memory\|monitor_node\|phash\|port_call\|port_info\|ports\|port_to_list\|process_display\|read_timer\|ref_to_list\|resume_process\|send\|send_after\|send_nosuspend\|set_cookie\|start_timer\|suspend_process\|system_flag\|system_info\|system_monitor\|system_profile\|trace\|trace_delivered\|trace_info\|trace_pattern\|universaltime\|universaltime_to_localtime\|yield\)(\@=/ -syn match erlangGBIF /\<erlang\%(:\w\)\@=/ - -" Link Erlang stuff to Vim groups -hi def link erlangTodo Todo -hi def link erlangString String -hi def link erlangNoSpellString String -hi def link erlangModifier SpecialChar -hi def link erlangStringModifier SpecialChar -hi def link erlangComment Comment -hi def link erlangAnnotation Special -hi def link erlangVariable Identifier -hi def link erlangInclude Include -hi def link erlangRecordDef Keyword -hi def link erlangAttribute Keyword -hi def link erlangKeyword Keyword -hi def link erlangMacro Macro -hi def link erlangDefine Define -hi def link erlangPreCondit PreCondit -hi def link erlangPreProc PreProc -hi def link erlangDelimiter Delimiter -hi def link erlangBitDelimiter Normal -hi def link erlangOperator Operator -hi def link erlangConditional Conditional -hi def link erlangGuard Conditional -hi def link erlangBoolean Boolean -hi def link erlangAtom Constant -hi def link erlangRecord Structure -hi def link erlangInteger Number -hi def link erlangFloat Number -hi def link erlangFloat Number -hi def link erlangFloat Number -hi def link erlangFloat Number -hi def link erlangHex Number -hi def link erlangFun Keyword -hi def link erlangList Delimiter -hi def link erlangTuple Delimiter -hi def link erlangBinary Keyword -hi def link erlangBitVariable Identifier -hi def link erlangBitType Type -hi def link erlangType Type -hi def link erlangBitSize Number - -" Optional highlighting -if g:erlang_highlight_bif - hi def link erlangBIF Keyword - hi def link erlangGBIF Keyword +syn match erlangBinary /<<\|>>/ + +" BIFS +syn match erlangBIF /\%([^:0-9A-Za-z_]\|\<erlang:\)\@<=\%(abs\|apply\|atom_to_list\|binary_part\|binary_to_list\|binary_to_term\|binary_to_atom\|binary_to_existing_atom\|bitstring_to_list\|check_process_code\|concat_binary\|date\|delete_module\|disconnect_node\|element\|erase\|error\|exit\|float\|float_to_list\|garbage_collect\|get\|get_keys\|group_leader\|halt\|hd\|integer_to_list\|iolist_to_binary\|iolist_size\|length\|link\|list_to_atom\|list_to_binary\|list_to_bitstring\|list_to_existing_atom\|list_to_float\|list_to_integer\|list_to_pid\|list_to_tuple\|load_module\|make_ref\|monitor_node\|node\|nodes\|now\|open_port\|pid_to_list\|port_close\|port_command\|port_connect\|port_control\|pre_loaded\|process_flag\|process_info\|processes\|purge_module\|put\|register\|registered\|round\|self\|setelement\|size\|bit_size\|byte_size\|spawn\|spawn_link\|spawn_opt\|split_binary\|statistics\|term_to_binary\|throw\|time\|tl\|trunc\|tuple_to_list\|unlink\|unregister\|whereis\)\((\|\/[0-9]\)\@=/ +syn match erlangBIF /\<\%(erlang:\)\@<=\%(append_element\|bump_reductions\|cancel_timer\|decode_packet\|demonitor\|display\|fault\|fun_info\|fun_to_list\|function_exported\|get_cookie\|get_stacktrace\|hash\|hibernate\|info\|is_builtin\|loaded\|localtime\|localtime_to_universaltime\|localtime_to_universaltime\|make_tuple\|md5\|md5_init\|md5_update\|memory\|monitor\|monitor_node\|phash\|phash2\|port_call\|port_info\|port_to_list\|ports\|process_display\|raise\|read_timer\|ref_to_list\|resume_process\|send\|send_after\|send_nosuspend\|set_cookie\|spawn_monitor\|start_timer\|suspend_process\|system_flag\|system_info\|system_monitor\|trace\|trace_delivered\|trace_info\|trace_pattern\|universaltime\|universaltime_to_localtime\|yield\)(\@=/ +syn match erlangGBIF /erlang\(:\w\)\@=/ +" }}} + +" Link Erlang stuff to Vim groups {{{1 +hi link erlangTodo Todo +hi link erlangString String +hi link erlangNoSpellString String +hi link erlangModifier SpecialChar +hi link erlangStringModifier SpecialChar +hi link erlangComment Comment +hi link erlangVariable Identifier +hi link erlangInclude Include +hi link erlangRecordDef Keyword +hi link erlangAttribute Keyword +hi link erlangKeyword Keyword +hi link erlangMacro Macro +hi link erlangDefine Define +hi link erlangPreCondit PreCondit +hi link erlangPreProc PreProc +hi link erlangDelimiter Delimiter +hi link erlangBitDelimiter Normal +hi link erlangOperator Operator +hi link erlangConditional Conditional +hi link erlangGuard Conditional +hi link erlangBoolean Boolean +hi link erlangAtom Constant +hi link erlangRecord Structure +hi link erlangInteger Number +hi link erlangFloat Number +hi link erlangFloat Number +hi link erlangFloat Number +hi link erlangFloat Number +hi link erlangHex Number +hi link erlangBIF Keyword +hi link erlangFun Keyword +hi link erlangList Delimiter +hi link erlangTuple Delimiter +hi link erlangBinary Keyword +hi link erlangBitVariable Identifier +hi link erlangBitType Type +hi link erlangType Type +hi link erlangBitSize Number +" }}} + +" Optional linkings {{{1 +if exists("g:erlangHighlightBif") && g:erlangHighlightBif + hi link erlangGBIF Keyword endif +" }}} + +let b:current_syntax = "erlang" + +" vim: set foldmethod=marker: |