Skip to content

Commit

Permalink
feat: simplify keybindings (#1241)
Browse files Browse the repository at this point in the history
  • Loading branch information
sxyazi committed Jul 1, 2024
1 parent 1a1da21 commit 987b1d5
Show file tree
Hide file tree
Showing 12 changed files with 323 additions and 244 deletions.
352 changes: 176 additions & 176 deletions yazi-config/preset/keymap.toml

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions yazi-config/src/keymap/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ use super::Key;

#[derive(Debug, Default, Deserialize)]
pub struct Control {
#[serde(deserialize_with = "super::deserialize_on")]
pub on: Vec<Key>,
#[serde(deserialize_with = "super::run_deserialize")]
#[serde(deserialize_with = "super::deserialize_run")]
pub run: Vec<Cmd>,
pub desc: Option<String>,
}
Expand All @@ -24,7 +25,7 @@ impl Control {

#[inline]
pub fn run(&self) -> String {
self.run.iter().map(|e| e.to_string()).collect::<Vec<_>>().join("; ")
self.run.iter().map(|c| c.to_string()).collect::<Vec<_>>().join("; ")
}

#[inline]
Expand Down
83 changes: 83 additions & 0 deletions yazi-config/src/keymap/deserializers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use std::{fmt, str::FromStr};

use anyhow::Result;
use serde::{de::{self, Visitor}, Deserializer};
use yazi_shared::event::Cmd;

use crate::keymap::Key;

pub(super) fn deserialize_on<'de, D>(deserializer: D) -> Result<Vec<Key>, D::Error>
where
D: Deserializer<'de>,
{
struct OnVisitor;

impl<'de> Visitor<'de> for OnVisitor {
type Value = Vec<Key>;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a `on` string or array of strings within keymap.toml")
}

fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: de::SeqAccess<'de>,
{
let mut cmds = vec![];
while let Some(value) = &seq.next_element::<String>()? {
cmds.push(Key::from_str(value).map_err(de::Error::custom)?);
}
if cmds.is_empty() {
return Err(de::Error::custom("`on` within keymap.toml cannot be empty"));
}
Ok(cmds)
}

fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(vec![Key::from_str(value).map_err(de::Error::custom)?])
}
}

deserializer.deserialize_any(OnVisitor)
}

pub(super) fn deserialize_run<'de, D>(deserializer: D) -> Result<Vec<Cmd>, D::Error>
where
D: Deserializer<'de>,
{
struct RunVisitor;

impl<'de> Visitor<'de> for RunVisitor {
type Value = Vec<Cmd>;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a `run` string or array of strings within keymap.toml")
}

fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: de::SeqAccess<'de>,
{
let mut cmds = vec![];
while let Some(value) = &seq.next_element::<String>()? {
cmds.push(Cmd::from_str(value).map_err(de::Error::custom)?);
}
if cmds.is_empty() {
return Err(de::Error::custom("`run` within keymap.toml cannot be empty"));
}
Ok(cmds)
}

fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(vec![Cmd::from_str(value).map_err(de::Error::custom)?])
}
}

deserializer.deserialize_any(RunVisitor)
}
10 changes: 1 addition & 9 deletions yazi-config/src/keymap/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ use std::{fmt::{Display, Write}, str::FromStr};

use anyhow::bail;
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use serde::Deserialize;

#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Hash)]
#[serde(try_from = "String")]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Key {
pub code: KeyCode,
pub shift: bool,
Expand Down Expand Up @@ -126,12 +124,6 @@ impl FromStr for Key {
}
}

impl TryFrom<String> for Key {
type Error = anyhow::Error;

fn try_from(s: String) -> Result<Self, Self::Error> { Self::from_str(&s) }
}

