1# https://cuelang.org 2# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 3 4# Detection 5# ‾‾‾‾‾‾‾‾‾ 6 7hook global BufCreate .*[.](cue) %{ 8 set-option buffer filetype cue 9} 10 11# Initialization 12# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 13 14hook global WinSetOption filetype=cue %[ 15 require-module cue 16 17 # cleanup trailing whitespaces when exiting insert mode 18 hook window ModeChange pop:insert:.* -group cue-trim-indent cue-trim-indent 19 hook window InsertChar \n -group cue-insert cue-insert-on-new-line 20 hook window InsertChar \n -group cue-indent cue-indent-on-new-line 21 hook window InsertChar \{ -group cue-indent cue-indent-on-opening-curly-brace 22 hook window InsertChar [)}] -group cue-indent cue-indent-on-closing 23 24 hook -once -always window WinSetOption filetype=.* %{ remove-hooks window cue-.+ } 25] 26 27hook -group cue-highlight global WinSetOption filetype=cue %{ 28 add-highlighter window/cue ref cue 29 hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/cue } 30} 31 32provide-module cue %§ 33 34# Highlighters 35# ‾‾‾‾‾‾‾‾‾‾‾‾ 36 37# https://cuelang.org/docs/references/spec/ 38 39add-highlighter shared/cue regions 40add-highlighter shared/cue/code default-region group 41add-highlighter shared/cue/simple_string region '"' (?<!\\)(\\\\)*" regions 42add-highlighter shared/cue/simple_bytes region "'" (?<!\\)(\\\\)*' fill string 43add-highlighter shared/cue/multiline_string region '"""' '"""' ref shared/cue/simple_string 44add-highlighter shared/cue/multiline_bytes region "'''" "'''" ref shared/cue/simple_bytes 45add-highlighter shared/cue/line_comment region "//" "$" fill comment 46 47add-highlighter shared/cue/simple_string/base default-region fill string 48add-highlighter shared/cue/simple_string/interpolation region -recurse \( \\\( \) fill meta 49 50evaluate-commands %sh{ 51 # Grammar 52 binary_digit="[01]" 53 decimal_digit="[0-9]" 54 hex_digit="[0-9a-fA-F]" 55 octal_digit="[0-7]" 56 57 decimal_lit="[1-9](_?${decimal_digit})*" 58 binary_lit="0b${binary_digit}(_?${binary_digit})*" 59 hex_lit="0[xX]${hex_digit}(_?${hex_digit})*" 60 octal_lit="0o${octal_digit}(_?${octal_digit})*" 61 62 decimals="${decimal_digit}(_?${decimal_digit})*" 63 multiplier="([KMGTP]i?)?" 64 exponent="([eE][+-]?${decimals})" 65 si_lit="(${decimals}(\.${decimals})?${multiplier}|\.${decimals}${multiplier})" 66 67 int_lit="\b(${decimal_lit}|${si_lit}|${octal_lit}|${binary_lit}|${hex_lit})\b" 68 float_lit="\b${decimals}\.(${decimals})?${exponent}?|\b${decimals}${exponent}\b|\.${decimals}${exponent}?\b" 69 70 operator_chars="(\+|-|\*|/|&|&&|\||\|\||=|==|=~|!|!=|!~|<|>|<=|>=)" 71 punctuation="(_\|_|:|::|,|\.|\.\.\.|\(|\{|\[|\)|\}|\])" 72 73 function_calls="\w+(?=\()" 74 identifier="(?!\d)[\w_$]+" 75 reserved="\b__${identifier}" 76 77 preamble="^(package|import)\b" 78 79 functions="len close and or" 80 keywords="for in if let" 81 operators="div mod quo rem" 82 types=" 83 bool string bytes rune number 84 uint uint8 uint16 uint32 uint64 uint128 85 int int8 int16 int32 int64 int128 86 float float32 float64 87 " 88 values="null true false" 89 90 join() { sep=$2; set -- $1; IFS="$sep"; echo "$*"; } 91 92 static_words="$(join "package import ${functions} ${keywords} ${operators} ${types} ${values}" ' ')" 93 94 # Add the language's grammar to the static completion list 95 printf %s\\n "declare-option str-list cue_static_words ${static_words}" 96 97 functions="$(join "${functions}" '|')" 98 keywords="$(join "${keywords}" '|')" 99 operators="$(join "${operators}" '|')" 100 types="$(join "${types}" '|')" 101 values="$(join "${values}" '|')" 102 103 # Highlight keywords 104 printf %s " 105 add-highlighter shared/cue/code/ regex ${float_lit} 0:value 106 add-highlighter shared/cue/code/ regex ${function_calls} 0:function 107 add-highlighter shared/cue/code/ regex ${int_lit} 0:value 108 add-highlighter shared/cue/code/ regex ${operator_chars} 0:operator 109 add-highlighter shared/cue/code/ regex ${preamble} 0:keyword 110 add-highlighter shared/cue/code/ regex ${punctuation} 0:operator 111 add-highlighter shared/cue/code/ regex ${reserved} 0:keyword 112 add-highlighter shared/cue/code/ regex \b(${functions})\b 0:builtin 113 add-highlighter shared/cue/code/ regex \b(${keywords})\b 0:keyword 114 add-highlighter shared/cue/code/ regex \b(${operators})\b 0:operator 115 add-highlighter shared/cue/code/ regex \b(${types})\b 0:type 116 add-highlighter shared/cue/code/ regex \b(${values})\b 0:value 117 " 118} 119 120# Commands 121# ‾‾‾‾‾‾‾‾ 122 123define-command -hidden cue-trim-indent %{ 124 # remove trailing white spaces 125 try %{ execute-keys -draft -itersel <a-x> s \h+$ <ret> d } 126} 127 128define-command -hidden cue-insert-on-new-line %~ 129 evaluate-commands -draft -itersel %< 130 # copy // comments prefix and following white spaces 131 try %{ execute-keys -draft <semicolon><c-s>k<a-x> s ^\h*\K//[!/]?\h* <ret> y<c-o>P<esc> } 132 > 133~ 134 135define-command -hidden cue-indent-on-new-line %~ 136 evaluate-commands -draft -itersel %< 137 # preserve previous line indent 138 try %{ execute-keys -draft <semicolon> K <a-&> } 139 try %< 140 # only if we didn't copy a comment 141 execute-keys -draft <a-x> <a-K> ^\h*// <ret> 142 # indent after lines ending with { or ( 143 try %[ execute-keys -draft k <a-x> <a-k> [{(]\h*$ <ret> j <a-gt> ] 144 # indent after lines ending with [{(].+ and move first parameter to own line 145 try %< execute-keys -draft [c[({],[)}] <ret> <a-k> \A[({][^\n]+\n[^\n]*\n?\z <ret> L i<ret><esc> <gt> <a-S> <a-&> > 146 # deindent closing brace(s) when after cursor 147 try %< execute-keys -draft <a-x> <a-k> ^\h*[})] <ret> gh / [})] <ret> m <a-S> 1<a-&> > 148 > 149 # filter previous line 150 try %{ execute-keys -draft k : cue-trim-indent <ret> } 151 > 152~ 153 154define-command -hidden cue-indent-on-opening-curly-brace %[ 155 evaluate-commands -draft -itersel %_ 156 # align indent with opening paren when { is entered on a new line after the closing paren 157 try %[ execute-keys -draft h <a-F> ) M <a-k> \A\(.*\)\h*\n\h*\{\z <ret> s \A|.\z <ret> 1<a-&> ] 158 _ 159] 160 161define-command -hidden cue-indent-on-closing %[ 162 evaluate-commands -draft -itersel %_ 163 # align to opening curly brace or paren when alone on a line 164 try %< execute-keys -draft <a-h> <a-k> ^\h*[)}]$ <ret> h m <a-S> 1<a-&> > 165 _ 166] 167 168§ 169