Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom event type replacing crossterm's Event #3169

Merged
merged 1 commit into from Aug 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 5 additions & 6 deletions helix-term/src/application.rs
Expand Up @@ -12,7 +12,7 @@ use serde_json::json;
use crate::{
args::Args,
commands::apply_workspace_edit,
compositor::Compositor,
compositor::{Compositor, Event},
config::Config,
job::Jobs,
keymap::Keymaps,
Expand All @@ -29,7 +29,7 @@ use std::{
use anyhow::{Context, Error};

use crossterm::{
event::{DisableMouseCapture, EnableMouseCapture, Event},
event::{DisableMouseCapture, EnableMouseCapture, Event as CrosstermEvent},
execute, terminal,
tty::IsTty,
};
Expand Down Expand Up @@ -418,21 +418,20 @@ impl Application {
}
}

pub fn handle_terminal_events(&mut self, event: Result<Event, crossterm::ErrorKind>) {
pub fn handle_terminal_events(&mut self, event: Result<CrosstermEvent, crossterm::ErrorKind>) {
let mut cx = crate::compositor::Context {
editor: &mut self.editor,
jobs: &mut self.jobs,
scroll: None,
};
// Handle key events
let should_redraw = match event {
Ok(Event::Resize(width, height)) => {
Ok(CrosstermEvent::Resize(width, height)) => {
self.compositor.resize(width, height);

self.compositor
.handle_event(Event::Resize(width, height), &mut cx)
}
Ok(event) => self.compositor.handle_event(event, &mut cx),
Ok(event) => self.compositor.handle_event(event.into(), &mut cx),
Err(x) => panic!("{}", x),
};

Expand Down
2 changes: 1 addition & 1 deletion helix-term/src/commands.rs
Expand Up @@ -4846,7 +4846,7 @@ fn replay_macro(cx: &mut Context) {
cx.callback = Some(Box::new(move |compositor, cx| {
for _ in 0..count {
for &key in keys.iter() {
compositor.handle_event(crossterm::event::Event::Key(key.into()), cx);
compositor.handle_event(compositor::Event::Key(key), cx);
}
}
// The macro under replay is cleared at the end of the callback, not in the
Expand Down
7 changes: 3 additions & 4 deletions helix-term/src/compositor.rs
Expand Up @@ -4,8 +4,6 @@
use helix_core::Position;
use helix_view::graphics::{CursorKind, Rect};

use crossterm::event::Event;

#[cfg(feature = "integration")]
use tui::backend::TestBackend;
use tui::buffer::Buffer as Surface;
Expand All @@ -18,9 +16,10 @@ pub enum EventResult {
Consumed(Option<Callback>),
}

use crate::job::Jobs;
use helix_view::Editor;

use crate::job::Jobs;
pub use helix_view::input::Event;

pub struct Context<'a> {
pub editor: &'a mut Editor,
Expand Down Expand Up @@ -161,7 +160,7 @@ impl Compositor {
pub fn handle_event(&mut self, event: Event, cx: &mut Context) -> bool {
// If it is a key event and a macro is being recorded, push the key event to the recording.
if let (Event::Key(key), Some((_, keys))) = (event, &mut cx.editor.macro_recording) {
keys.push(key.into());
keys.push(key);
}

let mut callbacks = Vec::new();
Expand Down
9 changes: 6 additions & 3 deletions helix-term/src/ui/completion.rs
@@ -1,13 +1,16 @@
use crate::compositor::{Component, Context, EventResult};
use crossterm::event::{Event, KeyCode, KeyEvent};
use crate::compositor::{Component, Context, Event, EventResult};
use helix_view::editor::CompleteAction;
use tui::buffer::Buffer as Surface;
use tui::text::Spans;

use std::borrow::Cow;

use helix_core::{Change, Transaction};
use helix_view::{graphics::Rect, Document, Editor};
use helix_view::{
graphics::Rect,
input::{KeyCode, KeyEvent},
Document, Editor,
};

use crate::commands;
use crate::ui::{menu, Markdown, Menu, Popup, PromptEvent};
Expand Down
14 changes: 6 additions & 8 deletions helix-term/src/ui/editor.rs
@@ -1,6 +1,6 @@
use crate::{
commands,
compositor::{Component, Context, EventResult},
compositor::{Component, Context, Event, EventResult},
job, key,
keymap::{KeymapResult, Keymaps},
ui::{Completion, ProgressSpinners},
Expand All @@ -19,13 +19,12 @@ use helix_view::{
document::Mode,
editor::{CompleteAction, CursorShapeConfig},
graphics::{Color, CursorKind, Modifier, Rect, Style},
input::KeyEvent,
input::{KeyEvent, MouseButton, MouseEvent, MouseEventKind},
keyboard::{KeyCode, KeyModifiers},
Document, Editor, Theme, View,
};
use std::borrow::Cow;

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

use super::lsp::SignatureHelp;
Expand Down Expand Up @@ -966,7 +965,7 @@ impl EditorView {
if let Some((pos, view_id)) = pos_and_view(editor, row, column) {
let doc = editor.document_mut(editor.tree.get(view_id).doc).unwrap();

if modifiers == crossterm::event::KeyModifiers::ALT {
if modifiers == KeyModifiers::ALT {
let selection = doc.selection(view_id).clone();
doc.set_selection(view_id, selection.push(Range::point(pos)));
} else {
Expand Down Expand Up @@ -1068,7 +1067,7 @@ impl EditorView {
let line = coords.row + view.offset.row;
if let Ok(pos) = doc.text().try_line_to_char(line) {
doc.set_selection(view_id, Selection::point(pos));
if modifiers == crossterm::event::KeyModifiers::ALT {
if modifiers == KeyModifiers::ALT {
commands::MappableCommand::dap_edit_log.execute(cxt);
} else {
commands::MappableCommand::dap_edit_condition.execute(cxt);
Expand All @@ -1087,7 +1086,7 @@ impl EditorView {
return EventResult::Ignored(None);
}

if modifiers == crossterm::event::KeyModifiers::ALT {
if modifiers == KeyModifiers::ALT {
commands::MappableCommand::replace_selections_with_primary_clipboard
.execute(cxt);

Expand Down Expand Up @@ -1132,9 +1131,8 @@ impl Component for EditorView {
// Handling it here but not re-rendering will cause flashing
EventResult::Consumed(None)
}
Event::Key(key) => {
Event::Key(mut key) => {
cx.editor.reset_idle_timer();
let mut key = KeyEvent::from(key);
canonicalize_key(&mut key);

// clear status
Expand Down
5 changes: 2 additions & 3 deletions helix-term/src/ui/menu.rs
@@ -1,10 +1,9 @@
use std::{borrow::Cow, path::PathBuf};

use crate::{
compositor::{Callback, Component, Compositor, Context, EventResult},
compositor::{Callback, Component, Compositor, Context, Event, EventResult},
ctrl, key, shift,
};
use crossterm::event::Event;
use tui::{buffer::Buffer as Surface, text::Spans, widgets::Table};

pub use tui::widgets::{Cell, Row};
Expand Down Expand Up @@ -237,7 +236,7 @@ impl<T: Item + 'static> Component for Menu<T> {
compositor.pop();
}));

match event.into() {
match event {
// esc or ctrl-c aborts the completion and closes the menu
key!(Esc) | ctrl!('c') => {
(self.callback_fn)(cx.editor, self.selection(), MenuEvent::Abort);
Expand Down
3 changes: 1 addition & 2 deletions helix-term/src/ui/overlay.rs
@@ -1,12 +1,11 @@
use crossterm::event::Event;
use helix_core::Position;
use helix_view::{
graphics::{CursorKind, Rect},
Editor,
};
use tui::buffer::Buffer;

use crate::compositor::{Component, Context, EventResult};
use crate::compositor::{Component, Context, Event, EventResult};

/// Contains a component placed in the center of the parent component
pub struct Overlay<T> {
Expand Down
5 changes: 2 additions & 3 deletions helix-term/src/ui/picker.rs
@@ -1,9 +1,8 @@
use crate::{
compositor::{Component, Compositor, Context, EventResult},
compositor::{Component, Compositor, Context, Event, EventResult},
ctrl, key, shift,
ui::{self, EditorView},
};
use crossterm::event::Event;
use tui::{
buffer::Buffer as Surface,
widgets::{Block, BorderType, Borders},
Expand Down Expand Up @@ -502,7 +501,7 @@ impl<T: Item + 'static> Component for Picker<T> {
compositor.last_picker = compositor.pop();
})));

match key_event.into() {
match key_event {
shift!(Tab) | key!(Up) | ctrl!('p') => {
self.move_by(1, Direction::Backward);
}
Expand Down
7 changes: 3 additions & 4 deletions helix-term/src/ui/popup.rs
@@ -1,9 +1,8 @@
use crate::{
commands::Open,
compositor::{Callback, Component, Context, EventResult},
compositor::{Callback, Component, Context, Event, EventResult},
ctrl, key,
};
use crossterm::event::Event;
use tui::buffer::Buffer as Surface;

use helix_core::Position;
Expand Down Expand Up @@ -149,7 +148,7 @@ impl<T: Component> Component for Popup<T> {
_ => return EventResult::Ignored(None),
};

if key!(Esc) == key.into() && self.ignore_escape_key {
if key!(Esc) == key && self.ignore_escape_key {
return EventResult::Ignored(None);
}

Expand All @@ -158,7 +157,7 @@ impl<T: Component> Component for Popup<T> {
compositor.remove(self.id.as_ref());
});

match key.into() {
match key {
// esc or ctrl-c aborts the completion and closes the menu
key!(Esc) | ctrl!('c') => {
let _ = self.contents.handle_event(event, cx);
Expand Down
5 changes: 2 additions & 3 deletions helix-term/src/ui/prompt.rs
@@ -1,6 +1,5 @@
use crate::compositor::{Component, Compositor, Context, EventResult};
use crate::compositor::{Component, Compositor, Context, Event, EventResult};
use crate::{alt, ctrl, key, shift, ui};
use crossterm::event::Event;
use helix_view::input::KeyEvent;
use helix_view::keyboard::KeyCode;
use std::{borrow::Cow, ops::RangeFrom};
Expand Down Expand Up @@ -479,7 +478,7 @@ impl Component for Prompt {
compositor.pop();
})));

match event.into() {
match event {
ctrl!('c') | key!(Esc) => {
(self.callback_fn)(cx, &self.line, PromptEvent::Abort);
return close_fn;
Expand Down
102 changes: 101 additions & 1 deletion helix-view/src/input.rs
Expand Up @@ -4,8 +4,53 @@ use helix_core::unicode::{segmentation::UnicodeSegmentation, width::UnicodeWidth
use serde::de::{self, Deserialize, Deserializer};
use std::fmt;

use crate::keyboard::{KeyCode, KeyModifiers};
pub use crate::keyboard::{KeyCode, KeyModifiers};

#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash)]
pub enum Event {
Key(KeyEvent),
Mouse(MouseEvent),
Resize(u16, u16),
}

#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash)]
pub struct MouseEvent {
/// The kind of mouse event that was caused.
pub kind: MouseEventKind,
/// The column that the event occurred on.
pub column: u16,
/// The row that the event occurred on.
pub row: u16,
/// The key modifiers active when the event occurred.
pub modifiers: KeyModifiers,
}

#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash)]
pub enum MouseEventKind {
/// Pressed mouse button. Contains the button that was pressed.
Down(MouseButton),
/// Released mouse button. Contains the button that was released.
Up(MouseButton),
/// Moved the mouse cursor while pressing the contained mouse button.
Drag(MouseButton),
/// Moved the mouse cursor while not pressing a mouse button.
Moved,
/// Scrolled mouse wheel downwards (towards the user).
ScrollDown,
/// Scrolled mouse wheel upwards (away from the user).
ScrollUp,
}

/// Represents a mouse button.
#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash)]
pub enum MouseButton {
/// Left mouse button.
Left,
/// Right mouse button.
Right,
/// Middle mouse button.
Middle,
}
/// Represents a key event.
// We use a newtype here because we want to customize Deserialize and Display.
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
Expand Down Expand Up @@ -219,6 +264,61 @@ impl<'de> Deserialize<'de> for KeyEvent {
}
}

#[cfg(feature = "term")]
impl From<crossterm::event::Event> for Event {
fn from(event: crossterm::event::Event) -> Self {
match event {
crossterm::event::Event::Key(key) => Self::Key(key.into()),
crossterm::event::Event::Mouse(mouse) => Self::Mouse(mouse.into()),
crossterm::event::Event::Resize(w, h) => Self::Resize(w, h),
}
}
}

#[cfg(feature = "term")]
impl From<crossterm::event::MouseEvent> for MouseEvent {
fn from(
crossterm::event::MouseEvent {
kind,
column,
row,
modifiers,
}: crossterm::event::MouseEvent,
) -> Self {
Self {
kind: kind.into(),
column,
row,
modifiers: modifiers.into(),
}
}
}

#[cfg(feature = "term")]
impl From<crossterm::event::MouseEventKind> for MouseEventKind {
fn from(kind: crossterm::event::MouseEventKind) -> Self {
match kind {
crossterm::event::MouseEventKind::Down(button) => Self::Down(button.into()),
crossterm::event::MouseEventKind::Up(button) => Self::Down(button.into()),
crossterm::event::MouseEventKind::Drag(button) => Self::Drag(button.into()),
crossterm::event::MouseEventKind::Moved => Self::Moved,
crossterm::event::MouseEventKind::ScrollDown => Self::ScrollDown,
crossterm::event::MouseEventKind::ScrollUp => Self::ScrollUp,
}
}
}

#[cfg(feature = "term")]
impl From<crossterm::event::MouseButton> for MouseButton {
fn from(button: crossterm::event::MouseButton) -> Self {
match button {
crossterm::event::MouseButton::Left => MouseButton::Left,
crossterm::event::MouseButton::Right => MouseButton::Right,
crossterm::event::MouseButton::Middle => MouseButton::Middle,
}
}
}

#[cfg(feature = "term")]
impl From<crossterm::event::KeyEvent> for KeyEvent {
fn from(crossterm::event::KeyEvent { code, modifiers }: crossterm::event::KeyEvent) -> Self {
Expand Down
1 change: 0 additions & 1 deletion helix-view/src/keyboard.rs
Expand Up @@ -55,7 +55,6 @@ impl From<crossterm::event::KeyModifiers> for KeyModifiers {

/// Represents a key.
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum KeyCode {
/// Backspace key.
Backspace,
Expand Down