yi-0.8.0: src/library/Yi/Scion.hs
{-# LANGUAGE FlexibleContexts, FlexibleInstances,
MultiParamTypeClasses, TypeSynonymInstances #-}
module Yi.Scion where
import Yi.Core (msgEditor)
import Prelude (lines)
import Bag
import Data.Maybe
import GHC
import HscTypes
import qualified Outputable as O
import Scion
import Scion.Types
import Scion.Utils
import Outputable
import GHC.SYB.Utils
import PprTyThing (pprTypeForUser)
import FastString (fsLit) -- ghosts
import Yi.Buffer
import Yi.Editor
import Yi.Keymap
import Scion.Inspect ( prettyResult )
import Scion.Inspect.Find ( overlaps, findHsThing, pathToDeepest)
import Scion.Inspect.TypeOf ( typeOf )
loadFile :: String -> ScionM TypecheckedModule
loadFile fn = do
addTarget =<< guessTarget fn Nothing
Scion.load LoadAllTargets
(m:_) <- modulesInDepOrder
typecheckModule =<< parseModule m
functionType :: (Int, Int) -- ^ The line and column of the current point
-> String -- ^ The filename in which the point is positioned
-> ScionM String -- ^ The `ScionM` action resulting in the function's type
functionType pt fn = do
addTarget =<< guessTarget fn Nothing
s <- handleSourceError handleError $ do
mss <- modulesInDepOrder
forM mss $ \m -> do
module' <- loadModule =<< typecheckModule =<< parseModule m
let t = n . fun_matches . unLoc .
last . bagToList . last . bagToList . mapBag m' .
filterBag (\l -> spans (getLoc l) pt) . typecheckedSource
m' = abs_binds . unLoc
n (MatchGroup _ t') = t'
return $ showSDoc $ ppr $ t module'
return . last $ s
-- maybe this can be improved by using "thingsAroundPoint"
play :: (Int, Int) -- ^ The line and column of the current point
-> String -- ^ The filename in which the point is positioned
-> ScionM [String] -- ^ The `ScionM` action resulting in the function's type
play pt fn = do
addTarget =<< guessTarget fn Nothing
handleSourceError handleError $ do
[m] <- modulesInDepOrder
module' <- loadModule =<< typecheckModule =<< parseModule m
lines <$> thingAtPoint pt fn module'
thingsAtPoint :: (Int, Int) -> String -> ScionM String
thingsAtPoint pt fn = do
addTarget =<< guessTarget fn Nothing
Scion.load LoadAllTargets
mss <- modulesInDepOrder
show <$> forM mss (\ms -> do
mod <- typecheckModule =<< parseModule ms
let Just (grp, _, _, _) = renamedSource mod
let bnds = typecheckedSource mod
let tyclds = thingsAroundPoint pt $ concat $ hs_tyclds grp
let ValBindsOut valds _ = hs_valds grp
return $ showData TypeChecker 2 bnds)
handleError :: SourceError -> ScionM [String]
handleError err = return [show err]
-- This is copied from Protocol.Vim
thingAtPoint :: (TypecheckedMod m) => (Int, Int) -> String -> m -> ScionM String
thingAtPoint (line,col) fname tcm = do
let loc = srcLocSpan $ mkSrcLoc (fsLit fname) line col
--let Just (src, _, _, _, _) = renamedSource tcm
let src = typecheckedSource tcm
--let in_range = const True
let in_range = overlaps loc
let r = findHsThing in_range src
--return (Just (O.showSDoc (O.ppr $ S.toList r)))
unqual <- unqualifiedForModule tcm
case pathToDeepest r of
Nothing -> return "no info"
Just (x,xs) ->
--return $ Just (O.showSDoc (O.ppr x O.$$ O.ppr xs))
case typeOf (x,xs) of
Just t ->
return $ O.showSDocForUser unqual
(prettyResult x O.<+> O.dcolon O.<+>
pprTypeForUser True t)
_ -> return $ O.showSDocDebug (O.ppr x O.$$ O.ppr xs )
{-# ANN runScionWithLocation "HLint: ignore Redundant do" #-}
runScionWithLocation :: Show a => ((Int, Int) -> String -> ScionM a) -> YiM a
runScionWithLocation f = do
(pt, fn) <- withEditor $ withBuffer0 $ do
ln <- curLn
col <- curCol
Just fn <- gets file
return ((ln, col), fn)
io $ runScion $ do
-- openCabalProject "." "dist" fails ...
-- loadFile fn
f pt fn
scion :: YiM ()
scion = msgEditor =<< show <$> runScionWithLocation play