Added Kidex plugin for file search.
This commit is contained in:
40
Cargo.lock
generated
40
Cargo.lock
generated
@@ -978,6 +978,26 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "kidex"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"abi_stable",
|
||||||
|
"anyrun-plugin",
|
||||||
|
"fuzzy-matcher",
|
||||||
|
"kidex-common",
|
||||||
|
"open",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "kidex-common"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://github.com/Kirottu/kidex#afcbf54b37dc47b914e0c8f873cb1f11c69674a7"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@@ -1214,6 +1234,16 @@ version = "1.17.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
|
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "open"
|
||||||
|
version = "3.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2078c0039e6a54a0c42c28faa984e115fb4c2d5bf2208f77d1961002df8576f8"
|
||||||
|
dependencies = [
|
||||||
|
"pathdiff",
|
||||||
|
"windows-sys 0.42.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl"
|
name = "openssl"
|
||||||
version = "0.10.45"
|
version = "0.10.45"
|
||||||
@@ -1333,6 +1363,12 @@ version = "1.0.11"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba"
|
checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pathdiff"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
@@ -1660,9 +1696,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.91"
|
version = "1.0.93"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
|
checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
|
@@ -7,5 +7,6 @@ members = [
|
|||||||
"plugins/symbols",
|
"plugins/symbols",
|
||||||
"plugins/rink",
|
"plugins/rink",
|
||||||
"plugins/shell",
|
"plugins/shell",
|
||||||
|
"plugins/kidex",
|
||||||
"plugins/translate",
|
"plugins/translate",
|
||||||
]
|
]
|
@@ -76,6 +76,8 @@ Anyrun requires plugins to function, as they provide the results for input. The
|
|||||||
- Calculator & unit conversion
|
- Calculator & unit conversion
|
||||||
- [Shell](plugins/shell)
|
- [Shell](plugins/shell)
|
||||||
- Run shell commands
|
- Run shell commands
|
||||||
|
- [Kidex](plugins/kidex)
|
||||||
|
- File search provided by [Kidex](https://github.com/Kirottu/kidex)
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
|
@@ -50,7 +50,8 @@ pub enum HandleResult {
|
|||||||
/// Shut down the program
|
/// Shut down the program
|
||||||
Close,
|
Close,
|
||||||
/// Refresh the items. Useful if the runner wants to alter results in place.
|
/// Refresh the items. Useful if the runner wants to alter results in place.
|
||||||
Refresh,
|
/// The inner value can set an exclusive mode for the plugin.
|
||||||
|
Refresh(bool),
|
||||||
/// Copy the content, due to how copying works it must be done like this.
|
/// Copy the content, due to how copying works it must be done like this.
|
||||||
Copy(RVec<u8>),
|
Copy(RVec<u8>),
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
use std::{cell::RefCell, env, fs, path::PathBuf, rc::Rc, time::Duration};
|
use std::{cell::RefCell, env, fs, mem, path::PathBuf, rc::Rc, time::Duration};
|
||||||
|
|
||||||
use abi_stable::std_types::{ROption, RVec};
|
use abi_stable::std_types::{ROption, RVec};
|
||||||
use anyrun_interface::{HandleResult, Match, PluginInfo, PluginRef, PollResult};
|
use anyrun_interface::{HandleResult, Match, PluginInfo, PluginRef, PollResult};
|
||||||
@@ -42,6 +42,9 @@ enum PostRunAction {
|
|||||||
/// Some data that needs to be shared between various parts
|
/// Some data that needs to be shared between various parts
|
||||||
struct RuntimeData {
|
struct RuntimeData {
|
||||||
args: Args,
|
args: Args,
|
||||||
|
/// A plugin may request exclusivity which is set with this
|
||||||
|
exclusive: Option<PluginView>,
|
||||||
|
plugins: Vec<PluginView>,
|
||||||
post_run_action: PostRunAction,
|
post_run_action: PostRunAction,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,6 +103,8 @@ fn main() {
|
|||||||
override_plugins,
|
override_plugins,
|
||||||
config_dir,
|
config_dir,
|
||||||
},
|
},
|
||||||
|
exclusive: None,
|
||||||
|
plugins: Vec::new(),
|
||||||
post_run_action: PostRunAction::None,
|
post_run_action: PostRunAction::None,
|
||||||
});
|
});
|
||||||
-1 // Magic GTK number to continue running
|
-1 // Magic GTK number to continue running
|
||||||
@@ -216,10 +221,10 @@ fn activate(app: >k::Application, runtime_data: Rc<RefCell<Option<RuntimeData>
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
// Load plugins from the paths specified in the config file
|
// Load plugins from the paths specified in the config file
|
||||||
let plugins = Rc::new(
|
runtime_data.borrow_mut().as_mut().unwrap().plugins = plugins
|
||||||
plugins
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|plugin_path| {
|
.map(|plugin_path| {
|
||||||
|
// Load the plugin's dynamic library.
|
||||||
let mut user_path = PathBuf::from(&format!("{}/plugins", config_dir));
|
let mut user_path = PathBuf::from(&format!("{}/plugins", config_dir));
|
||||||
let mut global_path = PathBuf::from("/etc/anyrun/plugins");
|
let mut global_path = PathBuf::from("/etc/anyrun/plugins");
|
||||||
user_path.extend(plugin_path.iter());
|
user_path.extend(plugin_path.iter());
|
||||||
@@ -265,12 +270,11 @@ fn activate(app: >k::Application, runtime_data: Rc<RefCell<Option<RuntimeData>
|
|||||||
|
|
||||||
PluginView { plugin, row, list }
|
PluginView { plugin, row, list }
|
||||||
})
|
})
|
||||||
.collect::<Vec<PluginView>>(),
|
.collect::<Vec<PluginView>>();
|
||||||
);
|
|
||||||
|
|
||||||
// Connect selection events to avoid completely messing up selection logic
|
// Connect selection events to avoid completely messing up selection logic
|
||||||
for plugin_view in plugins.iter() {
|
for plugin_view in runtime_data.borrow().as_ref().unwrap().plugins.iter() {
|
||||||
let plugins_clone = plugins.clone();
|
let plugins_clone = runtime_data.borrow().as_ref().unwrap().plugins.clone();
|
||||||
plugin_view.list.connect_row_selected(move |list, row| {
|
plugin_view.list.connect_row_selected(move |list, row| {
|
||||||
if row.is_some() {
|
if row.is_some() {
|
||||||
let combined_matches = plugins_clone
|
let combined_matches = plugins_clone
|
||||||
@@ -303,9 +307,9 @@ fn activate(app: >k::Application, runtime_data: Rc<RefCell<Option<RuntimeData>
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
// Refresh the matches when text input changes
|
// Refresh the matches when text input changes
|
||||||
let plugins_clone = plugins.clone();
|
let runtime_data_clone = runtime_data.clone();
|
||||||
entry.connect_changed(move |entry| {
|
entry.connect_changed(move |entry| {
|
||||||
refresh_matches(entry.text().to_string(), plugins_clone.clone())
|
refresh_matches(entry.text().to_string(), runtime_data_clone.clone())
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle other key presses for selection control and all other things that may be needed
|
// Handle other key presses for selection control and all other things that may be needed
|
||||||
@@ -321,7 +325,11 @@ fn activate(app: >k::Application, runtime_data: Rc<RefCell<Option<RuntimeData>
|
|||||||
// Handle selections
|
// Handle selections
|
||||||
constants::Down | constants::Tab | constants::Up => {
|
constants::Down | constants::Tab | constants::Up => {
|
||||||
// Combine all of the matches into a `Vec` to allow for easier handling of the selection
|
// Combine all of the matches into a `Vec` to allow for easier handling of the selection
|
||||||
let combined_matches = plugins
|
let combined_matches = runtime_data
|
||||||
|
.borrow()
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.plugins
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|view| {
|
.flat_map(|view| {
|
||||||
view.list.children().into_iter().map(|child| {
|
view.list.children().into_iter().map(|child| {
|
||||||
@@ -335,7 +343,11 @@ fn activate(app: >k::Application, runtime_data: Rc<RefCell<Option<RuntimeData>
|
|||||||
.collect::<Vec<(gtk::ListBoxRow, gtk::ListBox)>>();
|
.collect::<Vec<(gtk::ListBoxRow, gtk::ListBox)>>();
|
||||||
|
|
||||||
// Get the selected match
|
// Get the selected match
|
||||||
let (selected_match, selected_list) = match plugins
|
let (selected_match, selected_list) = match runtime_data
|
||||||
|
.borrow()
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.plugins
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|view| view.list.selected_row().map(|row| (row, view.list.clone())))
|
.find_map(|view| view.list.selected_row().map(|row| (row, view.list.clone())))
|
||||||
{
|
{
|
||||||
@@ -395,9 +407,14 @@ fn activate(app: >k::Application, runtime_data: Rc<RefCell<Option<RuntimeData>
|
|||||||
}
|
}
|
||||||
// Handle when the selected match is "activated"
|
// Handle when the selected match is "activated"
|
||||||
constants::Return => {
|
constants::Return => {
|
||||||
let (selected_match, plugin) = match plugins
|
let mut _runtime_data = runtime_data.borrow_mut();
|
||||||
|
|
||||||
|
let (selected_match, plugin_view) = match _runtime_data
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.plugins
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|view| view.list.selected_row().map(|row| (row, view.plugin)))
|
.find_map(|view| view.list.selected_row().map(|row| (row, view)))
|
||||||
{
|
{
|
||||||
Some(selected) => selected,
|
Some(selected) => selected,
|
||||||
None => {
|
None => {
|
||||||
@@ -406,19 +423,25 @@ fn activate(app: >k::Application, runtime_data: Rc<RefCell<Option<RuntimeData>
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Perform actions based on the result of handling the selection
|
// Perform actions based on the result of handling the selection
|
||||||
match plugin.handle_selection()(unsafe {
|
match plugin_view.plugin.handle_selection()(unsafe {
|
||||||
(*selected_match.data::<Match>("match").unwrap().as_ptr()).clone()
|
(*selected_match.data::<Match>("match").unwrap().as_ptr()).clone()
|
||||||
}) {
|
}) {
|
||||||
HandleResult::Close => {
|
HandleResult::Close => {
|
||||||
window.close();
|
window.close();
|
||||||
Inhibit(true)
|
Inhibit(true)
|
||||||
}
|
}
|
||||||
HandleResult::Refresh => {
|
HandleResult::Refresh(exclusive) => {
|
||||||
refresh_matches(entry_clone.text().to_string(), plugins.clone());
|
if exclusive {
|
||||||
|
_runtime_data.as_mut().unwrap().exclusive = Some(plugin_view.clone());
|
||||||
|
} else {
|
||||||
|
_runtime_data.as_mut().unwrap().exclusive = None;
|
||||||
|
}
|
||||||
|
mem::drop(_runtime_data); // Drop the mutable borrow
|
||||||
|
refresh_matches(entry_clone.text().into(), runtime_data.clone());
|
||||||
Inhibit(false)
|
Inhibit(false)
|
||||||
}
|
}
|
||||||
HandleResult::Copy(bytes) => {
|
HandleResult::Copy(bytes) => {
|
||||||
runtime_data.borrow_mut().as_mut().unwrap().post_run_action =
|
_runtime_data.as_mut().unwrap().post_run_action =
|
||||||
PostRunAction::Copy(bytes.into());
|
PostRunAction::Copy(bytes.into());
|
||||||
window.close();
|
window.close();
|
||||||
Inhibit(true)
|
Inhibit(true)
|
||||||
@@ -441,7 +464,11 @@ fn activate(app: >k::Application, runtime_data: Rc<RefCell<Option<RuntimeData>
|
|||||||
main_list.show();
|
main_list.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_matches(plugin_view: PluginView, plugins: Rc<Vec<PluginView>>, matches: RVec<Match>) {
|
fn handle_matches(
|
||||||
|
plugin_view: PluginView,
|
||||||
|
runtime_data: Rc<RefCell<Option<RuntimeData>>>,
|
||||||
|
matches: RVec<Match>,
|
||||||
|
) {
|
||||||
// Clear out the old matches from the list
|
// Clear out the old matches from the list
|
||||||
for widget in plugin_view.list.children() {
|
for widget in plugin_view.list.children() {
|
||||||
plugin_view.list.remove(&widget);
|
plugin_view.list.remove(&widget);
|
||||||
@@ -534,7 +561,11 @@ fn handle_matches(plugin_view: PluginView, plugins: Rc<Vec<PluginView>>, matches
|
|||||||
// Refresh the items in the view
|
// Refresh the items in the view
|
||||||
plugin_view.row.show_all();
|
plugin_view.row.show_all();
|
||||||
|
|
||||||
let combined_matches = plugins
|
let combined_matches = runtime_data
|
||||||
|
.borrow()
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.plugins
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|view| {
|
.flat_map(|view| {
|
||||||
view.list.children().into_iter().map(|child| {
|
view.list.children().into_iter().map(|child| {
|
||||||
@@ -595,27 +626,40 @@ fn create_info_box(info: &PluginInfo) -> gtk::Box {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Refresh the matches from the plugins
|
/// Refresh the matches from the plugins
|
||||||
fn refresh_matches(input: String, plugins: Rc<Vec<PluginView>>) {
|
fn refresh_matches(input: String, runtime_data: Rc<RefCell<Option<RuntimeData>>>) {
|
||||||
for plugin_view in plugins.iter() {
|
for plugin_view in runtime_data.borrow().as_ref().unwrap().plugins.iter() {
|
||||||
let id = plugin_view.plugin.get_matches()(input.clone().into());
|
let id = plugin_view.plugin.get_matches()(input.clone().into());
|
||||||
let plugin_view = plugin_view.clone();
|
let plugin_view = plugin_view.clone();
|
||||||
let plugins = plugins.clone();
|
let runtime_data_clone = runtime_data.clone();
|
||||||
// If the input is empty, skip getting matches and just clear everything out.
|
// If the input is empty, skip getting matches and just clear everything out.
|
||||||
if input.is_empty() {
|
if input.is_empty() {
|
||||||
handle_matches(plugin_view, plugins, RVec::new());
|
handle_matches(plugin_view, runtime_data_clone, RVec::new());
|
||||||
|
// If a plugin has requested exclusivity, respect it
|
||||||
|
} else if let Some(exclusive) = &runtime_data.borrow().as_ref().unwrap().exclusive {
|
||||||
|
if plugin_view.plugin.info() == exclusive.plugin.info() {
|
||||||
|
glib::timeout_add_local(Duration::from_micros(1000), move || {
|
||||||
|
async_match(plugin_view.clone(), runtime_data_clone.clone(), id)
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
handle_matches(plugin_view.clone(), runtime_data_clone, RVec::new());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
glib::timeout_add_local(Duration::from_micros(1000), move || {
|
glib::timeout_add_local(Duration::from_micros(1000), move || {
|
||||||
async_match(plugin_view.clone(), plugins.clone(), id)
|
async_match(plugin_view.clone(), runtime_data_clone.clone(), id)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle the asynchronously running match task
|
/// Handle the asynchronously running match task
|
||||||
fn async_match(plugin_view: PluginView, plugins: Rc<Vec<PluginView>>, id: u64) -> glib::Continue {
|
fn async_match(
|
||||||
|
plugin_view: PluginView,
|
||||||
|
runtime_data: Rc<RefCell<Option<RuntimeData>>>,
|
||||||
|
id: u64,
|
||||||
|
) -> glib::Continue {
|
||||||
match plugin_view.plugin.poll_matches()(id) {
|
match plugin_view.plugin.poll_matches()(id) {
|
||||||
PollResult::Ready(matches) => {
|
PollResult::Ready(matches) => {
|
||||||
handle_matches(plugin_view, plugins, matches);
|
handle_matches(plugin_view, runtime_data, matches);
|
||||||
glib::Continue(false)
|
glib::Continue(false)
|
||||||
}
|
}
|
||||||
PollResult::Pending => glib::Continue(true),
|
PollResult::Pending => glib::Continue(true),
|
||||||
|
16
plugins/kidex/Cargo.toml
Normal file
16
plugins/kidex/Cargo.toml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
[package]
|
||||||
|
name = "kidex"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyrun-plugin = { path = "../../anyrun-plugin" }
|
||||||
|
kidex-common = { git = "https://github.com/Kirottu/kidex", features = ["util"] }
|
||||||
|
abi_stable = "0.11.1"
|
||||||
|
fuzzy-matcher = "0.3.7"
|
||||||
|
open = "3.2.0"
|
146
plugins/kidex/src/lib.rs
Normal file
146
plugins/kidex/src/lib.rs
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
use abi_stable::std_types::{ROption, RString, RVec};
|
||||||
|
use anyrun_plugin::{anyrun_interface::HandleResult, *};
|
||||||
|
use fuzzy_matcher::FuzzyMatcher;
|
||||||
|
use kidex_common::IndexEntry;
|
||||||
|
use std::{os::unix::prelude::OsStrExt, process::Command};
|
||||||
|
|
||||||
|
pub struct State {
|
||||||
|
index: Vec<(usize, IndexEntry)>,
|
||||||
|
selection: Option<IndexEntry>,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum IndexAction {
|
||||||
|
Open,
|
||||||
|
CopyPath,
|
||||||
|
Back,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u64> for IndexAction {
|
||||||
|
fn from(value: u64) -> Self {
|
||||||
|
match value {
|
||||||
|
0 => Self::Open,
|
||||||
|
1 => Self::CopyPath,
|
||||||
|
2 => Self::Back,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handler(selection: Match, state: &mut State) -> HandleResult {
|
||||||
|
match &state.selection {
|
||||||
|
Some(index_entry) => match selection.id.unwrap().into() {
|
||||||
|
IndexAction::Open => {
|
||||||
|
if let Err(why) = Command::new("xdg-open").arg(&index_entry.path).spawn() {
|
||||||
|
println!("Error running xdg-open: {}", why);
|
||||||
|
}
|
||||||
|
HandleResult::Close
|
||||||
|
}
|
||||||
|
IndexAction::CopyPath => {
|
||||||
|
HandleResult::Copy(index_entry.path.clone().into_os_string().as_bytes().into())
|
||||||
|
}
|
||||||
|
IndexAction::Back => {
|
||||||
|
state.selection = None;
|
||||||
|
HandleResult::Refresh(false)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
let (_, index_entry) = state
|
||||||
|
.index
|
||||||
|
.iter()
|
||||||
|
.find(|(id, _)| selection.id == ROption::RSome(*id as u64))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
state.selection = Some(index_entry.clone());
|
||||||
|
HandleResult::Refresh(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init(_config_dir: RString) -> State {
|
||||||
|
State {
|
||||||
|
index: match kidex_common::util::get_index(None) {
|
||||||
|
Ok(index) => index.into_iter().enumerate().collect(),
|
||||||
|
Err(why) => {
|
||||||
|
println!("Failed to get kidex index: {}", why);
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selection: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_matches(input: RString, state: &mut State) -> RVec<Match> {
|
||||||
|
match &state.selection {
|
||||||
|
Some(index_entry) => {
|
||||||
|
let path = index_entry.path.to_string_lossy();
|
||||||
|
vec![
|
||||||
|
Match {
|
||||||
|
title: "Open File".into(),
|
||||||
|
description: ROption::RSome(path.clone().into()),
|
||||||
|
id: ROption::RSome(IndexAction::Open as u64),
|
||||||
|
icon: ROption::RSome("document-open".into()),
|
||||||
|
},
|
||||||
|
Match {
|
||||||
|
title: "Copy Path".into(),
|
||||||
|
description: ROption::RSome(path.into()),
|
||||||
|
id: ROption::RSome(IndexAction::CopyPath as u64),
|
||||||
|
icon: ROption::RSome("edit-copy".into()),
|
||||||
|
},
|
||||||
|
Match {
|
||||||
|
title: "Back".into(),
|
||||||
|
description: ROption::RNone,
|
||||||
|
id: ROption::RSome(IndexAction::Back as u64),
|
||||||
|
icon: ROption::RSome("edit-undo".into()),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let matcher = fuzzy_matcher::skim::SkimMatcherV2::default().smart_case();
|
||||||
|
let mut index = state
|
||||||
|
.index
|
||||||
|
.clone()
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|(id, index_entry)| {
|
||||||
|
matcher
|
||||||
|
.fuzzy_match(&index_entry.path.as_os_str().to_string_lossy(), &input)
|
||||||
|
.map(|val| (index_entry, id, val))
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
index.sort_by(|a, b| b.2.cmp(&a.2));
|
||||||
|
|
||||||
|
index.truncate(3);
|
||||||
|
index
|
||||||
|
.into_iter()
|
||||||
|
.map(|(entry_index, id, _)| Match {
|
||||||
|
title: entry_index
|
||||||
|
.path
|
||||||
|
.file_name()
|
||||||
|
.map(|name| name.to_string_lossy().into())
|
||||||
|
.unwrap_or("N/A".into()),
|
||||||
|
icon: ROption::RSome(if entry_index.directory {
|
||||||
|
"folder".into()
|
||||||
|
} else {
|
||||||
|
"text-x-generic".into()
|
||||||
|
}),
|
||||||
|
description: entry_index
|
||||||
|
.path
|
||||||
|
.parent()
|
||||||
|
.map(|path| path.display().to_string().into())
|
||||||
|
.into(),
|
||||||
|
id: ROption::RSome(id as u64),
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn info() -> PluginInfo {
|
||||||
|
PluginInfo {
|
||||||
|
name: "Kidex".into(),
|
||||||
|
icon: "folder".into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin!(init, info, get_matches, handler, State);
|
Reference in New Issue
Block a user