aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVanaIgr <vanaigranov@gmail.com>2023-12-13 13:54:28 -0600
committerVanaIgr <vanaigranov@gmail.com>2024-01-18 21:30:48 -0600
commit2f2f12122f3883dc6faf25751e176646f044db77 (patch)
treee4a81c5d4f5712f4cbde6220e30b936f59879132
parenta9c551e5e38f484e9055a930b3feaa9ac65d07be (diff)
downloadrneovim-2f2f12122f3883dc6faf25751e176646f044db77.tar.gz
rneovim-2f2f12122f3883dc6faf25751e176646f044db77.tar.bz2
rneovim-2f2f12122f3883dc6faf25751e176646f044db77.zip
perf: remove loop for computing last position in getvcol()
The function computed the start of the multibyte character and iterated until the current character reached this position. The loop at the start of the function handed the case where the index passed to the function was past the end of the line. This loop can be removed if the function instead compares the next position against the end position end exits the loop if it is greater than the end position.
-rw-r--r--src/nvim/plines.c30
1 files changed, 9 insertions, 21 deletions
diff --git a/src/nvim/plines.c b/src/nvim/plines.c
index 48c43e155e..13b580b142 100644
--- a/src/nvim/plines.c
+++ b/src/nvim/plines.c
@@ -493,7 +493,6 @@ static int virt_text_cursor_off(chartabsize_T *cts, bool on_NUL)
void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end)
{
char *ptr; // points to current char
- char *posptr; // points to char at pos->col
int incr;
int head;
colnr_T *vts = wp->w_buffer->b_p_vts_array;
@@ -502,21 +501,10 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en
colnr_T vcol = 0;
char *line = ptr = ml_get_buf(wp->w_buffer, pos->lnum); // start of the line
- if (pos->col == MAXCOL) {
- // continue until the NUL
- posptr = NULL;
- } else {
- // In a few cases the position can be beyond the end of the line.
- for (colnr_T i = 0; i < pos->col; i++) {
- if (ptr[i] == NUL) {
- pos->col = i;
- break;
- }
- }
- posptr = ptr + pos->col;
- posptr -= utf_head_off(line, posptr);
+ uintptr_t last_pos = (uintptr_t)(ptr + pos->col);
+ if (last_pos < (uintptr_t)ptr) {
+ last_pos = UINTPTR_MAX; // unsigned overflow
}
-
chartabsize_T cts;
bool on_NUL = false;
init_chartabsize_arg(&cts, wp, pos->lnum, 0, line, line);
@@ -566,13 +554,13 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en
}
}
- if ((posptr != NULL) && (ptr >= posptr)) {
- // character at pos->col
+ char *const next = ptr + utfc_ptr2len(ptr);
+ if ((uintptr_t)next > last_pos) {
break;
}
+ ptr = next;
vcol += incr;
- MB_PTR_ADV(ptr);
}
} else {
while (true) {
@@ -589,13 +577,13 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en
break;
}
- if ((posptr != NULL) && (cts.cts_ptr >= posptr)) {
- // character at pos->col
+ char *const next = cts.cts_ptr + utfc_ptr2len(cts.cts_ptr);
+ if ((uintptr_t)next > last_pos) {
break;
}
+ cts.cts_ptr = next;
cts.cts_vcol += incr;
- MB_PTR_ADV(cts.cts_ptr);
}
vcol = cts.cts_vcol;
ptr = cts.cts_ptr;