aboutsummaryrefslogtreecommitdiff
path: root/helix-tui
diff options
context:
space:
mode:
Diffstat (limited to 'helix-tui')
-rw-r--r--helix-tui/Cargo.toml1
-rw-r--r--helix-tui/src/backend/crossterm.rs70
-rw-r--r--helix-tui/src/backend/mod.rs5
-rw-r--r--helix-tui/src/backend/test.rs13
-rw-r--r--helix-tui/src/terminal.rs22
5 files changed, 109 insertions, 2 deletions
diff --git a/helix-tui/Cargo.toml b/helix-tui/Cargo.toml
index ccd016f5..3ca7e044 100644
--- a/helix-tui/Cargo.toml
+++ b/helix-tui/Cargo.toml
@@ -22,5 +22,6 @@ unicode-segmentation = "1.10"
crossterm = { version = "0.26", optional = true }
termini = "0.1"
serde = { version = "1", "optional" = true, features = ["derive"]}
+log = "~0.4"
helix-view = { version = "0.6", path = "../helix-view", features = ["term"] }
helix-core = { version = "0.6", path = "../helix-core" }
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 {