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.

Raspunde prin e-mail lui