]> code.delx.au - gnu-emacs-elpa/blobdiff - packages/eldoc-eval/eldoc-eval.el
Merge commit '4709fc4530da4ddfd29b910763c801292b228f69' from diff-hl
[gnu-emacs-elpa] / packages / eldoc-eval / eldoc-eval.el
index e157bdcdf466665d7da858160676a6b11d730734..bf208e041e2442544bdf9537df6a7f18363a40c9 100644 (file)
@@ -1,6 +1,6 @@
 ;;; eldoc-eval.el --- Enable eldoc support when minibuffer is in use.
 
-;; Copyright (C) 2011 Free Software Foundation, Inc.
+;; Copyright (C) 2011, 2012, 2013 Free Software Foundation, Inc.
 
 ;; Author: Thierry Volpiatto <thierry.volpiatto@gmail.com>
 ;; Version: 0.1
 
 ;;; Commentary:
 ;;
-;; This package enable eldoc support when minibuffer is in use.
+;; This package enables eldoc support when minibuffer is in use.
 ;;
-;; Eldoc info are shown by default in mode-line.
+;; Eldoc info is shown by default in mode-line,
 ;; but you can have eldoc info somewhere else by setting
-;; `eldoc-in-minibuffer-show-fn' to an other function (e.g `tooltip-show').
+;; `eldoc-in-minibuffer-show-fn' to another function (e.g `tooltip-show').
 ;;
 ;; By default with this package `M-:' will use `pp-eval-expression'
-;; instead of `eval-expression'; You can change that in
-;; `eval-prefered-function'.
+;; instead of `eval-expression'; you can change that by setting
+;; `eldoc-eval-preferred-function'.
 ;;
