Don't unfold folded region for changes on the same row as a folded region (but outside the fold), if the change doesn't actually insert anything, if the insertion is adding a new block, or if the change is undo/redo

This commit is contained in:
Jonatan Heyman 2025-06-13 12:52:42 +02:00
parent f8f874e2af
commit ef04ab9ba9
3 changed files with 29 additions and 2 deletions

View File

@ -16,3 +16,7 @@ export const SET_FONT = "heynote-set-font"
export function transactionsHasAnnotation(transactions, annotation) {
return transactions.some(tr => tr.annotation(heynoteEvent) === annotation)
}
export function transactionsHasHistoryEvent(transactions) {
return transactions.some(tr => tr.isUserEvent("undo") || tr.isUserEvent("redo"))
}

View File

@ -66,7 +66,8 @@ export const addNewBlockAfterCurrent = (editor) => ({ state, dispatch }) => {
from: block.content.to,
insert: delimText,
},
selection: EditorSelection.cursor(block.content.to + delimText.length)
selection: EditorSelection.cursor(block.content.to + delimText.length),
annotations: [heynoteEvent.of(ADD_NEW_BLOCK)],
}, {
scrollIntoView: true,
userEvent: "input",
@ -106,7 +107,8 @@ export const addNewBlockAfterLast = (editor) => ({ state, dispatch }) => {
from: block.content.to,
insert: delimText,
},
selection: EditorSelection.cursor(block.content.to + delimText.length)
selection: EditorSelection.cursor(block.content.to + delimText.length),
annotations: [heynoteEvent.of(ADD_NEW_BLOCK)],
}, {
scrollIntoView: true,
userEvent: "input",

View File

@ -4,10 +4,15 @@ import { RangeSet } from "@codemirror/state"
import { FOLD_LABEL_LENGTH } from "@/src/common/constants.js"
import { getNoteBlockFromPos } from "./block/block.js"
import { transactionsHasAnnotation, ADD_NEW_BLOCK, transactionsHasHistoryEvent } from "./annotation.js"
// This extension fixes so that a folded region is automatically unfolded if any changes happen
// on either the start line or the end line of the folded region (even if the change is not within the folded region)
// except for if the change is an insertion of a new block, or if the change doesn't actually insert anything.
//
// The purpose is to prevent extra characters to be inserted into a line that is folded, without the region
// being unfolded.
const autoUnfoldOnEdit = () => {
return EditorView.updateListener.of((update) => {
if (!update.docChanged){
@ -21,6 +26,22 @@ const autoUnfoldOnEdit = () => {
return
}
// we don't want to unfold a block/range if the user adds a new block
if (transactionsHasAnnotation(update.transactions, ADD_NEW_BLOCK)) {
return
}
// an undo/redo action should never be able to get characters into a folded line but if we don't have
// this check an undo/redo of a block insertion before/after the region will unfold the folded block
if (transactionsHasHistoryEvent(update.transactions)) {
return
}
// This fixes so that removing the previous block immediately after a folded block won't unfold the folded block
// Since nothing was inserted, there is no risk of us putting extra characters into folded lines
if (update.changes.inserted.length === 0) {
return
}
const unfoldRanges = []
update.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {