feat!: added functioning commands for most shortcuts
mellbacon committed
Jul 14, 2023 at 14:53 UTC
40d0f24f11330a66425f9ab5f3c641e52442b7e6
2 files changed
+101
-27
src/config/commands.ts
+21
-14
@@ -1,3 +1,4 @@
1
+import { append, copy, cut, deleteChars, redoChange, undoChange } from "../lib/Editor.svelte";
2
import { addEditorTab } from "../lib/EditorTabList.svelte";
3
import { saveFile, openFile, openFolder } from "../lib/File";
4
import { appWindow } from "@tauri-apps/api/window";
@@ -35,32 +36,33 @@ export const commands = {
36
},
37
"undo": {
38
"keybind": "Control+Z",
38
- "command": () => {
39
- console.warn("Feature not implemented yet.")
39
+ "command": async () => {
40
+ await undoChange();
41
}
42
},
43
"redo": {
44
"keybind": "Control+Shift+Z",
44
- "command": () => {
45
- console.warn("Feature not implemented yet.")
45
+ "command": async () => {
46
+ await redoChange();
47
}
48
},
49
"cut": {
50
"keybind": "Control+X",
50
- "command": () => {
51
- console.warn("Feature not implemented yet.")
51
+ "command": async () => {
52
+ await cut();
53
}
54
},
55
"copy": {
56
"keybind": "Control+C",
56
- "command": () => {
57
- console.warn("Feature not implemented yet.")
57
+ "command": async () => {
58
+ await copy();
59
}
60
},
61
"paste": {
62
"keybind": "Control+V",
62
- "command": () => {
63
- console.warn("Feature not implemented yet.")
63
+ "command": async () => {
64
+ const content = await navigator.clipboard.readText();
65
+ append(content);
66
}
67
},
68
"pasteFromHistory": {
@@ -71,8 +73,8 @@ export const commands = {
73
},
74
"delete": {
75
"keybind": "Delete",
74
- "command": () => {
75
- console.warn("Feature not implemented yet.")
76
+ "command": async () => {
77
+ await deleteChars();
78
}
79
},
80
"find": {
@@ -107,8 +109,13 @@ export const commands = {
109
},
110
"fullscreen": {
111
"keybind": "F11",
110
- "command": () => {
111
- console.warn("Feature not implemented yet.")
112
+ "command": async () => {
113
+ if (await appWindow.isFullscreen()) {
114
+ appWindow.setFullscreen(false);
115
+ }
116
+ else {
117
+ appWindow.setFullscreen(true);
118
+ }
119
}
120
},
121
"runFile": {
src/lib/Editor.svelte
+80
-13
@@ -2,14 +2,14 @@
2
import {keymap, highlightSpecialChars, drawSelection, highlightActiveLine, dropCursor,
3
rectangularSelection, crosshairCursor,
4
lineNumbers, highlightActiveLineGutter, EditorView} from "@codemirror/view"
5
- import {EditorState } from "@codemirror/state"
5
+ import {EditorState} from "@codemirror/state"
6
import {defaultHighlightStyle, syntaxHighlighting} from "@codemirror/language"
7
- import {defaultKeymap, history, historyKeymap, indentWithTab} from "@codemirror/commands"
8
- import {searchKeymap} from "@codemirror/search"
7
+ import {defaultKeymap, history, indentWithTab, undo, redo, deleteCharForward, deleteToLineEnd} from "@codemirror/commands";
8
import { onMount, tick } from "svelte";
9
import { writable } from "svelte/store";
10
import { saveFile, updateSaveState } from "./File";
11
import { appSettings } from "../config/config";
12
+ import { getCurrentEditor } from "./EditorTabList.svelte";
13
14
let ref;
15
let editorView: EditorView;
@@ -35,8 +35,27 @@
35
export function getLang(ext) {
36
return getLangFromExt(ext);
37
}
38
+ export function getView() {
39
+ return editorView;
40
+ }
41
42
onMount(async () => {
43
+ // disable default copy/paste/delete keys
44
+ // instead implement our own functions for copy/paste/delete so it can be bound to different keybindings
45
+ const disabledKeys = [
46
+ {
47
+ key: "Ctrl-v",
48
+ preventDefault: true
49
+ },
50
+ {
51
+ key: "Ctrl-c",
52
+ preventDefault: true
53
+ },
54
+ {
55
+ key: "Delete",
56
+ preventDefault: true
57
+ }
58
+ ]
59
editorView = new EditorView({
60
parent: ref,
61
state: EditorState.create({
@@ -54,9 +73,8 @@
73
EditorState.allowMultipleSelections.of(true),
74
syntaxHighlighting(defaultHighlightStyle, {fallback: true}),
75
keymap.of([
57
- ...defaultKeymap,
58
- ...historyKeymap,
59
- ...searchKeymap,
76
+ ...disabledKeys,
77
+ ...defaultKeymap
78
])
79
],
80
doc: content
@@ -67,9 +85,9 @@
85
});
86
87
let _ = null;
70
- async function updateContent() {
88
+ export async function updateContent() {
89
await tick();
72
- content = editorView.state.doc.toString();1
90
+ content = editorView.state.doc.toString();
91
if (await appSettings.get("editor.autosave") === true) {
92
clearTimeout(_);
93
_ = setTimeout(async () => {
@@ -94,7 +112,7 @@
112
updateLineInfo();
113
language.set($file_info.language);
114
}
97
- function updateLineInfo() {
115
+ export function updateLineInfo() {
116
let lineNumber = editorView.state.doc.lineAt(editorView.state.selection.main.head).number;
117
let columnNumber = editorView.state.selection.ranges[0].head - editorView.state.doc.lineAt(editorView.state.selection.main.head).from;
118
line_info.set({line: lineNumber.toString(), column: (columnNumber + 1).toString()})
@@ -131,12 +149,61 @@
149
}
150
}
151
export function setEditorFontSize(value: number) {
134
- const editorContainer = document.querySelector(".cm-scroller") as HTMLElement;
135
- editorContainer.style.setProperty("font-size", `${value}px`, "important")
152
+ // there could be a better way to do all this but. eh
153
+ const editors = document.querySelectorAll(".cm-scroller");
154
+ for (const editorContainer of editors) {
155
+ (editorContainer as HTMLElement).style.setProperty("font-size", `${value}px`, "important")
156
+ }
157
}
158
export function setEditorFontFamily(family: string) {
138
- const editorContainer = document.querySelector(".cm-scroller") as HTMLElement;
139
- editorContainer.style.setProperty("font-family", family, "important");
159
+ const editors = document.querySelectorAll(".cm-scroller");
160
+ for (const editorContainer of editors) {
161
+ (editorContainer as HTMLElement).style.setProperty("font-family", family, "important")
162
+ }
163
+ }
164
+
165
+ // yes im aware how messy all these functions are but it works!
166
+ export async function append(value: string) {
167
+ let cursorpos = getCurrentEditor().getView().state.selection.main.head + value.length;
168
+ const lines = value.split("\n").length - 1;
169
+ if (lines > 0) {
170
+ cursorpos -= lines;
171
+ }
172
+ getCurrentEditor().getView().dispatch({
173
+ changes: {
174
+ from: getCurrentEditor().getView().state.selection.ranges[0].from,
175
+ to: getCurrentEditor().getView().state.selection.ranges[0].to,
176
+ insert: value,
177
+ },
178
+ selection: {anchor: cursorpos, head: cursorpos},
179
+ scrollIntoView: true
180
+ })
181
+ await getCurrentEditor().updateContent();
182
+ getCurrentEditor().updateLineInfo();
183
+ }
184
+ export async function copy() {
185
+ const selection = getCurrentEditor().getView().state.sliceDoc(getCurrentEditor().getView().state.selection.main.from, getCurrentEditor().getView().state.selection.main.to)
186
+ await navigator.clipboard.writeText(selection);
187
+ }
188
+ export async function cut() {
189
+ deleteToLineEnd(getCurrentEditor().getView())
190
+ await getCurrentEditor().updateContent();
191
+ getCurrentEditor().updateLineInfo();
192
+ }
193
+ export async function undoChange() {
194
+ undo(getCurrentEditor().getView());
195
+ await getCurrentEditor().updateContent();
196
+ getCurrentEditor().updateLineInfo();
197
+ }
198
+ export async function redoChange() {
199
+ redo(getCurrentEditor().getView());
200
+ await getCurrentEditor().updateContent();
201
+ getCurrentEditor().updateLineInfo();
202
+ }
203
+ export async function deleteChars() {
204
+ deleteCharForward(getCurrentEditor().getView());
205
+ await getCurrentEditor().updateContent();
206
+ getCurrentEditor().updateLineInfo();
207
}
208
</script>
209