diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/eval.lua | 2 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 213 | ||||
-rw-r--r-- | src/nvim/sign.c | 272 | ||||
-rw-r--r-- | src/nvim/testdir/test_signs.vim | 132 |
4 files changed, 469 insertions, 150 deletions
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index aed0824ad6..b10e99fc08 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -316,8 +316,10 @@ return { sign_getplaced={args={0, 2}}, sign_jump={args={3, 3}}, sign_place={args={4, 5}}, + sign_placelist={args={1}}, sign_undefine={args={0, 1}}, sign_unplace={args={1, 2}}, + sign_unplacelist={args={1}}, simplify={args=1}, sin={args=1, func="float_op_wrapper", data="&sin"}, sinh={args=1, func="float_op_wrapper", data="&sinh"}, diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 51e5a27348..491d198cd9 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -8861,56 +8861,30 @@ static void f_shiftwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_sign_define(typval_T *argvars, typval_T *rettv, FunPtr fptr) { const char *name; - dict_T *dict; - char *icon = NULL; - char *linehl = NULL; - char *text = NULL; - char *texthl = NULL; - char *numhl = NULL; - rettv->vval.v_number = -1; + if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_UNKNOWN) { + // Define multiple signs + tv_list_alloc_ret(rettv, kListLenMayKnow); - name = tv_get_string_chk(&argvars[0]); - if (name == NULL) { + sign_define_multiple(argvars[0].vval.v_list, rettv->vval.v_list); return; } - if (argvars[1].v_type != VAR_UNKNOWN) { - if (argvars[1].v_type != VAR_DICT) { - EMSG(_(e_dictreq)); - return; - } + // Define a single sign + rettv->vval.v_number = -1; - // sign attributes - dict = argvars[1].vval.v_dict; - if (tv_dict_find(dict, "icon", -1) != NULL) { - icon = tv_dict_get_string(dict, "icon", true); - } - if (tv_dict_find(dict, "linehl", -1) != NULL) { - linehl = tv_dict_get_string(dict, "linehl", true); - } - if (tv_dict_find(dict, "text", -1) != NULL) { - text = tv_dict_get_string(dict, "text", true); - } - if (tv_dict_find(dict, "texthl", -1) != NULL) { - texthl = tv_dict_get_string(dict, "texthl", true); - } - if (tv_dict_find(dict, "numhl", -1) != NULL) { - numhl = tv_dict_get_string(dict, "numhl", true); - } + name = tv_get_string_chk(&argvars[0]); + if (name == NULL) { + return; } - if (sign_define_by_name((char_u *)name, (char_u *)icon, (char_u *)linehl, - (char_u *)text, (char_u *)texthl, (char_u *)numhl) - == OK) { - rettv->vval.v_number = 0; + if (argvars[1].v_type != VAR_UNKNOWN && argvars[1].v_type != VAR_DICT) { + EMSG(_(e_dictreq)); + return; } - xfree(icon); - xfree(linehl); - xfree(text); - xfree(texthl); - xfree(numhl); + rettv->vval.v_number = sign_define_from_dict( + name, argvars[1].v_type == VAR_DICT ? argvars[1].vval.v_dict : NULL); } /// "sign_getdefined()" function @@ -9031,83 +9005,44 @@ cleanup: /// "sign_place()" function static void f_sign_place(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - int sign_id; - char_u *group = NULL; - const char *sign_name; - buf_T *buf; - dict_T *dict; - dictitem_T *di; - linenr_T lnum = 0; - int prio = SIGN_DEF_PRIO; - bool notanum = false; + dict_T *dict = NULL; rettv->vval.v_number = -1; - // Sign identifier - sign_id = (int)tv_get_number_chk(&argvars[0], ¬anum); - if (notanum) { - return; - } - if (sign_id < 0) { - EMSG(_(e_invarg)); + if (argvars[4].v_type != VAR_UNKNOWN + && (argvars[4].v_type != VAR_DICT + || ((dict = argvars[4].vval.v_dict) == NULL))) { + EMSG(_(e_dictreq)); return; } - // Sign group - const char *group_chk = tv_get_string_chk(&argvars[1]); - if (group_chk == NULL) { - return; - } - if (group_chk[0] == '\0') { - group = NULL; // global sign group - } else { - group = vim_strsave((const char_u *)group_chk); - } + rettv->vval.v_number = sign_place_from_dict( + &argvars[0], &argvars[1], &argvars[2], &argvars[3], dict); +} - // Sign name - sign_name = tv_get_string_chk(&argvars[2]); - if (sign_name == NULL) { - goto cleanup; - } +/// "sign_placelist()" function. Place multiple signs. +static void f_sign_placelist(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + int sign_id; - // Buffer to place the sign - buf = get_buf_arg(&argvars[3]); - if (buf == NULL) { - goto cleanup; + tv_list_alloc_ret(rettv, kListLenMayKnow); + + if (argvars[0].v_type != VAR_LIST) { + EMSG(_(e_listreq)); + return; } - if (argvars[4].v_type != VAR_UNKNOWN) { - if (argvars[4].v_type != VAR_DICT - || ((dict = argvars[4].vval.v_dict) == NULL)) { + // Process the List of sign attributes + TV_LIST_ITER_CONST(argvars[0].vval.v_list, li, { + sign_id = -1; + if (TV_LIST_ITEM_TV(li)->v_type == VAR_DICT) { + sign_id = sign_place_from_dict( + NULL, NULL, NULL, NULL, TV_LIST_ITEM_TV(li)->vval.v_dict); + } else { EMSG(_(e_dictreq)); - goto cleanup; - } - - // Line number where the sign is to be placed - if ((di = tv_dict_find(dict, "lnum", -1)) != NULL) { - lnum = (linenr_T)tv_get_number_chk(&di->di_tv, ¬anum); - if (notanum) { - goto cleanup; - } - (void)lnum; - lnum = tv_get_lnum(&di->di_tv); - } - if ((di = tv_dict_find(dict, "priority", -1)) != NULL) { - // Sign priority - prio = (int)tv_get_number_chk(&di->di_tv, ¬anum); - if (notanum) { - goto cleanup; - } } - } - - if (sign_place(&sign_id, group, (const char_u *)sign_name, buf, lnum, prio) - == OK) { - rettv->vval.v_number = sign_id; - } - -cleanup: - xfree(group); + tv_list_append_number(rettv->vval.v_list, sign_id); + }); } /// "sign_undefine()" function @@ -9115,6 +9050,14 @@ static void f_sign_undefine(typval_T *argvars, typval_T *rettv, FunPtr fptr) { const char *name; + if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_UNKNOWN) { + // Undefine multiple signs + tv_list_alloc_ret(rettv, kListLenMayKnow); + + sign_undefine_multiple(argvars[0].vval.v_list, rettv->vval.v_list); + return; + } + rettv->vval.v_number = -1; if (argvars[0].v_type == VAR_UNKNOWN) { @@ -9137,11 +9080,7 @@ static void f_sign_undefine(typval_T *argvars, typval_T *rettv, FunPtr fptr) /// "sign_unplace()" function static void f_sign_unplace(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - dict_T *dict; - dictitem_T *di; - int sign_id = 0; - buf_T *buf = NULL; - char_u *group = NULL; + dict_T *dict = NULL; rettv->vval.v_number = -1; @@ -9150,46 +9089,38 @@ static void f_sign_unplace(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - const char *group_chk = tv_get_string(&argvars[0]); - if (group_chk[0] == '\0') { - group = NULL; // global sign group - } else { - group = vim_strsave((const char_u *)group_chk); - } - if (argvars[1].v_type != VAR_UNKNOWN) { if (argvars[1].v_type != VAR_DICT) { EMSG(_(e_dictreq)); - goto cleanup; + return; } dict = argvars[1].vval.v_dict; - - if ((di = tv_dict_find(dict, "buffer", -1)) != NULL) { - buf = get_buf_arg(&di->di_tv); - if (buf == NULL) { - goto cleanup; - } - } - if (tv_dict_find(dict, "id", -1) != NULL) { - sign_id = tv_dict_get_number(dict, "id"); - } } - if (buf == NULL) { - // Delete the sign in all the buffers - FOR_ALL_BUFFERS(cbuf) { - if (sign_unplace(sign_id, group, cbuf, 0) == OK) { - rettv->vval.v_number = 0; - } - } - } else { - if (sign_unplace(sign_id, group, buf, 0) == OK) { - rettv->vval.v_number = 0; - } + rettv->vval.v_number = sign_unplace_from_dict(&argvars[0], dict); +} + +/// "sign_unplacelist()" function +static void f_sign_unplacelist(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + int retval; + + tv_list_alloc_ret(rettv, kListLenMayKnow); + + if (argvars[0].v_type != VAR_LIST) { + EMSG(_(e_listreq)); + return; } -cleanup: - xfree(group); + TV_LIST_ITER_CONST(argvars[0].vval.v_list, li, { + retval = -1; + if (TV_LIST_ITEM_TV(li)->v_type == VAR_DICT) { + retval = sign_unplace_from_dict(NULL, TV_LIST_ITEM_TV(li)->vval.v_dict); + } else { + EMSG(_(e_dictreq)); + } + tv_list_append_number(rettv->vval.v_list, retval); + }); } /* diff --git a/src/nvim/sign.c b/src/nvim/sign.c index a8ae1b604f..665c4110b8 100644 --- a/src/nvim/sign.c +++ b/src/nvim/sign.c @@ -398,7 +398,8 @@ linenr_T buf_change_sign_type( buf_T *buf, // buffer to store sign in int markId, // sign ID const char_u *group, // sign group - int typenr // typenr of sign we are adding + int typenr, // typenr of sign we are adding + int prio // sign priority ) { signlist_T *sign; // a sign in the signlist @@ -406,6 +407,8 @@ linenr_T buf_change_sign_type( FOR_ALL_SIGNS_IN_BUF(buf, sign) { if (sign->id == markId && sign_in_group(sign, group)) { sign->typenr = typenr; + sign->priority = prio; + sign_sort_by_prio_on_line(buf, sign); return sign->lnum; } } @@ -1026,8 +1029,8 @@ int sign_place( sp->sn_typenr, has_text_or_icon); } else { - // ":sign place {id} file={fname}": change sign type - lnum = buf_change_sign_type(buf, *sign_id, sign_group, sp->sn_typenr); + // ":sign place {id} file={fname}": change sign type and/or priority + lnum = buf_change_sign_type(buf, *sign_id, sign_group, sp->sn_typenr, prio); } if (lnum > 0) { redraw_buf_line_later(buf, lnum); @@ -1869,3 +1872,266 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg) } } +/// Define a sign using the attributes in 'dict'. Returns 0 on success and -1 on +/// failure. +int sign_define_from_dict(const char *name_arg, dict_T *dict) +{ + char *name = NULL; + char *icon = NULL; + char *linehl = NULL; + char *text = NULL; + char *texthl = NULL; + char *numhl = NULL; + int retval = -1; + + if (name_arg == NULL) { + if (dict == NULL) { + return -1; + } + name = tv_dict_get_string(dict, "name", true); + } else { + name = xstrdup(name_arg); + } + if (name == NULL || name[0] == NUL) { + goto cleanup; + } + if (dict != NULL) { + icon = tv_dict_get_string(dict, "icon" , true); + linehl = tv_dict_get_string(dict, "linehl", true); + text = tv_dict_get_string(dict, "text" , true); + texthl = tv_dict_get_string(dict, "texthl", true); + numhl = tv_dict_get_string(dict, "numhl" , true); + } + + if (sign_define_by_name((char_u *)name, (char_u *)icon, (char_u *)linehl, + (char_u *)text, (char_u *)texthl, (char_u *)numhl) + == OK) { + retval = 0; + } + +cleanup: + xfree(name); + xfree(icon); + xfree(linehl); + xfree(text); + xfree(texthl); + xfree(numhl); + + return retval; +} + +/// Define multiple signs using attributes from list 'l' and store the return +/// values in 'retlist'. +void sign_define_multiple(list_T *l, list_T *retlist) +{ + int retval; + + TV_LIST_ITER_CONST(l, li, { + retval = -1; + if (TV_LIST_ITEM_TV(li)->v_type == VAR_DICT) { + retval = sign_define_from_dict(NULL, TV_LIST_ITEM_TV(li)->vval.v_dict); + } else { + EMSG(_(e_dictreq)); + } + tv_list_append_number(retlist, retval); + }); +} + +/// Place a new sign using the values specified in dict 'dict'. Returns the sign +/// identifier if successfully placed, otherwise returns 0. +int sign_place_from_dict( + typval_T *id_tv, + typval_T *group_tv, + typval_T *name_tv, + typval_T *buf_tv, + dict_T *dict) +{ + int sign_id = 0; + char_u *group = NULL; + char_u *sign_name = NULL; + buf_T *buf = NULL; + dictitem_T *di; + linenr_T lnum = 0; + int prio = SIGN_DEF_PRIO; + bool notanum = false; + int ret_sign_id = -1; + + // sign identifier + if (id_tv == NULL) { + di = tv_dict_find(dict, "id", -1); + if (di != NULL) { + id_tv = &di->di_tv; + } + } + if (id_tv == NULL) { + sign_id = 0; + } else { + sign_id = (int)tv_get_number_chk(id_tv, ¬anum); + if (notanum) { + return -1; + } + if (sign_id < 0) { + EMSG(_(e_invarg)); + return -1; + } + } + + // sign group + if (group_tv == NULL) { + di = tv_dict_find(dict, "group", -1); + if (di != NULL) { + group_tv = &di->di_tv; + } + } + if (group_tv == NULL) { + group = NULL; // global group + } else { + group = (char_u *)tv_get_string_chk(group_tv); + if (group == NULL) { + goto cleanup; + } + if (group[0] == '\0') { // global sign group + group = NULL; + } else { + group = vim_strsave(group); + if (group == NULL) { + return -1; + } + } + } + + // sign name + if (name_tv == NULL) { + di = tv_dict_find(dict, "name", -1); + if (di != NULL) { + name_tv = &di->di_tv; + } + } + if (name_tv == NULL) { + goto cleanup; + } + sign_name = (char_u *)tv_get_string_chk(name_tv); + if (sign_name == NULL) { + goto cleanup; + } + + // buffer to place the sign + if (buf_tv == NULL) { + di = tv_dict_find(dict, "buffer", -1); + if (di != NULL) { + buf_tv = &di->di_tv; + } + } + if (buf_tv == NULL) { + goto cleanup; + } + buf = get_buf_arg(buf_tv); + if (buf == NULL) { + goto cleanup; + } + + // line number of the sign + di = tv_dict_find(dict, "lnum", -1); + if (di != NULL) { + lnum = (int)tv_get_number_chk(&di->di_tv, ¬anum); + if (notanum) { + goto cleanup; + } + } + + // sign priority + di = tv_dict_find(dict, "priority", -1); + if (di != NULL) { + prio = (int)tv_get_number_chk(&di->di_tv, ¬anum); + if (notanum) { + goto cleanup; + } + } + + if (sign_place(&sign_id, group, sign_name, buf, lnum, prio) == OK) { + ret_sign_id = sign_id; + } + +cleanup: + xfree(group); + + return ret_sign_id; +} + +/// Undefine multiple signs +void sign_undefine_multiple(list_T *l, list_T *retlist) +{ + char_u *name; + int retval; + + TV_LIST_ITER_CONST(l, li, { + retval = -1; + name = (char_u *)tv_get_string_chk(TV_LIST_ITEM_TV(li)); + if (name != NULL && (sign_undefine_by_name(name) == OK)) { + retval = 0; + } + tv_list_append_number(retlist, retval); + }); +} + +/// Unplace the sign with attributes specified in 'dict'. Returns 0 on success +/// and -1 on failure. +int sign_unplace_from_dict(typval_T *group_tv, dict_T *dict) +{ + dictitem_T *di; + int sign_id = 0; + buf_T *buf = NULL; + char_u *group = NULL; + int retval = -1; + + // sign group + if (group_tv != NULL) { + group = (char_u *)tv_get_string(group_tv); + } else { + group = (char_u *)tv_dict_get_string(dict, "group", false); + } + if (group != NULL) { + if (group[0] == '\0') { // global sign group + group = NULL; + } else { + group = vim_strsave(group); + if (group == NULL) { + return -1; + } + } + } + + if (dict != NULL) { + if ((di = tv_dict_find(dict, "buffer", -1)) != NULL) { + buf = get_buf_arg(&di->di_tv); + if (buf == NULL) { + goto cleanup; + } + } + if (tv_dict_find(dict, "id", -1) != NULL) { + sign_id = (int)tv_dict_get_number(dict, "id"); + if (sign_id <= 0) { + EMSG(_(e_invarg)); + goto cleanup; + } + } + } + + if (buf == NULL) { + // Delete the sign in all the buffers + retval = 0; + FOR_ALL_BUFFERS(buf2) { + if (sign_unplace(sign_id, group, buf2, 0) != OK) { + retval = -1; + } + } + } else if (sign_unplace(sign_id, group, buf, 0) == OK) { + retval = 0; + } + +cleanup: + xfree(group); + + return retval; +} + diff --git a/src/nvim/testdir/test_signs.vim b/src/nvim/testdir/test_signs.vim index 9c3a5636ce..ee0bf135bb 100644 --- a/src/nvim/testdir/test_signs.vim +++ b/src/nvim/testdir/test_signs.vim @@ -134,7 +134,7 @@ func Test_sign() sign define Sign5 text=X\ linehl=Comment sign undefine Sign5 - sign define Sign5 linehl=Comment text=X\ + sign define Sign5 linehl=Comment text=X\ sign undefine Sign5 " define sign with backslash @@ -415,7 +415,7 @@ func Test_sign_funcs() " Tests for invalid arguments to sign_define() call assert_fails('call sign_define("sign4", {"text" : "===>"})', 'E239:') " call assert_fails('call sign_define("sign5", {"text" : ""})', 'E239:') - call assert_fails('call sign_define([])', 'E730:') + call assert_fails('call sign_define({})', 'E731:') call assert_fails('call sign_define("sign6", [])', 'E715:') " Tests for sign_getdefined() @@ -444,7 +444,7 @@ func Test_sign_funcs() call assert_fails('call sign_place([], "", "mySign", 1)', 'E745:') call assert_fails('call sign_place(5, "", "mySign", -1)', 'E158:') call assert_fails('call sign_place(-1, "", "sign1", "Xsign", [])', - \ 'E474:') + \ 'E715:') call assert_fails('call sign_place(-1, "", "sign1", "Xsign", \ {"lnum" : 30})', 'E474:') call assert_fails('call sign_place(10, "", "xsign1x", "Xsign", @@ -504,11 +504,21 @@ func Test_sign_funcs() \ {'id' : 20, 'buffer' : 200})", 'E158:') call assert_fails("call sign_unplace('g1', 'mySign')", 'E715:') + call sign_unplace('*') + + " Test for modifying a placed sign + call assert_equal(15, sign_place(15, '', 'sign1', 'Xsign', {'lnum' : 20})) + call assert_equal(15, sign_place(15, '', 'sign2', 'Xsign')) + call assert_equal([{'bufnr' : bufnr(''), 'signs' : + \ [{'id' : 15, 'group' : '', 'lnum' : 20, 'name' : 'sign2', + \ 'priority' : 10}]}], + \ sign_getplaced()) + " Tests for sign_undefine() call assert_equal(0, sign_undefine("sign1")) call assert_equal([], sign_getdefined("sign1")) call assert_fails('call sign_undefine("none")', 'E155:') - call assert_fails('call sign_undefine([])', 'E730:') + call assert_fails('call sign_undefine({})', 'E731:') " Test for using '.' as the line number for sign_place() call Sign_define_ignore_error("sign1", attr) @@ -644,7 +654,7 @@ func Test_sign_group() call assert_equal([], sign_getplaced(bnum, {'group' : '*'})[0].signs) " Error case - call assert_fails("call sign_unplace([])", 'E474:') + call assert_fails("call sign_unplace({})", 'E474:') " Place a sign in the global group and try to delete it using a group call assert_equal(5, sign_place(5, '', 'sign1', bnum, {'lnum' : 10})) @@ -1131,7 +1141,7 @@ func Test_sign_unplace() endfunc " Tests for auto-generating the sign identifier -func Test_sign_id_autogen() +func Test_aaa_sign_id_autogen() enew | only call sign_unplace('*') call sign_undefine() @@ -1868,3 +1878,113 @@ func Test_sign_numcol() set number& enew! | close endfunc + +" Test for managing multiple signs using the sign functions +func Test_sign_funcs_multi() + call writefile(repeat(["Sun is shining"], 30), "Xsign") + edit Xsign + let bnum = bufnr('') + + " Define multiple signs at once + call assert_equal([0, 0, 0, 0], sign_define([ + \ {'name' : 'sign1', 'text' : '=>', 'linehl' : 'Search', + \ 'texthl' : 'Search'}, + \ {'name' : 'sign2', 'text' : '=>', 'linehl' : 'Search', + \ 'texthl' : 'Search'}, + \ {'name' : 'sign3', 'text' : '=>', 'linehl' : 'Search', + \ 'texthl' : 'Search'}, + \ {'name' : 'sign4', 'text' : '=>', 'linehl' : 'Search', + \ 'texthl' : 'Search'}])) + + " Negative cases for sign_define() + call assert_equal([], sign_define([])) + call assert_equal([-1], sign_define([{}])) + call assert_fails('call sign_define([6])', 'E715:') + call assert_fails('call sign_define(["abc"])', 'E715:') + call assert_fails('call sign_define([[]])', 'E715:') + + " Place multiple signs at once with specific sign identifier + let l = sign_placelist([{'id' : 1, 'group' : 'g1', 'name' : 'sign1', + \ 'buffer' : 'Xsign', 'lnum' : 11, 'priority' : 50}, + \ {'id' : 2, 'group' : 'g2', 'name' : 'sign2', + \ 'buffer' : 'Xsign', 'lnum' : 11, 'priority' : 100}, + \ {'id' : 3, 'group' : '', 'name' : 'sign3', + \ 'buffer' : 'Xsign', 'lnum' : 11}]) + call assert_equal([1, 2, 3], l) + let s = sign_getplaced('Xsign', {'group' : '*'}) + call assert_equal([ + \ {'id' : 2, 'name' : 'sign2', 'lnum' : 11, + \ 'group' : 'g2', 'priority' : 100}, + \ {'id' : 1, 'name' : 'sign1', 'lnum' : 11, + \ 'group' : 'g1', 'priority' : 50}, + \ {'id' : 3, 'name' : 'sign3', 'lnum' : 11, + \ 'group' : '', 'priority' : 10}], s[0].signs) + + call sign_unplace('*') + + " Place multiple signs at once with auto-generated sign identifier + call assert_equal([1, 1, 5], sign_placelist([ + \ {'group' : 'g1', 'name' : 'sign1', + \ 'buffer' : 'Xsign', 'lnum' : 11}, + \ {'group' : 'g2', 'name' : 'sign2', + \ 'buffer' : 'Xsign', 'lnum' : 11}, + \ {'group' : '', 'name' : 'sign3', + \ 'buffer' : 'Xsign', 'lnum' : 11}])) + let s = sign_getplaced('Xsign', {'group' : '*'}) + call assert_equal([ + \ {'id' : 5, 'name' : 'sign3', 'lnum' : 11, + \ 'group' : '', 'priority' : 10}, + \ {'id' : 1, 'name' : 'sign2', 'lnum' : 11, + \ 'group' : 'g2', 'priority' : 10}, + \ {'id' : 1, 'name' : 'sign1', 'lnum' : 11, + \ 'group' : 'g1', 'priority' : 10}], s[0].signs) + + " Change an existing sign without specifying the group + call assert_equal([5], sign_placelist([ + \ {'id' : 5, 'name' : 'sign1', 'buffer' : 'Xsign'}])) + let s = sign_getplaced('Xsign', {'id' : 5, 'group' : ''}) + call assert_equal([{'id' : 5, 'name' : 'sign1', 'lnum' : 11, + \ 'group' : '', 'priority' : 10}], s[0].signs) + + " Place sign without a sign name + call assert_equal([-1], sign_placelist([{'id' : 10, 'buffer' : 'Xsign', + \ 'lnum' : 12, 'group' : ''}])) + + " Place sign without a buffer + call assert_equal([-1], sign_placelist([{'id' : 10, 'name' : 'sign1', + \ 'lnum' : 12, 'group' : ''}])) + + " Invalid arguments + call assert_equal([], sign_placelist([])) + call assert_fails('call sign_placelist({})', "E714:") + call assert_fails('call sign_placelist([[]])', "E715:") + call assert_fails('call sign_placelist(["abc"])', "E715:") + call assert_fails('call sign_placelist([100])', "E715:") + + " Unplace multiple signs + call assert_equal([0, 0, 0], sign_unplacelist([{'id' : 5}, + \ {'id' : 1, 'group' : 'g1'}, {'id' : 1, 'group' : 'g2'}])) + + " Invalid arguments + call assert_equal([], sign_unplacelist([])) + call assert_fails('call sign_unplacelist({})', "E714:") + call assert_fails('call sign_unplacelist([[]])', "E715:") + call assert_fails('call sign_unplacelist(["abc"])', "E715:") + call assert_fails('call sign_unplacelist([100])', "E715:") + call assert_fails("call sign_unplacelist([{'id' : -1}])", 'E474') + + call assert_equal([0, 0, 0, 0], + \ sign_undefine(['sign1', 'sign2', 'sign3', 'sign4'])) + call assert_equal([], sign_getdefined()) + + " Invalid arguments + call assert_equal([], sign_undefine([])) + call assert_fails('call sign_undefine([[]])', 'E730:') + call assert_fails('call sign_undefine([{}])', 'E731:') + call assert_fails('call sign_undefine(["1abc2"])', 'E155:') + + call sign_unplace('*') + call sign_undefine() + enew! + call delete("Xsign") +endfunc |