Skip to content

Commit

Permalink
add tag and lamguage list
Browse files Browse the repository at this point in the history
  • Loading branch information
Ninjani authored and Ninjani committed Dec 26, 2023
1 parent fc2aa4a commit c037e39
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 26 deletions.
19 changes: 10 additions & 9 deletions Cargo.lock

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

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ chrono = { version = "0.4.24", features = ["serde"] }
chrono-english = "0.1.7"

# Taking user input and showing progress
dialoguer = {version = "0.10.4", features = ["completion", "history", "fuzzy-select"]}
dialoguer = {version = "0.11.0", features = ["completion", "history", "fuzzy-select"]}
indicatif = "0.17.3"

# Fuzzy search
Expand All @@ -58,8 +58,8 @@ termcolor = "1.2.0"

# Sync to Gist/GitLab
ureq = { version = "2.6.2", features = ["json"] }
strum = "0.24.1"
strum_macros = "0.24.3"
strum = "0.25.0"
strum_macros = "0.25.3"

# pattern filter and filling shell script variables
regex = "1.8.1"
Expand Down
10 changes: 10 additions & 0 deletions src/the_way/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,16 @@ pub enum TheWaySubcommand {
/// Index of snippet to show
index: usize,
},
/// Lists (optionally filtered) tags
Tags {
#[clap(flatten)]
filters: Filters,
},
/// Lists (optionally filtered) languages
Languages {
#[clap(flatten)]
filters: Filters,
},
}

#[derive(Parser, Debug)]
Expand Down
60 changes: 56 additions & 4 deletions src/the_way/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ pub struct TheWay {
plain: bool,
}

pub enum ListType {
Snippet,
Tag,
Language,
}

// All command-line related functions
impl TheWay {
/// Initialize program with command line input.
Expand Down Expand Up @@ -89,7 +95,7 @@ impl TheWay {
TheWaySubcommand::Edit { index } => self.edit(index),
TheWaySubcommand::Del { index, force } => self.delete(index, force),
TheWaySubcommand::View { index } => self.view(index),
TheWaySubcommand::List { filters } => self.list(&filters),
TheWaySubcommand::List { filters } => self.list(&filters, ListType::Snippet),
TheWaySubcommand::Import {
file,
gist_url,
Expand All @@ -107,6 +113,8 @@ impl TheWay {
ConfigCommand::Get => TheWayConfig::print_config_location(),
},
TheWaySubcommand::Sync { cmd, force } => self.sync(cmd, force),
TheWaySubcommand::Tags { filters } => self.list(&filters, ListType::Tag),
TheWaySubcommand::Languages { filters } => self.list(&filters, ListType::Language),
}
}

Expand Down Expand Up @@ -296,11 +304,55 @@ impl TheWay {
Ok(())
}

fn show_counts(
&self,
object_to_count: HashMap<String, usize>,
list_type: ListType,
) -> color_eyre::Result<()> {
let mut objects = object_to_count.iter().collect::<Vec<_>>();
objects.sort_by(|(_, a), (_, b)| b.cmp(a));
let mut colorized = Vec::new();
for (object, count) in objects {
match list_type {
ListType::Tag => {
colorized.push((self.highlighter.tag_style, object.to_string()));
}
ListType::Language => {
colorized.push((self.highlighter.accent_style, object.to_string()));
}
_ => unreachable!(),
}
colorized.push((self.highlighter.main_style, format!(" ({count})\n")));
}
utils::smart_print(&colorized, false, self.colorize, self.plain)?;
Ok(())
}

/// Lists snippets (optionally filtered)
fn list(&self, filters: &Filters) -> color_eyre::Result<()> {
fn list(&self, filters: &Filters, list_type: ListType) -> color_eyre::Result<()> {
let mut snippets = self.filter_snippets(filters)?;
snippets.sort_by(|a, b| a.index.cmp(&b.index));
self.show_snippets(&snippets)?;
match list_type {
ListType::Snippet => {
snippets.sort_by(|a, b| a.index.cmp(&b.index));
self.show_snippets(&snippets)?;
}
ListType::Tag => {
let mut tags = HashMap::new();
for snippet in &snippets {
for tag in &snippet.tags {
*tags.entry(tag.to_owned()).or_insert(0) += 1;
}
}
self.show_counts(tags, list_type)?;
}
ListType::Language => {
let mut languages = HashMap::new();
for snippet in &snippets {
*languages.entry(snippet.language.to_owned()).or_insert(0) += 1;
}
self.show_counts(languages, list_type)?;
}
}
Ok(())
}

Expand Down
16 changes: 11 additions & 5 deletions src/the_way/snippet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ impl Snippet {
pub(crate) fn from_user(
index: usize,
languages: &HashMap<String, Language>,
all_tags: Vec<String>,
all_used_languages: Vec<String>,
used_tags: Vec<String>,
used_languages: Vec<String>,
old_snippet: Option<&Self>,
) -> color_eyre::Result<Self> {
let (old_description, old_language, old_tags, old_date, old_code) = match old_snippet {
Expand All @@ -114,14 +114,20 @@ impl Snippet {
false,
utils::TheWayCompletion::Empty,
)?;
let mut all_languages = all_used_languages;
all_languages.extend(languages.keys().map(|s| s.to_ascii_lowercase()));
let mut all_languages = used_languages;
let mut unused_languages = languages
.keys()
.map(|s| s.to_ascii_lowercase())
.collect::<Vec<_>>();
unused_languages.sort();
all_languages.extend(unused_languages);

let language_completions = utils::TheWayCompletion::Language(all_languages);
let language =
utils::user_input("Language", old_language, true, false, language_completions)?
.to_ascii_lowercase();
let extension = Language::get_extension(&language, languages);
let tag_completions = utils::TheWayCompletion::Tag(all_tags);
let tag_completions = utils::TheWayCompletion::Tag(used_tags);
let tags = utils::user_input(
"Tags (space separated)",
old_tags.as_deref(),
Expand Down
21 changes: 16 additions & 5 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::collections::HashSet;
use std::io::Write;
use std::process::{Command, Stdio};
use std::str;
Expand Down Expand Up @@ -169,15 +170,14 @@ pub fn user_input(
let theme = dialoguer::theme::ColorfulTheme::default();
match default {
Some(default) => {
let mut input = Input::with_theme(&theme);
input
let mut input = Input::with_theme(&theme)
.with_prompt(message)
.completion_with(&completions)
.allow_empty(allow_empty)
.default(default.to_owned())
.show_default(false);
if show_default {
input.with_initial_text(default);
input = input.with_initial_text(default);
}
Ok(input.interact_text()?.trim().to_owned())
}
Expand Down Expand Up @@ -283,14 +283,25 @@ impl Completion for TheWayCompletion {
}
}
Self::Tag(tags) => {
let current_tags_list = input
.split(' ')
.map(|s| s.to_string())
.collect::<HashSet<_>>();
let last_input = input.split(' ').last().unwrap_or("");
let last_space = input.rfind(' ').unwrap_or(0);
let matches = tags
.iter()
.filter(|option| option.starts_with(last_input))
.filter(|option| {
option.starts_with(last_input) && !current_tags_list.contains(*option)
})
.collect::<Vec<_>>();

if !matches.is_empty() {
Some(input.replace(last_input, matches[0]))
Some(
(input[..last_space].trim().to_string() + " " + matches[0])
.trim()
.to_string(),
)
} else {
None
}
Expand Down

0 comments on commit c037e39

Please sign in to comment.