attempt to fix issue w terminal
This commit is contained in:
37
src/app.rs
37
src/app.rs
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user