mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 8.2.0861: cannot easily get all the current marks
Problem: Cannot easily get all the current marks. Solution: Add getmarklist(). (Yegappan Lakshmanan, closes #6032)
This commit is contained in:
parent
aaad995f83
commit
cfb4b47de0
@ -2497,6 +2497,7 @@ getjumplist([{winnr} [, {tabnr}]])
|
|||||||
getline({lnum}) String line {lnum} of current buffer
|
getline({lnum}) String line {lnum} of current buffer
|
||||||
getline({lnum}, {end}) List lines {lnum} to {end} of current buffer
|
getline({lnum}, {end}) List lines {lnum} to {end} of current buffer
|
||||||
getloclist({nr} [, {what}]) List list of location list items
|
getloclist({nr} [, {what}]) List list of location list items
|
||||||
|
getmarklist([{expr}]) List list of global/local marks
|
||||||
getmatches([{win}]) List list of current matches
|
getmatches([{win}]) List list of current matches
|
||||||
getmousepos() Dict last known mouse position
|
getmousepos() Dict last known mouse position
|
||||||
getpid() Number process ID of Vim
|
getpid() Number process ID of Vim
|
||||||
@ -5365,6 +5366,25 @@ getloclist({nr} [, {what}]) *getloclist()*
|
|||||||
|location-list-file-window| for more
|
|location-list-file-window| for more
|
||||||
details.
|
details.
|
||||||
|
|
||||||
|
getmarklist([{expr}] *getmarklist()*
|
||||||
|
Without the {expr} argument returns a |List| with information
|
||||||
|
about all the global marks. |mark|
|
||||||
|
|
||||||
|
If the optional {expr} argument is specified, returns the
|
||||||
|
local marks defined in buffer {expr}. For the use of {expr},
|
||||||
|
see |bufname()|.
|
||||||
|
|
||||||
|
Each item in the retuned List is a |Dict| with the following:
|
||||||
|
name - name of the mark prefixed by "'"
|
||||||
|
pos - a |List| with the position of the mark:
|
||||||
|
[bufnum, lnum, col, off]
|
||||||
|
Refer to |getpos()| for more information.
|
||||||
|
file - file name
|
||||||
|
|
||||||
|
Refer to |getpos()| for getting information about a specific
|
||||||
|
mark.
|
||||||
|
|
||||||
|
|
||||||
getmatches([{win}]) *getmatches()*
|
getmatches([{win}]) *getmatches()*
|
||||||
Returns a |List| with all matches previously defined for the
|
Returns a |List| with all matches previously defined for the
|
||||||
current window by |matchadd()| and the |:match| commands.
|
current window by |matchadd()| and the |:match| commands.
|
||||||
|
@ -724,6 +724,7 @@ Cursor and mark position: *cursor-functions* *mark-functions*
|
|||||||
getcurpos() get position of the cursor
|
getcurpos() get position of the cursor
|
||||||
getpos() get position of cursor, mark, etc.
|
getpos() get position of cursor, mark, etc.
|
||||||
setpos() set position of cursor, mark, etc.
|
setpos() set position of cursor, mark, etc.
|
||||||
|
getmarklist() list of global/local marks
|
||||||
byte2line() get line number at a specific byte count
|
byte2line() get line number at a specific byte count
|
||||||
line2byte() byte count at a specific line
|
line2byte() byte count at a specific line
|
||||||
diff_filler() get the number of filler lines above a line
|
diff_filler() get the number of filler lines above a line
|
||||||
|
@ -579,6 +579,7 @@ static funcentry_T global_functions[] =
|
|||||||
{"getjumplist", 0, 2, FEARG_1, ret_list_any, f_getjumplist},
|
{"getjumplist", 0, 2, FEARG_1, ret_list_any, f_getjumplist},
|
||||||
{"getline", 1, 2, FEARG_1, ret_f_getline, f_getline},
|
{"getline", 1, 2, FEARG_1, ret_f_getline, f_getline},
|
||||||
{"getloclist", 1, 2, 0, ret_list_dict_any, f_getloclist},
|
{"getloclist", 1, 2, 0, ret_list_dict_any, f_getloclist},
|
||||||
|
{"getmarklist", 0, 1, 0, ret_list_dict_any, f_getmarklist},
|
||||||
{"getmatches", 0, 1, 0, ret_list_dict_any, f_getmatches},
|
{"getmatches", 0, 1, 0, ret_list_dict_any, f_getmatches},
|
||||||
{"getmousepos", 0, 0, 0, ret_dict_number, f_getmousepos},
|
{"getmousepos", 0, 0, 0, ret_dict_number, f_getmousepos},
|
||||||
{"getpid", 0, 0, 0, ret_number, f_getpid},
|
{"getpid", 0, 0, 0, ret_number, f_getpid},
|
||||||
|
121
src/mark.c
121
src/mark.c
@ -1412,3 +1412,124 @@ get_namedfm(void)
|
|||||||
{
|
{
|
||||||
return namedfm;
|
return namedfm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(FEAT_EVAL) || defined(PROTO)
|
||||||
|
/*
|
||||||
|
* Add information about mark 'mname' to list 'l'
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
add_mark(list_T *l, char_u *mname, pos_T *pos, int bufnr, char_u *fname)
|
||||||
|
{
|
||||||
|
dict_T *d;
|
||||||
|
list_T *lpos;
|
||||||
|
|
||||||
|
if (pos->lnum <= 0)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
d = dict_alloc();
|
||||||
|
if (d == NULL)
|
||||||
|
return FAIL;
|
||||||
|
|
||||||
|
if (list_append_dict(l, d) == FAIL)
|
||||||
|
{
|
||||||
|
dict_unref(d);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
lpos = list_alloc();
|
||||||
|
if (lpos == NULL)
|
||||||
|
return FAIL;
|
||||||
|
|
||||||
|
list_append_number(lpos, bufnr);
|
||||||
|
list_append_number(lpos, pos->lnum);
|
||||||
|
list_append_number(lpos, pos->col);
|
||||||
|
list_append_number(lpos, pos->coladd);
|
||||||
|
|
||||||
|
if (dict_add_string(d, "mark", mname) == FAIL
|
||||||
|
|| dict_add_list(d, "pos", lpos) == FAIL
|
||||||
|
|| (fname != NULL && dict_add_string(d, "file", fname) == FAIL))
|
||||||
|
return FAIL;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get information about marks local to a buffer.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
get_buf_local_marks(buf_T *buf, list_T *l)
|
||||||
|
{
|
||||||
|
char_u mname[3] = "' ";
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// Marks 'a' to 'z'
|
||||||
|
for (i = 0; i < NMARKS; ++i)
|
||||||
|
{
|
||||||
|
mname[1] = 'a' + i;
|
||||||
|
add_mark(l, mname, &buf->b_namedm[i], buf->b_fnum, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark '' is a window local mark and not a buffer local mark
|
||||||
|
add_mark(l, (char_u *)"''", &curwin->w_pcmark, curbuf->b_fnum, NULL);
|
||||||
|
|
||||||
|
add_mark(l, (char_u *)"'\"", &buf->b_last_cursor, buf->b_fnum, NULL);
|
||||||
|
add_mark(l, (char_u *)"'[", &buf->b_op_start, buf->b_fnum, NULL);
|
||||||
|
add_mark(l, (char_u *)"']", &buf->b_op_end, buf->b_fnum, NULL);
|
||||||
|
add_mark(l, (char_u *)"'^", &buf->b_last_insert, buf->b_fnum, NULL);
|
||||||
|
add_mark(l, (char_u *)"'.", &buf->b_last_change, buf->b_fnum, NULL);
|
||||||
|
add_mark(l, (char_u *)"'<", &buf->b_visual.vi_start, buf->b_fnum, NULL);
|
||||||
|
add_mark(l, (char_u *)"'>", &buf->b_visual.vi_end, buf->b_fnum, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get information about global marks ('A' to 'Z' and '0' to '9')
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
get_global_marks(list_T *l)
|
||||||
|
{
|
||||||
|
char_u mname[3] = "' ";
|
||||||
|
int i;
|
||||||
|
char_u *name;
|
||||||
|
|
||||||
|
// Marks 'A' to 'Z' and '0' to '9'
|
||||||
|
for (i = 0; i < NMARKS + EXTRA_MARKS; ++i)
|
||||||
|
{
|
||||||
|
if (namedfm[i].fmark.fnum != 0)
|
||||||
|
name = buflist_nr2name(namedfm[i].fmark.fnum, TRUE, TRUE);
|
||||||
|
else
|
||||||
|
name = namedfm[i].fname;
|
||||||
|
if (name != NULL)
|
||||||
|
{
|
||||||
|
mname[1] = i >= NMARKS ? i - NMARKS + '0' : i + 'A';
|
||||||
|
add_mark(l, mname, &namedfm[i].fmark.mark,
|
||||||
|
namedfm[i].fmark.fnum, name);
|
||||||
|
if (namedfm[i].fmark.fnum != 0)
|
||||||
|
vim_free(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getmarklist() function
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
f_getmarklist(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
buf_T *buf = NULL;
|
||||||
|
|
||||||
|
if (rettv_list_alloc(rettv) != OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (argvars[0].v_type == VAR_UNKNOWN)
|
||||||
|
{
|
||||||
|
get_global_marks(rettv->vval.v_list);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = tv_get_buf(&argvars[0], FALSE);
|
||||||
|
if (buf == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
get_buf_local_marks(buf, rettv->vval.v_list);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@ -27,4 +27,5 @@ void free_jumplist(win_T *wp);
|
|||||||
void set_last_cursor(win_T *win);
|
void set_last_cursor(win_T *win);
|
||||||
void free_all_marks(void);
|
void free_all_marks(void);
|
||||||
xfmark_T *get_namedfm(void);
|
xfmark_T *get_namedfm(void);
|
||||||
|
void f_getmarklist(typval_T *argvars, typval_T *rettv);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
@ -259,4 +259,29 @@ func Test_file_mark()
|
|||||||
call delete('Xtwo')
|
call delete('Xtwo')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" Test for the getmarklist() function
|
||||||
|
func Test_getmarklist()
|
||||||
|
new
|
||||||
|
" global marks
|
||||||
|
delmarks A-Z 0-9 \" ^.[]
|
||||||
|
call assert_equal([], getmarklist())
|
||||||
|
call setline(1, ['one', 'two', 'three'])
|
||||||
|
mark A
|
||||||
|
call cursor(3, 5)
|
||||||
|
normal mN
|
||||||
|
call assert_equal([{'file' : '', 'mark' : "'A", 'pos' : [bufnr(), 1, 0, 0]},
|
||||||
|
\ {'file' : '', 'mark' : "'N", 'pos' : [bufnr(), 3, 4, 0]}],
|
||||||
|
\ getmarklist())
|
||||||
|
" buffer local marks
|
||||||
|
delmarks!
|
||||||
|
call assert_equal([{'mark' : "''", 'pos' : [bufnr(), 1, 0, 0]},
|
||||||
|
\ {'mark' : "'\"", 'pos' : [bufnr(), 1, 0, 0]}], getmarklist(bufnr()))
|
||||||
|
call cursor(2, 2)
|
||||||
|
normal mr
|
||||||
|
call assert_equal({'mark' : "'r", 'pos' : [bufnr(), 2, 1, 0]},
|
||||||
|
\ getmarklist(bufnr())[0])
|
||||||
|
call assert_equal([], getmarklist({}))
|
||||||
|
close!
|
||||||
|
endfunc
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2 expandtab
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
@ -746,6 +746,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
861,
|
||||||
/**/
|
/**/
|
||||||
860,
|
860,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user