diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-07-04 18:28:35 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-07-04 18:28:35 +0200 |
commit | 4e038571aa91521e110187a256b5d16bff8b5820 (patch) | |
tree | 856767e58f9d20a121c0d23decc7a6117bf26ba4 /src/sign.c | |
parent | e809a4ed3014fbf717c936c727291b5f038829a5 (diff) | |
download | vim-git-4e038571aa91521e110187a256b5d16bff8b5820.tar.gz |
patch 8.1.1631: displaying signs is inefficientv8.1.1631
Problem: Displaying signs is inefficient.
Solution: Avoid making multiple calls to get information about a placed
sign. (Yegappan Lakshmanan, closes #4586)
Diffstat (limited to 'src/sign.c')
-rw-r--r-- | src/sign.c | 126 |
1 files changed, 66 insertions, 60 deletions
diff --git a/src/sign.c b/src/sign.c index a67f3ec8c..cf7581951 100644 --- a/src/sign.c +++ b/src/sign.c @@ -274,6 +274,20 @@ insert_sign_by_lnum_prio( } /* + * Lookup a sign by typenr. Returns NULL if sign is not found. + */ + static sign_T * +find_sign_by_typenr(int typenr) +{ + sign_T *sp; + + for (sp = first_sign; sp != NULL; sp = sp->sn_next) + if (sp->sn_typenr == typenr) + return sp; + return NULL; +} + +/* * Get the name of a sign by its typenr. */ static char_u * @@ -445,31 +459,44 @@ buf_change_sign_type( } /* - * Return the type number of the sign at line number 'lnum' in buffer 'buf' - * which has the attribute specified by 'type'. Returns 0 if a sign is not - * found at the line number or it doesn't have the specified attribute. + * Return the attributes of the first sign placed on line 'lnum' in buffer + * 'buf'. Used when refreshing the screen. Returns TRUE if a sign is found on + * 'lnum', FALSE otherwise. */ int -buf_getsigntype( - buf_T *buf, - linenr_T lnum, - int type) // SIGN_ICON, SIGN_TEXT, SIGN_ANY, SIGN_LINEHL +buf_get_signattrs(buf_T *buf, linenr_T lnum, sign_attrs_T *sattr) { - signlist_T *sign; // a sign in a b_signlist + signlist_T *sign; + sign_T *sp; + + vim_memset(sattr, 0, sizeof(sign_attrs_T)); FOR_ALL_SIGNS_IN_BUF(buf, sign) - if (sign->lnum == lnum - && (type == SIGN_ANY + { + if (sign->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->lnum == lnum) + { + sattr->typenr = sign->typenr; + sp = find_sign_by_typenr(sign->typenr); + if (sp == NULL) + return FALSE; + # ifdef FEAT_SIGN_ICONS - || (type == SIGN_ICON - && sign_get_image(sign->typenr) != NULL) + sattr->icon = sp->sn_image; # endif - || (type == SIGN_TEXT - && sign_get_text(sign->typenr) != NULL) - || (type == SIGN_LINEHL - && sign_get_attr(sign->typenr, TRUE) != 0))) - return sign->typenr; - return 0; + sattr->text = sp->sn_text; + if (sattr->text != NULL && sp->sn_text_hl > 0) + sattr->texthl = syn_id2attr(sp->sn_text_hl); + if (sp->sn_line_hl > 0) + sattr->linehl = syn_id2attr(sp->sn_line_hl); + return TRUE; + } + } + return FALSE; } /* @@ -571,8 +598,15 @@ buf_getsign_at_line( signlist_T *sign; // a sign in the signlist FOR_ALL_SIGNS_IN_BUF(buf, sign) + { + if (sign->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->lnum == lnum && sign_in_group(sign, groupname)) return sign; + } return NULL; } @@ -608,8 +642,15 @@ buf_findsigntype_id( signlist_T *sign; // a sign in the signlist FOR_ALL_SIGNS_IN_BUF(buf, sign) + { + if (sign->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->lnum == lnum && sign->typenr == typenr) return sign->id; + } return 0; } @@ -626,9 +667,16 @@ buf_signcount(buf_T *buf, linenr_T lnum) int count = 0; FOR_ALL_SIGNS_IN_BUF(buf, sign) + { + if (sign->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->lnum == lnum) if (sign_get_image(sign->typenr) != NULL) count++; + } return count; } @@ -1792,48 +1840,6 @@ sign_undefine(sign_T *sp, sign_T *sp_prev) vim_free(sp); } -/* - * Get highlighting attribute for sign "typenr". - * If "line" is TRUE: line highl, if FALSE: text highl. - */ - int -sign_get_attr(int typenr, int line) -{ - sign_T *sp; - - for (sp = first_sign; sp != NULL; sp = sp->sn_next) - if (sp->sn_typenr == typenr) - { - if (line) - { - if (sp->sn_line_hl > 0) - return syn_id2attr(sp->sn_line_hl); - } - else - { - if (sp->sn_text_hl > 0) - return syn_id2attr(sp->sn_text_hl); - } - break; - } - return 0; -} - -/* - * Get text mark for sign "typenr". - * Returns NULL if there isn't one. - */ - char_u * -sign_get_text(int typenr) -{ - sign_T *sp; - - for (sp = first_sign; sp != NULL; sp = sp->sn_next) - if (sp->sn_typenr == typenr) - return sp->sn_text; - return NULL; -} - # if defined(FEAT_SIGN_ICONS) || defined(PROTO) void * sign_get_image( |