mirror of
https://github.com/denisidoro/navi
synced 2024-11-13 23:37:10 +00:00
Add error info to core flow.
This commit is contained in:
parent
807c3a35a5
commit
ff264735b9
6 changed files with 59 additions and 34 deletions
|
@ -1,7 +1,7 @@
|
|||
use std::error::Error;
|
||||
use anyhow::Error;
|
||||
use std::process;
|
||||
|
||||
pub fn abort(operation: &str, issue_number: u32) -> Result<(), Box<dyn Error>> {
|
||||
pub fn abort(operation: &str, issue_number: u32) -> Result<(), Error> {
|
||||
eprintln!("This version of navi doesn't support {}.", operation);
|
||||
eprintln!(
|
||||
"Please check https://github.com/denisidoro/navi/issues/{} for more info.",
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::flows;
|
||||
use crate::flows::core::Variant;
|
||||
use crate::structures::option::Config;
|
||||
use std::error::Error;
|
||||
use anyhow::Error;
|
||||
|
||||
pub fn main(query: String, args: Vec<String>, config: Config) -> Result<(), Box<dyn Error>> {
|
||||
pub fn main(query: String, args: Vec<String>, config: Config) -> Result<(), Error> {
|
||||
if args.is_empty() {
|
||||
flows::core::main(Variant::Filter(query), config, false)
|
||||
} else {
|
||||
|
|
|
@ -8,9 +8,10 @@ use crate::structures::cheat::{Suggestion, VariableMap};
|
|||
use crate::structures::fzf::{Opts as FzfOpts, SuggestionType};
|
||||
use crate::structures::option;
|
||||
use crate::structures::option::Config;
|
||||
use anyhow::Context;
|
||||
use anyhow::Error;
|
||||
use regex::Regex;
|
||||
use std::collections::HashMap;
|
||||
use std::error::Error;
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use std::process::{Command, Stdio};
|
||||
|
@ -50,15 +51,18 @@ fn gen_core_fzf_opts(variant: Variant, config: &Config) -> FzfOpts {
|
|||
fn extract_from_selections(raw_snippet: &str, contains_key: bool) -> (&str, &str, &str) {
|
||||
let mut lines = raw_snippet.split('\n');
|
||||
let key = if contains_key {
|
||||
lines.next().unwrap()
|
||||
lines
|
||||
.next()
|
||||
.expect("Key was promised but not present in `selections`")
|
||||
} else {
|
||||
"enter"
|
||||
};
|
||||
|
||||
let mut parts = lines.next().unwrap().split(display::DELIMITER);
|
||||
parts.next();
|
||||
parts.next();
|
||||
parts.next();
|
||||
let mut parts = lines
|
||||
.next()
|
||||
.expect("No more parts in `selections`")
|
||||
.split(display::DELIMITER)
|
||||
.skip(3);
|
||||
|
||||
let tags = parts.next().unwrap_or("");
|
||||
parts.next();
|
||||
|
@ -72,7 +76,7 @@ fn prompt_with_suggestions(
|
|||
config: &Config,
|
||||
suggestion: &Suggestion,
|
||||
values: &HashMap<String, String>,
|
||||
) -> String {
|
||||
) -> Result<String, Error> {
|
||||
let mut vars_cmd = String::from("");
|
||||
for (key, value) in values.iter() {
|
||||
vars_cmd.push_str(format!("{}=\"{}\"; ", key, value).as_str());
|
||||
|
@ -85,9 +89,15 @@ fn prompt_with_suggestions(
|
|||
.arg("-c")
|
||||
.arg(command)
|
||||
.spawn()
|
||||
.unwrap();
|
||||
.context("Failed to execute bash")?;
|
||||
|
||||
let suggestions = String::from_utf8(child.wait_with_output().unwrap().stdout).unwrap();
|
||||
let suggestions = String::from_utf8(
|
||||
child
|
||||
.wait_with_output()
|
||||
.context("Failed to wait and collect output from bash")?
|
||||
.stdout,
|
||||
)
|
||||
.context("Suggestions are invalid utf8")?;
|
||||
|
||||
let opts = suggestion_opts.clone().unwrap_or_default();
|
||||
let opts = FzfOpts {
|
||||
|
@ -98,11 +108,13 @@ fn prompt_with_suggestions(
|
|||
};
|
||||
|
||||
let (output, _) = fzf::call(opts, |stdin| {
|
||||
stdin.write_all(suggestions.as_bytes()).unwrap();
|
||||
stdin
|
||||
.write_all(suggestions.as_bytes())
|
||||
.expect("Could not write to fzf's stdin");
|
||||
None
|
||||
});
|
||||
|
||||
output
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
fn prompt_without_suggestions(variable_name: &str) -> String {
|
||||
|
@ -137,10 +149,11 @@ fn replace_variables_from_snippet(
|
|||
.unwrap_or_else(|| {
|
||||
variables
|
||||
.get(&tags, &variable_name)
|
||||
.map(|suggestion| {
|
||||
.ok_or_else(|| anyhow!("No suggestions"))
|
||||
.and_then(|suggestion| {
|
||||
prompt_with_suggestions(variable_name, &config, suggestion, &values)
|
||||
})
|
||||
.unwrap_or_else(|| prompt_without_suggestions(variable_name))
|
||||
.unwrap_or_else(|_| prompt_without_suggestions(variable_name))
|
||||
});
|
||||
|
||||
values.insert(variable_name.to_string(), value.clone());
|
||||
|
@ -156,7 +169,7 @@ fn with_new_lines(txt: String) -> String {
|
|||
txt.replace(display::LINE_SEPARATOR, "\n")
|
||||
}
|
||||
|
||||
pub fn main(variant: Variant, config: Config, contains_key: bool) -> Result<(), Box<dyn Error>> {
|
||||
pub fn main(variant: Variant, config: Config, contains_key: bool) -> Result<(), Error> {
|
||||
let _ = display::WIDTHS;
|
||||
|
||||
let opts = gen_core_fzf_opts(variant, &config);
|
||||
|
@ -168,7 +181,7 @@ pub fn main(variant: Variant, config: Config, contains_key: bool) -> Result<(),
|
|||
let interpolated_snippet = with_new_lines(replace_variables_from_snippet(
|
||||
snippet,
|
||||
tags,
|
||||
variables.unwrap(),
|
||||
variables.expect("No variables received from fzf"),
|
||||
&config,
|
||||
));
|
||||
|
||||
|
@ -180,7 +193,7 @@ pub fn main(variant: Variant, config: Config, contains_key: bool) -> Result<(),
|
|||
println!("{}", interpolated_snippet);
|
||||
// save to file
|
||||
} else if let Some(s) = config.save {
|
||||
fs::write(s, interpolated_snippet)?;
|
||||
fs::write(s, interpolated_snippet).context("Unable to save config")?;
|
||||
// call navi (this prevents "failed to read /dev/tty" from fzf)
|
||||
} else if interpolated_snippet.starts_with("navi") {
|
||||
let new_config = option::config_from_iter(interpolated_snippet.split(' ').collect());
|
||||
|
@ -190,8 +203,10 @@ pub fn main(variant: Variant, config: Config, contains_key: bool) -> Result<(),
|
|||
Command::new("bash")
|
||||
.arg("-c")
|
||||
.arg(&interpolated_snippet[..])
|
||||
.spawn()?
|
||||
.wait()?;
|
||||
.spawn()
|
||||
.context("Failed to execute bash")?
|
||||
.wait()
|
||||
.context("bash was not running")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crate::flows;
|
||||
use crate::flows::core::Variant;
|
||||
use crate::structures::option::Config;
|
||||
use std::error::Error;
|
||||
use anyhow::Error;
|
||||
|
||||
pub fn main(query: String, config: Config) -> Result<(), Box<dyn Error>> {
|
||||
pub fn main(query: String, config: Config) -> Result<(), Error> {
|
||||
flows::core::main(Variant::Query(query), config, true)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use super::aux;
|
||||
use crate::structures::option::Config;
|
||||
use std::error::Error;
|
||||
use anyhow::Error;
|
||||
|
||||
pub fn main(_query: String, _config: Config) -> Result<(), Box<dyn Error>> {
|
||||
pub fn main(_query: String, _config: Config) -> Result<(), Error> {
|
||||
aux::abort("searching for cheats online", 201)
|
||||
}
|
||||
|
|
|
@ -7,21 +7,31 @@ use anyhow::Error;
|
|||
|
||||
pub fn handle_config(mut config: Config) -> Result<(), Error> {
|
||||
match config.cmd.as_mut() {
|
||||
None => Ok(flows::core::main(Variant::Core, config, true)
|
||||
.expect("TODO: convert this flow fn to anyhow error")),
|
||||
None => flows::core::main(Variant::Core, config, true),
|
||||
|
||||
Some(c) => {
|
||||
match c {
|
||||
Preview { line } => flows::preview::main(&line[..]),
|
||||
Query { query } => Ok(flows::query::main(query.clone(), config)
|
||||
.expect("TODO: convert this flow fn to anyhow error")),
|
||||
Best { query, args } => Ok(flows::best::main(query.clone(), args.to_vec(), config)
|
||||
.expect("TODO: convert this flow fn to anyhow error")),
|
||||
Search { query } => Ok(flows::search::main(query.clone(), config)
|
||||
.expect("TODO: convert this flow fn to anyhow error")),
|
||||
|
||||
Query { query } => {
|
||||
let error_string = format!("Failed to filter cheatsheets for {}", &query);
|
||||
flows::query::main(query.clone(), config).context(error_string)
|
||||
}
|
||||
|
||||
Best { query, args } => {
|
||||
let error_string = format!("Failed to execute snippet similar to {}", &query);
|
||||
flows::best::main(query.clone(), args.to_vec(), config).context(error_string)
|
||||
}
|
||||
|
||||
Search { query } => flows::search::main(query.clone(), config)
|
||||
.context("Failed to search for online cheatsheets"),
|
||||
|
||||
Widget { shell } => Ok(flows::shell::main(&shell[..])
|
||||
.expect("TODO: convert this flow fn to anyhow error")),
|
||||
|
||||
Fn { func, args } => flows::func::main(func.clone(), args.to_vec())
|
||||
.with_context(|| format!("Failed to execute function {}", func)),
|
||||
|
||||
Repo { cmd } => match cmd {
|
||||
RepoCommand::Add { uri } => flows::repo::add(uri.clone())
|
||||
.with_context(|| format!("Failed to import cheatsheets from {}", uri)),
|
||||
|
|
Loading…
Reference in a new issue