mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
up
This commit is contained in:
parent
5c69beb104
commit
83cbef649d
11 changed files with 103 additions and 43 deletions
24
Cargo.lock
generated
24
Cargo.lock
generated
|
|
@ -382,9 +382,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.8.1"
|
version = "1.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
|
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
|
|
@ -665,15 +665,6 @@ version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
|
checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "home"
|
|
||||||
version = "0.5.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb"
|
|
||||||
dependencies = [
|
|
||||||
"windows-sys 0.48.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http"
|
name = "http"
|
||||||
version = "0.2.9"
|
version = "0.2.9"
|
||||||
|
|
@ -1334,9 +1325,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.31"
|
version = "1.0.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0"
|
checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
@ -2358,12 +2349,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xdg"
|
name = "xdg"
|
||||||
version = "2.5.0"
|
version = "2.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "688597db5a750e9cad4511cb94729a078e274308099a0382b5b8203bbc767fee"
|
checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546"
|
||||||
dependencies = [
|
|
||||||
"home",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yaml-rust"
|
name = "yaml-rust"
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,25 @@ impl From<&str> for Exec {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToString for Exec {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
let mut s = self.cmd.clone();
|
||||||
|
for arg in &self.args {
|
||||||
|
s.push(' ');
|
||||||
|
s.push_str(arg);
|
||||||
|
}
|
||||||
|
for (name, value) in &self.named {
|
||||||
|
s.push_str(" --");
|
||||||
|
s.push_str(name);
|
||||||
|
if !value.is_empty() {
|
||||||
|
s.push('=');
|
||||||
|
s.push_str(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Exec {
|
impl Exec {
|
||||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<Exec>, D::Error>
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<Exec>, D::Error>
|
||||||
where
|
where
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,8 @@ impl TryFrom<String> for Key {
|
||||||
impl ToString for Key {
|
impl ToString for Key {
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
if let Some(c) = self.plain() {
|
if let Some(c) = self.plain() {
|
||||||
return if self.shift { c.to_ascii_uppercase() } else { c }.to_string();
|
let c = if self.shift { c.to_ascii_uppercase() } else { c };
|
||||||
|
return if c == ' ' { "<Space>".to_string() } else { c.to_string() };
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut s = "<".to_string();
|
let mut s = "<".to_string();
|
||||||
|
|
@ -149,6 +150,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(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 });
|
||||||
""
|
""
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,8 @@ pub struct Theme {
|
||||||
impl Theme {
|
impl Theme {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> 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 = absolute_path(&theme.preview.syntect_theme);
|
theme.preview.syntect_theme =
|
||||||
|
futures::executor::block_on(absolute_path(&theme.preview.syntect_theme));
|
||||||
theme
|
theme
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{collections::{BTreeMap, BTreeSet, HashMap, HashSet}, mem, path::PathBuf};
|
use std::{collections::{BTreeMap, BTreeSet, HashMap, HashSet}, env, mem, path::PathBuf};
|
||||||
|
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
|
|
||||||
|
|
@ -25,6 +25,8 @@ impl Manager {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn refresh(&mut self) {
|
pub fn refresh(&mut self) {
|
||||||
|
env::set_current_dir(&self.current().cwd).ok();
|
||||||
|
|
||||||
self.watcher.trigger(&self.current().cwd);
|
self.watcher.trigger(&self.current().cwd);
|
||||||
if let Some(p) = self.parent() {
|
if let Some(p) = self.parent() {
|
||||||
self.watcher.trigger(&p.cwd);
|
self.watcher.trigger(&p.cwd);
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,9 @@ impl Which {
|
||||||
} else if self.cands.len() == 1 {
|
} else if self.cands.len() == 1 {
|
||||||
self.visible = false;
|
self.visible = false;
|
||||||
emit!(Ctrl(self.cands.remove(0), self.layer));
|
emit!(Ctrl(self.cands.remove(0), self.layer));
|
||||||
|
} else if let Some(i) = self.cands.iter().position(|c| c.on.len() == self.times + 1) {
|
||||||
|
emit!(Ctrl(self.cands.remove(i), self.layer));
|
||||||
|
self.visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.times += 1;
|
self.times += 1;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@ use std::{env, path::{Path, PathBuf}};
|
||||||
|
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
|
|
||||||
pub fn absolute_path(p: &Path) -> PathBuf {
|
pub async fn absolute_path(p: impl AsRef<Path>) -> PathBuf {
|
||||||
|
let p = p.as_ref();
|
||||||
if p.starts_with("~") {
|
if p.starts_with("~") {
|
||||||
if let Ok(home) = env::var("HOME") {
|
if let Ok(home) = env::var("HOME") {
|
||||||
let mut expanded = PathBuf::new();
|
let mut expanded = PathBuf::new();
|
||||||
|
|
@ -11,7 +12,7 @@ pub fn absolute_path(p: &Path) -> PathBuf {
|
||||||
return expanded;
|
return expanded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.to_path_buf()
|
fs::canonicalize(p).await.unwrap_or_else(|_| p.to_path_buf())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn readable_path(p: &Path, base: &Path) -> String {
|
pub fn readable_path(p: &Path, base: &Path) -> String {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use crossterm::event::KeyEvent;
|
||||||
use tokio::sync::oneshot::{self};
|
use tokio::sync::oneshot::{self};
|
||||||
|
|
||||||
use super::{root::Root, Ctx, Executor, Logs, Signals, Term};
|
use super::{root::Root, Ctx, Executor, Logs, Signals, Term};
|
||||||
use crate::{config::keymap::{Control, Key, KeymapLayer}, core::{files::FilesOp, Event}, emit};
|
use crate::{config::keymap::{Control, Key, KeymapLayer}, core::{files::FilesOp, Event}, emit, misc::absolute_path};
|
||||||
|
|
||||||
pub struct App {
|
pub struct App {
|
||||||
cx: Ctx,
|
cx: Ctx,
|
||||||
|
|
@ -84,7 +84,7 @@ impl App {
|
||||||
let tasks = &mut self.cx.tasks;
|
let tasks = &mut self.cx.tasks;
|
||||||
match event {
|
match event {
|
||||||
Event::Cd(path) => {
|
Event::Cd(path) => {
|
||||||
manager.active_mut().cd(path).await;
|
manager.active_mut().cd(absolute_path(path).await).await;
|
||||||
}
|
}
|
||||||
Event::Refresh => {
|
Event::Refresh => {
|
||||||
manager.refresh();
|
manager.refresh();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use super::Ctx;
|
use super::Ctx;
|
||||||
use crate::{config::{keymap::{Control, Exec, Key, KeymapLayer}, KEYMAP}, core::input::InputMode, misc::optional_bool};
|
use crate::{config::{keymap::{Control, Exec, Key, KeymapLayer}, KEYMAP}, core::input::InputMode, emit, misc::optional_bool};
|
||||||
|
|
||||||
pub struct Executor;
|
pub struct Executor;
|
||||||
|
|
||||||
|
|
@ -60,6 +62,11 @@ impl Executor {
|
||||||
"enter" => cx.manager.active_mut().enter(),
|
"enter" => cx.manager.active_mut().enter(),
|
||||||
"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" => {
|
||||||
|
let path = exec.args.get(0).map(|s| PathBuf::from(s)).unwrap_or_default();
|
||||||
|
emit!(Cd(path));
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
// Selection
|
// Selection
|
||||||
"select" => {
|
"select" => {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use ratatui::{layout, prelude::{Buffer, Constraint, Direction, Rect}, widgets::Widget};
|
use ratatui::{layout, prelude::{Buffer, Constraint, Direction, Rect}, widgets::{Clear, Widget}};
|
||||||
|
|
||||||
use super::Side;
|
use super::Side;
|
||||||
use crate::ui::Ctx;
|
use crate::ui::Ctx;
|
||||||
|
|
@ -13,20 +13,35 @@ impl<'a> Which<'a> {
|
||||||
|
|
||||||
impl Widget for Which<'_> {
|
impl Widget for Which<'_> {
|
||||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||||
let chunks = layout::Layout::default()
|
let which = &self.cx.which;
|
||||||
.direction(Direction::Vertical)
|
let mut cands: (Vec<_>, Vec<_>, Vec<_>) = Default::default();
|
||||||
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
|
for (i, c) in which.cands.iter().enumerate() {
|
||||||
.split(area);
|
match i % 3 {
|
||||||
|
0 => cands.0.push(c),
|
||||||
|
1 => cands.1.push(c),
|
||||||
|
2 => cands.2.push(c),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let height = cands.0.len() as u16 + 2;
|
||||||
|
let area = Rect {
|
||||||
|
x: 1,
|
||||||
|
y: area.height.saturating_sub(height + 2),
|
||||||
|
width: area.width.saturating_sub(2),
|
||||||
|
height,
|
||||||
|
};
|
||||||
|
|
||||||
let chunks = layout::Layout::default()
|
let chunks = layout::Layout::default()
|
||||||
.direction(Direction::Horizontal)
|
.direction(Direction::Horizontal)
|
||||||
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
|
.constraints(
|
||||||
.split(chunks[1]);
|
[Constraint::Ratio(1, 3), Constraint::Ratio(1, 3), Constraint::Ratio(1, 3)].as_ref(),
|
||||||
|
)
|
||||||
let which = &self.cx.which;
|
.split(area);
|
||||||
let cands: (Vec<_>, Vec<_>) = which.cands.iter().enumerate().partition(|(i, _)| i % 2 == 0);
|
|
||||||
|
|
||||||
|
Clear.render(area, buf);
|
||||||
Side::new(which.times, cands.0).render(chunks[0], buf);
|
Side::new(which.times, cands.0).render(chunks[0], buf);
|
||||||
Side::new(which.times, cands.1).render(chunks[1], buf);
|
Side::new(which.times, cands.1).render(chunks[1], buf);
|
||||||
|
Side::new(which.times, cands.2).render(chunks[2], buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
use ratatui::{prelude::{Buffer, Rect}, widgets::{List, ListItem, Widget}};
|
use ratatui::{prelude::{Buffer, Rect}, style::{Color, Style, Stylize}, text::{Line, Span}, widgets::{Block, List, ListItem, Padding, Widget}};
|
||||||
|
|
||||||
use crate::config::keymap::Control;
|
use crate::config::keymap::Control;
|
||||||
|
|
||||||
pub struct Side<'a> {
|
pub struct Side<'a> {
|
||||||
times: usize,
|
times: usize,
|
||||||
cands: Vec<(usize, &'a Control)>,
|
cands: Vec<&'a Control>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Side<'a> {
|
impl<'a> Side<'a> {
|
||||||
pub fn new(times: usize, cands: Vec<(usize, &'a Control)>) -> Self { Self { times, cands } }
|
pub fn new(times: usize, cands: Vec<&'a Control>) -> Self { Self { times, cands } }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Widget for Side<'_> {
|
impl Widget for Side<'_> {
|
||||||
|
|
@ -16,12 +16,34 @@ impl Widget for Side<'_> {
|
||||||
let items = self
|
let items = self
|
||||||
.cands
|
.cands
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(_, c)| {
|
.map(|c| {
|
||||||
let s = c.on[self.times..].into_iter().map(ToString::to_string).collect::<String>();
|
let mut spans = vec![];
|
||||||
ListItem::new(format!("{:?}", s))
|
|
||||||
|
// Keys
|
||||||
|
let keys = c.on[self.times..].iter().map(ToString::to_string).collect::<Vec<_>>();
|
||||||
|
spans.push(Span::raw(" ".repeat(10usize.saturating_sub(keys.join("").len()))));
|
||||||
|
spans.push(Span::styled(keys[0].clone(), Style::default().fg(Color::LightCyan)));
|
||||||
|
spans.extend(
|
||||||
|
keys
|
||||||
|
.iter()
|
||||||
|
.skip(1)
|
||||||
|
.map(|k| Span::styled(k.to_string(), Style::default().fg(Color::DarkGray))),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Separator
|
||||||
|
spans.push(Span::styled(" ".to_string(), Style::default().fg(Color::DarkGray)));
|
||||||
|
|
||||||
|
// Exec
|
||||||
|
let exec = c.exec.iter().map(ToString::to_string).collect::<Vec<_>>().join("; ");
|
||||||
|
spans.push(Span::styled(exec, Style::default().fg(Color::Magenta)));
|
||||||
|
|
||||||
|
ListItem::new(Line::from(spans))
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
List::new(items).render(area, buf);
|
List::new(items)
|
||||||
|
.block(Block::new().padding(Padding::new(0, 1, 1, 1)))
|
||||||
|
.bg(Color::Rgb(47, 51, 73))
|
||||||
|
.render(area, buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue