summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--autoload/erlang_complete.vim219
-rw-r--r--autoload/erlangcomplete.vim161
-rwxr-xr-xbuild2
-rw-r--r--compiler/erlang.vim153
-rw-r--r--ftplugin/erlang.vim200
-rw-r--r--ftplugin/erlang_refactor.vim295
-rw-r--r--indent/erlang.vim235
-rw-r--r--syntax/erlang.vim163
9 files changed, 931 insertions, 499 deletions
diff --git a/README.md b/README.md
index 05993f05..3a581e8a 100644
--- a/README.md
+++ b/README.md
@@ -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
+
diff --git a/build b/build
index ba89ffe8..f21b49f2 100755
--- a/build
+++ b/build
@@ -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: