diff --git a/cli/src/cli_util.rs b/cli/src/cli_util.rs index 628de1e0be..c654bc1a7c 100644 --- a/cli/src/cli_util.rs +++ b/cli/src/cli_util.rs @@ -75,7 +75,7 @@ use crate::command_error::{ handle_command_result, internal_error, internal_error_with_message, user_error, user_error_with_hint, user_error_with_message, CommandError, }; -use crate::commit_templater::CommitTemplateLanguageExtension; +use crate::commit_templater::{CommitTemplateLanguage, CommitTemplateLanguageExtension}; use crate::config::{ new_config_path, AnnotatedValue, CommandNameAndArgs, ConfigSource, LayeredConfigs, }; @@ -84,10 +84,11 @@ use crate::git_util::{ is_colocated_git_workspace, print_failed_git_export, print_git_import_stats, }; use crate::merge_tools::{DiffEditor, MergeEditor, MergeToolConfigError}; +use crate::template_builder::TemplateLanguage; use crate::template_parser::TemplateAliasesMap; use crate::templater::Template; use crate::ui::{ColorChoice, Ui}; -use crate::{commit_templater, text_util}; +use crate::{template_builder, text_util}; #[derive(Clone)] struct ChromeTracingFlushGuard { @@ -230,10 +231,25 @@ impl CommandHelper { /// /// For most commands that depend on a loaded repo, you should use /// `WorkspaceCommandHelper::template_aliases_map()` instead. - pub fn load_template_aliases(&self, ui: &Ui) -> Result { + fn load_template_aliases(&self, ui: &Ui) -> Result { load_template_aliases(ui, &self.layered_configs) } + /// Parses template of the given language into evaluation tree. + /// + /// This function also loads template aliases from the settings. Use + /// `WorkspaceCommandHelper::parse_template()` if you've already + /// instantiated the workspace helper. + pub fn parse_template<'a, L: TemplateLanguage<'a> + ?Sized>( + &self, + ui: &Ui, + language: &L, + template_text: &str, + ) -> Result + 'a>, CommandError> { + let aliases = self.load_template_aliases(ui)?; + Ok(template_builder::parse(language, template_text, &aliases)?) + } + pub fn workspace_loader(&self) -> Result<&WorkspaceLoader, CommandError> { self.maybe_workspace_loader.as_ref().map_err(Clone::clone) } @@ -866,20 +882,28 @@ Set which revision the branch points to with `jj branch set {branch_name} -r + ?Sized>( + &self, + language: &L, + template_text: &str, + ) -> Result + 'a>, CommandError> { + let aliases = &self.template_aliases_map; + Ok(template_builder::parse(language, template_text, aliases)?) + } + + /// Parses commit template into evaluation tree. pub fn parse_commit_template( &self, template_text: &str, ) -> Result + '_>, CommandError> { - let id_prefix_context = self.id_prefix_context()?; - let template = commit_templater::parse( + let language = CommitTemplateLanguage::new( self.repo().as_ref(), self.workspace_id(), - id_prefix_context, + self.id_prefix_context()?, self.commit_template_extension.as_deref(), - template_text, - &self.template_aliases_map, - )?; - Ok(template) + ); + self.parse_template(&language, template_text) } fn commit_summary_template(&self) -> Box + '_> { @@ -1350,15 +1374,16 @@ impl WorkspaceCommandTransaction<'_> { ) -> std::io::Result<()> { // TODO: Use the disambiguation revset let id_prefix_context = IdPrefixContext::default(); - let template = commit_templater::parse( + let language = CommitTemplateLanguage::new( self.tx.repo(), self.helper.workspace_id(), &id_prefix_context, self.helper.commit_template_extension.as_deref(), - &self.helper.commit_summary_template_text, - &self.helper.template_aliases_map, - ) - .expect("parse error should be confined by WorkspaceCommandHelper::new()"); + ); + let template = self + .helper + .parse_template(&language, &self.helper.commit_summary_template_text) + .expect("parse error should be confined by WorkspaceCommandHelper::new()"); template.format(commit, formatter) } diff --git a/cli/src/commands/operation.rs b/cli/src/commands/operation.rs index 88190f17eb..7df773befe 100644 --- a/cli/src/commands/operation.rs +++ b/cli/src/commands/operation.rs @@ -26,7 +26,7 @@ use jj_lib::repo::Repo; use crate::cli_util::{short_operation_hash, CommandHelper, LogContentFormat}; use crate::command_error::{user_error, user_error_with_hint, CommandError}; use crate::graphlog::{get_graphlog, Edge}; -use crate::operation_templater; +use crate::operation_templater::OperationTemplateLanguage; use crate::templater::Template as _; use crate::ui::Ui; @@ -158,17 +158,17 @@ fn cmd_op_log( _ => None, }; - let template_string = match &args.template { - Some(value) => value.to_owned(), - None => command.settings().config().get_string("templates.op_log")?, + let template = { + let language = OperationTemplateLanguage::new( + repo_loader.op_store().root_operation_id(), + current_op_id, + ); + let text = match &args.template { + Some(value) => value.to_owned(), + None => command.settings().config().get_string("templates.op_log")?, + }; + command.parse_template(ui, &language, &text)? }; - let template_aliases = command.load_template_aliases(ui)?; - let template = operation_templater::parse( - repo_loader.op_store().root_operation_id(), - current_op_id, - &template_string, - &template_aliases, - )?; let with_content_format = LogContentFormat::new(ui, command.settings())?; ui.request_pager(); diff --git a/cli/src/commit_templater.rs b/cli/src/commit_templater.rs index ba45a549cc..e45759dc69 100644 --- a/cli/src/commit_templater.rs +++ b/cli/src/commit_templater.rs @@ -33,7 +33,7 @@ use crate::template_builder::{ self, merge_fn_map, BuildContext, CoreTemplateBuildFnTable, CoreTemplatePropertyKind, IntoTemplateProperty, TemplateBuildMethodFnMap, TemplateLanguage, }; -use crate::template_parser::{self, FunctionCallNode, TemplateAliasesMap, TemplateParseResult}; +use crate::template_parser::{self, FunctionCallNode, TemplateParseResult}; use crate::templater::{ self, IntoTemplate, PlainTextFormattedProperty, Template, TemplateFunction, TemplateProperty, TemplatePropertyFn, @@ -861,15 +861,3 @@ fn builtin_shortest_id_prefix_methods<'repo>( }); map } - -pub fn parse<'repo>( - repo: &'repo dyn Repo, - workspace_id: &WorkspaceId, - id_prefix_context: &'repo IdPrefixContext, - extension: Option<&dyn CommitTemplateLanguageExtension>, - template_text: &str, - aliases_map: &TemplateAliasesMap, -) -> TemplateParseResult + 'repo>> { - let language = CommitTemplateLanguage::new(repo, workspace_id, id_prefix_context, extension); - template_builder::parse(&language, template_text, aliases_map) -} diff --git a/cli/src/operation_templater.rs b/cli/src/operation_templater.rs index b15c0922cb..0773d0aab1 100644 --- a/cli/src/operation_templater.rs +++ b/cli/src/operation_templater.rs @@ -24,7 +24,7 @@ use crate::template_builder::{ self, BuildContext, CoreTemplateBuildFnTable, CoreTemplatePropertyKind, IntoTemplateProperty, TemplateBuildMethodFnMap, TemplateLanguage, }; -use crate::template_parser::{self, FunctionCallNode, TemplateAliasesMap, TemplateParseResult}; +use crate::template_parser::{self, FunctionCallNode, TemplateParseResult}; use crate::templater::{ IntoTemplate, PlainTextFormattedProperty, Template, TemplateFunction, TemplateProperty, TemplatePropertyFn, TimestampRange, @@ -261,13 +261,3 @@ fn builtin_operation_id_methods() -> OperationTemplateBuildMethodFnMap, - template_text: &str, - aliases_map: &TemplateAliasesMap, -) -> TemplateParseResult>> { - let language = OperationTemplateLanguage::new(root_op_id, current_op_id); - template_builder::parse(&language, template_text, aliases_map) -}