> On Nov 22, 2022, at 6:03 PM, Yuan Fu <casouri@gmail.com> wrote: > > > >> On Nov 21, 2022, at 4:44 PM, Phil Sainty <psainty@orcon.net.nz> wrote: >> >> On 2022-11-22 11:07, Yuan Fu wrote: >>> So I wonder if itâs ok to fall back to another major mode by simply >>> calling that mode. >> >> I think the following describes what that would do. >> >> >> Quoting myself from https://stackoverflow.com/a/19295380 (and as a >> tangent I'd be happy for some adaptation of that to live somewhere >> in the elisp manual, as I think it was a decent explanation of the >> processes), when we call `child-mode', the full sequence is: >> >> (run-hooks 'change-major-mode-hook) ;; actually the first thing done by >> (kill-all-local-variables) ;; <-- this function >> ,@grandparent-body >> ,@parent-body >> ,@child-body >> (run-hooks 'change-major-mode-after-body-hook) >> (run-hooks 'grandparent-mode-hook) >> (run-hooks 'parent-mode-hook) >> (run-hooks 'child-mode-hook) >> (run-hooks 'after-change-major-mode-hook) >> ;; plus the following final step, since: >> ;; commit 2eb6817ba971184cc109f8530f4b3b38f65650ea >> ;; Add :after-hook facility to define-derived-mode. >> (run-hooks delayed-after-hook-functions) >> >> >> `delay-mode-hooks' is still in effect until child-body has returned, >> so I believe calling (fallback-mode) within child-body would result >> in this sequence: >> >> >> (run-hooks 'change-major-mode-hook) ;; actually the first thing done by >> (kill-all-local-variables) ;; <-- this function >> ,@grandparent-body >> ,@parent-body >> ,@child-body >> + (run-hooks 'change-major-mode-hook) ;; actually the first thing done by >> + (kill-all-local-variables) ;; <-- this function >> + ,@fallback-parent-mode-body >> + ,@fallback-mode-body >> ;; The child-mode binding for `delay-mode-hooks' is now out of scope, >> ;; so `run-mode-hooks' finally acts... >> (run-hooks 'change-major-mode-after-body-hook) >> (run-hooks 'grandparent-mode-hook) >> (run-hooks 'parent-mode-hook) >> (run-hooks 'child-mode-hook) >> + (run-hooks 'fallback-parent-mode-hook) >> + (run-hooks 'fallback-mode-hook) >> (run-hooks 'after-change-major-mode-hook) >> (run-hooks delayed-after-hook-functions) >> >> >> It looks like things pushed onto `delayed-after-hook-functions' >> would happen in this sequence, though: >> >> - grandparent-mode >> - parent-mode >> - fallback-parent-mode >> - fallback-mode >> - child-mode >> >> Although `delayed-after-hook-functions' does not seem to be >> permanent-local, so in fact it might be this? >> >> - fallback-parent-mode >> - fallback-mode >> - child-mode > > Thanks for that detailed explanation :-) > > It seems the current modeâs after-hook is ran the very last. So it might be a > good place to call the fallback major mode. The call to run-hooks in a major > mode invocation command is outside the scope delay-mode-hooks, so simply > calling the fallback major mode should be fine? > > IMO, the sequence would be > - parent-mode > - child-mode > - parent-hook > - child-hook > - parent-after-hook > - child-after-hook: calls fallback-mode > - fallback-parent ⦠Perhaps itâs more clear with a demonstration: We define three modes, A for parent, B for child, F for fallback. Both B and F inherits A. When we call B-mode, it automatically falls back to F-mode in its after-hook (define-derived-mode A-mode nil "A" "A mode." :after-hook (message "A after-hook") (message "A body")) (define-derived-mode B-mode A-mode "B" "B mode." :after-hook (progn (message "B after-hook") (F-mode)) (message "B body")) (define-derived-mode F-mode A-mode "F" "F mode." :after-hook (message "F after-hook") (message "F body")) (setq A-mode-hook (list (lambda () (message "A hook")))) (setq B-mode-hook (list (lambda () (message "B hook")))) (setq F-mode-hook (list (lambda () (message "F hook")))) M-x B-mode RET produces: A body B body A hook A after-hook B after-hook (here F-mode is called) A body F body A hook A after-hook F after-hook All in all, I donât see any immediate harm of falling back to another mode like this. Aâs body and hook run twice, but so does it when the user manually changes B-mode to F-mode. If we want to be extra safe, perhaps we can do (run-with-idle-timer 0 nil #'F-mode) in B-modeâs after-hook. Yuan
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4