module Unison.LSP.DocumentSymbols
( documentSymbolsHandler,
)
where
import Control.Lens hiding (List)
import Language.LSP.Protocol.Lens hiding (error)
import Language.LSP.Protocol.Message qualified as Msg
import Language.LSP.Protocol.Types
import Unison.LSP.FileAnalysis
import Unison.LSP.FileAnalysis qualified as FileAnalysis
import Unison.LSP.Types
import Unison.Prelude
import Unison.PrettyPrintEnv (PrettyPrintEnv)
import Unison.PrettyPrintEnvDecl qualified as PPED
import Unison.Syntax.Name qualified as Name
import Unison.Syntax.TypePrinter qualified as TypePrinter
import Unison.Util.Pretty qualified as Pretty
documentSymbolsHandler :: Msg.TRequestMessage 'Msg.Method_TextDocumentDocumentSymbol -> (Either Msg.ResponseError (Msg.MessageResult 'Msg.Method_TextDocumentDocumentSymbol) -> Lsp ()) -> Lsp ()
documentSymbolsHandler :: TRequestMessage 'Method_TextDocumentDocumentSymbol
-> (Either
ResponseError (MessageResult 'Method_TextDocumentDocumentSymbol)
-> Lsp ())
-> Lsp ()
documentSymbolsHandler TRequestMessage 'Method_TextDocumentDocumentSymbol
m Either
ResponseError (MessageResult 'Method_TextDocumentDocumentSymbol)
-> Lsp ()
respond = do
Either
ResponseError ([SymbolInformation] |? ([DocumentSymbol] |? Null))
-> Lsp ()
Either
ResponseError (MessageResult 'Method_TextDocumentDocumentSymbol)
-> Lsp ()
respond (Either
ResponseError ([SymbolInformation] |? ([DocumentSymbol] |? Null))
-> Lsp ())
-> (Maybe [DocumentSymbol]
-> Either
ResponseError ([SymbolInformation] |? ([DocumentSymbol] |? Null)))
-> Maybe [DocumentSymbol]
-> Lsp ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([SymbolInformation] |? ([DocumentSymbol] |? Null))
-> Either
ResponseError ([SymbolInformation] |? ([DocumentSymbol] |? Null))
forall a b. b -> Either a b
Right (([SymbolInformation] |? ([DocumentSymbol] |? Null))
-> Either
ResponseError ([SymbolInformation] |? ([DocumentSymbol] |? Null)))
-> (Maybe [DocumentSymbol]
-> [SymbolInformation] |? ([DocumentSymbol] |? Null))
-> Maybe [DocumentSymbol]
-> Either
ResponseError ([SymbolInformation] |? ([DocumentSymbol] |? Null))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([SymbolInformation] |? ([DocumentSymbol] |? Null))
-> ([DocumentSymbol]
-> [SymbolInformation] |? ([DocumentSymbol] |? Null))
-> Maybe [DocumentSymbol]
-> [SymbolInformation] |? ([DocumentSymbol] |? Null)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (([DocumentSymbol] |? Null)
-> [SymbolInformation] |? ([DocumentSymbol] |? Null)
forall a b. b -> a |? b
InR (([DocumentSymbol] |? Null)
-> [SymbolInformation] |? ([DocumentSymbol] |? Null))
-> ([DocumentSymbol] -> [DocumentSymbol] |? Null)
-> [DocumentSymbol]
-> [SymbolInformation] |? ([DocumentSymbol] |? Null)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [DocumentSymbol] -> [DocumentSymbol] |? Null
forall a b. a -> a |? b
InL ([DocumentSymbol]
-> [SymbolInformation] |? ([DocumentSymbol] |? Null))
-> [DocumentSymbol]
-> [SymbolInformation] |? ([DocumentSymbol] |? Null)
forall a b. (a -> b) -> a -> b
$ []) (([DocumentSymbol] |? Null)
-> [SymbolInformation] |? ([DocumentSymbol] |? Null)
forall a b. b -> a |? b
InR (([DocumentSymbol] |? Null)
-> [SymbolInformation] |? ([DocumentSymbol] |? Null))
-> ([DocumentSymbol] -> [DocumentSymbol] |? Null)
-> [DocumentSymbol]
-> [SymbolInformation] |? ([DocumentSymbol] |? Null)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [DocumentSymbol] -> [DocumentSymbol] |? Null
forall a b. a -> a |? b
InL) (Maybe [DocumentSymbol] -> Lsp ())
-> Lsp (Maybe [DocumentSymbol]) -> Lsp ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< MaybeT Lsp [DocumentSymbol] -> Lsp (Maybe [DocumentSymbol])
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT do
let fileUri :: Uri
fileUri = TRequestMessage 'Method_TextDocumentDocumentSymbol
m TRequestMessage 'Method_TextDocumentDocumentSymbol
-> Getting
Uri (TRequestMessage 'Method_TextDocumentDocumentSymbol) Uri
-> Uri
forall s a. s -> Getting a s a -> a
^. (DocumentSymbolParams -> Const Uri DocumentSymbolParams)
-> TRequestMessage 'Method_TextDocumentDocumentSymbol
-> Const Uri (TRequestMessage 'Method_TextDocumentDocumentSymbol)
forall s a. HasParams s a => Lens' s a
Lens'
(TRequestMessage 'Method_TextDocumentDocumentSymbol)
DocumentSymbolParams
params ((DocumentSymbolParams -> Const Uri DocumentSymbolParams)
-> TRequestMessage 'Method_TextDocumentDocumentSymbol
-> Const Uri (TRequestMessage 'Method_TextDocumentDocumentSymbol))
-> ((Uri -> Const Uri Uri)
-> DocumentSymbolParams -> Const Uri DocumentSymbolParams)
-> Getting
Uri (TRequestMessage 'Method_TextDocumentDocumentSymbol) Uri
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TextDocumentIdentifier -> Const Uri TextDocumentIdentifier)
-> DocumentSymbolParams -> Const Uri DocumentSymbolParams
forall s a. HasTextDocument s a => Lens' s a
Lens' DocumentSymbolParams TextDocumentIdentifier
textDocument ((TextDocumentIdentifier -> Const Uri TextDocumentIdentifier)
-> DocumentSymbolParams -> Const Uri DocumentSymbolParams)
-> ((Uri -> Const Uri Uri)
-> TextDocumentIdentifier -> Const Uri TextDocumentIdentifier)
-> (Uri -> Const Uri Uri)
-> DocumentSymbolParams
-> Const Uri DocumentSymbolParams
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Uri -> Const Uri Uri)
-> TextDocumentIdentifier -> Const Uri TextDocumentIdentifier
forall s a. HasUri s a => Lens' s a
Lens' TextDocumentIdentifier Uri
uri
FileAnalysis {[UDocumentSymbol]
documentSymbols :: [UDocumentSymbol]
$sel:documentSymbols:FileAnalysis :: FileAnalysis -> [UDocumentSymbol]
documentSymbols} <- Uri -> MaybeT Lsp FileAnalysis
forall (m :: * -> *). Lspish m => Uri -> MaybeT m FileAnalysis
FileAnalysis.getFileAnalysis Uri
fileUri
PrettyPrintEnv
ppe <- PrettyPrintEnvDecl -> PrettyPrintEnv
PPED.suffixifiedPPE (PrettyPrintEnvDecl -> PrettyPrintEnv)
-> MaybeT Lsp PrettyPrintEnvDecl -> MaybeT Lsp PrettyPrintEnv
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Lsp PrettyPrintEnvDecl -> MaybeT Lsp PrettyPrintEnvDecl
forall (m :: * -> *) a. Monad m => m a -> MaybeT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Uri -> Lsp PrettyPrintEnvDecl
forall (m :: * -> *). Lspish m => Uri -> m PrettyPrintEnvDecl
ppedForFile Uri
fileUri)
[DocumentSymbol] -> MaybeT Lsp [DocumentSymbol]
forall a. a -> MaybeT Lsp a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PrettyPrintEnv -> UDocumentSymbol -> DocumentSymbol
asLspDocumentSymbols PrettyPrintEnv
ppe (UDocumentSymbol -> DocumentSymbol)
-> [UDocumentSymbol] -> [DocumentSymbol]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [UDocumentSymbol]
documentSymbols)
asLspDocumentSymbols :: PrettyPrintEnv -> UDocumentSymbol -> DocumentSymbol
asLspDocumentSymbols :: PrettyPrintEnv -> UDocumentSymbol -> DocumentSymbol
asLspDocumentSymbols
PrettyPrintEnv
ppe
UDocumentSymbol
{ Name
symbolName :: Name
$sel:symbolName:UDocumentSymbol :: UDocumentSymbol -> Name
symbolName,
Maybe (Type Symbol Ann)
symbolSignature :: Maybe (Type Symbol Ann)
$sel:symbolSignature:UDocumentSymbol :: UDocumentSymbol -> Maybe (Type Symbol Ann)
symbolSignature,
USymbolKind
symbolKind :: USymbolKind
$sel:symbolKind:UDocumentSymbol :: UDocumentSymbol -> USymbolKind
symbolKind,
Range
symbolRange :: Range
$sel:symbolRange:UDocumentSymbol :: UDocumentSymbol -> Range
symbolRange,
[UDocumentSymbol]
symbolChildren :: [UDocumentSymbol]
$sel:symbolChildren:UDocumentSymbol :: UDocumentSymbol -> [UDocumentSymbol]
symbolChildren
} =
DocumentSymbol
{ $sel:_name:DocumentSymbol :: Text
_name = Name -> Text
Name.toText Name
symbolName,
$sel:_detail:DocumentSymbol :: Maybe Text
_detail = do
Type Symbol Ann
typ <- Maybe (Type Symbol Ann)
symbolSignature
Text -> Maybe Text
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
": " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (Width -> PrettyPrintEnv -> Type Symbol Ann -> Text
forall v a. Var v => Width -> PrettyPrintEnv -> Type v a -> Text
TypePrinter.prettyStr Width
typeWidth PrettyPrintEnv
ppe Type Symbol Ann
typ),
$sel:_kind:DocumentSymbol :: SymbolKind
_kind = USymbolKind -> SymbolKind
lspSymbolKind USymbolKind
symbolKind,
$sel:_tags:DocumentSymbol :: Maybe [SymbolTag]
_tags = [SymbolTag] -> Maybe [SymbolTag]
forall a. a -> Maybe a
Just [],
$sel:_deprecated:DocumentSymbol :: Maybe Bool
_deprecated = Maybe Bool
forall a. Maybe a
Nothing,
$sel:_range:DocumentSymbol :: Range
_range = Range
symbolRange,
$sel:_selectionRange:DocumentSymbol :: Range
_selectionRange = Range
symbolRange,
$sel:_children:DocumentSymbol :: Maybe [DocumentSymbol]
_children = if [UDocumentSymbol] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [UDocumentSymbol]
symbolChildren then Maybe [DocumentSymbol]
forall a. Maybe a
Nothing else [DocumentSymbol] -> Maybe [DocumentSymbol]
forall a. a -> Maybe a
Just (PrettyPrintEnv -> UDocumentSymbol -> DocumentSymbol
asLspDocumentSymbols PrettyPrintEnv
ppe (UDocumentSymbol -> DocumentSymbol)
-> [UDocumentSymbol] -> [DocumentSymbol]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [UDocumentSymbol]
symbolChildren)
}
where
typeWidth :: Width
typeWidth = Int -> Width
Pretty.Width Int
120
lspSymbolKind :: USymbolKind -> SymbolKind
lspSymbolKind = \case
USymbolKind
DataDeclSymbol -> SymbolKind
SymbolKind_Class
USymbolKind
EffectDeclSymbol -> SymbolKind
SymbolKind_Interface
USymbolKind
TermSymbol -> SymbolKind
SymbolKind_Function