Merge search hihglighter and regex option highlighter in dynregex

This commit is contained in:
Maxime Coste 2015-11-09 09:34:03 +00:00
parent 62c981fe2d
commit 9b8e2526f9
3 changed files with 37 additions and 49 deletions

View File

@ -969,8 +969,8 @@ general highlighters are:
For example: `:addhl regex //(\h`TODO:)?[^\n]` 0:cyan 1:yellow,red` For example: `:addhl regex //(\h`TODO:)?[^\n]` 0:cyan 1:yellow,red`
will highlight C++ style comments in cyan, with an eventual 'TODO:' in will highlight C++ style comments in cyan, with an eventual 'TODO:' in
yellow on red background. yellow on red background.
* `search`: highlight every match to the current search pattern with the * `dynregex`: Similar to regex, but expand (like a command paramater would) the
`Search` face given expression before building a regex from the result.
* `flag_lines <flag> <option_name>`: add a column in front of text, and display the * `flag_lines <flag> <option_name>`: add a column in front of text, and display the
given flag in it for everly line contained in the int-list option named given flag in it for everly line contained in the int-list option named
<option_name>. <option_name>.

View File

@ -113,7 +113,6 @@ FaceRegistry::FaceRegistry()
{ "StatusCursor", Face{ Color::Black, Color::Cyan } }, { "StatusCursor", Face{ Color::Black, Color::Cyan } },
{ "Prompt", Face{ Color::Yellow, Color::Default } }, { "Prompt", Face{ Color::Yellow, Color::Default } },
{ "MatchingChar", Face{ Color::Default, Color::Default, Attribute::Bold } }, { "MatchingChar", Face{ Color::Default, Color::Default, Attribute::Bold } },
{ "Search", Face{ Color::Default, Color::Default, Attribute::Underline } },
} }
{} {}

View File

@ -249,15 +249,15 @@ public:
throw runtime_error("wrong parameter count"); throw runtime_error("wrong parameter count");
FacesSpec faces; FacesSpec faces;
for (auto it = params.begin() + 1; it != params.end(); ++it) for (auto& spec : params.subrange(1, params.size()-1))
{ {
auto colon = find(*it, ':'); auto colon = find(spec, ':');
if (colon == it->end()) if (colon == spec.end())
throw runtime_error("wrong face spec: '" + *it + throw runtime_error("wrong face spec: '" + spec +
"' expected <capture>:<facespec>"); "' expected <capture>:<facespec>");
get_face({colon+1, it->end()}); // throw if wrong face spec get_face({colon+1, spec.end()}); // throw if wrong face spec
int capture = str_to_int({it->begin(), colon}); int capture = str_to_int({spec.begin(), colon});
faces.emplace_back(capture, String{colon+1, it->end()}); faces.emplace_back(capture, String{colon+1, spec.end()});
} }
String id = "hlregex'" + params[0] + "'"; String id = "hlregex'" + params[0] + "'";
@ -429,46 +429,39 @@ make_dynamic_regex_highlighter(RegexGetter regex_getter, FaceGetter face_getter)
std::move(regex_getter), std::move(face_getter)); std::move(regex_getter), std::move(face_getter));
} }
HighlighterAndId create_search_highlighter(HighlighterParameters params) HighlighterAndId create_dynamic_regex_highlighter(HighlighterParameters params)
{ {
if (params.size() != 0) if (params.size() < 2)
throw runtime_error("wrong parameter count"); throw runtime_error("Wrong parameter count");
auto get_face = [](const Context& context){ FacesSpec faces;
return FacesSpec{ { 0, "Search" } }; for (auto& spec : params.subrange(1, params.size()-1))
}; {
auto get_regex = [](const Context& context){ auto colon = find(spec, ':');
auto s = context.main_sel_register_value("/"); if (colon == spec.end())
throw runtime_error("wrong face spec: '" + spec +
"' expected <capture>:<facespec>");
get_face({colon+1, spec.end()}); // throw if wrong face spec
int capture = str_to_int({spec.begin(), colon});
faces.emplace_back(capture, String{colon+1, spec.end()});
}
auto get_face = [faces](const Context& context){ return faces;; };
String expr = params[0];
auto get_regex = [expr](const Context& context){
try try
{ {
return s.empty() ? Regex{} : Regex{s.begin(), s.end()}; auto re = expand(expr, context);
return re.empty() ? Regex{} : Regex{re};
} }
catch (regex_error& err) catch (runtime_error& err)
{ {
write_to_debug_buffer(format("Error while evaluating dynamic regex expression", err.what()));
return Regex{}; return Regex{};
} }
}; };
return {"hlsearch", make_dynamic_regex_highlighter(get_regex, get_face)}; return {format("dynregex_{}", expr), make_dynamic_regex_highlighter(get_regex, get_face)};
}
HighlighterAndId create_regex_option_highlighter(HighlighterParameters params)
{
if (params.size() != 2)
throw runtime_error("wrong parameter count");
String facespec = params[1];
auto get_face = [=](const Context&){
return FacesSpec{ { 0, facespec } };
};
String option_name = params[0];
// verify option type now
GlobalScope::instance().options()[option_name].get<Regex>();
auto get_regex = [option_name](const Context& context){
return context.options()[option_name].get<Regex>();
};
return {"hloption_" + option_name, make_dynamic_regex_highlighter(get_regex, get_face)};
} }
HighlighterAndId create_line_highlighter(HighlighterParameters params) HighlighterAndId create_line_highlighter(HighlighterParameters params)
@ -1375,14 +1368,10 @@ void register_highlighters()
"Parameters: <regex> <capture num>:<face> <capture num>:<face>...\n" "Parameters: <regex> <capture num>:<face> <capture num>:<face>...\n"
"Highlights the matches for captures from the regex with the given faces" } }); "Highlights the matches for captures from the regex with the given faces" } });
registry.append({ registry.append({
"regex_option", "dynregex",
{ create_regex_option_highlighter, { create_dynamic_regex_highlighter,
"Parameters: <option name> <face>\n" "Parameters: <expr> <capture num>:<face> <capture num>:<face>...\n"
"Highlight matches for the regex stored in <option name> with <face>" } }); "Evaluate expression at every redraw to gather a regex" } });
registry.append({
"search",
{ create_search_highlighter,
"Highlight the current search pattern with the Search face" } });
registry.append({ registry.append({
"group", "group",
{ create_highlighter_group, { create_highlighter_group,