diff --git a/rc/asciidoc.kak b/rc/asciidoc.kak index 4a9becfc..7dbc6863 100644 --- a/rc/asciidoc.kak +++ b/rc/asciidoc.kak @@ -1,13 +1,13 @@ hook global BufCreate .*\.asciidoc %{ set buffer filetype asciidoc } -defhl asciidoc -addhl -def-group asciidoc regex (\A|\n\n)[^\n]+\n={2,}\h*\n\h*$ 0:blue -addhl -def-group asciidoc regex (\A|\n\n)[^\n]+\n-{2,}\h*\n\h*$ 0:cyan -addhl -def-group asciidoc regex ^\h+([-\*])\h+[^\n]*(\n\h+[^-\*]\S+[^\n]*)*$ 0:yellow 1:cyan -addhl -def-group asciidoc regex ^([-=~]+)\n[^\n\h].*?\n\1$ 0:magenta -addhl -def-group asciidoc regex (?(class|struct)\`(class|struct)[^{}\n]+(\n)?\s*\{\'ma;" ] ] -defhl cpp - -addhl -def-group cpp multi_region -default code root \ +addhl -group / multi_region -default code cpp \ string %{(?|\<-?\d+[fdiu]?|'((\\.)?|[^'\\])'" 0:value -addhl -def-group cpp/root/code regex "\<(void|int|char|unsigned|float|bool|size_t)\>" 0:type -addhl -def-group cpp/root/code regex "\<(while|for|if|else|do|switch|case|default|goto|break|continue|return|using|try|catch|throw|new|delete|and|or|not|operator|explicit)\>" 0:keyword -addhl -def-group cpp/root/code regex "\<(const|mutable|auto|namespace|inline|static|volatile|class|struct|enum|union|public|protected|private|template|typedef|virtual|friend|extern|typename|override|final)\>" 0:attribute -addhl -def-group cpp/root/code regex "^\h*?#.*?(?|\<-?\d+[fdiu]?|'((\\.)?|[^'\\])'" 0:value +addhl -group /cpp/code regex "\<(void|int|char|unsigned|float|bool|size_t)\>" 0:type +addhl -group /cpp/code regex "\<(while|for|if|else|do|switch|case|default|goto|break|continue|return|using|try|catch|throw|new|delete|and|or|not|operator|explicit)\>" 0:keyword +addhl -group /cpp/code regex "\<(const|mutable|auto|namespace|inline|static|volatile|class|struct|enum|union|public|protected|private|template|typedef|virtual|friend|extern|typename|override|final)\>" 0:attribute +addhl -group /cpp/code regex "^\h*?#.*?(? jump } -hook global WinSetOption filetype=(?!grep).* %{ rmhl grep-highlight; rmhooks buffer grep-hooks } +hook global WinSetOption filetype=(?!grep).* %{ rmhl grep; rmhooks buffer grep-hooks } decl str jumpclient diff --git a/rc/kakrc.kak b/rc/kakrc.kak index 3e95c5ad..fdfd86a3 100644 --- a/rc/kakrc.kak +++ b/rc/kakrc.kak @@ -2,23 +2,22 @@ hook global BufCreate (.*/)?(kakrc|.*.kak) %{ set buffer filetype kak } -defhl kakrc -addhl -def-group kakrc multi_region -default kakrc root \ - comment (^|\h)\K\# \n '' \ +addhl -group / multi_region -default code kakrc \ + comment (^|\h)\K\# $ '' \ double_string %{(^|\h)"} %{(? 0:keyword -addhl -def-group kakrc/root/kakrc regex \<(default|black|red|green|yellow|blue|magenta|cyan|white)\> 0:value -addhl -def-group kakrc/root/kakrc regex (?<=\ 0:keyword +addhl -group /kakrc/code regex \<(default|black|red|green|yellow|blue|magenta|cyan|white)\> 0:value +addhl -group /kakrc/code regex (?<=\]+@.*?> 0:string -addhl -def-group mail regex ^>.*?$ 0:comment +addhl -group / group mail +addhl -group /mail regex ^(From|To|Cc|Bcc|Subject|Reply-To|In-Reply-To):([^\n]*(?:\n\h+[^\n]+)*)$ 1:keyword 2:attribute +addhl -group /mail regex <[^@>]+@.*?> 0:string +addhl -group /mail regex ^>.*?$ 0:comment hook global WinSetOption filetype=mail %{ addhl ref mail } hook global WinSetOption filetype=(?!mail).* %{ rmhl mail } diff --git a/rc/make.kak b/rc/make.kak index c020a4e0..98fb4aff 100644 --- a/rc/make.kak +++ b/rc/make.kak @@ -13,8 +13,8 @@ def -shell-params make %{ %sh{ }" }} -defhl make -addhl -def-group make regex "^([^:\n]+):(\d+):(\d+):\h+(?:((?:fatal )?error)|(warning)|(note)|(required from(?: here)?))?.*?$" 1:cyan 2:green 3:green 4:red 5:yellow 6:blue 7:yellow +addhl -group / group make +addhl -group /make regex "^([^:\n]+):(\d+):(\d+):\h+(?:((?:fatal )?error)|(warning)|(note)|(required from(?: here)?))?.*?$" 1:cyan 2:green 3:green 4:red 5:yellow 6:blue 7:yellow hook global WinSetOption filetype=make %{ addhl ref make diff --git a/rc/sh.kak b/rc/sh.kak index af3eb26d..412d3d33 100644 --- a/rc/sh.kak +++ b/rc/sh.kak @@ -6,14 +6,21 @@ hook global BufSetOption mimetype=text/x-shellscript %{ set buffer filetype sh } -defhl sh -addhl -def-group sh regex \<(if|then|fi|while|for|do|done|case|esac|echo|cd|shift|return|exit|local)\> 0:keyword -addhl -def-group sh regex [\[\]\(\)&|]{2} 0:operator -addhl -def-group sh regex (\w+)= 1:identifier -addhl -def-group sh regex ^\h*(\w+)\h*\(\) 1:identifier -addhl -def-group sh regex "(^|\h)#.*?$" 0:comment -addhl -def-group sh regex (["'])(?:\\\1|.)*?\1 0:string -addhl -def-group sh regex \$(\w+|\{.+?\}) 0:identifier +addhl -group / group sh +addhl -group /sh regex \<(if|then|fi|while|for|do|done|case|esac|echo|cd|shift|return|exit|local)\> 0:keyword +addhl -group /sh regex [\[\]\(\)&|]{2} 0:operator +addhl -group /sh regex (\w+)= 1:identifier +addhl -group /sh regex ^\h*(\w+)\h*\(\) 1:identifier +addhl -group /sh regex "(^|\h)#.*?$" 0:comment +#addhl -group /sh regex (["'])(?:\\\1|.)*?\1 0:string + +addhl -group /sh region double_string %{(^|\h)"} %{(?: define a new reusable highlighter", - single_name_param, - CommandFlags::None, - CommandCompleter{}, - [](const ParametersParser& parser, Context& context) - { - const String& name = parser[0]; - DefinedHighlighters::instance().append({name, HighlighterGroup{}}); - } -}; - template CommandCompleter group_rm_completer(GetRootGroup get_root_group) { @@ -401,12 +387,11 @@ HighlighterGroup& get_highlighters(const Context& c) { return c.window().highlig const CommandDesc add_highlighter_cmd = { "addhl", "ah", - "addhl ...: add an highlighter to current window", + "addhl // ...: add an highlighter\n" + " can be shared or window", ParameterDesc{ - SwitchMap{ { "group", { true, "add highlighter to named group" } }, - { "def-group", { true, "add highlighter to reusable defined group" } } }, - ParameterDesc::Flags::SwitchesOnlyAtStart, 1 - }, + SwitchMap{ { "group", { true, "specify the group in which to put the highlighter" } } }, + ParameterDesc::Flags::SwitchesOnlyAtStart, 1 }, CommandFlags::None, group_add_completer(get_highlighters), [](const ParametersParser& parser, Context& context) @@ -414,26 +399,31 @@ const CommandDesc add_highlighter_cmd = { HighlighterRegistry& registry = HighlighterRegistry::instance(); auto begin = parser.begin(); - const String& name = *begin; + const String& name = *begin++; std::vector highlighter_params; - for (++begin; begin != parser.end(); ++begin) + for (; begin != parser.end(); ++begin) highlighter_params.push_back(*begin); - if (parser.has_option("group") and parser.has_option("def-group")) - throw runtime_error("-group and -def-group cannot be specified together"); - HighlighterGroup* group = nullptr; - - if (parser.has_option("def-group")) - group = &DefinedHighlighters::instance().get_group(parser.option_value("def-group"), '/'); - else + if (parser.has_option("group")) { - HighlighterGroup& window_hl = context.window().highlighters(); - group = parser.has_option("group") ? - &window_hl.get_group(parser.option_value("group"), '/') - : &window_hl; - } + StringView path = parser.option_value("group"); + if (path.empty()) + throw runtime_error("group param should not be empty"); + if (path[0] == '/') + { + group = &DefinedHighlighters::instance(); + path = path.substr(1_byte); + } + else + group = &context.window().highlighters(); + + if (not path.empty()) + group = &group->get_group(path, '/'); + } + else + group = &context.window().highlighters(); group->append(registry[name](highlighter_params)); } }; @@ -1333,7 +1323,6 @@ void register_commands() register_command(cm, delbuf_cmd); register_command(cm, force_delbuf_cmd); register_command(cm, namebuf_cmd); - register_command(cm, define_highlighter_cmd); register_command(cm, add_highlighter_cmd); register_command(cm, rm_highlighter_cmd); register_command(cm, add_hook_cmd); diff --git a/src/highlighter_group.cc b/src/highlighter_group.cc index 5f65cbdd..01bf090c 100644 --- a/src/highlighter_group.cc +++ b/src/highlighter_group.cc @@ -3,7 +3,7 @@ namespace Kakoune { -void HighlighterGroup::operator()(const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer) +void HighlighterGroup::operator()(const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer) const { for (auto& hl : m_highlighters) hl.second(context, flags, display_buffer); @@ -44,6 +44,23 @@ HighlighterGroup& HighlighterGroup::get_group(StringView path, Codepoint path_se throw group_not_found("not a group: "_str + id); } +HighlighterFunc HighlighterGroup::get_highlighter(StringView path, Codepoint path_separator) const +{ + auto sep_it = std::find(path.begin(), path.end(), path_separator); + StringView id(path.begin(), sep_it); + auto it = m_highlighters.find(id); + if (it == m_highlighters.end()) + throw group_not_found("no such id: "_str + id); + if (sep_it == path.end()) + return HighlighterFunc{std::ref(it->second)}; + else if (auto* group = it->second.target()) + return group->get_highlighter({sep_it+1, path.end()}, path_separator); + else if (auto* hier_group = it->second.target()) + return hier_group->get_highlighter({sep_it+1, path.end()}, path_separator); + else + throw group_not_found("not a group: "_str + id); +} + CandidateList HighlighterGroup::complete_id(StringView prefix, ByteCount cursor_pos) const { return m_highlighters.complete_id(prefix, cursor_pos); @@ -70,4 +87,17 @@ HighlighterGroup& HierachicalHighlighter::get_group(StringView path, Codepoint p return it->second; } +HighlighterFunc HierachicalHighlighter::get_highlighter(StringView path, Codepoint path_separator) const +{ + auto sep_it = std::find(path.begin(), path.end(), path_separator); + StringView id(path.begin(), sep_it); + auto it = m_groups.find(id); + if (it == m_groups.end()) + throw group_not_found("no such id: "_str + id); + if (sep_it != path.end()) + return it->second.get_highlighter(StringView(sep_it+1, path.end()), path_separator); + else + return HighlighterFunc(std::ref(it->second)); +} + } diff --git a/src/highlighter_group.hh b/src/highlighter_group.hh index 14419b49..0b01d29b 100644 --- a/src/highlighter_group.hh +++ b/src/highlighter_group.hh @@ -19,12 +19,13 @@ class HighlighterGroup public: void operator()(const Context& context, HighlightFlags flags, - DisplayBuffer& display_buffer); + DisplayBuffer& display_buffer) const; void append(HighlighterAndId&& hl); void remove(StringView id); HighlighterGroup& get_group(StringView path, Codepoint path_separator = 0); + HighlighterFunc get_highlighter(StringView path, Codepoint path_separator = 0) const; CandidateList complete_id(StringView prefix, ByteCount cursor_pos) const; CandidateList complete_group_id(StringView prefix, ByteCount cursor_pos) const; @@ -53,6 +54,7 @@ public: } HighlighterGroup& get_group(StringView path, Codepoint path_separator = 0); + HighlighterFunc get_highlighter(StringView path, Codepoint path_separator = 0) const; protected: Callback m_callback; diff --git a/src/highlighters.cc b/src/highlighters.cc index 2bebd6a9..62630188 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -655,17 +655,17 @@ HighlighterAndId reference_factory(HighlighterParameters params) // throw if not found //DefinedHighlighters::instance().get_group(name, '/'); - return HighlighterAndId(name, - [name](const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer) - { - try - { - DefinedHighlighters::instance().get_group(name, '/')(context, flags, display_buffer); - } - catch (group_not_found&) - { - } - }); + return {name, + [name](const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer) + { + try + { + DefinedHighlighters::instance().get_highlighter(name, '/')(context, flags, display_buffer); + } + catch (group_not_found&) + { + } + }}; } namespace RegionHighlight