diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 137 |
1 files changed, 47 insertions, 90 deletions
diff --git a/src/main.rs b/src/main.rs index 94d6f90..d6b2725 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,113 +1,70 @@ +// will uncomment this once it is closer to release +// #![warn(clippy::cargo)] #![warn(clippy::pedantic)] #![warn(clippy::nursery)] +#![warn(clippy::as_conversions)] +#![warn(clippy::get_unwrap)] +#![allow(clippy::cognitive_complexity)] #![allow(clippy::missing_const_for_fn)] +#![allow(clippy::option_option)] +#![allow(clippy::similar_names)] +#![allow(clippy::struct_excessive_bools)] +#![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_lines)] -#![allow(clippy::unused_self)] +#![allow(clippy::type_complexity)] +// this isn't super relevant in a binary - if it's actually a problem, we'll +// just get a compilation failure +#![allow(clippy::future_not_send)] -mod action; -mod builtins; +mod config; +mod dirs; +mod env; mod format; -mod history; +mod info; mod parse; -mod readline; -mod state; -mod util; +mod prelude; +mod runner; +mod shell; -use async_std::stream::StreamExt as _; +use prelude::*; -async fn resize( - action_w: &async_std::channel::Sender<crate::action::Action>, -) { - let size = terminal_size::terminal_size().map_or( - (24, 80), - |(terminal_size::Width(w), terminal_size::Height(h))| (h, w), - ); - action_w - .send(crate::action::Action::Resize(size)) - .await - .unwrap(); -} - -async fn async_main() -> anyhow::Result<()> { - let mut input = textmode::Input::new().await?; - let mut output = textmode::Output::new().await?; - - // avoid the guards getting stuck in a task that doesn't run to - // completion - let _input_guard = input.take_raw_guard(); - let _output_guard = output.take_screen_guard(); - - let (action_w, action_r) = async_std::channel::unbounded(); +use clap::Parser as _; - let state = state::State::new(); - state.render(&mut output, true).await.unwrap(); +#[derive(clap::Parser)] +#[clap(about = "NoteBook SHell")] +struct Opt { + #[clap(short = 'c')] + command: Option<String>, - let state = util::mutex(state); - - { - let mut signals = signal_hook_async_std::Signals::new(&[ - signal_hook::consts::signal::SIGWINCH, - ])?; - let action_w = action_w.clone(); - async_std::task::spawn(async move { - while signals.next().await.is_some() { - resize(&action_w).await; - } - }); - } - - resize(&action_w).await; + #[clap(long)] + status_fd: Option<std::os::unix::io::RawFd>, +} - { - let state = async_std::sync::Arc::clone(&state); - let action_w = action_w.clone(); - async_std::task::spawn(async move { - while let Some(key) = input.read_key().await.unwrap() { - if let Some(action) = - state.lock_arc().await.handle_key(key).await - { - action_w.send(action).await.unwrap(); - } - } +#[tokio::main] +async fn async_main(opt: Opt) -> Result<i32> { + if let Some(command) = opt.command { + let mut shell_write = opt.status_fd.and_then(|fd| { + nix::sys::stat::fstat(fd).ok().map(|_| { + // Safety: we don't create File instances for or read/write + // data on this fd anywhere else + unsafe { tokio::fs::File::from_raw_fd(fd) } + }) }); - } - // redraw the clock every second - { - let action_w = action_w.clone(); - async_std::task::spawn(async move { - let first_sleep = 1_000_000_000_u64.saturating_sub( - chrono::Local::now().timestamp_subsec_nanos().into(), - ); - async_std::task::sleep(std::time::Duration::from_nanos( - first_sleep, - )) - .await; - let mut interval = async_std::stream::interval( - std::time::Duration::from_secs(1), - ); - action_w.send(crate::action::Action::Render).await.unwrap(); - while interval.next().await.is_some() { - action_w.send(crate::action::Action::Render).await.unwrap(); - } - }); + return runner::main(command, &mut shell_write).await; } - let debouncer = crate::action::debounce(action_r); - while let Some(action) = debouncer.recv().await { - state - .lock_arc() - .await - .handle_action(action, &mut output, &action_w) - .await; - } + #[cfg(nbsh_tokio_console)] + console_subscriber::init(); - Ok(()) + shell::main().await } fn main() { - match async_std::task::block_on(async_main()) { - Ok(_) => (), + match async_main(Opt::parse()) { + Ok(code) => { + std::process::exit(code); + } Err(e) => { eprintln!("nbsh: {}", e); std::process::exit(1); |