วิธีเพิ่มการประทับเวลาในแต่ละรายการในบัฟเฟอร์ * Messages * ของ Emacs?


11

ฉันขึ้นอยู่กับ*Messages*บัฟเฟอร์เป็นจำนวนมาก แต่รายการไม่ได้ประทับเวลา

หนึ่งจะเพิ่มการประทับเวลาในแต่ละรายการในบัฟเฟอร์ข้อความของ Emacs ได้อย่างไร

ดังนั้นสิ่งนี้:

Loading /Users/gsl/lisp.d/init.el (source)...
No outline structure detected
For information about GNU Emacs and the GNU system, type C-h C-a.
Loading /Users/gsl/lisp.d/var/recentf...done
Error running timer: (wrong-number-of-arguments (lambda nil (setq gc-cons-threshold (* 64 1024 1024)) (message "WARNING: gc-cons-threshold restored to %S")) 1)
[yas] Prepared just-in-time loading of snippets successfully.
M-] is undefined
CHILDREN [2 times]
‘show-all’ is an obsolete command (as of 25.1); use ‘outline-show-all’ instead.
Invalid face reference: nil [33 times]
Auto-saving...done
Saving file /Users/gsl/lisp.d/init.el...
Wrote /Users/gsl/lisp.d/init.el
mwheel-scroll: Beginning of buffer [5 times]
Mark set
previous-line: Beginning of buffer [10 times]
Quit [4 times]

จะกลายเป็นดังนี้:

2017-02-14-18:50:01 Loading /Users/gsl/lisp.d/init.el (source)...
2017-02-14-18:50:02 No outline structure detected
2017-02-14-18:50:03 For information about GNU Emacs and the GNU system, type C-h C-a.
2017-02-14-18:50:05 Loading /Users/gsl/lisp.d/var/recentf...done
2017-02-14-18:50:10 Error running timer: (wrong-number-of-arguments (lambda nil (setq gc-cons-threshold (* 64 1024 1024)) (message "WARNING: gc-cons-threshold restored     to %S")) 1)
2017-02-14-18:50:12 [yas] Prepared just-in-time loading of snippets successfully.
2017-02-14-18:50:40 M-] is undefined
2017-02-14-18:50:41 CHILDREN [2 times]
2017-02-14-18:50:00 ‘show-all’ is an obsolete command (as of 25.1); use ‘outline-show-all’ instead.
2017-02-14-18:50:01 Invalid face reference: nil [33 times]
2017-02-14-18:51:01 Auto-saving...done
2017-02-14-18:51:03 Saving file /Users/gsl/lisp.d/init.el...
2017-02-14-18:51:06 Wrote /Users/gsl/lisp.d/init.el
2017-02-14-18:51:09 mwheel-scroll: Beginning of buffer [5 times]
2017-02-14-18:51:11 Mark set
2017-02-14-18:51:21 previous-line: Beginning of buffer [10 times]

ฉันค้นหา EmacsWiki, Reddit และ emacs.sx แน่นอนเพื่อประโยชน์

ฉันรู้command-log-modeซึ่งสามารถปรับให้เข้าสู่ระบบด้วยการประทับเวลา แต่มันมีประโยชน์เฉพาะสำหรับคำสั่งแบบโต้ตอบไม่ใช่ข้อความทั้งหมดรวมถึง Emacs '"system"

ทุกข้อความที่บันทึกไว้ในบัฟเฟอร์ข้อความควรจะประทับเวลาแทน

เราจะเพิ่มการประทับเวลาลงในแต่ละรายการในบัฟเฟอร์ข้อความของ Emacs ได้ไม่ว่าจะมาจากที่ใด


