diff --git a/README.md b/README.md
index 9e78a17e..5ae75e2e 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,7 @@
+## The main branch is the upcoming v0.4 development version. Please see [the `shipped` tag](https://github.com/sxyazi/yazi/tree/shipped) for the stable version of Yazi.
+
+For breaking changes, see [Migrating to Yazi v0.4.0](https://github.com/sxyazi/yazi/issues/1772).
+
@@ -16,7 +20,7 @@ Yazi (means "duck") is a terminal file manager written in Rust, based on non-blo
- 📡 **Data Distribution Service**: Built on a client-server architecture (no additional server process required), integrated with a Lua-based publish-subscribe model, achieving cross-instance communication and state persistence.
- 📦 **Package Manager**: Install plugins and themes with one command, keeping them up to date, or pin them to a specific version.
- 🧰 Integration with ripgrep, fd, fzf, zoxide
-- 💫 Vim-like input/select/confirm/which/notify component, auto-completion for cd paths
+- 💫 Vim-like input/pick/confirm/which/notify component, auto-completion for cd paths
- 🏷️ Multi-Tab Support, Cross-directory selection, Scrollable Preview (for videos, PDFs, archives, directories, code, etc.)
- 🔄 Bulk Renaming, Visual Mode, File Chooser
- 🎨 Theme System, Mouse Support, Trash Bin, Custom Layouts, CSI u
diff --git a/yazi-config/preset/keymap.toml b/yazi-config/preset/keymap.toml
index 9dabc302..0f59f98b 100644
--- a/yazi-config/preset/keymap.toml
+++ b/yazi-config/preset/keymap.toml
@@ -46,12 +46,14 @@ keymap = [
{ on = "K", run = "seek -5", desc = "Seek up 5 units in the preview" },
{ on = "J", run = "seek 5", desc = "Seek down 5 units in the preview" },
- # Selection
- { on = "", run = [ "select --state=none", "arrow 1" ], desc = "Toggle the current selection state" },
- { on = "v", run = "visual_mode", desc = "Enter visual mode (selection mode)" },
- { on = "V", run = "visual_mode --unset", desc = "Enter visual mode (unset mode)" },
- { on = "", run = "select_all --state=true", desc = "Select all files" },
- { on = "", run = "select_all --state=none", desc = "Inverse selection of all files" },
+ # Toggle
+ { on = "", run = [ "toggle", "arrow 1" ], desc = "Toggle the current selection state" },
+ { on = "", run = "toggle_all on", desc = "Select all files" },
+ { on = "", run = "toggle_all", desc = "Invert selection of all files" },
+
+ # Visual mode
+ { on = "v", run = "visual_mode", desc = "Enter visual mode (selection mode)" },
+ { on = "V", run = "visual_mode --unset", desc = "Enter visual mode (unset mode)" },
# Operation
{ on = "o", run = "open", desc = "Open selected files" },
@@ -173,13 +175,13 @@ keymap = [
{ on = "", run = "help", desc = "Open help" },
]
-[select]
+[pick]
keymap = [
- { on = "", run = "close", desc = "Cancel selection" },
- { on = "", run = "close", desc = "Cancel selection" },
- { on = "", run = "close", desc = "Cancel selection" },
- { on = "", run = "close --submit", desc = "Submit the selection" },
+ { on = "", run = "close", desc = "Cancel pick" },
+ { on = "", run = "close", desc = "Cancel pick" },
+ { on = "", run = "close", desc = "Cancel pick" },
+ { on = "", run = "close --submit", desc = "Submit the pick" },
{ on = "k", run = "arrow -1", desc = "Move cursor up" },
{ on = "j", run = "arrow 1", desc = "Move cursor down" },
diff --git a/yazi-config/preset/theme.toml b/yazi-config/preset/theme.toml
index 09e65b03..a5001a2d 100644
--- a/yazi-config/preset/theme.toml
+++ b/yazi-config/preset/theme.toml
@@ -77,9 +77,9 @@ permissions_s = { fg = "darkgray" }
# : }}}
-# : Select {{{
+# : Pick {{{
-[select]
+[pick]
border = { fg = "blue" }
active = { fg = "magenta", bold = true }
inactive = {}
diff --git a/yazi-config/preset/yazi.toml b/yazi-config/preset/yazi.toml
index 05a60fa2..9c71da8b 100644
--- a/yazi-config/preset/yazi.toml
+++ b/yazi-config/preset/yazi.toml
@@ -191,7 +191,7 @@ quit_content = "The following task is still running, are you sure you want to qu
quit_origin = "center"
quit_offset = [ 0, 0, 50, 15 ]
-[select]
+[pick]
open_title = "Open with:"
open_origin = "hovered"
open_offset = [ 0, 1, 50, 7 ]
diff --git a/yazi-config/src/keymap/keymap.rs b/yazi-config/src/keymap/keymap.rs
index c01851c8..2cf291ad 100644
--- a/yazi-config/src/keymap/keymap.rs
+++ b/yazi-config/src/keymap/keymap.rs
@@ -11,7 +11,7 @@ use crate::Preset;
pub struct Keymap {
pub manager: Vec,
pub tasks: Vec,
- pub select: Vec,
+ pub pick: Vec,
pub input: Vec,
pub confirm: Vec,
pub help: Vec,
@@ -25,7 +25,7 @@ impl Keymap {
Layer::App => unreachable!(),
Layer::Manager => &self.manager,
Layer::Tasks => &self.tasks,
- Layer::Select => &self.select,
+ Layer::Pick => &self.pick,
Layer::Input => &self.input,
Layer::Confirm => &self.confirm,
Layer::Help => &self.help,
@@ -50,7 +50,7 @@ impl<'de> Deserialize<'de> for Keymap {
struct Shadow {
manager: Inner,
tasks: Inner,
- select: Inner,
+ pick: Inner,
input: Inner,
confirm: Inner,
help: Inner,
@@ -81,7 +81,7 @@ impl<'de> Deserialize<'de> for 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),
+ pick: mix(shadow.pick.keymap, shadow.pick.prepend_keymap, shadow.pick.append_keymap),
#[rustfmt::skip]
input: mix(shadow.input.keymap, shadow.input.prepend_keymap, shadow.input.append_keymap),
#[rustfmt::skip]
diff --git a/yazi-config/src/lib.rs b/yazi-config/src/lib.rs
index da1efe4b..7c09c86d 100644
--- a/yazi-config/src/lib.rs
+++ b/yazi-config/src/lib.rs
@@ -1,8 +1,8 @@
#![allow(clippy::module_inception)]
-yazi_macro::mod_pub!(keymap, log, manager, open, plugin, popup, preview, tasks, theme, which);
+yazi_macro::mod_pub!(keymap log manager open plugin popup preview tasks theme which);
-yazi_macro::mod_flat!(layout, pattern, preset, priority);
+yazi_macro::mod_flat!(layout pattern preset priority);
use std::str::FromStr;
@@ -20,7 +20,7 @@ pub static TASKS: RoCell = RoCell::new();
pub static THEME: RoCell = RoCell::new();
pub static INPUT: RoCell = RoCell::new();
pub static CONFIRM: RoCell = RoCell::new();
-pub static SELECT: RoCell = RoCell::new();
+pub static PICK: RoCell = RoCell::new();
pub static WHICH: RoCell = RoCell::new();
pub fn init() -> anyhow::Result<()> {
@@ -41,7 +41,7 @@ pub fn init() -> anyhow::Result<()> {
THEME.init(<_>::from_str(theme_toml)?);
INPUT.init(<_>::from_str(yazi_toml)?);
CONFIRM.init(<_>::from_str(yazi_toml)?);
- SELECT.init(<_>::from_str(yazi_toml)?);
+ PICK.init(<_>::from_str(yazi_toml)?);
WHICH.init(<_>::from_str(yazi_toml)?);
// TODO: Remove in v0.3.2
diff --git a/yazi-config/src/popup/mod.rs b/yazi-config/src/popup/mod.rs
index 8adc3f49..f1611bbb 100644
--- a/yazi-config/src/popup/mod.rs
+++ b/yazi-config/src/popup/mod.rs
@@ -1 +1 @@
-yazi_macro::mod_flat!(confirm, input, offset, options, origin, position, select);
+yazi_macro::mod_flat!(confirm, input, offset, options, origin, pick, position);
diff --git a/yazi-config/src/popup/options.rs b/yazi-config/src/popup/options.rs
index 6cf419d9..c97a640c 100644
--- a/yazi-config/src/popup/options.rs
+++ b/yazi-config/src/popup/options.rs
@@ -2,7 +2,7 @@ use ratatui::{text::Text, widgets::{Paragraph, Wrap}};
use yazi_shared::fs::Url;
use super::{Offset, Origin, Position};
-use crate::{CONFIRM, INPUT, SELECT};
+use crate::{CONFIRM, INPUT, PICK};
#[derive(Default)]
pub struct InputCfg {
@@ -16,7 +16,7 @@ pub struct InputCfg {
}
#[derive(Default)]
-pub struct SelectCfg {
+pub struct PickCfg {
pub title: String,
pub items: Vec,
pub position: Position,
@@ -176,21 +176,18 @@ impl ConfirmCfg {
}
}
-impl SelectCfg {
+impl PickCfg {
#[inline]
fn max_height(len: usize) -> u16 {
- SELECT.open_offset.height.min(SELECT.border().saturating_add(len as u16))
+ PICK.open_offset.height.min(PICK.border().saturating_add(len as u16))
}
pub fn open(items: Vec) -> Self {
let max_height = Self::max_height(items.len());
Self {
- title: SELECT.open_title.to_owned(),
+ title: PICK.open_title.to_owned(),
items,
- position: Position::new(SELECT.open_origin, Offset {
- height: max_height,
- ..SELECT.open_offset
- }),
+ position: Position::new(PICK.open_origin, Offset { height: max_height, ..PICK.open_offset }),
}
}
}
diff --git a/yazi-config/src/popup/select.rs b/yazi-config/src/popup/pick.rs
similarity index 75%
rename from yazi-config/src/popup/select.rs
rename to yazi-config/src/popup/pick.rs
index df584df8..ea2218c3 100644
--- a/yazi-config/src/popup/select.rs
+++ b/yazi-config/src/popup/pick.rs
@@ -5,26 +5,26 @@ use serde::Deserialize;
use super::{Offset, Origin};
#[derive(Deserialize)]
-pub struct Select {
+pub struct Pick {
// open
pub open_title: String,
pub open_origin: Origin,
pub open_offset: Offset,
}
-impl Select {
+impl Pick {
pub const fn border(&self) -> u16 { 2 }
}
-impl FromStr for Select {
+impl FromStr for Pick {
type Err = toml::de::Error;
fn from_str(s: &str) -> Result {
#[derive(Deserialize)]
struct Outer {
- select: Select,
+ pick: Pick,
}
- Ok(toml::from_str::(s)?.select)
+ Ok(toml::from_str::(s)?.pick)
}
}
diff --git a/yazi-config/src/theme/theme.rs b/yazi-config/src/theme/theme.rs
index a8d6e417..6f872bf1 100644
--- a/yazi-config/src/theme/theme.rs
+++ b/yazi-config/src/theme/theme.rs
@@ -12,7 +12,7 @@ pub struct Theme {
pub manager: Manager,
status: Status,
pub input: Input,
- pub select: Select,
+ pub pick: Pick,
pub completion: Completion,
pub tasks: Tasks,
pub which: Which,
@@ -115,7 +115,7 @@ pub struct Input {
}
#[derive(Deserialize, Serialize)]
-pub struct Select {
+pub struct Pick {
pub border: Style,
pub active: Style,
pub inactive: Style,
diff --git a/yazi-core/src/input/op.rs b/yazi-core/src/input/op.rs
index 7a2fbae2..55ab0772 100644
--- a/yazi-core/src/input/op.rs
+++ b/yazi-core/src/input/op.rs
@@ -5,8 +5,7 @@ pub enum InputOp {
#[default]
None,
Select(usize),
- // cut, insert, start
- Delete(bool, bool, usize),
+ Delete(bool, bool, usize), // cut, insert, start
Yank(usize),
}
diff --git a/yazi-core/src/lib.rs b/yazi-core/src/lib.rs
index 952774c5..8d7616ef 100644
--- a/yazi-core/src/lib.rs
+++ b/yazi-core/src/lib.rs
@@ -6,7 +6,7 @@
clippy::unit_arg
)]
-yazi_macro::mod_pub!(completion, confirm, help, input, manager, notify, select, tab, tasks, which);
+yazi_macro::mod_pub!(completion confirm help input manager notify pick tab tasks which);
pub fn init() {
manager::WATCHED.with(<_>::default);
diff --git a/yazi-core/src/manager/commands/open.rs b/yazi-core/src/manager/commands/open.rs
index 449a15d8..630455b5 100644
--- a/yazi-core/src/manager/commands/open.rs
+++ b/yazi-core/src/manager/commands/open.rs
@@ -2,7 +2,7 @@ use std::{borrow::Cow, ffi::OsString};
use tracing::error;
use yazi_boot::ARGS;
-use yazi_config::{OPEN, popup::SelectCfg};
+use yazi_config::{OPEN, popup::PickCfg};
use yazi_fs::Folder;
use yazi_macro::emit;
use yazi_plugin::isolate;
@@ -96,7 +96,7 @@ impl Manager {
let urls = [opt.hovered].into_iter().chain(targets.into_iter().map(|(u, _)| u)).collect();
tokio::spawn(async move {
- let result = yazi_proxy::SelectProxy::show(SelectCfg::open(
+ let result = yazi_proxy::PickProxy::show(PickCfg::open(
openers.iter().map(|o| o.desc.clone()).collect(),
));
if let Ok(choice) = result.await {
diff --git a/yazi-core/src/select/commands/arrow.rs b/yazi-core/src/pick/commands/arrow.rs
similarity index 96%
rename from yazi-core/src/select/commands/arrow.rs
rename to yazi-core/src/pick/commands/arrow.rs
index deea6b36..e78883e8 100644
--- a/yazi-core/src/select/commands/arrow.rs
+++ b/yazi-core/src/pick/commands/arrow.rs
@@ -1,7 +1,7 @@
use yazi_macro::render;
use yazi_shared::event::{Cmd, Data};
-use crate::select::Select;
+use crate::pick::Pick;
struct Opt {
step: isize,
@@ -11,7 +11,7 @@ impl From for Opt {
fn from(c: Cmd) -> Self { Self { step: c.first().and_then(Data::as_isize).unwrap_or(0) } }
}
-impl Select {
+impl Pick {
#[yazi_codegen::command]
pub fn arrow(&mut self, opt: Opt) {
if opt.step > 0 { self.next(opt.step as usize) } else { self.prev(opt.step.unsigned_abs()) }
diff --git a/yazi-core/src/select/commands/close.rs b/yazi-core/src/pick/commands/close.rs
similarity index 93%
rename from yazi-core/src/select/commands/close.rs
rename to yazi-core/src/pick/commands/close.rs
index 6e73fd8b..cd684345 100644
--- a/yazi-core/src/select/commands/close.rs
+++ b/yazi-core/src/pick/commands/close.rs
@@ -2,7 +2,7 @@ use anyhow::anyhow;
use yazi_macro::render;
use yazi_shared::event::Cmd;
-use crate::select::Select;
+use crate::pick::Pick;
struct Opt {
submit: bool,
@@ -15,7 +15,7 @@ impl From for Opt {
fn from(submit: bool) -> Self { Self { submit } }
}
-impl Select {
+impl Pick {
#[yazi_codegen::command]
pub fn close(&mut self, opt: Opt) {
if let Some(cb) = self.callback.take() {
diff --git a/yazi-core/src/select/commands/mod.rs b/yazi-core/src/pick/commands/mod.rs
similarity index 100%
rename from yazi-core/src/select/commands/mod.rs
rename to yazi-core/src/pick/commands/mod.rs
diff --git a/yazi-core/src/select/commands/show.rs b/yazi-core/src/pick/commands/show.rs
similarity index 87%
rename from yazi-core/src/select/commands/show.rs
rename to yazi-core/src/pick/commands/show.rs
index 022fb8b3..dc24fefe 100644
--- a/yazi-core/src/select/commands/show.rs
+++ b/yazi-core/src/pick/commands/show.rs
@@ -1,12 +1,12 @@
use tokio::sync::oneshot;
-use yazi_config::popup::SelectCfg;
+use yazi_config::popup::PickCfg;
use yazi_macro::render;
use yazi_shared::event::Cmd;
-use crate::select::Select;
+use crate::pick::Pick;
pub struct Opt {
- cfg: SelectCfg,
+ cfg: PickCfg,
tx: oneshot::Sender>,
}
@@ -18,7 +18,7 @@ impl TryFrom for Opt {
}
}
-impl Select {
+impl Pick {
pub fn show(&mut self, opt: impl TryInto) {
let Ok(opt) = opt.try_into() else {
return;
diff --git a/yazi-core/src/select/mod.rs b/yazi-core/src/pick/mod.rs
similarity index 51%
rename from yazi-core/src/select/mod.rs
rename to yazi-core/src/pick/mod.rs
index 02c53b3c..c9f4add5 100644
--- a/yazi-core/src/select/mod.rs
+++ b/yazi-core/src/pick/mod.rs
@@ -1,3 +1,3 @@
yazi_macro::mod_pub!(commands);
-yazi_macro::mod_flat!(select);
+yazi_macro::mod_flat!(pick);
diff --git a/yazi-core/src/select/select.rs b/yazi-core/src/pick/pick.rs
similarity index 79%
rename from yazi-core/src/select/select.rs
rename to yazi-core/src/pick/pick.rs
index c86f27a4..dba61eb6 100644
--- a/yazi-core/src/select/select.rs
+++ b/yazi-core/src/pick/pick.rs
@@ -1,9 +1,9 @@
use anyhow::Result;
use tokio::sync::oneshot::Sender;
-use yazi_config::{SELECT, popup::Position};
+use yazi_config::{PICK, popup::Position};
#[derive(Default)]
-pub struct Select {
+pub struct Pick {
pub(super) title: String,
pub(super) items: Vec,
pub position: Position,
@@ -15,7 +15,7 @@ pub struct Select {
pub visible: bool,
}
-impl Select {
+impl Pick {
#[inline]
pub fn window(&self) -> &[String] {
let end = (self.offset + self.limit()).min(self.items.len());
@@ -24,11 +24,11 @@ impl Select {
#[inline]
pub(super) fn limit(&self) -> usize {
- self.position.offset.height.saturating_sub(SELECT.border()) as usize
+ self.position.offset.height.saturating_sub(PICK.border()) as usize
}
}
-impl Select {
+impl Pick {
#[inline]
pub fn title(&self) -> String { self.title.clone() }
diff --git a/yazi-core/src/tab/commands/mod.rs b/yazi-core/src/tab/commands/mod.rs
index dddf38dc..ef5f18c7 100644
--- a/yazi-core/src/tab/commands/mod.rs
+++ b/yazi-core/src/tab/commands/mod.rs
@@ -1,25 +1,25 @@
yazi_macro::mod_flat!(
- arrow,
- back,
- cd,
- copy,
- enter,
- escape,
- filter,
- filter_do,
- find,
- find_arrow,
- find_do,
- forward,
- hidden,
- leave,
- linemode,
- preview,
- reveal,
- search,
- select,
- select_all,
- shell,
- sort,
+ arrow
+ back
+ cd
+ copy
+ enter
+ escape
+ filter
+ filter_do
+ find
+ find_arrow
+ find_do
+ forward
+ hidden
+ leave
+ linemode
+ preview
+ reveal
+ search
+ shell
+ sort
+ toggle
+ toggle_all
visual_mode
);
diff --git a/yazi-core/src/tab/commands/select.rs b/yazi-core/src/tab/commands/toggle.rs
similarity index 83%
rename from yazi-core/src/tab/commands/select.rs
rename to yazi-core/src/tab/commands/toggle.rs
index 94fc57c2..2dfdf709 100644
--- a/yazi-core/src/tab/commands/select.rs
+++ b/yazi-core/src/tab/commands/toggle.rs
@@ -15,9 +15,9 @@ impl<'a> From for Opt<'a> {
fn from(mut c: Cmd) -> Self {
Self {
url: c.take("url").and_then(Data::into_url).map(Cow::Owned),
- state: match c.take_str("state").as_deref() {
- Some("true") => Some(true),
- Some("false") => Some(false),
+ state: match c.take_first_str().as_deref() {
+ Some("on") => Some(true),
+ Some("off") => Some(false),
_ => None,
},
}
@@ -26,7 +26,7 @@ impl<'a> From for Opt<'a> {
impl<'a> Tab {
#[yazi_codegen::command]
- pub fn select(&mut self, opt: Opt<'a>) {
+ pub fn toggle(&mut self, opt: Opt<'a>) {
let Some(url) = opt.url.or_else(|| self.current.hovered().map(|h| Cow::Borrowed(&h.url)))
else {
return;
@@ -40,7 +40,7 @@ impl<'a> Tab {
if !b {
AppProxy::notify_warn(
- "Select one",
+ "Toggle",
"This file cannot be selected, due to path nesting conflict.",
);
}
diff --git a/yazi-core/src/tab/commands/select_all.rs b/yazi-core/src/tab/commands/toggle_all.rs
similarity index 84%
rename from yazi-core/src/tab/commands/select_all.rs
rename to yazi-core/src/tab/commands/toggle_all.rs
index 4e568494..ebab9e97 100644
--- a/yazi-core/src/tab/commands/select_all.rs
+++ b/yazi-core/src/tab/commands/toggle_all.rs
@@ -11,9 +11,9 @@ struct Opt {
impl From for Opt {
fn from(mut c: Cmd) -> Self {
Self {
- state: match c.take_str("state").as_deref() {
- Some("true") => Some(true),
- Some("false") => Some(false),
+ state: match c.take_first_str().as_deref() {
+ Some("on") => Some(true),
+ Some("off") => Some(false),
_ => None,
},
}
@@ -25,7 +25,7 @@ impl From