@@ -26,7 +26,7 @@ import qualified Text.Megaparsec.Char.Lexer as L (decimal)
26
26
27
27
import Nixfmt.Lexer (lexeme )
28
28
import Nixfmt.Types
29
- (Ann , Binder (.. ), Expression (.. ), File (.. ), Fixity (.. ), Leaf , Operator (.. ),
29
+ (Ann ( .. ) , Binder (.. ), Expression (.. ), File (.. ), Fixity (.. ), Leaf , Operator (.. ),
30
30
ParamAttr (.. ), Parameter (.. ), Parser , Path , Selector (.. ), SimpleSelector (.. ),
31
31
String , StringPart (.. ), Term (.. ), Token (.. ), operators , tokenText )
32
32
import Nixfmt.Parser.Float (floatParse )
@@ -103,6 +103,21 @@ interpolation :: Parser StringPart
103
103
interpolation = Interpolation <$>
104
104
symbol TInterOpen <*> expression <*> rawSymbol TInterClose
105
105
106
+ -- Interpolation, but only allowing identifiers and simple strings inside
107
+ interpolationRestricted :: Parser StringPart
108
+ interpolationRestricted = Interpolation <$>
109
+ symbol TInterOpen <*>
110
+ -- simple string without dynamic interpolations
111
+ (Term <$> String <$> do
112
+ str <- string
113
+ guard $ not $ containsInterpolation str
114
+ return str
115
+ ) <*>
116
+ rawSymbol TInterClose
117
+ where
118
+ containsInterpolation (Ann str _ _) =
119
+ any (\ part -> case part of { Interpolation _ _ _ -> True ; _ -> False }) $ concat str
120
+
106
121
simpleStringPart :: Parser StringPart
107
122
simpleStringPart = TextPart <$> someText (
108
123
chunk " \\ n" *> pure " \n " <|>
@@ -214,18 +229,25 @@ parens :: Parser Term
214
229
parens = Parenthesized <$>
215
230
symbol TParenOpen <*> expression <*> symbol TParenClose
216
231
232
+ simpleSelector :: Parser StringPart -> Parser SimpleSelector
233
+ simpleSelector parseInterpolation =
234
+ ((IDSelector <$> identifier) <|>
235
+ (InterpolSelector <$> lexeme parseInterpolation) <|>
236
+ (StringSelector <$> lexeme simpleString))
237
+
217
238
selector :: Maybe (Parser Leaf ) -> Parser Selector
218
239
selector parseDot = Selector <$>
219
- sequence parseDot <* notFollowedBy path <*>
220
- ((IDSelector <$> identifier) <|>
221
- (InterpolSelector <$> lexeme interpolation) <|>
222
- (StringSelector <$> lexeme simpleString)) <*>
223
- optional (liftM2 (,) (reserved KOr ) term)
240
+ sequence parseDot <* notFollowedBy path <*> simpleSelector interpolation
224
241
225
242
selectorPath :: Parser [Selector ]
226
243
selectorPath = (pure <$> selector Nothing ) <>
227
244
many (selector $ Just $ symbol TDot )
228
245
246
+ -- Path with a leading dot
247
+ selectorPath' :: Parser [Selector ]
248
+ selectorPath' = many $ try $ selector $ Just $ symbol TDot
249
+
250
+ -- Everything but selection
229
251
simpleTerm :: Parser Term
230
252
simpleTerm = (String <$> string) <|> (Path <$> path) <|>
231
253
(Token <$> (envPath <|> float <|> integer <|> identifier)) <|>
@@ -234,9 +256,11 @@ simpleTerm = (String <$> string) <|> (Path <$> path) <|>
234
256
term :: Parser Term
235
257
term = label " term" $ do
236
258
t <- simpleTerm
237
- s <- many $ try $ selector $ Just $ symbol TDot
238
- return $ case s of [] -> t
239
- _ -> Selection t s
259
+ sel <- selectorPath'
260
+ def <- optional (liftM2 (,) (reserved KOr ) term)
261
+ return $ case sel of
262
+ [] -> t
263
+ _ -> Selection t sel def
240
264
241
265
-- ABSTRACTIONS
242
266
@@ -271,7 +295,7 @@ abstraction = try (Abstraction <$>
271
295
272
296
inherit :: Parser Binder
273
297
inherit = Inherit <$> reserved KInherit <*> optional parens <*>
274
- many identifier <*> symbol TSemicolon
298
+ many (simpleSelector interpolationRestricted) <*> symbol TSemicolon
275
299
276
300
assignment :: Parser Binder
277
301
assignment = Assignment <$>
0 commit comments