aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/lua/vim/shared.lua2
-rwxr-xr-xscripts/vim-patch.sh6
-rw-r--r--src/nvim/eval.c17
-rw-r--r--src/nvim/main.c4
-rw-r--r--src/nvim/memline.c5
-rw-r--r--src/nvim/move.c15
-rw-r--r--src/nvim/normal.c176
-rw-r--r--src/nvim/ops.c43
-rw-r--r--src/nvim/os/shell.c2
-rw-r--r--src/nvim/screen.c35
-rw-r--r--src/nvim/testdir/test_breakindent.vim67
-rw-r--r--src/nvim/testdir/test_listlbr.vim31
-rw-r--r--test/functional/ex_cmds/mksession_spec.lua23
-rw-r--r--test/functional/terminal/edit_spec.lua6
14 files changed, 258 insertions, 174 deletions
diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua
index a71e9878bb..ea1117a906 100644
--- a/runtime/lua/vim/shared.lua
+++ b/runtime/lua/vim/shared.lua
@@ -321,7 +321,7 @@ function vim.trim(s)
return s:match('^%s*(.*%S)') or ''
end
---- Escapes magic chars in a Lua pattern string.
+--- Escapes magic chars in a Lua pattern.
---
--@see https://github.com/rxi/lume
--@param s String to escape
diff --git a/scripts/vim-patch.sh b/scripts/vim-patch.sh
index ff78cb82f7..f9726e8a87 100755
--- a/scripts/vim-patch.sh
+++ b/scripts/vim-patch.sh
@@ -234,7 +234,8 @@ get_vimpatch() {
msg_ok "Saved patch to '${NVIM_SOURCE_DIR}/${patch_file}'."
}
-# shellcheck disable=SC2015 # "Note that A && B || C is not if-then-else."
+# shellcheck disable=SC2015
+# ^ "Note that A && B || C is not if-then-else."
stage_patch() {
get_vimpatch "$1"
local try_apply="${2:-}"
@@ -305,7 +306,8 @@ git_hub_pr() {
git hub pull new -m "$1"
}
-# shellcheck disable=SC2015 # "Note that A && B || C is not if-then-else."
+# shellcheck disable=SC2015
+# ^ "Note that A && B || C is not if-then-else."
submit_pr() {
require_executable git
local push_first
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 9379d94fa3..55b18d5f4f 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -18383,13 +18383,22 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
int pid = chan->stream.pty.process.pid;
- char buf[1024];
- // format the title with the pid to conform with the term:// URI
- snprintf(buf, sizeof(buf), "term://%s//%d:%s", cwd, pid, cmd);
+ // "./…" => "/home/foo/…"
+ vim_FullName(cwd, (char *)NameBuff, sizeof(NameBuff), false);
+ // "/home/foo/…" => "~/…"
+ size_t len = home_replace(NULL, NameBuff, IObuff, sizeof(IObuff), true);
+ // Trim slash.
+ if (IObuff[len - 1] == '\\' || IObuff[len - 1] == '/') {
+ IObuff[len - 1] = '\0';
+ }
+
+ // Terminal URI: "term://$CWD//$PID:$CMD"
+ snprintf((char *)NameBuff, sizeof(NameBuff), "term://%s//%d:%s",
+ (char *)IObuff, pid, cmd);
// at this point the buffer has no terminal instance associated yet, so unset
// the 'swapfile' option to ensure no swap file will be created
curbuf->b_p_swf = false;
- (void)setfname(curbuf, (char_u *)buf, NULL, true);
+ (void)setfname(curbuf, NameBuff, NULL, true);
// Save the job id and pid in b:terminal_job_{id,pid}
Error err = ERROR_INIT;
// deprecated: use 'channel' buffer option
diff --git a/src/nvim/main.c b/src/nvim/main.c
index be279b449a..a816221a9e 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -339,8 +339,8 @@ int main(int argc, char **argv)
"matchstr(expand(\"<amatch>\"), "
"'\\c\\m" PROTO "\\%(.\\{-}//\\%(\\d\\+:\\)\\?\\)\\?\\zs.*'), "
// capture the working directory
- "{'cwd': get(matchlist(expand(\"<amatch>\"), "
- "'\\c\\m" PROTO "\\(.\\{-}\\)//'), 1, '')})"
+ "{'cwd': expand(get(matchlist(expand(\"<amatch>\"), "
+ "'\\c\\m" PROTO "\\(.\\{-}\\)//'), 1, ''))})"
"|endif");
do_cmdline_cmd("augroup END");
#undef PROTO
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index e5ba17a0a7..922b684120 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -1802,9 +1802,10 @@ char_u *ml_get(linenr_T lnum)
/*
* Return pointer to position "pos".
*/
-char_u *ml_get_pos(pos_T *pos)
+char_u *ml_get_pos(const pos_T *pos)
+ FUNC_ATTR_NONNULL_ALL
{
- return ml_get_buf(curbuf, pos->lnum, FALSE) + pos->col;
+ return ml_get_buf(curbuf, pos->lnum, false) + pos->col;
}
/*
diff --git a/src/nvim/move.c b/src/nvim/move.c
index efbc548620..3ae4f32a83 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -1551,15 +1551,14 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
/* Stop when scrolled nothing or at least "min_scroll", found "extra"
* context for 'scrolloff' and counted all lines below the window. */
if ((((scrolled <= 0 || scrolled >= min_scroll)
- && extra >= (
- mouse_dragging > 0 ? mouse_dragging - 1 :
- p_so))
+ && extra >= (mouse_dragging > 0 ? mouse_dragging - 1 : p_so))
|| boff.lnum + 1 > curbuf->b_ml.ml_line_count)
&& loff.lnum <= curwin->w_botline
&& (loff.lnum < curwin->w_botline
|| loff.fill >= fill_below_window)
- )
+ ) {
break;
+ }
/* Add one line above */
topline_back(&loff);
@@ -1590,9 +1589,8 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
if (used > curwin->w_height_inner) {
break;
}
- if (extra < (
- mouse_dragging > 0 ? mouse_dragging - 1 :
- p_so) || scrolled < min_scroll) {
+ if (extra < (mouse_dragging > 0 ? mouse_dragging - 1 : p_so)
+ || scrolled < min_scroll) {
extra += boff.height;
if (boff.lnum >= curwin->w_botline
|| (boff.lnum + 1 == curwin->w_botline
@@ -1742,8 +1740,7 @@ void cursor_correct(void)
}
validate_botline();
if (curwin->w_botline == curbuf->b_ml.ml_line_count + 1
- && mouse_dragging == 0
- ) {
+ && mouse_dragging == 0) {
below_wanted = 0;
int max_off = (curwin->w_height_inner - 1) / 2;
if (above_wanted > max_off) {
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 3aff3cef84..dac4c8f527 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -760,7 +760,7 @@ static void normal_get_additional_char(NormalState *s)
// because if it's put back with vungetc() it's too late to apply
// mapping.
no_mapping--;
- while (enc_utf8 && lang && (s->c = vpeekc()) > 0
+ while (lang && (s->c = vpeekc()) > 0
&& (s->c >= 0x100 || MB_BYTE2LEN(vpeekc()) > 1)) {
s->c = plain_vgetc();
if (!utf_iscomposing(s->c)) {
@@ -1711,13 +1711,12 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
}
}
- /* Include the trailing byte of a multi-byte char. */
- if (has_mbyte && oap->inclusive) {
- int l;
-
- l = (*mb_ptr2len)(ml_get_pos(&oap->end));
- if (l > 1)
+ // Include the trailing byte of a multi-byte char.
+ if (oap->inclusive) {
+ const int l = utfc_ptr2len(ml_get_pos(&oap->end));
+ if (l > 1) {
oap->end.col += l - 1;
+ }
}
curwin->w_set_curswant = true;
@@ -1846,10 +1845,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
restart_edit = 0;
// Restore linebreak, so that when the user edits it looks as before.
- if (curwin->w_p_lbr != lbr_saved) {
- curwin->w_p_lbr = lbr_saved;
- get_op_vcol(oap, redo_VIsual_mode, false);
- }
+ curwin->w_p_lbr = lbr_saved;
// Reset finish_op now, don't want it set inside edit().
finish_op = false;
@@ -1935,10 +1931,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
restart_edit = 0;
// Restore linebreak, so that when the user edits it looks as before.
- if (curwin->w_p_lbr != lbr_saved) {
- curwin->w_p_lbr = lbr_saved;
- get_op_vcol(oap, redo_VIsual_mode, false);
- }
+ curwin->w_p_lbr = lbr_saved;
op_insert(oap, cap->count1);
@@ -1964,10 +1957,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
CancelRedo();
} else {
// Restore linebreak, so that when the user edits it looks as before.
- if (curwin->w_p_lbr != lbr_saved) {
- curwin->w_p_lbr = lbr_saved;
- get_op_vcol(oap, redo_VIsual_mode, false);
- }
+ curwin->w_p_lbr = lbr_saved;
op_replace(oap, cap->nchar);
}
@@ -2906,17 +2896,17 @@ static void find_end_of_word(pos_T *pos)
*/
static int get_mouse_class(char_u *p)
{
- int c;
-
- if (has_mbyte && MB_BYTE2LEN(p[0]) > 1)
+ if (MB_BYTE2LEN(p[0]) > 1) {
return mb_get_class(p);
+ }
- c = *p;
- if (c == ' ' || c == '\t')
+ const int c = *p;
+ if (c == ' ' || c == '\t') {
return 0;
-
- if (vim_iswordc(c))
+ }
+ if (vim_iswordc(c)) {
return 2;
+ }
/*
* There are a few special cases where we want certain combinations of
@@ -4916,10 +4906,9 @@ static void nv_ident(cmdarg_T *cap)
*p++ = '\\';
/* When current byte is a part of multibyte character, copy all
* bytes of that character. */
- if (has_mbyte) {
- size_t len = (size_t)((*mb_ptr2len)(ptr) - 1);
- for (size_t i = 0; i < len && n > 0; ++i, --n)
- *p++ = *ptr++;
+ const size_t len = (size_t)(utfc_ptr2len(ptr) - 1);
+ for (size_t i = 0; i < len && n > 0; i++, n--) {
+ *p++ = *ptr++;
}
*p++ = *ptr++;
}
@@ -4930,11 +4919,11 @@ static void nv_ident(cmdarg_T *cap)
* Execute the command.
*/
if (cmdchar == '*' || cmdchar == '#') {
- if (!g_cmd && (
- has_mbyte ? vim_iswordp(mb_prevptr(get_cursor_line_ptr(), ptr)) :
- vim_iswordc(ptr[-1])))
+ if (!g_cmd
+ && vim_iswordp(mb_prevptr(get_cursor_line_ptr(), ptr))) {
STRCAT(buf, "\\>");
- /* put pattern in search history */
+ }
+ // put pattern in search history
init_history();
add_to_history(HIST_SEARCH, (char_u *)buf, true, NUL);
(void)normal_search(cap, cmdchar == '*' ? '/' : '?', (char_u *)buf, 0,
@@ -4977,9 +4966,8 @@ get_visual_text (
*pp = ml_get_pos(&VIsual);
*lenp = (size_t)curwin->w_cursor.col - (size_t)VIsual.col + 1;
}
- if (has_mbyte)
- /* Correct the length to include the whole last character. */
- *lenp += (size_t)((*mb_ptr2len)(*pp + (*lenp - 1)) - 1);
+ // Correct the length to include the whole last character.
+ *lenp += (size_t)(utfc_ptr2len(*pp + (*lenp - 1)) - 1);
}
reset_VIsual_and_resel();
return true;
@@ -5197,11 +5185,7 @@ static void nv_left(cmdarg_T *cap)
char_u *cp = get_cursor_pos_ptr();
if (*cp != NUL) {
- if (has_mbyte) {
- curwin->w_cursor.col += (*mb_ptr2len)(cp);
- } else {
- curwin->w_cursor.col++;
- }
+ curwin->w_cursor.col += utfc_ptr2len(cp);
}
cap->retval |= CA_NO_ADJ_OP_END;
}
@@ -5859,7 +5843,6 @@ static void nv_replace(cmdarg_T *cap)
{
char_u *ptr;
int had_ctrl_v;
- long n;
if (checkclearop(cap->oap))
return;
@@ -5913,7 +5896,7 @@ static void nv_replace(cmdarg_T *cap)
/* Abort if not enough characters to replace. */
ptr = get_cursor_pos_ptr();
if (STRLEN(ptr) < (unsigned)cap->count1
- || (has_mbyte && mb_charlen(ptr) < cap->count1)
+ || (mb_charlen(ptr) < cap->count1)
) {
clearopbeep(cap->oap);
return;
@@ -5955,71 +5938,44 @@ static void nv_replace(cmdarg_T *cap)
NUL, 'r', NUL, had_ctrl_v, cap->nchar);
curbuf->b_op_start = curwin->w_cursor;
- if (has_mbyte) {
- int old_State = State;
-
- if (cap->ncharC1 != 0)
- AppendCharToRedobuff(cap->ncharC1);
- if (cap->ncharC2 != 0)
- AppendCharToRedobuff(cap->ncharC2);
-
- /* This is slow, but it handles replacing a single-byte with a
- * multi-byte and the other way around. Also handles adding
- * composing characters for utf-8. */
- for (n = cap->count1; n > 0; --n) {
- State = REPLACE;
- if (cap->nchar == Ctrl_E || cap->nchar == Ctrl_Y) {
- int c = ins_copychar(curwin->w_cursor.lnum
- + (cap->nchar == Ctrl_Y ? -1 : 1));
- if (c != NUL)
- ins_char(c);
- else
- /* will be decremented further down */
- ++curwin->w_cursor.col;
- } else
- ins_char(cap->nchar);
- State = old_State;
- if (cap->ncharC1 != 0)
- ins_char(cap->ncharC1);
- if (cap->ncharC2 != 0)
- ins_char(cap->ncharC2);
- }
- } else {
- /*
- * Replace the characters within one line.
- */
- for (n = cap->count1; n > 0; --n) {
- /*
- * Get ptr again, because u_save and/or showmatch() will have
- * released the line. At the same time we let know that the
- * line will be changed.
- */
- ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, true);
- if (cap->nchar == Ctrl_E || cap->nchar == Ctrl_Y) {
- int c = ins_copychar(curwin->w_cursor.lnum
- + (cap->nchar == Ctrl_Y ? -1 : 1));
- if (c != NUL) {
- assert(c >= 0 && c <= UCHAR_MAX);
- ptr[curwin->w_cursor.col] = (char_u)c;
- }
+ const int old_State = State;
+
+ if (cap->ncharC1 != 0) {
+ AppendCharToRedobuff(cap->ncharC1);
+ }
+ if (cap->ncharC2 != 0) {
+ AppendCharToRedobuff(cap->ncharC2);
+ }
+
+ // This is slow, but it handles replacing a single-byte with a
+ // multi-byte and the other way around. Also handles adding
+ // composing characters for utf-8.
+ for (long n = cap->count1; n > 0; n--) {
+ State = REPLACE;
+ if (cap->nchar == Ctrl_E || cap->nchar == Ctrl_Y) {
+ int c = ins_copychar(curwin->w_cursor.lnum
+ + (cap->nchar == Ctrl_Y ? -1 : 1));
+ if (c != NUL) {
+ ins_char(c);
} else {
- assert(cap->nchar >= 0 && cap->nchar <= UCHAR_MAX);
- ptr[curwin->w_cursor.col] = (char_u)cap->nchar;
+ // will be decremented further down
+ curwin->w_cursor.col++;
}
- if (p_sm && msg_silent == 0)
- showmatch(cap->nchar);
- ++curwin->w_cursor.col;
+ } else {
+ ins_char(cap->nchar);
+ }
+ State = old_State;
+ if (cap->ncharC1 != 0) {
+ ins_char(cap->ncharC1);
+ }
+ if (cap->ncharC2 != 0) {
+ ins_char(cap->ncharC2);
}
-
- /* mark the buffer as changed and prepare for displaying */
- changed_bytes(curwin->w_cursor.lnum,
- (colnr_T)(curwin->w_cursor.col - cap->count1));
}
--curwin->w_cursor.col; /* cursor on the last replaced char */
/* if the character on the left of the current cursor is a multi-byte
* character, move two characters left */
- if (has_mbyte)
- mb_adjust_cursor();
+ mb_adjust_cursor();
curbuf->b_op_end = curwin->w_cursor;
curwin->w_set_curswant = true;
set_last_insert(cap->nchar);
@@ -7365,10 +7321,9 @@ static void adjust_cursor(oparg_T *oap)
&& (!VIsual_active || *p_sel == 'o')
&& !virtual_active() && (ve_flags & VE_ONEMORE) == 0
) {
- --curwin->w_cursor.col;
- /* prevent cursor from moving on the trail byte */
- if (has_mbyte)
- mb_adjust_cursor();
+ curwin->w_cursor.col--;
+ // prevent cursor from moving on the trail byte
+ mb_adjust_cursor();
oap->inclusive = true;
}
}
@@ -7395,10 +7350,7 @@ static void adjust_for_sel(cmdarg_T *cap)
{
if (VIsual_active && cap->oap->inclusive && *p_sel == 'e'
&& gchar_cursor() != NUL && lt(VIsual, curwin->w_cursor)) {
- if (has_mbyte)
- inc_cursor();
- else
- ++curwin->w_cursor.col;
+ inc_cursor();
cap->oap->inclusive = false;
}
}
@@ -7988,9 +7940,7 @@ static void get_op_vcol(
oap->motion_type = kMTBlockWise;
// prevent from moving onto a trail byte
- if (has_mbyte) {
- mark_mb_adjustpos(curwin->w_buffer, &oap->end);
- }
+ mark_mb_adjustpos(curwin->w_buffer, &oap->end);
getvvcol(curwin, &(oap->start), &oap->start_vcol, NULL, &oap->end_vcol);
if (!redo_VIsual_busy) {
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 641323ae5e..db5c98ed78 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -357,15 +357,11 @@ static void shift_block(oparg_T *oap, int amount)
colnr_T ws_vcol = bd.start_vcol - bd.pre_whitesp;
char_u * old_textstart = bd.textstart;
if (bd.startspaces) {
- if (has_mbyte) {
- if ((*mb_ptr2len)(bd.textstart) == 1) {
- bd.textstart++;
- } else {
- ws_vcol = 0;
- bd.startspaces = 0;
- }
- } else {
+ if (utfc_ptr2len(bd.textstart) == 1) {
bd.textstart++;
+ } else {
+ ws_vcol = 0;
+ bd.startspaces = 0;
}
}
for (; ascii_iswhite(*bd.textstart); ) {
@@ -1215,9 +1211,7 @@ static void stuffescaped(const char *arg, int literally)
/* stuff a single special character */
if (*arg != NUL) {
- const int c = (has_mbyte
- ? mb_cptr2char_adv((const char_u **)&arg)
- : (uint8_t)(*arg++));
+ const int c = mb_cptr2char_adv((const char_u **)&arg);
if (literally && ((c < ' ' && c != TAB) || c == DEL)) {
stuffcharReadbuff(Ctrl_V);
}
@@ -1389,8 +1383,7 @@ int op_delete(oparg_T *oap)
return FAIL;
}
- if (has_mbyte)
- mb_adjust_opend(oap);
+ mb_adjust_opend(oap);
/*
* Imitate the strange Vi behaviour: If the delete spans more than one
@@ -1736,8 +1729,7 @@ int op_replace(oparg_T *oap, int c)
c = NL;
}
- if (has_mbyte)
- mb_adjust_opend(oap);
+ mb_adjust_opend(oap);
if (u_save((linenr_T)(oap->start.lnum - 1),
(linenr_T)(oap->end.lnum + 1)) == FAIL)
@@ -2012,17 +2004,16 @@ void op_tilde(oparg_T *oap)
* Returns TRUE if some character was changed.
*/
static int swapchars(int op_type, pos_T *pos, int length)
+ FUNC_ATTR_NONNULL_ALL
{
- int todo;
int did_change = 0;
- for (todo = length; todo > 0; --todo) {
- if (has_mbyte) {
- int len = (*mb_ptr2len)(ml_get_pos(pos));
+ for (int todo = length; todo > 0; todo--) {
+ const int len = utfc_ptr2len(ml_get_pos(pos));
- /* we're counting bytes, not characters */
- if (len > 0)
- todo -= len - 1;
+ // we're counting bytes, not characters
+ if (len > 0) {
+ todo -= len - 1;
}
did_change |= swapchar(op_type, pos);
if (inc(pos) == -1) /* at end of file */
@@ -3052,7 +3043,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col);
// move to start of next multi-byte character
- curwin->w_cursor.col += (*mb_ptr2len)(get_cursor_pos_ptr());
+ curwin->w_cursor.col += utfc_ptr2len(get_cursor_pos_ptr());
col++;
} else {
getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2);
@@ -3615,7 +3606,7 @@ dis_msg(
while (*p != NUL
&& !(*p == ESC && skip_esc && *(p + 1) == NUL)
&& (n -= ptr2cells(p)) >= 0) {
- if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) {
+ if ((l = utfc_ptr2len(p)) > 1) {
msg_outtrans_len(p, l);
p += l;
} else
@@ -4414,7 +4405,10 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum,
char_u *line;
char_u *prev_pstart;
char_u *prev_pend;
+ const int lbr_saved = curwin->w_p_lbr;
+ // Avoid a problem with unwanted linebreaks in block mode.
+ curwin->w_p_lbr = false;
bdp->startspaces = 0;
bdp->endspaces = 0;
bdp->textlen = 0;
@@ -4514,6 +4508,7 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum,
}
bdp->textcol = (colnr_T) (pstart - line);
bdp->textstart = pstart;
+ curwin->w_p_lbr = lbr_saved;
}
/// Handle the add/subtract operator.
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c
index f4377b1457..d1de18d5b3 100644
--- a/src/nvim/os/shell.c
+++ b/src/nvim/os/shell.c
@@ -423,7 +423,7 @@ static bool out_data_decide_throttle(size_t size)
pulse_msg[1] = (tick > 1) ? '.' : ' ';
pulse_msg[2] = (tick > 2) ? '.' : ' ';
if (visit == 1) {
- msg_puts("[...]\n");
+ msg_puts("...\n");
}
msg_putchar('\r'); // put cursor at start of line
msg_puts(pulse_msg);
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 97893223a4..b9450e63eb 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -2254,7 +2254,7 @@ win_line (
int change_start = MAXCOL; // first col of changed area
int change_end = -1; // last col of changed area
colnr_T trailcol = MAXCOL; // start of trailing spaces
- int need_showbreak = false; // overlong line, skip first x chars
+ bool need_showbreak = false; // overlong line, skip first x chars
int line_attr = 0; // attribute for the whole line
int line_attr_lowprio = 0; // low-priority attribute for the line
matchitem_T *cur; // points to the match list
@@ -2665,11 +2665,12 @@ win_line (
else if (fromcol >= 0 && fromcol < vcol)
fromcol = vcol;
- /* When w_skipcol is non-zero, first line needs 'showbreak' */
- if (wp->w_p_wrap)
- need_showbreak = TRUE;
- /* When spell checking a word we need to figure out the start of the
- * word and if it's badly spelled or not. */
+ // When w_skipcol is non-zero, first line needs 'showbreak'
+ if (wp->w_p_wrap) {
+ need_showbreak = true;
+ }
+ // When spell checking a word we need to figure out the start of the
+ // word and if it's badly spelled or not.
if (has_spell) {
size_t len;
colnr_T linecol = (colnr_T)(ptr - line);
@@ -2986,11 +2987,17 @@ win_line (
}
p_extra = NULL;
c_extra = ' ';
- n_extra = get_breakindent_win(wp, ml_get_buf(wp->w_buffer, lnum, FALSE));
- /* Correct end of highlighted area for 'breakindent',
- required wen 'linebreak' is also set. */
- if (tocol == vcol)
+ c_final = NUL;
+ n_extra =
+ get_breakindent_win(wp, ml_get_buf(wp->w_buffer, lnum, false));
+ if (wp->w_skipcol > 0 && wp->w_p_wrap) {
+ need_showbreak = false;
+ }
+ // Correct end of highlighted area for 'breakindent',
+ // required wen 'linebreak' is also set.
+ if (tocol == vcol) {
tocol += n_extra;
+ }
}
}
@@ -3019,7 +3026,9 @@ win_line (
c_final = NUL;
n_extra = (int)STRLEN(p_sbr);
char_attr = win_hl_attr(wp, HLF_AT);
- need_showbreak = false;
+ if (wp->w_skipcol == 0 || !wp->w_p_wrap) {
+ need_showbreak = false;
+ }
vcol_sbr = vcol + MB_CHARLEN(p_sbr);
/* Correct end of highlighted area for 'showbreak',
* required when 'linebreak' is also set. */
@@ -3296,9 +3305,7 @@ win_line (
} else {
int c0;
- if (p_extra_free != NULL) {
- XFREE_CLEAR(p_extra_free);
- }
+ XFREE_CLEAR(p_extra_free);
// Get a character from the line itself.
c0 = c = *ptr;
diff --git a/src/nvim/testdir/test_breakindent.vim b/src/nvim/testdir/test_breakindent.vim
index 4b34420cab..6d88f1dc5a 100644
--- a/src/nvim/testdir/test_breakindent.vim
+++ b/src/nvim/testdir/test_breakindent.vim
@@ -296,3 +296,70 @@ function Test_breakindent16()
call s:compare_lines(expect, lines)
call s:close_windows()
endfunction
+
+func Test_breakindent17_vartabs()
+ if !has("vartabs")
+ return
+ endif
+ let s:input = ""
+ call s:test_windows('setl breakindent list listchars=tab:<-> showbreak=+++')
+ call setline(1, "\t" . repeat('a', 63))
+ vert resize 30
+ norm! 1gg$
+ redraw!
+ let lines = s:screen_lines(1, 30)
+ let expect = [
+ \ "<-->aaaaaaaaaaaaaaaaaaaaaaaaaa",
+ \ " +++aaaaaaaaaaaaaaaaaaaaaaa",
+ \ " +++aaaaaaaaaaaaaa ",
+ \ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows('set breakindent& list& listchars& showbreak&')
+endfunc
+
+func Test_breakindent18_vartabs()
+ if !has("vartabs")
+ return
+ endif
+ let s:input = ""
+ call s:test_windows('setl breakindent list listchars=tab:<->')
+ call setline(1, "\t" . repeat('a', 63))
+ vert resize 30
+ norm! 1gg$
+ redraw!
+ let lines = s:screen_lines(1, 30)
+ let expect = [
+ \ "<-->aaaaaaaaaaaaaaaaaaaaaaaaaa",
+ \ " aaaaaaaaaaaaaaaaaaaaaaaaaa",
+ \ " aaaaaaaaaaa ",
+ \ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows('set breakindent& list& listchars&')
+endfunc
+
+func Test_breakindent19_sbr_nextpage()
+ let s:input = ""
+ call s:test_windows('setl breakindent briopt=shift:2,sbr,min:18 sbr=>')
+ call setline(1, repeat('a', 200))
+ norm! 1gg
+ redraw!
+ let lines = s:screen_lines(1, 20)
+ let expect = [
+ \ "aaaaaaaaaaaaaaaaaaaa",
+ \ "> aaaaaaaaaaaaaaaaaa",
+ \ "> aaaaaaaaaaaaaaaaaa",
+ \ ]
+ call s:compare_lines(expect, lines)
+ " Scroll down one screen line
+ setl scrolloff=5
+ norm! 5gj
+ redraw!
+ let lines = s:screen_lines(1, 20)
+ let expect = [
+ \ "> aaaaaaaaaaaaaaaaaa",
+ \ "> aaaaaaaaaaaaaaaaaa",
+ \ "> aaaaaaaaaaaaaaaaaa",
+ \ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows('set breakindent& briopt& sbr&')
+endfunc
diff --git a/src/nvim/testdir/test_listlbr.vim b/src/nvim/testdir/test_listlbr.vim
index d28dbc444c..cdc5e4cc7c 100644
--- a/src/nvim/testdir/test_listlbr.vim
+++ b/src/nvim/testdir/test_listlbr.vim
@@ -103,6 +103,37 @@ func Test_linebreak_with_conceal()
call s:close_windows()
endfunc
+func Test_linebreak_with_visual_operations()
+ call s:test_windows()
+ let line = '1234567890 2234567890 3234567890'
+ call setline(1, line)
+
+ " yank
+ exec "norm! ^w\<C-V>ey"
+ call assert_equal('2234567890', @@)
+ exec "norm! w\<C-V>ey"
+ call assert_equal('3234567890', @@)
+
+ " increment / decrement
+ exec "norm! ^w\<C-V>\<C-A>w\<C-V>\<C-X>"
+ call assert_equal('1234567890 3234567890 2234567890', getline(1))
+
+ " replace
+ exec "norm! ^w\<C-V>3lraw\<C-V>3lrb"
+ call assert_equal('1234567890 aaaa567890 bbbb567890', getline(1))
+
+ " tilde
+ exec "norm! ^w\<C-V>2l~w\<C-V>2l~"
+ call assert_equal('1234567890 AAAa567890 BBBb567890', getline(1))
+
+ " delete and insert
+ exec "norm! ^w\<C-V>3lc2345\<Esc>w\<C-V>3lc3456\<Esc>"
+ call assert_equal('1234567890 2345567890 3456567890', getline(1))
+ call assert_equal('BBBb', @@)
+
+ call s:close_windows()
+endfunc
+
func Test_virtual_block()
call s:test_windows('setl sbr=+')
call setline(1, [
diff --git a/test/functional/ex_cmds/mksession_spec.lua b/test/functional/ex_cmds/mksession_spec.lua
index 0f7860740e..855f8105aa 100644
--- a/test/functional/ex_cmds/mksession_spec.lua
+++ b/test/functional/ex_cmds/mksession_spec.lua
@@ -6,6 +6,8 @@ local command = helpers.command
local get_pathsep = helpers.get_pathsep
local eq = helpers.eq
local funcs = helpers.funcs
+local matches = helpers.matches
+local pesc = helpers.pesc
local rmdir = helpers.rmdir
local file_prefix = 'Xtest-functional-ex_cmds-mksession_spec'
@@ -48,7 +50,7 @@ describe(':mksession', function()
eq(cwd_dir .. get_pathsep() .. tab_dir, funcs.getcwd())
end)
- it('restores buffers when using tab-local working directories', function()
+ it('restores buffers with tab-local CWD', function()
local tmpfile_base = file_prefix .. '-tmpfile'
local cwd_dir = funcs.getcwd()
local session_path = cwd_dir .. get_pathsep() .. session_file
@@ -70,4 +72,23 @@ describe(':mksession', function()
command('tabnext 2')
eq(cwd_dir .. get_pathsep() .. tmpfile_base .. '2', funcs.expand('%:p'))
end)
+
+ it('restores CWD for :terminal buffers #11288', function()
+ local cwd_dir = funcs.fnamemodify('.', ':p:~'):gsub([[[\/]*$]], '')
+ local session_path = cwd_dir..get_pathsep()..session_file
+
+ command('cd '..tab_dir)
+ command('terminal echo $PWD')
+ command('cd '..cwd_dir)
+ command('mksession '..session_path)
+ command('qall!')
+
+ -- Create a new test instance of Nvim.
+ clear()
+ command('silent source '..session_path)
+
+ local expected_cwd = cwd_dir..get_pathsep()..tab_dir
+ matches('^term://'..pesc(expected_cwd)..'//%d+:', funcs.expand('%'))
+ command('qall!')
+ end)
end)
diff --git a/test/functional/terminal/edit_spec.lua b/test/functional/terminal/edit_spec.lua
index d213bae7b3..fabc5524ed 100644
--- a/test/functional/terminal/edit_spec.lua
+++ b/test/functional/terminal/edit_spec.lua
@@ -5,9 +5,12 @@ local curbufmeths = helpers.curbufmeths
local curwinmeths = helpers.curwinmeths
local nvim_dir = helpers.nvim_dir
local command = helpers.command
+local funcs = helpers.funcs
local meths = helpers.meths
local clear = helpers.clear
local eq = helpers.eq
+local matches = helpers.matches
+local pesc = helpers.pesc
describe(':edit term://*', function()
local get_screen = function(columns, lines)
@@ -28,7 +31,8 @@ describe(':edit term://*', function()
command('edit term://')
local termopen_runs = meths.get_var('termopen_runs')
eq(1, #termopen_runs)
- eq(termopen_runs[1], termopen_runs[1]:match('^term://.//%d+:$'))
+ local cwd = funcs.fnamemodify('.', ':p:~'):gsub([[[\/]*$]], '')
+ matches('^term://'..pesc(cwd)..'//%d+:$', termopen_runs[1])
end)
it("runs TermOpen early enough to set buffer-local 'scrollback'", function()