mirror of
https://github.com/martinvonz/jj.git
synced 2025-05-05 15:32:49 +00:00
Compare commits
6 Commits
deb4f1ba79
...
87f6db0a70
Author | SHA1 | Date | |
---|---|---|---|
|
87f6db0a70 | ||
|
8936a7bc4b | ||
|
780f9e547d | ||
|
b611c313aa | ||
|
7643364a76 | ||
|
577a484d1d |
@ -73,6 +73,11 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
* `jj config edit` will now roll back to previous version if a syntax error has been introduced in the new config.
|
||||
|
||||
* When using dynamic command-line completion, revision names will be completed
|
||||
in more complex expressions. For example, typing
|
||||
`jj log -r first-bookmark..sec` and then pressing Tab could complete the
|
||||
expression to `first-bookmark..second-bookmark`.
|
||||
|
||||
|
||||
### Fixed bugs
|
||||
|
||||
|
@ -18,9 +18,9 @@ use std::rc::Rc;
|
||||
use itertools::Itertools as _;
|
||||
use jj_cli::cli_util::CliRunner;
|
||||
use jj_cli::commit_templater::CommitTemplateBuildFnTable;
|
||||
use jj_cli::commit_templater::CommitTemplateLanguage;
|
||||
use jj_cli::commit_templater::CommitTemplateLanguageExtension;
|
||||
use jj_cli::template_builder::TemplateLanguage as _;
|
||||
use jj_cli::commit_templater::CommitTemplatePropertyKind;
|
||||
use jj_cli::template_builder::CoreTemplatePropertyVar as _;
|
||||
use jj_cli::template_parser;
|
||||
use jj_cli::template_parser::TemplateParseError;
|
||||
use jj_cli::templater::TemplatePropertyExt as _;
|
||||
@ -121,7 +121,7 @@ impl SymbolResolverExtension for TheDigitest {
|
||||
|
||||
impl CommitTemplateLanguageExtension for HexCounter {
|
||||
fn build_fn_table<'repo>(&self) -> CommitTemplateBuildFnTable<'repo> {
|
||||
type L<'repo> = CommitTemplateLanguage<'repo>;
|
||||
type P<'repo> = CommitTemplatePropertyKind<'repo>;
|
||||
let mut table = CommitTemplateBuildFnTable::empty();
|
||||
table.commit_methods.insert(
|
||||
"has_most_digits",
|
||||
@ -133,7 +133,7 @@ impl CommitTemplateLanguageExtension for HexCounter {
|
||||
.count(language.repo());
|
||||
let out_property =
|
||||
property.map(move |commit| num_digits_in_id(commit.id()) == most_digits);
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
table.commit_methods.insert(
|
||||
@ -141,7 +141,7 @@ impl CommitTemplateLanguageExtension for HexCounter {
|
||||
|_language, _diagnostics, _build_context, property, call| {
|
||||
call.expect_no_arguments()?;
|
||||
let out_property = property.map(|commit| num_digits_in_id(commit.id()));
|
||||
Ok(L::wrap_integer(out_property.into_dyn()))
|
||||
Ok(P::wrap_integer(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
table.commit_methods.insert(
|
||||
@ -161,7 +161,7 @@ impl CommitTemplateLanguageExtension for HexCounter {
|
||||
})?;
|
||||
|
||||
let out_property = property.map(move |commit| num_char_in_id(commit, char_arg));
|
||||
Ok(L::wrap_integer(out_property.into_dyn()))
|
||||
Ok(P::wrap_integer(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -14,9 +14,9 @@
|
||||
|
||||
use jj_cli::cli_util::CliRunner;
|
||||
use jj_cli::operation_templater::OperationTemplateBuildFnTable;
|
||||
use jj_cli::operation_templater::OperationTemplateLanguage;
|
||||
use jj_cli::operation_templater::OperationTemplateLanguageExtension;
|
||||
use jj_cli::template_builder::TemplateLanguage as _;
|
||||
use jj_cli::operation_templater::OperationTemplatePropertyKind;
|
||||
use jj_cli::template_builder::CoreTemplatePropertyVar as _;
|
||||
use jj_cli::template_parser;
|
||||
use jj_cli::template_parser::TemplateParseError;
|
||||
use jj_cli::templater::TemplatePropertyExt as _;
|
||||
@ -49,14 +49,14 @@ fn num_char_in_id(operation: Operation, ch_match: char) -> i64 {
|
||||
|
||||
impl OperationTemplateLanguageExtension for HexCounter {
|
||||
fn build_fn_table(&self) -> OperationTemplateBuildFnTable {
|
||||
type L = OperationTemplateLanguage;
|
||||
type P = OperationTemplatePropertyKind;
|
||||
let mut table = OperationTemplateBuildFnTable::empty();
|
||||
table.operation_methods.insert(
|
||||
"num_digits_in_id",
|
||||
|_language, _diagnostics, _build_context, property, call| {
|
||||
call.expect_no_arguments()?;
|
||||
let out_property = property.map(|operation| num_digits_in_id(operation.id()));
|
||||
Ok(L::wrap_integer(out_property.into_dyn()))
|
||||
Ok(P::wrap_integer(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
table.operation_methods.insert(
|
||||
@ -77,7 +77,7 @@ impl OperationTemplateLanguageExtension for HexCounter {
|
||||
|
||||
let out_property =
|
||||
property.map(move |operation| num_char_in_id(operation, char_arg));
|
||||
Ok(L::wrap_integer(out_property.into_dyn()))
|
||||
Ok(P::wrap_integer(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -152,6 +152,7 @@ use crate::command_error::user_error_with_hint;
|
||||
use crate::command_error::CommandError;
|
||||
use crate::commit_templater::CommitTemplateLanguage;
|
||||
use crate::commit_templater::CommitTemplateLanguageExtension;
|
||||
use crate::commit_templater::CommitTemplatePropertyKind;
|
||||
use crate::complete;
|
||||
use crate::config::config_from_environment;
|
||||
use crate::config::parse_config_args;
|
||||
@ -171,6 +172,7 @@ use crate::merge_tools::MergeEditor;
|
||||
use crate::merge_tools::MergeToolConfigError;
|
||||
use crate::operation_templater::OperationTemplateLanguage;
|
||||
use crate::operation_templater::OperationTemplateLanguageExtension;
|
||||
use crate::operation_templater::OperationTemplatePropertyKind;
|
||||
use crate::revset_util;
|
||||
use crate::revset_util::RevsetExpressionEvaluator;
|
||||
use crate::template_builder;
|
||||
@ -1738,7 +1740,7 @@ to the current parents may contain changes from multiple commits.
|
||||
ui,
|
||||
&language,
|
||||
template_text,
|
||||
CommitTemplateLanguage::wrap_commit,
|
||||
CommitTemplatePropertyKind::wrap_commit,
|
||||
)
|
||||
}
|
||||
|
||||
@ -1753,7 +1755,7 @@ to the current parents may contain changes from multiple commits.
|
||||
ui,
|
||||
&language,
|
||||
template_text,
|
||||
OperationTemplateLanguage::wrap_operation,
|
||||
OperationTemplatePropertyKind::wrap_operation,
|
||||
)
|
||||
}
|
||||
|
||||
@ -1778,7 +1780,7 @@ to the current parents may contain changes from multiple commits.
|
||||
self.reparse_valid_template(
|
||||
&language,
|
||||
&self.commit_summary_template_text,
|
||||
CommitTemplateLanguage::wrap_commit,
|
||||
CommitTemplatePropertyKind::wrap_commit,
|
||||
)
|
||||
}
|
||||
|
||||
@ -1788,7 +1790,7 @@ to the current parents may contain changes from multiple commits.
|
||||
self.reparse_valid_template(
|
||||
&language,
|
||||
&self.op_summary_template_text,
|
||||
OperationTemplateLanguage::wrap_operation,
|
||||
OperationTemplatePropertyKind::wrap_operation,
|
||||
)
|
||||
.labeled("operation")
|
||||
}
|
||||
@ -1798,7 +1800,7 @@ to the current parents may contain changes from multiple commits.
|
||||
self.reparse_valid_template(
|
||||
&language,
|
||||
SHORT_CHANGE_ID_TEMPLATE_TEXT,
|
||||
CommitTemplateLanguage::wrap_commit,
|
||||
CommitTemplatePropertyKind::wrap_commit,
|
||||
)
|
||||
}
|
||||
|
||||
@ -2460,7 +2462,7 @@ impl WorkspaceCommandTransaction<'_> {
|
||||
self.helper.reparse_valid_template(
|
||||
&language,
|
||||
&self.helper.commit_summary_template_text,
|
||||
CommitTemplateLanguage::wrap_commit,
|
||||
CommitTemplatePropertyKind::wrap_commit,
|
||||
)
|
||||
}
|
||||
|
||||
@ -2486,7 +2488,7 @@ impl WorkspaceCommandTransaction<'_> {
|
||||
ui,
|
||||
&language,
|
||||
template_text,
|
||||
CommitTemplateLanguage::wrap_commit,
|
||||
CommitTemplatePropertyKind::wrap_commit,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::io::Write as _;
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use itertools::Itertools as _;
|
||||
use jj_lib::backend::CommitId;
|
||||
use jj_lib::commit::CommitIteratorExt as _;
|
||||
@ -47,14 +47,14 @@ pub(crate) struct AbandonArgs {
|
||||
/// The revision(s) to abandon (default: @)
|
||||
#[arg(
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
revisions_pos: Vec<RevisionArg>,
|
||||
#[arg(
|
||||
short = 'r',
|
||||
hide = true,
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
revisions_opt: Vec<RevisionArg>,
|
||||
// TODO: Remove in jj 0.34+
|
||||
|
@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use jj_lib::absorb::absorb_hunks;
|
||||
use jj_lib::absorb::split_hunks_to_trees;
|
||||
use jj_lib::absorb::AbsorbSource;
|
||||
@ -46,7 +46,7 @@ pub(crate) struct AbsorbArgs {
|
||||
long, short,
|
||||
default_value = "@",
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
from: RevisionArg,
|
||||
/// Destination revisions to absorb into
|
||||
@ -56,7 +56,7 @@ pub(crate) struct AbsorbArgs {
|
||||
long, short = 't', visible_alias = "to",
|
||||
default_value = "mutable()",
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
into: Vec<RevisionArg>,
|
||||
/// Move only changes to these paths (instead of all paths)
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
use bstr::ByteVec as _;
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use itertools::Itertools as _;
|
||||
use jj_lib::object_id::ObjectId as _;
|
||||
use jj_lib::rewrite::merge_commit_trees;
|
||||
@ -38,7 +38,7 @@ pub(crate) struct BackoutArgs {
|
||||
long, short,
|
||||
default_value = "@",
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::all_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
revisions: Vec<RevisionArg>,
|
||||
/// The revision to apply the reverse changes on top of
|
||||
@ -48,7 +48,7 @@ pub(crate) struct BackoutArgs {
|
||||
long, short,
|
||||
default_value = "@",
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::all_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
destination: Vec<RevisionArg>,
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use itertools::Itertools as _;
|
||||
use jj_lib::object_id::ObjectId as _;
|
||||
use jj_lib::op_store::RefTarget;
|
||||
@ -41,7 +41,7 @@ pub struct BookmarkCreateArgs {
|
||||
long, short,
|
||||
visible_alias = "to",
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::all_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
revision: Option<RevisionArg>,
|
||||
|
||||
|
@ -33,7 +33,7 @@ use crate::cli_util::CommandHelper;
|
||||
use crate::cli_util::RevisionArg;
|
||||
use crate::command_error::CommandError;
|
||||
use crate::commit_templater::CommitRef;
|
||||
use crate::commit_templater::CommitTemplateLanguage;
|
||||
use crate::commit_templater::CommitTemplatePropertyKind;
|
||||
use crate::complete;
|
||||
use crate::ui::Ui;
|
||||
|
||||
@ -184,7 +184,7 @@ pub fn cmd_bookmark_list(
|
||||
ui,
|
||||
&language,
|
||||
&text,
|
||||
CommitTemplateLanguage::wrap_commit_ref,
|
||||
CommitTemplatePropertyKind::wrap_commit_ref,
|
||||
)?
|
||||
.labeled("bookmark_list")
|
||||
};
|
||||
|
@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use itertools::Itertools as _;
|
||||
use jj_lib::object_id::ObjectId as _;
|
||||
use jj_lib::op_store::RefTarget;
|
||||
@ -47,7 +48,7 @@ pub struct BookmarkMoveArgs {
|
||||
long, short,
|
||||
group = "source",
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::all_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
from: Vec<RevisionArg>,
|
||||
|
||||
@ -58,7 +59,7 @@ pub struct BookmarkMoveArgs {
|
||||
#[arg(
|
||||
long, short,
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::all_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
to: Option<RevisionArg>,
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use itertools::Itertools as _;
|
||||
use jj_lib::object_id::ObjectId as _;
|
||||
use jj_lib::op_store::RefTarget;
|
||||
@ -40,7 +41,7 @@ pub struct BookmarkSetArgs {
|
||||
long, short,
|
||||
visible_alias = "to",
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::all_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
revision: Option<RevisionArg>,
|
||||
|
||||
|
@ -22,7 +22,7 @@ use crate::cli_util::CommandHelper;
|
||||
use crate::cli_util::RemoteBookmarkNamePattern;
|
||||
use crate::command_error::CommandError;
|
||||
use crate::commit_templater::CommitRef;
|
||||
use crate::commit_templater::CommitTemplateLanguage;
|
||||
use crate::commit_templater::CommitTemplatePropertyKind;
|
||||
use crate::complete;
|
||||
use crate::ui::Ui;
|
||||
|
||||
@ -97,7 +97,7 @@ pub fn cmd_bookmark_track(
|
||||
ui,
|
||||
&language,
|
||||
&text,
|
||||
CommitTemplateLanguage::wrap_commit_ref,
|
||||
CommitTemplatePropertyKind::wrap_commit_ref,
|
||||
)?
|
||||
.labeled("bookmark_list")
|
||||
};
|
||||
|
@ -25,7 +25,9 @@ use crate::complete;
|
||||
use crate::config::resolved_config_values;
|
||||
use crate::config::AnnotatedValue;
|
||||
use crate::generic_templater::GenericTemplateLanguage;
|
||||
use crate::template_builder::TemplateLanguage as _;
|
||||
use crate::generic_templater::GenericTemplatePropertyKind;
|
||||
use crate::template_builder::CoreTemplatePropertyVar as _;
|
||||
use crate::template_builder::TemplateLanguage;
|
||||
use crate::templater::TemplatePropertyExt as _;
|
||||
use crate::ui::Ui;
|
||||
|
||||
@ -83,7 +85,7 @@ pub fn cmd_config_list(
|
||||
None => command.settings().get_string("templates.config_list")?,
|
||||
};
|
||||
command
|
||||
.parse_template(ui, &language, &text, GenericTemplateLanguage::wrap_self)?
|
||||
.parse_template(ui, &language, &text, GenericTemplatePropertyKind::wrap_self)?
|
||||
.labeled("config_list")
|
||||
};
|
||||
|
||||
@ -118,25 +120,25 @@ pub fn cmd_config_list(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
type ConfigTemplateLanguage = GenericTemplateLanguage<'static, AnnotatedValue>;
|
||||
|
||||
// AnnotatedValue will be cloned internally in the templater. If the cloning
|
||||
// cost matters, wrap it with Rc.
|
||||
fn config_template_language(
|
||||
settings: &UserSettings,
|
||||
) -> GenericTemplateLanguage<'static, AnnotatedValue> {
|
||||
type L = GenericTemplateLanguage<'static, AnnotatedValue>;
|
||||
let mut language = L::new(settings);
|
||||
fn config_template_language(settings: &UserSettings) -> ConfigTemplateLanguage {
|
||||
type P = <ConfigTemplateLanguage as TemplateLanguage<'static>>::Property;
|
||||
let mut language = ConfigTemplateLanguage::new(settings);
|
||||
language.add_keyword("name", |self_property| {
|
||||
let out_property = self_property.map(|annotated| annotated.name.to_string());
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
});
|
||||
language.add_keyword("value", |self_property| {
|
||||
// .decorated("", "") to trim leading/trailing whitespace
|
||||
let out_property = self_property.map(|annotated| annotated.value.decorated("", ""));
|
||||
Ok(L::wrap_config_value(out_property.into_dyn()))
|
||||
Ok(P::wrap_config_value(out_property.into_dyn()))
|
||||
});
|
||||
language.add_keyword("source", |self_property| {
|
||||
let out_property = self_property.map(|annotated| annotated.source.to_string());
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
});
|
||||
language.add_keyword("path", |self_property| {
|
||||
let out_property = self_property.map(|annotated| {
|
||||
@ -146,11 +148,11 @@ fn config_template_language(
|
||||
.as_ref()
|
||||
.map_or_else(String::new, |path| path.to_string_lossy().into_owned())
|
||||
});
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
});
|
||||
language.add_keyword("overridden", |self_property| {
|
||||
let out_property = self_property.map(|annotated| annotated.is_overridden);
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
});
|
||||
language
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ use std::io;
|
||||
use std::io::Read as _;
|
||||
use std::iter;
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use itertools::Itertools as _;
|
||||
use jj_lib::backend::Signature;
|
||||
use jj_lib::commit::CommitIteratorExt as _;
|
||||
@ -49,14 +49,14 @@ pub(crate) struct DescribeArgs {
|
||||
/// The revision(s) whose description to edit (default: @)
|
||||
#[arg(
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable)
|
||||
)]
|
||||
revisions_pos: Vec<RevisionArg>,
|
||||
#[arg(
|
||||
short = 'r',
|
||||
hide = true,
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable)
|
||||
)]
|
||||
revisions_opt: Vec<RevisionArg>,
|
||||
/// The change description to use (don't open editor)
|
||||
|
@ -12,7 +12,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use indexmap::IndexSet;
|
||||
use itertools::Itertools as _;
|
||||
@ -63,7 +62,7 @@ pub(crate) struct DiffArgs {
|
||||
short,
|
||||
value_name = "REVSETS",
|
||||
alias = "revision",
|
||||
add = ArgValueCandidates::new(complete::all_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
revisions: Option<Vec<RevisionArg>>,
|
||||
/// Show changes from this revision
|
||||
@ -72,7 +71,7 @@ pub(crate) struct DiffArgs {
|
||||
short,
|
||||
conflicts_with = "revisions",
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::all_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
from: Option<RevisionArg>,
|
||||
/// Show changes to this revision
|
||||
@ -81,7 +80,7 @@ pub(crate) struct DiffArgs {
|
||||
short,
|
||||
conflicts_with = "revisions",
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::all_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
to: Option<RevisionArg>,
|
||||
/// Restrict the diff to these paths
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
use std::io::Write as _;
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use itertools::Itertools as _;
|
||||
use jj_lib::matchers::EverythingMatcher;
|
||||
use jj_lib::object_id::ObjectId as _;
|
||||
@ -54,7 +54,7 @@ pub(crate) struct DiffeditArgs {
|
||||
long,
|
||||
short,
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
revision: Option<RevisionArg>,
|
||||
/// Show changes from this revision
|
||||
@ -64,7 +64,7 @@ pub(crate) struct DiffeditArgs {
|
||||
long, short,
|
||||
conflicts_with = "revision",
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::all_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
from: Option<RevisionArg>,
|
||||
/// Edit changes in this revision
|
||||
@ -74,7 +74,7 @@ pub(crate) struct DiffeditArgs {
|
||||
long, short,
|
||||
conflicts_with = "revision",
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
to: Option<RevisionArg>,
|
||||
/// Specify diff editor to be used
|
||||
|
@ -15,7 +15,7 @@
|
||||
use std::io::Write as _;
|
||||
|
||||
use bstr::ByteVec as _;
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use itertools::Itertools as _;
|
||||
use jj_lib::backend::BackendResult;
|
||||
use jj_lib::backend::CommitId;
|
||||
@ -56,14 +56,14 @@ pub(crate) struct DuplicateArgs {
|
||||
/// The revision(s) to duplicate (default: @)
|
||||
#[arg(
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::all_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
revisions_pos: Vec<RevisionArg>,
|
||||
#[arg(
|
||||
short = 'r',
|
||||
hide = true,
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::all_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
revisions_opt: Vec<RevisionArg>,
|
||||
/// The revision(s) to duplicate onto (can be repeated to create a merge
|
||||
@ -72,7 +72,7 @@ pub(crate) struct DuplicateArgs {
|
||||
long,
|
||||
short,
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::all_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
destination: Option<Vec<RevisionArg>>,
|
||||
/// The revision(s) to insert after (can be repeated to create a merge
|
||||
@ -83,7 +83,7 @@ pub(crate) struct DuplicateArgs {
|
||||
visible_alias = "after",
|
||||
conflicts_with = "destination",
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::all_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
insert_after: Option<Vec<RevisionArg>>,
|
||||
/// The revision(s) to insert before (can be repeated to create a merge
|
||||
@ -94,7 +94,7 @@ pub(crate) struct DuplicateArgs {
|
||||
visible_alias = "before",
|
||||
conflicts_with = "destination",
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
insert_before: Option<Vec<RevisionArg>>,
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
use std::io::Write as _;
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use jj_lib::object_id::ObjectId as _;
|
||||
use tracing::instrument;
|
||||
|
||||
@ -34,7 +34,7 @@ use crate::ui::Ui;
|
||||
#[derive(clap::Args, Clone, Debug)]
|
||||
pub(crate) struct EditArgs {
|
||||
/// The commit to edit
|
||||
#[arg(value_name = "REVSET", add = ArgValueCandidates::new(complete::mutable_revisions))]
|
||||
#[arg(value_name = "REVSET", add = ArgValueCompleter::new(complete::revset_expression_mutable))]
|
||||
revision: RevisionArg,
|
||||
/// Ignored (but lets you pass `-r` for consistency with other commands)
|
||||
#[arg(short = 'r', hide = true)]
|
||||
|
@ -15,6 +15,7 @@
|
||||
use std::convert::Infallible;
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use itertools::Itertools as _;
|
||||
use jj_lib::commit::Commit;
|
||||
use jj_lib::dag_walk::topo_order_reverse_ok;
|
||||
@ -29,7 +30,7 @@ use crate::cli_util::CommandHelper;
|
||||
use crate::cli_util::LogContentFormat;
|
||||
use crate::cli_util::RevisionArg;
|
||||
use crate::command_error::CommandError;
|
||||
use crate::commit_templater::CommitTemplateLanguage;
|
||||
use crate::commit_templater::CommitTemplatePropertyKind;
|
||||
use crate::complete;
|
||||
use crate::diff_util::DiffFormatArgs;
|
||||
use crate::graphlog::get_graphlog;
|
||||
@ -46,7 +47,7 @@ pub(crate) struct EvologArgs {
|
||||
long, short,
|
||||
default_value = "@",
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::all_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
revision: RevisionArg,
|
||||
/// Limit number of revisions to show
|
||||
@ -114,7 +115,7 @@ pub(crate) fn cmd_evolog(
|
||||
ui,
|
||||
&language,
|
||||
&template_string,
|
||||
CommitTemplateLanguage::wrap_commit,
|
||||
CommitTemplatePropertyKind::wrap_commit,
|
||||
)?
|
||||
.labeled("log");
|
||||
node_template = workspace_command
|
||||
@ -122,7 +123,7 @@ pub(crate) fn cmd_evolog(
|
||||
ui,
|
||||
&language,
|
||||
&get_node_template(graph_style, workspace_command.settings())?,
|
||||
CommitTemplateLanguage::wrap_commit_opt,
|
||||
CommitTemplatePropertyKind::wrap_commit_opt,
|
||||
)?
|
||||
.labeled("node");
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ use crate::cli_util::RevisionArg;
|
||||
use crate::command_error::user_error;
|
||||
use crate::command_error::CommandError;
|
||||
use crate::commit_templater::AnnotationLine;
|
||||
use crate::commit_templater::CommitTemplateLanguage;
|
||||
use crate::commit_templater::CommitTemplatePropertyKind;
|
||||
use crate::complete;
|
||||
use crate::templater::TemplateRenderer;
|
||||
use crate::ui::Ui;
|
||||
@ -47,7 +47,7 @@ pub(crate) struct FileAnnotateArgs {
|
||||
long,
|
||||
short,
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::all_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
revision: Option<RevisionArg>,
|
||||
/// Render each line using the given template
|
||||
@ -101,7 +101,7 @@ pub(crate) fn cmd_file_annotate(
|
||||
ui,
|
||||
&language,
|
||||
&template_text,
|
||||
CommitTemplateLanguage::wrap_annotation_line,
|
||||
CommitTemplatePropertyKind::wrap_annotation_line,
|
||||
)?;
|
||||
|
||||
// TODO: Should we add an option to limit the domain to e.g. recent commits?
|
||||
|
@ -12,7 +12,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use jj_lib::backend::TreeValue;
|
||||
use jj_lib::merged_tree::MergedTreeBuilder;
|
||||
@ -50,7 +49,7 @@ pub(crate) struct FileChmodArgs {
|
||||
long, short,
|
||||
default_value = "@",
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
revision: RevisionArg,
|
||||
/// Paths to change the executable bit for
|
||||
|
@ -12,13 +12,13 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::cli_util::CommandHelper;
|
||||
use crate::cli_util::RevisionArg;
|
||||
use crate::command_error::CommandError;
|
||||
use crate::commit_templater::CommitTemplateLanguage;
|
||||
use crate::commit_templater::CommitTemplatePropertyKind;
|
||||
use crate::commit_templater::TreeEntry;
|
||||
use crate::complete;
|
||||
use crate::ui::Ui;
|
||||
@ -31,7 +31,7 @@ pub(crate) struct FileListArgs {
|
||||
long, short,
|
||||
default_value = "@",
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::all_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
revision: RevisionArg,
|
||||
|
||||
@ -77,7 +77,7 @@ pub(crate) fn cmd_file_list(
|
||||
ui,
|
||||
&language,
|
||||
&text,
|
||||
CommitTemplateLanguage::wrap_tree_entry,
|
||||
CommitTemplatePropertyKind::wrap_tree_entry,
|
||||
)?
|
||||
.labeled("file_list")
|
||||
};
|
||||
|
@ -15,7 +15,6 @@
|
||||
use std::io;
|
||||
use std::io::Write as _;
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use jj_lib::backend::BackendResult;
|
||||
use jj_lib::conflicts::materialize_merge_result;
|
||||
@ -49,7 +48,7 @@ pub(crate) struct FileShowArgs {
|
||||
long, short,
|
||||
default_value = "@",
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::all_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
revision: RevisionArg,
|
||||
/// Paths to print
|
||||
|
@ -17,7 +17,7 @@ use std::io::Write as _;
|
||||
use std::path::Path;
|
||||
use std::process::Stdio;
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use itertools::Itertools as _;
|
||||
use jj_lib::backend::CommitId;
|
||||
use jj_lib::backend::FileId;
|
||||
@ -108,7 +108,7 @@ pub(crate) struct FixArgs {
|
||||
long,
|
||||
short,
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
source: Vec<RevisionArg>,
|
||||
/// Fix only these paths
|
||||
|
@ -160,7 +160,7 @@ pub struct GitPushArgs {
|
||||
// While `-r` will often be used with mutable revisions, immutable
|
||||
// revisions can be useful as parts of revsets or to push
|
||||
// special-purpose branches.
|
||||
add = ArgValueCandidates::new(complete::all_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
revisions: Vec<RevisionArg>,
|
||||
/// Push this commit by creating a bookmark based on its change ID (can be
|
||||
@ -177,7 +177,7 @@ pub struct GitPushArgs {
|
||||
// recently created mutable revisions, even though it can in theory
|
||||
// be used with immutable ones as well. We can change it if the guess
|
||||
// turns out to be wrong.
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
change: Vec<RevisionArg>,
|
||||
/// Specify a new bookmark name and a revision to push under that name, e.g.
|
||||
|
@ -15,7 +15,6 @@
|
||||
use std::slice;
|
||||
|
||||
use clap::ArgGroup;
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use tracing::instrument;
|
||||
|
||||
@ -41,7 +40,7 @@ pub(crate) struct InterdiffArgs {
|
||||
long,
|
||||
short,
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::all_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
from: Option<RevisionArg>,
|
||||
/// Show changes to this revision
|
||||
@ -49,7 +48,7 @@ pub(crate) struct InterdiffArgs {
|
||||
long,
|
||||
short,
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::all_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
to: Option<RevisionArg>,
|
||||
/// Restrict the diff to these paths
|
||||
|
@ -35,7 +35,7 @@ use crate::cli_util::CommandHelper;
|
||||
use crate::cli_util::LogContentFormat;
|
||||
use crate::cli_util::RevisionArg;
|
||||
use crate::command_error::CommandError;
|
||||
use crate::commit_templater::CommitTemplateLanguage;
|
||||
use crate::commit_templater::CommitTemplatePropertyKind;
|
||||
use crate::complete;
|
||||
use crate::diff_util::DiffFormatArgs;
|
||||
use crate::graphlog::get_graphlog;
|
||||
@ -74,7 +74,7 @@ pub(crate) struct LogArgs {
|
||||
long,
|
||||
short,
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::all_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
revisions: Vec<RevisionArg>,
|
||||
/// Show revisions modifying the given paths
|
||||
@ -176,7 +176,7 @@ pub(crate) fn cmd_log(
|
||||
ui,
|
||||
&language,
|
||||
&template_string,
|
||||
CommitTemplateLanguage::wrap_commit,
|
||||
CommitTemplatePropertyKind::wrap_commit,
|
||||
)?
|
||||
.labeled("log");
|
||||
node_template = workspace_command
|
||||
@ -184,7 +184,7 @@ pub(crate) fn cmd_log(
|
||||
ui,
|
||||
&language,
|
||||
&get_node_template(graph_style, settings)?,
|
||||
CommitTemplateLanguage::wrap_commit_opt,
|
||||
CommitTemplatePropertyKind::wrap_commit_opt,
|
||||
)?
|
||||
.labeled("node");
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
use std::collections::HashSet;
|
||||
use std::io::Write as _;
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use itertools::Itertools as _;
|
||||
use jj_lib::backend::CommitId;
|
||||
use jj_lib::repo::Repo as _;
|
||||
@ -49,7 +49,7 @@ pub(crate) struct NewArgs {
|
||||
#[arg(
|
||||
default_value = "@",
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::all_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
revisions: Option<Vec<RevisionArg>>,
|
||||
/// Ignored (but lets you pass `-d`/`-r` for consistency with other
|
||||
@ -98,7 +98,7 @@ pub(crate) struct NewArgs {
|
||||
conflicts_with = "revisions",
|
||||
value_name = "REVSETS",
|
||||
verbatim_doc_comment,
|
||||
add = ArgValueCandidates::new(complete::all_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
insert_after: Option<Vec<RevisionArg>>,
|
||||
/// Insert the new change before the given commit(s)
|
||||
@ -137,7 +137,7 @@ pub(crate) struct NewArgs {
|
||||
conflicts_with = "revisions",
|
||||
value_name = "REVSETS",
|
||||
verbatim_doc_comment,
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
insert_before: Option<Vec<RevisionArg>>,
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ use jj_lib::revset::RevsetIteratorExt as _;
|
||||
use crate::cli_util::CommandHelper;
|
||||
use crate::cli_util::LogContentFormat;
|
||||
use crate::command_error::CommandError;
|
||||
use crate::commit_templater::CommitTemplateLanguage;
|
||||
use crate::commit_templater::CommitTemplatePropertyKind;
|
||||
use crate::complete;
|
||||
use crate::diff_util::diff_formats_for_log;
|
||||
use crate::diff_util::DiffFormatArgs;
|
||||
@ -132,7 +132,12 @@ pub fn cmd_op_diff(
|
||||
let commit_summary_template = {
|
||||
let language = workspace_env.commit_template_language(merged_repo, &id_prefix_context);
|
||||
let text = settings.get_string("templates.commit_summary")?;
|
||||
workspace_env.parse_template(ui, &language, &text, CommitTemplateLanguage::wrap_commit)?
|
||||
workspace_env.parse_template(
|
||||
ui,
|
||||
&language,
|
||||
&text,
|
||||
CommitTemplatePropertyKind::wrap_commit,
|
||||
)?
|
||||
};
|
||||
|
||||
let op_summary_template = workspace_command.operation_summary_template();
|
||||
|
@ -32,7 +32,7 @@ use crate::cli_util::CommandHelper;
|
||||
use crate::cli_util::LogContentFormat;
|
||||
use crate::cli_util::WorkspaceCommandEnvironment;
|
||||
use crate::command_error::CommandError;
|
||||
use crate::commit_templater::CommitTemplateLanguage;
|
||||
use crate::commit_templater::CommitTemplatePropertyKind;
|
||||
use crate::complete;
|
||||
use crate::diff_util::diff_formats_for_log;
|
||||
use crate::diff_util::DiffFormatArgs;
|
||||
@ -41,6 +41,7 @@ use crate::formatter::Formatter;
|
||||
use crate::graphlog::get_graphlog;
|
||||
use crate::graphlog::GraphStyle;
|
||||
use crate::operation_templater::OperationTemplateLanguage;
|
||||
use crate::operation_templater::OperationTemplatePropertyKind;
|
||||
use crate::ui::Ui;
|
||||
|
||||
/// Show the operation log
|
||||
@ -139,7 +140,7 @@ fn do_op_log(
|
||||
ui,
|
||||
&language,
|
||||
&text,
|
||||
OperationTemplateLanguage::wrap_operation,
|
||||
OperationTemplatePropertyKind::wrap_operation,
|
||||
)?
|
||||
.labeled("operation")
|
||||
.labeled("op_log");
|
||||
@ -148,7 +149,7 @@ fn do_op_log(
|
||||
ui,
|
||||
&language,
|
||||
&get_node_template(graph_style, settings)?,
|
||||
OperationTemplateLanguage::wrap_operation,
|
||||
OperationTemplatePropertyKind::wrap_operation,
|
||||
)?
|
||||
.labeled("node");
|
||||
}
|
||||
@ -173,7 +174,7 @@ fn do_op_log(
|
||||
ui,
|
||||
&language,
|
||||
&template_text,
|
||||
CommitTemplateLanguage::wrap_commit,
|
||||
CommitTemplatePropertyKind::wrap_commit,
|
||||
)?
|
||||
};
|
||||
let path_converter = workspace_env.path_converter();
|
||||
|
@ -19,7 +19,7 @@ use super::diff::show_op_diff;
|
||||
use crate::cli_util::CommandHelper;
|
||||
use crate::cli_util::LogContentFormat;
|
||||
use crate::command_error::CommandError;
|
||||
use crate::commit_templater::CommitTemplateLanguage;
|
||||
use crate::commit_templater::CommitTemplatePropertyKind;
|
||||
use crate::complete;
|
||||
use crate::diff_util::diff_formats_for_log;
|
||||
use crate::diff_util::DiffFormatArgs;
|
||||
@ -66,7 +66,12 @@ pub fn cmd_op_show(
|
||||
let commit_summary_template = {
|
||||
let language = workspace_env.commit_template_language(repo.as_ref(), &id_prefix_context);
|
||||
let text = settings.get_string("templates.commit_summary")?;
|
||||
workspace_env.parse_template(ui, &language, &text, CommitTemplateLanguage::wrap_commit)?
|
||||
workspace_env.parse_template(
|
||||
ui,
|
||||
&language,
|
||||
&text,
|
||||
CommitTemplatePropertyKind::wrap_commit,
|
||||
)?
|
||||
};
|
||||
|
||||
let graph_style = GraphStyle::from_settings(settings)?;
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use indexmap::IndexSet;
|
||||
use itertools::Itertools as _;
|
||||
use jj_lib::backend::CommitId;
|
||||
@ -59,7 +59,7 @@ pub(crate) struct ParallelizeArgs {
|
||||
/// Revisions to parallelize
|
||||
#[arg(
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
revisions: Vec<RevisionArg>,
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ use std::io::Write as _;
|
||||
use std::sync::Arc;
|
||||
|
||||
use clap::ArgGroup;
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use itertools::Itertools as _;
|
||||
use jj_lib::backend::CommitId;
|
||||
use jj_lib::commit::Commit;
|
||||
@ -278,7 +278,7 @@ pub(crate) struct RebaseArgs {
|
||||
long,
|
||||
short,
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
branch: Vec<RevisionArg>,
|
||||
|
||||
@ -294,7 +294,7 @@ pub(crate) struct RebaseArgs {
|
||||
long,
|
||||
short,
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
source: Vec<RevisionArg>,
|
||||
/// Rebase the given revisions, rebasing descendants onto this revision's
|
||||
@ -308,7 +308,7 @@ pub(crate) struct RebaseArgs {
|
||||
long,
|
||||
short,
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
revisions: Vec<RevisionArg>,
|
||||
|
||||
@ -336,7 +336,7 @@ pub struct RebaseDestinationArgs {
|
||||
long,
|
||||
short,
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::all_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
destination: Option<Vec<RevisionArg>>,
|
||||
/// The revision(s) to insert after (can be repeated to create a merge
|
||||
@ -347,7 +347,7 @@ pub struct RebaseDestinationArgs {
|
||||
visible_alias = "after",
|
||||
conflicts_with = "destination",
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::all_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
insert_after: Option<Vec<RevisionArg>>,
|
||||
/// The revision(s) to insert before (can be repeated to create a merge
|
||||
@ -358,7 +358,7 @@ pub struct RebaseDestinationArgs {
|
||||
visible_alias = "before",
|
||||
conflicts_with = "destination",
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
insert_before: Option<Vec<RevisionArg>>,
|
||||
}
|
||||
|
@ -12,7 +12,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use itertools::Itertools as _;
|
||||
use jj_lib::object_id::ObjectId as _;
|
||||
@ -50,7 +49,7 @@ pub(crate) struct ResolveArgs {
|
||||
long, short,
|
||||
default_value = "@",
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
revision: RevisionArg,
|
||||
/// Instead of resolving conflicts, list all the conflicts
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
use std::io::Write as _;
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use indoc::formatdoc;
|
||||
use itertools::Itertools as _;
|
||||
@ -58,7 +57,7 @@ pub(crate) struct RestoreArgs {
|
||||
long,
|
||||
short,
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::all_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
from: Option<RevisionArg>,
|
||||
/// Revision to restore into (destination)
|
||||
@ -66,7 +65,7 @@ pub(crate) struct RestoreArgs {
|
||||
long, short = 't',
|
||||
visible_alias = "to",
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
into: Option<RevisionArg>,
|
||||
/// Undo the changes in a revision as compared to the merge of its parents.
|
||||
@ -81,7 +80,7 @@ pub(crate) struct RestoreArgs {
|
||||
long, short,
|
||||
value_name = "REVSET",
|
||||
conflicts_with_all = ["into", "from"],
|
||||
add = ArgValueCandidates::new(complete::all_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
changes_in: Option<RevisionArg>,
|
||||
/// Prints an error. DO NOT USE.
|
||||
|
@ -16,7 +16,7 @@ use std::collections::HashSet;
|
||||
|
||||
use bstr::ByteVec as _;
|
||||
use clap::ArgGroup;
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use indexmap::IndexSet;
|
||||
use itertools::Itertools as _;
|
||||
use jj_lib::backend::CommitId;
|
||||
@ -48,14 +48,14 @@ pub(crate) struct RevertArgs {
|
||||
#[arg(
|
||||
long, short,
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::all_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
revisions: Vec<RevisionArg>,
|
||||
/// The revision(s) to apply the reverse changes on top of
|
||||
#[arg(
|
||||
long, short,
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::all_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
destination: Option<Vec<RevisionArg>>,
|
||||
/// The revision(s) to insert the reverse changes after (can be repeated to
|
||||
@ -66,7 +66,7 @@ pub(crate) struct RevertArgs {
|
||||
visible_alias = "after",
|
||||
conflicts_with = "destination",
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::all_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
insert_after: Option<Vec<RevisionArg>>,
|
||||
/// The revision(s) to insert the reverse changes before (can be repeated to
|
||||
@ -77,7 +77,7 @@ pub(crate) struct RevertArgs {
|
||||
visible_alias = "before",
|
||||
conflicts_with = "destination",
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
insert_before: Option<Vec<RevisionArg>>,
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use jj_lib::matchers::EverythingMatcher;
|
||||
use tracing::instrument;
|
||||
|
||||
@ -30,7 +31,7 @@ pub(crate) struct ShowArgs {
|
||||
#[arg(
|
||||
default_value = "@",
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::all_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_all),
|
||||
)]
|
||||
revision: RevisionArg,
|
||||
/// Ignored (but lets you pass `-r` for consistency with other commands)
|
||||
|
@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use indexmap::IndexSet;
|
||||
use itertools::Itertools as _;
|
||||
use jj_lib::commit::Commit;
|
||||
@ -52,7 +52,7 @@ pub struct SignArgs {
|
||||
#[arg(
|
||||
long, short,
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
revisions: Vec<RevisionArg>,
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use itertools::Itertools as _;
|
||||
use jj_lib::backend::BackendError;
|
||||
use jj_lib::revset::RevsetExpression;
|
||||
@ -28,7 +28,7 @@ pub(crate) struct SimplifyParentsArgs {
|
||||
long,
|
||||
short,
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
source: Vec<RevisionArg>,
|
||||
/// Simplify specified revision(s) (can be repeated)
|
||||
@ -40,7 +40,7 @@ pub(crate) struct SimplifyParentsArgs {
|
||||
long,
|
||||
short,
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
revisions: Vec<RevisionArg>,
|
||||
}
|
||||
|
@ -13,7 +13,6 @@
|
||||
// limitations under the License.
|
||||
use std::io::Write as _;
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use jj_lib::commit::Commit;
|
||||
use jj_lib::matchers::Matcher;
|
||||
@ -67,7 +66,7 @@ pub(crate) struct SplitArgs {
|
||||
long, short,
|
||||
default_value = "@",
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
revision: RevisionArg,
|
||||
/// Split the revision into two parallel revisions instead of a parent and
|
||||
|
@ -12,7 +12,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use indoc::formatdoc;
|
||||
use itertools::Itertools as _;
|
||||
@ -69,7 +68,7 @@ pub(crate) struct SquashArgs {
|
||||
long,
|
||||
short,
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions)
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
revision: Option<RevisionArg>,
|
||||
/// Revision(s) to squash from (default: @)
|
||||
@ -77,7 +76,7 @@ pub(crate) struct SquashArgs {
|
||||
long, short,
|
||||
conflicts_with = "revision",
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
from: Vec<RevisionArg>,
|
||||
/// Revision to squash into (default: @)
|
||||
@ -86,7 +85,7 @@ pub(crate) struct SquashArgs {
|
||||
conflicts_with = "revision",
|
||||
visible_alias = "to",
|
||||
value_name = "REVSET",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
into: Option<RevisionArg>,
|
||||
/// The description to use for squashed revision (don't open editor)
|
||||
|
@ -18,7 +18,7 @@ use jj_lib::str_util::StringPattern;
|
||||
use crate::cli_util::CommandHelper;
|
||||
use crate::command_error::CommandError;
|
||||
use crate::commit_templater::CommitRef;
|
||||
use crate::commit_templater::CommitTemplateLanguage;
|
||||
use crate::commit_templater::CommitTemplatePropertyKind;
|
||||
use crate::complete;
|
||||
use crate::ui::Ui;
|
||||
|
||||
@ -86,7 +86,7 @@ fn cmd_tag_list(
|
||||
ui,
|
||||
&language,
|
||||
&text,
|
||||
CommitTemplateLanguage::wrap_commit_ref,
|
||||
CommitTemplatePropertyKind::wrap_commit_ref,
|
||||
)?
|
||||
.labeled("tag_list")
|
||||
};
|
||||
|
@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use clap_complete::ArgValueCandidates;
|
||||
use clap_complete::ArgValueCompleter;
|
||||
use indexmap::IndexSet;
|
||||
use itertools::Itertools as _;
|
||||
use jj_lib::commit::Commit;
|
||||
@ -38,7 +38,7 @@ pub struct UnsignArgs {
|
||||
#[arg(
|
||||
long, short,
|
||||
value_name = "REVSETS",
|
||||
add = ArgValueCandidates::new(complete::mutable_revisions),
|
||||
add = ArgValueCompleter::new(complete::revset_expression_mutable),
|
||||
)]
|
||||
revisions: Vec<RevisionArg>,
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ use crate::template_builder::merge_fn_map;
|
||||
use crate::template_builder::BuildContext;
|
||||
use crate::template_builder::CoreTemplateBuildFnTable;
|
||||
use crate::template_builder::CoreTemplatePropertyKind;
|
||||
use crate::template_builder::IntoTemplateProperty;
|
||||
use crate::template_builder::CoreTemplatePropertyVar;
|
||||
use crate::template_builder::TemplateBuildMethodFnMap;
|
||||
use crate::template_builder::TemplateLanguage;
|
||||
use crate::template_parser;
|
||||
@ -164,8 +164,6 @@ impl<'repo> CommitTemplateLanguage<'repo> {
|
||||
impl<'repo> TemplateLanguage<'repo> for CommitTemplateLanguage<'repo> {
|
||||
type Property = CommitTemplatePropertyKind<'repo>;
|
||||
|
||||
template_builder::impl_core_wrap_property_fns!('repo, CommitTemplatePropertyKind::Core);
|
||||
|
||||
fn settings(&self) -> &UserSettings {
|
||||
self.repo.base_repo().settings()
|
||||
}
|
||||
@ -213,8 +211,8 @@ impl<'repo> TemplateLanguage<'repo> for CommitTemplateLanguage<'repo> {
|
||||
build_ctx,
|
||||
property,
|
||||
function,
|
||||
Self::wrap_commit,
|
||||
Self::wrap_commit_list,
|
||||
Self::Property::wrap_commit,
|
||||
Self::Property::wrap_commit_list,
|
||||
)
|
||||
}
|
||||
CommitTemplatePropertyKind::CommitRef(property) => {
|
||||
@ -237,8 +235,8 @@ impl<'repo> TemplateLanguage<'repo> for CommitTemplateLanguage<'repo> {
|
||||
build_ctx,
|
||||
property,
|
||||
function,
|
||||
Self::wrap_commit_ref,
|
||||
Self::wrap_commit_ref_list,
|
||||
Self::Property::wrap_commit_ref,
|
||||
Self::Property::wrap_commit_ref_list,
|
||||
)
|
||||
}
|
||||
CommitTemplatePropertyKind::RepoPath(property) => {
|
||||
@ -281,8 +279,8 @@ impl<'repo> TemplateLanguage<'repo> for CommitTemplateLanguage<'repo> {
|
||||
build_ctx,
|
||||
property,
|
||||
function,
|
||||
Self::wrap_tree_diff_entry,
|
||||
Self::wrap_tree_diff_entry_list,
|
||||
Self::Property::wrap_tree_diff_entry,
|
||||
Self::Property::wrap_tree_diff_entry_list,
|
||||
)
|
||||
}
|
||||
CommitTemplatePropertyKind::TreeEntry(property) => {
|
||||
@ -324,7 +322,7 @@ impl<'repo> TemplateLanguage<'repo> for CommitTemplateLanguage<'repo> {
|
||||
expect_plain_text_expression(self, diagnostics, build_ctx, key_node)?;
|
||||
let out_property = (property, key_property)
|
||||
.map(|(trailers, key)| trailers.iter().any(|t| t.key == key));
|
||||
Ok(Self::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(Self::Property::wrap_boolean(out_property.into_dyn()))
|
||||
} else {
|
||||
template_builder::build_formattable_list_method(
|
||||
self,
|
||||
@ -332,8 +330,8 @@ impl<'repo> TemplateLanguage<'repo> for CommitTemplateLanguage<'repo> {
|
||||
build_ctx,
|
||||
property,
|
||||
function,
|
||||
Self::wrap_trailer,
|
||||
Self::wrap_trailer_list,
|
||||
Self::Property::wrap_trailer,
|
||||
Self::Property::wrap_trailer_list,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -359,120 +357,6 @@ impl<'repo> CommitTemplateLanguage<'repo> {
|
||||
pub fn cache_extension<T: Any>(&self) -> Option<&T> {
|
||||
self.cache_extensions.get::<T>()
|
||||
}
|
||||
|
||||
pub fn wrap_commit(
|
||||
property: BoxedTemplateProperty<'repo, Commit>,
|
||||
) -> CommitTemplatePropertyKind<'repo> {
|
||||
CommitTemplatePropertyKind::Commit(property)
|
||||
}
|
||||
|
||||
pub fn wrap_commit_opt(
|
||||
property: BoxedTemplateProperty<'repo, Option<Commit>>,
|
||||
) -> CommitTemplatePropertyKind<'repo> {
|
||||
CommitTemplatePropertyKind::CommitOpt(property)
|
||||
}
|
||||
|
||||
pub fn wrap_commit_list(
|
||||
property: BoxedTemplateProperty<'repo, Vec<Commit>>,
|
||||
) -> CommitTemplatePropertyKind<'repo> {
|
||||
CommitTemplatePropertyKind::CommitList(property)
|
||||
}
|
||||
|
||||
pub fn wrap_commit_ref(
|
||||
property: BoxedTemplateProperty<'repo, Rc<CommitRef>>,
|
||||
) -> CommitTemplatePropertyKind<'repo> {
|
||||
CommitTemplatePropertyKind::CommitRef(property)
|
||||
}
|
||||
|
||||
pub fn wrap_commit_ref_opt(
|
||||
property: BoxedTemplateProperty<'repo, Option<Rc<CommitRef>>>,
|
||||
) -> CommitTemplatePropertyKind<'repo> {
|
||||
CommitTemplatePropertyKind::CommitRefOpt(property)
|
||||
}
|
||||
|
||||
pub fn wrap_commit_ref_list(
|
||||
property: BoxedTemplateProperty<'repo, Vec<Rc<CommitRef>>>,
|
||||
) -> CommitTemplatePropertyKind<'repo> {
|
||||
CommitTemplatePropertyKind::CommitRefList(property)
|
||||
}
|
||||
|
||||
pub fn wrap_repo_path(
|
||||
property: BoxedTemplateProperty<'repo, RepoPathBuf>,
|
||||
) -> CommitTemplatePropertyKind<'repo> {
|
||||
CommitTemplatePropertyKind::RepoPath(property)
|
||||
}
|
||||
|
||||
pub fn wrap_repo_path_opt(
|
||||
property: BoxedTemplateProperty<'repo, Option<RepoPathBuf>>,
|
||||
) -> CommitTemplatePropertyKind<'repo> {
|
||||
CommitTemplatePropertyKind::RepoPathOpt(property)
|
||||
}
|
||||
|
||||
pub fn wrap_commit_or_change_id(
|
||||
property: BoxedTemplateProperty<'repo, CommitOrChangeId>,
|
||||
) -> CommitTemplatePropertyKind<'repo> {
|
||||
CommitTemplatePropertyKind::CommitOrChangeId(property)
|
||||
}
|
||||
|
||||
pub fn wrap_shortest_id_prefix(
|
||||
property: BoxedTemplateProperty<'repo, ShortestIdPrefix>,
|
||||
) -> CommitTemplatePropertyKind<'repo> {
|
||||
CommitTemplatePropertyKind::ShortestIdPrefix(property)
|
||||
}
|
||||
|
||||
pub fn wrap_tree_diff(
|
||||
property: BoxedTemplateProperty<'repo, TreeDiff>,
|
||||
) -> CommitTemplatePropertyKind<'repo> {
|
||||
CommitTemplatePropertyKind::TreeDiff(property)
|
||||
}
|
||||
|
||||
pub fn wrap_tree_diff_entry(
|
||||
property: BoxedTemplateProperty<'repo, TreeDiffEntry>,
|
||||
) -> CommitTemplatePropertyKind<'repo> {
|
||||
CommitTemplatePropertyKind::TreeDiffEntry(property)
|
||||
}
|
||||
|
||||
pub fn wrap_tree_diff_entry_list(
|
||||
property: BoxedTemplateProperty<'repo, Vec<TreeDiffEntry>>,
|
||||
) -> CommitTemplatePropertyKind<'repo> {
|
||||
CommitTemplatePropertyKind::TreeDiffEntryList(property)
|
||||
}
|
||||
|
||||
pub fn wrap_tree_entry(
|
||||
property: BoxedTemplateProperty<'repo, TreeEntry>,
|
||||
) -> CommitTemplatePropertyKind<'repo> {
|
||||
CommitTemplatePropertyKind::TreeEntry(property)
|
||||
}
|
||||
|
||||
pub fn wrap_diff_stats(
|
||||
property: BoxedTemplateProperty<'repo, DiffStatsFormatted<'repo>>,
|
||||
) -> CommitTemplatePropertyKind<'repo> {
|
||||
CommitTemplatePropertyKind::DiffStats(property)
|
||||
}
|
||||
|
||||
fn wrap_cryptographic_signature_opt(
|
||||
property: BoxedTemplateProperty<'repo, Option<CryptographicSignature>>,
|
||||
) -> CommitTemplatePropertyKind<'repo> {
|
||||
CommitTemplatePropertyKind::CryptographicSignatureOpt(property)
|
||||
}
|
||||
|
||||
pub fn wrap_annotation_line(
|
||||
property: BoxedTemplateProperty<'repo, AnnotationLine>,
|
||||
) -> CommitTemplatePropertyKind<'repo> {
|
||||
CommitTemplatePropertyKind::AnnotationLine(property)
|
||||
}
|
||||
|
||||
pub fn wrap_trailer(
|
||||
property: BoxedTemplateProperty<'repo, Trailer>,
|
||||
) -> CommitTemplatePropertyKind<'repo> {
|
||||
CommitTemplatePropertyKind::Trailer(property)
|
||||
}
|
||||
|
||||
pub fn wrap_trailer_list(
|
||||
property: BoxedTemplateProperty<'repo, Vec<Trailer>>,
|
||||
) -> CommitTemplatePropertyKind<'repo> {
|
||||
CommitTemplatePropertyKind::TrailerList(property)
|
||||
}
|
||||
}
|
||||
|
||||
pub enum CommitTemplatePropertyKind<'repo> {
|
||||
@ -498,7 +382,35 @@ pub enum CommitTemplatePropertyKind<'repo> {
|
||||
TrailerList(BoxedTemplateProperty<'repo, Vec<Trailer>>),
|
||||
}
|
||||
|
||||
impl<'repo> IntoTemplateProperty<'repo> for CommitTemplatePropertyKind<'repo> {
|
||||
impl<'repo> CommitTemplatePropertyKind<'repo> {
|
||||
template_builder::impl_wrap_property_fns!('repo, CommitTemplatePropertyKind, {
|
||||
pub wrap_commit(Commit) => Commit,
|
||||
pub wrap_commit_opt(Option<Commit>) => CommitOpt,
|
||||
pub wrap_commit_list(Vec<Commit>) => CommitList,
|
||||
pub wrap_commit_ref(Rc<CommitRef>) => CommitRef,
|
||||
pub wrap_commit_ref_opt(Option<Rc<CommitRef>>) => CommitRefOpt,
|
||||
pub wrap_commit_ref_list(Vec<Rc<CommitRef>>) => CommitRefList,
|
||||
pub wrap_repo_path(RepoPathBuf) => RepoPath,
|
||||
pub wrap_repo_path_opt(Option<RepoPathBuf>) => RepoPathOpt,
|
||||
pub wrap_commit_or_change_id(CommitOrChangeId) => CommitOrChangeId,
|
||||
pub wrap_shortest_id_prefix(ShortestIdPrefix) => ShortestIdPrefix,
|
||||
pub wrap_tree_diff(TreeDiff) => TreeDiff,
|
||||
pub wrap_tree_diff_entry(TreeDiffEntry) => TreeDiffEntry,
|
||||
pub wrap_tree_diff_entry_list(Vec<TreeDiffEntry>) => TreeDiffEntryList,
|
||||
pub wrap_tree_entry(TreeEntry) => TreeEntry,
|
||||
pub wrap_diff_stats(DiffStatsFormatted<'repo>) => DiffStats,
|
||||
pub wrap_cryptographic_signature_opt(
|
||||
Option<CryptographicSignature>
|
||||
) => CryptographicSignatureOpt,
|
||||
pub wrap_annotation_line(AnnotationLine) => AnnotationLine,
|
||||
pub wrap_trailer(Trailer) => Trailer,
|
||||
pub wrap_trailer_list(Vec<Trailer>) => TrailerList,
|
||||
});
|
||||
}
|
||||
|
||||
impl<'repo> CoreTemplatePropertyVar<'repo> for CommitTemplatePropertyKind<'repo> {
|
||||
template_builder::impl_core_wrap_property_fns!('repo, CommitTemplatePropertyKind::Core);
|
||||
|
||||
fn type_name(&self) -> &'static str {
|
||||
match self {
|
||||
CommitTemplatePropertyKind::Core(property) => property.type_name(),
|
||||
@ -816,7 +728,7 @@ impl<'repo> CommitKeywordCache<'repo> {
|
||||
}
|
||||
|
||||
fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Commit> {
|
||||
type L<'repo> = CommitTemplateLanguage<'repo>;
|
||||
type P<'repo> = CommitTemplatePropertyKind<'repo>;
|
||||
// Not using maplit::hashmap!{} or custom declarative macro here because
|
||||
// code completion inside macro is quite restricted.
|
||||
let mut map = CommitTemplateBuildMethodFnMap::<Commit>::new();
|
||||
@ -826,7 +738,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
function.expect_no_arguments()?;
|
||||
let out_property =
|
||||
self_property.map(|commit| text_util::complete_newline(commit.description()));
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -835,7 +747,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property
|
||||
.map(|commit| trailer::parse_description_trailers(commit.description()));
|
||||
Ok(L::wrap_trailer_list(out_property.into_dyn()))
|
||||
Ok(P::wrap_trailer_list(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -844,7 +756,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
function.expect_no_arguments()?;
|
||||
let out_property =
|
||||
self_property.map(|commit| CommitOrChangeId::Change(commit.change_id().to_owned()));
|
||||
Ok(L::wrap_commit_or_change_id(out_property.into_dyn()))
|
||||
Ok(P::wrap_commit_or_change_id(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -853,7 +765,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
function.expect_no_arguments()?;
|
||||
let out_property =
|
||||
self_property.map(|commit| CommitOrChangeId::Commit(commit.id().to_owned()));
|
||||
Ok(L::wrap_commit_or_change_id(out_property.into_dyn()))
|
||||
Ok(P::wrap_commit_or_change_id(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -862,7 +774,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
function.expect_no_arguments()?;
|
||||
let out_property =
|
||||
self_property.and_then(|commit| Ok(commit.parents().try_collect()?));
|
||||
Ok(L::wrap_commit_list(out_property.into_dyn()))
|
||||
Ok(P::wrap_commit_list(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -870,7 +782,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|commit| commit.author().clone());
|
||||
Ok(L::wrap_signature(out_property.into_dyn()))
|
||||
Ok(P::wrap_signature(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -878,7 +790,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|commit| commit.committer().clone());
|
||||
Ok(L::wrap_signature(out_property.into_dyn()))
|
||||
Ok(P::wrap_signature(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -887,7 +799,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
function.expect_no_arguments()?;
|
||||
let user_email = language.revset_parse_context.user_email.to_owned();
|
||||
let out_property = self_property.map(move |commit| commit.author().email == user_email);
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -895,7 +807,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(CryptographicSignature::new);
|
||||
Ok(L::wrap_cryptographic_signature_opt(out_property.into_dyn()))
|
||||
Ok(P::wrap_cryptographic_signature_opt(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -904,7 +816,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
function.expect_no_arguments()?;
|
||||
let repo = language.repo;
|
||||
let out_property = self_property.map(|commit| extract_working_copies(repo, &commit));
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -915,7 +827,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
let name = language.workspace_name.clone();
|
||||
let out_property = self_property
|
||||
.map(move |commit| Some(commit.id()) == repo.view().get_wc_commit_id(&name));
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -934,7 +846,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
.cloned()
|
||||
.collect()
|
||||
});
|
||||
Ok(L::wrap_commit_ref_list(out_property.into_dyn()))
|
||||
Ok(P::wrap_commit_ref_list(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -953,7 +865,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
.cloned()
|
||||
.collect()
|
||||
});
|
||||
Ok(L::wrap_commit_ref_list(out_property.into_dyn()))
|
||||
Ok(P::wrap_commit_ref_list(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -972,7 +884,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
.cloned()
|
||||
.collect()
|
||||
});
|
||||
Ok(L::wrap_commit_ref_list(out_property.into_dyn()))
|
||||
Ok(P::wrap_commit_ref_list(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -981,7 +893,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
function.expect_no_arguments()?;
|
||||
let index = language.keyword_cache.tags_index(language.repo).clone();
|
||||
let out_property = self_property.map(move |commit| index.get(commit.id()).to_vec());
|
||||
Ok(L::wrap_commit_ref_list(out_property.into_dyn()))
|
||||
Ok(P::wrap_commit_ref_list(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -990,7 +902,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
function.expect_no_arguments()?;
|
||||
let index = language.keyword_cache.git_refs_index(language.repo).clone();
|
||||
let out_property = self_property.map(move |commit| index.get(commit.id()).to_vec());
|
||||
Ok(L::wrap_commit_ref_list(out_property.into_dyn()))
|
||||
Ok(P::wrap_commit_ref_list(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1002,7 +914,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
let target = repo.view().git_head();
|
||||
target.added_ids().contains(commit.id())
|
||||
});
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1015,7 +927,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
let maybe_entries = repo.resolve_change_id(commit.change_id());
|
||||
maybe_entries.map_or(0, |entries| entries.len()) > 1
|
||||
});
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1024,7 +936,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
function.expect_no_arguments()?;
|
||||
let repo = language.repo;
|
||||
let out_property = self_property.map(|commit| commit.is_hidden(repo));
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1036,7 +948,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
.is_immutable_fn(language, function.name_span)?
|
||||
.clone();
|
||||
let out_property = self_property.and_then(move |commit| Ok(is_immutable(commit.id())?));
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1050,7 +962,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
})?;
|
||||
|
||||
let out_property = self_property.and_then(move |commit| Ok(is_contained(commit.id())?));
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1058,7 +970,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.and_then(|commit| Ok(commit.has_conflict()?));
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1067,7 +979,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
function.expect_no_arguments()?;
|
||||
let repo = language.repo;
|
||||
let out_property = self_property.and_then(|commit| Ok(commit.is_empty(repo)?));
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1085,7 +997,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
let matcher: Rc<dyn Matcher> = files.to_matcher().into();
|
||||
let out_property = self_property
|
||||
.and_then(move |commit| Ok(TreeDiff::from_commit(repo, &commit, matcher.clone())?));
|
||||
Ok(L::wrap_tree_diff(out_property.into_dyn()))
|
||||
Ok(P::wrap_tree_diff(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1095,7 +1007,7 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm
|
||||
let repo = language.repo;
|
||||
let out_property =
|
||||
self_property.map(|commit| commit.id() == repo.store().root_commit_id());
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map
|
||||
@ -1385,7 +1297,7 @@ impl Template for Vec<Rc<CommitRef>> {
|
||||
}
|
||||
|
||||
fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Rc<CommitRef>> {
|
||||
type L<'repo> = CommitTemplateLanguage<'repo>;
|
||||
type P<'repo> = CommitTemplatePropertyKind<'repo>;
|
||||
// Not using maplit::hashmap!{} or custom declarative macro here because
|
||||
// code completion inside macro is quite restricted.
|
||||
let mut map = CommitTemplateBuildMethodFnMap::<Rc<CommitRef>>::new();
|
||||
@ -1394,7 +1306,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo,
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|commit_ref| commit_ref.name.clone());
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1403,7 +1315,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo,
|
||||
function.expect_no_arguments()?;
|
||||
let out_property =
|
||||
self_property.map(|commit_ref| commit_ref.remote.clone().unwrap_or_default());
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1411,7 +1323,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo,
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|commit_ref| commit_ref.is_present());
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1419,7 +1331,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo,
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|commit_ref| commit_ref.has_conflict());
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1431,7 +1343,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo,
|
||||
let maybe_id = commit_ref.target.as_normal();
|
||||
Ok(maybe_id.map(|id| repo.store().get_commit(id)).transpose()?)
|
||||
});
|
||||
Ok(L::wrap_commit_opt(out_property.into_dyn()))
|
||||
Ok(P::wrap_commit_opt(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1443,7 +1355,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo,
|
||||
let ids = commit_ref.target.removed_ids();
|
||||
Ok(ids.map(|id| repo.store().get_commit(id)).try_collect()?)
|
||||
});
|
||||
Ok(L::wrap_commit_list(out_property.into_dyn()))
|
||||
Ok(P::wrap_commit_list(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1455,7 +1367,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo,
|
||||
let ids = commit_ref.target.added_ids();
|
||||
Ok(ids.map(|id| repo.store().get_commit(id)).try_collect()?)
|
||||
});
|
||||
Ok(L::wrap_commit_list(out_property.into_dyn()))
|
||||
Ok(P::wrap_commit_list(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1463,7 +1375,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo,
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|commit_ref| commit_ref.is_tracked());
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1471,7 +1383,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo,
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|commit_ref| commit_ref.is_tracking_present());
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1481,7 +1393,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo,
|
||||
let repo = language.repo;
|
||||
let out_property =
|
||||
self_property.and_then(|commit_ref| commit_ref.tracking_ahead_count(repo));
|
||||
Ok(L::wrap_size_hint(out_property.into_dyn()))
|
||||
Ok(P::wrap_size_hint(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1491,7 +1403,7 @@ fn builtin_commit_ref_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo,
|
||||
let repo = language.repo;
|
||||
let out_property =
|
||||
self_property.and_then(|commit_ref| commit_ref.tracking_behind_count(repo));
|
||||
Ok(L::wrap_size_hint(out_property.into_dyn()))
|
||||
Ok(P::wrap_size_hint(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map
|
||||
@ -1556,7 +1468,7 @@ impl Template for RepoPathBuf {
|
||||
}
|
||||
|
||||
fn builtin_repo_path_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, RepoPathBuf> {
|
||||
type L<'repo> = CommitTemplateLanguage<'repo>;
|
||||
type P<'repo> = CommitTemplatePropertyKind<'repo>;
|
||||
// Not using maplit::hashmap!{} or custom declarative macro here because
|
||||
// code completion inside macro is quite restricted.
|
||||
let mut map = CommitTemplateBuildMethodFnMap::<RepoPathBuf>::new();
|
||||
@ -1566,7 +1478,7 @@ fn builtin_repo_path_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, R
|
||||
function.expect_no_arguments()?;
|
||||
let path_converter = language.path_converter;
|
||||
let out_property = self_property.map(|path| path_converter.format_file_path(&path));
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1574,7 +1486,7 @@ fn builtin_repo_path_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, R
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|path| Some(path.parent()?.to_owned()));
|
||||
Ok(L::wrap_repo_path_opt(out_property.into_dyn()))
|
||||
Ok(P::wrap_repo_path_opt(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map
|
||||
@ -1627,7 +1539,7 @@ impl Template for CommitOrChangeId {
|
||||
|
||||
fn builtin_commit_or_change_id_methods<'repo>(
|
||||
) -> CommitTemplateBuildMethodFnMap<'repo, CommitOrChangeId> {
|
||||
type L<'repo> = CommitTemplateLanguage<'repo>;
|
||||
type P<'repo> = CommitTemplatePropertyKind<'repo>;
|
||||
// Not using maplit::hashmap!{} or custom declarative macro here because
|
||||
// code completion inside macro is quite restricted.
|
||||
let mut map = CommitTemplateBuildMethodFnMap::<CommitOrChangeId>::new();
|
||||
@ -1644,7 +1556,7 @@ fn builtin_commit_or_change_id_methods<'repo>(
|
||||
CommitOrChangeId::Change(id) => id.hex(),
|
||||
}
|
||||
});
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1663,7 +1575,7 @@ fn builtin_commit_or_change_id_methods<'repo>(
|
||||
.transpose()?;
|
||||
let out_property =
|
||||
(self_property, len_property).map(|(id, len)| id.short(len.unwrap_or(12)));
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1698,7 +1610,7 @@ fn builtin_commit_or_change_id_methods<'repo>(
|
||||
};
|
||||
let out_property = (self_property, len_property)
|
||||
.map(move |(id, len)| id.shortest(repo, &index, len.unwrap_or(0)));
|
||||
Ok(L::wrap_shortest_id_prefix(out_property.into_dyn()))
|
||||
Ok(P::wrap_shortest_id_prefix(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map
|
||||
@ -1734,7 +1646,7 @@ impl ShortestIdPrefix {
|
||||
|
||||
fn builtin_shortest_id_prefix_methods<'repo>(
|
||||
) -> CommitTemplateBuildMethodFnMap<'repo, ShortestIdPrefix> {
|
||||
type L<'repo> = CommitTemplateLanguage<'repo>;
|
||||
type P<'repo> = CommitTemplatePropertyKind<'repo>;
|
||||
// Not using maplit::hashmap!{} or custom declarative macro here because
|
||||
// code completion inside macro is quite restricted.
|
||||
let mut map = CommitTemplateBuildMethodFnMap::<ShortestIdPrefix>::new();
|
||||
@ -1743,7 +1655,7 @@ fn builtin_shortest_id_prefix_methods<'repo>(
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|id| id.prefix);
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1751,7 +1663,7 @@ fn builtin_shortest_id_prefix_methods<'repo>(
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|id| id.rest);
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1759,7 +1671,7 @@ fn builtin_shortest_id_prefix_methods<'repo>(
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|id| id.to_upper());
|
||||
Ok(L::wrap_shortest_id_prefix(out_property.into_dyn()))
|
||||
Ok(P::wrap_shortest_id_prefix(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1767,7 +1679,7 @@ fn builtin_shortest_id_prefix_methods<'repo>(
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|id| id.to_lower());
|
||||
Ok(L::wrap_shortest_id_prefix(out_property.into_dyn()))
|
||||
Ok(P::wrap_shortest_id_prefix(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map
|
||||
@ -1843,7 +1755,7 @@ where
|
||||
}
|
||||
|
||||
fn builtin_tree_diff_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, TreeDiff> {
|
||||
type L<'repo> = CommitTemplateLanguage<'repo>;
|
||||
type P<'repo> = CommitTemplatePropertyKind<'repo>;
|
||||
// Not using maplit::hashmap!{} or custom declarative macro here because
|
||||
// code completion inside macro is quite restricted.
|
||||
let mut map = CommitTemplateBuildMethodFnMap::<TreeDiff>::new();
|
||||
@ -1854,7 +1766,7 @@ fn builtin_tree_diff_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, T
|
||||
// TODO: cache and reuse diff entries within the current evaluation?
|
||||
let out_property =
|
||||
self_property.and_then(|diff| Ok(diff.collect_entries().block_on()?));
|
||||
Ok(L::wrap_tree_diff_entry_list(out_property.into_dyn()))
|
||||
Ok(P::wrap_tree_diff_entry_list(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1896,7 +1808,7 @@ fn builtin_tree_diff_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, T
|
||||
})
|
||||
})
|
||||
.into_template();
|
||||
Ok(L::wrap_template(template))
|
||||
Ok(P::wrap_template(template))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1936,7 +1848,7 @@ fn builtin_tree_diff_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, T
|
||||
})
|
||||
})
|
||||
.into_template();
|
||||
Ok(L::wrap_template(template))
|
||||
Ok(P::wrap_template(template))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1970,7 +1882,7 @@ fn builtin_tree_diff_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, T
|
||||
width: width.unwrap_or(80),
|
||||
})
|
||||
});
|
||||
Ok(L::wrap_diff_stats(out_property.into_dyn()))
|
||||
Ok(P::wrap_diff_stats(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -1985,7 +1897,7 @@ fn builtin_tree_diff_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, T
|
||||
})
|
||||
})
|
||||
.into_template();
|
||||
Ok(L::wrap_template(template))
|
||||
Ok(P::wrap_template(template))
|
||||
},
|
||||
);
|
||||
// TODO: add support for external tools
|
||||
@ -2036,7 +1948,7 @@ impl TreeDiffEntry {
|
||||
|
||||
fn builtin_tree_diff_entry_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, TreeDiffEntry>
|
||||
{
|
||||
type L<'repo> = CommitTemplateLanguage<'repo>;
|
||||
type P<'repo> = CommitTemplatePropertyKind<'repo>;
|
||||
// Not using maplit::hashmap!{} or custom declarative macro here because
|
||||
// code completion inside macro is quite restricted.
|
||||
let mut map = CommitTemplateBuildMethodFnMap::<TreeDiffEntry>::new();
|
||||
@ -2045,7 +1957,7 @@ fn builtin_tree_diff_entry_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'r
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|entry| entry.path.target);
|
||||
Ok(L::wrap_repo_path(out_property.into_dyn()))
|
||||
Ok(P::wrap_repo_path(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -2053,7 +1965,7 @@ fn builtin_tree_diff_entry_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'r
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|entry| entry.status_label().to_owned());
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
// TODO: add status_code() or status_char()?
|
||||
@ -2062,7 +1974,7 @@ fn builtin_tree_diff_entry_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'r
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(TreeDiffEntry::into_source_entry);
|
||||
Ok(L::wrap_tree_entry(out_property.into_dyn()))
|
||||
Ok(P::wrap_tree_entry(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -2070,7 +1982,7 @@ fn builtin_tree_diff_entry_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'r
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(TreeDiffEntry::into_target_entry);
|
||||
Ok(L::wrap_tree_entry(out_property.into_dyn()))
|
||||
Ok(P::wrap_tree_entry(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map
|
||||
@ -2084,7 +1996,7 @@ pub struct TreeEntry {
|
||||
}
|
||||
|
||||
fn builtin_tree_entry_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, TreeEntry> {
|
||||
type L<'repo> = CommitTemplateLanguage<'repo>;
|
||||
type P<'repo> = CommitTemplatePropertyKind<'repo>;
|
||||
// Not using maplit::hashmap!{} or custom declarative macro here because
|
||||
// code completion inside macro is quite restricted.
|
||||
let mut map = CommitTemplateBuildMethodFnMap::<TreeEntry>::new();
|
||||
@ -2093,7 +2005,7 @@ fn builtin_tree_entry_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo,
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|entry| entry.path);
|
||||
Ok(L::wrap_repo_path(out_property.into_dyn()))
|
||||
Ok(P::wrap_repo_path(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -2101,7 +2013,7 @@ fn builtin_tree_entry_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo,
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|entry| !entry.value.is_resolved());
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -2110,7 +2022,7 @@ fn builtin_tree_entry_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo,
|
||||
function.expect_no_arguments()?;
|
||||
let out_property =
|
||||
self_property.map(|entry| describe_file_type(&entry.value).to_owned());
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -2119,7 +2031,7 @@ fn builtin_tree_entry_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo,
|
||||
function.expect_no_arguments()?;
|
||||
let out_property =
|
||||
self_property.map(|entry| is_executable_file(&entry.value).unwrap_or_default());
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map
|
||||
@ -2161,7 +2073,7 @@ impl Template for DiffStatsFormatted<'_> {
|
||||
}
|
||||
|
||||
fn builtin_diff_stats_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, DiffStats> {
|
||||
type L<'repo> = CommitTemplateLanguage<'repo>;
|
||||
type P<'repo> = CommitTemplatePropertyKind<'repo>;
|
||||
// Not using maplit::hashmap!{} or custom declarative macro here because
|
||||
// code completion inside macro is quite restricted.
|
||||
let mut map = CommitTemplateBuildMethodFnMap::<DiffStats>::new();
|
||||
@ -2172,7 +2084,7 @@ fn builtin_diff_stats_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo,
|
||||
function.expect_no_arguments()?;
|
||||
let out_property =
|
||||
self_property.and_then(|stats| Ok(stats.count_total_added().try_into()?));
|
||||
Ok(L::wrap_integer(out_property.into_dyn()))
|
||||
Ok(P::wrap_integer(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -2181,7 +2093,7 @@ fn builtin_diff_stats_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo,
|
||||
function.expect_no_arguments()?;
|
||||
let out_property =
|
||||
self_property.and_then(|stats| Ok(stats.count_total_removed().try_into()?));
|
||||
Ok(L::wrap_integer(out_property.into_dyn()))
|
||||
Ok(P::wrap_integer(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map
|
||||
@ -2223,7 +2135,7 @@ impl CryptographicSignature {
|
||||
|
||||
fn builtin_cryptographic_signature_methods<'repo>(
|
||||
) -> CommitTemplateBuildMethodFnMap<'repo, CryptographicSignature> {
|
||||
type L<'repo> = CommitTemplateLanguage<'repo>;
|
||||
type P<'repo> = CommitTemplatePropertyKind<'repo>;
|
||||
// Not using maplit::hashmap!{} or custom declarative macro here because
|
||||
// code completion inside macro is quite restricted.
|
||||
let mut map = CommitTemplateBuildMethodFnMap::<CryptographicSignature>::new();
|
||||
@ -2236,7 +2148,7 @@ fn builtin_cryptographic_signature_methods<'repo>(
|
||||
Err(SignError::InvalidSignatureFormat) => Ok("invalid".to_string()),
|
||||
Err(err) => Err(err.into()),
|
||||
});
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -2244,7 +2156,7 @@ fn builtin_cryptographic_signature_methods<'repo>(
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.and_then(|sig| Ok(sig.key()?));
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -2252,7 +2164,7 @@ fn builtin_cryptographic_signature_methods<'repo>(
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.and_then(|sig| Ok(sig.display()?));
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map
|
||||
@ -2268,14 +2180,14 @@ pub struct AnnotationLine {
|
||||
|
||||
fn builtin_annotation_line_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, AnnotationLine>
|
||||
{
|
||||
type L<'repo> = CommitTemplateLanguage<'repo>;
|
||||
type P<'repo> = CommitTemplatePropertyKind<'repo>;
|
||||
let mut map = CommitTemplateBuildMethodFnMap::<AnnotationLine>::new();
|
||||
map.insert(
|
||||
"commit",
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|line| line.commit);
|
||||
Ok(L::wrap_commit(out_property.into_dyn()))
|
||||
Ok(P::wrap_commit(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -2284,7 +2196,7 @@ fn builtin_annotation_line_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'r
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|line| line.content);
|
||||
// TODO: Add Bytes or BString template type?
|
||||
Ok(L::wrap_template(out_property.into_template()))
|
||||
Ok(P::wrap_template(out_property.into_template()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -2292,7 +2204,7 @@ fn builtin_annotation_line_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'r
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.and_then(|line| Ok(line.line_number.try_into()?));
|
||||
Ok(L::wrap_integer(out_property.into_dyn()))
|
||||
Ok(P::wrap_integer(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -2300,7 +2212,7 @@ fn builtin_annotation_line_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'r
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|line| line.first_line_in_hunk);
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map
|
||||
@ -2319,14 +2231,14 @@ impl Template for Vec<Trailer> {
|
||||
}
|
||||
|
||||
fn builtin_trailer_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Trailer> {
|
||||
type L<'repo> = CommitTemplateLanguage<'repo>;
|
||||
type P<'repo> = CommitTemplatePropertyKind<'repo>;
|
||||
let mut map = CommitTemplateBuildMethodFnMap::<Trailer>::new();
|
||||
map.insert(
|
||||
"key",
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|trailer| trailer.key);
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -2334,7 +2246,7 @@ fn builtin_trailer_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Tra
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|trailer| trailer.value);
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map
|
||||
|
@ -230,7 +230,7 @@ pub fn aliases() -> Vec<CompletionCandidate> {
|
||||
})
|
||||
}
|
||||
|
||||
fn revisions(revisions: Option<&str>) -> Vec<CompletionCandidate> {
|
||||
fn revisions(match_prefix: &str, revset_filter: Option<&str>) -> Vec<CompletionCandidate> {
|
||||
with_jj(|jj, settings| {
|
||||
// display order
|
||||
const LOCAL_BOOKMARK_MINE: usize = 0;
|
||||
@ -257,36 +257,40 @@ fn revisions(revisions: Option<&str>) -> Vec<CompletionCandidate> {
|
||||
.arg(
|
||||
r#"if(remote != "git", name ++ if(remote, "@" ++ remote) ++ bookmark_help() ++ "\n")"#,
|
||||
);
|
||||
if let Some(revs) = revisions {
|
||||
if let Some(revs) = revset_filter {
|
||||
cmd.arg("--revisions").arg(revs);
|
||||
}
|
||||
let output = cmd.output().map_err(user_error)?;
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
|
||||
candidates.extend(stdout.lines().map(|line| {
|
||||
let (bookmark, help) = split_help_text(line);
|
||||
candidates.extend(
|
||||
stdout
|
||||
.lines()
|
||||
.map(split_help_text)
|
||||
.filter(|(bookmark, _)| bookmark.starts_with(match_prefix))
|
||||
.map(|(bookmark, help)| {
|
||||
let local = !bookmark.contains('@');
|
||||
let mine = prefix.as_ref().is_some_and(|p| bookmark.starts_with(p));
|
||||
|
||||
let local = !bookmark.contains('@');
|
||||
let mine = prefix.as_ref().is_some_and(|p| bookmark.starts_with(p));
|
||||
|
||||
let display_order = match (local, mine) {
|
||||
(true, true) => LOCAL_BOOKMARK_MINE,
|
||||
(true, false) => LOCAL_BOOKMARK,
|
||||
(false, true) => REMOTE_BOOKMARK_MINE,
|
||||
(false, false) => REMOTE_BOOKMARK,
|
||||
};
|
||||
CompletionCandidate::new(bookmark)
|
||||
.help(help)
|
||||
.display_order(Some(display_order))
|
||||
}));
|
||||
let display_order = match (local, mine) {
|
||||
(true, true) => LOCAL_BOOKMARK_MINE,
|
||||
(true, false) => LOCAL_BOOKMARK,
|
||||
(false, true) => REMOTE_BOOKMARK_MINE,
|
||||
(false, false) => REMOTE_BOOKMARK,
|
||||
};
|
||||
CompletionCandidate::new(bookmark)
|
||||
.help(help)
|
||||
.display_order(Some(display_order))
|
||||
}),
|
||||
);
|
||||
|
||||
// tags
|
||||
|
||||
// Tags cannot be filtered by revisions. In order to avoid suggesting
|
||||
// immutable tags for mutable revision args, we skip tags entirely if
|
||||
// revisions is set. This is not a big loss, since tags usually point
|
||||
// revset_filter is set. This is not a big loss, since tags usually point
|
||||
// to immutable revisions anyway.
|
||||
if revisions.is_none() {
|
||||
if revset_filter.is_none() {
|
||||
let output = jj
|
||||
.build()
|
||||
.arg("tag")
|
||||
@ -295,6 +299,7 @@ fn revisions(revisions: Option<&str>) -> Vec<CompletionCandidate> {
|
||||
.arg(BOOKMARK_HELP_TEMPLATE)
|
||||
.arg("--template")
|
||||
.arg(r#"name ++ bookmark_help() ++ "\n""#)
|
||||
.arg(format!("glob:{}*", glob::Pattern::escape(match_prefix)))
|
||||
.output()
|
||||
.map_err(user_error)?;
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
@ -309,7 +314,7 @@ fn revisions(revisions: Option<&str>) -> Vec<CompletionCandidate> {
|
||||
|
||||
// change IDs
|
||||
|
||||
let revisions = revisions
|
||||
let revisions = revset_filter
|
||||
.map(String::from)
|
||||
.or_else(|| settings.get_string("revsets.short-prefixes").ok())
|
||||
.or_else(|| settings.get_string("revsets.log").ok())
|
||||
@ -329,35 +334,92 @@ fn revisions(revisions: Option<&str>) -> Vec<CompletionCandidate> {
|
||||
.map_err(user_error)?;
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
|
||||
candidates.extend(stdout.lines().map(|line| {
|
||||
let (id, desc) = split_help_text(line);
|
||||
CompletionCandidate::new(id)
|
||||
.help(desc)
|
||||
.display_order(Some(CHANGE_ID))
|
||||
}));
|
||||
candidates.extend(
|
||||
stdout
|
||||
.lines()
|
||||
.map(split_help_text)
|
||||
.filter(|(id, _)| id.starts_with(match_prefix))
|
||||
.map(|(id, desc)| {
|
||||
CompletionCandidate::new(id)
|
||||
.help(desc)
|
||||
.display_order(Some(CHANGE_ID))
|
||||
}),
|
||||
);
|
||||
|
||||
// revset aliases
|
||||
|
||||
let revset_aliases = load_revset_aliases(&Ui::null(), settings.config())?;
|
||||
let mut symbol_names: Vec<_> = revset_aliases.symbol_names().collect();
|
||||
symbol_names.sort();
|
||||
candidates.extend(symbol_names.into_iter().map(|symbol| {
|
||||
let (_, defn) = revset_aliases.get_symbol(symbol).unwrap();
|
||||
CompletionCandidate::new(symbol)
|
||||
.help(Some(defn.into()))
|
||||
.display_order(Some(REVSET_ALIAS))
|
||||
}));
|
||||
candidates.extend(
|
||||
symbol_names
|
||||
.into_iter()
|
||||
.filter(|symbol| symbol.starts_with(match_prefix))
|
||||
.map(|symbol| {
|
||||
let (_, defn) = revset_aliases.get_symbol(symbol).unwrap();
|
||||
CompletionCandidate::new(symbol)
|
||||
.help(Some(defn.into()))
|
||||
.display_order(Some(REVSET_ALIAS))
|
||||
}),
|
||||
);
|
||||
|
||||
Ok(candidates)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn mutable_revisions() -> Vec<CompletionCandidate> {
|
||||
revisions(Some("mutable()"))
|
||||
fn revset_expression(
|
||||
current: &std::ffi::OsStr,
|
||||
revset_filter: Option<&str>,
|
||||
) -> Vec<CompletionCandidate> {
|
||||
let Some(current) = current.to_str() else {
|
||||
return Vec::new();
|
||||
};
|
||||
let (prepend, match_prefix) = split_revset_trailing_name(current).unwrap_or(("", current));
|
||||
let candidates = revisions(match_prefix, revset_filter);
|
||||
if prepend.is_empty() {
|
||||
candidates
|
||||
} else {
|
||||
candidates
|
||||
.into_iter()
|
||||
.map(|candidate| candidate.add_prefix(prepend))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn all_revisions() -> Vec<CompletionCandidate> {
|
||||
revisions(None)
|
||||
pub fn revset_expression_all(current: &std::ffi::OsStr) -> Vec<CompletionCandidate> {
|
||||
revset_expression(current, None)
|
||||
}
|
||||
|
||||
pub fn revset_expression_mutable(current: &std::ffi::OsStr) -> Vec<CompletionCandidate> {
|
||||
revset_expression(current, Some("mutable()"))
|
||||
}
|
||||
|
||||
/// Identifies if an incomplete expression ends with a name, or may be continued
|
||||
/// with a name.
|
||||
///
|
||||
/// If the expression ends with an name or a partial name, returns a tuple that
|
||||
/// splits the string at the point the name starts.
|
||||
/// If the expression is empty or ends with a prefix or infix operator that
|
||||
/// could plausibly be followed by a name, returns a tuple where the first
|
||||
/// item is the entire input string, and the second item is empty.
|
||||
/// Otherwise, returns `None`.
|
||||
///
|
||||
/// The input expression may be incomplete (e.g. missing closing parentheses),
|
||||
/// and the ability to reject invalid expressions is limited.
|
||||
fn split_revset_trailing_name(incomplete_revset_str: &str) -> Option<(&str, &str)> {
|
||||
let final_part = incomplete_revset_str
|
||||
.rsplit_once([':', '~', '|', '&', '(', ','])
|
||||
.map(|(_, rest)| rest)
|
||||
.unwrap_or(incomplete_revset_str);
|
||||
let final_part = final_part
|
||||
.rsplit_once("..")
|
||||
.map(|(_, rest)| rest)
|
||||
.unwrap_or(final_part)
|
||||
.trim_ascii_start();
|
||||
|
||||
let re = regex::Regex::new(r"^(?:[\p{XID_CONTINUE}_/]+[@.+-])*[\p{XID_CONTINUE}_/]*$").unwrap();
|
||||
re.is_match(final_part)
|
||||
.then(|| incomplete_revset_str.split_at(incomplete_revset_str.len() - final_part.len()))
|
||||
}
|
||||
|
||||
pub fn operations() -> Vec<CompletionCandidate> {
|
||||
@ -557,13 +619,8 @@ pub fn branch_name_equals_any_revision(current: &std::ffi::OsStr) -> Vec<Complet
|
||||
// Don't complete branch names since we want to create a new branch
|
||||
return Vec::new();
|
||||
};
|
||||
all_revisions()
|
||||
revset_expression(revision.as_ref(), None)
|
||||
.into_iter()
|
||||
.filter(|rev| {
|
||||
rev.get_value()
|
||||
.to_str()
|
||||
.is_some_and(|s| s.starts_with(revision))
|
||||
})
|
||||
.map(|rev| rev.add_prefix(format!("{branch_name}=")))
|
||||
.collect()
|
||||
}
|
||||
@ -1022,6 +1079,71 @@ mod parse {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_split_revset_trailing_name() {
|
||||
assert_eq!(split_revset_trailing_name(""), Some(("", "")));
|
||||
assert_eq!(split_revset_trailing_name(" "), Some((" ", "")));
|
||||
assert_eq!(split_revset_trailing_name("foo"), Some(("", "foo")));
|
||||
assert_eq!(split_revset_trailing_name(" foo"), Some((" ", "foo")));
|
||||
assert_eq!(split_revset_trailing_name("foo "), None);
|
||||
assert_eq!(split_revset_trailing_name("foo_"), Some(("", "foo_")));
|
||||
assert_eq!(split_revset_trailing_name("foo/"), Some(("", "foo/")));
|
||||
assert_eq!(split_revset_trailing_name("foo/b"), Some(("", "foo/b")));
|
||||
|
||||
assert_eq!(split_revset_trailing_name("foo-"), Some(("", "foo-")));
|
||||
assert_eq!(split_revset_trailing_name("foo+"), Some(("", "foo+")));
|
||||
assert_eq!(
|
||||
split_revset_trailing_name("foo-bar-"),
|
||||
Some(("", "foo-bar-"))
|
||||
);
|
||||
assert_eq!(
|
||||
split_revset_trailing_name("foo-bar-b"),
|
||||
Some(("", "foo-bar-b"))
|
||||
);
|
||||
|
||||
assert_eq!(split_revset_trailing_name("foo."), Some(("", "foo.")));
|
||||
assert_eq!(split_revset_trailing_name("foo..b"), Some(("foo..", "b")));
|
||||
assert_eq!(split_revset_trailing_name("..foo"), Some(("..", "foo")));
|
||||
|
||||
assert_eq!(split_revset_trailing_name("foo(bar"), Some(("foo(", "bar")));
|
||||
assert_eq!(split_revset_trailing_name("foo(bar)"), None);
|
||||
assert_eq!(split_revset_trailing_name("(f"), Some(("(", "f")));
|
||||
|
||||
assert_eq!(split_revset_trailing_name("foo@"), Some(("", "foo@")));
|
||||
assert_eq!(split_revset_trailing_name("foo@b"), Some(("", "foo@b")));
|
||||
assert_eq!(split_revset_trailing_name("..foo@"), Some(("..", "foo@")));
|
||||
assert_eq!(
|
||||
split_revset_trailing_name("::F(foo@origin.1..bar@origin."),
|
||||
Some(("::F(foo@origin.1..", "bar@origin."))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split_revset_trailing_name_with_trailing_operator() {
|
||||
assert_eq!(split_revset_trailing_name("foo|"), Some(("foo|", "")));
|
||||
assert_eq!(split_revset_trailing_name("foo | "), Some(("foo | ", "")));
|
||||
assert_eq!(split_revset_trailing_name("foo&"), Some(("foo&", "")));
|
||||
assert_eq!(split_revset_trailing_name("foo~"), Some(("foo~", "")));
|
||||
|
||||
assert_eq!(split_revset_trailing_name(".."), Some(("..", "")));
|
||||
assert_eq!(split_revset_trailing_name("foo.."), Some(("foo..", "")));
|
||||
assert_eq!(split_revset_trailing_name("::"), Some(("::", "")));
|
||||
assert_eq!(split_revset_trailing_name("foo::"), Some(("foo::", "")));
|
||||
|
||||
assert_eq!(split_revset_trailing_name("("), Some(("(", "")));
|
||||
assert_eq!(split_revset_trailing_name("foo("), Some(("foo(", "")));
|
||||
assert_eq!(split_revset_trailing_name("foo()"), None);
|
||||
assert_eq!(split_revset_trailing_name("foo(bar)"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split_revset_trailing_name_with_modifier() {
|
||||
assert_eq!(split_revset_trailing_name("all:"), Some(("all:", "")));
|
||||
assert_eq!(split_revset_trailing_name("all: "), Some(("all: ", "")));
|
||||
assert_eq!(split_revset_trailing_name("all:f"), Some(("all:", "f")));
|
||||
assert_eq!(split_revset_trailing_name("all: f"), Some(("all: ", "f")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_config_keys() {
|
||||
// Just make sure the schema is parsed without failure.
|
||||
|
@ -21,7 +21,7 @@ use crate::template_builder;
|
||||
use crate::template_builder::BuildContext;
|
||||
use crate::template_builder::CoreTemplateBuildFnTable;
|
||||
use crate::template_builder::CoreTemplatePropertyKind;
|
||||
use crate::template_builder::IntoTemplateProperty;
|
||||
use crate::template_builder::CoreTemplatePropertyVar;
|
||||
use crate::template_builder::TemplateLanguage;
|
||||
use crate::template_parser;
|
||||
use crate::template_parser::FunctionCallNode;
|
||||
@ -90,8 +90,6 @@ impl<'a, C> GenericTemplateLanguage<'a, C> {
|
||||
impl<'a, C> TemplateLanguage<'a> for GenericTemplateLanguage<'a, C> {
|
||||
type Property = GenericTemplatePropertyKind<'a, C>;
|
||||
|
||||
template_builder::impl_core_wrap_property_fns!('a, GenericTemplatePropertyKind::Core);
|
||||
|
||||
fn settings(&self) -> &UserSettings {
|
||||
&self.settings
|
||||
}
|
||||
@ -130,18 +128,20 @@ impl<'a, C> TemplateLanguage<'a> for GenericTemplateLanguage<'a, C> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, C> GenericTemplateLanguage<'a, C> {
|
||||
pub fn wrap_self(property: BoxedTemplateProperty<'a, C>) -> GenericTemplatePropertyKind<'a, C> {
|
||||
GenericTemplatePropertyKind::Self_(property)
|
||||
}
|
||||
}
|
||||
|
||||
pub enum GenericTemplatePropertyKind<'a, C> {
|
||||
Core(CoreTemplatePropertyKind<'a>),
|
||||
Self_(BoxedTemplateProperty<'a, C>),
|
||||
}
|
||||
|
||||
impl<'a, C> IntoTemplateProperty<'a> for GenericTemplatePropertyKind<'a, C> {
|
||||
impl<'a, C> GenericTemplatePropertyKind<'a, C> {
|
||||
template_builder::impl_wrap_property_fns!('a, GenericTemplatePropertyKind, {
|
||||
pub wrap_self(C) => Self_,
|
||||
});
|
||||
}
|
||||
|
||||
impl<'a, C> CoreTemplatePropertyVar<'a> for GenericTemplatePropertyKind<'a, C> {
|
||||
template_builder::impl_core_wrap_property_fns!('a, GenericTemplatePropertyKind::Core);
|
||||
|
||||
fn type_name(&self) -> &'static str {
|
||||
match self {
|
||||
GenericTemplatePropertyKind::Core(property) => property.type_name(),
|
||||
|
@ -30,7 +30,7 @@ use crate::template_builder::merge_fn_map;
|
||||
use crate::template_builder::BuildContext;
|
||||
use crate::template_builder::CoreTemplateBuildFnTable;
|
||||
use crate::template_builder::CoreTemplatePropertyKind;
|
||||
use crate::template_builder::IntoTemplateProperty;
|
||||
use crate::template_builder::CoreTemplatePropertyVar;
|
||||
use crate::template_builder::TemplateBuildMethodFnMap;
|
||||
use crate::template_builder::TemplateLanguage;
|
||||
use crate::template_parser;
|
||||
@ -88,8 +88,6 @@ impl OperationTemplateLanguage {
|
||||
impl TemplateLanguage<'static> for OperationTemplateLanguage {
|
||||
type Property = OperationTemplatePropertyKind;
|
||||
|
||||
template_builder::impl_core_wrap_property_fns!('static, OperationTemplatePropertyKind::Core);
|
||||
|
||||
fn settings(&self) -> &UserSettings {
|
||||
self.repo_loader.settings()
|
||||
}
|
||||
@ -135,18 +133,6 @@ impl OperationTemplateLanguage {
|
||||
pub fn cache_extension<T: Any>(&self) -> Option<&T> {
|
||||
self.cache_extensions.get::<T>()
|
||||
}
|
||||
|
||||
pub fn wrap_operation(
|
||||
property: BoxedTemplateProperty<'static, Operation>,
|
||||
) -> OperationTemplatePropertyKind {
|
||||
OperationTemplatePropertyKind::Operation(property)
|
||||
}
|
||||
|
||||
pub fn wrap_operation_id(
|
||||
property: BoxedTemplateProperty<'static, OperationId>,
|
||||
) -> OperationTemplatePropertyKind {
|
||||
OperationTemplatePropertyKind::OperationId(property)
|
||||
}
|
||||
}
|
||||
|
||||
pub enum OperationTemplatePropertyKind {
|
||||
@ -155,7 +141,16 @@ pub enum OperationTemplatePropertyKind {
|
||||
OperationId(BoxedTemplateProperty<'static, OperationId>),
|
||||
}
|
||||
|
||||
impl IntoTemplateProperty<'static> for OperationTemplatePropertyKind {
|
||||
impl OperationTemplatePropertyKind {
|
||||
template_builder::impl_wrap_property_fns!('static, OperationTemplatePropertyKind, {
|
||||
pub wrap_operation(Operation) => Operation,
|
||||
pub wrap_operation_id(OperationId) => OperationId,
|
||||
});
|
||||
}
|
||||
|
||||
impl CoreTemplatePropertyVar<'static> for OperationTemplatePropertyKind {
|
||||
template_builder::impl_core_wrap_property_fns!('static, OperationTemplatePropertyKind::Core);
|
||||
|
||||
fn type_name(&self) -> &'static str {
|
||||
match self {
|
||||
OperationTemplatePropertyKind::Core(property) => property.type_name(),
|
||||
@ -265,7 +260,7 @@ impl OperationTemplateBuildFnTable {
|
||||
}
|
||||
|
||||
fn builtin_operation_methods() -> OperationTemplateBuildMethodFnMap<Operation> {
|
||||
type L = OperationTemplateLanguage;
|
||||
type P = OperationTemplatePropertyKind;
|
||||
// Not using maplit::hashmap!{} or custom declarative macro here because
|
||||
// code completion inside macro is quite restricted.
|
||||
let mut map = OperationTemplateBuildMethodFnMap::<Operation>::new();
|
||||
@ -275,7 +270,7 @@ fn builtin_operation_methods() -> OperationTemplateBuildMethodFnMap<Operation> {
|
||||
function.expect_no_arguments()?;
|
||||
let current_op_id = language.current_op_id.clone();
|
||||
let out_property = self_property.map(move |op| Some(op.id()) == current_op_id.as_ref());
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -283,7 +278,7 @@ fn builtin_operation_methods() -> OperationTemplateBuildMethodFnMap<Operation> {
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|op| op.metadata().description.clone());
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -291,7 +286,7 @@ fn builtin_operation_methods() -> OperationTemplateBuildMethodFnMap<Operation> {
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|op| op.id().clone());
|
||||
Ok(L::wrap_operation_id(out_property.into_dyn()))
|
||||
Ok(P::wrap_operation_id(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -306,7 +301,7 @@ fn builtin_operation_methods() -> OperationTemplateBuildMethodFnMap<Operation> {
|
||||
.map(|(key, value)| format!("{key}: {value}"))
|
||||
.join("\n")
|
||||
});
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -314,7 +309,7 @@ fn builtin_operation_methods() -> OperationTemplateBuildMethodFnMap<Operation> {
|
||||
|_language, _diagnostics, _build_ctx, self_property, function| {
|
||||
function.expect_no_arguments()?;
|
||||
let out_property = self_property.map(|op| op.metadata().is_snapshot);
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -325,7 +320,7 @@ fn builtin_operation_methods() -> OperationTemplateBuildMethodFnMap<Operation> {
|
||||
start: op.metadata().start_time,
|
||||
end: op.metadata().end_time,
|
||||
});
|
||||
Ok(L::wrap_timestamp_range(out_property.into_dyn()))
|
||||
Ok(P::wrap_timestamp_range(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -336,7 +331,7 @@ fn builtin_operation_methods() -> OperationTemplateBuildMethodFnMap<Operation> {
|
||||
// TODO: introduce dedicated type and provide accessors?
|
||||
format!("{}@{}", op.metadata().username, op.metadata().hostname)
|
||||
});
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map.insert(
|
||||
@ -345,7 +340,7 @@ fn builtin_operation_methods() -> OperationTemplateBuildMethodFnMap<Operation> {
|
||||
function.expect_no_arguments()?;
|
||||
let root_op_id = language.repo_loader.op_store().root_operation_id().clone();
|
||||
let out_property = self_property.map(move |op| op.id() == &root_op_id);
|
||||
Ok(L::wrap_boolean(out_property.into_dyn()))
|
||||
Ok(P::wrap_boolean(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map
|
||||
@ -358,7 +353,7 @@ impl Template for OperationId {
|
||||
}
|
||||
|
||||
fn builtin_operation_id_methods() -> OperationTemplateBuildMethodFnMap<OperationId> {
|
||||
type L = OperationTemplateLanguage;
|
||||
type P = OperationTemplatePropertyKind;
|
||||
// Not using maplit::hashmap!{} or custom declarative macro here because
|
||||
// code completion inside macro is quite restricted.
|
||||
let mut map = OperationTemplateBuildMethodFnMap::<OperationId>::new();
|
||||
@ -381,7 +376,7 @@ fn builtin_operation_id_methods() -> OperationTemplateBuildMethodFnMap<Operation
|
||||
hex.truncate(len.unwrap_or(12));
|
||||
hex
|
||||
});
|
||||
Ok(L::wrap_string(out_property.into_dyn()))
|
||||
Ok(P::wrap_string(out_property.into_dyn()))
|
||||
},
|
||||
);
|
||||
map
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -792,6 +792,22 @@ fn test_revisions() {
|
||||
[EOF]
|
||||
");
|
||||
|
||||
// complete all revisions in a revset expression
|
||||
let output = work_dir.complete_fish(["log", "-r", ".."]);
|
||||
insta::assert_snapshot!(output, @r"
|
||||
..immutable_bookmark immutable
|
||||
..mutable_bookmark mutable
|
||||
..k working_copy
|
||||
..y mutable
|
||||
..q immutable
|
||||
..zq remote_commit
|
||||
..zz (no description set)
|
||||
..remote_bookmark@origin remote_commit
|
||||
..alias_with_newline roots(
|
||||
..siblings @-+ ~@
|
||||
[EOF]
|
||||
");
|
||||
|
||||
// complete only mutable revisions
|
||||
let output = work_dir.complete_fish(["squash", "--into", ""]);
|
||||
insta::assert_snapshot!(output, @r"
|
||||
@ -804,6 +820,25 @@ fn test_revisions() {
|
||||
[EOF]
|
||||
");
|
||||
|
||||
// complete only mutable revisions in a revset expression
|
||||
let output = work_dir.complete_fish(["abandon", "y::"]);
|
||||
insta::assert_snapshot!(output, @r"
|
||||
y::mutable_bookmark mutable
|
||||
y::k working_copy
|
||||
y::y mutable
|
||||
y::zq remote_commit
|
||||
y::alias_with_newline roots(
|
||||
y::siblings @-+ ~@
|
||||
[EOF]
|
||||
");
|
||||
|
||||
// complete remote bookmarks in a revset expression
|
||||
let output = work_dir.complete_fish(["log", "-r", "remote_bookmark@"]);
|
||||
insta::assert_snapshot!(output, @r"
|
||||
remote_bookmark@origin remote_commit
|
||||
[EOF]
|
||||
");
|
||||
|
||||
// complete args of the default command
|
||||
test_env.add_config("ui.default-command = 'log'");
|
||||
let output = work_dir.complete_fish(["-r", ""]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user