blob: c07676a4a813777d0b8b69649853ccf00819b8da [file] [log] [blame]
Bram Moolenaar86b48162022-12-06 18:20:10 +00001" Vim syntax file
2" Language: Nix
3" Maintainer: James Fleming <james@electronic-quill.net>
4" Original Author: Daiderd Jordan <daiderd@gmail.com>
5" Acknowledgement: Based on vim-nix maintained by Daiderd Jordan <daiderd@gmail.com>
6" https://github.com/LnL7/vim-nix
7" License: MIT
8" Last Change: 2022 Dec 06
9
10if exists("b:current_syntax")
11 finish
12endif
13
14let s:cpo_save = &cpo
15set cpo&vim
16
17syn keyword nixBoolean true false
18syn keyword nixNull null
19syn keyword nixRecKeyword rec
20
21syn keyword nixOperator or
22syn match nixOperator '!=\|!'
23syn match nixOperator '<=\?'
24syn match nixOperator '>=\?'
25syn match nixOperator '&&'
26syn match nixOperator '//\='
27syn match nixOperator '=='
28syn match nixOperator '?'
29syn match nixOperator '||'
30syn match nixOperator '++\='
31syn match nixOperator '-'
32syn match nixOperator '\*'
33syn match nixOperator '->'
34
35syn match nixParen '[()]'
36syn match nixInteger '\d\+'
37
38syn keyword nixTodo FIXME NOTE TODO OPTIMIZE XXX HACK contained
39syn match nixComment '#.*' contains=nixTodo,@Spell
40syn region nixComment start=+/\*+ end=+\*/+ contains=nixTodo,@Spell
41
42syn region nixInterpolation matchgroup=nixInterpolationDelimiter start="\${" end="}" contained contains=@nixExpr,nixInterpolationParam
43
44syn match nixSimpleStringSpecial /\\\%([nrt"\\$]\|$\)/ contained
45syn match nixStringSpecial /''['$]/ contained
46syn match nixStringSpecial /\$\$/ contained
47syn match nixStringSpecial /''\\[nrt]/ contained
48
49syn match nixSimpleStringSpecial /\$\$/ contained
50
51syn match nixInvalidSimpleStringEscape /\\[^nrt"\\$]/ contained
52syn match nixInvalidStringEscape /''\\[^nrt]/ contained
53
54syn region nixSimpleString matchgroup=nixStringDelimiter start=+"+ skip=+\\"+ end=+"+ contains=nixInterpolation,nixSimpleStringSpecial,nixInvalidSimpleStringEscape
55syn region nixString matchgroup=nixStringDelimiter start=+''+ skip=+''['$\\]+ end=+''+ contains=nixInterpolation,nixStringSpecial,nixInvalidStringEscape
56
57syn match nixFunctionCall "[a-zA-Z_][a-zA-Z0-9_'-]*"
58
59syn match nixPath "[a-zA-Z0-9._+-]*\%(/[a-zA-Z0-9._+-]\+\)\+"
60syn match nixHomePath "\~\%(/[a-zA-Z0-9._+-]\+\)\+"
61syn match nixSearchPath "[a-zA-Z0-9._+-]\+\%(\/[a-zA-Z0-9._+-]\+\)*" contained
62syn match nixPathDelimiter "[<>]" contained
63syn match nixSearchPathRef "<[a-zA-Z0-9._+-]\+\%(\/[a-zA-Z0-9._+-]\+\)*>" contains=nixSearchPath,nixPathDelimiter
64syn match nixURI "[a-zA-Z][a-zA-Z0-9.+-]*:[a-zA-Z0-9%/?:@&=$,_.!~*'+-]\+"
65
66syn match nixAttributeDot "\." contained
67syn match nixAttribute "[a-zA-Z_][a-zA-Z0-9_'-]*\ze\%([^a-zA-Z0-9_'.-]\|$\)" contained
68syn region nixAttributeAssignment start="=" end="\ze;" contained contains=@nixExpr
69syn region nixAttributeDefinition start=/\ze[a-zA-Z_"$]/ end=";" contained contains=nixComment,nixAttribute,nixInterpolation,nixSimpleString,nixAttributeDot,nixAttributeAssignment
70
71syn region nixInheritAttributeScope start="(" end="\ze)" contained contains=@nixExpr
72syn region nixAttributeDefinition matchgroup=nixInherit start="\<inherit\>" end=";" contained contains=nixComment,nixInheritAttributeScope,nixAttribute
73
74syn region nixAttributeSet start="{" end="}" contains=nixComment,nixAttributeDefinition
75
76" vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
77syn region nixArgumentDefinitionWithDefault matchgroup=nixArgumentDefinition start="[a-zA-Z_][a-zA-Z0-9_'-]*\ze\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*?\@=" matchgroup=NONE end="[,}]\@=" transparent contained contains=@nixExpr
78" vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
79syn match nixArgumentDefinition "[a-zA-Z_][a-zA-Z0-9_'-]*\ze\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*[,}]\@=" contained
80syn match nixArgumentEllipsis "\.\.\." contained
81syn match nixArgumentSeparator "," contained
82
83" vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
84syn match nixArgOperator '@\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*[a-zA-Z_][a-zA-Z0-9_'-]*\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*:'he=s+1 contained contains=nixAttribute
85
86" vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
87syn match nixArgOperator '[a-zA-Z_][a-zA-Z0-9_'-]*\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*@'hs=e-1 contains=nixAttribute nextgroup=nixFunctionArgument
88
89" This is a bit more complicated, because function arguments can be passed in a
90" very similar form on how attribute sets are defined and two regions with the
91" same start patterns will shadow each other. Instead of a region we could use a
92" match on {\_.\{-\}}, which unfortunately doesn't take nesting into account.
93"
94" So what we do instead is that we look forward until we are sure that it's a
95" function argument. Unfortunately, we need to catch comments and both vertical
96" and horizontal white space, which the following regex should hopefully do:
97"
98" "\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*"
99"
100" It is also used throught the whole file and is marked with 'v's as well.
101"
102" Fortunately the matching rules for function arguments are much simpler than
103" for real attribute sets, because we can stop when we hit the first ellipsis or
104" default value operator, but we also need to paste the "whitespace & comments
105" eating" regex all over the place (marked with 'v's):
106"
107" Region match 1: { foo ? ... } or { foo, ... } or { ... } (ellipsis)
108" vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv {----- identifier -----}vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
109syn region nixFunctionArgument start="{\ze\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*\%([a-zA-Z_][a-zA-Z0-9_'-]*\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*[,?}]\|\.\.\.\)" end="}" contains=nixComment,nixArgumentDefinitionWithDefault,nixArgumentDefinition,nixArgumentEllipsis,nixArgumentSeparator nextgroup=nixArgOperator
110
111" Now it gets more tricky, because we need to look forward for the colon, but
112" there could be something like "{}@foo:", even though it's highly unlikely.
113"
114" Region match 2: {}
115" vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv@vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv{----- identifier -----} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
116syn region nixFunctionArgument start="{\ze\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*}\%(\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*@\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*[a-zA-Z_][a-zA-Z0-9_'-]*\)\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*:" end="}" contains=nixComment nextgroup=nixArgOperator
117
118" vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
119syn match nixSimpleFunctionArgument "[a-zA-Z_][a-zA-Z0-9_'-]*\ze\%(\s\|#.\{-\}\n\|\n\|/\*\_.\{-\}\*/\)*:\([\n ]\)\@="
120
121syn region nixList matchgroup=nixListBracket start="\[" end="\]" contains=@nixExpr
122
123syn region nixLetExpr matchgroup=nixLetExprKeyword start="\<let\>" end="\<in\>" contains=nixComment,nixAttributeDefinition
124
125syn keyword nixIfExprKeyword then contained
126syn region nixIfExpr matchgroup=nixIfExprKeyword start="\<if\>" end="\<else\>" contains=@nixExpr,nixIfExprKeyword
127
128syn region nixWithExpr matchgroup=nixWithExprKeyword start="\<with\>" matchgroup=NONE end=";" contains=@nixExpr
129
130syn region nixAssertExpr matchgroup=nixAssertKeyword start="\<assert\>" matchgroup=NONE end=";" contains=@nixExpr
131
132syn cluster nixExpr contains=nixBoolean,nixNull,nixOperator,nixParen,nixInteger,nixRecKeyword,nixConditional,nixBuiltin,nixSimpleBuiltin,nixComment,nixFunctionCall,nixFunctionArgument,nixArgOperator,nixSimpleFunctionArgument,nixPath,nixHomePath,nixSearchPathRef,nixURI,nixAttributeSet,nixList,nixSimpleString,nixString,nixLetExpr,nixIfExpr,nixWithExpr,nixAssertExpr,nixInterpolation
133
134" These definitions override @nixExpr and have to come afterwards:
135
136syn match nixInterpolationParam "[a-zA-Z_][a-zA-Z0-9_'-]*\%(\.[a-zA-Z_][a-zA-Z0-9_'-]*\)*" contained
137
138" Non-namespaced Nix builtins as of version 2.0:
139syn keyword nixSimpleBuiltin
140 \ abort baseNameOf derivation derivationStrict dirOf fetchGit
141 \ fetchMercurial fetchTarball import isNull map mapAttrs placeholder removeAttrs
142 \ scopedImport throw toString
143
144
145" Namespaced and non-namespaced Nix builtins as of version 2.0:
146syn keyword nixNamespacedBuiltin contained
147 \ abort add addErrorContext all any attrNames attrValues baseNameOf
148 \ catAttrs compareVersions concatLists concatStringsSep currentSystem
149 \ currentTime deepSeq derivation derivationStrict dirOf div elem elemAt
150 \ fetchGit fetchMercurial fetchTarball fetchurl filter \ filterSource
151 \ findFile foldl' fromJSON functionArgs genList \ genericClosure getAttr
152 \ getEnv hasAttr hasContext hashString head import intersectAttrs isAttrs
153 \ isBool isFloat isFunction isInt isList isNull isString langVersion
154 \ length lessThan listToAttrs map mapAttrs match mul nixPath nixVersion
155 \ parseDrvName partition path pathExists placeholder readDir readFile
156 \ removeAttrs replaceStrings scopedImport seq sort split splitVersion
157 \ storeDir storePath stringLength sub substring tail throw toFile toJSON
158 \ toPath toString toXML trace tryEval typeOf unsafeDiscardOutputDependency
159 \ unsafeDiscardStringContext unsafeGetAttrPos valueSize fromTOML bitAnd
160 \ bitOr bitXor floor ceil
161
162syn match nixBuiltin "builtins\.[a-zA-Z']\+"he=s+9 contains=nixComment,nixNamespacedBuiltin
163
164hi def link nixArgOperator Operator
165hi def link nixArgumentDefinition Identifier
166hi def link nixArgumentEllipsis Operator
167hi def link nixAssertKeyword Keyword
168hi def link nixAttribute Identifier
169hi def link nixAttributeDot Operator
170hi def link nixBoolean Boolean
171hi def link nixBuiltin Special
172hi def link nixComment Comment
173hi def link nixConditional Conditional
174hi def link nixHomePath Include
175hi def link nixIfExprKeyword Keyword
176hi def link nixInherit Keyword
177hi def link nixInteger Integer
178hi def link nixInterpolation Macro
179hi def link nixInterpolationDelimiter Delimiter
180hi def link nixInterpolationParam Macro
181hi def link nixInvalidSimpleStringEscape Error
182hi def link nixInvalidStringEscape Error
183hi def link nixLetExprKeyword Keyword
184hi def link nixNamespacedBuiltin Special
185hi def link nixNull Constant
186hi def link nixOperator Operator
187hi def link nixPath Include
188hi def link nixPathDelimiter Delimiter
189hi def link nixRecKeyword Keyword
190hi def link nixSearchPath Include
191hi def link nixSimpleBuiltin Keyword
192hi def link nixSimpleFunctionArgument Identifier
193hi def link nixSimpleString String
194hi def link nixSimpleStringSpecial SpecialChar
195hi def link nixString String
196hi def link nixStringDelimiter Delimiter
197hi def link nixStringSpecial Special
198hi def link nixTodo Todo
199hi def link nixURI Include
200hi def link nixWithExprKeyword Keyword
201
202" This could lead up to slow syntax highlighting for large files, but usually
203" large files such as all-packages.nix are one large attribute set, so if we'd
204" use sync patterns we'd have to go back to the start of the file anyway
205syn sync fromstart
206
207let b:current_syntax = "nix"
208
209let &cpo = s:cpo_save
210unlet s:cpo_save