This commit is contained in:
sxyazi 2023-08-16 01:03:44 +08:00
parent c96bee7715
commit ea2e44c901
No known key found for this signature in database
21 changed files with 179 additions and 95 deletions

59
Cargo.lock generated
View file

@ -344,6 +344,7 @@ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
"crossterm 0.27.0", "crossterm 0.27.0",
"dirs",
"futures", "futures",
"glob", "glob",
"indexmap 2.0.0", "indexmap 2.0.0",
@ -355,7 +356,6 @@ dependencies = [
"shell-words", "shell-words",
"toml", "toml",
"validator", "validator",
"xdg",
] ]
[[package]] [[package]]
@ -515,6 +515,27 @@ dependencies = [
"crypto-common", "crypto-common",
] ]
[[package]]
name = "dirs"
version = "5.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs-sys"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
dependencies = [
"libc",
"option-ext",
"redox_users",
"windows-sys 0.48.0",
]
[[package]] [[package]]
name = "either" name = "either"
version = "1.9.0" version = "1.9.0"
@ -587,7 +608,7 @@ checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"redox_syscall", "redox_syscall 0.3.5",
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
@ -1212,6 +1233,12 @@ dependencies = [
"pkg-config", "pkg-config",
] ]
[[package]]
name = "option-ext"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]] [[package]]
name = "overload" name = "overload"
version = "0.1.1" version = "0.1.1"
@ -1236,7 +1263,7 @@ checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"redox_syscall", "redox_syscall 0.3.5",
"smallvec", "smallvec",
"windows-targets 0.48.2", "windows-targets 0.48.2",
] ]
@ -1415,6 +1442,15 @@ dependencies = [
"num_cpus", "num_cpus",
] ]
[[package]]
name = "redox_syscall"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [
"bitflags 1.3.2",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.3.5" version = "0.3.5"
@ -1424,6 +1460,17 @@ dependencies = [
"bitflags 1.3.2", "bitflags 1.3.2",
] ]
[[package]]
name = "redox_users"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
dependencies = [
"getrandom",
"redox_syscall 0.2.16",
"thiserror",
]
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.9.3" version = "1.9.3"
@ -2307,12 +2354,6 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "xdg"
version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546"
[[package]] [[package]]
name = "yaml-rust" name = "yaml-rust"
version = "0.4.5" version = "0.4.5"

View file

@ -3,7 +3,7 @@ use std::{path::Path, sync::Arc};
use anyhow::Result; use anyhow::Result;
use config::PREVIEW; use config::PREVIEW;
use image::{imageops::FilterType, DynamicImage, ImageFormat}; use image::{imageops::FilterType, DynamicImage, ImageFormat};
use shared::tty_ratio; use shared::Term;
use tokio::fs; use tokio::fs;
pub struct Image; pub struct Image;
@ -11,7 +11,7 @@ pub struct Image;
impl Image { impl Image {
pub(super) async fn crop(path: &Path, size: (u16, u16)) -> Result<DynamicImage> { pub(super) async fn crop(path: &Path, size: (u16, u16)) -> Result<DynamicImage> {
let (w, h) = { let (w, h) = {
let r = tty_ratio(); let r = Term::ratio();
let (w, h) = ((size.0 as f64 * r.0) as u32, (size.1 as f64 * r.1) as u32); let (w, h) = ((size.0 as f64 * r.0) as u32, (size.1 as f64 * r.1) as u32);
(w.min(PREVIEW.max_width), h.min(PREVIEW.max_height)) (w.min(PREVIEW.max_width), h.min(PREVIEW.max_height))
}; };

View file

@ -10,13 +10,13 @@ core = { path = "../core" }
shared = { path = "../shared" } shared = { path = "../shared" }
# External dependencies # External dependencies
ansi-to-tui = "^3" ansi-to-tui = "^3"
anyhow = "^1" anyhow = "^1"
crossterm = { version = "^0", features = [ "event-stream" ] } crossterm = { version = "^0", features = [ "event-stream" ] }
futures = "^0" futures = "^0"
ratatui = "^0" ratatui = "^0"
tokio = { version = "^1", features = [ "parking_lot" ] } tokio = { version = "^1", features = [ "parking_lot" ] }
unicode-width = "^0" unicode-width = "^0"
# Logging # Logging
tracing = "^0" tracing = "^0"

View file

@ -42,9 +42,17 @@ impl App {
fn dispatch_quit(&mut self) { fn dispatch_quit(&mut self) {
if let Some(p) = &BOOT.cwd_file { if let Some(p) = &BOOT.cwd_file {
use std::os::unix::prelude::OsStrExt;
let cwd = self.cx.manager.cwd().as_os_str(); let cwd = self.cx.manager.cwd().as_os_str();
std::fs::write(p, cwd.as_bytes()).ok();
#[cfg(target_os = "windows")]
{
std::fs::write(p, cwd.to_string_lossy().as_bytes()).ok();
}
#[cfg(not(target_os = "windows"))]
{
use std::os::unix::ffi::OsStrExt;
std::fs::write(p, cwd.as_bytes()).ok();
}
} }
} }

View file

@ -1,9 +1,9 @@
use core::{input::Input, manager::Manager, select::Select, tasks::Tasks, which::Which, Position}; use core::{input::Input, manager::Manager, select::Select, tasks::Tasks, which::Which, Position};
use config::keymap::KeymapLayer; use config::keymap::KeymapLayer;
use libc::winsize; use crossterm::terminal::WindowSize;
use ratatui::prelude::Rect; use ratatui::prelude::Rect;
use shared::tty_size; use shared::Term;
pub struct Ctx { pub struct Ctx {
pub manager: Manager, pub manager: Manager,
@ -25,14 +25,14 @@ impl Ctx {
} }
pub(super) fn area(&self, pos: &Position) -> Rect { pub(super) fn area(&self, pos: &Position) -> Rect {
let winsize { ws_row, ws_col, .. } = tty_size(); let WindowSize { rows, columns, .. } = Term::size();
let (x, y) = match pos { let (x, y) = match pos {
Position::None => return Rect::default(), Position::None => return Rect::default(),
Position::Top(Rect { mut x, mut y, width, height }) => { Position::Top(Rect { mut x, mut y, width, height }) => {
x = x.min(ws_col.saturating_sub(*width)); x = x.min(columns.saturating_sub(*width));
y = y.min(ws_row.saturating_sub(*height)); y = y.min(rows.saturating_sub(*height));
((tty_size().ws_col / 2).saturating_sub(width / 2) + x, y) ((columns / 2).saturating_sub(width / 2) + x, y)
} }
Position::Hovered(rect @ Rect { mut x, y, width, height }) => { Position::Hovered(rect @ Rect { mut x, y, width, height }) => {
let Some(r) = let Some(r) =
@ -41,8 +41,8 @@ impl Ctx {
return self.area(&Position::Top(*rect)); return self.area(&Position::Top(*rect));
}; };
x = x.min(ws_col.saturating_sub(*width)); x = x.min(columns.saturating_sub(*width));
if y + height + r.y + r.height > ws_row { if y + height + r.y + r.height > rows {
(x + r.x, r.y.saturating_sub(height.saturating_sub(1))) (x + r.x, r.y.saturating_sub(height.saturating_sub(1)))
} else { } else {
(x + r.x, y + r.y + r.height) (x + r.x, y + r.y + r.height)
@ -51,7 +51,7 @@ impl Ctx {
}; };
let (w, h) = pos.dimension().unwrap(); let (w, h) = pos.dimension().unwrap();
Rect { x, y, width: w.min(ws_col.saturating_sub(x)), height: h.min(ws_row.saturating_sub(y)) } Rect { x, y, width: w.min(columns.saturating_sub(x)), height: h.min(rows.saturating_sub(y)) }
} }
#[inline] #[inline]

View file

@ -11,6 +11,7 @@ pub(super) struct Right<'a> {
impl<'a> Right<'a> { impl<'a> Right<'a> {
pub(super) fn new(cx: &'a Ctx) -> Self { Self { cx } } pub(super) fn new(cx: &'a Ctx) -> Self { Self { cx } }
#[cfg(not(target_os = "windows"))]
fn permissions(&self, s: &str) -> Vec<Span> { fn permissions(&self, s: &str) -> Vec<Span> {
// Colors // Colors
let mode = self.cx.manager.active().mode(); let mode = self.cx.manager.active().mode();

View file

@ -1,11 +1,14 @@
cargo +stable build --release --target aarch64-apple-darwin cargo +stable build --release --target aarch64-apple-darwin
cargo +stable build --release --target x86_64-apple-darwin cargo +stable build --release --target x86_64-apple-darwin
cargo +stable build --release --target x86_64-unknown-linux-gnu cargo +stable build --release --target x86_64-unknown-linux-gnu
cargo +stable build --release --target x86_64-pc-windows-gnu
mv target/aarch64-apple-darwin/release/yazi yazi-aarch64-apple-darwin mv target/aarch64-apple-darwin/release/yazi yazi-aarch64-apple-darwin
mv target/x86_64-apple-darwin/release/yazi yazi-x86_64-apple-darwin mv target/x86_64-apple-darwin/release/yazi yazi-x86_64-apple-darwin
mv target/x86_64-unknown-linux-gnu/release/yazi yazi-x86_64-unknown-linux-gnu mv target/x86_64-unknown-linux-gnu/release/yazi yazi-x86_64-unknown-linux-gnu
mv target/x86_64-pc-windows-gnu/release/yazi yazi-x86_64-pc-windows-gnu
zip -j yazi-aarch64-apple-darwin.zip yazi-aarch64-apple-darwin zip -j yazi-aarch64-apple-darwin.zip yazi-aarch64-apple-darwin
zip -j yazi-x86_64-apple-darwin.zip yazi-x86_64-apple-darwin zip -j yazi-x86_64-apple-darwin.zip yazi-x86_64-apple-darwin
zip -j yazi-x86_64-unknown-linux-gnu.zip yazi-x86_64-unknown-linux-gnu zip -j yazi-x86_64-unknown-linux-gnu.zip yazi-x86_64-unknown-linux-gnu
zip -j yazi-x86_64-pc-windows-gnu.zip yazi-x86_64-pc-windows-gnu

View file

@ -10,6 +10,7 @@ shared = { path = "../shared" }
anyhow = "^1" anyhow = "^1"
clap = { version = "^4", features = [ "derive" ] } clap = { version = "^4", features = [ "derive" ] }
crossterm = "^0" crossterm = "^0"
dirs = "^5"
futures = "^0" futures = "^0"
glob = "^0" glob = "^0"
indexmap = "^2" indexmap = "^2"
@ -20,4 +21,3 @@ serde = { version = "^1", features = [ "derive" ] }
shell-words = "^1" shell-words = "^1"
toml = { version = "^0", features = [ "preserve_order" ] } toml = { version = "^0", features = [ "preserve_order" ] }
validator = { version = "^0", features = [ "derive" ] } validator = { version = "^0", features = [ "derive" ] }
xdg = "^2"

View file

@ -1,9 +1,11 @@
use std::{env, fs, os::unix::prelude::OsStrExt, path::{Path, PathBuf}, time::{self, SystemTime}}; use std::{env, fs, path::{Path, PathBuf}, time::{self, SystemTime}};
use clap::{command, Parser}; use clap::{command, Parser};
use md5::{Digest, Md5}; use md5::{Digest, Md5};
use shared::absolute_path; use shared::absolute_path;
use crate::Xdg;
#[derive(Debug)] #[derive(Debug)]
pub struct Boot { pub struct Boot {
pub cwd: PathBuf, pub cwd: PathBuf,
@ -63,9 +65,16 @@ impl Default for Boot {
impl Boot { impl Boot {
#[inline] #[inline]
pub fn cache(&self, path: &Path) -> PathBuf { pub fn cache(&self, path: &Path) -> PathBuf {
self #[cfg(target_os = "windows")]
.cache_dir let h = Md5::new_with_prefix(path.to_string_lossy().as_bytes());
.join(format!("{:x}", Md5::new_with_prefix(path.as_os_str().as_bytes()).finalize()))
#[cfg(not(target_os = "windows"))]
let h = {
use std::os::unix::ffi::OsStrExt;
Md5::new_with_prefix(path.as_os_str().as_bytes())
};
self.cache_dir.join(format!("{:x}", h.finalize()))
} }
#[inline] #[inline]

View file

@ -1,23 +0,0 @@
use std::path::PathBuf;
#[cfg(target_os = "windows")]
pub(crate) fn get_config_file(path: &str) -> PathBuf { dirs::config_dir().unwrap().join(path) }
#[cfg(not(target_os = "windows"))]
pub(crate) fn get_config_file(path: &str) -> PathBuf {
xdg::BaseDirectories::new().unwrap().get_config_file(path)
}
#[cfg(target_os = "windows")]
pub(crate) fn get_state_dir() -> Result<PathBuf, String> {
dirs::data_dir()
.map(|dir| dir.join("yazi").join("state"))
.ok_or_else(|| String::from("failed to get state directory"))
}
#[cfg(not(target_os = "windows"))]
pub(crate) fn get_state_dir() -> Result<PathBuf, String> {
xdg::BaseDirectories::with_prefix("yazi")
.map(|dirs| dirs.get_state_home())
.map_err(|e| e.to_string())
}

View file

@ -3,7 +3,6 @@
use shared::RoCell; use shared::RoCell;
mod boot; mod boot;
mod dir;
pub mod keymap; pub mod keymap;
mod log; mod log;
pub mod manager; pub mod manager;
@ -14,9 +13,11 @@ pub mod preview;
pub mod tasks; pub mod tasks;
pub mod theme; pub mod theme;
mod validation; mod validation;
mod xdg;
pub(crate) use pattern::*; pub(crate) use pattern::*;
pub(crate) use preset::*; pub(crate) use preset::*;
pub(crate) use xdg::*;
static MERGED_KEYMAP: RoCell<String> = RoCell::new(); static MERGED_KEYMAP: RoCell<String> = RoCell::new();
static MERGED_THEME: RoCell<String> = RoCell::new(); static MERGED_THEME: RoCell<String> = RoCell::new();

View file

@ -1,7 +1,8 @@
use std::fs; use std::fs;
use toml::Table; use toml::Table;
use xdg::BaseDirectories;
use crate::xdg::Xdg;
pub(crate) struct Preset; pub(crate) struct Preset;
@ -28,7 +29,7 @@ impl Preset {
} }
fn merge_str(user: &str, base: &str) -> String { fn merge_str(user: &str, base: &str) -> String {
let path = BaseDirectories::new().unwrap().get_config_file(user); let path = Xdg::config_dir().unwrap().join(user);
let mut user = fs::read_to_string(path).unwrap_or_default().parse::<Table>().unwrap(); let mut user = fs::read_to_string(path).unwrap_or_default().parse::<Table>().unwrap();
let base = base.parse::<Table>().unwrap(); let base = base.parse::<Table>().unwrap();
@ -38,16 +39,16 @@ impl Preset {
#[inline] #[inline]
pub(crate) fn keymap() -> String { pub(crate) fn keymap() -> String {
Self::merge_str("yazi/keymap.toml", include_str!("../preset/keymap.toml")) Self::merge_str("keymap.toml", include_str!("../preset/keymap.toml"))
} }
#[inline] #[inline]
pub(crate) fn theme() -> String { pub(crate) fn theme() -> String {
Self::merge_str("yazi/theme.toml", include_str!("../preset/theme.toml")) Self::merge_str("theme.toml", include_str!("../preset/theme.toml"))
} }
#[inline] #[inline]
pub(crate) fn yazi() -> String { pub(crate) fn yazi() -> String {
Self::merge_str("yazi/yazi.toml", include_str!("../preset/yazi.toml")) Self::merge_str("yazi.toml", include_str!("../preset/yazi.toml"))
} }
} }

35
config/src/xdg.rs Normal file
View file

@ -0,0 +1,35 @@
use std::path::PathBuf;
pub(super) struct Xdg;
impl Xdg {
pub(super) fn config_dir() -> Option<PathBuf> {
#[cfg(target_os = "windows")]
{
dirs::config_dir().map(|p| p.join("yazi").join("config"))
}
#[cfg(not(target_os = "windows"))]
{
std::env::var_os("XDG_CONFIG_HOME")
.map(PathBuf::from)
.and_then(|p| p.is_absolute().then_some(p))
.or_else(|| dirs::home_dir().map(|h| h.join(".config")))
.map(|p| p.join("yazi"))
}
}
pub(super) fn state_dir() -> Option<PathBuf> {
#[cfg(target_os = "windows")]
{
dirs::data_dir().map(|p| p.join("yazi").join("state"))
}
#[cfg(not(target_os = "windows"))]
{
std::env::var_os("XDG_STATE_HOME")
.map(PathBuf::from)
.and_then(|p| p.is_absolute().then_some(p))
.or_else(|| dirs::home_dir().map(|h| h.join(".local/state")))
.map(|p| p.join("yazi"))
}
}
}

View file

@ -1,8 +1,8 @@
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use crossterm::terminal::size;
use indexmap::map::Slice; use indexmap::map::Slice;
use ratatui::layout::Rect; use ratatui::layout::Rect;
use shared::Term;
use super::{ALL_RATIO, CURRENT_RATIO, DIR_PADDING, PARENT_RATIO}; use super::{ALL_RATIO, CURRENT_RATIO, DIR_PADDING, PARENT_RATIO};
use crate::{emit, files::{File, Files, FilesOp}}; use crate::{emit, files::{File, Files, FilesOp}};
@ -27,7 +27,7 @@ impl Folder {
} }
#[inline] #[inline]
pub fn limit() -> usize { size().unwrap_or_default().1.saturating_sub(DIR_PADDING) as usize } pub fn limit() -> usize { Term::size().rows.saturating_sub(DIR_PADDING) as usize }
pub fn update(&mut self, op: FilesOp) -> bool { pub fn update(&mut self, op: FilesOp) -> bool {
let b = match op { let b = match op {
@ -183,12 +183,12 @@ impl Folder {
pub fn rect_current(&self, path: &Path) -> Option<Rect> { pub fn rect_current(&self, path: &Path) -> Option<Rect> {
let pos = self.position(path)? - self.offset; let pos = self.position(path)? - self.offset;
let s = size().unwrap_or_default(); let s = Term::size();
Some(Rect { Some(Rect {
x: (s.0 as u32 * PARENT_RATIO / ALL_RATIO) as u16, x: (s.columns as u32 * PARENT_RATIO / ALL_RATIO) as u16,
y: pos as u16, y: pos as u16,
width: (s.0 as u32 * CURRENT_RATIO / ALL_RATIO) as u16, width: (s.columns as u32 * CURRENT_RATIO / ALL_RATIO) as u16,
height: 1, height: 1,
}) })
} }

View file

@ -1,4 +1,4 @@
use std::{collections::{BTreeMap, BTreeSet, HashMap, HashSet}, env, ffi::OsStr, io::{stdout, BufWriter, Write}, mem, os::unix::prelude::OsStrExt, path::{Path, PathBuf}}; use std::{collections::{BTreeMap, BTreeSet, HashMap, HashSet}, env, ffi::OsStr, io::{stdout, BufWriter, Write}, mem, path::{Path, PathBuf}};
use anyhow::{anyhow, bail, Error, Result}; use anyhow::{anyhow, bail, Error, Result};
use config::{open::Opener, BOOT, OPEN}; use config::{open::Opener, BOOT, OPEN};
@ -231,9 +231,17 @@ impl Manager {
}; };
{ {
let b = old.iter().map(|o| o.as_os_str()).collect::<Vec<_>>().join(OsStr::new("\n")); let s = old.iter().map(|o| o.as_os_str()).collect::<Vec<_>>().join(OsStr::new("\n"));
let mut f = OpenOptions::new().write(true).create_new(true).open(&tmp).await?; let mut f = OpenOptions::new().write(true).create_new(true).open(&tmp).await?;
f.write_all(b.as_bytes()).await?; #[cfg(target_os = "windows")]
{
f.write_all(s.to_string_lossy().as_bytes()).await?;
}
#[cfg(not(target_os = "windows"))]
{
use std::os::unix::ffi::OsStrExt;
f.write_all(s.as_bytes()).await?;
}
} }
let _guard = BLOCKER.acquire().await.unwrap(); let _guard = BLOCKER.acquire().await.unwrap();

View file

@ -4,7 +4,7 @@ use adaptor::Adaptor;
use anyhow::{anyhow, bail, Result}; use anyhow::{anyhow, bail, Result};
use config::{BOOT, PREVIEW}; use config::{BOOT, PREVIEW};
use ratatui::prelude::Rect; use ratatui::prelude::Rect;
use shared::{tty_size, MimeKind}; use shared::{MimeKind, Term};
use syntect::{easy::HighlightFile, util::as_24_bit_terminal_escaped}; use syntect::{easy::HighlightFile, util::as_24_bit_terminal_escaped};
use tokio::{fs, task::JoinHandle}; use tokio::{fs, task::JoinHandle};
@ -31,16 +31,16 @@ pub enum PreviewData {
impl Preview { impl Preview {
fn rect() -> Rect { fn rect() -> Rect {
let s = tty_size(); let s = Term::size();
let x = (s.ws_col as u32 * (PARENT_RATIO + CURRENT_RATIO) / ALL_RATIO) as u16; let x = (s.columns as u32 * (PARENT_RATIO + CURRENT_RATIO) / ALL_RATIO) as u16;
let width = (s.ws_col as u32 * PREVIEW_RATIO / ALL_RATIO) as u16; let width = (s.columns as u32 * PREVIEW_RATIO / ALL_RATIO) as u16;
Rect { Rect {
x: x.saturating_add(PREVIEW_BORDER / 2), x: x.saturating_add(PREVIEW_BORDER / 2),
y: PREVIEW_MARGIN / 2, y: PREVIEW_MARGIN / 2,
width: width.saturating_sub(PREVIEW_BORDER), width: width.saturating_sub(PREVIEW_BORDER),
height: s.ws_row.saturating_sub(PREVIEW_MARGIN), height: s.rows.saturating_sub(PREVIEW_MARGIN),
} }
} }

View file

@ -2,7 +2,7 @@ use std::{collections::{BTreeMap, HashMap, HashSet}, ffi::OsStr, io::{stdout, Wr
use config::{manager::SortBy, open::Opener, OPEN}; use config::{manager::SortBy, open::Opener, OPEN};
use crossterm::terminal::{disable_raw_mode, enable_raw_mode}; use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
use shared::{tty_size, Defer, MimeKind, Term}; use shared::{Defer, MimeKind, Term};
use tokio::{io::{stdin, AsyncReadExt}, select, sync::mpsc, time}; use tokio::{io::{stdin, AsyncReadExt}, select, sync::mpsc, time};
use tracing::trace; use tracing::trace;
@ -29,7 +29,7 @@ impl Tasks {
#[inline] #[inline]
pub fn limit() -> usize { pub fn limit() -> usize {
(tty_size().ws_row * TASKS_PERCENT / 100).saturating_sub(TASKS_PADDING) as usize (Term::size().rows * TASKS_PERCENT / 100).saturating_sub(TASKS_PADDING) as usize
} }
pub fn toggle(&mut self) -> bool { pub fn toggle(&mut self) -> bool {

View file

@ -91,11 +91,8 @@ pub fn copy_with_progress(from: &Path, to: &Path) -> mpsc::Receiver<Result<u64,
rx rx
} }
#[cfg(target_os = "windows")]
pub fn file_mode(_: u32) -> String { String::new() }
#[cfg(not(target_os = "windows"))]
// Convert a file mode to a string representation // Convert a file mode to a string representation
#[cfg(not(target_os = "windows"))]
#[allow(clippy::collapsible_else_if)] #[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

@ -7,7 +7,6 @@ mod mime;
mod ro_cell; mod ro_cell;
mod term; mod term;
mod throttle; mod throttle;
mod tty;
pub use buffer::*; pub use buffer::*;
pub use chars::*; pub use chars::*;
@ -18,4 +17,3 @@ pub use mime::*;
pub use ro_cell::*; pub use ro_cell::*;
pub use term::*; pub use term::*;
pub use throttle::*; pub use throttle::*;
pub use tty::*;

View file

@ -1,7 +1,7 @@
use std::{io::{stdout, Stdout, Write}, ops::{Deref, DerefMut}}; use std::{io::{stdout, Stdout, Write}, ops::{Deref, DerefMut}};
use anyhow::Result; use anyhow::Result;
use crossterm::{cursor::{MoveTo, SetCursorStyle}, event::{DisableBracketedPaste, DisableFocusChange, EnableBracketedPaste, EnableFocusChange, KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags}, execute, queue, terminal::{disable_raw_mode, enable_raw_mode, supports_keyboard_enhancement, Clear, ClearType, EnterAlternateScreen, LeaveAlternateScreen}}; use crossterm::{cursor::{MoveTo, SetCursorStyle}, event::{DisableBracketedPaste, DisableFocusChange, EnableBracketedPaste, EnableFocusChange, KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags}, execute, queue, terminal::{disable_raw_mode, enable_raw_mode, supports_keyboard_enhancement, Clear, ClearType, EnterAlternateScreen, LeaveAlternateScreen, WindowSize}};
use ratatui::{backend::CrosstermBackend, Terminal}; use ratatui::{backend::CrosstermBackend, Terminal};
pub struct Term { pub struct Term {
@ -32,6 +32,21 @@ impl Term {
Ok(term) Ok(term)
} }
#[inline]
pub fn size() -> WindowSize {
if let Ok(s) = crossterm::terminal::window_size() {
return s;
};
// TODO
WindowSize { rows: 1, columns: 1, width: 0, height: 0 }
}
#[inline]
pub fn ratio() -> (f64, f64) {
let s = Self::size();
(f64::from(s.width) / f64::from(s.columns), f64::from(s.height) / f64::from(s.rows))
}
#[inline] #[inline]
pub fn clear(stdout: &mut impl Write) -> Result<()> { pub fn clear(stdout: &mut impl Write) -> Result<()> {
execute!(stdout, Clear(ClearType::All))?; execute!(stdout, Clear(ClearType::All))?;

View file

@ -1,10 +0,0 @@
use crossterm::terminal::window_size;
#[inline]
pub fn tty_ratio() -> (f64, f64) {
if let Ok(ws) = window_size() {
(f64::from(ws.width) / f64::from(ws.columns), f64::from(ws.height) / f64::from(ws.rows))
} else {
(1f64, 1f64)
}
}