0

I've started to use eww and really like it but I would like the ability to open a search in a new tab with one command. Eww has eww-open-in-new-buffer, which works when I want to open links in a new tab and just opens a new buffer if point isn't on a link, and I thought I'd use it to define a command that allows me to perform a search in a new tab. So I defined

(defun ahp/eww-search-in-new-tab ()
  "This function searches in a new buffer/tab."
  (interactive)
  (call-interactively #'eww-open-in-new-buffer)
  (call-interactively #'eww-search-words)
  )

Now, when I use this command, eww opens a new tab with a new eww buffer, asks me for search input, then performs the search with the old buffer in the new tab. What's even stranger, if I perform the two commands by hand, one after the other, it doesn't do that but instead performs the search in the new eww buffer like it's supposed to. So I'm a bit confused. What's the difference?

1 Answer 1

2

A general answer to the question is: The Emacs Command Loop. A lot of things happen before and after every single command that you invoke manually. You can read about the command loop in the elisp manual:

C-hig (elisp)Command Loop


In your specific case you also need to be aware that the behaviour of eww-open-in-new-buffer (and eww generally) is asynchronous. It fires off a HTTP request for a URL and arranges for the response to be rendered once it arrives, but in the meantime the command exits and control returns to you. After the response arrives, the process sentinel configured by eww is triggered, and it sets about rendering the web page in the buffer in question.

When you call both commands in direct sequence in elisp, the second command is being run the moment that the first command has completed, which is after HTTP request has been sent, but long before any response has come back.


Edit: Having (I think) gleaned what you're actually trying to do, I think you'd be better off with something like this:

(let ((buf (get-buffer-create "foo")))
  ;; (or maybe `generate-new-buffer', depending on what you want)
  (tab-bar-new-tab)
  (switch-to-buffer buf)
  (eww-mode)
  (call-interactively #'eww-search-words))
8
  • I would have suggested trying (let ((eww-retrieve-command 'sync)) ...), but apparently there's a bug with this in Emacs 29.
    – phils
    Jan 9 at 1:20
  • I'm using Emacs 30.0.5 and I don't get an error message if I put the commands in the let-environment, but it also doesn't work. It does the same as if eww-retrieve-command wasn't set to sync. Jan 9 at 3:42
  • The bug isn't yet fixed in Emacs 30 (although it behaves a little differently).
    – phils
    Jan 9 at 5:02
  • 1
    Ok, I think I follow now... you're already starting from an eww buffer and are using the first command to create a new/separate eww buffer, and you want the prompt for the second command, and for it to use the second buffer.
    – phils
    Jan 9 at 5:12
  • 1
    As a side-note the aforementioned 'sync' bug is now fixed upstream for 29.2 and later versions, so it should only exist in version 29.1 (it was not present in 28.2).
    – phils
    Jan 16 at 21:35

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.