4141" 1. Variables {{{1
4242" ============
4343
44- let s: js_keywords = ' ^\s*\(break\|catch\|const\|continue\|debugger\|delete\|do\|else\|finally\|for\|function\|if\|in\|instanceof\|let\|new\|return\|switch\|this\|throw\|try\|typeof\|var\|void\|while\|with\)'
45- let s: expr_case = ' ^\s*\(case\s\+[^\:]*\|default\)\s*:\s*'
44+ let s: js_keywords = ' ^\s*\% (break\|catch\|const\|continue\|debugger\|delete\|do\|else\|finally\|for\|function\|if\|in\|instanceof\|let\|new\|return\|switch\|this\|throw\|try\|typeof\|var\|void\|while\|with\)\>\C '
45+ let s: expr_case = ' ^\s*\% (case\s\+[^\:]*\|default\)\s*:\s*\C '
4646" Regex of syntax group names that are or delimit string or are comments.
4747let s: syng_strcom = ' \%(string\|regex\|comment\|template\)\c'
4848
@@ -61,17 +61,17 @@ let s:skip_expr = "synIDattr(synID(line('.'),col('.'),1),'name') =~ '".s:syng_st
6161let s: line_term = ' \s*\%(\%(\/\/\).*\)\=$'
6262
6363" Regex that defines continuation lines, not including (, {, or [.
64- let s: continuation_regex = ' \%([\\*/.:]\|+\@<!+\|-\@<!-\|\%(<%\)\@<! =\|\W[|&?]\||| \|&&\|\%(=>.*\|=\ )\@<!=[^=>].* ,\)' . s: line_term
64+ let s: continuation_regex = ' \%([\\*/.? :]\|+\@<!+\|-\@<!-\|=\||| \|&&\|\%(=>.*\)\@<!=[^=>],\)' . s: line_term
6565
66- let s: one_line_scope_regex = ' \%(\<else\>\|=>\)' . s: line_term
66+ let s: one_line_scope_regex = ' \%(\<else\>\|=>\)\C ' . s: line_term
6767
6868function s: Onescope (lnum)
6969 if getline (a: lnum ) = ~ s: one_line_scope_regex
7070 return 1
7171 end
7272 let mypos = col (' .' )
7373 call cursor (a: lnum , 1 )
74- if search (' \<\%(while\|for\|if\)\>\s*(' , ' ce' , a: lnum ) > 0 && searchpair (' (' , ' ' , ' )' , ' W' , s: skip_expr , a: lnum ) > 0 && col (' .' ) == strlen (s: RemoveTrailingComments (getline (a: lnum )))
74+ if search (' \<\%(while\|for\|if\)\>\s*(\C ' , ' ce' , a: lnum ) > 0 && searchpair (' (' , ' ' , ' )' , ' W' , s: skip_expr , a: lnum ) > 0 && col (' .' ) == strlen (s: RemoveTrailingComments (getline (a: lnum )))
7575 call cursor (a: lnum , mypos)
7676 return 1
7777 else
@@ -85,10 +85,10 @@ let s:block_regex = '\%([{([]\)\s*\%(|\%([*@]\=\h\w*,\=\s*\)\%(,\s*[*@]\=\h\w*\)
8585
8686let s: operator_first = ' ^\s*\%([*.:?]\|\([-/+]\)\1\@!\|||\|&&\)'
8787
88- let s: var_stmt = ' ^\s*\%(const\|let\|var\)'
88+ let s: var_stmt = ' ^\s*\%(const\|let\|var\)\s\+\C '
8989
9090let s: comma_first = ' ^\s*,'
91- let s: comma_last = ' ,\s*$ '
91+ let s: comma_last = ' ,' . s: line_term
9292
9393" 2. Auxiliary Functions {{{1
9494" ======================
@@ -185,28 +185,35 @@ function s:RemoveTrailingComments(content)
185185endfunction
186186
187187" Find if the string is inside var statement (but not the first string)
188- function s: InMultiVarStatement (lnum)
188+ function s: InMultiVarStatement (lnum, cont, prev )
189189 let lnum = s: PrevNonBlankNonString (a: lnum - 1 )
190190
191- " let type = synIDattr(synID(lnum, indent(lnum) + 1, 0), 'name')
191+ " let type = synIDattr(synID(lnum, indent(lnum) + 1, 0), 'name')
192192
193193 " loop through previous expressions to find a var statement
194- while lnum > 0
194+ while lnum > 0 && ( s: Match (lnum, s: comma_last ) || ( a: cont && getline (lnum) = ~ ' ^\s*} ' ) || ( a: prev && s: Match ( a: prev , s: comma_last )))
195195 let line = getline (lnum)
196-
197196 " if the line is a js keyword
198197 if (line = ~ s: js_keywords )
199198 " check if the line is a var stmt
200199 " if the line has a comma first or comma last then we can assume that we
201200 " are in a multiple var statement
202- if (line = ~ s: var_stmt )
201+ if (line = ~ s: var_stmt ) && line = ~ s: comma_last
203202 return lnum
204203 endif
205204
206205 " other js keywords, not a var
207- return 0
206+ if line !~ s: comma_last
207+ return 0
208+ end
208209 endif
209-
210+ if a: cont
211+ call cursor (lnum,1 )
212+ if searchpair (' {' , ' ' , ' }' , ' bW' , s: skip_expr ) > 0
213+ let lnum = line (' .' )
214+ continue
215+ end
216+ end
210217 let lnum = s: PrevNonBlankNonString (lnum - 1 )
211218 endwhile
212219
@@ -217,7 +224,7 @@ endfunction
217224" Find line above with beginning of the var statement or returns 0 if it's not
218225" this statement
219226function s: GetVarIndent (lnum)
220- let lvar = s: InMultiVarStatement (a: lnum )
227+ let lvar = s: InMultiVarStatement (a: lnum, 0 , 0 )
221228 let prev_lnum = s: PrevNonBlankNonString (a: lnum - 1 )
222229
223230 if lvar
@@ -253,7 +260,7 @@ function s:LineHasOpeningBrackets(lnum)
253260 endif
254261 let pos = match (line , ' [][(){}]' , pos + 1 )
255262 endwhile
256- return (open_0 > 0 ? 1 : (open_0 == 0 ? 0 : 2 )) . (open_2 > 0 ) . (open_4 > 0 )
263+ return (open_0 > 0 ? 1 : (open_0 == 0 ? 0 : 2 )) . (open_2 > 0 ? 1 : (open_2 == 0 ? 0 : 2 )) . (open_4 > 0 ? 1 : (open_4 == 0 ? 0 : 2 ) )
257264endfunction
258265
259266function s: Match (lnum, regex)
@@ -283,11 +290,11 @@ function s:IndentWithContinuation(lnum, ind, width)
283290 if s: Match (lnum, s: continuation_regex )
284291 if lnum == p_lnum
285292 return msl_ind + a: width
286- elseif s: InMultiVarStatement (lnum) && getline (lnum) = ~ s: comma_last
287- return msl_ind - a: width
288293 else
289294 return msl_ind
290295 end
296+ elseif s: InMultiVarStatement (p_lnum, 0 ,v: lnum )
297+ return indent (p_lnum) - s: sw ()
291298 endif
292299
293300 return a: ind
@@ -354,15 +361,18 @@ function GetJavascriptIndent()
354361 if (line = ~ s: expr_case )
355362 return cindent (v: lnum )
356363 endif
364+ if s: Match (v: lnum , s: comma_first ) && s: Match (prevline,s: var_stmt )
365+ return indent (prevline) + s: sw ()
366+ end
357367 " If we got a closing bracket on an empty line, find its match and indent
358368 " according to it. For parentheses we indent to its column - 1, for the
359369 " others we indent to the containing line's MSL's level. Return -1 if fail.
360370 let col = matchend (line , ' ^\s*[],})]' )
361371 if col > 0 && ! s: IsInStringOrComment (v: lnum , col )
362372 call cursor (v: lnum , col )
363373
364- let lvar = s: InMultiVarStatement (v: lnum)
365- if lvar
374+ let lvar = s: InMultiVarStatement (v: lnum, 0 , 0 ) || line = ~ s: comma_first
375+ if lvar || line = ~ s: comma_first
366376 let prevline_contents = s: RemoveTrailingComments (getline (prevline))
367377
368378 " check for comma first
@@ -383,24 +393,14 @@ function GetJavascriptIndent()
383393
384394 let bs = strpart (' (){}[]' , stridx (' )}]' , line [col - 1 ]) * 2 , 2 )
385395 if searchpair (escape (bs [0 ], ' \[' ), ' ' , bs [1 ], ' bW' , s: skip_expr ) > 0
386- if line [col - 1 ]== ' )' && col (' .' ) != col (' $' ) - 1
387- let ind = virtcol (' .' )-1
388- else
389- let ind = s: InMultiVarStatement (line (' .' )) ? indent (line (' .' )) : indent (s: GetMSL (line (' .' ), 0 ))
390- endif
396+ let ind = s: InMultiVarStatement (line (' .' ), 0 , 0 ) ? indent (line (' .' )) : indent (s: GetMSL (line (' .' ), 0 ))
391397 endif
392398 return ind
393399 endif
394400
395401 " If the line is comma first, dedent 1 level
396402 if (getline (prevline) = ~ s: comma_first )
397403 return indent (prevline) - s: sw ()
398- elseif getline (s: PrevNonBlankNonString (prevline - 1 )) = ~ ' [])}]' . s: comma_last && getline (prevline) !~ s: block_regex
399- if getline (prevline) !~ s: comma_last
400- return indent (prevline) - s: sw ()
401- else
402- return indent (prevline)
403- end
404404 end
405405
406406 " If line starts with an operator...
@@ -445,12 +445,6 @@ function GetJavascriptIndent()
445445 end
446446 end
447447
448- " Check for multiple var assignments
449- " let var_indent = s:GetVarIndent(v:lnum)
450- " if var_indent >= 0
451- " return var_indent
452- " endif
453-
454448 " 3.3. Work on the previous line. {{{1
455449 " -------------------------------
456450
@@ -477,30 +471,35 @@ function GetJavascriptIndent()
477471
478472 " If the previous line ended with a block opening, add a level of indent.
479473 if s: Match (lnum, s: block_regex )
480- return s: InMultiVarStatement (lnum) ? indent (lnum) + s: sw () : indent (s: GetMSL (lnum, 0 )) + s: sw ()
474+ return s: InMultiVarStatement (lnum, 0 , 0 ) ? indent (lnum) + s: sw () : indent (s: GetMSL (lnum, 0 )) + s: sw ()
481475 endif
482476
483477 " Set up variables for current line.
484478 let line = getline (lnum)
485479 let ind = indent (lnum)
486480 " If the previous line contained an opening bracket, and we are still in it,
487481 " add indent depending on the bracket type.
488- if line = ~ ' [[({})\]]'
482+ if s: Match (lnum, ' [[({})\]]' )
489483 let counts = s: LineHasOpeningBrackets (lnum)
490- if counts[0 ] == ' 1' && searchpair (' (' , ' ' , ' )' , ' bW' , s: skip_expr ) > 0
491- if col (' .' ) + 1 == col (' $' ) || s: Onescope (lnum)
492- return ind + s: sw ()
493- else
494- return virtcol (' .' )
495- endif
496- elseif counts[0 ] == ' 2'
484+ if counts[0 ] == ' 2'
497485 call cursor (lnum, 1 )
498486 " Search for the opening tag
499- let mnum = searchpair (' (' , ' ' , ' )' , ' bW' , s: skip_expr )
500- if mnum > 0
501- return indent (s: GetMSL (mnum, 0 ))
487+ if searchpair (' (' , ' ' , ' )' , ' bW' , s: skip_expr ) > 0
488+ return indent (s: GetMSL (line (' .' ), 0 ))
502489 end
503- elseif counts[1 ] == ' 1' || counts[2 ] == ' 1' && counts[0 ] != ' 2'
490+ elseif counts[1 ] == ' 2' && line !~ ' ^\s*}'
491+ call cursor (lnum, 1 )
492+ " Search for the opening tag
493+ if searchpair (' {' , ' ' , ' }' , ' bW' , s: skip_expr ) > 0
494+ return indent (s: GetMSL (line (' .' ), 0 ))
495+ end
496+ elseif counts[2 ] == ' 2' && line !~ ' ^\s*]'
497+ call cursor (lnum, 1 )
498+ " Search for the opening tag
499+ if searchpair (' \[' , ' ' , ' \]' , ' bW' , s: skip_expr ) > 0
500+ return indent (s: GetMSL (line (' .' ), 0 ))
501+ end
502+ elseif counts[1 ] == ' 1' || counts[2 ] == ' 1' || counts[0 ] == ' 1' || s: Onescope (lnum)
504503 return ind + s: sw ()
505504 else
506505 call cursor (v: lnum , vcol)
@@ -509,7 +508,12 @@ function GetJavascriptIndent()
509508
510509 " 3.4. Work on the MSL line. {{{1
511510 " --------------------------
511+ if s: Match (lnum, s: comma_last ) && ! s: Match (lnum, s: continuation_regex )
512+ return line = ~ s: var_stmt ? indent (lnum) + s: sw () : indent (lnum)
512513
514+ elseif s: InMultiVarStatement (lnum, 1 , v: lnum ) && line !~ s: var_stmt
515+ return indent (lnum) - s: sw ()
516+ end
513517 let ind_con = ind
514518 let ind = s: IndentWithContinuation (lnum, ind_con, s: sw ())
515519
0 commit comments