diff --git a/src/sign.c b/src/sign.c index e225909506..2ae74e4ddf 100644 --- a/src/sign.c +++ b/src/sign.c @@ -81,18 +81,17 @@ init_signs(void) static signgroup_T * sign_group_ref(char_u *groupname) { - hash_T hash; - hashitem_T *hi; - signgroup_T *group; + hash_T hash = hash_hash(groupname); + hashitem_T *hi = hash_lookup(&sg_table, groupname, hash); + signgroup_T *group = NULL; - hash = hash_hash(groupname); - hi = hash_lookup(&sg_table, groupname, hash); if (HASHITEM_EMPTY(hi)) { // new group group = alloc(offsetof(signgroup_T, sg_name) + STRLEN(groupname) + 1); if (group == NULL) return NULL; + STRCPY(group->sg_name, groupname); group->sg_refcount = 1; group->sg_next_sign_id = 1; @@ -115,14 +114,11 @@ sign_group_ref(char_u *groupname) static void sign_group_unref(char_u *groupname) { - hashitem_T *hi; - signgroup_T *group; - - hi = hash_find(&sg_table, groupname); + hashitem_T *hi = hash_find(&sg_table, groupname); if (HASHITEM_EMPTY(hi)) return; - group = HI2SG(hi); + signgroup_T *group = HI2SG(hi); group->sg_refcount--; if (group->sg_refcount == 0) { @@ -167,19 +163,18 @@ sign_group_get_next_signid(buf_T *buf, char_u *groupname) { int id = 1; signgroup_T *group = NULL; - sign_entry_T *sign; - hashitem_T *hi; - int found = FALSE; + sign_entry_T *sign = NULL; if (groupname != NULL) { - hi = hash_find(&sg_table, groupname); + hashitem_T *hi = hash_find(&sg_table, groupname); if (HASHITEM_EMPTY(hi)) return id; group = HI2SG(hi); } // Search for the next usable sign identifier + int found = FALSE; while (!found) { if (group == NULL) @@ -216,15 +211,15 @@ insert_sign(buf_T *buf, // buffer to store sign in linenr_T lnum, // line number which gets the mark int typenr) // typenr of sign we are adding { - sign_entry_T *newsign; - - newsign = lalloc_id(sizeof(sign_entry_T), FALSE, aid_insert_sign); + sign_entry_T *newsign = + lalloc_id(sizeof(sign_entry_T), FALSE, aid_insert_sign); if (newsign == NULL) return; newsign->se_id = id; newsign->se_lnum = lnum; newsign->se_typenr = typenr; + if (group != NULL) { newsign->se_group = sign_group_ref(group); @@ -235,7 +230,10 @@ insert_sign(buf_T *buf, // buffer to store sign in } } else + { newsign->se_group = NULL; + } + newsign->se_priority = prio; newsign->se_next = next; newsign->se_prev = prev; @@ -260,7 +258,9 @@ insert_sign(buf_T *buf, // buffer to store sign in # endif } else + { prev->se_next = newsign; + } } /* @@ -275,16 +275,12 @@ insert_sign_by_lnum_prio(buf_T *buf, // buffer to store sign in linenr_T lnum, // line number which gets the mark int typenr) // typenr of sign we are adding { - sign_entry_T *sign; - // keep signs sorted by lnum and by priority: insert new sign at // the proper position in the list for this lnum. while (prev != NULL && prev->se_lnum == lnum && prev->se_priority <= prio) prev = prev->se_prev; - if (prev == NULL) - sign = buf->b_signlist; - else - sign = prev->se_next; + + sign_entry_T *sign = (prev == NULL) ? buf->b_signlist : prev->se_next; insert_sign(buf, prev, sign, id, group, prio, lnum, typenr); } @@ -295,8 +291,7 @@ insert_sign_by_lnum_prio(buf_T *buf, // buffer to store sign in static sign_T * find_sign_by_typenr(int typenr) { - sign_T *sp; - + sign_T *sp = NULL; FOR_ALL_SIGNS(sp) if (sp->sn_typenr == typenr) return sp; @@ -309,8 +304,7 @@ find_sign_by_typenr(int typenr) static char_u * sign_typenr2name(int typenr) { - sign_T *sp; - + sign_T *sp = NULL; FOR_ALL_SIGNS(sp) if (sp->sn_typenr == typenr) return sp->sn_name; @@ -323,10 +317,10 @@ sign_typenr2name(int typenr) static dict_T * sign_get_info(sign_entry_T *sign) { - dict_T *d; - - if ((d = dict_alloc_id(aid_sign_getinfo)) == NULL) + dict_T *d = dict_alloc_id(aid_sign_getinfo); + if (d == NULL) return NULL; + dict_add_number(d, "id", sign->se_id); dict_add_string(d, "group", (sign->se_group == NULL) ? (char_u *)"" @@ -346,8 +340,6 @@ sign_get_info(sign_entry_T *sign) static void sign_sort_by_prio_on_line(buf_T *buf, sign_entry_T *sign) { - sign_entry_T *p = NULL; - // If there is only one sign in the buffer or only one sign on the line or // the sign is already sorted by priority, then return. if ((sign->se_prev == NULL || sign->se_prev->se_lnum != sign->se_lnum || @@ -360,7 +352,7 @@ sign_sort_by_prio_on_line(buf_T *buf, sign_entry_T *sign) // Find a sign after which 'sign' should be inserted // First search backward for a sign with higher priority on the same line - p = sign; + sign_entry_T *p = sign; while (p->se_prev != NULL && p->se_prev->se_lnum == sign->se_lnum && p->se_prev->se_priority <= sign->se_priority) p = p->se_prev; @@ -378,10 +370,13 @@ sign_sort_by_prio_on_line(buf_T *buf, sign_entry_T *sign) // Remove 'sign' from the list if (buf->b_signlist == sign) buf->b_signlist = sign->se_next; + if (sign->se_prev != NULL) sign->se_prev->se_next = sign->se_next; + if (sign->se_next != NULL) sign->se_next->se_prev = sign->se_prev; + sign->se_prev = NULL; sign->se_next = NULL; @@ -394,6 +389,7 @@ sign_sort_by_prio_on_line(buf_T *buf, sign_entry_T *sign) p->se_prev = sign; if (sign->se_prev != NULL) sign->se_prev->se_next = sign; + if (buf->b_signlist == p) buf->b_signlist = sign; } @@ -419,10 +415,8 @@ buf_addsign(buf_T *buf, // buffer to store sign in linenr_T lnum, // line number which gets the mark int typenr) // typenr of sign we are adding { - sign_entry_T *sign; // a sign in the signlist - sign_entry_T *prev; // the previous sign - - prev = NULL; + sign_entry_T *sign = NULL; // a sign in the signlist + sign_entry_T *prev = NULL; // the previous sign FOR_ALL_SIGNS_IN_BUF(buf, sign) { if (lnum == sign->se_lnum && id == sign->se_id && @@ -444,7 +438,6 @@ buf_addsign(buf_T *buf, // buffer to store sign in } insert_sign_by_lnum_prio(buf, prev, id, groupname, prio, lnum, typenr); - return; } /* @@ -458,8 +451,7 @@ buf_change_sign_type(buf_T *buf, // buffer to store sign in int typenr, // typenr of sign we are adding int prio) // sign priority { - sign_entry_T *sign; // a sign in the signlist - + sign_entry_T *sign = NULL; // a sign in the signlist FOR_ALL_SIGNS_IN_BUF(buf, sign) { if (sign->se_id == markId && sign_in_group(sign, group)) @@ -482,17 +474,15 @@ buf_change_sign_type(buf_T *buf, // buffer to store sign in int buf_get_signattrs(win_T *wp, linenr_T lnum, sign_attrs_T *sattr) { - sign_entry_T *sign; - sign_T *sp; - buf_T *buf = wp->w_buffer; - CLEAR_POINTER(sattr); + buf_T *buf = wp->w_buffer; + sign_entry_T *sign = NULL; FOR_ALL_SIGNS_IN_BUF(buf, sign) { + // Signs are sorted by line number in the buffer. No need to check + // for signs after the specified line number 'lnum'. if (sign->se_lnum > lnum) - // Signs are sorted by line number in the buffer. No need to check - // for signs after the specified line number 'lnum'. break; if (sign->se_lnum == lnum @@ -502,7 +492,7 @@ buf_get_signattrs(win_T *wp, linenr_T lnum, sign_attrs_T *sattr) ) { sattr->sat_typenr = sign->se_typenr; - sp = find_sign_by_typenr(sign->se_typenr); + sign_T *sp = find_sign_by_typenr(sign->se_typenr); if (sp == NULL) return FALSE; @@ -510,14 +500,19 @@ buf_get_signattrs(win_T *wp, linenr_T lnum, sign_attrs_T *sattr) sattr->sat_icon = sp->sn_image; # endif sattr->sat_text = sp->sn_text; + if (sattr->sat_text != NULL && sp->sn_text_hl > 0) sattr->sat_texthl = syn_id2attr(sp->sn_text_hl); + if (sp->sn_line_hl > 0) sattr->sat_linehl = syn_id2attr(sp->sn_line_hl); + if (sp->sn_cul_hl > 0) sattr->sat_culhl = syn_id2attr(sp->sn_cul_hl); + if (sp->sn_num_hl > 0) sattr->sat_numhl = syn_id2attr(sp->sn_num_hl); + sattr->sat_priority = sign->se_priority; // If there is another sign next with the same priority, may @@ -527,25 +522,28 @@ buf_get_signattrs(win_T *wp, linenr_T lnum, sign_attrs_T *sattr) sign->se_next->se_lnum == sign->se_lnum) { sign_T *next_sp = find_sign_by_typenr(sign->se_next->se_typenr); + if (next_sp == NULL) + return FALSE; - if (next_sp != NULL) + if (sattr->sat_icon == NULL && sattr->sat_text == NULL) { - if (sattr->sat_icon == NULL && sattr->sat_text == NULL) - { # ifdef FEAT_SIGN_ICONS - sattr->sat_icon = next_sp->sn_image; + sattr->sat_icon = next_sp->sn_image; # endif - sattr->sat_text = next_sp->sn_text; - } - if (sp->sn_text_hl <= 0 && next_sp->sn_text_hl > 0) - sattr->sat_texthl = syn_id2attr(next_sp->sn_text_hl); - if (sp->sn_line_hl <= 0 && next_sp->sn_line_hl > 0) - sattr->sat_linehl = syn_id2attr(next_sp->sn_line_hl); - if (sp->sn_cul_hl <= 0 && next_sp->sn_cul_hl > 0) - sattr->sat_culhl = syn_id2attr(next_sp->sn_cul_hl); - if (sp->sn_num_hl <= 0 && next_sp->sn_num_hl > 0) - sattr->sat_numhl = syn_id2attr(next_sp->sn_num_hl); + sattr->sat_text = next_sp->sn_text; } + + if (sp->sn_text_hl <= 0 && next_sp->sn_text_hl > 0) + sattr->sat_texthl = syn_id2attr(next_sp->sn_text_hl); + + if (sp->sn_line_hl <= 0 && next_sp->sn_line_hl > 0) + sattr->sat_linehl = syn_id2attr(next_sp->sn_line_hl); + + if (sp->sn_cul_hl <= 0 && next_sp->sn_cul_hl > 0) + sattr->sat_culhl = syn_id2attr(next_sp->sn_cul_hl); + + if (sp->sn_num_hl <= 0 && next_sp->sn_num_hl > 0) + sattr->sat_numhl = syn_id2attr(next_sp->sn_num_hl); } return TRUE; } @@ -569,27 +567,28 @@ buf_delsign(buf_T *buf, // buffer sign is stored in int id, // sign id char_u *group) // sign group { - sign_entry_T **lastp; // pointer to pointer to current sign - sign_entry_T *sign; // a sign in a b_signlist - sign_entry_T *next; // the next sign in a b_signlist - linenr_T lnum; // line number whose sign was deleted + // pointer to pointer to current sign + sign_entry_T **lastp = &buf->b_signlist; + sign_entry_T *next = NULL; // the next sign in a b_signlist + linenr_T lnum = 0; // line number whose sign was deleted - lastp = &buf->b_signlist; - lnum = 0; - for (sign = buf->b_signlist; sign != NULL; sign = next) + for (sign_entry_T *sign = buf->b_signlist; sign != NULL; sign = next) { next = sign->se_next; + if ((id == 0 || sign->se_id == id) && (atlnum == 0 || sign->se_lnum == atlnum) && sign_in_group(sign, group)) - { *lastp = next; if (next != NULL) next->se_prev = sign->se_prev; + lnum = sign->se_lnum; + if (sign->se_group != NULL) sign_group_unref(sign->se_group->sg_name); + vim_free(sign); redraw_buf_line_later(buf, lnum); @@ -602,7 +601,9 @@ buf_delsign(buf_T *buf, // buffer sign is stored in break; } else + { lastp = &sign->se_next; + } } // When deleting the last sign the cursor position may change, because the @@ -626,8 +627,7 @@ buf_findsign(buf_T *buf, // buffer to store sign in int id, // sign ID char_u *group) // sign group { - sign_entry_T *sign; // a sign in the signlist - + sign_entry_T *sign = NULL; // a sign in the signlist FOR_ALL_SIGNS_IN_BUF(buf, sign) if (sign->se_id == id && sign_in_group(sign, group)) return sign->se_lnum; @@ -644,13 +644,12 @@ buf_getsign_at_line(buf_T *buf, // buffer whose sign we are searching for linenr_T lnum, // line number of sign char_u *groupname) // sign group name { - sign_entry_T *sign; // a sign in the signlist - + sign_entry_T *sign = NULL; // a sign in the signlist FOR_ALL_SIGNS_IN_BUF(buf, sign) { + // Signs are sorted by line number in the buffer. No need to check + // for signs after the specified line number 'lnum'. if (sign->se_lnum > lnum) - // Signs are sorted by line number in the buffer. No need to check - // for signs after the specified line number 'lnum'. break; if (sign->se_lnum == lnum && sign_in_group(sign, groupname)) @@ -668,9 +667,8 @@ buf_findsign_id(buf_T *buf, // buffer whose sign we are searching for linenr_T lnum, // line number of sign char_u *groupname) // sign group name { - sign_entry_T *sign; // a sign in the signlist - - sign = buf_getsign_at_line(buf, lnum, groupname); + // a sign in the signlist + sign_entry_T *sign = buf_getsign_at_line(buf, lnum, groupname); if (sign != NULL) return sign->se_id; @@ -686,13 +684,12 @@ 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 { - sign_entry_T *sign; // a sign in the signlist - + sign_entry_T *sign = NULL; // a sign in the signlist FOR_ALL_SIGNS_IN_BUF(buf, sign) { + // Signs are sorted by line number in the buffer. No need to check + // for signs after the specified line number 'lnum'. if (sign->se_lnum > lnum) - // Signs are sorted by line number in the buffer. No need to check - // for signs after the specified line number 'lnum'. break; if (sign->se_lnum == lnum && sign->se_typenr == typenr) @@ -709,19 +706,17 @@ buf_findsigntype_id(buf_T *buf, // buffer whose sign we are searching for int buf_signcount(buf_T *buf, linenr_T lnum) { - sign_entry_T *sign; // a sign in the signlist int count = 0; - + sign_entry_T *sign = NULL; // a sign in the signlist FOR_ALL_SIGNS_IN_BUF(buf, sign) { + // Signs are sorted by line number in the buffer. No need to check + // for signs after the specified line number 'lnum'. if (sign->se_lnum > lnum) - // Signs are sorted by line number in the buffer. No need to check - // for signs after the specified line number 'lnum'. break; - if (sign->se_lnum == lnum) - if (sign_get_image(sign->se_typenr) != NULL) - count++; + if (sign->se_lnum == lnum && sign_get_image(sign->se_typenr) != NULL) + count++; } return count; @@ -736,10 +731,6 @@ buf_signcount(buf_T *buf, linenr_T lnum) void buf_delete_signs(buf_T *buf, char_u *group) { - sign_entry_T *sign; - sign_entry_T **lastp; // pointer to pointer to current sign - sign_entry_T *next; - // When deleting the last sign need to redraw the windows to remove the // sign column. Not when curwin is NULL (this means we're exiting). if (buf->b_signlist != NULL && curwin != NULL) @@ -748,21 +739,29 @@ buf_delete_signs(buf_T *buf, char_u *group) changed_line_abv_curs(); } - lastp = &buf->b_signlist; - for (sign = buf->b_signlist; sign != NULL; sign = next) + // pointer to pointer to current sign + sign_entry_T **lastp = &buf->b_signlist; + sign_entry_T *next = NULL; + + for (sign_entry_T *sign = buf->b_signlist; sign != NULL; sign = next) { next = sign->se_next; if (sign_in_group(sign, group)) { *lastp = next; + if (next != NULL) next->se_prev = sign->se_prev; + if (sign->se_group != NULL) sign_group_unref(sign->se_group->sg_name); + vim_free(sign); } else + { lastp = &sign->se_next; + } } } @@ -772,17 +771,13 @@ buf_delete_signs(buf_T *buf, char_u *group) static void sign_list_placed(buf_T *rbuf, char_u *sign_group) { - buf_T *buf; - sign_entry_T *sign; char lbuf[MSG_BUF_LEN]; char group[MSG_BUF_LEN]; msg_puts_title(_("\n--- Signs ---")); msg_putchar('\n'); - if (rbuf == NULL) - buf = firstbuf; - else - buf = rbuf; + + buf_T *buf = (rbuf == NULL) ? firstbuf : rbuf; while (buf != NULL && !got_int) { if (buf->b_signlist != NULL) @@ -791,26 +786,34 @@ sign_list_placed(buf_T *rbuf, char_u *sign_group) msg_puts_attr(lbuf, HL_ATTR(HLF_D)); msg_putchar('\n'); } + + sign_entry_T *sign = NULL; FOR_ALL_SIGNS_IN_BUF(buf, sign) { if (got_int) break; + if (!sign_in_group(sign, sign_group)) continue; + if (sign->se_group != NULL) vim_snprintf(group, MSG_BUF_LEN, _(" group=%s"), sign->se_group->sg_name); else group[0] = '\0'; + vim_snprintf(lbuf, MSG_BUF_LEN, _(" line=%ld id=%d%s name=%s priority=%d"), (long)sign->se_lnum, sign->se_id, group, sign_typenr2name(sign->se_typenr), sign->se_priority); + msg_puts(lbuf); msg_putchar('\n'); } + if (rbuf != NULL) break; + buf = buf->b_next; } } @@ -821,23 +824,25 @@ sign_list_placed(buf_T *rbuf, char_u *sign_group) void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after) { - sign_entry_T *sign; // a sign in a b_signlist - linenr_T new_lnum; - + sign_entry_T *sign = NULL; // a sign in a b_signlist FOR_ALL_SIGNS_IN_BUF(curbuf, sign) { // Ignore changes to lines after the sign if (sign->se_lnum < line1) continue; - new_lnum = sign->se_lnum; + + linenr_T new_lnum = sign->se_lnum; + if (sign->se_lnum <= line2) { if (amount != MAXLNUM) new_lnum += amount; } else if (sign->se_lnum > line2) + { // Lines inserted or deleted before the sign new_lnum += amount_after; + } // If the new sign line number is past the last line in the buffer, // then don't adjust the line number. Otherwise, it will always be past @@ -855,13 +860,13 @@ static int sign_cmd_idx(char_u *begin_cmd, // begin of sign subcmd char_u *end_cmd) // just after sign subcmd { - int idx; + int idx = 0; char save = *end_cmd; - *end_cmd = NUL; - for (idx = 0;; ++idx) - if (cmds[idx] == NULL || STRCMP(begin_cmd, cmds[idx]) == 0) - break; + + while (cmds[idx] != NULL && STRCMP(begin_cmd, cmds[idx]) != 0) + ++idx; + *end_cmd = save; return idx; } @@ -872,14 +877,15 @@ sign_cmd_idx(char_u *begin_cmd, // begin of sign subcmd static sign_T * sign_find(char_u *name, sign_T **sp_prev) { - sign_T *sp; - if (sp_prev != NULL) *sp_prev = NULL; + + sign_T *sp = NULL; FOR_ALL_SIGNS(sp) { if (STRCMP(sp->sn_name, name) == 0) break; + if (sp_prev != NULL) *sp_prev = sp; } @@ -893,31 +899,33 @@ sign_find(char_u *name, sign_T **sp_prev) static sign_T * alloc_new_sign(char_u *name) { - sign_T *sp; - sign_T *lp; int start = next_sign_typenr; // Allocate a new sign. - sp = alloc_clear_id(sizeof(sign_T), aid_sign_define_by_name); + sign_T *sp = alloc_clear_id(sizeof(sign_T), aid_sign_define_by_name); if (sp == NULL) return NULL; // Check that next_sign_typenr is not already being used. // This only happens after wrapping around. Hopefully // another one got deleted and we can use its number. - for (lp = first_sign; lp != NULL;) + sign_T *lp = first_sign; + while (lp != NULL) { if (lp->sn_typenr == next_sign_typenr) { ++next_sign_typenr; + if (next_sign_typenr == MAX_TYPENR) next_sign_typenr = 1; + if (next_sign_typenr == start) { vim_free(sp); emsg(_(e_too_many_signs_defined)); return NULL; } + lp = first_sign; // start all over continue; } @@ -925,6 +933,7 @@ alloc_new_sign(char_u *name) } sp->sn_typenr = next_sign_typenr; + if (++next_sign_typenr == MAX_TYPENR) next_sign_typenr = 1; // wrap around @@ -964,37 +973,38 @@ sign_define_init_icon(sign_T *sp, char_u *icon) static int sign_define_init_text(sign_T *sp, char_u *text) { - char_u *s; - char_u *endp; - int cells; - int len; - - endp = text + (int)STRLEN(text); + char_u *s = NULL; + char_u *endp = text + (int)STRLEN(text); + int cells = 0; // Remove backslashes so that it is possible to use a space. for (s = text; s + 1 < endp; ++s) + { if (*s == '\\') { STRMOVE(s, s + 1); --endp; } + } // Count cells and check for non-printable chars if (has_mbyte) { - cells = 0; for (s = text; s < endp; s += (*mb_ptr2len)(s)) { if (!vim_isprintc((*mb_ptr2char)(s))) break; + cells += (*mb_ptr2cells)(s); } } else { for (s = text; s < endp; ++s) + { if (!vim_isprintc(*s)) break; + } cells = (int)(s - text); } @@ -1008,7 +1018,7 @@ sign_define_init_text(sign_T *sp, char_u *text) vim_free(sp->sn_text); // Allocate one byte more if we need to pad up // with a space. - len = (int)(endp - text + ((cells == 1) ? 1 : 0)); + int len = (int)(endp - text + ((cells == 1) ? 1 : 0)); sp->sn_text = vim_strnsave(text, len); // For single character sign text, pad with a space. @@ -1031,10 +1041,8 @@ sign_define_by_name(char_u *name, char_u *numhl, int prio) { - sign_T *sp_prev; - sign_T *sp; - - sp = sign_find(name, &sp_prev); + sign_T *sp_prev = NULL; + sign_T *sp = sign_find(name, &sp_prev); if (sp == NULL) { sp = alloc_new_sign(name); @@ -1049,13 +1057,14 @@ sign_define_by_name(char_u *name, } else { - win_T *wp; - + win_T *wp = NULL; // Signs may already exist, a redraw is needed in windows with a // non-empty sign list. FOR_ALL_WINDOWS(wp) + { if (wp->w_buffer->b_signlist != NULL) redraw_buf_later(wp->w_buffer, UPD_NOT_VALID); + } } // set values for a defined sign. @@ -1117,10 +1126,8 @@ sign_exists_by_name(char_u *name) int sign_undefine_by_name(char_u *name, int give_error) { - sign_T *sp_prev; - sign_T *sp; - - sp = sign_find(name, &sp_prev); + sign_T *sp_prev = NULL; + sign_T *sp = sign_find(name, &sp_prev); if (sp == NULL) { if (give_error) @@ -1138,9 +1145,7 @@ sign_undefine_by_name(char_u *name, int give_error) static void sign_list_by_name(char_u *name) { - sign_T *sp; - - sp = sign_find(name, NULL); + sign_T *sp = sign_find(name, NULL); if (sp != NULL) sign_list_defined(sp); else @@ -1150,14 +1155,16 @@ sign_list_by_name(char_u *name) static void may_force_numberwidth_recompute(buf_T *buf, int unplace) { - tabpage_T *tp; - win_T *wp; + tabpage_T *tp = NULL; + win_T *wp = NULL; FOR_ALL_TAB_WINDOWS(tp, wp) + { if (wp->w_buffer == buf && (wp->w_p_nu || wp->w_p_rnu) && (unplace || wp->w_nrwidth_width < 2) && (*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u')) wp->w_nrwidth_line_count = 0; + } } /* @@ -1171,20 +1178,23 @@ sign_place(int *sign_id, linenr_T lnum, int prio) { - sign_T *sp; - // Check for reserved character '*' in group name if (sign_group != NULL && (*sign_group == '*' || *sign_group == '\0')) return FAIL; + sign_T *sp = NULL; FOR_ALL_SIGNS(sp) + { if (STRCMP(sp->sn_name, sign_name) == 0) break; + } + if (sp == NULL) { semsg(_(e_unknown_sign_str), sign_name); return FAIL; } + if (*sign_id == 0) *sign_id = sign_group_get_next_signid(buf, sign_group); @@ -1193,13 +1203,18 @@ sign_place(int *sign_id, prio = (sp->sn_priority != -1) ? sp->sn_priority : SIGN_DEF_PRIO; if (lnum > 0) + { // ":sign place {id} line={lnum} name={name} file={fname}": // place a sign buf_addsign(buf, *sign_id, sign_group, prio, lnum, sp->sn_typenr); + } else + { // ":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); @@ -1234,10 +1249,8 @@ sign_unplace(int sign_id, char_u *sign_group, buf_T *buf, linenr_T atlnum) } else { - linenr_T lnum; - // Delete only the specified signs - lnum = buf_delsign(buf, atlnum, sign_id, sign_group); + linenr_T lnum = buf_delsign(buf, atlnum, sign_id, sign_group); if (lnum == 0) return FAIL; } @@ -1257,9 +1270,9 @@ sign_unplace(int sign_id, char_u *sign_group, buf_T *buf, linenr_T atlnum) static void sign_unplace_at_cursor(char_u *groupname) { - int id = -1; + int id = + buf_findsign_id(curwin->w_buffer, curwin->w_cursor.lnum, groupname); - id = buf_findsign_id(curwin->w_buffer, curwin->w_cursor.lnum, groupname); if (id > 0) sign_unplace(id, groupname, curwin->w_buffer, curwin->w_cursor.lnum); else @@ -1272,9 +1285,8 @@ sign_unplace_at_cursor(char_u *groupname) static 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) + linenr_T lnum = buf_findsign(buf, sign_id, sign_group); + if (lnum <= 0) { semsg(_(e_invalid_sign_id_nr), sign_id); return -1; @@ -1289,16 +1301,15 @@ sign_jump(int sign_id, char_u *sign_group, buf_T *buf) } else { // ... not currently in a window - char_u *cmd; - if (buf->b_fname == NULL) { emsg(_(e_cannot_jump_to_buffer_that_does_not_have_name)); return -1; } - cmd = alloc(STRLEN(buf->b_fname) + 25); + char_u *cmd = alloc(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); @@ -1316,7 +1327,7 @@ sign_jump(int sign_id, char_u *sign_group, buf_T *buf) static void sign_define_cmd(char_u *sign_name, char_u *cmdline) { - char_u *arg; + char_u *arg = NULL; char_u *p = cmdline; char_u *icon = NULL; char_u *text = NULL; @@ -1328,11 +1339,12 @@ sign_define_cmd(char_u *sign_name, char_u *cmdline) int failed = FALSE; // set values for a defined sign. - for (;;) + while (TRUE) { arg = skipwhite(p); if (*arg == NUL) break; + p = skiptowhite_esc(arg); if (STRNCMP(arg, "icon=", 5) == 0) { @@ -1450,6 +1462,7 @@ sign_unplace_cmd(buf_T *buf, if (id == -2) { if (buf != NULL) + { // :sign unplace * file={fname} // :sign unplace * group={group} file={fname} // :sign unplace * group=* file={fname} @@ -1457,17 +1470,23 @@ sign_unplace_cmd(buf_T *buf, // :sign unplace * group={group} buffer={nr} // :sign unplace * group=* buffer={nr} sign_unplace(0, group, buf, 0); + } else + { // :sign unplace * // :sign unplace * group={group} // :sign unplace * group=* FOR_ALL_BUFFERS(buf) + { if (buf->b_signlist != NULL) buf_delete_signs(buf, group); + } + } } else { if (buf != NULL) + { // :sign unplace {id} file={fname} // :sign unplace {id} group={group} file={fname} // :sign unplace {id} group=* file={fname} @@ -1475,6 +1494,7 @@ sign_unplace_cmd(buf_T *buf, // :sign unplace {id} group={group} buffer={nr} // :sign unplace {id} group=* buffer={nr} sign_unplace(id, group, buf, 0); + } else { if (id == -1) @@ -1523,6 +1543,7 @@ sign_jump_cmd(buf_T *buf, emsg(_(e_invalid_argument)); return; } + (void)sign_jump(id, group, buf); } @@ -1542,13 +1563,11 @@ parse_sign_cmd_args(int cmd, buf_T **buf, linenr_T *lnum) { - char_u *arg1; - char_u *name; + char_u *arg1 = arg; char_u *filename = NULL; int lnum_arg = FALSE; // first arg could be placed sign id - arg1 = arg; if (VIM_ISDIGIT(*arg)) { *signid = getdigits(&arg); @@ -1558,7 +1577,9 @@ parse_sign_cmd_args(int cmd, arg = arg1; } else + { arg = skipwhite(arg); + } } while (*arg != NUL) @@ -1583,12 +1604,14 @@ parse_sign_cmd_args(int cmd, else if (STRNCMP(arg, "name=", 5) == 0) { arg += 5; - name = arg; + char_u *name = arg; arg = skiptowhite(arg); if (*arg != NUL) *arg++ = NUL; + while (name[0] == '0' && name[1] != NUL) ++name; + *sign_name = name; } else if (STRNCMP(arg, "group=", 6) == 0) @@ -1617,8 +1640,10 @@ parse_sign_cmd_args(int cmd, arg += 7; filename = arg; *buf = buflist_findnr((int)getdigits(&arg)); + if (*skipwhite(arg) != NUL) semsg(_(e_trailing_characters_str), arg); + break; } else @@ -1626,6 +1651,7 @@ parse_sign_cmd_args(int cmd, emsg(_(e_invalid_argument)); return FAIL; } + arg = skipwhite(arg); } @@ -1651,14 +1677,10 @@ void ex_sign(exarg_T *eap) { char_u *arg = eap->arg; - char_u *p; - int idx; - sign_T *sp; - buf_T *buf = NULL; // Parse the subcommand. - p = skiptowhite(arg); - idx = sign_cmd_idx(arg, p); + char_u *p = skiptowhite(arg); + int idx = sign_cmd_idx(arg, p); if (idx == SIGNCMD_LAST) { semsg(_(e_unknown_sign_command_str), arg); @@ -1666,50 +1688,14 @@ ex_sign(exarg_T *eap) } arg = skipwhite(p); - if (idx <= SIGNCMD_LIST) + if (idx > SIGNCMD_LIST) { - // Define, undefine or list signs. - if (idx == SIGNCMD_LIST && *arg == NUL) - { - // ":sign list": list all defined signs - for (sp = first_sign; sp != NULL && !got_int; sp = sp->sn_next) - sign_list_defined(sp); - } - else if (*arg == NUL) - emsg(_(e_missing_sign_name)); - else - { - char_u *name; - - // Isolate the sign name. If it's a number skip leading zeroes, - // so that "099" and "99" are the same sign. But keep "0". - p = skiptowhite(arg); - if (*p != NUL) - *p++ = NUL; - while (arg[0] == '0' && arg[1] != NUL) - ++arg; - name = vim_strsave(arg); - - if (idx == SIGNCMD_DEFINE) - sign_define_cmd(name, p); - else if (idx == SIGNCMD_LIST) - // ":sign list {name}" - sign_list_by_name(name); - else - // ":sign undefine {name}" - sign_undefine_by_name(name, TRUE); - - vim_free(name); - return; - } - } - else - { - int id = -1; - linenr_T lnum = -1; char_u *sign_name = NULL; + int id = -1; char_u *group = NULL; int prio = -1; + buf_T *buf = NULL; + linenr_T lnum = -1; // Parse command line arguments if (parse_sign_cmd_args(idx, arg, &sign_name, &id, &group, &prio, &buf, @@ -1722,6 +1708,45 @@ ex_sign(exarg_T *eap) sign_unplace_cmd(buf, lnum, sign_name, id, group); else if (idx == SIGNCMD_JUMP) sign_jump_cmd(buf, lnum, sign_name, id, group); + + return; + } + + // Define, undefine or list signs. + if (idx == SIGNCMD_LIST && *arg == NUL) + { + // ":sign list": list all defined signs + for (sign_T *sp = first_sign; sp != NULL && !got_int; sp = sp->sn_next) + sign_list_defined(sp); + } + else if (*arg == NUL) + { + emsg(_(e_missing_sign_name)); + } + else + { + + // Isolate the sign name. If it's a number skip leading zeroes, + // so that "099" and "99" are the same sign. But keep "0". + p = skiptowhite(arg); + if (*p != NUL) + *p++ = NUL; + + while (arg[0] == '0' && arg[1] != NUL) + ++arg; + + char_u *name = vim_strsave(arg); + + if (idx == SIGNCMD_DEFINE) + sign_define_cmd(name, p); + else if (idx == SIGNCMD_LIST) + // ":sign list {name}" + sign_list_by_name(name); + else + // ":sign undefine {name}" + sign_undefine_by_name(name, TRUE); + + vim_free(name); } } @@ -1731,39 +1756,44 @@ ex_sign(exarg_T *eap) static void sign_getinfo(sign_T *sp, dict_T *retdict) { - char_u *p; - dict_add_string(retdict, "name", sp->sn_name); + if (sp->sn_icon != NULL) dict_add_string(retdict, "icon", sp->sn_icon); + if (sp->sn_text != NULL) dict_add_string(retdict, "text", sp->sn_text); + if (sp->sn_priority > 0) dict_add_number(retdict, "priority", sp->sn_priority); + if (sp->sn_line_hl > 0) { - p = get_highlight_name_ext(NULL, sp->sn_line_hl - 1, FALSE); + char_u *p = get_highlight_name_ext(NULL, sp->sn_line_hl - 1, FALSE); if (p == NULL) p = (char_u *)"NONE"; dict_add_string(retdict, "linehl", p); } + if (sp->sn_text_hl > 0) { - p = get_highlight_name_ext(NULL, sp->sn_text_hl - 1, FALSE); + char_u *p = get_highlight_name_ext(NULL, sp->sn_text_hl - 1, FALSE); if (p == NULL) p = (char_u *)"NONE"; dict_add_string(retdict, "texthl", p); } + if (sp->sn_cul_hl > 0) { - p = get_highlight_name_ext(NULL, sp->sn_cul_hl - 1, FALSE); + char_u *p = get_highlight_name_ext(NULL, sp->sn_cul_hl - 1, FALSE); if (p == NULL) p = (char_u *)"NONE"; dict_add_string(retdict, "culhl", p); } + if (sp->sn_num_hl > 0) { - p = get_highlight_name_ext(NULL, sp->sn_num_hl - 1, FALSE); + char_u *p = get_highlight_name_ext(NULL, sp->sn_num_hl - 1, FALSE); if (p == NULL) p = (char_u *)"NONE"; dict_add_string(retdict, "numhl", p); @@ -1778,7 +1808,6 @@ static void sign_getlist(char_u *name, list_T *retlist) { sign_T *sp = first_sign; - dict_T *dict; if (name != NULL) { @@ -1789,10 +1818,13 @@ sign_getlist(char_u *name, list_T *retlist) for (; sp != NULL && !got_int; sp = sp->sn_next) { - if ((dict = dict_alloc_id(aid_sign_getlist)) == NULL) + dict_T *dict = dict_alloc_id(aid_sign_getlist); + if (dict == NULL) return; + if (list_append_dict(retlist, dict) == FAIL) return; + sign_getinfo(sp, dict); if (name != NULL) // handle only the specified sign @@ -1806,12 +1838,11 @@ sign_getlist(char_u *name, list_T *retlist) void get_buffer_signs(buf_T *buf, list_T *l) { - sign_entry_T *sign; - dict_T *d; - + sign_entry_T *sign = NULL; FOR_ALL_SIGNS_IN_BUF(buf, sign) { - if ((d = sign_get_info(sign)) != NULL) + dict_T *d = sign_get_info(sign); + if (d != NULL) list_append_dict(l, d); } } @@ -1826,31 +1857,33 @@ sign_get_placed_in_buf(buf_T *buf, char_u *sign_group, list_T *retlist) { - dict_T *d; - list_T *l; - sign_entry_T *sign; - dict_T *sdict; - - if ((d = dict_alloc_id(aid_sign_getplaced_dict)) == NULL) + dict_T *d = dict_alloc_id(aid_sign_getplaced_dict); + if (d == NULL) return; + list_append_dict(retlist, d); dict_add_number(d, "bufnr", (long)buf->b_fnum); - if ((l = list_alloc_id(aid_sign_getplaced_list)) == NULL) + list_T *l = list_alloc_id(aid_sign_getplaced_list); + if (l == NULL) return; + dict_add_list(d, "signs", l); + sign_entry_T *sign = NULL; FOR_ALL_SIGNS_IN_BUF(buf, sign) { if (!sign_in_group(sign, sign_group)) continue; + if ((lnum == 0 && sign_id == 0) || (sign_id == 0 && lnum == sign->se_lnum) || (lnum == 0 && sign_id == sign->se_id) || (lnum == sign->se_lnum && sign_id == sign->se_id)) { - if ((sdict = sign_get_info(sign)) != NULL) + dict_T *sdict = sign_get_info(sign); + if (sdict != NULL) list_append_dict(l, sdict); } } @@ -1869,12 +1902,16 @@ sign_get_placed(buf_T *buf, list_T *retlist) { if (buf != NULL) + { sign_get_placed_in_buf(buf, lnum, sign_id, sign_group, retlist); + } else { FOR_ALL_BUFFERS(buf) + { if (buf->b_signlist != NULL) sign_get_placed_in_buf(buf, 0, sign_id, sign_group, retlist); + } } } @@ -1886,11 +1923,12 @@ sign_get_placed(buf_T *buf, void sign_gui_started(void) { - sign_T *sp; - + sign_T *sp = NULL; FOR_ALL_SIGNS(sp) + { if (sp->sn_icon != NULL) sp->sn_image = gui_mch_register_sign(sp->sn_icon); + } } # endif @@ -1900,10 +1938,10 @@ sign_gui_started(void) static void sign_list_defined(sign_T *sp) { - char_u *p; char lbuf[MSG_BUF_LEN]; smsg("sign %s", sp->sn_name); + if (sp->sn_icon != NULL) { msg_puts(" icon="); @@ -1915,47 +1953,57 @@ sign_list_defined(sign_T *sp) msg_puts(_(" (not supported)")); # endif } + if (sp->sn_text != NULL) { msg_puts(" text="); msg_outtrans(sp->sn_text); } + if (sp->sn_priority > 0) { vim_snprintf(lbuf, MSG_BUF_LEN, " priority=%d", sp->sn_priority); msg_puts(lbuf); } + if (sp->sn_line_hl > 0) { msg_puts(" linehl="); - p = get_highlight_name_ext(NULL, sp->sn_line_hl - 1, FALSE); + + char_u *p = get_highlight_name_ext(NULL, sp->sn_line_hl - 1, FALSE); if (p == NULL) msg_puts("NONE"); else msg_puts((char *)p); } + if (sp->sn_text_hl > 0) { msg_puts(" texthl="); - p = get_highlight_name_ext(NULL, sp->sn_text_hl - 1, FALSE); + + char_u *p = get_highlight_name_ext(NULL, sp->sn_text_hl - 1, FALSE); if (p == NULL) msg_puts("NONE"); else msg_puts((char *)p); } + if (sp->sn_cul_hl > 0) { msg_puts(" culhl="); - p = get_highlight_name_ext(NULL, sp->sn_cul_hl - 1, FALSE); + + char_u *p = get_highlight_name_ext(NULL, sp->sn_cul_hl - 1, FALSE); if (p == NULL) msg_puts("NONE"); else msg_puts((char *)p); } + if (sp->sn_num_hl > 0) { msg_puts(" numhl="); - p = get_highlight_name_ext(NULL, sp->sn_num_hl - 1, FALSE); + + char_u *p = get_highlight_name_ext(NULL, sp->sn_num_hl - 1, FALSE); if (p == NULL) msg_puts("NONE"); else @@ -1979,10 +2027,12 @@ sign_undefine(sign_T *sp, sign_T *sp_prev) } # endif vim_free(sp->sn_text); + if (sp_prev == NULL) first_sign = sp->sn_next; else sp_prev->sn_next = sp->sn_next; + vim_free(sp); } @@ -1990,11 +2040,12 @@ sign_undefine(sign_T *sp, sign_T *sp_prev) void * sign_get_image(int typenr) // the attribute which may have a sign { - sign_T *sp; - + sign_T *sp = NULL; FOR_ALL_SIGNS(sp) + { if (sp->sn_typenr == typenr) return sp->sn_image; + } return NULL; } # endif @@ -2026,14 +2077,15 @@ static enum static char_u * get_nth_sign_name(int idx) { - int current_idx; - sign_T *sp; + int current_idx = 0; + sign_T *sp = NULL; // Complete with name of signs already defined - current_idx = 0; FOR_ALL_SIGNS(sp) + { if (current_idx++ == idx) return sp->sn_name; + } return NULL; } @@ -2043,14 +2095,11 @@ get_nth_sign_name(int idx) static char_u * get_nth_sign_group_name(int idx) { - int current_idx; - int todo; - hashitem_T *hi; - signgroup_T *group; + int current_idx = 0; + int todo = (int)sg_table.ht_used; + hashitem_T *hi = NULL; // Complete with name of sign groups already defined - current_idx = 0; - todo = (int)sg_table.ht_used; FOR_ALL_HASHTAB_ITEMS(&sg_table, hi, todo) { if (!HASHITEM_EMPTY(hi)) @@ -2058,7 +2107,7 @@ get_nth_sign_group_name(int idx) --todo; if (current_idx++ == idx) { - group = HI2SG(hi); + signgroup_T *group = HI2SG(hi); return group->sg_name; } } @@ -2126,9 +2175,9 @@ set_context_in_sign_cmd(expand_T *xp, char_u *arg) xp->xp_pattern = arg; end_subcmd = skiptowhite(arg); + // expand subcmd name + // :sign {subcmd} if (*end_subcmd == NUL) - // expand subcmd name - // :sign {subcmd} return; cmd_idx = sign_cmd_idx(arg, end_subcmd); @@ -2250,16 +2299,17 @@ sign_define_from_dict(char_u *name_arg, dict_T *dict) int prio = -1; int retval = -1; + if (name_arg == NULL && dict == NULL) + return retval; + if (name_arg == NULL) - { - if (dict == NULL) - return -1; name = dict_get_string(dict, "name", TRUE); - } else name = vim_strsave(name_arg); + if (name == NULL || name[0] == NUL) goto cleanup; + if (dict != NULL) { icon = dict_get_string(dict, "icon", TRUE); @@ -2294,16 +2344,16 @@ cleanup: static void sign_define_multiple(list_T *l, list_T *retlist) { - listitem_T *li; - int retval; - + listitem_T *li = NULL; FOR_ALL_LIST_ITEMS(l, li) { - retval = -1; + int retval = -1; + if (li->li_tv.v_type == VAR_DICT) retval = sign_define_from_dict(NULL, li->li_tv.vval.v_dict); else emsg(_(e_dictionary_required)); + list_append_number(retlist, retval); } } @@ -2314,8 +2364,6 @@ sign_define_multiple(list_T *l, list_T *retlist) void f_sign_define(typval_T *argvars, typval_T *rettv) { - char_u *name; - if (in_vim9script() && (check_for_string_or_list_arg(argvars, 0) == FAIL || check_for_opt_dict_arg(argvars, 1) == FAIL)) return; @@ -2333,7 +2381,7 @@ f_sign_define(typval_T *argvars, typval_T *rettv) // Define a single sign rettv->vval.v_number = -1; - name = tv_get_string_chk(&argvars[0]); + char_u *name = tv_get_string_chk(&argvars[0]); if (name == NULL) return; @@ -2350,14 +2398,13 @@ f_sign_define(typval_T *argvars, typval_T *rettv) void f_sign_getdefined(typval_T *argvars, typval_T *rettv) { - char_u *name = NULL; - if (rettv_list_alloc_id(rettv, aid_sign_getdefined) == FAIL) return; if (in_vim9script() && check_for_opt_string_arg(argvars, 0) == FAIL) return; + char_u *name = NULL; if (argvars[0].v_type != VAR_UNKNOWN) name = tv_get_string(&argvars[0]); @@ -2371,12 +2418,9 @@ void f_sign_getplaced(typval_T *argvars, typval_T *rettv) { buf_T *buf = NULL; - dict_T *dict; - dictitem_T *di; linenr_T lnum = 0; int sign_id = 0; char_u *group = NULL; - int notanum = FALSE; if (rettv_list_alloc_id(rettv, aid_sign_getplaced) == FAIL) return; @@ -2397,27 +2441,36 @@ f_sign_getplaced(typval_T *argvars, typval_T *rettv) { if (check_for_nonnull_dict_arg(argvars, 1) == FAIL) return; - dict = argvars[1].vval.v_dict; + + dictitem_T *di = NULL; + dict_T *dict = argvars[1].vval.v_dict; + if ((di = dict_find(dict, (char_u *)"lnum", -1)) != NULL) { // get signs placed at this line - (void)tv_get_number_chk(&di->di_tv, ¬anum); + int notanum = FALSE; + tv_get_number_chk(&di->di_tv, ¬anum); if (notanum) return; + lnum = tv_get_lnum(&di->di_tv); } + if ((di = dict_find(dict, (char_u *)"id", -1)) != NULL) { // get sign placed with this identifier + int notanum = FALSE; sign_id = (int)tv_get_number_chk(&di->di_tv, ¬anum); if (notanum) return; } + if ((di = dict_find(dict, (char_u *)"group", -1)) != NULL) { group = tv_get_string_chk(&di->di_tv); if (group == NULL) return; + if (*group == '\0') // empty string means global group group = NULL; } @@ -2433,11 +2486,7 @@ f_sign_getplaced(typval_T *argvars, typval_T *rettv) 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; if (in_vim9script() && (check_for_number_arg(argvars, 0) == FAIL || @@ -2445,10 +2494,12 @@ f_sign_jump(typval_T *argvars, typval_T *rettv) check_for_buffer_arg(argvars, 2) == FAIL)) return; + int notanum = FALSE; // Sign identifier - sign_id = (int)tv_get_number_chk(&argvars[0], ¬anum); + int sign_id = (int)tv_get_number_chk(&argvars[0], ¬anum); if (notanum) return; + if (sign_id <= 0) { emsg(_(e_invalid_argument)); @@ -2459,8 +2510,11 @@ f_sign_jump(typval_T *argvars, typval_T *rettv) 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); @@ -2469,7 +2523,7 @@ f_sign_jump(typval_T *argvars, typval_T *rettv) } // Buffer to place the sign - buf = get_buf_arg(&argvars[2]); + buf_T *buf = get_buf_arg(&argvars[2]); if (buf == NULL) goto cleanup; @@ -2494,10 +2548,9 @@ sign_place_from_dict(typval_T *id_tv, char_u *group = NULL; char_u *sign_name = NULL; buf_T *buf = NULL; - dictitem_T *di; + dictitem_T *di = NULL; linenr_T lnum = 0; int prio = -1; - int notanum = FALSE; int ret_sign_id = -1; // sign identifier @@ -2507,13 +2560,19 @@ sign_place_from_dict(typval_T *id_tv, if (di != NULL) id_tv = &di->di_tv; } + if (id_tv == NULL) + { sign_id = 0; + } else { + int notanum = FALSE; sign_id = tv_get_number_chk(id_tv, ¬anum); + if (notanum) return -1; + if (sign_id < 0) { emsg(_(e_invalid_argument)); @@ -2528,15 +2587,21 @@ sign_place_from_dict(typval_T *id_tv, if (di != NULL) group_tv = &di->di_tv; } + if (group_tv == NULL) + { group = NULL; // global group + } else { group = 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); @@ -2552,8 +2617,10 @@ sign_place_from_dict(typval_T *id_tv, if (di != NULL) name_tv = &di->di_tv; } + if (name_tv == NULL) goto cleanup; + sign_name = tv_get_string_chk(name_tv); if (sign_name == NULL) goto cleanup; @@ -2565,8 +2632,10 @@ sign_place_from_dict(typval_T *id_tv, 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; @@ -2587,6 +2656,7 @@ sign_place_from_dict(typval_T *id_tv, di = dict_find(dict, (char_u *)"priority", -1); if (di != NULL) { + int notanum = FALSE; prio = (int)tv_get_number_chk(&di->di_tv, ¬anum); if (notanum) goto cleanup; @@ -2608,7 +2678,6 @@ void f_sign_place(typval_T *argvars, typval_T *rettv) { dict_T *dict = NULL; - rettv->vval.v_number = -1; if (in_vim9script() && (check_for_number_arg(argvars, 0) == FAIL || @@ -2635,9 +2704,6 @@ f_sign_place(typval_T *argvars, typval_T *rettv) void f_sign_placelist(typval_T *argvars, typval_T *rettv) { - listitem_T *li; - int sign_id; - if (rettv_list_alloc(rettv) == FAIL) return; @@ -2648,14 +2714,17 @@ f_sign_placelist(typval_T *argvars, typval_T *rettv) return; // Process the List of sign attributes + listitem_T *li = NULL; FOR_ALL_LIST_ITEMS(argvars[0].vval.v_list, li) { - sign_id = -1; + int sign_id = -1; + if (li->li_tv.v_type == VAR_DICT) sign_id = sign_place_from_dict(NULL, NULL, NULL, NULL, li->li_tv.vval.v_dict); else emsg(_(e_dictionary_required)); + list_append_number(rettv->vval.v_list, sign_id); } } @@ -2666,16 +2735,14 @@ f_sign_placelist(typval_T *argvars, typval_T *rettv) static void sign_undefine_multiple(list_T *l, list_T *retlist) { - char_u *name; - listitem_T *li; - int retval; - + listitem_T *li = NULL; FOR_ALL_LIST_ITEMS(l, li) { - retval = -1; - name = tv_get_string_chk(&li->li_tv); + int retval = -1; + char_u *name = tv_get_string_chk(&li->li_tv); if (name != NULL && (sign_undefine_by_name(name, TRUE) == OK)) retval = 0; + list_append_number(retlist, retval); } } @@ -2686,7 +2753,6 @@ sign_undefine_multiple(list_T *l, list_T *retlist) void f_sign_undefine(typval_T *argvars, typval_T *rettv) { - char_u *name; if (in_vim9script() && check_for_opt_string_or_list_arg(argvars, 0) == FAIL) return; @@ -2712,7 +2778,7 @@ f_sign_undefine(typval_T *argvars, typval_T *rettv) else { // Free only the specified sign - name = tv_get_string_chk(&argvars[0]); + char_u *name = tv_get_string_chk(&argvars[0]); if (name == NULL) return; @@ -2728,37 +2794,39 @@ f_sign_undefine(typval_T *argvars, typval_T *rettv) static 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 = tv_get_string(group_tv); - else - group = dict_get_string(dict, "group", FALSE); + group = (group_tv != NULL) ? tv_get_string(group_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; + return retval; } } if (dict != NULL) { - if ((di = dict_find(dict, (char_u *)"buffer", -1)) != NULL) + dictitem_T *di = di = dict_find(dict, (char_u *)"buffer", -1); + if (di != NULL) { buf = get_buf_arg(&di->di_tv); if (buf == NULL) goto cleanup; } + if (dict_has_key(dict, "id")) { sign_id = dict_get_number(dict, "id"); @@ -2813,8 +2881,10 @@ signcolumn_on(win_T *wp) if (*wp->w_p_scl == 'n') return FALSE; + if (*wp->w_p_scl == 'y') return TRUE; + return (get_first_valid_sign(wp) != NULL # ifdef FEAT_NETBEANS_INTG || wp->w_buffer->b_has_sign_column @@ -2829,7 +2899,6 @@ void f_sign_unplace(typval_T *argvars, typval_T *rettv) { dict_T *dict = NULL; - rettv->vval.v_number = -1; if ((check_for_string_arg(argvars, 0) == FAIL || @@ -2848,9 +2917,6 @@ f_sign_unplace(typval_T *argvars, typval_T *rettv) void f_sign_unplacelist(typval_T *argvars, typval_T *rettv) { - listitem_T *li; - int retval; - if (rettv_list_alloc(rettv) == FAIL) return; @@ -2860,13 +2926,16 @@ f_sign_unplacelist(typval_T *argvars, typval_T *rettv) if (check_for_list_arg(argvars, 0) == FAIL) return; + listitem_T *li = NULL; FOR_ALL_LIST_ITEMS(argvars[0].vval.v_list, li) { - retval = -1; + int retval = -1; + if (li->li_tv.v_type == VAR_DICT) retval = sign_unplace_from_dict(NULL, li->li_tv.vval.v_dict); else emsg(_(e_dictionary_required)); + list_append_number(rettv->vval.v_list, retval); } } diff --git a/src/version.c b/src/version.c index f81cf12bee..b569807722 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 885, /**/ 884, /**/