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