summaryrefslogtreecommitdiffstats
path: root/indent
diff options
context:
space:
mode:
Diffstat (limited to 'indent')
-rw-r--r--indent/crystal.vim279
-rw-r--r--indent/ecrystal.vim3
-rw-r--r--indent/plantuml.vim2
3 files changed, 51 insertions, 233 deletions
diff --git a/indent/crystal.vim b/indent/crystal.vim
index 96cdd586..c69b2a28 100644
--- a/indent/crystal.vim
+++ b/indent/crystal.vim
@@ -1,21 +1,21 @@
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'crystal') == -1
+" Initialization {{{1
+" ==============
+
" Only load this indent file when no other was loaded.
if exists('b:did_indent')
finish
endif
+
let b:did_indent = 1
setlocal nosmartindent
" Now, set up our indentation expression and keys that trigger it.
setlocal indentexpr=GetCrystalIndent(v:lnum)
-setlocal indentkeys=0{,0},0),0],!^F,o,O,e,:,.
+setlocal indentkeys=0{,0},0),0],!^F,o,O,e,.
setlocal indentkeys+==end,=else,=elsif,=when,=ensure,=rescue
-setlocal indentkeys+==private,=protected
-
-let s:cpo_save = &cpo
-set cpo&vim
" Only define the function once.
if exists('*GetCrystalIndent')
@@ -26,7 +26,7 @@ endif
if exists('*shiftwidth')
let s:sw = function('shiftwidth')
else
- function s:sw()
+ function! s:sw()
return &shiftwidth
endfunction
endif
@@ -34,262 +34,81 @@ endif
" GetCrystalIndent Function {{{1
" =========================
-function GetCrystalIndent(...)
+function! GetCrystalIndent(...) abort
" Setup {{{2
" -----
+ let indent_info = {}
+
+ " The value of a single shift-width
+ let indent_info.sw = s:sw()
+
" For the current line, use the first argument if given, else v:lnum
- let clnum = a:0 ? a:1 : v:lnum
+ let indent_info.clnum = a:0 ? a:1 : v:lnum
+ let indent_info.cline = getline(indent_info.clnum)
- " Set up variables for restoring position in file
- let vcol = col('.')
+ " Set up variables for restoring position in file.
+ let indent_info.col = col('.')
" Work on the current line {{{2
" ------------------------
- " Get the current line.
- let line = getline(clnum)
- let ind = -1
+ for callback_name in g:crystal#indent#curr_line_callbacks
+ let indent = call(function(callback_name), [indent_info])
- " If we got a closing bracket on an empty line, find its match and indent
- " according to it. For parentheses we indent to its column - 1, for the
- " others we indent to the containing line's MSL's level. Return -1 if fail.
- let col = matchend(line, '^\s*[]})]')
- if col > 0 && !crystal#indent#IsInStringOrComment(clnum, col)
- call cursor(clnum, col)
- let bs = strpart('(){}[]', stridx(')}]', line[col - 1]) * 2, 2)
- if searchpair(escape(bs[0], '\['), '', bs[1], 'bW', g:crystal#indent#skip_expr)
- if line[col-1] ==# ')' && col('.') != col('$') - 1
- let ind = virtcol('.') - 1
- else
- let ind = indent(crystal#indent#GetMSL(line('.')))
- endif
+ if indent >= 0
+ return indent
endif
- return ind
- endif
-
- " If we have a deindenting keyword, find its match and indent to its level.
- " TODO: this is messy
- if crystal#indent#Match(clnum, g:crystal#indent#crystal_deindent_keywords)
- call cursor(clnum, 1)
- if searchpair(
- \ g:crystal#indent#end_start_regex,
- \ g:crystal#indent#end_middle_regex,
- \ g:crystal#indent#end_end_regex,
- \ 'bW', g:crystal#indent#skip_expr)
- let msl = crystal#indent#GetMSL(line('.'))
- let line = getline(line('.'))
-
- if strpart(line, 0, col('.') - 1) =~# '=\s*$' &&
- \ strpart(line, col('.') - 1, 2) !~# 'do'
- " assignment to case/begin/etc, on the same line, hanging indent
- let ind = virtcol('.') - 1
- elseif getline(msl) =~# '=\s*\(#.*\)\=$'
- " in the case of assignment to the msl, align to the starting line,
- " not to the msl
- let ind = indent(line('.'))
- else
- " align to the msl
- let ind = indent(msl)
- endif
- endif
- return ind
- endif
-
- " If we are in a multi-line string, don't do anything to it.
- if crystal#indent#IsInString(clnum, matchend(line, '^\s*') + 1)
- return indent('.')
- endif
-
- " If we are at the closing delimiter of a "<<" heredoc-style string, set the
- " indent to 0.
- if line =~# '^\k\+\s*$'
- \ && crystal#indent#IsInStringDelimiter(clnum, 1)
- \ && search('\V<<'.line, 'nbW')
- return 0
- endif
-
- " If the current line starts with a leading operator, add a level of indent.
- if crystal#indent#Match(clnum, g:crystal#indent#leading_operator_regex)
- return indent(crystal#indent#GetMSL(clnum)) + s:sw()
- endif
+ endfor
" Work on the previous line. {{{2
" --------------------------
- " Find a non-blank, non-multi-line string line above the current line.
- let lnum = crystal#indent#PrevNonBlankNonString(clnum - 1)
-
- " If the line is empty and inside a string, use the previous line.
- if line =~# '^\s*$' && lnum != prevnonblank(clnum - 1)
- return indent(prevnonblank(clnum))
- endif
-
- " At the start of the file use zero indent.
- if lnum == 0
- return 0
- endif
-
- " Set up variables for the previous line.
- let line = getline(lnum)
- let ind = indent(lnum)
+ " Special case: we don't need the real PrevNonBlank for an empty line
+ " inside a string. And that call can be quite expensive in that
+ " particular situation.
+ let indent = crystal#indent#EmptyInsideString(indent_info)
- if crystal#indent#Match(lnum, g:crystal#indent#continuable_regex) &&
- \ crystal#indent#Match(lnum, g:crystal#indent#continuation_regex)
- return indent(crystal#indent#GetMSL(lnum)) + s:sw() * 2
+ if indent >= 0
+ return indent
endif
- " If the previous line ended with a block opening, add a level of indent.
- if crystal#indent#Match(lnum, g:crystal#indent#block_regex)
- let msl = crystal#indent#GetMSL(lnum)
+ " Previous line number
+ let indent_info.plnum = crystal#indent#PrevNonBlank(indent_info.clnum - 1)
+ let indent_info.pline = getline(indent_info.plnum)
- if getline(msl) =~# '=\s*\(#.*\)\=$'
- " in the case of assignment to the msl, align to the starting line,
- " not to the msl
- let ind = indent(lnum) + s:sw()
- else
- let ind = indent(msl) + s:sw()
- endif
- return ind
- endif
-
- " If the previous line started with a leading operator, use its MSL's level
- " of indent
- if crystal#indent#Match(lnum, g:crystal#indent#leading_operator_regex)
- return indent(crystal#indent#GetMSL(lnum))
- endif
-
- " If the previous line ended with the "*" of a splat, add a level of indent
- if line =~ g:crystal#indent#splat_regex
- return indent(lnum) + s:sw()
- endif
+ for callback_name in g:crystal#indent#prev_line_callbacks
+ let indent = call(function(callback_name), [indent_info])
- " If the previous line contained unclosed opening brackets and we are still
- " in them, find the rightmost one and add indent depending on the bracket
- " type.
- "
- " If it contained hanging closing brackets, find the rightmost one, find its
- " match and indent according to that.
- if line =~# '[[({]' || line =~# '[])]\s*\%(#.*\)\=$'
- let [opening, closing] = crystal#indent#ExtraBrackets(lnum)
-
- if opening.pos != -1
- if opening.type ==# '(' && searchpair('(', '', ')', 'bW', g:crystal#indent#skip_expr)
- if col('.') + 1 == col('$')
- return ind + s:sw()
- else
- return virtcol('.')
- endif
- else
- let nonspace = matchend(line, '\S', opening.pos + 1) - 1
- return nonspace > 0 ? nonspace : ind + s:sw()
- endif
- elseif closing.pos != -1
- call cursor(lnum, closing.pos + 1)
- keepjumps normal! %
-
- if crystal#indent#Match(line('.'), g:crystal#indent#crystal_indent_keywords)
- return indent('.') + s:sw()
- else
- return indent('.')
- endif
- else
- call cursor(clnum, vcol)
- end
- endif
-
- " If the previous line ended with an "end", match that "end"s beginning's
- " indent.
- let col = crystal#indent#Match(lnum, g:crystal#indent#end_end_regex)
- if col
- call cursor(lnum, col)
- if searchpair(
- \ g:crystal#indent#end_start_regex,
- \ g:crystal#indent#end_middle_regex,
- \ g:crystal#indent#end_end_regex,
- \ 'bW',
- \ g:crystal#indent#skip_expr)
- let n = line('.')
- let ind = indent('.')
- let msl = crystal#indent#GetMSL(n)
- if msl != n
- let ind = indent(msl)
- end
- return ind
+ if indent >= 0
+ return indent
endif
- end
+ endfor
- let col = crystal#indent#Match(lnum, g:crystal#indent#crystal_indent_keywords)
- if col
- call cursor(lnum, col)
- let ind = virtcol('.') - 1 + s:sw()
- " TODO: make this better (we need to count them) (or, if a searchpair
- " fails, we know that something is lacking an end and thus we indent a
- " level
- if crystal#indent#Match(lnum, g:crystal#indent#end_end_regex)
- let ind = indent('.')
- endif
- return ind
- endif
-
- " Work on the MSL line. {{{2
- " ---------------------
-
- " Set up variables to use and search for MSL to the previous line.
- let p_lnum = lnum
- let lnum = crystal#indent#GetMSL(lnum)
-
- " If the previous line wasn't a MSL.
- if p_lnum != lnum
- " If previous line ends bracket and begins non-bracket continuation decrease indent by 1.
- if crystal#indent#Match(p_lnum, g:crystal#indent#bracket_switch_continuation_regex)
- return ind - 1
- " If previous line is a continuation return its indent.
- " TODO: the || crystal#indent#IsInString() thing worries me a bit.
- elseif crystal#indent#Match(p_lnum, g:crystal#indent#non_bracket_continuation_regex) ||
- \ crystal#indent#IsInString(p_lnum,strlen(line))
- return ind
- endif
- endif
+ " Work on the MSL. {{{2
+ " ----------------
- " Set up more variables, now that we know we wasn't continuation bound.
- let line = getline(lnum)
- let msl_ind = indent(lnum)
+ " Most Significant line based on the previous one -- in case it's a
+ " contination of something above
+ let indent_info.plnum_msl = crystal#indent#GetMSL(indent_info.plnum)
+ let indent_info.pline_msl = getline(indent_info.plnum_msl)
- " If the MSL line had an indenting keyword in it, add a level of indent.
- " TODO: this does not take into account contrived things such as
- " module Foo; class Bar; end
- if crystal#indent#Match(lnum, g:crystal#indent#crystal_indent_keywords)
- let ind = msl_ind + s:sw()
- if crystal#indent#Match(lnum, g:crystal#indent#end_end_regex)
- let ind = ind - s:sw()
- endif
- return ind
- endif
+ for callback_name in g:crystal#indent#msl_callbacks
+ let indent = call(function(callback_name), [indent_info])
- " If the previous line ended with an operator -- but wasn't a block
- " ending, closing bracket, or type declaration -- indent one extra
- " level.
- if crystal#indent#Match(lnum, g:crystal#indent#non_bracket_continuation_regex) &&
- \ !crystal#indent#Match(lnum, '^\s*\([\])}]\|end\)')
- if lnum == p_lnum
- let ind = msl_ind + s:sw()
- else
- let ind = msl_ind
+ if indent >= 0
+ return indent
endif
- return ind
- endif
+ endfor
" }}}2
- return ind
+ " By default, just return the previous line's indent
+ return indent(indent_info.plnum)
endfunction
" }}}1
-let &cpo = s:cpo_save
-unlet s:cpo_save
-
-" vim:set sw=2 sts=2 ts=8 et:
+" vim:sw=2 sts=2 ts=8 fdm=marker et:
endif
diff --git a/indent/ecrystal.vim b/indent/ecrystal.vim
index 0d474587..9826cd7c 100644
--- a/indent/ecrystal.vim
+++ b/indent/ecrystal.vim
@@ -71,8 +71,7 @@ let s:ecr_control_open = '<%%\@!-\=[=#]\@!'
let s:ecr_comment_open = '<%%\@!-\=#'
let s:ecr_indent_regex =
- \ '\<\%(if\|unless\|else\|elsif\|case\|for\|when\|while\|until\|begin\|do\|rescue\|ensure\|' .
- \ 'class\|module\|struct\|lib\|enum\|union\)\>'
+ \ '\<\%(if\|unless\|else\|elsif\|case\|when\|while\|until\|begin\|do\|rescue\|ensure\|\)\>'
let s:ecr_dedent_regex =
\ '\<\%(end\|else\|elsif\|when\|rescue\|ensure\)\>'
diff --git a/indent/plantuml.vim b/indent/plantuml.vim
index 0d17276e..0553e706 100644
--- a/indent/plantuml.vim
+++ b/indent/plantuml.vim
@@ -77,7 +77,7 @@ endfunction
function! s:getIncIndent() abort
" Function to determine the s:incIndent pattern
return
- \ '^\s*\%(class\|entity\|object\|interface\|partition\|rectangle\|enum\|namespace\|package\)\>.*{\s*$\|' .
+ \ '^\s*\%(artifact\|class\|cloud\|database\|entity\|enum\|file\|folder\|frame\|interface\|namespace\|node\|object\|package\|partition\|rectangle\|skinparam\|state\|storage\|together\)\>.*{\s*$\|' .
\ '^\s*\%(loop\|alt\|opt\|group\|critical\|else\|legend\|box\|if\|while\|fork\|split\)\>\|' .
\ '^\s*ref\>[^:]*$\|' .
\ '^\s*[hr]\?note\>\%(\%("[^"]*" \<as\>\)\@![^:]\)*$\|' .