Як додати часову позначку до кожного запису в буфері * Повідомлення * 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.

Натомість кожне повідомлення, зареєстроване в буфері повідомлень, має бути відмічене часом.

Як можна додати часову позначку до кожного запису в буфері повідомлень Emacs , незалежно від його джерела?


2
Це звучить як запит на функцію для Emacs. messageКоманда реалізована в C і , ймовірно , має прямі абонент, так що ви не будете в змозі гарантувати , що кожне зафіксоване повідомлення отримує позначку часу без створення Emacs самостійно. Однак, можливо, ви зможете порадити messageкоманді ввести позначку часу, коли вона викликається від Elisp. Потрібна певна обережність: messageйого можна викликати без аргументів, порожнього рядка формату тощо. Ви також хочете уникнути рекурсивного циклу, якщо ваша порада щодо часових позначок сама подзвонить messageу якийсь шлях коду.
глюкас

1
Я не пробував , але мені здається , що ви повинні бути в змозі консультації на повідомлення emacswiki.org/emacs/AdvisingFunctions stackoverflow.com/questions/21524488 / ... superuser.com/questions/669701 / ...
eflanigan00

1
Я б схильний використовувати after-change-functions(в буфері повідомлень) для реалізації цього. Щоразу, коли щось вставляється в кінці буфера, приставте до нього часову позначку.
філс

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/

(EDIT: модернізовано для додавання та видалення незграбного режиму роботи з буфером лише для читання за порадою @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)

Це призводить до декорування буфера * Повідомлення * таким чином:

[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 Тому що ніхто цього не зробив. Можливо, це ти?
Філ Лорд

2
Не могли б ви переписати поради, використовуючи advice-add? Зараз це кращий метод, оскільки він знає, як впоратися з ситуаціями, які defadviceне можуть. Крім того, ви, мабуть, не повинні цього робити (read-only-mode 0), тому що це, ймовірно, є постійним. Ви можете прив’язати inhibit-read-onlyдо tкоду, який модифікує буфер.
блюджай

2
Я використовую ваш код, але відображаю багато повідомлень лише часову
позначку

5

Переклад простого рішення @ xinfatang на новий advice-addсинтаксис як обгортку навколо 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
Ви також можете просто відфільтрувати аргументи, а не скористатися порадами: (advice-add 'message :filter-args 'with-timestamp)працював би з такою функцією:(defun with-timestamp (args) (push (concat (format-time-string "[%F %T.%3N] ") (car args)) (cdr args)))
glucas

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

Нарешті, мені все ще подобається відповідь Стюарта Хікінботтома , оскільки це уникає показу часової позначки в 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.%3Nмікросекунди шоу
xinfa tang
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.