From: Colin Patrick Mccabe Date: Wed, 21 May 2014 22:18:43 +0000 (-0700) Subject: scala.vim: use a simpler indent X-Git-Url: http://club.cc.cmu.edu/~cmccabe/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=27d1c82956c1270b89b8ad00a35b2a7457f72cba;p=cmccabe-etc scala.vim: use a simpler indent The more complex one was not working well with the Spark coding style. Signed-off-by: Colin McCabe --- diff --git a/.vim/indent/scala.vim b/.vim/indent/scala.vim index 9cdb0e8..23caf49 100644 --- a/.vim/indent/scala.vim +++ b/.vim/indent/scala.vim @@ -1,593 +1,13 @@ -" Vim indent file -" Language : Scala (http://scala-lang.org/) -" Original Author : Stefan Matthias Aust -" Modifications by : Derek Wyatt -" Last Change: 2011 Mar 19 (Derek Wyatt) +if exists("b:did_indent") + finish +endif -"if exists("b:did_indent") -" finish -"endif -"let b:did_indent = 1 +let b:did_indent = 1 -setlocal indentexpr=GetScalaIndent() -setlocal indentkeys=0{,0},0),!^F,<>>,o,O,e,=case, -setlocal autoindent +" 2-column indentation with soft tabs +set sw=2 +set ts=2 +set et -"if exists("*GetScalaIndent") -" finish -"endif - -let s:defMatcher = '\%(\%(private\|protected\)\%(\[[^\]]*\]\)\?\s\+\|abstract\s\+\|override\s\+\)*\' -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*]*\)>.*$', '\1', '') - let [lineNum, colnum] = searchpairpos('<' . 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 . '\|\%(\\)\)', 'bnW') - let retvalue = -1 - if l != 0 && search('\%' . l . 'l\s*\', '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('{', 'Wb') - 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, 'Wb') - 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 . '\|\\).*[=({]\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*\\s*([^)]*)\s*\S.*$' - return 1 - else - return 0 - endif -endfunction - -function! scala#LineCompletesIfElse(lnum, line) - if a:line =~ '^\s*\%(\\|\%(}\s*\)\?\\)' - return 0 - endif - let result = search('^\%(\s*\\s*(.*).*\n\|\s*\\s*(.*)\s*\n.*\n\)\%(\s*\\s*\\s*(.*)\s*\n.*\n\)*\%(\s*\\s*\n\|\s*\[^{]*\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 prevline =~ '^\s*/\*\*' - return ind + 1 - 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*\' - return ind - &shiftwidth - elseif curline =~ '^\s*\' - 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*\.*[=]\s*$' - \ || prevline =~ '^\s*\%(}\s*\)\?\\s*$' - \ || prevline =~ '=\s*$' - call scala#ConditionalConfirm("4") - let ind = ind + &shiftwidth - elseif prevline =~ '^\s*\<\%(}\?\s*else\s\+\)\?if\>' && curline =~ '^\s*}\?\s*\' - 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*\\%(\s\+\\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*]*>' - call scala#ConditionalConfirm("14c") - return ind - &shiftwidth - endif - - let prevParenCount = scala#CountParens(prevline) - if prevline =~ '^\s*\.*$' && 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*\' - call scala#ConditionalConfirm("16") - let ind = ind + &shiftwidth - endif - - if ind == originalIndentValue && curline =~ '^\s*\' - 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 - 1 - endif - - if scala#LineEndsInIncomplete(curline) - 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)) =~ '^.*\\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 -" vim:set ts=2 sts=2 sw=2: -" vim600:fdm=marker fdl=1 fdc=0: +" 80 column limit +set tw=100