Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/markdown-language-features/src/languageFeatures/updateLinksOnPaste.ts
3292 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import * as vscode from 'vscode';
7
import { MdLanguageClient } from '../client/client';
8
import { Mime } from '../util/mimes';
9
10
class UpdatePastedLinksEditProvider implements vscode.DocumentPasteEditProvider {
11
12
public static readonly kind = vscode.DocumentDropOrPasteEditKind.Text.append('updateLinks', 'markdown');
13
14
public static readonly metadataMime = 'application/vnd.vscode.markdown.updatelinks.metadata';
15
16
constructor(
17
private readonly _client: MdLanguageClient,
18
) { }
19
20
async prepareDocumentPaste(document: vscode.TextDocument, ranges: readonly vscode.Range[], dataTransfer: vscode.DataTransfer, token: vscode.CancellationToken): Promise<void> {
21
if (!this._isEnabled(document)) {
22
return;
23
}
24
25
const metadata = await this._client.prepareUpdatePastedLinks(document.uri, ranges, token);
26
if (token.isCancellationRequested) {
27
return;
28
}
29
30
dataTransfer.set(UpdatePastedLinksEditProvider.metadataMime, new vscode.DataTransferItem(metadata));
31
}
32
33
async provideDocumentPasteEdits(
34
document: vscode.TextDocument,
35
ranges: readonly vscode.Range[],
36
dataTransfer: vscode.DataTransfer,
37
context: vscode.DocumentPasteEditContext,
38
token: vscode.CancellationToken,
39
): Promise<vscode.DocumentPasteEdit[] | undefined> {
40
if (!this._isEnabled(document)) {
41
return;
42
}
43
44
const metadata = dataTransfer.get(UpdatePastedLinksEditProvider.metadataMime)?.value;
45
if (!metadata) {
46
return;
47
}
48
49
const textItem = dataTransfer.get(Mime.textPlain);
50
const text = await textItem?.asString();
51
if (!text || token.isCancellationRequested) {
52
return;
53
}
54
55
// TODO: Handle cases such as:
56
// - copy empty line
57
// - Copy with multiple cursors and paste into multiple locations
58
// - ...
59
const edits = await this._client.getUpdatePastedLinksEdit(document.uri, ranges.map(x => new vscode.TextEdit(x, text)), metadata, token);
60
if (!edits?.length || token.isCancellationRequested) {
61
return;
62
}
63
64
const pasteEdit = new vscode.DocumentPasteEdit('', vscode.l10n.t("Paste and update pasted links"), UpdatePastedLinksEditProvider.kind);
65
const workspaceEdit = new vscode.WorkspaceEdit();
66
workspaceEdit.set(document.uri, edits.map(x => new vscode.TextEdit(new vscode.Range(x.range.start.line, x.range.start.character, x.range.end.line, x.range.end.character,), x.newText)));
67
pasteEdit.additionalEdit = workspaceEdit;
68
69
if (!context.only || !UpdatePastedLinksEditProvider.kind.contains(context.only)) {
70
pasteEdit.yieldTo = [vscode.DocumentDropOrPasteEditKind.Text];
71
}
72
73
return [pasteEdit];
74
}
75
76
private _isEnabled(document: vscode.TextDocument): boolean {
77
return vscode.workspace.getConfiguration('markdown', document.uri).get<boolean>('editor.updateLinksOnPaste.enabled', true);
78
}
79
}
80
81
export function registerUpdatePastedLinks(selector: vscode.DocumentSelector, client: MdLanguageClient) {
82
return vscode.languages.registerDocumentPasteEditProvider(selector, new UpdatePastedLinksEditProvider(client), {
83
copyMimeTypes: [UpdatePastedLinksEditProvider.metadataMime],
84
providedPasteEditKinds: [UpdatePastedLinksEditProvider.kind],
85
pasteMimeTypes: [UpdatePastedLinksEditProvider.metadataMime],
86
});
87
}
88
89