I created a script supposed to use python to autocomplete Python commands. The full code is available here, however, I can give you an example. For instance, let's consider:
command, the command I want to give completion to (it does not have to actually exist).script.py, the auto completion script.
import os, shlex
def complete(current_word, full_line):
split = shlex.split(full_line)
prefixes = ("test", "test-中文", 'test-한글')
items = list(i + "-level-" + current_word for i in prefixes)
word = "" if len(split) - 1 < int(current_word) else split[int(current_word)]
return list(i for i in items if i.startswith(word))
if __name__ == "__main__":
os.sys.stdout.write(" ".join(complete(
*os.sys.argv.__getitem__(slice(2, None)))))
os.sys.stdout.flush()
The following script can be executed directly into the shell, or added in the .bashrc to keep the changes persistent.
__complete_command() {
COMPREPLY=($(python3 script.py complete $COMP_CWORD "${COMP_LINE}"));
};
complete -F __complete_command command
Tested on Ubuntu 18.04 with python 3.8. If you want, you can type the following in a new console
cd $(mktemp -d)
__complete_command() {
COMPREPLY=($(python3 script.py complete $COMP_CWORD "${COMP_LINE}"));
};
complete -F __complete_command command
echo '
import os, shlex
def complete(current_word, full_line):
split = shlex.split(full_line)
prefixes = ("test", "test-中文", "test-한글")
items = list(i + "-level-" + current_word for i in prefixes)
word = "" if len(split) - 1 < int(current_word) else split[int(current_word)]
return list(i for i in items if i.startswith(word))
if __name__ == "__main__":
os.sys.stdout.write(" ".join(complete(
*os.sys.argv.__getitem__(slice(2, None)))))
os.sys.stdout.flush()' > script.py
Is it the most efficient way to do this?
completeis in the Bash man page, under "Builtin Commands". On some systems there's a separatebash-builtinsman page for convenience. \$\endgroup\$