aboutsummaryrefslogtreecommitdiffstats
path: root/crates/atuin-pty-proxy/src/runtime.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/atuin-pty-proxy/src/runtime.rs')
-rw-r--r--crates/atuin-pty-proxy/src/runtime.rs184
1 files changed, 0 insertions, 184 deletions
diff --git a/crates/atuin-pty-proxy/src/runtime.rs b/crates/atuin-pty-proxy/src/runtime.rs
deleted file mode 100644
index 2b34fbb7..00000000
--- a/crates/atuin-pty-proxy/src/runtime.rs
+++ /dev/null
@@ -1,184 +0,0 @@
-use std::io::{Read, Write};
-use std::sync::Arc;
-use std::sync::atomic::{AtomicU16, Ordering};
-use std::sync::mpsc;
-
-use crossterm::terminal;
-use portable_pty::{CommandBuilder, PtySize, native_pty_system};
-
-use crate::capture::CommandCaptureTracker;
-use crate::debug::{Osc133DebugHighlighter, RESET};
-use crate::pty_proxy::RuntimeOptions;
-use crate::screen::{self, Msg};
-
-pub(crate) fn main(options: RuntimeOptions) {
- if let Err(e) = run(options) {
- let _ = terminal::disable_raw_mode();
- eprintln!("atuin pty-proxy: {e:#}");
- std::process::exit(1);
- }
-}
-
-fn run(options: RuntimeOptions) -> eyre::Result<()> {
- let (cols, rows) = terminal::size()?;
-
- let pty_system = native_pty_system();
- let pair = pty_system
- .openpty(PtySize {
- rows,
- cols,
- pixel_width: 0,
- pixel_height: 0,
- })
- .map_err(|e| eyre::eyre!("{e:#}"))?;
-
- let sock_path = screen::socket_path();
- let _ = std::fs::remove_file(&sock_path);
-
- let mut cmd = CommandBuilder::new_default_prog();
- cmd.cwd(std::env::current_dir()?);
- cmd.env("ATUIN_PTY_PROXY_SOCKET", sock_path.as_os_str());
- cmd.env("ATUIN_PTY_PROXY_ACTIVE", "1");
-
- let mut child = pair
- .slave
- .spawn_command(cmd)
- .map_err(|e| eyre::eyre!("{e:#}"))?;
-
- drop(pair.slave);
-
- let mut pty_reader = pair
- .master
- .try_clone_reader()
- .map_err(|e| eyre::eyre!("{e:#}"))?;
- let mut pty_writer = pair
- .master
- .take_writer()
- .map_err(|e| eyre::eyre!("{e:#}"))?;
-
- let (msg_tx, msg_rx) = mpsc::sync_channel::<Msg>(64);
- let current_cols = Arc::new(AtomicU16::new(cols.max(1)));
-
- screen::spawn_parser_thread(rows, cols, msg_rx);
- screen::spawn_socket_server(sock_path.clone(), msg_tx.clone());
- spawn_resize_handler(pair.master, msg_tx.clone(), current_cols.clone())?;
-
- terminal::enable_raw_mode()?;
-
- let stdout_thread = std::thread::spawn(move || {
- let mut stdout = std::io::stdout();
- let mut highlighter = options.debug_osc133.then(Osc133DebugHighlighter::new);
- let mut capture_tracker = options
- .command_capture_sink
- .as_ref()
- .map(|_| CommandCaptureTracker::new(current_cols));
- let mut buf = [0u8; 8192];
-
- loop {
- match pty_reader.read(&mut buf) {
- Ok(0) | Err(_) => break,
- Ok(n) => {
- if let (Some(tracker), Some(sink)) = (
- capture_tracker.as_mut(),
- options.command_capture_sink.as_ref(),
- ) {
- tracker.push(&buf[..n], sink);
- }
-
- if let Some(highlighter) = highlighter.as_mut() {
- let rendered = highlighter.render(&buf[..n]);
- let _ = msg_tx.try_send(Msg::Data(rendered.clone()));
-
- if stdout.write_all(&rendered).is_err() {
- break;
- }
- } else {
- let _ = msg_tx.try_send(Msg::Data(buf[..n].to_vec()));
-
- if stdout.write_all(&buf[..n]).is_err() {
- break;
- }
- }
- let _ = stdout.flush();
- }
- }
- }
-
- if highlighter.is_some() {
- let _ = stdout.write_all(RESET);
- let _ = stdout.flush();
- }
- });
-
- std::thread::spawn(move || {
- let mut stdin = std::io::stdin();
- let mut buf = [0u8; 8192];
- loop {
- match stdin.read(&mut buf) {
- Ok(0) | Err(_) => break,
- Ok(n) => {
- if pty_writer.write_all(&buf[..n]).is_err() {
- break;
- }
- }
- }
- }
- });
-
- let status = child.wait()?;
- let _ = stdout_thread.join();
-
- let _ = terminal::disable_raw_mode();
- let _ = std::fs::remove_file(&sock_path);
-
- std::process::exit(process_exit_code(status.exit_code()));
-}
-
-fn spawn_resize_handler(
- master: Box<dyn portable_pty::MasterPty + Send>,
- resize_tx: mpsc::SyncSender<Msg>,
- current_cols: Arc<AtomicU16>,
-) -> eyre::Result<()> {
- use signal_hook::consts::SIGWINCH;
- use signal_hook::iterator::Signals;
-
- let mut signals = Signals::new([SIGWINCH])?;
-
- std::thread::spawn(move || {
- for _ in signals.forever() {
- if let Ok((cols, rows)) = terminal::size() {
- current_cols.store(cols.max(1), Ordering::Relaxed);
- let _ = master.resize(PtySize {
- rows,
- cols,
- pixel_width: 0,
- pixel_height: 0,
- });
- let _ = resize_tx.try_send(Msg::Resize { rows, cols });
- }
- }
- });
-
- Ok(())
-}
-
-fn process_exit_code(code: u32) -> i32 {
- i32::try_from(code).unwrap_or(1)
-}
-
-#[cfg(test)]
-mod tests {
- use super::process_exit_code;
-
- #[test]
- fn process_exit_code_preserves_valid_values() {
- assert_eq!(process_exit_code(0), 0);
- assert_eq!(process_exit_code(127), 127);
- assert_eq!(process_exit_code(i32::MAX as u32), i32::MAX);
- }
-
- #[test]
- fn process_exit_code_defaults_when_out_of_range() {
- assert_eq!(process_exit_code(i32::MAX as u32 + 1), 1);
- }
-}