Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when carriage return used as linebreak in comment #175

Open
9999years opened this issue Mar 27, 2024 · 3 comments
Open

Error when carriage return used as linebreak in comment #175

9999years opened this issue Mar 27, 2024 · 3 comments
Labels
bug Something isn't working correctness Output parses differently after formatting

Comments

@9999years
Copy link

Description

nixfmt errors when a carriage return is used as a linebreak in a comment.

Small example input

{
  x = #^M1;
}

(Where ^M is a literal carriage return character.)

We can see that nix-instantiate parses the file OK:

$ xxd crlf.nix
00000000: 7b0a 2020 7820 3d20 230d 313b 0a7d 0a    {.  x = #.1;.}.
$ nix-instantiate --parse crlf.nix
{ x = 1; }

Actual output

crlf.nix:2:8:
  |
1;|   x = #
  |        ^^^^
unexpected "<carriage return>1;<newline>}<newline>"
expecting expression
@piegamesde
Copy link
Member

Whatever kind of dark magic Nix does here, I'd say that not implementing that and giving an error is an acceptable thing to do here

@tomberek
Copy link
Contributor

Likely the carriage return stops the one-line comment: https://github.com/NixOS/nix/blob/master/src/libexpr/lexer.l#L284

eol from Megaparsec only understands \n. Something like this might work, but change things elsewhere? position values might get messed up? Have to make sure the "\r\n" sequence is replaced first.

diff --git a/src/Nixfmt/Lexer.hs b/src/Nixfmt/Lexer.hs
index b331359..996e847 100644
--- a/src/Nixfmt/Lexer.hs
+++ b/src/Nixfmt/Lexer.hs
@@ -17,7 +17,7 @@ import Data.Text as Text
 import Text.Megaparsec
   (SourcePos(..), anySingle, chunk, getSourcePos, hidden, many, manyTill, some,
   try, unPos, (<|>))
-import Text.Megaparsec.Char (eol)
+import Text.Megaparsec.Char (string, eol)
 
 import Nixfmt.Types (Ann(..), Parser, TrailingComment(..), Trivia, Trivium(..))
 import Nixfmt.Util (manyP)
@@ -32,7 +32,7 @@ preLexeme :: Parser a -> Parser a
 preLexeme p = p <* manyP (\x -> isSpace x && x /= '\n' && x /= '\r')
 
 newlines :: Parser ParseTrivium
-newlines = PTNewlines <$> Prelude.length <$> some (preLexeme eol)
+newlines = PTNewlines <$> Prelude.length <$> some (preLexeme (eol <|> string "\r"))
 
 splitLines :: Text -> [Text]
 splitLines = dropWhile Text.null . dropWhileEnd Text.null

@infinisil infinisil moved this to Todo in Nix formatting May 28, 2024
@dasJ dasJ added the bug Something isn't working label Jun 26, 2024
@piegamesde
Copy link
Member

Single \r carriage returns which are not followed by a line feed are effectively unsupported by Nix (= buggy arbitrary behavior) and thus won't be supported by Nixfmt. Any bugs in Nixfmt on files with CLRF line endings however should be handled.

@piegamesde piegamesde added the correctness Output parses differently after formatting label Dec 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working correctness Output parses differently after formatting
Projects
Status: Todo
Development

No branches or pull requests

4 participants