This commit is contained in:
sxyazi 2023-09-05 18:30:37 +08:00
parent 7a3809db53
commit 4b39a966da
No known key found for this signature in database
12 changed files with 64 additions and 48 deletions

View file

@ -4,7 +4,7 @@ use std::ffi::OsString;
use anyhow::{Ok, Result};
use config::{keymap::{Control, Key, KeymapLayer}, BOOT};
use crossterm::event::KeyEvent;
use shared::{absolute_path, Term};
use shared::{absolute_url, Term};
use tokio::sync::oneshot;
use crate::{Ctx, Executor, Logs, Root, Signals};
@ -119,9 +119,9 @@ impl App {
let manager = &mut self.cx.manager;
let tasks = &mut self.cx.tasks;
match event {
Event::Cd(path) => {
Event::Cd(url) => {
futures::executor::block_on(async {
manager.active_mut().cd(absolute_path(path).into()).await;
manager.active_mut().cd(absolute_url(url)).await;
});
}
Event::Refresh => {

View file

@ -73,11 +73,11 @@ impl Executor {
"back" => cx.manager.active_mut().back(),
"forward" => cx.manager.active_mut().forward(),
"cd" => {
let path = exec.args.get(0).map(Into::into).unwrap_or_default();
let url = exec.args.get(0).map(Into::into).unwrap_or_default();
if exec.named.contains_key("interactive") {
cx.manager.active_mut().cd_interactive(path)
cx.manager.active_mut().cd_interactive(url)
} else {
emit!(Cd(path));
emit!(Cd(url));
false
}
}

View file

@ -1,4 +1,4 @@
use std::{collections::{BTreeMap, BTreeSet}, mem, ops::Deref, path::Path};
use std::{collections::{BTreeMap, BTreeSet}, mem, ops::Deref};
use anyhow::Result;
use config::manager::SortBy;
@ -40,22 +40,22 @@ impl Deref for Files {
}
impl Files {
pub async fn read(paths: Vec<Url>) -> Vec<File> {
let mut items = Vec::with_capacity(paths.len());
for path in paths {
if let Ok(file) = File::from(path).await {
pub async fn read(urls: Vec<Url>) -> Vec<File> {
let mut items = Vec::with_capacity(urls.len());
for url in urls {
if let Ok(file) = File::from(url).await {
items.push(file);
}
}
items
}
pub async fn read_dir(path: &Path) -> Result<Vec<File>> {
let mut it = fs::read_dir(path).await?;
pub async fn read_dir(url: &Url) -> Result<Vec<File>> {
let mut it = fs::read_dir(url).await?;
let mut items = Vec::new();
while let Ok(Some(item)) = it.next_entry().await {
if let Ok(meta) = item.metadata().await {
items.push(File::from_meta(item.path().into(), meta).await);
items.push(File::from_meta(Url::new(item.path(), url), meta).await);
}
}
Ok(items)

View file

@ -29,7 +29,7 @@ impl FilesSorter {
match self.by {
SortBy::Alphabetical => {
items.sort_unstable_by(|a, b| self.cmp(&a.url, &b.url, self.promote(a, b)))
items.sort_unstable_by(|a, b| self.cmp(&*a.url, &*b.url, self.promote(a, b)))
}
SortBy::Created => items.sort_unstable_by(|a, b| {
if let (Ok(aa), Ok(bb)) = (a.meta.created(), b.meta.created()) {

View file

@ -189,7 +189,7 @@ impl Manager {
fs::File::create(path).await?;
}
if let Ok(file) = File::from(hovered.into()).await {
if let Ok(file) = File::from(Url::new(hovered, &cwd)).await {
emit!(Hover(file));
emit!(Refresh);
}

View file

@ -23,15 +23,17 @@ pub struct Tab {
impl From<Url> for Tab {
fn from(url: Url) -> Self {
let parent = url.parent_url().map(Folder::from);
Self {
mode: Default::default(),
current: Folder::from(&url),
parent: url.parent_url().map(Folder::from),
mode: Default::default(),
current: Folder::from(url),
parent,
history: Default::default(),
preview: Default::default(),
search: None,
search: None,
show_hidden: true,
}
}
@ -88,7 +90,7 @@ impl Tab {
let mut hovered = None;
if !file.is_dir() {
hovered = Some(file);
target = target.parent().unwrap().into();
target = target.parent_url().unwrap();
}
if self.current.cwd == target {
@ -124,8 +126,8 @@ impl Tab {
let result =
emit!(Input(InputOpt::top("Change directory:").with_value(target.to_string_lossy())));
if let Ok(target) = result.await {
emit!(Cd(target.into()));
if let Ok(s) = result.await {
emit!(Cd(Url::new(s, &target)));
}
});
false

View file

@ -35,7 +35,7 @@ impl Watcher {
let parent = path.parent_url().unwrap_or_else(|| path.clone());
match event.kind {
EventKind::Create(_) => {
tx.send(parent.into()).ok();
tx.send(parent).ok();
}
EventKind::Modify(kind) => {
match kind {
@ -79,12 +79,12 @@ impl Watcher {
)
};
for p in to_unwatch {
self.watcher.unwatch(&p).ok();
for u in to_unwatch {
self.watcher.unwatch(&u).ok();
}
for p in to_watch {
if self.watcher.watch(&p, RecursiveMode::NonRecursive).is_err() {
watched.remove(&p);
for u in to_watch {
if self.watcher.watch(&u, RecursiveMode::NonRecursive).is_err() {
watched.remove(&u);
}
}
@ -109,7 +109,7 @@ impl Watcher {
for k in to_resolve {
match fs::canonicalize(&k).await {
Ok(v) if v != *k => {
ext.insert(k, Some(v.into()));
ext.insert(k, Some(Url::from(v)));
}
_ => {}
}
@ -123,7 +123,7 @@ impl Watcher {
pub(super) fn trigger_dirs(&self, dirs: &[&Url]) {
let watched = self.watched.clone();
let dirs = dirs.iter().map(|&u| u.clone()).collect::<Vec<_>>();
let dirs: Vec<_> = dirs.iter().map(|&u| u.clone()).collect();
tokio::spawn(async move {
for dir in dirs {
Self::dir_changed(&dir, watched.clone()).await;

View file

@ -235,11 +235,11 @@ impl Tasks {
}
pub fn precache_image(&self, mimetype: &BTreeMap<Url, String>) -> bool {
let targets = mimetype
let targets: Vec<_> = mimetype
.iter()
.filter(|(_, m)| MimeKind::new(m) == MimeKind::Image)
.map(|(p, _)| p.clone())
.collect::<Vec<_>>();
.map(|(u, _)| u.clone())
.collect();
if !targets.is_empty() {
self.scheduler.precache_image(targets);
@ -248,11 +248,11 @@ impl Tasks {
}
pub fn precache_video(&self, mimetype: &BTreeMap<Url, String>) -> bool {
let targets = mimetype
let targets: Vec<_> = mimetype
.iter()
.filter(|(_, m)| MimeKind::new(m) == MimeKind::Video)
.map(|(p, _)| p.clone())
.collect::<Vec<_>>();
.map(|(u, _)| u.clone())
.collect();
if !targets.is_empty() {
self.scheduler.precache_video(targets);
@ -261,11 +261,11 @@ impl Tasks {
}
pub fn precache_pdf(&self, mimetype: &BTreeMap<Url, String>) -> bool {
let targets = mimetype
let targets: Vec<_> = mimetype
.iter()
.filter(|(_, m)| MimeKind::new(m) == MimeKind::PDF)
.map(|(p, _)| p.clone())
.collect::<Vec<_>>();
.map(|(u, _)| u.clone())
.collect();
if !targets.is_empty() {
self.scheduler.precache_pdf(targets);

View file

@ -256,7 +256,7 @@ impl File {
let mut dirs = VecDeque::from([task.target]);
while let Some(target) = dirs.pop_front() {
let mut it = match fs::read_dir(target).await {
let mut it = match fs::read_dir(&target).await {
Ok(it) => it,
Err(_) => continue,
};
@ -268,11 +268,11 @@ impl File {
};
if meta.is_dir() {
dirs.push_front(entry.path().into());
dirs.push_front(Url::new(entry.path(), &target));
continue;
}
task.target = entry.path().into();
task.target = Url::new(entry.path(), &target);
task.length = meta.len();
self.sch.send(TaskOp::New(task.id, meta.len()))?;
self.tx.send(FileOp::Delete(task.clone())).await?;

View file

@ -128,7 +128,7 @@ impl Precache {
handing.remove(path);
}
let parent = buf[0].0.parent().unwrap().into();
let parent = buf[0].0.parent_url().unwrap();
emit!(Files(FilesOp::Size(parent, BTreeMap::from_iter(buf))));
});

View file

@ -14,6 +14,12 @@ pub fn absolute_path(p: impl AsRef<Path>) -> PathBuf {
std::fs::canonicalize(p).unwrap_or_else(|_| p.to_path_buf())
}
#[inline]
pub fn absolute_url(mut u: Url) -> Url {
u.set_path(absolute_path(&u));
u
}
pub fn readable_path(p: &Path, base: &Path) -> String {
if let Ok(p) = p.strip_prefix(base) {
return p.display().to_string();

View file

@ -61,9 +61,19 @@ impl AsRef<OsStr> for Url {
}
impl Url {
#[inline]
pub fn new(url: impl Into<Url>, ctx: &Url) -> Self {
let mut url: Self = url.into();
url.scheme = ctx.scheme;
url
}
#[inline]
pub fn is_search(&self) -> bool { self.scheme == UrlScheme::Search }
#[inline]
pub fn set_path(&mut self, path: PathBuf) { self.path = path; }
#[inline]
pub fn strip_prefix(&self, base: impl AsRef<Path>) -> Option<&Path> {
self.path.strip_prefix(base).ok()
@ -74,11 +84,9 @@ impl Url {
#[inline]
pub fn parent_url(&self) -> Option<Url> {
self.path.parent().map(|p| Self { path: p.to_path_buf(), ..*self })
self.path.parent().map(|p| Self::new(p.to_path_buf(), self))
}
#[inline]
pub fn __join(&self, path: impl AsRef<Path>) -> Url {
Url { path: self.path.join(path), ..*self }
}
pub fn __join(&self, path: impl AsRef<Path>) -> Self { Self::new(self.path.join(path), self) }
}