diff options
author | Andrej Zieger <jerdna-regeiz@users.noreply.github.com> | 2019-05-20 13:12:30 +0200 |
---|---|---|
committer | Andrej Zieger <jerdna-regeiz@users.noreply.github.com> | 2019-05-26 19:32:32 +0200 |
commit | fa07cc215d6c7e86e3b4b7a83d856c017a655933 (patch) | |
tree | 74956d62a3d6a88a7b9b0dae02e6794992d9edaa | |
parent | e09f3baed8abc5fb821fb9b6226ad232d8e2f4c7 (diff) | |
download | rneovim-fa07cc215d6c7e86e3b4b7a83d856c017a655933.tar.gz rneovim-fa07cc215d6c7e86e3b4b7a83d856c017a655933.tar.bz2 rneovim-fa07cc215d6c7e86e3b4b7a83d856c017a655933.zip |
vim-patch:8.1.0717: there is no function for the ":sign jump" command
Problem: There is no function for the ":sign jump" command.
Solution: Add the sign_jump() function. (Yegappan Lakshmanan, closes vim/vim#3780)
https://github.com/vim/vim/commit/6b7b7190aa9e5c4f51bceaebf9275aa5097cfea1
-rw-r--r-- | runtime/doc/eval.txt | 17 | ||||
-rw-r--r-- | runtime/doc/sign.txt | 8 | ||||
-rw-r--r-- | runtime/doc/usr_41.txt | 1 | ||||
-rw-r--r-- | src/nvim/eval.c | 83 | ||||
-rw-r--r-- | src/nvim/eval.lua | 1 | ||||
-rw-r--r-- | src/nvim/sign.c | 111 | ||||
-rw-r--r-- | src/nvim/testdir/test_signs.vim | 45 |
7 files changed, 198 insertions, 68 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 77df15bf41..f6e8cdf762 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2293,6 +2293,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 @@ -7485,6 +7487,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}]) Place the sign defined as {name} at line {lnum} in file {expr} diff --git a/runtime/doc/sign.txt b/runtime/doc/sign.txt index cbc3a19399..cf7e01bcea 100644 --- a/runtime/doc/sign.txt +++ b/runtime/doc/sign.txt @@ -256,13 +256,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 @@ -309,6 +309,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}. diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt index cfda4fdb31..b8fd6cdf7b 100644 --- a/runtime/doc/usr_41.txt +++ b/runtime/doc/usr_41.txt @@ -920,6 +920,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 diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 7298f2e9a8..790f1081b5 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -7204,6 +7204,23 @@ static buf_T *tv_get_buf(typval_T *tv, int curtab_only) } /* + * 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 */ static void f_bufname(typval_T *argvars, typval_T *rettv, FunPtr fptr) @@ -15506,14 +15523,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) { @@ -15553,6 +15566,53 @@ f_sign_getplaced(typval_T *argvars, typval_T *rettv) } /* + * "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], ¬anum); + 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: + xfree(sign_group); +} + +/* * "sign_place()" function */ static void @@ -15599,12 +15659,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) { @@ -15708,13 +15765,9 @@ f_sign_unplace(typval_T *argvars, typval_T *rettv) if ((di = tv_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 (tv_dict_find(dict, (char_u *)"id", -1) != NULL) sign_id = tv_dict_get_number(dict, (char_u *)"id"); diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index f583123025..15f392d8f1 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -280,6 +280,7 @@ return { sign_define={args={1, 2}}, sign_getdefined={args={0, 1}}, sign_getplaced={args={0, 2}}, + sign_jump={args={3, 3}}, sign_place={args={4, 5}}, sign_undefine={args={0, 1}}, sign_unplace={args={1, 2}}, diff --git a/src/nvim/sign.c b/src/nvim/sign.c index 069f841d63..24ebd12e6a 100644 --- a/src/nvim/sign.c +++ b/src/nvim/sign.c @@ -36,7 +36,7 @@ struct 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 @@ -670,8 +670,8 @@ void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_a * "*end_cmd" must be writable. */ 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; @@ -968,8 +968,43 @@ static void 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 + if (buf->b_fname == NULL) { + EMSG(_("E934: Cannot jump to a buffer that does not have a name")); + return -1; + } + size_t cmdlen = STRLEN(buf->b_fname) + 24; + char *cmd = xmallocz(cmdlen); + snprintf(cmd, cmdlen, "e +%" PRId64 " %s", + (int64_t)lnum, buf->b_fname); + do_cmdline_cmd(cmd); + xfree(cmd); + } + + foldOpenCursor(); + + return lnum; +} + +/* + * ":sign define {name} ..." command */ static void sign_define_cmd(char_u *sign_name, char_u *cmdline) { @@ -1023,7 +1058,7 @@ static void sign_define_cmd(char_u *sign_name, char_u *cmdline) } /* - * :sign place command + * ":sign place" command */ static void sign_place_cmd( buf_T *buf, @@ -1065,7 +1100,7 @@ static void sign_place_cmd( } /* - * :sign unplace command + * ":sign unplace" command */ static void sign_unplace_cmd( buf_T *buf, @@ -1128,7 +1163,7 @@ static void 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} @@ -1155,31 +1190,7 @@ static void sign_jump_cmd( 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 - if (buf->b_fname == NULL) { - EMSG(_("E934: Cannot jump to a buffer that does not have a name")); - return; - } - size_t cmdlen = STRLEN(buf->b_fname) + 24; - char *cmd = xmallocz(cmdlen); - snprintf(cmd, cmdlen, "e +%" PRId64 " %s", - (int64_t)lnum, buf->b_fname); - do_cmdline_cmd(cmd); - xfree(cmd); - } - - foldOpenCursor(); + (void)sign_jump(id, group, buf); } /* @@ -1635,7 +1646,7 @@ char_u * 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; @@ -1658,11 +1669,11 @@ void free_signs(void) 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; /// Function given to ExpandGeneric() to obtain the sign command @@ -1713,15 +1724,15 @@ void 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); @@ -1733,18 +1744,18 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg) 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: @@ -1793,7 +1804,7 @@ void 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) { diff --git a/src/nvim/testdir/test_signs.vim b/src/nvim/testdir/test_signs.vim index 96f60a2ac8..3d6990f136 100644 --- a/src/nvim/testdir/test_signs.vim +++ b/src/nvim/testdir/test_signs.vim @@ -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 |