1;;; esh-module.el --- Eshell modules
2
3;; Copyright (C) 1999, 2000, 2002, 2003, 2004,
4;;   2005, 2006, 2007 Free Software Foundation, Inc.
5
6;; Author: John Wiegley <johnw@gnu.org>
7;; Keywords: processes
8
9;; This file is part of GNU Emacs.
10
11;; GNU Emacs is free software; you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by
13;; the Free Software Foundation; either version 2, or (at your option)
14;; any later version.
15
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
22;; along with GNU Emacs; see the file COPYING.  If not, write to the
23;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24;; Boston, MA 02110-1301, USA.
25
26(provide 'esh-module)
27
28(eval-when-compile
29  (require 'esh-maint)
30  (require 'cl))
31
32(defgroup eshell-module nil
33  "The `eshell-module' group is for Eshell extension modules, which
34provide optional behavior which the user can enable or disable by
35customizing the variable `eshell-modules-list'."
36  :tag "Extension modules"
37  :group 'eshell)
38
39;;; Commentary:
40
41(require 'esh-util)
42
43(defun eshell-load-defgroups (&optional directory)
44  "Load `defgroup' statements from Eshell's module files."
45  (let ((vc-handled-backends nil)) ; avoid VC fucking things up
46    (with-current-buffer
47	(find-file-noselect (expand-file-name "esh-groups.el" directory))
48      (erase-buffer)
49      (insert ";;; do not modify this file; it is auto-generated -*- no-byte-compile: t -*-\n\n")
50      (let ((files (directory-files (or directory
51					(car command-line-args-left))
52				    nil "\\`em-.*\\.el\\'")))
53	(while files
54	  (message "Loading defgroup from `%s'" (car files))
55	  (let (defgroup)
56	    (catch 'handled
57	      (with-current-buffer (find-file-noselect (car files))
58		(goto-char (point-min))
59		(while t
60		  (forward-sexp)
61		  (if (eobp) (throw 'handled t))
62		  (backward-sexp)
63		  (let ((begin (point))
64			(defg (looking-at "(defgroup")))
65		    (forward-sexp)
66		    (if defg
67			(setq defgroup (buffer-substring begin (point))))))))
68	    (if defgroup
69		(insert defgroup "\n\n")))
70	  (setq files (cdr files))))
71      (save-buffer))))
72
73;; load the defgroup's for the standard extension modules, so that
74;; documentation can be provided when the user customize's
75;; `eshell-modules-list'.
76(eval-when-compile
77  (when (and (boundp 'byte-compile-current-file)
78	     byte-compile-current-file
79	     (or
80	      (equal (file-name-nondirectory byte-compile-current-file)
81		     "esh-module.el")
82	      ;; When eshell file names are expanded from a wildcard
83	      ;; or by reading the Eshell directory, e.g. when they
84	      ;; say "make recompile" in the lisp directory, Emacs on
85	      ;; MS-DOS sees a truncated name "esh-modu.el" instead of
86	      ;; "esh-module.el".
87	      (and (fboundp 'msdos-long-file-names)
88		   (null (msdos-long-file-names))
89		   (equal (file-name-nondirectory byte-compile-current-file)
90			  "esh-modu.el"))))
91    (let* ((directory (file-name-directory byte-compile-current-file))
92	   (elc-file (expand-file-name "esh-groups.elc" directory)))
93      (eshell-load-defgroups directory)
94      (if (file-exists-p elc-file) (delete-file elc-file)))))
95
96(load "esh-groups" t t)
97
98;;; User Variables:
99
100(defcustom eshell-module-unload-hook
101  '(eshell-unload-extension-modules)
102  "*A hook run when `eshell-module' is unloaded."
103  :type 'hook
104  :group 'eshell-module)
105
106(defcustom eshell-modules-list
107  '(eshell-alias
108    eshell-banner
109    eshell-basic
110    eshell-cmpl
111    eshell-dirs
112    eshell-glob
113    eshell-hist
114    eshell-ls
115    eshell-pred
116    eshell-prompt
117    eshell-script
118    eshell-term
119    eshell-unix)
120  "*A list of optional add-on modules to be loaded by Eshell.
121Changes will only take effect in future Eshell buffers."
122  :type (append
123	 (list 'set ':tag "Supported modules")
124	 (mapcar
125	  (function
126	   (lambda (modname)
127	     (let ((modsym (intern modname)))
128	       (list 'const
129		     ':tag (format "%s -- %s" modname
130				   (get modsym 'custom-tag))
131		     ':link (caar (get modsym 'custom-links))
132		     ':doc (concat "\n" (get modsym 'group-documentation)
133				   "\n ")
134		     modsym))))
135	  (sort (mapcar 'symbol-name
136			(eshell-subgroups 'eshell-module))
137		'string-lessp))
138	 '((repeat :inline t :tag "Other modules" symbol)))
139  :group 'eshell-module)
140
141;;; Code:
142
143(defsubst eshell-using-module (module)
144  "Return non-nil if a certain Eshell MODULE is in use.
145The MODULE should be a symbol corresponding to that module's
146customization group.  Example: `eshell-cmpl' for that module."
147  (memq module eshell-modules-list))
148
149(defun eshell-unload-extension-modules ()
150  "Unload any memory resident extension modules."
151  (eshell-for module (eshell-subgroups 'eshell-module)
152    (if (featurep module)
153	(ignore-errors
154	  (message "Unloading %s..." (symbol-name module))
155	  (unload-feature module)
156	  (message "Unloading %s...done" (symbol-name module))))))
157
158;;; arch-tag: 97a3fa16-9d08-40e6-bc2c-36bd70986507
159;;; esh-module.el ends here
160