จะดึงเอกสารจากฟังก์ชั่นและตัวแปรได้อย่างไร


11

ฉันพยายามที่จะเขียนฟังก์ชั่นที่จะดึง docstrings จาก sexps ใด ๆ (def.*)ในแฟ้มที่แข่งขัน

ฉันต้องการทั้งสองสามารถเรียกคืนฟังก์ชั่น / มาโครใด ๆ รวมทั้งตัวแปรใด ๆ ที่กำหนดไว้ สำหรับตัวแปรที่ฉันต้องการ docstring ในขณะที่ฟังก์ชั่นใด ๆ ที่ฉันต้องการรายการอาร์กิวเมนต์


1
เพื่อชี้แจง: คุณมีไฟล์ต้นฉบับ Elisp (การตีความของฉัน) หรือคุณมีตัวแปรและฟังก์ชันมากมายในสภาพแวดล้อม Emacs ปัจจุบัน (การตีความของ Constantine) หรือไม่ และถ้าการตีความครั้งแรกคุณต้องการ(def…)sexps ทั้งหมดจริงๆไม่ใช่แค่สเปคระดับบนสุด? หรือการตีความระดับกลางของฟังก์ชั่นและตัวแปรที่จะกำหนดถ้าไฟล์โหลด? หรือคำจำกัดความที่ผ่อนคลายยิ่งกว่าซึ่งรวมถึงแบบฟอร์มระดับบนสุดเช่น (when nil (defun …)))
Gilles 'หยุดความชั่วร้าย'

ตอนแรกฉันต้องการสิ่งแรก แต่จากการตีความของคอนสแตนตินฉันสามารถใช้งานได้ตามที่ฉันต้องการ เป้าหมายคือการแปลงแหล่งที่มา elisp เป็นเอกสาร (เขียนในองค์กร) ขึ้นอยู่กับ Docstrings
Jonathan Leech-Pepin

ด้วยการตีความครั้งที่สองบิวท์อินdescribe-functionและเพื่อน ๆ จะเป็นส่วนที่ดีของสิ่งที่คุณต้องการ (docstring และรายการอาร์กิวเมนต์)
T. Verron

คำตอบ:


10

หากเป้าหมายคือการรับข้อมูลเกี่ยวกับฟังก์ชั่นและตัวแปรที่มีอยู่แล้วในสภาพแวดล้อม :

  • สำหรับเอกสารของฟังก์ชั่นและมาโครดูdocumentationฟังก์ชั่น

  • สำหรับตัวแปร docstrings ให้ใช้documentation-property; ตัวอย่างเช่น:

    (documentation-property
     'user-init-file 'variable-documentation)
    
  • สำหรับฟังก์ชั่น arity และรายการอาร์กิวเมนต์ให้ดูคำถาม Emacs.SE นี้คำตอบและความเห็นต่อคำถาม

(ฉันพบสิ่งนี้โดยการกดC-h k C-h fและ skimming ซอร์สโค้ดของdescribe-function(เหมือนกันกับ docstrings ตัวแปร แต่กำลังศึกษาdescribe-variable))

ในการวิเคราะห์ไฟล์ซอร์สโค้ดของ Emacs Lisp สมมติว่าเป้าหมายคือการรับข้อมูลเกี่ยวกับdef.*แบบฟอร์มระดับบนสุดเราสามารถทำสิ่งที่คล้ายกันดังต่อไปนี้

(defun get-defun-info (buffer)
  "Get information about all `defun' top-level sexps in a buffer
BUFFER. Returns a list with elements of the form (symbol args docstring)."
  (with-current-buffer buffer
    (save-excursion
      (save-restriction
        (widen)
        (goto-char (point-min))
        (let (result)
          ;; keep going while reading succeeds
          (while (condition-case nil
                     (progn
                       (read (current-buffer))
                       (forward-sexp -1)
                       t)
                   (error nil))
            (let ((form (read (current-buffer))))
              (cond
               ((not (listp form))      ; if it's not a list, skip it
                nil)
               ((eq (nth 0 form) 'defun) ; if it's a defun, collect info
                (let ((sym (nth 1 form))
                      (args (nth 2 form))
                      (doc (when (stringp (nth 3 form)) (nth 3 form))))
                  (push (list sym args doc) result))))))
          result)))))

นี้สามารถขยายได้อย่างง่ายดายเพื่อdefvar, defconstฯลฯ

เพื่อจัดการกับการdefunปรากฏตัวในแบบฟอร์มระดับบนสุดคุณจะต้องลงไปในแบบฟอร์มเหล่านี้ซึ่งอาจใช้การเรียกซ้ำ


2
+1 สำหรับบอกผู้อ่านถึงวิธีค้นหาข้อมูลนี้ด้วยตนเอง นั่นเป็นบทเรียนที่สำคัญยิ่งของสองสิ่งที่คุณสอน
ดึง

@Drew ดูเหมือนว่าเราอยู่ในสถานการณ์ที่แปลก: เป้าหมายของเว็บไซต์นี้คือการทำให้ตัวเองล้าสมัย ... นี่จะทำให้การสนทนาที่น่าสนใจในการแชท :)
ฌอน Allred

4
@SeanAllred การสอนผู้คนให้เรียนรู้ไม่ได้หยุดคำถามเพียง แต่ทำให้ดีขึ้นเท่านั้น
Malabarba

3
+1 ถึง Malabarba วัตถุประสงค์ของเว็บไซต์นี้ (IMHO) ควรจะตอบสิ่งที่ Emacs ตัวเองไม่สามารถตอบหรือไม่ตอบได้ดีหรือได้อย่างง่ายดาย การเปรียบเทียบ: สำหรับเว็บไซต์ภาษาอังกฤษและการใช้งานเหตุผลในการปิดคำถามคือ " คำถามที่สามารถตอบได้โดยใช้ การอ้างอิงที่มีอยู่ทั่วไปเป็นหัวข้อนอก *" (StackOverflow จะคล้าย.) เราไม่จำเป็นต้องเป็นมากบอกว่าคำถามที่ Emacs ตัวเองสามารถตอบเป็นปิดหัวข้อแต่ความคิดเดียวกันควรใช้: ให้ผู้ใช้พยายามที่จะหาคำตอบแรก ในกรณีของเราหมายความว่าโดยขอ Emacs
ดึง

@Drew Fair points :)
Sean Allred
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.