-
Notifications
You must be signed in to change notification settings - Fork 16
/
dired-rsync-transient.el
116 lines (107 loc) · 4.8 KB
/
dired-rsync-transient.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
;;; dired-rsync-transient.el --- Transient command for dired-rsync -*- lexical-binding: t -*-
;;
;; Copyright (C) 2018, 2019, 2020 Alex Bennée
;;
;; Author: Alex Bennée <[email protected]>
;; Maintainer: Alex Bennée <[email protected]>
;; Version: 0.6
;; Package-Requires: ((dired-rsync "0.6") (transient "0.3.0") (emacs "24.4"))
;; Homepage: https://github.com/stsquad/dired-rsync
;;
;; This file is not part of GNU Emacs.
;;
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;
;;; Commentary:
;;
;; This file provides a command `dired-rsync-transient', which allows
;; to alter `dired-rsync-options' temporarily with transient pop-up.
;;
;;; Code:
(require 'dired-rsync)
(require 'transient)
;;;###autoload (autoload 'dired-rsync-transient "dired-rsync-transient" nil t)
(transient-define-prefix dired-rsync-transient ()
"Transient command for `dired-rsync'."
:value '("-a" "-z" "--info=progress2")
["Arguments"
("-a" "archive mode; equals to -rlptgoD" "-a")
("-r" "recurse into directories" "-r")
("-z" "compress file data during the transfer" "-z")
("-c" "skip based on checksum, not mod-time & size" "-c" :level 6)
("-C" "auto-ignore files in the same way CVS does" "-C" :level 6)
("-u" "skip files that are newer on the receiver" "-u" :level 6)
("-m" "prune empty directory chains from file-list" "-m" :level 6)
("=d" "delete extraneous files from dest dirs" "--delete" :level 6)
("=s" "skip files that match in size" "--size-only" :level 6)
("=i" "include files matching PATTERN" "--include="
:multi-value t :reader dired-rsync-transient--read-multiple
:prompt "include (e.g. ‘*.pdf’ or ‘*.org, *.el’): " :level 6)
("=e" "exclude files matching PATTERN" "--exclude="
:multi-value t :reader dired-rsync-transient--read-multiple
:prompt "exclude (e.g. ‘.git’ or ‘*.bin, *.elc’): ")
("=o" "other rsync options" "--options="
:prompt "Other options (e.g. -v -n): ")]
["Information output"
("-i" "output a change-summary for all updates" "-i")
("-h" "output numbers in a human-readable format" "-h")
("=I" "per-file (1) or total transfer (2) progress" "--info="
:choices ("progress1" "progress2"))]
["Directory"
("d" "Destination" "--dest="
:init-value (lambda (o) (oset o value (dired-dwim-target-directory)))
:reader transient-read-directory
:prompt "rsync to: "
:always-read t)]
["Action"
[("x" "execute" dired-rsync-transient--execute)]
[("c" "copy command" dired-rsync-transient--copy :transient t)]]
(interactive nil dired-mode)
(transient-setup 'dired-rsync-transient))
(defun dired-rsync-transient--read-multiple (prompt &optional _initial-input history)
"Read multiple values after PROMPT with optional INITIAL_INPUT and HISTORY."
(completing-read-multiple prompt nil nil nil nil history))
(defun dired-rsync-transient--get-options (args)
"Extract and combine rsync options from ARGS."
(let (opts)
(dolist (arg args)
(cond
((listp arg)
(setq opts (append
(mapcar (lambda (x) (format "%s'%s'" (car arg) x)) (cdr arg))
opts)))
((string-prefix-p "--options=" arg)
(push (string-remove-prefix "--options=" arg) opts))
((string-prefix-p "--dest=" arg))
(t (push arg opts))))
(string-join (nreverse opts) " ")))
(defun dired-rsync-transient--execute (args)
"Execute rsync command generated by transient ARGS."
(interactive (list (transient-args transient-current-command)))
(let ((dest (transient-arg-value "--dest=" args))
(dired-rsync-options (dired-rsync-transient--get-options args)))
(dired-rsync dest)))
(defun dired-rsync-transient--copy (args)
"Copy rsync command generated by transient ARGS."
(interactive (list (transient-args transient-current-command)))
(let* ((dest (transient-arg-value "--dest=" args))
(dired-rsync-options (dired-rsync-transient--get-options args))
(cmd (dired-rsync--build-cmd (funcall dired-rsync-source-files) dest)))
(kill-new cmd)
(message "Command `%s' copied." cmd)))
;; don't show commands in M-x
(put 'dired-rsync-transient--copy 'completion-predicate 'ignore)
(put 'dired-rsync-transient--execute 'completion-predicate 'ignore)
(provide 'dired-rsync-transient)
;;; dired-rsync-transient.el ends here