@@ -30,22 +30,14 @@ use crate::{
3030
3131use log::{debug, error, warn};
3232use std::{
33− io::{stdin, stdout, Write},
33+ io::{stdin, stdout},
3434 sync::Arc,
3535 time::{Duration, Instant},
3636};
3737
3838use anyhow::{Context, Error};
3939
40−use crossterm::{
41− event::{
42− DisableBracketedPaste, DisableFocusChange, DisableMouseCapture, EnableBracketedPaste,
43− EnableFocusChange, EnableMouseCapture, Event as CrosstermEvent, KeyboardEnhancementFlags,
44− PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags,
45− },
46− execute, terminal,
47− tty::IsTty,
48−};
40+use crossterm::{event::Event as CrosstermEvent, tty::IsTty};
4941#[cfg(not(windows))]
5042use {
5143 signal_hook::{consts::signal, low_level},
@@ -63,10 +55,12 @@ use tui::backend::CrosstermBackend;
6355use tui::backend::TestBackend;
6456
6557#[cfg(not(feature = "integration"))]
66−type Terminal = tui::terminal::Terminal<CrosstermBackend<std::io::Stdout>>;
58+type TerminalBackend = CrosstermBackend<std::io::Stdout>;
6759
6860#[cfg(feature = "integration")]
69−type Terminal = tui::terminal::Terminal<TestBackend>;
61+type TerminalBackend = TestBackend;
62+
63+type Terminal = tui::terminal::Terminal<TerminalBackend>;
7064
7165pub struct Application {
7266 compositor: Compositor,
@@ -108,26 +102,6 @@ fn setup_integration_logging() {
108102 .apply();
109103}
110104
111−fn restore_term() -> Result<(), Error> {
112− let mut stdout = stdout();
113− // reset cursor shape
114− write!(stdout, "\x1B[0 q")?;
115− if matches!(terminal::supports_keyboard_enhancement(), Ok(true)) {
116− execute!(stdout, PopKeyboardEnhancementFlags)?;
117− }
118− // Ignore errors on disabling, this might trigger on windows if we call
119− // disable without calling enable previously
120− let _ = execute!(stdout, DisableMouseCapture);
121− execute!(
122− stdout,
123− DisableBracketedPaste,
124− DisableFocusChange,
125− terminal::LeaveAlternateScreen
126− )?;
127− terminal::disable_raw_mode()?;
128− Ok(())
129−}
130−
131105impl Application {
132106 pub fn new(
133107 args: Args,
@@ -472,13 +446,7 @@ impl Application {
472446 pub async fn handle_signals(&mut self, signal: i32) {
473447 match signal {
474448 signal::SIGTSTP => {
475− // restore cursor
476− use helix_view::graphics::CursorKind;
477− self.terminal
478− .backend_mut()
479− .show_cursor(CursorKind::Block)
480− .ok();
481− restore_term().unwrap();
449+ self.restore_term().unwrap();
482450 low_level::emulate_default_handler(signal::SIGTSTP).unwrap();
483451 }
484452 signal::SIGCONT => {
@@ -1054,37 +1022,19 @@ impl Application {
10541022 }
10551023 }
10561024
1057− async fn claim_term(&mut self) -> Result<(), Error> {
1058− use helix_view::graphics::CursorKind;
1059− terminal::enable_raw_mode()?;
1060− if self.terminal.cursor_kind() == CursorKind::Hidden {
1061− self.terminal.backend_mut().hide_cursor().ok();
1062− }
1063− let mut stdout = stdout();
1064− execute!(
1065− stdout,
1066− terminal::EnterAlternateScreen,
1067− EnableBracketedPaste,
1068− EnableFocusChange
1069− )?;
1070− execute!(stdout, terminal::Clear(terminal::ClearType::All))?;
1071− if self.config.load().editor.mouse {
1072− execute!(stdout, EnableMouseCapture)?;
1073− }
1074− if matches!(terminal::supports_keyboard_enhancement(), Ok(true)) {
1075− log::debug!("The enhanced keyboard protocol is supported on this terminal");
1076− execute!(
1077− stdout,
1078− PushKeyboardEnhancementFlags(
1079− KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES
1080− | KeyboardEnhancementFlags::REPORT_ALTERNATE_KEYS
1081− )
1082− )?;
1083− } else {
1084− log::debug!("The enhanced keyboard protocol is not supported on this terminal");
1085− }
1025+ async fn claim_term(&mut self) -> std::io::Result<()> {
1026+ let terminal_config = self.config.load().editor.clone().into();
1027+ self.terminal.claim(terminal_config)
1028+ }
10861029
1087− Ok(())
1030+ fn restore_term(&mut self) -> std::io::Result<()> {
1031+ let terminal_config = self.config.load().editor.clone().into();
1032+ use helix_view::graphics::CursorKind;
1033+ self.terminal
1034+ .backend_mut()
1035+ .show_cursor(CursorKind::Block)
1036+ .ok();
1037+ self.terminal.restore(terminal_config)
10881038 }
10891039
10901040 pub async fn run<S>(&mut self, input_stream: &mut S) -> Result<i32, Error>
@@ -1099,7 +1049,7 @@ impl Application {
10991049 // We can't handle errors properly inside this closure. And it's
11001050 // probably not a good idea to `unwrap()` inside a panic handler.
11011051 // So we just ignore the `Result`.
1102− let _ = restore_term();
1052+ let _ = TerminalBackend::force_restore();
11031053 hook(info);
11041054 }));
11051055
@@ -1107,13 +1057,7 @@ impl Application {
11071057
11081058 let close_errs = self.close().await;
11091059
1110− // restore cursor
1111− use helix_view::graphics::CursorKind;
1112− self.terminal
1113− .backend_mut()
1114− .show_cursor(CursorKind::Block)
1115− .ok();
1116− restore_term()?;
1060+ self.restore_term()?;
11171061
11181062 for err in close_errs {
11191063 self.editor.exit_code = 1;