AcademySoftwareFoundation / rez

An integrated package configuration, build and deployment system for software
https://rez.readthedocs.io
Apache License 2.0
949 stars 339 forks source link

Zsh autocompletion doesn't work : COMP_LINE and COMP_POINT are empty #1028

Open johhnry opened 3 years ago

johhnry commented 3 years ago

Hi,

I just installed rez 2.72.0 (7f760bf) on a Pop!_OS 20.04 computer (Python 3.8.6) and I have a zsh shell with the latest Oh My Zsh installed.

Steps to reproduce

I installed rez successfully with :

git clone https://github.com/nerdvegas/rez
cd rez
python ./install.py

Then added the paths to my .zshrc file :

# Rez
export PATH="/opt/rez/bin/rez:$PATH"
source /opt/rez/completion/complete.zsh

Now when I type rez env and press Tab, this is the error message :

$ rez env …Traceback (most recent call last):
  File "/opt/rez/bin/rez/_rez-complete", line 8, in <module>
    sys.exit(run_rez_complete())
  File "/opt/rez/lib/python3.8/site-packages/rez/cli/_entry_points.py", line 80, in run_rez_complete
    return run("complete")
  File "/opt/rez/lib/python3.8/site-packages/rez/cli/_main.py", line 170, in run
    returncode = run_cmd()
  File "/opt/rez/lib/python3.8/site-packages/rez/cli/_main.py", line 162, in run_cmd
    return func(opts, opts.parser, extra_arg_groups)
  File "/opt/rez/lib/python3.8/site-packages/rez/cli/complete.py", line 29, in command
    last_word = comp_line.split()[-1]
IndexError: list index out of range

Source of the issue

I've looked at the problematic line and it's caused because the COMP_LINE and COMP_POINT environment variables are empty strings :

# rez/lib/python3.8/site-packages/rez/cli/complete.py

# get comp info from environment variables
comp_line = os.getenv("COMP_LINE", "")
comp_point = os.getenv("COMP_POINT", "")

# ...

last_word = comp_line.split()[-1]

However this is working by setting manually the variables :

$ COMP_LINE="rez " _rez-complete
bind build config context cp depends diff env gui help interpret memcache pip pkg-cache plugins python release search selftest status suite test view yaml2py

Also I tried changing the complete function in complete.zsh file to this :

# rez/completion/complete.zsh

_rez_complete_fn()
{
    if [ -z "$COMP_LINE" ]; then echo "COMP_LINE is empty"; fi
    if [ -z "$COMP_POINT" ]; then echo "COMP_POINT is empty"; fi

    COMPREPLY=($(COMP_LINE=${COMP_LINE} COMP_POINT=${COMP_POINT} _rez-complete))
}

And it gives me this when pressing TAB :

COMP_LINE is empty
COMP_POINT is empty

So what is going on here?

zachlewis commented 3 years ago

Seems related to #1021 at first glance...

johhnry commented 3 years ago

Thanks for the answer.

In which way is it related to python 3 compared to python 2? And I just saw that it's not only related to Zsh but Bash too...

zachlewis commented 3 years ago

To be honest, I don't really remember much about #1021 -- the commit is from last August, which may as well be a decade ago... :]

In your traceback, I noticed you installed rez with python-3.8; and my PR specifically addresses an issue where comp_line and comp_point could either be string objects or a byte string objects. In python-2, both types have a decode attribute; but in python-3, only byte objects do; so python-3 has trouble with a line like:

comp_line.decode(sys_encoding)

I haven't really grokked the code beyond that, so I'm not sure what's specifically going on in zsh vs bash.

zachlewis commented 3 years ago

@johhnry, is this issue still occurring for you in the latest rez release?

johhnry commented 3 years ago

Hi @zachlewis ,

I reinstalled Rez 2.77.0 and it still doesn't work :cry: :

