Comment ajouter un horodatage à chaque entrée dans le tampon * Messages * d'Emacs?

11

Je dépend *Messages*beaucoup du tampon, mais les entrées ne sont pas horodatées.

Comment peut-on ajouter un horodatage à chaque entrée dans le tampon de messages d' Emacs ?

Donc, quelque chose comme ça:

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]

deviendra quelque chose comme ça:

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]

J'ai cherché sur EmacsWiki, Reddit et emacs.sx bien sûr, en vain.

Je sais command-log-mode, qui peut être ajusté pour se connecter avec des horodatages, mais il n'est utile que pour les commandes interactives, pas tous les messages, y compris ceux "système" d'Emacs.

Au lieu de cela, chaque message enregistré dans la mémoire tampon des messages doit être horodaté.

Comment peut-on ajouter un horodatage à chaque entrée dans le tampon des messages d' Emacs , quelle que soit sa source?

gsl
la source
2
Cela ressemble à une demande de fonctionnalité pour Emacs. La messagecommande est implémentée en C et a probablement des appelants directs, vous ne pourrez donc pas vous assurer que chaque message enregistré obtient un horodatage sans construire Emacs vous-même. Cela dit, vous pourrez peut-être conseiller à la messagecommande d'introduire un horodatage lorsqu'elle est appelée depuis Elisp. Une certaine prudence est requise: messagepeut être appelé sans arguments, une chaîne de format vide, etc. Vous voulez également éviter une boucle récursive si votre conseil d'horodatage lui-même appelle messagedans un chemin de code.
glucas
1
Je ne l'ai pas essayé mais il semble que vous devriez pouvoir donner des conseils sur le message emacswiki.org/emacs/AdvisingFunctions stackoverflow.com/questions/21524488/… superuser.com/questions/669701/…
eflanigan00
1
Je serais enclin à utiliser after-change-functions(dans le tampon des messages) pour implémenter cela. Chaque fois que quelque chose est inséré à la fin du tampon, préfixez-lui un horodatage.
phils
1
@phils Refer from gnu.org/software/emacs/manual/html_node/elisp/Change-Hooks.html La sortie des messages dans le tampon Messages n'appelle pas ces fonctions, pas plus que certaines modifications internes du tampon, telles que les modifications des tampons créées par Emacs en interne pour certains travaux, qui ne devraient pas être visibles par les programmes Lisp.
xinfa tang

Réponses:

7

J'ai l'extrait de code suivant dans mon init.el, qui a été adapté d'un original que j'ai trouvé dans le fil de discussion Reddit suivant: http://www.reddit.com/r/emacs/comments/16tzu9/anyone_know_of_a_reasonable_way_to_timestamp/

(EDIT: modernisé pour ajouter des conseils et supprimer la gestion des tampons en lecture seule maladroite sur les conseils de @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)

Cela entraîne la décoration du tampon * Messages * comme suit:

[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
la source
3
Je me demande pourquoi ce n'est pas fourni en option par défaut.
bertfred
1
Génial, c'est exactement ce que je cherchais. Je vous remercie.
gsl
2
@bertfred Parce que personne n'y est parvenu. Peut-être que c'est toi?
Phil Lord
2
Pourriez-vous réécrire les conseils en utilisant advice-add? C'est la méthode préférée maintenant, car elle sait gérer les situations qui defadvicene le peuvent pas. De plus, vous ne devriez probablement pas le faire (read-only-mode 0), car c'est probablement permanent. Vous pouvez vous lier inhibit-read-onlyà tautour du code qui modifie le tampon.
blujay
2
J'utilise votre code, mais affiche de nombreux messages juste un horodatage
xinfa tang
5

La traduction de la solution simple de @ xinfatang à la nouvelle advice-addsyntaxe comme enveloppe autour de la messagefonction est:

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

Sorties *Messages*comme:

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

Ajouter:

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

Retirer:

 (advice-remove 'message #'my-message-with-timestamp)
mithos
la source
3
Vous pouvez également filtrer les arguments plutôt que d'utiliser des conseils: (advice-add 'message :filter-args 'with-timestamp)fonctionnerait avec une fonction comme celle-ci:(defun with-timestamp (args) (push (concat (format-time-string "[%F %T.%3N] ") (car args)) (cdr args)))
glucas
1
@glucas Nice! Je reçois des horodatages sans message quand je passe la souris sur le mini-tampon. Y a-t-il un moyen d'éviter cela?
AstroFloyd
3

Reportez-vous à 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)) ))

Enfin, j'aime toujours la réponse de Stuart Hickinbottom , car il évite d'afficher l'horodatage dans le mini-tampon, ce qui suit est une version modifiée que j'utilise, il ignore les messages uniquement affichés dans la zone d'écho (par let message-log-maxà nilavant l'appel de la fonction de message):

 (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
la source
2
Changer le format d'horodatage %F %T.%3Npour afficher les microsecondes
xinfa tang