Add a regex filter
regex filter takes three arguments: <line_match> <insert_match> <replacement> <line_match> is checked from begining of line to point of insertion <insert_match> is checked on the inserted text (usually only one char) <replacement> is used to replace the inserted text, it can use $1..9 for captures in line_match, and $c to specify the cursor position. for example, ':addfilter regex .* \( ($c)' makes inserting an opening parens insert the closing one as well, keeping the insertion cursor in the right spot.
This commit is contained in:
parent
22c545884f
commit
c636a291bd
|
@ -59,6 +59,58 @@ void expand_tabulations(Buffer& buffer, Selection& selection, String& content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct RegexFilter
|
||||||
|
{
|
||||||
|
RegexFilter(const String& line_match, const String& insert_match,
|
||||||
|
const String& replacement)
|
||||||
|
: m_line_match(line_match.c_str()), m_insert_match(insert_match.c_str()),
|
||||||
|
m_replacement(replacement.c_str()) {}
|
||||||
|
|
||||||
|
void operator() (Buffer& buffer, Selection& selection, String& content)
|
||||||
|
{
|
||||||
|
const auto& position = selection.last();
|
||||||
|
auto line_begin = buffer.iterator_at_line_begin(position);
|
||||||
|
boost::match_results<BufferIterator> results;
|
||||||
|
if (boost::regex_match(content.c_str(), m_insert_match) and
|
||||||
|
boost::regex_match(line_begin, position, results, m_line_match))
|
||||||
|
{
|
||||||
|
String suffix;
|
||||||
|
content = results.format(m_replacement.c_str());
|
||||||
|
auto it = std::find(content.begin(), content.end(), '$');
|
||||||
|
if (it != content.end())
|
||||||
|
{
|
||||||
|
++it;
|
||||||
|
if (it != content.end() && *it == 'c')
|
||||||
|
{
|
||||||
|
String suffix(it+1, content.end());
|
||||||
|
content = String(content.begin(), it-1);
|
||||||
|
|
||||||
|
auto first = selection.first();
|
||||||
|
auto last = selection.last();
|
||||||
|
buffer.insert(position, suffix);
|
||||||
|
if (selection.first() == selection.last())
|
||||||
|
selection.first() -= suffix.length();
|
||||||
|
selection.last() -= suffix.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Regex m_line_match;
|
||||||
|
Regex m_insert_match;
|
||||||
|
String m_replacement;
|
||||||
|
};
|
||||||
|
|
||||||
|
FilterAndId regex_filter_factory(const FilterParameters& params)
|
||||||
|
{
|
||||||
|
if (params.size() != 3)
|
||||||
|
throw runtime_error("wrong parameter count");
|
||||||
|
|
||||||
|
return FilterAndId{"re" + params[0] + "__" + params[1],
|
||||||
|
RegexFilter{params[0], params[1], params[2]}};
|
||||||
|
}
|
||||||
|
|
||||||
template<void (*filter_func)(Buffer&, Selection&, String&)>
|
template<void (*filter_func)(Buffer&, Selection&, String&)>
|
||||||
class SimpleFilterFactory
|
class SimpleFilterFactory
|
||||||
{
|
{
|
||||||
|
@ -88,6 +140,7 @@ void register_filters()
|
||||||
registry.register_factory("preserve_indent", SimpleFilterFactory<preserve_indent>("preserve_indent"));
|
registry.register_factory("preserve_indent", SimpleFilterFactory<preserve_indent>("preserve_indent"));
|
||||||
registry.register_factory("cleanup_whitespaces", SimpleFilterFactory<cleanup_whitespaces>("cleanup_whitespaces"));
|
registry.register_factory("cleanup_whitespaces", SimpleFilterFactory<cleanup_whitespaces>("cleanup_whitespaces"));
|
||||||
registry.register_factory("expand_tabulations", SimpleFilterFactory<expand_tabulations>("expand_tabulations"));
|
registry.register_factory("expand_tabulations", SimpleFilterFactory<expand_tabulations>("expand_tabulations"));
|
||||||
|
registry.register_factory("regex", regex_filter_factory);
|
||||||
registry.register_factory("group", filter_group_factory);
|
registry.register_factory("group", filter_group_factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user