diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-06-05 00:41:12 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-06-05 00:42:14 +0300 |
| commit | acfbb7c85a44d28432512772e4070428df60cfd6 (patch) | |
| tree | b9adc71ef907fc865001a0c4fb976781e419c426 /src/ghostty | |
| parent | b4b69b3539fc02d855c9b626cb205074e1541c78 (diff) | |
fix: enable grapheme clusters in panes
refs #243
Diffstat (limited to 'src/ghostty')
| -rw-r--r-- | src/ghostty/mod.rs | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/ghostty/mod.rs b/src/ghostty/mod.rs index a64fece1..08d0e117 100644 --- a/src/ghostty/mod.rs +++ b/src/ghostty/mod.rs @@ -161,6 +161,7 @@ pub const MODE_MOUSE_ALTERNATE_SCROLL: u16 = 1007; pub const MODE_MOUSE_SGR_PIXELS: u16 = 1016; pub const MODE_BRACKETED_PASTE: u16 = 2004; pub const MODE_SYNCHRONIZED_OUTPUT: u16 = 2026; +pub const MODE_GRAPHEME_CLUSTER: u16 = 2027; const KITTY_IMAGE_STORAGE_LIMIT_BYTES: u64 = 64 * 1024 * 1024; const APC_MAX_BYTES: usize = 16 * 1024 * 1024; @@ -678,6 +679,10 @@ impl Terminal { unsafe { ffi::ghostty_terminal_mode_set(self.raw, mode, value).into_result() } } + pub fn enable_grapheme_cluster_mode(&mut self) -> Result<(), Error> { + self.mode_set(MODE_GRAPHEME_CLUSTER, true) + } + pub fn kitty_keyboard_flags(&self) -> Result<u8, Error> { let mut out = 0u8; unsafe { @@ -2962,6 +2967,43 @@ mod tests { } #[test] + fn grapheme_cluster_mode_keeps_issue_453_payload_safe() { + let mut terminal = Terminal::new(80, 3, 100).unwrap(); + terminal.enable_grapheme_cluster_mode().unwrap(); + terminal.write("README ๐จโ๐ฉโ๐งโ๐ฆ ๐งโ๐ป โ
โก ๆผขๅญ cafรฉ eฬ ๐ณ๏ธโ๐ ๐\r\n".as_bytes()); + + let mut render_state = RenderState::new().unwrap(); + render_state.update(&terminal).unwrap(); + + let mut row_iterator = RowIterator::new().unwrap(); + let mut rows = render_state + .populate_row_iterator(&mut row_iterator) + .unwrap(); + let mut row_cells = RowCells::new().unwrap(); + let mut codepoints = Vec::new(); + let mut text = String::new(); + + while rows.next() { + let mut cells = rows.populate_cells(&mut row_cells).unwrap(); + while cells.next() { + cells + .grapheme_text_into(&mut codepoints, &mut text) + .unwrap(); + } + } + } + + #[test] + fn grapheme_cluster_mode_is_default_and_survives_full_reset() { + let mut terminal = Terminal::new(80, 3, 100).unwrap(); + assert!(terminal.mode_get(MODE_GRAPHEME_CLUSTER).unwrap()); + + terminal.write(b"\x1bc"); + + assert!(terminal.mode_get(MODE_GRAPHEME_CLUSTER).unwrap()); + } + + #[test] fn render_state_row_dirty_can_be_cleared_independently() { let mut terminal = Terminal::new(8, 3, 100).unwrap(); let mut render_state = RenderState::new().unwrap(); |
