diff options
Diffstat (limited to '')
| -rw-r--r-- | indent/blade.vim | 94 | ||||
| -rw-r--r-- | indent/eelixir.vim | 5 | ||||
| -rw-r--r-- | indent/elixir.vim | 53 | ||||
| -rw-r--r-- | indent/swift.vim | 30 | ||||
| -rw-r--r-- | indent/typescript.vim | 524 | 
5 files changed, 548 insertions, 158 deletions
| diff --git a/indent/blade.vim b/indent/blade.vim index 8327f451..78a8a78c 100644 --- a/indent/blade.vim +++ b/indent/blade.vim @@ -1,66 +1,50 @@  if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'blade') == -1 -" Language:     Blade -" Author:       Barry Deeney <sitemaster16@gmail.com> -" Version:      0.1 -" Description:  BLADE indent file based on HTML indentation... +" Vim indent file +" Language:     Blade (Laravel) +" Maintainer:   Jason Walton <jwalton512@gmail.com> -" Check if this file has already been loaded  if exists("b:did_indent") -	finish +    finish  endif - -" Include HTML  runtime! indent/html.vim -runtime! indent/php.vim -silent! unlet b:did_indent - -" What function do we need to use to detect indentation? -setlocal indentexpr=BladeIndent() - -" What keys would trigger indentation? -setlocal indentkeys=o,O,<Return>,<>>,{,},!^F,0{,0},0),:,!^F,o,O,e,*<Return>,=?>,=<?,=*/ - -" THE MAIN INDENT FUNCTION. Return the amount of indent for v:lnum. -func! BladeIndent() -	" What is the current line? -	let current_line = v:lnum - -	" What is the current text? -	let current_text = tolower(getline(current_line)) - -	" What was the last non blank line? -	let previous_line = prevnonblank(current_line) - -	" What was the last non blank text? -	let previous_text = tolower(getline(previous_line)) - -	" How large are indents?? -	let indent_size = &sw - -	" Check if we have a PHPIndent value... -	let indent = GetPhpIndent() - -	" check if we have indent -	if indent == -1 -		" Check if we have BLADE -		if current_text =~ '^\s*@' || previous_text =~ '^\s*@' -			" We need to add to the indent -			return indent_size * indent(previous_text) -		endif +unlet! b:did_indent +let b:did_indent = 1 -		" Check if we have HTML -		if current_text =~ '^\s*<' || previous_text =~ '^\s*<' -			" We now give the honors to HtmlIndent() -			let indent = HtmlIndent() -		endif -	endif +setlocal autoindent +setlocal indentexpr=GetBladeIndent() +setlocal indentkeys=o,O,*<Return>,<>>,!^F,=@else,=@end,=@empty -	" Give the indent back! -	return indent -endfunc +" Only define the function once. +if exists("*GetBladeIndent") +    finish +endif -" Make sure we store that flag! -let b:did_indent = 1 +function! GetBladeIndent() +    let lnum = prevnonblank(v:lnum-1) +    if lnum == 0 +        return 0 +    endif + +    let line = substitute(substitute(getline(lnum), '\s\+$', '', ''), '^\s\+', '', '') +    let cline = substitute(substitute(getline(v:lnum), '\s\+$', '', ''), '^\s\+', '', '') +    let indent = indent(lnum) +    let cindent = indent(v:lnum) +    if cline =~# '@\%(else\|elseif\|empty\|end\)' +        let indent = cindent < indent ? cindent : indent - &sw +    elseif HtmlIndent() > -1 +        let indent = HtmlIndent() +    endif +    let increase = indent + &sw +    if indent = indent(lnum) +        let indent = cindent <= indent ? -1 : increase +    endif + +    if line =~# '@\%(if\|elseif\|else\|unless\|foreach\|forelse\|for\|while\)\%(.*\s*@end\)\@!' +        return increase +    else +        return indent +    endif +endfunction  endif diff --git a/indent/eelixir.vim b/indent/eelixir.vim index c5e2491e..d9538425 100644 --- a/indent/eelixir.vim +++ b/indent/eelixir.vim @@ -1,10 +1,5 @@  if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'elixir') == -1 -" Vim indent file -" Language: Embedded Elixir -" URL:      https://github.com/elixir-lang/vim-elixir - -  if exists("b:did_indent")    finish  endif diff --git a/indent/elixir.vim b/indent/elixir.vim index 863104d3..58179973 100644 --- a/indent/elixir.vim +++ b/indent/elixir.vim @@ -1,10 +1,5 @@  if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'elixir') == -1 -" Vim indent file -" Language: Elixir -" Maintainer: Carlos Galdino <carloshsgaldino@gmail.com> -" Last Change: 2013 Apr 24 -  if exists("b:did_indent")    finish  endif @@ -13,7 +8,7 @@ let b:did_indent = 1  setlocal nosmartindent  setlocal indentexpr=GetElixirIndent() -setlocal indentkeys+=0=end,0=else,0=match,0=elsif,0=catch,0=after,0=rescue +setlocal indentkeys+=0),0],0=end,0=else,0=match,0=elsif,0=catch,0=after,0=rescue  if exists("*GetElixirIndent")    finish @@ -22,17 +17,23 @@ endif  let s:cpo_save = &cpo  set cpo&vim -let s:skip_syntax  = '\%(Comment\|String\)$' -let s:block_skip   = "synIDattr(synID(line('.'),col('.'),1),'name') =~? '" . s:skip_syntax . "'" -let s:block_start  = 'do\|fn' -let s:block_middle = 'else\|match\|elsif\|catch\|after\|rescue' -let s:block_end    = 'end' -let s:symbols_end  = '\]\|}' -let s:arrow        = '^.*->$' -let s:pipeline     = '^\s*|>.*$' +let s:no_colon_before = ':\@<!' +let s:no_colon_after  = ':\@!' +let s:symbols_end     = '\]\|}' +let s:arrow           = '^.*->$' +let s:pipeline        = '^\s*|>.*$' +let s:skip_syntax     = '\%(Comment\|String\)$' +let s:block_skip      = "synIDattr(synID(line('.'),col('.'),1),'name') =~? '".s:skip_syntax."'" +let s:block_start     = 'do\|fn' +let s:block_middle    = 'else\|match\|elsif\|catch\|after\|rescue' +let s:block_end       = 'end' + +let s:indent_keywords   = '\<'.s:no_colon_before.'\%('.s:block_start.'\|'.s:block_middle.'\)$'.'\|'.s:arrow +let s:deindent_keywords = '^\s*\<\%('.s:block_end.'\|'.s:block_middle.'\)\>'.'\|'.s:arrow -let s:indent_keywords   = '\<\%(' . s:block_start . '\|' . s:block_middle . '\)$' . '\|' . s:arrow -let s:deindent_keywords = '^\s*\<\%(' . s:block_end . '\|' . s:block_middle . '\)\>' . '\|' . s:arrow +let s:pair_start  = '\<\%('.s:no_colon_before.s:block_start.'\)\>'.s:no_colon_after +let s:pair_middle = '\<\%('.s:block_middle.'\)\>'.s:no_colon_after.'\zs' +let s:pair_end    = '\<\%('.s:no_colon_before.s:block_end.'\)\>\zs'  function! GetElixirIndent()    let lnum = prevnonblank(v:lnum - 1) @@ -60,20 +61,16 @@ function! GetElixirIndent()      let opened_symbol += count(splited_line, '[') - count(splited_line, ']')      let opened_symbol += count(splited_line, '{') - count(splited_line, '}') -    let ind += opened_symbol * &sw +    let ind += (opened_symbol * &sw) -    if last_line =~ '^\s*\(' . s:symbols_end . '\)' +    if last_line =~ '^\s*\('.s:symbols_end.'\)' || last_line =~ s:indent_keywords        let ind += &sw      endif -    if current_line =~ '^\s*\(' . s:symbols_end . '\)' +    if current_line =~ '^\s*\('.s:symbols_end.'\)'        let ind -= &sw      endif -    if last_line =~ s:indent_keywords -      let ind += &sw -    endif -      " if line starts with pipeline      " and last line contains pipeline(s)      " align them @@ -99,11 +96,13 @@ function! GetElixirIndent()      endif      if current_line =~ s:deindent_keywords -      let bslnum = searchpair( '\<\%(' . s:block_start . '\):\@!\>', -            \ '\<\%(' . s:block_middle . '\):\@!\>\zs', -            \ '\<:\@<!' . s:block_end . '\>\zs', +      let bslnum = searchpair( +            \ s:pair_start, +            \ s:pair_middle, +            \ s:pair_end,              \ 'nbW', -            \ s:block_skip ) +            \ s:block_skip +            \ )        let ind = indent(bslnum)      endif diff --git a/indent/swift.vim b/indent/swift.vim index ba6d65ea..773e6451 100644 --- a/indent/swift.vim +++ b/indent/swift.vim @@ -14,7 +14,6 @@ let s:cpo_save = &cpo  set cpo&vim  setlocal nosmartindent -setlocal indentkeys-=:  setlocal indentkeys-=e  setlocal indentkeys+=0]  setlocal indentexpr=SwiftIndent() @@ -95,11 +94,13 @@ function! SwiftIndent(...)        return -1      endif -    return indent(openingSquare) -  endif +    " - Line starts with closing square, indent as opening square +    if line =~ '\v^\s*]' +      return indent(openingSquare) +    endif -  if s:IsExcludedFromIndent() -    return previousIndent +    " - Line contains closing square and more, indent a level above opening +    return indent(openingSquare) + shiftwidth()    endif    if line =~ ":$" @@ -153,7 +154,8 @@ function! SwiftIndent(...)        endif        return indent(openingBracket)      else -      return -1 +      " - Current line is blank, and the user presses 'o' +      return previousIndent      endif    endif @@ -195,7 +197,7 @@ function! SwiftIndent(...)        endif        let previousParen = match(previous, "(") -      return previousParen + 1 +      return indent(previousParen) + shiftwidth()      endif      if numOpenBrackets > numCloseBrackets @@ -207,6 +209,11 @@ function! SwiftIndent(...)        return indent(openingParen) + shiftwidth()      endif +    " - Previous line has close then open braces, indent previous + 1 'sw' +    if previous =~ "}.*{" +      return previousIndent + shiftwidth() +    endif +      let line = line(".")      let column = col(".")      call cursor(previousNum, column) @@ -216,9 +223,14 @@ function! SwiftIndent(...)      return indent(openingParen)    endif +  " - Line above has (unmatched) open paren, next line needs indent    if numOpenParens > 0 -    let previousParen = match(previous, "(") -    return previousParen + 1 +    let savePosition = getcurpos() +    " Must be at EOL because open paren has to be above (left of) the cursor +    call cursor(previousNum, col("$")) +    let previousParen = searchpair("(", "", ")", "bWn", "s:IsExcludedFromIndent()") +    call setpos(".", savePosition) +    return indent(previousParen) + shiftwidth()    endif    return cindent diff --git a/indent/typescript.vim b/indent/typescript.vim index 58dc7d03..ec4781a8 100644 --- a/indent/typescript.vim +++ b/indent/typescript.vim @@ -1,105 +1,505 @@  if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'typescript') == -1 -" Vim indent file, taken from indent/java.vim -" Language:	    Typescript -" Maintainer:	None!  Wanna improve this? -" Last Change:	2015 Mar 07 +" Vim indent file +" Language: Typescript +" Acknowledgement: Based off of vim-ruby maintained by Nikolai Weibull http://vim-ruby.rubyforge.org -if get(g:, 'typescript_indent_disable') -  finish -endif +" 0. Initialization {{{1 +" =================  " Only load this indent file when no other was loaded.  if exists("b:did_indent") -   finish +  finish  endif  let b:did_indent = 1 -" Use javascript cindent options -setlocal cindent cinoptions& cinoptions+=j1,J1 -setlocal indentkeys& +setlocal nosmartindent -" Load typescript indent function +" Now, set up our indentation expression and keys that trigger it.  setlocal indentexpr=GetTypescriptIndent() +setlocal formatexpr=Fixedgq(v:lnum,v:count) +setlocal indentkeys=0{,0},0),0],0\,,!^F,o,O,e -let b:undo_indent = "setl cin< cino< indentkeys< indentexpr<" - -" Only define the function once +" Only define the function once.  if exists("*GetTypescriptIndent") -    finish +  finish  endif -" Make sure we have vim capabilities -let s:keepcpo = &cpo +let s:cpo_save = &cpo  set cpo&vim -function! TypescriptPrevNonBlankOrComment(lnum) -    let pnum = prevnonblank(a:lnum) -    " skip any comments (either `//`, `/*` or `*`) -    while getline(pnum) =~ '^\s*\(\/\/\|\/\*\|\*\)' -        let pnum = prevnonblank(pnum-1) -    endwhile -    return pnum +" 1. Variables {{{1 +" ============ + +let s:ts_keywords = '^\s*\(break\|case\|catch\|continue\|debugger\|default\|delete\|do\|else\|finally\|for\|function\|if\|in\|instanceof\|new\|return\|switch\|this\|throw\|try\|typeof\|var\|void\|while\|with\)' + +" Regex of syntax group names that are or delimit string or are comments. +let s:syng_strcom = 'string\|regex\|comment\c' + +" Regex of syntax group names that are strings. +let s:syng_string = 'regex\c' + +" Regex of syntax group names that are strings or documentation. +let s:syng_multiline = 'comment\c' + +" Regex of syntax group names that are line comment. +let s:syng_linecom = 'linecomment\c' + +" Expression used to check whether we should skip a match with searchpair(). +let s:skip_expr = "synIDattr(synID(line('.'),col('.'),1),'name') =~ '".s:syng_strcom."'" + +let s:line_term = '\s*\%(\%(\/\/\).*\)\=$' + +" Regex that defines continuation lines, not including (, {, or [. +let s:continuation_regex = '\%([\\*+/.:]\|\%(<%\)\@<![=-]\|\W[|&?]\|||\|&&\|[^=]=[^=].*,\)' . s:line_term + +" Regex that defines continuation lines. +" TODO: this needs to deal with if ...: and so on +let s:msl_regex = s:continuation_regex + +let s:one_line_scope_regex = '\<\%(if\|else\|for\|while\)\>[^{;]*' . s:line_term + +" Regex that defines blocks. +let s:block_regex = '\%([{[]\)\s*\%(|\%([*@]\=\h\w*,\=\s*\)\%(,\s*[*@]\=\h\w*\)*|\)\=' . s:line_term + +let s:var_stmt = '^\s*var' + +let s:comma_first = '^\s*,' +let s:comma_last = ',\s*$' + +let s:ternary = '^\s\+[?|:]' +let s:ternary_q = '^\s\+?' + +" 2. Auxiliary Functions {{{1 +" ====================== + +" Check if the character at lnum:col is inside a string, comment, or is ascii. +function s:IsInStringOrComment(lnum, col) +  return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_strcom  endfunction -function GetTypescriptIndent() +" Check if the character at lnum:col is inside a string. +function s:IsInString(lnum, col) +  return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_string +endfunction + +" Check if the character at lnum:col is inside a multi-line comment. +function s:IsInMultilineComment(lnum, col) +  return !s:IsLineComment(a:lnum, a:col) && synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_multiline +endfunction + +" Check if the character at lnum:col is a line comment. +function s:IsLineComment(lnum, col) +  return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_linecom +endfunction -    " default value: trust cindent -    let ind = cindent(v:lnum) +" Find line above 'lnum' that isn't empty, in a comment, or in a string. +function s:PrevNonBlankNonString(lnum) +  let in_block = 0 +  let lnum = prevnonblank(a:lnum) +  while lnum > 0 +    " Go in and out of blocks comments as necessary. +    " If the line isn't empty (with opt. comment) or in a string, end search. +    let line = getline(lnum) +    if line =~ '/\*' +      if in_block +        let in_block = 0 +      else +        break +      endif +    elseif !in_block && line =~ '\*/' +      let in_block = 1 +    elseif !in_block && line !~ '^\s*\%(//\).*$' && !(s:IsInStringOrComment(lnum, 1) && s:IsInStringOrComment(lnum, strlen(line))) +      break +    endif +    let lnum = prevnonblank(lnum - 1) +  endwhile +  return lnum +endfunction -    if getline(v:lnum) =~ '^\s*[{}\*]' -        return ind +" Find line above 'lnum' that started the continuation 'lnum' may be part of. +function s:GetMSL(lnum, in_one_line_scope) +  " Start on the line we're at and use its indent. +  let msl = a:lnum +  let lnum = s:PrevNonBlankNonString(a:lnum - 1) +  while lnum > 0 +    " If we have a continuation line, or we're in a string, use line as MSL. +    " Otherwise, terminate search as we have found our MSL already. +    let line = getline(lnum) +    let col = match(line, s:msl_regex) + 1 +    if (col > 0 && !s:IsInStringOrComment(lnum, col)) || s:IsInString(lnum, strlen(line)) +      let msl = lnum +    else +      " Don't use lines that are part of a one line scope as msl unless the +      " flag in_one_line_scope is set to 1 +      " +      if a:in_one_line_scope +        break +      end +      let msl_one_line = s:Match(lnum, s:one_line_scope_regex) +      if msl_one_line == 0 +        break +      endif      endif +    let lnum = s:PrevNonBlankNonString(lnum - 1) +  endwhile +  return msl +endfunction + +function s:RemoveTrailingComments(content) +  let single = '\/\/\(.*\)\s*$' +  let multi = '\/\*\(.*\)\*\/\s*$' +  return substitute(substitute(a:content, single, '', ''), multi, '', '') +endfunction + +" Find if the string is inside var statement (but not the first string) +function s:InMultiVarStatement(lnum) +  let lnum = s:PrevNonBlankNonString(a:lnum - 1) -    " The last non-empty line -    let prev = TypescriptPrevNonBlankOrComment(v:lnum-1) +"  let type = synIDattr(synID(lnum, indent(lnum) + 1, 0), 'name') -    " Check if the previous line consists of a single `<variable> : <type>;` -    " declaration (e.g. in interface definitions) -    if getline(prev) =~ '^\s*\w\+\s*:[^{]\+;\s*$' -        return indent(prev) +  " loop through previous expressions to find a var statement +  while lnum > 0 +    let line = getline(lnum) + +    " if the line is a ts keyword +    if (line =~ s:ts_keywords) +      " check if the line is a var stmt +      " if the line has a comma first or comma last then we can assume that we +      " are in a multiple var statement +      if (line =~ s:var_stmt) +        return lnum +      endif + +      " other ts keywords, not a var +      return 0      endif -    " If the previous line starts with '@', we should have the same indent as -    " the previous one -    if getline(prev) =~ '^\s*@\S\+\s*$' -      return indent(prev) +    let lnum = s:PrevNonBlankNonString(lnum - 1) +  endwhile + +  " beginning of program, not a var +  return 0 +endfunction + +" Find line above with beginning of the var statement or returns 0 if it's not +" this statement +function s:GetVarIndent(lnum) +  let lvar = s:InMultiVarStatement(a:lnum) +  let prev_lnum = s:PrevNonBlankNonString(a:lnum - 1) + +  if lvar +    let line = s:RemoveTrailingComments(getline(prev_lnum)) + +    " if the previous line doesn't end in a comma, return to regular indent +    if (line !~ s:comma_last) +      return indent(prev_lnum) - &sw +    else +      return indent(lvar) + &sw      endif +  endif -    " If a var, let, or const was declared and the semicolon omitted, do not -    " indent the next line -    if getline(prev) =~ '^\s*\(var\|let\|const\)\s\+\w\+' -        return indent(prev) +  return -1 +endfunction + + +" Check if line 'lnum' has more opening brackets than closing ones. +function s:LineHasOpeningBrackets(lnum) +  let open_0 = 0 +  let open_2 = 0 +  let open_4 = 0 +  let line = getline(a:lnum) +  let pos = match(line, '[][(){}]', 0) +  while pos != -1 +    if !s:IsInStringOrComment(a:lnum, pos + 1) +      let idx = stridx('(){}[]', line[pos]) +      if idx % 2 == 0 +        let open_{idx} = open_{idx} + 1 +      else +        let open_{idx - 1} = open_{idx - 1} - 1 +      endif      endif +    let pos = match(line, '[][(){}]', pos + 1) +  endwhile +  return (open_0 > 0) . (open_2 > 0) . (open_4 > 0) +endfunction + +function s:Match(lnum, regex) +  let col = match(getline(a:lnum), a:regex) + 1 +  return col > 0 && !s:IsInStringOrComment(a:lnum, col) ? col : 0 +endfunction + +function s:IndentWithContinuation(lnum, ind, width) +  " Set up variables to use and search for MSL to the previous line. +  let p_lnum = a:lnum +  let lnum = s:GetMSL(a:lnum, 1) +  let line = getline(lnum) -    " If the line ended with a ',', we should have the same indent as -    " the previous one -    if getline(prev) =~ ',\s*$' -        return indent(prev) +  " If the previous line wasn't a MSL and is continuation return its indent. +  " TODO: the || s:IsInString() thing worries me a bit. +  if p_lnum != lnum +    if s:Match(p_lnum,s:continuation_regex)||s:IsInString(p_lnum,strlen(line)) +      return a:ind      endif +  endif -    " Try to find out whether the last `}` ended a `<variable> : {` block -    if getline(prev) =~ '};\s*$' -        " jump to matching `{` bracket -        call cursor(prev, 1) -        silent normal % +  " Set up more variables now that we know we aren't continuation bound. +  let msl_ind = indent(lnum) + +  " If the previous line ended with [*+/.-=], start a continuation that +  " indents an extra level. +  if s:Match(lnum, s:continuation_regex) +    if lnum == p_lnum +      return msl_ind + a:width +    else +      return msl_ind +    endif +  endif + +  return a:ind +endfunction + +function s:InOneLineScope(lnum) +  let msl = s:GetMSL(a:lnum, 1) +  if msl > 0 && s:Match(msl, s:one_line_scope_regex) +    return msl +  endif +  return 0 +endfunction -        " See if current line is type annotation without closing ';' but open -        " `{` bracket -        let lnum = line('.') -        if getline(lnum) =~ '^\s*\w\+\s*:[^;]\+{' -            let ind = indent(lnum) +function s:ExitingOneLineScope(lnum) +  let msl = s:GetMSL(a:lnum, 1) +  if msl > 0 +    " if the current line is in a one line scope .. +    if s:Match(msl, s:one_line_scope_regex) +      return 0 +    else +      let prev_msl = s:GetMSL(msl - 1, 1) +      if s:Match(prev_msl, s:one_line_scope_regex) +        return prev_msl +      endif +    endif +  endif +  return 0 +endfunction + +" 3. GetTypescriptIndent Function {{{1 +" ========================= + +function GetTypescriptIndent() +  " 3.1. Setup {{{2 +  " ---------- + +  " Set up variables for restoring position in file.  Could use v:lnum here. +  let vcol = col('.') + +  " 3.2. Work on the current line {{{2 +  " ----------------------------- + +  let ind = -1 +  " Get the current line. +  let line = getline(v:lnum) +  " previous nonblank line number +  let prevline = prevnonblank(v:lnum - 1) + +  " 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 && !s:IsInStringOrComment(v:lnum, col) +    call cursor(v:lnum, col) + +    let lvar = s:InMultiVarStatement(v:lnum) +    if lvar +      let prevline_contents = s:RemoveTrailingComments(getline(prevline)) + +      " check for comma first +      if (line[col - 1] =~ ',') +        " if the previous line ends in comma or semicolon don't indent +        if (prevline_contents =~ '[;,]\s*$') +          return indent(s:GetMSL(line('.'), 0)) +        " get previous line indent, if it's comma first return prevline indent +        elseif (prevline_contents =~ s:comma_first) +          return indent(prevline) +        " otherwise we indent 1 level +        else +          return indent(lvar) + &sw          endif +      endif      endif + +    let bs = strpart('(){}[]', stridx(')}]', line[col - 1]) * 2, 2) +    if searchpair(escape(bs[0], '\['), '', bs[1], 'bW', s:skip_expr) > 0 +      if line[col-1]==')' && col('.') != col('$') - 1 +        let ind = virtcol('.')-1 +      else +        let ind = indent(s:GetMSL(line('.'), 0)) +      endif +    endif      return ind +  endif + +  " If the line is comma first, dedent 1 level +  if (getline(prevline) =~ s:comma_first) +    return indent(prevline) - &sw +  endif + +  if (line =~ s:ternary) +    if (getline(prevline) =~ s:ternary_q) +      return indent(prevline) +    else +      return indent(prevline) + &sw +    endif +  endif + +  " If we are in a multi-line comment, cindent does the right thing. +  if s:IsInMultilineComment(v:lnum, 1) && !s:IsLineComment(v:lnum, 1) +    return cindent(v:lnum) +  endif + +  " Check for multiple var assignments +"  let var_indent = s:GetVarIndent(v:lnum) +"  if var_indent >= 0 +"    return var_indent +"  endif + +  " 3.3. Work on the previous line. {{{2 +  " ------------------------------- + +  " If the line is empty and the previous nonblank line was a multi-line +  " comment, use that comment's indent. Deduct one char to account for the +  " space in ' */'. +  if line =~ '^\s*$' && s:IsInMultilineComment(prevline, 1) +    return indent(prevline) - 1 +  endif + +  " Find a non-blank, non-multi-line string line above the current line. +  let lnum = s:PrevNonBlankNonString(v:lnum - 1) + +  " If the line is empty and inside a string, use the previous line. +  if line =~ '^\s*$' && lnum != prevline +    return indent(prevnonblank(v:lnum)) +  endif + +  " At the start of the file use zero indent. +  if lnum == 0 +    return 0 +  endif + +  " Set up variables for current line. +  let line = getline(lnum) +  let ind = indent(lnum) + +  " If the previous line ended with a block opening, add a level of indent. +  if s:Match(lnum, s:block_regex) +    return indent(s:GetMSL(lnum, 0)) + &sw +  endif + +  " If the previous line contained an opening bracket, and we are still in it, +  " add indent depending on the bracket type. +  if line =~ '[[({]' +    let counts = s:LineHasOpeningBrackets(lnum) +    if counts[0] == '1' && searchpair('(', '', ')', 'bW', s:skip_expr) > 0 +      if col('.') + 1 == col('$') +        return ind + &sw +      else +        return virtcol('.') +      endif +    elseif counts[1] == '1' || counts[2] == '1' +      return ind + &sw +    else +      call cursor(v:lnum, vcol) +    end +  endif + +  " 3.4. Work on the MSL line. {{{2 +  " -------------------------- +  let ind_con = ind +  let ind = s:IndentWithContinuation(lnum, ind_con, &sw) + +  " }}}2 +  " +  " +  let ols = s:InOneLineScope(lnum) +  if ols > 0 +    let ind = ind + &sw +  else +    let ols = s:ExitingOneLineScope(lnum) +    while ols > 0 && ind > 0 +      let ind = ind - &sw +      let ols = s:InOneLineScope(ols - 1) +    endwhile +  endif + +  return ind  endfunction -" Restore compatibility mode -let &cpo = s:keepcpo -unlet s:keepcpo +" }}}1 + +let &cpo = s:cpo_save +unlet s:cpo_save + +function! Fixedgq(lnum, count) +    let l:tw = &tw ? &tw : 80; + +    let l:count = a:count +    let l:first_char = indent(a:lnum) + 1 + +    if mode() == 'i' " gq was not pressed, but tw was set +        return 1 +    endif + +    " This gq is only meant to do code with strings, not comments +    if s:IsLineComment(a:lnum, l:first_char) || s:IsInMultilineComment(a:lnum, l:first_char) +        return 1 +    endif + +    if len(getline(a:lnum)) < l:tw && l:count == 1 " No need for gq +        return 1 +    endif + +    " Put all the lines on one line and do normal spliting after that +    if l:count > 1 +        while l:count > 1 +            let l:count -= 1 +            normal J +        endwhile +    endif + +    let l:winview = winsaveview() + +    call cursor(a:lnum, l:tw + 1) +    let orig_breakpoint = searchpairpos(' ', '', '\.', 'bcW', '', a:lnum) +    call cursor(a:lnum, l:tw + 1) +    let breakpoint = searchpairpos(' ', '', '\.', 'bcW', s:skip_expr, a:lnum) + +    " No need for special treatment, normal gq handles edgecases better +    if breakpoint[1] == orig_breakpoint[1] +        call winrestview(l:winview) +        return 1 +    endif + +    " Try breaking after string +    if breakpoint[1] <= indent(a:lnum) +        call cursor(a:lnum, l:tw + 1) +        let breakpoint = searchpairpos('\.', '', ' ', 'cW', s:skip_expr, a:lnum) +    endif -" vim: et + +    if breakpoint[1] != 0 +        call feedkeys("r\<CR>") +    else +        let l:count = l:count - 1 +    endif + +    " run gq on new lines +    if l:count == 1 +        call feedkeys("gqq") +    endif + +    return 0 +endfunction  endif | 
