แน่นอนว่าmy-defunแมโครเป็นวิธีที่ง่าย แต่ทางออกที่ง่ายกว่าคือ
(advice-add 'eval-when-compile :filter-return
(lambda (exp)
(if (and (eq 'quote (car-safe exp))
(stringp (cadr exp)))
(cadr exp)
exp)))
ซึ่งควรทำให้เคล็ดลับของคุณทำงานอย่างน้อยที่สุดในทุกกรณีที่ฟังก์ชั่นมาโครขยายตัวก่อนที่มันจะถูกกำหนดจริง ๆ ซึ่งควรรวมถึงกรณีการใช้งานหลัก (เช่นถ้ามันถูกโหลดจากไฟล์ถ้าคอมไพล์ด้วยไบต์หรือถ้ามันถูกกำหนด ผ่านM-C-x)
ยังนี้จะไม่แก้ไขรหัสที่มีอยู่ทั้งหมดดังนั้นอาจเป็นคำตอบที่ดีกว่าคือ:
;; -*- lexical-binding:t -*-
(defun my-shift-docstrings (orig ppss)
(let ((face (funcall orig ppss)))
(when (eq face 'font-lock-doc-face)
(save-excursion
(let ((start (point)))
(parse-partial-sexp (point) (point-max) nil nil ppss 'syntax-table)
(while (search-backward "\n" start t)
(put-text-property (point) (1+ (point)) 'display
(propertize "\n " 'cursor 0))))))
face))
(add-hook 'emacs-lisp-mode-hook
(lambda ()
(font-lock-mode 1)
(push 'display font-lock-extra-managed-props)
(add-function :around (local 'font-lock-syntactic-face-function)
#'my-shift-docstrings)))
ซึ่งควรเปลี่ยนเอกสารโดย 2 ช่องว่าง แต่เฉพาะในด้านการแสดงผลโดยไม่มีผลกับเนื้อหาจริงของบัฟเฟอร์
defunมันควรจะค่อนข้างง่ายที่จะสร้างแมโครที่จะขยายไปที่ ข้อเสียเปรียบที่จะวิธีการที่ - และมันเป็นขนาดใหญ่ - มีการที่จะสร้างความสับสนให้ซอฟต์แวร์ใด ๆ (นอกเหนือจาก Elisp คอมไพเลอร์ / ล่าม) ที่มีการแยกรหัสของคุณมองหาdefuns