mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
parent
d6081fbe6f
commit
4d858ae1c2
7 changed files with 49 additions and 17 deletions
|
|
@ -46,7 +46,11 @@ impl Deref for Files {
|
||||||
|
|
||||||
impl Files {
|
impl Files {
|
||||||
pub async fn from_dir(url: &Url) -> std::io::Result<UnboundedReceiver<File>> {
|
pub async fn from_dir(url: &Url) -> std::io::Result<UnboundedReceiver<File>> {
|
||||||
let mut it = fs::read_dir(url).await?;
|
let mut it = fs::read_dir(url).await.map_err(|e| {
|
||||||
|
FilesOp::IOErr(url.clone(), e.kind(), e.to_string()).emit();
|
||||||
|
e
|
||||||
|
})?;
|
||||||
|
|
||||||
let (tx, rx) = mpsc::unbounded_channel();
|
let (tx, rx) = mpsc::unbounded_channel();
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
|
|
@ -100,13 +104,18 @@ impl Files {
|
||||||
match fs::metadata(url).await {
|
match fs::metadata(url).await {
|
||||||
Ok(m) if !m.is_dir() => {
|
Ok(m) if !m.is_dir() => {
|
||||||
// FIXME: use `ErrorKind::NotADirectory` instead once it gets stabilized
|
// FIXME: use `ErrorKind::NotADirectory` instead once it gets stabilized
|
||||||
FilesOp::IOErr(url.clone(), std::io::ErrorKind::AlreadyExists).emit();
|
FilesOp::IOErr(
|
||||||
|
url.clone(),
|
||||||
|
std::io::ErrorKind::AlreadyExists,
|
||||||
|
"Not a directory".to_string(),
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
}
|
}
|
||||||
Ok(m) if mtime == m.modified().ok() => {}
|
Ok(m) if mtime == m.modified().ok() => {}
|
||||||
Ok(m) => return Some(m),
|
Ok(m) => return Some(m),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
if maybe_exists(url).await {
|
if maybe_exists(url).await {
|
||||||
FilesOp::IOErr(url.clone(), e.kind()).emit();
|
FilesOp::IOErr(url.clone(), e.kind(), e.to_string()).emit();
|
||||||
} else if let Some(p) = url.parent_url() {
|
} else if let Some(p) = url.parent_url() {
|
||||||
FilesOp::Deleting(p, vec![url.clone()]).emit();
|
FilesOp::Deleting(p, vec![url.clone()]).emit();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ impl From<&Url> for Folder {
|
||||||
|
|
||||||
impl Folder {
|
impl Folder {
|
||||||
pub fn update(&mut self, op: FilesOp) -> bool {
|
pub fn update(&mut self, op: FilesOp) -> bool {
|
||||||
let (stage, revision) = (self.stage, self.files.revision);
|
let (stage, revision) = (self.stage.clone(), self.files.revision);
|
||||||
match op {
|
match op {
|
||||||
FilesOp::Full(_, _, mtime) => {
|
FilesOp::Full(_, _, mtime) => {
|
||||||
(self.mtime, self.stage) = (mtime, FolderStage::Loaded);
|
(self.mtime, self.stage) = (mtime, FolderStage::Loaded);
|
||||||
|
|
@ -39,8 +39,8 @@ impl Folder {
|
||||||
FilesOp::Done(_, mtime, ticket) if ticket == self.files.ticket() => {
|
FilesOp::Done(_, mtime, ticket) if ticket == self.files.ticket() => {
|
||||||
(self.mtime, self.stage) = (mtime, FolderStage::Loaded);
|
(self.mtime, self.stage) = (mtime, FolderStage::Loaded);
|
||||||
}
|
}
|
||||||
FilesOp::IOErr(_, kind) => {
|
FilesOp::IOErr(_, kind, ref msg) => {
|
||||||
(self.mtime, self.stage) = (None, FolderStage::Failed(kind));
|
(self.mtime, self.stage) = (None, FolderStage::Failed(kind, msg.clone()));
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
@ -59,7 +59,7 @@ impl Folder {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.arrow(0);
|
self.arrow(0);
|
||||||
(stage, revision) != (self.stage, self.files.revision)
|
(stage, revision) != (self.stage.clone(), self.files.revision)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn arrow(&mut self, step: impl Into<Step>) -> bool {
|
pub fn arrow(&mut self, step: impl Into<Step>) -> bool {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||||
pub enum FolderStage {
|
pub enum FolderStage {
|
||||||
#[default]
|
#[default]
|
||||||
Loading,
|
Loading,
|
||||||
Loaded,
|
Loaded,
|
||||||
Failed(std::io::ErrorKind),
|
Failed(std::io::ErrorKind, String),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ impl Folder {
|
||||||
lua.register_userdata_type::<Self>(|reg| {
|
lua.register_userdata_type::<Self>(|reg| {
|
||||||
reg.add_field_method_get("cwd", |lua, me| Url::cast(lua, me.cwd.clone()));
|
reg.add_field_method_get("cwd", |lua, me| Url::cast(lua, me.cwd.clone()));
|
||||||
reg.add_field_method_get("files", |_, me| Files::make(0..me.files.len(), me, me.tab()));
|
reg.add_field_method_get("files", |_, me| Files::make(0..me.files.len(), me, me.tab()));
|
||||||
reg.add_field_method_get("stage", |lua, me| lua.create_any_userdata(me.stage));
|
reg.add_field_method_get("stage", |lua, me| lua.create_any_userdata(me.stage.clone()));
|
||||||
reg.add_field_method_get("window", |_, me| Files::make(me.window.clone(), me, me.tab()));
|
reg.add_field_method_get("window", |_, me| Files::make(me.window.clone(), me, me.tab()));
|
||||||
|
|
||||||
reg.add_field_method_get("offset", |_, me| Ok(me.offset));
|
reg.add_field_method_get("offset", |_, me| Ok(me.offset));
|
||||||
|
|
@ -53,12 +53,23 @@ impl Folder {
|
||||||
lua.register_userdata_type::<yazi_core::folder::FolderStage>(|reg| {
|
lua.register_userdata_type::<yazi_core::folder::FolderStage>(|reg| {
|
||||||
reg.add_meta_method(MetaMethod::ToString, |lua, me, ()| {
|
reg.add_meta_method(MetaMethod::ToString, |lua, me, ()| {
|
||||||
use yazi_core::folder::FolderStage::{Failed, Loaded, Loading};
|
use yazi_core::folder::FolderStage::{Failed, Loaded, Loading};
|
||||||
|
|
||||||
lua.create_string(match me {
|
lua.create_string(match me {
|
||||||
Loading => "loading",
|
Loading => "loading",
|
||||||
Loaded => "loaded",
|
Loaded => "loaded",
|
||||||
Failed(_) => "failed",
|
Failed(..) => "failed",
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
reg.add_field_method_get("error", |lua, me| {
|
||||||
|
use yazi_core::folder::FolderStage::{Failed, Loaded, Loading};
|
||||||
|
|
||||||
|
match me {
|
||||||
|
Loading => Ok(None),
|
||||||
|
Loaded => Ok(None),
|
||||||
|
Failed(_, msg) => Some(lua.create_string(msg)).transpose(),
|
||||||
|
}
|
||||||
|
});
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,12 @@ function Current:empty()
|
||||||
local line
|
local line
|
||||||
if self._folder.files.filter then
|
if self._folder.files.filter then
|
||||||
line = ui.Line("No filter results")
|
line = ui.Line("No filter results")
|
||||||
|
elseif tostring(self._folder.stage) == "loading" then
|
||||||
|
line = ui.Line("Loading...")
|
||||||
|
elseif tostring(self._folder.stage) == "failed" then
|
||||||
|
line = ui.Line(self._folder.stage.error)
|
||||||
else
|
else
|
||||||
line = ui.Line(self._folder.stage == "loading" and "Loading..." or "No items")
|
line = ui.Line("No items")
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,17 @@ function M:peek()
|
||||||
end
|
end
|
||||||
|
|
||||||
if #folder.files == 0 then
|
if #folder.files == 0 then
|
||||||
|
local line
|
||||||
|
if tostring(folder.stage) == "loading" then
|
||||||
|
line = ui.Line("Loading...")
|
||||||
|
elseif tostring(folder.stage) == "failed" then
|
||||||
|
line = ui.Line(folder.stage.error)
|
||||||
|
else
|
||||||
|
line = ui.Line("No items")
|
||||||
|
end
|
||||||
|
|
||||||
return ya.preview_widgets(self, {
|
return ya.preview_widgets(self, {
|
||||||
ui.Paragraph(self.area, { ui.Line(folder.stage == "loading" and "Loading..." or "No items") })
|
ui.Paragraph(self.area, { line }):align(ui.Paragraph.CENTER),
|
||||||
:align(ui.Paragraph.CENTER),
|
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ pub enum FilesOp {
|
||||||
Part(Url, Vec<File>, u64),
|
Part(Url, Vec<File>, u64),
|
||||||
Done(Url, Option<SystemTime>, u64),
|
Done(Url, Option<SystemTime>, u64),
|
||||||
Size(Url, HashMap<Url, u64>),
|
Size(Url, HashMap<Url, u64>),
|
||||||
IOErr(Url, std::io::ErrorKind),
|
IOErr(Url, std::io::ErrorKind, String),
|
||||||
|
|
||||||
Creating(Url, Vec<File>),
|
Creating(Url, Vec<File>),
|
||||||
Deleting(Url, Vec<Url>),
|
Deleting(Url, Vec<Url>),
|
||||||
|
|
@ -27,7 +27,7 @@ impl FilesOp {
|
||||||
Self::Part(url, ..) => url,
|
Self::Part(url, ..) => url,
|
||||||
Self::Done(url, ..) => url,
|
Self::Done(url, ..) => url,
|
||||||
Self::Size(url, _) => url,
|
Self::Size(url, _) => url,
|
||||||
Self::IOErr(url, _) => url,
|
Self::IOErr(url, ..) => url,
|
||||||
|
|
||||||
Self::Creating(url, _) => url,
|
Self::Creating(url, _) => url,
|
||||||
Self::Deleting(url, _) => url,
|
Self::Deleting(url, _) => url,
|
||||||
|
|
@ -83,7 +83,7 @@ impl FilesOp {
|
||||||
Self::Part(_, files, ticket) => Self::Part(u, files!(files), *ticket),
|
Self::Part(_, files, ticket) => Self::Part(u, files!(files), *ticket),
|
||||||
Self::Done(_, mtime, ticket) => Self::Done(u, *mtime, *ticket),
|
Self::Done(_, mtime, ticket) => Self::Done(u, *mtime, *ticket),
|
||||||
Self::Size(_, map) => Self::Size(u, map.iter().map(|(k, v)| (new!(k), *v)).collect()),
|
Self::Size(_, map) => Self::Size(u, map.iter().map(|(k, v)| (new!(k), *v)).collect()),
|
||||||
Self::IOErr(_, err) => Self::IOErr(u, *err),
|
Self::IOErr(_, err, msg) => Self::IOErr(u, *err, msg.clone()),
|
||||||
|
|
||||||
Self::Creating(_, files) => Self::Creating(u, files!(files)),
|
Self::Creating(_, files) => Self::Creating(u, files!(files)),
|
||||||
Self::Deleting(_, urls) => Self::Deleting(u, urls.iter().map(|u| new!(u)).collect()),
|
Self::Deleting(_, urls) => Self::Deleting(u, urls.iter().map(|u| new!(u)).collect()),
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue