mirror of
https://github.com/neovim/neovim.git
synced 2024-12-23 12:45:17 -07:00
Merge 2e94406ba0
into 02bc40c194
This commit is contained in:
commit
630e8b8919
@ -27,6 +27,7 @@
|
|||||||
#include "nvim/mbyte.h"
|
#include "nvim/mbyte.h"
|
||||||
#include "nvim/memory.h"
|
#include "nvim/memory.h"
|
||||||
#include "nvim/ops.h"
|
#include "nvim/ops.h"
|
||||||
|
#include "nvim/optionstr.h"
|
||||||
#include "nvim/pos_defs.h"
|
#include "nvim/pos_defs.h"
|
||||||
#include "nvim/regexp.h"
|
#include "nvim/regexp.h"
|
||||||
#include "nvim/strings.h"
|
#include "nvim/strings.h"
|
||||||
@ -317,7 +318,6 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Arena
|
|||||||
char *cmdline = NULL;
|
char *cmdline = NULL;
|
||||||
char *cmdname = NULL;
|
char *cmdname = NULL;
|
||||||
ArrayOf(String) args = ARRAY_DICT_INIT;
|
ArrayOf(String) args = ARRAY_DICT_INIT;
|
||||||
|
|
||||||
String retv = (String)STRING_INIT;
|
String retv = (String)STRING_INIT;
|
||||||
|
|
||||||
#define OBJ_TO_BOOL(var, value, default, varname) \
|
#define OBJ_TO_BOOL(var, value, default, varname) \
|
||||||
@ -633,6 +633,24 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Arena
|
|||||||
build_cmdline_str(&cmdline, &ea, &cmdinfo, args);
|
build_cmdline_str(&cmdline, &ea, &cmdinfo, args);
|
||||||
ea.cmdlinep = &cmdline;
|
ea.cmdlinep = &cmdline;
|
||||||
|
|
||||||
|
// set when Not Implemented
|
||||||
|
const int ni = is_cmd_ni(ea.cmdidx);
|
||||||
|
|
||||||
|
// Check for "++opt=val" argument.
|
||||||
|
if (ea.argt & EX_ARGOPT) {
|
||||||
|
while (ea.arg[0] == '+' && ea.arg[1] == '+') {
|
||||||
|
if (getargopt(&ea) == FAIL && !ni) {
|
||||||
|
api_set_error(err, kErrorTypeValidation, "Invalid argument");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for "+command" argument.
|
||||||
|
if ((ea.argt & EX_CMDARG) && !ea.usefilter) {
|
||||||
|
ea.do_ecmd_cmd = getargcmd(&ea.arg);
|
||||||
|
}
|
||||||
|
|
||||||
garray_T capture_local;
|
garray_T capture_local;
|
||||||
const int save_msg_silent = msg_silent;
|
const int save_msg_silent = msg_silent;
|
||||||
garray_T * const save_capture_ga = capture_ga;
|
garray_T * const save_capture_ga = capture_ga;
|
||||||
|
@ -4135,7 +4135,7 @@ void separate_nextcmd(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// get + command from ex argument
|
/// get + command from ex argument
|
||||||
static char *getargcmd(char **argp)
|
char *getargcmd(char **argp)
|
||||||
{
|
{
|
||||||
char *arg = *argp;
|
char *arg = *argp;
|
||||||
char *command = NULL;
|
char *command = NULL;
|
||||||
@ -4210,7 +4210,7 @@ static char *get_bad_name(expand_T *xp FUNC_ATTR_UNUSED, int idx)
|
|||||||
/// Get "++opt=arg" argument.
|
/// Get "++opt=arg" argument.
|
||||||
///
|
///
|
||||||
/// @return FAIL or OK.
|
/// @return FAIL or OK.
|
||||||
static int getargopt(exarg_T *eap)
|
int getargopt(exarg_T *eap)
|
||||||
{
|
{
|
||||||
char *arg = eap->arg + 2;
|
char *arg = eap->arg + 2;
|
||||||
int *pp = NULL;
|
int *pp = NULL;
|
||||||
|
@ -5388,4 +5388,156 @@ describe('API', function()
|
|||||||
api.nvim__redraw({ win = 0, range = { 0, -1 } })
|
api.nvim__redraw({ win = 0, range = { 0, -1 } })
|
||||||
n.assert_alive()
|
n.assert_alive()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
describe('nvim_cmd with plus #flags', function()
|
||||||
|
it('handles +flags correctly', function()
|
||||||
|
-- Write a file for testing +flags
|
||||||
|
command(':call writefile(["Line 1", "Line 2", "Line 3"], "testfile")')
|
||||||
|
|
||||||
|
-- Test + command (go to the last line)
|
||||||
|
local result = exec_lua([[
|
||||||
|
vim.cmd(vim.api.nvim_parse_cmd('edit + testfile', {}))
|
||||||
|
return vim.fn.line('.')
|
||||||
|
]])
|
||||||
|
eq(3, result)
|
||||||
|
|
||||||
|
-- Test +{num} command (go to line number)
|
||||||
|
result = exec_lua([[
|
||||||
|
vim.cmd(vim.api.nvim_parse_cmd('edit +1 testfile', {}))
|
||||||
|
return vim.fn.line('.')
|
||||||
|
]])
|
||||||
|
eq(1, result)
|
||||||
|
|
||||||
|
-- Test +/{pattern} command (go to line with pattern)
|
||||||
|
result = exec_lua([[
|
||||||
|
vim.cmd(vim.api.nvim_parse_cmd('edit +/Line\\ 2 testfile', {}))
|
||||||
|
return vim.fn.line('.')
|
||||||
|
]])
|
||||||
|
eq(2, result)
|
||||||
|
|
||||||
|
-- Test +{command} command (execute a command after opening the file)
|
||||||
|
result = exec_lua([[
|
||||||
|
vim.cmd(vim.api.nvim_parse_cmd('edit +set\\ nomodifiable testfile', {}))
|
||||||
|
return vim.bo.modifiable
|
||||||
|
]])
|
||||||
|
eq(false, result)
|
||||||
|
|
||||||
|
-- Clean up
|
||||||
|
os.remove('testfile')
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('handles various ++ flags correctly', function()
|
||||||
|
-- Test ++ff flag
|
||||||
|
exec_lua [[
|
||||||
|
vim.cmd(vim.api.nvim_parse_cmd('edit ++ff=mac test_ff_mac.txt', {}))
|
||||||
|
]]
|
||||||
|
eq('mac', api.nvim_get_option_value('fileformat', {}))
|
||||||
|
eq('test_ff_mac.txt', fn.fnamemodify(api.nvim_buf_get_name(0), ':t'))
|
||||||
|
|
||||||
|
exec_lua [[
|
||||||
|
vim.cmd(vim.api.nvim_parse_cmd('edit ++fileformat=unix test_ff_unix.txt', {}))
|
||||||
|
]]
|
||||||
|
eq('unix', api.nvim_get_option_value('fileformat', {}))
|
||||||
|
eq('test_ff_unix.txt', fn.fnamemodify(api.nvim_buf_get_name(0), ':t'))
|
||||||
|
|
||||||
|
-- Test ++enc flag
|
||||||
|
exec_lua [[
|
||||||
|
vim.cmd(vim.api.nvim_parse_cmd('edit ++enc=utf-32 test_enc.txt', {}))
|
||||||
|
]]
|
||||||
|
eq('ucs-4', api.nvim_get_option_value('fileencoding', {}))
|
||||||
|
eq('test_enc.txt', fn.fnamemodify(api.nvim_buf_get_name(0), ':t'))
|
||||||
|
|
||||||
|
-- Test ++bin and ++nobin flags
|
||||||
|
exec_lua [[
|
||||||
|
vim.cmd(vim.api.nvim_parse_cmd('edit ++bin test_bin.txt', {}))
|
||||||
|
]]
|
||||||
|
eq(true, api.nvim_get_option_value('binary', {}))
|
||||||
|
eq('test_bin.txt', fn.fnamemodify(api.nvim_buf_get_name(0), ':t'))
|
||||||
|
|
||||||
|
exec_lua [[
|
||||||
|
vim.cmd(vim.api.nvim_parse_cmd('edit ++nobin test_nobin.txt', {}))
|
||||||
|
]]
|
||||||
|
eq(false, api.nvim_get_option_value('binary', {}))
|
||||||
|
eq('test_nobin.txt', fn.fnamemodify(api.nvim_buf_get_name(0), ':t'))
|
||||||
|
|
||||||
|
-- Test multiple flags together
|
||||||
|
exec_lua [[
|
||||||
|
vim.cmd(vim.api.nvim_parse_cmd('edit ++ff=mac ++enc=utf-32 ++bin test_multi.txt', {}))
|
||||||
|
]]
|
||||||
|
eq(true, api.nvim_get_option_value('binary', {}))
|
||||||
|
eq('mac', api.nvim_get_option_value('fileformat', {}))
|
||||||
|
eq('ucs-4', api.nvim_get_option_value('fileencoding', {}))
|
||||||
|
eq('test_multi.txt', fn.fnamemodify(api.nvim_buf_get_name(0), ':t'))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('handles invalid and incorrect ++ flags gracefully', function()
|
||||||
|
-- Test invalid ++ff flag
|
||||||
|
local result = exec_lua [[
|
||||||
|
local cmd = vim.api.nvim_parse_cmd('edit ++ff=invalid test_invalid_ff.txt', {})
|
||||||
|
local _, err = pcall(vim.cmd, cmd)
|
||||||
|
return err
|
||||||
|
]]
|
||||||
|
eq('Invalid argument', result)
|
||||||
|
|
||||||
|
-- Test incorrect ++ syntax
|
||||||
|
result = exec_lua [[
|
||||||
|
local cmd = vim.api.nvim_parse_cmd('edit ++unknown=test_unknown.txt', {})
|
||||||
|
local _, err = pcall(vim.cmd, cmd)
|
||||||
|
return err
|
||||||
|
]]
|
||||||
|
eq('Invalid argument', result)
|
||||||
|
|
||||||
|
-- Test invalid ++bin flag
|
||||||
|
result = exec_lua [[
|
||||||
|
local cmd = vim.api.nvim_parse_cmd('edit ++binabc test_invalid_bin.txt', {})
|
||||||
|
local _, err = pcall(vim.cmd, cmd)
|
||||||
|
return err
|
||||||
|
]]
|
||||||
|
eq('Invalid argument', result)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('handles ++p for creating parent directory', function()
|
||||||
|
exec_lua [[
|
||||||
|
vim.cmd('edit flags_dir/test_create.txt')
|
||||||
|
vim.cmd(vim.api.nvim_parse_cmd('write! ++p', {}))
|
||||||
|
]]
|
||||||
|
eq(true, fn.isdirectory('flags_dir') == 1)
|
||||||
|
fn.delete('flags_dir', 'rf')
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('tests editing files with bad utf8 sequences', function()
|
||||||
|
-- Write a file with bad utf8 sequences
|
||||||
|
local file = io.open('Xfile', 'wb')
|
||||||
|
file:write('[\255][\192][\226\137\240][\194\194]')
|
||||||
|
file:close()
|
||||||
|
|
||||||
|
exec_lua([[
|
||||||
|
vim.cmd(vim.api.nvim_parse_cmd('edit! ++enc=utf8 Xfile', {}))
|
||||||
|
]])
|
||||||
|
eq('[?][?][???][??]', api.nvim_get_current_line())
|
||||||
|
|
||||||
|
exec_lua([[
|
||||||
|
vim.cmd(vim.api.nvim_parse_cmd('edit! ++enc=utf8 ++bad=_ Xfile', {}))
|
||||||
|
]])
|
||||||
|
eq('[_][_][___][__]', api.nvim_get_current_line())
|
||||||
|
|
||||||
|
exec_lua([[
|
||||||
|
vim.cmd(vim.api.nvim_parse_cmd('edit! ++enc=utf8 ++bad=drop Xfile', {}))
|
||||||
|
]])
|
||||||
|
eq('[][][][]', api.nvim_get_current_line())
|
||||||
|
|
||||||
|
exec_lua([[
|
||||||
|
vim.cmd(vim.api.nvim_parse_cmd('edit! ++enc=utf8 ++bad=keep Xfile', {}))
|
||||||
|
]])
|
||||||
|
eq('[\255][\192][\226\137\240][\194\194]', api.nvim_get_current_line())
|
||||||
|
|
||||||
|
local result = exec_lua([[
|
||||||
|
local _, err = pcall(vim.cmd, vim.api.nvim_parse_cmd('edit ++enc=utf8 ++bad=foo Xfile', {}))
|
||||||
|
return err
|
||||||
|
]])
|
||||||
|
eq('Invalid argument', result)
|
||||||
|
-- Clean up
|
||||||
|
os.remove('Xfile')
|
||||||
|
end)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user