When I browse my ~.zsh_history I sometimes wish that the timestamps would be a human readable time format. Is there any mode for emacs that can view the timestamps in a human readable format (just viewing/overlaying, not changing the file).

Sure I can do something like history -E 0 > hist_tmp; emacs hist_tmp. But is there a more direct emacs way to do it?

  • 1
    I don't know what history -E 0 does, but maybe you can run it in an emacs shell? Do C-h f shell for info.
    – NickD
    Mar 10 at 15:59

1 Answer 1


There's a epoch-view minor mode on Elpa (credits to this thread), which you can install as usual.

It's not very customizable though, so to have a different "face" and format you might have to override a few things. This setup looks good to my taste:

(use-package epoch-view
  :defer t
  (defun epoch-view--render (text)
    "Override `epoch-view--render' to avoid showing non-decoded text"
    (epoch-view--render-time text))

  (defun epoch-view-render ()
    "Override `epoch-view-render' to set a different face"
    (let ((text (match-string-no-properties 0)))
      `(face bold
             display ,(epoch-view--render text))))

Older answer:

Sure, you can define a simple major mode for zsh_history files as follows:

;;; --- zsh_history highlighting -*- lexical-binding: t -*-
(defvar zsh-hist-display-date-format "%a %d %b %Y %T %Z"
  "Date format for displaying the timestamp (see `locale -k date_fmt')")

(defun zsh-hist-convert-unix-timestamp (timestamp)
  (format-time-string zsh-hist-display-date-format
                      (seconds-to-time (string-to-number timestamp))))

(defun zsh-hist-display ()
  `( face bold
     display ,(zsh-hist-convert-unix-timestamp (match-string-no-properties 1))
     zsh-hist:fontified t))

(define-derived-mode zsh-history-mode text-mode "Zsh History Files"
  "Major mode for viewing zsh-history files."
  ;; BUG: this may potentially remove font-lock for other modes that decided to use
  ;; 'display. Unfortunately it is unclear how to make font-lock only remove 'display
  ;; for our mode.
  (setq-local font-lock-extra-managed-props '(zsh-hist:fontified display))
  (font-lock-add-keywords nil '(("^: \\([0-9]+\\)" (0 (zsh-hist-display))))))

(add-to-list 'auto-mode-alist '("zsh_history" . zsh-history-mode))

Note: unfortunately Emacs doesn't seem to provide a way to print time with the current locale format (or maybe I didn't find it, please comment if so), so you'll have to replace or customize zsh-hist-display-date-format variable manually to set its content to the output of locale -k date_fmt command.

  • Great thanks. Is there a way to toggle between this view and normal timestamp view? I tried to go back to fundamental mode, but it doesn't change the view back.
    – student
    Mar 10 at 20:01
  • Oh, that's a good point, let me see…
    – Hi-Angel
    Mar 10 at 20:02
  • Well, that's weird. What you usually do in minor modes is you execute a font-lock-remove-keywords upon exiting. The define-minor-mode allows for code to be executed both when enabling and disabling the mode. However, a major mode it seems like doesn't have such facility :/
    – Hi-Angel
    Mar 10 at 20:18
  • I did find a bug which I fixed: a font-lock has to be bound to a mode. Unfortunately that doesn't seem to fix the problem of switching off the display
    – Hi-Angel
    Mar 10 at 20:23
  • Sorry, I dug through documentation, I tried experimenting, I tried a bunch of things, but it just doesn't work. First of all, I found no documentation that would explain how that supposed to work My gut feeling is that Emacs ought to remove these font-locks automatically upon switching major mode. Because I'd presume that's what "mode" parameter of font-lock-add-keywords is for. In reality though Emacs just doesn't do it and I don't know why and again I found no documentation that would point me to anything.
    – Hi-Angel
    Mar 10 at 20:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.