mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 03:18:16 +00:00
Merge pull request #27061 from luukvbaal/extmark
fix(extmarks): do not remove invalid marks from decor upon deletion
This commit is contained in:
@@ -2594,8 +2594,8 @@ nvim_buf_get_extmark_by_id({buffer}, {ns_id}, {id}, {*opts})
|
|||||||
|
|
||||||
*nvim_buf_get_extmarks()*
|
*nvim_buf_get_extmarks()*
|
||||||
nvim_buf_get_extmarks({buffer}, {ns_id}, {start}, {end}, {*opts})
|
nvim_buf_get_extmarks({buffer}, {ns_id}, {start}, {end}, {*opts})
|
||||||
Gets |extmarks| (including |signs|) in "traversal order" from a |charwise|
|
Gets |extmarks| in "traversal order" from a |charwise| region defined by
|
||||||
region defined by buffer positions (inclusive, 0-indexed |api-indexing|).
|
buffer positions (inclusive, 0-indexed |api-indexing|).
|
||||||
|
|
||||||
Region can be given as (row,col) tuples, or valid extmark ids (whose
|
Region can be given as (row,col) tuples, or valid extmark ids (whose
|
||||||
positions define the bounds). 0 and -1 are understood as (0,0) and (-1,-1)
|
positions define the bounds). 0 and -1 are understood as (0,0) and (-1,-1)
|
||||||
@@ -2611,6 +2611,10 @@ nvim_buf_get_extmarks({buffer}, {ns_id}, {start}, {end}, {*opts})
|
|||||||
the `overlap` option might be useful. Otherwise only the start position of
|
the `overlap` option might be useful. Otherwise only the start position of
|
||||||
an extmark will be considered.
|
an extmark will be considered.
|
||||||
|
|
||||||
|
Note: legacy signs placed through the |:sign| commands are implemented as
|
||||||
|
extmarks and will show up here. Their details array will contain a
|
||||||
|
`sign_name` field.
|
||||||
|
|
||||||
Example: >lua
|
Example: >lua
|
||||||
local api = vim.api
|
local api = vim.api
|
||||||
local pos = api.nvim_win_get_cursor(0)
|
local pos = api.nvim_win_get_cursor(0)
|
||||||
@@ -2742,7 +2746,9 @@ nvim_buf_set_extmark({buffer}, {ns_id}, {line}, {col}, {*opts})
|
|||||||
text around the mark was deleted and then restored by
|
text around the mark was deleted and then restored by
|
||||||
undo. Defaults to true.
|
undo. Defaults to true.
|
||||||
• invalidate : boolean that indicates whether to hide the
|
• invalidate : boolean that indicates whether to hide the
|
||||||
extmark if the entirety of its range is deleted. If
|
extmark if the entirety of its range is deleted. For
|
||||||
|
hidden marks, an "invalid" key is added to the "details"
|
||||||
|
array of |nvim_buf_get_extmarks()| and family. If
|
||||||
"undo_restore" is false, the extmark is deleted instead.
|
"undo_restore" is false, the extmark is deleted instead.
|
||||||
• priority: a priority value for the highlight group or sign
|
• priority: a priority value for the highlight group or sign
|
||||||
attribute. For example treesitter highlighting uses a
|
attribute. For example treesitter highlighting uses a
|
||||||
|
11
runtime/lua/vim/_meta/api.lua
generated
11
runtime/lua/vim/_meta/api.lua
generated
@@ -323,8 +323,8 @@ function vim.api.nvim_buf_get_commands(buffer, opts) end
|
|||||||
--- @return integer[]
|
--- @return integer[]
|
||||||
function vim.api.nvim_buf_get_extmark_by_id(buffer, ns_id, id, opts) end
|
function vim.api.nvim_buf_get_extmark_by_id(buffer, ns_id, id, opts) end
|
||||||
|
|
||||||
--- Gets `extmarks` (including `signs`) in "traversal order" from a `charwise`
|
--- Gets `extmarks` in "traversal order" from a `charwise` region defined by
|
||||||
--- region defined by buffer positions (inclusive, 0-indexed `api-indexing`).
|
--- buffer positions (inclusive, 0-indexed `api-indexing`).
|
||||||
--- Region can be given as (row,col) tuples, or valid extmark ids (whose
|
--- Region can be given as (row,col) tuples, or valid extmark ids (whose
|
||||||
--- positions define the bounds). 0 and -1 are understood as (0,0) and (-1,-1)
|
--- positions define the bounds). 0 and -1 are understood as (0,0) and (-1,-1)
|
||||||
--- respectively, thus the following are equivalent:
|
--- respectively, thus the following are equivalent:
|
||||||
@@ -339,6 +339,9 @@ function vim.api.nvim_buf_get_extmark_by_id(buffer, ns_id, id, opts) end
|
|||||||
--- Note: when using extmark ranges (marks with a end_row/end_col position)
|
--- Note: when using extmark ranges (marks with a end_row/end_col position)
|
||||||
--- the `overlap` option might be useful. Otherwise only the start position of
|
--- the `overlap` option might be useful. Otherwise only the start position of
|
||||||
--- an extmark will be considered.
|
--- an extmark will be considered.
|
||||||
|
--- Note: legacy signs placed through the `:sign` commands are implemented as
|
||||||
|
--- extmarks and will show up here. Their details array will contain a
|
||||||
|
--- `sign_name` field.
|
||||||
--- Example:
|
--- Example:
|
||||||
---
|
---
|
||||||
--- ```lua
|
--- ```lua
|
||||||
@@ -567,7 +570,9 @@ function vim.api.nvim_buf_line_count(buffer) end
|
|||||||
--- text around the mark was deleted and then restored by
|
--- text around the mark was deleted and then restored by
|
||||||
--- undo. Defaults to true.
|
--- undo. Defaults to true.
|
||||||
--- • invalidate : boolean that indicates whether to hide the
|
--- • invalidate : boolean that indicates whether to hide the
|
||||||
--- extmark if the entirety of its range is deleted. If
|
--- extmark if the entirety of its range is deleted. For
|
||||||
|
--- hidden marks, an "invalid" key is added to the "details"
|
||||||
|
--- array of `nvim_buf_get_extmarks()` and family. If
|
||||||
--- "undo_restore" is false, the extmark is deleted instead.
|
--- "undo_restore" is false, the extmark is deleted instead.
|
||||||
--- • priority: a priority value for the highlight group or sign
|
--- • priority: a priority value for the highlight group or sign
|
||||||
--- attribute. For example treesitter highlighting uses a
|
--- attribute. For example treesitter highlighting uses a
|
||||||
|
@@ -215,8 +215,8 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id,
|
|||||||
return extmark_to_array(extmark, false, details, hl_name);
|
return extmark_to_array(extmark, false, details, hl_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets |extmarks| (including |signs|) in "traversal order" from a |charwise|
|
/// Gets |extmarks| in "traversal order" from a |charwise| region defined by
|
||||||
/// region defined by buffer positions (inclusive, 0-indexed |api-indexing|).
|
/// buffer positions (inclusive, 0-indexed |api-indexing|).
|
||||||
///
|
///
|
||||||
/// Region can be given as (row,col) tuples, or valid extmark ids (whose
|
/// Region can be given as (row,col) tuples, or valid extmark ids (whose
|
||||||
/// positions define the bounds). 0 and -1 are understood as (0,0) and (-1,-1)
|
/// positions define the bounds). 0 and -1 are understood as (0,0) and (-1,-1)
|
||||||
@@ -234,6 +234,10 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id,
|
|||||||
/// the `overlap` option might be useful. Otherwise only the start position
|
/// the `overlap` option might be useful. Otherwise only the start position
|
||||||
/// of an extmark will be considered.
|
/// of an extmark will be considered.
|
||||||
///
|
///
|
||||||
|
/// Note: legacy signs placed through the |:sign| commands are implemented
|
||||||
|
/// as extmarks and will show up here. Their details array will contain a
|
||||||
|
/// `sign_name` field.
|
||||||
|
///
|
||||||
/// Example:
|
/// Example:
|
||||||
///
|
///
|
||||||
/// ```lua
|
/// ```lua
|
||||||
@@ -434,7 +438,9 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e
|
|||||||
/// if text around the mark was deleted and then restored by undo.
|
/// if text around the mark was deleted and then restored by undo.
|
||||||
/// Defaults to true.
|
/// Defaults to true.
|
||||||
/// - invalidate : boolean that indicates whether to hide the
|
/// - invalidate : boolean that indicates whether to hide the
|
||||||
/// extmark if the entirety of its range is deleted. If
|
/// extmark if the entirety of its range is deleted. For
|
||||||
|
/// hidden marks, an "invalid" key is added to the "details"
|
||||||
|
/// array of |nvim_buf_get_extmarks()| and family. If
|
||||||
/// "undo_restore" is false, the extmark is deleted instead.
|
/// "undo_restore" is false, the extmark is deleted instead.
|
||||||
/// - priority: a priority value for the highlight group or sign
|
/// - priority: a priority value for the highlight group or sign
|
||||||
/// attribute. For example treesitter highlighting uses a
|
/// attribute. For example treesitter highlighting uses a
|
||||||
|
@@ -150,7 +150,11 @@ void extmark_del(buf_T *buf, MarkTreeIter *itr, MTKey key, bool restore)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mt_decor_any(key)) {
|
if (mt_decor_any(key)) {
|
||||||
buf_decor_remove(buf, key.pos.row, key2.pos.row, mt_decor(key), true);
|
if (mt_invalid(key)) {
|
||||||
|
decor_free(mt_decor(key));
|
||||||
|
} else {
|
||||||
|
buf_decor_remove(buf, key.pos.row, key2.pos.row, mt_decor(key), true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(bfredl): delete it from current undo header, opportunistically?
|
// TODO(bfredl): delete it from current undo header, opportunistically?
|
||||||
@@ -352,14 +356,12 @@ void extmark_splice_delete(buf_T *buf, int l_row, colnr_T l_col, int u_row, coln
|
|||||||
|
|
||||||
// Push mark to undo header
|
// Push mark to undo header
|
||||||
if (only_copy || (uvp != NULL && op == kExtmarkUndo && !mt_no_undo(mark))) {
|
if (only_copy || (uvp != NULL && op == kExtmarkUndo && !mt_no_undo(mark))) {
|
||||||
ExtmarkSavePos pos;
|
ExtmarkSavePos pos = {
|
||||||
pos.mark = mt_lookup_key(mark);
|
.mark = mt_lookup_key(mark),
|
||||||
pos.invalidated = invalidated;
|
.invalidated = invalidated,
|
||||||
pos.old_row = mark.pos.row;
|
.old_row = mark.pos.row,
|
||||||
pos.old_col = mark.pos.col;
|
.old_col = mark.pos.col
|
||||||
pos.row = -1;
|
};
|
||||||
pos.col = -1;
|
|
||||||
|
|
||||||
undo.data.savepos = pos;
|
undo.data.savepos = pos;
|
||||||
undo.type = kExtmarkSavePos;
|
undo.type = kExtmarkSavePos;
|
||||||
kv_push(*uvp, undo);
|
kv_push(*uvp, undo);
|
||||||
@@ -393,22 +395,17 @@ void extmark_apply_undo(ExtmarkUndoObject undo_info, bool undo)
|
|||||||
} else if (undo_info.type == kExtmarkSavePos) {
|
} else if (undo_info.type == kExtmarkSavePos) {
|
||||||
ExtmarkSavePos pos = undo_info.data.savepos;
|
ExtmarkSavePos pos = undo_info.data.savepos;
|
||||||
if (undo) {
|
if (undo) {
|
||||||
if (pos.old_row >= 0) {
|
if (pos.old_row >= 0
|
||||||
extmark_setraw(curbuf, pos.mark, pos.old_row, pos.old_col);
|
&& extmark_setraw(curbuf, pos.mark, pos.old_row, pos.old_col)
|
||||||
}
|
&& pos.invalidated) {
|
||||||
if (pos.invalidated) {
|
|
||||||
MarkTreeIter itr[1] = { 0 };
|
MarkTreeIter itr[1] = { 0 };
|
||||||
MTKey mark = marktree_lookup(curbuf->b_marktree, pos.mark, itr);
|
MTKey mark = marktree_lookup(curbuf->b_marktree, pos.mark, itr);
|
||||||
mt_itr_rawkey(itr).flags &= (uint16_t) ~MT_FLAG_INVALID;
|
mt_itr_rawkey(itr).flags &= (uint16_t) ~MT_FLAG_INVALID;
|
||||||
MTPos end = marktree_get_altpos(curbuf->b_marktree, mark, itr);
|
MTPos end = marktree_get_altpos(curbuf->b_marktree, mark, itr);
|
||||||
buf_put_decor(curbuf, mt_decor(mark), mark.pos.row, end.row);
|
buf_put_decor(curbuf, mt_decor(mark), mark.pos.row, end.row);
|
||||||
}
|
}
|
||||||
// Redo
|
|
||||||
} else {
|
|
||||||
if (pos.row >= 0) {
|
|
||||||
extmark_setraw(curbuf, pos.mark, pos.row, pos.col);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// No Redo since kExtmarkSplice will move marks back
|
||||||
} else if (undo_info.type == kExtmarkMove) {
|
} else if (undo_info.type == kExtmarkMove) {
|
||||||
ExtmarkMove move = undo_info.data.move;
|
ExtmarkMove move = undo_info.data.move;
|
||||||
if (undo) {
|
if (undo) {
|
||||||
|
@@ -45,8 +45,6 @@ typedef struct {
|
|||||||
uint64_t mark; // raw mark id of the marktree
|
uint64_t mark; // raw mark id of the marktree
|
||||||
int old_row;
|
int old_row;
|
||||||
colnr_T old_col;
|
colnr_T old_col;
|
||||||
int row;
|
|
||||||
colnr_T col;
|
|
||||||
bool invalidated;
|
bool invalidated;
|
||||||
} ExtmarkSavePos;
|
} ExtmarkSavePos;
|
||||||
|
|
||||||
|
@@ -1712,6 +1712,10 @@ describe('API/extmarks', function()
|
|||||||
aaa bbb ccc |*2
|
aaa bbb ccc |*2
|
||||||
|
|
|
|
||||||
]])
|
]])
|
||||||
|
-- decor is not removed twice
|
||||||
|
command('d3')
|
||||||
|
api.nvim_buf_del_extmark(0, ns, 1)
|
||||||
|
command('silent undo')
|
||||||
-- mark is deleted with undo_restore == false
|
-- mark is deleted with undo_restore == false
|
||||||
set_extmark(ns, 1, 0, 0, { invalidate = true, undo_restore = false, sign_text = 'S1' })
|
set_extmark(ns, 1, 0, 0, { invalidate = true, undo_restore = false, sign_text = 'S1' })
|
||||||
set_extmark(ns, 2, 1, 0, { invalidate = true, undo_restore = false, sign_text = 'S2' })
|
set_extmark(ns, 2, 1, 0, { invalidate = true, undo_restore = false, sign_text = 'S2' })
|
||||||
|
Reference in New Issue
Block a user