Shell – What’s the magic that allows me to tab-complete remote files as I type an scp command

autocompleteshellzsh

Presumably this is a feature provided by some plugin I have enabled in my oh-my-zsh setup (I have been using zsh for many years now).

I noticed ever since I added my public key to the server (now I can SSH to the server without entering a password), when I compose a scp command in my shell I am actually able to tab-complete remote file paths!

e.g.

$ diff <(scp Remoteuser@remote.domain.net:/var/www/html/

I hit tab and it just works! (as for what i am trying to accomplish with the command itself, I am going to use scp to "copy" to stdout, and feed that as a file to diff. This way I can see the exact changes I deploy to the server prior to running rsync)

I'm curious about what are the pieces that make this work so well. Is it something built into scp that was integrated with z shell? Or something else?

Best Answer

Oooh, I found an explanation.

To quote the relevant part:

The zsh shell comes with (more than one) great feature(s), such as remote tabcompletion. If you for example want to copy a file over scp, simply hit tab at any part of the filename on the remote host. zsh is able to establish an ssh session on the background, and fetch the related information for you, so you can tabcomplete trough the remote files.

The post goes on to show some zstyle declarations that achieve the completion, but I would strongly suggest using a zsh package such as the aforementioned oh-my-zsh to get this stuff maintained by the OSS community for you.

Something seemingly relevant, as seen on my system in my .oh-my-zsh dir:

$ ack scp 
plugins/common-aliases/common-aliases.plugin.zsh
85:zstyle -e ':completion:*:(ssh|scp|sftp|rsh|rsync):hosts' hosts 'reply=(${=${${(f)"$(cat {/etc/ssh_,~/.ssh/known_}hosts(|2)(N) /dev/null)"}%%
[# ]*}//,/ })'

<...>
Related Question