Skip to content

Commit

Permalink
completion: teach bookmark create, rename about prefix
Browse files Browse the repository at this point in the history
  • Loading branch information
senekor committed Nov 11, 2024
1 parent 482d2c4 commit 2f3ae25
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 1 deletion.
8 changes: 7 additions & 1 deletion cli/src/commands/bookmark/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// limitations under the License.

use clap::builder::NonEmptyStringValueParser;
use clap_complete::ArgValueCandidates;
use jj_lib::object_id::ObjectId as _;
use jj_lib::op_store::RefTarget;

Expand All @@ -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::ui::Ui;

/// Create a new bookmark
Expand All @@ -34,7 +36,11 @@ pub struct BookmarkCreateArgs {
revision: Option<RevisionArg>,

/// The bookmarks to create
#[arg(required = true, value_parser = NonEmptyStringValueParser::new())]
#[arg(
required = true,
value_parser = NonEmptyStringValueParser::new(),
add = ArgValueCandidates::new(complete::push_bookmark_prefix),
)]
names: Vec<String>,
}

Expand Down
1 change: 1 addition & 0 deletions cli/src/commands/bookmark/rename.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub struct BookmarkRenameArgs {
old: String,

/// The new name of the bookmark
#[arg(add = ArgValueCandidates::new(complete::bookmark_rename_new))]
new: String,
}

Expand Down
33 changes: 33 additions & 0 deletions cli/src/complete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,39 @@ pub fn local_bookmarks() -> Vec<CompletionCandidate> {
})
}

pub fn push_bookmark_prefix() -> Vec<CompletionCandidate> {
with_jj(|_, config| {
Ok(match config.get::<String>("git.push-bookmark-prefix") {
Ok(prefix) => vec![CompletionCandidate::new(prefix)],
Err(_) => Vec::new(), // user didn't configure a prefix
})
})
}

/// A specific completion function for the `new` argument of `bookmark rename`.
/// It suggests the `old` argument as first candidate, because the user may
/// want to fix a typo.
pub fn bookmark_rename_new() -> Vec<CompletionCandidate> {
let mut candidates = Vec::new();

let bookmark_to_rename = std::env::args_os()
.rev()
.filter_map(|arg| arg.into_string().ok())
.filter(|arg| !arg.starts_with("-"))
// The first non-flag argument is the one being completed, the second
// one is the "old" argument.
.nth(1);
if let Some(bookmark) = bookmark_to_rename {
candidates.push(CompletionCandidate::new(bookmark).display_order(Some(0)));
}
with_jj(|_, config| {
if let Ok(prefix) = config.get::<String>("git.push-bookmark-prefix") {
candidates.push(CompletionCandidate::new(prefix).display_order(Some(1)));
}
Ok(candidates)
})
}

/// Shell out to jj during dynamic completion generation
///
/// In case of errors, print them and early return an empty vector.
Expand Down
23 changes: 23 additions & 0 deletions cli/tests/test_completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,26 @@ fn test_global_arg_repository_is_respected() {
);
insta::assert_snapshot!(stdout, @"aaa");
}

#[test]
fn test_push_bookmark_prefix() {
let mut test_env = TestEnvironment::default();

test_env.add_config(r#"git.push-bookmark-prefix = "fancy-prefix/""#);

test_env.add_env_var("COMPLETE", "fish");

let stdout = test_env.jj_cmd_success(
test_env.env_root(),
&["--", "jj", "bookmark", "create", "f"],
);
insta::assert_snapshot!(stdout, @"fancy-prefix/");
let stdout = test_env.jj_cmd_success(
test_env.env_root(),
&["--", "jj", "bookmark", "rename", "fancy-old-name", "f"],
);
insta::assert_snapshot!(stdout, @r"
fancy-old-name
fancy-prefix/
");
}

0 comments on commit 2f3ae25

Please sign in to comment.