Skip to content

Commit

Permalink
Fix behavior of q in buffer mode
Browse files Browse the repository at this point in the history
- link exit buffer to entry at the appropriate time in the hook cycle
- streamline use of post-exit hooks
  • Loading branch information
countvajhula committed Sep 25, 2021
1 parent aefc1b0 commit e51b14b
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 42 deletions.
19 changes: 17 additions & 2 deletions chimera-hydra.el
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ If no VALUE is provided, this clears the flag."
(let* ((mode-name (chimera-mode-name mode))
(hydra (chimera--hydra-for-state mode-name)))
(when (hydra-get-property hydra :exiting)
;; TODO: probably don't need a generic callback here
;; rather, we should invoke handle-exit directly,
;; forwarding any callback(s) to it
(funcall callback mode)
(chimera--hydra-set-flag hydra :exiting))))

Expand All @@ -66,6 +69,19 @@ If no VALUE is provided, this clears the flag."
(defun chimera-handle-hydra-exit (mode)
"Adapter helper for hydra to call hooks upon exit."
(let ((mode-name (chimera-mode-name mode)))
(when (chimera-mode-manage-hooks mode)
(run-hooks (chimera-mode-exit-hook mode)))
;; TODO: chimera mustn't know about rigpa, so we should operate in
;; terms of callbacks here rather than call the rigpa interfaces
;; directly
;; TODO: there does not seem to be a way to use this to
;; identify post-exit in the case where a hydra is exited through
;; a non-head, since after-exit isn't called in that case ¯\_(ツ)_/¯
;; .. unless we can detect that a foreign key has been pressed in
;; the post hook, since that _is_ called always including for
;; foreign keys (but, alas, before executing the command).
;; In any case, this means that exit through non-head is not
;; a clean exit at this point.
(when (equal (symbol-name evil-state) mode-name)
;; hydra has exited but we haven't gone to a new state.
;; This means limbo, and we need to enter an appropriate
Expand All @@ -83,8 +99,7 @@ If no VALUE is provided, this clears the flag."
;; ensure the entry buffer reverts to a sane state
(rigpa--enter-appropriate-mode entry-buffer))
(chimera--hydra-set-flag hydra :entry-buffer))
(when (chimera-mode-manage-hooks mode)
(run-hooks (chimera-mode-exit-hook mode)))))
(run-hooks (chimera-mode-post-exit-hook mode))))

(provide 'chimera-hydra)
;;; chimera-hydra.el ends here
20 changes: 10 additions & 10 deletions rigpa-buffer-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ Version 2017-11-01"
buffer mode."
(interactive)
(condition-case nil
(switch-to-buffer (rigpa-buffer-original-buffer))
(buffer-ring-rotate-to-buffer (rigpa-buffer-original-buffer))
(error (message "Buffer no longer exists!"))))

(defun rigpa-buffer-link-to-original ()
Expand All @@ -161,11 +161,8 @@ re-insert (i.e. \"break insert\") the exit buffer at that position."
(unless (eq exit-buffer original-buffer)
;; rotate the ring back so the original buffer is at head, and
;; then surface the exit buffer so it's proximate to the original
(dynaring-rotate-until (buffer-ring-ring-ring (buffer-ring-current-ring))
#'dynaring-rotate-right
(lambda (buf)
(eq original-buffer buf)))
(buffer-ring-surface-buffer exit-buffer))))
(buffer-ring-rotate-to-buffer original-buffer)
(buffer-ring-switch-to-buffer exit-buffer))))

(defun rigpa-buffer--active-buffers ()
"Get active buffers."
Expand All @@ -181,7 +178,7 @@ re-insert (i.e. \"break insert\") the exit buffer at that position."
(not (member (buffer-name buf) rigpa-buffer-ignore-buffers))))
(buffer-list)))))

