Skip to content

Commit

Permalink
completion: teach commands about files
Browse files Browse the repository at this point in the history
This is heavily based on Benjamin Tan's fish completions:
https://gist.github.com/bnjmnt4n/9f47082b8b6e6ed2b2a805a1516090c8

Some differences include:
- The end of a `--from`, `--to` ranges is also considered.
- `jj log` is not completed (yet). It has a different `--revisions` argument
  that requires some special handling.
  • Loading branch information
senekor committed Nov 28, 2024
1 parent a5690be commit 5fcc549
Show file tree
Hide file tree
Showing 13 changed files with 542 additions and 11 deletions.
7 changes: 6 additions & 1 deletion cli/src/commands/commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::Signature;
use jj_lib::object_id::ObjectId;
use jj_lib::repo::Repo;
Expand All @@ -20,6 +21,7 @@ use tracing::instrument;
use crate::cli_util::CommandHelper;
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::join_message_paragraphs;
Expand All @@ -40,7 +42,10 @@ pub(crate) struct CommitArgs {
#[arg(long = "message", short, value_name = "MESSAGE")]
message_paragraphs: Vec<String>,
/// Put these paths in the first commit
#[arg(value_hint = clap::ValueHint::AnyPath)]
#[arg(
value_hint = clap::ValueHint::AnyPath,
add = ArgValueCandidates::new(complete::modified_files),
)]
paths: Vec<String>,
/// Reset the author to the configured user
///
Expand Down
5 changes: 4 additions & 1 deletion cli/src/commands/diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ pub(crate) struct DiffArgs {
#[arg(long, short, conflicts_with = "revision", add = ArgValueCandidates::new(complete::all_revisions))]
to: Option<RevisionArg>,
/// Restrict the diff to these paths
#[arg(value_hint = clap::ValueHint::AnyPath)]
#[arg(
value_hint = clap::ValueHint::AnyPath,
add = ArgValueCandidates::new(complete::modified_revision_or_range_files),
)]
paths: Vec<String>,
#[command(flatten)]
format: DiffFormatArgs,
Expand Down
6 changes: 5 additions & 1 deletion cli/src/commands/file/annotate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// limitations under the License.

use clap_complete::ArgValueCandidates;
use clap_complete::ArgValueCompleter;
use jj_lib::annotate::get_annotation_for_file;
use jj_lib::annotate::FileAnnotation;
use jj_lib::commit::Commit;
Expand All @@ -37,7 +38,10 @@ use crate::ui::Ui;
#[derive(clap::Args, Clone, Debug)]
pub(crate) struct FileAnnotateArgs {
/// the file to annotate
#[arg(value_hint = clap::ValueHint::AnyPath)]
#[arg(
value_hint = clap::ValueHint::AnyPath,
add = ArgValueCompleter::new(complete::all_revision_files),
)]
path: String,
/// an optional revision to start at
#[arg(long, short, add = ArgValueCandidates::new(complete::all_revisions))]
Expand Down
7 changes: 6 additions & 1 deletion cli/src/commands/file/chmod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// limitations under the License.

use clap_complete::ArgValueCandidates;
use clap_complete::ArgValueCompleter;
use jj_lib::backend::TreeValue;
use jj_lib::merged_tree::MergedTreeBuilder;
use jj_lib::object_id::ObjectId;
Expand Down Expand Up @@ -52,7 +53,11 @@ pub(crate) struct FileChmodArgs {
)]
revision: RevisionArg,
/// Paths to change the executable bit for
#[arg(required = true, value_hint = clap::ValueHint::AnyPath)]
#[arg(
required = true,
value_hint = clap::ValueHint::AnyPath,
add = ArgValueCompleter::new(complete::all_revision_files),
)]
paths: Vec<String>,
}

Expand Down
7 changes: 6 additions & 1 deletion cli/src/commands/file/show.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use std::io;
use std::io::Write;

use clap_complete::ArgValueCandidates;
use clap_complete::ArgValueCompleter;
use jj_lib::backend::BackendResult;
use jj_lib::conflicts::materialize_merge_result;
use jj_lib::conflicts::materialize_tree_value;
Expand Down Expand Up @@ -51,7 +52,11 @@ pub(crate) struct FileShowArgs {
)]
revision: RevisionArg,
/// Paths to print
#[arg(required = true, value_hint = clap::ValueHint::FilePath)]
#[arg(
required = true,
value_hint = clap::ValueHint::FilePath,
add = ArgValueCompleter::new(complete::all_revision_files),
)]
paths: Vec<String>,
}

