@@ -10,40 +10,40 @@ module Development.IDE.Plugin.Completions
10
10
11
11
import Control.Concurrent.Async (concurrently )
12
12
import Control.Concurrent.STM.Stats (readTVarIO )
13
- import Control.Monad.Extra
14
13
import Control.Monad.IO.Class
15
- import Control.Monad.Trans.Maybe
14
+ import Control.Lens ( (&) , (.~) )
16
15
import Data.Aeson
17
16
import qualified Data.HashMap.Strict as Map
18
17
import qualified Data.HashSet as Set
19
- import Data.List (find )
20
18
import Data.Maybe
21
19
import qualified Data.Text as T
22
20
import Development.IDE.Core.PositionMapping
21
+ import Development.IDE.Core.Compile
23
22
import Development.IDE.Core.RuleTypes
24
23
import Development.IDE.Core.Service hiding (Log , LogShake )
25
24
import Development.IDE.Core.Shake hiding (Log )
26
25
import qualified Development.IDE.Core.Shake as Shake
27
26
import Development.IDE.GHC.Compat
28
- import Development.IDE.GHC.Error (rangeToSrcSpan )
29
27
import Development.IDE.GHC.Util (printOutputable )
30
28
import Development.IDE.Graph
29
+ import Development.IDE.Spans.Common
30
+ import Development.IDE.Spans.Documentation
31
31
import Development.IDE.Plugin.Completions.Logic
32
32
import Development.IDE.Plugin.Completions.Types
33
33
import Development.IDE.Types.Exports
34
- import Development.IDE.Types.HscEnvEq (HscEnvEq (envPackageExports ),
34
+ import Development.IDE.Types.HscEnvEq (HscEnvEq (envPackageExports , envVisibleModuleNames ),
35
35
hscEnv )
36
36
import qualified Development.IDE.Types.KnownTargets as KT
37
37
import Development.IDE.Types.Location
38
38
import Development.IDE.Types.Logger (Pretty (pretty ),
39
39
Recorder ,
40
40
WithPriority ,
41
41
cmapWithPrio )
42
- import GHC.Exts (fromList , toList )
43
42
import Ide.Plugin.Config (Config )
44
43
import Ide.Types
45
44
import qualified Language.LSP.Server as LSP
46
45
import Language.LSP.Types
46
+ import qualified Language.LSP.Types.Lens as J
47
47
import qualified Language.LSP.VFS as VFS
48
48
import Numeric.Natural
49
49
import Text.Fuzzy.Parallel (Scored (.. ))
@@ -61,10 +61,12 @@ descriptor :: Recorder (WithPriority Log) -> PluginId -> PluginDescriptor IdeSta
61
61
descriptor recorder plId = (defaultPluginDescriptor plId)
62
62
{ pluginRules = produceCompletions recorder
63
63
, pluginHandlers = mkPluginHandler STextDocumentCompletion getCompletionsLSP
64
+ <> mkPluginHandler SCompletionItemResolve resolveCompletion
64
65
, pluginConfigDescriptor = defaultConfigDescriptor {configCustomConfig = mkCustomConfig properties}
65
66
, pluginPriority = ghcideCompletionsPluginPriority
66
67
}
67
68
69
+
68
70
produceCompletions :: Recorder (WithPriority Log ) -> Rules ()
69
71
produceCompletions recorder = do
70
72
define (cmapWithPrio LogShake recorder) $ \ LocalCompletions file -> do
@@ -89,8 +91,9 @@ produceCompletions recorder = do
89
91
(global, inScope) <- liftIO $ tcRnImportDecls env (dropListFromImportDecl <$> msrImports) `concurrently` tcRnImportDecls env msrImports
90
92
case (global, inScope) of
91
93
((_, Just globalEnv), (_, Just inScopeEnv)) -> do
94
+ visibleMods <- liftIO $ fmap (fromMaybe [] ) $ envVisibleModuleNames sess
92
95
let uri = fromNormalizedUri $ normalizedFilePathToUri file
93
- cdata <- liftIO $ cacheDataProducer uri sess (ms_mod msrModSummary) globalEnv inScopeEnv msrImports
96
+ let cdata = cacheDataProducer uri visibleMods (ms_mod msrModSummary) globalEnv inScopeEnv msrImports
94
97
return ([] , Just cdata)
95
98
(_diag, _) ->
96
99
return ([] , Nothing )
@@ -106,6 +109,44 @@ dropListFromImportDecl iDecl = let
106
109
f x = x
107
110
in f <$> iDecl
108
111
112
+ resolveCompletion :: IdeState -> PluginId -> CompletionItem -> LSP. LspM Config (Either ResponseError CompletionItem )
113
+ resolveCompletion ide _ comp@ CompletionItem {_detail,_documentation,_xdata}
114
+ | Just resolveData <- _xdata
115
+ , Success (uri, NameDetails mod occ) <- fromJSON resolveData
116
+ , Just file <- uriToNormalizedFilePath $ toNormalizedUri uri = do
117
+ mdkm <- liftIO $ runAction " Completion resolve" ide $ use GetDocMap file
118
+ case mdkm of
119
+ Nothing -> pure (Right comp)
120
+ Just (DKMap dm km) -> liftIO $ runAction " Completion resolve" ide $ do
121
+ let nc = ideNc $ shakeExtras ide
122
+ #if MIN_VERSION_ghc(9,3,0)
123
+ name <- liftIO $ lookupNameCache nc mod occ
124
+ #else
125
+ name <- liftIO $ upNameCache nc (lookupNameCache mod occ)
126
+ #endif
127
+ (ms,_) <- useWithStale_ GetModSummaryWithoutTimestamps file
128
+ (sess,_) <- useWithStale_ GhcSessionDeps file
129
+ let cur_mod = ms_mod $ msrModSummary ms
130
+ doc <- case lookupNameEnv dm name of
131
+ Just doc -> pure $ spanDocToMarkdown doc
132
+ Nothing -> liftIO $ spanDocToMarkdown <$> getDocumentationTryGhc (hscEnv sess) cur_mod name
133
+ typ <- case lookupNameEnv km name of
134
+ Just ty -> pure (safeTyThingType ty)
135
+ Nothing -> do
136
+ (safeTyThingType =<< ) <$> liftIO (lookupName (hscEnv sess) cur_mod name)
137
+ let det1 = case typ of
138
+ Just ty -> Just (" :: " <> printOutputable ty <> " \n " )
139
+ Nothing -> Nothing
140
+ doc1 = case _documentation of
141
+ Just (CompletionDocMarkup (MarkupContent MkMarkdown old)) ->
142
+ CompletionDocMarkup $ MarkupContent MkMarkdown $ T. intercalate sectionSeparator (old: doc)
143
+ _ -> CompletionDocMarkup $ MarkupContent MkMarkdown $ T. intercalate sectionSeparator doc
144
+ pure (Right $ comp & J. detail .~ (det1 <> _detail)
145
+ & J. documentation .~ Just doc1
146
+ )
147
+
148
+ resolveCompletion _ _ comp = pure (Right comp)
149
+
109
150
-- | Generate code actions.
110
151
getCompletionsLSP
111
152
:: IdeState
@@ -151,7 +192,7 @@ getCompletionsLSP ide plId
151
192
let clientCaps = clientCapabilities $ shakeExtras ide
152
193
plugins = idePlugins $ shakeExtras ide
153
194
config <- getCompletionsConfig plId
154
- allCompletions <- liftIO $ getCompletions plugins ideOpts cci' parsedMod bindMap pfix' clientCaps config moduleExports
195
+ allCompletions <- liftIO $ getCompletions plugins ideOpts cci' parsedMod bindMap pfix' clientCaps config moduleExports uri
155
196
pure $ InL (List $ orderedCompletions allCompletions)
156
197
_ -> return (InL $ List [] )
157
198
_ -> return (InL $ List [] )
0 commit comments