-;; It provide also a convenient macro to enable eldoc support
+;; It also provides a convenient macro to enable eldoc support
 ;; in your own functions using minibuffer or in your defadvices,
 ;; that is `with-eldoc-in-minibuffer'.
 ;;
 ;; Users of own minibuffer frame will have to set
-;; `eldoc-in-minibuffer-own-frame-p' to non--nil.
+;; `eldoc-in-minibuffer-own-frame-p' to non-nil.
 ;;
-;; You can turn off at anytime eldoc support in minibuffer
-;; by setting `eldoc-in-minibuffer' to nil.
+;; You can turn On/Off eldoc support in minibuffer any time
+;; with `eldoc-in-minibuffer-mode'.
+;;
+;;; Install:
+;; Add to .emacs:
+;;
+;;   (autoload 'eldoc-in-minibuffer-mode "eldoc-eval")
+;;   (eldoc-in-minibuffer-mode 1)
+
 
 ;;; Code:
 (require 'eldoc)
 
-
 ;;; 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)
+(defgroup eldoc-eval nil
+  "Show eldoc infos in mode line while minibuffer is in use."
+  :group 'eldoc)
 
 (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)
 
-(defcustom eval-prefered-function 'pp-eval-expression
-  "Prefered function to use with `M-:'."
-  :group 'lisp
+(defcustom eldoc-eval-preferred-function 'pp-eval-expression
+  "Preferred function to use with `M-:'."
   :type 'function)
 
 (defcustom  eldoc-in-minibuffer-own-frame-p nil
-  "Whether minibuffer have own frame or not."
-  :group 'lisp
+  "Whether minibuffer has its own frame or not."
   :type 'boolean)
 
+;;; Compatibility with Emacs-24.4
+;; New implementation of eldoc in minibuffer that come
+;; with Emacs-24.4 show the eldoc info of current-buffer while
+;; minibuffer is in use, disable this and inline old Emacs behavior.
+;;
+(defconst eldoc-eval--old-message-function
+  (and (boundp 'eldoc-message-function) eldoc-message-function))
+
+(defadvice eldoc-display-message-no-interference-p
+    (after eldoc-eval activate)
+  (when eldoc-in-minibuffer-mode
+    (setq ad-return-value
+          (and ad-return-value
+               ;; Having this mode operate in an active minibuffer/echo area
+               ;; causes interference with what's going on there.
+               (not cursor-in-echo-area)
+               (not (eq (selected-window) (minibuffer-window)))))))
+
 ;; Internal.
 (defvar eldoc-active-minibuffers-list nil
-  "Store actives minibuffers with eldoc enabled.")
+  "List of active minibuffers with eldoc enabled.")
 (defvar eldoc-mode-line-rolling-flag nil)
 
 (defun eldoc-store-minibuffer ()
@@ -86,31 +105,30 @@ Should take one arg: the string to display"
 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)))
+    (push (current-buffer) eldoc-active-minibuffers-list)))
 
 (defmacro with-eldoc-in-minibuffer (&rest body)
-  "Enable eldoc support for minibuffer input that run in BODY."
+  "Enable eldoc support for minibuffer input that runs in BODY."
   (declare (indent 0) (debug t))
-  `(let ((timer (and eldoc-in-minibuffer
+  `(let ((timer (and eldoc-in-minibuffer-mode
                      (run-with-idle-timer
                       eldoc-idle-delay
-                      'repeat 'eldoc-mode-in-minibuffer))))
+                      'repeat #'eldoc-run-in-minibuffer))))
      (unwind-protect
          (minibuffer-with-setup-hook
-             ;; When minibuffer is activated in body,
-             ;; store it.
-             'eldoc-store-minibuffer
+             ;; 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,
+       ;; Each time a minibuffer exits or aborts
+       ;; its 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-current-buffer ()
-  "The `current-buffer' before activating minibuffer."
+  "Return the current buffer prior to activating the minibuffer."
   (with-selected-frame (last-nonminibuffer-frame)
     (window-buffer
      (cond (eldoc-in-minibuffer-own-frame-p
@@ -144,40 +162,63 @@ See `with-eldoc-in-minibuffer'."
 
 (defun eldoc-mode-line-toggle-rolling ()
   (interactive)
-  (setq eldoc-mode-line-rolling-flag (not eldoc-mode-line-rolling-flag)))
-(define-key minibuffer-local-map (kbd "<C-M-right>") 'eldoc-mode-line-toggle-rolling)
-
-(defun eldoc-mode-in-minibuffer ()
-  "Show eldoc for current minibuffer input."
-  (let ((buf (with-selected-window (minibuffer-window)
-               (buffer-name))))
+  (if (and eldoc-in-minibuffer-mode
+           (minibuffer-window-active-p (selected-window)))
+      (setq eldoc-mode-line-rolling-flag (not eldoc-mode-line-rolling-flag))
+      (error "No active minibuffer found")))
+
+(defvar eldoc-in-minibuffer-mode-map
+  (let ((map (make-sparse-keymap)))
+    ;; FIXME: Should we use [remap eval-expression] instead?
+    (define-key map (kbd "M-:") 'eldoc-eval-expression)
+    map))
+
+;;;###autoload
+(define-minor-mode eldoc-in-minibuffer-mode
+    "Show eldoc for current minibuffer input."
+  :global t
+  (if eldoc-in-minibuffer-mode
+      (progn
+        (add-hook 'minibuffer-exit-hook
+                  (lambda ()
+                    (setq eldoc-mode-line-rolling-flag nil)))
+        (and (boundp 'eldoc-message-function)
+             (setq eldoc-message-function 'message))
+        (define-key minibuffer-local-map (kbd "C-@")
+          'eldoc-mode-line-toggle-rolling)
+        (setq eldoc-minor-mode-string " Eldoc-eval"))
+      (setq eldoc-minor-mode-string " Eldoc")
+      (and (boundp 'eldoc-message-function)
+           (setq eldoc-message-function eldoc-eval--old-message-function))
+      (define-key minibuffer-local-map (kbd "C-@") 'set-mark-command)))
+
+(defun eldoc-run-in-minibuffer ()
+  (let ((buf (window-buffer (active-minibuffer-window))))
     ;; 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 (with-current-buffer buf
-                        (minibuffer-completion-contents)))
-             (sym     (when str-all
-                        (with-temp-buffer
-                          (insert str-all)
-                          (goto-char (point-max))
+    (condition-case err
+        (when (member buf eldoc-active-minibuffers-list)
+          (with-current-buffer buf
+            (let* ((sym (save-excursion
                           (unless (looking-back ")\\|\"")
                             (forward-char -1))
-                          (eldoc-current-symbol))))
-             (info-fn (eldoc-fnsym-in-current-sexp))
-             (doc     (or (eldoc-get-var-docstring sym)
-                          (eldoc-get-fnsym-args-string
-                           (car info-fn) (cadr info-fn)))))
-        (when doc (funcall eldoc-in-minibuffer-show-fn doc))))))
-
-(defun eval-expression-with-eldoc ()
+                          (eldoc-current-symbol)))
+                   (info-fn (eldoc-fnsym-in-current-sexp))
+                   (doc     (or (eldoc-get-var-docstring sym)
+                                (eldoc-get-fnsym-args-string
+                                 (car info-fn) (cadr info-fn)))))
+              (when doc (funcall eldoc-in-minibuffer-show-fn doc)))))
+      (scan-error nil)
+      (beginning-of-buffer nil)
+      (error (message "Eldoc in minibuffer error: %S" err)))))
+
+;;;###autoload
+(defun eldoc-eval-expression ()
   "Eval expression with eldoc support in mode-line."
   (interactive)
   (with-eldoc-in-minibuffer
-    (call-interactively eval-prefered-function)))
-
-;; Bind it to `M-:'.
-(global-set-key [remap eval-expression] 'eval-expression-with-eldoc)
+    (call-interactively eldoc-eval-preferred-function)))
 
 
 (provide 'eldoc-eval)