mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: yazi --debug supports detecting whether tmux is built with --enable-sixel (#1762)
This commit is contained in:
parent
2014aee646
commit
c84917c5e8
6 changed files with 83 additions and 40 deletions
|
|
@ -7,7 +7,7 @@ use tokio::{io::{AsyncReadExt, BufReader}, time::timeout};
|
||||||
use tracing::{error, warn};
|
use tracing::{error, warn};
|
||||||
use yazi_shared::env_exists;
|
use yazi_shared::env_exists;
|
||||||
|
|
||||||
use crate::{Adapter, TMUX, tcsi};
|
use crate::{Adapter, Mux, TMUX};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Emulator {
|
pub enum Emulator {
|
||||||
|
|
@ -103,24 +103,11 @@ impl Emulator {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn via_env() -> (String, String) {
|
pub fn via_env() -> (String, String) {
|
||||||
fn tmux_env(name: &str) -> Option<String> {
|
let (term, program) = Mux::term_program();
|
||||||
String::from_utf8_lossy(
|
(
|
||||||
&std::process::Command::new("tmux").args(["show-environment", name]).output().ok()?.stdout,
|
term.unwrap_or(std::env::var("TERM").unwrap_or_default()),
|
||||||
)
|
program.unwrap_or(std::env::var("TERM_PROGRAM").unwrap_or_default()),
|
||||||
.trim()
|
)
|
||||||
.strip_prefix(&format!("{name}="))
|
|
||||||
.map(ToOwned::to_owned)
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut term = std::env::var("TERM").unwrap_or_default();
|
|
||||||
let mut program = std::env::var("TERM_PROGRAM").unwrap_or_default();
|
|
||||||
|
|
||||||
if *TMUX {
|
|
||||||
term = tmux_env("TERM").unwrap_or(term);
|
|
||||||
program = tmux_env("TERM_PROGRAM").unwrap_or(program);
|
|
||||||
}
|
|
||||||
|
|
||||||
(term, program)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn via_csi() -> Result<Self> {
|
pub fn via_csi() -> Result<Self> {
|
||||||
|
|
@ -130,7 +117,7 @@ impl Emulator {
|
||||||
execute!(
|
execute!(
|
||||||
LineWriter::new(stderr()),
|
LineWriter::new(stderr()),
|
||||||
SavePosition,
|
SavePosition,
|
||||||
Print(tcsi("\x1b[>q\x1b_Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA\x1b\\\x1b[c")),
|
Print(Mux::csi("\x1b[>q\x1b_Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA\x1b\\\x1b[c")),
|
||||||
RestorePosition
|
RestorePosition
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ mod iip;
|
||||||
mod image;
|
mod image;
|
||||||
mod kgp;
|
mod kgp;
|
||||||
mod kgp_old;
|
mod kgp_old;
|
||||||
|
mod mux;
|
||||||
mod sixel;
|
mod sixel;
|
||||||
mod ueberzug;
|
mod ueberzug;
|
||||||
|
|
||||||
|
|
@ -18,6 +19,7 @@ pub use emulator::*;
|
||||||
use iip::*;
|
use iip::*;
|
||||||
use kgp::*;
|
use kgp::*;
|
||||||
use kgp_old::*;
|
use kgp_old::*;
|
||||||
|
pub use mux::*;
|
||||||
use sixel::*;
|
use sixel::*;
|
||||||
use ueberzug::*;
|
use ueberzug::*;
|
||||||
use yazi_shared::{RoCell, env_exists, in_wsl};
|
use yazi_shared::{RoCell, env_exists, in_wsl};
|
||||||
|
|
@ -63,16 +65,3 @@ pub fn init() {
|
||||||
ADAPTOR.init(Adapter::matches());
|
ADAPTOR.init(Adapter::matches());
|
||||||
ADAPTOR.start();
|
ADAPTOR.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tcsi(s: &str) -> std::borrow::Cow<str> {
|
|
||||||
if *TMUX {
|
|
||||||
std::borrow::Cow::Owned(format!(
|
|
||||||
"{}{}{}",
|
|
||||||
*START,
|
|
||||||
s.trim_start_matches('\x1b').replace('\x1b', *ESCAPE),
|
|
||||||
*CLOSE
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
std::borrow::Cow::Borrowed(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
56
yazi-adapter/src/mux.rs
Normal file
56
yazi-adapter/src/mux.rs
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
use crate::{CLOSE, ESCAPE, START, TMUX};
|
||||||
|
|
||||||
|
pub struct Mux;
|
||||||
|
|
||||||
|
impl Mux {
|
||||||
|
pub fn csi(s: &str) -> std::borrow::Cow<str> {
|
||||||
|
if *TMUX {
|
||||||
|
std::borrow::Cow::Owned(format!(
|
||||||
|
"{}{}{}",
|
||||||
|
*START,
|
||||||
|
s.trim_start_matches('\x1b').replace('\x1b', *ESCAPE),
|
||||||
|
*CLOSE
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
std::borrow::Cow::Borrowed(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tmux_sixel_flag() -> &'static str {
|
||||||
|
let stdout = std::process::Command::new("tmux")
|
||||||
|
.args(["-LwU0dju1is5", "-f/dev/null", "start", ";", "display", "-p", "#{sixel_support}"])
|
||||||
|
.output()
|
||||||
|
.ok()
|
||||||
|
.and_then(|o| String::from_utf8(o.stdout).ok())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
match stdout.trim() {
|
||||||
|
"1" => "Supported",
|
||||||
|
"0" => "Unsupported",
|
||||||
|
_ => "Unknown",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn term_program() -> (Option<String>, Option<String>) {
|
||||||
|
let (mut term, mut program) = (None, None);
|
||||||
|
if !*TMUX {
|
||||||
|
return (term, program);
|
||||||
|
}
|
||||||
|
let Ok(output) = std::process::Command::new("tmux").arg("show-environment").output() else {
|
||||||
|
return (term, program);
|
||||||
|
};
|
||||||
|
for line in String::from_utf8_lossy(&output.stdout).lines() {
|
||||||
|
if let Some((k, v)) = line.trim().split_once('=') {
|
||||||
|
match k {
|
||||||
|
"TERM" => term = Some(v.to_owned()),
|
||||||
|
"TERM_PROGRAM" => program = Some(v.to_owned()),
|
||||||
|
_ => continue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if term.is_some() && program.is_some() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(term, program)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use std::{env, ffi::OsStr, fmt::Write};
|
use std::{env, ffi::OsStr, fmt::Write};
|
||||||
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
use yazi_adapter::Mux;
|
||||||
use yazi_shared::Xdg;
|
use yazi_shared::Xdg;
|
||||||
|
|
||||||
use super::Actions;
|
use super::Actions;
|
||||||
|
|
@ -51,14 +52,24 @@ impl Actions {
|
||||||
writeln!(s, "\nText Opener")?;
|
writeln!(s, "\nText Opener")?;
|
||||||
writeln!(
|
writeln!(
|
||||||
s,
|
s,
|
||||||
" default: {:?}",
|
" default : {:?}",
|
||||||
yazi_config::OPEN.openers("f75a.txt", "text/plain").and_then(|a| a.first().cloned())
|
yazi_config::OPEN.openers("f75a.txt", "text/plain").and_then(|a| a.first().cloned())
|
||||||
)?;
|
)?;
|
||||||
writeln!(s, " block : {:?}", yazi_config::OPEN.block_opener("bulk.txt", "text/plain"))?;
|
writeln!(
|
||||||
|
s,
|
||||||
|
" block-create: {:?}",
|
||||||
|
yazi_config::OPEN.block_opener("bulk-create.txt", "text/plain")
|
||||||
|
)?;
|
||||||
|
writeln!(
|
||||||
|
s,
|
||||||
|
" block-rename: {:?}",
|
||||||
|
yazi_config::OPEN.block_opener("bulk-rename.txt", "text/plain")
|
||||||
|
)?;
|
||||||
|
|
||||||
writeln!(s, "\nMultiplexers")?;
|
writeln!(s, "\nMultiplexers")?;
|
||||||
writeln!(s, " TMUX : {:?}", *yazi_adapter::TMUX)?;
|
writeln!(s, " TMUX : {:?}", *yazi_adapter::TMUX)?;
|
||||||
writeln!(s, " tmux version : {}", Self::process_output("tmux", "-V"))?;
|
writeln!(s, " tmux version : {}", Self::process_output("tmux", "-V"))?;
|
||||||
|
writeln!(s, " tmux build flags : enable-sixel={}", Mux::tmux_sixel_flag())?;
|
||||||
writeln!(s, " ZELLIJ_SESSION_NAME: {:?}", env::var_os("ZELLIJ_SESSION_NAME"))?;
|
writeln!(s, " ZELLIJ_SESSION_NAME: {:?}", env::var_os("ZELLIJ_SESSION_NAME"))?;
|
||||||
writeln!(s, " Zellij version : {}", Self::process_output("zellij", "--version"))?;
|
writeln!(s, " Zellij version : {}", Self::process_output("zellij", "--version"))?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use crate::manager::Manager;
|
||||||
|
|
||||||
impl Manager {
|
impl Manager {
|
||||||
pub(super) fn bulk_rename(&self) {
|
pub(super) fn bulk_rename(&self) {
|
||||||
let Some(opener) = OPEN.block_opener("bulk.txt", "text/plain") else {
|
let Some(opener) = OPEN.block_opener("bulk-rename.txt", "text/plain") else {
|
||||||
return AppProxy::notify_warn("Bulk rename", "No text opener found");
|
return AppProxy::notify_warn("Bulk rename", "No text opener found");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use anyhow::Result;
|
||||||
use crossterm::{event::{DisableBracketedPaste, EnableBracketedPaste, KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags}, execute, queue, style::Print, terminal::{EnterAlternateScreen, LeaveAlternateScreen, SetTitle, disable_raw_mode, enable_raw_mode}};
|
use crossterm::{event::{DisableBracketedPaste, EnableBracketedPaste, KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags}, execute, queue, style::Print, terminal::{EnterAlternateScreen, LeaveAlternateScreen, SetTitle, disable_raw_mode, enable_raw_mode}};
|
||||||
use cursor::RestoreCursor;
|
use cursor::RestoreCursor;
|
||||||
use ratatui::{CompletedFrame, Frame, Terminal, backend::CrosstermBackend, buffer::Buffer, layout::Rect};
|
use ratatui::{CompletedFrame, Frame, Terminal, backend::CrosstermBackend, buffer::Buffer, layout::Rect};
|
||||||
use yazi_adapter::{Emulator, tcsi};
|
use yazi_adapter::{Emulator, Mux};
|
||||||
use yazi_config::{INPUT, MANAGER};
|
use yazi_config::{INPUT, MANAGER};
|
||||||
|
|
||||||
static CSI_U: AtomicBool = AtomicBool::new(false);
|
static CSI_U: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
@ -28,9 +28,9 @@ impl Term {
|
||||||
enable_raw_mode()?;
|
enable_raw_mode()?;
|
||||||
execute!(
|
execute!(
|
||||||
BufWriter::new(stderr()),
|
BufWriter::new(stderr()),
|
||||||
Print(tcsi("\x1b[?12$p")), // Request cursor blink status (DECSET)
|
Print(Mux::csi("\x1b[?12$p")), // Request cursor blink status (DECSET)
|
||||||
Print(tcsi("\x1bP$q q\x1b\\")), // Request cursor shape (DECRQM)
|
Print(Mux::csi("\x1bP$q q\x1b\\")), // Request cursor shape (DECRQM)
|
||||||
Print(tcsi("\x1b[?u\x1b[c")), // Request keyboard enhancement flags (CSI u)
|
Print(Mux::csi("\x1b[?u\x1b[c")), // Request keyboard enhancement flags (CSI u)
|
||||||
EnterAlternateScreen,
|
EnterAlternateScreen,
|
||||||
EnableBracketedPaste,
|
EnableBracketedPaste,
|
||||||
mouse::SetMouse(true),
|
mouse::SetMouse(true),
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue