From 105a4aadfebcefda2645e0eec079cde72479788b Mon Sep 17 00:00:00 2001 From: bounceme Date: Mon, 25 Apr 2016 15:58:39 -0700 Subject: [PATCH 01/33] Switch mechanics, indent also now that I know about cindent i'm curious if there are other places like this to remove code and increase performance --- indent/javascript.vim | 38 ++++---------------------------------- 1 file changed, 4 insertions(+), 34 deletions(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index 80778907..0e1c8e84 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -65,10 +65,6 @@ let s:line_term = '\s*\%(\%(\/\/\).*\)\=$' " Regex that defines continuation lines, not including (, {, or [. let s:continuation_regex = '\%([\\*/.:]\|+\@].*,\)' . s:line_term -" Regex that defines continuation lines. -" TODO: this needs to deal with if ...: and so on -let s:msl_regex = s:continuation_regex.'\|'.s:expr_case - let s:one_line_scope_regex = '\%(\%(\\|\<\%(if\|for\|while\)\>\s*(\%([^()]*\|[^()]*(\%([^()]*\|[^()]*(\%([^()]*\|[^()]*([^()]*)[^()]*\))[^()]*\))[^()]*\))\)\|=>\)' . s:line_term " Regex that defines blocks. @@ -81,16 +77,6 @@ let s:var_stmt = '^\s*\%(const\|let\|var\)' let s:comma_first = '^\s*,' let s:comma_last = ',\s*$' -let s:case_indent = s:sw() -let s:case_indent_after = s:sw() -let s:m = matchlist(&cinoptions, ':\(.\)') -if (len(s:m) > 2) - let s:case_indent = s:m[1] -endif -let s:m = matchlist(&cinoptions, '=\(.\)') -if (len(s:m) > 2) - let s:case_indent_after = s:m[1] -endif " 2. Auxiliary Functions {{{1 " ====================== @@ -152,10 +138,10 @@ function s:GetMSL(lnum, in_one_line_scope) " If we have a continuation line, or we're in a string, use line as MSL. " Otherwise, terminate search as we have found our MSL already. let line = getline(lnum) - let col = match(line, s:msl_regex) + 1 + let col = match(line, s:continuation_regex) + 1 let line2 = getline(msl) let col2 = matchend(line2, ')') - if (col > 0 && !s:IsInStringOrComment(lnum, col)) || s:IsInString(lnum, strlen(line)) + if (col > 0 && !s:IsInStringOrComment(lnum, col) && !s:Match(lnum, s:expr_case)) || s:IsInString(lnum, strlen(line)) let msl = lnum " if there are more closing brackets, continue from the line which has the matching opening bracket @@ -327,7 +313,6 @@ endfunction function GetJavascriptIndent() " 3.1. Setup {{{2 " ---------- - " Set up variables for restoring position in file. Could use v:lnum here. let vcol = col('.') @@ -341,15 +326,7 @@ function GetJavascriptIndent() let prevline = prevnonblank(v:lnum - 1) if (line =~ s:expr_case) - if (getline(prevline) =~ s:expr_case) - return indent(prevline) - else - if (getline(prevline) =~ s:block_regex) - return indent(prevline) + s:case_indent - else - return indent(prevline) - s:case_indent_after - endif - endif + return cindent(v:lnum) endif " If we got a closing bracket on an empty line, find its match and indent " according to it. For parentheses we indent to its column - 1, for the @@ -393,9 +370,6 @@ function GetJavascriptIndent() if (getline(prevline) =~ s:comma_first) return indent(prevline) - s:sw() endif - if (getline(prevline) =~ s:expr_case) - return indent(prevline) + s:case_indent_after - endif " If line starts with an operator... if (s:Match(v:lnum, s:operator_first)) @@ -475,11 +449,7 @@ function GetJavascriptIndent() " If the previous line ended with a block opening, add a level of indent. if s:Match(lnum, s:block_regex) - if (line =~ s:expr_case) - return indent(s:GetMSL(lnum, 0)) + s:sw()/2 - else - return indent(s:GetMSL(lnum, 0)) + s:sw() - endif + return indent(s:GetMSL(lnum, 0)) + s:sw() endif " Set up variables for current line. From dde16a0564a78c58939721d7127e412f648a72da Mon Sep 17 00:00:00 2001 From: Amadeus Demarzi Date: Tue, 26 Apr 2016 13:20:04 -0700 Subject: [PATCH 02/33] Fix class definitions with no name Fixes #401 --- syntax/javascript.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/syntax/javascript.vim b/syntax/javascript.vim index 3bdb39a6..4ca08ecd 100644 --- a/syntax/javascript.vim +++ b/syntax/javascript.vim @@ -215,7 +215,7 @@ syntax match jsArrowFuncArgs /([^()]*)\s*\(=>\)\@=/ skipempty skipwhite conta syntax keyword jsClassKeywords extends class contained syntax match jsClassNoise /\./ contained syntax keyword jsClassMethodDefinitions get set static contained nextgroup=jsFuncName skipwhite skipempty -syntax match jsClassDefinition /class [a-zA-Z_$][0-9a-zA-Z_$ \n.]*/ contains=jsClassKeywords,jsClassNoise nextgroup=jsClassBlock skipwhite skipempty +syntax match jsClassDefinition /class\%( [a-zA-Z_$][0-9a-zA-Z_$ \n.]*\)*/ contains=jsClassKeywords,jsClassNoise nextgroup=jsClassBlock skipwhite skipempty " Define the default highlighting. " For version 5.7 and earlier: only when not done already From c4ccee6950c465d2a78c9f0b284a6ccf1b48a1a4 Mon Sep 17 00:00:00 2001 From: Amadeus Demarzi Date: Tue, 26 Apr 2016 21:27:06 -0700 Subject: [PATCH 03/33] Custom jsFuncName for object definitions This ES6 version of jsFuncName requires some special handling to not, by default, overwrite jsObjectKey and also not overwrite jsFuncCall. --- syntax/javascript.vim | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/syntax/javascript.vim b/syntax/javascript.vim index 4ca08ecd..a49c31f0 100644 --- a/syntax/javascript.vim +++ b/syntax/javascript.vim @@ -185,9 +185,9 @@ syntax cluster jsExpression contains=jsComment,jsLineComment,jsBlockComment,jsTa syntax cluster jsAll contains=@jsExpression,jsLabel,jsConditional,jsRepeat,jsReturn,jsStatement,jsTernaryIf,jsException syntax region jsBracket matchgroup=jsBrackets start="\[" end="\]" contains=@jsAll,jsParensErrB,jsParensErrC,jsBracket,jsParen,jsBlock,@htmlPreproc fold syntax region jsParen matchgroup=jsParens start="(" end=")" contains=@jsAll,jsOf,jsParensErrA,jsParensErrC,jsParen,jsBracket,jsBlock,@htmlPreproc fold extend -syntax region jsClassBlock matchgroup=jsClassBraces start="{" end="}" contains=jsFuncName,jsClassMethodDefinitions,jsOperator,jsArrowFunction,jsArrowFuncArgs,jsComment,jsBlockComment,jsLineComment contained fold +syntax region jsClassBlock matchgroup=jsClassBraces start="{" end="}" contains=jsFuncName,jsClassMethodDefinitions,jsOperator,jsArrowFunction,jsArrowFuncArgs,jsComment,jsBlockComment,jsLineComment,jsGenerator contained fold syntax region jsFuncBlock matchgroup=jsFuncBraces start="{" end="}" contains=@jsAll,jsParensErrA,jsParensErrB,jsParen,jsBracket,jsBlock,@htmlPreproc,jsClassDefinition fold extend -syntax region jsBlock matchgroup=jsBraces start="{" end="}" contains=@jsAll,jsParensErrA,jsParensErrB,jsParen,jsBracket,jsBlock,jsObjectKey,@htmlPreproc,jsClassDefinition fold extend +syntax region jsBlock matchgroup=jsBraces start="{" end="}" contains=@jsAll,jsParensErrA,jsParensErrB,jsParen,jsBracket,jsBlock,jsObjectKey,@htmlPreproc,jsClassDefinition extend syntax region jsTernaryIf matchgroup=jsTernaryIfOperator start=+?+ end=+:+ contains=@jsExpression,jsTernaryIf "" catch errors caused by wrong parenthesis @@ -200,8 +200,11 @@ syntax match jsFuncArgDestructuring contained /\({\|}\|=\|:\|\[\|\]\)/ extend exe 'syntax match jsFunction /\/ nextgroup=jsGenerator,jsFuncName,jsFuncArgs skipwhite '.(exists('g:javascript_conceal_function') ? 'conceal cchar='.g:javascript_conceal_function : '') exe 'syntax match jsArrowFunction /=>/ skipwhite nextgroup=jsFuncBlock contains=jsFuncBraces '.(exists('g:javascript_conceal_arrow_function') ? 'conceal cchar='.g:javascript_conceal_arrow_function : '') -syntax match jsGenerator contained '\*' nextgroup=jsFuncName,jsFuncArgs skipwhite -syntax match jsFuncName contained /\<[a-zA-Z_$][0-9a-zA-Z_$]*/ nextgroup=jsFuncArgs skipwhite +syntax match jsGenerator contained /\*/ nextgroup=jsFuncName,jsFuncArgs skipwhite skipempty +syntax match jsFuncName contained /\<[a-zA-Z_$][0-9a-zA-Z_$]*/ nextgroup=jsFuncArgs skipwhite skipempty +" These versions of jsFuncName is for use in object declarations with no key +syntax match jsFuncName contained /\%(^[\r\n\t ]*\)\@<=[*\r\n\t ]*[a-zA-Z_$][0-9a-zA-Z_$]*[\r\n\t ]*(\@=/ nextgroup=jsFuncArgs skipwhite skipempty containedin=jsBlock contains=jsGenerator +syntax match jsFuncName contained /\%(,[\r\n\t ]*\)\@<=[*\r\n\t ]*[a-zA-Z_$][0-9a-zA-Z_$]*[\r\n\t ]*(\@=/ nextgroup=jsFuncArgs skipwhite skipempty containedin=jsBlock contains=jsGenerator syntax region jsFuncArgs contained matchgroup=jsFuncParens start='(' end=')' contains=jsFuncArgCommas,jsFuncArgRest,jsComment,jsLineComment,jsStringS,jsStringD,jsNumber,jsFuncArgDestructuring,jsArrowFunction,jsParen,jsArrowFuncArgs nextgroup=jsFuncBlock keepend skipwhite skipempty syntax match jsFuncArgCommas contained ',' syntax match jsFuncArgRest contained /\%(\.\.\.[a-zA-Z_$][0-9a-zA-Z_$]*\))/ contains=jsFuncArgRestDots From b4e2faecd485f078a03c4ecef405c548c0992018 Mon Sep 17 00:00:00 2001 From: bounceme Date: Wed, 27 Apr 2016 15:52:33 -0700 Subject: [PATCH 04/33] Update javascript.vim --- indent/javascript.vim | 53 +++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index 0e1c8e84..788d4753 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -360,7 +360,7 @@ function GetJavascriptIndent() if line[col-1]==')' && col('.') != col('$') - 1 let ind = virtcol('.')-1 else - let ind = indent(s:GetMSL(line('.'), 0)) + let ind = s:InMultiVarStatement(line('.')) ? indent(line('.')) : indent(s:GetMSL(line('.'), 0)) endif endif return ind @@ -369,7 +369,9 @@ function GetJavascriptIndent() " If the line is comma first, dedent 1 level if (getline(prevline) =~ s:comma_first) return indent(prevline) - s:sw() - endif + elseif getline(s:PrevNonBlankNonString(prevline - 1)) =~ '[])}]' . s:comma_last && getline(prevline) !~ s:comma_last && getline(prevline) !~ s:block_regex + return indent(prevline) - s:sw() + end " If line starts with an operator... if (s:Match(v:lnum, s:operator_first)) @@ -390,17 +392,26 @@ function GetJavascriptIndent() return indent(prevline) + s:sw() end " If previous line starts with an operator... - elseif s:Match(prevline, s:operator_first) && !s:Match(prevline, s:comma_last) && !s:Match(prevline, '};\=' . s:line_term) + elseif (s:Match(prevline, s:operator_first) && !s:Match(prevline, s:comma_last) && !s:Match(prevline, '};\=' . s:line_term)) || s:Match(prevline, ');\=' . s:line_term) let counts = s:LineHasOpeningBrackets(prevline) - if counts[0] == '2' && counts[1] == '1' + if counts[0] == '2' && !s:Match(prevline, s:operator_first) call cursor(prevline, 1) " Search for the opening tag let mnum = searchpair('(', '', ')', 'bW', s:skip_expr) - if mnum > 0 && !s:Match(mnum, s:operator_first) - return indent(mnum) + s:sw() + if mnum > 0 && s:Match(mnum, s:operator_first) + return indent(mnum) - s:sw() + end + elseif s:Match(prevline, s:operator_first) + if counts[0] == '2' && counts[1] == '1' + call cursor(prevline, 1) + " Search for the opening tag + let mnum = searchpair('(', '', ')', 'bW', s:skip_expr) + if mnum > 0 && !s:Match(mnum, s:operator_first) + return indent(mnum) + s:sw() + end + elseif counts[0] != '1' && counts[1] != '1' && counts[2] != '1' + return indent(prevline) - s:sw() end - elseif counts[0] != '1' && counts[1] != '1' && counts[2] != '1' - return indent(prevline) - s:sw() end end @@ -449,7 +460,7 @@ function GetJavascriptIndent() " If the previous line ended with a block opening, add a level of indent. if s:Match(lnum, s:block_regex) - return indent(s:GetMSL(lnum, 0)) + s:sw() + return s:InMultiVarStatement(lnum) ? indent(lnum) + s:sw() : indent(s:GetMSL(lnum, 0)) + s:sw() endif " Set up variables for current line. @@ -457,7 +468,7 @@ function GetJavascriptIndent() let ind = indent(lnum) " If the previous line contained an opening bracket, and we are still in it, " add indent depending on the bracket type. - if line =~ '[[({]' + if line =~ '[[({})\]]' let counts = s:LineHasOpeningBrackets(lnum) if counts[0] == '1' && searchpair('(', '', ')', 'bW', s:skip_expr) > 0 if col('.') + 1 == col('$') || line =~ s:one_line_scope_regex @@ -465,29 +476,17 @@ function GetJavascriptIndent() else return virtcol('.') endif - elseif counts[1] == '1' || counts[2] == '1' && counts[0] != '2' - return ind + s:sw() - else - call cursor(v:lnum, vcol) - end - elseif line =~ '.\+};\=' . s:line_term - call cursor(lnum, 1) - " Search for the opening tag - let mnum = searchpair('{', '', '}', 'bW', s:skip_expr) - if mnum > 0 - return indent(s:GetMSL(mnum, 0)) - end - elseif line =~ '.\+);\=' || line =~ s:comma_last - let counts = s:LineHasOpeningBrackets(lnum) - if counts[0] == '2' + elseif counts[0] == '2' call cursor(lnum, 1) " Search for the opening tag let mnum = searchpair('(', '', ')', 'bW', s:skip_expr) if mnum > 0 return indent(s:GetMSL(mnum, 0)) end - elseif line !~ s:var_stmt - return indent(prevline) + elseif counts[1] == '1' || counts[2] == '1' && counts[0] != '2' + return ind + s:sw() + else + call cursor(v:lnum, vcol) end end From 50c433e8249bcd7a46ca57361dec7756b99c3de9 Mon Sep 17 00:00:00 2001 From: Amadeus Demarzi Date: Fri, 29 Apr 2016 11:21:09 -0700 Subject: [PATCH 05/33] Fix Issue 406 I am commenting this out since I am working through a better implementation. --- syntax/javascript.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/syntax/javascript.vim b/syntax/javascript.vim index a49c31f0..8ef89b0c 100644 --- a/syntax/javascript.vim +++ b/syntax/javascript.vim @@ -203,8 +203,8 @@ exe 'syntax match jsArrowFunction /=>/ skipwhite nextgroup=jsFuncBlock contains= syntax match jsGenerator contained /\*/ nextgroup=jsFuncName,jsFuncArgs skipwhite skipempty syntax match jsFuncName contained /\<[a-zA-Z_$][0-9a-zA-Z_$]*/ nextgroup=jsFuncArgs skipwhite skipempty " These versions of jsFuncName is for use in object declarations with no key -syntax match jsFuncName contained /\%(^[\r\n\t ]*\)\@<=[*\r\n\t ]*[a-zA-Z_$][0-9a-zA-Z_$]*[\r\n\t ]*(\@=/ nextgroup=jsFuncArgs skipwhite skipempty containedin=jsBlock contains=jsGenerator -syntax match jsFuncName contained /\%(,[\r\n\t ]*\)\@<=[*\r\n\t ]*[a-zA-Z_$][0-9a-zA-Z_$]*[\r\n\t ]*(\@=/ nextgroup=jsFuncArgs skipwhite skipempty containedin=jsBlock contains=jsGenerator +" syntax match jsFuncName contained /\%(^[\r\n\t ]*\)\@<=[*\r\n\t ]*[a-zA-Z_$][0-9a-zA-Z_$]*[\r\n\t ]*(\@=/ nextgroup=jsFuncArgs skipwhite skipempty containedin=jsBlock contains=jsGenerator +" syntax match jsFuncName contained /\%(,[\r\n\t ]*\)\@<=[*\r\n\t ]*[a-zA-Z_$][0-9a-zA-Z_$]*[\r\n\t ]*(\@=/ nextgroup=jsFuncArgs skipwhite skipempty containedin=jsBlock contains=jsGenerator syntax region jsFuncArgs contained matchgroup=jsFuncParens start='(' end=')' contains=jsFuncArgCommas,jsFuncArgRest,jsComment,jsLineComment,jsStringS,jsStringD,jsNumber,jsFuncArgDestructuring,jsArrowFunction,jsParen,jsArrowFuncArgs nextgroup=jsFuncBlock keepend skipwhite skipempty syntax match jsFuncArgCommas contained ',' syntax match jsFuncArgRest contained /\%(\.\.\.[a-zA-Z_$][0-9a-zA-Z_$]*\))/ contains=jsFuncArgRestDots From d2fa17618209e051f9d3ea815c6dffd4fe9a221c Mon Sep 17 00:00:00 2001 From: bounceme Date: Fri, 29 Apr 2016 18:15:46 -0700 Subject: [PATCH 06/33] multiline comment (#408) * Update javascript.vim * Update javascript.vim --- indent/javascript.vim | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index 788d4753..e8afa805 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -70,7 +70,7 @@ let s:one_line_scope_regex = '\%(\%(\\|\<\%(if\|for\|while\)\>\s*(\%([^() " Regex that defines blocks. let s:block_regex = '\%([{([]\)\s*\%(|\%([*@]\=\h\w*,\=\s*\)\%(,\s*[*@]\=\h\w*\)*|\)\=' . s:line_term -let s:operator_first = '^\s*\%([*/.:?]\|\([-+]\)\1\@!\|||\|&&\)' +let s:operator_first = '^\s*\%([*.:?]\|\([/-+]\)\1\@!\|||\|&&\)' let s:var_stmt = '^\s*\%(const\|let\|var\)' @@ -325,6 +325,11 @@ function GetJavascriptIndent() " previous nonblank line number let prevline = prevnonblank(v:lnum - 1) + " If we are in a multi-line comment, cindent does the right thing. + if s:IsInMultilineComment(v:lnum, 1) && !s:IsLineComment(v:lnum, 1) + return cindent(v:lnum) + endif + if (line =~ s:expr_case) return cindent(v:lnum) endif @@ -423,11 +428,6 @@ function GetJavascriptIndent() return indent(prevline) - s:sw() endif - " If we are in a multi-line comment, cindent does the right thing. - if s:IsInMultilineComment(v:lnum, 1) && !s:IsLineComment(v:lnum, 1) - return cindent(v:lnum) - endif - " Check for multiple var assignments " let var_indent = s:GetVarIndent(v:lnum) " if var_indent >= 0 From 617ccb50d644ad864421e471482219b4b380f5e2 Mon Sep 17 00:00:00 2001 From: bounceme Date: Fri, 29 Apr 2016 18:49:26 -0700 Subject: [PATCH 07/33] Update javascript.vim oh my --- indent/javascript.vim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index e8afa805..cadf7ccc 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -70,7 +70,7 @@ let s:one_line_scope_regex = '\%(\%(\\|\<\%(if\|for\|while\)\>\s*(\%([^() " Regex that defines blocks. let s:block_regex = '\%([{([]\)\s*\%(|\%([*@]\=\h\w*,\=\s*\)\%(,\s*[*@]\=\h\w*\)*|\)\=' . s:line_term -let s:operator_first = '^\s*\%([*.:?]\|\([/-+]\)\1\@!\|||\|&&\)' +let s:operator_first = '^\s*\%([*.:?]\|\([-/+]\)\1\@!\|||\|&&\)' let s:var_stmt = '^\s*\%(const\|let\|var\)' @@ -330,6 +330,7 @@ function GetJavascriptIndent() return cindent(v:lnum) endif + " cindent each line which has a switch label if (line =~ s:expr_case) return cindent(v:lnum) endif From 8fb5fa8c6352133229e0c8a63d277cf6fdd72baf Mon Sep 17 00:00:00 2001 From: bounceme Date: Mon, 2 May 2016 10:05:33 -0700 Subject: [PATCH 08/33] parentheses regex is thankfully gone (#412) proper asi for control statements --- indent/javascript.vim | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index cadf7ccc..1f6a1759 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -65,7 +65,22 @@ let s:line_term = '\s*\%(\%(\/\/\).*\)\=$' " Regex that defines continuation lines, not including (, {, or [. let s:continuation_regex = '\%([\\*/.:]\|+\@].*,\)' . s:line_term -let s:one_line_scope_regex = '\%(\%(\\|\<\%(if\|for\|while\)\>\s*(\%([^()]*\|[^()]*(\%([^()]*\|[^()]*(\%([^()]*\|[^()]*([^()]*)[^()]*\))[^()]*\))[^()]*\))\)\|=>\)' . s:line_term +let s:one_line_scope_regex = '\%(\\|=>\)' . s:line_term + +function s:Onescope(lnum) + if getline(a:lnum) =~ s:one_line_scope_regex + return 1 + end + let mypos = col('.') + call cursor(a:lnum, 1) + if search('\<\%(while\|for\|if\)\>\s*(', 'ce', a:lnum) > 0 && searchpair('(', '', ')', 'W', s:skip_expr, a:lnum) > 0 && col('.') + 1 == col('$') + call cursor(a:lnum, mypos) + return 1 + else + call cursor(a:lnum, mypos) + return 0 + end +endfunction " Regex that defines blocks. let s:block_regex = '\%([{([]\)\s*\%(|\%([*@]\=\h\w*,\=\s*\)\%(,\s*[*@]\=\h\w*\)*|\)\=' . s:line_term @@ -160,7 +175,7 @@ function s:GetMSL(lnum, in_one_line_scope) if a:in_one_line_scope break end - let msl_one_line = s:Match(lnum, s:one_line_scope_regex) + let msl_one_line = s:Onescope(lnum) if msl_one_line == 0 break endif @@ -285,7 +300,7 @@ endfunction function s:InOneLineScope(lnum) let msl = s:GetMSL(a:lnum, 1) - if msl > 0 && s:Match(msl, s:one_line_scope_regex) + if msl > 0 && s:Onescope(msl) return msl endif return 0 @@ -295,11 +310,11 @@ function s:ExitingOneLineScope(lnum) let msl = s:GetMSL(a:lnum, 1) if msl > 0 " if the current line is in a one line scope .. - if s:Match(msl, s:one_line_scope_regex) + if s:Onescope(msl) return 0 else let prev_msl = s:GetMSL(msl - 1, 1) - if s:Match(prev_msl, s:one_line_scope_regex) + if s:Onescope(prev_msl) return prev_msl endif endif @@ -472,7 +487,7 @@ function GetJavascriptIndent() if line =~ '[[({})\]]' let counts = s:LineHasOpeningBrackets(lnum) if counts[0] == '1' && searchpair('(', '', ')', 'bW', s:skip_expr) > 0 - if col('.') + 1 == col('$') || line =~ s:one_line_scope_regex + if col('.') + 1 == col('$') || s:Onescope(lnum) return ind + s:sw() else return virtcol('.') From 0fecb9295aa34d277a121d5915e3b94ac48d1f22 Mon Sep 17 00:00:00 2001 From: Amadeus Demarzi Date: Mon, 2 May 2016 11:45:29 -0700 Subject: [PATCH 09/33] Temporary fix for older versions of vim Will need to better fix this soon, just getting this hotfix out asap --- syntax/javascript.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/syntax/javascript.vim b/syntax/javascript.vim index 8ef89b0c..775f1995 100644 --- a/syntax/javascript.vim +++ b/syntax/javascript.vim @@ -97,7 +97,7 @@ syntax match jsRegexpOr "\v\<@!\|" contained syntax match jsRegexpMod "\v\(@<=\?[:=!>]" contained syntax cluster jsRegexpSpecial contains=jsSpecial,jsRegexpBoundary,jsRegexpBackRef,jsRegexpQuantifier,jsRegexpOr,jsRegexpMod syntax region jsRegexpGroup start="\\\@\|\<0[xX]\x\+\>/ syntax keyword jsNumber Infinity syntax match jsFloat /\<-\=\%(\d\+\.\d\+\|\d\+\.\|\.\d\+\)\%([eE][+-]\=\d\+\)\=\>/ From 8f16491ac58e019d48063cfa78a1386372201f87 Mon Sep 17 00:00:00 2001 From: bounceme Date: Fri, 6 May 2016 20:59:39 -0700 Subject: [PATCH 10/33] indent following line ending in comma with arrow (#420) an example here : https://github.com/jason0x43/vim-js-indent/issues/4#issuecomment-207838966 --- indent/javascript.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index 1f6a1759..f55fe742 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -63,7 +63,7 @@ let s:skip_expr = "synIDattr(synID(line('.'),col('.'),1),'name') =~ '".s:syng_st let s:line_term = '\s*\%(\%(\/\/\).*\)\=$' " Regex that defines continuation lines, not including (, {, or [. -let s:continuation_regex = '\%([\\*/.:]\|+\@].*,\)' . s:line_term +let s:continuation_regex = '\%([\\*/.:]\|+\@.*\|=\)\@].*,\)' . s:line_term let s:one_line_scope_regex = '\%(\\|=>\)' . s:line_term From c9eda1f5c10ffb91484ebc3f8b42322daface234 Mon Sep 17 00:00:00 2001 From: bounceme Date: Fri, 6 May 2016 21:32:49 -0700 Subject: [PATCH 11/33] template fixes (#422) --- indent/javascript.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index f55fe742..ec5853ea 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -43,7 +43,7 @@ endif 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\)' let s:expr_case = '^\s*\(case\s\+[^\:]*\|default\)\s*:\s*' " Regex of syntax group names that are or delimit string or are comments. -let s:syng_strcom = '\%(\%(template\)\@ Date: Sun, 8 May 2016 11:55:57 -0700 Subject: [PATCH 12/33] for better switch handling (#424) #423 --- indent/javascript.vim | 1 + 1 file changed, 1 insertion(+) diff --git a/indent/javascript.vim b/indent/javascript.vim index ec5853ea..9dde3526 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -17,6 +17,7 @@ setlocal nosmartindent setlocal indentexpr=GetJavascriptIndent() setlocal formatexpr=Fixedgq(v:lnum,v:count) setlocal indentkeys=0{,0},0),0],0\,:,!^F,o,O,e +setlocal cinoptions+=j1,J1 " Only define the function once. if exists("*GetJavascriptIndent") From b3ebfa5d96a9776e92be704ec55b7be76c082870 Mon Sep 17 00:00:00 2001 From: bounceme Date: Sun, 8 May 2016 20:18:54 -0700 Subject: [PATCH 13/33] c style opening curly braces (#426) * c style opening curly braces #68 * Update javascript.vim --- indent/javascript.vim | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/indent/javascript.vim b/indent/javascript.vim index 9dde3526..e3693173 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -345,6 +345,11 @@ function GetJavascriptIndent() if s:IsInMultilineComment(v:lnum, 1) && !s:IsLineComment(v:lnum, 1) return cindent(v:lnum) endif + + " single opening bracket will assume you want a c style of indenting + if s:Match(v:lnum, '^\s*{' . s:line_term) && s:GetMSL(v:lnum,0) == v:lnum + return cindent(v:lnum) + endif " cindent each line which has a switch label if (line =~ s:expr_case) From 7137e7eac1961f79b8063c49fe6957ae65456d9a Mon Sep 17 00:00:00 2001 From: Amadeus Demarzi Date: Tue, 3 May 2016 16:05:52 -0700 Subject: [PATCH 14/33] Prevent limited lookbehinds in older vers of vim --- syntax/javascript.vim | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/syntax/javascript.vim b/syntax/javascript.vim index 775f1995..57812317 100644 --- a/syntax/javascript.vim +++ b/syntax/javascript.vim @@ -97,7 +97,11 @@ syntax match jsRegexpOr "\v\<@!\|" contained syntax match jsRegexpMod "\v\(@<=\?[:=!>]" contained syntax cluster jsRegexpSpecial contains=jsSpecial,jsRegexpBoundary,jsRegexpBackRef,jsRegexpQuantifier,jsRegexpOr,jsRegexpMod syntax region jsRegexpGroup start="\\\@ 703 || v:version == 603 && has("patch1088") + syntax region jsRegexpString start=+\%(\%(\%(return\|case\)\s\+\)\@50<=\|\%(\%([)\]"']\|\d\|\w\)\s*\)\@50\|\<0[xX]\x\+\>/ syntax keyword jsNumber Infinity syntax match jsFloat /\<-\=\%(\d\+\.\d\+\|\d\+\.\|\.\d\+\)\%([eE][+-]\=\d\+\)\=\>/ From 61b89844d011fcd05028705364e7ab63525d4663 Mon Sep 17 00:00:00 2001 From: bounceme Date: Mon, 9 May 2016 13:25:53 -0700 Subject: [PATCH 15/33] specify template as a string this doesn't change any behavior it is just for clarity --- indent/javascript.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index e3693173..808bcb95 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -44,7 +44,7 @@ endif 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\)' let s:expr_case = '^\s*\(case\s\+[^\:]*\|default\)\s*:\s*' " Regex of syntax group names that are or delimit string or are comments. -let s:syng_strcom = '\%(string\|regex\|comment\)\c' +let s:syng_strcom = '\%(string\|regex\|comment\|template\)\c' " Regex of syntax group names that are or delimit template strings let s:syng_template = 'template\c' From a6e90baf0e4a53f9c30961f60f8bce406d6f48be Mon Sep 17 00:00:00 2001 From: bounceme Date: Tue, 10 May 2016 14:05:08 -0700 Subject: [PATCH 16/33] minor changes (#429) * Update javascript.vim * Update javascript.vim --- indent/javascript.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index 808bcb95..f1979fae 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -347,7 +347,7 @@ function GetJavascriptIndent() endif " single opening bracket will assume you want a c style of indenting - if s:Match(v:lnum, '^\s*{' . s:line_term) && s:GetMSL(v:lnum,0) == v:lnum + if s:Match(v:lnum, '^\s*{' . s:line_term) return cindent(v:lnum) endif From 206b85cfbe928697baa8a8562ca0384149dc70e0 Mon Sep 17 00:00:00 2001 From: bounceme Date: Wed, 11 May 2016 12:25:50 -0700 Subject: [PATCH 17/33] literal indentation in a multiline string (#430) --- indent/javascript.vim | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/indent/javascript.vim b/indent/javascript.vim index f1979fae..9ccf59c7 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -340,6 +340,11 @@ function GetJavascriptIndent() let line = getline(v:lnum) " previous nonblank line number let prevline = prevnonblank(v:lnum - 1) + + " to not change multiline string values + if (synIDattr(synID(v:lnum, 1, 1), 'name') =~? 'string' || s:IsInTempl(v:lnum, 1)) && line !~ '^\s*[''"`]' + return + endif " If we are in a multi-line comment, cindent does the right thing. if s:IsInMultilineComment(v:lnum, 1) && !s:IsLineComment(v:lnum, 1) From dc117664c4de7c49ec427795dbd62538cd85a22b Mon Sep 17 00:00:00 2001 From: bounceme Date: Wed, 11 May 2016 20:19:32 -0700 Subject: [PATCH 18/33] last actual column (#431) should be considered last non whitespace non comment --- indent/javascript.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index 9ccf59c7..5c774e4d 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -74,7 +74,7 @@ function s:Onescope(lnum) end let mypos = col('.') call cursor(a:lnum, 1) - if search('\<\%(while\|for\|if\)\>\s*(', 'ce', a:lnum) > 0 && searchpair('(', '', ')', 'W', s:skip_expr, a:lnum) > 0 && col('.') + 1 == col('$') + 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))) call cursor(a:lnum, mypos) return 1 else @@ -189,7 +189,7 @@ endfunction function s:RemoveTrailingComments(content) let single = '\/\/\(.*\)\s*$' let multi = '\/\*\(.*\)\*\/\s*$' - return substitute(substitute(a:content, single, '', ''), multi, '', '') + return substitute(substitute(substitute(a:content, single, '', ''), multi, '', ''), '\s\+$', '', '') endfunction " Find if the string is inside var statement (but not the first string) From fd98935f224dab93361216d513eb550ba602a31b Mon Sep 17 00:00:00 2001 From: bounceme Date: Wed, 11 May 2016 21:11:42 -0700 Subject: [PATCH 19/33] more fixes (#432) also I'm removing all the template string indentation, will leave it as a comment if someone can justify actually changing a string --- indent/javascript.vim | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index 5c774e4d..bbd8dd98 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -291,9 +291,11 @@ function s:IndentWithContinuation(lnum, ind, width) if s:Match(lnum, s:continuation_regex) if lnum == p_lnum return msl_ind + a:width - else + elseif !s:InMultiVarStatement(a:lnum) return msl_ind - endif + else + return msl_ind - a:width + end endif return a:ind @@ -401,8 +403,12 @@ function GetJavascriptIndent() " If the line is comma first, dedent 1 level if (getline(prevline) =~ s:comma_first) return indent(prevline) - s:sw() - elseif getline(s:PrevNonBlankNonString(prevline - 1)) =~ '[])}]' . s:comma_last && getline(prevline) !~ s:comma_last && getline(prevline) !~ s:block_regex - return indent(prevline) - s:sw() + elseif getline(s:PrevNonBlankNonString(prevline - 1)) =~ '[])}]' . s:comma_last && getline(prevline) !~ s:block_regex + if getline(prevline) !~ s:comma_last + return indent(prevline) - s:sw() + else + return indent(prevline) + end end " If line starts with an operator... @@ -447,13 +453,13 @@ function GetJavascriptIndent() end end - if getline(prevline) =~ '^\s*`$' && s:IsInTempl(v:lnum, 1) - if line !~ '^\s*`$' - return indent(prevline) + s:sw() - endif - elseif line =~ '^\s*`$' && s:IsInTempl(prevline, 1) - return indent(prevline) - s:sw() - endif + " if getline(prevline) =~ '^\s*`$' && s:IsInTempl(v:lnum, 1) + " if line !~ '^\s*`$' + " return indent(prevline) + s:sw() + " endif + " elseif line =~ '^\s*`$' && s:IsInTempl(prevline, 1) + " return indent(prevline) - s:sw() + " endif " Check for multiple var assignments " let var_indent = s:GetVarIndent(v:lnum) From 75fcd09e7b8a0bd906c6006803912fec9136c019 Mon Sep 17 00:00:00 2001 From: bounceme Date: Wed, 11 May 2016 21:18:48 -0700 Subject: [PATCH 20/33] must actually return a number --- indent/javascript.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index bbd8dd98..524331f9 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -345,7 +345,7 @@ function GetJavascriptIndent() " to not change multiline string values if (synIDattr(synID(v:lnum, 1, 1), 'name') =~? 'string' || s:IsInTempl(v:lnum, 1)) && line !~ '^\s*[''"`]' - return + return indent(v:lnum) endif " If we are in a multi-line comment, cindent does the right thing. From 7c7add5fe62c701cd634eebbecdc5ccc13d60096 Mon Sep 17 00:00:00 2001 From: bounceme Date: Wed, 11 May 2016 23:11:27 -0700 Subject: [PATCH 21/33] my mistake should have said more bugs #432 --- indent/javascript.vim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index 524331f9..d22b128c 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -291,10 +291,10 @@ function s:IndentWithContinuation(lnum, ind, width) if s:Match(lnum, s:continuation_regex) if lnum == p_lnum return msl_ind + a:width - elseif !s:InMultiVarStatement(a:lnum) - return msl_ind - else + elseif s:InMultiVarStatement(lnum) return msl_ind - a:width + else + return msl_ind end endif From 3ebaef31a9cd19a9ed5639b284bad3177482c454 Mon Sep 17 00:00:00 2001 From: bounceme Date: Thu, 12 May 2016 15:36:56 -0700 Subject: [PATCH 22/33] slight changes continuing from before this should be working now --- indent/javascript.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index d22b128c..900581ba 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -291,7 +291,7 @@ function s:IndentWithContinuation(lnum, ind, width) if s:Match(lnum, s:continuation_regex) if lnum == p_lnum return msl_ind + a:width - elseif s:InMultiVarStatement(lnum) + elseif s:InMultiVarStatement(lnum) && getline(lnum) =~ s:comma_last return msl_ind - a:width else return msl_ind From 04e412b77da3ae059bdf038e910bf36fca81a93b Mon Sep 17 00:00:00 2001 From: bounceme Date: Thu, 12 May 2016 23:54:30 -0700 Subject: [PATCH 23/33] removing some clutter (#434) also added a modeline to fold away the gq code --- indent/javascript.vim | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index 900581ba..533b5b3d 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -46,9 +46,6 @@ let s:expr_case = '^\s*\(case\s\+[^\:]*\|default\)\s*:\s*' " Regex of syntax group names that are or delimit string or are comments. let s:syng_strcom = '\%(string\|regex\|comment\|template\)\c' -" Regex of syntax group names that are or delimit template strings -let s:syng_template = 'template\c' - " Regex of syntax group names that are strings. let s:syng_string = 'regex\c' @@ -106,11 +103,6 @@ function s:IsInString(lnum, col) return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_string endfunction -" Check if the character at lnum:col is inside a template string. -function s:IsInTempl(lnum, col) - return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_template -endfunction - " Check if the character at lnum:col is inside a multi-line comment. function s:IsInMultilineComment(lnum, col) return !s:IsLineComment(a:lnum, a:col) && synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_multiline @@ -137,7 +129,7 @@ function s:PrevNonBlankNonString(lnum) endif elseif !in_block && s:IsInMultilineComment(lnum, matchend(line, '\*/') - 1) let in_block = 1 - elseif !in_block && line !~ '^\s*\%(//\).*$' && !(s:IsInStringOrComment(lnum, 1) && !s:IsInTempl(lnum,1) && s:IsInStringOrComment(lnum, strlen(line))) + elseif !in_block && line !~ '^\s*\%(//\).*$' && !(s:IsInStringOrComment(lnum, 1) && s:IsInStringOrComment(lnum, strlen(line))) break endif let lnum = prevnonblank(lnum - 1) @@ -329,12 +321,12 @@ endfunction " ========================= function GetJavascriptIndent() - " 3.1. Setup {{{2 + " 3.1. Setup {{{1 " ---------- " Set up variables for restoring position in file. Could use v:lnum here. let vcol = col('.') - " 3.2. Work on the current line {{{2 + " 3.2. Work on the current line {{{1 " ----------------------------- let ind = -1 @@ -344,7 +336,7 @@ function GetJavascriptIndent() let prevline = prevnonblank(v:lnum - 1) " to not change multiline string values - if (synIDattr(synID(v:lnum, 1, 1), 'name') =~? 'string' || s:IsInTempl(v:lnum, 1)) && line !~ '^\s*[''"`]' + if synIDattr(synID(v:lnum, 1, 1), 'name') =~? 'string\|template' && line !~ '^\s*[''"`]' return indent(v:lnum) endif @@ -453,21 +445,13 @@ function GetJavascriptIndent() end end - " if getline(prevline) =~ '^\s*`$' && s:IsInTempl(v:lnum, 1) - " if line !~ '^\s*`$' - " return indent(prevline) + s:sw() - " endif - " elseif line =~ '^\s*`$' && s:IsInTempl(prevline, 1) - " return indent(prevline) - s:sw() - " endif - " Check for multiple var assignments " let var_indent = s:GetVarIndent(v:lnum) " if var_indent >= 0 " return var_indent " endif - " 3.3. Work on the previous line. {{{2 + " 3.3. Work on the previous line. {{{1 " ------------------------------- " If the line is empty and the previous nonblank line was a multi-line @@ -523,7 +507,7 @@ function GetJavascriptIndent() end end - " 3.4. Work on the MSL line. {{{2 + " 3.4. Work on the MSL line. {{{1 " -------------------------- let ind_con = ind @@ -550,7 +534,7 @@ endfunction let &cpo = s:cpo_save unlet s:cpo_save - +" gq{{{2 function! Fixedgq(lnum, count) let l:tw = &tw ? &tw : 80; @@ -611,3 +595,5 @@ function! Fixedgq(lnum, count) return 0 endfunction +"}}} +" vim: foldmethod=marker:foldlevel=1 From 2c70878710f46c12ab94c0df7217f0bf995acff8 Mon Sep 17 00:00:00 2001 From: bounceme Date: Tue, 17 May 2016 17:11:41 -0700 Subject: [PATCH 24/33] random fixes and improvements (#435) * random fixes and improvements this also removes the parentheses alignment, we can leave it in I suppose, but I'd like to revisit that later. if anyone objects please let me know.this needs to be cleaned up a bit before merging * Update javascript.vim * Update javascript.vim * Update javascript.vim --- indent/javascript.vim | 104 ++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 50 deletions(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index 533b5b3d..fa2f8a87 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -41,8 +41,8 @@ endif " 1. Variables {{{1 " ============ -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\)' -let s:expr_case = '^\s*\(case\s\+[^\:]*\|default\)\s*:\s*' +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' +let s:expr_case = '^\s*\%(case\s\+[^\:]*\|default\)\s*:\s*\C' " Regex of syntax group names that are or delimit string or are comments. let s:syng_strcom = '\%(string\|regex\|comment\|template\)\c' @@ -61,9 +61,9 @@ let s:skip_expr = "synIDattr(synID(line('.'),col('.'),1),'name') =~ '".s:syng_st let s:line_term = '\s*\%(\%(\/\/\).*\)\=$' " Regex that defines continuation lines, not including (, {, or [. -let s:continuation_regex = '\%([\\*/.:]\|+\@.*\|=\)\@].*,\)' . s:line_term +let s:continuation_regex = '\%([\\*/.?:]\|+\@.*\)\@],\)' . s:line_term -let s:one_line_scope_regex = '\%(\\|=>\)' . s:line_term +let s:one_line_scope_regex = '\%(\\|=>\)\C' . s:line_term function s:Onescope(lnum) if getline(a:lnum) =~ s:one_line_scope_regex @@ -71,7 +71,7 @@ function s:Onescope(lnum) end let mypos = col('.') call cursor(a:lnum, 1) - 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))) + 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))) call cursor(a:lnum, mypos) return 1 else @@ -85,10 +85,10 @@ let s:block_regex = '\%([{([]\)\s*\%(|\%([*@]\=\h\w*,\=\s*\)\%(,\s*[*@]\=\h\w*\) let s:operator_first = '^\s*\%([*.:?]\|\([-/+]\)\1\@!\|||\|&&\)' -let s:var_stmt = '^\s*\%(const\|let\|var\)' +let s:var_stmt = '^\s*\%(const\|let\|var\)\s\+\C' let s:comma_first = '^\s*,' -let s:comma_last = ',\s*$' +let s:comma_last = ',' . s:line_term " 2. Auxiliary Functions {{{1 " ====================== @@ -185,28 +185,35 @@ function s:RemoveTrailingComments(content) endfunction " Find if the string is inside var statement (but not the first string) -function s:InMultiVarStatement(lnum) +function s:InMultiVarStatement(lnum, cont, prev) let lnum = s:PrevNonBlankNonString(a:lnum - 1) -" let type = synIDattr(synID(lnum, indent(lnum) + 1, 0), 'name') + " let type = synIDattr(synID(lnum, indent(lnum) + 1, 0), 'name') " loop through previous expressions to find a var statement - while lnum > 0 + while lnum > 0 && (s:Match(lnum, s:comma_last) || (a:cont && getline(lnum) =~ '^\s*}') || (a:prev && s:Match(a:prev, s:comma_last))) let line = getline(lnum) - " if the line is a js keyword if (line =~ s:js_keywords) " check if the line is a var stmt " if the line has a comma first or comma last then we can assume that we " are in a multiple var statement - if (line =~ s:var_stmt) + if (line =~ s:var_stmt) && line =~ s:comma_last return lnum endif " other js keywords, not a var - return 0 + if line !~ s:comma_last + return 0 + end endif - + if a:cont + call cursor(lnum,1) + if searchpair('{', '', '}', 'bW', s:skip_expr) > 0 + let lnum = line('.') + continue + end + end let lnum = s:PrevNonBlankNonString(lnum - 1) endwhile @@ -217,7 +224,7 @@ endfunction " Find line above with beginning of the var statement or returns 0 if it's not " this statement function s:GetVarIndent(lnum) - let lvar = s:InMultiVarStatement(a:lnum) + let lvar = s:InMultiVarStatement(a:lnum, 0,0) let prev_lnum = s:PrevNonBlankNonString(a:lnum - 1) if lvar @@ -253,7 +260,7 @@ function s:LineHasOpeningBrackets(lnum) endif let pos = match(line, '[][(){}]', pos + 1) endwhile - return (open_0 > 0 ? 1 : (open_0 == 0 ? 0 : 2)) . (open_2 > 0) . (open_4 > 0) + 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)) endfunction function s:Match(lnum, regex) @@ -283,11 +290,11 @@ function s:IndentWithContinuation(lnum, ind, width) if s:Match(lnum, s:continuation_regex) if lnum == p_lnum return msl_ind + a:width - elseif s:InMultiVarStatement(lnum) && getline(lnum) =~ s:comma_last - return msl_ind - a:width else return msl_ind end + elseif s:InMultiVarStatement(p_lnum, 0,v:lnum) + return indent(p_lnum) - s:sw() endif return a:ind @@ -354,6 +361,9 @@ function GetJavascriptIndent() if (line =~ s:expr_case) return cindent(v:lnum) endif + if s:Match(v:lnum, s:comma_first) && s:Match(prevline,s:var_stmt) + return indent(prevline) + s:sw() + end " If we got a closing bracket on an empty line, find its match and indent " according to it. For parentheses we indent to its column - 1, for the " others we indent to the containing line's MSL's level. Return -1 if fail. @@ -361,8 +371,8 @@ function GetJavascriptIndent() if col > 0 && !s:IsInStringOrComment(v:lnum, col) call cursor(v:lnum, col) - let lvar = s:InMultiVarStatement(v:lnum) - if lvar + let lvar = s:InMultiVarStatement(v:lnum, 0, 0) || line =~ s:comma_first + if lvar || line =~ s:comma_first let prevline_contents = s:RemoveTrailingComments(getline(prevline)) " check for comma first @@ -383,11 +393,7 @@ function GetJavascriptIndent() let bs = strpart('(){}[]', stridx(')}]', line[col - 1]) * 2, 2) if searchpair(escape(bs[0], '\['), '', bs[1], 'bW', s:skip_expr) > 0 - if line[col-1]==')' && col('.') != col('$') - 1 - let ind = virtcol('.')-1 - else - let ind = s:InMultiVarStatement(line('.')) ? indent(line('.')) : indent(s:GetMSL(line('.'), 0)) - endif + let ind = s:InMultiVarStatement(line('.'), 0, 0) ? indent(line('.')) : indent(s:GetMSL(line('.'), 0)) endif return ind endif @@ -395,12 +401,6 @@ function GetJavascriptIndent() " If the line is comma first, dedent 1 level if (getline(prevline) =~ s:comma_first) return indent(prevline) - s:sw() - elseif getline(s:PrevNonBlankNonString(prevline - 1)) =~ '[])}]' . s:comma_last && getline(prevline) !~ s:block_regex - if getline(prevline) !~ s:comma_last - return indent(prevline) - s:sw() - else - return indent(prevline) - end end " If line starts with an operator... @@ -445,12 +445,6 @@ function GetJavascriptIndent() end end - " Check for multiple var assignments -" let var_indent = s:GetVarIndent(v:lnum) -" if var_indent >= 0 -" return var_indent -" endif - " 3.3. Work on the previous line. {{{1 " ------------------------------- @@ -477,7 +471,7 @@ function GetJavascriptIndent() " If the previous line ended with a block opening, add a level of indent. if s:Match(lnum, s:block_regex) - return s:InMultiVarStatement(lnum) ? indent(lnum) + s:sw() : indent(s:GetMSL(lnum, 0)) + s:sw() + return s:InMultiVarStatement(lnum, 0, 0) ? indent(lnum) + s:sw() : indent(s:GetMSL(lnum, 0)) + s:sw() endif " Set up variables for current line. @@ -485,22 +479,27 @@ function GetJavascriptIndent() let ind = indent(lnum) " If the previous line contained an opening bracket, and we are still in it, " add indent depending on the bracket type. - if line =~ '[[({})\]]' + if s:Match(lnum, '[[({})\]]') let counts = s:LineHasOpeningBrackets(lnum) - if counts[0] == '1' && searchpair('(', '', ')', 'bW', s:skip_expr) > 0 - if col('.') + 1 == col('$') || s:Onescope(lnum) - return ind + s:sw() - else - return virtcol('.') - endif - elseif counts[0] == '2' + if counts[0] == '2' call cursor(lnum, 1) " Search for the opening tag - let mnum = searchpair('(', '', ')', 'bW', s:skip_expr) - if mnum > 0 - return indent(s:GetMSL(mnum, 0)) + if searchpair('(', '', ')', 'bW', s:skip_expr) > 0 + return indent(s:GetMSL(line('.'), 0)) end - elseif counts[1] == '1' || counts[2] == '1' && counts[0] != '2' + elseif counts[1] == '2' && line !~ '^\s*}' + call cursor(lnum, 1) + " Search for the opening tag + if searchpair('{', '', '}', 'bW', s:skip_expr) > 0 + return indent(s:GetMSL(line('.'), 0)) + end + elseif counts[2] == '2' && line !~ '^\s*]' + call cursor(lnum, 1) + " Search for the opening tag + if searchpair('\[', '', '\]', 'bW', s:skip_expr) > 0 + return indent(s:GetMSL(line('.'), 0)) + end + elseif counts[1] == '1' || counts[2] == '1' || counts[0] == '1' || s:Onescope(lnum) return ind + s:sw() else call cursor(v:lnum, vcol) @@ -509,7 +508,12 @@ function GetJavascriptIndent() " 3.4. Work on the MSL line. {{{1 " -------------------------- + if s:Match(lnum, s:comma_last) && !s:Match(lnum, s:continuation_regex) + return line =~ s:var_stmt ? indent(lnum) + s:sw() : indent(lnum) + elseif s:InMultiVarStatement(lnum, 1, v:lnum) && line !~ s:var_stmt + return indent(lnum) - s:sw() + end let ind_con = ind let ind = s:IndentWithContinuation(lnum, ind_con, s:sw()) From bf34e60dc378e06cb1ce7abc499bfd57b9dae9aa Mon Sep 17 00:00:00 2001 From: Amadeus Demarzi Date: Tue, 17 May 2016 21:49:31 -0700 Subject: [PATCH 25/33] Forcing `class` text to be a keyword This class regex will match if the text class is contained within a larger variable name, and therefore is broken. --- syntax/javascript.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/syntax/javascript.vim b/syntax/javascript.vim index 57812317..c9ba7dd9 100644 --- a/syntax/javascript.vim +++ b/syntax/javascript.vim @@ -222,7 +222,7 @@ syntax match jsArrowFuncArgs /([^()]*)\s*\(=>\)\@=/ skipempty skipwhite conta syntax keyword jsClassKeywords extends class contained syntax match jsClassNoise /\./ contained syntax keyword jsClassMethodDefinitions get set static contained nextgroup=jsFuncName skipwhite skipempty -syntax match jsClassDefinition /class\%( [a-zA-Z_$][0-9a-zA-Z_$ \n.]*\)*/ contains=jsClassKeywords,jsClassNoise nextgroup=jsClassBlock skipwhite skipempty +syntax match jsClassDefinition /\\%( [a-zA-Z_$][0-9a-zA-Z_$ \n.]*\)*/ contains=jsClassKeywords,jsClassNoise nextgroup=jsClassBlock skipwhite skipempty " Define the default highlighting. " For version 5.7 and earlier: only when not done already From 77387efb230d435ad655e5364bb0741121e0f87b Mon Sep 17 00:00:00 2001 From: bounceme Date: Sat, 21 May 2016 13:41:11 -0700 Subject: [PATCH 26/33] Update javascript.vim (#437) regexes have been cleaned and no longer have ruby specifics. all of the regex matching has been either refactored to use the s:match function if it is needed to look at the syntax of the characters, or changed to be a simple match to save performance.the current file has none of the bugs i talked about that were caused by the last commit --- indent/javascript.vim | 92 ++++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 44 deletions(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index fa2f8a87..76b50099 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -58,10 +58,10 @@ let s:syng_linecom = 'linecomment\c' " Expression used to check whether we should skip a match with searchpair(). let s:skip_expr = "synIDattr(synID(line('.'),col('.'),1),'name') =~ '".s:syng_strcom."'" -let s:line_term = '\s*\%(\%(\/\/\).*\)\=$' +let s:line_term = '\s*\%(\%(\/\/.*\)\=\|\%(\/\*.*\*\/\s*\)*\)$' " Regex that defines continuation lines, not including (, {, or [. -let s:continuation_regex = '\%([\\*/.?:]\|+\@.*\)\@],\)' . s:line_term +let s:continuation_regex = '\%([\\*/.?:]\|+\@\|=>\)\C' . s:line_term @@ -81,7 +81,7 @@ function s:Onescope(lnum) endfunction " Regex that defines blocks. -let s:block_regex = '\%([{([]\)\s*\%(|\%([*@]\=\h\w*,\=\s*\)\%(,\s*[*@]\=\h\w*\)*|\)\=' . s:line_term +let s:block_regex = '[{([]' . s:line_term let s:operator_first = '^\s*\%([*.:?]\|\([-/+]\)\1\@!\|||\|&&\)' @@ -179,8 +179,8 @@ function s:GetMSL(lnum, in_one_line_scope) endfunction function s:RemoveTrailingComments(content) - let single = '\/\/\(.*\)\s*$' - let multi = '\/\*\(.*\)\*\/\s*$' + let single = '\/\/\%(.*\)\s*$' + let multi = '\/\*\%(.*\)\*\/\s*$' return substitute(substitute(substitute(a:content, single, '', ''), multi, '', ''), '\s\+$', '', '') endfunction @@ -192,28 +192,26 @@ function s:InMultiVarStatement(lnum, cont, prev) " loop through previous expressions to find a var statement while lnum > 0 && (s:Match(lnum, s:comma_last) || (a:cont && getline(lnum) =~ '^\s*}') || (a:prev && s:Match(a:prev, s:comma_last))) - let line = getline(lnum) " if the line is a js keyword - if (line =~ s:js_keywords) + if a:cont + call cursor(lnum,1) + if searchpair('{', '', '}', 'bW', s:skip_expr) > 0 + let lnum = line('.') + end + end + if s:Match(lnum, s:js_keywords) " check if the line is a var stmt " if the line has a comma first or comma last then we can assume that we " are in a multiple var statement - if (line =~ s:var_stmt) && line =~ s:comma_last + if s:Match(lnum, s:var_stmt) && s:Match(lnum, s:comma_last) return lnum endif " other js keywords, not a var - if line !~ s:comma_last + if !s:Match(lnum, s:comma_last) return 0 end endif - if a:cont - call cursor(lnum,1) - if searchpair('{', '', '}', 'bW', s:skip_expr) > 0 - let lnum = line('.') - continue - end - end let lnum = s:PrevNonBlankNonString(lnum - 1) endwhile @@ -221,25 +219,25 @@ function s:InMultiVarStatement(lnum, cont, prev) return 0 endfunction -" Find line above with beginning of the var statement or returns 0 if it's not +" Find line above with beginning of the var statement or returns 0 if it's not"{{{2 " this statement -function s:GetVarIndent(lnum) - let lvar = s:InMultiVarStatement(a:lnum, 0,0) - let prev_lnum = s:PrevNonBlankNonString(a:lnum - 1) +" function s:GetVarIndent(lnum) +" let lvar = s:InMultiVarStatement(a:lnum, 0,0) +" let prev_lnum = s:PrevNonBlankNonString(a:lnum - 1) - if lvar - let line = s:RemoveTrailingComments(getline(prev_lnum)) +" if lvar +" let line = s:RemoveTrailingComments(getline(prev_lnum)) - " if the previous line doesn't end in a comma, return to regular indent - if (line !~ s:comma_last) - return indent(prev_lnum) - s:sw() - else - return indent(lvar) + s:sw() - endif - endif +" " if the previous line doesn't end in a comma, return to regular indent +" if (line !~ s:comma_last) +" return indent(prev_lnum) - s:sw() +" else +" return indent(lvar) + s:sw() +" endif +" endif - return -1 -endfunction +" return -1 +" endfunction"}}} " Check if line 'lnum' has more opening brackets than closing ones. @@ -361,8 +359,13 @@ function GetJavascriptIndent() if (line =~ s:expr_case) return cindent(v:lnum) endif - if s:Match(v:lnum, s:comma_first) && s:Match(prevline,s:var_stmt) - return indent(prevline) + s:sw() + + " the part first where we deal with comma first + if line =~ s:comma_first + let counts = s:LineHasOpeningBrackets(prevline) + if (s:Match(prevline, s:var_stmt) || counts[0] == '1' || counts[1] == '1' || counts[2] == '1') + return indent(prevline) + s:sw() + end end " If we got a closing bracket on an empty line, find its match and indent " according to it. For parentheses we indent to its column - 1, for the @@ -373,15 +376,14 @@ function GetJavascriptIndent() let lvar = s:InMultiVarStatement(v:lnum, 0, 0) || line =~ s:comma_first if lvar || line =~ s:comma_first - let prevline_contents = s:RemoveTrailingComments(getline(prevline)) " check for comma first if (line[col - 1] =~ ',') " if the previous line ends in comma or semicolon don't indent - if (prevline_contents =~ '[;,]\s*$') + if (getline(prevline) =~ '[;,]' . s:line_term) return indent(s:GetMSL(line('.'), 0)) " get previous line indent, if it's comma first return prevline indent - elseif (prevline_contents =~ s:comma_first) + elseif s:Match(prevline, s:comma_first) return indent(prevline) " otherwise we indent 1 level else @@ -399,12 +401,12 @@ function GetJavascriptIndent() endif " If the line is comma first, dedent 1 level - if (getline(prevline) =~ s:comma_first) + if s:Match(prevline, s:comma_first) return indent(prevline) - s:sw() end " If line starts with an operator... - if (s:Match(v:lnum, s:operator_first)) + if (line =~ s:operator_first) if (s:Match(prevline, s:operator_first)) " and so does previous line, don't indent return indent(prevline) @@ -422,7 +424,7 @@ function GetJavascriptIndent() return indent(prevline) + s:sw() end " If previous line starts with an operator... - elseif (s:Match(prevline, s:operator_first) && !s:Match(prevline, s:comma_last) && !s:Match(prevline, '};\=' . s:line_term)) || s:Match(prevline, ');\=' . s:line_term) + elseif (s:Match(prevline, s:operator_first) && getline(prevline) !~ s:comma_last && getline(prevline) !~ '};\=' . s:line_term) || getline(prevline) =~ ');\=' . s:line_term let counts = s:LineHasOpeningBrackets(prevline) if counts[0] == '2' && !s:Match(prevline, s:operator_first) call cursor(prevline, 1) @@ -487,13 +489,13 @@ function GetJavascriptIndent() if searchpair('(', '', ')', 'bW', s:skip_expr) > 0 return indent(s:GetMSL(line('.'), 0)) end - elseif counts[1] == '2' && line !~ '^\s*}' + elseif counts[1] == '2' && !s:Match(lnum, '^\s*}') call cursor(lnum, 1) " Search for the opening tag if searchpair('{', '', '}', 'bW', s:skip_expr) > 0 return indent(s:GetMSL(line('.'), 0)) end - elseif counts[2] == '2' && line !~ '^\s*]' + elseif counts[2] == '2' && !s:Match(lnum, '^\s*]') call cursor(lnum, 1) " Search for the opening tag if searchpair('\[', '', '\]', 'bW', s:skip_expr) > 0 @@ -509,10 +511,12 @@ function GetJavascriptIndent() " 3.4. Work on the MSL line. {{{1 " -------------------------- if s:Match(lnum, s:comma_last) && !s:Match(lnum, s:continuation_regex) - return line =~ s:var_stmt ? indent(lnum) + s:sw() : indent(lnum) + return s:Match(lnum, s:var_stmt) ? indent(lnum) + s:sw() : indent(lnum) - elseif s:InMultiVarStatement(lnum, 1, v:lnum) && line !~ s:var_stmt - return indent(lnum) - s:sw() + elseif s:Match(s:PrevNonBlankNonString(lnum - 1), s:comma_last) + if !s:Match(lnum, s:comma_last) && s:InMultiVarStatement(lnum,1,0) + return indent(lnum) - s:sw() + end end let ind_con = ind let ind = s:IndentWithContinuation(lnum, ind_con, s:sw()) From c180b0c322d578be6c510a9c0970e50322875877 Mon Sep 17 00:00:00 2001 From: bounceme Date: Sat, 21 May 2016 21:05:51 -0700 Subject: [PATCH 27/33] little bug affecting previous few commits another tiny commit, this is just fix which for a small bug that slipped past me --- indent/javascript.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index 76b50099..975da3ac 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -291,7 +291,7 @@ function s:IndentWithContinuation(lnum, ind, width) else return msl_ind end - elseif s:InMultiVarStatement(p_lnum, 0,v:lnum) + elseif s:InMultiVarStatement(p_lnum, 0, s:PrevNonBlankNonString(p_lnum - 1)) return indent(p_lnum) - s:sw() endif From c5fba22a90f17c4a09b961bc1834cfb8679adb28 Mon Sep 17 00:00:00 2001 From: bounceme Date: Tue, 24 May 2016 12:44:40 -0700 Subject: [PATCH 28/33] wrapping comments improved (#440) * wrapping comments improved this improves most regexes and the prevnonblanknonstring function --- indent/javascript.vim | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index 975da3ac..3fac0ab4 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -41,8 +41,9 @@ endif " 1. Variables {{{1 " ============ -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' -let s:expr_case = '^\s*\%(case\s\+[^\:]*\|default\)\s*:\s*\C' +let s:line_pre = '^\s*\%(\/\*.*\*\/\s*\)*' +let s:js_keywords = s:line_pre . '\%(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' +let s:expr_case = s:line_pre . '\%(case\s\+[^\:]*\|default\)\s*:\s*\C' " Regex of syntax group names that are or delimit string or are comments. let s:syng_strcom = '\%(string\|regex\|comment\|template\)\c' @@ -50,7 +51,7 @@ let s:syng_strcom = '\%(string\|regex\|comment\|template\)\c' let s:syng_string = 'regex\c' " Regex of syntax group names that are strings or documentation. -let s:syng_multiline = 'comment\c' +let s:syng_multiline = '\%(comment\|doc\)\c' " Regex of syntax group names that are line comment. let s:syng_linecom = 'linecomment\c' @@ -61,7 +62,7 @@ let s:skip_expr = "synIDattr(synID(line('.'),col('.'),1),'name') =~ '".s:syng_st let s:line_term = '\s*\%(\%(\/\/.*\)\=\|\%(\/\*.*\*\/\s*\)*\)$' " Regex that defines continuation lines, not including (, {, or [. -let s:continuation_regex = '\%([\\*/.?:]\|+\@\|=>\)\C' . s:line_term @@ -83,11 +84,11 @@ endfunction " Regex that defines blocks. let s:block_regex = '[{([]' . s:line_term -let s:operator_first = '^\s*\%([*.:?]\|\([-/+]\)\1\@!\|||\|&&\)' +let s:operator_first = s:line_pre . '\%([.:?]\|\([-/+*]\)\%(\1\|\*\|\/\)\@!\|||\|&&\)' -let s:var_stmt = '^\s*\%(const\|let\|var\)\s\+\C' +let s:var_stmt = s:line_pre . '\%(const\|let\|var\)\s\+\C' -let s:comma_first = '^\s*,' +let s:comma_first = s:line_pre . ',' let s:comma_last = ',' . s:line_term " 2. Auxiliary Functions {{{1 @@ -121,15 +122,15 @@ function s:PrevNonBlankNonString(lnum) " Go in and out of blocks comments as necessary. " If the line isn't empty (with opt. comment) or in a string, end search. let line = getline(lnum) - if s:IsInMultilineComment(lnum, matchend(line, '/\*') - 1) + if s:IsInMultilineComment(lnum, matchend(line, '^\s*/\*') - 1) && line !~ s:line_pre . '$' if in_block let in_block = 0 else break endif - elseif !in_block && s:IsInMultilineComment(lnum, matchend(line, '\*/') - 1) + elseif !in_block && s:IsInMultilineComment(lnum, match(line, '\*/\s*$') + 1) && line !~ s:line_pre . '$' let in_block = 1 - elseif !in_block && line !~ '^\s*\%(//\).*$' && !(s:IsInStringOrComment(lnum, 1) && s:IsInStringOrComment(lnum, strlen(line))) + elseif !in_block && line !~ s:line_pre . '\%(//\).*$' && !(s:IsInStringOrComment(lnum, 1) && s:IsInStringOrComment(lnum, strlen(line))) break endif let lnum = prevnonblank(lnum - 1) @@ -191,7 +192,7 @@ function s:InMultiVarStatement(lnum, cont, prev) " let type = synIDattr(synID(lnum, indent(lnum) + 1, 0), 'name') " loop through previous expressions to find a var statement - while lnum > 0 && (s:Match(lnum, s:comma_last) || (a:cont && getline(lnum) =~ '^\s*}') || (a:prev && s:Match(a:prev, s:comma_last))) + while lnum > 0 && (s:Match(lnum, s:comma_last) || (a:cont && getline(lnum) =~ s:line_pre . '}') || (a:prev && s:Match(a:prev, s:comma_last))) " if the line is a js keyword if a:cont call cursor(lnum,1) @@ -341,17 +342,18 @@ function GetJavascriptIndent() let prevline = prevnonblank(v:lnum - 1) " to not change multiline string values - if synIDattr(synID(v:lnum, 1, 1), 'name') =~? 'string\|template' && line !~ '^\s*[''"`]' + if synIDattr(synID(v:lnum, 1, 1), 'name') =~? 'string\|template' && line !~ s:line_pre . '[''"`]' return indent(v:lnum) endif " If we are in a multi-line comment, cindent does the right thing. - if s:IsInMultilineComment(v:lnum, 1) && !s:IsLineComment(v:lnum, 1) + if s:IsInMultilineComment(v:lnum, 1) && !s:IsLineComment(v:lnum, 1) && + \ s:IsInMultilineComment(v:lnum, match(line, '\s*$')) return cindent(v:lnum) endif " single opening bracket will assume you want a c style of indenting - if s:Match(v:lnum, '^\s*{' . s:line_term) + if s:Match(v:lnum, s:line_pre . '{' . s:line_term) return cindent(v:lnum) endif @@ -370,7 +372,7 @@ function GetJavascriptIndent() " If we got a closing bracket on an empty line, find its match and indent " according to it. For parentheses we indent to its column - 1, for the " others we indent to the containing line's MSL's level. Return -1 if fail. - let col = matchend(line, '^\s*[],})]') + let col = matchend(line, s:line_pre . '[],})]') if col > 0 && !s:IsInStringOrComment(v:lnum, col) call cursor(v:lnum, col) @@ -489,13 +491,13 @@ function GetJavascriptIndent() if searchpair('(', '', ')', 'bW', s:skip_expr) > 0 return indent(s:GetMSL(line('.'), 0)) end - elseif counts[1] == '2' && !s:Match(lnum, '^\s*}') + elseif counts[1] == '2' && !s:Match(lnum, s:line_pre . '}') call cursor(lnum, 1) " Search for the opening tag if searchpair('{', '', '}', 'bW', s:skip_expr) > 0 return indent(s:GetMSL(line('.'), 0)) end - elseif counts[2] == '2' && !s:Match(lnum, '^\s*]') + elseif counts[2] == '2' && !s:Match(lnum, s:line_pre . ']') call cursor(lnum, 1) " Search for the opening tag if searchpair('\[', '', '\]', 'bW', s:skip_expr) > 0 From fe096c0eec788006516b5be8ce580dbc23f7144f Mon Sep 17 00:00:00 2001 From: bounceme Date: Wed, 25 May 2016 11:58:00 -0700 Subject: [PATCH 29/33] another edge side effect (#443) this is just a more correct, thorough check, for multiline comments --- indent/javascript.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index 3fac0ab4..d3caf4ae 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -348,7 +348,7 @@ function GetJavascriptIndent() " If we are in a multi-line comment, cindent does the right thing. if s:IsInMultilineComment(v:lnum, 1) && !s:IsLineComment(v:lnum, 1) && - \ s:IsInMultilineComment(v:lnum, match(line, '\s*$')) + \ s:IsInMultilineComment(v:lnum, match(line, '\s*$')) && line !~ '^\/\*' return cindent(v:lnum) endif From d54b138f9113739780f1f61c9fe5aeec0e0ea088 Mon Sep 17 00:00:00 2001 From: bounceme Date: Thu, 26 May 2016 00:20:26 -0700 Subject: [PATCH 30/33] a comma should be considered an operator this fixes some serious issues with the way a continuation is detected and also removes the specific code for comma first style,which was very breakable --- indent/javascript.vim | 56 +++++++++++++------------------------------ 1 file changed, 16 insertions(+), 40 deletions(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index d3caf4ae..a0b78714 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -72,7 +72,9 @@ function s:Onescope(lnum) end let mypos = col('.') call cursor(a:lnum, 1) - 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))) + 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))) call cursor(a:lnum, mypos) return 1 else @@ -84,11 +86,10 @@ endfunction " Regex that defines blocks. let s:block_regex = '[{([]' . s:line_term -let s:operator_first = s:line_pre . '\%([.:?]\|\([-/+*]\)\%(\1\|\*\|\/\)\@!\|||\|&&\)' +let s:operator_first = s:line_pre . '\%([.,:?]\|\([-/+*]\)\%(\1\|\*\|\/\)\@!\|||\|&&\)' let s:var_stmt = s:line_pre . '\%(const\|let\|var\)\s\+\C' -let s:comma_first = s:line_pre . ',' let s:comma_last = ',' . s:line_term " 2. Auxiliary Functions {{{1 @@ -148,9 +149,11 @@ function s:GetMSL(lnum, in_one_line_scope) " Otherwise, terminate search as we have found our MSL already. let line = getline(lnum) let col = match(line, s:continuation_regex) + 1 + let coal = match(line, s:comma_last) + 1 let line2 = getline(msl) let col2 = matchend(line2, ')') - if (col > 0 && !s:IsInStringOrComment(lnum, col) && !s:Match(lnum, s:expr_case)) || s:IsInString(lnum, strlen(line)) + if ((col > 0 && !s:IsInStringOrComment(lnum, col) || coal > 0 && !s:IsInStringOrComment(lnum,coal)) && + \ !s:Match(lnum, s:expr_case)) || s:IsInString(lnum, strlen(line)) let msl = lnum " if there are more closing brackets, continue from the line which has the matching opening bracket @@ -192,7 +195,9 @@ function s:InMultiVarStatement(lnum, cont, prev) " let type = synIDattr(synID(lnum, indent(lnum) + 1, 0), 'name') " loop through previous expressions to find a var statement - while lnum > 0 && (s:Match(lnum, s:comma_last) || (a:cont && getline(lnum) =~ s:line_pre . '}') || (a:prev && s:Match(a:prev, s:comma_last))) + while lnum > 0 && (s:Match(lnum, s:comma_last) ||(a:cont && getline(lnum) =~ s:line_pre . '}') || + \ s:Match(lnum,s:continuation_regex)) || (a:prev && (s:Match(a:prev, s:comma_last) || + \ s:Match(a:prev,s:continuation_regex))) " if the line is a js keyword if a:cont call cursor(lnum,1) @@ -204,12 +209,12 @@ function s:InMultiVarStatement(lnum, cont, prev) " check if the line is a var stmt " if the line has a comma first or comma last then we can assume that we " are in a multiple var statement - if s:Match(lnum, s:var_stmt) && s:Match(lnum, s:comma_last) + if s:Match(lnum, s:var_stmt) && (s:Match(lnum, s:comma_last)||s:Match(lnum,s:continuation_regex)) return lnum endif " other js keywords, not a var - if !s:Match(lnum, s:comma_last) + if !s:Match(lnum, s:comma_last)||!s:Match(lnum,s:continuation_regex) return 0 end endif @@ -348,7 +353,7 @@ function GetJavascriptIndent() " If we are in a multi-line comment, cindent does the right thing. if s:IsInMultilineComment(v:lnum, 1) && !s:IsLineComment(v:lnum, 1) && - \ s:IsInMultilineComment(v:lnum, match(line, '\s*$')) && line !~ '^\/\*' + \ s:IsInMultilineComment(v:lnum, match(line, '\s*$')) && line !~ '^\/\*' return cindent(v:lnum) endif @@ -362,38 +367,13 @@ function GetJavascriptIndent() return cindent(v:lnum) endif - " the part first where we deal with comma first - if line =~ s:comma_first - let counts = s:LineHasOpeningBrackets(prevline) - if (s:Match(prevline, s:var_stmt) || counts[0] == '1' || counts[1] == '1' || counts[2] == '1') - return indent(prevline) + s:sw() - end - end " If we got a closing bracket on an empty line, find its match and indent " according to it. For parentheses we indent to its column - 1, for the " others we indent to the containing line's MSL's level. Return -1 if fail. - let col = matchend(line, s:line_pre . '[],})]') + let col = matchend(line, s:line_pre . '[]})]') if col > 0 && !s:IsInStringOrComment(v:lnum, col) call cursor(v:lnum, col) - let lvar = s:InMultiVarStatement(v:lnum, 0, 0) || line =~ s:comma_first - if lvar || line =~ s:comma_first - - " check for comma first - if (line[col - 1] =~ ',') - " if the previous line ends in comma or semicolon don't indent - if (getline(prevline) =~ '[;,]' . s:line_term) - return indent(s:GetMSL(line('.'), 0)) - " get previous line indent, if it's comma first return prevline indent - elseif s:Match(prevline, s:comma_first) - return indent(prevline) - " otherwise we indent 1 level - else - return indent(lvar) + s:sw() - endif - endif - endif - let bs = strpart('(){}[]', stridx(')}]', line[col - 1]) * 2, 2) if searchpair(escape(bs[0], '\['), '', bs[1], 'bW', s:skip_expr) > 0 @@ -402,11 +382,6 @@ function GetJavascriptIndent() return ind endif - " If the line is comma first, dedent 1 level - if s:Match(prevline, s:comma_first) - return indent(prevline) - s:sw() - end - " If line starts with an operator... if (line =~ s:operator_first) if (s:Match(prevline, s:operator_first)) @@ -426,7 +401,8 @@ function GetJavascriptIndent() return indent(prevline) + s:sw() end " If previous line starts with an operator... - elseif (s:Match(prevline, s:operator_first) && getline(prevline) !~ s:comma_last && getline(prevline) !~ '};\=' . s:line_term) || getline(prevline) =~ ');\=' . s:line_term + elseif (s:Match(prevline, s:operator_first) && getline(prevline) !~ s:continuation_regex && + \ getline(prevline) !~ '};\=' . s:line_term) || getline(prevline) =~ ');\=' . s:line_term let counts = s:LineHasOpeningBrackets(prevline) if counts[0] == '2' && !s:Match(prevline, s:operator_first) call cursor(prevline, 1) From b5de6ec2cc28bf28064712241d3fd624b966c336 Mon Sep 17 00:00:00 2001 From: bounceme Date: Thu, 26 May 2016 11:10:09 -0700 Subject: [PATCH 31/33] Update javascript.vim --- indent/javascript.vim | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/indent/javascript.vim b/indent/javascript.vim index a0b78714..8bd4bcf5 100644 --- a/indent/javascript.vim +++ b/indent/javascript.vim @@ -389,20 +389,20 @@ function GetJavascriptIndent() return indent(prevline) end let counts = s:LineHasOpeningBrackets(prevline) - if counts[0] == '2' + if counts[0] == '2' || counts[1] == '2' || counts[2] == '2' call cursor(prevline, 1) " Search for the opening tag - let mnum = searchpair('(', '', ')', 'bW', s:skip_expr) - if mnum > 0 && s:Match(mnum, s:operator_first) - return indent(mnum) + let bs = strpart('(){}[]', stridx(')}]', line[col - 1]) * 2, 2) + if searchpair(escape(bs[0], '\['), '', bs[1], 'bW', s:skip_expr) > 0 && s:Match(line('.'), s:operator_first) + return indent(line('.')) end elseif counts[0] != '1' && counts[1] != '1' && counts[2] != '1' " otherwise, indent 1 level return indent(prevline) + s:sw() end + " If previous line starts with an operator... - elseif (s:Match(prevline, s:operator_first) && getline(prevline) !~ s:continuation_regex && - \ getline(prevline) !~ '};\=' . s:line_term) || getline(prevline) =~ ');\=' . s:line_term + elseif (s:Match(prevline, s:operator_first) && !s:Match(prevline,s:continuation_regex))||getline(prevline) =~ ');\=' . s:line_term let counts = s:LineHasOpeningBrackets(prevline) if counts[0] == '2' && !s:Match(prevline, s:operator_first) call cursor(prevline, 1) @@ -412,14 +412,7 @@ function GetJavascriptIndent() return indent(mnum) - s:sw() end elseif s:Match(prevline, s:operator_first) - if counts[0] == '2' && counts[1] == '1' - call cursor(prevline, 1) - " Search for the opening tag - let mnum = searchpair('(', '', ')', 'bW', s:skip_expr) - if mnum > 0 && !s:Match(mnum, s:operator_first) - return indent(mnum) + s:sw() - end - elseif counts[0] != '1' && counts[1] != '1' && counts[2] != '1' + if counts[0] != '1' && counts[1] != '1' && counts[2] != '1' return indent(prevline) - s:sw() end end From fcec8b72d238e8c49b8755f294551c671ce3b0fd Mon Sep 17 00:00:00 2001 From: dNItro Date: Fri, 27 May 2016 01:30:45 +0430 Subject: [PATCH 32/33] Shebang doesn't have to contain env --- ftdetect/javascript.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ftdetect/javascript.vim b/ftdetect/javascript.vim index 036b352d..d6aa6d01 100644 --- a/ftdetect/javascript.vim +++ b/ftdetect/javascript.vim @@ -3,7 +3,7 @@ au BufNewFile,BufRead *.jsm setf javascript au BufNewFile,BufRead Jakefile setf javascript fun! s:SelectJavascript() - if getline(1) =~# '^#!.*/bin/env\s\+node\>' + if getline(1) =~# '^#!.*/bin/\%(env\s\+\)\?node\>' set ft=javascript endif endfun From 5b143bd2ad8dd4b98e4087d6991be423b9df7a2d Mon Sep 17 00:00:00 2001 From: bounceme Date: Thu, 26 May 2016 14:48:21 -0700 Subject: [PATCH 33/33] change the regex engine according to warning (#449) * change the regex engine according to warning the readme won't tell the user to change the regexpengine now that the correct one is set --- README.md | 12 ------------ ftplugin/javascript.vim | 3 +++ 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index fb5139c9..85b0d0b9 100644 --- a/README.md +++ b/README.md @@ -102,18 +102,6 @@ proposed change and how it is valuable. Report a bug on [GitHub Issues](https://github.com/pangloss/vim-javascript/issues). -## A Quick Note on Regexes - -Vim 7.4 with patches LESS than 1-7 exhibits a bug that broke how we handle -javascript regexes. Please update to a newer version or run the following -commands to fix: - -``` -:set regexpengine=1 -:syntax enable -``` - - ## License Distributed under the same terms as Vim itself. See `:help license`. diff --git a/ftplugin/javascript.vim b/ftplugin/javascript.vim index 9e2fc9b0..58755a4a 100644 --- a/ftplugin/javascript.vim +++ b/ftplugin/javascript.vim @@ -1 +1,4 @@ setlocal suffixesadd+=.js +if (v:version < 704 || (v:version == 704 && !has('patch002'))) && exists('®expengine') + set re=1 +end