Add navi repo browse (#280)

This commit is contained in:
Denis Isidoro 2020-03-16 22:56:47 -03:00 committed by GitHub
parent cc8982f014
commit 0b91a374fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 84 additions and 21 deletions

2
Cargo.lock generated
View file

@ -245,7 +245,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "navi"
version = "2.1.3"
version = "2.1.4"
dependencies = [
"dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"git2 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -1,6 +1,6 @@
[package]
name = "navi"
version = "2.1.3"
version = "2.1.4"
authors = ["Denis Isidoro <denis_isidoro@live.com>"]
edition = "2018"
description = "An interactive cheatsheet tool for the command-line"

View file

@ -91,16 +91,11 @@ fn prompt_with_suggestions(
..Default::default()
};
let mut column: Option<u8> = None;
let mut delimiter = r"\s\s+";
if let Some(o) = &suggestion_options {
opts.suggestion_type = o.suggestion_type;
opts.header_lines = o.header_lines;
column = o.column;
if let Some(d) = o.delimiter.as_ref() {
delimiter = d.as_str();
}
opts.column = o.column;
opts.delimiter = o.delimiter.as_deref();
};
let (output, _) = fzf::call(opts, |stdin| {
@ -108,16 +103,7 @@ fn prompt_with_suggestions(
None
});
if let Some(c) = column {
let re = regex::Regex::new(delimiter).unwrap();
let mut parts = re.split(output.as_str());
for _ in 0..(c - 1) {
parts.next().unwrap();
}
parts.next().unwrap().to_string()
} else {
output
}
output
}
fn prompt_without_suggestions(variable_name: &str) -> String {

View file

@ -1,3 +1,5 @@
use crate::handler;
use crate::option;
use std::error::Error;
use std::process::Command;
@ -13,6 +15,11 @@ pub fn main(func: String, args: Vec<String>) -> Result<(), Box<dyn Error>> {
.unwrap();
Ok(())
}
"welcome" => handler::handle_config(option::config_from_iter(
"navi --path /tmp/irrelevant".split(' ').collect(),
)),
_ => unreachable!(""),
}
}

View file

@ -8,11 +8,42 @@ use std::fs;
use std::io::Write;
use walkdir::WalkDir;
pub fn browse() -> Result<(), Box<dyn Error>> {
let repo_path_str = format!("{}/featured", filesystem::tmp_path_str());
filesystem::remove_dir(&repo_path_str);
filesystem::create_dir(&repo_path_str);
match Repository::clone("https://github.com/denisidoro/cheats", &repo_path_str) {
Ok(r) => r,
Err(e) => panic!("failed to clone: {}", e),
};
let repos = fs::read_to_string(format!("{}/featured_repos.txt", &repo_path_str))
.expect("Unable to fetch featured repos");
let opts = fzf::Opts {
column: Some(1),
..Default::default()
};
let (repo, _) = fzf::call(opts, |stdin| {
stdin
.write_all(repos.as_bytes())
.expect("Unable to prompt featured repos");
None
});
filesystem::remove_dir(&repo_path_str);
add(repo)
}
pub fn add(uri: String) -> Result<(), Box<dyn Error>> {
let (actual_uri, user, repo) = git::meta(uri.as_str());
let cheat_path_str = filesystem::pathbuf_to_string(filesystem::cheat_pathbuf().unwrap());
let tmp_path_str = format!("{}/tmp", cheat_path_str);
let tmp_path_str = filesystem::tmp_path_str();
let tmp_path_str_with_trailing_slash = format!("{}/", &tmp_path_str);
filesystem::remove_dir(&tmp_path_str);

View file

@ -83,3 +83,8 @@ pub fn create_dir(path: &str) {
pub fn remove_dir(path: &str) {
fs::remove_dir_all(path).unwrap_or(());
}
pub fn tmp_path_str() -> String {
let cheat_path_str = pathbuf_to_string(cheat_pathbuf().unwrap());
format!("{}/tmp", cheat_path_str)
}

View file

@ -16,6 +16,8 @@ pub struct Opts<'a> {
pub header_lines: u8,
pub header: Option<String>,
pub suggestion_type: SuggestionType,
pub delimiter: Option<&'a str>,
pub column: Option<u8>,
}
impl Default for Opts<'_> {
@ -30,10 +32,25 @@ impl Default for Opts<'_> {
header: None,
prompt: None,
suggestion_type: SingleSelection,
column: None,
delimiter: None,
}
}
}
fn get_column(text: String, column: Option<u8>, delimiter: Option<&str>) -> String {
if let Some(c) = column {
let re = regex::Regex::new(delimiter.unwrap_or(r"\s\s+")).unwrap();
let mut parts = re.split(text.as_str());
for _ in 0..(c - 1) {
parts.next().unwrap();
}
parts.next().unwrap().to_string()
} else {
text
}
}
pub fn call<F>(opts: Opts, stdin_fn: F) -> (String, Option<HashMap<String, cheat::Suggestion>>)
where
F: Fn(&mut process::ChildStdin) -> Option<HashMap<String, cheat::Suggestion>>,
@ -134,7 +151,15 @@ where
panic!("External command failed:\n {}", err)
}
};
(parse_output_single(text, opts.suggestion_type), result)
(
get_column(
parse_output_single(text, opts.suggestion_type),
opts.column,
opts.delimiter,
),
result,
)
}
fn parse_output_single(mut text: String, suggestion_type: SuggestionType) -> String {

View file

@ -15,6 +15,7 @@ pub fn handle_config(mut config: Config) -> Result<(), Box<dyn Error>> {
Fn { func, args } => cmds::func::main(func.clone(), args.to_vec()),
Repo { cmd } => match cmd {
RepoCommand::Add { uri } => cmds::repo::add(uri.clone()),
RepoCommand::Browse => cmds::repo::browse(),
},
},
}

View file

@ -92,6 +92,8 @@ pub enum RepoCommand {
/// A URI to a git repository containing .cheat files ("user/repo" will download cheats from github.com/user/repo)
uri: String,
},
/// Browses for featured cheatsheet repos
Browse,
}
pub enum InternalCommand {

View file

@ -14,5 +14,11 @@ pub fn cheatsheet(stdin: &mut std::process::ChildStdin) {
"navi repo add denisidoro/cheats",
stdin,
);
add_msg(
"cheatsheets",
"Browse for cheatsheet repos",
"navi repo browse",
stdin,
);
add_msg("more info", "Read --help message", "navi --help", stdin);
}