cli: migrate log formatting options to leverage template aliases

No more format!() template expressions.

We might want a separate namespace for configurable "default" aliases, but
let's start with a simple approach. Even if we had [default-templates]
section, it would be practically the same as [template-aliases] so long as
'default-templates.f()' appears as 'f()' in template.
This commit is contained in:
Yuya Nishihara 2023-02-14 13:20:05 +09:00
parent 7e271347d0
commit a2bc826cf4
2 changed files with 59 additions and 52 deletions

View file

@ -1536,6 +1536,45 @@ fn load_template_aliases(
) -> Result<TemplateAliasesMap, CommandError> {
const TABLE_KEY: &str = "template-aliases";
let mut aliases_map = TemplateAliasesMap::new();
// TODO: Reorganize default template aliases and config knobs:
// - remove these configs and let user override aliases?
// - separate namespace or config section for these "default" aliases? but how?
aliases_map
.insert("description_placeholder", DESCRIPTION_PLACEHOLDER_TEMPLATE)
.unwrap();
let timestamp_template = if settings.relative_timestamps() {
"timestamp.ago()"
} else {
"timestamp"
};
aliases_map
.insert("format_timestamp(timestamp)", timestamp_template)
.unwrap();
let desired_id_len = settings.log_id_preferred_length().unwrap_or(12);
// TODO: If/when this logic is relevant in the `lib` crate, make this into
// and enum similar to `ColorChoice`.
let id_template = match settings.unique_prefixes().as_str() {
"brackets" => format!("id.shortest({desired_id_len}).with_brackets()"),
"styled" => format!("id.shortest({desired_id_len})"),
_ => format!("id.short({desired_id_len})"),
};
aliases_map
.insert("format_short_id(id)", id_template)
.unwrap();
let signature_template = match settings.log_author_format().as_str() {
"none" => r#""""#,
"full" => "signature",
"name" => "signature.name()",
"username" => "signature.username()",
_ => "signature.email()",
};
aliases_map
.insert("format_short_signature(signature)", signature_template)
.unwrap();
let table = settings.config().get_table(TABLE_KEY)?;
for (decl, value) in table.into_iter().sorted_by(|a, b| a.0.cmp(&b.0)) {
let r = value
@ -1567,13 +1606,11 @@ fn parse_commit_summary_template<'a>(
template_parser::parse_commit_template(repo, workspace_id, &s, aliases_map).ok()
})
.unwrap_or_else(|| {
let s = format!(
r#"
let s = r#"
commit_id.short() " "
if(description, description.first_line(), {DESCRIPTION_PLACEHOLDER_TEMPLATE})
"#,
);
template_parser::parse_commit_template(repo, workspace_id, &s, aliases_map).unwrap()
if(description, description.first_line(), description_placeholder)
"#;
template_parser::parse_commit_template(repo, workspace_id, s, aliases_map).unwrap()
})
}

View file

@ -47,7 +47,7 @@ use crate::cli_util::{
self, check_stale_working_copy, print_checkout_stats, resolve_multiple_nonempty_revsets,
resolve_mutliple_nonempty_revsets_flag_guarded, run_ui_editor, serialize_config_value,
short_commit_hash, user_error, user_error_with_hint, Args, CommandError, CommandHelper,
DescriptionArg, RevisionArg, WorkspaceCommandHelper, DESCRIPTION_PLACEHOLDER_TEMPLATE,
DescriptionArg, RevisionArg, WorkspaceCommandHelper,
};
use crate::config::{config_path, AnnotatedValue, ConfigSource};
use crate::diff_util::{self, DiffFormat, DiffFormatArgs};
@ -1280,23 +1280,15 @@ fn cmd_show(ui: &mut Ui, command: &CommandHelper, args: &ShowArgs) -> Result<(),
let commit = workspace_command.resolve_single_rev(&args.revision)?;
// TODO: Add branches, tags, etc
// TODO: Indent the description like Git does
let (author_timestamp_template, committer_timestamp_template) =
if command.settings().relative_timestamps() {
("author.timestamp().ago()", "committer.timestamp().ago()")
} else {
("author.timestamp()", "committer.timestamp()")
};
let template_string = format!(
r#"
let template_string = r#"
"Commit ID: " commit_id "\n"
"Change ID: " change_id "\n"
"Author: " author " (" {author_timestamp_template} ")\n"
"Committer: " committer " (" {committer_timestamp_template} ")\n"
"Author: " author " (" format_timestamp(author.timestamp()) ")\n"
"Committer: " committer " (" format_timestamp(committer.timestamp()) ")\n"
"\n"
if(description, description, {DESCRIPTION_PLACEHOLDER_TEMPLATE} "\n")
"\n""#,
);
let template = workspace_command.parse_commit_template(&template_string)?;
if(description, description, description_placeholder "\n")
"\n""#;
let template = workspace_command.parse_commit_template(template_string)?;
ui.request_pager();
let mut formatter = ui.stdout_formatter();
let formatter = formatter.as_mut();
@ -1414,52 +1406,30 @@ fn cmd_status(
}
fn log_template(settings: &UserSettings) -> String {
let committer_timestamp = if settings.relative_timestamps() {
"committer.timestamp().ago()"
} else {
"committer.timestamp()"
};
let desired_id_len = settings.log_id_preferred_length().unwrap_or(12);
// TODO: If/when this logic is relevant in the `lib` crate, make this into
// and enum similar to `ColorChoice`.
let prefix_format = match settings.unique_prefixes().as_str() {
"brackets" => format!("shortest({desired_id_len}).with_brackets()"),
"styled" => format!("shortest({desired_id_len})"),
_ => format!("short({desired_id_len})"),
};
let author_template = match settings.log_author_format().as_str() {
"none" => r#""""#,
"full" => "author",
"name" => "author.name()",
"username" => "author.username()",
_ => "author.email()",
};
let default_template = format!(
r#"
let default_template = r#"
label(if(current_working_copy, "working_copy"),
separate(" ",
if(divergent,
label("divergent", change_id.{prefix_format} "??"),
change_id.{prefix_format}),
{author_template},
{committer_timestamp},
label("divergent", format_short_id(change_id) "??"),
format_short_id(change_id)),
format_short_signature(author),
format_timestamp(committer.timestamp()),
branches,
tags,
working_copies,
git_head,
commit_id.{prefix_format},
format_short_id(commit_id),
if(conflict, label("conflict", "conflict")),
)
"\n"
if(empty, label("empty", "(empty)") " ")
if(description, description.first_line(), {DESCRIPTION_PLACEHOLDER_TEMPLATE})
if(description, description.first_line(), description_placeholder)
"\n"
)"#,
);
)"#;
settings
.config()
.get_string("template.log.graph")
.unwrap_or(default_template)
.unwrap_or(default_template.to_owned())
}
fn cmd_log(ui: &mut Ui, command: &CommandHelper, args: &LogArgs) -> Result<(), CommandError> {