static-ls-0.1.2: src/StaticLS/IDE/Hover.hs
module StaticLS.IDE.Hover (
retrieveHover,
)
where
import Control.Monad.IO.Class
import Control.Monad.Trans.Maybe (MaybeT (..), runMaybeT)
import Data.Maybe
import Data.Text (Text, intercalate)
import qualified GHC.Iface.Ext.Types as GHC
import GHC.Plugins as GHC
import HieDb (pointCommand)
import Language.LSP.Protocol.Types (
Hover (..),
MarkupContent (..),
MarkupKind (..),
Position,
Range (..),
TextDocumentIdentifier,
sectionSeparator,
type (|?) (..),
)
import StaticLS.HI
import StaticLS.HI.File
import StaticLS.HIE
import StaticLS.HIE.File
import StaticLS.IDE.Hover.Info
import StaticLS.Maybe
import StaticLS.StaticEnv
-- | Retrieve hover information.
retrieveHover :: (HasCallStack, HasStaticEnv m, MonadIO m) => TextDocumentIdentifier -> Position -> m (Maybe Hover)
retrieveHover identifier position = do
runMaybeT $ do
hieFile <- getHieFileFromTdi identifier
docs <- docsAtPoint hieFile position
let info =
listToMaybe $
pointCommand
hieFile
(lspPositionToHieDbCoords position)
Nothing
(hoverInfo (GHC.hie_types hieFile) docs)
toAlt $ hoverInfoToHover <$> info
where
hoverInfoToHover :: (Maybe Range, [Text]) -> Hover
hoverInfoToHover (mRange, contents) =
Hover
{ _range = mRange
, _contents = InL $ MarkupContent MarkupKind_Markdown $ intercalate sectionSeparator contents
}
docsAtPoint :: (HasCallStack, HasStaticEnv m, MonadIO m) => GHC.HieFile -> Position -> m [NameDocs]
docsAtPoint hieFile position = do
let names = namesAtPoint hieFile (lspPositionToHieDbCoords position)
modNames = fmap GHC.moduleName . mapMaybe GHC.nameModule_maybe $ names
modIfaceFiles <- fromMaybe [] <$> runMaybeT (mapM modToHiFile modNames)
modIfaces <- catMaybes <$> mapM readHiFile modIfaceFiles
let docs = getDocsBatch names =<< modIfaces
pure docs