blob: 79c81d0f9cf51b2618da5f9bbb81dbff30636414 [file] [log] [blame]
Peter Benjamin72755b32025-01-20 21:56:41 +01001" Vim syntax file
2" Language: Justfile
3" Maintainer: Peter Benjamin <@pbnj>
Peter Benjamin509a8d52025-01-25 15:26:09 +01004" Last Change: 2025 Jan 25
Peter Benjamin72755b32025-01-20 21:56:41 +01005" Credits: The original author, Noah Bogart <https://github.com/NoahTheDuke/vim-just/>
6
7if exists('b:current_syntax')
8 finish
9endif
10
11let s:cpo_save = &cpo
12set cpo&vim
13
14let b:current_syntax = 'just'
15
16" syncing fromstart prevents mismatched highlighting when jumping around in a justfile
17" linebreaks= keeps multi-line constructs highlighted correctly while typing
18syn sync fromstart linebreaks=10
19
20" a-zA-Z0-9_-
21syn iskeyword @,48-57,_,-
22
23syn match justComment "#.*$" contains=@Spell,justCommentTodo
24syn match justCommentInBody '#.*$' contained contains=justCommentTodo,justInterpolation,@justOtherCurlyBraces
25syn keyword justCommentTodo TODO FIXME XXX contained
26syn match justShebang "^\s*#!.*$" contains=justInterpolation,@justOtherCurlyBraces
27syn match justName "\h\k*" contained
28syn match justFunction "\h\k*" contained
29
30syn match justPreBodyComment "\v%(\s|\\\n)*%([^\\]\n)@3<!#%([^!].*)?\n%(\t+| +)@=" transparent contained contains=justComment
31 \ nextgroup=@justBodies skipnl
32
33syn region justBacktick start=/`/ end=/`/
34syn region justBacktick start=/```/ end=/```/
35syn region justRawString start=/'/ end=/'/
36syn region justRawString start=/'''/ end=/'''/
37syn region justString start=/"/ skip=/\\\\\|\\"/ end=/"/ contains=justStringEscapeSequence,justStringUEscapeSequence,justStringEscapeError
38syn region justString start=/"""/ skip=/\\\\\|\\"/ end=/"""/ contains=justStringEscapeSequence,justStringUEscapeSequence,justStringEscapeError
39
40syn region justShellExpandRawString start=/\v\k@1<!x'/ end=/'/
41 \ contains=justShellExpandVarRaw,justDollarEscape
42syn region justShellExpandRawString start=/\v\k@1<!x'''/ end=/'''/
43 \ contains=justShellExpandVarRaw,justDollarEscape
44syn region justShellExpandString
45 \ start=/\v\k@1<!x"/ skip=/\\\\\|\\"/ end=/"/
46 \ contains=justStringEscapeSequence,justStringUEscapeSequence,justStringEscapeError,justShellExpandVar,justDollarEscape,justDollarEscapeSplit
47syn region justShellExpandString
48 \ start=/\v\k@1<!x"""/ skip=/\\\\\|\\"/ end=/"""/
49 \ contains=justStringEscapeSequence,justStringUEscapeSequence,justStringEscapeError,justShellExpandVar,justDollarEscape,justDollarEscapeSplit
50
51syn cluster justStringLiterals
52 \ contains=justRawString,justString,justShellExpandRawString,justShellExpandString
53syn cluster justAllStrings contains=justBacktick,@justStringLiterals
54
55syn match justRegexReplacement
56 \ /\v,%(\_s|\\\n)*%('\_[^']*'|'''%(\_.%(''')@!)*\_.?''')%(\_s|\\\n)*%(,%(\_s|\\\n)*)?\)/me=e-1
57 \ transparent contained contains=@justExpr,@justStringsWithRegexCapture
58syn match justRegexReplacement
59 \ /\v,%(\_s|\\\n)*%("%(\_[^"]|\\")*"|"""%(\_.%(""")@!)*\_.?""")%(\_s|\\\n)*%(,%(\_s|\\\n)*)?\)/me=e-1
60 \ transparent contained contains=@justExpr,@justStringsWithRegexCapture
61
62syn region justRawStrRegexRepl start=/\v'/ end=/'/ contained contains=justRegexCapture,justDollarEscape
63syn region justRawStrRegexRepl start=/\v'''/ end=/'''/ contained contains=justRegexCapture,justDollarEscape
64syn region justStringRegexRepl start=/\v"/ skip=/\\\\\|\\"/ end=/"/ contained contains=justStringEscapeSequence,justStringUEscapeSequence,justStringEscapeError,justRegexCapture,justDollarEscape,justDollarEscapeSplit
65syn region justStringRegexRepl start=/\v"""/ skip=/\\\\\|\\"/ end=/"""/ contained contains=justStringEscapeSequence,justStringUEscapeSequence,justStringEscapeError,justRegexCapture,justDollarEscape,justDollarEscapeSplit
66syn match justRegexCapture '\v\$%(\w+|\{\w+\})' contained
67syn cluster justStringsWithRegexCapture contains=justRawStrRegexRepl,justStringRegexRepl
68
69syn cluster justRawStrings contains=justRawString,justRawStrRegexRepl
70
71syn region justStringInsideBody start=/\v\\@1<!'/ end=/'/ contained contains=justInterpolation,@justOtherCurlyBraces,justIndentError
72syn region justStringInsideBody start=/\v\\@1<!"/ skip=/\v\\@1<!\\"/ end=/"/ contained contains=justInterpolation,@justOtherCurlyBraces,justIndentError
73syn region justStringInShebangBody start=/\v\\@1<!'/ end=/'/ contained contains=justInterpolation,@justOtherCurlyBraces,justShebangIndentError
74syn region justStringInShebangBody start=/\v\\@1<!"/ skip=/\v\\@1<!\\"/ end=/"/ contained contains=justInterpolation,@justOtherCurlyBraces,justShebangIndentError
75
76syn match justStringEscapeError '\\.' contained
77syn match justStringEscapeSequence '\v\\[tnr"\\]' contained
78syn match justStringUEscapeSequence '\v\\u\{[0-9A-Fa-f]{1,6}\}' contained
79
80syn match justAssignmentOperator "\V:=" contained
81
82syn region justExprParen start='\V(' end='\V)' transparent contains=@justExpr
83syn region justExprParenInInterp start='\V(' end='\V)' transparent contained contains=@justExprInInterp
84
85syn match justRecipeAt "^@" contained
86syn match justRecipeColon ":" contained
87
88syn region justRecipeAttributes
89 \ matchgroup=justRecipeAttr start='\v^%(\\\n)@3<!\[' end='\V]'
90 \ contains=justRecipeAttr,justRecipeAttrSep,justRecipeAttrArgs,justRecipeAttrArgError,justRecipeAttrValueShort
91
92syn keyword justRecipeAttr
93 \ confirm doc extension group linux macos no-cd no-exit-message no-quiet openbsd positional-arguments private script unix windows working-directory
94 \ contained
95syn match justRecipeAttrSep ',' contained
96syn match justRecipeAttrValueShort '\v:%(\_s|\\\n)*' transparent contained
97 \ contains=justRecipeAttrValueColon nextgroup=@justStringLiterals,justInvalidAttrValue
98syn match justRecipeAttrValueColon '\V:' contained
99syn region justRecipeAttrArgs matchgroup=justRecipeAttr start='\V(' end='\V)' contained
100 \ contains=@justStringLiterals
101syn match justRecipeAttrArgError '\v\(%(\s|\\?\n)*\)' contained
102
103syn match justInvalidAttrValue '\v[^"',]["']@![^,\]]*' contained
104
105syn match justRecipeDeclSimple "\v^\@?\h\k*%(%(\s|\\\n)*:\=@!)@="
106 \ transparent contains=justRecipeName
107 \ nextgroup=justRecipeNoDeps,justRecipeDeps
108
109syn region justRecipeDeclComplex start="\v^\@?\h\k*%(\s|\\\n)+%([+*$]+%(\s|\\\n)*)*\h" end="\v%(:\=@!)@=|$"
110 \ transparent
111 \ contains=justRecipeName,justParameter
112 \ nextgroup=justRecipeNoDeps,justRecipeDeps
113
114syn match justRecipeName "\v^\@?\h\k*" transparent contained contains=justRecipeAt,justFunction
115
116syn match justParameter "\v%(\s|\\\n)@3<=%(%([*+]%(\s|\\\n)*)?%(\$%(\s|\\\n)*)?|\$%(\s|\\\n)*[*+]%(\s|\\\n)*)\h\k*"
117 \ transparent contained
118 \ contains=justName,justVariadicPrefix,justParamExport,justVariadicPrefixError
119 \ nextgroup=justPreParamValue
120
121syn match justPreParamValue '\v%(\s|\\\n)*\=%(\s|\\\n)*'
122 \ contained transparent
123 \ contains=justParameterOperator
124 \ nextgroup=justParamValue
125
126syn region justParamValue contained transparent
127 \ start="\v\S"
128 \ skip="\\\n"
129 \ end="\v%(\s|^)%([*+$:]|\h)@=|:@=|$"
130 \ contains=@justAllStrings,justRecipeParenDefault,@justExprFunc
131 \ nextgroup=justParameterError
132syn match justParameterOperator "\V=" contained
133
134syn match justVariadicPrefix "\v%(\s|\\\n)@3<=[*+]%(%(\s|\\\n)*\$?%(\s|\\\n)*\h)@=" contained
135syn match justParamExport '\V$' contained
136syn match justVariadicPrefixError "\v\$%(\s|\\\n)*[*+]" contained
137
138syn match justParameterError "\v%(%([+*$]+%(\s|\\\n)*)*\h\k*)@>%(%(\s|\\\n)*\=)@!" contained
139
140syn region justRecipeParenDefault
141 \ matchgroup=justRecipeDepParamsParen start='\v%(\=%(\s|\\\n)*)@<=\(' end='\V)'
142 \ contained
143 \ contains=@justExpr
144syn match justRecipeSubsequentDeps '\V&&' contained
145
146syn match justRecipeNoDeps '\v:%(\s|\\\n)*\n|:#@=|:%(\s|\\\n)+#@='
147 \ transparent contained
148 \ contains=justRecipeColon
149 \ nextgroup=justPreBodyComment,@justBodies
150syn region justRecipeDeps start="\v:%(\s|\\\n)*%([a-zA-Z_(]|\&\&)" skip='\\\n' end="\v#@=|\\@1<!\n"
151 \ transparent contained
152 \ contains=justFunction,justRecipeColon,justRecipeSubsequentDeps,justRecipeParamDep
153 \ nextgroup=justPreBodyComment,@justBodies
154
155syn region justRecipeParamDep contained transparent
156 \ matchgroup=justRecipeDepParamsParen
157 \ start="\V("
158 \ end="\V)"
159 \ contains=justRecipeDepParenName,@justExpr
160
161syn keyword justBoolean true false contained
162
163syn match justAssignment "\v^\h\k*%(\s|\\\n)*:\=" transparent contains=justAssignmentOperator
164
165syn match justSet '\v^set' contained
166syn keyword justSetKeywords
167 \ allow-duplicate-recipes allow-duplicate-variables dotenv-load dotenv-filename dotenv-path dotenv-required export fallback ignore-comments positional-arguments quiet script-interpreter shell tempdir unstable windows-shell working-directory
168 \ contained
169syn keyword justSetDeprecatedKeywords windows-powershell contained
170syn match justBooleanSet "\v^set%(\s|\\\n)+%(allow-duplicate-%(recip|variabl)es|dotenv-%(loa|require)d|export|fallback|ignore-comments|positional-arguments|quiet|unstable|windows-powershell)%(%(\s|\\\n)*:\=%(\s|\\\n)*%(true|false))?%(\s|\\\n)*%($|#@=)"
171 \ contains=justSet,justSetKeywords,justSetDeprecatedKeywords,justAssignmentOperator,justBoolean
172 \ transparent
173
174syn match justStringSet '\v^set%(\s|\\\n)+\k+%(\s|\\\n)*:\=%(\s|\\\n)*%(x?['"])@=' transparent contains=justSet,justSetKeywords,justAssignmentOperator
175
176syn match justShellSet
177 \ "\v^set%(\s|\\\n)+%(s%(hell|cript-interpreter)|windows-shell)%(\s|\\\n)*:\=%(\s|\\\n)*\[@="
178 \ contains=justSet,justSetKeywords,justAssignmentOperator
179 \ transparent skipwhite
180 \ nextgroup=justShellSetValue
181syn region justShellSetValue
182 \ start='\V[' end='\V]'
183 \ contained
184 \ contains=@justStringLiterals,justShellSetError
185
186syn match justShellSetError '\v\k+['"]@!' contained
187
188syn match justAlias '\v^alias' contained
189syn match justAliasDecl "\v^alias%(\s|\\\n)+\h\k*%(\s|\\\n)*:\=%(\s|\\\n)*"
190 \ transparent
191 \ contains=justAlias,justFunction,justAssignmentOperator
192 \ nextgroup=justAliasRes
193syn match justAliasRes '\v\h\k*%(\s|\\\n)*%(#@=|$)' contained transparent contains=justFunction
194
195syn match justExportedAssignment "\v^export%(\s|\\\n)+\h\k*%(\s|\\\n)*:\=" transparent
196 \ contains=justExport,justAssignmentOperator
197
198syn match justExport '\v^export' contained
199
200syn match justUnexportStatement '\v^unexport%(\s|\\\n)+\w+\s*$' contains=justUnexport
201syn match justUnexport '\v^unexport' contained
202
203syn keyword justConditional if else
204syn region justConditionalBraces start="\v\{\{@!" end="\v\}@=" transparent contains=@justExpr
205syn region justConditionalBracesInInterp start="\v\{\{@!" end="\v\}@=" transparent contained contains=@justExprInInterp
206
207syn match justLineLeadingSymbol "\v^%(\\\n)@3<!\s+\zs%(\@-|-\@|\@|-)"
208
209syn match justLineContinuation "\\$"
210 \ containedin=ALLBUT,justComment,justCommentInBody,justShebang,@justRawStrings,justRecipeAttrArgError,justShellExpandRawDefaultValue
211
212syn region justBody
213 \ start=/\v^\z( +|\t+)%(#!)@!\S/
214 \ skip='\v\\\n|\n\s*$'
215 \ end="\v\n\z1@!|%(^\S)@2<=\_.@="
216 \ contains=justInterpolation,@justOtherCurlyBraces,justLineLeadingSymbol,justCommentInBody,justStringInsideBody,justIndentError
217 \ contained
218
219syn region justShebangBody
220 \ start="\v^\z( +|\t+)#!"
221 \ skip='\v\\\n|\n\s*$'
222 \ end="\v\n\z1@!|%(^\S)@2<=\_.@="
223 \ contains=justInterpolation,@justOtherCurlyBraces,justCommentInBody,justShebang,justStringInShebangBody,justShebangIndentError
224 \ contained
225
226syn cluster justBodies contains=justBody,justShebangBody
227
228syn match justIndentError '\v^%(\\\n)@3<!%( +\zs\t|\t+\zs )\s*\S@='
229syn match justShebangIndentError '\v^ +\zs\t\s*\S@='
230
231syn region justInterpolation
232 \ matchgroup=justInterpolationDelim
233 \ start="\v\{\{\{@!" end="\v%(%(\\\n\s|\S)\s*)@<=\}\}|$"
234 \ matchgroup=justInterpError end='^\S'
235 \ contained
236 \ contains=@justExprInInterp
237
238syn match justBadCurlyBraces '\v\{{3}\ze[^{]' contained
239syn match justCurlyBraces '\v\{{4}' contained
240syn match justBadCurlyBraces '\v\{{5}\ze[^{]' contained
241syn cluster justOtherCurlyBraces contains=justCurlyBraces,justBadCurlyBraces
242
243syn match justFunctionCall "\v\w+%(\s|\\\n)*\(@=" transparent contains=justBuiltInFunction
244
245" error() is intentionally not included in this list
246syn keyword justBuiltInFunction
247 \ absolute_path append arch blake3 blake3_file cache_dir cache_directory canonicalize capitalize choose clean config_dir config_directory config_local_dir config_local_directory data_dir data_directory data_local_dir data_local_directory datetime datetime_utc encode_uri_component env env_var env_var_or_default executable_dir executable_directory extension file_name file_stem home_dir home_directory invocation_dir invocation_dir_native invocation_directory invocation_directory_native is_dependency join just_executable just_pid justfile justfile_dir justfile_directory kebabcase lowercamelcase lowercase module_dir module_directory module_file num_cpus os os_family parent_dir parent_directory path_exists prepend quote replace replace_regex semver_matches sha256 sha256_file shell shoutykebabcase shoutysnakecase snakecase source_dir source_directory source_file style titlecase trim trim_end trim_end_match trim_end_matches trim_start trim_start_match trim_start_matches uppercamelcase uppercase uuid without_extension
248 \ contained
249
250syn match justUserDefinedError "\v%(assert|error)%(%(\s|\\\n)*\()@="
251
252syn match justReplaceRegex '\vreplace_regex%(\s|\\\n)*\(@=' transparent contains=justBuiltInFunction nextgroup=justReplaceRegexCall
253syn match justReplaceRegexInInterp '\vreplace_regex%(\s|\\\n)*\(@=' transparent contained contains=justBuiltInFunction nextgroup=justReplaceRegexCallInInterp
254
255syn region justReplaceRegexCall
256 \ matchgroup=justReplaceRegexCall
257 \ start='\V(' end='\V)'
258 \ transparent contained
259 \ contains=@justExpr,justRegexReplacement
260syn region justReplaceRegexCallInInterp
261 \ matchgroup=justReplaceRegexCall
262 \ start='\V(' end='\V)'
263 \ transparent contained
264 \ contains=@justExprInInterp,justRegexReplacement
265
266syn match justParameterLineContinuation '\v%(\s|\\\n)*' contained nextgroup=justParameterError
267
268syn match justRecipeDepParenName '\v%(\(\n?)@3<=%(\_s|\\\n)*\h\k*'
269 \ transparent contained
270 \ contains=justFunction
271
272syn cluster justBuiltInFunctions contains=justFunctionCall,justUserDefinedError
273
274syn match justConditionalOperator "\V=="
275syn match justConditionalOperator "\V!="
276syn match justConditionalOperator "\V=~"
277
278syn match justOperator "\V+"
279syn match justOperator "\V/"
280syn match justOperator "\V&&"
281syn match justOperator "\V||"
282
283syn keyword justConstant
284 \ HEX HEXLOWER HEXUPPER
285 \ CLEAR NORMAL BOLD ITALIC UNDERLINE INVERT HIDE STRIKETHROUGH
286 \ BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE
287 \ BG_BLACK BG_RED BG_GREEN BG_YELLOW BG_BLUE BG_MAGENTA BG_CYAN BG_WHITE
288
289syn match justShellExpandVarRaw '\v\$%(\{\_[^}]*\}|\w+)' contained contains=justShellExpandRawDefaultDelimiter
290syn match justShellExpandRawDefaultDelimiter '\V:-' contained nextgroup=justShellExpandRawDefaultValue
291syn match justShellExpandRawDefaultValue '\v\_[^}]*' contained
292syn match justShellExpandVar '\v\$%(\w|\\\n\s*)+' contained
293syn region justShellExpandVar start='\v\$%(\\\n\s*)*\{' end='\V}' contains=justShellExpandDefaultDelimiter,justStringEscapeSequence,justStringUEscapeSequence,justStringEscapeError
294syn match justShellExpandDefaultDelimiter '\v:%(\\\n\s*)*-@=' contained nextgroup=justShellExpandDefault
295syn region justShellExpandDefault
296 \ matchgroup=justShellExpandDefaultDelimiter start='\V-' end='\v\}@='
297 \ contained
298 \ contains=justStringEscapeSequence,justStringUEscapeSequence,justStringEscapeError
299
300syn match justDollarEscape '\V$$' contained
301syn match justDollarEscapeSplit '\v\$%(\\\n\s*)*\$' contained
302
303syn cluster justExprBase contains=@justAllStrings,@justBuiltInFunctions,justConditional,justConditionalOperator,justOperator,justConstant
304syn cluster justExpr contains=@justExprBase,justExprParen,justConditionalBraces,justReplaceRegex
305syn cluster justExprInInterp contains=@justExprBase,justName,justExprParenInInterp,justConditionalBracesInInterp,justReplaceRegexInInterp
306
307syn cluster justExprFunc contains=@justBuiltInFunctions,justReplaceRegex,justExprParen
308
309syn match justImport /\v^import%(%(\s|\\\n)*\?|%(\s|\\\n)+%(x?['"])@=)/ transparent
310 \ contains=justImportStatement,justOptionalFile
311syn match justImportStatement '^import' contained
312
313syn match justOldInclude "^!include"
314
315syn match justModule /\v^mod%(%(\s|\\\n)*\?)?%(\s|\\\n)+\h\k*\s*%($|%(\s|\\\n)*%(x?['"]|#)@=)/
316 \ transparent contains=justModStatement,justName,justOptionalFile
317syn match justModStatement '^mod' contained
318
319syn match justOptionalFile '\V?' contained
320
321" Most linked colorscheme colors are chosen based on semantics of the color name.
322" Some are for parity with other syntax files (for example, Number for recipe body highlighting
323" is to align with the make.vim distributed with Vim).
324" Deprecated `just` syntaxes are highlighted as Underlined.
325"
326" Colors are linked 'def'(ault) so that users who prefer other colors
327" can override them, e.g. in ~/.vim/after/syntax/just.vim
328"
329" Note that vim-just's highlight groups are an implementation detail and may be subject to change.
330
331" The list of highlight links is sorted alphabetically.
332
333hi def link justAlias Statement
334hi def link justAssignmentOperator Operator
335hi def link justBacktick Special
336hi def link justBadCurlyBraces Error
337hi def link justBody Number
338hi def link justBoolean Boolean
339hi def link justBuiltInFunction Function
340hi def link justComment Comment
341hi def link justCommentInBody Comment
342hi def link justCommentTodo Todo
343hi def link justConditional Conditional
344hi def link justConditionalOperator Conditional
345hi def link justConstant Constant
346hi def link justCurlyBraces Special
347hi def link justDollarEscape Special
348hi def link justDollarEscapeSplit Special
349hi def link justExport Statement
350hi def link justFunction Function
351hi def link justImportStatement Include
352hi def link justIndentError Error
353hi def link justInterpError Error
354hi def link justInterpolation Normal
355hi def link justInterpolationDelim Delimiter
356hi def link justInvalidAttrValue Error
357hi def link justLineContinuation Special
358hi def link justLineLeadingSymbol Special
359hi def link justModStatement Keyword
360hi def link justName Identifier
361hi def link justOldInclude Error
362hi def link justOperator Operator
363hi def link justOptionalFile Conditional
364hi def link justParameterError Error
365hi def link justParameterOperator Operator
366hi def link justParamExport Statement
367hi def link justRawString String
368hi def link justRawStrRegexRepl String
369hi def link justRecipeAt Special
370hi def link justRecipeAttr Type
371hi def link justRecipeAttrArgError Error
372hi def link justRecipeAttrSep Operator
373hi def link justRecipeAttrValueColon Operator
374hi def link justRecipeColon Operator
375hi def link justRecipeDepParamsParen Delimiter
376hi def link justRecipeSubsequentDeps Delimiter
377hi def link justRegexCapture Identifier
378hi def link justSet Statement
379hi def link justSetDeprecatedKeywords Underlined
380hi def link justSetKeywords Keyword
381hi def link justShebang SpecialComment
382hi def link justShebangBody Number
383hi def link justShebangIndentError Error
384hi def link justShellExpandDefault Character
385hi def link justShellExpandDefaultDelimiter Operator
386hi def link justShellExpandRawDefaultDelimiter Operator
387hi def link justShellExpandRawDefaultValue Character
388hi def link justShellExpandRawString String
389hi def link justShellExpandString String
390hi def link justShellExpandVar PreProc
391hi def link justShellExpandVarRaw PreProc
392hi def link justShellSetError Error
393hi def link justString String
394hi def link justStringEscapeError Error
395hi def link justStringEscapeSequence Special
396hi def link justStringInShebangBody String
397hi def link justStringInsideBody String
398hi def link justStringRegexRepl String
399hi def link justStringUEscapeSequence Special
400hi def link justUnexport Statement
401hi def link justUserDefinedError Exception
402hi def link justVariadicPrefix Statement
403hi def link justVariadicPrefixError Error
404
Peter Benjamin509a8d52025-01-25 15:26:09 +0100405let &cpo = s:cpo_save
406unlet s:cpo_save