คำตอบที่อัปเดตพร้อมกับการขยายเวลาค้นหา:
ฉันพูดในคำตอบดั้งเดิมของฉันว่าอาจมีวิธีการทำเช่นนี้ในการขยายเวลารวบรวม / แทนเวลาทำงานเพื่อให้มีประสิทธิภาพที่ดีขึ้นและในที่สุดฉันก็ใช้งานวันนี้ในขณะที่ทำงานกับคำตอบสำหรับคำถามนี้: ฉันจะกำหนดได้อย่างไร เรียกว่าแบบโต้ตอบในกอง?
นี่คือฟังก์ชั่นที่ให้ผลตอบแทนเฟรมย้อนหลังปัจจุบันทั้งหมด
(defun call-stack ()
  "Return the current call stack frames."
  (let ((frames)
        (frame)
        (index 5))
    (while (setq frame (backtrace-frame index))
      (push frame frames)
      (incf index))
    (remove-if-not 'car frames)))
การใช้สิ่งนั้นในแมโครเราสามารถค้นหา stack stack เพื่อดูว่านิยามฟังก์ชั่นใดถูกขยายในเวลาและทำให้ค่านั้นถูกต้องในโค้ด
นี่คือฟังก์ชั่นเพื่อทำการขยาย:
(defmacro compile-time-function-name ()
  "Get the name of calling function at expansion time."
  (symbol-name
   (cadadr
    (third
     (find-if (lambda (frame) (ignore-errors (equal (car (third frame)) 'defalias)))
              (reverse (call-stack)))))))
ที่นี่มันอยู่ในการดำเนินการ
(defun my-test-function ()
  (message "This function is named '%s'" (compile-time-function-name)))
(symbol-function 'my-test-function)
;; you can see the function body contains the name, not a lookup
(lambda nil (message "This function is named '%s'" "my-test-function"))
(my-test-function)
;; results in:
"This function is named 'my-test-function'"
คำตอบเดิม:
คุณสามารถใช้backtrace-frameเพื่อค้นหาสแต็กจนกว่าคุณจะเห็นเฟรมที่แสดงถึงการเรียกใช้ฟังก์ชันโดยตรงและรับชื่อจากนั้น
(defun get-current-func-name ()
  "Get the symbol of the function this function is called from."
  ;; 5 is the magic number that makes us look 
  ;; above this function
  (let* ((index 5)
         (frame (backtrace-frame index)))
    ;; from what I can tell, top level function call frames
    ;; start with t and the second value is the symbol of the function
    (while (not (equal t (first frame)))
      (setq frame (backtrace-frame (incf index))))
    (second frame)))
(defun my-function ()
  ;; here's the call inside my-function
  (when t (progn (or (and (get-current-func-name))))))
(defun my-other-function ()
  ;; we should expect the return value of this function
  ;; to be the return value of my-function which is the
  ;; symbol my-function
  (my-function))
(my-other-function) ;; => 'my-function
ที่นี่ฉันกำลังค้นหาชื่อฟังก์ชั่นที่รันไทม์แม้ว่ามันอาจเป็นไปได้ที่จะใช้สิ่งนี้ในแมโครที่ขยายโดยตรงในสัญลักษณ์ของฟังก์ชั่นซึ่งจะมีประสิทธิภาพมากขึ้นสำหรับการโทรซ้ำและ elisp ที่คอมไพล์
ฉันพบข้อมูลนี้ในขณะที่พยายามเขียนฟังก์ชันตัวเรียกการเรียกใช้งานสำหรับ elisp ซึ่งสามารถพบได้ที่นี่ในรูปแบบที่ไม่สมบูรณ์ แต่อาจเป็นประโยชน์กับคุณ https://github.com/jordonbiondo/call-log