mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-23 07:41:03 +00:00
feat: allow to specify layer for keymap commands (#2399)
This commit is contained in:
parent
235f6888d4
commit
953d567c63
54 changed files with 263 additions and 284 deletions
|
|
@ -321,7 +321,7 @@ keymap = [
|
|||
{ on = "<F1>", run = "help", desc = "Open help" },
|
||||
]
|
||||
|
||||
[completion]
|
||||
[cmp]
|
||||
|
||||
keymap = [
|
||||
{ on = "<C-c>", run = "close", desc = "Cancel completion" },
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ selected = { reversed = true }
|
|||
|
||||
# : Completion {{{
|
||||
|
||||
[completion]
|
||||
[cmp]
|
||||
border = { fg = "blue" }
|
||||
active = { reversed = true }
|
||||
inactive = {}
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ selected = { reversed = true }
|
|||
|
||||
# : Completion {{{
|
||||
|
||||
[completion]
|
||||
[cmp]
|
||||
border = { fg = "blue" }
|
||||
active = { reversed = true }
|
||||
inactive = {}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::{borrow::Cow, hash::{Hash, Hasher}, sync::OnceLock};
|
|||
|
||||
use regex::Regex;
|
||||
use serde::Deserialize;
|
||||
use yazi_shared::event::Cmd;
|
||||
use yazi_shared::{Layer, event::Cmd};
|
||||
|
||||
use super::Key;
|
||||
|
||||
|
|
@ -42,15 +42,25 @@ impl Chord {
|
|||
|
||||
pub fn desc_or_run(&self) -> Cow<str> { self.desc().unwrap_or_else(|| self.run().into()) }
|
||||
|
||||
#[inline]
|
||||
pub fn noop(&self) -> bool {
|
||||
self.run.len() == 1 && self.run[0].name == "noop" && self.run[0].args.is_empty()
|
||||
}
|
||||
|
||||
pub fn contains(&self, s: &str) -> bool {
|
||||
let s = s.to_lowercase();
|
||||
self.desc().map(|d| d.to_lowercase().contains(&s)) == Some(true)
|
||||
|| self.run().to_lowercase().contains(&s)
|
||||
|| self.on().to_lowercase().contains(&s)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn noop(&self) -> bool {
|
||||
self.run.len() == 1 && self.run[0].name == "noop" && self.run[0].args.is_empty()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn with_layer(mut self, layer: Layer) -> Self {
|
||||
for c in &mut self.run {
|
||||
if c.layer == Default::default() {
|
||||
c.layer = layer;
|
||||
}
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,21 +10,21 @@ use crate::{Preset, keymap::Key};
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct Keymap {
|
||||
pub mgr: Vec<Chord>,
|
||||
pub tasks: Vec<Chord>,
|
||||
pub spot: Vec<Chord>,
|
||||
pub pick: Vec<Chord>,
|
||||
pub input: Vec<Chord>,
|
||||
pub confirm: Vec<Chord>,
|
||||
pub help: Vec<Chord>,
|
||||
pub completion: Vec<Chord>,
|
||||
pub mgr: Vec<Chord>,
|
||||
pub tasks: Vec<Chord>,
|
||||
pub spot: Vec<Chord>,
|
||||
pub pick: Vec<Chord>,
|
||||
pub input: Vec<Chord>,
|
||||
pub confirm: Vec<Chord>,
|
||||
pub help: Vec<Chord>,
|
||||
pub cmp: Vec<Chord>,
|
||||
}
|
||||
|
||||
impl Keymap {
|
||||
#[inline]
|
||||
pub fn get(&self, layer: Layer) -> &[Chord] {
|
||||
match layer {
|
||||
Layer::App => unreachable!(),
|
||||
Layer::App => &[],
|
||||
Layer::Mgr => &self.mgr,
|
||||
Layer::Tasks => &self.tasks,
|
||||
Layer::Spot => &self.spot,
|
||||
|
|
@ -32,8 +32,8 @@ impl Keymap {
|
|||
Layer::Input => &self.input,
|
||||
Layer::Confirm => &self.confirm,
|
||||
Layer::Help => &self.help,
|
||||
Layer::Completion => &self.completion,
|
||||
Layer::Which => unreachable!(),
|
||||
Layer::Cmp => &self.cmp,
|
||||
Layer::Which => &[],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -54,14 +54,14 @@ impl<'de> Deserialize<'de> for Keymap {
|
|||
#[derive(Deserialize)]
|
||||
struct Shadow {
|
||||
#[serde(rename = "manager")]
|
||||
mgr: Inner, // TODO: remove serde(rename)
|
||||
tasks: Inner,
|
||||
spot: Inner,
|
||||
pick: Inner,
|
||||
input: Inner,
|
||||
confirm: Inner,
|
||||
help: Inner,
|
||||
completion: Inner,
|
||||
mgr: Inner, // TODO: remove serde(rename)
|
||||
tasks: Inner,
|
||||
spot: Inner,
|
||||
pick: Inner,
|
||||
input: Inner,
|
||||
confirm: Inner,
|
||||
help: Inner,
|
||||
cmp: Inner,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
struct Inner {
|
||||
|
|
@ -72,7 +72,7 @@ impl<'de> Deserialize<'de> for Keymap {
|
|||
append_keymap: IndexSet<Chord>,
|
||||
}
|
||||
|
||||
fn mix(a: IndexSet<Chord>, b: IndexSet<Chord>, c: IndexSet<Chord>) -> Vec<Chord> {
|
||||
fn mix(l: Layer, a: IndexSet<Chord>, b: IndexSet<Chord>, c: IndexSet<Chord>) -> Vec<Chord> {
|
||||
#[inline]
|
||||
fn on(Chord { on, .. }: &Chord) -> [Key; 2] {
|
||||
[on.first().copied().unwrap_or_default(), on.get(1).copied().unwrap_or_default()]
|
||||
|
|
@ -87,27 +87,28 @@ impl<'de> Deserialize<'de> for Keymap {
|
|||
c.into_iter().filter(|v| !b_seen.contains(&on(v))),
|
||||
)
|
||||
.filter(|chord| !chord.noop())
|
||||
.map(|chord| chord.with_layer(l))
|
||||
.collect()
|
||||
}
|
||||
|
||||
let shadow = Shadow::deserialize(deserializer)?;
|
||||
Ok(Self {
|
||||
#[rustfmt::skip]
|
||||
mgr: mix(shadow.mgr.prepend_keymap, shadow.mgr.keymap, shadow.mgr.append_keymap),
|
||||
mgr: mix(Layer::Mgr, shadow.mgr.prepend_keymap, shadow.mgr.keymap, shadow.mgr.append_keymap),
|
||||
#[rustfmt::skip]
|
||||
tasks: mix(shadow.tasks.prepend_keymap, shadow.tasks.keymap, shadow.tasks.append_keymap),
|
||||
tasks: mix(Layer::Tasks, shadow.tasks.prepend_keymap, shadow.tasks.keymap, shadow.tasks.append_keymap),
|
||||
#[rustfmt::skip]
|
||||
spot: mix(shadow.spot.prepend_keymap, shadow.spot.keymap, shadow.spot.append_keymap),
|
||||
spot: mix(Layer::Spot, shadow.spot.prepend_keymap, shadow.spot.keymap, shadow.spot.append_keymap),
|
||||
#[rustfmt::skip]
|
||||
pick: mix(shadow.pick.prepend_keymap, shadow.pick.keymap, shadow.pick.append_keymap),
|
||||
pick: mix(Layer::Pick, shadow.pick.prepend_keymap, shadow.pick.keymap, shadow.pick.append_keymap),
|
||||
#[rustfmt::skip]
|
||||
input: mix(shadow.input.prepend_keymap, shadow.input.keymap, shadow.input.append_keymap),
|
||||
input: mix(Layer::Input, shadow.input.prepend_keymap, shadow.input.keymap, shadow.input.append_keymap),
|
||||
#[rustfmt::skip]
|
||||
confirm: mix(shadow.confirm.prepend_keymap, shadow.confirm.keymap, shadow.confirm.append_keymap),
|
||||
confirm: mix(Layer::Confirm, shadow.confirm.prepend_keymap, shadow.confirm.keymap, shadow.confirm.append_keymap),
|
||||
#[rustfmt::skip]
|
||||
help: mix(shadow.help.prepend_keymap, shadow.help.keymap, shadow.help.append_keymap),
|
||||
help: mix(Layer::Help, shadow.help.prepend_keymap, shadow.help.keymap, shadow.help.append_keymap),
|
||||
#[rustfmt::skip]
|
||||
completion: mix(shadow.completion.prepend_keymap, shadow.completion.keymap, shadow.completion.append_keymap),
|
||||
cmp: mix(Layer::Cmp, shadow.cmp.prepend_keymap, shadow.cmp.keymap, shadow.cmp.append_keymap),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,20 +9,20 @@ use super::{Filetype, Flavor, Icons};
|
|||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct Theme {
|
||||
pub flavor: Flavor,
|
||||
pub flavor: Flavor,
|
||||
#[serde(rename = "manager")]
|
||||
pub mgr: Mgr, // TODO: Remove `serde(rename)`
|
||||
pub mode: Mode,
|
||||
pub status: Status,
|
||||
pub which: Which,
|
||||
pub confirm: Confirm,
|
||||
pub spot: Spot,
|
||||
pub notify: Notify,
|
||||
pub pick: Pick,
|
||||
pub input: Input,
|
||||
pub completion: Completion,
|
||||
pub tasks: Tasks,
|
||||
pub help: Help,
|
||||
pub mgr: Mgr, // TODO: Remove `serde(rename)`
|
||||
pub mode: Mode,
|
||||
pub status: Status,
|
||||
pub which: Which,
|
||||
pub confirm: Confirm,
|
||||
pub spot: Spot,
|
||||
pub notify: Notify,
|
||||
pub pick: Pick,
|
||||
pub input: Input,
|
||||
pub cmp: Cmp,
|
||||
pub tasks: Tasks,
|
||||
pub help: Help,
|
||||
|
||||
// File-specific styles
|
||||
#[serde(rename = "filetype", deserialize_with = "Filetype::deserialize", skip_serializing)]
|
||||
|
|
@ -178,7 +178,7 @@ pub struct Input {
|
|||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct Completion {
|
||||
pub struct Cmp {
|
||||
pub border: Style,
|
||||
pub active: Style,
|
||||
pub inactive: Style,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Completion {
|
||||
pub struct Cmp {
|
||||
pub(super) caches: HashMap<PathBuf, Vec<String>>,
|
||||
pub(super) cands: Vec<String>,
|
||||
pub(super) offset: usize,
|
||||
|
|
@ -11,7 +11,7 @@ pub struct Completion {
|
|||
pub visible: bool,
|
||||
}
|
||||
|
||||
impl Completion {
|
||||
impl Cmp {
|
||||
// --- Cands
|
||||
#[inline]
|
||||
pub fn window(&self) -> &[String] {
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
use yazi_macro::render;
|
||||
use yazi_shared::event::{CmdCow, Data};
|
||||
|
||||
use crate::completion::Completion;
|
||||
use crate::cmp::Cmp;
|
||||
|
||||
struct Opt {
|
||||
step: isize,
|
||||
|
|
@ -11,7 +11,7 @@ impl From<CmdCow> for Opt {
|
|||
fn from(c: CmdCow) -> Self { Self { step: c.first().and_then(Data::as_isize).unwrap_or(0) } }
|
||||
}
|
||||
|
||||
impl Completion {
|
||||
impl Cmp {
|
||||
#[yazi_codegen::command]
|
||||
pub fn arrow(&mut self, opt: Opt) {
|
||||
if opt.step > 0 {
|
||||
|
|
@ -2,7 +2,7 @@ use yazi_macro::render;
|
|||
use yazi_proxy::InputProxy;
|
||||
use yazi_shared::event::CmdCow;
|
||||
|
||||
use crate::completion::Completion;
|
||||
use crate::cmp::Cmp;
|
||||
|
||||
struct Opt {
|
||||
submit: bool,
|
||||
|
|
@ -15,7 +15,7 @@ impl From<bool> for Opt {
|
|||
fn from(submit: bool) -> Self { Self { submit } }
|
||||
}
|
||||
|
||||
impl Completion {
|
||||
impl Cmp {
|
||||
#[yazi_codegen::command]
|
||||
pub fn close(&mut self, opt: Opt) {
|
||||
if let Some(s) = self.selected().filter(|_| opt.submit) {
|
||||
|
|
@ -3,7 +3,7 @@ use std::{borrow::Cow, mem, ops::ControlFlow, path::PathBuf};
|
|||
use yazi_macro::render;
|
||||
use yazi_shared::event::{Cmd, CmdCow, Data};
|
||||
|
||||
use crate::completion::Completion;
|
||||
use crate::cmp::Cmp;
|
||||
|
||||
const LIMIT: usize = 30;
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ impl From<Cmd> for Opt {
|
|||
fn from(c: Cmd) -> Self { Self::from(CmdCow::from(c)) }
|
||||
}
|
||||
|
||||
impl Completion {
|
||||
impl Cmp {
|
||||
#[yazi_codegen::command]
|
||||
pub fn show(&mut self, opt: Opt) {
|
||||
if self.ticket != opt.ticket {
|
||||
|
|
@ -3,9 +3,9 @@ use std::{borrow::Cow, mem, path::{MAIN_SEPARATOR_STR, PathBuf}};
|
|||
use tokio::fs;
|
||||
use yazi_fs::{CWD, expand_path};
|
||||
use yazi_macro::{emit, render};
|
||||
use yazi_shared::{Layer, event::{Cmd, CmdCow, Data}};
|
||||
use yazi_shared::event::{Cmd, CmdCow, Data};
|
||||
|
||||
use crate::completion::Completion;
|
||||
use crate::cmp::Cmp;
|
||||
|
||||
struct Opt {
|
||||
word: Cow<'static, str>,
|
||||
|
|
@ -21,7 +21,7 @@ impl From<CmdCow> for Opt {
|
|||
}
|
||||
}
|
||||
|
||||
impl Completion {
|
||||
impl Cmp {
|
||||
#[yazi_codegen::command]
|
||||
pub fn trigger(&mut self, opt: Opt) {
|
||||
if opt.ticket < self.ticket {
|
||||
|
|
@ -55,12 +55,11 @@ impl Completion {
|
|||
|
||||
if !cache.is_empty() {
|
||||
emit!(Call(
|
||||
Cmd::new("show")
|
||||
Cmd::new("cmp:show")
|
||||
.with_any("cache", cache)
|
||||
.with_any("cache-name", parent)
|
||||
.with("word", word)
|
||||
.with("ticket", ticket),
|
||||
Layer::Completion
|
||||
.with("ticket", ticket)
|
||||
));
|
||||
}
|
||||
|
||||
|
|
@ -95,7 +94,7 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
fn compare(s: &str, parent: &str, child: &str) -> bool {
|
||||
let (p, c) = Completion::split_path(s).unwrap();
|
||||
let (p, c) = Cmp::split_path(s).unwrap();
|
||||
let p = p.strip_prefix(yazi_fs::CWD.load().as_ref()).unwrap_or(&p);
|
||||
p == Path::new(parent) && c == child
|
||||
}
|
||||
3
yazi-core/src/cmp/mod.rs
Normal file
3
yazi-core/src/cmp/mod.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
yazi_macro::mod_pub!(commands);
|
||||
|
||||
yazi_macro::mod_flat!(cmp);
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
yazi_macro::mod_pub!(commands);
|
||||
|
||||
yazi_macro::mod_flat!(completion);
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
use yazi_macro::render;
|
||||
use yazi_proxy::CompletionProxy;
|
||||
use yazi_proxy::CmpProxy;
|
||||
use yazi_shared::{errors::InputError, event::CmdCow};
|
||||
|
||||
use crate::input::Input;
|
||||
|
|
@ -19,7 +19,7 @@ impl Input {
|
|||
#[yazi_codegen::command]
|
||||
pub fn close(&mut self, opt: Opt) {
|
||||
if self.completion {
|
||||
CompletionProxy::close();
|
||||
CmpProxy::close();
|
||||
}
|
||||
|
||||
if let Some(cb) = self.callback.take() {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use yazi_macro::render;
|
||||
use yazi_proxy::CompletionProxy;
|
||||
use yazi_proxy::CmpProxy;
|
||||
use yazi_shared::event::CmdCow;
|
||||
|
||||
use crate::input::{Input, InputMode, op::InputOp};
|
||||
|
|
@ -29,7 +29,7 @@ impl Input {
|
|||
self.move_(-1);
|
||||
|
||||
if self.completion {
|
||||
CompletionProxy::close();
|
||||
CmpProxy::close();
|
||||
}
|
||||
}
|
||||
InputMode::Replace => {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
clippy::unit_arg
|
||||
)]
|
||||
|
||||
yazi_macro::mod_pub!(completion confirm help input mgr notify pick spot tab tasks which);
|
||||
yazi_macro::mod_pub!(cmp confirm help input mgr notify pick spot tab tasks which);
|
||||
|
||||
pub fn init() {
|
||||
mgr::WATCHED.with(<_>::default);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::time::Instant;
|
||||
|
||||
use yazi_macro::emit;
|
||||
use yazi_shared::{Layer, event::Cmd};
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
use crate::notify::{Message, Notify};
|
||||
|
||||
|
|
@ -14,7 +14,7 @@ impl Notify {
|
|||
|
||||
if self.messages.iter().all(|m| m != &msg) {
|
||||
self.messages.push(msg);
|
||||
emit!(Call(Cmd::args("update_notify", &[0]), Layer::App));
|
||||
emit!(Call(Cmd::args("app:update_notify", &[0])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::time::Duration;
|
|||
|
||||
use ratatui::layout::Rect;
|
||||
use yazi_macro::emit;
|
||||
use yazi_shared::{Layer, event::{Cmd, CmdCow, Data}};
|
||||
use yazi_shared::event::{Cmd, CmdCow, Data};
|
||||
|
||||
use crate::notify::Notify;
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ impl Notify {
|
|||
|
||||
self.tick_handle = Some(tokio::spawn(async move {
|
||||
tokio::time::sleep(interval).await;
|
||||
emit!(Call(Cmd::args("update_notify", &[interval.as_secs_f64()]), Layer::App));
|
||||
emit!(Call(Cmd::args("app:update_notify", &[interval.as_secs_f64()])));
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use yazi_config::popup::InputCfg;
|
|||
use yazi_dds::Pubsub;
|
||||
use yazi_fs::expand_path;
|
||||
use yazi_macro::render;
|
||||
use yazi_proxy::{CompletionProxy, InputProxy, MgrProxy, TabProxy};
|
||||
use yazi_proxy::{CmpProxy, InputProxy, MgrProxy, TabProxy};
|
||||
use yazi_shared::{Debounce, errors::InputError, event::CmdCow, url::Url};
|
||||
|
||||
use crate::tab::Tab;
|
||||
|
|
@ -98,7 +98,7 @@ impl Tab {
|
|||
}
|
||||
}
|
||||
Err(InputError::Completed(before, ticket)) => {
|
||||
CompletionProxy::trigger(&before, ticket);
|
||||
CmpProxy::trigger(&before, ticket);
|
||||
}
|
||||
_ => break,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use yazi_config::popup::InputCfg;
|
|||
use yazi_fs::FilterCase;
|
||||
use yazi_macro::emit;
|
||||
use yazi_proxy::InputProxy;
|
||||
use yazi_shared::{Debounce, Layer, errors::InputError, event::{Cmd, CmdCow}};
|
||||
use yazi_shared::{Debounce, errors::InputError, event::{Cmd, CmdCow}};
|
||||
|
||||
use crate::tab::Tab;
|
||||
|
||||
|
|
@ -41,11 +41,10 @@ impl Tab {
|
|||
let (Ok(s) | Err(InputError::Typed(s))) = result else { continue };
|
||||
|
||||
emit!(Call(
|
||||
Cmd::args("filter_do", &[s])
|
||||
Cmd::args("mgr:filter_do", &[s])
|
||||
.with_bool("smart", opt.case == FilterCase::Smart)
|
||||
.with_bool("insensitive", opt.case == FilterCase::Insensitive)
|
||||
.with_bool("done", done),
|
||||
Layer::Mgr
|
||||
.with_bool("done", done)
|
||||
));
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use yazi_config::popup::InputCfg;
|
|||
use yazi_fs::FilterCase;
|
||||
use yazi_macro::emit;
|
||||
use yazi_proxy::InputProxy;
|
||||
use yazi_shared::{Debounce, Layer, errors::InputError, event::{Cmd, CmdCow}};
|
||||
use yazi_shared::{Debounce, errors::InputError, event::{Cmd, CmdCow}};
|
||||
|
||||
use crate::tab::Tab;
|
||||
|
||||
|
|
@ -33,11 +33,10 @@ impl Tab {
|
|||
|
||||
while let Some(Ok(s)) | Some(Err(InputError::Typed(s))) = rx.next().await {
|
||||
emit!(Call(
|
||||
Cmd::args("find_do", &[s])
|
||||
Cmd::args("mgr:find_do", &[s])
|
||||
.with_bool("previous", opt.prev)
|
||||
.with_bool("smart", opt.case == FilterCase::Smart)
|
||||
.with_bool("insensitive", opt.case == FilterCase::Insensitive),
|
||||
Layer::Mgr
|
||||
.with_bool("insensitive", opt.case == FilterCase::Insensitive)
|
||||
));
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use tokio::{task::JoinHandle, time::sleep};
|
|||
use yazi_adapter::Dimension;
|
||||
use yazi_macro::emit;
|
||||
use yazi_scheduler::{Ongoing, Scheduler, TaskSummary};
|
||||
use yazi_shared::{Layer, event::Cmd};
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
use super::{TASKS_BORDER, TASKS_PADDING, TASKS_PERCENT, TasksProgress};
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ impl Tasks {
|
|||
let new = TasksProgress::from(&*ongoing.lock());
|
||||
if last != new {
|
||||
last = new;
|
||||
emit!(Call(Cmd::new("update_progress").with_any("progress", new), Layer::App));
|
||||
emit!(Call(Cmd::new("app:update_progress").with_any("progress", new)));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
use std::str::FromStr;
|
||||
|
||||
use yazi_config::{KEYMAP, keymap::{Chord, Key}};
|
||||
use yazi_macro::render;
|
||||
use yazi_shared::{Layer, event::CmdCow};
|
||||
|
|
@ -8,7 +6,6 @@ use crate::which::{Which, WhichSorter};
|
|||
|
||||
pub struct Opt {
|
||||
cands: Vec<Chord>,
|
||||
layer: Layer,
|
||||
silent: bool,
|
||||
}
|
||||
|
||||
|
|
@ -16,11 +13,7 @@ impl TryFrom<CmdCow> for Opt {
|
|||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
cands: c.take_any("candidates").unwrap_or_default(),
|
||||
layer: Layer::from_str(&c.take_str("layer").unwrap_or_default())?,
|
||||
silent: c.bool("silent"),
|
||||
})
|
||||
Ok(Self { cands: c.take_any("candidates").unwrap_or_default(), silent: c.bool("silent") })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -34,7 +27,6 @@ impl Which {
|
|||
return;
|
||||
}
|
||||
|
||||
self.layer = opt.layer;
|
||||
self.times = 0;
|
||||
self.cands = opt.cands.into_iter().map(|c| c.into()).collect();
|
||||
|
||||
|
|
@ -44,7 +36,6 @@ impl Which {
|
|||
}
|
||||
|
||||
pub fn show_with(&mut self, key: Key, layer: Layer) {
|
||||
self.layer = layer;
|
||||
self.times = 1;
|
||||
self.cands = KEYMAP
|
||||
.get(layer)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
use yazi_config::keymap::{ChordCow, Key};
|
||||
use yazi_macro::{emit, render_and};
|
||||
use yazi_shared::Layer;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Which {
|
||||
pub(super) layer: Layer,
|
||||
pub times: usize,
|
||||
pub cands: Vec<ChordCow>,
|
||||
pub times: usize,
|
||||
pub cands: Vec<ChordCow>,
|
||||
|
||||
// Visibility
|
||||
pub visible: bool,
|
||||
|
|
@ -21,10 +19,10 @@ impl Which {
|
|||
if self.cands.is_empty() {
|
||||
self.reset();
|
||||
} else if self.cands.len() == 1 {
|
||||
emit!(Seq(self.cands.remove(0).into_seq(), self.layer));
|
||||
emit!(Seq(self.cands.remove(0).into_seq()));
|
||||
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));
|
||||
emit!(Seq(self.cands.remove(i).into_seq()));
|
||||
self.reset();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::{fmt::Display, io::Write, str::FromStr};
|
|||
use anyhow::{Result, anyhow};
|
||||
use yazi_boot::BOOT;
|
||||
use yazi_macro::emit;
|
||||
use yazi_shared::{Layer, event::Cmd};
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
use crate::{ID, body::Body};
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ impl<'a> Payload<'a> {
|
|||
impl Payload<'static> {
|
||||
pub(super) fn emit(self) {
|
||||
self.try_flush();
|
||||
emit!(Call(Cmd::new("accept_payload").with_any("payload", self), Layer::App));
|
||||
emit!(Call(Cmd::new("app:accept_payload").with_any("payload", self)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use crossterm::event::KeyEvent;
|
|||
use yazi_config::keymap::Key;
|
||||
use yazi_core::input::InputMode;
|
||||
use yazi_macro::emit;
|
||||
use yazi_shared::{Layer, event::{CmdCow, Event, NEED_RENDER}};
|
||||
use yazi_shared::event::{CmdCow, Event, NEED_RENDER};
|
||||
|
||||
use crate::{Ctx, Executor, Router, Signals, Term, lives::Lives};
|
||||
|
||||
|
|
@ -53,8 +53,8 @@ impl App {
|
|||
#[inline]
|
||||
fn dispatch(&mut self, event: Event) -> Result<()> {
|
||||
match event {
|
||||
Event::Call(cmd, layer) => self.dispatch_call(cmd, layer),
|
||||
Event::Seq(cmds, layer) => self.dispatch_seq(cmds, layer),
|
||||
Event::Call(cmd) => self.dispatch_call(cmd),
|
||||
Event::Seq(cmds) => self.dispatch_seq(cmds),
|
||||
Event::Render => self.dispatch_render(),
|
||||
Event::Key(key) => self.dispatch_key(key),
|
||||
Event::Mouse(mouse) => self.mouse(mouse),
|
||||
|
|
@ -66,17 +66,15 @@ impl App {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn dispatch_call(&mut self, cmd: CmdCow, layer: Layer) {
|
||||
Executor::new(self).execute(cmd, layer);
|
||||
}
|
||||
fn dispatch_call(&mut self, cmd: CmdCow) { Executor::new(self).execute(cmd); }
|
||||
|
||||
#[inline]
|
||||
fn dispatch_seq(&mut self, mut cmds: Vec<CmdCow>, layer: Layer) {
|
||||
fn dispatch_seq(&mut self, mut cmds: Vec<CmdCow>) {
|
||||
if let Some(last) = cmds.pop() {
|
||||
Executor::new(self).execute(last, layer);
|
||||
Executor::new(self).execute(last);
|
||||
}
|
||||
if !cmds.is_empty() {
|
||||
emit!(Seq(cmds, layer));
|
||||
emit!(Seq(cmds));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,34 +6,31 @@ use yazi_config::{THEME, popup::{Offset, Position}};
|
|||
|
||||
use crate::Ctx;
|
||||
|
||||
pub(crate) struct Completion<'a> {
|
||||
pub(crate) struct Cmp<'a> {
|
||||
cx: &'a Ctx,
|
||||
}
|
||||
|
||||
impl<'a> Completion<'a> {
|
||||
impl<'a> Cmp<'a> {
|
||||
pub(crate) fn new(cx: &'a Ctx) -> Self { Self { cx } }
|
||||
}
|
||||
|
||||
impl Widget for Completion<'_> {
|
||||
impl Widget for Cmp<'_> {
|
||||
fn render(self, rect: Rect, buf: &mut Buffer) {
|
||||
let items: Vec<_> = self
|
||||
.cx
|
||||
.completion
|
||||
.cmp
|
||||
.window()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, x)| {
|
||||
let icon = if x.ends_with(MAIN_SEPARATOR) {
|
||||
&THEME.completion.icon_folder
|
||||
} else {
|
||||
&THEME.completion.icon_file
|
||||
};
|
||||
let icon =
|
||||
if x.ends_with(MAIN_SEPARATOR) { &THEME.cmp.icon_folder } else { &THEME.cmp.icon_file };
|
||||
|
||||
let mut item = ListItem::new(format!(" {icon} {x}"));
|
||||
if i == self.cx.completion.rel_cursor() {
|
||||
item = item.style(THEME.completion.active);
|
||||
if i == self.cx.cmp.rel_cursor() {
|
||||
item = item.style(THEME.cmp.active);
|
||||
} else {
|
||||
item = item.style(THEME.completion.inactive);
|
||||
item = item.style(THEME.cmp.inactive);
|
||||
}
|
||||
|
||||
item
|
||||
|
|
@ -57,9 +54,7 @@ impl Widget for Completion<'_> {
|
|||
|
||||
yazi_plugin::elements::Clear::default().render(area, buf);
|
||||
List::new(items)
|
||||
.block(
|
||||
Block::bordered().border_type(BorderType::Rounded).border_style(THEME.completion.border),
|
||||
)
|
||||
.block(Block::bordered().border_type(BorderType::Rounded).border_style(THEME.cmp.border))
|
||||
.render(area, buf);
|
||||
}
|
||||
}
|
||||
1
yazi-fm/src/cmp/mod.rs
Normal file
1
yazi-fm/src/cmp/mod.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
yazi_macro::mod_flat!(cmp);
|
||||
|
|
@ -1 +0,0 @@
|
|||
yazi_macro::mod_flat!(completion);
|
||||
|
|
@ -1,31 +1,31 @@
|
|||
use ratatui::layout::Rect;
|
||||
use yazi_core::{completion::Completion, confirm::Confirm, help::Help, input::Input, mgr::Mgr, notify::Notify, pick::Pick, tab::{Folder, Tab}, tasks::Tasks, which::Which};
|
||||
use yazi_core::{cmp::Cmp, confirm::Confirm, help::Help, input::Input, mgr::Mgr, notify::Notify, pick::Pick, tab::{Folder, Tab}, tasks::Tasks, which::Which};
|
||||
use yazi_shared::Layer;
|
||||
|
||||
pub struct Ctx {
|
||||
pub mgr: Mgr,
|
||||
pub tasks: Tasks,
|
||||
pub pick: Pick,
|
||||
pub input: Input,
|
||||
pub confirm: Confirm,
|
||||
pub help: Help,
|
||||
pub completion: Completion,
|
||||
pub which: Which,
|
||||
pub notify: Notify,
|
||||
pub mgr: Mgr,
|
||||
pub tasks: Tasks,
|
||||
pub pick: Pick,
|
||||
pub input: Input,
|
||||
pub confirm: Confirm,
|
||||
pub help: Help,
|
||||
pub cmp: Cmp,
|
||||
pub which: Which,
|
||||
pub notify: Notify,
|
||||
}
|
||||
|
||||
impl Ctx {
|
||||
pub fn make() -> Self {
|
||||
Self {
|
||||
mgr: Mgr::make(),
|
||||
tasks: Tasks::serve(),
|
||||
pick: Default::default(),
|
||||
input: Default::default(),
|
||||
confirm: Default::default(),
|
||||
help: Default::default(),
|
||||
completion: Default::default(),
|
||||
which: Default::default(),
|
||||
notify: Default::default(),
|
||||
mgr: Mgr::make(),
|
||||
tasks: Tasks::serve(),
|
||||
pick: Default::default(),
|
||||
input: Default::default(),
|
||||
confirm: Default::default(),
|
||||
help: Default::default(),
|
||||
cmp: Default::default(),
|
||||
which: Default::default(),
|
||||
notify: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -45,8 +45,8 @@ impl Ctx {
|
|||
pub fn layer(&self) -> Layer {
|
||||
if self.which.visible {
|
||||
Layer::Which
|
||||
} else if self.completion.visible {
|
||||
Layer::Completion
|
||||
} else if self.cmp.visible {
|
||||
Layer::Cmp
|
||||
} else if self.help.visible {
|
||||
Layer::Help
|
||||
} else if self.confirm.visible {
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ impl<'a> Executor<'a> {
|
|||
pub(super) fn new(app: &'a mut App) -> Self { Self { app } }
|
||||
|
||||
#[inline]
|
||||
pub(super) fn execute(&mut self, cmd: CmdCow, layer: Layer) {
|
||||
match layer {
|
||||
pub(super) fn execute(&mut self, cmd: CmdCow) {
|
||||
match cmd.layer {
|
||||
Layer::App => self.app(cmd),
|
||||
Layer::Mgr => self.mgr(cmd),
|
||||
Layer::Tasks => self.tasks(cmd),
|
||||
|
|
@ -22,7 +22,7 @@ impl<'a> Executor<'a> {
|
|||
Layer::Input => self.input(cmd),
|
||||
Layer::Confirm => self.confirm(cmd),
|
||||
Layer::Help => self.help(cmd),
|
||||
Layer::Completion => self.completion(cmd),
|
||||
Layer::Cmp => self.cmp(cmd),
|
||||
Layer::Which => self.which(cmd),
|
||||
}
|
||||
}
|
||||
|
|
@ -249,7 +249,7 @@ impl<'a> Executor<'a> {
|
|||
|
||||
if cmd.name.as_str() == "complete" {
|
||||
return if cmd.bool("trigger") {
|
||||
self.app.cx.completion.trigger(cmd)
|
||||
self.app.cx.cmp.trigger(cmd)
|
||||
} else {
|
||||
self.app.cx.input.complete(cmd)
|
||||
};
|
||||
|
|
@ -319,11 +319,11 @@ impl<'a> Executor<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn completion(&mut self, cmd: CmdCow) {
|
||||
fn cmp(&mut self, cmd: CmdCow) {
|
||||
macro_rules! on {
|
||||
($name:ident) => {
|
||||
if cmd.name == stringify!($name) {
|
||||
return self.app.cx.completion.$name(cmd);
|
||||
return self.app.cx.cmp.$name(cmd);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -336,7 +336,7 @@ impl<'a> Executor<'a> {
|
|||
match cmd.name.as_str() {
|
||||
"close_input" => self.app.cx.input.close(cmd),
|
||||
// Help
|
||||
"help" => self.app.cx.help.toggle(Layer::Completion),
|
||||
"help" => self.app.cx.help.toggle(Layer::Cmp),
|
||||
// Plugin
|
||||
"plugin" => self.app.plugin(cmd),
|
||||
_ => {}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
#[global_allocator]
|
||||
static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
|
||||
|
||||
yazi_macro::mod_pub!(app completion confirm help input lives mgr notify pick spot tasks which);
|
||||
yazi_macro::mod_pub!(app cmp confirm help input lives mgr notify pick spot tasks which);
|
||||
|
||||
yazi_macro::mod_flat!(context executor logs panic root router signals term);
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use ratatui::{buffer::Buffer, layout::Rect, widgets::Widget};
|
|||
use tracing::error;
|
||||
use yazi_plugin::{LUA, elements::render_once};
|
||||
|
||||
use super::{completion, confirm, help, input, mgr, pick, spot, tasks, which};
|
||||
use super::{cmp, confirm, help, input, mgr, pick, spot, tasks, which};
|
||||
use crate::Ctx;
|
||||
|
||||
pub(super) struct Root<'a> {
|
||||
|
|
@ -60,8 +60,8 @@ impl Widget for Root<'_> {
|
|||
help::Help::new(self.cx).render(area, buf);
|
||||
}
|
||||
|
||||
if self.cx.completion.visible {
|
||||
completion::Completion::new(self.cx).render(area, buf);
|
||||
if self.cx.cmp.visible {
|
||||
cmp::Cmp::new(self.cx).render(area, buf);
|
||||
}
|
||||
|
||||
if self.cx.which.visible {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ impl<'a> Router<'a> {
|
|||
L::Mgr | L::Tasks | L::Spot | L::Pick | L::Input | L::Confirm | L::Help => {
|
||||
self.matches(layer, key)
|
||||
}
|
||||
L::Completion => self.matches(L::Completion, key) || self.matches(L::Input, key),
|
||||
L::Cmp => self.matches(L::Cmp, key) || self.matches(L::Input, key),
|
||||
L::Which => cx.which.type_(key),
|
||||
}
|
||||
}
|
||||
|
|
@ -45,7 +45,7 @@ impl<'a> Router<'a> {
|
|||
if on.len() > 1 {
|
||||
self.app.cx.which.show_with(key, layer);
|
||||
} else {
|
||||
emit!(Seq(ChordCow::from(chord).into_seq(), layer));
|
||||
emit!(Seq(ChordCow::from(chord).into_seq()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use yazi_shared::{Id, Ids, Layer, event::Cmd, url::{Url, UrnBuf}};
|
||||
use yazi_shared::{Id, Ids, event::Cmd, url::{Url, UrnBuf}};
|
||||
|
||||
use super::{Cha, File};
|
||||
|
||||
|
|
@ -39,11 +39,8 @@ impl FilesOp {
|
|||
|
||||
#[inline]
|
||||
pub fn emit(self) {
|
||||
yazi_shared::event::Event::Call(
|
||||
Cmd::new("update_files").with_any("op", self).into(),
|
||||
Layer::Mgr,
|
||||
)
|
||||
.emit();
|
||||
yazi_shared::event::Event::Call(Cmd::new("mgr:update_files").with_any("op", self).into())
|
||||
.emit();
|
||||
}
|
||||
|
||||
pub fn prepare(cwd: &Url) -> Id {
|
||||
|
|
|
|||
|
|
@ -3,11 +3,11 @@ macro_rules! emit {
|
|||
(Quit($opt:expr)) => {
|
||||
yazi_shared::event::Event::Quit($opt).emit();
|
||||
};
|
||||
(Call($cmd:expr, $layer:expr)) => {
|
||||
yazi_shared::event::Event::Call(yazi_shared::event::CmdCow::from($cmd), $layer).emit();
|
||||
(Call($cmd:expr)) => {
|
||||
yazi_shared::event::Event::Call(yazi_shared::event::CmdCow::from($cmd)).emit();
|
||||
};
|
||||
(Seq($cmds:expr, $layer:expr)) => {
|
||||
yazi_shared::event::Event::Seq($cmds, $layer).emit();
|
||||
(Seq($cmds:expr)) => {
|
||||
yazi_shared::event::Event::Seq($cmds).emit();
|
||||
};
|
||||
($event:ident) => {
|
||||
yazi_shared::event::Event::$event.emit();
|
||||
|
|
|
|||
|
|
@ -40,21 +40,21 @@ impl Utils {
|
|||
|
||||
pub(super) fn app_emit(lua: &Lua) -> mlua::Result<Function> {
|
||||
lua.create_function(|_, (name, args): (String, Table)| {
|
||||
emit!(Call(Cmd { name, args: Sendable::table_to_args(args)? }, Layer::App));
|
||||
emit!(Call(Cmd { name, args: Sendable::table_to_args(args)?, layer: Layer::App }));
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn mgr_emit(lua: &Lua) -> mlua::Result<Function> {
|
||||
lua.create_function(|_, (name, args): (String, Table)| {
|
||||
emit!(Call(Cmd { name, args: Sendable::table_to_args(args)? }, Layer::Mgr));
|
||||
emit!(Call(Cmd { name, args: Sendable::table_to_args(args)?, layer: Layer::Mgr }));
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn input_emit(lua: &Lua) -> mlua::Result<Function> {
|
||||
lua.create_function(|_, (name, args): (String, Table)| {
|
||||
emit!(Call(Cmd { name, args: Sendable::table_to_args(args)? }, Layer::Input));
|
||||
emit!(Call(Cmd { name, args: Sendable::table_to_args(args)?, layer: Layer::Input }));
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use tokio_stream::wrappers::UnboundedReceiverStream;
|
|||
use yazi_config::{keymap::{Chord, Key}, popup::{ConfirmCfg, InputCfg}};
|
||||
use yazi_macro::emit;
|
||||
use yazi_proxy::{AppProxy, ConfirmProxy, InputProxy};
|
||||
use yazi_shared::{Debounce, Layer, event::Cmd};
|
||||
use yazi_shared::{Debounce, event::Cmd};
|
||||
|
||||
use super::Utils;
|
||||
use crate::{bindings::InputRx, elements::{Line, Pos, Text}};
|
||||
|
|
@ -21,18 +21,16 @@ impl Utils {
|
|||
let cand = cand?;
|
||||
cands.push(Chord {
|
||||
on: Self::parse_keys(cand.raw_get("on")?)?,
|
||||
run: vec![Cmd::args("callback", &[i]).with_any("tx", tx.clone())],
|
||||
run: vec![Cmd::args("which:callback", &[i]).with_any("tx", tx.clone())],
|
||||
desc: cand.raw_get("desc").ok(),
|
||||
});
|
||||
}
|
||||
|
||||
drop(tx);
|
||||
emit!(Call(
|
||||
Cmd::new("show")
|
||||
.with("layer", Layer::Which)
|
||||
Cmd::new("which:show")
|
||||
.with_any("candidates", cands)
|
||||
.with_bool("silent", t.raw_get("silent").unwrap_or_default()),
|
||||
Layer::Which
|
||||
.with_bool("silent", t.raw_get("silent").unwrap_or_default())
|
||||
));
|
||||
|
||||
Ok(rx.recv().await.map(|idx| idx + 1))
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use mlua::{AnyUserData, Function, IntoLuaMulti, Lua, Table, Value};
|
||||
use yazi_config::{PREVIEW, preview::PreviewWrap};
|
||||
use yazi_macro::emit;
|
||||
use yazi_shared::{Layer, errors::PeekError, event::Cmd};
|
||||
use yazi_shared::{errors::PeekError, event::Cmd};
|
||||
|
||||
use super::Utils;
|
||||
use crate::{elements::{Area, Rect, Renderable, Text, WRAP, WRAP_NO}, external::Highlighter, file::FileRef};
|
||||
|
|
@ -54,7 +54,7 @@ impl Utils {
|
|||
wrap: if PREVIEW.wrap == PreviewWrap::Yes { WRAP } else { WRAP_NO },
|
||||
})];
|
||||
|
||||
emit!(Call(Cmd::new("update_peeked").with_any("lock", lock), Layer::Mgr));
|
||||
emit!(Call(Cmd::new("mgr:update_peeked").with_any("lock", lock)));
|
||||
(Value::Nil, Value::Nil).into_lua_multi(&lua)
|
||||
})
|
||||
}
|
||||
|
|
@ -64,7 +64,7 @@ impl Utils {
|
|||
let mut lock = PreviewLock::try_from(t)?;
|
||||
lock.data = widgets.into_iter().map(Renderable::try_from).collect::<mlua::Result<_>>()?;
|
||||
|
||||
emit!(Call(Cmd::new("update_peeked").with_any("lock", lock), Layer::Mgr));
|
||||
emit!(Call(Cmd::new("mgr:update_peeked").with_any("lock", lock)));
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use mlua::{AnyUserData, Function, Lua, Table};
|
||||
use yazi_config::THEME;
|
||||
use yazi_macro::emit;
|
||||
use yazi_shared::{Layer, event::Cmd};
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
use super::Utils;
|
||||
use crate::{elements::Renderable, file::FileRef};
|
||||
|
|
@ -80,7 +80,7 @@ impl Utils {
|
|||
}),
|
||||
Renderable::Table(table),
|
||||
];
|
||||
emit!(Call(Cmd::new("update_spotted").with_any("lock", lock), Layer::Mgr));
|
||||
emit!(Call(Cmd::new("mgr:update_spotted").with_any("lock", lock)));
|
||||
|
||||
Ok(())
|
||||
})
|
||||
|
|
@ -91,7 +91,7 @@ impl Utils {
|
|||
let mut lock = SpotLock::try_from(t)?;
|
||||
lock.data = widgets.into_iter().map(Renderable::try_from).collect::<mlua::Result<_>>()?;
|
||||
|
||||
emit!(Call(Cmd::new("update_spotted").with_any("lock", lock), Layer::Mgr));
|
||||
emit!(Call(Cmd::new("mgr:update_spotted").with_any("lock", lock)));
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::time::Duration;
|
|||
|
||||
use tokio::sync::oneshot;
|
||||
use yazi_macro::emit;
|
||||
use yazi_shared::{Layer, event::Cmd};
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
use crate::options::{NotifyLevel, NotifyOpt, PluginOpt};
|
||||
|
||||
|
|
@ -12,18 +12,18 @@ impl AppProxy {
|
|||
#[inline]
|
||||
pub async fn stop() {
|
||||
let (tx, rx) = oneshot::channel::<()>();
|
||||
emit!(Call(Cmd::new("stop").with_any("tx", tx), Layer::App));
|
||||
emit!(Call(Cmd::new("app:stop").with_any("tx", tx)));
|
||||
rx.await.ok();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn resume() {
|
||||
emit!(Call(Cmd::new("resume"), Layer::App));
|
||||
emit!(Call(Cmd::new("app:resume")));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn notify(opt: NotifyOpt) {
|
||||
emit!(Call(Cmd::new("notify").with_any("option", opt), Layer::App));
|
||||
emit!(Call(Cmd::new("app:notify").with_any("option", opt)));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -48,11 +48,11 @@ impl AppProxy {
|
|||
|
||||
#[inline]
|
||||
pub fn plugin(opt: PluginOpt) {
|
||||
emit!(Call(Cmd::new("plugin").with_any("opt", opt), Layer::App));
|
||||
emit!(Call(Cmd::new("app:plugin").with_any("opt", opt)));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn plugin_do(opt: PluginOpt) {
|
||||
emit!(Call(Cmd::new("plugin_do").with_any("opt", opt), Layer::App));
|
||||
emit!(Call(Cmd::new("app:plugin_do").with_any("opt", opt)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
16
yazi-proxy/src/cmp.rs
Normal file
16
yazi-proxy/src/cmp.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
use yazi_macro::emit;
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
pub struct CmpProxy;
|
||||
|
||||
impl CmpProxy {
|
||||
#[inline]
|
||||
pub fn close() {
|
||||
emit!(Call(Cmd::new("cmp:close")));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn trigger(word: &str, ticket: usize) {
|
||||
emit!(Call(Cmd::args("cmp:trigger", &[word]).with("ticket", ticket)));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
use yazi_macro::emit;
|
||||
use yazi_shared::{Layer, event::Cmd};
|
||||
|
||||
pub struct CompletionProxy;
|
||||
|
||||
impl CompletionProxy {
|
||||
#[inline]
|
||||
pub fn close() {
|
||||
emit!(Call(Cmd::new("close"), Layer::Completion));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn trigger(word: &str, ticket: usize) {
|
||||
emit!(Call(Cmd::args("trigger", &[word]).with("ticket", ticket), Layer::Completion));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
use tokio::sync::oneshot;
|
||||
use yazi_config::popup::ConfirmCfg;
|
||||
use yazi_macro::emit;
|
||||
use yazi_shared::{Layer, event::Cmd};
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
pub struct ConfirmProxy;
|
||||
|
||||
|
|
@ -12,7 +12,7 @@ impl ConfirmProxy {
|
|||
#[inline]
|
||||
pub fn show_rx(cfg: ConfirmCfg) -> oneshot::Receiver<bool> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
emit!(Call(Cmd::new("show").with_any("tx", tx).with_any("cfg", cfg), Layer::Confirm));
|
||||
emit!(Call(Cmd::new("confirm:show").with_any("tx", tx).with_any("cfg", cfg)));
|
||||
rx
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use tokio::sync::mpsc;
|
||||
use yazi_config::popup::InputCfg;
|
||||
use yazi_macro::emit;
|
||||
use yazi_shared::{Layer, errors::InputError, event::Cmd};
|
||||
use yazi_shared::{errors::InputError, event::Cmd};
|
||||
|
||||
pub struct InputProxy;
|
||||
|
||||
|
|
@ -9,12 +9,12 @@ impl InputProxy {
|
|||
#[inline]
|
||||
pub fn show(cfg: InputCfg) -> mpsc::UnboundedReceiver<Result<String, InputError>> {
|
||||
let (tx, rx) = mpsc::unbounded_channel();
|
||||
emit!(Call(Cmd::new("show").with_any("tx", tx).with_any("cfg", cfg), Layer::Input));
|
||||
emit!(Call(Cmd::new("input:show").with_any("tx", tx).with_any("cfg", cfg)));
|
||||
rx
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn complete(word: &str, ticket: usize) {
|
||||
emit!(Call(Cmd::args("complete", &[word]).with("ticket", ticket), Layer::Input));
|
||||
emit!(Call(Cmd::args("input:complete", &[word]).with("ticket", ticket)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@ mod macros;
|
|||
|
||||
yazi_macro::mod_pub!(options);
|
||||
|
||||
yazi_macro::mod_flat!(app completion confirm input mgr pick semaphore tab tasks);
|
||||
yazi_macro::mod_flat!(app cmp confirm input mgr pick semaphore tab tasks);
|
||||
|
||||
pub fn init() { crate::init_semaphore(); }
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use yazi_macro::emit;
|
||||
use yazi_shared::{Id, Layer, event::Cmd, url::Url};
|
||||
use yazi_shared::{Id, event::Cmd, url::Url};
|
||||
|
||||
use crate::options::OpenDoOpt;
|
||||
|
||||
|
|
@ -8,55 +8,48 @@ pub struct MgrProxy;
|
|||
impl MgrProxy {
|
||||
#[inline]
|
||||
pub fn spot(skip: Option<usize>) {
|
||||
emit!(Call(Cmd::new("spot").with_opt("skip", skip), Layer::Mgr));
|
||||
emit!(Call(Cmd::new("mgr:spot").with_opt("skip", skip)));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn peek(force: bool) {
|
||||
emit!(Call(Cmd::new("peek").with_bool("force", force), Layer::Mgr));
|
||||
emit!(Call(Cmd::new("mgr:peek").with_bool("force", force)));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn hover(url: Option<Url>, tab: Id) {
|
||||
emit!(Call(
|
||||
Cmd::args("hover", &url.map_or_else(Vec::new, |u| vec![u])).with("tab", tab),
|
||||
Layer::Mgr
|
||||
));
|
||||
emit!(Call(Cmd::args("mgr:hover", &url.map_or_else(Vec::new, |u| vec![u])).with("tab", tab)));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn refresh() {
|
||||
emit!(Call(Cmd::new("refresh"), Layer::Mgr));
|
||||
emit!(Call(Cmd::new("mgr:refresh")));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn open_do(opt: OpenDoOpt) {
|
||||
emit!(Call(Cmd::new("open_do").with_any("option", opt), Layer::Mgr));
|
||||
emit!(Call(Cmd::new("mgr:open_do").with_any("option", opt)));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn remove_do(targets: Vec<Url>, permanently: bool) {
|
||||
emit!(Call(
|
||||
Cmd::new("remove_do").with_bool("permanently", permanently).with_any("targets", targets),
|
||||
Layer::Mgr
|
||||
Cmd::new("mgr:remove_do").with_bool("permanently", permanently).with_any("targets", targets)
|
||||
));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn update_tasks(url: &Url) {
|
||||
emit!(Call(Cmd::new("update_tasks").with_any("urls", vec![url.clone()]), Layer::Mgr));
|
||||
emit!(Call(Cmd::new("mgr:update_tasks").with_any("urls", vec![url.clone()])));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn update_paged() {
|
||||
emit!(Call(Cmd::new("update_paged"), Layer::Mgr));
|
||||
emit!(Call(Cmd::new("mgr:update_paged")));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn update_paged_by(page: usize, only_if: &Url) {
|
||||
emit!(Call(
|
||||
Cmd::args("update_paged", &[page]).with_any("only-if", only_if.clone()),
|
||||
Layer::Mgr
|
||||
));
|
||||
emit!(Call(Cmd::args("mgr:update_paged", &[page]).with_any("only-if", only_if.clone())));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use tokio::sync::oneshot;
|
||||
use yazi_config::popup::PickCfg;
|
||||
use yazi_macro::emit;
|
||||
use yazi_shared::{Layer, event::Cmd};
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
pub struct PickProxy;
|
||||
|
||||
|
|
@ -9,7 +9,7 @@ impl PickProxy {
|
|||
#[inline]
|
||||
pub async fn show(cfg: PickCfg) -> anyhow::Result<usize> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
emit!(Call(Cmd::new("show").with_any("tx", tx).with_any("cfg", cfg), Layer::Pick));
|
||||
emit!(Call(Cmd::new("pick:show").with_any("tx", tx).with_any("cfg", cfg)));
|
||||
rx.await?
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use yazi_macro::emit;
|
||||
use yazi_shared::{Layer, event::Cmd, url::Url};
|
||||
use yazi_shared::{event::Cmd, url::Url};
|
||||
|
||||
use crate::options::SearchOpt;
|
||||
|
||||
|
|
@ -8,25 +8,24 @@ pub struct TabProxy;
|
|||
impl TabProxy {
|
||||
#[inline]
|
||||
pub fn cd(target: &Url) {
|
||||
emit!(Call(Cmd::args("cd", &[target]), Layer::Mgr));
|
||||
emit!(Call(Cmd::args("mgr:cd", &[target])));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn reveal(target: &Url) {
|
||||
emit!(Call(Cmd::args("reveal", &[target]), Layer::Mgr));
|
||||
emit!(Call(Cmd::args("mgr:reveal", &[target])));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn arrow(step: isize) {
|
||||
emit!(Call(Cmd::args("arrow", &[step]), Layer::Mgr));
|
||||
emit!(Call(Cmd::args("mgr:arrow", &[step])));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn search_do(opt: SearchOpt) {
|
||||
emit!(Call(
|
||||
// TODO: use second positional argument instead of `args` parameter
|
||||
Cmd::args("search_do", &[opt.subject]).with("via", opt.via).with("args", opt.args_raw),
|
||||
Layer::Mgr
|
||||
Cmd::args("mgr:search_do", &[opt.subject]).with("via", opt.via).with("args", opt.args_raw)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::{borrow::Cow, ffi::OsString};
|
|||
use tokio::sync::oneshot;
|
||||
use yazi_config::open::Opener;
|
||||
use yazi_macro::emit;
|
||||
use yazi_shared::{Layer, event::Cmd, url::Url};
|
||||
use yazi_shared::{event::Cmd, url::Url};
|
||||
|
||||
use crate::options::{OpenWithOpt, ProcessExecOpt};
|
||||
|
||||
|
|
@ -12,24 +12,22 @@ pub struct TasksProxy;
|
|||
impl TasksProxy {
|
||||
#[inline]
|
||||
pub fn open_with(opener: Cow<'static, Opener>, cwd: Url, targets: Vec<Url>) {
|
||||
emit!(Call(
|
||||
Cmd::new("open_with").with_any("option", OpenWithOpt { opener, cwd, targets }),
|
||||
Layer::Tasks
|
||||
));
|
||||
emit!(Call(Cmd::new("tasks:open_with").with_any("option", OpenWithOpt {
|
||||
opener,
|
||||
cwd,
|
||||
targets
|
||||
})));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub async fn process_exec(opener: Cow<'static, Opener>, cwd: Url, args: Vec<OsString>) {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
emit!(Call(
|
||||
Cmd::new("process_exec").with_any("option", ProcessExecOpt {
|
||||
cwd,
|
||||
opener,
|
||||
args,
|
||||
done: Some(tx)
|
||||
}),
|
||||
Layer::Tasks
|
||||
));
|
||||
emit!(Call(Cmd::new("tasks:process_exec").with_any("option", ProcessExecOpt {
|
||||
cwd,
|
||||
opener,
|
||||
args,
|
||||
done: Some(tx)
|
||||
})));
|
||||
rx.await.ok();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +1,36 @@
|
|||
use std::{any::Any, borrow::Cow, collections::HashMap, fmt::{self, Display}, mem, str::FromStr};
|
||||
use std::{any::Any, borrow::Cow, collections::HashMap, fmt::{self, Display}, str::FromStr};
|
||||
|
||||
use anyhow::{Result, bail};
|
||||
use serde::{Deserialize, de};
|
||||
|
||||
use super::{Data, DataKey};
|
||||
use crate::url::Url;
|
||||
use crate::{Layer, url::Url};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Cmd {
|
||||
pub name: String,
|
||||
pub args: HashMap<DataKey, Data>,
|
||||
pub name: String,
|
||||
pub args: HashMap<DataKey, Data>,
|
||||
pub layer: Layer,
|
||||
}
|
||||
|
||||
impl Cmd {
|
||||
#[inline]
|
||||
pub fn new(name: &str) -> Self { Self { name: name.to_owned(), ..Default::default() } }
|
||||
pub fn new(s: &str) -> Self {
|
||||
let (layer, name) = match s.split_once(':') {
|
||||
Some((l, n)) => (Layer::from_str(l).unwrap_or_default(), n),
|
||||
None => (Layer::default(), s),
|
||||
};
|
||||
|
||||
Self { name: name.to_owned(), args: Default::default(), layer }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn args(name: &str, args: &[impl ToString]) -> Self {
|
||||
Self {
|
||||
name: name.to_owned(),
|
||||
args: args
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, s)| (DataKey::Integer(i as i64), Data::String(s.to_string())))
|
||||
.collect(),
|
||||
}
|
||||
let mut me = Self::new(name);
|
||||
me.args = args
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, s)| (DataKey::Integer(i as i64), Data::String(s.to_string())))
|
||||
.collect();
|
||||
me
|
||||
}
|
||||
|
||||
// --- With
|
||||
|
|
@ -170,15 +175,14 @@ impl FromStr for Cmd {
|
|||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut args = crate::shell::split_unix(s)?;
|
||||
let args = crate::shell::split_unix(s)?;
|
||||
if args.is_empty() || args[0].is_empty() {
|
||||
bail!("command name cannot be empty");
|
||||
}
|
||||
|
||||
Ok(Cmd {
|
||||
name: mem::take(&mut args[0]),
|
||||
args: Cmd::parse_args(args.into_iter().skip(1), true)?,
|
||||
})
|
||||
let mut me = Self::new(&args[0]);
|
||||
me.args = Cmd::parse_args(args.into_iter().skip(1), true)?;
|
||||
Ok(me)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,15 +4,15 @@ use crossterm::event::{KeyEvent, MouseEvent};
|
|||
use tokio::sync::mpsc;
|
||||
|
||||
use super::CmdCow;
|
||||
use crate::{Layer, RoCell};
|
||||
use crate::RoCell;
|
||||
|
||||
static TX: RoCell<mpsc::UnboundedSender<Event>> = RoCell::new();
|
||||
static RX: RoCell<mpsc::UnboundedReceiver<Event>> = RoCell::new();
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Event {
|
||||
Call(CmdCow, Layer),
|
||||
Seq(Vec<CmdCow>, Layer),
|
||||
Call(CmdCow),
|
||||
Seq(Vec<CmdCow>),
|
||||
Render,
|
||||
Key(KeyEvent),
|
||||
Mouse(MouseEvent),
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ pub enum Layer {
|
|||
Input,
|
||||
Confirm,
|
||||
Help,
|
||||
Completion,
|
||||
Cmp,
|
||||
Which,
|
||||
}
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ impl Display for Layer {
|
|||
Self::Input => "input",
|
||||
Self::Confirm => "confirm",
|
||||
Self::Help => "help",
|
||||
Self::Completion => "completion",
|
||||
Self::Cmp => "cmp",
|
||||
Self::Which => "which",
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue