Skip to content

Commit 0abbd05

Browse files
committed
Web.JSON: Add 'ensure_ascii' setting to encode().
1 parent fdfce8d commit 0abbd05

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

autoload/vital/__vital__/Web/JSON.vim

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,25 @@ function! s:encode(val, ...) abort
143143
\ 'indent': 0,
144144
\ 'allow_nan': 1,
145145
\ 'from_encoding': &encoding,
146+
\ 'ensure_ascii': 0,
146147
\}, get(a:000, 0, {})
147148
\)
148-
return s:_encode(a:val, settings)
149+
let json = s:_encode(a:val, settings)
150+
if settings.ensure_ascii
151+
let json = substitute(json, '[\U0000007f-\U0010ffff]',
152+
\ {m -> s:_escape_unicode_chars(m[0])}, 'g')
153+
endif
154+
return json
155+
endfunction
156+
157+
function! s:_escape_unicode_chars(char) abort
158+
let n = char2nr(a:char)
159+
if n < 0x10000
160+
return printf('\u%04x', n)
161+
else
162+
let n -= 0x10000
163+
return printf('\u%04x%\u%04x', 0xd800 + n / 0x400, 0xdc00 + and(0x3ff, n))
164+
endif
149165
endfunction
150166

151167
function! s:_encode(val, settings) abort

doc/vital/Web/JSON.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,18 @@ encode({object}[, {settings}]) *Vital.Web.JSON.encode()*
7777
" => [NaN,Infinity,-Infinity]
7878
echo s:JSON.encode([0.0/0], {'allow_nan': 0})
7979
" => vital: Web.JSON: Invalid float value: nan
80+
<
81+
'ensure_ascii'
82+
If 'ensure_ascii' is 0, all characters without control-chars
83+
(0x01-0x1f) will be output as-is.
84+
Otherwise the output is guaranteed to have all incoming non-ASCII
85+
characters escaped.
86+
The default value is 0.
87+
>
88+
echo s:JSON.encode(["foo", "bár", "\n"])
89+
" => '["foo","bár","\n"]'
90+
echo s:JSON.encode(["foo", "bár", "\n"], {'ensure_ascii': 1})
91+
" => '["foo","b\u00e1r","\n"]'
8092
<
8193
decode({json}[, {settings}]) *Vital.Web.JSON.decode()*
8294
Decode a JSON string into an object that vim can treat.

test/Web/JSON.vimspec

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,14 @@ Describe Web.JSON
157157
Assert Equals(JSON.encode(str_sjis, s), '"sあc漢g"')
158158
End
159159

160+
It encodes strings with {settings.ensure_ascii} = true
161+
let s = { 'ensure_ascii': v:true }
162+
" multibyte
163+
Assert Equals(JSON.encode("s¢cĴgё", s), '"s\u00a2c\u0134g\u0451"')
164+
" UTF-16 surrogate pair
165+
Assert Equals(JSON.encode("su\xf0\x9f\x8d\xa3shi", s), '"su\ud83c\udf63shi"')
166+
End
167+
160168
It encodes lists
161169
Assert Equals(JSON.encode([]), '[]')
162170
Assert Equals(JSON.encode([0, 1, 2]), '[0,1,2]')

0 commit comments

Comments
 (0)