Skip to content

Use dynamic registration for folding range options #413

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 1, 2021
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
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,23 @@ public struct CompletionRegistrationOptions: RegistrationOptions, TextDocumentRe
}
}

/// Folding range registration options.
public struct FoldingRangeRegistrationOptions: RegistrationOptions, TextDocumentRegistrationOptionsProtocol, Hashable {
public var textDocumentRegistrationOptions: TextDocumentRegistrationOptions
public var foldingRangeOptions: FoldingRangeOptions

public init(documentSelector: DocumentSelector? = nil, foldingRangeOptions: FoldingRangeOptions) {
self.textDocumentRegistrationOptions =
TextDocumentRegistrationOptions(documentSelector: documentSelector)
self.foldingRangeOptions = foldingRangeOptions
}

public func encodeIntoLSPAny(dict: inout [String: LSPAny]) {
textDocumentRegistrationOptions.encodeIntoLSPAny(dict: &dict)
// foldingRangeOptions is currently empty.
}
}

public struct SemanticTokensRegistrationOptions: RegistrationOptions, TextDocumentRegistrationOptionsProtocol, Hashable {
/// Method for registration, which defers from the actual requests' methods
/// since this registration handles multiple requests.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,11 @@ public struct CompletionOptions: Codable, Hashable {
}
}

public struct FoldingRangeOptions: Codable, Hashable {
/// Currently empty in the spec.
public init() {}
}

public struct SignatureHelpOptions: Codable, Hashable {
/// The characters that trigger signature help automatically.
public var triggerCharacters: [String]?
Expand Down
35 changes: 35 additions & 0 deletions Sources/SourceKitLSP/CapabilityRegistry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ public final class CapabilityRegistry {
/// Dynamically registered completion options.
private var completion: [CapabilityRegistration: CompletionRegistrationOptions] = [:]

/// Dynamically registered folding range options.
private var foldingRange: [CapabilityRegistration: FoldingRangeRegistrationOptions] = [:]

/// Dynamically registered semantic tokens options.
private var semanticTokens: [CapabilityRegistration: SemanticTokensRegistrationOptions] = [:]

Expand All @@ -36,6 +39,10 @@ public final class CapabilityRegistry {
clientCapabilities.textDocument?.completion?.dynamicRegistration == true
}

public var clientHasDynamicFoldingRangeRegistration: Bool {
clientCapabilities.textDocument?.foldingRange?.dynamicRegistration == true
}

public var clientHasDynamicSemanticTokensRegistration: Bool {
clientCapabilities.textDocument?.semanticTokens?.dynamicRegistration == true
}
Expand Down Expand Up @@ -68,6 +75,34 @@ public final class CapabilityRegistry {
registerOnClient(registration)
}

/// Dynamically register folding range capabilities if the client supports it and
/// we haven't yet registered any folding range capabilities for the given
/// languages.
public func registerFoldingRangeIfNeeded(
options: FoldingRangeOptions,
for languages: [Language],
registerOnClient: ClientRegistrationHandler
) {
guard clientHasDynamicFoldingRangeRegistration else { return }
if let registration = registration(for: languages, in: foldingRange) {
if options != registration.foldingRangeOptions {
log("Unable to register new folding range options \(options) for " +
"\(languages) due to pre-existing options \(registration.foldingRangeOptions)", level: .warning)
}
return
}
let registrationOptions = FoldingRangeRegistrationOptions(
documentSelector: self.documentSelector(for: languages),
foldingRangeOptions: options)
let registration = CapabilityRegistration(
method: FoldingRangeRequest.method,
registerOptions: self.encode(registrationOptions))

self.foldingRange[registration] = registrationOptions

registerOnClient(registration)
}

/// Dynamically register semantic tokens capabilities if the client supports
/// it and we haven't yet registered any semantic tokens capabilities for the
/// given languages.
Expand Down
7 changes: 6 additions & 1 deletion Sources/SourceKitLSP/SourceKitServer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ extension SourceKitServer {
supportsCodeActions: true
)),
colorProvider: .bool(true),
foldingRangeProvider: .bool(true),
foldingRangeProvider: .bool(!registry.clientHasDynamicFoldingRangeRegistration),
executeCommandProvider: ExecuteCommandOptions(
commands: builtinSwiftCommands // FIXME: Clangd commands?
)
Expand All @@ -563,6 +563,11 @@ extension SourceKitServer {
self.dynamicallyRegisterCapability($0, registry)
}
}
if server.foldingRangeProvider?.isSupported == true {
registry.registerFoldingRangeIfNeeded(options: FoldingRangeOptions(), for: languages) {
self.dynamicallyRegisterCapability($0, registry)
}
}
if let semanticTokensOptions = server.semanticTokensProvider {
registry.registerSemanticTokensIfNeeded(options: semanticTokensOptions, for: languages) {
self.dynamicallyRegisterCapability($0, registry)
Expand Down