mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
170 lines
4.5 KiB
Rust
170 lines
4.5 KiB
Rust
use std::{fmt::{self, Display}, str};
|
|
|
|
use base64::{Engine, engine::general_purpose};
|
|
|
|
/// 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<'a>(pub &'a [&'a str]);
|
|
|
|
impl Display for EnableDrop<'_> {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "\x1b]72;t=a;{}\x1b\\", ListDndMimes(self.0))
|
|
}
|
|
}
|
|
|
|
/// 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\\") }
|
|
}
|
|
|
|
/// Confirm drag: `OSC 72 ; t=o:o=operation ST`
|
|
pub enum ConfirmDrag<'a> {
|
|
Copy(&'a [&'a str]),
|
|
Move(&'a [&'a str]),
|
|
Either(&'a [&'a str]),
|
|
}
|
|
|
|
impl Display for ConfirmDrag<'_> {
|
|
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)),
|
|
Self::Move(mimes) => write!(f, "\x1b]72;t=o:o=2;{}\x1b\\", ListDndMimes(mimes)),
|
|
Self::Either(mimes) => write!(f, "\x1b]72;t=o:o=3;{}\x1b\\", ListDndMimes(mimes)),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Confirm dropped data: `OSC 72 ; t=m:o=O ; MIME list ST`
|
|
pub enum ConfirmDrop<'a> {
|
|
Reject,
|
|
Copy(&'a [&'a str]),
|
|
Move(&'a [&'a str]),
|
|
}
|
|
|
|
impl Display for ConfirmDrop<'_> {
|
|
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)),
|
|
Self::Move(mimes) => write!(f, "\x1b]72;t=m:o=2;{}\x1b\\", ListDndMimes(mimes)),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// 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 = general_purpose::STANDARD_NO_PAD.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 payload: &'a [u8],
|
|
}
|
|
|
|
impl Display for PresentDragIcon<'_> {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let b64 = general_purpose::STANDARD_NO_PAD.encode(self.payload).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<'a>(&'a [&'a str]);
|
|
|
|
impl Display for ListDndMimes<'_> {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
for (i, &m) in self.0.iter().enumerate() {
|
|
if i != 0 {
|
|
write!(f, " ")?;
|
|
}
|
|
write!(f, "{m}")?;
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|