summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2020-11-02 16:34:20 +0100
committerGitHub <noreply@github.com>2020-11-02 16:34:20 +0100
commit9f6bbc55b5ef405067b17bb203878a7ef6366821 (patch)
tree04d12bdb0a105ff9e14ba0255ec83bd5d72b815e
parent6a37b83e3a98560563a5225a22a2a45d5718c023 (diff)
feat(screen): split largest terminal (#19)
* feat(screen): split largest terminal * docs(readme): split largest terminal command
-rw-r--r--README.md1
-rw-r--r--src/main.rs8
-rw-r--r--src/pty_bus.rs7
-rw-r--r--src/screen.rs52
-rw-r--r--src/tests/integration/basic.rs19
-rw-r--r--src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-2.snap24
-rw-r--r--src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-3.snap24
-rw-r--r--src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-4.snap24
-rw-r--r--src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-5.snap24
-rw-r--r--src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-6.snap24
-rw-r--r--src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-7.snap24
-rw-r--r--src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-8.snap24
-rw-r--r--src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal.snap24
13 files changed, 279 insertions, 0 deletions
diff --git a/README.md b/README.md
index f8323ed41..2a4d6b607 100644
--- a/README.md
+++ b/README.md
@@ -35,6 +35,7 @@ If you're interested, watch this space or better yet - get involved!
Some temporary controls (these will be changed to something more convenient when the project matures a little):
* ctrl-n - split focused pane vertically
* ctrl-b - split focused pane horizontally
+ * ctrl-m - split largest terminal on screen (vertically or horizontally)
* ctrl-j - resize focused pane down
* ctrl-k - resize focused pane up
* ctrl-h - resize focused pane left
diff --git a/src/main.rs b/src/main.rs
index 56d45503a..7b1293f30 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -102,6 +102,9 @@ pub fn start(mut os_input: Box<dyn OsApi>) {
.recv()
.expect("failed to receive event on channel");
match event {
+ PtyInstruction::SpawnTerminal(file_to_open) => {
+ pty_bus.spawn_terminal(file_to_open);
+ }
PtyInstruction::SpawnTerminalVertically(file_to_open) => {
pty_bus.spawn_terminal_vertically(file_to_open);
}
@@ -136,6 +139,9 @@ pub fn start(mut os_input: Box<dyn OsApi>) {
ScreenInstruction::Render => {
screen.render();
},
+ ScreenInstruction::NewPane(pid) => {
+ screen.new_pane(pid);
+ }
ScreenInstruction::HorizontalSplit(pid) => {
screen.horizontal_split(pid);
}
@@ -241,6 +247,8 @@ pub fn start(mut os_input: Box<dyn OsApi>) {
send_screen_instructions.send(ScreenInstruction::ResizeLeft).unwrap();
} else if buffer[0] == 12 { // ctrl-l
send_screen_instructions.send(ScreenInstruction::ResizeRight).unwrap();
+ } else if buffer[0] == 13 { // ctrl-m
+ send_pty_instructions.send(PtyInstruction::SpawnTerminal(None)).unwrap();
} else if buffer[0] == 14 { // ctrl-n
send_pty_instructions.send(PtyInstruction::SpawnTerminalVertically(None)).unwrap();
} else if buffer[0] == 2 { // ctrl-b
diff --git a/src/pty_bus.rs b/src/pty_bus.rs
index bd04e45a3..705f8e4c8 100644
--- a/src/pty_bus.rs
+++ b/src/pty_bus.rs
@@ -135,6 +135,7 @@ impl vte::Perform for VteEventSender {
}
pub enum PtyInstruction {
+ SpawnTerminal(Option<PathBuf>),
SpawnTerminalVertically(Option<PathBuf>),
SpawnTerminalHorizontally(Option<PathBuf>),
ClosePane(RawFd),
@@ -215,6 +216,12 @@ impl PtyBus {
id_to_child_pid: HashMap::new(),
}
}
+ pub fn spawn_terminal(&mut self, file_to_open: Option<PathBuf>) {
+ let (pid_primary, pid_secondary): (RawFd, RawFd) = self.os_input.spawn_terminal(file_to_open);
+ stream_terminal_bytes(pid_primary, self.send_screen_instructions.clone(), self.os_input.clone());
+ self.id_to_child_pid.insert(pid_primary, pid_secondary);
+ self.send_screen_instructions.send(ScreenInstruction::NewPane(pid_primary)).unwrap();
+ }
pub fn spawn_terminal_vertically(&mut self, file_to_open: Option<PathBuf>) {
let (pid_primary, pid_secondary): (RawFd, RawFd) = self.os_input.spawn_terminal(file_to_open);
stream_terminal_bytes(pid_primary, self.send_screen_instructions.clone(), self.os_input.clone());
diff --git a/src/screen.rs b/src/screen.rs
index 6557e0bcb..ec72c8f3f 100644
--- a/src/screen.rs
+++ b/src/screen.rs
@@ -25,6 +25,8 @@ fn _debug_log_to_file (message: String) {
file.write_all("\n".as_bytes()).unwrap();
}
+const CURSOR_HEIGHT_WIDGH_RATIO: u16 = 4; // this is not accurate and kind of a magic number, TODO: look into this
+
type BorderAndPaneIds = (u16, Vec<RawFd>);
fn split_vertically_with_gap (rect: &Winsize) -> (Winsize, Winsize) {
@@ -57,6 +59,7 @@ fn split_horizontally_with_gap (rect: &Winsize) -> (Winsize, Winsize) {
pub enum ScreenInstruction {
Pty(RawFd, VteEvent),
Render,
+ NewPane(RawFd),
HorizontalSplit(RawFd),
VerticalSplit(RawFd),
WriteCharacter(u8),
@@ -93,6 +96,55 @@ impl Screen {
os_api,
}
}
+ pub fn new_pane(&mut self, pid: RawFd) {
+ if self.terminals.is_empty() {
+ let x = 0;
+ let y = 0;
+ let new_terminal = TerminalPane::new(pid, self.full_screen_ws.clone(), x, y);
+ self.os_api.set_terminal_size_using_fd(new_terminal.pid, new_terminal.display_cols, new_terminal.display_rows);
+ self.terminals.insert(pid, new_terminal);
+ self.active_terminal = Some(pid);
+ } else {
+ // TODO: check minimum size of active terminal
+
+ let (_longest_edge, terminal_id_to_split) = self.terminals.iter().fold((0, 0), |(current_longest_edge, current_terminal_id_to_split), id_and_terminal_to_check| {
+ let (id_of_terminal_to_check, terminal_to_check) = id_and_terminal_to_check;
+ let terminal_size = (terminal_to_check.display_rows * CURSOR_HEIGHT_WIDGH_RATIO) * terminal_to_check.display_cols;
+ if terminal_size > current_longest_edge {
+ (terminal_size, *id_of_terminal_to_check)
+ } else {
+ (current_longest_edge, current_terminal_id_to_split)
+ }
+ });
+ let terminal_to_split = self.terminals.get_mut(&terminal_id_to_split).unwrap();
+ let terminal_ws = Winsize {
+ ws_row: terminal_to_split.display_rows,
+ ws_col: terminal_to_split.display_cols,
+ ws_xpixel: terminal_to_split.x_coords,
+ ws_ypixel: terminal_to_split.y_coords,
+ };
+ if terminal_to_split.display_rows * CURSOR_HEIGHT_WIDGH_RATIO > terminal_to_split.display_cols {
+ let (top_winsize, bottom_winsize) = split_horizontally_with_gap(&terminal_ws);
+ let bottom_half_y = terminal_ws.ws_ypixel + top_winsize.ws_row + 1;
+ let new_terminal = TerminalPane::new(pid, bottom_winsize, terminal_ws.ws_xpixel, bottom_half_y);
+ self.os_api.set_terminal_size_using_fd(new_terminal.pid, bottom_winsize.ws_col, bottom_winsize.ws_row);
+ terminal_to_split.change_size(&top_winsize);
+ self.terminals.insert(pid, new_terminal);
+ self.os_api.set_terminal_size_using_fd(terminal_id_to_split, top_winsize.ws_col, top_winsize.ws_row);
+ self.active_terminal = Some(pid);
+ } else {
+ let (left_winszie, right_winsize) = split_vertically_with_gap(&terminal_ws);
+ let right_side_x = terminal_ws.ws_xpixel + left_winszie.ws_col + 1;
+ let new_terminal = TerminalPane::new(pid, right_winsize, right_side_x, terminal_ws.ws_ypixel);
+ self.os_api.set_terminal_size_using_fd(new_terminal.pid, right_winsize.ws_col, right_winsize.ws_row);
+ terminal_to_split.change_size(&left_winszie);
+ self.terminals.insert(pid, new_terminal);
+ self.os_api.set_terminal_size_using_fd(terminal_id_to_split, left_winszie.ws_col, left_winszie.ws_row);
+ }
+ self.active_terminal = Some(pid);
+ self.render();
+ }
+ }
pub fn horizontal_split(&mut self, pid: RawFd) {
if self.terminals.is_empty() {
let x = 0;
diff --git a/src/tests/integration/basic.rs b/src/tests/integration/basic.rs
index 49cfeda53..ef122583f 100644
--- a/src/tests/integration/basic.rs
+++ b/src/tests/integration/basic.rs
@@ -64,6 +64,25 @@ pub fn split_terminals_horizontally() {
}
#[test]
+pub fn split_largest_terminal () {
+ // this finds the largest pane and splits along its longest edge (vertically or horizontally)
+ let fake_win_size = Winsize { // TODO: combine with above
+ ws_col: 121,
+ ws_row: 20,
+ ws_xpixel: 0,
+ ws_ypixel: 0,
+ };
+ let mut fake_input_output = get_fake_os_input(&fake_win_size);
+ fake_input_output.add_terminal_input(&[13, 13, 13, 17]); // split-largest_terminal * 4 and quit (ctrl-m + ctrl-m + ctrl-m + ctrl-m + ctrl-q)
+ start(Box::new(fake_input_output.clone()));
+ let output_frames = fake_input_output.stdout_writer.output_frames.lock().unwrap();
+ let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size);
+ for snapshot in snapshots {
+ assert_snapshot!(snapshot);
+ }
+}
+
+#[test]
pub fn resize_right_and_up_on_the_same_axis() {
// this is a specific test to explicitly ensure that a tmux-like pane-container algorithm is not
// implemented (this test can never pass with such an algorithm)
diff --git a/src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-2.snap b/src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-2.snap
new file mode 100644
index 000000000..3d527ead6
--- /dev/null
+++ b/src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-2.snap
@@ -0,0 +1,24 @@
+---
+source: src/tests/integration/basic.rs
+expression: snapshot
+---
+a │█
+line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│
+a │
+line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│
+a │
+line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│
+a │
+line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│
+a │
+line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│
+a │
+line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│
+a │
+prompt $ │
diff --git a/src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-3.snap b/src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-3.snap
new file mode 100644
index 000000000..4a2fb1403
--- /dev/null
+++ b/src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-3.snap
@@ -0,0 +1,24 @@
+---
+source: src/tests/integration/basic.rs
+expression: snapshot
+---
+a │line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+prompt $ │prompt $ █
diff --git a/src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-4.snap b/src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-4.snap
new file mode 100644
index 000000000..4cd991587
--- /dev/null
+++ b/src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-4.snap
@@ -0,0 +1,24 @@
+---
+source: src/tests/integration/basic.rs
+expression: snapshot
+---
+line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+prompt $ │line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+────────────────────────────────────────────────────────────┤line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+█ │line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ │line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ │line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ │line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ │line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ │prompt $
diff --git a/src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-5.snap b/src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-5.snap
new file mode 100644
index 000000000..cc0f4bc6a
--- /dev/null
+++ b/src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-5.snap
@@ -0,0 +1,24 @@
+---
+source: src/tests/integration/basic.rs
+expression: snapshot
+---
+line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+prompt $ │line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+────────────────────────────────────────────────────────────┤line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+prompt $ █ │prompt $
diff --git a/src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-6.snap b/src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-6.snap
new file mode 100644
index 000000000..b0f22d41b
--- /dev/null
+++ b/src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-6.snap
@@ -0,0 +1,24 @@
+---
+source: src/tests/integration/basic.rs
+expression: snapshot
+---
+line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+prompt $ │prompt $
+────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────
+line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│█
+line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│
+line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│
+line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│
+line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│
+line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│
+line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│
+line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│
+prompt $ │
diff --git a/src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-7.snap b/src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-7.snap
new file mode 100644
index 000000000..e7d9ee8c7
--- /dev/null
+++ b/src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-7.snap
@@ -0,0 +1,24 @@
+---
+source: src/tests/integration/basic.rs
+expression: snapshot
+---
+line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+prompt $ │prompt $
+────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────
+line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+prompt $ │prompt $ █
diff --git a/src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-8.snap b/src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-8.snap
new file mode 100644
index 000000000..be0817da0
--- /dev/null
+++ b/src/tests/integration/snapshots/mosaic__tests__integration__basic__split_largest_terminal-8.snap
@@ -0,0 +1,24 @@
+---
+source: src/tests/integration/basic.rs
+expression: snapshot
+---
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb