mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: prepare for Windows
This commit is contained in:
parent
b70f83ced7
commit
c96bee7715
10 changed files with 67 additions and 28 deletions
|
|
@ -14,9 +14,7 @@ ansi-to-tui = "^3"
|
||||||
anyhow = "^1"
|
anyhow = "^1"
|
||||||
crossterm = { version = "^0", features = [ "event-stream" ] }
|
crossterm = { version = "^0", features = [ "event-stream" ] }
|
||||||
futures = "^0"
|
futures = "^0"
|
||||||
libc = "^0"
|
|
||||||
ratatui = "^0"
|
ratatui = "^0"
|
||||||
signal-hook-tokio = { version = "^0", features = [ "futures-v0_3" ] }
|
|
||||||
tokio = { version = "^1", features = [ "parking_lot" ] }
|
tokio = { version = "^1", features = [ "parking_lot" ] }
|
||||||
unicode-width = "^0"
|
unicode-width = "^0"
|
||||||
|
|
||||||
|
|
@ -25,6 +23,10 @@ tracing = "^0"
|
||||||
tracing-appender = "^0"
|
tracing-appender = "^0"
|
||||||
tracing-subscriber = "^0"
|
tracing-subscriber = "^0"
|
||||||
|
|
||||||
|
[target.'cfg(not(target_os = "windows"))'.dependencies]
|
||||||
|
libc = "^0"
|
||||||
|
signal-hook-tokio = { version = "^0", features = [ "futures-v0_3" ] }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "yazi"
|
name = "yazi"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
use core::{emit, files::FilesOp, input::InputMode, Event};
|
use core::{emit, files::FilesOp, input::InputMode, Event};
|
||||||
use std::{ffi::OsString, os::unix::prelude::OsStrExt};
|
|
||||||
|
|
||||||
use anyhow::{Ok, Result};
|
use anyhow::{Ok, Result};
|
||||||
use config::{keymap::{Control, Key, KeymapLayer}, BOOT};
|
use config::{keymap::{Control, Key, KeymapLayer}, BOOT};
|
||||||
|
|
@ -43,6 +42,7 @@ 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();
|
std::fs::write(p, cwd.as_bytes()).ok();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
use core::Event;
|
use core::Event;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use crossterm::event::{Event as CrosstermEvent, EventStream};
|
use crossterm::event::{Event as CrosstermEvent, EventStream, KeyEvent, KeyEventKind};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use libc::{SIGHUP, SIGINT, SIGQUIT, SIGTERM};
|
|
||||||
use tokio::{select, sync::{mpsc::{self, UnboundedReceiver, UnboundedSender}, oneshot}, task::JoinHandle};
|
use tokio::{select, sync::{mpsc::{self, UnboundedReceiver, UnboundedSender}, oneshot}, task::JoinHandle};
|
||||||
|
|
||||||
pub(super) struct Signals {
|
pub(super) struct Signals {
|
||||||
|
|
@ -46,7 +45,13 @@ impl Signals {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
fn spawn_system_task(&self) -> Result<()> { Ok(()) }
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
fn spawn_system_task(&self) -> Result<JoinHandle<()>> {
|
fn spawn_system_task(&self) -> Result<JoinHandle<()>> {
|
||||||
|
use libc::{SIGHUP, SIGINT, SIGQUIT, SIGTERM};
|
||||||
|
|
||||||
let tx = self.tx.clone();
|
let tx = self.tx.clone();
|
||||||
let mut signals = signal_hook_tokio::Signals::new([SIGHUP, SIGTERM, SIGINT, SIGQUIT])?;
|
let mut signals = signal_hook_tokio::Signals::new([SIGHUP, SIGTERM, SIGINT, SIGQUIT])?;
|
||||||
|
|
||||||
|
|
@ -76,7 +81,9 @@ impl Signals {
|
||||||
_ = &mut stop_rx => break,
|
_ = &mut stop_rx => break,
|
||||||
Some(Ok(event)) = reader.next() => {
|
Some(Ok(event)) = reader.next() => {
|
||||||
let event = match event {
|
let event = match event {
|
||||||
CrosstermEvent::Key(key) => Event::Key(key),
|
// We need to check key event kind;
|
||||||
|
// otherwise event will be dispatched twice.
|
||||||
|
CrosstermEvent::Key(key @ KeyEvent { kind: KeyEventKind::Press, .. }) => Event::Key(key),
|
||||||
CrosstermEvent::Paste(str) => Event::Paste(str),
|
CrosstermEvent::Paste(str) => Event::Paste(str),
|
||||||
CrosstermEvent::Resize(cols, rows) => Event::Resize(cols, rows),
|
CrosstermEvent::Resize(cols, rows) => Event::Resize(cols, rows),
|
||||||
_ => continue,
|
_ => continue,
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,5 @@
|
||||||
use std::os::unix::prelude::PermissionsExt;
|
|
||||||
|
|
||||||
use config::THEME;
|
use config::THEME;
|
||||||
use ratatui::{buffer::Buffer, layout::{Alignment, Rect}, text::{Line, Span}, widgets::{Paragraph, Widget}};
|
use ratatui::{buffer::Buffer, layout::{Alignment, Rect}, text::{Line, Span}, widgets::{Paragraph, Widget}};
|
||||||
use shared::file_mode;
|
|
||||||
|
|
||||||
use super::Progress;
|
use super::Progress;
|
||||||
use crate::Ctx;
|
use crate::Ctx;
|
||||||
|
|
@ -70,8 +67,10 @@ impl Widget for Right<'_> {
|
||||||
let mut spans = vec![];
|
let mut spans = vec![];
|
||||||
|
|
||||||
// Permissions
|
// Permissions
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
if let Some(h) = &manager.hovered {
|
if let Some(h) = &manager.hovered {
|
||||||
spans.extend(self.permissions(&file_mode(h.meta.permissions().mode())))
|
use std::os::unix::prelude::PermissionsExt;
|
||||||
|
spans.extend(self.permissions(&shared::file_mode(h.meta.permissions().mode())))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Position
|
// Position
|
||||||
|
|
|
||||||
23
config/src/dir.rs
Normal file
23
config/src/dir.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
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())
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
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;
|
||||||
|
|
|
||||||
|
|
@ -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::tty_size;
|
|
||||||
|
|
||||||
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 { tty_size().ws_row.saturating_sub(DIR_PADDING) as usize }
|
pub fn limit() -> usize { size().unwrap_or_default().1.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 = tty_size();
|
let s = size().unwrap_or_default();
|
||||||
|
|
||||||
Some(Rect {
|
Some(Rect {
|
||||||
x: (s.ws_col as u32 * PARENT_RATIO / ALL_RATIO) as u16,
|
x: (s.0 as u32 * PARENT_RATIO / ALL_RATIO) as u16,
|
||||||
y: pos as u16,
|
y: pos as u16,
|
||||||
width: (s.ws_col as u32 * CURRENT_RATIO / ALL_RATIO) as u16,
|
width: (s.0 as u32 * CURRENT_RATIO / ALL_RATIO) as u16,
|
||||||
height: 1,
|
height: 1,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,16 @@ impl File {
|
||||||
|
|
||||||
match fs::remove_file(&task.to).await {
|
match fs::remove_file(&task.to).await {
|
||||||
Err(e) if e.kind() != NotFound => Err(e)?,
|
Err(e) if e.kind() != NotFound => Err(e)?,
|
||||||
_ => fs::symlink(src, &task.to).await?,
|
_ => {
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
{
|
||||||
|
fs::symlink_file(src, &task.to).await?
|
||||||
|
}
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
{
|
||||||
|
fs::symlink(src, &task.to).await?
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if task.cut {
|
if task.cut {
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,10 @@ 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
|
||||||
#[allow(clippy::collapsible_else_if)]
|
#[allow(clippy::collapsible_else_if)]
|
||||||
pub fn file_mode(mode: u32) -> String {
|
pub fn file_mode(mode: u32) -> String {
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,10 @@
|
||||||
use libc::{ioctl, winsize, STDOUT_FILENO, TIOCGWINSZ};
|
use crossterm::terminal::window_size;
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn tty_size() -> winsize {
|
|
||||||
unsafe {
|
|
||||||
let s: winsize = std::mem::zeroed();
|
|
||||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &s);
|
|
||||||
s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn tty_ratio() -> (f64, f64) {
|
pub fn tty_ratio() -> (f64, f64) {
|
||||||
let s = tty_size();
|
if let Ok(ws) = window_size() {
|
||||||
(f64::from(s.ws_xpixel) / f64::from(s.ws_col), f64::from(s.ws_ypixel) / f64::from(s.ws_row))
|
(f64::from(ws.width) / f64::from(ws.columns), f64::from(ws.height) / f64::from(ws.rows))
|
||||||
|
} else {
|
||||||
|
(1f64, 1f64)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue