summaryrefslogtreecommitdiff
path: root/rc/filetype
diff options
context:
space:
mode:
authorJonathan <vanillajonathan@users.noreply.github.com>2025-03-18 14:13:25 +0000
committerJonathan <vanillajonathan@users.noreply.github.com>2025-03-18 14:13:25 +0000
commit153c592e70bca74d1a5804c0806a8ff014db1c48 (patch)
treefe8bd6371211c97f312905154c2b4fcda3d5dc9f /rc/filetype
parent203a375530fdf10f8add807066836c2f1119d1d9 (diff)
Add syntax highlighting for PRQL
PRQL is a modern language for transforming data — a simple, powerful, pipelined SQL replacement. https://prql-lang.org/ https://github.com/PRQL/prql
Diffstat (limited to 'rc/filetype')
-rw-r--r--rc/filetype/prql.kak159
1 files changed, 159 insertions, 0 deletions
diff --git a/rc/filetype/prql.kak b/rc/filetype/prql.kak
new file mode 100644
index 00000000..54b3c7bb
--- /dev/null
+++ b/rc/filetype/prql.kak
@@ -0,0 +1,159 @@
+# https://prql-lang.org/
+# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
+
+# Detection
+# ‾‾‾‾‾‾‾‾‾
+
+hook global BufCreate .*[.](prql) %{
+ set-option buffer filetype prql
+}
+
+# Initialization
+# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾
+
+hook global WinSetOption filetype=prql %{
+ require-module prql
+
+ set-option window static_words %opt{prql_static_words}
+
+ hook window InsertChar \n -group prql-insert prql-insert-on-new-line
+ hook window InsertChar \n -group prql-indent prql-indent-on-new-line
+ # cleanup trailing whitespaces on current line insert end
+ hook window ModeChange pop:insert:.* -group prql-trim-indent %{ try %{ execute-keys -draft <semicolon> x s ^\h+$ <ret> d } }
+ hook -once -always window WinSetOption filetype=.* %{ remove-hooks window prql-.+ }
+}
+
+hook -group prql-highlight global WinSetOption filetype=prql %{
+ add-highlighter window/prql ref prql
+ hook -once -always window WinSetOption filetype=.* %{ remove-highlighter window/prql }
+}
+
+provide-module prql %§
+
+# Highlighters & Completion
+# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
+
+add-highlighter shared/prql regions
+add-highlighter shared/prql/code default-region group
+
+add-highlighter shared/prql/documentation region '##' '$' fill documentation
+add-highlighter shared/prql/comment region '#' '$' fill comment
+
+# String interpolation
+add-highlighter shared/prql/f_triple_string region -match-capture f("""|''') (?<!\\)(?:\\\\)*("""|''') group
+add-highlighter shared/prql/f_triple_string/ fill string
+add-highlighter shared/prql/f_triple_string/ regex \{.*?\} 0:value
+
+add-highlighter shared/prql/f_double_string region 'f"' (?<!\\)(\\\\)*" group
+add-highlighter shared/prql/f_double_string/ fill string
+add-highlighter shared/prql/f_double_string/ regex \{.*?\} 0:value
+
+add-highlighter shared/prql/f_single_string region "f'" (?<!\\)(\\\\)*' group
+add-highlighter shared/prql/f_single_string/ fill string
+add-highlighter shared/prql/f_single_string/ regex \{.*?\} 0:value
+
+
+# Regular string
+add-highlighter shared/prql/triple_string region -match-capture ("""|''') (?<!\\)(?:\\\\)*("""|''') fill string
+add-highlighter shared/prql/double_string region '"' (?<!\\)(\\\\)*" fill string
+add-highlighter shared/prql/single_string region "'" (?<!\\)(\\\\)*' fill string
+
+# Integer formats
+add-highlighter shared/prql/code/ regex '(?i)\b0b[01]+l?\b' 0:value
+add-highlighter shared/prql/code/ regex '(?i)\b0x[\da-f]+l?\b' 0:value
+add-highlighter shared/prql/code/ regex '(?i)\b0o?[0-7]+l?\b' 0:value
+add-highlighter shared/prql/code/ regex '(?i)\b([1-9]\d*|0)l?\b' 0:value
+# Float formats
+add-highlighter shared/prql/code/ regex '\b\d+[eE][+-]?\d+\b' 0:value
+add-highlighter shared/prql/code/ regex '(\b\d+)?\.\d+\b' 0:value
+add-highlighter shared/prql/code/ regex '\b\d+\.' 0:value
+
+evaluate-commands %sh{
+ # Grammar
+ values="true false null this that"
+ meta="prql module"
+
+ keywords="case let type alias in loop"
+
+ types="bool float int int8 int16 int32 int64 int128 text date time timestamp"
+
+ functions="aggregate derive filter from group join select sort take window"
+
+ join() { sep=$2; eval set -- $1; IFS="$sep"; echo "$*"; }
+
+ # Add the language's grammar to the static completion list
+ printf %s\\n "declare-option str-list prql_static_words $(join "${values} ${meta} ${keywords} ${types} ${functions}" ' ')"
+
+ # Highlight keywords
+ printf %s "
+ add-highlighter shared/prql/code/ regex '\b($(join "${values}" '|'))\b' 0:value
+ add-highlighter shared/prql/code/ regex '\b($(join "${meta}" '|'))\b' 0:meta
+ add-highlighter shared/prql/code/ regex '\b($(join "${keywords}" '|'))\b' 0:keyword
+ add-highlighter shared/prql/code/ regex '\b($(join "${functions}" '|'))\b\(' 1:builtin
+ add-highlighter shared/prql/code/ regex '\b($(join "${types}" '|'))\b' 0:type
+ add-highlighter shared/prql/code/ regex '^\h*(@\{[\w_.]+\}))' 1:attribute
+ "
+}
+
+add-highlighter shared/prql/code/ regex (?<=[\w\s\d\)\]'"_])(<=|>=|<>?|>|!=|==|~=|\||\^|&|\+|-|\*\*?|//?|%|~) 0:operator
+add-highlighter shared/prql/code/ regex (?<=[\w\s\d'"_])((?<![=<>!]):?=(?![=])|[+*-]=) 0:builtin
+add-highlighter shared/prql/code/ regex ^\h*(?:module)\h+(\S+) 1:module
+
+# Commands
+# ‾‾‾‾‾‾‾‾
+
+define-command -hidden prql-insert-on-new-line %{ evaluate-commands -itersel -draft %{
+ execute-keys <semicolon>
+ try %{
+ evaluate-commands -draft -save-regs '/"' %{
+ # Ensure previous line is a comment
+ execute-keys -draft kxs^\h*#+\h*<ret>
+
+ # now handle the comment continuation logic
+ try %{
+ # try and match a regular block comment, copying the prefix
+ execute-keys -draft -save-regs '' k x 1s^(\h*#+\h*)\S.*$ <ret> y
+ execute-keys -draft P
+ } catch %{
+ try %{
+ # try and match a regular block comment followed by a single
+ # empty comment line
+ execute-keys -draft -save-regs '' kKx 1s^(\h*#+\h*)\S+\n\h*#+\h*$ <ret> y
+ execute-keys -draft P
+ } catch %{
+ try %{
+ # try and match a pair of empty comment lines, and delete
+ # them if we match
+ execute-keys -draft kKx <a-k> ^\h*#+\h*\n\h*#+\h*$ <ret> <a-d>
+ } catch %{
+ # finally, we need a special case for a new line inserted
+ # into a file that consists of a single empty comment - in
+ # that case we can't expect to copy the trailing whitespace,
+ # so we add our own
+ execute-keys -draft -save-regs '' k x1s^(\h*#+)\h*$<ret> y
+ execute-keys -draft P
+ execute-keys -draft i<space>
+ }
+ }
+ }
+ }
+
+ # trim trailing whitespace on the previous line
+ try %{ execute-keys -draft k x s\h+$<ret> d }
+ }
+} }
+
+define-command -hidden prql-indent-on-new-line %<
+ evaluate-commands -draft -itersel %<
+ # preserve previous line indent
+ try %{ execute-keys -draft <semicolon> K <a-&> }
+ # cleanup trailing whitespaces from previous line
+ try %{ execute-keys -draft k x s \h+$ <ret> d }
+ # indent after line ending with :
+ try %{ execute-keys -draft , k x <a-k> :$ <ret> <a-K> ^\h*# <ret> j <a-gt> }
+ # deindent closing brace/bracket when after cursor (for arrays and dictionaries)
+ try %< execute-keys -draft x <a-k> ^\h*[}\]] <ret> gh / [}\]] <ret> m <a-S> 1<a-&> >
+ >
+>
+