mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
fix: filter out the which candidates that overlap with longer key chords (#1562)
This commit is contained in:
parent
cd7209c040
commit
caacd15110
19 changed files with 120 additions and 114 deletions
5
Cargo.lock
generated
5
Cargo.lock
generated
|
|
@ -406,9 +406,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_complete"
|
||||
version = "4.5.23"
|
||||
version = "4.5.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "531d7959c5bbb6e266cecdd0f20213639c3a5c3e4d615f97db87661745f781ff"
|
||||
checksum = "6d7db6eca8c205649e8d3ccd05aa5042b1800a784e56bc7c43524fde8abbfa9b"
|
||||
dependencies = [
|
||||
"clap",
|
||||
]
|
||||
|
|
@ -1144,6 +1144,7 @@ checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c"
|
|||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ serde = { workspace = true }
|
|||
|
||||
[build-dependencies]
|
||||
clap = { workspace = true }
|
||||
clap_complete = "4.5.23"
|
||||
clap_complete = "4.5.24"
|
||||
clap_complete_fig = "4.5.2"
|
||||
clap_complete_nushell = "4.5.3"
|
||||
vergen-gitcl = { version = "1.0.0", features = [ "build" ] }
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ yazi-shared = { path = "../yazi-shared", version = "0.3.1" }
|
|||
# External build dependencies
|
||||
anyhow = { workspace = true }
|
||||
clap = { workspace = true }
|
||||
clap_complete = "4.5.23"
|
||||
clap_complete = "4.5.24"
|
||||
clap_complete_fig = "4.5.2"
|
||||
clap_complete_nushell = "4.5.3"
|
||||
serde_json = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ arc-swap = { workspace = true }
|
|||
bitflags = { workspace = true }
|
||||
crossterm = { workspace = true }
|
||||
globset = { workspace = true }
|
||||
indexmap = "2.4.0"
|
||||
indexmap = { version = "2.4.0", features = [ "serde" ] }
|
||||
ratatui = { workspace = true }
|
||||
regex = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::{borrow::Cow, collections::VecDeque, sync::OnceLock};
|
||||
use std::{borrow::Cow, collections::VecDeque, hash::{Hash, Hasher}, sync::OnceLock};
|
||||
|
||||
use regex::Regex;
|
||||
use serde::Deserialize;
|
||||
|
|
@ -9,7 +9,7 @@ use super::Key;
|
|||
static RE: OnceLock<Regex> = OnceLock::new();
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
pub struct Control {
|
||||
pub struct Chord {
|
||||
#[serde(deserialize_with = "super::deserialize_on")]
|
||||
pub on: Vec<Key>,
|
||||
#[serde(deserialize_with = "super::deserialize_run")]
|
||||
|
|
@ -17,12 +17,17 @@ pub struct Control {
|
|||
pub desc: Option<String>,
|
||||
}
|
||||
|
||||
impl Control {
|
||||
#[inline]
|
||||
pub fn to_seq(&self) -> VecDeque<Cmd> { self.run.iter().map(|c| c.shallow_clone()).collect() }
|
||||
impl PartialEq for Chord {
|
||||
fn eq(&self, other: &Self) -> bool { self.on == other.on }
|
||||
}
|
||||
|
||||
impl Control {
|
||||
impl Eq for Chord {}
|
||||
|
||||
impl Hash for Chord {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) { self.on.hash(state) }
|
||||
}
|
||||
|
||||
impl Chord {
|
||||
pub fn on(&self) -> String { self.on.iter().map(ToString::to_string).collect() }
|
||||
|
||||
pub fn run(&self) -> String {
|
||||
|
|
@ -44,4 +49,7 @@ impl Control {
|
|||
|| self.run().to_lowercase().contains(&s)
|
||||
|| self.on().to_lowercase().contains(&s)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_seq(&self) -> VecDeque<Cmd> { self.run.iter().map(|c| c.shallow_clone()).collect() }
|
||||
}
|
||||
|
|
@ -2,24 +2,24 @@ use std::{collections::VecDeque, ops::Deref};
|
|||
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
use super::Control;
|
||||
use super::Chord;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ControlCow {
|
||||
Owned(Control),
|
||||
Borrowed(&'static Control),
|
||||
pub enum ChordCow {
|
||||
Owned(Chord),
|
||||
Borrowed(&'static Chord),
|
||||
}
|
||||
|
||||
impl From<&'static Control> for ControlCow {
|
||||
fn from(c: &'static Control) -> Self { Self::Borrowed(c) }
|
||||
impl From<&'static Chord> for ChordCow {
|
||||
fn from(c: &'static Chord) -> Self { Self::Borrowed(c) }
|
||||
}
|
||||
|
||||
impl From<Control> for ControlCow {
|
||||
fn from(c: Control) -> Self { Self::Owned(c) }
|
||||
impl From<Chord> for ChordCow {
|
||||
fn from(c: Chord) -> Self { Self::Owned(c) }
|
||||
}
|
||||
|
||||
impl Deref for ControlCow {
|
||||
type Target = Control;
|
||||
impl Deref for ChordCow {
|
||||
type Target = Chord;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
match self {
|
||||
|
|
@ -29,11 +29,11 @@ impl Deref for ControlCow {
|
|||
}
|
||||
}
|
||||
|
||||
impl Default for ControlCow {
|
||||
fn default() -> Self { Self::Owned(Control::default()) }
|
||||
impl Default for ChordCow {
|
||||
fn default() -> Self { Self::Owned(Chord::default()) }
|
||||
}
|
||||
|
||||
impl ControlCow {
|
||||
impl ChordCow {
|
||||
pub fn into_seq(self) -> VecDeque<Cmd> {
|
||||
match self {
|
||||
Self::Owned(c) => c.run.into(),
|
||||
|
|
|
|||
|
|
@ -1,25 +1,26 @@
|
|||
use std::str::FromStr;
|
||||
use std::{collections::HashSet, str::FromStr};
|
||||
|
||||
use indexmap::IndexSet;
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use yazi_shared::Layer;
|
||||
|
||||
use super::Control;
|
||||
use super::Chord;
|
||||
use crate::Preset;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Keymap {
|
||||
pub manager: Vec<Control>,
|
||||
pub tasks: Vec<Control>,
|
||||
pub select: Vec<Control>,
|
||||
pub input: Vec<Control>,
|
||||
pub confirm: Vec<Control>,
|
||||
pub help: Vec<Control>,
|
||||
pub completion: Vec<Control>,
|
||||
pub manager: Vec<Chord>,
|
||||
pub tasks: Vec<Chord>,
|
||||
pub select: Vec<Chord>,
|
||||
pub input: Vec<Chord>,
|
||||
pub confirm: Vec<Chord>,
|
||||
pub help: Vec<Chord>,
|
||||
pub completion: Vec<Chord>,
|
||||
}
|
||||
|
||||
impl Keymap {
|
||||
#[inline]
|
||||
pub fn get(&self, layer: Layer) -> &Vec<Control> {
|
||||
pub fn get(&self, layer: Layer) -> &Vec<Chord> {
|
||||
match layer {
|
||||
Layer::App => unreachable!(),
|
||||
Layer::Manager => &self.manager,
|
||||
|
|
@ -57,38 +58,38 @@ impl<'de> Deserialize<'de> for Keymap {
|
|||
}
|
||||
#[derive(Deserialize)]
|
||||
struct Inner {
|
||||
keymap: Vec<Control>,
|
||||
keymap: IndexSet<Chord>,
|
||||
#[serde(default)]
|
||||
prepend_keymap: Vec<Control>,
|
||||
prepend_keymap: IndexSet<Chord>,
|
||||
#[serde(default)]
|
||||
append_keymap: Vec<Control>,
|
||||
append_keymap: IndexSet<Chord>,
|
||||
}
|
||||
|
||||
let mut shadow = Shadow::deserialize(deserializer)?;
|
||||
fn mix(mut a: IndexSet<Chord>, b: IndexSet<Chord>, c: IndexSet<Chord>) -> Vec<Chord> {
|
||||
let mut seen = HashSet::new();
|
||||
b.iter().filter_map(|v| v.on.get(1)).for_each(|&k| _ = seen.insert(k));
|
||||
c.iter().filter_map(|v| v.on.get(1)).for_each(|&k| _ = seen.insert(k));
|
||||
|
||||
#[rustfmt::skip]
|
||||
Preset::mix(&mut shadow.manager.keymap, shadow.manager.prepend_keymap, shadow.manager.append_keymap);
|
||||
#[rustfmt::skip]
|
||||
Preset::mix(&mut shadow.tasks.keymap, shadow.tasks.prepend_keymap, shadow.tasks.append_keymap);
|
||||
#[rustfmt::skip]
|
||||
Preset::mix(&mut shadow.select.keymap, shadow.select.prepend_keymap, shadow.select.append_keymap);
|
||||
#[rustfmt::skip]
|
||||
Preset::mix(&mut shadow.input.keymap, shadow.input.prepend_keymap, shadow.input.append_keymap);
|
||||
#[rustfmt::skip]
|
||||
Preset::mix(&mut shadow.confirm.keymap, shadow.confirm.prepend_keymap, shadow.confirm.append_keymap);
|
||||
#[rustfmt::skip]
|
||||
Preset::mix(&mut shadow.help.keymap, shadow.help.prepend_keymap, shadow.help.append_keymap);
|
||||
#[rustfmt::skip]
|
||||
Preset::mix(&mut shadow.completion.keymap, shadow.completion.prepend_keymap, shadow.completion.append_keymap);
|
||||
a.retain(|v| v.on.len() < 2 || !seen.contains(&v.on[1]));
|
||||
Preset::mix(a, b, c).collect()
|
||||
}
|
||||
|
||||
let shadow = Shadow::deserialize(deserializer)?;
|
||||
Ok(Self {
|
||||
manager: shadow.manager.keymap,
|
||||
tasks: shadow.tasks.keymap,
|
||||
select: shadow.select.keymap,
|
||||
input: shadow.input.keymap,
|
||||
confirm: shadow.confirm.keymap,
|
||||
help: shadow.help.keymap,
|
||||
completion: shadow.completion.keymap,
|
||||
#[rustfmt::skip]
|
||||
manager: mix(shadow.manager.keymap, shadow.manager.prepend_keymap, shadow.manager.append_keymap),
|
||||
#[rustfmt::skip]
|
||||
tasks: mix(shadow.tasks.keymap, shadow.tasks.prepend_keymap, shadow.tasks.append_keymap),
|
||||
#[rustfmt::skip]
|
||||
select: mix(shadow.select.keymap, shadow.select.prepend_keymap, shadow.select.append_keymap),
|
||||
#[rustfmt::skip]
|
||||
input: mix(shadow.input.keymap, shadow.input.prepend_keymap, shadow.input.append_keymap),
|
||||
#[rustfmt::skip]
|
||||
confirm: mix(shadow.confirm.keymap, shadow.confirm.prepend_keymap, shadow.confirm.append_keymap),
|
||||
#[rustfmt::skip]
|
||||
help: mix(shadow.help.keymap, shadow.help.prepend_keymap, shadow.help.append_keymap),
|
||||
#[rustfmt::skip]
|
||||
completion: mix(shadow.completion.keymap, shadow.completion.prepend_keymap, shadow.completion.append_keymap),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
mod control;
|
||||
mod chord;
|
||||
mod cow;
|
||||
mod deserializers;
|
||||
mod key;
|
||||
mod keymap;
|
||||
|
||||
pub use control::*;
|
||||
pub use chord::*;
|
||||
pub use cow::*;
|
||||
use deserializers::*;
|
||||
pub use key::*;
|
||||
|
|
|
|||
|
|
@ -87,7 +87,6 @@ impl<'de> Deserialize<'de> for Open {
|
|||
if outer.open.append_rules.iter().any(|r| r.any_dir()) {
|
||||
outer.open.rules.retain(|r| !r.any_dir());
|
||||
}
|
||||
Preset::mix(&mut outer.open.rules, outer.open.prepend_rules, outer.open.append_rules);
|
||||
|
||||
let openers = outer
|
||||
.opener
|
||||
|
|
@ -95,6 +94,10 @@ impl<'de> Deserialize<'de> for Open {
|
|||
.map(|(k, v)| (k, v.into_iter().filter_map(|o| o.take()).collect::<IndexSet<_>>()))
|
||||
.collect();
|
||||
|
||||
Ok(Self { rules: outer.open.rules, openers })
|
||||
Ok(Self {
|
||||
#[rustfmt::skip]
|
||||
rules: Preset::mix(outer.open.rules, outer.open.prepend_rules, outer.open.append_rules).collect(),
|
||||
openers,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,9 +86,12 @@ impl FromStr for Plugin {
|
|||
shadow.previewers.retain(|r| !r.any_dir());
|
||||
}
|
||||
|
||||
Preset::mix(&mut shadow.fetchers, shadow.prepend_fetchers, shadow.append_fetchers);
|
||||
Preset::mix(&mut shadow.preloaders, shadow.prepend_preloaders, shadow.append_preloaders);
|
||||
Preset::mix(&mut shadow.previewers, shadow.prepend_previewers, shadow.append_previewers);
|
||||
shadow.fetchers =
|
||||
Preset::mix(shadow.fetchers, shadow.prepend_fetchers, shadow.append_fetchers).collect();
|
||||
shadow.preloaders =
|
||||
Preset::mix(shadow.preloaders, shadow.prepend_preloaders, shadow.append_preloaders).collect();
|
||||
shadow.previewers =
|
||||
Preset::mix(shadow.previewers, shadow.prepend_previewers, shadow.append_previewers).collect();
|
||||
|
||||
if shadow.fetchers.len() + shadow.preloaders.len() > MAX_PREWORKERS as usize {
|
||||
panic!("Fetchers and preloaders exceed the limit of {MAX_PREWORKERS}");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::{borrow::Cow, mem, path::{Path, PathBuf}};
|
||||
use std::{borrow::Cow, path::{Path, PathBuf}};
|
||||
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use toml::{Table, Value};
|
||||
|
|
@ -32,8 +32,11 @@ impl Preset {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn mix<T>(a: &mut Vec<T>, b: Vec<T>, c: Vec<T>) {
|
||||
*a = b.into_iter().chain(mem::take(a)).chain(c).collect();
|
||||
pub(crate) fn mix<T, E>(a: T, b: T, c: T) -> impl Iterator<Item = E>
|
||||
where
|
||||
T: IntoIterator<Item = E>,
|
||||
{
|
||||
b.into_iter().chain(a).chain(c)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -124,36 +124,26 @@ impl<'de> Deserialize<'de> for Icons {
|
|||
fg_light: Option<Color>,
|
||||
}
|
||||
|
||||
let mut shadow = Shadow::deserialize(deserializer)?;
|
||||
Preset::mix(&mut shadow.globs, shadow.prepend_globs, shadow.append_globs);
|
||||
Preset::mix(&mut shadow.dirs, shadow.prepend_dirs, shadow.append_dirs);
|
||||
Preset::mix(&mut shadow.files, shadow.prepend_files, shadow.append_files);
|
||||
Preset::mix(&mut shadow.exts, shadow.prepend_exts, shadow.append_exts);
|
||||
Preset::mix(&mut shadow.conds, shadow.prepend_conds, shadow.append_conds);
|
||||
let shadow = Shadow::deserialize(deserializer)?;
|
||||
|
||||
let globs = shadow
|
||||
.globs
|
||||
.into_iter()
|
||||
let globs = Preset::mix(shadow.globs, shadow.prepend_globs, shadow.append_globs)
|
||||
.map(|v| {
|
||||
(v.name, Icon { text: v.text, style: Style { fg: v.fg_dark, ..Default::default() } })
|
||||
})
|
||||
.collect();
|
||||
|
||||
let conds = shadow
|
||||
.conds
|
||||
.into_iter()
|
||||
let conds = Preset::mix(shadow.conds, shadow.prepend_conds, shadow.append_conds)
|
||||
.map(|v| {
|
||||
(v.if_, Icon { text: v.text, style: Style { fg: v.fg_dark, ..Default::default() } })
|
||||
})
|
||||
.collect();
|
||||
|
||||
fn as_map(v: Vec<ShadowStr>) -> HashMap<String, Icon> {
|
||||
let mut map = HashMap::with_capacity(v.len());
|
||||
for item in v {
|
||||
map.entry(item.name).or_insert(Icon {
|
||||
text: item.text,
|
||||
style: Style { fg: item.fg_dark, ..Default::default() },
|
||||
});
|
||||
fn as_map(it: impl Iterator<Item = ShadowStr>) -> HashMap<String, Icon> {
|
||||
let mut map = HashMap::with_capacity(it.size_hint().0);
|
||||
for v in it {
|
||||
map
|
||||
.entry(v.name)
|
||||
.or_insert(Icon { text: v.text, style: Style { fg: v.fg_dark, ..Default::default() } });
|
||||
}
|
||||
map.shrink_to_fit();
|
||||
map
|
||||
|
|
@ -161,9 +151,9 @@ impl<'de> Deserialize<'de> for Icons {
|
|||
|
||||
Ok(Self {
|
||||
globs,
|
||||
dirs: as_map(shadow.dirs),
|
||||
files: as_map(shadow.files),
|
||||
exts: as_map(shadow.exts),
|
||||
dirs: as_map(Preset::mix(shadow.dirs, shadow.prepend_dirs, shadow.append_dirs)),
|
||||
files: as_map(Preset::mix(shadow.files, shadow.prepend_files, shadow.append_files)),
|
||||
exts: as_map(Preset::mix(shadow.exts, shadow.prepend_exts, shadow.append_exts)),
|
||||
conds,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use crossterm::event::KeyCode;
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
use yazi_adapter::Dimension;
|
||||
use yazi_config::{keymap::{Control, Key}, KEYMAP};
|
||||
use yazi_config::{keymap::{Chord, Key}, KEYMAP};
|
||||
use yazi_shared::{render, render_and, Layer};
|
||||
|
||||
use super::HELP_MARGIN;
|
||||
|
|
@ -11,7 +11,7 @@ use crate::input::Input;
|
|||
pub struct Help {
|
||||
pub visible: bool,
|
||||
pub layer: Layer,
|
||||
pub(super) bindings: Vec<&'static Control>,
|
||||
pub(super) bindings: Vec<&'static Chord>,
|
||||
|
||||
// Filter
|
||||
pub(super) keyword: String,
|
||||
|
|
@ -93,7 +93,7 @@ impl Help {
|
|||
|
||||
// --- Bindings
|
||||
#[inline]
|
||||
pub fn window(&self) -> &[&Control] {
|
||||
pub fn window(&self) -> &[&Chord] {
|
||||
let end = (self.offset + Self::limit()).min(self.bindings.len());
|
||||
&self.bindings[self.offset..end]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
use std::{collections::HashSet, str::FromStr};
|
||||
use std::str::FromStr;
|
||||
|
||||
use yazi_config::{keymap::{Control, Key}, KEYMAP};
|
||||
use yazi_config::{keymap::{Chord, Key}, KEYMAP};
|
||||
use yazi_shared::{event::Cmd, render, Layer};
|
||||
|
||||
use crate::which::{Which, WhichSorter};
|
||||
|
||||
pub struct Opt {
|
||||
cands: Vec<Control>,
|
||||
cands: Vec<Chord>,
|
||||
layer: Layer,
|
||||
silent: bool,
|
||||
}
|
||||
|
|
@ -42,16 +42,13 @@ impl Which {
|
|||
render!();
|
||||
}
|
||||
|
||||
pub fn show_with(&mut self, key: &Key, layer: Layer) {
|
||||
let mut seen = HashSet::new();
|
||||
|
||||
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)
|
||||
.filter(|&c| seen.insert(&c.on))
|
||||
.filter(|c| c.on.len() > 1 && c.on[0] == key)
|
||||
.map(|c| c.into())
|
||||
.collect();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::{borrow::Cow, mem};
|
||||
|
||||
use yazi_config::{keymap::ControlCow, which::SortBy, WHICH};
|
||||
use yazi_config::{keymap::ChordCow, which::SortBy, WHICH};
|
||||
use yazi_shared::{natsort, Transliterator};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
|
|
@ -23,7 +23,7 @@ impl Default for WhichSorter {
|
|||
}
|
||||
|
||||
impl WhichSorter {
|
||||
pub(super) fn sort(&self, items: &mut Vec<ControlCow>) {
|
||||
pub(super) fn sort(&self, items: &mut Vec<ChordCow>) {
|
||||
if self.by == SortBy::None || items.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
use yazi_config::keymap::{ControlCow, Key};
|
||||
use yazi_config::keymap::{ChordCow, Key};
|
||||
use yazi_shared::{emit, render, render_and, Layer};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Which {
|
||||
pub(super) layer: Layer,
|
||||
pub times: usize,
|
||||
pub cands: Vec<ControlCow>,
|
||||
pub cands: Vec<ChordCow>,
|
||||
|
||||
// Visibility
|
||||
pub visible: bool,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use yazi_config::{keymap::{Control, Key}, KEYMAP};
|
||||
use yazi_config::{keymap::{Chord, Key}, KEYMAP};
|
||||
use yazi_shared::{emit, Layer};
|
||||
|
||||
use crate::app::App;
|
||||
|
|
@ -44,13 +44,13 @@ impl<'a> Router<'a> {
|
|||
|
||||
#[inline]
|
||||
fn matches(&mut self, layer: Layer, key: Key) -> bool {
|
||||
for ctrl @ Control { on, .. } in KEYMAP.get(layer) {
|
||||
for ctrl @ Chord { on, .. } in KEYMAP.get(layer) {
|
||||
if on.is_empty() || on[0] != key {
|
||||
continue;
|
||||
}
|
||||
|
||||
if on.len() > 1 {
|
||||
self.app.cx.which.show_with(&key, layer);
|
||||
self.app.cx.which.show_with(key, layer);
|
||||
} else {
|
||||
emit!(Seq(ctrl.to_seq(), layer));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
use ratatui::{buffer::Buffer, layout::Rect, text::{Line, Span}, widgets::Widget};
|
||||
use yazi_config::{keymap::Control, THEME};
|
||||
use yazi_config::{keymap::Chord, THEME};
|
||||
|
||||
pub(super) struct Cand<'a> {
|
||||
cand: &'a Control,
|
||||
cand: &'a Chord,
|
||||
times: usize,
|
||||
}
|
||||
|
||||
impl<'a> Cand<'a> {
|
||||
pub(super) fn new(cand: &'a Control, times: usize) -> Self { Self { times, cand } }
|
||||
pub(super) fn new(cand: &'a Chord, times: usize) -> Self { Self { times, cand } }
|
||||
|
||||
fn keys(&self) -> Vec<String> {
|
||||
self.cand.on[self.times..].iter().map(ToString::to_string).collect()
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::{str::FromStr, time::Duration};
|
|||
use mlua::{ExternalError, ExternalResult, IntoLuaMulti, Lua, Table, Value};
|
||||
use tokio::sync::mpsc;
|
||||
use tokio_stream::wrappers::UnboundedReceiverStream;
|
||||
use yazi_config::{keymap::{Control, Key}, popup::InputCfg};
|
||||
use yazi_config::{keymap::{Chord, Key}, popup::InputCfg};
|
||||
use yazi_proxy::{AppProxy, InputProxy};
|
||||
use yazi_shared::{emit, event::Cmd, Debounce, Layer};
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ impl Utils {
|
|||
let mut cands = Vec::with_capacity(30);
|
||||
for (i, cand) in t.raw_get::<_, Table>("cands")?.sequence_values::<Table>().enumerate() {
|
||||
let cand = cand?;
|
||||
cands.push(Control {
|
||||
cands.push(Chord {
|
||||
on: Self::parse_keys(cand.raw_get("on")?)?,
|
||||
run: vec![Cmd::args("callback", &[i]).with_any("tx", tx.clone())],
|
||||
desc: cand.raw_get("desc").ok(),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue