Bagaimana cara menampilkan overlay seperti screencast ini?

10

Cara membuat overlay di Emacs seperti berikut (mungkin bukan overlay, saya tidak tahu, itu dari company-coq inline-docs):

hamparan seperti screencast ini

stardiviner
sumber

Jawaban:

8

Memang itu menyelesaikan perilaku itu menggunakan overlay. Khususnya - ini menggunakan 'after-stringproperti untuk menunjukkan dokumentasi (lihat: Overlay Properties ).

Jika Anda memeriksa fungsi company-coq--show-definition-overlay-at-point(mis: via M-x find-function), Anda dapat melihat persis bagaimana itu dibuat:

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

Referensi ke overlay disimpan company-coq-definition-overlayuntuk memudahkan menghapus overlay nanti:

(delete-overlay company-coq-definition-overlay)
(setq company-coq-definition-overlay nil)
Epa
sumber
Dengan (overlay-put OVERLAY 'after-string STR)tidak memiliki fontify seperti pada screencast.
stardiviner
@stardiviner apakah Anda bertanya-tanya tentang karakter / warna / gaya tertentu? Anda bisa menggunakan edebug untuk memeriksa string ins-strdi company-coq--show-definition-overlay-at-point. Wajah dan gaya khusus akan ada sebagai properti teks dalam string itu. Properti Teks: Properti Khusus adalah referensi yang bermanfaat untuk mendekode properti tersebut.
ebpa
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)

Saya membuat repo untuk ini, https://github.com/stardiviner/inline-docs.el Dan modul yang digunakan inline-docs.eluntuk eldoc. https://github.com/stardiviner/eldoc-overlay-mode .

stardiviner
sumber
Akan menyenangkan untuk memiliki itu sebagai modul tujuan umum, sehingga dapat digunakan tidak hanya untuk eldoc tetapi "modeline quickinfo" lainnya juga.
theldoria
Begitu ya, saya akan membuat mode umum untuk ini, lalu membuat mode terpisah untuk eldoc.
stardiviner