mirror of
https://github.com/youfoundjk/TeXcore.git
synced 2026-07-22 07:33:31 +00:00
fix(live-preview): fixed cursor kicking when editing referenced block
This commit is contained in:
parent
bcc862731a
commit
d1d809f029
2 changed files with 82 additions and 14 deletions
|
|
@ -149,12 +149,21 @@ const tagManagerAnnotation = Annotation.define<boolean>();
|
|||
function createTagManagerPlugin(plugin: LatexReferencer, equationField: StateField<EquationState>): ViewPlugin<object> {
|
||||
return ViewPlugin.fromClass(class {
|
||||
timeout: NodeJS.Timeout | null = null;
|
||||
blockedBySelection = false;
|
||||
|
||||
constructor(view: EditorView) { this.scheduleCheck(view); }
|
||||
constructor(view: EditorView) {
|
||||
this.scheduleCheck(view);
|
||||
}
|
||||
update(update: ViewUpdate) {
|
||||
if (update.docChanged && !update.transactions.some(tr => tr.annotation(tagManagerAnnotation))) {
|
||||
this.scheduleCheck(update.view);
|
||||
}
|
||||
|
||||
// If a previous run detected pending edits but skipped due to active selection
|
||||
// inside an equation block, retry once the selection changes.
|
||||
if (update.selectionSet && this.blockedBySelection) {
|
||||
this.scheduleCheck(update.view);
|
||||
}
|
||||
}
|
||||
scheduleCheck(view: EditorView) {
|
||||
if (this.timeout) clearTimeout(this.timeout);
|
||||
|
|
@ -166,8 +175,11 @@ function createTagManagerPlugin(plugin: LatexReferencer, equationField: StateFie
|
|||
runCheck(view: EditorView) {
|
||||
const equationInfos = view.state.field(equationField);
|
||||
const changes: { from: number; to: number; insert: string }[] = [];
|
||||
const selection = view.state.selection.main;
|
||||
let blockedChanges = 0;
|
||||
|
||||
for (const info of equationInfos) {
|
||||
const selectionOverlapsEquation = selection.from <= info.to && selection.to >= info.from;
|
||||
// Determine the prefix from the OPENING line of the block.
|
||||
// This is the source of truth for indentation/callout level.
|
||||
const startLine = view.state.doc.lineAt(info.from);
|
||||
|
|
@ -272,11 +284,17 @@ function createTagManagerPlugin(plugin: LatexReferencer, equationField: StateFie
|
|||
// We simply compare the strings.
|
||||
// Note: This replaces EVERYTHING from inside the block to the end of the block.
|
||||
if (existingSuffix !== proposedSuffix) {
|
||||
if (selectionOverlapsEquation) {
|
||||
blockedChanges += 1;
|
||||
continue;
|
||||
}
|
||||
changes.push({ from: info.from + 2, to: info.to, insert: proposedSuffix });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.blockedBySelection = blockedChanges > 0;
|
||||
|
||||
if (changes.length > 0) {
|
||||
view.dispatch({
|
||||
changes,
|
||||
|
|
|
|||
|
|
@ -1,16 +1,66 @@
|
|||
/**
|
||||
* A simple synchronous file logger used for intense UI diagnostic tracing.
|
||||
*
|
||||
* Usage:
|
||||
* Inject `logDebug("My message")` aggressively into CodeMirror rendering loops
|
||||
* or DOM observers to output an absolute timeline of execution to `debug.log`.
|
||||
* This is especially useful for capturing logs in contexts where the Obsidian
|
||||
* Developer Console might be silenced, asynchronous, or overwhelmed.
|
||||
*/
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
|
||||
export function logDebug(msg: string) {
|
||||
try {
|
||||
fs.appendFileSync("d:\\Codes\\plugin-latex-referencer\\debug.log", msg + "\n", { encoding: "utf-8" });
|
||||
} catch (e) { }
|
||||
type DebugCapablePlugin = {
|
||||
settings?: { debug?: boolean };
|
||||
app?: { vault?: { adapter?: { basePath?: string } } };
|
||||
};
|
||||
|
||||
let sequence = 0;
|
||||
|
||||
function getDefaultLogPath(plugin?: DebugCapablePlugin): string {
|
||||
const basePath = plugin?.app?.vault?.adapter?.basePath;
|
||||
if (typeof basePath === "string" && basePath.length > 0) {
|
||||
return path.join(basePath, "latex-referencer-debug.log");
|
||||
}
|
||||
return path.join(process.cwd(), "latex-referencer-debug.log");
|
||||
}
|
||||
|
||||
function canDebug(plugin?: DebugCapablePlugin): boolean {
|
||||
return !!plugin?.settings?.debug;
|
||||
}
|
||||
|
||||
function writeDebugLine(line: string, plugin?: DebugCapablePlugin) {
|
||||
try {
|
||||
fs.appendFileSync(getDefaultLogPath(plugin), line + "\n", { encoding: "utf-8" });
|
||||
} catch (_) {
|
||||
// Best-effort only. Console logging should still work.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Structured debug logging helper used in edit/render loops.
|
||||
* This is opt-in and gated by plugin.settings.debug.
|
||||
*/
|
||||
export function logDebugEvent(
|
||||
plugin: DebugCapablePlugin | undefined,
|
||||
scope: string,
|
||||
event: string,
|
||||
data?: Record<string, unknown> | (() => Record<string, unknown>)
|
||||
) {
|
||||
if (!canDebug(plugin)) return;
|
||||
sequence += 1;
|
||||
|
||||
const payload = typeof data === "function" ? data() : (data ?? {});
|
||||
const line = JSON.stringify({
|
||||
seq: sequence,
|
||||
ts: new Date().toISOString(),
|
||||
scope,
|
||||
event,
|
||||
...payload,
|
||||
});
|
||||
writeDebugLine(line, plugin);
|
||||
}
|
||||
|
||||
export function clearDebugLog(plugin?: DebugCapablePlugin) {
|
||||
const logPath = getDefaultLogPath(plugin);
|
||||
try {
|
||||
fs.writeFileSync(logPath, "", { encoding: "utf-8" });
|
||||
} catch (_) {
|
||||
// Ignore write failures.
|
||||
}
|
||||
}
|
||||
|
||||
export function getDebugLogPath(plugin?: DebugCapablePlugin): string {
|
||||
return getDefaultLogPath(plugin);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue