summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Duerr <contact@christianduerr.com>2020-07-23 21:55:15 +0000
committerGitHub <noreply@github.com>2020-07-23 21:55:15 +0000
commit0dfd8601c92666c45d0c2e056bd68f600a4cbe47 (patch)
treea8c4b508932610b73c76840b2eaf9a3122e7ed67
parentdd32447bc282c443f8c7dd74fe8be635203390c9 (diff)
downloadalacritty-0dfd8601c92666c45d0c2e056bd68f600a4cbe47.tar.gz
alacritty-0dfd8601c92666c45d0c2e056bd68f600a4cbe47.zip
Add secondary DA support
This adds support for the secondary DA escape sequence response. Alacritty's version is formatted allowing for up to 99 minor and patch versions, which should be sufficient. The tertiary DA is intentionally not implemented and marked as rejected in the documentation, since a lot of terminals do not support it, or report useless data (XTerm/URxvt/Kitty). Fixes #3100.
-rw-r--r--CHANGELOG.md4
-rw-r--r--alacritty_terminal/src/ansi.rs10
-rw-r--r--alacritty_terminal/src/term/mod.rs46
-rw-r--r--docs/escape_support.md2
4 files changed, 53 insertions, 9 deletions
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<W: io::Write>(&mut self, _: &mut W) {}
+ fn identify_terminal<W: io::Write>(&mut self, _: &mut W, _intermediate: Option<char>) {}
/// Report device status.
fn device_status<W: io::Write>(&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<W: io::Write>(&mut self, _: &mut W) {
+ fn identify_terminal<W: io::Write>(&mut self, _: &mut W, _intermediate: Option<char>) {
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<T: EventListener> Handler for Term<T> {
}
#[inline]
- fn identify_terminal<W: io::Write>(&mut self, writer: &mut W) {
- trace!("Reporting terminal identity");
- let _ = writer.write_all(b"\x1b[?6c");
+ fn identify_terminal<W: io::Write>(&mut self, writer: &mut W, intermediate: Option<char>) {
+ 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<T: EventListener> Handler for Term<T> {
}
}
+/// 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::<usize>().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 | |