Skip to content

Commit

Permalink
implement undo and pretty up CLI, fix #11
Browse files Browse the repository at this point in the history
  • Loading branch information
untitaker committed Jun 23, 2023
1 parent 1c6012e commit 6614767
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 150 deletions.
112 changes: 0 additions & 112 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ structopt = "0.3.20"
anyhow = "1.0.34"
ignore = "0.4.16"
difference = "2.0.0"
dialoguer = "0.7.1"
console = "0.13.0"
itertools = "0.10.0"

Expand Down
93 changes: 56 additions & 37 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
mod expr;

use std::collections::VecDeque;
use std::fmt;
use std::fs;
use std::path::PathBuf;
use std::str::FromStr;

use anyhow::{Context, Error};
use thiserror::Error;

use console::{style, Key};
use structopt::StructOpt;
use thiserror::Error;

use expr::{parse_pairs, Expr};

Expand Down Expand Up @@ -62,36 +60,14 @@ struct Cli {
enum PromptAnswer {
Yes,
No,
Undo,
All,
}

#[derive(Error, Debug)]
#[error("invalid answer!")]
struct PromptError;

impl FromStr for PromptAnswer {
type Err = PromptError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"yes" | "y" => Ok(PromptAnswer::Yes),
"no" | "n" => Ok(PromptAnswer::No),
"all" | "a" if s == "A" || s.len() != 1 => Ok(PromptAnswer::All),
_ => Err(PromptError),
}
}
}

impl fmt::Display for PromptAnswer {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
PromptAnswer::Yes => write!(f, "yes"),
PromptAnswer::No => write!(f, "no"),
PromptAnswer::All => write!(f, "all"),
}
}
}

fn main() -> Result<(), Error> {
let Cli {
search,
Expand Down Expand Up @@ -142,8 +118,22 @@ fn main() -> Result<(), Error> {
Err(_) => continue, // presumably binary file
};

let mut old_files = VecDeque::new();
let mut flashed_message = None;

let mut changed = false;

let mut change_i = 0;

let change_file = |file: &mut String, to: String| -> Result<(), Error> {
if fs::read_to_string(entry.path()).map_or(true, |x| x != *file) {
anyhow::bail!("file was changed while spacemod is running. Bailing out!");
}
*file = to;
fs::write(entry.path(), &*file)?;
Ok(())
};

loop {
let new_file = replacer.replace(&file, &replace);

Expand All @@ -154,32 +144,61 @@ fn main() -> Result<(), Error> {
if !accept_all {
term.clear_screen()?;

println!("{}\n\n\n", entry.path().display());
let changeset = difference::Changeset::new(&file.to_string(), &new_file, "\n");
print_changeset(changeset);
print!("\n\n\n");

let input: PromptAnswer = dialoguer::Input::new()
.with_prompt("Accept changes? [y]es [n]o [A]ll")
.with_initial_text("")
.default(PromptAnswer::Yes)
.interact_text()?;
println!(
"\n\n\n{path} [{change_i}] {flashed_message}",
path = style(entry.path().display()).blue(),
change_i = style(change_i).yellow(),
flashed_message = style(flashed_message.take().unwrap_or_default()).red()
);

println!(
"Accept changes? {y} {n} [u]ndo [A]ll",
y = style("[y]es").green(),
n = style("[n]o").red(),
);

let input = loop {
match term.read_key()? {
Key::Char('y') | Key::Enter => break PromptAnswer::Yes,
Key::Char('n') => break PromptAnswer::No,
Key::Char('u') => break PromptAnswer::Undo,
Key::Char('A') => break PromptAnswer::All,
_ => continue,
}
};

match input {
PromptAnswer::No => {
// BUG: this skips over the entire file instead of skipping a single change
continue 'files;
}
PromptAnswer::All => {
accept_all = true;
}
PromptAnswer::Undo => {
if let Some(old_file) = old_files.pop_front() {
change_file(&mut file, old_file)?;
change_i -= 1;
continue;
} else {
flashed_message = Some("!!! nothing on the undo stack");
continue;
}
}
PromptAnswer::Yes => {}
}
}

fs::write(entry.path(), &*new_file)?;
changed = true;

file = new_file.to_string();
old_files.push_front(file.to_string());
old_files.truncate(1024);

let new_file = new_file.to_string();
change_file(&mut file, new_file)?;
change_i += 1;
}

if accept_all && changed {
Expand Down

0 comments on commit 6614767

Please sign in to comment.