1{-# LANGUAGE DeriveDataTypeable #-}
2{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3{-# LANGUAGE LambdaCase #-}
5-- | Functions for working with comment stream.
7module Ormolu.CommentStream
15import Data.Data (Data)
16import Data.List (isPrefixOf, sortOn)
17import Data.List.NonEmpty (NonEmpty (..))
18import Data.Maybe (mapMaybe)
20import qualified Data.List.NonEmpty as NE
22import qualified Lexer as GHC
24-- | A stream of 'RealLocated' 'Comment's in ascending order with respect to
25-- beginning of corresponding spans.
27newtype CommentStream = CommentStream [RealLocated Comment]
28 deriving (Eq, Data, Semigroup, Monoid)
30-- | A wrapper for a single comment. The 'NonEmpty' list inside contains
31-- lines of multiline comment @{- … -}@ or just single item\/line otherwise.
33newtype Comment = Comment (NonEmpty String)
34 deriving (Eq, Show, Data)
36-- | Create 'CommentStream' from 'GHC.PState'.
39 :: [Located String] -- ^ Extra comments to include
40 -> GHC.PState -- ^ Parser state to use for comment extraction
42mkCommentStream extraComments pstate
44 -- NOTE It's easier to normalize pragmas right when we construct comment
45 -- streams. Because this way we need to do it only once and when we
46 -- perform checking later they'll automatically match.
47 . fmap (fmap (Comment . normalizeComment . normalizePragma))
49 . mapMaybe toRealSpan $
51 (fmap unAnnotationComment <$> GHC.comment_q pstate) ++
52 concatMap (fmap (fmap unAnnotationComment) . snd)
53 (GHC.annotations_comments pstate)
55 startOfSpan (L l _) = realSrcSpanStart l
56 toRealSpan (L (RealSrcSpan l) a) = Just (L l a)
57 toRealSpan _ = Nothing
59-- | Test whether a 'Comment' looks like a Haddock following a definition,
60-- i.e. something starting with @-- ^@.
62isPrevHaddock :: Comment -> Bool
63isPrevHaddock (Comment (x :| _)) = "-- ^" `isPrefixOf` x
65----------------------------------------------------------------------------
68-- | Normalize pragmas by deleting extra white space.
70normalizePragma :: String -> String
72 if "{-#" `isPrefixOf` x
73 then unwords (words x)
76-- | Normalize comment string. Sometimes one multi-line comment is turned
77-- into several lines for subsequent outputting with correct indentation for
80normalizeComment :: String -> NonEmpty String
82 case NE.nonEmpty (lines s) of
84 Just xs -> dropWhile (== ' ') <$> xs
86-- | Get a 'String' from 'GHC.AnnotationComment'.
88unAnnotationComment :: GHC.AnnotationComment -> String
89unAnnotationComment = \case
90 GHC.AnnDocCommentNext s -> s
91 GHC.AnnDocCommentPrev s -> s
92 GHC.AnnDocCommentNamed s -> s
93 GHC.AnnDocSection _ s -> s
94 GHC.AnnDocOptions s -> s
95 GHC.AnnLineComment s -> s
96 GHC.AnnBlockComment s -> s
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list