Skip to content

Commit

Permalink
Update prettier version and fix formatting bug.
Browse files Browse the repository at this point in the history
Prettier currently has a bug that causes it's formatWithCursor() to be extremely slow in some cases. In Heynote, whenever you pasted a large JSON chunk and auto formatted it, with the cursor at the beginning or the start of the block, this would trigger that bug. This commit introduces a work around by using format() if the cursor is at the beginning or the end of the block.

Update to latest version of Prettier.
  • Loading branch information
heyman committed Dec 21, 2023
1 parent eb886a3 commit 6086976
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 19 deletions.
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"electron-store": "^8.1.0",
"electron-updater": "^6.1.7",
"fs-jetpack": "^5.1.0",
"prettier": "^2.8.4",
"prettier": "^3.1.1",
"rollup-plugin-license": "^3.0.1",
"sass": "^1.57.1",
"typescript": "^4.9.4",
Expand Down
45 changes: 33 additions & 12 deletions src/editor/block/format-code.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
import { EditorSelection } from "@codemirror/state"

import { formatWithCursor, getSupportInfo } from "prettier"
import babelParser from "prettier/esm/parser-babel.mjs"
import * as prettier from "prettier/standalone"
import babelParser from "prettier/plugins/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 * as prettierPluginEstree from "prettier/plugins/estree.mjs";

import { getActiveNoteBlock } from "./block.js"


const PARSER_MAP = {
"json": {parser:"json-stringify", plugins: [babelParser]},
"javascript": {parser:"babel", plugins: [babelParser]},
"json": {parser:"json-stringify", plugins: [babelParser, prettierPluginEstree]},
"javascript": {parser:"babel", plugins: [babelParser, prettierPluginEstree]},
"html": {parser:"html", plugins: [htmlParser]},
"css": {parser:"css", plugins: [cssParser]},
"markdown": {parser:"markdown", plugins: [markdownParser]},
}


export const formatBlockContent = ({ state, dispatch }) => {
export const formatBlockContent = async ({ state, dispatch }) => {
if (state.readOnly)
return false
const block = getActiveNoteBlock(state)
Expand All @@ -34,14 +35,34 @@ export const formatBlockContent = ({ state, dispatch }) => {

//console.log("prettier supports:", getSupportInfo())

// There is a performance bug in prettier causing formatWithCursor() to be extremely slow in some cases (https://github.com/prettier/prettier/issues/4801)
// To work around this we use format() when the cursor is in the beginning or the end of the block.
// This is not a perfect solution, and once the following PR is merged and released, we should be abe to remove this workaround:
// https://github.com/prettier/prettier/pull/15709
let useFormat = false
if (cursorPos == block.content.from || cursorPos == block.content.to) {
useFormat = true
}

let formattedContent
try {
formattedContent = formatWithCursor(content, {
cursorOffset: cursorPos - block.content.from,
parser: PARSER_MAP[langName].parser,
plugins: PARSER_MAP[langName].plugins,
tabWidth: state.tabSize,
})
if (useFormat) {
formattedContent = {
formatted: await prettier.format(content, {
parser: PARSER_MAP[langName].parser,
plugins: PARSER_MAP[langName].plugins,
tabWidth: state.tabSize,
}),
cursorOffset: cursorPos == block.content.from ? 0 : content.length,
}
} else {
formattedContent = await prettier.formatWithCursor(content, {
cursorOffset: cursorPos - block.content.from,
parser: PARSER_MAP[langName].parser,
plugins: PARSER_MAP[langName].plugins,
tabWidth: state.tabSize,
})
}
} catch (e) {
const hyphens = "----------------------------------------------------------------------------"
console.log(`Error when trying to format block:\n${hyphens}\n${e.message}\n${hyphens}`)
Expand All @@ -54,7 +75,7 @@ export const formatBlockContent = ({ state, dispatch }) => {
to: block.content.to,
insert: formattedContent.formatted,
},
selection: EditorSelection.cursor(block.content.from + formattedContent.cursorOffset)
selection: EditorSelection.cursor(block.content.from + formattedContent.cursorOffset),
}, {
userEvent: "input",
scrollIntoView: true,
Expand Down

0 comments on commit 6086976

Please sign in to comment.