diff --git a/CHANGELOG.md b/CHANGELOG.md index 2065f4f3..1b042b95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## 0.6.0-dev +### Added + +- Secondary device attributes escape (`CSI > 0 c`) + ## 0.5.0-dev ### Packaging diff --git a/alacritty_terminal/src/ansi.rs b/alacritty_terminal/src/ansi.rs index 5f24dcff..bee19a06 100644 --- a/alacritty_terminal/src/ansi.rs +++ b/alacritty_terminal/src/ansi.rs @@ -164,7 +164,7 @@ pub trait Handler { /// Identify the terminal (should write back to the pty stream). /// /// TODO this should probably return an io::Result - fn identify_terminal(&mut self, _: &mut W) {} + fn identify_terminal(&mut self, _: &mut W, _intermediate: Option) {} /// Report device status. fn device_status(&mut self, _: &mut W, _: usize) {} @@ -973,8 +973,8 @@ where ('C', None) | ('a', None) => { handler.move_forward(Column(arg_or_default!(idx: 0, default: 1) as usize)) }, - ('c', None) if arg_or_default!(idx: 0, default: 0) == 0 => { - handler.identify_terminal(writer) + ('c', intermediate) if arg_or_default!(idx: 0, default: 0) == 0 => { + handler.identify_terminal(writer, intermediate.map(|&i| i as char)) }, ('D', None) => { handler.move_backward(Column(arg_or_default!(idx: 0, default: 1) as usize)) @@ -1148,7 +1148,7 @@ where }, (b'H', None) => self.handler.set_horizontal_tabstop(), (b'M', None) => self.handler.reverse_index(), - (b'Z', None) => self.handler.identify_terminal(self.writer), + (b'Z', None) => self.handler.identify_terminal(self.writer, None), (b'c', None) => self.handler.reset_state(), (b'0', intermediate) => { configure_charset!(StandardCharset::SpecialCharacterAndLineDrawing, intermediate) @@ -1408,7 +1408,7 @@ mod tests { self.index = index; } - fn identify_terminal(&mut self, _: &mut W) { + fn identify_terminal(&mut self, _: &mut W, _intermediate: Option) { self.identity_reported = true; } diff --git a/alacritty_terminal/src/term/mod.rs b/alacritty_terminal/src/term/mod.rs index 91748359..f27852de 100644 --- a/alacritty_terminal/src/term/mod.rs +++ b/alacritty_terminal/src/term/mod.rs @@ -1496,9 +1496,19 @@ impl Handler for Term { } #[inline] - fn identify_terminal(&mut self, writer: &mut W) { - trace!("Reporting terminal identity"); - let _ = writer.write_all(b"\x1b[?6c"); + fn identify_terminal(&mut self, writer: &mut W, intermediate: Option) { + match intermediate { + None => { + trace!("Reporting primary device attributes"); + let _ = writer.write_all(b"\x1b[?6c"); + }, + Some('>') => { + trace!("Reporting secondary device attributes"); + let version = version_number(env!("CARGO_PKG_VERSION")); + let _ = writer.write_all(format!("\x1b[>0;{};1c", version).as_bytes()); + }, + _ => debug!("Unsupported device attributes intermediate"), + } } #[inline] @@ -2184,6 +2194,27 @@ impl Handler for Term { } } +/// Terminal version for escape sequence reports. +/// +/// This returns the current terminal version as a unique number based on alacritty_terminal's +/// semver version. The different versions are padded to ensure that a higher semver version will +/// always report a higher version number. +fn version_number(mut version: &str) -> usize { + if let Some(separator) = version.rfind('-') { + version = &version[..separator]; + } + + let mut version_number = 0; + + let semver_versions = version.split('.'); + for (i, semver_version) in semver_versions.rev().enumerate() { + let semver_number = semver_version.parse::().unwrap_or(0); + version_number += usize::pow(100, i as u32) * semver_number; + } + + version_number +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ClipboardType { Clipboard, @@ -2688,6 +2719,15 @@ mod tests { term.set_title(None); assert_eq!(term.title, None); } + + #[test] + fn parse_cargo_version() { + assert!(version_number(env!("CARGO_PKG_VERSION")) >= 10_01); + assert_eq!(version_number("0.0.1-dev"), 1); + assert_eq!(version_number("0.1.2-dev"), 1_02); + assert_eq!(version_number("1.2.3-dev"), 1_02_03); + assert_eq!(version_number("999.99.99"), 9_99_99_99); + } } #[cfg(all(test, feature = "bench"))] diff --git a/docs/escape_support.md b/docs/escape_support.md index a02848b2..b757540d 100644 --- a/docs/escape_support.md +++ b/docs/escape_support.md @@ -43,7 +43,7 @@ brevity. | `CSI B` | IMPLEMENTED | | | `CSI b` | IMPLEMENTED | | | `CSI C` | IMPLEMENTED | | -| `CSI c` | PARTIAL | No parameter support | +| `CSI c` | IMPLEMENTED | | | `CSI D` | IMPLEMENTED | | | `CSI d` | IMPLEMENTED | | | `CSI E` | IMPLEMENTED | |