Làm cách nào để thêm dấu thời gian cho mỗi mục trong bộ đệm * Tin nhắn * của Emacs?


11

Tôi phụ thuộc vào *Messages*bộ đệm rất nhiều, nhưng các mục không được đánh dấu thời gian.

Làm cách nào để thêm dấu thời gian vào từng mục trong bộ đệm Tin nhắn của Emacs ?

Vì vậy, một cái gì đó như thế này:

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]

sẽ trở thành một cái gì đó như thế này:

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]

Tôi đã tìm kiếm trên EmacsWiki, Reddit và emacs.sx, tất nhiên, không có kết quả.

Tôi biết command-log-mode, có thể được điều chỉnh để đăng nhập bằng dấu thời gian, nhưng nó chỉ hữu ích cho các lệnh tương tác, không phải tất cả các thông báo, bao gồm cả các "hệ thống" của Emacs.

Thay vào đó, mọi tin nhắn được ghi vào bộ đệm Tin nhắn nên được đánh dấu thời gian.

Làm cách nào để thêm dấu thời gian vào từng mục trong bộ đệm Tin nhắn của Emacs , bất kể nguồn đó là gì?


2
Điều này nghe có vẻ như một yêu cầu tính năng cho Emacs. Các messagelệnh được thực hiện trong C và có khả năng có người gọi trực tiếp, vì vậy bạn sẽ không thể để đảm bảo mọi thông điệp Logged được một dấu thời gian mà không cần xây dựng Emacs mình. Điều đó nói rằng, bạn có thể có thể khuyên messagelệnh để giới thiệu một dấu thời gian khi nó được gọi từ Elisp. Một số lưu ý là bắt buộc: messagecó thể được gọi mà không có đối số, chuỗi định dạng trống, v.v. Bạn cũng muốn tránh một vòng lặp đệ quy nếu lời khuyên dấu thời gian của bạn tự gọi messagetrong một số đường dẫn mã.
glucas

1
Tôi chưa thử nhưng có vẻ như bạn có thể tư vấn về tin nhắn emacswiki.org/emacs/A mẹoingFifts stackoverflow.com/questions/21524488/ siêu superuser.com/questions/669701/
tựa

1
Tôi muốn sử dụng after-change-functions(trong bộ đệm thư) để thực hiện điều đó. Bất cứ khi nào một cái gì đó được chèn vào cuối bộ đệm, hãy thêm tiền tố vào dấu thời gian.
phils

1
@phils Tham khảo từ gnu.org/software/emacs/manual/html_node/elisp/Change-Hooks.html Đầu ra của tin nhắn vào bộ đệm Tin nhắn không gọi các hàm này và cũng không thay đổi bộ đệm bên trong nhất định, chẳng hạn như thay đổi bộ đệm được tạo bởi Emacs trong nội bộ cho một số công việc nhất định, các chương trình Lisp không thể nhìn thấy.
xinfa tang

Câu trả lời:


7

Tôi có đoạn mã sau trong init.el, được điều chỉnh từ bản gốc tôi tìm thấy trong chuỗi Reddit sau: http://www.reddit.com/r/emacs/comments/16tzu9/anyone_ledge_of_a_reasonable_way_to_timestamp/

(EDIT: được hiện đại hóa để thêm lời khuyên và loại bỏ việc xử lý bộ đệm chỉ đọc vụng về theo lời khuyên của @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)

Điều này dẫn đến việc trang trí bộ đệm * Tin nhắn * như sau:

[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
Tôi tự hỏi tại sao điều này không được cung cấp như một tùy chọn theo mặc định.
bertfred

1
Rực rỡ, đây chính xác là những gì tôi đang tìm kiếm. Cảm ơn bạn.
gsl

2
@bertfred Vì chưa có ai thực hiện. Có lẽ, đó là bạn?
Phil Lord

2
Bạn có thể viết lại lời khuyên bằng cách sử dụng advice-add? Bây giờ nó là phương pháp ưa thích, vì nó biết cách xử lý các tình huống defadvicekhông thể. Ngoài ra, bạn có thể không nên làm (read-only-mode 0), bởi vì đó có thể là vĩnh viễn. Bạn có thể liên kết inhibit-read-onlyvới txung quanh mã sửa đổi bộ đệm.
blujay

2
Tôi sử dụng mã của bạn, nhưng hiển thị nhiều thông báo chỉ là dấu thời gian
xinfa tang

5

Bản dịch của giải pháp đơn giản của @ xinfatang sang advice-addcú pháp mới như một trình bao bọc xung quanh messagehàm là:

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

Đầu ra *Messages*như:

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

Thêm vào:

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

Để xóa:

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

3
Bạn cũng có thể chỉ lọc các đối số, thay vì sử dụng lời khuyên xung quanh: (advice-add 'message :filter-args 'with-timestamp)sẽ hoạt động với chức năng như thế này:(defun with-timestamp (args) (push (concat (format-time-string "[%F %T.%3N] ") (car args)) (cdr args)))
glucas

1
@glika Đẹp quá! Tôi nhận được dấu thời gian thông báo w / o mặc dù khi tôi di chuột qua bộ thu nhỏ. Có cách nào để tránh điều đó?
AstroFloyd

3

Tham khảo từ 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)) ))

Cuối cùng tôi vẫn như Stuart Hickinbottom câu trả lời 's, bởi vì nó tránh cho thấy dấu thời gian trong minibuffer, sau đây là một phiên bản sửa đổi mà tôi sử dụng, nó bỏ qua tin nhắn chỉ hiển thị trong khu vực tiếng vang (bởi let message-log-maxđến niltrước khi gọi hàm nhắn):

 (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
Thay đổi định dạng dấu thời gian thành %F %T.%3Nhiển thị micro giây
xinfa tang
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.