Skip to content

Commit

Permalink
completion: include bookmarks and tags in revisions
Browse files Browse the repository at this point in the history
  • Loading branch information
senekor committed Nov 17, 2024
1 parent a22620d commit cad498d
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 15 deletions.
56 changes: 48 additions & 8 deletions cli/src/complete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,18 +218,58 @@ fn revisions(revisions: &str) -> Vec<CompletionCandidate> {
.arg("--revisions")
.arg(revisions)
.arg("--template")
.arg(r#"change_id.shortest() ++ " " ++ if(description, description.first_line(), "(no description set)") ++ "\n""#)
.arg(
r#"
change_id.shortest() ++ "\t" ++
bookmarks.map(|b| separate("@", b.name(), b.remote())).join(",") ++ "\t" ++
tags.map(|t| t.name()).join(",") ++ " " ++
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())
let mut candidates = Vec::new();

// display order:
// - 0: local bookmarks
// - 1: regular revisions
// - 2: tags
// - 3: remote bookmarks

for line in stdout.lines() {
let (id_and_refs, desc) = split_help_text(line);
let (id, bookmarks_and_tags) = id_and_refs
.split_once('\t')
.expect("template should contain a tab character");
let (bookmarks, tags) = bookmarks_and_tags
.split_once('\t')
.expect("template should contain two tab characters");

for b in bookmarks.split(',').filter(|b| !b.is_empty()) {
let order = if b.contains('@') { 3 } else { 0 };
candidates.push(
CompletionCandidate::new(b)
.help(desc.clone())
.display_order(Some(order)),
);
}
for t in tags.split(',').filter(|t| !t.is_empty()) {
candidates.push(
CompletionCandidate::new(t)
.help(desc.clone())
.display_order(Some(2)),
);
}
candidates.push(
CompletionCandidate::new(id)
.help(desc)
.display_order(Some(1)),
);
}

Ok(candidates)
})
}

Expand Down
48 changes: 41 additions & 7 deletions cli/tests/test_completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,10 +316,37 @@ fn test_revisions() {
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
let repo_path = test_env.env_root().join("repo");

// create remote to test remote branches
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "origin"]);
let origin_path = test_env.env_root().join("origin");
let origin_git_repo_path = origin_path
.join(".jj")
.join("repo")
.join("store")
.join("git");
test_env.jj_cmd_ok(
&repo_path,
&[
"git",
"remote",
"add",
"origin",
origin_git_repo_path.to_str().unwrap(),
],
);
test_env.jj_cmd_ok(&origin_path, &["b", "c", "remote_bookmark"]);
test_env.jj_cmd_ok(&origin_path, &["commit", "-m", "remote_commit"]);
test_env.jj_cmd_ok(&origin_path, &["git", "export"]);
test_env.jj_cmd_ok(&repo_path, &["git", "fetch"]);

test_env.jj_cmd_ok(&repo_path, &["b", "c", "immutable_bookmark"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "immutable"]);
test_env.add_config(r#"revset-aliases."immutable_heads()" = "immutable_bookmark""#);

test_env.jj_cmd_ok(&repo_path, &["b", "c", "mutable_bookmark"]);
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""#);

test_env.jj_cmd_ok(&repo_path, &["describe", "-m", "working_copy"]);

let mut test_env = test_env;
test_env.add_env_var("COMPLETE", "fish");
Expand All @@ -332,17 +359,24 @@ fn test_revisions() {
// 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
mutable_bookmark mutable
immutable_bookmark immutable
k working_copy
y mutable
q immutable
z (no description set)
zq remote_commit
zz (no description set)
remote_bookmark@origin remote_commit
");

// 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
mutable_bookmark mutable
k working_copy
y mutable
zq remote_commit
remote_bookmark@origin remote_commit
");
}

Expand Down

0 comments on commit cad498d

Please sign in to comment.