0

I want to optionally perform some functions on the data in buffer *WL:Message* right after I access and view it.

For example, when first viewing a new message in the *WL:Message* buffer via wl-summary-read or wl-summary-enter-handler, I'd like to perform the following logic (pseudo-code) ...

Enter the *WL:Message* buffer
IF *WL:Message* buffer contains images
THEN
   Scroll down to the first image
   Do a (recenter 1) to position this image at the top of the window
ENDIF

I know how to write the elisp code to do all of this. The problem is knowing when to issue this code. I haven't been able to find a hook that runs right as the *WL:Message* buffer is being displayed.

I tried to use advice around various existing wanderlust wl-summary and wl-message functions, but I haven't found a reliable way to do what I want. Sometimes (seemingly at random), the wl-message-buffer variable is not set, or that buffer's window is not live (it needs to be a live window in order for (recenter 1) to work).

Does anyone know of the proper place I can insert my code so that it always reliably runs whenever I first view a new message in the *WL:Message* buffer?

4
  • NOTE to the person who edited my message. This is the wanderlust *WL:Message* buffer, not the emacs *Messages* buffer. I changed this to be precise ...
    – HippoMan
    Commented Apr 9, 2017 at 15:54
  • How about using the wl-message-display-internal-hook? There are too many possibilities that I am not fully aware of that may affect displaying a buffer, so I cannot duplicate your own settings to test it out. The hook is on almost the last line of wl-message-display-internal (which gets called near the end of wl-message-buffer-display), so it looks promising. I disabled default displaying of buffers in Wanderlust and almost everything is noselect (i.e., populated in the background) so that I can display the WL folders and buffers wherever and whenever I choose.
    – lawlist
    Commented Apr 10, 2017 at 6:29
  • I see that wl-summary-down may also be getting in your way, so you may wish to have a look at that too. Functions like that are what I have removed in my custom version ... See also wl-message-redisplay-hook.
    – lawlist
    Commented Apr 10, 2017 at 6:43
  • It turns out that wl-message-redisplay-hook will indeed work for me. See my answer, below, for details. I can accept my answer in 22 hours from now, and I then will do so.
    – HippoMan
    Commented Apr 10, 2017 at 16:18

1 Answer 1

0

Thanks to the help from lawlist, I figured out the solution.

I'm pretty sure I had tried wl-message-redisplay-hook, but I was incorrectly trying to use the variable wl-message-buffer to get the current *WL:Message* buffer. However, in that hook (and in many other places in the wanderlust code), that variable's value is set to nil. In general, I believe we cannot ever reliably use the wl-message-buffer variable.

However, in wl-message-redisplay-hook, the (current-buffer) function will correctly return a reference to a live *WL:Message* buffer instance containing the new message. I can then do whatever I want within that buffer.

Here's my code for performing the function I described above ...

(defun my-redisplay-func ()
  ;; As long as this function is run as a
  ;; wl-message-redisplay-hook, (current-buffer)
  ;; will return an instance of a live *WL:Message*
  ;; buffer.
  (let ((win (get-buffer-window (current-buffer))))
    (when win
      (with-selected-window win
        (let ((cur (point-min))
              (end (point-max))
              (image-pos))
          ;; Get the position of the first displayed
          ;; image, if there is one.
          (while (and (not image-pos) (<= cur end))
            (when (get-char-property cur 'display)
              (setq image-pos cur))
            (setq cur (1+ cur)))
          (when image-pos
            ;; Scroll to the first image row and reposition
            ;; it to the bottom of the window.
            (goto-char image-pos)
            (next-line)
            (recenter -1)
            (goto-char image-pos)))))))
(add-hook 'wl-message-redisplay-hook 'my-redisplay-func)

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.