remove filters, use hooks instead
This commit is contained in:
parent
4c39743b69
commit
471aeaab9a
|
@ -464,34 +464,6 @@ existing highlighters are:
|
|||
given flag in it for everly lines contained in the int-list option named
|
||||
<option_name>.
|
||||
|
||||
Filters
|
||||
-------
|
||||
|
||||
Filters can be installed to interact with buffer modifications. They can be
|
||||
added or removed with
|
||||
|
||||
-----------------------------------------------
|
||||
:addfilter <filter_name> <filter_parameters...>
|
||||
-----------------------------------------------
|
||||
|
||||
and
|
||||
|
||||
---------------------
|
||||
:rmfilter <filter_id>
|
||||
---------------------
|
||||
|
||||
exisiting filters are:
|
||||
|
||||
* +preserve_indent+: insert previous line indent when inserting a newline
|
||||
* +cleanup_whitespaces+: remove trailing whitespaces on the previous line
|
||||
when inserting an end-of-line.
|
||||
* +expand_tabulations+: insert spaces instead of tab characters
|
||||
* +regex <line_regex> <insert_regex> <replacement>+: when the current line regex
|
||||
and inserted text regex matches, replace insereted text with the
|
||||
replacement text. Capture groups are available through $[0-9] escape
|
||||
sequence, and cursor position can be specified with $c.
|
||||
* +group+: same as highlighters group
|
||||
|
||||
Hooks
|
||||
-----
|
||||
|
||||
|
|
|
@ -982,14 +982,11 @@ private:
|
|||
|
||||
void insert(Codepoint key)
|
||||
{
|
||||
auto str = codepoint_to_str(key);
|
||||
auto& buffer = m_edition.editor().buffer();
|
||||
for (auto& sel : m_edition.editor().m_selections)
|
||||
{
|
||||
auto content = codepoint_to_str(key);
|
||||
m_edition.editor().filters()(buffer, sel, content);
|
||||
buffer.insert(buffer.iterator_at(sel.last()), content);
|
||||
}
|
||||
context().hooks().run_hook("InsertKey", codepoint_to_str(key), context());
|
||||
for (auto& sel : m_edition.editor().selections())
|
||||
buffer.insert(buffer.iterator_at(sel.last()), str);
|
||||
context().hooks().run_hook("InsertKey", str, context());
|
||||
}
|
||||
|
||||
void prepare(InsertMode mode)
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "debug.hh"
|
||||
#include "event_manager.hh"
|
||||
#include "file.hh"
|
||||
#include "filter.hh"
|
||||
#include "highlighter.hh"
|
||||
#include "highlighters.hh"
|
||||
#include "client.hh"
|
||||
|
@ -283,39 +282,6 @@ void rm_highlighter(CommandParameters params, Context& context)
|
|||
group.remove(parser[0]);
|
||||
}
|
||||
|
||||
void add_filter(CommandParameters params, Context& context)
|
||||
{
|
||||
ParametersParser parser(params, { { "group", true } }, ParametersParser::Flags::None, 1);
|
||||
|
||||
FilterRegistry& registry = FilterRegistry::instance();
|
||||
|
||||
auto begin = parser.begin();
|
||||
const String& name = *begin;
|
||||
std::vector<String> filter_params;
|
||||
for (++begin; begin != parser.end(); ++begin)
|
||||
filter_params.push_back(*begin);
|
||||
|
||||
Editor& editor = context.editor();
|
||||
FilterGroup& group = parser.has_option("group") ?
|
||||
get_group(editor.filters(), parser.option_value("group"))
|
||||
: editor.filters();
|
||||
|
||||
auto& factory = registry[name];
|
||||
group.append(factory(filter_params));
|
||||
}
|
||||
|
||||
void rm_filter(CommandParameters params, Context& context)
|
||||
{
|
||||
ParametersParser parser(params, { { "group", true } }, ParametersParser::Flags::None, 1, 1);
|
||||
|
||||
Editor& editor = context.editor();
|
||||
FilterGroup& group = parser.has_option("group") ?
|
||||
get_group(editor.filters(), parser.option_value("group"))
|
||||
: editor.filters();
|
||||
|
||||
group.remove(parser[0]);
|
||||
}
|
||||
|
||||
static HookManager& get_hook_manager(const String& scope, Context& context)
|
||||
{
|
||||
if (prefix_match("global", scope))
|
||||
|
@ -838,11 +804,8 @@ void register_commands()
|
|||
cm.register_commands({"nb", "namebuf"}, set_buffer_name);
|
||||
|
||||
auto get_highlighters = [](const Context& c) -> HighlighterGroup& { return c.window().highlighters(); };
|
||||
auto get_filters = [](const Context& c) -> FilterGroup& { return c.window().filters(); };
|
||||
cm.register_commands({ "ah", "addhl" }, add_highlighter, group_add_completer<HighlighterRegistry>(get_highlighters));
|
||||
cm.register_commands({ "rh", "rmhl" }, rm_highlighter, group_rm_completer(get_highlighters));
|
||||
cm.register_commands({ "af", "addfilter" }, add_filter, group_add_completer<FilterRegistry>(get_filters));
|
||||
cm.register_commands({ "rf", "rmfilter" }, rm_filter, group_rm_completer(get_filters));
|
||||
|
||||
cm.register_command("hook", add_hook);
|
||||
cm.register_command("rmhooks", rm_hooks);
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include "buffer.hh"
|
||||
#include "dynamic_selection_list.hh"
|
||||
#include "filter.hh"
|
||||
#include "memoryview.hh"
|
||||
|
||||
namespace Kakoune
|
||||
|
@ -82,11 +81,6 @@ public:
|
|||
bool undo();
|
||||
bool redo();
|
||||
|
||||
FilterGroup& filters() { return m_filters; }
|
||||
|
||||
CandidateList complete_filterid(const String& prefix,
|
||||
size_t cursor_pos = String::npos);
|
||||
|
||||
bool is_editing() const { return m_edition_level!= 0; }
|
||||
private:
|
||||
friend struct scoped_edition;
|
||||
|
@ -104,7 +98,6 @@ private:
|
|||
safe_ptr<Buffer> m_buffer;
|
||||
DynamicSelectionList m_selections;
|
||||
size_t m_main_sel;
|
||||
FilterGroup m_filters;
|
||||
};
|
||||
|
||||
struct scoped_edition
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
#ifndef filter_hh_INCLUDED
|
||||
#define filter_hh_INCLUDED
|
||||
|
||||
#include "function_group.hh"
|
||||
#include "function_registry.hh"
|
||||
#include "memoryview.hh"
|
||||
#include "string.hh"
|
||||
#include "utils.hh"
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
class Buffer;
|
||||
struct Selection;
|
||||
|
||||
// A Filter is a function which is applied to a Buffer and a pending
|
||||
// Modification in order to mutate the Buffer or the Modification
|
||||
// prior to it's application.
|
||||
|
||||
using FilterFunc = std::function<void (Buffer& buffer, Selection& selection, String& content)>;
|
||||
using FilterAndId = std::pair<String, FilterFunc>;
|
||||
using FilterGroup = FunctionGroup<Buffer&, Selection&, String&>;
|
||||
|
||||
using FilterParameters = memoryview<String>;
|
||||
using FilterFactory = std::function<FilterAndId (FilterParameters params)>;
|
||||
|
||||
struct FilterRegistry : FunctionRegistry<FilterFactory>,
|
||||
Singleton<FilterRegistry>
|
||||
{};
|
||||
|
||||
}
|
||||
|
||||
#endif // filter_hh_INCLUDED
|
144
src/filters.cc
144
src/filters.cc
|
@ -1,144 +0,0 @@
|
|||
#include "filters.hh"
|
||||
|
||||
#include "buffer.hh"
|
||||
#include "selection.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
void preserve_indent(Buffer& buffer, Selection& selection, String& content)
|
||||
{
|
||||
if (content == "\n")
|
||||
{
|
||||
BufferCoord line_begin{selection.last().line, 0};
|
||||
auto first_non_white = buffer.iterator_at(line_begin);
|
||||
while ((*first_non_white == '\t' or *first_non_white == ' ') and
|
||||
first_non_white != buffer.end())
|
||||
++first_non_white;
|
||||
|
||||
content += buffer.string(line_begin, first_non_white.coord());
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup_whitespaces(Buffer& buffer, Selection& selection, String& content)
|
||||
{
|
||||
const auto position = buffer.iterator_at(selection.last());
|
||||
if (content[0] == '\n' and position != buffer.begin())
|
||||
{
|
||||
auto whitespace_start = position-1;
|
||||
while ((*whitespace_start == ' ' or *whitespace_start == '\t') and
|
||||
whitespace_start != buffer.begin())
|
||||
--whitespace_start;
|
||||
++whitespace_start;
|
||||
if (whitespace_start != position)
|
||||
buffer.erase(whitespace_start, position);
|
||||
}
|
||||
}
|
||||
|
||||
void expand_tabulations(Buffer& buffer, Selection& selection, String& content)
|
||||
{
|
||||
const int tabstop = buffer.options()["tabstop"].get<int>();
|
||||
if (content == "\t")
|
||||
{
|
||||
int column = 0;
|
||||
const auto position = buffer.iterator_at(selection.last());
|
||||
for (auto it = buffer.iterator_at(selection.last().line);
|
||||
it != position; ++it)
|
||||
{
|
||||
kak_assert(*it != '\n');
|
||||
if (*it == '\t')
|
||||
column += tabstop - (column % tabstop);
|
||||
else
|
||||
++column;
|
||||
}
|
||||
|
||||
CharCount count = tabstop - (column % tabstop);
|
||||
content = String(' ', count);
|
||||
}
|
||||
}
|
||||
|
||||
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 = buffer.iterator_at(selection.last());
|
||||
auto line_begin = buffer.iterator_at(selection.last().line);
|
||||
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))
|
||||
{
|
||||
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);
|
||||
buffer.insert(position, suffix);
|
||||
|
||||
auto& first = selection.first();
|
||||
auto& last = selection.last();
|
||||
if (first == last)
|
||||
first = buffer.advance(first, -suffix.length());
|
||||
last = buffer.advance(last, -suffix.length());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Regex m_line_match;
|
||||
Regex m_insert_match;
|
||||
String m_replacement;
|
||||
};
|
||||
|
||||
FilterAndId regex_filter_factory(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
|
||||
{
|
||||
public:
|
||||
SimpleFilterFactory(const String& id) : m_id(id) {}
|
||||
|
||||
FilterAndId operator()(FilterParameters params) const
|
||||
{
|
||||
return FilterAndId(m_id, FilterFunc(filter_func));
|
||||
}
|
||||
private:
|
||||
String m_id;
|
||||
};
|
||||
|
||||
FilterAndId filter_group_factory(FilterParameters params)
|
||||
{
|
||||
if (params.size() != 1)
|
||||
throw runtime_error("wrong parameter count");
|
||||
|
||||
return FilterAndId(params[0], FilterGroup());
|
||||
}
|
||||
|
||||
void register_filters()
|
||||
{
|
||||
FilterRegistry& registry = FilterRegistry::instance();
|
||||
|
||||
registry.register_func("preserve_indent", SimpleFilterFactory<preserve_indent>("preserve_indent"));
|
||||
registry.register_func("cleanup_whitespaces", SimpleFilterFactory<cleanup_whitespaces>("cleanup_whitespaces"));
|
||||
registry.register_func("expand_tabulations", SimpleFilterFactory<expand_tabulations>("expand_tabulations"));
|
||||
registry.register_func("regex", regex_filter_factory);
|
||||
registry.register_func("group", filter_group_factory);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#ifndef filters_hh_INCLUDED
|
||||
#define filters_hh_INCLUDED
|
||||
|
||||
#include "filter.hh"
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
void register_filters();
|
||||
|
||||
}
|
||||
|
||||
#endif // filters_hh_INCLUDED
|
|
@ -9,7 +9,6 @@
|
|||
#include "debug.hh"
|
||||
#include "event_manager.hh"
|
||||
#include "file.hh"
|
||||
#include "filters.hh"
|
||||
#include "highlighters.hh"
|
||||
#include "hook_manager.hh"
|
||||
#include "ncurses.hh"
|
||||
|
@ -271,7 +270,6 @@ int kakoune(memoryview<String> params)
|
|||
BufferManager buffer_manager;
|
||||
RegisterManager register_manager;
|
||||
HighlighterRegistry highlighter_registry;
|
||||
FilterRegistry filter_registry;
|
||||
ColorRegistry color_registry;
|
||||
ClientManager client_manager;
|
||||
|
||||
|
@ -281,7 +279,6 @@ int kakoune(memoryview<String> params)
|
|||
register_registers();
|
||||
register_commands();
|
||||
register_highlighters();
|
||||
register_filters();
|
||||
|
||||
write_debug("*** This is the debug buffer, where debug info will be written ***");
|
||||
write_debug("pid: " + to_string(getpid()));
|
||||
|
|
|
@ -4,10 +4,10 @@ hook global BufCreate (.*/)?(kakrc|.*.kak) %{
|
|||
|
||||
hook global WinSetOption filetype=kak %{
|
||||
addhl group kak-highlight
|
||||
addhl -group kak-highlight regex \<(hook|rmhooks|addhl|rmhl|addfilter|rmfilter|exec|eval|source|runtime|def|decl|echo|edit|set)\> 0:keyword
|
||||
addhl -group kak-highlight regex \<(hook|rmhooks|addhl|rmhl|add|exec|eval|source|runtime|def|decl|echo|edit|set)\> 0:keyword
|
||||
addhl -group kak-highlight regex \<(default|black|red|green|yellow|blue|magenta|cyan|white)\> 0:value
|
||||
addhl -group kak-highlight regex (?<=\<hook)\h+((global|buffer|window)|(\S+))\h+(\S+)\h+(\H+) 2:attribute 3:error 4:identifier 5:string
|
||||
addhl -group kak-highlight regex (?<=\<set)\h+((global|buffer|window)|(\S+))\h+(\S+)\h+(\H+) 2:attribute 3:error 4:identifier 5:value
|
||||
addhl -group kak-highlight regex (?<=\<set)\h+((global|buffer|window)|(\S+))\h+(\S+)\h+(\S+) 2:attribute 3:error 4:identifier 5:value
|
||||
addhl -group kak-highlight regex (?<=\<regex)\h+(\S+) 1:string
|
||||
addhl -group kak-highlight regex (["'])(?:\\\1|.)*?\1 0:string
|
||||
addhl -group kak-highlight regex (^|\h)\#[^\n]*\n 0:comment
|
||||
|
|
Loading…
Reference in New Issue
Block a user