Skip to content

Commit 7e18f84

Browse files
jacgaherrmann-da
authored andcommitted
Refactor hover and go-to-definition searching (#260)
The process of searching for definitions is similar to the process of searching for hover information. In the original code (much of which was written out twice with occasional stylistic differences) the signal to noise ratio seemed pretty poor. Here is a refactoring which aims to make it easier to see the similarities and differences between these two related functionalities.
1 parent 6cf1d60 commit 7e18f84

File tree

6 files changed

+63
-96
lines changed

6 files changed

+63
-96
lines changed

ghcide.cabal

+1-2
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,7 @@ library
123123
Development.IDE.GHC.Warnings
124124
Development.IDE.Import.FindImports
125125
Development.IDE.LSP.CodeAction
126-
Development.IDE.LSP.Definition
127-
Development.IDE.LSP.Hover
126+
Development.IDE.LSP.HoverDefinition
128127
Development.IDE.LSP.Notifications
129128
Development.IDE.Spans.AtPoint
130129
Development.IDE.Spans.Calculate

src/Development/IDE/Core/Rules.hs

+2-2
Original file line numberDiff line numberDiff line change
@@ -102,17 +102,17 @@ getDependencies file = fmap transitiveModuleDeps <$> use GetDependencies file
102102
getAtPoint :: NormalizedFilePath -> Position -> Action (Maybe (Maybe Range, [T.Text]))
103103
getAtPoint file pos = fmap join $ runMaybeT $ do
104104
opts <- lift getIdeOptions
105+
spans <- useE GetSpanInfo file
105106
files <- transitiveModuleDeps <$> useE GetDependencies file
106107
tms <- usesE TypeCheck (file : files)
107-
spans <- useE GetSpanInfo file
108108
return $ AtPoint.atPoint opts (map tmrModule tms) spans pos
109109

110110
-- | Goto Definition.
111111
getDefinition :: NormalizedFilePath -> Position -> Action (Maybe Location)
112112
getDefinition file pos = fmap join $ runMaybeT $ do
113+
opts <- lift getIdeOptions
113114
spans <- useE GetSpanInfo file
114115
pkgState <- hscEnv <$> useE GhcSession file
115-
opts <- lift getIdeOptions
116116
let getHieFile x = useNoFile (GetHieFile x)
117117
lift $ AtPoint.gotoDefinition getHieFile opts pkgState spans pos
118118

src/Development/IDE/LSP/Definition.hs

-43
This file was deleted.

src/Development/IDE/LSP/Hover.hs

-47
This file was deleted.
+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
-- Copyright (c) 2019 The DAML Authors. All rights reserved.
2+
-- SPDX-License-Identifier: Apache-2.0
3+
4+
5+
-- | Display information on hover.
6+
module Development.IDE.LSP.HoverDefinition
7+
( setHandlersHover
8+
, setHandlersDefinition
9+
) where
10+
11+
import Development.IDE.Core.Rules
12+
import Development.IDE.Core.Service
13+
import Development.IDE.LSP.Server
14+
import Development.IDE.Types.Location
15+
import Development.IDE.Types.Logger
16+
import Development.Shake
17+
import qualified Language.Haskell.LSP.Core as LSP
18+
import Language.Haskell.LSP.Messages
19+
import Language.Haskell.LSP.Types
20+
21+
import qualified Data.Text as T
22+
23+
gotoDefinition :: IdeState -> TextDocumentPositionParams -> IO LocationResponseParams
24+
hover :: IdeState -> TextDocumentPositionParams -> IO (Maybe Hover)
25+
gotoDefinition = request "Definition" getDefinition (MultiLoc []) SingleLoc
26+
hover = request "Hover" getAtPoint Nothing foundHover
27+
28+
foundHover :: (Maybe Range, [T.Text]) -> Maybe Hover
29+
foundHover (mbRange, contents) =
30+
Just $ Hover (HoverContents $ MarkupContent MkMarkdown $ T.intercalate sectionSeparator contents) mbRange
31+
32+
setHandlersDefinition, setHandlersHover :: PartialHandlers
33+
setHandlersDefinition = PartialHandlers $ \WithMessage{..} x ->
34+
return x{LSP.definitionHandler = withResponse RspDefinition $ const gotoDefinition}
35+
setHandlersHover = PartialHandlers $ \WithMessage{..} x ->
36+
return x{LSP.hoverHandler = withResponse RspHover $ const hover}
37+
38+
-- | Respond to and log a hover or go-to-definition request
39+
request
40+
:: T.Text
41+
-> (NormalizedFilePath -> Position -> Action (Maybe a))
42+
-> b
43+
-> (a -> b)
44+
-> IdeState
45+
-> TextDocumentPositionParams
46+
-> IO b
47+
request label getResults notFound found ide (TextDocumentPositionParams (TextDocumentIdentifier uri) pos _) = do
48+
mbResult <- case uriToFilePath' uri of
49+
Just path -> logAndRunRequest label getResults ide pos path
50+
Nothing -> pure Nothing
51+
pure $ maybe notFound found mbResult
52+
53+
logAndRunRequest :: T.Text -> (NormalizedFilePath -> Position -> Action b) -> IdeState -> Position -> String -> IO b
54+
logAndRunRequest label getResults ide pos path = do
55+
let filePath = toNormalizedFilePath path
56+
logInfo (ideLogger ide) $
57+
label <> " request at position " <> T.pack (showPosition pos) <>
58+
" in file: " <> T.pack path
59+
runAction ide $ getResults filePath pos

src/Development/IDE/LSP/LanguageServer.hs

+1-2
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ import GHC.IO.Handle (hDuplicate)
2828
import System.IO
2929
import Control.Monad.Extra
3030

31-
import Development.IDE.LSP.Definition
32-
import Development.IDE.LSP.Hover
31+
import Development.IDE.LSP.HoverDefinition
3332
import Development.IDE.LSP.CodeAction
3433
import Development.IDE.LSP.Notifications
3534
import Development.IDE.Core.Service

0 commit comments

Comments
 (0)