From 19f2fd03cf1347ae517bd287a4ac04b5be608928 Mon Sep 17 00:00:00 2001 From: Stephan Dilly Date: Sun, 11 Jul 2021 13:24:19 +0200 Subject: [PATCH] app has its own async notifications now (#813) * app has its own async notifications now --- asyncgit/src/lib.rs | 6 --- src/app.rs | 35 ++++++++++-------- src/components/revision_files.rs | 7 ++-- src/components/revision_files_popup.rs | 17 ++------- src/components/syntax_text.rs | 18 ++++++--- src/components/taglist.rs | 19 +++++++--- src/main.rs | 51 ++++++++++++++++++++------ src/tabs/files.rs | 7 ++-- 8 files changed, 97 insertions(+), 63 deletions(-) diff --git a/asyncgit/src/lib.rs b/asyncgit/src/lib.rs index 885f4429..0768bc1c 100644 --- a/asyncgit/src/lib.rs +++ b/asyncgit/src/lib.rs @@ -83,12 +83,6 @@ pub enum AsyncGitNotification { Fetch, /// Blame, - /// - //TODO: this does not belong here - SyntaxHighlighting, - /// - //TODO: this does not belong here - RemoteTags, } /// current working directory `./` diff --git a/src/app.rs b/src/app.rs index 562fccfd..9bc394fd 100644 --- a/src/app.rs +++ b/src/app.rs @@ -18,6 +18,7 @@ use crate::{ strings::{self, order}, tabs::{FilesTab, Revlog, StashList, Stashing, Status}, ui::style::{SharedTheme, Theme}, + AsyncAppNotification, AsyncNotification, }; use anyhow::{bail, Result}; use asyncgit::{sync, AsyncGitNotification, CWD}; @@ -79,6 +80,7 @@ impl App { #[allow(clippy::too_many_lines)] pub fn new( sender: &Sender, + sender_app: &Sender, input: Input, theme: Theme, key_config: KeyConfig, @@ -108,7 +110,7 @@ impl App { ), revision_files_popup: RevisionFilesPopup::new( &queue, - sender, + sender_app, theme.clone(), key_config.clone(), ), @@ -167,7 +169,7 @@ impl App { ), tags_popup: TagListComponent::new( &queue, - sender, + sender_app, theme.clone(), key_config.clone(), ), @@ -206,7 +208,7 @@ impl App { key_config.clone(), ), files_tab: FilesTab::new( - sender, + sender_app, &queue, theme.clone(), key_config.clone(), @@ -342,21 +344,24 @@ impl App { } /// - pub fn update_git( + pub fn update_async( &mut self, - ev: AsyncGitNotification, + ev: AsyncNotification, ) -> Result<()> { - log::trace!("update_git: {:?}", ev); + log::trace!("update_async: {:?}", ev); - self.status_tab.update_git(ev)?; - self.stashing_tab.update_git(ev)?; - self.files_tab.update_git(ev); - self.revlog.update_git(ev)?; - self.blame_file_popup.update_git(ev)?; - self.inspect_commit_popup.update_git(ev)?; - self.push_popup.update_git(ev)?; - self.push_tags_popup.update_git(ev)?; - self.pull_popup.update_git(ev)?; + if let AsyncNotification::Git(ev) = ev { + self.status_tab.update_git(ev)?; + self.stashing_tab.update_git(ev)?; + self.revlog.update_git(ev)?; + self.blame_file_popup.update_git(ev)?; + self.inspect_commit_popup.update_git(ev)?; + self.push_popup.update_git(ev)?; + self.push_tags_popup.update_git(ev)?; + self.pull_popup.update_git(ev)?; + } + + self.files_tab.update_async(ev); self.revision_files_popup.update(ev); self.tags_popup.update(ev); diff --git a/src/components/revision_files.rs b/src/components/revision_files.rs index 85846984..7a3ba043 100644 --- a/src/components/revision_files.rs +++ b/src/components/revision_files.rs @@ -8,11 +8,12 @@ use crate::{ queue::{InternalEvent, Queue}, strings::{self, order}, ui::{self, common_nav, style::SharedTheme}, + AsyncAppNotification, AsyncNotification, }; use anyhow::Result; use asyncgit::{ sync::{self, CommitId, TreeFile}, - AsyncGitNotification, CWD, + CWD, }; use crossbeam_channel::Sender; use crossterm::event::Event; @@ -52,7 +53,7 @@ impl RevisionFilesComponent { /// pub fn new( queue: &Queue, - sender: &Sender, + sender: &Sender, theme: SharedTheme, key_config: SharedKeyConfig, ) -> Self { @@ -90,7 +91,7 @@ impl RevisionFilesComponent { } /// - pub fn update(&mut self, ev: AsyncGitNotification) { + pub fn update(&mut self, ev: AsyncNotification) { self.current_file.update(ev); } diff --git a/src/components/revision_files_popup.rs b/src/components/revision_files_popup.rs index 437fe42d..dcf61e2d 100644 --- a/src/components/revision_files_popup.rs +++ b/src/components/revision_files_popup.rs @@ -8,9 +8,10 @@ use crate::{ queue::Queue, strings::{self}, ui::style::SharedTheme, + AsyncAppNotification, AsyncNotification, }; use anyhow::Result; -use asyncgit::{sync::CommitId, AsyncGitNotification}; +use asyncgit::sync::CommitId; use crossbeam_channel::Sender; use crossterm::event::Event; use tui::{backend::Backend, layout::Rect, widgets::Clear, Frame}; @@ -25,7 +26,7 @@ impl RevisionFilesPopup { /// pub fn new( queue: &Queue, - sender: &Sender, + sender: &Sender, theme: SharedTheme, key_config: SharedKeyConfig, ) -> Self { @@ -50,7 +51,7 @@ impl RevisionFilesPopup { } /// - pub fn update(&mut self, ev: AsyncGitNotification) { + pub fn update(&mut self, ev: AsyncNotification) { self.files.update(ev); } @@ -68,16 +69,6 @@ impl DrawableComponent for RevisionFilesPopup { ) -> Result<()> { if self.is_visible() { f.render_widget(Clear, area); - // f.render_widget( - // Block::default() - // .borders(Borders::TOP) - // .title(Span::styled( - // format!(" {}", self.title), - // self.theme.title(true), - // )) - // .border_style(self.theme.block(true)), - // area, - // ); self.files.draw(f, area)?; } diff --git a/src/components/syntax_text.rs b/src/components/syntax_text.rs index a3850f6d..73de6d7b 100644 --- a/src/components/syntax_text.rs +++ b/src/components/syntax_text.rs @@ -9,12 +9,13 @@ use crate::{ self, common_nav, style::SharedTheme, AsyncSyntaxJob, ParagraphState, ScrollPos, StatefulParagraph, }, + AsyncAppNotification, AsyncNotification, }; use anyhow::Result; use asyncgit::{ asyncjob::AsyncSingleJob, sync::{self, TreeFile}, - AsyncGitNotification, CWD, + CWD, }; use crossbeam_channel::Sender; use crossterm::event::Event; @@ -32,7 +33,7 @@ use tui::{ pub struct SyntaxTextComponent { current_file: Option<(String, Either)>, async_highlighting: - AsyncSingleJob, + AsyncSingleJob, key_config: SharedKeyConfig, paragraph_state: Cell, focused: bool, @@ -42,14 +43,14 @@ pub struct SyntaxTextComponent { impl SyntaxTextComponent { /// pub fn new( - sender: &Sender, + sender: &Sender, key_config: SharedKeyConfig, theme: SharedTheme, ) -> Self { Self { async_highlighting: AsyncSingleJob::new( sender.clone(), - AsyncGitNotification::SyntaxHighlighting, + AsyncAppNotification::SyntaxHighlighting, ), current_file: None, paragraph_state: Cell::new(ParagraphState::default()), @@ -60,8 +61,13 @@ impl SyntaxTextComponent { } /// - pub fn update(&mut self, ev: AsyncGitNotification) { - if ev == AsyncGitNotification::SyntaxHighlighting { + pub fn update(&mut self, ev: AsyncNotification) { + if matches!( + ev, + AsyncNotification::App( + AsyncAppNotification::SyntaxHighlighting + ) + ) { if let Some(job) = self.async_highlighting.take_last() { if let Some((path, content)) = self.current_file.as_mut() diff --git a/src/components/taglist.rs b/src/components/taglist.rs index e4845950..8df70364 100644 --- a/src/components/taglist.rs +++ b/src/components/taglist.rs @@ -8,6 +8,7 @@ use crate::{ queue::{Action, InternalEvent, Queue}, strings, ui::{self, Size}, + AsyncAppNotification, AsyncNotification, }; use anyhow::Result; use asyncgit::{ @@ -46,7 +47,7 @@ pub struct TagListComponent { missing_remote_tags: Option>, basic_credential: Option, async_remote_tags: - AsyncSingleJob, + AsyncSingleJob, key_config: SharedKeyConfig, } @@ -250,7 +251,7 @@ impl Component for TagListComponent { impl TagListComponent { pub fn new( queue: &Queue, - sender: &Sender, + sender: &Sender, theme: SharedTheme, key_config: SharedKeyConfig, ) -> Self { @@ -265,7 +266,7 @@ impl TagListComponent { missing_remote_tags: None, async_remote_tags: AsyncSingleJob::new( sender.clone(), - AsyncGitNotification::RemoteTags, + AsyncAppNotification::RemoteTags, ), key_config, } @@ -297,15 +298,21 @@ impl TagListComponent { } /// - pub fn update(&mut self, event: AsyncGitNotification) { - if event == AsyncGitNotification::RemoteTags { + pub fn update(&mut self, ev: AsyncNotification) { + if matches!( + ev, + AsyncNotification::App(AsyncAppNotification::RemoteTags) + ) { if let Some(job) = self.async_remote_tags.take_last() { if let Some(Ok(missing_remote_tags)) = job.result() { self.missing_remote_tags = Some(missing_remote_tags); } } - } else if event == AsyncGitNotification::PushTags { + } else if matches!( + ev, + AsyncNotification::Git(AsyncGitNotification::PushTags) + ) { self.update_missing_remote_tags(); } } diff --git a/src/main.rs b/src/main.rs index 9c4fae7c..e68013da 100644 --- a/src/main.rs +++ b/src/main.rs @@ -72,10 +72,26 @@ static SPINNER_INTERVAL: Duration = Duration::from_millis(80); pub enum QueueEvent { Tick, SpinnerUpdate, - GitEvent(AsyncGitNotification), + AsyncEvent(AsyncNotification), InputEvent(InputEvent), } +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum AsyncAppNotification { + /// + SyntaxHighlighting, + /// + RemoteTags, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum AsyncNotification { + /// + App(AsyncAppNotification), + /// + Git(AsyncGitNotification), +} + fn main() -> Result<()> { let cliargs = process_cmdline()?; @@ -103,6 +119,7 @@ fn main() -> Result<()> { let mut terminal = start_terminal(io::stdout())?; let (tx_git, rx_git) = unbounded(); + let (tx_app, rx_app) = unbounded(); let input = Input::new(); @@ -110,7 +127,8 @@ fn main() -> Result<()> { let ticker = tick(TICK_INTERVAL); let spinner_ticker = tick(SPINNER_INTERVAL); - let mut app = App::new(&tx_git, input, theme, key_config); + let mut app = + App::new(&tx_git, &tx_app, input, theme, key_config); let mut spinner = Spinner::default(); let mut first_update = true; @@ -123,6 +141,7 @@ fn main() -> Result<()> { select_event( &rx_input, &rx_git, + &rx_app, &ticker, &spinner_ticker, )? @@ -147,13 +166,16 @@ fn main() -> Result<()> { app.event(ev)?; } QueueEvent::Tick => app.update()?, - QueueEvent::GitEvent(ev) - if ev - != AsyncGitNotification::FinishUnchanged => - { - app.update_git(ev)?; + QueueEvent::AsyncEvent(ev) => { + if !matches!( + ev, + AsyncNotification::Git( + AsyncGitNotification::FinishUnchanged + ) + ) { + app.update_async(ev)?; + } } - QueueEvent::GitEvent(..) => (), QueueEvent::SpinnerUpdate => unreachable!(), } @@ -217,6 +239,7 @@ fn valid_path() -> Result { fn select_event( rx_input: &Receiver, rx_git: &Receiver, + rx_app: &Receiver, rx_ticker: &Receiver, rx_spinner: &Receiver, ) -> Result { @@ -224,6 +247,7 @@ fn select_event( sel.recv(rx_input); sel.recv(rx_git); + sel.recv(rx_app); sel.recv(rx_ticker); sel.recv(rx_spinner); @@ -232,9 +256,14 @@ fn select_event( let ev = match index { 0 => oper.recv(rx_input).map(QueueEvent::InputEvent), - 1 => oper.recv(rx_git).map(QueueEvent::GitEvent), - 2 => oper.recv(rx_ticker).map(|_| QueueEvent::Tick), - 3 => oper.recv(rx_spinner).map(|_| QueueEvent::SpinnerUpdate), + 1 => oper.recv(rx_git).map(|e| { + QueueEvent::AsyncEvent(AsyncNotification::Git(e)) + }), + 2 => oper.recv(rx_app).map(|e| { + QueueEvent::AsyncEvent(AsyncNotification::App(e)) + }), + 3 => oper.recv(rx_ticker).map(|_| QueueEvent::Tick), + 4 => oper.recv(rx_spinner).map(|_| QueueEvent::SpinnerUpdate), _ => bail!("unknown select source"), }?; diff --git a/src/tabs/files.rs b/src/tabs/files.rs index 61d60857..f500edd1 100644 --- a/src/tabs/files.rs +++ b/src/tabs/files.rs @@ -12,9 +12,10 @@ use crate::{ keys::SharedKeyConfig, queue::Queue, ui::style::SharedTheme, + AsyncAppNotification, AsyncNotification, }; use anyhow::Result; -use asyncgit::{sync, AsyncGitNotification, CWD}; +use asyncgit::{sync, CWD}; use crossbeam_channel::Sender; pub struct FilesTab { @@ -27,7 +28,7 @@ pub struct FilesTab { impl FilesTab { /// pub fn new( - sender: &Sender, + sender: &Sender, queue: &Queue, theme: SharedTheme, key_config: SharedKeyConfig, @@ -60,7 +61,7 @@ impl FilesTab { } /// - pub fn update_git(&mut self, ev: AsyncGitNotification) { + pub fn update_async(&mut self, ev: AsyncNotification) { if self.is_visible() { self.files.update(ev); }