forked from mirrors/jj
diff_util: remove WorkspaceCommandHelper dependency from inner show functions
I've added a struct similar to RevsetWorkspaceContext. It can be a closure, but we'll need to duplicate format_file_path() function anyway if we add commit.diff() template.
This commit is contained in:
parent
b6d95c3504
commit
7341bff2f4
2 changed files with 44 additions and 27 deletions
|
@ -86,6 +86,7 @@ use crate::commit_templater::{CommitTemplateLanguage, CommitTemplateLanguageExte
|
||||||
use crate::config::{
|
use crate::config::{
|
||||||
new_config_path, AnnotatedValue, CommandNameAndArgs, ConfigSource, LayeredConfigs,
|
new_config_path, AnnotatedValue, CommandNameAndArgs, ConfigSource, LayeredConfigs,
|
||||||
};
|
};
|
||||||
|
use crate::diff_util::DiffWorkspaceContext;
|
||||||
use crate::formatter::{FormatRecorder, Formatter, PlainTextFormatter};
|
use crate::formatter::{FormatRecorder, Formatter, PlainTextFormatter};
|
||||||
use crate::git_util::{
|
use crate::git_util::{
|
||||||
is_colocated_git_workspace, print_failed_git_export, print_git_import_stats,
|
is_colocated_git_workspace, print_failed_git_export, print_git_import_stats,
|
||||||
|
@ -807,6 +808,14 @@ impl WorkspaceCommandHelper {
|
||||||
Ok(git_ignores)
|
Ok(git_ignores)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: make it private
|
||||||
|
pub(crate) fn diff_context(&self) -> DiffWorkspaceContext<'_> {
|
||||||
|
DiffWorkspaceContext {
|
||||||
|
cwd: &self.cwd,
|
||||||
|
workspace_root: self.workspace.workspace_root(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Loads diff editor from the settings.
|
/// Loads diff editor from the settings.
|
||||||
///
|
///
|
||||||
/// If the `tool_name` isn't specified, the default editor will be returned.
|
/// If the `tool_name` isn't specified, the default editor will be returned.
|
||||||
|
|
|
@ -16,6 +16,7 @@ use std::cmp::max;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use futures::{try_join, Stream, StreamExt};
|
use futures::{try_join, Stream, StreamExt};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
@ -32,7 +33,7 @@ use jj_lib::repo::Repo;
|
||||||
use jj_lib::repo_path::{RepoPath, RepoPathBuf};
|
use jj_lib::repo_path::{RepoPath, RepoPathBuf};
|
||||||
use jj_lib::settings::{ConfigResultExt as _, UserSettings};
|
use jj_lib::settings::{ConfigResultExt as _, UserSettings};
|
||||||
use jj_lib::store::Store;
|
use jj_lib::store::Store;
|
||||||
use jj_lib::{diff, files};
|
use jj_lib::{diff, file_util, files};
|
||||||
use pollster::FutureExt;
|
use pollster::FutureExt;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
@ -200,6 +201,22 @@ pub enum DiffRenderError {
|
||||||
Io(#[from] io::Error),
|
Io(#[from] io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Workspace information needed to render textual diff.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct DiffWorkspaceContext<'a> {
|
||||||
|
pub cwd: &'a Path,
|
||||||
|
pub workspace_root: &'a Path,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DiffWorkspaceContext<'_> {
|
||||||
|
fn format_file_path(&self, file: &RepoPath) -> String {
|
||||||
|
file_util::relative_path(self.cwd, &file.to_fs_path(self.workspace_root))
|
||||||
|
.to_str()
|
||||||
|
.unwrap()
|
||||||
|
.to_owned()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn show_diff(
|
pub fn show_diff(
|
||||||
ui: &Ui,
|
ui: &Ui,
|
||||||
formatter: &mut dyn Formatter,
|
formatter: &mut dyn Formatter,
|
||||||
|
@ -210,21 +227,22 @@ pub fn show_diff(
|
||||||
formats: &[DiffFormat],
|
formats: &[DiffFormat],
|
||||||
) -> Result<(), DiffRenderError> {
|
) -> Result<(), DiffRenderError> {
|
||||||
let repo = workspace_command.repo().as_ref();
|
let repo = workspace_command.repo().as_ref();
|
||||||
|
let workspace_ctx = workspace_command.diff_context();
|
||||||
for format in formats {
|
for format in formats {
|
||||||
match format {
|
match format {
|
||||||
DiffFormat::Summary => {
|
DiffFormat::Summary => {
|
||||||
let tree_diff = from_tree.diff_stream(to_tree, matcher);
|
let tree_diff = from_tree.diff_stream(to_tree, matcher);
|
||||||
show_diff_summary(formatter, workspace_command, tree_diff)?;
|
show_diff_summary(formatter, tree_diff, &workspace_ctx)?;
|
||||||
}
|
}
|
||||||
DiffFormat::Stat => {
|
DiffFormat::Stat => {
|
||||||
let tree_diff = from_tree.diff_stream(to_tree, matcher);
|
let tree_diff = from_tree.diff_stream(to_tree, matcher);
|
||||||
// TODO: In graph log, graph width should be subtracted
|
// TODO: In graph log, graph width should be subtracted
|
||||||
let width = usize::from(ui.term_width().unwrap_or(80));
|
let width = usize::from(ui.term_width().unwrap_or(80));
|
||||||
show_diff_stat(repo, formatter, workspace_command, tree_diff, width)?;
|
show_diff_stat(repo, formatter, tree_diff, &workspace_ctx, width)?;
|
||||||
}
|
}
|
||||||
DiffFormat::Types => {
|
DiffFormat::Types => {
|
||||||
let tree_diff = from_tree.diff_stream(to_tree, matcher);
|
let tree_diff = from_tree.diff_stream(to_tree, matcher);
|
||||||
show_types(formatter, workspace_command, tree_diff)?;
|
show_types(formatter, tree_diff, &workspace_ctx)?;
|
||||||
}
|
}
|
||||||
DiffFormat::Git { context } => {
|
DiffFormat::Git { context } => {
|
||||||
let tree_diff = from_tree.diff_stream(to_tree, matcher);
|
let tree_diff = from_tree.diff_stream(to_tree, matcher);
|
||||||
|
@ -232,7 +250,7 @@ pub fn show_diff(
|
||||||
}
|
}
|
||||||
DiffFormat::ColorWords { context } => {
|
DiffFormat::ColorWords { context } => {
|
||||||
let tree_diff = from_tree.diff_stream(to_tree, matcher);
|
let tree_diff = from_tree.diff_stream(to_tree, matcher);
|
||||||
show_color_words_diff(repo, formatter, workspace_command, *context, tree_diff)?;
|
show_color_words_diff(repo, formatter, *context, tree_diff, &workspace_ctx)?;
|
||||||
}
|
}
|
||||||
DiffFormat::Tool(tool) => {
|
DiffFormat::Tool(tool) => {
|
||||||
merge_tools::generate_diff(ui, formatter.raw(), from_tree, to_tree, matcher, tool)
|
merge_tools::generate_diff(ui, formatter.raw(), from_tree, to_tree, matcher, tool)
|
||||||
|
@ -462,15 +480,15 @@ fn basic_diff_file_type(value: &MaterializedTreeValue) -> &'static str {
|
||||||
pub fn show_color_words_diff(
|
pub fn show_color_words_diff(
|
||||||
repo: &dyn Repo,
|
repo: &dyn Repo,
|
||||||
formatter: &mut dyn Formatter,
|
formatter: &mut dyn Formatter,
|
||||||
workspace_command: &WorkspaceCommandHelper,
|
|
||||||
num_context_lines: usize,
|
num_context_lines: usize,
|
||||||
tree_diff: TreeDiffStream,
|
tree_diff: TreeDiffStream,
|
||||||
|
workspace_ctx: &DiffWorkspaceContext,
|
||||||
) -> Result<(), DiffRenderError> {
|
) -> Result<(), DiffRenderError> {
|
||||||
formatter.push_label("diff")?;
|
formatter.push_label("diff")?;
|
||||||
let mut diff_stream = materialized_diff_stream(repo.store(), tree_diff);
|
let mut diff_stream = materialized_diff_stream(repo.store(), tree_diff);
|
||||||
async {
|
async {
|
||||||
while let Some((path, diff)) = diff_stream.next().await {
|
while let Some((path, diff)) = diff_stream.next().await {
|
||||||
let ui_path = workspace_command.format_file_path(&path);
|
let ui_path = workspace_ctx.format_file_path(&path);
|
||||||
let (left_value, right_value) = diff?;
|
let (left_value, right_value) = diff?;
|
||||||
if left_value.is_absent() {
|
if left_value.is_absent() {
|
||||||
let description = basic_diff_file_type(&right_value);
|
let description = basic_diff_file_type(&right_value);
|
||||||
|
@ -876,31 +894,21 @@ pub fn show_git_diff(
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
pub fn show_diff_summary(
|
pub fn show_diff_summary(
|
||||||
formatter: &mut dyn Formatter,
|
formatter: &mut dyn Formatter,
|
||||||
workspace_command: &WorkspaceCommandHelper,
|
|
||||||
mut tree_diff: TreeDiffStream,
|
mut tree_diff: TreeDiffStream,
|
||||||
|
workspace_ctx: &DiffWorkspaceContext,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
formatter.with_label("diff", |formatter| -> io::Result<()> {
|
formatter.with_label("diff", |formatter| -> io::Result<()> {
|
||||||
async {
|
async {
|
||||||
while let Some((repo_path, diff)) = tree_diff.next().await {
|
while let Some((repo_path, diff)) = tree_diff.next().await {
|
||||||
let (before, after) = diff.unwrap();
|
let (before, after) = diff.unwrap();
|
||||||
|
let ui_path = workspace_ctx.format_file_path(&repo_path);
|
||||||
if before.is_present() && after.is_present() {
|
if before.is_present() && after.is_present() {
|
||||||
writeln!(
|
writeln!(formatter.labeled("modified"), "M {ui_path}")?;
|
||||||
formatter.labeled("modified"),
|
|
||||||
"M {}",
|
|
||||||
workspace_command.format_file_path(&repo_path)
|
|
||||||
)?;
|
|
||||||
} else if before.is_absent() {
|
} else if before.is_absent() {
|
||||||
writeln!(
|
writeln!(formatter.labeled("added"), "A {ui_path}")?;
|
||||||
formatter.labeled("added"),
|
|
||||||
"A {}",
|
|
||||||
workspace_command.format_file_path(&repo_path)
|
|
||||||
)?;
|
|
||||||
} else {
|
} else {
|
||||||
writeln!(
|
// `R` could be interpreted as "renamed"
|
||||||
formatter.labeled("removed"),
|
writeln!(formatter.labeled("removed"), "D {ui_path}")?;
|
||||||
"D {}", // `R` could be interpreted as "renamed"
|
|
||||||
workspace_command.format_file_path(&repo_path)
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -945,8 +953,8 @@ fn get_diff_stat(
|
||||||
pub fn show_diff_stat(
|
pub fn show_diff_stat(
|
||||||
repo: &dyn Repo,
|
repo: &dyn Repo,
|
||||||
formatter: &mut dyn Formatter,
|
formatter: &mut dyn Formatter,
|
||||||
workspace_command: &WorkspaceCommandHelper,
|
|
||||||
tree_diff: TreeDiffStream,
|
tree_diff: TreeDiffStream,
|
||||||
|
workspace_ctx: &DiffWorkspaceContext,
|
||||||
display_width: usize,
|
display_width: usize,
|
||||||
) -> Result<(), DiffRenderError> {
|
) -> Result<(), DiffRenderError> {
|
||||||
let mut stats: Vec<DiffStat> = vec![];
|
let mut stats: Vec<DiffStat> = vec![];
|
||||||
|
@ -957,7 +965,7 @@ pub fn show_diff_stat(
|
||||||
async {
|
async {
|
||||||
while let Some((repo_path, diff)) = diff_stream.next().await {
|
while let Some((repo_path, diff)) = diff_stream.next().await {
|
||||||
let (left, right) = diff?;
|
let (left, right) = diff?;
|
||||||
let path = workspace_command.format_file_path(&repo_path);
|
let path = workspace_ctx.format_file_path(&repo_path);
|
||||||
let left_content = diff_content(&repo_path, left)?;
|
let left_content = diff_content(&repo_path, left)?;
|
||||||
let right_content = diff_content(&repo_path, right)?;
|
let right_content = diff_content(&repo_path, right)?;
|
||||||
max_path_width = max(max_path_width, path.width());
|
max_path_width = max(max_path_width, path.width());
|
||||||
|
@ -1021,8 +1029,8 @@ pub fn show_diff_stat(
|
||||||
|
|
||||||
pub fn show_types(
|
pub fn show_types(
|
||||||
formatter: &mut dyn Formatter,
|
formatter: &mut dyn Formatter,
|
||||||
workspace_command: &WorkspaceCommandHelper,
|
|
||||||
mut tree_diff: TreeDiffStream,
|
mut tree_diff: TreeDiffStream,
|
||||||
|
workspace_ctx: &DiffWorkspaceContext,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
formatter.with_label("diff", |formatter| {
|
formatter.with_label("diff", |formatter| {
|
||||||
async {
|
async {
|
||||||
|
@ -1033,7 +1041,7 @@ pub fn show_types(
|
||||||
"{}{} {}",
|
"{}{} {}",
|
||||||
diff_summary_char(&before),
|
diff_summary_char(&before),
|
||||||
diff_summary_char(&after),
|
diff_summary_char(&after),
|
||||||
workspace_command.format_file_path(&repo_path)
|
workspace_ctx.format_file_path(&repo_path)
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Reference in a new issue