Skip to content

Commit

Permalink
Add modifier-list type and fix make-key to accept `modifier' type.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ambrevar committed Dec 12, 2023
1 parent 9518898 commit 714cfe3
Showing 1 changed file with 14 additions and 9 deletions.
23 changes: 14 additions & 9 deletions keymap.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,18 @@ filters out the modifier in its `modifiers' slot."
(deftype key-status-type ()
`(member :pressed :released))

(deftype modifier-list ()
"List of modifiers are sets: they are ordered and have no duplicates."
`fset:wb-set)

;; Must be a structure so that it can served as a key in a hash-table with
;; #'equalp tests.
(defstruct (key (:constructor %make-key (code value modifiers status))
(:copier %copy-key))
"The fundamental type to represent any input, be it keyboard, mouse or others."
(code 0 :type integer) ; TODO: Can a keycode be 0? I think not, so 0 might be a good non-value.
(value "" :type string)
(modifiers (fset:set) :type fset:wb-set)
(modifiers (fset:set) :type modifier-list)
(status :pressed :type key-status-type))

(defun key= (key1 key2)
Expand Down Expand Up @@ -89,17 +93,18 @@ specify a key-code binding."
:message (format nil "Unknown modifier ~a" string-or-modifier))))))

(declaim (ftype (function ((or (list-of string)
fset:wb-set))
fset:wb-set)
(list-of modifier)
modifier-list))
modifier-list)
modspecs->modifiers))
(defun modspecs->modifiers (strings-or-modifiers)
"Return the list of `modifier's corresponding to STRINGS-OR-MODIFIERS."
(flet ((list-difference (list1 list2)
(dolist (list2-elt list2 list1)
(setf list1 (delete list2-elt list1 :count 1)))))
(if (fset:set? strings-or-modifiers)
(if (typep strings-or-modifiers 'modifier-list)
strings-or-modifiers
(the (values fset:wb-set &optional)
(the (values modifier-list &optional)
(fset:convert 'fset:set
(let* ((mods (mapcar #'modspec->modifier strings-or-modifiers))
(no-dups-mods (delete-duplicates mods :test #'modifier=)))
Expand All @@ -116,8 +121,8 @@ specify a key-code binding."
modifiers
(status :pressed))
"Return new `key'.
Modifiers can be either a `modifier' type or a string that will be looked up in
`*modifier-list*'."
Modifiers can be either a list of `modifier' types or of strings that will be
looked up in `*modifier-list*'."
(unless (or explicit-code explicit-value)
(error 'make-key-required-arg))
(%make-key
Expand All @@ -127,7 +132,7 @@ Modifiers can be either a `modifier' type or a string that will be looked up in
status))

(declaim (ftype (function (key &key (:code integer) (:value string)
(:modifiers fset:wb-set) (:status keyword))
(:modifiers modifier-list) (:status keyword))
key)
copy-key))
(defun copy-key (key &key (code (key-code key)) (value (key-value key))
Expand Down Expand Up @@ -244,7 +249,7 @@ Parents are ordered by priority, the first parent has highest priority.")
(modifiers :accessor modifiers
:initarg :modifiers
:initform (fset:convert 'fset:set *modifier-list*)
:type fset:wb-set
:type modifier-list
:documentation "
Accepted modifiers for this `keymap'."))
(:documentation "A map of `key' bindings to values.
Expand Down

0 comments on commit 714cfe3

Please sign in to comment.