diff options
Diffstat (limited to 'helix-tui/src')
-rw-r--r-- | helix-tui/src/backend/crossterm.rs | 70 | ||||
-rw-r--r-- | helix-tui/src/backend/mod.rs | 5 | ||||
-rw-r--r-- | helix-tui/src/backend/test.rs | 13 | ||||
-rw-r--r-- | helix-tui/src/terminal.rs | 22 |
4 files changed, 108 insertions, 2 deletions
diff --git a/helix-tui/src/backend/crossterm.rs b/helix-tui/src/backend/crossterm.rs index 5305640c..e81c1e00 100644 --- a/helix-tui/src/backend/crossterm.rs +++ b/helix-tui/src/backend/crossterm.rs @@ -1,6 +1,11 @@ -use crate::{backend::Backend, buffer::Cell}; +use crate::{backend::Backend, buffer::Cell, terminal::Config}; use crossterm::{ cursor::{Hide, MoveTo, SetCursorStyle, Show}, + event::{ + DisableBracketedPaste, DisableFocusChange, DisableMouseCapture, EnableBracketedPaste, + EnableFocusChange, EnableMouseCapture, KeyboardEnhancementFlags, + PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags, + }, execute, queue, style::{ Attribute as CAttribute, Color as CColor, Print, SetAttribute, SetBackgroundColor, @@ -83,6 +88,69 @@ impl<W> Backend for CrosstermBackend<W> where W: Write, { + fn claim(&mut self, config: Config) -> io::Result<()> { + terminal::enable_raw_mode()?; + execute!( + self.buffer, + terminal::EnterAlternateScreen, + EnableBracketedPaste, + EnableFocusChange + )?; + execute!(self.buffer, terminal::Clear(terminal::ClearType::All))?; + if config.enable_mouse_capture { + execute!(self.buffer, EnableMouseCapture)?; + } + if matches!(terminal::supports_keyboard_enhancement(), Ok(true)) { + log::debug!("The enhanced keyboard protocol is supported on this terminal"); + execute!( + self.buffer, + PushKeyboardEnhancementFlags( + KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES + | KeyboardEnhancementFlags::REPORT_ALTERNATE_KEYS + ) + )?; + } else { + log::debug!("The enhanced keyboard protocol is not supported on this terminal"); + } + Ok(()) + } + + fn restore(&mut self, config: Config) -> io::Result<()> { + // reset cursor shape + write!(self.buffer, "\x1B[0 q")?; + if config.enable_mouse_capture { + execute!(self.buffer, DisableMouseCapture)?; + } + if matches!(terminal::supports_keyboard_enhancement(), Ok(true)) { + execute!(self.buffer, PopKeyboardEnhancementFlags)?; + } + execute!( + self.buffer, + DisableBracketedPaste, + DisableFocusChange, + terminal::LeaveAlternateScreen + )?; + terminal::disable_raw_mode() + } + + fn force_restore() -> io::Result<()> { + let mut stdout = io::stdout(); + + // reset cursor shape + write!(stdout, "\x1B[0 q")?; + // Ignore errors on disabling, this might trigger on windows if we call + // disable without calling enable previously + let _ = execute!(stdout, DisableMouseCapture); + let _ = execute!(stdout, PopKeyboardEnhancementFlags); + execute!( + stdout, + DisableBracketedPaste, + DisableFocusChange, + terminal::LeaveAlternateScreen + )?; + terminal::disable_raw_mode() + } + fn draw<'a, I>(&mut self, content: I) -> io::Result<()> where I: Iterator<Item = (u16, u16, &'a Cell)>, diff --git a/helix-tui/src/backend/mod.rs b/helix-tui/src/backend/mod.rs index c6c11019..6d7c3894 100644 --- a/helix-tui/src/backend/mod.rs +++ b/helix-tui/src/backend/mod.rs @@ -1,6 +1,6 @@ use std::io; -use crate::buffer::Cell; +use crate::{buffer::Cell, terminal::Config}; use helix_view::graphics::{CursorKind, Rect}; @@ -13,6 +13,9 @@ mod test; pub use self::test::TestBackend; pub trait Backend { + fn claim(&mut self, config: Config) -> Result<(), io::Error>; + fn restore(&mut self, config: Config) -> Result<(), io::Error>; + fn force_restore() -> Result<(), io::Error>; fn draw<'a, I>(&mut self, content: I) -> Result<(), io::Error> where I: Iterator<Item = (u16, u16, &'a Cell)>; diff --git a/helix-tui/src/backend/test.rs b/helix-tui/src/backend/test.rs index 52474148..ff133ff3 100644 --- a/helix-tui/src/backend/test.rs +++ b/helix-tui/src/backend/test.rs @@ -1,6 +1,7 @@ use crate::{ backend::Backend, buffer::{Buffer, Cell}, + terminal::Config, }; use helix_core::unicode::width::UnicodeWidthStr; use helix_view::graphics::{CursorKind, Rect}; @@ -106,6 +107,18 @@ impl TestBackend { } impl Backend for TestBackend { + fn claim(&mut self, _config: Config) -> Result<(), io::Error> { + Ok(()) + } + + fn restore(&mut self, _config: Config) -> Result<(), io::Error> { + Ok(()) + } + + fn force_restore() -> Result<(), io::Error> { + Ok(()) + } + fn draw<'a, I>(&mut self, content: I) -> Result<(), io::Error> where I: Iterator<Item = (u16, u16, &'a Cell)>, diff --git a/helix-tui/src/terminal.rs b/helix-tui/src/terminal.rs index 22e9232f..802a8c1d 100644 --- a/helix-tui/src/terminal.rs +++ b/helix-tui/src/terminal.rs @@ -1,4 +1,5 @@ use crate::{backend::Backend, buffer::Buffer}; +use helix_view::editor::Config as EditorConfig; use helix_view::graphics::{CursorKind, Rect}; use std::io; @@ -16,6 +17,19 @@ pub struct Viewport { resize_behavior: ResizeBehavior, } +#[derive(Debug)] +pub struct Config { + pub enable_mouse_capture: bool, +} + +impl From<EditorConfig> for Config { + fn from(config: EditorConfig) -> Self { + Self { + enable_mouse_capture: config.mouse, + } + } +} + impl Viewport { /// UNSTABLE pub fn fixed(area: Rect) -> Viewport { @@ -98,6 +112,14 @@ where }) } + pub fn claim(&mut self, config: Config) -> io::Result<()> { + self.backend.claim(config) + } + + pub fn restore(&mut self, config: Config) -> io::Result<()> { + self.backend.restore(config) + } + // /// Get a Frame object which provides a consistent view into the terminal state for rendering. // pub fn get_frame(&mut self) -> Frame<B> { // Frame { |