Flag to clear history file (#2720)

This commit is contained in:
Chris Gillespie 2020-11-09 08:23:41 -08:00 committed by GitHub
parent 0ee054b14d
commit 0113661c81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 21 deletions

View File

@ -323,6 +323,7 @@ pub async fn run_vec_of_pipelines(
#[cfg(feature = "rustyline-support")]
fn convert_rustyline_result_to_string(input: Result<String, ReadlineError>) -> LineResult {
match input {
Ok(s) if s == "history -c" || s == "history --clear" => LineResult::ClearHistory,
Ok(s) => LineResult::Success(s),
Err(ReadlineError::Interrupted) => LineResult::CtrlC,
Err(ReadlineError::Eof) => LineResult::CtrlD,
@ -499,6 +500,11 @@ pub async fn cli(mut context: EvaluationContext) -> Result<(), Box<dyn Error>> {
context.maybe_print_errors(Text::from(line));
}
LineResult::ClearHistory => {
rl.clear_history();
let _ = rl.save_history(&history_path);
}
LineResult::Error(line, err) => {
rl.add_history_entry(&line);
let _ = rl.save_history(&history_path);
@ -848,6 +854,7 @@ pub enum LineResult {
Break,
CtrlC,
CtrlD,
ClearHistory,
}
pub async fn parse_and_eval(line: &str, ctx: &mut EvaluationContext) -> Result<String, ShellError> {

View File

@ -27,6 +27,11 @@ pub fn history_path(config: &dyn Conf) -> PathBuf {
})
}
#[derive(Deserialize)]
struct Arguments {
clear: Option<bool>,
}
pub struct History;
#[async_trait]
@ -36,7 +41,7 @@ impl WholeStreamCommand for History {
}
fn signature(&self) -> Signature {
Signature::build("history")
Signature::build("history").switch("clear", "Clears out the history entries", Some('c'))
}
fn usage(&self) -> &str {
@ -48,31 +53,45 @@ impl WholeStreamCommand for History {
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
history(args, registry)
history(args, registry).await
}
}
fn history(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
async fn history(
args: CommandArgs,
_registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
let config: Box<dyn Conf> = Box::new(NuConfig::new());
let tag = args.call_info.name_tag;
let path = history_path(&config);
let file = File::open(path);
if let Ok(file) = file {
let reader = BufReader::new(file);
let output = reader.lines().filter_map(move |line| match line {
Ok(line) => Some(ReturnSuccess::value(
UntaggedValue::string(line).into_value(tag.clone()),
)),
Err(_) => None,
});
let tag = args.call_info.name_tag.clone();
let (Arguments { clear }, _) = args.process(&_registry).await?;
Ok(futures::stream::iter(output).to_output_stream())
} else {
Err(ShellError::labeled_error(
"Could not open history",
"history file could not be opened",
tag,
))
let path = history_path(&config);
match clear {
Some(_) => {
// This is a NOOP, the logic to clear is handled in cli.rs
Ok(OutputStream::empty())
}
None => {
if let Ok(file) = File::open(path) {
let reader = BufReader::new(file);
// Skips the first line, which is a Rustyline internal
let output = reader.lines().skip(1).filter_map(move |line| match line {
Ok(line) => Some(ReturnSuccess::value(
UntaggedValue::string(line).into_value(tag.clone()),
)),
Err(_) => None,
});
Ok(futures::stream::iter(output).to_output_stream())
} else {
Err(ShellError::labeled_error(
"Could not open history",
"history file could not be opened",
tag,
))
}
}
}
}