diff options
author | Jan Edmund Lazo <jan.lazo@mail.utoronto.ca> | 2020-02-20 22:53:38 -0500 |
---|---|---|
committer | Jan Edmund Lazo <jan.lazo@mail.utoronto.ca> | 2020-02-20 23:39:17 -0500 |
commit | 7ed4837298414488e238763953d40a4c7f2d7976 (patch) | |
tree | f94142cf8e46ebb37c430967e8fe09e3098dd91c /src | |
parent | 13b6f7a80676a0b43325f39dcaebbb2e7adf81c9 (diff) | |
download | rneovim-7ed4837298414488e238763953d40a4c7f2d7976.tar.gz rneovim-7ed4837298414488e238763953d40a4c7f2d7976.tar.bz2 rneovim-7ed4837298414488e238763953d40a4c7f2d7976.zip |
vim-patch:8.1.1122: char2nr() does not handle composing characters
Problem: char2nr() does not handle composing characters.
Solution: Add str2list() and list2str(). (Ozaki Kiichi, closes vim/vim#4190)
https://github.com/vim/vim/commit/9d40128afd7fcd038ff6532722b55b1a8c189ce8
'utf8' optional param is noop unlike Vim.
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/eval.lua | 2 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 41 | ||||
-rw-r--r-- | src/nvim/testdir/test_utf8.vim | 43 |
3 files changed, 86 insertions, 0 deletions
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 17d9cc56aa..4654f8cef6 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -214,6 +214,7 @@ return { line={args=1}, line2byte={args=1}, lispindent={args=1}, + list2str={args={1, 2}}, localtime={}, log={args=1, func="float_op_wrapper", data="&log"}, log10={args=1, func="float_op_wrapper", data="&log10"}, @@ -321,6 +322,7 @@ return { sqrt={args=1, func="float_op_wrapper", data="&sqrt"}, stdpath={args=1}, str2float={args=1}, + str2list={args={1, 2}}, str2nr={args={1, 2}}, strcharpart={args={2, 3}}, strchars={args={1,2}}, diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 36782e4223..bd57cec794 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -5246,6 +5246,36 @@ static void f_lispindent(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } +// "list2str()" function +static void f_list2str(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + garray_T ga; + + rettv->v_type = VAR_STRING; + rettv->vval.v_string = NULL; + if (argvars[0].v_type != VAR_LIST) { + EMSG(_(e_invarg)); + return; + } + + list_T *const l = argvars[0].vval.v_list; + if (l == NULL) { + return; // empty list results in empty string + } + + ga_init(&ga, 1, 80); + char_u buf[MB_MAXBYTES + 1]; + + TV_LIST_ITER_CONST(l, li, { + buf[utf_char2bytes(tv_get_number(TV_LIST_ITEM_TV(li)), buf)] = NUL; + ga_concat(&ga, buf); + }); + ga_append(&ga, NUL); + + rettv->v_type = VAR_STRING; + rettv->vval.v_string = ga.ga_data; +} + /* * "localtime()" function */ @@ -9353,6 +9383,17 @@ static void f_str2float(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->v_type = VAR_FLOAT; } +// "str2list()" function +static void f_str2list(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + tv_list_alloc_ret(rettv, kListLenUnknown); + const char_u *p = (const char_u *)tv_get_string(&argvars[0]); + + for (; *p != NUL; p += utf_ptr2len(p)) { + tv_list_append_number(rettv->vval.v_list, utf_ptr2char(p)); + } +} + // "str2nr()" function static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) { diff --git a/src/nvim/testdir/test_utf8.vim b/src/nvim/testdir/test_utf8.vim index b1f33f56dd..1b4ce4c4af 100644 --- a/src/nvim/testdir/test_utf8.vim +++ b/src/nvim/testdir/test_utf8.vim @@ -60,3 +60,46 @@ func Test_getvcol() call assert_equal(2, virtcol("'[")) call assert_equal(2, virtcol("']")) endfunc + +func Test_list2str_str2list_utf8() + " One Unicode codepoint + let s = "\u3042\u3044" + let l = [0x3042, 0x3044] + call assert_equal(l, str2list(s, 1)) + call assert_equal(s, list2str(l, 1)) + if &enc ==# 'utf-8' + call assert_equal(str2list(s), str2list(s, 1)) + call assert_equal(list2str(l), list2str(l, 1)) + endif + + " With composing characters + let s = "\u304b\u3099\u3044" + let l = [0x304b, 0x3099, 0x3044] + call assert_equal(l, str2list(s, 1)) + call assert_equal(s, list2str(l, 1)) + if &enc ==# 'utf-8' + call assert_equal(str2list(s), str2list(s, 1)) + call assert_equal(list2str(l), list2str(l, 1)) + endif + + " Null list is the same as an empty list + call assert_equal('', list2str([])) + " call assert_equal('', list2str(test_null_list())) +endfunc + +func Test_list2str_str2list_latin1() + " When 'encoding' is not multi-byte can still get utf-8 string. + " But we need to create the utf-8 string while 'encoding' is utf-8. + let s = "\u3042\u3044" + let l = [0x3042, 0x3044] + + let save_encoding = &encoding + " set encoding=latin1 + + let lres = str2list(s, 1) + let sres = list2str(l, 1) + + let &encoding = save_encoding + call assert_equal(l, lres) + call assert_equal(s, sres) +endfunc |