-
Notifications
You must be signed in to change notification settings - Fork 471
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: plugin interface for key events via
ya.which()
(#617)
- Loading branch information
Showing
15 changed files
with
244 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
use tokio::sync::mpsc; | ||
use tracing::error; | ||
use yazi_shared::event::Cmd; | ||
|
||
use crate::which::Which; | ||
|
||
pub struct Opt { | ||
tx: mpsc::Sender<usize>, | ||
idx: usize, | ||
} | ||
|
||
impl TryFrom<Cmd> for Opt { | ||
type Error = (); | ||
|
||
fn try_from(mut c: Cmd) -> Result<Self, Self::Error> { | ||
Ok(Self { | ||
tx: c.take_data().ok_or(())?, | ||
idx: c.take_first().and_then(|s| s.parse().ok()).ok_or(())?, | ||
}) | ||
} | ||
} | ||
|
||
impl Which { | ||
pub fn callback(&mut self, opt: impl TryInto<Opt>) { | ||
let Ok(opt) = opt.try_into() else { | ||
return; | ||
}; | ||
|
||
if opt.tx.try_send(opt.idx).is_err() { | ||
error!("callback: send error"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
mod callback; | ||
mod show; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
use std::str::FromStr; | ||
|
||
use yazi_config::{keymap::{Control, Key}, KEYMAP}; | ||
use yazi_shared::{event::Cmd, render, Layer}; | ||
|
||
use crate::which::Which; | ||
|
||
pub struct Opt { | ||
cands: Vec<Control>, | ||
layer: Layer, | ||
silent: bool, | ||
} | ||
|
||
impl TryFrom<Cmd> for Opt { | ||
type Error = anyhow::Error; | ||
|
||
fn try_from(mut c: Cmd) -> Result<Self, Self::Error> { | ||
Ok(Self { | ||
cands: c.take_data().unwrap_or_default(), | ||
layer: Layer::from_str(&c.take_name("layer").unwrap_or_default())?, | ||
silent: c.named.contains_key("silent"), | ||
}) | ||
} | ||
} | ||
|
||
impl Which { | ||
pub fn show(&mut self, opt: impl TryInto<Opt>) { | ||
let Ok(opt) = opt.try_into() else { | ||
return; | ||
}; | ||
|
||
if opt.cands.is_empty() { | ||
return; | ||
} | ||
|
||
self.layer = opt.layer; | ||
self.times = 0; | ||
self.cands = opt.cands.into_iter().map(|c| c.into()).collect(); | ||
|
||
self.visible = true; | ||
self.silent = opt.silent; | ||
render!(); | ||
} | ||
|
||
pub fn show_with(&mut self, key: &Key, layer: Layer) { | ||
self.layer = layer; | ||
self.times = 1; | ||
self.cands = KEYMAP | ||
.get(layer) | ||
.iter() | ||
.filter(|c| c.on.len() > 1 && &c.on[0] == key) | ||
.map(|c| c.into()) | ||
.collect(); | ||
|
||
self.visible = true; | ||
self.silent = false; | ||
render!(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
mod commands; | ||
mod which; | ||
|
||
pub use which::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,60 +1,40 @@ | ||
use yazi_config::{keymap::{Control, ControlCow, Key}, KEYMAP}; | ||
use yazi_config::keymap::{ControlCow, Key}; | ||
use yazi_shared::{emit, render, Layer}; | ||
|
||
#[derive(Default)] | ||
pub struct Which { | ||
layer: Layer, | ||
pub times: usize, | ||
pub cands: Vec<ControlCow>, | ||
pub(super) layer: Layer, | ||
pub times: usize, | ||
pub cands: Vec<ControlCow>, | ||
|
||
pub visible: bool, | ||
} | ||
|
||
impl Default for Which { | ||
fn default() -> Self { | ||
Self { layer: Layer::Manager, times: 0, cands: Default::default(), visible: false } | ||
} | ||
pub silent: bool, | ||
} | ||
|
||
impl Which { | ||
pub fn show(&mut self, key: &Key, layer: Layer) { | ||
self.layer = layer; | ||
self.times = 1; | ||
self.cands = KEYMAP | ||
.get(layer) | ||
.iter() | ||
.filter(|c| c.on.len() > 1 && &c.on[0] == key) | ||
.map(|c| c.into()) | ||
.collect(); | ||
|
||
self.visible = true; | ||
render!(); | ||
} | ||
|
||
pub fn show_with(&mut self, cands: Vec<Control>, layer: Layer) { | ||
self.layer = layer; | ||
fn reset(&mut self) { | ||
self.times = 0; | ||
self.cands = cands.into_iter().map(|c| c.into()).collect(); | ||
self.cands.clear(); | ||
|
||
self.visible = true; | ||
render!(); | ||
self.visible = false; | ||
self.silent = false; | ||
} | ||
|
||
pub fn type_(&mut self, key: Key) -> bool { | ||
self.cands.retain(|c| c.on.len() > self.times && c.on[self.times] == key); | ||
self.times += 1; | ||
|
||
if self.cands.is_empty() { | ||
self.visible = false; | ||
self.reset(); | ||
} else if self.cands.len() == 1 { | ||
self.visible = false; | ||
emit!(Seq(self.cands[0].to_seq(), self.layer)); | ||
} else if let Some(i) = self.cands.iter().position(|c| c.on.len() == self.times + 1) { | ||
self.visible = false; | ||
emit!(Seq(self.cands[i].to_seq(), self.layer)); | ||
emit!(Seq(self.cands.remove(0).into_seq(), self.layer)); | ||
self.reset(); | ||
} else if let Some(i) = self.cands.iter().position(|c| c.on.len() == self.times) { | ||
emit!(Seq(self.cands.remove(i).into_seq(), self.layer)); | ||
self.reset(); | ||
} | ||
|
||
self.times += 1; | ||
render!(); | ||
|
||
true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
use std::str::FromStr; | ||
|
||
use mlua::{ExternalError, ExternalResult, Lua, Table, Value}; | ||
use tokio::sync::mpsc; | ||
use yazi_config::keymap::{Control, Key}; | ||
use yazi_shared::{emit, event::Cmd, Layer}; | ||
|
||
use super::Utils; | ||
|
||
impl Utils { | ||
fn parse_keys(value: Value) -> mlua::Result<Vec<Key>> { | ||
Ok(match value { | ||
Value::String(s) => { | ||
vec![Key::from_str(s.to_str()?).into_lua_err()?] | ||
} | ||
Value::Table(t) => { | ||
let mut v = Vec::with_capacity(10); | ||
for s in t.sequence_values::<mlua::String>() { | ||
v.push(Key::from_str(s?.to_str()?).into_lua_err()?); | ||
} | ||
v | ||
} | ||
_ => Err("invalid `on`".into_lua_err())?, | ||
}) | ||
} | ||
|
||
pub(super) fn layer(lua: &Lua, ya: &Table) -> mlua::Result<()> { | ||
ya.set( | ||
"which", | ||
lua.create_async_function(|_, t: Table| async move { | ||
let (tx, mut rx) = mpsc::channel::<usize>(1); | ||
|
||
let mut cands = Vec::with_capacity(30); | ||
for (i, cand) in t.get::<_, Table>("cands")?.sequence_values::<Table>().enumerate() { | ||
let cand = cand?; | ||
cands.push(Control { | ||
on: Self::parse_keys(cand.get("on")?)?, | ||
exec: vec![Cmd::args("callback", vec![i.to_string()]).with_data(tx.clone())], | ||
desc: cand.get("desc").ok(), | ||
}); | ||
} | ||
|
||
drop(tx); | ||
emit!(Call( | ||
Cmd::new("show") | ||
.with("layer", Layer::Which) | ||
.with_bool("silent", t.get("silent").unwrap_or_default()) | ||
.with_data(cands), | ||
Layer::Which | ||
)); | ||
|
||
Ok(rx.recv().await.map(|idx| idx + 1)) | ||
})?, | ||
)?; | ||
|
||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
mod cache; | ||
mod call; | ||
mod image; | ||
mod layer; | ||
mod log; | ||
mod plugin; | ||
mod preview; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.