* lisp/simple.el (async-shell-command-buffer): New defcustom.
[bpt/emacs.git] / lisp / minibuf-eldef.el
CommitLineData
66d058c4
MB
1;;; minibuf-eldef.el --- Only show defaults in prompts when applicable
2;;
acaf905b 3;; Copyright (C) 2000-2012 Free Software Foundation, Inc.
66d058c4
MB
4;;
5;; Author: Miles Bader <miles@gnu.org>
6;; Keywords: convenience
7
8;; This file is part of GNU Emacs.
9
eb3fa2cf 10;; GNU Emacs is free software: you can redistribute it and/or modify
66d058c4 11;; it under the terms of the GNU General Public License as published by
eb3fa2cf
GM
12;; the Free Software Foundation, either version 3 of the License, or
13;; (at your option) any later version.
66d058c4
MB
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
eb3fa2cf 21;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
66d058c4
MB
22
23;;; Commentary:
24;;
25;; Defines the mode `minibuffer-electric-default-mode'.
26;;
27;; When active, minibuffer prompts that show a default value only show
28;; the default when it's applicable -- that is, when hitting RET would
29;; yield the default value. If the user modifies the input such that
30;; hitting RET would enter a non-default value, the prompt is modified
31;; to remove the default indication (which is restored if the input is
32;; ever restore to the match the initial input).
33
34;;; Code:
35
36(defvar minibuffer-default-in-prompt-regexps
2bb680b0 37 '(("\\( (default\\>.*)\\):? \\'" . 1) ("\\( \\[.*\\]\\):? *\\'" . 1))
fb7ada5f 38 "A list of regexps matching the parts of minibuffer prompts showing defaults.
66d058c4
MB
39When `minibuffer-electric-default-mode' is active, these regexps are
40used to identify the portions of prompts to elide.
41
42Each entry is either a string, which should be a regexp matching the
43default portion of the prompt, or a cons cell, who's car is a regexp
44matching the default part of the prompt, and who's cdr indicates the
45regexp subexpression that matched.")
46
47\f
48;;; Internal variables
49
50;; A list of minibuffers to which we've added a post-command-hook.
51(defvar minibuf-eldef-frobbed-minibufs nil)
f1180544 52
66d058c4
MB
53;;; The following are all local variables in the minibuffer
54
55;; Input pre-inserted into the minibuffer before the user can edit it.
56(defvar minibuf-eldef-initial-input)
57(make-variable-buffer-local 'minibuf-eldef-initial-input)
58;; and the length of the buffer with it inserted.
59(defvar minibuf-eldef-initial-buffer-length)
60(make-variable-buffer-local 'minibuf-eldef-initial-buffer-length)
61
62;; True if the current minibuffer prompt contains the default spec.
63(defvar minibuf-eldef-showing-default-in-prompt)
64(make-variable-buffer-local 'minibuf-eldef-showing-default-in-prompt)
65
66;; An overlay covering the default portion of the prompt
67(defvar minibuf-eldef-overlay)
68(make-variable-buffer-local 'minibuf-eldef-overlay)
69
70\f
71;;; Hook functions
72
73;; This function goes on minibuffer-setup-hook
74(defun minibuf-eldef-setup-minibuffer ()
75 "Set up a minibuffer for `minibuffer-electric-default-mode'.
76The prompt and initial input should already have been inserted."
8bbb7c70 77 (let ((regexps minibuffer-default-in-prompt-regexps)
66d058c4
MB
78 (match nil)
79 (inhibit-point-motion-hooks t))
80 (save-excursion
81 (save-restriction
82 ;; Narrow to only the prompt
83 (goto-char (point-min))
8bbb7c70 84 (narrow-to-region (point) (minibuffer-prompt-end))
66d058c4
MB
85 ;; See the prompt contains a default input indicator
86 (while regexps
87 (setq match (pop regexps))
88 (if (re-search-forward (if (stringp match) match (car match)) nil t)
89 (setq regexps nil)
90 (setq match nil)))))
91 (if (not match)
92 ;; Nope, so just make sure our post-command-hook isn't left around.
93 (remove-hook 'post-command-hook #'minibuf-eldef-update-minibuffer t)
94 ;; Yup; set things up so we can frob the prompt as the state of
95 ;; the input string changes.
96 (setq match (if (consp match) (cdr match) 0))
97 (setq minibuf-eldef-overlay
98 (make-overlay (match-beginning match) (match-end match)))
99 (setq minibuf-eldef-showing-default-in-prompt t)
100 (setq minibuf-eldef-initial-input
8bbb7c70 101 (minibuffer-contents-no-properties))
66d058c4
MB
102 (setq minibuf-eldef-initial-buffer-length (point-max))
103 (add-to-list 'minibuf-eldef-frobbed-minibufs (current-buffer))
104 (add-hook 'post-command-hook #'minibuf-eldef-update-minibuffer nil t))))
105
106;; post-command-hook to swap prompts when necessary
107(defun minibuf-eldef-update-minibuffer ()
108 "Update a minibuffer's prompt to include a default only when applicable.
109This is intended to be used as a minibuffer post-command-hook for
110`minibuffer-electric-default-mode'; the minibuffer should have already
111been set up by `minibuf-eldef-setup-minibuffer'."
112 (unless (eq minibuf-eldef-showing-default-in-prompt
113 (and (= (point-max) minibuf-eldef-initial-buffer-length)
8bbb7c70 114 (string-equal (minibuffer-contents-no-properties)
66d058c4
MB
115 minibuf-eldef-initial-input)))
116 ;; swap state
117 (setq minibuf-eldef-showing-default-in-prompt
118 (not minibuf-eldef-showing-default-in-prompt))
119 (cond (minibuf-eldef-showing-default-in-prompt
120 (overlay-put minibuf-eldef-overlay 'invisible nil)
121 (overlay-put minibuf-eldef-overlay 'intangible nil))
122 (t
123 (overlay-put minibuf-eldef-overlay 'invisible t)
124 (overlay-put minibuf-eldef-overlay 'intangible t)))))
125
126\f
127;;; Note this definition must be at the end of the file, because
128;;; `define-minor-mode' actually calls the mode-function if the
129;;; associated variable is non-nil, which requires that all needed
130;;; functions be already defined. [This is arguably a bug in d-m-m]
131;;;###autoload
132(define-minor-mode minibuffer-electric-default-mode
35cd0213 133 "Toggle Minibuffer Electric Default mode.
06e21633
CY
134With a prefix argument ARG, enable Minibuffer Electric Default
135mode if ARG is positive, and disable it otherwise. If called
136from Lisp, enable the mode if ARG is omitted or nil.
137
138Minibuffer Electric Default mode is a global minor mode. When
139enabled, minibuffer prompts that show a default value only show
140the default when it's applicable -- that is, when hitting RET
141would yield the default value. If the user modifies the input
142such that hitting RET would enter a non-default value, the prompt
143is modified to remove the default indication."
66d058c4
MB
144 :global t
145 :group 'minibuffer
146 (if minibuffer-electric-default-mode
147 ;; Enable the mode
148 (add-hook 'minibuffer-setup-hook 'minibuf-eldef-setup-minibuffer)
149 ;; Disable the mode
150 (remove-hook 'minibuffer-setup-hook 'minibuf-eldef-setup-minibuffer)
151 ;; Remove our entry from any post-command-hook variable's it's still in
152 (dolist (minibuf minibuf-eldef-frobbed-minibufs)
153 (with-current-buffer minibuf
154 (remove-hook 'post-command-hook #'minibuf-eldef-update-minibuffer t)))
155 (setq minibuf-eldef-frobbed-minibufs nil)))
156
157
158(provide 'minibuf-eldef)
159
160;;; minibuf-eldef.el ends here