Save alias (#1852)

* figuring out error with lines

* make progress in printing of block

* support for external commands; fix some tiny bugs in formatting

* basic printing of block; going to experiment with bubbling raw input to the command itself to avoid potential edge cases

* remove fmt::Display impls for hir structs; bubbled raw_input to command args

* compiling checkpoint :)

* process raw input alias to remove save flag; do duplicates stored

* fix warnings; run clippy

* removed tmux log file

* fix bug in looking for same alias; changed unwraps to safe unwraps
This commit is contained in:
Elton Leander Pinto 2020-05-20 13:31:04 -04:00 committed by GitHub
parent 3239e5055c
commit 8dc5c34932
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 72 additions and 8 deletions

View File

@ -732,6 +732,7 @@ async fn process_line(
Ok(line) => { Ok(line) => {
let line = chomp_newline(line); let line = chomp_newline(line);
ctx.raw_input = line.to_string();
let result = match nu_parser::lite_parse(&line, 0) { let result = match nu_parser::lite_parse(&line, 0) {
Err(err) => { Err(err) => {
@ -882,6 +883,7 @@ async fn process_line(
ctrl_c: ctx.ctrl_c.clone(), ctrl_c: ctx.ctrl_c.clone(),
registry: ctx.registry.clone(), registry: ctx.registry.clone(),
name: Tag::unknown(), name: Tag::unknown(),
raw_input: line.to_string(),
}; };
if let Ok(mut output_stream) = crate::commands::autoview::autoview(context) { if let Ok(mut output_stream) = crate::commands::autoview::autoview(context) {

View File

@ -1,8 +1,11 @@
use crate::commands::WholeStreamCommand; use crate::commands::WholeStreamCommand;
use crate::context::CommandRegistry; use crate::context::CommandRegistry;
use crate::data::config;
use crate::prelude::*; use crate::prelude::*;
use nu_errors::ShellError; use nu_errors::ShellError;
use nu_protocol::{hir::Block, CommandAction, ReturnSuccess, Signature, SyntaxShape, Value}; use nu_protocol::{
hir::Block, CommandAction, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
};
use nu_source::Tagged; use nu_source::Tagged;
pub struct Alias; pub struct Alias;
@ -12,6 +15,7 @@ pub struct AliasArgs {
pub name: Tagged<String>, pub name: Tagged<String>,
pub args: Vec<Value>, pub args: Vec<Value>,
pub block: Block, pub block: Block,
pub save: Option<bool>,
} }
impl WholeStreamCommand for Alias { impl WholeStreamCommand for Alias {
@ -28,6 +32,7 @@ impl WholeStreamCommand for Alias {
SyntaxShape::Block, SyntaxShape::Block,
"the block to run as the body of the alias", "the block to run as the body of the alias",
) )
.switch("save", "save the alias to your config", Some('s'))
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {
@ -39,7 +44,7 @@ impl WholeStreamCommand for Alias {
args: CommandArgs, args: CommandArgs,
registry: &CommandRegistry, registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
//args.process(registry, alias)?.run() // args.process(registry, alias)?.run()
alias(args, registry) alias(args, registry)
} }
@ -59,19 +64,60 @@ impl WholeStreamCommand for Alias {
} }
} }
// <<<<<<< HEAD
// pub fn alias(alias_args: AliasArgs, ctx: RunnableContext) -> Result<OutputStream, ShellError> {
// =======
pub fn alias(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { pub fn alias(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let registry = registry.clone(); let registry = registry.clone();
let stream = async_stream! { let stream = async_stream! {
let (AliasArgs { name, args: list, block }, _) = args.process(&registry).await?; let mut raw_input = args.raw_input.clone();
let mut args: Vec<String> = vec![]; let (AliasArgs { name, args: list, block, save}, ctx) = args.process(&registry).await?;
let mut processed_args: Vec<String> = vec![];
if let Some(true) = save {
let mut result = crate::data::config::read(name.clone().tag, &None)?;
// process the alias to remove the --save flag
let left_brace = raw_input.find('{').unwrap_or(0);
let right_brace = raw_input.rfind('}').unwrap_or(raw_input.len());
let mut left = raw_input[..left_brace].replace("--save", "").replace("-s", "");
let mut right = raw_input[right_brace..].replace("--save", "").replace("-s", "");
raw_input = format!("{}{}{}", left, &raw_input[left_brace..right_brace], right);
// create a value from raw_input alias
let alias: Value = raw_input.trim().to_string().into();
let alias_start = raw_input.find("[").unwrap_or(0); // used to check if the same alias already exists
// add to startup if alias doesn't exist and replce if it does
match result.get_mut("startup") {
Some(startup) => {
if let UntaggedValue::Table(ref mut commands) = startup.value {
if let Some(command) = commands.iter_mut().find(|command| {
let cmd_str = command.as_string().unwrap_or_default();
cmd_str.starts_with(&raw_input[..alias_start])
}) {
*command = alias;
} else {
commands.push(alias);
}
}
}
None => {
let mut table = UntaggedValue::table(&[alias]);
result.insert("startup".to_string(), table.into_value(Tag::default()));
}
}
config::write(&result, &None)?;
}
for item in list.iter() { for item in list.iter() {
if let Ok(string) = item.as_string() { if let Ok(string) = item.as_string() {
args.push(format!("${}", string)); processed_args.push(format!("${}", string));
} else { } else {
yield Err(ShellError::labeled_error("Expected a string", "expected a string", item.tag())); yield Err(ShellError::labeled_error("Expected a string", "expected a string", item.tag()));
} }
} }
yield ReturnSuccess::action(CommandAction::AddAlias(name.to_string(), args, block.clone())) yield ReturnSuccess::action(CommandAction::AddAlias(name.to_string(), processed_args, block.clone()))
}; };
Ok(stream.to_output_stream()) Ok(stream.to_output_stream())

View File

@ -35,6 +35,7 @@ impl WholeStreamCommand for Autoview {
host: args.host, host: args.host,
ctrl_c: args.ctrl_c, ctrl_c: args.ctrl_c,
name: args.call_info.name_tag, name: args.call_info.name_tag,
raw_input: args.raw_input,
}) })
} }

View File

@ -57,6 +57,7 @@ pub struct CommandArgs {
pub shell_manager: ShellManager, pub shell_manager: ShellManager,
pub call_info: UnevaluatedCallInfo, pub call_info: UnevaluatedCallInfo,
pub input: InputStream, pub input: InputStream,
pub raw_input: String,
} }
#[derive(Getters, Clone)] #[derive(Getters, Clone)]
@ -76,6 +77,7 @@ impl RawCommandArgs {
shell_manager: self.shell_manager, shell_manager: self.shell_manager,
call_info: self.call_info, call_info: self.call_info,
input: input.into(), input: input.into(),
raw_input: String::default(),
} }
} }
} }
@ -151,6 +153,7 @@ pub struct RunnableContext {
pub ctrl_c: Arc<AtomicBool>, pub ctrl_c: Arc<AtomicBool>,
pub registry: CommandRegistry, pub registry: CommandRegistry,
pub name: Tag, pub name: Tag,
pub raw_input: String,
} }
impl RunnableContext { impl RunnableContext {
@ -384,6 +387,7 @@ impl WholeStreamCommand for FnFilterCommand {
shell_manager, shell_manager,
call_info, call_info,
mut input, mut input,
..
} = args; } = args;
let host: Arc<parking_lot::Mutex<dyn Host>> = host.clone(); let host: Arc<parking_lot::Mutex<dyn Host>> = host.clone();

View File

@ -73,6 +73,7 @@ fn lines(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream,
} }
let success_lines: Vec<_> = lines.iter().map(|x| ReturnSuccess::value(UntaggedValue::line(x).into_untagged_value())).collect(); let success_lines: Vec<_> = lines.iter().map(|x| ReturnSuccess::value(UntaggedValue::line(x).into_untagged_value())).collect();
yield futures::stream::iter(success_lines) yield futures::stream::iter(success_lines)
} }
Some(Value { value: UntaggedValue::Primitive(Primitive::Line(st)), ..}) => { Some(Value { value: UntaggedValue::Primitive(Primitive::Line(st)), ..}) => {
@ -119,7 +120,6 @@ fn lines(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream,
} }
} }
.flatten(); .flatten();
Ok(stream.to_output_stream()) Ok(stream.to_output_stream())
} }

