summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2019-04-16 00:18:15 +1000
committerMaxime Coste <mawww@kakoune.org>2019-04-16 00:18:15 +1000
commit6d83828dabe2a9e314667ca88cfeb8942197181e (patch)
tree568f6fadaedd2c21abda91ab8b3c95220bfbed4d /src
parent6b79c1e000ab3f244f0e7f0d576aba77819f2818 (diff)
Support name captures in dynregex highlighters
Fixes #2856
Diffstat (limited to 'src')
-rw-r--r--src/highlighters.cc26
1 files changed, 21 insertions, 5 deletions
diff --git a/src/highlighters.cc b/src/highlighters.cc
index 31f50381..14587429 100644
--- a/src/highlighters.cc
+++ b/src/highlighters.cc
@@ -452,7 +452,7 @@ public:
void do_highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange range) override
{
Regex regex = m_regex_getter(context.context);
- FacesSpec face = m_face_getter(context.context);
+ FacesSpec face = regex.empty() ? FacesSpec{} : m_face_getter(context.context, regex);
if (regex != m_last_regex or face != m_last_face)
{
m_last_regex = std::move(regex);
@@ -479,15 +479,14 @@ std::unique_ptr<Highlighter> create_dynamic_regex_highlighter(HighlighterParamet
if (params.size() < 2)
throw runtime_error("wrong parameter count");
- FacesSpec faces;
+ Vector<std::pair<String, String>> faces;
for (auto& spec : params.subrange(1))
{
auto colon = find(spec, ':');
if (colon == spec.end())
throw runtime_error("wrong face spec: '" + spec +
"' expected <capture>:<facespec>");
- int capture = str_to_int({spec.begin(), colon});
- faces.emplace_back(capture, String{colon+1, spec.end()});
+ faces.emplace_back(String{spec.begin(), colon}, String{colon+1, spec.end()});
}
auto make_hl = [](auto& regex_getter, auto& face_getter) {
@@ -495,7 +494,24 @@ std::unique_ptr<Highlighter> create_dynamic_regex_highlighter(HighlighterParamet
std::decay_t<decltype(face_getter)>>>(
std::move(regex_getter), std::move(face_getter));
};
- auto get_face = [faces](const Context& context){ return faces; };
+ auto get_face = [faces=std::move(faces)](const Context& context, const Regex& regex){
+ FacesSpec spec;
+ for (auto& face : faces)
+ {
+ const int capture = str_to_int_ifp(face.first).value_or_compute([&] {
+ return regex.named_capture_index(face.first);
+ });
+ if (capture < 0)
+ {
+ write_to_debug_buffer(format("Error while evaluating dynamic regex expression faces,"
+ " {} is neither a capture index nor a capture name",
+ face.first));
+ return FacesSpec{};
+ }
+ spec.emplace_back(capture, face.second);
+ }
+ return spec;
+ };
CommandParser parser{params[0]};
auto token = parser.read_token(true);