mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
refactor: tab-specific config
This commit is contained in:
parent
9d4ba510df
commit
bed8172347
21 changed files with 177 additions and 104 deletions
|
|
@ -89,13 +89,13 @@ 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.active_mut().preview_reset();
|
self.cx.manager.active_mut().preview.reset(|_| true);
|
||||||
self.cx.manager.peek(true, self.cx.image_layer());
|
self.cx.manager.peek(true, self.cx.image_layer());
|
||||||
emit!(Render);
|
emit!(Render);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dispatch_stop(&mut self, state: bool, tx: Option<oneshot::Sender<()>>) {
|
fn dispatch_stop(&mut self, state: bool, tx: Option<oneshot::Sender<()>>) {
|
||||||
self.cx.manager.active_mut().preview_reset_image();
|
self.cx.manager.active_mut().preview.reset(|l| l.is_image());
|
||||||
if state {
|
if state {
|
||||||
self.signals.stop_term(true);
|
self.signals.stop_term(true);
|
||||||
self.term = None;
|
self.term = None;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use core::{emit, files::FilesSorter, input::InputMode, tab::FinderCase, Ctx};
|
use core::{emit, input::InputMode, tab::FinderCase, Ctx};
|
||||||
|
|
||||||
use config::{keymap::{Control, Exec, Key, KeymapLayer}, manager::SortBy, KEYMAP};
|
use config::{keymap::{Control, Exec, Key, KeymapLayer}, KEYMAP};
|
||||||
use shared::{optional_bool, Url};
|
use shared::{optional_bool, Url};
|
||||||
|
|
||||||
pub(super) struct Executor;
|
pub(super) struct Executor;
|
||||||
|
|
@ -126,13 +126,7 @@ impl Executor {
|
||||||
exec.named.contains_key("block"),
|
exec.named.contains_key("block"),
|
||||||
exec.named.contains_key("confirm"),
|
exec.named.contains_key("confirm"),
|
||||||
),
|
),
|
||||||
"hidden" => {
|
"hidden" => cx.manager.active_mut().hidden(exec),
|
||||||
cx.manager.active_mut().set_show_hidden(match exec.args.get(0).map(|s| s.as_str()) {
|
|
||||||
Some("show") => Some(true),
|
|
||||||
Some("hide") => Some(false),
|
|
||||||
_ => None,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
"search" => match exec.args.get(0).map(|s| s.as_str()).unwrap_or("") {
|
"search" => match exec.args.get(0).map(|s| s.as_str()).unwrap_or("") {
|
||||||
"rg" => cx.manager.active_mut().search(true),
|
"rg" => cx.manager.active_mut().search(true),
|
||||||
"fd" => cx.manager.active_mut().search(false),
|
"fd" => cx.manager.active_mut().search(false),
|
||||||
|
|
@ -160,13 +154,7 @@ impl Executor {
|
||||||
|
|
||||||
// Sorting
|
// Sorting
|
||||||
"sort" => {
|
"sort" => {
|
||||||
let b = cx.manager.active_mut().set_sorter(FilesSorter {
|
let b = cx.manager.active_mut().sort(exec);
|
||||||
by: SortBy::try_from(exec.args.get(0).cloned().unwrap_or_default())
|
|
||||||
.unwrap_or_default(),
|
|
||||||
sensitive: exec.named.contains_key("sensitive"),
|
|
||||||
reverse: exec.named.contains_key("reverse"),
|
|
||||||
dir_first: exec.named.contains_key("dir_first"),
|
|
||||||
});
|
|
||||||
cx.tasks.precache_size(&cx.manager.current().files);
|
cx.tasks.precache_size(&cx.manager.current().files);
|
||||||
b
|
b
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ sort_by = "modified"
|
||||||
sort_sensitive = true
|
sort_sensitive = true
|
||||||
sort_reverse = true
|
sort_reverse = true
|
||||||
sort_dir_first = true
|
sort_dir_first = true
|
||||||
|
linemode = "none"
|
||||||
show_hidden = false
|
show_hidden = false
|
||||||
show_symlink = true
|
show_symlink = true
|
||||||
|
|
||||||
|
|
|
||||||
26
config/src/manager/linemode.rs
Normal file
26
config/src/manager/linemode.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
use anyhow::bail;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Default, Deserialize, Serialize, PartialEq, Eq)]
|
||||||
|
#[serde(try_from = "String")]
|
||||||
|
pub enum Linemode {
|
||||||
|
#[default]
|
||||||
|
None,
|
||||||
|
Size,
|
||||||
|
Mtime,
|
||||||
|
Permissions,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<String> for Linemode {
|
||||||
|
type Error = anyhow::Error;
|
||||||
|
|
||||||
|
fn try_from(s: String) -> Result<Self, Self::Error> {
|
||||||
|
Ok(match s.as_str() {
|
||||||
|
"none" => Self::None,
|
||||||
|
"size" => Self::Size,
|
||||||
|
"mtime" => Self::Mtime,
|
||||||
|
"permissions" => Self::Permissions,
|
||||||
|
_ => bail!("invalid linemode value: {s}"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::{ManagerLayout, SortBy};
|
use super::{Linemode, ManagerLayout, SortBy};
|
||||||
use crate::MERGED_YAZI;
|
use crate::MERGED_YAZI;
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
|
@ -14,6 +14,7 @@ pub struct Manager {
|
||||||
pub sort_dir_first: bool,
|
pub sort_dir_first: bool,
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
|
pub linemode: Linemode,
|
||||||
pub show_hidden: bool,
|
pub show_hidden: bool,
|
||||||
pub show_symlink: bool,
|
pub show_symlink: bool,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
mod layout;
|
mod layout;
|
||||||
|
mod linemode;
|
||||||
mod manager;
|
mod manager;
|
||||||
mod sorting;
|
mod sorting;
|
||||||
|
|
||||||
pub use layout::*;
|
pub use layout::*;
|
||||||
|
pub use linemode::*;
|
||||||
pub use manager::*;
|
pub use manager::*;
|
||||||
pub use sorting::*;
|
pub use sorting::*;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
|
@ -5,6 +7,7 @@ use serde::{Deserialize, Serialize};
|
||||||
#[serde(try_from = "String")]
|
#[serde(try_from = "String")]
|
||||||
pub enum SortBy {
|
pub enum SortBy {
|
||||||
#[default]
|
#[default]
|
||||||
|
None,
|
||||||
Alphabetical,
|
Alphabetical,
|
||||||
Created,
|
Created,
|
||||||
Modified,
|
Modified,
|
||||||
|
|
@ -12,11 +15,12 @@ pub enum SortBy {
|
||||||
Size,
|
Size,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<String> for SortBy {
|
impl FromStr for SortBy {
|
||||||
type Error = anyhow::Error;
|
type Err = anyhow::Error;
|
||||||
|
|
||||||
fn try_from(s: String) -> Result<Self, Self::Error> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
Ok(match s.as_str() {
|
Ok(match s {
|
||||||
|
"none" => Self::None,
|
||||||
"alphabetical" => Self::Alphabetical,
|
"alphabetical" => Self::Alphabetical,
|
||||||
"created" => Self::Created,
|
"created" => Self::Created,
|
||||||
"modified" => Self::Modified,
|
"modified" => Self::Modified,
|
||||||
|
|
@ -26,3 +30,9 @@ impl TryFrom<String> for SortBy {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<String> for SortBy {
|
||||||
|
type Error = anyhow::Error;
|
||||||
|
|
||||||
|
fn try_from(s: String) -> Result<Self, Self::Error> { Self::from_str(&s) }
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ impl FromStr for Color {
|
||||||
impl TryFrom<String> for Color {
|
impl TryFrom<String> for Color {
|
||||||
type Error = anyhow::Error;
|
type Error = anyhow::Error;
|
||||||
|
|
||||||
fn try_from(s: String) -> Result<Self, Self::Error> { Self::from_str(s.as_str()) }
|
fn try_from(s: String) -> Result<Self, Self::Error> { Self::from_str(&s) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Color> for ratatui::style::Color {
|
impl From<Color> for ratatui::style::Color {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
use std::{cmp::Ordering, collections::BTreeMap, mem};
|
use std::{cmp::Ordering, collections::BTreeMap, mem};
|
||||||
|
|
||||||
use config::{manager::SortBy, MANAGER};
|
use config::manager::SortBy;
|
||||||
use shared::{natsort, Url};
|
use shared::{natsort, Url};
|
||||||
|
|
||||||
use super::File;
|
use super::File;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
#[derive(Clone, Copy, Default, PartialEq)]
|
||||||
pub struct FilesSorter {
|
pub struct FilesSorter {
|
||||||
pub by: SortBy,
|
pub by: SortBy,
|
||||||
pub sensitive: bool,
|
pub sensitive: bool,
|
||||||
|
|
@ -13,17 +13,6 @@ pub struct FilesSorter {
|
||||||
pub dir_first: bool,
|
pub dir_first: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for FilesSorter {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
by: MANAGER.sort_by,
|
|
||||||
sensitive: MANAGER.sort_sensitive,
|
|
||||||
reverse: MANAGER.sort_reverse,
|
|
||||||
dir_first: MANAGER.sort_dir_first,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FilesSorter {
|
impl FilesSorter {
|
||||||
pub(super) fn sort(&self, items: &mut Vec<File>, sizes: &BTreeMap<Url, u64>) -> bool {
|
pub(super) fn sort(&self, items: &mut Vec<File>, sizes: &BTreeMap<Url, u64>) -> bool {
|
||||||
if items.is_empty() {
|
if items.is_empty() {
|
||||||
|
|
@ -31,6 +20,7 @@ impl FilesSorter {
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.by {
|
match self.by {
|
||||||
|
SortBy::None => return false,
|
||||||
SortBy::Alphabetical => items.sort_unstable_by(|a, b| {
|
SortBy::Alphabetical => items.sort_unstable_by(|a, b| {
|
||||||
if self.sensitive {
|
if self.sensitive {
|
||||||
return self.cmp(&*a.url, &*b.url, self.promote(a, b));
|
return self.cmp(&*a.url, &*b.url, self.promote(a, b));
|
||||||
|
|
@ -98,7 +88,7 @@ impl FilesSorter {
|
||||||
*items = new;
|
*items = new;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline(always)]
|
||||||
#[allow(clippy::collapsible_else_if)]
|
#[allow(clippy::collapsible_else_if)]
|
||||||
fn cmp<T: Ord>(&self, a: T, b: T, promote: Ordering) -> Ordering {
|
fn cmp<T: Ord>(&self, a: T, b: T, promote: Ordering) -> Ordering {
|
||||||
if promote != Ordering::Equal {
|
if promote != Ordering::Equal {
|
||||||
|
|
@ -108,7 +98,7 @@ impl FilesSorter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline(always)]
|
||||||
fn promote(&self, a: &File, b: &File) -> Ordering {
|
fn promote(&self, a: &File, b: &File) -> Ordering {
|
||||||
if self.dir_first { b.is_dir().cmp(&a.is_dir()) } else { Ordering::Equal }
|
if self.dir_first { b.is_dir().cmp(&a.is_dir()) } else { Ordering::Equal }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,12 @@ use crate::manager::Manager;
|
||||||
impl Manager {
|
impl Manager {
|
||||||
pub fn peek(&mut self, sequent: bool, show_image: bool) -> bool {
|
pub fn peek(&mut self, sequent: bool, show_image: bool) -> bool {
|
||||||
let Some(hovered) = self.hovered().cloned() else {
|
let Some(hovered) = self.hovered().cloned() else {
|
||||||
return self.active_mut().preview_reset();
|
return self.active_mut().preview.reset(|_| true);
|
||||||
};
|
};
|
||||||
|
|
||||||
let url = &hovered.url;
|
let url = &hovered.url;
|
||||||
if !show_image {
|
if !show_image {
|
||||||
self.active_mut().preview_reset_image();
|
self.active_mut().preview.reset(|l| l.is_image());
|
||||||
}
|
}
|
||||||
|
|
||||||
if hovered.is_dir() {
|
if hovered.is_dir() {
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ impl Tabs {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut tab = Tab::from(url);
|
let mut tab = Tab::from(url);
|
||||||
tab.set_show_hidden(Some(self.active().show_hidden));
|
tab.conf = self.active().conf;
|
||||||
tab.set_sorter(self.active().sorter);
|
tab.apply_files_attrs(false);
|
||||||
|
|
||||||
self.items.insert(self.idx + 1, tab);
|
self.items.insert(self.idx + 1, tab);
|
||||||
self.set_idx(self.idx + 1);
|
self.set_idx(self.idx + 1);
|
||||||
|
|
@ -83,7 +83,7 @@ impl Tabs {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_idx(&mut self, idx: usize) {
|
fn set_idx(&mut self, idx: usize) {
|
||||||
self.idx = idx;
|
self.idx = idx;
|
||||||
self.active_mut().preview_reset_image();
|
self.active_mut().preview.reset(|l| l.is_image());
|
||||||
emit!(Refresh);
|
emit!(Refresh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,8 @@ impl Tab {
|
||||||
fn escape_search(&mut self) -> bool { self.search_stop() }
|
fn escape_search(&mut self) -> bool { self.search_stop() }
|
||||||
|
|
||||||
pub fn escape(&mut self, opt: impl Into<Opt>) -> bool {
|
pub fn escape(&mut self, opt: impl Into<Opt>) -> bool {
|
||||||
let opt = opt.into();
|
let opt = opt.into().0;
|
||||||
if opt.0 == 0 {
|
if opt == 0 {
|
||||||
return self.escape_find()
|
return self.escape_find()
|
||||||
|| self.escape_visual()
|
|| self.escape_visual()
|
||||||
|| self.escape_select()
|
|| self.escape_select()
|
||||||
|
|
@ -47,16 +47,16 @@ impl Tab {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut b = false;
|
let mut b = false;
|
||||||
if opt.0 & 0b0001 != 0 {
|
if opt & 0b0001 != 0 {
|
||||||
b |= self.escape_find();
|
b |= self.escape_find();
|
||||||
}
|
}
|
||||||
if opt.0 & 0b0010 != 0 {
|
if opt & 0b0010 != 0 {
|
||||||
b |= self.escape_visual();
|
b |= self.escape_visual();
|
||||||
}
|
}
|
||||||
if opt.0 & 0b0100 != 0 {
|
if opt & 0b0100 != 0 {
|
||||||
b |= self.escape_select();
|
b |= self.escape_select();
|
||||||
}
|
}
|
||||||
if opt.0 & 0b1000 != 0 {
|
if opt & 0b1000 != 0 {
|
||||||
b |= self.escape_search();
|
b |= self.escape_search();
|
||||||
}
|
}
|
||||||
b
|
b
|
||||||
|
|
|
||||||
18
core/src/tab/commands/hidden.rs
Normal file
18
core/src/tab/commands/hidden.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
use config::keymap::Exec;
|
||||||
|
|
||||||
|
use crate::{emit, tab::Tab};
|
||||||
|
|
||||||
|
impl Tab {
|
||||||
|
pub fn hidden(&mut self, e: &Exec) -> bool {
|
||||||
|
self.conf.show_hidden = match e.args.get(0).map(|s| s.as_bytes()) {
|
||||||
|
Some(b"show") => true,
|
||||||
|
Some(b"hide") => false,
|
||||||
|
_ => !self.conf.show_hidden,
|
||||||
|
};
|
||||||
|
if self.apply_files_attrs(false) {
|
||||||
|
emit!(Peek);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,9 +5,11 @@ mod copy;
|
||||||
mod enter;
|
mod enter;
|
||||||
mod escape;
|
mod escape;
|
||||||
mod find;
|
mod find;
|
||||||
|
mod hidden;
|
||||||
mod jump;
|
mod jump;
|
||||||
mod leave;
|
mod leave;
|
||||||
mod search;
|
mod search;
|
||||||
mod select;
|
mod select;
|
||||||
mod shell;
|
mod shell;
|
||||||
|
mod sort;
|
||||||
mod visual_mode;
|
mod visual_mode;
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ impl Tab {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut cwd = self.current.cwd.clone();
|
let mut cwd = self.current.cwd.clone();
|
||||||
let hidden = self.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::top("Search:"))).recv().await else {
|
let Some(Ok(subject)) = emit!(Input(InputOpt::top("Search:"))).recv().await else {
|
||||||
|
|
@ -49,7 +49,7 @@ impl Tab {
|
||||||
handle.abort();
|
handle.abort();
|
||||||
}
|
}
|
||||||
if self.current.cwd.is_search() {
|
if self.current.cwd.is_search() {
|
||||||
self.preview_reset_image();
|
self.preview.reset(|l| l.is_image());
|
||||||
|
|
||||||
let rep = self.history_new(&self.current.cwd.to_regular());
|
let rep = self.history_new(&self.current.cwd.to_regular());
|
||||||
drop(mem::replace(&mut self.current, rep));
|
drop(mem::replace(&mut self.current, rep));
|
||||||
|
|
|
||||||
18
core/src/tab/commands/sort.rs
Normal file
18
core/src/tab/commands/sort.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use config::{keymap::Exec, manager::SortBy};
|
||||||
|
|
||||||
|
use crate::tab::Tab;
|
||||||
|
|
||||||
|
impl Tab {
|
||||||
|
pub fn sort(&mut self, e: &Exec) -> bool {
|
||||||
|
if let Some(by) = e.args.get(0) {
|
||||||
|
self.conf.sort_by = SortBy::from_str(by).unwrap_or_default();
|
||||||
|
}
|
||||||
|
self.conf.sort_sensitive = e.named.contains_key("sensitive");
|
||||||
|
self.conf.sort_reverse = e.named.contains_key("reverse");
|
||||||
|
self.conf.sort_dir_first = e.named.contains_key("dir_first");
|
||||||
|
|
||||||
|
self.apply_files_attrs(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
50
core/src/tab/config.rs
Normal file
50
core/src/tab/config.rs
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
use config::{manager::{Linemode, SortBy}, MANAGER};
|
||||||
|
|
||||||
|
use crate::files::FilesSorter;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
|
pub struct Config {
|
||||||
|
// Sorting
|
||||||
|
pub sort_by: SortBy,
|
||||||
|
pub sort_sensitive: bool,
|
||||||
|
pub sort_reverse: bool,
|
||||||
|
pub sort_dir_first: bool,
|
||||||
|
|
||||||
|
// Display
|
||||||
|
pub linemode: Linemode,
|
||||||
|
pub show_hidden: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Config {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
// Sorting
|
||||||
|
sort_by: MANAGER.sort_by,
|
||||||
|
sort_sensitive: MANAGER.sort_sensitive,
|
||||||
|
sort_reverse: MANAGER.sort_reverse,
|
||||||
|
sort_dir_first: MANAGER.sort_dir_first,
|
||||||
|
|
||||||
|
// Display
|
||||||
|
linemode: MANAGER.linemode,
|
||||||
|
show_hidden: MANAGER.show_hidden,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
pub(super) fn patch<F: FnOnce(&mut Self)>(&mut self, f: F) -> bool {
|
||||||
|
let old = *self;
|
||||||
|
f(self);
|
||||||
|
*self != old
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(super) fn sorter(&self) -> FilesSorter {
|
||||||
|
FilesSorter {
|
||||||
|
by: self.sort_by,
|
||||||
|
sensitive: self.sort_sensitive,
|
||||||
|
reverse: self.sort_reverse,
|
||||||
|
dir_first: self.sort_dir_first,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
mod backstack;
|
mod backstack;
|
||||||
mod commands;
|
mod commands;
|
||||||
|
mod config;
|
||||||
mod finder;
|
mod finder;
|
||||||
mod folder;
|
mod folder;
|
||||||
mod mode;
|
mod mode;
|
||||||
mod tab;
|
mod tab;
|
||||||
|
|
||||||
pub use backstack::*;
|
pub use backstack::*;
|
||||||
|
pub use config::*;
|
||||||
pub use finder::*;
|
pub use finder::*;
|
||||||
pub use folder::*;
|
pub use folder::*;
|
||||||
pub use mode::*;
|
pub use mode::*;
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,24 @@
|
||||||
use std::{borrow::Cow, collections::BTreeMap};
|
use std::{borrow::Cow, collections::BTreeMap};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use config::MANAGER;
|
|
||||||
use shared::Url;
|
use shared::Url;
|
||||||
use tokio::task::JoinHandle;
|
use tokio::task::JoinHandle;
|
||||||
|
|
||||||
use super::{Backstack, Finder, Folder, Mode};
|
use super::{Backstack, Config, Finder, Folder, Mode};
|
||||||
use crate::{emit, files::{File, FilesSorter}, preview::{Preview, PreviewLock}};
|
use crate::{files::File, preview::{Preview, PreviewLock}};
|
||||||
|
|
||||||
pub struct Tab {
|
pub struct Tab {
|
||||||
pub mode: Mode,
|
pub mode: Mode,
|
||||||
|
pub conf: Config,
|
||||||
pub current: Folder,
|
pub current: Folder,
|
||||||
pub parent: Option<Folder>,
|
pub parent: Option<Folder>,
|
||||||
|
|
||||||
pub backstack: Backstack<Url>,
|
pub backstack: Backstack<Url>,
|
||||||
pub history: BTreeMap<Url, Folder>,
|
pub history: BTreeMap<Url, Folder>,
|
||||||
pub preview: Preview,
|
|
||||||
|
|
||||||
|
pub preview: Preview,
|
||||||
pub finder: Option<Finder>,
|
pub finder: Option<Finder>,
|
||||||
pub(super) search: Option<JoinHandle<Result<()>>>,
|
pub(super) search: Option<JoinHandle<Result<()>>>,
|
||||||
pub sorter: FilesSorter,
|
|
||||||
pub show_hidden: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Url> for Tab {
|
impl From<Url> for Tab {
|
||||||
|
|
@ -34,12 +32,12 @@ impl From<Url> for Tab {
|
||||||
|
|
||||||
backstack: Backstack::new(url),
|
backstack: Backstack::new(url),
|
||||||
history: Default::default(),
|
history: Default::default(),
|
||||||
preview: Default::default(),
|
|
||||||
|
|
||||||
|
preview: Default::default(),
|
||||||
finder: None,
|
finder: None,
|
||||||
search: None,
|
search: None,
|
||||||
sorter: Default::default(),
|
|
||||||
show_hidden: MANAGER.show_hidden,
|
conf: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -63,7 +61,7 @@ impl Tab {
|
||||||
|
|
||||||
pub fn update_preview(&mut self, lock: PreviewLock) -> bool {
|
pub fn update_preview(&mut self, lock: PreviewLock) -> bool {
|
||||||
let Some(hovered) = self.current.hovered().map(|h| &h.url) else {
|
let Some(hovered) = self.current.hovered().map(|h| &h.url) else {
|
||||||
return self.preview_reset();
|
return self.preview.reset(|_| true);
|
||||||
};
|
};
|
||||||
|
|
||||||
if lock.url != *hovered {
|
if lock.url != *hovered {
|
||||||
|
|
@ -101,45 +99,13 @@ impl Tab {
|
||||||
self.history.remove(url).unwrap_or_else(|| Folder::from(url))
|
self.history.remove(url).unwrap_or_else(|| Folder::from(url))
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Preview
|
|
||||||
#[inline]
|
|
||||||
pub fn preview_reset(&mut self) -> bool { self.preview.reset(|_| true) }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn preview_reset_image(&mut self) -> bool { self.preview.reset(|l| l.is_image()) }
|
|
||||||
|
|
||||||
// --- Sorter
|
|
||||||
pub fn set_sorter(&mut self, sorter: FilesSorter) -> bool {
|
|
||||||
if sorter == self.sorter {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.sorter = sorter;
|
|
||||||
self.apply_files_attrs(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Show hidden
|
|
||||||
pub fn set_show_hidden(&mut self, state: Option<bool>) -> bool {
|
|
||||||
let state = state.unwrap_or(!self.show_hidden);
|
|
||||||
if state == self.show_hidden {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.show_hidden = state;
|
|
||||||
if self.apply_files_attrs(false) {
|
|
||||||
emit!(Peek);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn apply_files_attrs(&mut self, just_preview: bool) -> bool {
|
pub fn apply_files_attrs(&mut self, just_preview: bool) -> bool {
|
||||||
let mut b = false;
|
let mut b = false;
|
||||||
if let Some(f) =
|
if let Some(f) =
|
||||||
self.current.hovered().filter(|h| h.is_dir()).and_then(|h| self.history.get_mut(&h.url))
|
self.current.hovered().filter(|h| h.is_dir()).and_then(|h| self.history.get_mut(&h.url))
|
||||||
{
|
{
|
||||||
b |= f.files.set_show_hidden(self.show_hidden);
|
b |= f.files.set_show_hidden(self.conf.show_hidden);
|
||||||
b |= f.files.set_sorter(self.sorter);
|
b |= f.files.set_sorter(self.conf.sorter());
|
||||||
}
|
}
|
||||||
|
|
||||||
if just_preview {
|
if just_preview {
|
||||||
|
|
@ -147,12 +113,12 @@ impl Tab {
|
||||||
}
|
}
|
||||||
|
|
||||||
let hovered = self.current.hovered().map(|h| h.url());
|
let hovered = self.current.hovered().map(|h| h.url());
|
||||||
b |= self.current.files.set_show_hidden(self.show_hidden);
|
b |= self.current.files.set_show_hidden(self.conf.show_hidden);
|
||||||
b |= self.current.files.set_sorter(self.sorter);
|
b |= self.current.files.set_sorter(self.conf.sorter());
|
||||||
|
|
||||||
if let Some(parent) = self.parent.as_mut() {
|
if let Some(parent) = self.parent.as_mut() {
|
||||||
b |= parent.files.set_show_hidden(self.show_hidden);
|
b |= parent.files.set_show_hidden(self.conf.show_hidden);
|
||||||
b |= parent.files.set_sorter(self.sorter);
|
b |= parent.files.set_sorter(self.conf.sorter());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current.repos(hovered);
|
self.current.repos(hovered);
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
{"version":"0.2","language":"en","flagWords":[],"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan"]}
|
{"language":"en","flagWords":[],"version":"0.2","words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","linemode"]}
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,8 @@ impl Base {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(self, cx: &core::Ctx, buf: &mut ratatui::buffer::Buffer) {
|
pub fn render(self, cx: &core::Ctx, buf: &mut ratatui::buffer::Buffer) {
|
||||||
match self.kind {
|
if self.kind == 0 {
|
||||||
0 => super::Preview::new(cx).render(self.area, buf),
|
super::Preview::new(cx).render(self.area, buf)
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue