Fix multiple issues found under Linux (#706)

Fixed:
* `sighandler_t` warning in nightly
* cppdbg + gdb pretty printing
* UTF8 parsing for SGR mouse coords
This commit is contained in:
Leonard Hecker 2025-12-01 22:24:27 +01:00 committed by GitHub
parent d71e94b303
commit 3df9e7cb6c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 34 additions and 28 deletions

10
.vscode/launch.json vendored
View File

@ -10,18 +10,20 @@
"program": "${workspaceFolder}/target/debug/edit",
"cwd": "${workspaceFolder}",
"args": [
"${workspaceFolder}/src/bin/edit/main.rs"
"${workspaceFolder}/crates/edit/src/bin/edit/main.rs"
],
},
{
"name": "Launch Debug (GDB/LLDB)",
"name": "Launch Debug (GDB)",
"preLaunchTask": "rust: cargo build",
"type": "cppdbg",
"request": "launch",
"miDebuggerPath": "rust-gdb",
"externalConsole": true,
"program": "${workspaceFolder}/target/debug/edit",
"cwd": "${workspaceFolder}",
"args": [
"${workspaceFolder}/src/bin/edit/main.rs"
"${workspaceFolder}/crates/edit/src/bin/edit/main.rs"
],
},
{
@ -32,7 +34,7 @@
"program": "${workspaceFolder}/target/debug/edit",
"cwd": "${workspaceFolder}",
"args": [
"${workspaceFolder}/src/bin/edit/main.rs"
"${workspaceFolder}/crates/edit/src/bin/edit/main.rs"
],
}
]

View File

@ -268,7 +268,7 @@ pub struct Parser {
bracketed_paste: bool,
bracketed_paste_buf: Vec<u8>,
x10_mouse_want: bool,
x10_mouse_buf: [u8; 3],
x10_mouse_buf: [char; 3],
x10_mouse_len: usize,
}
@ -281,7 +281,7 @@ impl Parser {
bracketed_paste: false,
bracketed_paste_buf: Vec::new(),
x10_mouse_want: false,
x10_mouse_buf: [0; 3],
x10_mouse_buf: ['\0'; 3],
x10_mouse_len: 0,
}
}
@ -535,27 +535,35 @@ impl<'input> Stream<'_, '_, 'input> {
/// This is so puzzling to me. The existence of this function makes me unhappy.
#[cold]
fn parse_x10_mouse_coordinates(&mut self) -> Option<Input<'input>> {
self.parser.x10_mouse_len +=
self.stream.read(&mut self.parser.x10_mouse_buf[self.parser.x10_mouse_len..]);
while self.parser.x10_mouse_len < 3 && !self.stream.done() {
self.parser.x10_mouse_buf[self.parser.x10_mouse_len] = self.stream.next_char();
self.parser.x10_mouse_len += 1;
}
if self.parser.x10_mouse_len < 3 {
return None;
}
let button = self.parser.x10_mouse_buf[0] & 0b11;
let modifier = self.parser.x10_mouse_buf[0] & 0b11100;
let b = self.parser.x10_mouse_buf[0] as u32;
let x = self.parser.x10_mouse_buf[1] as CoordType - 0x21;
let y = self.parser.x10_mouse_buf[2] as CoordType - 0x21;
let action = match button {
let action = match b & 0b11 {
0 => InputMouseState::Left,
1 => InputMouseState::Middle,
2 => InputMouseState::Right,
_ => InputMouseState::None,
};
let modifiers = match modifier {
4 => kbmod::SHIFT,
8 => kbmod::ALT,
16 => kbmod::CTRL,
_ => kbmod::NONE,
let modifiers = {
let mut m = kbmod::NONE;
if (b & 0b00100) != 0 {
m |= kbmod::SHIFT;
}
if (b & 0b01000) != 0 {
m |= kbmod::ALT;
}
if (b & 0b10000) != 0 {
m |= kbmod::CTRL;
}
m
};
self.parser.x10_mouse_want = false;

View File

@ -63,7 +63,7 @@ pub fn switch_modes() -> apperr::Result<()> {
// Set STATE.inject_resize to true whenever we get a SIGWINCH.
let mut sigwinch_action: libc::sigaction = mem::zeroed();
sigwinch_action.sa_sigaction = sigwinch_handler as libc::sighandler_t;
sigwinch_action.sa_sigaction = sigwinch_handler as *const () as libc::sighandler_t;
check_int_return(libc::sigaction(libc::SIGWINCH, &sigwinch_action, null_mut()))?;
// Get the original terminal modes so we can disable raw mode on exit.

View File

@ -128,17 +128,13 @@ impl<'input> Stream<'_, 'input> {
self.off
}
/// Reads and consumes raw bytes from the input.
pub fn read(&mut self, dst: &mut [u8]) -> usize {
let bytes = self.input.as_bytes();
let off = self.off.min(bytes.len());
let len = dst.len().min(bytes.len() - off);
dst[..len].copy_from_slice(&bytes[off..off + len]);
self.off += len;
len
/// Returns `true` if the input has been fully parsed.
pub fn done(&self) -> bool {
self.off >= self.input.len()
}
fn decode_next(&mut self) -> char {
/// Decodes and consumes the next UTF-8 character from the input.
pub fn next_char(&mut self) -> char {
let mut iter = Utf8Chars::new(self.input.as_bytes(), self.off);
let c = iter.next().unwrap_or('\0');
self.off = iter.offset();
@ -190,7 +186,7 @@ impl<'input> Stream<'_, 'input> {
return Some(Token::Text(&input[beg..self.off]));
}
},
State::Esc => match self.decode_next() {
State::Esc => match self.next_char() {
'[' => {
self.parser.state = State::Csi;
self.parser.csi.private_byte = '\0';
@ -216,7 +212,7 @@ impl<'input> Stream<'_, 'input> {
},
State::Ss3 => {
self.parser.state = State::Ground;
return Some(Token::SS3(self.decode_next()));
return Some(Token::SS3(self.next_char()));
}
State::Csi => {
loop {