refactor(tazjin/emacs): refactor LRU workspace list to use ring.el
This built-in emacs library actually provides a data structure that can work as an LRU list through the existing helper function to move an element to the front of the ring if it already exists. As a result, the code for workspace history moving becomes a lot less brittle and complicated than it was before. No more carefully figuring out when to modify state, just push it in the ring unless it's being rotated already. Change-Id: If354e0618fc5a6d7333776468eec077596cfe9df Reviewed-on: https://cl.tvl.fyi/c/depot/+/9162 Reviewed-by: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI
This commit is contained in:
parent
0a7a9e96ab
commit
d6bce3f83d
1 changed files with 21 additions and 40 deletions
|
@ -11,6 +11,7 @@
|
||||||
(require 'exwm-systemtray)
|
(require 'exwm-systemtray)
|
||||||
(require 'exwm-xim )
|
(require 'exwm-xim )
|
||||||
(require 'f)
|
(require 'f)
|
||||||
|
(require 'ring)
|
||||||
(require 's)
|
(require 's)
|
||||||
|
|
||||||
(defcustom tazjin--screen-lock-command "tazjin-screen-lock"
|
(defcustom tazjin--screen-lock-command "tazjin-screen-lock"
|
||||||
|
@ -136,47 +137,31 @@
|
||||||
|
|
||||||
;; Implement MRU functionality for EXWM workspaces, making it possible
|
;; Implement MRU functionality for EXWM workspaces, making it possible
|
||||||
;; to jump to the previous/next workspace very easily.
|
;; to jump to the previous/next workspace very easily.
|
||||||
(defvar *recent-workspaces* nil
|
(defvar *recent-workspaces-ring* (make-ring 5)
|
||||||
"List of the most recently used EXWM workspaces.")
|
"Ring of recently used EXWM workspaces.")
|
||||||
|
|
||||||
(defvar *workspace-jumping-to* nil
|
(defvar *workspace-ring-is-rotating* nil
|
||||||
"What offset in the workspace history are we jumping to?")
|
"Variable used to track whether the workspace ring is rotating,
|
||||||
|
and suppress insertions into the ring in that case.")
|
||||||
(defvar *workspace-history-position* 0
|
|
||||||
"Where in the workspace history are we right now?")
|
|
||||||
|
|
||||||
(defun update-recent-workspaces ()
|
(defun update-recent-workspaces ()
|
||||||
"Hook to run on every workspace switch which will prepend the new
|
"Hook run on EXWM workspace switches, adding new workspaces to the
|
||||||
workspace to the MRU list, unless we are already on that
|
ring."
|
||||||
workspace. Does not affect the MRU list if a jump is
|
|
||||||
in-progress."
|
|
||||||
|
|
||||||
(if *workspace-jumping-to*
|
(unless *workspace-ring-is-rotating*
|
||||||
(setq *workspace-history-position* *workspace-jumping-to*
|
(ring-remove+insert+extend *recent-workspaces-ring* exwm-workspace-current-index)))
|
||||||
*workspace-jumping-to* nil)
|
|
||||||
|
|
||||||
;; reset the history position to the front on a normal jump
|
|
||||||
(setq *workspace-history-position* 0)
|
|
||||||
|
|
||||||
(unless (eq exwm-workspace-current-index (car *recent-workspaces*))
|
|
||||||
(setq *recent-workspaces* (cons exwm-workspace-current-index
|
|
||||||
(-take 9 *recent-workspaces*))))))
|
|
||||||
|
|
||||||
(add-to-list 'exwm-workspace-switch-hook #'update-recent-workspaces)
|
(add-to-list 'exwm-workspace-switch-hook #'update-recent-workspaces)
|
||||||
|
|
||||||
(defun switch-to-previous-workspace ()
|
(defun switch-to-previous-workspace ()
|
||||||
"Switch to the previous workspace in the MRU workspace list."
|
"Switch to the previous workspace in the workspace ring."
|
||||||
(interactive)
|
(interactive)
|
||||||
|
|
||||||
(let* (;; the previous workspace is one position further down in the
|
(when-let ((*workspace-ring-is-rotating* t)
|
||||||
;; workspace history
|
(previous (condition-case err (ring-next *recent-workspaces-ring*
|
||||||
(position (+ *workspace-history-position* 1))
|
exwm-workspace-current-index)
|
||||||
(target-idx (elt *recent-workspaces* position)))
|
('error (message "No previous workspace in history!") nil))))
|
||||||
(if (not target-idx)
|
(exwm-workspace-switch previous)))
|
||||||
(message "No previous workspace in history!")
|
|
||||||
|
|
||||||
(setq *workspace-jumping-to* position)
|
|
||||||
(exwm-workspace-switch target-idx))))
|
|
||||||
|
|
||||||
(exwm-input-set-key (kbd "s-b") #'switch-to-previous-workspace)
|
(exwm-input-set-key (kbd "s-b") #'switch-to-previous-workspace)
|
||||||
|
|
||||||
|
@ -184,15 +169,11 @@ in-progress."
|
||||||
"Switch to the next workspace in the MRU workspace list."
|
"Switch to the next workspace in the MRU workspace list."
|
||||||
(interactive)
|
(interactive)
|
||||||
|
|
||||||
(if (= *workspace-history-position* 0)
|
(when-let ((*workspace-ring-is-rotating* t)
|
||||||
(message "No next workspace in history!")
|
(next (condition-case err (ring-previous *recent-workspaces-ring*
|
||||||
(let* (;; The next workspace is one position further up in the
|
exwm-workspace-current-index)
|
||||||
;; history. This always exists unless someone messed with
|
('error (message "No next workspace in history!") nil))))
|
||||||
;; it.
|
(exwm-workspace-switch next)))
|
||||||
(position (- *workspace-history-position* 1))
|
|
||||||
(target-idx (elt *recent-workspaces* position)))
|
|
||||||
(setq *workspace-jumping-to* position)
|
|
||||||
(exwm-workspace-switch target-idx))))
|
|
||||||
|
|
||||||
(exwm-input-set-key (kbd "s-f") #'switch-to-next-workspace)
|
(exwm-input-set-key (kbd "s-f") #'switch-to-next-workspace)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue