@@ -18,6 +18,10 @@ use crossterm::{
18 event::{DisableMouseCapture, EnableMouseCapture, Event, EventStream},
18 event::{DisableMouseCapture, EnableMouseCapture, Event, EventStream},
19 execute, terminal,
19 execute, terminal,
22+use signal_hook::{consts::signal, low_level};
24+use signal_hook_tokio::Signals;
22pub struct Application {
26pub struct Application {
23 compositor: Compositor,
27 compositor: Compositor,
@@ -36,6 +40,8 @@ pub struct Application {
36 #[allow(dead_code)]
40 #[allow(dead_code)]
37 syn_loader: Arc<syntax::Loader>,
41 syn_loader: Arc<syntax::Loader>,
39 jobs: Jobs,
45 jobs: Jobs,
40 lsp_progress: LspProgressMap,
46 lsp_progress: LspProgressMap,
@@ -102,6 +108,9 @@ impl Application {
103 editor.set_theme(theme);
109 editor.set_theme(theme);
111+ #[cfg(not(windows))]
112+ let signals = Signals::new(&[signal::SIGTSTP, signal::SIGCONT])?;
105 let app = Self {
114 let app = Self {
106 compositor,
115 compositor,
@@ -111,6 +120,8 @@ impl Application {
111 theme_loader,
120 theme_loader,
112 syn_loader,
121 syn_loader,
123+ #[cfg(not(windows))]
114 jobs: Jobs::new(),
125 jobs: Jobs::new(),
115 lsp_progress: LspProgressMap::new(),
126 lsp_progress: LspProgressMap::new(),
@@ -147,6 +158,51 @@ impl Application {
148 use futures_util::StreamExt;
159 use futures_util::StreamExt;
161+ #[cfg(not(windows))]
165+ event = reader.next() => {
166+ self.handle_terminal_events(event)
168+ Some(signal) = self.signals.next() => {
169+ use helix_view::graphics::Rect;
171+ signal::SIGTSTP => {
172+ self.compositor.save_cursor();
173+ self.restore_term().unwrap();
174+ low_level::emulate_default_handler(signal::SIGTSTP).unwrap();
176+ signal::SIGCONT => {
177+ self.claim_term().await.unwrap();
178+ // redraw the terminal
179+ let Rect { width, height, .. } = self.compositor.size();
180+ self.compositor.resize(width, height);
181+ self.compositor.load_cursor();
184+ _ => unreachable!(),
187+ Some((id, call)) = self.editor.language_servers.incoming.next() => {
188+ self.handle_language_server_message(call, id).await;
189+ // limit render calls for fast language server messages
190+ let last = self.editor.language_servers.incoming.is_empty();
191+ if last || last_render.elapsed() > deadline {
193+ last_render = Instant::now();
196+ Some(callback) = self.jobs.futures.next() => {
197+ self.jobs.handle_callback(&mut self.editor, &mut self.compositor, callback);
200+ Some(callback) = self.jobs.wait_futures.next() => {
201+ self.jobs.handle_callback(&mut self.editor, &mut self.compositor, callback);
150 tokio::select! {
206 tokio::select! {
@@ -443,15 +499,29 @@ impl Application {
446− pub async fn run(&mut self) -> Result<(), Error> {
502+ async fn claim_term(&mut self) -> Result<(), Error> {
447 terminal::enable_raw_mode()?;
503 terminal::enable_raw_mode()?;
449 let mut stdout = stdout();
504 let mut stdout = stdout();
451 execute!(stdout, terminal::EnterAlternateScreen)?;
505 execute!(stdout, terminal::EnterAlternateScreen)?;
506+ self.editor.close_language_servers(None).await?;
452 if self.config.terminal.mouse {
507 if self.config.terminal.mouse {
453 execute!(stdout, EnableMouseCapture)?;
508 execute!(stdout, EnableMouseCapture)?;
513+ fn restore_term(&mut self) -> Result<(), Error> {
514+ let mut stdout = stdout();
515+ // reset cursor shape
516+ write!(stdout, "\x1B[2 q")?;
517+ execute!(stdout, DisableMouseCapture)?;
518+ execute!(stdout, terminal::LeaveAlternateScreen)?;
519+ terminal::disable_raw_mode()?;
523+ pub async fn run(&mut self) -> Result<(), Error> {
524+ self.claim_term().await?;
456 // Exit the alternate screen and disable raw mode before panicking
526 // Exit the alternate screen and disable raw mode before panicking
457 let hook = std::panic::take_hook();
527 let hook = std::panic::take_hook();
@@ -469,13 +539,7 @@ impl Application {
470 self.editor.close_language_servers(None).await?;
540 self.editor.close_language_servers(None).await?;
472− // reset cursor shape
542+ self.restore_term()?;
473− write!(stdout, "\x1B[2 q")?;
475− execute!(stdout, DisableMouseCapture)?;
476− execute!(stdout, terminal::LeaveAlternateScreen)?;
478− terminal::disable_raw_mode()?;