mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +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])
|
- 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])
|
- 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 `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])
|
- Implement `__pairs` metamethod instead of `__index` for the callback argument of the `@yank` DDS event ([#2997])
|
||||||
|
|
||||||
### Deprecated
|
### 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
|
[#3271]: https://github.com/sxyazi/yazi/pull/3271
|
||||||
[#3286]: https://github.com/sxyazi/yazi/pull/3286
|
[#3286]: https://github.com/sxyazi/yazi/pull/3286
|
||||||
[#3290]: https://github.com/sxyazi/yazi/pull/3290
|
[#3290]: https://github.com/sxyazi/yazi/pull/3290
|
||||||
|
[#3313]: https://github.com/sxyazi/yazi/pull/3313
|
||||||
|
|
|
||||||
|
|
@ -65,10 +65,10 @@ impl Image {
|
||||||
Ok(img)
|
Ok(img)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn max_pixel(rect: Rect) -> (u32, u32) {
|
pub(super) fn max_pixel(rect: Rect) -> (u16, u16) {
|
||||||
Dimension::cell_size()
|
Dimension::cell_size()
|
||||||
.map(|(cw, ch)| {
|
.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))
|
(w.min(YAZI.preview.max_width), h.min(YAZI.preview.max_height))
|
||||||
})
|
})
|
||||||
.unwrap_or((YAZI.preview.max_width, 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()))?
|
.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};
|
use image::metadata::Orientation::{Rotate90, Rotate90FlipH, Rotate270, Rotate270FlipH};
|
||||||
match orientation {
|
match orientation {
|
||||||
Rotate90 | Rotate270 | Rotate90FlipH | Rotate270FlipH => (h, w),
|
Rotate90 | Rotate270 | Rotate90FlipH | Rotate270FlipH => (h as u32, w as u32),
|
||||||
_ => (w, h),
|
_ => (w as u32, h as u32),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@ const TABS: &[&str] = &["", " ", " ", " ", " ", " ", " ", "
|
||||||
pub struct Preview {
|
pub struct Preview {
|
||||||
pub wrap: PreviewWrap,
|
pub wrap: PreviewWrap,
|
||||||
pub tab_size: u8,
|
pub tab_size: u8,
|
||||||
pub max_width: u32,
|
pub max_width: u16,
|
||||||
pub max_height: u32,
|
pub max_height: u16,
|
||||||
|
|
||||||
pub cache_dir: PathBuf,
|
pub cache_dir: PathBuf,
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{ffi::OsStr, hash::{Hash, Hasher}, ops::Deref, path::{Path, PathBuf}};
|
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};
|
use crate::cha::{Cha, ChaType};
|
||||||
|
|
||||||
|
|
@ -37,7 +37,7 @@ impl File {
|
||||||
pub fn url_owned(&self) -> UrlBuf { self.url.to_owned() }
|
pub fn url_owned(&self) -> UrlBuf { self.url.to_owned() }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn uri(&self) -> &Path { self.url.uri() }
|
pub fn uri(&self) -> PathDyn<'_> { self.url.uri() }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn urn(&self) -> &Path { self.url.urn() }
|
pub fn urn(&self) -> &Path { self.url.urn() }
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{borrow::Cow, ffi::{OsStr, OsString}, path::{Path, PathBuf}};
|
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};
|
use crate::{CWD, path::clean_url};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,7 @@ function M:preload(job)
|
||||||
"-l", job.skip + 1,
|
"-l", job.skip + 1,
|
||||||
"-singlefile",
|
"-singlefile",
|
||||||
"-jpeg", "-jpegopt", "quality=" .. rt.preview.image_quality,
|
"-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)
|
:stderr(Command.PIPED)
|
||||||
:output()
|
:output()
|
||||||
|
|
@ -54,12 +52,7 @@ function M:preload(job)
|
||||||
return true, Err("Failed to convert PDF to image, stderr: %s", output.stderr), pages
|
return true, Err("Failed to convert PDF to image, stderr: %s", output.stderr), pages
|
||||||
end
|
end
|
||||||
|
|
||||||
local ok, err = os.rename(string.format("%s.jpg", cache), tostring(cache))
|
return ya.image_precache(Url(cache .. ".jpg"), cache)
|
||||||
if ok then
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return false, Err("Failed to rename `%s.jpg` to `%s`, error: %s", cache, cache, err)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
|
||||||
|
|
@ -204,11 +204,8 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mutate<F: FnOnce(&mut P)>(&mut self, f: F)
|
fn mutate<F: FnOnce(&mut P)>(&mut self, f: F) {
|
||||||
where
|
let mut inner = self.inner.take();
|
||||||
P: Default,
|
|
||||||
{
|
|
||||||
let mut inner = std::mem::take(&mut self.inner);
|
|
||||||
f(&mut inner);
|
f(&mut inner);
|
||||||
self.inner = Self::from(inner).inner;
|
self.inner = Self::from(inner).inner;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use crate::path::{AsInnerView, AsPathView, PathInner, PathLike};
|
||||||
|
|
||||||
pub trait PathBufLike
|
pub trait PathBufLike
|
||||||
where
|
where
|
||||||
Self: Default + 'static,
|
Self: 'static,
|
||||||
{
|
{
|
||||||
type Inner: for<'a> AsInnerView<'a, Self::InnerRef<'a>>;
|
type Inner: for<'a> AsInnerView<'a, Self::InnerRef<'a>>;
|
||||||
type InnerRef<'a>: PathInner<'a>;
|
type InnerRef<'a>: PathInner<'a>;
|
||||||
|
|
@ -21,6 +21,8 @@ where
|
||||||
fn set_file_name<T>(&mut self, name: T)
|
fn set_file_name<T>(&mut self, name: T)
|
||||||
where
|
where
|
||||||
T: for<'a> AsInnerView<'a, Self::InnerRef<'a>>;
|
T: for<'a> AsInnerView<'a, Self::InnerRef<'a>>;
|
||||||
|
|
||||||
|
fn take(&mut self) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PathBufLike for std::path::PathBuf {
|
impl PathBufLike for std::path::PathBuf {
|
||||||
|
|
@ -42,4 +44,6 @@ impl PathBufLike for std::path::PathBuf {
|
||||||
{
|
{
|
||||||
self.set_file_name(name.as_inner_view());
|
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)]
|
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||||
pub enum PathDyn<'p> {
|
pub enum PathDyn<'p> {
|
||||||
Os(&'p std::path::Path),
|
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)]
|
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||||
pub enum PathBufDyn {
|
pub enum PathBufDyn {
|
||||||
Os(std::path::PathBuf),
|
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;
|
unsafe fn from_encoded_bytes(bytes: &'p [u8]) -> Self;
|
||||||
|
|
||||||
|
fn is_empty(self) -> bool { self.encoded_bytes().is_empty() }
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn is_hidden(self) -> bool {
|
fn is_hidden(self) -> bool {
|
||||||
self.file_name().map_or(false, |n| n.encoded_bytes().get(0) == Some(&b'.'))
|
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 }
|
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
|
impl<'a, T, U> AsInnerView<'a, U> for &T
|
||||||
where
|
where
|
||||||
T: ?Sized + AsInnerView<'a, U>,
|
T: ?Sized + AsInnerView<'a, U>,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{borrow::Cow, ffi::OsStr, path::{Path, PathBuf}};
|
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
|
// --- AsUrl
|
||||||
pub trait 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 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() }
|
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 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)]
|
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
|
||||||
pub struct Url<'a> {
|
pub struct Url<'a> {
|
||||||
|
|
@ -97,10 +97,10 @@ impl<'a> Url<'a> {
|
||||||
(S::Search(_), S::Regular) => Some(prefix),
|
(S::Search(_), S::Regular) => Some(prefix),
|
||||||
|
|
||||||
// Only the entry of archives is a local file
|
// Only the entry of archives is a local file
|
||||||
(S::Regular, S::Archive(_)) => Some(prefix).filter(|_| base.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().as_os_str().is_empty()),
|
(S::Search(_), S::Archive(_)) => Some(prefix).filter(|_| base.uri().is_empty()),
|
||||||
(S::Archive(_), S::Regular) => Some(prefix).filter(|_| self.uri().as_os_str().is_empty()),
|
(S::Archive(_), S::Regular) => Some(prefix).filter(|_| self.uri().is_empty()),
|
||||||
(S::Archive(_), S::Search(_)) => Some(prefix).filter(|_| self.uri().as_os_str().is_empty()),
|
(S::Archive(_), S::Search(_)) => Some(prefix).filter(|_| self.uri().is_empty()),
|
||||||
|
|
||||||
// Independent virtual file space
|
// Independent virtual file space
|
||||||
(S::Regular, S::Sftp(_)) => None,
|
(S::Regular, S::Sftp(_)) => None,
|
||||||
|
|
@ -113,7 +113,7 @@ impl<'a> Url<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn uri(self) -> &'a Path { self.loc.uri() }
|
pub fn uri(self) -> PathDyn<'a> { self.loc.uri().into() }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn urn(self) -> &'a Path { self.loc.urn() }
|
pub fn urn(self) -> &'a Path { self.loc.urn() }
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue