Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/browser/controller/editContext/clipboardUtils.ts
3296 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
import { IViewModel } from '../../../common/viewModel.js';
6
import { Range } from '../../../common/core/range.js';
7
import { isWindows } from '../../../../base/common/platform.js';
8
import { Mimes } from '../../../../base/common/mime.js';
9
10
export function getDataToCopy(viewModel: IViewModel, modelSelections: Range[], emptySelectionClipboard: boolean, copyWithSyntaxHighlighting: boolean): ClipboardDataToCopy {
11
const rawTextToCopy = viewModel.getPlainTextToCopy(modelSelections, emptySelectionClipboard, isWindows);
12
const newLineCharacter = viewModel.model.getEOL();
13
14
const isFromEmptySelection = (emptySelectionClipboard && modelSelections.length === 1 && modelSelections[0].isEmpty());
15
const multicursorText = (Array.isArray(rawTextToCopy) ? rawTextToCopy : null);
16
const text = (Array.isArray(rawTextToCopy) ? rawTextToCopy.join(newLineCharacter) : rawTextToCopy);
17
18
let html: string | null | undefined = undefined;
19
let mode: string | null = null;
20
if (CopyOptions.forceCopyWithSyntaxHighlighting || (copyWithSyntaxHighlighting && text.length < 65536)) {
21
const richText = viewModel.getRichTextToCopy(modelSelections, emptySelectionClipboard);
22
if (richText) {
23
html = richText.html;
24
mode = richText.mode;
25
}
26
}
27
const dataToCopy: ClipboardDataToCopy = {
28
isFromEmptySelection,
29
multicursorText,
30
text,
31
html,
32
mode
33
};
34
return dataToCopy;
35
}
36
37
/**
38
* Every time we write to the clipboard, we record a bit of extra metadata here.
39
* Every time we read from the cipboard, if the text matches our last written text,
40
* we can fetch the previous metadata.
41
*/
42
export class InMemoryClipboardMetadataManager {
43
public static readonly INSTANCE = new InMemoryClipboardMetadataManager();
44
45
private _lastState: InMemoryClipboardMetadata | null;
46
47
constructor() {
48
this._lastState = null;
49
}
50
51
public set(lastCopiedValue: string, data: ClipboardStoredMetadata): void {
52
this._lastState = { lastCopiedValue, data };
53
}
54
55
public get(pastedText: string): ClipboardStoredMetadata | null {
56
if (this._lastState && this._lastState.lastCopiedValue === pastedText) {
57
// match!
58
return this._lastState.data;
59
}
60
this._lastState = null;
61
return null;
62
}
63
}
64
65
export interface ClipboardDataToCopy {
66
isFromEmptySelection: boolean;
67
multicursorText: string[] | null | undefined;
68
text: string;
69
html: string | null | undefined;
70
mode: string | null;
71
}
72
73
export interface ClipboardStoredMetadata {
74
version: 1;
75
id: string | undefined;
76
isFromEmptySelection: boolean | undefined;
77
multicursorText: string[] | null | undefined;
78
mode: string | null;
79
}
80
81
export const CopyOptions = {
82
forceCopyWithSyntaxHighlighting: false
83
};
84
85
interface InMemoryClipboardMetadata {
86
lastCopiedValue: string;
87
data: ClipboardStoredMetadata;
88
}
89
90
export const ClipboardEventUtils = {
91
92
getTextData(clipboardData: DataTransfer): [string, ClipboardStoredMetadata | null] {
93
const text = clipboardData.getData(Mimes.text);
94
let metadata: ClipboardStoredMetadata | null = null;
95
const rawmetadata = clipboardData.getData('vscode-editor-data');
96
if (typeof rawmetadata === 'string') {
97
try {
98
metadata = <ClipboardStoredMetadata>JSON.parse(rawmetadata);
99
if (metadata.version !== 1) {
100
metadata = null;
101
}
102
} catch (err) {
103
// no problem!
104
}
105
}
106
if (text.length === 0 && metadata === null && clipboardData.files.length > 0) {
107
// no textual data pasted, generate text from file names
108
const files: File[] = Array.prototype.slice.call(clipboardData.files, 0);
109
return [files.map(file => file.name).join('\n'), null];
110
}
111
return [text, metadata];
112
},
113
114
setTextData(clipboardData: DataTransfer, text: string, html: string | null | undefined, metadata: ClipboardStoredMetadata): void {
115
clipboardData.setData(Mimes.text, text);
116
if (typeof html === 'string') {
117
clipboardData.setData('text/html', html);
118
}
119
clipboardData.setData('vscode-editor-data', JSON.stringify(metadata));
120
}
121
};
122
123