1" Elm indent plugin file 2" Language: Elm 3" Maintainer: Andreas Scharf <[email protected]> 4" Original Author: Joseph Hager <[email protected]> 5" Copyright: Joseph Hager <[email protected]> 6" License: BSD3 7" Latest Revision: 2020-05-29 8 9" Only load this indent file when no other was loaded. 10if exists('b:did_indent') 11 finish 12endif 13let b:did_indent = 1 14 15" Local defaults 16setlocal expandtab 17setlocal indentexpr=GetElmIndent() 18setlocal indentkeys+=0=else,0=if,0=of,0=import,0=then,0=type,0\|,0},0\],0),=-},0=in 19setlocal nolisp 20setlocal nosmartindent 21 22" Only define the function once. 23if exists('*GetElmIndent') 24 finish 25endif 26 27" Indent pairs 28function! s:FindPair(pstart, pmid, pend) 29 "call search(a:pend, 'bW') 30 return indent(searchpair(a:pstart, a:pmid, a:pend, 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"')) 31endfunction 32 33function! GetElmIndent() 34 let l:lnum = v:lnum - 1 35 36 " Ident 0 if the first line of the file: 37 if l:lnum == 0 38 return 0 39 endif 40 41 let l:ind = indent(l:lnum) 42 let l:lline = getline(l:lnum) 43 let l:line = getline(v:lnum) 44 45 " Indent if current line begins with '}': 46 if l:line =~? '^\s*}' 47 return s:FindPair('{', '', '}') 48 49 " Indent if current line begins with 'else': 50 elseif l:line =~# '^\s*else\>' 51 if l:lline !~# '^\s*\(if\|then\)\>' 52 return s:FindPair('\<if\>', '', '\<else\>') 53 endif 54 55 " Indent if current line begins with 'then': 56 elseif l:line =~# '^\s*then\>' 57 if l:lline !~# '^\s*\(if\|else\)\>' 58 return s:FindPair('\<if\>', '', '\<then\>') 59 endif 60 61 " HACK: Indent lines in case with nearest case clause: 62 elseif l:line =~# '->' && l:line !~# ':' && l:line !~# '\\' 63 return indent(search('^\s*case', 'bWn')) + &shiftwidth 64 65 " HACK: Don't change the indentation if the last line is a comment. 66 elseif l:lline =~# '^\s*--' 67 return l:ind 68 69 " Align the end of block comments with the start 70 elseif l:line =~# '^\s*-}' 71 return indent(search('{-', 'bWn')) 72 73 " Indent double shift after let with an empty rhs 74 elseif l:lline =~# '\<let\>.*\s=$' 75 return l:ind + 4 + &shiftwidth 76 77 " Align 'in' with the parent let. 78 elseif l:line =~# '^\s*in\>' 79 return indent(search('^\s*let', 'bWn')) 80 81 " Align bindings with the parent let. 82 elseif l:lline =~# '\<let\>' 83 return l:ind + 4 84 85 " Align bindings with the parent in. 86 elseif l:lline =~# '^\s*in\>' 87 return l:ind 88 89 endif 90 91 " Add a 'shiftwidth' after lines ending with: 92 if l:lline =~# '\(|\|=\|->\|<-\|(\|\[\|{\|\<\(of\|else\|if\|then\)\)\s*$' 93 let l:ind = l:ind + &shiftwidth 94 95 " Add a 'shiftwidth' after lines starting with type ending with '=': 96 elseif l:lline =~# '^\s*type' && l:line =~# '^\s*=' 97 let l:ind = l:ind + &shiftwidth 98 99 " Back to normal indent after comments: 100 elseif l:lline =~# '-}\s*$' 101 call search('-}', 'bW') 102 let l:ind = indent(searchpair('{-', '', '-}', 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string"')) 103 104 " Ident some operators if there aren't any starting the last line. 105 elseif l:line =~# '^\s*\(!\|&\|(\|`\|+\||\|{\|[\|,\)=' && l:lline !~# '^\s*\(!\|&\|(\|`\|+\||\|{\|[\|,\)=' && l:lline !~# '^\s*$' 106 let l:ind = l:ind + &shiftwidth 107 108 elseif l:lline ==# '' && getline(l:lnum - 1) !=# '' 109 let l:ind = indent(search('^\s*\S+', 'bWn')) 110 111 endif 112 113 return l:ind 114endfunc 115