aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/charset.c
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2022-08-27 11:28:11 +0200
committerbfredl <bjorn.linse@gmail.com>2022-08-29 12:05:34 +0200
commitea4e9c71ccaf406fe7aa6b47d461cdab2d6c01e9 (patch)
treed8c14449741cdfcbf3fcb65d518a7ee0a15a70bb /src/nvim/charset.c
parent7a9b5937966d3db852c84b8eb232e77d92d3c355 (diff)
downloadrneovim-ea4e9c71ccaf406fe7aa6b47d461cdab2d6c01e9.tar.gz
rneovim-ea4e9c71ccaf406fe7aa6b47d461cdab2d6c01e9.tar.bz2
rneovim-ea4e9c71ccaf406fe7aa6b47d461cdab2d6c01e9.zip
refactor(plines): use a struct for chartabsize state
This is a refactor extracted from vim-patch 9.0.0067: cannot show virtual text The logic for inline virtual text is going to be different in nvim than text property based text in vim, but this refactor is still useful, as calculation of displayed linesize is going to be stateful in a similar way.
Diffstat (limited to 'src/nvim/charset.c')
-rw-r--r--src/nvim/charset.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index dc62b85716..3632c3d70b 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -930,14 +930,18 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en
posptr -= utf_head_off(line, posptr);
}
+ chartabsize_T cts;
+ init_chartabsize_arg(&cts, wp, pos->lnum, 0, line, line);
+
// This function is used very often, do some speed optimizations.
// When 'list', 'linebreak', 'showbreak' and 'breakindent' are not set
- // use a simple loop.
+ // and there are no virtual text use a simple loop.
// Also use this when 'list' is set but tabs take their normal size.
if ((!wp->w_p_list || (wp->w_p_lcs_chars.tab1 != NUL))
&& !wp->w_p_lbr
&& *get_showbreak_value(wp) == NUL
- && !wp->w_p_bri) {
+ && !wp->w_p_bri
+ && !cts.cts_has_virt_text) {
for (;;) {
head = 0;
int c = *ptr;
@@ -984,25 +988,29 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en
} else {
for (;;) {
// A tab gets expanded, depending on the current column
+ // Other things also take up space.
head = 0;
- incr = win_lbr_chartabsize(wp, line, ptr, vcol, &head);
+ incr = win_lbr_chartabsize(&cts, &head);
// make sure we don't go past the end of the line
- if (*ptr == NUL) {
+ if (*cts.cts_ptr == NUL) {
// NUL at end of line only takes one column
incr = 1;
break;
}
- if ((posptr != NULL) && (ptr >= posptr)) {
+ if ((posptr != NULL) && ((char_u *)cts.cts_ptr >= posptr)) {
// character at pos->col
break;
}
- vcol += incr;
- MB_PTR_ADV(ptr);
+ cts.cts_vcol += incr;
+ MB_PTR_ADV(cts.cts_ptr);
}
+ vcol = cts.cts_vcol;
+ ptr = (char_u *)cts.cts_ptr;
}
+ clear_chartabsize_arg(&cts);
if (start != NULL) {
*start = vcol + head;
@@ -1013,6 +1021,8 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en
}
if (cursor != NULL) {
+ // cursor is after inserted text
+ vcol += cts.cts_cur_text_width;
if ((*ptr == TAB)
&& (State & MODE_NORMAL)
&& !wp->w_p_list