Complete recipes in bash completion script (#685)

Modifies the bash completion script to complete both recipes and flags.
`just <TAB>` will complete recipes, and `just -<TAB>` will complete
flags and options.
This commit is contained in:
Vikesh Raj 2020-10-06 06:28:30 +05:30 committed by GitHub
parent 601cc69028
commit a8361012d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 21 deletions

View File

@ -21,10 +21,16 @@ _just() {
case "${cmd}" in case "${cmd}" in
just) just)
opts=" -q -u -v -e -l -h -V -f -d -s --dry-run --highlight --no-dotenv --no-highlight --quiet --clear-shell-args --unsorted --verbose --choose --dump --edit --evaluate --init --list --summary --variables --help --version --chooser --color --justfile --set --shell --shell-arg --working-directory --completions --show <ARGUMENTS>... " opts=" -q -u -v -e -l -h -V -f -d -s --dry-run --highlight --no-dotenv --no-highlight --quiet --clear-shell-args --unsorted --verbose --choose --dump --edit --evaluate --init --list --summary --variables --help --version --chooser --color --justfile --set --shell --shell-arg --working-directory --completions --show <ARGUMENTS>... "
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then if [[ ${cur} == -* ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0 return 0
fi elif [[ ${COMP_CWORD} -eq 1 ]]; then
local recipes=$(just --summary --color never 2> /dev/null)
if [[ $? -eq 0 ]]; then
COMPREPLY=( $(compgen -W "${recipes}" -- "${cur}") )
return 0
fi
fi
case "${prev}" in case "${prev}" in
--chooser) --chooser)

View File

@ -18,14 +18,6 @@ pub(crate) use std::{
usize, vec, usize, vec,
}; };
// modules used in tests
#[cfg(test)]
pub(crate) use crate::testing;
// structs and enums used in tests
#[cfg(test)]
pub(crate) use crate::{node::Node, tree::Tree};
// dependencies // dependencies
pub(crate) use derivative::Derivative; pub(crate) use derivative::Derivative;
pub(crate) use edit_distance::edit_distance; pub(crate) use edit_distance::edit_distance;
@ -73,3 +65,11 @@ pub(crate) type CompilationResult<'a, T> = Result<T, CompilationError<'a>>;
pub(crate) type ConfigResult<T> = Result<T, ConfigError>; pub(crate) type ConfigResult<T> = Result<T, ConfigError>;
pub(crate) type RunResult<'a, T> = Result<T, RuntimeError<'a>>; pub(crate) type RunResult<'a, T> = Result<T, RuntimeError<'a>>;
pub(crate) type SearchResult<T> = Result<T, SearchError>; pub(crate) type SearchResult<T> = Result<T, SearchError>;
// modules used in tests
#[cfg(test)]
pub(crate) use crate::testing;
// structs and enums used in tests
#[cfg(test)]
pub(crate) use crate::{node::Node, tree::Tree};

View File

@ -113,8 +113,27 @@ _just "$@""#,
), ),
]; ];
const BASH_COMPLETION_REPLACEMENTS: &[(&str, &str)] = &[(
r#" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi"#,
r#" if [[ ${cur} == -* ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
elif [[ ${COMP_CWORD} -eq 1 ]]; then
local recipes=$(just --summary --color never 2> /dev/null)
if [[ $? -eq 0 ]]; then
COMPREPLY=( $(compgen -W "${recipes}" -- "${cur}") )
return 0
fi
fi"#,
)];
impl Subcommand { impl Subcommand {
pub(crate) fn completions(shell: &str) -> Result<(), i32> { pub(crate) fn completions(shell: &str) -> Result<(), i32> {
use clap::Shell;
fn replace(haystack: &mut String, needle: &str, replacement: &str) -> Result<(), i32> { fn replace(haystack: &mut String, needle: &str, replacement: &str) -> Result<(), i32> {
if let Some(index) = haystack.find(needle) { if let Some(index) = haystack.find(needle) {
haystack.replace_range(index..index + needle.len(), replacement); haystack.replace_range(index..index + needle.len(), replacement);
@ -129,7 +148,7 @@ impl Subcommand {
} }
let shell = shell let shell = shell
.parse::<clap::Shell>() .parse::<Shell>()
.expect("Invalid value for clap::Shell"); .expect("Invalid value for clap::Shell");
let buffer = Vec::new(); let buffer = Vec::new();
@ -138,14 +157,19 @@ impl Subcommand {
let buffer = cursor.into_inner(); let buffer = cursor.into_inner();
let mut script = String::from_utf8(buffer).expect("Clap completion not UTF-8"); let mut script = String::from_utf8(buffer).expect("Clap completion not UTF-8");
if let clap::Shell::Zsh = shell { match shell {
for (needle, replacement) in ZSH_COMPLETION_REPLACEMENTS { Shell::Bash =>
replace(&mut script, needle, replacement)?; for (needle, replacement) in BASH_COMPLETION_REPLACEMENTS {
} replace(&mut script, needle, replacement)?;
} },
Shell::Fish => {
if let clap::Shell::Fish = shell { script.insert_str(0, FISH_RECIPE_COMPLETIONS);
script.insert_str(0, FISH_RECIPE_COMPLETIONS); },
Shell::Zsh =>
for (needle, replacement) in ZSH_COMPLETION_REPLACEMENTS {
replace(&mut script, needle, replacement)?;
},
_ => {},
} }
println!("{}", script.trim()); println!("{}", script.trim());