2
ดูเหมือนว่าคำขอคุณลักษณะสำหรับ Emacs messageคำสั่งจะดำเนินการใน C และมีแนวโน้มที่มีการโทรติดต่อโดยตรงดังนั้นคุณจะไม่สามารถที่จะให้แน่ใจว่าข้อความเข้าสู่ระบบทุกคนได้รับการประทับเวลาโดยไม่ต้องสร้าง Emacs ด้วยตัวคุณเอง ที่กล่าวมาคุณอาจจะสามารถแนะนำให้messageคำสั่งแนะนำการประทับเวลาเมื่อมันถูกเรียกจาก Elisp จำเป็นต้องใช้ความระมัดระวังบางอย่าง: messageสามารถเรียกได้โดยไม่มี args, สตริงรูปแบบที่ว่างเปล่า ฯลฯ นอกจากนี้คุณยังต้องการหลีกเลี่ยงการวนซ้ำแบบซ้ำหากคำแนะนำการประทับเวลาของคุณเรียกใช้messageในบางเส้นทางของรหัส
ลูกัส

1
ฉันยังไม่ได้ลอง แต่ดูเหมือนว่าคุณควรจะสามารถแนะนำข้อความ emacswiki.org/emacs/AdvisingFunctions stackoverflow.com/questions/21524488/ … superuser.com/questions/669701/ …
eflanigan00

1
ฉันอยากจะใช้after-change-functions(ในบัฟเฟอร์ข้อความ) เพื่อดำเนินการนั้น เมื่อใดก็ตามที่มีสิ่งใดแทรกอยู่ท้ายบัฟเฟอร์ให้นำหน้าบันทึกเวลาไว้
phils

1
@phils อ้างอิงจากgnu.org/software/emacs/manual/html_node/elisp/Change-Hooks.html เอาต์พุตของข้อความในบัฟเฟอร์ข้อความไม่เรียกฟังก์ชันเหล่านี้และไม่ทำการเปลี่ยนแปลงบัฟเฟอร์ภายในเช่นการเปลี่ยนแปลงในบัฟเฟอร์ที่สร้างขึ้น โดย Emacs ภายในสำหรับงานบางอย่างที่ไม่ควรปรากฏให้เห็นในโปรแกรม Lisp
xinfa tang

คำตอบ:


7

ฉันมีตัวอย่างต่อไปนี้ใน init.el ซึ่งดัดแปลงมาจากต้นฉบับที่ฉันพบในเธรด Reddit ต่อไปนี้: http://www.reddit.com/r/emacs/comments/16tzu9/anyone_know_of_a_reasonable_way_to_timestamp/

(แก้ไข: ทันสมัยเพื่อแนะนำเพิ่มและลบการจัดการบัฟเฟอร์แบบอ่านอย่างเดียวเงอะงะตามคำแนะนำของ @blujay)

(defun sh/current-time-microseconds ()
  "Return the current time formatted to include microseconds."
  (let* ((nowtime (current-time))
         (now-ms (nth 2 nowtime)))
    (concat (format-time-string "[%Y-%m-%dT%T" nowtime) (format ".%d]" now-ms))))

(defun sh/ad-timestamp-message (FORMAT-STRING &rest args)
  "Advice to run before `message' that prepends a timestamp to each message.

Activate this advice with:
(advice-add 'message :before 'sh/ad-timestamp-message)"
  (unless (string-equal FORMAT-STRING "%s%s")
    (let ((deactivate-mark nil)
          (inhibit-read-only t))
      (with-current-buffer "*Messages*"
        (goto-char (point-max))
        (if (not (bolp))
          (newline))
        (insert (sh/current-time-microseconds) " ")))))

(advice-add 'message :before 'sh/ad-timestamp-message)

สิ่งนี้ส่งผลให้มีการตกแต่งของบัฟเฟอร์ * Messages * ดังนี้:

[2017-06-13T07:21:13.270070] Turning on magit-auto-revert-mode...
[2017-06-13T07:21:13.467317] Turning on magit-auto-revert-mode...done
[2017-06-13T07:21:13.557918] For information about GNU Emacs and the GNU system, type C-h C-a.

3
ฉันสงสัยว่าทำไมไม่ให้ตัวเลือกนี้เป็นค่าเริ่มต้น
bertfred

