feat: support Super/Command/Windows key notation D- (#1069)

This commit is contained in:
三咲雅 · Misaki Masa 2024-05-22 13:11:23 +08:00 committed by GitHub
parent f41e3c8d8b
commit d9ecffd19e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 24 additions and 21 deletions

View file

@ -1,7 +1,7 @@
use std::{io::Write, path::Path}; use std::{io::Write, path::Path};
use anyhow::Result; use anyhow::Result;
use base64::{engine::general_purpose, Engine}; use base64::{engine::{general_purpose::STANDARD, Config}, Engine};
use image::{codecs::jpeg::JpegEncoder, DynamicImage}; use image::{codecs::jpeg::JpegEncoder, DynamicImage};
use ratatui::layout::Rect; use ratatui::layout::Rect;
use yazi_shared::term::Term; use yazi_shared::term::Term;
@ -38,20 +38,20 @@ impl Iterm2 {
async fn encode(img: DynamicImage) -> Result<Vec<u8>> { async fn encode(img: DynamicImage) -> Result<Vec<u8>> {
tokio::task::spawn_blocking(move || { tokio::task::spawn_blocking(move || {
let size = (img.width(), img.height());
let mut jpg = vec![]; let mut jpg = vec![];
JpegEncoder::new_with_quality(&mut jpg, 75).encode_image(&img)?; JpegEncoder::new_with_quality(&mut jpg, 75).encode_image(&img)?;
let mut buf = vec![]; let len = base64::encoded_len(jpg.len(), STANDARD.config().encode_padding());
let mut buf = Vec::with_capacity(200 + len.unwrap_or(1 << 16));
write!( write!(
buf, buf,
"{}]1337;File=inline=1;size={};width={}px;height={}px;doNotMoveCursor=1:{}\x07{}", "{}]1337;File=inline=1;size={};width={}px;height={}px;doNotMoveCursor=1:{}\x07{}",
START, START,
jpg.len(), jpg.len(),
size.0, img.width(),
size.1, img.height(),
general_purpose::STANDARD.encode(&jpg), STANDARD.encode(&jpg),
CLOSE CLOSE
)?; )?;
Ok(buf) Ok(buf)

View file

@ -7,29 +7,27 @@ use serde::Deserialize;
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Hash)] #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Hash)]
#[serde(try_from = "String")] #[serde(try_from = "String")]
pub struct Key { pub struct Key {
pub code: KeyCode, pub code: KeyCode,
pub shift: bool, pub shift: bool,
pub ctrl: bool, pub ctrl: bool,
pub alt: bool, pub alt: bool,
pub super_: bool,
} }
impl Key { impl Key {
#[inline] #[inline]
pub fn plain(&self) -> Option<char> { pub fn plain(&self) -> Option<char> {
match self.code { match self.code {
KeyCode::Char(c) if !self.ctrl && !self.alt => Some(c), KeyCode::Char(c) if !self.ctrl && !self.alt && !self.super_ => Some(c),
_ => None, _ => None,
} }
} }
#[inline]
pub fn is_enter(&self) -> bool {
matches!(self, Key { code: KeyCode::Enter, shift: false, ctrl: false, alt: false })
}
} }
impl Default for Key { impl Default for Key {
fn default() -> Self { Self { code: KeyCode::Null, shift: false, ctrl: false, alt: false } } fn default() -> Self {
Self { code: KeyCode::Null, shift: false, ctrl: false, alt: false, super_: false }
}
} }
impl From<KeyEvent> for Key { impl From<KeyEvent> for Key {
@ -56,6 +54,7 @@ impl From<KeyEvent> for Key {
shift, shift,
ctrl: value.modifiers.contains(KeyModifiers::CONTROL), ctrl: value.modifiers.contains(KeyModifiers::CONTROL),
alt: value.modifiers.contains(KeyModifiers::ALT), alt: value.modifiers.contains(KeyModifiers::ALT),
super_: value.modifiers.contains(KeyModifiers::SUPER),
} }
} }
} }
@ -82,6 +81,7 @@ impl FromStr for Key {
"S-" => key.shift = true, "S-" => key.shift = true,
"C-" => key.ctrl = true, "C-" => key.ctrl = true,
"A-" => key.alt = true, "A-" => key.alt = true,
"D-" => key.super_ = true,
"Space" => key.code = KeyCode::Char(' '), "Space" => key.code = KeyCode::Char(' '),
"Backspace" => key.code = KeyCode::Backspace, "Backspace" => key.code = KeyCode::Backspace,
@ -140,6 +140,9 @@ impl Display for Key {
} }
write!(f, "<")?; write!(f, "<")?;
if self.super_ {
write!(f, "D-")?;
}
if self.ctrl { if self.ctrl {
write!(f, "C-")?; write!(f, "C-")?;
} }

View file

@ -43,15 +43,15 @@ impl Help {
}; };
match key { match key {
Key { code: KeyCode::Esc, shift: false, ctrl: false, alt: false } => { Key { code: KeyCode::Esc, shift: false, ctrl: false, alt: false, super_: false } => {
self.in_filter = None; self.in_filter = None;
render!(); render!();
} }
Key { code: KeyCode::Enter, shift: false, ctrl: false, alt: false } => { Key { code: KeyCode::Enter, shift: false, ctrl: false, alt: false, super_: false } => {
self.in_filter = None; self.in_filter = None;
return render_and!(true); // Don't do the `filter_apply` below, since we already have the filtered results. return render_and!(true); // Don't do the `filter_apply` below, since we already have the filtered results.
} }
Key { code: KeyCode::Backspace, shift: false, ctrl: false, alt: false } => { Key { code: KeyCode::Backspace, shift: false, ctrl: false, alt: false, super_: false } => {
input.backspace(false); input.backspace(false);
} }
_ => { _ => {