Skip to content

Commit 00adec3

Browse files
authored
fix: restore folds when formatting if available (#1682)
1 parent 5680883 commit 00adec3

File tree

1 file changed

+88
-5
lines changed

1 file changed

+88
-5
lines changed

src/lib/acode.js

Lines changed: 88 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ import KeyboardEvent from "utils/keyboardEvent";
4545
import Url from "utils/Url";
4646
import constants from "./constants";
4747

48+
const { Fold } = ace.require("ace/edit_session/fold");
49+
const { Range } = ace.require("ace/range");
50+
4851
export default class Acode {
4952
#modules = {};
5053
#pluginsInit = {};
@@ -475,19 +478,28 @@ export default class Acode {
475478

476479
async format(selectIfNull = true) {
477480
const file = editorManager.activeFile;
481+
if (!file?.session) return;
482+
478483
const name = (file.session.getMode().$id || "").split("/").pop();
479484
const formatterId = appSettings.value.formatter[name];
480485
const formatter = this.#formatter.find(({ id }) => id === formatterId);
481486

482-
await formatter?.format();
483-
484-
if (!formatter && selectIfNull) {
487+
if (!formatter) {
488+
if (!selectIfNull) {
489+
toast(strings["please select a formatter"]);
490+
return;
491+
}
485492
formatterSettings(name);
486493
this.#afterSelectFormatter(name);
487494
return;
488495
}
489-
if (!formatter && !selectIfNull) {
490-
toast(strings["please select a formatter"]);
496+
497+
const foldsSnapshot = this.#captureFoldState(file.session);
498+
499+
try {
500+
await formatter.format();
501+
} finally {
502+
this.#restoreFoldState(file.session, foldsSnapshot);
491503
}
492504
}
493505

@@ -506,6 +518,77 @@ export default class Acode {
506518
return fsOperation(file);
507519
}
508520

521+
#captureFoldState(session) {
522+
if (!session?.getAllFolds) return null;
523+
return this.#serializeFolds(session.getAllFolds());
524+
}
525+
526+
#restoreFoldState(session, folds) {
527+
if (!session || !Array.isArray(folds) || !folds.length) return;
528+
529+
try {
530+
const foldObjects = this.#parseSerializableFolds(folds);
531+
if (!foldObjects.length) return;
532+
session.removeAllFolds?.();
533+
session.addFolds?.(foldObjects);
534+
} catch (error) {
535+
console.warn("Failed to restore folds after formatting:", error);
536+
}
537+
}
538+
539+
#serializeFolds(folds) {
540+
if (!Array.isArray(folds) || !folds.length) return null;
541+
542+
return folds
543+
.map((fold) => {
544+
if (!fold?.range) return null;
545+
const { start, end } = fold.range;
546+
if (!start || !end) return null;
547+
548+
return {
549+
range: {
550+
start: { row: start.row, column: start.column },
551+
end: { row: end.row, column: end.column },
552+
},
553+
placeholder: fold.placeholder,
554+
ranges: this.#serializeFolds(fold.ranges || []),
555+
};
556+
})
557+
.filter(Boolean);
558+
}
559+
560+
#parseSerializableFolds(folds) {
561+
if (!Array.isArray(folds) || !folds.length) return [];
562+
563+
return folds
564+
.map((fold) => {
565+
const { range, placeholder, ranges } = fold;
566+
const { start, end } = range || {};
567+
if (!start || !end) return null;
568+
569+
try {
570+
const foldInstance = new Fold(
571+
new Range(start.row, start.column, end.row, end.column),
572+
placeholder,
573+
);
574+
575+
if (Array.isArray(ranges) && ranges.length) {
576+
const subFolds = this.#parseSerializableFolds(ranges);
577+
if (subFolds.length) {
578+
foldInstance.subFolds = subFolds;
579+
foldInstance.ranges = subFolds;
580+
}
581+
}
582+
583+
return foldInstance;
584+
} catch (error) {
585+
console.warn("Failed to parse fold:", error);
586+
return null;
587+
}
588+
})
589+
.filter(Boolean);
590+
}
591+
509592
newEditorFile(filename, options) {
510593
new EditorFile(filename, options);
511594
}

0 commit comments

Comments
 (0)