diff --git a/src/Nixfmt/Parser.hs b/src/Nixfmt/Parser.hs index f424876f..9dbcae53 100644 --- a/src/Nixfmt/Parser.hs +++ b/src/Nixfmt/Parser.hs @@ -193,50 +193,17 @@ indentedStringPart :: Parser StringPart indentedStringPart = TextPart <$> someText - ( {- - This should match https://github.com/NixOS/nix/blob/052f1320ddf72d617e337479ff1bf22cb4ee682a/src/libexpr/lexer.l#L182-L205 - To understand that file, [this](https://westes.github.io/flex/manual/Matching.html#Matching) is important: - > If it finds more than one match, it takes the one matching the most text. - > If it finds two or more matches of the same length, the rule listed first in the flex input file is chosen. - - There are some inconsequential differences though: - - We only parse one line at a time here, so we make sure to not process any newlines - - We don't want to transform the input in any way, e.g. don't turn ''' into '' - This is to preserve the input string as-is - -} - - -- ([^\$\']|\$[^\{\']|\'[^\'\$])+ - -- While this rule doesn't have a fixed length, it's non-conflicting with the rules below, - -- so we can do it first without worrying about the length matching - someText - ( Text.singleton - <$> satisfy (\t -> t /= '$' && t /= '\'' && t /= '\n') - <|> try (Text.snoc <$> chunk "$" <*> satisfy (\t -> t /= '{' && t /= '\'' && t /= '\n')) - <|> try (Text.snoc <$> chunk "'" <*> satisfy (\t -> t /= '\'' && t /= '$' && t /= '\n')) - ) - -- These rules are of length 3, they need to come before shorter ones - -- \'\'\$ - <|> chunk "''$" - -- \'\'\' - <|> chunk "'''" - -- \'\'\\{ANY} -> Note that ANY can match newlines as well, but we need to ignore those - <|> do - prefix <- chunk "''\\" - -- If we do have a newline - rest <- - -- If there's no newline, take the next character - (notFollowedBy (char '\n') *> (Text.singleton <$> anySingle)) - -- Otherwise there's an unconsumed newline, which we don't need to handle, - -- it's consumed elsewhere - <|> pure "" - pure $ prefix <> rest - -- These are rules with length 2 and 1 - -- \$\{ -> don't match, this will be an interpolation - -- \$ -> do match, just a dollar - <|> try (chunk "$" <* notFollowedBy (char '{')) - -- \'\' -> don't match, indented string ends - -- \' -> do match, just a quote - <|> try (chunk "'" <* notFollowedBy (char '\'')) + ( chunk "''\\n" + <|> chunk "''\\r" + <|> chunk "''\\t" + <|> chunk "''\\" + *> (Text.singleton <$> anySingle) + <|> chunk "''$" + <|> chunk "'''" + <|> chunk "$$" + <|> try (chunk "$" <* notFollowedBy (char '{')) + <|> try (chunk "'" <* notFollowedBy (char '\'')) + <|> someP (\t -> t /= '\'' && t /= '$' && t /= '\n') ) indentedLine :: Parser [StringPart] diff --git a/test/correct/indented-string.nix b/test/correct/indented-string.nix deleted file mode 100644 index 0e7eb5a7..00000000 --- a/test/correct/indented-string.nix +++ /dev/null @@ -1,14 +0,0 @@ -# These come from previous parser bugs in Nix -[ - '' - ''\a - ''\ - - '${true}' - - $'\t' - '' - - ''ending dollar $'' - ''$'' -] diff --git a/test/correct/regression-197.nix b/test/correct/regression-197.nix deleted file mode 100644 index 66666b89..00000000 --- a/test/correct/regression-197.nix +++ /dev/null @@ -1,3 +0,0 @@ -'' - ''\'''${A} -''