{-# LANGUAGE DataKinds #-}
module Unison.LSP.Formatting where
import Control.Lens hiding (List)
import Data.Set qualified as Set
import Language.LSP.Protocol.Lens
import Language.LSP.Protocol.Message qualified as Msg
import Language.LSP.Protocol.Types
import Unison.Codebase.Editor.HandleInput.FormatFile qualified as Formatting
import Unison.Codebase.ProjectPath qualified as PP
import Unison.LSP.Conversions (lspToURange, uToLspRange)
import Unison.LSP.FileAnalysis (getFileAnalysis)
import Unison.LSP.FileAnalysis qualified as FileAnalysis
import Unison.LSP.Types
import Unison.Prelude
formatDocRequest :: Msg.TRequestMessage 'Msg.Method_TextDocumentFormatting -> (Either Msg.ResponseError (Msg.MessageResult 'Msg.Method_TextDocumentFormatting) -> Lsp ()) -> Lsp ()
formatDocRequest :: TRequestMessage 'Method_TextDocumentFormatting
-> (Either
ResponseError (MessageResult 'Method_TextDocumentFormatting)
-> Lsp ())
-> Lsp ()
formatDocRequest TRequestMessage 'Method_TextDocumentFormatting
m Either ResponseError (MessageResult 'Method_TextDocumentFormatting)
-> Lsp ()
respond = do
[TextEdit]
edits <- Uri -> Maybe (Set Range) -> Lsp [TextEdit]
formatDefs (TRequestMessage 'Method_TextDocumentFormatting
m TRequestMessage 'Method_TextDocumentFormatting
-> Getting Uri (TRequestMessage 'Method_TextDocumentFormatting) Uri
-> Uri
forall s a. s -> Getting a s a -> a
^. (DocumentFormattingParams -> Const Uri DocumentFormattingParams)
-> TRequestMessage 'Method_TextDocumentFormatting
-> Const Uri (TRequestMessage 'Method_TextDocumentFormatting)
forall s a. HasParams s a => Lens' s a
Lens'
(TRequestMessage 'Method_TextDocumentFormatting)
DocumentFormattingParams
params ((DocumentFormattingParams -> Const Uri DocumentFormattingParams)
-> TRequestMessage 'Method_TextDocumentFormatting
-> Const Uri (TRequestMessage 'Method_TextDocumentFormatting))
-> ((Uri -> Const Uri Uri)
-> DocumentFormattingParams -> Const Uri DocumentFormattingParams)
-> Getting Uri (TRequestMessage 'Method_TextDocumentFormatting) Uri
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TextDocumentIdentifier -> Const Uri TextDocumentIdentifier)
-> DocumentFormattingParams -> Const Uri DocumentFormattingParams
forall s a. HasTextDocument s a => Lens' s a
Lens' DocumentFormattingParams TextDocumentIdentifier
textDocument ((TextDocumentIdentifier -> Const Uri TextDocumentIdentifier)
-> DocumentFormattingParams -> Const Uri DocumentFormattingParams)
-> ((Uri -> Const Uri Uri)
-> TextDocumentIdentifier -> Const Uri TextDocumentIdentifier)
-> (Uri -> Const Uri Uri)
-> DocumentFormattingParams
-> Const Uri DocumentFormattingParams
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) Maybe (Set Range)
forall a. Maybe a
Nothing
Either ResponseError ([TextEdit] |? Null) -> Lsp ()
Either ResponseError (MessageResult 'Method_TextDocumentFormatting)
-> Lsp ()
respond (Either ResponseError ([TextEdit] |? Null) -> Lsp ())
-> ([TextEdit] -> Either ResponseError ([TextEdit] |? Null))
-> [TextEdit]
-> Lsp ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([TextEdit] |? Null) -> Either ResponseError ([TextEdit] |? Null)
forall a b. b -> Either a b
Right (([TextEdit] |? Null) -> Either ResponseError ([TextEdit] |? Null))
-> ([TextEdit] -> [TextEdit] |? Null)
-> [TextEdit]
-> Either ResponseError ([TextEdit] |? Null)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [TextEdit] -> [TextEdit] |? Null
forall a b. a -> a |? b
InL ([TextEdit] -> Lsp ()) -> [TextEdit] -> Lsp ()
forall a b. (a -> b) -> a -> b
$ [TextEdit]
edits
formatRangeRequest :: Msg.TRequestMessage 'Msg.Method_TextDocumentRangeFormatting -> (Either Msg.ResponseError (Msg.MessageResult 'Msg.Method_TextDocumentRangeFormatting) -> Lsp ()) -> Lsp ()
formatRangeRequest :: TRequestMessage 'Method_TextDocumentRangeFormatting
-> (Either
ResponseError (MessageResult 'Method_TextDocumentRangeFormatting)
-> Lsp ())
-> Lsp ()
formatRangeRequest TRequestMessage 'Method_TextDocumentRangeFormatting
m Either
ResponseError (MessageResult 'Method_TextDocumentRangeFormatting)
-> Lsp ()
respond = do
let p :: DocumentRangeFormattingParams
p = TRequestMessage 'Method_TextDocumentRangeFormatting
m TRequestMessage 'Method_TextDocumentRangeFormatting
-> Getting
DocumentRangeFormattingParams
(TRequestMessage 'Method_TextDocumentRangeFormatting)
DocumentRangeFormattingParams
-> DocumentRangeFormattingParams
forall s a. s -> Getting a s a -> a
^. Getting
DocumentRangeFormattingParams
(TRequestMessage 'Method_TextDocumentRangeFormatting)
DocumentRangeFormattingParams
forall s a. HasParams s a => Lens' s a
Lens'
(TRequestMessage 'Method_TextDocumentRangeFormatting)
DocumentRangeFormattingParams
params
[TextEdit]
edits <- Uri -> Maybe (Set Range) -> Lsp [TextEdit]
formatDefs (DocumentRangeFormattingParams
p DocumentRangeFormattingParams
-> Getting Uri DocumentRangeFormattingParams Uri -> Uri
forall s a. s -> Getting a s a -> a
^. (TextDocumentIdentifier -> Const Uri TextDocumentIdentifier)
-> DocumentRangeFormattingParams
-> Const Uri DocumentRangeFormattingParams
forall s a. HasTextDocument s a => Lens' s a
Lens' DocumentRangeFormattingParams TextDocumentIdentifier
textDocument ((TextDocumentIdentifier -> Const Uri TextDocumentIdentifier)
-> DocumentRangeFormattingParams
-> Const Uri DocumentRangeFormattingParams)
-> ((Uri -> Const Uri Uri)
-> TextDocumentIdentifier -> Const Uri TextDocumentIdentifier)
-> Getting Uri DocumentRangeFormattingParams Uri
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) (Set Range -> Maybe (Set Range)
forall a. a -> Maybe a
Just (Set Range -> Maybe (Set Range))
-> (Range -> Set Range) -> Range -> Maybe (Set Range)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Range -> Set Range
forall a. a -> Set a
Set.singleton (Range -> Maybe (Set Range)) -> Range -> Maybe (Set Range)
forall a b. (a -> b) -> a -> b
$ DocumentRangeFormattingParams
p DocumentRangeFormattingParams
-> Getting Range DocumentRangeFormattingParams Range -> Range
forall s a. s -> Getting a s a -> a
^. Getting Range DocumentRangeFormattingParams Range
forall s a. HasRange s a => Lens' s a
Lens' DocumentRangeFormattingParams Range
range)
Either ResponseError ([TextEdit] |? Null) -> Lsp ()
Either
ResponseError (MessageResult 'Method_TextDocumentRangeFormatting)
-> Lsp ()
respond (Either ResponseError ([TextEdit] |? Null) -> Lsp ())
-> ([TextEdit] -> Either ResponseError ([TextEdit] |? Null))
-> [TextEdit]
-> Lsp ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([TextEdit] |? Null) -> Either ResponseError ([TextEdit] |? Null)
forall a b. b -> Either a b
Right (([TextEdit] |? Null) -> Either ResponseError ([TextEdit] |? Null))
-> ([TextEdit] -> [TextEdit] |? Null)
-> [TextEdit]
-> Either ResponseError ([TextEdit] |? Null)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [TextEdit] -> [TextEdit] |? Null
forall a b. a -> a |? b
InL ([TextEdit] -> Lsp ()) -> [TextEdit] -> Lsp ()
forall a b. (a -> b) -> a -> b
$ [TextEdit]
edits
formatDefs :: Uri -> Maybe (Set Range ) -> Lsp [TextEdit]
formatDefs :: Uri -> Maybe (Set Range) -> Lsp [TextEdit]
formatDefs Uri
fileUri Maybe (Set Range)
mayRangesToFormat =
[TextEdit] -> Maybe [TextEdit] -> [TextEdit]
forall a. a -> Maybe a -> a
fromMaybe [] (Maybe [TextEdit] -> [TextEdit])
-> Lsp (Maybe [TextEdit]) -> Lsp [TextEdit]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MaybeT Lsp [TextEdit] -> Lsp (Maybe [TextEdit])
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT do
FileAnalysis {$sel:parsedFile:FileAnalysis :: FileAnalysis -> Maybe (UnisonFile Symbol Ann)
parsedFile = Maybe (UnisonFile Symbol Ann)
mayParsedFile, $sel:typecheckedFile:FileAnalysis :: FileAnalysis -> Maybe (TypecheckedUnisonFile Symbol Ann)
typecheckedFile = Maybe (TypecheckedUnisonFile Symbol Ann)
mayTypecheckedFile} <- Uri -> MaybeT Lsp FileAnalysis
getFileAnalysis Uri
fileUri
ProjectPath
pp <- Lsp ProjectPath -> MaybeT Lsp ProjectPath
forall (m :: * -> *) a. Monad m => m a -> MaybeT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift Lsp ProjectPath
getCurrentProjectPath
Config {Int
formattingWidth :: Int
$sel:formattingWidth:Config :: Config -> Int
formattingWidth} <- Lsp Config -> MaybeT Lsp Config
forall (m :: * -> *) a. Monad m => m a -> MaybeT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift Lsp Config
getConfig
Lsp (Maybe [TextEdit]) -> MaybeT Lsp [TextEdit]
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (Lsp (Maybe [TextEdit]) -> MaybeT Lsp [TextEdit])
-> Lsp (Maybe [TextEdit]) -> MaybeT Lsp [TextEdit]
forall a b. (a -> b) -> a -> b
$
(Maybe (UnisonFile Symbol Ann)
-> Maybe (TypecheckedUnisonFile Symbol Ann)
-> Lsp PrettyPrintEnvDecl)
-> Int
-> Absolute
-> Maybe (UnisonFile Symbol Ann)
-> Maybe (TypecheckedUnisonFile Symbol Ann)
-> Maybe (Set Range)
-> Lsp (Maybe [TextReplacement])
forall (m :: * -> *).
Monad m =>
(Maybe (UnisonFile Symbol Ann)
-> Maybe (TypecheckedUnisonFile Symbol Ann)
-> m PrettyPrintEnvDecl)
-> Int
-> Absolute
-> Maybe (UnisonFile Symbol Ann)
-> Maybe (TypecheckedUnisonFile Symbol Ann)
-> Maybe (Set Range)
-> m (Maybe [TextReplacement])
Formatting.formatFile (\Maybe (UnisonFile Symbol Ann)
uf Maybe (TypecheckedUnisonFile Symbol Ann)
tf -> Maybe (UnisonFile Symbol Ann)
-> Maybe (TypecheckedUnisonFile Symbol Ann)
-> Lsp PrettyPrintEnvDecl
forall a.
Maybe (UnisonFile Symbol a)
-> Maybe (TypecheckedUnisonFile Symbol a) -> Lsp PrettyPrintEnvDecl
FileAnalysis.ppedForFileHelper Maybe (UnisonFile Symbol Ann)
uf Maybe (TypecheckedUnisonFile Symbol Ann)
tf) Int
formattingWidth (ProjectPath
pp ProjectPath -> Getting Absolute ProjectPath Absolute -> Absolute
forall s a. s -> Getting a s a -> a
^. Getting Absolute ProjectPath Absolute
forall p b (f :: * -> *).
Functor f =>
(Absolute -> f Absolute)
-> ProjectPathG p b -> f (ProjectPathG p b)
PP.absPath_) Maybe (UnisonFile Symbol Ann)
mayParsedFile Maybe (TypecheckedUnisonFile Symbol Ann)
mayTypecheckedFile ((Range -> Range) -> Set Range -> Set Range
forall b a. Ord b => (a -> b) -> Set a -> Set b
Set.map Range -> Range
lspToURange (Set Range -> Set Range) -> Maybe (Set Range) -> Maybe (Set Range)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (Set Range)
mayRangesToFormat)
Lsp (Maybe [TextReplacement])
-> (Maybe [TextReplacement] -> Maybe [TextEdit])
-> Lsp (Maybe [TextEdit])
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> (([TextReplacement] -> [TextEdit])
-> Maybe [TextReplacement] -> Maybe [TextEdit]
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([TextReplacement] -> [TextEdit])
-> Maybe [TextReplacement] -> Maybe [TextEdit])
-> ((TextReplacement -> TextEdit)
-> [TextReplacement] -> [TextEdit])
-> (TextReplacement -> TextEdit)
-> Maybe [TextReplacement]
-> Maybe [TextEdit]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TextReplacement -> TextEdit) -> [TextReplacement] -> [TextEdit]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) TextReplacement -> TextEdit
uTextReplacementToLSP
where
uTextReplacementToLSP :: Formatting.TextReplacement -> TextEdit
uTextReplacementToLSP :: TextReplacement -> TextEdit
uTextReplacementToLSP (Formatting.TextReplacement Text
newText Range
range) = Range -> Text -> TextEdit
TextEdit (Range -> Range
uToLspRange Range
range) Text
newText