diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-08-31 08:35:08 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-31 08:35:08 +0800 |
commit | 839d919098ed2cf3dfb93b6337a3d2ea2bd210a0 (patch) | |
tree | 3095a377dcdcf8a50f71d4cf5d9aa98d5412d776 /src | |
parent | 5d49542b561e7f4826e28f7a0aeca94d47b3e0b7 (diff) | |
download | rneovim-839d919098ed2cf3dfb93b6337a3d2ea2bd210a0.tar.gz rneovim-839d919098ed2cf3dfb93b6337a3d2ea2bd210a0.tar.bz2 rneovim-839d919098ed2cf3dfb93b6337a3d2ea2bd210a0.zip |
vim-patch:9.0.1825: wrong cursor position with virt text and 'linebreak' (#24957)
Problem: Wrong cursor position with virtual text before a whitespace
character and 'linebreak'.
Solution: Always set "col_adj" to "size - 1" and apply 'linebreak' after
adding the size of 'breakindent' and 'showbreak'.
closes: vim/vim#12956
https://github.com/vim/vim/commit/6e55e85f92aff43c1b3cb564201440f3552d63f0
N/A patches:
vim-patch:9.0.1826: keytrans() doesn't translate recorded key typed in a GUI
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/plines.c | 95 |
1 files changed, 44 insertions, 51 deletions
diff --git a/src/nvim/plines.c b/src/nvim/plines.c index e18e774a72..f59a1754f5 100644 --- a/src/nvim/plines.c +++ b/src/nvim/plines.c @@ -195,8 +195,6 @@ int win_lbr_chartabsize(chartabsize_T *cts, int *headp) char *line = cts->cts_line; // start of the line char *s = cts->cts_ptr; colnr_T vcol = cts->cts_vcol; - - colnr_T col_adj = 0; // vcol + screen size of tab int mb_added = 0; cts->cts_cur_text_width_left = 0; @@ -249,54 +247,8 @@ int win_lbr_chartabsize(chartabsize_T *cts, int *headp) } } - int c = (uint8_t)(*s); - if (*s == TAB) { - col_adj = size - 1; - } - - // If 'linebreak' set check at a blank before a non-blank if the line - // needs a break here - if (wp->w_p_lbr - && vim_isbreak(c) - && !vim_isbreak((uint8_t)s[1]) - && wp->w_p_wrap - && (wp->w_width_inner != 0)) { - // Count all characters from first non-blank after a blank up to next - // non-blank after a blank. - int numberextra = win_col_off(wp); - colnr_T col2 = vcol; - colnr_T colmax = (colnr_T)(wp->w_width_inner - numberextra - col_adj); - - if (vcol >= colmax) { - colmax += col_adj; - int n = colmax + win_col_off2(wp); - - if (n > 0) { - colmax += (((vcol - colmax) / n) + 1) * n - col_adj; - } - } - - while (true) { - char *ps = s; - MB_PTR_ADV(s); - c = (uint8_t)(*s); - - if (!(c != NUL - && (vim_isbreak(c) || col2 == vcol || !vim_isbreak((uint8_t)(*ps))))) { - break; - } - - col2 += win_chartabsize(wp, s, col2); - - if (col2 >= colmax) { // doesn't fit - size = colmax - vcol + col_adj; - break; - } - } - } else if ((size == 2) - && (MB_BYTE2LEN((uint8_t)(*s)) > 1) - && wp->w_p_wrap - && in_win_border(wp, vcol)) { + if (size == 2 && MB_BYTE2LEN((uint8_t)(*s)) > 1 + && wp->w_p_wrap && in_win_border(wp, vcol)) { // Count the ">" in the last column. size++; mb_added = 1; @@ -335,6 +287,8 @@ int win_lbr_chartabsize(chartabsize_T *cts, int *headp) if (max_head_vcol <= 0 || vcol < max_head_vcol) { head += head_prev; } + } else { + head_prev = 0; } wcol += col_off_prev; } @@ -366,7 +320,7 @@ int win_lbr_chartabsize(chartabsize_T *cts, int *headp) head += (max_head_vcol - (vcol + head_prev + prev_rem) + width2 - 1) / width2 * head_mid; } else if (max_head_vcol < 0) { - int off = virt_text_cursor_off(cts, c == NUL); + int off = virt_text_cursor_off(cts, *s == NUL); if (off >= prev_rem) { if (size > off) { head += (1 + (off - prev_rem) / width) * head_mid; @@ -384,6 +338,45 @@ int win_lbr_chartabsize(chartabsize_T *cts, int *headp) if (headp != NULL) { *headp = head; } + + // If 'linebreak' set check at a blank before a non-blank if the line + // needs a break here + if (wp->w_p_lbr + && vim_isbreak((uint8_t)s[0]) + && !vim_isbreak((uint8_t)s[1]) + && wp->w_p_wrap + && wp->w_width_inner != 0) { + // Count all characters from first non-blank after a blank up to next + // non-blank after a blank. + int numberextra = win_col_off(wp); + colnr_T col_adj = size - 1; + colnr_T colmax = (colnr_T)(wp->w_width_inner - numberextra - col_adj); + if (vcol >= colmax) { + colmax += col_adj; + int n = colmax + win_col_off2(wp); + if (n > 0) { + colmax += (((vcol - colmax) / n) + 1) * n - col_adj; + } + } + + colnr_T vcol2 = vcol; + while (true) { + char *ps = s; + MB_PTR_ADV(s); + int c = (uint8_t)(*s); + if (!(c != NUL + && (vim_isbreak(c) || vcol2 == vcol || !vim_isbreak((uint8_t)(*ps))))) { + break; + } + + vcol2 += win_chartabsize(wp, s, vcol2); + if (vcol2 >= colmax) { // doesn't fit + size = colmax - vcol + col_adj; + break; + } + } + } + return size; } |