Skip to content

Commit ee376ba

Browse files
authored
reuse more code, various fixes
1 parent 867c3cc commit ee376ba

1 file changed

Lines changed: 45 additions & 78 deletions

File tree

indent/javascript.vim

Lines changed: 45 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
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.
88
if exists('b:did_indent')
@@ -107,7 +107,7 @@ function s:ParseCino(f)
107107
endfunction
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)
111111
function 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]
131131
endfunction
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()
183183
endfunction
184184

185185
function 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
190189
endfunction
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]))
200194
endfunction
201195

202196
function 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)
224214
endfunction
225215

@@ -240,35 +230,6 @@ function s:Continues(ln,con)
240230
return s:SynAt(a:ln, len(a:con)) !~? (tok == '>' ? 'jsflow\|^html' : 'regex')
241231
endfunction
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.
273234
function 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
288249
endfunction
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

303263
function 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
332295
endfunction
@@ -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

Comments
 (0)