fix(compatibility): improve vttest (#1671)
* Improve 'vttest' scenarios: 1. Report terminal as VT220 with sixel rather than VT400 family with sixel. This fixes a hang when launching vttest as it is waiting for a response to DECRQSS. 2. Test 6.2: Support NewLine mode (CR --> CRLF). 3. Test 6.3: Fix DSR cursor position report to honor scrolling region. 4. Test 6.7: Parse and respond to DECREQTPARM (Request Terminal Parameters - CSI x). This is a VT100 sequence that xterm used to respond to always, but more recently only responds to when explicitly set to VT100 level. * cargo fmt * Fix failing unit test snapshot * fix clippy error * VT100 UK character set
This commit is contained in:
parent
639de16c5e
commit
a316577d1e
5 changed files with 85 additions and 12 deletions
|
|
@ -352,6 +352,7 @@ pub struct Grid {
|
|||
pub sixel_scrolling: bool, // DECSDM
|
||||
pub insert_mode: bool,
|
||||
pub disable_linewrap: bool,
|
||||
pub new_line_mode: bool, // Automatic newline LNM
|
||||
pub clear_viewport_before_rendering: bool,
|
||||
pub width: usize,
|
||||
pub height: usize,
|
||||
|
|
@ -478,6 +479,7 @@ impl Grid {
|
|||
sixel_scrolling: false,
|
||||
insert_mode: false,
|
||||
disable_linewrap: false,
|
||||
new_line_mode: false,
|
||||
alternate_screen_state: None,
|
||||
clear_viewport_before_rendering: false,
|
||||
active_charset: Default::default(),
|
||||
|
|
@ -1515,6 +1517,7 @@ impl Grid {
|
|||
self.active_charset = Default::default();
|
||||
self.erasure_mode = false;
|
||||
self.disable_linewrap = false;
|
||||
self.new_line_mode = false;
|
||||
self.cursor.change_shape(CursorShape::Initial);
|
||||
self.output_buffer.update_all_lines();
|
||||
self.changed_colors = None;
|
||||
|
|
@ -2350,8 +2353,18 @@ impl Perform for Grid {
|
|||
_ => {},
|
||||
};
|
||||
}
|
||||
} else if let Some(4) = params_iter.next().map(|param| param[0]) {
|
||||
self.insert_mode = false;
|
||||
} else {
|
||||
for param in params_iter.map(|param| param[0]) {
|
||||
match param {
|
||||
4 => {
|
||||
self.insert_mode = false;
|
||||
},
|
||||
20 => {
|
||||
self.new_line_mode = false;
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if c == 'h' {
|
||||
let first_intermediate_is_questionmark = match intermediates.get(0) {
|
||||
|
|
@ -2434,8 +2447,18 @@ impl Perform for Grid {
|
|||
_ => {},
|
||||
}
|
||||
}
|
||||
} else if let Some(4) = params_iter.next().map(|param| param[0]) {
|
||||
self.insert_mode = true;
|
||||
} else {
|
||||
for param in params_iter.map(|param| param[0]) {
|
||||
match param {
|
||||
4 => {
|
||||
self.insert_mode = true;
|
||||
},
|
||||
20 => {
|
||||
self.new_line_mode = true;
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if c == 'r' {
|
||||
if params.len() > 1 {
|
||||
|
|
@ -2602,8 +2625,8 @@ impl Perform for Grid {
|
|||
// https://vt100.net/docs/vt510-rm/DA1.html
|
||||
match intermediates.get(0) {
|
||||
None | Some(0) => {
|
||||
// primary device attributes
|
||||
let terminal_capabilities = "\u{1b}[?64;4c";
|
||||
// primary device attributes - VT220 with sixel
|
||||
let terminal_capabilities = "\u{1b}[?62;4c";
|
||||
self.pending_messages_to_pty
|
||||
.push(terminal_capabilities.as_bytes().to_vec());
|
||||
},
|
||||
|
|
@ -2627,13 +2650,41 @@ impl Perform for Grid {
|
|||
},
|
||||
6 => {
|
||||
// CPR - cursor position report
|
||||
let position_report =
|
||||
format!("\x1b[{};{}R", self.cursor.y + 1, self.cursor.x + 1);
|
||||
|
||||
// Note that this is relative to scrolling region.
|
||||
let offset = match self.scroll_region {
|
||||
Some((scroll_region_top, _scroll_region_bottom)) => scroll_region_top,
|
||||
_ => 0,
|
||||
};
|
||||
let position_report = format!(
|
||||
"\u{1b}[{};{}R",
|
||||
self.cursor.y + 1 - offset,
|
||||
self.cursor.x + 1
|
||||
);
|
||||
self.pending_messages_to_pty
|
||||
.push(position_report.as_bytes().to_vec());
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
} else if c == 'x' {
|
||||
// DECREQTPARM - Request Terminal Parameters
|
||||
// https://vt100.net/docs/vt100-ug/chapter3.html#DECREQTPARM
|
||||
//
|
||||
// Respond with (same as xterm): Parity NONE, 8 bits,
|
||||
// xmitspeed 38400, recvspeed 38400. (CLoCk MULtiplier =
|
||||
// 1, STP option flags = 0)
|
||||
//
|
||||
// (xterm used to respond to DECREQTPARM in all modes.
|
||||
// Now it seems to only do so when explicitly in VT100 mode.)
|
||||
let query = next_param_or(0);
|
||||
match query {
|
||||
0 | 1 => {
|
||||
let response = format!("\u{1b}[{};1;1;128;128;1;0x", query + 2);
|
||||
self.pending_messages_to_pty
|
||||
.push(response.as_bytes().to_vec());
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
} else if c == 't' {
|
||||
match next_param_or(1) as usize {
|
||||
14 => {
|
||||
|
|
@ -2678,6 +2729,19 @@ impl Perform for Grid {
|
|||
|
||||
fn esc_dispatch(&mut self, intermediates: &[u8], _ignore: bool, byte: u8) {
|
||||
match (byte, intermediates.get(0)) {
|
||||
(b'A', charset_index_symbol) => {
|
||||
let charset_index: CharsetIndex = match charset_index_symbol {
|
||||
Some(b'(') => CharsetIndex::G0,
|
||||
Some(b')') => CharsetIndex::G1,
|
||||
Some(b'*') => CharsetIndex::G2,
|
||||
Some(b'+') => CharsetIndex::G3,
|
||||
_ => {
|
||||
// invalid, silently do nothing
|
||||
return;
|
||||
},
|
||||
};
|
||||
self.configure_charset(StandardCharset::UK, charset_index);
|
||||
},
|
||||
(b'B', charset_index_symbol) => {
|
||||
let charset_index: CharsetIndex = match charset_index_symbol {
|
||||
Some(b'(') => CharsetIndex::G0,
|
||||
|
|
|
|||
|
|
@ -586,6 +586,7 @@ impl Default for CharsetIndex {
|
|||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum StandardCharset {
|
||||
Ascii,
|
||||
UK,
|
||||
SpecialCharacterAndLineDrawing,
|
||||
}
|
||||
|
||||
|
|
@ -602,6 +603,10 @@ impl StandardCharset {
|
|||
pub fn map(self, c: char) -> char {
|
||||
match self {
|
||||
StandardCharset::Ascii => c,
|
||||
StandardCharset::UK => match c {
|
||||
'#' => '£',
|
||||
_ => c,
|
||||
},
|
||||
StandardCharset::SpecialCharacterAndLineDrawing => match c {
|
||||
'`' => '◆',
|
||||
'a' => '▒',
|
||||
|
|
|
|||
|
|
@ -162,6 +162,12 @@ impl Pane for TerminalPane {
|
|||
// needs to be adjusted.
|
||||
// here we match against those cases - if need be, we adjust the input and if not
|
||||
// we send back the original input
|
||||
if self.grid.new_line_mode {
|
||||
if let &[13] = input_bytes.as_slice() {
|
||||
// LNM - carriage return is followed by linefeed
|
||||
return "\u{0d}\u{0a}".as_bytes().to_vec();
|
||||
};
|
||||
}
|
||||
if self.grid.cursor_key_mode {
|
||||
match input_bytes.as_slice() {
|
||||
LEFT_ARROW => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
---
|
||||
source: zellij-server/src/panes/./unit/grid_tests.rs
|
||||
assertion_line: 721
|
||||
expression: "format!(\"{:?}\", grid.pending_messages_to_pty)"
|
||||
---
|
||||
[[27, 91, 63, 54, 52, 59, 52, 99], [27, 91, 56, 59, 53, 49, 59, 57, 55, 116], [27, 91, 63, 54, 99], [27, 91, 48, 110], [27, 91, 49, 59, 49, 82]]
|
||||
[[27, 91, 63, 54, 50, 59, 52, 99], [27, 91, 56, 59, 53, 49, 59, 57, 55, 116], [27, 91, 63, 54, 99], [27, 91, 48, 110], [27, 91, 49, 59, 49, 82]]
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
---
|
||||
source: zellij-server/src/panes/./unit/grid_tests.rs
|
||||
expression: "format!(\"{:?}\", grid)"
|
||||
|
||||
---
|
||||
00 (C): Selected as G0 (with SI) Selected as G1 (with SO)
|
||||
01 (C):
|
||||
|
|
@ -10,7 +9,7 @@ expression: "format!(\"{:?}\", grid)"
|
|||
04 (C): @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
|
||||
05 (C): `abcdefghijklmnopqrstuvwxyz{|}~ `abcdefghijklmnopqrstuvwxyz{|}~
|
||||
06 (C): Character set A (British)
|
||||
07 (C): !"#$%&'()*+,-./0123456789:;<=>? !"#$%&'()*+,-./0123456789:;<=>?
|
||||
07 (C): !"£$%&'()*+,-./0123456789:;<=>? !"£$%&'()*+,-./0123456789:;<=>?
|
||||
08 (C): @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
|
||||
09 (C): `abcdefghijklmnopqrstuvwxyz{|}~ `abcdefghijklmnopqrstuvwxyz{|}~
|
||||
10 (C): Character set 0 (DEC Special graphics and line drawing)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue