completion: teach commands about revisions

This commit is contained in:
Remo Senekowitsch 2024-11-15 14:59:54 +01:00
parent 68c0fd6350
commit dd6479f104
27 changed files with 226 additions and 45 deletions

View file

@ -14,6 +14,7 @@
use std::io::Write;
use clap_complete::ArgValueCandidates;
use itertools::Itertools as _;
use jj_lib::commit::CommitIteratorExt;
use jj_lib::object_id::ObjectId;
@ -22,6 +23,7 @@ use tracing::instrument;
use crate::cli_util::CommandHelper;
use crate::cli_util::RevisionArg;
use crate::command_error::CommandError;
use crate::complete;
use crate::ui::Ui;
/// Abandon a revision
@ -35,7 +37,7 @@ use crate::ui::Ui;
#[derive(clap::Args, Clone, Debug)]
pub(crate) struct AbandonArgs {
/// The revision(s) to abandon
#[arg(default_value = "@")]
#[arg(default_value = "@", add = ArgValueCandidates::new(complete::mutable_revisions))]
revisions: Vec<RevisionArg>,
/// Do not print every abandoned commit on a separate line
#[arg(long, short)]

View file

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use clap_complete::ArgValueCandidates;
use itertools::Itertools as _;
use jj_lib::object_id::ObjectId;
use jj_lib::rewrite::merge_commit_trees;
@ -20,18 +21,27 @@ use tracing::instrument;
use crate::cli_util::CommandHelper;
use crate::cli_util::RevisionArg;
use crate::command_error::CommandError;
use crate::complete;
use crate::ui::Ui;
/// Apply the reverse of a revision on top of another revision
#[derive(clap::Args, Clone, Debug)]
pub(crate) struct BackoutArgs {
/// The revision(s) to apply the reverse of
#[arg(long, short, default_value = "@")]
#[arg(
long, short,
default_value = "@",
add = ArgValueCandidates::new(complete::all_revisions),
)]
revisions: Vec<RevisionArg>,
/// The revision to apply the reverse changes on top of
// TODO: It seems better to default this to `@-`. Maybe the working
// copy should be rebased on top?
#[arg(long, short, default_value = "@")]
#[arg(
long, short,
default_value = "@",
add = ArgValueCandidates::new(complete::all_revisions),
)]
destination: Vec<RevisionArg>,
}

View file

