Mercurial > vim
comparison runtime/indent/javascript.vim @ 9975:03fa8a51e9dc
commit https://github.com/vim/vim/commit/e4a3bcf28d92d0bde9ca227ccb40d401038185e5
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Aug 26 19:52:37 2016 +0200
Updated runtime files. Add Scala files.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Fri, 26 Aug 2016 20:00:12 +0200 |
parents | 9eaf8ef656e9 |
children | 74effdaa369e |
comparison
equal
deleted
inserted
replaced
9974:cb480e05fb5f | 9975:03fa8a51e9dc |
---|---|
1 " Vim indent file | 1 " Vim indent file |
2 " Language: Javascript | 2 " Language: Javascript |
3 " Maintainer: vim-javascript community | 3 " Maintainer: Chris Paul ( https://github.com/bounceme ) |
4 " URL: https://github.com/pangloss/vim-javascript | 4 " URL: https://github.com/pangloss/vim-javascript |
5 " Last Change: August 12, 2016 | 5 " Last Change: August 25, 2016 |
6 | 6 |
7 " Only load this indent file when no other was loaded. | 7 " Only load this indent file when no other was loaded. |
8 if exists('b:did_indent') | 8 if exists('b:did_indent') |
9 finish | 9 finish |
10 endif | 10 endif |
11 let b:did_indent = 1 | 11 let b:did_indent = 1 |
12 | 12 |
13 " Now, set up our indentation expression and keys that trigger it. | 13 " Now, set up our indentation expression and keys that trigger it. |
14 setlocal indentexpr=GetJavascriptIndent() | 14 setlocal indentexpr=GetJavascriptIndent() |
15 setlocal nolisp | 15 setlocal nolisp noautoindent nosmartindent |
16 setlocal indentkeys=0{,0},0),0],:,!^F,o,O,e | 16 setlocal indentkeys=0{,0},0),0],:,!^F,o,O,e |
17 setlocal cinoptions+=j1,J1 | 17 setlocal cinoptions+=j1,J1 |
18 | 18 |
19 let b:undo_indent = 'setlocal indentexpr< indentkeys< cinoptions<' | 19 let b:undo_indent = 'setlocal indentexpr< smartindent< autoindent< indentkeys< cinoptions<' |
20 | 20 |
21 " Only define the function once. | 21 " Only define the function once. |
22 if exists('*GetJavascriptIndent') | 22 if exists('*GetJavascriptIndent') |
23 finish | 23 finish |
24 endif | 24 endif |
35 function s:sw() | 35 function s:sw() |
36 return &sw | 36 return &sw |
37 endfunction | 37 endfunction |
38 endif | 38 endif |
39 | 39 |
40 let s:line_pre = '^\s*\%(\/\*.\{-}\*\/\s*\)*' | 40 let s:line_pre = '^\s*\%(\%(\%(\/\*.\{-}\)\=\*\+\/\s*\)\=\)\@>' |
41 let s:expr_case = s:line_pre . '\%(\%(case\>.\+\)\|default\)\s*:' | 41 let s:expr_case = s:line_pre . '\%(\%(case\>.\+\)\|default\)\s*:' |
42 " Regex of syntax group names that are or delimit string or are comments. | 42 " Regex of syntax group names that are or delimit string or are comments. |
43 let s:syng_strcom = '\%(s\%(tring\|pecial\)\|comment\|regex\|doc\|template\)' | 43 let s:syng_strcom = '\%(s\%(tring\|pecial\)\|comment\|regex\|doc\|template\)' |
44 | 44 |
45 " Regex of syntax group names that are strings or documentation. | 45 " Regex of syntax group names that are strings or documentation. |
46 let s:syng_comment = '\%(comment\|doc\)' | 46 let s:syng_comment = '\%(comment\|doc\)' |
47 | 47 |
48 " Expression used to check whether we should skip a match with searchpair(). | 48 " Expression used to check whether we should skip a match with searchpair(). |
49 let s:skip_expr = "line('.') < (prevnonblank(v:lnum) - 2000) ? dummy : synIDattr(synID(line('.'),col('.'),0),'name') =~? '".s:syng_strcom."'" | 49 let s:skip_expr = "synIDattr(synID(line('.'),col('.'),0),'name') =~? '".s:syng_strcom."'" |
50 | 50 |
51 function s:lookForParens(start,end,flags,time) | 51 if has('reltime') |
52 if has('reltime') | 52 function s:GetPair(start,end,flags,time) |
53 return searchpair(a:start,'',a:end,a:flags,s:skip_expr,0,a:time) | 53 return searchpair(a:start,'',a:end,a:flags,s:skip_expr,max([prevnonblank(v:lnum) - 2000,0]),a:time) |
54 else | 54 endfunction |
55 return searchpair(a:start,'',a:end,a:flags,0,0) | 55 else |
56 endif | 56 function s:GetPair(start,end,flags,n) |
57 endfunction | 57 return searchpair(a:start,'',a:end,a:flags,0,max([prevnonblank(v:lnum) - 2000,0])) |
58 endfunction | |
59 endif | |
58 | 60 |
59 let s:line_term = '\%(\s*\%(\/\*.\{-}\*\/\s*\)\=\)\@>$' | 61 let s:line_term = '\s*\%(\%(\/\%(\%(\*.\{-}\*\/\)\|\%(\*\+\)\)\)\s*\)\=$' |
60 | 62 |
61 " configurable regexes that define continuation lines, not including (, {, or [. | 63 " configurable regexes that define continuation lines, not including (, {, or [. |
62 if !exists('g:javascript_opfirst') | 64 if !exists('g:javascript_opfirst') |
63 let g:javascript_opfirst = '\%([<>,:?^%]\|\([-/.+]\)\%(\1\|\*\|\/\)\@!\|\*\/\@!\|=>\@!\||\|&\|in\%(stanceof\)\=\>\)' | 65 let g:javascript_opfirst = '\%([<>,:?^%|*&]\|\/[^/*]\|\([-.+]\)\1\@!\|=>\@!\|in\%(stanceof\)\=\>\)' |
64 endif | 66 endif |
67 if !exists('g:javascript_continuation') | |
68 let g:javascript_continuation = '\%([<=,.?/*:^%|&]\|+\@<!+\|-\@<!-\|=\@<!>\|\<in\%(stanceof\)\=\)' | |
69 endif | |
70 | |
65 let g:javascript_opfirst = s:line_pre . g:javascript_opfirst | 71 let g:javascript_opfirst = s:line_pre . g:javascript_opfirst |
66 | |
67 if !exists('g:javascript_continuation') | |
68 let g:javascript_continuation = '\%([<*,.?:^%]\|+\@<!+\|-\@<!-\|=\@<!>\|\*\@<!\/\|=\||\|&\|\<in\%(stanceof\)\=\)' | |
69 endif | |
70 let g:javascript_continuation .= s:line_term | 72 let g:javascript_continuation .= s:line_term |
71 | 73 |
72 function s:Onescope(lnum,text,add) | 74 function s:OneScope(lnum,text,add) |
73 return a:text =~# '\%(\<else\|\<do\|=>' . (a:add ? '\|\<try\|\<finally' : '' ) . '\)' . s:line_term || | 75 return a:text =~# '\%(\<else\|\<do\|=>\)' . s:line_term ? 'no b' : |
74 \ ((a:add && a:text =~ s:line_pre . '$' && search('\%' . s:PrevCodeLine(a:lnum - 1) . 'l.)' . s:line_term)) || | 76 \ ((a:add && a:text =~ s:line_pre . '$' && search('\%' . s:PrevCodeLine(a:lnum - 1) . 'l.)' . s:line_term)) || |
75 \ cursor(a:lnum, match(a:text, ')' . s:line_term)) > -1) && | 77 \ cursor(a:lnum, match(a:text, ')' . s:line_term)) > -1) && |
76 \ s:lookForParens('(', ')', 'cbW', 100) > 0 && search((a:add ? | 78 \ s:GetPair('(', ')', 'cbW', 100) > 0 && search('\C\l\+\_s*\%#','bW') && |
77 \ '\%(function\*\|[[:lower:][:upper:]_$][[:digit:][:lower:][:upper:]_$]*\)' : | 79 \ (a:add || ((expand('<cword>') !=# 'while' || !s:GetPair('\C\<do\>', '\C\<while\>','nbW',100)) && |
78 \ '\<\%(for\%(\s\+each\)\=\|if\|let\|w\%(hile\|ith\)\)') . '\_s*\%#\C','bW') && | 80 \ (expand('<cword>') !=# 'each' || search('\C\<for\_s\+\%#','nbW')))) ? expand('<cword>') : '' |
79 \ (a:add || (expand('<cword>') ==# 'while' ? !s:lookForParens('\<do\>\C', '\<while\>\C','bW',100) : 1)) | 81 endfunction |
82 | |
83 " https://github.com/sweet-js/sweet.js/wiki/design#give-lookbehind-to-the-reader | |
84 function s:IsBlock() | |
85 return getline(line('.'))[col('.')-1] == '{' && !search( | |
86 \ '\C\%(\<return\s*\|\%([-=~!<*+,.?^%|&\[(]\|=\@<!>\|\*\@<!\/\|\<\%(var\|const\|let\|import\|export\%(\_s\+default\)\=\|yield\|delete\|void\|t\%(ypeof\|hrow\)\|new\|in\%(stanceof\)\=\)\)\_s*\)\%#','bnW') && | |
87 \ (!search(':\_s*\%#','bW') || (!s:GetPair('[({[]','[])}]','bW',200) || s:IsBlock())) | |
80 endfunction | 88 endfunction |
81 | 89 |
82 " Auxiliary Functions {{{2 | 90 " Auxiliary Functions {{{2 |
83 | 91 |
84 " strip line of comment | |
85 function s:StripLine(c) | |
86 return a:c !~# s:expr_case ? substitute(a:c, '\%(:\@<!\/\/.*\)$', '','') : a:c | |
87 endfunction | |
88 | |
89 " Find line above 'lnum' that isn't empty, in a comment, or in a string. | 92 " Find line above 'lnum' that isn't empty, in a comment, or in a string. |
90 function s:PrevCodeLine(lnum) | 93 function s:PrevCodeLine(lnum) |
91 let l:lnum = prevnonblank(a:lnum) | 94 let l:lnum = prevnonblank(a:lnum) |
92 while l:lnum > 0 | 95 while l:lnum |
93 if synIDattr(synID(l:lnum,matchend(getline(l:lnum), '^\s*[^''"]'),0),'name') !~? s:syng_strcom | 96 if synIDattr(synID(l:lnum,matchend(getline(l:lnum), '^\s*[^''"]'),0),'name') !~? s:syng_strcom |
94 break | 97 return l:lnum |
95 endif | 98 endif |
96 let l:lnum = prevnonblank(l:lnum - 1) | 99 let l:lnum = prevnonblank(l:lnum - 1) |
97 endwhile | 100 endwhile |
98 return l:lnum | |
99 endfunction | 101 endfunction |
100 | 102 |
101 " Check if line 'lnum' has a balanced amount of parentheses. | 103 " Check if line 'lnum' has a balanced amount of parentheses. |
102 function s:Balanced(lnum) | 104 function s:Balanced(lnum) |
103 let open_0 = 0 | 105 let [open_0,open_2,open_4] = [0,0,0] |
104 let open_2 = 0 | |
105 let open_4 = 0 | |
106 let l:line = getline(a:lnum) | 106 let l:line = getline(a:lnum) |
107 let pos = match(l:line, '[][(){}]', 0) | 107 let pos = match(l:line, '[][(){}]', 0) |
108 while pos != -1 | 108 while pos != -1 |
109 if synIDattr(synID(a:lnum,pos + 1,0),'name') !~? s:syng_strcom | 109 if synIDattr(synID(a:lnum,pos + 1,0),'name') !~? s:syng_strcom |
110 let idx = stridx('(){}[]', l:line[pos]) | 110 let idx = stridx('(){}[]', l:line[pos]) |
127 " Get the current line. | 127 " Get the current line. |
128 let l:line = getline(v:lnum) | 128 let l:line = getline(v:lnum) |
129 let syns = synIDattr(synID(v:lnum, 1, 0), 'name') | 129 let syns = synIDattr(synID(v:lnum, 1, 0), 'name') |
130 | 130 |
131 " start with strings,comments,etc.{{{2 | 131 " start with strings,comments,etc.{{{2 |
132 if (l:line !~ '^[''"`]' && syns =~? 'string\|template') || | 132 if (l:line !~ '^[''"`]' && syns =~? '\%(string\|template\)') || |
133 \ (l:line !~ '^\s*[/*]' && syns =~? s:syng_comment) | 133 \ (l:line !~ '^\s*[/*]' && syns =~? s:syng_comment) |
134 return -1 | 134 return -1 |
135 endif | 135 endif |
136 if l:line !~ '^\%(\/\*\|\s*\/\/\)' && syns =~? s:syng_comment | 136 if l:line !~ '^\%(\/\*\|\s*\/\/\)' && syns =~? s:syng_comment |
137 return cindent(v:lnum) | 137 return cindent(v:lnum) |
151 "}}} | 151 "}}} |
152 | 152 |
153 " the containing paren, bracket, curly. Memoize, last lineNr either has the | 153 " the containing paren, bracket, curly. Memoize, last lineNr either has the |
154 " same scope or starts a new one, unless if it closed a scope. | 154 " same scope or starts a new one, unless if it closed a scope. |
155 call cursor(v:lnum,1) | 155 call cursor(v:lnum,1) |
156 if b:js_cache[0] >= l:lnum && b:js_cache[0] <= v:lnum && b:js_cache[0] && | 156 if b:js_cache[0] >= l:lnum && b:js_cache[0] < v:lnum && b:js_cache[0] && |
157 \ (b:js_cache[0] > l:lnum || s:Balanced(l:lnum) > 0) | 157 \ (b:js_cache[0] > l:lnum || s:Balanced(l:lnum) > 0) |
158 let num = b:js_cache[1] | 158 let num = b:js_cache[1] |
159 elseif syns != '' && l:line[0] =~ '\s' | 159 elseif syns != '' && l:line[0] =~ '\s' |
160 let pattern = syns =~? 'block' ? ['{','}'] : syns =~? 'jsparen' ? ['(',')'] : | 160 let pattern = syns =~? 'block' ? ['{','}'] : syns =~? 'jsparen' ? ['(',')'] : |
161 \ syns =~? 'jsbracket'? ['\[','\]'] : ['[({[]','[])}]'] | 161 \ syns =~? 'jsbracket'? ['\[','\]'] : ['[({[]','[])}]'] |
162 let num = s:lookForParens(pattern[0],pattern[1],'bW',2000) | 162 let num = s:GetPair(pattern[0],pattern[1],'bW',2000) |
163 else | 163 else |
164 let num = s:lookForParens('[({[]','[])}]','bW',2000) | 164 let num = s:GetPair('[({[]','[])}]','bW',2000) |
165 endif | 165 endif |
166 let b:js_cache = [v:lnum,num,line('.') == v:lnum ? b:js_cache[2] : col('.')] | 166 let b:js_cache = [v:lnum,num,line('.') == v:lnum ? b:js_cache[2] : col('.')] |
167 | 167 |
168 if l:line =~ s:line_pre . '[])}]' | 168 if l:line =~ s:line_pre . '[])}]' |
169 return indent(num) | 169 return indent(num) |
170 endif | 170 endif |
171 | 171 |
172 let pline = s:StripLine(getline(l:lnum)) | 172 call cursor(b:js_cache[1],b:js_cache[2]) |
173 let inb = num == 0 ? 1 : (s:Onescope(num, s:StripLine(strpart(getline(num),0,b:js_cache[2] - 1)),1) || | 173 |
174 \ (l:line !~ s:line_pre . ',' && pline !~ ',' . s:line_term)) && num < l:lnum | 174 let swcase = getline(l:lnum) =~# s:expr_case |
175 let switch_offset = (!inb || num == 0) || expand("<cword>") !=# 'switch' ? 0 : &cino !~ ':' || !has('float') ? s:sw() : | 175 let pline = swcase ? getline(l:lnum) : substitute(getline(l:lnum), '\%(:\@<!\/\/.*\)$', '','') |
176 let inb = num == 0 || num < l:lnum && ((l:line !~ s:line_pre . ',' && pline !~ ',' . s:line_term) || s:IsBlock()) | |
177 let switch_offset = num == 0 || s:OneScope(num, strpart(getline(num),0,b:js_cache[2] - 1),1) !=# 'switch' ? 0 : | |
178 \ &cino !~ ':' || !has('float') ? s:sw() : | |
176 \ float2nr(str2float(matchstr(&cino,'.*:\zs[-0-9.]*')) * (&cino =~# '.*:[^,]*s' ? s:sw() : 1)) | 179 \ float2nr(str2float(matchstr(&cino,'.*:\zs[-0-9.]*')) * (&cino =~# '.*:[^,]*s' ? s:sw() : 1)) |
177 | 180 |
178 " most significant, find the indent amount | 181 " most significant, find the indent amount |
179 if (inb && (l:line =~# g:javascript_opfirst || | 182 if inb && !swcase && ((l:line =~# g:javascript_opfirst || pline =~# g:javascript_continuation) || |
180 \ (pline =~# g:javascript_continuation && pline !~# s:expr_case && (pline !~ ':' . s:line_term || l:line !~# | 183 \ num < l:lnum && s:OneScope(l:lnum,pline,0) =~# '\<\%(for\|each\|if\|let\|no\sb\|w\%(hile\|ith\)\)\>' && |
181 \ s:line_pre . '\%(d\%(o\|ebugger\)\|else\|f\%(or\|inally\)\|if\|let\|switch\|t\%(hrow\|ry\)\|w\%(hile\|ith\)\)\>')))) || | 184 \ l:line !~ s:line_pre . '{') |
182 \ (num < l:lnum && s:Onescope(l:lnum,pline,0) && l:line !~ s:line_pre . '{') | |
183 return (num > 0 ? indent(num) : -s:sw()) + (s:sw() * 2) + switch_offset | 185 return (num > 0 ? indent(num) : -s:sw()) + (s:sw() * 2) + switch_offset |
184 elseif num > 0 | 186 elseif num > 0 |
185 return indent(num) + s:sw() + switch_offset | 187 return indent(num) + s:sw() + switch_offset |
186 endif | 188 endif |
187 | 189 |