diff options
| author | Maxime Coste <frrrwww@gmail.com> | 2012-11-19 14:19:41 +0100 |
|---|---|---|
| committer | Maxime Coste <frrrwww@gmail.com> | 2012-11-19 14:19:41 +0100 |
| commit | c636a291bdee0d57dbee074bd735bdc45306edab (patch) | |
| tree | b576abddd4790fcbb7e5c058fdb184acdd5f61f3 /src | |
| parent | 22c545884fc9707720db4f7a6b69fbb027ad7699 (diff) | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/filters.cc | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/filters.cc b/src/filters.cc index d66bf652..d9fab000 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -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&)> class SimpleFilterFactory { @@ -88,6 +140,7 @@ void register_filters() registry.register_factory("preserve_indent", SimpleFilterFactory<preserve_indent>("preserve_indent")); registry.register_factory("cleanup_whitespaces", SimpleFilterFactory<cleanup_whitespaces>("cleanup_whitespaces")); registry.register_factory("expand_tabulations", SimpleFilterFactory<expand_tabulations>("expand_tabulations")); + registry.register_factory("regex", regex_filter_factory); registry.register_factory("group", filter_group_factory); } |
