mirror of
https://github.com/neovim/neovim.git
synced 2025-09-15 07:48:18 +00:00
Merge #8744 from janlazo/vim-8.0.0890
This commit is contained in:
111
src/nvim/edit.c
111
src/nvim/edit.c
@@ -240,8 +240,8 @@ static int ins_need_undo; /* call u_save() before inserting a
|
|||||||
char. Set when edit() is called.
|
char. Set when edit() is called.
|
||||||
after that arrow_used is used. */
|
after that arrow_used is used. */
|
||||||
|
|
||||||
static int did_add_space = FALSE; /* auto_format() added an extra space
|
static bool did_add_space = false; // auto_format() added an extra space
|
||||||
under the cursor */
|
// under the cursor
|
||||||
static TriState dont_sync_undo = kFalse; // CTRL-G U prevents syncing undo
|
static TriState dont_sync_undo = kFalse; // CTRL-G U prevents syncing undo
|
||||||
// for the next left/right cursor
|
// for the next left/right cursor
|
||||||
|
|
||||||
@@ -1766,8 +1766,8 @@ change_indent (
|
|||||||
/* We only put back the new line up to the cursor */
|
/* We only put back the new line up to the cursor */
|
||||||
new_line[curwin->w_cursor.col] = NUL;
|
new_line[curwin->w_cursor.col] = NUL;
|
||||||
|
|
||||||
/* Put back original line */
|
// Put back original line
|
||||||
ml_replace(curwin->w_cursor.lnum, orig_line, FALSE);
|
ml_replace(curwin->w_cursor.lnum, orig_line, false);
|
||||||
curwin->w_cursor.col = orig_col;
|
curwin->w_cursor.col = orig_col;
|
||||||
|
|
||||||
/* Backspace from cursor to start of line */
|
/* Backspace from cursor to start of line */
|
||||||
@@ -5693,8 +5693,8 @@ auto_format (
|
|||||||
pos = curwin->w_cursor;
|
pos = curwin->w_cursor;
|
||||||
old = get_cursor_line_ptr();
|
old = get_cursor_line_ptr();
|
||||||
|
|
||||||
/* may remove added space */
|
// may remove added space
|
||||||
check_auto_format(FALSE);
|
check_auto_format(false);
|
||||||
|
|
||||||
/* Don't format in Insert mode when the cursor is on a trailing blank, the
|
/* Don't format in Insert mode when the cursor is on a trailing blank, the
|
||||||
* user might insert normal text next. Also skip formatting when "1" is
|
* user might insert normal text next. Also skip formatting when "1" is
|
||||||
@@ -5760,12 +5760,13 @@ auto_format (
|
|||||||
pnew = vim_strnsave(new, len + 2);
|
pnew = vim_strnsave(new, len + 2);
|
||||||
pnew[len] = ' ';
|
pnew[len] = ' ';
|
||||||
pnew[len + 1] = NUL;
|
pnew[len + 1] = NUL;
|
||||||
ml_replace(curwin->w_cursor.lnum, pnew, FALSE);
|
ml_replace(curwin->w_cursor.lnum, pnew, false);
|
||||||
/* remove the space later */
|
// remove the space later
|
||||||
did_add_space = TRUE;
|
did_add_space = true;
|
||||||
} else
|
} else {
|
||||||
/* may remove added space */
|
// may remove added space
|
||||||
check_auto_format(FALSE);
|
check_auto_format(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
check_cursor();
|
check_cursor();
|
||||||
@@ -5776,9 +5777,8 @@ auto_format (
|
|||||||
* delete it now. The space must be under the cursor, just after the insert
|
* delete it now. The space must be under the cursor, just after the insert
|
||||||
* position.
|
* position.
|
||||||
*/
|
*/
|
||||||
static void
|
static void check_auto_format(
|
||||||
check_auto_format (
|
bool end_insert // true when ending Insert mode
|
||||||
int end_insert /* TRUE when ending Insert mode */
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int c = ' ';
|
int c = ' ';
|
||||||
@@ -5786,19 +5786,19 @@ check_auto_format (
|
|||||||
|
|
||||||
if (did_add_space) {
|
if (did_add_space) {
|
||||||
cc = gchar_cursor();
|
cc = gchar_cursor();
|
||||||
if (!WHITECHAR(cc))
|
if (!WHITECHAR(cc)) {
|
||||||
/* Somehow the space was removed already. */
|
// Somehow the space was removed already.
|
||||||
did_add_space = FALSE;
|
did_add_space = false;
|
||||||
else {
|
} else {
|
||||||
if (!end_insert) {
|
if (!end_insert) {
|
||||||
inc_cursor();
|
inc_cursor();
|
||||||
c = gchar_cursor();
|
c = gchar_cursor();
|
||||||
dec_cursor();
|
dec_cursor();
|
||||||
}
|
}
|
||||||
if (c != NUL) {
|
if (c != NUL) {
|
||||||
/* The space is no longer at the end of the line, delete it. */
|
// The space is no longer at the end of the line, delete it.
|
||||||
del_char(FALSE);
|
del_char(false);
|
||||||
did_add_space = FALSE;
|
did_add_space = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6023,8 +6023,8 @@ stop_insert (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If a space was inserted for auto-formatting, remove it now. */
|
// If a space was inserted for auto-formatting, remove it now.
|
||||||
check_auto_format(TRUE);
|
check_auto_format(true);
|
||||||
|
|
||||||
/* If we just did an auto-indent, remove the white space from the end
|
/* If we just did an auto-indent, remove the white space from the end
|
||||||
* of the line, and put the cursor back.
|
* of the line, and put the cursor back.
|
||||||
@@ -6043,10 +6043,12 @@ stop_insert (
|
|||||||
if (gchar_cursor() == NUL && curwin->w_cursor.col > 0)
|
if (gchar_cursor() == NUL && curwin->w_cursor.col > 0)
|
||||||
--curwin->w_cursor.col;
|
--curwin->w_cursor.col;
|
||||||
cc = gchar_cursor();
|
cc = gchar_cursor();
|
||||||
if (!ascii_iswhite(cc))
|
if (!ascii_iswhite(cc)) {
|
||||||
break;
|
break;
|
||||||
if (del_char(TRUE) == FAIL)
|
}
|
||||||
break; /* should not happen */
|
if (del_char(true) == FAIL) {
|
||||||
|
break; // should not happen
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (curwin->w_cursor.lnum != tpos.lnum)
|
if (curwin->w_cursor.lnum != tpos.lnum)
|
||||||
curwin->w_cursor = tpos;
|
curwin->w_cursor = tpos;
|
||||||
@@ -6698,8 +6700,8 @@ static void replace_do_bs(int limit_col)
|
|||||||
* text aligned. */
|
* text aligned. */
|
||||||
curwin->w_cursor.col += ins_len;
|
curwin->w_cursor.col += ins_len;
|
||||||
while (vcol > orig_vcols && gchar_cursor() == ' ') {
|
while (vcol > orig_vcols && gchar_cursor() == ' ') {
|
||||||
del_char(FALSE);
|
del_char(false);
|
||||||
++orig_vcols;
|
orig_vcols++;
|
||||||
}
|
}
|
||||||
curwin->w_cursor.col -= ins_len;
|
curwin->w_cursor.col -= ins_len;
|
||||||
}
|
}
|
||||||
@@ -7441,13 +7443,15 @@ static void ins_shift(int c, int lastc)
|
|||||||
*/
|
*/
|
||||||
if (c == Ctrl_D && (lastc == '0' || lastc == '^')
|
if (c == Ctrl_D && (lastc == '0' || lastc == '^')
|
||||||
&& curwin->w_cursor.col > 0) {
|
&& curwin->w_cursor.col > 0) {
|
||||||
--curwin->w_cursor.col;
|
curwin->w_cursor.col--;
|
||||||
(void)del_char(FALSE); /* delete the '^' or '0' */
|
(void)del_char(false); // delete the '^' or '0'
|
||||||
/* In Replace mode, restore the characters that '^' or '0' replaced. */
|
// In Replace mode, restore the characters that '^' or '0' replaced.
|
||||||
if (State & REPLACE_FLAG)
|
if (State & REPLACE_FLAG) {
|
||||||
replace_pop_ins();
|
replace_pop_ins();
|
||||||
if (lastc == '^')
|
}
|
||||||
old_indent = get_indent(); /* remember curr. indent */
|
if (lastc == '^') {
|
||||||
|
old_indent = get_indent(); // remember curr. indent
|
||||||
|
}
|
||||||
change_indent(INDENT_SET, 0, TRUE, 0, TRUE);
|
change_indent(INDENT_SET, 0, TRUE, 0, TRUE);
|
||||||
} else
|
} else
|
||||||
change_indent(c == Ctrl_D ? INDENT_DEC : INDENT_INC, 0, TRUE, 0, TRUE);
|
change_indent(c == Ctrl_D ? INDENT_DEC : INDENT_INC, 0, TRUE, 0, TRUE);
|
||||||
@@ -7463,17 +7467,23 @@ static void ins_shift(int c, int lastc)
|
|||||||
|
|
||||||
static void ins_del(void)
|
static void ins_del(void)
|
||||||
{
|
{
|
||||||
int temp;
|
if (stop_arrow() == FAIL) {
|
||||||
|
|
||||||
if (stop_arrow() == FAIL)
|
|
||||||
return;
|
return;
|
||||||
if (gchar_cursor() == NUL) { /* delete newline */
|
}
|
||||||
temp = curwin->w_cursor.col;
|
if (gchar_cursor() == NUL) { // delete newline
|
||||||
|
const int temp = curwin->w_cursor.col;
|
||||||
if (!can_bs(BS_EOL) // only if "eol" included
|
if (!can_bs(BS_EOL) // only if "eol" included
|
||||||
|| do_join(2, false, true, false, false) == FAIL) {
|
|| do_join(2, false, true, false, false) == FAIL) {
|
||||||
vim_beep(BO_BS);
|
vim_beep(BO_BS);
|
||||||
} else {
|
} else {
|
||||||
curwin->w_cursor.col = temp;
|
curwin->w_cursor.col = temp;
|
||||||
|
// Adjust orig_line_count in case more lines have been deleted than
|
||||||
|
// have been added. That makes sure, that open_line() later
|
||||||
|
// can access all buffer lines correctly
|
||||||
|
if (State & VREPLACE_FLAG
|
||||||
|
&& orig_line_count > curbuf->b_ml.ml_line_count) {
|
||||||
|
orig_line_count = curbuf->b_ml.ml_line_count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (del_char(false) == FAIL) { // delete char under cursor
|
} else if (del_char(false) == FAIL) { // delete char under cursor
|
||||||
vim_beep(BO_BS);
|
vim_beep(BO_BS);
|
||||||
@@ -7499,8 +7509,9 @@ static void ins_bs_one(colnr_T *vcolp)
|
|||||||
if (curwin->w_cursor.lnum != Insstart.lnum
|
if (curwin->w_cursor.lnum != Insstart.lnum
|
||||||
|| curwin->w_cursor.col >= Insstart.col)
|
|| curwin->w_cursor.col >= Insstart.col)
|
||||||
replace_do_bs(-1);
|
replace_do_bs(-1);
|
||||||
} else
|
} else {
|
||||||
(void)del_char(FALSE);
|
(void)del_char(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle Backspace, delete-word and delete-line in Insert mode.
|
/// Handle Backspace, delete-word and delete-line in Insert mode.
|
||||||
@@ -7764,16 +7775,16 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
|
|||||||
else {
|
else {
|
||||||
const bool l_enc_utf8 = enc_utf8;
|
const bool l_enc_utf8 = enc_utf8;
|
||||||
const int l_p_deco = p_deco;
|
const int l_p_deco = p_deco;
|
||||||
if (l_enc_utf8 && l_p_deco)
|
if (l_enc_utf8 && l_p_deco) {
|
||||||
(void)utfc_ptr2char(get_cursor_pos_ptr(), cpc);
|
(void)utfc_ptr2char(get_cursor_pos_ptr(), cpc);
|
||||||
(void)del_char(FALSE);
|
}
|
||||||
/*
|
(void)del_char(false);
|
||||||
* If there are combining characters and 'delcombine' is set
|
// If there are combining characters and 'delcombine' is set
|
||||||
* move the cursor back. Don't back up before the base
|
// move the cursor back. Don't back up before the base
|
||||||
* character.
|
// character.
|
||||||
*/
|
if (l_enc_utf8 && l_p_deco && cpc[0] != NUL) {
|
||||||
if (l_enc_utf8 && l_p_deco && cpc[0] != NUL)
|
|
||||||
inc_cursor();
|
inc_cursor();
|
||||||
|
}
|
||||||
if (revins_chars) {
|
if (revins_chars) {
|
||||||
revins_chars--;
|
revins_chars--;
|
||||||
revins_legal++;
|
revins_legal++;
|
||||||
|
@@ -10210,32 +10210,34 @@ static void f_gettabinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
static void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
static void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||||
{
|
{
|
||||||
win_T *oldcurwin;
|
win_T *oldcurwin;
|
||||||
tabpage_T *tp, *oldtabpage;
|
tabpage_T *oldtabpage;
|
||||||
dictitem_T *v;
|
|
||||||
bool done = false;
|
bool done = false;
|
||||||
|
|
||||||
rettv->v_type = VAR_STRING;
|
rettv->v_type = VAR_STRING;
|
||||||
rettv->vval.v_string = NULL;
|
rettv->vval.v_string = NULL;
|
||||||
|
|
||||||
const char *const varname = tv_get_string_chk(&argvars[1]);
|
const char *const varname = tv_get_string_chk(&argvars[1]);
|
||||||
tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL));
|
tabpage_T *const tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL));
|
||||||
if (tp != NULL && varname != NULL) {
|
if (tp != NULL && varname != NULL) {
|
||||||
// Set tp to be our tabpage, temporarily. Also set the window to the
|
// Set tp to be our tabpage, temporarily. Also set the window to the
|
||||||
// first window in the tabpage, otherwise the window is not valid.
|
// first window in the tabpage, otherwise the window is not valid.
|
||||||
win_T *window = tp->tp_firstwin == NULL ? firstwin : tp->tp_firstwin;
|
win_T *const window = tp == curtab || tp->tp_firstwin == NULL
|
||||||
|
? firstwin
|
||||||
|
: tp->tp_firstwin;
|
||||||
if (switch_win(&oldcurwin, &oldtabpage, window, tp, true) == OK) {
|
if (switch_win(&oldcurwin, &oldtabpage, window, tp, true) == OK) {
|
||||||
// look up the variable
|
// look up the variable
|
||||||
// Let gettabvar({nr}, "") return the "t:" dictionary.
|
// Let gettabvar({nr}, "") return the "t:" dictionary.
|
||||||
v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't',
|
const dictitem_T *const v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't',
|
||||||
varname, strlen(varname), false);
|
varname, strlen(varname),
|
||||||
|
false);
|
||||||
if (v != NULL) {
|
if (v != NULL) {
|
||||||
tv_copy(&v->di_tv, rettv);
|
tv_copy(&v->di_tv, rettv);
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* restore previous notion of curwin */
|
// restore previous notion of curwin
|
||||||
restore_win(oldcurwin, oldtabpage, TRUE);
|
restore_win(oldcurwin, oldtabpage, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!done && argvars[2].v_type != VAR_UNKNOWN) {
|
if (!done && argvars[2].v_type != VAR_UNKNOWN) {
|
||||||
|
@@ -716,11 +716,13 @@ void ex_retab(exarg_T *eap)
|
|||||||
memmove(new_line + start_col + len,
|
memmove(new_line + start_col + len,
|
||||||
ptr + col, (size_t)(old_len - col + 1));
|
ptr + col, (size_t)(old_len - col + 1));
|
||||||
ptr = new_line + start_col;
|
ptr = new_line + start_col;
|
||||||
for (col = 0; col < len; col++)
|
for (col = 0; col < len; col++) {
|
||||||
ptr[col] = (col < num_tabs) ? '\t' : ' ';
|
ptr[col] = (col < num_tabs) ? '\t' : ' ';
|
||||||
ml_replace(lnum, new_line, FALSE);
|
}
|
||||||
if (first_line == 0)
|
ml_replace(lnum, new_line, false);
|
||||||
|
if (first_line == 0) {
|
||||||
first_line = lnum;
|
first_line = lnum;
|
||||||
|
}
|
||||||
last_line = lnum;
|
last_line = lnum;
|
||||||
ptr = new_line;
|
ptr = new_line;
|
||||||
col = start_col + len;
|
col = start_col + len;
|
||||||
@@ -1598,6 +1600,7 @@ void ex_file(exarg_T *eap)
|
|||||||
// print full file name if :cd used
|
// print full file name if :cd used
|
||||||
fileinfo(false, false, eap->forceit);
|
fileinfo(false, false, eap->forceit);
|
||||||
}
|
}
|
||||||
|
redraw_tabline = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3624,7 +3627,7 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
|
|||||||
// before the cursor.
|
// before the cursor.
|
||||||
len_change = (int)STRLEN(new_line) - (int)STRLEN(orig_line);
|
len_change = (int)STRLEN(new_line) - (int)STRLEN(orig_line);
|
||||||
curwin->w_cursor.col += len_change;
|
curwin->w_cursor.col += len_change;
|
||||||
ml_replace(lnum, new_line, FALSE);
|
ml_replace(lnum, new_line, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
search_match_lines = regmatch.endpos[0].lnum
|
search_match_lines = regmatch.endpos[0].lnum
|
||||||
@@ -3666,9 +3669,10 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
|
|||||||
msg_col = 0;
|
msg_col = 0;
|
||||||
gotocmdline(TRUE);
|
gotocmdline(TRUE);
|
||||||
|
|
||||||
/* restore the line */
|
// restore the line
|
||||||
if (orig_line != NULL)
|
if (orig_line != NULL) {
|
||||||
ml_replace(lnum, orig_line, FALSE);
|
ml_replace(lnum, orig_line, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
need_wait_return = FALSE; /* no hit-return prompt */
|
need_wait_return = FALSE; /* no hit-return prompt */
|
||||||
@@ -3925,9 +3929,10 @@ skip:
|
|||||||
prev_matchcol = (colnr_T)STRLEN(sub_firstline)
|
prev_matchcol = (colnr_T)STRLEN(sub_firstline)
|
||||||
- prev_matchcol;
|
- prev_matchcol;
|
||||||
|
|
||||||
if (u_savesub(lnum) != OK)
|
if (u_savesub(lnum) != OK) {
|
||||||
break;
|
break;
|
||||||
ml_replace(lnum, new_start, TRUE);
|
}
|
||||||
|
ml_replace(lnum, new_start, true);
|
||||||
|
|
||||||
if (nmatch_tl > 0) {
|
if (nmatch_tl > 0) {
|
||||||
/*
|
/*
|
||||||
|
@@ -6084,7 +6084,7 @@ static int open_cmdwin(void)
|
|||||||
|
|
||||||
/* Replace the empty last line with the current command-line and put the
|
/* Replace the empty last line with the current command-line and put the
|
||||||
* cursor there. */
|
* cursor there. */
|
||||||
ml_replace(curbuf->b_ml.ml_line_count, ccline.cmdbuff, TRUE);
|
ml_replace(curbuf->b_ml.ml_line_count, ccline.cmdbuff, true);
|
||||||
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
|
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
|
||||||
curwin->w_cursor.col = ccline.cmdpos;
|
curwin->w_cursor.col = ccline.cmdpos;
|
||||||
changed_line_abv_curs();
|
changed_line_abv_curs();
|
||||||
|
@@ -1081,7 +1081,7 @@ int fkmap(int c)
|
|||||||
|
|
||||||
if (gchar_cursor() == _LAM) {
|
if (gchar_cursor() == _LAM) {
|
||||||
chg_l_toXor_X();
|
chg_l_toXor_X();
|
||||||
del_char(FALSE);
|
del_char(false);
|
||||||
AppendCharToRedobuff(K_BS);
|
AppendCharToRedobuff(K_BS);
|
||||||
|
|
||||||
if (!p_ri) {
|
if (!p_ri) {
|
||||||
|
@@ -1687,7 +1687,7 @@ static void foldDelMarker(linenr_T lnum, char_u *marker, size_t markerlen)
|
|||||||
assert(p >= line);
|
assert(p >= line);
|
||||||
memcpy(newline, line, (size_t)(p - line));
|
memcpy(newline, line, (size_t)(p - line));
|
||||||
STRCPY(newline + (p - line), p + len);
|
STRCPY(newline + (p - line), p + len);
|
||||||
ml_replace(lnum, newline, FALSE);
|
ml_replace(lnum, newline, false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -2378,7 +2378,7 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, int message)
|
|||||||
)
|
)
|
||||||
set_keep_msg((char_u *)_(no_lines_msg), 0);
|
set_keep_msg((char_u *)_(no_lines_msg), 0);
|
||||||
|
|
||||||
i = ml_replace((linenr_T)1, (char_u *)"", TRUE);
|
i = ml_replace((linenr_T)1, (char_u *)"", true);
|
||||||
buf->b_ml.ml_flags |= ML_EMPTY;
|
buf->b_ml.ml_flags |= ML_EMPTY;
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
|
@@ -771,7 +771,7 @@ open_line (
|
|||||||
(void)u_save_cursor(); /* errors are ignored! */
|
(void)u_save_cursor(); /* errors are ignored! */
|
||||||
vr_lines_changed++;
|
vr_lines_changed++;
|
||||||
}
|
}
|
||||||
ml_replace(curwin->w_cursor.lnum, p_extra, TRUE);
|
ml_replace(curwin->w_cursor.lnum, p_extra, true);
|
||||||
changed_bytes(curwin->w_cursor.lnum, 0);
|
changed_bytes(curwin->w_cursor.lnum, 0);
|
||||||
curwin->w_cursor.lnum--;
|
curwin->w_cursor.lnum--;
|
||||||
did_append = FALSE;
|
did_append = FALSE;
|
||||||
@@ -831,12 +831,13 @@ open_line (
|
|||||||
|
|
||||||
if (dir == FORWARD) {
|
if (dir == FORWARD) {
|
||||||
if (trunc_line || (State & INSERT)) {
|
if (trunc_line || (State & INSERT)) {
|
||||||
/* truncate current line at cursor */
|
// truncate current line at cursor
|
||||||
saved_line[curwin->w_cursor.col] = NUL;
|
saved_line[curwin->w_cursor.col] = NUL;
|
||||||
/* Remove trailing white space, unless OPENLINE_KEEPTRAIL used. */
|
// Remove trailing white space, unless OPENLINE_KEEPTRAIL used.
|
||||||
if (trunc_line && !(flags & OPENLINE_KEEPTRAIL))
|
if (trunc_line && !(flags & OPENLINE_KEEPTRAIL)) {
|
||||||
truncate_spaces(saved_line);
|
truncate_spaces(saved_line);
|
||||||
ml_replace(curwin->w_cursor.lnum, saved_line, FALSE);
|
}
|
||||||
|
ml_replace(curwin->w_cursor.lnum, saved_line, false);
|
||||||
saved_line = NULL;
|
saved_line = NULL;
|
||||||
if (did_append) {
|
if (did_append) {
|
||||||
changed_lines(curwin->w_cursor.lnum, curwin->w_cursor.col,
|
changed_lines(curwin->w_cursor.lnum, curwin->w_cursor.col,
|
||||||
@@ -912,8 +913,8 @@ open_line (
|
|||||||
/* Put new line in p_extra */
|
/* Put new line in p_extra */
|
||||||
p_extra = vim_strsave(get_cursor_line_ptr());
|
p_extra = vim_strsave(get_cursor_line_ptr());
|
||||||
|
|
||||||
/* Put back original line */
|
// Put back original line
|
||||||
ml_replace(curwin->w_cursor.lnum, next_line, FALSE);
|
ml_replace(curwin->w_cursor.lnum, next_line, false);
|
||||||
|
|
||||||
/* Insert new stuff into line again */
|
/* Insert new stuff into line again */
|
||||||
curwin->w_cursor.col = 0;
|
curwin->w_cursor.col = 0;
|
||||||
@@ -1497,8 +1498,8 @@ void ins_char_bytes(char_u *buf, size_t charlen)
|
|||||||
p[i] = ' ';
|
p[i] = ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Replace the line in the buffer. */
|
// Replace the line in the buffer.
|
||||||
ml_replace(lnum, newp, FALSE);
|
ml_replace(lnum, newp, false);
|
||||||
|
|
||||||
// mark the buffer as changed and prepare for displaying
|
// mark the buffer as changed and prepare for displaying
|
||||||
changed_bytes(lnum, (colnr_T)col);
|
changed_bytes(lnum, (colnr_T)col);
|
||||||
@@ -1548,19 +1549,17 @@ void ins_str(char_u *s)
|
|||||||
memmove(newp, oldp, (size_t)col);
|
memmove(newp, oldp, (size_t)col);
|
||||||
memmove(newp + col, s, (size_t)newlen);
|
memmove(newp + col, s, (size_t)newlen);
|
||||||
memmove(newp + col + newlen, oldp + col, (size_t)(oldlen - col + 1));
|
memmove(newp + col + newlen, oldp + col, (size_t)(oldlen - col + 1));
|
||||||
ml_replace(lnum, newp, FALSE);
|
ml_replace(lnum, newp, false);
|
||||||
changed_bytes(lnum, col);
|
changed_bytes(lnum, col);
|
||||||
curwin->w_cursor.col += newlen;
|
curwin->w_cursor.col += newlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Delete one character under the cursor.
|
||||||
* Delete one character under the cursor.
|
// If "fixpos" is true, don't leave the cursor on the NUL after the line.
|
||||||
* If "fixpos" is TRUE, don't leave the cursor on the NUL after the line.
|
// Caller must have prepared for undo.
|
||||||
* Caller must have prepared for undo.
|
//
|
||||||
*
|
// return FAIL for failure, OK otherwise
|
||||||
* return FAIL for failure, OK otherwise
|
int del_char(bool fixpos)
|
||||||
*/
|
|
||||||
int del_char(int fixpos)
|
|
||||||
{
|
{
|
||||||
if (has_mbyte) {
|
if (has_mbyte) {
|
||||||
/* Make sure the cursor is at the start of a character. */
|
/* Make sure the cursor is at the start of a character. */
|
||||||
@@ -1666,8 +1665,9 @@ int del_bytes(colnr_T count, bool fixpos_arg, bool use_delcombine)
|
|||||||
memmove(newp, oldp, (size_t)col);
|
memmove(newp, oldp, (size_t)col);
|
||||||
}
|
}
|
||||||
memmove(newp + col, oldp + col + count, (size_t)movelen);
|
memmove(newp + col, oldp + col + count, (size_t)movelen);
|
||||||
if (!was_alloced)
|
if (!was_alloced) {
|
||||||
ml_replace(lnum, newp, FALSE);
|
ml_replace(lnum, newp, false);
|
||||||
|
}
|
||||||
|
|
||||||
/* mark the buffer as changed and prepare for displaying */
|
/* mark the buffer as changed and prepare for displaying */
|
||||||
changed_bytes(lnum, curwin->w_cursor.col);
|
changed_bytes(lnum, curwin->w_cursor.col);
|
||||||
|
117
src/nvim/ops.c
117
src/nvim/ops.c
@@ -310,30 +310,32 @@ void shift_line(
|
|||||||
*/
|
*/
|
||||||
static void shift_block(oparg_T *oap, int amount)
|
static void shift_block(oparg_T *oap, int amount)
|
||||||
{
|
{
|
||||||
int left = (oap->op_type == OP_LSHIFT);
|
const bool left = (oap->op_type == OP_LSHIFT);
|
||||||
int oldstate = State;
|
const int oldstate = State;
|
||||||
int total;
|
char_u *newp;
|
||||||
char_u *newp, *oldp;
|
const int oldcol = curwin->w_cursor.col;
|
||||||
int oldcol = curwin->w_cursor.col;
|
const int p_sw = get_sw_value(curbuf);
|
||||||
int p_sw = get_sw_value(curbuf);
|
const int p_ts = (int)curbuf->b_p_ts;
|
||||||
int p_ts = (int)curbuf->b_p_ts;
|
|
||||||
struct block_def bd;
|
struct block_def bd;
|
||||||
int incr;
|
int incr;
|
||||||
colnr_T ws_vcol;
|
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
int len;
|
const int old_p_ri = p_ri;
|
||||||
int old_p_ri = p_ri;
|
|
||||||
|
|
||||||
p_ri = 0; /* don't want revins in indent */
|
p_ri = 0; /* don't want revins in indent */
|
||||||
|
|
||||||
State = INSERT; /* don't want REPLACE for State */
|
State = INSERT; // don't want REPLACE for State
|
||||||
block_prep(oap, &bd, curwin->w_cursor.lnum, TRUE);
|
block_prep(oap, &bd, curwin->w_cursor.lnum, true);
|
||||||
if (bd.is_short)
|
if (bd.is_short) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* total is number of screen columns to be inserted/removed */
|
// total is number of screen columns to be inserted/removed
|
||||||
total = amount * p_sw;
|
int total = (int)((unsigned)amount * (unsigned)p_sw);
|
||||||
oldp = get_cursor_line_ptr();
|
if ((total / p_sw) != amount) {
|
||||||
|
return; // multiplication overflow
|
||||||
|
}
|
||||||
|
|
||||||
|
char_u *const oldp = get_cursor_line_ptr();
|
||||||
|
|
||||||
if (!left) {
|
if (!left) {
|
||||||
/*
|
/*
|
||||||
@@ -342,8 +344,8 @@ static void shift_block(oparg_T *oap, int amount)
|
|||||||
* 3. Divvy into TABs & spp
|
* 3. Divvy into TABs & spp
|
||||||
* 4. Construct new string
|
* 4. Construct new string
|
||||||
*/
|
*/
|
||||||
total += bd.pre_whitesp; /* all virtual WS up to & incl a split TAB */
|
total += bd.pre_whitesp; // all virtual WS up to & incl a split TAB
|
||||||
ws_vcol = bd.start_vcol - bd.pre_whitesp;
|
colnr_T ws_vcol = bd.start_vcol - bd.pre_whitesp;
|
||||||
if (bd.startspaces) {
|
if (bd.startspaces) {
|
||||||
if (has_mbyte) {
|
if (has_mbyte) {
|
||||||
if ((*mb_ptr2len)(bd.textstart) == 1) {
|
if ((*mb_ptr2len)(bd.textstart) == 1) {
|
||||||
@@ -372,8 +374,8 @@ static void shift_block(oparg_T *oap, int amount)
|
|||||||
j = total;
|
j = total;
|
||||||
/* if we're splitting a TAB, allow for it */
|
/* if we're splitting a TAB, allow for it */
|
||||||
bd.textcol -= bd.pre_whitesp_c - (bd.startspaces != 0);
|
bd.textcol -= bd.pre_whitesp_c - (bd.startspaces != 0);
|
||||||
len = (int)STRLEN(bd.textstart) + 1;
|
const int len = (int)STRLEN(bd.textstart) + 1;
|
||||||
newp = (char_u *) xmalloc((size_t)(bd.textcol + i + j + len));
|
newp = (char_u *)xmalloc((size_t)(bd.textcol + i + j + len));
|
||||||
memset(newp, NUL, (size_t)(bd.textcol + i + j + len));
|
memset(newp, NUL, (size_t)(bd.textcol + i + j + len));
|
||||||
memmove(newp, oldp, (size_t)bd.textcol);
|
memmove(newp, oldp, (size_t)bd.textcol);
|
||||||
memset(newp + bd.textcol, TAB, (size_t)i);
|
memset(newp + bd.textcol, TAB, (size_t)i);
|
||||||
@@ -390,10 +392,7 @@ static void shift_block(oparg_T *oap, int amount)
|
|||||||
size_t fill; // nr of spaces that replace a TAB
|
size_t fill; // nr of spaces that replace a TAB
|
||||||
size_t new_line_len; // the length of the line after the
|
size_t new_line_len; // the length of the line after the
|
||||||
// block shift
|
// block shift
|
||||||
colnr_T block_space_width;
|
|
||||||
colnr_T shift_amount;
|
|
||||||
char_u *non_white = bd.textstart;
|
char_u *non_white = bd.textstart;
|
||||||
colnr_T non_white_col;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Firstly, let's find the first non-whitespace character that is
|
* Firstly, let's find the first non-whitespace character that is
|
||||||
@@ -410,19 +409,20 @@ static void shift_block(oparg_T *oap, int amount)
|
|||||||
MB_PTR_ADV(non_white);
|
MB_PTR_ADV(non_white);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The character's column is in "bd.start_vcol". */
|
// The character's column is in "bd.start_vcol".
|
||||||
non_white_col = bd.start_vcol;
|
colnr_T non_white_col = bd.start_vcol;
|
||||||
|
|
||||||
while (ascii_iswhite(*non_white)) {
|
while (ascii_iswhite(*non_white)) {
|
||||||
incr = lbr_chartabsize_adv(bd.textstart, &non_white, non_white_col);
|
incr = lbr_chartabsize_adv(bd.textstart, &non_white, non_white_col);
|
||||||
non_white_col += incr;
|
non_white_col += incr;
|
||||||
}
|
}
|
||||||
|
|
||||||
block_space_width = non_white_col - oap->start_vcol;
|
|
||||||
/* We will shift by "total" or "block_space_width", whichever is less.
|
|
||||||
*/
|
|
||||||
shift_amount = (block_space_width < total ? block_space_width : total);
|
|
||||||
|
|
||||||
|
const colnr_T block_space_width = non_white_col - oap->start_vcol;
|
||||||
|
// We will shift by "total" or "block_space_width", whichever is less.
|
||||||
|
const colnr_T shift_amount = block_space_width < total
|
||||||
|
? block_space_width
|
||||||
|
: total;
|
||||||
// The column to which we will shift the text.
|
// The column to which we will shift the text.
|
||||||
destination_col = non_white_col - shift_amount;
|
destination_col = non_white_col - shift_amount;
|
||||||
|
|
||||||
@@ -454,7 +454,7 @@ static void shift_block(oparg_T *oap, int amount)
|
|||||||
fill = (size_t)(destination_col - verbatim_copy_width);
|
fill = (size_t)(destination_col - verbatim_copy_width);
|
||||||
|
|
||||||
assert(verbatim_copy_end - oldp >= 0);
|
assert(verbatim_copy_end - oldp >= 0);
|
||||||
size_t verbatim_diff = (size_t)(verbatim_copy_end - oldp);
|
const size_t verbatim_diff = (size_t)(verbatim_copy_end - oldp);
|
||||||
// The replacement line will consist of:
|
// The replacement line will consist of:
|
||||||
// - the beginning of the original line up to "verbatim_copy_end",
|
// - the beginning of the original line up to "verbatim_copy_end",
|
||||||
// - "fill" number of spaces,
|
// - "fill" number of spaces,
|
||||||
@@ -466,8 +466,8 @@ static void shift_block(oparg_T *oap, int amount)
|
|||||||
memset(newp + verbatim_diff, ' ', fill);
|
memset(newp + verbatim_diff, ' ', fill);
|
||||||
STRMOVE(newp + verbatim_diff + fill, non_white);
|
STRMOVE(newp + verbatim_diff + fill, non_white);
|
||||||
}
|
}
|
||||||
/* replace the line */
|
// replace the line
|
||||||
ml_replace(curwin->w_cursor.lnum, newp, FALSE);
|
ml_replace(curwin->w_cursor.lnum, newp, false);
|
||||||
changed_bytes(curwin->w_cursor.lnum, (colnr_T)bd.textcol);
|
changed_bytes(curwin->w_cursor.lnum, (colnr_T)bd.textcol);
|
||||||
State = oldstate;
|
State = oldstate;
|
||||||
curwin->w_cursor.col = oldcol;
|
curwin->w_cursor.col = oldcol;
|
||||||
@@ -561,7 +561,7 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def
|
|||||||
offset += count;
|
offset += count;
|
||||||
STRMOVE(newp + offset, oldp);
|
STRMOVE(newp + offset, oldp);
|
||||||
|
|
||||||
ml_replace(lnum, newp, FALSE);
|
ml_replace(lnum, newp, false);
|
||||||
|
|
||||||
if (lnum == oap->end.lnum) {
|
if (lnum == oap->end.lnum) {
|
||||||
/* Set "']" mark to the end of the block instead of the end of
|
/* Set "']" mark to the end of the block instead of the end of
|
||||||
@@ -1427,10 +1427,11 @@ int op_delete(oparg_T *oap)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (lnum = curwin->w_cursor.lnum; lnum <= oap->end.lnum; ++lnum) {
|
for (lnum = curwin->w_cursor.lnum; lnum <= oap->end.lnum; lnum++) {
|
||||||
block_prep(oap, &bd, lnum, TRUE);
|
block_prep(oap, &bd, lnum, true);
|
||||||
if (bd.textlen == 0) /* nothing to delete */
|
if (bd.textlen == 0) { // nothing to delete
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* Adjust cursor position for tab replaced by spaces and 'lbr'. */
|
/* Adjust cursor position for tab replaced by spaces and 'lbr'. */
|
||||||
if (lnum == curwin->w_cursor.lnum) {
|
if (lnum == curwin->w_cursor.lnum) {
|
||||||
@@ -1656,11 +1657,12 @@ int op_replace(oparg_T *oap, int c)
|
|||||||
*/
|
*/
|
||||||
if (oap->motion_type == kMTBlockWise) {
|
if (oap->motion_type == kMTBlockWise) {
|
||||||
bd.is_MAX = (curwin->w_curswant == MAXCOL);
|
bd.is_MAX = (curwin->w_curswant == MAXCOL);
|
||||||
for (; curwin->w_cursor.lnum <= oap->end.lnum; ++curwin->w_cursor.lnum) {
|
for (; curwin->w_cursor.lnum <= oap->end.lnum; curwin->w_cursor.lnum++) {
|
||||||
curwin->w_cursor.col = 0; /* make sure cursor position is valid */
|
curwin->w_cursor.col = 0; // make sure cursor position is valid
|
||||||
block_prep(oap, &bd, curwin->w_cursor.lnum, TRUE);
|
block_prep(oap, &bd, curwin->w_cursor.lnum, true);
|
||||||
if (bd.textlen == 0 && (!virtual_op || bd.is_MAX))
|
if (bd.textlen == 0 && (!virtual_op || bd.is_MAX)) {
|
||||||
continue; /* nothing to replace */
|
continue; // nothing to replace
|
||||||
|
}
|
||||||
|
|
||||||
/* n == number of extra chars required
|
/* n == number of extra chars required
|
||||||
* If we split a TAB, it may be replaced by several characters.
|
* If we split a TAB, it may be replaced by several characters.
|
||||||
@@ -1747,8 +1749,8 @@ int op_replace(oparg_T *oap, int c)
|
|||||||
after_p = (char_u *)xmalloc(after_p_len);
|
after_p = (char_u *)xmalloc(after_p_len);
|
||||||
memmove(after_p, oldp, after_p_len);
|
memmove(after_p, oldp, after_p_len);
|
||||||
}
|
}
|
||||||
/* replace the line */
|
// replace the line
|
||||||
ml_replace(curwin->w_cursor.lnum, newp, FALSE);
|
ml_replace(curwin->w_cursor.lnum, newp, false);
|
||||||
if (after_p != NULL) {
|
if (after_p != NULL) {
|
||||||
ml_append(curwin->w_cursor.lnum++, after_p, (int)after_p_len, false);
|
ml_append(curwin->w_cursor.lnum++, after_p, (int)after_p_len, false);
|
||||||
appended_lines_mark(curwin->w_cursor.lnum, 1L);
|
appended_lines_mark(curwin->w_cursor.lnum, 1L);
|
||||||
@@ -1852,7 +1854,7 @@ void op_tilde(oparg_T *oap)
|
|||||||
for (; pos.lnum <= oap->end.lnum; pos.lnum++) {
|
for (; pos.lnum <= oap->end.lnum; pos.lnum++) {
|
||||||
int one_change;
|
int one_change;
|
||||||
|
|
||||||
block_prep(oap, &bd, pos.lnum, FALSE);
|
block_prep(oap, &bd, pos.lnum, false);
|
||||||
pos.col = bd.textcol;
|
pos.col = bd.textcol;
|
||||||
one_change = swapchars(oap->op_type, &pos, bd.textlen);
|
one_change = swapchars(oap->op_type, &pos, bd.textlen);
|
||||||
did_change |= one_change;
|
did_change |= one_change;
|
||||||
@@ -1956,7 +1958,7 @@ int swapchar(int op_type, pos_T *pos)
|
|||||||
|
|
||||||
/* Special handling of German sharp s: change to "SS". */
|
/* Special handling of German sharp s: change to "SS". */
|
||||||
curwin->w_cursor = *pos;
|
curwin->w_cursor = *pos;
|
||||||
del_char(FALSE);
|
del_char(false);
|
||||||
ins_char('S');
|
ins_char('S');
|
||||||
ins_char('S');
|
ins_char('S');
|
||||||
curwin->w_cursor = sp;
|
curwin->w_cursor = sp;
|
||||||
@@ -2030,8 +2032,8 @@ void op_insert(oparg_T *oap, long count1)
|
|||||||
--curwin->w_cursor.col;
|
--curwin->w_cursor.col;
|
||||||
ve_flags = old_ve_flags;
|
ve_flags = old_ve_flags;
|
||||||
}
|
}
|
||||||
/* Get the info about the block before entering the text */
|
// Get the info about the block before entering the text
|
||||||
block_prep(oap, &bd, oap->start.lnum, TRUE);
|
block_prep(oap, &bd, oap->start.lnum, true);
|
||||||
firstline = ml_get(oap->start.lnum) + bd.textcol;
|
firstline = ml_get(oap->start.lnum) + bd.textcol;
|
||||||
if (oap->op_type == OP_APPEND)
|
if (oap->op_type == OP_APPEND)
|
||||||
firstline += bd.textlen;
|
firstline += bd.textlen;
|
||||||
@@ -2119,7 +2121,7 @@ void op_insert(oparg_T *oap, long count1)
|
|||||||
* tabs. Get the starting column again and correct the length.
|
* tabs. Get the starting column again and correct the length.
|
||||||
* Don't do this when "$" used, end-of-line will have changed.
|
* Don't do this when "$" used, end-of-line will have changed.
|
||||||
*/
|
*/
|
||||||
block_prep(oap, &bd2, oap->start.lnum, TRUE);
|
block_prep(oap, &bd2, oap->start.lnum, true);
|
||||||
if (!bd.is_MAX || bd2.textlen < bd.textlen) {
|
if (!bd.is_MAX || bd2.textlen < bd.textlen) {
|
||||||
if (oap->op_type == OP_APPEND) {
|
if (oap->op_type == OP_APPEND) {
|
||||||
pre_textlen += bd2.textlen - bd.textlen;
|
pre_textlen += bd2.textlen - bd.textlen;
|
||||||
@@ -2239,7 +2241,7 @@ int op_change(oparg_T *oap)
|
|||||||
STRLCPY(ins_text, firstline + bd.textcol, ins_len + 1);
|
STRLCPY(ins_text, firstline + bd.textcol, ins_len + 1);
|
||||||
for (linenr = oap->start.lnum + 1; linenr <= oap->end.lnum;
|
for (linenr = oap->start.lnum + 1; linenr <= oap->end.lnum;
|
||||||
linenr++) {
|
linenr++) {
|
||||||
block_prep(oap, &bd, linenr, TRUE);
|
block_prep(oap, &bd, linenr, true);
|
||||||
if (!bd.is_short || virtual_op) {
|
if (!bd.is_short || virtual_op) {
|
||||||
pos_T vpos;
|
pos_T vpos;
|
||||||
|
|
||||||
@@ -2263,7 +2265,7 @@ int op_change(oparg_T *oap)
|
|||||||
offset += ins_len;
|
offset += ins_len;
|
||||||
oldp += bd.textcol;
|
oldp += bd.textcol;
|
||||||
STRMOVE(newp + offset, oldp);
|
STRMOVE(newp + offset, oldp);
|
||||||
ml_replace(linenr, newp, FALSE);
|
ml_replace(linenr, newp, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
check_cursor();
|
check_cursor();
|
||||||
@@ -3117,10 +3119,10 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
|
|||||||
ptr += yanklen;
|
ptr += yanklen;
|
||||||
}
|
}
|
||||||
STRMOVE(ptr, oldp + col);
|
STRMOVE(ptr, oldp + col);
|
||||||
ml_replace(lnum, newp, FALSE);
|
ml_replace(lnum, newp, false);
|
||||||
/* Place cursor on last putted char. */
|
// Place cursor on last putted char.
|
||||||
if (lnum == curwin->w_cursor.lnum) {
|
if (lnum == curwin->w_cursor.lnum) {
|
||||||
/* make sure curwin->w_virtcol is updated */
|
// make sure curwin->w_virtcol is updated
|
||||||
changed_cline_bef_curs();
|
changed_cline_bef_curs();
|
||||||
curwin->w_cursor.col += (colnr_T)(totlen - 1);
|
curwin->w_cursor.col += (colnr_T)(totlen - 1);
|
||||||
}
|
}
|
||||||
@@ -3164,7 +3166,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
|
|||||||
memmove(newp, oldp, (size_t)col);
|
memmove(newp, oldp, (size_t)col);
|
||||||
/* append to first line */
|
/* append to first line */
|
||||||
memmove(newp + col, y_array[0], (size_t)(yanklen + 1));
|
memmove(newp + col, y_array[0], (size_t)(yanklen + 1));
|
||||||
ml_replace(lnum, newp, FALSE);
|
ml_replace(lnum, newp, false);
|
||||||
|
|
||||||
curwin->w_cursor.lnum = lnum;
|
curwin->w_cursor.lnum = lnum;
|
||||||
i = 1;
|
i = 1;
|
||||||
@@ -3687,7 +3689,7 @@ int do_join(size_t count,
|
|||||||
curr = skipwhite(curr);
|
curr = skipwhite(curr);
|
||||||
currsize = (int)STRLEN(curr);
|
currsize = (int)STRLEN(curr);
|
||||||
}
|
}
|
||||||
ml_replace(curwin->w_cursor.lnum, newp, FALSE);
|
ml_replace(curwin->w_cursor.lnum, newp, false);
|
||||||
|
|
||||||
if (setmark) {
|
if (setmark) {
|
||||||
// Set the '] mark.
|
// Set the '] mark.
|
||||||
@@ -4239,7 +4241,8 @@ int paragraph_start(linenr_T lnum)
|
|||||||
* - start/endspaces is the number of columns of the first/last yanked char
|
* - start/endspaces is the number of columns of the first/last yanked char
|
||||||
* that are to be yanked.
|
* that are to be yanked.
|
||||||
*/
|
*/
|
||||||
static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, int is_del)
|
static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum,
|
||||||
|
bool is_del)
|
||||||
{
|
{
|
||||||
int incr = 0;
|
int incr = 0;
|
||||||
char_u *pend;
|
char_u *pend;
|
||||||
@@ -5376,7 +5379,7 @@ void cursor_pos_info(dict_T *dict)
|
|||||||
switch (l_VIsual_mode) {
|
switch (l_VIsual_mode) {
|
||||||
case Ctrl_V:
|
case Ctrl_V:
|
||||||
virtual_op = virtual_active();
|
virtual_op = virtual_active();
|
||||||
block_prep(&oparg, &bd, lnum, 0);
|
block_prep(&oparg, &bd, lnum, false);
|
||||||
virtual_op = kNone;
|
virtual_op = kNone;
|
||||||
s = bd.textstart;
|
s = bd.textstart;
|
||||||
len = (long)bd.textlen;
|
len = (long)bd.textlen;
|
||||||
|
@@ -2197,7 +2197,7 @@ win_line (
|
|||||||
match_T *shl; // points to search_hl or a match
|
match_T *shl; // points to search_hl or a match
|
||||||
int shl_flag; // flag to indicate whether search_hl
|
int shl_flag; // flag to indicate whether search_hl
|
||||||
// has been processed or not
|
// has been processed or not
|
||||||
int prevcol_hl_flag; // flag to indicate whether prevcol
|
bool prevcol_hl_flag; // flag to indicate whether prevcol
|
||||||
// equals startcol of search_hl or one
|
// equals startcol of search_hl or one
|
||||||
// of the matches
|
// of the matches
|
||||||
int prev_c = 0; // previous Arabic character
|
int prev_c = 0; // previous Arabic character
|
||||||
@@ -3026,6 +3026,12 @@ win_line (
|
|||||||
if (shl != &search_hl && cur != NULL)
|
if (shl != &search_hl && cur != NULL)
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
|
// Only highlight one character after the last column.
|
||||||
|
if (*ptr == NUL
|
||||||
|
&& (did_line_attr >= 1
|
||||||
|
|| (wp->w_p_list && lcs_eol_one == -1))) {
|
||||||
|
search_attr = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (diff_hlf != (hlf_T)0) {
|
if (diff_hlf != (hlf_T)0) {
|
||||||
@@ -3674,7 +3680,9 @@ win_line (
|
|||||||
|
|
||||||
// don't do search HL for the rest of the line
|
// don't do search HL for the rest of the line
|
||||||
if ((line_attr_lowprio || line_attr)
|
if ((line_attr_lowprio || line_attr)
|
||||||
&& char_attr == search_attr && col > 0) {
|
&& char_attr == search_attr
|
||||||
|
&& (did_line_attr > 1
|
||||||
|
|| (wp->w_p_list && lcs_eol > 0))) {
|
||||||
char_attr = line_attr;
|
char_attr = line_attr;
|
||||||
}
|
}
|
||||||
if (diff_hlf == HLF_TXD) {
|
if (diff_hlf == HLF_TXD) {
|
||||||
@@ -3833,9 +3841,12 @@ win_line (
|
|||||||
|| lnum == VIsual.lnum
|
|| lnum == VIsual.lnum
|
||||||
|| lnum == curwin->w_cursor.lnum)
|
|| lnum == curwin->w_cursor.lnum)
|
||||||
&& c == NUL)
|
&& c == NUL)
|
||||||
/* highlight 'hlsearch' match at end of line */
|
// highlight 'hlsearch' match at end of line
|
||||||
|| (prevcol_hl_flag == TRUE && did_line_attr <= 1)
|
|| (prevcol_hl_flag
|
||||||
)) {
|
&& !(wp->w_p_cul && lnum == wp->w_cursor.lnum
|
||||||
|
&& !(wp == curwin && VIsual_active))
|
||||||
|
&& diff_hlf == (hlf_T)0
|
||||||
|
&& did_line_attr <= 1))) {
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
if (wp->w_p_rl) {
|
if (wp->w_p_rl) {
|
||||||
@@ -5805,7 +5816,8 @@ void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1,
|
|||||||
// TODO(bfredl): The relevant caller should do this
|
// TODO(bfredl): The relevant caller should do this
|
||||||
if (row == Rows - 1) { // overwritten the command line
|
if (row == Rows - 1) { // overwritten the command line
|
||||||
redraw_cmdline = true;
|
redraw_cmdline = true;
|
||||||
if (c1 == ' ' && c2 == ' ') {
|
if (start_col == 0 && end_col == Columns
|
||||||
|
&& c1 == ' ' && c2 == ' ' && attr == 0) {
|
||||||
clear_cmdline = false; // command line has been cleared
|
clear_cmdline = false; // command line has been cleared
|
||||||
}
|
}
|
||||||
if (start_col == 0) {
|
if (start_col == 0) {
|
||||||
|
@@ -2941,7 +2941,7 @@ void spell_suggest(int count)
|
|||||||
memmove(p, line, c);
|
memmove(p, line, c);
|
||||||
STRCPY(p + c, stp->st_word);
|
STRCPY(p + c, stp->st_word);
|
||||||
STRCAT(p, sug.su_badptr + stp->st_orglen);
|
STRCAT(p, sug.su_badptr + stp->st_orglen);
|
||||||
ml_replace(curwin->w_cursor.lnum, p, FALSE);
|
ml_replace(curwin->w_cursor.lnum, p, false);
|
||||||
curwin->w_cursor.col = c;
|
curwin->w_cursor.col = c;
|
||||||
|
|
||||||
// For redo we use a change-word command.
|
// For redo we use a change-word command.
|
||||||
@@ -3059,7 +3059,7 @@ void ex_spellrepall(exarg_T *eap)
|
|||||||
memmove(p, line, curwin->w_cursor.col);
|
memmove(p, line, curwin->w_cursor.col);
|
||||||
STRCPY(p + curwin->w_cursor.col, repl_to);
|
STRCPY(p + curwin->w_cursor.col, repl_to);
|
||||||
STRCAT(p, line + curwin->w_cursor.col + STRLEN(repl_from));
|
STRCAT(p, line + curwin->w_cursor.col + STRLEN(repl_from));
|
||||||
ml_replace(curwin->w_cursor.lnum, p, FALSE);
|
ml_replace(curwin->w_cursor.lnum, p, false);
|
||||||
changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
|
changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
|
||||||
|
|
||||||
if (curwin->w_cursor.lnum != prev_lnum) {
|
if (curwin->w_cursor.lnum != prev_lnum) {
|
||||||
|
@@ -60,12 +60,14 @@ NEW_TESTS ?= \
|
|||||||
test_fnameescape.res \
|
test_fnameescape.res \
|
||||||
test_fold.res \
|
test_fold.res \
|
||||||
test_ga.res \
|
test_ga.res \
|
||||||
|
test_getvar.res \
|
||||||
test_glob2regpat.res \
|
test_glob2regpat.res \
|
||||||
test_gf.res \
|
test_gf.res \
|
||||||
test_gn.res \
|
test_gn.res \
|
||||||
test_hardcopy.res \
|
test_hardcopy.res \
|
||||||
test_help_tagjump.res \
|
test_help_tagjump.res \
|
||||||
test_hide.res \
|
test_hide.res \
|
||||||
|
test_highlight.res \
|
||||||
test_history.res \
|
test_history.res \
|
||||||
test_hlsearch.res \
|
test_hlsearch.res \
|
||||||
test_increment.res \
|
test_increment.res \
|
||||||
|
104
src/nvim/testdir/test_getvar.vim
Normal file
104
src/nvim/testdir/test_getvar.vim
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
" Tests for getwinvar(), gettabvar() and gettabwinvar().
|
||||||
|
func Test_var()
|
||||||
|
" Use strings to test for memory leaks. First, check that in an empty
|
||||||
|
" window, gettabvar() returns the correct value
|
||||||
|
let t:testvar='abcd'
|
||||||
|
call assert_equal('abcd', gettabvar(1, 'testvar'))
|
||||||
|
call assert_equal('abcd', gettabvar(1, 'testvar'))
|
||||||
|
|
||||||
|
" test for getwinvar()
|
||||||
|
let w:var_str = "Dance"
|
||||||
|
let def_str = "Chance"
|
||||||
|
call assert_equal('Dance', getwinvar(1, 'var_str'))
|
||||||
|
call assert_equal('Dance', getwinvar(1, 'var_str', def_str))
|
||||||
|
call assert_equal({'var_str': 'Dance'}, getwinvar(1, ''))
|
||||||
|
call assert_equal({'var_str': 'Dance'}, getwinvar(1, '', def_str))
|
||||||
|
unlet w:var_str
|
||||||
|
call assert_equal('Chance', getwinvar(1, 'var_str', def_str))
|
||||||
|
call assert_equal({}, getwinvar(1, ''))
|
||||||
|
call assert_equal({}, getwinvar(1, '', def_str))
|
||||||
|
call assert_equal('', getwinvar(9, ''))
|
||||||
|
call assert_equal('Chance', getwinvar(9, '', def_str))
|
||||||
|
call assert_equal(0, getwinvar(1, '&nu'))
|
||||||
|
call assert_equal(0, getwinvar(1, '&nu', 1))
|
||||||
|
unlet def_str
|
||||||
|
|
||||||
|
" test for gettabvar()
|
||||||
|
tabnew
|
||||||
|
tabnew
|
||||||
|
let t:var_list = [1, 2, 3]
|
||||||
|
let t:other = 777
|
||||||
|
let def_list = [4, 5, 6, 7]
|
||||||
|
tabrewind
|
||||||
|
call assert_equal([1, 2, 3], gettabvar(3, 'var_list'))
|
||||||
|
call assert_equal([1, 2, 3], gettabvar(3, 'var_list', def_list))
|
||||||
|
call assert_equal({'var_list': [1, 2, 3], 'other': 777}, gettabvar(3, ''))
|
||||||
|
call assert_equal({'var_list': [1, 2, 3], 'other': 777},
|
||||||
|
\ gettabvar(3, '', def_list))
|
||||||
|
|
||||||
|
tablast
|
||||||
|
unlet t:var_list
|
||||||
|
tabrewind
|
||||||
|
call assert_equal([4, 5, 6, 7], gettabvar(3, 'var_list', def_list))
|
||||||
|
call assert_equal('', gettabvar(9, ''))
|
||||||
|
call assert_equal([4, 5, 6, 7], gettabvar(9, '', def_list))
|
||||||
|
call assert_equal('', gettabvar(3, '&nu'))
|
||||||
|
call assert_equal([4, 5, 6, 7], gettabvar(3, '&nu', def_list))
|
||||||
|
unlet def_list
|
||||||
|
tabonly
|
||||||
|
|
||||||
|
" test for gettabwinvar()
|
||||||
|
tabnew
|
||||||
|
tabnew
|
||||||
|
tabprev
|
||||||
|
split
|
||||||
|
split
|
||||||
|
wincmd w
|
||||||
|
vert split
|
||||||
|
wincmd w
|
||||||
|
let w:var_dict = {'dict': 'tabwin'}
|
||||||
|
let def_dict = {'dict2': 'newval'}
|
||||||
|
wincmd b
|
||||||
|
tabrewind
|
||||||
|
call assert_equal({'dict': 'tabwin'}, gettabwinvar(2, 3, 'var_dict'))
|
||||||
|
call assert_equal({'dict': 'tabwin'},
|
||||||
|
\ gettabwinvar(2, 3, 'var_dict', def_dict))
|
||||||
|
call assert_equal({'var_dict': {'dict': 'tabwin'}}, gettabwinvar(2, 3, ''))
|
||||||
|
call assert_equal({'var_dict': {'dict': 'tabwin'}},
|
||||||
|
\ gettabwinvar(2, 3, '', def_dict))
|
||||||
|
|
||||||
|
tabnext
|
||||||
|
3wincmd w
|
||||||
|
unlet w:var_dict
|
||||||
|
tabrewind
|
||||||
|
call assert_equal({'dict2': 'newval'},
|
||||||
|
\ gettabwinvar(2, 3, 'var_dict', def_dict))
|
||||||
|
call assert_equal({}, gettabwinvar(2, 3, ''))
|
||||||
|
call assert_equal({}, gettabwinvar(2, 3, '', def_dict))
|
||||||
|
call assert_equal("", gettabwinvar(2, 9, ''))
|
||||||
|
call assert_equal({'dict2': 'newval'}, gettabwinvar(2, 9, '', def_dict))
|
||||||
|
call assert_equal('', gettabwinvar(9, 3, ''))
|
||||||
|
call assert_equal({'dict2': 'newval'}, gettabwinvar(9, 3, '', def_dict))
|
||||||
|
|
||||||
|
unlet def_dict
|
||||||
|
|
||||||
|
call assert_equal('', gettabwinvar(2, 3, '&nux'))
|
||||||
|
call assert_equal(1, gettabwinvar(2, 3, '&nux', 1))
|
||||||
|
tabonly
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" It was discovered that "gettabvar()" would fail if called from within the
|
||||||
|
" tabline when the user closed a window. This test confirms the fix.
|
||||||
|
func Test_gettabvar_in_tabline()
|
||||||
|
let t:var_str = 'value'
|
||||||
|
|
||||||
|
set tabline=%{assert_equal('value',gettabvar(1,'var_str'))}
|
||||||
|
set showtabline=2
|
||||||
|
|
||||||
|
" Simulate the user opening a split (which becomes window #1) and then
|
||||||
|
" closing the split, which triggers the redrawing of the tabline.
|
||||||
|
leftabove split
|
||||||
|
redrawstatus!
|
||||||
|
close
|
||||||
|
redrawstatus!
|
||||||
|
endfunc
|
535
src/nvim/testdir/test_highlight.vim
Normal file
535
src/nvim/testdir/test_highlight.vim
Normal file
@@ -0,0 +1,535 @@
|
|||||||
|
" Tests for ":highlight" and highlighting.
|
||||||
|
|
||||||
|
source view_util.vim
|
||||||
|
|
||||||
|
func Test_highlight()
|
||||||
|
" basic test if ":highlight" doesn't crash
|
||||||
|
highlight
|
||||||
|
hi Search
|
||||||
|
|
||||||
|
" test setting colors.
|
||||||
|
" test clearing one color and all doesn't generate error or warning
|
||||||
|
silent! hi NewGroup term=bold cterm=italic ctermfg=DarkBlue ctermbg=Grey gui= guifg=#00ff00 guibg=Cyan
|
||||||
|
silent! hi Group2 term= cterm=
|
||||||
|
hi Group3 term=underline cterm=bold
|
||||||
|
|
||||||
|
let res = split(execute("hi NewGroup"), "\n")[0]
|
||||||
|
" filter ctermfg and ctermbg, the numbers depend on the terminal
|
||||||
|
let res = substitute(res, 'ctermfg=\d*', 'ctermfg=2', '')
|
||||||
|
let res = substitute(res, 'ctermbg=\d*', 'ctermbg=3', '')
|
||||||
|
call assert_equal("NewGroup xxx cterm=italic ctermfg=2 ctermbg=3",
|
||||||
|
\ res)
|
||||||
|
call assert_equal("Group2 xxx cleared",
|
||||||
|
\ split(execute("hi Group2"), "\n")[0])
|
||||||
|
call assert_equal("Group3 xxx cterm=bold",
|
||||||
|
\ split(execute("hi Group3"), "\n")[0])
|
||||||
|
|
||||||
|
hi clear NewGroup
|
||||||
|
call assert_equal("NewGroup xxx cleared",
|
||||||
|
\ split(execute("hi NewGroup"), "\n")[0])
|
||||||
|
call assert_equal("Group2 xxx cleared",
|
||||||
|
\ split(execute("hi Group2"), "\n")[0])
|
||||||
|
hi Group2 NONE
|
||||||
|
call assert_equal("Group2 xxx cleared",
|
||||||
|
\ split(execute("hi Group2"), "\n")[0])
|
||||||
|
hi clear
|
||||||
|
call assert_equal("Group3 xxx cleared",
|
||||||
|
\ split(execute("hi Group3"), "\n")[0])
|
||||||
|
call assert_fails("hi Crash term='asdf", "E475:")
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
function! HighlightArgs(name)
|
||||||
|
return 'hi ' . substitute(split(execute('hi ' . a:name), '\n')[0], '\<xxx\>', '', '')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! IsColorable()
|
||||||
|
return has('gui_running') || str2nr(&t_Co) >= 8
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! HiCursorLine()
|
||||||
|
let hiCursorLine = HighlightArgs('CursorLine')
|
||||||
|
if has('gui_running')
|
||||||
|
let guibg = matchstr(hiCursorLine, 'guibg=\w\+')
|
||||||
|
let hi_ul = 'hi CursorLine gui=underline guibg=NONE'
|
||||||
|
let hi_bg = 'hi CursorLine gui=NONE ' . guibg
|
||||||
|
else
|
||||||
|
let hi_ul = 'hi CursorLine cterm=underline ctermbg=NONE'
|
||||||
|
let hi_bg = 'hi CursorLine cterm=NONE ctermbg=Gray'
|
||||||
|
endif
|
||||||
|
return [hiCursorLine, hi_ul, hi_bg]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! Check_lcs_eol_attrs(attrs, row, col)
|
||||||
|
let save_lcs = &lcs
|
||||||
|
set list
|
||||||
|
|
||||||
|
call assert_equal(a:attrs, ScreenAttrs(a:row, a:col)[0])
|
||||||
|
|
||||||
|
set nolist
|
||||||
|
let &lcs = save_lcs
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
func Test_highlight_eol_with_cursorline()
|
||||||
|
let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
|
||||||
|
|
||||||
|
call NewWindow('topleft 5', 20)
|
||||||
|
call setline(1, 'abcd')
|
||||||
|
call matchadd('Search', '\n')
|
||||||
|
|
||||||
|
" expected:
|
||||||
|
" 'abcd '
|
||||||
|
" ^^^^ ^^^^^ no highlight
|
||||||
|
" ^ 'Search' highlight
|
||||||
|
let attrs0 = ScreenAttrs(1, 10)[0]
|
||||||
|
call assert_equal(repeat([attrs0[0]], 4), attrs0[0:3])
|
||||||
|
call assert_equal(repeat([attrs0[0]], 5), attrs0[5:9])
|
||||||
|
call assert_notequal(attrs0[0], attrs0[4])
|
||||||
|
|
||||||
|
setlocal cursorline
|
||||||
|
|
||||||
|
" underline
|
||||||
|
exe hi_ul
|
||||||
|
|
||||||
|
" expected:
|
||||||
|
" 'abcd '
|
||||||
|
" ^^^^ underline
|
||||||
|
" ^ 'Search' highlight with underline
|
||||||
|
" ^^^^^ underline
|
||||||
|
let attrs = ScreenAttrs(1, 10)[0]
|
||||||
|
call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
|
||||||
|
call assert_equal([attrs[4]] + repeat([attrs[5]], 5), attrs[4:9])
|
||||||
|
call assert_notequal(attrs[0], attrs[4])
|
||||||
|
call assert_notequal(attrs[4], attrs[5])
|
||||||
|
call assert_notequal(attrs0[0], attrs[0])
|
||||||
|
call assert_notequal(attrs0[4], attrs[4])
|
||||||
|
call Check_lcs_eol_attrs(attrs, 1, 10)
|
||||||
|
|
||||||
|
if IsColorable()
|
||||||
|
" bg-color
|
||||||
|
exe hi_bg
|
||||||
|
|
||||||
|
" expected:
|
||||||
|
" 'abcd '
|
||||||
|
" ^^^^ bg-color of 'CursorLine'
|
||||||
|
" ^ 'Search' highlight
|
||||||
|
" ^^^^^ bg-color of 'CursorLine'
|
||||||
|
let attrs = ScreenAttrs(1, 10)[0]
|
||||||
|
call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
|
||||||
|
call assert_equal(repeat([attrs[5]], 5), attrs[5:9])
|
||||||
|
call assert_equal(attrs0[4], attrs[4])
|
||||||
|
call assert_notequal(attrs[0], attrs[4])
|
||||||
|
call assert_notequal(attrs[4], attrs[5])
|
||||||
|
call assert_notequal(attrs0[0], attrs[0])
|
||||||
|
call assert_notequal(attrs0[5], attrs[5])
|
||||||
|
call Check_lcs_eol_attrs(attrs, 1, 10)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call CloseWindow()
|
||||||
|
exe hiCursorLine
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_highlight_eol_with_cursorline_vertsplit()
|
||||||
|
if !has('vertsplit')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
|
||||||
|
|
||||||
|
call NewWindow('topleft 5', 5)
|
||||||
|
call setline(1, 'abcd')
|
||||||
|
call matchadd('Search', '\n')
|
||||||
|
|
||||||
|
let expected = "abcd |abcd "
|
||||||
|
let actual = ScreenLines(1, 15)[0]
|
||||||
|
call assert_equal(expected, actual)
|
||||||
|
|
||||||
|
" expected:
|
||||||
|
" 'abcd |abcd '
|
||||||
|
" ^^^^ ^^^^^^^^^ no highlight
|
||||||
|
" ^ 'Search' highlight
|
||||||
|
" ^ 'VertSplit' highlight
|
||||||
|
let attrs0 = ScreenAttrs(1, 15)[0]
|
||||||
|
call assert_equal(repeat([attrs0[0]], 4), attrs0[0:3])
|
||||||
|
call assert_equal(repeat([attrs0[0]], 9), attrs0[6:14])
|
||||||
|
call assert_notequal(attrs0[0], attrs0[4])
|
||||||
|
call assert_notequal(attrs0[0], attrs0[5])
|
||||||
|
call assert_notequal(attrs0[4], attrs0[5])
|
||||||
|
|
||||||
|
setlocal cursorline
|
||||||
|
|
||||||
|
" expected:
|
||||||
|
" 'abcd |abcd '
|
||||||
|
" ^^^^ underline
|
||||||
|
" ^ 'Search' highlight with underline
|
||||||
|
" ^ 'VertSplit' highlight
|
||||||
|
" ^^^^^^^^^ no highlight
|
||||||
|
|
||||||
|
" underline
|
||||||
|
exe hi_ul
|
||||||
|
|
||||||
|
let actual = ScreenLines(1, 15)[0]
|
||||||
|
call assert_equal(expected, actual)
|
||||||
|
|
||||||
|
let attrs = ScreenAttrs(1, 15)[0]
|
||||||
|
call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
|
||||||
|
call assert_equal(repeat([attrs[6]], 9), attrs[6:14])
|
||||||
|
call assert_equal(attrs0[5:14], attrs[5:14])
|
||||||
|
call assert_notequal(attrs[0], attrs[4])
|
||||||
|
call assert_notequal(attrs[0], attrs[5])
|
||||||
|
call assert_notequal(attrs[0], attrs[6])
|
||||||
|
call assert_notequal(attrs[4], attrs[5])
|
||||||
|
call assert_notequal(attrs[5], attrs[6])
|
||||||
|
call assert_notequal(attrs0[0], attrs[0])
|
||||||
|
call assert_notequal(attrs0[4], attrs[4])
|
||||||
|
call Check_lcs_eol_attrs(attrs, 1, 15)
|
||||||
|
|
||||||
|
if IsColorable()
|
||||||
|
" bg-color
|
||||||
|
exe hi_bg
|
||||||
|
|
||||||
|
let actual = ScreenLines(1, 15)[0]
|
||||||
|
call assert_equal(expected, actual)
|
||||||
|
|
||||||
|
let attrs = ScreenAttrs(1, 15)[0]
|
||||||
|
call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
|
||||||
|
call assert_equal(repeat([attrs[6]], 9), attrs[6:14])
|
||||||
|
call assert_equal(attrs0[5:14], attrs[5:14])
|
||||||
|
call assert_notequal(attrs[0], attrs[4])
|
||||||
|
call assert_notequal(attrs[0], attrs[5])
|
||||||
|
call assert_notequal(attrs[0], attrs[6])
|
||||||
|
call assert_notequal(attrs[4], attrs[5])
|
||||||
|
call assert_notequal(attrs[5], attrs[6])
|
||||||
|
call assert_notequal(attrs0[0], attrs[0])
|
||||||
|
call assert_equal(attrs0[4], attrs[4])
|
||||||
|
call Check_lcs_eol_attrs(attrs, 1, 15)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call CloseWindow()
|
||||||
|
exe hiCursorLine
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_highlight_eol_with_cursorline_rightleft()
|
||||||
|
if !has('rightleft')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
|
||||||
|
|
||||||
|
call NewWindow('topleft 5', 10)
|
||||||
|
setlocal rightleft
|
||||||
|
call setline(1, 'abcd')
|
||||||
|
call matchadd('Search', '\n')
|
||||||
|
let attrs0 = ScreenAttrs(1, 10)[0]
|
||||||
|
|
||||||
|
setlocal cursorline
|
||||||
|
|
||||||
|
" underline
|
||||||
|
exe hi_ul
|
||||||
|
|
||||||
|
" expected:
|
||||||
|
" ' dcba'
|
||||||
|
" ^^^^ underline
|
||||||
|
" ^ 'Search' highlight with underline
|
||||||
|
" ^^^^^ underline
|
||||||
|
let attrs = ScreenAttrs(1, 10)[0]
|
||||||
|
call assert_equal(repeat([attrs[9]], 4), attrs[6:9])
|
||||||
|
call assert_equal(repeat([attrs[4]], 5) + [attrs[5]], attrs[0:5])
|
||||||
|
call assert_notequal(attrs[9], attrs[5])
|
||||||
|
call assert_notequal(attrs[4], attrs[5])
|
||||||
|
call assert_notequal(attrs0[9], attrs[9])
|
||||||
|
call assert_notequal(attrs0[5], attrs[5])
|
||||||
|
call Check_lcs_eol_attrs(attrs, 1, 10)
|
||||||
|
|
||||||
|
if IsColorable()
|
||||||
|
" bg-color
|
||||||
|
exe hi_bg
|
||||||
|
|
||||||
|
" expected:
|
||||||
|
" ' dcba'
|
||||||
|
" ^^^^ bg-color of 'CursorLine'
|
||||||
|
" ^ 'Search' highlight
|
||||||
|
" ^^^^^ bg-color of 'CursorLine'
|
||||||
|
let attrs = ScreenAttrs(1, 10)[0]
|
||||||
|
call assert_equal(repeat([attrs[9]], 4), attrs[6:9])
|
||||||
|
call assert_equal(repeat([attrs[4]], 5), attrs[0:4])
|
||||||
|
call assert_equal(attrs0[5], attrs[5])
|
||||||
|
call assert_notequal(attrs[9], attrs[5])
|
||||||
|
call assert_notequal(attrs[5], attrs[4])
|
||||||
|
call assert_notequal(attrs0[9], attrs[9])
|
||||||
|
call assert_notequal(attrs0[4], attrs[4])
|
||||||
|
call Check_lcs_eol_attrs(attrs, 1, 10)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call CloseWindow()
|
||||||
|
exe hiCursorLine
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_highlight_eol_with_cursorline_linewrap()
|
||||||
|
let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
|
||||||
|
|
||||||
|
call NewWindow('topleft 5', 10)
|
||||||
|
call setline(1, [repeat('a', 51) . 'bcd', ''])
|
||||||
|
call matchadd('Search', '\n')
|
||||||
|
|
||||||
|
setlocal wrap
|
||||||
|
normal! gg$
|
||||||
|
let attrs0 = ScreenAttrs(5, 10)[0]
|
||||||
|
setlocal cursorline
|
||||||
|
|
||||||
|
" underline
|
||||||
|
exe hi_ul
|
||||||
|
|
||||||
|
" expected:
|
||||||
|
" 'abcd '
|
||||||
|
" ^^^^ underline
|
||||||
|
" ^ 'Search' highlight with underline
|
||||||
|
" ^^^^^ underline
|
||||||
|
let attrs = ScreenAttrs(5, 10)[0]
|
||||||
|
call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
|
||||||
|
call assert_equal([attrs[4]] + repeat([attrs[5]], 5), attrs[4:9])
|
||||||
|
call assert_notequal(attrs[0], attrs[4])
|
||||||
|
call assert_notequal(attrs[4], attrs[5])
|
||||||
|
call assert_notequal(attrs0[0], attrs[0])
|
||||||
|
call assert_notequal(attrs0[4], attrs[4])
|
||||||
|
call Check_lcs_eol_attrs(attrs, 5, 10)
|
||||||
|
|
||||||
|
if IsColorable()
|
||||||
|
" bg-color
|
||||||
|
exe hi_bg
|
||||||
|
|
||||||
|
" expected:
|
||||||
|
" 'abcd '
|
||||||
|
" ^^^^ bg-color of 'CursorLine'
|
||||||
|
" ^ 'Search' highlight
|
||||||
|
" ^^^^^ bg-color of 'CursorLine'
|
||||||
|
let attrs = ScreenAttrs(5, 10)[0]
|
||||||
|
call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
|
||||||
|
call assert_equal(repeat([attrs[5]], 5), attrs[5:9])
|
||||||
|
call assert_equal(attrs0[4], attrs[4])
|
||||||
|
call assert_notequal(attrs[0], attrs[4])
|
||||||
|
call assert_notequal(attrs[4], attrs[5])
|
||||||
|
call assert_notequal(attrs0[0], attrs[0])
|
||||||
|
call assert_notequal(attrs0[5], attrs[5])
|
||||||
|
call Check_lcs_eol_attrs(attrs, 5, 10)
|
||||||
|
endif
|
||||||
|
|
||||||
|
setlocal nocursorline nowrap
|
||||||
|
normal! gg$
|
||||||
|
let attrs0 = ScreenAttrs(1, 10)[0]
|
||||||
|
setlocal cursorline
|
||||||
|
|
||||||
|
" underline
|
||||||
|
exe hi_ul
|
||||||
|
|
||||||
|
" expected:
|
||||||
|
" 'aaabcd '
|
||||||
|
" ^^^^^^ underline
|
||||||
|
" ^ 'Search' highlight with underline
|
||||||
|
" ^^^ underline
|
||||||
|
let attrs = ScreenAttrs(1, 10)[0]
|
||||||
|
call assert_equal(repeat([attrs[0]], 6), attrs[0:5])
|
||||||
|
call assert_equal([attrs[6]] + repeat([attrs[7]], 3), attrs[6:9])
|
||||||
|
call assert_notequal(attrs[0], attrs[6])
|
||||||
|
call assert_notequal(attrs[6], attrs[7])
|
||||||
|
call assert_notequal(attrs0[0], attrs[0])
|
||||||
|
call assert_notequal(attrs0[6], attrs[6])
|
||||||
|
call Check_lcs_eol_attrs(attrs, 1, 10)
|
||||||
|
|
||||||
|
if IsColorable()
|
||||||
|
" bg-color
|
||||||
|
exe hi_bg
|
||||||
|
|
||||||
|
" expected:
|
||||||
|
" 'aaabcd '
|
||||||
|
" ^^^^^^ bg-color of 'CursorLine'
|
||||||
|
" ^ 'Search' highlight
|
||||||
|
" ^^^ bg-color of 'CursorLine'
|
||||||
|
let attrs = ScreenAttrs(1, 10)[0]
|
||||||
|
call assert_equal(repeat([attrs[0]], 6), attrs[0:5])
|
||||||
|
call assert_equal(repeat([attrs[7]], 3), attrs[7:9])
|
||||||
|
call assert_equal(attrs0[6], attrs[6])
|
||||||
|
call assert_notequal(attrs[0], attrs[6])
|
||||||
|
call assert_notequal(attrs[6], attrs[7])
|
||||||
|
call assert_notequal(attrs0[0], attrs[0])
|
||||||
|
call assert_notequal(attrs0[7], attrs[7])
|
||||||
|
call Check_lcs_eol_attrs(attrs, 1, 10)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call CloseWindow()
|
||||||
|
exe hiCursorLine
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_highlight_eol_with_cursorline_sign()
|
||||||
|
if !has('signs')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
|
||||||
|
|
||||||
|
call NewWindow('topleft 5', 10)
|
||||||
|
call setline(1, 'abcd')
|
||||||
|
call matchadd('Search', '\n')
|
||||||
|
|
||||||
|
sign define Sign text=>>
|
||||||
|
exe 'sign place 1 line=1 name=Sign buffer=' . bufnr('')
|
||||||
|
let attrs0 = ScreenAttrs(1, 10)[0]
|
||||||
|
setlocal cursorline
|
||||||
|
|
||||||
|
" underline
|
||||||
|
exe hi_ul
|
||||||
|
|
||||||
|
" expected:
|
||||||
|
" '>>abcd '
|
||||||
|
" ^^ sign
|
||||||
|
" ^^^^ underline
|
||||||
|
" ^ 'Search' highlight with underline
|
||||||
|
" ^^^ underline
|
||||||
|
let attrs = ScreenAttrs(1, 10)[0]
|
||||||
|
call assert_equal(repeat([attrs[2]], 4), attrs[2:5])
|
||||||
|
call assert_equal([attrs[6]] + repeat([attrs[7]], 3), attrs[6:9])
|
||||||
|
call assert_notequal(attrs[2], attrs[6])
|
||||||
|
call assert_notequal(attrs[6], attrs[7])
|
||||||
|
call assert_notequal(attrs0[2], attrs[2])
|
||||||
|
call assert_notequal(attrs0[6], attrs[6])
|
||||||
|
call Check_lcs_eol_attrs(attrs, 1, 10)
|
||||||
|
|
||||||
|
if IsColorable()
|
||||||
|
" bg-color
|
||||||
|
exe hi_bg
|
||||||
|
|
||||||
|
" expected:
|
||||||
|
" '>>abcd '
|
||||||
|
" ^^ sign
|
||||||
|
" ^^^^ bg-color of 'CursorLine'
|
||||||
|
" ^ 'Search' highlight
|
||||||
|
" ^^^ bg-color of 'CursorLine'
|
||||||
|
let attrs = ScreenAttrs(1, 10)[0]
|
||||||
|
call assert_equal(repeat([attrs[2]], 4), attrs[2:5])
|
||||||
|
call assert_equal(repeat([attrs[7]], 3), attrs[7:9])
|
||||||
|
call assert_equal(attrs0[6], attrs[6])
|
||||||
|
call assert_notequal(attrs[2], attrs[6])
|
||||||
|
call assert_notequal(attrs[6], attrs[7])
|
||||||
|
call assert_notequal(attrs0[2], attrs[2])
|
||||||
|
call assert_notequal(attrs0[7], attrs[7])
|
||||||
|
call Check_lcs_eol_attrs(attrs, 1, 10)
|
||||||
|
endif
|
||||||
|
|
||||||
|
sign unplace 1
|
||||||
|
call CloseWindow()
|
||||||
|
exe hiCursorLine
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_highlight_eol_with_cursorline_breakindent()
|
||||||
|
if !has('linebreak')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
|
||||||
|
|
||||||
|
call NewWindow('topleft 5', 10)
|
||||||
|
setlocal breakindent breakindentopt=min:0,shift:1 showbreak=>
|
||||||
|
call setline(1, ' ' . repeat('a', 9) . 'bcd')
|
||||||
|
call matchadd('Search', '\n')
|
||||||
|
let attrs0 = ScreenAttrs(2, 10)[0]
|
||||||
|
setlocal cursorline
|
||||||
|
|
||||||
|
" underline
|
||||||
|
exe hi_ul
|
||||||
|
|
||||||
|
" expected:
|
||||||
|
" ' >bcd '
|
||||||
|
" ^^^ breakindent and showbreak
|
||||||
|
" ^^^ underline
|
||||||
|
" ^ 'Search' highlight with underline
|
||||||
|
" ^^^ underline
|
||||||
|
let attrs = ScreenAttrs(2, 10)[0]
|
||||||
|
call assert_equal(repeat([attrs[0]], 2), attrs[0:1])
|
||||||
|
call assert_equal(repeat([attrs[3]], 3), attrs[3:5])
|
||||||
|
call assert_equal([attrs[6]] + repeat([attrs[7]], 3), attrs[6:9])
|
||||||
|
call assert_equal(attrs0[0], attrs[0])
|
||||||
|
call assert_notequal(attrs[0], attrs[2])
|
||||||
|
call assert_notequal(attrs[2], attrs[3])
|
||||||
|
call assert_notequal(attrs[3], attrs[6])
|
||||||
|
call assert_notequal(attrs[6], attrs[7])
|
||||||
|
call assert_notequal(attrs0[2], attrs[2])
|
||||||
|
call assert_notequal(attrs0[3], attrs[3])
|
||||||
|
call assert_notequal(attrs0[6], attrs[6])
|
||||||
|
call Check_lcs_eol_attrs(attrs, 2, 10)
|
||||||
|
|
||||||
|
if IsColorable()
|
||||||
|
" bg-color
|
||||||
|
exe hi_bg
|
||||||
|
|
||||||
|
" expected:
|
||||||
|
" ' >bcd '
|
||||||
|
" ^^^ breakindent and showbreak
|
||||||
|
" ^^^ bg-color of 'CursorLine'
|
||||||
|
" ^ 'Search' highlight
|
||||||
|
" ^^^ bg-color of 'CursorLine'
|
||||||
|
let attrs = ScreenAttrs(2, 10)[0]
|
||||||
|
call assert_equal(repeat([attrs[0]], 2), attrs[0:1])
|
||||||
|
call assert_equal(repeat([attrs[3]], 3), attrs[3:5])
|
||||||
|
call assert_equal(repeat([attrs[7]], 3), attrs[7:9])
|
||||||
|
call assert_equal(attrs0[0], attrs[0])
|
||||||
|
call assert_equal(attrs0[6], attrs[6])
|
||||||
|
call assert_notequal(attrs[0], attrs[2])
|
||||||
|
call assert_notequal(attrs[2], attrs[3])
|
||||||
|
call assert_notequal(attrs[3], attrs[6])
|
||||||
|
call assert_notequal(attrs[6], attrs[7])
|
||||||
|
call assert_notequal(attrs0[2], attrs[2])
|
||||||
|
call assert_notequal(attrs0[3], attrs[3])
|
||||||
|
call assert_notequal(attrs0[7], attrs[7])
|
||||||
|
call Check_lcs_eol_attrs(attrs, 2, 10)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call CloseWindow()
|
||||||
|
set showbreak=
|
||||||
|
exe hiCursorLine
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_highlight_eol_on_diff()
|
||||||
|
call setline(1, ['abcd', ''])
|
||||||
|
call matchadd('Search', '\n')
|
||||||
|
let attrs0 = ScreenAttrs(1, 10)[0]
|
||||||
|
|
||||||
|
diffthis
|
||||||
|
botright new
|
||||||
|
diffthis
|
||||||
|
|
||||||
|
" expected:
|
||||||
|
" ' abcd '
|
||||||
|
" ^^ sign
|
||||||
|
" ^^^^ ^^^ 'DiffAdd' highlight
|
||||||
|
" ^ 'Search' highlight
|
||||||
|
let attrs = ScreenAttrs(1, 10)[0]
|
||||||
|
call assert_equal(repeat([attrs[0]], 2), attrs[0:1])
|
||||||
|
call assert_equal(repeat([attrs[2]], 4), attrs[2:5])
|
||||||
|
call assert_equal(repeat([attrs[2]], 3), attrs[7:9])
|
||||||
|
call assert_equal(attrs0[4], attrs[6])
|
||||||
|
call assert_notequal(attrs[0], attrs[2])
|
||||||
|
call assert_notequal(attrs[0], attrs[6])
|
||||||
|
call assert_notequal(attrs[2], attrs[6])
|
||||||
|
call Check_lcs_eol_attrs(attrs, 1, 10)
|
||||||
|
|
||||||
|
bwipe!
|
||||||
|
diffoff
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_termguicolors()
|
||||||
|
if !exists('+termguicolors')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
if has('vtp') && !has('vcon')
|
||||||
|
" Win32: 'guicolors' doesn't work without virtual console.
|
||||||
|
call assert_fails('set termguicolors', 'E954:')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Basic test that setting 'termguicolors' works with one color.
|
||||||
|
set termguicolors
|
||||||
|
redraw
|
||||||
|
set t_Co=1
|
||||||
|
redraw
|
||||||
|
set t_Co=0
|
||||||
|
redraw
|
||||||
|
endfunc
|
@@ -17,6 +17,14 @@ func Test_block_shift_multibyte()
|
|||||||
q!
|
q!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_block_shift_overflow()
|
||||||
|
" This used to cause a multiplication overflow followed by a crash.
|
||||||
|
new
|
||||||
|
normal ii
|
||||||
|
exe "normal \<C-V>876543210>"
|
||||||
|
q!
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_Visual_ctrl_o()
|
func Test_Visual_ctrl_o()
|
||||||
new
|
new
|
||||||
call setline(1, ['one', 'two', 'three'])
|
call setline(1, ['one', 'two', 'three'])
|
||||||
@@ -118,9 +126,34 @@ func Test_blockwise_visual()
|
|||||||
enew!
|
enew!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" Test swapping corners in blockwise visual mode with o and O
|
||||||
|
func Test_blockwise_visual_o_O()
|
||||||
|
enew!
|
||||||
|
|
||||||
|
exe "norm! 10i.\<Esc>Y4P3lj\<C-V>4l2jr "
|
||||||
|
exe "norm! gvO\<Esc>ra"
|
||||||
|
exe "norm! gvO\<Esc>rb"
|
||||||
|
exe "norm! gvo\<C-c>rc"
|
||||||
|
exe "norm! gvO\<C-c>rd"
|
||||||
|
|
||||||
|
call assert_equal(['..........',
|
||||||
|
\ '...c d..',
|
||||||
|
\ '... ..',
|
||||||
|
\ '...a b..',
|
||||||
|
\ '..........'], getline(1, '$'))
|
||||||
|
|
||||||
|
enew!
|
||||||
|
endfun
|
||||||
|
|
||||||
" Test Virtual replace mode.
|
" Test Virtual replace mode.
|
||||||
func Test_virtual_replace()
|
func Test_virtual_replace()
|
||||||
throw 'skipped: TODO: '
|
throw 'skipped: TODO: '
|
||||||
|
if exists('&t_kD')
|
||||||
|
let save_t_kD = &t_kD
|
||||||
|
endif
|
||||||
|
if exists('&t_kb')
|
||||||
|
let save_t_kb = &t_kb
|
||||||
|
endif
|
||||||
exe "set t_kD=\<C-V>x7f t_kb=\<C-V>x08"
|
exe "set t_kD=\<C-V>x7f t_kb=\<C-V>x08"
|
||||||
enew!
|
enew!
|
||||||
exe "normal a\nabcdefghi\njk\tlmn\n opq rst\n\<C-D>uvwxyz"
|
exe "normal a\nabcdefghi\njk\tlmn\n opq rst\n\<C-D>uvwxyz"
|
||||||
@@ -151,4 +184,96 @@ func Test_virtual_replace()
|
|||||||
call assert_equal(['AB......CDEFGHI.Jkl',
|
call assert_equal(['AB......CDEFGHI.Jkl',
|
||||||
\ 'AB IJKLMNO QRst'], getline(12, 13))
|
\ 'AB IJKLMNO QRst'], getline(12, 13))
|
||||||
enew!
|
enew!
|
||||||
|
set noai bs&vim
|
||||||
|
if exists('save_t_kD')
|
||||||
|
let &t_kD = save_t_kD
|
||||||
|
endif
|
||||||
|
if exists('save_t_kb')
|
||||||
|
let &t_kb = save_t_kb
|
||||||
|
endif
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Test Virtual replace mode.
|
||||||
|
func Test_virtual_replace2()
|
||||||
|
enew!
|
||||||
|
set bs=2
|
||||||
|
exe "normal a\nabcdefghi\njk\tlmn\n opq rst\n\<C-D>uvwxyz"
|
||||||
|
call cursor(1,1)
|
||||||
|
" Test 1: Test that del deletes the newline
|
||||||
|
exe "normal gR0\<del> 1\nA\nBCDEFGHIJ\n\tKL\nMNO\nPQR"
|
||||||
|
call assert_equal(['0 1',
|
||||||
|
\ 'A',
|
||||||
|
\ 'BCDEFGHIJ',
|
||||||
|
\ ' KL',
|
||||||
|
\ 'MNO',
|
||||||
|
\ 'PQR',
|
||||||
|
\ ], getline(1, 6))
|
||||||
|
" Test 2:
|
||||||
|
" a newline is not deleted, if no newline has been added in virtual replace mode
|
||||||
|
%d_
|
||||||
|
call setline(1, ['abcd', 'efgh', 'ijkl'])
|
||||||
|
call cursor(2,1)
|
||||||
|
exe "norm! gR1234\<cr>5\<bs>\<bs>\<bs>"
|
||||||
|
call assert_equal(['abcd',
|
||||||
|
\ '123h',
|
||||||
|
\ 'ijkl'], getline(1, '$'))
|
||||||
|
" Test 3:
|
||||||
|
" a newline is deleted, if a newline has been inserted before in virtual replace mode
|
||||||
|
%d_
|
||||||
|
call setline(1, ['abcd', 'efgh', 'ijkl'])
|
||||||
|
call cursor(2,1)
|
||||||
|
exe "norm! gR1234\<cr>\<cr>56\<bs>\<bs>\<bs>"
|
||||||
|
call assert_equal(['abcd',
|
||||||
|
\ '1234',
|
||||||
|
\ 'ijkl'], getline(1, '$'))
|
||||||
|
" Test 4:
|
||||||
|
" delete add a newline, delete it, add it again and check undo
|
||||||
|
%d_
|
||||||
|
call setline(1, ['abcd', 'efgh', 'ijkl'])
|
||||||
|
call cursor(2,1)
|
||||||
|
" break undo sequence explicitly
|
||||||
|
let &ul = &ul
|
||||||
|
exe "norm! gR1234\<cr>\<bs>\<del>56\<cr>"
|
||||||
|
let &ul = &ul
|
||||||
|
call assert_equal(['abcd',
|
||||||
|
\ '123456',
|
||||||
|
\ ''], getline(1, '$'))
|
||||||
|
norm! u
|
||||||
|
call assert_equal(['abcd',
|
||||||
|
\ 'efgh',
|
||||||
|
\ 'ijkl'], getline(1, '$'))
|
||||||
|
" clean up
|
||||||
|
%d_
|
||||||
|
set bs&vim
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Test for Visual mode not being reset causing E315 error.
|
||||||
|
func TriggerTheProblem()
|
||||||
|
" At this point there is no visual selection because :call reset it.
|
||||||
|
" Let's restore the selection:
|
||||||
|
normal gv
|
||||||
|
'<,'>del _
|
||||||
|
try
|
||||||
|
exe "normal \<Esc>"
|
||||||
|
catch /^Vim\%((\a\+)\)\=:E315/
|
||||||
|
echom 'Snap! E315 error!'
|
||||||
|
let g:msg = 'Snap! E315 error!'
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_visual_mode_reset()
|
||||||
|
set belloff=all
|
||||||
|
enew
|
||||||
|
let g:msg = "Everything's fine."
|
||||||
|
enew
|
||||||
|
setl buftype=nofile
|
||||||
|
call append(line('$'), 'Delete this line.')
|
||||||
|
|
||||||
|
" NOTE: this has to be done by a call to a function because executing :del
|
||||||
|
" the ex-way will require the colon operator which resets the visual mode
|
||||||
|
" thus preventing the problem:
|
||||||
|
exe "normal! GV:call TriggerTheProblem()\<CR>"
|
||||||
|
call assert_equal("Everything's fine.", g:msg)
|
||||||
|
|
||||||
|
set belloff&
|
||||||
endfunc
|
endfunc
|
||||||
|
@@ -17,7 +17,7 @@ func Test_window_cmd_ls0_with_split()
|
|||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_window_cmd_cmdwin_with_vsp()
|
func Test_window_cmd_cmdwin_with_vsp()
|
||||||
let efmt='Expected 0 but got %d (in ls=%d, %s window)'
|
let efmt = 'Expected 0 but got %d (in ls=%d, %s window)'
|
||||||
for v in range(0, 2)
|
for v in range(0, 2)
|
||||||
exec "set ls=" . v
|
exec "set ls=" . v
|
||||||
vsplit
|
vsplit
|
||||||
@@ -417,4 +417,92 @@ func Test_window_newtab()
|
|||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
|
||||||
|
" Tests for adjusting window and contents
|
||||||
|
func GetScreenStr(row)
|
||||||
|
let str = ""
|
||||||
|
for c in range(1,3)
|
||||||
|
let str .= nr2char(screenchar(a:row, c))
|
||||||
|
endfor
|
||||||
|
return str
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_window_contents()
|
||||||
|
enew! | only | new
|
||||||
|
call setline(1, range(1,256))
|
||||||
|
|
||||||
|
exe "norm! \<C-W>t\<C-W>=1Gzt\<C-W>w\<C-W>+"
|
||||||
|
redraw
|
||||||
|
let s3 = GetScreenStr(1)
|
||||||
|
wincmd p
|
||||||
|
call assert_equal(1, line("w0"))
|
||||||
|
call assert_equal('1 ', s3)
|
||||||
|
|
||||||
|
exe "norm! \<C-W>t\<C-W>=50Gzt\<C-W>w\<C-W>+"
|
||||||
|
redraw
|
||||||
|
let s3 = GetScreenStr(1)
|
||||||
|
wincmd p
|
||||||
|
call assert_equal(50, line("w0"))
|
||||||
|
call assert_equal('50 ', s3)
|
||||||
|
|
||||||
|
exe "norm! \<C-W>t\<C-W>=59Gzt\<C-W>w\<C-W>+"
|
||||||
|
redraw
|
||||||
|
let s3 = GetScreenStr(1)
|
||||||
|
wincmd p
|
||||||
|
call assert_equal(59, line("w0"))
|
||||||
|
call assert_equal('59 ', s3)
|
||||||
|
|
||||||
|
bwipeout!
|
||||||
|
call test_garbagecollect_now()
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_access_freed_mem()
|
||||||
|
" This was accessing freed memory
|
||||||
|
au * 0 vs xxx
|
||||||
|
arg 0
|
||||||
|
argadd
|
||||||
|
all
|
||||||
|
all
|
||||||
|
au!
|
||||||
|
bwipe xxx
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_visual_cleared_after_window_split()
|
||||||
|
new | only!
|
||||||
|
let smd_save = &showmode
|
||||||
|
set showmode
|
||||||
|
let ls_save = &laststatus
|
||||||
|
set laststatus=1
|
||||||
|
call setline(1, ['a', 'b', 'c', 'd', ''])
|
||||||
|
norm! G
|
||||||
|
exe "norm! kkvk"
|
||||||
|
redraw
|
||||||
|
exe "norm! \<C-W>v"
|
||||||
|
redraw
|
||||||
|
" check if '-- VISUAL --' disappeared from command line
|
||||||
|
let columns = range(1, &columns)
|
||||||
|
let cmdlinechars = map(columns, 'nr2char(screenchar(&lines, v:val))')
|
||||||
|
let cmdline = join(cmdlinechars, '')
|
||||||
|
let cmdline_ltrim = substitute(cmdline, '^\s*', "", "")
|
||||||
|
let mode_shown = substitute(cmdline_ltrim, '\s*$', "", "")
|
||||||
|
call assert_equal('', mode_shown)
|
||||||
|
let &showmode = smd_save
|
||||||
|
let &laststatus = ls_save
|
||||||
|
bwipe!
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_winrestcmd()
|
||||||
|
2split
|
||||||
|
3vsplit
|
||||||
|
let a = winrestcmd()
|
||||||
|
call assert_equal(2, winheight(0))
|
||||||
|
call assert_equal(3, winwidth(0))
|
||||||
|
wincmd =
|
||||||
|
call assert_notequal(2, winheight(0))
|
||||||
|
call assert_notequal(3, winwidth(0))
|
||||||
|
exe a
|
||||||
|
call assert_equal(2, winheight(0))
|
||||||
|
call assert_equal(3, winwidth(0))
|
||||||
|
only
|
||||||
|
endfunc
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2 expandtab
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@@ -1,5 +1,10 @@
|
|||||||
" Functions about view shared by several tests
|
" Functions about view shared by several tests
|
||||||
|
|
||||||
|
" Only load this script once.
|
||||||
|
if exists('*ScreenLines')
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
" ScreenLines(lnum, width) or
|
" ScreenLines(lnum, width) or
|
||||||
" ScreenLines([start, end], width)
|
" ScreenLines([start, end], width)
|
||||||
function! ScreenLines(lnum, width) abort
|
function! ScreenLines(lnum, width) abort
|
||||||
@@ -18,6 +23,22 @@ function! ScreenLines(lnum, width) abort
|
|||||||
return lines
|
return lines
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! ScreenAttrs(lnum, width) abort
|
||||||
|
redraw!
|
||||||
|
if type(a:lnum) == v:t_list
|
||||||
|
let start = a:lnum[0]
|
||||||
|
let end = a:lnum[1]
|
||||||
|
else
|
||||||
|
let start = a:lnum
|
||||||
|
let end = a:lnum
|
||||||
|
endif
|
||||||
|
let attrs = []
|
||||||
|
for l in range(start, end)
|
||||||
|
let attrs += [map(range(1, a:width), 'screenattr(l, v:val)')]
|
||||||
|
endfor
|
||||||
|
return attrs
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! NewWindow(height, width) abort
|
function! NewWindow(height, width) abort
|
||||||
exe a:height . 'new'
|
exe a:height . 'new'
|
||||||
exe a:width . 'vsp'
|
exe a:width . 'vsp'
|
||||||
|
@@ -2233,10 +2233,11 @@ static void u_undoredo(int undo, bool do_buf_event)
|
|||||||
* If the file is empty, there is an empty line 1 that we
|
* If the file is empty, there is an empty line 1 that we
|
||||||
* should get rid of, by replacing it with the new line
|
* should get rid of, by replacing it with the new line
|
||||||
*/
|
*/
|
||||||
if (empty_buffer && lnum == 0)
|
if (empty_buffer && lnum == 0) {
|
||||||
ml_replace((linenr_T)1, uep->ue_array[i], TRUE);
|
ml_replace((linenr_T)1, uep->ue_array[i], true);
|
||||||
else
|
} else {
|
||||||
ml_append(lnum, uep->ue_array[i], (colnr_T)0, FALSE);
|
ml_append(lnum, uep->ue_array[i], (colnr_T)0, FALSE);
|
||||||
|
}
|
||||||
xfree(uep->ue_array[i]);
|
xfree(uep->ue_array[i]);
|
||||||
}
|
}
|
||||||
xfree((char_u *)uep->ue_array);
|
xfree((char_u *)uep->ue_array);
|
||||||
@@ -2902,7 +2903,7 @@ void u_undoline(void)
|
|||||||
curbuf->b_u_line_lnum + 1, (linenr_T)0, FALSE) == FAIL)
|
curbuf->b_u_line_lnum + 1, (linenr_T)0, FALSE) == FAIL)
|
||||||
return;
|
return;
|
||||||
oldp = u_save_line(curbuf->b_u_line_lnum);
|
oldp = u_save_line(curbuf->b_u_line_lnum);
|
||||||
ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, TRUE);
|
ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, true);
|
||||||
changed_bytes(curbuf->b_u_line_lnum, 0);
|
changed_bytes(curbuf->b_u_line_lnum, 0);
|
||||||
xfree(curbuf->b_u_line_ptr);
|
xfree(curbuf->b_u_line_ptr);
|
||||||
curbuf->b_u_line_ptr = oldp;
|
curbuf->b_u_line_ptr = oldp;
|
||||||
|
@@ -2296,6 +2296,9 @@ winframe_remove (
|
|||||||
if (frp2->fr_win != NULL)
|
if (frp2->fr_win != NULL)
|
||||||
frp2->fr_win->w_frame = frp2->fr_parent;
|
frp2->fr_win->w_frame = frp2->fr_parent;
|
||||||
frp = frp2->fr_parent;
|
frp = frp2->fr_parent;
|
||||||
|
if (topframe->fr_child == frp2) {
|
||||||
|
topframe->fr_child = frp;
|
||||||
|
}
|
||||||
xfree(frp2);
|
xfree(frp2);
|
||||||
|
|
||||||
frp2 = frp->fr_parent;
|
frp2 = frp->fr_parent;
|
||||||
@@ -2317,6 +2320,9 @@ winframe_remove (
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (topframe->fr_child == frp) {
|
||||||
|
topframe->fr_child = frp2;
|
||||||
|
}
|
||||||
xfree(frp);
|
xfree(frp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2959,7 +2965,6 @@ static int win_alloc_firstwin(win_T *oldwin)
|
|||||||
topframe = curwin->w_frame;
|
topframe = curwin->w_frame;
|
||||||
topframe->fr_width = Columns;
|
topframe->fr_width = Columns;
|
||||||
topframe->fr_height = Rows - p_ch;
|
topframe->fr_height = Rows - p_ch;
|
||||||
topframe->fr_win = curwin;
|
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@@ -3970,18 +3975,20 @@ win_remove (
|
|||||||
tabpage_T *tp /* tab page "win" is in, NULL for current */
|
tabpage_T *tp /* tab page "win" is in, NULL for current */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (wp->w_prev != NULL)
|
if (wp->w_prev != NULL) {
|
||||||
wp->w_prev->w_next = wp->w_next;
|
wp->w_prev->w_next = wp->w_next;
|
||||||
else if (tp == NULL)
|
} else if (tp == NULL) {
|
||||||
firstwin = wp->w_next;
|
firstwin = curtab->tp_firstwin = wp->w_next;
|
||||||
else
|
} else {
|
||||||
tp->tp_firstwin = wp->w_next;
|
tp->tp_firstwin = wp->w_next;
|
||||||
if (wp->w_next != NULL)
|
}
|
||||||
|
if (wp->w_next != NULL) {
|
||||||
wp->w_next->w_prev = wp->w_prev;
|
wp->w_next->w_prev = wp->w_prev;
|
||||||
else if (tp == NULL)
|
} else if (tp == NULL) {
|
||||||
lastwin = wp->w_prev;
|
lastwin = curtab->tp_lastwin = wp->w_prev;
|
||||||
else
|
} else {
|
||||||
tp->tp_lastwin = wp->w_prev;
|
tp->tp_lastwin = wp->w_prev;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -4015,12 +4022,18 @@ static void frame_insert(frame_T *before, frame_T *frp)
|
|||||||
*/
|
*/
|
||||||
static void frame_remove(frame_T *frp)
|
static void frame_remove(frame_T *frp)
|
||||||
{
|
{
|
||||||
if (frp->fr_prev != NULL)
|
if (frp->fr_prev != NULL) {
|
||||||
frp->fr_prev->fr_next = frp->fr_next;
|
frp->fr_prev->fr_next = frp->fr_next;
|
||||||
else
|
} else {
|
||||||
frp->fr_parent->fr_child = frp->fr_next;
|
frp->fr_parent->fr_child = frp->fr_next;
|
||||||
if (frp->fr_next != NULL)
|
// special case: topframe->fr_child == frp
|
||||||
|
if (topframe->fr_child == frp) {
|
||||||
|
topframe->fr_child = frp->fr_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (frp->fr_next != NULL) {
|
||||||
frp->fr_next->fr_prev = frp->fr_prev;
|
frp->fr_next->fr_prev = frp->fr_prev;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -5489,12 +5502,10 @@ int switch_win(win_T **save_curwin, tabpage_T **save_curtab, win_T *win, tabpage
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Restore current tabpage and window saved by switch_win(), if still valid.
|
||||||
* Restore current tabpage and window saved by switch_win(), if still valid.
|
// When "no_display" is true the display won't be affected, no redraw is
|
||||||
* When "no_display" is TRUE the display won't be affected, no redraw is
|
// triggered.
|
||||||
* triggered.
|
void restore_win(win_T *save_curwin, tabpage_T *save_curtab, bool no_display)
|
||||||
*/
|
|
||||||
void restore_win(win_T *save_curwin, tabpage_T *save_curtab, int no_display)
|
|
||||||
{
|
{
|
||||||
if (save_curtab != NULL && valid_tabpage(save_curtab)) {
|
if (save_curtab != NULL && valid_tabpage(save_curtab)) {
|
||||||
if (no_display) {
|
if (no_display) {
|
||||||
|
Reference in New Issue
Block a user