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

ssh tab completion with host name #46

Closed
protist opened this issue Apr 22, 2016 · 22 comments
Closed

ssh tab completion with host name #46

protist opened this issue Apr 22, 2016 · 22 comments
Labels
bug Something isn't working

Comments

@protist
Copy link

protist commented Apr 22, 2016

For bug reports, please provide the following information:

  • Zim commit ref: 6cb9d54
  • Zsh version: 5.2
  • $(uname -mosr): Linux 4.5.1-1-ARCH x86_64 GNU/Linux

Arch Linux, zim installed via AUR PKGBUILD (zsh-zim-git)

Description

prezto offers tab completion of ssh with host names. e.g. if there are hosts defined in ~/.ssh/config, you can tab complete with these. This seems to be missing in zim.

Steps to reproduce

Type in $ ssh f<tab>. Expect host foo to be offered as a completion.

@Eriner
Copy link
Member

Eriner commented Apr 22, 2016

I do not have this problem. I can tab complete hosts. Please link your .zimrc.

@Eriner Eriner added the question Further information is requested label Apr 22, 2016
@protist
Copy link
Author

protist commented Apr 26, 2016

I've pared down my ~/.zshrc, ~/.zimrc, and other files to exactly the same as those shipped by zim from the templates directory. I still hit this issue, but I may have described it poorly, so I will clarify.

In ~/.ssh/config, I have several entries such as the following.

Host foo
Hostname bar.com
IdentityFile ~/.ssh/protist@foo
User protist

I can type in ssh <tab>, and tab completion will offer a list of remote host names, including bar.com. However, completing to ssh bar.com will not use settings in ~/.ssh/config. Instead, one should normally connect with ssh foo. This expands the Host using the ssh config, using the correct identity file, port, etc.

Using zsh with zim will not tab complete to these Hosts. OTOH, prezto does offer to complete these Hosts.

@Eriner
Copy link
Member

Eriner commented Apr 26, 2016

so, it tab completes the hostnames rather than the hosts?

@protist
Copy link
Author

protist commented Apr 26, 2016

Yes. From memory, prezto offers to complete both.

@Eriner
Copy link
Member

Eriner commented Apr 26, 2016

mine tab completes both.

Completion of remote hosts in menu:
"ssh "

 -- remote host name --
arch.localdomain               github.com                     localhost
arch                           localhost.localdomain          aur.archlinux.org

Tab completion of Host from .ssh/config
"ssh gi"

ssh gitlab

@protist
Copy link
Author

protist commented Apr 26, 2016

With zim:

$ ssh a<tab>
 -- remote host name --
aur.archlinux.org
 -- login name --
avahi

With prezto installed (on top):

$ ssh a<tab>
 -- domain --
aur.archlinux.org
 -- host --
aur

I'm not really sure why the login name disappeared, but it shouldn't have really been in there in the first place.

@protist
Copy link
Author

protist commented May 8, 2016

Since I've pared the config files down to your repository versions, it's odd that I see different behaviour to you. Would it be possible for you to post your personal files, so I can try with them?

@Eriner
Copy link
Member

Eriner commented May 8, 2016

My personal files are basically the same as the template files. I haven't touched anything with ssh other than enabling and using the ssh agent feature.

@protist
Copy link
Author

protist commented May 10, 2016

FWIW I tried enabling the ssh module, but that didn't make any difference. I followed instructions here to get it working, but I've no idea why it's not working in vanilla zim.

@protist
Copy link
Author

protist commented May 16, 2016

Just a note for the code I'm currently using. It's sourced from the link above, but I've removed known_hosts, and added tab-completion for rsync.

