Skip to content

Instantly share code, notes, and snippets.

@marek-saji
Last active December 5, 2023 15:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marek-saji/dee1df3cd7af3f6b74e608ab1d7ec473 to your computer and use it in GitHub Desktop.
Save marek-saji/dee1df3cd7af3f6b74e608ab1d7ec473 to your computer and use it in GitHub Desktop.
Bash autocompletion for nx
#!/usr/bin/env bash
# Very naive completion for nx <https://www.npmjs.com/package/nx>.
#
# - Requires jq(1) to be present for completion of targets.
# - Uses _get_comp_words_by_ref and __ltrim_colon_completions which are
# usully found in /etc/bash_completion
#
# Gist: https://gist.github.com/marek-saji/dee1df3cd7af3f6b74e608ab1d7ec473
#
# Licensed under ISC license:
#
# Copyright © 2023 Marek “saji” Augustynowicz <marek.aug@gmail.com>
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
# above copyright notice and this permission notice appear in all
# copies.
#
# THE SOFTWARE IS PROVIDED “AS IS” AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY
# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
_nx_complete_command ()
{
local cur="$1"
# shellcheck disable=SC2207
COMPREPLY=($(
compgen \
-W "$( nx 2>&1 --help | grep -o '^ nx [a-z:-]*' | cut -d' ' -f4 )" \
-- "$cur"
))
}
_nx_complete_projects ()
{
local cur="$1"
# shellcheck disable=SC2207
COMPREPLY=($(
compgen \
-W "$( nx show projects )" \
-- "$cur"
))
}
_nx_complete_command_show ()
{
local cur="$1"
# shellcheck disable=SC2207
COMPREPLY=($(
compgen \
-W "project projects" \
-- "$cur"
))
}
_nx_complete_command_run ()
{
local cur="$1"
if command -v jq >/dev/null 2>&1
then
# shellcheck disable=SC2207
COMPREPLY=($(
compgen \
-W "$( jq 2>/dev/null -r '.name, .name + ":" + (.targets | keys | .[])' ./**/project.json | sort -u )" \
-- "$cur"
))
fi
}
_nx_complete_target ()
{
local cur="$1"
if command -v jq >/dev/null 2>&1
then
# shellcheck disable=SC2207
COMPREPLY=($(
# More correct way, but slow:
# nx show projects | xargs -n1 nx show project | jq -r '.targets | keys | .[]' | sort -u
compgen \
-W "$( jq 2>/dev/null -r '.targets | keys | .[]' ./**/project.json | sort -u )" \
-- "$cur"
))
fi
}
_nx_complete_branch ()
{
local cur="$1"
# shellcheck disable=SC2207
COMPREPLY=($(
compgen \
-W "$( git branch --all --format='%(refname:short)' )" \
-- "$cur"
))
}
_nx_complete_arg ()
{
local cur="$1"
local prev="$2"
local command="$3"
if [ "${cur:0:1}" = '-' ]
then
# shellcheck disable=SC2207
COMPREPLY=($(
compgen \
-W "$( nx 2>&1 "$command" --help | grep -Eo '^\s*(-[a-z-]*,?\s*)*' | grep -oE -- '-[a-z-]*' | sort -u )" \
-- "$cur"
))
else
local prev_word="${COMP_WORDS[COMP_CWORD - 1]}"
case "$prev_word" in
'-t' | '--target' | '--with-target')
_nx_complete_target "$cur"
;;
'--base' | '--head' )
_nx_complete_branch "$cur"
;;
esac
fi
}
_nx_complete ()
{
local words cword prev cur
_get_comp_words_by_ref -n : words cword prev cur
# DEBUG
# printf "\n<debug>\n"
# # set | grep ^COMP_
# echo " words=( ${words[*]} )"
# echo " cur=$cur"
# echo " prev=$prev"
# echo " cword=$cword"
# printf "</debug>\n"
if [ "$cword" -eq 1 ]
then
# TODO Also autocomplete `nx TARGET PROJECT RUN_ARGS`
_nx_complete_command "$cur"
elif [ "${words[*]:1:1}" = "show" ] && [ "$cword" -eq 2 ]
then
_nx_complete_command_show "$cur"
elif [ "${words[*]:1:2}" = "show project" ] && [ "$cword" -eq 3 ]
then
_nx_complete_projects "$cur"
elif [ "${words[*]:1:1}" = "run" ] && [ "$cword" -eq 2 ]
then
_nx_complete_command_run "$cur"
else
command="${words[1]}"
_nx_complete_arg "$cur" "$prev" "$command"
fi
__ltrim_colon_completions "$cur"
}
complete -F _nx_complete nx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment