about summary refs log tree commit diff
path: root/users/tazjin/emacs/config/desktop.el
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2023-08-28T20·25+0300
committertazjin <tazjin@tvl.su>2023-08-29T08·22+0000
commitd6bce3f83d2c1052c38ecba1445bbc10a9f03123 (patch)
tree35ff39dbfd54984d487671e4b7a97d10c746a6cc /users/tazjin/emacs/config/desktop.el
parent0a7a9e96ab0419439b1efc57b50091ae3507f005 (diff)
refactor(tazjin/emacs): refactor LRU workspace list to use ring.el r/6533
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
Diffstat (limited to 'users/tazjin/emacs/config/desktop.el')
-rw-r--r--users/tazjin/emacs/config/desktop.el61
1 files changed, 21 insertions, 40 deletions
diff --git a/users/tazjin/emacs/config/desktop.el b/users/tazjin/emacs/config/desktop.el
index 4789fda465..51a3f20848 100644
--- a/users/tazjin/emacs/config/desktop.el
+++ b/users/tazjin/emacs/config/desktop.el
@@ -11,6 +11,7 @@
 (require 'exwm-systemtray)
 (require 'exwm-xim )
 (require 'f)
+(require 'ring)
 (require 's)
 
 (defcustom tazjin--screen-lock-command "tazjin-screen-lock"
@@ -136,47 +137,31 @@
 
 ;; Implement MRU functionality for EXWM workspaces, making it possible
 ;; to jump to the previous/next workspace very easily.
-(defvar *recent-workspaces* nil
-  "List of the most recently used EXWM workspaces.")
+(defvar *recent-workspaces-ring* (make-ring 5)
+  "Ring of recently used EXWM workspaces.")
 
-(defvar *workspace-jumping-to* nil
-  "What offset in the workspace history are we jumping to?")
-
-(defvar *workspace-history-position* 0
-  "Where in the workspace history are we right now?")
+(defvar *workspace-ring-is-rotating* nil
+  "Variable used to track whether the workspace ring is rotating,
+and suppress insertions into the ring in that case.")
 
 (defun update-recent-workspaces ()
-  "Hook to run on every workspace switch which will prepend the new
-workspace to the MRU list, unless we are already on that
-workspace. Does not affect the MRU list if a jump is
-in-progress."
-
-  (if *workspace-jumping-to*
-      (setq *workspace-history-position* *workspace-jumping-to*
-            *workspace-jumping-to* nil)
+  "Hook run on EXWM workspace switches, adding new workspaces to the
+ring."
 
-    ;; 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*))))))
+  (unless *workspace-ring-is-rotating*
+    (ring-remove+insert+extend *recent-workspaces-ring* exwm-workspace-current-index)))
 
 (add-to-list 'exwm-workspace-switch-hook #'update-recent-workspaces)
 
 (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)
 
-  (let* (;; the previous workspace is one position further down in the
-         ;; workspace history
-         (position (+ *workspace-history-position* 1))
-         (target-idx (elt *recent-workspaces* position)))
-    (if (not target-idx)
-        (message "No previous workspace in history!")
-
-      (setq *workspace-jumping-to* position)
-      (exwm-workspace-switch target-idx))))
+  (when-let ((*workspace-ring-is-rotating* t)
+             (previous (condition-case err (ring-next *recent-workspaces-ring*
+                                                      exwm-workspace-current-index)
+                         ('error (message "No previous workspace in history!") nil))))
+    (exwm-workspace-switch previous)))
 
 (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."
   (interactive)
 
-  (if (= *workspace-history-position* 0)
-      (message "No next workspace in history!")
-    (let* (;; The next workspace is one position further up in the
-           ;; history. This always exists unless someone messed with
-           ;; it.
-           (position (- *workspace-history-position* 1))
-           (target-idx (elt *recent-workspaces* position)))
-      (setq *workspace-jumping-to* position)
-      (exwm-workspace-switch target-idx))))
+  (when-let ((*workspace-ring-is-rotating* t)
+             (next (condition-case err (ring-previous *recent-workspaces-ring*
+                                                      exwm-workspace-current-index)
+                     ('error (message "No next workspace in history!") nil))))
+    (exwm-workspace-switch next)))
 
 (exwm-input-set-key (kbd "s-f") #'switch-to-next-workspace)