Merge pull request #14499 from janlazo/vim-8.2.2819

vim-patch:8.0.1309,8.2.{1166,2819,2820,2825,2827,2828,2829,2832,2833}
This commit is contained in:
Jan Edmund Lazo
2021-05-06 09:00:24 -04:00
committed by GitHub
20 changed files with 180 additions and 52 deletions

View File

@@ -4316,8 +4316,9 @@ getchar([expr]) *getchar()*
When the user clicks a mouse button, the mouse event will be
returned. The position can then be found in |v:mouse_col|,
|v:mouse_lnum|, |v:mouse_winid| and |v:mouse_win|. This
example positions the mouse as it would normally happen: >
|v:mouse_lnum|, |v:mouse_winid| and |v:mouse_win|.
Mouse move events will be ignored.
This example positions the mouse as it would normally happen: >
let c = getchar()
if c == "\<LeftMouse>" && v:mouse_win > 0
exe v:mouse_win . "wincmd w"

View File

@@ -992,6 +992,7 @@ static int insert_handle_key(InsertState *s)
case K_LEFTDRAG:
case K_LEFTRELEASE:
case K_LEFTRELEASE_NM:
case K_MOUSEMOVE:
case K_MIDDLEMOUSE:
case K_MIDDLEDRAG:
case K_MIDDLERELEASE:

View File

