Skip to content

Commit

Permalink
(master) docstrings and improvements to hooks api
Browse files Browse the repository at this point in the history
  • Loading branch information
MrPicklePinosaur committed May 30, 2024
1 parent 737ccce commit 25e64ec
Show file tree
Hide file tree
Showing 13 changed files with 171 additions and 73 deletions.
5 changes: 3 additions & 2 deletions crates/shrs_core/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ extern crate proc_macro;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};

#[proc_macro_derive(HookCtx)]
// TODO should this automatically import the HookEvent trait?
#[proc_macro_derive(HookEvent)]
pub fn derive_ctx(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
// Parse the input tokens into a syntax tree
let input = parse_macro_input!(input as DeriveInput);
Expand All @@ -12,7 +13,7 @@ pub fn derive_ctx(input: proc_macro::TokenStream) -> proc_macro::TokenStream {

// Generate the implementation of the Ctx trait for the specified type
let expanded = quote! {
impl HookCtx for #type_name {}
impl HookEventMarker for #type_name {}
};

// Return the generated implementation as a TokenStream
Expand Down
31 changes: 23 additions & 8 deletions crates/shrs_core/src/cmd_output.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,45 @@
//! Command output is used by shell builtins as well as shell languages to pass return state of
//! commands or programs. This captures stdout and stderr output, as well as exit code

use std::{os::unix::process::ExitStatusExt, process::ExitStatus};

/// Describes the output of a command
#[derive(Clone, Debug)]
pub struct CmdOutput {
pub stdout: String,
pub stderr: String,
pub status: ExitStatus,
}

impl CmdOutput {
pub fn new(status: i32) -> Self {
/// Create a new [CmdOutput] with a specified exit code
pub fn from_status(status: i32) -> Self {
CmdOutput {
stdout: String::new(),
stderr: String::new(),
status: ExitStatus::from_raw(status << 8),
}
}

/// Create a new [CmdOutput] with a successful exit code of 0
pub fn success() -> Self {
CmdOutput::new(0)
CmdOutput::from_status(0)
}

/// Create a new [CmdOutput] with an erroneous exit code of 1
pub fn error() -> Self {
CmdOutput::new(1)
CmdOutput::from_status(1)
}
pub fn error_with_status(status: i32) -> Self {
CmdOutput::new(status)

// Set the stdout
pub fn stdout<S: ToString>(&mut self, stdout: S) -> &mut Self {
self.stdout = stdout.to_string();
self
}
pub fn set_output(&mut self, out: String, err: String) {
self.stdout = out;
self.stderr = err;

// Set the stderr
pub fn stderr<S: ToString>(&mut self, stderr: S) -> &mut Self {
self.stderr = stderr.to_string();
self
}
}
24 changes: 20 additions & 4 deletions crates/shrs_core/src/history.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,40 @@
//! Shell command history
//!
//! History is the ability for the shell to remember previous commands you have typed, providing
//! the ability to cycle back to re-run commands. The [History] trait provides a general interface
//! the shell will interact with to store or fetch shell history, leaving the method of storing the
//! history and the algorithms to fetch history generic.

use std::cell::RefCell;

use crate::prelude::{Shell, States};

/// Trait to implement for shell history
pub trait History {
/// Insert cmd into shell history
/// Insert a command into shell history
fn add(&self, sh: &Shell, states: &States, cmd: String);

/// Remove all history entries
fn clear(&self, sh: &Shell, states: &States);
/// Get number of history entries

/// Get the number of history entries
fn len(&self, sh: &Shell, states: &States) -> usize;

/// Get a history entry by index
fn get(&self, sh: &Shell, states: &States, i: usize) -> Option<String>;

/// Check if the history is empty
fn is_empty(&self, sh: &Shell, states: &States) -> bool {
self.len(sh, states) == 0
}

/// Fetch all the entries in history
// TODO this should be an iterator
fn items(&self, sh: &Shell, states: &States) -> Vec<String>;
}
/// Default implementation of [History] that saves history in process memory

/// Default implementation of [History] that saves history in process memory. This history will not
/// persist across instances of the shell
#[derive(Default)]
pub struct DefaultHistory {
hist: RefCell<Vec<String>>,
Expand All @@ -39,11 +54,12 @@ impl History for DefaultHistory {
fn len(&self, _sh: &Shell, _states: &States) -> usize {
self.hist.borrow().len()
}
/// Get index starts at most recent (index zero is previous command)

/// Get index starts at most recent (index zero is previous command)
fn get(&self, _sh: &Shell, _states: &States, i: usize) -> Option<String> {
self.hist.borrow().get(i).cloned()
}

fn items(&self, _sh: &Shell, _states: &States) -> Vec<String> {
self.hist.borrow().clone()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
use std::{path::PathBuf, process::ExitStatus, time::Duration};

use shrs_core_macros::HookCtx;
//! Hook definitions that are emitted by the shell

use crate::prelude::CmdOutput;
use std::{path::PathBuf, process::ExitStatus, time::Duration};

pub trait HookCtx: 'static + std::marker::Send + std::marker::Sync {}
use crate::prelude::{CmdOutput, HookEvent, HookEventMarker};

/// Runs when the shell starts up
#[derive(HookCtx)]
#[derive(HookEvent)]
pub struct StartupCtx {
/// How long it took the shell to startup
pub startup_time: Duration,
}

/// Runs before a command is executed
#[derive(HookCtx)]
#[derive(HookEvent)]
pub struct BeforeCommandCtx {
/// Literal command entered by user
pub raw_command: String,
/// Command to be executed, after performing all substitutions
pub command: String,
}

#[derive(HookCtx)]
/// Runs after a command has completed
#[derive(HookEvent)]
pub struct AfterCommandCtx {
/// The command that was ran
pub command: String,
Expand All @@ -31,18 +30,20 @@ pub struct AfterCommandCtx {
}

/// Runs when a command not found error is received
#[derive(HookCtx)]
#[derive(HookEvent)]
pub struct CommandNotFoundCtx {}

/// Runs when the current working directory is modified
#[derive(HookCtx)]
#[derive(HookEvent)]
pub struct ChangeDirCtx {
pub old_dir: PathBuf,
pub new_dir: PathBuf,
}

/// Runs when a job is completed
#[derive(HookCtx)]
///
/// Multiple jobs may have completed at the same time so a vector of exit statuses is returned
#[derive(HookEvent)]
pub struct JobExitCtx {
pub exit_statuses: Vec<ExitStatus>,
}
Loading

0 comments on commit 25e64ec

Please sign in to comment.