From 3b00170082e91d0dd68d7faf9b07c12b853642e9 Mon Sep 17 00:00:00 2001 From: Andrea Date: Tue, 28 Apr 2026 14:54:46 +0200 Subject: [PATCH] keep track of clientCapabilities --- src/DAP/Adaptor.hs | 4 ++++ src/DAP/Server.hs | 16 +++++++++++----- src/DAP/Types.hs | 5 +++++ 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/DAP/Adaptor.hs b/src/DAP/Adaptor.hs index f15d779..15b3bae 100644 --- a/src/DAP/Adaptor.hs +++ b/src/DAP/Adaptor.hs @@ -59,6 +59,7 @@ module DAP.Adaptor , runAdaptorRequest , withRequest , getHandle + , getClientCapabilities ) where ---------------------------------------------------------------------------- import Control.Concurrent.Lifted ( fork, killThread ) @@ -230,6 +231,9 @@ getAppStore = asks appStore getCommand :: Adaptor app Request Command getCommand = command <$> asks request ---------------------------------------------------------------------------- +getClientCapabilities :: Adaptor app request (Maybe InitializeRequestArguments) +getClientCapabilities = asks clientCapabilities +------------------------------------------------------------------------------- -- | 'sendRaw' (internal use only) -- Sends a raw JSON payload to the editor. No "seq", "type" or "command" fields are set. -- The message is still encoded with the ProtocolMessage Header, byte count, and CRLF. diff --git a/src/DAP/Server.hs b/src/DAP/Server.hs index 23bf0fb..ab5537f 100644 --- a/src/DAP/Server.hs +++ b/src/DAP/Server.hs @@ -37,7 +37,7 @@ import Control.Exception ( Exception , toException , throwIO ) import Control.Monad ( void ) -import Data.Aeson ( decodeStrict, eitherDecode, Value, FromJSON ) +import Data.Aeson ( decodeStrict, eitherDecode, Value, FromJSON, Result (..), fromJSON ) import Data.Aeson.Encode.Pretty ( encodePretty ) import Data.ByteString ( ByteString ) import Data.Char ( isDigit ) @@ -124,6 +124,7 @@ initAdaptorState logAction handle address appStore serverConfig = do handleLock <- newMVar () sessionId <- newIORef Nothing let request = () + let clientCapabilities = Nothing pure AdaptorLocal { .. } @@ -142,16 +143,21 @@ serviceClient -> IO () serviceClient communicate ackResp lcl = do rrr_or_nextRequest <- runAdaptorPoly lcl st getRequest - case rrr_or_nextRequest of + lcl' <- case rrr_or_nextRequest of Right nextRequest -> do - let lcl' = lcl{ request = nextRequest } + let lcl' = lcl{ request = nextRequest, clientCapabilities = clientCaps nextRequest } runAdaptorRequest lcl' st $ communicate (command nextRequest) - Left rrr -> + pure (void lcl') + Left rrr -> do runAdaptorPoly lcl st $ ackResp rrr - serviceClient communicate ackResp lcl + pure lcl + serviceClient communicate ackResp lcl' where st = AdaptorState MessageTypeResponse [] + clientCaps Request{command = CommandInitialize, args = Just (fromJSON -> Success v) } + = Just v + clientCaps _ = clientCapabilities lcl ---------------------------------------------------------------------------- -- | Handle exceptions from client threads, parse and log accordingly. -- Detects if client failed with `TerminateServer` and kills the server accordingly by sending an exception to the main thread. diff --git a/src/DAP/Types.hs b/src/DAP/Types.hs index 863d174..de9dc69 100644 --- a/src/DAP/Types.hs +++ b/src/DAP/Types.hs @@ -14,6 +14,7 @@ {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE LambdaCase #-} ---------------------------------------------------------------------------- module DAP.Types @@ -299,9 +300,13 @@ data AdaptorLocal app request = AdaptorLocal , logAction :: LogAction IO DAPLog -- ^ Where to send log output -- + , clientCapabilities :: Maybe InitializeRequestArguments + -- ^ Taken from Initialize Command Requests + , request :: request -- ^ Connection Request information, if we are responding to a request. } + deriving Functor ---------------------------------------------------------------------------- type SessionId = Text