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

Open
benoliver999 opened this Issue Jan 1, 2015 · 16 comments

Comments

Projects
None yet
8 participants
@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

This comment has been minimized.

Show comment
Hide comment
@zanchey

zanchey Jan 23, 2015

Member

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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@zanchey

zanchey Jan 23, 2015

Member

Fixed - thanks!

Member

zanchey commented Jan 23, 2015

Fixed - thanks!

@ocharles

This comment has been minimized.

Show comment
Hide comment
@ocharles

ocharles 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.

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

This comment has been minimized.

Show comment
Hide comment
@zanchey

zanchey Dec 4, 2015

Member

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

Member

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

This comment has been minimized.

Show comment
Hide comment
@faho

faho Dec 4, 2015

Member

@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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@nh2

nh2 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.

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

This comment has been minimized.

Show comment
Hide comment
@faho

faho Mar 17, 2016

Member

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

Member

faho commented Mar 17, 2016

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

@nh2

This comment has been minimized.

Show comment
Hide comment
@nh2

nh2 Mar 17, 2016

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

nh2 commented Mar 17, 2016

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

@faho

This comment has been minimized.

Show comment
Hide comment
@faho

faho Mar 18, 2016

Member

@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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@devster31

devster31 Dec 15, 2017

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

devster31 commented Dec 15, 2017

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

@faho

This comment has been minimized.

Show comment
Hide comment
@faho

faho Dec 16, 2017

Member

@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

Member

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

This comment has been minimized.

Show comment
Hide comment
@devster31

devster31 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.

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

This comment has been minimized.

Show comment
Hide comment
@faho

faho Jan 6, 2018

Member

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?

Member

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

This comment has been minimized.

Show comment
Hide comment
@devster31

devster31 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]

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

This comment has been minimized.

Show comment
Hide comment
@faho

faho Jan 6, 2018

Member

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

Member

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

This comment has been minimized.

Show comment
Hide comment
@devster31

devster31 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

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment