From 884de41b6606d805d9465004b5b3ce7758e065d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E9=9B=85=20=C2=B7=20Misaki=20Masa?= Date: Mon, 8 Apr 2024 08:29:21 +0800 Subject: [PATCH] feat: add new `--orphan` option to the `shell` command (#887) --- yazi-boot/src/boot.rs | 1 + yazi-config/preset/theme.toml | 6 ++-- yazi-config/preset/yazi.toml | 12 +++----- yazi-core/src/manager/commands/tab_create.rs | 30 +++++++++++++------- yazi-core/src/tab/commands/shell.rs | 4 ++- yazi-fm/src/notify/layout.rs | 2 +- yazi-plugin/preset/plugins/fzf.lua | 16 +++++++---- yazi-plugin/preset/plugins/zoxide.lua | 19 +++++++++---- yazi-scheduler/src/process/process.rs | 1 + 9 files changed, 54 insertions(+), 37 deletions(-) diff --git a/yazi-boot/src/boot.rs b/yazi-boot/src/boot.rs index 9005d493..a007bf32 100644 --- a/yazi-boot/src/boot.rs +++ b/yazi-boot/src/boot.rs @@ -79,6 +79,7 @@ impl Boot { )?; writeln!(s, "\nVariables")?; + writeln!(s, " SHELL: {:?}", env::var_os("SHELL"))?; writeln!(s, " EDITOR: {:?}", env::var_os("EDITOR"))?; writeln!(s, " ZELLIJ_SESSION_NAME: {:?}", env::var_os("ZELLIJ_SESSION_NAME"))?; writeln!(s, " YAZI_FILE_ONE: {:?}", env::var_os("YAZI_FILE_ONE"))?; diff --git a/yazi-config/preset/theme.toml b/yazi-config/preset/theme.toml index 20731d17..0386b784 100644 --- a/yazi-config/preset/theme.toml +++ b/yazi-config/preset/theme.toml @@ -177,11 +177,9 @@ rules = [ { mime = "audio/*", fg = "yellow" }, # Archives - { mime = "application/zip", fg = "magenta" }, - { mime = "application/gzip", fg = "magenta" }, + { mime = "application/*zip", fg = "magenta" }, { mime = "application/x-tar", fg = "magenta" }, - { mime = "application/x-bzip", fg = "magenta" }, - { mime = "application/x-bzip2", fg = "magenta" }, + { mime = "application/x-bzip*", fg = "magenta" }, { mime = "application/x-7z-compressed", fg = "magenta" }, { mime = "application/x-rar", fg = "magenta" }, { mime = "application/x-xz", fg = "magenta" }, diff --git a/yazi-config/preset/yazi.toml b/yazi-config/preset/yazi.toml index 852e1626..6e161a55 100644 --- a/yazi-config/preset/yazi.toml +++ b/yazi-config/preset/yazi.toml @@ -63,11 +63,9 @@ rules = [ { mime = "application/json", use = [ "edit", "reveal" ] }, { mime = "*/javascript", use = [ "edit", "reveal" ] }, - { mime = "application/zip", use = [ "extract", "reveal" ] }, - { mime = "application/gzip", use = [ "extract", "reveal" ] }, + { mime = "application/*zip", use = [ "extract", "reveal" ] }, { mime = "application/x-tar", use = [ "extract", "reveal" ] }, - { mime = "application/x-bzip", use = [ "extract", "reveal" ] }, - { mime = "application/x-bzip2", use = [ "extract", "reveal" ] }, + { mime = "application/x-bzip*", use = [ "extract", "reveal" ] }, { mime = "application/x-7z-compressed", use = [ "extract", "reveal" ] }, { mime = "application/x-rar", use = [ "extract", "reveal" ] }, { mime = "application/x-xz", use = [ "extract", "reveal" ] }, @@ -111,11 +109,9 @@ previewers = [ # PDF { mime = "application/pdf", run = "pdf" }, # Archive - { mime = "application/zip", run = "archive" }, - { mime = "application/gzip", run = "archive" }, + { mime = "application/*zip", run = "archive" }, { mime = "application/x-tar", run = "archive" }, - { mime = "application/x-bzip", run = "archive" }, - { mime = "application/x-bzip2", run = "archive" }, + { mime = "application/x-bzip*", run = "archive" }, { mime = "application/x-7z-compressed", run = "archive" }, { mime = "application/x-rar", run = "archive" }, { mime = "application/x-xz", run = "archive" }, diff --git a/yazi-core/src/manager/commands/tab_create.rs b/yazi-core/src/manager/commands/tab_create.rs index 4f079305..fd4671fe 100644 --- a/yazi-core/src/manager/commands/tab_create.rs +++ b/yazi-core/src/manager/commands/tab_create.rs @@ -1,3 +1,4 @@ +use yazi_proxy::AppProxy; use yazi_shared::{event::Cmd, fs::Url, render}; use crate::{manager::Tabs, tab::Tab}; @@ -5,34 +6,41 @@ use crate::{manager::Tabs, tab::Tab}; const MAX_TABS: usize = 9; pub struct Opt { - url: Option, + url: Url, current: bool, } impl From for Opt { fn from(mut c: Cmd) -> Self { - let mut opt = Self { url: None, current: c.named.contains_key("current") }; - - if !opt.current { - opt.url = Some(c.take_first().map_or_else(|| Url::from("."), Url::from)); + if c.named.contains_key("current") { + Self { url: Default::default(), current: true } + } else { + Self { url: c.take_first().map_or_else(|| Url::from("."), Url::from), current: false } } - opt } } impl Tabs { pub fn create(&mut self, opt: impl Into) { 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 url = if opt.current { self.active().current.cwd.to_owned() } else { opt.url.unwrap() }; - let mut tab = Tab::default(); - tab.conf = self.active().conf.clone(); - tab.apply_files_attrs(); - tab.cd(url); + + if !opt.current { + tab.cd(opt.url); + } else if let Some(h) = self.active().current.hovered() { + tab.conf = self.active().conf.clone(); + tab.apply_files_attrs(); + tab.reveal(h.url.to_owned()); + } else { + tab.conf = self.active().conf.clone(); + tab.apply_files_attrs(); + tab.cd(self.active().current.cwd.clone()); + } self.items.insert(self.cursor + 1, tab); self.set_idx(self.cursor + 1); diff --git a/yazi-core/src/tab/commands/shell.rs b/yazi-core/src/tab/commands/shell.rs index 3be29cd8..b9ae7dcb 100644 --- a/yazi-core/src/tab/commands/shell.rs +++ b/yazi-core/src/tab/commands/shell.rs @@ -9,6 +9,7 @@ use crate::tab::Tab; pub struct Opt { run: String, block: bool, + orphan: bool, confirm: bool, } @@ -17,6 +18,7 @@ impl From for Opt { Self { run: c.take_first().unwrap_or_default(), block: c.named.contains_key("block"), + orphan: c.named.contains_key("orphan"), confirm: c.named.contains_key("confirm"), } } @@ -45,7 +47,7 @@ impl Tab { Cow::Owned(Opener { run: opt.run, block: opt.block, - orphan: false, + orphan: opt.orphan, desc: Default::default(), for_: None, spread: true, diff --git a/yazi-fm/src/notify/layout.rs b/yazi-fm/src/notify/layout.rs index a3563e91..49746acf 100644 --- a/yazi-fm/src/notify/layout.rs +++ b/yazi-fm/src/notify/layout.rs @@ -20,7 +20,7 @@ impl<'a> Layout<'a> { .split(area); let chunks = - layout::Layout::vertical([Constraint::Max(1), Constraint::Min(1)]).split(chunks[1]); + layout::Layout::vertical([Constraint::Max(1), Constraint::Fill(1)]).split(chunks[1]); chunks[1] } diff --git a/yazi-plugin/preset/plugins/fzf.lua b/yazi-plugin/preset/plugins/fzf.lua index faa54907..c0c173fa 100644 --- a/yazi-plugin/preset/plugins/fzf.lua +++ b/yazi-plugin/preset/plugins/fzf.lua @@ -1,25 +1,29 @@ -local cwd = ya.sync(function() return tostring(cx.active.current.cwd) end) +local state = ya.sync(function() return tostring(cx.active.current.cwd) end) -local function notify(s, ...) ya.notify { title = "Fzf", content = string.format(s, ...), timeout = 5, level = "error" } end +local function fail(s, ...) ya.notify { title = "Fzf", content = string.format(s, ...), timeout = 5, level = "error" } end local function entry() local _permit = ya.hide() - local cwd = cwd() + local cwd = state() local child, err = Command("fzf"):cwd(cwd):stdin(Command.INHERIT):stdout(Command.PIPED):stderr(Command.INHERIT):spawn() if not child then - return notify("Spawn `fzf` failed with error code %s. Do you have it installed?", err) + return fail("Spawn `fzf` failed with error code %s. Do you have it installed?", err) end local output, err = child:wait_with_output() if not output then - return notify("`fzf` exited with error code %s", err) + return fail("Cannot read `fzf` output, error code %s", err) + elseif not output.status:success() and output.status:code() ~= 130 then + return fail("`fzf` exited with error code %s", output.status:code()) end local target = output.stdout:gsub("\n$", "") - ya.manager_emit(target:match("[/\\]$") and "cd" or "reveal", { target }) + if target ~= "" then + ya.manager_emit(target:match("[/\\]$") and "cd" or "reveal", { target }) + end end return { entry = entry } diff --git a/yazi-plugin/preset/plugins/zoxide.lua b/yazi-plugin/preset/plugins/zoxide.lua index a0b32dfc..2a57d87b 100644 --- a/yazi-plugin/preset/plugins/zoxide.lua +++ b/yazi-plugin/preset/plugins/zoxide.lua @@ -7,7 +7,7 @@ end) local set_state = ya.sync(function(st, empty) st.empty = empty end) -local function notify(s, ...) +local function fail(s, ...) ya.notify { title = "Zoxide", content = string.format(s, ...), timeout = 5, level = "error" } end @@ -39,6 +39,7 @@ local function setup(_, opts) "cd", function() ya.manager_emit("shell", { + orphan = true, confirm = true, "zoxide add " .. ya.quote(tostring(cx.active.current.cwd)), }) @@ -50,10 +51,10 @@ end local function entry() local st = state() if st.empty == true then - return notify("No directory history in the database, check out the `zoxide` docs to set it up.") + return fail("No directory history in the database, check out the `zoxide` docs to set it up.") elseif st.empty == nil and head(st.cwd) < 2 then set_state(true) - return notify("No directory history in the database, check out the `zoxide` docs to set it up.") + return fail("No directory history in the database, check out the `zoxide` docs to set it up.") end local _permit = ya.hide() @@ -66,14 +67,20 @@ local function entry() :spawn() if not child then - return notify("Spawn `zoxide` failed with error code %s. Do you have it installed?", err) + return fail("Spawn `zoxide` failed with error code %s. Do you have it installed?", err) end local output, err = child:wait_with_output() if not output then - return notify("`zoxide` exited with error code %s", err) + return fail("Cannot read `zoxide` output, error code %s", err) + elseif not output.status:success() and output.status:code() ~= 130 then + return fail("`zoxide` exited with error code %s", output.status:code()) + end + + local target = output.stdout:gsub("\n$", "") + if target ~= "" then + ya.manager_emit("cd", { output.stdout:gsub("\n$", "") }) end - ya.manager_emit("cd", { output.stdout:gsub("\n$", "") }) end return { setup = setup, entry = entry } diff --git a/yazi-scheduler/src/process/process.rs b/yazi-scheduler/src/process/process.rs index 0c2feb0f..e8a27cb8 100644 --- a/yazi-scheduler/src/process/process.rs +++ b/yazi-scheduler/src/process/process.rs @@ -28,6 +28,7 @@ impl Process { let status = result.unwrap().wait().await?; if !status.success() { let content = match status.code() { + Some(130) => return self.succ(id), // Ctrl-C pressed by user Some(code) => format!("Process exited with status code: {code}"), None => "Process terminated by signal".to_string(), };