Emacs: Triggering rsync from dired
If you are a heavy Emacs
user as me, you will have tried to move files
between different machines using TRAMP
. But this approach is not nice
for large files. TRAMP
is very slow for large files and it will block
Emacs
during the file transfer.
Although dired-rsync could help with that, I decided to write my own solution, as this is a great usecase for the dwim-shell-command package I am testing these days.
And it turned out that the solution was as easy as this:
(defun mono/dwim-rsync (output) "Use rsync to move selected files to OUTPUT." (interactive "D") (dwim-shell-command-on-marked-files (format "Moving selected files to %s" output) ;; we need to convert TRAMP ssh syntax (e.g. /ssh:myserver:/home) ;; to rsync syntax (e.g. myserver:/home). For the output file ;; it's easy, but for input files we need to do it in the command, ;; that is where '<<*>>' is expanded. (let ((clean-output (replace-regexp-in-string "\/ssh:" "" output)) (clean-files-cmd "echo <<*>> | sed 's/\\/ssh://g'")) (format "%s | xargs -i rsync -aP {} %s" clean-files-cmd clean-output)) :utils "rsync"))
It could have been a one-liner but I had to add some additional logic
to transform TRAMP
paths into valid rsync
ones.
Now, I just need to select some files in dired
and run
mono/dwim-rsync
. This will let me specify in the minibuffer any path I
want (local or remote, using ssh
), and rsync
will be used to copy the
files. Bye, Filezilla
!