Skip to content
This repository was archived by the owner on Oct 7, 2020. It is now read-only.

Commit 2947e3a

Browse files
committed
Merge pull request #135 from JPMoresmau/ghc-mod-find
Ghc mod find
2 parents d633537 + 67409e7 commit 2947e3a

File tree

6 files changed

+46
-20
lines changed

6 files changed

+46
-20
lines changed

docs/IdeIntegration.md

+1-3
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ contextMapping CtxFile = [fileParam]
105105
contextMapping CtxPoint = [fileParam,startPosParam]
106106
contextMapping CtxRegion = [fileParam,startPosParam,endPosParam]
107107
contextMapping CtxCabalTarget = [cabalParam]
108-
contextMapping CtxProject = []
108+
contextMapping CtxProject = [fileParam]
109109

110110
fileParam :: ParamDescription
111111
fileParam = RP "file" "a file name" PtFile
@@ -119,5 +119,3 @@ endPosParam = RP "end_pos" "end line and col" PtPos
119119
cabalParam :: ParamDescription
120120
cabalParam = RP "cabal" "cabal target" PtText
121121
```
122-
123-

hie-ghc-mod/Haskell/Ide/GhcModPlugin.hs

+22-11
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import Control.Exception
88
import Data.Either
99
import Data.Vinyl
1010
import Control.Monad.IO.Class
11+
import qualified Data.Map as M
1112
import qualified Data.Text as T
1213
import qualified Data.Text.Read as T
1314
import Haskell.Ide.Engine.PluginDescriptor
@@ -16,6 +17,7 @@ import Haskell.Ide.Engine.SemanticTypes
1617
import qualified Language.Haskell.GhcMod as GM
1718
import qualified Language.Haskell.GhcMod.Monad as GM
1819
import qualified Language.Haskell.GhcMod.Types as GM
20+
import qualified Language.Haskell.GhcMod.Utils as GM
1921
import System.FilePath
2022
import System.Directory
2123
import qualified Exception as G
@@ -83,20 +85,28 @@ checkCmd = CmdSync $ \_ctxs req -> do
8385

8486
-- ---------------------------------------------------------------------
8587

86-
-- TODO: Must define a directory to base the search from, to be able to resolve
87-
-- the project root.
88-
findCmd :: CommandFunc T.Text
88+
-- | Runs the find command from the given directory, for the given symbol
89+
findCmd :: CommandFunc ModuleList
8990
findCmd = CmdSync $ \_ctxs req -> do
90-
case getParams (IdText "symbol" :& RNil) req of
91+
case getParams (IdFile "dir" :& IdText "symbol" :& RNil) req of
9192
Left err -> return err
92-
Right (ParamText _symbol :& RNil) -> do
93-
-- liftIO $ runGhcModCommand (GM.findSymbol (T.unpack symbol))
94-
-- dir <- liftIO getCurrentDirectory
95-
-- return (IdeResponseOk (String $ T.pack dir))
96-
-- return (IdeResponseOk (String $ _symbol))
97-
return (IdeResponseOk "Placholder:Need to debug this in ghc-mod, returns 'does not exist (No such file or directory)'")
93+
Right (ParamFile dirName :& ParamText symbol :& RNil) -> do
94+
runGhcModCommand (T.pack (T.unpack dirName </> "dummy")) (\_->
95+
do
96+
-- adapted from ghc-mod find command, which launches the executable again
97+
tmpdir <- GM.cradleTempDir <$> GM.cradle
98+
sf <- takeWhile (`notElem` ['\r','\n']) <$> GM.dumpSymbol tmpdir
99+
db <- M.fromAscList . map conv . lines <$> liftIO (readFile sf)
100+
let f = M.findWithDefault ([]::[GM.ModuleString]) symbol db
101+
return $ ModuleList $ map (T.pack . GM.getModuleString) f
102+
)
103+
104+
-- return (IdeResponseOk "Placholder:Need to debug this in ghc-mod, returns 'does not exist (No such file or directory)'")
98105
Right _ -> return $ IdeResponseError (IdeError InternalError
99106
"GhcModPlugin.findCmd: ghc’s exhaustiveness checker is broken" Nothing)
107+
where
108+
conv :: String -> (T.Text, [GM.ModuleString])
109+
conv = read
100110

101111
-- ---------------------------------------------------------------------
102112

@@ -164,7 +174,8 @@ runGhcModCommand fp cmd = do
164174
-- ghc-mod returns a new line at the end...
165175
root <- takeWhile (`notElem` ['\r','\n']) <$> GM.runGmOutT opts GM.rootInfo
166176
liftIO $ setCurrentDirectory root
167-
let setRoot e = e{GM.gmCradle = (GM.gmCradle e){GM.cradleRootDir=root}}
177+
tmp <- liftIO $ GM.newTempDir root
178+
let setRoot e = e{GM.gmCradle = (GM.gmCradle e){GM.cradleRootDir=root,GM.cradleTempDir=tmp}}
168179
(IdeResponseOk <$> GM.gmeLocal setRoot (cmd f)) `G.gcatch` \(e :: GM.GhcModError) ->
169180
return $ IdeResponseFail $ IdeError PluginError (T.pack $ "hie-ghc-mod: " ++ show e) Nothing
170181
)

hie-plugin-api/Haskell/Ide/Engine/PluginDescriptor.hs

+6-2
Original file line numberDiff line numberDiff line change
@@ -226,19 +226,23 @@ type Plugins = Map.Map PluginId PluginDescriptor
226226

227227
-- ---------------------------------------------------------------------
228228

229-
-- |For a given 'AcceptedContext', define the parameters that are required in
229+
-- | For a given 'AcceptedContext', define the parameters that are required in
230230
-- the corresponding 'IdeRequest'
231231
contextMapping :: AcceptedContext -> [ParamDescription]
232232
contextMapping CtxNone = []
233233
contextMapping CtxFile = [fileParam]
234234
contextMapping CtxPoint = [fileParam,startPosParam]
235235
contextMapping CtxRegion = [fileParam,startPosParam,endPosParam]
236236
contextMapping CtxCabalTarget = [cabalParam]
237-
contextMapping CtxProject = []
237+
contextMapping CtxProject = [dirParam] -- the root directory of the project
238238

239239
fileParam :: ParamDescription
240240
fileParam = RP "file" "a file name" PtFile
241241

242+
-- | A parameter for a directory
243+
dirParam :: ParamDescription
244+
dirParam = RP "dir" "a directory name" PtFile
245+
242246
startPosParam :: ParamDescription
243247
startPosParam = RP "start_pos" "start line and col" PtPos
244248

hie-plugin-api/Haskell/Ide/Engine/SemanticTypes.hs

+13
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ data HieDiff = HieDiff
4141
, dDiff :: ![Diff (Int,T.Text)]
4242
} deriving (Show,Eq,Generic)
4343

44+
-- ---------------------------------------------------------------------
45+
46+
-- | A list of modules
47+
data ModuleList = ModuleList {
48+
mModules :: [T.Text]
49+
} deriving (Show,Read,Eq,Ord,Generic)
50+
4451
-- ---------------------------------------------------------------------
4552
-- JSON instances
4653

@@ -103,3 +110,9 @@ instance FromJSON (Diff (Int,T.Text)) where
103110
Just d -> return d
104111
_ -> empty
105112
parseJSON _ = empty
113+
114+
-- ---------------------------------------------------------------------
115+
116+
instance ValidResponse ModuleList where
117+
jsWrite (ModuleList ms) = H.fromList ["modules" .= ms]
118+
jsRead v = ModuleList <$> v .: "modules"

test/DispatcherSpec.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ dispatcherSpec = do
105105
it "identifies CtxProject" $ do
106106
chan <- atomically newTChan
107107
chSync <- atomically newTChan
108-
let req = IdeRequest "cmd6" (Map.fromList [])
108+
let req = IdeRequest "cmd6" (Map.fromList [("dir", ParamFileP ".")])
109109
cr = CReq "test" 1 req chan
110110
r <- withStdoutLogging $ runIdeM (IdeState Map.empty) (doDispatch (testPlugins chSync) cr)
111111
r `shouldBe` Just (IdeResponseOk (H.fromList ["ok" .= ("result:ctxs=[CtxProject]"::String)]))

test/GhcModPluginSpec.hs

+3-3
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,10 @@ ghcmodSpec = do
6969
-- ---------------------------------
7070

7171
it "runs the find command" $ do
72-
let req = IdeRequest "find" (Map.fromList [("symbol", ParamTextP "map")])
72+
let req = IdeRequest "find" (Map.fromList [("dir", ParamFileP "."),("symbol", ParamTextP "Show")])
7373
r <- dispatchRequest req
74-
r `shouldBe` Just (IdeResponseOk (H.fromList ["ok" .= ("Placholder:Need to debug this in ghc-mod, returns 'does not exist (No such file or directory)'"::String)]))
75-
pendingWith "need to debug in ghc-mod"
74+
r `shouldBe` Just (IdeResponseOk (H.fromList ["modules" .= ["GHC.Show"::String,"Prelude","Test.Hspec.Discover","Text.Show"]]))
75+
7676

7777
-- ---------------------------------
7878

0 commit comments

Comments
 (0)