Skip to content

Commit

Permalink
Nithin/state docs (#462)
Browse files Browse the repository at this point in the history
* shell is not optional, treated like state and StateMut

* adding optional params

* Option s

* fixes

* Adding docs for state
  • Loading branch information
nithinmuthukumar authored May 28, 2024
1 parent 36c1de0 commit e18929f
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 22 deletions.
28 changes: 6 additions & 22 deletions docs/content/docs/shell-config/builtins.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,40 +26,24 @@ help builtins
## Creating your own Builtin

An example of creating a builtin and registering it is provided below.

First, define a builtin and implement the `BuiltinCmd` trait:
Builtins are simply functions that have a required parameter `&Vec<String>`.
Other states can also be accessed by adding them to the parameters; see [States](../states/).

```rust
struct MyBuiltin { }

impl BuiltinCmd for MyBuiltin {
fn run(
&self,
sh: &Shell,
ctx: &mut Context,
rt: &mut Runtime,
args: &[String],
) -> ::anyhow::Result<CmdOutput> {

// builtin implementation ...
println!("this is my builtin~");

// return command status code
Ok(CmdOutput::success())
}
fn my_builtin(args: &Vec<String>){
Ok(CmdOutput::success())
}
```

Then you can register it like so
```rust
let mut builtins = Builtins::default();
builtins.insert("mybuiltin", MyBuiltin {});
builtins.insert("mybuiltin", my_builtin);

myshell.with_builtins(builtins);
```
The builtin can then be ran by calling `mybuiltin`. Any existing builtins of the same name will also be overwritten, so this is a good way to override default builtins with your own version.
The builtin can then be run by calling `mybuiltin`. Any existing builtins of the same name will also be overwritten, so this is a good way to override default builtins with your own version.

A much more comprehensive example can be found in the `shrs` examples directory, [here](https://github.com/MrPicklePinosaur/shrs/blob/master/crates/shrs/examples/custom_builtin.rs).

Note that we used `Builtins::default` instead of `Builtins::new`, it is highly recommended that you use the default builtins since it gives you many essential builtin commands like `cd` and `exit`, where `Builtins::new` gives you literally nothing. So it is much better practice to start with `Builtins::default` and override the ones you want.

70 changes: 70 additions & 0 deletions docs/content/docs/shell-config/states.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
+++
title = "States"
description = ""
date = 2023-12-01t08:00:00+00:00
updated = 2023-12-01t08:00:00+00:00
draft = false
weight = 10
sort_by = "weight"
template = "docs/page.html"

[extra]
lead = ''
toc = true
top = false
+++

**shrs** is highly extensible and allows customizing the states of the different parts of the shell. Shrs also allows users to define their own states which can be used to control various behaviours.

## Accessing states
States can be accessed in various defined callbacks such as [builtins](../builtins/), [hooks](../hooks/), [keybindings](../keybindings/), [prompt](../prompt/) and when initializing a plugin.

States are accessed by adding it to the function parameters, wrapped in either `State` or `StateMut`, depending on if the state should be mutable or not. Accessing `OutputWriter` in a keybinding to write to console can be done like so.

```rust
fn clear_screen(mut out: StateMut<OutputWriter>)-> {
out.println("Clear Screen")?;
}
```

Parameters can also be wrapped in an Option, if the state may not exist when the function is called. Otherwise, **shrs** will panic.

```rust
fn clear_screen(mut out: Option<StateMut<OutputWriter>>)-> {
if let Some(o) = out{
out.println("Clear Screen")?;
}
}
```

Shell is a special state that can only be accessed immutably and is guaranteed to always exist. Accessing state does not require `State` or `StateMut`.

```rust
fn clear_screen(mut out: Option<StateMut<OutputWriter>>,sh: &Shell)-> {
out.println("Clear Screen")?;
}
```

## Defining custom states
Custom states allow users to create states that can be accessed in the same manner as above. States can be easily inserted before the shell starts.

```rust
pub struct T{}
fn main(){
let myshell = ShellBuilder::default().with_state(T{}).build.unwrap();
myshell.run().unwrap();
}

```
States can also be queued to be inserted during callbacks and are inserted directly after.
```rust
pub struct H{}

pub fn f(sh: &Shell, ctx: &SCtx) -> Result<()> {
sh.run_cmd(|sh: &mut Shell, states: &mut States| {
states.insert(H{});
});

Ok(())
}
```

0 comments on commit e18929f

Please sign in to comment.