Skip to content

Commit

Permalink
Merge pull request #158 from out-of-cheese-error/skim
Browse files Browse the repository at this point in the history
Empty index for copy/delete/view/edit opens a search window
  • Loading branch information
Ninjani authored Dec 26, 2023
2 parents d5a7b71 + d322b75 commit a8803ad
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 32 deletions.
45 changes: 34 additions & 11 deletions src/the_way/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,19 @@ pub enum TheWaySubcommand {
/// shell snippet code
code: Option<String>,
},
/// Fuzzy search to find a snippet and copy, edit or delete it
/// Search to find a snippet and copy, edit or delete it
Search {
#[clap(flatten)]
filters: Filters,
/// Use exact search instead of fuzzy
#[clap(long, short)]
exact: bool,
/// Print to stdout instead of copying (with Enter)
#[clap(long, short)]
stdout: bool,
/// Use exact search instead of fuzzy
/// Don't ask for confirmation when deleting
#[clap(long, short)]
exact: bool,
force: bool,
},
/// Sync snippets to a Gist
///
Expand Down Expand Up @@ -116,31 +119,51 @@ pub enum TheWaySubcommand {
},
/// Change snippet
Edit {
/// Index of snippet to change
index: usize,
/// Index of snippet to change, opens a search window if not given
index: Option<usize>,
#[clap(flatten)]
filters: Filters,
/// Use exact search instead of fuzzy
#[clap(long, short)]
exact: bool,
},
/// Delete snippet
#[clap(alias = "delete")]
Del {
/// Index of snippet to delete
index: usize,
/// Index of snippet to delete, opens a search window if not given
index: Option<usize>,
#[clap(flatten)]
filters: Filters,
/// Use exact search instead of fuzzy
#[clap(long, short)]
exact: bool,
/// Don't ask for confirmation
#[clap(long, short)]
force: bool,
},
/// Copy snippet to clipboard
#[clap(alias = "copy")]
Cp {
/// Index of snippet to copy
index: usize,
/// Index of snippet to copy, opens a search window if not given
index: Option<usize>,
#[clap(flatten)]
filters: Filters,
/// Use exact search instead of fuzzy
#[clap(long, short)]
exact: bool,
/// Print to stdout instead of copying
#[clap(long, short)]
stdout: bool,
},
/// View snippet
View {
/// Index of snippet to show
index: usize,
/// Index of snippet to show, opens a search window if not given
index: Option<usize>,
#[clap(flatten)]
filters: Filters,
/// Use exact search instead of fuzzy
#[clap(long, short)]
exact: bool,
},
/// Lists (optionally filtered) tags
Tags {
Expand Down
54 changes: 47 additions & 7 deletions src/the_way/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,44 @@ impl TheWay {
TheWaySubcommand::Cmd { code } => self.the_way_cmd(code),
TheWaySubcommand::Search {
filters,
exact,
stdout,
force,
} => self.search(&filters, stdout, search::SkimCommand::All, exact, force),
TheWaySubcommand::Cp {
index,
filters,
exact,
stdout,
} => match index {
Some(index) => self.copy(index, stdout),
None => self.search(&filters, stdout, search::SkimCommand::Copy, exact, false),
},
TheWaySubcommand::Edit {
index,
filters,
exact,
} => match index {
Some(index) => self.edit(index),
None => self.search(&filters, exact, search::SkimCommand::Edit, false, false),
},
TheWaySubcommand::Del {
index,
filters,
exact,
} => self.search(&filters, stdout, exact),
TheWaySubcommand::Cp { index, stdout } => self.copy(index, stdout),
TheWaySubcommand::Edit { index } => self.edit(index),
TheWaySubcommand::Del { index, force } => self.delete(index, force),
TheWaySubcommand::View { index } => self.view(index),
force,
} => match index {
Some(index) => self.delete(index, force),
None => self.search(&filters, exact, search::SkimCommand::Delete, false, force),
},
TheWaySubcommand::View {
index,
filters,
exact,
} => match index {
Some(index) => self.view(index),
None => self.search(&filters, exact, search::SkimCommand::View, false, false),
},
TheWaySubcommand::List { filters } => self.list(&filters, ListType::Snippet),
TheWaySubcommand::Import {
file,
Expand Down Expand Up @@ -358,15 +389,24 @@ impl TheWay {

/// Displays all snippet descriptions in a skim fuzzy search window
/// A preview window on the right shows the indices of snippets matching the query
fn search(&mut self, filters: &Filters, stdout: bool, exact: bool) -> color_eyre::Result<()> {
fn search(
&mut self,
filters: &Filters,
exact: bool,
command: search::SkimCommand,
stdout: bool,
force: bool,
) -> color_eyre::Result<()> {
let mut snippets = self.filter_snippets(filters)?;
snippets.sort_by(|a, b| a.index.cmp(&b.index));
self.make_search(
snippets,
self.highlighter.skim_theme.clone(),
self.highlighter.selection_style,
stdout,
exact,
command,
stdout,
force,
)?;
Ok(())
}
Expand Down
83 changes: 69 additions & 14 deletions src/the_way/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,36 @@ impl SkimItem for SearchSnippet {
}
}

#[derive(Debug, Clone, Copy)]
pub(crate) enum SkimCommand {
Copy,
Delete,
Edit,
View,
All,
}

impl SkimCommand {
pub fn keys(&self) -> Vec<&'static str> {
match self {
SkimCommand::Copy | SkimCommand::Delete | SkimCommand::Edit | SkimCommand::View => {
vec!["Enter"]
}
SkimCommand::All => vec!["Enter", "shift-left", "shift-right"],
}
}

pub fn names(&self) -> Vec<&'static str> {
match self {
SkimCommand::Copy => vec!["copy"],
SkimCommand::Delete => vec!["delete"],
SkimCommand::Edit => vec!["edit"],
SkimCommand::View => vec!["view"],
SkimCommand::All => vec!["copy", "delete", "edit"],
}
}
}

impl TheWay {
/// Converts a list of snippets into searchable objects and opens a fuzzy search window with the
/// bottom panel listing each snippet's index, description, language and tags
Expand All @@ -134,8 +164,10 @@ impl TheWay {
snippets: Vec<Snippet>,
skim_theme: String,
selection_style: Style,
stdout: bool,
exact: bool,
command: SkimCommand,
stdout: bool,
force: bool,
) -> color_eyre::Result<()> {
let default_language = Language::default();

Expand Down Expand Up @@ -163,18 +195,28 @@ impl TheWay {
index: snippet.index,
});
}
let bind = command
.keys()
.into_iter()
.map(|s| format!("{s}:accept"))
.collect::<Vec<_>>();
let header = format!(
"Press {}",
command
.keys()
.into_iter()
.zip(command.names().into_iter())
.map(|(key, name)| format!("{key} to {name}"))
.collect::<Vec<_>>()
.join(", "),
);

let options = SkimOptionsBuilder::default()
.height(Some("100%"))
.preview(Some(""))
.preview_window(Some("up:70%:wrap"))
.bind(vec![
"shift-left:accept",
"shift-right:accept",
"Enter:accept",
])
.header(Some(
"Press Enter to copy, Shift-left to delete, Shift-right to edit",
))
.bind(bind.iter().map(|s| s.as_ref()).collect())
.header(Some(&header))
.exact(exact)
.multi(true)
.reverse(true)
Expand All @@ -195,14 +237,27 @@ impl TheWay {
.as_any()
.downcast_ref::<SearchSnippet>()
.ok_or(LostTheWay::SearchError)?;
match key {
Key::Enter => {

match (command, key) {
(SkimCommand::Copy, Key::Enter) => {
self.copy(snippet.index, stdout)?;
}
(SkimCommand::Delete, Key::Enter) => {
self.delete(snippet.index, force)?;
}
(SkimCommand::Edit, Key::Enter) => {
self.edit(snippet.index)?;
}
(SkimCommand::View, Key::Enter) => {
self.view(snippet.index)?;
}
(SkimCommand::All, Key::Enter) => {
self.copy(snippet.index, stdout)?;
}
Key::ShiftLeft => {
self.delete(snippet.index, false)?;
(SkimCommand::All, Key::ShiftLeft) => {
self.delete(snippet.index, force)?;
}
Key::ShiftRight => {
(SkimCommand::All, Key::ShiftRight) => {
self.edit(snippet.index)?;
}
_ => (),
Expand Down

0 comments on commit a8803ad

Please sign in to comment.