diff options
author | Sean Whitton <spwhitton@spwhitton.name> | 2022-01-28 23:14:14 -0700 |
---|---|---|
committer | Sean Whitton <spwhitton@spwhitton.name> | 2022-01-29 16:58:47 -0700 |
commit | a863a322b8b5eb1dd18948fde8be5f7e2ca4f13b (patch) | |
tree | 6d2ced5df86c97a1a06f537a9018abdeed8372a4 /.emacs.d/site-lisp | |
parent | 851fa42498456f46ffd0efbf88ec6d236802458f (diff) | |
download | dotfiles-a863a322b8b5eb1dd18948fde8be5f7e2ca4f13b.tar.gz |
attempt to extract transient-cycles-window-buffers-mode
Diffstat (limited to '.emacs.d/site-lisp')
-rw-r--r-- | .emacs.d/site-lisp/transient-cycles.el | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/.emacs.d/site-lisp/transient-cycles.el b/.emacs.d/site-lisp/transient-cycles.el index 08789259..f03df062 100644 --- a/.emacs.d/site-lisp/transient-cycles.el +++ b/.emacs.d/site-lisp/transient-cycles.el @@ -404,7 +404,75 @@ keys are \\`<left>' and \\`<right>'. Otherwise the fallbacks `transient-cycles-default-cycle-backwards-key' and `transient-cycles-default-cycle-forwards-key' are used." :lighter nil :keymap transient-cycles-window-buffers-mode-map :global t - :group 'transient-cycles) + :group 'transient-cycles + (if transient-cycles-window-buffers-mode + ;; Clear window parameter just when the list of next buffers is cleared. + (advice-add 'set-window-buffer :after + #'transient-cycles--reset-window-recent-buffer) + (advice-remove 'set-window-buffer + #'transient-cycles--reset-window-recent-buffer))) + +(cl-symbol-macrolet + ((param (window-parameter nil 'transient-cycles--window-recent-bufer))) + (transient-cycles-define-commands (recent-buffer last-recent-buffer) + (([remap previous-buffer] (count) + (interactive "p") + (setq recent-buffer (and (window-next-buffers) count) + last-recent-buffer param) + (previous-buffer count)) + + ([remap next-buffer] (count) + (interactive "p") + ;; We consider only the window's next buffers, not the frame's next + ;; buffers as `next-buffer' does. This is because otherwise our + ;; `recent-buffer' and window parameter become invalid. + ;; + ;; `previous-buffer' and `next-buffer' use `switch-to-prev-buffer' and + ;; `switch-to-next-buffer' as subroutines, so buffers previously shown + ;; in the selected window come up first + (if (window-next-buffers) + (progn (setq recent-buffer (* -1 count) + last-recent-buffer param) + (next-buffer count)) + (user-error "No next buffer")))) + + (lambda (_ignore) + (lambda (count) + (if (cl-plusp count) + (if (window-next-buffers) + (progn (when recent-buffer (cl-decf recent-buffer count)) + (next-buffer count)) + (message "No next buffer")) + (setq count (* -1 count)) + (when recent-buffer (cl-incf recent-buffer count)) + (previous-buffer count)))) + ;; If `recent-buffer' is zero then we are back where we started. + ;; in. In that case, restore the old parameter value so that + ;; `transient-cycles-window-buffers-back-and-forth' does something useful. + :on-exit (setq param (if (and recent-buffer (zerop recent-buffer)) + last-recent-buffer + recent-buffer)) + :keymap transient-cycles-window-buffers-mode-map) + + (defun transient-cycles--reset-window-recent-buffer (&rest _ignore) + (setq param nil)) + + (defun transient-cycles-window-buffers-back-and-forth () + "Switch to the buffer most recently accessed using the bindings +established by `transient-cycles-window-buffers-mode', on the +condition that no other commands have set this window's buffer +since then. Otherwise, call `previous-buffer'." + (interactive) + (cond (param + (let ((new (and (window-next-buffers) (* -1 param)))) + (cond ((cl-plusp param) (next-buffer param)) + ((cl-minusp param) (previous-buffer (* -1 param)))) + (setq param new))) + ((window-next-buffers) + (let ((count (length (window-next-buffers)))) + (next-buffer count) + (setq param (* -1 count)))) + (t (previous-buffer))))) (provide 'transient-cycles) |