| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 |
|
|---|
| 17 |
|
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 |
|
|---|
| 21 |
|
|---|
| 22 |
|
|---|
| 23 |
|
|---|
| 24 |
|
|---|
| 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 |
|---|
| 34 |
provide optional behavior which the user can enable or disable by |
|---|
| 35 |
customizing the variable `eshell-modules-list'." |
|---|
| 36 |
:tag "Extension modules" |
|---|
| 37 |
:group 'eshell) |
|---|
| 38 |
|
|---|
| 39 |
|
|---|
| 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)) |
|---|
| 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 |
|
|---|
| 74 |
|
|---|
| 75 |
|
|---|
| 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 |
|
|---|
| 83 |
|
|---|
| 84 |
|
|---|
| 85 |
|
|---|
| 86 |
|
|---|
| 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 |
|
|---|
| 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. |
|---|
| 121 |
Changes 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 |
|
|---|
| 142 |
|
|---|
| 143 |
(defsubst eshell-using-module (module) |
|---|
| 144 |
"Return non-nil if a certain Eshell MODULE is in use. |
|---|
| 145 |
The MODULE should be a symbol corresponding to that module's |
|---|
| 146 |
customization 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 |
|
|---|
| 159 |
|
|---|
| 160 |
|
|---|