aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/eval/funcs.c11
-rw-r--r--src/nvim/ex_cmds.c8
-rw-r--r--src/nvim/ex_getln.c7
-rw-r--r--src/nvim/tui/input.c24
-rw-r--r--src/nvim/tui/input.h3
-rw-r--r--src/nvim/tui/tui.c3
-rw-r--r--src/nvim/version.c2
-rw-r--r--test/functional/helpers.lua9
-rw-r--r--test/functional/terminal/api_spec.lua2
-rw-r--r--test/functional/terminal/buffer_spec.lua50
-rw-r--r--test/functional/terminal/highlight_spec.lua2
-rw-r--r--test/functional/terminal/tui_spec.lua13
-rw-r--r--test/functional/ui/inccommand_spec.lua336
-rw-r--r--test/functional/ui/options_spec.lua9
-rw-r--r--test/functional/ui/output_spec.lua2
-rw-r--r--test/unit/helpers.lua7
16 files changed, 326 insertions, 162 deletions
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 0054c47678..4029478072 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -3898,12 +3898,13 @@ static void f_jobresize(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
rettv->vval.v_number = 1;
}
-static const char *ignored_env_vars[] = {
+static const char *pty_ignored_env_vars[] = {
#ifndef MSWIN
"COLUMNS",
"LINES",
"TERMCAP",
"COLORFGBG",
+ "COLORTERM",
#endif
NULL
};
@@ -3943,9 +3944,9 @@ static dict_T *create_environment(const dictitem_T *job_env, const bool clear_en
// child process. We're removing them here so the user can still decide
// they want to explicitly set them.
for (size_t i = 0;
- i < ARRAY_SIZE(ignored_env_vars) && ignored_env_vars[i];
+ i < ARRAY_SIZE(pty_ignored_env_vars) && pty_ignored_env_vars[i];
i++) {
- dictitem_T *dv = tv_dict_find(env, ignored_env_vars[i], -1);
+ dictitem_T *dv = tv_dict_find(env, pty_ignored_env_vars[i], -1);
if (dv) {
tv_dict_item_remove(env, dv);
}
@@ -3953,10 +3954,6 @@ static dict_T *create_environment(const dictitem_T *job_env, const bool clear_en
#ifndef MSWIN
// Set COLORTERM to "truecolor" if termguicolors is set
if (p_tgc) {
- dictitem_T *dv = tv_dict_find(env, S_LEN("COLORTERM"));
- if (dv) {
- tv_dict_item_remove(env, dv);
- }
tv_dict_add_str(env, S_LEN("COLORTERM"), "truecolor");
}
#endif
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 0711d82fe5..68c316fde0 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -4580,7 +4580,6 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i
}
// Width of the "| lnum|..." column which displays the line numbers.
- linenr_T highest_num_line = 0;
int col_width = 0;
// Use preview window only when inccommand=split and range is not just the current line
bool preview = (*p_icm == 's') && (eap->line1 != old_cusr.lnum || eap->line2 != old_cusr.lnum);
@@ -4590,8 +4589,11 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i
assert(cmdpreview_buf != NULL);
if (lines.subresults.size > 0) {
- highest_num_line = kv_last(lines.subresults).end.lnum;
- col_width = (int)log10(highest_num_line) + 1 + 3;
+ SubResult last_match = kv_last(lines.subresults);
+ // `last_match.end.lnum` may be 0 when using 'n' flag.
+ linenr_T highest_lnum = MAX(last_match.start.lnum, last_match.end.lnum);
+ assert(highest_lnum > 0);
+ col_width = (int)log10(highest_lnum) + 1 + 3;
}
}
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index f31f8fec55..14d230331a 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -152,6 +152,8 @@ typedef struct cmdpreview_buf_info {
buf_T *buf;
OptInt save_b_p_ul;
int save_b_changed;
+ pos_T save_b_op_start;
+ pos_T save_b_op_end;
varnumber_T save_changedtick;
CpUndoInfo undo_info;
} CpBufInfo;
@@ -2360,6 +2362,8 @@ static void cmdpreview_prepare(CpInfo *cpinfo)
cp_bufinfo.buf = buf;
cp_bufinfo.save_b_p_ul = buf->b_p_ul;
cp_bufinfo.save_b_changed = buf->b_changed;
+ cp_bufinfo.save_b_op_start = buf->b_op_start;
+ cp_bufinfo.save_b_op_end = buf->b_op_end;
cp_bufinfo.save_changedtick = buf_get_changedtick(buf);
cmdpreview_save_undo(&cp_bufinfo.undo_info, buf);
kv_push(cpinfo->buf_info, cp_bufinfo);
@@ -2438,6 +2442,9 @@ static void cmdpreview_restore_state(CpInfo *cpinfo)
u_blockfree(buf);
cmdpreview_restore_undo(&cp_bufinfo.undo_info, buf);
+ buf->b_op_start = cp_bufinfo.save_b_op_start;
+ buf->b_op_end = cp_bufinfo.save_b_op_end;
+
if (cp_bufinfo.save_changedtick != buf_get_changedtick(buf)) {
buf_set_changedtick(buf, cp_bufinfo.save_changedtick);
}
diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c
index c533b288c1..6c47d1b5c7 100644
--- a/src/nvim/tui/input.c
+++ b/src/nvim/tui/input.c
@@ -156,14 +156,15 @@ void tinput_init(TermInput *input, Loop *loop)
rstream_init_fd(loop, &input->read_stream, input->in_fd, READ_STREAM_SIZE);
// initialize a timer handle for handling ESC with libtermkey
- time_watcher_init(loop, &input->timer_handle, input);
+ uv_timer_init(&loop->uv, &input->timer_handle);
+ input->timer_handle.data = input;
}
void tinput_destroy(TermInput *input)
{
map_destroy(int, &kitty_key_map);
rbuffer_free(input->key_buffer);
- time_watcher_close(&input->timer_handle, NULL);
+ uv_close((uv_handle_t *)&input->timer_handle, NULL);
stream_close(&input->read_stream, NULL, NULL);
termkey_destroy(input->tk);
}
@@ -176,7 +177,7 @@ void tinput_start(TermInput *input)
void tinput_stop(TermInput *input)
{
rstream_stop(&input->read_stream);
- time_watcher_stop(&input->timer_handle);
+ uv_timer_stop(&input->timer_handle);
}
static void tinput_done_event(void **argv)
@@ -466,17 +467,16 @@ static void tk_getkeys(TermInput *input, bool force)
if (input->ttimeout && input->ttimeoutlen >= 0) {
// Stop the current timer if already running
- time_watcher_stop(&input->timer_handle);
- time_watcher_start(&input->timer_handle, tinput_timer_cb,
- (uint64_t)input->ttimeoutlen, 0);
+ uv_timer_stop(&input->timer_handle);
+ uv_timer_start(&input->timer_handle, tinput_timer_cb, (uint64_t)input->ttimeoutlen, 0);
} else {
tk_getkeys(input, true);
}
}
-static void tinput_timer_cb(TimeWatcher *watcher, void *data)
+static void tinput_timer_cb(uv_timer_t *handle)
{
- TermInput *input = (TermInput *)data;
+ TermInput *input = handle->data;
// If the raw buffer is not empty, process the raw buffer first because it is
// processing an incomplete bracketed paster sequence.
if (rbuffer_size(input->read_stream.buffer)) {
@@ -489,8 +489,8 @@ static void tinput_timer_cb(TimeWatcher *watcher, void *data)
/// Handle focus events.
///
/// If the upcoming sequence of bytes in the input stream matches the termcode
-/// for "focus gained" or "focus lost", consume that sequence and schedule an
-/// event on the main loop.
+/// for "focus gained" or "focus lost", consume that sequence and send an event
+/// to Nvim server.
///
/// @param input the input stream
/// @return true iff handle_focus_event consumed some input
@@ -757,8 +757,8 @@ static void tinput_read_cb(Stream *stream, RBuffer *buf, size_t count_, void *da
int64_t ms = input->ttimeout
? (input->ttimeoutlen >= 0 ? input->ttimeoutlen : 0) : 0;
// Stop the current timer if already running
- time_watcher_stop(&input->timer_handle);
- time_watcher_start(&input->timer_handle, tinput_timer_cb, (uint32_t)ms, 0);
+ uv_timer_stop(&input->timer_handle);
+ uv_timer_start(&input->timer_handle, tinput_timer_cb, (uint32_t)ms, 0);
return;
}
diff --git a/src/nvim/tui/input.h b/src/nvim/tui/input.h
index 9d276277de..bc490754be 100644
--- a/src/nvim/tui/input.h
+++ b/src/nvim/tui/input.h
@@ -6,7 +6,6 @@
#include "nvim/event/loop.h"
#include "nvim/event/stream.h"
-#include "nvim/event/time.h"
#include "nvim/rbuffer_defs.h"
#include "nvim/tui/input_defs.h" // IWYU pragma: export
#include "nvim/tui/tui.h"
@@ -33,7 +32,7 @@ typedef struct {
OptInt ttimeoutlen;
TermKey *tk;
TermKey_Terminfo_Getstr_Hook *tk_ti_hook_fn; ///< libtermkey terminfo hook
- TimeWatcher timer_handle;
+ uv_timer_t timer_handle;
Loop *loop;
Stream read_stream;
RBuffer *key_buffer;
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index d625c22c76..f500994229 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -170,8 +170,7 @@ void tui_start(TUIData **tui_p, int *width, int *height, char **term, bool *rgb)
uv_timer_init(&tui->loop->uv, &tui->startup_delay_timer);
tui->startup_delay_timer.data = tui;
- uv_timer_start(&tui->startup_delay_timer, after_startup_cb,
- 100, 0);
+ uv_timer_start(&tui->startup_delay_timer, after_startup_cb, 100, 0);
*tui_p = tui;
loop_poll_events(&main_loop, 1);
diff --git a/src/nvim/version.c b/src/nvim/version.c
index fc93a01b32..2caf2c0cb8 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -896,7 +896,7 @@ static const int included_patches[] = {
// 1586,
1585,
// 1584,
- // 1583,
+ 1583,
1582,
1581,
// 1580,
diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua
index 5780d0a978..449c3ab9d8 100644
--- a/test/functional/helpers.lua
+++ b/test/functional/helpers.lua
@@ -28,17 +28,16 @@ module.nvim_prog = (
)
-- Default settings for the test session.
module.nvim_set = (
- 'set shortmess+=IS background=light noswapfile noautoindent startofline'
+ 'set shortmess+=IS background=light termguicolors noswapfile noautoindent startofline'
..' laststatus=1 undodir=. directory=. viewdir=. backupdir=.'
- ..' belloff= wildoptions-=pum joinspaces noshowcmd noruler nomore redrawdebug=invalid'
- ..' notermguicolors')
+ ..' belloff= wildoptions-=pum joinspaces noshowcmd noruler nomore redrawdebug=invalid')
module.nvim_argv = {
module.nvim_prog, '-u', 'NONE', '-i', 'NONE',
-- XXX: find treesitter parsers.
'--cmd', runtime_set,
'--cmd', module.nvim_set,
- '--cmd', 'mapclear',
- '--cmd', 'mapclear!',
+ -- Remove default mappings.
+ '--cmd', 'mapclear | mapclear!',
-- Make screentest work after changing to the new default color scheme
-- Source 'vim' color scheme without side effects
-- TODO: rewrite tests
diff --git a/test/functional/terminal/api_spec.lua b/test/functional/terminal/api_spec.lua
index 68082ba4fa..117a5b74b7 100644
--- a/test/functional/terminal/api_spec.lua
+++ b/test/functional/terminal/api_spec.lua
@@ -15,7 +15,7 @@ describe('api', function()
'-u', 'NONE',
'-i', 'NONE',
'--cmd', 'colorscheme vim',
- '--cmd', helpers.nvim_set,
+ '--cmd', helpers.nvim_set .. ' notermguicolors',
})
end)
after_each(function()
diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua
index 7a52ee2b13..ece09bca88 100644
--- a/test/functional/terminal/buffer_spec.lua
+++ b/test/functional/terminal/buffer_spec.lua
@@ -1,8 +1,10 @@
local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
local thelpers = require('test.functional.terminal.helpers')
local assert_alive = helpers.assert_alive
local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim
local poke_eventloop = helpers.poke_eventloop
+local nvim_prog = helpers.nvim_prog
local eval, feed_command, source = helpers.eval, helpers.feed_command, helpers.source
local pcall_err = helpers.pcall_err
local eq, neq = helpers.eq, helpers.neq
@@ -559,4 +561,52 @@ describe('termopen()', function()
eq("Vim:E11: Invalid in command-line window; <CR> executes, CTRL-C quits",
pcall_err(funcs.termopen, "bar"))
end)
+
+ describe('$COLORTERM value', function()
+ if skip(is_os('win'), 'Not applicable for Windows') then return end
+
+ before_each(function()
+ -- Outer value should never be propagated to :terminal
+ funcs.setenv('COLORTERM', 'wrongvalue')
+ end)
+
+ local function test_term_colorterm(expected, opts)
+ local screen = Screen.new(50, 4)
+ screen:attach()
+ funcs.termopen({
+ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless',
+ '-c', 'echo $COLORTERM | quit',
+ }, opts)
+ screen:expect(([[
+ ^%s{MATCH:%%s+}|
+ [Process exited 0] |
+ |
+ |
+ ]]):format(expected))
+ end
+
+ describe("with 'notermguicolors'", function()
+ before_each(function()
+ command('set notermguicolors')
+ end)
+ it('is empty by default', function()
+ test_term_colorterm('')
+ end)
+ it('can be overridden', function()
+ test_term_colorterm('expectedvalue', { env = { COLORTERM = 'expectedvalue' } })
+ end)
+ end)
+
+ describe("with 'termguicolors'", function()
+ before_each(function()
+ command('set termguicolors')
+ end)
+ it('is "truecolor" by default', function()
+ test_term_colorterm('truecolor')
+ end)
+ it('can be overridden', function()
+ test_term_colorterm('expectedvalue', { env = { COLORTERM = 'expectedvalue' } })
+ end)
+ end)
+ end)
end)
diff --git a/test/functional/terminal/highlight_spec.lua b/test/functional/terminal/highlight_spec.lua
index 2ac45771d4..4754d14052 100644
--- a/test/functional/terminal/highlight_spec.lua
+++ b/test/functional/terminal/highlight_spec.lua
@@ -143,7 +143,7 @@ it(':terminal highlight has lower precedence than editor #9964', function()
screen:attach({rgb=true})
-- Child nvim process in :terminal (with cterm colors).
funcs.termopen({
- nvim_prog_abs(), '-n', '-u', 'NORC', '-i', 'NONE', '--cmd', nvim_set,
+ nvim_prog_abs(), '-n', '-u', 'NORC', '-i', 'NONE', '--cmd', nvim_set .. ' notermguicolors',
'+hi Normal ctermfg=Blue ctermbg=Yellow',
'+norm! ichild nvim',
'+norm! oline 2',
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index a3043ab470..362f1fc1ee 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -43,7 +43,7 @@ describe('TUI', function()
'--listen', child_server,
'-u', 'NONE',
'-i', 'NONE',
- '--cmd', string.format('%s laststatus=2 background=dark', nvim_set),
+ '--cmd', nvim_set .. ' notermguicolors laststatus=2 background=dark',
'--cmd', 'colorscheme vim'
})
screen:expect([[
@@ -2217,7 +2217,7 @@ describe("TUI 't_Co' (terminal colors)", function()
'-u', 'NONE',
'-i', 'NONE',
'--cmd', 'colorscheme vim',
- '--cmd', nvim_set,
+ '--cmd', nvim_set .. ' notermguicolors',
}, {
env = {
LANG = 'C',
@@ -2495,7 +2495,7 @@ describe("TUI 'term' option", function()
screen = thelpers.setup_child_nvim({
'-u', 'NONE',
'-i', 'NONE',
- '--cmd', nvim_set,
+ '--cmd', nvim_set .. ' notermguicolors',
}, {
env = {
LANG = 'C',
@@ -2555,7 +2555,7 @@ describe("TUI", function()
'-u', 'NONE',
'-i', 'NONE',
'--cmd', 'colorscheme vim',
- '--cmd', nvim_set,
+ '--cmd', nvim_set .. ' notermguicolors',
extra_args,
}, {
env = {
@@ -2753,7 +2753,7 @@ describe("TUI as a client", function()
'-u', 'NONE',
'-i', 'NONE',
'--cmd', 'colorscheme vim',
- '--cmd', string.format('%s laststatus=2 background=dark', nvim_set),
+ '--cmd', nvim_set .. ' notermguicolors laststatus=2 background=dark',
})
feed_data("iHello, World")
@@ -2819,6 +2819,7 @@ describe("TUI as a client", function()
set_session(server)
local server_pipe = meths.get_vvar('servername')
server:request('nvim_input', 'iHalloj!<Esc>')
+ server:request('nvim_command', 'set notermguicolors')
set_session(client_super)
local screen_client = thelpers.setup_child_nvim({
@@ -2887,7 +2888,7 @@ describe("TUI as a client", function()
'-u', 'NONE',
'-i', 'NONE',
'--cmd', 'colorscheme vim',
- '--cmd', string.format('%s laststatus=2 background=dark', nvim_set),
+ '--cmd', nvim_set .. ' notermguicolors laststatus=2 background=dark',
})
screen_server:expect{grid=[[
{1: } |
diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua
index 3ee67a710c..351abcea2c 100644
--- a/test/functional/ui/inccommand_spec.lua
+++ b/test/functional/ui/inccommand_spec.lua
@@ -4,10 +4,10 @@ local clear = helpers.clear
local command = helpers.command
local eq = helpers.eq
local eval = helpers.eval
-local feed_command = helpers.feed_command
local expect = helpers.expect
local feed = helpers.feed
local insert = helpers.insert
+local funcs = helpers.funcs
local meths = helpers.meths
local neq = helpers.neq
local ok = helpers.ok
@@ -136,8 +136,10 @@ describe(":substitute, 'inccommand' preserves", function()
local screen = Screen.new(30,10)
common_setup(screen, "split", "ABC")
- feed_command("%s/AB/BA/")
- feed_command("ls")
+ feed(':%s/AB/BA/')
+ poke_eventloop()
+ feed('<CR>')
+ feed(':ls<CR>')
screen:expect([[
BAC |
@@ -153,29 +155,54 @@ describe(":substitute, 'inccommand' preserves", function()
]])
end)
+ it("'[ and '] marks #26439", function()
+ local screen = Screen.new(30, 10)
+ common_setup(screen, 'nosplit', ('abc\ndef\n'):rep(50))
+
+ feed('ggyG')
+ local X = meths.get_vvar('maxcol')
+ eq({0, 1, 1, 0}, funcs.getpos("'["))
+ eq({0, 101, X, 0}, funcs.getpos("']"))
+
+ feed(":'[,']s/def/")
+ poke_eventloop()
+ eq({0, 1, 1, 0}, funcs.getpos("'["))
+ eq({0, 101, X, 0}, funcs.getpos("']"))
+
+ feed('DEF/g')
+ poke_eventloop()
+ eq({0, 1, 1, 0}, funcs.getpos("'["))
+ eq({0, 101, X, 0}, funcs.getpos("']"))
+
+ feed('<CR>')
+ expect(('abc\nDEF\n'):rep(50))
+ end)
+
for _, case in pairs{"", "split", "nosplit"} do
it("various delimiters (inccommand="..case..")", function()
insert(default_text)
- feed_command("set inccommand=" .. case)
+ command("set inccommand=" .. case)
local delims = { '/', '#', ';', '%', ',', '@', '!' }
for _,delim in pairs(delims) do
- feed_command("%s"..delim.."lines"..delim.."LINES"..delim.."g")
+ feed(":%s"..delim.."lines"..delim.."LINES"..delim.."g")
+ poke_eventloop()
+ feed('<CR>')
expect([[
Inc substitution on
two LINES
]])
- feed_command("undo")
+ command("undo")
end
end)
end
for _, case in pairs{"", "split", "nosplit"} do
it("'undolevels' (inccommand="..case..")", function()
- feed_command("set undolevels=139")
- feed_command("setlocal undolevels=34")
- feed_command("split") -- Show the buffer in multiple windows
- feed_command("set inccommand=" .. case)
+ command("set undolevels=139")
+ command("setlocal undolevels=34")
+ command("split") -- Show the buffer in multiple windows
+ command("set inccommand=" .. case)
insert("as")
feed(":%s/as/glork/")
poke_eventloop()
@@ -187,8 +214,8 @@ describe(":substitute, 'inccommand' preserves", function()
for _, case in ipairs({"", "split", "nosplit"}) do
it("empty undotree() (inccommand="..case..")", function()
- feed_command("set undolevels=1000")
- feed_command("set inccommand=" .. case)
+ command("set undolevels=1000")
+ command("set inccommand=" .. case)
local expected_undotree = eval("undotree()")
-- Start typing an incomplete :substitute command.
@@ -205,8 +232,8 @@ describe(":substitute, 'inccommand' preserves", function()
for _, case in ipairs({"", "split", "nosplit"}) do
it("undotree() with branches (inccommand="..case..")", function()
- feed_command("set undolevels=1000")
- feed_command("set inccommand=" .. case)
+ command("set undolevels=1000")
+ command("set inccommand=" .. case)
-- Make some changes.
feed([[isome text 1<C-\><C-N>]])
feed([[osome text 2<C-\><C-N>]])
@@ -240,7 +267,7 @@ describe(":substitute, 'inccommand' preserves", function()
for _, case in pairs{"", "split", "nosplit"} do
it("b:changedtick (inccommand="..case..")", function()
- feed_command("set inccommand=" .. case)
+ command("set inccommand=" .. case)
feed([[isome text 1<C-\><C-N>]])
feed([[osome text 2<C-\><C-N>]])
local expected_tick = eval("b:changedtick")
@@ -326,37 +353,41 @@ describe(":substitute, 'inccommand' preserves undo", function()
local cases = { "", "split", "nosplit" }
local substrings = {
- ":%s/1",
- ":%s/1/",
- ":%s/1/<bs>",
- ":%s/1/a",
- ":%s/1/a<bs>",
- ":%s/1/ax",
- ":%s/1/ax<bs>",
- ":%s/1/ax<bs><bs>",
- ":%s/1/ax<bs><bs><bs>",
- ":%s/1/ax/",
- ":%s/1/ax/<bs>",
- ":%s/1/ax/<bs>/",
- ":%s/1/ax/g",
- ":%s/1/ax/g<bs>",
- ":%s/1/ax/g<bs><bs>"
+ { ':%s/', '1' },
+ { ':%s/', '1', '/' },
+ { ':%s/', '1', '/', '<bs>' },
+ { ':%s/', '1', '/', 'a' },
+ { ':%s/', '1', '/', 'a', '<bs>' },
+ { ':%s/', '1', '/', 'a', 'x' },
+ { ':%s/', '1', '/', 'a', 'x', '<bs>' },
+ { ':%s/', '1', '/', 'a', 'x', '<bs>', '<bs>' },
+ { ':%s/', '1', '/', 'a', 'x', '<bs>', '<bs>', '<bs>' },
+ { ':%s/', '1', '/', 'a', 'x', '/' },
+ { ':%s/', '1', '/', 'a', 'x', '/', '<bs>' },
+ { ':%s/', '1', '/', 'a', 'x', '/', '<bs>', '/' },
+ { ':%s/', '1', '/', 'a', 'x', '/', 'g' },
+ { ':%s/', '1', '/', 'a', 'x', '/', 'g', '<bs>' },
+ { ':%s/', '1', '/', 'a', 'x', '/', 'g', '<bs>', '<bs>' },
}
local function test_sub(substring, split, redoable)
command('bwipe!')
- feed_command("set inccommand=" .. split)
+ command("set inccommand=" .. split)
insert("1")
feed("o2<esc>")
- feed_command("undo")
+ command("undo")
feed("o3<esc>")
if redoable then
feed("o4<esc>")
- feed_command("undo")
+ command("undo")
end
- feed(substring.. "<enter>")
- feed_command("undo")
+ for _, s in pairs(substring) do
+ feed(s)
+ end
+ poke_eventloop()
+ feed("<enter>")
+ command("undo")
feed("g-")
expect([[
@@ -371,17 +402,21 @@ describe(":substitute, 'inccommand' preserves undo", function()
local function test_notsub(substring, split, redoable)
command('bwipe!')
- feed_command("set inccommand=" .. split)
+ command("set inccommand=" .. split)
insert("1")
feed("o2<esc>")
- feed_command("undo")
+ command("undo")
feed("o3<esc>")
if redoable then
feed("o4<esc>")
- feed_command("undo")
+ command("undo")
+ end
+ for _, s in pairs(substring) do
+ feed(s)
end
- feed(substring .. "<esc>")
+ poke_eventloop()
+ feed("<esc>")
feed("g-")
expect([[
@@ -405,7 +440,7 @@ describe(":substitute, 'inccommand' preserves undo", function()
local function test_threetree(substring, split)
command('bwipe!')
- feed_command("set inccommand=" .. split)
+ command("set inccommand=" .. split)
insert("1")
feed("o2<esc>")
@@ -425,7 +460,11 @@ describe(":substitute, 'inccommand' preserves undo", function()
-- 1 - 2 - 3
feed("2u")
- feed(substring .. "<esc>")
+ for _, s in pairs(substring) do
+ feed(s)
+ poke_eventloop()
+ end
+ feed("<esc>")
expect([[
1]])
feed("g-")
@@ -441,7 +480,11 @@ describe(":substitute, 'inccommand' preserves undo", function()
feed("g-") -- go to b
feed("2u")
- feed(substring .. "<esc>")
+ for _, s in pairs(substring) do
+ feed(s)
+ poke_eventloop()
+ end
+ feed("<esc>")
feed("<c-r>")
expect([[
1
@@ -449,7 +492,11 @@ describe(":substitute, 'inccommand' preserves undo", function()
feed("g-") -- go to 3
feed("2u")
- feed(substring .. "<esc>")
+ for _, s in pairs(substring) do
+ feed(s)
+ poke_eventloop()
+ end
+ feed("<esc>")
feed("<c-r>")
expect([[
1
@@ -500,22 +547,26 @@ describe(":substitute, 'inccommand' preserves undo", function()
for _, case in pairs(cases) do
clear()
common_setup(nil, case, default_text)
- feed_command("set undolevels=0")
+ command("set undolevels=0")
feed("1G0")
insert("X")
- feed(":%s/tw/MO/<esc>")
- feed_command("undo")
+ feed(":%s/tw/MO/")
+ poke_eventloop()
+ feed("<esc>")
+ command("undo")
expect(default_text)
- feed_command("undo")
+ command("undo")
expect(default_text:gsub("Inc", "XInc"))
- feed_command("undo")
+ command("undo")
- feed_command("%s/tw/MO/g")
+ feed(":%s/tw/MO/g")
+ poke_eventloop()
+ feed("<CR>")
expect(default_text:gsub("tw", "MO"))
- feed_command("undo")
+ command("undo")
expect(default_text)
- feed_command("undo")
+ command("undo")
expect(default_text:gsub("tw", "MO"))
end
end)
@@ -538,21 +589,28 @@ describe(":substitute, 'inccommand' preserves undo", function()
{15:~ }|
|
]])
- feed_command("set undolevels=1")
+ command("set undolevels=1")
feed("1G0")
insert("X")
feed("IY<esc>")
- feed(":%s/tw/MO/<esc>")
- -- feed_command("undo") here would cause "Press ENTER".
+ feed(":%s/tw/MO/")
+ poke_eventloop()
+ feed("<esc>")
feed("u")
expect(default_text:gsub("Inc", "XInc"))
feed("u")
expect(default_text)
- feed(":%s/tw/MO/g<enter>")
- feed(":%s/MO/GO/g<enter>")
- feed(":%s/GO/NO/g<enter>")
+ feed(":%s/tw/MO/g")
+ poke_eventloop()
+ feed("<enter>")
+ feed(":%s/MO/GO/g")
+ poke_eventloop()
+ feed("<enter>")
+ feed(":%s/GO/NO/g")
+ poke_eventloop()
+ feed("<enter>")
feed("u")
expect(default_text:gsub("tw", "GO"))
feed("u")
@@ -595,13 +653,14 @@ describe(":substitute, 'inccommand' preserves undo", function()
for _, case in pairs(cases) do
clear()
common_setup(screen, case, default_text)
- feed_command("set undolevels=2")
+ command("set undolevels=2")
feed("2GAx<esc>")
feed("Ay<esc>")
feed("Az<esc>")
- feed(":%s/tw/AR<esc>")
- -- feed_command("undo") here would cause "Press ENTER".
+ feed(":%s/tw/AR")
+ poke_eventloop()
+ feed("<esc>")
feed("u")
expect(default_text:gsub("lines", "linesxy"))
feed("u")
@@ -638,10 +697,18 @@ describe(":substitute, 'inccommand' preserves undo", function()
]])
end
- feed(":%s/tw/MO/g<enter>")
- feed(":%s/MO/GO/g<enter>")
- feed(":%s/GO/NO/g<enter>")
- feed(":%s/NO/LO/g<enter>")
+ feed(":%s/tw/MO/g")
+ poke_eventloop()
+ feed("<enter>")
+ feed(":%s/MO/GO/g")
+ poke_eventloop()
+ feed("<enter>")
+ feed(":%s/GO/NO/g")
+ poke_eventloop()
+ feed("<enter>")
+ feed(":%s/NO/LO/g")
+ poke_eventloop()
+ feed("<enter>")
feed("u")
expect(default_text:gsub("tw", "NO"))
feed("u")
@@ -687,9 +754,10 @@ describe(":substitute, 'inccommand' preserves undo", function()
clear()
common_setup(screen, case, default_text)
- feed_command("set undolevels=-1")
- feed(":%s/tw/MO/g<enter>")
- -- feed_command("undo") here will result in a "Press ENTER" prompt
+ command("set undolevels=-1")
+ feed(":%s/tw/MO/g")
+ poke_eventloop()
+ feed("<enter>")
feed("u")
if case == "split" then
screen:expect([[
@@ -723,10 +791,12 @@ describe(":substitute, 'inccommand' preserves undo", function()
clear()
common_setup(screen, case, default_text)
- feed_command("set undolevels=-1")
+ command("set undolevels=-1")
feed("1G")
feed("IL<esc>")
- feed(":%s/tw/MO/g<esc>")
+ feed(":%s/tw/MO/g")
+ poke_eventloop()
+ feed("<esc>")
feed("u")
screen:expect([[
@@ -756,7 +826,7 @@ describe(":substitute, inccommand=split", function()
end)
it("preserves 'modified' buffer flag", function()
- feed_command("set nomodified")
+ command("set nomodified")
feed(":%s/tw")
screen:expect([[
Inc substitution on |
@@ -991,7 +1061,7 @@ describe(":substitute, inccommand=split", function()
end)
it("'hlsearch' is active, 'cursorline' is not", function()
- feed_command("set hlsearch cursorline")
+ command("set hlsearch cursorline")
feed("gg")
-- Assert that 'cursorline' is active.
@@ -1010,7 +1080,7 @@ describe(":substitute, inccommand=split", function()
{15:~ }|
{15:~ }|
{15:~ }|
- :set hlsearch cursorline |
+ |
]])
feed(":%s/tw")
@@ -1080,8 +1150,8 @@ describe(":substitute, inccommand=split", function()
end)
it('previews correctly when previewhight is small', function()
- feed_command('set cwh=3')
- feed_command('set hls')
+ command('set cwh=3')
+ command('set hls')
feed('ggdG')
insert(string.rep('abc abc abc\n', 20))
feed(':%s/abc/MMM/g')
@@ -1105,7 +1175,9 @@ describe(":substitute, inccommand=split", function()
end)
it('actually replaces text', function()
- feed(":%s/tw/XX/g<Enter>")
+ feed(":%s/tw/XX/g")
+ poke_eventloop()
+ feed("<Enter>")
screen:expect([[
Inc substitution on |
@@ -1130,7 +1202,7 @@ describe(":substitute, inccommand=split", function()
feed("gg")
feed("2yy")
feed("2000p")
- feed_command("1,1000s/tw/BB/g")
+ command("1,1000s/tw/BB/g")
feed(":%s/tw/X")
screen:expect([[
@@ -1168,11 +1240,13 @@ describe(":substitute, inccommand=split", function()
feed("<CR>")
poke_eventloop()
feed(":vs tmp<enter>")
- eq(3, helpers.call('bufnr', '$'))
+ eq(3, funcs.bufnr('$'))
end)
it('works with the n flag', function()
- feed(":%s/tw/Mix/n<Enter>")
+ feed(":%s/tw/Mix/n")
+ poke_eventloop()
+ feed("<Enter>")
screen:expect([[
Inc substitution on |
two lines |
@@ -1198,9 +1272,9 @@ describe(":substitute, inccommand=split", function()
-- Assert that 'inccommand' is ENABLED initially.
eq("split", eval("&inccommand"))
-- Set 'redrawtime' to minimal value, to ensure timeout is triggered.
- feed_command("set redrawtime=1 nowrap")
+ command("set redrawtime=1 nowrap")
-- Load a big file.
- feed_command("silent edit! test/functional/fixtures/bigfile_oneline.txt")
+ command("silent edit! test/functional/fixtures/bigfile_oneline.txt")
-- Start :substitute with a slow pattern.
feed([[:%s/B.*N/x]])
poke_eventloop()
@@ -1267,7 +1341,7 @@ describe(":substitute, inccommand=split", function()
it("clears preview if non-previewable command is edited #5585", function()
feed('gg')
-- Put a non-previewable command in history.
- feed_command("echo 'foo'")
+ feed(":echo 'foo'<CR>")
-- Start an incomplete :substitute command.
feed(":1,2s/t/X")
@@ -1425,7 +1499,7 @@ describe("inccommand=nosplit", function()
end)
it("works with :smagic, :snomagic", function()
- feed_command("set hlsearch")
+ command("set hlsearch")
insert("Line *.3.* here")
feed(":%smagic/3.*/X") -- start :smagic command
@@ -1511,7 +1585,7 @@ describe("inccommand=nosplit", function()
end)
it('never shows preview buffer', function()
- feed_command("set hlsearch")
+ command("set hlsearch")
feed(":%s/tw")
screen:expect([[
@@ -1572,7 +1646,7 @@ describe("inccommand=nosplit", function()
it("clears preview if non-previewable command is edited", function()
-- Put a non-previewable command in history.
- feed_command("echo 'foo'")
+ feed(":echo 'foo'<CR>")
-- Start an incomplete :substitute command.
feed(":1,2s/t/X")
@@ -1660,8 +1734,10 @@ describe(":substitute, 'inccommand' with a failing expression", function()
it('in the pattern does nothing', function()
for _, case in pairs(cases) do
refresh(case)
- feed_command("set inccommand=" .. case)
- feed(":silent! %s/tw\\(/LARD/<enter>")
+ command("set inccommand=" .. case)
+ feed(":silent! %s/tw\\(/LARD/")
+ poke_eventloop()
+ feed("<enter>")
expect(default_text)
end
end)
@@ -1672,10 +1748,12 @@ describe(":substitute, 'inccommand' with a failing expression", function()
local replacements = { "\\='LARD", "\\=xx_novar__xx" }
for _, repl in pairs(replacements) do
- feed_command("set inccommand=" .. case)
- feed(":silent! %s/tw/" .. repl .. "/<enter>")
+ command("set inccommand=" .. case)
+ feed(":silent! %s/tw/" .. repl .. "/")
+ poke_eventloop()
+ feed("<enter>")
expect(default_text:gsub("tw", ""))
- feed_command("undo")
+ command("undo")
end
end
end)
@@ -1733,10 +1811,12 @@ describe("'inccommand' and :cnoremap", function()
for i = 1, string.len(cmd) do
local c = string.sub(cmd, i, i)
- feed_command("cnoremap ".. c .. " " .. c)
+ command("cnoremap ".. c .. " " .. c)
end
- feed_command(cmd)
+ feed(':' .. cmd)
+ poke_eventloop()
+ feed('<CR>')
expect([[
Inc substitution on
two LINES
@@ -1747,30 +1827,47 @@ describe("'inccommand' and :cnoremap", function()
it('work when mappings move the cursor', function()
for _, case in pairs(cases) do
refresh(case)
- feed_command("cnoremap ,S LINES/<left><left><left><left><left><left>")
+ command("cnoremap ,S LINES/<left><left><left><left><left><left>")
- feed(":%s/lines/,Sor three <enter>")
+ feed(":%s/lines/")
+ poke_eventloop()
+ feed(",S")
+ poke_eventloop()
+ feed("or three <enter>")
+ poke_eventloop()
expect([[
Inc substitution on
two or three LINES
]])
- feed_command("cnoremap ;S /X/<left><left><left>")
- feed(":%s/;SI<enter>")
+ command("cnoremap ;S /X/<left><left><left>")
+ feed(":%s/")
+ poke_eventloop()
+ feed(";S")
+ poke_eventloop()
+ feed("I<enter>")
expect([[
Xnc substitution on
two or three LXNES
]])
- feed_command("cnoremap ,T //Y/<left><left><left>")
- feed(":%s,TX<enter>")
+ command("cnoremap ,T //Y/<left><left><left>")
+ feed(":%s")
+ poke_eventloop()
+ feed(",T")
+ poke_eventloop()
+ feed("X<enter>")
expect([[
Ync substitution on
two or three LYNES
]])
- feed_command("cnoremap ;T s//Z/<left><left><left>")
- feed(":%;TY<enter>")
+ command("cnoremap ;T s//Z/<left><left><left>")
+ feed(":%")
+ poke_eventloop()
+ feed(";T")
+ poke_eventloop()
+ feed("Y<enter>")
expect([[
Znc substitution on
two or three LZNES
@@ -1781,7 +1878,7 @@ describe("'inccommand' and :cnoremap", function()
it('still works with a broken mapping', function()
for _, case in pairs(cases) do
refresh(case, true)
- feed_command("cnoremap <expr> x execute('bwipeout!')[-1].'x'")
+ command("cnoremap <expr> x execute('bwipeout!')[-1].'x'")
feed(":%s/tw/tox<enter>")
screen:expect{any=[[{14:^E565:]]}
@@ -1799,9 +1896,11 @@ describe("'inccommand' and :cnoremap", function()
it('work when temporarily moving the cursor', function()
for _, case in pairs(cases) do
refresh(case)
- feed_command("cnoremap <expr> x cursor(1, 1)[-1].'x'")
+ command("cnoremap <expr> x cursor(1, 1)[-1].'x'")
- feed(":%s/tw/tox/g<enter>")
+ feed(":%s/tw/tox")
+ poke_eventloop()
+ feed("/g<enter>")
expect(default_text:gsub("tw", "tox"))
end
end)
@@ -1809,9 +1908,11 @@ describe("'inccommand' and :cnoremap", function()
it("work when a mapping disables 'inccommand'", function()
for _, case in pairs(cases) do
refresh(case)
- feed_command("cnoremap <expr> x execute('set inccommand=')[-1]")
+ command("cnoremap <expr> x execute('set inccommand=')[-1]")
- feed(":%s/tw/toxa/g<enter>")
+ feed(":%s/tw/tox")
+ poke_eventloop()
+ feed("a/g<enter>")
expect(default_text:gsub("tw", "toa"))
end
end)
@@ -1823,6 +1924,7 @@ describe("'inccommand' and :cnoremap", function()
\.fo<CR><C-c>:new<CR>:bw!<CR>:<C-r>=remove(g:, 'fo')<CR>x]])
feed(":%s/tw/tox")
+ poke_eventloop()
feed("/<enter>")
expect(default_text:gsub("tw", "tox"))
end
@@ -1883,7 +1985,7 @@ describe("'inccommand' autocommands", function()
local function register_autocmd(event)
meths.set_var(event .. "_fired", {})
- feed_command("autocmd " .. event .. " * call add(g:" .. event .. "_fired, expand('<abuf>'))")
+ command("autocmd " .. event .. " * call add(g:" .. event .. "_fired, expand('<abuf>'))")
end
it('are not fired when splitting', function()
@@ -1930,8 +2032,8 @@ describe("'inccommand' split windows", function()
refresh()
feed("gg")
- feed_command("vsplit")
- feed_command("split")
+ command("vsplit")
+ command("split")
feed(":%s/tw")
screen:expect([[
Inc substitution on │Inc substitution on|
@@ -1967,9 +2069,9 @@ describe("'inccommand' split windows", function()
]])
feed("<esc>")
- feed_command("only")
- feed_command("split")
- feed_command("vsplit")
+ command("only")
+ command("split")
+ command("vsplit")
feed(":%s/tw")
screen:expect([[
@@ -2007,18 +2109,18 @@ describe("'inccommand' split windows", function()
end)
local settings = {
- "splitbelow",
- "splitright",
- "noequalalways",
- "equalalways eadirection=ver",
- "equalalways eadirection=hor",
- "equalalways eadirection=both",
+ "splitbelow",
+ "splitright",
+ "noequalalways",
+ "equalalways eadirection=ver",
+ "equalalways eadirection=hor",
+ "equalalways eadirection=both",
}
it("are not affected by various settings", function()
for _, setting in pairs(settings) do
refresh()
- feed_command("set " .. setting)
+ command("set " .. setting)
feed(":%s/tw")
diff --git a/test/functional/ui/options_spec.lua b/test/functional/ui/options_spec.lua
index 2c649709c6..4c197ad5b9 100644
--- a/test/functional/ui/options_spec.lua
+++ b/test/functional/ui/options_spec.lua
@@ -9,7 +9,7 @@ local eval = helpers.eval
describe('UI receives option updates', function()
local screen
- local function reset(opts, ...)
+ local function reset(screen_opts, clear_opts)
local defaults = {
ambiwidth='single',
arabicshape=true,
@@ -38,9 +38,12 @@ describe('UI receives option updates', function()
ext_termcolors=false,
}
- clear(...)
+ clear_opts = shallowcopy(clear_opts or {})
+ clear_opts.args_rm = clear_opts.args_rm or {}
+ table.insert(clear_opts.args_rm or {}, '--cmd')
+ clear(clear_opts)
screen = Screen.new(20,5)
- screen:attach(opts)
+ screen:attach(screen_opts)
-- NB: UI test suite can be run in both "linegrid" and legacy grid mode.
-- In both cases check that the received value is the one requested.
defaults.ext_linegrid = screen._options.ext_linegrid or false
diff --git a/test/functional/ui/output_spec.lua b/test/functional/ui/output_spec.lua
index 719634aa2f..40d7c8f21d 100644
--- a/test/functional/ui/output_spec.lua
+++ b/test/functional/ui/output_spec.lua
@@ -25,7 +25,7 @@ describe("shell command :!", function()
'-u', 'NONE',
'-i', 'NONE',
'--cmd', 'colorscheme vim',
- '--cmd', helpers.nvim_set,
+ '--cmd', helpers.nvim_set .. ' notermguicolors',
})
screen:expect([[
{1: } |
diff --git a/test/unit/helpers.lua b/test/unit/helpers.lua
index 86f3a7a662..e56f8d5058 100644
--- a/test/unit/helpers.lua
+++ b/test/unit/helpers.lua
@@ -800,7 +800,12 @@ local function cppimport(path)
return cimport(Paths.test_source_path .. '/test/includes/pre/' .. path)
end
-cimport('./src/nvim/types.h', './src/nvim/main.h', './src/nvim/os/time.h', './src/nvim/os/fs.h')
+cimport(
+ './src/nvim/types_defs.h',
+ './src/nvim/main.h',
+ './src/nvim/os/time.h',
+ './src/nvim/os/fs.h'
+)
local function conv_enum(etab, eval)
local n = tonumber(eval)