From 26699fe76502e79f56139a8e5f6d5a05d13dd6e2 Mon Sep 17 00:00:00 2001 From: Lux Aliaga Date: Wed, 26 Oct 2022 16:37:52 -0300 Subject: [PATCH] item: Implement undo command Brand new feature! Now you can easily undo your last action using "vento -u". While not a fully-fledged history, if you messed something up during your last action, you can now easily undo it! Thank you @Ephera@lemmy.ml for the suggestion! (https://slrpnk.net/post/103331/comment/24020) --- src/bin/drop.rs | 12 ++++---- src/bin/take.rs | 6 ++-- src/bin/vento.rs | 3 +- src/common.rs | 3 ++ src/item.rs | 75 ++++++++++++++++++++++++++++++++++++++---------- 5 files changed, 74 insertions(+), 25 deletions(-) diff --git a/src/bin/drop.rs b/src/bin/drop.rs index dd1c232..e7f7a55 100644 --- a/src/bin/drop.rs +++ b/src/bin/drop.rs @@ -30,11 +30,11 @@ fn main() -> Result<()> { if args[1].contains("--slot=") { // Checks if the user has provided the long argument "--slot=" match args.len() { - 4 => item::drop(&args[2], &args[1].as_str().replace("--slot=", ""), Path::new(&args[4]).to_path_buf())?, + 4 => item::drop(&args[2], &args[1].as_str().replace("--slot=", ""), Path::new(&args[4]).to_path_buf(), true)?, 3 => item::drop(&args[2], &args[1].as_str().replace("--slot=", ""), match env::current_dir() { Ok(dir) => dir, Err(_) => bail!("{}", "Vento was unable to detect your current directory. Have you configured your environment correctly?".red()) - })?, + }, true)?, 2 => bail!("{}", "You need to specify a file".red()), _ => bail!("{}", "Too many arguments".red()), }; @@ -42,21 +42,21 @@ fn main() -> Result<()> { match args[1].as_str() { "--help" | "-h" => help::drop()?, "-s" => match args.len() { - 5 => item::drop(&args[3], &args[2], Path::new(&args[4]).to_path_buf())?, + 5 => item::drop(&args[3], &args[2], Path::new(&args[4]).to_path_buf(), true)?, 4 => item::drop(&args[3], &args[2], match env::current_dir() { Ok(dir) => dir, Err(_) => bail!("{}", "Vento was unable to detect your current directory. Have you configured your environment correctly?".red()) - })?, + }, true)?, 3 => bail!("{}", "You need to specify a file".red()), 2 => bail!("{}", "You need to specify a slot".red()), _ => bail!("{}", "Too many arguments".red()), }, _ => match args.len() { - 3 => item::drop(&args[1], &String::from("active"), Path::new(&args[2]).to_path_buf())?, + 3 => item::drop(&args[1], &String::from("active"), Path::new(&args[2]).to_path_buf(), true)?, 2 => item::drop(&args[1], &String::from("active"), match env::current_dir() { Ok(dir) => dir, Err(_) => bail!("{}", "Vento was unable to detect your current directory. Have you configured your environment correctly?".red()) - })?, + }, true)?, _ => bail!("{}", "Too many arguments".red()), }, } diff --git a/src/bin/take.rs b/src/bin/take.rs index a38544c..dd91a62 100644 --- a/src/bin/take.rs +++ b/src/bin/take.rs @@ -29,7 +29,7 @@ fn main() -> Result<()> { if args[1].contains("--slot=") { // Checks if the user has provided the long argument "--slot=" match args.len() { - 3 => item::take(&args[2], &args[1].replace("--slot=", ""))?, + 3 => item::take(&args[2], &args[1].replace("--slot=", ""), true)?, 2 => bail!("{}", "You need to specify a file".red()), _ => bail!("{}", "Too many arguments".red()), }; @@ -37,13 +37,13 @@ fn main() -> Result<()> { match args[1].as_str() { "--help" | "-h" => help::take()?, "-s" => match args.len() { - 4 => item::take(&args[3], &args[2])?, + 4 => item::take(&args[3], &args[2], true)?, 3 => bail!("{}", "You need to specify a file".red()), 2 => bail!("{}", "You need to specify a slot".red()), _ => bail!("{}", "Too many arguments".red()), }, _ => match args.len() { - 2 => item::take(&args[1], &String::from("active"))?, + 2 => item::take(&args[1], &String::from("active"), true)?, _ => bail!("{}", "Too many arguments".red()), }, } diff --git a/src/bin/vento.rs b/src/bin/vento.rs index 270f977..c5db584 100644 --- a/src/bin/vento.rs +++ b/src/bin/vento.rs @@ -20,7 +20,7 @@ use anyhow::{bail, Result}; use colored::Colorize; use std::env; -use vento::{help, inv}; +use vento::{help, inv, item}; fn main() -> Result<()> { // Handles args in Vento @@ -39,6 +39,7 @@ fn main() -> Result<()> { "-h" | "--help" => help::vento()?, "-i" | "--init" => inv::init()?, "-c" | "--switch" => inv::switch()?, + "-u" | "--undo" => item::undo()?, "-s" => match args.len() { 4 => inv::list(&args[2], &args[3])?, 3 => inv::list(&args[2], "")?, diff --git a/src/common.rs b/src/common.rs index 1dd3a9b..b690258 100644 --- a/src/common.rs +++ b/src/common.rs @@ -33,6 +33,7 @@ pub struct Settings { pub struct HistoryData { pub path: PathBuf, pub file: String, + pub slot: String, pub action: Action, } @@ -108,9 +109,11 @@ pub fn history(data: HistoryData) -> Result<()> { &mut last_file, "{} {} +{} {}", data.path.to_str().unwrap(), data.file, + data.slot, match data.action { Action::Take => "take", Action::Drop => "drop", diff --git a/src/item.rs b/src/item.rs index 6ae8574..ca32895 100644 --- a/src/item.rs +++ b/src/item.rs @@ -24,7 +24,7 @@ use fs_extra::dir::{move_dir, CopyOptions}; use std::fs; use std::path::{Path, PathBuf}; -pub fn take(file: &String, slot: &str) -> Result<()> { +pub fn take(file: &String, slot: &str, message: bool) -> Result<()> { // Takes a file or directory let ventodir = &common::env_config()?.vento_dir; @@ -58,7 +58,9 @@ pub fn take(file: &String, slot: &str) -> Result<()> { let mut sourcelocation: PathBuf = fs::canonicalize(&sourcepath)?; sourcelocation.pop(); let filename = Path::new(&file).file_name().unwrap().to_str().unwrap(); - let destpath: PathBuf = [&slotdir, &sourcepath].iter().collect(); + let destpath: PathBuf = [&slotdir, &Path::new(&filename).to_path_buf()] + .iter() + .collect(); if Path::exists(&destpath) { // Checks if there's a file with the same name in the inventory. @@ -82,20 +84,23 @@ pub fn take(file: &String, slot: &str) -> Result<()> { common::history(common::HistoryData { path: sourcelocation.clone(), file: String::from(filename), + slot: String::from(slot), action: common::Action::Take, })?; - println!( - "✅ {} {} {} ", - "Took".green(), - &filename.bold(), - format!("from {}", &sourcelocation.to_str().unwrap()).green() - ); + if message { + println!( + "✅ {} {} {} ", + "Took".green(), + &filename.bold(), + format!("from {}", &sourcelocation.to_str().unwrap()).green() + ); + } Ok(()) } -pub fn drop(file: &String, slot: &str, dest: PathBuf) -> Result<()> { +pub fn drop(file: &String, slot: &str, dest: PathBuf, message: bool) -> Result<()> { // Drops a file or directory let ventodir = &common::env_config()?.vento_dir; @@ -156,15 +161,55 @@ pub fn drop(file: &String, slot: &str, dest: PathBuf) -> Result<()> { common::history(common::HistoryData { path: destpath.clone(), file: String::from(file), + slot: String::from(slot), action: common::Action::Drop, })?; - println!( - "✅ {} {} {} ", - "Dropped".green(), - &file.bold(), - format!("into {}", &destpath.to_str().unwrap()).green() - ); + if message { + println!( + "✅ {} {} {} ", + "Dropped".green(), + &file.bold(), + format!("into {}", &destpath.to_str().unwrap()).green() + ); + }; + + Ok(()) +} + +pub fn undo() -> Result<()> { + let lastpath: PathBuf = [ + common::env_config()?.vento_dir, + Path::new("last").to_path_buf(), + ] + .iter() + .collect(); + + let lastfile = fs::read_to_string(lastpath)?; + + let mut contents = vec![]; + + for line in lastfile.lines() { + contents.push(line); + } + + if contents.len() != 4 { + bail!("Invalid history length".red()); + } + + match contents[3] { + "take" => { + let destpath = Path::new(contents[0]).to_path_buf(); + drop(&String::from(contents[1]), contents[2], destpath, false)?; + } + "drop" => { + let path = vec![contents[0], contents[1]].join("/"); + take(&path, contents[2], false)?; + } + _ => bail!("Illegal action".red()), + } + + println!("✅ {}", "Last action undone".green(),); Ok(()) }