emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/swsw ccf0d780a5 078/146: Add support for custom window com


From: ELPA Syncer
Subject: [nongnu] elpa/swsw ccf0d780a5 078/146: Add support for custom window commands
Date: Wed, 25 May 2022 02:59:48 -0400 (EDT)

branch: elpa/swsw
commit ccf0d780a586e5b8465933b3d8e01c86efc42ca1
Author: Daniel Semyonov <cmstr@dsemy.com>
Commit: Daniel Semyonov <cmstr@dsemy.com>

    Add support for custom window commands
    
    * swsw.el (swsw--set-id-chars): Remove 'swsw-minibuffer-id' member
    check.
    (swsw-minibuffer-id, swsw--set-minibuffer-id): Removed.
    (swsw--id-map): New keymap for selecting window IDs.
    (swsw-window-count): New variable holding the amount of tracked
    windows.
    (swsw-update-window): Only increment 'swsw-window-count' when updating
    information for the minibuffer.  Replace addition of window to
    'swsw-window-list' with the addition of a command to 'swsw--id-map'.
    Add a step incrementing 'swsw-window-count'.
    (swsw-update): Add step resetting 'swsw--id-map'.
    (swsw--run-window-command): New helper function for defining window
    commands.
    (swsw-select): Redefine using 'swsw--run-window-command'.
    (swsw-select-minibuffer): New command for selecting the minibuffer if
    it's active.
    (swsw-command-map): New keymap for window commands.
    (swsw-format-id): Don't reverse the string.
    (swsw--read-id): Removed.
    (swsw-mode): Update hook steps to reflect changes to the hooks' names.
---
 swsw.el | 161 ++++++++++++++++++++++++++++++++++------------------------------
 1 file changed, 85 insertions(+), 76 deletions(-)

diff --git a/swsw.el b/swsw.el
index e174fee961..a60120c3d1 100644
--- a/swsw.el
+++ b/swsw.el
@@ -59,6 +59,11 @@
 
 ;;; Code:
 
