Describe the bug
Format on Save uses the active editor instead of the file being saved. If the user switches from file A to file B while an asynchronous save step is pending, formatting can target B even though the save still writes A.
The save also starts formatting without awaiting completion. An asynchronous formatter can therefore finish after the source write, leaving the saved content unformatted. Formatter failure does not stop that write.
Steps to reproduce
- Enable Format on Save and configure a formatter for two editable files, A and B.
- Edit A and use Save As with a provider whose destination
exists() check is delayed. For deterministic reproduction, hold the final existence check after the destination/filename dialogs close and before formatting begins.
- Switch to B before releasing that check.
- Let the save continue: the formatter resolves the active file B, while the save retains A as its destination.
- Separately, use an asynchronous formatter whose returned promise is delayed and observe whether the source write starts before formatting completes.
Expected behavior
- Format and save the intended file, regardless of tab switches; leave other files untouched.
- Wait for formatting to complete before capturing and writing the document.
- Preserve dirty/cache state and cursor state on the correct file.
- Abort the save on formatting failure without reporting success.
Cause and compatibility constraint
saveFile.js changes editorManager.activeFile.markChanged and calls acode.exec("format", false) without awaiting it. acode.format() selects the active file and invokes the formatter callback without a target argument.
Existing formatter plugins may read the active editor themselves, including after asynchronous work. Passing a file through command dispatch alone would not fix those callbacks. A later fix needs to account for compatibility, concurrent formatting requests, closure, and cleanup after failure; no implementation approach is selected here.
Environment and scope
Identified by source review while working on #2898, at revision 52d7d5d4504d5479bea7bbc63dbf0e083b1cd605. The steps above describe the controlled race; no specific released Android/WebView version is claimed as reproduced.
Track this separately from the cache/save fixes and defer implementation. Validate tab switching before and during formatting, the formatted source snapshot, and failure/closure behavior when addressing it.
Check for existing issues
Describe the bug
Format on Save uses the active editor instead of the file being saved. If the user switches from file A to file B while an asynchronous save step is pending, formatting can target B even though the save still writes A.
The save also starts formatting without awaiting completion. An asynchronous formatter can therefore finish after the source write, leaving the saved content unformatted. Formatter failure does not stop that write.
Steps to reproduce
exists()check is delayed. For deterministic reproduction, hold the final existence check after the destination/filename dialogs close and before formatting begins.Expected behavior
Cause and compatibility constraint
saveFile.jschangeseditorManager.activeFile.markChangedand callsacode.exec("format", false)without awaiting it.acode.format()selects the active file and invokes the formatter callback without a target argument.Existing formatter plugins may read the active editor themselves, including after asynchronous work. Passing a file through command dispatch alone would not fix those callbacks. A later fix needs to account for compatibility, concurrent formatting requests, closure, and cleanup after failure; no implementation approach is selected here.
Environment and scope
Identified by source review while working on #2898, at revision
52d7d5d4504d5479bea7bbc63dbf0e083b1cd605. The steps above describe the controlled race; no specific released Android/WebView version is claimed as reproduced.Track this separately from the cache/save fixes and defer implementation. Validate tab switching before and during formatting, the formatted source snapshot, and failure/closure behavior when addressing it.
Check for existing issues