From 9a3329ee25a6f5a5dcf8fa2d8824ed9ef02fb720 Mon Sep 17 00:00:00 2001 From: Ilya Grigoriev Date: Sat, 7 Jan 2023 11:09:55 -0800 Subject: [PATCH] `jj resolve --list`: make output aligned If all file names are short enough, this will align the conflict description at 4 spaces past the longest file name, as follows. ``` src/templater.rs 2-sided conflict src/templater_parsers.rs 2-sided conflict ``` If there is a long file name, conflict descriptions will either start or column 35 or one space from a file name, whichever is later. Previously, a single tab was used to separate file name from conflict description. This didn't look as nice as I hoped when multiple files are involved. I also don't think `jj` generally uses tabs in output. The tab uncovered a bug in a watcher program I was using. --- src/commands.rs | 19 ++++++++++----- tests/test_resolve_command.rs | 46 +++++++++++++++++++++-------------- 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/commands.rs b/src/commands.rs index a1c55635c..30570bd4e 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -2467,7 +2467,18 @@ fn print_conflicted_paths( formatter: &mut dyn Formatter, workspace_command: &WorkspaceCommandHelper, ) -> Result<(), CommandError> { - for (repo_path, conflict_id) in conflicts.iter() { + let formatted_paths = conflicts + .iter() + .map(|(path, _id)| workspace_command.format_file_path(path)) + .collect_vec(); + let max_path_len = formatted_paths.iter().map(|p| p.len()).max().unwrap_or(0); + let formatted_paths = formatted_paths + .into_iter() + .map(|p| format!("{:width$}", p, width = max_path_len.min(32) + 3)); + + for ((repo_path, conflict_id), formatted_path) in + std::iter::zip(conflicts.iter(), formatted_paths) + { let conflict = tree.store().read_conflict(repo_path, conflict_id)?; let n_adds = conflict.adds.len(); let sides = n_adds.max(conflict.removes.len() + 1); @@ -2506,11 +2517,7 @@ fn print_conflicted_paths( ); } - write!( - formatter, - "{}\t", - &workspace_command.format_file_path(repo_path) - )?; + write!(formatter, "{formatted_path} ",)?; formatter.with_label("conflict_description", |formatter| { let print_pair = |formatter: &mut dyn Formatter, (text, label): &(String, &str)| { formatter.with_label(label, |fmt| fmt.write_str(text)) diff --git a/tests/test_resolve_command.rs b/tests/test_resolve_command.rs index 41ec684c2..efa8a7a8d 100644 --- a/tests/test_resolve_command.rs +++ b/tests/test_resolve_command.rs @@ -63,7 +63,9 @@ fn test_resolution() { o "###); insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["resolve", "--list"]), - @"file 2-sided conflict"); + @r###" + file 2-sided conflict + "###); insta::assert_snapshot!( std::fs::read_to_string(repo_path.join("file")).unwrap() , @r###" @@ -182,7 +184,7 @@ conflict Working copy now at: 0bb40c908c8b conflict Added 0 files, modified 1 files, removed 0 files After this operation, some files at this revision still have conflicts: - file 2-sided conflict + file 2-sided conflict "###); insta::assert_snapshot!( std::fs::read_to_string(test_env.env_root().join("editor2")).unwrap(), @r###" @@ -207,7 +209,9 @@ conflict 7 7: >>>>>>> "###); insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["resolve", "--list"]), - @"file 2-sided conflict"); + @r###" + file 2-sided conflict + "###); // Check that if merge tool leaves conflict markers in output file but // `merge-tool-edits-conflict-markers=false` or is not specified, @@ -306,7 +310,9 @@ fn test_normal_conflict_input_files() { o "###); insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["resolve", "--list"]), - @"file 2-sided conflict"); + @r###" + file 2-sided conflict + "###); insta::assert_snapshot!( std::fs::read_to_string(repo_path.join("file")).unwrap() , @r###" @@ -345,7 +351,9 @@ fn test_baseless_conflict_input_files() { o "###); insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["resolve", "--list"]), - @"file 2-sided conflict"); + @r###" + file 2-sided conflict + "###); insta::assert_snapshot!( std::fs::read_to_string(repo_path.join("file")).unwrap() , @r###" @@ -374,11 +382,13 @@ fn test_too_many_parents() { create_commit(&test_env, &repo_path, "c", &["base"], &[("file", "c\n")]); create_commit(&test_env, &repo_path, "conflict", &["a", "b", "c"], &[]); insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["resolve", "--list"]), - @"file 3-sided conflict"); + @r###" + file 3-sided conflict + "###); // Test warning color insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["resolve", "--list", "--color=always"]), @r###" - file 3-sided conflict + file 3-sided conflict "###); let error = test_env.jj_cmd_failure(&repo_path, &["resolve"]); @@ -411,7 +421,7 @@ fn test_edit_delete_conflict_input_files() { "###); insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["resolve", "--list"]), @r###" - file 2-sided conflict including 1 deletion + file 2-sided conflict including 1 deletion "###); insta::assert_snapshot!( std::fs::read_to_string(repo_path.join("file")).unwrap() @@ -456,7 +466,7 @@ fn test_file_vs_dir() { insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["resolve", "--list"]), @r###" - file 2-sided conflict including a directory + file 2-sided conflict including a directory "###); let error = test_env.jj_cmd_failure(&repo_path, &["resolve"]); insta::assert_snapshot!(error, @r###" @@ -505,12 +515,12 @@ fn test_description_with_dir_and_deletion() { insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["resolve", "--list"]), @r###" - file 3-sided conflict including 1 deletion and a directory + file 3-sided conflict including 1 deletion and a directory "###); // Test warning color. The deletion is fine, so it's not highlighted insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["resolve", "--list", "--color=always"]), @r###" - file 3-sided conflict including 1 deletion and a directory + file 3-sided conflict including 1 deletion and a directory "###); let error = test_env.jj_cmd_failure(&repo_path, &["resolve"]); insta::assert_snapshot!(error, @r###" @@ -604,14 +614,14 @@ fn test_multiple_conflicts() { "###); insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["resolve", "--list"]), @r###" - another_file 2-sided conflict - this_file_has_a_very_long_name_to_test_padding 2-sided conflict + another_file 2-sided conflict + this_file_has_a_very_long_name_to_test_padding 2-sided conflict "###); // Test colors insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["resolve", "--list", "--color=always"]), @r###" - another_file 2-sided conflict - this_file_has_a_very_long_name_to_test_padding 2-sided conflict + another_file 2-sided conflict + this_file_has_a_very_long_name_to_test_padding 2-sided conflict "###); let editor_script = test_env.set_up_fake_editor(); @@ -623,7 +633,7 @@ fn test_multiple_conflicts() { Working copy now at: 07feb084c0d2 conflict Added 0 files, modified 1 files, removed 0 files After this operation, some files at this revision still have conflicts: - this_file_has_a_very_long_name_to_test_padding 2-sided conflict + this_file_has_a_very_long_name_to_test_padding 2-sided conflict "###); insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["diff"]), @r###" @@ -638,7 +648,7 @@ fn test_multiple_conflicts() { "###); insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["resolve", "--list"]), @r###" - this_file_has_a_very_long_name_to_test_padding 2-sided conflict + this_file_has_a_very_long_name_to_test_padding 2-sided conflict "###); // Repeat the above with the `--quiet` option. @@ -674,7 +684,7 @@ fn test_multiple_conflicts() { "###); insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["resolve", "--list"]), @r###" - this_file_has_a_very_long_name_to_test_padding 2-sided conflict + this_file_has_a_very_long_name_to_test_padding 2-sided conflict "###); std::fs::write( &editor_script,