Skip to main content

uncurses/ansi/
charset.rs

1//! Character-set designation and locking-shift sequences.
2//!
3//! ## Category
4//!
5//! This module emits SCS (`ESC` plus a G-set selector and charset designator)
6//! and the locking-shift controls that map G1/G2/G3 into GL or GR.
7//!
8//! ## Escape format
9//!
10//! SCS is a short 7-bit ESC sequence rather than CSI/OSC/DCS:
11//!
12//! ```text
13//! ESC ( B
14//! ─┬─ ┬ ┬
15//! intro G0 charset
16//! ```
17//!
18//! The caller supplies the G-set selector byte and charset identifier exactly as
19//! they should appear on the wire.
20//!
21//! ## Mode interaction
22//!
23//! Charset selection affects how subsequent bytes are rendered by terminals that
24//! honor ISO-2022 character sets. It is independent of DECSET/DECRST modes.
25
26use std::io::{self, Write};
27
28/// Designate a character set with `ESC <gset> <charset>`.
29///
30/// `gset` is the designator selector byte: `b'('`/`b')'`/`b'*'`/`b'+'` for G0-G3 94-character sets, or `b'-'`/`b'.'`/`b'/'` for G1-G3 96-character sets. `charset` is emitted as the final designator byte, for example `b'B'` or `b'0'`.
31pub fn write_select_charset<W: Write>(w: &mut W, gset: u8, charset: u8) -> io::Result<()> {
32    w.write_all(&[0x1b, gset, charset])
33}
34
35/// Lock G1 into GR: exact bytes `ESC ~`.
36///
37/// Use after designating G-sets with [`write_select_charset`] when a terminal honors ISO-2022 locking shifts.
38pub const LS1R: &[u8] = b"\x1b~";
39
40/// Lock G2 into GL: exact bytes `ESC n`.
41///
42/// Use after designating G-sets with [`write_select_charset`] when a terminal honors ISO-2022 locking shifts.
43pub const LS2: &[u8] = b"\x1bn";
44
45/// Lock G2 into GR: exact bytes `ESC }`.
46///
47/// Use after designating G-sets with [`write_select_charset`] when a terminal honors ISO-2022 locking shifts.
48pub const LS2R: &[u8] = b"\x1b}";
49
50/// Lock G3 into GL: exact bytes `ESC o`.
51///
52/// Use after designating G-sets with [`write_select_charset`] when a terminal honors ISO-2022 locking shifts.
53pub const LS3: &[u8] = b"\x1bo";
54
55/// Lock G3 into GR: exact bytes `ESC |`.
56///
57/// Use after designating G-sets with [`write_select_charset`] when a terminal honors ISO-2022 locking shifts.
58pub const LS3R: &[u8] = b"\x1b|";
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63
64    #[test]
65    fn test_scs_g0_usascii() {
66        let mut buf = Vec::new();
67        write_select_charset(&mut buf, b'(', b'B').unwrap();
68        assert_eq!(buf, b"\x1b(B");
69    }
70
71    #[test]
72    fn test_scs_g1_drawing() {
73        let mut buf = Vec::new();
74        write_select_charset(&mut buf, b')', b'0').unwrap();
75        assert_eq!(buf, b"\x1b)0");
76    }
77}