4

I was wondering if it is possible to have a column in Ibuffer that shows the last viewing time.

In the default view I can see these columns:

MR Name                    Size Mode             Filename/Process
-- ----                    ---- ----             ----------------

And with s v the buffers are sorted by last viewing time.
I would be interested in having a column with the value of last viewing/editing time, for example: 20secs, 14min, 1h 23min, 1day 2h 34min, etc...

nephewtom
  • 2,219
  • 17
  • 29
  • How are you defining "viewing time"? Since it was last in a window? For that I suspect you'd need to use `window-configuration-change-hook` to track the visible buffers at each change, compare the current set with the previously-visible set, and set a timestamp for any buffer which has just disappeared from view. You could look at (or build directly on top of) `winner.el` (which provides some tangentially-related functionality). – phils Mar 30 '17 at 02:14
  • The `ibuffer-formats` user option controls what you see in ibuffer, so whichever values you wish to display, you would utilise that to display them. – phils Mar 30 '17 at 02:20
  • 1
    Combine `define-ibuffer-column` with `get-buffer-window` and `buffer-display-time`. – politza Mar 30 '17 at 12:57
  • @politza https://emacs.stackexchange.com/questions/52052/how-to-interpret-buffer-display-time-values – nephewtom Aug 07 '19 at 22:26
  • @phils Anywya, I have no idea how to achieve this. The "viewing time" it would be based on how `ibuffer` does the sort by last viewing time. – nephewtom Aug 07 '19 at 22:38

1 Answers1

1

(In case someone wants the sorting, without the column, the built-in s v will sort by "recency" and should (roughly, see below) do the trick.)

I wanted something like this as well, so I put the above comments to work.

First create the actual column, via define-ibuffer-column. buffer-display-time is a local variable, hence with-current-buffer sets the context. I've formatted it here with my preferred display style (YYYY-MM-DD HH:MM) but that can obviously be changed; see the the docs on format-time-string. If you want it relative, you'll have to come up with a more involved, custom function (the definitions of org-evaluate-time-range and calendar-count-days-region may provide a jumping off point).

(define-ibuffer-column last-viewed
  (:name "Last-viewed" :inline t)
  (with-current-buffer buffer
    (format-time-string "%Y-%m-%d %R" buffer-display-time)))

Then we need to actually insert the column where you want it in ibuffer-formats. Here's what I've done, YMMV:

(setq ibuffer-formats
      '((mark modified read-only locked " "
              (name 18 18 :left :elide)
              " "
              (size 9 -1 :right)
              " "
              (mode 16 16 :left :elide)
              " "
              (last-viewed 18 -1 :left)
              " " filename-and-process)
        (mark " "
              (name 16 -1)
              " " filename)))

That's it — the column should appear, and you should be able to sort with s v!

There's something weird about that "recency" sorting I can't quite figure out — I think it's that it derives the list from buffer-list, so it interacts poorly with ibuffer-auto-mode? Regardless, it doesn't seem to reliably sort by buffer-display-time, so I also created a custom sorter function to override that:

(define-ibuffer-sorter last-viewed
  "Sort the buffers by last viewed time."
  (:description "last-viewed")
  (string-lessp (with-current-buffer (car a)
       (format-time-string "%Y-%m-%d %R" buffer-display-time))
     (with-current-buffer (car b)
       (format-time-string "%Y-%m-%d %R" buffer-display-time))))
(define-key ibuffer-mode-map (kbd "s v") 'ibuffer-do-sort-by-last-edited)
Amory
  • 135
  • 8