diff --git a/electron/config.js b/electron/config.js index dfacda02..c93be581 100644 --- a/electron/config.js +++ b/electron/config.js @@ -32,6 +32,7 @@ const schema = { "bufferPath" : {type: "string", default: ""}, "showInDock": {type: "boolean", default: true}, "showInMenu": {type: "boolean", default: false}, + "bracketClosing": {type: "boolean", default: false}, }, }, @@ -59,6 +60,7 @@ const defaults = { bufferPath: "", showInDock: true, showInMenu: false, + bracketClosing: false, }, theme: "system", } diff --git a/src/components/App.vue b/src/components/App.vue index 0588adae..a5f871aa 100644 --- a/src/components/App.vue +++ b/src/components/App.vue @@ -118,6 +118,7 @@ :keymap="settings.keymap" :showLineNumberGutter="settings.showLineNumberGutter" :showFoldGutter="settings.showFoldGutter" + :bracketClosing="settings.bracketClosing" class="editor" ref="editor" @openLanguageSelector="openLanguageSelector" diff --git a/src/components/Editor.vue b/src/components/Editor.vue index 95ca6838..49db4b73 100644 --- a/src/components/Editor.vue +++ b/src/components/Editor.vue @@ -19,6 +19,10 @@ type: Boolean, default: true, }, + bracketClosing: { + type: Boolean, + default: false, + }, }, components: {}, @@ -61,6 +65,7 @@ keymap: this.keymap, showLineNumberGutter: this.showLineNumberGutter, showFoldGutter: this.showFoldGutter, + bracketClosing: this.bracketClosing, }) window._heynote_editor = this.editor window.document.addEventListener("currenciesLoaded", this.onCurrenciesLoaded) @@ -116,6 +121,10 @@ showFoldGutter(show) { this.editor.setFoldGutter(show) }, + + bracketClosing(value) { + this.editor.setBracketClosing(value) + }, }, methods: { diff --git a/src/components/settings/Settings.vue b/src/components/settings/Settings.vue index a202b02f..5f330ca1 100644 --- a/src/components/settings/Settings.vue +++ b/src/components/settings/Settings.vue @@ -30,6 +30,7 @@ globalHotkey: this.initialSettings.globalHotkey, showInDock: this.initialSettings.showInDock, showInMenu: this.initialSettings.showInMenu, + bracketClosing: this.initialSettings.bracketClosing, autoUpdate: this.initialSettings.autoUpdate, activeTab: "general", @@ -64,6 +65,7 @@ showInDock: this.showInDock, showInMenu: this.showInMenu || !this.showInDock, autoUpdate: this.autoUpdate, + bracketClosing: this.bracketClosing, }) }, } @@ -83,6 +85,12 @@ :activeTab="activeTab" @click="activeTab = 'general'" /> + Show In - Show in dock - Show system tray + + + + + + + + Input settings + + + Auto-close brackets and quotation marks + diff --git a/src/editor/editor.js b/src/editor/editor.js index d215f99b..2b212082 100644 --- a/src/editor/editor.js +++ b/src/editor/editor.js @@ -2,6 +2,7 @@ import { Annotation, EditorState, Compartment } from "@codemirror/state" import { EditorView, keymap, drawSelection, ViewPlugin, lineNumbers } from "@codemirror/view" import { indentUnit, forceParsing, foldGutter } from "@codemirror/language" import { markdown } from "@codemirror/lang-markdown" +import { closeBrackets } from "@codemirror/autocomplete"; import { heynoteLight } from "./theme/light.js" import { heynoteDark } from "./theme/dark.js" @@ -41,6 +42,7 @@ export class HeynoteEditor { keymap="default", showLineNumberGutter=true, showFoldGutter=true, + bracketClosing=false, }) { this.element = element this.themeCompartment = new Compartment @@ -49,6 +51,7 @@ export class HeynoteEditor { this.lineNumberCompartment = new Compartment this.foldGutterCompartment = new Compartment this.readOnlyCompartment = new Compartment + this.closeBracketsCompartment = new Compartment this.deselectOnCopy = keymap === "emacs" const state = EditorState.create({ @@ -62,6 +65,8 @@ export class HeynoteEditor { customSetup, this.foldGutterCompartment.of(showFoldGutter ? [foldGutter()] : []), + this.closeBracketsCompartment.of(bracketClosing ? [closeBrackets()] : []), + this.readOnlyCompartment.of([]), this.themeCompartment.of(theme === "dark" ? heynoteDark : heynoteLight), @@ -177,6 +182,12 @@ export class HeynoteEditor { }) } + setBracketClosing(value) { + this.view.dispatch({ + effects: this.closeBracketsCompartment.reconfigure(value ? [closeBrackets()] : []), + }) + } + formatCurrentBlock() { formatBlockContent({ state: this.view.state, diff --git a/tests/auto-closing-brackets.spec.js b/tests/auto-closing-brackets.spec.js new file mode 100644 index 00000000..c4704697 --- /dev/null +++ b/tests/auto-closing-brackets.spec.js @@ -0,0 +1,27 @@ +import { test, expect } from "@playwright/test"; +import { HeynotePage } from "./test-utils.js"; + +let heynotePage + +test.beforeEach(async ({ page }) => { + heynotePage = new HeynotePage(page) + await heynotePage.goto() +}); + +test("test bracket closing default off", async ({ page }) => { + await page.locator("body").pressSequentially("{") + expect(await heynotePage.getBlockContent(0)).toBe("{") +}) + +test("test bracket closing", async ({ page }) => { + await page.locator("css=.status-block.settings").click() + await page.locator("css=li.tab-editing").click() + await page.getByLabel("Auto-close brackets and quotation marks").click() + await page.locator("body").press("Escape") + await page.locator("body").pressSequentially("{") + expect(await heynotePage.getBlockContent(0)).toBe("{}") + await page.locator("body").press("Backspace") + expect(await heynotePage.getBlockContent(0)).toBe("") + await page.locator("body").pressSequentially("(hej") + await page.locator("body").pressSequentially("(hej)") +}) diff --git a/webapp/bridge.js b/webapp/bridge.js index 3ce14d14..98048fbe 100644 --- a/webapp/bridge.js +++ b/webapp/bridge.js @@ -64,6 +64,7 @@ let initialSettings = { emacsMetaKey: "meta", showLineNumberGutter: true, showFoldGutter: true, + bracketClosing: false, } if (settingsData !== null) { initialSettings = Object.assign(initialSettings, JSON.parse(settingsData))