View File

@ -80,6 +80,7 @@ impl WholeStreamCommand for RunExternalCommand {
windows_drives_previous_cwd: Arc::new(Mutex::new( windows_drives_previous_cwd: Arc::new(Mutex::new(
std::collections::HashMap::new(), std::collections::HashMap::new(),
)), )),
raw_input: String::default(),
} }
} }
#[cfg(not(windows))] #[cfg(not(windows))]
@ -90,6 +91,7 @@ impl WholeStreamCommand for RunExternalCommand {
shell_manager: args.shell_manager.clone(), shell_manager: args.shell_manager.clone(),
ctrl_c: args.ctrl_c.clone(), ctrl_c: args.ctrl_c.clone(),
current_errors: Arc::new(Mutex::new(vec![])), current_errors: Arc::new(Mutex::new(vec![])),
raw_input: String::default(),
} }
} }
}; };

View File

@ -32,6 +32,7 @@ impl WholeStreamCommand for Sum {
host: args.host, host: args.host,
ctrl_c: args.ctrl_c, ctrl_c: args.ctrl_c,
name: args.call_info.name_tag, name: args.call_info.name_tag,
raw_input: args.raw_input,
}) })
} }

View File

@ -75,6 +75,7 @@ pub struct Context {
pub host: Arc<parking_lot::Mutex<Box<dyn Host>>>, pub host: Arc<parking_lot::Mutex<Box<dyn Host>>>,
pub current_errors: Arc<Mutex<Vec<ShellError>>>, pub current_errors: Arc<Mutex<Vec<ShellError>>>,
pub ctrl_c: Arc<AtomicBool>, pub ctrl_c: Arc<AtomicBool>,
pub raw_input: String,
pub(crate) shell_manager: ShellManager, pub(crate) shell_manager: ShellManager,
#[cfg(windows)] #[cfg(windows)]
@ -96,6 +97,7 @@ impl Context {
ctrl_c: raw_args.ctrl_c.clone(), ctrl_c: raw_args.ctrl_c.clone(),
shell_manager: raw_args.shell_manager.clone(), shell_manager: raw_args.shell_manager.clone(),
windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())), windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())),
raw_input: String::default(),
} }
} }
#[cfg(not(windows))] #[cfg(not(windows))]
@ -106,6 +108,7 @@ impl Context {
current_errors: Arc::new(Mutex::new(vec![])), current_errors: Arc::new(Mutex::new(vec![])),
ctrl_c: raw_args.ctrl_c.clone(), ctrl_c: raw_args.ctrl_c.clone(),
shell_manager: raw_args.shell_manager.clone(), shell_manager: raw_args.shell_manager.clone(),
raw_input: String::default(),
} }
} }
} }
@ -120,6 +123,7 @@ impl Context {
ctrl_c: args.ctrl_c.clone(), ctrl_c: args.ctrl_c.clone(),
shell_manager: args.shell_manager.clone(), shell_manager: args.shell_manager.clone(),
windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())), windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())),
raw_input: String::default(),
} }
} }
#[cfg(not(windows))] #[cfg(not(windows))]
@ -130,6 +134,7 @@ impl Context {
current_errors: Arc::new(Mutex::new(vec![])), current_errors: Arc::new(Mutex::new(vec![])),
ctrl_c: args.ctrl_c.clone(), ctrl_c: args.ctrl_c.clone(),
shell_manager: args.shell_manager.clone(), shell_manager: args.shell_manager.clone(),
raw_input: String::default(),
} }
} }
} }
@ -148,6 +153,7 @@ impl Context {
ctrl_c: Arc::new(AtomicBool::new(false)), ctrl_c: Arc::new(AtomicBool::new(false)),
shell_manager: ShellManager::basic(registry)?, shell_manager: ShellManager::basic(registry)?,
windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())), windows_drives_previous_cwd: Arc::new(Mutex::new(std::collections::HashMap::new())),
raw_input: String::default(),
}) })
} }
@ -161,6 +167,7 @@ impl Context {
current_errors: Arc::new(Mutex::new(vec![])), current_errors: Arc::new(Mutex::new(vec![])),
ctrl_c: Arc::new(AtomicBool::new(false)), ctrl_c: Arc::new(AtomicBool::new(false)),
shell_manager: ShellManager::basic(registry)?, shell_manager: ShellManager::basic(registry)?,
raw_input: String::default(),
}) })
} }
} }
@ -251,6 +258,7 @@ impl Context {
shell_manager: self.shell_manager.clone(), shell_manager: self.shell_manager.clone(),
call_info: self.call_info(args, name_tag, scope), call_info: self.call_info(args, name_tag, scope),
input, input,
raw_input: self.raw_input.clone(),
} }
} }

View File

@ -1,6 +1,6 @@
use std::cmp::{Ord, Ordering, PartialOrd}; use std::cmp::{Ord, Ordering, PartialOrd};
use std::convert::From;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::path::PathBuf; use std::path::PathBuf;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};