Skip to content

Commit b10f2de

Browse files
committed
feat: add --debug flag to print debug information (#794)
1 parent 9396d87 commit b10f2de

File tree

9 files changed

+299
-211
lines changed

9 files changed

+299
-211
lines changed

Diff for: .github/ISSUE_TEMPLATE/bug.yml

+14-9
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,14 @@ body:
1212
- Linux Wayland
1313
- macOS
1414
- Windows
15+
- Windows WSL
1516
validations:
1617
required: true
1718
- type: input
1819
id: terminal
1920
attributes:
2021
label: What terminal are you running Yazi in?
21-
placeholder: "ex: Kitty v0.30.1"
22-
validations:
23-
required: true
24-
- type: input
25-
id: version
26-
attributes:
27-
label: Yazi version
28-
description: Please do a `yazi -V` and paste the output here.
29-
placeholder: "ex: yazi 0.1.5 (3867c29 2023-11-25)"
22+
placeholder: "ex: kitty v0.32.2"
3023
validations:
3124
required: true
3225
- type: dropdown
@@ -38,6 +31,18 @@ body:
3831
- Not tried, and I'll explain why below
3932
validations:
4033
required: true
34+
- type: textarea
35+
id: debug
36+
attributes:
37+
label: "`yazi --debug` output"
38+
description: Please do a `yazi --debug` and paste the output here.
39+
value: |
40+
<!-- Paste the output between the backticks below: -->
41+
```sh
42+
43+
```
44+
validations:
45+
required: true
4146
- type: textarea
4247
id: description
4348
attributes:

Diff for: Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: yazi-adaptor/src/adaptor.rs

+41-181
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
use std::{env, fmt::Display, io::{Read, Write}, path::Path, sync::Arc};
1+
use std::{env, fmt::Display, path::Path, sync::Arc};
22

3-
use anyhow::{anyhow, Result};
4-
use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
3+
use anyhow::Result;
54
use ratatui::layout::Rect;
65
use tracing::warn;
76
use yazi_shared::{env_exists, term::Term};
87

98
use super::{Iterm2, Kitty, KittyOld};
10-
use crate::{ueberzug::Ueberzug, Sixel, SHOWN, TMUX};
9+
use crate::{ueberzug::Ueberzug, Emulator, Sixel, SHOWN, TMUX};
1110

1211
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
1312
pub enum Adaptor {
@@ -22,181 +21,6 @@ pub enum Adaptor {
2221
Chafa,
2322
}
2423

25-
#[derive(Clone)]
26-
enum Emulator {
27-
Unknown(Vec<Adaptor>),
28-
Kitty,
29-
Konsole,
30-
Iterm2,
31-
WezTerm,
32-
Foot,
33-
Ghostty,
34-
BlackBox,
35-
VSCode,
36-
Tabby,
37-
Hyper,
38-
Mintty,
39-
Neovim,
40-
}
41-
42-
impl Adaptor {
43-
fn emulator() -> Emulator {
44-
if env_exists("NVIM_LOG_FILE") && env_exists("NVIM") {
45-
return Emulator::Neovim;
46-
}
47-
48-
let vars = [
49-
("KITTY_WINDOW_ID", Emulator::Kitty),
50-
("KONSOLE_VERSION", Emulator::Konsole),
51-
("ITERM_SESSION_ID", Emulator::Iterm2),
52-
("WEZTERM_EXECUTABLE", Emulator::WezTerm),
53-
("GHOSTTY_RESOURCES_DIR", Emulator::Ghostty),
54-
("VSCODE_INJECTION", Emulator::VSCode),
55-
("TABBY_CONFIG_DIRECTORY", Emulator::Tabby),
56-
];
57-
match vars.into_iter().find(|v| env_exists(v.0)) {
58-
Some(var) => return var.1,
59-
None => warn!("[Adaptor] No special environment variables detected"),
60-
}
61-
62-
let (term, program) = Self::via_env();
63-
match program.as_str() {
64-
"iTerm.app" => return Emulator::Iterm2,
65-
"WezTerm" => return Emulator::WezTerm,
66-
"ghostty" => return Emulator::Ghostty,
67-
"BlackBox" => return Emulator::BlackBox,
68-
"vscode" => return Emulator::VSCode,
69-
"Tabby" => return Emulator::Tabby,
70-
"Hyper" => return Emulator::Hyper,
71-
"mintty" => return Emulator::Mintty,
72-
_ => warn!("[Adaptor] Unknown TERM_PROGRAM: {program}"),
73-
}
74-
match term.as_str() {
75-
"xterm-kitty" => return Emulator::Kitty,
76-
"foot" => return Emulator::Foot,
77-
"foot-extra" => return Emulator::Foot,
78-
"xterm-ghostty" => return Emulator::Ghostty,
79-
_ => warn!("[Adaptor] Unknown TERM: {term}"),
80-
}
81-
82-
Self::via_csi().unwrap_or(Emulator::Unknown(vec![]))
83-
}
84-
85-
pub(super) fn detect() -> Self {
86-
let mut protocols = match Self::emulator() {
87-
Emulator::Unknown(adapters) => adapters,
88-
Emulator::Kitty => vec![Self::Kitty],
89-
Emulator::Konsole => vec![Self::KittyOld, Self::Iterm2, Self::Sixel],
90-
Emulator::Iterm2 => vec![Self::Iterm2, Self::Sixel],
91-
Emulator::WezTerm => vec![Self::Iterm2, Self::Sixel],
92-
Emulator::Foot => vec![Self::Sixel],
93-
Emulator::Ghostty => vec![Self::KittyOld],
94-
Emulator::BlackBox => vec![Self::Sixel],
95-
Emulator::VSCode => vec![Self::Iterm2, Self::Sixel],
96-
Emulator::Tabby => vec![Self::Iterm2, Self::Sixel],
97-
Emulator::Hyper => vec![Self::Iterm2, Self::Sixel],
98-
Emulator::Mintty => vec![Self::Iterm2],
99-
Emulator::Neovim => vec![],
100-
};
101-
102-
#[cfg(windows)]
103-
protocols.retain(|p| *p == Self::Iterm2);
104-
if env_exists("ZELLIJ_SESSION_NAME") {
105-
protocols.retain(|p| *p == Self::Sixel);
106-
}
107-
if *TMUX && protocols.len() > 1 {
108-
protocols.retain(|p| *p != Self::KittyOld);
109-
}
110-
if let Some(p) = protocols.first() {
111-
return *p;
112-
}
113-
114-
match env::var("XDG_SESSION_TYPE").unwrap_or_default().as_str() {
115-
"x11" => return Self::X11,
116-
"wayland" => return Self::Wayland,
117-
_ => warn!("[Adaptor] Could not identify XDG_SESSION_TYPE"),
118-
}
119-
if env_exists("WAYLAND_DISPLAY") {
120-
return Self::Wayland;
121-
}
122-
if env_exists("DISPLAY") {
123-
return Self::X11;
124-
}
125-
if std::fs::symlink_metadata("/proc/sys/fs/binfmt_misc/WSLInterop").is_ok() {
126-
return Self::KittyOld;
127-
}
128-
129-
warn!("[Adaptor] Falling back to chafa");
130-
Self::Chafa
131-
}
132-
133-
fn via_env() -> (String, String) {
134-
fn tmux_env(name: &str) -> Result<String> {
135-
let output = std::process::Command::new("tmux").args(["show-environment", name]).output()?;
136-
137-
String::from_utf8(output.stdout)?
138-
.trim()
139-
.strip_prefix(&format!("{name}="))
140-
.map_or_else(|| Err(anyhow!("")), |s| Ok(s.to_string()))
141-
}
142-
143-
let mut term = env::var("TERM").unwrap_or_default();
144-
let mut program = env::var("TERM_PROGRAM").unwrap_or_default();
145-
146-
if *TMUX {
147-
term = tmux_env("TERM").unwrap_or(term);
148-
program = tmux_env("TERM_PROGRAM").unwrap_or(program);
149-
}
150-
151-
(term, program)
152-
}
153-
154-
fn via_csi() -> Result<Emulator> {
155-
enable_raw_mode()?;
156-
std::io::stdout().write_all(b"\x1b[>q\x1b_Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA\x1b\\\x1b[c")?;
157-
std::io::stdout().flush()?;
158-
159-
let mut stdin = std::io::stdin().lock();
160-
let mut buf = String::with_capacity(200);
161-
loop {
162-
let mut c = [0; 1];
163-
if stdin.read(&mut c)? == 0 {
164-
break;
165-
}
166-
if c[0] == b'c' && buf.contains("\x1b[?") {
167-
break;
168-
}
169-
buf.push(c[0] as char);
170-
}
171-
172-
disable_raw_mode().ok();
173-
let names = [
174-
("kitty", Emulator::Kitty),
175-
("Konsole", Emulator::Konsole),
176-
("iTerm2", Emulator::Iterm2),
177-
("WezTerm", Emulator::WezTerm),
178-
("foot", Emulator::Foot),
179-
("ghostty", Emulator::Ghostty),
180-
];
181-
182-
for (name, emulator) in names.iter() {
183-
if buf.contains(name) {
184-
return Ok(emulator.clone());
185-
}
186-
}
187-
188-
let mut adapters = Vec::with_capacity(2);
189-
if buf.contains("\x1b_Gi=31;OK") {
190-
adapters.push(Adaptor::KittyOld);
191-
}
192-
if ["?4;", "?4c", ";4;", ";4c"].iter().any(|s| buf.contains(s)) {
193-
adapters.push(Adaptor::Sixel);
194-
}
195-
196-
Ok(Emulator::Unknown(adapters))
197-
}
198-
}
199-
20024
impl Display for Adaptor {
20125
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20226
match self {
@@ -212,8 +36,6 @@ impl Display for Adaptor {
21236
}
21337

21438
impl Adaptor {
215-
pub(super) fn start(self) { Ueberzug::start(self); }
216-
21739
pub async fn image_show(self, path: &Path, rect: Rect) -> Result<(u32, u32)> {
21840
match self {
21941
Self::Kitty => Kitty::image_show(path, rect).await,
@@ -241,6 +63,8 @@ impl Adaptor {
24163
#[inline]
24264
pub fn shown_load(self) -> Option<Rect> { SHOWN.load_full().map(|r| *r) }
24365

66+
pub(super) fn start(self) { Ueberzug::start(self); }
67+
24468
#[inline]
24569
pub(super) fn shown_store(rect: Rect, size: (u32, u32)) {
24670
SHOWN.store(Some(Arc::new(
@@ -260,3 +84,39 @@ impl Adaptor {
26084
!matches!(self, Self::Kitty | Self::KittyOld | Self::Iterm2 | Self::Sixel)
26185
}
26286
}
87+
88+
impl Adaptor {
89+
pub fn matches() -> Self {
90+
let mut protocols = Emulator::detect().adapters();
91+
92+
#[cfg(windows)]
93+
protocols.retain(|p| *p == Self::Iterm2);
94+
if env_exists("ZELLIJ_SESSION_NAME") {
95+
protocols.retain(|p| *p == Self::Sixel);
96+
}
97+
if *TMUX && protocols.len() > 1 {
98+
protocols.retain(|p| *p != Self::KittyOld);
99+
}
100+
if let Some(p) = protocols.first() {
101+
return *p;
102+
}
103+
104+
match env::var("XDG_SESSION_TYPE").unwrap_or_default().as_str() {
105+
"x11" => return Self::X11,
106+
"wayland" => return Self::Wayland,
107+
_ => warn!("[Adaptor] Could not identify XDG_SESSION_TYPE"),
108+
}
109+
if env_exists("WAYLAND_DISPLAY") {
110+
return Self::Wayland;
111+
}
112+
if env_exists("DISPLAY") {
113+
return Self::X11;
114+
}
115+
if std::fs::symlink_metadata("/proc/sys/fs/binfmt_misc/WSLInterop").is_ok() {
116+
return Self::KittyOld;
117+
}
118+
119+
warn!("[Adaptor] Falling back to chafa");
120+
Self::Chafa
121+
}
122+
}

0 commit comments

Comments
 (0)