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

Rsync does not tab complete directories with spaces #1872

Closed
benoliver999 opened this issue Jan 1, 2015 · 18 comments
Closed

Rsync does not tab complete directories with spaces #1872

benoliver999 opened this issue Jan 1, 2015 · 18 comments
Assignees
Milestone

Comments

@benoliver999
Copy link

@benoliver999 benoliver999 commented Jan 1, 2015

rsync -rP remote:directory<tab> removes the directory altogether and ends up as rsync remote:

Manually entering the file name works fine, as does using a wildcard. The completion works as expected in bash.

scp also works fine with the tab completion.

@zanchey
Copy link
Member

@zanchey zanchey commented Jan 23, 2015

This is because of the awk pipeline using $NF instead of printing all fields beyond 5. Unfortunately the required text transformation ("add a / on the end if the line starts with d and then drop the first four fields") is impressively difficult with any of the standard text tools.

@zanchey zanchey self-assigned this Jan 23, 2015
@zanchey zanchey added this to the next-minor milestone Jan 23, 2015
@zanchey zanchey closed this in 1ff9aba Jan 23, 2015
@zanchey
Copy link
Member

@zanchey zanchey commented Jan 23, 2015

Fixed - thanks!

@ocharles
Copy link

@ocharles ocharles commented Jul 7, 2015

That doesn't seem to fix it - the tab completion only escapes it on the client side - you need to double escape for rsync. That is to say using the tab completion doesn't actually refer to the correct file.

@ridiculousfish ridiculousfish modified the milestones: fish-future, fish 2.2.0 Jul 7, 2015
@zanchey zanchey reopened this Sep 29, 2015
@zanchey
Copy link
Member

@zanchey zanchey commented Dec 4, 2015

This looks like the perfect candidate for conversion to the built-in string utility - piping through string escape -n a couple times should help.

@faho
Copy link
Member

@faho faho commented Dec 4, 2015

@zanchey: I've got a fix for this, but it's not looking great:

#
# Remote path
#
complete -c rsync -d "Remote path" -n "commandline -ct | string match '*:*'" -a "
(
    #Prepend any user@host:/path information supplied before the remote completion
    commandline -ct | string replace -r '/[^/]*\$' '/'
)(
    #Get the list of remote files from the specified rsync server
    # The string match ensures we only complete remote paths (rsync will error out if given nothing, and stderr is ignored)
    # The string replace removes everything up to and including a time (since rsync will justify its output)
    # The grep -v removes the "." line referring to the directory
    #TODO: Replace the `grep` call with `string`
    rsync --list-only ^/dev/null (commandline -ct | string match -r '.*:(.*/)?') | string replace -r '.*[0-9]{2}:[0-9]{2}:[0-9]{2} ' '' | grep -v '^.\$' | string escape -n
)
"

The grep -v really irks me and I've replaced the regexes with simpler ones - I don't like using regexes I don't understand - so there might be edgecases I don't see.

@nh2
Copy link

@nh2 nh2 commented Mar 17, 2016

Confirming this bug. When I have a target dir my\ dir on the remote side, and start with scp or rsync myfile otherhost:my and press TAB, then:

  • zsh completes correctly to otherhost:my\\\ dir/
  • fish completes incorrectly to otherhost:my\ dir/

and consequently fish copies everything into a new dir called my.

@faho
Copy link
Member

@faho faho commented Mar 17, 2016

@nh2: Can you try my fix (needs fish from git though)?

@nh2
Copy link

@nh2 nh2 commented Mar 17, 2016

@faho how recent git do I need and where does your code go?

@faho
Copy link
Member

@faho faho commented Mar 18, 2016

@nh2: You'll need #2296, so any build from the last couple of months should do, and my code goes into ~/.config/fish/completions/rsync.fish. Best make a copy of the other rsync.fish (in one of the directories $fish_complete_path) there and put the code into the right place.

@devster31
Copy link

@devster31 devster31 commented Dec 15, 2017

@faho I'm using fish, version 2.7.0 on MacOS but I'm still seeing this issue.

@faho
Copy link
Member

@faho faho commented Dec 16, 2017

@devster31: We've never merged the fix, since I couldn't test it. Would you mind checking my fix? You'd have to

  • Copy the rsync completion script to ~/.config/fish/completions (from its other place in $fish_complete_path)

  • Modify the "Remote path" part at the end to match what I did

@devster31
Copy link

@devster31 devster31 commented Jan 5, 2018

I just tried your snippet, the path is correctly escaped, there's a difference vs zsh however.
ZSH:

host.com:data/my\\\ long\\\ folder/

Fish:

host.com:data/my\\\ long\\\ folder█

The big black rectangle is only to show that there's a whitespace there at the end despite the directory being a folder.

@faho
Copy link
Member

@faho faho commented Jan 6, 2018

The big black rectangle is only to show that there's a whitespace there at the end despite the directory being a folder.

That's because fish thinks the token is complete. I'll have to look up how we do it in other completions.

In the meantime, can you try replacing that space with a "/" and pressing tab again?

@devster31
Copy link

@devster31 devster31 commented Jan 6, 2018

Adding a slash doesn't list anymore files, and starting the name doesn't list it either.
ZSH:

host.com:data/my\\\ long\\\ folder/my [press TAB]
host.com:data/my\\\ long\\\ folder/my\\\ file

Fish:

host.com:data/my\\\ long\\\ folder/ [press TAB -> nothing]
host.com:data/my\\\ long\\\ folder/my [press TAB -> nothing]
@faho
Copy link
Member

@faho faho commented Jan 6, 2018

@devster31: What does rsync --list-only host.com:data/my\\\ long\\\ folder/my print? What does it do without the my or /my?

@devster31
Copy link

@devster31 devster31 commented Jan 7, 2018

rsync --list-only host.com:data/my\\\ folder
drwxrwxr-x          4,096 2018/01/07 03:19:51 my folder

rsync --list-only host.com:data/my\\\ folder/
drwxrwxr-x          4,096 2018/01/07 03:19:51 .
-rw-rw-r--              0 2018/01/07 03:19:51 my file

rsync --list-only host.com:data/my\\\ folder/my
rsync: link_stat "/home/user/my folder/my" failed: No such file or directory (2)
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1721) [Receiver=3.1.2]
rsync: [Receiver] write error: Broken pipe (32)

rsync --list-only host.com:data/my\\\ folder/my\*
-rw-rw-r--              0 2018/01/07 03:19:51 my file
@mqudsi mqudsi added the completions label Sep 30, 2018
@2m
Copy link

@2m 2m commented Oct 9, 2018

I have also been bitten by this recently. Anything I could do to help out?

I have noticed that rsync --list-only does the right thing only if the spaces and other escapable symbols are escaped with triple back-slashes like so:

rsync --list-only remote:test/dir\\\ with\\\ spaces\\\ \\\(and\\\)\\\ \\\[other\\\]\\
\ \\\[symbols\\\]/
@devster31
Copy link

@devster31 devster31 commented May 1, 2019

The latest workaround seem to add an extra space at the end of a directory.
Furthermore it seems it stops autocompleting deeper paths after that, so for example:

rsync user@host.com:/my/path/with\\\ spaces # gets a trailing space here
rsync user@host.com:/my/path/with\\\ spaces/file with spaces # completion does not work for this path

I'm running fish version 3.0.2 on Darwin

@krobelus krobelus modified the milestones: fish-future, fish 3.1.0 Jan 13, 2020
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 16, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.