@ -16,6 +16,7 @@ use std::collections::HashMap;
use std::io;
use std::io::Read;
use clap_complete::ArgValueCandidates;
use itertools::Itertools;
use jj_lib::backend::Signature;
use jj_lib::commit::CommitIteratorExt;
@ -26,6 +27,7 @@ use crate::cli_util::CommandHelper;
use crate::cli_util::RevisionArg;
use crate::command_error::user_error;
use crate::command_error::CommandError;
use crate::complete;
use crate::description_util::description_template;
use crate::description_util::edit_description;
use crate::description_util::edit_multiple_descriptions;
@ -42,7 +44,7 @@ use crate::ui::Ui;
#[command(alias = "desc")]
pub(crate) struct DescribeArgs {
/// The revision(s) whose description to edit
#[arg(default_value = "@")]
#[arg(default_value = "@", add = ArgValueCandidates::new(complete::mutable_revisions))]
revisions: Vec<RevisionArg>,
/// Ignored (but lets you pass `-r` for consistency with other commands)
#[arg(short = 'r', hide = true, action = clap::ArgAction::Count)]

View file

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use clap_complete::ArgValueCandidates;
use itertools::Itertools;
use jj_lib::copies::CopyRecords;
use jj_lib::repo::Repo;
@ -22,6 +23,7 @@ use crate::cli_util::print_unmatched_explicit_paths;
use crate::cli_util::CommandHelper;
use crate::cli_util::RevisionArg;
use crate::command_error::CommandError;
use crate::complete;
use crate::diff_util::get_copy_records;
use crate::diff_util::DiffFormatArgs;
use crate::ui::Ui;
@ -46,13 +48,13 @@ pub(crate) struct DiffArgs {
/// If the revision is a merge commit, this shows changes *from* the
/// automatic merge of the contents of all of its parents *to* the contents
/// of the revision itself.
#[arg(long, short)]
#[arg(long, short, add = ArgValueCandidates::new(complete::all_revisions))]
revision: Option<RevisionArg>,
/// Show changes from this revision
#[arg(long, conflicts_with = "revision")]
#[arg(long, conflicts_with = "revision", add = ArgValueCandidates::new(complete::all_revisions))]
from: Option<RevisionArg>,
/// Show changes to this revision
#[arg(long, conflicts_with = "revision")]
#[arg(long, conflicts_with = "revision", add = ArgValueCandidates::new(complete::all_revisions))]
to: Option<RevisionArg>,
/// Restrict the diff to these paths
#[arg(value_hint = clap::ValueHint::AnyPath)]

View file

@ -14,6 +14,7 @@
use std::io::Write;
use clap_complete::ArgValueCandidates;
use itertools::Itertools;
use jj_lib::matchers::EverythingMatcher;
use jj_lib::object_id::ObjectId;
@ -23,6 +24,7 @@ use tracing::instrument;
use crate::cli_util::CommandHelper;
use crate::cli_util::RevisionArg;
use crate::command_error::CommandError;
use crate::complete;
use crate::ui::Ui;
/// Touch up the content changes in a revision with a diff editor
@ -48,17 +50,17 @@ pub(crate) struct DiffeditArgs {
/// The revision to touch up
///
/// Defaults to @ if neither --to nor --from are specified.
#[arg(long, short)]
#[arg(long, short, add = ArgValueCandidates::new(complete::mutable_revisions))]
revision: Option<RevisionArg>,
/// Show changes from this revision
///
/// Defaults to @ if --to is specified.
#[arg(long, conflicts_with = "revision")]
#[arg(long, conflicts_with = "revision", add = ArgValueCandidates::new(complete::all_revisions))]
from: Option<RevisionArg>,
/// Edit changes in this revision
///
/// Defaults to @ if --from is specified.
#[arg(long, conflicts_with = "revision")]
#[arg(long, conflicts_with = "revision", add = ArgValueCandidates::new(complete::mutable_revisions))]
to: Option<RevisionArg>,
/// Specify diff editor to be used
#[arg(long, value_name = "NAME")]

View file

@ -15,6 +15,7 @@
use std::io::Write;
use std::rc::Rc;
use clap_complete::ArgValueCandidates;
use itertools::Itertools;
use jj_lib::backend::CommitId;
use jj_lib::commit::CommitIteratorExt;
@ -32,6 +33,7 @@ use crate::cli_util::CommandHelper;
use crate::cli_util::RevisionArg;
use crate::command_error::user_error;
use crate::command_error::CommandError;
use crate::complete;
use crate::ui::Ui;
/// Create new changes with the same content as existing ones
@ -50,14 +52,14 @@ use crate::ui::Ui;
#[derive(clap::Args, Clone, Debug)]
pub(crate) struct DuplicateArgs {
/// The revision(s) to duplicate
#[arg(default_value = "@")]
#[arg(default_value = "@", add = ArgValueCandidates::new(complete::all_revisions))]
revisions: Vec<RevisionArg>,
/// Ignored (but lets you pass `-r` for consistency with other commands)
#[arg(short = 'r', hide = true, action = clap::ArgAction::Count)]
unused_revision: u8,
/// The revision(s) to duplicate onto (can be repeated to create a merge
/// commit)
#[arg(long, short)]
#[arg(long, short, add = ArgValueCandidates::new(complete::all_revisions))]
destination: Vec<RevisionArg>,
/// The revision(s) to insert after (can be repeated to create a merge
/// commit)
@ -65,7 +67,8 @@ pub(crate) struct DuplicateArgs {
long,
short = 'A',
visible_alias = "after",
conflicts_with = "destination"
conflicts_with = "destination",
add = ArgValueCandidates::new(complete::all_revisions),
)]
insert_after: Vec<RevisionArg>,
/// The revision(s) to insert before (can be repeated to create a merge
@ -74,7 +77,8 @@ pub(crate) struct DuplicateArgs {
long,
short = 'B',
visible_alias = "before",
conflicts_with = "destination"
conflicts_with = "destination",
add = ArgValueCandidates::new(complete::mutable_revisions)
)]
insert_before: Vec<RevisionArg>,
}

View file

@ -14,12 +14,14 @@
use std::io::Write;
use clap_complete::ArgValueCandidates;
use jj_lib::object_id::ObjectId;
use tracing::instrument;
use crate::cli_util::CommandHelper;
use crate::cli_util::RevisionArg;
use crate::command_error::CommandError;
use crate::complete;
use crate::ui::Ui;
/// Sets the specified revision as the working-copy revision
@ -31,6 +33,7 @@ use crate::ui::Ui;
#[derive(clap::Args, Clone, Debug)]
pub(crate) struct EditArgs {
/// The commit to edit
#[arg(add = ArgValueCandidates::new(complete::mutable_revisions))]
revision: RevisionArg,
/// Ignored (but lets you pass `-r` for consistency with other commands)
#[arg(short = 'r', hide = true)]

View file

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use clap_complete::ArgValueCandidates;
use itertools::Itertools;
use jj_lib::commit::Commit;
use jj_lib::dag_walk::topo_order_reverse_ok;
@ -25,6 +26,7 @@ use crate::cli_util::LogContentFormat;
use crate::cli_util::RevisionArg;
use crate::command_error::CommandError;
use crate::commit_templater::CommitTemplateLanguage;
use crate::complete;
use crate::diff_util::DiffFormatArgs;
use crate::graphlog::get_graphlog;
use crate::graphlog::Edge;
@ -37,7 +39,11 @@ use crate::ui::Ui;
/// of a change evolves when the change is updated, rebased, etc.
#[derive(clap::Args, Clone, Debug)]
pub(crate) struct EvologArgs {
#[arg(long, short, default_value = "@")]
#[arg(
long, short,
default_value = "@",
add = ArgValueCandidates::new(complete::all_revisions),
)]
revision: RevisionArg,
/// Limit number of revisions to show
#[arg(long, short = 'n')]

View file

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use clap_complete::ArgValueCandidates;
use jj_lib::annotate::get_annotation_for_file;
use jj_lib::annotate::FileAnnotation;
use jj_lib::commit::Commit;
@ -23,6 +24,7 @@ use crate::cli_util::CommandHelper;
use crate::cli_util::RevisionArg;
use crate::command_error::user_error;
use crate::command_error::CommandError;
use crate::complete;
use crate::templater::TemplateRenderer;
use crate::ui::Ui;
@ -38,7 +40,7 @@ pub(crate) struct FileAnnotateArgs {
#[arg(value_hint = clap::ValueHint::AnyPath)]
path: String,
/// an optional revision to start at
#[arg(long, short)]
#[arg(long, short, add = ArgValueCandidates::new(complete::all_revisions))]
revision: Option<RevisionArg>,
}

View file

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use clap_complete::ArgValueCandidates;
use jj_lib::backend::TreeValue;
use jj_lib::merged_tree::MergedTreeBuilder;
use jj_lib::object_id::ObjectId;
@ -22,6 +23,7 @@ use crate::cli_util::CommandHelper;
use crate::cli_util::RevisionArg;
use crate::command_error::user_error;
use crate::command_error::CommandError;
use crate::complete;
use crate::ui::Ui;
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, clap::ValueEnum)]
@ -43,7 +45,11 @@ enum ChmodMode {
pub(crate) struct FileChmodArgs {
mode: ChmodMode,
/// The revision to update
#[arg(long, short, default_value = "@")]
#[arg(
long, short,
default_value = "@",
add = ArgValueCandidates::new(complete::mutable_revisions),
)]
revision: RevisionArg,
/// Paths to change the executable bit for
#[arg(required = true, value_hint = clap::ValueHint::AnyPath)]

