Patch 8.2.0861
Problem: Cannot easily get all the current marks.
Solution: Add getmarklist(). (Yegappan Lakshmanan, closes #6032)
Files: runtime/doc/eval.txt, runtime/doc/usr_41.txt, src/evalfunc.c,
src/mark.c, src/proto/mark.pro, src/testdir/test_marks.vim
*** ../vim-8.2.0860/runtime/doc/eval.txt 2020-05-30 21:52:49.238816739
+0200
--- runtime/doc/eval.txt 2020-05-31 15:36:50.376200139 +0200
***************
*** 2491,2496 ****
--- 2497,2503 ----
getline({lnum}) String line {lnum} of current buffer
getline({lnum}, {end}) List lines {lnum} to {end} of
current buffer
getloclist({nr} [, {what}]) List list of location list items
+ getmarklist([{expr}]) List list of global/local marks
getmatches([{win}]) List list of current matches
getmousepos() Dict last known mouse position
getpid() Number process ID of Vim
***************
*** 5355,5360 ****
--- 5366,5390 ----
|location-list-file-window| for more
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()*
Returns a |List| with all matches previously defined for the
current window by |matchadd()| and the |:match| commands.
*** ../vim-8.2.0860/runtime/doc/usr_41.txt 2020-03-15 16:12:16.548208667
+0100
--- runtime/doc/usr_41.txt 2020-05-31 15:29:55.977504175 +0200
***************
*** 724,729 ****
--- 727,733 ----
getcurpos() get position of the cursor
getpos() get 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
line2byte() byte count at a specific line
diff_filler() get the number of filler lines above a line
*** ../vim-8.2.0860/src/evalfunc.c 2020-05-30 18:14:37.824521074 +0200
--- src/evalfunc.c 2020-05-31 15:29:55.981504159 +0200
***************
*** 579,584 ****
--- 579,585 ----
{"getjumplist", 0, 2, FEARG_1, ret_list_any, f_getjumplist},
{"getline", 1, 2, FEARG_1, ret_f_getline, f_getline},
{"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},
{"getmousepos", 0, 0, 0, ret_dict_number, f_getmousepos},
{"getpid", 0, 0, 0, ret_number, f_getpid},
*** ../vim-8.2.0860/src/mark.c 2019-12-27 17:33:23.475080942 +0100
--- src/mark.c 2020-05-31 15:29:55.981504159 +0200
***************
*** 1412,1414 ****
--- 1412,1535 ----
{
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
*** ../vim-8.2.0860/src/proto/mark.pro 2019-12-12 12:55:26.000000000 +0100
--- src/proto/mark.pro 2020-05-31 15:40:05.231523743 +0200
***************
*** 27,30 ****
--- 27,31 ----
void set_last_cursor(win_T *win);
void free_all_marks(void);
xfmark_T *get_namedfm(void);
+ void f_getmarklist(typval_T *argvars, typval_T *rettv);
/* vim: set ft=c : */
*** ../vim-8.2.0860/src/testdir/test_marks.vim 2020-04-09 18:42:08.358066443
+0200
--- src/testdir/test_marks.vim 2020-05-31 15:29:55.981504159 +0200
***************
*** 259,262 ****
--- 259,287 ----
call delete('Xtwo')
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-8.2.0860/src/version.c 2020-05-31 15:08:55.118721233 +0200
--- src/version.c 2020-05-31 15:40:22.511462518 +0200
***************
*** 748,749 ****
--- 748,751 ----
{ /* Add new patch number below this line */
+ /**/
+ 861,
/**/
--
A computer without Windows is like a fish without a bicycle.
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/vim_dev/202005311342.04VDgSTa628699%40masaka.moolenaar.net.