Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Qhughes/tabcomplete #4

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions activate-argcomplete.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Copyright 2012-2019, Andrey Kislyuk and argcomplete contributors.
# Licensed under the Apache License. See https://github.com/kislyuk/argcomplete for more info.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@brianthelion are there consequences for our license in pulling this file in?


# Copy of __expand_tilde_by_ref from bash-completion
__python_argcomplete_expand_tilde_by_ref () {
if [ "${!1:0:1}" = "~" ]; then
if [ "${!1}" != "${!1//\/}" ]; then
eval $1="${!1/%\/*}"/'${!1#*/}';
else
eval $1="${!1}";
fi;
fi
}

# Run something, muting output or redirecting it to the debug stream
# depending on the value of _ARC_DEBUG.
# If ARGCOMPLETE_USE_TEMPFILES is set, use tempfiles for IPC.
__python_argcomplete_run() {
if [[ -z "$ARGCOMPLETE_USE_TEMPFILES" ]]; then
__python_argcomplete_run_inner "$@"
return
fi
local tmpfile="$(mktemp)"
_ARGCOMPLETE_STDOUT_FILENAME="$tmpfile" __python_argcomplete_run_inner "$@"
local code=$?
cat "$tmpfile"
rm "$tmpfile"
return $code
}

__python_argcomplete_run_inner() {
if [[ -z "$_ARC_DEBUG" ]]; then
"$@" 8>&1 9>&2 1>/dev/null 2>&1
else
"$@" 8>&1 9>&2 1>&9 2>&1
fi
}

# Scan the beginning of an executable file ($1) for a regexp ($2). By default,
# scan for the magic string indicating that the executable supports the
# argcomplete completion protocol. By default, scan the first kilobyte;
# if $3 is set to -n, scan until the first line break up to a kilobyte.
__python_argcomplete_scan_head() {
read -s -r ${3:--N} 1024 < "$1"
[[ "$REPLY" =~ ${2:-PYTHON_ARGCOMPLETE_OK} ]]
}

__python_argcomplete_scan_head_noerr() {
__python_argcomplete_scan_head "$@" 2>/dev/null
}

_python_argcomplete_global() {
local executable=$1
__python_argcomplete_expand_tilde_by_ref executable

local ARGCOMPLETE=0
if [[ "$executable" == python* ]] || [[ "$executable" == pypy* ]]; then
if [[ "${COMP_WORDS[1]}" == -m ]]; then
if __python_argcomplete_run "$executable" -m argcomplete._check_module "${COMP_WORDS[2]}"; then
ARGCOMPLETE=3
else
return
fi
elif [[ -f "${COMP_WORDS[1]}" ]] && __python_argcomplete_scan_head_noerr "${COMP_WORDS[1]}"; then
local ARGCOMPLETE=2
else
return
fi
elif type -P "$executable" >/dev/null 2>&1; then
local SCRIPT_NAME=$(type -P "$executable")
if (type -t pyenv && [[ "$SCRIPT_NAME" = $(pyenv root)/shims/* ]]) >/dev/null 2>&1; then
local SCRIPT_NAME=$(pyenv which "$executable")
fi
if __python_argcomplete_scan_head_noerr "$SCRIPT_NAME"; then
local ARGCOMPLETE=1
elif __python_argcomplete_scan_head_noerr "$SCRIPT_NAME" '^#!(.*)$' -n && [[ "${BASH_REMATCH[1]}" =~ ^.*(python|pypy)[0-9\.]*$ ]]; then
local interpreter="$BASH_REMATCH"
if (__python_argcomplete_scan_head_noerr "$SCRIPT_NAME" "(PBR Generated)|(EASY-INSTALL-(SCRIPT|ENTRY-SCRIPT|DEV-SCRIPT))" \
&& "$interpreter" "$(type -P python-argcomplete-check-easy-install-script)" "$SCRIPT_NAME") >/dev/null 2>&1; then
local ARGCOMPLETE=1
elif __python_argcomplete_run "$interpreter" -m argcomplete._check_console_script "$SCRIPT_NAME"; then
local ARGCOMPLETE=1
fi
fi
fi

if [[ $ARGCOMPLETE != 0 ]]; then
local IFS=$(echo -e '\v')
COMPREPLY=( $(_ARGCOMPLETE_IFS="$IFS" \
COMP_LINE="$COMP_LINE" \
COMP_POINT="$COMP_POINT" \
COMP_TYPE="$COMP_TYPE" \
_ARGCOMPLETE_COMP_WORDBREAKS="$COMP_WORDBREAKS" \
_ARGCOMPLETE=$ARGCOMPLETE \
_ARGCOMPLETE_SUPPRESS_SPACE=1 \
__python_argcomplete_run "$executable" "${COMP_WORDS[@]:1:ARGCOMPLETE-1}") )
if [[ $? != 0 ]]; then
unset COMPREPLY
elif [[ "$COMPREPLY" =~ [=/:]$ ]]; then
compopt -o nospace
fi
else
type -t _completion_loader | grep -q 'function' && _completion_loader "$@"
fi
}
complete -o default -o bashdefault -D -F _python_argcomplete_global
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ package_dir =
setup_requires = pyscaffold>=3.2a0,<3.3a0
# Add here dependencies of your project (semicolon/line-separated), e.g.
# install_requires = numpy; scipy
install_requires = venusian; pandas;
install_requires = venusian; pandas; argcomplete;
# The usage of test_requires is discouraged, see `Dependency Management` docs
# tests_require = pytest; pytest-cov
# Require a specific Python version, e.g. Python 2.7 or >= 3.4
Expand Down
3 changes: 2 additions & 1 deletion src/plugnparse/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from .decorators import *
from .parserfactory import ParserFactory
from .plugins import PluginScanner

import argcomplete

def scan_and_run(package_name, base_parser=None, use_dict=True, use_kwargs=True):
return run(
Expand All @@ -30,6 +30,7 @@ def scan(package_name, base_parser=None):

def run(factory, use_dict=True, use_kwargs=True):
parser = factory.make_parser()
argcomplete.autocomplete(parser)
ns, _func = parser.parse_args()
ns = vars(ns) if use_dict or use_kwargs else ns
if use_kwargs:
Expand Down