This seems to do the trick:
(defvar my/org-habit-show-graphs-everywhere nil
"If non-nil, show habit graphs in all types of agenda buffers.
Normally, habits display consistency graphs only in
\"agenda\"-type agenda buffers, not in other types of agenda
buffers. Set this variable to any non-nil variable to show
consistency graphs in all Org mode agendas.")
(defun my/org-agenda-mark-habits ()
"Mark all habits in current agenda for graph display.
This function enforces `my/org-habit-show-graphs-everywhere' by
marking all habits in the current agenda as such. When run just
before `org-agenda-finalize' (such as by advice; unfortunately,
`org-agenda-finalize-hook' is run too late), this has the effect
of displaying consistency graphs for these habits.
When `my/org-habit-show-graphs-everywhere' is nil, this function
has no effect."
(when (and my/org-habit-show-graphs-everywhere
(not (get-text-property (point) 'org-series)))
(let ((cursor (point))
item data)
(while (setq cursor (next-single-property-change cursor 'org-marker))
(setq item (get-text-property cursor 'org-marker))
(when (and item (org-is-habit-p item))
(with-current-buffer (marker-buffer item)
(setq data (org-habit-parse-todo item)))
(put-text-property cursor
(next-single-property-change cursor 'org-marker)
'org-habit-p data))))))
(advice-add #'org-agenda-finalize :before #'my/org-agenda-mark-habits)
To explain further, it appears that every agenda function calls
org-agenda-finalize
once the agenda buffer has been mostly
constructed, and this is the function which adds the habit graphs.
Moreover, it just adds the graph to every item which has the
org-habit-p
text property (which encodes the details the graph will
display). So all we need to do is go through and tag the habits with
this information at some point prior to that.
Also, I chose to make this behavior depend on a variable because this
should allow you to set the variable in custom agenda commands, if you
want only some agendas to display habits. I haven't tested that, but
there's no reason it shouldn't work.
EDIT: My original solution had problems with block agendas. It turns out that org-agenda-finalize
is called once for each block, and then once for the agenda as a whole. When that final call happens, the agenda is read-only, so an error gets thrown if the agenda contains any habits. Since all the work has already been done by that point, it makes no sense to scan the agenda again anyway, and I just added a check for the 'org-series property, which is added to the whole agenda after the per-block calls and before the final read-only call.