Skip to content

Commit 1c40fbf

Browse files
authored
Merge pull request #518 from haskell/mpj/caps
Fill in remaining capabilities and dynamic registration options
2 parents 6ed8fe8 + d8fcd36 commit 1c40fbf

File tree

5 files changed

+120
-87
lines changed

5 files changed

+120
-87
lines changed

lsp-types/ChangeLog.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Revision history for lsp-types
22

3+
## Unreleased
4+
5+
- Add `dynamicRegistrationSupported` to `Capabilities`.
6+
- Fully update `fullCaps` for recent spec versions.
7+
38
## 2.0.2.0
49

510
- Add `Language.LSP.Protocol.Utils.Misc.prettyJSON :: Value -> Doc ann` for prettyprinting JSON,

lsp-types/src/Language/LSP/Protocol/Capabilities.hs

+88-36
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,38 @@
11
{-# LANGUAGE DuplicateRecordFields #-}
22
{-# LANGUAGE OverloadedLabels #-}
33
{-# LANGUAGE OverloadedStrings #-}
4+
{-# LANGUAGE FlexibleContexts #-}
5+
{-# LANGUAGE RankNTypes #-}
46
module Language.LSP.Protocol.Capabilities
57
(
68
fullCaps
79
, LSPVersion(..)
810
, capsForVersion
11+
, dynamicRegistrationSupported
912
) where
1013

14+
import Control.Lens
1115
import Data.Row
1216
import qualified Data.Set as Set
17+
import Data.Maybe
1318
import Language.LSP.Protocol.Types
19+
import Language.LSP.Protocol.Message
20+
import qualified Language.LSP.Protocol.Lens as L
1421
import Prelude hiding (min)
1522

1623
{-
1724
TODO: this is out-of-date/needs an audit
1825
TODO: can we generate this? process the 'since' annotations in the metamodel?
1926
-}
2027

21-
-- | Capabilities for full conformance to the current (v3.15) LSP specification.
28+
-- | Capabilities for full conformance to the current LSP specification.
2229
fullCaps :: ClientCapabilities
2330
fullCaps = capsForVersion (LSPVersion maxBound maxBound)
2431

2532
-- | A specific version of the LSP specification.
26-
data LSPVersion = LSPVersion Int Int -- ^ Construct a major.minor version
33+
data LSPVersion = LSPVersion Int Int
2734

2835
-- | Capabilities for full conformance to the LSP specification up until a version.
29-
-- Some important milestones:
30-
--
31-
-- * 3.12 textDocument/prepareRename request
32-
-- * 3.11 CodeActionOptions provided by the server
33-
-- * 3.10 hierarchical document symbols, folding ranges
34-
-- * 3.9 completion item preselect
35-
-- * 3.8 codeAction literals
36-
-- * 3.7 related information in diagnostics
37-
-- * 3.6 workspace folders, colors, goto type/implementation
38-
-- * 3.4 extended completion item and symbol item kinds
39-
-- * 3.0 dynamic registration
4036
capsForVersion :: LSPVersion -> ClientCapabilities
4137
capsForVersion (LSPVersion maj min) = caps
4238
where
@@ -45,9 +41,8 @@ capsForVersion (LSPVersion maj min) = caps
4541
, _textDocument=Just td
4642
, _window=Just window
4743
, _general=since 3 16 general
44+
, _notebookDocument=since 3 17 $ NotebookDocumentClientCapabilities $ NotebookDocumentSyncClientCapabilities dynamicReg (Just True)
4845
, _experimental=Nothing
49-
-- TODO
50-
, _notebookDocument=Nothing
5146
}
5247
w = WorkspaceClientCapabilities {
5348
_applyEdit = Just True
@@ -61,15 +56,14 @@ capsForVersion (LSPVersion maj min) = caps
6156
, _didChangeWatchedFiles = Just (DidChangeWatchedFilesClientCapabilities dynamicReg (Just True))
6257
, _symbol = Just symbolCapabilities
6358
, _executeCommand = Just (ExecuteCommandClientCapabilities dynamicReg)
59+
, _codeLens = Just (CodeLensWorkspaceClientCapabilities $ Just True)
6460
, _workspaceFolders = since 3 6 True
6561
, _configuration = since 3 6 True
6662
, _semanticTokens = since 3 16 (SemanticTokensWorkspaceClientCapabilities $ Just True)
67-
, _inlayHint = since 3 17 inlayHint
68-
-- TODO
69-
, _codeLens = Nothing
70-
, _fileOperations = Nothing
71-
, _inlineValue = Nothing
72-
, _diagnostics = Nothing
63+
, _inlayHint = since 3 17 (InlayHintWorkspaceClientCapabilities $ Just True)
64+
, _fileOperations = since 3 16 fileOperations
65+
, _inlineValue = since 3 17 (InlineValueWorkspaceClientCapabilities $ Just True)
66+
, _diagnostics = since 3 17 (DiagnosticWorkspaceClientCapabilities $ Just True)
7367
}
7468

7569
resourceOperations =
@@ -78,6 +72,15 @@ capsForVersion (LSPVersion maj min) = caps
7872
, ResourceOperationKind_Rename
7973
]
8074

75+
fileOperations = FileOperationClientCapabilities
76+
dynamicReg
77+
(Just True)
78+
(Just True)
79+
(Just True)
80+
(Just True)
81+
(Just True)
82+
(Just True)
83+
8184
symbolCapabilities = WorkspaceSymbolClientCapabilities
8285
dynamicReg
8386
(since 3 4 (#valueSet .== Just sKs))
@@ -158,13 +161,12 @@ capsForVersion (LSPVersion maj min) = caps
158161
, _selectionRange=since 3 5 (SelectionRangeClientCapabilities dynamicReg)
159162
, _callHierarchy=since 3 16 (CallHierarchyClientCapabilities dynamicReg)
160163
, _semanticTokens=since 3 16 semanticTokensCapabilities
164+
, _linkedEditingRange=since 3 16 (LinkedEditingRangeClientCapabilities dynamicReg)
165+
, _moniker=since 3 16 (MonikerClientCapabilities dynamicReg)
161166
, _inlayHint=since 3 17 inlayHintCapabilities
162-
-- TODO
163-
, _linkedEditingRange=Nothing
164-
, _moniker=Nothing
165-
, _typeHierarchy=Nothing
166-
, _inlineValue=Nothing
167-
, _diagnostic=Nothing
167+
, _typeHierarchy=since 3 17 (TypeHierarchyClientCapabilities dynamicReg)
168+
, _inlineValue=since 3 17 (InlineValueClientCapabilities dynamicReg)
169+
, _diagnostic=since 3 17 (DiagnosticClientCapabilities dynamicReg (Just True))
168170
}
169171

170172
sync =
@@ -184,16 +186,11 @@ capsForVersion (LSPVersion maj min) = caps
184186
, _contextSupport=since 3 3 True
185187
, _completionList=since 3 17 (#itemDefaults .== Just [])
186188
}
187-
188-
inlayHint =
189-
InlayHintWorkspaceClientCapabilities{
190-
_refreshSupport=since 3 17 True
191-
}
192-
189+
193190
inlayHintCapabilities =
194191
InlayHintClientCapabilities{
195192
_dynamicRegistration=dynamicReg,
196-
_resolveSupport= since 3 17 (#properties .== [])
193+
_resolveSupport=Just (#properties .== [])
197194
}
198195

199196
completionItemCapabilities =
@@ -312,8 +309,63 @@ capsForVersion (LSPVersion maj min) = caps
312309
_staleRequestSupport=since 3 16 (#cancel .== True .+ #retryOnContentModified .== [])
313310
, _regularExpressions=since 3 16 $ RegularExpressionsClientCapabilities "" Nothing
314311
, _markdown=since 3 16 $ MarkdownClientCapabilities "" Nothing (Just [])
315-
-- TODO
316-
, _positionEncodings=Nothing
312+
, _positionEncodings=since 3 17 [PositionEncodingKind_UTF16]
317313
}
318314

319315
allMarkups = [MarkupKind_PlainText, MarkupKind_Markdown]
316+
317+
-- | Whether the client supports dynamic registration for the given method.
318+
dynamicRegistrationSupported :: SMethod m -> ClientCapabilities -> Bool
319+
dynamicRegistrationSupported method caps = fromMaybe False $ case method of
320+
SMethod_WorkspaceDidChangeConfiguration -> caps ^? ws . L.didChangeConfiguration . _Just . dyn
321+
SMethod_WorkspaceDidChangeWatchedFiles -> caps ^? ws . L.didChangeWatchedFiles . _Just . dyn
322+
SMethod_WorkspaceSymbol -> caps ^? ws . L.symbol . _Just . dyn
323+
SMethod_WorkspaceExecuteCommand -> caps ^? ws . L.executeCommand . _Just . dyn
324+
SMethod_WorkspaceWillCreateFiles -> caps ^? ws . L.fileOperations . _Just . dyn
325+
SMethod_WorkspaceDidCreateFiles -> caps ^? ws . L.fileOperations . _Just . dyn
326+
SMethod_WorkspaceWillDeleteFiles -> caps ^? ws . L.fileOperations . _Just . dyn
327+
SMethod_WorkspaceDidDeleteFiles -> caps ^? ws . L.fileOperations . _Just . dyn
328+
SMethod_TextDocumentDidOpen -> caps ^? td . L.synchronization . _Just . dyn
329+
SMethod_TextDocumentDidChange -> caps ^? td . L.synchronization . _Just . dyn
330+
SMethod_TextDocumentDidClose -> caps ^? td . L.synchronization . _Just . dyn
331+
SMethod_TextDocumentCompletion -> caps ^? td . L.completion . _Just . dyn
332+
SMethod_TextDocumentHover -> caps ^? td . L.hover . _Just . dyn
333+
SMethod_TextDocumentSignatureHelp -> caps ^? td . L.signatureHelp . _Just . dyn
334+
SMethod_TextDocumentDeclaration -> caps ^? td . L.declaration . _Just . dyn
335+
SMethod_TextDocumentDefinition -> caps ^? td . L.definition . _Just . dyn
336+
SMethod_TextDocumentTypeDefinition -> caps ^? td . L.typeDefinition . _Just . dyn
337+
SMethod_TextDocumentImplementation -> caps ^? td . L.implementation . _Just . dyn
338+
SMethod_TextDocumentReferences -> caps ^? td . L.references . _Just . dyn
339+
SMethod_TextDocumentDocumentHighlight -> caps ^? td . L.documentHighlight . _Just . dyn
340+
SMethod_TextDocumentDocumentSymbol -> caps ^? td . L.documentSymbol . _Just . dyn
341+
SMethod_TextDocumentCodeAction -> caps ^? td . L.codeAction . _Just . dyn
342+
SMethod_TextDocumentCodeLens -> caps ^? td . L.codeLens . _Just . dyn
343+
SMethod_TextDocumentDocumentLink -> caps ^? td . L.documentLink . _Just . dyn
344+
SMethod_TextDocumentDocumentColor -> caps ^? td . L.colorProvider . _Just . dyn
345+
SMethod_TextDocumentColorPresentation -> caps ^? td . L.colorProvider . _Just . dyn
346+
SMethod_TextDocumentFormatting -> caps ^? td . L.formatting . _Just . dyn
347+
SMethod_TextDocumentRangeFormatting -> caps ^? td . L.rangeFormatting . _Just . dyn
348+
SMethod_TextDocumentOnTypeFormatting -> caps ^? td . L.onTypeFormatting . _Just . dyn
349+
SMethod_TextDocumentRename -> caps ^? td . L.rename . _Just . dyn
350+
SMethod_TextDocumentFoldingRange -> caps ^? td . L.foldingRange . _Just . dyn
351+
SMethod_TextDocumentSelectionRange -> caps ^? td . L.selectionRange . _Just . dyn
352+
SMethod_TextDocumentLinkedEditingRange -> caps ^? td . L.linkedEditingRange . _Just . dyn
353+
SMethod_TextDocumentPrepareCallHierarchy -> caps ^? td . L.callHierarchy . _Just . dyn
354+
SMethod_TextDocumentInlayHint -> caps ^? td . L.inlayHint . _Just . dyn
355+
SMethod_TextDocumentInlineValue -> caps ^? td . L.inlineValue . _Just . dyn
356+
SMethod_TextDocumentMoniker -> caps ^? td . L.moniker . _Just . dyn
357+
SMethod_TextDocumentPrepareTypeHierarchy -> caps ^? td . L.typeHierarchy . _Just . dyn
358+
SMethod_TextDocumentDiagnostic -> caps ^? td . L.diagnostic . _Just . dyn
359+
-- semantic tokens is messed up due to it having you register with an otherwise non-existent method
360+
--SMethod_TextDocumentSemanticTokens -> capDyn $ clientCaps ^? L.textDocument . _Just . L.semanticTokens . _Just
361+
-- Notebook document methods alway support dynamic registration, it seems?
362+
_ -> Just False
363+
where
364+
td :: Traversal' ClientCapabilities TextDocumentClientCapabilities
365+
td = L.textDocument . _Just
366+
367+
ws :: Traversal' ClientCapabilities WorkspaceClientCapabilities
368+
ws = L.workspace . _Just
369+
370+
dyn :: L.HasDynamicRegistration a (Maybe Bool) => Traversal' a Bool
371+
dyn = L.dynamicRegistration . _Just

lsp/ChangeLog.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Revision history for lsp
22

3+
## Unreleased
4+
5+
- Fix inference of server capabilities for newer methods (except notebook methods).
6+
37
## 2.2.0.0
48

59
- Many changes relating to client configuration

lsp/src/Language/LSP/Server/Core.hs

+2-42
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ import Data.Text (Text)
5454
import qualified Data.Text as T
5555
import qualified Data.UUID as UUID
5656
import Language.LSP.Diagnostics
57+
import Language.LSP.Protocol.Capabilities
5758
import qualified Language.LSP.Protocol.Lens as L
5859
import Language.LSP.Protocol.Message
5960
import qualified Language.LSP.Protocol.Message as L
@@ -551,7 +552,7 @@ registerCapability method regOpts f = do
551552
go _clientCaps True = pure Nothing
552553
go clientCaps False
553554
-- First, check to see if the client supports dynamic registration on this method
554-
| dynamicSupported clientCaps = do
555+
| dynamicRegistrationSupported method clientCaps = do
555556
uuid <- liftIO $ UUID.toText <$> getStdRandom random
556557
let registration = L.TRegistration uuid method (Just regOpts)
557558
params = L.RegistrationParams [toUntypedRegistration registration]
@@ -572,47 +573,6 @@ registerCapability method regOpts f = do
572573
pure (Just (RegistrationToken method regId))
573574
| otherwise = pure Nothing
574575

575-
-- Also I'm thinking we should move this function to somewhere in messages.hs so
576-
-- we don't forget to update it when adding new methods...
577-
capDyn :: L.HasDynamicRegistration a (Maybe Bool) => Maybe a -> Bool
578-
capDyn (Just x) = fromMaybe False $ x ^. L.dynamicRegistration
579-
capDyn Nothing = False
580-
581-
-- | Checks if client capabilities declares that the method supports dynamic registration
582-
dynamicSupported clientCaps = case method of
583-
SMethod_WorkspaceDidChangeConfiguration -> capDyn $ clientCaps ^? L.workspace . _Just . L.didChangeConfiguration . _Just
584-
SMethod_WorkspaceDidChangeWatchedFiles -> capDyn $ clientCaps ^? L.workspace . _Just . L.didChangeWatchedFiles . _Just
585-
SMethod_WorkspaceSymbol -> capDyn $ clientCaps ^? L.workspace . _Just . L.symbol . _Just
586-
SMethod_WorkspaceExecuteCommand -> capDyn $ clientCaps ^? L.workspace . _Just . L.executeCommand . _Just
587-
SMethod_TextDocumentDidOpen -> capDyn $ clientCaps ^? L.textDocument . _Just . L.synchronization . _Just
588-
SMethod_TextDocumentDidChange -> capDyn $ clientCaps ^? L.textDocument . _Just . L.synchronization . _Just
589-
SMethod_TextDocumentDidClose -> capDyn $ clientCaps ^? L.textDocument . _Just . L.synchronization . _Just
590-
SMethod_TextDocumentCompletion -> capDyn $ clientCaps ^? L.textDocument . _Just . L.completion . _Just
591-
SMethod_TextDocumentHover -> capDyn $ clientCaps ^? L.textDocument . _Just . L.hover . _Just
592-
SMethod_TextDocumentSignatureHelp -> capDyn $ clientCaps ^? L.textDocument . _Just . L.signatureHelp . _Just
593-
SMethod_TextDocumentDeclaration -> capDyn $ clientCaps ^? L.textDocument . _Just . L.declaration . _Just
594-
SMethod_TextDocumentDefinition -> capDyn $ clientCaps ^? L.textDocument . _Just . L.definition . _Just
595-
SMethod_TextDocumentTypeDefinition -> capDyn $ clientCaps ^? L.textDocument . _Just . L.typeDefinition . _Just
596-
SMethod_TextDocumentImplementation -> capDyn $ clientCaps ^? L.textDocument . _Just . L.implementation . _Just
597-
SMethod_TextDocumentReferences -> capDyn $ clientCaps ^? L.textDocument . _Just . L.references . _Just
598-
SMethod_TextDocumentDocumentHighlight -> capDyn $ clientCaps ^? L.textDocument . _Just . L.documentHighlight . _Just
599-
SMethod_TextDocumentDocumentSymbol -> capDyn $ clientCaps ^? L.textDocument . _Just . L.documentSymbol . _Just
600-
SMethod_TextDocumentCodeAction -> capDyn $ clientCaps ^? L.textDocument . _Just . L.codeAction . _Just
601-
SMethod_TextDocumentCodeLens -> capDyn $ clientCaps ^? L.textDocument . _Just . L.codeLens . _Just
602-
SMethod_TextDocumentDocumentLink -> capDyn $ clientCaps ^? L.textDocument . _Just . L.documentLink . _Just
603-
SMethod_TextDocumentDocumentColor -> capDyn $ clientCaps ^? L.textDocument . _Just . L.colorProvider . _Just
604-
SMethod_TextDocumentColorPresentation -> capDyn $ clientCaps ^? L.textDocument . _Just . L.colorProvider . _Just
605-
SMethod_TextDocumentFormatting -> capDyn $ clientCaps ^? L.textDocument . _Just . L.formatting . _Just
606-
SMethod_TextDocumentRangeFormatting -> capDyn $ clientCaps ^? L.textDocument . _Just . L.rangeFormatting . _Just
607-
SMethod_TextDocumentOnTypeFormatting -> capDyn $ clientCaps ^? L.textDocument . _Just . L.onTypeFormatting . _Just
608-
SMethod_TextDocumentRename -> capDyn $ clientCaps ^? L.textDocument . _Just . L.rename . _Just
609-
SMethod_TextDocumentFoldingRange -> capDyn $ clientCaps ^? L.textDocument . _Just . L.foldingRange . _Just
610-
SMethod_TextDocumentSelectionRange -> capDyn $ clientCaps ^? L.textDocument . _Just . L.selectionRange . _Just
611-
SMethod_TextDocumentPrepareCallHierarchy -> capDyn $ clientCaps ^? L.textDocument . _Just . L.callHierarchy . _Just
612-
SMethod_TextDocumentInlayHint -> capDyn $ clientCaps ^? L.textDocument . _Just . L.inlayHint . _Just
613-
--SMethod_TextDocumentSemanticTokens -> capDyn $ clientCaps ^? L.textDocument . _Just . L.semanticTokens . _Just
614-
_ -> False
615-
616576
-- | Sends a @client/unregisterCapability@ request and removes the handler
617577
-- for that associated registration.
618578
unregisterCapability :: MonadLsp config f => RegistrationToken m -> f ()

lsp/src/Language/LSP/Server/Processing.hs

+21-9
Original file line numberDiff line numberDiff line change
@@ -220,16 +220,20 @@ inferServerCapabilities clientCaps o h =
220220
, _semanticTokensProvider = semanticTokensProvider
221221
, _workspaceSymbolProvider = supportedBool SMethod_WorkspaceSymbol
222222
, _workspace = Just workspace
223-
-- TODO: Add something for experimental
224223
, _experimental = Nothing :: Maybe Value
225-
-- TODO
226-
, _positionEncoding = Nothing
227-
, _notebookDocumentSync = Nothing
228-
, _linkedEditingRangeProvider = Nothing
229-
, _monikerProvider = Nothing
230-
, _typeHierarchyProvider = Nothing
231-
, _inlineValueProvider = Nothing
232-
, _diagnosticProvider = Nothing
224+
-- The only encoding the VFS supports is the legacy UTF16 option at the moment
225+
, _positionEncoding = Just PositionEncodingKind_UTF16
226+
, _linkedEditingRangeProvider = supported' SMethod_TextDocumentLinkedEditingRange $
227+
InR $ InL $ LinkedEditingRangeOptions { _workDoneProgress=Nothing }
228+
, _monikerProvider = supported' SMethod_TextDocumentMoniker $
229+
InR $ InL $ MonikerOptions { _workDoneProgress=Nothing }
230+
, _typeHierarchyProvider = supported' SMethod_TextDocumentPrepareTypeHierarchy $
231+
InR $ InL $ TypeHierarchyOptions { _workDoneProgress=Nothing }
232+
, _inlineValueProvider = supported' SMethod_TextDocumentInlineValue $
233+
InR $ InL $ InlineValueOptions { _workDoneProgress=Nothing }
234+
, _diagnosticProvider = diagnosticProvider
235+
-- TODO: super unclear what to do about notebooks in general
236+
, _notebookDocumentSync = Nothing
233237
}
234238
where
235239

@@ -343,6 +347,14 @@ inferServerCapabilities clientCaps o h =
343347
-- sign up to receive notifications
344348
WorkspaceFoldersServerCapabilities (Just True) (Just (InR True))
345349

350+
diagnosticProvider = supported' SMethod_TextDocumentDiagnostic $ InL $ DiagnosticOptions
351+
{ _workDoneProgress=Nothing
352+
, _identifier=Nothing
353+
-- TODO: this is a conservative but maybe inaccurate, unclear how much it matters
354+
, _interFileDependencies=True
355+
, _workspaceDiagnostics=supported_b SMethod_WorkspaceDiagnostic
356+
}
357+
346358
-- | Invokes the registered dynamic or static handlers for the given message and
347359
-- method, as well as doing some bookkeeping.
348360
handle :: (m ~ LspM config) => LogAction m (WithSeverity LspProcessingLog) -> SClientMethod meth -> TClientMessage meth -> m ()

0 commit comments

Comments
 (0)