Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

200 lines (173 sloc) 5.057 kb
" Vim ftplugin file
" Language: Erlang
" Maintainer: Oscar Hellström <oscar@oscarh.net>
" URL: http://personal.oscarh.net
" Version: 2010-08-09
" ------------------------------------------------------------------------------
" Usage: {{{1
"
" To enable folding put in your vimrc
" let g:erlangFold=1
"
" 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
" let g:erlangFoldSplitFunction=1
" in your vimrc file
"
" }}}
" ------------------------------------------------------------------------------
" Plugin init {{{1
if exists("b:did_ftplugin")
finish
endif
" Don't load any other
let b:did_ftplugin=1
if exists('s:doneFunctionDefinitions')
call s:SetErlangOptions()
finish
endif
let s:doneFunctionDefinitions=1
" }}}
" Local settings {{{1
" Run Erlang make instead of GNU Make
function s:SetErlangOptions()
if version >= 700
setlocal omnifunc=erlangcomplete#Complete
endif
" {{{2 Settings for folding
if (exists("g:erlangFold")) && g:erlangFold
setlocal foldmethod=expr
setlocal foldexpr=GetErlangFold(v:lnum)
setlocal foldtext=ErlangFoldText()
"setlocal fml=2
endif
endfunction
" Define folding functions {{{1
if !exists("*GetErlangFold")
" Folding params {{{2
" FIXME: Could these be shared between scripts?
let s:ErlangFunEnd = '^[^%]*\.\s*\(%.*\)\?$'
let s:ErlangFunHead = '^\a\w*(.*)\(\s+when\s+.*\)\?\s\+->\s*$'
let s:ErlangBeginHead = '^\a\w*(.*$'
let s:ErlangEndHead = '^\s\+[a-zA-Z-_{}\[\], ]\+)\(\s+when\s+.*\)\?\s\+->\s\(%.*\)\?*$'
let s:ErlangBlankLine = '^\s*\(%.*\)\?$'
" Auxiliary fold functions {{{2
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 {{{2
function GetErlangFold(lnum)
let lnum = a:lnum
let line = getline(lnum)
" Function head gives fold level 1 {{{3
if line=~ s:ErlangBeginHead
while line !~ s:ErlangEndHead
if 0 == lnum " EOF / BOF
return '='
endif
if line =~ s:ErlangFunEnd
return '='
endif
endif
let lnum = s:GetNextNonBlank(lnum)
let line = getline(lnum)
endwhile
" check if prev line was really end of function
let lnum = s:GetPrevNonBlank(a:lnum)
if exists("g:erlangFoldSplitFunction") && g:erlangFoldSplitFunction
if getline(lnum) !~ s:ErlangFunEnd
return '='
endif
endif
return '1>'
endif
" End of function (only on . not ;) gives fold level 0 {{{3
if line =~ s:ErlangFunEnd
return '<1'
endif
" Check if line below is a new function head {{{3
" Only used if we want to split folds for different function heads
" Ignores blank lines
if exists("g:erlangFoldSplitFunction") && g:erlangFoldSplitFunction
let lnum = s:GetNextNonBlank(lnum)
if 0 == lnum " EOF
return '<1'
endif
let line = getline(lnum)
" End of prev function head (new function here), ending fold level 1
if line =~ s:ErlangFunHead || line =~ s:ErlangBeginHead
return '<1'
endif
endif
" Otherwise use fold from previous line
return '='
endfunction
" Erlang fold description (foldtext function) {{{2
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()
" Skeletons {{{1
function GenServer()
echo foo
endfunction
" }}}
" vim: set foldmethod=marker:
Jump to Line
Something went wrong with that request. Please try again.