@@ -167,16 +167,78 @@ This is just a pass through to message usually. However, it can be
167167overridden in tests to test the output of message."
168168 (when resize-window-notify-with-messages (apply #'message info)))
169169
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 (cl-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+ (cl-assoc-if
221+ (lambda (k )
222+ (string= key-str (resize-window--key-str k)))
223+ sequence)))
224+
170225(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.
172227Match the KEY against the alias table. If found, return the value that it
173228points to, which should be a key in the `resize-window-dispatch-alist' .
174229Otherwise, 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)))
176232 (if alias
177233 (car (cdr alias))
178234 key)))
179235
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+
180242(defun resize-window--choice-keybinding (choice )
181243 " Get the keybinding associated with CHOICE."
182244 (car choice))
@@ -201,8 +263,12 @@ nil."
201263CHOICE is a \( key function documentation allows-capitals\) ."
202264 (let ((key (resize-window--choice-keybinding choice)))
203265 (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-str
269+ (resize-window--key-to-upper key)))
270+ (format " %s "
271+ (resize-window--key-str key)))
206272 " : "
207273 (resize-window--choice-documentation choice))))
208274
@@ -238,7 +304,8 @@ CHOICE is a \(key function documentation allows-capitals\).
238304If SCALED, then call action with the `resize-window-uppercase-argument' ."
239305 (let ((action (resize-window--choice-lambda choice))
240306 (description (resize-window--choice-documentation choice)))
241- (unless (equal (resize-window--choice-keybinding choice) ?? )
307+ (unless (resize-window--keys-equal
308+ (resize-window--choice-keybinding choice) [?? ])
242309 (resize-window--notify " %s" description))
243310 (condition-case nil
244311 (if scaled
@@ -247,7 +314,7 @@ If SCALED, then call action with the `resize-window-uppercase-argument'."
247314 (wrong-number-of-arguments
248315 (resize-window--notify
249316 " Invalid arity in function for %s"
250- (char-to-string
317+ (resize-window--key-str
251318 (resize-window--choice-keybinding choice)))))))
252319
253320;;;### autoload
@@ -260,38 +327,38 @@ to resize right."
260327 ; ; NOTE: Do not trim the stack here. Let stack requests to handle
261328 ; ; window configurations in excess.
262329 (resize-window--add-backgrounds)
263- (resize-window--notify " Resize mode: enter character , ? for help" )
330+ (resize-window--notify " Resize mode: insert KEY , ? for help" )
264331 (condition-case nil
265- (let ((reading-characters t )
332+ (let ((reading-keys t )
266333 ; ; allow mini-buffer to collapse after displaying menu
267334 (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))))
335+ (while reading-keys
336+ (let* ((kin (read-key-sequence-vector nil nil t ))
337+ (key (and kin (resize-window--match-alias kin)))
338+ (choice (and key (resize-window--match-dispatch key)))
339+ (lower (and key (resize-window--key-to-lower key)))
340+ (capital (and lower (resize-window--match-dispatch lower))))
273341 (cond
274342 (choice (resize-window--execute-action choice))
275343 ((and capital (resize-window--allows-capitals capital))
276344 ; ; rather than pass an argument, we tell it to "scale" it
277345 ; ; with t and that method can worry about how to get that
278346 ; ; action
279347 (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 )
348+ ((or resize-window-unregistered-key-quit
349+ (resize-window--keys-equal key [?q ])
350+ (resize-window--keys-equal key [?Q ])
351+ (resize-window--keys-equal key [? ])
352+ (resize-window--keys-equal key " C-g" ))
353+ (setq reading-keys nil )
287354 (message nil )
288355 (resize-window--display-menu 'kill )
289356 (resize-window--remove-backgrounds))
290357 (t
291358 (resize-window--notify
292359 (format
293- " Unregistered key: (%s) %s"
294- char ( single- key-description char ))))))))
360+ " Unregistered key: %s -> %s"
361+ key (resize-window-- key-str key ))))))))
295362 (quit
296363 (message nil )
297364 (resize-window--display-menu 'kill )
@@ -551,22 +618,26 @@ See also `resize-window-stack-size'."
551618
552619(defun resize-window--key-available? (key )
553620 " Return non-nil if KEY is bound, otherwise return nil."
554- (and (not (assoc key resize-window-alias-list))
555- (not (assoc key resize-window-dispatch-alist))))
621+ (and (not (resize-window--key-element
622+ key resize-window-alias-list))
623+ (not (resize-window--key-element
624+ key resize-window-dispatch-alist))))
556625
557626(defun resize-window-add-choice (key func doc &optional allows-capitals )
558627 " Register a new binding for `resize-window' .
559- KEY is the char (eg ?c) that should invoke the FUNC. DOC is a doc
560- string for the help menu, and optional ALLOWS-CAPITALS should be
561- t or nil. Functions should be of zero arity if they do not allow
562- capitals, and should be of optional single arity if they allow
563- capitals. Invoking with the capital will pass the capital
564- argument."
628+
629+ KEY is the key (e.g. ?c) that invokes the function FUNC. DOC is a
630+ docstring for the help menu. A non-nil ALLOWS-CAPITALS tells FUNC
631+ accepts capital letters. FUNC should be of zero arity if does not
632+ allow capitals, otherwise to allow capitals should be of optional
633+ single arity so a capital KEY may be passed to FUNC when pressed.
634+
635+ See also `resize-window--key-str' ."
565636 (if (resize-window--key-available? key)
566637 (push (list key func doc allows-capitals)
567638 resize-window-dispatch-alist)
568639 (message " The `%s ` key is already taken for resize-window. "
569- (char-to-string key))))
640+ (resize-window--key-str key))))
570641
571642(provide 'resize-window )
572643; ;; resize-window.el ends here
0 commit comments