aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/event/loop.h9
-rw-r--r--src/nvim/ex_docmd.c13
-rw-r--r--src/nvim/testdir/runtest.vim1
-rw-r--r--src/nvim/testdir/test_cmdline.vim25
-rw-r--r--src/nvim/testdir/test_functions.vim34
-rw-r--r--src/nvim/tui/tui.c36
-rw-r--r--src/nvim/version.c8
7 files changed, 103 insertions, 23 deletions
diff --git a/src/nvim/event/loop.h b/src/nvim/event/loop.h
index b0ddc59469..d1a40d5cc9 100644
--- a/src/nvim/event/loop.h
+++ b/src/nvim/event/loop.h
@@ -19,12 +19,11 @@ typedef struct loop {
MultiQueue *events;
MultiQueue *thread_events;
// Immediate events:
- // "Events that should be processed after exiting uv_run() (to avoid
- // recursion), but before returning from loop_poll_events()."
- // 502aee690c980fcb3cfcb3f211dcfad06103db46
- // Practical consequence: these events are processed by
+ // "Processed after exiting uv_run() (to avoid recursion), but before
+ // returning from loop_poll_events()." 502aee690c98
+ // Practical consequence (for main_loop): these events are processed by
// state_enter()..os_inchar()
- // whereas "regular" (main_loop.events) events are processed by
+ // whereas "regular" events (main_loop.events) are processed by
// state_enter()..VimState.execute()
// But state_enter()..os_inchar() can be "too early" if you want the event
// to trigger UI updates and other user-activity-related side-effects.
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 3202f8a848..f6a5f59676 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -3484,10 +3484,17 @@ char_u *skip_range(
{
unsigned delim;
- while (vim_strchr((char_u *)" \t0123456789.$%'/?-+,;", *cmd) != NULL) {
- if (*cmd == '\'') {
- if (*++cmd == NUL && ctx != NULL)
+ while (vim_strchr((char_u *)" \t0123456789.$%'/?-+,;\\", *cmd) != NULL) {
+ if (*cmd == '\\') {
+ if (cmd[1] == '?' || cmd[1] == '/' || cmd[1] == '&') {
+ cmd++;
+ } else {
+ break;
+ }
+ } else if (*cmd == '\'') {
+ if (*++cmd == NUL && ctx != NULL) {
*ctx = EXPAND_NOTHING;
+ }
} else if (*cmd == '/' || *cmd == '?') {
delim = *cmd++;
while (*cmd != NUL && *cmd != delim)
diff --git a/src/nvim/testdir/runtest.vim b/src/nvim/testdir/runtest.vim
index 39ffabc024..4de1345679 100644
--- a/src/nvim/testdir/runtest.vim
+++ b/src/nvim/testdir/runtest.vim
@@ -203,7 +203,6 @@ let s:flaky = [
\ ]
" Locate Test_ functions and execute them.
-set nomore
redir @q
silent function /^Test_
redir END
diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim
index 5fc519f822..ac44e09a5a 100644
--- a/src/nvim/testdir/test_cmdline.vim
+++ b/src/nvim/testdir/test_cmdline.vim
@@ -306,3 +306,28 @@ func Test_cmdline_complete_wildoptions()
call assert_equal(a, b)
bw!
endfunc
+
+" using a leading backslash here
+set cpo+=C
+
+func Test_cmdline_search_range()
+ new
+ call setline(1, ['a', 'b', 'c', 'd'])
+ /d
+ 1,\/s/b/B/
+ call assert_equal('B', getline(2))
+
+ /a
+ $
+ \?,4s/c/C/
+ call assert_equal('C', getline(3))
+
+ call setline(1, ['a', 'b', 'c', 'd'])
+ %s/c/c/
+ 1,\&s/b/B/
+ call assert_equal('B', getline(2))
+
+ bwipe!
+endfunc
+
+set cpo&
diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim
index 59807ca946..0ce034b63e 100644
--- a/src/nvim/testdir/test_functions.vim
+++ b/src/nvim/testdir/test_functions.vim
@@ -207,39 +207,73 @@ func! Test_mode()
normal! 3G
exe "normal i\<F2>\<Esc>"
call assert_equal('i-i', g:current_modes)
+ " i_CTRL-P: Multiple matches
exe "normal i\<C-G>uBa\<C-P>\<F2>\<Esc>u"
call assert_equal('i-ic', g:current_modes)
+ " i_CTRL-P: Single match
exe "normal iBro\<C-P>\<F2>\<Esc>u"
call assert_equal('i-ic', g:current_modes)
+ " i_CTRL-X
exe "normal iBa\<C-X>\<F2>\<Esc>u"
call assert_equal('i-ix', g:current_modes)
+ " i_CTRL-X CTRL-P: Multiple matches
exe "normal iBa\<C-X>\<C-P>\<F2>\<Esc>u"
call assert_equal('i-ic', g:current_modes)
+ " i_CTRL-X CTRL-P: Single match
exe "normal iBro\<C-X>\<C-P>\<F2>\<Esc>u"
call assert_equal('i-ic', g:current_modes)
+ " i_CTRL-X CTRL-P + CTRL-P: Single match
exe "normal iBro\<C-X>\<C-P>\<C-P>\<F2>\<Esc>u"
call assert_equal('i-ic', g:current_modes)
+ " i_CTRL-X CTRL-L: Multiple matches
+ exe "normal i\<C-X>\<C-L>\<F2>\<Esc>u"
+ call assert_equal('i-ic', g:current_modes)
+ " i_CTRL-X CTRL-L: Single match
+ exe "normal iBlu\<C-X>\<C-L>\<F2>\<Esc>u"
+ call assert_equal('i-ic', g:current_modes)
+ " i_CTRL-P: No match
exe "normal iCom\<C-P>\<F2>\<Esc>u"
call assert_equal('i-ic', g:current_modes)
+ " i_CTRL-X CTRL-P: No match
exe "normal iCom\<C-X>\<C-P>\<F2>\<Esc>u"
call assert_equal('i-ic', g:current_modes)
+ " i_CTRL-X CTRL-L: No match
+ exe "normal iabc\<C-X>\<C-L>\<F2>\<Esc>u"
+ call assert_equal('i-ic', g:current_modes)
+ " R_CTRL-P: Multiple matches
exe "normal RBa\<C-P>\<F2>\<Esc>u"
call assert_equal('R-Rc', g:current_modes)
+ " R_CTRL-P: Single match
exe "normal RBro\<C-P>\<F2>\<Esc>u"
call assert_equal('R-Rc', g:current_modes)
+ " R_CTRL-X
exe "normal RBa\<C-X>\<F2>\<Esc>u"
call assert_equal('R-Rx', g:current_modes)
+ " R_CTRL-X CTRL-P: Multiple matches
exe "normal RBa\<C-X>\<C-P>\<F2>\<Esc>u"
call assert_equal('R-Rc', g:current_modes)
+ " R_CTRL-X CTRL-P: Single match
exe "normal RBro\<C-X>\<C-P>\<F2>\<Esc>u"
call assert_equal('R-Rc', g:current_modes)
+ " R_CTRL-X CTRL-P + CTRL-P: Single match
exe "normal RBro\<C-X>\<C-P>\<C-P>\<F2>\<Esc>u"
call assert_equal('R-Rc', g:current_modes)
+ " R_CTRL-X CTRL-L: Multiple matches
+ exe "normal R\<C-X>\<C-L>\<F2>\<Esc>u"
+ call assert_equal('R-Rc', g:current_modes)
+ " R_CTRL-X CTRL-L: Single match
+ exe "normal RBlu\<C-X>\<C-L>\<F2>\<Esc>u"
+ call assert_equal('R-Rc', g:current_modes)
+ " R_CTRL-P: No match
exe "normal RCom\<C-P>\<F2>\<Esc>u"
call assert_equal('R-Rc', g:current_modes)
+ " R_CTRL-X CTRL-P: No match
exe "normal RCom\<C-X>\<C-P>\<F2>\<Esc>u"
call assert_equal('R-Rc', g:current_modes)
+ " R_CTRL-X CTRL-L: No match
+ exe "normal Rabc\<C-X>\<C-L>\<F2>\<Esc>u"
+ call assert_equal('R-Rc', g:current_modes)
call assert_equal('n', mode(0))
call assert_equal('n', mode(1))
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 724d59b15a..2436295ad4 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -167,6 +167,24 @@ static size_t unibi_pre_fmt_str(TUIData *data, unsigned int unibi_index,
return unibi_run(str, data->params, buf, len);
}
+/// Emits some termcodes after Nvim startup, which were observed to slowdown
+/// rendering during startup in tmux 2.3 (+focus-events). #7649
+static void terminfo_after_startup_event(void **argv)
+{
+ UI *ui = argv[0];
+ bool defer = argv[1] != NULL; // clever(?) boolean without malloc() dance.
+ TUIData *data = ui->data;
+ if (defer) { // We're on the main-loop. Now forward to the TUI loop.
+ loop_schedule(data->loop,
+ event_create(terminfo_after_startup_event, 2, ui, NULL));
+ return;
+ }
+ // Enable bracketed paste
+ unibi_out_ext(ui, data->unibi_ext.enable_bracketed_paste);
+ // Enable focus reporting
+ unibi_out_ext(ui, data->unibi_ext.enable_focus_reporting);
+}
+
static void termname_set_event(void **argv)
{
char *termname = argv[0];
@@ -244,10 +262,6 @@ static void terminfo_start(UI *ui)
unibi_out(ui, unibi_enter_ca_mode);
unibi_out(ui, unibi_keypad_xmit);
unibi_out(ui, unibi_clear_screen);
- // Enable bracketed paste
- unibi_out_ext(ui, data->unibi_ext.enable_bracketed_paste);
- // Enable focus reporting
- unibi_out_ext(ui, data->unibi_ext.enable_focus_reporting);
uv_loop_init(&data->write_loop);
if (data->out_isatty) {
uv_tty_init(&data->write_loop, &data->output_handle.tty, data->out_fd, 0);
@@ -260,6 +274,9 @@ static void terminfo_start(UI *ui)
uv_pipe_init(&data->write_loop, &data->output_handle.pipe, 0);
uv_pipe_open(&data->output_handle.pipe, data->out_fd);
}
+
+ loop_schedule(&main_loop,
+ event_create(terminfo_after_startup_event, 2, ui, ui));
}
static void terminfo_stop(UI *ui)
@@ -342,7 +359,7 @@ static void tui_main(UIBridgeData *bridge, UI *ui)
CONTINUE(bridge);
while (!data->stop) {
- loop_poll_events(&tui_loop, -1);
+ loop_poll_events(&tui_loop, -1); // tui_loop.events is never processed
}
ui_bridge_stopped(bridge);
@@ -1620,9 +1637,8 @@ static void augment_terminfo(TUIData *data, const char *term,
ut, NULL, "\033]12;#%p1%06x\007");
}
- /// Terminals generally ignore private modes that they do not recognize,
- /// and there is no known ambiguity with these modes from terminal type to
- /// terminal type, so we can afford to just set these unconditionally.
+ /// Terminals usually ignore unrecognized private modes, and there is no
+ /// known ambiguity with these. So we just set them unconditionally.
data->unibi_ext.enable_lr_margin = (int)unibi_add_ext_str(ut, NULL,
"\x1b[?69h");
data->unibi_ext.disable_lr_margin = (int)unibi_add_ext_str(ut, NULL,
@@ -1632,9 +1648,9 @@ static void augment_terminfo(TUIData *data, const char *term,
data->unibi_ext.disable_bracketed_paste = (int)unibi_add_ext_str(ut, NULL,
"\x1b[?2004l");
data->unibi_ext.enable_focus_reporting = (int)unibi_add_ext_str(ut, NULL,
- "\x1b[?1004h");
+ rxvt ? "\x1b]777;focus;on\x7" : "\x1b[?1004h");
data->unibi_ext.disable_focus_reporting = (int)unibi_add_ext_str(ut, NULL,
- "\x1b[?1004l");
+ rxvt ? "\x1b]777;focus;off\x7" : "\x1b[?1004l");
data->unibi_ext.enable_mouse = (int)unibi_add_ext_str(ut, NULL,
"\x1b[?1002h\x1b[?1006h");
data->unibi_ext.disable_mouse = (int)unibi_add_ext_str(ut, NULL,
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 9ef35e66f8..1a9c9d73e5 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -950,7 +950,7 @@ static const int included_patches[] = {
// 309,
308,
307,
- // 306,
+ 306,
305,
// 304,
// 303,
@@ -958,10 +958,10 @@ static const int included_patches[] = {
// 301,
300,
// 299,
- // 298,
+ 298,
297,
// 296,
- // 295,
+ 295,
294,
// 293,
292,
@@ -1085,7 +1085,7 @@ static const int included_patches[] = {
174,
// 173 NA
172,
- // 171,
+ // 171 NA
// 170 NA
// 169 NA
168,