Jak dodać znacznik czasu do każdego wpisu w buforze * Wiadomości * Emacsa?

11

Bardzo zależę od *Messages*bufora, ale wpisy nie są oznaczone datą.

Jak dodać znacznik czasu do każdego wpisu w buforze Wiadomości Emacsa ?

Więc coś takiego:

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]

stanie się mniej więcej tak:

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]

Przeszukałem oczywiście EmacsWiki, Reddit i emacs.sx, ale bezskutecznie.

Wiem o tym command-log-mode, co można dostosować do rejestrowania za pomocą znaczników czasu, ale jest to przydatne tylko w przypadku interaktywnych poleceń, a nie wszystkich komunikatów, w tym również „systemowych” Emacsa.

Zamiast tego każda wiadomość zalogowana w buforze Wiadomości powinna być oznaczona znacznikiem czasu.

Jak dodać znacznik czasu do każdego wpisu w buforze Wiadomości Emacsa , bez względu na jego źródło?

gsl
źródło
2
To brzmi jak prośba o funkcję dla Emacsa. messageKomenda jest zaimplementowana w C i prawdopodobnie ma bezpośrednie rozmówców, więc nie będzie w stanie zapewnić każda zalogowana wiadomość dostaje znacznik czasu bez budowania Emacs samodzielnie. To powiedziawszy, możesz być w stanie doradzić messagepoleceniu wprowadzenia znacznika czasu, gdy jest wywoływany z Elisp. Wymagana jest pewna ostrożność: messagemożna ją wywoływać bez argumentów, pustych ciągów formatu itp. Aby uniknąć pętli rekurencyjnej, należy również wywoływać porady dotyczące znaczników czasu messagena ścieżce kodu.
glucas
1
Nie próbowałem tego, ale wygląda na to, że powinieneś być w stanie poradzić się na wiadomość emacswiki.org/emacs/AdvisingFunctions stackoverflow.com/questions/21524488/… superuser.com/questions/669701/...
eflanigan00 14.04.17
1
Byłbym skłonny użyć after-change-functions(w buforze komunikatów) do wdrożenia tego. Ilekroć coś jest wstawiane na końcu bufora, poprzedź przed nim znacznik czasu.
phils
1
@phils Refer from gnu.org/software/emacs/manual/html_node/elisp/Change-Hooks.html Wyjście wiadomości do bufora Messages nie wywołuje tych funkcji i nie dokonuje pewnych zmian bufora wewnętrznego, takich jak zmiany w utworzonych buforach przez Emacsa wewnętrznie dla niektórych zadań, które nie powinny być widoczne dla programów Lisp.
xinfa tang

Odpowiedzi:

7

W moim pliku init.el mam następujący fragment kodu, który został zaadaptowany z oryginału znalezionego w następującym wątku Reddit: http://www.reddit.com/r/emacs/comments/16tzu9/anyone_know_of_a_reasonable_way_to_timestamp/

(EDYCJA: zmodernizowano w celu dodawania porad i usunięto niezdarną obsługę buforów tylko do odczytu zgodnie z zaleceniami @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)

Powoduje to dekorację bufora * Messages * w następujący sposób:

[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.
Stuart Hickinbottom
źródło
3
Zastanawiam się, dlaczego domyślnie nie jest to przewidziane.
bertfred
1
Genialnie, właśnie tego szukałem. Dziękuję Ci.
gsl
2
@bertfred Ponieważ nikt tego nie zrobił. Być może to ty?
Phil Lord
2
Czy mógłbyś przepisać poradę za pomocą advice-add? Jest to obecnie preferowana metoda, ponieważ wie, jak radzić sobie w sytuacjach, które defadvicenie są w stanie. Ponadto prawdopodobnie nie powinieneś tego robić (read-only-mode 0), ponieważ prawdopodobnie jest to trwałe. Można powiązać inhibit-read-onlydo tcałego kodu, który modyfikuje buforowego.
blujay,
2
Używam twojego kodu, ale wyświetlam wiele wiadomości tylko znacznikiem czasu
xinfa tang
5

Tłumaczenie prostego rozwiązania @ xinfatang na nową advice-addskładnię jako otoki messagefunkcji:

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

Wyjścia *Messages*takie jak:

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

Dodać:

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

Usuwać:

 (advice-remove 'message #'my-message-with-timestamp)
mitos
źródło
3
Możesz również po prostu odfiltrować argumenty, zamiast korzystać z porad: (advice-add 'message :filter-args 'with-timestamp)działałby z taką funkcją:(defun with-timestamp (args) (push (concat (format-time-string "[%F %T.%3N] ") (car args)) (cdr args)))
glucas
1
@glucas Nice! Dostaję komunikat bez znaczników czasu, gdy zatrzymam kursor myszy nad minibuforem. Czy istnieje sposób, aby tego uniknąć?
AstroFloyd
3

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

Wreszcie ja wciąż jak Stuart Hickinbottom odpowiedź „s, ponieważ uniknąć Pokaż czas w minibufora dodaje to zmodyfikowana wersja którego używam, to zignorować komunikaty wyświetlane tylko w obszarze echa (przez let message-log-maxsię nilprzed wywołaniem funkcji wiadomości):

 (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)
Xinfa Tang
źródło
2
Zmień format znacznika czasu na %F %T.%3Nna mikrosekundy pokazu
xinfa tang