[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/window-commander ccf0d780a5 078/170: Add support for cu
From: |
ELPA Syncer |
Subject: |
[elpa] externals/window-commander ccf0d780a5 078/170: Add support for custom window commands |
Date: |
Wed, 28 Jun 2023 19:00:28 -0400 (EDT) |
branch: externals/window-commander
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)
- [elpa] externals/window-commander 2002152fb7 023/170: ; Add .gitignore file, (continued)
- [elpa] externals/window-commander 2002152fb7 023/170: ; Add .gitignore file, ELPA Syncer, 2023/06/28
- [elpa] externals/window-commander 5937f8bc6e 043/170: ; Update .gitignore to ignore some build artifacts, ELPA Syncer, 2023/06/28
- [elpa] externals/window-commander d5ab98b9db 044/170: ; Bump version to 1.1, ELPA Syncer, 2023/06/28
- [elpa] externals/window-commander 04ace20d03 063/170: ; Fix indentation and compact structure in some places, ELPA Syncer, 2023/06/28
- [elpa] externals/window-commander eba70478e0 065/170: Update window information after 'swsw-scope' is customized, ELPA Syncer, 2023/06/28
- [elpa] externals/window-commander d195e574c0 066/170: ; Add latest changes to the news file, ELPA Syncer, 2023/06/28
- [elpa] externals/window-commander cf70d1d22c 071/170: ; Make an if statement more readable, ELPA Syncer, 2023/06/28
- [elpa] externals/window-commander b3e00165f2 073/170: ; Add latest changes to the NEWS file and indicate that 1.1.2 is WIP, ELPA Syncer, 2023/06/28
- [elpa] externals/window-commander 522bfb2da0 074/170: ; Add versioning scheme information to the NEWS file, ELPA Syncer, 2023/06/28
- [elpa] externals/window-commander 3261f323e9 077/170: ; Bump version to 1.1.2, ELPA Syncer, 2023/06/28
- [elpa] externals/window-commander ccf0d780a5 078/170: Add support for custom window commands,
ELPA Syncer <=
- [elpa] externals/window-commander b10ff98f3d 079/170: Add a window deletion command, ELPA Syncer, 2023/06/28
- [elpa] externals/window-commander 51fcc776bd 081/170: ; Reorganize swsw.el, ELPA Syncer, 2023/06/28
- [elpa] externals/window-commander 69dfbd08de 083/170: ; Bump version to 2.0, ELPA Syncer, 2023/06/28
- [elpa] externals/window-commander 8febd864f9 085/170: ; Remove old reference to 'swsw-minibuffer-id', ELPA Syncer, 2023/06/28
- [elpa] externals/window-commander 220c023a2a 088/170: ; Update copyright years, ELPA Syncer, 2023/06/28
- [elpa] externals/window-commander c884983ae2 090/170: ; Fix makefile for OpenBSD, ELPA Syncer, 2023/06/28
- [elpa] externals/window-commander 3882424448 099/170: ; Bump to version 2.0.2, ELPA Syncer, 2023/06/28
- [elpa] externals/window-commander 09bb140ee3 096/170: * swsw.el (swsw-update): Use 'dotimes' instead of 'while', ELPA Syncer, 2023/06/28
- [elpa] externals/window-commander 7db205a145 105/170: ; Change all instances of "‘" and "’" to "`" and "'" respectively, ELPA Syncer, 2023/06/28
- [elpa] externals/window-commander 384dae5d45 128/170: ; Move local mode declaration to the top of NEWS, ELPA Syncer, 2023/06/28