mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 14:51:03 +00:00
fix: u16 instead of u32 as the type of max_width and max_height options (#3313)
This commit is contained in:
parent
97c63e2708
commit
587950bb5b
13 changed files with 162 additions and 33 deletions
|
|
@ -45,6 +45,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/):
|
|||
- Rename `mime` fetcher to `mime.local`, and introduce `mime.dir` fetcher to support folder MIME types ([#3222])
|
||||
- Remove `$0` parameter in opener rules to make the `open` command work under empty directories ([#3226])
|
||||
- Use `body` instead of the term `content` in confirmations ([#2921])
|
||||
- Use `u16` instead of `u32` as the type of `max_width` and `max_height` options to avoid memory exhaustion ([#3313])
|
||||
- Implement `__pairs` metamethod instead of `__index` for the callback argument of the `@yank` DDS event ([#2997])
|
||||
|
||||
### Deprecated
|
||||
|
|
@ -1533,3 +1534,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/):
|
|||
[#3271]: https://github.com/sxyazi/yazi/pull/3271
|
||||
[#3286]: https://github.com/sxyazi/yazi/pull/3286
|
||||
[#3290]: https://github.com/sxyazi/yazi/pull/3290
|
||||
[#3313]: https://github.com/sxyazi/yazi/pull/3313
|
||||
|
|
|
|||
|
|
@ -65,10 +65,10 @@ impl Image {
|
|||
Ok(img)
|
||||
}
|
||||
|
||||
pub(super) fn max_pixel(rect: Rect) -> (u32, u32) {
|
||||
pub(super) fn max_pixel(rect: Rect) -> (u16, u16) {
|
||||
Dimension::cell_size()
|
||||
.map(|(cw, ch)| {
|
||||
let (w, h) = ((rect.width as f64 * cw) as u32, (rect.height as f64 * ch) as u32);
|
||||
let (w, h) = ((rect.width as f64 * cw) as u16, (rect.height as f64 * ch) as u16);
|
||||
(w.min(YAZI.preview.max_width), h.min(YAZI.preview.max_height))
|
||||
})
|
||||
.unwrap_or((YAZI.preview.max_width, YAZI.preview.max_height))
|
||||
|
|
@ -122,11 +122,11 @@ impl Image {
|
|||
.map_err(|e| ImageError::IoError(e.into()))?
|
||||
}
|
||||
|
||||
fn flip_size(orientation: Orientation, (w, h): (u32, u32)) -> (u32, u32) {
|
||||
fn flip_size(orientation: Orientation, (w, h): (u16, u16)) -> (u32, u32) {
|
||||
use image::metadata::Orientation::{Rotate90, Rotate90FlipH, Rotate270, Rotate270FlipH};
|
||||
match orientation {
|
||||
Rotate90 | Rotate270 | Rotate90FlipH | Rotate270FlipH => (h, w),
|
||||
_ => (w, h),
|
||||
Rotate90 | Rotate270 | Rotate90FlipH | Rotate270FlipH => (h as u32, w as u32),
|
||||
_ => (w as u32, h as u32),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ const TABS: &[&str] = &["", " ", " ", " ", " ", " ", " ", "
|
|||
pub struct Preview {
|
||||
pub wrap: PreviewWrap,
|
||||
pub tab_size: u8,
|
||||
pub max_width: u32,
|
||||
pub max_height: u32,
|
||||
pub max_width: u16,
|
||||
pub max_height: u16,
|
||||
|
||||
pub cache_dir: PathBuf,
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::{ffi::OsStr, hash::{Hash, Hasher}, ops::Deref, path::{Path, PathBuf}};
|
||||
|
||||
use yazi_shared::url::{UrlBuf, UrlLike};
|
||||
use yazi_shared::{path::PathDyn, url::{UrlBuf, UrlLike}};
|
||||
|
||||
use crate::cha::{Cha, ChaType};
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ impl File {
|
|||
pub fn url_owned(&self) -> UrlBuf { self.url.to_owned() }
|
||||
|
||||
#[inline]
|
||||
pub fn uri(&self) -> &Path { self.url.uri() }
|
||||
pub fn uri(&self) -> PathDyn<'_> { self.url.uri() }
|
||||
|
||||
#[inline]
|
||||
pub fn urn(&self) -> &Path { self.url.urn() }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::{borrow::Cow, ffi::{OsStr, OsString}, path::{Path, PathBuf}};
|
||||
|
||||
use yazi_shared::{loc::LocBuf, url::{AsUrl, Url, UrlBuf, UrlCow}};
|
||||
use yazi_shared::{loc::LocBuf, path::PathLike, url::{AsUrl, Url, UrlBuf, UrlCow}};
|
||||
|
||||
use crate::{CWD, path::clean_url};
|
||||
|
||||
|
|
|
|||
|
|
@ -40,9 +40,7 @@ function M:preload(job)
|
|||
"-l", job.skip + 1,
|
||||
"-singlefile",
|
||||
"-jpeg", "-jpegopt", "quality=" .. rt.preview.image_quality,
|
||||
"-scale-to-x", rt.preview.max_width, "-scale-to-y", "-1",
|
||||
tostring(job.file.url),
|
||||
tostring(cache),
|
||||
tostring(job.file.url), tostring(cache),
|
||||
})
|
||||
:stderr(Command.PIPED)
|
||||
:output()
|
||||
|
|
@ -54,12 +52,7 @@ function M:preload(job)
|
|||
return true, Err("Failed to convert PDF to image, stderr: %s", output.stderr), pages
|
||||
end
|
||||
|
||||
local ok, err = os.rename(string.format("%s.jpg", cache), tostring(cache))
|
||||
if ok then
|
||||
return true
|
||||
else
|
||||
return false, Err("Failed to rename `%s.jpg` to `%s`, error: %s", cache, cache, err)
|
||||
end
|
||||
return ya.image_precache(Url(cache .. ".jpg"), cache)
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
|||
|
|
@ -204,11 +204,8 @@ where
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn mutate<F: FnOnce(&mut P)>(&mut self, f: F)
|
||||
where
|
||||
P: Default,
|
||||
{
|
||||
let mut inner = std::mem::take(&mut self.inner);
|
||||
fn mutate<F: FnOnce(&mut P)>(&mut self, f: F) {
|
||||
let mut inner = self.inner.take();
|
||||
f(&mut inner);
|
||||
self.inner = Self::from(inner).inner;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use crate::path::{AsInnerView, AsPathView, PathInner, PathLike};
|
|||
|
||||
pub trait PathBufLike
|
||||
where
|
||||
Self: Default + 'static,
|
||||
Self: 'static,
|
||||
{
|
||||
type Inner: for<'a> AsInnerView<'a, Self::InnerRef<'a>>;
|
||||
type InnerRef<'a>: PathInner<'a>;
|
||||
|
|
@ -21,6 +21,8 @@ where
|
|||
fn set_file_name<T>(&mut self, name: T)
|
||||
where
|
||||
T: for<'a> AsInnerView<'a, Self::InnerRef<'a>>;
|
||||
|
||||
fn take(&mut self) -> Self;
|
||||
}
|
||||
|
||||
impl PathBufLike for std::path::PathBuf {
|
||||
|
|
@ -42,4 +44,6 @@ impl PathBufLike for std::path::PathBuf {
|
|||
{
|
||||
self.set_file_name(name.as_inner_view());
|
||||
}
|
||||
|
||||
fn take(&mut self) -> Self { std::mem::take(self) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,132 @@
|
|||
use super::{AsInnerView, AsPathView};
|
||||
use crate::path::{PathBufLike, PathLike};
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
pub enum PathDyn<'p> {
|
||||
Os(&'p std::path::Path),
|
||||
}
|
||||
|
||||
impl<'a> AsPathView<'a, PathDyn<'a>> for PathDyn<'a> {
|
||||
fn as_path_view(self) -> PathDyn<'a> { self }
|
||||
}
|
||||
|
||||
impl<'a> AsPathView<'a, PathDyn<'a>> for std::path::Components<'a> {
|
||||
fn as_path_view(self) -> PathDyn<'a> { PathDyn::Os(self.as_path()) }
|
||||
}
|
||||
|
||||
impl<'a> From<&'a std::path::Path> for PathDyn<'a> {
|
||||
fn from(value: &'a std::path::Path) -> Self { PathDyn::Os(value) }
|
||||
}
|
||||
|
||||
impl<'p> PathLike<'p> for PathDyn<'p> {
|
||||
type Components<'a> = std::path::Components<'a>;
|
||||
type Inner = &'p [u8];
|
||||
type Owned = PathBufDyn;
|
||||
type View<'a> = PathDyn<'a>;
|
||||
|
||||
fn components(self) -> Self::Components<'p> {
|
||||
match self {
|
||||
Self::Os(p) => p.components(),
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: remove
|
||||
fn default() -> Self { Self::Os(std::path::Path::new("")) }
|
||||
|
||||
fn encoded_bytes(self) -> &'p [u8] {
|
||||
match self {
|
||||
Self::Os(p) => p.as_os_str().as_encoded_bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
fn extension(self) -> Option<Self::Inner> {
|
||||
Some(match self {
|
||||
Self::Os(p) => p.extension()?.as_encoded_bytes(),
|
||||
})
|
||||
}
|
||||
|
||||
fn file_name(self) -> Option<Self::Inner> {
|
||||
Some(match self {
|
||||
Self::Os(p) => p.file_name()?.as_encoded_bytes(),
|
||||
})
|
||||
}
|
||||
|
||||
fn file_stem(self) -> Option<Self::Inner> {
|
||||
Some(match self {
|
||||
Self::Os(p) => p.file_stem()?.as_encoded_bytes(),
|
||||
})
|
||||
}
|
||||
|
||||
// FIXME: remove
|
||||
unsafe fn from_encoded_bytes(bytes: &'p [u8]) -> Self {
|
||||
Self::Os(std::path::Path::new(unsafe { std::ffi::OsStr::from_encoded_bytes_unchecked(bytes) }))
|
||||
}
|
||||
|
||||
fn join<'a, T>(self, base: T) -> Self::Owned
|
||||
where
|
||||
T: AsPathView<'a, Self::View<'a>>,
|
||||
{
|
||||
match (self, base.as_path_view()) {
|
||||
(Self::Os(p), PathDyn::Os(q)) => Self::Owned::Os(p.join(q)),
|
||||
}
|
||||
}
|
||||
|
||||
fn parent(self) -> Option<Self> {
|
||||
Some(match self {
|
||||
Self::Os(p) => Self::Os(p.parent()?),
|
||||
})
|
||||
}
|
||||
|
||||
fn strip_prefix<'a, T>(self, base: T) -> Option<Self>
|
||||
where
|
||||
T: AsPathView<'a, Self::View<'a>>,
|
||||
{
|
||||
Some(match (self, base.as_path_view()) {
|
||||
(Self::Os(p), PathDyn::Os(q)) => Self::Os(p.strip_prefix(q).ok()?),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
pub enum PathBufDyn {
|
||||
Os(std::path::PathBuf),
|
||||
}
|
||||
|
||||
impl PathBufLike for PathBufDyn {
|
||||
type Borrowed<'a> = PathDyn<'a>;
|
||||
type Inner = Vec<u8>;
|
||||
type InnerRef<'a> = &'a [u8];
|
||||
|
||||
fn encoded_bytes(&self) -> &[u8] {
|
||||
match self {
|
||||
Self::Os(p) => p.as_os_str().as_encoded_bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: remove
|
||||
unsafe fn from_encoded_bytes(bytes: Vec<u8>) -> Self {
|
||||
Self::Os(std::path::PathBuf::from(unsafe {
|
||||
std::ffi::OsString::from_encoded_bytes_unchecked(bytes)
|
||||
}))
|
||||
}
|
||||
|
||||
fn into_encoded_bytes(self) -> Vec<u8> {
|
||||
match self {
|
||||
Self::Os(p) => p.into_os_string().into_encoded_bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_file_name<T>(&mut self, name: T)
|
||||
where
|
||||
T: for<'a> AsInnerView<'a, Self::InnerRef<'a>>,
|
||||
{
|
||||
// TODO: introduce a new `PathInnerDyn`
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn take(&mut self) -> Self {
|
||||
match self {
|
||||
Self::Os(p) => Self::Os(std::mem::take(p)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ where
|
|||
|
||||
unsafe fn from_encoded_bytes(bytes: &'p [u8]) -> Self;
|
||||
|
||||
fn is_empty(self) -> bool { self.encoded_bytes().is_empty() }
|
||||
|
||||
#[cfg(unix)]
|
||||
fn is_hidden(self) -> bool {
|
||||
self.file_name().map_or(false, |n| n.encoded_bytes().get(0) == Some(&b'.'))
|
||||
|
|
|
|||
|
|
@ -82,6 +82,14 @@ impl<'a> AsInnerView<'a, &'a std::ffi::OsStr> for std::ffi::OsString {
|
|||
fn as_inner_view(&'a self) -> &'a std::ffi::OsStr { self }
|
||||
}
|
||||
|
||||
impl<'a> AsInnerView<'a, &'a [u8]> for [u8] {
|
||||
fn as_inner_view(&'a self) -> &'a [u8] { self }
|
||||
}
|
||||
|
||||
impl<'a> AsInnerView<'a, &'a [u8]> for Vec<u8> {
|
||||
fn as_inner_view(&'a self) -> &'a [u8] { self }
|
||||
}
|
||||
|
||||
impl<'a, T, U> AsInnerView<'a, U> for &T
|
||||
where
|
||||
T: ?Sized + AsInnerView<'a, U>,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::{borrow::Cow, ffi::OsStr, path::{Path, PathBuf}};
|
||||
|
||||
use crate::{loc::Loc, scheme::{AsScheme, SchemeRef}, url::{Components, Display, Url, UrlBuf, UrlCow}};
|
||||
use crate::{loc::Loc, path::PathDyn, scheme::{AsScheme, SchemeRef}, url::{Components, Display, Url, UrlBuf, UrlCow}};
|
||||
|
||||
// --- AsUrl
|
||||
pub trait AsUrl {
|
||||
|
|
@ -117,7 +117,7 @@ where
|
|||
|
||||
fn strip_prefix(&self, base: impl AsUrl) -> Option<&Path> { self.as_url().strip_prefix(base) }
|
||||
|
||||
fn uri(&self) -> &Path { self.as_url().uri() }
|
||||
fn uri(&self) -> PathDyn<'_> { self.as_url().uri() }
|
||||
|
||||
fn urn(&self) -> &Path { self.as_url().urn() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::{borrow::Cow, ffi::OsStr, fmt::{Debug, Formatter}, path::{Path, PathBuf
|
|||
|
||||
use hashbrown::Equivalent;
|
||||
|
||||
use crate::{loc::{Loc, LocBuf}, scheme::SchemeRef, url::{AsUrl, Components, Encode, UrlBuf}};
|
||||
use crate::{loc::{Loc, LocBuf}, path::{PathDyn, PathLike}, scheme::SchemeRef, url::{AsUrl, Components, Encode, UrlBuf}};
|
||||
|
||||
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
|
||||
pub struct Url<'a> {
|
||||
|
|
@ -97,10 +97,10 @@ impl<'a> Url<'a> {
|
|||
(S::Search(_), S::Regular) => Some(prefix),
|
||||
|
||||
// Only the entry of archives is a local file
|
||||
(S::Regular, S::Archive(_)) => Some(prefix).filter(|_| base.uri().as_os_str().is_empty()),
|
||||
(S::Search(_), S::Archive(_)) => Some(prefix).filter(|_| base.uri().as_os_str().is_empty()),
|
||||
(S::Archive(_), S::Regular) => Some(prefix).filter(|_| self.uri().as_os_str().is_empty()),
|
||||
(S::Archive(_), S::Search(_)) => Some(prefix).filter(|_| self.uri().as_os_str().is_empty()),
|
||||
(S::Regular, S::Archive(_)) => Some(prefix).filter(|_| base.uri().is_empty()),
|
||||
(S::Search(_), S::Archive(_)) => Some(prefix).filter(|_| base.uri().is_empty()),
|
||||
(S::Archive(_), S::Regular) => Some(prefix).filter(|_| self.uri().is_empty()),
|
||||
(S::Archive(_), S::Search(_)) => Some(prefix).filter(|_| self.uri().is_empty()),
|
||||
|
||||
// Independent virtual file space
|
||||
(S::Regular, S::Sftp(_)) => None,
|
||||
|
|
@ -113,7 +113,7 @@ impl<'a> Url<'a> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn uri(self) -> &'a Path { self.loc.uri() }
|
||||
pub fn uri(self) -> PathDyn<'a> { self.loc.uri().into() }
|
||||
|
||||
#[inline]
|
||||
pub fn urn(self) -> &'a Path { self.loc.urn() }
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue