22" Language: Javascript
33" Maintainer: Chris Paul ( https://github.com/bounceme )
44" URL: https://github.com/pangloss/vim-javascript
5- " Last Change: August 12 , 2017
5+ " Last Change: August 30 , 2017
66
77" Only load this indent file when no other was loaded.
88if exists (' b:did_indent' )
@@ -107,7 +107,7 @@ function s:ParseCino(f)
107107endfunction
108108
109109" Optimized {skip} expr, only callable from the search loop which
110- " GetJavascriptIndent does to find the containing [[{(] (relies on s:vars )
110+ " GetJavascriptIndent does to find the containing [[{(] (side-effects )
111111function s: SkipFunc ()
112112 if s: top_col == 1
113113 throw ' out of bounds'
@@ -130,12 +130,12 @@ function s:SkipFunc()
130130 let [s: looksyn , s: top_col ] = getpos (' .' )[1 :2 ]
131131endfunction
132132
133- function s: AlternatePair ()
133+ function s: AlternatePair (top )
134134 let [pat, l: for ] = [' [][(){};]' , 2 ]
135- while s: SearchLoop (' \m ' . pat,' bW' ,s: script_tag ,' s:SkipFunc()' )
135+ while s: SearchLoop (pat,' bW' ,a: top ,' s:SkipFunc()' )
136136 if s: LookingAt () == ' ;'
137137 if ! l: for
138- if s: GetPair (' {' ,' }' ,' bW' ,' s:SkipFunc()' ,2000 ,s: script_tag )
138+ if s: GetPair (' {' ,' }' ,' bW' ,' s:SkipFunc()' ,2000 ,a: top )
139139 return
140140 endif
141141 break
@@ -146,7 +146,7 @@ function s:AlternatePair()
146146 let idx = stridx (' ])}' ,s: LookingAt ())
147147 if idx == -1
148148 return
149- elseif ! s: GetPair (' [({' [idx],' ])}' [idx],' bW' ,' s:SkipFunc()' ,2000 ,s: script_tag )
149+ elseif ! s: GetPair (' [({' [idx],' ])}' [idx],' bW' ,' s:SkipFunc()' ,2000 ,a: top )
150150 break
151151 endif
152152 endif
@@ -171,7 +171,7 @@ function s:PreviousToken()
171171 if search (' \m\k\{1,}\|\S' ,' ebW' )
172172 if (strpart (getline (' .' ),col (' .' )-2 ,2 ) == ' */' || line (' .' ) != l: pos [1 ] &&
173173 \ getline (' .' )[: col (' .' )-1 ] = ~ ' \/\/' ) && s: SynAt (line (' .' ),col (' .' )) = ~? s: syng_com
174- if s: SearchLoop (' \m\ S\ze\_s*\/[/*]' ,' bW' ," s:SynAt(line('.'),col('.')) =~? s:syng_com" )
174+ if s: SearchLoop (' \S\ze\_s*\/[/*]' ,' bW' ," s:SynAt(line('.'),col('.')) =~? s:syng_com" )
175175 return s: Token ()
176176 endif
177177 call setpos (' .' ,l: pos )
@@ -183,30 +183,21 @@ function s:PreviousToken()
183183endfunction
184184
185185function s: Pure (f ,... )
186- let l: pos = getpos (' .' )
187- let ret = call (a: f ,a: 000 )
186+ let [l: pos , l: v ] = [getpos (' .' ), call (a: f ,a: 000 )]
188187 call setpos (' .' ,l: pos )
189- return ret
188+ return l: v
190189endfunction
191190
192- function s: SearchLoop (... )
193- let l: pos = getpos (' .' )
194- while call (' search' ,a: 000 [:-2 ]) " search flags [^nc]
195- if ! eval (a: 000 [-1 ])
196- return line (' .' )
197- endif
198- endwhile
199- call setpos (' .' ,l: pos )
191+ function s: SearchLoop (pat,flags,top ,... )
192+ let pair = insert ([a: pat ,a: flags ], ' \_$.' , a: flags = ~# ' b' )
193+ return call (' s:GetPair' ,pair + (a: 0 ? [a: 1 , 200 , a: top ] : [a: top , 200 ]))
200194endfunction
201195
202196function s: ExprCol ()
203- if getline (' .' )[col (' .' )-2 ] == ' :'
204- return 1
205- endif
206- let [bal, l: pos ] = [0 , getpos (' .' )]
207- while s: SearchLoop (' \m[{}?:]' ,' bW' ,s: script_tag ,s: skip_expr )
197+ let bal = 0
198+ while s: SearchLoop (' [{}?]\|\_[^:]\zs::\@!' ,' bW' ,s: script_tag ,s: skip_expr )
208199 if s: LookingAt () == ' :'
209- let bal -= strpart ( getline ( ' . ' ), col ( ' . ' ) -2 , 3 ) !~ ' :: '
200+ let bal -= 1
210201 elseif s: LookingAt () == ' ?'
211202 let bal += 1
212203 if bal == 1
@@ -219,7 +210,6 @@ function s:ExprCol()
219210 break
220211 endif
221212 endwhile
222- call setpos (' .' ,l: pos )
223213 return s: Nat (bal)
224214endfunction
225215
@@ -240,35 +230,6 @@ function s:Continues(ln,con)
240230 return s: SynAt (a: ln , len (a: con )) !~? (tok == ' >' ? ' jsflow\|^html' : ' regex' )
241231endfunction
242232
243- function s: Trim (ln )
244- let divi = split (getline (a: ln ),' \s\+$\|\S\zs\ze\s*\/[/*]' )
245- while len (divi) > 1 && s: SynAt (a: ln , len (join (divi,' ' ))) = ~? s: syng_com
246- call remove (divi,-1 )
247- endwhile
248- return join (divi,' ' )
249- endfunction
250-
251- " Find line above 'lnum' that isn't empty or in a comment
252- function s: PrevCodeLine (lnum)
253- let [l: multi , l: n , l: pos ] = [0 , prevnonblank (a: lnum ), getpos (' .' )]
254- while l: n
255- if getline (l: n ) = ~ ' ^\s*\/[/*]' && (getline (l: n ) !~ ' `' &&
256- \ getline (l: n- 1 )[-1 :] != ' \' || s: SynAt (l: n ,1 ) !~? b: syng_str )
257- let l: n = prevnonblank (l: n- 1 )
258- continue
259- elseif l: multi || getline (l: n ) = ~ ' \*\/'
260- call cursor (l: n ,1 )
261- if search (' \m\/\*\|\(\*\/\)' ,' bWp' ) == 1 && s: SynAt (l: n ,1 ) = ~? s: syng_com
262- let [l: multi , l: n ] = [1 , line (' .' )]
263- continue
264- endif
265- endif
266- break
267- endwhile
268- call setpos (' .' ,l: pos )
269- return l: n
270- endfunction
271-
272233" Check if line 'lnum' has a balanced amount of parentheses.
273234function s: Balanced (lnum)
274235 let [l: open , l: line ] = [0 , getline (a: lnum )]
@@ -287,8 +248,7 @@ function s:Balanced(lnum)
287248 return ! l: open
288249endfunction
289250
290- function s: OneScope (lnum)
291- call cursor (a: lnum , len (s: Trim (a: lnum )))
251+ function s: OneScope ()
292252 if s: LookingAt () == ' )' && s: GetPair (' (' , ' )' , ' bW' , s: skip_expr , 100 )
293253 let tok = s: PreviousToken ()
294254 return (tok = ~# ' ^\%(for\|if\|let\|while\|with\)$' ||
@@ -302,7 +262,7 @@ endfunction
302262
303263function s: DoWhile ()
304264 let cpos = searchpos (' \m\<' ,' cbW' )
305- if s: SearchLoop (' \m\ C[{}]\|\<\%(do\|while\)\>' ,' bW' ,s: skip_expr )
265+ if s: SearchLoop (' \C[{}]\|\<\%(do\|while\)\>' ,' bW' ,s: skip_expr )
306266 if s: {s: LookingAt () == ' }' && s: GetPair (' {' ,' }' ,' bW' ,s: skip_expr ,200 ) ?
307267 \ ' Previous' : ' ' }Token () == # ' do' && s: IsBlock ()
308268 return 1
@@ -314,19 +274,22 @@ endfunction
314274" returns braceless levels started by 'i' and above lines * &sw. 'num' is the
315275" lineNr which encloses the entire context, 'cont' if whether line 'i' + 1 is
316276" a continued expression, which could have started in a braceless context
317- function s: IsContOne (i , num,cont)
318- let [l: i , l: num , b_l] = [a: i , a: num + ! a: num , 0 ]
277+ function s: IsContOne (num,cont)
278+ let [l: startline , l: num , b_l] = [line ( ' . ' ) , a: num + ! a: num , 0 ]
319279 let pind = a: num ? indent (a: num ) + s: sw () : 0
320- let ind = indent (a: i ) + ( a: cont ? 0 : s: sw ())
321- while l: i > l: num && ind > pind || l: i == l: num
322- if indent (l: i ) < ind && s: OneScope (l: i )
280+ let ind = indent (' . ' ) + ! a: cont
281+ while line ( ' . ' ) > l: num && ind > pind || line ( ' . ' ) == l: num
282+ if indent (' . ' ) < ind && s: OneScope ()
323283 let b_l += 1
324- let l: i = line (' .' )
325- elseif ! a: cont || b_l || ind < indent (a: i )
284+ elseif ! a: cont || b_l || ind < indent (l: startline )
285+ break
286+ else
287+ call cursor (0 ,1 )
288+ endif
289+ let ind = min ([ind, indent (' .' )])
290+ if s: PreviousToken () is ' '
326291 break
327292 endif
328- let ind = min ([ind, indent (l: i )])
329- let l: i = s: PrevCodeLine (l: i - 1 )
330293 endwhile
331294 return b_l
332295endfunction
@@ -358,7 +321,7 @@ function s:IsBlock()
358321 elseif tok == ' *'
359322 return s: Pure (' s:PreviousToken' ) == ' :'
360323 elseif tok == ' :'
361- return ! s: ExprCol ()
324+ return s: Pure ( ' eval ' , ' s:PreviousToken() =~ "^\\K\\k*$" && !s:ExprCol() ' )
362325 elseif tok == ' /'
363326 return s: SynAt (line (' .' ),col (' .' )) = ~? ' regex'
364327 elseif tok !~ ' [=~!<,.?^%|&([]'
@@ -389,10 +352,12 @@ function GetJavascriptIndent()
389352 endif
390353 return -1
391354 endif
392- let l: lnum = s: PrevCodeLine (v: lnum - 1 )
393- if ! l: lnum
355+
356+ call cursor (v: lnum ,1 )
357+ if s: PreviousToken () is ' '
394358 return
395359 endif
360+ let [l: lnum , pline] = [line (' .' ), getline (' .' )[: col (' .' )-1 ]]
396361
397362 let l: line = substitute (l: line ,' ^\s*' ,' ' ,' ' )
398363 let l: line_raw = l: line
@@ -411,26 +376,27 @@ function GetJavascriptIndent()
411376 call call (' cursor' ,b: js_cache [2 ] ? b: js_cache [1 :] : [v: lnum ,1 ])
412377 else
413378 call cursor (v: lnum ,1 )
414- let [s: looksyn , s: check_in , s: top_col ] = [v: lnum - 1 , 0 , 0 ]
379+ let [s: looksyn , s: top_col , s: check_in , l: actual_top ] = [v: lnum - 1 ,0 ,0 ,
380+ \ max ([s: script_tag , search (' \m^.\{400,}' ,' nbW' ,s: script_tag + 1 ) + 1 ])]
415381 try
416382 if idx != -1
417- call s: GetPair (' [({' [idx],' ])}' [idx],' bW' ,' s:SkipFunc()' ,2000 ,s: script_tag )
418- elseif getline (v: lnum ) !~ ' ^\S' && syns = ~? ' block'
419- call s: GetPair (' {' ,' }' ,' bW' ,' s:SkipFunc()' ,2000 ,s: script_tag )
383+ call s: GetPair (' [({' [idx],' ])}' [idx],' bW' ,' s:SkipFunc()' ,2000 ,l: actual_top )
384+ elseif getline (v: lnum ) !~ ' ^\S' && syns = ~? ' block\|^jsobject$ '
385+ call s: GetPair (' {' ,' }' ,' bW' ,' s:SkipFunc()' ,2000 ,l: actual_top )
420386 else
421- call s: AlternatePair ()
387+ call s: AlternatePair (l: actual_top )
422388 endif
423- catch
389+ catch /^\Cout of bounds$/
424390 call cursor (v: lnum ,1 )
425391 endtry
426392 endif
427393
428394 let b: js_cache = [v: lnum ] + (line (' .' ) == v: lnum ? [s: script_tag ,0 ] : getpos (' .' )[1 :2 ])
429- let num = b: js_cache [1 ]
395+ let [ num, s: script_tag ] = [ b: js_cache [1 ], get ( l: , ' actual_top ' , s: script_tag ) ]
430396
431397 let [num_ind, is_op, b_l, l: switch_offset ] = [s: Nat (indent (num)),0 ,0 ,0 ]
432398 if ! b: js_cache [2 ] || s: LookingAt () == ' {' && s: IsBlock ()
433- let [ ilnum, pline] = [ line (' .' ), s: Trim ( l: lnum )]
399+ let ilnum = line (' .' )
434400 if b: js_cache [2 ] && s: LookingAt () == ' )' && s: GetPair (' (' ,' )' ,' bW' ,s: skip_expr ,100 )
435401 if ilnum == num
436402 let [num, num_ind] = [line (' .' ), indent (' .' )]
@@ -460,7 +426,8 @@ function GetJavascriptIndent()
460426 else
461427 let is_op = s: sw ()
462428 endif
463- let b_l = s: Nat (s: IsContOne (l: lnum ,b: js_cache [1 ],is_op) -
429+ call cursor (l: lnum , len (pline))
430+ let b_l = s: Nat (s: IsContOne (b: js_cache [1 ],is_op) -
464431 \ (! is_op && l: line = ~ ' ^{' )) * s: sw ()
465432 endif
466433 elseif idx == -1 && getline (b: js_cache [1 ])[b: js_cache [2 ]-1 ] == ' (' && &cino = ~ ' (' &&
0 commit comments