From 6211758bd2af6f9183f0b47f01299fa4e2b54add Mon Sep 17 00:00:00 2001 From: wuyangfan <1102042793@qq.com> Date: Sun, 17 May 2026 16:54:28 +0800 Subject: [PATCH] fix: crash after open_commit_editor on Windows Use a dedicated OpenCommitEditor event, keep the commit popup visible, and disable raw mode while the external editor runs so the terminal is restored before committing. Co-authored-by: Cursor --- src/app.rs | 34 +++++++++++++++++++++++----------- src/popups/commit.rs | 5 +---- src/popups/externaleditor.rs | 19 +++++++++++++++++-- src/queue.rs | 2 ++ 4 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/app.rs b/src/app.rs index 8626aa3b8e..a47a380d5f 100644 --- a/src/app.rs +++ b/src/app.rs @@ -119,6 +119,7 @@ pub struct App { // "Flags" requires_redraw: Cell, file_to_open: Option, + open_commit_editor: bool, } pub struct Environment { @@ -244,6 +245,7 @@ impl App { key_config: env.key_config, requires_redraw: Cell::new(false), file_to_open: None, + open_commit_editor: false, repo: env.repo, repo_path_text, popup_stack: PopupStack::default(), @@ -371,17 +373,19 @@ impl App { } else if let InputEvent::State(polling_state) = ev { self.external_editor_popup.hide(); if matches!(polling_state, InputState::Paused) { - let result = - if let Some(path) = self.file_to_open.take() { - ExternalEditorPopup::open_file_in_editor( - &self.repo.borrow(), - Path::new(&path), - ) - } else { - let changes = - self.status_tab.get_files_changes()?; - self.commit_popup.show_editor(changes) - }; + let result = if self.open_commit_editor { + self.open_commit_editor = false; + let changes = + self.status_tab.get_files_changes()?; + self.commit_popup.show_editor(changes) + } else if let Some(path) = self.file_to_open.take() { + ExternalEditorPopup::open_file_in_editor( + &self.repo.borrow(), + Path::new(&path), + ) + } else { + Ok(()) + }; if let Err(e) = result { let msg = @@ -816,11 +820,19 @@ impl App { } } InternalEvent::OpenExternalEditor(path) => { + self.open_commit_editor = false; self.input.set_polling(false); self.external_editor_popup.show()?; self.file_to_open = path; flags.insert(NeedsUpdate::COMMANDS); } + InternalEvent::OpenCommitEditor => { + self.file_to_open = None; + self.open_commit_editor = true; + self.input.set_polling(false); + self.external_editor_popup.show()?; + flags.insert(NeedsUpdate::COMMANDS); + } InternalEvent::Push(branch, push_type, force, delete) => { self.push_popup .push(branch, push_type, force, delete)?; diff --git a/src/popups/commit.rs b/src/popups/commit.rs index b5dff7677c..3c0f26d26e 100644 --- a/src/popups/commit.rs +++ b/src/popups/commit.rs @@ -586,10 +586,7 @@ impl Component for CommitPopup { e, self.key_config.keys.open_commit_editor, ) { - self.queue.push( - InternalEvent::OpenExternalEditor(None), - ); - self.hide(); + self.queue.push(InternalEvent::OpenCommitEditor); true } else if key_match( e, diff --git a/src/popups/externaleditor.rs b/src/popups/externaleditor.rs index 52a7327b13..baa033f0f8 100644 --- a/src/popups/externaleditor.rs +++ b/src/popups/externaleditor.rs @@ -14,7 +14,10 @@ use asyncgit::sync::{ }; use crossterm::{ event::Event, - terminal::{EnterAlternateScreen, LeaveAlternateScreen}, + terminal::{ + disable_raw_mode, enable_raw_mode, is_raw_mode_enabled, + EnterAlternateScreen, LeaveAlternateScreen, + }, ExecutableCommand, }; use ratatui::{ @@ -61,9 +64,21 @@ impl ExternalEditorPopup { bail!("file not found: {path:?}"); } + let raw_mode_enabled = is_raw_mode_enabled()?; + if raw_mode_enabled { + disable_raw_mode()?; + } + io::stdout().execute(LeaveAlternateScreen)?; defer! { - io::stdout().execute(EnterAlternateScreen).expect("reset terminal"); + if let Err(e) = io::stdout().execute(EnterAlternateScreen) { + log::error!("failed to re-enter alternate screen: {e}"); + } + if raw_mode_enabled { + if let Err(e) = enable_raw_mode() { + log::error!("failed to re-enable raw mode: {e}"); + } + } } let environment_options = ["GIT_EDITOR", "VISUAL", "EDITOR"]; diff --git a/src/queue.rs b/src/queue.rs index 5cdfe3cef0..c784180c75 100644 --- a/src/queue.rs +++ b/src/queue.rs @@ -123,6 +123,8 @@ pub enum InternalEvent { /// OpenExternalEditor(Option), /// + OpenCommitEditor, + /// Push(String, PushType, bool, bool), /// Pull(String),