diff options
-rw-r--r-- | src/nvim/eval/funcs.c | 11 | ||||
-rw-r--r-- | src/nvim/ex_cmds.c | 8 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 7 | ||||
-rw-r--r-- | src/nvim/tui/input.c | 24 | ||||
-rw-r--r-- | src/nvim/tui/input.h | 3 | ||||
-rw-r--r-- | src/nvim/tui/tui.c | 3 | ||||
-rw-r--r-- | src/nvim/version.c | 2 | ||||
-rw-r--r-- | test/functional/helpers.lua | 9 | ||||
-rw-r--r-- | test/functional/terminal/api_spec.lua | 2 | ||||
-rw-r--r-- | test/functional/terminal/buffer_spec.lua | 50 | ||||
-rw-r--r-- | test/functional/terminal/highlight_spec.lua | 2 | ||||
-rw-r--r-- | test/functional/terminal/tui_spec.lua | 13 | ||||
-rw-r--r-- | test/functional/ui/inccommand_spec.lua | 336 | ||||
-rw-r--r-- | test/functional/ui/options_spec.lua | 9 | ||||
-rw-r--r-- | test/functional/ui/output_spec.lua | 2 | ||||
-rw-r--r-- | test/unit/helpers.lua | 7 |
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) |