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

bug: -F breaks tab completion in zsh #1054

Open
markplotnick opened this issue Jul 12, 2024 · 9 comments
Open

bug: -F breaks tab completion in zsh #1054

markplotnick opened this issue Jul 12, 2024 · 9 comments
Labels
errors Something isn't working good first issue Good for newcomers

Comments

@markplotnick
Copy link

  • The version of eza being used: v0.18.18
  • The command-line arguments you are using: eza -F
  • Your shell and terminal: zsh iterm2
  • Your operating system and hardware platform: macbook MacOS 14.5

Awkward to not be able to use tab completion but discovered that it was the '-F' argument.
I had this set in the aliased version of eza I used.

An easy workaround is to use '--classify=auto' instead of '-F' which works for me since I use an aliased variant of eza but for one-off invocations of eza, that is a hand full to write instead of just -F

@markplotnick markplotnick added the errors Something isn't working label Jul 12, 2024
@cafkafk
Copy link
Member

cafkafk commented Jul 15, 2024

for anyone feeling inspired to tackle this, a starting point for this is it could be caused by something in https://github.com/eza-community/eza/blob/main/completions/zsh/_eza causing trouble.

personally I have no idea how zsh completions work 🤷‍♀️

@cafkafk cafkafk added the good first issue Good for newcomers label Jul 15, 2024
@sellithy
Copy link

sellithy commented Jul 16, 2024

Have exact same setup and can't reproduce this. The completion script looks ok to me too.

Here's how I'd test this more from your side:

  1. Open a new clean iTerm window (no Tmux no nothing else)
  2. Run exec zsh --no-rcs
  3. Run autoload -Uz compinit && compinit - minimal for the completion system to work (I think)
  4. Type eza -F (note the space after the 'F') then press tab. Should give you the four options

If this does work then this is not an issue related to eza. Happy to help (here or somewhere else) though
If this does not work then share the zsh --version and maybe that'll help triage?

Follow up

I'm not an expert in zsh completion but I know enough to make an educated guess but take what I'm saying with a grain of salt.
Note spaces in all lines below. <tab> is pressing the tab key

eza -F= <tab> behaves differently than eza --classify= <tab>.
I think what's happening here is that, in the first one, _arguments thinks you're passing two single-letter options to eza (-F and -=) and in the second, _arguments thinks you're passing one multi-letter option

@markplotnick
Copy link
Author

I did the above.
If I try
eza -F
and hit tab, I see the following as possible completions:
always auto automatic never
which seem to be the values for the "--classify" switch.

If I do the same for ls -F
I would see the possible file name completions in the current directory, which is what I expected for eza -F.

So, from my home directory, I have 4 'D' file/directories.
ls -F D {tab}
results in
Desktop/ Documents/ Downloads/ Dropbox/
but
eza -F D {tab}
results in {bell} because there is no completion match.

My expectation is that eza -F would be work-a-like to ls -F, of course, I am not working on the tool and respect that the eza developers implement/configure a different behavior but in that case, it would be helpful if the eza help/documentation noted the difference from ls behavior.

@cafkafk
Copy link
Member

cafkafk commented Jul 17, 2024

My expectation is that eza -F would be work-a-like to ls -F

fwiw on fish shell, if I hit tab on eza -F I get file names. Also, when I use zsh this also works like that...

Could you try on the latest version of eza instead of 0.18.18?

@sellithy
Copy link

sellithy commented Jul 17, 2024

I don't think the eza version would make much of a difference. The difference in the completion behavior is correctly reflecting a difference between how ls and eza behaves. IMO, the completions should always follow the behavior of eza as it's often hard to mirror a specific ls's version of completion (check your zsh's version of _ls and see how many different cases they need to check for).

I think the important question here is if eza's maintainers want to follow ls's behavior exactly or not. I suspect the answer is no and I'd recommend that the answer should be no. Example of how the behavior differs below.

Example

Let's say I have a directory with (very weirdly named) subdirectories as such:

.
├── always
│  └── inside_always_dir
├── auto
│  └── inside_auto_dir
└── foo
   └── inside_foo_dir

There is a behavioral difference between ls -F always and eza -F always. Precisely,
ls -F always will output

inside_always_dir

but eza -F always will output

always/  auto/  foo/

Note that ls -F foo and eza -F foo behave the same. Which means eza -F foo and eza -F always behave differently!

Summary

  • The difference in the completion behavior correctly reflects difference in actual behavior
  • There are differences between how eza and ls behave when handling-F
  • There's inconsistent internal behavior (internal to eza that is) when passing the -F flag depending on whether or not a directory with a name that -F accepts exists or not

IMO, the third point is scary but scary mainly if someone decides to script using eza (which they shouldn't do because ls exists). I'm not a maintainer (although I might soon try to contribute) but I think to fix it, I'd make -F/--classify not take any arguments and introduce another option called something like --classify-when, but that obviously breaks aliases and stuff (will break mine lol) so I don't know how desirable that is either.
The other option is to make -F/--classify always take an argument, which will also break aliases but (I'm guessing) a smaller subset of them

@cafkafk
Copy link
Member

cafkafk commented Jul 17, 2024

I don't think the eza version would make much of a difference.

I mean, sure, but consider e.g. https://github.com/eza-community/eza/releases/tag/v0.18.21, it does have an effect

@markplotnick
Copy link
Author

My expectation is that eza -F would be work-a-like to ls -F

fwiw on fish shell, if I hit tab on eza -F I get file names. Also, when I use zsh this also works like that...

Could you try on the latest version of eza instead of 0.18.18?

Same results for v0.18.23

@thbe
Copy link

thbe commented Sep 3, 2024

The problem is the way how oh-my-zsh and others alias ls. This is the example from oh-my-zsh common-aliases plugin for the la alias:

ls -lAFh

Works fine with ls but not with eza as it takes h as a parameter for F:

eza -lAFh
eza: Flag -F cannot take a value

The solution could be either to create a PR, for example, for oh-my-zsh and the other alias sets to adjust the order of the parameters for the ls aliases, for example into ls -lhAF which works with eza as well. The second option could be to change the way how eza reads the parameters when F is part of a single dash-initiated parameter list. I would vote for the second option as eza should able to mimic the complete ls parameter set and additionally, the first option would end up in a lot of PRs as many projects use such kind of alias.

@cgahr
Copy link

cgahr commented Sep 3, 2024

I have the same issue with version 0.19.1. I'm also using zsh with the zsh-eza plugin https://github.com/z-shell/zsh-eza

It defines the following aliases

  eza_params=(
    '--git' '--icons' '--group' '--group-directories-first'
    '--time-style=long-iso' '--color-scale=all'
  )

  [[ ! -z $_EZA_PARAMS ]] && eza_params=($_EZA_PARAMS)

  alias ls='eza $eza_params'
  alias l='eza --git-ignore $eza_params'
  alias ll='eza --all --header --long $eza_params'
  alias llm='eza --all --header --long --sort=modified $eza_params'
  alias la='eza -lbhHigUmuSa'
  alias lx='eza -lbhHigUmuSa@'
  alias lt='eza --tree $eza_params'
  alias tree='eza --tree $eza_params'

Of these aliases, only ls does not complete correctly, and instead shows

ls <TAB>
always auto automatic never

If I can help, let me know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
errors Something isn't working good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

5 participants