mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 03:18:16 +00:00
Merge pull request #14326 from janlazo/vim-8.2.0623
vim-patch:8.2.{623,1822,2738}
This commit is contained in:
@@ -5563,13 +5563,14 @@ id({expr}) *id()*
|
||||
Returns a |String| which is a unique identifier of the
|
||||
container type (|List|, |Dict| and |Partial|). It is
|
||||
guaranteed that for the mentioned types `id(v1) ==# id(v2)`
|
||||
returns true iff `type(v1) == type(v2) && v1 is v2` (note:
|
||||
|v:_null_list| and |v:_null_dict| have the same `id()` with
|
||||
different types because they are internally represented as
|
||||
a NULL pointers). Currently `id()` returns a hexadecimal
|
||||
representanion of the pointers to the containers (i.e. like
|
||||
`0x994a40`), same as `printf("%p", {expr})`, but it is advised
|
||||
against counting on exact format of return value.
|
||||
returns true iff `type(v1) == type(v2) && v1 is v2`.
|
||||
Note that |v:_null_string|, |v:_null_list|, and |v:_null_dict|
|
||||
have the same `id()` with different types because they are
|
||||
internally represented as a NULL pointers. `id()` returns a
|
||||
hexadecimal representanion of the pointers to the containers
|
||||
(i.e. like `0x994a40`), same as `printf("%p", {expr})`,
|
||||
but it is advised against counting on the exact format of
|
||||
return value.
|
||||
|
||||
It is not guaranteed that `id(no_longer_existing_container)`
|
||||
will not be equal to some other `id()`: new containers may
|
||||
|
@@ -229,6 +229,7 @@ static struct vimvar {
|
||||
// Neovim
|
||||
VV(VV_STDERR, "stderr", VAR_NUMBER, VV_RO),
|
||||
VV(VV_MSGPACK_TYPES, "msgpack_types", VAR_DICT, VV_RO),
|
||||
VV(VV__NULL_STRING, "_null_string", VAR_STRING, VV_RO),
|
||||
VV(VV__NULL_LIST, "_null_list", VAR_LIST, VV_RO),
|
||||
VV(VV__NULL_DICT, "_null_dict", VAR_DICT, VV_RO),
|
||||
VV(VV_LUA, "lua", VAR_PARTIAL, VV_RO),
|
||||
|
@@ -158,6 +158,7 @@ typedef enum {
|
||||
// Neovim
|
||||
VV_STDERR,
|
||||
VV_MSGPACK_TYPES,
|
||||
VV__NULL_STRING, // String with NULL value. For test purposes only.
|
||||
VV__NULL_LIST, // List with NULL value. For test purposes only.
|
||||
VV__NULL_DICT, // Dictionary with NULL value. For test purposes only.
|
||||
VV_LUA,
|
||||
|
@@ -506,6 +506,15 @@ func Test_dict_lock_extend()
|
||||
call assert_equal({'a': 99, 'b': 100}, d)
|
||||
endfunc
|
||||
|
||||
" Cannot use += with a locked dict
|
||||
func Test_dict_lock_operator()
|
||||
unlet! d
|
||||
let d = {}
|
||||
lockvar d
|
||||
call assert_fails("let d += {'k' : 10}", 'E741:')
|
||||
unlockvar d
|
||||
endfunc
|
||||
|
||||
" No remove() of write-protected scope-level variable
|
||||
func! Tfunc(this_is_a_long_parameter_name)
|
||||
call assert_fails("call remove(a:, 'this_is_a_long_parameter_name')", 'E742')
|
||||
@@ -709,6 +718,23 @@ func Test_listdict_extend()
|
||||
|
||||
call assert_fails("call extend([1, 2], 1)", 'E712:')
|
||||
call assert_fails("call extend([1, 2], {})", 'E712:')
|
||||
|
||||
" Extend g: dictionary with an invalid variable name
|
||||
call assert_fails("call extend(g:, {'-!' : 10})", 'E461:')
|
||||
|
||||
" Extend a list with itself.
|
||||
let l = [1, 5, 7]
|
||||
call extend(l, l, 0)
|
||||
call assert_equal([1, 5, 7, 1, 5, 7], l)
|
||||
let l = [1, 5, 7]
|
||||
call extend(l, l, 1)
|
||||
call assert_equal([1, 1, 5, 7, 5, 7], l)
|
||||
let l = [1, 5, 7]
|
||||
call extend(l, l, 2)
|
||||
call assert_equal([1, 5, 1, 5, 7, 7], l)
|
||||
let l = [1, 5, 7]
|
||||
call extend(l, l, 3)
|
||||
call assert_equal([1, 5, 7, 1, 5, 7], l)
|
||||
endfunc
|
||||
|
||||
func s:check_scope_dict(x, fixed)
|
||||
@@ -782,3 +808,40 @@ func Test_scope_dict()
|
||||
" Test for v:
|
||||
call s:check_scope_dict('v', v:true)
|
||||
endfunc
|
||||
|
||||
" Test for a null list
|
||||
func Test_null_list()
|
||||
let l = v:_null_list
|
||||
call assert_equal('', join(l))
|
||||
call assert_equal(0, len(l))
|
||||
call assert_equal(1, empty(l))
|
||||
call assert_fails('let s = join([1, 2], [])', 'E730:')
|
||||
call assert_equal([], split(v:_null_string))
|
||||
call assert_equal([], l[:2])
|
||||
call assert_true([] == l)
|
||||
call assert_equal('[]', string(l))
|
||||
" call assert_equal(0, sort(l))
|
||||
" call assert_equal(0, sort(l))
|
||||
" call assert_equal(0, uniq(l))
|
||||
let k = [] + l
|
||||
call assert_equal([], k)
|
||||
let k = l + []
|
||||
call assert_equal([], k)
|
||||
call assert_equal(0, len(copy(l)))
|
||||
call assert_equal(0, count(l, 5))
|
||||
call assert_equal([], deepcopy(l))
|
||||
call assert_equal(5, get(l, 2, 5))
|
||||
call assert_equal(-1, index(l, 2, 5))
|
||||
" call assert_equal(0, insert(l, 2, -1))
|
||||
call assert_equal(0, min(l))
|
||||
call assert_equal(0, max(l))
|
||||
" call assert_equal(0, remove(l, 0, 2))
|
||||
call assert_equal([], repeat(l, 2))
|
||||
" call assert_equal(0, reverse(l))
|
||||
" call assert_equal(0, sort(l))
|
||||
call assert_equal('[]', string(l))
|
||||
" call assert_equal(0, extend(l, l, 0))
|
||||
lockvar l
|
||||
call assert_equal(1, islocked('l'))
|
||||
unlockvar l
|
||||
endfunc
|
||||
|
@@ -84,7 +84,7 @@ func Test_list2str_str2list_utf8()
|
||||
|
||||
" Null list is the same as an empty list
|
||||
call assert_equal('', list2str([]))
|
||||
" call assert_equal('', list2str(test_null_list()))
|
||||
call assert_equal('', list2str(v:_null_list))
|
||||
endfunc
|
||||
|
||||
func Test_list2str_str2list_latin1()
|
||||
|
@@ -14,7 +14,8 @@ describe('NULL', function()
|
||||
clear()
|
||||
command('let L = v:_null_list')
|
||||
command('let D = v:_null_dict')
|
||||
command('let S = $XXX_NONEXISTENT_VAR_XXX')
|
||||
command('let S = v:_null_string')
|
||||
command('let V = $XXX_NONEXISTENT_VAR_XXX')
|
||||
end)
|
||||
local tmpfname = 'Xtest-functional-viml-null'
|
||||
after_each(function()
|
||||
@@ -129,6 +130,7 @@ describe('NULL', function()
|
||||
null_expr_test('is accepted by setloclist()', 'setloclist(1, L)', 0, 0)
|
||||
null_test('is accepted by :cexpr', 'cexpr L', 0)
|
||||
null_test('is accepted by :lexpr', 'lexpr L', 0)
|
||||
null_expr_test('does not crash execute()', 'execute(L)', 0, '')
|
||||
end)
|
||||
describe('dict', function()
|
||||
it('does not crash when indexing NULL dict', function()
|
||||
@@ -142,4 +144,26 @@ describe('NULL', function()
|
||||
null_expr_test('makes map() return v:_null_dict', 'map(D, "v:val") is# D', 0, 1)
|
||||
null_expr_test('makes filter() return v:_null_dict', 'filter(D, "1") is# D', 0, 1)
|
||||
end)
|
||||
describe('string', function()
|
||||
null_test('does not crash :echomsg', 'echomsg S', 0)
|
||||
null_test('does not crash :execute', 'execute S', 0)
|
||||
null_expr_test('does not crash execute()', 'execute(S)', 0, '')
|
||||
null_expr_test('makes executable() error out', 'executable(S)', 'E928: String required', 0)
|
||||
null_expr_test('does not crash filereadable()', 'filereadable(S)', 0, 0)
|
||||
null_expr_test('does not crash filewritable()', 'filewritable(S)', 0, 0)
|
||||
null_expr_test('does not crash fnamemodify()', 'fnamemodify(S, S)', 0, '')
|
||||
null_expr_test('does not crash getfperm()', 'getfperm(S)', 0, '')
|
||||
null_expr_test('does not crash getfsize()', 'getfsize(S)', 0, -1)
|
||||
null_expr_test('does not crash getftime()', 'getftime(S)', 0, -1)
|
||||
null_expr_test('does not crash getftype()', 'getftype(S)', 0, '')
|
||||
null_expr_test('does not crash glob()', 'glob(S)', 0, '')
|
||||
null_expr_test('does not crash globpath()', 'globpath(S, S)', 0, '')
|
||||
null_expr_test('does not crash mkdir()', 'mkdir(S)', 0, 0)
|
||||
null_expr_test('does not crash sort()', 'sort(["b", S, "a"])', 0, {'', 'a', 'b'})
|
||||
null_expr_test('does not crash split()', 'split(S)', 0, {})
|
||||
|
||||
null_test('can be used to set an option', 'let &grepprg = S', 0)
|
||||
|
||||
null_expr_test('is equal to non-existent variable', 'S == V', 0, 1)
|
||||
end)
|
||||
end)
|
||||
|
@@ -59,6 +59,16 @@ describe('writefile()', function()
|
||||
eq('\n', read_file(fname))
|
||||
end)
|
||||
|
||||
it('writes list with a null string to a file', function()
|
||||
eq(0, exc_exec(
|
||||
('call writefile([v:_null_string], "%s", "b")'):format(
|
||||
fname)))
|
||||
eq('', read_file(fname))
|
||||
eq(0, exc_exec(('call writefile([v:_null_string], "%s")'):format(
|
||||
fname)))
|
||||
eq('\n', read_file(fname))
|
||||
end)
|
||||
|
||||
it('appends to a file', function()
|
||||
eq(nil, read_file(fname))
|
||||
eq(0, funcs.writefile({'abc', 'def', 'ghi'}, fname))
|
||||
|
Reference in New Issue
Block a user