From ce734da4fd4f378f4615dc84c9792c485efb02cb Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Tue, 1 Sep 2026 21:43:13 +0200 Subject: [PATCH] Don't refresh while the editor still has the hunk Editing a hunk points an editor at a patch we wrote to a temp file and waits. Nothing about the repo has changed when the editor returns: the change lands when the caller applies what came back. But the suspend path this went through refreshes as soon as the subprocess exits, so it reads the state from before the patch is applied and then races the caller's own refresh to publish it. Whichever lands last wins, and when it is the stale one the files panel goes on showing the file as it was before the edit until something else refreshes. The caller is the one that knows when there is something new to see, and both callers already refresh once they have applied the patch, so the refresh in the middle only ever had a wrong answer to give. Being a publish-order race, it doesn't reproduce reliably enough for a test; holding a background refresh between its read and its publish shows it every time. Co-authored-by: Claude Opus 5 (1M context) --- pkg/gui/controllers/helpers/files_helper.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pkg/gui/controllers/helpers/files_helper.go b/pkg/gui/controllers/helpers/files_helper.go index 81c9b272e..1f7ed5188 100644 --- a/pkg/gui/controllers/helpers/files_helper.go +++ b/pkg/gui/controllers/helpers/files_helper.go @@ -46,8 +46,16 @@ func (self *FilesHelper) EditFileAtLineAndWait(filename string, lineNumber int) // Always suspend, regardless of the value of the suspend config, // since we want to prevent interacting with the UI until the editor - // returns, even if the editor doesn't use the terminal - return self.callEditor(cmdStr, true) + // returns, even if the editor doesn't use the terminal. + // + // And nothing is refreshed here; that is why this doesn't go through + // callEditor. The editor was handed a patch we wrote for it, so the repo + // hasn't changed when it returns; it changes when the caller applies what + // came back. A refresh in between reads the state from before that, and + // then races the caller's own refresh to publish it. + _, err = self.c.RunSubprocess( + self.c.OS().Cmd.NewShell(cmdStr, self.c.UserConfig().OS.ShellFunctionsFile)) + return err } func (self *FilesHelper) OpenDirInEditor(path string) error {