+;; Avoid byte-compilation warnings.
+(eval-when-compile
+  (defvar swsw-display-function)
+  (defvar swsw-command-map))
+
 ;;;; Customization:
 
 (defgroup swsw nil
@@ -68,19 +73,13 @@
 
 (defun swsw--set-id-chars (sym chars)
   "Set the variable ‘swsw-id-chars’.
-Check that the new list has at least two elements, check that no
-element is equal to ‘swsw-minibuffer-id’, set SYM’s value to
+Check that the new list has at least two elements, set SYM’s value to
 CHARS, and call ‘swsw-update’."
-  (cond ((< (length chars) 2)
-         (user-error
-          "‘swsw-id-chars’ should contain at least two characters"))
-        ((memq ?m chars)
-         (user-error
-          "‘swsw-id-chars’ shouldn't contain ‘swsw-minibuffer-id’"))
-        (t
-         (set-default sym chars)
-         (when (fboundp 'swsw-update)
-           (swsw-update)))))
+  (when (< (length chars) 2)
+    (user-error "‘swsw-id-chars’ should contain at least two characters"))
+  (set-default sym chars)
+  (when (fboundp 'swsw-update)
+    (swsw-update)))
 
 (defcustom swsw-id-chars '(?a ?s ?d ?f ?g ?h ?j ?k ?l)
   "Base set of characters from which window IDs are constructed.
@@ -89,21 +88,6 @@ No character in this list should be equal to 
‘swsw-minibuffer-id’."
   :type '(repeat character)
   :set #'swsw--set-id-chars)
 
-(defun swsw--set-minibuffer-id (sym id)
-  "Set the variable ‘swsw-minbuffer-id’.
-Check that ID isn't a member of ‘swsw-id-chars’ and set SYM’s value to
-ID."
-  (if (memq id swsw-id-chars)
-      (user-error
-       "‘swsw-minibuffer-id’ shouldn't be a member of ‘swsw-id-chars’")
-    (set-default sym id)))
-
-(defcustom swsw-minibuffer-id ?m
-  "ID reserved for the minibuffer.
-This character shouldn't appear in ‘swsw-id-chars’."
-  :type '(character)
-  :set #'swsw--set-minibuffer-id)
-
 (defun swsw--set-scope (sym scope)
   "Set the variable ‘swsw-scope’.
 Set SYM’s value to SCOPE and call ‘swsw-update’."
@@ -127,9 +111,6 @@ t means consider all windows on all existing frames.
                  current))
   :set #'swsw--set-scope)
 
-(eval-when-compile ; Avoid byte-compilation warning.
-  (defvar swsw-display-function))
-
 (defun swsw--set-display-function (sym fun)
   "Set the variable ‘swsw-display-function’.
 Call the previous display function with nil as the sole argument
@@ -156,10 +137,16 @@ If set to ‘lighter’, use the mode line lighter of 
‘swsw-mode’."
 %s is replaced with a representation of the window's ID."
   :type '(string))
 
-;;;; Simple window switching minor mode:
+;;;; Window tracking:
 
-(defvar swsw-window-list nil
-  "Alist of active active windows and their IDs.")
+(defvar swsw--id-counter nil
+  "Counter which determines the next possible ID.")
+
+(defvar swsw--id-map (make-sparse-keymap)
+  "Key map for window ID selection.")
+
+(defvar swsw-window-count 0
+  "Amount of windows that have been assigned an ID.")
 
 (defun swsw--get-scope ()
   "Return the current scope in which windows should be tracked."
@@ -174,9 +161,6 @@ If set to ‘lighter’, use the mode line lighter of 
‘swsw-mode’."
     (if (= windows 1) 1
       (ceiling (log windows (length swsw-id-chars))))))
 
-(defvar swsw--id-counter nil
-  "Counter which determines the next possible ID.")
-
 (defun swsw--next-id ()
   "Get the next available ID."
   (let ((len (length swsw-id-chars)) (adv-flag t) id)
@@ -195,57 +179,82 @@ If set to ‘lighter’, use the mode line lighter of 
‘swsw-mode’."
 (defun swsw-update-window (window)
   "Update information for WINDOW."
   (let ((id (if (window-minibuffer-p window)
-                swsw-minibuffer-id
+                (progn
+                  (setq swsw-window-count (1+ swsw-window-count))
+                  nil)
               (swsw--next-id))))
     (when id
-      (push (cons id window) swsw-window-list)
-      (set-window-parameter window 'swsw-id id))))
+      (define-key swsw--id-map (apply #'vector id)
+        `(lambda ()
+           (interactive)
+           (funcall last-command ,window)))
+      (set-window-parameter window 'swsw-id id)
+      (setq swsw-window-count (1+ swsw-window-count)))))
 
 (defun swsw-update (&optional _frame)
   "Update information for all windows."
-  (setq swsw-window-list nil
-        swsw--id-counter nil)
+  (setq swsw--id-map (make-sparse-keymap))
+  (set-keymap-parent swsw--id-map swsw-command-map)
+  (setq swsw--id-counter nil
+        swsw-window-count 0)
   (let ((acc 0) (len (swsw--get-id-length)))
     (while (< acc len)
       (push 0 swsw--id-counter)
       (setq acc (1+ acc))))
   (walk-windows #'swsw-update-window nil (swsw--get-scope)))
 
+;;;; Window commands:
+
+(defun swsw--run-window-command (fun)
+  "Run FUN as a window command.
+Run ‘swsw-before-command-hook’, set ‘this-command’ to FUN and set a
+transient map for ID selection which runs ‘swsw-after-command-hook’ on
+exit."
+  (run-hooks 'swsw-before-command-hook)
+  (setq this-command fun)
+  (set-transient-map swsw--id-map (lambda ()
+                                    (run-hooks
+                                     'swsw-after-command-hook))))
+
+(defun swsw-select ()
+  "Start window selection.
+If less than three windows have been assigned an ID, switch to the
+window returned by ‘next-window’.
+Otherwise, window selection allows either choosing a window by its ID
+\(switching to it), or using a window manipulation command.
+This command is intended to be used only when ‘swsw-mode’ is enabled."
+  (interactive)
+  (if (< swsw-window-count 3)
+      (select-window (next-window))
+    (swsw--run-window-command #'select-window)))
+
+(defun swsw-select-minibuffer ()
+  "Select the active minibuffer window (if it exists).
+This command is intended to be used only when ‘swsw-mode’ is enabled."
+  (interactive)
+  (let ((window (active-minibuffer-window)))
+    (if window (select-window window)
+      (message "There is no active minibuffer window"))))
+
+(defvar swsw-command-map (let ((map (make-sparse-keymap)))
+                           (define-key map [?o] #'swsw-select)
+                           (define-key map [?m] #'swsw-select-minibuffer)
+                           map)
+  "Key map for window commands.
+This key map is set as the parent of ‘swsw--id-map’ during ID
+selection.")
+
+;;;; Simple window switching mode:
+
 (defun swsw-format-id (window)
   "Format an ID string for WINDOW."
   (format swsw-id-format
-          (reverse (apply #'string (window-parameter window 'swsw-id)))))
-
-(defun swsw--read-id (len)
-  "Read a window ID of length LEN using ‘read-char’."
-  (let ((acc 1) id)
-    ;; Special case for the minibuffer.
-    (if (eq (car (push (read-char) id)) swsw-minibuffer-id)
-        id
-      (while (< acc len)
-        (push (read-char) id)
-        (setq acc (1+ acc)))
-      (list id))))
-
-(defun swsw-select (&optional id)
-  "Select a window by its ID.
-If less than three windows have been assigned an ID, select the
-window returned by ‘next-window’.
-This command is intended to be used only when ‘swsw-mode’ is enabled."
-  (interactive (unless (< (length swsw-window-list) 3)
-                 (run-hooks 'swsw-before-select-hook)
-                 (unwind-protect
-                     (swsw--read-id (swsw--get-id-length))
-                   (run-hooks 'swsw-after-select-hook))))
-  (let ((window (cdr (assoc id swsw-window-list))))
-    (select-window (if window window
-                     (if id (selected-window) (next-window))))))
+          (apply #'string (window-parameter window 'swsw-id))))
 
 ;;;###autoload
 (define-minor-mode swsw-mode
-  "Minor mode for selecting windows by their ID.
-
-Use \\[swsw-select] to select a window."
+  "Minor mode for managing windows using an ID assigned to them
+automatically."
   :global t
   :lighter
   (:eval (when (eq swsw-display-function 'lighter)
@@ -298,17 +307,17 @@ This display function respects ‘swsw-id-format’."
 
 (defun swsw-mode-line-conditional-display-function (switch)
   "Display window IDs at the beginning of the mode line, conditionally.
-Add a hook to ‘swsw-before-select-hook’ which displays window IDs on
-the mode line and add a hook to ‘swsw-after-select-hook’ which hides
+Add a hook to ‘swsw-before-command-hook’ which displays window IDs on
+the mode line and add a hook to ‘swsw-after-command-hook’ which hides
 window IDs from the mode line if SWITCH isn't nil, and remove those
 hooks if SWITCH is nil.
 This display function respects ‘swsw-id-format’."
   (if switch
       (progn
-        (add-hook 'swsw-before-select-hook #'swsw--mode-line-display)
-        (add-hook 'swsw-after-select-hook #'swsw--mode-line-hide))
-    (remove-hook 'swsw-before-select-hook #'swsw--mode-line-display)
-    (remove-hook 'swsw-after-select-hook #'swsw--mode-line-hide)))
+        (add-hook 'swsw-before-command-hook #'swsw--mode-line-display)
+        (add-hook 'swsw-after-command-hook #'swsw--mode-line-hide))
+    (remove-hook 'swsw-before-command-hook #'swsw--mode-line-display)
+    (remove-hook 'swsw-after-command-hook #'swsw--mode-line-hide)))
 
 (provide 'swsw)
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]