Skip to content

Commit 4dee33f

Browse files
committed
Adds multiple var indent and comma-first style
* Multiple variable indentation now possible thanks to the efforts of @utyf Some modifications were made to ensure that when coding without semicolons the indentation would be preserved/adjusted. Also multiline array, objects, and functions are now possible. * Adds support for comma-first style indentation. Now when using comma-first style the indentation is automatically adjusted once you press the comma. The indentation will always dedent on carriage return. Examples: var a = 1, b = 2, c = 3 // dedents var a = 1 , b = 2 // when pressing the comma it indents , c = 3 // dedents Fixes #53
1 parent b64a250 commit 4dee33f

File tree

1 file changed

+72
-36
lines changed

1 file changed

+72
-36
lines changed

indent/javascript.vim

Lines changed: 72 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ setlocal nosmartindent
1515

1616
" Now, set up our indentation expression and keys that trigger it.
1717
setlocal 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.
2121
if exists("*GetJavascriptIndent")
@@ -55,7 +55,9 @@ let s:one_line_scope_regex = '\<\%(if\|else\|for\|while\)\>[^{;]*' . s:line_term
5555
let 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
129131
endfunction
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)
132140
function 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
152155
endfunction
153156

154157
" Find line above with beginning of the var statement or returns 0 if it's not
155158
" this statement
156159
function 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'
171180
endfunction
172-
181+
173182

174183
" Check if line 'lnum' has more opening brackets than closing ones.
175184
function 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

Comments
 (0)