Autocompleting recipies inside of modules only works in Bash
I've noticed that auto-completion for recipes inside of modules only works in Bash. I'm using Just 1.35.0.
I've setup two files:
Justfile
mod bar
bar.just
command:
echo "work work work"
When using bash I can type just bar:: and tab complete returns command as expected. When using Fish, Zsh, or Nushell I don't get a response.
I've looked at this issue, but it seems unrelated.
Just incase it's useful, here's the contents of my completions.
Fish
function __fish_just_complete_recipes
if string match -rq '(-f|--justfile)\s*=?(?<justfile>[^\s]+)' -- (string split -- ' -- ' (commandline -pc))[1]
set -fx JUST_JUSTFILE "$justfile"
end
just --list 2> /dev/null | tail -n +2 | awk '{
command = $1;
args = $0;
desc = "";
delim = "";
sub(/^[[:space:]]*[^[:space:]]*/, "", args);
gsub(/^[[:space:]]+|[[:space:]]+$/, "", args);
if (match(args, /#.*/)) {
desc = substr(args, RSTART+2, RLENGTH);
args = substr(args, 0, RSTART-1);
gsub(/^[[:space:]]+|[[:space:]]+$/, "", args);
}
gsub(/\+|=[`\'"][^`\'"]*[`\'"]/, "", args);
gsub(/ /, ",", args);
if (args != ""){
args = "Args: " args;
}
if (args != "" && desc != "") {
delim = "; ";
}
print command "\t" args delim desc
}'
end
# don't suggest files right off
complete -c just -n "__fish_is_first_arg" --no-files
# complete recipes
complete -c just -a '(__fish_just_complete_recipes)'
# autogenerated completions
complete -c just -l chooser -d 'Override binary invoked by `--choose`' -r
complete -c just -l color -d 'Print colorful output' -r -f -a "{auto\t'',always\t'',never\t''}"
complete -c just -l command-color -d 'Echo recipe lines in <COMMAND-COLOR>' -r -f -a "{black\t'',blue\t'',cyan\t'',green\t'',purple\t'',red\t'',yellow\t''}"
complete -c just -l dotenv-filename -d 'Search for environment file named <DOTENV-FILENAME> instead of `.env`' -r
complete -c just -s E -l dotenv-path -d 'Load <DOTENV-PATH> as environment file instead of searching for one' -r -F
complete -c just -l dump-format -d 'Dump justfile as <FORMAT>' -r -f -a "{json\t'',just\t''}"
complete -c just -s f -l justfile -d 'Use <JUSTFILE> as justfile' -r -F
complete -c just -l list-heading -d 'Print <TEXT> before list' -r
complete -c just -l list-prefix -d 'Print <TEXT> before each list item' -r
complete -c just -l set -d 'Override <VARIABLE> with <VALUE>' -r
complete -c just -l shell -d 'Invoke <SHELL> to run recipes' -r
complete -c just -l shell-arg -d 'Invoke shell with <SHELL-ARG> as an argument' -r
complete -c just -l timestamp-format -d 'Timestamp format string' -r
complete -c just -s d -l working-directory -d 'Use <WORKING-DIRECTORY> as working directory. --justfile must also be set' -r -F
complete -c just -s c -l command -d 'Run an arbitrary command with the working directory, `.env`, overrides, and exports set' -r
complete -c just -l completions -d 'Print shell completion script for <SHELL>' -r -f -a "{bash\t'',elvish\t'',fish\t'',nushell\t'',powershell\t'',zsh\t''}"
complete -c just -s l -l list -d 'List available recipes' -r
complete -c just -s s -l show -d 'Show recipe at <PATH>' -r
complete -c just -l check -d 'Run `--fmt` in \'check\' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.'
complete -c just -l clear-shell-args -d 'Clear shell arguments'
complete -c just -s n -l dry-run -d 'Print what just would do without doing it'
complete -c just -s g -l global-justfile -d 'Use global justfile'
complete -c just -l highlight -d 'Highlight echoed recipe lines in bold'
complete -c just -l list-submodules -d 'List recipes in submodules'
complete -c just -l no-aliases -d 'Don\'t show aliases in list'
complete -c just -l no-deps -d 'Don\'t run recipe dependencies'
complete -c just -l no-dotenv -d 'Don\'t load `.env` file'
complete -c just -l no-highlight -d 'Don\'t highlight echoed recipe lines in bold'
complete -c just -s q -l quiet -d 'Suppress all output'
complete -c just -l shell-command -d 'Invoke <COMMAND> with the shell used to run recipe lines and backticks'
complete -c just -l timestamp -d 'Print recipe command timestamps'
complete -c just -s u -l unsorted -d 'Return list and summary entries in source order'
complete -c just -l unstable -d 'Enable unstable features'
complete -c just -s v -l verbose -d 'Use verbose output'
complete -c just -l yes -d 'Automatically confirm all recipes.'
complete -c just -l changelog -d 'Print changelog'
complete -c just -l choose -d 'Select one or more recipes to run using a binary chooser. If `--chooser` is not passed the chooser defaults to the value of $JUST_CHOOSER, falling back to `fzf`'
complete -c just -l dump -d 'Print justfile'
complete -c just -s e -l edit -d 'Edit justfile with editor given by $VISUAL or $EDITOR, falling back to `vim`'
complete -c just -l evaluate -d 'Evaluate and print all variables. If a variable name is given as an argument, only print that variable\'s value.'
complete -c just -l fmt -d 'Format and overwrite justfile'
complete -c just -l groups -d 'List recipe groups'
complete -c just -l init -d 'Initialize new justfile in project root'
complete -c just -l man -d 'Print man page'
complete -c just -l summary -d 'List names of available recipes'
complete -c just -l variables -d 'List names of variables'
complete -c just -s h -l help -d 'Print help'
complete -c just -s V -l version -d 'Print version'
Bash
_just() {
local i cur prev words cword opts cmd
COMPREPLY=()
# Modules use "::" as the separator, which is considered a wordbreak character in bash.
# The _get_comp_words_by_ref function is a hack to allow for exceptions to this rule without
# modifying the global COMP_WORDBREAKS environment variable.
if type _get_comp_words_by_ref &>/dev/null; then
_get_comp_words_by_ref -n : cur prev words cword
else
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
words=$COMP_WORDS
cword=$COMP_CWORD
fi
cmd=""
opts=""
for i in ${words[@]}
do
case "${cmd},${i}" in
",$1")
cmd="just"
;;
*)
;;
esac
done
case "${cmd}" in
just)
opts="-E -n -g -f -q -u -v -d -c -e -l -s -h -V --check --chooser --clear-shell-args --color --command-color --dotenv-filename --dotenv-path --dry-run --dump-format --global-justfile --highlight --justfile --list-heading --list-prefix --list-submodules --no-aliases --no-deps --no-dotenv --no-highlight --quiet --set --shell --shell-arg --shell-command --timestamp --timestamp-format --unsorted --unstable --verbose --working-directory --yes --changelog --choose --command --completions --dump --edit --evaluate --fmt --groups --init --list --man --show --summary --variables --help --version [ARGUMENTS]..."
if [[ ${cur} == -* ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
elif [[ ${cword} -eq 1 ]]; then
local recipes=$(just --summary 2> /dev/null)
if echo "${cur}" | \grep -qF '/'; then
local path_prefix=$(echo "${cur}" | sed 's/[/][^/]*$/\//')
local recipes=$(just --summary 2> /dev/null -- "${path_prefix}")
local recipes=$(printf "${path_prefix}%s\t" $recipes)
fi
if [[ $? -eq 0 ]]; then
COMPREPLY=( $(compgen -W "${recipes}" -- "${cur}") )
if type __ltrim_colon_completions &>/dev/null; then
__ltrim_colon_completions "$cur"
fi
return 0
fi
fi
case "${prev}" in
--chooser)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--color)
COMPREPLY=($(compgen -W "auto always never" -- "${cur}"))
return 0
;;
--command-color)
COMPREPLY=($(compgen -W "black blue cyan green purple red yellow" -- "${cur}"))
return 0
;;
--dotenv-filename)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--dotenv-path)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-E)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--dump-format)
COMPREPLY=($(compgen -W "json just" -- "${cur}"))
return 0
;;
--justfile)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-f)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--list-heading)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--list-prefix)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--set)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--shell)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--shell-arg)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--timestamp-format)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--working-directory)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-d)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--command)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-c)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--completions)
COMPREPLY=($(compgen -W "bash elvish fish nushell powershell zsh" -- "${cur}"))
return 0
;;
--list)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-l)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--show)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-s)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
esac
}
if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then
complete -F _just -o nosort -o bashdefault -o default just
else
complete -F _just -o bashdefault -o default just
fi
NuShell
just --completions nushell
def "nu-complete just" [] {
(^just --dump --unstable --dump-format json | from json).recipes | transpose recipe data | flatten | where {|row| $row.private == false } | select recipe doc parameters | rename value description
}
# Just: A Command Runner
export extern "just" [
...recipe: string@"nu-complete just", # Recipe(s) to run, may be with argument(s)
]
Looks like maybe https://github.com/casey/just/pull/1863 added support for this in Bash, was never implemented for fish?
Fish completion seems to be working for me since 1.39 🎉
Sweet, good to hear!