1

I use notmuch to read emails.
I've configured notmuch to call offlineimap via pre-new hook.
When I press G to refresh my notmuch buffer, I want emacs to open my offlineimap log file in another window so I can see the sync process in real time. Here's is what I've done:

(use-package notmuch
  :bind
  (:map notmuch-hello-mode-map
   ("G" . (lambda ()
            (interactive)
            (find-file-other-window "~/Maildir/.notmuch/hooks/offlineimap.log")
            (notmuch-poll-and-refresh-this-buffer)))))

Problem with this is, emacs would only open the log file after sync is done.
How do I make emacs open the log file before notmuch and offlineimap action?

5
  • emacs.stackexchange.com/tags/elisp/info
    – Drew
    Dec 17, 2020 at 3:33
  • You may be interested in having a look at the asynchronous section of the manual -- perhaps there is something there that might suit your needs: gnu.org/software/emacs/manual/html_node/elisp/… You have written the question is such a way that whoever answers it would probably need to install a lot of packages and utilities to be able to test and debug any answer, and then to tweak the answer and/or address follow-up questions. Consider creating a minimal working example that does not require the installation of lots of packages and external utilities.
    – lawlist
    Dec 17, 2020 at 4:41
  • Is that because no redipslay is triggered between the two calls? If so, you might add a (sit-for 0) in between. But it's more likely that the refresh function is synchronous and so emacs is "frozen" until it is done. In fact, this seems to say as much, but it also provides a patch to make it asynchronous. Whether that's enough, I don't know, but I would guess not: you still need to tail the logfile which would probably require a bit more work.
    – NickD
    Dec 17, 2020 at 21:25
  • @NickD adding (sit-for 0) does fix the problem. Thank you so much. Now a new problem is that the other window wouldn't auto-revert until function run is complete. Guess this is not as easy as I thought it would be. Maybe i'll settle with using a terminal to tail my log file. Dec 17, 2020 at 22:36
  • That's the problem that @lawlist and I mentioned: emacs is inherently single-threaded, so if it is busy doing something, then it cannot do something else at the same time. In some cases, the async mechanism can help do the long-running "thing" in a different process (while monitoring that process) so that emacs can continue being responsive in the UI.
    – NickD
    Dec 18, 2020 at 0:45

2 Answers 2

1

Thanks to lawlist's suggestion, I've ended up with this:

(use-package notmuch
  :bind
  (("G" . (lambda ()
            (interactive)
            (find-file-other-window "~/Maildir/.notmuch/hooks/offlineimap.log")
            (start-process "notmuch" "notmuch" "notmuch" "new")))))

since (notmuch-poll-and-refresh-this-buffer) is essentially just calling the external notmuch program and updates the current buffer, I decided to call notmuch myself. The drawback of this is I'll need to press g to update the notmuch buffer once after the external program finishes.

0

Here is my function that logs into a buffer and also updates notmuch buffers:

(setq-default notmuch-new-buffer "*notmuch-new*")

(defun my/notmuch-new ()
  """Update mail."""
  (interactive)
  (my/notmuch-new-prepare-buffer)
  (let ((process (my/notmuch-new-process)))
    (set-process-sentinel process 'my/notmuch-new-sentinel)))

(defun my/notmuch-new-prepare-buffer ()
  (switch-to-buffer notmuch-new-buffer)
  (erase-buffer)
  (insert "Updating mail...")
  (newline))

(defun my/notmuch-new-process ()
  (start-process "notmuch" notmuch-new-buffer "notmuch" "new"))

(defun my/notmuch-new-sentinel (process event)
  (notmuch-refresh-all-buffers))

Your Answer

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

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