View file

@ -14,18 +14,24 @@
use std::io::Write;
use clap_complete::ArgValueCandidates;
use tracing::instrument;
use crate::cli_util::CommandHelper;
use crate::cli_util::RevisionArg;
use crate::command_error::CommandError;
use crate::complete;
use crate::ui::Ui;
/// List files in a revision
#[derive(clap::Args, Clone, Debug)]
pub(crate) struct FileListArgs {
/// The revision to list files in
#[arg(long, short, default_value = "@")]
#[arg(
long, short,
default_value = "@",
add = ArgValueCandidates::new(complete::all_revisions),
)]
revision: RevisionArg,
/// Only list files matching these prefixes (instead of all files)
#[arg(value_hint = clap::ValueHint::AnyPath)]

View file

@ -15,6 +15,7 @@
use std::io;
use std::io::Write;
use clap_complete::ArgValueCandidates;
use jj_lib::backend::BackendResult;
use jj_lib::conflicts::materialize_merge_result;
use jj_lib::conflicts::materialize_tree_value;
@ -33,6 +34,7 @@ use crate::cli_util::RevisionArg;
use crate::cli_util::WorkspaceCommandHelper;
use crate::command_error::user_error;
use crate::command_error::CommandError;
use crate::complete;
use crate::ui::Ui;
/// Print contents of files in a revision
@ -42,7 +44,11 @@ use crate::ui::Ui;
#[derive(clap::Args, Clone, Debug)]
pub(crate) struct FileShowArgs {
/// The revision to get the file contents from
#[arg(long, short, default_value = "@")]
#[arg(
long, short,
default_value = "@",
add = ArgValueCandidates::new(complete::all_revisions),
)]
revision: RevisionArg,
/// Paths to print
#[arg(required = true, value_hint = clap::ValueHint::FilePath)]

