]> granicus.if.org Git - vim/commitdiff
patch 8.1.0717: there is no function for the ":sign jump" command v8.1.0717
authorBram Moolenaar <Bram@vim.org>
Fri, 11 Jan 2019 12:42:41 +0000 (13:42 +0100)
committerBram Moolenaar <Bram@vim.org>
Fri, 11 Jan 2019 12:42:41 +0000 (13:42 +0100)
Problem:    There is no function for the ":sign jump" command.
Solution:   Add the sign_jump() function. (Yegappan Lakshmanan, closes #3780)

runtime/doc/eval.txt
runtime/doc/sign.txt
runtime/doc/usr_41.txt
src/evalfunc.c
src/proto/sign.pro
src/sign.c
src/testdir/test_signs.vim
src/version.c

index 1278c97a2ca33bca9f3df42d64415863c093bda5..236f65ce0d06c20d820e839a0cad1e9e54f9e2bc 100644 (file)
@@ -2412,6 +2412,8 @@ sign_define({name} [, {dict}])    Number  define or update a sign
 sign_getdefined([{name}])      List    get a list of defined signs
 sign_getplaced([{expr} [, {dict}]])
                                List    get a list of placed signs
+sign_jump({id}, {group}, {expr})
+                               Number  jump to a sign
 sign_place({id}, {group}, {name}, {expr} [, {dict}])
                                Number  place a sign
 sign_undefine([{name}])                Number  undefine a sign
@@ -7997,6 +7999,21 @@ sign_getplaced([{expr} [, {dict}]])                      *sign_getplaced()*
 
                        " Get a List of all the placed signs
                        echo sign_getplaced()
+<
+                                                       *sign_jump()*
+sign_jump({id}, {group}, {expr})
+               Open the buffer {expr} or jump to the window that contains
+               {expr} and position the cursor at sign {id} in group {group}.
+               This is similar to the |:sign-jump| command.
+
+               For the use of {expr}, see |bufname()|.
+
+               Returns the line number of the sign. Returns -1 if the
+               arguments are invalid.
+
+               Example: >
+                       " Jump to sign 10 in the current buffer
+                       call sign_jump(10, '', '')
 <
                                                        *sign_place()*
 sign_place({id}, {group}, {name}, {expr} [, {dict}])
index 6eb11a052dde83bc031198744dd99551774d41a9..7b33a2da321daab2886fd34833b4bb680e9cfb3c 100644 (file)
@@ -263,13 +263,13 @@ See |sign_unplace()| for the equivalent Vim script function.
                all the files it appears in.
 
 :sign unplace *
-               Remove placed signs in the global group from all the files.
+               Remove all placed signs in the global group from all the files.
 
 :sign unplace * group={group}
-               Remove placed signs in group {group} from all the files.
+               Remove all placed signs in group {group} from all the files.
 
 :sign unplace * group=*
-               Remove placed signs in all the groups from all the files.
+               Remove all placed signs in all the groups from all the files.
 
 :sign unplace
                Remove a placed sign at the cursor position. If multiple signs
@@ -317,6 +317,8 @@ See |sign_getplaced()| for the equivalent Vim script function.
 
 JUMPING TO A SIGN                                      *:sign-jump* *E157*
 
+See |sign_jump()| for the equivalent Vim script function.
+
 :sign jump {id} file={fname}
                Open the file {fname} or jump to the window that contains
                {fname} and position the cursor at sign {id}.
index 343d476a4c76cc5fb3db516fc7e31128c99048f6..c7bfffdc54741e43245c6221c3b936fa172537bd 100644 (file)
@@ -987,6 +987,7 @@ Signs:                                              *sign-functions*
        sign_define()           define or update a sign
        sign_getdefined()       get a list of defined signs
        sign_getplaced()        get a list of placed signs
+       sign_jump()             jump to a sign
        sign_place()            place a sign
        sign_undefine()         undefine a sign
        sign_unplace()          unplace a sign
index cd0888b626acd143bd465cec885cf5286df75f04..e74a3c95fdf200779994072f7afcca8763de73cc 100644 (file)
@@ -371,6 +371,7 @@ static void f_shiftwidth(typval_T *argvars, typval_T *rettv);
 static void f_sign_define(typval_T *argvars, typval_T *rettv);
 static void f_sign_getdefined(typval_T *argvars, typval_T *rettv);
 static void f_sign_getplaced(typval_T *argvars, typval_T *rettv);
+static void f_sign_jump(typval_T *argvars, typval_T *rettv);
 static void f_sign_place(typval_T *argvars, typval_T *rettv);
 static void f_sign_undefine(typval_T *argvars, typval_T *rettv);
 static void f_sign_unplace(typval_T *argvars, typval_T *rettv);
@@ -858,6 +859,7 @@ static struct fst
     {"sign_define",    1, 2, f_sign_define},
     {"sign_getdefined",        0, 1, f_sign_getdefined},
     {"sign_getplaced", 0, 2, f_sign_getplaced},
+    {"sign_jump",      3, 3, f_sign_jump},
     {"sign_place",     4, 5, f_sign_place},
     {"sign_undefine",  0, 1, f_sign_undefine},
     {"sign_unplace",   1, 2, f_sign_unplace},
@@ -1917,6 +1919,23 @@ tv_get_buf(typval_T *tv, int curtab_only)
     return buf;
 }
 
