Path: blob/main/src/vs/editor/browser/controller/editContext/clipboardUtils.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/4import { IViewModel } from '../../../common/viewModel.js';5import { Range } from '../../../common/core/range.js';6import { isWindows } from '../../../../base/common/platform.js';7import { Mimes } from '../../../../base/common/mime.js';89export function getDataToCopy(viewModel: IViewModel, modelSelections: Range[], emptySelectionClipboard: boolean, copyWithSyntaxHighlighting: boolean): ClipboardDataToCopy {10const rawTextToCopy = viewModel.getPlainTextToCopy(modelSelections, emptySelectionClipboard, isWindows);11const newLineCharacter = viewModel.model.getEOL();1213const isFromEmptySelection = (emptySelectionClipboard && modelSelections.length === 1 && modelSelections[0].isEmpty());14const multicursorText = (Array.isArray(rawTextToCopy) ? rawTextToCopy : null);15const text = (Array.isArray(rawTextToCopy) ? rawTextToCopy.join(newLineCharacter) : rawTextToCopy);1617let html: string | null | undefined = undefined;18let mode: string | null = null;19if (CopyOptions.forceCopyWithSyntaxHighlighting || (copyWithSyntaxHighlighting && text.length < 65536)) {20const richText = viewModel.getRichTextToCopy(modelSelections, emptySelectionClipboard);21if (richText) {22html = richText.html;23mode = richText.mode;24}25}26const dataToCopy: ClipboardDataToCopy = {27isFromEmptySelection,28multicursorText,29text,30html,31mode32};33return dataToCopy;34}3536/**37* Every time we write to the clipboard, we record a bit of extra metadata here.38* Every time we read from the cipboard, if the text matches our last written text,39* we can fetch the previous metadata.40*/41export class InMemoryClipboardMetadataManager {42public static readonly INSTANCE = new InMemoryClipboardMetadataManager();4344private _lastState: InMemoryClipboardMetadata | null;4546constructor() {47this._lastState = null;48}4950public set(lastCopiedValue: string, data: ClipboardStoredMetadata): void {51this._lastState = { lastCopiedValue, data };52}5354public get(pastedText: string): ClipboardStoredMetadata | null {55if (this._lastState && this._lastState.lastCopiedValue === pastedText) {56// match!57return this._lastState.data;58}59this._lastState = null;60return null;61}62}6364export interface ClipboardDataToCopy {65isFromEmptySelection: boolean;66multicursorText: string[] | null | undefined;67text: string;68html: string | null | undefined;69mode: string | null;70}7172export interface ClipboardStoredMetadata {73version: 1;74id: string | undefined;75isFromEmptySelection: boolean | undefined;76multicursorText: string[] | null | undefined;77mode: string | null;78}7980export const CopyOptions = {81forceCopyWithSyntaxHighlighting: false82};8384interface InMemoryClipboardMetadata {85lastCopiedValue: string;86data: ClipboardStoredMetadata;87}8889export const ClipboardEventUtils = {9091getTextData(clipboardData: DataTransfer): [string, ClipboardStoredMetadata | null] {92const text = clipboardData.getData(Mimes.text);93let metadata: ClipboardStoredMetadata | null = null;94const rawmetadata = clipboardData.getData('vscode-editor-data');95if (typeof rawmetadata === 'string') {96try {97metadata = <ClipboardStoredMetadata>JSON.parse(rawmetadata);98if (metadata.version !== 1) {99metadata = null;100}101} catch (err) {102// no problem!103}104}105if (text.length === 0 && metadata === null && clipboardData.files.length > 0) {106// no textual data pasted, generate text from file names107const files: File[] = Array.prototype.slice.call(clipboardData.files, 0);108return [files.map(file => file.name).join('\n'), null];109}110return [text, metadata];111},112113setTextData(clipboardData: DataTransfer, text: string, html: string | null | undefined, metadata: ClipboardStoredMetadata): void {114clipboardData.setData(Mimes.text, text);115if (typeof html === 'string') {116clipboardData.setData('text/html', html);117}118clipboardData.setData('vscode-editor-data', JSON.stringify(metadata));119}120};121122123