From 9e1d8af26424e4a19f2bdf740f80c21d1c464f05 Mon Sep 17 00:00:00 2001 From: Stephan Dilly Date: Tue, 9 Jun 2020 17:23:59 +0200 Subject: [PATCH] request commit based diff async --- asyncgit/src/diff.rs | 36 ++++++++++++++++++++++++++++---- asyncgit/src/lib.rs | 2 +- src/components/inspect_commit.rs | 30 ++++++++++++++++++-------- src/tabs/status.rs | 13 ++++++++++-- 4 files changed, 65 insertions(+), 16 deletions(-) diff --git a/asyncgit/src/diff.rs b/asyncgit/src/diff.rs index 7dbea7f3..f13cd06e 100644 --- a/asyncgit/src/diff.rs +++ b/asyncgit/src/diff.rs @@ -9,10 +9,27 @@ use std::{ Arc, Mutex, }, }; +use sync::CommitId; /// -#[derive(Default, Hash, Clone, PartialEq)] -pub struct DiffParams(pub String, pub bool); +#[derive(Hash, Clone, PartialEq)] +pub enum DiffType { + /// diff in a given commit + Commit(CommitId), + /// diff against staged file + Stage, + /// diff against file in workdir + WorkDir, +} + +/// +#[derive(Hash, Clone, PartialEq)] +pub struct DiffParams { + /// path to the file to diff + pub path: String, + /// what kind of diff + pub diff_type: DiffType, +} struct Request(R, Option); @@ -121,8 +138,19 @@ impl AsyncDiff { arc_current: Arc>>, hash: u64, ) -> Result { - let res = - sync::diff::get_diff(CWD, params.0.clone(), params.1)?; + let res = match params.diff_type { + DiffType::Stage => { + sync::diff::get_diff(CWD, params.path.clone(), true)? + } + DiffType::WorkDir => { + sync::diff::get_diff(CWD, params.path.clone(), false)? + } + DiffType::Commit(id) => sync::diff::get_diff_commit( + CWD, + id, + params.path.clone(), + )?, + }; let mut notify = false; { diff --git a/asyncgit/src/lib.rs b/asyncgit/src/lib.rs index 3c973287..f2007a5c 100644 --- a/asyncgit/src/lib.rs +++ b/asyncgit/src/lib.rs @@ -15,7 +15,7 @@ pub mod sync; pub use crate::{ commit_files::AsyncCommitFiles, - diff::{AsyncDiff, DiffParams}, + diff::{AsyncDiff, DiffParams, DiffType}, revlog::{AsyncLog, FetchStatus}, status::{AsyncStatus, StatusParams}, sync::{ diff --git a/src/components/inspect_commit.rs b/src/components/inspect_commit.rs index c96b1182..b73efc26 100644 --- a/src/components/inspect_commit.rs +++ b/src/components/inspect_commit.rs @@ -7,7 +7,9 @@ use crate::{ accessors, keys, queue::Queue, strings, ui::style::Theme, }; use anyhow::Result; -use asyncgit::{sync, AsyncNotification, CWD}; +use asyncgit::{ + sync, AsyncDiff, AsyncNotification, DiffParams, DiffType, +}; use crossbeam_channel::Sender; use crossterm::event::Event; use strings::commands; @@ -23,6 +25,7 @@ pub struct InspectCommitComponent { commit_id: Option, diff: DiffComponent, details: CommitDetailsComponent, + git_diff: AsyncDiff, visible: bool, } @@ -159,6 +162,7 @@ impl InspectCommitComponent { ), diff: DiffComponent::new(None, theme), commit_id: None, + git_diff: AsyncDiff::new(sender.clone()), visible: false, } } @@ -173,7 +177,7 @@ impl InspectCommitComponent { /// pub fn any_work_pending(&self) -> bool { - self.details.any_work_pending() + self.git_diff.is_pending() || self.details.any_work_pending() } /// @@ -185,7 +189,7 @@ impl InspectCommitComponent { if let AsyncNotification::CommitFiles = ev { self.update()? } else if let AsyncNotification::Diff = ev { - self.update()? + self.update_diff()? } } @@ -198,13 +202,21 @@ impl InspectCommitComponent { if let Some(id) = self.commit_id { if let Some(f) = self.details.files().selection_file() { - self.diff.update( - f.path.clone(), - false, - sync::get_diff_commit(CWD, id, f.path)?, - )?; + let diff_params = DiffParams { + path: f.path.clone(), + diff_type: DiffType::Commit(id), + }; - return Ok(()); + if let Some((params, last)) = + self.git_diff.last()? + { + if params == diff_params { + self.diff.update(f.path, false, last)?; + return Ok(()); + } + } + + self.git_diff.request(diff_params)?; } } diff --git a/src/tabs/status.rs b/src/tabs/status.rs index aa71f760..f24bf4f7 100644 --- a/src/tabs/status.rs +++ b/src/tabs/status.rs @@ -13,7 +13,7 @@ use crate::{ use anyhow::Result; use asyncgit::{ sync::{self, status::StatusType}, - AsyncDiff, AsyncNotification, AsyncStatus, DiffParams, + AsyncDiff, AsyncNotification, AsyncStatus, DiffParams, DiffType, StatusParams, CWD, }; use components::{command_pump, visibility_blocking}; @@ -243,7 +243,16 @@ impl Status { /// pub fn update_diff(&mut self) -> Result<()> { if let Some((path, is_stage)) = self.selected_path() { - let diff_params = DiffParams(path.clone(), is_stage); + let diff_type = if is_stage { + DiffType::Stage + } else { + DiffType::WorkDir + }; + + let diff_params = DiffParams { + path: path.clone(), + diff_type, + }; if self.diff.current() == (path.clone(), is_stage) { // we are already showing a diff of the right file