fix: border column number under `display-line-number-mode'
[inline-docs.git] / inline-docs.el
blob2a256cad48e3ba378ac626e867aaaa4953b20ee6
1 ;;; inline-docs.el --- Show inline contextual docs.
3 ;; Author: stardiviner <numbchild@gmail.com>
4 ;; Keywords: inline docs overlay
5 ;; URL: https://repo.or.cz/inline-docs.git
6 ;; Created: 20th Jan 2017
7 ;; Version: 1.0.1
8 ;; Package-Requires: ((emacs "24.3"))
10 ;;; Commentary:
12 ;; This is a library for showing inline contextual docs above or below.
14 ;; You can use this library function `inline-docs` in packages like
15 ;; https://repo.or.cz/eldoc-overlay.git
17 ;; ```eldoc
18 ;; (setq eldoc-message-function #'inline-docs)
19 ;; ```
21 ;; ```elisp
22 ;; (inline-docs "FORMATED-STRING")
23 ;; (inline-docs "STRING")
24 ;; ```
26 ;;; Code:
27 ;;; ----------------------------------------------------------------------------
29 (require 'cl-lib)
31 (defvar inline-docs-overlay nil)
33 (defgroup inline-docs nil
34 "Show inline contextual docs."
35 :group 'docs)
37 (defcustom inline-docs-position 'above
38 "Specify inline-docs display position, up or down.
40 Set `inline-docs-position' to `up' to fix issue that `inline-docs' does not show on single line which don't has next line."
41 :type '(choice
42 :tag "Specify inline-docs display position."
43 (const :tag "up" above)
44 (const :tag "down" below))
45 :group 'inline-docs)
47 (defcustom inline-docs-border-symbol ?―
48 "Specify symbol for inline-docs border."
49 :type 'character
50 :group 'inline-docs)
52 (defcustom inline-docs-prefix-symbol ?\s
53 "Specify symbol for inline-docs prefix."
54 :type 'character
55 :group 'inline-docs)
57 (defcustom inline-docs-indicator-symbol "➜"
58 "Specify symbol for inline-docs indicator."
59 :type 'character
60 :group 'inline-docs)
62 (defface inline-docs-face
63 '((t (:inherit font-lock-string-face)))
64 "Face for `inline-docs-mode'."
65 :group 'inline-docs)
67 (defface inline-docs-border-face
68 '((t (:inherit font-lock-doc-face)))
69 "Face for inline docs border lines."
70 :group 'inline-docs)
72 (defface inline-docs-prefix-face
73 '((t (:inherit default)))
74 "Face for inline docs prefix."
75 :group 'inline-docs)
77 (defface inline-docs-indicator-face
78 '((t (:inherit font-lock-doc-face)))
79 "Face for inline docs indicator."
80 :group 'inline-docs)
82 (defun inline-docs--clear-overlay ()
83 "Clear inline-docs overlays."
84 (when (overlayp inline-docs-overlay)
85 (delete-overlay inline-docs-overlay))
86 (remove-hook 'post-command-hook 'inline-docs--clear-overlay))
88 (defun inline-docs--string-display (string apply-face)
89 "Show STRING contents below point line until next command with APPLY-FACE."
90 ;; note that `display-line-numbers-mode' takes 2 + `line-number-display-width' columns
91 (let* ((total-column-number (if display-line-numbers-mode
92 (- (window-body-width) (+ 2 (line-number-display-width)))
93 (window-body-width)))
94 (border-line (make-string total-column-number inline-docs-border-symbol))
95 (offset (make-string
96 (if (= (current-indentation) 0) ; fix (wrong-type-argument wholenump -1) when current indentation is 0 minus 1 will caused wholenump exception.
97 (current-indentation)
98 (- (current-indentation) 1))
99 inline-docs-prefix-symbol))
100 (str (concat (propertize border-line
101 'face 'inline-docs-border-face)
102 "\n"
103 offset
104 (propertize (concat inline-docs-indicator-symbol " ")
105 'face 'inline-docs-indicator-face)
106 (copy-sequence string) ; original eldoc string with format.
107 "\n"
108 (propertize border-line
109 'face 'inline-docs-border-face)
110 "\n"
112 start-pos end-pos)
113 (unwind-protect
114 (save-excursion
115 ;; clear overlay
116 (inline-docs--clear-overlay)
117 ;; decide overlay positions
118 (cl-case inline-docs-position
119 (above (forward-line 0))
120 (below (forward-line)))
121 (setq start-pos (point))
122 (end-of-line)
123 (setq end-pos (point))
124 ;; create overlay
125 (setq inline-docs-overlay (make-overlay start-pos end-pos (current-buffer)))
126 ;; change the face
127 (if apply-face
128 (overlay-put inline-docs-overlay 'face 'inline-docs-face))
129 ;; hide full line
130 ;; (overlay-put inline-docs-overlay 'display "")
131 ;; (overlay-put inline-docs-overlay 'display :height 20)
132 ;; pre-pend indentation spaces
133 ;; (overlay-put inline-docs-overlay 'line-prefix prefix)
134 ;; auto delete overlay
135 (overlay-put inline-docs-overlay 'evaporate t)
136 ;; display message
137 (overlay-put inline-docs-overlay 'before-string str))
138 (add-hook 'post-command-hook 'inline-docs--clear-overlay))))
140 ;;;###autoload
141 (defun inline-docs-display-docs-momentary (format-string &rest args)
142 "Display inline docs FORMAT-STRING under point with extra ARGS."
143 (when format-string
144 (inline-docs--string-display
145 (apply 'format format-string args)
146 t)))
148 ;;;###autoload
149 (defalias 'inline-docs 'inline-docs-display-docs-momentary)
151 ;;; ----------------------------------------------------------------------------
153 (provide 'inline-docs)
155 ;;; inline-docs.el ends here