diff options
author | Luuk van Baal <luukvbaal@gmail.com> | 2023-11-11 00:52:50 +0100 |
---|---|---|
committer | Luuk van Baal <luukvbaal@gmail.com> | 2023-11-17 15:10:15 +0100 |
commit | c4afb9788c4f139eb2e3b7aa4d6a6a20b67ba156 (patch) | |
tree | abc3a6da1906ea61f40aaacf3bdb813c27e19d64 /src/nvim/buffer.c | |
parent | ba58c6f8a44c9c37e97fce1d802dc5b5defceb3d (diff) | |
download | rneovim-c4afb9788c4f139eb2e3b7aa4d6a6a20b67ba156.tar.gz rneovim-c4afb9788c4f139eb2e3b7aa4d6a6a20b67ba156.tar.bz2 rneovim-c4afb9788c4f139eb2e3b7aa4d6a6a20b67ba156.zip |
refactor(sign): move legacy signs to extmarks
Problem: The legacy signlist data structures and associated functions are
redundant since the introduction of extmark signs.
Solution: Store signs defined through the legacy commands in a hashmap, placed
signs in the extmark tree. Replace signlist associated functions.
Usage of the legacy sign commands should yield no change in behavior with the
exception of:
- "orphaned signs" are now always removed when the line it is placed on is
deleted. This used to depend on the value of 'signcolumn'.
- It is no longer possible to place multiple signs with the same identifier
in a single group on multiple lines. This will now move the sign instead.
Moreover, both signs placed through the legacy sign commands and through
|nvim_buf_set_extmark()|:
- Will show up in both |sign-place| and |nvim_buf_get_extmarks()|.
- Are displayed by increasing sign identifier, left to right.
Extmark signs used to be ordered decreasingly as opposed to legacy signs.
Diffstat (limited to 'src/nvim/buffer.c')
-rw-r--r-- | src/nvim/buffer.c | 95 |
1 files changed, 14 insertions, 81 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 230cd4cef7..8c522a6c44 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -917,7 +917,6 @@ static void free_buffer_stuff(buf_T *buf, int free_flags) buf_init_changedtick(buf); } uc_clear(&buf->b_ucmds); // clear local user commands - buf_delete_signs(buf, "*"); // delete any signs extmark_free_all(buf); // delete any extmarks map_clear_mode(buf, MAP_ALL_MODES, true, false); // clear local mappings map_clear_mode(buf, MAP_ALL_MODES, true, true); // clear local abbrevs @@ -4021,62 +4020,6 @@ char *buf_spname(buf_T *buf) return NULL; } -static int buf_signcols_inner(buf_T *buf, int maximum) -{ - sign_entry_T *sign; // a sign in the sign list - int signcols = 0; - int linesum = 0; - linenr_T curline = 0; - - buf->b_signcols.sentinel = 0; - - FOR_ALL_SIGNS_IN_BUF(buf, sign) { - if (sign->se_lnum > curline) { - // Counted all signs, now add extmark signs - if (curline > 0) { - linesum += decor_signcols(buf, &decor_state, (int)curline - 1, (int)curline - 1, - maximum - linesum); - } - curline = sign->se_lnum; - if (linesum > signcols) { - signcols = linesum; - buf->b_signcols.sentinel = curline; - if (signcols >= maximum) { - return maximum; - } - } - linesum = 0; - } - if (sign->se_has_text_or_icon) { - linesum++; - } - } - - if (curline > 0) { - linesum += decor_signcols(buf, &decor_state, (int)curline - 1, (int)curline - 1, - maximum - linesum); - } - if (linesum > signcols) { - signcols = linesum; - if (signcols >= maximum) { - return maximum; - } - } - - // Check extmarks between signs - linesum = decor_signcols(buf, &decor_state, 0, (int)buf->b_ml.ml_line_count - 1, maximum); - - if (linesum > signcols) { - signcols = linesum; - buf->b_signcols.sentinel = curline; - if (signcols >= maximum) { - return maximum; - } - } - - return signcols; -} - /// Invalidate the signcolumn if needed after deleting /// signs between line1 and line2 (inclusive). /// @@ -4106,18 +4049,18 @@ void buf_signcols_del_check(buf_T *buf, linenr_T line1, linenr_T line2) /// /// @param buf buffer to check /// @param added sign being added -void buf_signcols_add_check(buf_T *buf, sign_entry_T *added) +void buf_signcols_add_check(buf_T *buf, linenr_T lnum) { if (!buf->b_signcols.valid) { return; } - if (!added || !buf->b_signcols.sentinel) { + if (!buf->b_signcols.sentinel) { buf->b_signcols.valid = false; return; } - if (added->se_lnum == buf->b_signcols.sentinel) { + if (lnum == buf->b_signcols.sentinel) { if (buf->b_signcols.size == buf->b_signcols.max) { buf->b_signcols.max++; } @@ -4126,42 +4069,32 @@ void buf_signcols_add_check(buf_T *buf, sign_entry_T *added) return; } - sign_entry_T *s; - - // Get first sign for added lnum - for (s = added; s->se_prev && s->se_lnum == s->se_prev->se_lnum; s = s->se_prev) {} - - // Count signs for lnum - int linesum = 1; - for (; s->se_next && s->se_lnum == s->se_next->se_lnum; s = s->se_next) { - linesum++; - } - linesum += decor_signcols(buf, &decor_state, (int)s->se_lnum - 1, (int)s->se_lnum - 1, - SIGN_SHOW_MAX - linesum); + int signcols = decor_signcols(buf, lnum - 1, lnum - 1, SIGN_SHOW_MAX); - if (linesum > buf->b_signcols.size) { - buf->b_signcols.size = linesum; - buf->b_signcols.max = linesum; - buf->b_signcols.sentinel = added->se_lnum; + if (signcols > buf->b_signcols.size) { + buf->b_signcols.size = signcols; + buf->b_signcols.max = signcols; + buf->b_signcols.sentinel = lnum; redraw_buf_later(buf, UPD_NOT_VALID); } } -int buf_signcols(buf_T *buf, int maximum) +int buf_signcols(buf_T *buf, int max) { // The maximum can be determined from 'signcolumn' which is window scoped so // need to invalidate signcols if the maximum is greater than the previous - // maximum. - if (maximum > buf->b_signcols.max) { + // (valid) maximum. + if (buf->b_signcols.max && max > buf->b_signcols.max) { buf->b_signcols.valid = false; } if (!buf->b_signcols.valid) { - int signcols = buf_signcols_inner(buf, maximum); + buf->b_signcols.sentinel = 0; + int signcols = decor_signcols(buf, 0, (int)buf->b_ml.ml_line_count - 1, max); // Check if we need to redraw if (signcols != buf->b_signcols.size) { buf->b_signcols.size = signcols; - buf->b_signcols.max = maximum; + buf->b_signcols.max = max; redraw_buf_later(buf, UPD_NOT_VALID); } |