Do not replace partially selected ranges in replace-ranges highlighter

Partially selected ranges should not be replaced to make it possible
to see what is actually selected.
This commit is contained in:
Maxime Coste 2020-04-26 19:27:44 +10:00
parent 0fdfbdfd15
commit cb119251bc
8 changed files with 41 additions and 11 deletions

View File

@ -265,6 +265,7 @@ DisplayLine parse_display_line(StringView line, const FaceRegistry& faces, const
else
{
content += StringView{pos, it};
if (not content.empty())
res.push_back({std::move(content), face});
content.clear();
auto closing = std::find(it+1, end, '}');

View File

@ -55,6 +55,13 @@ public:
m_text = std::move(text);
}
void replace(const BufferRange& range)
{
kak_assert(m_type == Text);
m_type = ReplacedRange;
m_range = range;
}
bool has_buffer_range() const
{
return m_type == Range or m_type == ReplacedRange;

View File

@ -96,10 +96,7 @@ void replace_range(DisplayBuffer& display_buffer,
{
auto& range = line.range();
if ((begin == end) and begin == range.end)
{
func(line, line.atoms().size(), line.atoms().size());
continue;
}
return func(line, line.end());
if (range.end <= begin or end < range.begin)
continue;
@ -128,7 +125,7 @@ void replace_range(DisplayBuffer& display_buffer,
}
if (beg_idx != -1 and end_idx != -1)
func(line, beg_idx, end_idx);
return func(line, line.erase(line.begin() + beg_idx, line.begin() + end_idx));
}
}
@ -1582,17 +1579,28 @@ private:
return c.line >= 0 and c.column >= 0 and c.line < buffer.line_count() and c.column <= buffer[c.line].length();
};
auto is_fully_selected = [&sels=context.context.selections()](const InclusiveBufferRange& range) {
auto it = std::lower_bound(sels.begin(), sels.end(), range.first, [](const Selection& s, const BufferCoord& c) { return s.max() < c; });
if (it == sels.end())
return true;
return it->min() > range.last or (it->min() <= range.first and it->max() >= range.last);
};
for (auto& [range, spec] : range_and_faces.list)
{
try
{
if (!is_valid(range.first) or (!is_empty(range) and !is_valid(range.last)))
if (!is_valid(range.first) or (!is_empty(range) and !is_valid(range.last)) or !is_fully_selected(range))
continue;
auto replacement = parse_display_line(spec, context.context.faces());
replace_range(display_buffer, range.first, is_empty(range) ? range.first : buffer.char_next(range.last),
[&](DisplayLine& line, int beg_idx, int end_idx){
auto it = line.erase(line.begin() + beg_idx, line.begin() + end_idx);
std::move(replacement.begin(), replacement.end(), std::inserter(line, it));
auto end = is_empty(range) ? range.first : buffer.char_next(range.last);
replace_range(display_buffer, range.first, end,
[&](DisplayLine& line, DisplayLine::iterator pos){
for (auto& atom : replacement)
{
atom.replace(BufferRange{range.first, end});
pos = ++line.insert(pos, std::move(atom));
}
});
}
catch (runtime_error&)

View File

@ -0,0 +1 @@
'reg' ':' '' 'wq'

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,3 @@
%(12345)
1%(234)5
1%(2)345

View File

@ -0,0 +1,2 @@
declare-option range-specs test_ranges %val{timestamp} '1.2,1.4|{blue}replaced{green} text' '2.2,2.4|{blue}replaced{green} text' '3.2,3.4|{red}not {blue}replaced{green} text'
add-highlighter window/ replace-ranges test_ranges

View File

@ -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": "blue", "attributes": [] }, "contents": "1" }, { "face": { "fg": "black", "bg": "blue", "attributes": [] }, "contents": "replaced" }, { "face": { "fg": "black", "bg": "blue", "attributes": [] }, "contents": " text" }, { "face": { "fg": "black", "bg": "white", "attributes": [] }, "contents": "5" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "\u000a" }], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "1" }, { "face": { "fg": "black", "bg": "white", "attributes": [] }, "contents": "replaced" }, { "face": { "fg": "black", "bg": "white", "attributes": [] }, "contents": " text" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "5\u000a" }], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "1" }, { "face": { "fg": "black", "bg": "white", "attributes": [] }, "contents": "2" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "345\u000a" }]], { "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 3:2 " }, { "face": { "fg": "black", "bg": "yellow", "attributes": [] }, "contents": "[+]" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "blue", "bg": "default", "attributes": [] }, "contents": "3 sels (3)" }, { "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": 2, "column": 1 }] }'
ui_out '{ "jsonrpc": "2.0", "method": "refresh", "params": [true] }'