commit a51ad175ee8e345b1ae5631f6d2ae6aafcb6fc0e Author: Thierry Volpiatto Date: Sat Jul 2 15:39:24 2011 +0200 eldoc-in-minibuffer Introduce eldoc support for minibuffer. * lisp/emacs-lisp/eldoc.el (eldoc-in-minibuffer, eldoc-in-minibuffer-show-fn, eldoc-show-in-mode-line-delay,): New user variables (with-eldoc-in-minibuffer): Macro to enable eldoc support in any code that use minibuffer as input. (eldoc-show-in-mode-line, eldoc-mode-in-minibuffer, eldoc-store-minibuffer): New, used by `with-eldoc-in-minibuffer' * lisp/emacs-lisp/pp.el (pp-eval-expression): Enable eldoc support. * lisp/simple.el (eval-expression): Same. * lisp/emacs-lisp/edebug.el (edebug-eval-expression): Same. diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index f84de03..ccc3c8d 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -3702,13 +3702,15 @@ Return the result of the last expression." (defalias 'edebug-format 'format) (defalias 'edebug-message 'message) + (defun edebug-eval-expression (edebug-expr) "Evaluate an expression in the outside environment. If interactive, prompt for the expression. Print result in minibuffer." - (interactive (list (read-from-minibuffer - "Eval: " nil read-expression-map t - 'read-expression-history))) + (interactive (list (with-eldoc-in-minibuffer + (read-from-minibuffer + "Eval: " nil read-expression-map t + 'read-expression-history)))) (princ (edebug-outside-excursion (setq values (cons (edebug-eval edebug-expr) values)) diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el index cd9b779..e43b4ce 100644 --- a/lisp/emacs-lisp/eldoc.el +++ b/lisp/emacs-lisp/eldoc.el @@ -204,6 +204,92 @@ With prefix ARG, turn ElDoc mode on if and only if ARG is positive." (omessage (message nil))))) eldoc-last-message) +;;; Minibuffer support. +;; Enable displaying eldoc info in something else +;; Than minibuffer when this one is in use. +;; +(defcustom eldoc-in-minibuffer t + "Turn on eldoc in minibuffer." + :group 'eldoc + :type 'bolean) + +(defcustom eldoc-in-minibuffer-show-fn 'eldoc-show-in-mode-line + "A function to display eldoc info. +Should take one arg: the string to display" + :group 'eldoc + :type 'function) + +(defcustom eldoc-show-in-mode-line-delay 12 + "The time we show eldoc when emacs is idle." + :group 'eldoc + :type 'number) + +;; Internal. +(defvar eldoc-active-minibuffers-list nil + "Store actives minibuffers with eldoc enabled.") + +(defun eldoc-store-minibuffer () + "Store minibuffer buffer name in `eldoc-active-minibuffers-list'. +This function is called by each minibuffer started with eldoc support. +See `with-eldoc-in-minibuffer'." + (with-selected-window (minibuffer-window) + (push (buffer-name) eldoc-active-minibuffers-list))) + +(defmacro with-eldoc-in-minibuffer (&rest body) + "Enable eldoc support for minibuffer input that run in BODY." + (declare (indent 0) (debug t)) + `(let ((timer (and eldoc-in-minibuffer + (run-with-idle-timer + eldoc-idle-delay + 'repeat 'eldoc-mode-in-minibuffer)))) + (unwind-protect + (minibuffer-with-setup-hook + ;; When minibuffer is activated in body, + ;; store it. + 'eldoc-store-minibuffer + ,@body) + (and timer (cancel-timer timer)) + ;; Each time a minibuffer exit or abort + ;; his buffer is removed from stack, + ;; assuming we can only exit the active minibuffer + ;; on top of stack. + (setq eldoc-active-minibuffers-list + (cdr eldoc-active-minibuffers-list))))) + +(defun eldoc-show-in-mode-line (str) + "Display string STR in the mode-line next to minibuffer." + (let (mode-line-in-non-selected-windows) + (with-current-buffer (window-buffer + (with-selected-frame (selected-frame) + (window-in-direction + 'above (minibuffer-window)))) + (make-local-variable 'mode-line-format) + (let ((mode-line-format (concat " " str))) + (force-mode-line-update nil) + (sit-for eldoc-show-in-mode-line-delay)) + (force-mode-line-update)))) + +(defun eldoc-mode-in-minibuffer () + "Show eldoc for current minibuffer input." + (let ((buf (with-selected-window (minibuffer-window) + (buffer-name)))) + ;; If this minibuffer have been started with + ;;`with-eldoc-in-minibuffer' give it eldoc support + ;; and update mode-line, otherwise do nothing. + (when (member buf eldoc-active-minibuffers-list) + (let* ((str-all (minibuffer-completion-contents)) + (sym (when str-all + (with-temp-buffer + (insert str-all) + (goto-char (point-max)) + (unless (looking-back ")\\|\"") + (forward-char -1)) + (eldoc-current-symbol)))) + (doc (or (eldoc-get-var-docstring sym) + (eldoc-get-fnsym-args-string + (car (eldoc-fnsym-in-current-sexp)))))) + (when doc (funcall eldoc-in-minibuffer-show-fn doc)))))) + ;; This function goes on pre-command-hook for XEmacs or when using idle ;; timers in Emacs. Motion commands clear the echo area for some reason, ;; which make eldoc messages flicker or disappear just before motion diff --git a/lisp/emacs-lisp/pp.el b/lisp/emacs-lisp/pp.el index 2d1b886..13dd650 100644 --- a/lisp/emacs-lisp/pp.el +++ b/lisp/emacs-lisp/pp.el @@ -133,8 +133,9 @@ after OUT-BUFFER-NAME." "Evaluate EXPRESSION and pretty-print its value. Also add the value to the front of the list in the variable `values'." (interactive - (list (read-from-minibuffer "Eval: " nil read-expression-map t - 'read-expression-history))) + (list (with-eldoc-in-minibuffer + (read-from-minibuffer "Eval: " nil read-expression-map t + 'read-expression-history)))) (message "Evaluating...") (setq values (cons (eval expression) values)) (pp-display-expression (car values) "*Pp Eval Output*")) diff --git a/lisp/simple.el b/lisp/simple.el index b36cf2e..7ed5ea3 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -1163,9 +1163,10 @@ If `eval-expression-debug-on-error' is non-nil, which is the default, this command arranges for all errors to enter the debugger." (interactive (list (let ((minibuffer-completing-symbol t)) - (read-from-minibuffer "Eval: " - nil read-expression-map t - 'read-expression-history)) + (with-eldoc-in-minibuffer + (read-from-minibuffer "Eval: " + nil read-expression-map t + 'read-expression-history))) current-prefix-arg)) (if (null eval-expression-debug-on-error)