From f3c5a49fbf648d116f2fdf5cf2ea41d5eb513c49 Mon Sep 17 00:00:00 2001 From: Jonatan Heyman Date: Fri, 3 Mar 2023 00:57:33 +0100 Subject: [PATCH] Add ability to format code for JSON, JS, CSS, HTML and Markdown blocks --- electron/initial-content.ts | 2 ++ package-lock.json | 16 ++++++++++ package.json | 1 + src/editor/block/format-code.js | 55 +++++++++++++++++++++++++++++++++ src/editor/keymap.js | 5 ++- 5 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 src/editor/block/format-code.js diff --git a/electron/initial-content.ts b/electron/initial-content.ts index ef0cb6f..618f7f2 100644 --- a/electron/initial-content.ts +++ b/electron/initial-content.ts @@ -13,6 +13,7 @@ Welcome to Heynote! [${modChar} + Up] Goto previous block [${modChar} + A] Select all text in a note block. Press again to select the whole scratchpad [${modChar} + ⌥ + Up/Down]  Add additional cursor above/below +[${modChar} + B]  Format block content (works for JSON, JavaScript, HTML, CSS and Markdown) ∞∞∞math This is a Math block. Here, rows are evaluated as math expressions. @@ -40,6 +41,7 @@ Welcome to Heynote! [${modChar} + Up] Goto previous block [${modChar} + A] Select all text in a note block. Press again to select the whole scratchpad [${modChar} + ⌥ + Up/Down]  Add additional cursor above/below +[${modChar} + B]  Format block content (works for JSON, JavaScript, HTML, CSS and Markdown) ∞∞∞math This is a Math block. Here, rows are evaluated as math expressions. diff --git a/package-lock.json b/package-lock.json index e5cfff6..01d4dd9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,6 +34,7 @@ "electron-builder": "^23.6.0", "electron-store": "^8.1.0", "fs-jetpack": "^5.1.0", + "prettier": "^2.8.4", "sass": "^1.57.1", "typescript": "^4.9.4", "vite": "^4.0.3", @@ -4088,6 +4089,21 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/prettier": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz", + "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", diff --git a/package.json b/package.json index 87c71af..e31d397 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "electron-builder": "^23.6.0", "electron-store": "^8.1.0", "fs-jetpack": "^5.1.0", + "prettier": "^2.8.4", "sass": "^1.57.1", "typescript": "^4.9.4", "vite": "^4.0.3", diff --git a/src/editor/block/format-code.js b/src/editor/block/format-code.js new file mode 100644 index 0000000..d7711de --- /dev/null +++ b/src/editor/block/format-code.js @@ -0,0 +1,55 @@ +import { EditorSelection } from "@codemirror/state" + +import { formatWithCursor, getSupportInfo } from "prettier" +import babelParser from "prettier/esm/parser-babel.mjs" +import htmlParser from "prettier/esm/parser-html.mjs" +import cssParser from "prettier/esm/parser-postcss.mjs" +import markdownParser from "prettier/esm/parser-markdown.mjs" + +import { getActiveNoteBlock } from "./block.js" + + +const PARSER_MAP = { + "json": {parser:"json-stringify", plugins: [babelParser]}, + "javascript": {parser:"babel", plugins: [babelParser]}, + "html": {parser:"html", plugins: [htmlParser]}, + "css": {parser:"css", plugins: [cssParser]}, + "markdown": {parser:"markdown", plugins: [markdownParser]}, +} + + +export const formatBlockContent = ({ state, dispatch }) => { + if (state.readOnly) + return false + const block = getActiveNoteBlock(state) + + const langName = block.language.name + if (!(langName in PARSER_MAP)) + return false + + // get current cursor position + const cursorPos = state.selection.asSingle().ranges[0].to + // get block content + const content = state.sliceDoc(block.content.from, block.content.to) + + //console.log("prettier supports:", getSupportInfo()) + const formattedContent = formatWithCursor(content, { + cursorOffset: cursorPos - block.content.from, + parser: PARSER_MAP[langName].parser, + plugins: PARSER_MAP[langName].plugins, + tabWidth: state.tabSize, + }) + + dispatch(state.update({ + changes: { + from: block.content.from, + to: block.content.to, + insert: formattedContent.formatted, + }, + selection: EditorSelection.cursor(block.content.from + formattedContent.cursorOffset) + }, { + userEvent: "input", + })) + return true; +} + diff --git a/src/editor/keymap.js b/src/editor/keymap.js index ee837bc..9fb9610 100644 --- a/src/editor/keymap.js +++ b/src/editor/keymap.js @@ -26,7 +26,9 @@ import { selectNextBlock, selectPreviousBlock, gotoPreviousParagraph, gotoNextParagraph, selectNextParagraph, selectPreviousParagraph, -} from "./block/commands.js"; +} from "./block/commands.js" + +import { formatBlockContent } from "./block/format-code.js" function keymapFromSpec(specs) { @@ -54,6 +56,7 @@ export function heynoteKeymap(editor) { ["Alt-ArrowUp", moveLineUp], ["Alt-ArrowDown", moveLineDown], ["Mod-l", () => editor.openLanguageSelector()], + ["Mod-b", formatBlockContent], {key:"Mod-ArrowUp", run:gotoPreviousBlock, shift:selectPreviousBlock}, {key:"Mod-ArrowDown", run:gotoNextBlock, shift:selectNextBlock}, {key:"Ctrl-ArrowUp", run:gotoPreviousParagraph, shift:selectPreviousParagraph},