aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-08-31 08:35:08 +0800
committerGitHub <noreply@github.com>2023-08-31 08:35:08 +0800
commit839d919098ed2cf3dfb93b6337a3d2ea2bd210a0 (patch)
tree3095a377dcdcf8a50f71d4cf5d9aa98d5412d776 /src
parent5d49542b561e7f4826e28f7a0aeca94d47b3e0b7 (diff)
downloadrneovim-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.c95
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;
}