2017-08-15 06:31:11 -07:00
|
|
|
|
-- Test suite for testing interactions with API bindings
|
2024-04-20 08:44:13 -07:00
|
|
|
|
local t = require('test.testutil')
|
|
|
|
|
local n = require('test.functional.testnvim')()
|
2019-09-02 12:59:58 -07:00
|
|
|
|
local Screen = require('test.functional.ui.screen')
|
2017-08-15 06:31:11 -07:00
|
|
|
|
|
2024-04-20 08:44:13 -07:00
|
|
|
|
local nvim_prog = n.nvim_prog
|
|
|
|
|
local fn = n.fn
|
|
|
|
|
local api = n.api
|
|
|
|
|
local command = n.command
|
2024-04-08 02:03:20 -07:00
|
|
|
|
local dedent = t.dedent
|
2024-04-20 08:44:13 -07:00
|
|
|
|
local insert = n.insert
|
|
|
|
|
local clear = n.clear
|
2024-04-08 02:03:20 -07:00
|
|
|
|
local eq = t.eq
|
|
|
|
|
local ok = t.ok
|
2024-01-12 04:28:20 -07:00
|
|
|
|
local pesc = vim.pesc
|
2024-04-20 08:44:13 -07:00
|
|
|
|
local eval = n.eval
|
|
|
|
|
local feed = n.feed
|
2024-04-08 02:03:20 -07:00
|
|
|
|
local pcall_err = t.pcall_err
|
2024-04-20 08:44:13 -07:00
|
|
|
|
local exec_lua = n.exec_lua
|
2024-04-08 02:03:20 -07:00
|
|
|
|
local matches = t.matches
|
2024-04-20 08:44:13 -07:00
|
|
|
|
local exec = n.exec
|
2024-01-12 04:28:20 -07:00
|
|
|
|
local NIL = vim.NIL
|
2024-04-08 02:03:20 -07:00
|
|
|
|
local retry = t.retry
|
2024-04-20 08:44:13 -07:00
|
|
|
|
local next_msg = n.next_msg
|
2024-04-08 02:03:20 -07:00
|
|
|
|
local remove_trace = t.remove_trace
|
2024-04-20 08:44:13 -07:00
|
|
|
|
local mkdir_p = n.mkdir_p
|
|
|
|
|
local rmdir = n.rmdir
|
2024-04-08 02:03:20 -07:00
|
|
|
|
local write_file = t.write_file
|
2024-04-20 08:44:13 -07:00
|
|
|
|
local poke_eventloop = n.poke_eventloop
|
|
|
|
|
local assert_alive = n.assert_alive
|
2024-10-31 18:11:15 -07:00
|
|
|
|
local expect = n.expect
|
2017-08-15 06:31:11 -07:00
|
|
|
|
|
2019-09-03 13:51:45 -07:00
|
|
|
|
describe('lua stdlib', function()
|
2022-03-01 06:27:19 -07:00
|
|
|
|
before_each(clear)
|
2017-08-15 06:31:11 -07:00
|
|
|
|
-- İ: `tolower("İ")` is `i` which has length 1 while `İ` itself has
|
|
|
|
|
-- length 2 (in bytes).
|
|
|
|
|
-- Ⱥ: `tolower("Ⱥ")` is `ⱥ` which has length 2 while `Ⱥ` itself has
|
|
|
|
|
-- length 3 (in bytes).
|
2017-10-22 07:29:36 -07:00
|
|
|
|
--
|
|
|
|
|
-- Note: 'i' !=? 'İ' and 'ⱥ' !=? 'Ⱥ' on some systems.
|
|
|
|
|
-- Note: Built-in Nvim comparison (on systems lacking `strcasecmp`) works
|
|
|
|
|
-- only on ASCII characters.
|
2019-06-04 10:32:43 -07:00
|
|
|
|
it('vim.stricmp', function()
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("a", "A")'))
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("A", "a")'))
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("a", "a")'))
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("A", "A")'))
|
|
|
|
|
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("", "")'))
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("\\0", "\\0")'))
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("\\0\\0", "\\0\\0")'))
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("\\0\\0\\0", "\\0\\0\\0")'))
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("\\0\\0\\0A", "\\0\\0\\0a")'))
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("\\0\\0\\0a", "\\0\\0\\0A")'))
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("\\0\\0\\0a", "\\0\\0\\0a")'))
|
|
|
|
|
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("a\\0", "A\\0")'))
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("A\\0", "a\\0")'))
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("a\\0", "a\\0")'))
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("A\\0", "A\\0")'))
|
|
|
|
|
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("\\0a", "\\0A")'))
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("\\0A", "\\0a")'))
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("\\0a", "\\0a")'))
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("\\0A", "\\0A")'))
|
|
|
|
|
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("\\0a\\0", "\\0A\\0")'))
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("\\0A\\0", "\\0a\\0")'))
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("\\0a\\0", "\\0a\\0")'))
|
|
|
|
|
eq(0, fn.luaeval('vim.stricmp("\\0A\\0", "\\0A\\0")'))
|
|
|
|
|
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("a", "B")'))
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("A", "b")'))
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("a", "b")'))
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("A", "B")'))
|
|
|
|
|
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("", "\\0")'))
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("\\0", "\\0\\0")'))
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("\\0\\0", "\\0\\0\\0")'))
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("\\0\\0\\0A", "\\0\\0\\0b")'))
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("\\0\\0\\0a", "\\0\\0\\0B")'))
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("\\0\\0\\0a", "\\0\\0\\0b")'))
|
|
|
|
|
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("a\\0", "B\\0")'))
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("A\\0", "b\\0")'))
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("a\\0", "b\\0")'))
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("A\\0", "B\\0")'))
|
|
|
|
|
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("\\0a", "\\0B")'))
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("\\0A", "\\0b")'))
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("\\0a", "\\0b")'))
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("\\0A", "\\0B")'))
|
|
|
|
|
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("\\0a\\0", "\\0B\\0")'))
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("\\0A\\0", "\\0b\\0")'))
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("\\0a\\0", "\\0b\\0")'))
|
|
|
|
|
eq(-1, fn.luaeval('vim.stricmp("\\0A\\0", "\\0B\\0")'))
|
|
|
|
|
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("c", "B")'))
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("C", "b")'))
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("c", "b")'))
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("C", "B")'))
|
|
|
|
|
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("\\0", "")'))
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("\\0\\0", "\\0")'))
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("\\0\\0\\0", "\\0\\0")'))
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("\\0\\0\\0\\0", "\\0\\0\\0")'))
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("\\0\\0\\0C", "\\0\\0\\0b")'))
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("\\0\\0\\0c", "\\0\\0\\0B")'))
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("\\0\\0\\0c", "\\0\\0\\0b")'))
|
|
|
|
|
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("c\\0", "B\\0")'))
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("C\\0", "b\\0")'))
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("c\\0", "b\\0")'))
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("C\\0", "B\\0")'))
|
|
|
|
|
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("c\\0", "B")'))
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("C\\0", "b")'))
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("c\\0", "b")'))
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("C\\0", "B")'))
|
|
|
|
|
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("\\0c", "\\0B")'))
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("\\0C", "\\0b")'))
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("\\0c", "\\0b")'))
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("\\0C", "\\0B")'))
|
|
|
|
|
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("\\0c\\0", "\\0B\\0")'))
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("\\0C\\0", "\\0b\\0")'))
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("\\0c\\0", "\\0b\\0")'))
|
|
|
|
|
eq(1, fn.luaeval('vim.stricmp("\\0C\\0", "\\0B\\0")'))
|
2017-08-15 06:31:11 -07:00
|
|
|
|
end)
|
2019-01-07 07:42:20 -07:00
|
|
|
|
|
2024-05-16 05:33:04 -07:00
|
|
|
|
--- @param prerel string | nil
|
|
|
|
|
local function test_vim_deprecate(prerel)
|
2023-03-15 05:56:13 -07:00
|
|
|
|
-- vim.deprecate(name, alternative, version, plugin, backtrace)
|
2024-01-15 12:19:34 -07:00
|
|
|
|
-- See MAINTAIN.md for the soft/hard deprecation policy
|
|
|
|
|
|
2024-05-16 05:33:04 -07:00
|
|
|
|
describe(('vim.deprecate prerel=%s,'):format(prerel or 'nil'), function()
|
2024-06-12 07:47:42 -07:00
|
|
|
|
local curver --- @type {major:number, minor:number}
|
|
|
|
|
|
|
|
|
|
before_each(function()
|
|
|
|
|
curver = exec_lua('return vim.version()')
|
|
|
|
|
end)
|
2024-05-16 09:33:09 -07:00
|
|
|
|
|
|
|
|
|
it('plugin=nil, same message skipped', function()
|
2024-06-12 07:47:42 -07:00
|
|
|
|
-- "0.10" or "0.10-dev+xxx"
|
|
|
|
|
local curstr = ('%s.%s%s'):format(curver.major, curver.minor, prerel or '')
|
2024-01-15 12:19:34 -07:00
|
|
|
|
eq(
|
2024-09-01 13:01:24 -07:00
|
|
|
|
([[foo.bar() is deprecated. Run ":checkhealth vim.deprecated" for more information]]):format(
|
|
|
|
|
curstr
|
|
|
|
|
),
|
2024-05-16 05:33:04 -07:00
|
|
|
|
exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', curstr)
|
2024-01-15 12:19:34 -07:00
|
|
|
|
)
|
2024-05-16 05:33:04 -07:00
|
|
|
|
-- Same message as above; skipped this time.
|
|
|
|
|
eq(vim.NIL, exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', curstr))
|
2024-05-16 09:33:09 -07:00
|
|
|
|
end)
|
2024-01-15 12:19:34 -07:00
|
|
|
|
|
2024-05-16 09:33:09 -07:00
|
|
|
|
it('plugin=nil, no error if soft-deprecated', function()
|
2024-10-17 08:58:13 -07:00
|
|
|
|
eq(vim.NIL, exec_lua [[return vim.deprecate('old1', 'new1', '0.99.0')]])
|
|
|
|
|
-- Major version > current Nvim major is always "soft-deprecated".
|
|
|
|
|
-- XXX: This is also a reminder to update the hardcoded `nvim_major`, when Nvim reaches 1.0.
|
|
|
|
|
eq(vim.NIL, exec_lua [[return vim.deprecate('old2', 'new2', '1.0.0')]])
|
2024-05-16 09:33:09 -07:00
|
|
|
|
end)
|
2024-01-15 12:19:34 -07:00
|
|
|
|
|
2024-05-16 09:33:09 -07:00
|
|
|
|
it('plugin=nil, show error if hard-deprecated', function()
|
2024-06-12 07:47:42 -07:00
|
|
|
|
-- "0.10" or "0.11"
|
|
|
|
|
local nextver = ('%s.%s'):format(curver.major, curver.minor + (prerel and 0 or 1))
|
|
|
|
|
|
|
|
|
|
local was_removed = prerel and 'was removed' or 'will be removed'
|
2024-01-15 12:19:34 -07:00
|
|
|
|
eq(
|
2024-05-16 09:33:09 -07:00
|
|
|
|
dedent(
|
|
|
|
|
[[
|
|
|
|
|
foo.hard_dep() is deprecated. Run ":checkhealth vim.deprecated" for more information]]
|
|
|
|
|
):format(was_removed, nextver),
|
2024-05-16 05:33:04 -07:00
|
|
|
|
exec_lua('return vim.deprecate(...)', 'foo.hard_dep()', 'vim.new_api()', nextver)
|
2024-01-15 12:19:34 -07:00
|
|
|
|
)
|
2024-05-16 09:33:09 -07:00
|
|
|
|
end)
|
2024-01-15 12:19:34 -07:00
|
|
|
|
|
2024-05-16 05:33:04 -07:00
|
|
|
|
it('plugin specified', function()
|
2024-01-15 12:19:34 -07:00
|
|
|
|
-- When `plugin` is specified, don't show ":help deprecated". #22235
|
|
|
|
|
eq(
|
|
|
|
|
dedent [[
|
|
|
|
|
foo.bar() is deprecated, use zub.wooo{ok=yay} instead.
|
2024-04-18 07:57:58 -07:00
|
|
|
|
Feature will be removed in my-plugin.nvim 0.3.0]],
|
2024-01-15 12:19:34 -07:00
|
|
|
|
exec_lua(
|
|
|
|
|
'return vim.deprecate(...)',
|
|
|
|
|
'foo.bar()',
|
|
|
|
|
'zub.wooo{ok=yay}',
|
|
|
|
|
'0.3.0',
|
|
|
|
|
'my-plugin.nvim',
|
|
|
|
|
false
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
-- plugins: no soft deprecation period
|
|
|
|
|
eq(
|
|
|
|
|
dedent [[
|
|
|
|
|
foo.bar() is deprecated, use zub.wooo{ok=yay} instead.
|
2024-04-18 07:57:58 -07:00
|
|
|
|
Feature will be removed in my-plugin.nvim 0.11.0]],
|
2024-01-15 12:19:34 -07:00
|
|
|
|
exec_lua(
|
|
|
|
|
'return vim.deprecate(...)',
|
|
|
|
|
'foo.bar()',
|
|
|
|
|
'zub.wooo{ok=yay}',
|
|
|
|
|
'0.11.0',
|
|
|
|
|
'my-plugin.nvim',
|
|
|
|
|
false
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
end)
|
|
|
|
|
end
|
|
|
|
|
|
2024-05-16 05:33:04 -07:00
|
|
|
|
test_vim_deprecate()
|
|
|
|
|
test_vim_deprecate('-dev+g0000000')
|
2023-03-15 05:56:13 -07:00
|
|
|
|
|
2019-12-01 06:32:55 -07:00
|
|
|
|
it('vim.startswith', function()
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(true, fn.luaeval('vim.startswith("123", "1")'))
|
|
|
|
|
eq(true, fn.luaeval('vim.startswith("123", "")'))
|
|
|
|
|
eq(true, fn.luaeval('vim.startswith("123", "123")'))
|
|
|
|
|
eq(true, fn.luaeval('vim.startswith("", "")'))
|
2019-12-01 06:32:55 -07:00
|
|
|
|
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(false, fn.luaeval('vim.startswith("123", " ")'))
|
|
|
|
|
eq(false, fn.luaeval('vim.startswith("123", "2")'))
|
|
|
|
|
eq(false, fn.luaeval('vim.startswith("123", "1234")'))
|
2019-12-01 06:32:55 -07:00
|
|
|
|
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches(
|
|
|
|
|
'prefix: expected string, got nil',
|
2021-11-06 07:26:10 -07:00
|
|
|
|
pcall_err(exec_lua, 'return vim.startswith("123", nil)')
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-11-06 07:26:10 -07:00
|
|
|
|
matches('s: expected string, got nil', pcall_err(exec_lua, 'return vim.startswith(nil, "123")'))
|
2019-12-01 06:32:55 -07:00
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('vim.endswith', function()
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(true, fn.luaeval('vim.endswith("123", "3")'))
|
|
|
|
|
eq(true, fn.luaeval('vim.endswith("123", "")'))
|
|
|
|
|
eq(true, fn.luaeval('vim.endswith("123", "123")'))
|
|
|
|
|
eq(true, fn.luaeval('vim.endswith("", "")'))
|
2019-12-01 06:32:55 -07:00
|
|
|
|
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(false, fn.luaeval('vim.endswith("123", " ")'))
|
|
|
|
|
eq(false, fn.luaeval('vim.endswith("123", "2")'))
|
|
|
|
|
eq(false, fn.luaeval('vim.endswith("123", "1234")'))
|
2019-12-01 06:32:55 -07:00
|
|
|
|
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches(
|
|
|
|
|
'suffix: expected string, got nil',
|
2021-11-06 07:26:10 -07:00
|
|
|
|
pcall_err(exec_lua, 'return vim.endswith("123", nil)')
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-11-06 07:26:10 -07:00
|
|
|
|
matches('s: expected string, got nil', pcall_err(exec_lua, 'return vim.endswith(nil, "123")'))
|
2019-12-01 06:32:55 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2019-08-04 06:12:07 -07:00
|
|
|
|
it('vim.str_utfindex/str_byteindex', function()
|
2022-09-12 02:26:27 -07:00
|
|
|
|
exec_lua([[_G.test_text = "xy åäö ɧ 汉语 ↥ 🤦x🦄 å بِيَّ\000ъ"]])
|
2022-11-28 18:45:48 -07:00
|
|
|
|
local indices32 = {
|
|
|
|
|
[0] = 0,
|
|
|
|
|
1,
|
|
|
|
|
2,
|
|
|
|
|
3,
|
|
|
|
|
5,
|
|
|
|
|
7,
|
|
|
|
|
9,
|
|
|
|
|
10,
|
|
|
|
|
12,
|
|
|
|
|
13,
|
|
|
|
|
16,
|
|
|
|
|
19,
|
|
|
|
|
20,
|
|
|
|
|
23,
|
|
|
|
|
24,
|
|
|
|
|
28,
|
|
|
|
|
29,
|
|
|
|
|
33,
|
|
|
|
|
34,
|
|
|
|
|
35,
|
|
|
|
|
37,
|
|
|
|
|
38,
|
|
|
|
|
40,
|
|
|
|
|
42,
|
|
|
|
|
44,
|
|
|
|
|
46,
|
|
|
|
|
48,
|
|
|
|
|
49,
|
|
|
|
|
51,
|
|
|
|
|
}
|
|
|
|
|
local indices16 = {
|
|
|
|
|
[0] = 0,
|
2024-01-02 18:09:18 -07:00
|
|
|
|
1,
|
2022-11-28 18:45:48 -07:00
|
|
|
|
2,
|
|
|
|
|
3,
|
|
|
|
|
5,
|
|
|
|
|
7,
|
|
|
|
|
9,
|
|
|
|
|
10,
|
|
|
|
|
12,
|
|
|
|
|
13,
|
|
|
|
|
16,
|
|
|
|
|
19,
|
|
|
|
|
20,
|
|
|
|
|
23,
|
|
|
|
|
24,
|
|
|
|
|
28,
|
2024-01-02 18:09:18 -07:00
|
|
|
|
28,
|
|
|
|
|
29,
|
2022-11-28 18:45:48 -07:00
|
|
|
|
33,
|
2024-01-02 18:09:18 -07:00
|
|
|
|
33,
|
|
|
|
|
34,
|
|
|
|
|
35,
|
|
|
|
|
37,
|
|
|
|
|
38,
|
|
|
|
|
40,
|
|
|
|
|
42,
|
|
|
|
|
44,
|
|
|
|
|
46,
|
|
|
|
|
48,
|
|
|
|
|
49,
|
|
|
|
|
51,
|
|
|
|
|
}
|
feat(stdlib): overload vim.str_byteindex, vim.str_utfindex #30735
PROBLEM:
There are several limitations to vim.str_byteindex, vim.str_utfindex:
1. They throw given out-of-range indexes. An invalid (often user/lsp-provided)
index doesn't feel exceptional and should be handled by the caller.
`:help dev-error-patterns` suggests that `retval, errmsg` is the preferred
way to handle this kind of failure.
2. They cannot accept an encoding. So LSP needs wrapper functions. #25272
3. The current signatures are not extensible.
* Calling: The function currently uses a fairly opaque boolean value to
indicate to identify the encoding.
* Returns: The fact it can throw requires wrapping in pcall.
4. The current name doesn't follow suggestions in `:h dev-naming` and I think
`get` would be suitable.
SOLUTION:
- Because these are performance-sensitive, don't introduce `opts`.
- Introduce an "overload" that accepts `encoding:string` and
`strict_indexing:bool` params.
```lua
local col = vim.str_utfindex(line, encoding, [index, [no_out_of_range]])
```
Support the old versions by dispatching on the type of argument 2, and
deprecate that form.
```lua
vim.str_utfindex(line) -- (utf-32 length, utf-16 length), deprecated
vim.str_utfindex(line, index) -- (utf-32 index, utf-16 index), deprecated
vim.str_utfindex(line, 'utf-16') -- utf-16 length
vim.str_utfindex(line, 'utf-16', index) -- utf-16 index
vim.str_utfindex(line, 'utf-16', math.huge) -- error: index out of range
vim.str_utfindex(line, 'utf-16', math.huge, false) -- utf-16 length
```
2024-10-23 06:33:57 -07:00
|
|
|
|
local indices8 = {
|
|
|
|
|
[0] = 0,
|
|
|
|
|
1,
|
|
|
|
|
2,
|
|
|
|
|
3,
|
|
|
|
|
4,
|
|
|
|
|
5,
|
|
|
|
|
6,
|
|
|
|
|
7,
|
|
|
|
|
8,
|
|
|
|
|
9,
|
|
|
|
|
10,
|
|
|
|
|
11,
|
|
|
|
|
12,
|
|
|
|
|
13,
|
|
|
|
|
14,
|
|
|
|
|
15,
|
|
|
|
|
16,
|
|
|
|
|
17,
|
|
|
|
|
18,
|
|
|
|
|
19,
|
|
|
|
|
20,
|
|
|
|
|
21,
|
|
|
|
|
22,
|
|
|
|
|
23,
|
|
|
|
|
24,
|
|
|
|
|
25,
|
|
|
|
|
26,
|
|
|
|
|
27,
|
|
|
|
|
28,
|
|
|
|
|
29,
|
|
|
|
|
30,
|
|
|
|
|
31,
|
|
|
|
|
32,
|
|
|
|
|
33,
|
|
|
|
|
34,
|
|
|
|
|
35,
|
|
|
|
|
36,
|
|
|
|
|
37,
|
|
|
|
|
38,
|
|
|
|
|
39,
|
|
|
|
|
40,
|
|
|
|
|
41,
|
|
|
|
|
42,
|
|
|
|
|
43,
|
|
|
|
|
44,
|
|
|
|
|
45,
|
|
|
|
|
46,
|
|
|
|
|
47,
|
|
|
|
|
48,
|
|
|
|
|
49,
|
|
|
|
|
50,
|
|
|
|
|
51,
|
|
|
|
|
}
|
2022-11-28 18:45:48 -07:00
|
|
|
|
for i, k in pairs(indices32) do
|
2019-08-04 06:12:07 -07:00
|
|
|
|
eq(k, exec_lua('return vim.str_byteindex(_G.test_text, ...)', i), i)
|
feat(stdlib): overload vim.str_byteindex, vim.str_utfindex #30735
PROBLEM:
There are several limitations to vim.str_byteindex, vim.str_utfindex:
1. They throw given out-of-range indexes. An invalid (often user/lsp-provided)
index doesn't feel exceptional and should be handled by the caller.
`:help dev-error-patterns` suggests that `retval, errmsg` is the preferred
way to handle this kind of failure.
2. They cannot accept an encoding. So LSP needs wrapper functions. #25272
3. The current signatures are not extensible.
* Calling: The function currently uses a fairly opaque boolean value to
indicate to identify the encoding.
* Returns: The fact it can throw requires wrapping in pcall.
4. The current name doesn't follow suggestions in `:h dev-naming` and I think
`get` would be suitable.
SOLUTION:
- Because these are performance-sensitive, don't introduce `opts`.
- Introduce an "overload" that accepts `encoding:string` and
`strict_indexing:bool` params.
```lua
local col = vim.str_utfindex(line, encoding, [index, [no_out_of_range]])
```
Support the old versions by dispatching on the type of argument 2, and
deprecate that form.
```lua
vim.str_utfindex(line) -- (utf-32 length, utf-16 length), deprecated
vim.str_utfindex(line, index) -- (utf-32 index, utf-16 index), deprecated
vim.str_utfindex(line, 'utf-16') -- utf-16 length
vim.str_utfindex(line, 'utf-16', index) -- utf-16 index
vim.str_utfindex(line, 'utf-16', math.huge) -- error: index out of range
vim.str_utfindex(line, 'utf-16', math.huge, false) -- utf-16 length
```
2024-10-23 06:33:57 -07:00
|
|
|
|
eq(k, exec_lua('return vim.str_byteindex(_G.test_text, ..., false)', i), i)
|
|
|
|
|
eq(k, exec_lua('return vim.str_byteindex(_G.test_text, "utf-32", ...)', i), i)
|
2019-08-04 06:12:07 -07:00
|
|
|
|
end
|
2022-11-28 18:45:48 -07:00
|
|
|
|
for i, k in pairs(indices16) do
|
2019-08-04 06:12:07 -07:00
|
|
|
|
eq(k, exec_lua('return vim.str_byteindex(_G.test_text, ..., true)', i), i)
|
feat(stdlib): overload vim.str_byteindex, vim.str_utfindex #30735
PROBLEM:
There are several limitations to vim.str_byteindex, vim.str_utfindex:
1. They throw given out-of-range indexes. An invalid (often user/lsp-provided)
index doesn't feel exceptional and should be handled by the caller.
`:help dev-error-patterns` suggests that `retval, errmsg` is the preferred
way to handle this kind of failure.
2. They cannot accept an encoding. So LSP needs wrapper functions. #25272
3. The current signatures are not extensible.
* Calling: The function currently uses a fairly opaque boolean value to
indicate to identify the encoding.
* Returns: The fact it can throw requires wrapping in pcall.
4. The current name doesn't follow suggestions in `:h dev-naming` and I think
`get` would be suitable.
SOLUTION:
- Because these are performance-sensitive, don't introduce `opts`.
- Introduce an "overload" that accepts `encoding:string` and
`strict_indexing:bool` params.
```lua
local col = vim.str_utfindex(line, encoding, [index, [no_out_of_range]])
```
Support the old versions by dispatching on the type of argument 2, and
deprecate that form.
```lua
vim.str_utfindex(line) -- (utf-32 length, utf-16 length), deprecated
vim.str_utfindex(line, index) -- (utf-32 index, utf-16 index), deprecated
vim.str_utfindex(line, 'utf-16') -- utf-16 length
vim.str_utfindex(line, 'utf-16', index) -- utf-16 index
vim.str_utfindex(line, 'utf-16', math.huge) -- error: index out of range
vim.str_utfindex(line, 'utf-16', math.huge, false) -- utf-16 length
```
2024-10-23 06:33:57 -07:00
|
|
|
|
eq(k, exec_lua('return vim.str_byteindex(_G.test_text, "utf-16", ...)', i), i)
|
2019-08-04 06:12:07 -07:00
|
|
|
|
end
|
feat(stdlib): overload vim.str_byteindex, vim.str_utfindex #30735
PROBLEM:
There are several limitations to vim.str_byteindex, vim.str_utfindex:
1. They throw given out-of-range indexes. An invalid (often user/lsp-provided)
index doesn't feel exceptional and should be handled by the caller.
`:help dev-error-patterns` suggests that `retval, errmsg` is the preferred
way to handle this kind of failure.
2. They cannot accept an encoding. So LSP needs wrapper functions. #25272
3. The current signatures are not extensible.
* Calling: The function currently uses a fairly opaque boolean value to
indicate to identify the encoding.
* Returns: The fact it can throw requires wrapping in pcall.
4. The current name doesn't follow suggestions in `:h dev-naming` and I think
`get` would be suitable.
SOLUTION:
- Because these are performance-sensitive, don't introduce `opts`.
- Introduce an "overload" that accepts `encoding:string` and
`strict_indexing:bool` params.
```lua
local col = vim.str_utfindex(line, encoding, [index, [no_out_of_range]])
```
Support the old versions by dispatching on the type of argument 2, and
deprecate that form.
```lua
vim.str_utfindex(line) -- (utf-32 length, utf-16 length), deprecated
vim.str_utfindex(line, index) -- (utf-32 index, utf-16 index), deprecated
vim.str_utfindex(line, 'utf-16') -- utf-16 length
vim.str_utfindex(line, 'utf-16', index) -- utf-16 index
vim.str_utfindex(line, 'utf-16', math.huge) -- error: index out of range
vim.str_utfindex(line, 'utf-16', math.huge, false) -- utf-16 length
```
2024-10-23 06:33:57 -07:00
|
|
|
|
for i, k in pairs(indices8) do
|
|
|
|
|
eq(k, exec_lua('return vim.str_byteindex(_G.test_text, "utf-8", ...)', i), i)
|
|
|
|
|
end
|
|
|
|
|
matches(
|
2022-11-28 18:45:48 -07:00
|
|
|
|
'index out of range',
|
|
|
|
|
pcall_err(exec_lua, 'return vim.str_byteindex(_G.test_text, ...)', #indices32 + 1)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
feat(stdlib): overload vim.str_byteindex, vim.str_utfindex #30735
PROBLEM:
There are several limitations to vim.str_byteindex, vim.str_utfindex:
1. They throw given out-of-range indexes. An invalid (often user/lsp-provided)
index doesn't feel exceptional and should be handled by the caller.
`:help dev-error-patterns` suggests that `retval, errmsg` is the preferred
way to handle this kind of failure.
2. They cannot accept an encoding. So LSP needs wrapper functions. #25272
3. The current signatures are not extensible.
* Calling: The function currently uses a fairly opaque boolean value to
indicate to identify the encoding.
* Returns: The fact it can throw requires wrapping in pcall.
4. The current name doesn't follow suggestions in `:h dev-naming` and I think
`get` would be suitable.
SOLUTION:
- Because these are performance-sensitive, don't introduce `opts`.
- Introduce an "overload" that accepts `encoding:string` and
`strict_indexing:bool` params.
```lua
local col = vim.str_utfindex(line, encoding, [index, [no_out_of_range]])
```
Support the old versions by dispatching on the type of argument 2, and
deprecate that form.
```lua
vim.str_utfindex(line) -- (utf-32 length, utf-16 length), deprecated
vim.str_utfindex(line, index) -- (utf-32 index, utf-16 index), deprecated
vim.str_utfindex(line, 'utf-16') -- utf-16 length
vim.str_utfindex(line, 'utf-16', index) -- utf-16 index
vim.str_utfindex(line, 'utf-16', math.huge) -- error: index out of range
vim.str_utfindex(line, 'utf-16', math.huge, false) -- utf-16 length
```
2024-10-23 06:33:57 -07:00
|
|
|
|
matches(
|
2022-11-28 18:45:48 -07:00
|
|
|
|
'index out of range',
|
|
|
|
|
pcall_err(exec_lua, 'return vim.str_byteindex(_G.test_text, ..., true)', #indices16 + 1)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
feat(stdlib): overload vim.str_byteindex, vim.str_utfindex #30735
PROBLEM:
There are several limitations to vim.str_byteindex, vim.str_utfindex:
1. They throw given out-of-range indexes. An invalid (often user/lsp-provided)
index doesn't feel exceptional and should be handled by the caller.
`:help dev-error-patterns` suggests that `retval, errmsg` is the preferred
way to handle this kind of failure.
2. They cannot accept an encoding. So LSP needs wrapper functions. #25272
3. The current signatures are not extensible.
* Calling: The function currently uses a fairly opaque boolean value to
indicate to identify the encoding.
* Returns: The fact it can throw requires wrapping in pcall.
4. The current name doesn't follow suggestions in `:h dev-naming` and I think
`get` would be suitable.
SOLUTION:
- Because these are performance-sensitive, don't introduce `opts`.
- Introduce an "overload" that accepts `encoding:string` and
`strict_indexing:bool` params.
```lua
local col = vim.str_utfindex(line, encoding, [index, [no_out_of_range]])
```
Support the old versions by dispatching on the type of argument 2, and
deprecate that form.
```lua
vim.str_utfindex(line) -- (utf-32 length, utf-16 length), deprecated
vim.str_utfindex(line, index) -- (utf-32 index, utf-16 index), deprecated
vim.str_utfindex(line, 'utf-16') -- utf-16 length
vim.str_utfindex(line, 'utf-16', index) -- utf-16 index
vim.str_utfindex(line, 'utf-16', math.huge) -- error: index out of range
vim.str_utfindex(line, 'utf-16', math.huge, false) -- utf-16 length
```
2024-10-23 06:33:57 -07:00
|
|
|
|
matches(
|
|
|
|
|
'index out of range',
|
|
|
|
|
pcall_err(exec_lua, 'return vim.str_byteindex(_G.test_text, "utf-16", ...)', #indices16 + 1)
|
|
|
|
|
)
|
|
|
|
|
matches(
|
|
|
|
|
'index out of range',
|
|
|
|
|
pcall_err(exec_lua, 'return vim.str_byteindex(_G.test_text, "utf-32", ...)', #indices32 + 1)
|
|
|
|
|
)
|
|
|
|
|
matches(
|
|
|
|
|
'invalid encoding',
|
|
|
|
|
pcall_err(exec_lua, 'return vim.str_byteindex("hello", "madeupencoding", 1)')
|
|
|
|
|
)
|
|
|
|
|
eq(
|
|
|
|
|
indices32[#indices32],
|
|
|
|
|
exec_lua('return vim.str_byteindex(_G.test_text, "utf-32", 99999, false)')
|
|
|
|
|
)
|
|
|
|
|
eq(
|
|
|
|
|
indices16[#indices16],
|
|
|
|
|
exec_lua('return vim.str_byteindex(_G.test_text, "utf-16", 99999, false)')
|
|
|
|
|
)
|
|
|
|
|
eq(
|
|
|
|
|
indices8[#indices8],
|
|
|
|
|
exec_lua('return vim.str_byteindex(_G.test_text, "utf-8", 99999, false)')
|
|
|
|
|
)
|
|
|
|
|
eq(2, exec_lua('return vim.str_byteindex("é", "utf-16", 2, false)'))
|
|
|
|
|
local i32, i16, i8 = 0, 0, 0
|
2022-09-12 02:26:27 -07:00
|
|
|
|
local len = 51
|
|
|
|
|
for k = 0, len do
|
2022-11-28 18:45:48 -07:00
|
|
|
|
if indices32[i32] < k then
|
2019-08-04 06:12:07 -07:00
|
|
|
|
i32 = i32 + 1
|
|
|
|
|
end
|
2022-11-28 18:45:48 -07:00
|
|
|
|
if indices16[i16] < k then
|
2019-08-04 06:12:07 -07:00
|
|
|
|
i16 = i16 + 1
|
2022-11-28 18:45:48 -07:00
|
|
|
|
if indices16[i16 + 1] == indices16[i16] then
|
2019-08-04 06:12:07 -07:00
|
|
|
|
i16 = i16 + 1
|
|
|
|
|
end
|
|
|
|
|
end
|
feat(stdlib): overload vim.str_byteindex, vim.str_utfindex #30735
PROBLEM:
There are several limitations to vim.str_byteindex, vim.str_utfindex:
1. They throw given out-of-range indexes. An invalid (often user/lsp-provided)
index doesn't feel exceptional and should be handled by the caller.
`:help dev-error-patterns` suggests that `retval, errmsg` is the preferred
way to handle this kind of failure.
2. They cannot accept an encoding. So LSP needs wrapper functions. #25272
3. The current signatures are not extensible.
* Calling: The function currently uses a fairly opaque boolean value to
indicate to identify the encoding.
* Returns: The fact it can throw requires wrapping in pcall.
4. The current name doesn't follow suggestions in `:h dev-naming` and I think
`get` would be suitable.
SOLUTION:
- Because these are performance-sensitive, don't introduce `opts`.
- Introduce an "overload" that accepts `encoding:string` and
`strict_indexing:bool` params.
```lua
local col = vim.str_utfindex(line, encoding, [index, [no_out_of_range]])
```
Support the old versions by dispatching on the type of argument 2, and
deprecate that form.
```lua
vim.str_utfindex(line) -- (utf-32 length, utf-16 length), deprecated
vim.str_utfindex(line, index) -- (utf-32 index, utf-16 index), deprecated
vim.str_utfindex(line, 'utf-16') -- utf-16 length
vim.str_utfindex(line, 'utf-16', index) -- utf-16 index
vim.str_utfindex(line, 'utf-16', math.huge) -- error: index out of range
vim.str_utfindex(line, 'utf-16', math.huge, false) -- utf-16 length
```
2024-10-23 06:33:57 -07:00
|
|
|
|
if indices8[i8] < k then
|
|
|
|
|
i8 = i8 + 1
|
|
|
|
|
end
|
2019-08-04 06:12:07 -07:00
|
|
|
|
eq({ i32, i16 }, exec_lua('return {vim.str_utfindex(_G.test_text, ...)}', k), k)
|
feat(stdlib): overload vim.str_byteindex, vim.str_utfindex #30735
PROBLEM:
There are several limitations to vim.str_byteindex, vim.str_utfindex:
1. They throw given out-of-range indexes. An invalid (often user/lsp-provided)
index doesn't feel exceptional and should be handled by the caller.
`:help dev-error-patterns` suggests that `retval, errmsg` is the preferred
way to handle this kind of failure.
2. They cannot accept an encoding. So LSP needs wrapper functions. #25272
3. The current signatures are not extensible.
* Calling: The function currently uses a fairly opaque boolean value to
indicate to identify the encoding.
* Returns: The fact it can throw requires wrapping in pcall.
4. The current name doesn't follow suggestions in `:h dev-naming` and I think
`get` would be suitable.
SOLUTION:
- Because these are performance-sensitive, don't introduce `opts`.
- Introduce an "overload" that accepts `encoding:string` and
`strict_indexing:bool` params.
```lua
local col = vim.str_utfindex(line, encoding, [index, [no_out_of_range]])
```
Support the old versions by dispatching on the type of argument 2, and
deprecate that form.
```lua
vim.str_utfindex(line) -- (utf-32 length, utf-16 length), deprecated
vim.str_utfindex(line, index) -- (utf-32 index, utf-16 index), deprecated
vim.str_utfindex(line, 'utf-16') -- utf-16 length
vim.str_utfindex(line, 'utf-16', index) -- utf-16 index
vim.str_utfindex(line, 'utf-16', math.huge) -- error: index out of range
vim.str_utfindex(line, 'utf-16', math.huge, false) -- utf-16 length
```
2024-10-23 06:33:57 -07:00
|
|
|
|
eq({ i32 }, exec_lua('return {vim.str_utfindex(_G.test_text, "utf-32", ...)}', k), k)
|
|
|
|
|
eq({ i16 }, exec_lua('return {vim.str_utfindex(_G.test_text, "utf-16", ...)}', k), k)
|
|
|
|
|
eq({ i8 }, exec_lua('return {vim.str_utfindex(_G.test_text, "utf-8", ...)}', k), k)
|
2019-08-04 06:12:07 -07:00
|
|
|
|
end
|
feat(stdlib): overload vim.str_byteindex, vim.str_utfindex #30735
PROBLEM:
There are several limitations to vim.str_byteindex, vim.str_utfindex:
1. They throw given out-of-range indexes. An invalid (often user/lsp-provided)
index doesn't feel exceptional and should be handled by the caller.
`:help dev-error-patterns` suggests that `retval, errmsg` is the preferred
way to handle this kind of failure.
2. They cannot accept an encoding. So LSP needs wrapper functions. #25272
3. The current signatures are not extensible.
* Calling: The function currently uses a fairly opaque boolean value to
indicate to identify the encoding.
* Returns: The fact it can throw requires wrapping in pcall.
4. The current name doesn't follow suggestions in `:h dev-naming` and I think
`get` would be suitable.
SOLUTION:
- Because these are performance-sensitive, don't introduce `opts`.
- Introduce an "overload" that accepts `encoding:string` and
`strict_indexing:bool` params.
```lua
local col = vim.str_utfindex(line, encoding, [index, [no_out_of_range]])
```
Support the old versions by dispatching on the type of argument 2, and
deprecate that form.
```lua
vim.str_utfindex(line) -- (utf-32 length, utf-16 length), deprecated
vim.str_utfindex(line, index) -- (utf-32 index, utf-16 index), deprecated
vim.str_utfindex(line, 'utf-16') -- utf-16 length
vim.str_utfindex(line, 'utf-16', index) -- utf-16 index
vim.str_utfindex(line, 'utf-16', math.huge) -- error: index out of range
vim.str_utfindex(line, 'utf-16', math.huge, false) -- utf-16 length
```
2024-10-23 06:33:57 -07:00
|
|
|
|
|
|
|
|
|
eq({ #indices32, #indices16 }, exec_lua('return {vim.str_utfindex(_G.test_text)}'))
|
|
|
|
|
|
|
|
|
|
eq(#indices32, exec_lua('return vim.str_utfindex(_G.test_text, "utf-32", math.huge, false)'))
|
|
|
|
|
eq(#indices16, exec_lua('return vim.str_utfindex(_G.test_text, "utf-16", math.huge, false)'))
|
|
|
|
|
eq(#indices8, exec_lua('return vim.str_utfindex(_G.test_text, "utf-8", math.huge, false)'))
|
|
|
|
|
|
|
|
|
|
eq(#indices32, exec_lua('return vim.str_utfindex(_G.test_text, "utf-32")'))
|
|
|
|
|
eq(#indices16, exec_lua('return vim.str_utfindex(_G.test_text, "utf-16")'))
|
|
|
|
|
eq(#indices8, exec_lua('return vim.str_utfindex(_G.test_text, "utf-8")'))
|
|
|
|
|
matches(
|
|
|
|
|
'invalid encoding',
|
|
|
|
|
pcall_err(exec_lua, 'return vim.str_utfindex(_G.test_text, "madeupencoding", ...)', 1)
|
|
|
|
|
)
|
|
|
|
|
matches(
|
2022-11-14 03:01:35 -07:00
|
|
|
|
'index out of range',
|
|
|
|
|
pcall_err(exec_lua, 'return vim.str_utfindex(_G.test_text, ...)', len + 1)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2019-08-04 06:12:07 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2021-10-30 10:30:40 -07:00
|
|
|
|
it('vim.str_utf_start', function()
|
|
|
|
|
exec_lua([[_G.test_text = "xy åäö ɧ 汉语 ↥ 🤦x🦄 å بِيَّ"]])
|
|
|
|
|
local expected_positions = {
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
-1,
|
|
|
|
|
0,
|
|
|
|
|
-1,
|
|
|
|
|
0,
|
|
|
|
|
-1,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
-1,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
-1,
|
|
|
|
|
-2,
|
|
|
|
|
0,
|
|
|
|
|
-1,
|
|
|
|
|
-2,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
-1,
|
|
|
|
|
-2,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
-1,
|
|
|
|
|
-2,
|
|
|
|
|
-3,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
-1,
|
|
|
|
|
-2,
|
|
|
|
|
-3,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
-1,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
-1,
|
|
|
|
|
0,
|
|
|
|
|
-1,
|
|
|
|
|
0,
|
|
|
|
|
-1,
|
|
|
|
|
0,
|
|
|
|
|
-1,
|
|
|
|
|
0,
|
|
|
|
|
-1,
|
|
|
|
|
}
|
|
|
|
|
eq(
|
|
|
|
|
expected_positions,
|
|
|
|
|
exec_lua([[
|
|
|
|
|
local start_codepoint_positions = {}
|
|
|
|
|
for idx = 1, #_G.test_text do
|
|
|
|
|
table.insert(start_codepoint_positions, vim.str_utf_start(_G.test_text, idx))
|
|
|
|
|
end
|
|
|
|
|
return start_codepoint_positions
|
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-10-30 10:30:40 -07:00
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('vim.str_utf_end', function()
|
|
|
|
|
exec_lua([[_G.test_text = "xy åäö ɧ 汉语 ↥ 🤦x🦄 å بِيَّ"]])
|
|
|
|
|
local expected_positions = {
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
1,
|
|
|
|
|
0,
|
|
|
|
|
1,
|
|
|
|
|
0,
|
|
|
|
|
1,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
1,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
2,
|
|
|
|
|
1,
|
|
|
|
|
0,
|
|
|
|
|
2,
|
|
|
|
|
1,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
2,
|
|
|
|
|
1,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
3,
|
|
|
|
|
2,
|
|
|
|
|
1,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
3,
|
|
|
|
|
2,
|
|
|
|
|
1,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
1,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
1,
|
|
|
|
|
0,
|
|
|
|
|
1,
|
|
|
|
|
0,
|
|
|
|
|
1,
|
|
|
|
|
0,
|
|
|
|
|
1,
|
|
|
|
|
0,
|
|
|
|
|
1,
|
2024-01-02 18:09:18 -07:00
|
|
|
|
0,
|
2021-10-30 10:30:40 -07:00
|
|
|
|
}
|
|
|
|
|
eq(
|
|
|
|
|
expected_positions,
|
|
|
|
|
exec_lua([[
|
|
|
|
|
local end_codepoint_positions = {}
|
|
|
|
|
for idx = 1, #_G.test_text do
|
|
|
|
|
table.insert(end_codepoint_positions, vim.str_utf_end(_G.test_text, idx))
|
|
|
|
|
end
|
|
|
|
|
return end_codepoint_positions
|
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-10-30 10:30:40 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2021-10-22 22:48:46 -07:00
|
|
|
|
it('vim.str_utf_pos', function()
|
|
|
|
|
exec_lua([[_G.test_text = "xy åäö ɧ 汉语 ↥ 🤦x🦄 å بِيَّ"]])
|
|
|
|
|
local expected_positions = {
|
|
|
|
|
1,
|
|
|
|
|
2,
|
|
|
|
|
3,
|
|
|
|
|
4,
|
|
|
|
|
6,
|
|
|
|
|
8,
|
|
|
|
|
10,
|
|
|
|
|
11,
|
|
|
|
|
13,
|
|
|
|
|
14,
|
|
|
|
|
17,
|
|
|
|
|
20,
|
|
|
|
|
21,
|
|
|
|
|
24,
|
|
|
|
|
25,
|
|
|
|
|
29,
|
|
|
|
|
30,
|
|
|
|
|
34,
|
|
|
|
|
35,
|
|
|
|
|
36,
|
|
|
|
|
38,
|
|
|
|
|
39,
|
|
|
|
|
41,
|
|
|
|
|
43,
|
|
|
|
|
45,
|
|
|
|
|
47,
|
|
|
|
|
}
|
|
|
|
|
eq(expected_positions, exec_lua('return vim.str_utf_pos(_G.test_text)'))
|
|
|
|
|
end)
|
|
|
|
|
|
2019-06-04 10:32:43 -07:00
|
|
|
|
it('vim.schedule', function()
|
2019-08-04 06:12:07 -07:00
|
|
|
|
exec_lua([[
|
2019-06-04 10:32:43 -07:00
|
|
|
|
test_table = {}
|
|
|
|
|
vim.schedule(function()
|
|
|
|
|
table.insert(test_table, "xx")
|
|
|
|
|
end)
|
|
|
|
|
table.insert(test_table, "yy")
|
2019-08-04 06:12:07 -07:00
|
|
|
|
]])
|
|
|
|
|
eq({ 'yy', 'xx' }, exec_lua('return test_table'))
|
2019-06-04 10:32:43 -07:00
|
|
|
|
|
2019-10-26 01:30:58 -07:00
|
|
|
|
-- Validates args.
|
2020-11-04 02:41:22 -07:00
|
|
|
|
matches('vim.schedule: expected function', pcall_err(exec_lua, "vim.schedule('stringly')"))
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches('vim.schedule: expected function', pcall_err(exec_lua, 'vim.schedule()'))
|
2019-06-04 10:32:43 -07:00
|
|
|
|
|
2019-08-04 06:12:07 -07:00
|
|
|
|
exec_lua([[
|
2019-06-04 10:32:43 -07:00
|
|
|
|
vim.schedule(function()
|
|
|
|
|
error("big failure\nvery async")
|
|
|
|
|
end)
|
2019-08-04 06:12:07 -07:00
|
|
|
|
]])
|
2019-06-04 10:32:43 -07:00
|
|
|
|
|
|
|
|
|
feed('<cr>')
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches('big failure\nvery async', remove_trace(eval('v:errmsg')))
|
2019-09-02 12:59:58 -07:00
|
|
|
|
|
|
|
|
|
local screen = Screen.new(60, 5)
|
|
|
|
|
screen:expect {
|
|
|
|
|
grid = [[
|
|
|
|
|
^ |
|
2023-12-09 05:42:00 -07:00
|
|
|
|
{1:~ }|*3
|
2019-09-02 12:59:58 -07:00
|
|
|
|
|
|
|
|
|
|
]],
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-21 01:30:05 -07:00
|
|
|
|
-- nvim_command causes a Vimscript exception, check that it is properly caught
|
2019-09-02 12:59:58 -07:00
|
|
|
|
-- and propagated as an error message in async contexts.. #10809
|
|
|
|
|
exec_lua([[
|
|
|
|
|
vim.schedule(function()
|
|
|
|
|
vim.api.nvim_command(":echo 'err")
|
|
|
|
|
end)
|
|
|
|
|
]])
|
|
|
|
|
screen:expect {
|
|
|
|
|
grid = [[
|
2024-08-14 04:42:05 -07:00
|
|
|
|
{9:stack traceback:} |
|
|
|
|
|
{9: [C]: in function 'nvim_command'} |
|
|
|
|
|
{9: [string "<nvim>"]:2: in function <[string "<nvim>"]:}|
|
|
|
|
|
{9:1>} |
|
|
|
|
|
{6:Press ENTER or type command to continue}^ |
|
2019-09-02 12:59:58 -07:00
|
|
|
|
]],
|
|
|
|
|
}
|
2019-06-04 10:32:43 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2023-03-20 00:12:33 -07:00
|
|
|
|
it('vim.gsplit, vim.split', function()
|
2019-01-07 07:42:20 -07:00
|
|
|
|
local tests = {
|
2023-04-20 21:46:18 -07:00
|
|
|
|
-- plain trimempty
|
2023-03-20 00:12:33 -07:00
|
|
|
|
{ 'a,b', ',', false, false, { 'a', 'b' } },
|
|
|
|
|
{ ':aa::::bb:', ':', false, false, { '', 'aa', '', '', '', 'bb', '' } },
|
|
|
|
|
{ ':aa::::bb:', ':', false, true, { 'aa', '', '', '', 'bb' } },
|
2023-04-20 21:46:18 -07:00
|
|
|
|
{ 'aa::::bb:', ':', false, true, { 'aa', '', '', '', 'bb' } },
|
2023-03-20 00:12:33 -07:00
|
|
|
|
{ ':aa::bb:', ':', false, true, { 'aa', '', 'bb' } },
|
|
|
|
|
{ '/a/b:/b/\n', '[:\n]', false, true, { '/a/b', '/b/' } },
|
|
|
|
|
{ '::ee::ff:', ':', false, false, { '', '', 'ee', '', 'ff', '' } },
|
|
|
|
|
{ '::ee::ff::', ':', false, true, { 'ee', '', 'ff' } },
|
|
|
|
|
{ 'ab', '.', false, false, { '', '', '' } },
|
|
|
|
|
{ 'a1b2c', '[0-9]', false, false, { 'a', 'b', 'c' } },
|
|
|
|
|
{ 'xy', '', false, false, { 'x', 'y' } },
|
|
|
|
|
{ 'here be dragons', ' ', false, false, { 'here', 'be', 'dragons' } },
|
|
|
|
|
{ 'axaby', 'ab?', false, false, { '', 'x', 'y' } },
|
|
|
|
|
{ 'f v2v v3v w2w ', '([vw])2%1', false, false, { 'f ', ' v3v ', ' ' } },
|
|
|
|
|
{ '', '', false, false, {} },
|
|
|
|
|
{ '', '', false, true, {} },
|
|
|
|
|
{ '\n', '[:\n]', false, true, {} },
|
|
|
|
|
{ '', 'a', false, false, { '' } },
|
|
|
|
|
{ 'x*yz*oo*l', '*', true, false, { 'x', 'yz', 'oo', 'l' } },
|
2019-01-07 07:42:20 -07:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-08 02:03:20 -07:00
|
|
|
|
for _, q in ipairs(tests) do
|
|
|
|
|
eq(q[5], vim.split(q[1], q[2], { plain = q[3], trimempty = q[4] }), q[1])
|
2019-01-07 07:42:20 -07:00
|
|
|
|
end
|
|
|
|
|
|
2021-09-25 19:08:36 -07:00
|
|
|
|
-- Test old signature
|
2023-03-20 00:12:33 -07:00
|
|
|
|
eq({ 'x', 'yz', 'oo', 'l' }, vim.split('x*yz*oo*l', '*', true))
|
2021-09-25 19:08:36 -07:00
|
|
|
|
|
2019-01-07 07:42:20 -07:00
|
|
|
|
local loops = {
|
|
|
|
|
{ 'abc', '.-' },
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-08 02:03:20 -07:00
|
|
|
|
for _, q in ipairs(loops) do
|
|
|
|
|
matches('Infinite loop detected', pcall_err(vim.split, q[1], q[2]))
|
2019-01-07 07:42:20 -07:00
|
|
|
|
end
|
2019-10-21 07:46:28 -07:00
|
|
|
|
|
2019-10-26 01:30:58 -07:00
|
|
|
|
-- Validates args.
|
2023-03-20 00:12:33 -07:00
|
|
|
|
eq(true, pcall(vim.split, 'string', 'string'))
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches('s: expected string, got number', pcall_err(vim.split, 1, 'string'))
|
|
|
|
|
matches('sep: expected string, got number', pcall_err(vim.split, 'string', 1))
|
2023-03-20 00:12:33 -07:00
|
|
|
|
matches('opts: expected table, got number', pcall_err(vim.split, 'string', 'string', 1))
|
2019-01-07 07:42:20 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2019-06-04 10:32:43 -07:00
|
|
|
|
it('vim.trim', function()
|
2019-01-07 07:42:20 -07:00
|
|
|
|
local trim = function(s)
|
2019-08-04 06:12:07 -07:00
|
|
|
|
return exec_lua('return vim.trim(...)', s)
|
2019-01-07 07:42:20 -07:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local trims = {
|
|
|
|
|
{ ' a', 'a' },
|
|
|
|
|
{ ' b ', 'b' },
|
|
|
|
|
{ '\tc', 'c' },
|
|
|
|
|
{ 'r\n', 'r' },
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-08 02:03:20 -07:00
|
|
|
|
for _, q in ipairs(trims) do
|
|
|
|
|
assert(q[2], trim(q[1]))
|
2019-01-07 07:42:20 -07:00
|
|
|
|
end
|
|
|
|
|
|
2019-10-26 01:30:58 -07:00
|
|
|
|
-- Validates args.
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches('s: expected string, got number', pcall_err(trim, 2))
|
2019-01-07 07:42:20 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2019-06-04 10:32:43 -07:00
|
|
|
|
it('vim.inspect', function()
|
2019-01-07 07:42:20 -07:00
|
|
|
|
-- just make sure it basically works, it has its own test suite
|
2024-04-08 02:03:20 -07:00
|
|
|
|
local inspect = function(q, opts)
|
|
|
|
|
return exec_lua('return vim.inspect(...)', q, opts)
|
2019-01-07 07:42:20 -07:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
eq('2', inspect(2))
|
2019-01-13 18:05:56 -07:00
|
|
|
|
eq('{+a = {+b = 1+}+}', inspect({ a = { b = 1 } }, { newline = '+', indent = '' }))
|
2019-01-14 10:08:17 -07:00
|
|
|
|
|
|
|
|
|
-- special value vim.inspect.KEY works
|
2019-08-04 06:12:07 -07:00
|
|
|
|
eq(
|
|
|
|
|
'{ KEY_a = "x", KEY_b = "y"}',
|
|
|
|
|
exec_lua([[
|
2019-01-14 10:08:17 -07:00
|
|
|
|
return vim.inspect({a="x", b="y"}, {newline = '', process = function(item, path)
|
|
|
|
|
if path[#path] == vim.inspect.KEY then
|
|
|
|
|
return 'KEY_'..item
|
|
|
|
|
end
|
|
|
|
|
return item
|
|
|
|
|
end})
|
2019-08-04 06:12:07 -07:00
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2019-01-07 07:42:20 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2019-06-04 10:32:43 -07:00
|
|
|
|
it('vim.deepcopy', function()
|
2020-02-14 03:40:02 -07:00
|
|
|
|
ok(exec_lua([[
|
2019-01-07 07:42:20 -07:00
|
|
|
|
local a = { x = { 1, 2 }, y = 5}
|
|
|
|
|
local b = vim.deepcopy(a)
|
|
|
|
|
|
2020-03-02 00:38:43 -07:00
|
|
|
|
return b.x[1] == 1 and b.x[2] == 2 and b.y == 5 and vim.tbl_count(b) == 2
|
2019-01-07 07:42:20 -07:00
|
|
|
|
and tostring(a) ~= tostring(b)
|
2020-02-14 03:40:02 -07:00
|
|
|
|
]]))
|
2020-02-12 19:55:43 -07:00
|
|
|
|
|
2020-02-14 03:40:02 -07:00
|
|
|
|
ok(exec_lua([[
|
2020-02-12 19:55:43 -07:00
|
|
|
|
local a = {}
|
|
|
|
|
local b = vim.deepcopy(a)
|
|
|
|
|
|
2024-04-21 06:19:43 -07:00
|
|
|
|
return vim.islist(b) and vim.tbl_count(b) == 0 and tostring(a) ~= tostring(b)
|
2020-02-14 03:40:02 -07:00
|
|
|
|
]]))
|
2020-02-12 19:55:43 -07:00
|
|
|
|
|
2020-02-14 03:40:02 -07:00
|
|
|
|
ok(exec_lua([[
|
2020-02-12 19:55:43 -07:00
|
|
|
|
local a = vim.empty_dict()
|
|
|
|
|
local b = vim.deepcopy(a)
|
|
|
|
|
|
2024-04-21 06:19:43 -07:00
|
|
|
|
return not vim.islist(b) and vim.tbl_count(b) == 0
|
2020-02-14 03:40:02 -07:00
|
|
|
|
]]))
|
2020-02-12 19:55:43 -07:00
|
|
|
|
|
2020-02-14 03:40:02 -07:00
|
|
|
|
ok(exec_lua([[
|
2020-02-12 19:55:43 -07:00
|
|
|
|
local a = {x = vim.empty_dict(), y = {}}
|
|
|
|
|
local b = vim.deepcopy(a)
|
|
|
|
|
|
2024-04-21 06:19:43 -07:00
|
|
|
|
return not vim.islist(b.x) and vim.islist(b.y)
|
2020-03-02 00:38:43 -07:00
|
|
|
|
and vim.tbl_count(b) == 2
|
2020-02-12 19:55:43 -07:00
|
|
|
|
and tostring(a) ~= tostring(b)
|
2020-02-14 03:40:02 -07:00
|
|
|
|
]]))
|
2020-04-18 16:04:37 -07:00
|
|
|
|
|
|
|
|
|
ok(exec_lua([[
|
|
|
|
|
local f1 = function() return 1 end
|
|
|
|
|
local f2 = function() return 2 end
|
|
|
|
|
local t1 = {f = f1}
|
|
|
|
|
local t2 = vim.deepcopy(t1)
|
|
|
|
|
t1.f = f2
|
|
|
|
|
return t1.f() ~= t2.f()
|
|
|
|
|
]]))
|
|
|
|
|
|
2021-11-26 03:06:43 -07:00
|
|
|
|
ok(exec_lua([[
|
|
|
|
|
local t1 = {a = 5}
|
|
|
|
|
t1.self = t1
|
|
|
|
|
local t2 = vim.deepcopy(t1)
|
|
|
|
|
return t2.self == t2 and t2.self ~= t1
|
|
|
|
|
]]))
|
|
|
|
|
|
|
|
|
|
ok(exec_lua([[
|
|
|
|
|
local mt = {mt=true}
|
|
|
|
|
local t1 = setmetatable({a = 5}, mt)
|
|
|
|
|
local t2 = vim.deepcopy(t1)
|
|
|
|
|
return getmetatable(t2) == mt
|
|
|
|
|
]]))
|
|
|
|
|
|
2022-11-14 12:26:27 -07:00
|
|
|
|
ok(exec_lua([[
|
|
|
|
|
local t1 = {a = vim.NIL}
|
|
|
|
|
local t2 = vim.deepcopy(t1)
|
|
|
|
|
return t2.a == vim.NIL
|
|
|
|
|
]]))
|
|
|
|
|
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches(
|
|
|
|
|
'Cannot deepcopy object of type thread',
|
2020-11-04 02:41:22 -07:00
|
|
|
|
pcall_err(
|
|
|
|
|
exec_lua,
|
|
|
|
|
[[
|
2020-04-18 16:04:37 -07:00
|
|
|
|
local thread = coroutine.create(function () return 0 end)
|
|
|
|
|
local t = {thr = thread}
|
|
|
|
|
vim.deepcopy(t)
|
|
|
|
|
]]
|
|
|
|
|
)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2019-01-07 07:42:20 -07:00
|
|
|
|
end)
|
2019-09-03 13:51:45 -07:00
|
|
|
|
|
|
|
|
|
it('vim.pesc', function()
|
2019-10-26 01:30:58 -07:00
|
|
|
|
eq('foo%-bar', exec_lua([[return vim.pesc('foo-bar')]]))
|
|
|
|
|
eq('foo%%%-bar', exec_lua([[return vim.pesc(vim.pesc('foo-bar'))]]))
|
2022-10-24 05:53:53 -07:00
|
|
|
|
-- pesc() returns one result. #20751
|
|
|
|
|
eq({ 'x' }, exec_lua([[return {vim.pesc('x')}]]))
|
2019-10-21 07:46:28 -07:00
|
|
|
|
|
2019-10-26 01:30:58 -07:00
|
|
|
|
-- Validates args.
|
2020-11-04 02:41:22 -07:00
|
|
|
|
matches('s: expected string, got number', pcall_err(exec_lua, [[return vim.pesc(2)]]))
|
2019-09-03 13:51:45 -07:00
|
|
|
|
end)
|
2019-08-25 13:01:35 -07:00
|
|
|
|
|
2023-04-14 01:39:57 -07:00
|
|
|
|
it('vim.list_contains', function()
|
|
|
|
|
eq(true, exec_lua("return vim.list_contains({'a','b','c'}, 'c')"))
|
|
|
|
|
eq(false, exec_lua("return vim.list_contains({'a','b','c'}, 'd')"))
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('vim.tbl_contains', function()
|
|
|
|
|
eq(true, exec_lua("return vim.tbl_contains({'a','b','c'}, 'c')"))
|
|
|
|
|
eq(false, exec_lua("return vim.tbl_contains({'a','b','c'}, 'd')"))
|
|
|
|
|
eq(true, exec_lua("return vim.tbl_contains({[2]='a',foo='b',[5] = 'c'}, 'c')"))
|
|
|
|
|
eq(
|
|
|
|
|
true,
|
|
|
|
|
exec_lua([[
|
|
|
|
|
return vim.tbl_contains({ 'a', { 'b', 'c' } }, function(v)
|
|
|
|
|
return vim.deep_equal(v, { 'b', 'c' })
|
|
|
|
|
end, { predicate = true })
|
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2023-04-14 01:39:57 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2019-11-13 13:55:26 -07:00
|
|
|
|
it('vim.tbl_keys', function()
|
|
|
|
|
eq({}, exec_lua('return vim.tbl_keys({})'))
|
|
|
|
|
for _, v in pairs(exec_lua("return vim.tbl_keys({'a', 'b', 'c'})")) do
|
|
|
|
|
eq(true, exec_lua('return vim.tbl_contains({ 1, 2, 3 }, ...)', v))
|
|
|
|
|
end
|
|
|
|
|
for _, v in pairs(exec_lua('return vim.tbl_keys({a=1, b=2, c=3})')) do
|
|
|
|
|
eq(true, exec_lua("return vim.tbl_contains({ 'a', 'b', 'c' }, ...)", v))
|
|
|
|
|
end
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('vim.tbl_values', function()
|
|
|
|
|
eq({}, exec_lua('return vim.tbl_values({})'))
|
|
|
|
|
for _, v in pairs(exec_lua("return vim.tbl_values({'a', 'b', 'c'})")) do
|
|
|
|
|
eq(true, exec_lua("return vim.tbl_contains({ 'a', 'b', 'c' }, ...)", v))
|
|
|
|
|
end
|
|
|
|
|
for _, v in pairs(exec_lua('return vim.tbl_values({a=1, b=2, c=3})')) do
|
|
|
|
|
eq(true, exec_lua('return vim.tbl_contains({ 1, 2, 3 }, ...)', v))
|
|
|
|
|
end
|
|
|
|
|
end)
|
|
|
|
|
|
2020-02-18 01:41:29 -07:00
|
|
|
|
it('vim.tbl_map', function()
|
|
|
|
|
eq(
|
|
|
|
|
{},
|
|
|
|
|
exec_lua([[
|
|
|
|
|
return vim.tbl_map(function(v) return v * 2 end, {})
|
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2020-02-18 01:41:29 -07:00
|
|
|
|
eq(
|
|
|
|
|
{ 2, 4, 6 },
|
|
|
|
|
exec_lua([[
|
|
|
|
|
return vim.tbl_map(function(v) return v * 2 end, {1, 2, 3})
|
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2020-02-18 01:41:29 -07:00
|
|
|
|
eq(
|
|
|
|
|
{ { i = 2 }, { i = 4 }, { i = 6 } },
|
|
|
|
|
exec_lua([[
|
|
|
|
|
return vim.tbl_map(function(v) return { i = v.i * 2 } end, {{i=1}, {i=2}, {i=3}})
|
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2020-02-18 01:41:29 -07:00
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('vim.tbl_filter', function()
|
|
|
|
|
eq(
|
|
|
|
|
{},
|
|
|
|
|
exec_lua([[
|
|
|
|
|
return vim.tbl_filter(function(v) return (v % 2) == 0 end, {})
|
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2020-02-18 01:41:29 -07:00
|
|
|
|
eq(
|
|
|
|
|
{ 2 },
|
|
|
|
|
exec_lua([[
|
|
|
|
|
return vim.tbl_filter(function(v) return (v % 2) == 0 end, {1, 2, 3})
|
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2020-02-18 01:41:29 -07:00
|
|
|
|
eq(
|
|
|
|
|
{ { i = 2 } },
|
|
|
|
|
exec_lua([[
|
|
|
|
|
return vim.tbl_filter(function(v) return (v.i % 2) == 0 end, {{i=1}, {i=2}, {i=3}})
|
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2020-02-18 01:41:29 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2024-04-21 08:29:10 -07:00
|
|
|
|
it('vim.isarray', function()
|
|
|
|
|
eq(true, exec_lua('return vim.isarray({})'))
|
|
|
|
|
eq(false, exec_lua('return vim.isarray(vim.empty_dict())'))
|
|
|
|
|
eq(true, exec_lua("return vim.isarray({'a', 'b', 'c'})"))
|
|
|
|
|
eq(false, exec_lua("return vim.isarray({'a', '32', a='hello', b='baz'})"))
|
|
|
|
|
eq(false, exec_lua("return vim.isarray({1, a='hello', b='baz'})"))
|
|
|
|
|
eq(false, exec_lua("return vim.isarray({a='hello', b='baz', 1})"))
|
|
|
|
|
eq(false, exec_lua("return vim.isarray({1, 2, nil, a='hello'})"))
|
|
|
|
|
eq(true, exec_lua('return vim.isarray({1, 2, nil, 4})'))
|
|
|
|
|
eq(true, exec_lua('return vim.isarray({nil, 2, 3, 4})'))
|
|
|
|
|
eq(false, exec_lua('return vim.isarray({1, [1.5]=2, [3]=3})'))
|
2023-04-14 03:01:08 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2024-04-21 06:19:43 -07:00
|
|
|
|
it('vim.islist', function()
|
|
|
|
|
eq(true, exec_lua('return vim.islist({})'))
|
|
|
|
|
eq(false, exec_lua('return vim.islist(vim.empty_dict())'))
|
|
|
|
|
eq(true, exec_lua("return vim.islist({'a', 'b', 'c'})"))
|
|
|
|
|
eq(false, exec_lua("return vim.islist({'a', '32', a='hello', b='baz'})"))
|
|
|
|
|
eq(false, exec_lua("return vim.islist({1, a='hello', b='baz'})"))
|
|
|
|
|
eq(false, exec_lua("return vim.islist({a='hello', b='baz', 1})"))
|
|
|
|
|
eq(false, exec_lua("return vim.islist({1, 2, nil, a='hello'})"))
|
|
|
|
|
eq(false, exec_lua('return vim.islist({1, 2, nil, 4})'))
|
|
|
|
|
eq(false, exec_lua('return vim.islist({nil, 2, 3, 4})'))
|
|
|
|
|
eq(false, exec_lua('return vim.islist({1, [1.5]=2, [3]=3})'))
|
2019-11-13 13:55:26 -07:00
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('vim.tbl_isempty', function()
|
|
|
|
|
eq(true, exec_lua('return vim.tbl_isempty({})'))
|
|
|
|
|
eq(false, exec_lua('return vim.tbl_isempty({ 1, 2, 3 })'))
|
|
|
|
|
eq(false, exec_lua('return vim.tbl_isempty({a=1, b=2, c=3})'))
|
|
|
|
|
end)
|
|
|
|
|
|
2022-03-24 12:01:04 -07:00
|
|
|
|
it('vim.tbl_get', function()
|
|
|
|
|
eq(
|
|
|
|
|
true,
|
|
|
|
|
exec_lua("return vim.tbl_get({ test = { nested_test = true }}, 'test', 'nested_test')")
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2022-05-01 12:08:05 -07:00
|
|
|
|
eq(NIL, exec_lua("return vim.tbl_get({ unindexable = true }, 'unindexable', 'missing_key')"))
|
|
|
|
|
eq(NIL, exec_lua("return vim.tbl_get({ unindexable = 1 }, 'unindexable', 'missing_key')"))
|
|
|
|
|
eq(
|
|
|
|
|
NIL,
|
|
|
|
|
exec_lua(
|
|
|
|
|
"return vim.tbl_get({ unindexable = coroutine.create(function () end) }, 'unindexable', 'missing_key')"
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
eq(
|
|
|
|
|
NIL,
|
|
|
|
|
exec_lua(
|
|
|
|
|
"return vim.tbl_get({ unindexable = function () end }, 'unindexable', 'missing_key')"
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
|
|
|
|
)
|
2022-03-24 12:01:04 -07:00
|
|
|
|
eq(NIL, exec_lua("return vim.tbl_get({}, 'missing_key')"))
|
|
|
|
|
eq(NIL, exec_lua('return vim.tbl_get({})'))
|
2022-12-14 18:27:23 -07:00
|
|
|
|
eq(1, exec_lua("return select('#', vim.tbl_get({}))"))
|
|
|
|
|
eq(1, exec_lua("return select('#', vim.tbl_get({ nested = {} }, 'nested', 'missing_key'))"))
|
2022-03-24 12:01:04 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2020-02-14 03:40:02 -07:00
|
|
|
|
it('vim.tbl_extend', function()
|
|
|
|
|
ok(exec_lua([[
|
|
|
|
|
local a = {x = 1}
|
|
|
|
|
local b = {y = 2}
|
|
|
|
|
local c = vim.tbl_extend("keep", a, b)
|
|
|
|
|
|
2020-03-02 00:38:43 -07:00
|
|
|
|
return c.x == 1 and b.y == 2 and vim.tbl_count(c) == 2
|
2020-02-14 03:40:02 -07:00
|
|
|
|
]]))
|
|
|
|
|
|
|
|
|
|
ok(exec_lua([[
|
|
|
|
|
local a = {x = 1}
|
|
|
|
|
local b = {y = 2}
|
|
|
|
|
local c = {z = 3}
|
|
|
|
|
local d = vim.tbl_extend("keep", a, b, c)
|
|
|
|
|
|
2020-03-02 00:38:43 -07:00
|
|
|
|
return d.x == 1 and d.y == 2 and d.z == 3 and vim.tbl_count(d) == 3
|
2020-02-14 03:40:02 -07:00
|
|
|
|
]]))
|
|
|
|
|
|
|
|
|
|
ok(exec_lua([[
|
|
|
|
|
local a = {x = 1}
|
|
|
|
|
local b = {x = 3}
|
|
|
|
|
local c = vim.tbl_extend("keep", a, b)
|
|
|
|
|
|
2020-03-02 00:38:43 -07:00
|
|
|
|
return c.x == 1 and vim.tbl_count(c) == 1
|
2020-02-14 03:40:02 -07:00
|
|
|
|
]]))
|
|
|
|
|
|
|
|
|
|
ok(exec_lua([[
|
|
|
|
|
local a = {x = 1}
|
|
|
|
|
local b = {x = 3}
|
|
|
|
|
local c = vim.tbl_extend("force", a, b)
|
|
|
|
|
|
2020-03-02 00:38:43 -07:00
|
|
|
|
return c.x == 3 and vim.tbl_count(c) == 1
|
2020-02-14 03:40:02 -07:00
|
|
|
|
]]))
|
|
|
|
|
|
|
|
|
|
ok(exec_lua([[
|
|
|
|
|
local a = vim.empty_dict()
|
|
|
|
|
local b = {}
|
|
|
|
|
local c = vim.tbl_extend("keep", a, b)
|
|
|
|
|
|
2024-04-21 06:19:43 -07:00
|
|
|
|
return not vim.islist(c) and vim.tbl_count(c) == 0
|
2020-02-14 03:40:02 -07:00
|
|
|
|
]]))
|
|
|
|
|
|
|
|
|
|
ok(exec_lua([[
|
|
|
|
|
local a = {}
|
|
|
|
|
local b = vim.empty_dict()
|
|
|
|
|
local c = vim.tbl_extend("keep", a, b)
|
|
|
|
|
|
2024-04-21 06:19:43 -07:00
|
|
|
|
return vim.islist(c) and vim.tbl_count(c) == 0
|
2020-02-14 03:40:02 -07:00
|
|
|
|
]]))
|
|
|
|
|
|
2020-05-17 10:24:34 -07:00
|
|
|
|
ok(exec_lua([[
|
|
|
|
|
local a = {x = {a = 1, b = 2}}
|
|
|
|
|
local b = {x = {a = 2, c = {y = 3}}}
|
|
|
|
|
local c = vim.tbl_extend("keep", a, b)
|
|
|
|
|
|
|
|
|
|
local count = 0
|
|
|
|
|
for _ in pairs(c) do count = count + 1 end
|
|
|
|
|
|
|
|
|
|
return c.x.a == 1 and c.x.b == 2 and c.x.c == nil and count == 1
|
|
|
|
|
]]))
|
|
|
|
|
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches(
|
|
|
|
|
'invalid "behavior": nil',
|
2020-11-04 02:41:22 -07:00
|
|
|
|
pcall_err(
|
|
|
|
|
exec_lua,
|
|
|
|
|
[[
|
2020-02-14 03:40:02 -07:00
|
|
|
|
return vim.tbl_extend()
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches(
|
|
|
|
|
'wrong number of arguments %(given 1, expected at least 3%)',
|
2020-11-04 02:41:22 -07:00
|
|
|
|
pcall_err(
|
|
|
|
|
exec_lua,
|
|
|
|
|
[[
|
2020-02-14 03:40:02 -07:00
|
|
|
|
return vim.tbl_extend("keep")
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches(
|
|
|
|
|
'wrong number of arguments %(given 2, expected at least 3%)',
|
2020-11-04 02:41:22 -07:00
|
|
|
|
pcall_err(
|
|
|
|
|
exec_lua,
|
|
|
|
|
[[
|
2020-02-14 03:40:02 -07:00
|
|
|
|
return vim.tbl_extend("keep", {})
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
2020-05-17 10:24:34 -07:00
|
|
|
|
it('vim.tbl_deep_extend', function()
|
|
|
|
|
ok(exec_lua([[
|
|
|
|
|
local a = {x = {a = 1, b = 2}}
|
|
|
|
|
local b = {x = {a = 2, c = {y = 3}}}
|
|
|
|
|
local c = vim.tbl_deep_extend("keep", a, b)
|
|
|
|
|
|
|
|
|
|
local count = 0
|
|
|
|
|
for _ in pairs(c) do count = count + 1 end
|
|
|
|
|
|
|
|
|
|
return c.x.a == 1 and c.x.b == 2 and c.x.c.y == 3 and count == 1
|
|
|
|
|
]]))
|
|
|
|
|
|
|
|
|
|
ok(exec_lua([[
|
|
|
|
|
local a = {x = {a = 1, b = 2}}
|
|
|
|
|
local b = {x = {a = 2, c = {y = 3}}}
|
|
|
|
|
local c = vim.tbl_deep_extend("force", a, b)
|
|
|
|
|
|
|
|
|
|
local count = 0
|
|
|
|
|
for _ in pairs(c) do count = count + 1 end
|
|
|
|
|
|
|
|
|
|
return c.x.a == 2 and c.x.b == 2 and c.x.c.y == 3 and count == 1
|
|
|
|
|
]]))
|
|
|
|
|
|
|
|
|
|
ok(exec_lua([[
|
|
|
|
|
local a = {x = {a = 1, b = 2}}
|
|
|
|
|
local b = {x = {a = 2, c = {y = 3}}}
|
|
|
|
|
local c = {x = {c = 4, d = {y = 4}}}
|
|
|
|
|
local d = vim.tbl_deep_extend("keep", a, b, c)
|
|
|
|
|
|
|
|
|
|
local count = 0
|
|
|
|
|
for _ in pairs(c) do count = count + 1 end
|
|
|
|
|
|
|
|
|
|
return d.x.a == 1 and d.x.b == 2 and d.x.c.y == 3 and d.x.d.y == 4 and count == 1
|
|
|
|
|
]]))
|
|
|
|
|
|
|
|
|
|
ok(exec_lua([[
|
|
|
|
|
local a = {x = {a = 1, b = 2}}
|
|
|
|
|
local b = {x = {a = 2, c = {y = 3}}}
|
|
|
|
|
local c = {x = {c = 4, d = {y = 4}}}
|
|
|
|
|
local d = vim.tbl_deep_extend("force", a, b, c)
|
|
|
|
|
|
|
|
|
|
local count = 0
|
|
|
|
|
for _ in pairs(c) do count = count + 1 end
|
|
|
|
|
|
|
|
|
|
return d.x.a == 2 and d.x.b == 2 and d.x.c == 4 and d.x.d.y == 4 and count == 1
|
|
|
|
|
]]))
|
|
|
|
|
|
|
|
|
|
ok(exec_lua([[
|
|
|
|
|
local a = vim.empty_dict()
|
|
|
|
|
local b = {}
|
|
|
|
|
local c = vim.tbl_deep_extend("keep", a, b)
|
|
|
|
|
|
|
|
|
|
local count = 0
|
|
|
|
|
for _ in pairs(c) do count = count + 1 end
|
|
|
|
|
|
2024-04-21 06:19:43 -07:00
|
|
|
|
return not vim.islist(c) and count == 0
|
2020-05-17 10:24:34 -07:00
|
|
|
|
]]))
|
|
|
|
|
|
|
|
|
|
ok(exec_lua([[
|
|
|
|
|
local a = {}
|
|
|
|
|
local b = vim.empty_dict()
|
|
|
|
|
local c = vim.tbl_deep_extend("keep", a, b)
|
|
|
|
|
|
|
|
|
|
local count = 0
|
|
|
|
|
for _ in pairs(c) do count = count + 1 end
|
|
|
|
|
|
2024-04-21 06:19:43 -07:00
|
|
|
|
return vim.islist(c) and count == 0
|
2020-05-17 10:24:34 -07:00
|
|
|
|
]]))
|
|
|
|
|
|
2022-04-25 20:35:05 -07:00
|
|
|
|
eq(
|
|
|
|
|
{ a = { b = 1 } },
|
|
|
|
|
exec_lua([[
|
2021-07-19 08:52:44 -07:00
|
|
|
|
local a = { a = { b = 1 } }
|
|
|
|
|
local b = { a = {} }
|
|
|
|
|
return vim.tbl_deep_extend("force", a, b)
|
2022-04-25 20:35:05 -07:00
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-07-19 08:52:44 -07:00
|
|
|
|
|
2022-04-25 20:35:05 -07:00
|
|
|
|
eq(
|
|
|
|
|
{ a = { b = 1 } },
|
|
|
|
|
exec_lua([[
|
2021-07-19 08:52:44 -07:00
|
|
|
|
local a = { a = 123 }
|
|
|
|
|
local b = { a = { b = 1} }
|
|
|
|
|
return vim.tbl_deep_extend("force", a, b)
|
2022-04-25 20:35:05 -07:00
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-07-19 08:52:44 -07:00
|
|
|
|
|
|
|
|
|
ok(exec_lua([[
|
|
|
|
|
local a = { a = {[2] = 3} }
|
|
|
|
|
local b = { a = {[3] = 3} }
|
|
|
|
|
local c = vim.tbl_deep_extend("force", a, b)
|
2024-09-03 09:14:25 -07:00
|
|
|
|
return vim.deep_equal(c, {a = {[2] = 3, [3] = 3}})
|
2021-07-19 08:52:44 -07:00
|
|
|
|
]]))
|
|
|
|
|
|
2022-04-25 20:35:05 -07:00
|
|
|
|
eq(
|
|
|
|
|
{ a = 123 },
|
|
|
|
|
exec_lua([[
|
2021-07-19 08:52:44 -07:00
|
|
|
|
local a = { a = { b = 1} }
|
|
|
|
|
local b = { a = 123 }
|
|
|
|
|
return vim.tbl_deep_extend("force", a, b)
|
2022-04-25 20:35:05 -07:00
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-07-19 08:52:44 -07:00
|
|
|
|
|
2024-09-03 09:14:25 -07:00
|
|
|
|
ok(exec_lua([[
|
2024-09-08 09:23:46 -07:00
|
|
|
|
local a = { sub = { 'a', 'b' } }
|
|
|
|
|
local b = { sub = { 'b', 'c' } }
|
2024-09-03 09:14:25 -07:00
|
|
|
|
local c = vim.tbl_deep_extend('force', a, b)
|
2024-09-08 09:23:46 -07:00
|
|
|
|
return vim.deep_equal(c, { sub = { 'b', 'c' } })
|
2024-09-03 09:14:25 -07:00
|
|
|
|
]]))
|
|
|
|
|
|
2024-09-07 09:41:02 -07:00
|
|
|
|
matches('invalid "behavior": nil', pcall_err(exec_lua, [[return vim.tbl_deep_extend()]]))
|
2020-05-17 10:24:34 -07:00
|
|
|
|
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches(
|
|
|
|
|
'wrong number of arguments %(given 1, expected at least 3%)',
|
2024-09-07 09:41:02 -07:00
|
|
|
|
pcall_err(exec_lua, [[return vim.tbl_deep_extend("keep")]])
|
2020-05-17 10:24:34 -07:00
|
|
|
|
)
|
|
|
|
|
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches(
|
|
|
|
|
'wrong number of arguments %(given 2, expected at least 3%)',
|
2024-09-07 09:41:02 -07:00
|
|
|
|
pcall_err(exec_lua, [[return vim.tbl_deep_extend("keep", {})]])
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
matches(
|
|
|
|
|
'after the second argument%: expected table, got number',
|
|
|
|
|
pcall_err(exec_lua, [[return vim.tbl_deep_extend("keep", {}, 42)]])
|
2020-05-17 10:24:34 -07:00
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
2020-03-02 00:38:43 -07:00
|
|
|
|
it('vim.tbl_count', function()
|
|
|
|
|
eq(0, exec_lua [[ return vim.tbl_count({}) ]])
|
|
|
|
|
eq(0, exec_lua [[ return vim.tbl_count(vim.empty_dict()) ]])
|
|
|
|
|
eq(0, exec_lua [[ return vim.tbl_count({nil}) ]])
|
|
|
|
|
eq(0, exec_lua [[ return vim.tbl_count({a=nil}) ]])
|
|
|
|
|
eq(1, exec_lua [[ return vim.tbl_count({1}) ]])
|
|
|
|
|
eq(2, exec_lua [[ return vim.tbl_count({1, 2}) ]])
|
|
|
|
|
eq(2, exec_lua [[ return vim.tbl_count({1, nil, 3}) ]])
|
|
|
|
|
eq(1, exec_lua [[ return vim.tbl_count({a=1}) ]])
|
|
|
|
|
eq(2, exec_lua [[ return vim.tbl_count({a=1, b=2}) ]])
|
|
|
|
|
eq(2, exec_lua [[ return vim.tbl_count({a=1, b=nil, c=3}) ]])
|
|
|
|
|
end)
|
|
|
|
|
|
2019-11-13 13:55:26 -07:00
|
|
|
|
it('vim.deep_equal', function()
|
|
|
|
|
eq(true, exec_lua [[ return vim.deep_equal({a=1}, {a=1}) ]])
|
|
|
|
|
eq(true, exec_lua [[ return vim.deep_equal({a={b=1}}, {a={b=1}}) ]])
|
|
|
|
|
eq(true, exec_lua [[ return vim.deep_equal({a={b={nil}}}, {a={b={}}}) ]])
|
|
|
|
|
eq(true, exec_lua [[ return vim.deep_equal({a=1, [5]=5}, {nil,nil,nil,nil,5,a=1}) ]])
|
|
|
|
|
eq(false, exec_lua [[ return vim.deep_equal(1, {nil,nil,nil,nil,5,a=1}) ]])
|
|
|
|
|
eq(false, exec_lua [[ return vim.deep_equal(1, 3) ]])
|
|
|
|
|
eq(false, exec_lua [[ return vim.deep_equal(nil, 3) ]])
|
|
|
|
|
eq(false, exec_lua [[ return vim.deep_equal({a=1}, {a=2}) ]])
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('vim.list_extend', function()
|
|
|
|
|
eq({ 1, 2, 3 }, exec_lua [[ return vim.list_extend({1}, {2,3}) ]])
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches(
|
|
|
|
|
'src: expected table, got nil',
|
2020-11-04 02:41:22 -07:00
|
|
|
|
pcall_err(exec_lua, [[ return vim.list_extend({1}, nil) ]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2019-11-13 13:55:26 -07:00
|
|
|
|
eq({ 1, 2 }, exec_lua [[ return vim.list_extend({1}, {2;a=1}) ]])
|
|
|
|
|
eq(true, exec_lua [[ local a = {1} return vim.list_extend(a, {2;a=1}) == a ]])
|
2019-11-20 18:09:21 -07:00
|
|
|
|
eq({ 2 }, exec_lua [[ return vim.list_extend({}, {2;a=1}, 1) ]])
|
|
|
|
|
eq({}, exec_lua [[ return vim.list_extend({}, {2;a=1}, 2) ]])
|
|
|
|
|
eq({}, exec_lua [[ return vim.list_extend({}, {2;a=1}, 1, -1) ]])
|
|
|
|
|
eq({ 2 }, exec_lua [[ return vim.list_extend({}, {2;a=1}, -1, 2) ]])
|
2019-11-13 13:55:26 -07:00
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('vim.tbl_add_reverse_lookup', function()
|
|
|
|
|
eq(
|
|
|
|
|
true,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
local a = { A = 1 }
|
|
|
|
|
vim.tbl_add_reverse_lookup(a)
|
|
|
|
|
return vim.deep_equal(a, { A = 1; [1] = 'A'; })
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
-- Throw an error for trying to do it twice (run into an existing key)
|
|
|
|
|
local code = [[
|
|
|
|
|
local res = {}
|
|
|
|
|
local a = { A = 1 }
|
|
|
|
|
vim.tbl_add_reverse_lookup(a)
|
|
|
|
|
assert(vim.deep_equal(a, { A = 1; [1] = 'A'; }))
|
|
|
|
|
vim.tbl_add_reverse_lookup(a)
|
|
|
|
|
]]
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches(
|
|
|
|
|
'The reverse lookup found an existing value for "[1A]" while processing key "[1A]"$',
|
2020-11-04 02:41:22 -07:00
|
|
|
|
pcall_err(exec_lua, code)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2019-11-13 13:55:26 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2023-01-23 02:26:46 -07:00
|
|
|
|
it('vim.spairs', function()
|
|
|
|
|
local res = ''
|
|
|
|
|
local table = {
|
|
|
|
|
ccc = 1,
|
|
|
|
|
bbb = 2,
|
|
|
|
|
ddd = 3,
|
|
|
|
|
aaa = 4,
|
|
|
|
|
}
|
|
|
|
|
for key, _ in vim.spairs(table) do
|
|
|
|
|
res = res .. key
|
|
|
|
|
end
|
|
|
|
|
matches('aaabbbcccddd', res)
|
|
|
|
|
end)
|
|
|
|
|
|
2019-10-27 15:05:59 -07:00
|
|
|
|
it('vim.call, vim.fn', function()
|
2019-08-25 13:01:35 -07:00
|
|
|
|
eq(true, exec_lua([[return vim.call('sin', 0.0) == 0.0 ]]))
|
|
|
|
|
eq(true, exec_lua([[return vim.fn.sin(0.0) == 0.0 ]]))
|
2023-07-21 01:30:05 -07:00
|
|
|
|
-- compat: nvim_call_function uses "special" value for Vimscript float
|
2019-08-25 13:01:35 -07:00
|
|
|
|
eq(false, exec_lua([[return vim.api.nvim_call_function('sin', {0.0}) == 0.0 ]]))
|
|
|
|
|
|
2022-03-17 12:21:47 -07:00
|
|
|
|
exec([[
|
2019-08-25 13:01:35 -07:00
|
|
|
|
func! FooFunc(test)
|
|
|
|
|
let g:test = a:test
|
|
|
|
|
return {}
|
|
|
|
|
endfunc
|
|
|
|
|
func! VarArg(...)
|
|
|
|
|
return a:000
|
|
|
|
|
endfunc
|
2019-10-27 12:49:03 -07:00
|
|
|
|
func! Nilly()
|
|
|
|
|
return [v:null, v:null]
|
|
|
|
|
endfunc
|
2019-08-25 13:01:35 -07:00
|
|
|
|
]])
|
|
|
|
|
eq(true, exec_lua([[return next(vim.fn.FooFunc(3)) == nil ]]))
|
|
|
|
|
eq(3, eval('g:test'))
|
2024-07-11 03:26:52 -07:00
|
|
|
|
eq(true, exec_lua([[return vim.tbl_isempty(vim.api.nvim_call_function("FooFunc", {5}))]]))
|
2019-08-25 13:01:35 -07:00
|
|
|
|
eq(5, eval('g:test'))
|
|
|
|
|
|
|
|
|
|
eq({ 2, 'foo', true }, exec_lua([[return vim.fn.VarArg(2, "foo", true)]]))
|
|
|
|
|
|
2019-10-27 12:49:03 -07:00
|
|
|
|
eq(
|
|
|
|
|
true,
|
|
|
|
|
exec_lua([[
|
|
|
|
|
local x = vim.fn.Nilly()
|
|
|
|
|
return #x == 2 and x[1] == vim.NIL and x[2] == vim.NIL
|
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2019-10-27 12:49:03 -07:00
|
|
|
|
eq({ NIL, NIL }, exec_lua([[return vim.fn.Nilly()]]))
|
|
|
|
|
|
2019-08-25 13:01:35 -07:00
|
|
|
|
-- error handling
|
2020-12-02 11:37:18 -07:00
|
|
|
|
eq(
|
|
|
|
|
{ false, 'Vim:E897: List or Blob required' },
|
|
|
|
|
exec_lua([[return {pcall(vim.fn.add, "aa", "bb")}]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2022-03-17 12:21:47 -07:00
|
|
|
|
|
|
|
|
|
-- conversion between LuaRef and Vim Funcref
|
|
|
|
|
eq(
|
|
|
|
|
true,
|
|
|
|
|
exec_lua([[
|
|
|
|
|
local x = vim.fn.VarArg(function() return 'foo' end, function() return 'bar' end)
|
|
|
|
|
return #x == 2 and x[1]() == 'foo' and x[2]() == 'bar'
|
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2022-09-16 08:09:26 -07:00
|
|
|
|
|
|
|
|
|
-- Test for #20211
|
|
|
|
|
eq(
|
|
|
|
|
'a (b) c',
|
|
|
|
|
exec_lua([[
|
|
|
|
|
return vim.fn.substitute('a b c', 'b', function(m) return '(' .. m[1] .. ')' end, 'g')
|
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2019-08-25 13:01:35 -07:00
|
|
|
|
end)
|
2019-10-27 12:49:03 -07:00
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('vim.fn errors when calling API function', function()
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches(
|
|
|
|
|
'Tried to call API function with vim.fn: use vim.api.nvim_get_current_line instead',
|
2021-03-09 14:23:42 -07:00
|
|
|
|
pcall_err(exec_lua, 'vim.fn.nvim_get_current_line()')
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-02-04 08:22:27 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2022-05-17 06:25:56 -07:00
|
|
|
|
it('vim.fn is allowed in "fast" context by some functions #18306', function()
|
2022-04-29 09:26:57 -07:00
|
|
|
|
exec_lua([[
|
2023-06-03 03:06:00 -07:00
|
|
|
|
local timer = vim.uv.new_timer()
|
2022-04-29 09:26:57 -07:00
|
|
|
|
timer:start(0, 0, function()
|
|
|
|
|
timer:close()
|
|
|
|
|
assert(vim.in_fast_event())
|
|
|
|
|
vim.g.fnres = vim.fn.iconv('hello', 'utf-8', 'utf-8')
|
|
|
|
|
end)
|
|
|
|
|
]])
|
|
|
|
|
|
2024-01-12 04:28:20 -07:00
|
|
|
|
poke_eventloop()
|
2022-04-29 09:26:57 -07:00
|
|
|
|
eq('hello', exec_lua [[return vim.g.fnres]])
|
|
|
|
|
end)
|
|
|
|
|
|
2019-10-27 12:49:03 -07:00
|
|
|
|
it('vim.rpcrequest and vim.rpcnotify', function()
|
|
|
|
|
exec_lua([[
|
|
|
|
|
chan = vim.fn.jobstart({'cat'}, {rpc=true})
|
|
|
|
|
vim.rpcrequest(chan, 'nvim_set_current_line', 'meow')
|
|
|
|
|
]])
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq('meow', api.nvim_get_current_line())
|
2019-10-27 12:49:03 -07:00
|
|
|
|
command("let x = [3, 'aa', v:true, v:null]")
|
|
|
|
|
eq(
|
|
|
|
|
true,
|
|
|
|
|
exec_lua([[
|
|
|
|
|
ret = vim.rpcrequest(chan, 'nvim_get_var', 'x')
|
|
|
|
|
return #ret == 4 and ret[1] == 3 and ret[2] == 'aa' and ret[3] == true and ret[4] == vim.NIL
|
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2019-10-27 12:49:03 -07:00
|
|
|
|
eq({ 3, 'aa', true, NIL }, exec_lua([[return ret]]))
|
|
|
|
|
|
2019-11-27 12:45:41 -07:00
|
|
|
|
eq(
|
|
|
|
|
{ {}, {}, false, true },
|
|
|
|
|
exec_lua([[
|
|
|
|
|
vim.rpcrequest(chan, 'nvim_exec', 'let xx = {}\nlet yy = []', false)
|
|
|
|
|
local dict = vim.rpcrequest(chan, 'nvim_eval', 'xx')
|
|
|
|
|
local list = vim.rpcrequest(chan, 'nvim_eval', 'yy')
|
2024-04-21 06:19:43 -07:00
|
|
|
|
return {dict, list, vim.islist(dict), vim.islist(list)}
|
2019-11-27 12:45:41 -07:00
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2019-11-27 12:45:41 -07:00
|
|
|
|
|
|
|
|
|
exec_lua([[
|
|
|
|
|
vim.rpcrequest(chan, 'nvim_set_var', 'aa', {})
|
|
|
|
|
vim.rpcrequest(chan, 'nvim_set_var', 'bb', vim.empty_dict())
|
|
|
|
|
]])
|
|
|
|
|
eq({ 1, 1 }, eval('[type(g:aa) == type([]), type(g:bb) == type({})]'))
|
|
|
|
|
|
2019-10-27 12:49:03 -07:00
|
|
|
|
-- error handling
|
|
|
|
|
eq({ false, 'Invalid channel: 23' }, exec_lua([[return {pcall(vim.rpcrequest, 23, 'foo')}]]))
|
|
|
|
|
eq({ false, 'Invalid channel: 23' }, exec_lua([[return {pcall(vim.rpcnotify, 23, 'foo')}]]))
|
|
|
|
|
|
2024-01-02 18:09:18 -07:00
|
|
|
|
eq(
|
2019-10-27 12:49:03 -07:00
|
|
|
|
{ false, 'Vim:E121: Undefined variable: foobar' },
|
|
|
|
|
exec_lua([[return {pcall(vim.rpcrequest, chan, 'nvim_eval', "foobar")}]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2019-10-27 12:49:03 -07:00
|
|
|
|
|
|
|
|
|
-- rpcnotify doesn't wait on request
|
|
|
|
|
eq(
|
|
|
|
|
'meow',
|
|
|
|
|
exec_lua([[
|
|
|
|
|
vim.rpcnotify(chan, 'nvim_set_current_line', 'foo')
|
|
|
|
|
return vim.api.nvim_get_current_line()
|
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2019-11-10 09:12:41 -07:00
|
|
|
|
retry(10, nil, function()
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq('foo', api.nvim_get_current_line())
|
2019-11-10 09:12:41 -07:00
|
|
|
|
end)
|
2019-10-27 12:49:03 -07:00
|
|
|
|
|
|
|
|
|
local screen = Screen.new(50, 7)
|
|
|
|
|
exec_lua([[
|
2023-06-03 03:06:00 -07:00
|
|
|
|
timer = vim.uv.new_timer()
|
2019-10-27 12:49:03 -07:00
|
|
|
|
timer:start(20, 0, function ()
|
|
|
|
|
-- notify ok (executed later when safe)
|
|
|
|
|
vim.rpcnotify(chan, 'nvim_set_var', 'yy', {3, vim.NIL})
|
|
|
|
|
-- rpcrequest an error
|
|
|
|
|
vim.rpcrequest(chan, 'nvim_set_current_line', 'bork')
|
|
|
|
|
end)
|
|
|
|
|
]])
|
|
|
|
|
screen:expect {
|
|
|
|
|
grid = [[
|
2024-08-14 04:42:05 -07:00
|
|
|
|
{9:[string "<nvim>"]:6: E5560: rpcrequest must not be}|
|
2024-06-20 05:48:06 -07:00
|
|
|
|
{9: called in a fast event context} |
|
2024-08-14 04:42:05 -07:00
|
|
|
|
{9:stack traceback:} |
|
|
|
|
|
{9: [C]: in function 'rpcrequest'} |
|
|
|
|
|
{9: [string "<nvim>"]:6: in function <[string }|
|
|
|
|
|
{9:"<nvim>"]:2>} |
|
|
|
|
|
{6:Press ENTER or type command to continue}^ |
|
2019-10-27 12:49:03 -07:00
|
|
|
|
]],
|
|
|
|
|
}
|
|
|
|
|
feed('<cr>')
|
2024-10-19 04:25:43 -07:00
|
|
|
|
retry(10, nil, function()
|
|
|
|
|
eq({ 3, NIL }, api.nvim_get_var('yy'))
|
|
|
|
|
end)
|
2019-11-27 12:45:41 -07:00
|
|
|
|
|
|
|
|
|
exec_lua([[timer:close()]])
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('vim.empty_dict()', function()
|
|
|
|
|
eq(
|
|
|
|
|
{ true, false, true, true },
|
|
|
|
|
exec_lua([[
|
|
|
|
|
vim.api.nvim_set_var('listy', {})
|
|
|
|
|
vim.api.nvim_set_var('dicty', vim.empty_dict())
|
|
|
|
|
local listy = vim.fn.eval("listy")
|
|
|
|
|
local dicty = vim.fn.eval("dicty")
|
2024-04-21 06:19:43 -07:00
|
|
|
|
return {vim.islist(listy), vim.islist(dicty), next(listy) == nil, next(dicty) == nil}
|
2019-11-27 12:45:41 -07:00
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2019-11-27 12:45:41 -07:00
|
|
|
|
|
|
|
|
|
-- vim.empty_dict() gives new value each time
|
|
|
|
|
-- equality is not overridden (still by ref)
|
|
|
|
|
-- non-empty table uses the usual heuristics (ignores the tag)
|
|
|
|
|
eq(
|
|
|
|
|
{ false, { 'foo' }, { namey = 'bar' } },
|
|
|
|
|
exec_lua([[
|
|
|
|
|
local aa = vim.empty_dict()
|
|
|
|
|
local bb = vim.empty_dict()
|
|
|
|
|
local equally = (aa == bb)
|
|
|
|
|
aa[1] = "foo"
|
|
|
|
|
bb["namey"] = "bar"
|
|
|
|
|
return {equally, aa, bb}
|
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2019-11-27 12:45:41 -07:00
|
|
|
|
|
|
|
|
|
eq('{ {}, vim.empty_dict() }', exec_lua('return vim.inspect({{}, vim.empty_dict()})'))
|
2020-02-12 04:51:15 -07:00
|
|
|
|
eq('{}', exec_lua([[ return vim.fn.json_encode(vim.empty_dict()) ]]))
|
|
|
|
|
eq('{"a": {}, "b": []}', exec_lua([[ return vim.fn.json_encode({a=vim.empty_dict(), b={}}) ]]))
|
2019-10-27 12:49:03 -07:00
|
|
|
|
end)
|
2019-10-28 04:52:18 -07:00
|
|
|
|
|
2024-10-18 03:33:12 -07:00
|
|
|
|
it('vim.validate (fast form)', function()
|
|
|
|
|
exec_lua("vim.validate('arg1', {}, 'table')")
|
|
|
|
|
exec_lua("vim.validate('arg1', nil, 'table', true)")
|
|
|
|
|
exec_lua("vim.validate('arg1', { foo='foo' }, 'table')")
|
|
|
|
|
exec_lua("vim.validate('arg1', { 'foo' }, 'table')")
|
|
|
|
|
exec_lua("vim.validate('arg1', 'foo', 'string')")
|
|
|
|
|
exec_lua("vim.validate('arg1', nil, 'string', true)")
|
|
|
|
|
exec_lua("vim.validate('arg1', 1, 'number')")
|
|
|
|
|
exec_lua("vim.validate('arg1', 0, 'number')")
|
|
|
|
|
exec_lua("vim.validate('arg1', 0.1, 'number')")
|
|
|
|
|
exec_lua("vim.validate('arg1', nil, 'number', true)")
|
|
|
|
|
exec_lua("vim.validate('arg1', true, 'boolean')")
|
|
|
|
|
exec_lua("vim.validate('arg1', false, 'boolean')")
|
|
|
|
|
exec_lua("vim.validate('arg1', nil, 'boolean', true)")
|
|
|
|
|
exec_lua("vim.validate('arg1', function()end, 'function')")
|
|
|
|
|
exec_lua("vim.validate('arg1', nil, 'function', true)")
|
|
|
|
|
exec_lua("vim.validate('arg1', nil, 'nil')")
|
|
|
|
|
exec_lua("vim.validate('arg1', nil, 'nil', true)")
|
|
|
|
|
exec_lua("vim.validate('arg1', coroutine.create(function()end), 'thread')")
|
|
|
|
|
exec_lua("vim.validate('arg1', nil, 'thread', true)")
|
|
|
|
|
exec_lua("vim.validate('arg1', 2, function(a) return (a % 2) == 0 end, 'even number')")
|
|
|
|
|
exec_lua("vim.validate('arg1', 5, {'number', 'string'})")
|
|
|
|
|
exec_lua("vim.validate('arg2', 'foo', {'number', 'string'})")
|
|
|
|
|
|
|
|
|
|
matches('arg1: expected number, got nil', pcall_err(vim.validate, 'arg1', nil, 'number'))
|
|
|
|
|
matches('arg1: expected string, got nil', pcall_err(vim.validate, 'arg1', nil, 'string'))
|
|
|
|
|
matches('arg1: expected table, got nil', pcall_err(vim.validate, 'arg1', nil, 'table'))
|
|
|
|
|
matches('arg1: expected function, got nil', pcall_err(vim.validate, 'arg1', nil, 'function'))
|
|
|
|
|
matches('arg1: expected string, got number', pcall_err(vim.validate, 'arg1', 5, 'string'))
|
|
|
|
|
matches('arg1: expected table, got number', pcall_err(vim.validate, 'arg1', 5, 'table'))
|
|
|
|
|
matches('arg1: expected function, got number', pcall_err(vim.validate, 'arg1', 5, 'function'))
|
|
|
|
|
matches('arg1: expected number, got string', pcall_err(vim.validate, 'arg1', '5', 'number'))
|
|
|
|
|
matches('arg1: expected x, got number', pcall_err(exec_lua, "vim.validate('arg1', 1, 'x')"))
|
|
|
|
|
matches('invalid validator: 1', pcall_err(exec_lua, "vim.validate('arg1', 1, 1)"))
|
|
|
|
|
matches('invalid arguments', pcall_err(exec_lua, "vim.validate('arg1', { 1 })"))
|
|
|
|
|
|
|
|
|
|
-- Validated parameters are required by default.
|
|
|
|
|
matches(
|
|
|
|
|
'arg1: expected string, got nil',
|
|
|
|
|
pcall_err(exec_lua, "vim.validate('arg1', nil, 'string')")
|
|
|
|
|
)
|
|
|
|
|
-- Explicitly required.
|
|
|
|
|
matches(
|
|
|
|
|
'arg1: expected string, got nil',
|
|
|
|
|
pcall_err(exec_lua, "vim.validate('arg1', nil, 'string', false)")
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
matches(
|
|
|
|
|
'arg1: expected table, got number',
|
|
|
|
|
pcall_err(exec_lua, "vim.validate('arg1', 1, 'table')")
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
matches(
|
|
|
|
|
'arg1: expected even number, got 3',
|
|
|
|
|
pcall_err(exec_lua, "vim.validate('arg1', 3, function(a) return a == 1 end, 'even number')")
|
|
|
|
|
)
|
|
|
|
|
matches(
|
|
|
|
|
'arg1: expected %?, got 3',
|
|
|
|
|
pcall_err(exec_lua, "vim.validate('arg1', 3, function(a) return a == 1 end)")
|
|
|
|
|
)
|
|
|
|
|
matches(
|
|
|
|
|
'arg1: expected number|string, got nil',
|
|
|
|
|
pcall_err(exec_lua, "vim.validate('arg1', nil, {'number', 'string'})")
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
-- Pass an additional message back.
|
|
|
|
|
matches(
|
|
|
|
|
'arg1: expected %?, got 3. Info: TEST_MSG',
|
|
|
|
|
pcall_err(exec_lua, "vim.validate('arg1', 3, function(a) return a == 1, 'TEST_MSG' end)")
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('vim.validate (spec form)', function()
|
2019-11-10 20:58:14 -07:00
|
|
|
|
exec_lua("vim.validate{arg1={{}, 'table' }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={{}, 't' }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={nil, 't', true }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={{ foo='foo' }, 't' }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={{ 'foo' }, 't' }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={'foo', 'string' }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={'foo', 's' }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={'', 's' }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={nil, 's', true }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={1, 'number' }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={1, 'n' }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={0, 'n' }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={0.1, 'n' }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={nil, 'n', true }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={true, 'boolean' }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={true, 'b' }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={false, 'b' }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={nil, 'b', true }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={function()end, 'function' }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={function()end, 'f' }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={nil, 'f', true }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={nil, 'nil' }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={nil, 'nil', true }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={coroutine.create(function()end), 'thread' }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={nil, 'thread', true }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={{}, 't' }, arg2={ 'foo', 's' }}")
|
|
|
|
|
exec_lua("vim.validate{arg1={2, function(a) return (a % 2) == 0 end, 'even number' }}")
|
2022-01-01 12:35:15 -07:00
|
|
|
|
exec_lua("vim.validate{arg1={5, {'n', 's'} }, arg2={ 'foo', {'n', 's'} }}")
|
2024-05-27 06:08:23 -07:00
|
|
|
|
|
2020-11-04 02:41:22 -07:00
|
|
|
|
matches('expected table, got number', pcall_err(exec_lua, "vim.validate{ 1, 'x' }"))
|
2024-10-18 03:33:12 -07:00
|
|
|
|
matches('arg1: expected x, got number', pcall_err(exec_lua, "vim.validate{ arg1={ 1, 'x' }}"))
|
|
|
|
|
matches('invalid validator: 1', pcall_err(exec_lua, 'vim.validate{ arg1={ 1, 1 }}'))
|
|
|
|
|
matches('invalid validator: nil', pcall_err(exec_lua, 'vim.validate{ arg1={ 1 }}'))
|
2019-11-10 20:58:14 -07:00
|
|
|
|
|
2019-11-10 23:18:59 -07:00
|
|
|
|
-- Validated parameters are required by default.
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches(
|
|
|
|
|
'arg1: expected string, got nil',
|
2020-11-04 02:41:22 -07:00
|
|
|
|
pcall_err(exec_lua, "vim.validate{ arg1={ nil, 's' }}")
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2019-11-10 23:18:59 -07:00
|
|
|
|
-- Explicitly required.
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches(
|
|
|
|
|
'arg1: expected string, got nil',
|
2020-11-04 02:41:22 -07:00
|
|
|
|
pcall_err(exec_lua, "vim.validate{ arg1={ nil, 's', false }}")
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
|
|
|
|
|
2020-11-04 02:41:22 -07:00
|
|
|
|
matches('arg1: expected table, got number', pcall_err(exec_lua, "vim.validate{arg1={1, 't'}}"))
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches(
|
|
|
|
|
'arg2: expected string, got number',
|
2020-11-04 02:41:22 -07:00
|
|
|
|
pcall_err(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={1, 's'}}")
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches(
|
|
|
|
|
'arg2: expected string, got nil',
|
2020-11-04 02:41:22 -07:00
|
|
|
|
pcall_err(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={nil, 's'}}")
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches(
|
|
|
|
|
'arg2: expected string, got nil',
|
2020-11-04 02:41:22 -07:00
|
|
|
|
pcall_err(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={nil, 's'}}")
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches(
|
|
|
|
|
'arg1: expected even number, got 3',
|
2020-11-04 02:41:22 -07:00
|
|
|
|
pcall_err(exec_lua, "vim.validate{arg1={3, function(a) return a == 1 end, 'even number'}}")
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches(
|
|
|
|
|
'arg1: expected %?, got 3',
|
2020-11-04 02:41:22 -07:00
|
|
|
|
pcall_err(exec_lua, 'vim.validate{arg1={3, function(a) return a == 1 end}}')
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2022-01-01 12:35:15 -07:00
|
|
|
|
matches(
|
|
|
|
|
'arg1: expected number|string, got nil',
|
|
|
|
|
pcall_err(exec_lua, "vim.validate{ arg1={ nil, {'n', 's'} }}")
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2020-09-12 19:04:22 -07:00
|
|
|
|
|
|
|
|
|
-- Pass an additional message back.
|
2021-12-16 09:27:39 -07:00
|
|
|
|
matches(
|
|
|
|
|
'arg1: expected %?, got 3. Info: TEST_MSG',
|
2020-11-04 02:41:22 -07:00
|
|
|
|
pcall_err(exec_lua, "vim.validate{arg1={3, function(a) return a == 1, 'TEST_MSG' end}}")
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2019-10-28 04:52:18 -07:00
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('vim.is_callable', function()
|
|
|
|
|
eq(true, exec_lua('return vim.is_callable(function()end)'))
|
|
|
|
|
eq(
|
|
|
|
|
true,
|
|
|
|
|
exec_lua([[
|
|
|
|
|
local meta = { __call = function()end }
|
|
|
|
|
local function new_callable()
|
|
|
|
|
return setmetatable({}, meta)
|
|
|
|
|
end
|
|
|
|
|
local callable = new_callable()
|
|
|
|
|
return vim.is_callable(callable)
|
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2019-10-28 04:52:18 -07:00
|
|
|
|
|
2024-07-03 15:36:00 -07:00
|
|
|
|
eq(
|
|
|
|
|
{ false, false },
|
|
|
|
|
exec_lua([[
|
|
|
|
|
local meta = { __call = {} }
|
|
|
|
|
assert(meta.__call)
|
|
|
|
|
local function new()
|
|
|
|
|
return setmetatable({}, meta)
|
|
|
|
|
end
|
|
|
|
|
local not_callable = new()
|
|
|
|
|
return { pcall(function() not_callable() end), vim.is_callable(not_callable) }
|
|
|
|
|
]])
|
|
|
|
|
)
|
|
|
|
|
eq(
|
|
|
|
|
{ false, false },
|
|
|
|
|
exec_lua([[
|
|
|
|
|
local function new()
|
|
|
|
|
return { __call = function()end }
|
|
|
|
|
end
|
|
|
|
|
local not_callable = new()
|
|
|
|
|
assert(not_callable.__call)
|
|
|
|
|
return { pcall(function() not_callable() end), vim.is_callable(not_callable) }
|
|
|
|
|
]])
|
|
|
|
|
)
|
|
|
|
|
eq(
|
|
|
|
|
{ false, false },
|
|
|
|
|
exec_lua([[
|
|
|
|
|
local meta = setmetatable(
|
|
|
|
|
{ __index = { __call = function() end } },
|
|
|
|
|
{ __index = { __call = function() end } }
|
|
|
|
|
)
|
|
|
|
|
assert(meta.__call)
|
|
|
|
|
local not_callable = setmetatable({}, meta)
|
|
|
|
|
assert(not_callable.__call)
|
|
|
|
|
return { pcall(function() not_callable() end), vim.is_callable(not_callable) }
|
|
|
|
|
]])
|
|
|
|
|
)
|
|
|
|
|
eq(
|
|
|
|
|
{ false, false },
|
|
|
|
|
exec_lua([[
|
|
|
|
|
local meta = setmetatable({
|
|
|
|
|
__index = function()
|
|
|
|
|
return function() end
|
|
|
|
|
end,
|
|
|
|
|
}, {
|
|
|
|
|
__index = function()
|
|
|
|
|
return function() end
|
|
|
|
|
end,
|
|
|
|
|
})
|
|
|
|
|
assert(meta.__call)
|
|
|
|
|
local not_callable = setmetatable({}, meta)
|
|
|
|
|
assert(not_callable.__call)
|
|
|
|
|
return { pcall(function() not_callable() end), vim.is_callable(not_callable) }
|
|
|
|
|
]])
|
|
|
|
|
)
|
2019-10-28 04:52:18 -07:00
|
|
|
|
eq(false, exec_lua('return vim.is_callable(1)'))
|
|
|
|
|
eq(false, exec_lua("return vim.is_callable('foo')"))
|
|
|
|
|
eq(false, exec_lua('return vim.is_callable({})'))
|
|
|
|
|
end)
|
Lua: vim.env, vim.{g,v,w,bo,wo} #11442
- Add vim variable meta accessors: vim.env, vim.{g,v,w,bo,wo}
- Redo gen_char_blob to generate multiple blobs instead of just one
so that multiple Lua modules can be inlined.
- Reorder vim.lua inclusion so that it can use previously defined C
functions and utility functions like vim.shared and vim.inspect things.
- Inline shared.lua into nvim, but also keep it available in runtime.
2019-11-24 03:28:48 -07:00
|
|
|
|
|
|
|
|
|
it('vim.g', function()
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.api.nvim_set_var("testing", "hi")
|
|
|
|
|
vim.api.nvim_set_var("other", 123)
|
2020-03-31 12:44:21 -07:00
|
|
|
|
vim.api.nvim_set_var("floaty", 5120.1)
|
|
|
|
|
vim.api.nvim_set_var("nullvar", vim.NIL)
|
2020-05-07 12:22:24 -07:00
|
|
|
|
vim.api.nvim_set_var("to_delete", {hello="world"})
|
Lua: vim.env, vim.{g,v,w,bo,wo} #11442
- Add vim variable meta accessors: vim.env, vim.{g,v,w,bo,wo}
- Redo gen_char_blob to generate multiple blobs instead of just one
so that multiple Lua modules can be inlined.
- Reorder vim.lua inclusion so that it can use previously defined C
functions and utility functions like vim.shared and vim.inspect things.
- Inline shared.lua into nvim, but also keep it available in runtime.
2019-11-24 03:28:48 -07:00
|
|
|
|
]]
|
2020-05-07 12:22:24 -07:00
|
|
|
|
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq('hi', fn.luaeval 'vim.g.testing')
|
|
|
|
|
eq(123, fn.luaeval 'vim.g.other')
|
|
|
|
|
eq(5120.1, fn.luaeval 'vim.g.floaty')
|
|
|
|
|
eq(NIL, fn.luaeval 'vim.g.nonexistent')
|
|
|
|
|
eq(NIL, fn.luaeval 'vim.g.nullvar')
|
2020-03-31 12:44:21 -07:00
|
|
|
|
-- lost over RPC, so test locally:
|
|
|
|
|
eq(
|
|
|
|
|
{ false, true },
|
|
|
|
|
exec_lua [[
|
2022-10-22 18:45:39 -07:00
|
|
|
|
return {vim.g.nonexistent == vim.NIL, vim.g.nullvar == vim.NIL}
|
2020-03-31 12:44:21 -07:00
|
|
|
|
]]
|
|
|
|
|
)
|
2020-05-07 12:22:24 -07:00
|
|
|
|
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq({ hello = 'world' }, fn.luaeval 'vim.g.to_delete')
|
2020-05-07 12:22:24 -07:00
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.g.to_delete = nil
|
|
|
|
|
]]
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(NIL, fn.luaeval 'vim.g.to_delete')
|
2021-09-23 07:00:25 -07:00
|
|
|
|
|
|
|
|
|
matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.g[0].testing'))
|
2022-01-08 18:02:02 -07:00
|
|
|
|
|
|
|
|
|
exec_lua [[
|
|
|
|
|
local counter = 0
|
2022-03-17 12:21:47 -07:00
|
|
|
|
local function add_counter() counter = counter + 1 end
|
|
|
|
|
local function get_counter() return counter end
|
|
|
|
|
vim.g.AddCounter = add_counter
|
|
|
|
|
vim.g.GetCounter = get_counter
|
2024-01-12 10:59:57 -07:00
|
|
|
|
vim.g.fn = {add = add_counter, get = get_counter}
|
2022-09-16 08:09:26 -07:00
|
|
|
|
vim.g.AddParens = function(s) return '(' .. s .. ')' end
|
2022-01-08 18:02:02 -07:00
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq(0, eval('g:GetCounter()'))
|
|
|
|
|
eval('g:AddCounter()')
|
|
|
|
|
eq(1, eval('g:GetCounter()'))
|
|
|
|
|
eval('g:AddCounter()')
|
|
|
|
|
eq(2, eval('g:GetCounter()'))
|
|
|
|
|
exec_lua([[vim.g.AddCounter()]])
|
|
|
|
|
eq(3, exec_lua([[return vim.g.GetCounter()]]))
|
|
|
|
|
exec_lua([[vim.api.nvim_get_var('AddCounter')()]])
|
|
|
|
|
eq(4, exec_lua([[return vim.api.nvim_get_var('GetCounter')()]]))
|
2024-01-12 10:59:57 -07:00
|
|
|
|
exec_lua([[vim.g.fn.add()]])
|
|
|
|
|
eq(5, exec_lua([[return vim.g.fn.get()]]))
|
|
|
|
|
exec_lua([[vim.api.nvim_get_var('fn').add()]])
|
|
|
|
|
eq(6, exec_lua([[return vim.api.nvim_get_var('fn').get()]]))
|
2022-09-16 08:09:26 -07:00
|
|
|
|
eq('((foo))', eval([['foo'->AddParens()->AddParens()]]))
|
2022-01-08 18:02:02 -07:00
|
|
|
|
|
|
|
|
|
exec_lua [[
|
|
|
|
|
local counter = 0
|
2022-03-17 12:21:47 -07:00
|
|
|
|
local function add_counter() counter = counter + 1 end
|
|
|
|
|
local function get_counter() return counter end
|
|
|
|
|
vim.api.nvim_set_var('AddCounter', add_counter)
|
|
|
|
|
vim.api.nvim_set_var('GetCounter', get_counter)
|
2024-01-12 10:59:57 -07:00
|
|
|
|
vim.api.nvim_set_var('fn', {add = add_counter, get = get_counter})
|
2022-09-16 08:09:26 -07:00
|
|
|
|
vim.api.nvim_set_var('AddParens', function(s) return '(' .. s .. ')' end)
|
2022-01-08 18:02:02 -07:00
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq(0, eval('g:GetCounter()'))
|
|
|
|
|
eval('g:AddCounter()')
|
|
|
|
|
eq(1, eval('g:GetCounter()'))
|
|
|
|
|
eval('g:AddCounter()')
|
|
|
|
|
eq(2, eval('g:GetCounter()'))
|
|
|
|
|
exec_lua([[vim.g.AddCounter()]])
|
|
|
|
|
eq(3, exec_lua([[return vim.g.GetCounter()]]))
|
|
|
|
|
exec_lua([[vim.api.nvim_get_var('AddCounter')()]])
|
|
|
|
|
eq(4, exec_lua([[return vim.api.nvim_get_var('GetCounter')()]]))
|
2024-01-12 10:59:57 -07:00
|
|
|
|
exec_lua([[vim.g.fn.add()]])
|
|
|
|
|
eq(5, exec_lua([[return vim.g.fn.get()]]))
|
|
|
|
|
exec_lua([[vim.api.nvim_get_var('fn').add()]])
|
|
|
|
|
eq(6, exec_lua([[return vim.api.nvim_get_var('fn').get()]]))
|
2022-09-16 08:09:26 -07:00
|
|
|
|
eq('((foo))', eval([['foo'->AddParens()->AddParens()]]))
|
2022-02-11 21:54:25 -07:00
|
|
|
|
|
2022-03-19 17:08:50 -07:00
|
|
|
|
exec([[
|
|
|
|
|
function Test()
|
|
|
|
|
endfunction
|
|
|
|
|
function s:Test()
|
|
|
|
|
endfunction
|
|
|
|
|
let g:Unknown_func = function('Test')
|
|
|
|
|
let g:Unknown_script_func = function('s:Test')
|
|
|
|
|
]])
|
|
|
|
|
eq(NIL, exec_lua([[return vim.g.Unknown_func]]))
|
|
|
|
|
eq(NIL, exec_lua([[return vim.g.Unknown_script_func]]))
|
|
|
|
|
|
2022-02-11 21:54:25 -07:00
|
|
|
|
-- Check if autoload works properly
|
2024-04-20 08:44:13 -07:00
|
|
|
|
local pathsep = n.get_pathsep()
|
2022-02-11 21:54:25 -07:00
|
|
|
|
local xconfig = 'Xhome' .. pathsep .. 'Xconfig'
|
|
|
|
|
local xdata = 'Xhome' .. pathsep .. 'Xdata'
|
|
|
|
|
local autoload_folder = table.concat({ xconfig, 'nvim', 'autoload' }, pathsep)
|
|
|
|
|
local autoload_file = table.concat({ autoload_folder, 'testload.vim' }, pathsep)
|
|
|
|
|
mkdir_p(autoload_folder)
|
|
|
|
|
write_file(autoload_file, [[let testload#value = 2]])
|
|
|
|
|
|
|
|
|
|
clear { args_rm = { '-u' }, env = { XDG_CONFIG_HOME = xconfig, XDG_DATA_HOME = xdata } }
|
|
|
|
|
|
|
|
|
|
eq(2, exec_lua("return vim.g['testload#value']"))
|
|
|
|
|
rmdir('Xhome')
|
2020-05-07 12:22:24 -07:00
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('vim.b', function()
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.api.nvim_buf_set_var(0, "testing", "hi")
|
|
|
|
|
vim.api.nvim_buf_set_var(0, "other", 123)
|
2020-03-31 12:44:21 -07:00
|
|
|
|
vim.api.nvim_buf_set_var(0, "floaty", 5120.1)
|
|
|
|
|
vim.api.nvim_buf_set_var(0, "nullvar", vim.NIL)
|
2020-05-07 12:22:24 -07:00
|
|
|
|
vim.api.nvim_buf_set_var(0, "to_delete", {hello="world"})
|
2021-09-23 07:00:25 -07:00
|
|
|
|
BUF = vim.api.nvim_create_buf(false, true)
|
|
|
|
|
vim.api.nvim_buf_set_var(BUF, "testing", "bye")
|
2020-05-07 12:22:24 -07:00
|
|
|
|
]]
|
|
|
|
|
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq('hi', fn.luaeval 'vim.b.testing')
|
|
|
|
|
eq('bye', fn.luaeval 'vim.b[BUF].testing')
|
|
|
|
|
eq(123, fn.luaeval 'vim.b.other')
|
|
|
|
|
eq(5120.1, fn.luaeval 'vim.b.floaty')
|
|
|
|
|
eq(NIL, fn.luaeval 'vim.b.nonexistent')
|
|
|
|
|
eq(NIL, fn.luaeval 'vim.b[BUF].nonexistent')
|
|
|
|
|
eq(NIL, fn.luaeval 'vim.b.nullvar')
|
2020-03-31 12:44:21 -07:00
|
|
|
|
-- lost over RPC, so test locally:
|
|
|
|
|
eq(
|
|
|
|
|
{ false, true },
|
|
|
|
|
exec_lua [[
|
2022-10-22 18:45:39 -07:00
|
|
|
|
return {vim.b.nonexistent == vim.NIL, vim.b.nullvar == vim.NIL}
|
2020-03-31 12:44:21 -07:00
|
|
|
|
]]
|
|
|
|
|
)
|
2020-05-07 12:22:24 -07:00
|
|
|
|
|
2021-09-23 07:00:25 -07:00
|
|
|
|
matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.b[BUF][0].testing'))
|
|
|
|
|
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq({ hello = 'world' }, fn.luaeval 'vim.b.to_delete')
|
2020-05-07 12:22:24 -07:00
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.b.to_delete = nil
|
|
|
|
|
]]
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(NIL, fn.luaeval 'vim.b.to_delete')
|
2020-05-07 12:22:24 -07:00
|
|
|
|
|
2022-01-08 18:02:02 -07:00
|
|
|
|
exec_lua [[
|
|
|
|
|
local counter = 0
|
2022-03-17 12:21:47 -07:00
|
|
|
|
local function add_counter() counter = counter + 1 end
|
|
|
|
|
local function get_counter() return counter end
|
|
|
|
|
vim.b.AddCounter = add_counter
|
|
|
|
|
vim.b.GetCounter = get_counter
|
2024-01-12 10:59:57 -07:00
|
|
|
|
vim.b.fn = {add = add_counter, get = get_counter}
|
2022-09-16 08:09:26 -07:00
|
|
|
|
vim.b.AddParens = function(s) return '(' .. s .. ')' end
|
2022-01-08 18:02:02 -07:00
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq(0, eval('b:GetCounter()'))
|
|
|
|
|
eval('b:AddCounter()')
|
|
|
|
|
eq(1, eval('b:GetCounter()'))
|
|
|
|
|
eval('b:AddCounter()')
|
|
|
|
|
eq(2, eval('b:GetCounter()'))
|
|
|
|
|
exec_lua([[vim.b.AddCounter()]])
|
|
|
|
|
eq(3, exec_lua([[return vim.b.GetCounter()]]))
|
|
|
|
|
exec_lua([[vim.api.nvim_buf_get_var(0, 'AddCounter')()]])
|
|
|
|
|
eq(4, exec_lua([[return vim.api.nvim_buf_get_var(0, 'GetCounter')()]]))
|
2024-01-12 10:59:57 -07:00
|
|
|
|
exec_lua([[vim.b.fn.add()]])
|
|
|
|
|
eq(5, exec_lua([[return vim.b.fn.get()]]))
|
|
|
|
|
exec_lua([[vim.api.nvim_buf_get_var(0, 'fn').add()]])
|
|
|
|
|
eq(6, exec_lua([[return vim.api.nvim_buf_get_var(0, 'fn').get()]]))
|
2022-09-16 08:09:26 -07:00
|
|
|
|
eq('((foo))', eval([['foo'->b:AddParens()->b:AddParens()]]))
|
2022-01-08 18:02:02 -07:00
|
|
|
|
|
|
|
|
|
exec_lua [[
|
|
|
|
|
local counter = 0
|
2022-03-17 12:21:47 -07:00
|
|
|
|
local function add_counter() counter = counter + 1 end
|
|
|
|
|
local function get_counter() return counter end
|
|
|
|
|
vim.api.nvim_buf_set_var(0, 'AddCounter', add_counter)
|
|
|
|
|
vim.api.nvim_buf_set_var(0, 'GetCounter', get_counter)
|
2024-01-12 10:59:57 -07:00
|
|
|
|
vim.api.nvim_buf_set_var(0, 'fn', {add = add_counter, get = get_counter})
|
2022-09-16 08:09:26 -07:00
|
|
|
|
vim.api.nvim_buf_set_var(0, 'AddParens', function(s) return '(' .. s .. ')' end)
|
2022-01-08 18:02:02 -07:00
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq(0, eval('b:GetCounter()'))
|
|
|
|
|
eval('b:AddCounter()')
|
|
|
|
|
eq(1, eval('b:GetCounter()'))
|
|
|
|
|
eval('b:AddCounter()')
|
|
|
|
|
eq(2, eval('b:GetCounter()'))
|
|
|
|
|
exec_lua([[vim.b.AddCounter()]])
|
|
|
|
|
eq(3, exec_lua([[return vim.b.GetCounter()]]))
|
|
|
|
|
exec_lua([[vim.api.nvim_buf_get_var(0, 'AddCounter')()]])
|
|
|
|
|
eq(4, exec_lua([[return vim.api.nvim_buf_get_var(0, 'GetCounter')()]]))
|
2024-01-12 10:59:57 -07:00
|
|
|
|
exec_lua([[vim.b.fn.add()]])
|
|
|
|
|
eq(5, exec_lua([[return vim.b.fn.get()]]))
|
|
|
|
|
exec_lua([[vim.api.nvim_buf_get_var(0, 'fn').add()]])
|
|
|
|
|
eq(6, exec_lua([[return vim.api.nvim_buf_get_var(0, 'fn').get()]]))
|
2022-09-16 08:09:26 -07:00
|
|
|
|
eq('((foo))', eval([['foo'->b:AddParens()->b:AddParens()]]))
|
2022-01-08 18:02:02 -07:00
|
|
|
|
|
2022-03-19 17:08:50 -07:00
|
|
|
|
exec([[
|
|
|
|
|
function Test()
|
|
|
|
|
endfunction
|
|
|
|
|
function s:Test()
|
|
|
|
|
endfunction
|
|
|
|
|
let b:Unknown_func = function('Test')
|
|
|
|
|
let b:Unknown_script_func = function('s:Test')
|
|
|
|
|
]])
|
|
|
|
|
eq(NIL, exec_lua([[return vim.b.Unknown_func]]))
|
|
|
|
|
eq(NIL, exec_lua([[return vim.b.Unknown_script_func]]))
|
|
|
|
|
|
2020-05-07 12:22:24 -07:00
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.cmd "vnew"
|
|
|
|
|
]]
|
|
|
|
|
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(NIL, fn.luaeval 'vim.b.testing')
|
|
|
|
|
eq(NIL, fn.luaeval 'vim.b.other')
|
|
|
|
|
eq(NIL, fn.luaeval 'vim.b.nonexistent')
|
2020-05-07 12:22:24 -07:00
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('vim.w', function()
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.api.nvim_win_set_var(0, "testing", "hi")
|
|
|
|
|
vim.api.nvim_win_set_var(0, "other", 123)
|
|
|
|
|
vim.api.nvim_win_set_var(0, "to_delete", {hello="world"})
|
2021-09-23 07:00:25 -07:00
|
|
|
|
BUF = vim.api.nvim_create_buf(false, true)
|
|
|
|
|
WIN = vim.api.nvim_open_win(BUF, false, {
|
|
|
|
|
width=10, height=10,
|
|
|
|
|
relative='win', row=0, col=0
|
|
|
|
|
})
|
|
|
|
|
vim.api.nvim_win_set_var(WIN, "testing", "bye")
|
2020-05-07 12:22:24 -07:00
|
|
|
|
]]
|
|
|
|
|
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq('hi', fn.luaeval 'vim.w.testing')
|
|
|
|
|
eq('bye', fn.luaeval 'vim.w[WIN].testing')
|
|
|
|
|
eq(123, fn.luaeval 'vim.w.other')
|
|
|
|
|
eq(NIL, fn.luaeval 'vim.w.nonexistent')
|
|
|
|
|
eq(NIL, fn.luaeval 'vim.w[WIN].nonexistent')
|
2021-09-23 07:00:25 -07:00
|
|
|
|
|
|
|
|
|
matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.w[WIN][0].testing'))
|
2020-05-07 12:22:24 -07:00
|
|
|
|
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq({ hello = 'world' }, fn.luaeval 'vim.w.to_delete')
|
2020-05-07 12:22:24 -07:00
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.w.to_delete = nil
|
|
|
|
|
]]
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(NIL, fn.luaeval 'vim.w.to_delete')
|
2020-05-07 12:22:24 -07:00
|
|
|
|
|
2022-01-08 18:02:02 -07:00
|
|
|
|
exec_lua [[
|
|
|
|
|
local counter = 0
|
2022-03-17 12:21:47 -07:00
|
|
|
|
local function add_counter() counter = counter + 1 end
|
|
|
|
|
local function get_counter() return counter end
|
|
|
|
|
vim.w.AddCounter = add_counter
|
|
|
|
|
vim.w.GetCounter = get_counter
|
2024-01-12 10:59:57 -07:00
|
|
|
|
vim.w.fn = {add = add_counter, get = get_counter}
|
2022-09-16 08:09:26 -07:00
|
|
|
|
vim.w.AddParens = function(s) return '(' .. s .. ')' end
|
2022-01-08 18:02:02 -07:00
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq(0, eval('w:GetCounter()'))
|
|
|
|
|
eval('w:AddCounter()')
|
|
|
|
|
eq(1, eval('w:GetCounter()'))
|
|
|
|
|
eval('w:AddCounter()')
|
|
|
|
|
eq(2, eval('w:GetCounter()'))
|
|
|
|
|
exec_lua([[vim.w.AddCounter()]])
|
|
|
|
|
eq(3, exec_lua([[return vim.w.GetCounter()]]))
|
|
|
|
|
exec_lua([[vim.api.nvim_win_get_var(0, 'AddCounter')()]])
|
|
|
|
|
eq(4, exec_lua([[return vim.api.nvim_win_get_var(0, 'GetCounter')()]]))
|
2024-01-12 10:59:57 -07:00
|
|
|
|
exec_lua([[vim.w.fn.add()]])
|
|
|
|
|
eq(5, exec_lua([[return vim.w.fn.get()]]))
|
|
|
|
|
exec_lua([[vim.api.nvim_win_get_var(0, 'fn').add()]])
|
|
|
|
|
eq(6, exec_lua([[return vim.api.nvim_win_get_var(0, 'fn').get()]]))
|
2022-09-16 08:09:26 -07:00
|
|
|
|
eq('((foo))', eval([['foo'->w:AddParens()->w:AddParens()]]))
|
2022-01-08 18:02:02 -07:00
|
|
|
|
|
|
|
|
|
exec_lua [[
|
|
|
|
|
local counter = 0
|
2022-03-17 12:21:47 -07:00
|
|
|
|
local function add_counter() counter = counter + 1 end
|
|
|
|
|
local function get_counter() return counter end
|
|
|
|
|
vim.api.nvim_win_set_var(0, 'AddCounter', add_counter)
|
|
|
|
|
vim.api.nvim_win_set_var(0, 'GetCounter', get_counter)
|
2024-01-12 10:59:57 -07:00
|
|
|
|
vim.api.nvim_win_set_var(0, 'fn', {add = add_counter, get = get_counter})
|
2022-09-16 08:09:26 -07:00
|
|
|
|
vim.api.nvim_win_set_var(0, 'AddParens', function(s) return '(' .. s .. ')' end)
|
2022-01-08 18:02:02 -07:00
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq(0, eval('w:GetCounter()'))
|
|
|
|
|
eval('w:AddCounter()')
|
|
|
|
|
eq(1, eval('w:GetCounter()'))
|
|
|
|
|
eval('w:AddCounter()')
|
|
|
|
|
eq(2, eval('w:GetCounter()'))
|
|
|
|
|
exec_lua([[vim.w.AddCounter()]])
|
|
|
|
|
eq(3, exec_lua([[return vim.w.GetCounter()]]))
|
|
|
|
|
exec_lua([[vim.api.nvim_win_get_var(0, 'AddCounter')()]])
|
|
|
|
|
eq(4, exec_lua([[return vim.api.nvim_win_get_var(0, 'GetCounter')()]]))
|
2024-01-12 10:59:57 -07:00
|
|
|
|
exec_lua([[vim.w.fn.add()]])
|
|
|
|
|
eq(5, exec_lua([[return vim.w.fn.get()]]))
|
|
|
|
|
exec_lua([[vim.api.nvim_win_get_var(0, 'fn').add()]])
|
|
|
|
|
eq(6, exec_lua([[return vim.api.nvim_win_get_var(0, 'fn').get()]]))
|
2022-09-16 08:09:26 -07:00
|
|
|
|
eq('((foo))', eval([['foo'->w:AddParens()->w:AddParens()]]))
|
2022-01-08 18:02:02 -07:00
|
|
|
|
|
2022-03-19 17:08:50 -07:00
|
|
|
|
exec([[
|
|
|
|
|
function Test()
|
|
|
|
|
endfunction
|
|
|
|
|
function s:Test()
|
|
|
|
|
endfunction
|
|
|
|
|
let w:Unknown_func = function('Test')
|
|
|
|
|
let w:Unknown_script_func = function('s:Test')
|
|
|
|
|
]])
|
|
|
|
|
eq(NIL, exec_lua([[return vim.w.Unknown_func]]))
|
|
|
|
|
eq(NIL, exec_lua([[return vim.w.Unknown_script_func]]))
|
|
|
|
|
|
2020-05-07 12:22:24 -07:00
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.cmd "vnew"
|
|
|
|
|
]]
|
|
|
|
|
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(NIL, fn.luaeval 'vim.w.testing')
|
|
|
|
|
eq(NIL, fn.luaeval 'vim.w.other')
|
|
|
|
|
eq(NIL, fn.luaeval 'vim.w.nonexistent')
|
2020-05-07 12:22:24 -07:00
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('vim.t', function()
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.api.nvim_tabpage_set_var(0, "testing", "hi")
|
|
|
|
|
vim.api.nvim_tabpage_set_var(0, "other", 123)
|
|
|
|
|
vim.api.nvim_tabpage_set_var(0, "to_delete", {hello="world"})
|
|
|
|
|
]]
|
|
|
|
|
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq('hi', fn.luaeval 'vim.t.testing')
|
|
|
|
|
eq(123, fn.luaeval 'vim.t.other')
|
|
|
|
|
eq(NIL, fn.luaeval 'vim.t.nonexistent')
|
|
|
|
|
eq('hi', fn.luaeval 'vim.t[0].testing')
|
|
|
|
|
eq(123, fn.luaeval 'vim.t[0].other')
|
|
|
|
|
eq(NIL, fn.luaeval 'vim.t[0].nonexistent')
|
2021-09-23 07:00:25 -07:00
|
|
|
|
|
|
|
|
|
matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.t[0][0].testing'))
|
2020-05-07 12:22:24 -07:00
|
|
|
|
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq({ hello = 'world' }, fn.luaeval 'vim.t.to_delete')
|
2020-05-07 12:22:24 -07:00
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.t.to_delete = nil
|
|
|
|
|
]]
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(NIL, fn.luaeval 'vim.t.to_delete')
|
2020-05-07 12:22:24 -07:00
|
|
|
|
|
2022-01-08 18:02:02 -07:00
|
|
|
|
exec_lua [[
|
|
|
|
|
local counter = 0
|
2022-03-17 12:21:47 -07:00
|
|
|
|
local function add_counter() counter = counter + 1 end
|
|
|
|
|
local function get_counter() return counter end
|
|
|
|
|
vim.t.AddCounter = add_counter
|
|
|
|
|
vim.t.GetCounter = get_counter
|
2024-01-12 10:59:57 -07:00
|
|
|
|
vim.t.fn = {add = add_counter, get = get_counter}
|
2022-09-16 08:09:26 -07:00
|
|
|
|
vim.t.AddParens = function(s) return '(' .. s .. ')' end
|
2022-01-08 18:02:02 -07:00
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq(0, eval('t:GetCounter()'))
|
|
|
|
|
eval('t:AddCounter()')
|
|
|
|
|
eq(1, eval('t:GetCounter()'))
|
|
|
|
|
eval('t:AddCounter()')
|
|
|
|
|
eq(2, eval('t:GetCounter()'))
|
|
|
|
|
exec_lua([[vim.t.AddCounter()]])
|
|
|
|
|
eq(3, exec_lua([[return vim.t.GetCounter()]]))
|
|
|
|
|
exec_lua([[vim.api.nvim_tabpage_get_var(0, 'AddCounter')()]])
|
|
|
|
|
eq(4, exec_lua([[return vim.api.nvim_tabpage_get_var(0, 'GetCounter')()]]))
|
2024-01-12 10:59:57 -07:00
|
|
|
|
exec_lua([[vim.t.fn.add()]])
|
|
|
|
|
eq(5, exec_lua([[return vim.t.fn.get()]]))
|
|
|
|
|
exec_lua([[vim.api.nvim_tabpage_get_var(0, 'fn').add()]])
|
|
|
|
|
eq(6, exec_lua([[return vim.api.nvim_tabpage_get_var(0, 'fn').get()]]))
|
2022-09-16 08:09:26 -07:00
|
|
|
|
eq('((foo))', eval([['foo'->t:AddParens()->t:AddParens()]]))
|
2022-01-08 18:02:02 -07:00
|
|
|
|
|
|
|
|
|
exec_lua [[
|
|
|
|
|
local counter = 0
|
2022-03-17 12:21:47 -07:00
|
|
|
|
local function add_counter() counter = counter + 1 end
|
|
|
|
|
local function get_counter() return counter end
|
|
|
|
|
vim.api.nvim_tabpage_set_var(0, 'AddCounter', add_counter)
|
|
|
|
|
vim.api.nvim_tabpage_set_var(0, 'GetCounter', get_counter)
|
2024-01-12 10:59:57 -07:00
|
|
|
|
vim.api.nvim_tabpage_set_var(0, 'fn', {add = add_counter, get = get_counter})
|
2022-09-16 08:09:26 -07:00
|
|
|
|
vim.api.nvim_tabpage_set_var(0, 'AddParens', function(s) return '(' .. s .. ')' end)
|
2022-01-08 18:02:02 -07:00
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq(0, eval('t:GetCounter()'))
|
|
|
|
|
eval('t:AddCounter()')
|
|
|
|
|
eq(1, eval('t:GetCounter()'))
|
|
|
|
|
eval('t:AddCounter()')
|
|
|
|
|
eq(2, eval('t:GetCounter()'))
|
|
|
|
|
exec_lua([[vim.t.AddCounter()]])
|
|
|
|
|
eq(3, exec_lua([[return vim.t.GetCounter()]]))
|
|
|
|
|
exec_lua([[vim.api.nvim_tabpage_get_var(0, 'AddCounter')()]])
|
|
|
|
|
eq(4, exec_lua([[return vim.api.nvim_tabpage_get_var(0, 'GetCounter')()]]))
|
2024-01-12 10:59:57 -07:00
|
|
|
|
exec_lua([[vim.t.fn.add()]])
|
|
|
|
|
eq(5, exec_lua([[return vim.t.fn.get()]]))
|
|
|
|
|
exec_lua([[vim.api.nvim_tabpage_get_var(0, 'fn').add()]])
|
|
|
|
|
eq(6, exec_lua([[return vim.api.nvim_tabpage_get_var(0, 'fn').get()]]))
|
2022-09-16 08:09:26 -07:00
|
|
|
|
eq('((foo))', eval([['foo'->t:AddParens()->t:AddParens()]]))
|
2022-01-08 18:02:02 -07:00
|
|
|
|
|
2020-05-07 12:22:24 -07:00
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.cmd "tabnew"
|
|
|
|
|
]]
|
|
|
|
|
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(NIL, fn.luaeval 'vim.t.testing')
|
|
|
|
|
eq(NIL, fn.luaeval 'vim.t.other')
|
|
|
|
|
eq(NIL, fn.luaeval 'vim.t.nonexistent')
|
Lua: vim.env, vim.{g,v,w,bo,wo} #11442
- Add vim variable meta accessors: vim.env, vim.{g,v,w,bo,wo}
- Redo gen_char_blob to generate multiple blobs instead of just one
so that multiple Lua modules can be inlined.
- Reorder vim.lua inclusion so that it can use previously defined C
functions and utility functions like vim.shared and vim.inspect things.
- Inline shared.lua into nvim, but also keep it available in runtime.
2019-11-24 03:28:48 -07:00
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('vim.env', function()
|
2022-09-28 17:56:00 -07:00
|
|
|
|
exec_lua([[vim.fn.setenv('A', 123)]])
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq('123', fn.luaeval('vim.env.A'))
|
2022-09-28 17:56:00 -07:00
|
|
|
|
exec_lua([[vim.env.A = 456]])
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq('456', fn.luaeval('vim.env.A'))
|
2022-09-28 17:56:00 -07:00
|
|
|
|
exec_lua([[vim.env.A = nil]])
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(NIL, fn.luaeval('vim.env.A'))
|
2022-09-28 17:56:00 -07:00
|
|
|
|
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(true, fn.luaeval('vim.env.B == nil'))
|
2022-09-28 17:56:00 -07:00
|
|
|
|
|
|
|
|
|
command([[let $HOME = 'foo']])
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq('foo', fn.expand('~'))
|
|
|
|
|
eq('foo', fn.luaeval('vim.env.HOME'))
|
2022-09-28 17:56:00 -07:00
|
|
|
|
exec_lua([[vim.env.HOME = nil]])
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq('foo', fn.expand('~'))
|
2022-09-28 17:56:00 -07:00
|
|
|
|
exec_lua([[vim.env.HOME = 'bar']])
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq('bar', fn.expand('~'))
|
|
|
|
|
eq('bar', fn.luaeval('vim.env.HOME'))
|
Lua: vim.env, vim.{g,v,w,bo,wo} #11442
- Add vim variable meta accessors: vim.env, vim.{g,v,w,bo,wo}
- Redo gen_char_blob to generate multiple blobs instead of just one
so that multiple Lua modules can be inlined.
- Reorder vim.lua inclusion so that it can use previously defined C
functions and utility functions like vim.shared and vim.inspect things.
- Inline shared.lua into nvim, but also keep it available in runtime.
2019-11-24 03:28:48 -07:00
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('vim.v', function()
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(fn.luaeval "vim.api.nvim_get_vvar('progpath')", fn.luaeval 'vim.v.progpath')
|
|
|
|
|
eq(false, fn.luaeval "vim.v['false']")
|
|
|
|
|
eq(NIL, fn.luaeval 'vim.v.null')
|
2021-09-23 07:00:25 -07:00
|
|
|
|
matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.v[0].progpath'))
|
2023-09-23 19:57:09 -07:00
|
|
|
|
eq('Key is read-only: count', pcall_err(exec_lua, [[vim.v.count = 42]]))
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
eq('Dict is locked', pcall_err(exec_lua, [[vim.v.nosuchvar = 42]]))
|
2023-09-23 19:57:09 -07:00
|
|
|
|
eq('Key is fixed: errmsg', pcall_err(exec_lua, [[vim.v.errmsg = nil]]))
|
|
|
|
|
exec_lua([[vim.v.errmsg = 'set by Lua']])
|
|
|
|
|
eq('set by Lua', eval('v:errmsg'))
|
|
|
|
|
exec_lua([[vim.v.errmsg = 42]])
|
|
|
|
|
eq('42', eval('v:errmsg'))
|
|
|
|
|
exec_lua([[vim.v.oldfiles = { 'one', 'two' }]])
|
|
|
|
|
eq({ 'one', 'two' }, eval('v:oldfiles'))
|
|
|
|
|
exec_lua([[vim.v.oldfiles = {}]])
|
|
|
|
|
eq({}, eval('v:oldfiles'))
|
|
|
|
|
eq('Setting v:oldfiles to value with wrong type', pcall_err(exec_lua, [[vim.v.oldfiles = 'a']]))
|
|
|
|
|
eq({}, eval('v:oldfiles'))
|
|
|
|
|
|
|
|
|
|
feed('i foo foo foo<Esc>0/foo<CR>')
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq({ 1, 1 }, api.nvim_win_get_cursor(0))
|
2023-09-23 19:57:09 -07:00
|
|
|
|
eq(1, eval('v:searchforward'))
|
|
|
|
|
feed('n')
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq({ 1, 5 }, api.nvim_win_get_cursor(0))
|
2023-09-23 19:57:09 -07:00
|
|
|
|
exec_lua([[vim.v.searchforward = 0]])
|
|
|
|
|
eq(0, eval('v:searchforward'))
|
|
|
|
|
feed('n')
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq({ 1, 1 }, api.nvim_win_get_cursor(0))
|
2023-09-23 19:57:09 -07:00
|
|
|
|
exec_lua([[vim.v.searchforward = 1]])
|
|
|
|
|
eq(1, eval('v:searchforward'))
|
|
|
|
|
feed('n')
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq({ 1, 5 }, api.nvim_win_get_cursor(0))
|
2023-09-23 19:57:09 -07:00
|
|
|
|
|
|
|
|
|
local screen = Screen.new(60, 3)
|
|
|
|
|
eq(1, eval('v:hlsearch'))
|
|
|
|
|
screen:expect {
|
|
|
|
|
grid = [[
|
2024-08-14 04:42:05 -07:00
|
|
|
|
{10:foo} {10:^foo} {10:foo} |
|
|
|
|
|
{1:~ }|
|
2023-09-23 19:57:09 -07:00
|
|
|
|
|
|
|
|
|
|
]],
|
|
|
|
|
}
|
|
|
|
|
exec_lua([[vim.v.hlsearch = 0]])
|
|
|
|
|
eq(0, eval('v:hlsearch'))
|
|
|
|
|
screen:expect {
|
|
|
|
|
grid = [[
|
|
|
|
|
foo ^foo foo |
|
2024-08-14 04:42:05 -07:00
|
|
|
|
{1:~ }|
|
2023-09-23 19:57:09 -07:00
|
|
|
|
|
|
|
|
|
|
]],
|
|
|
|
|
}
|
|
|
|
|
exec_lua([[vim.v.hlsearch = 1]])
|
|
|
|
|
eq(1, eval('v:hlsearch'))
|
|
|
|
|
screen:expect {
|
|
|
|
|
grid = [[
|
2024-08-14 04:42:05 -07:00
|
|
|
|
{10:foo} {10:^foo} {10:foo} |
|
|
|
|
|
{1:~ }|
|
2023-09-23 19:57:09 -07:00
|
|
|
|
|
|
|
|
|
|
]],
|
|
|
|
|
}
|
Lua: vim.env, vim.{g,v,w,bo,wo} #11442
- Add vim variable meta accessors: vim.env, vim.{g,v,w,bo,wo}
- Redo gen_char_blob to generate multiple blobs instead of just one
so that multiple Lua modules can be inlined.
- Reorder vim.lua inclusion so that it can use previously defined C
functions and utility functions like vim.shared and vim.inspect things.
- Inline shared.lua into nvim, but also keep it available in runtime.
2019-11-24 03:28:48 -07:00
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('vim.bo', function()
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq('', fn.luaeval 'vim.bo.filetype')
|
Lua: vim.env, vim.{g,v,w,bo,wo} #11442
- Add vim variable meta accessors: vim.env, vim.{g,v,w,bo,wo}
- Redo gen_char_blob to generate multiple blobs instead of just one
so that multiple Lua modules can be inlined.
- Reorder vim.lua inclusion so that it can use previously defined C
functions and utility functions like vim.shared and vim.inspect things.
- Inline shared.lua into nvim, but also keep it available in runtime.
2019-11-24 03:28:48 -07:00
|
|
|
|
exec_lua [[
|
2023-05-21 23:47:10 -07:00
|
|
|
|
vim.api.nvim_set_option_value("filetype", "markdown", {})
|
Lua: vim.env, vim.{g,v,w,bo,wo} #11442
- Add vim variable meta accessors: vim.env, vim.{g,v,w,bo,wo}
- Redo gen_char_blob to generate multiple blobs instead of just one
so that multiple Lua modules can be inlined.
- Reorder vim.lua inclusion so that it can use previously defined C
functions and utility functions like vim.shared and vim.inspect things.
- Inline shared.lua into nvim, but also keep it available in runtime.
2019-11-24 03:28:48 -07:00
|
|
|
|
BUF = vim.api.nvim_create_buf(false, true)
|
2022-12-19 09:37:45 -07:00
|
|
|
|
vim.api.nvim_set_option_value("modifiable", false, {buf = BUF})
|
Lua: vim.env, vim.{g,v,w,bo,wo} #11442
- Add vim variable meta accessors: vim.env, vim.{g,v,w,bo,wo}
- Redo gen_char_blob to generate multiple blobs instead of just one
so that multiple Lua modules can be inlined.
- Reorder vim.lua inclusion so that it can use previously defined C
functions and utility functions like vim.shared and vim.inspect things.
- Inline shared.lua into nvim, but also keep it available in runtime.
2019-11-24 03:28:48 -07:00
|
|
|
|
]]
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(false, fn.luaeval 'vim.bo.modified')
|
|
|
|
|
eq('markdown', fn.luaeval 'vim.bo.filetype')
|
|
|
|
|
eq(false, fn.luaeval 'vim.bo[BUF].modifiable')
|
Lua: vim.env, vim.{g,v,w,bo,wo} #11442
- Add vim variable meta accessors: vim.env, vim.{g,v,w,bo,wo}
- Redo gen_char_blob to generate multiple blobs instead of just one
so that multiple Lua modules can be inlined.
- Reorder vim.lua inclusion so that it can use previously defined C
functions and utility functions like vim.shared and vim.inspect things.
- Inline shared.lua into nvim, but also keep it available in runtime.
2019-11-24 03:28:48 -07:00
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.bo.filetype = ''
|
2019-11-26 09:57:53 -07:00
|
|
|
|
vim.bo[BUF].modifiable = true
|
Lua: vim.env, vim.{g,v,w,bo,wo} #11442
- Add vim variable meta accessors: vim.env, vim.{g,v,w,bo,wo}
- Redo gen_char_blob to generate multiple blobs instead of just one
so that multiple Lua modules can be inlined.
- Reorder vim.lua inclusion so that it can use previously defined C
functions and utility functions like vim.shared and vim.inspect things.
- Inline shared.lua into nvim, but also keep it available in runtime.
2019-11-24 03:28:48 -07:00
|
|
|
|
]]
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq('', fn.luaeval 'vim.bo.filetype')
|
|
|
|
|
eq(true, fn.luaeval 'vim.bo[BUF].modifiable')
|
2020-11-04 02:41:22 -07:00
|
|
|
|
matches("Unknown option 'nosuchopt'$", pcall_err(exec_lua, 'return vim.bo.nosuchopt'))
|
|
|
|
|
matches('Expected Lua string$', pcall_err(exec_lua, 'return vim.bo[0][0].autoread'))
|
2022-06-22 12:19:03 -07:00
|
|
|
|
matches('Invalid buffer id: %-1$', pcall_err(exec_lua, 'return vim.bo[-1].filetype'))
|
Lua: vim.env, vim.{g,v,w,bo,wo} #11442
- Add vim variable meta accessors: vim.env, vim.{g,v,w,bo,wo}
- Redo gen_char_blob to generate multiple blobs instead of just one
so that multiple Lua modules can be inlined.
- Reorder vim.lua inclusion so that it can use previously defined C
functions and utility functions like vim.shared and vim.inspect things.
- Inline shared.lua into nvim, but also keep it available in runtime.
2019-11-24 03:28:48 -07:00
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('vim.wo', function()
|
|
|
|
|
exec_lua [[
|
2023-05-21 23:47:10 -07:00
|
|
|
|
vim.api.nvim_set_option_value("cole", 2, {})
|
2019-12-07 04:34:02 -07:00
|
|
|
|
vim.cmd "split"
|
2023-05-21 23:47:10 -07:00
|
|
|
|
vim.api.nvim_set_option_value("cole", 2, {})
|
Lua: vim.env, vim.{g,v,w,bo,wo} #11442
- Add vim variable meta accessors: vim.env, vim.{g,v,w,bo,wo}
- Redo gen_char_blob to generate multiple blobs instead of just one
so that multiple Lua modules can be inlined.
- Reorder vim.lua inclusion so that it can use previously defined C
functions and utility functions like vim.shared and vim.inspect things.
- Inline shared.lua into nvim, but also keep it available in runtime.
2019-11-24 03:28:48 -07:00
|
|
|
|
]]
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(2, fn.luaeval 'vim.wo.cole')
|
Lua: vim.env, vim.{g,v,w,bo,wo} #11442
- Add vim variable meta accessors: vim.env, vim.{g,v,w,bo,wo}
- Redo gen_char_blob to generate multiple blobs instead of just one
so that multiple Lua modules can be inlined.
- Reorder vim.lua inclusion so that it can use previously defined C
functions and utility functions like vim.shared and vim.inspect things.
- Inline shared.lua into nvim, but also keep it available in runtime.
2019-11-24 03:28:48 -07:00
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.wo.conceallevel = 0
|
|
|
|
|
]]
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(0, fn.luaeval 'vim.wo.cole')
|
|
|
|
|
eq(0, fn.luaeval 'vim.wo[0].cole')
|
|
|
|
|
eq(0, fn.luaeval 'vim.wo[1001].cole')
|
2020-11-04 02:41:22 -07:00
|
|
|
|
matches("Unknown option 'notanopt'$", pcall_err(exec_lua, 'return vim.wo.notanopt'))
|
2022-06-22 12:19:03 -07:00
|
|
|
|
matches('Invalid window id: %-1$', pcall_err(exec_lua, 'return vim.wo[-1].list'))
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(2, fn.luaeval 'vim.wo[1000].cole')
|
2019-12-07 04:34:02 -07:00
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.wo[1000].cole = 0
|
|
|
|
|
]]
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(0, fn.luaeval 'vim.wo[1000].cole')
|
fix(api): nvim_set_option_value for global-local options
global-local window options need to be handled specially. When `win` is
given but `scope` is not, then we want to set the local version of the
option but not the global one, therefore we need to force
`scope='local'`.
Note this does not apply to window-local only options (e.g. 'number')
Example:
nvim_set_option_value('scrolloff', 10, {}) -- global-local window option; set global value
nvim_set_option_value('scrolloff', 20, {win=0}) -- global-local window option; set local value
nvim_set_option_value('number', true, {}) -- local window option
is now equivalent to:
nvim_set_option_value('scrolloff', 10, {})
nvim_set_option_value('scrolloff', 20, {win=0, scope='local'}) -- changed from before
nvim_set_option_value('number', true, {win=0}) -- unchanged from before
Only the global-local option with a `win` provided gets forced to local
scope.
2022-06-21 09:13:01 -07:00
|
|
|
|
|
|
|
|
|
-- Can handle global-local values
|
|
|
|
|
exec_lua [[vim.o.scrolloff = 100]]
|
|
|
|
|
exec_lua [[vim.wo.scrolloff = 200]]
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(200, fn.luaeval 'vim.wo.scrolloff')
|
fix(api): nvim_set_option_value for global-local options
global-local window options need to be handled specially. When `win` is
given but `scope` is not, then we want to set the local version of the
option but not the global one, therefore we need to force
`scope='local'`.
Note this does not apply to window-local only options (e.g. 'number')
Example:
nvim_set_option_value('scrolloff', 10, {}) -- global-local window option; set global value
nvim_set_option_value('scrolloff', 20, {win=0}) -- global-local window option; set local value
nvim_set_option_value('number', true, {}) -- local window option
is now equivalent to:
nvim_set_option_value('scrolloff', 10, {})
nvim_set_option_value('scrolloff', 20, {win=0, scope='local'}) -- changed from before
nvim_set_option_value('number', true, {win=0}) -- unchanged from before
Only the global-local option with a `win` provided gets forced to local
scope.
2022-06-21 09:13:01 -07:00
|
|
|
|
exec_lua [[vim.wo.scrolloff = -1]]
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(100, fn.luaeval 'vim.wo.scrolloff')
|
2023-07-07 08:37:36 -07:00
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.wo[0][0].scrolloff = 200
|
2023-08-23 01:32:15 -07:00
|
|
|
|
vim.cmd "enew"
|
2023-07-07 08:37:36 -07:00
|
|
|
|
]]
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(100, fn.luaeval 'vim.wo.scrolloff')
|
2024-06-12 07:35:54 -07:00
|
|
|
|
|
2024-06-12 07:47:42 -07:00
|
|
|
|
matches('only bufnr=0 is supported', pcall_err(exec_lua, 'vim.wo[0][10].signcolumn = "no"'))
|
2024-06-12 07:35:54 -07:00
|
|
|
|
|
2024-06-12 07:47:42 -07:00
|
|
|
|
matches('only bufnr=0 is supported', pcall_err(exec_lua, 'local a = vim.wo[0][10].signcolumn'))
|
Lua: vim.env, vim.{g,v,w,bo,wo} #11442
- Add vim variable meta accessors: vim.env, vim.{g,v,w,bo,wo}
- Redo gen_char_blob to generate multiple blobs instead of just one
so that multiple Lua modules can be inlined.
- Reorder vim.lua inclusion so that it can use previously defined C
functions and utility functions like vim.shared and vim.inspect things.
- Inline shared.lua into nvim, but also keep it available in runtime.
2019-11-24 03:28:48 -07:00
|
|
|
|
end)
|
2019-12-01 06:28:53 -07:00
|
|
|
|
|
2021-05-28 08:24:48 -07:00
|
|
|
|
describe('vim.opt', function()
|
|
|
|
|
-- TODO: We still need to write some tests for optlocal, opt and then getting the options
|
|
|
|
|
-- Probably could also do some stuff with getting things from viml side as well to confirm behavior is the same.
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows setting number values', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local scrolloff = exec_lua [[
|
|
|
|
|
vim.opt.scrolloff = 10
|
|
|
|
|
return vim.o.scrolloff
|
|
|
|
|
]]
|
2024-03-11 07:23:14 -07:00
|
|
|
|
eq(10, scrolloff)
|
2021-05-28 08:24:48 -07:00
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
pending('handles STUPID window things', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local result = exec_lua [[
|
|
|
|
|
local result = {}
|
|
|
|
|
|
2022-12-19 09:37:45 -07:00
|
|
|
|
table.insert(result, vim.api.nvim_get_option_value('scrolloff', {scope='global'}))
|
|
|
|
|
table.insert(result, vim.api.nvim_get_option_value('scrolloff', {win=0}))
|
2021-05-28 08:24:48 -07:00
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq({}, result)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows setting tables', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local wildignore = exec_lua [[
|
|
|
|
|
vim.opt.wildignore = { 'hello', 'world' }
|
|
|
|
|
return vim.o.wildignore
|
|
|
|
|
]]
|
2024-03-11 07:23:14 -07:00
|
|
|
|
eq('hello,world', wildignore)
|
2021-05-28 08:24:48 -07:00
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows setting tables with shortnames', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local wildignore = exec_lua [[
|
|
|
|
|
vim.opt.wig = { 'hello', 'world' }
|
|
|
|
|
return vim.o.wildignore
|
|
|
|
|
]]
|
2024-03-11 07:23:14 -07:00
|
|
|
|
eq('hello,world', wildignore)
|
2021-05-28 08:24:48 -07:00
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('errors when you attempt to set string values to numeric options', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local result = exec_lua [[
|
|
|
|
|
return {
|
|
|
|
|
pcall(function() vim.opt.textwidth = 'hello world' end)
|
|
|
|
|
}
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq(false, result[1])
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('errors when you attempt to setlocal a global value', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local result = exec_lua [[
|
|
|
|
|
return pcall(function() vim.opt_local.clipboard = "hello" end)
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq(false, result)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows you to set boolean values', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
eq(
|
|
|
|
|
{ true, false, true },
|
|
|
|
|
exec_lua [[
|
|
|
|
|
local results = {}
|
|
|
|
|
|
|
|
|
|
vim.opt.autoindent = true
|
|
|
|
|
table.insert(results, vim.bo.autoindent)
|
|
|
|
|
|
|
|
|
|
vim.opt.autoindent = false
|
|
|
|
|
table.insert(results, vim.bo.autoindent)
|
|
|
|
|
|
|
|
|
|
vim.opt.autoindent = not vim.opt.autoindent:get()
|
|
|
|
|
table.insert(results, vim.bo.autoindent)
|
|
|
|
|
|
|
|
|
|
return results
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('changes current buffer values and defaults for global local values', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local result = exec_lua [[
|
|
|
|
|
local result = {}
|
|
|
|
|
|
|
|
|
|
vim.opt.makeprg = "global-local"
|
2022-12-19 09:37:45 -07:00
|
|
|
|
table.insert(result, vim.go.makeprg)
|
|
|
|
|
table.insert(result, vim.api.nvim_get_option_value('makeprg', {buf=0}))
|
2021-05-28 08:24:48 -07:00
|
|
|
|
|
|
|
|
|
vim.opt_local.mp = "only-local"
|
2022-12-19 09:37:45 -07:00
|
|
|
|
table.insert(result, vim.go.makeprg)
|
|
|
|
|
table.insert(result, vim.api.nvim_get_option_value('makeprg', {buf=0}))
|
2021-05-28 08:24:48 -07:00
|
|
|
|
|
|
|
|
|
vim.opt_global.makeprg = "only-global"
|
2022-12-19 09:37:45 -07:00
|
|
|
|
table.insert(result, vim.go.makeprg)
|
|
|
|
|
table.insert(result, vim.api.nvim_get_option_value('makeprg', {buf=0}))
|
2021-05-28 08:24:48 -07:00
|
|
|
|
|
|
|
|
|
vim.opt.makeprg = "global-local"
|
2022-12-19 09:37:45 -07:00
|
|
|
|
table.insert(result, vim.go.makeprg)
|
|
|
|
|
table.insert(result, vim.api.nvim_get_option_value('makeprg', {buf=0}))
|
2021-05-28 08:24:48 -07:00
|
|
|
|
return result
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
-- Set -> global & local
|
|
|
|
|
eq('global-local', result[1])
|
2021-10-11 21:09:08 -07:00
|
|
|
|
eq('', result[2])
|
2021-05-28 08:24:48 -07:00
|
|
|
|
|
|
|
|
|
-- Setlocal -> only local
|
|
|
|
|
eq('global-local', result[3])
|
|
|
|
|
eq('only-local', result[4])
|
|
|
|
|
|
|
|
|
|
-- Setglobal -> only global
|
|
|
|
|
eq('only-global', result[5])
|
|
|
|
|
eq('only-local', result[6])
|
|
|
|
|
|
2021-10-11 21:09:08 -07:00
|
|
|
|
-- Set -> sets global value and resets local value
|
2021-05-28 08:24:48 -07:00
|
|
|
|
eq('global-local', result[7])
|
2021-10-11 21:09:08 -07:00
|
|
|
|
eq('', result[8])
|
2021-05-28 08:24:48 -07:00
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows you to retrieve window opts even if they have not been set', function()
|
2021-05-30 04:08:43 -07:00
|
|
|
|
local result = exec_lua [[
|
|
|
|
|
local result = {}
|
|
|
|
|
table.insert(result, vim.opt.number:get())
|
|
|
|
|
table.insert(result, vim.opt_local.number:get())
|
|
|
|
|
|
|
|
|
|
vim.opt_local.number = true
|
|
|
|
|
table.insert(result, vim.opt.number:get())
|
|
|
|
|
table.insert(result, vim.opt_local.number:get())
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
]]
|
|
|
|
|
eq({ false, false, true, true }, result)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows all sorts of string manipulation', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
eq(
|
|
|
|
|
{ 'hello', 'hello world', 'start hello world' },
|
|
|
|
|
exec_lua [[
|
|
|
|
|
local results = {}
|
|
|
|
|
|
|
|
|
|
vim.opt.makeprg = "hello"
|
|
|
|
|
table.insert(results, vim.o.makeprg)
|
|
|
|
|
|
|
|
|
|
vim.opt.makeprg = vim.opt.makeprg + " world"
|
|
|
|
|
table.insert(results, vim.o.makeprg)
|
|
|
|
|
|
|
|
|
|
vim.opt.makeprg = vim.opt.makeprg ^ "start "
|
|
|
|
|
table.insert(results, vim.o.makeprg)
|
|
|
|
|
|
|
|
|
|
return results
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
describe('option:get()', function()
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('works for boolean values', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
eq(
|
|
|
|
|
false,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.opt.number = false
|
|
|
|
|
return vim.opt.number:get()
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('works for number values', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local tabstop = exec_lua [[
|
|
|
|
|
vim.opt.tabstop = 10
|
|
|
|
|
return vim.opt.tabstop:get()
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq(10, tabstop)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('works for string values', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
eq(
|
|
|
|
|
'hello world',
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.opt.makeprg = "hello world"
|
|
|
|
|
return vim.opt.makeprg:get()
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('works for set type flaglists', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local formatoptions = exec_lua [[
|
|
|
|
|
vim.opt.formatoptions = 'tcro'
|
|
|
|
|
return vim.opt.formatoptions:get()
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq(true, formatoptions.t)
|
|
|
|
|
eq(true, not formatoptions.q)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('works for set type flaglists', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local formatoptions = exec_lua [[
|
|
|
|
|
vim.opt.formatoptions = { t = true, c = true, r = true, o = true }
|
|
|
|
|
return vim.opt.formatoptions:get()
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq(true, formatoptions.t)
|
|
|
|
|
eq(true, not formatoptions.q)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('works for array list type options', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local wildignore = exec_lua [[
|
|
|
|
|
vim.opt.wildignore = "*.c,*.o,__pycache__"
|
|
|
|
|
return vim.opt.wildignore:get()
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq(3, #wildignore)
|
|
|
|
|
eq('*.c', wildignore[1])
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('works for options that are both commalist and flaglist', function()
|
2021-06-11 09:28:15 -07:00
|
|
|
|
local result = exec_lua [[
|
|
|
|
|
vim.opt.whichwrap = "b,s"
|
|
|
|
|
return vim.opt.whichwrap:get()
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq({ b = true, s = true }, result)
|
|
|
|
|
|
|
|
|
|
result = exec_lua [[
|
|
|
|
|
vim.opt.whichwrap = { b = true, s = false, h = true }
|
|
|
|
|
return vim.opt.whichwrap:get()
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq({ b = true, h = true }, result)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('works for key-value pair options', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local listchars = exec_lua [[
|
2021-07-04 00:14:39 -07:00
|
|
|
|
vim.opt.listchars = "tab:> ,space:_"
|
2021-05-28 08:24:48 -07:00
|
|
|
|
return vim.opt.listchars:get()
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq({
|
2021-07-04 00:14:39 -07:00
|
|
|
|
tab = '> ',
|
2021-05-28 08:24:48 -07:00
|
|
|
|
space = '_',
|
|
|
|
|
}, listchars)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows you to add numeric options', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
eq(
|
|
|
|
|
16,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.opt.tabstop = 12
|
|
|
|
|
vim.opt.tabstop = vim.opt.tabstop + 4
|
|
|
|
|
return vim.bo.tabstop
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows you to subtract numeric options', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
eq(
|
|
|
|
|
2,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.opt.tabstop = 4
|
|
|
|
|
vim.opt.tabstop = vim.opt.tabstop - 2
|
|
|
|
|
return vim.bo.tabstop
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
describe('key:value style options', function()
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('handles dict style', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local listchars = exec_lua [[
|
|
|
|
|
vim.opt.listchars = {
|
|
|
|
|
eol = "~",
|
|
|
|
|
space = ".",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return vim.o.listchars
|
|
|
|
|
]]
|
|
|
|
|
eq('eol:~,space:.', listchars)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows adding dict style', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local listchars = exec_lua [[
|
|
|
|
|
vim.opt.listchars = {
|
|
|
|
|
eol = "~",
|
|
|
|
|
space = ".",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vim.opt.listchars = vim.opt.listchars + { space = "-" }
|
|
|
|
|
|
|
|
|
|
return vim.o.listchars
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq('eol:~,space:-', listchars)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows adding dict style', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local listchars = exec_lua [[
|
|
|
|
|
vim.opt.listchars = {
|
|
|
|
|
eol = "~",
|
|
|
|
|
space = ".",
|
|
|
|
|
}
|
|
|
|
|
vim.opt.listchars = vim.opt.listchars + { space = "-" } + { space = "_" }
|
|
|
|
|
|
|
|
|
|
return vim.o.listchars
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq('eol:~,space:_', listchars)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows completely new keys', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local listchars = exec_lua [[
|
|
|
|
|
vim.opt.listchars = {
|
|
|
|
|
eol = "~",
|
|
|
|
|
space = ".",
|
|
|
|
|
}
|
|
|
|
|
vim.opt.listchars = vim.opt.listchars + { tab = ">>>" }
|
|
|
|
|
|
|
|
|
|
return vim.o.listchars
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq('eol:~,space:.,tab:>>>', listchars)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows subtracting dict style', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local listchars = exec_lua [[
|
|
|
|
|
vim.opt.listchars = {
|
|
|
|
|
eol = "~",
|
|
|
|
|
space = ".",
|
|
|
|
|
}
|
|
|
|
|
vim.opt.listchars = vim.opt.listchars - "space"
|
|
|
|
|
|
|
|
|
|
return vim.o.listchars
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq('eol:~', listchars)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows subtracting dict style', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local listchars = exec_lua [[
|
|
|
|
|
vim.opt.listchars = {
|
|
|
|
|
eol = "~",
|
|
|
|
|
space = ".",
|
|
|
|
|
}
|
|
|
|
|
vim.opt.listchars = vim.opt.listchars - "space" - "eol"
|
|
|
|
|
|
|
|
|
|
return vim.o.listchars
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq('', listchars)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows subtracting dict style multiple times', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local listchars = exec_lua [[
|
|
|
|
|
vim.opt.listchars = {
|
|
|
|
|
eol = "~",
|
|
|
|
|
space = ".",
|
|
|
|
|
}
|
|
|
|
|
vim.opt.listchars = vim.opt.listchars - "space" - "space"
|
|
|
|
|
|
|
|
|
|
return vim.o.listchars
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq('eol:~', listchars)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows adding a key:value string to a listchars', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local listchars = exec_lua [[
|
|
|
|
|
vim.opt.listchars = {
|
|
|
|
|
eol = "~",
|
|
|
|
|
space = ".",
|
|
|
|
|
}
|
|
|
|
|
vim.opt.listchars = vim.opt.listchars + "tab:>~"
|
|
|
|
|
|
|
|
|
|
return vim.o.listchars
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq('eol:~,space:.,tab:>~', listchars)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows prepending a key:value string to a listchars', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local listchars = exec_lua [[
|
|
|
|
|
vim.opt.listchars = {
|
|
|
|
|
eol = "~",
|
|
|
|
|
space = ".",
|
|
|
|
|
}
|
|
|
|
|
vim.opt.listchars = vim.opt.listchars ^ "tab:>~"
|
|
|
|
|
|
|
|
|
|
return vim.o.listchars
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq('eol:~,space:.,tab:>~', listchars)
|
|
|
|
|
end)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('automatically sets when calling remove', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
eq(
|
|
|
|
|
'foo,baz',
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.opt.wildignore = "foo,bar,baz"
|
|
|
|
|
vim.opt.wildignore:remove("bar")
|
|
|
|
|
|
|
|
|
|
return vim.o.wildignore
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('automatically sets when calling remove with a table', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
eq(
|
|
|
|
|
'foo',
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.opt.wildignore = "foo,bar,baz"
|
|
|
|
|
vim.opt.wildignore:remove { "bar", "baz" }
|
|
|
|
|
|
|
|
|
|
return vim.o.wildignore
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('automatically sets when calling append', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
eq(
|
|
|
|
|
'foo,bar,baz,bing',
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.opt.wildignore = "foo,bar,baz"
|
|
|
|
|
vim.opt.wildignore:append("bing")
|
|
|
|
|
|
|
|
|
|
return vim.o.wildignore
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('automatically sets when calling append with a table', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
eq(
|
|
|
|
|
'foo,bar,baz,bing,zap',
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.opt.wildignore = "foo,bar,baz"
|
|
|
|
|
vim.opt.wildignore:append { "bing", "zap" }
|
|
|
|
|
|
|
|
|
|
return vim.o.wildignore
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows adding tables', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local wildignore = exec_lua [[
|
|
|
|
|
vim.opt.wildignore = 'foo'
|
|
|
|
|
return vim.o.wildignore
|
|
|
|
|
]]
|
2024-03-11 07:23:14 -07:00
|
|
|
|
eq('foo', wildignore)
|
2021-05-28 08:24:48 -07:00
|
|
|
|
|
|
|
|
|
wildignore = exec_lua [[
|
|
|
|
|
vim.opt.wildignore = vim.opt.wildignore + { 'bar', 'baz' }
|
|
|
|
|
return vim.o.wildignore
|
|
|
|
|
]]
|
2024-03-11 07:23:14 -07:00
|
|
|
|
eq('foo,bar,baz', wildignore)
|
2021-05-28 08:24:48 -07:00
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('handles adding duplicates', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local wildignore = exec_lua [[
|
|
|
|
|
vim.opt.wildignore = 'foo'
|
|
|
|
|
return vim.o.wildignore
|
|
|
|
|
]]
|
2024-03-11 07:23:14 -07:00
|
|
|
|
eq('foo', wildignore)
|
2021-05-28 08:24:48 -07:00
|
|
|
|
|
|
|
|
|
wildignore = exec_lua [[
|
|
|
|
|
vim.opt.wildignore = vim.opt.wildignore + { 'bar', 'baz' }
|
|
|
|
|
return vim.o.wildignore
|
|
|
|
|
]]
|
2024-03-11 07:23:14 -07:00
|
|
|
|
eq('foo,bar,baz', wildignore)
|
2021-05-28 08:24:48 -07:00
|
|
|
|
|
|
|
|
|
wildignore = exec_lua [[
|
|
|
|
|
vim.opt.wildignore = vim.opt.wildignore + { 'bar', 'baz' }
|
|
|
|
|
return vim.o.wildignore
|
|
|
|
|
]]
|
2024-03-11 07:23:14 -07:00
|
|
|
|
eq('foo,bar,baz', wildignore)
|
2021-05-28 08:24:48 -07:00
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows adding multiple times', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local wildignore = exec_lua [[
|
|
|
|
|
vim.opt.wildignore = 'foo'
|
|
|
|
|
vim.opt.wildignore = vim.opt.wildignore + 'bar' + 'baz'
|
|
|
|
|
return vim.o.wildignore
|
|
|
|
|
]]
|
2024-03-11 07:23:14 -07:00
|
|
|
|
eq('foo,bar,baz', wildignore)
|
2021-05-28 08:24:48 -07:00
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('removes values when you use minus', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local wildignore = exec_lua [[
|
|
|
|
|
vim.opt.wildignore = 'foo'
|
|
|
|
|
return vim.o.wildignore
|
|
|
|
|
]]
|
2024-03-11 07:23:14 -07:00
|
|
|
|
eq('foo', wildignore)
|
2021-05-28 08:24:48 -07:00
|
|
|
|
|
|
|
|
|
wildignore = exec_lua [[
|
|
|
|
|
vim.opt.wildignore = vim.opt.wildignore + { 'bar', 'baz' }
|
|
|
|
|
return vim.o.wildignore
|
|
|
|
|
]]
|
2024-03-11 07:23:14 -07:00
|
|
|
|
eq('foo,bar,baz', wildignore)
|
2021-05-28 08:24:48 -07:00
|
|
|
|
|
|
|
|
|
wildignore = exec_lua [[
|
|
|
|
|
vim.opt.wildignore = vim.opt.wildignore - 'bar'
|
|
|
|
|
return vim.o.wildignore
|
|
|
|
|
]]
|
2024-03-11 07:23:14 -07:00
|
|
|
|
eq('foo,baz', wildignore)
|
2021-05-28 08:24:48 -07:00
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('prepends values when using ^', function()
|
2021-05-28 08:24:48 -07:00
|
|
|
|
local wildignore = exec_lua [[
|
|
|
|
|
vim.opt.wildignore = 'foo'
|
|
|
|
|
vim.opt.wildignore = vim.opt.wildignore ^ 'first'
|
|
|
|
|
return vim.o.wildignore
|
|
|
|
|
]]
|
|
|
|
|
eq('first,foo', wildignore)
|
|
|
|
|
|
|
|
|
|
wildignore = exec_lua [[
|
|
|
|
|
vim.opt.wildignore = vim.opt.wildignore ^ 'super_first'
|
|
|
|
|
return vim.o.wildignore
|
|
|
|
|
]]
|
2024-03-11 07:23:14 -07:00
|
|
|
|
eq('super_first,first,foo', wildignore)
|
2021-05-28 08:24:48 -07:00
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('does not remove duplicates from wildmode: #14708', function()
|
2021-06-11 08:13:43 -07:00
|
|
|
|
local wildmode = exec_lua [[
|
|
|
|
|
vim.opt.wildmode = {"full", "list", "full"}
|
|
|
|
|
return vim.o.wildmode
|
|
|
|
|
]]
|
|
|
|
|
|
2024-03-11 07:23:14 -07:00
|
|
|
|
eq('full,list,full', wildmode)
|
2021-06-11 08:13:43 -07:00
|
|
|
|
end)
|
2021-05-30 05:49:19 -07:00
|
|
|
|
|
|
|
|
|
describe('option types', function()
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows to set option with numeric value', function()
|
2021-05-30 05:49:19 -07:00
|
|
|
|
eq(
|
|
|
|
|
4,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.opt.tabstop = 4
|
|
|
|
|
return vim.bo.tabstop
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
matches(
|
|
|
|
|
"Invalid option type 'string' for 'tabstop'",
|
|
|
|
|
pcall_err(
|
|
|
|
|
exec_lua,
|
|
|
|
|
[[
|
|
|
|
|
vim.opt.tabstop = '4'
|
|
|
|
|
]]
|
|
|
|
|
)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-05-30 05:49:19 -07:00
|
|
|
|
matches(
|
|
|
|
|
"Invalid option type 'boolean' for 'tabstop'",
|
|
|
|
|
pcall_err(
|
|
|
|
|
exec_lua,
|
|
|
|
|
[[
|
|
|
|
|
vim.opt.tabstop = true
|
|
|
|
|
]]
|
|
|
|
|
)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-05-30 05:49:19 -07:00
|
|
|
|
matches(
|
|
|
|
|
"Invalid option type 'table' for 'tabstop'",
|
|
|
|
|
pcall_err(
|
|
|
|
|
exec_lua,
|
|
|
|
|
[[
|
|
|
|
|
vim.opt.tabstop = {4, 2}
|
|
|
|
|
]]
|
|
|
|
|
)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-05-30 05:49:19 -07:00
|
|
|
|
matches(
|
|
|
|
|
"Invalid option type 'function' for 'tabstop'",
|
|
|
|
|
pcall_err(
|
|
|
|
|
exec_lua,
|
|
|
|
|
[[
|
|
|
|
|
vim.opt.tabstop = function()
|
|
|
|
|
return 4
|
|
|
|
|
end
|
|
|
|
|
]]
|
|
|
|
|
)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-05-30 05:49:19 -07:00
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows to set option with boolean value', function()
|
2021-05-30 05:49:19 -07:00
|
|
|
|
eq(
|
|
|
|
|
true,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.opt.undofile = true
|
|
|
|
|
return vim.bo.undofile
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
matches(
|
|
|
|
|
"Invalid option type 'number' for 'undofile'",
|
|
|
|
|
pcall_err(
|
|
|
|
|
exec_lua,
|
|
|
|
|
[[
|
|
|
|
|
vim.opt.undofile = 0
|
|
|
|
|
]]
|
|
|
|
|
)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-05-30 05:49:19 -07:00
|
|
|
|
matches(
|
|
|
|
|
"Invalid option type 'table' for 'undofile'",
|
|
|
|
|
pcall_err(
|
|
|
|
|
exec_lua,
|
|
|
|
|
[[
|
|
|
|
|
vim.opt.undofile = {true}
|
|
|
|
|
]]
|
|
|
|
|
)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-05-30 05:49:19 -07:00
|
|
|
|
matches(
|
|
|
|
|
"Invalid option type 'string' for 'undofile'",
|
|
|
|
|
pcall_err(
|
|
|
|
|
exec_lua,
|
|
|
|
|
[[
|
|
|
|
|
vim.opt.undofile = 'true'
|
|
|
|
|
]]
|
|
|
|
|
)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-05-30 05:49:19 -07:00
|
|
|
|
matches(
|
|
|
|
|
"Invalid option type 'function' for 'undofile'",
|
|
|
|
|
pcall_err(
|
|
|
|
|
exec_lua,
|
|
|
|
|
[[
|
|
|
|
|
vim.opt.undofile = function()
|
|
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
]]
|
|
|
|
|
)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-05-30 05:49:19 -07:00
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows to set option with array or string value', function()
|
2021-05-30 05:49:19 -07:00
|
|
|
|
eq(
|
|
|
|
|
'indent,eol,start',
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.opt.backspace = {'indent','eol','start'}
|
|
|
|
|
return vim.go.backspace
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
eq(
|
|
|
|
|
'indent,eol,start',
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.opt.backspace = 'indent,eol,start'
|
|
|
|
|
return vim.go.backspace
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
matches(
|
|
|
|
|
"Invalid option type 'boolean' for 'backspace'",
|
|
|
|
|
pcall_err(
|
|
|
|
|
exec_lua,
|
|
|
|
|
[[
|
|
|
|
|
vim.opt.backspace = true
|
|
|
|
|
]]
|
|
|
|
|
)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-05-30 05:49:19 -07:00
|
|
|
|
matches(
|
|
|
|
|
"Invalid option type 'number' for 'backspace'",
|
|
|
|
|
pcall_err(
|
|
|
|
|
exec_lua,
|
|
|
|
|
[[
|
|
|
|
|
vim.opt.backspace = 2
|
|
|
|
|
]]
|
|
|
|
|
)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-05-30 05:49:19 -07:00
|
|
|
|
matches(
|
|
|
|
|
"Invalid option type 'function' for 'backspace'",
|
|
|
|
|
pcall_err(
|
|
|
|
|
exec_lua,
|
|
|
|
|
[[
|
|
|
|
|
vim.opt.backspace = function()
|
|
|
|
|
return 'indent,eol,start'
|
|
|
|
|
end
|
|
|
|
|
]]
|
|
|
|
|
)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-05-30 05:49:19 -07:00
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows set option with map or string value', function()
|
2021-05-30 05:49:19 -07:00
|
|
|
|
eq(
|
|
|
|
|
'eol:~,space:.',
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.opt.listchars = {
|
|
|
|
|
eol = "~",
|
|
|
|
|
space = ".",
|
|
|
|
|
}
|
|
|
|
|
return vim.o.listchars
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
eq(
|
|
|
|
|
'eol:~,space:.,tab:>~',
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.opt.listchars = "eol:~,space:.,tab:>~"
|
|
|
|
|
return vim.o.listchars
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
matches(
|
|
|
|
|
"Invalid option type 'boolean' for 'listchars'",
|
|
|
|
|
pcall_err(
|
|
|
|
|
exec_lua,
|
|
|
|
|
[[
|
|
|
|
|
vim.opt.listchars = true
|
|
|
|
|
]]
|
|
|
|
|
)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-05-30 05:49:19 -07:00
|
|
|
|
matches(
|
|
|
|
|
"Invalid option type 'number' for 'listchars'",
|
|
|
|
|
pcall_err(
|
|
|
|
|
exec_lua,
|
|
|
|
|
[[
|
|
|
|
|
vim.opt.listchars = 2
|
|
|
|
|
]]
|
|
|
|
|
)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-05-30 05:49:19 -07:00
|
|
|
|
matches(
|
|
|
|
|
"Invalid option type 'function' for 'listchars'",
|
|
|
|
|
pcall_err(
|
|
|
|
|
exec_lua,
|
|
|
|
|
[[
|
|
|
|
|
vim.opt.listchars = function()
|
|
|
|
|
return "eol:~,space:.,tab:>~"
|
|
|
|
|
end
|
|
|
|
|
]]
|
|
|
|
|
)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-05-30 05:49:19 -07:00
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows set option with set or string value', function()
|
2021-05-30 05:49:19 -07:00
|
|
|
|
local ww = exec_lua [[
|
|
|
|
|
vim.opt.whichwrap = {
|
|
|
|
|
b = true,
|
|
|
|
|
s = 1,
|
|
|
|
|
}
|
|
|
|
|
return vim.go.whichwrap
|
|
|
|
|
]]
|
2021-06-11 09:28:15 -07:00
|
|
|
|
|
2024-03-11 07:23:14 -07:00
|
|
|
|
eq('b,s', ww)
|
2021-05-30 05:49:19 -07:00
|
|
|
|
eq(
|
|
|
|
|
'b,s,<,>,[,]',
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.opt.whichwrap = "b,s,<,>,[,]"
|
|
|
|
|
return vim.go.whichwrap
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
matches(
|
|
|
|
|
"Invalid option type 'boolean' for 'whichwrap'",
|
|
|
|
|
pcall_err(
|
|
|
|
|
exec_lua,
|
|
|
|
|
[[
|
|
|
|
|
vim.opt.whichwrap = true
|
|
|
|
|
]]
|
|
|
|
|
)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-05-30 05:49:19 -07:00
|
|
|
|
matches(
|
|
|
|
|
"Invalid option type 'number' for 'whichwrap'",
|
|
|
|
|
pcall_err(
|
|
|
|
|
exec_lua,
|
|
|
|
|
[[
|
|
|
|
|
vim.opt.whichwrap = 2
|
|
|
|
|
]]
|
|
|
|
|
)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-05-30 05:49:19 -07:00
|
|
|
|
matches(
|
|
|
|
|
"Invalid option type 'function' for 'whichwrap'",
|
|
|
|
|
pcall_err(
|
|
|
|
|
exec_lua,
|
|
|
|
|
[[
|
|
|
|
|
vim.opt.whichwrap = function()
|
|
|
|
|
return "b,s,<,>,[,]"
|
|
|
|
|
end
|
|
|
|
|
]]
|
|
|
|
|
)
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2021-05-30 05:49:19 -07:00
|
|
|
|
end)
|
|
|
|
|
end)
|
2021-06-11 10:39:59 -07:00
|
|
|
|
|
|
|
|
|
-- isfname=a,b,c,,,d,e,f
|
|
|
|
|
it('can handle isfname ,,,', function()
|
|
|
|
|
local result = exec_lua [[
|
|
|
|
|
vim.opt.isfname = "a,b,,,c"
|
2022-12-19 09:37:45 -07:00
|
|
|
|
return { vim.opt.isfname:get(), vim.go.isfname }
|
2021-06-11 10:39:59 -07:00
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq({ { ',', 'a', 'b', 'c' }, 'a,b,,,c' }, result)
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
-- isfname=a,b,c,^,,def
|
|
|
|
|
it('can handle isfname ,^,,', function()
|
|
|
|
|
local result = exec_lua [[
|
|
|
|
|
vim.opt.isfname = "a,b,^,,c"
|
2022-12-19 09:37:45 -07:00
|
|
|
|
return { vim.opt.isfname:get(), vim.go.isfname }
|
2021-06-11 10:39:59 -07:00
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq({ { '^,', 'a', 'b', 'c' }, 'a,b,^,,c' }, result)
|
|
|
|
|
end)
|
2021-06-29 06:18:59 -07:00
|
|
|
|
|
|
|
|
|
describe('https://github.com/neovim/neovim/issues/14828', function()
|
|
|
|
|
it('gives empty list when item is empty:array', function()
|
|
|
|
|
eq(
|
|
|
|
|
{},
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.cmd("set wildignore=")
|
|
|
|
|
return vim.opt.wildignore:get()
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
eq(
|
|
|
|
|
{},
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.opt.wildignore = {}
|
|
|
|
|
return vim.opt.wildignore:get()
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('gives empty list when item is empty:set', function()
|
|
|
|
|
eq(
|
|
|
|
|
{},
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.cmd("set formatoptions=")
|
|
|
|
|
return vim.opt.formatoptions:get()
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
eq(
|
|
|
|
|
{},
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.opt.formatoptions = {}
|
|
|
|
|
return vim.opt.formatoptions:get()
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('does not append to empty item', function()
|
|
|
|
|
eq(
|
|
|
|
|
{ '*.foo', '*.bar' },
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.opt.wildignore = {}
|
|
|
|
|
vim.opt.wildignore:append { "*.foo", "*.bar" }
|
|
|
|
|
|
|
|
|
|
return vim.opt.wildignore:get()
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('does not prepend to empty item', function()
|
|
|
|
|
eq(
|
|
|
|
|
{ '*.foo', '*.bar' },
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.opt.wildignore = {}
|
|
|
|
|
vim.opt.wildignore:prepend { "*.foo", "*.bar" }
|
|
|
|
|
|
|
|
|
|
return vim.opt.wildignore:get()
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('append to empty set', function()
|
|
|
|
|
eq(
|
|
|
|
|
{ t = true },
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.opt.formatoptions = {}
|
|
|
|
|
vim.opt.formatoptions:append("t")
|
|
|
|
|
|
|
|
|
|
return vim.opt.formatoptions:get()
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('prepend to empty set', function()
|
|
|
|
|
eq(
|
|
|
|
|
{ t = true },
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.opt.formatoptions = {}
|
|
|
|
|
vim.opt.formatoptions:prepend("t")
|
|
|
|
|
|
|
|
|
|
return vim.opt.formatoptions:get()
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
end)
|
2021-06-11 08:13:43 -07:00
|
|
|
|
end) -- vim.opt
|
2021-05-28 08:24:48 -07:00
|
|
|
|
|
2023-09-16 15:35:12 -07:00
|
|
|
|
describe('vim.opt_local', function()
|
|
|
|
|
it('appends into global value when changing local option value', function()
|
2022-12-12 08:14:50 -07:00
|
|
|
|
eq(
|
|
|
|
|
{ 'foo,bar,baz,qux' },
|
|
|
|
|
exec_lua [[
|
|
|
|
|
local result = {}
|
|
|
|
|
|
|
|
|
|
vim.opt.tags = "foo,bar"
|
|
|
|
|
vim.opt_local.tags:append("baz")
|
|
|
|
|
vim.opt_local.tags:append("qux")
|
|
|
|
|
|
|
|
|
|
table.insert(result, vim.bo.tags)
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
end)
|
|
|
|
|
|
2023-09-16 15:35:12 -07:00
|
|
|
|
describe('vim.opt_global', function()
|
|
|
|
|
it('gets current global option value', function()
|
|
|
|
|
eq(
|
|
|
|
|
{ 'yes' },
|
|
|
|
|
exec_lua [[
|
|
|
|
|
local result = {}
|
|
|
|
|
|
|
|
|
|
vim.cmd "setglobal signcolumn=yes"
|
|
|
|
|
table.insert(result, vim.opt_global.signcolumn:get())
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
end)
|
|
|
|
|
|
2019-12-01 06:28:53 -07:00
|
|
|
|
it('vim.cmd', function()
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.cmd "autocmd BufNew * ++once lua BUF = vim.fn.expand('<abuf>')"
|
|
|
|
|
vim.cmd "new"
|
|
|
|
|
]]
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq('2', fn.luaeval 'BUF')
|
|
|
|
|
eq(2, fn.luaeval '#vim.api.nvim_list_bufs()')
|
2022-07-20 04:29:24 -07:00
|
|
|
|
|
|
|
|
|
-- vim.cmd can be indexed with a command name
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.cmd.let 'g:var = 2'
|
|
|
|
|
]]
|
|
|
|
|
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(2, fn.luaeval 'vim.g.var')
|
2019-12-01 06:28:53 -07:00
|
|
|
|
end)
|
2019-11-04 12:40:30 -07:00
|
|
|
|
|
|
|
|
|
it('vim.regex', function()
|
|
|
|
|
exec_lua [[
|
|
|
|
|
re1 = vim.regex"ab\\+c"
|
|
|
|
|
vim.cmd "set nomagic ignorecase"
|
|
|
|
|
re2 = vim.regex"xYz"
|
|
|
|
|
]]
|
|
|
|
|
eq({}, exec_lua [[return {re1:match_str("x ac")}]])
|
|
|
|
|
eq({ 3, 7 }, exec_lua [[return {re1:match_str("ac abbc")}]])
|
|
|
|
|
|
2024-01-12 10:59:57 -07:00
|
|
|
|
api.nvim_buf_set_lines(0, 0, -1, true, { 'yy', 'abc abbc' })
|
2019-11-04 12:40:30 -07:00
|
|
|
|
eq({}, exec_lua [[return {re1:match_line(0, 0)}]])
|
|
|
|
|
eq({ 0, 3 }, exec_lua [[return {re1:match_line(0, 1)}]])
|
|
|
|
|
eq({ 3, 7 }, exec_lua [[return {re1:match_line(0, 1, 1)}]])
|
|
|
|
|
eq({ 3, 7 }, exec_lua [[return {re1:match_line(0, 1, 1, 8)}]])
|
|
|
|
|
eq({}, exec_lua [[return {re1:match_line(0, 1, 1, 7)}]])
|
|
|
|
|
eq({ 0, 3 }, exec_lua [[return {re1:match_line(0, 1, 0, 7)}]])
|
2022-10-09 17:04:08 -07:00
|
|
|
|
|
|
|
|
|
-- vim.regex() error inside :silent! should not crash. #20546
|
|
|
|
|
command([[silent! lua vim.regex('\\z')]])
|
|
|
|
|
assert_alive()
|
2019-11-04 12:40:30 -07:00
|
|
|
|
end)
|
2020-05-18 06:49:50 -07:00
|
|
|
|
|
|
|
|
|
it('vim.defer_fn', function()
|
2020-05-20 08:08:19 -07:00
|
|
|
|
eq(
|
|
|
|
|
false,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.g.test = false
|
|
|
|
|
vim.defer_fn(function() vim.g.test = true end, 150)
|
|
|
|
|
return vim.g.test
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
exec_lua [[vim.wait(1000, function() return vim.g.test end)]]
|
|
|
|
|
eq(true, exec_lua [[return vim.g.test]])
|
2020-05-18 06:49:50 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2022-10-14 02:12:46 -07:00
|
|
|
|
describe('vim.region', function()
|
|
|
|
|
it('charwise', function()
|
refactor!: rename vim.pretty_print => vim.print
Problem:
The function name `vim.pretty_print`:
1. is verbose, which partially defeats its purpose as sugar
2. does not draw from existing precedent or any sort of convention
(except external projects like penlight or python?), which reduces
discoverability, and degrades signaling about best practices.
Solution:
- Rename to `vim.print`.
- Change the behavior so that
1. strings are printed without quotes
2. each arg is printed on its own line
3. tables are indented with 2 instead of 4 spaces
- Example:
:lua ='a', 'b', 42, {a=3}
a
b
42
{
a = 3
}
Comparison of alternatives:
- `vim.print`:
- pro: consistent with Lua's `print()`
- pro: aligns with potential `nvim_print` API function which will
replace nvim_echo, nvim_notify, etc.
- con: behaves differently than Lua's `print()`, slightly misleading?
- `vim.echo`:
- pro: `:echo` has similar "pretty print" behavior.
- con: inconsistent with Lua idioms.
- `vim.p`:
- pro: very short, fits with `vim.o`, etc.
- con: not as discoverable as "echo"
- con: less opportunity for `local p = vim.p` because of potential shadowing.
2023-03-07 08:04:57 -07:00
|
|
|
|
insert(dedent([[
|
2022-10-14 02:12:46 -07:00
|
|
|
|
text tααt tααt text
|
|
|
|
|
text tαxt txtα tex
|
|
|
|
|
text tαxt tαxt
|
|
|
|
|
]]))
|
2023-11-20 23:25:45 -07:00
|
|
|
|
eq({ 5, 13 }, exec_lua [[ return vim.region(0,{0,5},{0,13},'v',false)[0] ]])
|
|
|
|
|
eq({ 5, 15 }, exec_lua [[ return vim.region(0,{0,5},{0,13},'v',true)[0] ]])
|
|
|
|
|
eq({ 5, 15 }, exec_lua [[ return vim.region(0,{0,5},{0,14},'v',true)[0] ]])
|
|
|
|
|
eq({ 5, 15 }, exec_lua [[ return vim.region(0,{0,5},{0,15},'v',false)[0] ]])
|
|
|
|
|
eq({ 5, 17 }, exec_lua [[ return vim.region(0,{0,5},{0,15},'v',true)[0] ]])
|
|
|
|
|
eq({ 5, 17 }, exec_lua [[ return vim.region(0,{0,5},{0,16},'v',true)[0] ]])
|
|
|
|
|
eq({ 5, 17 }, exec_lua [[ return vim.region(0,{0,5},{0,17},'v',false)[0] ]])
|
|
|
|
|
eq({ 5, 18 }, exec_lua [[ return vim.region(0,{0,5},{0,17},'v',true)[0] ]])
|
2022-10-14 02:12:46 -07:00
|
|
|
|
end)
|
|
|
|
|
it('blockwise', function()
|
|
|
|
|
insert([[αα]])
|
|
|
|
|
eq({ 0, 5 }, exec_lua [[ return vim.region(0,{0,0},{0,4},'3',true)[0] ]])
|
|
|
|
|
end)
|
2023-10-06 05:44:50 -07:00
|
|
|
|
it('linewise', function()
|
|
|
|
|
insert(dedent([[
|
|
|
|
|
text tααt tααt text
|
|
|
|
|
text tαxt txtα tex
|
|
|
|
|
text tαxt tαxt
|
|
|
|
|
]]))
|
|
|
|
|
eq({ 0, -1 }, exec_lua [[ return vim.region(0,{1,5},{1,14},'V',true)[1] ]])
|
|
|
|
|
end)
|
2023-04-11 07:28:46 -07:00
|
|
|
|
it('getpos() input', function()
|
|
|
|
|
insert('getpos')
|
|
|
|
|
eq({ 0, 6 }, exec_lua [[ return vim.region(0,{0,0},'.','v',true)[0] ]])
|
|
|
|
|
end)
|
2020-05-18 06:49:50 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2021-08-22 18:26:35 -07:00
|
|
|
|
describe('vim.on_key', function()
|
2024-03-29 03:37:07 -07:00
|
|
|
|
it('tracks Unicode input', function()
|
2021-08-22 18:26:35 -07:00
|
|
|
|
insert([[hello world ]])
|
2020-08-14 07:03:17 -07:00
|
|
|
|
|
|
|
|
|
exec_lua [[
|
2021-08-22 18:26:35 -07:00
|
|
|
|
keys = {}
|
2024-03-30 20:20:05 -07:00
|
|
|
|
typed = {}
|
2020-08-14 07:03:17 -07:00
|
|
|
|
|
2024-03-30 20:20:05 -07:00
|
|
|
|
vim.on_key(function(buf, typed_buf)
|
2020-08-14 07:03:17 -07:00
|
|
|
|
if buf:byte() == 27 then
|
|
|
|
|
buf = "<ESC>"
|
|
|
|
|
end
|
2024-03-30 20:20:05 -07:00
|
|
|
|
if typed_buf:byte() == 27 then
|
|
|
|
|
typed_buf = "<ESC>"
|
|
|
|
|
end
|
2020-08-14 07:03:17 -07:00
|
|
|
|
|
2021-08-22 18:26:35 -07:00
|
|
|
|
table.insert(keys, buf)
|
2024-03-30 20:20:05 -07:00
|
|
|
|
table.insert(typed, typed_buf)
|
2020-08-14 07:03:17 -07:00
|
|
|
|
end)
|
|
|
|
|
]]
|
|
|
|
|
|
2024-03-29 03:37:07 -07:00
|
|
|
|
insert([[next 🤦 lines å …]])
|
2020-08-14 07:03:17 -07:00
|
|
|
|
|
|
|
|
|
-- It has escape in the keys pressed
|
2024-03-29 03:37:07 -07:00
|
|
|
|
eq('inext 🤦 lines å …<ESC>', exec_lua [[return table.concat(keys, '')]])
|
2024-03-30 20:20:05 -07:00
|
|
|
|
eq('inext 🤦 lines å …<ESC>', exec_lua [[return table.concat(typed, '')]])
|
2024-03-29 03:37:07 -07:00
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('tracks input with modifiers', function()
|
|
|
|
|
exec_lua [[
|
|
|
|
|
keys = {}
|
2024-03-30 20:20:05 -07:00
|
|
|
|
typed = {}
|
2024-03-29 03:37:07 -07:00
|
|
|
|
|
2024-03-30 20:20:05 -07:00
|
|
|
|
vim.on_key(function(buf, typed_buf)
|
2024-03-29 03:37:07 -07:00
|
|
|
|
table.insert(keys, vim.fn.keytrans(buf))
|
2024-03-30 20:20:05 -07:00
|
|
|
|
table.insert(typed, vim.fn.keytrans(typed_buf))
|
2024-03-29 03:37:07 -07:00
|
|
|
|
end)
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
feed([[i<C-V><C-;><C-V><C-…><Esc>]])
|
|
|
|
|
|
|
|
|
|
eq('i<C-V><C-;><C-V><C-…><Esc>', exec_lua [[return table.concat(keys, '')]])
|
2024-03-30 20:20:05 -07:00
|
|
|
|
eq('i<C-V><C-;><C-V><C-…><Esc>', exec_lua [[return table.concat(typed, '')]])
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('works with character find and Select mode', function()
|
|
|
|
|
insert('12345')
|
|
|
|
|
|
|
|
|
|
exec_lua [[
|
|
|
|
|
typed = {}
|
|
|
|
|
|
|
|
|
|
vim.cmd('snoremap # @')
|
|
|
|
|
|
|
|
|
|
vim.on_key(function(buf, typed_buf)
|
|
|
|
|
table.insert(typed, vim.fn.keytrans(typed_buf))
|
|
|
|
|
end)
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
feed('F3gHβγδεζ<Esc>gH…<Esc>gH#$%^')
|
|
|
|
|
eq('F3gHβγδεζ<Esc>gH…<Esc>gH#$%^', exec_lua [[return table.concat(typed, '')]])
|
2020-08-14 07:03:17 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2021-08-22 18:26:35 -07:00
|
|
|
|
it('allows removing on_key listeners', function()
|
2023-11-06 17:33:38 -07:00
|
|
|
|
-- Create some unused namespaces
|
2024-01-12 10:59:57 -07:00
|
|
|
|
api.nvim_create_namespace('unused1')
|
|
|
|
|
api.nvim_create_namespace('unused2')
|
|
|
|
|
api.nvim_create_namespace('unused3')
|
|
|
|
|
api.nvim_create_namespace('unused4')
|
2023-11-06 17:33:38 -07:00
|
|
|
|
|
2021-08-22 18:26:35 -07:00
|
|
|
|
insert([[hello world]])
|
2020-08-14 07:03:17 -07:00
|
|
|
|
|
|
|
|
|
exec_lua [[
|
2021-08-22 18:26:35 -07:00
|
|
|
|
keys = {}
|
2020-08-14 07:03:17 -07:00
|
|
|
|
|
2021-08-22 18:26:35 -07:00
|
|
|
|
return vim.on_key(function(buf)
|
2020-08-14 07:03:17 -07:00
|
|
|
|
if buf:byte() == 27 then
|
|
|
|
|
buf = "<ESC>"
|
|
|
|
|
end
|
|
|
|
|
|
2021-08-22 18:26:35 -07:00
|
|
|
|
table.insert(keys, buf)
|
2020-08-14 07:03:17 -07:00
|
|
|
|
end, vim.api.nvim_create_namespace("logger"))
|
|
|
|
|
]]
|
|
|
|
|
|
2021-08-22 18:26:35 -07:00
|
|
|
|
insert([[next lines]])
|
2020-08-14 07:03:17 -07:00
|
|
|
|
|
2021-08-22 18:26:35 -07:00
|
|
|
|
eq(1, exec_lua('return vim.on_key()'))
|
|
|
|
|
exec_lua("vim.on_key(nil, vim.api.nvim_create_namespace('logger'))")
|
|
|
|
|
eq(0, exec_lua('return vim.on_key()'))
|
2020-08-14 07:03:17 -07:00
|
|
|
|
|
2021-08-22 18:26:35 -07:00
|
|
|
|
insert([[more lines]])
|
2020-08-14 07:03:17 -07:00
|
|
|
|
|
|
|
|
|
-- It has escape in the keys pressed
|
2021-08-22 18:26:35 -07:00
|
|
|
|
eq('inext lines<ESC>', exec_lua [[return table.concat(keys, '')]])
|
2020-08-14 07:03:17 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2024-11-01 19:11:06 -07:00
|
|
|
|
it('skips any function that caused an error and shows stacktrace', function()
|
2021-08-22 18:26:35 -07:00
|
|
|
|
insert([[hello world]])
|
2020-08-14 07:03:17 -07:00
|
|
|
|
|
|
|
|
|
exec_lua [[
|
2024-11-01 19:11:06 -07:00
|
|
|
|
local function ErrF2()
|
|
|
|
|
error("Dumb Error")
|
|
|
|
|
end
|
|
|
|
|
local function ErrF1()
|
|
|
|
|
ErrF2()
|
|
|
|
|
end
|
|
|
|
|
|
2021-08-22 18:26:35 -07:00
|
|
|
|
keys = {}
|
2020-08-14 07:03:17 -07:00
|
|
|
|
|
2021-08-22 18:26:35 -07:00
|
|
|
|
return vim.on_key(function(buf)
|
2020-08-14 07:03:17 -07:00
|
|
|
|
if buf:byte() == 27 then
|
|
|
|
|
buf = "<ESC>"
|
|
|
|
|
end
|
|
|
|
|
|
2021-08-22 18:26:35 -07:00
|
|
|
|
table.insert(keys, buf)
|
2020-08-14 07:03:17 -07:00
|
|
|
|
|
|
|
|
|
if buf == 'l' then
|
2024-11-01 19:11:06 -07:00
|
|
|
|
ErrF1()
|
2020-08-14 07:03:17 -07:00
|
|
|
|
end
|
|
|
|
|
end)
|
|
|
|
|
]]
|
|
|
|
|
|
2021-08-22 18:26:35 -07:00
|
|
|
|
insert([[next lines]])
|
|
|
|
|
insert([[more lines]])
|
2020-08-14 07:03:17 -07:00
|
|
|
|
|
|
|
|
|
-- Only the first letter gets added. After that we remove the callback
|
2021-08-22 18:26:35 -07:00
|
|
|
|
eq('inext l', exec_lua [[ return table.concat(keys, '') ]])
|
2024-11-01 19:11:06 -07:00
|
|
|
|
|
|
|
|
|
local errmsg = api.nvim_get_vvar('errmsg')
|
|
|
|
|
matches(
|
|
|
|
|
[[
|
|
|
|
|
^Error executing vim%.on%_key%(%) callbacks:.*
|
|
|
|
|
With ns%_id %d+: .*: Dumb Error
|
|
|
|
|
stack traceback:
|
|
|
|
|
.*: in function 'error'
|
|
|
|
|
.*: in function 'ErrF2'
|
|
|
|
|
.*: in function 'ErrF1'
|
|
|
|
|
.*]],
|
|
|
|
|
errmsg
|
|
|
|
|
)
|
2020-08-14 07:03:17 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2024-03-30 20:20:05 -07:00
|
|
|
|
it('argument 1 is keys after mapping, argument 2 is typed keys', function()
|
2020-08-14 07:03:17 -07:00
|
|
|
|
exec_lua [[
|
2021-08-22 18:26:35 -07:00
|
|
|
|
keys = {}
|
2024-03-30 20:20:05 -07:00
|
|
|
|
typed = {}
|
2020-08-14 07:03:17 -07:00
|
|
|
|
|
|
|
|
|
vim.cmd("inoremap hello world")
|
|
|
|
|
|
2024-03-30 20:20:05 -07:00
|
|
|
|
vim.on_key(function(buf, typed_buf)
|
2020-08-14 07:03:17 -07:00
|
|
|
|
if buf:byte() == 27 then
|
|
|
|
|
buf = "<ESC>"
|
|
|
|
|
end
|
2024-03-30 20:20:05 -07:00
|
|
|
|
if typed_buf:byte() == 27 then
|
|
|
|
|
typed_buf = "<ESC>"
|
|
|
|
|
end
|
2020-08-14 07:03:17 -07:00
|
|
|
|
|
2021-08-22 18:26:35 -07:00
|
|
|
|
table.insert(keys, buf)
|
2024-03-30 20:20:05 -07:00
|
|
|
|
table.insert(typed, typed_buf)
|
2020-08-14 07:03:17 -07:00
|
|
|
|
end)
|
|
|
|
|
]]
|
2021-08-22 18:26:35 -07:00
|
|
|
|
insert('hello')
|
2020-08-14 07:03:17 -07:00
|
|
|
|
|
2021-08-22 18:26:35 -07:00
|
|
|
|
eq('iworld<ESC>', exec_lua [[return table.concat(keys, '')]])
|
2024-03-30 20:20:05 -07:00
|
|
|
|
eq('ihello<ESC>', exec_lua [[return table.concat(typed, '')]])
|
2020-08-14 07:03:17 -07:00
|
|
|
|
end)
|
2022-06-16 03:51:36 -07:00
|
|
|
|
|
|
|
|
|
it('can call vim.fn functions on Ctrl-C #17273', function()
|
|
|
|
|
exec_lua([[
|
|
|
|
|
_G.ctrl_c_cmdtype = ''
|
|
|
|
|
|
|
|
|
|
vim.on_key(function(c)
|
|
|
|
|
if c == '\3' then
|
|
|
|
|
_G.ctrl_c_cmdtype = vim.fn.getcmdtype()
|
|
|
|
|
end
|
|
|
|
|
end)
|
|
|
|
|
]])
|
|
|
|
|
feed('/')
|
|
|
|
|
poke_eventloop() -- This is needed because Ctrl-C flushes input
|
|
|
|
|
feed('<C-C>')
|
|
|
|
|
eq('/', exec_lua([[return _G.ctrl_c_cmdtype]]))
|
|
|
|
|
end)
|
2024-10-11 17:07:05 -07:00
|
|
|
|
|
|
|
|
|
it('callback is not invoked recursively #30752', function()
|
|
|
|
|
local screen = Screen.new(60, 10)
|
|
|
|
|
exec_lua([[
|
|
|
|
|
vim.on_key(function(key, typed)
|
|
|
|
|
vim.api.nvim_echo({
|
|
|
|
|
{ 'key_cb\n' },
|
|
|
|
|
{ ("KEYCB: key '%s', typed '%s'\n"):format(key, typed) },
|
|
|
|
|
}, false, {})
|
|
|
|
|
end)
|
|
|
|
|
]])
|
|
|
|
|
feed('^')
|
|
|
|
|
screen:expect([[
|
|
|
|
|
|
|
|
|
|
|
{1:~ }|*5
|
|
|
|
|
{3: }|
|
|
|
|
|
key_cb |
|
|
|
|
|
KEYCB: key '^', typed '^' |
|
|
|
|
|
{6:Press ENTER or type command to continue}^ |
|
|
|
|
|
]])
|
|
|
|
|
feed('<C-C>')
|
|
|
|
|
screen:expect([[
|
|
|
|
|
|
|
|
|
|
|
{1:~ }|*3
|
|
|
|
|
{3: }|
|
|
|
|
|
key_cb |
|
|
|
|
|
KEYCB: key '^', typed '^' |
|
|
|
|
|
key_cb |
|
|
|
|
|
KEYCB: key '{18:^C}', typed '{18:^C}' |
|
|
|
|
|
{6:Press ENTER or type command to continue}^ |
|
|
|
|
|
]])
|
|
|
|
|
feed('<C-C>')
|
|
|
|
|
screen:expect([[
|
|
|
|
|
^ |
|
|
|
|
|
{1:~ }|*8
|
|
|
|
|
|
|
|
|
|
|
]])
|
|
|
|
|
end)
|
2024-10-31 18:11:15 -07:00
|
|
|
|
|
|
|
|
|
it('can discard input', function()
|
|
|
|
|
clear()
|
|
|
|
|
-- discard every other normal 'x' command
|
|
|
|
|
exec_lua [[
|
|
|
|
|
n_key = 0
|
|
|
|
|
|
|
|
|
|
vim.on_key(function(buf, typed_buf)
|
|
|
|
|
if typed_buf == 'x' then
|
|
|
|
|
n_key = n_key + 1
|
|
|
|
|
end
|
|
|
|
|
return (n_key % 2 == 0) and "" or nil
|
|
|
|
|
end)
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
api.nvim_buf_set_lines(0, 0, -1, true, { '54321' })
|
|
|
|
|
|
|
|
|
|
feed('x')
|
|
|
|
|
expect('4321')
|
|
|
|
|
feed('x')
|
|
|
|
|
expect('4321')
|
|
|
|
|
feed('x')
|
|
|
|
|
expect('321')
|
|
|
|
|
feed('x')
|
|
|
|
|
expect('321')
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('callback invalid return', function()
|
|
|
|
|
clear()
|
|
|
|
|
-- second key produces an error which removes the callback
|
|
|
|
|
exec_lua [[
|
|
|
|
|
n_call = 0
|
2024-11-01 19:11:06 -07:00
|
|
|
|
|
2024-10-31 18:11:15 -07:00
|
|
|
|
vim.on_key(function(buf, typed_buf)
|
|
|
|
|
if typed_buf == 'x' then
|
|
|
|
|
n_call = n_call + 1
|
|
|
|
|
end
|
|
|
|
|
return n_call >= 2 and '!' or nil
|
|
|
|
|
end)
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
api.nvim_buf_set_lines(0, 0, -1, true, { '54321' })
|
|
|
|
|
|
|
|
|
|
local function cleanup_msg(msg)
|
2024-11-01 19:11:06 -07:00
|
|
|
|
return msg:gsub('^Error .*\nWith ns%_id %d+: ', '')
|
2024-10-31 18:11:15 -07:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
feed('x')
|
|
|
|
|
eq(1, exec_lua [[ return n_call ]])
|
|
|
|
|
|
|
|
|
|
eq(1, exec_lua [[ return vim.on_key(nil, nil) ]])
|
|
|
|
|
|
|
|
|
|
eq('', cleanup_msg(eval('v:errmsg')))
|
|
|
|
|
feed('x')
|
|
|
|
|
eq(2, exec_lua [[ return n_call ]])
|
|
|
|
|
eq('return string must be empty', cleanup_msg(eval('v:errmsg')))
|
|
|
|
|
command('let v:errmsg = ""')
|
|
|
|
|
|
|
|
|
|
eq(0, exec_lua [[ return vim.on_key(nil, nil) ]])
|
|
|
|
|
|
|
|
|
|
feed('x')
|
|
|
|
|
eq(2, exec_lua [[ return n_call ]])
|
|
|
|
|
expect('21')
|
|
|
|
|
eq('', cleanup_msg(eval('v:errmsg')))
|
|
|
|
|
end)
|
2020-08-14 07:03:17 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2020-05-20 08:08:19 -07:00
|
|
|
|
describe('vim.wait', function()
|
|
|
|
|
before_each(function()
|
|
|
|
|
exec_lua [[
|
|
|
|
|
-- high precision timer
|
|
|
|
|
get_time = function()
|
|
|
|
|
return vim.fn.reltimefloat(vim.fn.reltime())
|
|
|
|
|
end
|
|
|
|
|
]]
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('runs from lua', function()
|
2020-05-20 08:08:19 -07:00
|
|
|
|
exec_lua [[vim.wait(100, function() return true end)]]
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('waits the expected time if false', function()
|
2020-05-20 08:08:19 -07:00
|
|
|
|
eq(
|
|
|
|
|
{ time = true, wait_result = { false, -1 } },
|
|
|
|
|
exec_lua [[
|
|
|
|
|
start_time = get_time()
|
|
|
|
|
wait_succeed, wait_fail_val = vim.wait(200, function() return false end)
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
-- 150ms waiting or more results in true. Flaky tests are bad.
|
|
|
|
|
time = (start_time + 0.15) < get_time(),
|
|
|
|
|
wait_result = {wait_succeed, wait_fail_val}
|
|
|
|
|
}
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('does not block other events', function()
|
2020-05-20 08:08:19 -07:00
|
|
|
|
eq(
|
|
|
|
|
{ time = true, wait_result = true },
|
|
|
|
|
exec_lua [[
|
|
|
|
|
start_time = get_time()
|
|
|
|
|
|
|
|
|
|
vim.g.timer_result = false
|
2023-06-03 03:06:00 -07:00
|
|
|
|
timer = vim.uv.new_timer()
|
2020-05-20 08:08:19 -07:00
|
|
|
|
timer:start(100, 0, vim.schedule_wrap(function()
|
|
|
|
|
vim.g.timer_result = true
|
|
|
|
|
end))
|
|
|
|
|
|
|
|
|
|
-- Would wait ten seconds if results blocked.
|
|
|
|
|
wait_result = vim.wait(10000, function() return vim.g.timer_result end)
|
|
|
|
|
|
2021-09-19 09:50:24 -07:00
|
|
|
|
timer:close()
|
|
|
|
|
|
2020-05-20 08:08:19 -07:00
|
|
|
|
return {
|
|
|
|
|
time = (start_time + 5) > get_time(),
|
|
|
|
|
wait_result = wait_result,
|
|
|
|
|
}
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('does not process non-fast events when commanded', function()
|
2020-10-06 09:58:05 -07:00
|
|
|
|
eq(
|
|
|
|
|
{ wait_result = false },
|
|
|
|
|
exec_lua [[
|
|
|
|
|
start_time = get_time()
|
|
|
|
|
|
|
|
|
|
vim.g.timer_result = false
|
2023-06-03 03:06:00 -07:00
|
|
|
|
timer = vim.uv.new_timer()
|
2020-10-06 09:58:05 -07:00
|
|
|
|
timer:start(100, 0, vim.schedule_wrap(function()
|
|
|
|
|
vim.g.timer_result = true
|
|
|
|
|
end))
|
|
|
|
|
|
|
|
|
|
wait_result = vim.wait(300, function() return vim.g.timer_result end, nil, true)
|
|
|
|
|
|
2021-09-19 09:50:24 -07:00
|
|
|
|
timer:close()
|
|
|
|
|
|
2020-10-06 09:58:05 -07:00
|
|
|
|
return {
|
|
|
|
|
wait_result = wait_result,
|
|
|
|
|
}
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
2023-11-10 00:24:36 -07:00
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('works with vim.defer_fn', function()
|
2020-05-20 08:08:19 -07:00
|
|
|
|
eq(
|
|
|
|
|
{ time = true, wait_result = true },
|
|
|
|
|
exec_lua [[
|
|
|
|
|
start_time = get_time()
|
|
|
|
|
|
|
|
|
|
vim.defer_fn(function() vim.g.timer_result = true end, 100)
|
|
|
|
|
wait_result = vim.wait(10000, function() return vim.g.timer_result end)
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
time = (start_time + 5) > get_time(),
|
|
|
|
|
wait_result = wait_result,
|
|
|
|
|
}
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('does not crash when callback errors', function()
|
2021-11-06 07:26:10 -07:00
|
|
|
|
local result = exec_lua [[
|
2020-10-06 09:58:05 -07:00
|
|
|
|
return {pcall(function() vim.wait(1000, function() error("As Expected") end) end)}
|
2021-11-06 07:26:10 -07:00
|
|
|
|
]]
|
|
|
|
|
eq({ false, '[string "<nvim>"]:1: As Expected' }, { result[1], remove_trace(result[2]) })
|
2020-05-20 08:08:19 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2020-10-06 09:58:05 -07:00
|
|
|
|
it('if callback is passed, it must be a function', function()
|
2020-11-04 02:41:22 -07:00
|
|
|
|
eq(
|
|
|
|
|
{ false, 'vim.wait: if passed, condition must be a function' },
|
|
|
|
|
exec_lua [[
|
2020-10-06 09:58:05 -07:00
|
|
|
|
return {pcall(function() vim.wait(1000, 13) end)}
|
2020-11-04 02:41:22 -07:00
|
|
|
|
]]
|
|
|
|
|
)
|
2020-10-06 09:58:05 -07:00
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows waiting with no callback, explicit', function()
|
2020-10-06 09:58:05 -07:00
|
|
|
|
eq(
|
|
|
|
|
true,
|
|
|
|
|
exec_lua [[
|
2023-06-03 03:06:00 -07:00
|
|
|
|
local start_time = vim.uv.hrtime()
|
2020-10-06 09:58:05 -07:00
|
|
|
|
vim.wait(50, nil)
|
2023-06-03 03:06:00 -07:00
|
|
|
|
return vim.uv.hrtime() - start_time > 25000
|
2020-10-06 09:58:05 -07:00
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('allows waiting with no callback, implicit', function()
|
2020-10-06 09:58:05 -07:00
|
|
|
|
eq(
|
|
|
|
|
true,
|
|
|
|
|
exec_lua [[
|
2023-06-03 03:06:00 -07:00
|
|
|
|
local start_time = vim.uv.hrtime()
|
2020-10-06 09:58:05 -07:00
|
|
|
|
vim.wait(50)
|
2023-06-03 03:06:00 -07:00
|
|
|
|
return vim.uv.hrtime() - start_time > 25000
|
2020-10-06 09:58:05 -07:00
|
|
|
|
]]
|
|
|
|
|
)
|
2020-05-20 08:08:19 -07:00
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('calls callbacks exactly once if they return true immediately', function()
|
2020-05-20 08:08:19 -07:00
|
|
|
|
eq(
|
|
|
|
|
true,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.g.wait_count = 0
|
|
|
|
|
vim.wait(1000, function()
|
|
|
|
|
vim.g.wait_count = vim.g.wait_count + 1
|
|
|
|
|
return true
|
|
|
|
|
end, 20)
|
|
|
|
|
return vim.g.wait_count == 1
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('calls callbacks few times with large `interval`', function()
|
2020-05-20 08:08:19 -07:00
|
|
|
|
eq(
|
|
|
|
|
true,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.g.wait_count = 0
|
|
|
|
|
vim.wait(50, function() vim.g.wait_count = vim.g.wait_count + 1 end, 200)
|
|
|
|
|
return vim.g.wait_count < 5
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('plays nice with `not` when fails', function()
|
2020-05-20 08:08:19 -07:00
|
|
|
|
eq(
|
|
|
|
|
true,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
if not vim.wait(50, function() end) then
|
|
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('plays nice with `if` when success', function()
|
2020-05-20 08:08:19 -07:00
|
|
|
|
eq(
|
|
|
|
|
true,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
if vim.wait(50, function() return true end) then
|
|
|
|
|
return true
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('returns immediately with false if timeout is 0', function()
|
2020-05-20 08:08:19 -07:00
|
|
|
|
eq(
|
|
|
|
|
{ false, -1 },
|
|
|
|
|
exec_lua [[
|
|
|
|
|
return {
|
|
|
|
|
vim.wait(0, function() return false end)
|
|
|
|
|
}
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('works with tables with __call', function()
|
2020-05-20 08:08:19 -07:00
|
|
|
|
eq(
|
|
|
|
|
true,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
local t = setmetatable({}, {__call = function(...) return true end})
|
|
|
|
|
return vim.wait(100, t, 10)
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('works with tables with __call that change', function()
|
2020-05-20 08:08:19 -07:00
|
|
|
|
eq(
|
|
|
|
|
true,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
local t = {count = 0}
|
|
|
|
|
setmetatable(t, {
|
|
|
|
|
__call = function()
|
|
|
|
|
t.count = t.count + 1
|
|
|
|
|
return t.count > 3
|
|
|
|
|
end
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return vim.wait(1000, t, 10)
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('fails with negative intervals', function()
|
2020-05-20 08:08:19 -07:00
|
|
|
|
local pcall_result = exec_lua [[
|
|
|
|
|
return pcall(function() vim.wait(1000, function() return false end, -1) end)
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq(false, pcall_result)
|
|
|
|
|
end)
|
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('fails with weird intervals', function()
|
2020-05-20 08:08:19 -07:00
|
|
|
|
local pcall_result = exec_lua [[
|
|
|
|
|
return pcall(function() vim.wait(1000, function() return false end, 'a string value') end)
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
eq(false, pcall_result)
|
|
|
|
|
end)
|
2022-07-18 18:11:13 -07:00
|
|
|
|
|
|
|
|
|
describe('returns -2 when interrupted', function()
|
|
|
|
|
before_each(function()
|
2024-02-12 06:50:39 -07:00
|
|
|
|
local channel = api.nvim_get_chan_info(0).id
|
2024-01-12 10:59:57 -07:00
|
|
|
|
api.nvim_set_var('channel', channel)
|
2022-07-18 18:11:13 -07:00
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('without callback', function()
|
|
|
|
|
exec_lua([[
|
|
|
|
|
function _G.Wait()
|
|
|
|
|
vim.rpcnotify(vim.g.channel, 'ready')
|
|
|
|
|
local _, interrupted = vim.wait(4000)
|
|
|
|
|
vim.rpcnotify(vim.g.channel, 'wait', interrupted)
|
|
|
|
|
end
|
|
|
|
|
]])
|
|
|
|
|
feed(':lua _G.Wait()<CR>')
|
|
|
|
|
eq({ 'notification', 'ready', {} }, next_msg(500))
|
|
|
|
|
feed('<C-C>')
|
|
|
|
|
eq({ 'notification', 'wait', { -2 } }, next_msg(500))
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('with callback', function()
|
|
|
|
|
exec_lua([[
|
|
|
|
|
function _G.Wait()
|
|
|
|
|
vim.rpcnotify(vim.g.channel, 'ready')
|
|
|
|
|
local _, interrupted = vim.wait(4000, function() end)
|
|
|
|
|
vim.rpcnotify(vim.g.channel, 'wait', interrupted)
|
|
|
|
|
end
|
|
|
|
|
]])
|
|
|
|
|
feed(':lua _G.Wait()<CR>')
|
|
|
|
|
eq({ 'notification', 'ready', {} }, next_msg(500))
|
|
|
|
|
feed('<C-C>')
|
|
|
|
|
eq({ 'notification', 'wait', { -2 } }, next_msg(500))
|
|
|
|
|
end)
|
|
|
|
|
end)
|
2023-11-21 04:24:30 -07:00
|
|
|
|
|
refactor(api)!: rename Dictionary => Dict
In the api_info() output:
:new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val')
...
{'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1}
The `ArrayOf(Integer, 2)` return type didn't break clients when we added
it, which is evidence that clients don't use the `return_type` field,
thus renaming Dictionary => Dict in api_info() is not (in practice)
a breaking change.
2024-09-19 22:34:50 -07:00
|
|
|
|
it('fails in fast callbacks #26122', function()
|
2023-11-27 03:24:32 -07:00
|
|
|
|
local screen = Screen.new(80, 10)
|
2023-11-21 04:24:30 -07:00
|
|
|
|
exec_lua([[
|
2023-11-27 03:24:32 -07:00
|
|
|
|
local timer = vim.uv.new_timer()
|
|
|
|
|
timer:start(0, 0, function()
|
|
|
|
|
timer:close()
|
|
|
|
|
vim.wait(100, function() end)
|
2023-11-21 04:24:30 -07:00
|
|
|
|
end)
|
|
|
|
|
]])
|
2023-11-27 03:24:32 -07:00
|
|
|
|
screen:expect({
|
2024-06-20 05:48:06 -07:00
|
|
|
|
any = pesc('E5560: vim.wait must not be called in a fast event context'),
|
2023-11-27 03:24:32 -07:00
|
|
|
|
})
|
|
|
|
|
feed('<CR>')
|
2023-11-21 04:24:30 -07:00
|
|
|
|
assert_alive()
|
|
|
|
|
end)
|
2020-05-18 06:49:50 -07:00
|
|
|
|
end)
|
2020-09-09 01:37:42 -07:00
|
|
|
|
|
2022-01-06 11:10:56 -07:00
|
|
|
|
it('vim.notify_once', function()
|
|
|
|
|
local screen = Screen.new(60, 5)
|
|
|
|
|
screen:expect {
|
|
|
|
|
grid = [[
|
|
|
|
|
^ |
|
2024-08-14 04:42:05 -07:00
|
|
|
|
{1:~ }|*3
|
2022-01-06 11:10:56 -07:00
|
|
|
|
|
|
|
|
|
|
]],
|
|
|
|
|
}
|
|
|
|
|
exec_lua [[vim.notify_once("I'll only tell you this once...", vim.log.levels.WARN)]]
|
|
|
|
|
screen:expect {
|
|
|
|
|
grid = [[
|
|
|
|
|
^ |
|
2024-08-14 04:42:05 -07:00
|
|
|
|
{1:~ }|*3
|
|
|
|
|
{19:I'll only tell you this once...} |
|
2022-01-06 11:10:56 -07:00
|
|
|
|
]],
|
|
|
|
|
}
|
|
|
|
|
feed('<C-l>')
|
|
|
|
|
screen:expect {
|
|
|
|
|
grid = [[
|
|
|
|
|
^ |
|
2024-08-14 04:42:05 -07:00
|
|
|
|
{1:~ }|*3
|
2022-01-06 11:10:56 -07:00
|
|
|
|
|
|
|
|
|
|
]],
|
|
|
|
|
}
|
|
|
|
|
exec_lua [[vim.notify_once("I'll only tell you this once...")]]
|
|
|
|
|
screen:expect_unchanged()
|
|
|
|
|
end)
|
|
|
|
|
|
2021-08-07 12:17:45 -07:00
|
|
|
|
describe('vim.schedule_wrap', function()
|
|
|
|
|
it('preserves argument lists', function()
|
|
|
|
|
exec_lua [[
|
|
|
|
|
local fun = vim.schedule_wrap(function(kling, klang, klonk)
|
|
|
|
|
vim.rpcnotify(1, 'mayday_mayday', {a=kling, b=klang, c=klonk})
|
|
|
|
|
end)
|
|
|
|
|
fun("BOB", nil, "MIKE")
|
|
|
|
|
]]
|
|
|
|
|
eq({ 'notification', 'mayday_mayday', { { a = 'BOB', c = 'MIKE' } } }, next_msg())
|
|
|
|
|
|
|
|
|
|
-- let's gooooo
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.schedule_wrap(function(...) vim.rpcnotify(1, 'boogalo', select('#', ...)) end)(nil,nil,nil,nil)
|
|
|
|
|
]]
|
|
|
|
|
eq({ 'notification', 'boogalo', { 4 } }, next_msg())
|
|
|
|
|
end)
|
|
|
|
|
end)
|
|
|
|
|
|
2020-09-09 01:37:42 -07:00
|
|
|
|
describe('vim.api.nvim_buf_call', function()
|
|
|
|
|
it('can access buf options', function()
|
2024-01-16 06:26:21 -07:00
|
|
|
|
local buf1 = api.nvim_get_current_buf()
|
2020-09-09 01:37:42 -07:00
|
|
|
|
local buf2 = exec_lua [[
|
|
|
|
|
buf2 = vim.api.nvim_create_buf(false, true)
|
|
|
|
|
return buf2
|
|
|
|
|
]]
|
|
|
|
|
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(false, api.nvim_get_option_value('autoindent', { buf = buf1 }))
|
|
|
|
|
eq(false, api.nvim_get_option_value('autoindent', { buf = buf2 }))
|
2020-09-09 01:37:42 -07:00
|
|
|
|
|
|
|
|
|
local val = exec_lua [[
|
|
|
|
|
return vim.api.nvim_buf_call(buf2, function()
|
|
|
|
|
vim.cmd "set autoindent"
|
|
|
|
|
return vim.api.nvim_get_current_buf()
|
|
|
|
|
end)
|
|
|
|
|
]]
|
|
|
|
|
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq(false, api.nvim_get_option_value('autoindent', { buf = buf1 }))
|
|
|
|
|
eq(true, api.nvim_get_option_value('autoindent', { buf = buf2 }))
|
2024-01-16 06:26:21 -07:00
|
|
|
|
eq(buf1, api.nvim_get_current_buf())
|
2020-09-09 01:37:42 -07:00
|
|
|
|
eq(buf2, val)
|
|
|
|
|
end)
|
2022-01-07 10:33:01 -07:00
|
|
|
|
|
|
|
|
|
it('does not cause ml_get errors with invalid visual selection', function()
|
|
|
|
|
-- Should be fixed by vim-patch:8.2.4028.
|
|
|
|
|
exec_lua [[
|
2023-04-05 09:19:53 -07:00
|
|
|
|
local api = vim.api
|
|
|
|
|
local t = function(s) return api.nvim_replace_termcodes(s, true, true, true) end
|
|
|
|
|
api.nvim_buf_set_lines(0, 0, -1, true, {"a", "b", "c"})
|
|
|
|
|
api.nvim_feedkeys(t "G<C-V>", "txn", false)
|
|
|
|
|
api.nvim_buf_call(api.nvim_create_buf(false, true), function() vim.cmd "redraw" end)
|
2022-01-07 10:33:01 -07:00
|
|
|
|
]]
|
|
|
|
|
end)
|
2022-12-02 05:39:24 -07:00
|
|
|
|
|
|
|
|
|
it('can be nested crazily with hidden buffers', function()
|
|
|
|
|
eq(
|
|
|
|
|
true,
|
|
|
|
|
exec_lua([[
|
|
|
|
|
local function scratch_buf_call(fn)
|
|
|
|
|
local buf = vim.api.nvim_create_buf(false, true)
|
2022-12-19 09:37:45 -07:00
|
|
|
|
vim.api.nvim_set_option_value('cindent', true, {buf = buf})
|
2022-12-02 05:39:24 -07:00
|
|
|
|
return vim.api.nvim_buf_call(buf, function()
|
|
|
|
|
return vim.api.nvim_get_current_buf() == buf
|
2022-12-19 09:37:45 -07:00
|
|
|
|
and vim.api.nvim_get_option_value('cindent', {buf = buf})
|
2022-12-02 05:39:24 -07:00
|
|
|
|
and fn()
|
|
|
|
|
end) and vim.api.nvim_buf_delete(buf, {}) == nil
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return scratch_buf_call(function()
|
|
|
|
|
return scratch_buf_call(function()
|
|
|
|
|
return scratch_buf_call(function()
|
|
|
|
|
return scratch_buf_call(function()
|
|
|
|
|
return scratch_buf_call(function()
|
|
|
|
|
return scratch_buf_call(function()
|
|
|
|
|
return scratch_buf_call(function()
|
|
|
|
|
return scratch_buf_call(function()
|
|
|
|
|
return scratch_buf_call(function()
|
|
|
|
|
return scratch_buf_call(function()
|
|
|
|
|
return scratch_buf_call(function()
|
|
|
|
|
return scratch_buf_call(function()
|
|
|
|
|
return true
|
|
|
|
|
end)
|
|
|
|
|
end)
|
|
|
|
|
end)
|
|
|
|
|
end)
|
|
|
|
|
end)
|
|
|
|
|
end)
|
|
|
|
|
end)
|
|
|
|
|
end)
|
|
|
|
|
end)
|
|
|
|
|
end)
|
|
|
|
|
end)
|
|
|
|
|
end)
|
|
|
|
|
]])
|
2024-01-02 18:09:18 -07:00
|
|
|
|
)
|
2022-12-02 05:39:24 -07:00
|
|
|
|
end)
|
2024-02-11 07:46:14 -07:00
|
|
|
|
|
|
|
|
|
it('can return values by reference', function()
|
|
|
|
|
eq(
|
|
|
|
|
{ 4, 7 },
|
|
|
|
|
exec_lua [[
|
|
|
|
|
local val = {4, 10}
|
|
|
|
|
local ref = vim.api.nvim_buf_call(0, function() return val end)
|
|
|
|
|
ref[2] = 7
|
|
|
|
|
return val
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
2020-09-09 01:37:42 -07:00
|
|
|
|
end)
|
2021-06-03 17:47:43 -07:00
|
|
|
|
|
|
|
|
|
describe('vim.api.nvim_win_call', function()
|
|
|
|
|
it('can access window options', function()
|
|
|
|
|
command('vsplit')
|
2024-01-16 06:26:21 -07:00
|
|
|
|
local win1 = api.nvim_get_current_win()
|
2021-06-03 17:47:43 -07:00
|
|
|
|
command('wincmd w')
|
|
|
|
|
local win2 = exec_lua [[
|
|
|
|
|
win2 = vim.api.nvim_get_current_win()
|
|
|
|
|
return win2
|
|
|
|
|
]]
|
|
|
|
|
command('wincmd p')
|
|
|
|
|
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq('', api.nvim_get_option_value('winhighlight', { win = win1 }))
|
|
|
|
|
eq('', api.nvim_get_option_value('winhighlight', { win = win2 }))
|
2021-06-03 17:47:43 -07:00
|
|
|
|
|
|
|
|
|
local val = exec_lua [[
|
|
|
|
|
return vim.api.nvim_win_call(win2, function()
|
|
|
|
|
vim.cmd "setlocal winhighlight=Normal:Normal"
|
|
|
|
|
return vim.api.nvim_get_current_win()
|
|
|
|
|
end)
|
|
|
|
|
]]
|
|
|
|
|
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq('', api.nvim_get_option_value('winhighlight', { win = win1 }))
|
|
|
|
|
eq('Normal:Normal', api.nvim_get_option_value('winhighlight', { win = win2 }))
|
2024-01-16 06:26:21 -07:00
|
|
|
|
eq(win1, api.nvim_get_current_win())
|
2021-06-03 17:47:43 -07:00
|
|
|
|
eq(win2, val)
|
|
|
|
|
end)
|
2022-01-08 05:27:35 -07:00
|
|
|
|
|
|
|
|
|
it('does not cause ml_get errors with invalid visual selection', function()
|
|
|
|
|
-- Add lines to the current buffer and make another window looking into an empty buffer.
|
|
|
|
|
exec_lua [[
|
2023-04-05 09:19:53 -07:00
|
|
|
|
_G.api = vim.api
|
|
|
|
|
_G.t = function(s) return api.nvim_replace_termcodes(s, true, true, true) end
|
|
|
|
|
_G.win_lines = api.nvim_get_current_win()
|
2022-01-08 05:27:35 -07:00
|
|
|
|
vim.cmd "new"
|
2023-04-05 09:19:53 -07:00
|
|
|
|
_G.win_empty = api.nvim_get_current_win()
|
|
|
|
|
api.nvim_set_current_win(win_lines)
|
|
|
|
|
api.nvim_buf_set_lines(0, 0, -1, true, {"a", "b", "c"})
|
2022-01-08 05:27:35 -07:00
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
-- Start Visual in current window, redraw in other window with fewer lines.
|
|
|
|
|
-- Should be fixed by vim-patch:8.2.4018.
|
|
|
|
|
exec_lua [[
|
2023-04-05 09:19:53 -07:00
|
|
|
|
api.nvim_feedkeys(t "G<C-V>", "txn", false)
|
|
|
|
|
api.nvim_win_call(win_empty, function() vim.cmd "redraw" end)
|
2022-01-08 05:27:35 -07:00
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
-- Start Visual in current window, extend it in other window with more lines.
|
|
|
|
|
-- Fixed for win_execute by vim-patch:8.2.4026, but nvim_win_call should also not be affected.
|
|
|
|
|
exec_lua [[
|
2023-04-05 09:19:53 -07:00
|
|
|
|
api.nvim_feedkeys(t "<Esc>gg", "txn", false)
|
|
|
|
|
api.nvim_set_current_win(win_empty)
|
|
|
|
|
api.nvim_feedkeys(t "gg<C-V>", "txn", false)
|
|
|
|
|
api.nvim_win_call(win_lines, function() api.nvim_feedkeys(t "G<C-V>", "txn", false) end)
|
2022-01-08 05:27:35 -07:00
|
|
|
|
vim.cmd "redraw"
|
|
|
|
|
]]
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('updates ruler if cursor moved', function()
|
|
|
|
|
-- Fixed for win_execute in vim-patch:8.1.2124, but should've applied to nvim_win_call too!
|
|
|
|
|
local screen = Screen.new(30, 5)
|
|
|
|
|
exec_lua [[
|
2023-04-05 09:19:53 -07:00
|
|
|
|
_G.api = vim.api
|
2022-01-08 05:27:35 -07:00
|
|
|
|
vim.opt.ruler = true
|
|
|
|
|
local lines = {}
|
|
|
|
|
for i = 0, 499 do lines[#lines + 1] = tostring(i) end
|
2023-04-05 09:19:53 -07:00
|
|
|
|
api.nvim_buf_set_lines(0, 0, -1, true, lines)
|
|
|
|
|
api.nvim_win_set_cursor(0, {20, 0})
|
2022-01-08 05:27:35 -07:00
|
|
|
|
vim.cmd "split"
|
2023-04-05 09:19:53 -07:00
|
|
|
|
_G.win = api.nvim_get_current_win()
|
2022-01-08 05:27:35 -07:00
|
|
|
|
vim.cmd "wincmd w | redraw"
|
|
|
|
|
]]
|
|
|
|
|
screen:expect [[
|
|
|
|
|
19 |
|
|
|
|
|
{2:[No Name] [+] 20,1 3%}|
|
2024-08-14 04:42:05 -07:00
|
|
|
|
^19 |
|
|
|
|
|
{3:[No Name] [+] 20,1 3%}|
|
2022-01-08 05:27:35 -07:00
|
|
|
|
|
|
|
|
|
|
]]
|
|
|
|
|
exec_lua [[
|
2023-04-05 09:19:53 -07:00
|
|
|
|
api.nvim_win_call(win, function() api.nvim_win_set_cursor(0, {100, 0}) end)
|
2022-01-08 05:27:35 -07:00
|
|
|
|
vim.cmd "redraw"
|
|
|
|
|
]]
|
|
|
|
|
screen:expect [[
|
|
|
|
|
99 |
|
2024-08-14 04:42:05 -07:00
|
|
|
|
{2:[No Name] [+] 100,1 19%}|
|
2022-01-08 05:27:35 -07:00
|
|
|
|
^19 |
|
2024-08-14 04:42:05 -07:00
|
|
|
|
{3:[No Name] [+] 20,1 3%}|
|
2022-01-08 05:27:35 -07:00
|
|
|
|
|
|
|
|
|
|
]]
|
|
|
|
|
end)
|
2024-02-11 07:46:14 -07:00
|
|
|
|
|
|
|
|
|
it('can return values by reference', function()
|
|
|
|
|
eq(
|
|
|
|
|
{ 7, 10 },
|
|
|
|
|
exec_lua [[
|
|
|
|
|
local val = {4, 10}
|
|
|
|
|
local ref = vim.api.nvim_win_call(0, function() return val end)
|
|
|
|
|
ref[1] = 7
|
|
|
|
|
return val
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
2024-03-09 13:24:08 -07:00
|
|
|
|
|
|
|
|
|
it('layout in current tabpage does not affect windows in others', function()
|
|
|
|
|
command('tab split')
|
|
|
|
|
local t2_move_win = api.nvim_get_current_win()
|
|
|
|
|
command('vsplit')
|
|
|
|
|
local t2_other_win = api.nvim_get_current_win()
|
|
|
|
|
command('tabprevious')
|
|
|
|
|
matches('E36: Not enough room$', pcall_err(command, 'execute "split|"->repeat(&lines)'))
|
|
|
|
|
command('vsplit')
|
|
|
|
|
|
|
|
|
|
-- Without vim-patch:8.2.3862, this gives E36, despite just the 1st tabpage being full.
|
|
|
|
|
exec_lua('vim.api.nvim_win_call(..., function() vim.cmd.wincmd "J" end)', t2_move_win)
|
|
|
|
|
eq({ 'col', { { 'leaf', t2_other_win }, { 'leaf', t2_move_win } } }, fn.winlayout(2))
|
|
|
|
|
end)
|
2021-06-03 17:47:43 -07:00
|
|
|
|
end)
|
2022-08-24 06:41:31 -07:00
|
|
|
|
|
|
|
|
|
describe('vim.iconv', function()
|
|
|
|
|
it('can convert strings', function()
|
|
|
|
|
eq(
|
|
|
|
|
'hello',
|
|
|
|
|
exec_lua [[
|
|
|
|
|
return vim.iconv('hello', 'latin1', 'utf-8')
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('can validate arguments', function()
|
|
|
|
|
eq(
|
|
|
|
|
{ false, 'Expected at least 3 arguments' },
|
|
|
|
|
exec_lua [[
|
|
|
|
|
return {pcall(vim.iconv, 'hello')}
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
eq(
|
|
|
|
|
{ false, "bad argument #3 to '?' (expected string)" },
|
|
|
|
|
exec_lua [[
|
|
|
|
|
return {pcall(vim.iconv, 'hello', 'utf-8', true)}
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('can handle bad encodings', function()
|
|
|
|
|
eq(
|
|
|
|
|
NIL,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
return vim.iconv('hello', 'foo', 'bar')
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('can handle strings with NUL bytes', function()
|
|
|
|
|
eq(
|
|
|
|
|
7,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
local a = string.char(97, 98, 99, 0, 100, 101, 102) -- abc\0def
|
|
|
|
|
return string.len(vim.iconv(a, 'latin1', 'utf-8'))
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
end)
|
|
|
|
|
|
2022-09-06 23:39:56 -07:00
|
|
|
|
describe('vim.defaulttable', function()
|
|
|
|
|
it('creates nested table by default', function()
|
|
|
|
|
eq(
|
|
|
|
|
{ b = { c = 1 } },
|
|
|
|
|
exec_lua [[
|
|
|
|
|
local a = vim.defaulttable()
|
|
|
|
|
a.b.c = 1
|
|
|
|
|
return a
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('allows to create default objects', function()
|
|
|
|
|
eq(
|
|
|
|
|
{ b = 1 },
|
|
|
|
|
exec_lua [[
|
|
|
|
|
local a = vim.defaulttable(function() return 0 end)
|
|
|
|
|
a.b = a.b + 1
|
|
|
|
|
return a
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
2023-04-01 07:02:58 -07:00
|
|
|
|
|
|
|
|
|
it('accepts the key name', function()
|
|
|
|
|
eq(
|
|
|
|
|
{ b = 'b', c = 'c' },
|
|
|
|
|
exec_lua [[
|
|
|
|
|
local a = vim.defaulttable(function(k) return k end)
|
|
|
|
|
local _ = a.b
|
|
|
|
|
local _ = a.c
|
|
|
|
|
return a
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
2022-09-06 23:39:56 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2021-01-27 01:00:28 -07:00
|
|
|
|
it('vim.lua_omnifunc', function()
|
|
|
|
|
local screen = Screen.new(60, 5)
|
|
|
|
|
command [[ set omnifunc=v:lua.vim.lua_omnifunc ]]
|
|
|
|
|
|
|
|
|
|
-- Note: the implementation is shared with lua command line completion.
|
|
|
|
|
-- More tests for completion in lua/command_line_completion_spec.lua
|
|
|
|
|
feed [[ivim.insp<c-x><c-o>]]
|
|
|
|
|
screen:expect {
|
|
|
|
|
grid = [[
|
|
|
|
|
vim.inspect^ |
|
2024-08-14 04:42:05 -07:00
|
|
|
|
{1:~ }{12: inspect }{1: }|
|
|
|
|
|
{1:~ }{4: inspect_pos }{1: }|
|
2021-01-27 01:00:28 -07:00
|
|
|
|
{1:~ }|
|
2024-08-14 04:42:05 -07:00
|
|
|
|
{5:-- Omni completion (^O^N^P) }{6:match 1 of 2} |
|
2021-01-27 01:00:28 -07:00
|
|
|
|
]],
|
|
|
|
|
}
|
|
|
|
|
end)
|
refactor!: rename vim.pretty_print => vim.print
Problem:
The function name `vim.pretty_print`:
1. is verbose, which partially defeats its purpose as sugar
2. does not draw from existing precedent or any sort of convention
(except external projects like penlight or python?), which reduces
discoverability, and degrades signaling about best practices.
Solution:
- Rename to `vim.print`.
- Change the behavior so that
1. strings are printed without quotes
2. each arg is printed on its own line
3. tables are indented with 2 instead of 4 spaces
- Example:
:lua ='a', 'b', 42, {a=3}
a
b
42
{
a = 3
}
Comparison of alternatives:
- `vim.print`:
- pro: consistent with Lua's `print()`
- pro: aligns with potential `nvim_print` API function which will
replace nvim_echo, nvim_notify, etc.
- con: behaves differently than Lua's `print()`, slightly misleading?
- `vim.echo`:
- pro: `:echo` has similar "pretty print" behavior.
- con: inconsistent with Lua idioms.
- `vim.p`:
- pro: very short, fits with `vim.o`, etc.
- con: not as discoverable as "echo"
- con: less opportunity for `local p = vim.p` because of potential shadowing.
2023-03-07 08:04:57 -07:00
|
|
|
|
|
|
|
|
|
it('vim.print', function()
|
|
|
|
|
-- vim.print() returns its args.
|
|
|
|
|
eq(
|
|
|
|
|
{ 42, 'abc', { a = { b = 77 } } },
|
|
|
|
|
exec_lua [[return {vim.print(42, 'abc', { a = { b = 77 }})}]]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
-- vim.print() pretty-prints the args.
|
|
|
|
|
eq(
|
|
|
|
|
dedent [[
|
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
abc
|
|
|
|
|
{
|
|
|
|
|
a = {
|
|
|
|
|
b = 77
|
|
|
|
|
}
|
|
|
|
|
}]],
|
|
|
|
|
eval [[execute('lua vim.print(42, "abc", { a = { b = 77 }})')]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
2023-04-07 07:22:47 -07:00
|
|
|
|
|
|
|
|
|
it('vim.F.if_nil', function()
|
|
|
|
|
local function if_nil(...)
|
|
|
|
|
return exec_lua(
|
|
|
|
|
[[
|
|
|
|
|
local args = {...}
|
|
|
|
|
local nargs = select('#', ...)
|
|
|
|
|
for i = 1, nargs do
|
|
|
|
|
if args[i] == vim.NIL then
|
|
|
|
|
args[i] = nil
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
return vim.F.if_nil(unpack(args, 1, nargs))
|
|
|
|
|
]],
|
|
|
|
|
...
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local a = NIL
|
|
|
|
|
local b = NIL
|
|
|
|
|
local c = 42
|
|
|
|
|
local d = false
|
|
|
|
|
eq(42, if_nil(a, c))
|
|
|
|
|
eq(false, if_nil(d, b))
|
|
|
|
|
eq(42, if_nil(a, b, c, d))
|
|
|
|
|
eq(false, if_nil(d))
|
|
|
|
|
eq(false, if_nil(d, c))
|
|
|
|
|
eq(NIL, if_nil(a))
|
|
|
|
|
end)
|
2023-04-20 04:19:38 -07:00
|
|
|
|
|
|
|
|
|
it('lpeg', function()
|
|
|
|
|
eq(
|
|
|
|
|
5,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
local m = vim.lpeg
|
|
|
|
|
return m.match(m.R'09'^1, '4504ab')
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
eq(4, exec_lua [[ return vim.re.match("abcde", '[a-c]+') ]])
|
|
|
|
|
end)
|
2023-06-08 03:11:24 -07:00
|
|
|
|
|
|
|
|
|
it('vim.ringbuf', function()
|
|
|
|
|
local results = exec_lua([[
|
|
|
|
|
local ringbuf = vim.ringbuf(3)
|
|
|
|
|
ringbuf:push("a") -- idx: 0
|
|
|
|
|
local peeka1 = ringbuf:peek()
|
|
|
|
|
local peeka2 = ringbuf:peek()
|
|
|
|
|
local popa = ringbuf:pop()
|
|
|
|
|
local popnil = ringbuf:pop()
|
|
|
|
|
ringbuf:push("a") -- idx: 1
|
|
|
|
|
ringbuf:push("b") -- idx: 2
|
|
|
|
|
|
|
|
|
|
-- doesn't read last added item, but uses separate read index
|
|
|
|
|
local pop_after_add_b = ringbuf:pop()
|
|
|
|
|
|
|
|
|
|
ringbuf:push("c") -- idx: 3 wraps around, overrides idx: 0 "a"
|
|
|
|
|
ringbuf:push("d") -- idx: 4 wraps around, overrides idx: 1 "a"
|
|
|
|
|
return {
|
|
|
|
|
peeka1 = peeka1,
|
|
|
|
|
peeka2 = peeka2,
|
|
|
|
|
pop1 = popa,
|
|
|
|
|
pop2 = popnil,
|
|
|
|
|
pop3 = ringbuf:pop(),
|
|
|
|
|
pop4 = ringbuf:pop(),
|
|
|
|
|
pop5 = ringbuf:pop(),
|
|
|
|
|
pop_after_add_b = pop_after_add_b,
|
|
|
|
|
}
|
|
|
|
|
]])
|
|
|
|
|
local expected = {
|
|
|
|
|
peeka1 = 'a',
|
|
|
|
|
peeka2 = 'a',
|
|
|
|
|
pop1 = 'a',
|
|
|
|
|
pop2 = nil,
|
|
|
|
|
pop3 = 'b',
|
|
|
|
|
pop4 = 'c',
|
|
|
|
|
pop5 = 'd',
|
|
|
|
|
pop_after_add_b = 'a',
|
|
|
|
|
}
|
|
|
|
|
eq(expected, results)
|
|
|
|
|
end)
|
2020-05-20 08:08:19 -07:00
|
|
|
|
end)
|
2020-12-07 15:47:28 -07:00
|
|
|
|
|
2022-03-01 06:27:19 -07:00
|
|
|
|
describe('lua: builtin modules', function()
|
|
|
|
|
local function do_tests()
|
|
|
|
|
eq(2, exec_lua [[return vim.tbl_count {x=1,y=2}]])
|
|
|
|
|
eq('{ 10, "spam" }', exec_lua [[return vim.inspect {10, 'spam'}]])
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it('works', function()
|
|
|
|
|
clear()
|
|
|
|
|
do_tests()
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('works when disabled', function()
|
|
|
|
|
clear('--luamod-dev')
|
|
|
|
|
do_tests()
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('works without runtime', function()
|
|
|
|
|
clear { env = { VIMRUNTIME = 'fixtures/a' } }
|
|
|
|
|
do_tests()
|
|
|
|
|
end)
|
|
|
|
|
|
2023-01-16 12:43:13 -07:00
|
|
|
|
it('fails when disabled without runtime', function()
|
|
|
|
|
clear()
|
|
|
|
|
command("let $VIMRUNTIME='fixtures/a'")
|
|
|
|
|
-- Use system([nvim,…]) instead of clear() to avoid stderr noise. #21844
|
2024-01-12 10:59:57 -07:00
|
|
|
|
local out = fn.system({
|
|
|
|
|
nvim_prog,
|
|
|
|
|
'--clean',
|
|
|
|
|
'--luamod-dev',
|
|
|
|
|
[[+call nvim_exec_lua('return vim.tbl_count {x=1,y=2}')]],
|
|
|
|
|
'+qa!',
|
|
|
|
|
}):gsub('\r\n', '\n')
|
2023-01-16 12:43:13 -07:00
|
|
|
|
eq(1, eval('v:shell_error'))
|
|
|
|
|
matches("'vim%.shared' not found", out)
|
2022-03-01 06:27:19 -07:00
|
|
|
|
end)
|
|
|
|
|
end)
|
|
|
|
|
|
2020-12-07 15:47:28 -07:00
|
|
|
|
describe('lua: require("mod") from packages', function()
|
|
|
|
|
before_each(function()
|
2022-03-01 06:27:19 -07:00
|
|
|
|
clear('--cmd', 'set rtp+=test/functional/fixtures pp+=test/functional/fixtures')
|
2020-12-07 15:47:28 -07:00
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('propagates syntax error', function()
|
|
|
|
|
local syntax_error_msg = exec_lua [[
|
|
|
|
|
local _, err = pcall(require, "syntax_error")
|
|
|
|
|
return err
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
matches('unexpected symbol', syntax_error_msg)
|
|
|
|
|
end)
|
2021-09-28 04:51:26 -07:00
|
|
|
|
|
|
|
|
|
it('uses the right order of mod.lua vs mod/init.lua', function()
|
|
|
|
|
-- lua/fancy_x.lua takes precedence over lua/fancy_x/init.lua
|
|
|
|
|
eq('I am fancy_x.lua', exec_lua [[ return require'fancy_x' ]])
|
|
|
|
|
-- but lua/fancy_y/init.lua takes precedence over after/lua/fancy_y.lua
|
|
|
|
|
eq('I am init.lua of fancy_y!', exec_lua [[ return require'fancy_y' ]])
|
|
|
|
|
-- safety check: after/lua/fancy_z.lua is still loaded
|
|
|
|
|
eq('I am fancy_z.lua', exec_lua [[ return require'fancy_z' ]])
|
|
|
|
|
end)
|
2020-12-07 15:47:28 -07:00
|
|
|
|
end)
|
feat(lua): add vim.keymap
This introduces two new functions `vim.keymap.set` & `vim.keymap.del`
differences compared to regular set_keymap:
- remap is used as opposite of noremap. By default it's true for <Plug> keymaps and false for others.
- rhs can be lua function.
- mode can be a list of modes.
- replace_keycodes option for lua function expr maps. (Default: true)
- handles buffer specific keymaps
Examples:
```lua
vim.keymap.set('n', 'asdf', function() print("real lua function") end)
vim.keymap.set({'n', 'v'}, '<leader>lr', vim.lsp.buf.references, {buffer=true})
vim.keymap.set('n', '<leader>w', "<cmd>w<cr>", {silent = true, buffer = 5 })
vim.keymap.set('i', '<Tab>', function()
return vim.fn.pumvisible() == 1 and "<C-n>" or "<Tab>"
end, {expr = true})
vim.keymap.set('n', '[%', '<Plug>(MatchitNormalMultiBackward)')
vim.keymap.del('n', 'asdf')
vim.keymap.del({'n', 'i', 'v'}, '<leader>w', {buffer = 5 })
```
2021-12-30 00:30:49 -07:00
|
|
|
|
|
|
|
|
|
describe('vim.keymap', function()
|
2022-03-01 06:27:19 -07:00
|
|
|
|
before_each(clear)
|
|
|
|
|
|
2024-09-25 07:01:27 -07:00
|
|
|
|
it('validates', function()
|
|
|
|
|
matches(
|
|
|
|
|
'mode: expected string|table, got number',
|
|
|
|
|
pcall_err(exec_lua, [[vim.keymap.set(42, 'x', print)]])
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
matches(
|
|
|
|
|
'rhs: expected string|function, got nil',
|
|
|
|
|
pcall_err(exec_lua, [[vim.keymap.set('n', 'x')]])
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
matches(
|
|
|
|
|
'lhs: expected string, got table',
|
|
|
|
|
pcall_err(exec_lua, [[vim.keymap.set('n', {}, print)]])
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
matches(
|
2024-10-18 03:33:12 -07:00
|
|
|
|
'rhs: expected string|function, got number',
|
2024-09-25 07:01:27 -07:00
|
|
|
|
pcall_err(exec_lua, [[vim.keymap.set({}, 'x', 42, function() end)]])
|
|
|
|
|
)
|
|
|
|
|
|
2024-10-18 03:33:12 -07:00
|
|
|
|
matches(
|
|
|
|
|
'opts: expected table, got function',
|
|
|
|
|
pcall_err(exec_lua, [[vim.keymap.set({}, 'x', 'x', function() end)]])
|
|
|
|
|
)
|
|
|
|
|
|
2024-09-25 07:01:27 -07:00
|
|
|
|
matches(
|
|
|
|
|
'rhs: expected string|function, got number',
|
|
|
|
|
pcall_err(exec_lua, [[vim.keymap.set('z', 'x', 42)]])
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
matches('Invalid mode shortname: "z"', pcall_err(exec_lua, [[vim.keymap.set('z', 'x', 'y')]]))
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('mapping', function()
|
feat(lua): add vim.keymap
This introduces two new functions `vim.keymap.set` & `vim.keymap.del`
differences compared to regular set_keymap:
- remap is used as opposite of noremap. By default it's true for <Plug> keymaps and false for others.
- rhs can be lua function.
- mode can be a list of modes.
- replace_keycodes option for lua function expr maps. (Default: true)
- handles buffer specific keymaps
Examples:
```lua
vim.keymap.set('n', 'asdf', function() print("real lua function") end)
vim.keymap.set({'n', 'v'}, '<leader>lr', vim.lsp.buf.references, {buffer=true})
vim.keymap.set('n', '<leader>w', "<cmd>w<cr>", {silent = true, buffer = 5 })
vim.keymap.set('i', '<Tab>', function()
return vim.fn.pumvisible() == 1 and "<C-n>" or "<Tab>"
end, {expr = true})
vim.keymap.set('n', '[%', '<Plug>(MatchitNormalMultiBackward)')
vim.keymap.del('n', 'asdf')
vim.keymap.del({'n', 'i', 'v'}, '<leader>w', {buffer = 5 })
```
2021-12-30 00:30:49 -07:00
|
|
|
|
eq(
|
|
|
|
|
0,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
GlobalCount = 0
|
|
|
|
|
vim.keymap.set('n', 'asdf', function() GlobalCount = GlobalCount + 1 end)
|
|
|
|
|
return GlobalCount
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
feed('asdf\n')
|
|
|
|
|
|
|
|
|
|
eq(1, exec_lua [[return GlobalCount]])
|
|
|
|
|
end)
|
|
|
|
|
|
2024-09-25 07:01:27 -07:00
|
|
|
|
it('expr mapping', function()
|
feat(lua): add vim.keymap
This introduces two new functions `vim.keymap.set` & `vim.keymap.del`
differences compared to regular set_keymap:
- remap is used as opposite of noremap. By default it's true for <Plug> keymaps and false for others.
- rhs can be lua function.
- mode can be a list of modes.
- replace_keycodes option for lua function expr maps. (Default: true)
- handles buffer specific keymaps
Examples:
```lua
vim.keymap.set('n', 'asdf', function() print("real lua function") end)
vim.keymap.set({'n', 'v'}, '<leader>lr', vim.lsp.buf.references, {buffer=true})
vim.keymap.set('n', '<leader>w', "<cmd>w<cr>", {silent = true, buffer = 5 })
vim.keymap.set('i', '<Tab>', function()
return vim.fn.pumvisible() == 1 and "<C-n>" or "<Tab>"
end, {expr = true})
vim.keymap.set('n', '[%', '<Plug>(MatchitNormalMultiBackward)')
vim.keymap.del('n', 'asdf')
vim.keymap.del({'n', 'i', 'v'}, '<leader>w', {buffer = 5 })
```
2021-12-30 00:30:49 -07:00
|
|
|
|
exec_lua [[
|
2022-08-01 20:13:22 -07:00
|
|
|
|
vim.keymap.set('n', 'aa', function() return '<Insert>π<C-V><M-π>foo<lt><Esc>' end, {expr = true})
|
feat(lua): add vim.keymap
This introduces two new functions `vim.keymap.set` & `vim.keymap.del`
differences compared to regular set_keymap:
- remap is used as opposite of noremap. By default it's true for <Plug> keymaps and false for others.
- rhs can be lua function.
- mode can be a list of modes.
- replace_keycodes option for lua function expr maps. (Default: true)
- handles buffer specific keymaps
Examples:
```lua
vim.keymap.set('n', 'asdf', function() print("real lua function") end)
vim.keymap.set({'n', 'v'}, '<leader>lr', vim.lsp.buf.references, {buffer=true})
vim.keymap.set('n', '<leader>w', "<cmd>w<cr>", {silent = true, buffer = 5 })
vim.keymap.set('i', '<Tab>', function()
return vim.fn.pumvisible() == 1 and "<C-n>" or "<Tab>"
end, {expr = true})
vim.keymap.set('n', '[%', '<Plug>(MatchitNormalMultiBackward)')
vim.keymap.del('n', 'asdf')
vim.keymap.del({'n', 'i', 'v'}, '<leader>w', {buffer = 5 })
```
2021-12-30 00:30:49 -07:00
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
feed('aa')
|
|
|
|
|
|
2024-01-12 10:59:57 -07:00
|
|
|
|
eq({ 'π<M-π>foo<' }, api.nvim_buf_get_lines(0, 0, -1, false))
|
feat(lua): add vim.keymap
This introduces two new functions `vim.keymap.set` & `vim.keymap.del`
differences compared to regular set_keymap:
- remap is used as opposite of noremap. By default it's true for <Plug> keymaps and false for others.
- rhs can be lua function.
- mode can be a list of modes.
- replace_keycodes option for lua function expr maps. (Default: true)
- handles buffer specific keymaps
Examples:
```lua
vim.keymap.set('n', 'asdf', function() print("real lua function") end)
vim.keymap.set({'n', 'v'}, '<leader>lr', vim.lsp.buf.references, {buffer=true})
vim.keymap.set('n', '<leader>w', "<cmd>w<cr>", {silent = true, buffer = 5 })
vim.keymap.set('i', '<Tab>', function()
return vim.fn.pumvisible() == 1 and "<C-n>" or "<Tab>"
end, {expr = true})
vim.keymap.set('n', '[%', '<Plug>(MatchitNormalMultiBackward)')
vim.keymap.del('n', 'asdf')
vim.keymap.del({'n', 'i', 'v'}, '<leader>w', {buffer = 5 })
```
2021-12-30 00:30:49 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2024-09-25 07:01:27 -07:00
|
|
|
|
it('overwrite a mapping', function()
|
feat(lua): add vim.keymap
This introduces two new functions `vim.keymap.set` & `vim.keymap.del`
differences compared to regular set_keymap:
- remap is used as opposite of noremap. By default it's true for <Plug> keymaps and false for others.
- rhs can be lua function.
- mode can be a list of modes.
- replace_keycodes option for lua function expr maps. (Default: true)
- handles buffer specific keymaps
Examples:
```lua
vim.keymap.set('n', 'asdf', function() print("real lua function") end)
vim.keymap.set({'n', 'v'}, '<leader>lr', vim.lsp.buf.references, {buffer=true})
vim.keymap.set('n', '<leader>w', "<cmd>w<cr>", {silent = true, buffer = 5 })
vim.keymap.set('i', '<Tab>', function()
return vim.fn.pumvisible() == 1 and "<C-n>" or "<Tab>"
end, {expr = true})
vim.keymap.set('n', '[%', '<Plug>(MatchitNormalMultiBackward)')
vim.keymap.del('n', 'asdf')
vim.keymap.del({'n', 'i', 'v'}, '<leader>w', {buffer = 5 })
```
2021-12-30 00:30:49 -07:00
|
|
|
|
eq(
|
|
|
|
|
0,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
GlobalCount = 0
|
|
|
|
|
vim.keymap.set('n', 'asdf', function() GlobalCount = GlobalCount + 1 end)
|
|
|
|
|
return GlobalCount
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
feed('asdf\n')
|
|
|
|
|
|
|
|
|
|
eq(1, exec_lua [[return GlobalCount]])
|
|
|
|
|
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.keymap.set('n', 'asdf', function() GlobalCount = GlobalCount - 1 end)
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
feed('asdf\n')
|
|
|
|
|
|
|
|
|
|
eq(0, exec_lua [[return GlobalCount]])
|
|
|
|
|
end)
|
|
|
|
|
|
2024-09-25 07:01:27 -07:00
|
|
|
|
it('unmap', function()
|
feat(lua): add vim.keymap
This introduces two new functions `vim.keymap.set` & `vim.keymap.del`
differences compared to regular set_keymap:
- remap is used as opposite of noremap. By default it's true for <Plug> keymaps and false for others.
- rhs can be lua function.
- mode can be a list of modes.
- replace_keycodes option for lua function expr maps. (Default: true)
- handles buffer specific keymaps
Examples:
```lua
vim.keymap.set('n', 'asdf', function() print("real lua function") end)
vim.keymap.set({'n', 'v'}, '<leader>lr', vim.lsp.buf.references, {buffer=true})
vim.keymap.set('n', '<leader>w', "<cmd>w<cr>", {silent = true, buffer = 5 })
vim.keymap.set('i', '<Tab>', function()
return vim.fn.pumvisible() == 1 and "<C-n>" or "<Tab>"
end, {expr = true})
vim.keymap.set('n', '[%', '<Plug>(MatchitNormalMultiBackward)')
vim.keymap.del('n', 'asdf')
vim.keymap.del({'n', 'i', 'v'}, '<leader>w', {buffer = 5 })
```
2021-12-30 00:30:49 -07:00
|
|
|
|
eq(
|
|
|
|
|
0,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
GlobalCount = 0
|
|
|
|
|
vim.keymap.set('n', 'asdf', function() GlobalCount = GlobalCount + 1 end)
|
|
|
|
|
return GlobalCount
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
feed('asdf\n')
|
|
|
|
|
|
|
|
|
|
eq(1, exec_lua [[return GlobalCount]])
|
|
|
|
|
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.keymap.del('n', 'asdf')
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
feed('asdf\n')
|
|
|
|
|
|
|
|
|
|
eq(1, exec_lua [[return GlobalCount]])
|
2024-04-20 08:44:13 -07:00
|
|
|
|
eq('\nNo mapping found', n.exec_capture('nmap asdf'))
|
feat(lua): add vim.keymap
This introduces two new functions `vim.keymap.set` & `vim.keymap.del`
differences compared to regular set_keymap:
- remap is used as opposite of noremap. By default it's true for <Plug> keymaps and false for others.
- rhs can be lua function.
- mode can be a list of modes.
- replace_keycodes option for lua function expr maps. (Default: true)
- handles buffer specific keymaps
Examples:
```lua
vim.keymap.set('n', 'asdf', function() print("real lua function") end)
vim.keymap.set({'n', 'v'}, '<leader>lr', vim.lsp.buf.references, {buffer=true})
vim.keymap.set('n', '<leader>w', "<cmd>w<cr>", {silent = true, buffer = 5 })
vim.keymap.set('i', '<Tab>', function()
return vim.fn.pumvisible() == 1 and "<C-n>" or "<Tab>"
end, {expr = true})
vim.keymap.set('n', '[%', '<Plug>(MatchitNormalMultiBackward)')
vim.keymap.del('n', 'asdf')
vim.keymap.del({'n', 'i', 'v'}, '<leader>w', {buffer = 5 })
```
2021-12-30 00:30:49 -07:00
|
|
|
|
end)
|
|
|
|
|
|
2024-09-25 07:01:27 -07:00
|
|
|
|
it('buffer-local mappings', function()
|
2022-04-22 17:01:08 -07:00
|
|
|
|
eq(
|
|
|
|
|
0,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
GlobalCount = 0
|
|
|
|
|
vim.keymap.set('n', 'asdf', function() GlobalCount = GlobalCount + 1 end, {buffer=true})
|
|
|
|
|
return GlobalCount
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
feed('asdf\n')
|
|
|
|
|
|
|
|
|
|
eq(1, exec_lua [[return GlobalCount]])
|
|
|
|
|
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.keymap.del('n', 'asdf', {buffer=true})
|
|
|
|
|
]]
|
|
|
|
|
|
|
|
|
|
feed('asdf\n')
|
|
|
|
|
|
|
|
|
|
eq(1, exec_lua [[return GlobalCount]])
|
2024-04-20 08:44:13 -07:00
|
|
|
|
eq('\nNo mapping found', n.exec_capture('nmap asdf'))
|
2022-04-22 17:01:08 -07:00
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
it('does not mutate the opts parameter', function()
|
|
|
|
|
eq(
|
|
|
|
|
true,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
opts = {buffer=true}
|
|
|
|
|
vim.keymap.set('n', 'asdf', function() end, opts)
|
|
|
|
|
return opts.buffer
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
eq(
|
|
|
|
|
true,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
vim.keymap.del('n', 'asdf', opts)
|
|
|
|
|
return opts.buffer
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
end)
|
|
|
|
|
|
2024-09-25 07:01:27 -07:00
|
|
|
|
it('<Plug> mappings', function()
|
feat(lua): add vim.keymap
This introduces two new functions `vim.keymap.set` & `vim.keymap.del`
differences compared to regular set_keymap:
- remap is used as opposite of noremap. By default it's true for <Plug> keymaps and false for others.
- rhs can be lua function.
- mode can be a list of modes.
- replace_keycodes option for lua function expr maps. (Default: true)
- handles buffer specific keymaps
Examples:
```lua
vim.keymap.set('n', 'asdf', function() print("real lua function") end)
vim.keymap.set({'n', 'v'}, '<leader>lr', vim.lsp.buf.references, {buffer=true})
vim.keymap.set('n', '<leader>w', "<cmd>w<cr>", {silent = true, buffer = 5 })
vim.keymap.set('i', '<Tab>', function()
return vim.fn.pumvisible() == 1 and "<C-n>" or "<Tab>"
end, {expr = true})
vim.keymap.set('n', '[%', '<Plug>(MatchitNormalMultiBackward)')
vim.keymap.del('n', 'asdf')
vim.keymap.del({'n', 'i', 'v'}, '<leader>w', {buffer = 5 })
```
2021-12-30 00:30:49 -07:00
|
|
|
|
eq(
|
|
|
|
|
0,
|
|
|
|
|
exec_lua [[
|
|
|
|
|
GlobalCount = 0
|
|
|
|
|
vim.keymap.set('n', '<plug>(asdf)', function() GlobalCount = GlobalCount + 1 end)
|
|
|
|
|
vim.keymap.set('n', 'ww', '<plug>(asdf)')
|
|
|
|
|
return GlobalCount
|
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
feed('ww\n')
|
|
|
|
|
|
|
|
|
|
eq(1, exec_lua [[return GlobalCount]])
|
|
|
|
|
end)
|
2023-12-12 05:34:02 -07:00
|
|
|
|
end)
|
feat(lua): add vim.keymap
This introduces two new functions `vim.keymap.set` & `vim.keymap.del`
differences compared to regular set_keymap:
- remap is used as opposite of noremap. By default it's true for <Plug> keymaps and false for others.
- rhs can be lua function.
- mode can be a list of modes.
- replace_keycodes option for lua function expr maps. (Default: true)
- handles buffer specific keymaps
Examples:
```lua
vim.keymap.set('n', 'asdf', function() print("real lua function") end)
vim.keymap.set({'n', 'v'}, '<leader>lr', vim.lsp.buf.references, {buffer=true})
vim.keymap.set('n', '<leader>w', "<cmd>w<cr>", {silent = true, buffer = 5 })
vim.keymap.set('i', '<Tab>', function()
return vim.fn.pumvisible() == 1 and "<C-n>" or "<Tab>"
end, {expr = true})
vim.keymap.set('n', '[%', '<Plug>(MatchitNormalMultiBackward)')
vim.keymap.del('n', 'asdf')
vim.keymap.del({'n', 'i', 'v'}, '<leader>w', {buffer = 5 })
```
2021-12-30 00:30:49 -07:00
|
|
|
|
|
2023-12-12 05:34:02 -07:00
|
|
|
|
describe('Vimscript function exists()', function()
|
|
|
|
|
it('can check a lua function', function()
|
|
|
|
|
eq(
|
|
|
|
|
1,
|
|
|
|
|
exec_lua [[
|
2023-12-12 04:06:22 -07:00
|
|
|
|
_G.test = function() print("hello") end
|
2024-01-22 01:04:50 -07:00
|
|
|
|
return vim.fn.exists('*v:lua.test')
|
2023-12-12 04:06:22 -07:00
|
|
|
|
]]
|
|
|
|
|
)
|
|
|
|
|
|
2024-01-22 01:04:50 -07:00
|
|
|
|
eq(1, fn.exists('*v:lua.require("mpack").decode'))
|
|
|
|
|
eq(1, fn.exists("*v:lua.require('mpack').decode"))
|
|
|
|
|
eq(1, fn.exists('*v:lua.require"mpack".decode'))
|
|
|
|
|
eq(1, fn.exists("*v:lua.require'mpack'.decode"))
|
|
|
|
|
eq(1, fn.exists("*v:lua.require('vim.lsp').start"))
|
|
|
|
|
eq(1, fn.exists('*v:lua.require"vim.lsp".start'))
|
|
|
|
|
eq(1, fn.exists("*v:lua.require'vim.lsp'.start"))
|
|
|
|
|
eq(0, fn.exists("*v:lua.require'vim.lsp'.unknown"))
|
|
|
|
|
eq(0, fn.exists('*v:lua.?'))
|
2023-12-12 04:06:22 -07:00
|
|
|
|
end)
|
feat(lua): add vim.keymap
This introduces two new functions `vim.keymap.set` & `vim.keymap.del`
differences compared to regular set_keymap:
- remap is used as opposite of noremap. By default it's true for <Plug> keymaps and false for others.
- rhs can be lua function.
- mode can be a list of modes.
- replace_keycodes option for lua function expr maps. (Default: true)
- handles buffer specific keymaps
Examples:
```lua
vim.keymap.set('n', 'asdf', function() print("real lua function") end)
vim.keymap.set({'n', 'v'}, '<leader>lr', vim.lsp.buf.references, {buffer=true})
vim.keymap.set('n', '<leader>w', "<cmd>w<cr>", {silent = true, buffer = 5 })
vim.keymap.set('i', '<Tab>', function()
return vim.fn.pumvisible() == 1 and "<C-n>" or "<Tab>"
end, {expr = true})
vim.keymap.set('n', '[%', '<Plug>(MatchitNormalMultiBackward)')
vim.keymap.del('n', 'asdf')
vim.keymap.del({'n', 'i', 'v'}, '<leader>w', {buffer = 5 })
```
2021-12-30 00:30:49 -07:00
|
|
|
|
end)
|