This commit is contained in:
sxyazi 2023-11-15 12:27:23 +08:00
parent 4e9f39d6dc
commit c95b613ed5
No known key found for this signature in database
25 changed files with 154 additions and 278 deletions

View file

@ -90,6 +90,16 @@ rename_title = "Rename:"
rename_position = "hovered" rename_position = "hovered"
rename_offset = [ 0, 1, 50, 3 ] rename_offset = [ 0, 1, 50, 3 ]
# trash
trash_title = "Move {n} selected file{s} to trash? (y/N)"
trash_position = "top-center"
trash_offset = [ 0, 2, 50, 3 ]
# delete
delete_title = "Delete {n} selected file{s} permanently? (y/N)"
delete_position = "top-center"
delete_offset = [ 0, 2, 50, 3 ]
# find # find
find_title = [ "Find previous:", "Find next:" ] find_title = [ "Find previous:", "Find next:" ]
find_position = "top-center" find_position = "top-center"
@ -107,6 +117,11 @@ shell_position = "top-center"
shell_offset = [ 0, 2, 50, 3 ] shell_offset = [ 0, 2, 50, 3 ]
shell_highlight = true shell_highlight = true
# overwrite
overwrite_title = "Overwrite an existing file? (y/N)"
overwrite_position = "top-center"
overwrite_offset = [ 0, 2, 50, 3 ]
[select] [select]
open_title = "Open with:" open_title = "Open with:"
open_position = "hovered" open_position = "hovered"

View file

