Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 37 additions & 25 deletions docs/architecture.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/app/commit_log_fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use std::sync::mpsc;
use std::thread;

use crate::util::{REAP_TIMEOUT, try_timed_join};
use crate::platform::threading::{REAP_TIMEOUT, try_timed_join};

use git2::{Oid, Repository};

Expand Down
2 changes: 1 addition & 1 deletion src/app/commit_log_pagination.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use std::sync::mpsc::Receiver;
use std::thread::JoinHandle;

use crate::util::{REAP_TIMEOUT, try_timed_join};
use crate::platform::threading::{REAP_TIMEOUT, try_timed_join};

use super::commit_log_fetch::CommitLogPageMsg;

Expand Down
2 changes: 1 addition & 1 deletion src/app/session_io.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::{App, Focus, NoticeKind, ViewMode};
use crate::git::diff::{load_commit_files, load_commit_log};
use crate::runtime::terminal::TerminalFullscreen;
use crate::session::SessionState;
use crate::workspace::persistence::SessionState;

impl App {
// The live view, except for a selection still waiting on its first
Expand Down
16 changes: 8 additions & 8 deletions src/app/tests/session_restore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ fn save_session_round_trips_list_fullscreen() {
fn restore_session_list_fullscreen_forces_filelist_focus() {
let mut app = app_with_files(vec![]);

app.restore_session(&crate::session::SessionState {
app.restore_session(&crate::workspace::persistence::SessionState {
focus: Some(Focus::DiffViewer),
list_fullscreen: true,
..Default::default()
Expand All @@ -132,7 +132,7 @@ fn restore_session_prefers_terminal_fullscreen_over_list_fullscreen() {
title: "shell".into(),
}];

app.restore_session(&crate::session::SessionState {
app.restore_session(&crate::workspace::persistence::SessionState {
focus: Some(Focus::FileList),
terminal_fullscreen: true,
list_fullscreen: true,
Expand Down Expand Up @@ -182,7 +182,7 @@ fn restore_session_restores_active_pane_even_when_focus_is_not_terminal() {
},
];

app.restore_session(&crate::session::SessionState {
app.restore_session(&crate::workspace::persistence::SessionState {
focus: Some(Focus::FileList),
active_pane: 1,
..Default::default()
Expand All @@ -200,7 +200,7 @@ fn restore_session_fullscreen_forces_terminal_focus() {
title: "shell".into(),
}];

app.restore_session(&crate::session::SessionState {
app.restore_session(&crate::workspace::persistence::SessionState {
focus: Some(Focus::FileList),
terminal_fullscreen: true,
..Default::default()
Expand All @@ -214,7 +214,7 @@ fn restore_session_fullscreen_forces_terminal_focus() {
fn restore_session_diff_fullscreen_forces_diff_focus() {
let mut app = app_with_files(vec![]);

app.restore_session(&crate::session::SessionState {
app.restore_session(&crate::workspace::persistence::SessionState {
focus: Some(Focus::FileList),
diff_fullscreen: true,
..Default::default()
Expand All @@ -232,7 +232,7 @@ fn restore_session_prefers_terminal_fullscreen_over_diff_fullscreen() {
title: "shell".into(),
}];

app.restore_session(&crate::session::SessionState {
app.restore_session(&crate::workspace::persistence::SessionState {
focus: Some(Focus::FileList),
terminal_fullscreen: true,
diff_fullscreen: true,
Expand Down Expand Up @@ -263,7 +263,7 @@ fn save_session_round_trips_diff_fullscreen() {
fn restore_session_normalizes_accent_index() {
let mut app = app_with_files(vec![]);

app.restore_session(&crate::session::SessionState {
app.restore_session(&crate::workspace::persistence::SessionState {
accent_idx: usize::MAX,
..Default::default()
});
Expand All @@ -289,7 +289,7 @@ fn restore_session_keeps_log_scroll_after_loading_commit_diff() {
let mut app = app_with_files(vec![]);
app.repo_path = path;

app.restore_session(&crate::session::SessionState {
app.restore_session(&crate::workspace::persistence::SessionState {
mode: Some(ViewMode::Log),
scroll: 2,
..Default::default()
Expand Down
4 changes: 2 additions & 2 deletions src/app/tests/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ fn a_saved_mode_lands_immediately_and_survives_being_changed() {
..app_with_files(vec![])
};

app.restore_session(&crate::session::SessionState {
app.restore_session(&crate::workspace::persistence::SessionState {
mode: Some(ViewMode::Tree),
..Default::default()
});
Expand Down Expand Up @@ -85,7 +85,7 @@ fn a_saved_selection_is_restored_by_the_first_snapshot() {
..app_with_files(vec![])
};

app.restore_session(&crate::session::SessionState {
app.restore_session(&crate::workspace::persistence::SessionState {
selected_file: Some("b.rs".to_string()),
..Default::default()
});
Expand Down
4 changes: 2 additions & 2 deletions src/app/tests/terminal_init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fn restore_session_overrides_fresh_launch_terminal_focus() {
app.ensure_initial_terminal(&[]);
assert_eq!(app.focus, Focus::Terminal);
// A restored session must win over the fresh-launch terminal focus.
app.restore_session(&crate::session::SessionState {
app.restore_session(&crate::workspace::persistence::SessionState {
focus: Some(Focus::FileList),
..Default::default()
});
Expand All @@ -40,7 +40,7 @@ fn restore_pane_focus_wins_immediately_without_snapshot() {
let mut app = app_with_fake_backend();
app.ensure_initial_terminal(&[]);
assert_eq!(app.focus, Focus::Terminal);
app.restore_pane_focus(&crate::session::SessionState {
app.restore_pane_focus(&crate::workspace::persistence::SessionState {
focus: Some(Focus::FileList),
..Default::default()
});
Expand Down
6 changes: 3 additions & 3 deletions src/app/tests/tree_session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ fn restoring_tree_session_clears_lingering_status_search() {
app.search_push('x');
assert!(app.status_view.search_active);

app.restore_session(&crate::session::SessionState {
app.restore_session(&crate::workspace::persistence::SessionState {
mode: Some(ViewMode::Tree),
..Default::default()
});
Expand Down Expand Up @@ -163,7 +163,7 @@ fn restore_tree_session_ignores_unsafe_expanded_paths() {
let (dir, path) = make_tree_repo();
let mut app = app_on(&path);

app.restore_session(&crate::session::SessionState {
app.restore_session(&crate::workspace::persistence::SessionState {
mode: Some(ViewMode::Tree),
tree_expanded: vec![
"../../..".to_string(),
Expand Down Expand Up @@ -191,7 +191,7 @@ fn restore_tree_session_prunes_expansion_gone_since_save() {
std::fs::rename(Path::new(&path).join("src"), Path::new(&path).join("lib")).unwrap();
let mut app = app_on(&path);

app.restore_session(&crate::session::SessionState {
app.restore_session(&crate::workspace::persistence::SessionState {
mode: Some(ViewMode::Tree),
tree_expanded: vec!["src".to_string()],
tree_selected_path: Some("src".to_string()),
Expand Down
2 changes: 1 addition & 1 deletion src/app_init.rs → src/application/bootstrap.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::app::App;
use crate::session::SessionState;
use crate::workspace::persistence::SessionState;

pub(crate) fn init_app(
repo_path: &str,
Expand Down
12 changes: 6 additions & 6 deletions src/event_loop.rs → src/application/event_loop.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
pub(crate) use crate::application::input::dispatch::ProjectContext;
use crate::application::input::dispatch::{KeyOutcome, ProjectRequest, dispatch_key};
use crate::application::input::mouse::dispatch_mouse;
use crate::application::input::paste::dispatch_paste;
use crate::cli::WebSurfaces;
pub(crate) use crate::key_dispatch::ProjectContext;
use crate::key_dispatch::{KeyOutcome, ProjectRequest, dispatch_key};
use crate::mouse::dispatch_mouse;
use crate::paste::dispatch_paste;
use crate::workspace::Workspace;
use crossterm::event::{self, Event};
use ratatui::layout::Rect;
Expand Down Expand Up @@ -256,7 +256,7 @@ pub(crate) fn apply_project_request(
// `close_active` carries the project's view state into the
// remembered set; writing here means a crash later cannot lose it.
if ws.close_active() {
crate::session::save_workspace(&ws.to_persisted());
crate::workspace::persistence::save_workspace(&ws.to_persisted());
}
}
ProjectRequest::Open(repo_path) => {
Expand All @@ -280,7 +280,7 @@ pub(crate) fn apply_project_request(
return;
}
let saved = ws.session_for(&repo_path).cloned();
let project = crate::app_init::init_app(
let project = crate::application::bootstrap::init_app(
&repo_path,
ctx.cfg,
ctx.startup_commands,
Expand Down
4 changes: 2 additions & 2 deletions src/key_dispatch.rs → src/application/input/dispatch.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::app::{App, Focus};
use crate::input::{Action, encode_key, map_key, prefix_action, prefix_action_fullscreen};
use crate::key_handlers::{
use crate::application::input::handlers::{
handle_empty_key, handle_repo_input_key, handle_terminal_key, handle_upper_key,
};
use crate::input::{Action, encode_key, map_key, prefix_action, prefix_action_fullscreen};
use crate::workspace::Workspace;
use crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers};

Expand Down
4 changes: 3 additions & 1 deletion src/key_handlers.rs → src/application/input/handlers.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::app::{App, DiffPaneView, Focus, ViewMode};
use crate::application::input::dispatch::{
KeyOutcome, ProjectRequest, matches_text_command, text_input_char,
};
use crate::input::{Action, encode_key, prefix_action, vim_navigation_action};
use crate::key_dispatch::{KeyOutcome, ProjectRequest, matches_text_command, text_input_char};
use crate::runtime::terminal::SCROLL_LINE_STEP;
use crate::workspace::Workspace;
use crossterm::event::{KeyCode, KeyEvent};
Expand Down
6 changes: 6 additions & 0 deletions src/application/input/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//! Translate terminal and browser input into application actions.

pub(crate) mod dispatch;
mod handlers;
pub(crate) mod mouse;
pub(crate) mod paste;
2 changes: 1 addition & 1 deletion src/mouse.rs → src/application/input/mouse.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::app::{App, Focus};
use crate::key_dispatch::{KeyOutcome, ProjectRequest, handle_key};
use crate::application::input::dispatch::{KeyOutcome, ProjectRequest, handle_key};
use crate::runtime::terminal::WHEEL_LINES_PER_NOTCH;
use crate::workspace::Workspace;
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers, MouseEvent, MouseEventKind};
Expand Down
File renamed without changes.
10 changes: 10 additions & 0 deletions src/application/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//! Process-level orchestration for the native TUI.
//!
//! This layer owns startup and event routing. Domain state lives in `app`,
//! while rendering, runtime services, and persistence stay in their own
//! top-level modules.

pub(crate) mod bootstrap;
pub(crate) mod event_loop;
pub(crate) mod input;
pub(crate) mod splash;
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion src/main_tests/mouse.rs → src/application/tests/mouse.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::helpers::*;
use crate::app::Focus;
use crate::mouse::{dispatch_mouse, handle_mouse};
use crate::application::input::mouse::{dispatch_mouse, handle_mouse};
use crate::workspace::Workspace;
use crossterm::event::MouseEventKind;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::helpers::*;
use crate::app::Focus;
use crate::key_dispatch::KeyOutcome;
use crate::mouse::handle_mouse;
use crate::application::input::dispatch::KeyOutcome;
use crate::application::input::mouse::handle_mouse;
use crossterm::event::MouseEventKind;

#[test]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use super::helpers::*;
use crate::app;
use crate::app::tests::{app_with_fake_backend, app_with_files};
use crate::key_dispatch::{KeyOutcome, ProjectRequest};
use crate::mouse::{dispatch_mouse, handle_mouse};
use crate::application::input::dispatch::{KeyOutcome, ProjectRequest};
use crate::application::input::mouse::{dispatch_mouse, handle_mouse};
use crate::workspace::Workspace;
use crossterm::event::MouseEventKind;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::helpers::*;
use crate::mouse::handle_mouse;
use crate::application::input::mouse::handle_mouse;
use crossterm::event::MouseEventKind;

#[test]
Expand Down
4 changes: 2 additions & 2 deletions src/main_tests/paste.rs → src/application/tests/paste.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use super::helpers::*;
use crate::app::Focus;
use crate::app::tests::app_with_files;
use crate::key_dispatch::handle_key;
use crate::paste::{dispatch_paste, handle_paste};
use crate::application::input::dispatch::handle_key;
use crate::application::input::paste::{dispatch_paste, handle_paste};

#[test]
fn paste_while_prefix_armed_cancels_prefix() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::helpers::*;
use crate::app::Focus;
use crate::app::tests::app_with_files;
use crate::key_dispatch::{KeyOutcome, ProjectRequest, dispatch_key, handle_key};
use crate::application::input::dispatch::{KeyOutcome, ProjectRequest, dispatch_key, handle_key};
use crate::workspace::Workspace;
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::helpers::*;
use crate::app::tests::app_with_files;
use crate::app::{Focus, ViewMode};
use crate::key_dispatch::handle_key;
use crate::application::input::dispatch::handle_key;
use crossterm::event::{KeyCode, KeyModifiers};

#[test]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::helpers::*;
use crate::app::tests::app_with_files;
use crate::app::{DiffPaneView, Focus};
use crate::key_dispatch::handle_key;
use crate::application::input::dispatch::handle_key;
use crossterm::event::{KeyCode, KeyModifiers};

#[test]
Expand Down
2 changes: 1 addition & 1 deletion src/main_tests/swap.rs → src/application/tests/swap.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::helpers::*;
use crate::app::Focus;
use crate::key_dispatch::handle_key;
use crate::application::input::dispatch::handle_key;
use crossterm::event::{KeyCode, KeyModifiers};

#[test]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::helpers::*;
use crate::key_dispatch::handle_key;
use crate::application::input::dispatch::handle_key;
use crossterm::event::{KeyCode, KeyModifiers};

#[test]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use super::helpers::*;
use crate::app::tests::app_with_files;
use crate::event_loop::apply_project_request;
use crate::key_dispatch::{KeyOutcome, ProjectContext, ProjectRequest, dispatch_key, handle_key};
use crate::application::event_loop::apply_project_request;
use crate::application::input::dispatch::{
KeyOutcome, ProjectContext, ProjectRequest, dispatch_key, handle_key,
};
use crate::workspace::Workspace;
use crossterm::event::{KeyCode, KeyModifiers};

Expand Down
2 changes: 1 addition & 1 deletion src/backend/pty.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::{BackendEvent, PaneId, TerminalBackend};
use crate::util::try_timed_join;
use crate::platform::threading::try_timed_join;
use anyhow::Result;
use portable_pty::{CommandBuilder, NativePtySystem, PtySize, PtySystem};
use std::collections::BTreeMap;
Expand Down
Loading
Loading