mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #19975 from bfredl/chartabsize
refactor(plines): use a struct for chartabsize state
This commit is contained in:
commit
f05cc672e3
@ -653,9 +653,9 @@ void ins_char_bytes(char_u *buf, size_t charlen)
|
|||||||
// cells. May result in adding spaces to fill a gap.
|
// cells. May result in adding spaces to fill a gap.
|
||||||
colnr_T vcol;
|
colnr_T vcol;
|
||||||
getvcol(curwin, &curwin->w_cursor, NULL, &vcol, NULL);
|
getvcol(curwin, &curwin->w_cursor, NULL, &vcol, NULL);
|
||||||
colnr_T new_vcol = vcol + win_chartabsize(curwin, buf, vcol);
|
colnr_T new_vcol = vcol + win_chartabsize(curwin, (char *)buf, vcol);
|
||||||
while (oldp[col + oldlen] != NUL && vcol < new_vcol) {
|
while (oldp[col + oldlen] != NUL && vcol < new_vcol) {
|
||||||
vcol += win_chartabsize(curwin, oldp + col + oldlen, vcol);
|
vcol += win_chartabsize(curwin, (char *)oldp + col + oldlen, vcol);
|
||||||
// Don't need to remove a TAB that takes us to the right
|
// Don't need to remove a TAB that takes us to the right
|
||||||
// position.
|
// position.
|
||||||
if (vcol > new_vcol && oldp[col + oldlen] == TAB) {
|
if (vcol > new_vcol && oldp[col + oldlen] == TAB) {
|
||||||
|
@ -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);
|
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.
|
// This function is used very often, do some speed optimizations.
|
||||||
// When 'list', 'linebreak', 'showbreak' and 'breakindent' are not set
|
// 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.
|
// 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))
|
if ((!wp->w_p_list || (wp->w_p_lcs_chars.tab1 != NUL))
|
||||||
&& !wp->w_p_lbr
|
&& !wp->w_p_lbr
|
||||||
&& *get_showbreak_value(wp) == NUL
|
&& *get_showbreak_value(wp) == NUL
|
||||||
&& !wp->w_p_bri) {
|
&& !wp->w_p_bri
|
||||||
|
&& !cts.cts_has_virt_text) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
head = 0;
|
head = 0;
|
||||||
int c = *ptr;
|
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 {
|
} else {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// A tab gets expanded, depending on the current column
|
// A tab gets expanded, depending on the current column
|
||||||
|
// Other things also take up space.
|
||||||
head = 0;
|
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
|
// 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
|
// NUL at end of line only takes one column
|
||||||
incr = 1;
|
incr = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((posptr != NULL) && (ptr >= posptr)) {
|
if ((posptr != NULL) && ((char_u *)cts.cts_ptr >= posptr)) {
|
||||||
// character at pos->col
|
// character at pos->col
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
vcol += incr;
|
cts.cts_vcol += incr;
|
||||||
MB_PTR_ADV(ptr);
|
MB_PTR_ADV(cts.cts_ptr);
|
||||||
}
|
}
|
||||||
|
vcol = cts.cts_vcol;
|
||||||
|
ptr = (char_u *)cts.cts_ptr;
|
||||||
}
|
}
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
|
|
||||||
if (start != NULL) {
|
if (start != NULL) {
|
||||||
*start = vcol + head;
|
*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) {
|
if (cursor != NULL) {
|
||||||
|
// cursor is after inserted text
|
||||||
|
vcol += cts.cts_cur_text_width;
|
||||||
if ((*ptr == TAB)
|
if ((*ptr == TAB)
|
||||||
&& (State & MODE_NORMAL)
|
&& (State & MODE_NORMAL)
|
||||||
&& !wp->w_p_list
|
&& !wp->w_p_list
|
||||||
|
@ -137,14 +137,18 @@ static int coladvance2(pos_T *pos, bool addspaces, bool finetune, colnr_T wcol_a
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char_u *ptr = line;
|
chartabsize_T cts;
|
||||||
while (col <= wcol && *ptr != NUL) {
|
init_chartabsize_arg(&cts, curwin, pos->lnum, 0, line, line);
|
||||||
|
while (cts.cts_vcol <= wcol && *cts.cts_ptr != NUL) {
|
||||||
// Count a tab for what it's worth (if list mode not on)
|
// Count a tab for what it's worth (if list mode not on)
|
||||||
csize = win_lbr_chartabsize(curwin, line, ptr, col, &head);
|
csize = win_lbr_chartabsize(&cts, &head);
|
||||||
MB_PTR_ADV(ptr);
|
MB_PTR_ADV(cts.cts_ptr);
|
||||||
col += csize;
|
cts.cts_vcol += csize;
|
||||||
}
|
}
|
||||||
idx = (int)(ptr - line);
|
col = cts.cts_vcol;
|
||||||
|
idx = (int)(cts.cts_ptr - (char *)line);
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
|
|
||||||
// Handle all the special cases. The virtual_active() check
|
// Handle all the special cases. The virtual_active() check
|
||||||
// is needed to ensure that a virtual position off the end of
|
// is needed to ensure that a virtual position off the end of
|
||||||
// a line has the correct indexing. The one_more comparison
|
// a line has the correct indexing. The one_more comparison
|
||||||
|
@ -940,12 +940,19 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
|
|||||||
}
|
}
|
||||||
if (v > 0 && !number_only) {
|
if (v > 0 && !number_only) {
|
||||||
char_u *prev_ptr = ptr;
|
char_u *prev_ptr = ptr;
|
||||||
while (vcol < v && *ptr != NUL) {
|
chartabsize_T cts;
|
||||||
c = win_lbr_chartabsize(wp, line, ptr, (colnr_T)vcol, NULL);
|
int charsize;
|
||||||
vcol += c;
|
|
||||||
prev_ptr = ptr;
|
init_chartabsize_arg(&cts, wp, lnum, (colnr_T)vcol, line, ptr);
|
||||||
MB_PTR_ADV(ptr);
|
while (cts.cts_vcol < v && *cts.cts_ptr != NUL) {
|
||||||
|
charsize = win_lbr_chartabsize(&cts, NULL);
|
||||||
|
cts.cts_vcol += charsize;
|
||||||
|
prev_ptr = (char_u *)cts.cts_ptr;
|
||||||
|
MB_PTR_ADV(cts.cts_ptr);
|
||||||
}
|
}
|
||||||
|
vcol = cts.cts_vcol;
|
||||||
|
ptr = (char_u *)cts.cts_ptr;
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
|
|
||||||
// When:
|
// When:
|
||||||
// - 'cuc' is set, or
|
// - 'cuc' is set, or
|
||||||
@ -963,11 +970,11 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
|
|||||||
// Handle a character that's not completely on the screen: Put ptr at
|
// Handle a character that's not completely on the screen: Put ptr at
|
||||||
// that character but skip the first few screen characters.
|
// that character but skip the first few screen characters.
|
||||||
if (vcol > v) {
|
if (vcol > v) {
|
||||||
vcol -= c;
|
vcol -= charsize;
|
||||||
ptr = prev_ptr;
|
ptr = prev_ptr;
|
||||||
// If the character fits on the screen, don't need to skip it.
|
// If the character fits on the screen, don't need to skip it.
|
||||||
// Except for a TAB.
|
// Except for a TAB.
|
||||||
if (utf_ptr2cells((char *)ptr) >= c || *ptr == TAB) {
|
if (utf_ptr2cells((char *)ptr) >= charsize || *ptr == TAB) {
|
||||||
n_skip = (int)(v - vcol);
|
n_skip = (int)(v - vcol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1798,8 +1805,10 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
|
|||||||
&& !vim_isbreak((int)(*ptr))) {
|
&& !vim_isbreak((int)(*ptr))) {
|
||||||
int mb_off = utf_head_off(line, ptr - 1);
|
int mb_off = utf_head_off(line, ptr - 1);
|
||||||
char_u *p = ptr - (mb_off + 1);
|
char_u *p = ptr - (mb_off + 1);
|
||||||
// TODO(neovim): is passing p for start of the line OK?
|
chartabsize_T cts;
|
||||||
n_extra = win_lbr_chartabsize(wp, line, p, (colnr_T)vcol, NULL) - 1;
|
|
||||||
|
init_chartabsize_arg(&cts, wp, lnum, (colnr_T)vcol, line, p);
|
||||||
|
n_extra = win_lbr_chartabsize(&cts, NULL) - 1;
|
||||||
|
|
||||||
// We have just drawn the showbreak value, no need to add
|
// We have just drawn the showbreak value, no need to add
|
||||||
// space for it again.
|
// space for it again.
|
||||||
@ -1825,6 +1834,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
|
|||||||
c = ' ';
|
c = ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
}
|
}
|
||||||
|
|
||||||
in_multispace = c == ' ' && ((ptr > line + 1 && ptr[-2] == ' ') || *ptr == ' ');
|
in_multispace = c == ' ' && ((ptr > line + 1 && ptr[-2] == ' ') || *ptr == ' ');
|
||||||
|
@ -1665,28 +1665,28 @@ void change_indent(int type, int amount, int round, int replaced, int call_chang
|
|||||||
} else if (!(State & MODE_INSERT)) {
|
} else if (!(State & MODE_INSERT)) {
|
||||||
new_cursor_col = curwin->w_cursor.col;
|
new_cursor_col = curwin->w_cursor.col;
|
||||||
} else {
|
} else {
|
||||||
/*
|
// Compute the screen column where the cursor should be.
|
||||||
* Compute the screen column where the cursor should be.
|
|
||||||
*/
|
|
||||||
vcol = get_indent() - vcol;
|
vcol = get_indent() - vcol;
|
||||||
curwin->w_virtcol = (colnr_T)((vcol < 0) ? 0 : vcol);
|
curwin->w_virtcol = (colnr_T)((vcol < 0) ? 0 : vcol);
|
||||||
|
|
||||||
/*
|
// Advance the cursor until we reach the right screen column.
|
||||||
* Advance the cursor until we reach the right screen column.
|
last_vcol = 0;
|
||||||
*/
|
|
||||||
vcol = last_vcol = 0;
|
|
||||||
new_cursor_col = -1;
|
|
||||||
ptr = get_cursor_line_ptr();
|
ptr = get_cursor_line_ptr();
|
||||||
while (vcol <= (int)curwin->w_virtcol) {
|
chartabsize_T cts;
|
||||||
last_vcol = vcol;
|
init_chartabsize_arg(&cts, curwin, 0, 0, ptr, ptr);
|
||||||
if (new_cursor_col >= 0) {
|
while (cts.cts_vcol <= (int)curwin->w_virtcol) {
|
||||||
new_cursor_col += utfc_ptr2len((char *)ptr + new_cursor_col);
|
last_vcol = cts.cts_vcol;
|
||||||
} else {
|
if (cts.cts_vcol > 0) {
|
||||||
new_cursor_col++;
|
MB_PTR_ADV(cts.cts_ptr);
|
||||||
}
|
}
|
||||||
vcol += lbr_chartabsize(ptr, ptr + new_cursor_col, (colnr_T)vcol);
|
if (*cts.cts_ptr == NUL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cts.cts_vcol += lbr_chartabsize(&cts);
|
||||||
}
|
}
|
||||||
vcol = last_vcol;
|
vcol = last_vcol;
|
||||||
|
new_cursor_col = (int)(cts.cts_ptr - cts.cts_line);
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* May need to insert spaces to be able to position the cursor on
|
* May need to insert spaces to be able to position the cursor on
|
||||||
@ -2991,7 +2991,7 @@ static void replace_do_bs(int limit_col)
|
|||||||
// Get the number of screen cells used by the character we are
|
// Get the number of screen cells used by the character we are
|
||||||
// going to delete.
|
// going to delete.
|
||||||
getvcol(curwin, &curwin->w_cursor, NULL, &start_vcol, NULL);
|
getvcol(curwin, &curwin->w_cursor, NULL, &start_vcol, NULL);
|
||||||
orig_vcols = win_chartabsize(curwin, get_cursor_pos_ptr(), start_vcol);
|
orig_vcols = win_chartabsize(curwin, (char *)get_cursor_pos_ptr(), start_vcol);
|
||||||
}
|
}
|
||||||
(void)del_char_after_col(limit_col);
|
(void)del_char_after_col(limit_col);
|
||||||
if (l_State & VREPLACE_FLAG) {
|
if (l_State & VREPLACE_FLAG) {
|
||||||
@ -3006,7 +3006,7 @@ static void replace_do_bs(int limit_col)
|
|||||||
ins_len = (int)STRLEN(p) - orig_len;
|
ins_len = (int)STRLEN(p) - orig_len;
|
||||||
vcol = start_vcol;
|
vcol = start_vcol;
|
||||||
for (i = 0; i < ins_len; i++) {
|
for (i = 0; i < ins_len; i++) {
|
||||||
vcol += win_chartabsize(curwin, p + i, vcol);
|
vcol += win_chartabsize(curwin, (char *)p + i, vcol);
|
||||||
i += utfc_ptr2len((char *)p) - 1;
|
i += utfc_ptr2len((char *)p) - 1;
|
||||||
}
|
}
|
||||||
vcol -= start_vcol;
|
vcol -= start_vcol;
|
||||||
@ -4644,11 +4644,15 @@ static bool ins_tab(void)
|
|||||||
getvcol(curwin, &fpos, &vcol, NULL, NULL);
|
getvcol(curwin, &fpos, &vcol, NULL, NULL);
|
||||||
getvcol(curwin, cursor, &want_vcol, NULL, NULL);
|
getvcol(curwin, cursor, &want_vcol, NULL, NULL);
|
||||||
|
|
||||||
|
char_u *tab = (char_u *)"\t";
|
||||||
|
chartabsize_T cts;
|
||||||
|
init_chartabsize_arg(&cts, curwin, 0, vcol, tab, tab);
|
||||||
|
|
||||||
// Use as many TABs as possible. Beware of 'breakindent', 'showbreak'
|
// Use as many TABs as possible. Beware of 'breakindent', 'showbreak'
|
||||||
// and 'linebreak' adding extra virtual columns.
|
// and 'linebreak' adding extra virtual columns.
|
||||||
while (ascii_iswhite(*ptr)) {
|
while (ascii_iswhite(*ptr)) {
|
||||||
i = lbr_chartabsize(NULL, (char_u *)"\t", vcol);
|
i = lbr_chartabsize(&cts);
|
||||||
if (vcol + i > want_vcol) {
|
if (cts.cts_vcol + i > want_vcol) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (*ptr != TAB) {
|
if (*ptr != TAB) {
|
||||||
@ -4663,19 +4667,24 @@ static bool ins_tab(void)
|
|||||||
}
|
}
|
||||||
fpos.col++;
|
fpos.col++;
|
||||||
ptr++;
|
ptr++;
|
||||||
vcol += i;
|
cts.cts_vcol += i;
|
||||||
}
|
}
|
||||||
|
vcol = cts.cts_vcol;
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
|
|
||||||
if (change_col >= 0) {
|
if (change_col >= 0) {
|
||||||
int repl_off = 0;
|
int repl_off = 0;
|
||||||
char_u *line = ptr;
|
|
||||||
|
|
||||||
// Skip over the spaces we need.
|
// Skip over the spaces we need.
|
||||||
while (vcol < want_vcol && *ptr == ' ') {
|
init_chartabsize_arg(&cts, curwin, 0, vcol, ptr, ptr);
|
||||||
vcol += lbr_chartabsize(line, ptr, vcol);
|
while (cts.cts_vcol < want_vcol && *cts.cts_ptr == ' ') {
|
||||||
ptr++;
|
cts.cts_vcol += lbr_chartabsize(&cts);
|
||||||
|
cts.cts_ptr++;
|
||||||
repl_off++;
|
repl_off++;
|
||||||
}
|
}
|
||||||
|
ptr = (char_u *)cts.cts_ptr;
|
||||||
|
vcol = cts.cts_vcol;
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
|
|
||||||
if (vcol > want_vcol) {
|
if (vcol > want_vcol) {
|
||||||
// Must have a char with 'showbreak' just before it.
|
// Must have a char with 'showbreak' just before it.
|
||||||
ptr--;
|
ptr--;
|
||||||
@ -4855,7 +4864,6 @@ static int ins_digraph(void)
|
|||||||
int ins_copychar(linenr_T lnum)
|
int ins_copychar(linenr_T lnum)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
int temp;
|
|
||||||
char_u *ptr, *prev_ptr;
|
char_u *ptr, *prev_ptr;
|
||||||
char_u *line;
|
char_u *line;
|
||||||
|
|
||||||
@ -4865,17 +4873,23 @@ int ins_copychar(linenr_T lnum)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// try to advance to the cursor column
|
// try to advance to the cursor column
|
||||||
temp = 0;
|
line = ml_get(lnum);
|
||||||
line = ptr = ml_get(lnum);
|
prev_ptr = line;
|
||||||
prev_ptr = ptr;
|
|
||||||
validate_virtcol();
|
validate_virtcol();
|
||||||
while ((colnr_T)temp < curwin->w_virtcol && *ptr != NUL) {
|
|
||||||
prev_ptr = ptr;
|
chartabsize_T cts;
|
||||||
temp += lbr_chartabsize_adv(line, &ptr, (colnr_T)temp);
|
init_chartabsize_arg(&cts, curwin, lnum, 0, line, line);
|
||||||
|
while (cts.cts_vcol < curwin->w_virtcol && *cts.cts_ptr != NUL) {
|
||||||
|
prev_ptr = (char_u *)cts.cts_ptr;
|
||||||
|
cts.cts_vcol += lbr_chartabsize_adv(&cts);
|
||||||
}
|
}
|
||||||
if ((colnr_T)temp > curwin->w_virtcol) {
|
|
||||||
|
if (cts.cts_vcol > curwin->w_virtcol) {
|
||||||
ptr = prev_ptr;
|
ptr = prev_ptr;
|
||||||
|
} else {
|
||||||
|
ptr = (char_u *)cts.cts_ptr;
|
||||||
}
|
}
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
|
|
||||||
c = utf_ptr2char((char *)ptr);
|
c = utf_ptr2char((char *)ptr);
|
||||||
if (c == NUL) {
|
if (c == NUL) {
|
||||||
|
@ -849,11 +849,11 @@ static void get_col(typval_T *argvars, typval_T *rettv, bool charcol)
|
|||||||
// col(".") when the cursor is on the NUL at the end of the line
|
// col(".") when the cursor is on the NUL at the end of the line
|
||||||
// because of "coladd" can be seen as an extra column.
|
// because of "coladd" can be seen as an extra column.
|
||||||
if (virtual_active() && fp == &curwin->w_cursor) {
|
if (virtual_active() && fp == &curwin->w_cursor) {
|
||||||
char_u *p = get_cursor_pos_ptr();
|
char *p = (char *)get_cursor_pos_ptr();
|
||||||
if (curwin->w_cursor.coladd >=
|
if (curwin->w_cursor.coladd >=
|
||||||
(colnr_T)win_chartabsize(curwin, p, curwin->w_virtcol - curwin->w_cursor.coladd)) {
|
(colnr_T)win_chartabsize(curwin, p, curwin->w_virtcol - curwin->w_cursor.coladd)) {
|
||||||
int l;
|
int l;
|
||||||
if (*p != NUL && p[(l = utfc_ptr2len((char *)p))] == NUL) {
|
if (*p != NUL && p[(l = utfc_ptr2len(p))] == NUL) {
|
||||||
col += l;
|
col += l;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8537,7 +8537,7 @@ static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv, EvalFuncData f
|
|||||||
col = (int)tv_get_number(&argvars[1]);
|
col = (int)tv_get_number(&argvars[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, (char_u *)s) - col);
|
rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, (char *)s) - col);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "strwidth()" function
|
/// "strwidth()" function
|
||||||
|
@ -841,7 +841,7 @@ void ex_retab(exarg_T *eap)
|
|||||||
if (ptr[col] == NUL) {
|
if (ptr[col] == NUL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
vcol += win_chartabsize(curwin, (char_u *)ptr + col, (colnr_T)vcol);
|
vcol += win_chartabsize(curwin, ptr + col, (colnr_T)vcol);
|
||||||
if (vcol >= MAXCOL) {
|
if (vcol >= MAXCOL) {
|
||||||
emsg(_(e_resulting_text_too_long));
|
emsg(_(e_resulting_text_too_long));
|
||||||
break;
|
break;
|
||||||
|
@ -2547,7 +2547,7 @@ static int vgetorpeek(bool advance)
|
|||||||
&& (State & MODE_INSERT)
|
&& (State & MODE_INSERT)
|
||||||
&& (p_timeout || (keylen == KEYLEN_PART_KEY && p_ttimeout))
|
&& (p_timeout || (keylen == KEYLEN_PART_KEY && p_ttimeout))
|
||||||
&& (c = inchar(typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len, 3, 25L)) == 0) {
|
&& (c = inchar(typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len, 3, 25L)) == 0) {
|
||||||
colnr_T col = 0, vcol;
|
colnr_T col = 0;
|
||||||
char_u *ptr;
|
char_u *ptr;
|
||||||
|
|
||||||
if (mode_displayed) {
|
if (mode_displayed) {
|
||||||
@ -2565,15 +2565,20 @@ static int vgetorpeek(bool advance)
|
|||||||
// We are expecting to truncate the trailing
|
// We are expecting to truncate the trailing
|
||||||
// white-space, so find the last non-white
|
// white-space, so find the last non-white
|
||||||
// character -- webb
|
// character -- webb
|
||||||
col = vcol = curwin->w_wcol = 0;
|
curwin->w_wcol = 0;
|
||||||
ptr = get_cursor_line_ptr();
|
ptr = get_cursor_line_ptr();
|
||||||
while (col < curwin->w_cursor.col) {
|
chartabsize_T cts;
|
||||||
if (!ascii_iswhite(ptr[col])) {
|
init_chartabsize_arg(&cts, curwin,
|
||||||
curwin->w_wcol = vcol;
|
curwin->w_cursor.lnum, 0, ptr, ptr);
|
||||||
|
while ((char_u *)cts.cts_ptr < ptr + curwin->w_cursor.col) {
|
||||||
|
if (!ascii_iswhite(*cts.cts_ptr)) {
|
||||||
|
curwin->w_wcol = cts.cts_vcol;
|
||||||
}
|
}
|
||||||
vcol += lbr_chartabsize(ptr, ptr + col, vcol);
|
cts.cts_vcol += lbr_chartabsize(&cts);
|
||||||
col += utfc_ptr2len((char *)ptr + col);
|
cts.cts_ptr += utfc_ptr2len(cts.cts_ptr);
|
||||||
}
|
}
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
|
|
||||||
curwin->w_wrow = curwin->w_cline_row
|
curwin->w_wrow = curwin->w_cline_row
|
||||||
+ curwin->w_wcol / curwin->w_width_inner;
|
+ curwin->w_wcol / curwin->w_width_inner;
|
||||||
curwin->w_wcol %= curwin->w_width_inner;
|
curwin->w_wcol %= curwin->w_width_inner;
|
||||||
|
@ -1034,13 +1034,15 @@ int get_lisp_indent(void)
|
|||||||
amount = 2;
|
amount = 2;
|
||||||
} else {
|
} else {
|
||||||
char_u *line = that;
|
char_u *line = that;
|
||||||
|
chartabsize_T cts;
|
||||||
amount = 0;
|
init_chartabsize_arg(&cts, curwin, pos->lnum, 0, line, line);
|
||||||
|
while (*cts.cts_ptr != NUL && col > 0) {
|
||||||
while (*that && col) {
|
cts.cts_vcol += lbr_chartabsize_adv(&cts);
|
||||||
amount += lbr_chartabsize_adv(line, &that, (colnr_T)amount);
|
|
||||||
col--;
|
col--;
|
||||||
}
|
}
|
||||||
|
amount = cts.cts_vcol;
|
||||||
|
that = (char_u *)cts.cts_ptr;
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
|
|
||||||
// Some keywords require "body" indenting rules (the
|
// Some keywords require "body" indenting rules (the
|
||||||
// non-standard-lisp ones are Scheme special forms):
|
// non-standard-lisp ones are Scheme special forms):
|
||||||
@ -1056,10 +1058,15 @@ int get_lisp_indent(void)
|
|||||||
}
|
}
|
||||||
firsttry = amount;
|
firsttry = amount;
|
||||||
|
|
||||||
while (ascii_iswhite(*that)) {
|
init_chartabsize_arg(&cts, curwin, (colnr_T)(that - line),
|
||||||
amount += lbr_chartabsize(line, that, (colnr_T)amount);
|
amount, line, that);
|
||||||
that++;
|
while (ascii_iswhite(*cts.cts_ptr)) {
|
||||||
|
cts.cts_vcol += lbr_chartabsize(&cts);
|
||||||
|
cts.cts_ptr++;
|
||||||
}
|
}
|
||||||
|
that = (char_u *)cts.cts_ptr;
|
||||||
|
amount = cts.cts_vcol;
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
|
|
||||||
if (*that && (*that != ';')) {
|
if (*that && (*that != ';')) {
|
||||||
// Not a comment line.
|
// Not a comment line.
|
||||||
@ -1072,33 +1079,38 @@ int get_lisp_indent(void)
|
|||||||
parencount = 0;
|
parencount = 0;
|
||||||
quotecount = 0;
|
quotecount = 0;
|
||||||
|
|
||||||
|
init_chartabsize_arg(&cts, curwin,
|
||||||
|
(colnr_T)(that - line), amount, line, that);
|
||||||
if (vi_lisp || ((*that != '"') && (*that != '\'')
|
if (vi_lisp || ((*that != '"') && (*that != '\'')
|
||||||
&& (*that != '#') && ((*that < '0') || (*that > '9')))) {
|
&& (*that != '#') && ((*that < '0') || (*that > '9')))) {
|
||||||
while (*that
|
while (*cts.cts_ptr
|
||||||
&& (!ascii_iswhite(*that) || quotecount || parencount)
|
&& (!ascii_iswhite(*cts.cts_ptr) || quotecount || parencount)
|
||||||
&& (!((*that == '(' || *that == '[')
|
&& (!((*cts.cts_ptr == '(' || *cts.cts_ptr == '[')
|
||||||
&& !quotecount && !parencount && vi_lisp))) {
|
&& !quotecount && !parencount && vi_lisp))) {
|
||||||
if (*that == '"') {
|
if (*cts.cts_ptr == '"') {
|
||||||
quotecount = !quotecount;
|
quotecount = !quotecount;
|
||||||
}
|
}
|
||||||
if (((*that == '(') || (*that == '[')) && !quotecount) {
|
if (((*cts.cts_ptr == '(') || (*cts.cts_ptr == '[')) && !quotecount) {
|
||||||
parencount++;
|
parencount++;
|
||||||
}
|
}
|
||||||
if (((*that == ')') || (*that == ']')) && !quotecount) {
|
if (((*cts.cts_ptr == ')') || (*cts.cts_ptr == ']')) && !quotecount) {
|
||||||
parencount--;
|
parencount--;
|
||||||
}
|
}
|
||||||
if ((*that == '\\') && (*(that + 1) != NUL)) {
|
if ((*cts.cts_ptr == '\\') && (*(cts.cts_ptr + 1) != NUL)) {
|
||||||
amount += lbr_chartabsize_adv(line, &that, (colnr_T)amount);
|
cts.cts_vcol += lbr_chartabsize_adv(&cts);
|
||||||
}
|
}
|
||||||
|
|
||||||
amount += lbr_chartabsize_adv(line, &that, (colnr_T)amount);
|
cts.cts_vcol += lbr_chartabsize_adv(&cts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (ascii_iswhite(*that)) {
|
while (ascii_iswhite(*cts.cts_ptr)) {
|
||||||
amount += lbr_chartabsize(line, that, (colnr_T)amount);
|
cts.cts_vcol += lbr_chartabsize(&cts);
|
||||||
that++;
|
cts.cts_ptr++;
|
||||||
}
|
}
|
||||||
|
that = (char_u *)cts.cts_ptr;
|
||||||
|
amount = cts.cts_vcol;
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
|
|
||||||
if (!*that || (*that == ';')) {
|
if (!*that || (*that == ';')) {
|
||||||
amount = firsttry;
|
amount = firsttry;
|
||||||
|
@ -631,14 +631,16 @@ colnr_T vcol2col(win_T *const wp, const linenr_T lnum, const colnr_T vcol)
|
|||||||
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
// try to advance to the specified column
|
// try to advance to the specified column
|
||||||
char_u *ptr = ml_get_buf(wp->w_buffer, lnum, false);
|
char_u *line = ml_get_buf(wp->w_buffer, lnum, false);
|
||||||
char_u *const line = ptr;
|
chartabsize_T cts;
|
||||||
colnr_T count = 0;
|
init_chartabsize_arg(&cts, wp, lnum, 0, line, line);
|
||||||
while (count < vcol && *ptr != NUL) {
|
while (cts.cts_vcol < vcol && *cts.cts_ptr != NUL) {
|
||||||
count += win_lbr_chartabsize(wp, line, ptr, count, NULL);
|
cts.cts_vcol += win_lbr_chartabsize(&cts, NULL);
|
||||||
MB_PTR_ADV(ptr);
|
MB_PTR_ADV(cts.cts_ptr);
|
||||||
}
|
}
|
||||||
return (colnr_T)(ptr - line);
|
clear_chartabsize_arg(&cts);
|
||||||
|
|
||||||
|
return (colnr_T)((char_u *)cts.cts_ptr - line);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set UI mouse depending on current mode and 'mouse'.
|
/// Set UI mouse depending on current mode and 'mouse'.
|
||||||
@ -667,7 +669,7 @@ static colnr_T scroll_line_len(linenr_T lnum)
|
|||||||
char_u *line = ml_get(lnum);
|
char_u *line = ml_get(lnum);
|
||||||
if (*line != NUL) {
|
if (*line != NUL) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int numchar = win_chartabsize(curwin, line, col);
|
int numchar = win_chartabsize(curwin, (char *)line, col);
|
||||||
MB_PTR_ADV(line);
|
MB_PTR_ADV(line);
|
||||||
if (*line == NUL) { // don't count the last character
|
if (*line == NUL) { // don't count the last character
|
||||||
break;
|
break;
|
||||||
@ -790,7 +792,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col)
|
|||||||
// checked for concealed characters.
|
// checked for concealed characters.
|
||||||
vcol = 0;
|
vcol = 0;
|
||||||
while (vcol < offset && *ptr != NUL) {
|
while (vcol < offset && *ptr != NUL) {
|
||||||
vcol += win_chartabsize(curwin, ptr, vcol);
|
vcol += win_chartabsize(curwin, (char *)ptr, vcol);
|
||||||
ptr += utfc_ptr2len((char *)ptr);
|
ptr += utfc_ptr2len((char *)ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -801,7 +803,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col)
|
|||||||
vcol = offset;
|
vcol = offset;
|
||||||
ptr_end = ptr_row_offset;
|
ptr_end = ptr_row_offset;
|
||||||
while (vcol < col && *ptr_end != NUL) {
|
while (vcol < col && *ptr_end != NUL) {
|
||||||
vcol += win_chartabsize(curwin, ptr_end, vcol);
|
vcol += win_chartabsize(curwin, (char *)ptr_end, vcol);
|
||||||
ptr_end += utfc_ptr2len((char *)ptr_end);
|
ptr_end += utfc_ptr2len((char *)ptr_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -816,7 +818,7 @@ static int mouse_adjust_click(win_T *wp, int row, int col)
|
|||||||
#define DECR() nudge--; ptr_end -= utfc_ptr2len((char *)ptr_end)
|
#define DECR() nudge--; ptr_end -= utfc_ptr2len((char *)ptr_end)
|
||||||
|
|
||||||
while (ptr < ptr_end && *ptr != NUL) {
|
while (ptr < ptr_end && *ptr != NUL) {
|
||||||
cwidth = win_chartabsize(curwin, ptr, vcol);
|
cwidth = win_chartabsize(curwin, (char *)ptr, vcol);
|
||||||
vcol += cwidth;
|
vcol += cwidth;
|
||||||
if (cwidth > 1 && *ptr == '\t' && nudge > 0) {
|
if (cwidth > 1 && *ptr == '\t' && nudge > 0) {
|
||||||
// A tab will "absorb" any previous adjustments.
|
// A tab will "absorb" any previous adjustments.
|
||||||
|
101
src/nvim/ops.c
101
src/nvim/ops.c
@ -378,12 +378,20 @@ static void shift_block(oparg_T *oap, int amount)
|
|||||||
bd.startspaces = 0;
|
bd.startspaces = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (; ascii_iswhite(*bd.textstart);) {
|
|
||||||
// TODO(fmoralesc): is passing bd.textstart for start of the line OK?
|
// TODO(vim): is passing bd.textstart for start of the line OK?
|
||||||
incr = lbr_chartabsize_adv(bd.textstart, &bd.textstart, bd.start_vcol);
|
chartabsize_T cts;
|
||||||
|
init_chartabsize_arg(&cts, curwin, curwin->w_cursor.lnum,
|
||||||
|
bd.start_vcol, bd.textstart, bd.textstart);
|
||||||
|
while (ascii_iswhite(*cts.cts_ptr)) {
|
||||||
|
incr = lbr_chartabsize_adv(&cts);
|
||||||
total += incr;
|
total += incr;
|
||||||
bd.start_vcol += incr;
|
cts.cts_vcol += incr;
|
||||||
}
|
}
|
||||||
|
bd.textstart = (char_u *)cts.cts_ptr;
|
||||||
|
bd.start_vcol = cts.cts_vcol;
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
|
|
||||||
// OK, now total=all the VWS reqd, and textstart points at the 1st
|
// OK, now total=all the VWS reqd, and textstart points at the 1st
|
||||||
// non-ws char in the block.
|
// non-ws char in the block.
|
||||||
if (!curbuf->b_p_et) {
|
if (!curbuf->b_p_et) {
|
||||||
@ -438,10 +446,16 @@ static void shift_block(oparg_T *oap, int amount)
|
|||||||
// The character's column is in "bd.start_vcol".
|
// The character's column is in "bd.start_vcol".
|
||||||
colnr_T non_white_col = bd.start_vcol;
|
colnr_T non_white_col = bd.start_vcol;
|
||||||
|
|
||||||
while (ascii_iswhite(*non_white)) {
|
chartabsize_T cts;
|
||||||
incr = lbr_chartabsize_adv(bd.textstart, &non_white, non_white_col);
|
init_chartabsize_arg(&cts, curwin, curwin->w_cursor.lnum,
|
||||||
non_white_col += incr;
|
non_white_col, bd.textstart, non_white);
|
||||||
|
while (ascii_iswhite(*cts.cts_ptr)) {
|
||||||
|
incr = lbr_chartabsize_adv(&cts);
|
||||||
|
cts.cts_vcol += incr;
|
||||||
}
|
}
|
||||||
|
non_white_col = cts.cts_vcol;
|
||||||
|
non_white = (char_u *)cts.cts_ptr;
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
|
|
||||||
const colnr_T block_space_width = non_white_col - oap->start_vcol;
|
const colnr_T block_space_width = non_white_col - oap->start_vcol;
|
||||||
// We will shift by "total" or "block_space_width", whichever is less.
|
// We will shift by "total" or "block_space_width", whichever is less.
|
||||||
@ -462,17 +476,19 @@ static void shift_block(oparg_T *oap, int amount)
|
|||||||
if (bd.startspaces) {
|
if (bd.startspaces) {
|
||||||
verbatim_copy_width -= bd.start_char_vcols;
|
verbatim_copy_width -= bd.start_char_vcols;
|
||||||
}
|
}
|
||||||
while (verbatim_copy_width < destination_col) {
|
init_chartabsize_arg(&cts, curwin, 0, verbatim_copy_width,
|
||||||
char_u *line = verbatim_copy_end;
|
bd.textstart, verbatim_copy_end);
|
||||||
|
while (cts.cts_vcol < destination_col) {
|
||||||
// TODO: is passing verbatim_copy_end for start of the line OK?
|
incr = lbr_chartabsize(&cts);
|
||||||
incr = lbr_chartabsize(line, verbatim_copy_end, verbatim_copy_width);
|
if (cts.cts_vcol + incr > destination_col) {
|
||||||
if (verbatim_copy_width + incr > destination_col) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
verbatim_copy_width += incr;
|
cts.cts_vcol += incr;
|
||||||
MB_PTR_ADV(verbatim_copy_end);
|
MB_PTR_ADV(cts.cts_ptr);
|
||||||
}
|
}
|
||||||
|
verbatim_copy_width = cts.cts_vcol;
|
||||||
|
verbatim_copy_end = (char_u *)cts.cts_ptr;
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
|
|
||||||
// If "destination_col" is different from the width of the initial
|
// If "destination_col" is different from the width of the initial
|
||||||
// part of the line that will be copied, it means we encountered a tab
|
// part of the line that will be copied, it means we encountered a tab
|
||||||
@ -1550,6 +1566,7 @@ int op_delete(oparg_T *oap)
|
|||||||
// Put deleted text into register 1 and shift number registers if the
|
// Put deleted text into register 1 and shift number registers if the
|
||||||
// delete contains a line break, or when using a specific operator (Vi
|
// delete contains a line break, or when using a specific operator (Vi
|
||||||
// compatible)
|
// compatible)
|
||||||
|
|
||||||
if (oap->motion_type == kMTLineWise || oap->line_count > 1 || oap->use_reg_one) {
|
if (oap->motion_type == kMTLineWise || oap->line_count > 1 || oap->use_reg_one) {
|
||||||
shift_delete_registers(is_append_register(oap->regname));
|
shift_delete_registers(is_append_register(oap->regname));
|
||||||
reg = &y_regs[1];
|
reg = &y_regs[1];
|
||||||
@ -3280,12 +3297,19 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
|
|||||||
// get the old line and advance to the position to insert at
|
// get the old line and advance to the position to insert at
|
||||||
oldp = get_cursor_line_ptr();
|
oldp = get_cursor_line_ptr();
|
||||||
oldlen = STRLEN(oldp);
|
oldlen = STRLEN(oldp);
|
||||||
for (ptr = oldp; vcol < col && *ptr;) {
|
chartabsize_T cts;
|
||||||
|
init_chartabsize_arg(&cts, curwin, curwin->w_cursor.lnum, 0,
|
||||||
|
oldp, oldp);
|
||||||
|
|
||||||
|
while (cts.cts_vcol < col && *cts.cts_ptr != NUL) {
|
||||||
// Count a tab for what it's worth (if list mode not on)
|
// Count a tab for what it's worth (if list mode not on)
|
||||||
incr = lbr_chartabsize_adv(oldp, &ptr, vcol);
|
incr = lbr_chartabsize_adv(&cts);
|
||||||
vcol += incr;
|
cts.cts_vcol += incr;
|
||||||
}
|
}
|
||||||
|
vcol = cts.cts_vcol;
|
||||||
|
ptr = (char_u *)cts.cts_ptr;
|
||||||
bd.textcol = (colnr_T)(ptr - oldp);
|
bd.textcol = (colnr_T)(ptr - oldp);
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
|
|
||||||
shortline = (vcol < col) || (vcol == col && !*ptr);
|
shortline = (vcol < col) || (vcol == col && !*ptr);
|
||||||
|
|
||||||
@ -3312,9 +3336,14 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
|
|||||||
// calculate number of spaces required to fill right side of
|
// calculate number of spaces required to fill right side of
|
||||||
// block
|
// block
|
||||||
spaces = y_width + 1;
|
spaces = y_width + 1;
|
||||||
|
init_chartabsize_arg(&cts, curwin, 0, 0,
|
||||||
|
(char_u *)y_array[i], (char_u *)y_array[i]);
|
||||||
for (int j = 0; j < yanklen; j++) {
|
for (int j = 0; j < yanklen; j++) {
|
||||||
spaces -= lbr_chartabsize(NULL, (char_u *)(&y_array[i][j]), 0);
|
spaces -= lbr_chartabsize(&cts);
|
||||||
|
cts.cts_ptr++;
|
||||||
|
cts.cts_vcol = 0;
|
||||||
}
|
}
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
if (spaces < 0) {
|
if (spaces < 0) {
|
||||||
spaces = 0;
|
spaces = 0;
|
||||||
}
|
}
|
||||||
@ -4227,22 +4256,28 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool
|
|||||||
bdp->start_char_vcols = 0;
|
bdp->start_char_vcols = 0;
|
||||||
|
|
||||||
line = ml_get(lnum);
|
line = ml_get(lnum);
|
||||||
pstart = line;
|
|
||||||
prev_pstart = line;
|
prev_pstart = line;
|
||||||
while (bdp->start_vcol < oap->start_vcol && *pstart) {
|
|
||||||
|
chartabsize_T cts;
|
||||||
|
init_chartabsize_arg(&cts, curwin, lnum, bdp->start_vcol, line, line);
|
||||||
|
while (cts.cts_vcol < oap->start_vcol && *cts.cts_ptr != NUL) {
|
||||||
// Count a tab for what it's worth (if list mode not on)
|
// Count a tab for what it's worth (if list mode not on)
|
||||||
incr = lbr_chartabsize(line, pstart, bdp->start_vcol);
|
incr = lbr_chartabsize(&cts);
|
||||||
bdp->start_vcol += incr;
|
cts.cts_vcol += incr;
|
||||||
if (ascii_iswhite(*pstart)) {
|
if (ascii_iswhite(*cts.cts_ptr)) {
|
||||||
bdp->pre_whitesp += incr;
|
bdp->pre_whitesp += incr;
|
||||||
bdp->pre_whitesp_c++;
|
bdp->pre_whitesp_c++;
|
||||||
} else {
|
} else {
|
||||||
bdp->pre_whitesp = 0;
|
bdp->pre_whitesp = 0;
|
||||||
bdp->pre_whitesp_c = 0;
|
bdp->pre_whitesp_c = 0;
|
||||||
}
|
}
|
||||||
prev_pstart = pstart;
|
prev_pstart = (char_u *)cts.cts_ptr;
|
||||||
MB_PTR_ADV(pstart);
|
MB_PTR_ADV(cts.cts_ptr);
|
||||||
}
|
}
|
||||||
|
bdp->start_vcol = cts.cts_vcol;
|
||||||
|
pstart = (char_u *)cts.cts_ptr;
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
|
|
||||||
bdp->start_char_vcols = incr;
|
bdp->start_char_vcols = incr;
|
||||||
if (bdp->start_vcol < oap->start_vcol) { // line too short
|
if (bdp->start_vcol < oap->start_vcol) { // line too short
|
||||||
bdp->end_vcol = bdp->start_vcol;
|
bdp->end_vcol = bdp->start_vcol;
|
||||||
@ -4278,13 +4313,19 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
init_chartabsize_arg(&cts, curwin, lnum, bdp->end_vcol,
|
||||||
|
line, pend);
|
||||||
prev_pend = pend;
|
prev_pend = pend;
|
||||||
while (bdp->end_vcol <= oap->end_vcol && *pend != NUL) {
|
while (cts.cts_vcol <= oap->end_vcol && *cts.cts_ptr != NUL) {
|
||||||
// Count a tab for what it's worth (if list mode not on)
|
// Count a tab for what it's worth (if list mode not on)
|
||||||
prev_pend = pend;
|
prev_pend = (char_u *)cts.cts_ptr;
|
||||||
incr = lbr_chartabsize_adv(line, &pend, bdp->end_vcol);
|
incr = lbr_chartabsize_adv(&cts);
|
||||||
bdp->end_vcol += incr;
|
cts.cts_vcol += incr;
|
||||||
}
|
}
|
||||||
|
bdp->end_vcol = cts.cts_vcol;
|
||||||
|
pend = (char_u *)cts.cts_ptr;
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
|
|
||||||
if (bdp->end_vcol <= oap->end_vcol
|
if (bdp->end_vcol <= oap->end_vcol
|
||||||
&& (!is_del
|
&& (!is_del
|
||||||
|| oap->op_type == OP_APPEND
|
|| oap->op_type == OP_APPEND
|
||||||
|
@ -98,15 +98,15 @@ int plines_win_nofill(win_T *wp, linenr_T lnum, bool winheight)
|
|||||||
/// "wp". Does not care about folding, 'wrap' or 'diff'.
|
/// "wp". Does not care about folding, 'wrap' or 'diff'.
|
||||||
int plines_win_nofold(win_T *wp, linenr_T lnum)
|
int plines_win_nofold(win_T *wp, linenr_T lnum)
|
||||||
{
|
{
|
||||||
char_u *s;
|
char *s;
|
||||||
unsigned int col;
|
unsigned int col;
|
||||||
int width;
|
int width;
|
||||||
|
|
||||||
s = ml_get_buf(wp->w_buffer, lnum, false);
|
s = (char *)ml_get_buf(wp->w_buffer, lnum, false);
|
||||||
if (*s == NUL) { // empty line
|
if (*s == NUL) { // empty line
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
col = win_linetabsize(wp, s, MAXCOL);
|
col = win_linetabsize(wp, lnum, (char_u *)s, MAXCOL);
|
||||||
|
|
||||||
// If list mode is on, then the '$' at the end of the line may take up one
|
// If list mode is on, then the '$' at the end of the line may take up one
|
||||||
// extra column.
|
// extra column.
|
||||||
@ -145,23 +145,27 @@ int plines_win_col(win_T *wp, linenr_T lnum, long column)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char_u *line = ml_get_buf(wp->w_buffer, lnum, false);
|
char_u *line = ml_get_buf(wp->w_buffer, lnum, false);
|
||||||
char_u *s = line;
|
|
||||||
|
|
||||||
colnr_T col = 0;
|
colnr_T col = 0;
|
||||||
while (*s != NUL && --column >= 0) {
|
chartabsize_T cts;
|
||||||
col += win_lbr_chartabsize(wp, line, s, col, NULL);
|
|
||||||
MB_PTR_ADV(s);
|
init_chartabsize_arg(&cts, wp, lnum, 0, line, line);
|
||||||
|
while (*cts.cts_ptr != NUL && --column >= 0) {
|
||||||
|
cts.cts_vcol += win_lbr_chartabsize(&cts, NULL);
|
||||||
|
MB_PTR_ADV(cts.cts_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If *s is a TAB, and the TAB is not displayed as ^I, and we're not in
|
// If *cts.cts_ptr is a TAB, and the TAB is not displayed as ^I, and we're not
|
||||||
// MODE_INSERT state, then col must be adjusted so that it represents the
|
// in MODE_INSERT state, then col must be adjusted so that it represents the
|
||||||
// last screen position of the TAB. This only fixes an error when the TAB
|
// last screen position of the TAB. This only fixes an error when the TAB
|
||||||
// wraps from one screen line to the next (when 'columns' is not a multiple
|
// wraps from one screen line to the next (when 'columns' is not a multiple
|
||||||
// of 'ts') -- webb.
|
// of 'ts') -- webb.
|
||||||
if (*s == TAB && (State & MODE_NORMAL)
|
col = cts.cts_vcol;
|
||||||
|
if (*cts.cts_ptr == TAB && (State & MODE_NORMAL)
|
||||||
&& (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) {
|
&& (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) {
|
||||||
col += win_lbr_chartabsize(wp, line, s, col, NULL) - 1;
|
col += win_lbr_chartabsize(&cts, NULL) - 1;
|
||||||
}
|
}
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
|
|
||||||
// Add column offset for 'number', 'relativenumber', 'foldcolumn', etc.
|
// Add column offset for 'number', 'relativenumber', 'foldcolumn', etc.
|
||||||
int width = wp->w_width_inner - win_col_off(wp);
|
int width = wp->w_width_inner - win_col_off(wp);
|
||||||
@ -223,7 +227,7 @@ int plines_m_win(win_T *wp, linenr_T first, linenr_T last)
|
|||||||
/// @param col
|
/// @param col
|
||||||
///
|
///
|
||||||
/// @return Number of characters.
|
/// @return Number of characters.
|
||||||
int win_chartabsize(win_T *wp, char_u *p, colnr_T col)
|
int win_chartabsize(win_T *wp, char *p, colnr_T col)
|
||||||
{
|
{
|
||||||
buf_T *buf = wp->w_buffer;
|
buf_T *buf = wp->w_buffer;
|
||||||
if (*p == TAB && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) {
|
if (*p == TAB && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) {
|
||||||
@ -241,24 +245,24 @@ int win_chartabsize(win_T *wp, char_u *p, colnr_T col)
|
|||||||
/// @return Number of characters the string will take on the screen.
|
/// @return Number of characters the string will take on the screen.
|
||||||
int linetabsize(char_u *s)
|
int linetabsize(char_u *s)
|
||||||
{
|
{
|
||||||
return linetabsize_col(0, s);
|
return linetabsize_col(0, (char *)s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Like linetabsize(), but starting at column "startcol".
|
/// Like linetabsize(), but "s" starts at column "startcol".
|
||||||
///
|
///
|
||||||
/// @param startcol
|
/// @param startcol
|
||||||
/// @param s
|
/// @param s
|
||||||
///
|
///
|
||||||
/// @return Number of characters the string will take on the screen.
|
/// @return Number of characters the string will take on the screen.
|
||||||
int linetabsize_col(int startcol, char_u *s)
|
int linetabsize_col(int startcol, char *s)
|
||||||
{
|
{
|
||||||
colnr_T col = startcol;
|
chartabsize_T cts;
|
||||||
char_u *line = s; // pointer to start of line, for breakindent
|
init_chartabsize_arg(&cts, curwin, 0, startcol, (char_u *)s, (char_u *)s);
|
||||||
|
while (*cts.cts_ptr != NUL) {
|
||||||
while (*s != NUL) {
|
cts.cts_vcol += lbr_chartabsize_adv(&cts);
|
||||||
col += lbr_chartabsize_adv(line, &s, col);
|
|
||||||
}
|
}
|
||||||
return (int)col;
|
clear_chartabsize_arg(&cts);
|
||||||
|
return (int)cts.cts_vcol;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Like linetabsize(), but for a given window instead of the current one.
|
/// Like linetabsize(), but for a given window instead of the current one.
|
||||||
@ -268,19 +272,39 @@ int linetabsize_col(int startcol, char_u *s)
|
|||||||
/// @param len
|
/// @param len
|
||||||
///
|
///
|
||||||
/// @return Number of characters the string will take on the screen.
|
/// @return Number of characters the string will take on the screen.
|
||||||
unsigned int win_linetabsize(win_T *wp, char_u *line, colnr_T len)
|
unsigned int win_linetabsize(win_T *wp, linenr_T lnum, char_u *line, colnr_T len)
|
||||||
{
|
{
|
||||||
colnr_T col = 0;
|
chartabsize_T cts;
|
||||||
|
init_chartabsize_arg(&cts, wp, lnum, 0, line, line);
|
||||||
for (char_u *s = line;
|
for (; *cts.cts_ptr != NUL && (len == MAXCOL || cts.cts_ptr < (char *)line + len);
|
||||||
*s != NUL && (len == MAXCOL || s < line + len);
|
MB_PTR_ADV(cts.cts_ptr)) {
|
||||||
MB_PTR_ADV(s)) {
|
cts.cts_vcol += win_lbr_chartabsize(&cts, NULL);
|
||||||
col += win_lbr_chartabsize(wp, line, s, col, NULL);
|
|
||||||
}
|
}
|
||||||
|
clear_chartabsize_arg(&cts);
|
||||||
return (unsigned int)col;
|
return (unsigned int)cts.cts_vcol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Prepare the structure passed to chartabsize functions.
|
||||||
|
///
|
||||||
|
/// "line" is the start of the line, "ptr" is the first relevant character.
|
||||||
|
/// When "lnum" is zero do not use text properties that insert text.
|
||||||
|
void init_chartabsize_arg(chartabsize_T *cts, win_T *wp, linenr_T lnum, colnr_T col, char_u *line,
|
||||||
|
char_u *ptr)
|
||||||
|
{
|
||||||
|
cts->cts_win = wp;
|
||||||
|
cts->cts_lnum = lnum;
|
||||||
|
cts->cts_vcol = col;
|
||||||
|
cts->cts_line = (char *)line;
|
||||||
|
cts->cts_ptr = (char *)ptr;
|
||||||
|
cts->cts_cur_text_width = 0;
|
||||||
|
// TODO(bfredl): actually lookup inline virtual text here
|
||||||
|
cts->cts_has_virt_text = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Free any allocated item in "cts".
|
||||||
|
void clear_chartabsize_arg(chartabsize_T *cts)
|
||||||
|
{}
|
||||||
|
|
||||||
/// like win_chartabsize(), but also check for line breaks on the screen
|
/// like win_chartabsize(), but also check for line breaks on the screen
|
||||||
///
|
///
|
||||||
/// @param line
|
/// @param line
|
||||||
@ -288,16 +312,16 @@ unsigned int win_linetabsize(win_T *wp, char_u *line, colnr_T len)
|
|||||||
/// @param col
|
/// @param col
|
||||||
///
|
///
|
||||||
/// @return The number of characters taken up on the screen.
|
/// @return The number of characters taken up on the screen.
|
||||||
int lbr_chartabsize(char_u *line, unsigned char *s, colnr_T col)
|
int lbr_chartabsize(chartabsize_T *cts)
|
||||||
{
|
{
|
||||||
if (!curwin->w_p_lbr && *get_showbreak_value(curwin) == NUL
|
if (!curwin->w_p_lbr && *get_showbreak_value(curwin) == NUL
|
||||||
&& !curwin->w_p_bri) {
|
&& !curwin->w_p_bri && !cts->cts_has_virt_text) {
|
||||||
if (curwin->w_p_wrap) {
|
if (curwin->w_p_wrap) {
|
||||||
return win_nolbr_chartabsize(curwin, s, col, NULL);
|
return win_nolbr_chartabsize(cts, NULL);
|
||||||
}
|
}
|
||||||
return win_chartabsize(curwin, s, col);
|
return win_chartabsize(curwin, cts->cts_ptr, cts->cts_vcol);
|
||||||
}
|
}
|
||||||
return win_lbr_chartabsize(curwin, line == NULL ? s: line, s, col, NULL);
|
return win_lbr_chartabsize(cts, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Call lbr_chartabsize() and advance the pointer.
|
/// Call lbr_chartabsize() and advance the pointer.
|
||||||
@ -307,12 +331,12 @@ int lbr_chartabsize(char_u *line, unsigned char *s, colnr_T col)
|
|||||||
/// @param col
|
/// @param col
|
||||||
///
|
///
|
||||||
/// @return The number of characters take up on the screen.
|
/// @return The number of characters take up on the screen.
|
||||||
int lbr_chartabsize_adv(char_u *line, char_u **s, colnr_T col)
|
int lbr_chartabsize_adv(chartabsize_T *cts)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
retval = lbr_chartabsize(line, *s, col);
|
retval = lbr_chartabsize(cts);
|
||||||
MB_PTR_ADV(*s);
|
MB_PTR_ADV(cts->cts_ptr);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,17 +346,19 @@ int lbr_chartabsize_adv(char_u *line, char_u **s, colnr_T col)
|
|||||||
/// string at start of line. Warning: *headp is only set if it's a non-zero
|
/// string at start of line. Warning: *headp is only set if it's a non-zero
|
||||||
/// value, init to 0 before calling.
|
/// value, init to 0 before calling.
|
||||||
///
|
///
|
||||||
/// @param wp
|
/// @param cts
|
||||||
/// @param line
|
|
||||||
/// @param s
|
|
||||||
/// @param col
|
|
||||||
/// @param headp
|
/// @param headp
|
||||||
///
|
///
|
||||||
/// @return The number of characters taken up on the screen.
|
/// @return The number of characters taken up on the screen.
|
||||||
int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *headp)
|
int win_lbr_chartabsize(chartabsize_T *cts, int *headp)
|
||||||
{
|
{
|
||||||
|
win_T *wp = cts->cts_win;
|
||||||
|
char *line = cts->cts_line; // start of the line
|
||||||
|
char_u *s = (char_u *)cts->cts_ptr;
|
||||||
|
colnr_T vcol = cts->cts_vcol;
|
||||||
|
|
||||||
colnr_T col2;
|
colnr_T col2;
|
||||||
colnr_T col_adj = 0; // col + screen size of tab
|
colnr_T col_adj = 0; // vcol + screen size of tab
|
||||||
colnr_T colmax;
|
colnr_T colmax;
|
||||||
int added;
|
int added;
|
||||||
int mb_added = 0;
|
int mb_added = 0;
|
||||||
@ -340,16 +366,23 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he
|
|||||||
char_u *ps;
|
char_u *ps;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
|
cts->cts_cur_text_width = 0;
|
||||||
|
|
||||||
// No 'linebreak', 'showbreak' and 'breakindent': return quickly.
|
// No 'linebreak', 'showbreak' and 'breakindent': return quickly.
|
||||||
if (!wp->w_p_lbr && !wp->w_p_bri && *get_showbreak_value(wp) == NUL) {
|
if (!wp->w_p_lbr && !wp->w_p_bri && *get_showbreak_value(wp) == NUL
|
||||||
|
&& !cts->cts_has_virt_text) {
|
||||||
if (wp->w_p_wrap) {
|
if (wp->w_p_wrap) {
|
||||||
return win_nolbr_chartabsize(wp, s, col, headp);
|
return win_nolbr_chartabsize(cts, headp);
|
||||||
}
|
}
|
||||||
return win_chartabsize(wp, s, col);
|
return win_chartabsize(wp, (char *)s, vcol);
|
||||||
|
}
|
||||||
|
|
||||||
|
// First get normal size, without 'linebreak' or virtual text
|
||||||
|
int size = win_chartabsize(wp, (char *)s, vcol);
|
||||||
|
if (cts->cts_has_virt_text) {
|
||||||
|
// TODO(bfredl): inline virtual text
|
||||||
}
|
}
|
||||||
|
|
||||||
// First get normal size, without 'linebreak'
|
|
||||||
int size = win_chartabsize(wp, s, col);
|
|
||||||
int c = *s;
|
int c = *s;
|
||||||
if (*s == TAB) {
|
if (*s == TAB) {
|
||||||
col_adj = size - 1;
|
col_adj = size - 1;
|
||||||
@ -365,15 +398,15 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he
|
|||||||
// Count all characters from first non-blank after a blank up to next
|
// Count all characters from first non-blank after a blank up to next
|
||||||
// non-blank after a blank.
|
// non-blank after a blank.
|
||||||
numberextra = win_col_off(wp);
|
numberextra = win_col_off(wp);
|
||||||
col2 = col;
|
col2 = vcol;
|
||||||
colmax = (colnr_T)(wp->w_width_inner - numberextra - col_adj);
|
colmax = (colnr_T)(wp->w_width_inner - numberextra - col_adj);
|
||||||
|
|
||||||
if (col >= colmax) {
|
if (vcol >= colmax) {
|
||||||
colmax += col_adj;
|
colmax += col_adj;
|
||||||
n = colmax + win_col_off2(wp);
|
n = colmax + win_col_off2(wp);
|
||||||
|
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
colmax += (((col - colmax) / n) + 1) * n - col_adj;
|
colmax += (((vcol - colmax) / n) + 1) * n - col_adj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,21 +416,21 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he
|
|||||||
c = *s;
|
c = *s;
|
||||||
|
|
||||||
if (!(c != NUL
|
if (!(c != NUL
|
||||||
&& (vim_isbreak(c) || col2 == col || !vim_isbreak((int)(*ps))))) {
|
&& (vim_isbreak(c) || col2 == vcol || !vim_isbreak((int)(*ps))))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
col2 += win_chartabsize(wp, s, col2);
|
col2 += win_chartabsize(wp, (char *)s, col2);
|
||||||
|
|
||||||
if (col2 >= colmax) { // doesn't fit
|
if (col2 >= colmax) { // doesn't fit
|
||||||
size = colmax - col + col_adj;
|
size = colmax - vcol + col_adj;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ((size == 2)
|
} else if ((size == 2)
|
||||||
&& (MB_BYTE2LEN(*s) > 1)
|
&& (MB_BYTE2LEN(*s) > 1)
|
||||||
&& wp->w_p_wrap
|
&& wp->w_p_wrap
|
||||||
&& in_win_border(wp, col)) {
|
&& in_win_border(wp, vcol)) {
|
||||||
// Count the ">" in the last column.
|
// Count the ">" in the last column.
|
||||||
size++;
|
size++;
|
||||||
mb_added = 1;
|
mb_added = 1;
|
||||||
@ -409,40 +442,40 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he
|
|||||||
added = 0;
|
added = 0;
|
||||||
|
|
||||||
char *const sbr = (char *)get_showbreak_value(wp);
|
char *const sbr = (char *)get_showbreak_value(wp);
|
||||||
if ((*sbr != NUL || wp->w_p_bri) && wp->w_p_wrap && col != 0) {
|
if ((*sbr != NUL || wp->w_p_bri) && wp->w_p_wrap && vcol != 0) {
|
||||||
colnr_T sbrlen = 0;
|
colnr_T sbrlen = 0;
|
||||||
int numberwidth = win_col_off(wp);
|
int numberwidth = win_col_off(wp);
|
||||||
|
|
||||||
numberextra = numberwidth;
|
numberextra = numberwidth;
|
||||||
col += numberextra + mb_added;
|
vcol += numberextra + mb_added;
|
||||||
|
|
||||||
if (col >= (colnr_T)wp->w_width_inner) {
|
if (vcol >= (colnr_T)wp->w_width_inner) {
|
||||||
col -= wp->w_width_inner;
|
vcol -= wp->w_width_inner;
|
||||||
numberextra = wp->w_width_inner - (numberextra - win_col_off2(wp));
|
numberextra = wp->w_width_inner - (numberextra - win_col_off2(wp));
|
||||||
if (col >= numberextra && numberextra > 0) {
|
if (vcol >= numberextra && numberextra > 0) {
|
||||||
col %= numberextra;
|
vcol %= numberextra;
|
||||||
}
|
}
|
||||||
if (*sbr != NUL) {
|
if (*sbr != NUL) {
|
||||||
sbrlen = (colnr_T)mb_charlen((char_u *)sbr);
|
sbrlen = (colnr_T)mb_charlen((char_u *)sbr);
|
||||||
if (col >= sbrlen) {
|
if (vcol >= sbrlen) {
|
||||||
col -= sbrlen;
|
vcol -= sbrlen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (col >= numberextra && numberextra > 0) {
|
if (vcol >= numberextra && numberextra > 0) {
|
||||||
col %= numberextra;
|
vcol %= numberextra;
|
||||||
} else if (col > 0 && numberextra > 0) {
|
} else if (vcol > 0 && numberextra > 0) {
|
||||||
col += numberwidth - win_col_off2(wp);
|
vcol += numberwidth - win_col_off2(wp);
|
||||||
}
|
}
|
||||||
|
|
||||||
numberwidth -= win_col_off2(wp);
|
numberwidth -= win_col_off2(wp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (col == 0 || (col + size + sbrlen > (colnr_T)wp->w_width_inner)) {
|
if (vcol == 0 || (vcol + size + sbrlen > (colnr_T)wp->w_width_inner)) {
|
||||||
if (*sbr != NUL) {
|
if (*sbr != NUL) {
|
||||||
if (size + sbrlen + numberwidth > (colnr_T)wp->w_width_inner) {
|
if (size + sbrlen + numberwidth > (colnr_T)wp->w_width_inner) {
|
||||||
// Calculate effective window width.
|
// Calculate effective window width.
|
||||||
int width = (colnr_T)wp->w_width_inner - sbrlen - numberwidth;
|
int width = (colnr_T)wp->w_width_inner - sbrlen - numberwidth;
|
||||||
int prev_width = col ? ((colnr_T)wp->w_width_inner - (sbrlen + col))
|
int prev_width = vcol ? ((colnr_T)wp->w_width_inner - (sbrlen + vcol))
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
if (width <= 0) {
|
if (width <= 0) {
|
||||||
@ -459,11 +492,11 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (wp->w_p_bri) {
|
if (wp->w_p_bri) {
|
||||||
added += get_breakindent_win(wp, line);
|
added += get_breakindent_win(wp, (char_u *)line);
|
||||||
}
|
}
|
||||||
|
|
||||||
size += added;
|
size += added;
|
||||||
if (col != 0) {
|
if (vcol != 0) {
|
||||||
added = 0;
|
added = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -485,8 +518,11 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he
|
|||||||
/// @param headp
|
/// @param headp
|
||||||
///
|
///
|
||||||
/// @return The number of characters take up on the screen.
|
/// @return The number of characters take up on the screen.
|
||||||
static int win_nolbr_chartabsize(win_T *wp, char_u *s, colnr_T col, int *headp)
|
static int win_nolbr_chartabsize(chartabsize_T *cts, int *headp)
|
||||||
{
|
{
|
||||||
|
win_T *wp = cts->cts_win;
|
||||||
|
char *s = cts->cts_ptr;
|
||||||
|
colnr_T col = cts->cts_vcol;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if ((*s == TAB) && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) {
|
if ((*s == TAB) && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) {
|
||||||
@ -498,7 +534,7 @@ static int win_nolbr_chartabsize(win_T *wp, char_u *s, colnr_T col, int *headp)
|
|||||||
|
|
||||||
// Add one cell for a double-width character in the last column of the
|
// Add one cell for a double-width character in the last column of the
|
||||||
// window, displayed with a ">".
|
// window, displayed with a ">".
|
||||||
if ((n == 2) && (MB_BYTE2LEN(*s) > 1) && in_win_border(wp, col)) {
|
if ((n == 2) && (MB_BYTE2LEN((uint8_t)(*s)) > 1) && in_win_border(wp, col)) {
|
||||||
if (headp != NULL) {
|
if (headp != NULL) {
|
||||||
*headp = 1;
|
*headp = 1;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,20 @@
|
|||||||
|
|
||||||
#include "nvim/vim.h"
|
#include "nvim/vim.h"
|
||||||
|
|
||||||
|
// Argument for lbr_chartabsize().
|
||||||
|
typedef struct {
|
||||||
|
win_T *cts_win;
|
||||||
|
linenr_T cts_lnum; // zero when not using text properties
|
||||||
|
char *cts_line; // start of the line
|
||||||
|
char *cts_ptr; // current position in line
|
||||||
|
|
||||||
|
bool cts_has_virt_text; // true if if a property inserts text
|
||||||
|
int cts_cur_text_width; // width of current inserted text
|
||||||
|
// TODO(bfredl): iterator in to the marktree for scanning virt text
|
||||||
|
|
||||||
|
int cts_vcol; // virtual column at current position
|
||||||
|
} chartabsize_T;
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "plines.h.generated.h"
|
# include "plines.h.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -1165,7 +1165,7 @@ static bool reg_match_visual(void)
|
|||||||
rex.line = reg_getline(rex.lnum);
|
rex.line = reg_getline(rex.lnum);
|
||||||
rex.input = rex.line + col;
|
rex.input = rex.line + col;
|
||||||
|
|
||||||
unsigned int cols_u = win_linetabsize(wp, rex.line, col);
|
unsigned int cols_u = win_linetabsize(wp, rex.reg_firstlnum + rex.lnum, rex.line, col);
|
||||||
assert(cols_u <= MAXCOL);
|
assert(cols_u <= MAXCOL);
|
||||||
colnr_T cols = (colnr_T)cols_u;
|
colnr_T cols = (colnr_T)cols_u;
|
||||||
if (cols < start || cols > end - (*p_sel == 'e')) {
|
if (cols < start || cols > end - (*p_sel == 'e')) {
|
||||||
|
@ -3764,6 +3764,7 @@ static bool regmatch(char_u *scan, proftime_T *tm, int *timed_out)
|
|||||||
case RE_VCOL:
|
case RE_VCOL:
|
||||||
if (!re_num_cmp(win_linetabsize(rex.reg_win == NULL
|
if (!re_num_cmp(win_linetabsize(rex.reg_win == NULL
|
||||||
? curwin : rex.reg_win,
|
? curwin : rex.reg_win,
|
||||||
|
rex.reg_firstlnum + rex.lnum,
|
||||||
rex.line,
|
rex.line,
|
||||||
(colnr_T)(rex.input - rex.line)) + 1,
|
(colnr_T)(rex.input - rex.line)) + 1,
|
||||||
scan)) {
|
scan)) {
|
||||||
|
@ -6910,7 +6910,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm
|
|||||||
result = col > t->state->val * ts;
|
result = col > t->state->val * ts;
|
||||||
}
|
}
|
||||||
if (!result) {
|
if (!result) {
|
||||||
uintmax_t lts = win_linetabsize(wp, rex.line, col);
|
uintmax_t lts = win_linetabsize(wp, rex.reg_firstlnum + rex.lnum, rex.line, col);
|
||||||
assert(t->state->val >= 0);
|
assert(t->state->val >= 0);
|
||||||
result = nfa_re_num_cmp((uintmax_t)t->state->val, op, lts + 1);
|
result = nfa_re_num_cmp((uintmax_t)t->state->val, op, lts + 1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user