Mercurial > hg > xemacs-beta
diff lisp/custom/cus-edit.el @ 124:9b50b4588a93 r20-1b15
Import from CVS: tag r20-1b15
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:26:39 +0200 |
parents | cca96a509cfe |
children | 34a5b81f86ba |
line wrap: on
line diff
--- a/lisp/custom/cus-edit.el Mon Aug 13 09:26:04 2007 +0200 +++ b/lisp/custom/cus-edit.el Mon Aug 13 09:26:39 2007 +0200 @@ -4,7 +4,7 @@ ;; ;; Author: Per Abrahamsen <abraham@dina.kvl.dk> ;; Keywords: help, faces -;; Version: 1.74 +;; Version: 1.84 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ ;;; Commentary: @@ -206,9 +206,90 @@ :link '(url-link :tag "Development Page" "http://www.dina.kvl.dk/~abraham/custom/") :prefix "custom-" - :group 'help + :group 'help) + +(defgroup custom-faces nil + "Faces used by customize." + :group 'customize :group 'faces) +(defgroup abbrev-mode nil + "Word abbreviations mode." + :group 'abbrev) + +(defgroup alloc nil + "Storage allocation and gc for GNU Emacs Lisp interpreter." + :tag "Storage Allocation" + :group 'internal) + +(defgroup undo nil + "Undoing changes in buffers." + :group 'editing) + +(defgroup modeline nil + "Content of the modeline." + :group 'environment) + +(defgroup fill nil + "Indenting and filling text." + :group 'editing) + +(defgroup editing-basics nil + "Most basic editing facilities." + :group 'editing) + +(defgroup display nil + "How characters are displayed in buffers." + :group 'environment) + +(defgroup execute nil + "Executing external commands." + :group 'processes) + +(defgroup installation nil + "The Emacs installation." + :group 'environment) + +(defgroup dired nil + "Directory editing." + :group 'environment) + +(defgroup limits nil + "Internal Emacs limits." + :group 'internal) + +(defgroup debug nil + "Debugging Emacs itself." + :group 'development) + +(defgroup minibuffer nil + "Controling the behaviour of the minibuffer." + :group 'environment) + +(defgroup keyboard nil + "Input from the keyboard." + :group 'environment) + +(defgroup mouse nil + "Input from the mouse." + :group 'environment) + +(defgroup menu nil + "Input from the menus." + :group 'environment) + +(defgroup auto-save nil + "Preventing accidential loss of data." + :group 'data) + +(defgroup processes-basics nil + "Basic stuff dealing with processes." + :group 'processes) + +(defgroup windows nil + "Windows within a frame." + :group 'processes) + ;;; Utilities. (defun custom-quote (sexp) @@ -240,6 +321,23 @@ (nreverse (cons (substring regexp start) all))) regexp)) +(defun custom-variable-prompt () + ;; Code stolen from `help.el'. + "Prompt for a variable, defaulting to the variable at point. +Return a list suitable for use in `interactive'." + (let ((v (variable-at-point)) + (enable-recursive-minibuffers t) + val) + (setq val (completing-read + (if v + (format "Customize variable (default %s): " v) + "Customize variable: ") + obarray 'boundp t)) + (list (if (equal val "") + v (intern val))))) + +;;; Unlispify. + (defvar custom-prefix-list nil "List of prefixes that should be ignored by `custom-unlispify'") @@ -298,7 +396,9 @@ (concat (symbol-name symbol) "-")) prefixes)) -(defcustom custom-guess-type-alist +;;; Guess. + +(defcustom custom-guess-name-alist '(("-p\\'" boolean) ("-hook\\'" hook) ("-face\\'" face) @@ -316,79 +416,53 @@ This is used for guessing the type of variables not declared with customize." - :type '(repeat (group regexp sexp)) + :type '(repeat (group (regexp :tag "Match") (sexp :tag "Type"))) + :group 'customize) + +(defcustom custom-guess-doc-alist + '(("\\`\\*?Non-nil " boolean)) + "Alist of (MATCH TYPE). + +MATCH should be a regexp matching a documentation string, and TYPE +should be a widget suitable for editing the value of a variable with +that documentation string. The TYPE of the first entry where MATCH +matches the name of the symbol will be used. + +This is used for guessing the type of variables not declared with +customize." + :type '(repeat (group (regexp :tag "Match") (sexp :tag "Type"))) :group 'customize) (defun custom-guess-type (symbol) "Guess a widget suitable for editing the value of SYMBOL. -This is done by matching SYMBOL with `custom-guess-type-alist'." +This is done by matching SYMBOL with `custom-guess-name-alist' and +if that fails, the doc string with `custom-guess-doc-alist'." (let ((name (symbol-name symbol)) - (alist custom-guess-type-alist) + (names custom-guess-name-alist) current found) - (while alist - (setq current (car alist) - alist (cdr alist)) + (while names + (setq current (car names) + names (cdr names)) (when (string-match (nth 0 current) name) (setq found (nth 1 current) - alist nil))) + names nil))) + (unless found + (let ((doc (documentation-property symbol 'variable-documentation)) + (docs custom-guess-doc-alist)) + (when doc + (while docs + (setq current (car docs) + docs (cdr docs)) + (when (string-match (nth 0 current) doc) + (setq found (nth 1 current) + docs nil)))))) found)) -;;; The Custom Mode. +;;; Custom Mode Commands. (defvar custom-options nil "Customization widgets in the current buffer.") -(defvar custom-mode-map nil - "Keymap for `custom-mode'.") - -(unless custom-mode-map - (setq custom-mode-map (make-sparse-keymap)) - (set-keymap-parent custom-mode-map widget-keymap) - (define-key custom-mode-map "q" 'bury-buffer)) - -(easy-menu-define custom-mode-menu - custom-mode-map - "Menu used in customization buffers." - '("Custom" - ["Set" custom-set t] - ["Save" custom-save t] - ["Reset to Current" custom-reset-current t] - ["Reset to Saved" custom-reset-saved t] - ["Reset to Factory Settings" custom-reset-factory t] - ["Info" (Info-goto-node "(custom)The Customization Buffer") t])) - -(defcustom custom-mode-hook nil - "Hook called when entering custom-mode." - :type 'hook - :group 'customize) - -(defun custom-mode () - "Major mode for editing customization buffers. - -The following commands are available: - -\\[widget-forward] Move to next button or editable field. -\\[widget-backward] Move to previous button or editable field. -\\[widget-button-click] Activate button under the mouse pointer. -\\[widget-button-press] Activate button under point. -\\[custom-set] Set all modifications. -\\[custom-save] Make all modifications default. -\\[custom-reset-current] Reset all modified options. -\\[custom-reset-saved] Reset all modified or set options. -\\[custom-reset-factory] Reset all options. - -Entry to this mode calls the value of `custom-mode-hook' -if that value is non-nil." - (kill-all-local-variables) - (setq major-mode 'custom-mode - mode-name "Custom") - (use-local-map custom-mode-map) - (easy-menu-add custom-mode-menu) - (make-local-variable 'custom-options) - (run-hooks 'custom-mode-hook)) - -;;; Custom Mode Commands. - (defun custom-set () "Set changes in all modified options." (interactive) @@ -473,21 +547,17 @@ ;;;###autoload (defun customize-variable (symbol) "Customize SYMBOL, which must be a variable." - (interactive - ;; Code stolen from `help.el'. - (let ((v (variable-at-point)) - (enable-recursive-minibuffers t) - val) - (setq val (completing-read - (if v - (format "Customize variable (default %s): " v) - "Customize variable: ") - obarray 'boundp t)) - (list (if (equal val "") - v (intern val))))) + (interactive (custom-variable-prompt)) (custom-buffer-create (list (list symbol 'custom-variable)))) ;;;###autoload +(defun customize-variable-other-window (symbol) + "Customize SYMBOL, which must be a variable. +Show the buffer in another window, but don't select it." + (interactive (custom-variable-prompt)) + (custom-buffer-create-other-window (list (list symbol 'custom-variable)))) + +;;;###autoload (defun customize-face (&optional symbol) "Customize SYMBOL, which should be a face name or nil. If SYMBOL is nil, customize all faces." @@ -498,7 +568,10 @@ (message "Looking for faces...") (mapcar (lambda (symbol) (setq found (cons (list symbol 'custom-face) found))) - (face-list)) + (nreverse (mapcar 'intern + (sort (mapcar 'symbol-name (face-list)) + 'string<)))) + (custom-buffer-create found)) (if (stringp symbol) (setq symbol (intern symbol))) @@ -507,6 +580,19 @@ (custom-buffer-create (list (list symbol 'custom-face))))) ;;;###autoload +(defun customize-face-other-window (&optional symbol) + "Show customization buffer for FACE in other window." + (interactive (list (completing-read "Customize face: " + obarray 'custom-facep))) + (if (or (null symbol) (and (stringp symbol) (zerop (length symbol)))) + () + (if (stringp symbol) + (setq symbol (intern symbol))) + (unless (symbolp symbol) + (error "Should be a symbol %S" symbol)) + (custom-buffer-create-other-window (list (list symbol 'custom-face))))) + +;;;###autoload (defun customize-customized () "Customize all already customized user options." (interactive) @@ -554,9 +640,24 @@ OPTIONS should be an alist of the form ((SYMBOL WIDGET)...), where SYMBOL is a customization option, and WIDGET is a widget for editing that option." - (message "Creating customization buffer...") (kill-buffer (get-buffer-create "*Customization*")) (switch-to-buffer (get-buffer-create "*Customization*")) + (custom-buffer-create-internal options)) + +(defun custom-buffer-create-other-window (options) + "Create a buffer containing OPTIONS. +OPTIONS should be an alist of the form ((SYMBOL WIDGET)...), where +SYMBOL is a customization option, and WIDGET is a widget for editing +that option." + (kill-buffer (get-buffer-create "*Customization*")) + (let ((window (selected-window))) + (switch-to-buffer-other-window (get-buffer-create "*Customization*")) + (custom-buffer-create-internal options) + (select-window window))) + + +(defun custom-buffer-create-internal (options) + (message "Creating customization buffer...") (custom-mode) (widget-insert "This is a customization buffer. Push RET or click mouse-2 on the word ") @@ -634,6 +735,7 @@ (message "Creating customization setup...") (widget-setup) (goto-char (point-min)) + (forward-char) ;Kludge: bob is writable in XEmacs. (message "Creating customization buffer...done")) ;;; Modification of Basic Widgets. @@ -796,7 +898,8 @@ (string :tag "Magic") face (string :tag "Description")))) - :group 'customize) + :group 'customize + :group 'custom-faces) (defcustom custom-magic-show 'long "Show long description of the state of each customization option." @@ -999,22 +1102,27 @@ (t (funcall show widget value))))) +(defvar custom-load-recursion nil + "Hack to avoid recursive dependencies.") + (defun custom-load-symbol (symbol) "Load all dependencies for SYMBOL." - (let ((loads (get symbol 'custom-loads)) - load) - (while loads - (setq load (car loads) - loads (cdr loads)) - (cond ((symbolp load) - (condition-case nil - (require load) - (error nil))) - ((assoc load load-history)) - (t - (condition-case nil - (load-library load) - (error nil))))))) + (unless custom-load-recursion + (let ((custom-load-recursion t) + (loads (get symbol 'custom-loads)) + load) + (while loads + (setq load (car loads) + loads (cdr loads)) + (cond ((symbolp load) + (condition-case nil + (require load) + (error nil))) + ((assoc load load-history)) + (t + (condition-case nil + (load-library load) + (error nil)))))))) (defun custom-load-widget (widget) "Load all dependencies for WIDGET." @@ -1024,11 +1132,11 @@ (defface custom-variable-sample-face '((t (:underline t))) "Face used for unpushable variable tags." - :group 'customize) + :group 'custom-faces) (defface custom-variable-button-face '((t (:underline t :bold t))) "Face used for pushable variable tags." - :group 'customize) + :group 'custom-faces) (define-widget 'custom-variable 'custom "Customize variable." @@ -1051,7 +1159,8 @@ If SYMBOL has a `custom-type' property, use that. Otherwise, look up symbol in `custom-guess-type-alist'." (let* ((type (or (get symbol 'custom-type) - (custom-guess-type symbol) + (and (not (get symbol 'factory-value)) + (custom-guess-type symbol)) 'sexp)) (options (get symbol 'custom-options)) (tmp (if (listp type) @@ -1213,10 +1322,10 @@ (goto-char (widget-get val :from)) (error "%s" (widget-get val :error))) ((eq form 'lisp) - (set symbol (eval (setq val (widget-value child)))) + (set-default symbol (eval (setq val (widget-value child)))) (put symbol 'customized-value (list val))) (t - (set symbol (setq val (widget-value child))) + (set-default symbol (setq val (widget-value child))) (put symbol 'customized-value (list (custom-quote val))))) (custom-variable-state-set widget) (custom-redraw-magic widget))) @@ -1235,12 +1344,12 @@ (error "%s" (widget-get val :error))) ((eq form 'lisp) (put symbol 'saved-value (list (widget-value child))) - (set symbol (eval (widget-value child)))) + (set-default symbol (eval (widget-value child)))) (t (put symbol 'saved-value (list (custom-quote (widget-value child)))) - (set symbol (widget-value child)))) + (set-default symbol (widget-value child)))) (put symbol 'customized-value nil) (custom-save-all) (custom-variable-state-set widget) @@ -1251,7 +1360,7 @@ (let ((symbol (widget-value widget))) (if (get symbol 'saved-value) (condition-case nil - (set symbol (eval (car (get symbol 'saved-value)))) + (set-default symbol (eval (car (get symbol 'saved-value)))) (error nil)) (error "No saved value for %s" symbol)) (put symbol 'customized-value nil) @@ -1262,7 +1371,7 @@ "Restore the factory setting for the variable being edited by WIDGET." (let ((symbol (widget-value widget))) (if (get symbol 'factory-value) - (set symbol (eval (car (get symbol 'factory-value)))) + (set-default symbol (eval (car (get symbol 'factory-value)))) (error "No factory default for %S" symbol)) (put symbol 'customized-value nil) (when (get symbol 'saved-value) @@ -1362,7 +1471,7 @@ (defface custom-face-tag-face '((t (:underline t))) "Face used for face tags." - :group 'customize) + :group 'custom-faces) (define-widget 'custom-face 'custom "Customize face." @@ -1664,7 +1773,7 @@ and so forth. The remaining group tags are shown with `custom-group-tag-face'." :type '(repeat face) - :group 'customize) + :group 'custom-faces) (defface custom-group-tag-face-1 '((((class color) (background dark)) @@ -1683,7 +1792,7 @@ (:foreground "blue" :underline t)) (t (:underline t))) "Face used for low level group tags." - :group 'customize) + :group 'custom-faces) (define-widget 'custom-group 'custom "Customize group." @@ -2004,16 +2113,12 @@ (custom-menu-create symbol)))) ;;;###autoload -(defun custom-menu-create (symbol &optional name) +(defun custom-menu-create (symbol) "Create menu for customization group SYMBOL. -If optional NAME is given, use that as the name of the menu. -Otherwise make up a name from SYMBOL. The menu is in a format applicable to `easy-menu-define'." - (unless name - (setq name (custom-unlispify-menu-entry symbol))) - (let ((item (vector name - `(custom-buffer-create '((,symbol custom-group))) - t))) + (let* ((item (vector (custom-unlispify-menu-entry symbol) + `(custom-buffer-create '((,symbol custom-group))) + t))) (if (and (or (not (boundp 'custom-menu-nesting)) (>= custom-menu-nesting 0)) (< (length (get symbol 'custom-group)) widget-menu-max-size)) @@ -2031,46 +2136,78 @@ (get symbol 'custom-group)))) item))) -;;; Dependencies. +;;;###autoload +(defun customize-menu-create (symbol &optional name) + "Return a customize menu for customization group SYMBOL. +If optional NAME is given, use that as the name of the menu. +Otherwise the menu will be named `Customize'. +The format is suitable for use with `easy-menu-define'." + (unless name + (setq name "Customize")) + (if (string-match "XEmacs" emacs-version) + ;; We can delay it under XEmacs. + `(,name + :filter (lambda (&rest junk) + (cdr (custom-menu-create ',symbol)))) + ;; But we must create it now under Emacs. + (cons name (cdr (custom-menu-create symbol))))) + +;;; The Custom Mode. + +(defvar custom-mode-map nil + "Keymap for `custom-mode'.") + +(unless custom-mode-map + (setq custom-mode-map (make-sparse-keymap)) + (set-keymap-parent custom-mode-map widget-keymap) + (define-key custom-mode-map "q" 'bury-buffer)) + +(easy-menu-define custom-mode-customize-menu + custom-mode-map + "Menu used in customization buffers." + (customize-menu-create 'customize)) -;;;###autoload -(defun custom-make-dependencies () - "Batch function to extract custom dependencies from .el files. -Usage: emacs -batch *.el -f custom-make-dependencies > deps.el" - (let ((buffers (buffer-list))) - (while buffers - (set-buffer (car buffers)) - (setq buffers (cdr buffers)) - (let ((file (buffer-file-name))) - (when (and file (string-match "\\`\\(.*\\)\\.el\\'" file)) - (goto-char (point-min)) - (condition-case nil - (let ((name (file-name-nondirectory (match-string 1 file)))) - (while t - (let ((expr (read (current-buffer)))) - (when (and (listp expr) - (memq (car expr) '(defcustom defface defgroup))) - (eval expr) - (put (nth 1 expr) 'custom-where name))))) - (error nil)))))) - (mapatoms (lambda (symbol) - (let ((members (get symbol 'custom-group)) - item where found) - (when members - (princ "(put '") - (princ symbol) - (princ " 'custom-loads '(") - (while members - (setq item (car (car members)) - members (cdr members) - where (get item 'custom-where)) - (unless (or (null where) - (member where found)) - (when found - (princ " ")) - (prin1 where) - (push where found))) - (princ "))\n")))))) +(easy-menu-define custom-mode-menu + custom-mode-map + "Menu used in customization buffers." + `("Custom" + ["Set" custom-set t] + ["Save" custom-save t] + ["Reset to Current" custom-reset-current t] + ["Reset to Saved" custom-reset-saved t] + ["Reset to Factory Settings" custom-reset-factory t] + ["Info" (Info-goto-node "(custom)The Customization Buffer") t])) + +(defcustom custom-mode-hook nil + "Hook called when entering custom-mode." + :type 'hook + :group 'customize) + +(defun custom-mode () + "Major mode for editing customization buffers. + +The following commands are available: + +Move to next button or editable field. \\[widget-forward] +Move to previous button or editable field. \\[widget-backward] +Activate button under the mouse pointer. \\[widget-button-click] +Activate button under point. \\[widget-button-press] +Set all modifications. \\[custom-set] +Make all modifications default. \\[custom-save] +Reset all modified options. \\[custom-reset-current] +Reset all modified or set options. \\[custom-reset-saved] +Reset all options. \\[custom-reset-factory] + +Entry to this mode calls the value of `custom-mode-hook' +if that value is non-nil." + (kill-all-local-variables) + (setq major-mode 'custom-mode + mode-name "Custom") + (use-local-map custom-mode-map) + (easy-menu-add custom-mode-customize-menu) + (easy-menu-add custom-mode-menu) + (make-local-variable 'custom-options) + (run-hooks 'custom-mode-hook)) ;;; The End.