10

How to make an overlay in Emacs like the following (maybe it's not overlay, I don't know, it's from company-coq inline-docs):

overlay like this screencast

8

Indeed it does accomplish that behavior using overlays. Specifically- it uses the 'after-string property to show the documentation (see: Overlay Properties).

If you examine the function company-coq--show-definition-overlay-at-point (ex: via M-x find-function) you can see exactly how it's created:

(setq company-coq-definition-overlay (make-overlay ins-pos ins-pos))
(overlay-put company-coq-definition-overlay 'after-string ins-str)

A reference to the overlay is kept in company-coq-definition-overlay to make it easy to remove the overlay later:

(delete-overlay company-coq-definition-overlay)
(setq company-coq-definition-overlay nil)
  • With (overlay-put OVERLAY 'after-string STR) does not have fontify as in screencast. – stardiviner Jan 19 '17 at 3:49
  • @stardiviner are you wondering about specific characters/colors/style? You could use the edebug to examine the string ins-str in company-coq--show-definition-overlay-at-point. Specific faces and styling will exist as text properties in that string. Text Properties: Special Properties is a helpful reference for decoding those properties. – ebpa Jan 19 '17 at 18:45
1
(defvar inline-docs-overlay nil)

(defgroup inline-docs nil
  "Show inline contextual docs in Emacs."
  :group 'docs)

(defcustom inline-docs-border-symbol ?―
  "Specify symbol for inline-docs border."
  :group 'inline-docs)

(defcustom inline-docs-prefix-symbol ?\s
  "Specify symbol for inline-docs prefix."
  :group 'inline-docs)

(defcustom inline-docs-indicator-symbol "➜"
  "Specify symbol for inline-docs indicator."
  :group 'inline-docs)

(defface inline-docs-face
  '((t (:inherit italic)))
  "Face for `inline-docs-mode'."
  :group 'inline-docs)

(defface inline-docs-border-face
  '((t (:inherit font-lock-doc-face)))
  "Face for inline docs border lines."
  :group 'inline-docs)

(defface inline-docs-prefix-face
  '((t (:inherit default)))
  "Face for inline docs prefix."
  :group 'inline-docs)

(defface inline-docs-indicator-face
  '((t (:inherit font-lock-doc-face)))
  "Face for inline docs indicator."
  :group 'inline-docs)

(defun inline-docs--clear-overlay ()
  "Clear inline-docs overlays."
  (when (overlayp inline-docs-overlay)
    (delete-overlay inline-docs-overlay))
  (remove-hook 'post-command-hook 'inline-docs--clear-overlay))

(defun inline-docs--string-display-next-line (string apply-face)
  "Show STRING contents below point line until next command with APPLY-FACE."
  (let* ((border-line (make-string (window-body-width) inline-docs-border-symbol))
         (prefix (make-string
                  (if (= (current-indentation) 0) ; fix (wrong-type-argument wholenump -1) when current indentation is 0 minus 1 will caused wholenump exception.
                      (current-indentation)
                    (- (current-indentation) 1))
                  inline-docs-prefix-symbol))
         (str (concat (propertize border-line
                                  'face 'inline-docs-border-face)
                      "\n"
                      prefix
                      (propertize (concat inline-docs-indicator-symbol " ")
                                  'face 'inline-docs-indicator-face)
                      (copy-sequence string) ; original eldoc string with format.
                      "\n"
                      (propertize border-line
                                  'face 'inline-docs-border-face)
                      "\n"
                      ))
         start-pos end-pos)
    (unwind-protect
        (save-excursion
          (inline-docs--clear-overlay)
          (forward-line)
          (setq start-pos (point))
          (end-of-line)
          (setq end-pos (point))
          (setq inline-docs-overlay (make-overlay start-pos end-pos (current-buffer)))
          ;; change the face
          (if apply-face
              (overlay-put inline-docs-overlay 'face 'inline-docs-face))
          ;; hide full line
          ;; (overlay-put inline-docs-overlay 'display "")
          ;; (overlay-put inline-docs-overlay 'display :height 20)
          ;; pre-pend indentation spaces
          ;; (overlay-put inline-docs-overlay 'line-prefix prefix)
          ;; auto delete overlay
          (overlay-put inline-docs-overlay 'evaporate t)
          ;; display message
          (overlay-put inline-docs-overlay 'before-string str))
      (add-hook 'post-command-hook 'inline-docs--clear-overlay))))

(defun inline-docs-display-docs-momentary (format-string &rest args)
  "Display inline docs FORMAT-STRING under point with extra ARGS."
  (when format-string
    (inline-docs--string-display-next-line
     (apply 'format format-string args)
     t)))

;;;###autoload
(defalias 'inline-docs 'inline-docs-display-docs-momentary)

I created a repo for this, https://github.com/stardiviner/inline-docs.el And a module which use inline-docs.el for eldoc. https://github.com/stardiviner/eldoc-overlay-mode.

  • It would be nice to have that as a general purpose module, such that it could be used not only for eldoc but other "modeline quickinfo" as well. – theldoria Jan 20 '17 at 11:09
  • I see, I will create a general mode for this, then create a separate mode for eldoc. – stardiviner Jan 20 '17 at 11:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.