Skip to content

Commit f70b6cb

Browse files
committed
fix(tui): use reliable image protocol per terminal
1 parent 0531214 commit f70b6cb

1 file changed

Lines changed: 39 additions & 14 deletions

File tree

crates/jcode-tui-mermaid/src/mermaid_runtime.rs

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -129,28 +129,32 @@ pub(super) fn infer_protocol_from_env(
129129
lc_terminal: Option<&str>,
130130
kitty_window_id: Option<&str>,
131131
) -> Option<ProtocolType> {
132-
if kitty_window_id.is_some() {
133-
return Some(ProtocolType::Kitty);
134-
}
135-
136132
let term = term.unwrap_or("").to_ascii_lowercase();
137133
let term_program = term_program.unwrap_or("").to_ascii_lowercase();
138134
let lc_terminal = lc_terminal.unwrap_or("").to_ascii_lowercase();
139135

136+
// WezTerm advertises several image protocols, but ratatui-image's Kitty
137+
// path relies on Unicode placeholders that WezTerm does not implement
138+
// correctly. Its iTerm2 path is the upstream-tested, glitch-free choice.
139+
// Prefer this explicit terminal identity over TERM/KITTY_WINDOW_ID, which
140+
// may be inherited or deliberately overridden.
141+
if term_program.contains("wezterm") || lc_terminal.contains("wezterm") {
142+
return Some(ProtocolType::Iterm2);
143+
}
144+
145+
if kitty_window_id.is_some() {
146+
return Some(ProtocolType::Kitty);
147+
}
148+
140149
if term.contains("kitty")
141150
|| term_program.contains("kitty")
142-
|| term_program.contains("wezterm")
143151
|| term_program.contains("ghostty")
144152
|| term_program.contains("handterm")
145153
{
146154
return Some(ProtocolType::Kitty);
147155
}
148156

149-
if term_program.contains("iterm")
150-
|| term.contains("iterm")
151-
|| lc_terminal.contains("iterm")
152-
|| lc_terminal.contains("wezterm")
153-
{
157+
if term_program.contains("iterm") || term.contains("iterm") || lc_terminal.contains("iterm") {
154158
return Some(ProtocolType::Iterm2);
155159
}
156160

@@ -484,10 +488,6 @@ mod tests {
484488
infer_protocol_from_env(None, Some("HandTerm"), None, None),
485489
Some(ProtocolType::Kitty)
486490
);
487-
assert_eq!(
488-
infer_protocol_from_env(None, Some("WezTerm"), None, None),
489-
Some(ProtocolType::Kitty)
490-
);
491491
// KITTY_WINDOW_ID present is sufficient.
492492
assert_eq!(
493493
infer_protocol_from_env(Some("xterm-256color"), None, None, Some("3")),
@@ -501,12 +501,37 @@ mod tests {
501501
infer_protocol_from_env(None, Some("iTerm.app"), None, None),
502502
Some(ProtocolType::Iterm2)
503503
);
504+
assert_eq!(
505+
infer_protocol_from_env(None, Some("WezTerm"), None, None),
506+
Some(ProtocolType::Iterm2)
507+
);
504508
assert_eq!(
505509
infer_protocol_from_env(Some("xterm-sixel"), None, None, None),
506510
Some(ProtocolType::Sixel)
507511
);
508512
}
509513

514+
#[test]
515+
fn explicit_wezterm_identity_avoids_incomplete_kitty_placeholders() {
516+
assert_eq!(
517+
infer_protocol_from_env(
518+
Some("xterm-kitty"),
519+
Some("WezTerm"),
520+
None,
521+
Some("stale-kitty-window")
522+
),
523+
Some(ProtocolType::Iterm2)
524+
);
525+
assert_eq!(
526+
infer_protocol_from_env(Some("foot"), Some("foot"), None, None),
527+
None
528+
);
529+
assert_eq!(
530+
infer_protocol_from_env(Some("xterm-256color"), Some("konsole"), None, None),
531+
None
532+
);
533+
}
534+
510535
#[test]
511536
fn infer_protocol_misses_inside_masking_multiplexer() {
512537
// Herdr/tmux advertise a bland TERM with no graphics hints.

0 commit comments

Comments
 (0)