├── readme.md └── tmtxt-dired-async.el /readme.md: -------------------------------------------------------------------------------- 1 | # Asynchoronous execution library for Emacs Dired 2 | 3 | A library for Emacs Dired mode to copy, compress, decompress files 4 | asynchronously. It also provides the ability to mark files in multiple 5 | directories and then copy all of them into a destination library. This library 6 | is designed for Unix-based system like MacOS, Ubuntu,... 7 | 8 | For more information, please refer to this project's homepage: 9 | [tmtxt-dired-async homepage](http://truongtx.me/tmtxt-dired-async.html) 10 | -------------------------------------------------------------------------------- /tmtxt-dired-async.el: -------------------------------------------------------------------------------- 1 | ;;; an collection of functions that I developed to execute some commands 2 | ;;; asynchronously 3 | ;;; only run ob unix-based systems 4 | 5 | ;;; TODO: stick the output window with the result buffer 6 | ;;; using dedicated window 7 | ;;; TODO: shortcut keys for close the result window 8 | ;;; TODO: check process exit status, if not success, not close the result window 9 | ;;; TODO: undo function 10 | 11 | ;;; ---------------------------------------------- 12 | ;;; ---------------------------------------------- 13 | ;;; get file size 14 | (defvar tda/get-files-size-command "du" 15 | "The name of \"du\" command (or the path to the \"du\" command)") 16 | (defvar tda/get-files-size-arguments "-hc" 17 | "The arguments for passing into the \"du\" command") 18 | 19 | ;;; get file size 20 | (defun tda/get-files-size () 21 | "Calculate files size for all the marked files" 22 | (interactive) 23 | (let ((files (dired-get-marked-files)) command) 24 | ;; the get files size command 25 | (setq command tda/get-files-size-command) 26 | (setq command (concat command " " tda/get-files-size-arguments " ")) 27 | ;; add selected file names as arguments to the command 28 | (dolist (file files) 29 | (setq command (concat command (shell-quote-argument file) " "))) 30 | ;; execute the command 31 | (tat/execute-async command "file size"))) 32 | 33 | ;;; ---------------------------------------------- 34 | ;;; ---------------------------------------------- 35 | ;;; Async Rsync 36 | (defvar tda/rsync-command-name "rsync" 37 | "The name of rsync command (or the path to the rsync command).") 38 | (defvar tda/rsync-arguments "-avz --progress" 39 | "The arguments for passing into the rsync command") 40 | 41 | (defun tda/rsync (dest) 42 | "Asynchronously copy file using Rsync for dired. 43 | This function runs only on Unix-based system. 44 | Usage: same as normal dired copy function." 45 | (interactive ;; offer dwim target as the suggestion 46 | (list (expand-file-name (read-file-name "Rsync to:" (dired-dwim-target-directory))))) 47 | (let ((files (dired-get-marked-files nil current-prefix-arg)) 48 | command) 49 | ;; the rsync command 50 | (setq command 51 | (concat tda/rsync-command-name " " tda/rsync-arguments " ")) 52 | ;; add all selected file names as arguments to the rsync command 53 | (dolist (file files) 54 | (setq command (concat command (shell-quote-argument file) " "))) 55 | ;; append the destination to the rsync command 56 | (setq command (concat command (shell-quote-argument dest))) 57 | ;; execute the command asynchronously 58 | (tat/execute-async command "rsync"))) 59 | 60 | (defun tda/rsync-sudo (dest) 61 | "Asynchronously copy file using Rsync for dired. 62 | This function runs only on Unix-based system. 63 | Usage: same as normal dired copy function." 64 | (interactive ;; offer dwim target as the suggestion 65 | (list (expand-file-name (read-file-name "Rsync to:" (dired-dwim-target-directory))))) 66 | (let ((files (dired-get-marked-files nil current-prefix-arg)) 67 | command) 68 | ;; the rsync command 69 | (setq command 70 | (concat "sudo " tda/rsync-command-name " " tda/rsync-arguments " ")) 71 | ;; add all selected file names as arguments to the rsync command 72 | (dolist (file files) 73 | (setq command (concat command (shell-quote-argument file) " "))) 74 | ;; append the destination to the rsync command 75 | (setq command (concat command (shell-quote-argument dest))) 76 | ;; execute the command asynchronously 77 | (tat/execute-async command "rsync"))) 78 | 79 | (defun tda/rsync-delete (dest) 80 | "Asynchronously copy file using Rsync for dired include the delete option 81 | This function runs only on Unix-based system. 82 | Usage: same as normal dired copy function." 83 | (interactive ;; offer dwim target as the suggestion 84 | (list (expand-file-name (read-file-name "Rsync delete to:" (dired-dwim-target-directory))))) 85 | (let ((files (dired-get-marked-files nil current-prefix-arg)) 86 | command) 87 | ;; the rsync command 88 | (setq command 89 | (concat tda/rsync-command-name " " tda/rsync-arguments " --delete ")) 90 | ;; add all selected file names as arguments to the rsync command 91 | (dolist (file files) 92 | (setq command (concat command (shell-quote-argument file) " "))) 93 | ;; append the destination to the rsync command 94 | (setq command (concat command (shell-quote-argument dest))) 95 | ;; execute the command asynchronously 96 | (tat/execute-async command "rsync"))) 97 | 98 | (defun tda/rsync-delete-sudo (dest) 99 | "Asynchronously copy file using Rsync for dired include the delete option 100 | This function runs only on Unix-based system. 101 | Usage: same as normal dired copy function." 102 | (interactive ;; offer dwim target as the suggestion 103 | (list (expand-file-name (read-file-name "Rsync delete to:" (dired-dwim-target-directory))))) 104 | (let ((files (dired-get-marked-files nil current-prefix-arg)) 105 | command) 106 | ;; the rsync command 107 | (setq command 108 | (concat "sudo " tda/rsync-command-name " " tda/rsync-arguments " --delete ")) 109 | ;; add all selected file names as arguments to the rsync command 110 | (dolist (file files) 111 | (setq command (concat command (shell-quote-argument file) " "))) 112 | ;; append the destination to the rsync command 113 | (setq command (concat command (shell-quote-argument dest))) 114 | ;; execute the command asynchronously 115 | (tat/execute-async command "rsync"))) 116 | 117 | ;;; ---------------------------------------------- 118 | ;;; ---------------------------------------------- 119 | ;;; async zip files 120 | (defvar tda/zip-command "zip" 121 | "The command name (or the path to the zip command") 122 | (defvar tda/zip-arguments 123 | "-ru9" "The compression level for dired async zip command, from 0-9. This variable is a string, so if you change this value, please set it as a string.") 124 | 125 | (defun tda/zip (output) 126 | "Asynchronously compress marked files to the output file" 127 | (interactive 128 | (list (expand-file-name (read-file-name "Add to file: ")))) 129 | 130 | (let (command 131 | (files (dired-get-marked-files nil current-prefix-arg))) 132 | ;; the zip command 133 | (setq command 134 | (concat tda/zip-command " " tda/zip-arguments " ")) 135 | ;; append the output file 136 | (setq command 137 | (concat command (shell-quote-argument output) " ")) 138 | ;; add all selected files as argument 139 | (dolist (file files) 140 | (setq command 141 | (concat command 142 | (shell-quote-argument 143 | (file-name-nondirectory file)) " "))) 144 | (message command) 145 | ;; execute the command asynchronously 146 | (tat/execute-async command "zip"))) 147 | 148 | ;;; ---------------------------------------------- 149 | ;;; ---------------------------------------------- 150 | ;;; Uncompress function 151 | (defvar tda/unzip-command "unzip" 152 | "The command name (or path to the unzip command)") 153 | (defvar tda/unzip-arguments "" 154 | "The arguments for passing into the unzip command") 155 | 156 | (defun tda/unzip () 157 | "Asynchronously decompress the zip file at point" 158 | (interactive) 159 | 160 | (let (command 161 | output-directory 162 | (file (dired-get-filename 'verbatim))) 163 | 164 | ;; new directory name for the output files 165 | (setq output-directory 166 | (file-name-sans-extension 167 | (dired-get-filename 'verbatim))) 168 | 169 | ;; the unzip command 170 | (setq command (concat tda/unzip-command " " tda/unzip-arguments " ")) 171 | ;; append the file name 172 | (setq command 173 | (concat command 174 | (shell-quote-argument file) " ")) 175 | ;; append the output directory name 176 | (setq command 177 | (concat command "-d " 178 | (shell-quote-argument output-directory))) 179 | 180 | ;; execute the command asynchronously 181 | (tat/execute-async command "unzip"))) 182 | 183 | ;;; ---------------------------------------------- 184 | ;;; ---------------------------------------------- 185 | ;;; Rsync from multiple directories 186 | (defvar tda/rsync-multiple-file-list 187 | () "The list of the files to be copied") 188 | 189 | (defun tda/rsync-multiple-mark-file () 190 | "Add file to waiting list for copying" 191 | (interactive) 192 | ;; Add file to the list 193 | (add-to-list 'tda/rsync-multiple-file-list 194 | (dired-get-filename)) 195 | ;; Message for user 196 | (message 197 | (concat "File " (dired-get-filename 'verbatim) " added to waiting list."))) 198 | 199 | (defun tda/rsync-multiple-empty-list () 200 | "Empty the waiting list" 201 | (interactive) 202 | ;; Empty the list 203 | (setq tda/rsync-multiple-file-list '()) 204 | ;; message for the user 205 | (message "Waiting list empty.")) 206 | 207 | (defun tda/rsync-multiple-remove-item () 208 | "Remove the file at point from the waiting list if it is in" 209 | (interactive) 210 | (let ((file-to-remove (dired-get-filename))) 211 | ;; remove the item from the list 212 | (setq tda/rsync-multiple-file-list 213 | (remove file-to-remove tda/rsync-multiple-file-list)) 214 | ;; message for the use 215 | (message 216 | (concat "File " (dired-get-filename 'verbatim) " removed from the list.")))) 217 | 218 | ;; Copy file from multiple directories 219 | (defun tda/rsync-multiple () 220 | "Mark file in multiple places and then paste in 1 directory" 221 | (interactive) 222 | 223 | (let (command) 224 | (if (equal tda/rsync-multiple-file-list ()) 225 | (progn 226 | (message "Please add file to the waiting list.")) 227 | (progn 228 | ;; the rsync command 229 | (setq command (concat tda/rsync-command-name " " tda/rsync-arguments " ")) 230 | ;; add all selected file names as arguments to the rsync command 231 | (dolist (file tda/rsync-multiple-file-list) 232 | (setq command 233 | (concat command (shell-quote-argument file) " "))) 234 | ;; append the destination to the rsync command 235 | (setq command 236 | (concat command 237 | (shell-quote-argument (expand-file-name default-directory)))) 238 | ;; execute the command asynchronously 239 | (tat/execute-async command "rsync") 240 | ;; empty the waiting list 241 | (tda/rsync-multiple-empty-list))))) 242 | 243 | ;;; ---------------------------------------------- 244 | ;;; ---------------------------------------------- 245 | ;;; download file to current dir 246 | (defvar tda/download-command "wget" 247 | "The download program to download to current dir. The default is wget, ou can replace it to curl, aria2c,...") 248 | (defun tda/download-to-current-dir (src) 249 | "Read the link and download the file to current directory" 250 | (interactive (list (read-from-minibuffer "Link: "))) 251 | (let ((command "")) 252 | ;; create the command 253 | (setq command (concat command tda/download-command " ")) 254 | ;; append the link 255 | (setq command (concat command (shell-quote-argument src))) 256 | ;; execute 257 | (tat/execute-async command "download"))) 258 | (defun tda/download-clipboard-link-to-current-dir () 259 | "Read the clipboard link and download it into the current dir" 260 | (interactive) 261 | (tda/download-to-current-dir (x-get-clipboard))) 262 | 263 | (provide 'tmtxt-dired-async) 264 | --------------------------------------------------------------------------------