@@ -10,11 +10,13 @@ use helix_view::{
10 align_view,
10 align_view,
11 document::DocumentSavedEventResult,
11 document::DocumentSavedEventResult,
12 editor::{ConfigEvent, EditorEvent},
12 editor::{ConfigEvent, EditorEvent},
14 tree::Layout,
15 tree::Layout,
15 Align, Editor,
16 Align, Editor,
17use serde_json::json;
18use serde_json::json;
19+use tui::backend::Backend;
19use crate::{
21use crate::{
20 args::Args,
22 args::Args,
@@ -53,8 +55,18 @@ type Signals = futures_util::stream::Empty<()>;
54const LSP_DEADLINE: Duration = Duration::from_millis(16);
56const LSP_DEADLINE: Duration = Duration::from_millis(16);
58+#[cfg(not(feature = "integration"))]
59+use tui::backend::CrosstermBackend;
61+#[cfg(not(feature = "integration"))]
62+type Terminal = tui::terminal::Terminal<CrosstermBackend<std::io::Stdout>>;
64+#[cfg(feature = "integration")]
65+type Terminal = tui::terminal::Terminal<TestBackend>;
56pub struct Application {
67pub struct Application {
57 compositor: Compositor,
68 compositor: Compositor,
58 pub editor: Editor,
70 pub editor: Editor,
60 config: Arc<ArcSwap<Config>>,
72 config: Arc<ArcSwap<Config>>,
@@ -143,10 +155,18 @@ impl Application {
144 let syn_loader = std::sync::Arc::new(syntax::Loader::new(syn_loader_conf));
156 let syn_loader = std::sync::Arc::new(syntax::Loader::new(syn_loader_conf));
158+ #[cfg(not(feature = "integration"))]
159+ let backend = CrosstermBackend::new(stdout());
161+ #[cfg(feature = "integration")]
162+ let backend = TestBackend::new(120, 150);
164+ let terminal = Terminal::new(backend)?;
165+ let area = terminal.size().expect("couldn't get terminal size");
146− let mut compositor = Compositor::new().context("build compositor")?;
166+ let mut compositor = Compositor::new(area);
147 let config = Arc::new(ArcSwap::from_pointee(config));
167 let config = Arc::new(ArcSwap::from_pointee(config));
148 let mut editor = Editor::new(
168 let mut editor = Editor::new(
149− compositor.size(),
169+ area,
150 theme_loader.clone(),
170 theme_loader.clone(),
151 syn_loader.clone(),
171 syn_loader.clone(),
152 Box::new(Map::new(Arc::clone(&config), |config: &Config| {
172 Box::new(Map::new(Arc::clone(&config), |config: &Config| {
@@ -233,6 +253,7 @@ impl Application {
234 let app = Self {
254 let app = Self {
235 compositor,
255 compositor,
@@ -254,15 +275,26 @@ impl Application {
255 #[cfg(not(feature = "integration"))]
276 #[cfg(not(feature = "integration"))]
256 fn render(&mut self) {
277 fn render(&mut self) {
257− let compositor = &mut self.compositor;
259 let mut cx = crate::compositor::Context {
278 let mut cx = crate::compositor::Context {
260 editor: &mut self.editor,
279 editor: &mut self.editor,
261 jobs: &mut self.jobs,
280 jobs: &mut self.jobs,
262 scroll: None,
281 scroll: None,
287+ .expect("Unable to determine terminal size");
289+ // TODO: need to recalculate view tree if necessary
291+ let surface = self.terminal.current_buffer_mut();
265− compositor.render(&mut cx);
293+ self.compositor.render(area, surface, &mut cx);
295+ let (pos, kind) = self.compositor.cursor(area, &self.editor);
296+ let pos = pos.map(|pos| (pos.col as u16, pos.row as u16));
297+ self.terminal.draw(pos, kind).unwrap();
268 pub async fn event_loop<S>(&mut self, input_stream: &mut S)
300 pub async fn event_loop<S>(&mut self, input_stream: &mut S)
@@ -392,17 +424,24 @@ impl Application {
393 #[cfg(not(windows))]
425 #[cfg(not(windows))]
394 pub async fn handle_signals(&mut self, signal: i32) {
426 pub async fn handle_signals(&mut self, signal: i32) {
395− use helix_view::graphics::Rect;
396 match signal {
427 match signal {
397 signal::SIGTSTP => {
428 signal::SIGTSTP => {
430+ use helix_view::graphics::CursorKind;
433+ .show_cursor(CursorKind::Block)
398 restore_term().unwrap();
435 restore_term().unwrap();
399 low_level::emulate_default_handler(signal::SIGTSTP).unwrap();
436 low_level::emulate_default_handler(signal::SIGTSTP).unwrap();
401 signal::SIGCONT => {
438 signal::SIGCONT => {
402 self.claim_term().await.unwrap();
439 self.claim_term().await.unwrap();
403 // redraw the terminal
440 // redraw the terminal
404− let Rect { width, height, .. } = self.compositor.size();
441+ let area = self.terminal.size().expect("couldn't get terminal size");
405− self.compositor.resize(width, height);
442+ self.compositor.resize(area);
443+ self.terminal.clear().expect("couldn't clear terminal");
406 self.render();
445 self.render();
408 signal::SIGUSR1 => {
447 signal::SIGUSR1 => {
@@ -539,7 +578,14 @@ impl Application {
539 // Handle key events
578 // Handle key events
540 let should_redraw = match event.unwrap() {
579 let should_redraw = match event.unwrap() {
541 CrosstermEvent::Resize(width, height) => {
580 CrosstermEvent::Resize(width, height) => {
542− self.compositor.resize(width, height);
582+ .resize(Rect::new(0, 0, width, height))
583+ .expect("Unable to resize terminal");
585+ let area = self.terminal.size().expect("couldn't get terminal size");
587+ self.compositor.resize(area);
543 self.compositor
589 self.compositor
544 .handle_event(&Event::Resize(width, height), &mut cx)
590 .handle_event(&Event::Resize(width, height), &mut cx)
@@ -923,10 +969,9 @@ impl Application {
924 async fn claim_term(&mut self) -> Result<(), Error> {
970 async fn claim_term(&mut self) -> Result<(), Error> {
925 use helix_view::graphics::CursorKind;
971 use helix_view::graphics::CursorKind;
926− use tui::backend::Backend;
927 terminal::enable_raw_mode()?;
972 terminal::enable_raw_mode()?;
928− if self.compositor.terminal.cursor_kind() == CursorKind::Hidden {
973+ if self.terminal.cursor_kind() == CursorKind::Hidden {
929− self.compositor.terminal.backend_mut().hide_cursor().ok();
974+ self.terminal.backend_mut().hide_cursor().ok();
931 let mut stdout = stdout();
976 let mut stdout = stdout();
932 execute!(
977 execute!(
@@ -962,14 +1007,12 @@ impl Application {
963 let close_errs = self.close().await;
1008 let close_errs = self.close().await;
965 use helix_view::graphics::CursorKind;
1011 use helix_view::graphics::CursorKind;
966− use tui::backend::Backend;
968− .terminal
1012+ self.terminal
969 .backend_mut()
1013 .backend_mut()
970 .show_cursor(CursorKind::Block)
1014 .show_cursor(CursorKind::Block)
973 restore_term()?;
1016 restore_term()?;
975 for err in close_errs {
1018 for err in close_errs {