(defun rigpa-buffer-create-ring ()
(defun rigpa-buffer-refresh-ring ()
"Create or update the buffer ring upon entry into buffer mode."
(interactive)
(let* ((ring-name (if (eq rigpa--complex rigpa-meta-tower-complex)
Expand Down Expand Up @@ -264,8 +261,7 @@ current ('original') buffer."

(defhydra hydra-buffer (:columns 3
:body-pre (chimera-hydra-signal-entry chimera-buffer-mode)
:post (progn (rigpa-buffer-link-to-original)
(chimera-hydra-portend-exit chimera-buffer-mode t))
:post (chimera-hydra-portend-exit chimera-buffer-mode t)
:after-exit (chimera-hydra-signal-exit chimera-buffer-mode
#'chimera-handle-hydra-exit))
"Buffer mode"
Expand Down Expand Up @@ -304,7 +300,7 @@ current ('original') buffer."
"Enter buffer mode (idempotent)."
(interactive)
(rigpa-buffer--setup-buffer-marks-table)
(rigpa-buffer-create-ring)
(rigpa-buffer-refresh-ring)
(unless (chimera-hydra-is-active-p "buffer")
(let* ((ring-name (if (eq rigpa--complex rigpa-meta-tower-complex)
"2"
Expand All @@ -315,6 +311,10 @@ current ('original') buffer."
(buffer-ring-torus-switch-to-ring buffer-ring-name))
(hydra-buffer/body)))

(defun rigpa--on-buffer-mode-post-exit ()
"Actions to take upon exit from buffer mode."
(rigpa-buffer-link-to-original))

(defvar chimera-buffer-mode
(make-chimera-mode :name "buffer"
:enter #'rigpa-buffer-enter-mode
Expand Down
65 changes: 37 additions & 28 deletions rigpa-mode-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
(defvar rigpa-modes
(ht))

(defun rigpa--minor-mode-enable-hook (name)
(defun rigpa--minor-mode-enabler (name)
"Return a function to enable the minor mode for the mode named NAME.
We modulate keybindings in evil states (e.g. in particular visual and
Expand All @@ -53,27 +53,28 @@ the minor mode is activated *before* entering the evil state, we need
to define pre-entry hooks at the chimera level and can't just use the
evil entry hooks.
We need this extra layer of indirection because lambdas as hooks
can't be removed since they are anonymous. This just gives us a way
to parametrize the hook but still be able to remove it."
We need this extra layer of indirection because lambdas can't be
removed from hooks since they are anonymous. This just gives us a way
to parametrize the hook function but still be able to remove it."
(let ((enable-mode
(intern
(concat "rigpa--enable-" name "-minor-mode"))))
enable-mode))

(defun rigpa--on-mode-entry (name)
"Return the function that takes actions upon mode entry."
(let ((on-entry
(intern
(concat "rigpa--on-" name "-mode-entry"))))
on-entry))
(intern
(concat "rigpa--on-" name "-mode-entry")))

(defun rigpa--on-mode-exit (name)
"Return the function that takes actions upon mode exit."
(let ((on-exit
(intern
(concat "rigpa--on-" name "-mode-exit"))))
on-exit))
(intern
(concat "rigpa--on-" name "-mode-exit")))

(defun rigpa--on-mode-post-exit (name)
"Return the function that takes actions upon mode post-exit."
(intern
(concat "rigpa--on-" name "-mode-post-exit")))

(defun rigpa--disable-other-minor-modes ()
"Disable all rigpa mode minor modes.
Expand All @@ -98,17 +99,21 @@ to ensure, upon state transitions, that:
(let ((name (chimera-mode-name mode))
(pre-entry-hook (chimera-mode-pre-entry-hook mode))
(entry-hook (chimera-mode-entry-hook mode))
(exit-hook (chimera-mode-exit-hook mode)))
(exit-hook (chimera-mode-exit-hook mode))
(post-exit-hook (chimera-mode-post-exit-hook mode)))
(ht-set! rigpa-modes name mode)
(let ((minor-mode-entry (rigpa--minor-mode-enable-hook name)))
(let ((minor-mode-entry (rigpa--minor-mode-enabler name)))
(when (fboundp minor-mode-entry)
(add-hook pre-entry-hook minor-mode-entry)))
(let ((on-mode-entry (rigpa--on-mode-entry name)))
(when (fboundp on-mode-entry)
(add-hook pre-entry-hook on-mode-entry)))
(let ((on-mode-exit (rigpa--on-mode-exit name)))
(when (fboundp on-mode-exit)
(add-hook exit-hook on-mode-exit)))
(let ((fn (rigpa--on-mode-entry name)))
(when (fboundp fn)
(add-hook pre-entry-hook fn)))
(let ((fn (rigpa--on-mode-exit name)))
(when (fboundp fn)
(add-hook exit-hook fn)))
(let ((fn (rigpa--on-mode-post-exit name)))
(when (fboundp fn)
(add-hook post-exit-hook fn)))
(add-hook entry-hook #'rigpa-reconcile-level)
(add-hook pre-entry-hook #'rigpa--disable-other-minor-modes)
(add-hook exit-hook #'rigpa-remember-for-recall)))
Expand All @@ -118,17 +123,21 @@ to ensure, upon state transitions, that:
(let ((name (chimera-mode-name mode))
(pre-entry-hook (chimera-mode-pre-entry-hook mode))
(entry-hook (chimera-mode-entry-hook mode))
(exit-hook (chimera-mode-exit-hook mode)))
(exit-hook (chimera-mode-exit-hook mode))
(post-exit-hook (chimera-mode-post-exit-hook mode)))
(ht-remove! rigpa-modes name)
(let ((minor-mode-entry (rigpa--minor-mode-enable-hook name)))
(let ((minor-mode-entry (rigpa--minor-mode-enabler name)))
(when (fboundp minor-mode-entry)
(remove-hook pre-entry-hook minor-mode-entry)))
(let ((on-mode-entry (rigpa--on-mode-entry name)))
(when (fboundp on-mode-entry)
(remove-hook pre-entry-hook on-mode-entry)))
(let ((on-mode-exit (rigpa--on-mode-exit name)))
(when (fboundp on-mode-exit)
(remove-hook exit-hook on-mode-exit)))
(let ((fn (rigpa--on-mode-entry name)))
(when (fboundp fn)
(remove-hook pre-entry-hook fn)))
(let ((fn (rigpa--on-mode-exit name)))
(when (fboundp fn)
(remove-hook exit-hook fn)))
(let ((fn (rigpa--on-mode-post-exit name)))
(when (fboundp fn)
(remove-hook post-exit-hook fn)))
(remove-hook entry-hook #'rigpa-reconcile-level)
(remove-hook pre-entry-hook #'rigpa--disable-other-minor-modes)
(remove-hook exit-hook #'rigpa-remember-for-recall)))
Expand Down
2 changes: 1 addition & 1 deletion rigpa-view-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@
(blink-cursor-mode -1)
(internal-show-cursor nil nil))

(defun rigpa--on-view-mode-exit ()
(defun rigpa--on-view-mode-post-exit ()
"Actions to take upon exit from view mode."
(blink-cursor-mode 1) ; TODO: depend on user config instead
(internal-show-cursor nil t)
Expand Down
2 changes: 1 addition & 1 deletion rigpa.el
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
;; Author: Siddhartha Kasivajhula <[email protected]>
;; URL: https://github.com/countvajhula/rigpa
;; Version: 0.1
;; Package-Requires: ((emacs "26.1") (evil "1.2.14") (hydra "0.15.0") (symex "0.8.1") (dynaring "0.3") (buffer-ring "0.3") (ivy "0.13.0") (centaur-tabs "3.1") (beacon "1.3.4") (dictionary "1.11") (ace-window "0.9.0") (git-timemachine "4.11") (parsec "0.1.3") (ht "2.0") (s "1.12.0") (dash "2.18.0") (transpose-frame "0.2.0"))
;; Package-Requires: ((emacs "26.1") (evil "1.2.14") (hydra "0.15.0") (symex "0.8.1") (dynaring "0.3") (buffer-ring "0.3.1") (ivy "0.13.0") (centaur-tabs "3.1") (beacon "1.3.4") (dictionary "1.11") (ace-window "0.9.0") (git-timemachine "4.11") (parsec "0.1.3") (ht "2.0") (s "1.12.0") (dash "2.18.0") (transpose-frame "0.2.0"))
;; Keywords: emulations, frames, convenience

;; This program is "part of the world," in the sense described at
Expand Down

0 comments on commit e51b14b

Please sign in to comment.