@@ -15,7 +15,7 @@ setlocal nosmartindent
1515
1616" Now, set up our indentation expression and keys that trigger it.
1717setlocal indentexpr = GetJavascriptIndent ()
18- setlocal indentkeys = 0 {,0 },0 ),0 ],! ^F,o ,O,e
18+ setlocal indentkeys = 0 {,0 },0 ),0 ],0 \, , ! ^F,o ,O,e
1919
2020" Only define the function once.
2121if exists (" *GetJavascriptIndent" )
@@ -55,7 +55,9 @@ let s:one_line_scope_regex = '\<\%(if\|else\|for\|while\)\>[^{;]*' . s:line_term
5555let s: block_regex = ' \%({\)\s*\%(|\%([*@]\=\h\w*,\=\s*\)\%(,\s*[*@]\=\h\w*\)*|\)\=' . s: line_term
5656
5757" Var string
58- let s: var_regex = ' \s*var\s[^;]\+$'
58+ let s: var_regex = ' \s*var\(.*\),$'
59+
60+ let s: comma_first = ' ^\s*,'
5961
6062" 2. Auxiliary Functions {{{1
6163" ======================
@@ -128,48 +130,55 @@ function s:GetMSL(lnum, in_one_line_scope)
128130 return msl
129131endfunction
130132
133+ function s: RemoveTrailingComments (content)
134+ let single = ' \/\/\(.*\)\s*$'
135+ let multi = ' \/\*\(.*\)\*\/\s*$'
136+ return substitute (substitute (a: content , single, ' ' , ' ' ), multi, ' ' , ' ' )
137+ endfunction
138+
131139" Find if the string is inside var statement (but not the first string)
132140function s: InVarStatement (lnum)
133- let lnum = s: PrevNonBlankNonString (a: lnum - 1 )
134-
135- while lnum > 0
136- let line = getline (lnum)
137-
138- " if line has var statement, return it's number
139- if ( line = ~ s: var_regex )
140- return lnum
141- endif
141+ let lnum = s: PrevNonBlankNonString (a: lnum - 1 )
142142
143- " if line has brackets or semi-colon, return 0
144- if ( line = ~ ' [{};]' )
145- return 0
146- endif
143+ while lnum > 0
144+ let line = getline (lnum)
147145
148- let lnum = s: PrevNonBlankNonString (lnum - 1 )
149- endwhile
146+ " if line has var statement, return its number
147+ if (line = ~ s: var_regex )
148+ return lnum
149+ endif
150150
151- return 0
151+ let lnum = s: PrevNonBlankNonString (lnum - 1 )
152+ endwhile
153+
154+ return 0
152155endfunction
153156
154157" Find line above with beginning of the var statement or returns 0 if it's not
155158" this statement
156159function s: GetVarIndent (lnum)
157- let lvar = s: InVarStatement (a: lnum )
158- let prev_lnum = s: PrevNonBlankNonString (a: lnum - 1 )
159- let prev_lvar = s: InVarStatement (prev_lnum)
160+ let lvar = s: InVarStatement (a: lnum )
161+ let prev_lnum = s: PrevNonBlankNonString (a: lnum - 1 )
162+ let prev_lvar = s: InVarStatement (prev_lnum)
160163
161- if ( lvar )
162- return indent (lvar) + &sw
163- endif
164+ if (lvar)
165+ let line = s: RemoveTrailingComments (getline (prev_lnum))
164166
165- if ( prev_lvar )
166- return indent (prev_lvar)
167+ " if the line doesn't end in a comma, return to regular indent
168+ if (line !~ ' ,\s*$' )
169+ return indent (lvar)
170+ else
171+ return indent (lvar) + &sw
167172 endif
173+ endif
174+
175+ if (prev_lvar)
176+ return indent (prev_lvar)
177+ endif
168178
169- return ' null'
170-
179+ return ' null'
171180endfunction
172-
181+
173182
174183" Check if line 'lnum' has more opening brackets than closing ones.
175184function s: LineHasOpeningBrackets (lnum)
@@ -264,16 +273,39 @@ function GetJavascriptIndent()
264273 " 3.2. Work on the current line {{{2
265274 " -----------------------------
266275
276+ let ind = -1
267277 " Get the current line.
268278 let line = getline (v: lnum )
269- let ind = -1
279+ " previous nonblank line number
280+ let prevline = prevnonblank (v: lnum - 1 )
270281
271282 " If we got a closing bracket on an empty line, find its match and indent
272283 " according to it. For parentheses we indent to its column - 1, for the
273284 " others we indent to the containing line's MSL's level. Return -1 if fail.
274- let col = matchend (line , ' ^\s*[]})]' )
285+ let col = matchend (line , ' ^\s*[], })]' )
275286 if col > 0 && ! s: IsInStringOrComment (v: lnum , col )
276287 call cursor (v: lnum , col )
288+
289+ let lvar = s: InVarStatement (v: lnum )
290+ if lvar
291+ let prevline_contents = s: RemoveTrailingComments (getline (prevline))
292+
293+ " check for comma first
294+ if (line [col - 1 ] = ~ ' ,' )
295+ " if the previous line ends in comma or semicolon don't indent
296+ if (prevline_contents = ~ ' [;,]\s*$' )
297+ return indent (s: GetMSL (line (' .' ), 0 ))
298+ " get previous line indent, if it's comma first return prevline indent
299+ elseif (prevline_contents = ~ s: comma_first )
300+ return indent (prevline)
301+ " otherwise we indent 1 level
302+ else
303+ return indent (prevline) + &sw
304+ endif
305+ endif
306+ endif
307+
308+
277309 let bs = strpart (' (){}[]' , stridx (' )}]' , line [col - 1 ]) * 2 , 2 )
278310 if searchpair (escape (bs [0 ], ' \[' ), ' ' , bs [1 ], ' bW' , s: skip_expr ) > 0
279311 if line [col - 1 ]== ' )' && col (' .' ) != col (' $' ) - 1
@@ -285,12 +317,17 @@ function GetJavascriptIndent()
285317 return ind
286318 endif
287319
320+ " If the line is comma first, dedent 1 level
321+ if (getline (prevline) = ~ s: comma_first )
322+ return indent (prevline) - &sw
323+ endif
324+
288325 " If we are in a multi-line comment, cindent does the right thing.
289326 if s: IsInMultilineComment (v: lnum , 1 )
290327 return cindent (v: lnum )
291328 endif
292329
293- " Work with var statements' blocks
330+ " Check for multiple var assignments
294331 let var_indent = s: GetVarIndent (v: lnum )
295332 if var_indent != ' null'
296333 return var_indent
@@ -302,16 +339,15 @@ function GetJavascriptIndent()
302339 " If the line is empty and the previous nonblank line was a multi-line
303340 " comment, use that comment's indent. Deduct one char to account for the
304341 " space in ' */'.
305- let nonblank_lnum = prevnonblank (v: lnum - 1 )
306- if line = ~ ' ^\s*$' && s: IsInMultilineComment (nonblank_lnum, 1 )
307- return indent (nonblank_lnum) - 1
342+ if line = ~ ' ^\s*$' && s: IsInMultilineComment (prevline, 1 )
343+ return indent (prevline) - 1
308344 endif
309345
310346 " Find a non-blank, non-multi-line string line above the current line.
311347 let lnum = s: PrevNonBlankNonString (v: lnum - 1 )
312348
313349 " If the line is empty and inside a string, use the previous line.
314- if line = ~ ' ^\s*$' && lnum != nonblank_lnum
350+ if line = ~ ' ^\s*$' && lnum != prevline
315351 return indent (prevnonblank (v: lnum ))
316352 endif
317353
0 commit comments