Add source command and prepare to expand the file names in source command.
This commit is contained in:
@@ -20,3 +20,4 @@ sha1 = "0.10.5"
|
||||
base64 = "0.20.0"
|
||||
rpassword = "7.2.0"
|
||||
shlex = "1.1.0"
|
||||
shellexpand = "3.0.0"
|
||||
|
||||
@@ -17,6 +17,7 @@ peg::parser! {
|
||||
/ mv_cmd()
|
||||
/ rm_cmd()
|
||||
/ pb_cmd()
|
||||
/ source_cmd()
|
||||
/ enc_cmd()
|
||||
/ pass_cmd()
|
||||
/ noop_cmd()
|
||||
@@ -77,6 +78,7 @@ peg::parser! {
|
||||
rule help_cmd() -> Command<'input> = "help" { Command::Help }
|
||||
rule quit_cmd() -> Command<'input> = "quit" { Command::Quit }
|
||||
rule pb_cmd() -> Command<'input> = "pb" _ e:$(([' '..='~'])+) { Command::PasteBuffer(e.to_string()) }
|
||||
rule source_cmd() -> Command<'input> = "source" _ s:$(([' '..='~'])+) { Command::Source(s.to_string()) }
|
||||
rule ls_cmd() -> Command<'input> = "ls" f:comment()? { Command::Ls(f.unwrap_or(".".to_string())) }
|
||||
rule add_cmd() -> Command<'input> = "add" _ name:name() { Command::Add(Rc::new(RefCell::new(name))) }
|
||||
rule error_cmd() -> Command<'input> = "error" _ e:$(([' '..='~'])+) { Command::Error(LKErr::Error(e)) }
|
||||
|
||||
+30
-1
@@ -3,12 +3,13 @@ use rpassword::prompt_password;
|
||||
use rustyline::error::ReadlineError;
|
||||
use rustyline::Editor;
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::lk::LK;
|
||||
use crate::parser::command_parser;
|
||||
use crate::password::{fix_password_recursion, PasswordRef};
|
||||
use crate::structs::{Command, LKErr, Radix, HISTORY_FILE};
|
||||
use crate::utils::{ call_cmd_with_input, get_copy_command_from_env };
|
||||
use crate::utils::{ call_cmd_with_input, get_copy_command_from_env, get_cmd_args_from_command };
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LKRead {
|
||||
@@ -203,6 +204,33 @@ impl<'a> LKEval<'a> {
|
||||
};
|
||||
}
|
||||
|
||||
fn cmd_source(&self, out: &mut Vec<String>, source: &String) {
|
||||
let script = if source.trim().ends_with("|") {
|
||||
let (cmd, args) = match get_cmd_args_from_command(source.trim().trim_end_matches('|')) {
|
||||
Ok(c) => c,
|
||||
Err(e) => { out.push(format!("error: failed to parse command {:?}: {}", source, e.to_string())); return; },
|
||||
};
|
||||
match call_cmd_with_input(&cmd, &args, "") {
|
||||
Ok(o) => o,
|
||||
Err(e) => { out.push(format!("error: failed to execute command {}: {}", cmd, e.to_string())); return; },
|
||||
}
|
||||
} else {
|
||||
let script = PathBuf::from(source);
|
||||
match std::fs::read_to_string(script) {
|
||||
Ok(script) => script,
|
||||
Err(err) => { out.push(format!("error: failed to read file {}: {}", source, err.to_string())); return; }
|
||||
}
|
||||
};
|
||||
match command_parser::script(&script) {
|
||||
Ok(cmd_list) => {
|
||||
for cmd in cmd_list {
|
||||
LKEval::new(cmd, self.state.clone(), prompt_password).eval().print();
|
||||
}
|
||||
}
|
||||
Err(err) => { out.push(format!("error: {}", err.to_string())); return; }
|
||||
};
|
||||
}
|
||||
|
||||
fn cmd_ls(&self, out: &mut Vec<String>, filter: String) {
|
||||
let re = match Regex::new(&filter) {
|
||||
Ok(re) => re,
|
||||
@@ -268,6 +296,7 @@ impl<'a> LKEval<'a> {
|
||||
},
|
||||
Command::Enc(name) => self.cmd_enc(&mut out, name),
|
||||
Command::PasteBuffer(command) => self.cmd_pb(&mut out, command),
|
||||
Command::Source(script) => self.cmd_source(&mut out, script),
|
||||
Command::Pass(name) => match self.get_password(name) {
|
||||
Some(p) => {
|
||||
self.state.borrow_mut().secrets.insert(
|
||||
|
||||
@@ -27,6 +27,7 @@ pub enum Command<'a> {
|
||||
Enc(Name),
|
||||
Pass(Name),
|
||||
PasteBuffer(String),
|
||||
Source(String),
|
||||
Comment(Name, Comment),
|
||||
Error(LKErr<'a>),
|
||||
Noop,
|
||||
|
||||
+9
-2
@@ -23,6 +23,14 @@ pub fn call_cmd_with_input(cmd: &str, args: &Vec<String>, input: &str) -> io::Re
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_cmd_args_from_command(command: &str) -> io::Result<(String, Vec<String>)> {
|
||||
let args = match split(command) {
|
||||
Some(c) => c,
|
||||
None => return Err(io::Error::new(io::ErrorKind::InvalidData, format!("Failed to parse the command: {:?}", command))),
|
||||
};
|
||||
Ok((args[0].clone(), args[1..].to_vec()))
|
||||
}
|
||||
|
||||
pub fn get_copy_command_from_env() -> (String, Vec<String>) {
|
||||
let cmd_os_str = env::var_os("LESSKEY_PB").unwrap_or_else(|| match env::consts::OS {
|
||||
_ if env::var("TMUX").is_ok() => OsString::from("tmux load-buffer -"),
|
||||
@@ -30,8 +38,7 @@ pub fn get_copy_command_from_env() -> (String, Vec<String>) {
|
||||
"linux" => OsString::from("xclip"),
|
||||
_ => OsString::from("cat"),
|
||||
});
|
||||
let args = split(&cmd_os_str.to_string_lossy()).unwrap_or_else(|| vec!["cat".to_string()]);
|
||||
(args[0].clone(), args[1..].to_vec())
|
||||
get_cmd_args_from_command(&cmd_os_str.to_string_lossy()).unwrap_or_else(|_| ("cat".to_string(), vec![]))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user