Transform boost/std regex_error to Kakoune::regex_error at Regex construction
Fixes #318
This commit is contained in:
parent
7d9ec52bf2
commit
17e3be48a5
|
@ -253,31 +253,24 @@ public:
|
||||||
if (params.size() < 2)
|
if (params.size() < 2)
|
||||||
throw runtime_error("wrong parameter count");
|
throw runtime_error("wrong parameter count");
|
||||||
|
|
||||||
try
|
FacesSpec faces;
|
||||||
|
for (auto it = params.begin() + 1; it != params.end(); ++it)
|
||||||
{
|
{
|
||||||
FacesSpec faces;
|
auto colon = find(*it, ':');
|
||||||
for (auto it = params.begin() + 1; it != params.end(); ++it)
|
if (colon == it->end())
|
||||||
{
|
throw runtime_error("wrong face spec: '" + *it +
|
||||||
auto colon = find(*it, ':');
|
"' expected <capture>:<facespec>");
|
||||||
if (colon == it->end())
|
get_face({colon+1, it->end()}); // throw if wrong face spec
|
||||||
throw runtime_error("wrong face spec: '" + *it +
|
int capture = str_to_int({it->begin(), colon});
|
||||||
"' expected <capture>:<facespec>");
|
faces.emplace_back(capture, String{colon+1, it->end()});
|
||||||
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<RegexHighlighter>(std::move(ex),
|
|
||||||
std::move(faces))};
|
|
||||||
}
|
|
||||||
catch (RegexError& err)
|
|
||||||
{
|
|
||||||
throw runtime_error(StringView{"regex error: "} + err.what());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String id = "hlregex'" + params[0] + "'";
|
||||||
|
|
||||||
|
Regex ex{params[0].begin(), params[0].end(), Regex::optimize};
|
||||||
|
|
||||||
|
return {id, make_unique<RegexHighlighter>(std::move(ex),
|
||||||
|
std::move(faces))};
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -465,7 +458,7 @@ HighlighterAndId create_search_highlighter(HighlighterParameters params)
|
||||||
{
|
{
|
||||||
return s.empty() ? Regex{} : Regex{s.begin(), s.end()};
|
return s.empty() ? Regex{} : Regex{s.begin(), s.end()};
|
||||||
}
|
}
|
||||||
catch (RegexError& err)
|
catch (regex_error& err)
|
||||||
{
|
{
|
||||||
return Regex{};
|
return Regex{};
|
||||||
}
|
}
|
||||||
|
@ -1170,39 +1163,32 @@ public:
|
||||||
|
|
||||||
static HighlighterAndId create(HighlighterParameters params)
|
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 <id> (<group name> <begin> <end> <recurse>)+");
|
||||||
|
|
||||||
|
RegionsHighlighter::NamedRegionDescList regions;
|
||||||
|
for (size_t i = 1; i < parser.positional_count(); i += 4)
|
||||||
{
|
{
|
||||||
static const ParameterDesc param_desc{
|
if (parser[i].empty() or parser[i+1].empty() or parser[i+2].empty())
|
||||||
{ { "default", { true, "" } } },
|
throw runtime_error("group id, begin and end must not be empty");
|
||||||
ParameterDesc::Flags::SwitchesOnlyAtStart, 5
|
|
||||||
};
|
|
||||||
|
|
||||||
ParametersParser parser{params, param_desc};
|
Regex begin{parser[i+1], Regex::nosubs | Regex::optimize };
|
||||||
if ((parser.positional_count() % 4) != 1)
|
Regex end{parser[i+2], Regex::nosubs | Regex::optimize };
|
||||||
throw runtime_error("wrong parameter count, expect <id> (<group name> <begin> <end> <recurse>)+");
|
Regex recurse;
|
||||||
|
if (not parser[i+3].empty())
|
||||||
|
recurse = Regex{parser[i+3], Regex::nosubs | Regex::optimize };
|
||||||
|
|
||||||
RegionsHighlighter::NamedRegionDescList regions;
|
regions.push_back({ parser[i], {std::move(begin), std::move(end), std::move(recurse)} });
|
||||||
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<RegionsHighlighter>(std::move(regions), default_group)};
|
|
||||||
}
|
|
||||||
catch (RegexError& err)
|
|
||||||
{
|
|
||||||
throw runtime_error(StringView{"regex error: "} + err.what());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto default_group = parser.get_switch("default").value_or(StringView{}).str();
|
||||||
|
return {parser[0], make_unique<RegionsHighlighter>(std::move(regions), default_group)};
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -596,27 +596,13 @@ void regex_prompt(Context& context, const String prompt, T func)
|
||||||
: Regex{str.begin(), str.end()};
|
: Regex{str.begin(), str.end()};
|
||||||
func(std::move(regex), event, context);
|
func(std::move(regex), event, context);
|
||||||
}
|
}
|
||||||
catch (RegexError& err)
|
catch (regex_error& err)
|
||||||
{
|
{
|
||||||
if (event == PromptEvent::Validate)
|
if (event == PromptEvent::Validate)
|
||||||
throw runtime_error(format("regex error: {}", err.what()));
|
throw;
|
||||||
else
|
else
|
||||||
context.input_handler().set_prompt_face(get_face("Error"));
|
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&)
|
catch (runtime_error&)
|
||||||
{
|
{
|
||||||
context.selections_write_only() = selections;
|
context.selections_write_only() = selections;
|
||||||
|
@ -648,17 +634,10 @@ void search_next(Context& context, NormalParams params)
|
||||||
StringView str = context.main_sel_register_value("/");
|
StringView str = context.main_sel_register_value("/");
|
||||||
if (not str.empty())
|
if (not str.empty())
|
||||||
{
|
{
|
||||||
try
|
Regex ex{str.begin(), str.end()};
|
||||||
{
|
do {
|
||||||
Regex ex{str.begin(), str.end()};
|
select_next_match<direction, mode>(context.buffer(), context.selections(), ex);
|
||||||
do {
|
} while (--params.count > 0);
|
||||||
select_next_match<direction, mode>(context.buffer(), context.selections(), ex);
|
|
||||||
} while (--params.count > 0);
|
|
||||||
}
|
|
||||||
catch (RegexError& err)
|
|
||||||
{
|
|
||||||
throw runtime_error(format("regex error: ", err.what()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw runtime_error("no search pattern");
|
throw runtime_error("no search pattern");
|
||||||
|
|
|
@ -13,14 +13,7 @@ String option_to_string(const Regex& re)
|
||||||
|
|
||||||
void option_from_string(StringView str, Regex& re)
|
void option_from_string(StringView str, Regex& re)
|
||||||
{
|
{
|
||||||
try
|
re = Regex{str.begin(), str.end()};
|
||||||
{
|
|
||||||
re = Regex{str.begin(), str.end()};
|
|
||||||
}
|
|
||||||
catch (RegexError& err)
|
|
||||||
{
|
|
||||||
throw runtime_error(format("unable to create regex: {}", err.what()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
22
src/regex.hh
22
src/regex.hh
|
@ -2,6 +2,7 @@
|
||||||
#define regex_hh_INCLUDED
|
#define regex_hh_INCLUDED
|
||||||
|
|
||||||
#include "string.hh"
|
#include "string.hh"
|
||||||
|
#include "exception.hh"
|
||||||
|
|
||||||
#ifdef KAK_USE_STDREGEX
|
#ifdef KAK_USE_STDREGEX
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
@ -12,18 +13,27 @@
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct regex_error : runtime_error
|
||||||
|
{
|
||||||
|
regex_error(StringView desc)
|
||||||
|
: runtime_error{format("regex error: '{}'", desc)}
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef KAK_USE_STDREGEX
|
#ifdef KAK_USE_STDREGEX
|
||||||
// Regex that keeps track of its string representation
|
// Regex that keeps track of its string representation
|
||||||
struct Regex : std::regex
|
struct Regex : std::regex
|
||||||
{
|
{
|
||||||
Regex() = default;
|
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) {}
|
: std::regex(re.begin(), re.end(), flags), m_str(re) {}
|
||||||
|
catch (std::runtime_error& err) { throw regex_error(err.what()); }
|
||||||
|
|
||||||
template<typename Iterator>
|
template<typename Iterator>
|
||||||
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) {}
|
: 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 empty() const { return m_str.empty(); }
|
||||||
bool operator==(const Regex& other) const { return m_str == other.m_str; }
|
bool operator==(const Regex& other) const { return m_str == other.m_str; }
|
||||||
|
@ -40,12 +50,14 @@ struct Regex : boost::regex
|
||||||
{
|
{
|
||||||
Regex() = default;
|
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) {}
|
: boost::regex(re.begin(), re.end(), flags) {}
|
||||||
|
catch (std::runtime_error& err) { throw regex_error(err.what()); }
|
||||||
|
|
||||||
template<typename Iterator>
|
template<typename Iterator>
|
||||||
Regex(Iterator begin, Iterator end, flag_type flags = ECMAScript)
|
Regex(Iterator begin, Iterator end, flag_type flags = ECMAScript) try
|
||||||
: boost::regex(begin, end, flags) {}
|
: 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()}; }
|
String str() const { auto s = boost::regex::str(); return {s.begin(), s.end()}; }
|
||||||
};
|
};
|
||||||
|
@ -58,8 +70,6 @@ using RegexIterator = regex_ns::regex_iterator<Iterator>;
|
||||||
template<typename Iterator>
|
template<typename Iterator>
|
||||||
using MatchResults = regex_ns::match_results<Iterator>;
|
using MatchResults = regex_ns::match_results<Iterator>;
|
||||||
|
|
||||||
using RegexError = regex_ns::regex_error;
|
|
||||||
|
|
||||||
String option_to_string(const Regex& re);
|
String option_to_string(const Regex& re);
|
||||||
void option_from_string(StringView str, Regex& re);
|
void option_from_string(StringView str, Regex& re);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user