impl Display for Key {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(c) = self.plain() {
Expand Down
5 changes: 2 additions & 3 deletions yazi-config/src/keymap/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
mod control;
mod cow;
mod deserializers;
mod key;
mod keymap;
mod run;

pub use control::*;
pub use cow::*;
use deserializers::*;
pub use key::*;
pub use keymap::*;
#[allow(unused_imports)]
pub use run::*;
43 changes: 0 additions & 43 deletions yazi-config/src/keymap/run.rs

This file was deleted.

14 changes: 14 additions & 0 deletions yazi-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,19 @@ pub fn init() -> anyhow::Result<()> {
SELECT.init(<_>::from_str(yazi_toml)?);
WHICH.init(<_>::from_str(yazi_toml)?);

// TODO: Remove in v0.3.2
for c in &KEYMAP.manager {
for r in &c.run {
if r.name == "shell" && !r.bool("confirm") && !r.bool("interactive") {
eprintln!(
r#"WARNING: In Yazi v0.3, the behavior of the interactive `shell` (i.e., shell templates) must be explicitly specified with `--interactive`.
Please replace e.g. `shell` with `shell --interactive`, `shell "my-template"` with `shell "my-template" --interactive`, in your keymap.toml"#
);
return Ok(());
}
}
}

Ok(())
}
6 changes: 5 additions & 1 deletion yazi-core/src/input/snaps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ impl InputSnaps {
}

pub(super) fn tag(&mut self, limit: usize) -> bool {
if self.versions.len() <= self.idx {
return false;
}

// Sync *current* cursor position to the *last* version:
// Save offset/cursor/ect. of the *current* as the last version,
// while keeping the *last* value unchanged.
Expand Down Expand Up @@ -49,7 +53,7 @@ impl InputSnaps {
}

pub(super) fn redo(&mut self) -> bool {
if self.idx + 1 == self.versions.len() {
if self.idx + 1 >= self.versions.len() {
return false;
}

Expand Down
38 changes: 29 additions & 9 deletions yazi-core/src/tab/commands/shell.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
use std::borrow::Cow;

use yazi_config::{open::Opener, popup::InputCfg};
use yazi_proxy::{InputProxy, TasksProxy};
use yazi_proxy::{AppProxy, InputProxy, TasksProxy};
use yazi_shared::event::Cmd;

use crate::tab::Tab;

pub struct Opt {
run: String,
block: bool,
orphan: bool,
confirm: bool,
run: String,
block: bool,
orphan: bool,
confirm: bool,
interactive: bool,
}

impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self {
Self {
run: c.take_first_str().unwrap_or_default(),
block: c.bool("block"),
orphan: c.bool("orphan"),
confirm: c.bool("confirm"),
run: c.take_first_str().unwrap_or_default(),
block: c.bool("block"),
orphan: c.bool("orphan"),
confirm: c.bool("confirm"),
interactive: c.bool("interactive"),
}
}
}
Expand All @@ -31,6 +33,24 @@ impl Tab {
}

let mut opt = opt.into() as Opt;

// TODO: Remove in v0.3.2
if !opt.interactive && !opt.confirm {
AppProxy::notify_error(
"`shell` command",
r#"In Yazi v0.3, the behavior of the interactive `shell` (i.e., shell templates) must be explicitly specified with `--interactive`.
Please replace e.g. `shell` with `shell --interactive`, `shell "my-template"` with `shell "my-template" --interactive`, in your keymap.toml"#,
);
return;
} else if opt.interactive && opt.confirm {
AppProxy::notify_error(
"`shell` command",
"The `shell` command cannot specify both `--confirm` and `--interactive` at the same time.",
);
return;
}

let selected = self.hovered_and_selected(true).cloned().collect();

tokio::spawn(async move {
Expand Down
2 changes: 1 addition & 1 deletion yazi-plugin/preset/components/current.lua
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ function Current:click(event, up)

ya.manager_emit("arrow", { event.y + f.offset - f.hovered.idx })
if event.is_right then
ya.manager_emit("open", { hovered = true })
ya.manager_emit("open", {})
end
end

Expand Down
1 change: 1 addition & 0 deletions yazi-plugin/preset/setup.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
os.setlocale("")
package.path = BOOT.plugin_dir .. "/?.yazi/init.lua;" .. package.path

require("dds"):setup()
8 changes: 8 additions & 0 deletions yazi-plugin/src/utils/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ impl Utils {
})?,
)?;

ya.raw_set(
"input_emit",
lua.create_function(|_, (name, args): (String, Table)| {
emit!(Call(Cmd { name, args: Self::parse_args(args)? }, Layer::Input));
Ok(())
})?,
)?;

Ok(())
}
}

0 comments on commit 987b1d5

Please sign in to comment.