View file

@ -18,6 +18,7 @@ use std::io::Write;
use std::process::Stdio;
use std::sync::mpsc::channel;
use clap_complete::ArgValueCandidates;
use futures::StreamExt;
use itertools::Itertools;
use jj_lib::backend::BackendError;
@ -49,6 +50,7 @@ use crate::cli_util::RevisionArg;
use crate::command_error::config_error;
use crate::command_error::print_parse_diagnostics;
use crate::command_error::CommandError;
use crate::complete;
use crate::config::to_toml_value;
use crate::config::CommandNameAndArgs;
use crate::ui::Ui;
@ -124,7 +126,7 @@ pub(crate) struct FixArgs {
/// Fix files in the specified revision(s) and their descendants. If no
/// revisions are specified, this defaults to the `revsets.fix` setting, or
/// `reachable(@, mutable())` if it is not set.
#[arg(long, short)]
#[arg(long, short, add = ArgValueCandidates::new(complete::mutable_revisions))]
source: Vec<RevisionArg>,
/// Fix only these paths
#[arg(value_hint = clap::ValueHint::AnyPath)]

View file

@ -15,11 +15,13 @@
use std::slice;
use clap::ArgGroup;
use clap_complete::ArgValueCandidates;
use tracing::instrument;
use crate::cli_util::CommandHelper;
use crate::cli_util::RevisionArg;
use crate::command_error::CommandError;
use crate::complete;
use crate::diff_util::DiffFormatArgs;
use crate::ui::Ui;
@ -34,10 +36,10 @@ use crate::ui::Ui;
#[command(mut_arg("ignore_space_change", |a| a.short('b')))]
pub(crate) struct InterdiffArgs {
/// Show changes from this revision
#[arg(long)]
#[arg(long, add = ArgValueCandidates::new(complete::all_revisions))]
from: Option<RevisionArg>,
/// Show changes to this revision
#[arg(long)]
#[arg(long, add = ArgValueCandidates::new(complete::all_revisions))]
to: Option<RevisionArg>,
/// Restrict the diff to these paths
#[arg(value_hint = clap::ValueHint::AnyPath)]

View file

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use clap_complete::ArgValueCandidates;
use jj_lib::backend::CommitId;
use jj_lib::graph::GraphEdgeType;
use jj_lib::graph::ReverseGraphIterator;
@ -31,6 +32,7 @@ use crate::cli_util::LogContentFormat;
use crate::cli_util::RevisionArg;
use crate::command_error::CommandError;
use crate::commit_templater::CommitTemplateLanguage;
use crate::complete;
use crate::diff_util::DiffFormatArgs;
use crate::graphlog::get_graphlog;
use crate::graphlog::Edge;
@ -51,7 +53,7 @@ pub(crate) struct LogArgs {
///
/// If no paths nor revisions are specified, this defaults to the
/// `revsets.log` setting.
#[arg(long, short)]
#[arg(long, short, add = ArgValueCandidates::new(complete::all_revisions))]
revisions: Vec<RevisionArg>,
/// Show revisions modifying the given paths
#[arg(value_hint = clap::ValueHint::AnyPath)]

View file

@ -13,6 +13,7 @@
// limitations under the License.
use clap::ArgGroup;
use clap_complete::ArgValueCandidates;
use jj_lib::object_id::ObjectId;
use tracing::instrument;
@ -22,6 +23,7 @@ use crate::cli_util::CommandHelper;
use crate::cli_util::RevisionArg;
use crate::command_error::user_error;
use crate::command_error::CommandError;
use crate::complete;
use crate::ui::Ui;
/// Move changes from one revision into another (DEPRECATED, use `jj squash`)
@ -43,10 +45,10 @@ use crate::ui::Ui;
#[command(group(ArgGroup::new("to_move").args(&["from", "to"]).multiple(true).required(true)))]
pub(crate) struct MoveArgs {
/// Move part of this change into the destination
#[arg(long, short)]
#[arg(long, short, add = ArgValueCandidates::new(complete::mutable_revisions))]
from: Option<RevisionArg>,
/// Move part of the source into this change
#[arg(long, short)]
#[arg(long, short, add = ArgValueCandidates::new(complete::mutable_revisions))]
to: Option<RevisionArg>,
/// Interactively choose which parts to move
#[arg(long, short)]

View file

@ -16,6 +16,7 @@ use std::collections::HashSet;
use std::io::Write;
use std::rc::Rc;
use clap_complete::ArgValueCandidates;
use itertools::Itertools;
use jj_lib::backend::CommitId;
use jj_lib::commit::CommitIteratorExt;
@ -33,6 +34,7 @@ use crate::cli_util::CommandHelper;
use crate::cli_util::RevisionArg;
use crate::command_error::user_error;
use crate::command_error::CommandError;
use crate::complete;
use crate::description_util::join_message_paragraphs;
use crate::ui::Ui;
@ -50,7 +52,7 @@ use crate::ui::Ui;
#[derive(clap::Args, Clone, Debug)]
pub(crate) struct NewArgs {
/// Parent(s) of the new change
#[arg(default_value = "@")]
#[arg(default_value = "@", add = ArgValueCandidates::new(complete::all_revisions))]
pub(crate) revisions: Vec<RevisionArg>,
/// Ignored (but lets you pass `-d`/`-r` for consistency with other
/// commands)
@ -70,7 +72,8 @@ pub(crate) struct NewArgs {
long,
short = 'A',
visible_alias = "after",
conflicts_with = "revisions"
conflicts_with = "revisions",
add = ArgValueCandidates::new(complete::all_revisions),
)]
insert_after: Vec<RevisionArg>,
/// Insert the new change before the given commit(s)
@ -78,7 +81,8 @@ pub(crate) struct NewArgs {
long,
short = 'B',
visible_alias = "before",
conflicts_with = "revisions"
conflicts_with = "revisions",
add = ArgValueCandidates::new(complete::mutable_revisions),
)]
insert_before: Vec<RevisionArg>,
}

View file

@ -14,6 +14,7 @@
use std::collections::HashMap;
use clap_complete::ArgValueCandidates;
use indexmap::IndexSet;
use itertools::Itertools;
use jj_lib::backend::CommitId;
@ -24,6 +25,7 @@ use tracing::instrument;
use crate::cli_util::CommandHelper;
use crate::cli_util::RevisionArg;
use crate::command_error::CommandError;
use crate::complete;
use crate::ui::Ui;
/// Parallelize revisions by making them siblings
@ -55,6 +57,7 @@ use crate::ui::Ui;
#[command(verbatim_doc_comment)]
pub(crate) struct ParallelizeArgs {
/// Revisions to parallelize
#[arg(add = ArgValueCandidates::new(complete::mutable_revisions))]
revisions: Vec<RevisionArg>,
}

View file

@ -17,6 +17,7 @@ use std::rc::Rc;
use std::sync::Arc;
use clap::ArgGroup;
use clap_complete::ArgValueCandidates;
use itertools::Itertools;
use jj_lib::backend::CommitId;
use jj_lib::commit::Commit;
@ -42,6 +43,7 @@ use crate::cli_util::WorkspaceCommandHelper;
use crate::command_error::cli_error;
use crate::command_error::user_error;
use crate::command_error::CommandError;
use crate::complete;
use crate::ui::Ui;
/// Move revisions to different parent(s)
@ -140,7 +142,7 @@ pub(crate) struct RebaseArgs {
/// -d=dst`.
///
/// If none of `-b`, `-s`, or `-r` is provided, then the default is `-b @`.
#[arg(long, short)]
#[arg(long, short, add = ArgValueCandidates::new(complete::mutable_revisions))]
branch: Vec<RevisionArg>,
/// Rebase specified revision(s) together with their trees of descendants
@ -151,7 +153,7 @@ pub(crate) struct RebaseArgs {
/// of others.
///
/// If none of `-b`, `-s`, or `-r` is provided, then the default is `-b @`.
#[arg(long, short)]
#[arg(long, short, add = ArgValueCandidates::new(complete::mutable_revisions))]
source: Vec<RevisionArg>,
/// Rebase the given revisions, rebasing descendants onto this revision's
/// parent(s)
@ -160,7 +162,7 @@ pub(crate) struct RebaseArgs {
/// descendant of `A`.
///
/// If none of `-b`, `-s`, or `-r` is provided, then the default is `-b @`.
#[arg(long, short)]
#[arg(long, short, add = ArgValueCandidates::new(complete::mutable_revisions))]
revisions: Vec<RevisionArg>,
#[command(flatten)]
@ -183,7 +185,7 @@ pub(crate) struct RebaseArgs {
pub struct RebaseDestinationArgs {
/// The revision(s) to rebase onto (can be repeated to create a merge
/// commit)
#[arg(long, short)]
#[arg(long, short, add = ArgValueCandidates::new(complete::all_revisions))]
destination: Option<Vec<RevisionArg>>,
/// The revision(s) to insert after (can be repeated to create a merge
/// commit)
@ -191,7 +193,8 @@ pub struct RebaseDestinationArgs {
long,
short = 'A',
visible_alias = "after",
conflicts_with = "destination"
conflicts_with = "destination",
add = ArgValueCandidates::new(complete::all_revisions),
)]
insert_after: Option<Vec<RevisionArg>>,
/// The revision(s) to insert before (can be repeated to create a merge
@ -200,7 +203,8 @@ pub struct RebaseDestinationArgs {
long,
short = 'B',
visible_alias = "before",
conflicts_with = "destination"
conflicts_with = "destination",
add = ArgValueCandidates::new(complete::mutable_revisions),
)]
insert_before: Option<Vec<RevisionArg>>,
}

View file

@ -14,6 +14,7 @@
use std::io::Write;
use clap_complete::ArgValueCandidates;
use itertools::Itertools;
use jj_lib::object_id::ObjectId;
use tracing::instrument;
@ -23,6 +24,7 @@ use crate::cli_util::CommandHelper;
use crate::cli_util::RevisionArg;
use crate::command_error::cli_error;
use crate::command_error::CommandError;
use crate::complete;
use crate::ui::Ui;
/// Resolve a conflicted file with an external merge tool
@ -42,7 +44,11 @@ use crate::ui::Ui;
// simplify the present one.
#[derive(clap::Args, Clone, Debug)]
pub(crate) struct ResolveArgs {
#[arg(long, short, default_value = "@")]
#[arg(
long, short,
default_value = "@",
add = ArgValueCandidates::new(complete::mutable_revisions),
)]
revision: RevisionArg,
/// Instead of resolving one conflict, list all the conflicts
// TODO: Also have a `--summary` option. `--list` currently acts like

View file

@ -14,6 +14,7 @@
use std::io::Write;
use clap_complete::ArgValueCandidates;
use jj_lib::object_id::ObjectId;
use jj_lib::rewrite::restore_tree;
use tracing::instrument;
@ -22,6 +23,7 @@ use crate::cli_util::CommandHelper;
use crate::cli_util::RevisionArg;
use crate::command_error::user_error;
use crate::command_error::CommandError;
use crate::complete;
use crate::ui::Ui;
/// Restore paths from another revision
@ -46,10 +48,10 @@ pub(crate) struct RestoreArgs {
#[arg(value_hint = clap::ValueHint::AnyPath)]
paths: Vec<String>,
/// Revision to restore from (source)
#[arg(long)]
#[arg(long, add = ArgValueCandidates::new(complete::all_revisions))]
from: Option<RevisionArg>,
/// Revision to restore into (destination)
#[arg(long)]
#[arg(long, add = ArgValueCandidates::new(complete::mutable_revisions))]
to: Option<RevisionArg>,
/// Undo the changes in a revision as compared to the merge of its parents.
///
@ -59,7 +61,12 @@ pub(crate) struct RestoreArgs {
///
/// The default behavior of `jj restore` is equivalent to `jj restore
/// --changes-in @`.
#[arg(long, short, value_name="REVISION", conflicts_with_all=["to", "from"])]
#[arg(
long, short,
value_name = "REVISION",
conflicts_with_all = ["to", "from"],
add = ArgValueCandidates::new(complete::all_revisions),
)]
changes_in: Option<RevisionArg>,
/// Prints an error. DO NOT USE.
///

View file

@ -12,12 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use clap_complete::ArgValueCandidates;
use jj_lib::matchers::EverythingMatcher;
use tracing::instrument;
use crate::cli_util::CommandHelper;
use crate::cli_util::RevisionArg;
use crate::command_error::CommandError;
use crate::complete;
use crate::diff_util::DiffFormatArgs;
use crate::ui::Ui;
@ -25,7 +27,7 @@ use crate::ui::Ui;
#[derive(clap::Args, Clone, Debug)]
pub(crate) struct ShowArgs {
/// Show changes in this revision, compared to its parent(s)
#[arg(default_value = "@")]
#[arg(default_value = "@", add = ArgValueCandidates::new(complete::all_revisions))]
revision: RevisionArg,
/// Ignored (but lets you pass `-r` for consistency with other commands)
#[arg(short = 'r', hide = true)]

View file

@ -1,5 +1,6 @@
use std::collections::HashSet;
use clap_complete::ArgValueCandidates;
use itertools::Itertools;
use jj_lib::backend::BackendResult;
use jj_lib::revset::RevsetExpression;
@ -9,6 +10,7 @@ use jj_lib::settings::UserSettings;
use crate::cli_util::CommandHelper;
use crate::cli_util::RevisionArg;
use crate::command_error::CommandError;
use crate::complete;
use crate::ui::Ui;
/// Simplify parent edges for the specified revision(s).
@ -25,10 +27,18 @@ use crate::ui::Ui;
pub(crate) struct SimplifyParentsArgs {
/// Simplify specified revision(s) together with their trees of descendants
/// (can be repeated)
#[arg(long, short, group = "revision-args")]
#[arg(
long, short,
group = "revision-args",
add = ArgValueCandidates::new(complete::mutable_revisions),
)]
source: Vec<RevisionArg>,
/// Simplify specified revision(s) (can be repeated)
#[arg(long, short, group = "revision-args")]
#[arg(
long, short,
group = "revision-args",
add = ArgValueCandidates::new(complete::mutable_revisions),
)]
revisions: Vec<RevisionArg>,
}

