feature: added basic syntax highlighting
Signed-off-by: mellobacon <mellodev@outlook.com>
mellobacon committed
Oct 31, 2023 at 18:49 UTC
0bbb4035fcb1cd65235cb77834f4ca52fa51ee4a
3 files changed
+111
-19
src/config/syntaxhighlighting/dark.ts
new
+83
@@ -0,0 +1,83 @@
1
+import {HighlightStyle, syntaxHighlighting} from "@codemirror/language"
2
+import {tags as t} from "@lezer/highlight"
3
+
4
+// Using https://github.com/one-dark/vscode-one-dark-theme/ as reference for the colors
5
+
6
+const chalky = "#e5c07b",
7
+ coral = "#e06c75",
8
+ cyan = "#56b6c2",
9
+ invalid = "#ffffff",
10
+ ivory = "#abb2bf",
11
+ stone = "#7d8799", // Brightened compared to original to increase contrast
12
+ malibu = "#61afef",
13
+ sage = "#98c379",
14
+ whiskey = "#d19a66",
15
+ violet = "#c678dd",
16
+ darkBackground = "#21252b",
17
+ highlightBackground = "#2c313a",
18
+ background = "#282c34",
19
+ tooltipBackground = "#353a42",
20
+ selection = "#3E4451",
21
+ cursor = "#528bff"
22
+
23
+/// The colors used in the theme, as CSS color strings.
24
+export const color = {
25
+ chalky,
26
+ coral,
27
+ cyan,
28
+ invalid,
29
+ ivory,
30
+ stone,
31
+ malibu,
32
+ sage,
33
+ whiskey,
34
+ violet,
35
+ darkBackground,
36
+ highlightBackground,
37
+ background,
38
+ tooltipBackground,
39
+ selection,
40
+ cursor
41
+}
42
+
43
+/// The highlighting style for code in the One Dark theme.
44
+export const oneDarkHighlightStyle = HighlightStyle.define([
45
+ {tag: t.keyword,
46
+ color: violet},
47
+ {tag: [t.name, t.deleted, t.character, t.propertyName, t.macroName],
48
+ color: coral},
49
+ {tag: [t.function(t.variableName), t.labelName],
50
+ color: malibu},
51
+ {tag: [t.color, t.constant(t.name), t.standard(t.name)],
52
+ color: whiskey},
53
+ {tag: [t.definition(t.name), t.separator],
54
+ color: ivory},
55
+ {tag: [t.typeName, t.className, t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace],
56
+ color: chalky},
57
+ {tag: [t.operator, t.operatorKeyword, t.url, t.escape, t.regexp, t.link, t.special(t.string)],
58
+ color: cyan},
59
+ {tag: [t.meta, t.comment],
60
+ color: stone},
61
+ {tag: t.strong,
62
+ fontWeight: "bold"},
63
+ {tag: t.emphasis,
64
+ fontStyle: "italic"},
65
+ {tag: t.strikethrough,
66
+ textDecoration: "line-through"},
67
+ {tag: t.link,
68
+ color: stone,
69
+ textDecoration: "underline"},
70
+ {tag: t.heading,
71
+ fontWeight: "bold",
72
+ color: coral},
73
+ {tag: [t.atom, t.bool, t.special(t.variableName)],
74
+ color: whiskey },
75
+ {tag: [t.processingInstruction, t.string, t.inserted],
76
+ color: sage},
77
+ {tag: t.invalid,
78
+ color: invalid},
79
+])
80
+
81
+/// Extension to enable the One Dark theme (both the editor theme and
82
+/// the highlight style).
83
+export const oneDark = syntaxHighlighting(oneDarkHighlightStyle, {fallback: true});
\ No newline at end of file
src/lib/Editor.svelte
+27
-18
@@ -1,15 +1,14 @@
1
<script lang="ts">
2
import {keymap, highlightSpecialChars, drawSelection, highlightActiveLine, dropCursor,
3
rectangularSelection, crosshairCursor,
4
- lineNumbers, highlightActiveLineGutter, EditorView} from "@codemirror/view"
5
- import {EditorState} from "@codemirror/state"
6
- import {defaultHighlightStyle, syntaxHighlighting} from "@codemirror/language"
7
- import {defaultKeymap, history, indentWithTab, undo, redo, deleteCharForward, deleteToLineEnd} from "@codemirror/commands";
4
+ lineNumbers, highlightActiveLineGutter, EditorView} from "@codemirror/view";
5
+ import {EditorState, Compartment} from "@codemirror/state"
6
+ import {defaultKeymap, history, indentWithTab } from "@codemirror/commands";
7
import { onMount, tick } from "svelte";
8
import { writable } from "svelte/store";
9
import { saveFile, updateSaveState } from "./File";
10
import { appSettings } from "../config/config";
12
- import { getCurrentEditor } from "./EditorTabList.svelte";
11
+ import { oneDark } from "../config/syntaxhighlighting/dark";
12
13
let ref;
14
let editorView: EditorView;
@@ -24,6 +23,7 @@
23
"hasBom": false,
24
"readonly": false,
25
});
26
+ const lang = new Compartment();
27
28
export function updateFileInfo(file) {
29
file_info.set(file);
@@ -34,8 +34,23 @@
34
export function getFileContent() {
35
return content;
36
}
37
- export function getLang(ext) {
38
- return getLangFromExt(ext);
37
+ export async function getLang(ext) {
38
+ if (ext === "txt") {
39
+ return "Plain Text";
40
+ }
41
+ let language = getLangFromExt(ext);
42
+ if (language) {
43
+ const mode = await language.load();
44
+ setLangMode(mode);
45
+ return language.name;
46
+ }
47
+
48
+ return "Unknown";
49
+ }
50
+ function setLangMode(mode) {
51
+ editorView.dispatch({
52
+ effects: lang.reconfigure(mode)
53
+ })
54
}
55
export function getEncoding() {
56
return $file_info.encoding;
@@ -62,8 +77,10 @@
77
crosshairCursor(),
78
rectangularSelection(),
79
keymap.of([indentWithTab]),
80
+ lang.of([]),
81
EditorState.allowMultipleSelections.of(true),
66
- syntaxHighlighting(defaultHighlightStyle, {fallback: true}),
82
+ //syntaxHighlighting(defaultHighlightStyle, {fallback: true}),
83
+ oneDark,
84
keymap.of([
85
...defaultKeymap
86
]),
@@ -134,19 +151,11 @@
151
export const line_info = writable({line: "-", column: "-"});
152
export const language = writable("Unknown");
153
export const encoding = writable({value: "UTF-8", hasBom: false});
154
+ const langmode = writable(null);
155
156
export function getLangFromExt(ext: string) {
139
- if (ext === "txt") {
140
- return "Plain Text";
141
- }
142
-
157
let cmlang = cmLangs.find(l => l.extensions.includes(ext));
144
- if (cmlang) {
145
- return cmlang.name;
146
- }
147
- else {
148
- return "Unknown";
149
- }
158
+ return cmlang;
159
}
160
export function setEditorFontSize(value: number) {
161
// there could be a better way to do all this but. eh
src/lib/Tab/Tab.ts
+1
-1
@@ -87,7 +87,7 @@ export class Tab {
87
"filename": tab.label,
88
"path": tab.path,
89
"fileType": fileData.extension,
90
- "language": content.getLang(fileData.extension),
90
+ "language": await content.getLang(fileData.extension),
91
"encoding": fileData.encoding,
92
"hasBom": fileData.bom,
93
"readonly": false,