Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 16 additions & 15 deletions src/picker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,27 +117,28 @@ impl Picker {
capabilities: Vec::new(),
};

let mut options_with_blacklist = options;
let is_wezterm = env::var("WEZTERM_EXECUTABLE").is_ok_and(|s| !s.is_empty());
let is_konsole = env::var("KONSOLE_VERSION").is_ok_and(|s| !s.is_empty());
if is_wezterm || is_konsole {
// WezTerm could use Sixel, but iTerm2 (detected later is better).
// Konsole's Sixel implementation is buggy: https://github.com/benjajaja/ratatui-image?tab=readme-ov-file#compatibility-matrix
// Neither implement the placeholder part of kitty correctly.
options_with_blacklist
.blacklist_protocols(vec![ProtocolType::Kitty, ProtocolType::Sixel]);
}

// Write and read to stdin to query protocol capabilities and font-size.
match query_with_timeout(is_tmux, options) {
match query_with_timeout(is_tmux, options_with_blacklist) {
Ok((capability_proto, font_size, caps)) => {
let iterm2_proto = iterm2_from_env();

// Wezterm reports kitty support but its implementation is incomplete.
// Suppress kitty and default to iterm2 (which wezterm fully supports).
let is_wezterm = env::var("WEZTERM_EXECUTABLE").is_ok_and(|s| !s.is_empty());

// IO-based detection is authoritative; env-based hints are fallbacks
// (env vars like KITTY_WINDOW_ID can be stale in tmux sessions).
let protocol_type = if is_wezterm {
capability_proto
.filter(|p| *p != ProtocolType::Kitty)
.unwrap_or(ProtocolType::Iterm2)
} else {
capability_proto
.or(tmux_proto)
.or(iterm2_proto)
.unwrap_or(ProtocolType::Halfblocks)
};
let protocol_type = capability_proto
.or(tmux_proto)
.or(iterm2_proto)
.unwrap_or(ProtocolType::Halfblocks);

if let Some(font_size) = font_size {
Ok(Self {
Expand Down
26 changes: 20 additions & 6 deletions src/picker/cap_parser.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Terminal stdio query parser module.
use std::{fmt::Write, time::Duration};

use crate::picker::STDIN_READ_TIMEOUT_MILLIS;
use crate::picker::{ProtocolType, STDIN_READ_TIMEOUT_MILLIS};

pub struct Parser {
data: String,
Expand All @@ -27,20 +27,30 @@ pub enum Response {

/// Extra query options
pub struct QueryStdioOptions {
// Timeout for the stdio query.
/// Timeout for the stdio query.
pub timeout: Duration,
/// Query for [Text Sizing Protocol]. The result can be checked by searching for
/// [crate::picker::Capability::TextSizingProtocol] in [crate::picker::Picker::capabilities].
///
/// [Text Sizing Protocol] <https://sw.kovidgoyal.net/kitty/text-sizing-protocol//>
pub text_sizing_protocol: bool,
/// Blacklist protocols from the detection query. Currently only kitty can be detected, so that
/// is the only ProtocolType that can have any effect here.
/// [`crate::picker::Picker`] currently sets ProtocolType::Kitty for WezTerm and Konsole.
blacklist_protocols: Vec<ProtocolType>,
}
impl QueryStdioOptions {
pub(crate) fn blacklist_protocols(&mut self, protocol_types: Vec<ProtocolType>) {
self.blacklist_protocols = protocol_types;
}
}

impl Default for QueryStdioOptions {
fn default() -> Self {
Self {
timeout: Duration::from_millis(STDIN_READ_TIMEOUT_MILLIS),
text_sizing_protocol: false,
blacklist_protocols: Vec::new(),
}
}
}
Expand Down Expand Up @@ -74,11 +84,15 @@ impl Parser {
let mut buf = String::with_capacity(100);
buf.push_str(start);

// Kitty graphics
write!(buf, "{escape}_Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA{escape}\\").unwrap();
if !options.blacklist_protocols.contains(&ProtocolType::Kitty) {
// Kitty graphics
write!(buf, "{escape}_Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA{escape}\\").unwrap();
}

// Device Attributes Report 1 (sixel support)
write!(buf, "{escape}[c").unwrap();
if !options.blacklist_protocols.contains(&ProtocolType::Sixel) {
// Device Attributes Report 1 (sixel support)
write!(buf, "{escape}[c").unwrap();
}

// Font size in pixels
write!(buf, "{escape}[16t").unwrap();
Expand Down
Loading