Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: new search_do command to make it easier to achieve a flat view #1431

Merged
merged 1 commit into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion yazi-config/preset/keymap.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ keymap = [
{ on = ".", run = "hidden toggle", desc = "Toggle the visibility of hidden files" },
{ on = "s", run = "search fd", desc = "Search files by name using fd" },
{ 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 = "escape --search", desc = "Cancel the ongoing search" },
{ on = "z", run = "plugin zoxide", desc = "Jump to a directory using zoxide" },
{ on = "Z", run = "plugin fzf", desc = "Jump to a directory or reveal a file using fzf" },

Expand Down
8 changes: 3 additions & 5 deletions yazi-core/src/tab/commands/escape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,10 @@ impl Tab {
}

pub fn escape_search(&mut self) -> bool {
if !self.current.cwd.is_search() {
return false;
}

let b = self.current.cwd.is_search();
self.search_stop();
render_and!(true)

render_and!(b)
}

pub fn try_escape_visual(&mut self) -> bool {
Expand Down
95 changes: 39 additions & 56 deletions yazi-core/src/tab/commands/search.rs
Original file line number Diff line number Diff line change
@@ -1,68 +1,45 @@
use std::{fmt::Display, mem, time::Duration};
use std::{mem, time::Duration};

use anyhow::bail;
use tokio::pin;
use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
use tracing::error;
use yazi_config::popup::InputCfg;
use yazi_plugin::external;
use yazi_proxy::{AppProxy, InputProxy, ManagerProxy, TabProxy};
use yazi_shared::{event::Cmd, fs::FilesOp, render};
use yazi_proxy::{options::{SearchOpt, SearchOptVia}, AppProxy, InputProxy, ManagerProxy, TabProxy};
use yazi_shared::fs::FilesOp;

use crate::tab::Tab;

#[derive(PartialEq, Eq)]
pub enum OptType {
None,
Rg,
Fd,
}
impl Tab {
pub fn search(&mut self, opt: impl TryInto<SearchOpt>) {
let Ok(mut opt) = opt.try_into() else {
return AppProxy::notify_error("Invalid `search` option", "Failed to parse search option");
};

impl From<String> for OptType {
fn from(value: String) -> Self {
match value.as_str() {
"rg" => Self::Rg,
"fd" => Self::Fd,
_ => Self::None,
if opt.via == SearchOptVia::None {
return self.search_stop();
}
}
}

impl Display for OptType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
Self::Rg => "rg",
Self::Fd => "fd",
Self::None => "none",
})
}
}

pub struct Opt {
pub type_: OptType,
pub args: Vec<String>,
}
if let Some(handle) = self.search.take() {
handle.abort();
}

impl TryFrom<Cmd> for Opt {
type Error = ();
tokio::spawn(async move {
let mut input =
InputProxy::show(InputCfg::search(&opt.via.to_string()).with_value(opt.subject));

fn try_from(mut c: Cmd) -> Result<Self, Self::Error> {
Ok(Self {
type_: c.take_first_str().unwrap_or_default().into(),
args: shell_words::split(c.str("args").unwrap_or_default()).map_err(|_| ())?,
})
if let Some(Ok(subject)) = input.recv().await {
opt.subject = subject;
TabProxy::search_do(opt);
}
});
}
}

impl Tab {
pub fn search(&mut self, opt: impl TryInto<Opt>) {
pub fn search_do(&mut self, opt: impl TryInto<SearchOpt>) {
let Ok(opt) = opt.try_into() else {
return AppProxy::notify_error("Invalid `search` option", "Failed to parse search option");
return error!("Failed to parse search option for `search_do`");
};

if opt.type_ == OptType::None {
return self.search_stop();
}

if let Some(handle) = self.search.take() {
handle.abort();
}
Expand All @@ -71,14 +48,21 @@ impl Tab {
let hidden = self.conf.show_hidden;

self.search = Some(tokio::spawn(async move {
let mut input = InputProxy::show(InputCfg::search(&opt.type_.to_string()));
let Some(Ok(subject)) = input.recv().await else { bail!("") };

cwd = cwd.into_search(subject.clone());
let rx = if opt.type_ == OptType::Rg {
external::rg(external::RgOpt { cwd: cwd.clone(), hidden, subject, args: opt.args })
cwd = cwd.into_search(opt.subject.clone());
let rx = if opt.via == SearchOptVia::Rg {
external::rg(external::RgOpt {
cwd: cwd.clone(),
hidden,
subject: opt.subject,
args: opt.args,
})
} else {
external::fd(external::FdOpt { cwd: cwd.clone(), hidden, subject, args: opt.args })
external::fd(external::FdOpt {
cwd: cwd.clone(),
hidden,
subject: opt.subject,
args: opt.args,
})
}?;

let rx = UnboundedReceiverStream::new(rx).chunks_timeout(1000, Duration::from_millis(300));
Expand All @@ -89,10 +73,9 @@ impl Tab {
FilesOp::Part(cwd.clone(), chunk, ticket).emit();
}
FilesOp::Done(cwd, None, ticket).emit();

Ok(())
}));

render!();
}

pub(super) fn search_stop(&mut self) {
Expand Down
2 changes: 1 addition & 1 deletion yazi-dds/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ tracing = { workspace = true }
vergen-gitcl = { version = "1.0.0", features = [ "build" ] }

[target."cfg(unix)".dependencies]
uzers = "0.12.0"
uzers = "0.12.1"
1 change: 1 addition & 0 deletions yazi-fm/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ impl<'a> Executor<'a> {
on!(ACTIVE, hidden);
on!(ACTIVE, linemode);
on!(ACTIVE, search);
on!(ACTIVE, search_do);

// Filter
on!(ACTIVE, filter);
Expand Down
2 changes: 1 addition & 1 deletion yazi-plugin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ unicode-width = { workspace = true }
yazi-prebuild = "0.1.2"

[target."cfg(unix)".dependencies]
uzers = "0.12.0"
uzers = "0.12.1"

[target."cfg(windows)".dependencies]
clipboard-win = "5.4.0"
Expand Down
7 changes: 4 additions & 3 deletions yazi-proxy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ yazi-config = { path = "../yazi-config", version = "0.3.0" }
yazi-shared = { path = "../yazi-shared", version = "0.3.0" }

# External dependencies
anyhow = { workspace = true }
mlua = { workspace = true }
tokio = { workspace = true }
anyhow = { workspace = true }
mlua = { workspace = true }
shell-words = { workspace = true }
tokio = { workspace = true }
2 changes: 2 additions & 0 deletions yazi-proxy/src/options/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
mod notify;
mod open;
mod process;
mod search;

pub use notify::*;
pub use open::*;
pub use process::*;
pub use search::*;
53 changes: 53 additions & 0 deletions yazi-proxy/src/options/search.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use std::fmt::Display;

use yazi_shared::event::Cmd;

pub struct SearchOpt {
pub via: SearchOptVia,
pub subject: String,
pub args: Vec<String>,
pub args_raw: String,
}

impl TryFrom<Cmd> for SearchOpt {
type Error = ();

fn try_from(mut c: Cmd) -> Result<Self, Self::Error> {
Ok(Self {
// TODO: remove `c.take_first_str()` in the future
via: c.take_str("via").or_else(|| c.take_first_str()).unwrap_or_default().into(),
subject: c.take_first_str().unwrap_or_default(),
args: shell_words::split(c.str("args").unwrap_or_default()).map_err(|_| ())?,
args_raw: c.take_str("args").unwrap_or_default(),
})
}
}

// Via
#[derive(PartialEq, Eq)]
pub enum SearchOptVia {
// TODO: remove `None` in the future
None,
Rg,
Fd,
}

impl From<String> for SearchOptVia {
fn from(value: String) -> Self {
match value.as_str() {
"rg" => Self::Rg,
"fd" => Self::Fd,
_ => Self::None,
}
}
}

impl Display for SearchOptVia {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
Self::Rg => "rg",
Self::Fd => "fd",
Self::None => "none",
})
}
}
10 changes: 10 additions & 0 deletions yazi-proxy/src/tab.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use yazi_shared::{emit, event::Cmd, fs::Url, Layer};

use crate::options::SearchOpt;

pub struct TabProxy;

impl TabProxy {
Expand All @@ -12,4 +14,12 @@ impl TabProxy {
pub fn reveal(target: &Url) {
emit!(Call(Cmd::args("reveal", vec![target.to_string()]), Layer::Manager));
}

#[inline]
pub fn search_do(opt: SearchOpt) {
emit!(Call(
Cmd::args("search_do", vec![opt.subject]).with("via", opt.via).with("args", opt.args_raw),
Layer::Manager
));
}
}
2 changes: 2 additions & 0 deletions yazi-shared/src/fs/url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ impl Url {
#[inline]
pub fn into_regular(mut self) -> Self {
self.scheme = UrlScheme::Regular;
self.frag = String::new();
self
}

Expand All @@ -192,6 +193,7 @@ impl Url {
#[inline]
pub fn into_archive(mut self) -> Self {
self.scheme = UrlScheme::Archive;
self.frag = String::new();
self
}

Expand Down