mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: re-implement fzf as a built-in plugin (#884)
This commit is contained in:
parent
cd2e7ff945
commit
0cfb50bd49
7 changed files with 41 additions and 61 deletions
|
|
@ -82,7 +82,7 @@ keymap = [
|
||||||
{ on = [ "S" ], run = "search rg", desc = "Search files by content using ripgrep" },
|
{ on = [ "S" ], run = "search rg", desc = "Search files by content using ripgrep" },
|
||||||
{ on = [ "<C-s>" ], run = "search none", desc = "Cancel the ongoing search" },
|
{ on = [ "<C-s>" ], run = "search none", desc = "Cancel the ongoing search" },
|
||||||
{ on = [ "z" ], run = "plugin zoxide", desc = "Jump to a directory using zoxide" },
|
{ on = [ "z" ], run = "plugin zoxide", desc = "Jump to a directory using zoxide" },
|
||||||
{ on = [ "Z" ], run = "jump fzf", desc = "Jump to a directory, or reveal a file using fzf" },
|
{ on = [ "Z" ], run = "plugin fzf", desc = "Jump to a directory, or reveal a file using fzf" },
|
||||||
|
|
||||||
# Linemode
|
# Linemode
|
||||||
{ on = [ "m", "s" ], run = "linemode size", desc = "Set linemode to size" },
|
{ on = [ "m", "s" ], run = "linemode size", desc = "Set linemode to size" },
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ ratio = [ 1, 4, 3 ]
|
||||||
sort_by = "alphabetical"
|
sort_by = "alphabetical"
|
||||||
sort_sensitive = false
|
sort_sensitive = false
|
||||||
sort_reverse = false
|
sort_reverse = false
|
||||||
sort_dir_first = false
|
sort_dir_first = true
|
||||||
linemode = "none"
|
linemode = "none"
|
||||||
show_hidden = false
|
show_hidden = false
|
||||||
show_symlink = true
|
show_symlink = true
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use yazi_plugin::external::{self, FzfOpt};
|
use yazi_proxy::{options::{NotifyLevel, NotifyOpt}, AppProxy};
|
||||||
use yazi_proxy::{options::{NotifyLevel, NotifyOpt}, AppProxy, TabProxy, HIDER};
|
use yazi_shared::{emit, event::Cmd, Layer};
|
||||||
use yazi_shared::{emit, event::Cmd, fs::ends_with_slash, Defer, Layer};
|
|
||||||
|
|
||||||
use crate::tab::Tab;
|
use crate::tab::Tab;
|
||||||
|
|
||||||
|
|
@ -30,48 +29,27 @@ impl From<Cmd> for Opt {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tab {
|
impl Tab {
|
||||||
|
// TODO: Remove this once Yazi v0.2.7 is released
|
||||||
pub fn jump(&self, opt: impl Into<Opt>) {
|
pub fn jump(&self, opt: impl Into<Opt>) {
|
||||||
let opt = opt.into() as Opt;
|
AppProxy::notify(NotifyOpt {
|
||||||
if opt.type_ == OptType::None {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Remove this once Yazi v0.2.7 is released
|
|
||||||
if opt.type_ == OptType::Zoxide {
|
|
||||||
AppProxy::notify(NotifyOpt {
|
|
||||||
title: "Jump".to_owned(),
|
title: "Jump".to_owned(),
|
||||||
content: r#"The `jump zoxide` command has been deprecated in Yazi v0.2.5. Please replace it with `plugin zoxide` in your `keymap.toml`.
|
content: r#"The `jump` command has been deprecated in Yazi v0.2.5.
|
||||||
|
Please replace `jump fzf` with `plugin fzf`, and `jump zoxide` with `plugin zoxide`, in your `keymap.toml`.
|
||||||
|
|
||||||
See https://github.com/sxyazi/yazi/issues/865 for more details."#.to_owned(),
|
See https://github.com/sxyazi/yazi/issues/865 for more details."#.to_owned(),
|
||||||
level: NotifyLevel::Warn,
|
level: NotifyLevel::Warn,
|
||||||
timeout: Duration::from_secs(15),
|
timeout: Duration::from_secs(15),
|
||||||
});
|
});
|
||||||
|
|
||||||
emit!(Call(Cmd::args("plugin", vec!["zoxide".to_owned()]), Layer::App));
|
let opt = opt.into() as Opt;
|
||||||
|
if opt.type_ == OptType::None {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let cwd = self.current.cwd.clone();
|
if opt.type_ == OptType::Fzf {
|
||||||
tokio::spawn(async move {
|
emit!(Call(Cmd::args("plugin", vec!["fzf".to_owned()]), Layer::App));
|
||||||
let _permit = HIDER.acquire().await.unwrap();
|
} else {
|
||||||
let _defer = Defer::new(AppProxy::resume);
|
emit!(Call(Cmd::args("plugin", vec!["zoxide".to_owned()]), Layer::App));
|
||||||
AppProxy::stop().await;
|
}
|
||||||
|
|
||||||
let result = if opt.type_ == OptType::Fzf {
|
|
||||||
external::fzf(FzfOpt { cwd }).await
|
|
||||||
} else {
|
|
||||||
unreachable!()
|
|
||||||
};
|
|
||||||
|
|
||||||
let Ok(url) = result else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
if opt.type_ == OptType::Fzf && !ends_with_slash(&url) {
|
|
||||||
TabProxy::reveal(&url)
|
|
||||||
} else {
|
|
||||||
TabProxy::cd(&url)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
25
yazi-plugin/preset/plugins/fzf.lua
Normal file
25
yazi-plugin/preset/plugins/fzf.lua
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
local cwd = 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 entry()
|
||||||
|
local _permit = ya.hide()
|
||||||
|
local cwd = cwd()
|
||||||
|
|
||||||
|
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)
|
||||||
|
end
|
||||||
|
|
||||||
|
local output, err = child:wait_with_output()
|
||||||
|
if not output then
|
||||||
|
return notify("`fzf` exited with error code %s", err)
|
||||||
|
end
|
||||||
|
|
||||||
|
local target = output.stdout:gsub("\n$", "")
|
||||||
|
ya.manager_emit(target:match("[/\\]$") and "cd" or "reveal", { target })
|
||||||
|
end
|
||||||
|
|
||||||
|
return { entry = entry }
|
||||||
22
yazi-plugin/src/external/fzf.rs
vendored
22
yazi-plugin/src/external/fzf.rs
vendored
|
|
@ -1,22 +0,0 @@
|
||||||
use std::{path::Path, process::Stdio};
|
|
||||||
|
|
||||||
use anyhow::{bail, Result};
|
|
||||||
use tokio::process::Command;
|
|
||||||
use yazi_shared::fs::Url;
|
|
||||||
|
|
||||||
pub struct FzfOpt {
|
|
||||||
pub cwd: Url,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn fzf(opt: FzfOpt) -> Result<Url> {
|
|
||||||
let child =
|
|
||||||
Command::new("fzf").current_dir(&opt.cwd).kill_on_drop(true).stdout(Stdio::piped()).spawn()?;
|
|
||||||
|
|
||||||
let output = child.wait_with_output().await?;
|
|
||||||
let selected = String::from_utf8_lossy(&output.stdout).trim().to_string();
|
|
||||||
|
|
||||||
if selected.is_empty() {
|
|
||||||
bail!("No match")
|
|
||||||
}
|
|
||||||
return Ok(Url::from(Path::new(&opt.cwd).join(selected)));
|
|
||||||
}
|
|
||||||
2
yazi-plugin/src/external/mod.rs
vendored
2
yazi-plugin/src/external/mod.rs
vendored
|
|
@ -1,11 +1,9 @@
|
||||||
mod fd;
|
mod fd;
|
||||||
mod fzf;
|
|
||||||
mod highlighter;
|
mod highlighter;
|
||||||
mod lsar;
|
mod lsar;
|
||||||
mod rg;
|
mod rg;
|
||||||
|
|
||||||
pub use fd::*;
|
pub use fd::*;
|
||||||
pub use fzf::*;
|
|
||||||
pub use highlighter::*;
|
pub use highlighter::*;
|
||||||
pub use lsar::*;
|
pub use lsar::*;
|
||||||
pub use rg::*;
|
pub use rg::*;
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ impl Loader {
|
||||||
"code" => include_bytes!("../../preset/plugins/code.lua"),
|
"code" => include_bytes!("../../preset/plugins/code.lua"),
|
||||||
"file" => include_bytes!("../../preset/plugins/file.lua"),
|
"file" => include_bytes!("../../preset/plugins/file.lua"),
|
||||||
"folder" => include_bytes!("../../preset/plugins/folder.lua"),
|
"folder" => include_bytes!("../../preset/plugins/folder.lua"),
|
||||||
|
"fzf" => include_bytes!("../../preset/plugins/fzf.lua"),
|
||||||
"image" => include_bytes!("../../preset/plugins/image.lua"),
|
"image" => include_bytes!("../../preset/plugins/image.lua"),
|
||||||
"json" => include_bytes!("../../preset/plugins/json.lua"),
|
"json" => include_bytes!("../../preset/plugins/json.lua"),
|
||||||
"mime" => include_bytes!("../../preset/plugins/mime.lua"),
|
"mime" => include_bytes!("../../preset/plugins/mime.lua"),
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue