Implement possibility to copy output of commands to paste buffers.
This commit is contained in:
@@ -19,3 +19,4 @@ home = "0.5.4"
|
|||||||
sha1 = "0.10.5"
|
sha1 = "0.10.5"
|
||||||
base64 = "0.20.0"
|
base64 = "0.20.0"
|
||||||
rpassword = "7.2.0"
|
rpassword = "7.2.0"
|
||||||
|
shlex = "1.1.0"
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ peg::parser! {
|
|||||||
/ ls_cmd()
|
/ ls_cmd()
|
||||||
/ mv_cmd()
|
/ mv_cmd()
|
||||||
/ rm_cmd()
|
/ rm_cmd()
|
||||||
|
/ pb_cmd()
|
||||||
/ enc_cmd()
|
/ enc_cmd()
|
||||||
/ pass_cmd()
|
/ pass_cmd()
|
||||||
/ noop_cmd()
|
/ noop_cmd()
|
||||||
@@ -75,6 +76,7 @@ peg::parser! {
|
|||||||
rule noop_cmd() -> Command<'input> = (" " / "\r" / "\n" / "\t")* ("#" comment())? { Command::Noop }
|
rule noop_cmd() -> Command<'input> = (" " / "\r" / "\n" / "\t")* ("#" comment())? { Command::Noop }
|
||||||
rule help_cmd() -> Command<'input> = "help" { Command::Help }
|
rule help_cmd() -> Command<'input> = "help" { Command::Help }
|
||||||
rule quit_cmd() -> Command<'input> = "quit" { Command::Quit }
|
rule quit_cmd() -> Command<'input> = "quit" { Command::Quit }
|
||||||
|
rule pb_cmd() -> Command<'input> = "pb" _ e:$(([' '..='~'])+) { Command::PasteBuffer(e.to_string()) }
|
||||||
rule ls_cmd() -> Command<'input> = "ls" f:comment()? { Command::Ls(f.unwrap_or(".".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 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)) }
|
rule error_cmd() -> Command<'input> = "error" _ e:$(([' '..='~'])+) { Command::Error(LKErr::Error(e)) }
|
||||||
|
|||||||
+21
@@ -8,6 +8,7 @@ use crate::lk::LK;
|
|||||||
use crate::parser::command_parser;
|
use crate::parser::command_parser;
|
||||||
use crate::password::{fix_password_recursion, PasswordRef};
|
use crate::password::{fix_password_recursion, PasswordRef};
|
||||||
use crate::structs::{Command, LKErr, Radix, HISTORY_FILE};
|
use crate::structs::{Command, LKErr, Radix, HISTORY_FILE};
|
||||||
|
use crate::utils::{ call_cmd_with_input, get_copy_command_from_env };
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct LKRead {
|
pub struct LKRead {
|
||||||
@@ -183,6 +184,25 @@ impl<'a> LKEval<'a> {
|
|||||||
out.push(pass);
|
out.push(pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cmd_pb(&self, out: &mut Vec<String>, command: &String) {
|
||||||
|
match command_parser::cmd(command) {
|
||||||
|
Ok(cmd) => {
|
||||||
|
let print = LKEval::new(cmd, self.state.clone(), prompt_password).eval();
|
||||||
|
let data = print.out.join("\n");
|
||||||
|
let (copy_command, copy_cmd_args) = get_copy_command_from_env();
|
||||||
|
match call_cmd_with_input(©_command, ©_cmd_args, &data) {
|
||||||
|
Ok(s) if s.len() > 0 => {
|
||||||
|
out.push(format!("Copied output with the command {}, and got following output:", copy_command));
|
||||||
|
out.push(s.trim().to_string());
|
||||||
|
}
|
||||||
|
Ok(_) => out.push(format!("Copied output with command {}", copy_command)),
|
||||||
|
Err(e) => out.push(format!("error: failed to copy: {}", e.to_string())),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Err(e) => out.push(format!("error: faild to parse command {}: {}", command, e.to_string())),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fn cmd_ls(&self, out: &mut Vec<String>, filter: String) {
|
fn cmd_ls(&self, out: &mut Vec<String>, filter: String) {
|
||||||
let re = match Regex::new(&filter) {
|
let re = match Regex::new(&filter) {
|
||||||
Ok(re) => re,
|
Ok(re) => re,
|
||||||
@@ -247,6 +267,7 @@ impl<'a> LKEval<'a> {
|
|||||||
None => out.push("error: password not found".to_string()),
|
None => out.push("error: password not found".to_string()),
|
||||||
},
|
},
|
||||||
Command::Enc(name) => self.cmd_enc(&mut out, name),
|
Command::Enc(name) => self.cmd_enc(&mut out, name),
|
||||||
|
Command::PasteBuffer(command) => self.cmd_pb(&mut out, command),
|
||||||
Command::Pass(name) => match self.get_password(name) {
|
Command::Pass(name) => match self.get_password(name) {
|
||||||
Some(p) => {
|
Some(p) => {
|
||||||
self.state.borrow_mut().secrets.insert(
|
self.state.borrow_mut().secrets.insert(
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ pub enum Command<'a> {
|
|||||||
Rm(Name),
|
Rm(Name),
|
||||||
Enc(Name),
|
Enc(Name),
|
||||||
Pass(Name),
|
Pass(Name),
|
||||||
|
PasteBuffer(String),
|
||||||
Comment(Name, Comment),
|
Comment(Name, Comment),
|
||||||
Error(LKErr<'a>),
|
Error(LKErr<'a>),
|
||||||
Noop,
|
Noop,
|
||||||
|
|||||||
+23
-5
@@ -1,8 +1,11 @@
|
|||||||
|
use std::env;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
|
use shlex::split;
|
||||||
|
use std::ffi::OsString;
|
||||||
|
|
||||||
pub fn call_cmd_with_input(cmd: &str, args: Vec<&str>, input: &str) -> io::Result<String> {
|
pub fn call_cmd_with_input(cmd: &str, args: &Vec<String>, input: &str) -> io::Result<String> {
|
||||||
let mut cmd = Command::new(cmd).args(args).stdin(Stdio::piped()).stdout(Stdio::piped()).spawn()?;
|
let mut cmd = Command::new(cmd).args(args).stdin(Stdio::piped()).stdout(Stdio::piped()).spawn()?;
|
||||||
let mut stdin = cmd.stdin.take().unwrap();
|
let mut stdin = cmd.stdin.take().unwrap();
|
||||||
let stdout = cmd.stdout.as_mut().unwrap();
|
let stdout = cmd.stdout.as_mut().unwrap();
|
||||||
@@ -20,15 +23,30 @@ pub fn call_cmd_with_input(cmd: &str, args: Vec<&str>, input: &str) -> io::Resul
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 -"),
|
||||||
|
"macos" => OsString::from("pbcopy"),
|
||||||
|
"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())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn cmd_exec_test() {
|
fn cmd_exec_test() {
|
||||||
assert_eq!(call_cmd_with_input("true", vec![], "").unwrap(), "".to_string());
|
assert_eq!(call_cmd_with_input("true", &vec![], "").unwrap(), "".to_string());
|
||||||
assert_eq!(call_cmd_with_input("cat", vec![], "ok").unwrap(), "ok".to_string());
|
assert_eq!(call_cmd_with_input("cat", &vec![], "ok").unwrap(), "ok".to_string());
|
||||||
assert_ne!(call_cmd_with_input("cat", vec![], "notok").unwrap(), "ok".to_string());
|
assert_eq!(call_cmd_with_input("cat", &vec![], r###"line 1
|
||||||
assert_eq!(call_cmd_with_input("echo", vec!["-n", "test is ok"], "").unwrap(), "test is ok".to_string());
|
line 2
|
||||||
|
line 3
|
||||||
|
line 4"###).unwrap(), "line 1\nline 2\nline 3\nline 4".to_string());
|
||||||
|
assert_ne!(call_cmd_with_input("cat", &vec![], "notok").unwrap(), "ok".to_string());
|
||||||
|
assert_eq!(call_cmd_with_input("echo", &vec!["-n".to_string(), "test is ok".to_string()], "").unwrap(), "test is ok".to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user