diff --git a/rc/filetype/cue.kak b/rc/filetype/cue.kak new file mode 100644 index 00000000..a2fbb0c7 --- /dev/null +++ b/rc/filetype/cue.kak @@ -0,0 +1,159 @@ +# https://cuelang.org +# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ + +# Detection +# ‾‾‾‾‾‾‾‾‾ + +hook global BufCreate .*[.](cue) %{ + set-option buffer filetype cue +} + +# Initialization +# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ + +hook global WinSetOption filetype=cue %[ + require-module cue + + # cleanup trailing whitespaces when exiting insert mode + hook window ModeChange pop:insert:.* -group cue-trim-indent cue-trim-indent + hook window InsertChar \n -group cue-indent cue-indent-on-new-line + hook window InsertChar \{ -group cue-indent cue-indent-on-opening-curly-brace + hook window InsertChar [)}] -group cue-indent cue-indent-on-closing + + hook -once -always window WinSetOption filetype=.* %{ remove-hooks window cue-.+ } +] + +hook -group cue-highlight global WinSetOption filetype=cue %{ + add-highlighter window/cue ref cue + hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/cue } +} + +provide-module cue %§ + +# Highlighters +# ‾‾‾‾‾‾‾‾‾‾‾‾ + +# https://cuelang.org/docs/references/spec/ + +add-highlighter shared/cue regions +add-highlighter shared/cue/code default-region group +add-highlighter shared/cue/simple_string region '"' (?|<=|>=)" + punctuation="(_\|_|:|::|,|\.|\.\.\.|\(|\{|\[|\)|\}|\])" + + function_calls="\w+(?=\()" + identifier="(?!\d)[\w_$]+" + reserved="\b__${identifier}" + + preamble="^(package|import)\b" + + functions="len close and or" + keywords="for in if let" + operators="div mod quo rem" + types=" + bool string bytes rune number + uint uint8 uint16 uint32 uint64 uint128 + int int8 int16 int32 int64 int128 + float float32 float64 + " + values="null true false" + + join() { sep=$2; set -- $1; IFS="$sep"; echo "$*"; } + + static_words="$(join "package import ${functions} ${keywords} ${operators} ${types} ${values}" ' ')" + + # Add the language's grammar to the static completion list + printf %s\\n "declare-option str-list cue_static_words ${static_words}" + + functions="$(join "${functions}" '|')" + keywords="$(join "${keywords}" '|')" + operators="$(join "${operators}" '|')" + types="$(join "${types}" '|')" + values="$(join "${values}" '|')" + + # Highlight keywords + printf %s " + add-highlighter shared/cue/code/ regex ${float_lit} 0:value + add-highlighter shared/cue/code/ regex ${function_calls} 0:function + add-highlighter shared/cue/code/ regex ${int_lit} 0:value + add-highlighter shared/cue/code/ regex ${operator_chars} 0:operator + add-highlighter shared/cue/code/ regex ${preamble} 0:keyword + add-highlighter shared/cue/code/ regex ${punctuation} 0:operator + add-highlighter shared/cue/code/ regex ${reserved} 0:keyword + add-highlighter shared/cue/code/ regex \b(${functions})\b 0:builtin + add-highlighter shared/cue/code/ regex \b(${keywords})\b 0:keyword + add-highlighter shared/cue/code/ regex \b(${operators})\b 0:operator + add-highlighter shared/cue/code/ regex \b(${types})\b 0:type + add-highlighter shared/cue/code/ regex \b(${values})\b 0:value + " +} + +# Commands +# ‾‾‾‾‾‾‾‾ + +define-command -hidden cue-trim-indent %{ + # remove trailing white spaces + try %{ execute-keys -draft -itersel s \h+$ d } +} + +define-command -hidden cue-indent-on-new-line %~ + evaluate-commands -draft -itersel %< + # copy // comments prefix and following white spaces + try %{ + execute-keys -draft k s ^\h*\K//[!/]?\h* y gh j P + } catch %| + # preserve previous line indent + try %{ execute-keys -draft K } + # indent after lines ending with { or ( + try %[ execute-keys -draft k [{(]\h*$ j ] + # indent after lines ending with [{(].+ and move first parameter to own line + try %< execute-keys -draft [c[({],[)}] \A[({][^\n]+\n[^\n]*\n?\z L i > + | + # filter previous line + try %{ execute-keys -draft k : cue-trim-indent } + > +~ + +define-command -hidden cue-indent-on-opening-curly-brace %[ + evaluate-commands -draft -itersel %_ + # align indent with opening paren when { is entered on a new line after the closing paren + try %[ execute-keys -draft h ) M \A\(.*\)\h*\n\h*\{\z s \A|.\z 1 ] + _ +] + +define-command -hidden cue-indent-on-closing %[ + evaluate-commands -draft -itersel %_ + # align to opening curly brace or paren when alone on a line + try %< execute-keys -draft ^\h*[)}]$ h m 1 > + _ +] + +§