mirror of
https://github.com/neovim/neovim
synced 2025-07-16 01:01:49 +00:00
fix(column): don't count signs on lines beyond eob #33410
Problem: Computed previous buffer line count may be beyond end of
buffer. This results in signs being removed from `b_signcols`
that were never included in it, tripping an assertion.
Solution: Store the previous line count as it was before appending or
deleting lines. Use it to clamp the edited region when
clearing signs before a splice, after which it is reset.
(cherry picked from commit 4a706a7092
)
This commit is contained in:
committed by
github-actions[bot]
parent
9da90af0f7
commit
b8e5fd51fd
@ -718,6 +718,11 @@ struct file_buffer {
|
||||
MarkTree b_marktree[1];
|
||||
Map(uint32_t, uint32_t) b_extmark_ns[1]; // extmark namespaces
|
||||
|
||||
// Store the line count as it was before appending or inserting lines.
|
||||
// Used to determine a valid range before splicing marks, when the line
|
||||
// count has already changed.
|
||||
int b_prev_line_count;
|
||||
|
||||
// array of channel_id:s which have asked to receive updates for this
|
||||
// buffer.
|
||||
kvec_t(uint64_t) update_channels;
|
||||
|
@ -580,8 +580,9 @@ void extmark_splice_impl(buf_T *buf, int start_row, colnr_T start_col, bcount_t
|
||||
|
||||
// Remove signs inside edited region from "b_signcols.count", add after splicing.
|
||||
if (old_row > 0 || new_row > 0) {
|
||||
int row2 = MIN(buf->b_ml.ml_line_count - (new_row - old_row) - 1, start_row + old_row);
|
||||
buf_signcols_count_range(buf, start_row, row2, 0, kTrue);
|
||||
int count = buf->b_prev_line_count > 0 ? buf->b_prev_line_count : buf->b_ml.ml_line_count;
|
||||
buf_signcols_count_range(buf, start_row, MIN(count - 1, start_row + old_row), 0, kTrue);
|
||||
buf->b_prev_line_count = 0;
|
||||
}
|
||||
|
||||
marktree_splice(buf->b_marktree, (int32_t)start_row, start_col,
|
||||
|
@ -2088,6 +2088,9 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, boo
|
||||
dp = hp->bh_data;
|
||||
}
|
||||
|
||||
if (buf->b_prev_line_count == 0) {
|
||||
buf->b_prev_line_count = buf->b_ml.ml_line_count;
|
||||
}
|
||||
buf->b_ml.ml_line_count++;
|
||||
|
||||
if ((int)dp->db_free >= space_needed) { // enough room in data block
|
||||
@ -2573,6 +2576,9 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, bool message)
|
||||
int count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 2;
|
||||
int idx = lnum - buf->b_ml.ml_locked_low;
|
||||
|
||||
if (buf->b_prev_line_count == 0) {
|
||||
buf->b_prev_line_count = buf->b_ml.ml_line_count;
|
||||
}
|
||||
buf->b_ml.ml_line_count--;
|
||||
|
||||
int line_start = ((dp->db_index[idx]) & DB_INDEX_MASK);
|
||||
|
@ -681,4 +681,11 @@ describe('Signs', function()
|
||||
:lua log, needs_clear = {}, true |
|
||||
]])
|
||||
end)
|
||||
|
||||
it('signcolumn tracking does not consider signs beyond eob', function()
|
||||
api.nvim_set_option_value('signcolumn', 'auto:2', {})
|
||||
api.nvim_buf_set_extmark(0, api.nvim_create_namespace(''), 1, 0, { sign_text = 's' })
|
||||
api.nvim_buf_set_lines(0, 0, -1, false, {})
|
||||
n.assert_alive()
|
||||
end)
|
||||
end)
|
||||
|
Reference in New Issue
Block a user