diff --git a/src/app/editor.ts b/src/app/editor.ts index 73cba68..7b0850c 100644 --- a/src/app/editor.ts +++ b/src/app/editor.ts @@ -1,9 +1,4 @@ -import { - Transaction, - StateEffect, - Compartment, - Extension, -} from "@codemirror/state"; +import { Transaction, Compartment, Extension } from "@codemirror/state"; import { EditorView, keymap, @@ -27,8 +22,10 @@ import { } from "@codemirror/language"; import { languages } from "@codemirror/language-data"; import { highlightSelectionMatches, searchKeymap } from "@codemirror/search"; +import van from "vanjs-core"; import { OpenFile } from "./filestate"; +import { Displayable } from "./editorgrid"; const fixedHeightEditor = EditorView.theme({ "&": { @@ -44,12 +41,13 @@ const fixedHeightEditor = EditorView.theme({ ".cm-scroller": { overflow: "auto scroll" }, }); -export class Editor { +export class Editor implements Displayable { view: EditorView; file: OpenFile; deleteFn?: () => void; private wordWrapCompartment = new Compartment(); + private languageCompartment = new Compartment(); dispatch(tr: Transaction, inhibitSync = false) { this.view.update([tr]); @@ -95,6 +93,7 @@ export class Editor { fixedHeightEditor, kmap, this.wordWrapCompartment.of(EditorView.lineWrapping), + this.languageCompartment.of([]), lineNumbers(), highlightSpecialChars(), foldGutter(), @@ -113,12 +112,16 @@ export class Editor { // lintKeymap, ], }); - LanguageDescription.matchFilename(languages, file.filePath.val) - ?.load() - .then((Lang) => { - const eff = StateEffect.appendConfig.of(Lang); - this.view.dispatch({ effects: [eff] }); - }); + + van.derive(() => { + LanguageDescription.matchFilename(languages, file.filePath.val) + ?.load() + .then((Lang) => { + // const eff = StateEffect.appendConfig.of(Lang); + const eff = this.languageCompartment.reconfigure(Lang); + this.view.dispatch({ effects: [eff] }); + }); + }); } get dom() { @@ -130,9 +133,13 @@ export class Editor { this.view.focus(); } + title(): string { + return this.file.filePath.val + (this.file.isDirty() ? "*" : ""); + } + changeWidth(increment: number) { const w = parseInt(window.getComputedStyle(this.view.dom).width, 10); - this.view.dom.style.width = (w + increment) + 'px'; + this.view.dom.style.width = w + increment + "px"; return true; } diff --git a/src/app/editorgrid.ts b/src/app/editorgrid.ts index 5743fa5..70e37d9 100644 --- a/src/app/editorgrid.ts +++ b/src/app/editorgrid.ts @@ -6,7 +6,18 @@ import { OpenFile } from "./filestate"; import * as u from "./utils"; import { Editor } from "./editor"; -const EditorWrapper = (editor: State, del: () => void, k: number) => { +export interface Displayable { + setDeleteFunction(del: () => void): void; + title(): string; + close(): void; + dom: HTMLElement; +} + +const EditorWrapper = ( + editor: State, + del: () => void, + k: number, +) => { // Set the delete function on the editor when it's created van.derive(() => { if (editor.val) { @@ -18,12 +29,7 @@ const EditorWrapper = (editor: State, del: () => void, k: number) => { { class: "flex flex-col" }, v.div( { class: "flex" }, - v.span( - { class: "mx-1 flex-1" }, - () => - editor.val.file.filePath.val + - (editor.val.file.isDirty() ? "*" : ""), - ), + v.span({ class: "mx-1 flex-1" }, () => editor.val.title()), u.InlineButton(() => editor.val.close(), "Close", "❌"), ), v.div({ class: "flex-auto h-4" }, editor.val.dom), @@ -55,6 +61,7 @@ const TabHeader = (tab: State, del: () => void, k: number) => v.span({ class: "mx-1 flex-1" }, "Tab " + k), u.InlineButton(del, "Close", "❌"), ); + const EditorGrid = (tab: State, del: () => void, k: number) => { console.log("Rendering", tab.val, "with key", k); const main = v.main({ @@ -64,12 +71,15 @@ const EditorGrid = (tab: State, del: () => void, k: number) => { vanX.list(main, tab.val, EditorWrapper); return main; }; + const TabBar = v.div({ class: "flex-none flex" }); + export const EditorTabs = v.div( { class: "flex flex-col flex-auto min-w-4", }, TabBar, ); + vanX.list(TabBar, editors, TabHeader); vanX.list(EditorTabs, editors, EditorGrid); diff --git a/src/app/filestate.ts b/src/app/filestate.ts index 8be28ef..9100815 100644 --- a/src/app/filestate.ts +++ b/src/app/filestate.ts @@ -40,13 +40,14 @@ export class OpenFile { } private setPath(path: string) { - delete openFiles[this.filePath?.val]; + delete openFiles[this.filePath.val]; this.filePath.val = path; openFiles[path] = this; + // TODO: what if openFiles[path] already exists? } async saveFile() { - if (this.filePath) { + if (this.filePath.val) { await window.electronAPI.saveFile( this.rootState.val.doc.toString(), this.filePath.val,