refactor: introduce Clippy (#38)

This commit is contained in:
三咲雅 · Misaki Masa 2023-08-09 14:36:19 +08:00 committed by GitHub
parent 7000e764e6
commit d198f142e2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
49 changed files with 140 additions and 153 deletions

20
Cargo.lock generated
View file

@ -193,9 +193,9 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.81" version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c6b2562119bf28c3439f7f02db99faf0aa1a8cdfe5772a2ee155d32227239f0" checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@ -705,9 +705,9 @@ dependencies = [
[[package]] [[package]]
name = "image" name = "image"
version = "0.24.6" version = "0.24.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "527909aa81e20ac3a44803521443a765550f09b5130c2c2fa1ea59c2f8f50a3a" checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
"byteorder", "byteorder",
@ -1283,18 +1283,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.182" version = "1.0.183"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdb30a74471f5b7a1fa299f40b4bf1be93af61116df95465b2b5fc419331e430" checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.182" version = "1.0.183"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f4c2c6ea4bc09b5c419012eafcdb0fcef1d9119d626c8f3a0708a5b92d38a70" checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1488,9 +1488,9 @@ dependencies = [
[[package]] [[package]]
name = "tiff" name = "tiff"
version = "0.8.1" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7449334f9ff2baf290d55d73983a7d6fa15e01198faef72af07e2a8db851e471" checksum = "6d172b0f4d3fba17ba89811858b9d3d97f928aece846475bbda076ca46736211"
dependencies = [ dependencies = [
"flate2", "flate2",
"jpeg-decoder", "jpeg-decoder",

View file

@ -11,6 +11,7 @@ use crate::{Image, Sixel};
static IMAGE_SHOWN: AtomicBool = AtomicBool::new(false); static IMAGE_SHOWN: AtomicBool = AtomicBool::new(false);
#[allow(clippy::type_complexity)]
static UEBERZUG: Lazy<Option<UnboundedSender<Option<(PathBuf, Rect)>>>> = static UEBERZUG: Lazy<Option<UnboundedSender<Option<(PathBuf, Rect)>>>> =
Lazy::new(|| if PREVIEW.adaptor.needs_ueberzug() { Ueberzug::start().ok() } else { None }); Lazy::new(|| if PREVIEW.adaptor.needs_ueberzug() { Ueberzug::start().ok() } else { None });

View file

@ -1,3 +1,5 @@
#![allow(clippy::unit_arg)]
mod adaptor; mod adaptor;
mod image; mod image;
mod iterm2; mod iterm2;
@ -5,9 +7,9 @@ mod kitty;
mod sixel; mod sixel;
mod ueberzug; mod ueberzug;
pub use crate::adaptor::*; use iterm2::*;
pub use crate::image::*; use kitty::*;
pub(self) use iterm2::*; use sixel::*;
pub(self) use kitty::*; use ueberzug::*;
pub(self) use sixel::*;
pub(self) use ueberzug::*; pub use crate::{adaptor::*, image::*};

View file

@ -55,7 +55,7 @@ impl Sixel {
} }
for y in 0..img.height() { for y in 0..img.height() {
let c = (b'?' + (1 << (y % 6))) as u8 as char; let c = (b'?' + (1 << (y % 6))) as char;
let mut last = 0; let mut last = 0;
let mut repeat = 0usize; let mut repeat = 0usize;

View file

@ -56,7 +56,7 @@ impl App {
fn dispatch_render(&mut self) { fn dispatch_render(&mut self) {
if let Some(term) = &mut self.term { if let Some(term) = &mut self.term {
let _ = term.draw(|f| { let _ = term.draw(|f| {
f.render_widget(Root::new(&mut self.cx), f.size()); f.render_widget(Root::new(&self.cx), f.size());
if let Some((x, y)) = self.cx.cursor() { if let Some((x, y)) = self.cx.cursor() {
f.set_cursor(x, y); f.set_cursor(x, y);

View file

@ -14,7 +14,7 @@ pub struct Ctx {
impl Ctx { impl Ctx {
pub(super) fn new() -> Self { pub(super) fn new() -> Self {
Self { Self {
manager: Manager::new(), manager: Manager::make(),
which: Default::default(), which: Default::default(),
select: Default::default(), select: Default::default(),
input: Default::default(), input: Default::default(),
@ -47,11 +47,7 @@ impl Ctx {
#[inline] #[inline]
pub(super) fn image_layer(&self) -> bool { pub(super) fn image_layer(&self) -> bool {
match self.layer() { !matches!(self.layer(), KeymapLayer::Which | KeymapLayer::Tasks)
KeymapLayer::Which => false,
KeymapLayer::Tasks => false,
_ => true,
}
} }
pub(super) fn position(&self, pos: Position) -> Position { pub(super) fn position(&self, pos: Position) -> Position {

View file

@ -66,7 +66,7 @@ impl Executor {
"back" => cx.manager.active_mut().back(), "back" => cx.manager.active_mut().back(),
"forward" => cx.manager.active_mut().forward(), "forward" => cx.manager.active_mut().forward(),
"cd" => { "cd" => {
let path = exec.args.get(0).map(|s| PathBuf::from(s)).unwrap_or_default(); let path = exec.args.get(0).map(PathBuf::from).unwrap_or_default();
emit!(Cd(path)); emit!(Cd(path));
false false
} }
@ -182,7 +182,7 @@ impl Executor {
"arrow" => { "arrow" => {
let step: isize = exec.args.get(0).and_then(|s| s.parse().ok()).unwrap_or(0); let step: isize = exec.args.get(0).and_then(|s| s.parse().ok()).unwrap_or(0);
if step > 0 { cx.select.next(step as usize) } else { cx.select.prev(step.abs() as usize) } if step > 0 { cx.select.next(step as usize) } else { cx.select.prev(step.unsigned_abs()) }
} }
_ => false, _ => false,

View file

@ -23,7 +23,7 @@ impl<'a> Widget for Layout<'a> {
let location = if current.in_search { let location = if current.in_search {
format!("{} (search)", readable_home(&current.cwd)) format!("{} (search)", readable_home(&current.cwd))
} else { } else {
format!("{}", readable_home(&current.cwd)) readable_home(&current.cwd)
}; };
Paragraph::new(location).style(Style::new().fg(Color::Cyan)).render(chunks[0], buf); Paragraph::new(location).style(Style::new().fg(Color::Cyan)).render(chunks[0], buf);

View file

@ -2,4 +2,4 @@ mod layout;
mod tabs; mod tabs;
pub(super) use layout::*; pub(super) use layout::*;
pub(self) use tabs::*; use tabs::*;

View file

@ -1,3 +1,5 @@
#![allow(clippy::module_inception)]
mod app; mod app;
mod context; mod context;
mod executor; mod executor;
@ -12,12 +14,12 @@ mod status;
mod tasks; mod tasks;
mod which; mod which;
pub(self) use app::*; use app::*;
pub(self) use context::*; use context::*;
pub(self) use executor::*; use executor::*;
pub(self) use logs::*; use logs::*;
pub(self) use root::*; use root::*;
pub(self) use signals::*; use signals::*;
#[tokio::main] #[tokio::main]
async fn main() -> anyhow::Result<()> { async fn main() -> anyhow::Result<()> {

View file

@ -38,7 +38,7 @@ impl<'a> Folder<'a> {
.iter() .iter()
.find(|x| x.matches(&file.path, mimetype.get(&file.path).cloned(), file.meta.is_dir())) .find(|x| x.matches(&file.path, mimetype.get(&file.path).cloned(), file.meta.is_dir()))
.map(|x| x.style.get()) .map(|x| x.style.get())
.unwrap_or_else(|| Style::new()) .unwrap_or_else(Style::new)
} }
} }

View file

@ -31,7 +31,7 @@ impl<'a> Widget for Layout<'a> {
// Parent // Parent
let block = Block::new().borders(Borders::RIGHT).padding(Padding::new(1, 0, 0, 0)); let block = Block::new().borders(Borders::RIGHT).padding(Padding::new(1, 0, 0, 0));
if let Some(ref parent) = manager.parent() { if let Some(parent) = manager.parent() {
Folder::new(self.cx, parent).render(block.inner(chunks[0]), buf); Folder::new(self.cx, parent).render(block.inner(chunks[0]), buf);
} }
block.render(chunks[0], buf); block.render(chunks[0], buf);

View file

@ -2,6 +2,6 @@ mod folder;
mod layout; mod layout;
mod preview; mod preview;
pub(self) use folder::*; use folder::*;
pub(super) use layout::*; pub(super) use layout::*;
pub(self) use preview::*; use preview::*;

View file

@ -4,6 +4,6 @@ mod progress;
mod right; mod right;
pub(super) use layout::*; pub(super) use layout::*;
pub(self) use left::*; use left::*;
pub(self) use progress::*; use progress::*;
pub(self) use right::*; use right::*;

View file

@ -34,7 +34,7 @@ impl<'a> Right<'a> {
.collect() .collect()
} }
fn position<'b>(&self) -> Vec<Span> { fn position(&self) -> Vec<Span> {
// Colors // Colors
let mode = self.cx.manager.active().mode(); let mode = self.cx.manager.active().mode();
let primary = mode.color(&THEME.status.primary); let primary = mode.color(&THEME.status.primary);

View file

@ -1,5 +1,5 @@
mod clear; mod clear;
mod layout; mod layout;
pub(self) use clear::*; use clear::*;
pub(super) use layout::*; pub(super) use layout::*;

View file

@ -2,4 +2,4 @@ mod layout;
mod side; mod side;
pub(super) use layout::*; pub(super) use layout::*;
pub(self) use side::*; use side::*;

View file

@ -13,11 +13,11 @@ impl From<&str> for Exec {
fn from(value: &str) -> Self { fn from(value: &str) -> Self {
let mut exec = Self::default(); let mut exec = Self::default();
for x in value.split_whitespace() { for x in value.split_whitespace() {
if x.starts_with("--") { if let Some(kv) = x.strip_prefix("--") {
let mut it = x[2..].splitn(2, '='); let mut it = kv.splitn(2, '=');
let name = it.next().unwrap(); let key = it.next().unwrap();
let value = it.next().unwrap_or(""); let value = it.next().unwrap_or("");
exec.named.insert(name.to_string(), value.to_string()); exec.named.insert(key.to_string(), value.to_string());
} else if exec.cmd.is_empty() { } else if exec.cmd.is_empty() {
exec.cmd = x.to_string(); exec.cmd = x.to_string();
} else { } else {

View file

@ -122,7 +122,6 @@ impl ToString for Key {
} }
let code = match self.code { let code = match self.code {
KeyCode::Char(' ') => "Space",
KeyCode::Backspace => "Backspace", KeyCode::Backspace => "Backspace",
KeyCode::Enter => "Enter", KeyCode::Enter => "Enter",
KeyCode::Left => "Left", KeyCode::Left => "Left",
@ -150,7 +149,7 @@ impl ToString for Key {
KeyCode::F(12) => "F12", KeyCode::F(12) => "F12",
KeyCode::Esc => "Esc", KeyCode::Esc => "Esc",
KeyCode::Char(c) if c == ' ' => "Space", KeyCode::Char(' ') => "Space",
KeyCode::Char(c) => { KeyCode::Char(c) => {
s.push(if self.shift { c.to_ascii_uppercase() } else { c }); s.push(if self.shift { c.to_ascii_uppercase() } else { c });
"" ""

View file

@ -54,9 +54,11 @@ impl<'de> Deserialize<'de> for Keymap {
} }
} }
impl Keymap { impl Default for Keymap {
pub fn new() -> Self { toml::from_str(&MERGED_KEYMAP).unwrap() } fn default() -> Self { toml::from_str(&MERGED_KEYMAP).unwrap() }
}
impl Keymap {
#[inline] #[inline]
pub fn get(&self, layer: KeymapLayer) -> &Vec<Control> { pub fn get(&self, layer: KeymapLayer) -> &Vec<Control> {
match layer { match layer {

View file

@ -1,3 +1,5 @@
#![allow(clippy::module_inception)]
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
pub mod keymap; pub mod keymap;
@ -12,16 +14,16 @@ pub mod theme;
pub(crate) use pattern::*; pub(crate) use pattern::*;
pub(crate) use preset::*; pub(crate) use preset::*;
static MERGED_KEYMAP: Lazy<String> = Lazy::new(|| Preset::keymap()); static MERGED_KEYMAP: Lazy<String> = Lazy::new(Preset::keymap);
static MERGED_THEME: Lazy<String> = Lazy::new(|| Preset::theme()); static MERGED_THEME: Lazy<String> = Lazy::new(Preset::theme);
static MERGED_YAZI: Lazy<String> = Lazy::new(|| Preset::yazi()); static MERGED_YAZI: Lazy<String> = Lazy::new(Preset::yazi);
pub static KEYMAP: Lazy<keymap::Keymap> = Lazy::new(|| keymap::Keymap::new()); pub static KEYMAP: Lazy<keymap::Keymap> = Lazy::new(Default::default);
pub static LOG: Lazy<log::Log> = Lazy::new(|| log::Log::new()); pub static LOG: Lazy<log::Log> = Lazy::new(Default::default);
pub static MANAGER: Lazy<manager::Manager> = Lazy::new(|| manager::Manager::new()); pub static MANAGER: Lazy<manager::Manager> = Lazy::new(Default::default);
pub static OPEN: Lazy<open::Open> = Lazy::new(|| open::Open::new()); pub static OPEN: Lazy<open::Open> = Lazy::new(Default::default);
pub static PREVIEW: Lazy<preview::Preview> = Lazy::new(|| preview::Preview::new()); pub static PREVIEW: Lazy<preview::Preview> = Lazy::new(Default::default);
pub static THEME: Lazy<theme::Theme> = Lazy::new(|| theme::Theme::new()); pub static THEME: Lazy<theme::Theme> = Lazy::new(Default::default);
pub fn init() { pub fn init() {
Lazy::force(&KEYMAP); Lazy::force(&KEYMAP);

View file

@ -10,8 +10,8 @@ pub struct Log {
pub root: PathBuf, pub root: PathBuf,
} }
impl Log { impl Default for Log {
pub fn new() -> Self { toml::from_str(&MERGED_YAZI).unwrap() } fn default() -> Self { toml::from_str(&MERGED_YAZI).unwrap() }
} }
impl<'de> Deserialize<'de> for Log { impl<'de> Deserialize<'de> for Log {

View file

@ -20,8 +20,8 @@ pub struct Manager {
pub show_hidden: bool, pub show_hidden: bool,
} }
impl Manager { impl Default for Manager {
pub fn new() -> Self { fn default() -> Self {
#[derive(Deserialize)] #[derive(Deserialize)]
struct Outer { struct Outer {
manager: Manager, manager: Manager,

View file

@ -20,9 +20,11 @@ struct OpenRule {
use_: String, use_: String,
} }
impl Open { impl Default for Open {
pub fn new() -> Self { toml::from_str(&MERGED_YAZI).unwrap() } fn default() -> Self { toml::from_str(&MERGED_YAZI).unwrap() }
}
impl Open {
pub fn openers<P, M>(&self, path: P, mime: M) -> Option<Vec<&Opener>> pub fn openers<P, M>(&self, path: P, mime: M) -> Option<Vec<&Opener>>
where where
P: AsRef<Path>, P: AsRef<Path>,
@ -39,11 +41,8 @@ impl Open {
}) })
} }
pub fn common_openers<'a>( pub fn common_openers(&self, targets: &[(impl AsRef<Path>, impl AsRef<str>)]) -> Vec<&Opener> {
&self, let grouped = targets.iter().filter_map(|(p, m)| self.openers(p, m)).collect::<Vec<_>>();
targets: &[(impl AsRef<Path>, impl AsRef<str>)],
) -> Vec<&Opener> {
let grouped = targets.into_iter().filter_map(|(p, m)| self.openers(p, m)).collect::<Vec<_>>();
let flat = grouped.iter().flatten().cloned().collect::<BTreeSet<_>>(); let flat = grouped.iter().flatten().cloned().collect::<BTreeSet<_>>();
flat.into_iter().filter(|o| grouped.iter().all(|g| g.contains(o))).collect() flat.into_iter().filter(|o| grouped.iter().all(|g| g.contains(o))).collect()
} }

View file

@ -28,12 +28,13 @@ impl Default for PreviewAdaptor {
match env::var("TERM_PROGRAM").unwrap_or_default().as_str() { match env::var("TERM_PROGRAM").unwrap_or_default().as_str() {
"iTerm.app" => return Self::Iterm2, "iTerm.app" => return Self::Iterm2,
"WezTerm" => return Self::Kitty, "WezTerm" => return Self::Kitty,
"vscode" => return Self::Sixel,
"Hyper" => return Self::Sixel, "Hyper" => return Self::Sixel,
_ => {} _ => {}
} }
match env::var("XDG_SESSION_TYPE").unwrap_or_default().as_str() { match env::var("XDG_SESSION_TYPE").unwrap_or_default().as_str() {
"x11" => return Self::X11, "x11" => Self::X11,
"wayland" => return Self::Wayland, "wayland" => Self::Wayland,
_ => Self::Chafa, _ => Self::Chafa,
} }
} }
@ -56,11 +57,6 @@ impl ToString for PreviewAdaptor {
impl PreviewAdaptor { impl PreviewAdaptor {
#[inline] #[inline]
pub fn needs_ueberzug(&self) -> bool { pub fn needs_ueberzug(&self) -> bool {
match self { !matches!(self, PreviewAdaptor::Kitty | PreviewAdaptor::Iterm2 | PreviewAdaptor::Sixel)
PreviewAdaptor::Kitty => false,
PreviewAdaptor::Iterm2 => false,
PreviewAdaptor::Sixel => false,
_ => true,
}
} }
} }

View file

@ -13,8 +13,8 @@ pub struct Preview {
pub max_height: u32, pub max_height: u32,
} }
impl Preview { impl Default for Preview {
pub fn new() -> Self { fn default() -> Self {
#[derive(Deserialize)] #[derive(Deserialize)]
struct Outer { struct Outer {
preview: Preview, preview: Preview,

View file

@ -69,8 +69,8 @@ pub struct Theme {
pub icons: Vec<Icon>, pub icons: Vec<Icon>,
} }
impl Theme { impl Default for Theme {
pub fn new() -> Self { fn default() -> Self {
let mut theme: Self = toml::from_str(&MERGED_THEME).unwrap(); let mut theme: Self = toml::from_str(&MERGED_THEME).unwrap();
theme.preview.syntect_theme = theme.preview.syntect_theme =
futures::executor::block_on(absolute_path(&theme.preview.syntect_theme)); futures::executor::block_on(absolute_path(&theme.preview.syntect_theme));

View file

@ -19,13 +19,13 @@ pub async fn file(files: &[impl AsRef<OsStr>]) -> Result<BTreeMap<PathBuf, Strin
let output = String::from_utf8_lossy(&output.stdout); let output = String::from_utf8_lossy(&output.stdout);
let mimes = BTreeMap::from_iter( let mimes = BTreeMap::from_iter(
files files
.into_iter() .iter()
.zip(output.trim().lines()) .zip(output.trim().lines())
.filter(|(_, m)| MimeKind::valid(m)) .filter(|(_, m)| MimeKind::valid(m))
.map(|(f, m)| (f.as_ref().into(), m.to_string())), .map(|(f, m)| (f.as_ref().into(), m.to_string())),
); );
if mimes.len() == 0 { if mimes.is_empty() {
bail!("failed to get mime types"); bail!("failed to get mime types");
} }
Ok(mimes) Ok(mimes)

View file

@ -15,5 +15,5 @@ pub async fn pdftoppm(src: &Path, dest: impl AsRef<Path>) -> Result<()> {
if !output.status.success() { if !output.status.success() {
bail!("failed to generate PDF thumbnail: {}", String::from_utf8_lossy(&output.stderr)); bail!("failed to generate PDF thumbnail: {}", String::from_utf8_lossy(&output.stderr));
} }
Ok(Image::precache_anyway(output.stdout.into(), dest).await?) Image::precache_anyway(output.stdout.into(), dest).await
} }

View file

@ -13,7 +13,7 @@ pub struct RgOpt {
pub fn rg(opt: RgOpt) -> Result<UnboundedReceiver<Vec<PathBuf>>> { pub fn rg(opt: RgOpt) -> Result<UnboundedReceiver<Vec<PathBuf>>> {
let mut child = Command::new("rg") let mut child = Command::new("rg")
.current_dir(&opt.cwd) .current_dir(&opt.cwd)
.args(&["--color=never", "--files-with-matches", "--smart-case"]) .args(["--color=never", "--files-with-matches", "--smart-case"])
.arg(if opt.hidden { "--hidden" } else { "--no-hidden" }) .arg(if opt.hidden { "--hidden" } else { "--no-hidden" })
.arg(&opt.subject) .arg(&opt.subject)
.kill_on_drop(true) .kill_on_drop(true)

View file

@ -5,8 +5,8 @@ use tokio::{io::{AsyncReadExt, BufReader}, process::Command};
pub async fn unar_head(path: &Path, target: &Path) -> Result<Vec<u8>> { pub async fn unar_head(path: &Path, target: &Path) -> Result<Vec<u8>> {
let mut child = Command::new("unar") let mut child = Command::new("unar")
.args(&[path, target]) .args([path, target])
.args(&["-o", "-"]) .args(["-o", "-"])
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.stderr(Stdio::null()) .stderr(Stdio::null())
.kill_on_drop(true) .kill_on_drop(true)

View file

@ -9,7 +9,7 @@ pub struct ZoxideOpt {
pub fn zoxide(opt: ZoxideOpt) -> Result<Receiver<Result<PathBuf>>> { pub fn zoxide(opt: ZoxideOpt) -> Result<Receiver<Result<PathBuf>>> {
let child = Command::new("zoxide") let child = Command::new("zoxide")
.args(&["query", "-i", "--exclude"]) .args(["query", "-i", "--exclude"])
.arg(opt.cwd) .arg(opt.cwd)
.kill_on_drop(true) .kill_on_drop(true)
.stdout(Stdio::piped()) .stdout(Stdio::piped())

View file

@ -103,7 +103,7 @@ impl Input {
let snap = self.snap(); let snap = self.snap();
let b = self.handle_op( let b = self.handle_op(
if step <= 0 { if step <= 0 {
snap.cursor.saturating_sub(step.abs() as usize) snap.cursor.saturating_sub(step.unsigned_abs())
} else { } else {
snap.count().min(snap.cursor + step as usize) snap.count().min(snap.cursor + step as usize)
}, },
@ -333,11 +333,7 @@ impl Input {
pub fn selected(&self) -> Option<Rect> { pub fn selected(&self) -> Option<Rect> {
let snap = self.snap(); let snap = self.snap();
let start = if let Some(s) = snap.op.start() { let start = snap.op.start()?;
s
} else {
return None;
};
let (start, end) = let (start, end) =
if start < snap.cursor { (start, snap.cursor) } else { (snap.cursor + 1, start + 1) }; if start < snap.cursor { (start, snap.cursor) } else { (snap.cursor + 1, start + 1) };

View file

@ -52,7 +52,7 @@ impl InputSnaps {
#[inline] #[inline]
pub(super) fn catch(&mut self) { pub(super) fn catch(&mut self) {
let value = mem::replace(&mut self.versions[self.idx].value, String::new()); let value = mem::take(&mut self.versions[self.idx].value);
self.versions[self.idx] = self.current.clone(); self.versions[self.idx] = self.current.clone();
self.versions[self.idx].value = value; self.versions[self.idx].value = value;
self.versions[self.idx].reset(); self.versions[self.idx].reset();

View file

@ -1,3 +1,10 @@
#![allow(
clippy::if_same_then_else,
clippy::len_without_is_empty,
clippy::module_inception,
clippy::option_map_unit_fn
)]
mod blocker; mod blocker;
mod event; mod event;
pub mod external; pub mod external;

View file

@ -17,9 +17,9 @@ pub struct Manager {
} }
impl Manager { impl Manager {
pub fn new() -> Self { pub fn make() -> Self {
Self { Self {
tabs: Tabs::new(), tabs: Tabs::make(),
yanked: Default::default(), yanked: Default::default(),
watcher: Watcher::start(), watcher: Watcher::start(),

View file

@ -45,7 +45,7 @@ impl Preview {
} }
pub fn go(&mut self, path: &Path, mime: &str, show_image: bool) { pub fn go(&mut self, path: &Path, mime: &str, show_image: bool) {
let kind = MimeKind::new(&mime); let kind = MimeKind::new(mime);
if !show_image && matches!(kind, MimeKind::Image | MimeKind::Video) { if !show_image && matches!(kind, MimeKind::Image | MimeKind::Video) {
return; return;
} else if self.same(path, mime) { } else if self.same(path, mime) {
@ -99,7 +99,7 @@ impl Preview {
} }
pub async fn folder(path: &Path) -> Result<PreviewData> { pub async fn folder(path: &Path) -> Result<PreviewData> {
emit!(Files(match Files::read_dir(&path).await { emit!(Files(match Files::read_dir(path).await {
Ok(items) => FilesOp::Read(path.to_path_buf(), items), Ok(items) => FilesOp::Read(path.to_path_buf(), items),
Err(_) => FilesOp::IOErr(path.to_path_buf()), Err(_) => FilesOp::IOErr(path.to_path_buf()),
})); }));

View file

@ -23,7 +23,7 @@ impl Tab {
Self { Self {
mode: Default::default(), mode: Default::default(),
current: Folder::new(path), current: Folder::new(path),
parent: path.parent().map(|p| Folder::new(p)), parent: path.parent().map(Folder::new),
search: None, search: None,
@ -54,7 +54,7 @@ impl Tab {
let ok = if step > 0 { let ok = if step > 0 {
self.current.next(step as usize) self.current.next(step as usize)
} else { } else {
self.current.prev(step.abs() as usize) self.current.prev(step.unsigned_abs())
}; };
if !ok { if !ok {
return false; return false;

View file

@ -13,7 +13,7 @@ pub struct Tabs {
} }
impl Tabs { impl Tabs {
pub fn new() -> Self { pub fn make() -> Self {
let mut tabs = Self { idx: usize::MAX, items: vec![Tab::new(&MANAGER.cwd)] }; let mut tabs = Self { idx: usize::MAX, items: vec![Tab::new(&MANAGER.cwd)] };
tabs.set_idx(0); tabs.set_idx(0);
tabs tabs
@ -53,7 +53,7 @@ impl Tabs {
pub fn close(&mut self, idx: usize) -> bool { pub fn close(&mut self, idx: usize) -> bool {
let len = self.items.len(); let len = self.items.len();
if len < 2 || idx as usize >= len { if len < 2 || idx >= len {
return false; return false;
} }
@ -70,7 +70,7 @@ impl Tabs {
if rel > 0 { if rel > 0 {
(self.idx + rel as usize).min(self.items.len() - 1) (self.idx + rel as usize).min(self.items.len() - 1)
} else { } else {
self.idx.saturating_sub(rel.abs() as usize) self.idx.saturating_sub(rel.unsigned_abs())
} }
} }

View file

@ -56,7 +56,7 @@ impl Watcher {
tx.blocking_send(path).ok(); tx.blocking_send(path).ok();
tx.blocking_send(parent).ok(); tx.blocking_send(parent).ok();
} }
_ => return, _ => (),
} }
} }
}, },
@ -111,7 +111,7 @@ impl Watcher {
self.watcher.unwatch(p).ok(); self.watcher.unwatch(p).ok();
} }
for p in to_watch.clone().difference(&keys) { for p in to_watch.clone().difference(&keys) {
if self.watcher.watch(&p, RecursiveMode::NonRecursive).is_err() { if self.watcher.watch(p, RecursiveMode::NonRecursive).is_err() {
to_watch.remove(p); to_watch.remove(p);
} }
} }

View file

@ -27,9 +27,7 @@ impl Running {
pub(super) fn get_mut(&mut self, id: usize) -> Option<&mut Task> { self.all.get_mut(&id) } pub(super) fn get_mut(&mut self, id: usize) -> Option<&mut Task> { self.all.get_mut(&id) }
#[inline] #[inline]
pub(super) fn get_id(&self, idx: usize) -> Option<usize> { pub(super) fn get_id(&self, idx: usize) -> Option<usize> { self.values().nth(idx).map(|t| t.id) }
self.values().skip(idx).next().map(|t| t.id)
}
#[inline] #[inline]
pub(super) fn len(&self) -> usize { self.all.len() } pub(super) fn len(&self) -> usize { self.all.len() }

View file

@ -46,16 +46,16 @@ impl Task {
} }
} }
impl Into<TaskSummary> for &Task { impl From<&Task> for TaskSummary {
fn into(self) -> TaskSummary { fn from(task: &Task) -> Self {
TaskSummary { TaskSummary {
name: self.name.clone(), name: task.name.clone(),
found: self.found, found: task.found,
processed: self.processed, processed: task.processed,
todo: self.todo, todo: task.todo,
done: self.done, done: task.done,
} }
} }
} }

View file

@ -38,6 +38,7 @@ impl Tasks {
true true
} }
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> bool { pub fn next(&mut self) -> bool {
let limit = Self::limit().min(self.len()); let limit = Self::limit().min(self.len());
@ -132,7 +133,7 @@ impl Tasks {
let mut openers = BTreeMap::new(); let mut openers = BTreeMap::new();
for (path, mime) in targets { for (path, mime) in targets {
if let Some(opener) = OPEN.openers(path, mime).and_then(|o| o.first().cloned()) { if let Some(opener) = OPEN.openers(path, mime).and_then(|o| o.first().cloned()) {
openers.entry(opener).or_insert_with(|| vec![]).push(path.as_ref()); openers.entry(opener).or_insert_with(Vec::new).push(path.as_ref());
} }
} }
for (opener, args) in openers { for (opener, args) in openers {
@ -143,13 +144,13 @@ impl Tasks {
pub fn file_open_with(&self, opener: &Opener, args: &[impl AsRef<OsStr>]) -> bool { pub fn file_open_with(&self, opener: &Opener, args: &[impl AsRef<OsStr>]) -> bool {
if opener.spread { if opener.spread {
self.scheduler.process_open(&opener, args); self.scheduler.process_open(opener, args);
return false; return false;
} }
for target in args { for target in args {
self.scheduler.process_open(&opener, &[target]); self.scheduler.process_open(opener, &[target]);
} }
return false; false
} }
pub fn file_cut(&self, src: &HashSet<PathBuf>, dest: PathBuf, force: bool) -> bool { pub fn file_cut(&self, src: &HashSet<PathBuf>, dest: PathBuf, force: bool) -> bool {
@ -238,7 +239,7 @@ impl Tasks {
pub fn precache_image(&self, mimetype: &BTreeMap<PathBuf, String>) -> bool { pub fn precache_image(&self, mimetype: &BTreeMap<PathBuf, String>) -> bool {
let targets = mimetype let targets = mimetype
.into_iter() .iter()
.filter(|(_, m)| MimeKind::new(m) == MimeKind::Image) .filter(|(_, m)| MimeKind::new(m) == MimeKind::Image)
.map(|(p, _)| p.clone()) .map(|(p, _)| p.clone())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -251,7 +252,7 @@ impl Tasks {
pub fn precache_video(&self, mimetype: &BTreeMap<PathBuf, String>) -> bool { pub fn precache_video(&self, mimetype: &BTreeMap<PathBuf, String>) -> bool {
let targets = mimetype let targets = mimetype
.into_iter() .iter()
.filter(|(_, m)| MimeKind::new(m) == MimeKind::Video) .filter(|(_, m)| MimeKind::new(m) == MimeKind::Video)
.map(|(p, _)| p.clone()) .map(|(p, _)| p.clone())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -264,7 +265,7 @@ impl Tasks {
pub fn precache_pdf(&self, mimetype: &BTreeMap<PathBuf, String>) -> bool { pub fn precache_pdf(&self, mimetype: &BTreeMap<PathBuf, String>) -> bool {
let targets = mimetype let targets = mimetype
.into_iter() .iter()
.filter(|(_, m)| MimeKind::new(m) == MimeKind::PDF) .filter(|(_, m)| MimeKind::new(m) == MimeKind::PDF)
.map(|(p, _)| p.clone()) .map(|(p, _)| p.clone())
.collect::<Vec<_>>(); .collect::<Vec<_>>();

View file

@ -21,7 +21,7 @@ pub(crate) struct Precache {
pub(crate) enum PrecacheOp { pub(crate) enum PrecacheOp {
Image(PrecacheOpImage), Image(PrecacheOpImage),
Video(PrecacheOpVideo), Video(PrecacheOpVideo),
PDF(PrecacheOpPDF), Pdf(PrecacheOpPDF),
} }
#[derive(Debug)] #[derive(Debug)]
@ -66,7 +66,7 @@ impl Precache {
Ok(match self.rx.recv().await? { Ok(match self.rx.recv().await? {
PrecacheOp::Image(t) => (t.id, PrecacheOp::Image(t)), PrecacheOp::Image(t) => (t.id, PrecacheOp::Image(t)),
PrecacheOp::Video(t) => (t.id, PrecacheOp::Video(t)), PrecacheOp::Video(t) => (t.id, PrecacheOp::Video(t)),
PrecacheOp::PDF(t) => (t.id, PrecacheOp::PDF(t)), PrecacheOp::Pdf(t) => (t.id, PrecacheOp::Pdf(t)),
}) })
} }
@ -91,7 +91,7 @@ impl Precache {
external::ffmpegthumbnailer(&task.target, &cache).await.ok(); external::ffmpegthumbnailer(&task.target, &cache).await.ok();
self.sch.send(TaskOp::Adv(task.id, 1, 0))?; self.sch.send(TaskOp::Adv(task.id, 1, 0))?;
} }
PrecacheOp::PDF(task) => { PrecacheOp::Pdf(task) => {
let cache = Image::cache(&task.target); let cache = Image::cache(&task.target);
if fs::metadata(&cache).await.is_ok() { if fs::metadata(&cache).await.is_ok() {
return Ok(self.sch.send(TaskOp::Adv(task.id, 1, 0))?); return Ok(self.sch.send(TaskOp::Adv(task.id, 1, 0))?);
@ -159,7 +159,7 @@ impl Precache {
pub(crate) fn pdf(&self, id: usize, targets: Vec<PathBuf>) -> Result<()> { pub(crate) fn pdf(&self, id: usize, targets: Vec<PathBuf>) -> Result<()> {
for target in targets { for target in targets {
self.sch.send(TaskOp::New(id, 0))?; self.sch.send(TaskOp::New(id, 0))?;
self.tx.send_blocking(PrecacheOp::PDF(PrecacheOpPDF { id, target }))?; self.tx.send_blocking(PrecacheOp::Pdf(PrecacheOpPDF { id, target }))?;
} }
self.done(id) self.done(id)
} }

View file

@ -22,18 +22,14 @@ impl Which {
pub fn show(&mut self, key: &Key, layer: KeymapLayer) -> bool { pub fn show(&mut self, key: &Key, layer: KeymapLayer) -> bool {
self.layer = layer; self.layer = layer;
self.times = 1; self.times = 1;
self.cands = KEYMAP self.cands =
.get(layer) KEYMAP.get(layer).iter().filter(|s| s.on.len() > 1 && s.on[0] == *key).cloned().collect();
.into_iter()
.filter(|s| s.on.len() > 1 && s.on[0] == *key)
.cloned()
.collect();
self.switch(true); self.switch(true);
true true
} }
pub fn press(&mut self, key: Key) -> bool { pub fn press(&mut self, key: Key) -> bool {
self.cands = mem::replace(&mut self.cands, Vec::new()) self.cands = mem::take(&mut self.cands)
.into_iter() .into_iter()
.filter(|s| s.on.len() > self.times && s.on[self.times] == key) .filter(|s| s.on.len() > self.times && s.on[self.times] == key)
.collect(); .collect();
@ -49,7 +45,7 @@ impl Which {
} }
self.times += 1; self.times += 1;
return true; true
} }
#[inline] #[inline]

View file

@ -1 +1 @@
{"version":"0.2","flagWords":[],"language":"en","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"]} {"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"],"language":"en","version":"0.2","flagWords":[]}

View file

@ -98,6 +98,7 @@ pub fn copy_with_progress(from: &Path, to: &Path) -> mpsc::Receiver<Result<u64,
} }
// Convert a file mode to a string representation // Convert a file mode to a string representation
#[allow(clippy::collapsible_else_if)]
pub fn file_mode(mode: u32) -> String { pub fn file_mode(mode: u32) -> String {
use libc::{S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFMT, S_IFSOCK, S_IRGRP, S_IROTH, S_IRUSR, S_ISGID, S_ISUID, S_ISVTX, S_IWGRP, S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR}; use libc::{S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO, S_IFLNK, S_IFMT, S_IFSOCK, S_IRGRP, S_IROTH, S_IRUSR, S_ISGID, S_ISUID, S_ISVTX, S_IWGRP, S_IWOTH, S_IWUSR, S_IXGRP, S_IXOTH, S_IXUSR};

View file

@ -28,19 +28,8 @@ impl MimeKind {
return false; return false;
} }
let b = match parts[0] { #[rustfmt::skip]
"application" => true, let b = matches!(parts[0], "application" | "audio" | "example" | "font" | "image" | "message" | "model" | "multipart" | "text" | "video");
"audio" => true,
"example" => true,
"font" => true,
"image" => true,
"message" => true,
"model" => true,
"multipart" => true,
"text" => true,
"video" => true,
_ => false,
};
b && !parts[1].is_empty() b && !parts[1].is_empty()
} }

View file

@ -47,7 +47,7 @@ impl<T> Throttle<T> {
where where
F: FnOnce(Vec<T>), F: FnOnce(Vec<T>),
{ {
let mut buf = mem::replace(&mut *self.buf.lock(), Vec::new()); let mut buf = mem::take(&mut *self.buf.lock());
buf.push(data); buf.push(data);
f(buf) f(buf)
} }