]> code.delx.au - gnu-emacs-elpa/blobdiff - packages/eldoc-eval/eldoc-eval.el
Merge commit 'aecfbcbc10cf03ec94062ac3e590f8118e5a0434'
[gnu-emacs-elpa] / packages / eldoc-eval / eldoc-eval.el
index 6d20da2413d6a2cb354f548814e2d09a61dab229..bf208e041e2442544bdf9537df6a7f18363a40c9 100644 (file)
@@ -1,6 +1,6 @@
 ;;; eldoc-eval.el --- Enable eldoc support when minibuffer is in use.
 
-;; Copyright (C) 2011, 2012 Free Software Foundation, Inc.
+;; Copyright (C) 2011, 2012, 2013 Free Software Foundation, Inc.
 
 ;; Author: Thierry Volpiatto <thierry.volpiatto@gmail.com>
 ;; Version: 0.1
@@ -30,7 +30,7 @@
 ;;
 ;; By default with this package `M-:' will use `pp-eval-expression'
 ;; instead of `eval-expression'; you can change that by setting
-;; `eval-preferred-function'.
+;; `eldoc-eval-preferred-function'.
 ;;
 ;; It also provides a convenient macro to enable eldoc support
 ;; in your own functions using minibuffer or in your defadvices,
 ;; Users of own minibuffer frame will have to set
 ;; `eldoc-in-minibuffer-own-frame-p' to non-nil.
 ;;
-;; You can turn off eldoc support in minibuffer any time
-;; 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-preferred-function 'pp-eval-expression
+(defcustom eldoc-eval-preferred-function 'pp-eval-expression
   "Preferred function to use with `M-:'."
-  :group 'lisp
   :type 'function)
 
 (defcustom  eldoc-in-minibuffer-own-frame-p nil
   "Whether minibuffer has its own frame or not."
-  :group 'lisp
   :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
   "List of active minibuffers with eldoc enabled.")
@@ -86,20 +105,19 @@ 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 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 exits or aborts
@@ -144,34 +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 (window-buffer (minibuffer-window))))
+  (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* ((sym (with-current-buffer buf
-                    (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 ()
+    (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)))))
+      (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-preferred-function)))
-
-;; Bind it to `M-:'.
-(global-set-key [remap eval-expression] 'eval-expression-with-eldoc)
+    (call-interactively eldoc-eval-preferred-function)))
 
 
 (provide 'eldoc-eval)