-
-
Save grzs/61220178b6c4b5f8bc9aeb20c9600aca to your computer and use it in GitHub Desktop.
auto-rsync.el - Emacs minor mode to execute rsync automaticlly
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; auto-rsync-mode -- minor mode for auto rsync | |
;; | |
;; Author: @l3msh0 | |
;; | |
;;; Example | |
;; | |
;; (require 'auto-rsync) | |
;; (auto-rsync-mode t) | |
;; (setq auto-rsync-dir-alist | |
;; '(("/path/to/src1/" . "/path/to/dest1/") | |
;; ("/path/to/src2/" . "username@hostname:/path/to/dest2/"))) | |
;; (add-to-list auto-rsync-exclude-patterns-alist '("git" "*~" ".git")) | |
;; (setq auto-rsync-excludes-alist | |
;; '(("/path/to/src1/" . "default") | |
;; ("/path/to/src2/" . "git"))) | |
;;; Customize | |
;; | |
(defgroup auto-rsync nil "Auto rsync") | |
(defcustom auto-rsync-command "rsync" "rsync command path" :group 'auto-rsync) | |
(defcustom auto-rsync-flags '("-azq") "rsync command flags" :group 'auto-rsync) | |
;;; TODO | |
;; | |
;; open remote counterpart | |
;; | |
(defvar auto-rsync-dir-alist nil "Pair of rsync source and destination dir") | |
(defvar auto-rsync-dir-ssh-port-alist nil "Per source dir list of flags") | |
(defvar auto-rsync-exclude-patterns-alist '(("default" "*~")) "Sets of exclude patterns") | |
(defvar auto-rsync-excludes-alist nil "Pair of rsync source and exclude set") | |
;;; Code | |
(defun auto-rsync-excludes (list) | |
"Assembles a list of --exclude options" | |
(let (result) | |
(dolist (elt list result) | |
(setq elt (concat "'" elt "'")) | |
(setq result (append (list "--exclude" elt) result))))) | |
(defun auto-rsync-exec-rsync () | |
"execute rsync if editing file path matches src dir" | |
(interactive) | |
(let* ((normalized-alist (mapcar (lambda (x) (cons (file-name-as-directory (expand-file-name (car x))) | |
(cdr x))) | |
auto-rsync-dir-alist)) | |
(sync-pair (assoc buffer-file-name normalized-alist | |
(lambda (dirname filename) (eq 0 (string-match dirname filename))))) | |
;; excludes | |
(normalized-excludes-alist (mapcar (lambda (x) (cons (file-name-as-directory (expand-file-name (car x))) | |
(cdr x))) | |
auto-rsync-excludes-alist)) | |
(excludes-key (cdr (assoc buffer-file-name normalized-excludes-alist | |
(lambda (dirname filename) (eq 0 (string-match dirname filename)))))) | |
(excludes (cdr (assoc excludes-key auto-rsync-exclude-patterns-alist))) | |
;; ssh port | |
(normalized-dir-ssh-port-alist (mapcar (lambda (x) (cons (file-name-as-directory (expand-file-name (car x))) | |
(cdr x))) | |
auto-rsync-dir-ssh-port-alist)) | |
(dir-ssh-port (cdr (assoc buffer-file-name normalized-dir-ssh-port-alist | |
(lambda (dirname filename) (eq 0 (string-match dirname filename)))))) | |
;; rsync options | |
(rsync-options-list (if excludes | |
(append auto-rsync-flags (auto-rsync-excludes excludes)) | |
auto-rsync-flags)) | |
(rsync-options-list (if dir-ssh-port | |
(cons (format "-e 'ssh -p %s'" dir-ssh-port) rsync-options-list) rsync-options-list)) | |
(rsync-options (string-join rsync-options-list " "))) | |
(when sync-pair | |
(save-window-excursion | |
;; avoid annoying shell comannd window | |
(shell-command (format "%s %s %s %s &" auto-rsync-command rsync-options (car sync-pair) (cdr sync-pair)) nil)) | |
))) | |
(define-minor-mode auto-rsync-mode | |
"automatically execute rsync when editing file's path matches `auto-rsync-dir-alist`" | |
:lighter " rsync" | |
:global t | |
(cond (auto-rsync-mode | |
(add-hook 'after-save-hook 'auto-rsync-exec-rsync)) | |
(t | |
(remove-hook 'after-save-hook 'auto-rsync-exec-rsync)))) | |
(provide 'auto-rsync) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey Janos, thanks for this, worked like a charm out of the box! --Tamas