From 647e568d3b24936fae20af245b283755a712d62a Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Tue, 16 Aug 2022 19:14:05 +0200 Subject: [PATCH 1/3] rc kakrc: add kak=kakrc highlighter alias for markdown/restructuredtext Filetypes markdown and restructuredtext reuse highlighters from other filetypes to highlight code blocks. For example, to highlight a code block of language foo they essentially do require-module foo add-highlighter [...] ref foo This works great if the module name matches the shared highlighter. This is the case almost all scripts in rc/filetype*. The only exception is kakrc.kak: the highlighter is named "kakrc" (just like the filetype) but the module is named "kak". This requires weird hacks in markdown/restructuredtext. Ideally we could remove this inconsistency by renaming both the filetype and the highlighter to "kak" but that's a breaking change. Until we do that, let's add an alias so we can treat filetypes uniformly. This helps the following commits, which otherwise would need to add ugly extra code for kakrc highlighters. The following commit will generalize this approach, allowing users to add arbitrary aliases. --- rc/filetype/kakrc.kak | 2 ++ rc/filetype/markdown.kak | 5 ++--- rc/filetype/restructuredtext.kak | 3 +-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rc/filetype/kakrc.kak b/rc/filetype/kakrc.kak index 65ef2bdc..32080b6e 100644 --- a/rc/filetype/kakrc.kak +++ b/rc/filetype/kakrc.kak @@ -90,6 +90,8 @@ add-highlighter shared/kakrc/double_string/escape regex '""' 0:default+b add-highlighter shared/kakrc/single_string/fill fill string add-highlighter shared/kakrc/single_string/escape regex "''" 0:default+b +add-highlighter shared/kak ref kakrc + # Commands # ‾‾‾‾‾‾‾‾ diff --git a/rc/filetype/markdown.kak b/rc/filetype/markdown.kak index 599dfd5d..abd73481 100644 --- a/rc/filetype/markdown.kak +++ b/rc/filetype/markdown.kak @@ -54,13 +54,12 @@ evaluate-commands %sh{ ruby rust sass scala scss sh swift toml tupfile typescript yaml sql " for lang in ${languages}; do - [ "${lang}" = kak ] && ref=kakrc || ref="${lang}" printf 'add-highlighter shared/markdown/%s region -match-capture ^(\h*)```\h*(%s\\b|\\{[.=]?%s\\}) ^(\h*)``` regions\n' "${lang}" "${lang}" "${lang}" printf 'add-highlighter shared/markdown/%s/ default-region fill meta\n' "${lang}" - printf 'add-highlighter shared/markdown/%s/inner region \A\h*```[^\\n]*\K (?=```) ref %s\n' "${lang}" "${ref}" + printf 'add-highlighter shared/markdown/%s/inner region \A\h*```[^\\n]*\K (?=```) ref %s\n' "${lang}" "${lang}" printf 'add-highlighter shared/markdown/listblock/%s region -match-capture ^(\h*)```\h*(%s\\b|\\{[.=]?%s\\}) ^(\h*)``` regions\n' "${lang}" "${lang}" "${lang}" printf 'add-highlighter shared/markdown/listblock/%s/ default-region fill meta\n' "${lang}" - printf 'add-highlighter shared/markdown/listblock/%s/inner region \A\h*```[^\\n]*\K (?=```) ref %s\n' "${lang}" "${ref}" + printf 'add-highlighter shared/markdown/listblock/%s/inner region \A\h*```[^\\n]*\K (?=```) ref %s\n' "${lang}" "${lang}" done } diff --git a/rc/filetype/restructuredtext.kak b/rc/filetype/restructuredtext.kak index b1a69806..90c61f40 100644 --- a/rc/filetype/restructuredtext.kak +++ b/rc/filetype/restructuredtext.kak @@ -32,8 +32,7 @@ evaluate-commands %sh{ julia kak kickstart latex lisp lua makefile moon objc \ perl pug python ragel ruby rust sass scala scss sh swift \ tupfile yaml; do - if [ "$ft" = kak ]; then ref="kakrc"; else ref="$ft"; fi - printf 'add-highlighter shared/restructuredtext/%s region %s %s ref %s\n' "$ft" "\.\.\h*code-block::\h*$ft\h*\n" '^(?=\S)' "$ref" + printf 'add-highlighter shared/restructuredtext/%s region %s %s ref %s\n' "$ft" "\.\.\h*code-block::\h*$ft\h*\n" '^(?=\S)' "$ft" done } From 907ad84f46447e1c73fcd80c6a020a50b9ea2266 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Tue, 16 Aug 2022 19:47:23 +0200 Subject: [PATCH 2/3] rc markdown: only add language highlighters for actual code blocks in buffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There have been proposals to add more language aliases to markdown.kak (#4592) and allow users to add their own aliases (#4489). To recap: various markdown implementations allow specifying aliases for languages. For example, here is a code block that should be highlighted as filetype "haskell" but isn't: ```hs -- highlight as haskell ``` There are lots of aliases out in the wild - "pygmentize -L" lists some but I don't think there is a canonical list. Today we have a hardcoded list of supported filetypes. This is hard to mainta, extend, and it can impact performance. This patch simply attempts to load the module "hs" and the shared highlighter "hs". This means that users can use this (obvious?) snippet to add their own aliases: provide-module hs %{ require-module haskell add-highlighter shared/hs ref haskell } Untrusted Markdown files can load arbitrary modules, but that was already true before, and modules are assumed to be trusted anyway. Since language highlighters are now loaded *after* the generic code-block highlighter, we need to make sure the language highlighters take precedence. Do this by making them sub-regions of the generic one. Closes #4489 This improves performance on the [5MB Markdown file](https://github.com/mawww/kakoune/issues/4685#issuecomment-1208129806). $ HOME=$PWD hyperfine -w 1 'git checkout HEAD'{~,}' -- :/rc/filetype/markdown.kak && ./kak.opt big_markdown.md -e "hook global NormalIdle .* quit" -ui dummy' Benchmark 1: git checkout HEAD~ -- :/rc/filetype/markdown.kak && ./kak.opt big_markdown.md -e "hook global NormalIdle .* quit" -ui dummy Time (mean ± σ): 3.225 s ± 0.074 s [User: 3.199 s, System: 0.027 s] Range (min … max): 3.099 s … 3.362 s 10 runs Benchmark 2: git checkout HEAD -- :/rc/filetype/markdown.kak && ./kak.opt big_markdown.md -e "hook global NormalIdle .* quit" -ui dummy Time (mean ± σ): 1.181 s ± 0.030 s [User: 1.162 s, System: 0.021 s] Range (min … max): 1.149 s … 1.234 s 10 runs Summary 'git checkout HEAD -- :/rc/filetype/markdown.kak && ./kak.opt big_markdown.md -e "hook global NormalIdle .* quit" -ui dummy' ran 2.73 ± 0.09 times faster than 'git checkout HEAD~ -- :/rc/filetype/markdown.kak && ./kak.opt big_markdown.md -e "hook global NormalIdle .* quit" -ui dummy' (These numbers depend on another optimization.) --- rc/filetype/markdown.kak | 53 +++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/rc/filetype/markdown.kak b/rc/filetype/markdown.kak index abd73481..f201770a 100644 --- a/rc/filetype/markdown.kak +++ b/rc/filetype/markdown.kak @@ -21,8 +21,12 @@ hook global WinSetOption filetype=markdown %{ } hook -group markdown-load-languages global WinSetOption filetype=markdown %{ - hook -group markdown-load-languages window NormalIdle .* markdown-load-languages - hook -group markdown-load-languages window InsertIdle .* markdown-load-languages + markdown-load-languages '%' +} + +hook -group markdown-load-languages global WinSetOption filetype=markdown %{ + hook -group markdown-load-languages window NormalIdle .* %{markdown-load-languages gtGbGl} + hook -group markdown-load-languages window InsertIdle .* %{markdown-load-languages gtGbGl} } @@ -46,31 +50,16 @@ add-highlighter shared/markdown/listblock/g default-region group add-highlighter shared/markdown/listblock/g/ ref markdown/inline add-highlighter shared/markdown/listblock/g/marker regex ^\h*([-*])\s 1:bullet -evaluate-commands %sh{ - languages=" - awk c cabal clojure coffee cpp crystal css cucumber d diff dockerfile elixir erlang fish - gas go haml haskell html ini java javascript json julia kak kickstart - latex lisp lua makefile markdown moon objc ocaml perl pug python ragel - ruby rust sass scala scss sh swift toml tupfile typescript yaml sql - " - for lang in ${languages}; do - printf 'add-highlighter shared/markdown/%s region -match-capture ^(\h*)```\h*(%s\\b|\\{[.=]?%s\\}) ^(\h*)``` regions\n' "${lang}" "${lang}" "${lang}" - printf 'add-highlighter shared/markdown/%s/ default-region fill meta\n' "${lang}" - printf 'add-highlighter shared/markdown/%s/inner region \A\h*```[^\\n]*\K (?=```) ref %s\n' "${lang}" "${lang}" - printf 'add-highlighter shared/markdown/listblock/%s region -match-capture ^(\h*)```\h*(%s\\b|\\{[.=]?%s\\}) ^(\h*)``` regions\n' "${lang}" "${lang}" "${lang}" - printf 'add-highlighter shared/markdown/listblock/%s/ default-region fill meta\n' "${lang}" - printf 'add-highlighter shared/markdown/listblock/%s/inner region \A\h*```[^\\n]*\K (?=```) ref %s\n' "${lang}" "${lang}" - done -} - add-highlighter shared/markdown/codeblock region -match-capture \ ^(\h*)```\h* \ ^(\h*)```\h*$ \ - fill meta + regions +add-highlighter shared/markdown/codeblock/ default-region fill meta add-highlighter shared/markdown/listblock/codeblock region -match-capture \ ^(\h*)```\h* \ ^(\h*)```\h*$ \ - fill meta + regions +add-highlighter shared/markdown/listblock/codeblock/ default-region fill meta add-highlighter shared/markdown/codeline region "^( {4}|\t)" "$" fill meta # https://spec.commonmark.org/0.29/#link-destination @@ -102,6 +91,21 @@ add-highlighter shared/markdown/inline/text/ regex "\H( {2,})$" 1:+r@meta # Commands # ‾‾‾‾‾‾‾‾ +define-command markdown-load-languages -params 1 %{ + evaluate-commands -draft %{ try %{ + execute-keys "%arg{1}s```\h*\{?[.=]?\K\w+" # } + evaluate-commands -itersel %{ try %{ + require-module %val{selection} + add-highlighter "shared/markdown/codeblock/%val{selection}" region -match-capture "^(\h*)```\h*(%val{selection}\b|\{[.=]?%val{selection}\})" ^(\h*)``` regions + add-highlighter "shared/markdown/codeblock/%val{selection}/" default-region fill meta + add-highlighter "shared/markdown/codeblock/%val{selection}/inner" region \A\h*```[^\n]*\K (?=```) ref %val{selection} + add-highlighter "shared/markdown/listblock/codeblock/%val{selection}" region -match-capture "^(\h*)```\h*(%val{selection}\b|\{[.=]?%val{selection}\})" ^(\h*)``` regions + add-highlighter "shared/markdown/listblock/codeblock/%val{selection}/" default-region fill meta + add-highlighter "shared/markdown/listblock/codeblock/%val{selection}/inner" region \A\h*```[^\n]*\K (?=```) ref %val{selection} + }} + }} +} + define-command -hidden markdown-trim-indent %{ evaluate-commands -no-hooks -draft -itersel %{ execute-keys x @@ -123,11 +127,4 @@ define-command -hidden markdown-indent-on-new-line %{ } } -define-command -hidden markdown-load-languages %{ - evaluate-commands -draft %{ try %{ - execute-keys 'gtGbGls```\h*\{?[.=]?\K[^}\s]+' - evaluate-commands -itersel %{ try %{ require-module %val{selection} } } - }} -} - } From 9fc62609b1d94e014f32cb46f27826608a859590 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Sat, 13 Aug 2022 23:00:03 +0200 Subject: [PATCH 3/3] rc restructuredtext: only add language highlighters for actual code blocks in buffer Analogous to markdown.kak. --- rc/filetype/restructuredtext.kak | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/rc/filetype/restructuredtext.kak b/rc/filetype/restructuredtext.kak index 90c61f40..7853b301 100644 --- a/rc/filetype/restructuredtext.kak +++ b/rc/filetype/restructuredtext.kak @@ -12,6 +12,15 @@ hook global WinSetOption filetype=restructuredtext %{ require-module restructuredtext } +hook -group restructuredtext-load-languages global WinSetOption filetype=restructuredtext %{ + restructuredtext-load-languages '%' +} + +hook -group restructuredtext-load-languages global WinSetOption filetype=restructuredtext %{ + hook -group restructuredtext-load-languages window NormalIdle .* %{restructuredtext-load-languages gtGbGl} + hook -group restructuredtext-load-languages window InsertIdle .* %{restructuredtext-load-languages gtGbGl} +} + hook -group restructuredtext-highlight global WinSetOption filetype=restructuredtext %{ add-highlighter window/restructuredtext ref restructuredtext hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/restructuredtext } @@ -26,16 +35,6 @@ add-highlighter shared/restructuredtext regions add-highlighter shared/restructuredtext/content default-region group add-highlighter shared/restructuredtext/code region ::\h*\n ^(?=\S) fill meta -evaluate-commands %sh{ - for ft in c cabal clojure coffee cpp css cucumber ddiff dockerfile \ - fish gas go haml haskell html ini java javascript json \ - julia kak kickstart latex lisp lua makefile moon objc \ - perl pug python ragel ruby rust sass scala scss sh swift \ - tupfile yaml; do - printf 'add-highlighter shared/restructuredtext/%s region %s %s ref %s\n' "$ft" "\.\.\h*code-block::\h*$ft\h*\n" '^(?=\S)' "$ft" - done -} - # Setext-style header # Valid header characters: # # ! " $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ @@ -78,4 +77,16 @@ add-highlighter shared/restructuredtext/content/ regex [^*](\*\*([^\s*]|([^\s*][ add-highlighter shared/restructuredtext/content/ regex [^*](\*([^\s*]|([^\s*][^*]*[^\s*]))\*)[^*] 1:+i add-highlighter shared/restructuredtext/content/ regex [^`](``([^\s`]|([^\s`][^`]*[^\s`]))``)[^`] 1:mono +define-command restructuredtext-load-languages -params 1 %{ + evaluate-commands -draft %{ try %{ + execute-keys "%arg{1}s^\.\.\h*code-block::\h*\K\w+" + evaluate-commands -itersel %{ try %{ + require-module %val{selection} + add-highlighter "shared/restructuredtext/%val{selection}" region "\.\.\h*code-block::\h*%val{selection}\h*\n" '^(?=\S)' regions + add-highlighter "shared/restructuredtext/%val{selection}/" default-region fill meta + add-highlighter "shared/restructuredtext/%val{selection}/inner" region \A\.\.\h*code-block::[^\n]*\K '^(?=\S)' ref %val{selection} + }} + }} +} + }