From c67aba614a978b7587f6885e3f630ac19f1c9559 Mon Sep 17 00:00:00 2001 From: thomasjm Date: Sun, 11 Oct 2026 20:28:04 -0700 Subject: [PATCH] Let the config decide which documents to handle and whether to write the shadow file --- app/Main.hs | 22 +++++++++-------- src/Transform/Config.hs | 52 ++++++++++++++++++++--------------------- stack.yaml | 2 +- stack.yaml.lock | 8 +++---- 4 files changed, 42 insertions(+), 42 deletions(-) diff --git a/app/Main.hs b/app/Main.hs index 6a14444..488495a 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -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 @@ -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|] @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/src/Transform/Config.hs b/src/Transform/Config.hs index 23de74d..58b0a7b 100644 --- a/src/Transform/Config.hs +++ b/src/Transform/Config.hs @@ -24,14 +24,15 @@ 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" @@ -39,34 +40,31 @@ rustNotebookConfig = NotebookConfig { -- | 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 diff --git a/stack.yaml b/stack.yaml index 1e62eec..6812b7c 100644 --- a/stack.yaml +++ b/stack.yaml @@ -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 diff --git a/stack.yaml.lock b/stack.yaml.lock index e3c441d..3846166 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -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: