2015-07-21 10:22:57 +02:00
|
|
|
# https://golang.org/
|
|
|
|
#
|
|
|
|
|
|
|
|
# Detection
|
|
|
|
# ‾‾‾‾‾‾‾‾‾
|
|
|
|
|
2015-09-04 13:51:36 +02:00
|
|
|
hook global BufCreate .*\.go %{
|
2017-11-03 08:34:41 +01:00
|
|
|
set-option buffer filetype go
|
2015-07-21 10:22:57 +02:00
|
|
|
}
|
|
|
|
|
2019-04-10 05:54:19 +02:00
|
|
|
# Initialization
|
|
|
|
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
|
|
|
|
|
|
|
hook global WinSetOption filetype=go %{
|
2019-03-13 06:24:33 +01:00
|
|
|
require-module go
|
2019-04-10 05:54:19 +02:00
|
|
|
|
|
|
|
set-option window static_words %opt{go_static_words}
|
|
|
|
|
|
|
|
# cleanup trailing whitespaces when exiting insert mode
|
2022-03-16 23:20:07 +01:00
|
|
|
hook window ModeChange pop:insert:.* -group go-trim-indent %{ try %{ execute-keys -draft xs^\h+$<ret>d } }
|
2019-04-10 05:54:19 +02:00
|
|
|
hook window InsertChar \n -group go-indent go-indent-on-new-line
|
|
|
|
hook window InsertChar \{ -group go-indent go-indent-on-opening-curly-brace
|
|
|
|
hook window InsertChar \} -group go-indent go-indent-on-closing-curly-brace
|
2022-06-24 10:52:56 +02:00
|
|
|
hook window InsertChar \n -group go-comment-insert go-insert-comment-on-new-line
|
|
|
|
hook window InsertChar \n -group go-closing-delimiter-insert go-insert-closing-delimiter-on-new-line
|
2019-04-10 05:54:19 +02:00
|
|
|
|
2020-09-06 14:15:53 +02:00
|
|
|
alias window alt go-alternative-file
|
|
|
|
|
|
|
|
hook -once -always window WinSetOption filetype=.* %{
|
|
|
|
remove-hooks window go-.+
|
|
|
|
unalias window alt go-alternative-file
|
|
|
|
}
|
2019-04-10 05:54:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
hook -group go-highlight global WinSetOption filetype=go %{
|
|
|
|
add-highlighter window/go ref go
|
|
|
|
hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/go }
|
2019-03-13 06:24:33 +01:00
|
|
|
}
|
|
|
|
|
2019-04-13 21:57:57 +02:00
|
|
|
provide-module go %§
|
2019-03-13 06:24:33 +01:00
|
|
|
|
2015-07-21 10:22:57 +02:00
|
|
|
# Highlighters
|
|
|
|
# ‾‾‾‾‾‾‾‾‾‾‾‾
|
|
|
|
|
2018-07-01 11:53:35 +02:00
|
|
|
add-highlighter shared/go regions
|
|
|
|
add-highlighter shared/go/code default-region group
|
2018-07-02 12:59:12 +02:00
|
|
|
add-highlighter shared/go/back_string region '`' '`' fill string
|
|
|
|
add-highlighter shared/go/double_string region '"' (?<!\\)(\\\\)*" fill string
|
|
|
|
add-highlighter shared/go/single_string region "'" (?<!\\)(\\\\)*' fill string
|
|
|
|
add-highlighter shared/go/comment region /\* \*/ fill comment
|
|
|
|
add-highlighter shared/go/comment_line region '//' $ fill comment
|
2015-07-21 10:22:57 +02:00
|
|
|
|
2023-09-06 20:24:06 +02:00
|
|
|
add-highlighter shared/go/code/numeric regex %{-?([0-9]*\.(?!0[xX]))?\b([0-9]+|0[xX][0-9a-fA-F]+)\.?([eE][+-]?[0-9]+)?i?\b} 0:value
|
2023-09-03 19:10:11 +02:00
|
|
|
add-highlighter shared/go/code/function regex "\b(\w*)\b\h*(?:\[[\w\s\.,]*\])?\h*\(" 1:function
|
2023-01-12 05:40:51 +01:00
|
|
|
add-highlighter shared/go/code/operator regex "(\+|-|\*|/|%|\+\+|--|\+=|-=|\*=|/=|%=|==|!=|>|<|>=|<=|&|&&|\|\||!|<-|:=|\.\.\.)" 1:operator
|
2016-03-14 13:08:51 +01:00
|
|
|
|
2018-05-06 23:29:52 +02:00
|
|
|
evaluate-commands %sh{
|
2016-03-14 13:08:51 +01:00
|
|
|
# Grammar
|
2019-04-10 05:54:19 +02:00
|
|
|
keywords='break default func interface select case defer go map struct
|
|
|
|
chan else goto package switch const fallthrough if range type
|
|
|
|
continue for import return var'
|
2022-04-05 05:09:28 +02:00
|
|
|
types='any bool byte chan comparable complex128 complex64 error float32 float64 int int16 int32
|
2022-04-05 05:14:31 +02:00
|
|
|
int64 int8 interface intptr map rune string struct uint uint16 uint32 uint64 uint8 uintptr'
|
2019-04-10 05:54:19 +02:00
|
|
|
values='false true nil iota'
|
|
|
|
functions='append cap close complex copy delete imag len make new panic print println real recover'
|
|
|
|
|
|
|
|
join() { sep=$2; eval set -- $1; IFS="$sep"; echo "$*"; }
|
2016-03-14 13:08:51 +01:00
|
|
|
|
|
|
|
# Add the language's grammar to the static completion list
|
2019-04-10 05:54:19 +02:00
|
|
|
printf %s\\n "declare-option str-list go_static_words $(join "${keywords} ${attributes} ${types} ${values} ${functions}" ' ')"
|
2016-03-14 13:08:51 +01:00
|
|
|
|
|
|
|
# Highlight keywords
|
2016-03-17 14:30:14 +01:00
|
|
|
printf %s "
|
2022-12-17 08:10:08 +01:00
|
|
|
add-highlighter shared/go/code/keyword regex \b($(join "${keywords}" '|'))\b 0:keyword
|
|
|
|
add-highlighter shared/go/code/attribute regex \b($(join "${attributes}" '|'))\b 0:attribute
|
|
|
|
add-highlighter shared/go/code/type regex \b($(join "${types}" '|'))\b 0:type
|
|
|
|
add-highlighter shared/go/code/value regex \b($(join "${values}" '|'))\b 0:value
|
|
|
|
add-highlighter shared/go/code/builtin regex \b($(join "${functions}" '|'))\b 0:builtin
|
2016-03-14 13:08:51 +01:00
|
|
|
"
|
|
|
|
}
|
2015-07-21 10:22:57 +02:00
|
|
|
|
|
|
|
# Commands
|
|
|
|
# ‾‾‾‾‾‾‾‾
|
|
|
|
|
2020-09-06 14:15:53 +02:00
|
|
|
define-command go-alternative-file -docstring 'Jump to the alternate file (implementation ↔ test)' %{ evaluate-commands %sh{
|
|
|
|
case $kak_buffile in
|
|
|
|
*_test.go)
|
|
|
|
altfile=${kak_buffile%_test.go}.go
|
|
|
|
test ! -f "$altfile" && echo "fail 'implementation file not found'" && exit
|
|
|
|
;;
|
|
|
|
*.go)
|
|
|
|
altfile=${kak_buffile%.go}_test.go
|
|
|
|
test ! -f "$altfile" && echo "fail 'test file not found'" && exit
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
echo "fail 'alternative file not found'" && exit
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
printf "edit -- '%s'" "$(printf %s "$altfile" | sed "s/'/''/g")"
|
|
|
|
}}
|
|
|
|
|
2017-11-03 08:34:41 +01:00
|
|
|
define-command -hidden go-indent-on-new-line %~
|
2017-11-03 09:09:45 +01:00
|
|
|
evaluate-commands -draft -itersel %=
|
2015-07-21 10:22:57 +02:00
|
|
|
# preserve previous line indent
|
2019-10-22 11:02:06 +02:00
|
|
|
try %{ execute-keys -draft <semicolon>K<a-&> }
|
2015-07-21 10:22:57 +02:00
|
|
|
# cleanup trailing white spaces on the previous line
|
2022-03-16 23:20:07 +01:00
|
|
|
try %{ execute-keys -draft kx s \h+$ <ret>d }
|
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
|
|
|
try %<
|
2022-04-23 05:51:00 +02:00
|
|
|
try %{ # line comment
|
2022-03-16 23:20:07 +01:00
|
|
|
execute-keys -draft kx s ^\h*// <ret>
|
2022-04-23 05:51:00 +02:00
|
|
|
} catch %{ # block comment
|
|
|
|
execute-keys -draft <a-?> /\* <ret> <a-K>\*/<ret>
|
|
|
|
}
|
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
|
|
|
> catch %<
|
2022-06-04 23:53:18 +02:00
|
|
|
# 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> >
|
2022-04-23 05:51:00 +02:00
|
|
|
# indent after a switch's case/default statements
|
2022-03-16 23:20:07 +01:00
|
|
|
try %[ execute-keys -draft kx <a-k> ^\h*(case|default).*:$ <ret> j<a-gt> ]
|
2022-04-23 05:51:00 +02:00
|
|
|
# deindent closing brace(s) when after cursor
|
2022-03-16 23:20:07 +01:00
|
|
|
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
|
|
|
>
|
2015-07-21 10:22:57 +02:00
|
|
|
=
|
|
|
|
~
|
|
|
|
|
2017-11-03 08:34:41 +01:00
|
|
|
define-command -hidden go-indent-on-opening-curly-brace %[
|
2015-07-21 10:22:57 +02:00
|
|
|
# align indent with opening paren when { is entered on a new line after the closing paren
|
2017-11-03 09:09:45 +01:00
|
|
|
try %[ execute-keys -draft -itersel h<a-F>)M <a-k> \A\(.*\)\h*\n\h*\{\z <ret> s \A|.\z <ret> 1<a-&> ]
|
2015-07-21 10:22:57 +02:00
|
|
|
]
|
|
|
|
|
2017-11-03 08:34:41 +01:00
|
|
|
define-command -hidden go-indent-on-closing-curly-brace %[
|
2015-07-21 10:22:57 +02:00
|
|
|
# align to opening curly brace when alone on a line
|
2017-11-03 09:09:45 +01:00
|
|
|
try %[ execute-keys -itersel -draft <a-h><a-k>^\h+\}$<ret>hms\A|.\z<ret>1<a-&> ]
|
2015-07-21 10:22:57 +02:00
|
|
|
]
|
|
|
|
|
2022-06-24 10:52:56 +02:00
|
|
|
define-command -hidden go-insert-comment-on-new-line %[
|
2020-09-04 20:21:35 +02:00
|
|
|
evaluate-commands -no-hooks -draft -itersel %[
|
2021-04-17 10:17:01 +02:00
|
|
|
# copy // comments prefix and following white spaces
|
2022-03-16 23:20:07 +01:00
|
|
|
try %{ execute-keys -draft <semicolon><c-s>kx s ^\h*\K/{2,}\h* <ret> y<c-o>P<esc> }
|
2022-06-04 16:34:37 +02:00
|
|
|
]
|
|
|
|
]
|
2021-04-17 10:17:01 +02:00
|
|
|
|
2022-06-04 16:34:37 +02:00
|
|
|
define-command -hidden go-insert-closing-delimiter-on-new-line %[
|
|
|
|
evaluate-commands -no-hooks -draft -itersel %[
|
2020-09-04 20:21:35 +02:00
|
|
|
# Wisely add '}'.
|
|
|
|
evaluate-commands -save-regs x %[
|
|
|
|
# Save previous line indent in register x.
|
2022-03-16 23:20:07 +01:00
|
|
|
try %[ execute-keys -draft kxs^\h+<ret>"xy ] catch %[ reg x '' ]
|
2020-09-04 20:21:35 +02:00
|
|
|
try %[
|
|
|
|
# Validate previous line and that it is not closed yet.
|
2022-03-16 23:20:07 +01:00
|
|
|
execute-keys -draft kx <a-k>^<c-r>x.*\{\h*\(?\h*$<ret> j}iJx <a-K>^<c-r>x\)?\h*\}<ret>
|
2020-09-04 20:21:35 +02:00
|
|
|
# Insert closing '}'.
|
|
|
|
execute-keys -draft o<c-r>x}<esc>
|
|
|
|
# Delete trailing '}' on the line below the '{'.
|
2022-03-16 23:20:07 +01:00
|
|
|
execute-keys -draft xs\}$<ret>d
|
2020-09-04 20:21:35 +02:00
|
|
|
]
|
|
|
|
]
|
|
|
|
|
|
|
|
# Wisely add ')'.
|
|
|
|
evaluate-commands -save-regs x %[
|
|
|
|
# Save previous line indent in register x.
|
2022-03-16 23:20:07 +01:00
|
|
|
try %[ execute-keys -draft kxs^\h+<ret>"xy ] catch %[ reg x '' ]
|
2020-09-04 20:21:35 +02:00
|
|
|
try %[
|
|
|
|
# Validate previous line and that it is not closed yet.
|
2022-03-16 23:20:07 +01:00
|
|
|
execute-keys -draft kx <a-k>^<c-r>x.*\(\h*$<ret> J}iJx <a-K>^<c-r>x\)<ret>
|
2020-09-04 20:21:35 +02:00
|
|
|
# Insert closing ')'.
|
|
|
|
execute-keys -draft o<c-r>x)<esc>
|
|
|
|
# Delete trailing ')' on the line below the '('.
|
2022-03-16 23:20:07 +01:00
|
|
|
execute-keys -draft xs\)\h*\}?\h*$<ret>d
|
2020-09-04 20:21:35 +02:00
|
|
|
]
|
|
|
|
]
|
|
|
|
]
|
|
|
|
]
|
|
|
|
|
2019-04-13 21:57:57 +02:00
|
|
|
§
|