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