View file

@ -13,6 +13,7 @@
// limitations under the License.
use std::io::Write;
use clap_complete::ArgValueCandidates;
use jj_lib::object_id::ObjectId;
use jj_lib::repo::Repo;
use tracing::instrument;
@ -21,6 +22,7 @@ use crate::cli_util::CommandHelper;
use crate::cli_util::RevisionArg;
use crate::command_error::user_error_with_hint;
use crate::command_error::CommandError;
use crate::complete;
use crate::description_util::description_template;
use crate::description_util::edit_description;
use crate::ui::Ui;
@ -52,7 +54,11 @@ pub(crate) struct SplitArgs {
#[arg(long, value_name = "NAME")]
tool: Option<String>,
/// The revision to split
#[arg(long, short, default_value = "@")]
#[arg(
long, short,
default_value = "@",
add = ArgValueCandidates::new(complete::mutable_revisions)
)]
revision: RevisionArg,
/// Split the revision into two parallel revisions instead of a parent and
/// child.

View file

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use clap_complete::ArgValueCandidates;
use itertools::Itertools as _;
use jj_lib::commit::Commit;
use jj_lib::commit::CommitIteratorExt;
@ -29,6 +30,7 @@ use crate::cli_util::WorkspaceCommandTransaction;
use crate::command_error::user_error;
use crate::command_error::user_error_with_hint;
use crate::command_error::CommandError;
use crate::complete;
use crate::description_util::combine_messages;
use crate::description_util::join_message_paragraphs;
use crate::ui::Ui;
@ -57,13 +59,22 @@ use crate::ui::Ui;
#[derive(clap::Args, Clone, Debug)]
pub(crate) struct SquashArgs {
/// Revision to squash into its parent (default: @)
#[arg(long, short)]
#[arg(long, short, add = ArgValueCandidates::new(complete::mutable_revisions))]
revision: Option<RevisionArg>,
/// Revision(s) to squash from (default: @)
#[arg(long, short, conflicts_with = "revision")]
#[arg(
long, short,
conflicts_with = "revision",
add = ArgValueCandidates::new(complete::mutable_revisions),
)]
from: Vec<RevisionArg>,
/// Revision to squash into (default: @)
#[arg(long, short = 't', conflicts_with = "revision", visible_alias = "to")]
#[arg(
long, short = 't',
conflicts_with = "revision",
visible_alias = "to",
add = ArgValueCandidates::new(complete::mutable_revisions),
)]
into: Option<RevisionArg>,
/// The description to use for squashed revision (don't open editor)
#[arg(long = "message", short, value_name = "MESSAGE")]

