diff options
Diffstat (limited to 'src/nvim/eval.c')
-rw-r--r-- | src/nvim/eval.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 4b83bda804..07f0799bc4 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -8192,7 +8192,7 @@ char *save_tv_as_string(typval_T *tv, ptrdiff_t *const len, bool endnl) /// Convert the specified byte index of line 'lnum' in buffer 'buf' to a /// character index. Works only for loaded buffers. Returns -1 on failure. -/// The index of the first character is one. +/// The index of the first byte and the first character is zero. int buf_byteidx_to_charidx(buf_T *buf, int lnum, int byteidx) { if (buf == NULL || buf->b_ml.ml_mfp == NULL) { @@ -8206,15 +8206,29 @@ int buf_byteidx_to_charidx(buf_T *buf, int lnum, int byteidx) char_u *str = ml_get_buf(buf, lnum, false); if (*str == NUL) { - return 1; + return 0; + } + + // count the number of characters + char_u *t = str; + int count; + for (count = 0; *t != NUL && t <= str + byteidx; count++) { + t += utfc_ptr2len(t); + } + + // In insert mode, when the cursor is at the end of a non-empty line, + // byteidx points to the NUL character immediately past the end of the + // string. In this case, add one to the character count. + if (*t == NUL && byteidx != 0 && t == str + byteidx) { + count++; } - return mb_charlen_len(str, byteidx + 1); + return count - 1; } /// Convert the specified character index of line 'lnum' in buffer 'buf' to a -/// byte index. Works only for loaded buffers. Returns -1 on failure. The index -/// of the first byte and the first character is one. +/// byte index. Works only for loaded buffers. Returns -1 on failure. +/// The index of the first byte and the first character is zero. int buf_charidx_to_byteidx(buf_T *buf, int lnum, int charidx) { if (buf == NULL || buf->b_ml.ml_mfp == NULL) { @@ -8233,7 +8247,7 @@ int buf_charidx_to_byteidx(buf_T *buf, int lnum, int charidx) t += utfc_ptr2len(t); } - return t - str + 1; + return t - str; } /// Translate a VimL object into a position @@ -8315,7 +8329,7 @@ pos_T *var2fpos(const typval_T *const tv, const bool dollar_lnum, int *const ret if (name[0] == '.') { // Cursor. pos = curwin->w_cursor; if (charcol) { - pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col) - 1; + pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col); } return &pos; } @@ -8326,7 +8340,7 @@ pos_T *var2fpos(const typval_T *const tv, const bool dollar_lnum, int *const ret pos = curwin->w_cursor; } if (charcol) { - pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col) - 1; + pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col); } return &pos; } @@ -8336,7 +8350,7 @@ pos_T *var2fpos(const typval_T *const tv, const bool dollar_lnum, int *const ret return NULL; } if (charcol) { - pp->col = buf_byteidx_to_charidx(curbuf, pp->lnum, pp->col) - 1; + pp->col = buf_byteidx_to_charidx(curbuf, pp->lnum, pp->col); } return pp; } @@ -8423,7 +8437,7 @@ int list2fpos(typval_T *arg, pos_T *posp, int *fnump, colnr_T *curswantp, bool c if (buf == NULL || buf->b_ml.ml_mfp == NULL) { return FAIL; } - n = buf_charidx_to_byteidx(buf, posp->lnum, n); + n = buf_charidx_to_byteidx(buf, posp->lnum, n) + 1; } posp->col = n; |