Better handle moves of multiple markdown links (#161354)

This makes the markdown language service handle moving/renaming multiple files instead of making multiple calls into the language service
This commit is contained in:
Matt Bierner
2022-09-20 21:53:58 -07:00
committed by GitHub
parent 5f291e5bd3
commit 333754f29b
6 changed files with 33 additions and 32 deletions

View File

@@ -5,7 +5,7 @@
import type Token = require('markdown-it/lib/token');
import * as vscode from 'vscode';
import { RequestType } from 'vscode-languageclient';
import { FileRename, RequestType } from 'vscode-languageclient';
import type * as lsp from 'vscode-languageserver-types';
import type * as md from 'vscode-markdown-languageservice';
@@ -30,7 +30,7 @@ export const findMarkdownFilesInWorkspace = new RequestType<{}, string[], any>('
//#region To server
export const getReferencesToFileInWorkspace = new RequestType<{ uri: string }, lsp.Location[], any>('markdown/getReferencesToFileInWorkspace');
export const getEditForFileRenames = new RequestType<Array<{ oldUri: string; newUri: string }>, lsp.WorkspaceEdit, any>('markdown/getEditForFileRenames');
export const getEditForFileRenames = new RequestType<Array<FileRename>, { participatingRenames: readonly FileRename[]; edit: lsp.WorkspaceEdit }, any>('markdown/getEditForFileRenames');
export const fs_watcher_onChange = new RequestType<{ id: number; uri: string; kind: 'create' | 'change' | 'delete' }, void, any>('markdown/fs/watcher/onChange');

View File

@@ -69,18 +69,11 @@ class UpdateLinksOnFileRenameHandler extends Disposable {
const renames = Array.from(this._pendingRenames);
this._pendingRenames.clear();
const edit = new vscode.WorkspaceEdit();
const resourcesBeingRenamed: vscode.Uri[] = [];
const result = await this.getEditsForFileRename(renames, noopToken);
for (const { oldUri, newUri } of renames) {
if (await this.withEditsForFileRename(edit, oldUri, newUri, noopToken)) {
resourcesBeingRenamed.push(newUri);
}
}
if (edit.size) {
if (await this.confirmActionWithUser(resourcesBeingRenamed)) {
await vscode.workspace.applyEdit(edit);
if (result && result.edit.size) {
if (await this.confirmActionWithUser(result.resourcesBeingRenamed)) {
await vscode.workspace.applyEdit(result.edit);
}
}
}
@@ -194,25 +187,25 @@ class UpdateLinksOnFileRenameHandler extends Disposable {
return false;
}
private async withEditsForFileRename(
workspaceEdit: vscode.WorkspaceEdit,
oldUri: vscode.Uri,
newUri: vscode.Uri,
token: vscode.CancellationToken,
): Promise<boolean> {
const edit = await this.client.getEditForFileRenames([{ oldUri: oldUri.toString(), newUri: newUri.toString() }], token);
if (!edit.documentChanges?.length) {
return false;
private async getEditsForFileRename(renames: readonly RenameAction[], token: vscode.CancellationToken): Promise<{ edit: vscode.WorkspaceEdit; resourcesBeingRenamed: vscode.Uri[] } | undefined> {
const result = await this.client.getEditForFileRenames(renames.map(rename => ({ oldUri: rename.oldUri.toString(), newUri: rename.newUri.toString() })), token);
if (!result?.edit.documentChanges?.length) {
return undefined;
}
for (const change of edit.documentChanges as TextDocumentEdit[]) {
const workspaceEdit = new vscode.WorkspaceEdit();
for (const change of result.edit.documentChanges as TextDocumentEdit[]) {
const uri = vscode.Uri.parse(change.textDocument.uri);
for (const edit of change.edits) {
workspaceEdit.replace(uri, convertRange(edit.range), edit.newText);
}
}
return true;
return {
edit: workspaceEdit,
resourcesBeingRenamed: result.participatingRenames.map(x => vscode.Uri.parse(x.newUri)),
};
}
private getConfirmMessage(start: string, resourcesToConfirm: readonly vscode.Uri[]): string {