Skip to content

Commit

Permalink
Add shell completion script + entrypoint
Browse files Browse the repository at this point in the history
  • Loading branch information
eelkevdbos committed Dec 7, 2021
1 parent a62ca57 commit 7ec403d
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 2 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ $ judo

You may also choose to include a `.judorc` file in your `$HOME` folder (`~/.judorc`). Commands defined in this file will always be loaded first and will be overwritten if an overlapping command was found.

## Shell completions

To install judo shell completions, execute `judo-completions [--apply] {bash|fish|zsh}` to get instructions on how to install completions for your shell of choice. By including the `--apply` option, the installation instructions will be applied for you.

**Note:** Don't forget to reload your shell session after installation to load the completions.

## Development

To contribute to this library, first checkout the code. Then create a new virtual environment:
Expand Down
29 changes: 29 additions & 0 deletions completions/judo.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
_judo_completion() {
local IFS=$'\n'
local response

response=$(env COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD _JUDO_COMPLETE=bash_complete $1)

for completion in $response; do
IFS=',' read type value <<< "$completion"

if [[ $type == 'dir' ]]; then
COMREPLY=()
compopt -o dirnames
elif [[ $type == 'file' ]]; then
COMREPLY=()
compopt -o default
elif [[ $type == 'plain' ]]; then
COMPREPLY+=($value)
fi
done

return 0
}

_judo_completion_setup() {
complete -o nosort -F _judo_completion judo
}

_judo_completion_setup;

22 changes: 22 additions & 0 deletions completions/judo.fish
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
function _judo_completion;
set -l response;

for value in (env _JUDO_COMPLETE=fish_complete COMP_WORDS=(commandline -cp) COMP_CWORD=(commandline -t) judo);
set response $response $value;
end;

for completion in $response;
set -l metadata (string split "," $completion);

if test $metadata[1] = "dir";
__fish_complete_directories $metadata[2];
else if test $metadata[1] = "file";
__fish_complete_path $metadata[2];
else if test $metadata[1] = "plain";
echo $metadata[2];
end;
end;
end;

complete --no-files --command judo --arguments "(_judo_completion)";

35 changes: 35 additions & 0 deletions completions/judo.zsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#compdef judo

_judo_completion() {
local -a completions
local -a completions_with_descriptions
local -a response
(( ! $+commands[judo] )) && return 1

response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) _JUDO_COMPLETE=zsh_complete judo)}")

for type key descr in ${response}; do
if [[ "$type" == "plain" ]]; then
if [[ "$descr" == "_" ]]; then
completions+=("$key")
else
completions_with_descriptions+=("$key":"$descr")
fi
elif [[ "$type" == "dir" ]]; then
_path_files -/
elif [[ "$type" == "file" ]]; then
_path_files -f
fi
done

if [ -n "$completions_with_descriptions" ]; then
_describe -V unsorted completions_with_descriptions -U
fi

if [ -n "$completions" ]; then
compadd -U -V unsorted -a completions
fi
}

compdef _judo_completion judo;

8 changes: 6 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from setuptools import setup
import os

VERSION = "0.2"
VERSION = "0.3"


def get_long_description():
Expand All @@ -28,9 +28,13 @@ def get_long_description():
license="MIT",
version=VERSION,
packages=setuptools.find_packages("src"),
include_package_data=True,
package_dir={"": "src"},
entry_points={
"console_scripts": ["judo=judoka.cli:hub"]
"console_scripts": [
"judo=judoka.cli:hub",
"judo-completions=judoka.completion:install",
]
},
install_requires=["toml", "click"],
extras_require={"test": ["pytest"]},
Expand Down
3 changes: 3 additions & 0 deletions src/judoka/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
from os.path import dirname, abspath

package_path = abspath(dirname(__file__))
completions_path = dirname(dirname(package_path)) + "/completions"
74 changes: 74 additions & 0 deletions src/judoka/completion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import pathlib
import subprocess
from functools import partial
from shutil import copy

import click

from judoka import completions_path


def rc_installer(rc_file, completion_source):
judoka_homedir = pathlib.Path("~/.judo").expanduser()
judoka_homedir.mkdir(exist_ok=True)

completion_target = copy(
pathlib.Path(completions_path) / completion_source,
judoka_homedir,
)

return f"echo 'source {completion_target}' >> {rc_file}"


def path_installer(install_path, completion_source):
install_path.mkdir(exist_ok=True)
copy(
pathlib.Path(completions_path) / completion_source,
install_path,
)


installers = {
"bash": partial(
rc_installer,
rc_file=pathlib.Path("~/.bashrc").expanduser(),
completion_source="judo.bash",
),
"zsh": partial(
rc_installer,
rc_file=pathlib.Path("~/.zshrc").expanduser(),
completion_source="judo.zsh",
),
"fish": partial(
path_installer,
install_path=pathlib.Path("~/.config/fish/completions/").expanduser(),
completion_source="judo.fish",
),
}


@click.command()
@click.argument("shell", type=click.Choice(["bash", "fish", "zsh"]))
@click.option("--apply/--no-apply", default=False)
def install(shell, apply=False):
installer = installers.get(shell)

if not installer:
click.echo(f"No installer found for shell '{shell}'")
exit(1)

instruction = installer()
if instruction:
if not apply:
click.echo("\nTo complete installation, execute the following command:\n")
click.echo(instruction)
click.echo("\nAlternatively, run with --force to automate installation.\n")
else:
subprocess.run(instruction, shell=True)
click.echo(f"Shell completion was installed for you via: \n{instruction}")
else:
click.echo("Shell completion was installed")


if __name__ == "__main__":
install()

0 comments on commit 7ec403d

Please sign in to comment.