@@ -55,33 +55,52 @@ atPoint
5555 -> [SpanInfo]
5656 -> Position
5757 -> Maybe (Maybe Range, [T.Text])
58−atPoint IdeOptions{..} tcs srcSpans pos = do
59− SpanInfo{..} <- listToMaybe $ orderSpans $ spansAtPoint pos srcSpans
60− ty <- spaninfoType
61− let mbName = getNameM spaninfoSource
62− mbDefinedAt = fmap (\name -> "**Defined " <> T.pack (showSDocUnsafe $ pprNameDefnLoc name) <> "**\n") mbName
63− docInfo = maybe [] (\name -> getDocumentation name tcs) mbName
64− range = Range
65− (Position spaninfoStartLine spaninfoStartCol)
66− (Position spaninfoEndLine spaninfoEndCol)
67− colon = if optNewColonConvention then ":" else "::"
68− wrapLanguageSyntax x = T.unlines [ "```" <> T.pack optLanguageSyntax, x, "```"]
69− typeSig = wrapLanguageSyntax $ case mbName of
70− Nothing -> colon <> " " <> showName ty
71− Just name ->
72− let modulePrefix = maybe "" (<> ".") (getModuleNameAsText name)
73− in modulePrefix <> showName name <> "\n " <> colon <> " " <> showName ty
74− hoverInfo = docInfo <> [typeSig] <> maybeToList mbDefinedAt
75− return (Just range, hoverInfo)
58+atPoint IdeOptions{..} tcs pos srcSpans = do
59+ firstSpan <- listToMaybe $ deEmpasizeGeneratedEqShow $ spansAtPoint srcSpans pos
60+ return (Just (range firstSpan), hoverInfo firstSpan)
7661 where
62+ -- Hover info for types, classes, type variables
63+ hoverInfo SpanInfo{spaninfoType = Nothing , ..} =
64+ documentation <> (wrapLanguageSyntax <$> name <> kind) <> location
65+ where
66+ documentation = findDocumentation mbName
67+ name = [maybe shouldNotHappen showName mbName]
68+ location = [maybe shouldNotHappen definedAt mbName]
69+ kind = [] -- TODO
70+ shouldNotHappen = "ghcide: did not expect a type level component without a name"
71+ mbName = getNameM spaninfoSource
72+
73+ -- Hover info for values/data
74+ hoverInfo SpanInfo{spaninfoType = (Just typ), ..} =
75+ documentation <> (wrapLanguageSyntax <$> nameOrSource <> typeAnnotation) <> location
76+ where
77+ mbName = getNameM spaninfoSource
78+ documentation = findDocumentation mbName
79+ typeAnnotation = [colon <> showName typ]
80+ nameOrSource = [maybe literalSource qualifyNameIfPossible mbName]
81+ literalSource = "" -- TODO: literals: display (length-limited) source
82+ qualifyNameIfPossible name' = modulePrefix <> showName name'
83+ where modulePrefix = maybe "" (<> ".") (getModuleNameAsText name')
84+ location = [maybe "" definedAt mbName]
85+
86+ findDocumentation = maybe [] (getDocumentation tcs)
87+ definedAt name = "**Defined " <> T.pack (showSDocUnsafe $ pprNameDefnLoc name) <> "**\n"
88+
89+ range SpanInfo{..} = Range
90+ (Position spaninfoStartLine spaninfoStartCol)
91+ (Position spaninfoEndLine spaninfoEndCol)
92+
93+ colon = if optNewColonConvention then ": " else ":: "
94+ wrapLanguageSyntax x = T.unlines [ "```" <> T.pack optLanguageSyntax, x, "```"]
95+
7796 -- NOTE(RJR): This is a bit hacky.
7897 -- We don't want to show the user type signatures generated from Eq and Show
7998 -- instances, as they do not appear in the source program.
8099 -- However the user could have written an `==` or `show` function directly,
81100 -- in which case we still want to show information for that.
82101 -- Hence we just move such information later in the list of spans.
83− orderSpans :: [SpanInfo] -> [SpanInfo]
84− orderSpans = uncurry (++) . partition (not . isTypeclassDeclSpan)
102+ deEmpasizeGeneratedEqShow :: [SpanInfo] -> [SpanInfo]
103+ deEmpasizeGeneratedEqShow = uncurry (++) . partition (not . isTypeclassDeclSpan)
85104 isTypeclassDeclSpan :: SpanInfo -> Bool
86105 isTypeclassDeclSpan spanInfo =
87106 case getNameM (spaninfoSource spanInfo) of
@@ -90,9 +109,7 @@ atPoint IdeOptions{..} tcs srcSpans pos = do
90109
91110locationsAtPoint :: forall m . MonadIO m => (FilePath -> m (Maybe HieFile)) -> IdeOptions -> HscEnv -> Position -> [SpanInfo] -> m [Location]
92111locationsAtPoint getHieFile IdeOptions{..} pkgState pos =
93− fmap (map srcSpanToLocation) .
94− mapMaybeM (getSpan . spaninfoSource) .
95− spansAtPoint pos
112+ fmap (map srcSpanToLocation) . mapMaybeM (getSpan . spaninfoSource) . spansAtPoint pos
96113 where getSpan :: SpanSource -> m (Maybe SrcSpan)
97114 getSpan NoSource = pure Nothing
98115 getSpan (SpanS sp) = pure $ Just sp
@@ -121,6 +138,7 @@ locationsAtPoint getHieFile IdeOptions{..} pkgState pos =
121138 setFileName f (RealSrcSpan span) = RealSrcSpan (span { srcSpanFile = mkFastString f })
122139 setFileName _ span@(UnhelpfulSpan _) = span
123140
141+-- | Filter out spans which do not enclose a given point
124142spansAtPoint :: Position -> [SpanInfo] -> [SpanInfo]
125143spansAtPoint pos = filter atp where
126144 line = _line pos