Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-term/src/application.rs')
-rw-r--r--helix-term/src/application.rs62
1 files changed, 50 insertions, 12 deletions
diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs
index c402633c..9ee02a53 100644
--- a/helix-term/src/application.rs
+++ b/helix-term/src/application.rs
@@ -36,6 +36,7 @@ use std::{
sync::Arc,
};
+#[cfg_attr(windows, allow(unused_imports))]
use anyhow::{Context, Error};
#[cfg(not(windows))]
@@ -43,18 +44,27 @@ use {signal_hook::consts::signal, signal_hook_tokio::Signals};
#[cfg(windows)]
type Signals = futures_util::stream::Empty<()>;
-#[cfg(not(feature = "integration"))]
+#[cfg(all(not(windows), not(feature = "integration")))]
use tui::backend::TerminaBackend;
+#[cfg(all(windows, not(feature = "integration")))]
+use tui::backend::CrosstermBackend;
+
#[cfg(feature = "integration")]
use tui::backend::TestBackend;
-#[cfg(not(feature = "integration"))]
+#[cfg(all(not(windows), not(feature = "integration")))]
type TerminalBackend = TerminaBackend;
-
+#[cfg(all(windows, not(feature = "integration")))]
+type TerminalBackend = CrosstermBackend<std::io::Stdout>;
#[cfg(feature = "integration")]
type TerminalBackend = TestBackend;
+#[cfg(not(windows))]
+type TerminalEvent = termina::Event;
+#[cfg(windows)]
+type TerminalEvent = crossterm::event::Event;
+
type Terminal = tui::terminal::Terminal<TerminalBackend>;
pub struct Application {
@@ -102,9 +112,11 @@ impl Application {
theme_parent_dirs.extend(helix_loader::runtime_dirs().iter().cloned());
let theme_loader = theme::Loader::new(&theme_parent_dirs);
- #[cfg(not(feature = "integration"))]
+ #[cfg(all(not(windows), not(feature = "integration")))]
let backend = TerminaBackend::new((&config.editor).into())
.context("failed to create terminal backend")?;
+ #[cfg(all(windows, not(feature = "integration")))]
+ let backend = CrosstermBackend::new(std::io::stdout(), (&config.editor).into());
#[cfg(feature = "integration")]
let backend = TestBackend::new(120, 150);
@@ -286,7 +298,7 @@ impl Application {
pub async fn event_loop<S>(&mut self, input_stream: &mut S)
where
- S: Stream<Item = std::io::Result<termina::Event>> + Unpin,
+ S: Stream<Item = std::io::Result<TerminalEvent>> + Unpin,
{
self.render().await;
@@ -299,7 +311,7 @@ impl Application {
pub async fn event_loop_until_idle<S>(&mut self, input_stream: &mut S) -> bool
where
- S: Stream<Item = std::io::Result<termina::Event>> + Unpin,
+ S: Stream<Item = std::io::Result<TerminalEvent>> + Unpin,
{
loop {
if self.editor.should_close() {
@@ -659,7 +671,7 @@ impl Application {
false
}
- pub async fn handle_terminal_events(&mut self, event: std::io::Result<termina::Event>) {
+ pub async fn handle_terminal_events(&mut self, event: std::io::Result<TerminalEvent>) {
let mut cx = crate::compositor::Context {
editor: &mut self.editor,
jobs: &mut self.jobs,
@@ -667,6 +679,7 @@ impl Application {
};
// Handle key events
let should_redraw = match event.unwrap() {
+ #[cfg(not(windows))]
termina::Event::WindowResized(termina::WindowSize { rows, cols, .. }) => {
self.terminal
.resize(Rect::new(0, 0, cols, rows))
@@ -679,11 +692,31 @@ impl Application {
self.compositor
.handle_event(&Event::Resize(cols, rows), &mut cx)
}
+ #[cfg(not(windows))]
// Ignore keyboard release events.
termina::Event::Key(termina::event::KeyEvent {
kind: termina::event::KeyEventKind::Release,
..
}) => false,
+ #[cfg(windows)]
+ TerminalEvent::Resize(width, height) => {
+ self.terminal
+ .resize(Rect::new(0, 0, width, height))
+ .expect("Unable to resize terminal");
+
+ let area = self.terminal.size().expect("couldn't get terminal size");
+
+ self.compositor.resize(area);
+
+ self.compositor
+ .handle_event(&Event::Resize(width, height), &mut cx)
+ }
+ #[cfg(windows)]
+ // Ignore keyboard release events.
+ crossterm::event::Event::Key(crossterm::event::KeyEvent {
+ kind: crossterm::event::KeyEventKind::Release,
+ ..
+ }) => false,
event => self.compositor.handle_event(&event.into(), &mut cx),
};
@@ -1132,15 +1165,20 @@ impl Application {
self.terminal.restore()
}
- #[cfg(not(feature = "integration"))]
- pub fn event_stream(&self) -> impl Stream<Item = std::io::Result<termina::Event>> + Unpin {
+ #[cfg(all(not(feature = "integration"), not(windows)))]
+ pub fn event_stream(&self) -> impl Stream<Item = std::io::Result<TerminalEvent>> + Unpin {
use termina::Terminal as _;
let reader = self.terminal.backend().terminal().event_reader();
termina::EventStream::new(reader, |event| !event.is_escape())
}
+ #[cfg(all(not(feature = "integration"), windows))]
+ pub fn event_stream(&self) -> impl Stream<Item = std::io::Result<TerminalEvent>> + Unpin {
+ crossterm::event::EventStream::new()
+ }
+
#[cfg(feature = "integration")]
- pub fn event_stream(&self) -> impl Stream<Item = std::io::Result<termina::Event>> + Unpin {
+ pub fn event_stream(&self) -> impl Stream<Item = std::io::Result<TerminalEvent>> + Unpin {
use std::{
pin::Pin,
task::{Context, Poll},
@@ -1150,7 +1188,7 @@ impl Application {
pub struct DummyEventStream;
impl Stream for DummyEventStream {
- type Item = std::io::Result<termina::Event>;
+ type Item = std::io::Result<TerminalEvent>;
fn poll_next(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
Poll::Pending
@@ -1162,7 +1200,7 @@ impl Application {
pub async fn run<S>(&mut self, input_stream: &mut S) -> Result<i32, Error>
where
- S: Stream<Item = std::io::Result<termina::Event>> + Unpin,
+ S: Stream<Item = std::io::Result<TerminalEvent>> + Unpin,
{
self.terminal.claim()?;