0

I'm trying to create a hook for ein package that will clean up split windows and focus on the rendered buffer. The package provides one hook (called ein:ipynb-mode-hook), but running functions below doesn't work - it seems like the buffers are not ready by the time they are fired.

Is there any other way in emacs to wait/hook for such buffers?

(add-hook 'ein:ipynb-mode-hook
          (lambda ()
            (cl-letf (((symbol-function 'read-directory-name)
                       (lambda (_prompt dir &rest _args) dir)))
              (ein:process-find-file-callback)
              (mapc 'switch-to-buffer
                    (cl-remove-if-not
                     (lambda (b)
                       (and (string-match-p "ein" (buffer-name b))
                            (string-match-p "ipynb" (buffer-name b))))
                     (buffer-list)))
              (delete-other-windows)
              )))
phils
  • 48,657
  • 3
  • 76
  • 115
  • 1
    Tangentially, I highly recommend only using named functions (symbols) in hooks; not lambda forms. – phils May 29 '23 at 23:35
  • Thanks, that's good to know. I would gladly simplify that part of the hook - it came from one of the developers of the ein package and I find it very hard to understand. If there's a better way to write it, please let me know. – Daniel Krajnik May 29 '23 at 23:42
  • I know nothing of `ein`, but mechanically that code temporarily causes `read-directory-name` to just return its DIR argument value (presumably for the benefit of this next call...); calls `(ein:process-find-file-callback)`; calls `switch-to-buffer` on every buffer with a name matching "ein" or "ipynb"; and then maximises the selected window. – phils May 29 '23 at 23:47
  • 1
    If you extract the lambda form, replace `(lambda ()` with `(defun my-ein:ipynb-mode-hook` (or whichever name you want), and then change the add-hook form to just `(add-hook 'ein:ipynb-mode-hook 'my-ein:ipynb-mode-hook)` (for whichever name you used), then you're only adding the symbol to the hook var, which makes it nicer to inspect the hook var, remove the value from the hook, update the function definition (without then needing to remove an old lambda and add a new one), or jump to the function's definition with `find-function`. – phils May 29 '23 at 23:54
  • n.b. If you use Emacs 28.1 or later, you can `M-x remove-hook` interactively, which makes it easier to remove old lambdas from hooks. – phils May 29 '23 at 23:57
  • Thank you for explaining, I will give it a try. I've realized though that this script won't work that easily due to the windows appearing long after the hook fires. It may need some emacs equivalent of await/async? Anyway I think that this is way above my skillset, but I'm happy to pay $500 for anyone who'd be willing to fix this - I really need that ein package to just work. – Daniel Krajnik May 30 '23 at 00:21
  • 1
    I suggest making that offer to the `ein` maintainers -- I imagine they would be happy to look into that further for you, and it's a nice way to give back to the people who have done the heavy lifting. Perhaps a new ein hook is needed for the situation in question. – phils May 30 '23 at 01:27
  • I don't think that maintainers work on this project anymore, but if they did sure - anyone able to solve this should be rewarded. – Daniel Krajnik May 30 '23 at 10:13

0 Answers0