diff options
Diffstat (limited to 'src/run')
| -rw-r--r-- | src/run/builtin.rs | 125 | ||||
| -rw-r--r-- | src/run/mod.rs | 18 |
2 files changed, 143 insertions, 0 deletions
diff --git a/src/run/builtin.rs b/src/run/builtin.rs index f5dff81..507759f 100644 --- a/src/run/builtin.rs +++ b/src/run/builtin.rs @@ -601,3 +601,128 @@ impl Builtin for terminfo { Ok(()) } } + +pub struct bind; +impl Builtin for bind { + fn name(&self) -> &str { + "bind" + } + + fn io( + &self, + session: Arc<Mutex<Session>>, + args: &[BString], + _stdin: &mut dyn Read, + stdout: &mut dyn Write, + ) -> Result { + let mut usage = || { + writeln!( + stdout, + "usage: bind ti NAMED_KEYBIND COMMAND | bind key KEY COMMAND" + )?; + Err(Error::Exit(1)) + }; + + if args.len() < 3 { + return usage(); + } + + let kind = &args[0]; + let key = &args[1]; + let cmd = &args[2]; + let args = &args[3..]; + + let mut se = session.lock().unwrap(); + + let map = match &kind[..] { + b"ti" => &mut se.ti_keybinds, + b"key" => &mut se.ascii_keybinds, + _ => return usage(), + }; + + map.insert( + key.clone(), + crate::parse::Command { + cmd: cmd.clone(), + args: args.to_vec(), + }, + ); + + Ok(()) + } +} + +pub struct exit; +impl Builtin for exit { + fn name(&self) -> &str { + "exit" + } + + fn special(&self, _session: Arc<Mutex<Session>>, args: &[BString]) { + let exit_code: i32 = loop { + let Some(arg) = args.get(0) else { + break 0; + }; + let Ok(arg) = String::from_utf8(arg.clone()) else { + break 1; + }; + let Ok(num) = arg.parse() else { + break 1; + }; + break num; + }; + + std::process::exit(exit_code); + } + + fn io( + &self, + _session: Arc<Mutex<Session>>, + _args: &[BString], + _stdin: &mut dyn Read, + _stdout: &mut dyn Write, + ) -> Result { + Ok(()) + } +} + +/// control terminal +pub struct ct; +impl Builtin for ct { + fn name(&self) -> &str { + "ct" + } + + fn io( + &self, + session: Arc<Mutex<Session>>, + args: &[BString], + _stdin: &mut dyn Read, + _stdout: &mut dyn Write, + ) -> Result { + let Some(arg) = args.get(0) else { + return Err(Error::Exit(-1)); + }; + + let mut se = session.lock().unwrap(); + + match &arg[..] { + b"cursor_begin" => se.move_to_begin(), + b"cursor_end" => se.move_to_end(), + b"cursor_right" => se.cursor_right(), + b"cursor_left" => se.cursor_left(), + b"cursor_right_word" => se.cursor_right_word(), + b"cursor_left_word" => se.cursor_left_word(), + b"prompt_clear" => se.prompt_clear(), + b"complete" => { + drop(se); + Session::complete(session) + } + b"history_previous" => se.history_up(), + b"history_next" => se.history_down(), + _ => return Err(Error::Exit(-2)), + } + + Ok(()) + } +} diff --git a/src/run/mod.rs b/src/run/mod.rs index c866c6e..a31ff1a 100644 --- a/src/run/mod.rs +++ b/src/run/mod.rs @@ -477,6 +477,21 @@ fn exec(se: Arc<Mutex<Session>>, ast: Ast<PreExpansion>) -> Result<(), ExecError exec.exec_loop(cmd, &mut [c1, c2]) } +pub fn run_quiet( + se: Arc<Mutex<Session>>, + cmd: parse::Command<PostExpansion>, +) -> Result<(), ExecError> { + let mut exec = Executor { + se: se.clone(), + args: None, + expand_commands: true, + }; + let (i, c1) = InputReader::new(Input::Null); + let (o, c2) = OutputWriter::new(Output::Null); + let cmd = exec.execute_pipeline(parse::Pipes { cmds: vec![cmd] }, i, o); + exec.exec_loop(cmd, &mut [c1, c2]) +} + pub fn run(se: Arc<Mutex<Session>>, parsed: Ast<PreExpansion>) { se.lock().unwrap().raw.disable(); let result = exec(se.clone(), parsed); @@ -550,6 +565,9 @@ const BUILTINS: &[&'static dyn Builtin] = &[ #[cfg(debug_assertions)] &builtin::debug, &builtin::terminfo, + &builtin::bind, + &builtin::exit, + &builtin::ct, ]; pub fn builtin_map() -> HashMap<BString, &'static dyn Builtin> { |
