[PATCH 2/3] emacs: Add thread-outline functionality

Austin Clements amdragon at mit.edu
Mon Jun 13 10:23:20 PDT 2011


Have you tried post-command-hook?  It's overkill, but if you can very
quickly check that you don't have to do anything, the overhead should
be negligible.  It doesn't have the strange point-entered behavior,
but still has a marked advantage over zero-duration idle timers
because you can register your hook for just the outline and show
buffers and it won't get called after actions in other buffers.

I do have one overall structural concern with this patch.  This might
be addressed along with better synchronization between the show and
outline buffers, but my concern is what happens when you switch
between buffers (in particular, multiple show buffers).  I think the
behavior I would expect is that if I switch to another show buffer,
the outline would update to reflect that other show buffer.  If I
switch to a non-show buffer, I would probably expect the outline
window to go away.  Thoughts?

 (defun notmuch-kill-this-buffer ()
   "Kill the current buffer."
   (interactive)
+  ;; if we are in a notmuch-show buffer, kill the associated outline
buffer, if any
+  (when (eq major-mode 'notmuch-show-mode)
+    (let ((outline-buf (get-buffer (notmuch-show-outline-buffer-name))))
+      (when outline-buf
+	(kill-buffer outline-buf))))
   (kill-buffer (current-buffer)))

Just killing the buffer leads to some strange behavior for me.  If I'm
in a show buffer, then hit 'o' and then 'q', my frame is still split
into two windows, one of which shows where I came from, and the other
shows some other buffer (probably the next furthest back in the LRU;
usually notmuch-hello or another search).

Also, would it work better to store the outline buffer object as a
buffer-local variable in the show buffer?  Then you wouldn't have to
go hunting for it.

+(defvar notmuch-outline-button-map
+  (let ((map (copy-keymap button-map)))
+    (define-key map (kbd "<mouse-1>") 'push-button)
+    map)
+  "Keymap used for buttons in thread outlines.")

I don't think you need this.  Does it work if you just add
'follow-link t to the make-button call?

+(defun notmuch-goto-marker (m)
+"Open corresponding buffer and go to marker position in another window."
+  (switch-to-buffer-other-window (marker-buffer m))
+  (goto-char (marker-position m)))

Overkill?

+(defcustom notmuch-outline-format
+  '(("author" . "%s")
+    "-"
+    ("reldate" . "%s"))
+  "Format in which thread-outline entries are displayed
+
+The following fields are supported: date, reldate, author,
+subject.  The list can also contain strings as elements which
+will be printed literally.  This variable can also be a function
+that will be given the message as returned by
+`notmuch-show-get-message-properties' and should return a
+string."

I would recommend a format closer to Emacs' standard format lines like
mode-line-format and header-line-format, or, more likely, some
compatible subset thereof.  In addition to being familiar, those have
the advantage of being recursive, symbolic, and able to embed
arbitrary computations within the convenience of the rest of the
formatter.  One trick I've found works really well in the past is to
let-bind things like `author' and `reldate' in the format function;
this combines naturally with expanding symbols to their values like
mode-line-format does.

+(defun notmuch-show-has-outline ()
+  "Returns non-nil if there is an outline for the current thread."
+  (get-buffer (notmuch-show-outline-buffer-name)))

Unused?

+(defun notmuch-outline-message ()
+  "Outline the message under the point.
+
+Expects the point to be on the beginning of the first line of the message."
+  (lexical-let* ((extent (notmuch-show-message-extent))
+                (buffer-name (notmuch-show-outline-buffer-name))

This would probably be simpler if you just passed the outline buffer
as an argument to `notmuch-outline-message', rather than
reconstructing the buffer name.

+      ;; this is not very robust if the output of notmuch-show changes
+      (while (string-equal (thing-at-point 'char) " ")
+       (incf indentation)
+       (forward-char))

Rather than parsing the notmuch-show buffer, would it make more sense
for notmuch-show to add some property indicating the reply level,
which this could simply read?  Counting spaces seems like asking for
trouble.

+      (loop for i from 1 to indentation do
+           (princ " ")) ;; somewhat ugly

If you move the "(with-current-buffer standard-output" up, this could
simply be indent-to (and the princ's could be replaced with the less
unusual `insert').


More information about the notmuch mailing list