in crates/figterm/src/input/mod.rs [1637:1752]
fn process_bytes<F: FnMut(Option<Bytes>, InputEvent)>(&mut self, mut callback: F, maybe_more: bool) {
while !self.buf.is_empty() {
match self.state {
InputState::Pasting(offset) => {
let end_paste = PASTE_END.as_bytes();
if let Some(idx) = self.buf.find_subsequence(offset, end_paste) {
let pasted = String::from_utf8_lossy(&self.buf.as_slice()[0..idx]).to_string();
self.advance_buf(pasted.len() + end_paste.len());
let raw = self.raw_byte_stack.split();
callback(Some(raw.freeze()), InputEvent::Paste(pasted));
self.state = InputState::Normal;
} else {
// Advance our offset so that in the case where we receive a paste that
// is spread across N reads of size 8K, we don't need to search for the
// end marker in 8K, 16K, 24K etc. of text until the final buffer is received.
// Ensure that we use saturating math here for the case where the amount
// of buffered data after the begin paste is smaller than the end paste marker
// <https://github.com/wez/wezterm/pull/1832>
self.state = InputState::Pasting(self.buf.len().saturating_sub(end_paste.len()));
return;
}
},
InputState::EscapeMaybeAlt | InputState::Normal => {
/* Ignore mouse events for now. This requires the full VT Parser from wezterm.
if self.state == InputState::Normal && self.buf.as_slice()[0] == b'\x1b' {
// This feels a bit gross because we have two different parsers at play
// here. We want to re-use the escape sequence parser to crack the
// parameters out from things like mouse reports. The keymap tree doesn't
// know how to grok this.
let mut parser = Parser::new();
if let Some((Action::CSI(CSI::Mouse(mouse)), len)) =
parser.parse_first(self.buf.as_slice())
{
self.buf.advance(len);
match mouse {
MouseReport::SGR1006 {
x,
y,
button,
modifiers,
} => {
callback(InputEvent::Mouse(MouseEvent {
x,
y,
mouse_buttons: button.into(),
modifiers,
}));
}
MouseReport::SGR1016 {
x_pixels,
y_pixels,
button,
modifiers,
} => {
callback(InputEvent::PixelMouse(PixelMouseEvent {
x_pixels: x_pixels,
y_pixels: y_pixels,
mouse_buttons: button.into(),
modifiers,
}));
}
}
continue;
}
}
*/
match (self.key_map.lookup(self.buf.as_slice()), maybe_more) {
// If we got an unambiguous ESC and we have more data to
// follow, then this is likely the Meta version of the
// following keypress. Buffer up the escape key and
// consume it from the input. dispatch_callback() will
// emit either the ESC or the ALT modified following key.
(
Found::Exact(
len,
InputEvent::Key(KeyEvent {
key: KeyCode::Escape,
modifiers: Modifiers::NONE,
}),
),
_,
) if self.state == InputState::Normal && self.buf.len() > len => {
self.state = InputState::EscapeMaybeAlt;
self.advance_buf(len);
},
(Found::Exact(len, event), _) | (Found::Ambiguous(len, event), false) => {
self.advance_buf(len);
self.dispatch_callback(&mut callback, event.clone());
},
(Found::Ambiguous(_, _) | Found::NeedData, true) => {
return;
},
(Found::None, _) | (Found::NeedData, false) => {
// No pre-defined key, so pull out a unicode character
if let Some((c, len)) = Self::decode_one_char(self.buf.as_slice()) {
self.advance_buf(len);
self.dispatch_callback(
&mut callback,
InputEvent::Key(KeyEvent {
key: KeyCode::Char(c),
modifiers: Modifiers::NONE,
}),
);
} else {
// We need more data to recognize the input, so
// yield the remainder of the slice
return;
}
},
}
},
}
}
}