mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
..
This commit is contained in:
parent
00ba9bdb0e
commit
6380791aca
15 changed files with 103 additions and 65 deletions
|
|
@ -91,7 +91,7 @@ it will automatically use the "Window system protocol" to display images -- this
|
||||||
- [x] Integration with fzf, zoxide for fast directory navigation
|
- [x] Integration with fzf, zoxide for fast directory navigation
|
||||||
- [x] Integration with fd, rg for fuzzy file searching
|
- [x] Integration with fd, rg for fuzzy file searching
|
||||||
- [x] Documentation of commands and options
|
- [x] Documentation of commands and options
|
||||||
- [ ] Support for Überzug++ for image previews with X11/wayland environment
|
- [x] Support for Überzug++ for image previews with X11/wayland environment
|
||||||
- [ ] Batch renaming support
|
- [ ] Batch renaming support
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ pub enum PreviewAdaptor {
|
||||||
Iterm2,
|
Iterm2,
|
||||||
|
|
||||||
// Supported by Überzug++
|
// Supported by Überzug++
|
||||||
|
Sixel,
|
||||||
X11,
|
X11,
|
||||||
Wayland,
|
Wayland,
|
||||||
Sixel,
|
|
||||||
Chafa,
|
Chafa,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,9 +43,9 @@ impl ToString for PreviewAdaptor {
|
||||||
match self {
|
match self {
|
||||||
PreviewAdaptor::Kitty => "kitty",
|
PreviewAdaptor::Kitty => "kitty",
|
||||||
PreviewAdaptor::Iterm2 => "iterm2",
|
PreviewAdaptor::Iterm2 => "iterm2",
|
||||||
|
PreviewAdaptor::Sixel => "sixel",
|
||||||
PreviewAdaptor::X11 => "x11",
|
PreviewAdaptor::X11 => "x11",
|
||||||
PreviewAdaptor::Wayland => "wayland",
|
PreviewAdaptor::Wayland => "wayland",
|
||||||
PreviewAdaptor::Sixel => "sixel",
|
|
||||||
PreviewAdaptor::Chafa => "chafa",
|
PreviewAdaptor::Chafa => "chafa",
|
||||||
}
|
}
|
||||||
.to_string()
|
.to_string()
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use crate::config::{preview::PreviewAdaptor, PREVIEW};
|
||||||
static IMAGE_SHOWN: AtomicBool = AtomicBool::new(false);
|
static IMAGE_SHOWN: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
static UEBERZUG: Lazy<Option<UnboundedSender<Option<(PathBuf, Rect)>>>> =
|
static UEBERZUG: Lazy<Option<UnboundedSender<Option<(PathBuf, Rect)>>>> =
|
||||||
Lazy::new(|| if PREVIEW.adaptor.needs_ueberzug() { Ueberzug::init().ok() } else { None });
|
Lazy::new(|| if PREVIEW.adaptor.needs_ueberzug() { Ueberzug::start().ok() } else { None });
|
||||||
|
|
||||||
pub struct Adaptor;
|
pub struct Adaptor;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use crate::config::PREVIEW;
|
||||||
pub(super) struct Ueberzug;
|
pub(super) struct Ueberzug;
|
||||||
|
|
||||||
impl Ueberzug {
|
impl Ueberzug {
|
||||||
pub(super) fn init() -> Result<UnboundedSender<Option<(PathBuf, Rect)>>> {
|
pub(super) fn start() -> Result<UnboundedSender<Option<(PathBuf, Rect)>>> {
|
||||||
let mut child = Self::create_demon().ok();
|
let mut child = Self::create_demon().ok();
|
||||||
let (tx, mut rx) = mpsc::unbounded_channel();
|
let (tx, mut rx) = mpsc::unbounded_channel();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ pub enum Event {
|
||||||
Pages(usize),
|
Pages(usize),
|
||||||
Mimetype(BTreeMap<PathBuf, String>),
|
Mimetype(BTreeMap<PathBuf, String>),
|
||||||
Hover(Option<File>),
|
Hover(Option<File>),
|
||||||
Preview(PathBuf, PreviewData),
|
Preview(PathBuf, String, PreviewData),
|
||||||
|
|
||||||
// Input
|
// Input
|
||||||
Select(SelectOpt, oneshot::Sender<Result<usize>>),
|
Select(SelectOpt, oneshot::Sender<Result<usize>>),
|
||||||
|
|
@ -94,8 +94,8 @@ macro_rules! emit {
|
||||||
(Hover($file:expr)) => {
|
(Hover($file:expr)) => {
|
||||||
$crate::core::Event::Hover(Some($file)).emit();
|
$crate::core::Event::Hover(Some($file)).emit();
|
||||||
};
|
};
|
||||||
(Preview($path:expr, $data:expr)) => {
|
(Preview($path:expr, $mime:expr, $data:expr)) => {
|
||||||
$crate::core::Event::Preview($path, $data).emit();
|
$crate::core::Event::Preview($path, $mime, $data).emit();
|
||||||
};
|
};
|
||||||
|
|
||||||
(Select($opt:expr)) => {{
|
(Select($opt:expr)) => {{
|
||||||
|
|
|
||||||
|
|
@ -49,20 +49,24 @@ impl Manager {
|
||||||
self.watcher.watch(to_watch);
|
self.watcher.watch(to_watch);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn preview(&mut self) -> bool {
|
pub fn preview(&mut self, show_image: bool) -> bool {
|
||||||
let hovered = if let Some(h) = self.hovered() {
|
let hovered = if let Some(h) = self.hovered() {
|
||||||
h.clone()
|
h.clone()
|
||||||
} else {
|
} else {
|
||||||
return self.active_mut().preview.reset();
|
return self.active_mut().preview.reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if !show_image {
|
||||||
|
self.active_mut().preview.reset_image();
|
||||||
|
}
|
||||||
|
|
||||||
if hovered.meta.is_dir() {
|
if hovered.meta.is_dir() {
|
||||||
self.active_mut().preview.go(&hovered.path, MIME_DIR);
|
self.active_mut().preview.go(&hovered.path, MIME_DIR, show_image);
|
||||||
if self.active().history(&hovered.path).is_some() {
|
if self.active().history(&hovered.path).is_some() {
|
||||||
emit!(Preview(hovered.path, PreviewData::Folder));
|
emit!(Preview(hovered.path, MIME_DIR.to_owned(), PreviewData::Folder));
|
||||||
}
|
}
|
||||||
} else if let Some(mime) = self.mimetype.get(&hovered.path).cloned() {
|
} else if let Some(mime) = self.mimetype.get(&hovered.path).cloned() {
|
||||||
self.active_mut().preview.go(&hovered.path, &mime);
|
self.active_mut().preview.go(&hovered.path, &mime, show_image);
|
||||||
} else {
|
} else {
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
if let Ok(mimes) = external::file(&[hovered.path]).await {
|
if let Ok(mimes) = external::file(&[hovered.path]).await {
|
||||||
|
|
@ -300,11 +304,10 @@ impl Manager {
|
||||||
tasks.precache_video(&mimes);
|
tasks.precache_video(&mimes);
|
||||||
|
|
||||||
self.mimetype.extend(mimes);
|
self.mimetype.extend(mimes);
|
||||||
self.preview();
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_preview(&mut self, path: PathBuf, data: PreviewData) -> bool {
|
pub fn update_preview(&mut self, path: PathBuf, mime: String, data: PreviewData) -> bool {
|
||||||
let hovered = if let Some(ref h) = self.current().hovered {
|
let hovered = if let Some(ref h) = self.current().hovered {
|
||||||
h.path()
|
h.path()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -316,7 +319,7 @@ impl Manager {
|
||||||
}
|
}
|
||||||
|
|
||||||
let preview = &mut self.active_mut().preview;
|
let preview = &mut self.active_mut().preview;
|
||||||
preview.path = path;
|
preview.lock = Some((path, mime));
|
||||||
preview.data = data;
|
preview.data = data;
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{fs::File, io::{BufRead, BufReader}, path::{Path, PathBuf}, sync::OnceLock};
|
use std::{fs::File, io::{BufRead, BufReader}, mem, path::{Path, PathBuf}, sync::OnceLock};
|
||||||
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use ratatui::prelude::Rect;
|
use ratatui::prelude::Rect;
|
||||||
|
|
@ -11,8 +11,9 @@ use crate::{config::{PREVIEW, THEME}, core::{adaptor::Adaptor, external, files::
|
||||||
static SYNTECT_SYNTAX: OnceLock<SyntaxSet> = OnceLock::new();
|
static SYNTECT_SYNTAX: OnceLock<SyntaxSet> = OnceLock::new();
|
||||||
static SYNTECT_THEME: OnceLock<Theme> = OnceLock::new();
|
static SYNTECT_THEME: OnceLock<Theme> = OnceLock::new();
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
pub struct Preview {
|
pub struct Preview {
|
||||||
pub path: PathBuf,
|
pub lock: Option<(PathBuf, String)>,
|
||||||
pub data: PreviewData,
|
pub data: PreviewData,
|
||||||
|
|
||||||
handle: Option<JoinHandle<()>>,
|
handle: Option<JoinHandle<()>>,
|
||||||
|
|
@ -24,18 +25,10 @@ pub enum PreviewData {
|
||||||
None,
|
None,
|
||||||
Folder,
|
Folder,
|
||||||
Text(String),
|
Text(String),
|
||||||
|
Image,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Preview {
|
impl Preview {
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
path: Default::default(),
|
|
||||||
data: Default::default(),
|
|
||||||
|
|
||||||
handle: Default::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn rect() -> Rect {
|
fn rect() -> Rect {
|
||||||
let s = tty_size();
|
let s = tty_size();
|
||||||
|
|
||||||
|
|
@ -50,12 +43,19 @@ impl Preview {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn go(&mut self, path: &Path, mime: &str) {
|
pub fn go(&mut self, path: &Path, mime: &str, show_image: bool) {
|
||||||
|
let kind = MimeKind::new(&mime);
|
||||||
|
if !show_image && matches!(kind, MimeKind::Image | MimeKind::Video) {
|
||||||
|
return;
|
||||||
|
} else if self.same(path, mime) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
self.reset();
|
self.reset();
|
||||||
|
}
|
||||||
|
|
||||||
let (path, mime) = (path.to_path_buf(), mime.to_owned());
|
let (path, mime) = (path.to_path_buf(), mime.to_owned());
|
||||||
self.handle = Some(tokio::spawn(async move {
|
self.handle = Some(tokio::spawn(async move {
|
||||||
let result = match MimeKind::new(&mime) {
|
let result = match kind {
|
||||||
MimeKind::Dir => Self::folder(&path).await,
|
MimeKind::Dir => Self::folder(&path).await,
|
||||||
MimeKind::JSON => Self::json(&path).await.map(PreviewData::Text),
|
MimeKind::JSON => Self::json(&path).await.map(PreviewData::Text),
|
||||||
MimeKind::Text => Self::highlight(&path).await.map(PreviewData::Text),
|
MimeKind::Text => Self::highlight(&path).await.map(PreviewData::Text),
|
||||||
|
|
@ -65,7 +65,7 @@ impl Preview {
|
||||||
MimeKind::Others => Err(anyhow!("Unsupported mimetype: {}", mime)),
|
MimeKind::Others => Err(anyhow!("Unsupported mimetype: {}", mime)),
|
||||||
};
|
};
|
||||||
|
|
||||||
emit!(Preview(path, result.unwrap_or_default()));
|
emit!(Preview(path, mime, result.unwrap_or_default()));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,13 +73,22 @@ impl Preview {
|
||||||
self.handle.take().map(|h| h.abort());
|
self.handle.take().map(|h| h.abort());
|
||||||
Adaptor::image_hide(Self::rect());
|
Adaptor::image_hide(Self::rect());
|
||||||
|
|
||||||
if self.path == PathBuf::default() {
|
self.lock = None;
|
||||||
return false;
|
!matches!(
|
||||||
|
mem::replace(&mut self.data, PreviewData::None),
|
||||||
|
PreviewData::None | PreviewData::Image
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.path = Default::default();
|
pub fn reset_image(&mut self) -> bool {
|
||||||
self.data = Default::default();
|
self.handle.take().map(|h| h.abort());
|
||||||
true
|
Adaptor::image_hide(Self::rect());
|
||||||
|
|
||||||
|
if matches!(self.data, PreviewData::Image) {
|
||||||
|
self.lock = None;
|
||||||
|
self.data = PreviewData::None;
|
||||||
|
}
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn folder(path: &Path) -> Result<PreviewData> {
|
pub async fn folder(path: &Path) -> Result<PreviewData> {
|
||||||
|
|
@ -98,7 +107,7 @@ impl Preview {
|
||||||
}
|
}
|
||||||
|
|
||||||
Adaptor::image_show(path, Self::rect()).await?;
|
Adaptor::image_show(path, Self::rect()).await?;
|
||||||
Ok(PreviewData::None)
|
Ok(PreviewData::Image)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn video(path: &Path) -> Result<PreviewData> {
|
pub async fn video(path: &Path) -> Result<PreviewData> {
|
||||||
|
|
@ -166,3 +175,15 @@ impl Preview {
|
||||||
.await?
|
.await?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Preview {
|
||||||
|
#[inline]
|
||||||
|
pub fn same(&self, path: &Path, mime: &str) -> bool {
|
||||||
|
self.lock.as_ref().map(|(p, m)| p == path && m == mime).unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn same_path(&self, path: &Path) -> bool {
|
||||||
|
self.lock.as_ref().map(|(p, _)| p == path).unwrap_or(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ impl Tab {
|
||||||
search: None,
|
search: None,
|
||||||
|
|
||||||
history: Default::default(),
|
history: Default::default(),
|
||||||
preview: Preview::new(),
|
preview: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ impl Tasks {
|
||||||
|
|
||||||
pub fn toggle(&mut self) -> bool {
|
pub fn toggle(&mut self) -> bool {
|
||||||
self.visible = !self.visible;
|
self.visible = !self.visible;
|
||||||
|
emit!(Hover); // Show/hide preview for images
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ impl Which {
|
||||||
.filter(|s| s.on.len() > 1 && s.on[0] == *key)
|
.filter(|s| s.on.len() > 1 && s.on[0] == *key)
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
self.visible = true;
|
self.switch(true);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -37,16 +37,22 @@ impl Which {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if self.cands.is_empty() {
|
if self.cands.is_empty() {
|
||||||
self.visible = false;
|
self.switch(false);
|
||||||
} else if self.cands.len() == 1 {
|
} else if self.cands.len() == 1 {
|
||||||
self.visible = false;
|
self.switch(false);
|
||||||
emit!(Ctrl(self.cands.remove(0), self.layer));
|
emit!(Ctrl(self.cands.remove(0), self.layer));
|
||||||
} else if let Some(i) = self.cands.iter().position(|c| c.on.len() == self.times + 1) {
|
} else if let Some(i) = self.cands.iter().position(|c| c.on.len() == self.times + 1) {
|
||||||
|
self.switch(false);
|
||||||
emit!(Ctrl(self.cands.remove(i), self.layer));
|
emit!(Ctrl(self.cands.remove(i), self.layer));
|
||||||
self.visible = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.times += 1;
|
self.times += 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn switch(&mut self, state: bool) {
|
||||||
|
self.visible = state;
|
||||||
|
emit!(Hover); // Show/hide preview for images
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ impl App {
|
||||||
let _ = term.draw(|f| {
|
let _ = term.draw(|f| {
|
||||||
f.render_widget(Root::new(&mut self.cx), f.size());
|
f.render_widget(Root::new(&mut self.cx), f.size());
|
||||||
|
|
||||||
if let Some((x, y)) = self.cx.cursor {
|
if let Some((x, y)) = self.cx.cursor() {
|
||||||
f.set_cursor(x, y);
|
f.set_cursor(x, y);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -64,7 +64,7 @@ impl App {
|
||||||
|
|
||||||
fn dispatch_resize(&mut self) {
|
fn dispatch_resize(&mut self) {
|
||||||
self.cx.manager.current_mut().set_page(true);
|
self.cx.manager.current_mut().set_page(true);
|
||||||
self.cx.manager.preview();
|
self.cx.manager.preview(self.cx.image_layer());
|
||||||
emit!(Render);
|
emit!(Render);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -123,17 +123,17 @@ impl App {
|
||||||
Event::Mimetype(mimes) => {
|
Event::Mimetype(mimes) => {
|
||||||
if manager.update_mimetype(mimes, tasks) {
|
if manager.update_mimetype(mimes, tasks) {
|
||||||
emit!(Render);
|
emit!(Render);
|
||||||
|
self.cx.manager.preview(self.cx.image_layer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::Hover(file) => {
|
Event::Hover(file) => {
|
||||||
let mut b = file.map(|f| manager.current_mut().hover_force(f)).unwrap_or(false);
|
if file.map(|f| manager.current_mut().hover_force(f)).unwrap_or(false) {
|
||||||
b |= manager.preview();
|
|
||||||
if b {
|
|
||||||
emit!(Render);
|
emit!(Render);
|
||||||
}
|
}
|
||||||
|
self.cx.manager.preview(self.cx.image_layer());
|
||||||
}
|
}
|
||||||
Event::Preview(file, data) => {
|
Event::Preview(path, mime, data) => {
|
||||||
manager.update_preview(file, data);
|
manager.update_preview(path, mime, data);
|
||||||
emit!(Render);
|
emit!(Render);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
use crate::{config::keymap::KeymapLayer, core::{input::Input, manager::Manager, select::Select, tasks::Tasks, which::Which, Position}, misc::tty_size};
|
use crate::{config::keymap::KeymapLayer, core::{input::Input, manager::Manager, select::Select, tasks::Tasks, which::Which, Position}, misc::tty_size};
|
||||||
|
|
||||||
pub struct Ctx {
|
pub struct Ctx {
|
||||||
pub cursor: Option<(u16, u16)>,
|
|
||||||
|
|
||||||
pub manager: Manager,
|
pub manager: Manager,
|
||||||
pub which: Which,
|
pub which: Which,
|
||||||
pub select: Select,
|
pub select: Select,
|
||||||
|
|
@ -13,8 +11,6 @@ pub struct Ctx {
|
||||||
impl Ctx {
|
impl Ctx {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
cursor: None,
|
|
||||||
|
|
||||||
manager: Manager::new(),
|
manager: Manager::new(),
|
||||||
which: Default::default(),
|
which: Default::default(),
|
||||||
select: Default::default(),
|
select: Default::default(),
|
||||||
|
|
@ -23,6 +19,14 @@ impl Ctx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn cursor(&self) -> Option<(u16, u16)> {
|
||||||
|
if self.input.visible {
|
||||||
|
return Some(self.input.cursor());
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn layer(&self) -> KeymapLayer {
|
pub fn layer(&self) -> KeymapLayer {
|
||||||
if self.which.visible {
|
if self.which.visible {
|
||||||
|
|
@ -38,6 +42,15 @@ impl Ctx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn image_layer(&self) -> bool {
|
||||||
|
match self.layer() {
|
||||||
|
KeymapLayer::Which => false,
|
||||||
|
KeymapLayer::Tasks => false,
|
||||||
|
_ => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn position(&self, pos: Position) -> Position {
|
pub fn position(&self, pos: Position) -> Position {
|
||||||
match pos {
|
match pos {
|
||||||
Position::Top => Position::Coords((tty_size().ws_col / 2).saturating_sub(25), 2),
|
Position::Top => Position::Coords((tty_size().ws_col / 2).saturating_sub(25), 2),
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,6 @@ impl<'a> Widget for Preview<'a> {
|
||||||
buf,
|
buf,
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: image
|
|
||||||
// if self.cx.input.visible || self.cx.select.visible || self.cx.tasks.visible {
|
|
||||||
// }
|
|
||||||
|
|
||||||
let manager = &self.cx.manager;
|
let manager = &self.cx.manager;
|
||||||
let hovered = if let Some(h) = manager.hovered() {
|
let hovered = if let Some(h) = manager.hovered() {
|
||||||
h.path()
|
h.path()
|
||||||
|
|
@ -36,7 +32,7 @@ impl<'a> Widget for Preview<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let preview = manager.active().preview();
|
let preview = manager.active().preview();
|
||||||
if preview.path != hovered {
|
if !preview.same_path(&hovered) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -51,6 +47,7 @@ impl<'a> Widget for Preview<'a> {
|
||||||
let p = Paragraph::new(s.as_bytes().into_text().unwrap());
|
let p = Paragraph::new(s.as_bytes().into_text().unwrap());
|
||||||
p.render(area, buf);
|
p.render(area, buf);
|
||||||
}
|
}
|
||||||
|
PreviewData::Image => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,11 @@ use ratatui::{buffer::Buffer, layout::{Constraint, Direction, Layout, Rect}, wid
|
||||||
use super::{header, manager, status, tasks, which::Which, Ctx, Input, Select};
|
use super::{header, manager, status, tasks, which::Which, Ctx, Input, Select};
|
||||||
|
|
||||||
pub struct Root<'a> {
|
pub struct Root<'a> {
|
||||||
cx: &'a mut Ctx,
|
cx: &'a Ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Root<'a> {
|
impl<'a> Root<'a> {
|
||||||
pub fn new(cx: &'a mut Ctx) -> Self { Self { cx } }
|
pub fn new(cx: &'a Ctx) -> Self { Self { cx } }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Widget for Root<'a> {
|
impl<'a> Widget for Root<'a> {
|
||||||
|
|
@ -31,9 +31,6 @@ impl<'a> Widget for Root<'a> {
|
||||||
|
|
||||||
if self.cx.input.visible {
|
if self.cx.input.visible {
|
||||||
Input::new(self.cx).render(area, buf);
|
Input::new(self.cx).render(area, buf);
|
||||||
self.cx.cursor = Some(self.cx.input.cursor());
|
|
||||||
} else {
|
|
||||||
self.cx.cursor = None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.cx.which.visible {
|
if self.cx.which.visible {
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,11 @@ use super::Side;
|
||||||
use crate::ui::Ctx;
|
use crate::ui::Ctx;
|
||||||
|
|
||||||
pub struct Which<'a> {
|
pub struct Which<'a> {
|
||||||
cx: &'a mut Ctx,
|
cx: &'a Ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Which<'a> {
|
impl<'a> Which<'a> {
|
||||||
pub fn new(cx: &'a mut Ctx) -> Self { Self { cx } }
|
pub fn new(cx: &'a Ctx) -> Self { Self { cx } }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Widget for Which<'_> {
|
impl Widget for Which<'_> {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue