kakoune/rc/filetype/hare.kak

145 lines
6.9 KiB
Plaintext
Raw Normal View History

2022-06-09 03:18:00 +02:00
# detection
hook global BufCreate .*[.]ha %{
set-option buffer filetype hare
}
# initialisation
hook global WinSetOption filetype=hare %{
require-module hare
hook window ModeChange pop:insert:.* -group hare-trim-indent hare-trim-indent
hook window InsertChar \n -group hare-insert hare-insert-on-new-line
hook window InsertChar \n -group hare-indent hare-indent-on-new-line
2022-06-09 10:29:32 +02:00
hook window InsertChar \{ -group hare-indent hare-indent-on-opening-curly-brace
hook window InsertChar \} -group hare-indent hare-indent-on-closing-curly-brace
2022-06-09 03:18:00 +02:00
}
hook -group hare-highlight global WinSetOption filetype=hare %{
add-highlighter window/hare ref hare
hook -once -always window WinSetOption filetype=*. %{ remove-highlighter window/hare }
}
# highlighters
2022-06-09 10:29:32 +02:00
provide-module hare %§
2022-06-09 03:18:00 +02:00
add-highlighter shared/hare regions
add-highlighter shared/hare/code default-region group
add-highlighter shared/hare/comment region // $ fill comment
add-highlighter shared/hare/rawstring region ` ` group
add-highlighter shared/hare/rawstring/ fill string
add-highlighter shared/hare/string region '"' (?<!\\)(\\\\)*" group
add-highlighter shared/hare/string/ fill string
add-highlighter shared/hare/string/ regex '(\\0|\\a|\\b|\\f|\\n|\\r|\\t|\\v|\\\\|\\")' 0:meta
add-highlighter shared/hare/string/ regex "\\'" 0:meta
add-highlighter shared/hare/string/ regex "(\\x[0-9a-fA-F]{2})" 0:meta
add-highlighter shared/hare/string/ regex "(\\u[0-9a-fA-F]{4})" 0:meta
add-highlighter shared/hare/string/ regex "(\\U[0-9a-fA-F]{8})" 0:meta
add-highlighter shared/hare/rune region "'" (?<!\\)(\\\\)*' group
add-highlighter shared/hare/rune/ fill string
add-highlighter shared/hare/rune/ regex "(\\0|\\a|\\b|\\f|\\n|\\r|\\t|\\v|\\\\|\\')" 0:meta
add-highlighter shared/hare/rune/ regex '\\"' 0:meta
add-highlighter shared/hare/rune/ regex "(\\x[0-9a-fA-F]{2})" 0:meta
add-highlighter shared/hare/rune/ regex "(\\u[0-9a-fA-F]{4})" 0:meta
add-highlighter shared/hare/rune/ regex "(\\U[0-9a-fA-F]{8})" 0:meta
# imports
add-highlighter shared/hare/code/ regex "\buse\s.*?(?=;)" 0:module
2022-06-09 03:18:00 +02:00
add-highlighter shared/hare/code/ regex "\buse\b" 0:meta
2022-10-07 08:16:33 +02:00
# functions
2022-10-09 09:19:21 +02:00
add-highlighter shared/hare/code/ regex "\b([0-9a-zA-Z_]*)\h*\(" 1:function
2022-10-07 08:16:33 +02:00
2022-06-09 03:18:00 +02:00
# attributes
add-highlighter shared/hare/code/ regex "@(packed|offset|init|fini|test|noreturn|symbol)\b" 0:attribute
2022-06-09 03:18:00 +02:00
# declarations
add-highlighter shared/hare/code/ regex "\b(let|export|const)\b" 0:meta
add-highlighter shared/hare/code/ regex "\b(fn|type|def)\b" 0:keyword
# builtins
add-highlighter shared/hare/code/ regex "\b(len|offset|free|alloc|assert|append|abort|delete|insert|vastart|vaarg|vaend)\b" 0:builtin
add-highlighter shared/hare/code/ regex "\b(as|is)\b" 0:builtin
# types
add-highlighter shared/hare/code/ regex "\b(struct|union|enum)\b" 0:type
add-highlighter shared/hare/code/ regex "\b(nullable|null|void)\b" 0:type
add-highlighter shared/hare/code/ regex "\b(u8|u16|u32|u64|uint)\b" 0:type
add-highlighter shared/hare/code/ regex "\b(i8|i16|i32|i64|int)\b" 0:type
add-highlighter shared/hare/code/ regex "\b(size|uintptr|char)\b" 0:type
add-highlighter shared/hare/code/ regex "\b(f32|f64)\b" 0:type
add-highlighter shared/hare/code/ regex "\b(str|rune)\b" 0:type
add-highlighter shared/hare/code/ regex "\b(bool)\b" 0:type
add-highlighter shared/hare/code/ regex "\b(valist)\b" 0:type
# literals
add-highlighter shared/hare/code/ regex "\b(true|false)\b" 0:value
add-highlighter shared/hare/code/ regex "\b[0-9]+([eE][-+]?[0-9]+)?(z|(i|u)(8|16|32|64)?)?\b" 0:value
add-highlighter shared/hare/code/ regex "\b[0-9]+([eE][-+]?[0-9]+)?((?=e)|(?=u)|(?=i))" 0:value
add-highlighter shared/hare/code/ regex "\b0b[0-1]+(z|(i|u)(8|16|32|64)?)?\b" 0:value
add-highlighter shared/hare/code/ regex "\b0b[0-1]+((?=u)|(?=i))" 0:value
add-highlighter shared/hare/code/ regex "\b0o[0-7]+(z|(i|u)(8|16|32|64)?)?\b" 0:value
add-highlighter shared/hare/code/ regex "\b0o[0-7]+((?=u)|(?=i))" 0:value
add-highlighter shared/hare/code/ regex "\b0x[0-9a-fA-F]+(z|(i|u)(8|16|32|64)?)?\b" 0:value
add-highlighter shared/hare/code/ regex "\b0x[0-9a-fA-F]+((?=u)|(?=i))" 0:value
# floats
add-highlighter shared/hare/code/ regex "\b[0-9]+\.[0-9]+([eE][-+]?[0-9]+)?(f32|f64)?\b" 0:value
add-highlighter shared/hare/code/ regex "\b[0-9]+\.[0-9]+([eE][-+]?[0-9]+)?((?=e)|(?=f))" 0:value
add-highlighter shared/hare/code/ regex "\b[0-9]+([eE][-+]?[0-9]+)?(f32|f64)\b" 0:value
add-highlighter shared/hare/code/ regex "\b[0-9]+([eE][-+]?[0-9]+)?(?=f)" 0:value
2022-10-07 08:16:33 +02:00
# constants
2022-10-09 09:19:21 +02:00
add-highlighter shared/hare/code/ regex "\b[0-9A-Z_]*\b" 0:value
2022-06-09 03:18:00 +02:00
# control flow
add-highlighter shared/hare/code/ regex "\b(for|if|else|switch|match|return|break|continue|defer|yield|case|static)\b" 0:keyword
2022-10-07 08:16:33 +02:00
# operators
add-highlighter shared/hare/code/ regex "(=|\+|-|\*|/|<|>|!|\?|&|\||\.\.(\.)?)" 0:operator
2022-10-07 08:16:33 +02:00
2022-06-09 03:18:00 +02:00
# commands
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
define-command -hidden hare-indent-on-new-line %[ evaluate-commands -draft -itersel %[
2022-06-09 03:18:00 +02:00
# preserve indentation on new lines
try %{ execute-keys -draft <semicolon> K <a-&> }
2022-06-09 10:29:32 +02:00
# indent after lines ending with { or (
try %[ execute-keys -draft kx <a-k> [{(]\h*$ <ret> j i<tab> ]
2022-06-09 10:29:32 +02:00
# cleanup trailing white spaces on the previous line
2022-06-09 10:38:10 +02:00
execute-keys -draft k :hare-trim-indent <ret>
2022-06-09 10:54:50 +02:00
# indent after match/switch's case statements
try %[ execute-keys -draft kx <a-k> case\h.*=>\h*$ <ret> j<a-gt> ]
2022-06-09 10:29:32 +02:00
# deindent closing brace(s) when after cursor
try %[ execute-keys -draft x <a-k> ^\h*[})] <ret> gh / [})] <ret> m <a-S> 1<a-&> ]
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
] ]
2022-06-09 03:18:00 +02:00
define-command -hidden hare-insert-on-new-line %{ evaluate-commands -draft -itersel %{
try %{ evaluate-commands -draft -save-regs '/"' %{
# copy the comment prefix
execute-keys -save-regs '' k x s ^\h*\K//\h* <ret> y
2022-06-09 03:18:00 +02:00
try %{
# paste the comment prefix
execute-keys x j x s ^\h* <ret>P
2022-06-09 03:18:00 +02:00
}
} }
try %{
# remove trailing whitespace on the above line
execute-keys -draft k :hare-trim-indent <ret>
}
} }
2022-06-09 10:29:32 +02:00
define-command -hidden hare-indent-on-opening-curly-brace %[
# align indent with opening paren when { is entered on a new line after the closing paren
try %[ execute-keys -draft -itersel h<a-F>)M <a-k> \A\(.*\)\h*\n\h*\{\z <ret> s \A|.\z <ret> 1<a-&> ]
]
define-command -hidden hare-indent-on-closing-curly-brace %[
# align to opening curly brace when alone on a line
try %[ execute-keys -itersel -draft <a-h><a-k>^\h+\}$<ret>hms\A|.\z<ret>1<a-&> ]
]
2022-06-09 03:18:00 +02:00
define-command -hidden hare-trim-indent %{ evaluate-commands -draft -itersel %{
# remove trailing whitespace
try %{ execute-keys -draft x s \h+$ <ret> d }
2022-06-09 03:18:00 +02:00
} }
2022-06-09 14:11:14 +02:00
§