aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/change.c
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2024-09-04 12:09:42 +0200
committerbfredl <bjorn.linse@gmail.com>2024-09-06 10:22:29 +0200
commitfa99afe35eb5d8cf01d875e12b53165bf1104a60 (patch)
tree2a304fcd0262e71ef64d2bbb91fcbdc5eb89507d /src/nvim/change.c
parent7b7c95dac97d6ea4f10855cc198dce650a796c20 (diff)
downloadrneovim-fa99afe35eb5d8cf01d875e12b53165bf1104a60.tar.gz
rneovim-fa99afe35eb5d8cf01d875e12b53165bf1104a60.tar.bz2
rneovim-fa99afe35eb5d8cf01d875e12b53165bf1104a60.zip
fix(multibyte): handle backspace of wide clusters in replace mode
Make utf_head_off more robust against invalid sequences and embedded NUL chars
Diffstat (limited to 'src/nvim/change.c')
-rw-r--r--src/nvim/change.c22
1 files changed, 9 insertions, 13 deletions
diff --git a/src/nvim/change.c b/src/nvim/change.c
index 47a9f0ce92..51a13b80e7 100644
--- a/src/nvim/change.c
+++ b/src/nvim/change.c
@@ -756,10 +756,8 @@ void ins_char_bytes(char *buf, size_t charlen)
// put back when BS is used. The bytes of a multi-byte character are
// done the other way around, so that the first byte is popped off
// first (it tells the byte length of the character).
- replace_push(NUL);
- for (size_t i = 0; i < oldlen; i++) {
- i += (size_t)replace_push_mb(oldp + col + i) - 1;
- }
+ replace_push_nul();
+ replace_push(oldp + col, oldlen);
}
char *newp = xmalloc(linelen + newlen - oldlen);
@@ -1137,12 +1135,10 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
// on the line onto the replace stack. We'll push any other characters
// that might be replaced at the start of the next line (due to
// autoindent etc) a bit later.
- replace_push(NUL); // Call twice because BS over NL expects it
- replace_push(NUL);
+ replace_push_nul(); // Call twice because BS over NL expects it
+ replace_push_nul();
p = saved_line + curwin->w_cursor.col;
- while (*p != NUL) {
- p += replace_push_mb(p);
- }
+ replace_push(p, strlen(p));
saved_line[curwin->w_cursor.col] = NUL;
}
@@ -1691,13 +1687,13 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
// stack, preceded by a NUL, so they can be put back when a BS is
// entered.
if (REPLACE_NORMAL(State)) {
- replace_push(NUL); // end of extra blanks
+ replace_push_nul(); // end of extra blanks
}
if (curbuf->b_p_ai || (flags & OPENLINE_DELSPACES)) {
while ((*p_extra == ' ' || *p_extra == '\t')
&& !utf_iscomposing_first(utf_ptr2char(p_extra + 1))) {
if (REPLACE_NORMAL(State)) {
- replace_push(*p_extra);
+ replace_push(p_extra, 1); // always ascii, len = 1
}
p_extra++;
less_cols_off++;
@@ -1794,7 +1790,7 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
// must be a NUL on the replace stack, for when it is deleted with BS
if (REPLACE_NORMAL(State)) {
for (colnr_T n = 0; n < curwin->w_cursor.col; n++) {
- replace_push(NUL);
+ replace_push_nul();
}
}
newcol += curwin->w_cursor.col;
@@ -1808,7 +1804,7 @@ bool open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
// must be a NUL on the replace stack, for when it is deleted with BS.
if (REPLACE_NORMAL(State)) {
while (lead_len-- > 0) {
- replace_push(NUL);
+ replace_push_nul();
}
}