This commit is contained in:
Zef Hemel
2026-04-30 10:59:53 +02:00
parent 49ab50af43
commit 81dbdae857
2 changed files with 26 additions and 9 deletions
+9 -7
View File
@@ -1,9 +1,5 @@
import customMarkdownStyle from "../style.ts";
import {
history,
insertNewlineAndIndent,
isolateHistory,
} from "@codemirror/commands";
import { history, insertNewlineAndIndent } from "@codemirror/commands";
import {
autocompletion,
closeBrackets,
@@ -20,6 +16,7 @@ import {
unfoldEffect,
} from "@codemirror/language";
import {
Annotation,
Compartment,
EditorState,
type Extension,
@@ -57,6 +54,11 @@ import { codeCopyPlugin } from "../codemirror/code_copy.ts";
import { disableSpellcheck } from "../codemirror/spell_checking.ts";
import type { ClickEvent } from "@silverbulletmd/silverbullet/type/client";
// Annotation marking a transaction whose changes came from outside the
// editor's edit stream (e.g. a page re-fetch from storage), so the
// save-on-change handler can skip it and avoid an immediate re-save loop.
export const externalUpdate = Annotation.define<boolean>();
export function createEditorState(
client: Client,
pageName: string,
@@ -292,9 +294,9 @@ export function createEditorState(
}
}
if (update.docChanged) {
// Find if there's a history isolate in the transaction, if so it came from a local reload and we don't do anything
// Skip saving if the change came from outside the editor (e.g. storage reload)
if (
update.transactions.some((t) => t.annotation(isolateHistory))
update.transactions.some((t) => t.annotation(externalUpdate))
) {
return;
}
+17 -2
View File
@@ -18,7 +18,10 @@ import {
notFoundError,
offlineError,
} from "@silverbulletmd/silverbullet/constants";
import { createEditorState } from "./codemirror/editor_state.ts";
import {
createEditorState,
externalUpdate,
} from "./codemirror/editor_state.ts";
import { diffAndPrepareChanges } from "./codemirror/cm_util.ts";
import { DocumentEditor } from "./document_editor.ts";
import { fsEndpoint } from "./spaces/constants.ts";
@@ -382,7 +385,7 @@ export class ContentManager {
this.client.editorView.setState(editorState);
} else {
// Just apply minimal patches so that the cursor is preserved
this.setEditorText(doc.text, true);
this.applyExternalPatches(doc.text);
}
this.client.space.watchFile(path);
@@ -492,6 +495,18 @@ export class ContentManager {
});
}
// Like setEditorText, but marks the transaction as an external update (e.g.
// a page re-fetch from storage) so the save-on-change handler skips it and
// we avoid an immediate re-save loop.
private applyExternalPatches(newText: string) {
const currentText = this.client.editorView.state.sliceDoc();
const allChanges = diffAndPrepareChanges(currentText, newText);
this.client.editorView.dispatch({
changes: allChanges,
annotations: [isolateHistory.of("full"), externalUpdate.of(true)],
});
}
private navigateWithinPage(pageState: LocationState) {
if (!isMarkdownPath(pageState.path)) return;