2024-04-20 08:44:13 -07:00
local t = require ( ' test.testutil ' )
local n = require ( ' test.functional.testnvim ' ) ( )
2015-07-27 04:39:38 -07:00
local Screen = require ( ' test.functional.ui.screen ' )
2024-01-12 04:28:20 -07:00
local uv = vim.uv
2017-11-04 16:41:44 -07:00
2021-09-01 07:29:38 -07:00
local fmt = string.format
2024-04-08 02:03:20 -07:00
local dedent = t.dedent
2024-04-20 08:44:13 -07:00
local assert_alive = n.assert_alive
2024-01-12 04:28:20 -07:00
local NIL = vim.NIL
2024-04-20 08:44:13 -07:00
local clear , eq , neq = n.clear , t.eq , t.neq
local command = n.command
local command_output = n.api . nvim_command_output
local exec = n.exec
local exec_capture = n.exec_capture
local eval = n.eval
local expect = n.expect
local fn = n.fn
local api = n.api
2024-04-08 02:03:20 -07:00
local matches = t.matches
2024-01-12 04:28:20 -07:00
local pesc = vim.pesc
2024-04-20 08:44:13 -07:00
local mkdir_p = n.mkdir_p
local ok , nvim_async , feed = t.ok , n.nvim_async , n.feed
local async_meths = n.async_meths
2024-04-08 02:03:20 -07:00
local is_os = t.is_os
2024-04-20 08:44:13 -07:00
local parse_context = n.parse_context
local request = n.request
local rmdir = n.rmdir
local source = n.source
local next_msg = n.next_msg
2024-04-08 02:03:20 -07:00
local tmpname = t.tmpname
local write_file = t.write_file
2024-04-20 08:44:13 -07:00
local exec_lua = n.exec_lua
local exc_exec = n.exc_exec
local insert = n.insert
2024-04-08 02:03:20 -07:00
local skip = t.skip
local pcall_err = t.pcall_err
2024-01-15 14:14:32 -07:00
local format_string = require ( ' test.format_string ' ) . format_string
2024-04-08 02:03:20 -07:00
local intchar2lua = t.intchar2lua
local mergedicts_copy = t.mergedicts_copy
2024-01-12 04:28:20 -07:00
local endswith = vim.endswith
2017-11-04 16:41:44 -07:00
2018-06-07 01:56:44 -07:00
describe ( ' API ' , function ( )
2014-10-08 09:56:01 -07:00
before_each ( clear )
2018-06-07 01:56:44 -07:00
it ( ' validates requests ' , function ( )
2018-08-29 22:50:18 -07:00
-- RPC
2023-12-07 04:19:35 -07:00
matches ( ' Invalid method: bogus$ ' , pcall_err ( request , ' bogus ' ) )
matches ( ' Invalid method: … の り 。…$ ' , pcall_err ( request , ' … の り 。… ' ) )
matches ( ' Invalid method: <empty>$ ' , pcall_err ( request , ' ' ) )
2018-08-29 22:50:18 -07:00
-- Non-RPC: rpcrequest(v:servername) uses internal channel.
2023-12-07 04:19:35 -07:00
matches (
' Invalid method: … の り 。…$ ' ,
pcall_err (
request ,
' nvim_eval ' ,
[=[rpcrequest(sockconnect('pipe', v:servername, {'rpc':1}), '… の り 。…')]=]
)
)
matches (
' Invalid method: bogus$ ' ,
pcall_err (
request ,
' nvim_eval ' ,
[=[rpcrequest(sockconnect('pipe', v:servername, {'rpc':1}), 'bogus')]=]
)
)
2018-08-29 22:50:18 -07:00
-- XXX: This must be the last one, else next one will fail:
-- "Packer instance already working. Use another Packer ..."
2023-12-07 04:19:35 -07:00
matches ( " can't serialize object of type .$ " , pcall_err ( request , nil ) )
2018-06-07 01:56:44 -07:00
end )
2018-12-01 08:44:36 -07:00
it ( ' handles errors in async requests ' , function ( )
2024-01-12 10:59:57 -07:00
local error_types = api.nvim_get_api_info ( ) [ 2 ] . error_types
2019-04-12 17:13:29 -07:00
nvim_async ( ' bogus ' )
2023-12-07 04:19:35 -07:00
eq ( {
' notification ' ,
' nvim_error_event ' ,
2024-01-15 09:10:51 -07:00
{ error_types.Exception . id , ' Invalid method: bogus ' } ,
2023-12-07 04:19:35 -07:00
} , next_msg ( ) )
2018-12-01 08:44:36 -07:00
-- error didn't close channel.
2021-09-01 09:42:53 -07:00
assert_alive ( )
2018-12-01 08:44:36 -07:00
end )
2019-04-12 17:13:29 -07:00
it ( ' failed async request emits nvim_error_event ' , function ( )
2024-01-12 10:59:57 -07:00
local error_types = api.nvim_get_api_info ( ) [ 2 ] . error_types
2024-01-15 09:10:51 -07:00
async_meths.nvim_command ( ' bogus ' )
2023-12-07 04:19:35 -07:00
eq ( {
' notification ' ,
' nvim_error_event ' ,
{ error_types.Exception . id , ' Vim:E492: Not an editor command: bogus ' } ,
} , next_msg ( ) )
2019-04-12 17:13:29 -07:00
-- error didn't close channel.
2021-09-01 09:42:53 -07:00
assert_alive ( )
2019-04-12 17:13:29 -07:00
end )
2024-02-06 21:11:22 -07:00
it ( ' input is processed first when followed immediately by non-fast events ' , function ( )
api.nvim_set_current_line ( ' ab ' )
async_meths.nvim_input ( ' x ' )
async_meths.nvim_exec_lua ( ' _G.res1 = vim.api.nvim_get_current_line() ' , { } )
async_meths.nvim_exec_lua ( ' _G.res2 = vim.api.nvim_get_current_line() ' , { } )
eq ( { ' b ' , ' b ' } , exec_lua ( ' return { _G.res1, _G.res2 } ' ) )
end )
2019-04-07 17:33:00 -07:00
it ( ' does not set CA_COMMAND_BUSY #7254 ' , function ( )
2024-01-12 06:11:28 -07:00
command ( ' split ' )
command ( ' autocmd WinEnter * startinsert ' )
command ( ' wincmd w ' )
2024-01-12 10:59:57 -07:00
eq ( { mode = ' i ' , blocking = false } , api.nvim_get_mode ( ) )
2019-04-07 17:33:00 -07:00
end )
2023-03-25 09:58:48 -07:00
describe ( ' nvim_exec2 ' , function ( )
it ( ' always returns table ' , function ( )
-- In built version this results into `vim.empty_dict()`
2024-01-12 10:59:57 -07:00
eq ( { } , api.nvim_exec2 ( ' echo "Hello" ' , { } ) )
eq ( { } , api.nvim_exec2 ( ' echo "Hello" ' , { output = false } ) )
eq ( { output = ' Hello ' } , api.nvim_exec2 ( ' echo "Hello" ' , { output = true } ) )
2023-03-25 09:58:48 -07:00
end )
it ( ' default options ' , function ( )
-- Should be equivalent to { output = false }
2024-01-12 10:59:57 -07:00
api.nvim_exec2 ( " let x0 = 'a' " , { } )
eq ( ' a ' , api.nvim_get_var ( ' x0 ' ) )
2023-03-25 09:58:48 -07:00
end )
2019-10-06 19:40:36 -07:00
it ( ' one-line input ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_exec2 ( " let x1 = 'a' " , { output = false } )
eq ( ' a ' , api.nvim_get_var ( ' x1 ' ) )
2019-10-06 13:37:54 -07:00
end )
2019-10-06 19:40:36 -07:00
it ( ' :verbose set {option}? ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_exec2 ( ' set nowrap ' , { output = false } )
2023-12-07 04:19:35 -07:00
eq (
{ output = ' nowrap \n \t Last set from anonymous :source ' } ,
2024-01-12 10:59:57 -07:00
api.nvim_exec2 ( ' verbose set wrap? ' , { output = true } )
2023-12-07 04:19:35 -07:00
)
2021-10-13 16:40:46 -07:00
-- Using script var to force creation of a script item
2024-01-12 10:59:57 -07:00
api.nvim_exec2 (
2023-12-07 04:19:35 -07:00
[ [
2021-10-13 16:40:46 -07:00
let s : a = 1
set nowrap
2023-12-07 04:19:35 -07:00
] ] ,
{ output = false }
)
eq (
{ output = ' nowrap \n \t Last set from anonymous :source (script id 1) ' } ,
2024-01-12 10:59:57 -07:00
api.nvim_exec2 ( ' verbose set wrap? ' , { output = true } )
2023-12-07 04:19:35 -07:00
)
2019-10-06 13:37:54 -07:00
end )
2019-10-06 19:40:36 -07:00
it ( ' multiline input ' , function ( )
-- Heredoc + empty lines.
2024-01-12 10:59:57 -07:00
api.nvim_exec2 ( " let x2 = 'a' \n " , { output = false } )
eq ( ' a ' , api.nvim_get_var ( ' x2 ' ) )
api.nvim_exec2 ( ' lua <<EOF \n \n \n \n y=3 \n \n \n EOF ' , { output = false } )
eq ( 3 , api.nvim_eval ( " luaeval('y') " ) )
2019-10-06 13:37:54 -07:00
2024-01-12 10:59:57 -07:00
eq ( { } , api.nvim_exec2 ( ' lua <<EOF \n y=3 \n EOF ' , { output = false } ) )
eq ( 3 , api.nvim_eval ( " luaeval('y') " ) )
2019-10-06 19:40:36 -07:00
-- Multiple statements
2024-01-12 10:59:57 -07:00
api.nvim_exec2 ( ' let x1=1 \n let x2=2 \n let x3=3 \n ' , { output = false } )
eq ( 1 , api.nvim_eval ( ' x1 ' ) )
eq ( 2 , api.nvim_eval ( ' x2 ' ) )
eq ( 3 , api.nvim_eval ( ' x3 ' ) )
2019-10-06 19:40:36 -07:00
-- Functions
2024-01-12 10:59:57 -07:00
api.nvim_exec2 ( ' function Foo() \n call setline(1,["xxx"]) \n endfunction ' , { output = false } )
eq ( ' ' , api.nvim_get_current_line ( ) )
api.nvim_exec2 ( ' call Foo() ' , { output = false } )
eq ( ' xxx ' , api.nvim_get_current_line ( ) )
2019-10-06 19:40:36 -07:00
-- Autocmds
2024-01-12 10:59:57 -07:00
api.nvim_exec2 ( ' autocmd BufAdd * :let x1 = "Hello" ' , { output = false } )
2024-01-12 06:11:28 -07:00
command ( ' new foo ' )
2019-10-06 19:40:36 -07:00
eq ( ' Hello ' , request ( ' nvim_eval ' , ' g:x1 ' ) )
2021-09-14 16:35:33 -07:00
-- Line continuations
2024-01-12 10:59:57 -07:00
api.nvim_exec2 (
2023-12-07 04:19:35 -07:00
[ [
2021-09-14 16:35:33 -07:00
let abc = # {
\ a : 1 ,
" \ b: 2,
\ c : 3
2023-12-07 04:19:35 -07:00
\ } ] ] ,
{ output = false }
)
eq ( { a = 1 , c = 3 } , request ( ' nvim_eval ' , ' g:abc ' ) )
2021-09-14 16:35:33 -07:00
-- try no spaces before continuations to catch off-by-one error
2024-01-12 10:59:57 -07:00
api.nvim_exec2 ( ' let ab = #{ \n \\ a: 98, \n " \\ b: 2 \n \\ } ' , { output = false } )
2023-12-07 04:19:35 -07:00
eq ( { a = 98 } , request ( ' nvim_eval ' , ' g:ab ' ) )
2021-10-09 14:13:11 -07:00
-- Script scope (s:)
2023-12-07 04:19:35 -07:00
eq (
{ output = ' ahoy! script-scoped varrrrr ' } ,
2024-01-12 10:59:57 -07:00
api.nvim_exec2 (
2023-12-07 04:19:35 -07:00
[ [
2021-10-09 14:13:11 -07:00
let s : pirate = ' script-scoped varrrrr '
function ! s : avast_ye_hades ( s ) abort
return a : s .. ' ' .. s : pirate
endfunction
echo < sid > avast_ye_hades ( ' ahoy! ' )
2023-12-07 04:19:35 -07:00
] ] ,
{ output = true }
)
)
eq (
{ output = " {'output': 'ahoy! script-scoped varrrrr'} " } ,
2024-01-12 10:59:57 -07:00
api.nvim_exec2 (
2023-12-07 04:19:35 -07:00
[ [
2021-10-09 14:13:11 -07:00
let s : pirate = ' script-scoped varrrrr '
function ! Avast_ye_hades ( s ) abort
return a : s .. ' ' .. s : pirate
endfunction
2023-03-25 09:58:48 -07:00
echo nvim_exec2 ( ' echo Avast_ye_hades( ' ' ahoy! ' ' ) ' , { ' output ' : v : true } )
2023-12-07 04:19:35 -07:00
] ] ,
{ output = true }
)
)
matches (
' Vim%(echo%):E121: Undefined variable: s:pirate$ ' ,
pcall_err (
request ,
' nvim_exec2 ' ,
[ [
2021-10-09 14:13:11 -07:00
let s : pirate = ' script-scoped varrrrr '
2023-03-25 09:58:48 -07:00
call nvim_exec2 ( ' echo s:pirate ' , { ' output ' : v : true } )
2023-12-07 04:19:35 -07:00
] ] ,
{ output = false }
)
)
2021-10-13 16:40:46 -07:00
-- Script items are created only on script var access
2023-12-07 04:19:35 -07:00
eq (
{ output = ' 1 \n 0 ' } ,
2024-01-12 10:59:57 -07:00
api.nvim_exec2 (
2023-12-07 04:19:35 -07:00
[ [
2021-10-13 16:40:46 -07:00
echo expand ( " <SID> " ) -> empty ( )
let s : a = 123
echo expand ( " <SID> " ) -> empty ( )
2023-12-07 04:19:35 -07:00
] ] ,
{ output = true }
)
)
eq (
{ output = ' 1 \n 0 ' } ,
2024-01-12 10:59:57 -07:00
api.nvim_exec2 (
2023-12-07 04:19:35 -07:00
[ [
2021-10-13 16:40:46 -07:00
echo expand ( " <SID> " ) -> empty ( )
function s : a ( ) abort
endfunction
echo expand ( " <SID> " ) -> empty ( )
2023-12-07 04:19:35 -07:00
] ] ,
{ output = true }
)
)
2019-10-06 13:37:54 -07:00
end )
2019-10-06 19:40:36 -07:00
it ( ' non-ASCII input ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_exec2 (
2023-12-07 04:19:35 -07:00
[ = [
2019-10-06 19:40:36 -07:00
new
exe " normal! i ax \n Ax "
: % s / ax /-- a1234 --/g | :%s/Ax/--A1234--/g
2023-12-07 04:19:35 -07:00
] = ] ,
{ output = false }
)
2024-01-12 06:11:28 -07:00
command ( ' 1 ' )
2024-01-12 10:59:57 -07:00
eq ( ' --a1234-- ' , api.nvim_get_current_line ( ) )
2024-01-12 06:11:28 -07:00
command ( ' 2 ' )
2024-01-12 10:59:57 -07:00
eq ( ' --A1234-- ' , api.nvim_get_current_line ( ) )
2019-10-06 19:40:36 -07:00
2024-01-12 10:59:57 -07:00
api.nvim_exec2 (
2023-12-07 04:19:35 -07:00
[ [
2019-10-06 19:40:36 -07:00
new
call setline ( 1 , [ ' xxx ' ] )
call feedkeys ( ' r ' )
call feedkeys ( ' ñ ' , ' xt ' )
2023-12-07 04:19:35 -07:00
] ] ,
{ output = false }
)
2024-01-12 10:59:57 -07:00
eq ( ' ñxx ' , api.nvim_get_current_line ( ) )
2019-10-06 13:37:54 -07:00
end )
2019-10-06 19:40:36 -07:00
it ( ' execution error ' , function ( )
2023-12-07 04:19:35 -07:00
eq (
' nvim_exec2(): Vim:E492: Not an editor command: bogus_command ' ,
pcall_err ( request , ' nvim_exec2 ' , ' bogus_command ' , { } )
)
2024-01-12 10:59:57 -07:00
eq ( ' ' , api.nvim_eval ( ' v:errmsg ' ) ) -- v:errmsg was not updated.
2019-10-06 13:37:54 -07:00
eq ( ' ' , eval ( ' v:exception ' ) )
2023-12-07 04:19:35 -07:00
eq (
' nvim_exec2(): Vim(buffer):E86: Buffer 23487 does not exist ' ,
pcall_err ( request , ' nvim_exec2 ' , ' buffer 23487 ' , { } )
)
eq ( ' ' , eval ( ' v:errmsg ' ) ) -- v:errmsg was not updated.
2019-10-06 13:37:54 -07:00
eq ( ' ' , eval ( ' v:exception ' ) )
end )
2019-10-06 19:40:36 -07:00
it ( ' recursion ' , function ( )
2019-12-01 23:26:36 -07:00
local fname = tmpname ( )
2019-10-06 19:40:36 -07:00
write_file ( fname , ' let x1 = "set from :source file" \n ' )
2023-03-25 09:58:48 -07:00
-- nvim_exec2
2019-10-06 19:40:36 -07:00
-- :source
2023-03-25 09:58:48 -07:00
-- nvim_exec2
request ( ' nvim_exec2 ' , [ [
2019-10-06 19:40:36 -07:00
let x2 = substitute ( ' foo ' , ' o ' , ' X ' , ' g ' )
let x4 = ' should be overwritten '
2023-12-07 04:19:35 -07:00
call nvim_exec2 ( " source ]] .. fname .. [[ \n let x3 = substitute('foo','foo','set by recursive nvim_exec2','g') \n let x5='overwritten' \n let x4=x5 \n " , { ' output ' : v : false } )
2023-03-25 09:58:48 -07:00
] ] , { output = false } )
2019-10-06 19:40:36 -07:00
eq ( ' set from :source file ' , request ( ' nvim_get_var ' , ' x1 ' ) )
eq ( ' fXX ' , request ( ' nvim_get_var ' , ' x2 ' ) )
2023-03-25 09:58:48 -07:00
eq ( ' set by recursive nvim_exec2 ' , request ( ' nvim_get_var ' , ' x3 ' ) )
2019-10-06 19:40:36 -07:00
eq ( ' overwritten ' , request ( ' nvim_get_var ' , ' x4 ' ) )
eq ( ' overwritten ' , request ( ' nvim_get_var ' , ' x5 ' ) )
os.remove ( fname )
2019-10-06 13:37:54 -07:00
end )
2019-10-09 06:04:37 -07:00
it ( ' traceback ' , function ( )
2019-12-01 23:26:36 -07:00
local fname = tmpname ( )
2019-10-09 06:04:37 -07:00
write_file ( fname , ' echo "hello" \n ' )
2019-12-01 23:26:36 -07:00
local sourcing_fname = tmpname ( )
2023-12-07 04:19:35 -07:00
write_file ( sourcing_fname , ' call nvim_exec2("source ' .. fname .. ' ", {"output": v:false}) \n ' )
2024-01-12 10:59:57 -07:00
api.nvim_exec2 ( ' set verbose=2 ' , { output = false } )
2023-12-07 04:19:35 -07:00
local traceback_output = dedent ( [ [
line 0 : sourcing " %s "
line 0 : sourcing " %s "
hello
finished sourcing % s
continuing in nvim_exec2 ( ) called at % s : 1
finished sourcing % s
continuing in nvim_exec2 ( ) called at nvim_exec2 ( ) : 0 ] ] ) : format (
sourcing_fname ,
fname ,
fname ,
sourcing_fname ,
sourcing_fname
)
eq (
{ output = traceback_output } ,
2024-01-12 10:59:57 -07:00
api.nvim_exec2 (
2023-12-07 04:19:35 -07:00
' call nvim_exec2("source ' .. sourcing_fname .. ' ", {"output": v:false}) ' ,
{ output = true }
)
)
2019-10-09 06:04:37 -07:00
os.remove ( fname )
os.remove ( sourcing_fname )
end )
2019-12-01 23:26:36 -07:00
it ( ' returns output ' , function ( )
2023-12-07 04:19:35 -07:00
eq (
{ output = ' this is spinal tap ' } ,
2024-01-12 10:59:57 -07:00
api.nvim_exec2 ( ' lua <<EOF \n \n \n print("this is spinal tap") \n \n \n EOF ' , { output = true } )
2023-12-07 04:19:35 -07:00
)
2024-01-12 10:59:57 -07:00
eq ( { output = ' ' } , api.nvim_exec2 ( ' echo ' , { output = true } ) )
eq ( { output = ' foo 42 ' } , api.nvim_exec2 ( ' echo "foo" 42 ' , { output = true } ) )
2019-10-09 06:04:37 -07:00
end )
2021-04-21 01:41:37 -07:00
2023-03-25 09:58:48 -07:00
it ( ' displays messages when opts.output=false ' , function ( )
2021-04-21 01:41:37 -07:00
local screen = Screen.new ( 40 , 8 )
screen : attach ( )
2024-01-12 10:59:57 -07:00
api.nvim_exec2 ( " echo 'hello' " , { output = false } )
2023-12-07 04:19:35 -07:00
screen : expect {
grid = [ [
2021-04-21 01:41:37 -07:00
^ |
2024-05-25 10:18:57 -07:00
{ 1 : ~ } |* 6
2021-04-21 01:41:37 -07:00
hello |
2023-12-07 04:19:35 -07:00
] ] ,
}
2021-04-21 01:41:37 -07:00
end )
2023-12-07 04:19:35 -07:00
it ( " doesn't display messages when output=true " , function ( )
2022-08-16 02:30:39 -07:00
local screen = Screen.new ( 40 , 6 )
2021-04-21 01:41:37 -07:00
screen : attach ( )
2024-01-12 10:59:57 -07:00
api.nvim_exec2 ( " echo 'hello' " , { output = true } )
2023-12-07 04:19:35 -07:00
screen : expect {
grid = [ [
2021-04-21 01:41:37 -07:00
^ |
2024-05-25 10:18:57 -07:00
{ 1 : ~ } |* 4
2022-08-16 02:30:39 -07:00
|
2023-12-07 04:19:35 -07:00
] ] ,
}
2022-08-16 02:30:39 -07:00
exec ( [ [
func Print ( )
2023-03-25 09:58:48 -07:00
call nvim_exec2 ( ' echo "hello" ' , { ' output ' : v : true } )
2022-08-16 02:30:39 -07:00
endfunc
] ] )
feed ( [[:echon 1 | call Print() | echon 5<CR>]] )
2023-12-07 04:19:35 -07:00
screen : expect {
grid = [ [
2022-08-16 02:30:39 -07:00
^ |
2024-05-25 10:18:57 -07:00
{ 1 : ~ } |* 4
2022-08-16 02:30:39 -07:00
15 |
2023-12-07 04:19:35 -07:00
] ] ,
}
2021-04-21 01:41:37 -07:00
end )
2024-01-26 23:03:44 -07:00
it ( ' errors properly when command too recursive ' , function ( )
exec_lua ( [ [
_G.success = false
vim.api . nvim_create_user_command ( ' Test ' , function ( )
vim.api . nvim_exec2 ( ' Test ' , { } )
_G.success = true
end , { } )
] ] )
pcall_err ( command , ' Test ' )
assert_alive ( )
eq ( false , exec_lua ( ' return _G.success ' ) )
end )
2019-10-06 13:37:54 -07:00
end )
2016-10-22 15:02:22 -07:00
describe ( ' nvim_command ' , function ( )
2014-10-08 09:56:01 -07:00
it ( ' works ' , function ( )
2019-12-01 23:26:36 -07:00
local fname = tmpname ( )
2024-01-12 06:11:28 -07:00
command ( ' new ' )
command ( ' edit ' .. fname )
command ( ' normal itesting \n api ' )
command ( ' w ' )
2023-06-28 04:51:55 -07:00
local f = assert ( io.open ( fname ) )
2019-09-04 06:58:04 -07:00
if is_os ( ' win ' ) then
2015-12-29 12:23:51 -07:00
eq ( ' testing \r \n api \r \n ' , f : read ( ' *a ' ) )
else
eq ( ' testing \n api \n ' , f : read ( ' *a ' ) )
end
2014-10-08 09:56:01 -07:00
f : close ( )
os.remove ( fname )
end )
2016-10-22 15:02:22 -07:00
2023-06-22 04:09:14 -07:00
it ( ' Vimscript validation error: fails with specific error ' , function ( )
2024-01-12 06:11:28 -07:00
local status , rv = pcall ( command , ' bogus_command ' )
2023-12-07 04:19:35 -07:00
eq ( false , status ) -- nvim_command() failed.
eq ( ' E492: ' , string.match ( rv , ' E%d*: ' ) ) -- Vimscript error was returned.
2024-01-12 10:59:57 -07:00
eq ( ' ' , api.nvim_eval ( ' v:errmsg ' ) ) -- v:errmsg was not updated.
2018-05-06 18:24:01 -07:00
eq ( ' ' , eval ( ' v:exception ' ) )
2016-10-22 15:02:22 -07:00
end )
2018-01-05 03:17:21 -07:00
2023-06-22 04:09:14 -07:00
it ( ' Vimscript execution error: fails with specific error ' , function ( )
2024-01-12 06:11:28 -07:00
local status , rv = pcall ( command , ' buffer 23487 ' )
2023-12-07 04:19:35 -07:00
eq ( false , status ) -- nvim_command() failed.
eq ( ' E86: Buffer 23487 does not exist ' , string.match ( rv , ' E%d*:.* ' ) )
eq ( ' ' , eval ( ' v:errmsg ' ) ) -- v:errmsg was not updated.
2018-05-06 18:24:01 -07:00
eq ( ' ' , eval ( ' v:exception ' ) )
2018-01-05 03:17:21 -07:00
end )
2023-05-05 04:03:08 -07:00
it ( ' gives E493 instead of prompting on backwards range ' , function ( )
command ( ' split ' )
2023-12-07 04:19:35 -07:00
eq (
' Vim(windo):E493: Backwards range given: 2,1windo echo ' ,
pcall_err ( command , ' 2,1windo echo ' )
)
2023-05-05 04:03:08 -07:00
end )
2018-01-05 03:17:21 -07:00
end )
describe ( ' nvim_command_output ' , function ( )
it ( ' does not induce hit-enter prompt ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_ui_attach ( 80 , 20 , { } )
2018-01-05 03:17:21 -07:00
-- Induce a hit-enter prompt use nvim_input (non-blocking).
2024-01-12 06:11:28 -07:00
command ( ' set cmdheight=1 ' )
2024-01-12 10:59:57 -07:00
api.nvim_input ( [[:echo "hi\nhi2"<CR>]] )
2018-01-05 03:17:21 -07:00
-- Verify hit-enter prompt.
2024-01-12 10:59:57 -07:00
eq ( { mode = ' r ' , blocking = true } , api.nvim_get_mode ( ) )
api.nvim_input ( [[<C-c>]] )
2018-01-05 03:17:21 -07:00
-- Verify NO hit-enter prompt.
2024-01-12 06:11:28 -07:00
command_output ( [[echo "hi\nhi2"]] )
2024-01-12 10:59:57 -07:00
eq ( { mode = ' n ' , blocking = false } , api.nvim_get_mode ( ) )
2018-01-05 03:17:21 -07:00
end )
2018-01-09 02:36:25 -07:00
it ( ' captures command output ' , function ( )
2024-01-12 06:11:28 -07:00
eq ( ' this is \n spinal tap ' , command_output ( [[echo "this is\nspinal tap"]] ) )
eq ( ' no line ending! ' , command_output ( [[echon "no line ending!"]] ) )
2018-01-05 03:17:21 -07:00
end )
2018-01-09 02:36:25 -07:00
it ( ' captures empty command output ' , function ( )
2024-01-12 06:11:28 -07:00
eq ( ' ' , command_output ( ' echo ' ) )
2018-01-09 02:36:25 -07:00
end )
it ( ' captures single-char command output ' , function ( )
2024-01-12 06:11:28 -07:00
eq ( ' x ' , command_output ( ' echo "x" ' ) )
2018-01-09 02:36:25 -07:00
end )
it ( ' captures multiple commands ' , function ( )
2024-01-12 06:11:28 -07:00
eq ( ' foo \n 1 %a "[No Name]" line 1 ' , command_output ( ' echo "foo" | ls ' ) )
2018-01-09 02:36:25 -07:00
end )
it ( ' captures nested execute() ' , function ( )
2023-12-07 04:19:35 -07:00
eq (
' \n nested1 \n nested2 \n 1 %a "[No Name]" line 1 ' ,
2024-01-12 06:11:28 -07:00
command_output ( [[echo execute('echo "nested1\nnested2"') | ls]] )
2023-12-07 04:19:35 -07:00
)
2018-01-09 02:36:25 -07:00
end )
it ( ' captures nested nvim_command_output() ' , function ( )
2023-12-07 04:19:35 -07:00
eq (
' nested1 \n nested2 \n 1 %a "[No Name]" line 1 ' ,
2024-01-12 06:11:28 -07:00
command_output ( [[echo nvim_command_output('echo "nested1\nnested2"') | ls]] )
2023-12-07 04:19:35 -07:00
)
2018-01-09 02:36:25 -07:00
end )
2018-01-21 11:58:19 -07:00
it ( ' returns shell |:!| output ' , function ( )
2022-11-21 17:13:30 -07:00
local win_lf = is_os ( ' win ' ) and ' \r ' or ' '
2024-01-12 06:11:28 -07:00
eq ( ' :!echo foo \r \n \n foo ' .. win_lf .. ' \n ' , command_output ( [[!echo foo]] ) )
2018-01-05 03:17:21 -07:00
end )
2023-06-22 04:09:14 -07:00
it ( ' Vimscript validation error: fails with specific error ' , function ( )
2024-01-12 06:11:28 -07:00
local status , rv = pcall ( command_output , ' bogus commannnd ' )
2023-12-07 04:19:35 -07:00
eq ( false , status ) -- nvim_command_output() failed.
eq ( ' E492: Not an editor command: bogus commannnd ' , string.match ( rv , ' E%d*:.* ' ) )
eq ( ' ' , eval ( ' v:errmsg ' ) ) -- v:errmsg was not updated.
2018-01-05 03:17:21 -07:00
-- Verify NO hit-enter prompt.
2024-01-12 10:59:57 -07:00
eq ( { mode = ' n ' , blocking = false } , api.nvim_get_mode ( ) )
2018-01-05 03:17:21 -07:00
end )
2023-06-22 04:09:14 -07:00
it ( ' Vimscript execution error: fails with specific error ' , function ( )
2024-01-12 06:11:28 -07:00
local status , rv = pcall ( command_output , ' buffer 42 ' )
2023-12-07 04:19:35 -07:00
eq ( false , status ) -- nvim_command_output() failed.
eq ( ' E86: Buffer 42 does not exist ' , string.match ( rv , ' E%d*:.* ' ) )
eq ( ' ' , eval ( ' v:errmsg ' ) ) -- v:errmsg was not updated.
2018-01-05 03:17:21 -07:00
-- Verify NO hit-enter prompt.
2024-01-12 10:59:57 -07:00
eq ( { mode = ' n ' , blocking = false } , api.nvim_get_mode ( ) )
2018-01-05 03:17:21 -07:00
end )
2019-08-22 01:07:54 -07:00
2023-07-05 21:56:19 -07:00
it ( ' does not cause heap buffer overflow with large output ' , function ( )
2024-01-12 06:11:28 -07:00
eq ( eval ( ' string(range(1000000)) ' ) , command_output ( ' echo range(1000000) ' ) )
2019-08-22 01:07:54 -07:00
end )
2014-10-08 09:56:01 -07:00
end )
2016-10-22 15:02:22 -07:00
describe ( ' nvim_eval ' , function ( )
2014-10-08 09:56:01 -07:00
it ( ' works ' , function ( )
2024-01-12 06:11:28 -07:00
command ( ' let g:v1 = "a" ' )
command ( ' let g:v2 = [1, 2, {"v3": 3}] ' )
2024-01-12 10:59:57 -07:00
eq ( { v1 = ' a ' , v2 = { 1 , 2 , { v3 = 3 } } } , api.nvim_eval ( ' g: ' ) )
2014-10-08 09:56:01 -07:00
end )
2015-02-12 10:55:13 -07:00
it ( ' handles NULL-initialized strings correctly ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( 1 , api.nvim_eval ( " matcharg(1) == ['', ''] " ) )
eq ( { ' ' , ' ' } , api.nvim_eval ( ' matcharg(1) ' ) )
2015-02-12 10:55:13 -07:00
end )
2016-06-28 12:45:19 -07:00
it ( ' works under deprecated name ' , function ( )
2023-12-07 04:19:35 -07:00
eq ( 2 , request ( ' vim_eval ' , ' 1+1 ' ) )
2016-06-28 12:45:19 -07:00
end )
2016-10-22 15:02:22 -07:00
2023-12-07 04:19:35 -07:00
it ( ' Vimscript error: returns error details, does NOT update v:errmsg ' , function ( )
eq ( ' Vim:E121: Undefined variable: bogus ' , pcall_err ( request , ' nvim_eval ' , ' bogus expression ' ) )
eq ( ' ' , eval ( ' v:errmsg ' ) ) -- v:errmsg was not updated.
2016-10-22 15:02:22 -07:00
end )
2024-04-16 15:34:10 -07:00
it ( ' can return Lua function to Lua code ' , function ( )
eq (
[["a string with \"double quotes\" and 'single quotes'"]] ,
exec_lua ( [ = [
local fun = vim.api . nvim_eval ( [[luaeval('string.format')]] )
return fun ( ' %q ' , [[a string with "double quotes" and 'single quotes']] )
] = ] )
)
end )
2014-10-08 09:56:01 -07:00
end )
2016-10-22 15:02:22 -07:00
describe ( ' nvim_call_function ' , function ( )
2015-07-07 22:40:28 -07:00
it ( ' works ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_call_function ( ' setqflist ' , { { { filename = ' something ' , lnum = 17 } } , ' r ' } )
eq ( 17 , api.nvim_call_function ( ' getqflist ' , { } ) [ 1 ] . lnum )
eq ( 17 , api.nvim_call_function ( ' eval ' , { 17 } ) )
eq ( ' foo ' , api.nvim_call_function ( ' simplify ' , { ' this/./is//redundant/../../../foo ' } ) )
2023-12-07 04:19:35 -07:00
end )
it ( ' Vimscript validation error: returns specific error, does NOT update v:errmsg ' , function ( )
eq (
' Vim:E117: Unknown function: bogus function ' ,
pcall_err ( request , ' nvim_call_function ' , ' bogus function ' , { ' arg1 ' } )
)
eq (
' Vim:E119: Not enough arguments for function: atan ' ,
pcall_err ( request , ' nvim_call_function ' , ' atan ' , { } )
)
2018-05-06 18:24:01 -07:00
eq ( ' ' , eval ( ' v:exception ' ) )
2023-12-07 04:19:35 -07:00
eq ( ' ' , eval ( ' v:errmsg ' ) ) -- v:errmsg was not updated.
end )
it ( ' Vimscript error: returns error details, does NOT update v:errmsg ' , function ( )
eq (
' Vim:E808: Number or Float required ' ,
pcall_err ( request , ' nvim_call_function ' , ' atan ' , { ' foo ' } )
)
eq (
' Vim:Invalid channel stream "xxx" ' ,
pcall_err ( request , ' nvim_call_function ' , ' chanclose ' , { 999 , ' xxx ' } )
)
eq (
' Vim:E900: Invalid channel id ' ,
pcall_err ( request , ' nvim_call_function ' , ' chansend ' , { 999 , ' foo ' } )
)
2018-05-06 18:24:01 -07:00
eq ( ' ' , eval ( ' v:exception ' ) )
2023-12-07 04:19:35 -07:00
eq ( ' ' , eval ( ' v:errmsg ' ) ) -- v:errmsg was not updated.
2018-05-06 18:24:01 -07:00
end )
2023-12-07 04:19:35 -07:00
it ( ' Vimscript exception: returns exception details, does NOT update v:errmsg ' , function ( )
2018-05-06 18:24:01 -07:00
source ( [ [
function ! Foo ( ) abort
throw ' wtf '
endfunction
] ] )
2023-01-15 15:38:50 -07:00
eq ( ' function Foo, line 1: wtf ' , pcall_err ( request , ' nvim_call_function ' , ' Foo ' , { } ) )
2018-05-06 18:24:01 -07:00
eq ( ' ' , eval ( ' v:exception ' ) )
2023-12-07 04:19:35 -07:00
eq ( ' ' , eval ( ' v:errmsg ' ) ) -- v:errmsg was not updated.
2016-10-22 15:02:22 -07:00
end )
2018-05-06 18:24:01 -07:00
2023-02-14 12:19:28 -07:00
it ( ' validation ' , function ( )
2023-12-07 04:19:35 -07:00
-- stylua: ignore
2018-05-03 23:23:37 -07:00
local too_many_args = { ' x ' , ' x ' , ' x ' , ' x ' , ' x ' , ' x ' , ' x ' , ' x ' , ' x ' , ' x ' , ' x ' , ' x ' , ' x ' , ' x ' , ' x ' , ' x ' , ' x ' , ' x ' , ' x ' , ' x ' , ' x ' }
source ( [ [
function ! Foo ( ... ) abort
echo a : 000
endfunction
] ] )
-- E740
2023-12-07 04:19:35 -07:00
eq (
' Function called with too many arguments ' ,
pcall_err ( request , ' nvim_call_function ' , ' Foo ' , too_many_args )
)
2018-05-03 23:23:37 -07:00
end )
2024-04-16 15:34:10 -07:00
it ( ' can return Lua function to Lua code ' , function ( )
eq (
[["a string with \"double quotes\" and 'single quotes'"]] ,
exec_lua ( [ = [
local fun = vim.api . nvim_call_function ( ' luaeval ' , { ' string.format ' } )
return fun ( ' %q ' , [[a string with "double quotes" and 'single quotes']] )
] = ] )
)
end )
2016-10-22 15:02:22 -07:00
end )
2018-05-02 14:38:18 -07:00
describe ( ' nvim_call_dict_function ' , function ( )
2023-06-22 04:09:14 -07:00
it ( ' invokes Vimscript dict function ' , function ( )
2018-05-03 23:20:37 -07:00
source ( [ [
function ! F ( name ) dict
2018-05-06 05:37:51 -07:00
return self.greeting . ' , ' . a : name . ' ! '
endfunction
let g : test_dict_fn = { ' greeting ' : ' Hello ' , ' F ' : function ( ' F ' ) }
let g : test_dict_fn2 = { ' greeting ' : ' Hi ' }
function g : test_dict_fn2 . F2 ( name )
return self.greeting . ' , ' . a : name . ' ... '
2018-05-03 23:20:37 -07:00
endfunction
] ] )
2018-05-06 05:37:51 -07:00
-- :help Dictionary-function
2024-01-12 10:59:57 -07:00
eq ( ' Hello, World! ' , api.nvim_call_dict_function ( ' g:test_dict_fn ' , ' F ' , { ' World ' } ) )
2018-05-06 05:37:51 -07:00
-- Funcref is sent as NIL over RPC.
2024-01-12 10:59:57 -07:00
eq ( { greeting = ' Hello ' , F = NIL } , api.nvim_get_var ( ' test_dict_fn ' ) )
2018-05-03 23:20:37 -07:00
2018-05-06 05:37:51 -07:00
-- :help numbered-function
2024-01-12 10:59:57 -07:00
eq ( ' Hi, Moon ... ' , api.nvim_call_dict_function ( ' g:test_dict_fn2 ' , ' F2 ' , { ' Moon ' } ) )
2018-05-06 05:37:51 -07:00
-- Funcref is sent as NIL over RPC.
2024-01-12 10:59:57 -07:00
eq ( { greeting = ' Hi ' , F2 = NIL } , api.nvim_get_var ( ' test_dict_fn2 ' ) )
2018-05-06 05:37:51 -07:00
-- Function specified via RPC dict.
source ( ' function! G() dict \n return "@".(self.result)."@" \n endfunction ' )
2024-01-12 10:59:57 -07:00
eq ( ' @it works@ ' , api.nvim_call_dict_function ( { result = ' it works ' , G = ' G ' } , ' G ' , { } ) )
2018-05-02 14:38:18 -07:00
end )
2018-05-06 05:37:51 -07:00
2023-02-14 12:19:28 -07:00
it ( ' validation ' , function ( )
2018-05-02 15:20:14 -07:00
command ( ' let g:d={"baz":"zub","meep":[]} ' )
2023-12-07 04:19:35 -07:00
eq (
' Not found: bogus ' ,
pcall_err ( request , ' nvim_call_dict_function ' , ' g:d ' , ' bogus ' , { 1 , 2 } )
)
eq (
' Not a function: baz ' ,
pcall_err ( request , ' nvim_call_dict_function ' , ' g:d ' , ' baz ' , { 1 , 2 } )
)
eq (
' Not a function: meep ' ,
pcall_err ( request , ' nvim_call_dict_function ' , ' g:d ' , ' meep ' , { 1 , 2 } )
)
eq (
' Vim:E117: Unknown function: f ' ,
pcall_err ( request , ' nvim_call_dict_function ' , { f = ' ' } , ' f ' , { 1 , 2 } )
)
eq (
' Not a function: f ' ,
pcall_err ( request , ' nvim_call_dict_function ' , " { 'f': '' } " , ' f ' , { 1 , 2 } )
)
eq (
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
' dict argument type must be String or Dict ' ,
2023-12-07 04:19:35 -07:00
pcall_err ( request , ' nvim_call_dict_function ' , 42 , ' f ' , { 1 , 2 } )
)
eq (
' Failed to evaluate dict expression ' ,
pcall_err ( request , ' nvim_call_dict_function ' , ' foo ' , ' f ' , { 1 , 2 } )
)
eq ( ' dict not found ' , pcall_err ( request , ' nvim_call_dict_function ' , ' 42 ' , ' f ' , { 1 , 2 } ) )
eq (
' Invalid (empty) function name ' ,
pcall_err ( request , ' nvim_call_dict_function ' , " { 'f': '' } " , ' ' , { 1 , 2 } )
)
2018-05-02 14:38:18 -07:00
end )
end )
2022-02-09 18:41:25 -07:00
describe ( ' nvim_set_current_dir ' , function ( )
local start_dir
before_each ( function ( )
2024-01-12 10:59:57 -07:00
fn.mkdir ( ' Xtestdir ' )
start_dir = fn.getcwd ( )
2022-02-09 18:41:25 -07:00
end )
after_each ( function ( )
2024-04-20 08:44:13 -07:00
n.rmdir ( ' Xtestdir ' )
2022-02-09 18:41:25 -07:00
end )
it ( ' works ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_set_current_dir ( ' Xtestdir ' )
2024-04-20 08:44:13 -07:00
eq ( start_dir .. n.get_pathsep ( ) .. ' Xtestdir ' , fn.getcwd ( ) )
2022-02-09 18:41:25 -07:00
end )
it ( ' sets previous directory ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_set_current_dir ( ' Xtestdir ' )
2023-03-25 19:49:32 -07:00
command ( ' cd - ' )
2024-03-11 07:23:14 -07:00
eq ( start_dir , fn.getcwd ( ) )
2022-02-09 18:41:25 -07:00
end )
end )
2019-12-02 01:46:46 -07:00
describe ( ' nvim_exec_lua ' , function ( )
2017-05-08 23:55:04 -07:00
it ( ' works ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_exec_lua ( ' vim.api.nvim_set_var("test", 3) ' , { } )
eq ( 3 , api.nvim_get_var ( ' test ' ) )
2017-05-08 23:55:04 -07:00
2024-01-12 10:59:57 -07:00
eq ( 17 , api.nvim_exec_lua ( ' a, b = ... \n return a + b ' , { 10 , 7 } ) )
2017-05-08 23:55:04 -07:00
2024-01-12 10:59:57 -07:00
eq ( NIL , api.nvim_exec_lua ( ' function xx(a,b) \n return a..b \n end ' , { } ) )
eq ( ' xy ' , api.nvim_exec_lua ( ' return xx(...) ' , { ' x ' , ' y ' } ) )
2019-12-02 01:46:46 -07:00
-- Deprecated name: nvim_execute_lua.
2024-01-12 10:59:57 -07:00
eq ( ' xy ' , api.nvim_execute_lua ( ' return xx(...) ' , { ' x ' , ' y ' } ) )
2017-05-08 23:55:04 -07:00
end )
it ( ' reports errors ' , function ( )
2023-12-07 04:19:35 -07:00
eq (
[[Error loading lua: [string "<nvim>"]:0: '=' expected near '+']] ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_exec_lua , ' a+*b ' , { } )
2023-12-07 04:19:35 -07:00
)
2017-05-08 23:55:04 -07:00
2023-12-07 04:19:35 -07:00
eq (
[[Error loading lua: [string "<nvim>"]:0: unexpected symbol near '1']] ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_exec_lua , ' 1+2 ' , { } )
2023-12-07 04:19:35 -07:00
)
2017-05-08 23:55:04 -07:00
2023-12-07 04:19:35 -07:00
eq (
[[Error loading lua: [string "<nvim>"]:0: unexpected symbol]] ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_exec_lua , ' aa=bb \0 ' , { } )
2023-12-07 04:19:35 -07:00
)
2017-05-08 23:55:04 -07:00
2024-01-12 05:44:54 -07:00
eq (
[[attempt to call global 'bork' (a nil value)]] ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_exec_lua , ' bork() ' , { } )
2024-01-12 05:44:54 -07:00
)
2019-01-22 11:55:31 -07:00
2024-01-12 10:59:57 -07:00
eq ( ' did \n the \n fail ' , pcall_err ( api.nvim_exec_lua , ' error("did \\ nthe \\ nfail") ' , { } ) )
2017-05-08 23:55:04 -07:00
end )
2019-07-01 06:50:57 -07:00
it ( ' uses native float values ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( 2.5 , api.nvim_exec_lua ( ' return select(1, ...) ' , { 2.5 } ) )
eq ( ' 2.5 ' , api.nvim_exec_lua ( ' return vim.inspect(...) ' , { 2.5 } ) )
2019-07-01 06:50:57 -07:00
-- "special" float values are still accepted as return values.
2024-01-12 10:59:57 -07:00
eq ( 2.5 , api.nvim_exec_lua ( " return vim.api.nvim_eval('2.5') " , { } ) )
2023-12-07 04:19:35 -07:00
eq (
' { \n [false] = 2.5, \n [true] = 3 \n } ' ,
2024-01-12 10:59:57 -07:00
api.nvim_exec_lua ( " return vim.inspect(vim.api.nvim_eval('2.5')) " , { } )
2023-12-07 04:19:35 -07:00
)
2019-07-01 06:50:57 -07:00
end )
2017-05-08 23:55:04 -07:00
end )
2021-02-01 15:16:50 -07:00
describe ( ' nvim_notify ' , function ( )
2021-02-09 03:41:02 -07:00
it ( ' can notify a info message ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_notify ( ' hello world ' , 2 , { } )
2021-02-09 03:41:02 -07:00
end )
2021-09-17 10:07:00 -07:00
it ( ' can be overridden ' , function ( )
2023-12-07 04:19:35 -07:00
command ( ' lua vim.notify = function(...) return 42 end ' )
2024-01-12 10:59:57 -07:00
eq ( 42 , api.nvim_exec_lua ( " return vim.notify('Hello world') " , { } ) )
api.nvim_notify ( ' hello world ' , 4 , { } )
2021-02-01 15:16:50 -07:00
end )
end )
2016-10-22 15:02:22 -07:00
describe ( ' nvim_input ' , function ( )
2023-12-07 04:19:35 -07:00
it ( ' Vimscript error: does NOT fail, updates v:errmsg ' , function ( )
2024-01-12 10:59:57 -07:00
local status , _ = pcall ( api.nvim_input , ' :call bogus_fn()<CR> ' )
local v_errnum = string.match ( api.nvim_eval ( ' v:errmsg ' ) , ' E%d*: ' )
2023-12-07 04:19:35 -07:00
eq ( true , status ) -- nvim_input() did not fail.
eq ( ' E117: ' , v_errnum ) -- v:errmsg was updated.
2016-10-22 15:02:22 -07:00
end )
2020-05-24 22:57:44 -07:00
it ( ' does not crash even if trans_special result is largest #11788, #12287 ' , function ( )
command ( " call nvim_input('<M-'.nr2char(0x40000000).'>') " )
eq ( 1 , eval ( ' 1 ' ) )
end )
2015-07-07 22:40:28 -07:00
end )
2019-08-24 04:54:27 -07:00
describe ( ' nvim_paste ' , function ( )
2023-02-14 12:19:28 -07:00
it ( ' validation ' , function ( )
2023-12-07 04:19:35 -07:00
eq ( " Invalid 'phase': -2 " , pcall_err ( request , ' nvim_paste ' , ' foo ' , true , - 2 ) )
eq ( " Invalid 'phase': 4 " , pcall_err ( request , ' nvim_paste ' , ' foo ' , true , 4 ) )
2019-08-24 04:54:27 -07:00
end )
2022-03-05 15:56:24 -07:00
local function run_streamed_paste_tests ( )
it ( ' stream: multiple chunks form one undo-block ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' 1/chunk 1 (start) \n ' , true , 1 )
api.nvim_paste ( ' 1/chunk 2 (end) \n ' , true , 3 )
2022-03-05 15:56:24 -07:00
local expected1 = [ [
1 / chunk 1 ( start )
1 / chunk 2 ( end )
] ]
expect ( expected1 )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' 2/chunk 1 (start) \n ' , true , 1 )
api.nvim_paste ( ' 2/chunk 2 \n ' , true , 2 )
2022-03-05 15:56:24 -07:00
expect ( [ [
1 / chunk 1 ( start )
1 / chunk 2 ( end )
2 / chunk 1 ( start )
2 / chunk 2
] ] )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' 2/chunk 3 \n ' , true , 2 )
api.nvim_paste ( ' 2/chunk 4 (end) \n ' , true , 3 )
2022-03-05 15:56:24 -07:00
expect ( [ [
1 / chunk 1 ( start )
1 / chunk 2 ( end )
2 / chunk 1 ( start )
2 / chunk 2
2 / chunk 3
2 / chunk 4 ( end )
] ] )
2023-12-07 04:19:35 -07:00
feed ( ' u ' ) -- Undo.
2022-03-05 15:56:24 -07:00
expect ( expected1 )
2022-03-05 15:56:24 -07:00
end )
2022-03-05 15:56:24 -07:00
it ( ' stream: Insert mode ' , function ( )
2022-03-05 15:56:24 -07:00
-- If nvim_paste() calls :undojoin without making any changes, this makes it an error.
feed ( ' afoo<Esc>u ' )
2022-03-05 15:56:24 -07:00
feed ( ' i ' )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' aaaaaa ' , false , 1 )
api.nvim_paste ( ' bbbbbb ' , false , 2 )
api.nvim_paste ( ' cccccc ' , false , 2 )
api.nvim_paste ( ' dddddd ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( ' aaaaaabbbbbbccccccdddddd ' )
feed ( ' <Esc>u ' )
expect ( ' ' )
2022-03-05 15:56:24 -07:00
end )
2022-03-05 15:56:24 -07:00
describe ( ' stream: Normal mode ' , function ( )
describe ( ' on empty line ' , function ( )
before_each ( function ( )
-- If nvim_paste() calls :undojoin without making any changes, this makes it an error.
feed ( ' afoo<Esc>u ' )
end )
after_each ( function ( )
feed ( ' u ' )
expect ( ' ' )
end )
it ( ' pasting one line ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' aaaaaa ' , false , 1 )
api.nvim_paste ( ' bbbbbb ' , false , 2 )
api.nvim_paste ( ' cccccc ' , false , 2 )
api.nvim_paste ( ' dddddd ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( ' aaaaaabbbbbbccccccdddddd ' )
end )
it ( ' pasting multiple lines ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' aaaaaa \n ' , false , 1 )
api.nvim_paste ( ' bbbbbb \n ' , false , 2 )
api.nvim_paste ( ' cccccc \n ' , false , 2 )
api.nvim_paste ( ' dddddd ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( [ [
2022-03-05 15:56:24 -07:00
aaaaaa
bbbbbb
cccccc
2022-03-05 15:56:24 -07:00
dddddd ] ] )
end )
end )
describe ( ' not at the end of a line ' , function ( )
before_each ( function ( )
feed ( ' i||<Esc> ' )
-- If nvim_paste() calls :undojoin without making any changes, this makes it an error.
feed ( ' afoo<Esc>u ' )
feed ( ' 0 ' )
end )
after_each ( function ( )
feed ( ' u ' )
expect ( ' || ' )
end )
it ( ' pasting one line ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' aaaaaa ' , false , 1 )
api.nvim_paste ( ' bbbbbb ' , false , 2 )
api.nvim_paste ( ' cccccc ' , false , 2 )
api.nvim_paste ( ' dddddd ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( ' |aaaaaabbbbbbccccccdddddd| ' )
end )
it ( ' pasting multiple lines ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' aaaaaa \n ' , false , 1 )
api.nvim_paste ( ' bbbbbb \n ' , false , 2 )
api.nvim_paste ( ' cccccc \n ' , false , 2 )
api.nvim_paste ( ' dddddd ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( [ [
| aaaaaa
2022-03-05 15:56:24 -07:00
bbbbbb
cccccc
2022-03-05 15:56:24 -07:00
dddddd | ] ] )
end )
end )
describe ( ' at the end of a line ' , function ( )
before_each ( function ( )
feed ( ' i||<Esc> ' )
-- If nvim_paste() calls :undojoin without making any changes, this makes it an error.
feed ( ' afoo<Esc>u ' )
feed ( ' 2| ' )
end )
after_each ( function ( )
feed ( ' u ' )
expect ( ' || ' )
end )
it ( ' pasting one line ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' aaaaaa ' , false , 1 )
api.nvim_paste ( ' bbbbbb ' , false , 2 )
api.nvim_paste ( ' cccccc ' , false , 2 )
api.nvim_paste ( ' dddddd ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( ' ||aaaaaabbbbbbccccccdddddd ' )
end )
it ( ' pasting multiple lines ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' aaaaaa \n ' , false , 1 )
api.nvim_paste ( ' bbbbbb \n ' , false , 2 )
api.nvim_paste ( ' cccccc \n ' , false , 2 )
api.nvim_paste ( ' dddddd ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( [ [
|| aaaaaa
bbbbbb
cccccc
dddddd ] ] )
end )
2022-03-05 15:56:24 -07:00
end )
end )
2022-03-05 15:56:24 -07:00
describe ( ' stream: Visual mode ' , function ( )
describe ( ' neither end at the end of a line ' , function ( )
before_each ( function ( )
feed ( ' i|xxx<CR>xxx|<Esc> ' )
-- If nvim_paste() calls :undojoin without making any changes, this makes it an error.
feed ( ' afoo<Esc>u ' )
feed ( ' 3|vhk ' )
end )
after_each ( function ( )
feed ( ' u ' )
expect ( [ [
| xxx
xxx | ] ] )
end )
it ( ' with non-empty chunks ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' aaaaaa ' , false , 1 )
api.nvim_paste ( ' bbbbbb ' , false , 2 )
api.nvim_paste ( ' cccccc ' , false , 2 )
api.nvim_paste ( ' dddddd ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( ' |aaaaaabbbbbbccccccdddddd| ' )
end )
it ( ' with empty first chunk ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' ' , false , 1 )
api.nvim_paste ( ' bbbbbb ' , false , 2 )
api.nvim_paste ( ' cccccc ' , false , 2 )
api.nvim_paste ( ' dddddd ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( ' |bbbbbbccccccdddddd| ' )
end )
it ( ' with all chunks empty ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' ' , false , 1 )
api.nvim_paste ( ' ' , false , 2 )
api.nvim_paste ( ' ' , false , 2 )
api.nvim_paste ( ' ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( ' || ' )
end )
end )
describe ( ' cursor at the end of a line ' , function ( )
before_each ( function ( )
feed ( ' i||xxx<CR>xxx<Esc> ' )
-- If nvim_paste() calls :undojoin without making any changes, this makes it an error.
feed ( ' afoo<Esc>u ' )
feed ( ' 3|vko ' )
end )
after_each ( function ( )
feed ( ' u ' )
expect ( [ [
|| xxx
xxx ] ] )
end )
it ( ' with non-empty chunks ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' aaaaaa ' , false , 1 )
api.nvim_paste ( ' bbbbbb ' , false , 2 )
api.nvim_paste ( ' cccccc ' , false , 2 )
api.nvim_paste ( ' dddddd ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( ' ||aaaaaabbbbbbccccccdddddd ' )
end )
it ( ' with empty first chunk ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' ' , false , 1 )
api.nvim_paste ( ' bbbbbb ' , false , 2 )
api.nvim_paste ( ' cccccc ' , false , 2 )
api.nvim_paste ( ' dddddd ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( ' ||bbbbbbccccccdddddd ' )
end )
end )
describe ( ' other end at the end of a line ' , function ( )
before_each ( function ( )
feed ( ' i||xxx<CR>xxx<Esc> ' )
-- If nvim_paste() calls :undojoin without making any changes, this makes it an error.
feed ( ' afoo<Esc>u ' )
feed ( ' 3|vk ' )
end )
after_each ( function ( )
feed ( ' u ' )
expect ( [ [
|| xxx
xxx ] ] )
end )
it ( ' with non-empty chunks ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' aaaaaa ' , false , 1 )
api.nvim_paste ( ' bbbbbb ' , false , 2 )
api.nvim_paste ( ' cccccc ' , false , 2 )
api.nvim_paste ( ' dddddd ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( ' ||aaaaaabbbbbbccccccdddddd ' )
end )
it ( ' with empty first chunk ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' ' , false , 1 )
api.nvim_paste ( ' bbbbbb ' , false , 2 )
api.nvim_paste ( ' cccccc ' , false , 2 )
api.nvim_paste ( ' dddddd ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( ' ||bbbbbbccccccdddddd ' )
end )
2022-03-05 15:56:24 -07:00
end )
end )
2022-03-05 15:56:24 -07:00
describe ( ' stream: linewise Visual mode ' , function ( )
2022-03-05 15:56:24 -07:00
before_each ( function ( )
2022-03-05 15:56:24 -07:00
feed ( ' i123456789<CR>987654321<CR>123456789<Esc> ' )
-- If nvim_paste() calls :undojoin without making any changes, this makes it an error.
feed ( ' afoo<Esc>u ' )
2022-03-05 15:56:24 -07:00
end )
2022-03-05 15:56:24 -07:00
after_each ( function ( )
feed ( ' u ' )
2022-03-05 15:56:24 -07:00
expect ( [ [
123456789
987654321
2022-03-05 15:56:24 -07:00
123456789 ] ] )
2022-03-05 15:56:24 -07:00
end )
2022-03-05 15:56:24 -07:00
describe ( ' selecting the start of a file ' , function ( )
before_each ( function ( )
feed ( ' ggV ' )
end )
it ( ' pasting text without final new line ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' aaaaaa \n ' , false , 1 )
api.nvim_paste ( ' bbbbbb \n ' , false , 2 )
api.nvim_paste ( ' cccccc \n ' , false , 2 )
api.nvim_paste ( ' dddddd ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( [ [
aaaaaa
bbbbbb
cccccc
dddddd987654321
123456789 ] ] )
end )
it ( ' pasting text with final new line ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' aaaaaa \n ' , false , 1 )
api.nvim_paste ( ' bbbbbb \n ' , false , 2 )
api.nvim_paste ( ' cccccc \n ' , false , 2 )
api.nvim_paste ( ' dddddd \n ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( [ [
aaaaaa
bbbbbb
cccccc
dddddd
987654321
123456789 ] ] )
end )
end )
describe ( ' selecting the middle of a file ' , function ( )
before_each ( function ( )
feed ( ' 2ggV ' )
end )
it ( ' pasting text without final new line ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' aaaaaa \n ' , false , 1 )
api.nvim_paste ( ' bbbbbb \n ' , false , 2 )
api.nvim_paste ( ' cccccc \n ' , false , 2 )
api.nvim_paste ( ' dddddd ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( [ [
123456789
aaaaaa
bbbbbb
cccccc
dddddd123456789 ] ] )
end )
it ( ' pasting text with final new line ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' aaaaaa \n ' , false , 1 )
api.nvim_paste ( ' bbbbbb \n ' , false , 2 )
api.nvim_paste ( ' cccccc \n ' , false , 2 )
api.nvim_paste ( ' dddddd \n ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( [ [
123456789
aaaaaa
bbbbbb
cccccc
dddddd
123456789 ] ] )
end )
end )
describe ( ' selecting the end of a file ' , function ( )
before_each ( function ( )
feed ( ' 3ggV ' )
end )
it ( ' pasting text without final new line ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' aaaaaa \n ' , false , 1 )
api.nvim_paste ( ' bbbbbb \n ' , false , 2 )
api.nvim_paste ( ' cccccc \n ' , false , 2 )
api.nvim_paste ( ' dddddd ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( [ [
123456789
987654321
aaaaaa
bbbbbb
cccccc
dddddd ] ] )
end )
it ( ' pasting text with final new line ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' aaaaaa \n ' , false , 1 )
api.nvim_paste ( ' bbbbbb \n ' , false , 2 )
api.nvim_paste ( ' cccccc \n ' , false , 2 )
api.nvim_paste ( ' dddddd \n ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( [ [
123456789
987654321
aaaaaa
bbbbbb
cccccc
dddddd
] ] )
end )
end )
describe ( ' selecting the whole file ' , function ( )
before_each ( function ( )
feed ( ' ggVG ' )
end )
it ( ' pasting text without final new line ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' aaaaaa \n ' , false , 1 )
api.nvim_paste ( ' bbbbbb \n ' , false , 2 )
api.nvim_paste ( ' cccccc \n ' , false , 2 )
api.nvim_paste ( ' dddddd ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( [ [
aaaaaa
bbbbbb
cccccc
dddddd ] ] )
end )
it ( ' pasting text with final new line ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' aaaaaa \n ' , false , 1 )
api.nvim_paste ( ' bbbbbb \n ' , false , 2 )
api.nvim_paste ( ' cccccc \n ' , false , 2 )
api.nvim_paste ( ' dddddd \n ' , false , 3 )
2022-03-05 15:56:24 -07:00
expect ( [ [
aaaaaa
bbbbbb
cccccc
dddddd
] ] )
end )
2022-03-05 15:56:24 -07:00
end )
end )
2022-03-05 15:56:24 -07:00
end
describe ( ' without virtualedit, ' , function ( )
run_streamed_paste_tests ( )
end )
describe ( ' with virtualedit=onemore, ' , function ( )
before_each ( function ( )
command ( ' set virtualedit=onemore ' )
2022-03-05 15:56:24 -07:00
end )
2022-03-05 15:56:24 -07:00
run_streamed_paste_tests ( )
2022-03-05 15:56:24 -07:00
end )
2019-08-24 04:54:27 -07:00
it ( ' non-streaming ' , function ( )
-- With final "\n".
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' line 1 \n line 2 \n line 3 \n ' , true , - 1 )
2019-08-24 04:54:27 -07:00
expect ( [ [
line 1
line 2
line 3
] ] )
2024-01-12 10:59:57 -07:00
eq ( { 0 , 4 , 1 , 0 } , fn.getpos ( ' . ' ) ) -- Cursor follows the paste.
eq ( false , api.nvim_get_option_value ( ' paste ' , { } ) )
2019-08-24 04:54:27 -07:00
command ( ' %delete _ ' )
-- Without final "\n".
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' line 1 \n line 2 \n line 3 ' , true , - 1 )
2019-08-24 04:54:27 -07:00
expect ( [ [
line 1
line 2
line 3 ] ] )
2024-01-12 10:59:57 -07:00
eq ( { 0 , 3 , 6 , 0 } , fn.getpos ( ' . ' ) )
2019-08-29 14:45:02 -07:00
command ( ' %delete _ ' )
-- CRLF #10872
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' line 1 \r \n line 2 \r \n line 3 \r \n ' , true , - 1 )
2019-08-29 14:45:02 -07:00
expect ( [ [
line 1
line 2
line 3
] ] )
2024-01-12 10:59:57 -07:00
eq ( { 0 , 4 , 1 , 0 } , fn.getpos ( ' . ' ) )
2019-08-29 14:45:02 -07:00
command ( ' %delete _ ' )
-- CRLF without final "\n".
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' line 1 \r \n line 2 \r \n line 3 \r ' , true , - 1 )
2019-08-29 14:45:02 -07:00
expect ( [ [
line 1
line 2
line 3
] ] )
2024-01-12 10:59:57 -07:00
eq ( { 0 , 4 , 1 , 0 } , fn.getpos ( ' . ' ) )
2019-08-29 14:45:02 -07:00
command ( ' %delete _ ' )
-- CRLF without final "\r\n".
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' line 1 \r \n line 2 \r \n line 3 ' , true , - 1 )
2019-08-29 14:45:02 -07:00
expect ( [ [
line 1
line 2
line 3 ] ] )
2024-01-12 10:59:57 -07:00
eq ( { 0 , 3 , 6 , 0 } , fn.getpos ( ' . ' ) )
2019-08-29 14:45:02 -07:00
command ( ' %delete _ ' )
-- Various other junk.
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' line 1 \r \n \r \r line 2 \n line 3 \r line 4 \r ' , true , - 1 )
2019-08-29 14:45:02 -07:00
expect ( ' line 1 \n \n \n line 2 \n line 3 \n line 4 \n ' )
2024-01-12 10:59:57 -07:00
eq ( { 0 , 7 , 1 , 0 } , fn.getpos ( ' . ' ) )
eq ( false , api.nvim_get_option_value ( ' paste ' , { } ) )
2019-08-24 04:54:27 -07:00
end )
2020-05-05 04:18:41 -07:00
it ( ' Replace-mode ' , function ( )
-- Within single line
2024-01-12 10:59:57 -07:00
api.nvim_put ( { ' aabbccdd ' , ' eeffgghh ' , ' iijjkkll ' } , ' c ' , true , false )
2020-05-05 04:18:41 -07:00
command ( ' normal l ' )
command ( ' startreplace ' )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' 123456 ' , true , - 1 )
2020-05-05 04:18:41 -07:00
expect ( [ [
a123456d
eeffgghh
iijjkkll ] ] )
command ( ' %delete _ ' )
-- Across lines
2024-01-12 10:59:57 -07:00
api.nvim_put ( { ' aabbccdd ' , ' eeffgghh ' , ' iijjkkll ' } , ' c ' , true , false )
2020-05-05 04:18:41 -07:00
command ( ' normal l ' )
command ( ' startreplace ' )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' 123 \n 456 ' , true , - 1 )
2020-05-05 04:18:41 -07:00
expect ( [ [
a123
456 d
eeffgghh
iijjkkll ] ] )
end )
2022-03-05 15:56:24 -07:00
it ( ' when searching in Visual mode ' , function ( )
feed ( ' v/ ' )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' aabbccdd ' , true , - 1 )
eq ( ' aabbccdd ' , fn.getcmdline ( ) )
2022-03-05 15:56:24 -07:00
expect ( ' ' )
end )
2022-04-16 17:11:53 -07:00
it ( ' mappings are disabled in Cmdline mode ' , function ( )
command ( ' cnoremap a b ' )
feed ( ' : ' )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' a ' , true , - 1 )
eq ( ' a ' , fn.getcmdline ( ) )
2022-04-16 17:11:53 -07:00
end )
2022-11-05 21:43:05 -07:00
it ( ' pasted text is saved in cmdline history when <CR> comes from mapping #20957 ' , function ( )
command ( ' cnoremap <CR> <CR> ' )
feed ( ' : ' )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' echo ' , true , - 1 )
eq ( ' ' , fn.histget ( ' : ' ) )
2022-11-05 21:43:05 -07:00
feed ( ' <CR> ' )
2024-01-12 10:59:57 -07:00
eq ( ' echo ' , fn.histget ( ' : ' ) )
2022-11-05 21:43:05 -07:00
end )
2022-03-05 15:56:24 -07:00
it ( ' pasting with empty last chunk in Cmdline mode ' , function ( )
local screen = Screen.new ( 20 , 4 )
screen : attach ( )
feed ( ' : ' )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' Foo ' , true , 1 )
api.nvim_paste ( ' ' , true , 3 )
2022-03-05 15:56:24 -07:00
screen : expect ( [ [
|
2024-03-22 03:02:52 -07:00
{ 1 : ~ } |* 2
2022-03-05 15:56:24 -07:00
: Foo ^ |
] ] )
end )
2022-03-14 15:04:50 -07:00
it ( ' pasting text with control characters in Cmdline mode ' , function ( )
local screen = Screen.new ( 20 , 4 )
screen : attach ( )
feed ( ' : ' )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' normal! \023 \022 \006 \027 ' , true , - 1 )
2022-03-14 15:04:50 -07:00
screen : expect ( [ [
|
2024-03-22 03:02:52 -07:00
{ 1 : ~ } |* 2
: normal ! { 18 : ^ W ^ V ^ F ^ [ } ^ |
2022-03-14 15:04:50 -07:00
] ] )
end )
2019-08-29 15:16:19 -07:00
it ( ' crlf=false does not break lines at CR, CRLF ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_paste ( ' line 1 \r \n \r \r line 2 \n line 3 \r line 4 \r ' , false , - 1 )
2024-09-21 15:02:48 -07:00
local expected = ' line 1 \r \n \r \r line 2 \n line 3 \r line 4 \r '
expect ( expected )
2024-01-12 10:59:57 -07:00
eq ( { 0 , 3 , 14 , 0 } , fn.getpos ( ' . ' ) )
2024-09-21 15:02:48 -07:00
feed ( ' u ' ) -- Undo.
expect ( ' ' )
feed ( ' . ' ) -- Dot-repeat.
expect ( expected )
end )
describe ( ' repeating a paste via redo/recording ' , function ( )
-- Test with indent and control chars and multibyte chars containing 0x80 bytes
local text = dedent ( ( [ [
foo
bar
baz
! ! ! % s ! ! ! % s ! ! ! % s ! ! !
最 … 倒 … 倀 …
] ] ) : format ( ' \0 ' , ' \2 \3 \6 \21 \22 \23 \24 \27 ' , ' \127 ' ) )
before_each ( function ( )
api.nvim_set_option_value ( ' autoindent ' , true , { } )
end )
local function test_paste_repeat_normal_insert ( is_insert )
feed ( ' qr ' .. ( is_insert and ' i ' or ' ' ) )
eq ( ' r ' , fn.reg_recording ( ) )
api.nvim_paste ( text , true , - 1 )
feed ( is_insert and ' <Esc> ' or ' ' )
expect ( text )
feed ( ' . ' )
expect ( text : rep ( 2 ) )
feed ( ' q ' )
eq ( ' ' , fn.reg_recording ( ) )
feed ( ' 3. ' )
expect ( text : rep ( 5 ) )
feed ( ' 2@r ' )
expect ( text : rep ( 9 ) )
end
it ( ' works in Normal mode ' , function ( )
test_paste_repeat_normal_insert ( false )
end )
it ( ' works in Insert mode ' , function ( )
test_paste_repeat_normal_insert ( true )
end )
local function test_paste_repeat_visual_select ( is_select )
insert ( ( ' xxx \n ' ) : rep ( 5 ) )
feed ( ' ggqr ' .. ( is_select and ' gH ' or ' V ' ) )
api.nvim_paste ( text , true , - 1 )
feed ( ' q ' )
expect ( text .. ( ' xxx \n ' ) : rep ( 4 ) )
feed ( ' 2@r ' )
expect ( text : rep ( 3 ) .. ( ' xxx \n ' ) : rep ( 2 ) )
end
it ( ' works in Visual mode (recording only) ' , function ( )
test_paste_repeat_visual_select ( false )
end )
it ( ' works in Select mode (recording only) ' , function ( )
test_paste_repeat_visual_select ( true )
end )
2019-08-29 15:16:19 -07:00
end )
feat(paste): unify cancel and error behavior (#30476)
Before this PR, the behavior of nvim_paste is:
- When vim.paste() returns false, return false to the client, but treat
following chunks normally (i.e. rely on the client cancelling the
paste as expected).
- When vim.paste() throws an error, still return true to the client, but
drain the following chunks in the stream without calling vim.paste().
There are two problems with such behavior:
- When vim.paste() errors, the client is still supposed to send the
remaining chunks of the stream, even though they do nothing.
- Having different code paths for two uncommon but similar situations
complicates maintenance.
This PR makes both the cancel case and the error case return false to
the client and drain the remaining chunks of the stream, which, apart
from sharing the same code path, is beneficial whether the client checks
the return value of nvim_paste or not:
- If the client checks the return value, it can avoid sending the
following chunks needlessly after an error.
- If the client doesn't check the return value, chunks following a
cancelled chunk won't be pasted on the server regardless, which leads
to less confusing behavior.
2024-09-23 16:14:14 -07:00
local function test_paste_cancel_error ( is_error )
before_each ( function ( )
exec_lua ( ( [ [
vim.paste = ( function ( overridden )
return function ( lines , phase )
for i , line in ipairs ( lines ) do
if line == ' CANCEL ' then
% s
end
end
return overridden ( lines , phase )
end
end ) ( vim.paste )
] ] ) : format ( is_error and ' error("fake fail") ' or ' return false ' ) )
end )
local function check_paste_cancel_error ( data , crlf , phase )
if is_error then
eq ( ' fake fail ' , pcall_err ( api.nvim_paste , data , crlf , phase ) )
else
eq ( false , api.nvim_paste ( data , crlf , phase ) )
end
end
it ( ' in phase -1 ' , function ( )
feed ( ' A ' )
check_paste_cancel_error ( ' CANCEL ' , true , - 1 )
feed ( ' <Esc> ' )
expect ( ' ' )
feed ( ' . ' )
expect ( ' ' )
end )
it ( ' in phase 1 ' , function ( )
feed ( ' A ' )
check_paste_cancel_error ( ' CANCEL ' , true , 1 )
feed ( ' <Esc> ' )
expect ( ' ' )
feed ( ' . ' )
expect ( ' ' )
end )
it ( ' in phase 2 ' , function ( )
feed ( ' A ' )
eq ( true , api.nvim_paste ( ' aaa ' , true , 1 ) )
expect ( ' aaa ' )
check_paste_cancel_error ( ' CANCEL ' , true , 2 )
feed ( ' <Esc> ' )
expect ( ' aaa ' )
feed ( ' . ' )
expect ( ' aaaaaa ' )
end )
it ( ' in phase 3 ' , function ( )
feed ( ' A ' )
eq ( true , api.nvim_paste ( ' aaa ' , true , 1 ) )
expect ( ' aaa ' )
eq ( true , api.nvim_paste ( ' bbb ' , true , 2 ) )
expect ( ' aaabbb ' )
check_paste_cancel_error ( ' CANCEL ' , true , 3 )
feed ( ' <Esc> ' )
expect ( ' aaabbb ' )
feed ( ' . ' )
expect ( ' aaabbbaaabbb ' )
end )
end
describe ( ' vim.paste() cancel ' , function ( )
test_paste_cancel_error ( false )
end )
describe ( ' vim.paste() error ' , function ( )
test_paste_cancel_error ( true )
2019-08-26 11:57:57 -07:00
end )
2019-08-24 04:54:27 -07:00
end )
2019-08-19 14:43:19 -07:00
describe ( ' nvim_put ' , function ( )
2023-02-14 12:19:28 -07:00
it ( ' validation ' , function ( )
2023-12-07 04:19:35 -07:00
eq (
" Invalid 'line': expected String, got Integer " ,
pcall_err ( request , ' nvim_put ' , { 42 } , ' l ' , false , false )
)
eq ( " Invalid 'type': 'x' " , pcall_err ( request , ' nvim_put ' , { ' foo ' } , ' x ' , false , false ) )
2019-08-24 04:54:27 -07:00
end )
2019-08-26 20:19:32 -07:00
it ( " fails if 'nomodifiable' " , function ( )
command ( ' set nomodifiable ' )
2023-12-07 04:19:35 -07:00
eq (
[[Vim:E21: Cannot make changes, 'modifiable' is off]] ,
pcall_err ( request , ' nvim_put ' , { ' a ' , ' b ' } , ' l ' , true , true )
)
2019-08-26 20:19:32 -07:00
end )
2019-08-19 14:43:19 -07:00
it ( ' inserts text ' , function ( )
-- linewise
2024-01-12 10:59:57 -07:00
api.nvim_put ( { ' line 1 ' , ' line 2 ' , ' line 3 ' } , ' l ' , true , true )
2019-08-19 14:43:19 -07:00
expect ( [ [
line 1
line 2
line 3 ] ] )
2024-01-12 10:59:57 -07:00
eq ( { 0 , 4 , 1 , 0 } , fn.getpos ( ' . ' ) )
2019-08-19 14:43:19 -07:00
command ( ' %delete _ ' )
-- charwise
2024-01-12 10:59:57 -07:00
api.nvim_put ( { ' line 1 ' , ' line 2 ' , ' line 3 ' } , ' c ' , true , false )
2019-08-19 14:43:19 -07:00
expect ( [ [
line 1
line 2
line 3 ] ] )
2024-01-12 10:59:57 -07:00
eq ( { 0 , 1 , 1 , 0 } , fn.getpos ( ' . ' ) ) -- follow=false
2019-08-19 14:43:19 -07:00
-- blockwise
2024-01-12 10:59:57 -07:00
api.nvim_put ( { ' AA ' , ' BB ' } , ' b ' , true , true )
2019-08-19 14:43:19 -07:00
expect ( [ [
lAAine 1
lBBine 2
line 3 ] ] )
2024-01-12 10:59:57 -07:00
eq ( { 0 , 2 , 4 , 0 } , fn.getpos ( ' . ' ) )
2019-08-19 14:43:19 -07:00
command ( ' %delete _ ' )
-- Empty lines list.
2024-01-12 10:59:57 -07:00
api.nvim_put ( { } , ' c ' , true , true )
eq ( { 0 , 1 , 1 , 0 } , fn.getpos ( ' . ' ) )
2019-08-19 14:43:19 -07:00
expect ( [[]] )
-- Single empty line.
2024-01-12 10:59:57 -07:00
api.nvim_put ( { ' ' } , ' c ' , true , true )
eq ( { 0 , 1 , 1 , 0 } , fn.getpos ( ' . ' ) )
2019-08-19 14:43:19 -07:00
expect ( [ [
] ] )
2024-01-12 10:59:57 -07:00
api.nvim_put ( { ' AB ' } , ' c ' , true , true )
2019-08-20 14:53:13 -07:00
-- after=false, follow=true
2024-01-12 10:59:57 -07:00
api.nvim_put ( { ' line 1 ' , ' line 2 ' } , ' c ' , false , true )
2019-08-20 14:53:13 -07:00
expect ( [ [
Aline 1
line 2 B ] ] )
2024-01-12 10:59:57 -07:00
eq ( { 0 , 2 , 7 , 0 } , fn.getpos ( ' . ' ) )
2019-08-20 14:53:13 -07:00
command ( ' %delete _ ' )
2024-01-12 10:59:57 -07:00
api.nvim_put ( { ' AB ' } , ' c ' , true , true )
2019-08-20 14:53:13 -07:00
-- after=false, follow=false
2024-01-12 10:59:57 -07:00
api.nvim_put ( { ' line 1 ' , ' line 2 ' } , ' c ' , false , false )
2019-08-20 14:53:13 -07:00
expect ( [ [
Aline 1
line 2 B ] ] )
2024-01-12 10:59:57 -07:00
eq ( { 0 , 1 , 2 , 0 } , fn.getpos ( ' . ' ) )
eq ( ' ' , api.nvim_eval ( ' v:errmsg ' ) )
2019-08-19 14:43:19 -07:00
end )
2019-08-26 11:57:57 -07:00
it ( ' detects charwise/linewise text (empty {type}) ' , function ( )
-- linewise (final item is empty string)
2024-01-12 10:59:57 -07:00
api.nvim_put ( { ' line 1 ' , ' line 2 ' , ' line 3 ' , ' ' } , ' ' , true , true )
2019-08-26 11:57:57 -07:00
expect ( [ [
line 1
line 2
line 3 ] ] )
2024-01-12 10:59:57 -07:00
eq ( { 0 , 4 , 1 , 0 } , fn.getpos ( ' . ' ) )
2019-08-26 11:57:57 -07:00
command ( ' %delete _ ' )
-- charwise (final item is non-empty)
2024-01-12 10:59:57 -07:00
api.nvim_put ( { ' line 1 ' , ' line 2 ' , ' line 3 ' } , ' ' , true , true )
2019-08-26 11:57:57 -07:00
expect ( [ [
line 1
line 2
line 3 ] ] )
2024-01-12 10:59:57 -07:00
eq ( { 0 , 3 , 6 , 0 } , fn.getpos ( ' . ' ) )
2019-08-26 11:57:57 -07:00
end )
2019-08-30 11:19:56 -07:00
it ( ' allows block width ' , function ( )
-- behave consistently with setreg(); support "\022{NUM}" return by getregtype()
2024-01-12 10:59:57 -07:00
api.nvim_put ( { ' line 1 ' , ' line 2 ' , ' line 3 ' } , ' l ' , false , false )
2019-08-30 11:19:56 -07:00
expect ( [ [
line 1
line 2
line 3
] ] )
-- larger width create spaces
2024-01-12 10:59:57 -07:00
api.nvim_put ( { ' a ' , ' bc ' } , ' b3 ' , false , false )
2019-08-30 11:19:56 -07:00
expect ( [ [
a line 1
bc line 2
line 3
] ] )
-- smaller width is ignored
2024-01-12 10:59:57 -07:00
api.nvim_put ( { ' xxx ' , ' yyy ' } , ' \022 1 ' , false , true )
2019-08-30 11:19:56 -07:00
expect ( [ [
xxxa line 1
yyybc line 2
line 3
] ] )
2024-01-12 10:59:57 -07:00
eq ( " Invalid 'type': 'bx' " , pcall_err ( api.nvim_put , { ' xxx ' , ' yyy ' } , ' bx ' , false , true ) )
eq ( " Invalid 'type': 'b3x' " , pcall_err ( api.nvim_put , { ' xxx ' , ' yyy ' } , ' b3x ' , false , true ) )
2019-08-30 11:19:56 -07:00
end )
2019-08-19 14:43:19 -07:00
end )
2016-10-22 15:02:22 -07:00
describe ( ' nvim_strwidth ' , function ( )
2014-10-08 09:56:01 -07:00
it ( ' works ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( 3 , api.nvim_strwidth ( ' abc ' ) )
2014-10-08 09:56:01 -07:00
-- 6 + (neovim)
-- 19 * 2 (each japanese character occupies two cells)
2024-01-12 10:59:57 -07:00
eq ( 44 , api.nvim_strwidth ( ' neovimのデザインかなりまともなのになってる。 ' ) )
2014-10-08 09:56:01 -07:00
end )
2014-10-24 13:36:30 -07:00
it ( ' cannot handle NULs ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( 0 , api.nvim_strwidth ( ' \0 abc ' ) )
2014-10-24 13:36:30 -07:00
end )
2024-08-08 01:42:08 -07:00
it ( ' can handle emoji with variant selectors and ZWJ ' , function ( )
local selector = ' ❤️ '
eq ( 2 , fn.strchars ( selector ) )
eq ( 1 , fn.strcharlen ( selector ) )
eq ( 2 , api.nvim_strwidth ( selector ) )
local no_selector = ' ❤ '
eq ( 1 , fn.strchars ( no_selector ) )
eq ( 1 , fn.strcharlen ( no_selector ) )
eq ( 1 , api.nvim_strwidth ( no_selector ) )
local selector_zwj_selector = ' 🏳️⚧️ '
eq ( 5 , fn.strchars ( selector_zwj_selector ) )
eq ( 1 , fn.strcharlen ( selector_zwj_selector ) )
eq ( 2 , api.nvim_strwidth ( selector_zwj_selector ) )
local emoji_zwj_emoji = ' 🧑🌾 '
eq ( 3 , fn.strchars ( emoji_zwj_emoji ) )
eq ( 1 , fn.strcharlen ( emoji_zwj_emoji ) )
eq ( 2 , api.nvim_strwidth ( emoji_zwj_emoji ) )
end )
2014-10-08 09:56:01 -07:00
end )
2016-10-22 15:02:22 -07:00
describe ( ' nvim_get_current_line, nvim_set_current_line ' , function ( )
2014-10-08 09:56:01 -07:00
it ( ' works ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( ' ' , api.nvim_get_current_line ( ) )
api.nvim_set_current_line ( ' abc ' )
eq ( ' abc ' , api.nvim_get_current_line ( ) )
2014-10-08 09:56:01 -07:00
end )
end )
2019-01-13 16:40:38 -07:00
describe ( ' set/get/del variables ' , function ( )
2023-02-14 12:19:28 -07:00
it ( ' validation ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( ' Key not found: bogus ' , pcall_err ( api.nvim_get_var , ' bogus ' ) )
eq ( ' Key not found: bogus ' , pcall_err ( api.nvim_del_var , ' bogus ' ) )
2023-02-14 12:19:28 -07:00
end )
2019-01-13 16:40:38 -07:00
it ( ' nvim_get_var, nvim_set_var, nvim_del_var ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_set_var ( ' lua ' , { 1 , 2 , { [ ' 3 ' ] = 1 } } )
eq ( { 1 , 2 , { [ ' 3 ' ] = 1 } } , api.nvim_get_var ( ' lua ' ) )
eq ( { 1 , 2 , { [ ' 3 ' ] = 1 } } , api.nvim_eval ( ' g:lua ' ) )
eq ( 1 , fn.exists ( ' g:lua ' ) )
api.nvim_del_var ( ' lua ' )
eq ( 0 , fn.exists ( ' g:lua ' ) )
eq ( ' Key not found: lua ' , pcall_err ( api.nvim_del_var , ' lua ' ) )
api.nvim_set_var ( ' lua ' , 1 )
2019-01-13 16:40:38 -07:00
2023-12-06 09:02:13 -07:00
-- Empty keys are allowed in Vim dicts (and msgpack).
2024-01-12 10:59:57 -07:00
api.nvim_set_var ( ' dict_empty_key ' , { [ ' ' ] = ' empty key ' } )
eq ( { [ ' ' ] = ' empty key ' } , api.nvim_get_var ( ' dict_empty_key ' ) )
2023-12-06 09:02:13 -07:00
2019-01-13 16:40:38 -07:00
-- Set locked g: var.
2017-02-22 15:34:25 -07:00
command ( ' lockvar lua ' )
2024-01-12 10:59:57 -07:00
eq ( ' Key is locked: lua ' , pcall_err ( api.nvim_del_var , ' lua ' ) )
eq ( ' Key is locked: lua ' , pcall_err ( api.nvim_set_var , ' lua ' , 1 ) )
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 ' )
] ] )
2024-01-12 10:59:57 -07:00
eq ( NIL , api.nvim_get_var ( ' Unknown_func ' ) )
eq ( NIL , api.nvim_get_var ( ' Unknown_script_func ' ) )
2022-03-19 17:08:50 -07:00
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 '
2023-12-07 04:19:35 -07:00
local autoload_folder = table.concat ( { xconfig , ' nvim ' , ' autoload ' } , pathsep )
local autoload_file = table.concat ( { autoload_folder , ' testload.vim ' } , pathsep )
2022-02-11 21:54:25 -07:00
mkdir_p ( autoload_folder )
2023-12-07 04:19:35 -07:00
write_file ( autoload_file , [[let testload#value = 2]] )
2022-02-11 21:54:25 -07:00
2023-12-07 04:19:35 -07:00
clear { args_rm = { ' -u ' } , env = { XDG_CONFIG_HOME = xconfig , XDG_DATA_HOME = xdata } }
2024-01-12 10:59:57 -07:00
eq ( 2 , api.nvim_get_var ( ' testload#value ' ) )
2022-02-11 21:54:25 -07:00
rmdir ( ' Xhome ' )
2014-10-08 09:56:01 -07:00
end )
2014-10-24 13:36:30 -07:00
2019-01-13 16:40:38 -07:00
it ( ' nvim_get_vvar, nvim_set_vvar ' , function ( )
2023-09-23 19:57:09 -07:00
eq ( ' Key is read-only: count ' , pcall_err ( request , ' nvim_set_vvar ' , ' 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 ( request , ' nvim_set_vvar ' , ' nosuchvar ' , 42 ) )
2024-01-12 10:59:57 -07:00
api.nvim_set_vvar ( ' errmsg ' , ' set by API ' )
eq ( ' set by API ' , api.nvim_get_vvar ( ' errmsg ' ) )
2024-07-11 03:26:52 -07:00
api.nvim_set_vvar ( ' completed_item ' , { word = ' a ' , user_data = vim.empty_dict ( ) } )
eq ( { } , api.nvim_get_vvar ( ' completed_item ' ) [ ' user_data ' ] )
2024-01-12 10:59:57 -07:00
api.nvim_set_vvar ( ' errmsg ' , 42 )
2023-09-23 19:57:09 -07:00
eq ( ' 42 ' , eval ( ' v:errmsg ' ) )
2024-01-12 10:59:57 -07:00
api.nvim_set_vvar ( ' oldfiles ' , { ' one ' , ' two ' } )
2023-09-23 19:57:09 -07:00
eq ( { ' one ' , ' two ' } , eval ( ' v:oldfiles ' ) )
2024-01-12 10:59:57 -07:00
api.nvim_set_vvar ( ' oldfiles ' , { } )
2023-09-23 19:57:09 -07:00
eq ( { } , eval ( ' v:oldfiles ' ) )
2024-01-12 05:44:54 -07:00
eq (
' Setting v:oldfiles to value with wrong type ' ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_set_vvar , ' oldfiles ' , ' a ' )
2024-01-12 05:44:54 -07:00
)
2023-09-23 19:57:09 -07:00
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 ) )
api.nvim_set_vvar ( ' searchforward ' , 0 )
2023-09-23 19:57:09 -07:00
eq ( 0 , eval ( ' v:searchforward ' ) )
feed ( ' n ' )
2024-01-12 10:59:57 -07:00
eq ( { 1 , 1 } , api.nvim_win_get_cursor ( 0 ) )
api.nvim_set_vvar ( ' searchforward ' , 1 )
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
local screen = Screen.new ( 60 , 3 )
screen : attach ( )
eq ( 1 , eval ( ' v:hlsearch ' ) )
2023-12-07 04:19:35 -07:00
screen : expect {
grid = [ [
2024-05-25 10:18:57 -07:00
{ 10 : foo } { 10 : ^ foo } { 10 : foo } |
{ 1 : ~ } |
2023-09-23 19:57:09 -07:00
|
2023-12-07 04:19:35 -07:00
] ] ,
}
2024-01-12 10:59:57 -07:00
api.nvim_set_vvar ( ' hlsearch ' , 0 )
2023-09-23 19:57:09 -07:00
eq ( 0 , eval ( ' v:hlsearch ' ) )
2023-12-07 04:19:35 -07:00
screen : expect {
grid = [ [
2023-09-23 19:57:09 -07:00
foo ^ foo foo |
2024-05-25 10:18:57 -07:00
{ 1 : ~ } |
2023-09-23 19:57:09 -07:00
|
2023-12-07 04:19:35 -07:00
] ] ,
}
2024-01-12 10:59:57 -07:00
api.nvim_set_vvar ( ' hlsearch ' , 1 )
2023-09-23 19:57:09 -07:00
eq ( 1 , eval ( ' v:hlsearch ' ) )
2023-12-07 04:19:35 -07:00
screen : expect {
grid = [ [
2024-05-25 10:18:57 -07:00
{ 10 : foo } { 10 : ^ foo } { 10 : foo } |
{ 1 : ~ } |
2023-09-23 19:57:09 -07:00
|
2023-12-07 04:19:35 -07:00
] ] ,
}
2019-01-13 16:40:38 -07:00
end )
2016-09-14 02:17:07 -07:00
it ( ' vim_set_var returns the old value ' , function ( )
2023-12-07 04:19:35 -07:00
local val1 = { 1 , 2 , { [ ' 3 ' ] = 1 } }
local val2 = { 4 , 7 }
2016-09-14 02:17:07 -07:00
eq ( NIL , request ( ' vim_set_var ' , ' lua ' , val1 ) )
eq ( val1 , request ( ' vim_set_var ' , ' lua ' , val2 ) )
2015-06-24 21:13:33 -07:00
end )
2016-09-14 02:17:07 -07:00
it ( ' vim_del_var returns the old value ' , function ( )
2023-12-07 04:19:35 -07:00
local val1 = { 1 , 2 , { [ ' 3 ' ] = 1 } }
local val2 = { 4 , 7 }
eq ( NIL , request ( ' vim_set_var ' , ' lua ' , val1 ) )
2016-09-14 02:17:07 -07:00
eq ( val1 , request ( ' vim_set_var ' , ' lua ' , val2 ) )
eq ( val2 , request ( ' vim_del_var ' , ' lua ' ) )
2016-02-10 16:01:17 -07:00
end )
2024-06-25 06:33:47 -07:00
it ( ' preserves values with NULs in them ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_set_var ( ' xxx ' , ' ab \0 cd ' )
2024-06-25 06:33:47 -07:00
eq ( ' ab \000 cd ' , api.nvim_get_var ( ' xxx ' ) )
2014-10-24 13:36:30 -07:00
end )
2014-10-08 09:56:01 -07:00
end )
2022-12-19 09:37:45 -07:00
describe ( ' nvim_get_option_value, nvim_set_option_value ' , function ( )
2014-10-08 09:56:01 -07:00
it ( ' works ' , function ( )
2024-01-12 10:59:57 -07:00
ok ( api.nvim_get_option_value ( ' equalalways ' , { } ) )
api.nvim_set_option_value ( ' equalalways ' , false , { } )
ok ( not api.nvim_get_option_value ( ' equalalways ' , { } ) )
2014-10-08 09:56:01 -07:00
end )
2017-03-30 13:03:52 -07:00
it ( ' works to get global value of local options ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( false , api.nvim_get_option_value ( ' lisp ' , { } ) )
eq ( 8 , api.nvim_get_option_value ( ' shiftwidth ' , { } ) )
2017-03-30 13:03:52 -07:00
end )
it ( ' works to set global value of local options ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' lisp ' , true , { scope = ' global ' } )
eq ( true , api.nvim_get_option_value ( ' lisp ' , { scope = ' global ' } ) )
eq ( false , api.nvim_get_option_value ( ' lisp ' , { } ) )
2024-01-12 06:11:28 -07:00
eq ( nil , command_output ( ' setglobal lisp? ' ) : match ( ' nolisp ' ) )
eq ( ' nolisp ' , command_output ( ' setlocal lisp? ' ) : match ( ' nolisp ' ) )
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' shiftwidth ' , 20 , { scope = ' global ' } )
2024-01-12 06:11:28 -07:00
eq ( ' 20 ' , command_output ( ' setglobal shiftwidth? ' ) : match ( ' %d+ ' ) )
eq ( ' 8 ' , command_output ( ' setlocal shiftwidth? ' ) : match ( ' %d+ ' ) )
2017-03-30 13:03:52 -07:00
end )
2018-04-29 19:02:17 -07:00
it ( ' updates where the option was last set from ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' equalalways ' , false , { } )
2024-01-12 06:11:28 -07:00
local status , rv = pcall ( command_output , ' verbose set equalalways? ' )
2018-04-29 19:02:17 -07:00
eq ( true , status )
2024-03-29 18:29:21 -07:00
matches ( ' noequalalways \n ' .. ' \t Last set from API client %(channel id %d+%) ' , rv )
2018-04-29 19:02:17 -07:00
2024-01-12 10:59:57 -07:00
api.nvim_exec_lua ( ' vim.api.nvim_set_option_value("equalalways", true, {}) ' , { } )
2024-01-12 06:11:28 -07:00
status , rv = pcall ( command_output , ' verbose set equalalways? ' )
2018-04-29 19:02:17 -07:00
eq ( true , status )
2024-03-29 16:57:22 -07:00
eq ( ' equalalways \n \t Last set from Lua (run Nvim with -V1 for more details) ' , rv )
2018-04-29 19:02:17 -07:00
end )
2023-09-05 05:03:25 -07:00
it ( ' updates whether the option has ever been set #25025 ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( false , api.nvim_get_option_info2 ( ' autochdir ' , { } ) . was_set )
api.nvim_set_option_value ( ' autochdir ' , true , { } )
eq ( true , api.nvim_get_option_info2 ( ' autochdir ' , { } ) . was_set )
2023-09-05 05:03:25 -07:00
2024-01-12 10:59:57 -07:00
eq ( false , api.nvim_get_option_info2 ( ' cmdwinheight ' , { } ) . was_set )
api.nvim_set_option_value ( ' cmdwinheight ' , 10 , { } )
eq ( true , api.nvim_get_option_info2 ( ' cmdwinheight ' , { } ) . was_set )
2023-09-05 05:03:25 -07:00
2024-01-12 10:59:57 -07:00
eq ( false , api.nvim_get_option_info2 ( ' debug ' , { } ) . was_set )
api.nvim_set_option_value ( ' debug ' , ' beep ' , { } )
eq ( true , api.nvim_get_option_info2 ( ' debug ' , { } ) . was_set )
2023-09-05 05:03:25 -07:00
end )
2021-10-11 21:09:08 -07:00
2023-02-14 03:19:04 -07:00
it ( ' validation ' , function ( )
2023-12-07 04:19:35 -07:00
eq (
" Invalid 'scope': expected 'local' or 'global' " ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_get_option_value , ' scrolloff ' , { scope = ' bogus ' } )
2023-12-07 04:19:35 -07:00
)
eq (
" Invalid 'scope': expected 'local' or 'global' " ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_set_option_value , ' scrolloff ' , 1 , { scope = ' bogus ' } )
2023-12-07 04:19:35 -07:00
)
eq (
" Invalid 'scope': expected String, got Integer " ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_get_option_value , ' scrolloff ' , { scope = 42 } )
2023-12-07 04:19:35 -07:00
)
eq (
" Invalid 'value': expected valid option type, got Array " ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_set_option_value , ' scrolloff ' , { } , { } )
2023-12-07 04:19:35 -07:00
)
eq (
" Invalid value for option 'scrolloff': expected number, got boolean true " ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_set_option_value , ' scrolloff ' , true , { } )
2023-12-07 04:19:35 -07:00
)
eq (
' Invalid value for option \' scrolloff \' : expected number, got string "wrong" ' ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_set_option_value , ' scrolloff ' , ' wrong ' , { } )
2023-12-07 04:19:35 -07:00
)
2023-02-14 03:19:04 -07:00
end )
2021-10-11 21:09:08 -07:00
it ( ' can get local values when global value is set ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( 0 , api.nvim_get_option_value ( ' scrolloff ' , { } ) )
eq ( - 1 , api.nvim_get_option_value ( ' scrolloff ' , { scope = ' local ' } ) )
2021-10-11 21:09:08 -07:00
end )
it ( ' can set global and local values ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' makeprg ' , ' hello ' , { } )
eq ( ' hello ' , api.nvim_get_option_value ( ' makeprg ' , { } ) )
eq ( ' ' , api.nvim_get_option_value ( ' makeprg ' , { scope = ' local ' } ) )
api.nvim_set_option_value ( ' makeprg ' , ' world ' , { scope = ' local ' } )
eq ( ' world ' , api.nvim_get_option_value ( ' makeprg ' , { scope = ' local ' } ) )
api.nvim_set_option_value ( ' makeprg ' , ' goodbye ' , { scope = ' global ' } )
eq ( ' goodbye ' , api.nvim_get_option_value ( ' makeprg ' , { scope = ' global ' } ) )
api.nvim_set_option_value ( ' makeprg ' , ' hello ' , { } )
eq ( ' hello ' , api.nvim_get_option_value ( ' makeprg ' , { scope = ' global ' } ) )
eq ( ' hello ' , api.nvim_get_option_value ( ' makeprg ' , { } ) )
eq ( ' ' , api.nvim_get_option_value ( ' makeprg ' , { scope = ' local ' } ) )
2021-10-11 21:09:08 -07:00
end )
2021-12-21 14:20:34 -07:00
it ( ' clears the local value of an option with nil ' , function ( )
-- Set global value
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' shiftwidth ' , 42 , { } )
eq ( 42 , api.nvim_get_option_value ( ' shiftwidth ' , { } ) )
2021-12-21 14:20:34 -07:00
-- Set local value
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' shiftwidth ' , 8 , { scope = ' local ' } )
eq ( 8 , api.nvim_get_option_value ( ' shiftwidth ' , { } ) )
eq ( 8 , api.nvim_get_option_value ( ' shiftwidth ' , { scope = ' local ' } ) )
eq ( 42 , api.nvim_get_option_value ( ' shiftwidth ' , { scope = ' global ' } ) )
2021-12-21 14:20:34 -07:00
-- Clear value without scope
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' shiftwidth ' , NIL , { } )
eq ( 42 , api.nvim_get_option_value ( ' shiftwidth ' , { } ) )
eq ( 42 , api.nvim_get_option_value ( ' shiftwidth ' , { scope = ' local ' } ) )
2021-12-21 14:20:34 -07:00
-- Clear value with explicit scope
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' shiftwidth ' , 8 , { scope = ' local ' } )
api.nvim_set_option_value ( ' shiftwidth ' , NIL , { scope = ' local ' } )
eq ( 42 , api.nvim_get_option_value ( ' shiftwidth ' , { } ) )
eq ( 42 , api.nvim_get_option_value ( ' shiftwidth ' , { scope = ' local ' } ) )
2021-12-21 14:20:34 -07:00
-- Now try with options with a special "local is unset" value (e.g. 'undolevels')
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' undolevels ' , 1000 , { } )
api.nvim_set_option_value ( ' undolevels ' , 1200 , { scope = ' local ' } )
eq ( 1200 , api.nvim_get_option_value ( ' undolevels ' , { scope = ' local ' } ) )
api.nvim_set_option_value ( ' undolevels ' , NIL , { scope = ' local ' } )
eq ( - 123456 , api.nvim_get_option_value ( ' undolevels ' , { scope = ' local ' } ) )
eq ( 1000 , api.nvim_get_option_value ( ' undolevels ' , { } ) )
2021-12-21 14:20:34 -07:00
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' autoread ' , true , { } )
api.nvim_set_option_value ( ' autoread ' , false , { scope = ' local ' } )
eq ( false , api.nvim_get_option_value ( ' autoread ' , { scope = ' local ' } ) )
api.nvim_set_option_value ( ' autoread ' , NIL , { scope = ' local ' } )
eq ( NIL , api.nvim_get_option_value ( ' autoread ' , { scope = ' local ' } ) )
eq ( true , api.nvim_get_option_value ( ' autoread ' , { } ) )
2021-12-21 14:20:34 -07:00
end )
2022-05-11 05:49:43 -07:00
it ( ' set window options ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' colorcolumn ' , ' 4,3 ' , { } )
eq ( ' 4,3 ' , api.nvim_get_option_value ( ' colorcolumn ' , { scope = ' local ' } ) )
2023-12-07 04:19:35 -07:00
command ( ' set modified hidden ' )
command ( ' enew ' ) -- edit new buffer, window option is preserved
2024-01-12 10:59:57 -07:00
eq ( ' 4,3 ' , api.nvim_get_option_value ( ' colorcolumn ' , { scope = ' local ' } ) )
2022-05-11 05:49:43 -07:00
end )
it ( ' set local window options ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' colorcolumn ' , ' 4,3 ' , { win = 0 , scope = ' local ' } )
eq ( ' 4,3 ' , api.nvim_get_option_value ( ' colorcolumn ' , { win = 0 , scope = ' local ' } ) )
2023-12-07 04:19:35 -07:00
command ( ' set modified hidden ' )
command ( ' enew ' ) -- edit new buffer, window option is reset
2024-01-12 10:59:57 -07:00
eq ( ' ' , api.nvim_get_option_value ( ' colorcolumn ' , { win = 0 , scope = ' local ' } ) )
2022-06-20 07:20:06 -07:00
end )
it ( ' get buffer or window-local options ' , function ( )
2024-01-12 06:11:28 -07:00
command ( ' new ' )
2024-01-16 06:26:21 -07:00
local buf = api.nvim_get_current_buf ( )
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' tagfunc ' , ' foobar ' , { buf = buf } )
eq ( ' foobar ' , api.nvim_get_option_value ( ' tagfunc ' , { buf = buf } ) )
2022-06-20 07:20:06 -07:00
2024-01-16 06:26:21 -07:00
local win = api.nvim_get_current_win ( )
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' number ' , true , { win = win } )
eq ( true , api.nvim_get_option_value ( ' number ' , { win = win } ) )
2022-05-11 05:49:43 -07:00
end )
2022-07-15 18:31:05 -07:00
it ( ' getting current buffer option does not adjust cursor #19381 ' , function ( )
2024-01-12 06:11:28 -07:00
command ( ' new ' )
2024-01-16 06:26:21 -07:00
local buf = api.nvim_get_current_buf ( )
print ( vim.inspect ( api.nvim_get_current_buf ( ) ) )
local win = api.nvim_get_current_win ( )
2022-07-15 18:31:05 -07:00
insert ( ' some text ' )
feed ( ' 0v$ ' )
2024-01-12 10:59:57 -07:00
eq ( { 1 , 9 } , api.nvim_win_get_cursor ( win ) )
api.nvim_get_option_value ( ' filetype ' , { buf = buf } )
eq ( { 1 , 9 } , api.nvim_win_get_cursor ( win ) )
2022-07-15 18:31:05 -07:00
end )
2023-03-11 10:11:02 -07:00
it ( ' can get default option values for filetypes ' , function ( )
command ( ' filetype plugin on ' )
for ft , opts in pairs {
lua = { commentstring = ' -- %s ' } ,
vim = { commentstring = ' "%s ' } ,
2023-12-07 04:19:35 -07:00
man = { tagfunc = " v:lua.require'man'.goto_tag " } ,
xml = { formatexpr = ' xmlformat#Format() ' } ,
2023-03-11 10:11:02 -07:00
} do
for option , value in pairs ( opts ) do
2024-01-12 10:59:57 -07:00
eq ( value , api.nvim_get_option_value ( option , { filetype = ft } ) )
2023-03-11 10:11:02 -07:00
end
end
2023-12-07 04:19:35 -07:00
command ' au FileType lua setlocal commentstring=NEW \\ %s '
2023-03-11 10:11:02 -07:00
2024-01-12 10:59:57 -07:00
eq ( ' NEW %s ' , api.nvim_get_option_value ( ' commentstring ' , { filetype = ' lua ' } ) )
2023-03-11 10:11:02 -07:00
end )
it ( ' errors for bad FileType autocmds ' , function ( )
2023-12-07 04:19:35 -07:00
command ' au FileType lua setlocal commentstring=BAD '
eq (
[[FileType Autocommands for "lua": Vim(setlocal):E537: 'commentstring' must be empty or contain %s: commentstring=BAD]] ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_get_option_value , ' commentstring ' , { filetype = ' lua ' } )
2023-12-07 04:19:35 -07:00
)
2023-03-11 10:11:02 -07:00
end )
2023-10-28 09:51:07 -07:00
it ( " value of 'modified' is always false for scratch buffers " , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_set_current_buf ( api.nvim_create_buf ( true , true ) )
2023-10-28 09:51:07 -07:00
insert ( [ [
foo
bar
baz
] ] )
2024-01-12 10:59:57 -07:00
eq ( false , api.nvim_get_option_value ( ' modified ' , { } ) )
2023-10-28 09:51:07 -07:00
end )
2021-10-11 21:09:08 -07:00
end )
2016-10-22 15:02:22 -07:00
describe ( ' nvim_{get,set}_current_buf, nvim_list_bufs ' , function ( )
2014-10-08 09:56:01 -07:00
it ( ' works ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( 1 , # api.nvim_list_bufs ( ) )
eq ( api.nvim_list_bufs ( ) [ 1 ] , api.nvim_get_current_buf ( ) )
2024-01-12 06:11:28 -07:00
command ( ' new ' )
2024-01-12 10:59:57 -07:00
eq ( 2 , # api.nvim_list_bufs ( ) )
eq ( api.nvim_list_bufs ( ) [ 2 ] , api.nvim_get_current_buf ( ) )
api.nvim_set_current_buf ( api.nvim_list_bufs ( ) [ 1 ] )
eq ( api.nvim_list_bufs ( ) [ 1 ] , api.nvim_get_current_buf ( ) )
2014-10-08 09:56:01 -07:00
end )
end )
2016-10-22 15:02:22 -07:00
describe ( ' nvim_{get,set}_current_win, nvim_list_wins ' , function ( )
2014-10-08 09:56:01 -07:00
it ( ' works ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( 1 , # api.nvim_list_wins ( ) )
eq ( api.nvim_list_wins ( ) [ 1 ] , api.nvim_get_current_win ( ) )
2024-01-12 06:11:28 -07:00
command ( ' vsplit ' )
command ( ' split ' )
2024-01-12 10:59:57 -07:00
eq ( 3 , # api.nvim_list_wins ( ) )
eq ( api.nvim_list_wins ( ) [ 1 ] , api.nvim_get_current_win ( ) )
api.nvim_set_current_win ( api.nvim_list_wins ( ) [ 2 ] )
eq ( api.nvim_list_wins ( ) [ 2 ] , api.nvim_get_current_win ( ) )
2014-10-08 09:56:01 -07:00
end )
end )
2016-10-22 15:02:22 -07:00
describe ( ' nvim_{get,set}_current_tabpage, nvim_list_tabpages ' , function ( )
2014-10-08 09:56:01 -07:00
it ( ' works ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( 1 , # api.nvim_list_tabpages ( ) )
eq ( api.nvim_list_tabpages ( ) [ 1 ] , api.nvim_get_current_tabpage ( ) )
2024-01-12 06:11:28 -07:00
command ( ' tabnew ' )
2024-01-12 10:59:57 -07:00
eq ( 2 , # api.nvim_list_tabpages ( ) )
eq ( 2 , # api.nvim_list_wins ( ) )
eq ( api.nvim_list_wins ( ) [ 2 ] , api.nvim_get_current_win ( ) )
eq ( api.nvim_list_tabpages ( ) [ 2 ] , api.nvim_get_current_tabpage ( ) )
api.nvim_set_current_win ( api.nvim_list_wins ( ) [ 1 ] )
2014-10-08 09:56:01 -07:00
-- Switching window also switches tabpages if necessary
2024-01-12 10:59:57 -07:00
eq ( api.nvim_list_tabpages ( ) [ 1 ] , api.nvim_get_current_tabpage ( ) )
eq ( api.nvim_list_wins ( ) [ 1 ] , api.nvim_get_current_win ( ) )
api.nvim_set_current_tabpage ( api.nvim_list_tabpages ( ) [ 2 ] )
eq ( api.nvim_list_tabpages ( ) [ 2 ] , api.nvim_get_current_tabpage ( ) )
eq ( api.nvim_list_wins ( ) [ 2 ] , api.nvim_get_current_win ( ) )
2014-10-08 09:56:01 -07:00
end )
end )
2014-10-23 17:14:50 -07:00
2017-03-13 07:02:37 -07:00
describe ( ' nvim_get_mode ' , function ( )
2023-12-07 04:19:35 -07:00
it ( ' during normal-mode `g` returns blocking=true ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_input ( ' o ' ) -- add a line
eq ( { mode = ' i ' , blocking = false } , api.nvim_get_mode ( ) )
api.nvim_input ( [[<C-\><C-N>]] )
eq ( 2 , api.nvim_eval ( " line('.') " ) )
eq ( { mode = ' n ' , blocking = false } , api.nvim_get_mode ( ) )
2017-03-13 07:02:37 -07:00
2024-01-12 10:59:57 -07:00
api.nvim_input ( ' g ' )
eq ( { mode = ' n ' , blocking = true } , api.nvim_get_mode ( ) )
2017-03-13 07:02:37 -07:00
2024-01-12 10:59:57 -07:00
api.nvim_input ( ' k ' ) -- complete the operator
eq ( 1 , api.nvim_eval ( " line('.') " ) ) -- verify the completed operator
eq ( { mode = ' n ' , blocking = false } , api.nvim_get_mode ( ) )
2017-03-13 07:02:37 -07:00
end )
2023-12-07 04:19:35 -07:00
it ( ' returns the correct result multiple consecutive times ' , function ( )
for _ = 1 , 5 do
2024-01-12 10:59:57 -07:00
eq ( { mode = ' n ' , blocking = false } , api.nvim_get_mode ( ) )
2017-03-13 07:02:37 -07:00
end
2024-01-12 10:59:57 -07:00
api.nvim_input ( ' g ' )
2023-12-07 04:19:35 -07:00
for _ = 1 , 4 do
2024-01-12 10:59:57 -07:00
eq ( { mode = ' n ' , blocking = true } , api.nvim_get_mode ( ) )
2017-03-13 07:02:37 -07:00
end
2024-01-12 10:59:57 -07:00
api.nvim_input ( ' g ' )
2023-12-07 04:19:35 -07:00
for _ = 1 , 7 do
2024-01-12 10:59:57 -07:00
eq ( { mode = ' n ' , blocking = false } , api.nvim_get_mode ( ) )
2017-03-13 07:02:37 -07:00
end
end )
2023-12-07 04:19:35 -07:00
it ( ' during normal-mode CTRL-W, returns blocking=true ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_input ( ' <C-W> ' )
eq ( { mode = ' n ' , blocking = true } , api.nvim_get_mode ( ) )
2017-03-13 07:02:37 -07:00
2024-01-12 10:59:57 -07:00
api.nvim_input ( ' s ' ) -- complete the operator
eq ( 2 , api.nvim_eval ( " winnr('$') " ) ) -- verify the completed operator
eq ( { mode = ' n ' , blocking = false } , api.nvim_get_mode ( ) )
2017-03-13 07:02:37 -07:00
end )
2023-12-07 04:19:35 -07:00
it ( ' during press-enter prompt without UI returns blocking=false ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( { mode = ' n ' , blocking = false } , api.nvim_get_mode ( ) )
2022-01-24 23:59:17 -07:00
command ( " echom 'msg1' " )
command ( " echom 'msg2' " )
command ( " echom 'msg3' " )
command ( " echom 'msg4' " )
command ( " echom 'msg5' " )
2024-01-12 10:59:57 -07:00
eq ( { mode = ' n ' , blocking = false } , api.nvim_get_mode ( ) )
api.nvim_input ( ' :messages<CR> ' )
eq ( { mode = ' n ' , blocking = false } , api.nvim_get_mode ( ) )
2022-01-24 23:59:17 -07:00
end )
2023-12-07 04:19:35 -07:00
it ( ' during press-enter prompt returns blocking=true ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_ui_attach ( 80 , 20 , { } )
eq ( { mode = ' n ' , blocking = false } , api.nvim_get_mode ( ) )
2017-03-13 07:02:37 -07:00
command ( " echom 'msg1' " )
command ( " echom 'msg2' " )
command ( " echom 'msg3' " )
command ( " echom 'msg4' " )
command ( " echom 'msg5' " )
2024-01-12 10:59:57 -07:00
eq ( { mode = ' n ' , blocking = false } , api.nvim_get_mode ( ) )
api.nvim_input ( ' :messages<CR> ' )
eq ( { mode = ' r ' , blocking = true } , api.nvim_get_mode ( ) )
2017-03-13 07:02:37 -07:00
end )
2023-12-07 04:19:35 -07:00
it ( ' during getchar() returns blocking=false ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_input ( ' :let g:test_input = nr2char(getchar())<CR> ' )
2017-03-13 07:02:37 -07:00
-- Events are enabled during getchar(), RPC calls are *not* blocked. #5384
2024-01-12 10:59:57 -07:00
eq ( { mode = ' n ' , blocking = false } , api.nvim_get_mode ( ) )
eq ( 0 , api.nvim_eval ( " exists('g:test_input') " ) )
api.nvim_input ( ' J ' )
eq ( ' J ' , api.nvim_eval ( ' g:test_input ' ) )
eq ( { mode = ' n ' , blocking = false } , api.nvim_get_mode ( ) )
2017-03-13 07:02:37 -07:00
end )
-- TODO: bug #6247#issuecomment-286403810
2023-12-07 04:19:35 -07:00
it ( ' batched with input ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_ui_attach ( 80 , 20 , { } )
eq ( { mode = ' n ' , blocking = false } , api.nvim_get_mode ( ) )
2017-03-13 07:02:37 -07:00
command ( " echom 'msg1' " )
command ( " echom 'msg2' " )
command ( " echom 'msg3' " )
command ( " echom 'msg4' " )
command ( " echom 'msg5' " )
local req = {
2023-12-07 04:19:35 -07:00
{ ' nvim_get_mode ' , { } } ,
{ ' nvim_input ' , { ' :messages<CR> ' } } ,
{ ' nvim_get_mode ' , { } } ,
{ ' nvim_eval ' , { ' 1 ' } } ,
2017-03-13 07:02:37 -07:00
}
2023-12-07 04:19:35 -07:00
eq ( {
{
{ mode = ' n ' , blocking = false } ,
13 ,
{ mode = ' n ' , blocking = false } , -- TODO: should be blocked=true ?
1 ,
} ,
NIL ,
2024-01-12 10:59:57 -07:00
} , api.nvim_call_atomic ( req ) )
eq ( { mode = ' r ' , blocking = true } , api.nvim_get_mode ( ) )
2017-03-13 07:02:37 -07:00
end )
2023-12-07 04:19:35 -07:00
it ( ' during insert-mode map-pending, returns blocking=true #6166 ' , function ( )
command ( ' inoremap xx foo ' )
2024-01-12 10:59:57 -07:00
api.nvim_input ( ' ix ' )
eq ( { mode = ' i ' , blocking = true } , api.nvim_get_mode ( ) )
2017-03-13 07:02:37 -07:00
end )
2023-12-07 04:19:35 -07:00
it ( ' during normal-mode gU, returns blocking=false #6166 ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_input ( ' gu ' )
eq ( { mode = ' no ' , blocking = false } , api.nvim_get_mode ( ) )
2017-03-13 07:02:37 -07:00
end )
2020-02-19 03:00:09 -07:00
it ( " at '-- More --' prompt returns blocking=true #11899 " , function ( )
command ( ' set more ' )
feed ( ' :digraphs<cr> ' )
2024-01-12 10:59:57 -07:00
eq ( { mode = ' rm ' , blocking = true } , api.nvim_get_mode ( ) )
2020-02-19 03:00:09 -07:00
end )
2022-03-29 14:25:00 -07:00
it ( ' after <Nop> mapping returns blocking=false #17257 ' , function ( )
command ( ' nnoremap <F2> <Nop> ' )
feed ( ' <F2> ' )
2024-01-12 10:59:57 -07:00
eq ( { mode = ' n ' , blocking = false } , api.nvim_get_mode ( ) )
2022-03-29 14:25:00 -07:00
end )
it ( ' after empty string <expr> mapping returns blocking=false #17257 ' , function ( )
command ( ' nnoremap <expr> <F2> "" ' )
feed ( ' <F2> ' )
2024-01-12 10:59:57 -07:00
eq ( { mode = ' n ' , blocking = false } , api.nvim_get_mode ( ) )
2022-03-29 14:25:00 -07:00
end )
2017-03-13 07:02:37 -07:00
end )
2021-12-26 00:23:39 -07:00
describe ( ' RPC (K_EVENT) ' , function ( )
it ( ' does not complete ("interrupt") normal-mode operator-pending #6166 ' , function ( )
2024-04-20 08:44:13 -07:00
n.insert ( [ [
2017-09-02 06:12:32 -07:00
FIRST LINE
SECOND LINE ] ] )
2024-01-12 10:59:57 -07:00
api.nvim_input ( ' gg ' )
api.nvim_input ( ' gu ' )
2017-09-04 13:45:14 -07:00
-- Make any RPC request (can be non-async: op-pending does not block).
2024-01-12 10:59:57 -07:00
api.nvim_get_current_buf ( )
2017-09-02 06:12:32 -07:00
-- Buffer should not change.
2019-08-19 14:43:19 -07:00
expect ( [ [
2017-09-02 06:12:32 -07:00
FIRST LINE
SECOND LINE ] ] )
-- Now send input to complete the operator.
2024-01-12 10:59:57 -07:00
api.nvim_input ( ' j ' )
2019-08-19 14:43:19 -07:00
expect ( [ [
2017-09-04 13:45:14 -07:00
first line
second line ] ] )
2017-09-02 06:12:32 -07:00
end )
2017-09-16 03:17:59 -07:00
it ( ' does not complete ("interrupt") `d` #3732 ' , function ( )
local screen = Screen.new ( 20 , 4 )
screen : attach ( )
command ( ' set listchars=eol:$ ' )
command ( ' set list ' )
feed ( ' ia<cr>b<cr>c<cr><Esc>kkk ' )
feed ( ' d ' )
-- Make any RPC request (can be non-async: op-pending does not block).
2024-01-12 10:59:57 -07:00
api.nvim_get_current_buf ( )
2017-09-16 03:17:59 -07:00
screen : expect ( [ [
2024-03-22 03:02:52 -07:00
^ a { 1 : $ } |
b { 1 : $ } |
c { 1 : $ } |
2017-09-16 03:17:59 -07:00
|
] ] )
end )
2021-12-26 00:23:39 -07:00
it ( ' does not complete ("interrupt") normal-mode map-pending #6166 ' , function ( )
2017-09-02 06:12:32 -07:00
command ( " nnoremap dd :let g:foo='it worked...'<CR> " )
2024-04-20 08:44:13 -07:00
n.insert ( [ [
2017-09-02 06:12:32 -07:00
FIRST LINE
SECOND LINE ] ] )
2024-01-12 10:59:57 -07:00
api.nvim_input ( ' gg ' )
api.nvim_input ( ' d ' )
2017-09-04 13:45:14 -07:00
-- Make any RPC request (must be async, because map-pending blocks).
2024-01-12 10:59:57 -07:00
api.nvim_get_api_info ( )
2017-09-02 06:12:32 -07:00
-- Send input to complete the mapping.
2024-01-12 10:59:57 -07:00
api.nvim_input ( ' d ' )
2019-08-19 14:43:19 -07:00
expect ( [ [
2017-09-02 06:12:32 -07:00
FIRST LINE
SECOND LINE ] ] )
2024-04-20 08:44:13 -07:00
eq ( ' it worked... ' , n.eval ( ' g:foo ' ) )
2017-09-02 06:12:32 -07:00
end )
2021-12-26 00:23:39 -07:00
it ( ' does not complete ("interrupt") insert-mode map-pending #6166 ' , function ( )
2017-09-04 13:45:14 -07:00
command ( ' inoremap xx foo ' )
command ( ' set timeoutlen=9999 ' )
2024-04-20 08:44:13 -07:00
n.insert ( [ [
2017-09-02 06:12:32 -07:00
FIRST LINE
SECOND LINE ] ] )
2024-01-12 10:59:57 -07:00
api.nvim_input ( ' ix ' )
2017-09-04 13:45:14 -07:00
-- Make any RPC request (must be async, because map-pending blocks).
2024-01-12 10:59:57 -07:00
api.nvim_get_api_info ( )
2017-09-02 06:12:32 -07:00
-- Send input to complete the mapping.
2024-01-12 10:59:57 -07:00
api.nvim_input ( ' x ' )
2019-08-19 14:43:19 -07:00
expect ( [ [
2017-09-02 06:12:32 -07:00
FIRST LINE
2017-09-04 13:45:14 -07:00
SECOND LINfooE ] ] )
2017-09-02 06:12:32 -07:00
end )
2021-12-26 00:23:39 -07:00
it ( ' does not interrupt Insert mode i_CTRL-O #10035 ' , function ( )
feed ( ' iHello World<c-o> ' )
2024-01-12 10:59:57 -07:00
eq ( { mode = ' niI ' , blocking = false } , api.nvim_get_mode ( ) ) -- fast event
2023-12-07 04:19:35 -07:00
eq ( 2 , eval ( ' 1+1 ' ) ) -- causes K_EVENT key
2024-01-12 10:59:57 -07:00
eq ( { mode = ' niI ' , blocking = false } , api.nvim_get_mode ( ) ) -- still in ctrl-o mode
2021-12-26 00:23:39 -07:00
feed ( ' dd ' )
2024-01-12 10:59:57 -07:00
eq ( { mode = ' i ' , blocking = false } , api.nvim_get_mode ( ) ) -- left ctrl-o mode
2021-12-26 00:23:39 -07:00
expect ( ' ' ) -- executed the command
end )
it ( ' does not interrupt Select mode v_CTRL-O #15688 ' , function ( )
feed ( ' iHello World<esc>gh<c-o> ' )
2024-01-12 10:59:57 -07:00
eq ( { mode = ' vs ' , blocking = false } , api.nvim_get_mode ( ) ) -- fast event
eq ( { mode = ' vs ' , blocking = false } , api.nvim_get_mode ( ) ) -- again #15288
2023-12-07 04:19:35 -07:00
eq ( 2 , eval ( ' 1+1 ' ) ) -- causes K_EVENT key
2024-01-12 10:59:57 -07:00
eq ( { mode = ' vs ' , blocking = false } , api.nvim_get_mode ( ) ) -- still in ctrl-o mode
2021-12-26 00:23:39 -07:00
feed ( ' ^ ' )
2024-01-12 10:59:57 -07:00
eq ( { mode = ' s ' , blocking = false } , api.nvim_get_mode ( ) ) -- left ctrl-o mode
2021-12-26 00:23:39 -07:00
feed ( ' h ' )
2024-01-12 10:59:57 -07:00
eq ( { mode = ' i ' , blocking = false } , api.nvim_get_mode ( ) ) -- entered insert mode
2023-12-07 04:19:35 -07:00
expect ( ' h ' ) -- selection is the whole line and is replaced
2021-12-26 00:23:39 -07:00
end )
it ( ' does not interrupt Insert mode i_0_CTRL-D #13997 ' , function ( )
command ( ' set timeoutlen=9999 ' )
feed ( ' i<Tab><Tab>a0 ' )
2023-12-07 04:19:35 -07:00
eq ( 2 , eval ( ' 1+1 ' ) ) -- causes K_EVENT key
2021-12-26 00:23:39 -07:00
feed ( ' <C-D> ' )
2023-12-07 04:19:35 -07:00
expect ( ' a ' ) -- recognized i_0_CTRL-D
2021-12-26 00:23:39 -07:00
end )
2023-07-04 21:06:14 -07:00
it ( " does not interrupt with 'digraph' " , function ( )
command ( ' set digraph ' )
feed ( ' i, ' )
2023-12-07 04:19:35 -07:00
eq ( 2 , eval ( ' 1+1 ' ) ) -- causes K_EVENT key
2023-07-04 21:06:14 -07:00
feed ( ' <BS> ' )
2023-12-07 04:19:35 -07:00
eq ( 2 , eval ( ' 1+1 ' ) ) -- causes K_EVENT key
2023-07-04 21:06:14 -07:00
feed ( ' . ' )
2023-12-07 04:19:35 -07:00
expect ( ' … ' ) -- digraph ",." worked
2023-07-04 21:06:14 -07:00
feed ( ' <Esc> ' )
feed ( ' :, ' )
2023-12-07 04:19:35 -07:00
eq ( 2 , eval ( ' 1+1 ' ) ) -- causes K_EVENT key
2023-07-04 21:06:14 -07:00
feed ( ' <BS> ' )
2023-12-07 04:19:35 -07:00
eq ( 2 , eval ( ' 1+1 ' ) ) -- causes K_EVENT key
2023-07-04 21:06:14 -07:00
feed ( ' . ' )
2024-01-12 10:59:57 -07:00
eq ( ' … ' , fn.getcmdline ( ) ) -- digraph ",." worked
2023-07-04 21:06:14 -07:00
end )
2017-09-02 06:12:32 -07:00
end )
2019-07-17 13:00:50 -07:00
describe ( ' nvim_get_context ' , function ( )
2023-02-14 12:19:28 -07:00
it ( ' validation ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( " Invalid key: 'blah' " , pcall_err ( api.nvim_get_context , { blah = { } } ) )
2023-12-07 04:19:35 -07:00
eq (
" Invalid 'types': expected Array, got Integer " ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_get_context , { types = 42 } )
2023-12-07 04:19:35 -07:00
)
eq (
" Invalid 'type': 'zub' " ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_get_context , { types = { ' jumps ' , ' zub ' , ' zam ' } } )
2023-12-07 04:19:35 -07:00
)
2019-09-14 18:13:02 -07:00
end )
it ( ' returns map of current editor state ' , function ( )
2023-12-07 04:19:35 -07:00
local opts = { types = { ' regs ' , ' jumps ' , ' bufs ' , ' gvars ' } }
2024-01-12 10:59:57 -07:00
eq ( { } , parse_context ( api.nvim_get_context ( { } ) ) )
2019-07-17 13:00:50 -07:00
feed ( ' i1<cr>2<cr>3<c-[>ddddddqahjklquuu ' )
feed ( ' gg ' )
feed ( ' G ' )
command ( ' edit! BUF1 ' )
command ( ' edit BUF2 ' )
2024-01-12 10:59:57 -07:00
api.nvim_set_var ( ' one ' , 1 )
api.nvim_set_var ( ' Two ' , 2 )
api.nvim_set_var ( ' THREE ' , 3 )
2019-07-17 13:00:50 -07:00
local expected_ctx = {
[ ' regs ' ] = {
2023-12-07 04:19:35 -07:00
{ [ ' rt ' ] = 1 , [ ' rc ' ] = { ' 1 ' } , [ ' n ' ] = 49 , [ ' ru ' ] = true } ,
{ [ ' rt ' ] = 1 , [ ' rc ' ] = { ' 2 ' } , [ ' n ' ] = 50 } ,
{ [ ' rt ' ] = 1 , [ ' rc ' ] = { ' 3 ' } , [ ' n ' ] = 51 } ,
{ [ ' rc ' ] = { ' hjkl ' } , [ ' n ' ] = 97 } ,
2019-07-17 13:00:50 -07:00
} ,
2024-01-15 09:10:51 -07:00
[ ' jumps ' ] = eval ( ( ( [ [
2023-01-23 04:32:27 -07:00
filter ( map ( add (
getjumplist ( ) [ 0 ] , { ' bufnr ' : bufnr ( ' % ' ) , ' lnum ' : getcurpos ( ) [ 1 ] } ) ,
' filter(
{ " f " : expand ( " # " . v : val.bufnr . " :p " ) , " l " : v : val.lnum } ,
{ k , v -> k ! = " l " || v ! = 1 } ) ' ), ' ! empty ( v : val.f ) ' )
2024-01-15 09:10:51 -07:00
] ] ) : gsub ( ' \n ' , ' ' ) ) ) ,
2019-07-17 13:00:50 -07:00
2019-09-14 18:52:16 -07:00
[ ' bufs ' ] = eval ( [ [
2019-07-17 13:00:50 -07:00
filter ( map ( getbufinfo ( ) , ' { "f": v:val.name } ' ) , ' !empty(v:val.f) ' )
] ] ) ,
2023-12-07 04:19:35 -07:00
[ ' gvars ' ] = { { ' one ' , 1 } , { ' Two ' , 2 } , { ' THREE ' , 3 } } ,
2019-07-17 13:00:50 -07:00
}
2024-01-12 10:59:57 -07:00
eq ( expected_ctx , parse_context ( api.nvim_get_context ( opts ) ) )
eq ( expected_ctx , parse_context ( api.nvim_get_context ( { } ) ) )
eq ( expected_ctx , parse_context ( api.nvim_get_context ( { types = { } } ) ) )
2019-07-17 13:00:50 -07:00
end )
end )
describe ( ' nvim_load_context ' , 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 ( ' sets current editor state to given context dict ' , function ( )
2023-12-07 04:19:35 -07:00
local opts = { types = { ' regs ' , ' jumps ' , ' bufs ' , ' gvars ' } }
2024-01-12 10:59:57 -07:00
eq ( { } , parse_context ( api.nvim_get_context ( opts ) ) )
api.nvim_set_var ( ' one ' , 1 )
api.nvim_set_var ( ' Two ' , 2 )
api.nvim_set_var ( ' THREE ' , 3 )
local ctx = api.nvim_get_context ( opts )
api.nvim_set_var ( ' one ' , ' a ' )
api.nvim_set_var ( ' Two ' , ' b ' )
api.nvim_set_var ( ' THREE ' , ' c ' )
2023-12-07 04:19:35 -07:00
eq ( { ' a ' , ' b ' , ' c ' } , eval ( ' [g:one, g:Two, g:THREE] ' ) )
2024-01-12 10:59:57 -07:00
api.nvim_load_context ( ctx )
2023-12-07 04:19:35 -07:00
eq ( { 1 , 2 , 3 } , eval ( ' [g:one, g:Two, g:THREE] ' ) )
2019-07-17 13:00:50 -07:00
end )
2023-11-10 19:21:14 -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 ( ' errors when context dict is invalid ' , function ( )
2023-12-07 04:19:35 -07:00
eq (
' E474: Failed to convert list to msgpack string buffer ' ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_load_context , { regs = { { } } , jumps = { { } } } )
2023-12-07 04:19:35 -07:00
)
eq (
' E474: Failed to convert list to msgpack string buffer ' ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_load_context , { regs = { { [ ' ' ] = ' ' } } } )
2023-12-07 04:19:35 -07:00
)
2023-11-10 19:21:14 -07:00
end )
2019-07-17 13:00:50 -07:00
end )
2016-10-22 15:02:22 -07:00
describe ( ' nvim_replace_termcodes ' , function ( )
2014-10-20 02:21:24 -07:00
it ( ' escapes K_SPECIAL as K_SPECIAL KS_SPECIAL KE_FILLER ' , function ( )
2024-04-20 08:44:13 -07:00
eq ( ' \128 \254 X ' , n.api . nvim_replace_termcodes ( ' \128 ' , true , true , true ) )
2014-10-20 02:21:24 -07:00
end )
2016-02-20 15:09:15 -07:00
it ( ' leaves non-K_SPECIAL string unchanged ' , function ( )
2024-04-20 08:44:13 -07:00
eq ( ' abc ' , n.api . nvim_replace_termcodes ( ' abc ' , true , true , true ) )
2014-10-20 02:21:24 -07:00
end )
it ( ' converts <expressions> ' , function ( )
2024-04-20 08:44:13 -07:00
eq ( ' \\ ' , n.api . nvim_replace_termcodes ( ' <Leader> ' , true , true , true ) )
2016-02-20 15:09:15 -07:00
end )
it ( ' converts <LeftMouse> to K_SPECIAL KS_EXTRA KE_LEFTMOUSE ' , function ( )
-- K_SPECIAL KS_EXTRA KE_LEFTMOUSE
-- 0x80 0xfd 0x2c
-- 128 253 44
2024-04-20 08:44:13 -07:00
eq ( ' \128 \253 \44 ' , n.api . nvim_replace_termcodes ( ' <LeftMouse> ' , true , true , true ) )
2014-10-20 02:21:24 -07:00
end )
2016-07-15 16:26:04 -07:00
2017-05-20 13:20:21 -07:00
it ( ' converts keycodes ' , function ( )
2024-04-20 08:44:13 -07:00
eq ( ' \n x \27 x \r x<x ' , n.api . nvim_replace_termcodes ( ' <NL>x<Esc>x<CR>x<lt>x ' , true , true , true ) )
2017-05-20 13:20:21 -07:00
end )
2017-07-02 04:21:38 -07:00
it ( ' does not convert keycodes if special=false ' , function ( )
2023-12-07 04:19:35 -07:00
eq (
' <NL>x<Esc>x<CR>x<lt>x ' ,
2024-04-20 08:44:13 -07:00
n.api . nvim_replace_termcodes ( ' <NL>x<Esc>x<CR>x<lt>x ' , true , true , false )
2023-12-07 04:19:35 -07:00
)
2017-07-02 04:21:38 -07:00
end )
2016-07-15 16:26:04 -07:00
it ( ' does not crash when transforming an empty string ' , function ( )
-- Actually does not test anything, because current code will use NULL for
-- an empty string.
--
-- Problem here is that if String argument has .data in allocated memory
-- then `return str` in vim_replace_termcodes body will make Neovim free
-- `str.data` twice: once when freeing arguments, then when freeing return
-- value.
2024-01-12 10:59:57 -07:00
eq ( ' ' , api.nvim_replace_termcodes ( ' ' , true , true , true ) )
2016-07-15 16:26:04 -07:00
end )
2023-08-13 07:14:48 -07:00
-- Not exactly the case, as nvim_replace_termcodes() escapes K_SPECIAL in Unicode
it ( ' translates the result of keytrans() on string with 0x80 byte back ' , function ( )
local s = ' ff \128 \253 \097 tt '
2024-01-12 10:59:57 -07:00
eq ( s , api.nvim_replace_termcodes ( fn.keytrans ( s ) , true , true , true ) )
2023-08-13 07:14:48 -07:00
end )
2014-10-20 02:21:24 -07:00
end )
2016-10-22 15:02:22 -07:00
describe ( ' nvim_feedkeys ' , function ( )
2022-01-21 03:08:56 -07:00
it ( ' K_SPECIAL escaping ' , function ( )
2014-10-20 02:21:24 -07:00
local function on_setup ( )
-- notice the special char(…) \xe2\80\xa6
2024-01-12 10:59:57 -07:00
api.nvim_feedkeys ( ' :let x1="…" \n ' , ' ' , true )
2014-10-20 02:21:24 -07:00
2017-07-02 04:21:38 -07:00
-- Both nvim_replace_termcodes and nvim_feedkeys escape \x80
2024-04-20 08:44:13 -07:00
local inp = n.api . nvim_replace_termcodes ( ' :let x2="…"<CR> ' , true , true , true )
2024-01-12 10:59:57 -07:00
api.nvim_feedkeys ( inp , ' ' , true ) -- escape_ks=true
2014-10-20 02:21:24 -07:00
2022-01-21 03:08:56 -07:00
-- nvim_feedkeys with K_SPECIAL escaping disabled
2024-04-20 08:44:13 -07:00
inp = n.api . nvim_replace_termcodes ( ' :let x3="…"<CR> ' , true , true , true )
2024-01-12 10:59:57 -07:00
api.nvim_feedkeys ( inp , ' ' , false ) -- escape_ks=false
2014-10-20 02:21:24 -07:00
2024-04-20 08:44:13 -07:00
n.stop ( )
2014-10-20 02:21:24 -07:00
end
-- spin the loop a bit
2024-04-20 08:44:13 -07:00
n.run ( nil , nil , on_setup )
2014-10-20 02:21:24 -07:00
2024-01-12 10:59:57 -07:00
eq ( ' … ' , api.nvim_get_var ( ' x1 ' ) )
2014-10-20 02:21:24 -07:00
-- Because of the double escaping this is neq
2024-01-12 10:59:57 -07:00
neq ( ' … ' , api.nvim_get_var ( ' x2 ' ) )
eq ( ' … ' , api.nvim_get_var ( ' x3 ' ) )
2014-10-20 02:21:24 -07:00
end )
end )
2022-10-08 05:10:00 -07:00
describe ( ' nvim_out_write ' , function ( )
2023-09-24 20:06:15 -07:00
local screen
before_each ( function ( )
screen = Screen.new ( 40 , 8 )
screen : attach ( )
end )
2022-10-08 05:10:00 -07:00
it ( ' prints long messages correctly #20534 ' , function ( )
exec ( [ [
set more
redir => g : out
silent ! call nvim_out_write ( ' a ' )
silent ! call nvim_out_write ( ' a ' )
silent ! call nvim_out_write ( ' a ' )
silent ! call nvim_out_write ( " \n " )
silent ! call nvim_out_write ( ' a ' )
silent ! call nvim_out_write ( ' a ' )
silent ! call nvim_out_write ( repeat ( ' a ' , 5000 ) .. " \n " )
silent ! call nvim_out_write ( ' a ' )
silent ! call nvim_out_write ( ' a ' )
silent ! call nvim_out_write ( ' a ' )
silent ! call nvim_out_write ( " \n " )
redir END
] ] )
2024-01-12 10:59:57 -07:00
eq ( ' \n aaa \n ' .. ( ' a ' ) : rep ( 5002 ) .. ' \n aaa ' , api.nvim_get_var ( ' out ' ) )
2022-10-08 05:10:00 -07:00
end )
2023-07-03 16:19:02 -07:00
2023-09-24 20:06:15 -07:00
it ( ' blank line in message ' , function ( )
2023-07-03 16:19:02 -07:00
feed ( [[:call nvim_out_write("\na\n")<CR>]] )
2023-12-07 04:19:35 -07:00
screen : expect {
grid = [ [
2023-07-03 16:19:02 -07:00
|
2024-05-25 10:18:57 -07:00
{ 1 : ~ } |* 3
{ 3 : } |
2023-07-03 16:19:02 -07:00
|
a |
2024-05-25 10:18:57 -07:00
{ 6 : Press ENTER or type command to continue } ^ |
2023-12-07 04:19:35 -07:00
] ] ,
}
2023-07-03 16:19:02 -07:00
feed ( ' <CR> ' )
feed ( [[:call nvim_out_write("b\n\nc\n")<CR>]] )
2023-12-07 04:19:35 -07:00
screen : expect {
grid = [ [
2023-07-03 16:19:02 -07:00
|
2024-05-25 10:18:57 -07:00
{ 1 : ~ } |* 2
{ 3 : } |
2023-07-03 16:19:02 -07:00
b |
|
c |
2024-05-25 10:18:57 -07:00
{ 6 : Press ENTER or type command to continue } ^ |
2023-12-07 04:19:35 -07:00
] ] ,
}
2023-07-03 16:19:02 -07:00
end )
2023-09-24 20:06:15 -07:00
it ( ' NUL bytes in message ' , function ( )
feed ( [[:lua vim.api.nvim_out_write('aaa\0bbb\0\0ccc\nddd\0\0\0eee\n')<CR>]] )
2023-12-07 04:19:35 -07:00
screen : expect {
grid = [ [
2023-09-24 20:06:15 -07:00
|
2024-05-25 10:18:57 -07:00
{ 1 : ~ } |* 3
{ 3 : } |
aaa { 18 : ^ @ } bbb { 18 : ^ @ ^ @ } ccc |
ddd { 18 : ^ @ ^ @ ^ @ } eee |
{ 6 : Press ENTER or type command to continue } ^ |
2023-12-07 04:19:35 -07:00
] ] ,
}
2023-09-24 20:06:15 -07:00
end )
2022-10-08 05:10:00 -07:00
end )
2016-10-22 15:02:22 -07:00
describe ( ' nvim_err_write ' , function ( )
2015-11-17 15:31:22 -07:00
local screen
2015-07-27 04:39:38 -07:00
before_each ( function ( )
screen = Screen.new ( 40 , 8 )
screen : attach ( )
end )
it ( ' can show one line ' , function ( )
2024-01-15 09:10:51 -07:00
async_meths.nvim_err_write ( ' has bork \n ' )
2015-07-27 04:39:38 -07:00
screen : expect ( [ [
^ |
2024-05-25 10:18:57 -07:00
{ 1 : ~ } |* 6
{ 9 : has bork } |
2015-07-27 04:39:38 -07:00
] ] )
end )
it ( ' shows return prompt when more than &cmdheight lines ' , function ( )
2024-01-15 09:10:51 -07:00
async_meths.nvim_err_write ( ' something happened \n very bad \n ' )
2015-07-27 04:39:38 -07:00
screen : expect ( [ [
2018-03-31 02:12:27 -07:00
|
2024-05-25 10:18:57 -07:00
{ 1 : ~ } |* 3
2018-03-31 02:12:27 -07:00
{ 3 : } |
2024-05-25 10:18:57 -07:00
{ 9 : something happened } |
{ 9 : very bad } |
{ 6 : Press ENTER or type command to continue } ^ |
2015-07-27 04:39:38 -07:00
] ] )
end )
it ( ' shows return prompt after all lines are shown ' , function ( )
2024-01-15 09:10:51 -07:00
async_meths.nvim_err_write ( ' FAILURE \n ERROR \n EXCEPTION \n TRACEBACK \n ' )
2015-07-27 04:39:38 -07:00
screen : expect ( [ [
2018-03-31 02:12:27 -07:00
|
2024-05-25 10:18:57 -07:00
{ 1 : ~ } |
2018-03-31 02:12:27 -07:00
{ 3 : } |
2024-05-25 10:18:57 -07:00
{ 9 : FAILURE } |
{ 9 : ERROR } |
{ 9 : EXCEPTION } |
{ 9 : TRACEBACK } |
{ 6 : Press ENTER or type command to continue } ^ |
2015-07-27 04:39:38 -07:00
] ] )
end )
it ( ' handles multiple calls ' , function ( )
-- without linebreak text is joined to one line
2024-01-15 09:10:51 -07:00
async_meths.nvim_err_write ( ' very ' )
async_meths.nvim_err_write ( ' fail \n ' )
2015-07-27 04:39:38 -07:00
screen : expect ( [ [
^ |
2024-05-25 10:18:57 -07:00
{ 1 : ~ } |* 6
{ 9 : very fail } |
2015-07-27 04:39:38 -07:00
] ] )
2024-04-20 08:44:13 -07:00
n.poke_eventloop ( )
2015-07-27 04:39:38 -07:00
-- shows up to &cmdheight lines
2024-01-15 09:10:51 -07:00
async_meths.nvim_err_write ( ' more fail \n too fail \n ' )
2015-07-27 04:39:38 -07:00
screen : expect ( [ [
2018-03-31 02:12:27 -07:00
|
2024-05-25 10:18:57 -07:00
{ 1 : ~ } |* 3
2018-03-31 02:12:27 -07:00
{ 3 : } |
2024-05-25 10:18:57 -07:00
{ 9 : more fail } |
{ 9 : too fail } |
{ 6 : Press ENTER or type command to continue } ^ |
2015-07-27 04:39:38 -07:00
] ] )
2023-12-07 04:19:35 -07:00
feed ( ' <cr> ' ) -- exit the press ENTER screen
2015-07-27 04:39:38 -07:00
end )
2023-09-24 20:06:15 -07:00
it ( ' NUL bytes in message ' , function ( )
2024-01-15 09:10:51 -07:00
async_meths.nvim_err_write ( ' aaa \0 bbb \0 \0 ccc \n ddd \0 \0 \0 eee \n ' )
2023-12-07 04:19:35 -07:00
screen : expect {
grid = [ [
2023-09-24 20:06:15 -07:00
|
2024-05-25 10:18:57 -07:00
{ 1 : ~ } |* 3
2023-09-24 20:06:15 -07:00
{ 3 : } |
2024-05-25 10:18:57 -07:00
{ 9 : aaa ^ @ bbb ^ @ ^ @ ccc } |
{ 9 : ddd ^ @ ^ @ ^ @ eee } |
{ 6 : Press ENTER or type command to continue } ^ |
2023-12-07 04:19:35 -07:00
] ] ,
}
2023-09-24 20:06:15 -07:00
end )
2015-07-27 04:39:38 -07:00
end )
2023-04-03 17:59:11 -07:00
describe ( ' nvim_err_writeln ' , function ( )
local screen
before_each ( function ( )
screen = Screen.new ( 40 , 8 )
screen : attach ( )
end )
it ( ' shows only one return prompt after all lines are shown ' , function ( )
2024-01-15 09:10:51 -07:00
async_meths.nvim_err_writeln ( ' FAILURE \n ERROR \n EXCEPTION \n TRACEBACK ' )
2023-04-03 17:59:11 -07:00
screen : expect ( [ [
|
2024-05-25 10:18:57 -07:00
{ 1 : ~ } |
2023-04-03 17:59:11 -07:00
{ 3 : } |
2024-05-25 10:18:57 -07:00
{ 9 : FAILURE } |
{ 9 : ERROR } |
{ 9 : EXCEPTION } |
{ 9 : TRACEBACK } |
{ 6 : Press ENTER or type command to continue } ^ |
2023-04-03 17:59:11 -07:00
] ] )
feed ( ' <CR> ' )
screen : expect ( [ [
^ |
2024-05-25 10:18:57 -07:00
{ 1 : ~ } |* 6
2023-04-03 17:59:11 -07:00
|
] ] )
end )
end )
2021-09-01 07:29:38 -07:00
describe ( ' nvim_list_chans, nvim_get_chan_info ' , function ( )
2017-05-13 22:43:07 -07:00
before_each ( function ( )
2021-09-01 07:29:38 -07:00
command ( ' autocmd ChanOpen * let g:opened_event = deepcopy(v:event) ' )
command ( ' autocmd ChanInfo * let g:info_event = deepcopy(v:event) ' )
2017-05-13 22:43:07 -07:00
end )
local testinfo = {
stream = ' stdio ' ,
id = 1 ,
mode = ' rpc ' ,
client = { } ,
}
local stderr = {
stream = ' stderr ' ,
id = 2 ,
mode = ' bytes ' ,
}
it ( ' returns {} for invalid channel ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( { } , api.nvim_get_chan_info ( - 1 ) )
2017-05-13 22:43:07 -07:00
-- more preallocated numbers might be added, try something high
2024-01-12 10:59:57 -07:00
eq ( { } , api.nvim_get_chan_info ( 10 ) )
2017-05-13 22:43:07 -07:00
end )
2021-09-01 07:29:38 -07:00
it ( ' stream=stdio channel ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( { [ 1 ] = testinfo , [ 2 ] = stderr } , api.nvim_list_chans ( ) )
2024-02-08 03:59:31 -07:00
-- 0 should return current channel
eq ( testinfo , api.nvim_get_chan_info ( 0 ) )
2024-01-12 10:59:57 -07:00
eq ( testinfo , api.nvim_get_chan_info ( 1 ) )
eq ( stderr , api.nvim_get_chan_info ( 2 ) )
2017-05-13 22:43:07 -07:00
2024-01-12 10:59:57 -07:00
api.nvim_set_client_info (
2023-12-07 04:19:35 -07:00
' functionaltests ' ,
{ major = 0 , minor = 3 , patch = 17 } ,
' ui ' ,
{ do_stuff = { n_args = { 2 , 3 } } } ,
{ license = ' Apache2 ' }
)
2017-05-13 22:43:07 -07:00
local info = {
stream = ' stdio ' ,
id = 1 ,
mode = ' rpc ' ,
client = {
2023-12-07 04:19:35 -07:00
name = ' functionaltests ' ,
version = { major = 0 , minor = 3 , patch = 17 } ,
type = ' ui ' ,
methods = { do_stuff = { n_args = { 2 , 3 } } } ,
attributes = { license = ' Apache2 ' } ,
2017-05-13 22:43:07 -07:00
} ,
}
2024-01-12 10:59:57 -07:00
eq ( { info = info } , api.nvim_get_var ( ' info_event ' ) )
eq ( { [ 1 ] = info , [ 2 ] = stderr } , api.nvim_list_chans ( ) )
eq ( info , api.nvim_get_chan_info ( 1 ) )
2017-05-13 22:43:07 -07:00
end )
2021-09-01 07:29:38 -07:00
it ( ' stream=job channel ' , function ( )
2017-05-13 22:43:07 -07:00
eq ( 3 , eval ( " jobstart(['cat'], {'rpc': v:true}) " ) )
2021-09-01 07:29:38 -07:00
local catpath = eval ( ' exepath("cat") ' )
2017-05-13 22:43:07 -07:00
local info = {
2023-12-07 04:19:35 -07:00
stream = ' job ' ,
id = 3 ,
argv = { catpath } ,
mode = ' rpc ' ,
client = { } ,
2017-05-13 22:43:07 -07:00
}
2024-01-12 10:59:57 -07:00
eq ( { info = info } , api.nvim_get_var ( ' opened_event ' ) )
eq ( { [ 1 ] = testinfo , [ 2 ] = stderr , [ 3 ] = info } , api.nvim_list_chans ( ) )
eq ( info , api.nvim_get_chan_info ( 3 ) )
2023-12-07 04:19:35 -07:00
eval (
' rpcrequest(3, "nvim_set_client_info", "amazing-cat", {}, "remote", '
.. ' {"nvim_command":{"n_args":1}}, ' -- and so on
.. ' {"description":"The Amazing Cat"}) '
)
2017-05-13 22:43:07 -07:00
info = {
2023-12-07 04:19:35 -07:00
stream = ' job ' ,
id = 3 ,
argv = { catpath } ,
mode = ' rpc ' ,
2017-05-13 22:43:07 -07:00
client = {
2023-12-07 04:19:35 -07:00
name = ' amazing-cat ' ,
version = { major = 0 } ,
type = ' remote ' ,
methods = { nvim_command = { n_args = 1 } } ,
attributes = { description = ' The Amazing Cat ' } ,
2017-05-13 22:43:07 -07:00
} ,
}
2024-01-12 10:59:57 -07:00
eq ( { info = info } , api.nvim_get_var ( ' info_event ' ) )
eq ( { [ 1 ] = testinfo , [ 2 ] = stderr , [ 3 ] = info } , api.nvim_list_chans ( ) )
2019-01-24 11:15:39 -07:00
2023-12-07 04:19:35 -07:00
eq (
" Vim:Error invoking 'nvim_set_current_buf' on channel 3 (amazing-cat): \n Wrong type for argument 1 when calling nvim_set_current_buf, expecting Buffer " ,
pcall_err ( eval , ' rpcrequest(3, "nvim_set_current_buf", -1) ' )
)
2024-02-08 03:59:31 -07:00
eq ( info , eval ( ' rpcrequest(3, "nvim_get_chan_info", 0) ' ) )
2017-05-13 22:43:07 -07:00
end )
2021-09-01 07:29:38 -07:00
it ( ' stream=job :terminal channel ' , function ( )
command ( ' :terminal ' )
2024-01-16 06:26:21 -07:00
eq ( 1 , api.nvim_get_current_buf ( ) )
2024-01-12 10:59:57 -07:00
eq ( 3 , api.nvim_get_option_value ( ' channel ' , { buf = 1 } ) )
2017-05-13 22:43:07 -07:00
local info = {
2023-12-07 04:19:35 -07:00
stream = ' job ' ,
id = 3 ,
argv = { eval ( ' exepath(&shell) ' ) } ,
mode = ' terminal ' ,
2017-05-13 22:43:07 -07:00
buffer = 1 ,
2023-12-07 04:19:35 -07:00
pty = ' ? ' ,
2017-05-13 22:43:07 -07:00
}
2024-01-12 10:59:57 -07:00
local event = api.nvim_get_var ( ' opened_event ' )
2022-11-21 17:13:30 -07:00
if not is_os ( ' win ' ) then
2017-05-13 22:43:07 -07:00
info.pty = event.info . pty
2023-12-07 04:19:35 -07:00
neq ( nil , string.match ( info.pty , ' ^/dev/ ' ) )
2017-05-13 22:43:07 -07:00
end
2023-12-07 04:19:35 -07:00
eq ( { info = info } , event )
2024-01-16 06:26:21 -07:00
info.buffer = 1
2024-01-12 10:59:57 -07:00
eq ( { [ 1 ] = testinfo , [ 2 ] = stderr , [ 3 ] = info } , api.nvim_list_chans ( ) )
eq ( info , api.nvim_get_chan_info ( 3 ) )
2021-09-01 07:29:38 -07:00
-- :terminal with args + running process.
2023-12-07 17:00:27 -07:00
command ( ' enew ' )
local progpath_esc = eval ( ' shellescape(v:progpath) ' )
2024-01-12 10:59:57 -07:00
fn.termopen ( ( ' %s -u NONE -i NONE ' ) : format ( progpath_esc ) , {
2023-12-07 04:19:35 -07:00
env = { VIMRUNTIME = os.getenv ( ' VIMRUNTIME ' ) } ,
2023-12-07 17:00:27 -07:00
} )
2023-12-07 04:19:35 -07:00
eq ( - 1 , eval ( ' jobwait([&channel], 0)[0] ' ) ) -- Running?
2021-09-01 07:29:38 -07:00
local expected2 = {
stream = ' job ' ,
id = 4 ,
2023-12-07 04:19:35 -07:00
argv = ( is_os ( ' win ' ) and {
eval ( ' &shell ' ) ,
' /s ' ,
' /c ' ,
fmt ( ' "%s -u NONE -i NONE" ' , progpath_esc ) ,
} or {
eval ( ' &shell ' ) ,
eval ( ' &shellcmdflag ' ) ,
fmt ( ' %s -u NONE -i NONE ' , progpath_esc ) ,
} ) ,
2021-09-01 07:29:38 -07:00
mode = ' terminal ' ,
buffer = 2 ,
pty = ' ? ' ,
}
local actual2 = eval ( ' nvim_get_chan_info(&channel) ' )
expected2.pty = actual2.pty
eq ( expected2 , actual2 )
-- :terminal with args + stopped process.
eq ( 1 , eval ( ' jobstop(&channel) ' ) )
2023-12-07 04:19:35 -07:00
eval ( ' jobwait([&channel], 1000) ' ) -- Wait.
expected2.pty = ( is_os ( ' win ' ) and ' ? ' or ' ' ) -- pty stream was closed.
2021-09-01 07:29:38 -07:00
eq ( expected2 , eval ( ' nvim_get_chan_info(&channel) ' ) )
2017-05-13 22:43:07 -07:00
end )
end )
2016-10-22 15:02:22 -07:00
describe ( ' nvim_call_atomic ' , function ( )
2016-04-13 07:37:09 -07:00
it ( ' works ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_buf_set_lines ( 0 , 0 , - 1 , true , { ' first ' } )
2016-04-13 07:37:09 -07:00
local req = {
2023-12-07 04:19:35 -07:00
{ ' nvim_get_current_line ' , { } } ,
{ ' nvim_set_current_line ' , { ' second ' } } ,
2016-04-13 07:37:09 -07:00
}
2024-01-12 10:59:57 -07:00
eq ( { { ' first ' , NIL } , NIL } , api.nvim_call_atomic ( req ) )
eq ( { ' second ' } , api.nvim_buf_get_lines ( 0 , 0 , - 1 , true ) )
2016-04-13 07:37:09 -07:00
end )
it ( ' allows multiple return values ' , function ( )
local req = {
2023-12-07 04:19:35 -07:00
{ ' nvim_set_var ' , { ' avar ' , true } } ,
{ ' nvim_set_var ' , { ' bvar ' , ' string ' } } ,
{ ' nvim_get_var ' , { ' avar ' } } ,
{ ' nvim_get_var ' , { ' bvar ' } } ,
2016-04-13 07:37:09 -07:00
}
2024-01-12 10:59:57 -07:00
eq ( { { NIL , NIL , true , ' string ' } , NIL } , api.nvim_call_atomic ( req ) )
2016-04-13 07:37:09 -07:00
end )
it ( ' is aborted by errors in call ' , function ( )
2024-01-12 10:59:57 -07:00
local error_types = api.nvim_get_api_info ( ) [ 2 ] . error_types
2016-04-13 07:37:09 -07:00
local req = {
2023-12-07 04:19:35 -07:00
{ ' nvim_set_var ' , { ' one ' , 1 } } ,
{ ' nvim_buf_set_lines ' , { } } ,
{ ' nvim_set_var ' , { ' two ' , 2 } } ,
2016-04-13 07:37:09 -07:00
}
2023-12-07 04:19:35 -07:00
eq ( {
{ NIL } ,
{
1 ,
error_types.Exception . id ,
' Wrong number of arguments: expecting 5 but got 0 ' ,
} ,
2024-01-12 10:59:57 -07:00
} , api.nvim_call_atomic ( req ) )
eq ( 1 , api.nvim_get_var ( ' one ' ) )
eq ( false , pcall ( api.nvim_get_var , ' two ' ) )
2016-04-13 07:37:09 -07:00
-- still returns all previous successful calls
req = {
2023-12-07 04:19:35 -07:00
{ ' nvim_set_var ' , { ' avar ' , 5 } } ,
{ ' nvim_set_var ' , { ' bvar ' , ' string ' } } ,
{ ' nvim_get_var ' , { ' avar ' } } ,
{ ' nvim_buf_get_lines ' , { 0 , 10 , 20 , true } } ,
{ ' nvim_get_var ' , { ' bvar ' } } ,
2016-04-13 07:37:09 -07:00
}
2023-12-07 04:19:35 -07:00
eq (
{ { NIL , NIL , 5 } , { 3 , error_types.Validation . id , ' Index out of bounds ' } } ,
2024-01-12 10:59:57 -07:00
api.nvim_call_atomic ( req )
2023-12-07 04:19:35 -07:00
)
2016-04-13 07:37:09 -07:00
req = {
2023-12-07 04:19:35 -07:00
{ ' i_am_not_a_method ' , { ' xx ' } } ,
{ ' nvim_set_var ' , { ' avar ' , 10 } } ,
2016-04-13 07:37:09 -07:00
}
2023-12-07 04:19:35 -07:00
eq (
{ { } , { 0 , error_types.Exception . id , ' Invalid method: i_am_not_a_method ' } } ,
2024-01-12 10:59:57 -07:00
api.nvim_call_atomic ( req )
2023-12-07 04:19:35 -07:00
)
2024-01-12 10:59:57 -07:00
eq ( 5 , api.nvim_get_var ( ' avar ' ) )
2016-04-13 07:37:09 -07:00
end )
2023-02-14 03:19:04 -07:00
it ( ' validation ' , function ( )
2016-04-13 07:37:09 -07:00
local req = {
2023-12-07 04:19:35 -07:00
{ ' nvim_set_var ' , { ' avar ' , 1 } } ,
{ ' nvim_set_var ' } ,
{ ' nvim_set_var ' , { ' avar ' , 2 } } ,
2016-04-13 07:37:09 -07:00
}
2024-01-12 10:59:57 -07:00
eq ( " Invalid 'calls' item: expected 2-item Array " , pcall_err ( api.nvim_call_atomic , req ) )
2016-04-13 07:37:09 -07:00
-- call before was done, but not after
2024-01-12 10:59:57 -07:00
eq ( 1 , api.nvim_get_var ( ' avar ' ) )
2016-04-13 07:37:09 -07:00
req = {
2017-02-22 15:12:26 -07:00
{ ' nvim_set_var ' , { ' bvar ' , { 2 , 3 } } } ,
2016-04-13 07:37:09 -07:00
12 ,
}
2024-01-12 10:59:57 -07:00
eq ( " Invalid 'calls' item: expected Array, got Integer " , pcall_err ( api.nvim_call_atomic , req ) )
eq ( { 2 , 3 } , api.nvim_get_var ( ' bvar ' ) )
2016-04-13 07:37:09 -07:00
req = {
2023-12-07 04:19:35 -07:00
{ ' nvim_set_current_line ' , ' little line ' } ,
{ ' nvim_set_var ' , { ' avar ' , 3 } } ,
2016-04-13 07:37:09 -07:00
}
2024-01-12 10:59:57 -07:00
eq ( ' Invalid call args: expected Array, got String ' , pcall_err ( api.nvim_call_atomic , req ) )
2016-04-13 07:37:09 -07:00
-- call before was done, but not after
2024-01-12 10:59:57 -07:00
eq ( 1 , api.nvim_get_var ( ' avar ' ) )
eq ( { ' ' } , api.nvim_buf_get_lines ( 0 , 0 , - 1 , true ) )
2016-04-13 07:37:09 -07:00
end )
end )
2018-02-16 01:40:40 -07:00
describe ( ' nvim_list_runtime_paths ' , function ( )
2021-10-02 01:37:30 -07:00
setup ( function ( )
2024-04-20 08:44:13 -07:00
local pathsep = n.get_pathsep ( )
2023-12-07 04:19:35 -07:00
mkdir_p ( ' Xtest ' .. pathsep .. ' a ' )
mkdir_p ( ' Xtest ' .. pathsep .. ' b ' )
2021-10-02 01:37:30 -07:00
end )
teardown ( function ( )
rmdir ' Xtest '
end )
before_each ( function ( )
2024-01-12 10:59:57 -07:00
api.nvim_set_current_dir ' Xtest '
2021-10-02 01:37:30 -07:00
end )
2017-05-22 14:16:23 -07:00
it ( ' returns nothing with empty &runtimepath ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' runtimepath ' , ' ' , { } )
eq ( { } , api.nvim_list_runtime_paths ( ) )
2017-05-22 14:16:23 -07:00
end )
it ( ' returns single runtimepath ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' runtimepath ' , ' a ' , { } )
eq ( { ' a ' } , api.nvim_list_runtime_paths ( ) )
2017-05-22 14:16:23 -07:00
end )
it ( ' returns two runtimepaths ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' runtimepath ' , ' a,b ' , { } )
eq ( { ' a ' , ' b ' } , api.nvim_list_runtime_paths ( ) )
2017-05-22 14:16:23 -07:00
end )
it ( ' returns empty strings when appropriate ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' runtimepath ' , ' a,,b ' , { } )
eq ( { ' a ' , ' ' , ' b ' } , api.nvim_list_runtime_paths ( ) )
api.nvim_set_option_value ( ' runtimepath ' , ' ,a,b ' , { } )
eq ( { ' ' , ' a ' , ' b ' } , api.nvim_list_runtime_paths ( ) )
2022-10-09 05:21:52 -07:00
-- Trailing "," is ignored. Use ",," if you really really want CWD.
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' runtimepath ' , ' a,b, ' , { } )
eq ( { ' a ' , ' b ' } , api.nvim_list_runtime_paths ( ) )
api.nvim_set_option_value ( ' runtimepath ' , ' a,b,, ' , { } )
eq ( { ' a ' , ' b ' , ' ' } , api.nvim_list_runtime_paths ( ) )
2017-05-22 14:16:23 -07:00
end )
it ( ' truncates too long paths ' , function ( )
local long_path = ( ' /a ' ) : rep ( 8192 )
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' runtimepath ' , long_path , { } )
local paths_list = api.nvim_list_runtime_paths ( )
2021-10-02 01:37:30 -07:00
eq ( { } , paths_list )
2017-05-22 14:16:23 -07:00
end )
end )
2014-10-23 17:14:50 -07:00
it ( ' can throw exceptions ' , function ( )
2024-01-12 10:59:57 -07:00
local status , err = pcall ( api.nvim_get_option_value , ' invalid-option ' , { } )
2014-10-23 17:14:50 -07:00
eq ( false , status )
2024-03-29 18:29:21 -07:00
matches ( " Unknown option 'invalid%-option' " , err )
2014-10-23 17:14:50 -07:00
end )
2016-07-16 07:51:56 -07:00
2017-04-21 05:58:52 -07:00
it ( ' does not truncate error message <1 MB #5984 ' , function ( )
2023-12-07 04:19:35 -07:00
local very_long_name = ' A ' .. ( ' x ' ) : rep ( 10000 ) .. ' Z '
2024-01-12 10:59:57 -07:00
local status , err = pcall ( api.nvim_get_option_value , very_long_name , { } )
2017-04-21 05:58:52 -07:00
eq ( false , status )
eq ( very_long_name , err : match ( ' Ax+Z? ' ) )
end )
2023-12-07 04:19:35 -07:00
it ( ' does not leak memory on incorrect argument types ' , function ( )
2024-01-12 10:59:57 -07:00
local status , err = pcall ( api.nvim_set_current_dir , { ' not ' , ' a ' , ' dir ' } )
2016-07-16 07:51:56 -07:00
eq ( false , status )
2024-03-29 18:29:21 -07:00
matches ( ' : Wrong type for argument 1 when calling nvim_set_current_dir, expecting String ' , err )
2016-07-16 07:51:56 -07:00
end )
2017-11-03 01:38:59 -07:00
describe ( ' nvim_parse_expression ' , function ( )
2017-11-26 06:08:53 -07:00
before_each ( function ( )
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' isident ' , ' ' , { } )
2017-11-26 06:08:53 -07:00
end )
2019-08-14 14:57:45 -07:00
2017-11-04 16:41:44 -07:00
local function simplify_east_api_node ( line , east_api_node )
2017-11-05 11:06:12 -07:00
if east_api_node == NIL then
return nil
end
2017-11-04 16:41:44 -07:00
if east_api_node.children then
for k , v in pairs ( east_api_node.children ) do
east_api_node.children [ k ] = simplify_east_api_node ( line , v )
end
end
local typ = east_api_node.type
if typ == ' Register ' then
2023-12-07 04:19:35 -07:00
typ = typ .. ( ' (name=%s) ' ) : format ( tostring ( intchar2lua ( east_api_node.name ) ) )
2017-11-04 16:41:44 -07:00
east_api_node.name = nil
elseif typ == ' PlainIdentifier ' then
2023-12-07 04:19:35 -07:00
typ = typ
.. ( ' (scope=%s,ident=%s) ' ) : format (
tostring ( intchar2lua ( east_api_node.scope ) ) ,
east_api_node.ident
)
2017-11-04 16:41:44 -07:00
east_api_node.scope = nil
east_api_node.ident = nil
elseif typ == ' PlainKey ' then
typ = typ .. ( ' (key=%s) ' ) : format ( east_api_node.ident )
east_api_node.ident = nil
elseif typ == ' Comparison ' then
2023-12-07 04:19:35 -07:00
typ = typ
.. ( ' (type=%s,inv=%u,ccs=%s) ' ) : format (
east_api_node.cmp_type ,
east_api_node.invert and 1 or 0 ,
east_api_node.ccs_strategy
)
2017-11-04 16:41:44 -07:00
east_api_node.ccs_strategy = nil
east_api_node.cmp_type = nil
east_api_node.invert = nil
elseif typ == ' Integer ' then
typ = typ .. ( ' (val=%u) ' ) : format ( east_api_node.ivalue )
east_api_node.ivalue = nil
elseif typ == ' Float ' then
2017-11-19 11:40:34 -07:00
typ = typ .. format_string ( ' (val=%e) ' , east_api_node.fvalue )
2017-11-04 16:41:44 -07:00
east_api_node.fvalue = nil
elseif typ == ' SingleQuotedString ' or typ == ' DoubleQuotedString ' then
typ = format_string ( ' %s(val=%q) ' , typ , east_api_node.svalue )
east_api_node.svalue = nil
elseif typ == ' Option ' then
typ = ( ' %s(scope=%s,ident=%s) ' ) : format (
typ ,
tostring ( intchar2lua ( east_api_node.scope ) ) ,
2023-12-07 04:19:35 -07:00
east_api_node.ident
)
2017-11-04 16:41:44 -07:00
east_api_node.ident = nil
east_api_node.scope = nil
elseif typ == ' Environment ' then
typ = ( ' %s(ident=%s) ' ) : format ( typ , east_api_node.ident )
east_api_node.ident = nil
2017-11-19 10:20:06 -07:00
elseif typ == ' Assignment ' then
local aug = east_api_node.augmentation
2023-12-07 04:19:35 -07:00
if aug == ' ' then
aug = ' Plain '
end
2017-11-19 10:20:06 -07:00
typ = ( ' %s(%s) ' ) : format ( typ , aug )
east_api_node.augmentation = nil
2017-11-04 16:41:44 -07:00
end
typ = ( ' %s:%u:%u:%s ' ) : format (
2023-12-07 04:19:35 -07:00
typ ,
east_api_node.start [ 1 ] ,
east_api_node.start [ 2 ] ,
line : sub ( east_api_node.start [ 2 ] + 1 , east_api_node.start [ 2 ] + 1 + east_api_node.len - 1 )
)
2017-11-04 16:41:44 -07:00
assert ( east_api_node.start [ 2 ] + east_api_node.len - 1 <= # line )
for k , _ in pairs ( east_api_node.start ) do
2023-12-07 04:19:35 -07:00
assert ( ( { true , true } ) [ k ] )
2017-11-04 16:41:44 -07:00
end
east_api_node.start = nil
east_api_node.type = nil
east_api_node.len = nil
local can_simplify = true
for _ , _ in pairs ( east_api_node ) do
2023-12-07 04:19:35 -07:00
if can_simplify then
can_simplify = false
end
2017-11-04 16:41:44 -07:00
end
if can_simplify then
return typ
else
east_api_node [ 1 ] = typ
return east_api_node
end
end
local function simplify_east_api ( line , east_api )
if east_api.error then
east_api.err = east_api.error
east_api.error = nil
east_api.err . msg = east_api.err . message
east_api.err . message = nil
end
if east_api.ast then
2023-12-07 04:19:35 -07:00
east_api.ast = { simplify_east_api_node ( line , east_api.ast ) }
2017-11-19 10:20:06 -07:00
if # east_api.ast == 0 then
east_api.ast = nil
end
2017-11-04 16:41:44 -07:00
end
2017-11-05 15:15:18 -07:00
if east_api.len == # line then
east_api.len = nil
end
2017-11-04 16:41:44 -07:00
return east_api
end
local function simplify_east_hl ( line , east_hl )
for i , v in ipairs ( east_hl ) do
2023-12-07 04:19:35 -07:00
east_hl [ i ] = ( ' %s:%u:%u:%s ' ) : format ( v [ 4 ] , v [ 1 ] , v [ 2 ] , line : sub ( v [ 2 ] + 1 , v [ 3 ] ) )
2017-11-04 16:41:44 -07:00
end
return east_hl
end
2017-11-05 11:06:12 -07:00
local FLAGS_TO_STR = {
2023-12-07 04:19:35 -07:00
[ 0 ] = ' ' ,
[ 1 ] = ' m ' ,
[ 2 ] = ' E ' ,
[ 3 ] = ' mE ' ,
[ 4 ] = ' l ' ,
[ 5 ] = ' lm ' ,
[ 6 ] = ' lE ' ,
[ 7 ] = ' lmE ' ,
2017-11-05 11:06:12 -07:00
}
2023-12-07 04:19:35 -07:00
local function _check_parsing ( opts , str , exp_ast , exp_highlighting_fs , nz_flags_exps )
2017-11-19 10:20:06 -07:00
if type ( str ) ~= ' string ' then
return
end
local zflags = opts.flags [ 1 ]
2017-11-05 11:06:12 -07:00
nz_flags_exps = nz_flags_exps or { }
2017-11-19 10:20:06 -07:00
for _ , flags in ipairs ( opts.flags ) do
2017-11-05 11:06:12 -07:00
local err , msg = pcall ( function ( )
2024-01-12 10:59:57 -07:00
local east_api = api.nvim_parse_expression ( str , FLAGS_TO_STR [ flags ] , true )
2017-11-05 11:06:12 -07:00
local east_hl = east_api.highlight
east_api.highlight = nil
local ast = simplify_east_api ( str , east_api )
local hls = simplify_east_hl ( str , east_hl )
local exps = {
ast = exp_ast ,
hl_fs = exp_highlighting_fs ,
}
local add_exps = nz_flags_exps [ flags ]
2017-11-19 10:20:06 -07:00
if not add_exps and flags == 3 + zflags then
add_exps = nz_flags_exps [ 1 + zflags ] or nz_flags_exps [ 2 + zflags ]
2017-11-04 16:41:44 -07:00
end
2017-11-05 11:06:12 -07:00
if add_exps then
if add_exps.ast then
exps.ast = mergedicts_copy ( exps.ast , add_exps.ast )
end
if add_exps.hl_fs then
exps.hl_fs = mergedicts_copy ( exps.hl_fs , add_exps.hl_fs )
end
end
eq ( exps.ast , ast )
if exp_highlighting_fs then
local exp_highlighting = { }
local next_col = 0
for i , h in ipairs ( exps.hl_fs ) do
exp_highlighting [ i ] , next_col = h ( next_col )
end
eq ( exp_highlighting , hls )
end
end )
if not err then
2018-02-01 14:55:22 -07:00
if type ( msg ) == ' table ' then
2023-12-07 04:19:35 -07:00
local merr , new_msg = pcall ( format_string , ' table error: \n %s \n \n (%r) ' , msg.message , msg )
2018-02-01 14:55:22 -07:00
if merr then
msg = new_msg
else
2023-12-07 04:19:35 -07:00
msg = format_string ( ' table error without .message: \n (%r) ' , msg )
2018-02-01 14:55:22 -07:00
end
elseif type ( msg ) ~= ' string ' then
msg = format_string ( ' non-string non-table error: \n %r ' , msg )
end
2023-12-07 04:19:35 -07:00
error (
format_string (
' Error while processing test (%r, %s): \n %s ' ,
str ,
FLAGS_TO_STR [ flags ] ,
msg
)
)
2017-11-04 16:41:44 -07:00
end
end
end
local function hl ( group , str , shift )
return function ( next_col )
local col = next_col + ( shift or 0 )
2023-12-07 04:19:35 -07:00
return ( ( ' %s:%u:%u:%s ' ) : format ( ' Nvim ' .. group , 0 , col , str ) ) , ( col + # str )
2017-11-04 16:41:44 -07:00
end
end
2017-11-19 10:20:06 -07:00
local function fmtn ( typ , args , rest )
2023-12-07 04:19:35 -07:00
if
typ == ' UnknownFigure '
or typ == ' DictLiteral '
or typ == ' CurlyBracesIdentifier '
or typ == ' Lambda '
then
2017-11-19 10:20:06 -07:00
return ( ' %s%s ' ) : format ( typ , rest )
elseif typ == ' DoubleQuotedString ' or typ == ' SingleQuotedString ' then
if args : sub ( - 4 ) == ' NULL ' then
args = args : sub ( 1 , - 5 ) .. ' "" '
end
return ( ' %s(%s)%s ' ) : format ( typ , args , rest )
end
end
2024-07-10 14:42:37 -07:00
it ( ' does not crash parsing invalid VimL expression #29648 ' , function ( )
api.nvim_input ( ' :<C-r>= ' )
api.nvim_input ( ' 1bork/ ' )
assert_alive ( )
end )
2023-12-07 04:19:35 -07:00
require ( ' test.unit.viml.expressions.parser_tests ' ) ( it , _check_parsing , hl , fmtn )
2017-11-03 01:38:59 -07:00
end )
2018-02-16 01:40:40 -07:00
describe ( ' nvim_list_uis ' , function ( )
it ( ' returns empty if --headless ' , function ( )
2018-11-15 18:00:04 -07:00
-- Test runner defaults to --headless.
2024-01-12 10:59:57 -07:00
eq ( { } , api.nvim_list_uis ( ) )
2018-02-16 01:40:40 -07:00
end )
it ( ' returns attached UIs ' , function ( )
local screen = Screen.new ( 20 , 4 )
2023-12-07 04:19:35 -07:00
screen : attach ( { override = true } )
2018-02-16 01:40:40 -07:00
local expected = {
{
2018-05-31 01:58:31 -07:00
chan = 1 ,
2018-02-16 01:40:40 -07:00
ext_cmdline = false ,
2023-02-23 10:29:36 -07:00
ext_hlstate = false ,
2018-09-28 05:19:37 -07:00
ext_linegrid = screen._options . ext_linegrid or false ,
2023-02-23 10:29:36 -07:00
ext_messages = false ,
2017-12-09 03:26:06 -07:00
ext_multigrid = false ,
2023-02-23 10:29:36 -07:00
ext_popupmenu = false ,
ext_tabline = false ,
2017-10-31 08:46:02 -07:00
ext_termcolors = false ,
2023-02-23 10:29:36 -07:00
ext_wildmenu = false ,
2018-02-16 01:40:40 -07:00
height = 4 ,
UI/nvim_ui_attach(): add `override` option
Before now, Nvim always degrades UI capabilities to the lowest-common
denominator. For example, if any connected UI has `ext_messages=false`
then `ext_messages=true` requested by any other connected UI is ignored.
Now `nvim_ui_attach()` supports `override=true`, which flips the
behavior: if any UI requests an `ext_*` UI capability then the
capability is enabled (and the legacy behavior is disabled).
Legacy UIs will be broken while a `override=true` UI is connected, but
it's useful for debugging: you can type into the TUI and observe the UI
events from another connected (UI) client. And the legacy UI will
"recover" after the `override=true` UI disconnects.
Example using pynvim:
>>> n.ui_attach(2048, 2048, rgb=True, override=True, ext_multigrid=True, ext_messages=True, ext_popupmenu=True)
>>> while True: n.next_message();
2019-05-09 10:35:38 -07:00
override = true ,
2023-02-23 10:29:36 -07:00
rgb = true ,
stdin_tty = false ,
stdout_tty = false ,
term_background = ' ' ,
term_colors = 0 ,
term_name = ' ' ,
2018-02-16 01:40:40 -07:00
width = 20 ,
2023-12-07 04:19:35 -07:00
} ,
2018-02-16 01:40:40 -07:00
}
2023-02-23 10:29:36 -07:00
2024-01-12 10:59:57 -07:00
eq ( expected , api.nvim_list_uis ( ) )
2018-02-16 01:40:40 -07:00
screen : detach ( )
screen = Screen.new ( 44 , 99 )
screen : attach ( { rgb = false } )
2018-07-06 05:39:50 -07:00
expected [ 1 ] . rgb = false
UI/nvim_ui_attach(): add `override` option
Before now, Nvim always degrades UI capabilities to the lowest-common
denominator. For example, if any connected UI has `ext_messages=false`
then `ext_messages=true` requested by any other connected UI is ignored.
Now `nvim_ui_attach()` supports `override=true`, which flips the
behavior: if any UI requests an `ext_*` UI capability then the
capability is enabled (and the legacy behavior is disabled).
Legacy UIs will be broken while a `override=true` UI is connected, but
it's useful for debugging: you can type into the TUI and observe the UI
events from another connected (UI) client. And the legacy UI will
"recover" after the `override=true` UI disconnects.
Example using pynvim:
>>> n.ui_attach(2048, 2048, rgb=True, override=True, ext_multigrid=True, ext_messages=True, ext_popupmenu=True)
>>> while True: n.next_message();
2019-05-09 10:35:38 -07:00
expected [ 1 ] . override = false
2018-07-06 05:39:50 -07:00
expected [ 1 ] . width = 44
expected [ 1 ] . height = 99
2024-01-12 10:59:57 -07:00
eq ( expected , api.nvim_list_uis ( ) )
2018-02-16 01:40:40 -07:00
end )
end )
2017-06-23 00:56:35 -07:00
describe ( ' nvim_create_namespace ' , function ( )
it ( ' works ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( { } , api.nvim_get_namespaces ( ) )
eq ( 1 , api.nvim_create_namespace ( ' ns-1 ' ) )
eq ( 2 , api.nvim_create_namespace ( ' ns-2 ' ) )
eq ( 1 , api.nvim_create_namespace ( ' ns-1 ' ) )
eq ( { [ ' ns-1 ' ] = 1 , [ ' ns-2 ' ] = 2 } , api.nvim_get_namespaces ( ) )
eq ( 3 , api.nvim_create_namespace ( ' ' ) )
eq ( 4 , api.nvim_create_namespace ( ' ' ) )
eq ( { [ ' ns-1 ' ] = 1 , [ ' ns-2 ' ] = 2 } , api.nvim_get_namespaces ( ) )
2017-06-23 00:56:35 -07:00
end )
end )
2017-09-02 05:21:06 -07:00
describe ( ' nvim_create_buf ' , function ( )
it ( ' works ' , function ( )
2024-01-16 06:26:21 -07:00
eq ( 2 , api.nvim_create_buf ( true , false ) )
eq ( 3 , api.nvim_create_buf ( false , false ) )
2023-12-07 04:19:35 -07:00
eq (
' 1 %a "[No Name]" line 1 \n '
.. ' 2 h "[No Name]" line 0 ' ,
2024-01-12 06:11:28 -07:00
command_output ( ' ls ' )
2023-12-07 04:19:35 -07:00
)
2017-09-02 05:21:06 -07:00
-- current buffer didn't change
2024-01-16 06:26:21 -07:00
eq ( 1 , api.nvim_get_current_buf ( ) )
2017-09-02 05:21:06 -07:00
local screen = Screen.new ( 20 , 4 )
screen : attach ( )
2024-01-12 10:59:57 -07:00
api.nvim_buf_set_lines ( 2 , 0 , - 1 , true , { ' some text ' } )
api.nvim_set_current_buf ( 2 )
2023-12-07 04:19:35 -07:00
screen : expect (
[ [
2017-09-02 05:21:06 -07:00
^ some text |
2023-12-09 05:42:00 -07:00
{ 1 : ~ } |* 2
2017-09-02 05:21:06 -07:00
|
2023-12-07 04:19:35 -07:00
] ] ,
{
[ 1 ] = { bold = true , foreground = Screen.colors . Blue1 } ,
}
)
2017-09-02 05:21:06 -07:00
end )
it ( ' can change buftype before visiting ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' hidden ' , false , { } )
2024-01-16 06:26:21 -07:00
eq ( 2 , api.nvim_create_buf ( true , false ) )
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' buftype ' , ' nofile ' , { buf = 2 } )
api.nvim_buf_set_lines ( 2 , 0 , - 1 , true , { ' test text ' } )
2023-12-07 04:19:35 -07:00
command ( ' split | buffer 2 ' )
2024-01-16 06:26:21 -07:00
eq ( 2 , api.nvim_get_current_buf ( ) )
2017-09-02 05:21:06 -07:00
-- if the buf_set_option("buftype") didn't work, this would error out.
2023-12-07 04:19:35 -07:00
command ( ' close ' )
2024-01-16 06:26:21 -07:00
eq ( 1 , api.nvim_get_current_buf ( ) )
2017-09-02 05:21:06 -07:00
end )
2019-02-09 08:38:36 -07:00
2023-12-07 04:19:35 -07:00
it ( ' does not trigger BufEnter, BufWinEnter ' , function ( )
command ( ' let g:fired = v:false ' )
command ( ' au BufEnter,BufWinEnter * let g:fired = v:true ' )
2019-06-03 04:08:05 -07:00
2024-01-16 06:26:21 -07:00
eq ( 2 , api.nvim_create_buf ( true , false ) )
2024-01-12 10:59:57 -07:00
api.nvim_buf_set_lines ( 2 , 0 , - 1 , true , { ' test ' , ' text ' } )
2019-06-03 04:08:05 -07:00
eq ( false , eval ( ' g:fired ' ) )
end )
2023-10-03 05:54:42 -07:00
it ( ' TextChanged and TextChangedI do not trigger without changes ' , function ( )
2024-01-12 10:59:57 -07:00
local buf = api.nvim_create_buf ( true , false )
2023-10-03 05:54:42 -07:00
command ( [[let g:changed = '']] )
2024-01-12 10:59:57 -07:00
api.nvim_create_autocmd ( { ' TextChanged ' , ' TextChangedI ' } , {
2023-10-03 05:54:42 -07:00
buffer = buf ,
command = ' let g:changed ..= mode() ' ,
} )
2024-01-12 10:59:57 -07:00
api.nvim_set_current_buf ( buf )
2023-10-03 05:54:42 -07:00
feed ( ' i ' )
2024-01-12 10:59:57 -07:00
eq ( ' ' , api.nvim_get_var ( ' changed ' ) )
2023-10-03 05:54:42 -07:00
end )
2020-05-29 09:45:32 -07:00
it ( ' scratch-buffer ' , function ( )
2024-01-16 06:26:21 -07:00
eq ( 2 , api.nvim_create_buf ( false , true ) )
eq ( 3 , api.nvim_create_buf ( true , true ) )
eq ( 4 , api.nvim_create_buf ( true , true ) )
2019-02-09 08:38:36 -07:00
local scratch_bufs = { 2 , 3 , 4 }
2023-12-07 04:19:35 -07:00
eq (
' 1 %a "[No Name]" line 1 \n '
.. ' 3 h "[Scratch]" line 0 \n '
.. ' 4 h "[Scratch]" line 0 ' ,
exec_capture ( ' ls ' )
)
2019-02-09 08:38:36 -07:00
-- current buffer didn't change
2024-01-16 06:26:21 -07:00
eq ( 1 , api.nvim_get_current_buf ( ) )
2019-02-09 08:38:36 -07:00
local screen = Screen.new ( 20 , 4 )
screen : attach ( )
--
-- Editing a scratch-buffer does NOT change its properties.
--
local edited_buf = 2
2024-01-12 10:59:57 -07:00
api.nvim_buf_set_lines ( edited_buf , 0 , - 1 , true , { ' some text ' } )
2023-12-07 04:19:35 -07:00
for _ , b in ipairs ( scratch_bufs ) do
2024-01-12 10:59:57 -07:00
eq ( ' nofile ' , api.nvim_get_option_value ( ' buftype ' , { buf = b } ) )
eq ( ' hide ' , api.nvim_get_option_value ( ' bufhidden ' , { buf = b } ) )
eq ( false , api.nvim_get_option_value ( ' swapfile ' , { buf = b } ) )
eq ( false , api.nvim_get_option_value ( ' modeline ' , { buf = b } ) )
2019-02-09 08:38:36 -07:00
end
--
2019-03-04 09:53:41 -07:00
-- Visiting a scratch-buffer DOES NOT change its properties.
2019-02-09 08:38:36 -07:00
--
2024-01-12 10:59:57 -07:00
api.nvim_set_current_buf ( edited_buf )
2019-02-09 08:38:36 -07:00
screen : expect ( [ [
^ some text |
2023-12-09 05:42:00 -07:00
{ 1 : ~ } |* 2
2019-02-09 08:38:36 -07:00
|
2019-03-04 09:53:41 -07:00
] ] )
2024-01-12 10:59:57 -07:00
eq ( ' nofile ' , api.nvim_get_option_value ( ' buftype ' , { buf = edited_buf } ) )
eq ( ' hide ' , api.nvim_get_option_value ( ' bufhidden ' , { buf = edited_buf } ) )
eq ( false , api.nvim_get_option_value ( ' swapfile ' , { buf = edited_buf } ) )
eq ( false , api.nvim_get_option_value ( ' modeline ' , { buf = edited_buf } ) )
2019-03-04 09:53:41 -07:00
2020-05-29 09:45:32 -07:00
-- Scratch buffer can be wiped without error.
2019-03-04 09:53:41 -07:00
command ( ' bwipe ' )
screen : expect ( [ [
^ |
2023-12-09 05:42:00 -07:00
{ 1 : ~ } |* 2
2019-03-04 09:53:41 -07:00
|
] ] )
2019-02-09 08:38:36 -07:00
end )
2019-08-25 00:11:22 -07:00
it ( ' does not cause heap-use-after-free on exit while setting options ' , function ( )
command ( ' au OptionSet * q ' )
refactor(change): do API changes to buffer without curbuf switch
Most of the messy things when changing a non-current buffer is
not about the buffer, it is about windows. In particular, it is about
`curwin`.
When editing a non-current buffer which is displayed in some other
window in the current tabpage, one such window will be "borrowed" as the
curwin. But this means if two or more non-current windows displayed the buffers,
one of them will be treated differenty. this is not desirable.
In particular, with nvim_buf_set_text, cursor _column_ position was only
corrected for one single window. Two new tests are added: the test
with just one non-current window passes, but the one with two didn't.
Two corresponding such tests were also added for nvim_buf_set_lines.
This already worked correctly on master, but make sure this is
well-tested for future refactors.
Also, nvim_create_buf no longer invokes autocmds just because you happened
to use `scratch=true`. No option value was changed, therefore OptionSet
must not be fired.
2023-08-21 05:52:17 -07:00
command ( ' silent! call nvim_create_buf(0, 1) ' )
-- nowadays this works because we don't execute any spurious autocmds at all #24824
assert_alive ( )
2019-08-25 00:11:22 -07:00
end )
2024-03-19 03:55:33 -07:00
it ( ' no memory leak when autocommands load the buffer immediately ' , function ( )
exec ( [ [
autocmd BufNew * ++ once call bufload ( expand ( " <abuf> " ) -> str2nr ( ) )
\ | let loaded = bufloaded ( expand ( " <abuf> " ) -> str2nr ( ) )
] ] )
api.nvim_create_buf ( false , true )
eq ( 1 , eval ( ' g:loaded ' ) )
end )
2024-03-19 05:59:44 -07:00
it ( ' creating scratch buffer where autocommands set &swapfile works ' , function ( )
exec ( [ [
autocmd BufNew * ++ once execute expand ( " <abuf> " ) " buffer "
\ | file foobar
\ | setlocal swapfile
] ] )
local new_buf = api.nvim_create_buf ( false , true )
neq ( ' ' , fn.swapname ( new_buf ) )
end )
it ( ' fires expected autocommands ' , function ( )
exec ( [ = [
" Append the &buftype to check autocommands trigger *after* the buffer was configured to be
" scratch, if applicable.
autocmd BufNew * let fired += [ [ " BufNew " , expand ( " <abuf> " ) -> str2nr ( ) ,
\ getbufvar ( expand ( " <abuf> " ) -> str2nr ( ) , " &buftype " ) ] ]
autocmd BufAdd * let fired += [ [ " BufAdd " , expand ( " <abuf> " ) -> str2nr ( ) ,
\ getbufvar ( expand ( " <abuf> " ) -> str2nr ( ) , " &buftype " ) ] ]
" Don't want to see OptionSet; buffer options set from passing true for " scratch " , etc.
" should be configured invisibly, and before autocommands.
autocmd OptionSet * let fired += [["OptionSet", expand("<amatch>")]]
let fired = [ ]
] = ] )
local new_buf = api.nvim_create_buf ( false , false )
eq ( { { ' BufNew ' , new_buf , ' ' } } , eval ( ' g:fired ' ) )
command ( ' let fired = [] ' )
new_buf = api.nvim_create_buf ( false , true )
eq ( { { ' BufNew ' , new_buf , ' nofile ' } } , eval ( ' g:fired ' ) )
command ( ' let fired = [] ' )
new_buf = api.nvim_create_buf ( true , false )
eq ( { { ' BufNew ' , new_buf , ' ' } , { ' BufAdd ' , new_buf , ' ' } } , eval ( ' g:fired ' ) )
command ( ' let fired = [] ' )
new_buf = api.nvim_create_buf ( true , true )
eq ( { { ' BufNew ' , new_buf , ' nofile ' } , { ' BufAdd ' , new_buf , ' nofile ' } } , eval ( ' g:fired ' ) )
end )
2017-09-02 05:21:06 -07:00
end )
2020-01-25 05:29:52 -07:00
describe ( ' nvim_get_runtime_file ' , function ( )
2024-09-08 12:29:20 -07:00
local p = t.fix_slashes
2020-11-24 06:18:46 -07:00
it ( ' can find files ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( { } , api.nvim_get_runtime_file ( ' bork.borkbork ' , false ) )
eq ( { } , api.nvim_get_runtime_file ( ' bork.borkbork ' , true ) )
eq ( 1 , # api.nvim_get_runtime_file ( ' autoload/msgpack.vim ' , false ) )
eq ( 1 , # api.nvim_get_runtime_file ( ' autoload/msgpack.vim ' , true ) )
local val = api.nvim_get_runtime_file ( ' autoload/remote/*.vim ' , true )
2020-01-25 05:29:52 -07:00
eq ( 2 , # val )
2023-12-07 04:19:35 -07:00
if endswith ( val [ 1 ] , ' define.vim ' ) then
2024-09-08 12:29:20 -07:00
ok ( endswith ( p ( val [ 1 ] ) , ' autoload/remote/define.vim ' ) )
ok ( endswith ( p ( val [ 2 ] ) , ' autoload/remote/host.vim ' ) )
2020-01-25 05:29:52 -07:00
else
2024-09-08 12:29:20 -07:00
ok ( endswith ( p ( val [ 1 ] ) , ' autoload/remote/host.vim ' ) )
ok ( endswith ( p ( val [ 2 ] ) , ' autoload/remote/define.vim ' ) )
2020-01-25 05:29:52 -07:00
end
2024-01-12 10:59:57 -07:00
val = api.nvim_get_runtime_file ( ' autoload/remote/*.vim ' , false )
2020-01-25 05:29:52 -07:00
eq ( 1 , # val )
2023-12-07 04:19:35 -07:00
ok (
2024-09-08 12:29:20 -07:00
endswith ( p ( val [ 1 ] ) , ' autoload/remote/define.vim ' )
or endswith ( p ( val [ 1 ] ) , ' autoload/remote/host.vim ' )
2023-12-07 04:19:35 -07:00
)
2020-11-24 06:18:46 -07:00
2024-01-12 10:59:57 -07:00
val = api.nvim_get_runtime_file ( ' lua ' , true )
2021-09-11 07:20:59 -07:00
eq ( 1 , # val )
2024-09-08 12:29:20 -07:00
ok ( endswith ( p ( val [ 1 ] ) , ' lua ' ) )
2021-09-11 07:20:59 -07:00
2024-01-12 10:59:57 -07:00
val = api.nvim_get_runtime_file ( ' lua/vim ' , true )
2021-09-11 07:20:59 -07:00
eq ( 1 , # val )
2024-09-08 12:29:20 -07:00
ok ( endswith ( p ( val [ 1 ] ) , ' lua/vim ' ) )
2020-11-24 06:18:46 -07:00
end )
it ( ' can find directories ' , function ( )
2024-01-12 10:59:57 -07:00
local val = api.nvim_get_runtime_file ( ' lua/ ' , true )
2020-11-24 06:18:46 -07:00
eq ( 1 , # val )
2024-09-08 12:29:20 -07:00
ok ( endswith ( p ( val [ 1 ] ) , ' lua/ ' ) )
2020-11-24 06:18:46 -07:00
2024-01-12 10:59:57 -07:00
val = api.nvim_get_runtime_file ( ' lua/vim/ ' , true )
2020-11-24 06:18:46 -07:00
eq ( 1 , # val )
2024-09-08 12:29:20 -07:00
ok ( endswith ( p ( val [ 1 ] ) , ' lua/vim/ ' ) )
2020-11-24 06:18:46 -07:00
2024-01-12 10:59:57 -07:00
eq ( { } , api.nvim_get_runtime_file ( ' foobarlang/ ' , true ) )
2020-01-25 05:29:52 -07:00
end )
2021-12-16 04:40:23 -07:00
it ( ' can handle bad patterns ' , function ( )
2022-11-21 17:13:30 -07:00
skip ( is_os ( ' win ' ) )
2021-12-16 04:40:23 -07:00
2024-01-12 10:59:57 -07:00
eq ( ' Vim:E220: Missing }. ' , pcall_err ( api.nvim_get_runtime_file , ' { ' , false ) )
2021-12-16 04:40:23 -07:00
2023-12-07 04:19:35 -07:00
eq (
' Vim(echo):E5555: API call: Vim:E220: Missing }. ' ,
exc_exec ( " echo nvim_get_runtime_file('{', v:false) " )
)
2021-12-16 04:40:23 -07:00
end )
2024-09-22 03:51:22 -07:00
it ( ' preserves order of runtimepath ' , function ( )
local vimruntime = fn.getenv ( ' VIMRUNTIME ' )
local rtp = string.format ( ' %s/syntax,%s/ftplugin ' , vimruntime , vimruntime )
api.nvim_set_option_value ( ' runtimepath ' , rtp , { } )
local val = api.nvim_get_runtime_file ( ' vim.vim ' , true )
eq ( 2 , # val )
eq ( p ( val [ 1 ] ) , vimruntime .. ' /syntax/vim.vim ' )
eq ( p ( val [ 2 ] ) , vimruntime .. ' /ftplugin/vim.vim ' )
end )
2020-01-25 05:29:52 -07:00
end )
2020-12-03 18:59:36 -07:00
2020-12-04 02:59:58 -07:00
describe ( ' nvim_get_all_options_info ' , function ( )
2020-12-03 18:59:36 -07:00
it ( ' should have key value pairs of option names ' , function ( )
2024-01-12 10:59:57 -07:00
local options_info = api.nvim_get_all_options_info ( )
2020-12-03 18:59:36 -07:00
neq ( nil , options_info.listchars )
neq ( nil , options_info.tabstop )
2020-12-04 02:59:58 -07:00
2024-01-12 10:59:57 -07:00
eq ( api.nvim_get_option_info ' winhighlight ' , options_info.winhighlight )
2020-12-03 18:59:36 -07:00
end )
2021-05-24 22:06:50 -07:00
it ( ' should not crash when echoed ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_exec2 ( ' echo nvim_get_all_options_info() ' , { output = true } )
2021-05-24 22:06:50 -07:00
end )
2020-12-03 18:59:36 -07:00
end )
describe ( ' nvim_get_option_info ' , function ( )
it ( ' should error for unknown options ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( " Invalid option (not found): 'bogus' " , pcall_err ( api.nvim_get_option_info , ' bogus ' ) )
2020-12-03 18:59:36 -07:00
end )
it ( ' should return the same options for short and long name ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( api.nvim_get_option_info ' winhl ' , api.nvim_get_option_info ' winhighlight ' )
2020-12-03 18:59:36 -07:00
end )
it ( ' should have information about window options ' , function ( )
2020-12-04 02:59:58 -07:00
eq ( {
2022-09-07 08:59:27 -07:00
allows_duplicates = false ,
2023-12-07 04:19:35 -07:00
commalist = true ,
default = ' ' ,
flaglist = false ,
global_local = false ,
last_set_chan = 0 ,
last_set_linenr = 0 ,
last_set_sid = 0 ,
name = ' winhighlight ' ,
scope = ' win ' ,
shortname = ' winhl ' ,
type = ' string ' ,
was_set = false ,
2024-01-12 10:59:57 -07:00
} , api.nvim_get_option_info ' winhl ' )
2020-12-03 18:59:36 -07:00
end )
it ( ' should have information about buffer options ' , function ( )
2020-12-04 02:59:58 -07:00
eq ( {
2021-06-11 10:39:59 -07:00
allows_duplicates = true ,
2020-12-04 02:59:58 -07:00
commalist = false ,
2023-12-07 04:19:35 -07:00
default = ' ' ,
2020-12-04 02:59:58 -07:00
flaglist = false ,
global_local = false ,
last_set_chan = 0 ,
last_set_linenr = 0 ,
last_set_sid = 0 ,
2023-12-07 04:19:35 -07:00
name = ' filetype ' ,
scope = ' buf ' ,
shortname = ' ft ' ,
type = ' string ' ,
was_set = false ,
2024-01-12 10:59:57 -07:00
} , api.nvim_get_option_info ' filetype ' )
2020-12-03 18:59:36 -07:00
end )
it ( ' should have information about global options ' , function ( )
2020-12-04 02:59:58 -07:00
-- precondition: the option was changed from its default
-- in test setup.
2024-01-12 10:59:57 -07:00
eq ( false , api.nvim_get_option_value ( ' showcmd ' , { } ) )
2020-12-04 02:59:58 -07:00
eq ( {
2021-06-11 10:39:59 -07:00
allows_duplicates = true ,
2020-12-04 02:59:58 -07:00
commalist = false ,
default = true ,
flaglist = false ,
global_local = false ,
last_set_chan = 0 ,
last_set_linenr = 0 ,
last_set_sid = - 2 ,
2023-12-07 04:19:35 -07:00
name = ' showcmd ' ,
scope = ' global ' ,
shortname = ' sc ' ,
type = ' boolean ' ,
was_set = true ,
2024-01-12 10:59:57 -07:00
} , api.nvim_get_option_info ' showcmd ' )
2023-03-11 06:09:11 -07:00
2024-01-12 10:59:57 -07:00
api.nvim_set_option_value ( ' showcmd ' , true , { } )
2023-03-11 06:09:11 -07:00
eq ( {
allows_duplicates = true ,
commalist = false ,
default = true ,
flaglist = false ,
global_local = false ,
last_set_chan = 1 ,
last_set_linenr = 0 ,
last_set_sid = - 9 ,
2023-12-07 04:19:35 -07:00
name = ' showcmd ' ,
scope = ' global ' ,
shortname = ' sc ' ,
type = ' boolean ' ,
was_set = true ,
2024-01-12 10:59:57 -07:00
} , api.nvim_get_option_info ' showcmd ' )
2020-12-03 18:59:36 -07:00
end )
end )
2021-01-10 23:18:51 -07:00
2023-03-29 00:59:01 -07:00
describe ( ' nvim_get_option_info2 ' , function ( )
local fname
local bufs
local wins
before_each ( function ( )
fname = tmpname ( )
2023-12-07 04:19:35 -07:00
write_file (
fname ,
[ [
2023-03-29 00:59:01 -07:00
setglobal dictionary = mydict " 1, global-local (buffer)
setlocal formatprg = myprg " 2, global-local (buffer)
setglobal equalprg = prg1 " 3, global-local (buffer)
setlocal equalprg = prg2 " 4, global-local (buffer)
setglobal fillchars = stl : x " 5, global-local (window)
setlocal listchars = eol : c " 6, global-local (window)
setglobal showbreak = aaa " 7, global-local (window)
setlocal showbreak = bbb " 8, global-local (window)
setglobal completeopt = menu " 9, global
2023-12-07 04:19:35 -07:00
] ]
)
2023-03-29 00:59:01 -07:00
exec_lua ' vim.cmd.vsplit() '
2024-01-12 10:59:57 -07:00
api.nvim_create_buf ( false , false )
2023-03-29 00:59:01 -07:00
2024-01-12 10:59:57 -07:00
bufs = api.nvim_list_bufs ( )
wins = api.nvim_list_wins ( )
2023-03-29 00:59:01 -07:00
2024-01-16 06:26:21 -07:00
api.nvim_win_set_buf ( wins [ 1 ] , bufs [ 1 ] )
api.nvim_win_set_buf ( wins [ 2 ] , bufs [ 2 ] )
2023-03-29 00:59:01 -07:00
2024-01-16 06:26:21 -07:00
api.nvim_set_current_win ( wins [ 2 ] )
2024-01-12 10:59:57 -07:00
api.nvim_exec ( ' source ' .. fname , false )
2023-03-29 00:59:01 -07:00
2024-01-16 06:26:21 -07:00
api.nvim_set_current_win ( wins [ 1 ] )
2023-03-29 00:59:01 -07:00
end )
after_each ( function ( )
os.remove ( fname )
end )
it ( ' should return option information ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( api.nvim_get_option_info ( ' dictionary ' ) , api.nvim_get_option_info2 ( ' dictionary ' , { } ) ) -- buffer
eq ( api.nvim_get_option_info ( ' fillchars ' ) , api.nvim_get_option_info2 ( ' fillchars ' , { } ) ) -- window
eq ( api.nvim_get_option_info ( ' completeopt ' ) , api.nvim_get_option_info2 ( ' completeopt ' , { } ) ) -- global
2023-03-29 00:59:01 -07:00
end )
describe ( ' last set ' , function ( )
2023-12-07 04:19:35 -07:00
-- stylua: ignore
2023-03-29 00:59:01 -07:00
local tests = {
{ desc = " (buf option, global requested, global set) points to global " , linenr = 1 , sid = 1 , args = { ' dictionary ' , { scope = ' global ' } } } ,
{ desc = " (buf option, global requested, local set) is not set " , linenr = 0 , sid = 0 , args = { ' formatprg ' , { scope = ' global ' } } } ,
{ desc = " (buf option, global requested, both set) points to global " , linenr = 3 , sid = 1 , args = { ' equalprg ' , { scope = ' global ' } } } ,
{ desc = " (buf option, local requested, global set) is not set " , linenr = 0 , sid = 0 , args = { ' dictionary ' , { scope = ' local ' } } } ,
{ desc = " (buf option, local requested, local set) points to local " , linenr = 2 , sid = 1 , args = { ' formatprg ' , { scope = ' local ' } } } ,
{ desc = " (buf option, local requested, both set) points to local " , linenr = 4 , sid = 1 , args = { ' equalprg ' , { scope = ' local ' } } } ,
{ desc = " (buf option, fallback requested, global set) points to global " , linenr = 1 , sid = 1 , args = { ' dictionary ' , { } } } ,
{ desc = " (buf option, fallback requested, local set) points to local " , linenr = 2 , sid = 1 , args = { ' formatprg ' , { } } } ,
{ desc = " (buf option, fallback requested, both set) points to local " , linenr = 4 , sid = 1 , args = { ' equalprg ' , { } } } ,
{ desc = " (win option, global requested, global set) points to global " , linenr = 5 , sid = 1 , args = { ' fillchars ' , { scope = ' global ' } } } ,
{ desc = " (win option, global requested, local set) is not set " , linenr = 0 , sid = 0 , args = { ' listchars ' , { scope = ' global ' } } } ,
{ desc = " (win option, global requested, both set) points to global " , linenr = 7 , sid = 1 , args = { ' showbreak ' , { scope = ' global ' } } } ,
{ desc = " (win option, local requested, global set) is not set " , linenr = 0 , sid = 0 , args = { ' fillchars ' , { scope = ' local ' } } } ,
{ desc = " (win option, local requested, local set) points to local " , linenr = 6 , sid = 1 , args = { ' listchars ' , { scope = ' local ' } } } ,
{ desc = " (win option, local requested, both set) points to local " , linenr = 8 , sid = 1 , args = { ' showbreak ' , { scope = ' local ' } } } ,
{ desc = " (win option, fallback requested, global set) points to global " , linenr = 5 , sid = 1 , args = { ' fillchars ' , { } } } ,
{ desc = " (win option, fallback requested, local set) points to local " , linenr = 6 , sid = 1 , args = { ' listchars ' , { } } } ,
{ desc = " (win option, fallback requested, both set) points to local " , linenr = 8 , sid = 1 , args = { ' showbreak ' , { } } } ,
{ desc = " (global option, global requested) points to global " , linenr = 9 , sid = 1 , args = { ' completeopt ' , { scope = ' global ' } } } ,
{ desc = " (global option, local requested) is not set " , linenr = 0 , sid = 0 , args = { ' completeopt ' , { scope = ' local ' } } } ,
{ desc = " (global option, fallback requested) points to global " , linenr = 9 , sid = 1 , args = { ' completeopt ' , { } } } ,
}
2024-04-08 02:03:20 -07:00
for _ , test in pairs ( tests ) do
it ( test.desc , function ( )
2023-03-29 00:59:01 -07:00
-- Switch to the target buffer/window so that curbuf/curwin are used.
2024-01-16 06:26:21 -07:00
api.nvim_set_current_win ( wins [ 2 ] )
2024-04-08 02:03:20 -07:00
local info = api.nvim_get_option_info2 ( unpack ( test.args ) )
eq ( test.linenr , info.last_set_linenr )
eq ( test.sid , info.last_set_sid )
2023-03-29 00:59:01 -07:00
end )
end
it ( ' is provided for cross-buffer requests ' , function ( )
2024-01-16 06:26:21 -07:00
local info = api.nvim_get_option_info2 ( ' formatprg ' , { buf = bufs [ 2 ] } )
2023-03-29 00:59:01 -07:00
eq ( 2 , info.last_set_linenr )
eq ( 1 , info.last_set_sid )
end )
it ( ' is provided for cross-window requests ' , function ( )
2024-01-16 06:26:21 -07:00
local info = api.nvim_get_option_info2 ( ' listchars ' , { win = wins [ 2 ] } )
2023-03-29 00:59:01 -07:00
eq ( 6 , info.last_set_linenr )
eq ( 1 , info.last_set_sid )
end )
end )
end )
2021-01-10 23:18:51 -07:00
describe ( ' nvim_echo ' , function ( )
local screen
before_each ( function ( )
screen = Screen.new ( 40 , 8 )
screen : attach ( )
command ( ' highlight Statement gui=bold guifg=Brown ' )
command ( ' highlight Special guifg=SlateBlue ' )
end )
2021-01-21 05:49:25 -07:00
it ( ' should clear cmdline message before echo ' , function ( )
feed ( ' :call nvim_echo([["msg"]], v:false, {})<CR> ' )
2023-12-07 04:19:35 -07:00
screen : expect {
grid = [ [
2021-01-21 05:49:25 -07:00
^ |
2024-05-25 10:18:57 -07:00
{ 1 : ~ } |* 6
2021-01-21 05:49:25 -07:00
msg |
2023-12-07 04:19:35 -07:00
] ] ,
}
2021-01-21 05:49:25 -07:00
end )
2021-01-10 23:18:51 -07:00
it ( ' can show highlighted line ' , function ( )
2024-01-15 09:10:51 -07:00
async_meths.nvim_echo (
2023-12-07 04:19:35 -07:00
{ { ' msg_a ' } , { ' msg_b ' , ' Statement ' } , { ' msg_c ' , ' Special ' } } ,
true ,
{ }
)
screen : expect {
grid = [ [
2021-01-10 23:18:51 -07:00
^ |
2024-05-25 10:18:57 -07:00
{ 1 : ~ } |* 6
msg_a { 15 : msg_b } { 16 : msg_c } |
2023-12-07 04:19:35 -07:00
] ] ,
}
2021-01-10 23:18:51 -07:00
end )
it ( ' can show highlighted multiline ' , function ( )
2024-01-15 09:10:51 -07:00
async_meths.nvim_echo ( { { ' msg_a \n msg_a ' , ' Statement ' } , { ' msg_b ' , ' Special ' } } , true , { } )
2023-12-07 04:19:35 -07:00
screen : expect {
grid = [ [
2021-01-10 23:18:51 -07:00
|
2024-05-25 10:18:57 -07:00
{ 1 : ~ } |* 3
{ 3 : } |
{ 15 : msg_a } |
{ 15 : msg_a } { 16 : msg_b } |
{ 6 : Press ENTER or type command to continue } ^ |
2023-12-07 04:19:35 -07:00
] ] ,
}
2021-01-10 23:18:51 -07:00
end )
it ( ' can save message history ' , function ( )
2024-01-12 06:11:28 -07:00
command ( ' set cmdheight=2 ' ) -- suppress Press ENTER
2024-01-12 10:59:57 -07:00
api.nvim_echo ( { { ' msg \n msg ' } , { ' msg ' } } , true , { } )
2023-12-07 04:19:35 -07:00
eq ( ' msg \n msgmsg ' , exec_capture ( ' messages ' ) )
2021-01-10 23:18:51 -07:00
end )
it ( ' can disable saving message history ' , function ( )
2024-01-12 06:11:28 -07:00
command ( ' set cmdheight=2 ' ) -- suppress Press ENTER
2024-01-15 09:10:51 -07:00
async_meths.nvim_echo ( { { ' msg \n msg ' } , { ' msg ' } } , false , { } )
2023-12-07 04:19:35 -07:00
eq ( ' ' , exec_capture ( ' messages ' ) )
2021-01-10 23:18:51 -07:00
end )
end )
2020-12-20 08:52:01 -07:00
describe ( ' nvim_open_term ' , function ( )
local screen
before_each ( function ( )
screen = Screen.new ( 100 , 35 )
screen : attach ( )
2024-05-25 10:18:57 -07:00
screen : add_extra_attr_ids {
[ 100 ] = { background = tonumber ( ' 0xffff40 ' ) , bg_indexed = true } ,
[ 101 ] = {
2023-12-07 04:19:35 -07:00
background = Screen.colors . LightMagenta ,
2024-05-25 10:18:57 -07:00
foreground = tonumber ( ' 0x00e000 ' ) ,
fg_indexed = true ,
2023-12-07 04:19:35 -07:00
} ,
2024-05-25 10:18:57 -07:00
[ 102 ] = { background = Screen.colors . LightMagenta , reverse = true } ,
[ 103 ] = { background = Screen.colors . LightMagenta , bold = true , reverse = true } ,
}
2020-12-20 08:52:01 -07:00
end )
it ( ' can batch process sequences ' , function ( )
2024-01-12 10:59:57 -07:00
local b = api.nvim_create_buf ( true , true )
api.nvim_open_win (
2024-01-12 05:44:54 -07:00
b ,
false ,
{ width = 79 , height = 31 , row = 1 , col = 1 , relative = ' editor ' }
)
2024-04-08 02:03:20 -07:00
local term = api.nvim_open_term ( b , { } )
2020-12-20 08:52:01 -07:00
2024-04-08 02:03:20 -07:00
api.nvim_chan_send ( term , io.open ( ' test/functional/fixtures/smile2.cat ' , ' r ' ) : read ( ' *a ' ) )
2023-12-07 04:19:35 -07:00
screen : expect {
grid = [ [
2020-12-20 08:52:01 -07:00
^ |
2024-05-25 10:18:57 -07:00
{ 1 : ~ } { 4 :: smile } { 1 : } |
{ 1 : ~ } { 4 : } { 100 : oooo $ $ $ $ $ $ $ $ $ $ $ $ oooo } { 4 : } { 1 : } |
{ 1 : ~ } { 4 : } { 100 : oo $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ o } { 4 : } { 1 : } |
{ 1 : ~ } { 4 : } { 100 : oo $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ o } { 4 : } { 100 : o $ } { 4 : } { 100 : $ $ } { 4 : } { 100 : o $ } { 4 : } { 1 : } |
{ 1 : ~ } { 4 : } { 100 : o } { 4 : } { 100 : $ } { 4 : } { 100 : oo } { 4 : } { 100 : o $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ o } { 4 : } { 100 : $ $ } { 4 : } { 100 : $ $ } { 4 : } { 100 : $ $ o $ } { 4 : } { 1 : } |
{ 1 : ~ } { 4 : } { 100 : oo } { 4 : } { 100 : $ } { 4 : } { 100 : $ } { 4 : " }{100:$}{4: }{100:o$$$$$$$$$}{4: }{100:$$$$$$$$$$$$$}{4: }{100:$$$$$$$$$o}{4: }{100:$$$o$$o$}{4: }{1: }|
{ 1 : ~ } { 4 : " }{100:$$$$$$o$}{4: }{100:o$$$$$$$$$}{4: }{100:$$$$$$$$$$$}{4: }{100:$$$$$$$$$$o}{4: }{100:$$$$$$$$}{4: }{1: }|
{ 1 : ~ } { 4 : } { 100 : $ $ $ $ $ $ $ } { 4 : } { 100 : $ $ $ $ $ $ $ $ $ $ $ } { 4 : } { 100 : $ $ $ $ $ $ $ $ $ $ $ } { 4 : } { 100 : $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ } { 4 : } { 1 : } |
{ 1 : ~ } { 4 : } { 100 : $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ } { 4 : } { 100 : $ $ $ $ $ $ $ $ $ $ $ $ $ } { 4 : } { 100 : $ $ $ $ $ $ $ $ $ $ $ $ $ $ } { 4 : " " " }{100:$$$}{4: }{1: }|
{ 1 : ~ } { 4 : " }{100:$$$}{4: " " " " }{100:$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}{4: " } { 100 : $ $ $ } { 4 : } { 1 : } |
{ 1 : ~ } { 4 : } { 100 : $ $ $ } { 4 : } { 100 : o $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ } { 4 : " }{100:$$$o}{4: }{1: }|
{ 1 : ~ } { 4 : } { 100 : o $ $ } { 4 : " }{100:$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}{4: }{100:$$$o}{4: }{1: }|
{ 1 : ~ } { 4 : } { 100 : $ $ $ } { 4 : } { 100 : $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ } { 4 : " " } { 100 : $ $ $ $ $ $ ooooo $ $ $ $ o } { 4 : } { 1 : } |
{ 1 : ~ } { 4 : } { 100 : o $ $ $ oooo $ $ $ $ $ } { 4 : } { 100 : $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ } { 4 : } { 100 : o $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ } { 4 : } { 1 : } |
{ 1 : ~ } { 4 : } { 100 : $ $ $ $ $ $ $ $ } { 4 : " }{100:$$$$}{4: }{100:$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}{4: }{100:$$$$}{4: " " " " " " " " }{1: }|
{ 1 : ~ } { 4 : " " " " } { 100 : $ $ $ $ } { 4 : " }{100:$$$$$$$$$$$$$$$$$$$$$$$$$$$$}{4: " } { 100 : o $ $ $ } { 4 : } { 1 : } |
{ 1 : ~ } { 4 : " }{100:$$$o}{4: " " " } { 100 : $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ } { 4 : " }{100:$$}{4: " } { 100 : $ $ $ } { 4 : } { 1 : } |
{ 1 : ~ } { 4 : } { 100 : $ $ $ o } { 4 : " }{100:$$}{4: " " }{100:$$$$$$}{4: " " " " }{100:o$$$}{4: }{1: }|
{ 1 : ~ } { 4 : } { 100 : $ $ $ $ o } { 4 : } { 100 : o $ $ $ } { 4 : " }{1: }|
{ 1 : ~ } { 4 : " }{100:$$$$o}{4: }{100:o$$$$$$o}{4: " } { 100 : $ $ $ $ o } { 4 : } { 100 : o $ $ $ $ } { 4 : } { 1 : } |
{ 1 : ~ } { 4 : " }{100:$$$$$oo}{4: " " }{100:$$$$o$$$$$o}{4: }{100:o$$$$}{4: " " }{1: }|
{ 1 : ~ } { 4 : " " } { 100 : $ $ $ $ $ oooo } { 4 : " }{100:$$$o$$$$$$$$$}{4: " " " } { 1 : } |
{ 1 : ~ } { 4 : " " } { 100 : $ $ $ $ $ $ $ oo } { 4 : } { 100 : $ $ $ $ $ $ $ $ $ $ } { 4 : } { 1 : } |
{ 1 : ~ } { 4 : " " " " } { 100 : $ $ $ $ $ $ $ $ $ $ $ } { 4 : } { 1 : } |
{ 1 : ~ } { 4 : } { 100 : $ $ $ $ $ $ $ $ $ $ $ $ } { 4 : } { 1 : } |
{ 1 : ~ } { 4 : } { 100 : $ $ $ $ $ $ $ $ $ $ } { 4 : " }{1: }|
{ 1 : ~ } { 4 : " }{100:$$$}{4: " " " " }{1: }|
{ 1 : ~ } { 4 : } { 1 : } |
{ 1 : ~ } { 101 : Press ENTER or type command to continue } { 4 : } { 1 : } |
{ 1 : ~ } { 103 : term : //~/ config2 / docs / pres // 32693 : vim --clean +smile 29,39 All}{1: }|
{ 1 : ~ } { 4 :: call nvim__screenshot ( " smile2 . cat " ) } { 1 : } |
{ 1 : ~ } |* 2
2020-12-20 08:52:01 -07:00
|
2023-12-07 04:19:35 -07:00
] ] ,
}
2020-12-20 08:52:01 -07:00
end )
2020-12-24 15:15:20 -07:00
it ( ' can handle input ' , function ( )
screen : try_resize ( 50 , 10 )
2023-12-07 04:19:35 -07:00
eq (
{ 3 , 2 } ,
exec_lua [ [
2020-12-24 15:15:20 -07:00
buf = vim.api . nvim_create_buf ( 1 , 1 )
stream = ' '
do_the_echo = false
function input ( _ , t1 , b1 , data )
stream = stream .. data
_G.vals = { t1 , b1 }
if do_the_echo then
vim.api . nvim_chan_send ( t1 , data )
end
end
term = vim.api . nvim_open_term ( buf , { on_input = input } )
vim.api . nvim_open_win ( buf , true , { width = 40 , height = 5 , row = 1 , col = 1 , relative = ' editor ' } )
return { term , buf }
2023-12-07 04:19:35 -07:00
] ]
)
2020-12-24 15:15:20 -07:00
2023-12-07 04:19:35 -07:00
screen : expect {
grid = [ [
2020-12-24 15:15:20 -07:00
|
2024-05-25 10:18:57 -07:00
{ 1 : ~ } { 4 : ^ } { 1 : } |
{ 1 : ~ } { 4 : } { 1 : } |* 4
{ 1 : ~ } |* 3
2020-12-24 15:15:20 -07:00
|
2023-12-07 04:19:35 -07:00
] ] ,
}
2020-12-24 15:15:20 -07:00
feed ' iba<c-x>bla '
2023-12-07 04:19:35 -07:00
screen : expect {
grid = [ [
2020-12-24 15:15:20 -07:00
|
2024-05-25 10:18:57 -07:00
{ 1 : ~ } { 102 : } { 4 : } { 1 : } |
{ 1 : ~ } { 4 : } { 1 : } |* 4
{ 1 : ~ } |* 3
{ 5 : -- TERMINAL --} |
2023-12-07 04:19:35 -07:00
] ] ,
}
2020-12-24 15:15:20 -07:00
eq ( ' ba \024 bla ' , exec_lua [[ return stream ]] )
2023-12-07 04:19:35 -07:00
eq ( { 3 , 2 } , exec_lua [[ return vals ]] )
2020-12-24 15:15:20 -07:00
exec_lua [[ do_the_echo = true ]]
feed ' herrejösses! '
2023-12-07 04:19:35 -07:00
screen : expect {
grid = [ [
2020-12-24 15:15:20 -07:00
|
2024-05-25 10:18:57 -07:00
{ 1 : ~ } { 4 : herrejösses ! } { 102 : } { 4 : } { 1 : } |
{ 1 : ~ } { 4 : } { 1 : } |* 4
{ 1 : ~ } |* 3
{ 5 : -- TERMINAL --} |
2023-12-07 04:19:35 -07:00
] ] ,
}
2020-12-24 15:15:20 -07:00
eq ( ' ba \024 blaherrejösses! ' , exec_lua [[ return stream ]] )
end )
2020-12-20 08:52:01 -07:00
end )
2021-10-05 08:49:20 -07:00
describe ( ' nvim_del_mark ' , function ( )
it ( ' works ' , function ( )
2024-01-12 10:59:57 -07:00
local buf = api.nvim_create_buf ( false , true )
api.nvim_buf_set_lines ( buf , - 1 , - 1 , true , { ' a ' , ' bit of ' , ' text ' } )
eq ( true , api.nvim_buf_set_mark ( buf , ' F ' , 2 , 2 , { } ) )
eq ( true , api.nvim_del_mark ( ' F ' ) )
eq ( { 0 , 0 } , api.nvim_buf_get_mark ( buf , ' F ' ) )
2021-10-05 08:49:20 -07:00
end )
2023-02-14 03:19:04 -07:00
it ( ' validation ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( " Invalid mark name (must be file/uppercase): 'f' " , pcall_err ( api.nvim_del_mark , ' f ' ) )
eq ( " Invalid mark name (must be file/uppercase): '!' " , pcall_err ( api.nvim_del_mark , ' ! ' ) )
eq ( " Invalid mark name (must be a single char): 'fail' " , pcall_err ( api.nvim_del_mark , ' fail ' ) )
2021-10-05 08:49:20 -07:00
end )
end )
describe ( ' nvim_get_mark ' , function ( )
it ( ' works ' , function ( )
2024-01-12 10:59:57 -07:00
local buf = api.nvim_create_buf ( false , true )
api.nvim_buf_set_lines ( buf , - 1 , - 1 , true , { ' a ' , ' bit of ' , ' text ' } )
api.nvim_buf_set_mark ( buf , ' F ' , 2 , 2 , { } )
api.nvim_buf_set_name ( buf , ' mybuf ' )
local mark = api.nvim_get_mark ( ' F ' , { } )
2022-11-28 18:45:48 -07:00
-- Compare the path tail only
2024-03-29 18:29:21 -07:00
matches ( ' mybuf$ ' , mark [ 4 ] )
2024-01-16 06:26:21 -07:00
eq ( { 2 , 2 , buf , mark [ 4 ] } , mark )
2021-10-05 08:49:20 -07:00
end )
2023-02-14 03:19:04 -07:00
it ( ' validation ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( " Invalid mark name (must be file/uppercase): 'f' " , pcall_err ( api.nvim_get_mark , ' f ' , { } ) )
eq ( " Invalid mark name (must be file/uppercase): '!' " , pcall_err ( api.nvim_get_mark , ' ! ' , { } ) )
2024-01-12 05:44:54 -07:00
eq (
" Invalid mark name (must be a single char): 'fail' " ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_get_mark , ' fail ' , { } )
2024-01-12 05:44:54 -07:00
)
2021-10-05 08:49:20 -07:00
end )
it ( ' returns the expected when mark is not set ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( true , api.nvim_del_mark ( ' A ' ) )
eq ( { 0 , 0 , 0 , ' ' } , api.nvim_get_mark ( ' A ' , { } ) )
2021-10-05 08:49:20 -07:00
end )
it ( ' works with deleted buffers ' , function ( )
local fname = tmpname ( )
write_file ( fname , ' a \n bit of \t ext ' )
2024-01-12 06:11:28 -07:00
command ( ' edit ' .. fname )
2024-01-12 10:59:57 -07:00
local buf = api.nvim_get_current_buf ( )
2021-10-05 08:49:20 -07:00
2024-01-12 10:59:57 -07:00
api.nvim_buf_set_mark ( buf , ' F ' , 2 , 2 , { } )
2024-01-12 06:11:28 -07:00
command ( ' new ' ) -- Create new buf to avoid :bd failing
2024-01-16 06:26:21 -07:00
command ( ' bd! ' .. buf )
2021-10-05 08:49:20 -07:00
os.remove ( fname )
2024-01-12 10:59:57 -07:00
local mark = api.nvim_get_mark ( ' F ' , { } )
2021-10-05 08:49:20 -07:00
-- To avoid comparing relative vs absolute path
local mfname = mark [ 4 ]
local tail_patt = [[[\/][^\/]*$]]
-- tail of paths should be equals
eq ( fname : match ( tail_patt ) , mfname : match ( tail_patt ) )
2024-01-16 06:26:21 -07:00
eq ( { 2 , 2 , buf , mark [ 4 ] } , mark )
2021-10-05 08:49:20 -07:00
end )
end )
2024-02-16 17:45:35 -07:00
2021-10-18 12:44:17 -07:00
describe ( ' nvim_eval_statusline ' , function ( )
it ( ' works ' , function ( )
eq ( {
2023-12-07 04:19:35 -07:00
str = ' %StatusLineStringWithHighlights ' ,
width = 31 ,
2024-01-12 10:59:57 -07:00
} , api.nvim_eval_statusline ( ' %%StatusLineString%#WarningMsg#WithHighlights ' , { } ) )
2021-10-18 12:44:17 -07:00
end )
2024-02-16 17:45:35 -07:00
2023-12-07 04:19:35 -07:00
it ( " doesn't exceed maxwidth " , function ( )
2021-10-18 12:44:17 -07:00
eq ( {
2023-12-07 04:19:35 -07:00
str = ' Should be trun> ' ,
width = 15 ,
2024-01-12 10:59:57 -07:00
} , api.nvim_eval_statusline ( ' Should be truncated%< ' , { maxwidth = 15 } ) )
2021-10-18 12:44:17 -07:00
end )
2024-02-16 17:45:35 -07:00
it ( ' has correct default fillchar ' , function ( )
local oldwin = api.nvim_get_current_win ( )
command ( ' set fillchars=stl:#,stlnc:$,wbr:% ' )
command ( ' new ' )
eq ( { str = ' a###b ' , width = 5 } , api.nvim_eval_statusline ( ' a%=b ' , { maxwidth = 5 } ) )
2023-12-07 04:19:35 -07:00
eq (
2024-02-16 17:45:35 -07:00
{ str = ' a$$$b ' , width = 5 } ,
api.nvim_eval_statusline ( ' a%=b ' , { winid = oldwin , maxwidth = 5 } )
2023-12-07 04:19:35 -07:00
)
eq (
2024-02-16 17:45:35 -07:00
{ str = ' a%%%b ' , width = 5 } ,
api.nvim_eval_statusline ( ' a%=b ' , { use_winbar = true , maxwidth = 5 } )
2023-12-07 04:19:35 -07:00
)
eq (
2024-02-16 17:45:35 -07:00
{ str = ' a b ' , width = 5 } ,
api.nvim_eval_statusline ( ' a%=b ' , { use_tabline = true , maxwidth = 5 } )
2023-12-07 04:19:35 -07:00
)
eq (
2024-02-16 17:45:35 -07:00
{ str = ' a b ' , width = 5 } ,
api.nvim_eval_statusline ( ' a%=b ' , { use_statuscol_lnum = 1 , maxwidth = 5 } )
2023-12-07 04:19:35 -07:00
)
2022-01-16 03:44:28 -07:00
end )
2024-02-16 17:45:35 -07:00
for fc , desc in pairs ( {
[ ' ~ ' ] = ' supports ASCII fillchar ' ,
[ ' ━ ' ] = ' supports single-width multibyte fillchar ' ,
[ ' c̳ ' ] = ' supports single-width fillchar with composing ' ,
[ ' 哦 ' ] = ' treats double-width fillchar as single-width ' ,
[ ' \031 ' ] = ' treats control character fillchar as single-width ' ,
} ) do
it ( desc , function ( )
eq (
{ str = ' a ' .. fc : rep ( 3 ) .. ' b ' , width = 5 } ,
api.nvim_eval_statusline ( ' a%=b ' , { fillchar = fc , maxwidth = 5 } )
)
eq (
{ str = ' a ' .. fc : rep ( 3 ) .. ' b ' , width = 5 } ,
api.nvim_eval_statusline ( ' a%=b ' , { fillchar = fc , use_winbar = true , maxwidth = 5 } )
)
eq (
{ str = ' a ' .. fc : rep ( 3 ) .. ' b ' , width = 5 } ,
api.nvim_eval_statusline ( ' a%=b ' , { fillchar = fc , use_tabline = true , maxwidth = 5 } )
)
eq (
{ str = ' a ' .. fc : rep ( 3 ) .. ' b ' , width = 5 } ,
api.nvim_eval_statusline ( ' a%=b ' , { fillchar = fc , use_statuscol_lnum = 1 , maxwidth = 5 } )
)
end )
end
2022-01-16 03:44:28 -07:00
it ( ' rejects multiple-character fillchar ' , function ( )
2023-12-07 04:19:35 -07:00
eq (
" Invalid 'fillchar': expected single character " ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_eval_statusline , ' ' , { fillchar = ' aa ' } )
2023-12-07 04:19:35 -07:00
)
2022-01-16 03:44:28 -07:00
end )
2024-02-16 17:45:35 -07:00
2022-01-16 03:44:28 -07:00
it ( ' rejects empty string fillchar ' , function ( )
2023-12-07 04:19:35 -07:00
eq (
" Invalid 'fillchar': expected single character " ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_eval_statusline , ' ' , { fillchar = ' ' } )
2023-12-07 04:19:35 -07:00
)
2022-01-16 03:44:28 -07:00
end )
2024-02-16 17:45:35 -07:00
2022-01-16 03:44:28 -07:00
it ( ' rejects non-string fillchar ' , function ( )
2023-12-07 04:19:35 -07:00
eq (
" Invalid 'fillchar': expected String, got Integer " ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_eval_statusline , ' ' , { fillchar = 1 } )
2023-12-07 04:19:35 -07:00
)
2022-01-16 03:44:28 -07:00
end )
2024-02-16 17:45:35 -07:00
2022-05-15 13:06:23 -07:00
it ( ' rejects invalid string ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( ' E539: Illegal character <}> ' , pcall_err ( api.nvim_eval_statusline , ' %{%} ' , { } ) )
2022-05-15 13:06:23 -07:00
end )
2024-02-16 17:45:35 -07:00
2023-01-10 06:18:12 -07:00
it ( ' supports various items ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( { str = ' 0 ' , width = 1 } , api.nvim_eval_statusline ( ' %l ' , { maxwidth = 5 } ) )
2023-01-10 06:18:12 -07:00
command ( ' set readonly ' )
2024-01-12 10:59:57 -07:00
eq ( { str = ' [RO] ' , width = 4 } , api.nvim_eval_statusline ( ' %r ' , { maxwidth = 5 } ) )
2022-12-27 03:04:42 -07:00
local screen = Screen.new ( 80 , 24 )
screen : attach ( )
command ( ' set showcmd ' )
feed ( ' 1234 ' )
2023-12-07 04:19:35 -07:00
screen : expect ( { any = ' 1234 ' } )
2024-01-12 10:59:57 -07:00
eq ( { str = ' 1234 ' , width = 4 } , api.nvim_eval_statusline ( ' %S ' , { maxwidth = 5 } ) )
2022-12-27 03:04:42 -07:00
feed ( ' 56 ' )
2023-12-07 04:19:35 -07:00
screen : expect ( { any = ' 123456 ' } )
2024-01-12 10:59:57 -07:00
eq ( { str = ' <3456 ' , width = 5 } , api.nvim_eval_statusline ( ' %S ' , { maxwidth = 5 } ) )
2022-12-27 03:04:42 -07:00
end )
2024-02-16 17:45:35 -07:00
2021-10-18 12:44:17 -07:00
describe ( ' highlight parsing ' , function ( )
it ( ' works ' , function ( )
2023-12-07 04:19:35 -07:00
eq (
{
str = ' TextWithWarningHighlightTextWithUserHighlight ' ,
2021-10-18 12:44:17 -07:00
width = 45 ,
highlights = {
{ start = 0 , group = ' WarningMsg ' } ,
2023-12-07 04:19:35 -07:00
{ start = 24 , group = ' User1 ' } ,
2021-10-18 12:44:17 -07:00
} ,
} ,
2024-01-12 10:59:57 -07:00
api.nvim_eval_statusline (
2021-10-18 12:44:17 -07:00
' %#WarningMsg#TextWithWarningHighlight%1*TextWithUserHighlight ' ,
2023-12-07 04:19:35 -07:00
{ highlights = true }
)
)
2021-10-18 12:44:17 -07:00
end )
2024-02-16 17:45:35 -07:00
2021-10-18 12:44:17 -07:00
it ( ' works with no highlight ' , function ( )
eq ( {
2023-12-07 04:19:35 -07:00
str = ' TextWithNoHighlight ' ,
width = 19 ,
highlights = {
{ start = 0 , group = ' StatusLine ' } ,
2021-10-18 12:44:17 -07:00
} ,
2024-01-12 10:59:57 -07:00
} , api.nvim_eval_statusline ( ' TextWithNoHighlight ' , { highlights = true } ) )
2021-10-18 12:44:17 -07:00
end )
2024-02-16 17:45:35 -07:00
2021-10-18 12:44:17 -07:00
it ( ' works with inactive statusline ' , function ( )
command ( ' split ' )
2023-12-07 04:19:35 -07:00
eq (
{
2021-10-18 12:44:17 -07:00
str = ' TextWithNoHighlightTextWithWarningHighlight ' ,
width = 43 ,
highlights = {
{ start = 0 , group = ' StatusLineNC ' } ,
2023-12-07 04:19:35 -07:00
{ start = 19 , group = ' WarningMsg ' } ,
} ,
2021-10-18 12:44:17 -07:00
} ,
2024-01-12 10:59:57 -07:00
api.nvim_eval_statusline (
2021-10-18 12:44:17 -07:00
' TextWithNoHighlight%#WarningMsg#TextWithWarningHighlight ' ,
2024-01-16 06:26:21 -07:00
{ winid = api.nvim_list_wins ( ) [ 2 ] , highlights = true }
2023-12-07 04:19:35 -07:00
)
)
2021-10-18 12:44:17 -07:00
end )
2024-02-16 17:45:35 -07:00
2021-10-18 12:44:17 -07:00
it ( ' works with tabline ' , function ( )
2023-12-07 04:19:35 -07:00
eq (
{
2021-10-18 12:44:17 -07:00
str = ' TextWithNoHighlightTextWithWarningHighlight ' ,
width = 43 ,
highlights = {
{ start = 0 , group = ' TabLineFill ' } ,
2023-12-07 04:19:35 -07:00
{ start = 19 , group = ' WarningMsg ' } ,
} ,
2021-10-18 12:44:17 -07:00
} ,
2024-01-12 10:59:57 -07:00
api.nvim_eval_statusline (
2021-10-18 12:44:17 -07:00
' TextWithNoHighlight%#WarningMsg#TextWithWarningHighlight ' ,
2023-12-07 04:19:35 -07:00
{ use_tabline = true , highlights = true }
)
)
2021-10-18 12:44:17 -07:00
end )
2024-02-16 17:45:35 -07:00
2022-05-13 07:47:11 -07:00
it ( ' works with winbar ' , function ( )
2023-12-07 04:19:35 -07:00
eq (
{
2022-05-13 07:47:11 -07:00
str = ' TextWithNoHighlightTextWithWarningHighlight ' ,
width = 43 ,
highlights = {
{ start = 0 , group = ' WinBar ' } ,
2023-12-07 04:19:35 -07:00
{ start = 19 , group = ' WarningMsg ' } ,
} ,
2022-05-13 07:47:11 -07:00
} ,
2024-01-12 10:59:57 -07:00
api.nvim_eval_statusline (
2022-05-13 07:47:11 -07:00
' TextWithNoHighlight%#WarningMsg#TextWithWarningHighlight ' ,
2023-12-07 04:19:35 -07:00
{ use_winbar = true , highlights = true }
)
)
2022-05-13 07:47:11 -07:00
end )
2024-02-16 17:45:35 -07:00
2023-04-01 05:58:52 -07:00
it ( ' works with statuscolumn ' , function ( )
2023-04-05 18:33:57 -07:00
exec ( [ [
2023-04-01 05:58:52 -07:00
let & stc = ' %C%s%=%l '
2024-02-16 16:44:31 -07:00
" should not use " stl " from 'fillchars'
set cul nu nuw = 3 scl = yes : 2 fdc = 2 fillchars = stl : #
2023-04-01 05:58:52 -07:00
call setline ( 1 , repeat ( [ ' aaaaa ' ] , 5 ) )
let g : ns = nvim_create_namespace ( ' ' )
call sign_define ( ' a ' , { ' text ' : ' aa ' , ' texthl ' : ' IncSearch ' , ' numhl ' : ' Normal ' } )
call sign_place ( 2 , 1 , ' a ' , bufnr ( ) , { ' lnum ' : 4 } )
call nvim_buf_set_extmark ( 0 , g : ns , 3 , 1 , { ' sign_text ' : ' bb ' , ' sign_hl_group ' : ' ErrorMsg ' } )
1 , 5 fold | 1 , 5 fold | foldopen !
2023-04-05 18:33:57 -07:00
norm 4 G
2023-04-01 05:58:52 -07:00
] ] )
eq ( {
feat(signs)!: place higher-priority signs from the left #27781
Problem:
Higher-priority signs may be hidden by lower-priority signs.
Solution:
Place higher-priority signs from the left.
Example:
nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='H', priority=1})
nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='W', priority=2})
nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='E', priority=3})
Before:
| |
H | W E |
^ | |
Not visible
After:
| |
| E W | H
| | ^
Not visible
Fixes #16632
2024-05-21 09:21:42 -07:00
str = ' ││bbaa 4 ' ,
2023-04-01 05:58:52 -07:00
width = 9 ,
highlights = {
{ group = ' CursorLineFold ' , start = 0 } ,
{ group = ' Normal ' , start = 6 } ,
feat(signs)!: place higher-priority signs from the left #27781
Problem:
Higher-priority signs may be hidden by lower-priority signs.
Solution:
Place higher-priority signs from the left.
Example:
nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='H', priority=1})
nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='W', priority=2})
nvim_buf_set_extmark(0, ns, 0, -1, {sign_text='E', priority=3})
Before:
| |
H | W E |
^ | |
Not visible
After:
| |
| E W | H
| | ^
Not visible
Fixes #16632
2024-05-21 09:21:42 -07:00
{ group = ' ErrorMsg ' , start = 6 } ,
{ group = ' IncSearch ' , start = 8 } ,
2023-12-07 04:19:35 -07:00
{ group = ' Normal ' , start = 10 } ,
} ,
2024-01-12 10:59:57 -07:00
} , api.nvim_eval_statusline (
2024-01-12 05:44:54 -07:00
' %C%s%=%l ' ,
{ use_statuscol_lnum = 4 , highlights = true }
2023-12-07 04:19:35 -07:00
) )
2024-01-12 05:44:54 -07:00
eq (
{
2024-06-14 20:46:43 -07:00
str = ' 3 ' ,
width = 9 ,
2024-01-12 05:44:54 -07:00
highlights = {
{ group = ' LineNr ' , start = 0 } ,
2024-06-14 20:46:43 -07:00
{ group = ' ErrorMsg ' , start = 8 } ,
2024-01-12 05:44:54 -07:00
} ,
} ,
2024-01-12 10:59:57 -07:00
api.nvim_eval_statusline ( ' %l%#ErrorMsg# ' , { use_statuscol_lnum = 3 , highlights = true } )
2024-01-12 05:44:54 -07:00
)
2023-04-01 05:58:52 -07:00
end )
2024-02-16 17:45:35 -07:00
2023-01-16 16:31:36 -07:00
it ( ' no memory leak with click functions ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_eval_statusline ( ' %@ClickFunc@StatusLineStringWithClickFunc%T ' , { } )
2023-01-16 16:31:36 -07:00
eq ( {
2023-12-07 04:19:35 -07:00
str = ' StatusLineStringWithClickFunc ' ,
width = 29 ,
2024-01-12 10:59:57 -07:00
} , api.nvim_eval_statusline ( ' %@ClickFunc@StatusLineStringWithClickFunc%T ' , { } ) )
2023-01-16 16:31:36 -07:00
end )
2021-10-18 12:44:17 -07:00
end )
end )
2023-07-01 06:33:51 -07:00
2022-04-22 21:21:59 -07:00
describe ( ' nvim_parse_cmd ' , function ( )
it ( ' works ' , function ( )
eq ( {
cmd = ' echo ' ,
args = { ' foo ' } ,
bang = false ,
addr = ' none ' ,
magic = {
2023-12-07 04:19:35 -07:00
file = false ,
bar = false ,
2022-04-22 21:21:59 -07:00
} ,
nargs = ' * ' ,
nextcmd = ' ' ,
mods = {
browse = false ,
confirm = false ,
emsg_silent = false ,
2022-06-28 03:22:29 -07:00
filter = {
2023-12-07 04:19:35 -07:00
pattern = ' ' ,
force = false ,
2022-06-28 03:22:29 -07:00
} ,
2022-04-22 21:21:59 -07:00
hide = false ,
2022-09-01 05:32:59 -07:00
horizontal = false ,
2022-04-22 21:21:59 -07:00
keepalt = false ,
keepjumps = false ,
keepmarks = false ,
keeppatterns = false ,
lockmarks = false ,
noautocmd = false ,
noswapfile = false ,
sandbox = false ,
silent = false ,
2023-12-07 04:19:35 -07:00
split = ' ' ,
2022-09-01 03:46:34 -07:00
tab = - 1 ,
2022-07-02 04:35:11 -07:00
unsilent = false ,
verbose = - 1 ,
vertical = false ,
2023-12-07 04:19:35 -07:00
} ,
2024-01-12 10:59:57 -07:00
} , api.nvim_parse_cmd ( ' echo foo ' , { } ) )
2022-04-22 21:21:59 -07:00
end )
it ( ' works with ranges ' , function ( )
eq ( {
cmd = ' substitute ' ,
args = { ' /math.random/math.max/ ' } ,
bang = false ,
2022-05-04 12:49:29 -07:00
range = { 4 , 6 } ,
2022-04-22 21:21:59 -07:00
addr = ' line ' ,
magic = {
2023-12-07 04:19:35 -07:00
file = false ,
bar = false ,
2022-04-22 21:21:59 -07:00
} ,
nargs = ' * ' ,
nextcmd = ' ' ,
mods = {
browse = false ,
confirm = false ,
emsg_silent = false ,
2022-06-28 03:22:29 -07:00
filter = {
2023-12-07 04:19:35 -07:00
pattern = ' ' ,
force = false ,
2022-06-28 03:22:29 -07:00
} ,
2022-04-22 21:21:59 -07:00
hide = false ,
2022-09-01 05:32:59 -07:00
horizontal = false ,
2022-04-22 21:21:59 -07:00
keepalt = false ,
keepjumps = false ,
keepmarks = false ,
keeppatterns = false ,
lockmarks = false ,
noautocmd = false ,
noswapfile = false ,
sandbox = false ,
silent = false ,
2023-12-07 04:19:35 -07:00
split = ' ' ,
2022-09-01 03:46:34 -07:00
tab = - 1 ,
2022-07-02 04:35:11 -07:00
unsilent = false ,
verbose = - 1 ,
vertical = false ,
2023-12-07 04:19:35 -07:00
} ,
2024-01-12 10:59:57 -07:00
} , api.nvim_parse_cmd ( ' 4,6s/math.random/math.max/ ' , { } ) )
2022-04-22 21:21:59 -07:00
end )
2022-05-04 05:04:01 -07:00
it ( ' works with count ' , function ( )
eq ( {
cmd = ' buffer ' ,
args = { } ,
bang = false ,
2022-05-06 19:57:21 -07:00
range = { 1 } ,
2022-05-04 05:04:01 -07:00
count = 1 ,
addr = ' buf ' ,
magic = {
2023-12-07 04:19:35 -07:00
file = false ,
bar = true ,
2022-05-04 05:04:01 -07:00
} ,
nargs = ' * ' ,
nextcmd = ' ' ,
mods = {
browse = false ,
confirm = false ,
emsg_silent = false ,
2022-06-28 03:22:29 -07:00
filter = {
2023-12-07 04:19:35 -07:00
pattern = ' ' ,
force = false ,
2022-06-28 03:22:29 -07:00
} ,
2022-05-04 05:04:01 -07:00
hide = false ,
2022-09-01 05:32:59 -07:00
horizontal = false ,
2022-05-04 05:04:01 -07:00
keepalt = false ,
keepjumps = false ,
keepmarks = false ,
keeppatterns = false ,
lockmarks = false ,
noautocmd = false ,
noswapfile = false ,
sandbox = false ,
silent = false ,
2023-12-07 04:19:35 -07:00
split = ' ' ,
2022-09-01 03:46:34 -07:00
tab = - 1 ,
2022-07-02 04:35:11 -07:00
unsilent = false ,
verbose = - 1 ,
vertical = false ,
2023-12-07 04:19:35 -07:00
} ,
2024-01-12 10:59:57 -07:00
} , api.nvim_parse_cmd ( ' buffer 1 ' , { } ) )
2022-05-04 05:04:01 -07:00
end )
it ( ' works with register ' , function ( )
eq ( {
cmd = ' put ' ,
args = { } ,
bang = false ,
2022-05-04 12:49:29 -07:00
range = { } ,
2022-05-04 05:04:01 -07:00
reg = ' + ' ,
addr = ' line ' ,
magic = {
2023-12-07 04:19:35 -07:00
file = false ,
bar = true ,
2022-05-04 05:04:01 -07:00
} ,
nargs = ' 0 ' ,
nextcmd = ' ' ,
mods = {
browse = false ,
confirm = false ,
emsg_silent = false ,
2022-06-28 03:22:29 -07:00
filter = {
2023-12-07 04:19:35 -07:00
pattern = ' ' ,
force = false ,
2022-06-28 03:22:29 -07:00
} ,
2022-05-04 05:04:01 -07:00
hide = false ,
2022-09-01 05:32:59 -07:00
horizontal = false ,
2022-05-04 05:04:01 -07:00
keepalt = false ,
keepjumps = false ,
keepmarks = false ,
keeppatterns = false ,
lockmarks = false ,
noautocmd = false ,
noswapfile = false ,
sandbox = false ,
silent = false ,
2023-12-07 04:19:35 -07:00
split = ' ' ,
2022-09-01 03:46:34 -07:00
tab = - 1 ,
2022-07-02 04:35:11 -07:00
unsilent = false ,
verbose = - 1 ,
vertical = false ,
2023-12-07 04:19:35 -07:00
} ,
2024-01-12 10:59:57 -07:00
} , api.nvim_parse_cmd ( ' put + ' , { } ) )
2022-09-26 23:40:10 -07:00
eq ( {
cmd = ' put ' ,
args = { } ,
bang = false ,
range = { } ,
reg = ' ' ,
addr = ' line ' ,
magic = {
2023-12-07 04:19:35 -07:00
file = false ,
bar = true ,
2022-09-26 23:40:10 -07:00
} ,
nargs = ' 0 ' ,
nextcmd = ' ' ,
mods = {
browse = false ,
confirm = false ,
emsg_silent = false ,
filter = {
2023-12-07 04:19:35 -07:00
pattern = ' ' ,
force = false ,
2022-09-26 23:40:10 -07:00
} ,
hide = false ,
horizontal = false ,
keepalt = false ,
keepjumps = false ,
keepmarks = false ,
keeppatterns = false ,
lockmarks = false ,
noautocmd = false ,
noswapfile = false ,
sandbox = false ,
silent = false ,
2023-12-07 04:19:35 -07:00
split = ' ' ,
2022-09-26 23:40:10 -07:00
tab = - 1 ,
unsilent = false ,
verbose = - 1 ,
vertical = false ,
2023-12-07 04:19:35 -07:00
} ,
2024-01-12 10:59:57 -07:00
} , api.nvim_parse_cmd ( ' put ' , { } ) )
2022-05-04 05:04:01 -07:00
end )
2022-05-06 19:57:21 -07:00
it ( ' works with range, count and register ' , function ( )
eq ( {
cmd = ' delete ' ,
args = { } ,
bang = false ,
range = { 3 , 7 } ,
count = 7 ,
reg = ' * ' ,
addr = ' line ' ,
magic = {
2023-12-07 04:19:35 -07:00
file = false ,
bar = true ,
2022-05-06 19:57:21 -07:00
} ,
nargs = ' 0 ' ,
nextcmd = ' ' ,
mods = {
browse = false ,
confirm = false ,
emsg_silent = false ,
2022-06-28 03:22:29 -07:00
filter = {
2023-12-07 04:19:35 -07:00
pattern = ' ' ,
force = false ,
2022-06-28 03:22:29 -07:00
} ,
2022-05-06 19:57:21 -07:00
hide = false ,
2022-09-01 05:32:59 -07:00
horizontal = false ,
2022-05-06 19:57:21 -07:00
keepalt = false ,
keepjumps = false ,
keepmarks = false ,
keeppatterns = false ,
lockmarks = false ,
noautocmd = false ,
noswapfile = false ,
sandbox = false ,
silent = false ,
2023-12-07 04:19:35 -07:00
split = ' ' ,
2022-09-01 03:46:34 -07:00
tab = - 1 ,
2022-07-02 04:35:11 -07:00
unsilent = false ,
verbose = - 1 ,
vertical = false ,
2023-12-07 04:19:35 -07:00
} ,
2024-01-12 10:59:57 -07:00
} , api.nvim_parse_cmd ( ' 1,3delete * 5 ' , { } ) )
2022-05-06 19:57:21 -07:00
end )
2022-04-22 21:21:59 -07:00
it ( ' works with bang ' , function ( )
eq ( {
cmd = ' write ' ,
args = { } ,
bang = true ,
2022-05-04 12:49:29 -07:00
range = { } ,
2022-04-22 21:21:59 -07:00
addr = ' line ' ,
magic = {
2023-12-07 04:19:35 -07:00
file = true ,
bar = true ,
2022-04-22 21:21:59 -07:00
} ,
nargs = ' ? ' ,
nextcmd = ' ' ,
mods = {
browse = false ,
confirm = false ,
emsg_silent = false ,
2022-06-28 03:22:29 -07:00
filter = {
2023-12-07 04:19:35 -07:00
pattern = ' ' ,
force = false ,
2022-06-28 03:22:29 -07:00
} ,
2022-04-22 21:21:59 -07:00
hide = false ,
2022-09-01 05:32:59 -07:00
horizontal = false ,
2022-04-22 21:21:59 -07:00
keepalt = false ,
keepjumps = false ,
keepmarks = false ,
keeppatterns = false ,
lockmarks = false ,
noautocmd = false ,
noswapfile = false ,
sandbox = false ,
silent = false ,
2023-12-07 04:19:35 -07:00
split = ' ' ,
2022-09-01 03:46:34 -07:00
tab = - 1 ,
2022-07-02 04:35:11 -07:00
unsilent = false ,
verbose = - 1 ,
vertical = false ,
2022-04-22 21:21:59 -07:00
} ,
2024-01-12 10:59:57 -07:00
} , api.nvim_parse_cmd ( ' w! ' , { } ) )
2022-04-22 21:21:59 -07:00
end )
it ( ' works with modifiers ' , function ( )
2024-01-12 05:44:54 -07:00
eq (
{
cmd = ' split ' ,
args = { ' foo.txt ' } ,
bang = false ,
range = { } ,
addr = ' ? ' ,
magic = {
file = true ,
bar = true ,
} ,
nargs = ' ? ' ,
nextcmd = ' ' ,
mods = {
browse = false ,
confirm = false ,
emsg_silent = true ,
filter = {
pattern = ' foo ' ,
force = false ,
} ,
hide = false ,
horizontal = true ,
keepalt = false ,
keepjumps = false ,
keepmarks = false ,
keeppatterns = false ,
lockmarks = false ,
noautocmd = false ,
noswapfile = false ,
sandbox = false ,
silent = true ,
split = ' topleft ' ,
tab = 1 ,
unsilent = false ,
verbose = 15 ,
vertical = false ,
2022-06-28 03:22:29 -07:00
} ,
} ,
2024-01-12 10:59:57 -07:00
api.nvim_parse_cmd (
2024-01-12 05:44:54 -07:00
' 15verbose silent! horizontal topleft tab filter /foo/ split foo.txt ' ,
{ }
)
)
eq (
{
cmd = ' split ' ,
args = { ' foo.txt ' } ,
bang = false ,
range = { } ,
addr = ' ? ' ,
magic = {
file = true ,
bar = true ,
} ,
nargs = ' ? ' ,
nextcmd = ' ' ,
mods = {
browse = false ,
confirm = true ,
emsg_silent = false ,
filter = {
pattern = ' foo ' ,
force = true ,
} ,
hide = false ,
horizontal = false ,
keepalt = false ,
keepjumps = false ,
keepmarks = false ,
keeppatterns = false ,
lockmarks = false ,
noautocmd = false ,
noswapfile = false ,
sandbox = false ,
silent = false ,
split = ' botright ' ,
tab = 0 ,
unsilent = true ,
verbose = 0 ,
vertical = false ,
2022-06-28 03:22:29 -07:00
} ,
} ,
2024-01-12 10:59:57 -07:00
api.nvim_parse_cmd (
2024-01-12 05:44:54 -07:00
' 0verbose unsilent botright 0tab confirm filter! /foo/ split foo.txt ' ,
{ }
)
)
2022-04-22 21:21:59 -07:00
end )
it ( ' works with user commands ' , function ( )
command ( ' command -bang -nargs=+ -range -addr=lines MyCommand echo foo ' )
eq ( {
cmd = ' MyCommand ' ,
args = { ' test ' , ' it ' } ,
bang = true ,
2022-05-04 12:49:29 -07:00
range = { 4 , 6 } ,
2022-04-22 21:21:59 -07:00
addr = ' line ' ,
magic = {
2023-12-07 04:19:35 -07:00
file = false ,
bar = false ,
2022-04-22 21:21:59 -07:00
} ,
nargs = ' + ' ,
nextcmd = ' ' ,
mods = {
browse = false ,
confirm = false ,
emsg_silent = false ,
2022-06-28 03:22:29 -07:00
filter = {
2023-12-07 04:19:35 -07:00
pattern = ' ' ,
force = false ,
2022-06-28 03:22:29 -07:00
} ,
2022-04-22 21:21:59 -07:00
hide = false ,
2022-09-01 05:32:59 -07:00
horizontal = false ,
2022-04-22 21:21:59 -07:00
keepalt = false ,
keepjumps = false ,
keepmarks = false ,
keeppatterns = false ,
lockmarks = false ,
noautocmd = false ,
noswapfile = false ,
sandbox = false ,
silent = false ,
2023-12-07 04:19:35 -07:00
split = ' ' ,
2022-09-01 03:46:34 -07:00
tab = - 1 ,
2022-07-02 04:35:11 -07:00
unsilent = false ,
verbose = - 1 ,
vertical = false ,
2023-12-07 04:19:35 -07:00
} ,
2024-01-12 10:59:57 -07:00
} , api.nvim_parse_cmd ( ' 4,6MyCommand! test it ' , { } ) )
2022-04-22 21:21:59 -07:00
end )
it ( ' works for commands separated by bar ' , function ( )
eq ( {
cmd = ' argadd ' ,
args = { ' a.txt ' } ,
bang = false ,
2022-05-04 12:49:29 -07:00
range = { } ,
2022-04-22 21:21:59 -07:00
addr = ' arg ' ,
magic = {
2023-12-07 04:19:35 -07:00
file = true ,
bar = true ,
2022-04-22 21:21:59 -07:00
} ,
nargs = ' * ' ,
nextcmd = ' argadd b.txt ' ,
mods = {
browse = false ,
confirm = false ,
emsg_silent = false ,
2022-06-28 03:22:29 -07:00
filter = {
2023-12-07 04:19:35 -07:00
pattern = ' ' ,
force = false ,
2022-06-28 03:22:29 -07:00
} ,
2022-04-22 21:21:59 -07:00
hide = false ,
2022-09-01 05:32:59 -07:00
horizontal = false ,
2022-04-22 21:21:59 -07:00
keepalt = false ,
keepjumps = false ,
keepmarks = false ,
keeppatterns = false ,
lockmarks = false ,
noautocmd = false ,
noswapfile = false ,
sandbox = false ,
silent = false ,
2023-12-07 04:19:35 -07:00
split = ' ' ,
2022-09-01 03:46:34 -07:00
tab = - 1 ,
2022-07-02 04:35:11 -07:00
unsilent = false ,
verbose = - 1 ,
vertical = false ,
2023-12-07 04:19:35 -07:00
} ,
2024-01-12 10:59:57 -07:00
} , api.nvim_parse_cmd ( ' argadd a.txt | argadd b.txt ' , { } ) )
2022-04-22 21:21:59 -07:00
end )
it ( ' works for nargs=1 ' , function ( )
command ( ' command -nargs=1 MyCommand echo <q-args> ' )
eq ( {
cmd = ' MyCommand ' ,
args = { ' test it ' } ,
bang = false ,
addr = ' none ' ,
magic = {
2023-12-07 04:19:35 -07:00
file = false ,
bar = false ,
2022-04-22 21:21:59 -07:00
} ,
nargs = ' 1 ' ,
nextcmd = ' ' ,
mods = {
browse = false ,
confirm = false ,
emsg_silent = false ,
2022-06-28 03:22:29 -07:00
filter = {
2023-12-07 04:19:35 -07:00
pattern = ' ' ,
force = false ,
2022-06-28 03:22:29 -07:00
} ,
2022-04-22 21:21:59 -07:00
hide = false ,
2022-09-01 05:32:59 -07:00
horizontal = false ,
2022-04-22 21:21:59 -07:00
keepalt = false ,
keepjumps = false ,
keepmarks = false ,
keeppatterns = false ,
lockmarks = false ,
noautocmd = false ,
noswapfile = false ,
sandbox = false ,
silent = false ,
2023-12-07 04:19:35 -07:00
split = ' ' ,
2022-09-01 03:46:34 -07:00
tab = - 1 ,
2022-07-02 04:35:11 -07:00
unsilent = false ,
verbose = - 1 ,
vertical = false ,
2023-12-07 04:19:35 -07:00
} ,
2024-01-12 10:59:57 -07:00
} , api.nvim_parse_cmd ( ' MyCommand test it ' , { } ) )
2022-04-22 21:21:59 -07:00
end )
2023-06-28 04:51:55 -07:00
it ( ' validates command ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( ' Error while parsing command line ' , pcall_err ( api.nvim_parse_cmd , ' ' , { } ) )
eq ( ' Error while parsing command line ' , pcall_err ( api.nvim_parse_cmd , ' " foo ' , { } ) )
2023-12-07 04:19:35 -07:00
eq (
' Error while parsing command line: E492: Not an editor command: Fubar ' ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_parse_cmd , ' Fubar ' , { } )
2023-12-07 04:19:35 -07:00
)
2022-04-22 21:21:59 -07:00
command ( ' command! Fubar echo foo ' )
2023-12-07 04:19:35 -07:00
eq (
' Error while parsing command line: E477: No ! allowed ' ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_parse_cmd , ' Fubar! ' , { } )
2023-12-07 04:19:35 -07:00
)
eq (
' Error while parsing command line: E481: No range allowed ' ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_parse_cmd , ' 4,6Fubar ' , { } )
2023-12-07 04:19:35 -07:00
)
2022-06-26 23:10:13 -07:00
command ( ' command! Foobar echo foo ' )
2023-12-07 04:19:35 -07:00
eq (
' Error while parsing command line: E464: Ambiguous use of user-defined command ' ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_parse_cmd , ' F ' , { } )
2023-12-07 04:19:35 -07:00
)
2022-04-22 21:21:59 -07:00
end )
2022-07-16 18:59:32 -07:00
it ( ' does not interfere with printing line in Ex mode #19400 ' , function ( )
local screen = Screen.new ( 60 , 7 )
screen : attach ( )
insert ( [ [
foo
bar ] ] )
feed ( ' gQ1 ' )
screen : expect ( [ [
foo |
bar |
2024-05-25 10:18:57 -07:00
{ 1 : ~ } |* 2
{ 3 : } |
2022-07-16 18:59:32 -07:00
Entering Ex mode . Type " visual " to go to Normal mode . |
: 1 ^ |
] ] )
2024-01-12 10:59:57 -07:00
eq ( ' Error while parsing command line ' , pcall_err ( api.nvim_parse_cmd , ' ' , { } ) )
2022-07-16 18:59:32 -07:00
feed ( ' <CR> ' )
screen : expect ( [ [
foo |
bar |
2024-05-25 10:18:57 -07:00
{ 3 : } |
2022-07-16 18:59:32 -07:00
Entering Ex mode . Type " visual " to go to Normal mode . |
: 1 |
foo |
: ^ |
] ] )
end )
2022-08-22 03:06:18 -07:00
it ( ' does not move cursor or change search history/pattern #19878 #19890 ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_buf_set_lines ( 0 , 0 , - 1 , true , { ' foo ' , ' bar ' , ' foo ' , ' bar ' } )
eq ( { 1 , 0 } , api.nvim_win_get_cursor ( 0 ) )
eq ( ' ' , fn.getreg ( ' / ' ) )
eq ( ' ' , fn.histget ( ' search ' ) )
2023-12-07 04:19:35 -07:00
feed ( ' : ' ) -- call the API in cmdline mode to test whether it changes search history
2022-08-22 03:06:18 -07:00
eq ( {
cmd = ' normal ' ,
2023-12-07 04:19:35 -07:00
args = { ' x ' } ,
2022-08-22 03:06:18 -07:00
bang = true ,
2023-12-07 04:19:35 -07:00
range = { 3 , 4 } ,
2022-08-22 03:06:18 -07:00
addr = ' line ' ,
magic = {
file = false ,
bar = false ,
} ,
nargs = ' + ' ,
nextcmd = ' ' ,
mods = {
browse = false ,
confirm = false ,
emsg_silent = false ,
filter = {
2023-12-07 04:19:35 -07:00
pattern = ' ' ,
2022-08-22 03:06:18 -07:00
force = false ,
} ,
hide = false ,
2022-09-01 05:32:59 -07:00
horizontal = false ,
2022-08-22 03:06:18 -07:00
keepalt = false ,
keepjumps = false ,
keepmarks = false ,
keeppatterns = false ,
lockmarks = false ,
noautocmd = false ,
noswapfile = false ,
sandbox = false ,
silent = false ,
2023-12-07 04:19:35 -07:00
split = ' ' ,
2022-09-01 03:46:34 -07:00
tab = - 1 ,
2022-08-22 03:06:18 -07:00
unsilent = false ,
verbose = - 1 ,
vertical = false ,
2023-12-07 04:19:35 -07:00
} ,
2024-01-12 10:59:57 -07:00
} , api.nvim_parse_cmd ( ' +2;/bar/normal! x ' , { } ) )
eq ( { 1 , 0 } , api.nvim_win_get_cursor ( 0 ) )
eq ( ' ' , fn.getreg ( ' / ' ) )
eq ( ' ' , fn.histget ( ' search ' ) )
2022-08-22 03:06:18 -07:00
end )
2022-09-26 23:40:10 -07:00
it ( ' result can be used directly by nvim_cmd #20051 ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( ' foo ' , api.nvim_cmd ( api.nvim_parse_cmd ( ' echo "foo" ' , { } ) , { output = true } ) )
api.nvim_cmd ( api.nvim_parse_cmd ( ' set cursorline ' , { } ) , { } )
eq ( true , api.nvim_get_option_value ( ' cursorline ' , { } ) )
2022-09-26 23:40:10 -07:00
end )
2023-07-01 06:33:51 -07:00
it ( ' no side-effects (error messages) in pcall() #20339 ' , function ( )
2023-12-07 04:19:35 -07:00
eq (
{ false , ' Error while parsing command line: E16: Invalid range ' } ,
exec_lua ( [=[return {pcall(vim.api.nvim_parse_cmd, "'<,'>n", {})}]=] )
)
2023-07-01 06:33:51 -07:00
eq ( ' ' , eval ( ' v:errmsg ' ) )
end )
2022-04-22 21:21:59 -07:00
end )
2023-07-01 06:33:51 -07:00
2022-05-08 04:39:45 -07:00
describe ( ' nvim_cmd ' , function ( )
2023-12-07 04:19:35 -07:00
it ( ' works ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_cmd ( { cmd = ' set ' , args = { ' cursorline ' } } , { } )
eq ( true , api.nvim_get_option_value ( ' cursorline ' , { } ) )
2022-05-08 04:39:45 -07:00
end )
2023-02-16 08:07:18 -07:00
it ( ' validation ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( " Invalid 'cmd': expected non-empty String " , pcall_err ( api.nvim_cmd , { cmd = ' ' } , { } ) )
eq ( " Invalid 'cmd': expected String, got Array " , pcall_err ( api.nvim_cmd , { cmd = { } } , { } ) )
2023-12-07 04:19:35 -07:00
eq (
" Invalid 'args': expected Array, got Boolean " ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_cmd , { cmd = ' set ' , args = true } , { } )
2023-12-07 04:19:35 -07:00
)
eq (
' Invalid command arg: expected non-whitespace ' ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_cmd , { cmd = ' set ' , args = { ' ' } } , { } )
2023-12-07 04:19:35 -07:00
)
eq (
' Invalid command arg: expected valid type, got Array ' ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_cmd , { cmd = ' set ' , args = { { } } } , { } )
2023-12-07 04:19:35 -07:00
)
2024-01-12 10:59:57 -07:00
eq ( ' Wrong number of arguments ' , pcall_err ( api.nvim_cmd , { cmd = ' aboveleft ' , args = { } } , { } ) )
2023-12-07 04:19:35 -07:00
eq (
' Command cannot accept bang: print ' ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_cmd , { cmd = ' print ' , args = { } , bang = true } , { } )
2023-12-07 04:19:35 -07:00
)
eq (
' Command cannot accept range: set ' ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_cmd , { cmd = ' set ' , args = { } , range = { 1 } } , { } )
2023-12-07 04:19:35 -07:00
)
eq (
" Invalid 'range': expected Array, got Boolean " ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_cmd , { cmd = ' print ' , args = { } , range = true } , { } )
2023-12-07 04:19:35 -07:00
)
eq (
" Invalid 'range': expected <=2 elements " ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_cmd , { cmd = ' print ' , args = { } , range = { 1 , 2 , 3 , 4 } } , { } )
2023-12-07 04:19:35 -07:00
)
eq (
' Invalid range element: expected non-negative Integer ' ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_cmd , { cmd = ' print ' , args = { } , range = { - 1 } } , { } )
2023-12-07 04:19:35 -07:00
)
eq (
' Command cannot accept count: set ' ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_cmd , { cmd = ' set ' , args = { } , count = 1 } , { } )
2023-12-07 04:19:35 -07:00
)
eq (
" Invalid 'count': expected Integer, got Boolean " ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_cmd , { cmd = ' print ' , args = { } , count = true } , { } )
2023-12-07 04:19:35 -07:00
)
eq (
" Invalid 'count': expected non-negative Integer " ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_cmd , { cmd = ' print ' , args = { } , count = - 1 } , { } )
2023-12-07 04:19:35 -07:00
)
eq (
' Command cannot accept register: set ' ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_cmd , { cmd = ' set ' , args = { } , reg = ' x ' } , { } )
2024-01-12 05:44:54 -07:00
)
eq (
' Cannot use register "= ' ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_cmd , { cmd = ' put ' , args = { } , reg = ' = ' } , { } )
2023-12-07 04:19:35 -07:00
)
eq (
" Invalid 'reg': expected single character, got xx " ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_cmd , { cmd = ' put ' , args = { } , reg = ' xx ' } , { } )
2023-12-07 04:19:35 -07:00
)
2023-02-16 08:07:18 -07:00
2023-06-28 04:51:55 -07:00
-- #20681
2024-01-12 10:59:57 -07:00
eq ( ' Invalid command: "win_getid" ' , pcall_err ( api.nvim_cmd , { cmd = ' win_getid ' } , { } ) )
eq ( ' Invalid command: "echo "hi"" ' , pcall_err ( api.nvim_cmd , { cmd = ' echo "hi" ' } , { } ) )
2023-06-28 04:51:55 -07:00
eq ( ' Invalid command: "win_getid" ' , pcall_err ( exec_lua , [[return vim.cmd.win_getid{}]] ) )
2023-02-16 08:07:18 -07:00
-- Lua call allows empty {} for dict item.
eq ( ' ' , exec_lua ( [[return vim.cmd{ cmd = "set", args = {}, magic = {} }]] ) )
eq ( ' ' , exec_lua ( [[return vim.cmd{ cmd = "set", args = {}, mods = {} }]] ) )
2024-01-12 10:59:57 -07:00
eq ( ' ' , api.nvim_cmd ( { cmd = ' set ' , args = { } , magic = { } } , { } ) )
2023-02-16 08:07:18 -07:00
-- Lua call does not allow non-empty list-like {} for dict item.
2023-12-07 04:19:35 -07:00
eq (
" Invalid 'magic': Expected Dict-like Lua table " ,
pcall_err ( exec_lua , [[return vim.cmd{ cmd = "set", args = {}, magic = { 'a' } }]] )
)
eq (
" Invalid key: 'bogus' " ,
pcall_err ( exec_lua , [[return vim.cmd{ cmd = "set", args = {}, magic = { bogus = true } }]] )
)
eq (
" Invalid key: 'bogus' " ,
pcall_err ( exec_lua , [[return vim.cmd{ cmd = "set", args = {}, mods = { bogus = true } }]] )
)
2023-02-16 08:07:18 -07:00
end )
2022-05-08 04:39:45 -07:00
it ( ' captures output ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( ' foo ' , api.nvim_cmd ( { cmd = ' echo ' , args = { ' "foo" ' } } , { output = true } ) )
2022-05-08 04:39:45 -07:00
end )
2023-02-16 08:07:18 -07:00
2022-05-08 04:39:45 -07:00
it ( ' sets correct script context ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_cmd ( { cmd = ' set ' , args = { ' cursorline ' } } , { } )
2023-03-25 19:49:32 -07:00
local str = exec_capture ( [[verbose set cursorline?]] )
2023-12-07 04:19:35 -07:00
neq ( nil , str : find ( ' cursorline \n \t Last set from API client %(channel id %d+%) ' ) )
2022-05-08 04:39:45 -07:00
end )
2023-02-16 08:07:18 -07:00
2022-05-08 04:39:45 -07:00
it ( ' works with range ' , function ( )
insert [ [
line1
line2
line3
line4
you didn ' t expect this
line5
line6
] ]
2024-01-12 10:59:57 -07:00
api.nvim_cmd ( { cmd = ' del ' , range = { 2 , 4 } } , { } )
2022-05-08 04:39:45 -07:00
expect [ [
line1
you didn ' t expect this
line5
line6
] ]
end )
2024-01-26 23:03:44 -07:00
2022-05-08 04:39:45 -07:00
it ( ' works with count ' , function ( )
insert [ [
line1
line2
line3
line4
you didn ' t expect this
line5
line6
] ]
2024-01-12 10:59:57 -07:00
api.nvim_cmd ( { cmd = ' del ' , range = { 2 } , count = 4 } , { } )
2022-05-08 04:39:45 -07:00
expect [ [
line1
line5
line6
] ]
end )
2024-01-26 23:03:44 -07:00
2022-05-08 04:39:45 -07:00
it ( ' works with register ' , function ( )
insert [ [
line1
line2
line3
line4
you didn ' t expect this
line5
line6
] ]
2024-01-12 10:59:57 -07:00
api.nvim_cmd ( { cmd = ' del ' , range = { 2 , 4 } , reg = ' a ' } , { } )
2023-03-25 19:49:32 -07:00
command ( ' 1put a ' )
2022-05-08 04:39:45 -07:00
expect [ [
line1
line2
line3
line4
you didn ' t expect this
line5
line6
] ]
end )
2024-01-26 23:03:44 -07:00
2023-12-07 04:19:35 -07:00
it ( ' works with bang ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_create_user_command ( ' Foo ' , ' echo "<bang>" ' , { bang = true } )
eq ( ' ! ' , api.nvim_cmd ( { cmd = ' Foo ' , bang = true } , { output = true } ) )
eq ( ' ' , api.nvim_cmd ( { cmd = ' Foo ' , bang = false } , { output = true } ) )
2022-05-08 04:39:45 -07:00
end )
2024-01-26 23:03:44 -07:00
2022-05-08 04:39:45 -07:00
it ( ' works with modifiers ' , function ( )
2022-12-15 17:54:13 -07:00
-- with silent = true output is still captured
2023-12-07 04:19:35 -07:00
eq (
' 1 ' ,
2024-01-12 10:59:57 -07:00
api.nvim_cmd (
2024-01-12 05:44:54 -07:00
{ cmd = ' echomsg ' , args = { ' 1 ' } , mods = { silent = true } } ,
{ output = true }
)
2023-12-07 04:19:35 -07:00
)
2022-09-01 05:32:59 -07:00
-- but message isn't added to message history
2024-01-12 10:59:57 -07:00
eq ( ' ' , api.nvim_cmd ( { cmd = ' messages ' } , { output = true } ) )
2022-12-15 17:54:13 -07:00
2024-01-12 10:59:57 -07:00
api.nvim_create_user_command ( ' Foo ' , ' set verbose ' , { } )
eq ( ' verbose=1 ' , api.nvim_cmd ( { cmd = ' Foo ' , mods = { verbose = 1 } } , { output = true } ) )
2023-12-07 04:19:35 -07:00
2024-01-12 10:59:57 -07:00
api.nvim_create_user_command ( ' Mods ' , " echo '<mods>' " , { } )
2023-12-07 04:19:35 -07:00
eq (
' keepmarks keeppatterns silent 3verbose aboveleft horizontal ' ,
2024-01-12 10:59:57 -07:00
api.nvim_cmd ( {
2023-12-07 04:19:35 -07:00
cmd = ' Mods ' ,
mods = {
horizontal = true ,
keepmarks = true ,
keeppatterns = true ,
silent = true ,
split = ' aboveleft ' ,
verbose = 3 ,
} ,
} , { output = true } )
)
2024-01-12 10:59:57 -07:00
eq ( 0 , api.nvim_get_option_value ( ' verbose ' , { } ) )
2022-12-15 17:54:13 -07:00
2022-06-28 03:22:29 -07:00
command ( ' edit foo.txt | edit bar.txt ' )
2023-12-07 04:19:35 -07:00
eq (
' 1 #h "foo.txt" line 1 ' ,
2024-01-12 10:59:57 -07:00
api.nvim_cmd (
2023-12-07 04:19:35 -07:00
{ cmd = ' buffers ' , mods = { filter = { pattern = ' foo ' , force = false } } } ,
{ output = true }
)
)
eq (
' 2 %a "bar.txt" line 1 ' ,
2024-01-12 10:59:57 -07:00
api.nvim_cmd (
2023-12-07 04:19:35 -07:00
{ cmd = ' buffers ' , mods = { filter = { pattern = ' foo ' , force = true } } } ,
{ output = true }
)
)
2022-12-15 17:54:13 -07:00
2023-04-04 10:07:33 -07:00
-- with emsg_silent = true error is suppressed
2022-12-15 17:54:13 -07:00
feed ( [[:lua vim.api.nvim_cmd({ cmd = 'call', mods = { emsg_silent = true } }, {})<CR>]] )
2024-01-12 10:59:57 -07:00
eq ( ' ' , api.nvim_cmd ( { cmd = ' messages ' } , { output = true } ) )
2022-12-15 17:54:13 -07:00
-- error from the next command typed is not suppressed #21420
feed ( ' :call<CR><CR> ' )
2024-01-12 10:59:57 -07:00
eq ( ' E471: Argument required ' , api.nvim_cmd ( { cmd = ' messages ' } , { output = true } ) )
2022-05-08 04:39:45 -07:00
end )
2024-01-26 23:03:44 -07:00
2022-05-08 04:39:45 -07:00
it ( ' works with magic.file ' , function ( )
exec_lua ( [ [
vim.api . nvim_create_user_command ( " Foo " , function ( opts )
vim.api . nvim_echo ( { { opts.fargs [ 1 ] } } , false , { } )
end , { nargs = 1 } )
] ] )
2023-12-07 04:19:35 -07:00
eq (
2024-01-12 04:28:20 -07:00
uv.cwd ( ) ,
2024-01-12 10:59:57 -07:00
api.nvim_cmd (
2024-01-12 05:44:54 -07:00
{ cmd = ' Foo ' , args = { ' %:p:h ' } , magic = { file = true } } ,
{ output = true }
)
2023-12-07 04:19:35 -07:00
)
2022-05-08 04:39:45 -07:00
end )
2024-01-26 23:03:44 -07:00
2022-05-08 04:39:45 -07:00
it ( ' splits arguments correctly ' , function ( )
2023-03-25 19:49:32 -07:00
exec ( [ [
2022-05-08 04:39:45 -07:00
function ! FooFunc ( ... )
echo a : 000
endfunction
2023-03-25 19:49:32 -07:00
] ] )
2024-01-12 10:59:57 -07:00
api.nvim_create_user_command ( ' Foo ' , ' call FooFunc(<f-args>) ' , { nargs = ' + ' } )
2023-12-07 04:19:35 -07:00
eq (
[=[['a quick', 'brown fox', 'jumps over the', 'lazy dog']]=] ,
2024-01-12 10:59:57 -07:00
api.nvim_cmd (
2023-12-07 04:19:35 -07:00
{ cmd = ' Foo ' , args = { ' a quick ' , ' brown fox ' , ' jumps over the ' , ' lazy dog ' } } ,
{ output = true }
)
)
eq (
[=[['test \ \\ \"""\', 'more\ tests\" ']]=] ,
2024-01-12 10:59:57 -07:00
api.nvim_cmd (
2023-12-07 04:19:35 -07:00
{ cmd = ' Foo ' , args = { [[test \ \\ \"""\]] , [[more\ tests\" ]] } } ,
{ output = true }
)
)
2022-05-08 04:39:45 -07:00
end )
2024-01-26 23:03:44 -07:00
2022-05-08 04:39:45 -07:00
it ( ' splits arguments correctly for Lua callback ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_exec_lua (
2023-12-07 04:19:35 -07:00
[ [
2022-05-08 04:39:45 -07:00
local function FooFunc ( opts )
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
vim.print ( opts.fargs )
2022-05-08 04:39:45 -07:00
end
vim.api . nvim_create_user_command ( " Foo " , FooFunc , { nargs = ' + ' } )
2023-12-07 04:19:35 -07:00
] ] ,
{ }
)
eq (
[[{ "a quick", "brown fox", "jumps over the", "lazy dog" }]] ,
2024-01-12 10:59:57 -07:00
api.nvim_cmd (
2023-12-07 04:19:35 -07:00
{ cmd = ' Foo ' , args = { ' a quick ' , ' brown fox ' , ' jumps over the ' , ' lazy dog ' } } ,
{ output = true }
)
)
eq (
[[{ 'test \\ \\\\ \\"""\\', 'more\\ tests\\" ' }]] ,
2024-01-12 10:59:57 -07:00
api.nvim_cmd (
2023-12-07 04:19:35 -07:00
{ cmd = ' Foo ' , args = { [[test \ \\ \"""\]] , [[more\ tests\" ]] } } ,
{ output = true }
)
)
2022-05-08 04:39:45 -07:00
end )
2024-01-26 23:03:44 -07:00
2022-05-08 04:39:45 -07:00
it ( ' works with buffer names ' , function ( )
2023-12-07 04:19:35 -07:00
command ( ' edit foo.txt | edit bar.txt ' )
2024-01-12 10:59:57 -07:00
api.nvim_cmd ( { cmd = ' buffer ' , args = { ' foo.txt ' } } , { } )
eq ( ' foo.txt ' , fn.fnamemodify ( api.nvim_buf_get_name ( 0 ) , ' :t ' ) )
api.nvim_cmd ( { cmd = ' buffer ' , args = { ' bar.txt ' } } , { } )
eq ( ' bar.txt ' , fn.fnamemodify ( api.nvim_buf_get_name ( 0 ) , ' :t ' ) )
2022-05-08 04:39:45 -07:00
end )
2024-01-26 23:03:44 -07:00
2022-05-08 04:39:45 -07:00
it ( ' triggers CmdUndefined event if command is not found ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_exec_lua (
2023-12-07 04:19:35 -07:00
[ [
2022-05-08 04:39:45 -07:00
vim.api . nvim_create_autocmd ( " CmdUndefined " ,
{ pattern = " Foo " ,
callback = function ( )
vim.api . nvim_create_user_command ( " Foo " , " echo 'foo' " , { } )
end
} )
2023-12-07 04:19:35 -07:00
] ] ,
{ }
)
2024-01-12 10:59:57 -07:00
eq ( ' foo ' , api.nvim_cmd ( { cmd = ' Foo ' } , { output = true } ) )
2022-05-08 04:39:45 -07:00
end )
2024-01-26 23:03:44 -07:00
2022-05-08 04:39:45 -07:00
it ( ' errors if command is not implemented ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( ' Command not implemented: winpos ' , pcall_err ( api.nvim_cmd , { cmd = ' winpos ' } , { } ) )
2022-05-08 04:39:45 -07:00
end )
2024-01-26 23:03:44 -07:00
2022-05-11 09:51:53 -07:00
it ( ' works with empty arguments list ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_cmd ( { cmd = ' update ' } , { } )
api.nvim_cmd ( { cmd = ' buffer ' , count = 0 } , { } )
2022-05-11 09:51:53 -07:00
end )
2024-01-26 23:03:44 -07:00
2023-12-07 04:19:35 -07:00
it ( " doesn't suppress errors when used in keymapping " , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_exec_lua (
2023-12-07 04:19:35 -07:00
[ [
2022-05-19 08:49:12 -07:00
vim.keymap . set ( " n " , " [l " ,
function ( ) vim.api . nvim_cmd ( { cmd = " echo " , args = { " foo " } } , { } ) end )
2023-12-07 04:19:35 -07:00
] ] ,
{ }
)
feed ( ' [l ' )
neq ( nil , string.find ( eval ( ' v:errmsg ' ) , ' E5108: ' ) )
2022-05-19 08:49:12 -07:00
end )
2024-01-26 23:03:44 -07:00
2022-08-06 05:53:37 -07:00
it ( ' handles 0 range #19608 ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_buf_set_lines ( 0 , 0 , - 1 , false , { ' aa ' } )
api.nvim_cmd ( { cmd = ' delete ' , range = { 0 } } , { } )
2022-08-06 05:53:37 -07:00
command ( ' undo ' )
2024-01-12 10:59:57 -07:00
eq ( { ' aa ' } , api.nvim_buf_get_lines ( 0 , 0 , 1 , false ) )
2022-08-06 05:53:37 -07:00
assert_alive ( )
end )
2024-01-26 23:03:44 -07:00
2022-09-29 01:04:14 -07:00
it ( ' supports filename expansion ' , function ( )
2024-01-12 10:59:57 -07:00
api.nvim_cmd ( { cmd = ' argadd ' , args = { ' %:p:h:t ' , ' %:p:h:t ' } } , { } )
local arg = fn.expand ( ' %:p:h:t ' )
eq ( { arg , arg } , fn.argv ( ) )
2022-09-29 01:04:14 -07:00
end )
2024-01-26 23:03:44 -07:00
it ( " :make command works when argument count isn't 1 #19696 " , function ( )
2022-08-10 03:37:59 -07:00
command ( ' set makeprg=echo ' )
2022-09-29 01:04:14 -07:00
command ( ' set shellquote= ' )
2024-01-12 10:59:57 -07:00
matches ( ' ^:!echo ' , api.nvim_cmd ( { cmd = ' make ' } , { output = true } ) )
2022-09-29 01:04:14 -07:00
assert_alive ( )
2023-12-07 04:19:35 -07:00
matches (
' ^:!echo foo bar ' ,
2024-01-12 10:59:57 -07:00
api.nvim_cmd ( { cmd = ' make ' , args = { ' foo ' , ' bar ' } } , { output = true } )
2023-12-07 04:19:35 -07:00
)
2022-08-10 03:37:59 -07:00
assert_alive ( )
2024-01-12 10:59:57 -07:00
local arg_pesc = pesc ( fn.expand ( ' %:p:h:t ' ) )
2023-12-07 04:19:35 -07:00
matches (
( ' ^:!echo %s %s ' ) : format ( arg_pesc , arg_pesc ) ,
2024-01-12 10:59:57 -07:00
api.nvim_cmd ( { cmd = ' make ' , args = { ' %:p:h:t ' , ' %:p:h:t ' } } , { output = true } )
2023-12-07 04:19:35 -07:00
)
2022-08-10 03:37:59 -07:00
assert_alive ( )
end )
2024-01-26 23:03:44 -07:00
2023-12-07 04:19:35 -07:00
it ( " doesn't display messages when output=true " , function ( )
2022-08-16 02:30:39 -07:00
local screen = Screen.new ( 40 , 6 )
screen : attach ( )
2024-01-12 10:59:57 -07:00
api.nvim_cmd ( { cmd = ' echo ' , args = { [['hello']] } } , { output = true } )
2023-12-07 04:19:35 -07:00
screen : expect {
grid = [ [
2022-08-16 02:30:39 -07:00
^ |
2024-05-25 10:18:57 -07:00
{ 1 : ~ } |* 4
2022-08-16 02:30:39 -07:00
|
2023-12-07 04:19:35 -07:00
] ] ,
}
2022-08-16 02:30:39 -07:00
exec ( [ [
func Print ( )
call nvim_cmd ( # { cmd : ' echo ' , args : [ ' "hello" ' ] } , # { output : v : true } )
endfunc
] ] )
feed ( [[:echon 1 | call Print() | echon 5<CR>]] )
2023-12-07 04:19:35 -07:00
screen : expect {
grid = [ [
2022-08-16 02:30:39 -07:00
^ |
2024-05-25 10:18:57 -07:00
{ 1 : ~ } |* 4
2022-08-16 02:30:39 -07:00
15 |
2023-12-07 04:19:35 -07:00
] ] ,
}
2022-08-16 02:30:39 -07:00
end )
2024-01-26 23:03:44 -07:00
2022-09-28 04:43:18 -07:00
it ( ' works with non-String args ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( ' 2 ' , api.nvim_cmd ( { cmd = ' echo ' , args = { 2 } } , { output = true } ) )
eq ( ' 1 ' , api.nvim_cmd ( { cmd = ' echo ' , args = { true } } , { output = true } ) )
2022-09-28 04:43:18 -07:00
end )
2024-01-26 23:03:44 -07:00
2022-09-28 04:43:18 -07:00
describe ( ' first argument as count ' , function ( )
it ( ' works ' , function ( )
command ( ' vsplit | enew ' )
2024-01-12 10:59:57 -07:00
api.nvim_cmd ( { cmd = ' bdelete ' , args = { api.nvim_get_current_buf ( ) } } , { } )
2024-01-16 06:26:21 -07:00
eq ( 1 , api.nvim_get_current_buf ( ) )
2022-09-28 04:43:18 -07:00
end )
2024-01-26 23:03:44 -07:00
2022-09-28 04:43:18 -07:00
it ( ' works with :sleep using milliseconds ' , function ( )
2024-01-12 04:28:20 -07:00
local start = uv.now ( )
2024-01-12 10:59:57 -07:00
api.nvim_cmd ( { cmd = ' sleep ' , args = { ' 100m ' } } , { } )
2024-01-12 04:28:20 -07:00
ok ( uv.now ( ) - start <= 300 )
2022-09-28 04:43:18 -07:00
end )
end )
2024-01-26 23:03:44 -07:00
2023-11-30 22:56:04 -07:00
it ( ' :call with unknown function does not crash #26289 ' , function ( )
2023-12-07 04:19:35 -07:00
eq (
' Vim:E117: Unknown function: UnknownFunc ' ,
2024-01-12 10:59:57 -07:00
pcall_err ( api.nvim_cmd , { cmd = ' call ' , args = { ' UnknownFunc() ' } } , { } )
2023-12-07 04:19:35 -07:00
)
2023-11-30 22:56:04 -07:00
end )
2024-01-26 23:03:44 -07:00
2023-11-30 22:56:04 -07:00
it ( ' :throw does not crash #24556 ' , function ( )
2024-01-12 10:59:57 -07:00
eq ( ' 42 ' , pcall_err ( api.nvim_cmd , { cmd = ' throw ' , args = { ' 42 ' } } , { } ) )
2023-11-30 22:56:04 -07:00
end )
2024-01-26 23:03:44 -07:00
2023-11-30 22:56:04 -07:00
it ( ' can use :return #24556 ' , function ( )
exec ( [ [
func Foo ( )
let g : pos = ' before '
call nvim_cmd ( { ' cmd ' : ' return ' , ' args ' : [ ' [1, 2, 3] ' ] } , { } )
let g : pos = ' after '
endfunc
let g : result = Foo ( )
] ] )
2024-01-12 10:59:57 -07:00
eq ( ' before ' , api.nvim_get_var ( ' pos ' ) )
eq ( { 1 , 2 , 3 } , api.nvim_get_var ( ' result ' ) )
2023-11-30 22:56:04 -07:00
end )
2024-01-26 23:03:44 -07:00
it ( ' errors properly when command too recursive #27210 ' , function ( )
exec_lua ( [ [
_G.success = false
vim.api . nvim_create_user_command ( ' Test ' , function ( )
vim.api . nvim_cmd ( { cmd = ' Test ' } , { } )
_G.success = true
end , { } )
] ] )
pcall_err ( command , ' Test ' )
assert_alive ( )
eq ( false , exec_lua ( ' return _G.success ' ) )
end )
2022-05-08 04:39:45 -07:00
end )
2024-04-10 02:42:46 -07:00
it ( ' nvim__redraw ' , function ( )
local screen = Screen.new ( 60 , 5 )
screen : attach ( )
eq ( ' at least one action required ' , pcall_err ( api.nvim__redraw , { } ) )
eq ( ' at least one action required ' , pcall_err ( api.nvim__redraw , { buf = 0 } ) )
eq ( ' at least one action required ' , pcall_err ( api.nvim__redraw , { win = 0 } ) )
eq ( " cannot use both 'buf' and 'win' " , pcall_err ( api.nvim__redraw , { buf = 0 , win = 0 } ) )
2024-05-20 11:21:11 -07:00
local win = api.nvim_get_current_win ( )
-- Can move cursor to recently opened window and window is flushed #28868
2024-04-10 02:42:46 -07:00
feed ( ' :echo getchar()<CR> ' )
2024-05-20 11:21:11 -07:00
local newwin = api.nvim_open_win ( 0 , false , {
relative = ' editor ' ,
width = 1 ,
height = 1 ,
row = 1 ,
col = 10 ,
} )
api.nvim__redraw ( { win = newwin , cursor = true } )
screen : expect ( {
grid = [ [
|
{ 1 : ~ } { 4 : ^ } { 1 : } |
{ 1 : ~ } |* 2
: echo getchar ( ) |
] ] ,
} )
2024-04-10 02:42:46 -07:00
fn.setline ( 1 , ' foobar ' )
command ( ' vnew ' )
fn.setline ( 1 , ' foobaz ' )
-- Can flush pending screen updates
api.nvim__redraw ( { flush = true } )
screen : expect ( {
grid = [ [
foobaz │ foobar |
2024-05-20 11:21:11 -07:00
{ 1 : ~ } { 4 : ^ f } { 1 : } │ { 1 : ~ } |
{ 1 : ~ } │ { 1 : ~ } |
2024-04-10 02:42:46 -07:00
{ 3 : [ No Name ] [ + ] } { 2 : [ No Name ] [ + ] } |
2024-05-20 11:21:11 -07:00
: echo getchar ( ) |
2024-04-10 02:42:46 -07:00
] ] ,
} )
2024-05-20 11:21:11 -07:00
api.nvim_win_close ( newwin , true )
2024-04-10 02:42:46 -07:00
-- Can update the grid cursor position #20793
api.nvim__redraw ( { cursor = true } )
screen : expect ( {
grid = [ [
^ foobaz │ foobar |
{ 1 : ~ } │ { 1 : ~ } |* 2
{ 3 : [ No Name ] [ + ] } { 2 : [ No Name ] [ + ] } |
: echo getchar ( ) |
] ] ,
} )
-- Also in non-current window
api.nvim__redraw ( { cursor = true , win = win } )
screen : expect ( {
grid = [ [
foobaz │ ^ foobar |
{ 1 : ~ } │ { 1 : ~ } |* 2
{ 3 : [ No Name ] [ + ] } { 2 : [ No Name ] [ + ] } |
: echo getchar ( ) |
] ] ,
} )
-- Can update the 'statusline' in a single window
api.nvim_set_option_value ( ' statusline ' , ' statusline1 ' , { win = 0 } )
api.nvim_set_option_value ( ' statusline ' , ' statusline2 ' , { win = win } )
api.nvim__redraw ( { cursor = true , win = 0 , statusline = true } )
screen : expect ( {
grid = [ [
^ foobaz │ foobar |
{ 1 : ~ } │ { 1 : ~ } |* 2
{ 3 : statusline1 } { 2 : [ No Name ] [ + ] } |
: echo getchar ( ) |
] ] ,
} )
api.nvim__redraw ( { win = win , statusline = true } )
screen : expect ( {
grid = [ [
^ foobaz │ foobar |
{ 1 : ~ } │ { 1 : ~ } |* 2
{ 3 : statusline1 } { 2 : statusline2 } |
: echo getchar ( ) |
] ] ,
} )
-- Can update the 'statusline' in all windows
api.nvim_set_option_value ( ' statusline ' , ' ' , { win = win } )
api.nvim_set_option_value ( ' statusline ' , ' statusline3 ' , { } )
api.nvim__redraw ( { statusline = true } )
screen : expect ( {
grid = [ [
^ foobaz │ foobar |
{ 1 : ~ } │ { 1 : ~ } |* 2
{ 3 : statusline3 } { 2 : statusline3 } |
: echo getchar ( ) |
] ] ,
} )
-- Can update the 'statuscolumn'
api.nvim_set_option_value ( ' statuscolumn ' , ' statuscolumn ' , { win = win } )
api.nvim__redraw ( { statuscolumn = true } )
screen : expect ( {
grid = [ [
^ foobaz │ { 8 : statuscolumn } foobar |
{ 1 : ~ } │ { 1 : ~ } |* 2
{ 3 : statusline3 } { 2 : statusline3 } |
: echo getchar ( ) |
] ] ,
} )
-- Can update the 'winbar'
api.nvim_set_option_value ( ' winbar ' , ' winbar ' , { win = 0 } )
api.nvim__redraw ( { win = 0 , winbar = true } )
screen : expect ( {
grid = [ [
{ 5 : ^ winbar } │ { 8 : statuscolumn } foobar |
foobaz │ { 1 : ~ } |
{ 1 : ~ } │ { 1 : ~ } |
{ 3 : statusline3 } { 2 : statusline3 } |
: echo getchar ( ) |
] ] ,
} )
-- Can update the 'tabline'
api.nvim_set_option_value ( ' showtabline ' , 2 , { } )
api.nvim_set_option_value ( ' tabline ' , ' tabline ' , { } )
api.nvim__redraw ( { tabline = true } )
screen : expect ( {
grid = [ [
{ 2 : ^ tabline } |
{ 5 : winbar } │ { 8 : statuscolumn } foobar |
foobaz │ { 1 : ~ } |
{ 3 : statusline3 } { 2 : statusline3 } |
: echo getchar ( ) |
] ] ,
} )
-- Can update multiple status widgets
api.nvim_set_option_value ( ' tabline ' , ' tabline2 ' , { } )
api.nvim_set_option_value ( ' statusline ' , ' statusline4 ' , { } )
api.nvim__redraw ( { statusline = true , tabline = true } )
screen : expect ( {
grid = [ [
{ 2 : ^ tabline2 } |
{ 5 : winbar } │ { 8 : statuscolumn } foobar |
foobaz │ { 1 : ~ } |
{ 3 : statusline4 } { 2 : statusline4 } |
: echo getchar ( ) |
] ] ,
} )
-- Can update all status widgets
api.nvim_set_option_value ( ' tabline ' , ' tabline3 ' , { } )
api.nvim_set_option_value ( ' statusline ' , ' statusline5 ' , { } )
api.nvim_set_option_value ( ' statuscolumn ' , ' statuscolumn2 ' , { } )
api.nvim_set_option_value ( ' winbar ' , ' winbar2 ' , { } )
api.nvim__redraw ( { statuscolumn = true , statusline = true , tabline = true , winbar = true } )
screen : expect ( {
grid = [ [
{ 2 : ^ tabline3 } |
{ 5 : winbar2 } │ { 5 : winbar2 } |
{ 8 : statuscolumn2 } foobaz │ { 8 : statuscolumn } foobar |
{ 3 : statusline5 } { 2 : statusline5 } |
: echo getchar ( ) |
] ] ,
} )
-- Can update status widget for a specific window
feed ( ' <CR><CR> ' )
command ( ' let g:status=0 ' )
api.nvim_set_option_value ( ' statusline ' , ' %{%g:status%} ' , { win = 0 } )
command ( ' vsplit ' )
screen : expect ( {
grid = [ [
{ 2 : tabline3 } |
{ 5 : winbar2 } │ { 5 : winbar2 } │ { 5 : winbar2 } |
{ 8 : statuscolumn2 } ^ foobaz │ { 8 : statuscolumn2 } foobaz │ { 8 : statuscolumn } foobar |
{ 3 : 0 } { 2 : 0 statusline5 } |
13 |
] ] ,
} )
command ( ' let g:status=1 ' )
api.nvim__redraw ( { win = 0 , statusline = true } )
screen : expect ( {
grid = [ [
{ 2 : tabline3 } |
{ 5 : winbar2 } │ { 5 : winbar2 } │ { 5 : winbar2 } |
{ 8 : statuscolumn2 } ^ foobaz │ { 8 : statuscolumn2 } foobaz │ { 8 : statuscolumn } foobar |
{ 3 : 1 } { 2 : 0 statusline5 } |
13 |
] ] ,
} )
-- Can update status widget for a specific buffer
command ( ' let g:status=2 ' )
api.nvim__redraw ( { buf = 0 , statusline = true } )
screen : expect ( {
grid = [ [
{ 2 : tabline3 } |
{ 5 : winbar2 } │ { 5 : winbar2 } │ { 5 : winbar2 } |
{ 8 : statuscolumn2 } ^ foobaz │ { 8 : statuscolumn2 } foobaz │ { 8 : statuscolumn } foobar |
{ 3 : 2 } { 2 : 2 statusline5 } |
13 |
] ] ,
} )
-- valid = true does not draw any lines on its own
exec_lua ( [ [
2024-05-02 19:35:32 -07:00
_G.lines = 0
2024-04-10 02:42:46 -07:00
ns = vim.api . nvim_create_namespace ( ' ' )
vim.api . nvim_set_decoration_provider ( ns , {
2024-05-02 19:35:32 -07:00
on_win = function ( )
if _G.do_win then
vim.api . nvim_buf_set_extmark ( 0 , ns , 0 , 0 , { hl_group = ' IncSearch ' , end_col = 6 } )
end
end ,
2024-04-10 02:42:46 -07:00
on_line = function ( )
2024-05-02 19:35:32 -07:00
_G.lines = _G.lines + 1
2024-04-10 02:42:46 -07:00
end ,
} )
] ] )
local lines = exec_lua ( ' return lines ' )
api.nvim__redraw ( { buf = 0 , valid = true , flush = true } )
2024-05-02 19:35:32 -07:00
eq ( lines , exec_lua ( ' return _G.lines ' ) )
2024-04-10 02:42:46 -07:00
-- valid = false does
api.nvim__redraw ( { buf = 0 , valid = false , flush = true } )
2024-05-02 19:35:32 -07:00
neq ( lines , exec_lua ( ' return _G.lines ' ) )
2024-04-10 02:42:46 -07:00
-- valid = true does redraw lines if affected by on_win callback
2024-05-02 19:35:32 -07:00
exec_lua ( ' _G.do_win = true ' )
2024-04-10 02:42:46 -07:00
api.nvim__redraw ( { buf = 0 , valid = true , flush = true } )
screen : expect ( {
grid = [ [
{ 2 : tabline3 } |
{ 5 : winbar2 } │ { 5 : winbar2 } │ { 5 : winbar2 } |
{ 8 : statuscolumn2 } { 2 : ^ foobaz } │ { 8 : statuscolumn2 } { 2 : foobaz } │ { 8 : statuscolumn } foobar |
{ 3 : 2 } { 2 : 2 statusline5 } |
13 |
] ] ,
} )
2024-05-02 19:35:32 -07:00
-- takes buffer line count from correct buffer with "win" and {0, -1} "range"
api.nvim__redraw ( { win = 0 , range = { 0 , - 1 } } )
n.assert_alive ( )
2024-04-10 02:42:46 -07:00
end )
2014-10-08 09:56:01 -07:00
end )