Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions app/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import Language.LSP.NotebookLanguageServer.Process
import Language.LSP.NotebookLanguageServer.RequestMap
import Streams
import Language.LSP.Notebook
import Language.LSP.NotebookLanguageServer.Config
import Transform.Config


Expand Down Expand Up @@ -138,12 +139,13 @@ main = do
}

withMaybeShadowDir optShadowDirTemplate $ \maybeShadowDir -> do
transformerState <- newTransformerState maybeShadowDir optDidSaveDebouncePeriodMs
let config = rustNotebookConfig maybeShadowDir optDidSaveDebouncePeriodMs
transformerState <- newTransformerState

flip runLoggingT logFn $ filterLogger logFilterFn $ flip runReaderT transformerState $
withAsync (readWrappedOut clientReqMap serverReqMap wrappedOut sendToStdout) $ \_wrappedOutAsync ->
withAsync (readWrappedOut config clientReqMap serverReqMap wrappedOut sendToStdout) $ \_wrappedOutAsync ->
withAsync (readWrappedErr wrappedErr) $ \_wrappedErrAsync ->
withAsync (forever $ handleStdin wrappedIn clientReqMap serverReqMap) $ \_stdinAsync -> do
withAsync (forever $ handleStdin config wrappedIn clientReqMap serverReqMap) $ \_stdinAsync -> do
waitForProcess p >>= \case
ExitFailure n -> logErrorN [i|rust-analyzer subprocess exited with code #{n}|]
ExitSuccess -> logInfoN [i|rust-analyzer subprocess exited successfully|]
Expand All @@ -160,8 +162,8 @@ withMaybeShadowDir maybeTemplate cb = withSystemTempDirectory "rust-analyzer-sha

handleStdin :: forall m. (
MonadLoggerIO m, MonadReader (TransformerState RustNotebookTransformer) m, MonadUnliftIO m, MonadFail m
) => Handle -> MVar ClientRequestMap -> MVar ServerRequestMap -> m ()
handleStdin wrappedIn clientReqMap serverReqMap = do
) => NotebookConfig RustNotebookTransformer -> Handle -> MVar ClientRequestMap -> MVar ServerRequestMap -> m ()
handleStdin config wrappedIn clientReqMap serverReqMap = do
(A.eitherDecode <$> liftIO (parseStream stdin)) >>= \case
Left err -> logErr [i|Couldn't decode incoming message: #{err}|]
Right (x :: A.Value) -> do
Expand All @@ -177,9 +179,9 @@ handleStdin wrappedIn clientReqMap serverReqMap = do
modifyMVar_ clientReqMap $ \m -> case updateClientRequestMap m msgId (SMethodAndParams meth (msg ^. Lens.params)) of
Just m' -> return m'
Nothing -> return m
transformClientReq rustNotebookConfig meth msg >>= liftIO . writeToHandle wrappedIn . A.encode
transformClientReq config meth msg >>= liftIO . writeToHandle wrappedIn . A.encode
Right (ClientToServerNot meth msg) ->
transformClientNot rustNotebookConfig sendExtraNotification meth msg >>= (liftIO . writeToHandle wrappedIn . A.encode)
transformClientNot config sendExtraNotification meth msg >>= (liftIO . writeToHandle wrappedIn . A.encode)
where
sendExtraNotification :: SendExtraNotificationFn m
sendExtraNotification msg = do
Expand All @@ -188,8 +190,8 @@ handleStdin wrappedIn clientReqMap serverReqMap = do

readWrappedOut :: (
MonadUnliftIO m, MonadLoggerIO m, MonadReader (TransformerState RustNotebookTransformer) m, MonadFail m
) => MVar ClientRequestMap -> MVar ServerRequestMap -> Handle -> (forall a. ToJSON a => a -> m ()) -> m b
readWrappedOut clientReqMap serverReqMap wrappedOut sendToStdout = forever $ do
) => NotebookConfig RustNotebookTransformer -> MVar ClientRequestMap -> MVar ServerRequestMap -> Handle -> (forall a. ToJSON a => a -> m ()) -> m b
readWrappedOut config clientReqMap serverReqMap wrappedOut sendToStdout = forever $ do
(A.eitherDecode <$> liftIO (parseStream wrappedOut)) >>= \case
Left err -> logErr [i|Couldn't decode wrapped output: #{err}|]
Right (x :: A.Value) -> do
Expand All @@ -207,7 +209,7 @@ readWrappedOut clientReqMap serverReqMap wrappedOut sendToStdout = forever $ do
Nothing -> return m
sendToStdout (transformServerReq meth msg)
Right (ServerToClientRsp meth initialParams msg) ->
transformServerRsp rustNotebookConfig meth initialParams msg >>= sendToStdout
transformServerRsp config meth initialParams msg >>= sendToStdout

readWrappedErr :: MonadLoggerIO m => Handle -> m ()
readWrappedErr wrappedErr = forever $ do
Expand Down
52 changes: 25 additions & 27 deletions src/Transform/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -24,49 +24,47 @@ import UnliftIO.Directory
import UnliftIO.MVar


rustNotebookConfig :: NotebookConfig RustNotebookTransformer
rustNotebookConfig = NotebookConfig {
notebookConfigTransformerParams = transformerParams
, notebookConfigIdTransformerParams = idTransformerParams
, notebookConfigMakeShadowDocument = makeShadowDocument
rustNotebookConfig :: FilePath -> Int -> NotebookConfig RustNotebookTransformer
rustNotebookConfig shadowDir didSaveDebounceMs = NotebookConfig {
notebookConfigHandles = const True
, notebookConfigDidSaveDebounceMs = Just didSaveDebounceMs
, notebookConfigTransformerParamsFor = \u -> if isNotebook u then transformerParams else idTransformerParams
, notebookConfigMakeShadowDocument = makeShadowDocument shadowDir
, notebookConfigUnopenedUri = addExtensionToUri ".rs"
, notebookConfigOnDocumentsChanged = updateLibRs
, notebookConfigTransformInitialize = transformInitialize
, notebookConfigOnDocumentsChanged = updateLibRs shadowDir
, notebookConfigTransformInitialize = transformInitialize shadowDir
, notebookConfigCustomUriMethods = ["rust-analyzer/analyzerStatus"]
, notebookConfigIgnoreSymbol = const False
, notebookConfigLanguageName = "rust"
}

-- | rust-analyzer gets pointed at the shadow crate rather than the notebook's directory, and
-- we need didSave notifications to keep the crate on disk up to date.
transformInitialize :: TransformerMonad RustNotebookTransformer n => InitializeParams -> n InitializeParams
transformInitialize params = do
dir <- asks transformerShadowDir
pure $ params
& set rootPath (Just (InL (T.pack dir)))
& set rootUri (InL (filePathToUri dir))
& set (capabilities . textDocument . _Just . synchronization) (Just $ TextDocumentSyncClientCapabilities {
_dynamicRegistration = Just False
, _willSave = Just True
, _willSaveWaitUntil = Just False
, _didSave = Just True
})
transformInitialize :: TransformerMonad RustNotebookTransformer n => FilePath -> InitializeParams -> n InitializeParams
transformInitialize shadowDir params = pure $ params
& set rootPath (Just (InL (T.pack shadowDir)))
& set rootUri (InL (filePathToUri shadowDir))
& set (capabilities . textDocument . _Just . synchronization) (Just $ TextDocumentSyncClientCapabilities {
_dynamicRegistration = Just False
, _willSave = Just True
, _willSaveWaitUntil = Just False
, _didSave = Just True
})

makeShadowDocument :: TransformerMonad RustNotebookTransformer n => Uri -> Doc -> n (Uri, FilePath, Regex)
makeShadowDocument _origUri projected = do
TransformerState {transformerShadowDir} <- ask
makeShadowDocument :: TransformerMonad RustNotebookTransformer n => FilePath -> Uri -> Doc -> n (Uri, FilePath, Regex)
makeShadowDocument shadowDir _origUri projected = do
identifier <- makeUUID' 15
let path = transformerShadowDir </> "src" </> identifier <.> "rs"
let path = shadowDir </> "src" </> identifier <.> "rs"
createDirectoryIfMissing True (takeDirectory path)
liftIO $ T.writeFile path (Rope.toText projected)
pure (filePathToUri path, path, mkDocRegex (T.pack (identifier <.> "rs")))

updateLibRs :: TransformerMonad RustNotebookTransformer m => m ()
updateLibRs = do
updateLibRs :: TransformerMonad RustNotebookTransformer m => FilePath -> m ()
updateLibRs shadowDir = do
TransformerState {..} <- ask
docs <- readMVar transformerDocuments
let identifiers = [dropExtension (takeFileName newPath) | DocumentState {..} <- fmap snd (M.toList docs)]
let libRsContent = T.intercalate "\n" [T.pack ("mod " <> x <> ";") | x <- identifiers]
logInfoN [i|libRsContent: #{libRsContent}|]
liftIO $ createDirectoryIfMissing True (transformerShadowDir </> "src")
liftIO $ T.writeFile (transformerShadowDir </> "src" </> "lib.rs") libRsContent
liftIO $ createDirectoryIfMissing True (shadowDir </> "src")
liftIO $ T.writeFile (shadowDir </> "src" </> "lib.rs") libRsContent
2 changes: 1 addition & 1 deletion stack.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ system-ghc: true

extra-deps:
- git: https://github.com/codedownio/notebook-language-server-core.git
commit: b181af10fe24da329fba6d48581245e0d7867acb
commit: d8ca894fa723d805abaacb85f35503f72c3aec7f

# - language-rust-0.2.0.27

Expand Down
8 changes: 4 additions & 4 deletions stack.yaml.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@

packages:
- completed:
commit: b181af10fe24da329fba6d48581245e0d7867acb
commit: d8ca894fa723d805abaacb85f35503f72c3aec7f
git: https://github.com/codedownio/notebook-language-server-core.git
name: notebook-language-server-core
pantry-tree:
sha256: d07fbf4896e49b11bbf12bb2f4895dab55ed01cf2740cc7b96e494baa9cdb198
size: 1919
sha256: 1dbe24fb672a644b2664955e8a7d786688eea9c02c91af5a05b31490f7a7e29f
size: 1969
version: 0.1.0.0
original:
commit: b181af10fe24da329fba6d48581245e0d7867acb
commit: d8ca894fa723d805abaacb85f35503f72c3aec7f
git: https://github.com/codedownio/notebook-language-server-core.git
snapshots:
- completed:
Expand Down
Loading