Add support for config file (#518)

This commit is contained in:
Denis Isidoro 2021-04-17 10:17:22 -03:00 committed by GitHub
parent d8d0d81368
commit 7fb2b53463
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 718 additions and 331 deletions

View file

@ -1,44 +1,24 @@
use crate::actor;
use crate::cheatsh;
use crate::config::Source;
use crate::config::CONFIG;
use crate::extractor;
use crate::filesystem;
use crate::finder::structures::{Opts as FinderOpts, SuggestionType};
use crate::finder::structures::Opts as FinderOpts;
use crate::finder::Finder;
use crate::structures::cheat::VariableMap;
use crate::structures::config::Config;
use crate::structures::config::Source;
use crate::structures::fetcher::Fetcher;
use crate::tldr;
use crate::welcome;
use anyhow::Context;
use anyhow::Result;
fn gen_core_finder_opts(config: &Config) -> Result<FinderOpts> {
let opts = FinderOpts {
preview: Some(format!("{} preview {{}}", filesystem::exe_string()?)),
overrides: config.fzf_overrides.clone(),
suggestion_type: SuggestionType::SnippetSelection,
query: if config.best_match {
None
} else {
config.get_query()
},
filter: if config.best_match {
config.get_query()
} else {
None
},
..Default::default()
};
Ok(opts)
}
pub fn main(config: Config) -> Result<()> {
let opts = gen_core_finder_opts(&config).context("Failed to generate finder options")?;
pub fn main() -> Result<()> {
let config = &CONFIG;
let opts = FinderOpts::from_config(&config)?;
let (raw_selection, variables, files) = config
.finder
.finder()
.call(opts, |stdin, files| {
let fetcher: Box<dyn Fetcher> = match config.source() {
Source::Cheats(query) => Box::new(cheatsh::Fetcher::new(query)),
@ -59,13 +39,13 @@ pub fn main(config: Config) -> Result<()> {
})
.context("Failed getting selection and variables from finder")?;
let extractions = extractor::extract_from_selections(&raw_selection, config.best_match);
let extractions = extractor::extract_from_selections(&raw_selection, config.best_match());
if extractions.is_err() {
return main(config);
return main();
}
actor::act(extractions, config, files, variables)?;
actor::act(extractions, files, variables)?;
Ok(())
}

View file

@ -1,9 +1,11 @@
use crate::handler;
use crate::shell::{self, ShellSpawnError};
use crate::structures::config;
use crate::cheat_variable;
use crate::shell::{self};
use crate::url;
use crate::welcome;
use anyhow::Result;
use std::io::{self, Read};
#[derive(Debug)]
pub enum Func {
@ -16,58 +18,8 @@ pub enum Func {
pub fn main(func: &Func, args: Vec<String>) -> Result<()> {
match func {
Func::UrlOpen => url::open(args),
Func::Welcome => handler::handle_config(config::config_from_iter(
"navi --path /tmp/navi/irrelevant".split(' ').collect(),
)),
Func::WidgetLastCommand => widget_last_command(),
Func::MapExpand => map_expand(),
Func::Welcome => welcome::main(),
Func::WidgetLastCommand => shell::widget_last_command(),
Func::MapExpand => cheat_variable::map_expand(),
}
}
fn map_expand() -> Result<()> {
let cmd = r#"sed -e 's/^.*$/"&"/' | tr '\n' ' '"#;
shell::command()
.arg("-c")
.arg(cmd)
.spawn()
.map_err(|e| ShellSpawnError::new(cmd, e))?
.wait()?;
Ok(())
}
fn widget_last_command() -> Result<()> {
let mut text = String::new();
io::stdin().read_to_string(&mut text)?;
let replacements = vec![("|", ""), ("||", ""), ("&&", "")];
let parts = shellwords::split(&text).unwrap_or_else(|_| text.split('|').map(|s| s.to_string()).collect());
for p in parts {
for (pattern, escaped) in replacements.clone() {
if p.contains(pattern) && p != pattern {
let replacement = p.replace(pattern, escaped);
text = text.replace(&p, &replacement);
}
}
}
let mut extracted = text.clone();
for (pattern, _) in replacements.clone() {
let mut new_parts = text.rsplit(pattern);
if let Some(extracted_attempt) = new_parts.next() {
if extracted_attempt.len() <= extracted.len() {
extracted = extracted_attempt.to_string();
}
}
}
for (pattern, escaped) in replacements.clone() {
text = text.replace(&escaped, &pattern);
extracted = extracted.replace(&escaped, &pattern);
}
println!("{}", extracted.trim_start());
Ok(())
}

View file

@ -1,15 +1,17 @@
use crate::filesystem::default_cheat_pathbuf;
use crate::filesystem;
use crate::fs::pathbuf_to_string;
use anyhow::Result;
#[derive(Debug)]
pub enum Info {
CheatsPath,
ConfigPath,
}
pub fn main(info: &Info) -> Result<()> {
match info {
Info::CheatsPath => println!("{}", pathbuf_to_string(&default_cheat_pathbuf()?)?),
Info::CheatsPath => println!("{}", pathbuf_to_string(&filesystem::default_cheat_pathbuf()?)?),
Info::ConfigPath => println!("{}", pathbuf_to_string(&filesystem::default_config_pathbuf()?)?),
}
Ok(())
}

View file

@ -3,27 +3,28 @@ pub mod func;
pub mod info;
pub mod preview;
pub mod preview_var;
pub mod repo;
pub mod repo_add;
pub mod repo_browse;
pub mod shell;
use crate::config::Command::{Fn, Info, Preview, PreviewVar, Repo, Widget};
use crate::config::{RepoCommand, CONFIG};
use crate::handler;
use crate::structures::config::Command::{Fn, Info, Preview, PreviewVar, Repo, Widget};
use crate::structures::config::{Config, RepoCommand};
use anyhow::Context;
use anyhow::Result;
pub fn handle_config(config: Config) -> Result<()> {
match config.cmd.as_ref() {
None => handler::core::main(config),
pub fn handle() -> Result<()> {
match CONFIG.cmd() {
None => handler::core::main(),
Some(c) => match c {
Preview { line } => handler::preview::main(&line),
Preview { line } => handler::preview::main(line),
PreviewVar {
selection,
query,
variable,
} => handler::preview_var::main(&selection, &query, &variable),
} => handler::preview_var::main(selection, query, variable),
Widget { shell } => handler::shell::main(shell).context("Failed to print shell widget code"),
@ -36,13 +37,16 @@ pub fn handle_config(config: Config) -> Result<()> {
Repo { cmd } => match cmd {
RepoCommand::Add { uri } => {
handler::repo::add(uri.clone(), &config.finder)
handler::repo_add::main(uri.clone())
.with_context(|| format!("Failed to import cheatsheets from `{}`", uri))?;
handler::core::main(config)
handler::core::main()
}
RepoCommand::Browse => {
handler::repo::browse(&config.finder).context("Failed to browse featured cheatsheets")?;
handler::core::main(config)
let repo =
handler::repo_browse::main().context("Failed to browse featured cheatsheets")?;
handler::repo_add::main(repo.clone())
.with_context(|| format!("Failed to import cheatsheets from `{}`", repo))?;
handler::core::main()
}
},
},

View file

@ -1,3 +1,4 @@
use crate::config::CONFIG;
use crate::ui;
use crate::writer;
use anyhow::Result;
@ -12,13 +13,15 @@ fn extract_elements(argstr: &str) -> (&str, &str, &str) {
}
pub fn main(line: &str) -> Result<()> {
// dbg!(CONFIG.comment_color());
let (tags, comment, snippet) = extract_elements(line);
println!(
"{comment} {tags} \n{snippet}",
comment = ui::style(comment).with(*ui::COMMENT_COLOR),
tags = ui::style(format!("[{}]", tags)).with(*ui::TAG_COLOR),
snippet = ui::style(writer::fix_newlines(snippet)).with(*ui::SNIPPET_COLOR),
comment = ui::style(comment).with(CONFIG.comment_color()),
tags = ui::style(format!("[{}]", tags)).with(CONFIG.tag_color()),
snippet = ui::style(writer::fix_newlines(snippet)).with(CONFIG.snippet_color()),
);
process::exit(0)

View file

@ -1,11 +1,9 @@
use crate::config::CONFIG;
use crate::env_var;
use crate::finder;
use crate::terminal::style::style;
use crate::ui;
use crate::writer;
use anyhow::Result;
use std::collections::HashSet;
use std::iter;
use std::process;
@ -18,8 +16,8 @@ pub fn main(selection: &str, query: &str, variable: &str) -> Result<()> {
let delimiter = env_var::get(env_var::PREVIEW_DELIMITER).ok();
let map = env_var::get(env_var::PREVIEW_MAP).ok();
let active_color = *ui::TAG_COLOR;
let inactive_color = *ui::COMMENT_COLOR;
let active_color = CONFIG.tag_color();
let inactive_color = CONFIG.comment_color();
let mut colored_snippet = String::from(&snippet);
let mut visited_vars: HashSet<&str> = HashSet::new();
@ -28,8 +26,8 @@ pub fn main(selection: &str, query: &str, variable: &str) -> Result<()> {
println!(
"{comment} {tags}",
comment = style(comment).with(*ui::COMMENT_COLOR),
tags = style(format!("[{}]", tags)).with(*ui::TAG_COLOR),
comment = style(comment).with(CONFIG.comment_color()),
tags = style(format!("[{}]", tags)).with(CONFIG.tag_color()),
);
let bracketed_current_variable = format!("<{}>", variable);

View file

@ -1,3 +1,4 @@
use crate::config::CONFIG;
use crate::filesystem;
use crate::finder::structures::{Opts as FinderOpts, SuggestionType};
use crate::finder::{Finder, FinderChoice};
@ -9,51 +10,7 @@ use std::fs;
use std::io::Write;
use std::path;
pub fn browse(finder: &FinderChoice) -> Result<()> {
let repo_pathbuf = {
let mut p = filesystem::tmp_pathbuf()?;
p.push("featured");
p
};
let repo_path_str = pathbuf_to_string(&repo_pathbuf)?;
let _ = filesystem::remove_dir(&repo_pathbuf);
filesystem::create_dir(&repo_pathbuf)?;
let (repo_url, _, _) = git::meta("denisidoro/cheats");
git::shallow_clone(repo_url.as_str(), &repo_path_str)
.with_context(|| format!("Failed to clone `{}`", repo_url))?;
let feature_repos_file = {
let mut p = repo_pathbuf.clone();
p.push("featured_repos.txt");
p
};
let repos = fs::read_to_string(&feature_repos_file).context("Unable to fetch featured repositories")?;
let opts = FinderOpts {
column: Some(1),
suggestion_type: SuggestionType::SingleSelection,
..Default::default()
};
let (repo, _, _) = finder
.call(opts, |stdin, _| {
stdin
.write_all(repos.as_bytes())
.context("Unable to prompt featured repositories")?;
Ok(None)
})
.context("Failed to get repo URL from finder")?;
filesystem::remove_dir(&repo_pathbuf)?;
add(repo, finder)
}
pub fn ask_if_should_import_all(finder: &FinderChoice) -> Result<bool> {
fn ask_if_should_import_all(finder: &FinderChoice) -> Result<bool> {
let opts = FinderOpts {
column: Some(1),
header: Some("Do you want to import all files from this repo?".to_string()),
@ -76,8 +33,10 @@ pub fn ask_if_should_import_all(finder: &FinderChoice) -> Result<bool> {
}
}
pub fn add(uri: String, finder: &FinderChoice) -> Result<()> {
let should_import_all = ask_if_should_import_all(finder).unwrap_or(false);
pub fn main(uri: String) -> Result<()> {
let finder = CONFIG.finder();
let should_import_all = ask_if_should_import_all(&finder).unwrap_or(false);
let (actual_uri, user, repo) = git::meta(uri.as_str());
let cheat_pathbuf = filesystem::default_cheat_pathbuf()?;

View file

@ -0,0 +1,56 @@
use crate::config::CONFIG;
use crate::filesystem;
use crate::finder::structures::{Opts as FinderOpts, SuggestionType};
use crate::finder::Finder;
use crate::fs::pathbuf_to_string;
use crate::git;
use anyhow::Context;
use anyhow::Result;
use std::fs;
use std::io::Write;
pub fn main() -> Result<String> {
let finder = CONFIG.finder();
let repo_pathbuf = {
let mut p = filesystem::tmp_pathbuf()?;
p.push("featured");
p
};
let repo_path_str = pathbuf_to_string(&repo_pathbuf)?;
let _ = filesystem::remove_dir(&repo_pathbuf);
filesystem::create_dir(&repo_pathbuf)?;
let (repo_url, _, _) = git::meta("denisidoro/cheats");
git::shallow_clone(repo_url.as_str(), &repo_path_str)
.with_context(|| format!("Failed to clone `{}`", repo_url))?;
let feature_repos_file = {
let mut p = repo_pathbuf.clone();
p.push("featured_repos.txt");
p
};
let repos = fs::read_to_string(&feature_repos_file).context("Unable to fetch featured repositories")?;
let opts = FinderOpts {
column: Some(1),
suggestion_type: SuggestionType::SingleSelection,
..Default::default()
};
let (repo, _, _) = finder
.call(opts, |stdin, _| {
stdin
.write_all(repos.as_bytes())
.context("Unable to prompt featured repositories")?;
Ok(None)
})
.context("Failed to get repo URL from finder")?;
filesystem::remove_dir(&repo_pathbuf)?;
Ok(repo)
}