diff --git a/Cargo.lock b/Cargo.lock index 63ac44ba..f0b2bdc9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3247,6 +3247,14 @@ dependencies = [ "yazi-shared", ] +[[package]] +name = "yazi-codegen" +version = "0.3.3" +dependencies = [ + "quote", + "syn 2.0.79", +] + [[package]] name = "yazi-config" version = "0.3.3" @@ -3287,10 +3295,10 @@ dependencies = [ "unicode-width", "yazi-adapter", "yazi-boot", + "yazi-codegen", "yazi-config", "yazi-dds", "yazi-fs", - "yazi-macro", "yazi-plugin", "yazi-proxy", "yazi-scheduler", @@ -3339,11 +3347,11 @@ dependencies = [ "tracing-subscriber", "yazi-adapter", "yazi-boot", + "yazi-codegen", "yazi-config", "yazi-core", "yazi-dds", "yazi-fs", - "yazi-macro", "yazi-plugin", "yazi-proxy", "yazi-shared", @@ -3366,10 +3374,6 @@ dependencies = [ [[package]] name = "yazi-macro" version = "0.3.3" -dependencies = [ - "quote", - "syn 2.0.79", -] [[package]] name = "yazi-plugin" @@ -3460,6 +3464,7 @@ dependencies = [ "tokio", "uzers", "windows-sys 0.59.0", + "yazi-macro", ] [[package]] diff --git a/cspell.json b/cspell.json index c7af4498..c24a9b1f 100644 --- a/cspell.json +++ b/cspell.json @@ -1 +1 @@ -{"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","imagesize","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM","repeek","cwds","tcsi","Hyprland","Wayfire","SWAYSOCK"],"version":"0.2","language":"en","flagWords":[]} \ No newline at end of file +{"language":"en","words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","imagesize","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM","repeek","cwds","tcsi","Hyprland","Wayfire","SWAYSOCK","btime","nsec","codegen"],"version":"0.2","flagWords":[]} \ No newline at end of file diff --git a/yazi-adapter/src/emulator.rs b/yazi-adapter/src/emulator.rs index 6d172a00..6b351b52 100644 --- a/yazi-adapter/src/emulator.rs +++ b/yazi-adapter/src/emulator.rs @@ -113,10 +113,11 @@ impl Emulator { } let mut term = std::env::var("TERM").unwrap_or_default(); - let program = std::env::var("TERM_PROGRAM").unwrap_or_default(); + let mut program = std::env::var("TERM_PROGRAM").unwrap_or_default(); if *TMUX { term = tmux_env("TERM").unwrap_or(term); + program = tmux_env("TERM_PROGRAM").unwrap_or(program); } (term, program) diff --git a/yazi-codegen/Cargo.toml b/yazi-codegen/Cargo.toml new file mode 100644 index 00000000..537b5e9c --- /dev/null +++ b/yazi-codegen/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "yazi-codegen" +version = "0.3.3" +edition = "2021" +license = "MIT" +authors = [ "sxyazi " ] +description = "Yazi codegen" +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" diff --git a/yazi-codegen/src/lib.rs b/yazi-codegen/src/lib.rs new file mode 100644 index 00000000..e1c930bf --- /dev/null +++ b/yazi-codegen/src/lib.rs @@ -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` + 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() +} diff --git a/yazi-config/preset/keymap.toml b/yazi-config/preset/keymap.toml index 3236ebaf..9dabc302 100644 --- a/yazi-config/preset/keymap.toml +++ b/yazi-config/preset/keymap.toml @@ -83,7 +83,7 @@ keymap = [ # Linemode { on = [ "m", "s" ], run = "linemode size", desc = "Linemode: size" }, { on = [ "m", "p" ], run = "linemode permissions", desc = "Linemode: permissions" }, - { on = [ "m", "c" ], run = "linemode ctime", desc = "Linemode: ctime" }, + { on = [ "m", "b" ], run = "linemode btime", desc = "Linemode: btime" }, { on = [ "m", "m" ], run = "linemode mtime", desc = "Linemode: mtime" }, { on = [ "m", "o" ], run = "linemode owner", desc = "Linemode: owner" }, { on = [ "m", "n" ], run = "linemode none", desc = "Linemode: none" }, @@ -104,19 +104,19 @@ keymap = [ { on = "N", run = "find_arrow --previous", desc = "Goto the previous found" }, # Sorting - { on = [ ",", "m" ], run = [ "sort modified --reverse=no", "linemode mtime" ], desc = "Sort by modified time" }, - { on = [ ",", "M" ], run = [ "sort modified --reverse", "linemode mtime" ], desc = "Sort by modified time (reverse)" }, - { on = [ ",", "c" ], run = [ "sort created --reverse=no", "linemode ctime" ], desc = "Sort by created time" }, - { on = [ ",", "C" ], run = [ "sort created --reverse", "linemode ctime" ], desc = "Sort by created time (reverse)" }, - { on = [ ",", "e" ], run = "sort extension --reverse=no", desc = "Sort by extension" }, - { on = [ ",", "E" ], run = "sort extension --reverse", desc = "Sort by extension (reverse)" }, - { on = [ ",", "a" ], run = "sort alphabetical --reverse=no", desc = "Sort alphabetically" }, - { on = [ ",", "A" ], run = "sort alphabetical --reverse", desc = "Sort alphabetically (reverse)" }, - { on = [ ",", "n" ], run = "sort natural --reverse=no", desc = "Sort naturally" }, - { on = [ ",", "N" ], run = "sort natural --reverse", desc = "Sort naturally (reverse)" }, - { on = [ ",", "s" ], run = [ "sort size --reverse=no", "linemode size" ], desc = "Sort by size" }, - { on = [ ",", "S" ], run = [ "sort size --reverse", "linemode size" ], desc = "Sort by size (reverse)" }, - { on = [ ",", "r" ], run = "sort random --reverse=no", desc = "Sort randomly" }, + { on = [ ",", "m" ], run = [ "sort mtime --reverse=no", "linemode mtime" ], desc = "Sort by modified time" }, + { on = [ ",", "M" ], run = [ "sort mtime --reverse", "linemode mtime" ], desc = "Sort by modified time (reverse)" }, + { on = [ ",", "b" ], run = [ "sort btime --reverse=no", "linemode btime" ], desc = "Sort by birth time" }, + { on = [ ",", "B" ], run = [ "sort btime --reverse", "linemode btime" ], desc = "Sort by birth time (reverse)" }, + { on = [ ",", "e" ], run = "sort extension --reverse=no", desc = "Sort by extension" }, + { on = [ ",", "E" ], run = "sort extension --reverse", desc = "Sort by extension (reverse)" }, + { on = [ ",", "a" ], run = "sort alphabetical --reverse=no", desc = "Sort alphabetically" }, + { on = [ ",", "A" ], run = "sort alphabetical --reverse", desc = "Sort alphabetically (reverse)" }, + { on = [ ",", "n" ], run = "sort natural --reverse=no", desc = "Sort naturally" }, + { on = [ ",", "N" ], run = "sort natural --reverse", desc = "Sort naturally (reverse)" }, + { on = [ ",", "s" ], run = [ "sort size --reverse=no", "linemode size" ], desc = "Sort by size" }, + { on = [ ",", "S" ], run = [ "sort size --reverse", "linemode size" ], desc = "Sort by size (reverse)" }, + { on = [ ",", "r" ], run = "sort random --reverse=no", desc = "Sort randomly" }, # Goto { on = [ "g", "h" ], run = "cd ~", desc = "Go home" }, diff --git a/yazi-config/src/manager/sorting.rs b/yazi-config/src/manager/sorting.rs index 648efb87..0ae94a28 100644 --- a/yazi-config/src/manager/sorting.rs +++ b/yazi-config/src/manager/sorting.rs @@ -8,8 +8,8 @@ use serde::{Deserialize, Serialize}; pub enum SortBy { #[default] None, - Modified, - Created, + Mtime, + Btime, Extension, Alphabetical, Natural, @@ -23,8 +23,8 @@ impl FromStr for SortBy { fn from_str(s: &str) -> Result { Ok(match s { "none" => Self::None, - "modified" => Self::Modified, - "created" => Self::Created, + "mtime" => Self::Mtime, + "btime" => Self::Btime, "extension" => Self::Extension, "alphabetical" => Self::Alphabetical, "natural" => Self::Natural, @@ -45,8 +45,8 @@ impl Display for SortBy { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(match self { Self::None => "none", - Self::Modified => "modified", - Self::Created => "created", + Self::Mtime => "mtime", + Self::Btime => "btime", Self::Extension => "extension", Self::Alphabetical => "alphabetical", Self::Natural => "natural", diff --git a/yazi-core/Cargo.toml b/yazi-core/Cargo.toml index f0331b6c..b058b4fe 100644 --- a/yazi-core/Cargo.toml +++ b/yazi-core/Cargo.toml @@ -11,10 +11,10 @@ repository = "https://github.com/sxyazi/yazi" [dependencies] yazi-adapter = { path = "../yazi-adapter", version = "0.3.3" } yazi-boot = { path = "../yazi-boot", version = "0.3.3" } +yazi-codegen = { path = "../yazi-codegen", 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" } diff --git a/yazi-core/src/completion/commands/arrow.rs b/yazi-core/src/completion/commands/arrow.rs index 78e9894e..35860b4b 100644 --- a/yazi-core/src/completion/commands/arrow.rs +++ b/yazi-core/src/completion/commands/arrow.rs @@ -11,7 +11,7 @@ impl From for Opt { } impl Completion { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn arrow(&mut self, opt: Opt) { if opt.step > 0 { self.next(opt.step as usize); diff --git a/yazi-core/src/completion/commands/close.rs b/yazi-core/src/completion/commands/close.rs index 476c9125..c7008d1a 100644 --- a/yazi-core/src/completion/commands/close.rs +++ b/yazi-core/src/completion/commands/close.rs @@ -15,7 +15,7 @@ impl From for Opt { } impl Completion { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn close(&mut self, opt: Opt) { if let Some(s) = self.selected().filter(|_| opt.submit) { InputProxy::complete(s, self.ticket); diff --git a/yazi-core/src/completion/commands/show.rs b/yazi-core/src/completion/commands/show.rs index e25e8407..cc0a3cff 100644 --- a/yazi-core/src/completion/commands/show.rs +++ b/yazi-core/src/completion/commands/show.rs @@ -25,7 +25,7 @@ impl From for Opt { } impl Completion { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn show(&mut self, opt: Opt) { if self.ticket != opt.ticket { return; diff --git a/yazi-core/src/completion/commands/trigger.rs b/yazi-core/src/completion/commands/trigger.rs index 86821144..76303359 100644 --- a/yazi-core/src/completion/commands/trigger.rs +++ b/yazi-core/src/completion/commands/trigger.rs @@ -26,7 +26,7 @@ impl From for Opt { } impl Completion { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn trigger(&mut self, opt: Opt) { if opt.ticket < self.ticket { return; diff --git a/yazi-core/src/confirm/commands/arrow.rs b/yazi-core/src/confirm/commands/arrow.rs index 1fe6ce96..76ba73d7 100644 --- a/yazi-core/src/confirm/commands/arrow.rs +++ b/yazi-core/src/confirm/commands/arrow.rs @@ -11,7 +11,7 @@ impl From for Opt { } impl Confirm { - #[yazi_macro::command] + #[yazi_codegen::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) diff --git a/yazi-core/src/confirm/commands/close.rs b/yazi-core/src/confirm/commands/close.rs index 9c6862cd..d2fdd809 100644 --- a/yazi-core/src/confirm/commands/close.rs +++ b/yazi-core/src/confirm/commands/close.rs @@ -14,7 +14,7 @@ impl From for Opt { } impl Confirm { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn close(&mut self, opt: Opt) { if let Some(cb) = self.callback.take() { _ = cb.send(opt.submit); diff --git a/yazi-core/src/help/commands/arrow.rs b/yazi-core/src/help/commands/arrow.rs index b8766e3c..e608fe29 100644 --- a/yazi-core/src/help/commands/arrow.rs +++ b/yazi-core/src/help/commands/arrow.rs @@ -14,7 +14,7 @@ impl From for Opt { } impl Help { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn arrow(&mut self, opt: Opt) { let max = self.bindings.len().saturating_sub(1); self.offset = self.offset.min(max); diff --git a/yazi-core/src/input/commands/backspace.rs b/yazi-core/src/input/commands/backspace.rs index e2d2310d..525f2a31 100644 --- a/yazi-core/src/input/commands/backspace.rs +++ b/yazi-core/src/input/commands/backspace.rs @@ -14,7 +14,7 @@ impl From for Opt { } impl Input { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn backspace(&mut self, opt: Opt) { let snap = self.snaps.current_mut(); if !opt.under && snap.cursor < 1 { diff --git a/yazi-core/src/input/commands/close.rs b/yazi-core/src/input/commands/close.rs index eab0e519..5105f550 100644 --- a/yazi-core/src/input/commands/close.rs +++ b/yazi-core/src/input/commands/close.rs @@ -15,7 +15,7 @@ impl From for Opt { } impl Input { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn close(&mut self, opt: Opt) { if self.completion { CompletionProxy::close(); diff --git a/yazi-core/src/input/commands/complete.rs b/yazi-core/src/input/commands/complete.rs index 0b26808b..21222ce0 100644 --- a/yazi-core/src/input/commands/complete.rs +++ b/yazi-core/src/input/commands/complete.rs @@ -25,7 +25,7 @@ impl From for Opt { } impl Input { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn complete(&mut self, opt: Opt) { if self.ticket != opt.ticket { return; diff --git a/yazi-core/src/input/commands/delete.rs b/yazi-core/src/input/commands/delete.rs index a704fae7..ef9203a2 100644 --- a/yazi-core/src/input/commands/delete.rs +++ b/yazi-core/src/input/commands/delete.rs @@ -12,7 +12,7 @@ impl From for Opt { } impl Input { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn delete(&mut self, opt: Opt) { match self.snap().op { InputOp::None => { diff --git a/yazi-core/src/input/commands/escape.rs b/yazi-core/src/input/commands/escape.rs index fc60696d..5643710c 100644 --- a/yazi-core/src/input/commands/escape.rs +++ b/yazi-core/src/input/commands/escape.rs @@ -13,7 +13,7 @@ impl From<()> for Opt { } impl Input { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn escape(&mut self, _: Opt) { let snap = self.snap_mut(); match snap.mode { diff --git a/yazi-core/src/input/commands/forward.rs b/yazi-core/src/input/commands/forward.rs index 5a058d90..d3bf8026 100644 --- a/yazi-core/src/input/commands/forward.rs +++ b/yazi-core/src/input/commands/forward.rs @@ -11,7 +11,7 @@ impl From for Opt { } impl Input { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn forward(&mut self, opt: Opt) { let snap = self.snap(); diff --git a/yazi-core/src/input/commands/insert.rs b/yazi-core/src/input/commands/insert.rs index 525ed700..76a519d4 100644 --- a/yazi-core/src/input/commands/insert.rs +++ b/yazi-core/src/input/commands/insert.rs @@ -14,7 +14,7 @@ impl From for Opt { } impl Input { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn insert(&mut self, opt: Opt) { let snap = self.snap_mut(); if snap.mode == InputMode::Normal { diff --git a/yazi-core/src/input/commands/kill.rs b/yazi-core/src/input/commands/kill.rs index a4f7fdd1..b2dd34db 100644 --- a/yazi-core/src/input/commands/kill.rs +++ b/yazi-core/src/input/commands/kill.rs @@ -13,7 +13,7 @@ impl From for Opt { } impl Input { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn kill(&mut self, opt: Opt) { let snap = self.snap_mut(); match opt.kind.as_str() { diff --git a/yazi-core/src/input/commands/move_.rs b/yazi-core/src/input/commands/move_.rs index 9b30a18d..7b52d711 100644 --- a/yazi-core/src/input/commands/move_.rs +++ b/yazi-core/src/input/commands/move_.rs @@ -21,7 +21,7 @@ impl From for Opt { } impl Input { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn move_(&mut self, opt: Opt) { let snap = self.snap(); if opt.in_operating && snap.op == InputOp::None { diff --git a/yazi-core/src/input/commands/paste.rs b/yazi-core/src/input/commands/paste.rs index fb4296b0..e03f2228 100644 --- a/yazi-core/src/input/commands/paste.rs +++ b/yazi-core/src/input/commands/paste.rs @@ -12,7 +12,7 @@ impl From for Opt { } impl Input { - #[yazi_macro::command] + #[yazi_codegen::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); diff --git a/yazi-core/src/manager/commands/create.rs b/yazi-core/src/manager/commands/create.rs index ac2963b0..ae70e481 100644 --- a/yazi-core/src/manager/commands/create.rs +++ b/yazi-core/src/manager/commands/create.rs @@ -18,7 +18,7 @@ impl From for Opt { } impl Manager { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn create(&self, opt: Opt) { let cwd = self.cwd().to_owned(); tokio::spawn(async move { diff --git a/yazi-core/src/manager/commands/hardlink.rs b/yazi-core/src/manager/commands/hardlink.rs index f2068ee4..040eb0b4 100644 --- a/yazi-core/src/manager/commands/hardlink.rs +++ b/yazi-core/src/manager/commands/hardlink.rs @@ -12,7 +12,7 @@ impl From for Opt { } impl Manager { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn hardlink(&mut self, opt: Opt, tasks: &Tasks) { if self.yanked.cut { return; diff --git a/yazi-core/src/manager/commands/hover.rs b/yazi-core/src/manager/commands/hover.rs index a2b1fcdc..e56cc580 100644 --- a/yazi-core/src/manager/commands/hover.rs +++ b/yazi-core/src/manager/commands/hover.rs @@ -23,7 +23,7 @@ impl From> for Opt { } impl Manager { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn hover(&mut self, opt: Opt) { if let Some(u) = opt.url { self.hover_do(u, opt.tab); diff --git a/yazi-core/src/manager/commands/link.rs b/yazi-core/src/manager/commands/link.rs index 6956dbc9..69864b2e 100644 --- a/yazi-core/src/manager/commands/link.rs +++ b/yazi-core/src/manager/commands/link.rs @@ -12,7 +12,7 @@ impl From for Opt { } impl Manager { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn link(&mut self, opt: Opt, tasks: &Tasks) { if self.yanked.cut { return; diff --git a/yazi-core/src/manager/commands/open.rs b/yazi-core/src/manager/commands/open.rs index fe4c13b6..e91d6475 100644 --- a/yazi-core/src/manager/commands/open.rs +++ b/yazi-core/src/manager/commands/open.rs @@ -23,7 +23,7 @@ impl From for Opt { } impl Manager { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn open(&mut self, opt: Opt, tasks: &Tasks) { if !self.active_mut().try_escape_visual() { return; @@ -72,7 +72,7 @@ impl Manager { }); } - #[yazi_macro::command] + #[yazi_codegen::command] pub fn open_do(&mut self, opt: OpenDoOpt, tasks: &Tasks) { let targets: Vec<_> = opt .targets diff --git a/yazi-core/src/manager/commands/paste.rs b/yazi-core/src/manager/commands/paste.rs index d1c754d8..ea3cca73 100644 --- a/yazi-core/src/manager/commands/paste.rs +++ b/yazi-core/src/manager/commands/paste.rs @@ -12,7 +12,7 @@ impl From for Opt { } impl Manager { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn paste(&mut self, opt: Opt, tasks: &Tasks) { let (src, dest) = (self.yanked.iter().collect::>(), self.cwd()); diff --git a/yazi-core/src/manager/commands/peek.rs b/yazi-core/src/manager/commands/peek.rs index 16726e51..6902a80e 100644 --- a/yazi-core/src/manager/commands/peek.rs +++ b/yazi-core/src/manager/commands/peek.rs @@ -25,7 +25,7 @@ impl From for Opt { } impl Manager { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn peek(&mut self, opt: Opt) { let Some(hovered) = self.hovered().cloned() else { return self.active_mut().preview.reset(); diff --git a/yazi-core/src/manager/commands/quit.rs b/yazi-core/src/manager/commands/quit.rs index f1280c53..78f1737a 100644 --- a/yazi-core/src/manager/commands/quit.rs +++ b/yazi-core/src/manager/commands/quit.rs @@ -19,7 +19,7 @@ impl From for Opt { } impl Manager { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn quit(&self, opt: Opt, tasks: &Tasks) { let opt = EventQuit { no_cwd_file: opt.no_cwd_file, ..Default::default() }; diff --git a/yazi-core/src/manager/commands/remove.rs b/yazi-core/src/manager/commands/remove.rs index c05d74da..eb693649 100644 --- a/yazi-core/src/manager/commands/remove.rs +++ b/yazi-core/src/manager/commands/remove.rs @@ -23,7 +23,7 @@ impl From for Opt { } impl Manager { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn remove(&mut self, mut opt: Opt, tasks: &Tasks) { if !self.active_mut().try_escape_visual() { return; @@ -55,7 +55,7 @@ impl Manager { }); } - #[yazi_macro::command] + #[yazi_codegen::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); diff --git a/yazi-core/src/manager/commands/rename.rs b/yazi-core/src/manager/commands/rename.rs index 154affc5..87f6cb0c 100644 --- a/yazi-core/src/manager/commands/rename.rs +++ b/yazi-core/src/manager/commands/rename.rs @@ -28,7 +28,7 @@ impl From for Opt { } impl Manager { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn rename(&mut self, opt: Opt) { if !self.active_mut().try_escape_visual() { return; diff --git a/yazi-core/src/manager/commands/seek.rs b/yazi-core/src/manager/commands/seek.rs index 402f5bc9..b486196d 100644 --- a/yazi-core/src/manager/commands/seek.rs +++ b/yazi-core/src/manager/commands/seek.rs @@ -14,7 +14,7 @@ impl From for Opt { } impl Manager { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn seek(&mut self, opt: Opt) { let Some(hovered) = self.hovered() else { return self.active_mut().preview.reset(); diff --git a/yazi-core/src/manager/commands/tab_close.rs b/yazi-core/src/manager/commands/tab_close.rs index d05b951a..b213551d 100644 --- a/yazi-core/src/manager/commands/tab_close.rs +++ b/yazi-core/src/manager/commands/tab_close.rs @@ -15,7 +15,7 @@ impl From for Opt { } impl Tabs { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn close(&mut self, opt: Opt) { let len = self.items.len(); if len < 2 || opt.idx >= len { diff --git a/yazi-core/src/manager/commands/tab_create.rs b/yazi-core/src/manager/commands/tab_create.rs index 5d2738ab..24d0c011 100644 --- a/yazi-core/src/manager/commands/tab_create.rs +++ b/yazi-core/src/manager/commands/tab_create.rs @@ -28,7 +28,7 @@ impl From for Opt { } impl Tabs { - #[yazi_macro::command] + #[yazi_codegen::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."); diff --git a/yazi-core/src/manager/commands/tab_swap.rs b/yazi-core/src/manager/commands/tab_swap.rs index a8714497..c42dfc30 100644 --- a/yazi-core/src/manager/commands/tab_swap.rs +++ b/yazi-core/src/manager/commands/tab_swap.rs @@ -11,7 +11,7 @@ impl From for Opt { } impl Tabs { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn swap(&mut self, opt: Opt) { let idx = self.absolute(opt.step); if idx == self.cursor { diff --git a/yazi-core/src/manager/commands/tab_switch.rs b/yazi-core/src/manager/commands/tab_switch.rs index a506e3bc..46273782 100644 --- a/yazi-core/src/manager/commands/tab_switch.rs +++ b/yazi-core/src/manager/commands/tab_switch.rs @@ -14,7 +14,7 @@ impl From for Opt { } impl Tabs { - #[yazi_macro::command] + #[yazi_codegen::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 diff --git a/yazi-core/src/manager/commands/unyank.rs b/yazi-core/src/manager/commands/unyank.rs index 0619ea66..e95af63c 100644 --- a/yazi-core/src/manager/commands/unyank.rs +++ b/yazi-core/src/manager/commands/unyank.rs @@ -12,7 +12,7 @@ impl From<()> for Opt { } impl Manager { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn unyank(&mut self, _: Opt) { self.yanked.clear(); render!(self.yanked.catchup_revision(false)); diff --git a/yazi-core/src/manager/commands/yank.rs b/yazi-core/src/manager/commands/yank.rs index 262b915b..88ed51b2 100644 --- a/yazi-core/src/manager/commands/yank.rs +++ b/yazi-core/src/manager/commands/yank.rs @@ -11,7 +11,7 @@ impl From for Opt { } impl Manager { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn yank(&mut self, opt: Opt) { if !self.active_mut().try_escape_visual() { return; diff --git a/yazi-core/src/select/commands/arrow.rs b/yazi-core/src/select/commands/arrow.rs index 29570b8c..2b7008fb 100644 --- a/yazi-core/src/select/commands/arrow.rs +++ b/yazi-core/src/select/commands/arrow.rs @@ -11,7 +11,7 @@ impl From for Opt { } impl Select { - #[yazi_macro::command] + #[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/select/commands/close.rs index bb7c43ec..ffd0af57 100644 --- a/yazi-core/src/select/commands/close.rs +++ b/yazi-core/src/select/commands/close.rs @@ -15,7 +15,7 @@ impl From for Opt { } impl Select { - #[yazi_macro::command] + #[yazi_codegen::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")) }); diff --git a/yazi-core/src/tab/commands/arrow.rs b/yazi-core/src/tab/commands/arrow.rs index 0d76d9bd..6f805e77 100644 --- a/yazi-core/src/tab/commands/arrow.rs +++ b/yazi-core/src/tab/commands/arrow.rs @@ -25,7 +25,7 @@ impl From for Opt { } impl Tab { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn arrow(&mut self, opt: Opt) { if !self.current.arrow(opt.step) { return; diff --git a/yazi-core/src/tab/commands/cd.rs b/yazi-core/src/tab/commands/cd.rs index 667a7484..130ff208 100644 --- a/yazi-core/src/tab/commands/cd.rs +++ b/yazi-core/src/tab/commands/cd.rs @@ -29,7 +29,7 @@ impl From for Opt { } impl Tab { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn cd(&mut self, opt: Opt) { if !self.try_escape_visual() { return; diff --git a/yazi-core/src/tab/commands/copy.rs b/yazi-core/src/tab/commands/copy.rs index 3effedb0..ea8fed4d 100644 --- a/yazi-core/src/tab/commands/copy.rs +++ b/yazi-core/src/tab/commands/copy.rs @@ -14,7 +14,7 @@ impl From for Opt { } impl Tab { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn copy(&mut self, opt: Opt) { if !self.try_escape_visual() { return; diff --git a/yazi-core/src/tab/commands/escape.rs b/yazi-core/src/tab/commands/escape.rs index b7035820..10fe02dd 100644 --- a/yazi-core/src/tab/commands/escape.rs +++ b/yazi-core/src/tab/commands/escape.rs @@ -31,7 +31,7 @@ impl From for Opt { } impl Tab { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn escape(&mut self, opt: Opt) { if opt.is_empty() { _ = self.escape_find() diff --git a/yazi-core/src/tab/commands/filter.rs b/yazi-core/src/tab/commands/filter.rs index 786ecbc8..b7b46efc 100644 --- a/yazi-core/src/tab/commands/filter.rs +++ b/yazi-core/src/tab/commands/filter.rs @@ -27,7 +27,7 @@ impl From for Opt { } impl Tab { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn filter(&mut self, opt: Opt) { tokio::spawn(async move { let rx = InputProxy::show(InputCfg::filter()); diff --git a/yazi-core/src/tab/commands/filter_do.rs b/yazi-core/src/tab/commands/filter_do.rs index 30f7d609..cc1fad7f 100644 --- a/yazi-core/src/tab/commands/filter_do.rs +++ b/yazi-core/src/tab/commands/filter_do.rs @@ -6,7 +6,7 @@ use super::filter::Opt; use crate::tab::Tab; impl Tab { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn filter_do(&mut self, opt: Opt) { let filter = if opt.query.is_empty() { None diff --git a/yazi-core/src/tab/commands/find.rs b/yazi-core/src/tab/commands/find.rs index ded0ed07..24a79657 100644 --- a/yazi-core/src/tab/commands/find.rs +++ b/yazi-core/src/tab/commands/find.rs @@ -22,7 +22,7 @@ impl From for Opt { } impl Tab { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn find(&mut self, opt: Opt) { tokio::spawn(async move { let rx = InputProxy::show(InputCfg::find(opt.prev)); diff --git a/yazi-core/src/tab/commands/find_arrow.rs b/yazi-core/src/tab/commands/find_arrow.rs index 51d4f02f..6c217993 100644 --- a/yazi-core/src/tab/commands/find_arrow.rs +++ b/yazi-core/src/tab/commands/find_arrow.rs @@ -11,7 +11,7 @@ impl From for Opt { } impl Tab { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn find_arrow(&mut self, opt: Opt) { let Some(finder) = &mut self.finder else { return; diff --git a/yazi-core/src/tab/commands/find_do.rs b/yazi-core/src/tab/commands/find_do.rs index 8d8796f4..b6d41d51 100644 --- a/yazi-core/src/tab/commands/find_do.rs +++ b/yazi-core/src/tab/commands/find_do.rs @@ -4,7 +4,7 @@ use super::find::Opt; use crate::tab::{Finder, Tab}; impl Tab { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn find_do(&mut self, opt: Opt) { let Some(query) = opt.query else { return; diff --git a/yazi-core/src/tab/commands/leave.rs b/yazi-core/src/tab/commands/leave.rs index ac7fa4eb..529a28be 100644 --- a/yazi-core/src/tab/commands/leave.rs +++ b/yazi-core/src/tab/commands/leave.rs @@ -11,7 +11,7 @@ impl From for Opt { } impl Tab { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn leave(&mut self, _: Opt) { self .current diff --git a/yazi-core/src/tab/commands/reveal.rs b/yazi-core/src/tab/commands/reveal.rs index 4d2aba1c..5365e82e 100644 --- a/yazi-core/src/tab/commands/reveal.rs +++ b/yazi-core/src/tab/commands/reveal.rs @@ -22,7 +22,7 @@ impl From for Opt { } impl Tab { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn reveal(&mut self, opt: Opt) { let Some(parent) = opt.target.parent_url() else { return; diff --git a/yazi-core/src/tab/commands/select.rs b/yazi-core/src/tab/commands/select.rs index 5eccb283..5968c339 100644 --- a/yazi-core/src/tab/commands/select.rs +++ b/yazi-core/src/tab/commands/select.rs @@ -24,7 +24,7 @@ impl<'a> From for Opt<'a> { } impl<'a> Tab { - #[yazi_macro::command] + #[yazi_codegen::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 { diff --git a/yazi-core/src/tab/commands/select_all.rs b/yazi-core/src/tab/commands/select_all.rs index 26c8976a..c5620247 100644 --- a/yazi-core/src/tab/commands/select_all.rs +++ b/yazi-core/src/tab/commands/select_all.rs @@ -23,7 +23,7 @@ impl From> for Opt { } impl Tab { - #[yazi_macro::command] + #[yazi_codegen::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.state { diff --git a/yazi-core/src/tab/commands/visual_mode.rs b/yazi-core/src/tab/commands/visual_mode.rs index 57e148aa..6593da4b 100644 --- a/yazi-core/src/tab/commands/visual_mode.rs +++ b/yazi-core/src/tab/commands/visual_mode.rs @@ -13,7 +13,7 @@ impl From for Opt { } impl Tab { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn visual_mode(&mut self, opt: Opt) { let idx = self.current.cursor; if opt.unset { diff --git a/yazi-core/src/tasks/commands/arrow.rs b/yazi-core/src/tasks/commands/arrow.rs index efd21490..6222a637 100644 --- a/yazi-core/src/tasks/commands/arrow.rs +++ b/yazi-core/src/tasks/commands/arrow.rs @@ -15,7 +15,7 @@ impl From for Opt { } impl Tasks { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn arrow(&mut self, opt: Opt) { let old = self.cursor; if opt.step > 0 { diff --git a/yazi-core/src/tasks/commands/toggle.rs b/yazi-core/src/tasks/commands/toggle.rs index f2d44a8d..46aade38 100644 --- a/yazi-core/src/tasks/commands/toggle.rs +++ b/yazi-core/src/tasks/commands/toggle.rs @@ -12,7 +12,7 @@ impl From<()> for Opt { } impl Tasks { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn toggle(&mut self, _: Opt) { self.visible = !self.visible; diff --git a/yazi-fm/Cargo.toml b/yazi-fm/Cargo.toml index 1b2f511d..75aad875 100644 --- a/yazi-fm/Cargo.toml +++ b/yazi-fm/Cargo.toml @@ -15,11 +15,11 @@ vendored-lua = [ "mlua/vendored" ] [dependencies] yazi-adapter = { path = "../yazi-adapter", version = "0.3.3" } yazi-boot = { path = "../yazi-boot", version = "0.3.3" } +yazi-codegen = { path = "../yazi-codegen", version = "0.3.3" } 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" } diff --git a/yazi-fm/src/app/commands/mouse.rs b/yazi-fm/src/app/commands/mouse.rs index 528584a9..152838d6 100644 --- a/yazi-fm/src/app/commands/mouse.rs +++ b/yazi-fm/src/app/commands/mouse.rs @@ -15,7 +15,7 @@ impl From for Opt { } impl App { - #[yazi_macro::command] + #[yazi_codegen::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 }; diff --git a/yazi-fm/src/app/commands/resize.rs b/yazi-fm/src/app/commands/resize.rs index 1bdabc95..83a6843f 100644 --- a/yazi-fm/src/app/commands/resize.rs +++ b/yazi-fm/src/app/commands/resize.rs @@ -13,7 +13,7 @@ impl From<()> for Opt { } impl App { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn resize(&mut self, _: Opt) { self.cx.manager.active_mut().preview.reset(); self.render(); diff --git a/yazi-fm/src/app/commands/stop.rs b/yazi-fm/src/app/commands/stop.rs index 62a0b312..ac7f63fa 100644 --- a/yazi-fm/src/app/commands/stop.rs +++ b/yazi-fm/src/app/commands/stop.rs @@ -12,7 +12,7 @@ impl From for Opt { } impl App { - #[yazi_macro::command] + #[yazi_codegen::command] pub fn stop(&mut self, opt: Opt) { self.cx.manager.active_mut().preview.reset_image(); diff --git a/yazi-fs/src/sorter.rs b/yazi-fs/src/sorter.rs index 5e597839..59cd87a5 100644 --- a/yazi-fs/src/sorter.rs +++ b/yazi-fs/src/sorter.rs @@ -28,12 +28,12 @@ impl FilesSorter { match self.by { SortBy::None => {} - SortBy::Modified => items.sort_unstable_by(|a, b| { + SortBy::Mtime => items.sort_unstable_by(|a, b| { let ord = self.cmp(a.mtime, b.mtime, self.promote(a, b)); if ord == Ordering::Equal { by_alphabetical(a, b) } else { ord } }), - SortBy::Created => items.sort_unstable_by(|a, b| { - let ord = self.cmp(a.ctime, b.ctime, self.promote(a, b)); + SortBy::Btime => items.sort_unstable_by(|a, b| { + let ord = self.cmp(a.btime, b.btime, self.promote(a, b)); if ord == Ordering::Equal { by_alphabetical(a, b) } else { ord } }), SortBy::Extension => items.sort_unstable_by(|a, b| { diff --git a/yazi-macro/Cargo.toml b/yazi-macro/Cargo.toml index 25ed4744..13177518 100644 --- a/yazi-macro/Cargo.toml +++ b/yazi-macro/Cargo.toml @@ -7,11 +7,3 @@ authors = [ "sxyazi " ] 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" diff --git a/yazi-macro/src/lib.rs b/yazi-macro/src/lib.rs index e1c930bf..621e15f8 100644 --- a/yazi-macro/src/lib.rs +++ b/yazi-macro/src/lib.rs @@ -1,41 +1,2 @@ -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` - 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() -} +mod module; +mod platform; diff --git a/yazi-macro/src/module.rs b/yazi-macro/src/module.rs new file mode 100644 index 00000000..dc3ed1e2 --- /dev/null +++ b/yazi-macro/src/module.rs @@ -0,0 +1,9 @@ +#[macro_export] +macro_rules! mod_use { + [ $( $name:ident $(,)? )+ ] => { + $( + mod $name; + pub use $name::*; + )+ + }; +} diff --git a/yazi-macro/src/platform.rs b/yazi-macro/src/platform.rs new file mode 100644 index 00000000..c5604e6b --- /dev/null +++ b/yazi-macro/src/platform.rs @@ -0,0 +1,13 @@ +#[macro_export] +macro_rules! unix_either { + ($a:expr, $b:expr) => {{ + #[cfg(unix)] + { + $a + } + #[cfg(not(unix))] + { + $b + } + }}; +} diff --git a/yazi-plugin/preset/components/linemode.lua b/yazi-plugin/preset/components/linemode.lua index 2ca2b881..42c26008 100644 --- a/yazi-plugin/preset/components/linemode.lua +++ b/yazi-plugin/preset/components/linemode.lua @@ -32,8 +32,8 @@ function Linemode:size() end end -function Linemode:ctime() - local time = (self._file.cha.created or 0) // 1 +function Linemode:btime() + local time = math.floor(self._file.cha.btime or 0) if time == 0 then return ui.Line("") elseif os.date("%Y", time) == os.date("%Y") then @@ -44,7 +44,7 @@ function Linemode:ctime() end function Linemode:mtime() - local time = (self._file.cha.modified or 0) // 1 + local time = math.floor(self._file.cha.mtime or 0) if time == 0 then return ui.Line("") elseif os.date("%Y", time) == os.date("%Y") then @@ -54,7 +54,7 @@ function Linemode:mtime() end end -function Linemode:permissions() return ui.Line(self._file.cha:permissions() or "") end +function Linemode:permissions() return ui.Line(self._file.cha:perm() or "") end function Linemode:owner() local user = self._file.cha.uid and ya.user_name(self._file.cha.uid) or self._file.cha.uid diff --git a/yazi-plugin/preset/components/status.lua b/yazi-plugin/preset/components/status.lua index 605c1741..8686a1d5 100644 --- a/yazi-plugin/preset/components/status.lua +++ b/yazi-plugin/preset/components/status.lua @@ -52,7 +52,7 @@ function Status:size() local style = self:style() return ui.Line { - ui.Span(" " .. ya.readable_size(h:size() or h.cha.length) .. " "):fg(style.bg):bg(THEME.status.separator_style.bg), + ui.Span(" " .. ya.readable_size(h:size() or h.cha.len) .. " "):fg(style.bg):bg(THEME.status.separator_style.bg), ui.Span(THEME.status.separator_close):fg(THEME.status.separator_style.fg), } end @@ -72,7 +72,7 @@ function Status:permissions() return ui.Line {} end - local perm = h.cha:permissions() + local perm = h.cha:perm() if not perm then return ui.Line {} end diff --git a/yazi-plugin/preset/plugins/video.lua b/yazi-plugin/preset/plugins/video.lua index 4b30570b..c4846ed5 100644 --- a/yazi-plugin/preset/plugins/video.lua +++ b/yazi-plugin/preset/plugins/video.lua @@ -34,7 +34,7 @@ function M:preload() end local cha = fs.cha(cache) - if cha and cha.length > 0 then + if cha and cha.len > 0 then return 1 end diff --git a/yazi-plugin/src/cha/cha.rs b/yazi-plugin/src/cha/cha.rs index cf62b389..cd236298 100644 --- a/yazi-plugin/src/cha/cha.rs +++ b/yazi-plugin/src/cha/cha.rs @@ -7,6 +7,22 @@ use crate::bindings::Cast; pub struct Cha; +static WARNED: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false); + +#[inline] +fn warn_deprecated() { + if !WARNED.swap(true, std::sync::atomic::Ordering::Relaxed) { + yazi_proxy::AppProxy::notify(yazi_proxy::options::NotifyOpt { + title: "Deprecated API".to_owned(), + content: "The `created`, `modified`, `accessed`, `length`, and `permissions` properties of `Cha` have been deprecated. + +Please use the new `btime`, `mtime`, `atime`, `len`, and `perm` instead.".to_string(), + level: yazi_proxy::options::NotifyLevel::Warn, + timeout: Duration::from_secs(20), + }); + } +} + impl Cha { pub fn register(lua: &Lua) -> mlua::Result<()> { lua.register_userdata_type::(|reg| { @@ -29,17 +45,21 @@ impl Cha { reg.add_field_method_get("nlink", |_, me| Ok((!me.is_dummy()).then_some(me.nlink))); } - reg.add_field_method_get("length", |_, me| Ok(me.len)); - reg.add_field_method_get("created", |_, me| { - Ok(me.ctime.and_then(|t| t.duration_since(UNIX_EPOCH).map(|d| d.as_secs_f64()).ok())) - }); - reg.add_field_method_get("modified", |_, me| { - Ok(me.mtime.and_then(|t| t.duration_since(UNIX_EPOCH).map(|d| d.as_secs_f64()).ok())) - }); - reg.add_field_method_get("accessed", |_, me| { + reg.add_field_method_get("len", |_, me| Ok(me.len)); + reg.add_field_method_get("atime", |_, me| { Ok(me.atime.and_then(|t| t.duration_since(UNIX_EPOCH).map(|d| d.as_secs_f64()).ok())) }); - reg.add_method("permissions", |_, _me, ()| { + reg.add_field_method_get("btime", |_, me| { + Ok(me.btime.and_then(|t| t.duration_since(UNIX_EPOCH).map(|d| d.as_secs_f64()).ok())) + }); + #[cfg(unix)] + reg.add_field_method_get("ctime", |_, me| { + Ok(me.ctime.and_then(|t| t.duration_since(UNIX_EPOCH).map(|d| d.as_secs_f64()).ok())) + }); + reg.add_field_method_get("mtime", |_, me| { + Ok(me.mtime.and_then(|t| t.duration_since(UNIX_EPOCH).map(|d| d.as_secs_f64()).ok())) + }); + reg.add_method("perm", |_, _me, ()| { Ok( #[cfg(unix)] Some(yazi_shared::fs::permissions(_me.perm, _me.is_dummy())), @@ -47,6 +67,35 @@ impl Cha { None::, ) }); + + // TODO: remove these deprecated properties in the future + { + reg.add_field_method_get("length", |_, me| { + warn_deprecated(); + Ok(me.len) + }); + reg.add_field_method_get("created", |_, me| { + warn_deprecated(); + Ok(me.btime.and_then(|t| t.duration_since(UNIX_EPOCH).map(|d| d.as_secs_f64()).ok())) + }); + reg.add_field_method_get("modified", |_, me| { + warn_deprecated(); + Ok(me.mtime.and_then(|t| t.duration_since(UNIX_EPOCH).map(|d| d.as_secs_f64()).ok())) + }); + reg.add_field_method_get("accessed", |_, me| { + warn_deprecated(); + Ok(me.atime.and_then(|t| t.duration_since(UNIX_EPOCH).map(|d| d.as_secs_f64()).ok())) + }); + reg.add_method("permissions", |_, _me, ()| { + warn_deprecated(); + Ok( + #[cfg(unix)] + Some(yazi_shared::fs::permissions(_me.perm, _me.is_dummy())), + #[cfg(windows)] + None::, + ) + }); + } })?; Ok(()) @@ -72,6 +121,8 @@ impl Cha { kind, len: t.raw_get("len").unwrap_or_default(), atime: parse_time(t.raw_get("atime").ok())?, + btime: parse_time(t.raw_get("btime").ok())?, + #[cfg(unix)] ctime: parse_time(t.raw_get("ctime").ok())?, mtime: parse_time(t.raw_get("mtime").ok())?, #[cfg(unix)] diff --git a/yazi-proxy/src/app.rs b/yazi-proxy/src/app.rs index c9f79caf..cea1d0fe 100644 --- a/yazi-proxy/src/app.rs +++ b/yazi-proxy/src/app.rs @@ -27,27 +27,21 @@ impl AppProxy { #[inline] pub fn notify_warn(title: &str, content: impl ToString) { - emit!(Call( - Cmd::new("notify").with_any("option", NotifyOpt { - title: title.to_owned(), - content: content.to_string(), - level: NotifyLevel::Warn, - timeout: Duration::from_secs(5), - }), - Layer::App - )); + Self::notify(NotifyOpt { + title: title.to_owned(), + content: content.to_string(), + level: NotifyLevel::Warn, + timeout: Duration::from_secs(5), + }); } #[inline] pub fn notify_error(title: &str, content: impl ToString) { - emit!(Call( - Cmd::new("notify").with_any("option", NotifyOpt { - title: title.to_owned(), - content: content.to_string(), - level: NotifyLevel::Error, - timeout: Duration::from_secs(10), - }), - Layer::App - )); + Self::notify(NotifyOpt { + title: title.to_owned(), + content: content.to_string(), + level: NotifyLevel::Error, + timeout: Duration::from_secs(10), + }); } } diff --git a/yazi-shared/Cargo.toml b/yazi-shared/Cargo.toml index 93753393..12568fe1 100644 --- a/yazi-shared/Cargo.toml +++ b/yazi-shared/Cargo.toml @@ -10,6 +10,9 @@ repository = "https://github.com/sxyazi/yazi" rust-version = "1.78.0" [dependencies] +yazi-macro = { path = "../yazi-macro", version = "0.3.3" } + +# External dependencies anyhow = { workspace = true } bitflags = { workspace = true } crossterm = { workspace = true } diff --git a/yazi-shared/src/fs/cha.rs b/yazi-shared/src/fs/cha.rs index 6f76c5d5..2e26ba2e 100644 --- a/yazi-shared/src/fs/cha.rs +++ b/yazi-shared/src/fs/cha.rs @@ -1,6 +1,7 @@ use std::{fs::{FileType, Metadata}, time::SystemTime}; use bitflags::bitflags; +use yazi_macro::unix_either; bitflags! { #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] @@ -20,6 +21,8 @@ pub struct Cha { pub kind: ChaKind, pub len: u64, pub atime: Option, + pub btime: Option, + #[cfg(unix)] pub ctime: Option, pub mtime: Option, #[cfg(unix)] @@ -40,11 +43,16 @@ impl From for Cha { } Self { - kind: ck, - len: m.len(), - atime: m.accessed().ok(), - ctime: m.created().ok(), - mtime: m.modified().ok(), + kind: ck, + len: m.len(), + atime: m.accessed().ok(), + btime: m.created().ok(), + #[cfg(unix)] + ctime: { + use std::{os::unix::fs::MetadataExt, time::{Duration, UNIX_EPOCH}}; + UNIX_EPOCH.checked_add(Duration::new(m.ctime() as u64, m.ctime_nsec() as u32)) + }, + mtime: m.modified().ok(), #[cfg(unix)] perm: { @@ -126,16 +134,12 @@ impl Cha { #[inline] pub fn hits(self, c: Self) -> bool { - self.len == c.len && self.mtime == c.mtime && self.ctime == c.ctime && self.kind == c.kind && { - #[cfg(unix)] - { - self.perm == c.perm - } - #[cfg(windows)] - { - true - } - } + self.len == c.len + && self.mtime == c.mtime + && unix_either!(self.ctime == c.ctime, true) + && self.btime == c.btime + && self.kind == c.kind + && unix_either!(self.perm == c.perm, true) } } @@ -157,73 +161,27 @@ impl Cha { #[inline] pub const fn is_block(&self) -> bool { - #[cfg(unix)] - { - self.perm & libc::S_IFMT == libc::S_IFBLK - } - #[cfg(windows)] - { - false - } + unix_either!(self.perm & libc::S_IFMT == libc::S_IFBLK, false) } #[inline] pub const fn is_char(&self) -> bool { - #[cfg(unix)] - { - self.perm & libc::S_IFMT == libc::S_IFCHR - } - #[cfg(windows)] - { - false - } + unix_either!(self.perm & libc::S_IFMT == libc::S_IFCHR, false) } #[inline] pub const fn is_fifo(&self) -> bool { - #[cfg(unix)] - { - self.perm & libc::S_IFMT == libc::S_IFIFO - } - #[cfg(windows)] - { - false - } + unix_either!(self.perm & libc::S_IFMT == libc::S_IFIFO, false) } #[inline] pub const fn is_sock(&self) -> bool { - #[cfg(unix)] - { - self.perm & libc::S_IFMT == libc::S_IFSOCK - } - #[cfg(windows)] - { - false - } + unix_either!(self.perm & libc::S_IFMT == libc::S_IFSOCK, false) } #[inline] - pub const fn is_exec(&self) -> bool { - #[cfg(unix)] - { - self.perm & libc::S_IXUSR != 0 - } - #[cfg(windows)] - { - false - } - } + pub const fn is_exec(&self) -> bool { unix_either!(self.perm & libc::S_IXUSR != 0, false) } #[inline] - pub const fn is_sticky(&self) -> bool { - #[cfg(unix)] - { - self.perm & libc::S_ISVTX != 0 - } - #[cfg(windows)] - { - false - } - } + pub const fn is_sticky(&self) -> bool { unix_either!(self.perm & libc::S_ISVTX != 0, false) } }