make eldoc-overlay-mode as a global minor mode
[eldoc-overlay.git] / eldoc-overlay.el
blob50db5814864fefe35b693c13d8e6b81b9308acbf
1 ;;; eldoc-overlay.el --- Display eldoc with contextual documentation overlay
3 ;; Author: stardiviner <numbchild@gmail.com>
4 ;; Author: Robert Weiner <rsw@gnu.org>
5 ;; Maintainer: stardiviner <numbchild@gmail.com>
6 ;; Keywords: docs, eldoc, overlay
7 ;; URL: https://repo.or.cz/eldoc-overlay.git
8 ;; Created: 14th Jan 2017
9 ;; Modified: 18th Dec 2017
10 ;; Version: 0.1.1
11 ;; Package-Requires: ((emacs "24.4") (inline-docs "1.0.1") (quick-peek "1.0"))
13 ;;; Commentary:
15 ;; Eldoc displays the function signature of the closest function call
16 ;; around point either in the minibuffer or in the modeline.
18 ;; This package modifies Eldoc to display this documentation inline
19 ;; using a buffer text overlay.
21 ;; `eldoc-overlay-mode' is a per-buffer local minor mode.
23 ;; By default, the overlay is not used in the minibuffer, eldoc is shown in the modeline
24 ;; in this case. Set the option `eldoc-overlay-enable-in-minibuffer' non-nil if you want
25 ;; to enable overlay use in the minibuffer.
27 ;; Finally, see the documentation for `eldoc-overlay-backend' if you want to try
28 ;; a different overlay display package backend.
30 ;;; Code:
31 ;;; ----------------------------------------------------------------------------
33 (require 'eldoc)
34 (declare-function 'inline-docs "inline-docs" format-string &rest args)
35 (declare-function 'inline-docs--clear-overlay "inline-docs")
36 (declare-function 'quick-peek-show "quick-peek" str &optional pos min-h max-h)
37 (declare-function 'quick-peek-hide "quick-peek" &optional pos)
38 (declare-function 'company-box--get-frame "company-box")
39 (declare-function 'company-tooltip-visible-p "company")
41 ;; User Options
42 (defgroup eldoc-overlay nil
43 "Display Eldoc function signatures using in-buffer text overlays"
44 :prefix "eldoc-overlay-"
45 :group 'eldoc)
47 (defcustom eldoc-overlay-enable-in-minibuffer nil
48 "Non-nil (default: nil) means enable `eldoc-overlay-mode' in the minibuffer.
49 When nil and in the minibuffer, if standard `eldoc-mode' is
50 enabled, it displays function signatures in the modeline."
51 :type 'boolean
52 :group 'eldoc-overlay)
54 (defvar eldoc-overlay-delay nil
55 "A seconds timer delay with `sleep-for' for eldoc-overlay display.")
57 ;; Variables
58 (defcustom eldoc-overlay-backend 'quick-peek
59 "The backend library that displays eldoc overlays.
60 Two backends are supported: `inline-docs' and `quick-peek'."
61 :type 'function
62 :safe #'functionp)
64 ;; Functions
65 ;;; FIXME: the current line font-lock color is messed up by `eldoc-overlay'.
66 (defun eldoc-overlay-inline-docs (format-string &rest args)
67 "Inline-docs backend function to show FORMAT-STRING and ARGS."
68 (inline-docs format-string args))
70 (defun eldoc-overlay-quick-peek (format-string &rest args)
71 "Quick-peek backend function to show FORMAT-STRING and ARGS."
72 (when format-string
73 (quick-peek-show
74 (apply 'format format-string args)
75 (point)
76 1)))
78 ;;; `eldoc-minibuffer-message', `eldoc--message'
79 (defun eldoc-overlay-message (format-string &rest args)
80 "Display eldoc in overlay using backend function from `eldoc-overlay-backend'.
81 This function used as value of `eldoc-message-function'."
82 (unless (or (company-tooltip-visible-p)
83 (when (and (featurep 'company-box) (fboundp company-box--get-frame))
84 (frame-visible-p (company-box--get-frame)))
85 (not format-string))
86 (if (and (minibufferp) (not eldoc-overlay-enable-in-minibuffer))
87 (apply #'eldoc-minibuffer-message format-string args)
88 (when (and (bound-and-true-p eldoc-overlay-delay)
89 (numberp eldoc-overlay-delay))
90 (run-with-timer eldoc-overlay-delay nil #'eldoc-overlay-message-backend)
91 (eldoc-overlay-message-backend format-string args)
92 ;; (apply 'eldoc-overlay-quick-peek (list (funcall eldoc-documentation-function)))
93 ))))
95 (defun eldoc-overlay-message-backend (format-string &rest args)
96 (funcall (pcase eldoc-overlay-backend
97 ('inline-docs 'eldoc-overlay-inline-docs)
98 ('quick-peek 'eldoc-overlay-quick-peek))
99 (apply #'format format-string args)))
101 ;; Reference `eldoc-display-in-buffer', `eldoc-display-in-echo-area'
102 (defun eldoc-overlay-display (docs _interactive) ; the `docs' is a docstring in style of cons ((#(text-property)) . nil).
103 (when docs
104 (let* ((docs-text-property (caar docs))
105 (docs-plain (substring-no-properties docs-text-property)))
106 (funcall (pcase eldoc-overlay-backend
107 ('inline-docs 'eldoc-overlay-inline-docs)
108 ('quick-peek 'eldoc-overlay-quick-peek))
109 docs-plain))))
111 (defun eldoc-overlay-enable ()
112 ;; adopt for new eldoc mechanism.
113 ;; (when (and (boundp 'eldoc-documentation-strategy)
114 ;; (fboundp 'eldoc-documentation-compose))
115 ;; (setq eldoc-documentation-strategy #'eldoc-documentation-compose))
116 (if (boundp 'eldoc-documentation-functions)
117 (add-to-list 'eldoc-display-functions #'eldoc-overlay-display)
118 ;; roll back to old mechanism.
119 (setq eldoc-message-function #'eldoc-overlay-message))
120 (when (eq eldoc-overlay-backend 'quick-peek)
121 (add-hook 'post-command-hook #'quick-peek-hide)))
123 (defun eldoc-overlay-disable ()
124 (pcase eldoc-overlay-backend
125 ('quick-peek
126 (quick-peek-hide)
127 ;; Remove hook when no buffers have any peek overlays
128 (unless (delq nil (mapcar (lambda (buf) (buffer-local-value 'quick-peek--overlays buf)) (buffer-list)))
129 (remove-hook 'post-command-hook #'quick-peek-hide)))
130 ('inline-docs
131 (inline-docs--clear-overlay)))
132 (when (boundp 'eldoc-documentation-functions)
133 (setq eldoc-display-functions
134 (delq #'eldoc-overlay-display eldoc-display-functions)))
135 (setq eldoc-message-function #'eldoc-minibuffer-message))
137 ;;;###autoload
138 (define-minor-mode eldoc-overlay-mode
139 "Minor mode for displaying eldoc contextual documentation using a text overlay."
140 :require 'eldoc-overlay-mode
141 :group 'eldoc-overlay
142 :init-value nil
143 :global t
144 :lighter nil
145 (if eldoc-overlay-mode
146 (eldoc-overlay-enable)
147 (eldoc-overlay-disable)))
149 ;;; ----------------------------------------------------------------------------
151 (provide 'eldoc-overlay)
153 ;;; eldoc-overlay.el ends here