+/*
+ * Get the buffer from "arg" and give an error and return NULL if it is not
+ * valid.
+ */
+    static buf_T *
+get_buf_arg(typval_T *arg)
+{
+    buf_T *buf;
+
+    ++emsg_off;
+    buf = tv_get_buf(arg, FALSE);
+    --emsg_off;
+    if (buf == NULL)
+       EMSG2(_("E158: Invalid buffer name: %s"), tv_get_string(arg));
+    return buf;
+}
+
 /*
  * "bufname(expr)" function
  */
@@ -11366,14 +11385,10 @@ f_sign_getplaced(typval_T *argvars, typval_T *rettv)
 
     if (argvars[0].v_type != VAR_UNKNOWN)
     {
-       // get signs placed in this buffer
-       buf = tv_get_buf(&argvars[0], FALSE);
+       // get signs placed in the specified buffer
+       buf = get_buf_arg(&argvars[0]);
        if (buf == NULL)
-       {
-           EMSG2(_("E158: Invalid buffer name: %s"),
-                                               tv_get_string(&argvars[0]));
            return;
-       }
 
        if (argvars[1].v_type != VAR_UNKNOWN)
        {
@@ -11412,6 +11427,53 @@ f_sign_getplaced(typval_T *argvars, typval_T *rettv)
     sign_get_placed(buf, lnum, sign_id, group, rettv->vval.v_list);
 }
 
+/*
+ * "sign_jump()" function
+ */
+    static void
+f_sign_jump(typval_T *argvars, typval_T *rettv)
+{
+    int                sign_id;
+    char_u     *sign_group = NULL;
+    buf_T      *buf;
+    int                notanum = FALSE;
+
+    rettv->vval.v_number = -1;
+
+    // Sign identifer
+    sign_id = (int)tv_get_number_chk(&argvars[0], &notanum);
+    if (notanum)
+       return;
+    if (sign_id <= 0)
+    {
+       EMSG(_(e_invarg));
+       return;
+    }
+
+    // Sign group
+    sign_group = tv_get_string_chk(&argvars[1]);
+    if (sign_group == NULL)
+       return;
+    if (sign_group[0] == '\0')
+       sign_group = NULL;                      // global sign group
+    else
+    {
+       sign_group = vim_strsave(sign_group);
+       if (sign_group == NULL)
+           return;
+    }
+
+    // Buffer to place the sign
+    buf = get_buf_arg(&argvars[2]);
+    if (buf == NULL)
+       goto cleanup;
+
+    rettv->vval.v_number = sign_jump(sign_id, sign_group, buf);
+
+cleanup:
+    vim_free(sign_group);
+}
+
 /*
  * "sign_place()" function
  */
@@ -11459,12 +11521,9 @@ f_sign_place(typval_T *argvars, typval_T *rettv)
        goto cleanup;
 
     // Buffer to place the sign
-    buf = tv_get_buf(&argvars[3], FALSE);
+    buf = get_buf_arg(&argvars[3]);
     if (buf == NULL)
-    {
-       EMSG2(_("E158: Invalid buffer name: %s"), tv_get_string(&argvars[3]));
        goto cleanup;
-    }
 
     if (argvars[4].v_type != VAR_UNKNOWN)
     {
@@ -11568,13 +11627,9 @@ f_sign_unplace(typval_T *argvars, typval_T *rettv)
 
        if ((di = dict_find(dict, (char_u *)"buffer", -1)) != NULL)
        {
-           buf = tv_get_buf(&di->di_tv, FALSE);
+           buf = get_buf_arg(&di->di_tv);
            if (buf == NULL)
-           {
-               EMSG2(_("E158: Invalid buffer name: %s"),
-                                               tv_get_string(&di->di_tv));
                goto cleanup;
-           }
        }
        if (dict_find(dict, (char_u *)"id", -1) != NULL)
            sign_id = dict_get_number(dict, (char_u *)"id");
index 6470f52f81de7c4c1654860acbadea84a372cb99..ef9f71ad208b8b358727af296811e7543c0bba9e 100644 (file)
@@ -11,6 +11,7 @@ void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_a
 int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text, char_u *texthl);
 int sign_undefine_by_name(char_u *name);
 int sign_place(int *sign_id, char_u *sign_group, char_u *sign_name, buf_T *buf, linenr_T lnum, int prio);
+linenr_T sign_jump(int sign_id, char_u *sign_group, buf_T *buf);
 int sign_unplace(int sign_id, char_u *sign_group, buf_T *buf, linenr_T atlnum);
 void ex_sign(exarg_T *eap);
 void sign_getlist(char_u *name, list_T *retlist);
index 2cb39a5e1f52c5d9a127c5fec9f2adb65d088628..53a90f8aa45019ae4ed0e046494f55f8491e8d9c 100644 (file)
@@ -22,16 +22,16 @@ typedef struct sign sign_T;
 
 struct sign
 {
-    sign_T     *sn_next;       /* next sign in list */
-    int                sn_typenr;      /* type number of sign */
-    char_u     *sn_name;       /* name of sign */
-    char_u     *sn_icon;       /* name of pixmap */
+    sign_T     *sn_next;       // next sign in list
+    int                sn_typenr;      // type number of sign
+    char_u     *sn_name;       // name of sign
+    char_u     *sn_icon;       // name of pixmap
 # ifdef FEAT_SIGN_ICONS
-    void       *sn_image;      /* icon image */
+    void       *sn_image;      // icon image
 # endif
-    char_u     *sn_text;       /* text used instead of pixmap */
-    int                sn_line_hl;     /* highlight ID for line */
-    int                sn_text_hl;     /* highlight ID for text */
+    char_u     *sn_text;       // text used instead of pixmap
+    int                sn_line_hl;     // highlight ID for line
+    int                sn_text_hl;     // highlight ID for text
 };
 
 static sign_T  *first_sign = NULL;
@@ -381,9 +381,9 @@ buf_change_sign_type(
 buf_getsigntype(
     buf_T      *buf,
     linenr_T   lnum,
-    int                type)   /* SIGN_ICON, SIGN_TEXT, SIGN_ANY, SIGN_LINEHL */
+    int                type)   // SIGN_ICON, SIGN_TEXT, SIGN_ANY, SIGN_LINEHL
 {
-    signlist_T *sign;          /* a sign in a b_signlist */
+    signlist_T *sign;          // a sign in a b_signlist
 
     FOR_ALL_SIGNS_IN_BUF(buf, sign)
        if (sign->lnum == lnum
@@ -526,11 +526,11 @@ buf_findsign_id(
  */
     int
 buf_findsigntype_id(
-    buf_T      *buf,           /* buffer whose sign we are searching for */
-    linenr_T   lnum,           /* line number of sign */
-    int                typenr)         /* sign type number */
+    buf_T      *buf,           // buffer whose sign we are searching for
+    linenr_T   lnum,           // line number of sign
+    int                typenr)         // sign type number
 {
-    signlist_T *sign;          /* a sign in the signlist */
+    signlist_T *sign;          // a sign in the signlist
 
     FOR_ALL_SIGNS_IN_BUF(buf, sign)
        if (sign->lnum == lnum && sign->typenr == typenr)
@@ -656,7 +656,7 @@ sign_mark_adjust(
     long       amount,
     long       amount_after)
 {
-    signlist_T *sign;          /* a sign in a b_signlist */
+    signlist_T *sign;          // a sign in a b_signlist
 
     FOR_ALL_SIGNS_IN_BUF(curbuf, sign)
     {
@@ -678,8 +678,8 @@ sign_mark_adjust(
  */
     static int
 sign_cmd_idx(
-    char_u     *begin_cmd,     /* begin of sign subcmd */
-    char_u     *end_cmd)       /* just after sign subcmd */
+    char_u     *begin_cmd,     // begin of sign subcmd
+    char_u     *end_cmd)       // just after sign subcmd
 {
     int                idx;
     char       save = *end_cmd;
@@ -984,8 +984,51 @@ sign_unplace_at_cursor(char_u *groupname)
 }
 
 /*
- * sign define command
- *   ":sign define {name} ..."
+ * Jump to a sign.
+ */
+    linenr_T
+sign_jump(int sign_id, char_u *sign_group, buf_T *buf)
+{
+    linenr_T   lnum;
+
+    if ((lnum = buf_findsign(buf, sign_id, sign_group)) <= 0)
+    {
+       EMSGN(_("E157: Invalid sign ID: %ld"), sign_id);
+       return -1;
+    }
+
+    // goto a sign ...
+    if (buf_jump_open_win(buf) != NULL)
+    {                  // ... in a current window
+       curwin->w_cursor.lnum = lnum;
+       check_cursor_lnum();
+       beginline(BL_WHITE);
+    }
+    else
+    {                  // ... not currently in a window
+       char_u  *cmd;
+
+       if (buf->b_fname == NULL)
+       {
+           EMSG(_("E934: Cannot jump to a buffer that does not have a name"));
+           return -1;
+       }
+       cmd = alloc((unsigned)STRLEN(buf->b_fname) + 25);
+       if (cmd == NULL)
+           return -1;
+       sprintf((char *)cmd, "e +%ld %s", (long)lnum, buf->b_fname);
+       do_cmdline_cmd(cmd);
+       vim_free(cmd);
+    }
+# ifdef FEAT_FOLDING
+    foldOpenCursor();
+# endif
+
+    return lnum;
+}
+
+/*
+ * ":sign define {name} ..." command
  */
     static void
 sign_define_cmd(char_u *sign_name, char_u *cmdline)
@@ -1043,7 +1086,7 @@ sign_define_cmd(char_u *sign_name, char_u *cmdline)
 }
 
 /*
- * :sign place command
+ * ":sign place" command
  */
     static void
 sign_place_cmd(
@@ -1087,7 +1130,7 @@ sign_place_cmd(
 }
 
 /*
- * :sign unplace command
+ * ":sign unplace" command
  */
     static void
 sign_unplace_cmd(
@@ -1152,7 +1195,7 @@ sign_unplace_cmd(
 }
 
 /*
- * Jump to a placed sign
+ * Jump to a placed sign commands:
  *   :sign jump {id} file={fname}
  *   :sign jump {id} buffer={nr}
  *   :sign jump {id} group={group} file={fname}
@@ -1180,39 +1223,7 @@ sign_jump_cmd(
        EMSG(_(e_invarg));
        return;
     }
-
-    if ((lnum = buf_findsign(buf, id, group)) <= 0)
-    {
-       EMSGN(_("E157: Invalid sign ID: %ld"), id);
-       return;
-    }
-
-    // goto a sign ...
-    if (buf_jump_open_win(buf) != NULL)
-    {                  // ... in a current window
-       curwin->w_cursor.lnum = lnum;
-       check_cursor_lnum();
-       beginline(BL_WHITE);
-    }
-    else
-    {                  // ... not currently in a window
-       char_u  *cmd;
-
-       if (buf->b_fname == NULL)
-       {
-           EMSG(_("E934: Cannot jump to a buffer that does not have a name"));
-           return;
-       }
-       cmd = alloc((unsigned)STRLEN(buf->b_fname) + 25);
-       if (cmd == NULL)
-           return;
-       sprintf((char *)cmd, "e +%ld %s", (long)lnum, buf->b_fname);
-       do_cmdline_cmd(cmd);
-       vim_free(cmd);
-    }
-# ifdef FEAT_FOLDING
-    foldOpenCursor();
-# endif
+    (void)sign_jump(id, group, buf);
 }
 
 /*
@@ -1685,7 +1696,7 @@ sign_get_text(int typenr)
 # if defined(FEAT_SIGN_ICONS) || defined(PROTO)
     void *
 sign_get_image(
-    int                typenr)         /* the attribute which may have a sign */
+    int                typenr)         // the attribute which may have a sign
 {
     sign_T     *sp;
 
@@ -1709,11 +1720,11 @@ free_signs(void)
 # if defined(FEAT_CMDL_COMPL) || defined(PROTO)
 static enum
 {
-    EXP_SUBCMD,                /* expand :sign sub-commands */
-    EXP_DEFINE,                /* expand :sign define {name} args */
-    EXP_PLACE,         /* expand :sign place {id} args */
-    EXP_UNPLACE,       /* expand :sign unplace" */
-    EXP_SIGN_NAMES     /* expand with name of placed signs */
+    EXP_SUBCMD,                // expand :sign sub-commands
+    EXP_DEFINE,                // expand :sign define {name} args
+    EXP_PLACE,         // expand :sign place {id} args
+    EXP_UNPLACE,       // expand :sign unplace"
+    EXP_SIGN_NAMES     // expand with name of placed signs
 } expand_what;
 
 /*
@@ -1753,7 +1764,7 @@ get_sign_name(expand_T *xp UNUSED, int idx)
            return (char_u *)unplace_arg[idx];
        }
     case EXP_SIGN_NAMES:
-       /* Complete with name of signs already defined */
+       // Complete with name of signs already defined
        current_idx = 0;
        for (sp = first_sign; sp != NULL; sp = sp->sn_next)
            if (current_idx++ == idx)
@@ -1776,38 +1787,38 @@ set_context_in_sign_cmd(expand_T *xp, char_u *arg)
     int                cmd_idx;
     char_u     *begin_subcmd_args;
 
-    /* Default: expand subcommands. */
+    // Default: expand subcommands.
     xp->xp_context = EXPAND_SIGN;
     expand_what = EXP_SUBCMD;
     xp->xp_pattern = arg;
 
     end_subcmd = skiptowhite(arg);
     if (*end_subcmd == NUL)
-       /* expand subcmd name
-        * :sign {subcmd}<CTRL-D>*/
+       // expand subcmd name
+       // :sign {subcmd}<CTRL-D>
        return;
 
     cmd_idx = sign_cmd_idx(arg, end_subcmd);
 
-    /* :sign {subcmd} {subcmd_args}
-     *               |
-     *               begin_subcmd_args */
+    // :sign {subcmd} {subcmd_args}
+    //               |
+    //               begin_subcmd_args
     begin_subcmd_args = skipwhite(end_subcmd);
     p = skiptowhite(begin_subcmd_args);
     if (*p == NUL)
     {
-       /*
-        * Expand first argument of subcmd when possible.
-        * For ":jump {id}" and ":unplace {id}", we could
-        * possibly expand the ids of all signs already placed.
-        */
+       //
+       // Expand first argument of subcmd when possible.
+       // For ":jump {id}" and ":unplace {id}", we could
+       // possibly expand the ids of all signs already placed.
+       //
        xp->xp_pattern = begin_subcmd_args;
        switch (cmd_idx)
        {
            case SIGNCMD_LIST:
            case SIGNCMD_UNDEFINE:
-               /* :sign list <CTRL-D>
-                * :sign undefine <CTRL-D> */
+               // :sign list <CTRL-D>
+               // :sign undefine <CTRL-D>
                expand_what = EXP_SIGN_NAMES;
                break;
            default:
@@ -1816,13 +1827,13 @@ set_context_in_sign_cmd(expand_T *xp, char_u *arg)
        return;
     }
 
-    /* expand last argument of subcmd */
+    // expand last argument of subcmd
 
-    /* :sign define {name} {args}...
-     *             |
-     *             p */
+    // :sign define {name} {args}...
+    //             |
+    //             p
 
-    /* Loop until reaching last argument. */
+    // Loop until reaching last argument.
     do
     {
        p = skipwhite(p);
@@ -1832,12 +1843,12 @@ set_context_in_sign_cmd(expand_T *xp, char_u *arg)
 
     p = vim_strchr(last, '=');
 
-    /* :sign define {name} {args}... {last}=
-     *                              |     |
-     *                           last     p */
+    // :sign define {name} {args}... {last}=
+    //                              |     |
+    //                           last     p
     if (p == NULL)
     {
-       /* Expand last argument name (before equal sign). */
+       // Expand last argument name (before equal sign).
        xp->xp_pattern = last;
        switch (cmd_idx)
        {
@@ -1857,7 +1868,7 @@ set_context_in_sign_cmd(expand_T *xp, char_u *arg)
     }
     else
     {
-       /* Expand last argument value (after equal sign). */
+       // Expand last argument value (after equal sign).
        xp->xp_pattern = p + 1;
        switch (cmd_idx)
        {
index 07547bb2bbd0451720d9697d3814aa64aba8715b..5962ab534597bded16c54a443aee0bb4651b87c7 100644 (file)
@@ -1255,3 +1255,48 @@ func Test_sign_change_type()
   sign undefine sign2
   enew!
 endfunc
+
+" Test for the sign_jump() function
+func Test_sign_jump_func()
+  enew! | only!
+
+  sign define sign1 text=#> linehl=Comment
+
+  edit foo
+  set buftype=nofile
+  call setline(1, ['A', 'B', 'C', 'D', 'E'])
+  call sign_place(5, '', 'sign1', '', {'lnum' : 2})
+  call sign_place(5, 'g1', 'sign1', '', {'lnum' : 3})
+  call sign_place(6, '', 'sign1', '', {'lnum' : 4})
+  call sign_place(6, 'g1', 'sign1', '', {'lnum' : 5})
+  split bar
+  set buftype=nofile
+  call setline(1, ['P', 'Q', 'R', 'S', 'T'])
+  call sign_place(5, '', 'sign1', '', {'lnum' : 2})
+  call sign_place(5, 'g1', 'sign1', '', {'lnum' : 3})
+  call sign_place(6, '', 'sign1', '', {'lnum' : 4})
+  call sign_place(6, 'g1', 'sign1', '', {'lnum' : 5})
+
+  let r = sign_jump(5, '', 'foo')
+  call assert_equal(2, r)
+  call assert_equal(2, line('.'))
+  let r = sign_jump(6, 'g1', 'foo')
+  call assert_equal(5, r)
+  call assert_equal(5, line('.'))
+  let r = sign_jump(5, '', 'bar')
+  call assert_equal(2, r)
+  call assert_equal(2, line('.'))
+
+  " Error cases
+  call assert_fails("call sign_jump(99, '', 'bar')", 'E157:')
+  call assert_fails("call sign_jump(0, '', 'foo')", 'E474:')
+  call assert_fails("call sign_jump(5, 'g5', 'foo')", 'E157:')
+  call assert_fails('call sign_jump([], "", "foo")', 'E745:')
+  call assert_fails('call sign_jump(2, [], "foo")', 'E730:')
+  call assert_fails('call sign_jump(2, "", {})', 'E158:')
+  call assert_fails('call sign_jump(2, "", "baz")', 'E158:')
+
+  sign unplace * group=*
+  sign undefine sign1
+  enew! | only!
+endfunc
index 9fffc2a9fd1684e4370a90d7160357a27321f961..9d534c7782b00542e9e845f40ef255ebb967f2be 100644 (file)
@@ -799,6 +799,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    717,
 /**/
     716,
 /**/