Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions crates/deep-code-tui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,13 @@ unicode-width = "0.2"
tokio = { version = "1", features = ["macros", "rt-multi-thread", "sync", "time"] }
tokio-util = { version = "0.7", features = ["rt"] }

# Redirect stderr to the log file on Windows (SetStdHandle), mirroring the
# unix `dup2` path so stray writes can't paint over the alternate-screen TUI.
[target.'cfg(windows)'.dependencies]
windows-sys = { version = "0.59", features = [
"Win32_Foundation",
"Win32_System_Console",
] }

[dev-dependencies]
tempfile = "3"
36 changes: 35 additions & 1 deletion crates/deep-code-tui/src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,41 @@ fn redirect_stderr_to_log() {
}
}

#[cfg(not(unix))]
/// Windows equivalent of the unix path: point the process's `STD_ERROR_HANDLE`
/// at the log file via `SetStdHandle`, so LSP/persistence `eprintln!`s land in
/// the log instead of corrupting the alternate-screen TUI.
#[cfg(windows)]
fn redirect_stderr_to_log() {
use std::os::windows::io::AsRawHandle;

use windows_sys::Win32::Foundation::HANDLE;
use windows_sys::Win32::System::Console::{STD_ERROR_HANDLE, SetStdHandle};

let path = crate::cli::workspace_root()
.join(".deep-code")
.join("deep-code.log");
if let Some(parent) = path.parent() {
let _ = std::fs::create_dir_all(parent);
}
let Ok(file) = std::fs::OpenOptions::new()
.create(true)
.append(true)
.open(&path)
else {
return;
};
let handle: HANDLE = file.as_raw_handle();
// SAFETY: `handle` is a valid, writable file handle. SetStdHandle just
// records it as the process's stderr; `forget` keeps it open for the
// process lifetime (the alternate-screen TUI runs until exit), mirroring how
// the unix `dup2` fd outlives the dropped `File`.
unsafe {
SetStdHandle(STD_ERROR_HANDLE, handle);
}
std::mem::forget(file);
}

#[cfg(not(any(unix, windows)))]
fn redirect_stderr_to_log() {}

fn run_loop(terminal: &mut AppTerminal, app: &mut App) -> Result<()> {
Expand Down
Loading