mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-12 23:23:20 +00:00
completion: teach jj about aliases
This makes completions suggest aliases from the user or repository
configuration. It's more useful for long aliases that aren't used very often,
but serve the purpose of "executable documentation" of complex and useful jj
commands.
An earlier patch "resolved" aliases, meaning that any arguments following an
alias would be completed as if the normal command had been used. So it only
made sure that using aliases doesn't degrade the rest of the completions.
Commit ID: 325402dc94
This commit is contained in:
parent
ef8e664555
commit
26ccc1c4cc
4 changed files with 78 additions and 2 deletions
|
@ -3248,7 +3248,11 @@ fn handle_shell_completion(
|
|||
let resolved_aliases = expand_args(ui, app, env::args_os().skip(2), config)?;
|
||||
args.extend(resolved_aliases.into_iter().map(OsString::from));
|
||||
}
|
||||
let ran_completion = clap_complete::CompleteEnv::with_factory(|| app.clone())
|
||||
let ran_completion = clap_complete::CompleteEnv::with_factory(|| {
|
||||
app.clone()
|
||||
// for completing aliases
|
||||
.allow_external_subcommands(true)
|
||||
})
|
||||
.try_complete(args.iter(), Some(cwd))?;
|
||||
assert!(
|
||||
ran_completion,
|
||||
|
|
|
@ -64,17 +64,20 @@ use std::fmt::Debug;
|
|||
use clap::CommandFactory;
|
||||
use clap::FromArgMatches;
|
||||
use clap::Subcommand;
|
||||
use clap_complete::engine::SubcommandCandidates;
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::cli_util::Args;
|
||||
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;
|
||||
|
||||
#[derive(clap::Parser, Clone, Debug)]
|
||||
#[command(disable_help_subcommand = true)]
|
||||
#[command(after_long_help = help::show_keyword_hint_after_help())]
|
||||
#[command(add = SubcommandCandidates::new(complete::aliases))]
|
||||
enum Command {
|
||||
Abandon(abandon::AbandonArgs),
|
||||
Absorb(absorb::AbsorbArgs),
|
||||
|
|
|
@ -144,6 +144,21 @@ pub fn git_remotes() -> Vec<CompletionCandidate> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn aliases() -> Vec<CompletionCandidate> {
|
||||
with_jj(|_, config| {
|
||||
Ok(config
|
||||
.get_table("aliases")?
|
||||
.into_keys()
|
||||
// This is opinionated, but many people probably have several
|
||||
// single- or two-letter aliases they use all the time. These
|
||||
// aliases don't need to be completed and they would only clutter
|
||||
// the output of `jj <TAB>`.
|
||||
.filter(|alias| alias.len() > 2)
|
||||
.map(CompletionCandidate::new)
|
||||
.collect())
|
||||
})
|
||||
}
|
||||
|
||||
/// Shell out to jj during dynamic completion generation
|
||||
///
|
||||
/// In case of errors, print them and early return an empty vector.
|
||||
|
|
|
@ -242,3 +242,57 @@ fn test_remote_names() {
|
|||
);
|
||||
insta::assert_snapshot!(stdout, @r"origin");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_aliases_are_completed() {
|
||||
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");
|
||||
|
||||
// user config alias
|
||||
test_env.add_config(r#"aliases.user-alias = ["bookmark"]"#);
|
||||
// repo config alias
|
||||
test_env.jj_cmd_ok(
|
||||
&repo_path,
|
||||
&[
|
||||
"config",
|
||||
"set",
|
||||
"--repo",
|
||||
"aliases.repo-alias",
|
||||
"['bookmark']",
|
||||
],
|
||||
);
|
||||
|
||||
let mut test_env = test_env;
|
||||
test_env.add_env_var("COMPLETE", "fish");
|
||||
let test_env = test_env;
|
||||
|
||||
let stdout = test_env.jj_cmd_success(&repo_path, &["--", "jj", "user-al"]);
|
||||
insta::assert_snapshot!(stdout, @"user-alias");
|
||||
|
||||
// make sure --repository flag is respected
|
||||
let stdout = test_env.jj_cmd_success(
|
||||
test_env.env_root(),
|
||||
&[
|
||||
"--",
|
||||
"jj",
|
||||
"--repository",
|
||||
repo_path.to_str().unwrap(),
|
||||
"repo-al",
|
||||
],
|
||||
);
|
||||
insta::assert_snapshot!(stdout, @"repo-alias");
|
||||
|
||||
// cannot load aliases from --config-toml flag
|
||||
let stdout = test_env.jj_cmd_success(
|
||||
test_env.env_root(),
|
||||
&[
|
||||
"--",
|
||||
"jj",
|
||||
"--config-toml",
|
||||
"aliases.cli-alias = ['bookmark']",
|
||||
"cli-al",
|
||||
],
|
||||
);
|
||||
insta::assert_snapshot!(stdout, @"");
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue