Skip to content

Commit

Permalink
Add the workspace/foldingRange/refresh method (#1309)
Browse files Browse the repository at this point in the history
* Add the workspace/foldingRange/refresh method

* Add proposed tag

* Move refreshSupport to workspace scoped capability

---------

Co-authored-by: Dirk Bäumer <dirkb@microsoft.com>
  • Loading branch information
c-claeys and dbaeumer committed Sep 18, 2023
1 parent a57d7f1 commit 4e057d5
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 11 deletions.
24 changes: 19 additions & 5 deletions client/src/common/foldingRange.ts
Expand Up @@ -4,12 +4,12 @@
* ------------------------------------------------------------------------------------------ */

import {
languages as Languages, Disposable, TextDocument, ProviderResult, FoldingRange as VFoldingRange, FoldingContext, FoldingRangeProvider
languages as Languages, Disposable, TextDocument, ProviderResult, FoldingRange as VFoldingRange, FoldingContext, FoldingRangeProvider, EventEmitter
} from 'vscode';

import {
ClientCapabilities, CancellationToken, ServerCapabilities, DocumentSelector, FoldingRangeRequest, FoldingRangeParams,
FoldingRangeRegistrationOptions, FoldingRangeOptions, FoldingRangeKind
FoldingRangeRegistrationOptions, FoldingRangeOptions, FoldingRangeKind, FoldingRangeRefreshRequest
} from 'vscode-languageserver-protocol';

import { TextDocumentLanguageFeature, FeatureClient, ensure } from './features';
Expand All @@ -22,7 +22,12 @@ export interface FoldingRangeProviderMiddleware {
provideFoldingRanges?: (this: void, document: TextDocument, context: FoldingContext, token: CancellationToken, next: ProvideFoldingRangeSignature) => ProviderResult<VFoldingRange[]>;
}

export class FoldingRangeFeature extends TextDocumentLanguageFeature<boolean | FoldingRangeOptions, FoldingRangeRegistrationOptions, FoldingRangeProvider, FoldingRangeProviderMiddleware> {
export type FoldingRangeProviderShape = {
provider: FoldingRangeProvider;
onDidChangeFoldingRange: EventEmitter<void>;
};

export class FoldingRangeFeature extends TextDocumentLanguageFeature<boolean | FoldingRangeOptions, FoldingRangeRegistrationOptions, FoldingRangeProviderShape, FoldingRangeProviderMiddleware> {

constructor(client: FeatureClient<FoldingRangeProviderMiddleware>) {
super(client, FoldingRangeRequest.type);
Expand All @@ -35,19 +40,28 @@ export class FoldingRangeFeature extends TextDocumentLanguageFeature<boolean | F
capability.lineFoldingOnly = true;
capability.foldingRangeKind = { valueSet: [ FoldingRangeKind.Comment, FoldingRangeKind.Imports, FoldingRangeKind.Region ] };
capability.foldingRange = { collapsedText: false };
ensure(ensure(capabilities, 'workspace')!, 'foldingRange')!.refreshSupport = true;
}

public initialize(capabilities: ServerCapabilities, documentSelector: DocumentSelector): void {
this._client.onRequest(FoldingRangeRefreshRequest.type, async () => {
for (const provider of this.getAllProviders()) {
provider.onDidChangeFoldingRange.fire();
}
});

let [id, options] = this.getRegistration(documentSelector, capabilities.foldingRangeProvider);
if (!id || !options) {
return;
}
this.register({ id: id, registerOptions: options });
}

protected registerLanguageProvider(options: FoldingRangeRegistrationOptions): [Disposable, FoldingRangeProvider] {
protected registerLanguageProvider(options: FoldingRangeRegistrationOptions): [Disposable, FoldingRangeProviderShape] {
const selector = options.documentSelector!;
const eventEmitter: EventEmitter<void> = new EventEmitter<void>();
const provider: FoldingRangeProvider = {
onDidChangeFoldingRanges: eventEmitter.event,
provideFoldingRanges: (document, context, token) => {
const client = this._client;
const provideFoldingRanges: ProvideFoldingRangeSignature = (document, _, token) => {
Expand All @@ -69,6 +83,6 @@ export class FoldingRangeFeature extends TextDocumentLanguageFeature<boolean | F
: provideFoldingRanges(document, context, token);
}
};
return [Languages.registerFoldingRangeProvider(this._client.protocol2CodeConverter.asDocumentSelector(selector), provider), provider];
return [Languages.registerFoldingRangeProvider(this._client.protocol2CodeConverter.asDocumentSelector(selector), provider), { provider: provider, onDidChangeFoldingRange: eventEmitter }];
}
}
41 changes: 41 additions & 0 deletions protocol/metaModel.json
Expand Up @@ -243,6 +243,17 @@
},
"documentation": "A request to provide folding ranges in a document. The request's\nparameter is of type {@link FoldingRangeParams}, the\nresponse is of type {@link FoldingRangeList} or a Thenable\nthat resolves to such."
},
{
"method": "workspace/foldingRange/refresh",
"result": {
"kind": "base",
"name": "null"
},
"messageDirection": "serverToClient",
"documentation": "@since 3.18.0\n@proposed",
"since": "3.18.0",
"proposed": true
},
{
"method": "textDocument/declaration",
"result": {
Expand Down Expand Up @@ -10670,6 +10681,17 @@
"optional": true,
"documentation": "Capabilities specific to the diagnostic requests scoped to the\nworkspace.\n\n@since 3.17.0.",
"since": "3.17.0."
},
{
"name": "foldingRange",
"type": {
"kind": "reference",
"name": "FoldingRangeWorkspaceClientCapabilities"
},
"optional": true,
"documentation": "Capabilities specific to the folding range requests scoped to the workspace.\n\n@since 3.18.0\n@proposed",
"since": "3.18.0",
"proposed": true
}
],
"documentation": "Workspace specific client capabilities."
Expand Down Expand Up @@ -11489,6 +11511,25 @@
"documentation": "Workspace client capabilities specific to diagnostic pull requests.\n\n@since 3.17.0",
"since": "3.17.0"
},
{
"name": "FoldingRangeWorkspaceClientCapabilities",
"properties": [
{
"name": "refreshSupport",
"type": {
"kind": "base",
"name": "boolean"
},
"optional": true,
"documentation": "Whether the client implementation supports a refresh request sent from the\nserver to the client.\n\nNote that this event is global and will force the client to refresh all\nfolding ranges currently shown. It should be used with absolute care and is\nuseful for situation where a server for example detects a project wide\nchange that requires such a calculation.\n\n@since 3.18.0\n@proposed",
"since": "3.18.0",
"proposed": true
}
],
"documentation": "Client workspace capabilities specific to folding ranges\n\n@since 3.18.0\n@proposed",
"since": "3.18.0",
"proposed": true
},
{
"name": "TextDocumentSyncClientCapabilities",
"properties": [
Expand Down
38 changes: 36 additions & 2 deletions protocol/src/common/protocol.foldingRange.ts
Expand Up @@ -3,10 +3,10 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { RequestHandler } from 'vscode-jsonrpc';
import { RequestHandler, RequestHandler0 } from 'vscode-jsonrpc';
import { TextDocumentIdentifier, uinteger, FoldingRange, FoldingRangeKind } from 'vscode-languageserver-types';

import { MessageDirection, ProtocolRequestType } from './messages';
import { MessageDirection, ProtocolRequestType, ProtocolRequestType0 } from './messages';
import type {
TextDocumentRegistrationOptions, StaticRegistrationOptions, PartialResultParams, WorkDoneProgressParams, WorkDoneProgressOptions
} from './protocol';
Expand Down Expand Up @@ -68,6 +68,29 @@ export interface FoldingRangeClientCapabilities {
};
}

/**
* Client workspace capabilities specific to folding ranges
*
* @since 3.18.0
* @proposed
*/
export interface FoldingRangeWorkspaceClientCapabilities {

/**
* Whether the client implementation supports a refresh request sent from the
* server to the client.
*
* Note that this event is global and will force the client to refresh all
* folding ranges currently shown. It should be used with absolute care and is
* useful for situation where a server for example detects a project wide
* change that requires such a calculation.
*
* @since 3.18.0
* @proposed
*/
refreshSupport?: boolean;
}

export interface FoldingRangeOptions extends WorkDoneProgressOptions {
}

Expand Down Expand Up @@ -96,3 +119,14 @@ export namespace FoldingRangeRequest {
export const type = new ProtocolRequestType<FoldingRangeParams, FoldingRange[] | null, FoldingRange[], void, FoldingRangeRegistrationOptions>(method);
export type HandlerSignature = RequestHandler<FoldingRangeParams, FoldingRange[] | null, void>;
}

/**
* @since 3.18.0
* @proposed
*/
export namespace FoldingRangeRefreshRequest {
export const method: `workspace/foldingRange/refresh` = `workspace/foldingRange/refresh`;
export const messageDirection: MessageDirection = MessageDirection.serverToClient;
export const type = new ProtocolRequestType0<void, void, void, void>(method);
export type HandlerSignature = RequestHandler0<void, void>;
}
12 changes: 10 additions & 2 deletions protocol/src/common/protocol.ts
Expand Up @@ -43,7 +43,7 @@ import {
} from './protocol.colorProvider';

import {
FoldingRangeClientCapabilities, FoldingRangeOptions, FoldingRangeRequest, FoldingRangeParams, FoldingRangeRegistrationOptions
FoldingRangeClientCapabilities, FoldingRangeOptions, FoldingRangeRequest, FoldingRangeParams, FoldingRangeRegistrationOptions, FoldingRangeRefreshRequest, FoldingRangeWorkspaceClientCapabilities
} from './protocol.foldingRange';

import {
Expand Down Expand Up @@ -556,6 +556,14 @@ export interface WorkspaceClientCapabilities {
* @since 3.17.0.
*/
diagnostics?: DiagnosticWorkspaceClientCapabilities;

/**
* Capabilities specific to the folding range requests scoped to the workspace.
*
* @since 3.18.0
* @proposed
*/
foldingRange?: FoldingRangeWorkspaceClientCapabilities;
}

/**
Expand Down Expand Up @@ -3874,7 +3882,7 @@ export {
WorkspaceFoldersRequest, DidChangeWorkspaceFoldersNotification, DidChangeWorkspaceFoldersParams, WorkspaceFoldersChangeEvent,
ConfigurationRequest, ConfigurationParams, ConfigurationItem,
DocumentColorRequest, ColorPresentationRequest, DocumentColorOptions, DocumentColorParams, ColorPresentationParams, DocumentColorRegistrationOptions,
FoldingRangeClientCapabilities, FoldingRangeOptions, FoldingRangeRequest, FoldingRangeParams, FoldingRangeRegistrationOptions,
FoldingRangeClientCapabilities, FoldingRangeOptions, FoldingRangeRequest, FoldingRangeParams, FoldingRangeRegistrationOptions, FoldingRangeRefreshRequest,
DeclarationClientCapabilities, DeclarationRequest, DeclarationParams, DeclarationRegistrationOptions, DeclarationOptions,
SelectionRangeClientCapabilities, SelectionRangeOptions, SelectionRangeParams, SelectionRangeRequest, SelectionRangeRegistrationOptions,
WorkDoneProgressBegin, WorkDoneProgressReport, WorkDoneProgressEnd, WorkDoneProgress, WorkDoneProgressCreateParams,
Expand Down
49 changes: 49 additions & 0 deletions server/src/common/foldingRange.ts
@@ -0,0 +1,49 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */
'use strict';

import { FoldingRange, Disposable, FoldingRangeParams, FoldingRangeRefreshRequest, FoldingRangeRequest } from 'vscode-languageserver-protocol';

import type { Feature, _Languages, ServerRequestHandler } from './server';

/**
* Shape of the folding range feature
*/
export interface FoldingRangeFeatureShape {
foldingRange: {
/**
* Ask the client to refresh all folding ranges
*
* @since 3.18.0.
* @proposed
*/
refresh(): Promise<void>;

/**
* Installs a handler for the folding range request.
*
* @param handler The corresponding handler.
*/
on(handler: ServerRequestHandler<FoldingRangeParams, FoldingRange[] | undefined | null, FoldingRange[], void>): Disposable;
};
}

export const FoldingRangeFeature: Feature<_Languages, FoldingRangeFeatureShape> = (Base) => {
return class extends Base implements FoldingRangeFeatureShape {
public get foldingRange() {
return {
refresh: (): Promise<void> => {
return this.connection.sendRequest(FoldingRangeRefreshRequest.type);
},
on: (handler: ServerRequestHandler<FoldingRangeParams, FoldingRange[] | undefined | null, FoldingRange[], void>): Disposable => {
const type = FoldingRangeRequest.type;
return this.connection.onRequest(type, (params, cancel) => {
return handler(params, cancel, this.attachWorkDoneProgress(params), this.attachPartialResultProgress(type, params));
});
}
};
}
};
};
5 changes: 3 additions & 2 deletions server/src/common/server.ts
Expand Up @@ -39,6 +39,7 @@ import { FileOperationsFeature, FileOperationsFeatureShape } from './fileOperati
import { LinkedEditingRangeFeature, LinkedEditingRangeFeatureShape } from './linkedEditingRange';
import { TypeHierarchyFeatureShape, TypeHierarchyFeature } from './typeHierarchy';
import { InlineValueFeatureShape, InlineValueFeature } from './inlineValue';
import { FoldingRangeFeatureShape, FoldingRangeFeature } from './foldingRange';
// import { InlineCompletionFeatureShape, InlineCompletionFeature } from './inlineCompletion.proposed';
import { InlayHintFeatureShape, InlayHintFeature } from './inlayHint';
import { DiagnosticFeatureShape, DiagnosticFeature } from './diagnostic';
Expand Down Expand Up @@ -828,8 +829,8 @@ export class _LanguagesImpl implements Remote, _Languages {
}
}

export type Languages = _Languages & CallHierarchy & SemanticTokensFeatureShape & LinkedEditingRangeFeatureShape & TypeHierarchyFeatureShape & InlineValueFeatureShape & InlayHintFeatureShape & DiagnosticFeatureShape & MonikerFeatureShape;
const LanguagesImpl: new () => Languages = MonikerFeature(DiagnosticFeature(InlayHintFeature(InlineValueFeature(TypeHierarchyFeature(LinkedEditingRangeFeature(SemanticTokensFeature(CallHierarchyFeature(_LanguagesImpl)))))))) as (new () => Languages);
export type Languages = _Languages & CallHierarchy & SemanticTokensFeatureShape & LinkedEditingRangeFeatureShape & TypeHierarchyFeatureShape & InlineValueFeatureShape & InlayHintFeatureShape & DiagnosticFeatureShape & MonikerFeatureShape & FoldingRangeFeatureShape;
const LanguagesImpl: new () => Languages = FoldingRangeFeature(MonikerFeature(DiagnosticFeature(InlayHintFeature(InlineValueFeature(TypeHierarchyFeature(LinkedEditingRangeFeature(SemanticTokensFeature(CallHierarchyFeature(_LanguagesImpl))))))))) as (new () => Languages);

export interface _Notebooks extends FeatureBase {
connection: Connection;
Expand Down

0 comments on commit 4e057d5

Please sign in to comment.