h=()
if [[ -r ~/.ssh/config ]]; then
  h=($h ${${${(@M)${(f)"$(cat ~/.ssh/config)"}:#Host *}#Host }:#*[*?]*})
fi
if [[ $#h -gt 0 ]]; then
  zstyle ':completion:*:ssh:*' hosts $h
  zstyle ':completion:*:slogin:*' hosts $h
  zstyle ':completion:*:rsync:*' hosts $h
fi

@PatTheMav
Copy link

While I haven't found time to find a fix for this issue I can confirm the reported behavior.

Tab completion delivers known_hosts entries only, but not HOST entries from the SSH config (which contains the necessary combination of hostname, username and identity file).

@Eriner
Copy link
Member

Eriner commented Jul 5, 2016

If someone wants to follow this up, this seems like a good place to start: http://www.zsh.org/mla/workers/2010/msg00535.html

@Eriner Eriner added bug Something isn't working on hold and removed question Further information is requested labels Sep 27, 2016
@ratheesh
Copy link

I copied following lines from prezto (modules/completion/init.zsh - L95-99)

zstyle -e ':completion:*:hosts' hosts 'reply=( ${=${=${=${${(f)"$(cat {/etc/ssh_,~/.ssh/known_}hosts(|2)(N) 2>/dev/null)"}%%[#| ]*}//\]:[0-9]*/ }//,/ }//\[/ } ${=${(f)"$(cat /etc/hosts(|)(N) <<(ypcat hosts 2>/dev/null))"}%%\#*} ${=${${${${(@M)${(f)"$(cat ~/.ssh/config 2>/dev/null)"}:#Host *}#Host }:#*\**}:#*\?*}} )'

After including this, ssh hostcompletion from ~/.ssh/config works fine for me.

@PatTheMav
Copy link

TBH, I dunno if @Eriner changed anything recently, but for some time now tab autocompletes to my aliases, so I figured that it was fixed somehow quite a while ago..

@protist
Copy link
Author

protist commented Nov 15, 2016

@PatTheMav FWIW it's still broken for me, once I take out my fix from ~/.zshrc.

@neeklamy
Copy link

  • Zim commit ref: dca1803
  • Zsh version: zsh 5.3.1 (x86_64-apple-darwin15.6.0)
  • Darwin 15.6.0 x86_64 (10.11.6)

I haven’t made any customisations to Zim.

I do have ssh tab completion, but:

  1. If I just ssh <tab> the servers I’ve set up in ~/.ssh/config don’t appear. If I try ssh di<tab>, my DigitalOcean entry from config completes just fine.
  2. If an entry in ~/.ssh/known_hosts includes the same name (it ignores any TLDs and capitalisation), then it takes precedence over any related entry in config. So for example:
# known_hosts
digitalocean.com,12.345.67.89 ecdsa-sha2-nistp256 […]

# config
Host DigitalOcean
	HostName 12.345.67.89
	IdentityFile ~/.ssh/id_rsa

Hitting ssh di<tab> will always complete to ssh digitalocean.com On this second point, the fix is easy enough, just remove any domains from known_hosts.

The first issue remains though, recalling a list of configured domains from tab completion doesn’t work.

The code that @protist links to (comment) fixes it though.

@Eriner
Copy link
Member

Eriner commented Sep 18, 2017

Might be looking into seeing what can be learned from prezto's approach, as well as the issues and resolutions for omz: ohmyzsh/ohmyzsh#4345

@Eriner
Copy link
Member

Eriner commented Sep 17, 2018

Hi friends, it wouldn't let me tag some of you in the PR, but I believe #294 will solve this problem for everyone by forcing the completion to fallback to the _ssh_hosts builtin ~/.ssh/config parsing. The only downside here is that the matching isn't ideal and it essentially matches by host* and thus IPs are also included in the initial list. Not a big enough deal to prevent PR imo.

@Eriner
Copy link
Member

Eriner commented Sep 17, 2018

@protist, @PatTheMav, does that PR resolve the issue to your satisfaction?

@lnicola
Copy link
Contributor

lnicola commented Sep 17, 2018

@Eriner, for whatever reason, ~/.ssh/config completion is now working for me, even without #294.

@protist
Copy link
Author

protist commented Sep 17, 2018

Thanks @Eriner! I compared the output to my earlier comment, and the host is now offered as an alternative! (To remind us, it's aur in the suggestions below.)

$ ssh a<tab>
-- remote host name --
aur                aur.archlinux.org
-- login name --
avahi

However, TBH I find this an inferior fix than what I have in ~/.zshrc, because it suggests things that I'd prefer not in there, i.e. the hostname aur.archlinux.org, and the login name avahi. In my current code below, it only suggests the host itself.

# ssh tab completion
h=()
if [[ -r ~/.ssh/config ]]; then
  h=($h ${${${(@M)${(f)"$(cat ~/.ssh/config)"}:#Host *}#Host }:#*[*?]*})
fi
if [[ $#h -gt 0 ]]; then
  zstyle ':completion:*:ssh:*' hosts $h
  zstyle ':completion:*:slogin:*' hosts $h
  zstyle ':completion:*:rsync:*' hosts $h
fi
# Prevent autocompletion of user names
zstyle ':completion:*:rsync:*' users
zstyle ':completion:*:ssh:*' users

You can see in my code the part suppressing the login names. I presume there's a way to suppress the plain hostname itself as well. So, long story short, it's definitely better than it was, but I'd probably still need to add code to fit my needs. Thanks again for persisting with this!

@Eriner
Copy link
Member

Eriner commented Sep 17, 2018

@protist Cool. We can add more zstyle configurables later if necessary, but I believe this fixes the core issue and the built-in _ssh_hosts now behaves as expected and parses ~/.ssh/config and not just known_hosts and /etc/hosts.

Just as a short follow-up, you can define the my_hosts function with your filter to add only the Host xyz entries and not the Hostname entries. The fallthrough to the _ssh_hosts will glob anything like host*, as explained in my previous comment.

@Eriner Eriner removed the on hold label Sep 17, 2018
@ericbn ericbn closed this as completed in 2436a6d Sep 27, 2018
ericbn pushed a commit to zimfw/completion that referenced this issue Oct 2, 2018
I think this change results in the _expected_ behavior. Users can always
override this by overriding the zstyle, as that is a benefit of using
zstyles.

Ref: https://www.zsh.org/mla/users/2015/msg00467.html

and `which _ssh_hosts`

Fixes zimfw/zimfw#46. Closes zimfw/zimfw#294.

Copied from zimfw/zimfw@2436a6d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Development

No branches or pull requests

6 participants