@@ -26,13 +26,11 @@ endfunction
26
26
"
27
27
" private api
28
28
"
29
- " work around: '[^\r\n]*' doesn't work well in old-vim, but "[^\r\n]*" works well
30
- let s: skip_pattern = ' \C^\%(\_s\+\|' . " #[^\r \n ]*" . ' \)'
31
- let s: table_name_pattern = ' \%([^ [:tab:]#.[\]=]\+\)'
32
- let s: table_key_pattern = s: table_name_pattern
29
+ let s: skip_pattern = ' \C^\%(\%(\s\|\r\?\n\)\+\|#[^\r\n]*\)'
30
+ let s: bare_key_pattern = ' \%([A-Za-z0-9_-]\+\)'
33
31
34
32
function ! s: _skip (input ) abort
35
- while s: _match (a: input , ' \%(\_s \|#\)' )
33
+ while s: _match (a: input , ' \%(\s\|\r\?\n \|#\)' )
36
34
let a: input .p = matchend (a: input .text, s: skip_pattern , a: input .p )
37
35
endwhile
38
36
endfunction
@@ -68,14 +66,10 @@ function! s:_eof(input) abort
68
66
endfunction
69
67
70
68
function ! s: _error (input ) abort
71
- let buf = []
72
- let offset = 0
73
- while (a: input .p + offset) < a: input .length && a: input .text[a: input .p + offset] !~# " [\r \n ]"
74
- let buf += [a: input .text[a: input .p + offset]]
75
- let offset += 1
76
- endwhile
69
+ let s = matchstr (a: input .text, s: regex_prefix . ' .\{-}\ze\%(\r\?\n\|$\)' , a: input .p )
70
+ let s = substitute (s , ' \r' , ' \\r' , ' g' )
77
71
78
- throw printf (" vital: Text.TOML: Illegal toml format at `%s'." , join ( buf , ' ' ) )
72
+ throw printf (" vital: Text.TOML: Illegal toml format at `%s'." , s )
79
73
endfunction
80
74
81
75
function ! s: _parse (input ) abort
@@ -84,25 +78,16 @@ function! s:_parse(input) abort
84
78
call s: _skip (a: input )
85
79
while ! s: _eof (a: input )
86
80
if s: _match (a: input , ' [^ [:tab:]#.[\]]' )
87
- let key = s: _key (a: input )
81
+ let keys = s: _keys (a: input, ' = ' )
88
82
call s: _equals (a: input )
89
83
let value = s: _value (a: input )
90
-
91
- call s: _put_dict (data, key , value)
92
-
93
- unlet value
84
+ call s: _put_dict (data, keys , value)
94
85
elseif s: _match (a: input , ' \[\[' )
95
- let [key , value] = s: _array_of_tables (a: input )
96
-
97
- call s: _put_array (data, key , value)
98
-
99
- unlet value
86
+ let [keys , value] = s: _array_of_tables (a: input )
87
+ call s: _put_array (data, keys , value)
100
88
elseif s: _match (a: input , ' \[' )
101
- let [key , value] = s: _table (a: input )
102
-
103
- call s: _put_dict (data, key , value)
104
-
105
- unlet value
89
+ let [keys , value] = s: _table (a: input )
90
+ call s: _put_dict (data, keys , value)
106
91
else
107
92
call s: _error (a: input )
108
93
endif
@@ -112,14 +97,26 @@ function! s:_parse(input) abort
112
97
return data
113
98
endfunction
114
99
115
- function ! s: _key (input ) abort
116
- let s = s: _consume (a: input , s: table_key_pattern )
117
- return s
100
+ function ! s: _keys (input , end ) abort
101
+ let keys = []
102
+ while ! s: _eof (a: input ) && ! s: _match (a: input , a: end )
103
+ call s: _skip (a: input )
104
+ if s: _match (a: input , ' "' )
105
+ let key = s: _basic_string (a: input )
106
+ else
107
+ let key = s: _consume (a: input , s: bare_key_pattern )
108
+ endif
109
+ let keys += [key ]
110
+ call s: _consume (a: input , ' \.\?' )
111
+ endwhile
112
+ if empty (keys )
113
+ return s: _error (a: input )
114
+ endif
115
+ return keys
118
116
endfunction
119
117
120
118
function ! s: _equals (input ) abort
121
- call s: _consume (a: input , ' =' )
122
- return ' ='
119
+ return s: _consume (a: input , ' =' )
123
120
endfunction
124
121
125
122
function ! s: _value (input ) abort
@@ -135,11 +132,13 @@ function! s:_value(input) abort
135
132
return s: _literal (a: input )
136
133
elseif s: _match (a: input , ' \[' )
137
134
return s: _array (a: input )
135
+ elseif s: _match (a: input , ' {' )
136
+ return s: _inline_table (a: input )
138
137
elseif s: _match (a: input , ' \%(true\|false\)' )
139
138
return s: _boolean (a: input )
140
139
elseif s: _match (a: input , ' \d\{4}-' )
141
140
return s: _datetime (a: input )
142
- elseif s: _match (a: input , ' [+-]\?\%( \d\+\.\d\|\ d\+\%(\.\d\+\)\?[eE]\)' )
141
+ elseif s: _match (a: input , ' [+-]\?\d\+\%(_ \d\+\)*\%(\ .\d\+\%(_\ d\+\)*\|\ %(\.\d\+\%(_\d\+\)* \)\?[eE]\)' )
143
142
return s: _float (a: input )
144
143
else
145
144
return s: _integer (a: input )
@@ -158,8 +157,8 @@ endfunction
158
157
function ! s: _multiline_basic_string (input ) abort
159
158
let s = s: _consume (a: input , ' "\{3}\%(\\.\|\_.\)\{-}"\{3}' )
160
159
let s = s [3 : -4 ]
161
- let s = substitute (s , " ^ \n " , ' ' , ' ' )
162
- let s = substitute (s , ' \\' . " \n " . ' \_s *' , ' ' , ' g' )
160
+ let s = substitute (s , ' ^\r\?\n ' , ' ' , ' ' )
161
+ let s = substitute (s , ' \\\%(\s\|\r\?\n\) *' , ' ' , ' g' )
163
162
return s: _unescape (s )
164
163
endfunction
165
164
@@ -171,36 +170,25 @@ endfunction
171
170
function ! s: _multiline_literal (input ) abort
172
171
let s = s: _consume (a: input , " '\\ {3}.\\ {-}'\\ {3}" )
173
172
let s = s [3 : -4 ]
174
- let s = substitute (s , " ^ \n " , ' ' , ' ' )
173
+ let s = substitute (s , ' ^\r\?\n ' , ' ' , ' ' )
175
174
return s
176
175
endfunction
177
176
178
177
"
179
178
" Integer
180
179
"
181
180
function ! s: _integer (input ) abort
182
- let s = s: _consume (a: input , ' [+-]\?\d\+' )
181
+ let s = s: _consume (a: input , ' [+-]\?\d\+\%(_\d\+\)*' )
182
+ let s = substitute (s , ' _' , ' ' , ' g' )
183
183
return str2nr (s )
184
184
endfunction
185
185
186
186
"
187
187
" Float
188
188
"
189
189
function ! s: _float (input ) abort
190
- if s: _match (a: input , ' [+-]\?[0-9.]\+[eE][+-]\?\d\+' )
191
- return s: _exponent (a: input )
192
- else
193
- return s: _fractional (a: input )
194
- endif
195
- endfunction
196
-
197
- function ! s: _fractional (input ) abort
198
- let s = s: _consume (a: input , ' [+-]\?[0-9.]\+' )
199
- return str2float (s )
200
- endfunction
201
-
202
- function ! s: _exponent (input ) abort
203
- let s = s: _consume (a: input , ' [+-]\?[0-9.]\+[eE][+-]\?\d\+' )
190
+ let s = s: _consume (a: input , ' [+-]\?[0-9._]\+\%([eE][+-]\?\d\+\%(_\d\+\)*\)\?' )
191
+ let s = substitute (s , ' _' , ' ' , ' g' )
204
192
return str2float (s )
205
193
endfunction
206
194
@@ -241,40 +229,54 @@ endfunction
241
229
"
242
230
function ! s: _table (input ) abort
243
231
let tbl = {}
244
- let name = s: _consume (a: input , ' \[\s*' . s: table_name_pattern . ' \%(\s*\.\s*' . s: table_name_pattern . ' \)*\s*\]' )
245
- let name = name[1 : -2 ]
232
+ call s: _consume (a: input , ' \[' )
233
+ let name = s: _keys (a: input , ' \]' )
234
+ call s: _consume (a: input , ' \]' )
246
235
call s: _skip (a: input )
247
236
" while !s:_eof(a:input) && !s:_match(a:input, '\[\{1,2}[a-zA-Z0-9.]\+\]\{1,2}')
248
237
while ! s: _eof (a: input ) && ! s: _match (a: input , ' \[' )
249
- let key = s: _key (a: input )
238
+ let keys = s: _keys (a: input, ' = ' )
250
239
call s: _equals (a: input )
251
240
let value = s: _value (a: input )
252
-
253
- let tbl[key ] = value
254
-
255
- unlet value
241
+ call s: _put_dict (tbl, keys , value)
256
242
call s: _skip (a: input )
257
243
endwhile
258
244
return [name, tbl]
259
245
endfunction
260
246
261
247
"
262
- " Array of tables
248
+ " Inline Table
249
+ "
250
+ function ! s: _inline_table (input ) abort
251
+ let tbl = {}
252
+ call s: _consume (a: input , ' {' )
253
+ while ! s: _eof (a: input ) && ! s: _match (a: input , ' }' )
254
+ let keys = s: _keys (a: input , ' =' )
255
+ call s: _equals (a: input )
256
+ let value = s: _value (a: input )
257
+ call s: _put_dict (tbl, keys , value)
258
+ call s: _consume (a: input , ' ,\?' )
259
+ call s: _skip (a: input )
260
+ endwhile
261
+ call s: _consume (a: input , ' }' )
262
+ return tbl
263
+ endfunction
264
+
265
+ "
266
+ " Array of Tables
263
267
"
264
268
function ! s: _array_of_tables (input ) abort
265
269
let tbl = {}
266
- let name = s: _consume (a: input , ' \[\[\s*' . s: table_name_pattern . ' \%(\s*\.\s*' . s: table_name_pattern . ' \)*\s*\]\]' )
267
- let name = name[2 : -3 ]
270
+ call s: _consume (a: input , ' \[\[' )
271
+ let name = s: _keys (a: input , ' \]\]' )
272
+ call s: _consume (a: input , ' \]\]' )
268
273
call s: _skip (a: input )
269
274
" while !s:_eof(a:input) && !s:_match(a:input, '\[\{1,2}[a-zA-Z0-9.]\+\]\{1,2}')
270
275
while ! s: _eof (a: input ) && ! s: _match (a: input , ' \[' )
271
- let key = s: _key (a: input )
276
+ let keys = s: _keys (a: input, ' = ' )
272
277
call s: _equals (a: input )
273
278
let value = s: _value (a: input )
274
-
275
- let tbl[key ] = value
276
-
277
- unlet value
279
+ call s: _put_dict (tbl, keys , value)
278
280
call s: _skip (a: input )
279
281
endwhile
280
282
return [name, [tbl]]
@@ -288,7 +290,6 @@ function! s:_unescape(text) abort
288
290
let text = substitute (text, ' \\n' , " \n " , ' g' )
289
291
let text = substitute (text, ' \\f' , " \f " , ' g' )
290
292
let text = substitute (text, ' \\r' , " \r " , ' g' )
291
- let text = substitute (text, ' \\/' , ' /' , ' g' )
292
293
let text = substitute (text, ' \\\\' , ' \' , ' g' )
293
294
let text = substitute (text, ' \C\\u\(\x\{4}\)' , ' \=s:_nr2char("0x" . submatch(1))' , ' g' )
294
295
let text = substitute (text, ' \C\\U\(\x\{8}\)' , ' \=s:_nr2char("0x" . submatch(1))' , ' g' )
@@ -299,39 +300,35 @@ function! s:_nr2char(nr) abort
299
300
return iconv (nr2char (a: nr ), &encoding , ' utf8' )
300
301
endfunction
301
302
302
- function ! s: _put_dict (dict , key , value) abort
303
- let keys = split (a: key , ' \.' )
304
-
303
+ function ! s: _put_dict (dict , keys , value) abort
305
304
let ref = a: dict
306
- for key in keys [ : -2 ]
307
- if has_key (ref, key ) && type (ref[key ]) == type ({})
305
+ for key in a: keys [: -2 ]
306
+ if has_key (ref, key ) && type (ref[key ]) == v: t_dict
308
307
let ref = ref[key ]
309
- elseif has_key (ref, key ) && type (ref[key ]) == type ([])
308
+ elseif has_key (ref, key ) && type (ref[key ]) == v: t_list
310
309
let ref = ref[key ][-1 ]
311
310
else
312
311
let ref[key ] = {}
313
312
let ref = ref[key ]
314
313
endif
315
314
endfor
316
315
317
- let ref[keys [-1 ]] = a: value
316
+ let ref[a: keys [-1 ]] = a: value
318
317
endfunction
319
318
320
- function ! s: _put_array (dict , key , value) abort
321
- let keys = split (a: key , ' \.' )
322
-
319
+ function ! s: _put_array (dict , keys , value) abort
323
320
let ref = a: dict
324
- for key in keys [ : -2 ]
321
+ for key in a: keys [: -2 ]
325
322
let ref[key ] = get (ref, key , {})
326
323
327
- if type (ref[key ]) == type ([])
324
+ if type (ref[key ]) == v: t_list
328
325
let ref = ref[key ][-1 ]
329
326
else
330
327
let ref = ref[key ]
331
328
endif
332
329
endfor
333
330
334
- let ref[keys [-1 ]] = get (ref, keys [-1 ], []) + a: value
331
+ let ref[a: keys [-1 ]] = get (ref, a: keys [-1 ], []) + a: value
335
332
endfunction
336
333
337
334
let &cpo = s: save_cpo
0 commit comments