attempt to fix issue w terminal

This commit is contained in:
2026-03-23 16:57:26 -05:00
parent b541865ff1
commit b4a28efcba
3 changed files with 91 additions and 13 deletions

View File

@@ -2,6 +2,7 @@ use std::{
env::set_current_dir,
path::{Path, PathBuf},
process::Command,
sync::{Arc, atomic::Ordering},
};
use clap::CommandFactory;
@@ -206,25 +207,37 @@ impl App {
fn watch(mode: &Option<String>, args: Option<Vec<String>>) -> std::io::Result<()> {
use std::io::Write;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
// save terminal state
let mut stdout = std::io::stdout();
// enter alternate screen — this is a separate terminal buffer,
// exiting it restores everything exactly as it was
// enter alternate screen
write!(stdout, "\x1b[?1049h")?;
stdout.flush()?;
// make sure we always restore the terminal, even on panic
let result = watch_inner(mode, args);
// set up ctrl+c handler BEFORE doing anything else
let running = Arc::new(AtomicBool::new(true));
let running_clone = running.clone();
ctrlc::set_handler(move || {
running_clone.store(false, Ordering::SeqCst);
})
.map_err(|e| std::io::Error::other(format!("{e}")))?;
// exit alternate screen
let result = watch_inner(mode, args, running);
// exit alternate screen — guaranteed to run now
write!(stdout, "\x1b[?1049l")?;
stdout.flush()?;
result
}
fn watch_inner(mode: &Option<String>, args: Option<Vec<String>>) -> std::io::Result<()> {
fn watch_inner(
mode: &Option<String>,
args: Option<Vec<String>>,
running: Arc<std::sync::atomic::AtomicBool>,
) -> std::io::Result<()> {
use notify::{Event, RecursiveMode, Watcher, recommended_watcher};
use std::io::Write;
use std::sync::mpsc;
@@ -294,8 +307,8 @@ fn watch_inner(mode: &Option<String>, args: Option<Vec<String>>) -> std::io::Res
.checked_sub(Duration::from_secs(1))
.unwrap_or(Instant::now());
loop {
match rx.recv() {
while running.load(Ordering::SeqCst) {
match rx.recv_timeout(Duration::from_millis(100)) {
Ok(Ok(event)) => {
let is_relevant = matches!(
event.kind,
@@ -332,10 +345,8 @@ fn watch_inner(mode: &Option<String>, args: Option<Vec<String>>) -> std::io::Res
}
}
Ok(Err(e)) => eprintln!(" {} watch error: {e}", "Error".red().bold()),
Err(e) => {
eprintln!(" {} channel error: {e}", "Error".red().bold());
break;
}
Err(mpsc::RecvTimeoutError::Timeout) => continue, // check running flag and loop
Err(mpsc::RecvTimeoutError::Disconnected) => break,
}
}