Mercurial > vim
annotate runtime/indent/yaml.vim @ 33361:241a1c2d30fd v9.0.1942
patch 9.0.1942: Vim9: execution stack invalidated with null object
Commit: https://github.com/vim/vim/commit/c1946267f22efe3ec5eb0a1a914f30782a538983
Author: Yegappan Lakshmanan <yegappan@yahoo.com>
Date: Mon Sep 25 21:00:46 2023 +0200
patch 9.0.1942: Vim9: execution stack invalidated with null object
Problem: Vim9: execution stack invalidated with null object
Solution: Check for a null object before adjusting the execution stack
closes: #13186
Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Mon, 25 Sep 2023 21:15:07 +0200 |
parents | ebed259f919f |
children | e3d2ba1fd1a3 |
rev | line source |
---|---|
3996 | 1 " Vim indent file |
20753 | 2 " Language: YAML |
3 " Maintainer: Nikolai Pavlov <zyx.vim@gmail.com> | |
30085 | 4 " Last Updates: Lukas Reineke, "lacygoill" |
29236 | 5 " Last Change: 2022 Jun 17 |
3996 | 6 |
7 " Only load this indent file when no other was loaded. | |
8 if exists('b:did_indent') | |
9 finish | |
10 endif | |
11 | |
12 let b:did_indent = 1 | |
13 | |
14 setlocal indentexpr=GetYAMLIndent(v:lnum) | |
7228
873eae260c97
commit https://github.com/vim/vim/commit/b4ff518d95aa57c2f8c0568c915035bef849581b
Christian Brabandt <cb@256bit.org>
parents:
7147
diff
changeset
|
15 setlocal indentkeys=!^F,o,O,0#,0},0],<:>,0- |
3996 | 16 setlocal nosmartindent |
17 | |
18 let b:undo_indent = 'setlocal indentexpr< indentkeys< smartindent<' | |
19 | |
20 " Only define the function once. | |
21 if exists('*GetYAMLIndent') | |
22 finish | |
23 endif | |
24 | |
23737 | 25 let s:save_cpo = &cpo |
26 set cpo&vim | |
27 | |
3996 | 28 function s:FindPrevLessIndentedLine(lnum, ...) |
29 let prevlnum = prevnonblank(a:lnum-1) | |
30 let curindent = a:0 ? a:1 : indent(a:lnum) | |
31 while prevlnum | |
30085 | 32 \ && indent(prevlnum) >= curindent |
33 \ && getline(prevlnum) !~# '^\s*#' | |
3996 | 34 let prevlnum = prevnonblank(prevlnum-1) |
35 endwhile | |
36 return prevlnum | |
37 endfunction | |
38 | |
39 function s:FindPrevLEIndentedLineMatchingRegex(lnum, regex) | |
40 let plilnum = s:FindPrevLessIndentedLine(a:lnum, indent(a:lnum)+1) | |
41 while plilnum && getline(plilnum) !~# a:regex | |
42 let plilnum = s:FindPrevLessIndentedLine(plilnum) | |
43 endwhile | |
44 return plilnum | |
45 endfunction | |
46 | |
29236 | 47 let s:mapkeyregex = '\v^\s*\#@!\S@=%(\''%([^'']|\''\'')*\''' .. |
48 \ '|\"%([^"\\]|\\.)*\"' .. | |
9887
b4da19b7539f
commit https://github.com/vim/vim/commit/dc1f1645cb495fa6bfbe216d7359f23539a0e25d
Christian Brabandt <cb@256bit.org>
parents:
7228
diff
changeset
|
49 \ '|%(%(\:\ )@!.)*)\:%(\ |$)' |
29236 | 50 let s:liststartregex = '\v^\s*%(\-%(\ |$))' |
3996 | 51 |
9887
b4da19b7539f
commit https://github.com/vim/vim/commit/dc1f1645cb495fa6bfbe216d7359f23539a0e25d
Christian Brabandt <cb@256bit.org>
parents:
7228
diff
changeset
|
52 let s:c_ns_anchor_char = '\v%([\n\r\uFEFF \t,[\]{}]@!\p)' |
29236 | 53 let s:c_ns_anchor_name = s:c_ns_anchor_char .. '+' |
54 let s:c_ns_anchor_property = '\v\&' .. s:c_ns_anchor_name | |
9887
b4da19b7539f
commit https://github.com/vim/vim/commit/dc1f1645cb495fa6bfbe216d7359f23539a0e25d
Christian Brabandt <cb@256bit.org>
parents:
7228
diff
changeset
|
55 |
b4da19b7539f
commit https://github.com/vim/vim/commit/dc1f1645cb495fa6bfbe216d7359f23539a0e25d
Christian Brabandt <cb@256bit.org>
parents:
7228
diff
changeset
|
56 let s:ns_word_char = '\v[[:alnum:]_\-]' |
30085 | 57 let s:ns_tag_char = '\v%(\x\x|' .. s:ns_word_char .. '|[#/;?:@&=+$.~*''()])' |
29236 | 58 let s:c_named_tag_handle = '\v\!' .. s:ns_word_char .. '+\!' |
9887
b4da19b7539f
commit https://github.com/vim/vim/commit/dc1f1645cb495fa6bfbe216d7359f23539a0e25d
Christian Brabandt <cb@256bit.org>
parents:
7228
diff
changeset
|
59 let s:c_secondary_tag_handle = '\v\!\!' |
b4da19b7539f
commit https://github.com/vim/vim/commit/dc1f1645cb495fa6bfbe216d7359f23539a0e25d
Christian Brabandt <cb@256bit.org>
parents:
7228
diff
changeset
|
60 let s:c_primary_tag_handle = '\v\!' |
29236 | 61 let s:c_tag_handle = '\v%(' .. s:c_named_tag_handle. |
62 \ '|' .. s:c_secondary_tag_handle. | |
63 \ '|' .. s:c_primary_tag_handle .. ')' | |
64 let s:c_ns_shorthand_tag = '\v' .. s:c_tag_handle .. s:ns_tag_char .. '+' | |
9887
b4da19b7539f
commit https://github.com/vim/vim/commit/dc1f1645cb495fa6bfbe216d7359f23539a0e25d
Christian Brabandt <cb@256bit.org>
parents:
7228
diff
changeset
|
65 let s:c_non_specific_tag = '\v\!' |
30085 | 66 let s:ns_uri_char = '\v%(\x\x|' .. s:ns_word_char .. '\v|[#/;?:@&=+$,.!~*''()[\]])' |
29236 | 67 let s:c_verbatim_tag = '\v\!\<' .. s:ns_uri_char.. '+\>' |
68 let s:c_ns_tag_property = '\v' .. s:c_verbatim_tag. | |
69 \ '\v|' .. s:c_ns_shorthand_tag. | |
70 \ '\v|' .. s:c_non_specific_tag | |
9887
b4da19b7539f
commit https://github.com/vim/vim/commit/dc1f1645cb495fa6bfbe216d7359f23539a0e25d
Christian Brabandt <cb@256bit.org>
parents:
7228
diff
changeset
|
71 |
b4da19b7539f
commit https://github.com/vim/vim/commit/dc1f1645cb495fa6bfbe216d7359f23539a0e25d
Christian Brabandt <cb@256bit.org>
parents:
7228
diff
changeset
|
72 let s:block_scalar_header = '\v[|>]%([+-]?[1-9]|[1-9]?[+-])?' |
b4da19b7539f
commit https://github.com/vim/vim/commit/dc1f1645cb495fa6bfbe216d7359f23539a0e25d
Christian Brabandt <cb@256bit.org>
parents:
7228
diff
changeset
|
73 |
3996 | 74 function GetYAMLIndent(lnum) |
75 if a:lnum == 1 || !prevnonblank(a:lnum-1) | |
76 return 0 | |
77 endif | |
78 | |
79 let prevlnum = prevnonblank(a:lnum-1) | |
80 let previndent = indent(prevlnum) | |
81 | |
82 let line = getline(a:lnum) | |
83 if line =~# '^\s*#' && getline(a:lnum-1) =~# '^\s*#' | |
84 " Comment blocks should have identical indent | |
85 return previndent | |
86 elseif line =~# '^\s*[\]}]' | |
87 " Lines containing only closing braces should have previous indent | |
88 return indent(s:FindPrevLessIndentedLine(a:lnum)) | |
89 endif | |
90 | |
91 " Ignore comment lines when calculating indent | |
92 while getline(prevlnum) =~# '^\s*#' | |
93 let prevlnum = prevnonblank(prevlnum-1) | |
94 if !prevlnum | |
95 return previndent | |
96 endif | |
97 endwhile | |
98 | |
99 let prevline = getline(prevlnum) | |
100 let previndent = indent(prevlnum) | |
101 | |
102 " Any examples below assume that shiftwidth=2 | |
103 if prevline =~# '\v[{[:]$|[:-]\ [|>][+\-]?%(\s+\#.*|\s*)$' | |
104 " Mapping key: | |
105 " nested mapping: ... | |
106 " | |
107 " - { | |
108 " key: [ | |
109 " list value | |
110 " ] | |
111 " } | |
112 " | |
113 " - |- | |
114 " Block scalar without indentation indicator | |
11518 | 115 return previndent+shiftwidth() |
3996 | 116 elseif prevline =~# '\v[:-]\ [|>]%(\d+[+\-]?|[+\-]?\d+)%(\#.*|\s*)$' |
117 " - |+2 | |
118 " block scalar with indentation indicator | |
119 "#^^ indent+2, not indent+shiftwidth | |
120 return previndent + str2nr(matchstr(prevline, | |
121 \'\v([:-]\ [|>])@<=[+\-]?\d+%([+\-]?%(\s+\#.*|\s*)$)@=')) | |
122 elseif prevline =~# '\v\"%([^"\\]|\\.)*\\$' | |
123 " "Multiline string \ | |
124 " with escaped end" | |
125 let qidx = match(prevline, '\v\"%([^"\\]|\\.)*\\') | |
126 return virtcol([prevlnum, qidx+1]) | |
127 elseif line =~# s:liststartregex | |
128 " List line should have indent equal to previous list line unless it was | |
129 " caught by one of the previous rules | |
130 return indent(s:FindPrevLEIndentedLineMatchingRegex(a:lnum, | |
131 \ s:liststartregex)) | |
132 elseif line =~# s:mapkeyregex | |
133 " Same for line containing mapping key | |
7147
c590de398af9
commit https://github.com/vim/vim/commit/ca63501fbcd1cf9c8aa9ff12c093c95b62a89ed7
Christian Brabandt <cb@256bit.org>
parents:
3996
diff
changeset
|
134 let prevmapline = s:FindPrevLEIndentedLineMatchingRegex(a:lnum, |
c590de398af9
commit https://github.com/vim/vim/commit/ca63501fbcd1cf9c8aa9ff12c093c95b62a89ed7
Christian Brabandt <cb@256bit.org>
parents:
3996
diff
changeset
|
135 \ s:mapkeyregex) |
c590de398af9
commit https://github.com/vim/vim/commit/ca63501fbcd1cf9c8aa9ff12c093c95b62a89ed7
Christian Brabandt <cb@256bit.org>
parents:
3996
diff
changeset
|
136 if getline(prevmapline) =~# '^\s*- ' |
c590de398af9
commit https://github.com/vim/vim/commit/ca63501fbcd1cf9c8aa9ff12c093c95b62a89ed7
Christian Brabandt <cb@256bit.org>
parents:
3996
diff
changeset
|
137 return indent(prevmapline) + 2 |
c590de398af9
commit https://github.com/vim/vim/commit/ca63501fbcd1cf9c8aa9ff12c093c95b62a89ed7
Christian Brabandt <cb@256bit.org>
parents:
3996
diff
changeset
|
138 else |
c590de398af9
commit https://github.com/vim/vim/commit/ca63501fbcd1cf9c8aa9ff12c093c95b62a89ed7
Christian Brabandt <cb@256bit.org>
parents:
3996
diff
changeset
|
139 return indent(prevmapline) |
c590de398af9
commit https://github.com/vim/vim/commit/ca63501fbcd1cf9c8aa9ff12c093c95b62a89ed7
Christian Brabandt <cb@256bit.org>
parents:
3996
diff
changeset
|
140 endif |
3996 | 141 elseif prevline =~# '^\s*- ' |
142 " - List with | |
143 " multiline scalar | |
144 return previndent+2 | |
29236 | 145 elseif prevline =~# s:mapkeyregex .. '\v\s*%(%(' .. s:c_ns_tag_property .. |
146 \ '\v|' .. s:c_ns_anchor_property .. | |
147 \ '\v|' .. s:block_scalar_header .. | |
9887
b4da19b7539f
commit https://github.com/vim/vim/commit/dc1f1645cb495fa6bfbe216d7359f23539a0e25d
Christian Brabandt <cb@256bit.org>
parents:
7228
diff
changeset
|
148 \ '\v)%(\s+|\s*%(\#.*)?$))*' |
3996 | 149 " Mapping with: value |
150 " that is multiline scalar | |
11518 | 151 return previndent+shiftwidth() |
3996 | 152 endif |
153 return previndent | |
154 endfunction | |
155 | |
156 let &cpo = s:save_cpo |