@ -6,23 +6,44 @@ use crate::MERGED_YAZI;
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct Input { pub struct Input {
// cd // cd
pub cd_position: Position, pub cd_title: String,
pub cd_offset: Offset, pub cd_position: Position,
pub cd_offset: Offset,
// create // create
pub create_title: String,
pub create_position: Position, pub create_position: Position,
pub create_offset: Offset, pub create_offset: Offset,
// rename // rename
pub rename_title: String,
pub rename_position: Position, pub rename_position: Position,
pub rename_offset: Offset, pub rename_offset: Offset,
// trash
pub trash_title: String,
pub trash_position: Position,
pub trash_offset: Offset,
// delete
pub delete_title: String,
pub delete_position: Position,
pub delete_offset: Offset,
// find // find
pub find_position: Position, pub find_title: [String; 2],
pub find_offset: Offset, pub find_position: Position,
pub find_offset: Offset,
// search // search
pub search_title: String,
pub search_position: Position, pub search_position: Position,
pub search_offset: Offset, pub search_offset: Offset,
// shell // shell
pub shell_position: Position, pub shell_title: [String; 2],
pub shell_offset: Offset, pub shell_position: Position,
pub shell_offset: Offset,
} }
impl Default for Input { impl Default for Input {

View file

@ -1,7 +1,9 @@
mod input; mod input;
mod options;
mod position; mod position;
mod select; mod select;
pub use input::*; pub use input::*;
pub use options::*;
pub use position::*; pub use position::*;
pub use select::*; pub use select::*;

View file

@ -0,0 +1,63 @@
use super::Position;
pub struct InputOpt {
pub title: String,
pub value: String,
pub position: Position,
pub realtime: bool,
pub completion: bool,
pub highlight: bool,
}
pub struct SelectOpt {
pub title: String,
pub items: Vec<String>,
pub position: Position,
}
impl InputOpt {
#[inline]
pub fn cd() -> Self { todo!() }
#[inline]
pub fn create() -> Self { todo!() }
#[inline]
pub fn rename() -> Self { todo!() }
#[inline]
pub fn trash(n: usize) -> Self { todo!() }
#[inline]
pub fn delete(n: usize) -> Self { todo!() }
#[inline]
pub fn find(prev: bool) -> Self { todo!() }
#[inline]
pub fn search() -> Self { todo!() }
#[inline]
pub fn shell(block: bool) -> Self { todo!() }
#[inline]
pub fn overwrite() -> Self { todo!() }
#[inline]
pub fn with_value(mut self, value: impl Into<String>) -> Self {
self.value = value.into();
self
}
}
impl SelectOpt {
#[inline]
pub fn open() -> Self { todo!() }
#[inline]
pub fn with_items(mut self, items: Vec<String>) -> Self {
self.items = items;
self
}
}

View file

@ -1,7 +1,7 @@
use anyhow::bail; use anyhow::bail;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize)] #[derive(Debug, Default, Deserialize)]
pub enum Position { pub enum Position {
#[serde(rename = "top-left")] #[serde(rename = "top-left")]
TopLeft, TopLeft,
@ -9,14 +9,17 @@ pub enum Position {
TopCenter, TopCenter,
#[serde(rename = "top-right")] #[serde(rename = "top-right")]
TopRight, TopRight,
#[serde(rename = "center")]
Center,
#[serde(rename = "bottom-left")] #[serde(rename = "bottom-left")]
BottomLeft, BottomLeft,
#[serde(rename = "bottom-center")] #[serde(rename = "bottom-center")]
BottomCenter, BottomCenter,
#[serde(rename = "bottom-right")] #[serde(rename = "bottom-right")]
BottomRight, BottomRight,
#[serde(rename = "center")]
#[default]
Center,
#[serde(rename = "hovered")] #[serde(rename = "hovered")]
Hovered, Hovered,
} }

View file

@ -6,6 +6,7 @@ use crate::MERGED_YAZI;
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct Select { pub struct Select {
// open // open
pub open_title: String,
pub open_position: Position, pub open_position: Position,
pub open_offset: Offset, pub open_offset: Offset,
} }

View file

@ -1,8 +1,9 @@
use crossterm::terminal::WindowSize; use crossterm::terminal::WindowSize;
use ratatui::prelude::Rect; use ratatui::prelude::Rect;
use yazi_config::popup::Position;
use yazi_shared::Term; use yazi_shared::Term;
use crate::{completion::Completion, help::Help, input::Input, manager::Manager, select::Select, tasks::Tasks, which::Which, Offset, Position}; use crate::{completion::Completion, help::Help, input::Input, manager::Manager, select::Select, tasks::Tasks, which::Which};
pub struct Ctx { pub struct Ctx {
pub manager: Manager, pub manager: Manager,

View file

@ -3,10 +3,10 @@ use std::{collections::BTreeMap, ffi::OsString};
use anyhow::Result; use anyhow::Result;
use crossterm::event::KeyEvent; use crossterm::event::KeyEvent;
use tokio::sync::{mpsc::{self, UnboundedSender}, oneshot}; use tokio::sync::{mpsc::{self, UnboundedSender}, oneshot};
use yazi_config::{keymap::{Exec, KeymapLayer}, open::Opener}; use yazi_config::{keymap::{Exec, KeymapLayer}, open::Opener, popup::{InputOpt, SelectOpt}};
use yazi_shared::{InputError, RoCell, Url}; use yazi_shared::{InputError, RoCell, Url};
use super::{files::FilesOp, input::InputOpt, select::SelectOpt}; use super::files::FilesOp;
use crate::{preview::PreviewLock, tasks::TasksProgress}; use crate::{preview::PreviewLock, tasks::TasksProgress};
static TX: RoCell<UnboundedSender<Event>> = RoCell::new(); static TX: RoCell<UnboundedSender<Event>> = RoCell::new();

View file

@ -2,10 +2,11 @@ use std::ops::Range;
use tokio::sync::mpsc::UnboundedSender; use tokio::sync::mpsc::UnboundedSender;
use unicode_width::UnicodeWidthStr; use unicode_width::UnicodeWidthStr;
use yazi_config::popup::{InputOpt, Position};
use yazi_shared::InputError; use yazi_shared::InputError;
use super::{mode::InputMode, op::InputOp, InputOpt, InputSnap, InputSnaps}; use super::{mode::InputMode, op::InputOp, InputSnap, InputSnaps};
use crate::{external, Position}; use crate::external;
#[derive(Default)] #[derive(Default)]
pub struct Input { pub struct Input {

View file

@ -2,7 +2,6 @@ mod commands;
mod input; mod input;
mod mode; mod mode;
mod op; mod op;
mod option;
mod shell; mod shell;
mod snap; mod snap;
mod snaps; mod snaps;
@ -10,6 +9,5 @@ mod snaps;
pub use input::*; pub use input::*;
pub use mode::*; pub use mode::*;
use op::*; use op::*;
pub use option::*;
use snap::*; use snap::*;
use snaps::*; use snaps::*;

View file

@ -1,83 +0,0 @@
use yazi_config::popup::{Offset as CfgOffset, Position as CfgPosition};
use crate::{Position, Offset};
#[derive(Default)]
pub struct InputOpt {
pub title: String,
pub value: String,
pub position: Position,
pub realtime: bool,
pub completion: bool,
pub highlight: bool,
}
macro_rules! gen_method {
($func_name:ident, $position:ident) => {
pub fn $func_name(title: impl AsRef<str>, rect: Offset) -> InputOpt {
InputOpt {
title: title.as_ref().to_owned(),
position: Position::$position(rect),
..Default::default()
}
}
};
}
impl InputOpt {
gen_method!(top_left, TopLeft);
gen_method!(top_right, TopRight);
gen_method!(top_center, TopCenter);
gen_method!(center, Center);
gen_method!(bottom_center, BottomCenter);
gen_method!(bottom_left, BottomLeft);
gen_method!(bottom_right, BottomRight);
gen_method!(hovered, Hovered);
pub fn from_cfg(title: impl AsRef<str>, pos: &CfgPosition, rect: &CfgOffset) -> Self {
let rect =
Offset { x_offset: rect.x, y_offset: rect.y, width: rect.width, height: rect.height };
match pos {
CfgPosition::TopLeft => Self::top_left(title, rect),
CfgPosition::TopRight => Self::top_right(title, rect),
CfgPosition::TopCenter => Self::top_center(title, rect),
CfgPosition::Center => Self::center(title, rect),
CfgPosition::BottomCenter => Self::bottom_center(title, rect),
CfgPosition::BottomLeft => Self::bottom_left(title, rect),
CfgPosition::BottomRight => Self::bottom_right(title, rect),
CfgPosition::Hovered => Self::hovered(title, rect),
}
}
#[inline]
pub fn with_value(mut self, value: impl AsRef<str>) -> Self {
self.value = value.as_ref().to_owned();
self
}
#[inline]
pub fn with_realtime(mut self) -> Self {
self.realtime = true;
self
}
#[inline]
pub fn with_completion(mut self) -> Self {
self.completion = true;
self
}
#[inline]
pub fn with_highlight(mut self) -> Self {
self.highlight = true;
self
}
}

View file

@ -16,7 +16,6 @@ pub mod help;
mod highlighter; mod highlighter;
pub mod input; pub mod input;
pub mod manager; pub mod manager;
mod position;
pub mod preview; pub mod preview;
pub mod select; pub mod select;
mod step; mod step;
@ -28,7 +27,6 @@ pub use blocker::*;
pub use context::*; pub use context::*;
pub use event::*; pub use event::*;
pub use highlighter::*; pub use highlighter::*;
pub use position::*;
pub use step::*; pub use step::*;
pub fn init() { init_blocker(); } pub fn init() { init_blocker(); }

View file

@ -1,10 +1,10 @@
use std::path::{PathBuf, MAIN_SEPARATOR}; use std::path::{PathBuf, MAIN_SEPARATOR};
use tokio::fs; use tokio::fs;
use yazi_config::keymap::Exec; use yazi_config::{keymap::Exec, popup::InputOpt};
use yazi_shared::Url; use yazi_shared::Url;
use crate::{emit, files::{File, FilesOp}, input::InputOpt, manager::Manager}; use crate::{emit, files::{File, FilesOp}, manager::Manager};
pub struct Opt { pub struct Opt {
force: bool, force: bool,
@ -19,20 +19,14 @@ impl Manager {
let opt = opt.into() as Opt; let opt = opt.into() as Opt;
let cwd = self.cwd().to_owned(); let cwd = self.cwd().to_owned();
tokio::spawn(async move { tokio::spawn(async move {
let mut result = emit!(Input(InputOpt::top_center("Create:", Default::default()))); let mut result = emit!(Input(InputOpt::create()));
let Some(Ok(name)) = result.recv().await else { let Some(Ok(name)) = result.recv().await else {
return Ok(()); return Ok(());
}; };
let path = cwd.join(&name); let path = cwd.join(&name);
if !opt.force && fs::symlink_metadata(&path).await.is_ok() { if !opt.force && fs::symlink_metadata(&path).await.is_ok() {
match emit!(Input(InputOpt::top_center( match emit!(Input(InputOpt::overwrite())).recv().await {
"Overwrite an existing file? (y/N)",
Default::default()
)))
.recv()
.await
{
Some(Ok(c)) if c == "y" || c == "Y" => (), Some(Ok(c)) if c == "y" || c == "Y" => (),
_ => return Ok(()), _ => return Ok(()),
} }

View file

@ -1,9 +1,9 @@
use std::ffi::OsString; use std::ffi::OsString;
use yazi_config::{keymap::Exec, OPEN, SELECT}; use yazi_config::{keymap::Exec, popup::SelectOpt, OPEN, SELECT};
use yazi_shared::MIME_DIR; use yazi_shared::MIME_DIR;
use crate::{emit, external, manager::Manager, select::SelectOpt}; use crate::{emit, external, manager::Manager};
pub struct Opt { pub struct Opt {
interactive: bool, interactive: bool,
@ -20,12 +20,8 @@ impl Manager {
return; return;
} }
let result = emit!(Select(SelectOpt::from_cfg( let result =
"Open with:", emit!(Select(SelectOpt::open().with_items(openers.iter().map(|o| o.desc.clone()).collect())));
openers.iter().map(|o| o.desc.clone()).collect(),
&SELECT.open_position,
&SELECT.open_offset
)));
if let Ok(choice) = result.await { if let Ok(choice) = result.await {
emit!(Open(files, Some(openers[choice].clone()))); emit!(Open(files, Some(openers[choice].clone())));

View file

@ -1,6 +1,6 @@
use yazi_config::keymap::Exec; use yazi_config::keymap::Exec;
use crate::{emit, input::InputOpt, manager::Manager, tasks::Tasks}; use crate::{emit, manager::Manager, tasks::Tasks};
#[derive(Default)] #[derive(Default)]
pub struct Opt { pub struct Opt {

View file

@ -2,10 +2,10 @@ use std::{collections::BTreeSet, ffi::OsStr, io::{stdout, BufWriter, Write}, pat
use anyhow::{anyhow, bail, Result}; use anyhow::{anyhow, bail, Result};
use tokio::{fs::{self, OpenOptions}, io::{stdin, AsyncReadExt, AsyncWriteExt}}; use tokio::{fs::{self, OpenOptions}, io::{stdin, AsyncReadExt, AsyncWriteExt}};
use yazi_config::{keymap::Exec, INPUT, OPEN, PREVIEW}; use yazi_config::{keymap::Exec, popup::InputOpt, INPUT, OPEN, PREVIEW};
use yazi_shared::{max_common_root, Defer, Term, Url}; use yazi_shared::{max_common_root, Defer, Term, Url};
use crate::{emit, external::{self, ShellOpt}, files::{File, FilesOp}, input::InputOpt, manager::Manager, Event, BLOCKER}; use crate::{emit, external::{self, ShellOpt}, files::{File, FilesOp}, manager::Manager, Event, BLOCKER};
pub struct Opt { pub struct Opt {
force: bool, force: bool,
@ -42,10 +42,8 @@ impl Manager {
let opt = opt.into() as Opt; let opt = opt.into() as Opt;
tokio::spawn(async move { tokio::spawn(async move {
let mut result = emit!(Input( let mut result =
InputOpt::from_cfg("Rename:", &INPUT.rename_position, &INPUT.rename_offset) emit!(Input(InputOpt::rename().with_value(hovered.file_name().unwrap().to_string_lossy())));
.with_value(hovered.file_name().unwrap().to_string_lossy())
));
let Some(Ok(name)) = result.recv().await else { let Some(Ok(name)) = result.recv().await else {
return; return;
@ -57,11 +55,7 @@ impl Manager {
return; return;
} }
let mut result = emit!(Input(InputOpt::from_cfg( let mut result = emit!(Input(InputOpt::overwrite()));
"Overwrite an existing file? (y/N)",
&INPUT.rename_position,
&INPUT.rename_offset
)));
if let Some(Ok(choice)) = result.recv().await { if let Some(Ok(choice)) = result.recv().await {
if choice == "y" || choice == "Y" { if choice == "y" || choice == "Y" {
Self::rename_and_hover(hovered, Url::from(new)).await.ok(); Self::rename_and_hover(hovered, Url::from(new)).await.ok();

View file

@ -1,50 +0,0 @@
use ratatui::prelude::Rect;
#[derive(Debug, Clone, Copy)]
pub struct Offset {
pub x_offset: i16,
pub y_offset: i16,
pub width: u16,
pub height: u16,
}
impl Default for Offset {
fn default() -> Self { Self { x_offset: 0, y_offset: 2, width: 50, height: 3 } }
}
#[derive(Debug, Clone)]
pub enum Position {
TopLeft(Offset),
TopRight(Offset),
TopCenter(Offset),
Center(Offset),
BottomCenter(Offset),
BottomLeft(Offset),
BottomRight(Offset),
Hovered(Offset),
Sticky(Offset, Rect),
}
impl Default for Position {
fn default() -> Self { Self::TopCenter(Offset::default()) }
}
impl Position {
#[inline]
pub fn offset(&self) -> &Offset {
match self {
Position::TopLeft(offset) => offset,
Position::TopRight(offset) => offset,
Position::TopCenter(offset) => offset,
Position::Center(offset) => offset,
Position::BottomCenter(offset) => offset,
Position::BottomLeft(offset) => offset,
Position::BottomRight(offset) => offset,
Position::Hovered(offset) => offset,
Position::Sticky(offset, _) => offset,
}
}
#[inline]
pub fn dimension(&self) -> (u16, u16) { (self.offset().width, self.offset().height) }
}

View file

@ -1,8 +1,6 @@
mod commands; mod commands;
mod option;
mod select; mod select;
pub use option::*;
pub use select::*; pub use select::*;
pub const SELECT_PADDING: u16 = 2; pub const SELECT_PADDING: u16 = 2;

View file

@ -1,59 +0,0 @@
use yazi_config::popup::{Offset as CfgOffset, Position as CfgPosition};
use crate::{Position, Offset};
pub struct SelectOpt {
pub title: String,
pub items: Vec<String>,
pub position: Position,
}
macro_rules! gen_method {
($func_name:ident, $position:ident) => {
pub fn $func_name(title: &str, items: Vec<String>, rect: Offset) -> SelectOpt {
let height = 2
+ items.len().min(
5, // TODO: hardcode
) as u16;
Self {
title: title.to_owned(),
items,
position: Position::$position(Offset { height, ..rect }),
}
}
};
}
impl SelectOpt {
gen_method!(top_left, TopLeft);
gen_method!(top_right, TopRight);
gen_method!(top_center, TopCenter);
gen_method!(center, Center);
gen_method!(bottom_center, BottomCenter);
gen_method!(bottom_left, BottomLeft);
gen_method!(bottom_right, BottomRight);
gen_method!(hovered, Hovered);
pub fn from_cfg(title: &str, items: Vec<String>, pos: &CfgPosition, rect: &CfgOffset) -> Self {
let rect =
Offset { x_offset: rect.x, y_offset: rect.y, width: rect.width, height: rect.height };
match pos {
CfgPosition::TopLeft => Self::top_left(title, items, rect),
CfgPosition::TopRight => Self::top_right(title, items, rect),
CfgPosition::TopCenter => Self::top_center(title, items, rect),
CfgPosition::Center => Self::center(title, items, rect),
CfgPosition::BottomCenter => Self::bottom_center(title, items, rect),
CfgPosition::BottomLeft => Self::bottom_left(title, items, rect),
CfgPosition::BottomRight => Self::bottom_right(title, items, rect),
CfgPosition::Hovered => Self::hovered(title, items, rect),
}
}
}

View file

@ -1,8 +1,6 @@
use anyhow::Result; use anyhow::Result;
use tokio::sync::oneshot::Sender; use tokio::sync::oneshot::Sender;
use yazi_config::popup::{Position, SelectOpt};
use super::SelectOpt;
use crate::Position;
#[derive(Default)] #[derive(Default)]
pub struct Select { pub struct Select {

View file

@ -2,10 +2,10 @@ use std::{mem, time::Duration};
use tokio::{fs, pin}; use tokio::{fs, pin};
use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt}; use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
use yazi_config::{keymap::{Exec, KeymapLayer}, INPUT}; use yazi_config::{keymap::{Exec, KeymapLayer}, popup::InputOpt};
use yazi_shared::{expand_path, Debounce, InputError, Url}; use yazi_shared::{expand_path, Debounce, InputError, Url};
use crate::{emit, input::InputOpt, tab::Tab}; use crate::{emit, tab::Tab};
pub struct Opt { pub struct Opt {
target: Url, target: Url,
@ -65,11 +65,7 @@ impl Tab {
let opt = opt.into() as Opt; let opt = opt.into() as Opt;
tokio::spawn(async move { tokio::spawn(async move {
let rx = emit!(Input( let rx = emit!(Input(InputOpt::cd().with_value(opt.target.to_string_lossy())));
InputOpt::from_cfg("Change directory:", &INPUT.cd_position, &INPUT.cd_offset)
.with_value(opt.target.to_string_lossy())
.with_completion()
));
let rx = Debounce::new(UnboundedReceiverStream::new(rx), Duration::from_millis(50)); let rx = Debounce::new(UnboundedReceiverStream::new(rx), Duration::from_millis(50));
pin!(rx); pin!(rx);

View file

@ -2,10 +2,10 @@ use std::time::Duration;
use tokio::pin; use tokio::pin;
use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt}; use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
use yazi_config::{keymap::{Exec, KeymapLayer}, INPUT}; use yazi_config::{keymap::{Exec, KeymapLayer}, popup::InputOpt, INPUT};
use yazi_shared::{Debounce, InputError}; use yazi_shared::{Debounce, InputError};
use crate::{emit, input::InputOpt, tab::{Finder, FinderCase, Tab}}; use crate::{emit, tab::{Finder, FinderCase, Tab}};
pub struct Opt<'a> { pub struct Opt<'a> {
query: Option<&'a str>, query: Option<&'a str>,
@ -40,9 +40,7 @@ impl Tab {
let opt = opt.into() as Opt; let opt = opt.into() as Opt;
tokio::spawn(async move { tokio::spawn(async move {
let title = if opt.prev { "Find previous:" } else { "Find next:" }; let title = if opt.prev { "Find previous:" } else { "Find next:" };
let rx = emit!(Input( let rx = emit!(Input(InputOpt::find(opt.prev)));
InputOpt::from_cfg(title, &INPUT.find_position, &INPUT.find_offset).with_realtime()
));
let rx = Debounce::new(UnboundedReceiverStream::new(rx), Duration::from_millis(50)); let rx = Debounce::new(UnboundedReceiverStream::new(rx), Duration::from_millis(50));
pin!(rx); pin!(rx);

View file

@ -3,9 +3,9 @@ use std::{mem, time::Duration};
use anyhow::bail; use anyhow::bail;
use tokio::pin; use tokio::pin;
use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt}; use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
use yazi_config::{keymap::{Exec, KeymapLayer}, INPUT}; use yazi_config::{keymap::{Exec, KeymapLayer}, popup::InputOpt, INPUT};
use crate::{emit, external, files::FilesOp, input::InputOpt, tab::Tab}; use crate::{emit, external, files::FilesOp, tab::Tab};
pub struct Opt { pub struct Opt {
pub type_: OptType, pub type_: OptType,
@ -45,9 +45,7 @@ impl Tab {
let hidden = self.conf.show_hidden; let hidden = self.conf.show_hidden;
self.search = Some(tokio::spawn(async move { self.search = Some(tokio::spawn(async move {
let Some(Ok(subject)) = emit!(Input(InputOpt::from_cfg("Search:", &INPUT.cd_position, &INPUT.cd_offset))).recv().await else { let Some(Ok(subject)) = emit!(Input(InputOpt::search())).recv().await else { bail!("") };
bail!("")
};
cwd = cwd.into_search(subject.clone()); cwd = cwd.into_search(subject.clone());
let rx = if opt.type_ == OptType::Rg { let rx = if opt.type_ == OptType::Rg {

View file

@ -1,6 +1,6 @@
use yazi_config::{keymap::Exec, open::Opener, INPUT}; use yazi_config::{keymap::Exec, open::Opener, popup::InputOpt, INPUT};
use crate::{emit, input::InputOpt, tab::Tab}; use crate::{emit, tab::Tab};
pub struct Opt { pub struct Opt {
cmd: String, cmd: String,
@ -29,12 +29,7 @@ impl Tab {
let mut opt = opt.into() as Opt; let mut opt = opt.into() as Opt;
tokio::spawn(async move { tokio::spawn(async move {
if !opt.confirm || opt.cmd.is_empty() { if !opt.confirm || opt.cmd.is_empty() {
let title = if opt.block { "Shell (block):" } else { "Shell:" }; let mut result = emit!(Input(InputOpt::shell(opt.block).with_value(opt.cmd)));
let mut result = emit!(Input(
InputOpt::from_cfg(title, &INPUT.shell_position, &INPUT.shell_offset)
.with_value(opt.cmd)
.with_highlight()
));
match result.recv().await { match result.recv().await {
Some(Ok(e)) => opt.cmd = e, Some(Ok(e)) => opt.cmd = e,
_ => return, _ => return,

View file

@ -2,11 +2,11 @@ use std::{collections::{BTreeMap, HashMap, HashSet}, ffi::OsStr, path::Path, syn
use serde::Serialize; use serde::Serialize;
use tracing::debug; use tracing::debug;
use yazi_config::{manager::SortBy, open::Opener, OPEN}; use yazi_config::{manager::SortBy, open::Opener, popup::InputOpt, OPEN};
use yazi_shared::{MimeKind, Term, Url}; use yazi_shared::{MimeKind, Term, Url};
use super::{running::Running, task::TaskSummary, Scheduler, TASKS_PADDING, TASKS_PERCENT}; use super::{running::Running, task::TaskSummary, Scheduler, TASKS_PADDING, TASKS_PERCENT};
use crate::{emit, files::{File, Files}, input::InputOpt}; use crate::{emit, files::{File, Files}};
pub struct Tasks { pub struct Tasks {
pub(super) scheduler: Arc<Scheduler>, pub(super) scheduler: Arc<Scheduler>,
@ -110,13 +110,11 @@ impl Tasks {
let scheduler = self.scheduler.clone(); let scheduler = self.scheduler.clone();
tokio::spawn(async move { tokio::spawn(async move {
let s = if targets.len() > 1 { "s" } else { "" }; let mut result = emit!(Input(if permanently {
let prompt = if permanently { InputOpt::delete(targets.len())
format!("Delete {} selected file{s} permanently? (y/N)", targets.len())
} else { } else {
format!("Move {} selected file{s} to trash? (y/N)", targets.len()) InputOpt::trash(targets.len())
}; }));
let mut result = emit!(Input(InputOpt::hovered(prompt, Default::default())));
if let Some(Ok(choice)) = result.recv().await { if let Some(Ok(choice)) = result.recv().await {
if choice != "y" && choice != "Y" { if choice != "y" && choice != "Y" {