diff options
author | Bram Moolenaar <Bram@vim.org> | 2016-08-26 19:52:37 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2016-08-26 19:52:37 +0200 |
commit | e4a3bcf28d92d0bde9ca227ccb40d401038185e5 (patch) | |
tree | 276387ac4364fdee74b72c2503fc4505e8728043 /runtime/indent | |
parent | dd74ab9b464f3d1a5f6f6395469b76f8e0e6dccd (diff) |
Updated runtime files. Add Scala files.
Diffstat (limited to 'runtime/indent')
-rw-r--r-- | runtime/indent/fortran.vim | 10 | ||||
-rw-r--r-- | runtime/indent/javascript.vim | 96 | ||||
-rw-r--r-- | runtime/indent/rnoweb.vim | 14 | ||||
-rw-r--r-- | runtime/indent/scala.vim | 609 |
4 files changed, 675 insertions, 54 deletions
diff --git a/runtime/indent/fortran.vim b/runtime/indent/fortran.vim index e19a19fb1f..be2f0866d5 100644 --- a/runtime/indent/fortran.vim +++ b/runtime/indent/fortran.vim @@ -1,7 +1,7 @@ " Vim indent file " Language: Fortran 2008 (and older: Fortran 2003, 95, 90, and 77) -" Version: 0.44 -" Last Change: 2016 Jan. 26 +" Version: 0.45 +" Last Change: 2016 Aug. 18 " Maintainer: Ajit J. Thakkar <ajit@unb.ca>; <http://www2.unb.ca/~ajit/> " Usage: For instructions, do :help fortran-indent from Vim " Credits: @@ -121,7 +121,7 @@ function FortranGetIndent(lnum) let prefix='\(\(pure\|impure\|elemental\|recursive\)\s\+\)\{,2}' let type='\(\(integer\|real\|double\s\+precision\|complex\|logical' \.'\|character\|type\|class\)\s*\S*\s\+\)\=' - if prevstat =~? '^\s*\(module\|contains\|program\)\>' + if prevstat =~? '^\s*\(module\|contains\/submodule\|program\)\>' \ ||prevstat =~? '^\s*'.prefix.'subroutine\>' \ ||prevstat =~? '^\s*'.prefix.type.'function\>' \ ||prevstat =~? '^\s*'.type.prefix.'function\>' @@ -129,14 +129,14 @@ function FortranGetIndent(lnum) endif if getline(v:lnum) =~? '^\s*contains\>' \ ||getline(v:lnum)=~? '^\s*end\s*' - \ .'\(function\|subroutine\|module\|program\)\>' + \ .'\(function\|subroutine\|module\/submodule\|program\)\>' let ind = ind - shiftwidth() endif endif "Subtract a shiftwidth from else, else if, elsewhere, case, end if, " end where, end select, end forall, end interface, end associate, - " end enum, and end type statements + " end enum, end type, end block and end type statements if getline(v:lnum) =~? '^\s*\(\d\+\s\)\=\s*' \. '\(else\|else\s*if\|else\s*where\|case\|' \. 'end\s*\(if\|where\|select\|interface\|' diff --git a/runtime/indent/javascript.vim b/runtime/indent/javascript.vim index 3507e305ed..0d6c11d151 100644 --- a/runtime/indent/javascript.vim +++ b/runtime/indent/javascript.vim @@ -1,8 +1,8 @@ " Vim indent file " Language: Javascript -" Maintainer: vim-javascript community +" Maintainer: Chris Paul ( https://github.com/bounceme ) " URL: https://github.com/pangloss/vim-javascript -" Last Change: August 12, 2016 +" Last Change: August 25, 2016 " Only load this indent file when no other was loaded. if exists('b:did_indent') @@ -12,11 +12,11 @@ let b:did_indent = 1 " Now, set up our indentation expression and keys that trigger it. setlocal indentexpr=GetJavascriptIndent() -setlocal nolisp +setlocal nolisp noautoindent nosmartindent setlocal indentkeys=0{,0},0),0],:,!^F,o,O,e setlocal cinoptions+=j1,J1 -let b:undo_indent = 'setlocal indentexpr< indentkeys< cinoptions<' +let b:undo_indent = 'setlocal indentexpr< smartindent< autoindent< indentkeys< cinoptions<' " Only define the function once. if exists('*GetJavascriptIndent') @@ -37,7 +37,7 @@ else endfunction endif -let s:line_pre = '^\s*\%(\/\*.\{-}\*\/\s*\)*' +let s:line_pre = '^\s*\%(\%(\%(\/\*.\{-}\)\=\*\+\/\s*\)\=\)\@>' let s:expr_case = s:line_pre . '\%(\%(case\>.\+\)\|default\)\s*:' " Regex of syntax group names that are or delimit string or are comments. let s:syng_strcom = '\%(s\%(tring\|pecial\)\|comment\|regex\|doc\|template\)' @@ -46,63 +46,63 @@ let s:syng_strcom = '\%(s\%(tring\|pecial\)\|comment\|regex\|doc\|template\)' let s:syng_comment = '\%(comment\|doc\)' " Expression used to check whether we should skip a match with searchpair(). -let s:skip_expr = "line('.') < (prevnonblank(v:lnum) - 2000) ? dummy : synIDattr(synID(line('.'),col('.'),0),'name') =~? '".s:syng_strcom."'" +let s:skip_expr = "synIDattr(synID(line('.'),col('.'),0),'name') =~? '".s:syng_strcom."'" -function s:lookForParens(start,end,flags,time) - if has('reltime') - return searchpair(a:start,'',a:end,a:flags,s:skip_expr,0,a:time) - else - return searchpair(a:start,'',a:end,a:flags,0,0) - endif -endfunction +if has('reltime') + function s:GetPair(start,end,flags,time) + return searchpair(a:start,'',a:end,a:flags,s:skip_expr,max([prevnonblank(v:lnum) - 2000,0]),a:time) + endfunction +else + function s:GetPair(start,end,flags,n) + return searchpair(a:start,'',a:end,a:flags,0,max([prevnonblank(v:lnum) - 2000,0])) + endfunction +endif -let s:line_term = '\%(\s*\%(\/\*.\{-}\*\/\s*\)\=\)\@>$' +let s:line_term = '\s*\%(\%(\/\%(\%(\*.\{-}\*\/\)\|\%(\*\+\)\)\)\s*\)\=$' " configurable regexes that define continuation lines, not including (, {, or [. if !exists('g:javascript_opfirst') - let g:javascript_opfirst = '\%([<>,:?^%]\|\([-/.+]\)\%(\1\|\*\|\/\)\@!\|\*\/\@!\|=>\@!\||\|&\|in\%(stanceof\)\=\>\)' + let g:javascript_opfirst = '\%([<>,:?^%|*&]\|\/[^/*]\|\([-.+]\)\1\@!\|=>\@!\|in\%(stanceof\)\=\>\)' endif -let g:javascript_opfirst = s:line_pre . g:javascript_opfirst - if !exists('g:javascript_continuation') - let g:javascript_continuation = '\%([<*,.?:^%]\|+\@<!+\|-\@<!-\|=\@<!>\|\*\@<!\/\|=\||\|&\|\<in\%(stanceof\)\=\)' + let g:javascript_continuation = '\%([<=,.?/*:^%|&]\|+\@<!+\|-\@<!-\|=\@<!>\|\<in\%(stanceof\)\=\)' endif + +let g:javascript_opfirst = s:line_pre . g:javascript_opfirst let g:javascript_continuation .= s:line_term -function s:Onescope(lnum,text,add) - return a:text =~# '\%(\<else\|\<do\|=>' . (a:add ? '\|\<try\|\<finally' : '' ) . '\)' . s:line_term || +function s:OneScope(lnum,text,add) + return a:text =~# '\%(\<else\|\<do\|=>\)' . s:line_term ? 'no b' : \ ((a:add && a:text =~ s:line_pre . '$' && search('\%' . s:PrevCodeLine(a:lnum - 1) . 'l.)' . s:line_term)) || \ cursor(a:lnum, match(a:text, ')' . s:line_term)) > -1) && - \ s:lookForParens('(', ')', 'cbW', 100) > 0 && search((a:add ? - \ '\%(function\*\|[[:lower:][:upper:]_$][[:digit:][:lower:][:upper:]_$]*\)' : - \ '\<\%(for\%(\s\+each\)\=\|if\|let\|w\%(hile\|ith\)\)') . '\_s*\%#\C','bW') && - \ (a:add || (expand('<cword>') ==# 'while' ? !s:lookForParens('\<do\>\C', '\<while\>\C','bW',100) : 1)) + \ s:GetPair('(', ')', 'cbW', 100) > 0 && search('\C\l\+\_s*\%#','bW') && + \ (a:add || ((expand('<cword>') !=# 'while' || !s:GetPair('\C\<do\>', '\C\<while\>','nbW',100)) && + \ (expand('<cword>') !=# 'each' || search('\C\<for\_s\+\%#','nbW')))) ? expand('<cword>') : '' endfunction -" Auxiliary Functions {{{2 - -" strip line of comment -function s:StripLine(c) - return a:c !~# s:expr_case ? substitute(a:c, '\%(:\@<!\/\/.*\)$', '','') : a:c +" https://github.com/sweet-js/sweet.js/wiki/design#give-lookbehind-to-the-reader +function s:IsBlock() + return getline(line('.'))[col('.')-1] == '{' && !search( + \ '\C\%(\<return\s*\|\%([-=~!<*+,.?^%|&\[(]\|=\@<!>\|\*\@<!\/\|\<\%(var\|const\|let\|import\|export\%(\_s\+default\)\=\|yield\|delete\|void\|t\%(ypeof\|hrow\)\|new\|in\%(stanceof\)\=\)\)\_s*\)\%#','bnW') && + \ (!search(':\_s*\%#','bW') || (!s:GetPair('[({[]','[])}]','bW',200) || s:IsBlock())) endfunction +" Auxiliary Functions {{{2 + " Find line above 'lnum' that isn't empty, in a comment, or in a string. function s:PrevCodeLine(lnum) let l:lnum = prevnonblank(a:lnum) - while l:lnum > 0 + while l:lnum if synIDattr(synID(l:lnum,matchend(getline(l:lnum), '^\s*[^''"]'),0),'name') !~? s:syng_strcom - break + return l:lnum endif let l:lnum = prevnonblank(l:lnum - 1) endwhile - return l:lnum endfunction " Check if line 'lnum' has a balanced amount of parentheses. function s:Balanced(lnum) - let open_0 = 0 - let open_2 = 0 - let open_4 = 0 + let [open_0,open_2,open_4] = [0,0,0] let l:line = getline(a:lnum) let pos = match(l:line, '[][(){}]', 0) while pos != -1 @@ -129,7 +129,7 @@ function GetJavascriptIndent() let syns = synIDattr(synID(v:lnum, 1, 0), 'name') " start with strings,comments,etc.{{{2 - if (l:line !~ '^[''"`]' && syns =~? 'string\|template') || + if (l:line !~ '^[''"`]' && syns =~? '\%(string\|template\)') || \ (l:line !~ '^\s*[/*]' && syns =~? s:syng_comment) return -1 endif @@ -153,15 +153,15 @@ function GetJavascriptIndent() " the containing paren, bracket, curly. Memoize, last lineNr either has the " same scope or starts a new one, unless if it closed a scope. call cursor(v:lnum,1) - if b:js_cache[0] >= l:lnum && b:js_cache[0] <= v:lnum && b:js_cache[0] && + if b:js_cache[0] >= l:lnum && b:js_cache[0] < v:lnum && b:js_cache[0] && \ (b:js_cache[0] > l:lnum || s:Balanced(l:lnum) > 0) let num = b:js_cache[1] elseif syns != '' && l:line[0] =~ '\s' let pattern = syns =~? 'block' ? ['{','}'] : syns =~? 'jsparen' ? ['(',')'] : \ syns =~? 'jsbracket'? ['\[','\]'] : ['[({[]','[])}]'] - let num = s:lookForParens(pattern[0],pattern[1],'bW',2000) + let num = s:GetPair(pattern[0],pattern[1],'bW',2000) else - let num = s:lookForParens('[({[]','[])}]','bW',2000) + let num = s:GetPair('[({[]','[])}]','bW',2000) endif let b:js_cache = [v:lnum,num,line('.') == v:lnum ? b:js_cache[2] : col('.')] @@ -169,17 +169,19 @@ function GetJavascriptIndent() return indent(num) endif - let pline = s:StripLine(getline(l:lnum)) - let inb = num == 0 ? 1 : (s:Onescope(num, s:StripLine(strpart(getline(num),0,b:js_cache[2] - 1)),1) || - \ (l:line !~ s:line_pre . ',' && pline !~ ',' . s:line_term)) && num < l:lnum - let switch_offset = (!inb || num == 0) || expand("<cword>") !=# 'switch' ? 0 : &cino !~ ':' || !has('float') ? s:sw() : + call cursor(b:js_cache[1],b:js_cache[2]) + + let swcase = getline(l:lnum) =~# s:expr_case + let pline = swcase ? getline(l:lnum) : substitute(getline(l:lnum), '\%(:\@<!\/\/.*\)$', '','') + let inb = num == 0 || num < l:lnum && ((l:line !~ s:line_pre . ',' && pline !~ ',' . s:line_term) || s:IsBlock()) + let switch_offset = num == 0 || s:OneScope(num, strpart(getline(num),0,b:js_cache[2] - 1),1) !=# 'switch' ? 0 : + \ &cino !~ ':' || !has('float') ? s:sw() : \ float2nr(str2float(matchstr(&cino,'.*:\zs[-0-9.]*')) * (&cino =~# '.*:[^,]*s' ? s:sw() : 1)) " most significant, find the indent amount - if (inb && (l:line =~# g:javascript_opfirst || - \ (pline =~# g:javascript_continuation && pline !~# s:expr_case && (pline !~ ':' . s:line_term || l:line !~# - \ s:line_pre . '\%(d\%(o\|ebugger\)\|else\|f\%(or\|inally\)\|if\|let\|switch\|t\%(hrow\|ry\)\|w\%(hile\|ith\)\)\>')))) || - \ (num < l:lnum && s:Onescope(l:lnum,pline,0) && l:line !~ s:line_pre . '{') + if inb && !swcase && ((l:line =~# g:javascript_opfirst || pline =~# g:javascript_continuation) || + \ num < l:lnum && s:OneScope(l:lnum,pline,0) =~# '\<\%(for\|each\|if\|let\|no\sb\|w\%(hile\|ith\)\)\>' && + \ l:line !~ s:line_pre . '{') return (num > 0 ? indent(num) : -s:sw()) + (s:sw() * 2) + switch_offset elseif num > 0 return indent(num) + s:sw() + switch_offset diff --git a/runtime/indent/rnoweb.vim b/runtime/indent/rnoweb.vim index 29fa5bc78f..8c11e85cb3 100644 --- a/runtime/indent/rnoweb.vim +++ b/runtime/indent/rnoweb.vim @@ -2,7 +2,7 @@ " Language: Rnoweb " Author: Jakson Alves de Aquino <jalvesaq@gmail.com> " Homepage: https://github.com/jalvesaq/R-Vim-runtime -" Last Change: Tue Apr 07, 2015 04:38PM +" Last Change: Fri Apr 15, 2016 10:58PM " Only load this indent file when no other was loaded. @@ -10,7 +10,17 @@ if exists("b:did_indent") finish endif runtime indent/tex.vim -let s:TeXIndent = function(substitute(&indentexpr, "()", "", "")) + +function! s:NoTeXIndent() + return indent(line(".")) +endfunction + +if &indentexpr == "" || &indentexpr == "GetRnowebIndent()" + let s:TeXIndent = function("s:NoTeXIndent") +else + let s:TeXIndent = function(substitute(&indentexpr, "()", "", "")) +endif + unlet b:did_indent runtime indent/r.vim let s:RIndent = function(substitute(&indentexpr, "()", "", "")) diff --git a/runtime/indent/scala.vim b/runtime/indent/scala.vim new file mode 100644 index 0000000000..f97c79bbab --- /dev/null +++ b/runtime/indent/scala.vim @@ -0,0 +1,609 @@ +" Vim indent file +" Language: Scala (http://scala-lang.org/) +" Original Author: Stefan Matthias Aust +" Modifications By: Derek Wyatt +" URL: https://github.com/derekwyatt/vim-scala +" Last Change: 2016 Aug 26 + +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal autoindent +setlocal indentexpr=GetScalaIndent() +setlocal indentkeys=0{,0},0),!^F,<>>,o,O,e,=case,<CR> + +if exists("*GetScalaIndent") + finish +endif +let s:keepcpo= &cpo +set cpo&vim + +let s:defMatcher = '\%(\%(private\|protected\)\%(\[[^\]]*\]\)\?\s\+\|abstract\s\+\|override\s\+\)*\<def\>' +let s:funcNameMatcher = '\w\+' +let s:typeSpecMatcher = '\%(\s*\[\_[^\]]*\]\)' +let s:defArgMatcher = '\%((\_.\{-})\)' +let s:returnTypeMatcher = '\%(:\s*\w\+' . s:typeSpecMatcher . '\?\)' +let g:fullDefMatcher = '^\s*' . s:defMatcher . '\s\+' . s:funcNameMatcher . '\s*' . s:typeSpecMatcher . '\?\s*' . s:defArgMatcher . '\?\s*' . s:returnTypeMatcher . '\?\s*[={]' + +function! scala#ConditionalConfirm(msg) + if 0 + call confirm(a:msg) + endif +endfunction + +function! scala#GetLine(lnum) + let line = substitute(getline(a:lnum), '//.*$', '', '') + let line = substitute(line, '"\(.\|\\"\)\{-}"', '""', 'g') + return line +endfunction + +function! scala#CountBrackets(line, openBracket, closedBracket) + let line = substitute(a:line, '"\(.\|\\"\)\{-}"', '', 'g') + let open = substitute(line, '[^' . a:openBracket . ']', '', 'g') + let close = substitute(line, '[^' . a:closedBracket . ']', '', 'g') + return strlen(open) - strlen(close) +endfunction + +function! scala#CountParens(line) + return scala#CountBrackets(a:line, '(', ')') +endfunction + +function! scala#CountCurlies(line) + return scala#CountBrackets(a:line, '{', '}') +endfunction + +function! scala#LineEndsInIncomplete(line) + if a:line =~ '[.,]\s*$' + return 1 + else + return 0 + endif +endfunction + +function! scala#LineIsAClosingXML(line) + if a:line =~ '^\s*</\w' + return 1 + else + return 0 + endif +endfunction + +function! scala#LineCompletesXML(lnum, line) + let savedpos = getpos('.') + call setpos('.', [savedpos[0], a:lnum, 0, savedpos[3]]) + let tag = substitute(a:line, '^.*</\([^>]*\)>.*$', '\1', '') + let [lineNum, colnum] = searchpairpos('<' . tag . '>', '', '</' . tag . '>', 'Wbn') + call setpos('.', savedpos) + let pline = scala#GetLine(prevnonblank(lineNum - 1)) + if pline =~ '=\s*$' + return 1 + else + return 0 + endif +endfunction + +function! scala#IsParentCase() + let savedpos = getpos('.') + call setpos('.', [savedpos[0], savedpos[1], 0, savedpos[3]]) + let [l, c] = searchpos('^\s*\%(' . s:defMatcher . '\|\%(\<case\>\)\)', 'bnW') + let retvalue = -1 + if l != 0 && search('\%' . l . 'l\s*\<case\>', 'bnW') + let retvalue = l + endif + call setpos('.', savedpos) + return retvalue +endfunction + +function! scala#CurlyMatcher() + let matchline = scala#GetLineThatMatchesBracket('{', '}') + if scala#CountParens(scala#GetLine(matchline)) < 0 + let savedpos = getpos('.') + call setpos('.', [savedpos[0], matchline, 9999, savedpos[3]]) + call searchpos('{', 'Wbc') + call searchpos(')', 'Wb') + let [lnum, colnum] = searchpairpos('(', '', ')', 'Wbn') + call setpos('.', savedpos) + let line = scala#GetLine(lnum) + if line =~ '^\s*' . s:defMatcher + return lnum + else + return matchline + endif + else + return matchline + endif +endfunction + +function! scala#GetLineAndColumnThatMatchesCurly() + return scala#GetLineAndColumnThatMatchesBracket('{', '}') +endfunction + +function! scala#GetLineAndColumnThatMatchesParen() + return scala#GetLineAndColumnThatMatchesBracket('(', ')') +endfunction + +function! scala#GetLineAndColumnThatMatchesBracket(openBracket, closedBracket) + let savedpos = getpos('.') + let curline = scala#GetLine(line('.')) + if curline =~ a:closedBracket . '.*' . a:openBracket . '.*' . a:closedBracket + call setpos('.', [savedpos[0], savedpos[1], 0, savedpos[3]]) + call searchpos(a:closedBracket . '\ze[^' . a:closedBracket . a:openBracket . ']*' . a:openBracket, 'W') + else + call setpos('.', [savedpos[0], savedpos[1], 9999, savedpos[3]]) + call searchpos(a:closedBracket, 'Wbc') + endif + let [lnum, colnum] = searchpairpos(a:openBracket, '', a:closedBracket, 'Wbn') + call setpos('.', savedpos) + return [lnum, colnum] +endfunction + +function! scala#GetLineThatMatchesCurly() + return scala#GetLineThatMatchesBracket('{', '}') +endfunction + +function! scala#GetLineThatMatchesParen() + return scala#GetLineThatMatchesBracket('(', ')') +endfunction + +function! scala#GetLineThatMatchesBracket(openBracket, closedBracket) + let [lnum, colnum] = scala#GetLineAndColumnThatMatchesBracket(a:openBracket, a:closedBracket) + return lnum +endfunction + +function! scala#NumberOfBraceGroups(line) + let line = substitute(a:line, '[^()]', '', 'g') + if strlen(line) == 0 + return 0 + endif + let line = substitute(line, '^)*', '', 'g') + if strlen(line) == 0 + return 0 + endif + let line = substitute(line, '^(', '', 'g') + if strlen(line) == 0 + return 0 + endif + let c = 1 + let counter = 0 + let groupCount = 0 + while counter < strlen(line) + let char = strpart(line, counter, 1) + if char == '(' + let c = c + 1 + elseif char == ')' + let c = c - 1 + endif + if c == 0 + let groupCount = groupCount + 1 + endif + let counter = counter + 1 + endwhile + return groupCount +endfunction + +function! scala#MatchesIncompleteDefValr(line) + if a:line =~ '^\s*\%(' . s:defMatcher . '\|\<va[lr]\>\).*[=({]\s*$' + return 1 + else + return 0 + endif +endfunction + +function! scala#LineIsCompleteIf(line) + if scala#CountBrackets(a:line, '{', '}') == 0 && + \ scala#CountBrackets(a:line, '(', ')') == 0 && + \ a:line =~ '^\s*\<if\>\s*([^)]*)\s*\S.*$' + return 1 + else + return 0 + endif +endfunction + +function! scala#LineCompletesIfElse(lnum, line) + if a:line =~ '^\s*\%(\<if\>\|\%(}\s*\)\?\<else\>\)' + return 0 + endif + let result = search('^\%(\s*\<if\>\s*(.*).*\n\|\s*\<if\>\s*(.*)\s*\n.*\n\)\%(\s*\<else\>\s*\<if\>\s*(.*)\s*\n.*\n\)*\%(\s*\<else\>\s*\n\|\s*\<else\>[^{]*\n\)\?\%' . a:lnum . 'l', 'Wbn') + if result != 0 && scala#GetLine(prevnonblank(a:lnum - 1)) !~ '{\s*$' + return result + endif + return 0 +endfunction + +function! scala#GetPrevCodeLine(lnum) + " This needs to skip comment lines + return prevnonblank(a:lnum - 1) +endfunction + +function! scala#InvertBracketType(openBracket, closedBracket) + if a:openBracket == '(' + return [ '{', '}' ] + else + return [ '(', ')' ] + endif +endfunction + +function! scala#Testhelper(lnum, line, openBracket, closedBracket, iteration) + let bracketCount = scala#CountBrackets(a:line, a:openBracket, a:closedBracket) + " There are more '}' braces than '{' on this line so it may be completing the function definition + if bracketCount < 0 + let [matchedLNum, matchedColNum] = scala#GetLineAndColumnThatMatchesBracket(a:openBracket, a:closedBracket) + if matchedLNum == a:lnum + return -1 + endif + let matchedLine = scala#GetLine(matchedLNum) + if ! scala#MatchesIncompleteDefValr(matchedLine) + let bracketLine = substitute(substitute(matchedLine, '\%' . matchedColNum . 'c.*$', '', ''), '[^{}()]', '', 'g') + if bracketLine =~ '}$' + return scala#Testhelper(matchedLNum, matchedLine, '{', '}', a:iteration + 1) + elseif bracketLine =~ ')$' + return scala#Testhelper(matchedLNum, matchedLine, '(', ')', a:iteration + 1) + else + let prevCodeLNum = scala#GetPrevCodeLine(matchedLNum) + if scala#MatchesIncompleteDefValr(scala#GetLine(prevCodeLNum)) + return prevCodeLNum + else + return -1 + endif + endif + else + " return indent value instead + return matchedLNum + endif + " There's an equal number of '{' and '}' on this line so it may be a single line function definition + elseif bracketCount == 0 + if a:iteration == 0 + let otherBracketType = scala#InvertBracketType(a:openBracket, a:closedBracket) + return scala#Testhelper(a:lnum, a:line, otherBracketType[0], otherBracketType[1], a:iteration + 1) + else + let prevCodeLNum = scala#GetPrevCodeLine(a:lnum) + let prevCodeLine = scala#GetLine(prevCodeLNum) + if scala#MatchesIncompleteDefValr(prevCodeLine) && prevCodeLine !~ '{\s*$' + return prevCodeLNum + else + let possibleIfElse = scala#LineCompletesIfElse(a:lnum, a:line) + if possibleIfElse != 0 + let defValrLine = prevnonblank(possibleIfElse - 1) + let possibleDefValr = scala#GetLine(defValrLine) + if scala#MatchesIncompleteDefValr(possibleDefValr) && possibleDefValr =~ '^.*=\s*$' + return possibleDefValr + else + return -1 + endif + else + return -1 + endif + endif + endif + else + return -1 + endif +endfunction + +function! scala#Test(lnum, line, openBracket, closedBracket) + return scala#Testhelper(a:lnum, a:line, a:openBracket, a:closedBracket, 0) +endfunction + +function! scala#LineCompletesDefValr(lnum, line) + let bracketCount = scala#CountBrackets(a:line, '{', '}') + if bracketCount < 0 + let matchedBracket = scala#GetLineThatMatchesBracket('{', '}') + if ! scala#MatchesIncompleteDefValr(scala#GetLine(matchedBracket)) + let possibleDefValr = scala#GetLine(prevnonblank(matchedBracket - 1)) + if matchedBracket != -1 && scala#MatchesIncompleteDefValr(possibleDefValr) + return 1 + else + return 0 + endif + else + return 0 + endif + elseif bracketCount == 0 + let bracketCount = scala#CountBrackets(a:line, '(', ')') + if bracketCount < 0 + let matchedBracket = scala#GetLineThatMatchesBracket('(', ')') + if ! scala#MatchesIncompleteDefValr(scala#GetLine(matchedBracket)) + let possibleDefValr = scala#GetLine(prevnonblank(matchedBracket - 1)) + if matchedBracket != -1 && scala#MatchesIncompleteDefValr(possibleDefValr) + return 1 + else + return 0 + endif + else + return 0 + endif + elseif bracketCount == 0 + let possibleDefValr = scala#GetLine(prevnonblank(a:lnum - 1)) + if scala#MatchesIncompleteDefValr(possibleDefValr) && possibleDefValr =~ '^.*=\s*$' + return 1 + else + let possibleIfElse = scala#LineCompletesIfElse(a:lnum, a:line) + if possibleIfElse != 0 + let possibleDefValr = scala#GetLine(prevnonblank(possibleIfElse - 1)) + if scala#MatchesIncompleteDefValr(possibleDefValr) && possibleDefValr =~ '^.*=\s*$' + return 2 + else + return 0 + endif + else + return 0 + endif + endif + else + return 0 + endif + endif +endfunction + +function! scala#SpecificLineCompletesBrackets(lnum, openBracket, closedBracket) + let savedpos = getpos('.') + call setpos('.', [savedpos[0], a:lnum, 9999, savedpos[3]]) + let retv = scala#LineCompletesBrackets(a:openBracket, a:closedBracket) + call setpos('.', savedpos) + + return retv +endfunction + +function! scala#LineCompletesBrackets(openBracket, closedBracket) + let savedpos = getpos('.') + let offline = 0 + while offline == 0 + let [lnum, colnum] = searchpos(a:closedBracket, 'Wb') + let [lnumA, colnumA] = searchpairpos(a:openBracket, '', a:closedBracket, 'Wbn') + if lnum != lnumA + let [lnumB, colnumB] = searchpairpos(a:openBracket, '', a:closedBracket, 'Wbnr') + let offline = 1 + endif + endwhile + call setpos('.', savedpos) + if lnumA == lnumB && colnumA == colnumB + return lnumA + else + return -1 + endif +endfunction + +function! GetScalaIndent() + " Find a non-blank line above the current line. + let prevlnum = prevnonblank(v:lnum - 1) + + " Hit the start of the file, use zero indent. + if prevlnum == 0 + return 0 + endif + + let ind = indent(prevlnum) + let originalIndentValue = ind + let prevline = scala#GetLine(prevlnum) + let curlnum = v:lnum + let curline = scala#GetLine(curlnum) + if get(g:, 'scala_scaladoc_indent', 0) + let star_indent = 2 + else + let star_indent = 1 + end + + if prevline =~ '^\s*/\*\*' + if prevline =~ '\*/\s*$' + return ind + else + return ind + star_indent + endif + endif + + if curline =~ '^\s*\*' + return cindent(curlnum) + endif + + " If this line starts with a { then make it indent the same as the previous line + if curline =~ '^\s*{' + call scala#ConditionalConfirm("1") + " Unless, of course, the previous one is a { as well + if prevline !~ '^\s*{' + call scala#ConditionalConfirm("2") + return indent(prevlnum) + endif + endif + + " '.' continuations + if curline =~ '^\s*\.' + if prevline =~ '^\s*\.' + return ind + else + return ind + &shiftwidth + endif + endif + + " Indent html literals + if prevline !~ '/>\s*$' && prevline =~ '^\s*<[a-zA-Z][^>]*>\s*$' + call scala#ConditionalConfirm("3") + return ind + &shiftwidth + endif + + " assumes curly braces around try-block + if curline =~ '^\s*}\s*\<catch\>' + return ind - &shiftwidth + elseif curline =~ '^\s*\<catch\>' + return ind + endif + + " Add a 'shiftwidth' after lines that start a block + " If 'if', 'for' or 'while' end with ), this is a one-line block + " If 'val', 'var', 'def' end with =, this is a one-line block + if (prevline =~ '^\s*\<\%(\%(}\?\s*else\s\+\)\?if\|for\|while\)\>.*[)=]\s*$' && scala#NumberOfBraceGroups(prevline) <= 1) + \ || prevline =~ '^\s*' . s:defMatcher . '.*=\s*$' + \ || prevline =~ '^\s*\<va[lr]\>.*[=]\s*$' + \ || prevline =~ '^\s*\%(}\s*\)\?\<else\>\s*$' + \ || prevline =~ '=\s*$' + call scala#ConditionalConfirm("4") + let ind = ind + &shiftwidth + elseif prevline =~ '^\s*\<\%(}\?\s*else\s\+\)\?if\>' && curline =~ '^\s*}\?\s*\<else\>' + return ind + endif + + let lineCompletedBrackets = 0 + let bracketCount = scala#CountBrackets(prevline, '{', '}') + if bracketCount > 0 || prevline =~ '.*{\s*$' + call scala#ConditionalConfirm("5b") + let ind = ind + &shiftwidth + elseif bracketCount < 0 + call scala#ConditionalConfirm("6b") + " if the closing brace actually completes the braces entirely, then we + " have to indent to line that started the whole thing + let completeLine = scala#LineCompletesBrackets('{', '}') + if completeLine != -1 + call scala#ConditionalConfirm("8b") + let prevCompleteLine = scala#GetLine(prevnonblank(completeLine - 1)) + " However, what actually started this part looks like it was a function + " definition, so we need to indent to that line instead. This is + " actually pretty weak at the moment. + if prevCompleteLine =~ '=\s*$' + call scala#ConditionalConfirm("9b") + let ind = indent(prevnonblank(completeLine - 1)) + else + call scala#ConditionalConfirm("10b") + let ind = indent(completeLine) + endif + else + let lineCompletedBrackets = 1 + endif + endif + + if ind == originalIndentValue + let bracketCount = scala#CountBrackets(prevline, '(', ')') + if bracketCount > 0 || prevline =~ '.*(\s*$' + call scala#ConditionalConfirm("5a") + let ind = ind + &shiftwidth + elseif bracketCount < 0 + call scala#ConditionalConfirm("6a") + " if the closing brace actually completes the braces entirely, then we + " have to indent to line that started the whole thing + let completeLine = scala#LineCompletesBrackets('(', ')') + if completeLine != -1 && prevline !~ '^.*{\s*$' + call scala#ConditionalConfirm("8a") + let prevCompleteLine = scala#GetLine(prevnonblank(completeLine - 1)) + " However, what actually started this part looks like it was a function + " definition, so we need to indent to that line instead. This is + " actually pretty weak at the moment. + if prevCompleteLine =~ '=\s*$' + call scala#ConditionalConfirm("9a") + let ind = indent(prevnonblank(completeLine - 1)) + else + call scala#ConditionalConfirm("10a") + let ind = indent(completeLine) + endif + else + " This is the only part that's different from from the '{', '}' one below + " Yup... some refactoring is necessary at some point. + let ind = ind + (bracketCount * &shiftwidth) + let lineCompletedBrackets = 1 + endif + endif + endif + + if curline =~ '^\s*}\?\s*\<else\>\%(\s\+\<if\>\s*(.*)\)\?\s*{\?\s*$' && + \ ! scala#LineIsCompleteIf(prevline) && + \ prevline !~ '^.*}\s*$' + let ind = ind - &shiftwidth + endif + + " Subtract a 'shiftwidth' on '}' or html + let curCurlyCount = scala#CountCurlies(curline) + if curCurlyCount < 0 + call scala#ConditionalConfirm("14a") + let matchline = scala#CurlyMatcher() + return indent(matchline) + elseif curline =~ '^\s*</[a-zA-Z][^>]*>' + call scala#ConditionalConfirm("14c") + return ind - &shiftwidth + endif + + let prevParenCount = scala#CountParens(prevline) + if prevline =~ '^\s*\<for\>.*$' && prevParenCount > 0 + call scala#ConditionalConfirm("15") + let ind = indent(prevlnum) + 5 + endif + + let prevCurlyCount = scala#CountCurlies(prevline) + if prevCurlyCount == 0 && prevline =~ '^.*\%(=>\|⇒\)\s*$' && prevline !~ '^\s*this\s*:.*\%(=>\|⇒\)\s*$' && curline !~ '^\s*\<case\>' + call scala#ConditionalConfirm("16") + let ind = ind + &shiftwidth + endif + + if ind == originalIndentValue && curline =~ '^\s*\<case\>' + call scala#ConditionalConfirm("17") + let parentCase = scala#IsParentCase() + if parentCase != -1 + call scala#ConditionalConfirm("17a") + return indent(parentCase) + endif + endif + + if prevline =~ '^\s*\*/' + \ || prevline =~ '*/\s*$' + call scala#ConditionalConfirm("18") + let ind = ind - star_indent + endif + + if scala#LineEndsInIncomplete(prevline) + call scala#ConditionalConfirm("19") + return ind + endif + + if scala#LineIsAClosingXML(prevline) + if scala#LineCompletesXML(prevlnum, prevline) + call scala#ConditionalConfirm("20a") + return ind - &shiftwidth + else + call scala#ConditionalConfirm("20b") + return ind + endif + endif + + if ind == originalIndentValue + "let indentMultiplier = scala#LineCompletesDefValr(prevlnum, prevline) + "if indentMultiplier != 0 + " call scala#ConditionalConfirm("19a") + " let ind = ind - (indentMultiplier * &shiftwidth) + let defValrLine = scala#Test(prevlnum, prevline, '{', '}') + if defValrLine != -1 + call scala#ConditionalConfirm("21a") + let ind = indent(defValrLine) + elseif lineCompletedBrackets == 0 + call scala#ConditionalConfirm("21b") + if scala#GetLine(prevnonblank(prevlnum - 1)) =~ '^.*\<else\>\s*\%(//.*\)\?$' + call scala#ConditionalConfirm("21c") + let ind = ind - &shiftwidth + elseif scala#LineCompletesIfElse(prevlnum, prevline) + call scala#ConditionalConfirm("21d") + let ind = ind - &shiftwidth + elseif scala#CountParens(curline) < 0 && curline =~ '^\s*)' && scala#GetLine(scala#GetLineThatMatchesBracket('(', ')')) =~ '.*(\s*$' + " Handles situations that look like this: + " + " val a = func( + " 10 + " ) + " + " or + " + " val a = func( + " 10 + " ).somethingHere() + call scala#ConditionalConfirm("21e") + let ind = ind - &shiftwidth + endif + endif + endif + + call scala#ConditionalConfirm("returning " . ind) + + return ind +endfunction + +let &cpo = s:keepcpo +unlet s:keepcpo + +" vim:set sw=2 sts=2 ts=8 et: +" vim600:fdm=marker fdl=1 fdc=0: |