Come aggiungere un timestamp a ciascuna voce nel buffer * Messaggi * di Emacs?


11

Dipendo molto dal *Messages*buffer, ma le voci non sono timestamp.

Come si può aggiungere un timestamp a ciascuna voce nel buffer dei messaggi di Emacs ?

In modo che qualcosa del genere:

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]

diventerà qualcosa del genere:

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]

Ho cercato su EmacsWiki, Reddit ed emacs.sx ovviamente, senza risultati.

Sono a conoscenza command-log-mode, che può essere regolato per accedere con i timestamp, ma è utile solo per i comandi interattivi, non tutti i messaggi, compresi quelli di "sistema" di Emacs.

Invece, ogni messaggio registrato nel buffer Messaggi deve essere marcato con il timestamp.

Come si può aggiungere un timestamp a ciascuna voce nel buffer dei messaggi di Emacs , indipendentemente dalla sua origine?


2
Sembra una richiesta di funzionalità per Emacs. Il messagecomando è implementato in C e probabilmente ha i chiamanti diretti, quindi non sarai in grado di assicurarti che ogni messaggio registrato ottenga un timestamp senza creare Emacs. Detto questo, potresti essere in grado di consigliare il messagecomando di introdurre un timestamp quando viene chiamato da Elisp. È necessaria una certa cautela: messagepuò essere chiamato senza argomenti, una stringa di formato vuota, ecc. Si desidera anche evitare un ciclo ricorsivo nel caso in cui il proprio avviso di data e ora richiami messageun percorso di codice.
Glucas,

1
Non ho provato, ma sembra che si dovrebbe essere in grado di consigli sui messaggi emacswiki.org/emacs/AdvisingFunctions stackoverflow.com/questions/21524488/... superuser.com/questions/669701/...
eflanigan00

1
Sarei propenso a usare after-change-functions(nel buffer dei messaggi) per implementarlo. Ogni volta che qualcosa viene inserito alla fine del buffer, aggiungere un codice temporale ad esso.
phils,

1
@phils Consultare da gnu.org/software/emacs/manual/html_node/elisp/Change-Hooks.html L' output di messaggi nel buffer dei messaggi non chiama queste funzioni e non effettua nemmeno alcune modifiche al buffer interno, come le modifiche ai buffer creati Emacs internamente per determinati lavori, che non dovrebbero essere visibili ai programmi Lisp.
Xinfa Tang,

Risposte:


7

Ho il seguente frammento nel mio init.el, che è stato adattato da un originale che ho trovato nel seguente thread Reddit: http://www.reddit.com/r/emacs/comments/16tzu9/anyone_know_of_a_reasonable_way_to_timestamp/

(EDIT: modernizzato per aggiungere consigli e rimuovere la gestione del buffer di sola lettura goffa su consiglio di @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)

Ciò comporta la decorazione del buffer * Messaggi * come segue:

[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
Mi chiedo perché questo non sia fornito come opzione per impostazione predefinita.
Berterted

1
Fantastico, questo è esattamente quello che stavo cercando. Grazie.
gsl

2
@bertfred Perché nessuno l'ha fatto accadere. Forse sei tu?
Phil Lord,

2
Potresti riscrivere il consiglio usando advice-add? Ora è il metodo preferito, poiché sa come gestire situazioni che defadvicenon possono. Inoltre, probabilmente non dovresti farlo (read-only-mode 0), perché probabilmente è permanente. È possibile associarsi inhibit-read-onlyal tcodice che modifica il buffer.
Blujay,

2
Uso il tuo codice, ma visualizzo molti messaggi solo un timestamp
xinfa tang

5

La traduzione della semplice soluzione di @ xinfatang nella nuova advice-addsintassi come wrapper per la messagefunzione è:

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

Uscite *Messages*come:

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

Aggiungere:

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

Rimuovere:

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

3
Potresti anche semplicemente filtrare gli arg, piuttosto che usare un consiglio: (advice-add 'message :filter-args 'with-timestamp)funzionerebbe con una funzione come questa:(defun with-timestamp (args) (push (concat (format-time-string "[%F %T.%3N] ") (car args)) (cdr args)))
glucas,

1
@glucas Nice! Ricevo i timestamp senza il messaggio, però quando passo il mouse sopra il minibuffer. C'è un modo per evitarlo?
AstroFloyd il

3

Fare riferimento da 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)) ))

Finalmente mi piace ancora la risposta di Stuart Hickinbottom , perché evita di mostrare il timestamp nel minibuffer, la seguente è una versione modificata che uso, ignora i messaggi mostrano solo nell'area di eco (da let message-log-maxa nilprima della chiamata di funzione del messaggio):

 (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
Cambia il formato del timestamp in %F %T.%3Nper mostrare i microsecondi
xinfa tang
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.