1
ยอดเยี่ยมนี่คือสิ่งที่ฉันกำลังมองหา ขอบคุณ.
gsl

2
@bertfred เพราะไม่มีใครทำให้มันเกิดขึ้น บางทีนั่นคือคุณ?
Phil Lord

2
คุณสามารถเขียนคำแนะนำโดยใช้ใหม่ได้advice-addไหม? เป็นวิธีที่ต้องการตอนนี้เนื่องจากรู้วิธีจัดการกับสถานการณ์ที่defadviceไม่สามารถทำได้ นอกจากนี้คุณไม่ควรทำ(read-only-mode 0)เพราะนั่นอาจจะถาวร คุณสามารถผูกinhibit-read-onlyไปtรอบรหัสที่ปรับเปลี่ยนกันชน
blujay

2
ฉันใช้รหัสของคุณ แต่แสดงข้อความจำนวนมากเพียงประทับเวลา
xinfa tang

5

การแปลคำตอบง่าย ๆ ของ @ xinfatang เป็นadvice-addไวยากรณ์ใหม่เป็น wrapper รอบmessageฟังก์ชันคือ:

(defun my-message-with-timestamp (old-func fmt-string &rest args)
   "Prepend current timestamp (with microsecond precision) to a message"
   (apply old-func
          (concat (format-time-string "[%F %T.%3N %Z] ")
                   fmt-string)
          args))

ผลลัพธ์*Messages*เช่น:

[2018-02-25 10:13:45.442 PST] Mark set

เพื่อเพิ่ม:

 (advice-add 'message :around #'my-message-with-timestamp)

เพื่อลบ:

 (advice-remove 'message #'my-message-with-timestamp)

3
นอกจากนี้คุณยังสามารถกรอง args แทนที่จะใช้คำแนะนำรอบ ๆ : (advice-add 'message :filter-args 'with-timestamp)จะทำงานกับฟังก์ชั่นเช่นนี้:(defun with-timestamp (args) (push (concat (format-time-string "[%F %T.%3N] ") (car args)) (cdr args)))
ลูกัส

1
@glucas ดี! ฉันได้รับการประทับเวลาโดยไม่มีข้อความถึงแม้ว่าเมื่อฉันวางเมาส์ไว้เหนือมินิบัสเกอร์ มีวิธีหลีกเลี่ยงสิ่งนั้นหรือไม่?
AstroFloyd

3

อ้างอิงจากhttps://www.emacswiki.org/emacs/DebugMessages :

(defadvice message (before when-was-that activate)
  "Add timestamps to `message' output."
  (ad-set-arg 0 (concat (format-time-string "[%Y-%m-%d %T %Z] ") 
                        (ad-get-arg 0)) ))

ในที่สุดผมก็ยังคงชอบStuart Hickinbottomคำตอบ 's เพราะมันหลีกเลี่ยงการประทับเวลาในการแสดง minibuffer ต่อไปนี้เป็นรุ่นที่แก้ไขที่ผมใช้ก็ไม่สนใจเฉพาะข้อความที่แสดงในพื้นที่ก้อง (โดยlet message-log-maxไปnilก่อนที่จะเรียกใช้ฟังก์ชันข้อความ):

 (defun my/ad-timestamp-message (FORMAT-STRING &rest args)
   "Advice to run before `message' that prepends a timestamp to each message.
    Activate this advice with:
      (advice-add 'message :before 'my/ad-timestamp-message)
    Deactivate this advice with:
      (advice-remove 'message 'my/ad-timestamp-message)"
       (if message-log-max
           (let ((deactivate-mark nil)
                 (inhibit-read-only t))
             (with-current-buffer "*Messages*"
               (goto-char (point-max))
               (if (not (bolp))
                   (newline))
               (insert (format-time-string "[%F %T.%3N] "))))))
 (advice-add 'message :before 'my/ad-timestamp-message)

2
เปลี่ยนรูปแบบเวลาประทับเป็น%F %T.%3Nmicroseconds แสดง
xinfa tang
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.