;;; shadowfile.el --- automatic file copying
-;; Copyright (C) 1993, 1994, 2001, 2002 Free Software Foundation, Inc.
+;; Copyright (C) 1993, 1994, 2001, 2002, 2003, 2004,
+;; 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
;; Author: Boris Goldowsky <boris@gnu.org>
;; Keywords: comm files
;; GNU Emacs 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 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
;;; Commentary:
:group 'shadow)
(defcustom shadow-inhibit-message nil
- "*If nonnil, do not display a message when a file needs copying."
+ "*If non-nil, do not display a message when a file needs copying."
:type 'boolean
:group 'shadow)
(defcustom shadow-inhibit-overload nil
- "If nonnil, shadowfile won't redefine \\[save-buffers-kill-emacs].
-Normally it overloads the function `save-buffers-kill-emacs' to check
-for files have been changed and need to be copied to other systems."
+ "If non-nil, shadowfile won't redefine \\[save-buffers-kill-emacs].
+Normally it overloads the function `save-buffers-kill-emacs' to check for
+files that have been changed and need to be copied to other systems."
:type 'boolean
:group 'shadow)
(defvar shadow-literal-groups nil
"List of files that are shared between hosts.
This list contains shadow structures with literal filenames, created by
-shadow-define-group.")
+`shadow-define-literal-group'.")
(defvar shadow-regexp-groups nil
"List of file types that are shared between hosts.
(shadow-union (cdr a) (cons (car a) b)))))
(defun shadow-find (func list)
- "If FUNC applied to some element of LIST is nonnil, return first such element."
+ "If FUNC applied to some element of LIST is non-nil, return first such element."
(while (and list (not (funcall func (car list))))
(setq list (cdr list)))
(car list))
(defun shadow-suffix (prefix string)
"If PREFIX begins STRING, return the rest.
-Return value is nonnil if PREFIX and STRING are string= up to the length of
+Return value is non-nil if PREFIX and STRING are `string=' up to the length of
PREFIX."
(let ((lp (length prefix))
(ls (length string)))
ans)))
(defun shadow-site-match (site1 site2)
- "Nonnil iff SITE1 is or includes SITE2.
-Each may be a host or cluster name; if they are clusters, regexp of site1 will
-be matched against the primary of site2."
+ "Non-nil if SITE1 is or includes SITE2.
+Each may be a host or cluster name; if they are clusters, regexp of SITE1 will
+be matched against the primary of SITE2."
(or (string-equal site1 site2) ; quick check
(let* ((cluster1 (shadow-get-cluster site1))
(primary2 (shadow-site-primary site2)))
(defun shadow-parse-fullname (fullname)
"Parse FULLNAME into \(site user path) list.
-Leave it alone if it already is one. Returns nil if the argument is
+Leave it alone if it already is one. Return nil if the argument is
not a full ange-ftp pathname."
(if (listp fullname)
fullname
(nth 2 hup))))))
(defun shadow-expand-file-name (file &optional default)
- "Expand file name and get file's true name."
+ "Expand file name and get FILE's true name."
(file-truename (expand-file-name file default)))
(defun shadow-contract-file-name (file)
"Return t if PATTERN matches FILE.
If REGEXP is supplied and non-nil, the file part of the pattern is a regular
expression, otherwise it must match exactly. The sites and usernames must
-match---see shadow-same-site. The pattern must be in full ange-ftp format, but
-the file can be any valid filename. This function does not do any filename
-expansion or contraction, you must do that yourself first."
+match---see `shadow-same-site'. The pattern must be in full ange-ftp format,
+but the file can be any valid filename. This function does not do any
+filename expansion or contraction, you must do that yourself first."
(let* ((pattern-sup (shadow-parse-fullname pattern))
(file-sup (shadow-parse-name file)))
(and (shadow-same-site pattern-sup file-sup)
This is a group of hosts that share directories, so that copying to or from
one of them is sufficient to update the file on all of them. Clusters are
defined by a name, the network address of a primary host \(the one we copy
-files to), and a regular expression that matches the hostnames of all the sites
-in the cluster."
+files to), and a regular expression that matches the hostnames of all the
+sites in the cluster."
(interactive (list (completing-read "Cluster name: " shadow-clusters () ())))
(let* ((old (shadow-get-cluster name))
(primary (read-string "Primary host: "
(sit-for 2))
try-regexp))
; (username (read-no-blanks-input
-; (format "Username [default: %s]: "
+; (format "Username (default %s): "
; (shadow-get-user primary))
; (if old (or (shadow-cluster-username old) "")
; (user-login-name))))
(name (nth 2 hup))
user site group)
(while (setq site (shadow-read-site))
- (setq user (read-string (format "Username [default %s]: "
+ (setq user (read-string (format "Username (default %s): "
(shadow-get-user site)))
name (read-string "Filename: " name))
(setq group (cons (shadow-make-fullname site
"Make each of a group of files be shared between hosts.
Prompts for regular expression; files matching this are shared between a list
of sites, which are also prompted for. The filenames must be identical on all
-hosts \(if they aren't, use shadow-define-group instead of this function).
-Each site can be either a hostname or the name of a cluster \(see
+hosts \(if they aren't, use `shadow-define-literal-group' instead of this
+function). Each site can be either a hostname or the name of a cluster \(see
`shadow-define-cluster')."
(interactive)
(let ((regexp (read-string
`shadow-save-buffers-kill-emacs', so it is not usually necessary to
call it manually."
(interactive "P")
- (if (and (not shadow-files-to-copy) (interactive-p))
- (message "No files need to be shadowed.")
+ (if (not shadow-files-to-copy)
+ (if (interactive-p)
+ (message "No files need to be shadowed."))
(save-excursion
(map-y-or-n-p (function
(lambda (pair)
(defun shadow-remove-from-todo (pair)
"Remove PAIR from `shadow-files-to-copy'.
-PAIR must be (eq to) one of the elements of that list."
+PAIR must be `eq' to one of the elements of that list."
(setq shadow-files-to-copy
(shadow-remove-if (function (lambda (s) (eq s pair)))
shadow-files-to-copy)))
(defun shadow-read-files ()
"Visit and load `shadow-info-file' and `shadow-todo-file'.
Thus restores shadowfile's state from your last Emacs session.
-Returns t unless files were locked; then returns nil."
+Return t unless files were locked; then return nil."
(interactive)
(if (and (fboundp 'file-locked-p)
(or (stringp (file-locked-p shadow-info-file))
(stringp (file-locked-p shadow-todo-file))))
(progn
- (message "Shadowfile is running in another emacs; can't have two.")
+ (message "Shadowfile is running in another Emacs; can't have two.")
(beep)
(sit-for 3)
nil)
(message "Data recovered from %s."
(car (insert-file-contents (make-auto-save-file-name))))
(sit-for 1))
- (eval-current-buffer))
+ (eval-buffer))
(when shadow-todo-file
(set-buffer (setq shadow-todo-buffer
(find-file-noselect shadow-todo-file)))
(message "Data recovered from %s."
(car (insert-file-contents (make-auto-save-file-name))))
(sit-for 1))
- (eval-current-buffer nil))
+ (eval-buffer nil))
(shadow-invalidate-hashtable))
t))
(shadow-insert-var 'shadow-regexp-groups))))
(defun shadow-write-todo-file (&optional save)
- "Write out information to shadow-todo-file.
-With nonnil argument also saves the buffer."
+ "Write out information to `shadow-todo-file'.
+With non-nil argument also saves the buffer."
(save-excursion
(if (not shadow-todo-buffer)
(setq shadow-todo-buffer (find-file-noselect shadow-todo-file)))
(setq shadow-hashtable (make-vector 37 0)))
(defun shadow-insert-var (variable)
- "Prettily insert a setq command for VARIABLE.
-which, when later evaluated, will restore it to its current setting.
-SYMBOL must be the name of a variable whose value is a list."
+ "Build a `setq' to restore VARIABLE.
+Prettily insert a `setq' command which, when later evaluated,
+will restore VARIABLE to its current setting.
+VARIABLE must be the name of a variable whose value is a list."
(let ((standard-output (current-buffer)))
(insert (format "(setq %s" variable))
(cond ((consp (eval variable))
(symbol-function 'shadow-orig-save-buffers-kill-emacs)))
(remove-hook 'write-file-hooks 'shadow-add-to-todo))
+(add-hook 'shadowfile-unload-hook 'shadowfile-unload-hook)
+
(provide 'shadowfile)
;;; arch-tag: e2f4cdd7-2bab-4def-9130-9e69b412b79e