mirror of
https://github.com/denisidoro/navi.git
synced 2026-07-29 13:00:37 +00:00
Add support for config file (#518)
This commit is contained in:
parent
d8d0d81368
commit
7fb2b53463
28 changed files with 718 additions and 331 deletions
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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()?;
|
||||
56
src/handler/repo_browse.rs
Normal file
56
src/handler/repo_browse.rs
Normal 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)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue