yazi/yazi-tty/src/sequence/dnd.rs
三咲雅 misaki masa 2c3f174eb5
Some checks failed
Cachix / Publish Flake (push) Has been cancelled
Check / clippy (push) Has been cancelled
Check / rustfmt (push) Has been cancelled
Check / stylua (push) Has been cancelled
Draft / build-unix (gcc-aarch64-linux-gnu, ubuntu-latest, aarch64-unknown-linux-gnu) (push) Has been cancelled
Draft / build-unix (gcc-i686-linux-gnu, ubuntu-latest, i686-unknown-linux-gnu) (push) Has been cancelled
Draft / build-unix (gcc-riscv64-linux-gnu, ubuntu-latest, riscv64gc-unknown-linux-gnu) (push) Has been cancelled
Draft / build-unix (gcc-sparc64-linux-gnu, ubuntu-latest, sparc64-unknown-linux-gnu) (push) Has been cancelled
Draft / build-unix (macos-latest, aarch64-apple-darwin) (push) Has been cancelled
Draft / build-unix (macos-latest, x86_64-apple-darwin) (push) Has been cancelled
Draft / build-unix (ubuntu-latest, x86_64-unknown-linux-gnu) (push) Has been cancelled
Draft / build-windows (windows-latest, aarch64-pc-windows-msvc) (push) Has been cancelled
Draft / build-windows (windows-latest, x86_64-pc-windows-msvc) (push) Has been cancelled
Draft / build-musl (aarch64-unknown-linux-musl) (push) Has been cancelled
Draft / build-musl (x86_64-unknown-linux-musl) (push) Has been cancelled
Draft / build-snap (amd64, ubuntu-latest) (push) Has been cancelled
Draft / build-snap (arm64, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (macos-latest) (push) Has been cancelled
Test / test (ubuntu-latest) (push) Has been cancelled
Test / test (windows-latest) (push) Has been cancelled
Draft / snap (push) Has been cancelled
Draft / draft (push) Has been cancelled
Draft / nightly (push) Has been cancelled
feat: allow restoring trashed items recursively (#4159)
2026-07-25 11:39:19 +08:00

172 lines
4.5 KiB
Rust

use std::{fmt::{self, Display}, str};
use base64::{Engine, engine::general_purpose::STANDARD_NO_PAD_INDIFFERENT};
use super::traits::Mimelist;
/// Enable drag support: `OSC 72 ; t=o:x=1 ; machine id ST`
pub struct EnableDrag<'a>(pub &'a str);
impl Display for EnableDrag<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "\x1b]72;t=o:x=1;{}\x1b\\", self.0)
}
}
/// Enable drop support: `OSC 72 ; t=a ; MIME list ST`
pub struct EnableDrop<M>(pub M);
impl<M: Mimelist> Display for EnableDrop<M> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "\x1b]72;t=a;{}\x1b\\", ListDndMimes(self.0.clone()))
}
}
/// Disable drag support: `OSC 72 ; t=o:x=2 ST`
pub struct DisableDrag;
impl Display for DisableDrag {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("\x1b]72;t=o:x=2\x1b\\") }
}
/// Disable drop support: `OSC 72 ; t=A ST`
pub struct DisableDrop;
impl Display for DisableDrop {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("\x1b]72;t=A\x1b\\") }
}
/// Agree drag: `OSC 72 ; t=o:o=operation ST`
pub enum AgreeDrag<M> {
Copy(M),
Move(M),
Either(M),
}
impl<M: Mimelist> Display for AgreeDrag<M> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Copy(mimes) => write!(f, "\x1b]72;t=o:o=1;{}\x1b\\", ListDndMimes(mimes.clone())),
Self::Move(mimes) => write!(f, "\x1b]72;t=o:o=2;{}\x1b\\", ListDndMimes(mimes.clone())),
Self::Either(mimes) => write!(f, "\x1b]72;t=o:o=3;{}\x1b\\", ListDndMimes(mimes.clone())),
}
}
}
/// Agree drop: `OSC 72 ; t=m:o=O ; MIME list ST`
pub enum AgreeDrop<M> {
Reject,
Copy(M),
Move(M),
}
impl<M: Mimelist> Display for AgreeDrop<M> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Reject => write!(f, "\x1b]72;t=m:o=0\x1b\\"),
Self::Copy(mimes) => write!(f, "\x1b]72;t=m:o=1;{}\x1b\\", ListDndMimes(mimes.clone())),
Self::Move(mimes) => write!(f, "\x1b]72;t=m:o=2;{}\x1b\\", ListDndMimes(mimes.clone())),
}
}
}
/// Start dragging: `OSC 72 ; t=P:x=-1 ST`
pub struct StartDrag;
impl Display for StartDrag {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("\x1b]72;t=P:x=-1\x1b\\") }
}
/// Start requesting dropped data: `OSC 72 ; t=r:x=idx ST`
pub struct StartDrop(pub u8);
impl Display for StartDrop {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "\x1b]72;t=r:x={}\x1b\\", self.0)
}
}
/// Present drag data: `OSC 72 ; t=p:x=idx ; base64 encoded data ST`
pub struct PresentDrag<'a>(pub u8, pub &'a [u8]);
impl Display for PresentDrag<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let b64 = STANDARD_NO_PAD_INDIFFERENT.encode(self.1).into_bytes();
let chunks = b64.len().div_ceil(4096);
for (i, chunk) in b64.chunks(4096).enumerate() {
let s = unsafe { str::from_utf8_unchecked(chunk) };
if i == 0 {
write!(f, "\x1b]72;t=p:x={}:m={};{s}\x1b\\", self.0, (chunks > 1) as u8)?;
} else {
write!(f, "\x1b]72;m={};{s}\x1b\\", (i + 1 < chunks) as u8)?;
}
}
write!(f, "\x1b]72;t=p:x={}\x1b\\", self.0)
}
}
/// Present drag icon data:
/// `OSC 72 ; t=p:x=-1:y=fmt:X=width:Y=height:o=opacity ; base64 payload ST`
pub struct PresentDragIcon<'a> {
pub format: u8,
pub opacity: u16,
pub width: u32,
pub height: u32,
pub data: &'a [u8],
}
impl Display for PresentDragIcon<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let b64 = STANDARD_NO_PAD_INDIFFERENT.encode(self.data).into_bytes();
let chunks = b64.len().div_ceil(4096);
for (i, chunk) in b64.chunks(4096).enumerate() {
let s = unsafe { str::from_utf8_unchecked(chunk) };
if i == 0 {
write!(
f,
"\x1b]72;t=p:x=-1:y={}:X={}:Y={}:o={}:m={};{s}\x1b\\",
self.format,
self.width,
self.height,
self.opacity,
(chunks > 1) as u8
)?;
} else {
write!(f, "\x1b]72;m={};{s}\x1b\\", (i + 1 < chunks) as u8)?;
}
}
Ok(())
}
}
/// Finish requesting dropped data: `OSC 72 ; t=r:o=operation ST`
#[derive(Clone, Copy)]
pub enum FinishDrop {
Copy = 1,
Move = 2,
}
impl Display for FinishDrop {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "\x1b]72;t=r:o={}\x1b\\", *self as u8)
}
}
/// Write MIME types separated by spaces.
struct ListDndMimes<M>(pub M);
impl<M: Mimelist> Display for ListDndMimes<M> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for (i, m) in self.0.clone().into_iter().enumerate() {
if i != 0 {
write!(f, " ")?;
}
write!(f, "{m}")?;
}
Ok(())
}
}