Add -override support to add-highlighter

This allow replacing a highlighter in place, not loosing its current
position in its parent.

Fixes #3436
main
Maxime Coste 2020-03-30 21:03:51 +11:00
parent b42885ef71
commit c585107ab5
8 changed files with 34 additions and 18 deletions

View File

@ -252,12 +252,12 @@ of the file onto the filesystem
*colorscheme* <name>::
load named colorscheme
*add-highlighter* <highlighter_name> <highlighter_parameters> ...::
*add-highlighter* [<switches>] <highlighter_path> <highlighter_parameters> ...::
*alias* addhl +
add a highlighter to the current window
(See <<highlighters#,`:doc highlighters`>>)
*remove-highlighter* <highlighter_id>::
*remove-highlighter* <highlighter_path>::
*alias* rmhl +
remove the highlighter whose id is *highlighter_id*
(See <<highlighters#,`:doc highlighters`>>)

View File

@ -5,9 +5,9 @@
Manipulation of the displayed text is done through highlighters, which can
be added or removed with the following commands:
-----------------------------------------------------
add-highlighter <path>/<name> <type> <parameters> ...
-----------------------------------------------------
-----------------------------------------------------------------
add-highlighter [-override] <path>/<name> <type> <parameters> ...
-----------------------------------------------------------------
and
@ -23,6 +23,9 @@ separated path starting with a scope. Scopes are *global*, *buffer*,
`add-highlighter` (the path ends with a `/`), it will be auto-generated
from the remaining parameters.
if `-override` is specified and the given name already exists, that
highlighter is replaced with the new one.
== Convenient highlighters
*show-matching*::

View File

@ -950,7 +950,10 @@ const CommandDesc add_highlighter_cmd = {
"add-highlighter <path>/<name> <type> <type params>...: add an highlighter to the group identified by <path>\n"
" <path> is a '/' delimited path or the parent highlighter, starting with either\n"
" 'global', 'buffer', 'window' or 'shared', if <name> is empty, it will be autogenerated",
ParameterDesc{ {}, ParameterDesc::Flags::SwitchesAsPositional, 2 },
ParameterDesc{
{ { "override", { false, "replace existing highlighter with same path if it exists" } }, },
ParameterDesc::Flags::SwitchesOnlyAtStart, 2
},
CommandFlags::None,
[](const Context& context, CommandParameters params) -> String
{
@ -990,7 +993,7 @@ const CommandDesc add_highlighter_cmd = {
String name{slash.base(), path.end()};
Highlighter& parent = get_highlighter(context, {path.begin(), slash.base() - 1});
parent.add_child(name.empty() ? auto_name(parser.positionals_from(1)) : std::move(name),
it->value.factory(highlighter_params, &parent));
it->value.factory(highlighter_params, &parent), (bool)parser.get_switch("override"));
redraw_relevant_clients(context, path);
}

View File

@ -34,7 +34,7 @@ Highlighter& Highlighter::get_child(StringView path)
throw runtime_error("this highlighter does not hold children");
}
void Highlighter::add_child(String name, std::unique_ptr<Highlighter>&& hl)
void Highlighter::add_child(String, std::unique_ptr<Highlighter>&&, bool)
{
throw runtime_error("this highlighter does not hold children");
}

View File

@ -69,7 +69,7 @@ struct Highlighter
virtual bool has_children() const;
virtual Highlighter& get_child(StringView path);
virtual void add_child(String name, std::unique_ptr<Highlighter>&& hl);
virtual void add_child(String name, std::unique_ptr<Highlighter>&& hl, bool override = false);
virtual void remove_child(StringView id);
virtual Completions complete_child(StringView path, ByteCount cursor_pos, bool group) const;
virtual void fill_unique_ids(Vector<StringView>& unique_ids) const;

View File

@ -24,13 +24,19 @@ void HighlighterGroup::fill_unique_ids(Vector<StringView>& unique_ids) const
hl.value->fill_unique_ids(unique_ids);
}
void HighlighterGroup::add_child(String name, std::unique_ptr<Highlighter>&& hl)
void HighlighterGroup::add_child(String name, std::unique_ptr<Highlighter>&& hl, bool override)
{
if ((hl->passes() & passes()) != hl->passes())
throw runtime_error{"cannot add that highlighter to this group, passes don't match"};
if (m_highlighters.contains(name))
throw runtime_error(format("duplicate id: '{}'", name));
auto it = m_highlighters.find(name);
if (it != m_highlighters.end())
{
if (not override)
throw runtime_error(format("duplicate id: '{}'", name));
it->value = std::move(hl);
return;
}
m_highlighters.insert({std::move(name), std::move(hl)});
}

View File

@ -21,7 +21,7 @@ public:
HighlighterGroup(HighlightPass passes) : Highlighter{passes} {}
bool has_children() const override { return true; }
void add_child(String name, std::unique_ptr<Highlighter>&& hl) override;
void add_child(String name, std::unique_ptr<Highlighter>&& hl, bool override = false) override;
void remove_child(StringView id) override;
Highlighter& get_child(StringView path) override;

View File

@ -1873,11 +1873,12 @@ public:
return it->value->get_child({sep_it+1, path.end()});
}
void add_child(String name, std::unique_ptr<Highlighter>&& hl) override
void add_child(String name, std::unique_ptr<Highlighter>&& hl, bool override) override
{
if (not dynamic_cast<RegionHighlighter*>(hl.get()))
throw runtime_error{"only region highlighter can be added as child of a regions highlighter"};
if (m_regions.contains(name))
auto it = m_regions.find(name);
if (not override and it != m_regions.end())
throw runtime_error{format("duplicate id: '{}'", name)};
std::unique_ptr<RegionHighlighter> region_hl{dynamic_cast<RegionHighlighter*>(hl.release())};
@ -1888,7 +1889,10 @@ public:
m_default_region = name;
}
m_regions.insert({std::move(name), std::move(region_hl)});
if (it != m_regions.end())
it->value = std::move(region_hl);
else
m_regions.insert({std::move(name), std::move(region_hl)});
++m_regions_timestamp;
}
@ -2132,9 +2136,9 @@ private:
return m_delegate->get_child(path);
}
void add_child(String name, std::unique_ptr<Highlighter>&& hl) override
void add_child(String name, std::unique_ptr<Highlighter>&& hl, bool override) override
{
return m_delegate->add_child(name, std::move(hl));
return m_delegate->add_child(name, std::move(hl), override);
}
void remove_child(StringView id) override