@@ -167,16 +167,78 @@ This is just a pass through to message usually. However, it can be
167
167
overridden in tests to test the output of message."
168
168
(when resize-window-notify-with-messages (apply #'message info)))
169
169
170
+ (defun resize-window--key-str (key )
171
+ " Return the string representation of KEY.
172
+ KEY is a symbol, character (integer), key text, or key sequence.
173
+
174
+ For instance, ?n \" n\" [?n] [(?n)] are considered the same, and
175
+ ?\\ C-n \" C-n\" \" \\ C-n\" [?\\ C-n] [(?\\ C-n)] [(control ?n)] too."
176
+ ; ; NOTE: Fail loudly when KEY is wrong to help debugging.
177
+ (key-description
178
+ (cond
179
+ ((and (not (booleanp key))
180
+ (or (symbolp key) (integerp key)))
181
+ (vector key))
182
+ ((stringp key)
183
+ (kbd key))
184
+ ((vectorp key)
185
+ key)
186
+ (t
187
+ (signal 'wrong-type-argument
188
+ `((symbolp integerp stringp vectorp) , key ))))))
189
+
190
+ (defun resize-window--keys-equal (&rest keys )
191
+ " Return non-nil if KEYS are considered equal.
192
+ If there is only one key return non-nil."
193
+ (let ((key-str (resize-window--key-str (car keys))))
194
+ (not (find-if-not
195
+ (lambda (k )
196
+ (string= key-str (resize-window--key-str k)))
197
+ (cdr keys)))))
198
+
199
+ (defun resize-window--key-to-lower (key )
200
+ " Return the lowercase key sequence of KEY.
201
+ Return nil if KEY isn't an uppercase letter."
202
+ (let* ((key-str (resize-window--key-str key))
203
+ (char (if (= (length key-str) 1 ) (string-to-char key-str))))
204
+ (and char
205
+ (member char resize-window--capital-letters)
206
+ (vector (+ char 32 )))))
207
+
208
+ (defun resize-window--key-to-upper (key )
209
+ " Return the uppercase key sequence of KEY.
210
+ Return nil if KEY isn't an lowercase letter."
211
+ (let* ((key-str (resize-window--key-str key))
212
+ (char (if (= (length key-str) 1 ) (string-to-char key-str))))
213
+ (and char
214
+ (member char resize-window--lower-letters)
215
+ (vector (- char 32 )))))
216
+
217
+ (defun resize-window--key-element (key sequence )
218
+ " Return the first element in SEQUENCE whose car equals KEY."
219
+ (let ((key-str (resize-window--key-str key)))
220
+ (assoc-if
221
+ (lambda (k )
222
+ (string= key-str (resize-window--key-str k)))
223
+ sequence)))
224
+
170
225
(defun resize-window--match-alias (key )
171
- " Taken the KEY or keyboard selection from `read-key' check for alias.
226
+ " Taken the KEY or keyboard selection check for alias.
172
227
Match the KEY against the alias table. If found, return the value that it
173
228
points to, which should be a key in the `resize-window-dispatch-alist' .
174
229
Otherwise, return the KEY."
175
- (let ((alias (assoc key resize-window-alias-list)))
230
+ (let ((alias (resize-window--key-element
231
+ key resize-window-alias-list)))
176
232
(if alias
177
233
(car (cdr alias))
178
234
key)))
179
235
236
+ (defun resize-window--match-dispatch (key )
237
+ " Taken the KEY or keyboard selection check for an action.
238
+ Match the KEY against the alias table `resize-window-dispatch-alist' ."
239
+ (resize-window--key-element
240
+ key resize-window-dispatch-alist))
241
+
180
242
(defun resize-window--choice-keybinding (choice )
181
243
" Get the keybinding associated with CHOICE."
182
244
(car choice))
@@ -201,8 +263,11 @@ nil."
201
263
CHOICE is a \( key function documentation allows-capitals\) ."
202
264
(let ((key (resize-window--choice-keybinding choice)))
203
265
(concat (if (resize-window--allows-capitals choice)
204
- (format " %s |%s " (string key) (string (- key 32 )))
205
- (format " %s " (string key)))
266
+ (format " %s |%s "
267
+ (resize-window--key-str key)
268
+ (resize-window--key-to-upper key))
269
+ (format " %s "
270
+ (resize-window--key-str key)))
206
271
" : "
207
272
(resize-window--choice-documentation choice))))
208
273
@@ -238,7 +303,8 @@ CHOICE is a \(key function documentation allows-capitals\).
238
303
If SCALED, then call action with the `resize-window-uppercase-argument' ."
239
304
(let ((action (resize-window--choice-lambda choice))
240
305
(description (resize-window--choice-documentation choice)))
241
- (unless (equal (resize-window--choice-keybinding choice) ?? )
306
+ (unless (resize-window--keys-equal
307
+ (resize-window--choice-keybinding choice) [?? ])
242
308
(resize-window--notify " %s" description))
243
309
(condition-case nil
244
310
(if scaled
@@ -247,7 +313,7 @@ If SCALED, then call action with the `resize-window-uppercase-argument'."
247
313
(wrong-number-of-arguments
248
314
(resize-window--notify
249
315
" Invalid arity in function for %s"
250
- (char-to-string
316
+ (resize-window--key-str
251
317
(resize-window--choice-keybinding choice)))))))
252
318
253
319
;;;### autoload
@@ -260,37 +326,37 @@ to resize right."
260
326
; ; NOTE: Do not trim the stack here. Let stack requests to handle
261
327
; ; window configurations in excess.
262
328
(resize-window--add-backgrounds)
263
- (resize-window--notify " Resize mode: enter character , ? for help" )
329
+ (resize-window--notify " Resize mode: insert KEY , ? for help" )
264
330
(condition-case nil
265
- (let ((reading-characters t )
331
+ (let ((reading-keys t )
266
332
; ; allow mini-buffer to collapse after displaying menu
267
333
(resize-mini-windows t ))
268
- (while reading-characters
269
- (let* ((char (resize-window--match-alias (read-key )))
270
- (choice (assoc char resize-window-dispatch-alist))
271
- (capital (when (numberp char)
272
- (assoc (+ char 32 ) resize-window-dispatch-alist))))
334
+ (while reading-keys
335
+ (let* ((kin (read-key-sequence-vector nil nil t ))
336
+ (key (and kin (resize-window--match-alias kin)))
337
+ (choice (and key (resize-window--match-dispatch key)))
338
+ (lower (and key (resize-window--key-to-lower key)))
339
+ (capital (and lower (resize-window--match-dispatch lower))))
273
340
(cond
274
341
(choice (resize-window--execute-action choice))
275
342
((and capital (resize-window--allows-capitals capital))
276
343
; ; rather than pass an argument, we tell it to "scale" it
277
344
; ; with t and that method can worry about how to get that
278
345
; ; action
279
346
(resize-window--execute-action capital t ))
280
- (; ; NOTE: Don't use `=' , if `char' is a symbol like
281
- ; ; 'insertchar it will fail. Use `equal' instead.
282
- (or resize-window-unregistered-key-quit
283
- (equal char ?q )
284
- (equal char ?Q )
285
- (equal char (string-to-char " " )))
286
- (setq reading-characters nil )
347
+ ((or resize-window-unregistered-key-quit
348
+ (resize-window--keys-equal key [?q ])
349
+ (resize-window--keys-equal key [?Q ])
350
+ (resize-window--keys-equal key [? ])
351
+ (resize-window--keys-equal key " C-g" ))
352
+ (setq reading-keys nil )
287
353
(resize-window--display-menu 'kill )
288
354
(resize-window--remove-backgrounds))
289
355
(t
290
356
(resize-window--notify
291
357
(format
292
- " Unregistered key: (%s) %s"
293
- char ( single- key-description char ))))))))
358
+ " Unregistered key: %s -> %s"
359
+ key (resize-window-- key-str key ))))))))
294
360
(quit
295
361
(resize-window--display-menu 'kill )
296
362
(resize-window--remove-backgrounds))))
@@ -539,22 +605,26 @@ See also `resize-window-stack-size'."
539
605
540
606
(defun resize-window--key-available? (key )
541
607
" Return non-nil if KEY is bound, otherwise return nil."
542
- (and (not (assoc key resize-window-alias-list))
543
- (not (assoc key resize-window-dispatch-alist))))
608
+ (and (not (resize-window--key-element
609
+ key resize-window-alias-list))
610
+ (not (resize-window--key-element
611
+ key resize-window-dispatch-alist))))
544
612
545
613
(defun resize-window-add-choice (key func doc &optional allows-capitals )
546
614
" Register a new binding for `resize-window' .
547
- KEY is the char (eg ?c) that should invoke the FUNC. DOC is a doc
548
- string for the help menu, and optional ALLOWS-CAPITALS should be
549
- t or nil. Functions should be of zero arity if they do not allow
550
- capitals, and should be of optional single arity if they allow
551
- capitals. Invoking with the capital will pass the capital
552
- argument."
615
+
616
+ KEY is the key (e.g. ?c) that invokes the function FUNC. DOC is a
617
+ docstring for the help menu. A non-nil ALLOWS-CAPITALS tells FUNC
618
+ accepts capital letters. FUNC should be of zero arity if does not
619
+ allow capitals, otherwise to allow capitals should be of optional
620
+ single arity so a capital KEY may be passed to FUNC when pressed.
621
+
622
+ See also `resize-window--key-str' ."
553
623
(if (resize-window--key-available? key)
554
624
(push (list key func doc allows-capitals)
555
625
resize-window-dispatch-alist)
556
626
(message " The `%s ` key is already taken for resize-window. "
557
- (char-to-string key))))
627
+ (resize-window--key-str key))))
558
628
559
629
(provide 'resize-window )
560
630
; ;; resize-window.el ends here
0 commit comments