From cccb21df3b4c6fe0aaa99743c418aa973aeebad0 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 04:10:59 +0200 Subject: Merging upstream version 2:9.1.0374. Signed-off-by: Daniel Baumann --- src/edit.c | 95 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 57 insertions(+), 38 deletions(-) (limited to 'src/edit.c') diff --git a/src/edit.c b/src/edit.c index 69ec255..075b39b 100644 --- a/src/edit.c +++ b/src/edit.c @@ -845,9 +845,10 @@ doESCkey: did_cursorhold = FALSE; // ins_redraw() triggers TextChangedI only when no characters - // are in the typeahead buffer, so only reset curbuf->b_last_changedtick + // are in the typeahead buffer, so reset curbuf->b_last_changedtick only // if the TextChangedI was not blocked by char_avail() (e.g. using :norm!) - if (!char_avail()) + // and the TextChangedI autocommand has been triggered. + if (!char_avail() && curbuf->b_last_changedtick_i == CHANGEDTICK(curbuf)) curbuf->b_last_changedtick = CHANGEDTICK(curbuf); return (c == Ctrl_O); } @@ -3958,10 +3959,9 @@ ins_del(void) * Delete one character for ins_bs(). */ static void -ins_bs_one(colnr_T *vcolp) +ins_bs_one(void) { dec_cursor(); - getvcol(curwin, &curwin->w_cursor, vcolp, NULL, NULL); if (State & REPLACE_FLAG) { // Don't delete characters before the insert point when in @@ -4211,44 +4211,69 @@ ins_bs( && (!*inserted_space_p || arrow_used)))))) { - int ts; - colnr_T vcol; + colnr_T vcol = 0; colnr_T want_vcol; - colnr_T start_vcol; + char_u *line; + char_u *ptr; + char_u *cursor_ptr; + char_u *space_ptr; + colnr_T space_vcol = 0; + int prev_space = FALSE; + colnr_T want_col; *inserted_space_p = FALSE; - // Compute the virtual column where we want to be. Since - // 'showbreak' may get in the way, need to get the last column of - // the previous character. - getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL); - start_vcol = vcol; - dec_cursor(); - getvcol(curwin, &curwin->w_cursor, NULL, NULL, &want_vcol); - inc_cursor(); -#ifdef FEAT_VARTABS - if (p_sta && in_indent) + + space_ptr = ptr = line = ml_get_curline(); + cursor_ptr = line + curwin->w_cursor.col; + + // Compute virtual column of cursor position, and find the last + // whitespace before cursor that is preceded by non-whitespace. + // Use chartabsize() so that virtual text and wrapping are ignored. + while (ptr < cursor_ptr) { - ts = (int)get_sw_value(curbuf); - want_vcol = (want_vcol / ts) * ts; + int cur_space = VIM_ISWHITE(*ptr); + + if (!prev_space && cur_space) + { + space_ptr = ptr; + space_vcol = vcol; + } + vcol += chartabsize(ptr, vcol); + MB_PTR_ADV(ptr); + prev_space = cur_space; } + + // Compute the virtual column where we want to be. + want_vcol = vcol > 0 ? vcol - 1 : 0; + if (p_sta && in_indent) + want_vcol -= want_vcol % (int)get_sw_value(curbuf); else +#ifdef FEAT_VARTABS want_vcol = tabstop_start(want_vcol, get_sts_value(), curbuf->b_p_vsts_array); #else - if (p_sta && in_indent) - ts = (int)get_sw_value(curbuf); - else - ts = (int)get_sts_value(); - want_vcol = (want_vcol / ts) * ts; + want_vcol -= want_vcol % (int)get_sts_value(); #endif - // delete characters until we are at or before want_vcol - while (vcol > want_vcol && curwin->w_cursor.col > 0 - && (cc = *(ml_get_cursor() - 1), VIM_ISWHITE(cc))) - ins_bs_one(&vcol); + // Find the position to stop backspacing. + // Use chartabsize() so that virtual text and wrapping are ignored. + while (TRUE) + { + int size = chartabsize(space_ptr, space_vcol); - // insert extra spaces until we are at want_vcol - while (vcol < want_vcol) + if (space_vcol + size > want_vcol) + break; + space_vcol += size; + MB_PTR_ADV(space_ptr); + } + want_col = space_ptr - line; + + // Delete characters until we are at or before want_col. + while (curwin->w_cursor.col > want_col) + ins_bs_one(); + + // Insert extra spaces until we are at want_vcol. + for (; space_vcol < want_vcol; space_vcol++) { // Remember the first char we inserted if (curwin->w_cursor.lnum == Insstart_orig.lnum @@ -4263,13 +4288,7 @@ ins_bs( if ((State & REPLACE_FLAG)) replace_push(NUL); } - getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL); } - - // If we are now back where we started delete one character. Can - // happen when using 'sts' and 'linebreak'. - if (vcol >= start_vcol) - ins_bs_one(&vcol); } /* @@ -4783,7 +4802,7 @@ ins_pageup(void) } tpos = curwin->w_cursor; - if (onepage(BACKWARD, 1L) == OK) + if (pagescroll(BACKWARD, 1L, FALSE) == OK) { start_arrow(&tpos); can_cindent = TRUE; @@ -4840,7 +4859,7 @@ ins_pagedown(void) } tpos = curwin->w_cursor; - if (onepage(FORWARD, 1L) == OK) + if (pagescroll(FORWARD, 1L, FALSE) == OK) { start_arrow(&tpos); can_cindent = TRUE; -- cgit v1.2.3