mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
feat: platform-specific key binding (#2526)
This commit is contained in:
parent
83f4deecfe
commit
e138364102
10 changed files with 57 additions and 43 deletions
|
|
@ -1,4 +1,4 @@
|
|||
use anyhow::{Context, Result};
|
||||
use anyhow::{Context, Result, bail};
|
||||
use tokio::fs;
|
||||
use twox_hash::XxHash3_128;
|
||||
use yazi_fs::ok_or_not_found;
|
||||
|
|
@ -22,18 +22,21 @@ impl Dependency {
|
|||
&["LICENSE", "README.md", "main.lua"][..]
|
||||
};
|
||||
|
||||
let mut hasher = XxHash3_128::new();
|
||||
for file in files {
|
||||
hasher.write(file.as_bytes());
|
||||
hasher.write(b"VpvFw9Atb7cWGOdqhZCra634CcJJRlsRl72RbZeV0vpG1\0");
|
||||
hasher.write(&ok_or_not_found(fs::read(dir.join(file)).await)?);
|
||||
let mut h = XxHash3_128::new();
|
||||
for &file in files {
|
||||
h.write(file.as_bytes());
|
||||
h.write(b"VpvFw9Atb7cWGOdqhZCra634CcJJRlsRl72RbZeV0vpG1\0");
|
||||
h.write(&ok_or_not_found(fs::read(dir.join(file)).await)?);
|
||||
}
|
||||
|
||||
let mut assets = vec![];
|
||||
match fs::read_dir(dir.join("assets")).await {
|
||||
Ok(mut it) => {
|
||||
while let Some(entry) = it.next_entry().await? {
|
||||
assets.push((entry.file_name(), fs::read(entry.path()).await?));
|
||||
let Ok(name) = entry.file_name().into_string() else {
|
||||
bail!("asset path is not valid UTF-8: {}", entry.path().display());
|
||||
};
|
||||
assets.push((name, fs::read(entry.path()).await?));
|
||||
}
|
||||
}
|
||||
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {}
|
||||
|
|
@ -42,11 +45,11 @@ impl Dependency {
|
|||
|
||||
assets.sort_unstable_by(|(a, _), (b, _)| a.cmp(b));
|
||||
for (name, data) in assets {
|
||||
hasher.write(name.as_encoded_bytes());
|
||||
hasher.write(b"pQU2in0xcsu97Y77Nuq2LnT8mczMlFj22idcYRmMrglqU\0");
|
||||
hasher.write(&data);
|
||||
h.write(name.as_bytes());
|
||||
h.write(b"pQU2in0xcsu97Y77Nuq2LnT8mczMlFj22idcYRmMrglqU\0");
|
||||
h.write(&data);
|
||||
}
|
||||
|
||||
Ok(format!("{:x}", hasher.finish_128()))
|
||||
Ok(format!("{:x}", h.finish_128()))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::{borrow::Cow, hash::{Hash, Hasher}, sync::OnceLock};
|
||||
|
||||
use anyhow::Result;
|
||||
use regex::Regex;
|
||||
use serde::Deserialize;
|
||||
use yazi_shared::{Layer, event::Cmd};
|
||||
|
|
@ -15,6 +16,8 @@ pub struct Chord {
|
|||
#[serde(deserialize_with = "super::deserialize_run")]
|
||||
pub run: Vec<Cmd>,
|
||||
pub desc: Option<String>,
|
||||
#[serde(rename = "for")]
|
||||
pub for_: Option<String>,
|
||||
}
|
||||
|
||||
impl PartialEq for Chord {
|
||||
|
|
@ -53,14 +56,15 @@ impl Chord {
|
|||
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;
|
||||
impl Chord {
|
||||
pub(super) fn reshape(mut self, layer: Layer) -> Result<Self> {
|
||||
for cmd in &mut self.run {
|
||||
if cmd.layer == Default::default() {
|
||||
cmd.layer = layer;
|
||||
}
|
||||
}
|
||||
self
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ where
|
|||
where
|
||||
A: de::SeqAccess<'de>,
|
||||
{
|
||||
let mut cmds = vec![];
|
||||
let mut cmds = Vec::with_capacity(seq.size_hint().unwrap_or(0));
|
||||
while let Some(value) = &seq.next_element::<String>()? {
|
||||
cmds.push(Key::from_str(value).map_err(de::Error::custom)?);
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ where
|
|||
where
|
||||
A: de::SeqAccess<'de>,
|
||||
{
|
||||
let mut cmds = vec![];
|
||||
let mut cmds = Vec::with_capacity(seq.size_hint().unwrap_or(0));
|
||||
while let Some(value) = &seq.next_element::<String>()? {
|
||||
cmds.push(Cmd::from_str(value).map_err(de::Error::custom)?);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,19 +3,19 @@ use serde::Deserialize;
|
|||
use yazi_codegen::DeserializeOver1;
|
||||
use yazi_shared::Layer;
|
||||
|
||||
use super::{Chord, KeymapRule};
|
||||
use super::{Chord, KeymapRules};
|
||||
|
||||
#[derive(Deserialize, DeserializeOver1)]
|
||||
pub struct Keymap {
|
||||
#[serde(rename = "manager")]
|
||||
pub mgr: KeymapRule,
|
||||
pub tasks: KeymapRule,
|
||||
pub spot: KeymapRule,
|
||||
pub pick: KeymapRule,
|
||||
pub input: KeymapRule,
|
||||
pub confirm: KeymapRule,
|
||||
pub help: KeymapRule,
|
||||
pub cmp: KeymapRule,
|
||||
pub mgr: KeymapRules,
|
||||
pub tasks: KeymapRules,
|
||||
pub spot: KeymapRules,
|
||||
pub pick: KeymapRules,
|
||||
pub input: KeymapRules,
|
||||
pub confirm: KeymapRules,
|
||||
pub help: KeymapRules,
|
||||
pub cmp: KeymapRules,
|
||||
}
|
||||
|
||||
impl Keymap {
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
yazi_macro::mod_flat!(chord cow deserializers key keymap rule);
|
||||
yazi_macro::mod_flat!(chord cow deserializers key keymap rules);
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ use yazi_codegen::DeserializeOver2;
|
|||
use yazi_shared::Layer;
|
||||
|
||||
use super::Chord;
|
||||
use crate::{Preset, keymap::Key};
|
||||
use crate::{Preset, check_for, keymap::Key};
|
||||
|
||||
#[derive(Default, Deserialize, DeserializeOver2)]
|
||||
pub struct KeymapRule {
|
||||
pub struct KeymapRules {
|
||||
pub keymap: Vec<Chord>,
|
||||
#[serde(default)]
|
||||
prepend_keymap: Vec<Chord>,
|
||||
|
|
@ -17,13 +17,13 @@ pub struct KeymapRule {
|
|||
append_keymap: Vec<Chord>,
|
||||
}
|
||||
|
||||
impl Deref for KeymapRule {
|
||||
impl Deref for KeymapRules {
|
||||
type Target = Vec<Chord>;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.keymap }
|
||||
}
|
||||
|
||||
impl KeymapRule {
|
||||
impl KeymapRules {
|
||||
pub(crate) fn reshape(self, layer: Layer) -> Result<Self> {
|
||||
#[inline]
|
||||
fn on(Chord { on, .. }: &Chord) -> [Key; 2] {
|
||||
|
|
@ -38,9 +38,10 @@ impl KeymapRule {
|
|||
self.keymap.into_iter().filter(|v| !a_seen.contains(&on(v))),
|
||||
self.append_keymap.into_iter().filter(|v| !b_seen.contains(&on(v))),
|
||||
)
|
||||
.filter(|chord| !chord.noop())
|
||||
.map(|chord| chord.with_layer(layer))
|
||||
.collect();
|
||||
.map(|mut chord| (chord.for_.take(), chord))
|
||||
.filter(|(for_, chord)| !chord.noop() && check_for(for_.as_deref()))
|
||||
.map(|(_, chord)| chord.reshape(layer))
|
||||
.collect::<Result<_>>()?;
|
||||
|
||||
Ok(Self { keymap, ..Default::default() })
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
yazi_macro::mod_pub!(keymap mgr open opener plugin popup preview tasks theme which);
|
||||
|
||||
yazi_macro::mod_flat!(layout pattern preset priority yazi);
|
||||
yazi_macro::mod_flat!(layout pattern platform preset priority yazi);
|
||||
|
||||
use std::io::{Read, Write};
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use indexmap::IndexSet;
|
|||
use serde::Deserialize;
|
||||
|
||||
use super::OpenerRule;
|
||||
use crate::check_for;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Opener(HashMap<String, Vec<OpenerRule>>);
|
||||
|
|
@ -44,12 +45,7 @@ impl Opener {
|
|||
*rules = mem::take(rules)
|
||||
.into_iter()
|
||||
.map(|mut r| (r.for_.take(), r))
|
||||
.filter(|(for_, _)| match for_.as_ref().map(|s| s.as_str()) {
|
||||
Some("unix") if cfg!(unix) => true,
|
||||
Some(os) if os == std::env::consts::OS => true,
|
||||
Some(_) => false,
|
||||
None => true,
|
||||
})
|
||||
.filter(|(for_, _)| check_for(for_.as_deref()))
|
||||
.map(|(_, r)| r.reshape())
|
||||
.collect::<Result<IndexSet<_>>>()?
|
||||
.into_iter()
|
||||
|
|
|
|||
9
yazi-config/src/platform.rs
Normal file
9
yazi-config/src/platform.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#[inline]
|
||||
pub(crate) fn check_for(for_: Option<&str>) -> bool {
|
||||
match 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,
|
||||
}
|
||||
}
|
||||
|
|
@ -23,6 +23,7 @@ impl Utils {
|
|||
on: Self::parse_keys(cand.raw_get("on")?)?,
|
||||
run: vec![Cmd::args("which:callback", &[i]).with_any("tx", tx.clone())],
|
||||
desc: cand.raw_get("desc").ok(),
|
||||
for_: None,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue