Skip to content

Commit 64efbf4

Browse files
committed
fix(save): make format-on-save await the formatter and target the saved file
- Await the format command so the document write captures the formatted content instead of racing an async formatter - Only format when the file being saved is the active file: formatters operate on the active editor document, so a tab switch mid-save could previously rewrite the wrong file - Toggle markChanged on the file being saved, not whatever tab is active - Abort the save when the formatter fails instead of writing unformatted content and reporting success - acode.format() now returns null (not a failure) when no formatter is configured, so format-on-save keeps working for unformatted file types; the format command propagates the tri-state result Fixes #2900
1 parent 2803dda commit 64efbf4

3 files changed

Lines changed: 25 additions & 4 deletions

File tree

src/lib/acode.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,13 @@ class Acode {
826826
appSettings.update(false);
827827
}
828828

829+
/**
830+
* Formats the active file with the configured formatter.
831+
* @param {boolean} [selectIfNull] open the formatter picker when no formatter is configured
832+
* @returns {Promise<boolean|null>} `true` when formatting ran, `false`
833+
* when the formatter failed, `null` when no formatter is configured
834+
* (not a failure; callers should not treat it as one)
835+
*/
829836
async format(selectIfNull = true) {
830837
const file = editorManager.activeFile;
831838
if (!file || file.type !== "editor") return false;
@@ -858,7 +865,9 @@ class Acode {
858865
} else {
859866
toast(strings["please select a formatter"]);
860867
}
861-
return false;
868+
// No formatter configured: not a failure, so report `null`
869+
// instead of `false` (both are falsy for existing callers).
870+
return null;
862871
}
863872

864873
try {

src/lib/commands.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,7 @@ export default {
727727
// Restore cursor position after formatting (pos.row is now 1-based)
728728
editor.gotoLine(pos.row, pos.column);
729729
}
730+
return didFormat;
730731
},
731732
async eol() {
732733
if (editorManager.activeFile?.type !== "editor") return;

src/lib/saveFile.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,22 @@ async function saveFile(
172172
}
173173

174174
if (appSettings.value.formatOnSave) {
175-
editorManager.activeFile.markChanged = false;
175+
// Formatters operate on the active editor document. If the user
176+
// switched tabs while an async save step was pending, formatting
177+
// here would rewrite the wrong file, so only format when the file
178+
// being saved is the active one.
179+
file.markChanged = false;
176180
try {
177-
acode.exec("format", false);
181+
if (editorManager.activeFile === file) {
182+
// Await the formatter so the write below captures the
183+
// formatted document. A failed format aborts the save;
184+
// `null` means no formatter is configured, which is not
185+
// a failure.
186+
const formatted = await acode.exec("format", false);
187+
if (formatted === false) return false;
188+
}
178189
} finally {
179-
editorManager.activeFile.markChanged = true;
190+
file.markChanged = true;
180191
}
181192
}
182193

0 commit comments

Comments
 (0)