diff --git a/src/highlighters.cc b/src/highlighters.cc index de4e6ed1a..5ff6d6a20 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -253,31 +253,24 @@ public: if (params.size() < 2) throw runtime_error("wrong parameter count"); - try + FacesSpec faces; + for (auto it = params.begin() + 1; it != params.end(); ++it) { - FacesSpec faces; - for (auto it = params.begin() + 1; it != params.end(); ++it) - { - auto colon = find(*it, ':'); - if (colon == it->end()) - throw runtime_error("wrong face spec: '" + *it + - "' expected :"); - get_face({colon+1, it->end()}); // throw if wrong face spec - int capture = str_to_int({it->begin(), colon}); - faces.emplace_back(capture, String{colon+1, it->end()}); - } - - String id = "hlregex'" + params[0] + "'"; - - Regex ex{params[0].begin(), params[0].end(), Regex::optimize}; - - return {id, make_unique(std::move(ex), - std::move(faces))}; - } - catch (RegexError& err) - { - throw runtime_error(StringView{"regex error: "} + err.what()); + auto colon = find(*it, ':'); + if (colon == it->end()) + throw runtime_error("wrong face spec: '" + *it + + "' expected :"); + get_face({colon+1, it->end()}); // throw if wrong face spec + int capture = str_to_int({it->begin(), colon}); + faces.emplace_back(capture, String{colon+1, it->end()}); } + + String id = "hlregex'" + params[0] + "'"; + + Regex ex{params[0].begin(), params[0].end(), Regex::optimize}; + + return {id, make_unique(std::move(ex), + std::move(faces))}; } private: @@ -465,7 +458,7 @@ HighlighterAndId create_search_highlighter(HighlighterParameters params) { return s.empty() ? Regex{} : Regex{s.begin(), s.end()}; } - catch (RegexError& err) + catch (regex_error& err) { return Regex{}; } @@ -1170,39 +1163,32 @@ public: static HighlighterAndId create(HighlighterParameters params) { - try + static const ParameterDesc param_desc{ + { { "default", { true, "" } } }, + ParameterDesc::Flags::SwitchesOnlyAtStart, 5 + }; + + ParametersParser parser{params, param_desc}; + if ((parser.positional_count() % 4) != 1) + throw runtime_error("wrong parameter count, expect ( )+"); + + RegionsHighlighter::NamedRegionDescList regions; + for (size_t i = 1; i < parser.positional_count(); i += 4) { - static const ParameterDesc param_desc{ - { { "default", { true, "" } } }, - ParameterDesc::Flags::SwitchesOnlyAtStart, 5 - }; + if (parser[i].empty() or parser[i+1].empty() or parser[i+2].empty()) + throw runtime_error("group id, begin and end must not be empty"); - ParametersParser parser{params, param_desc}; - if ((parser.positional_count() % 4) != 1) - throw runtime_error("wrong parameter count, expect ( )+"); + Regex begin{parser[i+1], Regex::nosubs | Regex::optimize }; + Regex end{parser[i+2], Regex::nosubs | Regex::optimize }; + Regex recurse; + if (not parser[i+3].empty()) + recurse = Regex{parser[i+3], Regex::nosubs | Regex::optimize }; - RegionsHighlighter::NamedRegionDescList regions; - for (size_t i = 1; i < parser.positional_count(); i += 4) - { - if (parser[i].empty() or parser[i+1].empty() or parser[i+2].empty()) - throw runtime_error("group id, begin and end must not be empty"); - - Regex begin{parser[i+1], Regex::nosubs | Regex::optimize }; - Regex end{parser[i+2], Regex::nosubs | Regex::optimize }; - Regex recurse; - if (not parser[i+3].empty()) - recurse = Regex{parser[i+3], Regex::nosubs | Regex::optimize }; - - regions.push_back({ parser[i], {std::move(begin), std::move(end), std::move(recurse)} }); - } - - auto default_group = parser.get_switch("default").value_or(StringView{}).str(); - return {parser[0], make_unique(std::move(regions), default_group)}; - } - catch (RegexError& err) - { - throw runtime_error(StringView{"regex error: "} + err.what()); + regions.push_back({ parser[i], {std::move(begin), std::move(end), std::move(recurse)} }); } + + auto default_group = parser.get_switch("default").value_or(StringView{}).str(); + return {parser[0], make_unique(std::move(regions), default_group)}; } private: diff --git a/src/normal.cc b/src/normal.cc index 4c54ea051..af2553e14 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -596,27 +596,13 @@ void regex_prompt(Context& context, const String prompt, T func) : Regex{str.begin(), str.end()}; func(std::move(regex), event, context); } - catch (RegexError& err) + catch (regex_error& err) { if (event == PromptEvent::Validate) - throw runtime_error(format("regex error: {}", err.what())); + throw; else context.input_handler().set_prompt_face(get_face("Error")); } - catch (std::runtime_error& err) - { - if (event == PromptEvent::Validate) - throw runtime_error(format("regex error: {}", err.what())); - else - { - context.input_handler().set_prompt_face(get_face("Error")); - if (context.has_ui()) - { - Face face = get_face("Information"); - context.ui().info_show("regex error", err.what(), CharCoord{}, face, InfoStyle::Prompt); - } - } - } catch (runtime_error&) { context.selections_write_only() = selections; @@ -648,17 +634,10 @@ void search_next(Context& context, NormalParams params) StringView str = context.main_sel_register_value("/"); if (not str.empty()) { - try - { - Regex ex{str.begin(), str.end()}; - do { - select_next_match(context.buffer(), context.selections(), ex); - } while (--params.count > 0); - } - catch (RegexError& err) - { - throw runtime_error(format("regex error: ", err.what())); - } + Regex ex{str.begin(), str.end()}; + do { + select_next_match(context.buffer(), context.selections(), ex); + } while (--params.count > 0); } else throw runtime_error("no search pattern"); diff --git a/src/regex.cc b/src/regex.cc index d678a62ad..c650651c1 100644 --- a/src/regex.cc +++ b/src/regex.cc @@ -13,14 +13,7 @@ String option_to_string(const Regex& re) void option_from_string(StringView str, Regex& re) { - try - { - re = Regex{str.begin(), str.end()}; - } - catch (RegexError& err) - { - throw runtime_error(format("unable to create regex: {}", err.what())); - } + re = Regex{str.begin(), str.end()}; } } diff --git a/src/regex.hh b/src/regex.hh index d76156d6f..ffc200482 100644 --- a/src/regex.hh +++ b/src/regex.hh @@ -2,6 +2,7 @@ #define regex_hh_INCLUDED #include "string.hh" +#include "exception.hh" #ifdef KAK_USE_STDREGEX #include @@ -12,18 +13,27 @@ namespace Kakoune { +struct regex_error : runtime_error +{ + regex_error(StringView desc) + : runtime_error{format("regex error: '{}'", desc)} + {} +}; + #ifdef KAK_USE_STDREGEX // Regex that keeps track of its string representation struct Regex : std::regex { Regex() = default; - explicit Regex(StringView re, flag_type flags = ECMAScript) + explicit Regex(StringView re, flag_type flags = ECMAScript) try : std::regex(re.begin(), re.end(), flags), m_str(re) {} + catch (std::runtime_error& err) { throw regex_error(err.what()); } template - Regex(Iterator begin, Iterator end, flag_type flags = ECMAScript) + Regex(Iterator begin, Iterator end, flag_type flags = ECMAScript) try : std::regex(begin, end, flags), m_str(begin, end) {} + catch (std::runtime_error& err) { throw regex_error(err.what()); } bool empty() const { return m_str.empty(); } bool operator==(const Regex& other) const { return m_str == other.m_str; } @@ -40,12 +50,14 @@ struct Regex : boost::regex { Regex() = default; - explicit Regex(StringView re, flag_type flags = ECMAScript) + explicit Regex(StringView re, flag_type flags = ECMAScript) try : boost::regex(re.begin(), re.end(), flags) {} + catch (std::runtime_error& err) { throw regex_error(err.what()); } template - Regex(Iterator begin, Iterator end, flag_type flags = ECMAScript) + Regex(Iterator begin, Iterator end, flag_type flags = ECMAScript) try : boost::regex(begin, end, flags) {} + catch (std::runtime_error& err) { throw regex_error(err.what()); } String str() const { auto s = boost::regex::str(); return {s.begin(), s.end()}; } }; @@ -58,8 +70,6 @@ using RegexIterator = regex_ns::regex_iterator; template using MatchResults = regex_ns::match_results; -using RegexError = regex_ns::regex_error; - String option_to_string(const Regex& re); void option_from_string(StringView str, Regex& re);