Pretty-print haskell source code with comments
Asked Answered
P

2

9

I'm trying to reformat/reprint haskell source code (remove/add whitespace, linebreaks, change indention style...). I've found the package haskell-src-exts which can parse and pretty-print haskell source code.

Using the function parseFileWithComments :: ParseMode -> FilePath -> IO (ParseResult (Module, [Comment])) I also get the comments included in the source code. Now I want to print the Module/AST with the comments at the original positions, but I cannot find a function which will do that. I can only pretty-print the AST. Do I have to implement printing of the AST plus the comments myself or does such a library already exist?

To clarify consider following example:

file A.hs:

module A (fn1) where

-- | Haddock-comment
fn1 ::
    String ->
    String
fn1 _ = "" -- another comment

In ghci, typing

Prelude Control.Monad.Reader Language.Haskell.Exts> (liftM prettyPrint) $ (liftM fst) $ (liftM fromParseResult) $ parseFileWithComments defaultParseMode "A.hs"`

prints the module source code (without the comments, of course). I can use any prettyPrint-function to modify the source code formatting.

Now I want to be able to do something like this:

do
    (ast, comments) <- fromParseResult $ parseFileWithComments defaultParseMode "A.hs"
    prettyPrintWithComments ast comments

to get a pretty-printed version of the original file including the comments.

Pindling answered 22/2, 2012 at 9:55 Comment(0)
S
6

Use the Annotated versions of the modules, e.g. Language.Haskell.Exts.Annotated vs Language.Haskell.Exts.

Same answered 22/2, 2012 at 10:24 Comment(8)
That's quite helpful, but not exactly what I wanted. I still want to be able to reformat the actual source code with a configured pretty-print Style and PPHsMode.Pindling
@haja: why can't you? It's still an instance of haskell-src-ext's Pretty class...Same
but then again, how can the original comments be included in the pretty-print output? I can't find a function which pretty-prints the ast including comments.Pindling
@haja: OK, my mistake: I thought that comments were included in the AST. However, does the Language.Haskell.Exts.Annotated.ExactPrint module solve your issue?Same
sadly not, since I still want to reformat the source code, which is not possible with Language.Haskell.Exts.Annotated.ExactPrint. It only prints the source code exactly as it was before parsing.Pindling
@Pindling From that module: "The input is a (semi-concrete) abstract syntax tree, annotated with exact source information" - doesn't that mean you can modify that format syntax tree and ExactPrint will then print it according to your formatting changes?Watermark
@Watermark I'm afraid I don't really understand what you mean. There is no format syntax tree, just an abstract syntax tree. The format is applied to the printed output, not to the ast. The ast stays the same.Pindling
@Pindling I was suggesting the following: You call e.g. exactPrint m comments where m might be Module SrcLoc. You could transform m so that it looks like what you want, modifying the SrcLocs; same with the comments. Yes, that is probably tedious and complicated. I emailed the maintainer of haskell-src-exts (see hackage page), and apparently he is interested in making tasks like this more convenient. I suggested an intermediate parse tree with all information (comments and whitespace) present. Perhaps you should join the discussion.Watermark
T
3

Depending on what kind of pretty printing do you want to do, you might want to take a look at the hscolour package, which is used to colorize Haskell source code into various output formats.

In particular, the module Language.Haskell.HsColour.Classify contains a Haskell tokenizer which preserves whitespace and comments, which might serve as a good starting point.

Twobyfour answered 22/2, 2012 at 13:25 Comment(1)
thanks, but I'm not looking for this kind of pretty-printing. I updated my question to clarify what kind of pretty-printing I want.Pindling

© 2022 - 2024 — McMap. All rights reserved.