From fb9abd7d993cf2166b73810c7621f432bedd325d Mon Sep 17 00:00:00 2001 From: Andrej Zieger Date: Tue, 7 May 2019 08:26:09 +0200 Subject: vim-patch:8.1.0614: placing signs can be complicated Problem: Placing signs can be complicated. Solution: Add functions for defining and placing signs. Introduce a group name to avoid different plugins using the same signs. (Yegappan Lakshmanan, closes vim/vim#3652) https://github.com/vim/vim/commit/162b71479bd4dcdb3a2ef9198a1444f6f99e6843 --- src/nvim/buffer.c | 250 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 192 insertions(+), 58 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index a5ad1f1a11..da65682fbe 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -805,7 +805,7 @@ free_buffer_stuff( hash_init(&buf->b_vars->dv_hashtab); buf_init_changedtick(buf); uc_clear(&buf->b_ucmds); // clear local user commands - buf_delete_signs(buf); // delete any signs + buf_delete_signs(buf, (char_u *)"*"); // delete any signs bufhl_clear_all(buf); // delete any highligts map_clear_int(buf, MAP_ALL_MODES, true, false); // clear local mappings map_clear_int(buf, MAP_ALL_MODES, true, true); // clear local abbrevs @@ -5256,13 +5256,16 @@ bool find_win_for_buf(buf_T *buf, win_T **wp, tabpage_T **tp) } /* - * Insert the sign into the signlist. + * Insert a new sign into the signlist for buffer 'buf' between the 'prev' and + * 'next' signs. */ static void insert_sign( buf_T *buf, // buffer to store sign in signlist_T *prev, // previous sign entry signlist_T *next, // next sign entry int id, // sign ID + char_u *group, // sign group; NULL for global group + int prio, // sign priority linenr_T lnum, // line number which gets the mark int typenr // typenr of sign we are adding ) @@ -5271,6 +5274,11 @@ static void insert_sign( newsign->id = id; newsign->lnum = lnum; newsign->typenr = typenr; + if (group != NULL) + newsign->group = vim_strsave(group); + else + newsign->group = NULL; + newsign->priority = prio; newsign->next = next; newsign->prev = prev; if (next != NULL) { @@ -5279,8 +5287,8 @@ static void insert_sign( buf->b_signcols_max = -1; if (prev == NULL) { - /* When adding first sign need to redraw the windows to create the - * column for signs. */ + // When adding first sign need to redraw the windows to create the + // column for signs. if (buf->b_signlist == NULL) { redraw_buf_later(buf, NOT_VALID); changed_cline_bef_curs(); @@ -5384,12 +5392,75 @@ int buf_signcols(buf_T *buf) return buf->b_signcols; } +/* + * Insert a new sign sorted by line number and sign priority. + */ +static void insert_sign_by_lnum_prio( + buf_T *buf, // buffer to store sign in + signlist_T *prev, // previous sign entry + int id, // sign ID + char_u *group, // sign group; NULL for global group + int prio, // sign priority + linenr_T lnum, // line number which gets the mark + int typenr // typenr of sign we are adding +) +{ + signlist_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->lnum == lnum && prev->priority <= prio) { + prev = prev->prev; + } + if (prev == NULL) { + sign = buf->b_signlist; + } else { + sign = prev->next; + } + + insert_sign(buf, prev, sign, id, group, prio, lnum, typenr); +} + +/* + * Returns TRUE if 'sign' is in 'group'. + * A sign can either be in the global group (sign->group == NULL) + * or in a named group. If 'group' is '*', then the sign is part of the group. + */ +int sign_in_group(signlist_T *sign, char_u *group) +{ + return ((group != NULL && STRCMP(group, "*") == 0) || + (group == NULL && sign->group == NULL) || + (group != NULL && sign->group != NULL && + STRCMP(group, sign->group) == 0)); +} + +/* + * Return information about a sign in a Dict + */ +dict_T * sign_get_info(signlist_T *sign) +{ + dict_T *d; + + if ((d = tv_dict_alloc()) == NULL) { + return NULL; + } + tv_dict_add_nr(d, S_LEN("id"), sign->id); + tv_dict_add_str(d, S_LEN("group"), (sign->group == NULL) ? (char_u *)"" : sign->group); + tv_dict_add_nr(d, S_LEN("lnum"), sign->lnum); + tv_dict_add_str(d, S_LEN("name"), sign_typenr2name(sign->typenr)); + tv_dict_add_nr(d, S_LEN("priority"), sign->priority); + + return d; +} + /* * Add the sign into the signlist. Find the right spot to do it though. */ void buf_addsign( buf_T *buf, // buffer to store sign in int id, // sign ID + char_u *group, // sign group + int prio, // sign priority linenr_T lnum, // line number which gets the mark int typenr // typenr of sign we are adding ) @@ -5399,38 +5470,21 @@ void buf_addsign( signlist_T *prev; // the previous sign prev = NULL; - for (sign = buf->b_signlist; sign != NULL; sign = sign->next) { - if (lnum == sign->lnum && id == sign->id) { - sign->typenr = typenr; - return; + FOR_ALL_SIGNS_IN_BUF(buf) { + if (lnum == sign->lnum && id == sign->id && + sign_in_group(sign, group)) { + // Update an existing sign + sign->typenr = typenr; + return; } else if ((lnum == sign->lnum && id != sign->id) || (id < 0 && lnum < sign->lnum)) { - // keep signs sorted by lnum: insert new sign at head of list for - // this lnum - while (prev != NULL && prev->lnum == lnum) { - prev = prev->prev; - } - if (prev == NULL) { - sign = buf->b_signlist; - } else { - sign = prev->next; - } - insert_sign(buf, prev, sign, id, lnum, typenr); + insert_sign_by_lnum_prio(buf, prev, id, group, prio, lnum, typenr); return; } prev = sign; } - // insert new sign at head of list for this lnum - while (prev != NULL && prev->lnum == lnum) { - prev = prev->prev; - } - if (prev == NULL) { - sign = buf->b_signlist; - } else { - sign = prev->next; - } - insert_sign(buf, prev, sign, id, lnum, typenr); + insert_sign_by_lnum_prio(buf, prev, id, group, prio, lnum, typenr); // Having more than one sign with _the same type_ and on the _same line_ is // unwanted, let's prevent it. @@ -5451,13 +5505,14 @@ void buf_addsign( linenr_T buf_change_sign_type( buf_T *buf, // buffer to store sign in int markId, // sign ID + char_u *group, // sign group int typenr // typenr of sign we are adding ) { signlist_T *sign; // a sign in the signlist - for (sign = buf->b_signlist; sign != NULL; sign = sign->next) { - if (sign->id == markId) { + FOR_ALL_SIGNS_IN_BUF(buf) { + if (sign->id == markId && sign_in_group(sign, group)) { sign->typenr = typenr; return sign->lnum; } @@ -5484,7 +5539,7 @@ int buf_getsigntype(buf_T *buf, linenr_T lnum, SignType type, signlist_T *matches[9]; int nr_matches = 0; - for (sign = buf->b_signlist; sign != NULL; sign = sign->next) { + FOR_ALL_SIGNS_IN_BUF(buf) { if (sign->lnum == lnum && (type == SIGN_ANY || (type == SIGN_TEXT @@ -5517,9 +5572,20 @@ int buf_getsigntype(buf_T *buf, linenr_T lnum, SignType type, return 0; } +/* + * Delete sign 'id' in group 'group' from buffer 'buf'. + * If 'id' is zero, then delete all the signs in group 'group'. Otherwise + * delete only the specified sign. + * If 'group' is '*', then delete the sign in all the groups. If 'group' is + * NULL, then delete the sign in the global group. Otherwise delete the sign in + * the specified group. + * Returns the line number of the deleted sign. If multiple signs are deleted, + * then returns the line number of the last sign deleted. + */ linenr_T buf_delsign( buf_T *buf, // buffer sign is stored in - int id // sign id + int id, // sign id + char_u *group// sign group ) { signlist_T **lastp; // pointer to pointer to current sign @@ -5532,13 +5598,16 @@ linenr_T buf_delsign( lnum = 0; for (sign = buf->b_signlist; sign != NULL; sign = next) { next = sign->next; - if (sign->id == id) { + if ((id == 0 || sign->id == id) && sign_in_group(sign, group)) { *lastp = next; if (next != NULL) { next->prev = sign->prev; } lnum = sign->lnum; + xfree(sign->group); xfree(sign); + // Check whether only one sign needs to be deleted + if (group == NULL || (*group != '*' && id != 0)) break; } else { lastp = &sign->next; @@ -5557,19 +5626,20 @@ linenr_T buf_delsign( /* - * Find the line number of the sign with the requested id. If the sign does - * not exist, return 0 as the line number. This will still let the correct file - * get loaded. + * Find the line number of the sign with the requested id in group 'group'. If + * the sign does not exist, return 0 as the line number. This will still let + * the correct file get loaded. */ int buf_findsign( buf_T *buf, // buffer to store sign in - int id // sign ID + int id, // sign ID + char_u *group // sign group ) { signlist_T *sign; // a sign in the signlist - for (sign = buf->b_signlist; sign != NULL; sign = sign->next) { - if (sign->id == id) { + FOR_ALL_SIGNS_IN_BUF(buf) { + if (sign->id == id && sign_in_group(sign, group)){ return (int)sign->lnum; } } @@ -5577,6 +5647,49 @@ int buf_findsign( return 0; } +/* + * Return the sign at line 'lnum' in buffer 'buf'. Returns NULL if a sign is + * not found at the line. + */ +static signlist_T * buf_getsign_at_line( + buf_T *buf, // buffer whose sign we are searching for + linenr_T lnum // line number of sign +) +{ + signlist_T *sign; // a sign in the signlist + + FOR_ALL_SIGNS_IN_BUF(buf) { + if (sign->lnum == lnum) { + return sign; + } + } + + return NULL; +} + +/* + * Return the sign with identifier 'id' in group 'group' placed in buffer 'buf' + */ +signlist_T *buf_getsign_with_id( + buf_T *buf, // buffer whose sign we are searching for + int id, // sign identifier + char_u *group// sign group +) +{ + signlist_T *sign; // a sign in the signlist + + FOR_ALL_SIGNS_IN_BUF(buf) { + if (sign->id == id && sign_in_group(sign, group)) { + return sign; + } + } + + return NULL; +} + +/* + * Return the identifier of the sign at line number 'lnum' in buffer 'buf'. + */ int buf_findsign_id( buf_T *buf, // buffer whose sign we are searching for linenr_T lnum // line number of sign @@ -5584,10 +5697,9 @@ int buf_findsign_id( { signlist_T *sign; // a sign in the signlist - for (sign = buf->b_signlist; sign != NULL; sign = sign->next) { - if (sign->lnum == lnum) { - return sign->id; - } + sign = buf_getsign_at_line(buf, lnum); + if (sign != NULL) { + return sign->id; } return 0; @@ -5597,8 +5709,10 @@ int buf_findsign_id( /* * Delete signs in buffer "buf". */ -void buf_delete_signs(buf_T *buf) +buf_delete_signs(buf_T *buf, char_u *group) { + signlist_T *sign; + signlist_T **lastp; // pointer to pointer to current sign signlist_T *next; // When deleting the last sign need to redraw the windows to remove the @@ -5608,10 +5722,19 @@ void buf_delete_signs(buf_T *buf) changed_cline_bef_curs(); } - while (buf->b_signlist != NULL) { - next = buf->b_signlist->next; - xfree(buf->b_signlist); - buf->b_signlist = next; + lastp = &buf->b_signlist; + for (sign = buf->b_signlist; sign != NULL; sign = next) { + next = sign->next; + if (sign_in_group(sign, group)) { + *lastp = next; + if (next != NULL) { + next->prev = sign->prev; + } + xfree(sign->group); + xfree(sign); + } else { + lastp = &sign->next; + } } buf->b_signcols_max = -1; } @@ -5623,7 +5746,7 @@ void buf_delete_all_signs(void) { FOR_ALL_BUFFERS(buf) { if (buf->b_signlist != NULL) { - buf_delete_signs(buf); + buf_delete_signs(buf, (char_u *)"*"); } } } @@ -5631,11 +5754,12 @@ void buf_delete_all_signs(void) /* * List placed signs for "rbuf". If "rbuf" is NULL do it for all buffers. */ -void sign_list_placed(buf_T *rbuf) +void sign_list_placed(buf_T *rbuf, char_u *sign_group) { buf_T *buf; - signlist_T *p; + signlist_T *sign; char lbuf[BUFSIZ]; + char group[BUFSIZ]; MSG_PUTS_TITLE(_("\n--- Signs ---")); msg_putchar('\n'); @@ -5650,11 +5774,21 @@ void sign_list_placed(buf_T *rbuf) MSG_PUTS_ATTR(lbuf, HL_ATTR(HLF_D)); msg_putchar('\n'); } - for (p = buf->b_signlist; p != NULL && !got_int; p = p->next) { - vim_snprintf(lbuf, BUFSIZ, _(" line=%" PRId64 " id=%d name=%s"), - (int64_t)p->lnum, p->id, sign_typenr2name(p->typenr)); - MSG_PUTS(lbuf); - msg_putchar('\n'); + FOR_ALL_SIGNS_IN_BUF(buf) { + if (!sign_in_group(sign, sign_group)) { + continue; + } + if (sign->group != NULL) { + vim_snprintf(group, BUFSIZ, " group=%s", sign->group); + } else { + group[0] = '\0'; + } + vim_snprintf(lbuf, BUFSIZ, _(" line=%ld id=%d%s name=%s " + "priority=%d"), + (long)sign->lnum, sign->id, group, + sign_typenr2name(sign->typenr), sign->priority); + MSG_PUTS(lbuf); + msg_putchar('\n'); } if (rbuf != NULL) { break; @@ -5675,7 +5809,7 @@ void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_a curbuf->b_signcols_max = -1; lastp = &curbuf->b_signlist; - for (sign = curbuf->b_signlist; sign != NULL; sign = next) { + FOR_ALL_SIGNS_IN_BUF(curbuf) { next = sign->next; if (sign->lnum >= line1 && sign->lnum <= line2) { if (amount == MAXLNUM) { -- cgit From 4f844c587c18b12ffb9253f461557a8a8da258af Mon Sep 17 00:00:00 2001 From: Andrej Zieger Date: Thu, 9 May 2019 17:30:23 +0200 Subject: vim-patch:8.1.0632: using sign group names is inefficient Problem: Using sign group names is inefficient. Solution: Store group names in a hash table and use a reference to them. Also remove unnecessary use of ":exe" from the tests. (Yegappan Lakshmanan, closes vim/vim#3715) https://github.com/vim/vim/commit/7a2d9892b7158edf8dc48e9bcaaae70a40787b37 --- src/nvim/buffer.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 89 insertions(+), 11 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index da65682fbe..3ddd2a7163 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -64,6 +64,7 @@ #include "nvim/quickfix.h" #include "nvim/regexp.h" #include "nvim/screen.h" +#include "nvim/sign.h" #include "nvim/spell.h" #include "nvim/strings.h" #include "nvim/syntax.h" @@ -5255,6 +5256,70 @@ bool find_win_for_buf(buf_T *buf, win_T **wp, tabpage_T **tp) return false; } +static hashtab_T sg_table; // sign group (signgroup_T) hashtable + +/* + * A new sign in group 'groupname' is added. If the group is not present, + * create it. Otherwise reference the group. + */ +static signgroup_T * sign_group_ref(char_u *groupname) +{ + static int initialized = FALSE; + hash_T hash; + hashitem_T *hi; + signgroup_T *group; + + if (!initialized) { + initialized = TRUE; + hash_init(&sg_table); + } + + hash = hash_hash(groupname); + hi = hash_lookup(&sg_table, S_LEN(groupname), hash); + if (HASHITEM_EMPTY(hi)) + { + // new group + group = (signgroup_T *)xmalloc( + (unsigned)(sizeof(signgroup_T) + STRLEN(groupname))); + if (group == NULL) + return NULL; + STRCPY(group->sg_name, groupname); + group->refcount = 1; + hash_add_item(&sg_table, hi, group->sg_name, hash); + } + else + { + // existing group + group = HI2SG(hi); + group->refcount++; + } + + return group; +} + +/* + * A sign in group 'groupname' is removed. If all the signs in this group are + * removed, then remove the group. + */ +static void sign_group_unref(char_u *groupname) +{ + hashitem_T *hi; + signgroup_T *group; + + hi = hash_find(&sg_table, groupname); + if (!HASHITEM_EMPTY(hi)) + { + group = HI2SG(hi); + group->refcount--; + if (group->refcount == 0) + { + // All the signs in this group are removed + hash_remove(&sg_table, hi); + xfree(group); + } + } +} + /* * Insert a new sign into the signlist for buffer 'buf' between the 'prev' and * 'next' signs. @@ -5275,7 +5340,14 @@ static void insert_sign( newsign->lnum = lnum; newsign->typenr = typenr; if (group != NULL) - newsign->group = vim_strsave(group); + { + newsign->group = sign_group_ref(group); + if (newsign->group == NULL) + { + xfree(newsign); + return; + } + } else newsign->group = NULL; newsign->priority = prio; @@ -5431,7 +5503,7 @@ int sign_in_group(signlist_T *sign, char_u *group) return ((group != NULL && STRCMP(group, "*") == 0) || (group == NULL && sign->group == NULL) || (group != NULL && sign->group != NULL && - STRCMP(group, sign->group) == 0)); + STRCMP(group, sign->group->sg_name) == 0)); } /* @@ -5445,7 +5517,7 @@ dict_T * sign_get_info(signlist_T *sign) return NULL; } tv_dict_add_nr(d, S_LEN("id"), sign->id); - tv_dict_add_str(d, S_LEN("group"), (sign->group == NULL) ? (char_u *)"" : sign->group); + tv_dict_add_str(d, S_LEN("group"), (sign->group == NULL) ? (char_u *)"" : sign->group->sg_name); tv_dict_add_nr(d, S_LEN("lnum"), sign->lnum); tv_dict_add_str(d, S_LEN("name"), sign_typenr2name(sign->typenr)); tv_dict_add_nr(d, S_LEN("priority"), sign->priority); @@ -5459,7 +5531,7 @@ dict_T * sign_get_info(signlist_T *sign) void buf_addsign( buf_T *buf, // buffer to store sign in int id, // sign ID - char_u *group, // sign group + char_u *groupname, // sign group int prio, // sign priority linenr_T lnum, // line number which gets the mark int typenr // typenr of sign we are adding @@ -5472,19 +5544,19 @@ void buf_addsign( prev = NULL; FOR_ALL_SIGNS_IN_BUF(buf) { if (lnum == sign->lnum && id == sign->id && - sign_in_group(sign, group)) { + sign_in_group(sign, groupname)) { // Update an existing sign sign->typenr = typenr; return; } else if ((lnum == sign->lnum && id != sign->id) || (id < 0 && lnum < sign->lnum)) { - insert_sign_by_lnum_prio(buf, prev, id, group, prio, lnum, typenr); + insert_sign_by_lnum_prio(buf, prev, id, groupname, prio, lnum, typenr); return; } prev = sign; } - insert_sign_by_lnum_prio(buf, prev, id, group, prio, lnum, typenr); + insert_sign_by_lnum_prio(buf, prev, id, groupname, prio, lnum, typenr); // Having more than one sign with _the same type_ and on the _same line_ is // unwanted, let's prevent it. @@ -5604,7 +5676,8 @@ linenr_T buf_delsign( next->prev = sign->prev; } lnum = sign->lnum; - xfree(sign->group); + if (sign->group != NULL) + sign_group_unref(sign->group->sg_name); xfree(sign); // Check whether only one sign needs to be deleted if (group == NULL || (*group != '*' && id != 0)) @@ -5709,7 +5782,7 @@ int buf_findsign_id( /* * Delete signs in buffer "buf". */ -buf_delete_signs(buf_T *buf, char_u *group) +void buf_delete_signs(buf_T *buf, char_u *group) { signlist_T *sign; signlist_T **lastp; // pointer to pointer to current sign @@ -5730,7 +5803,9 @@ buf_delete_signs(buf_T *buf, char_u *group) if (next != NULL) { next->prev = sign->prev; } - xfree(sign->group); + if (sign->group != NULL) { + sign_group_unref(sign->group->sg_name); + } xfree(sign); } else { lastp = &sign->next; @@ -5775,11 +5850,14 @@ void sign_list_placed(buf_T *rbuf, char_u *sign_group) msg_putchar('\n'); } FOR_ALL_SIGNS_IN_BUF(buf) { + if (got_int) { + break; + } if (!sign_in_group(sign, sign_group)) { continue; } if (sign->group != NULL) { - vim_snprintf(group, BUFSIZ, " group=%s", sign->group); + vim_snprintf(group, BUFSIZ, " group=%s", sign->group->sg_name); } else { group[0] = '\0'; } -- cgit From 3ee55edd2e27dd66c3bf8c319929beb0a6426bb3 Mon Sep 17 00:00:00 2001 From: Andrej Zieger Date: Wed, 15 May 2019 22:02:10 +0200 Subject: vim-patch:8.1.0644: finding next sign ID is inefficient Problem: Finding next sign ID is inefficient. Solution: Add next_sign_id. (Yegappan Lakshmanan, closes vim/vim#3717) https://github.com/vim/vim/commit/6436cd83f90a0efc326798792e49e8ff96a43dce --- src/nvim/buffer.c | 76 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 14 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 3ddd2a7163..06207c93f2 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -5257,6 +5257,16 @@ bool find_win_for_buf(buf_T *buf, win_T **wp, tabpage_T **tp) } static hashtab_T sg_table; // sign group (signgroup_T) hashtable +static int next_sign_id = 1; // next sign id in the global group + +/* + * Initialize data needed for managing signs + */ + void +init_signs(void) +{ + hash_init(&sg_table); // sign group hash table +} /* * A new sign in group 'groupname' is added. If the group is not present, @@ -5264,16 +5274,10 @@ static hashtab_T sg_table; // sign group (signgroup_T) hashtable */ static signgroup_T * sign_group_ref(char_u *groupname) { - static int initialized = FALSE; hash_T hash; hashitem_T *hi; signgroup_T *group; - if (!initialized) { - initialized = TRUE; - hash_init(&sg_table); - } - hash = hash_hash(groupname); hi = hash_lookup(&sg_table, S_LEN(groupname), hash); if (HASHITEM_EMPTY(hi)) @@ -5285,6 +5289,7 @@ static signgroup_T * sign_group_ref(char_u *groupname) return NULL; STRCPY(group->sg_name, groupname); group->refcount = 1; + group->next_sign_id = 1; hash_add_item(&sg_table, hi, group->sg_name, hash); } else @@ -5320,6 +5325,49 @@ static void sign_group_unref(char_u *groupname) } } +/* + * Get the next free sign identifier in the specified group + */ + int +sign_group_get_next_signid(buf_T *buf, char_u *groupname) +{ + int id = 1; + signgroup_T *group = NULL; + signlist_T *sign; + hashitem_T *hi; + int found = FALSE; + + if (groupname != NULL) + { + hi = hash_find(&sg_table, groupname); + if (HASHITEM_EMPTY(hi)) + return id; + group = HI2SG(hi); + } + + // Search for the next usuable sign identifier + while (!found) + { + if (group == NULL) + id = next_sign_id++; // global group + else + id = group->next_sign_id++; + + // Check whether this sign is already placed in the buffer + found = TRUE; + FOR_ALL_SIGNS_IN_BUF(buf, sign) + { + if (id == sign->id && sign_in_group(sign, groupname)) + { + found = FALSE; // sign identifier is in use + break; + } + } + } + + return id; +} + /* * Insert a new sign into the signlist for buffer 'buf' between the 'prev' and * 'next' signs. @@ -5542,7 +5590,7 @@ void buf_addsign( signlist_T *prev; // the previous sign prev = NULL; - FOR_ALL_SIGNS_IN_BUF(buf) { + FOR_ALL_SIGNS_IN_BUF(buf, sign) { if (lnum == sign->lnum && id == sign->id && sign_in_group(sign, groupname)) { // Update an existing sign @@ -5583,7 +5631,7 @@ linenr_T buf_change_sign_type( { signlist_T *sign; // a sign in the signlist - FOR_ALL_SIGNS_IN_BUF(buf) { + FOR_ALL_SIGNS_IN_BUF(buf, sign) { if (sign->id == markId && sign_in_group(sign, group)) { sign->typenr = typenr; return sign->lnum; @@ -5611,7 +5659,7 @@ int buf_getsigntype(buf_T *buf, linenr_T lnum, SignType type, signlist_T *matches[9]; int nr_matches = 0; - FOR_ALL_SIGNS_IN_BUF(buf) { + FOR_ALL_SIGNS_IN_BUF(buf, sign) { if (sign->lnum == lnum && (type == SIGN_ANY || (type == SIGN_TEXT @@ -5711,7 +5759,7 @@ int buf_findsign( { signlist_T *sign; // a sign in the signlist - FOR_ALL_SIGNS_IN_BUF(buf) { + FOR_ALL_SIGNS_IN_BUF(buf, sign) { if (sign->id == id && sign_in_group(sign, group)){ return (int)sign->lnum; } @@ -5731,7 +5779,7 @@ static signlist_T * buf_getsign_at_line( { signlist_T *sign; // a sign in the signlist - FOR_ALL_SIGNS_IN_BUF(buf) { + FOR_ALL_SIGNS_IN_BUF(buf, sign) { if (sign->lnum == lnum) { return sign; } @@ -5751,7 +5799,7 @@ signlist_T *buf_getsign_with_id( { signlist_T *sign; // a sign in the signlist - FOR_ALL_SIGNS_IN_BUF(buf) { + FOR_ALL_SIGNS_IN_BUF(buf, sign) { if (sign->id == id && sign_in_group(sign, group)) { return sign; } @@ -5849,7 +5897,7 @@ void sign_list_placed(buf_T *rbuf, char_u *sign_group) MSG_PUTS_ATTR(lbuf, HL_ATTR(HLF_D)); msg_putchar('\n'); } - FOR_ALL_SIGNS_IN_BUF(buf) { + FOR_ALL_SIGNS_IN_BUF(buf, sign) { if (got_int) { break; } @@ -5887,7 +5935,7 @@ void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_a curbuf->b_signcols_max = -1; lastp = &curbuf->b_signlist; - FOR_ALL_SIGNS_IN_BUF(curbuf) { + FOR_ALL_SIGNS_IN_BUF(curbuf, sign) { next = sign->next; if (sign->lnum >= line1 && sign->lnum <= line2) { if (amount == MAXLNUM) { -- cgit From 09c236ba5c03732a7d7aa5f14f602d6f130f0057 Mon Sep 17 00:00:00 2001 From: Andrej Zieger Date: Thu, 16 May 2019 21:27:41 +0200 Subject: vim-patch:8.1.0658: deleting signs and completion for :sign is insufficient Problem: Deleting signs and completion for :sign is insufficient. Solution: Add deleting signs in a specified or any group from the current cursor location. Add group and priority to sign command completion. Add tests for different sign unplace commands. Update help text. Add tests for sign jump with group. Update help for sign jump. (Yegappan Lakshmanan, closes vim/vim#3731) https://github.com/vim/vim/commit/7d83bf4f2b785b46d87c7bc376fc9d0a862af782 --- src/nvim/buffer.c | 100 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 56 insertions(+), 44 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 06207c93f2..9ccbfa4dd1 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -5548,10 +5548,10 @@ static void insert_sign_by_lnum_prio( */ int sign_in_group(signlist_T *sign, char_u *group) { - return ((group != NULL && STRCMP(group, "*") == 0) || - (group == NULL && sign->group == NULL) || - (group != NULL && sign->group != NULL && - STRCMP(group, sign->group->sg_name) == 0)); + return ((group != NULL && STRCMP(group, "*") == 0) + || (group == NULL && sign->group == NULL) + || (group != NULL && sign->group != NULL + && STRCMP(group, sign->group->sg_name) == 0)); } /* @@ -5704,45 +5704,55 @@ int buf_getsigntype(buf_T *buf, linenr_T lnum, SignType type, */ linenr_T buf_delsign( buf_T *buf, // buffer sign is stored in + linenr_T atlnum, // sign at this line, 0 - at any line int id, // sign id char_u *group// sign group -) + ) { - signlist_T **lastp; // pointer to pointer to current sign - signlist_T *sign; // a sign in a b_signlist - signlist_T *next; // the next sign in a b_signlist - linenr_T lnum; // line number whose sign was deleted - - buf->b_signcols_max = -1; - lastp = &buf->b_signlist; - lnum = 0; - for (sign = buf->b_signlist; sign != NULL; sign = next) { - next = sign->next; - if ((id == 0 || sign->id == id) && sign_in_group(sign, group)) { - *lastp = next; - if (next != NULL) { - next->prev = sign->prev; - } - lnum = sign->lnum; - if (sign->group != NULL) - sign_group_unref(sign->group->sg_name); - xfree(sign); - // Check whether only one sign needs to be deleted - if (group == NULL || (*group != '*' && id != 0)) - break; - } else { - lastp = &sign->next; - } + signlist_T **lastp; // pointer to pointer to current sign + signlist_T *sign; // a sign in a b_signlist + signlist_T *next; // the next sign in a b_signlist + linenr_T lnum; // line number whose sign was deleted + + buf->b_signcols_max = -1; + lastp = &buf->b_signlist; + lnum = 0; + for (sign = buf->b_signlist; sign != NULL; sign = next) { + next = sign->next; + if ((id == 0 || sign->id == id) && + (atlnum == 0 || sign->lnum == atlnum) && + sign_in_group(sign, group)) { + *lastp = next; + if (next != NULL) { + next->prev = sign->prev; + } + lnum = sign->lnum; + if (sign->group != NULL) + sign_group_unref(sign->group->sg_name); + xfree(sign); + redraw_buf_line_later(buf, lnum); + // Check whether only one sign needs to be deleted + // If deleting a sign with a specific identifer in a particular + // group or deleting any sign at a particular line number, delete + // only one sign. + if (group == NULL + || (*group != '*' && id != 0) + || (*group == '*' && atlnum != 0)) { + break; + } + } else { + lastp = &sign->next; } + } - /* When deleted the last sign needs to redraw the windows to remove the - * sign column. */ - if (buf->b_signlist == NULL) { - redraw_buf_later(buf, NOT_VALID); - changed_cline_bef_curs(); - } + /* When deleted the last sign needs to redraw the windows to remove the + * sign column. */ + if (buf->b_signlist == NULL) { + redraw_buf_later(buf, NOT_VALID); + changed_cline_bef_curs(); + } - return lnum; + return lnum; } @@ -5770,17 +5780,18 @@ int buf_findsign( /* * Return the sign at line 'lnum' in buffer 'buf'. Returns NULL if a sign is - * not found at the line. + * not found at the line. If 'groupname' is NULL, searches in the global group. */ static signlist_T * buf_getsign_at_line( buf_T *buf, // buffer whose sign we are searching for - linenr_T lnum // line number of sign + linenr_T lnum, // line number of sign + char_u *groupname // sign group name ) { signlist_T *sign; // a sign in the signlist FOR_ALL_SIGNS_IN_BUF(buf, sign) { - if (sign->lnum == lnum) { + if (sign->lnum == lnum && sign_in_group(sign, groupname)) { return sign; } } @@ -5813,12 +5824,13 @@ signlist_T *buf_getsign_with_id( */ int buf_findsign_id( buf_T *buf, // buffer whose sign we are searching for - linenr_T lnum // line number of sign + linenr_T lnum, // line number of sign + char_u *groupname // sign group name ) { signlist_T *sign; // a sign in the signlist - sign = buf_getsign_at_line(buf, lnum); + sign = buf_getsign_at_line(buf, lnum, groupname); if (sign != NULL) { return sign->id; } @@ -5865,11 +5877,11 @@ void buf_delete_signs(buf_T *buf, char_u *group) /* * Delete all signs in all buffers. */ -void buf_delete_all_signs(void) +void buf_delete_all_signs(char_u *groupname) { FOR_ALL_BUFFERS(buf) { if (buf->b_signlist != NULL) { - buf_delete_signs(buf, (char_u *)"*"); + buf_delete_signs(buf, groupname); } } } -- cgit From 83025f0028ee5b1b6e09340fa419999643e3f8f6 Mon Sep 17 00:00:00 2001 From: Andrej Zieger Date: Sat, 18 May 2019 15:35:33 +0200 Subject: vim-patch:8.1.0673: functionality for signs is spread out over several files Problem: Functionality for signs is spread out over several files. Solution: Move most of the sign functionality into sign.c. (Yegappan Lakshmanan, closes vim/vim#3751) https://github.com/vim/vim/commit/bbea47075cc4e7826e9f8c203e4272ba023ed7b0 --- src/nvim/buffer.c | 618 ------------------------------------------------------ 1 file changed, 618 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 9ccbfa4dd1..1f4a1e0cd1 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -5256,172 +5256,6 @@ bool find_win_for_buf(buf_T *buf, win_T **wp, tabpage_T **tp) return false; } -static hashtab_T sg_table; // sign group (signgroup_T) hashtable -static int next_sign_id = 1; // next sign id in the global group - -/* - * Initialize data needed for managing signs - */ - void -init_signs(void) -{ - hash_init(&sg_table); // sign group hash table -} - -/* - * A new sign in group 'groupname' is added. If the group is not present, - * create it. Otherwise reference the group. - */ -static signgroup_T * sign_group_ref(char_u *groupname) -{ - hash_T hash; - hashitem_T *hi; - signgroup_T *group; - - hash = hash_hash(groupname); - hi = hash_lookup(&sg_table, S_LEN(groupname), hash); - if (HASHITEM_EMPTY(hi)) - { - // new group - group = (signgroup_T *)xmalloc( - (unsigned)(sizeof(signgroup_T) + STRLEN(groupname))); - if (group == NULL) - return NULL; - STRCPY(group->sg_name, groupname); - group->refcount = 1; - group->next_sign_id = 1; - hash_add_item(&sg_table, hi, group->sg_name, hash); - } - else - { - // existing group - group = HI2SG(hi); - group->refcount++; - } - - return group; -} - -/* - * A sign in group 'groupname' is removed. If all the signs in this group are - * removed, then remove the group. - */ -static void sign_group_unref(char_u *groupname) -{ - hashitem_T *hi; - signgroup_T *group; - - hi = hash_find(&sg_table, groupname); - if (!HASHITEM_EMPTY(hi)) - { - group = HI2SG(hi); - group->refcount--; - if (group->refcount == 0) - { - // All the signs in this group are removed - hash_remove(&sg_table, hi); - xfree(group); - } - } -} - -/* - * Get the next free sign identifier in the specified group - */ - int -sign_group_get_next_signid(buf_T *buf, char_u *groupname) -{ - int id = 1; - signgroup_T *group = NULL; - signlist_T *sign; - hashitem_T *hi; - int found = FALSE; - - if (groupname != NULL) - { - hi = hash_find(&sg_table, groupname); - if (HASHITEM_EMPTY(hi)) - return id; - group = HI2SG(hi); - } - - // Search for the next usuable sign identifier - while (!found) - { - if (group == NULL) - id = next_sign_id++; // global group - else - id = group->next_sign_id++; - - // Check whether this sign is already placed in the buffer - found = TRUE; - FOR_ALL_SIGNS_IN_BUF(buf, sign) - { - if (id == sign->id && sign_in_group(sign, groupname)) - { - found = FALSE; // sign identifier is in use - break; - } - } - } - - return id; -} - -/* - * Insert a new sign into the signlist for buffer 'buf' between the 'prev' and - * 'next' signs. - */ -static void insert_sign( - buf_T *buf, // buffer to store sign in - signlist_T *prev, // previous sign entry - signlist_T *next, // next sign entry - int id, // sign ID - char_u *group, // sign group; NULL for global group - int prio, // sign priority - linenr_T lnum, // line number which gets the mark - int typenr // typenr of sign we are adding -) -{ - signlist_T *newsign = xmalloc(sizeof(signlist_T)); - newsign->id = id; - newsign->lnum = lnum; - newsign->typenr = typenr; - if (group != NULL) - { - newsign->group = sign_group_ref(group); - if (newsign->group == NULL) - { - xfree(newsign); - return; - } - } - else - newsign->group = NULL; - newsign->priority = prio; - newsign->next = next; - newsign->prev = prev; - if (next != NULL) { - next->prev = newsign; - } - buf->b_signcols_max = -1; - - if (prev == NULL) { - // When adding first sign need to redraw the windows to create the - // column for signs. - if (buf->b_signlist == NULL) { - redraw_buf_later(buf, NOT_VALID); - changed_cline_bef_curs(); - } - - // first sign in signlist - buf->b_signlist = newsign; - } - else { - prev->next = newsign; - } -} - static int sign_compare(const void *a1, const void *a2) { const signlist_T *s1 = *(const signlist_T **)a1; @@ -5512,458 +5346,6 @@ int buf_signcols(buf_T *buf) return buf->b_signcols; } -/* - * Insert a new sign sorted by line number and sign priority. - */ -static void insert_sign_by_lnum_prio( - buf_T *buf, // buffer to store sign in - signlist_T *prev, // previous sign entry - int id, // sign ID - char_u *group, // sign group; NULL for global group - int prio, // sign priority - linenr_T lnum, // line number which gets the mark - int typenr // typenr of sign we are adding -) -{ - signlist_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->lnum == lnum && prev->priority <= prio) { - prev = prev->prev; - } - if (prev == NULL) { - sign = buf->b_signlist; - } else { - sign = prev->next; - } - - insert_sign(buf, prev, sign, id, group, prio, lnum, typenr); -} - -/* - * Returns TRUE if 'sign' is in 'group'. - * A sign can either be in the global group (sign->group == NULL) - * or in a named group. If 'group' is '*', then the sign is part of the group. - */ -int sign_in_group(signlist_T *sign, char_u *group) -{ - return ((group != NULL && STRCMP(group, "*") == 0) - || (group == NULL && sign->group == NULL) - || (group != NULL && sign->group != NULL - && STRCMP(group, sign->group->sg_name) == 0)); -} - -/* - * Return information about a sign in a Dict - */ -dict_T * sign_get_info(signlist_T *sign) -{ - dict_T *d; - - if ((d = tv_dict_alloc()) == NULL) { - return NULL; - } - tv_dict_add_nr(d, S_LEN("id"), sign->id); - tv_dict_add_str(d, S_LEN("group"), (sign->group == NULL) ? (char_u *)"" : sign->group->sg_name); - tv_dict_add_nr(d, S_LEN("lnum"), sign->lnum); - tv_dict_add_str(d, S_LEN("name"), sign_typenr2name(sign->typenr)); - tv_dict_add_nr(d, S_LEN("priority"), sign->priority); - - return d; -} - -/* - * Add the sign into the signlist. Find the right spot to do it though. - */ -void buf_addsign( - buf_T *buf, // buffer to store sign in - int id, // sign ID - char_u *groupname, // sign group - int prio, // sign priority - linenr_T lnum, // line number which gets the mark - int typenr // typenr of sign we are adding -) -{ - signlist_T **lastp; // pointer to pointer to current sign - signlist_T *sign; // a sign in the signlist - signlist_T *prev; // the previous sign - - prev = NULL; - FOR_ALL_SIGNS_IN_BUF(buf, sign) { - if (lnum == sign->lnum && id == sign->id && - sign_in_group(sign, groupname)) { - // Update an existing sign - sign->typenr = typenr; - return; - } else if ((lnum == sign->lnum && id != sign->id) - || (id < 0 && lnum < sign->lnum)) { - insert_sign_by_lnum_prio(buf, prev, id, groupname, prio, lnum, typenr); - return; - } - prev = sign; - } - - insert_sign_by_lnum_prio(buf, prev, id, groupname, prio, lnum, typenr); - - // Having more than one sign with _the same type_ and on the _same line_ is - // unwanted, let's prevent it. - - lastp = &buf->b_signlist; - for (sign = buf->b_signlist; sign != NULL; sign = sign->next) { - if (lnum == sign->lnum && sign->typenr == typenr && id != sign->id) { - *lastp = sign->next; - xfree(sign); - } else { - lastp = &sign->next; - } - } -} - -// For an existing, placed sign "markId" change the type to "typenr". -// Returns the line number of the sign, or zero if the sign is not found. -linenr_T buf_change_sign_type( - buf_T *buf, // buffer to store sign in - int markId, // sign ID - char_u *group, // sign group - int typenr // typenr of sign we are adding -) -{ - signlist_T *sign; // a sign in the signlist - - FOR_ALL_SIGNS_IN_BUF(buf, sign) { - if (sign->id == markId && sign_in_group(sign, group)) { - sign->typenr = typenr; - return sign->lnum; - } - } - - return (linenr_T)0; -} - - -/// Gets a sign from a given line. -/// -/// @param buf Buffer in which to search -/// @param lnum Line in which to search -/// @param type Type of sign to look for -/// @param idx if there multiple signs, this index will pick the n-th -// out of the most `max_signs` sorted ascending by Id. -/// @param max_signs the number of signs, with priority for the ones -// with the highest Ids. -/// @return Identifier of the matching sign, or 0 -int buf_getsigntype(buf_T *buf, linenr_T lnum, SignType type, - int idx, int max_signs) -{ - signlist_T *sign; // a sign in a b_signlist - signlist_T *matches[9]; - int nr_matches = 0; - - FOR_ALL_SIGNS_IN_BUF(buf, sign) { - if (sign->lnum == lnum - && (type == SIGN_ANY - || (type == SIGN_TEXT - && sign_get_text(sign->typenr) != NULL) - || (type == SIGN_LINEHL - && sign_get_attr(sign->typenr, SIGN_LINEHL) != 0) - || (type == SIGN_NUMHL - && sign_get_attr(sign->typenr, SIGN_NUMHL) != 0))) { - matches[nr_matches] = sign; - nr_matches++; - - if (nr_matches == ARRAY_SIZE(matches)) { - break; - } - } - } - - if (nr_matches > 0) { - if (nr_matches > max_signs) { - idx += nr_matches - max_signs; - } - - if (idx >= nr_matches) { - return 0; - } - - return matches[idx]->typenr; - } - - return 0; -} - -/* - * Delete sign 'id' in group 'group' from buffer 'buf'. - * If 'id' is zero, then delete all the signs in group 'group'. Otherwise - * delete only the specified sign. - * If 'group' is '*', then delete the sign in all the groups. If 'group' is - * NULL, then delete the sign in the global group. Otherwise delete the sign in - * the specified group. - * Returns the line number of the deleted sign. If multiple signs are deleted, - * then returns the line number of the last sign deleted. - */ -linenr_T buf_delsign( - buf_T *buf, // buffer sign is stored in - linenr_T atlnum, // sign at this line, 0 - at any line - int id, // sign id - char_u *group// sign group - ) -{ - signlist_T **lastp; // pointer to pointer to current sign - signlist_T *sign; // a sign in a b_signlist - signlist_T *next; // the next sign in a b_signlist - linenr_T lnum; // line number whose sign was deleted - - buf->b_signcols_max = -1; - lastp = &buf->b_signlist; - lnum = 0; - for (sign = buf->b_signlist; sign != NULL; sign = next) { - next = sign->next; - if ((id == 0 || sign->id == id) && - (atlnum == 0 || sign->lnum == atlnum) && - sign_in_group(sign, group)) { - *lastp = next; - if (next != NULL) { - next->prev = sign->prev; - } - lnum = sign->lnum; - if (sign->group != NULL) - sign_group_unref(sign->group->sg_name); - xfree(sign); - redraw_buf_line_later(buf, lnum); - // Check whether only one sign needs to be deleted - // If deleting a sign with a specific identifer in a particular - // group or deleting any sign at a particular line number, delete - // only one sign. - if (group == NULL - || (*group != '*' && id != 0) - || (*group == '*' && atlnum != 0)) { - break; - } - } else { - lastp = &sign->next; - } - } - - /* When deleted the last sign needs to redraw the windows to remove the - * sign column. */ - if (buf->b_signlist == NULL) { - redraw_buf_later(buf, NOT_VALID); - changed_cline_bef_curs(); - } - - return lnum; -} - - -/* - * Find the line number of the sign with the requested id in group 'group'. If - * the sign does not exist, return 0 as the line number. This will still let - * the correct file get loaded. - */ -int buf_findsign( - buf_T *buf, // buffer to store sign in - int id, // sign ID - char_u *group // sign group -) -{ - signlist_T *sign; // a sign in the signlist - - FOR_ALL_SIGNS_IN_BUF(buf, sign) { - if (sign->id == id && sign_in_group(sign, group)){ - return (int)sign->lnum; - } - } - - return 0; -} - -/* - * Return the sign at line 'lnum' in buffer 'buf'. Returns NULL if a sign is - * not found at the line. If 'groupname' is NULL, searches in the global group. - */ -static signlist_T * 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 -) -{ - signlist_T *sign; // a sign in the signlist - - FOR_ALL_SIGNS_IN_BUF(buf, sign) { - if (sign->lnum == lnum && sign_in_group(sign, groupname)) { - return sign; - } - } - - return NULL; -} - -/* - * Return the sign with identifier 'id' in group 'group' placed in buffer 'buf' - */ -signlist_T *buf_getsign_with_id( - buf_T *buf, // buffer whose sign we are searching for - int id, // sign identifier - char_u *group// sign group -) -{ - signlist_T *sign; // a sign in the signlist - - FOR_ALL_SIGNS_IN_BUF(buf, sign) { - if (sign->id == id && sign_in_group(sign, group)) { - return sign; - } - } - - return NULL; -} - -/* - * Return the identifier of the sign at line number 'lnum' in buffer 'buf'. - */ -int 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 -) -{ - signlist_T *sign; // a sign in the signlist - - sign = buf_getsign_at_line(buf, lnum, groupname); - if (sign != NULL) { - return sign->id; - } - - return 0; -} - - -/* - * Delete signs in buffer "buf". - */ -void buf_delete_signs(buf_T *buf, char_u *group) -{ - signlist_T *sign; - signlist_T **lastp; // pointer to pointer to current sign - signlist_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){ - redraw_buf_later(buf, NOT_VALID); - changed_cline_bef_curs(); - } - - lastp = &buf->b_signlist; - for (sign = buf->b_signlist; sign != NULL; sign = next) { - next = sign->next; - if (sign_in_group(sign, group)) { - *lastp = next; - if (next != NULL) { - next->prev = sign->prev; - } - if (sign->group != NULL) { - sign_group_unref(sign->group->sg_name); - } - xfree(sign); - } else { - lastp = &sign->next; - } - } - buf->b_signcols_max = -1; -} - -/* - * Delete all signs in all buffers. - */ -void buf_delete_all_signs(char_u *groupname) -{ - FOR_ALL_BUFFERS(buf) { - if (buf->b_signlist != NULL) { - buf_delete_signs(buf, groupname); - } - } -} - -/* - * List placed signs for "rbuf". If "rbuf" is NULL do it for all buffers. - */ -void sign_list_placed(buf_T *rbuf, char_u *sign_group) -{ - buf_T *buf; - signlist_T *sign; - char lbuf[BUFSIZ]; - char group[BUFSIZ]; - - MSG_PUTS_TITLE(_("\n--- Signs ---")); - msg_putchar('\n'); - if (rbuf == NULL) { - buf = firstbuf; - } else { - buf = rbuf; - } - while (buf != NULL && !got_int) { - if (buf->b_signlist != NULL) { - vim_snprintf(lbuf, BUFSIZ, _("Signs for %s:"), buf->b_fname); - MSG_PUTS_ATTR(lbuf, HL_ATTR(HLF_D)); - msg_putchar('\n'); - } - FOR_ALL_SIGNS_IN_BUF(buf, sign) { - if (got_int) { - break; - } - if (!sign_in_group(sign, sign_group)) { - continue; - } - if (sign->group != NULL) { - vim_snprintf(group, BUFSIZ, " group=%s", sign->group->sg_name); - } else { - group[0] = '\0'; - } - vim_snprintf(lbuf, BUFSIZ, _(" line=%ld id=%d%s name=%s " - "priority=%d"), - (long)sign->lnum, sign->id, group, - sign_typenr2name(sign->typenr), sign->priority); - MSG_PUTS(lbuf); - msg_putchar('\n'); - } - if (rbuf != NULL) { - break; - } - buf = buf->b_next; - } -} - -/* - * Adjust a placed sign for inserted/deleted lines. - */ -void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after) -{ - signlist_T *sign; // a sign in a b_signlist - signlist_T *next; // the next sign in a b_signlist - signlist_T **lastp; // pointer to pointer to current sign - - curbuf->b_signcols_max = -1; - lastp = &curbuf->b_signlist; - - FOR_ALL_SIGNS_IN_BUF(curbuf, sign) { - next = sign->next; - if (sign->lnum >= line1 && sign->lnum <= line2) { - if (amount == MAXLNUM) { - *lastp = next; - xfree(sign); - continue; - } else { - sign->lnum += amount; - } - } else if (sign->lnum > line2) { - sign->lnum += amount_after; - } - lastp = &sign->next; - } -} - // bufhl: plugin highlights associated with a buffer /// Get reference to line in kbtree_t -- cgit From 7d43943e4ecf5bd82ffc041b1039e0b2db4d6d60 Mon Sep 17 00:00:00 2001 From: Andrej Zieger Date: Wed, 22 May 2019 22:41:05 +0200 Subject: Fixed ordering of signs to align vim and neovim behaviour --- src/nvim/buffer.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 1f4a1e0cd1..39242b0575 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -5261,7 +5261,7 @@ static int sign_compare(const void *a1, const void *a2) const signlist_T *s1 = *(const signlist_T **)a1; const signlist_T *s2 = *(const signlist_T **)a2; - // Sort by line number and the by id + // Sort by line number, priority and id if (s1->lnum > s2->lnum) { return 1; @@ -5269,12 +5269,18 @@ static int sign_compare(const void *a1, const void *a2) if (s1->lnum < s2->lnum) { return -1; } - if (s1->id > s2->id) { + if (s1->priority > s2->priority) { + return -1; + } + if (s1->priority < s2->priority) { return 1; } - if (s1->id < s2->id) { + if (s1->id > s2->id) { return -1; } + if (s1->id < s2->id) { + return 1; + } return 0; } -- cgit From 80f40f0203f5af167f8c77bf6b9f22a4d1abd6da Mon Sep 17 00:00:00 2001 From: Andrej Zieger Date: Sun, 26 May 2019 17:06:50 +0200 Subject: lint --- src/nvim/buffer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/nvim/buffer.c') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 39242b0575..078d4fe782 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -805,9 +805,9 @@ free_buffer_stuff( vars_clear(&buf->b_vars->dv_hashtab); // free all internal variables hash_init(&buf->b_vars->dv_hashtab); buf_init_changedtick(buf); - uc_clear(&buf->b_ucmds); // clear local user commands - buf_delete_signs(buf, (char_u *)"*"); // delete any signs - bufhl_clear_all(buf); // delete any highligts + uc_clear(&buf->b_ucmds); // clear local user commands + buf_delete_signs(buf, (char_u *)"*"); // delete any signs + bufhl_clear_all(buf); // delete any highligts map_clear_int(buf, MAP_ALL_MODES, true, false); // clear local mappings map_clear_int(buf, MAP_ALL_MODES, true, true); // clear local abbrevs XFREE_CLEAR(buf->b_start_fenc); -- cgit