Skip to content

Commit 61365df

Browse files
committed
Add a custom event type that's shared across backends
1 parent e0f9d86 commit 61365df

File tree

12 files changed

+145
-42
lines changed

12 files changed

+145
-42
lines changed

helix-term/src/application.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use helix_view::{align_view, editor::ConfigEvent, graphics::Rect, theme, Align,
1515

1616
use crate::{
1717
args::Args,
18-
compositor::Compositor,
18+
compositor::{Compositor, Event},
1919
config::Config,
2020
job::Jobs,
2121
keymap::Keymaps,
@@ -31,7 +31,7 @@ use std::{
3131
use anyhow::Error;
3232

3333
use crossterm::{
34-
event::{DisableMouseCapture, EnableMouseCapture, Event, EventStream},
34+
event::{DisableMouseCapture, EnableMouseCapture, Event as CrosstermEvent, EventStream},
3535
execute, terminal,
3636
tty::IsTty,
3737
};
@@ -397,14 +397,17 @@ impl Application {
397397
}
398398
}
399399

400-
pub fn handle_terminal_events(&mut self, event: Option<Result<Event, crossterm::ErrorKind>>) {
400+
pub fn handle_terminal_events(
401+
&mut self,
402+
event: Option<Result<CrosstermEvent, crossterm::ErrorKind>>,
403+
) {
401404
let mut cx = crate::compositor::Context {
402405
editor: &mut self.editor,
403406
jobs: &mut self.jobs,
404407
};
405408
// Handle key events
406409
let should_redraw = match event {
407-
Some(Ok(Event::Resize(width, height))) => {
410+
Some(Ok(CrosstermEvent::Resize(width, height))) => {
408411
self.terminal
409412
.resize(Rect::new(0, 0, width, height))
410413
.expect("Unable to resize terminal");
@@ -416,7 +419,7 @@ impl Application {
416419
self.compositor
417420
.handle_event(Event::Resize(width, height), &mut cx)
418421
}
419-
Some(Ok(event)) => self.compositor.handle_event(event, &mut cx),
422+
Some(Ok(event)) => self.compositor.handle_event(event.into(), &mut cx),
420423
Some(Err(x)) => panic!("{}", x),
421424
None => panic!(),
422425
};

helix-term/src/commands.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4570,7 +4570,7 @@ fn replay_macro(cx: &mut Context) {
45704570
cx.callback = Some(Box::new(move |compositor, cx| {
45714571
for _ in 0..count {
45724572
for &key in keys.iter() {
4573-
compositor.handle_event(crossterm::event::Event::Key(key.into()), cx);
4573+
compositor.handle_event(compositor::Event::Key(key), cx);
45744574
}
45754575
}
45764576
}));

helix-term/src/compositor.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
use helix_core::Position;
55
use helix_view::graphics::{CursorKind, Rect};
66

7-
use crossterm::event::Event;
8-
use tui::buffer::Buffer as Surface;
9-
107
pub type Callback = Box<dyn FnOnce(&mut Compositor, &mut Context)>;
118

129
// Cursive-inspired
@@ -15,21 +12,29 @@ pub enum EventResult {
1512
Consumed(Option<Callback>),
1613
}
1714

15+
use crate::job::Jobs;
1816
use helix_view::Editor;
1917

20-
use crate::job::Jobs;
18+
pub use helix_view::input::Event;
2119

2220
pub struct Context<'a> {
2321
pub editor: &'a mut Editor,
2422
pub jobs: &'a mut Jobs,
2523
}
2624

27-
pub struct RenderContext<'a> {
28-
pub editor: &'a Editor,
29-
pub surface: &'a mut Surface,
30-
pub scroll: Option<usize>,
25+
mod term {
26+
use super::*;
27+
pub use tui::buffer::Buffer as Surface;
28+
29+
pub struct RenderContext<'a> {
30+
pub editor: &'a Editor,
31+
pub surface: &'a mut Surface,
32+
pub scroll: Option<usize>,
33+
}
3134
}
3235

36+
pub use term::*;
37+
3338
pub trait Component: Any + AnyComponent {
3439
/// Process input events, return true if handled.
3540
fn handle_event(&mut self, _event: Event, _ctx: &mut Context) -> EventResult {
@@ -115,7 +120,7 @@ impl Compositor {
115120
pub fn handle_event(&mut self, event: Event, cx: &mut Context) -> bool {
116121
// If it is a key event and a macro is being recorded, push the key event to the recording.
117122
if let (Event::Key(key), Some((_, keys))) = (event, &mut cx.editor.macro_recording) {
118-
keys.push(key.into());
123+
keys.push(key);
119124
}
120125

121126
let mut callbacks = Vec::new();

helix-term/src/ui/completion.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
use crate::compositor::{Component, Context, EventResult, RenderContext};
2-
use crossterm::event::{Event, KeyCode, KeyEvent};
1+
use crate::compositor::{Component, Context, Event, EventResult, RenderContext};
32
use helix_view::editor::CompleteAction;
43

54
use std::borrow::Cow;
65

76
use helix_core::{Change, Transaction};
8-
use helix_view::{graphics::Rect, Document, Editor};
7+
use helix_view::{
8+
graphics::Rect,
9+
input::{KeyCode, KeyEvent},
10+
Document, Editor,
11+
};
912

1013
use crate::commands;
1114
use crate::ui::{menu, Markdown, Menu, Popup, PromptEvent};

helix-term/src/ui/editor.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{
22
commands,
3-
compositor::{Component, Context, EventResult, RenderContext},
3+
compositor::{Component, Context, Event, EventResult, RenderContext},
44
key,
55
keymap::{KeymapResult, Keymaps},
66
ui::{Completion, ProgressSpinners},
@@ -21,13 +21,12 @@ use helix_view::{
2121
document::{Mode, SCRATCH_BUFFER_NAME},
2222
editor::{CompleteAction, CursorShapeConfig},
2323
graphics::{CursorKind, Modifier, Rect, Style},
24-
input::KeyEvent,
24+
input::{KeyEvent, MouseButton, MouseEvent, MouseEventKind},
2525
keyboard::{KeyCode, KeyModifiers},
2626
Document, Editor, Theme, View,
2727
};
2828
use std::borrow::Cow;
2929

30-
use crossterm::event::{Event, MouseButton, MouseEvent, MouseEventKind};
3130
use tui::buffer::Buffer as Surface;
3231

3332
pub struct EditorView {
@@ -977,7 +976,7 @@ impl EditorView {
977976
if let Some((pos, view_id)) = result {
978977
let doc = editor.document_mut(editor.tree.get(view_id).doc).unwrap();
979978

980-
if modifiers == crossterm::event::KeyModifiers::ALT {
979+
if modifiers == KeyModifiers::ALT {
981980
let selection = doc.selection(view_id).clone();
982981
doc.set_selection(view_id, selection.push(Range::point(pos)));
983982
} else {
@@ -1108,7 +1107,7 @@ impl EditorView {
11081107
let line = coords.row + view.offset.row;
11091108
if let Ok(pos) = doc.text().try_line_to_char(line) {
11101109
doc.set_selection(view_id, Selection::point(pos));
1111-
if modifiers == crossterm::event::KeyModifiers::ALT {
1110+
if modifiers == KeyModifiers::ALT {
11121111
commands::MappableCommand::dap_edit_log.execute(cxt);
11131112
} else {
11141113
commands::MappableCommand::dap_edit_condition.execute(cxt);
@@ -1132,7 +1131,7 @@ impl EditorView {
11321131
return EventResult::Ignored(None);
11331132
}
11341133

1135-
if modifiers == crossterm::event::KeyModifiers::ALT {
1134+
if modifiers == KeyModifiers::ALT {
11361135
commands::MappableCommand::replace_selections_with_primary_clipboard
11371136
.execute(cxt);
11381137

@@ -1181,9 +1180,8 @@ impl Component for EditorView {
11811180
// Handling it here but not re-rendering will cause flashing
11821181
EventResult::Consumed(None)
11831182
}
1184-
Event::Key(key) => {
1183+
Event::Key(mut key) => {
11851184
cx.editor.reset_idle_timer();
1186-
let mut key = KeyEvent::from(key);
11871185
canonicalize_key(&mut key);
11881186

11891187
// clear status

helix-term/src/ui/menu.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
use crate::{
2-
compositor::{Callback, Component, Compositor, Context, EventResult, RenderContext},
2+
compositor::{Callback, Component, Compositor, Context, Event, EventResult, RenderContext},
33
ctrl, key, shift,
44
};
5-
use crossterm::event::Event;
65
use tui::widgets::Table;
76

87
pub use tui::widgets::{Cell, Row};
@@ -210,7 +209,7 @@ impl<T: Item + 'static> Component for Menu<T> {
210209
compositor.pop();
211210
}));
212211

213-
match event.into() {
212+
match event {
214213
// esc or ctrl-c aborts the completion and closes the menu
215214
key!(Esc) | ctrl!('c') => {
216215
(self.callback_fn)(cx.editor, self.selection(), MenuEvent::Abort);

helix-term/src/ui/overlay.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
use crossterm::event::Event;
21
use helix_core::Position;
32
use helix_view::{
43
graphics::{CursorKind, Rect},
54
Editor,
65
};
76

8-
use crate::compositor::{Component, Context, EventResult, RenderContext};
7+
use crate::compositor::{Component, Context, Event, EventResult, RenderContext};
98

109
/// Contains a component placed in the center of the parent component
1110
pub struct Overlay<T> {

helix-term/src/ui/picker.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
use crate::{
2-
compositor::{Component, Compositor, Context, EventResult, RenderContext},
2+
compositor::{Component, Compositor, Context, Event, EventResult, RenderContext},
33
ctrl, key, shift,
44
ui::{self, EditorView},
55
};
6-
use crossterm::event::Event;
76
use tui::widgets::{Block, BorderType, Borders};
87

98
use fuzzy_matcher::skim::SkimMatcherV2 as Matcher;
@@ -496,7 +495,7 @@ impl<T: 'static> Component for Picker<T> {
496495
compositor.last_picker = compositor.pop();
497496
})));
498497

499-
match key_event.into() {
498+
match key_event {
500499
shift!(Tab) | key!(Up) | ctrl!('p') => {
501500
self.move_by(1, Direction::Backward);
502501
}

helix-term/src/ui/popup.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
use crate::{
2-
compositor::{Callback, Component, Context, EventResult, RenderContext},
2+
compositor::{Callback, Component, Context, Event, EventResult, RenderContext},
33
ctrl, key,
44
};
5-
use crossterm::event::Event;
65

76
use helix_core::Position;
87
use helix_view::{
@@ -124,7 +123,7 @@ impl<T: Component> Component for Popup<T> {
124123
compositor.pop();
125124
});
126125

127-
match key.into() {
126+
match key {
128127
// esc or ctrl-c aborts the completion and closes the menu
129128
key!(Esc) | ctrl!('c') => {
130129
let _ = self.contents.handle_event(event, cx);

helix-term/src/ui/prompt.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
use crate::compositor::{Component, Compositor, Context, EventResult, RenderContext};
1+
use crate::compositor::{Component, Compositor, Context, Event, EventResult, RenderContext};
22
use crate::{alt, ctrl, key, shift, ui};
3-
use crossterm::event::Event;
43
use helix_view::input::KeyEvent;
54
use helix_view::keyboard::KeyCode;
65
use std::{borrow::Cow, ops::RangeFrom};
@@ -454,7 +453,7 @@ impl Component for Prompt {
454453
compositor.pop();
455454
})));
456455

457-
match event.into() {
456+
match event {
458457
ctrl!('c') | key!(Esc) => {
459458
(self.callback_fn)(cx, &self.line, PromptEvent::Abort);
460459
return close_fn;

helix-view/src/input.rs

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,53 @@ use helix_core::unicode::width::UnicodeWidthStr;
44
use serde::de::{self, Deserialize, Deserializer};
55
use std::fmt;
66

7-
use crate::keyboard::{KeyCode, KeyModifiers};
7+
pub use crate::keyboard::{KeyCode, KeyModifiers};
88

9+
#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash)]
10+
pub enum Event {
11+
Key(KeyEvent),
12+
Mouse(MouseEvent),
13+
Resize(u16, u16),
14+
}
15+
16+
#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash)]
17+
pub struct MouseEvent {
18+
/// The kind of mouse event that was caused.
19+
pub kind: MouseEventKind,
20+
/// The column that the event occurred on.
21+
pub column: u16,
22+
/// The row that the event occurred on.
23+
pub row: u16,
24+
/// The key modifiers active when the event occurred.
25+
pub modifiers: KeyModifiers,
26+
}
27+
28+
#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash)]
29+
pub enum MouseEventKind {
30+
/// Pressed mouse button. Contains the button that was pressed.
31+
Down(MouseButton),
32+
/// Released mouse button. Contains the button that was released.
33+
Up(MouseButton),
34+
/// Moved the mouse cursor while pressing the contained mouse button.
35+
Drag(MouseButton),
36+
/// Moved the mouse cursor while not pressing a mouse button.
37+
Moved,
38+
/// Scrolled mouse wheel downwards (towards the user).
39+
ScrollDown,
40+
/// Scrolled mouse wheel upwards (away from the user).
41+
ScrollUp,
42+
}
43+
44+
/// Represents a mouse button.
45+
#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash)]
46+
pub enum MouseButton {
47+
/// Left mouse button.
48+
Left,
49+
/// Right mouse button.
50+
Right,
51+
/// Middle mouse button.
52+
Middle,
53+
}
954
/// Represents a key event.
1055
// We use a newtype here because we want to customize Deserialize and Display.
1156
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
@@ -214,6 +259,61 @@ impl<'de> Deserialize<'de> for KeyEvent {
214259
}
215260
}
216261

262+
#[cfg(feature = "term")]
263+
impl From<crossterm::event::Event> for Event {
264+
fn from(event: crossterm::event::Event) -> Self {
265+
match event {
266+
crossterm::event::Event::Key(key) => Self::Key(key.into()),
267+
crossterm::event::Event::Mouse(mouse) => Self::Mouse(mouse.into()),
268+
crossterm::event::Event::Resize(w, h) => Self::Resize(w, h),
269+
}
270+
}
271+
}
272+
273+
#[cfg(feature = "term")]
274+
impl From<crossterm::event::MouseEvent> for MouseEvent {
275+
fn from(
276+
crossterm::event::MouseEvent {
277+
kind,
278+
column,
279+
row,
280+
modifiers,
281+
}: crossterm::event::MouseEvent,
282+
) -> Self {
283+
Self {
284+
kind: kind.into(),
285+
column,
286+
row,
287+
modifiers: modifiers.into(),
288+
}
289+
}
290+
}
291+
292+
#[cfg(feature = "term")]
293+
impl From<crossterm::event::MouseEventKind> for MouseEventKind {
294+
fn from(kind: crossterm::event::MouseEventKind) -> Self {
295+
match kind {
296+
crossterm::event::MouseEventKind::Down(button) => Self::Down(button.into()),
297+
crossterm::event::MouseEventKind::Up(button) => Self::Down(button.into()),
298+
crossterm::event::MouseEventKind::Drag(button) => Self::Drag(button.into()),
299+
crossterm::event::MouseEventKind::Moved => Self::Moved,
300+
crossterm::event::MouseEventKind::ScrollDown => Self::ScrollDown,
301+
crossterm::event::MouseEventKind::ScrollUp => Self::ScrollUp,
302+
}
303+
}
304+
}
305+
306+
#[cfg(feature = "term")]
307+
impl From<crossterm::event::MouseButton> for MouseButton {
308+
fn from(button: crossterm::event::MouseButton) -> Self {
309+
match button {
310+
crossterm::event::MouseButton::Left => MouseButton::Left,
311+
crossterm::event::MouseButton::Right => MouseButton::Right,
312+
crossterm::event::MouseButton::Middle => MouseButton::Middle,
313+
}
314+
}
315+
}
316+
217317
#[cfg(feature = "term")]
218318
impl From<crossterm::event::KeyEvent> for KeyEvent {
219319
fn from(crossterm::event::KeyEvent { code, modifiers }: crossterm::event::KeyEvent) -> Self {

0 commit comments

Comments
 (0)