# 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 > # deindent closing brace(s) when after cursor try %< execute-keys -draft ^\h*[})]+\h*$ hm 1 > | # 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 > _ ] §