Skip to content

Commit d7f4728

Browse files
committed
Merge pull request #395 from pangloss/develop
Develop -> Master
2 parents 1833982 + 4b6f9c5 commit d7f4728

File tree

3 files changed

+167
-85
lines changed

3 files changed

+167
-85
lines changed

README.md

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,74 @@
1-
# vim-javascript v0.10.0
1+
# vim-javascript v1.0.0
22

3-
JavaScript bundle for vim, this bundle provides syntax and indent plugins.
3+
JavaScript bundle for vim, this bundle provides syntax highlighting and
4+
improved indentation.
45

5-
## A Quick Note on Regexes
66

7-
Vim 7.4 was released recently, and unfortunately broke how this plugin
8-
handles regexes. There was no real easy way for us to fix this unless we
9-
completely rewrote how regexes work.
7+
## Installation
108

11-
Good News: There was a recent update to Vim 7.4 that fixes this issue.
9+
### Install with [Vundle](https://github.com/gmarik/vundle)
1210

13-
Make sure you are at least using Vim 7.4, with patches 1-7.
11+
Add to vimrc:
1412

15-
If you are stuck on an older version of Vim 7.4 with no way to update,
16-
then simply perform the following commands to fix your current buffer:
13+
Plugin 'pangloss/vim-javascript'
1714

18-
```
19-
:set regexpengine=1
20-
:syntax enable
21-
```
15+
And install it:
2216

23-
## Installation
17+
:so ~/.vimrc
18+
:PluginInstall
2419

25-
### Install with [Vundle](https://github.com/gmarik/vundle)
20+
### Install with [vim-plug](https://github.com/junegunn/vim-plug)
2621

2722
Add to vimrc:
2823

29-
Plugin 'pangloss/vim-javascript'
24+
Plug 'pangloss/vim-javascript'
3025

3126
And install it:
3227

3328
:so ~/.vimrc
34-
:PluginInstall
29+
:PlugInstall
3530

3631
### Install with [pathogen](https://github.com/tpope/vim-pathogen)
3732

3833
git clone https://github.com/pangloss/vim-javascript.git ~/.vim/bundle/vim-javascript
3934

40-
## Configuration
35+
36+
## Configuration Variables
4137

4238
The following variables control certain syntax highlighting features. You can
4339
add them to your `.vimrc` to enable/disable their features.
4440

45-
#### javascript_enable_domhtmlcss
41+
```
42+
let g:javascript_enable_domhtmlcss = 1
43+
```
4644

4745
Enables HTML/CSS syntax highlighting in your JavaScript file.
4846

4947
Default Value: 0
5048

51-
#### b:javascript_fold
49+
-----------------
5250

53-
Enables JavaScript code folding.
51+
```
52+
let g:javascript_ignore_javaScriptdoc = 1
53+
```
5454

55-
Default Value: 1
55+
Disables JSDoc syntax highlighting
5656

57+
Default Value: 0
5758

58-
#### javascript_ignore_javaScriptdoc
59+
-----------------
5960

60-
Disables JSDoc syntax highlighting
61+
```
62+
set foldmethod=syntax
63+
```
6164

62-
Default Value: 0
65+
Enables code folding based on our syntax file.
66+
67+
Please note this can have a dramatic effect on performance and because it is a
68+
global vim option, we do not set it ourselves.
6369

64-
#### Concealing Characters
70+
71+
## Concealing Characters
6572

6673
You can customize concealing characters by defining one or more of the following
6774
variables:
@@ -77,6 +84,7 @@ variables:
7784
let g:javascript_conceal_super = "Ω"
7885
let g:javascript_conceal_arrow_function = "⇒"
7986

87+
8088
## Contributing
8189

