Browse Source

Add `exwm-nw-find-workspace' which uses completing-read

tags/v0.1.0^0
Peter J. Jones 1 year ago
parent
commit
0f39c89406
Signed by: Peter Jones <pjones@devalot.com> GPG Key ID: 9DAFAA8D01941E49
3 changed files with 86 additions and 20 deletions
  1. 7
    0
      CHANGES.md
  2. 21
    0
      README.md
  3. 58
    20
      exwm-nw.el

+ 7
- 0
CHANGES.md View File

@@ -0,0 +1,7 @@
1
+Release Notes for `exwm-nw`
2
+===========================
3
+
4
+Version 0.1.0 (June 22, 2018)
5
+-----------------------------
6
+
7
+  * Initial release

+ 21
- 0
README.md View File

@@ -0,0 +1,21 @@
1
+Named Workspaces for EXWM
2
+=========================
3
+
4
+Global minor mode that helps manage workspaces in EXWM.
5
+
6
+Some of its features are:
7
+
8
+  - Keep a history of workspaces in a ring
9
+  - Assign a name to a workspace (`exwm-nw-set`)
10
+  - Jump to the previous workspace (`exwm-nw-goto-previous`)
11
+  - Jump to a workspace by name (`exwm-nw-find-workspace`)
12
+
13
+By default this minor mode does not have any keybindings in order
14
+to avoid clobbering any bindings you may already have.  Here are
15
+some recommendations:
16
+
17
+    (define-key exwm-nw-mode-map (kbd "s-n") 'exwm-nw-set)
18
+    (define-key exwm-nw-mode-map (kbd "s-l") 'exwm-nw-goto-previous)
19
+    (define-key exwm-workspace--switch-map (kbd "C-u") 'universal-argument)
20
+    (define-key exwm-workspace--switch-map (kbd "C-s") 'exwm-nw-find-workspace)
21
+    (define-key exwm-workspace--switch-map (kbd "C-l") 'exwm-nw-goto-previous)

+ 58
- 20
exwm-nw.el View File

@@ -11,7 +11,8 @@
11 11
 
12 12
 ;;; Commentary:
13 13
 ;;
14
-;; FIXME:
14
+;; Assign names to EXWM worspaces and jump to workspaces using their
15
+;; names.  See the documentation for `exwm-nw-mode'.
15 16
 
16 17
 ;;; License:
17 18
 ;;
@@ -36,6 +37,7 @@
36 37
 
37 38
 ;;; Code:
