Bagaimana cara mengambil dokumen dari fungsi dan variabel?

11

Saya mencoba untuk menulis fungsi yang akan mengambil dokumen dari setiap sexps dalam file yang cocok (def.*).

Saya ingin keduanya dapat mengambil fungsi / makro, serta variabel apa pun yang didefinisikan. Untuk variabel saya ingin docstring, sedangkan untuk fungsi apa pun saya juga ingin daftar argumen.

Jonathan Leech-Pepin
sumber
1
Untuk memperjelas: apakah Anda memiliki file sumber Elisp (interpretasi saya), atau apakah Anda memiliki banyak variabel dan fungsi di lingkungan Emacs saat ini (interpretasi Constantine)? Dan jika interpretasi pertama, apakah Anda benar-benar menginginkan semua (def…)sexps, bukan hanya spesifikasi tingkat atas? Atau interpretasi menengah fungsi dan variabel yang akan ditentukan jika file dimuat? Atau definisi yang lebih santai yang mencakup bentuk tingkat atas seperti (when nil (defun …)))?
Gilles 'SANGAT berhenti menjadi jahat'
Saya awalnya menginginkan yang pertama, namun berdasarkan interpretasi Constantine saya bisa mendapatkan implementasi fungsional yang membuat saya mendapatkan apa yang saya butuhkan. Tujuannya adalah untuk mengubah sumber elisp menjadi dokumentasi (ditulis dalam Org) berdasarkan Dokumen.
Jonathan Leech-Pepin
Dengan interpretasi kedua, built-in describe-functiondan teman-teman melakukan bagian yang cukup baik dari apa yang Anda inginkan (docstring dan daftar argumen).
T. Verron

Jawaban:

10

Jika tujuannya adalah untuk mendapatkan informasi tentang fungsi dan variabel yang sudah ada di lingkungan :

  • Untuk dokumentasi fungsi dan makro, lihat documentationfungsi.

  • Untuk dokumen variabel, gunakan documentation-property; sebagai contoh:

    (documentation-property
     'user-init-file 'variable-documentation)
    
  • Untuk fungsi arity dan daftar argumen, lihat pertanyaan Emacs.SE ini , jawabannya, dan komentar untuk pertanyaan itu.

(Saya menemukan ini dengan menekan C-h k C-h fdan membaca kode sumber describe-function(sama untuk variabel docstring, tetapi belajar describe-variable).)

Untuk menganalisis file kode sumber Emacs Lisp, dengan asumsi bahwa tujuannya adalah untuk mendapatkan informasi tentang def.*formulir tingkat atas , orang dapat melakukan sesuatu yang mirip dengan yang berikut ini.

(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)))))

Hal ini dapat dengan mudah diperluas untuk defvar, defconst, dll

Untuk menangani defunmuncul di dalam bentuk tingkat atas seseorang harus turun ke bentuk ini, mungkin menggunakan rekursi.

Constantine
sumber
2
+1 untuk memberi tahu pembaca cara menemukan info ini sendiri. Itulah pelajaran yang lebih penting dari keduanya yang Anda ajarkan.
Drew
@Drew Tampaknya kita berada dalam situasi yang aneh: tujuan dari situs ini adalah untuk membuat dirinya usang ... Ini akan membuat diskusi yang menarik dalam obrolan :)
Sean Allred
4
@SeanAllred Mengajar orang untuk belajar tidak menghentikan pertanyaan, itu hanya membuat mereka lebih baik.
Malabarba
3
+1 ke Malabarba. Tujuan dari situs ini adalah (IMHO) untuk menjawab apa yang tidak dapat dijawab oleh Emacs atau tidak dijawab dengan baik atau mudah . Analogi: Untuk situs Bahasa Inggris & Penggunaan alasan untuk menutup pertanyaan adalah bahwa " Pertanyaan yang dapat dijawab menggunakan referensi yang tersedia secara umum adalah di luar topik *". (StackOverflow serupa.) Kita tidak perlu terlalu ekstrem, mengatakan bahwa pertanyaan yang bisa dijawab Emacs adalah di luar topik , tetapi ide yang sama harus diterapkan: suruh pengguna mencoba menemukan jawabannya terlebih dahulu . Dalam kasus kami, itu berarti dengan meminta Emacs .
Drew
@Drew Fair points :)
Sean Allred