8290
This project uses the [git
@@ -87,6 +95,24 @@ the price of admission is 1 pull request. Please follow the general code style
8795
guides (read the code) and in your pull request explain the reason for the
8896
proposed change and how it is valuable.
8997

90-
## Bug report
98+
99+
## Bug Reports
91100

92101
Report a bug on [GitHub Issues](https://github.com/pangloss/vim-javascript/issues).
102+
103+
104+
## A Quick Note on Regexes
105+
106+
Vim 7.4 with patches LESS than 1-7 exhibits a bug that broke how we handle
107+
javascript regexes. Please update to a newer version or run the following
108+
commands to fix:
109+
110+
```
111+
:set regexpengine=1
112+
:syntax enable
113+
```
114+
115+
116+
## License
117+
118+
Distributed under the same terms as Vim itself. See `:help license`.

indent/javascript.vim

Lines changed: 90 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ endif
4343
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\)'
4444
let s:expr_case = '^\s*\(case\s\+[^\:]*\|default\)\s*:\s*'
4545
" Regex of syntax group names that are or delimit string or are comments.
46-
let s:syng_strcom = 'string\|regex\|comment\c'
46+
let s:syng_strcom = '\%(\%(template\)\@<!string\|regex\|comment\)\c'
47+
48+
" Regex of syntax group names that are or delimit template strings
49+
let s:syng_template = 'template\c'
4750

4851
" Regex of syntax group names that are strings.
4952
let s:syng_string = 'regex\c'
@@ -60,25 +63,24 @@ let s:skip_expr = "synIDattr(synID(line('.'),col('.'),1),'name') =~ '".s:syng_st
6063
let s:line_term = '\s*\%(\%(\/\/\).*\)\=$'
6164

6265
" Regex that defines continuation lines, not including (, {, or [.
63-
let s:continuation_regex = '\%([\\*+/.:]\|\%(<%\)\@<![=-]\|\W[|&?]\|||\|&&\|[^=]=[^=].*,\)' . s:line_term
66+
let s:continuation_regex = '\%([\\*/.:]\|+\@<!+\|-\@<!-\|\%(<%\)\@<!=\|\W[|&?]\|||\|&&\|[^=]=[^=>].*,\)' . s:line_term
6467

6568
" Regex that defines continuation lines.
6669
" TODO: this needs to deal with if ...: and so on
67-
let s:msl_regex = s:continuation_regex.'|'.s:expr_case
70+
let s:msl_regex = s:continuation_regex.'\|'.s:expr_case
6871

69-
let s:one_line_scope_regex = '\%(\<else\>\|\<\%(if\|for\|while\)\>\s*(.*)\)' . s:line_term
72+
let s:one_line_scope_regex = '\%(\%(\<else\>\|\<\%(if\|for\|while\)\>\s*(\%([^()]*\|[^()]*(\%([^()]*\|[^()]*(\%([^()]*\|[^()]*([^()]*)[^()]*\))[^()]*\))[^()]*\))\)\|=>\)' . s:line_term
7073

7174
" Regex that defines blocks.
72-
let s:block_regex = '\%([{[]\)\s*\%(|\%([*@]\=\h\w*,\=\s*\)\%(,\s*[*@]\=\h\w*\)*|\)\=' . s:line_term
75+
let s:block_regex = '\%([{([]\)\s*\%(|\%([*@]\=\h\w*,\=\s*\)\%(,\s*[*@]\=\h\w*\)*|\)\=' . s:line_term
76+
77+
let s:operator_first = '^\s*\%([*/.:?]\|\([-+]\)\1\@!\|||\|&&\)'
7378

74-
let s:var_stmt = '^\s*(const\|let\|var)'
79+
let s:var_stmt = '^\s*\%(const\|let\|var\)'
7580

7681
let s:comma_first = '^\s*,'
7782
let s:comma_last = ',\s*$'
7883

79-
let s:ternary = '^\s\+[?|:]'
80-
let s:ternary_q = '^\s\+?'
81-
8284
let s:case_indent = s:sw()
8385
let s:case_indent_after = s:sw()
8486
let s:m = matchlist(&cinoptions, ':\(.\)')
@@ -102,6 +104,11 @@ function s:IsInString(lnum, col)
102104
return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_string
103105
endfunction
104106

107+
" Check if the character at lnum:col is inside a template string.
108+
function s:IsInTempl(lnum, col)
109+
return synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_template
110+
endfunction
111+
105112
" Check if the character at lnum:col is inside a multi-line comment.
106113
function s:IsInMultilineComment(lnum, col)
107114
return !s:IsLineComment(a:lnum, a:col) && synIDattr(synID(a:lnum, a:col, 1), 'name') =~ s:syng_multiline
@@ -120,13 +127,13 @@ function s:PrevNonBlankNonString(lnum)
120127
" Go in and out of blocks comments as necessary.
121128
" If the line isn't empty (with opt. comment) or in a string, end search.
122129
let line = getline(lnum)
123-
if line =~ '/\*'
130+
if s:IsInMultilineComment(lnum, matchend(line, '/\*') - 1)
124131
if in_block
125132
let in_block = 0
126133
else
127134
break
128135
endif
129-
elseif !in_block && line =~ '\*/'
136+
elseif !in_block && s:IsInMultilineComment(lnum, matchend(line, '\*/') - 1)
130137
let in_block = 1
131138
elseif !in_block && line !~ '^\s*\%(//\).*$' && !(s:IsInStringOrComment(lnum, 1) && s:IsInStringOrComment(lnum, strlen(line)))
132139
break
@@ -146,9 +153,21 @@ function s:GetMSL(lnum, in_one_line_scope)
146153
" Otherwise, terminate search as we have found our MSL already.
147154
let line = getline(lnum)
148155
let col = match(line, s:msl_regex) + 1
156+
let line2 = getline(msl)
157+
let col2 = matchend(line2, ')')
149158
if (col > 0 && !s:IsInStringOrComment(lnum, col)) || s:IsInString(lnum, strlen(line))
150159
let msl = lnum
160+
161+
" if there are more closing brackets, continue from the line which has the matching opening bracket
162+
elseif col2 > 0 && !s:IsInStringOrComment(msl, col2) && s:LineHasOpeningBrackets(msl)[0] == '2' && !a:in_one_line_scope
163+
call cursor(msl, 1)
164+
if searchpair('(', '', ')', 'bW', s:skip_expr) > 0
165+
let lnum = line('.')
166+
let msl = lnum
167+
endif
168+
151169
else
170+
152171
" Don't use lines that are part of a one line scope as msl unless the
153172
" flag in_one_line_scope is set to 1
154173
"
@@ -159,7 +178,7 @@ function s:GetMSL(lnum, in_one_line_scope)
159178
if msl_one_line == 0
160179
break
161180
endif
162-
endif
181+
end
163182
let lnum = s:PrevNonBlankNonString(lnum - 1)
164183
endwhile
165184
return msl
@@ -240,7 +259,7 @@ function s:LineHasOpeningBrackets(lnum)
240259
endif
241260
let pos = match(line, '[][(){}]', pos + 1)
242261
endwhile
243-
return (open_0 > 0) . (open_2 > 0) . (open_4 > 0)
262+
return (open_0 > 0 ? 1 : (open_0 == 0 ? 0 : 2)) . (open_2 > 0) . (open_4 > 0)
244263
endfunction
245264

246265
function s:Match(lnum, regex)
@@ -378,12 +397,45 @@ function GetJavascriptIndent()
378397
return indent(prevline) + s:case_indent_after
379398
endif
380399

381-
if (line =~ s:ternary)
382-
if (getline(prevline) =~ s:ternary_q)
400+
" If line starts with an operator...
401+
if (s:Match(v:lnum, s:operator_first))
402+
if (s:Match(prevline, s:operator_first))
403+
" and so does previous line, don't indent
383404
return indent(prevline)
384-
else
405+
end
406+
let counts = s:LineHasOpeningBrackets(prevline)
407+
if counts[0] == '2'
408+
call cursor(prevline, 1)
409+
" Search for the opening tag
410+
let mnum = searchpair('(', '', ')', 'bW', s:skip_expr)
411+
if mnum > 0 && s:Match(mnum, s:operator_first)
412+
return indent(mnum)
413+
end
414+
elseif counts[0] != '1' && counts[1] != '1' && counts[2] != '1'
415+
" otherwise, indent 1 level
416+
return indent(prevline) + s:sw()
417+
end
418+
" If previous line starts with an operator...
419+
elseif s:Match(prevline, s:operator_first) && !s:Match(prevline, s:comma_last) && !s:Match(prevline, '};\=' . s:line_term)
420+
let counts = s:LineHasOpeningBrackets(prevline)
421+
if counts[0] == '2' && counts[1] == '1'
422+
call cursor(prevline, 1)
423+
" Search for the opening tag
424+
let mnum = searchpair('(', '', ')', 'bW', s:skip_expr)
425+
if mnum > 0 && !s:Match(mnum, s:operator_first)
426+
return indent(mnum) + s:sw()
427+
end
428+
elseif counts[0] != '1' && counts[1] != '1' && counts[2] != '1'
429+
return indent(prevline) - s:sw()
430+
end
431+
end
432+
433+
if getline(prevline) =~ '^\s*`$' && s:IsInTempl(v:lnum, 1)
434+
if line !~ '^\s*`$'
385435
return indent(prevline) + s:sw()
386436
endif
437+
elseif line =~ '^\s*`$' && s:IsInTempl(prevline, 1)
438+
return indent(prevline) - s:sw()
387439
endif
388440

389441
" If we are in a multi-line comment, cindent does the right thing.
@@ -438,17 +490,36 @@ function GetJavascriptIndent()
438490
if line =~ '[[({]'
439491
let counts = s:LineHasOpeningBrackets(lnum)
440492
if counts[0] == '1' && searchpair('(', '', ')', 'bW', s:skip_expr) > 0
441-
if col('.') + 1 == col('$')
493+
if col('.') + 1 == col('$') || line =~ s:one_line_scope_regex
442494
return ind + s:sw()
443495
else
444496
return virtcol('.')
445497
endif
446-
elseif counts[1] == '1' || counts[2] == '1'
498+
elseif counts[1] == '1' || counts[2] == '1' && counts[0] != '2'
447499
return ind + s:sw()
448500
else
449501
call cursor(v:lnum, vcol)
450502
end
451-
endif
503+
elseif line =~ '.\+};\=' . s:line_term
504+
call cursor(lnum, 1)
505+
" Search for the opening tag
506+
let mnum = searchpair('{', '', '}', 'bW', s:skip_expr)
507+
if mnum > 0
508+
return indent(s:GetMSL(mnum, 0))
509+
end
510+
elseif line =~ '.\+);\=' || line =~ s:comma_last
511+
let counts = s:LineHasOpeningBrackets(lnum)
512+
if counts[0] == '2'
513+
call cursor(lnum, 1)
514+
" Search for the opening tag
515+
let mnum = searchpair('(', '', ')', 'bW', s:skip_expr)
516+
if mnum > 0
517+
return indent(s:GetMSL(mnum, 0))
518+
end
519+
elseif line !~ s:var_stmt
520+
return indent(prevline)
521+
end
522+
end
452523

453524
" 3.4. Work on the MSL line. {{{2
454525
" --------------------------

0 commit comments

Comments
 (0)