Expand Down
8 changes: 7 additions & 1 deletion cli/src/commands/file/untrack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

use std::io::Write;

use clap_complete::ArgValueCompleter;
use itertools::Itertools;
use jj_lib::merge::Merge;
use jj_lib::merged_tree::MergedTreeBuilder;
Expand All @@ -24,6 +25,7 @@ use tracing::instrument;
use crate::cli_util::CommandHelper;
use crate::command_error::user_error_with_hint;
use crate::command_error::CommandError;
use crate::complete;
use crate::ui::Ui;

/// Stop tracking specified paths in the working copy
Expand All @@ -33,7 +35,11 @@ pub(crate) struct FileUntrackArgs {
///
/// The paths could be ignored via a .gitignore or .git/info/exclude (in
/// colocated repos).
#[arg(required = true, value_hint = clap::ValueHint::AnyPath)]
#[arg(
required = true,
value_hint = clap::ValueHint::AnyPath,
add = ArgValueCompleter::new(complete::all_revision_files),
)]
paths: Vec<String>,
}

Expand Down
5 changes: 4 additions & 1 deletion cli/src/commands/interdiff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ pub(crate) struct InterdiffArgs {
#[arg(long, short, add = ArgValueCandidates::new(complete::all_revisions))]
to: Option<RevisionArg>,
/// Restrict the diff to these paths
#[arg(value_hint = clap::ValueHint::AnyPath)]
#[arg(
value_hint = clap::ValueHint::AnyPath,
add = ArgValueCandidates::new(complete::interdiff_files),
)]
paths: Vec<String>,
#[command(flatten)]
format: DiffFormatArgs,
Expand Down
5 changes: 4 additions & 1 deletion cli/src/commands/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ pub(crate) struct ResolveArgs {
/// will attempt to resolve the first conflict we can find. You can use
/// the `--list` argument to find paths to use here.
// TODO: Find the conflict we can resolve even if it's not the first one.
#[arg(value_hint = clap::ValueHint::AnyPath)]
#[arg(
value_hint = clap::ValueHint::AnyPath,
add = ArgValueCandidates::new(complete::revision_conflicted_files),
)]
paths: Vec<String>,
}

Expand Down
5 changes: 4 additions & 1 deletion cli/src/commands/restore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ use crate::ui::Ui;
#[derive(clap::Args, Clone, Debug)]
pub(crate) struct RestoreArgs {
/// Restore only these paths (instead of all paths)
#[arg(value_hint = clap::ValueHint::AnyPath)]
#[arg(
value_hint = clap::ValueHint::AnyPath,
add = ArgValueCandidates::new(complete::modified_range_files),
)]
paths: Vec<String>,
/// Revision to restore from (source)
#[arg(long, short, add = ArgValueCandidates::new(complete::all_revisions))]
Expand Down
5 changes: 4 additions & 1 deletion cli/src/commands/split.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ pub(crate) struct SplitArgs {
#[arg(long, short, alias = "siblings")]
parallel: bool,
/// Put these paths in the first commit
#[arg(value_hint = clap::ValueHint::AnyPath)]
#[arg(
value_hint = clap::ValueHint::AnyPath,
add = ArgValueCandidates::new(complete::modified_revision_files),
)]
paths: Vec<String>,
}

Expand Down
6 changes: 5 additions & 1 deletion cli/src/commands/squash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,11 @@ pub(crate) struct SquashArgs {
#[arg(long, value_name = "NAME")]
tool: Option<String>,
/// Move only changes to these paths (instead of all paths)
#[arg(conflicts_with_all = ["interactive", "tool"], value_hint = clap::ValueHint::AnyPath)]
#[arg(
conflicts_with_all = ["interactive", "tool"],
value_hint = clap::ValueHint::AnyPath,
add = ArgValueCandidates::new(complete::squash_revision_files),
)]
paths: Vec<String>,
/// The source revision will not be abandoned
#[arg(long, short)]
Expand Down
Loading

0 comments on commit 5fcc549

Please sign in to comment.