rez en…Traceback (most recent call last):                                    josephhenry@pop-os
  File "/opt/rez/bin/rez/_rez-complete", line 8, in <module>
    sys.exit(run_rez_complete())
  File "/opt/rez/lib/python3.8/site-packages/rez/cli/_entry_points.py", line 80, in run_rez_complete
    return run("complete")
  File "/opt/rez/lib/python3.8/site-packages/rez/cli/_main.py", line 170, in run
    returncode = run_cmd()
  File "/opt/rez/lib/python3.8/site-packages/rez/cli/_main.py", line 162, in run_cmd
    return func(opts, opts.parser, extra_arg_groups)
  File "/opt/rez/lib/python3.8/site-packages/rez/cli/complete.py", line 29, in command
    last_word = comp_line.split()[-1]
johhnry commented 3 years ago

Hi again,

I installed Rez 2.80.0 on a Centos 8 with Python 3.9 and it still doesn't work !

rez-bind Traceback (most recent call last):
  File "/home/josephhenry/rez/bin/rez/_rez-complete", line 8, in <module>
    sys.exit(run_rez_complete())
  File "/home/josephhenry/rez/lib/python3.9/site-packages/rez/cli/_entry_points.py", line 80, in run_rez_complete
    return run("complete")
  File "/home/josephhenry/rez/lib/python3.9/site-packages/rez/cli/_main.py", line 170, in run
    returncode = run_cmd()
  File "/home/josephhenry/rez/lib/python3.9/site-packages/rez/cli/_main.py", line 162, in run_cmd
    return func(opts, opts.parser, extra_arg_groups)
  File "/home/josephhenry/rez/lib/python3.9/site-packages/rez/cli/complete.py", line 29, in command
    last_word = comp_line.split()[-1]
IndexError: list index out of range
maxnbk commented 2 years ago

in an msys2 shell, I installed zsh, invoke zsh, and using default zsh config, installed rez and run rez-env, and I do not get any reproduction of the above stack trace. (python-3.7). Can I have the minimal .zshrc which could reproduce this (ideally without anything specific to your user or host)?

johhnry commented 1 year ago

Hi @maxnbk,

It's been a long time, but the error still happens on Rez v2.112.0

Here is a reproducible environment with Docker:

# Dockerfile

FROM alpine:latest

WORKDIR /home
RUN apk add --no-cache zsh python3 py3-pip git
RUN git clone --branch master --depth 1 https://github.com/AcademySoftwareFoundation/rez.git
WORKDIR /home/rez
RUN python install.py

ENV PATH="$PATH:/opt/rez/bin/rez"
RUN echo "source /opt/rez/completion/complete.zsh" > ~/.zshrc

ENTRYPOINT [ "/bin/zsh" ]

Then run it:

$ docker build -t rez-zsh . && docker run -it --rm rez-zsh
(rez-zsh) $ rez --version
Rez 2.112.0 from /opt/rez/lib/python3.10/site-packages/rez (python 3.10)
(rez-zsh) $ rez <TAB> Traceback (most recent call last):
  File "/opt/rez/bin/rez/_rez-complete", line 8, in <module>
    sys.exit(run_rez_complete())
  File "/opt/rez/lib/python3.10/site-packages/rez/cli/_entry_points.py", line 85, in run_rez_complete
    return run("complete")
  File "/opt/rez/lib/python3.10/site-packages/rez/cli/_main.py", line 191, in run
    returncode = run_cmd()
  File "/opt/rez/lib/python3.10/site-packages/rez/cli/_main.py", line 183, in run_cmd
    return func(opts, opts.parser, extra_arg_groups)
  File "/opt/rez/lib/python3.10/site-packages/rez/cli/complete.py", line 33, in command
    last_word = comp_line.split()[-1]
IndexError: list index out of range
dexterp commented 1 year ago

COMP_LINE and COMP_POINT are variables set by the bash shell, not the zsh shell & is only for bash completion not zsh. I'm looking for similar ways to set environment variables for a command I'm working on, but not having much luck.

dexterp commented 1 year ago

Actually looking at AWS documentation, zsh has substitute shell functions for the ones in bash that handle completion. https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-completion.html It would seem it is a matter of loading these functions.

autoload bashcompinit && bashcompinit
autoload -Uz compinit && compinit
# For AWS completion, your program "res" would have something similar.
complete -C '/usr/local/bin/aws_completer' aws