feat: add new --orphan option to the shell command (#887)

This commit is contained in:
三咲雅 · Misaki Masa 2024-04-08 08:29:21 +08:00 committed by GitHub
parent 0cfb50bd49
commit 884de41b66
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 54 additions and 37 deletions

View File

@ -79,6 +79,7 @@ impl Boot {
)?; )?;
writeln!(s, "\nVariables")?; writeln!(s, "\nVariables")?;
writeln!(s, " SHELL: {:?}", env::var_os("SHELL"))?;
writeln!(s, " EDITOR: {:?}", env::var_os("EDITOR"))?; writeln!(s, " EDITOR: {:?}", env::var_os("EDITOR"))?;
writeln!(s, " ZELLIJ_SESSION_NAME: {:?}", env::var_os("ZELLIJ_SESSION_NAME"))?; writeln!(s, " ZELLIJ_SESSION_NAME: {:?}", env::var_os("ZELLIJ_SESSION_NAME"))?;
writeln!(s, " YAZI_FILE_ONE: {:?}", env::var_os("YAZI_FILE_ONE"))?; writeln!(s, " YAZI_FILE_ONE: {:?}", env::var_os("YAZI_FILE_ONE"))?;

View File

@ -177,11 +177,9 @@ rules = [
{ mime = "audio/*", fg = "yellow" }, { mime = "audio/*", fg = "yellow" },
# Archives # Archives
{ mime = "application/zip", fg = "magenta" }, { mime = "application/*zip", fg = "magenta" },
{ mime = "application/gzip", fg = "magenta" },
{ mime = "application/x-tar", fg = "magenta" }, { mime = "application/x-tar", fg = "magenta" },
{ mime = "application/x-bzip", fg = "magenta" }, { mime = "application/x-bzip*", fg = "magenta" },
{ mime = "application/x-bzip2", fg = "magenta" },
{ mime = "application/x-7z-compressed", fg = "magenta" }, { mime = "application/x-7z-compressed", fg = "magenta" },
{ mime = "application/x-rar", fg = "magenta" }, { mime = "application/x-rar", fg = "magenta" },
{ mime = "application/x-xz", fg = "magenta" }, { mime = "application/x-xz", fg = "magenta" },

View File

@ -63,11 +63,9 @@ rules = [
{ mime = "application/json", use = [ "edit", "reveal" ] }, { mime = "application/json", use = [ "edit", "reveal" ] },
{ mime = "*/javascript", use = [ "edit", "reveal" ] }, { mime = "*/javascript", use = [ "edit", "reveal" ] },
{ mime = "application/zip", use = [ "extract", "reveal" ] }, { mime = "application/*zip", use = [ "extract", "reveal" ] },
{ mime = "application/gzip", use = [ "extract", "reveal" ] },
{ mime = "application/x-tar", use = [ "extract", "reveal" ] }, { mime = "application/x-tar", use = [ "extract", "reveal" ] },
{ mime = "application/x-bzip", use = [ "extract", "reveal" ] }, { mime = "application/x-bzip*", use = [ "extract", "reveal" ] },
{ mime = "application/x-bzip2", use = [ "extract", "reveal" ] },
{ mime = "application/x-7z-compressed", use = [ "extract", "reveal" ] }, { mime = "application/x-7z-compressed", use = [ "extract", "reveal" ] },
{ mime = "application/x-rar", use = [ "extract", "reveal" ] }, { mime = "application/x-rar", use = [ "extract", "reveal" ] },
{ mime = "application/x-xz", use = [ "extract", "reveal" ] }, { mime = "application/x-xz", use = [ "extract", "reveal" ] },
@ -111,11 +109,9 @@ previewers = [
# PDF # PDF
{ mime = "application/pdf", run = "pdf" }, { mime = "application/pdf", run = "pdf" },
# Archive # Archive
{ mime = "application/zip", run = "archive" }, { mime = "application/*zip", run = "archive" },
{ mime = "application/gzip", run = "archive" },
{ mime = "application/x-tar", run = "archive" }, { mime = "application/x-tar", run = "archive" },
{ mime = "application/x-bzip", run = "archive" }, { mime = "application/x-bzip*", run = "archive" },
{ mime = "application/x-bzip2", run = "archive" },
{ mime = "application/x-7z-compressed", run = "archive" }, { mime = "application/x-7z-compressed", run = "archive" },
{ mime = "application/x-rar", run = "archive" }, { mime = "application/x-rar", run = "archive" },
{ mime = "application/x-xz", run = "archive" }, { mime = "application/x-xz", run = "archive" },

View File

@ -1,3 +1,4 @@
use yazi_proxy::AppProxy;
use yazi_shared::{event::Cmd, fs::Url, render}; use yazi_shared::{event::Cmd, fs::Url, render};
use crate::{manager::Tabs, tab::Tab}; use crate::{manager::Tabs, tab::Tab};
@ -5,34 +6,41 @@ use crate::{manager::Tabs, tab::Tab};
const MAX_TABS: usize = 9; const MAX_TABS: usize = 9;
pub struct Opt { pub struct Opt {
url: Option<Url>, url: Url,
current: bool, current: bool,
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(mut c: Cmd) -> Self {
let mut opt = Self { url: None, current: c.named.contains_key("current") }; if c.named.contains_key("current") {
Self { url: Default::default(), current: true }
if !opt.current { } else {
opt.url = Some(c.take_first().map_or_else(|| Url::from("."), Url::from)); Self { url: c.take_first().map_or_else(|| Url::from("."), Url::from), current: false }
} }
opt
} }
} }
impl Tabs { impl Tabs {
pub fn create(&mut self, opt: impl Into<Opt>) { pub fn create(&mut self, opt: impl Into<Opt>) {
if self.items.len() >= MAX_TABS { 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; return;
} }
let opt = opt.into() as Opt; 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(); let mut tab = Tab::default();
tab.conf = self.active().conf.clone();
tab.apply_files_attrs(); if !opt.current {
tab.cd(url); 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.items.insert(self.cursor + 1, tab);
self.set_idx(self.cursor + 1); self.set_idx(self.cursor + 1);

View File

@ -9,6 +9,7 @@ use crate::tab::Tab;
pub struct Opt { pub struct Opt {
run: String, run: String,
block: bool, block: bool,
orphan: bool,
confirm: bool, confirm: bool,
} }
@ -17,6 +18,7 @@ impl From<Cmd> for Opt {
Self { Self {
run: c.take_first().unwrap_or_default(), run: c.take_first().unwrap_or_default(),
block: c.named.contains_key("block"), block: c.named.contains_key("block"),
orphan: c.named.contains_key("orphan"),
confirm: c.named.contains_key("confirm"), confirm: c.named.contains_key("confirm"),
} }
} }
@ -45,7 +47,7 @@ impl Tab {
Cow::Owned(Opener { Cow::Owned(Opener {
run: opt.run, run: opt.run,
block: opt.block, block: opt.block,
orphan: false, orphan: opt.orphan,
desc: Default::default(), desc: Default::default(),
for_: None, for_: None,
spread: true, spread: true,

View File

@ -20,7 +20,7 @@ impl<'a> Layout<'a> {
.split(area); .split(area);
let chunks = 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] chunks[1]
} }

View File

@ -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 function entry()
local _permit = ya.hide() local _permit = ya.hide()
local cwd = cwd() local cwd = state()
local child, err = local child, err =
Command("fzf"):cwd(cwd):stdin(Command.INHERIT):stdout(Command.PIPED):stderr(Command.INHERIT):spawn() Command("fzf"):cwd(cwd):stdin(Command.INHERIT):stdout(Command.PIPED):stderr(Command.INHERIT):spawn()
if not child then 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 end
local output, err = child:wait_with_output() local output, err = child:wait_with_output()
if not output then 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 end
local target = output.stdout:gsub("\n$", "") 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 end
return { entry = entry } return { entry = entry }

View File

@ -7,7 +7,7 @@ end)
local set_state = ya.sync(function(st, empty) st.empty = empty 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" } ya.notify { title = "Zoxide", content = string.format(s, ...), timeout = 5, level = "error" }
end end
@ -39,6 +39,7 @@ local function setup(_, opts)
"cd", "cd",
function() function()
ya.manager_emit("shell", { ya.manager_emit("shell", {
orphan = true,
confirm = true, confirm = true,
"zoxide add " .. ya.quote(tostring(cx.active.current.cwd)), "zoxide add " .. ya.quote(tostring(cx.active.current.cwd)),
}) })
@ -50,10 +51,10 @@ end
local function entry() local function entry()
local st = state() local st = state()
if st.empty == true then 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 elseif st.empty == nil and head(st.cwd) < 2 then
set_state(true) 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 end
local _permit = ya.hide() local _permit = ya.hide()
@ -66,14 +67,20 @@ local function entry()
:spawn() :spawn()
if not child then 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 end
local output, err = child:wait_with_output() local output, err = child:wait_with_output()
if not output then 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 end
ya.manager_emit("cd", { output.stdout:gsub("\n$", "") })
end end
return { setup = setup, entry = entry } return { setup = setup, entry = entry }

View File

@ -28,6 +28,7 @@ impl Process {
let status = result.unwrap().wait().await?; let status = result.unwrap().wait().await?;
if !status.success() { if !status.success() {
let content = match status.code() { 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}"), Some(code) => format!("Process exited with status code: {code}"),
None => "Process terminated by signal".to_string(), None => "Process terminated by signal".to_string(),
}; };