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
|
given flag in it for everly lines contained in the int-list option named
|
||||||
<option_name>.
|
<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
|
Hooks
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
|
|
@ -982,14 +982,11 @@ private:
|
||||||
|
|
||||||
void insert(Codepoint key)
|
void insert(Codepoint key)
|
||||||
{
|
{
|
||||||
|
auto str = codepoint_to_str(key);
|
||||||
auto& buffer = m_edition.editor().buffer();
|
auto& buffer = m_edition.editor().buffer();
|
||||||
for (auto& sel : m_edition.editor().m_selections)
|
for (auto& sel : m_edition.editor().selections())
|
||||||
{
|
buffer.insert(buffer.iterator_at(sel.last()), str);
|
||||||
auto content = codepoint_to_str(key);
|
context().hooks().run_hook("InsertKey", str, context());
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepare(InsertMode mode)
|
void prepare(InsertMode mode)
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "debug.hh"
|
#include "debug.hh"
|
||||||
#include "event_manager.hh"
|
#include "event_manager.hh"
|
||||||
#include "file.hh"
|
#include "file.hh"
|
||||||
#include "filter.hh"
|
|
||||||
#include "highlighter.hh"
|
#include "highlighter.hh"
|
||||||
#include "highlighters.hh"
|
#include "highlighters.hh"
|
||||||
#include "client.hh"
|
#include "client.hh"
|
||||||
|
@ -283,39 +282,6 @@ void rm_highlighter(CommandParameters params, Context& context)
|
||||||
group.remove(parser[0]);
|
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)
|
static HookManager& get_hook_manager(const String& scope, Context& context)
|
||||||
{
|
{
|
||||||
if (prefix_match("global", scope))
|
if (prefix_match("global", scope))
|
||||||
|
@ -838,11 +804,8 @@ void register_commands()
|
||||||
cm.register_commands({"nb", "namebuf"}, set_buffer_name);
|
cm.register_commands({"nb", "namebuf"}, set_buffer_name);
|
||||||
|
|
||||||
auto get_highlighters = [](const Context& c) -> HighlighterGroup& { return c.window().highlighters(); };
|
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({ "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({ "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("hook", add_hook);
|
||||||
cm.register_command("rmhooks", rm_hooks);
|
cm.register_command("rmhooks", rm_hooks);
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#include "buffer.hh"
|
#include "buffer.hh"
|
||||||
#include "dynamic_selection_list.hh"
|
#include "dynamic_selection_list.hh"
|
||||||
#include "filter.hh"
|
|
||||||
#include "memoryview.hh"
|
#include "memoryview.hh"
|
||||||
|
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
|
@ -82,11 +81,6 @@ public:
|
||||||
bool undo();
|
bool undo();
|
||||||
bool redo();
|
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; }
|
bool is_editing() const { return m_edition_level!= 0; }
|
||||||
private:
|
private:
|
||||||
friend struct scoped_edition;
|
friend struct scoped_edition;
|
||||||
|
@ -104,7 +98,6 @@ private:
|
||||||
safe_ptr<Buffer> m_buffer;
|
safe_ptr<Buffer> m_buffer;
|
||||||
DynamicSelectionList m_selections;
|
DynamicSelectionList m_selections;
|
||||||
size_t m_main_sel;
|
size_t m_main_sel;
|
||||||
FilterGroup m_filters;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct scoped_edition
|
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 "debug.hh"
|
||||||
#include "event_manager.hh"
|
#include "event_manager.hh"
|
||||||
#include "file.hh"
|
#include "file.hh"
|
||||||
#include "filters.hh"
|
|
||||||
#include "highlighters.hh"
|
#include "highlighters.hh"
|
||||||
#include "hook_manager.hh"
|
#include "hook_manager.hh"
|
||||||
#include "ncurses.hh"
|
#include "ncurses.hh"
|
||||||
|
@ -271,7 +270,6 @@ int kakoune(memoryview<String> params)
|
||||||
BufferManager buffer_manager;
|
BufferManager buffer_manager;
|
||||||
RegisterManager register_manager;
|
RegisterManager register_manager;
|
||||||
HighlighterRegistry highlighter_registry;
|
HighlighterRegistry highlighter_registry;
|
||||||
FilterRegistry filter_registry;
|
|
||||||
ColorRegistry color_registry;
|
ColorRegistry color_registry;
|
||||||
ClientManager client_manager;
|
ClientManager client_manager;
|
||||||
|
|
||||||
|
@ -281,7 +279,6 @@ int kakoune(memoryview<String> params)
|
||||||
register_registers();
|
register_registers();
|
||||||
register_commands();
|
register_commands();
|
||||||
register_highlighters();
|
register_highlighters();
|
||||||
register_filters();
|
|
||||||
|
|
||||||
write_debug("*** This is the debug buffer, where debug info will be written ***");
|
write_debug("*** This is the debug buffer, where debug info will be written ***");
|
||||||
write_debug("pid: " + to_string(getpid()));
|
write_debug("pid: " + to_string(getpid()));
|
||||||
|
|
|
@ -4,10 +4,10 @@ hook global BufCreate (.*/)?(kakrc|.*.kak) %{
|
||||||
|
|
||||||
hook global WinSetOption filetype=kak %{
|
hook global WinSetOption filetype=kak %{
|
||||||
addhl group kak-highlight
|
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 \<(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 (?<=\<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 (?<=\<regex)\h+(\S+) 1:string
|
||||||
addhl -group kak-highlight regex (["'])(?:\\\1|.)*?\1 0:string
|
addhl -group kak-highlight regex (["'])(?:\\\1|.)*?\1 0:string
|
||||||
addhl -group kak-highlight regex (^|\h)\#[^\n]*\n 0:comment
|
addhl -group kak-highlight regex (^|\h)\#[^\n]*\n 0:comment
|
||||||
|
|
Loading…
Reference in New Issue
Block a user