mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
refactor: derive the Into<Opt> trait with procedural macros to avoid bloat (#1742)
This commit is contained in:
parent
dcbe7873cd
commit
064517665d
61 changed files with 360 additions and 266 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
|
@ -3310,6 +3310,7 @@ dependencies = [
|
|||
"yazi-config",
|
||||
"yazi-dds",
|
||||
"yazi-fs",
|
||||
"yazi-macro",
|
||||
"yazi-plugin",
|
||||
"yazi-proxy",
|
||||
"yazi-scheduler",
|
||||
|
|
@ -3362,6 +3363,7 @@ dependencies = [
|
|||
"yazi-core",
|
||||
"yazi-dds",
|
||||
"yazi-fs",
|
||||
"yazi-macro",
|
||||
"yazi-plugin",
|
||||
"yazi-proxy",
|
||||
"yazi-shared",
|
||||
|
|
@ -3381,6 +3383,14 @@ dependencies = [
|
|||
"yazi-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yazi-macro"
|
||||
version = "0.3.3"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yazi-plugin"
|
||||
version = "0.3.3"
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ yazi-boot = { path = "../yazi-boot", version = "0.3.3" }
|
|||
yazi-config = { path = "../yazi-config", version = "0.3.3" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "0.3.3" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "0.3.3" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "0.3.3" }
|
||||
yazi-plugin = { path = "../yazi-plugin", version = "0.3.3" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "0.3.3" }
|
||||
yazi-scheduler = { path = "../yazi-scheduler", version = "0.3.3" }
|
||||
|
|
|
|||
|
|
@ -11,6 +11,15 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Completion {
|
||||
#[yazi_macro::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());
|
||||
}
|
||||
}
|
||||
|
||||
fn next(&mut self, step: usize) {
|
||||
let len = self.cands.len();
|
||||
if len == 0 {
|
||||
|
|
@ -38,13 +47,4 @@ impl Completion {
|
|||
|
||||
render!(old != self.cursor);
|
||||
}
|
||||
|
||||
pub fn arrow(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
if opt.step > 0 {
|
||||
self.next(opt.step as usize);
|
||||
} else {
|
||||
self.prev(opt.step.unsigned_abs());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,9 +15,8 @@ impl From<bool> for Opt {
|
|||
}
|
||||
|
||||
impl Completion {
|
||||
pub fn close(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
|
||||
#[yazi_macro::command]
|
||||
pub fn close(&mut self, opt: Opt) {
|
||||
if let Some(s) = self.selected().filter(|_| opt.submit) {
|
||||
InputProxy::complete(s, self.ticket);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,31 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Completion {
|
||||
#[yazi_macro::command]
|
||||
pub fn show(&mut self, opt: Opt) {
|
||||
if self.ticket != opt.ticket {
|
||||
return;
|
||||
}
|
||||
|
||||
if !opt.cache.is_empty() {
|
||||
self.caches.insert(opt.cache_name.to_owned(), opt.cache);
|
||||
}
|
||||
let Some(cache) = self.caches.get(&opt.cache_name) else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.ticket = opt.ticket;
|
||||
self.cands = Self::match_candidates(&opt.word, cache);
|
||||
if self.cands.is_empty() {
|
||||
return render!(mem::replace(&mut self.visible, false));
|
||||
}
|
||||
|
||||
self.offset = 0;
|
||||
self.cursor = 0;
|
||||
self.visible = true;
|
||||
render!();
|
||||
}
|
||||
|
||||
fn match_candidates(word: &str, cache: &[String]) -> Vec<String> {
|
||||
let smart = !word.bytes().any(|c| c.is_ascii_uppercase());
|
||||
|
||||
|
|
@ -55,29 +80,4 @@ impl Completion {
|
|||
}
|
||||
prefixed.into_iter().map(ToOwned::to_owned).collect()
|
||||
}
|
||||
|
||||
pub fn show(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
if self.ticket != opt.ticket {
|
||||
return;
|
||||
}
|
||||
|
||||
if !opt.cache.is_empty() {
|
||||
self.caches.insert(opt.cache_name.to_owned(), opt.cache);
|
||||
}
|
||||
let Some(cache) = self.caches.get(&opt.cache_name) else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.ticket = opt.ticket;
|
||||
self.cands = Self::match_candidates(&opt.word, cache);
|
||||
if self.cands.is_empty() {
|
||||
return render!(mem::replace(&mut self.visible, false));
|
||||
}
|
||||
|
||||
self.offset = 0;
|
||||
self.cursor = 0;
|
||||
self.visible = true;
|
||||
render!();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Completion {
|
||||
pub fn trigger(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
#[yazi_macro::command]
|
||||
pub fn trigger(&mut self, opt: Opt) {
|
||||
if opt.ticket < self.ticket {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,15 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Confirm {
|
||||
#[yazi_macro::command]
|
||||
pub fn arrow(&mut self, opt: Opt, manager: &Manager) {
|
||||
if opt.step > 0 {
|
||||
self.next(opt.step as usize, manager.area(self.position).width)
|
||||
} else {
|
||||
self.prev(opt.step.unsigned_abs())
|
||||
}
|
||||
}
|
||||
|
||||
fn next(&mut self, step: usize, width: u16) {
|
||||
let height = self.list.line_count(width);
|
||||
if height == 0 {
|
||||
|
|
@ -29,13 +38,4 @@ impl Confirm {
|
|||
|
||||
render!(old != self.offset);
|
||||
}
|
||||
|
||||
pub fn arrow(&mut self, opt: impl Into<Opt>, manager: &Manager) {
|
||||
let opt = opt.into() as Opt;
|
||||
if opt.step > 0 {
|
||||
self.next(opt.step as usize, manager.area(self.position).width)
|
||||
} else {
|
||||
self.prev(opt.step.unsigned_abs())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ impl From<bool> for Opt {
|
|||
}
|
||||
|
||||
impl Confirm {
|
||||
pub fn close(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
#[yazi_macro::command]
|
||||
pub fn close(&mut self, opt: Opt) {
|
||||
if let Some(cb) = self.callback.take() {
|
||||
_ = cb.send(opt.submit);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,13 +14,12 @@ impl From<isize> for Opt {
|
|||
}
|
||||
|
||||
impl Help {
|
||||
#[inline]
|
||||
pub fn arrow(&mut self, opt: impl Into<Opt>) {
|
||||
#[yazi_macro::command]
|
||||
pub fn arrow(&mut self, opt: Opt) {
|
||||
let max = self.bindings.len().saturating_sub(1);
|
||||
self.offset = self.offset.min(max);
|
||||
self.cursor = self.cursor.min(max);
|
||||
|
||||
let opt = opt.into() as Opt;
|
||||
if opt.step > 0 {
|
||||
self.next(opt.step as usize);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ impl From<bool> for Opt {
|
|||
}
|
||||
|
||||
impl Input {
|
||||
pub fn backspace(&mut self, opt: impl Into<Opt>) {
|
||||
#[yazi_macro::command]
|
||||
pub fn backspace(&mut self, opt: Opt) {
|
||||
let snap = self.snaps.current_mut();
|
||||
let opt = opt.into() as Opt;
|
||||
if !opt.under && snap.cursor < 1 {
|
||||
return;
|
||||
} else if opt.under && snap.cursor >= snap.value.len() {
|
||||
|
|
|
|||
|
|
@ -15,9 +15,8 @@ impl From<bool> for Opt {
|
|||
}
|
||||
|
||||
impl Input {
|
||||
pub fn close(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
|
||||
#[yazi_macro::command]
|
||||
pub fn close(&mut self, opt: Opt) {
|
||||
if self.completion {
|
||||
CompletionProxy::close();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Input {
|
||||
pub fn complete(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
#[yazi_macro::command]
|
||||
pub fn complete(&mut self, opt: Opt) {
|
||||
if self.ticket != opt.ticket {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Input {
|
||||
pub fn delete(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
#[yazi_macro::command]
|
||||
pub fn delete(&mut self, opt: Opt) {
|
||||
match self.snap().op {
|
||||
InputOp::None => {
|
||||
self.snap_mut().op = InputOp::Delete(opt.cut, opt.insert, self.snap().cursor);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ impl From<()> for Opt {
|
|||
}
|
||||
|
||||
impl Input {
|
||||
pub fn escape(&mut self, _: impl Into<Opt>) {
|
||||
#[yazi_macro::command]
|
||||
pub fn escape(&mut self, _: Opt) {
|
||||
let snap = self.snap_mut();
|
||||
match snap.mode {
|
||||
InputMode::Normal if snap.op == InputOp::None => {
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Input {
|
||||
pub fn forward(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
#[yazi_macro::command]
|
||||
pub fn forward(&mut self, opt: Opt) {
|
||||
let snap = self.snap();
|
||||
|
||||
let mut it = snap.value.chars().skip(snap.cursor).enumerate();
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ impl From<bool> for Opt {
|
|||
}
|
||||
|
||||
impl Input {
|
||||
pub fn insert(&mut self, opt: impl Into<Opt>) {
|
||||
#[yazi_macro::command]
|
||||
pub fn insert(&mut self, opt: Opt) {
|
||||
let snap = self.snap_mut();
|
||||
if snap.mode == InputMode::Normal {
|
||||
snap.op = InputOp::None;
|
||||
|
|
@ -23,7 +24,6 @@ impl Input {
|
|||
return;
|
||||
}
|
||||
|
||||
let opt = opt.into() as Opt;
|
||||
if opt.append {
|
||||
self.move_(1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,33 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Input {
|
||||
#[yazi_macro::command]
|
||||
pub fn kill(&mut self, opt: Opt) {
|
||||
let snap = self.snap_mut();
|
||||
match opt.kind.as_str() {
|
||||
"all" => self.kill_range(..),
|
||||
"bol" => {
|
||||
let end = snap.idx(snap.cursor).unwrap_or(snap.len());
|
||||
self.kill_range(..end)
|
||||
}
|
||||
"eol" => {
|
||||
let start = snap.idx(snap.cursor).unwrap_or(snap.len());
|
||||
self.kill_range(start..)
|
||||
}
|
||||
"backward" => {
|
||||
let end = snap.idx(snap.cursor).unwrap_or(snap.len());
|
||||
let start = end - Self::find_word_boundary(snap.value[..end].chars().rev());
|
||||
self.kill_range(start..end)
|
||||
}
|
||||
"forward" => {
|
||||
let start = snap.idx(snap.cursor).unwrap_or(snap.len());
|
||||
let end = start + Self::find_word_boundary(snap.value[start..].chars());
|
||||
self.kill_range(start..end)
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn kill_range(&mut self, range: impl RangeBounds<usize>) {
|
||||
let snap = self.snap_mut();
|
||||
snap.cursor = match range.start_bound() {
|
||||
|
|
@ -64,32 +91,4 @@ impl Input {
|
|||
let n = n + count_characters(input.clone().skip(n));
|
||||
input.take(n).fold(0, |acc, c| acc + c.len_utf8())
|
||||
}
|
||||
|
||||
pub fn kill(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
let snap = self.snap_mut();
|
||||
|
||||
match opt.kind.as_str() {
|
||||
"all" => self.kill_range(..),
|
||||
"bol" => {
|
||||
let end = snap.idx(snap.cursor).unwrap_or(snap.len());
|
||||
self.kill_range(..end)
|
||||
}
|
||||
"eol" => {
|
||||
let start = snap.idx(snap.cursor).unwrap_or(snap.len());
|
||||
self.kill_range(start..)
|
||||
}
|
||||
"backward" => {
|
||||
let end = snap.idx(snap.cursor).unwrap_or(snap.len());
|
||||
let start = end - Self::find_word_boundary(snap.value[..end].chars().rev());
|
||||
self.kill_range(start..end)
|
||||
}
|
||||
"forward" => {
|
||||
let start = snap.idx(snap.cursor).unwrap_or(snap.len());
|
||||
let end = start + Self::find_word_boundary(snap.value[start..].chars());
|
||||
self.kill_range(start..end)
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,8 @@ impl From<isize> for Opt {
|
|||
}
|
||||
|
||||
impl Input {
|
||||
pub fn move_(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
|
||||
#[yazi_macro::command]
|
||||
pub fn move_(&mut self, opt: Opt) {
|
||||
let snap = self.snap();
|
||||
if opt.in_operating && snap.op == InputOp::None {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Input {
|
||||
pub fn paste(&mut self, opt: impl Into<Opt>) {
|
||||
#[yazi_macro::command]
|
||||
pub fn paste(&mut self, opt: Opt) {
|
||||
if let Some(start) = self.snap().op.start() {
|
||||
self.snap_mut().op = InputOp::Delete(false, false, start);
|
||||
self.handle_op(self.snap().cursor, true);
|
||||
|
|
@ -23,7 +24,6 @@ impl Input {
|
|||
return;
|
||||
}
|
||||
|
||||
let opt = opt.into() as Opt;
|
||||
self.insert(!opt.before);
|
||||
self.type_str(&s.to_string_lossy());
|
||||
self.escape(());
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Manager {
|
||||
pub fn create(&self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
#[yazi_macro::command]
|
||||
pub fn create(&self, opt: Opt) {
|
||||
let cwd = self.cwd().to_owned();
|
||||
tokio::spawn(async move {
|
||||
let mut result = InputProxy::show(InputCfg::create(opt.dir));
|
||||
|
|
|
|||
|
|
@ -12,12 +12,12 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Manager {
|
||||
pub fn hardlink(&mut self, opt: impl Into<Opt>, tasks: &Tasks) {
|
||||
#[yazi_macro::command]
|
||||
pub fn hardlink(&mut self, opt: Opt, tasks: &Tasks) {
|
||||
if self.yanked.cut {
|
||||
return;
|
||||
}
|
||||
|
||||
let opt = opt.into() as Opt;
|
||||
tasks.file_hardlink(&self.yanked, self.cwd(), opt.force, opt.follow);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ impl From<Option<Url>> for Opt {
|
|||
}
|
||||
|
||||
impl Manager {
|
||||
pub fn hover(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
#[yazi_macro::command]
|
||||
pub fn hover(&mut self, opt: Opt) {
|
||||
if let Some(u) = opt.url {
|
||||
self.hover_do(u, opt.tab);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -12,12 +12,12 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Manager {
|
||||
pub fn link(&mut self, opt: impl Into<Opt>, tasks: &Tasks) {
|
||||
#[yazi_macro::command]
|
||||
pub fn link(&mut self, opt: Opt, tasks: &Tasks) {
|
||||
if self.yanked.cut {
|
||||
return;
|
||||
}
|
||||
|
||||
let opt = opt.into() as Opt;
|
||||
tasks.file_link(&self.yanked, self.cwd(), opt.relative, opt.force);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Manager {
|
||||
pub fn open(&mut self, opt: impl Into<Opt>, tasks: &Tasks) {
|
||||
#[yazi_macro::command]
|
||||
pub fn open(&mut self, opt: Opt, tasks: &Tasks) {
|
||||
if !self.active_mut().try_escape_visual() {
|
||||
return;
|
||||
}
|
||||
|
|
@ -31,7 +32,6 @@ impl Manager {
|
|||
return;
|
||||
};
|
||||
|
||||
let opt = opt.into() as Opt;
|
||||
let selected =
|
||||
if opt.hovered { vec![&hovered] } else { self.selected_or_hovered(true).collect() };
|
||||
|
||||
|
|
@ -72,8 +72,8 @@ impl Manager {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn open_do(&mut self, opt: impl Into<OpenDoOpt>, tasks: &Tasks) {
|
||||
let opt = opt.into() as OpenDoOpt;
|
||||
#[yazi_macro::command]
|
||||
pub fn open_do(&mut self, opt: OpenDoOpt, tasks: &Tasks) {
|
||||
let targets: Vec<_> = opt
|
||||
.targets
|
||||
.into_iter()
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Manager {
|
||||
pub fn paste(&mut self, opt: impl Into<Opt>, tasks: &Tasks) {
|
||||
let opt = opt.into() as Opt;
|
||||
#[yazi_macro::command]
|
||||
pub fn paste(&mut self, opt: Opt, tasks: &Tasks) {
|
||||
let (src, dest) = (self.yanked.iter().collect::<Vec<_>>(), self.cwd());
|
||||
|
||||
if self.yanked.cut {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ impl From<bool> for Opt {
|
|||
}
|
||||
|
||||
impl Manager {
|
||||
pub fn peek(&mut self, opt: impl Into<Opt>) {
|
||||
#[yazi_macro::command]
|
||||
pub fn peek(&mut self, opt: Opt) {
|
||||
let Some(hovered) = self.hovered().cloned() else {
|
||||
return self.active_mut().preview.reset();
|
||||
};
|
||||
|
|
@ -40,7 +41,6 @@ impl Manager {
|
|||
self.active_mut().preview.reset();
|
||||
}
|
||||
|
||||
let opt = opt.into() as Opt;
|
||||
if matches!(opt.only_if, Some(u) if u != hovered.url) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,9 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Manager {
|
||||
pub fn quit(&self, opt: impl Into<Opt>, tasks: &Tasks) {
|
||||
let opt = EventQuit { no_cwd_file: opt.into().no_cwd_file, ..Default::default() };
|
||||
#[yazi_macro::command]
|
||||
pub fn quit(&self, opt: Opt, tasks: &Tasks) {
|
||||
let opt = EventQuit { no_cwd_file: opt.no_cwd_file, ..Default::default() };
|
||||
|
||||
let ongoing = tasks.ongoing().clone();
|
||||
let (left, left_names) = {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Manager {
|
||||
pub fn remove(&mut self, opt: impl Into<Opt>, tasks: &Tasks) {
|
||||
#[yazi_macro::command]
|
||||
pub fn remove(&mut self, mut opt: Opt, tasks: &Tasks) {
|
||||
if !self.active_mut().try_escape_visual() {
|
||||
return;
|
||||
}
|
||||
|
|
@ -31,7 +32,6 @@ impl Manager {
|
|||
return;
|
||||
};
|
||||
|
||||
let mut opt = opt.into() as Opt;
|
||||
opt.targets = if opt.hovered {
|
||||
vec![hovered.clone()]
|
||||
} else {
|
||||
|
|
@ -55,9 +55,8 @@ impl Manager {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn remove_do(&mut self, opt: impl Into<Opt>, tasks: &Tasks) {
|
||||
let opt = opt.into() as Opt;
|
||||
|
||||
#[yazi_macro::command]
|
||||
pub fn remove_do(&mut self, opt: Opt, tasks: &Tasks) {
|
||||
self.tabs.iter_mut().for_each(|t| {
|
||||
t.selected.remove_many(&opt.targets, false);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Manager {
|
||||
pub fn rename(&mut self, opt: impl Into<Opt>) {
|
||||
#[yazi_macro::command]
|
||||
pub fn rename(&mut self, opt: Opt) {
|
||||
if !self.active_mut().try_escape_visual() {
|
||||
return;
|
||||
}
|
||||
|
|
@ -36,7 +37,6 @@ impl Manager {
|
|||
return;
|
||||
};
|
||||
|
||||
let opt = opt.into() as Opt;
|
||||
if !opt.hovered && !self.active().selected.is_empty() {
|
||||
return self.bulk_rename();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Manager {
|
||||
pub fn seek(&mut self, opt: impl Into<Opt>) {
|
||||
#[yazi_macro::command]
|
||||
pub fn seek(&mut self, opt: Opt) {
|
||||
let Some(hovered) = self.hovered() else {
|
||||
return self.active_mut().preview.reset();
|
||||
};
|
||||
|
|
@ -31,7 +32,6 @@ impl Manager {
|
|||
return self.active_mut().preview.reset();
|
||||
};
|
||||
|
||||
let opt = opt.into() as Opt;
|
||||
isolate::seek_sync(&previewer.run, hovered.clone(), opt.units);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,9 +15,8 @@ impl From<usize> for Opt {
|
|||
}
|
||||
|
||||
impl Tabs {
|
||||
pub fn close(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
|
||||
#[yazi_macro::command]
|
||||
pub fn close(&mut self, opt: Opt) {
|
||||
let len = self.items.len();
|
||||
if len < 2 || opt.idx >= len {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -28,13 +28,13 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Tabs {
|
||||
pub fn create(&mut self, opt: impl Into<Opt>) {
|
||||
#[yazi_macro::command]
|
||||
pub fn create(&mut self, opt: Opt) {
|
||||
if self.items.len() >= MAX_TABS {
|
||||
AppProxy::notify_warn("Too many tabs", "You can only open up to 9 tabs at the same time.");
|
||||
return;
|
||||
}
|
||||
|
||||
let opt = opt.into() as Opt;
|
||||
let mut tab = Tab { idx: self.cursor + 1, ..Default::default() };
|
||||
|
||||
if !opt.current {
|
||||
|
|
|
|||
|
|
@ -11,8 +11,9 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Tabs {
|
||||
pub fn swap(&mut self, opt: impl Into<Opt>) {
|
||||
let idx = self.absolute(opt.into().step);
|
||||
#[yazi_macro::command]
|
||||
pub fn swap(&mut self, opt: Opt) {
|
||||
let idx = self.absolute(opt.step);
|
||||
if idx == self.cursor {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Tabs {
|
||||
pub fn switch(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
#[yazi_macro::command]
|
||||
pub fn switch(&mut self, opt: Opt) {
|
||||
let idx = if opt.relative {
|
||||
(self.cursor as isize + opt.step).rem_euclid(self.items.len() as isize) as usize
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ impl From<()> for Opt {
|
|||
}
|
||||
|
||||
impl Manager {
|
||||
pub fn unyank(&mut self, _: impl Into<Opt>) {
|
||||
#[yazi_macro::command]
|
||||
pub fn unyank(&mut self, _: Opt) {
|
||||
self.yanked.clear();
|
||||
render!(self.yanked.catchup_revision(false));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,12 +11,13 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Manager {
|
||||
pub fn yank(&mut self, opt: impl Into<Opt>) {
|
||||
#[yazi_macro::command]
|
||||
pub fn yank(&mut self, opt: Opt) {
|
||||
if !self.active_mut().try_escape_visual() {
|
||||
return;
|
||||
}
|
||||
|
||||
self.yanked = Yanked::new(opt.into().cut, self.selected_or_hovered(false).cloned().collect());
|
||||
self.yanked = Yanked::new(opt.cut, self.selected_or_hovered(false).cloned().collect());
|
||||
render!(self.yanked.catchup_revision(true));
|
||||
|
||||
self.active_mut().escape_select();
|
||||
|
|
|
|||
|
|
@ -11,6 +11,11 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Select {
|
||||
#[yazi_macro::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()) }
|
||||
}
|
||||
|
||||
fn next(&mut self, step: usize) {
|
||||
let len = self.items.len();
|
||||
if len == 0 {
|
||||
|
|
@ -38,9 +43,4 @@ impl Select {
|
|||
|
||||
render!(old != self.cursor);
|
||||
}
|
||||
|
||||
pub fn arrow(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
if opt.step > 0 { self.next(opt.step as usize) } else { self.prev(opt.step.unsigned_abs()) }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ impl From<bool> for Opt {
|
|||
}
|
||||
|
||||
impl Select {
|
||||
pub fn close(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
#[yazi_macro::command]
|
||||
pub fn close(&mut self, opt: Opt) {
|
||||
if let Some(cb) = self.callback.take() {
|
||||
_ = cb.send(if opt.submit { Ok(self.cursor) } else { Err(anyhow!("canceled")) });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ impl From<isize> for Opt {
|
|||
}
|
||||
|
||||
impl Tab {
|
||||
pub fn arrow(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
#[yazi_macro::command]
|
||||
pub fn arrow(&mut self, opt: Opt) {
|
||||
if !self.current.arrow(opt.step) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,12 +29,12 @@ impl From<Url> for Opt {
|
|||
}
|
||||
|
||||
impl Tab {
|
||||
pub fn cd(&mut self, opt: impl Into<Opt>) {
|
||||
#[yazi_macro::command]
|
||||
pub fn cd(&mut self, opt: Opt) {
|
||||
if !self.try_escape_visual() {
|
||||
return;
|
||||
}
|
||||
|
||||
let opt = opt.into() as Opt;
|
||||
if opt.interactive {
|
||||
return self.cd_interactive();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Tab {
|
||||
pub fn copy(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
#[yazi_macro::command]
|
||||
pub fn copy(&mut self, opt: Opt) {
|
||||
if !self.try_escape_visual() {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Tab {
|
||||
pub fn escape(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
#[yazi_macro::command]
|
||||
pub fn escape(&mut self, opt: Opt) {
|
||||
if opt.is_empty() {
|
||||
_ = self.escape_find()
|
||||
|| self.escape_visual()
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ use std::time::Duration;
|
|||
use tokio::pin;
|
||||
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
|
||||
use yazi_config::popup::InputCfg;
|
||||
use yazi_fs::{Filter, FilterCase};
|
||||
use yazi_proxy::{InputProxy, ManagerProxy};
|
||||
use yazi_shared::{Debounce, InputError, Layer, emit, event::Cmd, render};
|
||||
use yazi_fs::FilterCase;
|
||||
use yazi_proxy::InputProxy;
|
||||
use yazi_shared::{Debounce, InputError, Layer, emit, event::Cmd};
|
||||
|
||||
use crate::tab::Tab;
|
||||
|
||||
|
|
@ -27,8 +27,8 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Tab {
|
||||
pub fn filter(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
#[yazi_macro::command]
|
||||
pub fn filter(&mut self, opt: Opt) {
|
||||
tokio::spawn(async move {
|
||||
let rx = InputProxy::show(InputCfg::filter());
|
||||
|
||||
|
|
@ -49,32 +49,4 @@ impl Tab {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn filter_do(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
|
||||
let filter = if opt.query.is_empty() {
|
||||
None
|
||||
} else if let Ok(f) = Filter::new(&opt.query, opt.case) {
|
||||
Some(f)
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
|
||||
if opt.done {
|
||||
ManagerProxy::update_paged(); // Update for paged files in next loop
|
||||
}
|
||||
|
||||
let hovered = self.current.hovered().map(|f| f.urn_owned());
|
||||
if !self.current.files.set_filter(filter) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.current.repos(hovered.as_ref().map(|u| u.as_urn()));
|
||||
if self.current.hovered().map(|f| f.urn()) != hovered.as_ref().map(|u| u.as_urn()) {
|
||||
ManagerProxy::hover(None, self.idx);
|
||||
}
|
||||
|
||||
render!();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
35
yazi-core/src/tab/commands/filter_do.rs
Normal file
35
yazi-core/src/tab/commands/filter_do.rs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
use yazi_fs::Filter;
|
||||
use yazi_proxy::ManagerProxy;
|
||||
use yazi_shared::render;
|
||||
|
||||
use super::filter::Opt;
|
||||
use crate::tab::Tab;
|
||||
|
||||
impl Tab {
|
||||
#[yazi_macro::command]
|
||||
pub fn filter_do(&mut self, opt: Opt) {
|
||||
let filter = if opt.query.is_empty() {
|
||||
None
|
||||
} else if let Ok(f) = Filter::new(&opt.query, opt.case) {
|
||||
Some(f)
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
|
||||
if opt.done {
|
||||
ManagerProxy::update_paged(); // Update for paged files in next loop
|
||||
}
|
||||
|
||||
let hovered = self.current.hovered().map(|f| f.urn_owned());
|
||||
if !self.current.files.set_filter(filter) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.current.repos(hovered.as_ref().map(|u| u.as_urn()));
|
||||
if self.current.hovered().map(|f| f.urn()) != hovered.as_ref().map(|u| u.as_urn()) {
|
||||
ManagerProxy::hover(None, self.idx);
|
||||
}
|
||||
|
||||
render!();
|
||||
}
|
||||
}
|
||||
|
|
@ -5,14 +5,14 @@ use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
|
|||
use yazi_config::popup::InputCfg;
|
||||
use yazi_fs::FilterCase;
|
||||
use yazi_proxy::InputProxy;
|
||||
use yazi_shared::{Debounce, InputError, Layer, emit, event::Cmd, render};
|
||||
use yazi_shared::{Debounce, InputError, Layer, emit, event::Cmd};
|
||||
|
||||
use crate::tab::{Finder, Tab};
|
||||
use crate::tab::Tab;
|
||||
|
||||
pub struct Opt {
|
||||
query: Option<String>,
|
||||
prev: bool,
|
||||
case: FilterCase,
|
||||
pub(super) query: Option<String>,
|
||||
pub(super) prev: bool,
|
||||
pub(super) case: FilterCase,
|
||||
}
|
||||
|
||||
impl From<Cmd> for Opt {
|
||||
|
|
@ -21,17 +21,9 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct ArrowOpt {
|
||||
prev: bool,
|
||||
}
|
||||
|
||||
impl From<Cmd> for ArrowOpt {
|
||||
fn from(c: Cmd) -> Self { Self { prev: c.bool("previous") } }
|
||||
}
|
||||
|
||||
impl Tab {
|
||||
pub fn find(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
#[yazi_macro::command]
|
||||
pub fn find(&mut self, opt: Opt) {
|
||||
tokio::spawn(async move {
|
||||
let rx = InputProxy::show(InputCfg::find(opt.prev));
|
||||
|
||||
|
|
@ -49,48 +41,4 @@ impl Tab {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn find_do(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
let Some(query) = opt.query else {
|
||||
return;
|
||||
};
|
||||
if query.is_empty() {
|
||||
self.escape_find();
|
||||
return;
|
||||
}
|
||||
|
||||
let Ok(finder) = Finder::new(&query, opt.case) else {
|
||||
return;
|
||||
};
|
||||
if matches!(&self.finder, Some(f) if f.filter == finder.filter) {
|
||||
return;
|
||||
}
|
||||
|
||||
let step = if opt.prev {
|
||||
finder.prev(&self.current.files, self.current.cursor, true)
|
||||
} else {
|
||||
finder.next(&self.current.files, self.current.cursor, true)
|
||||
};
|
||||
|
||||
if let Some(step) = step {
|
||||
self.arrow(step);
|
||||
}
|
||||
|
||||
self.finder = Some(finder);
|
||||
render!();
|
||||
}
|
||||
|
||||
pub fn find_arrow(&mut self, opt: impl Into<ArrowOpt>) {
|
||||
let Some(finder) = &mut self.finder else {
|
||||
return;
|
||||
};
|
||||
|
||||
render!(finder.catchup(&self.current.files));
|
||||
if opt.into().prev {
|
||||
finder.prev(&self.current.files, self.current.cursor, false).map(|s| self.arrow(s));
|
||||
} else {
|
||||
finder.next(&self.current.files, self.current.cursor, false).map(|s| self.arrow(s));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
27
yazi-core/src/tab/commands/find_arrow.rs
Normal file
27
yazi-core/src/tab/commands/find_arrow.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
use yazi_shared::{event::Cmd, render};
|
||||
|
||||
use crate::tab::Tab;
|
||||
|
||||
pub struct Opt {
|
||||
prev: bool,
|
||||
}
|
||||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(c: Cmd) -> Self { Self { prev: c.bool("previous") } }
|
||||
}
|
||||
|
||||
impl Tab {
|
||||
#[yazi_macro::command]
|
||||
pub fn find_arrow(&mut self, opt: Opt) {
|
||||
let Some(finder) = &mut self.finder else {
|
||||
return;
|
||||
};
|
||||
|
||||
render!(finder.catchup(&self.current.files));
|
||||
if opt.prev {
|
||||
finder.prev(&self.current.files, self.current.cursor, false).map(|s| self.arrow(s));
|
||||
} else {
|
||||
finder.next(&self.current.files, self.current.cursor, false).map(|s| self.arrow(s));
|
||||
}
|
||||
}
|
||||
}
|
||||
37
yazi-core/src/tab/commands/find_do.rs
Normal file
37
yazi-core/src/tab/commands/find_do.rs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
use yazi_shared::render;
|
||||
|
||||
use super::find::Opt;
|
||||
use crate::tab::{Finder, Tab};
|
||||
|
||||
impl Tab {
|
||||
#[yazi_macro::command]
|
||||
pub fn find_do(&mut self, opt: Opt) {
|
||||
let Some(query) = opt.query else {
|
||||
return;
|
||||
};
|
||||
if query.is_empty() {
|
||||
self.escape_find();
|
||||
return;
|
||||
}
|
||||
|
||||
let Ok(finder) = Finder::new(&query, opt.case) else {
|
||||
return;
|
||||
};
|
||||
if matches!(&self.finder, Some(f) if f.filter == finder.filter) {
|
||||
return;
|
||||
}
|
||||
|
||||
let step = if opt.prev {
|
||||
finder.prev(&self.current.files, self.current.cursor, true)
|
||||
} else {
|
||||
finder.next(&self.current.files, self.current.cursor, true)
|
||||
};
|
||||
|
||||
if let Some(step) = step {
|
||||
self.arrow(step);
|
||||
}
|
||||
|
||||
self.finder = Some(finder);
|
||||
render!();
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,8 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Tab {
|
||||
pub fn leave(&mut self, _: impl Into<Opt>) {
|
||||
#[yazi_macro::command]
|
||||
pub fn leave(&mut self, _: Opt) {
|
||||
self
|
||||
.current
|
||||
.hovered()
|
||||
|
|
|
|||
|
|
@ -5,7 +5,10 @@ mod copy;
|
|||
mod enter;
|
||||
mod escape;
|
||||
mod filter;
|
||||
mod filter_do;
|
||||
mod find;
|
||||
mod find_arrow;
|
||||
mod find_do;
|
||||
mod forward;
|
||||
mod hidden;
|
||||
mod leave;
|
||||
|
|
|
|||
|
|
@ -22,9 +22,8 @@ impl From<Url> for Opt {
|
|||
}
|
||||
|
||||
impl Tab {
|
||||
pub fn reveal(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
|
||||
#[yazi_macro::command]
|
||||
pub fn reveal(&mut self, opt: Opt) {
|
||||
let Some(parent) = opt.target.parent_url() else {
|
||||
return;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ impl<'a> From<Cmd> for Opt<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Tab {
|
||||
pub fn select(&mut self, opt: impl Into<Opt<'a>>) {
|
||||
let opt = opt.into() as Opt;
|
||||
#[yazi_macro::command]
|
||||
pub fn select(&mut self, opt: Opt<'a>) {
|
||||
let Some(url) = opt.url.or_else(|| self.current.hovered().map(|h| Cow::Borrowed(&h.url)))
|
||||
else {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -23,9 +23,10 @@ impl From<Option<bool>> for Opt {
|
|||
}
|
||||
|
||||
impl Tab {
|
||||
pub fn select_all(&mut self, opt: impl Into<Opt>) {
|
||||
#[yazi_macro::command]
|
||||
pub fn select_all(&mut self, opt: Opt) {
|
||||
let iter = self.current.files.iter().map(|f| &f.url);
|
||||
let (removal, addition): (Vec<_>, Vec<_>) = match opt.into().state {
|
||||
let (removal, addition): (Vec<_>, Vec<_>) = match opt.state {
|
||||
Some(true) => (vec![], iter.collect()),
|
||||
Some(false) => (iter.collect(), vec![]),
|
||||
None => iter.partition(|&u| self.selected.contains_key(u)),
|
||||
|
|
|
|||
|
|
@ -13,10 +13,9 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl Tab {
|
||||
pub fn visual_mode(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
#[yazi_macro::command]
|
||||
pub fn visual_mode(&mut self, opt: Opt) {
|
||||
let idx = self.current.cursor;
|
||||
|
||||
if opt.unset {
|
||||
self.mode = Mode::Unset(idx, BTreeSet::from([idx]));
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -15,9 +15,10 @@ impl From<isize> for Opt {
|
|||
}
|
||||
|
||||
impl Tasks {
|
||||
pub fn arrow(&mut self, opt: impl Into<Opt>) {
|
||||
#[yazi_macro::command]
|
||||
pub fn arrow(&mut self, opt: Opt) {
|
||||
let old = self.cursor;
|
||||
if opt.into().step > 0 {
|
||||
if opt.step > 0 {
|
||||
self.cursor += 1;
|
||||
} else {
|
||||
self.cursor = self.cursor.saturating_sub(1);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ impl From<()> for Opt {
|
|||
}
|
||||
|
||||
impl Tasks {
|
||||
pub fn toggle(&mut self, _: impl Into<Opt>) {
|
||||
#[yazi_macro::command]
|
||||
pub fn toggle(&mut self, _: Opt) {
|
||||
self.visible = !self.visible;
|
||||
|
||||
if self.visible {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ yazi-config = { path = "../yazi-config", version = "0.3.3" }
|
|||
yazi-core = { path = "../yazi-core", version = "0.3.3" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "0.3.3" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "0.3.3" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "0.3.3" }
|
||||
yazi-plugin = { path = "../yazi-plugin", version = "0.3.3" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "0.3.3" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "0.3.3" }
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ impl From<MouseEvent> for Opt {
|
|||
}
|
||||
|
||||
impl App {
|
||||
pub(crate) fn mouse(&mut self, opt: impl Into<Opt>) {
|
||||
let event = (opt.into() as Opt).event;
|
||||
|
||||
#[yazi_macro::command]
|
||||
pub fn mouse(&mut self, opt: Opt) {
|
||||
let event = opt.event;
|
||||
let Some(size) = self.term.as_ref().and_then(|t| t.size().ok()) else { return };
|
||||
let Ok(evt) = yazi_plugin::bindings::MouseEvent::cast(&LUA, event) else { return };
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ impl From<()> for Opt {
|
|||
}
|
||||
|
||||
impl App {
|
||||
pub(crate) fn resize(&mut self, _: impl Into<Opt>) {
|
||||
#[yazi_macro::command]
|
||||
pub fn resize(&mut self, _: Opt) {
|
||||
self.cx.manager.active_mut().preview.reset();
|
||||
self.render();
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ impl From<Cmd> for Opt {
|
|||
}
|
||||
|
||||
impl App {
|
||||
pub(crate) fn stop(&mut self, opt: impl Into<Opt>) {
|
||||
#[yazi_macro::command]
|
||||
pub fn stop(&mut self, opt: Opt) {
|
||||
self.cx.manager.active_mut().preview.reset_image();
|
||||
|
||||
// We need to destroy the `term` first before stopping the `signals`
|
||||
|
|
@ -20,6 +21,6 @@ impl App {
|
|||
// while the app is being suspended.
|
||||
self.term = None;
|
||||
|
||||
self.signals.stop(opt.into().tx);
|
||||
self.signals.stop(opt.tx);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
17
yazi-macro/Cargo.toml
Normal file
17
yazi-macro/Cargo.toml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
[package]
|
||||
name = "yazi-macro"
|
||||
version = "0.3.3"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
description = "Yazi macros"
|
||||
homepage = "https://yazi-rs.github.io"
|
||||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
# External dependencies
|
||||
syn = "2.0.79"
|
||||
quote = "1.0.37"
|
||||
41
yazi-macro/src/lib.rs
Normal file
41
yazi-macro/src/lib.rs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
use proc_macro::TokenStream;
|
||||
use quote::{format_ident, quote};
|
||||
use syn::{FnArg, ItemFn};
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn command(_: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let mut f: ItemFn = syn::parse(item).unwrap();
|
||||
let mut ins = f.sig.inputs.clone();
|
||||
|
||||
// Turn `opt: Opt` into `opt: impl Into<Opt>`
|
||||
ins[1] = {
|
||||
let FnArg::Typed(opt) = &f.sig.inputs[1] else {
|
||||
panic!("Cannot find the `opt` argument in the function signature.");
|
||||
};
|
||||
|
||||
let opt_ty = &opt.ty;
|
||||
syn::parse2(quote! { opt: impl Into<#opt_ty> }).unwrap()
|
||||
};
|
||||
|
||||
// Make the original function private and add a public wrapper
|
||||
assert!(matches!(f.vis, syn::Visibility::Public(_)));
|
||||
f.vis = syn::Visibility::Inherited;
|
||||
|
||||
// Add `__` prefix to the original function name
|
||||
let name_ori = f.sig.ident;
|
||||
f.sig.ident = format_ident!("__{}", name_ori);
|
||||
let name_new = &f.sig.ident;
|
||||
|
||||
// Collect the rest of the arguments
|
||||
let rest_args = ins.iter().skip(2).map(|arg| match arg {
|
||||
FnArg::Receiver(_) => unreachable!(),
|
||||
FnArg::Typed(t) => &t.pat,
|
||||
});
|
||||
|
||||
quote! {
|
||||
#[inline]
|
||||
pub fn #name_ori(#ins) { self.#name_new(opt.into(), #(#rest_args),*); }
|
||||
#f
|
||||
}
|
||||
.into()
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue