Commits (3)
This diff is collapsed.
- clean-up handling of finished tasks
- rationalise the quoting of arguments
- automatically set mode-line-process with status
- added LICENSE file to repo
- first release to MELPA
......@@ -20,12 +20,14 @@ command to your prefered ~dired~ binding.
A variable called ~dired-rsync-modeline-status~ is provided for mode
lines that will report the number of active rsync operations in
progress. However by default that value is also set in
~mode-line-process~ which is a common place for things to report
inferior process status.
* Technical Notes
While you can use rsync to copy files locally the main use case is
copying files too/from a remote system. The rsync tool is always run
copying files to/from a remote system. The rsync tool is always run
locally as rsync needs working SSH authentication to work. If you can
access a remote machine via tramp/ssh without having to enter a
password (because ssh-agent is working) then rsync should work fine.
dired-rsync (0.3-1) unstable; urgency=medium
* New upstream version 0.3
-- Lev Lamberov <dogsleg@debian.org> Sat, 05 May 2018 14:06:34 +0500
dired-rsync (0.2-1) unstable; urgency=medium
* Initial release (Closes: #896770)
......@@ -4,7 +4,7 @@
;; Author: Alex Bennée <alex@bennee.com>
;; Maintainer: Alex Bennée <alex@bennee.com>
;; Version: 0.2
;; Version: 0.3
;; Package-Requires: ((s "1.12.0") (dash "2.0.0") (emacs "24"))
;; Homepage: https://github.com/stsquad/dired-rsync
......@@ -58,7 +58,7 @@
(defvar dired-rsync-modeline-status
"A string defining current dired-rsync status, useful for modelines.")
"A string defining current `dired-rsync' status, useful for modelines.")
;; Helpers
......@@ -67,25 +67,27 @@
(or (string-prefix-p "/scp:" file-or-path)
(string-prefix-p "/ssh:" file-or-path)))
(defun dired-rsync--convert-from-tramp (file-or-path)
(defun dired-rsync--quote-and-maybe-convert-from-tramp (file-or-path)
"Reformat a tramp FILE-OR-PATH to one usable for rsync."
(if (dired-rsync--is-remote-tramp-p file-or-path)
;; tramp format is /method:remote:path
(let ((parts (s-split ":" file-or-path)))
(format "%s:\"%s\"" (nth 1 parts) (shell-quote-argument (nth 2 parts))))
(shell-quote-argument file-or-path)))
;; Update status with count/speed
(defun dired-rsync-calculate-modeline ()
"Display number of jobs and calculate throughput."
(defun dired-rsync--update-modeline ()
"Update the number of current jobs."
(let ((jobs 0)
(mapc (lambda(job)
(when (process-live-p (car job))
(setq jobs (1+ jobs)))) dired-rsync-jobs)
(if (> jobs 0)
(format "R:%d %s" jobs (if (= jobs 1) "job" "jobs"))
(format ""))))
(setq mode-line-process
(setq dired-rsync-modeline-status
(if (> jobs 0)
(format " R:%d " jobs)
;; Running rsync: We need to take care of a couple of things here. We
......@@ -96,17 +98,22 @@
(defun dired-rsync--sentinel(proc desc)
"Process sentinel for rsync processes. This gets called whenever the
inferior process changes state."
"Process sentinel for rsync processes.
This gets called whenever the inferior `PROC' changes state as
described by `DESC'."
(let ((details (cdr (assoc proc dired-rsync-jobs))))
(if (s-starts-with-p "finished" desc)
(with-current-buffer (plist-get details ':dired-buffer)
(message "finished: %s" details))
(message "%s: %s" proc desc))
(setq dired-rsync-jobs
(assq-delete-all proc dired-rsync-jobs)))
(setq dired-rsync-modeline-status (dired-rsync-calculate-modeline)))
(when (s-starts-with-p "finished" desc)
;; clean-up finished tasks
(let ((proc-buf (process-buffer proc))
(dired-buf (plist-get details ':dired-buffer)))
(with-current-buffer dired-buf
(kill-buffer proc-buf)))
;; clean-up data left from dead/finished processes
(when (not (process-live-p proc))
(setq dired-rsync-jobs
(assq-delete-all proc dired-rsync-jobs))))
(defun dired-rsync--do-run (command details)
"Run rsync COMMAND in a unique buffer, saving DETAILS in job list."
......@@ -114,7 +121,7 @@ inferior process changes state."
(proc (start-process-shell-command "*rsync*" buf command)))
(setq dired-rsync-jobs (add-to-list 'dired-rsync-jobs (cons proc details)))
(set-process-sentinel proc #'dired-rsync--sentinel)
(setq dired-rsync-modeline-status (dired-rsync-calculate-modeline))))
(defun dired-rsync (dest)
......@@ -127,28 +134,20 @@ ssh/scp tramp connections."
(list (read-file-name "rsync to:" (dired-dwim-target-directory))))
(let ((src-files (dired-get-marked-files nil current-prefix-arg))
;; check if the source is remote or destination is and munge
;; tramp style to rsync style appropriately.
(if (dired-rsync--is-remote-tramp-p default-directory)
(setq src-files (-map 'dired-rsync--convert-from-tramp src-files)
source (nth 1 (s-split ":" default-directory)))
(when (dired-rsync--is-remote-tramp-p dest)
(setq dest (dired-rsync--convert-from-tramp dest)
source "local")))
(let ((src-files (-map
(dired-get-marked-files nil current-prefix-arg)))
(final-dest (dired-rsync--quote-and-maybe-convert-from-tramp dest)))
;; now build the rsync command
(let ((cmd (s-join " "
(list dired-rsync-command
src-files dest)))))
(dired-rsync--do-run cmd
(list :marked-files src-files
:dest dest
:source source
:dired-buffer (buffer-name))))))
(provide 'dired-rsync)