Mercurial > vim
annotate runtime/indent/json.vim @ 27392:ec2ba9acec1b v8.2.4224
patch 8.2.4224: Vim9: no error when using a number for map() second argument
Commit: https://github.com/vim/vim/commit/1080c48ec8d672d7e9fbefb5a1255c9df09a2884
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed Jan 26 18:26:21 2022 +0000
patch 8.2.4224: Vim9: no error when using a number for map() second argument
Problem: Vim9: no error when using a number for map() second argument
Solution: Disallow number to string conversion. (closes https://github.com/vim/vim/issues/9630)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 26 Jan 2022 19:30:03 +0100 |
parents | 11b656e74444 |
children | fee9eccee266 |
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 |
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. | |
22171 | 22 setlocal indentexpr=GetJSONIndent(v:lnum) |
6180 | 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 | |
22171 | 89 function GetJSONIndent(...) |
6180 | 90 " 3.1. Setup {{{2 |
91 " ---------- | |
22171 | 92 " For the current line, use the first argument if given, else v:lnum |
93 let clnum = a:0 ? a:1 : v:lnum | |
6180 | 94 |
22171 | 95 " Set up variables for restoring position in file. Could use clnum here. |
6180 | 96 let vcol = col('.') |
97 | |
98 " 3.2. Work on the current line {{{2 | |
99 " ----------------------------- | |
6070
32a77cc160d9
Update runtime files. Make matchparen plugin backwards compatible.
Bram Moolenaar <bram@vim.org>
parents:
diff
changeset
|
100 |
6180 | 101 " Get the current line. |
22171 | 102 let line = getline(clnum) |
6180 | 103 let ind = -1 |
104 | |
105 " If we got a closing bracket on an empty line, find its match and indent | |
106 " according to it. | |
107 let col = matchend(line, '^\s*[]}]') | |
108 | |
22171 | 109 if col > 0 && !s:IsInString(clnum, col) |
110 call cursor(clnum, col) | |
6180 | 111 let bs = strpart('{}[]', stridx('}]', line[col - 1]) * 2, 2) |
112 | |
113 let pairstart = escape(bs[0], '[') | |
114 let pairend = escape(bs[1], ']') | |
115 let pairline = searchpair(pairstart, '', pairend, 'bW') | |
116 | |
117 if pairline > 0 | |
118 let ind = indent(pairline) | |
119 else | |
120 let ind = virtcol('.') - 1 | |
121 endif | |
122 | |
123 return ind | |
124 endif | |
125 | |
126 " If we are in a multi-line string, don't do anything to it. | |
22171 | 127 if s:IsInString(clnum, matchend(line, '^\s*') + 1) |
6180 | 128 return indent('.') |
129 endif | |
130 | |
131 " 3.3. Work on the previous line. {{{2 | |
132 " ------------------------------- | |
133 | |
22171 | 134 let lnum = prevnonblank(clnum - 1) |
6180 | 135 |
136 if lnum == 0 | |
137 return 0 | |
138 endif | |
139 | |
140 " Set up variables for current line. | |
141 let line = getline(lnum) | |
142 let ind = indent(lnum) | |
143 | |
144 " If the previous line ended with a block opening, add a level of indent. | |
145 " if s:Match(lnum, s:block_regex) | |
11518 | 146 " return indent(lnum) + shiftwidth() |
6180 | 147 " endif |
148 | |
149 " If the previous line contained an opening bracket, and we are still in it, | |
150 " add indent depending on the bracket type. | |
151 if line =~ '[[({]' | |
152 let counts = s:LineHasOpeningBrackets(lnum) | |
153 if counts[0] == '1' || counts[1] == '1' || counts[2] == '1' | |
11518 | 154 return ind + shiftwidth() |
6180 | 155 else |
22171 | 156 call cursor(clnum, vcol) |
6180 | 157 end |
158 endif | |
159 | |
160 " }}}2 | |
161 | |
162 return ind | |
163 endfunction | |
164 | |
165 " }}}1 | |
166 | |
167 let &cpo = s:cpo_save | |
168 unlet s:cpo_save | |
169 | |
170 " vim:set sw=2 sts=2 ts=8 noet: |