@@ -3016,7 +3016,10 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
n = safe_vgetc();
}
if (n == K_IGNORE || n == K_VER_SCROLLBAR || n == K_HOR_SCROLLBAR) {
if (n == K_IGNORE
|| n == K_MOUSEMOVE
|| n == K_VER_SCROLLBAR
|| n == K_HOR_SCROLLBAR) {
continue;
}
break;

View File

@@ -1953,6 +1953,7 @@ static int command_line_handle_key(CommandLineState *s)
case K_X2MOUSE:
case K_X2DRAG:
case K_X2RELEASE:
case K_MOUSEMOVE:
return command_line_not_changed(s);

View File

@@ -447,18 +447,25 @@ static int put_view(
if (do_cursor) {
// Restore the cursor line in the file and relatively in the
// window. Don't use "G", it changes the jumplist.
if (wp->w_height_inner <= 0) {
if (fprintf(fd, "let s:l = %" PRIdLINENR "\n", wp->w_cursor.lnum) < 0) {
return FAIL;
}
} else if (fprintf(fd,
"let s:l = %" PRIdLINENR " - ((%" PRIdLINENR
" * winheight(0) + %" PRId64 ") / %" PRId64 ")\n",
wp->w_cursor.lnum,
wp->w_cursor.lnum - wp->w_topline,
(int64_t)(wp->w_height_inner / 2),
(int64_t)wp->w_height_inner) < 0) {
return FAIL;
}
if (fprintf(fd,
"let s:l = %" PRId64 " - ((%" PRId64
" * winheight(0) + %" PRId64 ") / %" PRId64 ")\n"
"if s:l < 1 | let s:l = 1 | endif\n"
"keepjumps exe s:l\n"
"normal! zt\n"
"keepjumps %" PRId64 "\n",
(int64_t)wp->w_cursor.lnum,
(int64_t)(wp->w_cursor.lnum - wp->w_topline),
(int64_t)(wp->w_height_inner / 2),
(int64_t)wp->w_height_inner,
(int64_t)wp->w_cursor.lnum) < 0) {
"keepjumps %" PRIdLINENR "\n",
wp->w_cursor.lnum) < 0) {
return FAIL;
}
// Restore the cursor column and left offset when not wrapping.

View File

@@ -4560,11 +4560,12 @@ int vim_rename(const char_u *from, const char_u *to)
if (!os_path_exists(tempname)) {
if (os_rename(from, tempname) == OK) {
if (os_rename(tempname, to) == OK)
if (os_rename(tempname, to) == OK) {
return 0;
/* Strange, the second step failed. Try moving the
* file back and return failure. */
os_rename(tempname, from);
}
// Strange, the second step failed. Try moving the
// file back and return failure.
(void)os_rename(tempname, from);
return -1;
}
/* If it fails for one temp name it will most likely fail

View File

@@ -1322,7 +1322,7 @@ void openscript(
do {
update_topline_cursor(); // update cursor position and topline
normal_cmd(&oa, false); // execute one command
vpeekc(); // check for end of file
(void)vpeekc(); // check for end of file
} while (scriptin[oldcurscript] != NULL);
State = save_State;
@@ -1586,7 +1586,9 @@ int plain_vgetc(void)
do {
c = safe_vgetc();
} while (c == K_IGNORE || c == K_VER_SCROLLBAR || c == K_HOR_SCROLLBAR);
} while (c == K_IGNORE
|| c == K_VER_SCROLLBAR || c == K_HOR_SCROLLBAR
|| c == K_MOUSEMOVE);
return c;
}
@@ -3831,7 +3833,16 @@ bool check_abbr(int c, char_u *ptr, int col, int mincol)
if (c >= ABBR_OFF) {
c -= ABBR_OFF;
}
j += utf_char2bytes(c, tb + j);
int newlen = utf_char2bytes(c, tb + j);
tb[j + newlen] = NUL;
// Need to escape K_SPECIAL.
char_u *escaped = vim_strsave_escape_csi(tb + j);
if (escaped != NULL) {
newlen = (int)STRLEN(escaped);
memmove(tb + j, escaped, (size_t)newlen);
j += newlen;
xfree(escaped);
}
}
tb[j] = NUL;
// insert the last typed char

View File

@@ -288,6 +288,7 @@ static const struct key_name_entry {
{ K_LEFTDRAG, "LeftDrag" },
{ K_LEFTRELEASE, "LeftRelease" },
{ K_LEFTRELEASE_NM, "LeftReleaseNM" },
{ K_MOUSEMOVE, "MouseMove" },
{ K_MIDDLEMOUSE, "MiddleMouse" },
{ K_MIDDLEDRAG, "MiddleDrag" },
{ K_MIDDLERELEASE, "MiddleRelease" },
@@ -317,32 +318,32 @@ static const struct key_name_entry {
};
static struct mousetable {
int pseudo_code; /* Code for pseudo mouse event */
int button; /* Which mouse button is it? */
int is_click; /* Is it a mouse button click event? */
int is_drag; /* Is it a mouse drag event? */
int pseudo_code; // Code for pseudo mouse event
int button; // Which mouse button is it?
bool is_click; // Is it a mouse button click event?
bool is_drag; // Is it a mouse drag event?
} mouse_table[] =
{
{(int)KE_LEFTMOUSE, MOUSE_LEFT, TRUE, FALSE},
{(int)KE_LEFTDRAG, MOUSE_LEFT, FALSE, TRUE},
{(int)KE_LEFTRELEASE, MOUSE_LEFT, FALSE, FALSE},
{(int)KE_MIDDLEMOUSE, MOUSE_MIDDLE, TRUE, FALSE},
{(int)KE_MIDDLEDRAG, MOUSE_MIDDLE, FALSE, TRUE},
{(int)KE_MIDDLERELEASE, MOUSE_MIDDLE, FALSE, FALSE},
{(int)KE_RIGHTMOUSE, MOUSE_RIGHT, TRUE, FALSE},
{(int)KE_RIGHTDRAG, MOUSE_RIGHT, FALSE, TRUE},
{(int)KE_RIGHTRELEASE, MOUSE_RIGHT, FALSE, FALSE},
{(int)KE_X1MOUSE, MOUSE_X1, TRUE, FALSE},
{(int)KE_X1DRAG, MOUSE_X1, FALSE, TRUE},
{(int)KE_X1RELEASE, MOUSE_X1, FALSE, FALSE},
{(int)KE_X2MOUSE, MOUSE_X2, TRUE, FALSE},
{(int)KE_X2DRAG, MOUSE_X2, FALSE, TRUE},
{(int)KE_X2RELEASE, MOUSE_X2, FALSE, FALSE},
/* DRAG without CLICK */
{(int)KE_IGNORE, MOUSE_RELEASE, FALSE, TRUE},
/* RELEASE without CLICK */
{(int)KE_IGNORE, MOUSE_RELEASE, FALSE, FALSE},
{0, 0, 0, 0},
{ (int)KE_LEFTMOUSE, MOUSE_LEFT, true, false },
{ (int)KE_LEFTDRAG, MOUSE_LEFT, false, true },
{ (int)KE_LEFTRELEASE, MOUSE_LEFT, false, false },
{ (int)KE_MIDDLEMOUSE, MOUSE_MIDDLE, true, false },
{ (int)KE_MIDDLEDRAG, MOUSE_MIDDLE, false, true },
{ (int)KE_MIDDLERELEASE, MOUSE_MIDDLE, false, false },
{ (int)KE_RIGHTMOUSE, MOUSE_RIGHT, true, false },
{ (int)KE_RIGHTDRAG, MOUSE_RIGHT, false, true },
{ (int)KE_RIGHTRELEASE, MOUSE_RIGHT, false, false },
{ (int)KE_X1MOUSE, MOUSE_X1, true, false },
{ (int)KE_X1DRAG, MOUSE_X1, false, true },
{ (int)KE_X1RELEASE, MOUSE_X1, false, false },
{ (int)KE_X2MOUSE, MOUSE_X2, true, false },
{ (int)KE_X2DRAG, MOUSE_X2, false, true },
{ (int)KE_X2RELEASE, MOUSE_X2, false, false },
// DRAG without CLICK
{ (int)K_MOUSEMOVE, MOUSE_RELEASE, false, true },
// RELEASE without CLICK
{ (int)KE_IGNORE, MOUSE_RELEASE, false, false },
{ 0, 0, 0, 0 },
};
/// Return the modifier mask bit (#MOD_MASK_*) corresponding to mod name

View File

@@ -242,7 +242,7 @@ enum key_extra {
, KE_NOP = 97 // no-op: does nothing
// , KE_FOCUSGAINED = 98 // focus gained
// , KE_FOCUSLOST = 99 // focus lost
// , KE_MOUSEMOVE = 100 // mouse moved with no button down
, KE_MOUSEMOVE = 100 // mouse moved with no button down
// , KE_CANCEL = 101 // return from vgetc
, KE_EVENT = 102 // event
, KE_COMMAND = 104 // <Cmd> special key
@@ -411,6 +411,7 @@ enum key_extra {
#define K_LEFTDRAG TERMCAP2KEY(KS_EXTRA, KE_LEFTDRAG)
#define K_LEFTRELEASE TERMCAP2KEY(KS_EXTRA, KE_LEFTRELEASE)
#define K_LEFTRELEASE_NM TERMCAP2KEY(KS_EXTRA, KE_LEFTRELEASE_NM)
#define K_MOUSEMOVE TERMCAP2KEY(KS_EXTRA, KE_MOUSEMOVE)
#define K_MIDDLEMOUSE TERMCAP2KEY(KS_EXTRA, KE_MIDDLEMOUSE)
#define K_MIDDLEDRAG TERMCAP2KEY(KS_EXTRA, KE_MIDDLEDRAG)
#define K_MIDDLERELEASE TERMCAP2KEY(KS_EXTRA, KE_MIDDLERELEASE)

View File

@@ -1193,7 +1193,8 @@ void wait_return(int redraw)
|| c == K_MIDDLEDRAG || c == K_MIDDLERELEASE
|| c == K_RIGHTDRAG || c == K_RIGHTRELEASE
|| c == K_MOUSELEFT || c == K_MOUSERIGHT
|| c == K_MOUSEDOWN || c == K_MOUSEUP);
|| c == K_MOUSEDOWN || c == K_MOUSEUP
|| c == K_MOUSEMOVE);
os_breakcheck();
/*
* Avoid that the mouse-up event causes visual mode to start.

View File

@@ -602,6 +602,7 @@ int is_mouse_key(int c)
|| c == K_LEFTDRAG
|| c == K_LEFTRELEASE
|| c == K_LEFTRELEASE_NM
|| c == K_MOUSEMOVE
|| c == K_MIDDLEMOUSE
|| c == K_MIDDLEDRAG
|| c == K_MIDDLERELEASE

View File

@@ -294,6 +294,7 @@ static const struct nv_cmd {
{ K_LEFTDRAG, nv_mouse, 0, 0 },
{ K_LEFTRELEASE, nv_mouse, 0, 0 },
{ K_LEFTRELEASE_NM, nv_mouse, 0, 0 },
{ K_MOUSEMOVE, nv_mouse, 0, 0 },
{ K_MIDDLEMOUSE, nv_mouse, 0, 0 },
{ K_MIDDLEDRAG, nv_mouse, 0, 0 },
{ K_MIDDLERELEASE, nv_mouse, 0, 0 },
@@ -879,8 +880,9 @@ static void normal_finish_command(NormalState *s)
s->old_mapped_len = typebuf_maplen();
}
// If an operation is pending, handle it. But not for K_IGNORE.
if (s->ca.cmdchar != K_IGNORE) {
// If an operation is pending, handle it. But not for K_IGNORE or
// K_MOUSEMOVE.
if (s->ca.cmdchar != K_IGNORE && s->ca.cmdchar != K_MOUSEMOVE) {
do_pending_operator(&s->ca, s->old_col, false);
}
@@ -2263,6 +2265,10 @@ do_mouse (
break;
}
if (c == K_MOUSEMOVE) {
// Mouse moved without a button pressed.
return false;
}
/*
* Ignore drag and release events if we didn't get a click.
@@ -3390,7 +3396,7 @@ bool add_to_showcmd(int c)
static int ignore[] =
{
K_IGNORE,
K_LEFTMOUSE, K_LEFTDRAG, K_LEFTRELEASE,
K_LEFTMOUSE, K_LEFTDRAG, K_LEFTRELEASE, K_MOUSEMOVE,
K_MIDDLEMOUSE, K_MIDDLEDRAG, K_MIDDLERELEASE,
K_RIGHTMOUSE, K_RIGHTDRAG, K_RIGHTRELEASE,
K_MOUSEDOWN, K_MOUSEUP, K_MOUSELEFT, K_MOUSERIGHT,
@@ -7036,6 +7042,7 @@ static void nv_g_cmd(cmdarg_T *cap)
case K_LEFTMOUSE:
case K_LEFTDRAG:
case K_LEFTRELEASE:
case K_MOUSEMOVE:
case K_RIGHTMOUSE:
case K_RIGHTDRAG:
case K_RIGHTRELEASE:

View File

@@ -3436,7 +3436,7 @@ static long bt_regexec_multi(regmmatch_T *rmp, win_T *win, buf_T *buf,
}
/// Match a regexp against a string ("line" points to the string) or multiple
/// lines ("line" is NULL, use reg_getline()).
/// lines (if "line" is NULL, use reg_getline()).
/// @return 0 for failure, or number of lines contained in the match.
static long bt_regexec_both(char_u *line,
colnr_T col, // column to start search

View File

@@ -6491,7 +6491,7 @@ static long nfa_regtry(nfa_regprog_T *prog,
}
/// Match a regexp against a string ("line" points to the string) or multiple
/// lines ("line" is NULL, use reg_getline()).
/// lines (if "line" is NULL, use reg_getline()).
///
/// @param line String in which to search or NULL
/// @param startcol Column to start looking for match

View File

@@ -450,6 +450,7 @@ static int terminal_execute(VimState *state, int key)
case K_LEFTMOUSE:
case K_LEFTDRAG:
case K_LEFTRELEASE:
case K_MOUSEMOVE:
case K_MIDDLEMOUSE:
case K_MIDDLEDRAG:
case K_MIDDLERELEASE:
@@ -1098,6 +1099,7 @@ static bool send_mouse_event(Terminal *term, int c)
switch (c) {
case K_LEFTDRAG: drag = true; FALLTHROUGH;
case K_LEFTMOUSE: button = 1; break;
case K_MOUSEMOVE: drag = true; button = 0; break;
case K_MIDDLEDRAG: drag = true; FALLTHROUGH;
case K_MIDDLEMOUSE: button = 2; break;
case K_RIGHTDRAG: drag = true; FALLTHROUGH;

View File

@@ -132,6 +132,61 @@ func Test_confirm_cmd_cancel()
call StopVimInTerminal(buf)
endfunc
func Test_confirm_write_ro()
CheckNotGui
CheckRunVimInTerminal
call writefile(['foo'], 'Xconfirm_write_ro')
let lines =<< trim END
set nobackup ff=unix cmdheight=2
edit Xconfirm_write_ro
norm Abar
END
call writefile(lines, 'Xscript')
let buf = RunVimInTerminal('-S Xscript', {'rows': 20})
" Try to write with 'ro' option.
call term_sendkeys(buf, ":set ro | confirm w\n")
call WaitForAssert({-> assert_match("^'readonly' option is set for \"Xconfirm_write_ro\"\. *$",
\ term_getline(buf, 18))}, 1000)
call WaitForAssert({-> assert_match('^Do you wish to write anyway? *$',
\ term_getline(buf, 19))}, 1000)
call WaitForAssert({-> assert_match('^(Y)es, \[N\]o: *$', term_getline(buf, 20))}, 1000)
call term_sendkeys(buf, 'N')
call WaitForAssert({-> assert_match('^ *$', term_getline(buf, 19))}, 1000)
call WaitForAssert({-> assert_match('.* All$', term_getline(buf, 20))}, 1000)
call assert_equal(['foo'], readfile('Xconfirm_write_ro'))
call term_sendkeys(buf, ":confirm w\n")
call WaitForAssert({-> assert_match("^'readonly' option is set for \"Xconfirm_write_ro\"\. *$",
\ term_getline(buf, 18))}, 1000)
call WaitForAssert({-> assert_match('^Do you wish to write anyway? *$',
\ term_getline(buf, 19))}, 1000)
call WaitForAssert({-> assert_match('^(Y)es, \[N\]o: *$', term_getline(buf, 20))}, 1000)
call term_sendkeys(buf, 'Y')
call WaitForAssert({-> assert_match('^"Xconfirm_write_ro" 1L, 7B written$',
\ term_getline(buf, 19))}, 1000)
call assert_equal(['foobar'], readfile('Xconfirm_write_ro'))
" Try to write with read-only file permissions.
call setfperm('Xconfirm_write_ro', 'r--r--r--')
call term_sendkeys(buf, ":set noro | undo | confirm w\n")
call WaitForAssert({-> assert_match("^File permissions of \"Xconfirm_write_ro\" are read-only\. *$",
\ term_getline(buf, 17))}, 1000)
call WaitForAssert({-> assert_match('^It may still be possible to write it\. *$',
\ term_getline(buf, 18))}, 1000)
call WaitForAssert({-> assert_match('^Do you wish to try? *$', term_getline(buf, 19))}, 1000)
call WaitForAssert({-> assert_match('^(Y)es, \[N\]o: *$', term_getline(buf, 20))}, 1000)
call term_sendkeys(buf, 'Y')
call WaitForAssert({-> assert_match('^"Xconfirm_write_ro" 1L, 4B written$',
\ term_getline(buf, 19))}, 1000)
call assert_equal(['foo'], readfile('Xconfirm_write_ro'))
call StopVimInTerminal(buf)
call delete('Xscript')
call delete('Xconfirm_write_ro')
endfunc
" Test for the :winsize command
func Test_winsize_cmd()
call assert_fails('winsize 1', 'E465:')

View File

@@ -1,6 +1,6 @@
" Test for :execute, :while and :if
" Test for :execute, :while, :for and :if
function Test_exec_while_if()
func Test_exec_while_if()
new
let i = 0
@@ -50,4 +50,6 @@ function Test_exec_while_if()
\ "7x999999999888888887777777666666555554444333221",
\ "8",
\ "9x"], getline(1, 10))
endfunction
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -559,4 +559,13 @@ func Test_map_cmdkey_redo()
ounmap i-
endfunc
func Test_abbreviate_multi_byte()
new
iabbrev foo bar
call feedkeys("ifoo…\<Esc>", 'xt')
call assert_equal("bar…", getline(1))
iunabbrev foo
bwipe!
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -149,6 +149,21 @@ func Test_mksession_large_winheight()
call delete('Xtest_mks_winheight.out')
endfunc
func Test_mksession_zero_winheight()
set winminheight=0
edit SomeFile
split
wincmd _
mksession! Xtest_mks_zero
set winminheight&
" let text = readfile('Xtest_mks_zero')->join()
let text = join(readfile('Xtest_mks_zero'))
call delete('Xtest_mks_zero')
close
" check there is no divide by zero
call assert_notmatch('/ 0[^0-9]', text)
endfunc
func Test_mksession_rtp()
if has('win32')
" TODO: fix problem with backslashes

View File

@@ -754,4 +754,13 @@ func Test_submatch_list_concatenate()
call assert_equal(substitute('A1', pat, Rep, ''), "[['A1'], ['1']]")
endfunc
func Test_substitute_skipped_range()
new
if 0
/1/5/2/2/\n
endif
call assert_equal([0, 1, 1, 0, 1], getcurpos())
bwipe!
endfunc
" vim: shiftwidth=2 sts=2 expandtab