Mercurial > vim
annotate runtime/indent/json.vim @ 14418:d221232f4578
Added tag v8.1.0223 for changeset 5d9b450e78273833ed4f7a7e588378c8a11c0fb4
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sat, 28 Jul 2018 19:30:06 +0200 |
parents | 63b0b7b79b25 |
children | d4c7b3e9cd17 |
rev | line source |
---|---|
6070
32a77cc160d9
Update runtime files. Make matchparen plugin backwards compatible.
Bram Moolenaar <bram@vim.org>
parents:
diff
changeset
|
1 " Vim indent file |
32a77cc160d9
Update runtime files. Make matchparen plugin backwards compatible.
Bram Moolenaar <bram@vim.org>
parents:
diff
changeset
|
2 " Language: JSON |
6180 | 3 " Mantainer: Eli Parra <eli@elzr.com> https://github.com/elzr/vim-json |
11518 | 4 " Last Change: 2017 Jun 13 |
6180 | 5 " https://github.com/jakar/vim-json/commit/20b650e22aa750c4ab6a66aa646bdd95d7cd548a#diff-e81fc111b2052e306d126bd9989f7b7c |
6 " Original Author: Rogerz Zhang <rogerz.zhang at gmail.com> http://github.com/rogerz/vim-json | |
7 " Acknowledgement: Based off of vim-javascript maintained by Darrick Wiebe | |
8 " http://www.vim.org/scripts/script.php?script_id=2765 | |
9 | |
10 " 0. Initialization {{{1 | |
11 " ================= | |
6070
32a77cc160d9
Update runtime files. Make matchparen plugin backwards compatible.
Bram Moolenaar <bram@vim.org>
parents:
diff
changeset
|
12 |
6180 | 13 " Only load this indent file when no other was loaded. |
14 if exists("b:did_indent") | |
15 finish | |
16 endif | |
17 let b:did_indent = 1 | |
18 | |
19 setlocal nosmartindent | |
20 | |
21 " Now, set up our indentation expression and keys that trigger it. | |
22 setlocal indentexpr=GetJSONIndent() | |
23 setlocal indentkeys=0{,0},0),0[,0],!^F,o,O,e | |
24 | |
25 " Only define the function once. | |
26 if exists("*GetJSONIndent") | |
27 finish | |
6070
32a77cc160d9
Update runtime files. Make matchparen plugin backwards compatible.
Bram Moolenaar <bram@vim.org>
parents:
diff
changeset
|
28 endif |
32a77cc160d9
Update runtime files. Make matchparen plugin backwards compatible.
Bram Moolenaar <bram@vim.org>
parents:
diff
changeset
|
29 |
6180 | 30 let s:cpo_save = &cpo |
31 set cpo&vim | |
32 | |
33 " 1. Variables {{{1 | |
34 " ============ | |
35 | |
36 let s:line_term = '\s*\%(\%(\/\/\).*\)\=$' | |
37 " Regex that defines blocks. | |
38 let s:block_regex = '\%({\)\s*\%(|\%([*@]\=\h\w*,\=\s*\)\%(,\s*[*@]\=\h\w*\)*|\)\=' . s:line_term | |
39 | |
40 " 2. Auxiliary Functions {{{1 | |
41 " ====================== | |
42 | |
43 " Check if the character at lnum:col is inside a string. | |
44 function s:IsInString(lnum, col) | |
45 return synIDattr(synID(a:lnum, a:col, 1), 'name') == 'jsonString' | |
46 endfunction | |
47 | |
48 " Find line above 'lnum' that isn't empty, or in a string. | |
49 function s:PrevNonBlankNonString(lnum) | |
50 let lnum = prevnonblank(a:lnum) | |
51 while lnum > 0 | |
52 " If the line isn't empty or in a string, end search. | |
53 let line = getline(lnum) | |
54 if !(s:IsInString(lnum, 1) && s:IsInString(lnum, strlen(line))) | |
55 break | |
56 endif | |
57 let lnum = prevnonblank(lnum - 1) | |
58 endwhile | |
59 return lnum | |
60 endfunction | |
61 | |
62 " Check if line 'lnum' has more opening brackets than closing ones. | |
63 function s:LineHasOpeningBrackets(lnum) | |
64 let open_0 = 0 | |
65 let open_2 = 0 | |
66 let open_4 = 0 | |
67 let line = getline(a:lnum) | |
68 let pos = match(line, '[][(){}]', 0) | |
69 while pos != -1 | |
70 let idx = stridx('(){}[]', line[pos]) | |
71 if idx % 2 == 0 | |
72 let open_{idx} = open_{idx} + 1 | |
73 else | |
74 let open_{idx - 1} = open_{idx - 1} - 1 | |
75 endif | |
76 let pos = match(line, '[][(){}]', pos + 1) | |
77 endwhile | |
78 return (open_0 > 0) . (open_2 > 0) . (open_4 > 0) | |
79 endfunction | |
80 | |
81 function s:Match(lnum, regex) | |
82 let col = match(getline(a:lnum), a:regex) + 1 | |
83 return col > 0 && !s:IsInString(a:lnum, col) ? col : 0 | |
84 endfunction | |
85 | |
86 " 3. GetJSONIndent Function {{{1 | |
87 " ========================= | |
88 | |
89 function GetJSONIndent() | |
90 " 3.1. Setup {{{2 | |
91 " ---------- | |
92 | |
93 " Set up variables for restoring position in file. Could use v:lnum here. | |
94 let vcol = col('.') | |
95 | |
96 " 3.2. Work on the current line {{{2 | |
97 " ----------------------------- | |
6070
32a77cc160d9
Update runtime files. Make matchparen plugin backwards compatible.
Bram Moolenaar <bram@vim.org>
parents:
diff
changeset
|
98 |
6180 | 99 " Get the current line. |
100 let line = getline(v:lnum) | |
101 let ind = -1 | |
102 | |
103 " If we got a closing bracket on an empty line, find its match and indent | |
104 " according to it. | |
105 let col = matchend(line, '^\s*[]}]') | |
106 | |
107 if col > 0 && !s:IsInString(v:lnum, col) | |
108 call cursor(v:lnum, col) | |
109 let bs = strpart('{}[]', stridx('}]', line[col - 1]) * 2, 2) | |
110 | |
111 let pairstart = escape(bs[0], '[') | |
112 let pairend = escape(bs[1], ']') | |
113 let pairline = searchpair(pairstart, '', pairend, 'bW') | |
114 | |
115 if pairline > 0 | |
116 let ind = indent(pairline) | |
117 else | |
118 let ind = virtcol('.') - 1 | |
119 endif | |
120 | |
121 return ind | |
122 endif | |
123 | |
124 " If we are in a multi-line string, don't do anything to it. | |
125 if s:IsInString(v:lnum, matchend(line, '^\s*') + 1) | |
126 return indent('.') | |
127 endif | |
128 | |
129 " 3.3. Work on the previous line. {{{2 | |
130 " ------------------------------- | |
131 | |
132 let lnum = prevnonblank(v:lnum - 1) | |
133 | |
134 if lnum == 0 | |
135 return 0 | |
136 endif | |
137 | |
138 " Set up variables for current line. | |
139 let line = getline(lnum) | |
140 let ind = indent(lnum) | |
141 | |
142 " If the previous line ended with a block opening, add a level of indent. | |
143 " if s:Match(lnum, s:block_regex) | |
11518 | 144 " return indent(lnum) + shiftwidth() |
6180 | 145 " endif |
146 | |
147 " If the previous line contained an opening bracket, and we are still in it, | |
148 " add indent depending on the bracket type. | |
149 if line =~ '[[({]' | |
150 let counts = s:LineHasOpeningBrackets(lnum) | |
151 if counts[0] == '1' || counts[1] == '1' || counts[2] == '1' | |
11518 | 152 return ind + shiftwidth() |
6180 | 153 else |
154 call cursor(v:lnum, vcol) | |
155 end | |
156 endif | |
157 | |
158 " }}}2 | |
159 | |
160 return ind | |
161 endfunction | |
162 | |
163 " }}}1 | |
164 | |
165 let &cpo = s:cpo_save | |
166 unlet s:cpo_save | |
167 | |
168 " vim:set sw=2 sts=2 ts=8 noet: |