From 5b9d30c088108e7c3a85dfe1c2e6a2ad2eee23aa Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Sat, 12 Dec 2015 06:50:58 +0000 Subject: [PATCH] Optimize the dynregex case where the expression refers directly to a regex option --- src/command_manager.cc | 123 +++++++++++++++-------------------------- src/command_manager.hh | 38 +++++++++++++ src/highlighters.cc | 11 ++++ 3 files changed, 93 insertions(+), 79 deletions(-) diff --git a/src/command_manager.cc b/src/command_manager.cc index d5ccdeb7..8dfb5181 100644 --- a/src/command_manager.cc +++ b/src/command_manager.cc @@ -43,41 +43,6 @@ struct parse_error : runtime_error namespace { -struct Token -{ - enum class Type - { - Raw, - RawQuoted, - RawEval, - ShellExpand, - RegisterExpand, - OptionExpand, - ValExpand, - ArgExpand, - CommandSeparator - }; - Token() : m_type(Type::Raw) {} - - Token(Type type, ByteCount b, ByteCount e, CharCoord coord, String str = "") - : m_type(type), m_begin(b), m_end(e), m_coord(coord), m_content(std::move(str)) {} - - Type type() const { return m_type; } - ByteCount begin() const { return m_begin; } - ByteCount end() const { return m_end; } - CharCoord coord() const { return m_coord; } - const String& content() const { return m_content; } - -private: - Type m_type; - ByteCount m_begin; - ByteCount m_end; - CharCoord m_coord; - String m_content; -}; - -using TokenList = Vector; - struct Reader { public: @@ -278,6 +243,50 @@ Token parse_percent_token(Reader& reader) } } +String expand_token(const Token& token, const Context& context, + const ShellContext& shell_context) +{ + auto& content = token.content(); + switch (token.type()) + { + case Token::Type::ShellExpand: + return ShellManager::instance().eval(content, context, {}, + ShellManager::Flags::WaitForStdout, + shell_context).first; + case Token::Type::RegisterExpand: + return context.main_sel_register_value(content).str(); + case Token::Type::OptionExpand: + return context.options()[content].get_as_string(); + case Token::Type::ValExpand: + { + auto it = shell_context.env_vars.find(content); + if (it != shell_context.env_vars.end()) + return it->value; + return ShellManager::instance().get_val(content, context); + } + case Token::Type::ArgExpand: + { + auto& params = shell_context.params; + if (content == '@') + return join(params, ' '); + + const int arg = str_to_int(content)-1; + if (arg < 0) + throw runtime_error("invalid argument index"); + return arg < params.size() ? params[arg] : String{}; + } + case Token::Type::RawEval: + return expand(content, context, shell_context); + case Token::Type::Raw: + case Token::Type::RawQuoted: + return content; + default: kak_assert(false); + } + return {}; +} + +} + template TokenList parse(StringView line) { @@ -325,50 +334,6 @@ TokenList parse(StringView line) return result; } -String expand_token(const Token& token, const Context& context, - const ShellContext& shell_context) -{ - auto& content = token.content(); - switch (token.type()) - { - case Token::Type::ShellExpand: - return ShellManager::instance().eval(content, context, {}, - ShellManager::Flags::WaitForStdout, - shell_context).first; - case Token::Type::RegisterExpand: - return context.main_sel_register_value(content).str(); - case Token::Type::OptionExpand: - return context.options()[content].get_as_string(); - case Token::Type::ValExpand: - { - auto it = shell_context.env_vars.find(content); - if (it != shell_context.env_vars.end()) - return it->value; - return ShellManager::instance().get_val(content, context); - } - case Token::Type::ArgExpand: - { - auto& params = shell_context.params; - if (content == '@') - return join(params, ' '); - - const int arg = str_to_int(content)-1; - if (arg < 0) - throw runtime_error("invalid argument index"); - return arg < params.size() ? params[arg] : String{}; - } - case Token::Type::RawEval: - return expand(content, context, shell_context); - case Token::Type::Raw: - case Token::Type::RawQuoted: - return content; - default: kak_assert(false); - } - return {}; -} - -} - String expand(StringView str, const Context& context, const ShellContext& shell_context) { diff --git a/src/command_manager.hh b/src/command_manager.hh index 2251e8b7..dbc87e81 100644 --- a/src/command_manager.hh +++ b/src/command_manager.hh @@ -61,6 +61,44 @@ private: using CommandInfo = std::pair; +struct Token +{ + enum class Type + { + Raw, + RawQuoted, + RawEval, + ShellExpand, + RegisterExpand, + OptionExpand, + ValExpand, + ArgExpand, + CommandSeparator + }; + Token() : m_type(Type::Raw) {} + + Token(Type type, ByteCount b, ByteCount e, CharCoord coord, String str = "") + : m_type(type), m_begin(b), m_end(e), m_coord(coord), m_content(std::move(str)) {} + + Type type() const { return m_type; } + ByteCount begin() const { return m_begin; } + ByteCount end() const { return m_end; } + CharCoord coord() const { return m_coord; } + const String& content() const { return m_content; } + +private: + Type m_type; + ByteCount m_begin; + ByteCount m_end; + CharCoord m_coord; + String m_content; +}; + +using TokenList = Vector; + +template +TokenList parse(StringView line); + class CommandManager : public Singleton { public: diff --git a/src/highlighters.cc b/src/highlighters.cc index 5708801d..68f0bdb5 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -449,6 +449,17 @@ HighlighterAndId create_dynamic_regex_highlighter(HighlighterParameters params) auto get_face = [faces](const Context& context){ return faces;; }; String expr = params[0]; + auto tokens = parse(expr); + if (tokens.size() == 1 and tokens[0].type() == Token::Type::OptionExpand and + GlobalScope::instance().options()[tokens[0].content()].is_of_type()) + { + String option_name = tokens[0].content(); + auto get_regex = [option_name](const Context& context) { + return context.options()[option_name].get(); + }; + return {format("dynregex_{}", expr), make_dynamic_regex_highlighter(get_regex, get_face)}; + } + auto get_regex = [expr](const Context& context){ try {