38 39
 (require 'ring)
40
+(require 'map)
39 41
 (require 'exwm)
40 42
 
41 43
 
@@ -56,10 +58,10 @@ workspaces."
56 58
 (defvar exwm-nw-mode-map (make-sparse-keymap)
57 59
   "Key map for the `exwm-nw' minor mode.")
58 60
 
59
-(defvar exwm-nw-prev-workspace-index-map exwm-workspace-index-map
61
+(defvar exwm-nw--prev-workspace-index-map exwm-workspace-index-map
60 62
   "Used to restore the previous value of `exwm-workspace-index-map'.")
61 63
 
62
-(defvar exwm-nw-workspace-ring nil
64
+(defvar exwm-nw--workspace-ring nil
63 65
   "Ring of workspaces.")
64 66
 
65 67
 (defvar exwm-nw--previous-workspace nil
@@ -67,16 +69,11 @@ workspaces."
67 69
 
68 70
 
69 71
 ;; Internal Functions
70
-(defun exwm-nw-set-name-prompt (workspace)
72
+(defun exwm-nw--set-name-prompt (workspace)
71 73
   "Prompt for the new name of WORKSPACE."
72
-  (read-string "Workspace Name: " (exwm-nw-get workspace)))
74
+  (read-string "Workspace name: " (exwm-nw-get workspace)))
73 75
 
74
-(defun exwm-nw-get (frame-or-index)
75
-  "Return the name of the workspace identified by FRAME-OR-INDEX."
76
-  (let ((ws (exwm-workspace--workspace-from-frame-or-index frame-or-index)))
77
-    (frame-parameter ws 'exwm-nw-name)))
78
-
79
-(defun exwm-nw-format (index)
76
+(defun exwm-nw--format (index)
80 77
   "Format the name of the workspace at INDEX."
81 78
   (let ((name (exwm-nw-get index)))
82 79
     (if name (format "%s:%s" index name)
@@ -92,7 +89,7 @@ workspaces."
92 89
              (not (equal exwm-nw--previous-workspace
93 90
                          exwm-workspace--current)))
94 91
     (ring-remove+insert+extend
95
-     exwm-nw-workspace-ring
92
+     exwm-nw--workspace-ring
96 93
      exwm-nw--previous-workspace)))
97 94
 
98 95
 (defun exwm-nw--goto-workspace (workspace)
@@ -104,8 +101,30 @@ workspaces."
104 101
           (exit-minibuffer)))
105 102
     (exwm-workspace-switch workspace)))
106 103
 
104
+(defun exwm-nw--workspace-alist (keep-current)
105
+  "Return an alist of workspace names and their indexes.
106
+
107
+When KEEP-CURRENT is non-nil then the current workspace will be
108
+included in the returned alist.
109
+
110
+The alist is ordered so that recently visited workspaces come first."
111
+  (let ((current exwm-workspace--current) names)
112
+    (dolist (w (append (ring-elements exwm-nw--workspace-ring)
113
+                       exwm-workspace--list))
114
+      (if (and (exwm-workspace--workspace-p w)
115
+               (or keep-current (not (eq w current))))
116
+          (let ((name (exwm-nw-get w))
117
+                (pos  (exwm-workspace--position w)))
118
+            (if (and name (not (assoc name names)))
119
+                (setq names (append names (list (cons name pos))))))))
120
+    names))
121
+
107 122
 
108 123
 ;; Public functions:
124
+(defun exwm-nw-get (frame-or-index)
125
+  "Return the name of the workspace identified by FRAME-OR-INDEX."
126
+  (let ((ws (exwm-workspace--workspace-from-frame-or-index frame-or-index)))
127
+    (frame-parameter ws 'exwm-nw-name)))
109 128
 
110 129
 ;;;###autoload
111 130
 (defun exwm-nw-set (frame-or-index &optional name)
@@ -115,7 +134,7 @@ You probably want to bind this function to a key in
115 134
 `exwm-nw-mode-map'."
116 135
   (interactive (list exwm-workspace--current nil))
117 136
   (let* ((ws (exwm-workspace--workspace-from-frame-or-index frame-or-index))
118
-         (name (or name (exwm-nw-set-name-prompt ws))))
137
+         (name (or name (exwm-nw--set-name-prompt ws))))
119 138
     (when (and ws name)
120 139
       (set-frame-parameter ws 'exwm-nw-name name)
121 140
       (setq exwm-workspace--switch-history-outdated t))))
@@ -127,26 +146,45 @@ You probably want to bind this function to a key in
127 146
 You may want to bind this function to a key in `exwm-nw-mode-map'
128 147
 and in `exwm-workspace--switch-map'."
129 148
   (interactive)
130
-  (let ((ws (ring-ref exwm-nw-workspace-ring 0)))
149
+  (let ((ws (ring-ref exwm-nw--workspace-ring 0)))
131 150
     (when ws (exwm-nw--goto-workspace ws))))
132 151
 
152
+;;;###autoload
153
+(defun exwm-nw-find-workspace (allow-create)
154
+  "Pick a workspace from a completion list and go there.
155
+
156
+When ALLOW-CREATE is non-nil, allow creating new workspaces."
157
+  (interactive "P")
158
+  (let* ((names (exwm-nw--workspace-alist nil))
159
+         (must-match (if allow-create 'confirm t))
160
+         (result (completing-read "Workspace: " names nil must-match))
161
+         (selected (cdr (assoc result names))))
162
+    (if selected (exwm-nw--goto-workspace
163
+                  (exwm-workspace--workspace-from-frame-or-index selected))
164
+      (when allow-create
165
+        (exwm-workspace-switch-create (exwm-workspace--count))
166
+        (exwm-nw-set exwm-workspace--current result)
167
+        (exwm-nw--goto-workspace exwm-workspace--current)))))
168
+
133 169
 ;;;###autoload
134 170
 (define-minor-mode exwm-nw-mode
135 171
   "Global minor mode that helps manage workspaces in EXWM.
136 172
 
137 173
 Some of its features are:
138 174
 
139
-  - Assign a name to a workspace (`exwm-nw-set')
140 175
   - Keep a history of workspaces in a ring
176
+  - Assign a name to a workspace (`exwm-nw-set')
141 177
   - Jump to the previous workspace (`exwm-nw-goto-previous')
178
+  - Jump to a workspace by name (`exwm-nw-find-workspace')
142 179
 
143 180
 By default this minor mode does not have any keybindings in order
144 181
 to avoid clobbering any bindings you may already have.  Here are
145 182
 some recommendations:
146 183
 
147
-
148 184
     (define-key exwm-nw-mode-map (kbd \"s-n\") 'exwm-nw-set)
149 185
     (define-key exwm-nw-mode-map (kbd \"s-l\") 'exwm-nw-goto-previous)
186
+    (define-key exwm-workspace--switch-map (kbd \"C-u\") 'universal-argument)
187
+    (define-key exwm-workspace--switch-map (kbd \"C-s\") 'exwm-nw-find-workspace)
150 188
     (define-key exwm-workspace--switch-map (kbd \"C-l\") 'exwm-nw-goto-previous)
151 189
 
152 190
 Enjoy!"
@@ -155,12 +193,12 @@ Enjoy!"
155 193
   :global t
156 194
   (if exwm-nw-mode
157 195
       (progn
158
-        (setq exwm-nw-prev-workspace-index-map exwm-workspace-index-map
159
-              exwm-workspace-index-map #'exwm-nw-format
160
-              exwm-nw-workspace-ring (make-ring exwm-nw-workspace-ring-size))
196
+        (setq exwm-nw--prev-workspace-index-map exwm-workspace-index-map
197
+              exwm-workspace-index-map #'exwm-nw--format
198
+              exwm-nw--workspace-ring (make-ring exwm-nw-workspace-ring-size))
161 199
         (add-hook 'exwm-workspace-switch-hook #'exwm-nw--workspace-switch-hook)
162 200
         (advice-add 'exwm-workspace-switch :before #'exwm-nw--remember-current-workspace))
163
-    (setq exwm-workspace-index-map exwm-nw-prev-workspace-index-map)
201
+    (setq exwm-workspace-index-map exwm-nw--prev-workspace-index-map)
164 202
     (remove-hook 'exwm-workspace-switch-hook #'exwm-nw--workspace-switch-hook)
165 203
     (advice-remove 'exwm-workspace-switch #'exwm-nw--remember-current-workspace)))
166 204
 

Loading…
Cancel
Save