mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-24 10:38:59 +01:00
Hook up mapped code edits experiment for TS (#198478)
For https://github.com/microsoft/TypeScript/pull/55406
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { API } from '../tsServer/api';
|
||||
import { FileSpan } from '../tsServer/protocol/protocol';
|
||||
import { ITypeScriptServiceClient } from '../typescriptService';
|
||||
import { conditionalRegistration, requireMinVersion } from './util/dependentRegistration';
|
||||
import { Range, WorkspaceEdit } from '../typeConverters';
|
||||
import { DocumentSelector } from '../configuration/documentSelector';
|
||||
|
||||
class TsMappedEditsProvider implements vscode.MappedEditsProvider {
|
||||
constructor(
|
||||
private readonly client: ITypeScriptServiceClient
|
||||
) { }
|
||||
|
||||
async provideMappedEdits(document: vscode.TextDocument, codeBlocks: string[], context: vscode.MappedEditsContext, token: vscode.CancellationToken): Promise<vscode.WorkspaceEdit | undefined> {
|
||||
if (!this.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const file = this.client.toOpenTsFilePath(document);
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await this.client.execute('mapCode', {
|
||||
mappings: [{
|
||||
file,
|
||||
contents: codeBlocks,
|
||||
focusLocations: context.documents.map(documents => {
|
||||
return documents.flatMap((contextItem): FileSpan[] => {
|
||||
const file = this.client.toTsFilePath(contextItem.uri);
|
||||
if (!file) {
|
||||
return [];
|
||||
}
|
||||
return contextItem.ranges.map((range): FileSpan => ({ file, ...Range.toTextSpan(range) }));
|
||||
});
|
||||
}),
|
||||
}],
|
||||
}, token);
|
||||
if (response.type !== 'response' || !response.body) {
|
||||
return;
|
||||
}
|
||||
|
||||
return WorkspaceEdit.fromFileCodeEdits(this.client, response.body);
|
||||
}
|
||||
|
||||
private isEnabled(): boolean {
|
||||
return vscode.workspace.getConfiguration('typescript').get<boolean>('experimental.mappedCodeEdits.enabled', false);
|
||||
}
|
||||
}
|
||||
|
||||
export function register(
|
||||
selector: DocumentSelector,
|
||||
client: ITypeScriptServiceClient,
|
||||
) {
|
||||
return conditionalRegistration([
|
||||
requireMinVersion(client, API.v540)
|
||||
], () => {
|
||||
const provider = new TsMappedEditsProvider(client);
|
||||
return vscode.chat.registerMappedEditsProvider(selector.semantic, provider);
|
||||
});
|
||||
}
|
||||
@@ -77,6 +77,7 @@ export default class LanguageProvider extends Disposable {
|
||||
import('./languageFeatures/inlayHints').then(provider => this._register(provider.register(selector, this.description, this.client, this.fileConfigurationManager, this.telemetryReporter))),
|
||||
import('./languageFeatures/jsDocCompletions').then(provider => this._register(provider.register(selector, this.description, this.client, this.fileConfigurationManager))),
|
||||
import('./languageFeatures/linkedEditing').then(provider => this._register(provider.register(selector, this.client))),
|
||||
import('./languageFeatures/mappedCodeEditProvider').then(provider => this._register(provider.register(selector, this.client))),
|
||||
import('./languageFeatures/organizeImports').then(provider => this._register(provider.register(selector, this.client, this.commandManager, this.fileConfigurationManager, this.telemetryReporter))),
|
||||
import('./languageFeatures/quickFix').then(provider => this._register(provider.register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.client.diagnosticsManager, this.telemetryReporter))),
|
||||
import('./languageFeatures/refactor').then(provider => this._register(provider.register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.telemetryReporter))),
|
||||
|
||||
@@ -35,6 +35,7 @@ export class API {
|
||||
public static readonly v500 = API.fromSimpleString('5.0.0');
|
||||
public static readonly v510 = API.fromSimpleString('5.1.0');
|
||||
public static readonly v520 = API.fromSimpleString('5.2.0');
|
||||
public static readonly v540 = API.fromSimpleString('5.4.0');
|
||||
|
||||
public static fromVersionString(versionString: string): API {
|
||||
let version = semver.valid(versionString);
|
||||
|
||||
@@ -19,5 +19,43 @@ declare module 'typescript/lib/tsserverlibrary' {
|
||||
interface Response {
|
||||
readonly _serverType?: ServerType;
|
||||
}
|
||||
|
||||
export interface MapCodeRequestArgs {
|
||||
/// The files and changes to try and apply/map.
|
||||
mappings: MapCodeRequestDocumentMapping[];
|
||||
|
||||
/// Edits to apply to the current workspace before performing the mapping.
|
||||
updates?: FileCodeEdits[]
|
||||
}
|
||||
|
||||
export interface MapCodeRequestDocumentMapping {
|
||||
/// The file for the request (absolute pathname required). Null/undefined
|
||||
/// if specific file is unknown.
|
||||
file?: string;
|
||||
|
||||
/// Optional name of project that contains file
|
||||
projectFileName?: string;
|
||||
|
||||
/// The specific code to map/insert/replace in the file.
|
||||
contents: string[];
|
||||
|
||||
/// Areas of "focus" to inform the code mapper with. For example, cursor
|
||||
/// location, current selection, viewport, etc. Nested arrays denote
|
||||
/// priority: toplevel arrays are more important than inner arrays, and
|
||||
/// inner array priorities are based on items within that array. Items
|
||||
/// earlier in the arrays have higher priority.
|
||||
focusLocations?: FileSpan[][];
|
||||
}
|
||||
|
||||
export interface MapCodeRequest extends Request {
|
||||
command: 'mapCode',
|
||||
arguments: MapCodeRequestArgs;
|
||||
}
|
||||
|
||||
export interface MapCodeResponse extends Response {
|
||||
body: FileCodeEdits[]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ interface StandardTsServerRequests {
|
||||
'findSourceDefinition': [Proto.FileLocationRequestArgs, Proto.DefinitionResponse];
|
||||
'getMoveToRefactoringFileSuggestions': [Proto.GetMoveToRefactoringFileSuggestionsRequestArgs, Proto.GetMoveToRefactoringFileSuggestions];
|
||||
'linkedEditingRange': [Proto.FileLocationRequestArgs, Proto.LinkedEditingRangeResponse];
|
||||
'mapCode': [Proto.MapCodeRequestArgs, Proto.MapCodeResponse];
|
||||
}
|
||||
|
||||
interface NoResponseTsServerRequests {
|
||||
|
||||
Reference in New Issue
Block a user