View file

@ -208,6 +208,39 @@ pub fn aliases() -> Vec<CompletionCandidate> {
})
}
fn revisions(revisions: &str) -> Vec<CompletionCandidate> {
with_jj(|mut jj, _| {
let output = jj
.arg("log")
.arg("--no-graph")
.arg("--limit")
.arg("100")
.arg("--revisions")
.arg(revisions)
.arg("--template")
.arg(r#"change_id.shortest() ++ " " ++ if(description, description.first_line(), "(no description set)") ++ "\n""#)
.output()
.map_err(user_error)?;
let stdout = String::from_utf8_lossy(&output.stdout);
Ok(stdout
.lines()
.map(|line| {
let (id, desc) = split_help_text(line);
CompletionCandidate::new(id).help(desc)
})
.collect())
})
}
pub fn mutable_revisions() -> Vec<CompletionCandidate> {
revisions("mutable()")
}
pub fn all_revisions() -> Vec<CompletionCandidate> {
revisions("all()")
}
/// Shell out to jj during dynamic completion generation
///
/// In case of errors, print them and early return an empty vector.

View file

@ -309,3 +309,39 @@ fn test_aliases_are_completed() {
);
insta::assert_snapshot!(stdout, @"");
}
#[test]
fn test_revisions() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
let repo_path = test_env.env_root().join("repo");
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "immutable"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "mutable"]);
test_env.jj_cmd_ok(&repo_path, &["bookmark", "create", "main", "-r", "@--"]);
test_env.add_config(r#"revset-aliases."immutable_heads()" = "main""#);
let mut test_env = test_env;
test_env.add_env_var("COMPLETE", "fish");
let test_env = test_env;
// There are _a lot_ of commands and arguments accepting revisions.
// Let's not test all of them. Having at least one test per variation of
// completion function should be sufficient.
// complete all revisions
let stdout = test_env.jj_cmd_success(&repo_path, &["--", "jj", "diff", "--from", ""]);
insta::assert_snapshot!(stdout, @r"
k (no description set)
r mutable
q immutable
z (no description set)
");
// complete only mutable revisions
let stdout = test_env.jj_cmd_success(&repo_path, &["--", "jj", "squash", "--into", ""]);
insta::assert_snapshot!(stdout, @r"
k (no description set)
r mutable
");
}