@@ -36,25 +36,35 @@ use std::{
36
36
sync:: Arc ,
37
37
} ;
38
38
39
+ #[ cfg_attr( windows, allow( unused_imports) ) ]
39
40
use anyhow:: { Context , Error } ;
40
41
41
42
#[ cfg( not( windows) ) ]
42
43
use { signal_hook:: consts:: signal, signal_hook_tokio:: Signals } ;
43
44
#[ cfg( windows) ]
44
45
type Signals = futures_util:: stream:: Empty < ( ) > ;
45
46
46
- #[ cfg( not( feature = "integration" ) ) ]
47
+ #[ cfg( all ( not( windows ) , not ( feature = "integration" ) ) ) ]
47
48
use tui:: backend:: TerminaBackend ;
48
49
50
+ #[ cfg( all( windows, not( feature = "integration" ) ) ) ]
51
+ use tui:: backend:: CrosstermBackend ;
52
+
49
53
#[ cfg( feature = "integration" ) ]
50
54
use tui:: backend:: TestBackend ;
51
55
52
- #[ cfg( not( feature = "integration" ) ) ]
56
+ #[ cfg( all ( not( windows ) , not ( feature = "integration" ) ) ) ]
53
57
type TerminalBackend = TerminaBackend ;
54
-
58
+ #[ cfg( all( windows, not( feature = "integration" ) ) ) ]
59
+ type TerminalBackend = CrosstermBackend < std:: io:: Stdout > ;
55
60
#[ cfg( feature = "integration" ) ]
56
61
type TerminalBackend = TestBackend ;
57
62
63
+ #[ cfg( not( windows) ) ]
64
+ type TerminalEvent = termina:: Event ;
65
+ #[ cfg( windows) ]
66
+ type TerminalEvent = crossterm:: event:: Event ;
67
+
58
68
type Terminal = tui:: terminal:: Terminal < TerminalBackend > ;
59
69
60
70
pub struct Application {
@@ -102,9 +112,11 @@ impl Application {
102
112
theme_parent_dirs. extend ( helix_loader:: runtime_dirs ( ) . iter ( ) . cloned ( ) ) ;
103
113
let theme_loader = theme:: Loader :: new ( & theme_parent_dirs) ;
104
114
105
- #[ cfg( not( feature = "integration" ) ) ]
115
+ #[ cfg( all ( not( windows ) , not ( feature = "integration" ) ) ) ]
106
116
let backend = TerminaBackend :: new ( ( & config. editor ) . into ( ) )
107
117
. context ( "failed to create terminal backend" ) ?;
118
+ #[ cfg( all( windows, not( feature = "integration" ) ) ) ]
119
+ let backend = CrosstermBackend :: new ( std:: io:: stdout ( ) , ( & config. editor ) . into ( ) ) ;
108
120
109
121
#[ cfg( feature = "integration" ) ]
110
122
let backend = TestBackend :: new ( 120 , 150 ) ;
@@ -286,7 +298,7 @@ impl Application {
286
298
287
299
pub async fn event_loop < S > ( & mut self , input_stream : & mut S )
288
300
where
289
- S : Stream < Item = std:: io:: Result < termina :: Event > > + Unpin ,
301
+ S : Stream < Item = std:: io:: Result < TerminalEvent > > + Unpin ,
290
302
{
291
303
self . render ( ) . await ;
292
304
@@ -299,7 +311,7 @@ impl Application {
299
311
300
312
pub async fn event_loop_until_idle < S > ( & mut self , input_stream : & mut S ) -> bool
301
313
where
302
- S : Stream < Item = std:: io:: Result < termina :: Event > > + Unpin ,
314
+ S : Stream < Item = std:: io:: Result < TerminalEvent > > + Unpin ,
303
315
{
304
316
loop {
305
317
if self . editor . should_close ( ) {
@@ -659,14 +671,15 @@ impl Application {
659
671
false
660
672
}
661
673
662
- pub async fn handle_terminal_events ( & mut self , event : std:: io:: Result < termina :: Event > ) {
674
+ pub async fn handle_terminal_events ( & mut self , event : std:: io:: Result < TerminalEvent > ) {
663
675
let mut cx = crate :: compositor:: Context {
664
676
editor : & mut self . editor ,
665
677
jobs : & mut self . jobs ,
666
678
scroll : None ,
667
679
} ;
668
680
// Handle key events
669
681
let should_redraw = match event. unwrap ( ) {
682
+ #[ cfg( not( windows) ) ]
670
683
termina:: Event :: WindowResized ( termina:: WindowSize { rows, cols, .. } ) => {
671
684
self . terminal
672
685
. resize ( Rect :: new ( 0 , 0 , cols, rows) )
@@ -679,11 +692,31 @@ impl Application {
679
692
self . compositor
680
693
. handle_event ( & Event :: Resize ( cols, rows) , & mut cx)
681
694
}
695
+ #[ cfg( not( windows) ) ]
682
696
// Ignore keyboard release events.
683
697
termina:: Event :: Key ( termina:: event:: KeyEvent {
684
698
kind : termina:: event:: KeyEventKind :: Release ,
685
699
..
686
700
} ) => false ,
701
+ #[ cfg( windows) ]
702
+ TerminalEvent :: Resize ( width, height) => {
703
+ self . terminal
704
+ . resize ( Rect :: new ( 0 , 0 , width, height) )
705
+ . expect ( "Unable to resize terminal" ) ;
706
+
707
+ let area = self . terminal . size ( ) . expect ( "couldn't get terminal size" ) ;
708
+
709
+ self . compositor . resize ( area) ;
710
+
711
+ self . compositor
712
+ . handle_event ( & Event :: Resize ( width, height) , & mut cx)
713
+ }
714
+ #[ cfg( windows) ]
715
+ // Ignore keyboard release events.
716
+ crossterm:: event:: Event :: Key ( crossterm:: event:: KeyEvent {
717
+ kind : crossterm:: event:: KeyEventKind :: Release ,
718
+ ..
719
+ } ) => false ,
687
720
event => self . compositor . handle_event ( & event. into ( ) , & mut cx) ,
688
721
} ;
689
722
@@ -1132,15 +1165,20 @@ impl Application {
1132
1165
self . terminal . restore ( )
1133
1166
}
1134
1167
1135
- #[ cfg( not( feature = "integration" ) ) ]
1136
- pub fn event_stream ( & self ) -> impl Stream < Item = std:: io:: Result < termina :: Event > > + Unpin {
1168
+ #[ cfg( all ( not( feature = "integration" ) , not ( windows ) ) ) ]
1169
+ pub fn event_stream ( & self ) -> impl Stream < Item = std:: io:: Result < TerminalEvent > > + Unpin {
1137
1170
use termina:: Terminal as _;
1138
1171
let reader = self . terminal . backend ( ) . terminal ( ) . event_reader ( ) ;
1139
1172
termina:: EventStream :: new ( reader, |event| !event. is_escape ( ) )
1140
1173
}
1141
1174
1175
+ #[ cfg( all( not( feature = "integration" ) , windows) ) ]
1176
+ pub fn event_stream ( & self ) -> impl Stream < Item = std:: io:: Result < TerminalEvent > > + Unpin {
1177
+ crossterm:: event:: EventStream :: new ( )
1178
+ }
1179
+
1142
1180
#[ cfg( feature = "integration" ) ]
1143
- pub fn event_stream ( & self ) -> impl Stream < Item = std:: io:: Result < termina :: Event > > + Unpin {
1181
+ pub fn event_stream ( & self ) -> impl Stream < Item = std:: io:: Result < TerminalEvent > > + Unpin {
1144
1182
use std:: {
1145
1183
pin:: Pin ,
1146
1184
task:: { Context , Poll } ,
@@ -1150,7 +1188,7 @@ impl Application {
1150
1188
pub struct DummyEventStream ;
1151
1189
1152
1190
impl Stream for DummyEventStream {
1153
- type Item = std:: io:: Result < termina :: Event > ;
1191
+ type Item = std:: io:: Result < TerminalEvent > ;
1154
1192
1155
1193
fn poll_next ( self : Pin < & mut Self > , _cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
1156
1194
Poll :: Pending
@@ -1162,7 +1200,7 @@ impl Application {
1162
1200
1163
1201
pub async fn run < S > ( & mut self , input_stream : & mut S ) -> Result < i32 , Error >
1164
1202
where
1165
- S : Stream < Item = std:: io:: Result < termina :: Event > > + Unpin ,
1203
+ S : Stream < Item = std:: io:: Result < TerminalEvent > > + Unpin ,
1166
1204
{
1167
1205
self . terminal . claim ( ) ?;
1168
1206
0 commit comments