|
| 1 | +" Vim syntax file |
| 2 | +" Language: PRQL |
| 3 | +" Maintainer: vanillajonathan |
| 4 | +" Last Change: 2025-03-07 |
| 5 | +" |
| 6 | +" https://prql-lang.org/ |
| 7 | +" https://github.com/PRQL/prql |
| 8 | + |
| 9 | +" quit when a syntax file was already loaded. |
| 10 | +if exists("b:current_syntax") |
| 11 | + finish |
| 12 | +endif |
| 13 | + |
| 14 | +" We need nocompatible mode in order to continue lines with backslashes. |
| 15 | +" Original setting will be restored. |
| 16 | +let s:cpo_save = &cpo |
| 17 | +set cpo&vim |
| 18 | + |
| 19 | +syn keyword prqlBoolean false true |
| 20 | +syn keyword prqlSelf this that |
| 21 | +syn keyword prqlStatement null |
| 22 | +syn keyword prqlConditional case |
| 23 | +syn keyword prqlStatement prql let type alias in |
| 24 | +syn keyword prqlRepeat loop |
| 25 | +syn match prqlOperator display "\%(+\|-\|/\|*\|=\|\^\|&\||\|!\|>\|<\|%\|\~\)=\?" |
| 26 | +syn match prqlOperator display "&&\|||" |
| 27 | +syn keyword prqlInclude module |
| 28 | + |
| 29 | +" Annotations |
| 30 | +syn match prqlAnnotation "@" display contained |
| 31 | +syn match prqlAnnotationName "@\s*{\h\%(\w\|=\)*}" display contains=prqlAnnotation |
| 32 | + |
| 33 | +syn match prqlFunction "\h\w*" display contained |
| 34 | + |
| 35 | +syn match prqlComment "#.*$" contains=prqlTodo,@Spell |
| 36 | +syn keyword prqlTodo FIXME NOTE TODO XXX contained |
| 37 | + |
| 38 | +" Triple-quoted strings can contain doctests. |
| 39 | +syn region prqlString matchgroup=prqlQuotes |
| 40 | + \ start=+\z(['"]\)+ end="\z1" skip="\\\\\|\\\z1" |
| 41 | + \ contains=prqlEscape,@Spell |
| 42 | +syn region prqlString matchgroup=prqlTripleQuotes |
| 43 | + \ start=+\z('''\|"""\)+ end="\z1" keepend |
| 44 | + \ contains=prqlEscape,prqlSpaceError,prqlDoctest,@Spell |
| 45 | +syn region prqlFString matchgroup=prqlQuotes |
| 46 | + \ start=+[f]\z(['"]\)+ end="\z1" skip="\\\\\|\\\z1" |
| 47 | + \ contains=prqlEscape,@Spell |
| 48 | +syn region prqlFString matchgroup=prqlTripleQuotes |
| 49 | + \ start=+f\z('''\|"""\)+ end="\z1" keepend |
| 50 | + \ contains=prqlEscape,prqlSpaceError,prqlDoctest,@Spell |
| 51 | +syn region prqlRString matchgroup=prqlQuotes |
| 52 | + \ start=+r\z(['"]\)+ end="\z1" skip="\\\\\|\\\z1" |
| 53 | + \ contains=@Spell |
| 54 | +syn region prqlRString matchgroup=prqlTripleQuotes |
| 55 | + \ start=+r\z('''\|"""\)+ end="\z1" keepend |
| 56 | + \ contains=prqlSpaceError,prqlDoctest,@Spell |
| 57 | +syn region prqlSString matchgroup=prqlQuotes |
| 58 | + \ start=+s\z(['"]\)+ end="\z1" skip="\\\\\|\\\z1" |
| 59 | + \ contains=@Spell |
| 60 | +syn region prqlSString matchgroup=prqlTripleQuotes |
| 61 | + \ start=+s\z('''\|"""\)+ end="\z1" keepend |
| 62 | + \ contains=prqlSpaceError,prqlDoctest,@Spell |
| 63 | + |
| 64 | +syn match prqlEscape +\\[bfnrt'"\\]+ contained |
| 65 | +syn match prqlEscape "\\\o\{1,3}" contained |
| 66 | +syn match prqlEscape "\\x\x\{2}" contained |
| 67 | +syn match prqlEscape "\%(\\u\x\{1,6}\)" contained |
| 68 | +syn match prqlEscape "\\$" |
| 69 | + |
| 70 | +" It is very important to understand all details before changing the |
| 71 | +" regular expressions below or their order. |
| 72 | +" The word boundaries are *not* the floating-point number boundaries |
| 73 | +" because of a possible leading or trailing decimal point. |
| 74 | +" The expressions below ensure that all valid number literals are |
| 75 | +" highlighted, and invalid number literals are not. For example, |
| 76 | +" |
| 77 | +" - a decimal point in '4.' at the end of a line is highlighted, |
| 78 | +" - a second dot in 1.0.0 is not highlighted, |
| 79 | +" - 08 is not highlighted, |
| 80 | +" - 08e0 or 08j are highlighted, |
| 81 | +" |
| 82 | +if !exists("prql_no_number_highlight") |
| 83 | + " numbers (including complex) |
| 84 | + syn match prqlNumber "\<0[oO]\%(_\=\o\)\+\>" |
| 85 | + syn match prqlNumber "\<0[xX]\%(_\=\x\)\+\>" |
| 86 | + syn match prqlNumber "\<0[bB]\%(_\=[01]\)\+\>" |
| 87 | + syn match prqlNumber "\<\%([1-9]\%(_\=\d\)*\|0\+\%(_\=0\)*\)\>" |
| 88 | + syn match prqlNumber "\<\d\%(_\=\d\)*[jJ]\>" |
| 89 | + syn match prqlNumber "\<\d\%(_\=\d\)*[eE][+-]\=\d\%(_\=\d\)*[jJ]\=\>" |
| 90 | + syn match prqlNumber |
| 91 | + \ "\<\d\%(_\=\d\)*\.\%([eE][+-]\=\d\%(_\=\d\)*\)\=[jJ]\=\%(\W\|$\)\@=" |
| 92 | + syn match prqlNumber |
| 93 | + \ "\%(^\|\W\)\zs\%(\d\%(_\=\d\)*\)\=\.\d\%(_\=\d\)*\%([eE][+-]\=\d\%(_\=\d\)*\)\=[jJ]\=\>" |
| 94 | +endif |
| 95 | + |
| 96 | +" https://prql-lang.org/book/reference/stdlib/transforms/ |
| 97 | +" |
| 98 | +" PRQL built-in functions are in alphabetical order. |
| 99 | +" |
| 100 | + |
| 101 | +" Built-in functions |
| 102 | +syn keyword prqlBuiltin aggregate derive filter from group join select sort take window |
| 103 | + |
| 104 | +" Built-in types |
| 105 | +syn keyword prqlType bool float int int8 int16 int32 int64 int128 text date time timestamp |
| 106 | + |
| 107 | +" avoid highlighting attributes as builtins |
| 108 | +syn match prqlAttribute /\.\h\w*/hs=s+1 |
| 109 | + \ contains=ALLBUT,prqlBuiltin,prqlFunction |
| 110 | + \ transparent |
| 111 | + |
| 112 | +if exists("prql_space_error_highlight") |
| 113 | + " trailing whitespace |
| 114 | + syn match prqlSpaceError display excludenl "\s\+$" |
| 115 | + " mixed tabs and spaces |
| 116 | + syn match prqlSpaceError display " \+\t" |
| 117 | + syn match prqlSpaceError display "\t\+ " |
| 118 | +endif |
| 119 | + |
| 120 | +" Do not spell doctests inside strings. |
| 121 | +" Notice that the end of a string, either ''', or """, will end the contained |
| 122 | +" doctest too. Thus, we do *not* need to have it as an end pattern. |
| 123 | +if !exists("prql_no_doctest_highlight") |
| 124 | + if !exists("prql_no_doctest_code_highlight") |
| 125 | + syn region prqlDoctest |
| 126 | + \ start="^\s*>>>\s" end="^\s*$" |
| 127 | + \ contained contains=ALLBUT,prqlDoctest,prqlFunction,@Spell |
| 128 | + syn region prqlDoctestValue |
| 129 | + \ start=+^\s*\%(>>>\s\|\.\.\.\s\|"""\|'''\)\@!\S\++ end="$" |
| 130 | + \ contained |
| 131 | + else |
| 132 | + syn region prqlDoctest |
| 133 | + \ start="^\s*>>>" end="^\s*$" |
| 134 | + \ contained contains=@NoSpell |
| 135 | + endif |
| 136 | +endif |
| 137 | + |
| 138 | +" The default highlight links. Can be overridden later. |
| 139 | +hi def link prqlBoolean Boolean |
| 140 | +hi def link prqlStatement Statement |
| 141 | +hi def link prqlType Type |
| 142 | +hi def link prqlConditional Conditional |
| 143 | +hi def link prqlRepeat Repeat |
| 144 | +hi def link prqlOperator Operator |
| 145 | +hi def link prqlInclude Include |
| 146 | +hi def link prqlAnnotation Define |
| 147 | +hi def link prqlAnnotationName Function |
| 148 | +hi def link prqlFunction Function |
| 149 | +hi def link prqlComment Comment |
| 150 | +hi def link prqlTodo Todo |
| 151 | +hi def link prqlSelf Constant |
| 152 | +hi def link prqlString String |
| 153 | +hi def link prqlFString String |
| 154 | +hi def link prqlRString String |
| 155 | +hi def link prqlSString String |
| 156 | +hi def link prqlQuotes String |
| 157 | +hi def link prqlTripleQuotes prqlQuotes |
| 158 | +hi def link prqlEscape Special |
| 159 | +if !exists("prql_no_number_highlight") |
| 160 | + hi def link prqlNumber Number |
| 161 | +endif |
| 162 | +if !exists("prql_no_builtin_highlight") |
| 163 | + hi def link prqlBuiltin Function |
| 164 | +endif |
| 165 | +if exists("prql_space_error_highlight") |
| 166 | + hi def link prqlSpaceError Error |
| 167 | +endif |
| 168 | +if !exists("prql_no_doctest_highlight") |
| 169 | + hi def link prqlDoctest Special |
| 170 | + hi def link prqlDoctestValue Define |
| 171 | +endif |
| 172 | + |
| 173 | +let b:current_syntax = "prql" |
| 174 | + |
| 175 | +let &cpo = s:cpo_save |
| 176 | +unlet s:cpo_save |
| 177 | + |
| 178 | +" vim:set sw=2 sts=2 ts=8 noet: |
0 commit comments