kakoune/rc/filetype/markdown.kak

131 lines
5.6 KiB
Plaintext
Raw Normal View History

2014-07-14 22:51:33 +02:00
# http://daringfireball.net/projects/markdown
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
# Detection
# ‾‾‾‾‾‾‾‾‾
hook global BufCreate .*[.](markdown|md|mkd) %{
set-option buffer filetype markdown
2014-07-14 22:51:33 +02:00
}
# Initialization
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾
hook global WinSetOption filetype=markdown %{
require-module markdown
hook window ModeChange pop:insert:.* -group markdown-trim-indent markdown-trim-indent
2021-04-02 02:18:11 +02:00
hook window InsertChar \n -group markdown-insert markdown-insert-on-new-line
hook window InsertChar \n -group markdown-indent markdown-indent-on-new-line
hook -once -always window WinSetOption filetype=.* %{ remove-hooks window markdown-.+ }
}
hook -group markdown-load-languages global WinSetOption filetype=markdown %{
rc markdown: only add language highlighters for actual code blocks in buffer 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.)
2022-08-16 19:47:23 +02:00
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}
}
hook -group markdown-highlight global WinSetOption filetype=markdown %{
add-highlighter window/markdown ref markdown
hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/markdown }
}
provide-module markdown %{
2014-07-14 22:51:33 +02:00
# Highlighters
# ‾‾‾‾‾‾‾‾‾‾‾‾
add-highlighter shared/markdown regions
2018-11-08 18:44:03 +01:00
add-highlighter shared/markdown/inline default-region regions
add-highlighter shared/markdown/inline/text default-region group
add-highlighter shared/markdown/listblock region ^\h*[-*]\s ^(?=\S) regions
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
add-highlighter shared/markdown/codeblock region -match-capture \
^(\h*)```\h* \
^(\h*)```\h*$ \
rc markdown: only add language highlighters for actual code blocks in buffer 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.)
2022-08-16 19:47:23 +02:00
regions
add-highlighter shared/markdown/codeblock/ default-region fill meta
add-highlighter shared/markdown/listblock/codeblock region -match-capture \
^(\h*)```\h* \
^(\h*)```\h*$ \
rc markdown: only add language highlighters for actual code blocks in buffer 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.)
2022-08-16 19:47:23 +02:00
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
add-highlighter shared/markdown/angle_bracket_url region (?<=<)([a-z]+://|(mailto|magnet|xmpp):) (?!\\).(?=>)|\n fill link
add-highlighter shared/markdown/inline/url region -recurse \( (\b[a-z]+://|(mailto|magnet|xmpp):) (?!\\).(?=\))|\s fill link
add-highlighter shared/markdown/listblock/angle_bracket_url region (?<=<)(\b[a-z]+://|(mailto|magnet|xmpp):) (?!\\).(?=>)|\n fill link
2018-11-08 18:44:03 +01:00
2021-01-05 19:09:33 +01:00
try %{
require-module html
add-highlighter shared/markdown/inline/tag region (?i)</?[a-z][a-z0-9-]*\s*([a-z_:]|(?=>)) > ref html/tag
2021-01-05 19:09:33 +01:00
}
2018-11-08 18:44:03 +01:00
add-highlighter shared/markdown/inline/code region -match-capture (`+) (`+) fill mono
2014-07-14 22:51:33 +02:00
# Setext-style header
add-highlighter shared/markdown/inline/text/ regex (\A|^\n)[^\n]+\n={2,}\h*\n\h*$ 0:title
add-highlighter shared/markdown/inline/text/ regex (\A|^\n)[^\n]+\n-{2,}\h*\n\h*$ 0:header
2014-07-14 22:51:33 +02:00
# Atx-style header
add-highlighter shared/markdown/inline/text/ regex ^#[^\n]* 0:header
2018-11-08 18:44:03 +01:00
add-highlighter shared/markdown/inline/text/ regex (?<!\*)(\*([^\s*]|([^\s*](\n?[^\n*])*[^\s*]))\*)(?!\*) 1:+i
add-highlighter shared/markdown/inline/text/ regex (?<!_)(_([^\s_]|([^\s_](\n?[^\n_])*[^\s_]))_)(?!_) 1:+i
add-highlighter shared/markdown/inline/text/ regex (?<!\*)(\*\*([^\s*]|([^\s*](\n?[^\n*])*[^\s*]))\*\*)(?!\*) 1:+b
add-highlighter shared/markdown/inline/text/ regex (?<!_)(__([^\s_]|([^\s_](\n?[^\n_])*[^\s_]))__)(?!_) 1:+b
2018-11-08 18:44:03 +01:00
add-highlighter shared/markdown/inline/text/ regex ^\h*(>\h*)+ 0:comment
add-highlighter shared/markdown/inline/text/ regex "\H( {2,})$" 1:+r@meta
2014-07-14 22:51:33 +02:00
# Commands
# ‾‾‾‾‾‾‾‾
rc markdown: only add language highlighters for actual code blocks in buffer 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.)
2022-08-16 19:47:23 +02:00
define-command markdown-load-languages -params 1 %{
evaluate-commands -draft %{ try %{
Avoid semantically significant comments in kak files Kakoune's balanced strings require that delimiter characters nested inside them are also paired, so for example in %{ }, each nested { must occur before a corresponding } to balance it out. In general this will automatically be the case for code in common scripting languages, but sometimes regular expressions used for syntax highlighting do end up containing an unbalanced bracket of one type or another. This problem is easily solved because there is a free choice of balanced delimiter characters. However, it can also be worked around by adding a comment which itself contains an unbalanced delimiter character, to 'balance out' the unpaired one in the regular expression. These unbalanced comments are not ideal as the semantic role they perform is easy for a casual reader to overlook. A good example is catch %{ # indent after lines with an unclosed { or ( try %< execute-keys -draft [c[({],[)}] <ret> <a-k> \A[({][^\n]*\n[^\n]*\n?\z <ret> j<a- gt> > # indent after a switch's case/default statements try %[ execute-keys -draft kx <a-k> ^\h*(case|default).*:$ <ret> j<a-gt> ] # deindent closing brace(s) when after cursor try %[ execute-keys -draft x <a-k> ^\h*[})] <ret> gh / [})] <ret> m <a-S> 1<a-&> ] } in rc/filetype/go/kak. Here, it is not instantly obvious that the comment containing an unmatched { is required for correctness. If you change the comment, delete it or rearrange the contents of the catch block, go.kak will fail to load, and if you cut-and-paste this code as the basis for a new filetype, it is a loaded gun pointing at your feet. Luckily, a careful audit of the standard kakoune library turned up only three such instances, in go.kak, hare.kak and markdown.kak. The examples in go.kak and hare.kak are easily made robust by replacing a %{ } with %< > or %[ ] respectively. The example in markdown.kak is least-intrusively fixed by rewriting the affected regular expression slightly so it has balanced { and } anyway.
2023-12-13 17:40:48 +01:00
execute-keys "%arg{1}1s```\h*\{?[.=]?(\w+)\}?<ret>"
rc markdown: only add language highlighters for actual code blocks in buffer 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.)
2022-08-16 19:47:23 +02:00
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
# remove trailing white spaces
try %{ execute-keys -draft s \h + $ <ret> d }
}
}
2021-04-02 02:18:11 +02:00
define-command -hidden markdown-insert-on-new-line %{
try %{ execute-keys -draft -itersel k x s ^\h*\K((>\h*)+([*+-]\h)?|(>\h*)*[*+-]\h)\h* <ret> y gh j P }
2021-04-02 02:18:11 +02:00
}
define-command -hidden markdown-indent-on-new-line %{
evaluate-commands -draft -itersel %{
2014-07-14 22:51:33 +02:00
# preserve previous line indent
try %{ execute-keys -draft <semicolon> K <a-&> }
# remove trailing white spaces
try %{ execute-keys -draft k x s \h+$ <ret> d }
2014-07-14 22:51:33 +02:00
}
}
}