aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2020-11-11 11:56:48 +0100
committerGitHub <noreply@github.com>2020-11-11 11:56:48 +0100
commit5a88b1a6ee85ae3a534049e87297a40001ff3a25 (patch)
tree653050c1a8351a99ca7bb45fda8b62e493a32c01 /src
parentfix(compatibility): various issues involving starship (#37) (diff)
downloadsl0ppij-5a88b1a6ee85ae3a534049e87297a40001ff3a25.tar.gz
sl0ppij-5a88b1a6ee85ae3a534049e87297a40001ff3a25.tar.xz
sl0ppij-5a88b1a6ee85ae3a534049e87297a40001ff3a25.zip
fix(ui): exit app when last pane is closed (#40)
Diffstat (limited to 'src')
-rw-r--r--src/main.rs131
-rw-r--r--src/screen.rs14
-rw-r--r--src/tests/integration/close_pane.rs26
-rw-r--r--src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-2.snap24
-rw-r--r--src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-3.snap24
-rw-r--r--src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-4.snap24
-rw-r--r--src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-5.snap24
-rw-r--r--src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-6.snap24
-rw-r--r--src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-7.snap24
-rw-r--r--src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-8.snap24
-rw-r--r--src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-9.snap24
-rw-r--r--src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app.snap24
12 files changed, 334 insertions, 53 deletions
diff --git a/src/main.rs b/src/main.rs
index 6050af3b..ea3594c3 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -84,6 +84,10 @@ pub fn main() {
}
}
+pub enum AppInstruction {
+ Exit
+}
+
pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
let mut active_threads = vec![];
@@ -91,7 +95,8 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
os_input.into_raw_mode(0);
let (send_screen_instructions, receive_screen_instructions): (Sender<ScreenInstruction>, Receiver<ScreenInstruction>) = channel();
let (send_pty_instructions, receive_pty_instructions): (Sender<PtyInstruction>, Receiver<PtyInstruction>) = channel();
- let mut screen = Screen::new(receive_screen_instructions, send_pty_instructions.clone(), &full_screen_ws, os_input.clone(), opts.max_panes);
+ let (send_app_instructions, receive_app_instructions): (Sender<AppInstruction>, Receiver<AppInstruction>) = channel();
+ let mut screen = Screen::new(receive_screen_instructions, send_pty_instructions.clone(), send_app_instructions.clone(), &full_screen_ws, os_input.clone(), opts.max_panes);
let mut pty_bus = PtyBus::new(receive_pty_instructions, send_screen_instructions.clone(), os_input.clone());
active_threads.push(
@@ -239,62 +244,84 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
}
}).unwrap();
- let mut stdin = os_input.get_stdin_reader();
+ let _stdin_thread = thread::Builder::new()
+ .name("ipc_server".to_string())
+ .spawn({
+ let send_screen_instructions = send_screen_instructions.clone();
+ let send_pty_instructions = send_pty_instructions.clone();
+ let send_app_instructions = send_app_instructions.clone();
+ let os_input = os_input.clone();
+ move || {
+ let mut stdin = os_input.get_stdin_reader();
+ loop {
+ let mut buffer = [0; 10]; // TODO: more accurately
+ stdin.read(&mut buffer).expect("failed to read stdin");
+ // uncomment this to print the entered character to a log file (/tmp/mosaic-log.txt) for debugging
+ // _debug_log_to_file(format!("buffer {:?}", buffer));
+ match buffer {
+ [10, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-j
+ send_screen_instructions.send(ScreenInstruction::ResizeDown).unwrap();
+ },
+ [11, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-k
+ send_screen_instructions.send(ScreenInstruction::ResizeUp).unwrap();
+ },
+ [16, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-p
+ send_screen_instructions.send(ScreenInstruction::MoveFocus).unwrap();
+ },
+ [8, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-h
+ send_screen_instructions.send(ScreenInstruction::ResizeLeft).unwrap();
+ },
+ [12, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-l
+ send_screen_instructions.send(ScreenInstruction::ResizeRight).unwrap();
+ },
+ [26, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-z
+ send_pty_instructions.send(PtyInstruction::SpawnTerminal(None)).unwrap();
+ },
+ [14, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-n
+ send_pty_instructions.send(PtyInstruction::SpawnTerminalVertically(None)).unwrap();
+ },
+ [2, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-b
+ send_pty_instructions.send(PtyInstruction::SpawnTerminalHorizontally(None)).unwrap();
+ },
+ [17, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-q
+ let _ = send_screen_instructions.send(ScreenInstruction::Quit);
+ let _ = send_pty_instructions.send(PtyInstruction::Quit);
+ let _ = send_app_instructions.send(AppInstruction::Exit);
+ break;
+ },
+ [27, 91, 53, 94, 0, 0, 0, 0, 0, 0] => { // ctrl-PgUp
+ send_screen_instructions.send(ScreenInstruction::ScrollUp).unwrap();
+ },
+ [27, 91, 54, 94, 0, 0, 0, 0, 0, 0] => { // ctrl-PgDown
+ send_screen_instructions.send(ScreenInstruction::ScrollDown).unwrap();
+ },
+ [24, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-x
+ send_screen_instructions.send(ScreenInstruction::CloseFocusedPane).unwrap();
+ // ::std::thread::sleep(::std::time::Duration::from_millis(10));
+ },
+ [5, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-e
+ send_screen_instructions.send(ScreenInstruction::ToggleActiveTerminalFullscreen).unwrap();
+ },
+ _ => {
+ send_screen_instructions.send(ScreenInstruction::ClearScroll).unwrap();
+ send_screen_instructions.send(ScreenInstruction::WriteCharacter(buffer)).unwrap();
+ }
+ }
+ };
+ }
+ });
loop {
- let mut buffer = [0; 10]; // TODO: more accurately
- stdin.read(&mut buffer).expect("failed to read stdin");
- // uncomment this to print the entered character to a log file (/tmp/mosaic-log.txt) for debugging
- // _debug_log_to_file(format!("buffer {:?}", buffer));
- match buffer {
- [10, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-j
- send_screen_instructions.send(ScreenInstruction::ResizeDown).unwrap();
- },
- [11, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-k
- send_screen_instructions.send(ScreenInstruction::ResizeUp).unwrap();
- },
- [16, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-p
- send_screen_instructions.send(ScreenInstruction::MoveFocus).unwrap();
- },
- [8, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-h
- send_screen_instructions.send(ScreenInstruction::ResizeLeft).unwrap();
- },
- [12, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-l
- send_screen_instructions.send(ScreenInstruction::ResizeRight).unwrap();
- },
- [26, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-z
- send_pty_instructions.send(PtyInstruction::SpawnTerminal(None)).unwrap();
- },
- [14, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-n
- send_pty_instructions.send(PtyInstruction::SpawnTerminalVertically(None)).unwrap();
- },
- [2, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-b
- send_pty_instructions.send(PtyInstruction::SpawnTerminalHorizontally(None)).unwrap();
- },
- [17, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-q
- send_screen_instructions.send(ScreenInstruction::Quit).unwrap();
- send_pty_instructions.send(PtyInstruction::Quit).unwrap();
+ let app_instruction = receive_app_instructions.recv().expect("failed to receive app instruction on channel");
+ match app_instruction {
+ AppInstruction::Exit => {
+ let _ = send_screen_instructions.send(ScreenInstruction::Quit);
+ let _ = send_pty_instructions.send(PtyInstruction::Quit);
break;
},
- [27, 91, 53, 94, 0, 0, 0, 0, 0, 0] => { // ctrl-PgUp
- send_screen_instructions.send(ScreenInstruction::ScrollUp).unwrap();
- },
- [27, 91, 54, 94, 0, 0, 0, 0, 0, 0] => { // ctrl-PgDown
- send_screen_instructions.send(ScreenInstruction::ScrollDown).unwrap();
- },
- [24, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-x
- send_screen_instructions.send(ScreenInstruction::CloseFocusedPane).unwrap();
- },
- [5, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-e
- send_screen_instructions.send(ScreenInstruction::ToggleActiveTerminalFullscreen).unwrap();
- },
- _ => {
- send_screen_instructions.send(ScreenInstruction::ClearScroll).unwrap();
- send_screen_instructions.send(ScreenInstruction::WriteCharacter(buffer)).unwrap();
- }
}
- };
-
+ }
+
for thread_handler in active_threads {
thread_handler.join().unwrap();
}
diff --git a/src/screen.rs b/src/screen.rs
index 10e6451e..a5bb2a73 100644
--- a/src/screen.rs
+++ b/src/screen.rs
@@ -8,6 +8,7 @@ use crate::os_input_output::OsApi;
use crate::terminal_pane::TerminalPane;
use crate::pty_bus::{VteEvent, PtyInstruction};
use crate::boundaries::Boundaries;
+use crate::AppInstruction;
/*
* Screen
@@ -81,6 +82,7 @@ pub struct Screen {
pub receiver: Receiver<ScreenInstruction>,
max_panes: Option<usize>,
send_pty_instructions: Sender<PtyInstruction>,
+ send_app_instructions: Sender<AppInstruction>,
full_screen_ws: Winsize,
terminals: BTreeMap<RawFd, TerminalPane>, // BTreeMap because we need a predictable order when changing focus
panes_to_hide: HashSet<RawFd>,
@@ -92,6 +94,7 @@ impl Screen {
pub fn new (
receive_screen_instructions: Receiver<ScreenInstruction>,
send_pty_instructions: Sender<PtyInstruction>,
+ send_app_instructions: Sender<AppInstruction>,
full_screen_ws: &Winsize,
os_api: Box<dyn OsApi>,
max_panes: Option<usize>,
@@ -100,6 +103,7 @@ impl Screen {
receiver: receive_screen_instructions,
max_panes,
send_pty_instructions,
+ send_app_instructions,
full_screen_ws: full_screen_ws.clone(),
terminals: BTreeMap::new(),
panes_to_hide: HashSet::new(),
@@ -307,6 +311,11 @@ impl Screen {
}
}
pub fn render (&mut self) {
+ if self.active_terminal.is_none() {
+ // we might not have an active terminal if we closed the last pane
+ // in that case, we should not render as the app is exiting
+ return;
+ }
let mut stdout = self.os_api.get_stdout_writer();
let mut boundaries = Boundaries::new(self.full_screen_ws.ws_col, self.full_screen_ws.ws_row);
for (pid, terminal) in self.terminals.iter_mut() {
@@ -1072,9 +1081,12 @@ impl Screen {
self.active_terminal = Some(*terminals.last().unwrap());
}
} else {
- return; // TODO: exit app? here we're trying to close the last pane on screen
}
self.terminals.remove(&id);
+ if self.terminals.is_empty() {
+ self.active_terminal = None;
+ let _ = self.send_app_instructions.send(AppInstruction::Exit);
+ }
}
}
pub fn close_focused_pane(&mut self) {
diff --git a/src/tests/integration/close_pane.rs b/src/tests/integration/close_pane.rs
index d8cb4858..ddb41d1e 100644
--- a/src/tests/integration/close_pane.rs
+++ b/src/tests/integration/close_pane.rs
@@ -469,3 +469,29 @@ pub fn close_pane_with_multiple_panes_to_the_right_away_from_screen_edges() {
assert_snapshot!(snapshot);
}
}
+
+#[test]
+pub fn closing_last_pane_exits_app() {
+ let fake_win_size = Winsize {
+ 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(&[
+ SPLIT_VERTICALLY,
+ SPLIT_HORIZONTALLY,
+ MOVE_FOCUS,
+ CLOSE_FOCUSED_PANE,
+ CLOSE_FOCUSED_PANE,
+ CLOSE_FOCUSED_PANE,
+ ]);
+ start(Box::new(fake_input_output.clone()), Opt::default());
+
+ 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);
+ }
+}
diff --git a/src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-2.snap b/src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-2.snap
new file mode 100644
index 00000000..9a71d42d
--- /dev/null
+++ b/src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-2.snap
@@ -0,0 +1,24 @@
+---
+source: src/tests/integration/close_pane.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__close_pane__closing_last_pane_exits_app-3.snap b/src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-3.snap
new file mode 100644
index 00000000..dd774309
--- /dev/null
+++ b/src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-3.snap
@@ -0,0 +1,24 @@
+---
+source: src/tests/integration/close_pane.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__close_pane__closing_last_pane_exits_app-4.snap b/src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-4.snap
new file mode 100644
index 00000000..99eb28a1
--- /dev/null
+++ b/src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-4.snap
@@ -0,0 +1,24 @@
+---
+source: src/tests/integration/close_pane.rs
+expression: snapshot
+---
+a │line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │prompt $
+line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa├────────────────────────────────────────────────────────────
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│█
+a │
+line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│
+a │
+line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│
+a │
+prompt $ │
diff --git a/src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-5.snap b/src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-5.snap
new file mode 100644
index 00000000..d0b86d12
--- /dev/null
+++ b/src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-5.snap
@@ -0,0 +1,24 @@
+---
+source: src/tests/integration/close_pane.rs
+expression: snapshot
+---
+a │line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │prompt $
+line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa├────────────────────────────────────────────────────────────
+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__close_pane__closing_last_pane_exits_app-6.snap b/src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-6.snap
new file mode 100644
index 00000000..9dc5ec08
--- /dev/null
+++ b/src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-6.snap
@@ -0,0 +1,24 @@
+---
+source: src/tests/integration/close_pane.rs
+expression: snapshot
+---
+a │line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+a │prompt $
+line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa├────────────────────────────────────────────────────────────
+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__close_pane__closing_last_pane_exits_app-7.snap b/src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-7.snap
new file mode 100644
index 00000000..94890f9d
--- /dev/null
+++ b/src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-7.snap
@@ -0,0 +1,24 @@
+---
+source: src/tests/integration/close_pane.rs
+expression: snapshot
+---
+line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+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__close_pane__closing_last_pane_exits_app-8.snap b/src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-8.snap
new file mode 100644
index 00000000..49442175
--- /dev/null
+++ b/src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-8.snap
@@ -0,0 +1,24 @@
+---
+source: src/tests/integration/close_pane.rs
+expression: snapshot
+---
+line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+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__close_pane__closing_last_pane_exits_app-9.snap b/src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-9.snap
new file mode 100644
index 00000000..841a1eae
--- /dev/null
+++ b/src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app-9.snap
@@ -0,0 +1,24 @@
+---
+source: src/tests/integration/close_pane.rs
+expression: snapshot
+---
+line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+prompt $
+Bye from Mosaic!█
diff --git a/src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app.snap b/src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app.snap
new file mode 100644
index 00000000..78935c87
--- /dev/null
+++ b/src/tests/integration/snapshots/mosaic__tests__integration__close_pane__closing_last_pane_exits_app.snap
@@ -0,0 +1,24 @@
+---
+source: src/tests/integration/close_pane.rs
+expression: snapshot
+---
+line1-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line2-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line3-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line4-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line5-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line6-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line7-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line8-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line9-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line10-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+prompt $ █