summaryrefslogtreecommitdiffstats
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs137
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);