1use std::io;
2use std::process::{Command, Stdio};
3
4use radicle_term::element;
5use radicle_term::{Constraint, Element};
6
7use crate::terminal;
8
9pub fn run(elem: impl Element) -> io::Result<()> {
12 let Some(constraint) = Constraint::from_env() else {
13 return elem.write(Constraint::UNBOUNDED);
14 };
15 let Some(rows) = terminal::rows() else {
16 return elem.write(Constraint::UNBOUNDED);
17 };
18 if elem.size(Constraint::UNBOUNDED).rows <= rows {
19 return elem.write(Constraint::UNBOUNDED);
20 }
21 let Some(pager) = radicle::profile::env::pager() else {
22 return elem.write(Constraint::UNBOUNDED);
23 };
24
25 #[cfg(unix)]
26 let Some(parts) = shlex::split(&pager) else {
27 return elem.write(Constraint::UNBOUNDED);
28 };
29 #[cfg(windows)]
30 let parts = winsplit::split(&pager);
31
32 let Some((program, args)) = parts.split_first() else {
33 return elem.write(Constraint::UNBOUNDED);
34 };
35
36 let mut child = Command::new(program)
37 .stdin(Stdio::piped())
38 .stdout(Stdio::inherit())
39 .stderr(Stdio::inherit())
40 .args(args)
41 .spawn()?;
42
43 let writer = child.stdin.as_mut().unwrap();
44 let result = element::write_to(&elem, writer, constraint);
45
46 child.wait()?;
47
48 match result {
49 Err(e) if e.kind() == io::ErrorKind::BrokenPipe => {}
51 Err(e) => return Err(e),
52 Ok(_) => {}
53 }
54
55 Ok(())
56}