mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 8.2.2324: not easy to get mark en cursor posotion by character count
Problem: Not easy to get mark en cursor posotion by character count. Solution: Add functions that use character index. (Yegappan Lakshmanan, closes #7648)
This commit is contained in:
100
src/eval.c
100
src/eval.c
@@ -5053,6 +5053,61 @@ string2float(
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
int
|
||||
buf_byteidx_to_charidx(buf_T *buf, int lnum, int byteidx)
|
||||
{
|
||||
char_u *str;
|
||||
|
||||
if (buf == NULL || buf->b_ml.ml_mfp == NULL)
|
||||
return -1;
|
||||
|
||||
if (lnum > buf->b_ml.ml_line_count)
|
||||
lnum = buf->b_ml.ml_line_count;
|
||||
|
||||
str = ml_get_buf(buf, lnum, FALSE);
|
||||
if (str == NULL)
|
||||
return -1;
|
||||
|
||||
if (*str == NUL)
|
||||
return 1;
|
||||
|
||||
return mb_charlen_len(str, byteidx + 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.
|
||||
*/
|
||||
int
|
||||
buf_charidx_to_byteidx(buf_T *buf, int lnum, int charidx)
|
||||
{
|
||||
char_u *str;
|
||||
char_u *t;
|
||||
|
||||
if (buf == NULL || buf->b_ml.ml_mfp == NULL)
|
||||
return -1;
|
||||
|
||||
if (lnum > buf->b_ml.ml_line_count)
|
||||
lnum = buf->b_ml.ml_line_count;
|
||||
|
||||
str = ml_get_buf(buf, lnum, FALSE);
|
||||
if (str == NULL)
|
||||
return -1;
|
||||
|
||||
// Convert the character offset to a byte offset
|
||||
t = str;
|
||||
while (*t != NUL && --charidx > 0)
|
||||
t += mb_ptr2len(t);
|
||||
|
||||
return t - str + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate a String variable into a position.
|
||||
* Returns NULL when there is an error.
|
||||
@@ -5061,7 +5116,8 @@ string2float(
|
||||
var2fpos(
|
||||
typval_T *varp,
|
||||
int dollar_lnum, // TRUE when $ is last line
|
||||
int *fnum) // set to fnum for '0, 'A, etc.
|
||||
int *fnum, // set to fnum for '0, 'A, etc.
|
||||
int charcol) // return character column
|
||||
{
|
||||
char_u *name;
|
||||
static pos_T pos;
|
||||
@@ -5083,7 +5139,10 @@ var2fpos(
|
||||
pos.lnum = list_find_nr(l, 0L, &error);
|
||||
if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count)
|
||||
return NULL; // invalid line number
|
||||
len = (long)STRLEN(ml_get(pos.lnum));
|
||||
if (charcol)
|
||||
len = (long)mb_charlen(ml_get(pos.lnum));
|
||||
else
|
||||
len = (long)STRLEN(ml_get(pos.lnum));
|
||||
|
||||
// Get the column number
|
||||
// We accept "$" for the column number: last column.
|
||||
@@ -5118,18 +5177,29 @@ var2fpos(
|
||||
if (name == NULL)
|
||||
return NULL;
|
||||
if (name[0] == '.') // cursor
|
||||
return &curwin->w_cursor;
|
||||
{
|
||||
pos = curwin->w_cursor;
|
||||
if (charcol)
|
||||
pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col) - 1;
|
||||
return &pos;
|
||||
}
|
||||
if (name[0] == 'v' && name[1] == NUL) // Visual start
|
||||
{
|
||||
if (VIsual_active)
|
||||
return &VIsual;
|
||||
return &curwin->w_cursor;
|
||||
pos = VIsual;
|
||||
else
|
||||
pos = curwin->w_cursor;
|
||||
if (charcol)
|
||||
pos.col = buf_byteidx_to_charidx(curbuf, pos.lnum, pos.col) - 1;
|
||||
return &pos;
|
||||
}
|
||||
if (name[0] == '\'') // mark
|
||||
{
|
||||
pp = getmark_buf_fnum(curbuf, name[1], FALSE, fnum);
|
||||
if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0)
|
||||
return NULL;
|
||||
if (charcol)
|
||||
pp->col = buf_byteidx_to_charidx(curbuf, pp->lnum, pp->col) - 1;
|
||||
return pp;
|
||||
}
|
||||
|
||||
@@ -5164,7 +5234,10 @@ var2fpos(
|
||||
else
|
||||
{
|
||||
pos.lnum = curwin->w_cursor.lnum;
|
||||
pos.col = (colnr_T)STRLEN(ml_get_curline());
|
||||
if (charcol)
|
||||
pos.col = (colnr_T)mb_charlen(ml_get_curline());
|
||||
else
|
||||
pos.col = (colnr_T)STRLEN(ml_get_curline());
|
||||
}
|
||||
return &pos;
|
||||
}
|
||||
@@ -5184,7 +5257,8 @@ list2fpos(
|
||||
typval_T *arg,
|
||||
pos_T *posp,
|
||||
int *fnump,
|
||||
colnr_T *curswantp)
|
||||
colnr_T *curswantp,
|
||||
int charcol)
|
||||
{
|
||||
list_T *l = arg->vval.v_list;
|
||||
long i = 0;
|
||||
@@ -5216,6 +5290,18 @@ list2fpos(
|
||||
n = list_find_nr(l, i++, NULL); // col
|
||||
if (n < 0)
|
||||
return FAIL;
|
||||
// If character position is specified, then convert to byte position
|
||||
if (charcol)
|
||||
{
|
||||
buf_T *buf;
|
||||
|
||||
// Get the text for the specified line in a loaded buffer
|
||||
buf = buflist_findnr(fnump == NULL ? curbuf->b_fnum : *fnump);
|
||||
if (buf == NULL || buf->b_ml.ml_mfp == NULL)
|
||||
return FAIL;
|
||||
|
||||
n = buf_charidx_to_byteidx(buf, posp->lnum, n);
|
||||
}
|
||||
posp->col = n;
|
||||
|
||||
n = list_find_nr(l, i, NULL); // off
|
||||
|
Reference in New Issue
Block a user