-
Notifications
You must be signed in to change notification settings - Fork 37
/
copypaste.ts
73 lines (65 loc) · 1.79 KB
/
copypaste.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/**
* (c) 2022, Micro:bit Educational Foundation and contributors
*
* SPDX-License-Identifier: MIT
*/
import { Extension } from "@codemirror/state";
import { EditorView } from "@codemirror/view";
import { deployment } from "../../deployment";
import { CodeInsertType } from "./dnd";
import { calculateChanges } from "./edits";
export interface PasteContext {
code: string;
codeWithImports: string;
type: CodeInsertType;
id?: string;
}
let pasteContext: PasteContext | undefined;
/**
* Set the copied code snippet.
*
* We can't represent it on the clipboard as FF doesn't yet support ClipboardItem.
*/
export const copyCodeSnippet = (context: PasteContext | undefined) => {
pasteContext = context;
};
const copyPasteHandlers = () => [
EditorView.domEventHandlers({
paste(event, view) {
if (!view.state.facet(EditorView.editable)) {
return;
}
if (!pasteContext) {
return;
}
if (
event.clipboardData?.getData("text").replace(/\r\n/g, "\n") !==
pasteContext.code
) {
// Must have happened since the code snippet copy.
pasteContext = undefined;
return;
}
event.preventDefault();
deployment.logging.event({
type: "code-paste",
message: pasteContext.id,
});
const line = view.state.doc.lineAt(view.state.selection.ranges[0].from);
const lineNumber = line.number;
const column = view.state.selection.ranges[0].from - line.from;
view.dispatch(
calculateChanges(
view.state,
pasteContext.codeWithImports,
pasteContext.type,
lineNumber,
Math.floor(column / 4),
true
)
);
view.focus();
},
}),
];
export const copyPasteSupport = (): Extension => [copyPasteHandlers()];