1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-26 07:33:47 +00:00
emacs/lisp/minibuf-eldef.el

161 lines
6.6 KiB
EmacsLisp
Raw Normal View History

2000-12-09 04:02:59 +00:00
;;; minibuf-eldef.el --- Only show defaults in prompts when applicable
;;
;; Copyright (C) 2000-2012 Free Software Foundation, Inc.
2000-12-09 04:02:59 +00:00
;;
;; Author: Miles Bader <miles@gnu.org>
;; Keywords: convenience
;; This file is part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
2000-12-09 04:02:59 +00:00
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
2000-12-09 04:02:59 +00:00
;; GNU Emacs 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 GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
2000-12-09 04:02:59 +00:00
;;; Commentary:
;;
;; Defines the mode `minibuffer-electric-default-mode'.
;;
;; When active, minibuffer prompts that show a default value only show
;; the default when it's applicable -- that is, when hitting RET would
;; yield the default value. If the user modifies the input such that
;; hitting RET would enter a non-default value, the prompt is modified
;; to remove the default indication (which is restored if the input is
;; ever restore to the match the initial input).
;;; Code:
(defvar minibuffer-default-in-prompt-regexps
'(("\\( (default\\>.*)\\):? \\'" . 1) ("\\( \\[.*\\]\\):? *\\'" . 1))
2000-12-09 04:02:59 +00:00
"*A list of regexps matching the parts of minibuffer prompts showing defaults.
When `minibuffer-electric-default-mode' is active, these regexps are
used to identify the portions of prompts to elide.
Each entry is either a string, which should be a regexp matching the
default portion of the prompt, or a cons cell, who's car is a regexp
matching the default part of the prompt, and who's cdr indicates the
regexp subexpression that matched.")
;;; Internal variables
;; A list of minibuffers to which we've added a post-command-hook.
(defvar minibuf-eldef-frobbed-minibufs nil)
2003-02-04 12:29:42 +00:00
2000-12-09 04:02:59 +00:00
;;; The following are all local variables in the minibuffer
;; Input pre-inserted into the minibuffer before the user can edit it.
(defvar minibuf-eldef-initial-input)
(make-variable-buffer-local 'minibuf-eldef-initial-input)
;; and the length of the buffer with it inserted.
(defvar minibuf-eldef-initial-buffer-length)
(make-variable-buffer-local 'minibuf-eldef-initial-buffer-length)
;; True if the current minibuffer prompt contains the default spec.
(defvar minibuf-eldef-showing-default-in-prompt)
(make-variable-buffer-local 'minibuf-eldef-showing-default-in-prompt)
;; An overlay covering the default portion of the prompt
(defvar minibuf-eldef-overlay)
(make-variable-buffer-local 'minibuf-eldef-overlay)
;;; Hook functions
;; This function goes on minibuffer-setup-hook
(defun minibuf-eldef-setup-minibuffer ()
"Set up a minibuffer for `minibuffer-electric-default-mode'.
The prompt and initial input should already have been inserted."
(let ((regexps minibuffer-default-in-prompt-regexps)
2000-12-09 04:02:59 +00:00
(match nil)
(inhibit-point-motion-hooks t))
(save-excursion
(save-restriction
;; Narrow to only the prompt
(goto-char (point-min))
(narrow-to-region (point) (minibuffer-prompt-end))
2000-12-09 04:02:59 +00:00
;; See the prompt contains a default input indicator
(while regexps
(setq match (pop regexps))
(if (re-search-forward (if (stringp match) match (car match)) nil t)
(setq regexps nil)
(setq match nil)))))
(if (not match)
;; Nope, so just make sure our post-command-hook isn't left around.
(remove-hook 'post-command-hook #'minibuf-eldef-update-minibuffer t)
;; Yup; set things up so we can frob the prompt as the state of
;; the input string changes.
(setq match (if (consp match) (cdr match) 0))
(setq minibuf-eldef-overlay
(make-overlay (match-beginning match) (match-end match)))
(setq minibuf-eldef-showing-default-in-prompt t)
(setq minibuf-eldef-initial-input
(minibuffer-contents-no-properties))
2000-12-09 04:02:59 +00:00
(setq minibuf-eldef-initial-buffer-length (point-max))
(add-to-list 'minibuf-eldef-frobbed-minibufs (current-buffer))
(add-hook 'post-command-hook #'minibuf-eldef-update-minibuffer nil t))))
;; post-command-hook to swap prompts when necessary
(defun minibuf-eldef-update-minibuffer ()
"Update a minibuffer's prompt to include a default only when applicable.
This is intended to be used as a minibuffer post-command-hook for
`minibuffer-electric-default-mode'; the minibuffer should have already
been set up by `minibuf-eldef-setup-minibuffer'."
(unless (eq minibuf-eldef-showing-default-in-prompt
(and (= (point-max) minibuf-eldef-initial-buffer-length)
(string-equal (minibuffer-contents-no-properties)
2000-12-09 04:02:59 +00:00
minibuf-eldef-initial-input)))
;; swap state
(setq minibuf-eldef-showing-default-in-prompt
(not minibuf-eldef-showing-default-in-prompt))
(cond (minibuf-eldef-showing-default-in-prompt
(overlay-put minibuf-eldef-overlay 'invisible nil)
(overlay-put minibuf-eldef-overlay 'intangible nil))
(t
(overlay-put minibuf-eldef-overlay 'invisible t)
(overlay-put minibuf-eldef-overlay 'intangible t)))))
;;; Note this definition must be at the end of the file, because
;;; `define-minor-mode' actually calls the mode-function if the
;;; associated variable is non-nil, which requires that all needed
;;; functions be already defined. [This is arguably a bug in d-m-m]
;;;###autoload
(define-minor-mode minibuffer-electric-default-mode
"Toggle Minibuffer Electric Default mode.
Fix minor mode docstrings for the new meaning of a nil ARG. * abbrev.el (abbrev-mode): * allout.el (allout-mode): * autoinsert.el (auto-insert-mode): * autoarg.el (autoarg-mode, autoarg-kp-mode): * autorevert.el (auto-revert-mode, auto-revert-tail-mode) (global-auto-revert-mode): * battery.el (display-battery-mode): * composite.el (global-auto-composition-mode) (auto-composition-mode): * delsel.el (delete-selection-mode): * desktop.el (desktop-save-mode): * dired-x.el (dired-omit-mode): * dirtrack.el (dirtrack-mode): * doc-view.el (doc-view-minor-mode): * double.el (double-mode): * electric.el (electric-indent-mode, electric-pair-mode): * emacs-lock.el (emacs-lock-mode): * epa-hook.el (auto-encryption-mode): * follow.el (follow-mode): * font-core.el (font-lock-mode): * frame.el (auto-raise-mode, auto-lower-mode, blink-cursor-mode): * help.el (temp-buffer-resize-mode): * hilit-chg.el (highlight-changes-mode) (highlight-changes-visible-mode): * hi-lock.el (hi-lock-mode): * hl-line.el (hl-line-mode, global-hl-line-mode): * icomplete.el (icomplete-mode): * ido.el (ido-everywhere): * image-file.el (auto-image-file-mode): * image-mode.el (image-minor-mode): * iswitchb.el (iswitchb-mode): * jka-cmpr-hook.el (auto-compression-mode): * linum.el (linum-mode): * longlines.el (longlines-mode): * master.el (master-mode): * mb-depth.el (minibuffer-depth-indicate-mode): * menu-bar.el (menu-bar-mode): * minibuf-eldef.el (minibuffer-electric-default-mode): * mouse-sel.el (mouse-sel-mode): * msb.el (msb-mode): * mwheel.el (mouse-wheel-mode): * outline.el (outline-minor-mode): * paren.el (show-paren-mode): * recentf.el (recentf-mode): * reveal.el (reveal-mode, global-reveal-mode): * rfn-eshadow.el (file-name-shadow-mode): * ruler-mode.el (ruler-mode): * savehist.el (savehist-mode): * scroll-all.el (scroll-all-mode): * scroll-bar.el (scroll-bar-mode): * server.el (server-mode): * shell.el (shell-dirtrack-mode): * simple.el (auto-fill-mode, transient-mark-mode) (visual-line-mode, overwrite-mode, binary-overwrite-mode) (line-number-mode, column-number-mode, size-indication-mode) (auto-save-mode, normal-erase-is-backspace-mode, visible-mode): * strokes.el (strokes-mode): * time.el (display-time-mode): * t-mouse.el (gpm-mouse-mode): * tool-bar.el (tool-bar-mode): * tooltip.el (tooltip-mode): * type-break.el (type-break-mode-line-message-mode) (type-break-query-mode): * view.el (view-mode): * whitespace.el (whitespace-mode, whitespace-newline-mode) (global-whitespace-mode, global-whitespace-newline-mode): * xt-mouse.el (xterm-mouse-mode): Doc fix. * emacs-lisp/easy-mmode.el (define-globalized-minor-mode): Fix autogenerated docstring.
2011-10-19 12:54:24 +00:00
With a prefix argument ARG, enable Minibuffer Electric Default
mode if ARG is positive, and disable it otherwise. If called
from Lisp, enable the mode if ARG is omitted or nil.
Minibuffer Electric Default mode is a global minor mode. When
enabled, minibuffer prompts that show a default value only show
the default when it's applicable -- that is, when hitting RET
would yield the default value. If the user modifies the input
such that hitting RET would enter a non-default value, the prompt
is modified to remove the default indication."
2000-12-09 04:02:59 +00:00
:global t
:group 'minibuffer
(if minibuffer-electric-default-mode
;; Enable the mode
(add-hook 'minibuffer-setup-hook 'minibuf-eldef-setup-minibuffer)
;; Disable the mode
(remove-hook 'minibuffer-setup-hook 'minibuf-eldef-setup-minibuffer)
;; Remove our entry from any post-command-hook variable's it's still in
(dolist (minibuf minibuf-eldef-frobbed-minibufs)
(with-current-buffer minibuf
(remove-hook 'post-command-hook #'minibuf-eldef-update-minibuffer t)))
(setq minibuf-eldef-frobbed-minibufs nil)))
(provide 'minibuf-eldef)
;;; minibuf-eldef.el ends here