feat: expose stash action and give it a new search source (#3872)

This commit is contained in:
三咲雅 misaki masa 2026-04-11 07:59:38 +08:00 committed by GitHub
parent f6408656b4
commit 74d903a49a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
55 changed files with 471 additions and 274 deletions

View file

@ -6,6 +6,7 @@ use serde::Deserialize;
use yazi_shared::{Layer, Source, event::Action};
use super::Key;
use crate::Platform;
static RE: OnceLock<Regex> = OnceLock::new();
@ -16,7 +17,8 @@ pub struct Chord {
#[serde(deserialize_with = "super::deserialize_run")]
pub run: Vec<Action>,
pub desc: Option<String>,
pub r#for: Option<String>,
#[serde(default)]
pub r#for: Platform,
}
impl PartialEq for Chord {

View file

@ -3,6 +3,7 @@ use std::ops::Deref;
use yazi_shared::event::ActionCow;
use super::Chord;
use crate::Platform;
#[derive(Clone, Debug)]
pub enum ChordCow {
@ -31,7 +32,7 @@ impl Deref for ChordCow {
impl Default for ChordCow {
fn default() -> Self {
const C: &Chord = &Chord { on: vec![], run: vec![], desc: None, r#for: None };
const C: &Chord = &Chord { on: vec![], run: vec![], desc: None, r#for: Platform::All };
Self::Borrowed(C)
}
}

View file

@ -7,7 +7,7 @@ use yazi_codegen::DeserializeOver2;
use yazi_shared::Layer;
use super::Chord;
use crate::{Preset, check_for, keymap::Key};
use crate::{Preset, keymap::Key};
#[derive(Default, Deserialize, DeserializeOver2)]
pub struct KeymapRules {
@ -39,9 +39,8 @@ impl KeymapRules {
self.keymap.into_iter().filter(|v| !a_seen.contains(&on(v))),
self.append_keymap.into_iter().filter(|v| !b_seen.contains(&on(v))),
)
.map(|mut chord| (chord.r#for.take(), chord))
.filter(|(r#for, chord)| !chord.noop() && check_for(r#for.as_deref()))
.map(|(_, chord)| chord.reshape(layer))
.filter(|chord| !chord.noop() && chord.r#for.matches())
.map(|chord| chord.reshape(layer))
.collect::<Result<_>>()?;
Ok(Self { keymap, ..Default::default() })

View file

@ -8,7 +8,6 @@ use toml::{Spanned, de::DeTable};
use yazi_codegen::DeserializeOver;
use super::OpenerRule;
use crate::check_for;
#[derive(Debug, Deserialize, DeserializeOver)]
pub struct Opener(HashMap<String, Vec<OpenerRule>>);
@ -47,9 +46,8 @@ impl Opener {
for rules in self.0.values_mut() {
*rules = mem::take(rules)
.into_iter()
.map(|mut r| (r.r#for.take(), r))
.filter(|(r#for, _)| check_for(r#for.as_deref()))
.map(|(_, r)| r.reshape())
.filter(|r| r.r#for.matches())
.map(|r| r.reshape())
.collect::<Result<IndexSet<_>>>()?
.into_iter()
.collect();

View file

@ -2,6 +2,8 @@ use anyhow::{Result, bail};
use serde::Deserialize;
use yazi_fs::Splatter;
use crate::Platform;
#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct OpenerRule {
pub run: String,
@ -11,7 +13,8 @@ pub struct OpenerRule {
pub orphan: bool,
#[serde(default)]
pub desc: String,
pub r#for: Option<String>,
#[serde(default)]
pub r#for: Platform,
#[serde(skip)]
pub spread: bool,
}

View file

@ -1,9 +1,26 @@
#[inline]
pub(crate) fn check_for(r#for: Option<&str>) -> bool {
match r#for.as_ref().map(|s| s.as_ref()) {
Some("unix") if cfg!(unix) => true,
Some(os) if os == std::env::consts::OS => true,
Some(_) => false,
None => true,
use serde::Deserialize;
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(rename_all = "kebab-case")]
pub enum Platform {
#[default]
All,
Linux,
Macos,
Windows,
Android,
Unix,
}
impl Platform {
pub(crate) fn matches(self) -> bool {
match self {
Self::All => true,
Self::Linux => cfg!(target_os = "linux"),
Self::Macos => cfg!(target_os = "macos"),
Self::Windows => cfg!(windows),
Self::Android => cfg!(target_os = "android"),
Self::Unix => cfg!(unix),
}
}
}