aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/extmark.c26
-rw-r--r--src/nvim/api/keysets.lua1
-rw-r--r--src/nvim/api/vim.c5
-rw-r--r--src/nvim/autocmd.c5
-rw-r--r--src/nvim/cursor.c1
-rw-r--r--src/nvim/edit.c38
-rw-r--r--src/nvim/lua/executor.c3
-rw-r--r--src/nvim/screen.c4
-rw-r--r--src/nvim/terminal.c5
-rw-r--r--src/nvim/testdir/runtest.vim5
-rw-r--r--src/nvim/testdir/test_filetype.vim3
-rw-r--r--src/nvim/testdir/test_prompt_buffer.vim80
-rw-r--r--src/nvim/window.c65
13 files changed, 212 insertions, 29 deletions
diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c
index 6e25e627b9..742b953c2a 100644
--- a/src/nvim/api/extmark.c
+++ b/src/nvim/api/extmark.c
@@ -339,7 +339,7 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e
/// @param col Column where to place the mark, 0-based. |api-indexing|
/// @param opts Optional parameters.
/// - id : id of the extmark to edit.
-/// - end_line : ending line of the mark, 0-based inclusive.
+/// - end_row : ending line of the mark, 0-based inclusive.
/// - end_col : ending col of the mark, 0-based exclusive.
/// - hl_group : name of the highlight group used to highlight
/// this mark.
@@ -431,16 +431,26 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
}
int line2 = -1;
- if (opts->end_line.type == kObjectTypeInteger) {
- Integer val = opts->end_line.data.integer;
+
+ // For backward compatibility we support "end_line" as an alias for "end_row"
+ if (HAS_KEY(opts->end_line)) {
+ if (HAS_KEY(opts->end_row)) {
+ api_set_error(err, kErrorTypeValidation, "cannot use both end_row and end_line");
+ goto error;
+ }
+ opts->end_row = opts->end_line;
+ }
+
+ if (opts->end_row.type == kObjectTypeInteger) {
+ Integer val = opts->end_row.data.integer;
if (val < 0 || val > buf->b_ml.ml_line_count) {
- api_set_error(err, kErrorTypeValidation, "end_line value outside range");
+ api_set_error(err, kErrorTypeValidation, "end_row value outside range");
goto error;
} else {
line2 = (int)val;
}
- } else if (HAS_KEY(opts->end_line)) {
- api_set_error(err, kErrorTypeValidation, "end_line is not an integer");
+ } else if (HAS_KEY(opts->end_row)) {
+ api_set_error(err, kErrorTypeValidation, "end_row is not an integer");
goto error;
}
@@ -571,10 +581,10 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
OPTION_TO_BOOL(right_gravity, right_gravity, true);
// Only error out if they try to set end_right_gravity without
- // setting end_col or end_line
+ // setting end_col or end_row
if (line2 == -1 && col2 == -1 && HAS_KEY(opts->end_right_gravity)) {
api_set_error(err, kErrorTypeValidation,
- "cannot set end_right_gravity without setting end_line or end_col");
+ "cannot set end_right_gravity without setting end_row or end_col");
goto error;
}
diff --git a/src/nvim/api/keysets.lua b/src/nvim/api/keysets.lua
index e956a54dbc..f3e7f2f1dc 100644
--- a/src/nvim/api/keysets.lua
+++ b/src/nvim/api/keysets.lua
@@ -5,6 +5,7 @@ return {
set_extmark = {
"id";
"end_line";
+ "end_row";
"end_col";
"hl_group";
"virt_text";
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 36179b1fab..4f7c320129 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -842,7 +842,7 @@ void nvim_echo(Array chunks, Boolean history, Dictionary opts, Error *err)
for (uint32_t i = 0; i < kv_size(hl_msg); i++) {
HlMessageChunk chunk = kv_A(hl_msg, i);
msg_multiline_attr((const char *)chunk.text.data, chunk.attr,
- false, &need_clear);
+ true, &need_clear);
}
if (history) {
msg_ext_set_kind("echomsg");
@@ -1842,6 +1842,9 @@ static void write_msg(String message, bool to_err)
++no_wait_return;
for (uint32_t i = 0; i < message.size; i++) {
+ if (got_int) {
+ break;
+ }
if (to_err) {
PUSH_CHAR(i, err_pos, err_line_buf, emsg);
} else {
diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c
index 490fe5a0ac..9044657358 100644
--- a/src/nvim/autocmd.c
+++ b/src/nvim/autocmd.c
@@ -1213,10 +1213,13 @@ win_found:
// Hmm, original window disappeared. Just use the first one.
curwin = firstwin;
}
+ curbuf = curwin->w_buffer;
+ // May need to restore insert mode for a prompt buffer.
+ entering_window(curwin);
+
prevwin = win_find_by_handle(aco->save_prevwin_handle);
vars_clear(&aucmd_win->w_vars->dv_hashtab); // free all w: variables
hash_init(&aucmd_win->w_vars->dv_hashtab); // re-use the hashtab
- curbuf = curwin->w_buffer;
xfree(globaldir);
globaldir = aco->globaldir;
diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c
index e334fd166e..4e1d7f9d78 100644
--- a/src/nvim/cursor.c
+++ b/src/nvim/cursor.c
@@ -108,6 +108,7 @@ static int coladvance2(pos_T *pos, bool addspaces, bool finetune, colnr_T wcol_a
int head = 0;
one_more = (State & INSERT)
+ || (State & TERM_FOCUS)
|| restart_edit != NUL
|| (VIsual_active && *p_sel != 'o')
|| ((ve_flags & VE_ONEMORE) && wcol < MAXCOL);
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index fe69da7fcb..9bfb8a9d4a 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -227,6 +227,7 @@ typedef struct insert_state {
cmdarg_T *ca;
int mincol;
int cmdchar;
+ int cmdchar_todo; // cmdchar to handle once in init_prompt
int startln;
long count;
int c;
@@ -290,6 +291,7 @@ static void insert_enter(InsertState *s)
s->did_backspace = true;
s->old_topfill = -1;
s->replaceState = REPLACE;
+ s->cmdchar_todo = s->cmdchar;
// Remember whether editing was restarted after CTRL-O
did_restart_edit = restart_edit;
// sleep before redrawing, needed for "CTRL-O :" that results in an
@@ -585,7 +587,8 @@ static int insert_check(VimState *state)
}
if (bt_prompt(curbuf)) {
- init_prompt(s->cmdchar);
+ init_prompt(s->cmdchar_todo);
+ s->cmdchar_todo = NUL;
}
// If we inserted a character at the last position of the last line in the
@@ -655,10 +658,17 @@ static int insert_check(VimState *state)
static int insert_execute(VimState *state, int key)
{
+ InsertState *const s = (InsertState *)state;
+ if (stop_insert_mode) {
+ // Insert mode ended, possibly from a callback.
+ s->count = 0;
+ s->nomove = true;
+ return 0;
+ }
+
if (key == K_IGNORE || key == K_NOP) {
return -1; // get another key
}
- InsertState *s = (InsertState *)state;
s->c = key;
// Don't want K_EVENT with cursorhold for the second key, e.g., after CTRL-V.
@@ -984,6 +994,15 @@ static int insert_handle_key(InsertState *s)
break;
case Ctrl_W: // delete word before the cursor
+ if (bt_prompt(curbuf) && (mod_mask & MOD_MASK_SHIFT) == 0) {
+ // In a prompt window CTRL-W is used for window commands.
+ // Use Shift-CTRL-W to delete a word.
+ stuffcharReadbuff(Ctrl_W);
+ restart_edit = 'A';
+ s->nomove = true;
+ s->count = 0;
+ return 0;
+ }
s->did_backspace = ins_bs(s->c, BACKSPACE_WORD, &s->inserted_space);
auto_format(false, true);
break;
@@ -1653,10 +1672,21 @@ static void init_prompt(int cmdchar_todo)
coladvance(MAXCOL);
changed_bytes(curbuf->b_ml.ml_line_count, 0);
}
+
+ // Insert always starts after the prompt, allow editing text after it.
+ if (Insstart_orig.lnum != curwin->w_cursor.lnum || Insstart_orig.col != (colnr_T)STRLEN(prompt)) {
+ Insstart.lnum = curwin->w_cursor.lnum;
+ Insstart.col = STRLEN(prompt);
+ Insstart_orig = Insstart;
+ Insstart_textlen = Insstart.col;
+ Insstart_blank_vcol = MAXCOL;
+ arrow_used = false;
+ }
+
if (cmdchar_todo == 'A') {
coladvance(MAXCOL);
}
- if (cmdchar_todo == 'I' || curwin->w_cursor.col <= (int)STRLEN(prompt)) {
+ if (curwin->w_cursor.col < (colnr_T)STRLEN(prompt)) {
curwin->w_cursor.col = STRLEN(prompt);
}
// Make sure the cursor is in a valid position.
@@ -8241,7 +8271,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
|| (!revins_on
&& ((curwin->w_cursor.lnum == 1 && curwin->w_cursor.col == 0)
|| (!can_bs(BS_START)
- && (arrow_used
+ && ((arrow_used && !bt_prompt(curbuf))
|| (curwin->w_cursor.lnum == Insstart_orig.lnum
&& curwin->w_cursor.col <= Insstart_orig.col)))
|| (!can_bs(BS_INDENT) && !arrow_used && ai_col > 0
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 6a8b70a158..a899ca63ac 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -521,6 +521,9 @@ static void nlua_print_event(void **argv)
const size_t len = (size_t)(intptr_t)argv[1]-1; // exclude final NUL
for (size_t i = 0; i < len;) {
+ if (got_int) {
+ break;
+ }
const size_t start = i;
while (i < len) {
switch (str[i]) {
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 4146ae0fe3..a666b9c8b0 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -6932,7 +6932,7 @@ int showmode(void)
do_mode = ((p_smd && msg_silent == 0)
&& ((State & TERM_FOCUS)
|| (State & INSERT)
- || restart_edit
+ || restart_edit != NUL
|| VIsual_active));
if (do_mode || reg_recording != 0) {
// Don't show mode right now, when not redrawing or inside a mapping.
@@ -7012,7 +7012,7 @@ int showmode(void)
}
msg_puts_attr(_(" INSERT"), attr);
} else if (restart_edit == 'I' || restart_edit == 'i'
- || restart_edit == 'a') {
+ || restart_edit == 'a' || restart_edit == 'A') {
msg_puts_attr(_(" (insert)"), attr);
} else if (restart_edit == 'R') {
msg_puts_attr(_(" (replace)"), attr);
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index 83ade74db1..afebda4948 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -46,6 +46,7 @@
#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/change.h"
+#include "nvim/cursor.h"
#include "nvim/edit.h"
#include "nvim/event/loop.h"
#include "nvim/event/time.h"
@@ -464,9 +465,7 @@ static void terminal_check_cursor(void)
row_to_linenr(term, term->cursor.row));
// Nudge cursor when returning to normal-mode.
int off = is_focused(term) ? 0 : (curwin->w_p_rl ? 1 : -1);
- curwin->w_cursor.col = MAX(0, term->cursor.col + win_col_off(curwin) + off);
- curwin->w_cursor.coladd = 0;
- mb_check_adjust_col(curwin);
+ coladvance(MAX(0, term->cursor.col + off));
}
// Function executed before each iteration of terminal mode.
diff --git a/src/nvim/testdir/runtest.vim b/src/nvim/testdir/runtest.vim
index 49993c03aa..ab047fd2a8 100644
--- a/src/nvim/testdir/runtest.vim
+++ b/src/nvim/testdir/runtest.vim
@@ -197,7 +197,12 @@ func RunTheTest(test)
" Close any extra tab pages and windows and make the current one not modified.
while tabpagenr('$') > 1
+ let winid = win_getid()
quit!
+ if winid == win_getid()
+ echoerr 'Could not quit window'
+ break
+ endif
endwhile
while 1
diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim
index 69edbc227d..31052ce47d 100644
--- a/src/nvim/testdir/test_filetype.vim
+++ b/src/nvim/testdir/test_filetype.vim
@@ -502,7 +502,7 @@ let s:filename_checks = {
\ 'tex': ['file.latex', 'file.sty', 'file.dtx', 'file.ltx', 'file.bbl'],
\ 'texinfo': ['file.texinfo', 'file.texi', 'file.txi'],
\ 'texmf': ['texmf.cnf'],
- \ 'text': ['file.text', 'README', 'LICENSE', 'COPYING', 'AUTHORS', '/usr/share/doc/bash-completion/AUTHORS', '/etc/apt/apt.conf.d/README', '/etc/Muttrc.d/README'],
+ \ 'text': ['file.text', 'file.txt', 'README', 'LICENSE', 'COPYING', 'AUTHORS', '/usr/share/doc/bash-completion/AUTHORS', '/etc/apt/apt.conf.d/README', '/etc/Muttrc.d/README'],
\ 'tf': ['file.tf', '.tfrc', 'tfrc'],
\ 'tidy': ['.tidyrc', 'tidyrc', 'tidy.conf'],
\ 'tilde': ['file.t.html'],
@@ -568,6 +568,7 @@ let s:filename_checks = {
\ 'yaml': ['file.yaml', 'file.yml'],
\ 'raml': ['file.raml'],
\ 'z8a': ['file.z8a'],
+ \ 'zig': ['file.zig'],
\ 'zimbu': ['file.zu'],
\ 'zimbutempl': ['file.zut'],
\ 'zsh': ['.zprofile', '/etc/zprofile', '.zfbfmarks', 'file.zsh', '.zcompdump', '.zlogin', '.zlogout', '.zshenv', '.zshrc', '.zcompdump-file', '.zlog', '.zlog-file', '.zsh', '.zsh-file', 'any/etc/zprofile', 'zlog', 'zlog-file', 'zsh', 'zsh-file'],
diff --git a/src/nvim/testdir/test_prompt_buffer.vim b/src/nvim/testdir/test_prompt_buffer.vim
index c59a00afcc..8f94a8572b 100644
--- a/src/nvim/testdir/test_prompt_buffer.vim
+++ b/src/nvim/testdir/test_prompt_buffer.vim
@@ -41,6 +41,10 @@ func WriteScript(name)
\ ' set nomodified',
\ 'endfunc',
\ '',
+ \ 'func SwitchWindows()',
+ \ ' call timer_start(0, {-> execute("wincmd p|wincmd p", "")})',
+ \ 'endfunc',
+ \ '',
\ 'call setline(1, "other buffer")',
\ 'set nomodified',
\ 'new',
@@ -89,9 +93,12 @@ func Test_prompt_editing()
call term_sendkeys(buf, left . left . left . bs . '-')
call WaitForAssert({-> assert_equal('cmd: -hel', term_getline(buf, 1))})
+ call term_sendkeys(buf, "\<C-O>lz")
+ call WaitForAssert({-> assert_equal('cmd: -hzel', term_getline(buf, 1))})
+
let end = "\<End>"
call term_sendkeys(buf, end . "x")
- call WaitForAssert({-> assert_equal('cmd: -helx', term_getline(buf, 1))})
+ call WaitForAssert({-> assert_equal('cmd: -hzelx', term_getline(buf, 1))})
call term_sendkeys(buf, "\<C-U>exit\<CR>")
call WaitForAssert({-> assert_equal('other buffer', term_getline(buf, 1))})
@@ -100,6 +107,28 @@ func Test_prompt_editing()
call delete(scriptName)
endfunc
+func Test_prompt_switch_windows()
+ throw 'skipped: TODO'
+ call CanTestPromptBuffer()
+ let scriptName = 'XpromptSwitchWindows'
+ call WriteScript(scriptName)
+
+ let buf = RunVimInTerminal('-S ' . scriptName, {'rows': 12})
+ call WaitForAssert({-> assert_equal('cmd:', term_getline(buf, 1))})
+ call WaitForAssert({-> assert_match('-- INSERT --', term_getline(buf, 12))})
+
+ call term_sendkeys(buf, "\<C-O>:call SwitchWindows()\<CR>")
+ call term_wait(buf, 50)
+ call WaitForAssert({-> assert_match('-- INSERT --', term_getline(buf, 12))})
+
+ call term_sendkeys(buf, "\<Esc>")
+ call term_wait(buf, 50)
+ call WaitForAssert({-> assert_match('^ *$', term_getline(buf, 12))})
+
+ call StopVimInTerminal(buf)
+ call delete(scriptName)
+endfunc
+
func Test_prompt_garbage_collect()
func MyPromptCallback(x, text)
" NOP
@@ -126,6 +155,14 @@ func Test_prompt_garbage_collect()
bwipe!
endfunc
+func Test_prompt_backspace()
+ new
+ set buftype=prompt
+ call feedkeys("A123456\<Left>\<BS>\<Esc>", 'xt')
+ call assert_equal('% 12346', getline(1))
+ bwipe!
+endfunc
+
" Test for editing the prompt buffer
func Test_prompt_buffer_edit()
new
@@ -145,10 +182,9 @@ func Test_prompt_buffer_edit()
call assert_beeps("normal! \<C-X>")
" pressing CTRL-W in the prompt buffer should trigger the window commands
call assert_equal(1, winnr())
- " In Nvim, CTRL-W commands aren't usable from insert mode in a prompt buffer
- " exe "normal A\<C-W>\<C-W>"
- " call assert_equal(2, winnr())
- " wincmd w
+ exe "normal A\<C-W>\<C-W>"
+ call assert_equal(2, winnr())
+ wincmd w
close!
call assert_equal(0, prompt_setprompt([], ''))
endfunc
@@ -187,4 +223,38 @@ func Test_prompt_buffer_getbufinfo()
%bwipe!
endfunc
+function! Test_prompt_while_writing_to_hidden_buffer()
+ throw 'skipped: TODO'
+ call CanTestPromptBuffer()
+ CheckUnix
+
+ " Make a job continuously write to a hidden buffer, check that the prompt
+ " buffer is not affected.
+ let scriptName = 'XpromptscriptHiddenBuf'
+ let script =<< trim END
+ set buftype=prompt
+ call prompt_setprompt( bufnr(), 'cmd:' )
+ let job = job_start(['/bin/sh', '-c',
+ \ 'while true;
+ \ do echo line;
+ \ sleep 0.1;
+ \ done'], #{out_io: 'buffer', out_name: ''})
+ startinsert
+ END
+ eval script->writefile(scriptName)
+
+ let buf = RunVimInTerminal('-S ' .. scriptName, {})
+ call WaitForAssert({-> assert_equal('cmd:', term_getline(buf, 1))})
+
+ call term_sendkeys(buf, 'test')
+ call WaitForAssert({-> assert_equal('cmd:test', term_getline(buf, 1))})
+ call term_sendkeys(buf, 'test')
+ call WaitForAssert({-> assert_equal('cmd:testtest', term_getline(buf, 1))})
+ call term_sendkeys(buf, 'test')
+ call WaitForAssert({-> assert_equal('cmd:testtesttest', term_getline(buf, 1))})
+
+ call StopVimInTerminal(buf)
+ call delete(scriptName)
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 3e6e42dec2..be963d8374 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -2229,6 +2229,54 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int
}
}
+static void leaving_window(win_T *const win)
+ FUNC_ATTR_NONNULL_ALL
+{
+ // Only matters for a prompt window.
+ if (!bt_prompt(win->w_buffer)) {
+ return;
+ }
+
+ // When leaving a prompt window stop Insert mode and perhaps restart
+ // it when entering that window again.
+ win->w_buffer->b_prompt_insert = restart_edit;
+ if (restart_edit != NUL && mode_displayed) {
+ clear_cmdline = true; // unshow mode later
+ }
+ restart_edit = NUL;
+
+ // When leaving the window (or closing the window) was done from a
+ // callback we need to break out of the Insert mode loop and restart Insert
+ // mode when entering the window again.
+ if (State & INSERT) {
+ stop_insert_mode = true;
+ if (win->w_buffer->b_prompt_insert == NUL) {
+ win->w_buffer->b_prompt_insert = 'A';
+ }
+ }
+}
+
+void entering_window(win_T *const win)
+ FUNC_ATTR_NONNULL_ALL
+{
+ // Only matters for a prompt window.
+ if (!bt_prompt(win->w_buffer)) {
+ return;
+ }
+
+ // When switching to a prompt buffer that was in Insert mode, don't stop
+ // Insert mode, it may have been set in leaving_window().
+ if (win->w_buffer->b_prompt_insert != NUL) {
+ stop_insert_mode = false;
+ }
+
+ // When entering the prompt window restart Insert mode if we were in Insert
+ // mode when we left it and not already in Insert mode.
+ if ((State & INSERT) == 0) {
+ restart_edit = win->w_buffer->b_prompt_insert;
+ }
+}
+
/// Closes all windows for buffer `buf`.
///
/// @param keep_curwin don't close `curwin`
@@ -2367,6 +2415,7 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf, tabpage_T *prev
shell_new_rows();
}
}
+ entering_window(curwin);
// Since goto_tabpage_tp above did not trigger *Enter autocommands, do
// that now.
@@ -2434,10 +2483,10 @@ int win_close(win_T *win, bool free_buf)
}
if (win == curwin) {
- /*
- * Guess which window is going to be the new current window.
- * This may change because of the autocommands (sigh).
- */
+ leaving_window(curwin);
+
+ // Guess which window is going to be the new current window.
+ // This may change because of the autocommands (sigh).
if (!win->w_floating) {
wp = frame2win(win_altframe(win, NULL));
} else {
@@ -3801,6 +3850,8 @@ int win_new_tabpage(int after, char_u *filename)
lastused_tabpage = old_curtab;
+ entering_window(curwin);
+
apply_autocmds(EVENT_WINNEW, NULL, NULL, false, curbuf);
apply_autocmds(EVENT_WINENTER, NULL, NULL, false, curbuf);
apply_autocmds(EVENT_TABNEW, filename, filename, false, curbuf);
@@ -3956,6 +4007,7 @@ static int leave_tabpage(buf_T *new_curbuf, bool trigger_leave_autocmds)
{
tabpage_T *tp = curtab;
+ leaving_window(curwin);
reset_VIsual_and_resel(); // stop Visual mode
if (trigger_leave_autocmds) {
if (new_curbuf != curbuf) {
@@ -4478,6 +4530,10 @@ static void win_enter_ext(win_T *const wp, const int flags)
return;
}
+ if (!curwin_invalid) {
+ leaving_window(curwin);
+ }
+
if (!curwin_invalid && (flags & WEE_TRIGGER_LEAVE_AUTOCMDS)) {
// Be careful: If autocommands delete the window, return now.
if (wp->w_buffer != curbuf) {
@@ -4525,6 +4581,7 @@ static void win_enter_ext(win_T *const wp, const int flags)
fix_current_dir();
+ entering_window(curwin);
// Careful: autocommands may close the window and make "wp" invalid
if (flags & WEE_TRIGGER_NEW_AUTOCMDS) {
apply_autocmds(EVENT_WINNEW, NULL, NULL, false, curbuf);