From 978dfe4bdf5d28810a69a964ba52fe1d569250ba Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Tue, 16 Feb 2021 12:32:05 +1100 Subject: [PATCH] Fix splitting display line in front of a replaced range When a replaced buffer range atom was starting exactly at the location we wanted to split onto the code would split *after* that atom instead of before. Fixes #4052 --- src/display_buffer.cc | 5 ++++- .../cmd | 0 .../in | 3 +++ .../rc | 4 ++++ .../script | 7 +++++++ 5 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 test/regression/4052-replace-range-vs-whitespace-highlighter-interaction/cmd create mode 100644 test/regression/4052-replace-range-vs-whitespace-highlighter-interaction/in create mode 100644 test/regression/4052-replace-range-vs-whitespace-highlighter-interaction/rc create mode 100644 test/regression/4052-replace-range-vs-whitespace-highlighter-interaction/script diff --git a/src/display_buffer.cc b/src/display_buffer.cc index 8ade4047..b7564550 100644 --- a/src/display_buffer.cc +++ b/src/display_buffer.cc @@ -113,7 +113,10 @@ DisplayLine::iterator DisplayLine::split(iterator it, ColumnCount count) DisplayLine::iterator DisplayLine::split(BufferCoord pos) { - auto it = find_if(begin(), end(), [pos](const DisplayAtom& a) { return a.type() == DisplayAtom::Range and a.end() > pos; }); + auto it = find_if(begin(), end(), [pos](const DisplayAtom& a) { + return (a.has_buffer_range() && a.begin() >= pos) || + (a.type() == DisplayAtom::Range and a.end() > pos); + }); if (it == end() or it->begin() >= pos) return it; return ++split(it, pos); diff --git a/test/regression/4052-replace-range-vs-whitespace-highlighter-interaction/cmd b/test/regression/4052-replace-range-vs-whitespace-highlighter-interaction/cmd new file mode 100644 index 00000000..e69de29b diff --git a/test/regression/4052-replace-range-vs-whitespace-highlighter-interaction/in b/test/regression/4052-replace-range-vs-whitespace-highlighter-interaction/in new file mode 100644 index 00000000..0c478cf3 --- /dev/null +++ b/test/regression/4052-replace-range-vs-whitespace-highlighter-interaction/in @@ -0,0 +1,3 @@ +fn main() { + let my_str = String::from("abc"); +} diff --git a/test/regression/4052-replace-range-vs-whitespace-highlighter-interaction/rc b/test/regression/4052-replace-range-vs-whitespace-highlighter-interaction/rc new file mode 100644 index 00000000..d6820968 --- /dev/null +++ b/test/regression/4052-replace-range-vs-whitespace-highlighter-interaction/rc @@ -0,0 +1,4 @@ +declare-option -hidden range-specs test_inlay_hints +add-highlighter window/whitespaces show-whitespaces -tab '›' -tabpad '⋅' -spc ' ' -nbsp '⍽' +add-highlighter window/test_inlay_hints replace-ranges test_inlay_hints +set buffer test_inlay_hints %val{timestamp} '2.15+0|{Information}{\}: String' diff --git a/test/regression/4052-replace-range-vs-whitespace-highlighter-interaction/script b/test/regression/4052-replace-range-vs-whitespace-highlighter-interaction/script new file mode 100644 index 00000000..b3e5e881 --- /dev/null +++ b/test/regression/4052-replace-range-vs-whitespace-highlighter-interaction/script @@ -0,0 +1,7 @@ +ui_out '{ "jsonrpc": "2.0", "method": "set_ui_options", "params": [{}] }' +ui_out '{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "black", "bg": "white", "attributes": [] }, "contents": "f" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "n" }, { "face": { "fg": "default", "bg": "default", "attributes": ["final_fg"] }, "contents": " " }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "main()" }, { "face": { "fg": "default", "bg": "default", "attributes": ["final_fg"] }, "contents": " " }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "{" }, { "face": { "fg": "default", "bg": "default", "attributes": ["final_fg"] }, "contents": "¬" }], [{ "face": { "fg": "default", "bg": "default", "attributes": ["final_fg"] }, "contents": " " }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "let" }, { "face": { "fg": "default", "bg": "default", "attributes": ["final_fg"] }, "contents": " " }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "my_str" }, { "face": { "fg": "black", "bg": "yellow", "attributes": [] }, "contents": ": String" }, { "face": { "fg": "default", "bg": "default", "attributes": ["final_fg"] }, "contents": " " }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "=" }, { "face": { "fg": "default", "bg": "default", "attributes": ["final_fg"] }, "contents": " " }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "String::from(\"abc\");" }, { "face": { "fg": "default", "bg": "default", "attributes": ["final_fg"] }, "contents": "¬" }], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "}" }, { "face": { "fg": "default", "bg": "default", "attributes": ["final_fg"] }, "contents": "¬" }]], { "fg": "default", "bg": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "attributes": [] }] }' +ui_out '{ "jsonrpc": "2.0", "method": "menu_hide", "params": [] }' +ui_out '{ "jsonrpc": "2.0", "method": "info_hide", "params": [] }' +ui_out '{ "jsonrpc": "2.0", "method": "draw_status", "params": [[], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "out 1:1 " }, { "face": { "fg": "black", "bg": "yellow", "attributes": [] }, "contents": "" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "blue", "bg": "default", "attributes": [] }, "contents": "1 sel" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " - client0@[kak-tests]" }], { "fg": "cyan", "bg": "default", "attributes": [] }] }' +ui_out '{ "jsonrpc": "2.0", "method": "set_cursor", "params": ["buffer", { "line": 0, "column": 0 }] }' +ui_out '{ "jsonrpc": "2.0", "method": "refresh", "params": [true] }'