Commits

Didier Verna committed 7cc9260

Add rcfiles.el.

Comments (0)

Files changed (2)

+2013-06-03  Didier Verna  <didier@xemacs.org>
+
+	* rcfiles.el: New file.
+
 2013-03-19  Norbert Koch  <viteno@xemacs.org>
 
 	* Makefile (VERSION): XEmacs package 2.35 released.
+;;; rcfiles.el --- Unix-like rc files for Emacs Lisp libraries
+
+;; Copyright (C) 2006, 2007, 2012, 2013 Didier Verna
+
+;; Author: Didier Verna <didier@didierverna.net>
+;; Version: 1.0
+;; Keywords: extensions, lisp
+
+;; This file is part of el-rcfiles.
+
+;; el-rcfiles is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License version 3, as
+;; published by the Free Software Foundation.
+
+;; el-rcfiles 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, write to the Free Software
+;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+;;; Commentary:
+
+;; The purpose of el-rcfiles is to provide the equivalent of traditional
+;; Unix rc files (i.e. configuration files) for Emacs Lisp
+;; libraries. The advantages of using configuration files are the
+;; following:
+;;   - your initialization file is less bloated,
+;;   - since configuration files are lazily loaded, your Emacs session
+;;     is (or begins) lighter. That is unless you already use lots of
+;;     EVAL-AFTER-LOAD forms...
+
+;; Usage:
+
+;; 1. Load the library, go to the rcfiles Custom group and tweak (or not).
+;; 2. Put a call to (rcfiles-register-rc-files) in your initialization
+;;    file. This function can also be called interactively anytime you
+;;    add, remove or modify a configuration file.
+;; 3. Put your configuration code for a library `foo' in a file called
+;;    `<rcfiles-directory>/foo<rcfiles-pseudo-extension>.el'.
+
+
+;;; Code:
+
+(require 'cl)
+
+
+(defvar rcfiles-version "1.0"
+  "Current version number of el-rcfiles.")
+
+(defun rcfiles-version ()
+  "Show the current version number of el-rcfiles."
+  (interactive)
+  (message "%s" rcfiles-version))
+
+
+(defgroup rcfiles nil
+  "Configuration files for Emacs Lisp libraries."
+  :group 'emacs)
+
+(defcustom rcfiles-directory
+  (if (featurep 'xemacs) "~/.xemacs/rc" "~/.emacs.d/rc")
+  "Directory where el-rcfiles looks for configuration files."
+  :group 'rcfiles
+  :type 'string)
+
+(defcustom rcfiles-pseudo-extension "-rc"
+  "Pseudo extension for configuration files.
+It is added between the name of the library and the .el
+extension."
+  :group 'rcfiles
+  :type 'string)
+
+(defun rcfiles-rc-files ()
+  "Return the list of configuration files currently available.
+File names are expanded but their extension is removed."
+  (let ((ext-regexp
+	 (concat (regexp-quote rcfiles-pseudo-extension) "\\.el[c]?$")))
+    (mapcar #'file-name-sans-extension
+	    ;; #### NOTE: potential duplicates (such as when there is
+	    ;; both a .el and a .elc file) are not a problem because
+	    ;; EVAL-AFTER-LOAD takes care of that.
+	    (directory-files rcfiles-directory t ext-regexp))))
+
+(defun rcfiles-prune (rcfiles)
+  "Unregister configuration files not in RCFILES."
+  (let ((dir
+	 (concat "^" (regexp-quote (expand-file-name rcfiles-directory)))))
+    (setq after-load-alist
+	  (remove-if (lambda (file)
+		       (and (stringp file)
+			    (string-match dir file)
+			    (not (member file rcfiles))))
+		     after-load-alist
+		     :key (lambda (form)
+			    (ignore-errors
+			      (let ((load-form
+				     ;; are we having fun yet?
+				     (caddr (cadr (cadr (cadr form))))))
+				(when (eq (car load-form) 'rcfiles-try-load)
+				  (cadr load-form)))))))))
+
+(defun rcfiles-try-load (rcfile)
+  "Attempt to load RCFILE. If loading fails, throw a warning."
+  (condition-case ignore (load rcfile)
+    (error (warn (format "Unable to load %s.
+Maybe you need to call RCFILES-REGISTER-RC-FILES again?"
+			 rcfile)))))
+
+(defun rcfiles-register (rcfiles)
+  "Register the configuration files in the RCFILES list."
+  (let ((len (length rcfiles-pseudo-extension)))
+    (dolist (rcfile rcfiles)
+      (eval-after-load (file-name-nondirectory (substring rcfile 0 (- len)))
+	`(rcfiles-try-load ,rcfile)))))
+
+;;;###autoload
+(defun rcfiles-register-rc-files ()
+  "Register the configuration files currently available.
+This function can be called at startup and every time the
+registration changes. Obsolete entries are removed and new ones
+are added."
+  (interactive)
+  (let ((rcfiles (rcfiles-rc-files)))
+    (rcfiles-prune rcfiles)
+    (rcfiles-register rcfiles)))
+
+
+(provide 'rcfiles)
+
+;;; rcfiles.el ends here