summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlexandru Macovei <alexnmaco@gmail.com>2022-10-03 13:01:39 +0300
committerextrawurst <776816+extrawurst@users.noreply.github.com>2024-02-12 12:55:10 +0100
commit0383f9517b433f65e705c41b1ce91cb499ae0473 (patch)
tree0d968db1081cbd87ba04347658cc225643eb0105 /src
parent5259fd90b3e7ff16164693f1c0cb402f4d7d2d85 (diff)
(refactor) shorten component creation by grouping common items in an Environment
Diffstat (limited to 'src')
-rw-r--r--src/app.rs280
-rw-r--r--src/components/blame_file.rs23
-rw-r--r--src/components/branchlist.rs16
-rw-r--r--src/components/changes.rs24
-rw-r--r--src/components/commit.rs27
-rw-r--r--src/components/commit_details/compare_details.rs11
-rw-r--r--src/components/commit_details/details.rs14
-rw-r--r--src/components/commit_details/mod.rs42
-rw-r--r--src/components/commitlist.rs17
-rw-r--r--src/components/compare_commits.rs42
-rw-r--r--src/components/create_branch.rs23
-rw-r--r--src/components/cred.rs14
-rw-r--r--src/components/diff.rs20
-rw-r--r--src/components/externaleditor.rs10
-rw-r--r--src/components/fetch.rs26
-rw-r--r--src/components/file_revlog.rs35
-rw-r--r--src/components/fuzzy_find_popup.rs22
-rw-r--r--src/components/help.rs10
-rw-r--r--src/components/inspect_commit.rs42
-rw-r--r--src/components/log_search_popup.rs25
-rw-r--r--src/components/msg.rs10
-rw-r--r--src/components/options_popup.rs16
-rw-r--r--src/components/pull.rs29
-rw-r--r--src/components/push.rs28
-rw-r--r--src/components/push_tags.rs27
-rw-r--r--src/components/rename_branch.rs22
-rw-r--r--src/components/reset.rs13
-rw-r--r--src/components/reset_popup.rs22
-rw-r--r--src/components/revision_files.rs32
-rw-r--r--src/components/revision_files_popup.rs32
-rw-r--r--src/components/stashmsg.rs22
-rw-r--r--src/components/status_tree.rs83
-rw-r--r--src/components/submodules.rs16
-rw-r--r--src/components/syntax_text.rs19
-rw-r--r--src/components/tag_commit.rs18
-rw-r--r--src/components/taglist.rs23
-rw-r--r--src/components/textinput.rs32
-rw-r--r--src/main.rs4
-rw-r--r--src/options.rs11
-rw-r--r--src/tabs/files.rs32
-rw-r--r--src/tabs/revlog.rs51
-rw-r--r--src/tabs/stashing.rs29
-rw-r--r--src/tabs/stashlist.rs22
-rw-r--r--src/tabs/status.rs62
44 files changed, 467 insertions, 911 deletions
diff --git a/src/app.rs b/src/app.rs
index 2bdb2754..3278d0bf 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -113,14 +113,41 @@ pub struct App {
file_to_open: Option<String>,
}
+pub struct Environment {
+ pub queue: Queue,
+ pub theme: SharedTheme,
+ pub key_config: SharedKeyConfig,
+ pub repo: RepoPathRef,
+ pub options: SharedOptions,
+ pub sender_git: Sender<AsyncGitNotification>,
+ pub sender_app: Sender<AsyncAppNotification>,
+}
+
+/// The need to construct a "whatever" environment only arises in testing right now
+#[cfg(test)]
+impl Default for Environment {
+ fn default() -> Self {
+ use crossbeam_channel::unbounded;
+ Self {
+ queue: Queue::new(),
+ theme: Default::default(),
+ key_config: Default::default(),
+ repo: RefCell::new(RepoPath::Path(Default::default())),
+ options: Default::default(),
+ sender_git: unbounded().0,
+ sender_app: unbounded().0,
+ }
+ }
+}
+
// public interface
impl App {
///
#[allow(clippy::too_many_lines)]
pub fn new(
repo: RepoPathRef,
- sender: &Sender<AsyncGitNotification>,
- sender_app: &Sender<AsyncAppNotification>,
+ sender_git: Sender<AsyncGitNotification>,
+ sender_app: Sender<AsyncAppNotification>,
input: Input,
theme: Theme,
key_config: KeyConfig,
@@ -130,219 +157,66 @@ impl App {
let repo_path_text =
repo_work_dir(&repo.borrow()).unwrap_or_default();
- let queue = Queue::new();
- let theme = Rc::new(theme);
- let key_config = Rc::new(key_config);
- let options = Options::new(repo.clone());
+ let env = Environment {
+ queue: Queue::new(),
+ theme: Rc::new(theme),
+ key_config: Rc::new(key_config),
+ options: Options::new(repo.clone()),
+ repo,
+ sender_git,
+ sender_app,
+ };
- let tab = options.borrow().current_tab();
+ let tab = env.options.borrow().current_tab();
let mut app = Self {
input,
- reset: ConfirmComponent::new(
- queue.clone(),
- theme.clone(),
- key_config.clone(),
- ),
- commit: CommitComponent::new(
- repo.clone(),
- queue.clone(),
- theme.clone(),
- key_config.clone(),
- options.clone(),
- ),
+ reset: ConfirmComponent::new(&env),
+ commit: CommitComponent::new(&env),
blame_file_popup: BlameFileComponent::new(
- &repo,
- &queue,
- sender,
- &strings::blame_title(&key_config),
- theme.clone(),
- key_config.clone(),
- ),
- file_revlog_popup: FileRevlogComponent::new(
- &repo,
- &queue,
- sender,
- theme.clone(),
- key_config.clone(),
- options.clone(),
- ),
- revision_files_popup: RevisionFilesPopup::new(
- repo.clone(),
- &queue,
- sender_app,
- sender.clone(),
- theme.clone(),
- key_config.clone(),
- ),
- stashmsg_popup: StashMsgComponent::new(
- repo.clone(),
- queue.clone(),
- theme.clone(),
- key_config.clone(),
- ),
- inspect_commit_popup: InspectCommitComponent::new(
- &repo,
- &queue,
- sender,
- theme.clone(),
- key_config.clone(),
- options.clone(),
- ),
- compare_commits_popup: CompareCommitsComponent::new(
- &repo,
- &queue,
- sender,
- theme.clone(),
- key_config.clone(),
- options.clone(),
- ),
- external_editor_popup: ExternalEditorComponent::new(
- theme.clone(),
- key_config.clone(),
- ),
- push_popup: PushComponent::new(
- &repo,
- &queue,
- sender,
- theme.clone(),
- key_config.clone(),
- ),
- push_tags_popup: PushTagsComponent::new(
- &repo,
- &queue,
- sender,
- theme.clone(),
- key_config.clone(),
- ),
- reset_popup: ResetPopupComponent::new(
- &queue,
- &repo,
- theme.clone(),
- key_config.clone(),
- ),
- pull_popup: PullComponent::new(
- &repo,
- &queue,
- sender,
- theme.clone(),
- key_config.clone(),
- ),
- fetch_popup: FetchComponent::new(
- repo.clone(),
- &queue,
- sender,
- theme.clone(),
- key_config.clone(),
- ),
- tag_commit_popup: TagCommitComponent::new(
- repo.clone(),
- queue.clone(),
- theme.clone(),
- key_config.clone(),
- ),
- create_branch_popup: CreateBranchComponent::new(
- repo.clone(),
- queue.clone(),
- theme.clone(),
- key_config.clone(),
- ),
- rename_branch_popup: RenameBranchComponent::new(
- repo.clone(),
- queue.clone(),
- theme.clone(),
- key_config.clone(),
- ),
- select_branch_popup: BranchListComponent::new(
- repo.clone(),
- queue.clone(),
- theme.clone(),
- key_config.clone(),
- ),
- tags_popup: TagListComponent::new(
- repo.clone(),
- &queue,
- sender,
- theme.clone(),
- key_config.clone(),
- ),
- options_popup: OptionsPopupComponent::new(
- &queue,
- theme.clone(),
- key_config.clone(),
- options.clone(),
- ),
- submodule_popup: SubmodulesListComponent::new(
- repo.clone(),
- &queue,
- theme.clone(),
- key_config.clone(),
- ),
- log_search_popup: LogSearchPopupComponent::new(
- repo.clone(),
- &queue,
- theme.clone(),
- key_config.clone(),
- ),
- fuzzy_find_popup: FuzzyFindPopup::new(
- &queue,
- theme.clone(),
- key_config.clone(),
+ &env,
+ &strings::blame_title(&env.key_config),
),
+ file_revlog_popup: FileRevlogComponent::new(&env),
+ revision_files_popup: RevisionFilesPopup::new(&env),
+ stashmsg_popup: StashMsgComponent::new(&env),
+ inspect_commit_popup: InspectCommitComponent::new(&env),
+ compare_commits_popup: CompareCommitsComponent::new(&env),
+ external_editor_popup: ExternalEditorComponent::new(&env),
+ push_popup: PushComponent::new(&env),
+ push_tags_popup: PushTagsComponent::new(&env),
+ reset_popup: ResetPopupComponent::new(&env),
+ pull_popup: PullComponent::new(&env),
+ fetch_popup: FetchComponent::new(&env),
+ tag_commit_popup: TagCommitComponent::new(&env),
+ create_branch_popup: CreateBranchComponent::new(&env),
+ rename_branch_popup: RenameBranchComponent::new(&env),
+ select_branch_popup: BranchListComponent::new(&env),
+ tags_popup: TagListComponent::new(&env),
+ options_popup: OptionsPopupComponent::new(&env),
+ submodule_popup: SubmodulesListComponent::new(&env),
+ log_search_popup: LogSearchPopupComponent::new(&env),
+ fuzzy_find_popup: FuzzyFindPopup::new(&env),
do_quit: QuitState::None,
cmdbar: RefCell::new(CommandBar::new(
- theme.clone(),
- key_config.clone(),
+ env.theme.clone(),
+ env.key_config.clone(),
)),
- help: HelpComponent::new(
- theme.clone(),
- key_config.clone(),
- ),
- msg: MsgComponent::new(theme.clone(), key_config.clone()),
- revlog: Revlog::new(
- &repo,
- &queue,
- sender,
- theme.clone(),
- key_config.clone(),
- ),
- status_tab: Status::new(
- repo.clone(),
- &queue,
- sender,
- theme.clone(),
- key_config.clone(),
- options.clone(),
- ),
- stashing_tab: Stashing::new(
- &repo,
- sender,
- &queue,
- theme.clone(),
- key_config.clone(),
- ),
- stashlist_tab: StashList::new(
- repo.clone(),
- &queue,
- theme.clone(),
- key_config.clone(),
- ),
- files_tab: FilesTab::new(
- repo.clone(),
- sender_app,
- sender.clone(),
- &queue,
- theme.clone(),
- key_config.clone(),
- ),
+ help: HelpComponent::new(&env),
+ msg: MsgComponent::new(&env),
+ revlog: Revlog::new(&env),
+ status_tab: Status::new(&env),
+ stashing_tab: Stashing::new(&env),
+ stashlist_tab: StashList::new(&env),
+ files_tab: FilesTab::new(&env),
tab: 0,
- queue,
- theme,
- options,
- key_config,
+ queue: env.queue,
+ theme: env.theme,
+ options: env.options,
+ key_config: env.key_config,
requires_redraw: Cell::new(false),
file_to_open: None,
- repo,
+ repo: env.repo,
repo_path_text,
popup_stack: PopupStack::default(),
};
diff --git a/src/components/blame_file.rs b/src/components/blame_file.rs
index 632006fa..2a86aba5 100644
--- a/src/components/blame_file.rs
+++ b/src/components/blame_file.rs
@@ -4,6 +4,7 @@ use super::{
InspectCommitOpen,
};
use crate::{
+ app::Environment,
components::{utils::string_width_align, ScrollType},
keys::{key_match, SharedKeyConfig},
queue::{InternalEvent, Queue, StackablePopupOpen},
@@ -13,10 +14,9 @@ use crate::{
};
use anyhow::Result;
use asyncgit::{
- sync::{BlameHunk, CommitId, FileBlame, RepoPathRef},
+ sync::{BlameHunk, CommitId, FileBlame},
AsyncBlame, AsyncGitNotification, BlameParams,
};
-use crossbeam_channel::Sender;
use crossterm::event::Event;
use ratatui::{
backend::Backend,
@@ -272,28 +272,21 @@ impl Component for BlameFileComponent {
impl BlameFileComponent {
///
- pub fn new(
- repo: &RepoPathRef,
- queue: &Queue,
- sender: &Sender<AsyncGitNotification>,
- title: &str,
- theme: SharedTheme,
- key_config: SharedKeyConfig,
- ) -> Self {
+ pub fn new(env: &Environment, title: &str) -> Self {
Self {
title: String::from(title),
- theme,
+ theme: env.theme.clone(),
async_blame: AsyncBlame::new(
- repo.borrow().clone(),
- sender,
+ env.repo.borrow().clone(),
+ &env.sender_git,
),
- queue: queue.clone(),
+ queue: env.queue.clone(),
visible: false,
params: None,
file_blame: None,
open_request: None,
table_state: std::cell::Cell::new(TableState::default()),
- key_config,
+ key_config: env.key_config.clone(),
current_height: std::cell::Cell::new(0),
}
}
diff --git a/src/components/branchlist.rs b/src/components/branchlist.rs
index b097ce6d..d3cc147a 100644
--- a/src/components/branchlist.rs
+++ b/src/components/branchlist.rs
@@ -4,6 +4,7 @@ use super::{
EventState, FuzzyFinderTarget, InspectCommitOpen,
};
use crate::{
+ app::Environment,
components::ScrollType,
keys::{key_match, SharedKeyConfig},
queue::{
@@ -329,12 +330,7 @@ impl Component for BranchListComponent {
}
impl BranchListComponent {
- pub fn new(
- repo: RepoPathRef,
- queue: Queue,
- theme: SharedTheme,
- key_config: SharedKeyConfig,
- ) -> Self {
+ pub fn new(env: &Environment) -> Self {
Self {
branches: Vec::new(),
local: true,
@@ -342,11 +338,11 @@ impl BranchListComponent {
visible: false,
selection: 0,
scroll: VerticalScroll::new(),
- queue,
- theme,
- key_config,
+ queue: env.queue.clone(),
+ theme: env.theme.clone(),
+ key_config: env.key_config.clone(),
current_height: Cell::new(0),
- repo,
+ repo: env.repo.clone(),
}
}
diff --git a/src/components/changes.rs b/src/components/changes.rs
index 3b573a99..af8d68f0 100644
--- a/src/components/changes.rs
+++ b/src/components/changes.rs
@@ -4,12 +4,12 @@ use super::{
CommandBlocking, DrawableComponent,
};
use crate::{
+ app::Environment,
components::{CommandInfo, Component, EventState},
keys::{key_match, SharedKeyConfig},
options::SharedOptions,
queue::{Action, InternalEvent, NeedsUpdate, Queue, ResetItem},
strings, try_or_popup,
- ui::style::SharedTheme,
};
use anyhow::Result;
use asyncgit::{
@@ -35,28 +35,18 @@ impl ChangesComponent {
//TODO: fix
#[allow(clippy::too_many_arguments)]
pub fn new(
- repo: RepoPathRef,
+ env: &Environment,
title: &str,
focus: bool,
is_working_dir: bool,
- queue: Queue,
- theme: SharedTheme,
- key_config: SharedKeyConfig,
- options: SharedOptions,
) -> Self {
Self {
- files: StatusTreeComponent::new(
- title,
- focus,
- Some(queue.clone()),
- theme,
- key_config.clone(),
- ),
+ files: StatusTreeComponent::new(env, title, focus),
is_working_dir,
- queue,
- key_config,
- options,
- repo,
+ queue: env.queue.clone(),
+ key_config: env.key_config.clone(),
+ options: env.options.clone(),
+ repo: env.repo.clone(),
}
}
diff --git a/src/components/commit.rs b/src/components/commit.rs
index bd762878..8a26ecd3 100644
--- a/src/components/commit.rs
+++ b/src/components/commit.rs
@@ -65,30 +65,25 @@ const FIRST_LINE_LIMIT: usize = 50;
impl CommitComponent {
///
- pub fn new(
- repo: RepoPathRef,
- queue: Queue,
- theme: SharedTheme,
- key_config: SharedKeyConfig,
- options: SharedOptions,
- ) -> Self {
+ pub fn new(env: &crate::app::Environment) -> Self {
Self {
- queue,
+ queue: env.queue.clone(),
mode: Mode::Normal,
input: TextInputComponent::new(
- theme.clone(),
- key_config.clone(),
+ env,
"",
- &strings::commit_msg(&key_config),
+ &strings::commit_msg(&env.key_config),
true,
),
- key_config,
- git_branch_name: cached::BranchName::new(repo.clone()),
+ key_config: env.key_config.clone(),
+ git_branch_name: cached::BranchName::new(
+ env.repo.clone(),
+ ),
commit_template: None,
- theme,
- repo,
+ theme: env.theme.clone(),
+ repo: env.repo.clone(),
commit_msg_history_idx: 0,
- options,
+ options: env.options.clone(),
verify: true,
}
}
diff --git a/src/components/commit_details/compare_details.rs b/src/components/commit_details/compare_details.rs
index 015e3ff3..2f184a25 100644
--- a/src/components/commit_details/compare_details.rs
+++ b/src/components/commit_details/compare_details.rs
@@ -1,6 +1,7 @@
use std::borrow::Cow;
use crate::{
+ app::Environment,
components::{
commit_details::style::{style_detail, Detail},
dialog_paragraph,
@@ -30,16 +31,12 @@ pub struct CompareDetailsComponent {
impl CompareDetailsComponent {
///
- pub const fn new(
- repo: RepoPathRef,
- theme: SharedTheme,
- focused: bool,
- ) -> Self {
+ pub fn new(env: &Environment, focused: bool) -> Self {
Self {
data: None,
- theme,
+ theme: env.theme.clone(),
focused,
- repo,
+ repo: env.repo.clone(),
}
}
diff --git a/src/components/commit_details/details.rs b/src/components/commit_details/details.rs
index 6c1a86c7..e1bce3fd 100644
--- a/src/components/commit_details/details.rs
+++ b/src/components/commit_details/details.rs
@@ -1,4 +1,5 @@
use crate::{
+ app::Environment,
components::{
commit_details::style::style_detail,
dialog_paragraph,
@@ -45,22 +46,17 @@ type WrappedCommitMessage<'a> =
impl DetailsComponent {
///
- pub const fn new(
- repo: RepoPathRef,
- theme: SharedTheme,
- key_config: SharedKeyConfig,
- focused: bool,
- ) -> Self {
+ pub fn new(env: &Environment, focused: bool) -> Self {
Self {
- repo,
+ repo: env.repo.clone(),
data: None,
tags: Vec::new(),
- theme,
+ theme: env.theme.clone(),
focused,
scroll_to_bottom_next_draw: Cell::new(false),
current_width: Cell::new(0),
scroll: VerticalScroll::new(),
- key_config,
+ key_config: env.key_config.clone(),
}
}
diff --git a/src/components/commit_details/mod.rs b/src/components/commit_details/mod.rs
index 35317670..2e14aeca 100644
--- a/src/components/commit_details/mod.rs
+++ b/src/components/commit_details/mod.rs
@@ -8,18 +8,15 @@ use super::{
};
use crate::{
accessors,
+ app::Environment,
keys::{key_match, SharedKeyConfig},
- queue::Queue,
strings,
- ui::style::SharedTheme,
};
use anyhow::Result;
use asyncgit::{
- sync::{CommitTags, RepoPathRef},
- AsyncCommitFiles, AsyncGitNotification, CommitFilesParams,
+ sync::CommitTags, AsyncCommitFiles, CommitFilesParams,
};
use compare_details::CompareDetailsComponent;
-use crossbeam_channel::Sender;
use crossterm::event::Event;
use details::DetailsComponent;
use ratatui::{
@@ -42,39 +39,18 @@ impl CommitDetailsComponent {
accessors!(self, [single_details, compare_details, file_tree]);
///
- pub fn new(
- repo: &RepoPathRef,
- queue: &Queue,
- sender: &Sender<AsyncGitNotification>,
- theme: SharedTheme,
- key_config: SharedKeyConfig,
- ) -> Self {
+ pub fn new(env: &Environment) -> Self {
Self {
- single_details: DetailsComponent::new(
- repo.clone(),
- theme.clone(),
- key_config.clone(),
- false,
- ),
- compare_details: CompareDetailsComponent::new(
- repo.clone(),
- theme.clone(),
- false,
- ),
+ single_details: DetailsComponent::new(env, false),
+ compare_details: CompareDetailsComponent::new(env, false),
git_commit_files: AsyncCommitFiles::new(
- repo.borrow().clone(),
- sender,
- ),
- file_tree: StatusTreeComponent::new(
- "",
- false,
- Some(queue.clone()),
- theme,
- key_config.clone(),
+ env.repo.borrow().clone(),
+ &env.sender_git,
),
+ file_tree: StatusTreeComponent::new(env, "", false),
visible: false,
commit: None,
- key_config,
+ key_config: env.key_config.clone(),
}
}
diff --git a/src/components/commitlist.rs b/src/components/commitlist.rs
index 7f9cef3a..9f2956b7 100644
--- a/src/components/commitlist.rs
+++ b/src/components/commitlist.rs
@@ -1,5 +1,6 @@
use super::utils::logitems::{ItemBatch, LogEntry};
use crate::{
+ app::Environment,
components::{
utils::string_width_align, CommandBlocking, CommandInfo,
Component, DrawableComponent, EventState, ScrollType,
@@ -59,15 +60,9 @@ pub struct CommitList {
impl CommitList {
///
- pub fn new(
- repo: RepoPathRef,
- title: &str,
- theme: SharedTheme,
- queue: Queue,
- key_config: SharedKeyConfig,
- ) -> Self {
+ pub fn new(env: &Environment, title: &str) -> Self {
Self {
- repo,
+ repo: env.repo.clone(),
items: ItemBatch::default(),
marked: Vec::with_capacity(2),
selection: 0,
@@ -80,9 +75,9 @@ impl CommitList {
remote_branches: BTreeMap::default(),
current_size: Cell::new(None),
scroll_top: Cell::new(0),
- theme,
- queue,
- key_config,
+ theme: env.theme.clone(),
+ queue: env.queue.clone(),
+ key_config: env.key_config.clone(),
title: title.into(),
}
}
diff --git a/src/components/compare_commits.rs b/src/components/compare_commits.rs
index db5ea23c..49937c58 100644
--- a/src/components/compare_commits.rs
+++ b/src/components/compare_commits.rs
@@ -5,11 +5,11 @@ use super::{
};
use crate::{
accessors,
+ app::Environment,
keys::{key_match, SharedKeyConfig},
options::SharedOptions,
queue::{InternalEvent, Queue, StackablePopupOpen},
strings,
- ui::style::SharedTheme,
};
use anyhow::Result;
use asyncgit::{
@@ -17,7 +17,6 @@ use asyncgit::{
AsyncDiff, AsyncGitNotification, CommitFilesParams, DiffParams,
DiffType,
};
-use crossbeam_channel::Sender;
use crossterm::event::Event;
use ratatui::{
backend::Backend,
@@ -168,37 +167,20 @@ impl CompareCommitsComponent {
accessors!(self, [diff, details]);
///
- pub fn new(
- repo: &RepoPathRef,
- queue: &Queue,
- sender: &Sender<AsyncGitNotification>,
- theme: SharedTheme,
- key_config: SharedKeyConfig,
- options: SharedOptions,
- ) -> Self {
+ pub fn new(env: &Environment) -> Self {
Self {
- repo: repo.clone(),
- details: CommitDetailsComponent::new(
- repo,
- queue,
- sender,
- theme.clone(),
- key_config.clone(),
- ),
- diff: DiffComponent::new(
- repo.clone(),
- queue.clone(),
- theme,
- key_config.clone(),
- true,</