| [6] | 1 | ;;; -*- Log: hemlock.log; Package: Hemlock-Internals -*-
|
|---|
| 2 | ;;;
|
|---|
| 3 | ;;; **********************************************************************
|
|---|
| 4 | ;;; This code was written as part of the CMU Common Lisp project at
|
|---|
| 5 | ;;; Carnegie Mellon University, and has been placed in the public domain.
|
|---|
| 6 | ;;;
|
|---|
| 7 | #+CMU (ext:file-comment
|
|---|
| 8 | "$Header$")
|
|---|
| 9 | ;;;
|
|---|
| 10 | ;;; **********************************************************************
|
|---|
| 11 | ;;;
|
|---|
| 12 | ;;; Written by Rob MacLachlan and Blaine Burks.
|
|---|
| 13 | ;;;
|
|---|
| 14 | ;;; This file contains the routines which define hemlock commands and
|
|---|
| 15 | ;;; the command interpreter.
|
|---|
| 16 | ;;;
|
|---|
| 17 |
|
|---|
| 18 | (in-package :hemlock-internals)
|
|---|
| 19 |
|
|---|
| [553] | 20 |
|
|---|
| 21 |
|
|---|
| [670] | 22 |
|
|---|
| [6] | 23 | (defun %print-hcommand (obj stream depth)
|
|---|
| 24 | (declare (ignore depth))
|
|---|
| 25 | (write-string "#<Hemlock Command \"" stream)
|
|---|
| 26 | (write-string (command-name obj) stream)
|
|---|
| 27 | (write-string "\">" stream))
|
|---|
| 28 |
|
|---|
| 29 |
|
|---|
| 30 | |
|---|
| 31 |
|
|---|
| 32 | ;;;; Key Tables:
|
|---|
| 33 | ;;;
|
|---|
| 34 | ;;; A key table provides a way to translate a sequence of characters to some
|
|---|
| 35 | ;;; lisp object. It is currently represented by a tree of hash-tables, where
|
|---|
| 36 | ;;; each level is a hashing from a key to either another hash-table or a value.
|
|---|
| 37 |
|
|---|
| 38 |
|
|---|
| 39 | ;;; GET-TABLE-ENTRY returns the value at the end of a series of hashings. For
|
|---|
| 40 | ;;; our purposes it is presently used to look up commands and key-translations.
|
|---|
| [8428] | 41 | ;;;
|
|---|
| [6] | 42 | (defun get-table-entry (table key &key (end (length key)))
|
|---|
| [8428] | 43 | (let ((foo nil))
|
|---|
| [6] | 44 | (dotimes (i end foo)
|
|---|
| 45 | (let ((key-event (aref key i)))
|
|---|
| 46 | (setf foo (gethash key-event table))
|
|---|
| 47 | (unless (hash-table-p foo) (return foo))
|
|---|
| 48 | (setf table foo)))))
|
|---|
| 49 |
|
|---|
| 50 | ;;; SET-TABLE-ENTRY sets the entry for key in table to val, creating new
|
|---|
| 51 | ;;; tables as needed. If val is nil, then use REMHASH to remove this element
|
|---|
| 52 | ;;; from the hash-table.
|
|---|
| 53 | ;;;
|
|---|
| 54 | (defun set-table-entry (table key val)
|
|---|
| 55 | (dotimes (i (1- (length key)))
|
|---|
| 56 | (let* ((key-event (aref key i))
|
|---|
| 57 | (foo (gethash key-event table)))
|
|---|
| 58 | (if (hash-table-p foo)
|
|---|
| 59 | (setf table foo)
|
|---|
| 60 | (let ((new-table (make-hash-table)))
|
|---|
| 61 | (setf (gethash key-event table) new-table)
|
|---|
| 62 | (setf table new-table)))))
|
|---|
| 63 | (if (null val)
|
|---|
| 64 | (remhash (aref key (1- (length key))) table)
|
|---|
| 65 | (setf (gethash (aref key (1- (length key))) table) val)))
|
|---|
| 66 |
|
|---|
| 67 | |
|---|
| 68 |
|
|---|
| 69 | ;;;; Key Translation:
|
|---|
| 70 | ;;;
|
|---|
| 71 | ;;; Key translations are maintained using a key table. If a value is an
|
|---|
| 72 | ;;; integer, then it is prefix bits to be OR'ed with the next character. If it
|
|---|
| 73 | ;;; is a key, then we translate to that key.
|
|---|
| 74 |
|
|---|
| 75 | (defvar *key-translations* (make-hash-table))
|
|---|
| 76 |
|
|---|
| 77 | ;;; TRANSLATE-KEY -- Internal
|
|---|
| 78 | ;;;
|
|---|
| 79 | ;;; This is used internally to do key translations when we want the
|
|---|
| 80 | ;;; canonical representation for Key. Result, if supplied, is an adjustable
|
|---|
| 81 | ;;; vector with a fill pointer. We compute the output in this vector. If the
|
|---|
| 82 | ;;; key ends in the prefix of a translation, we just return that part
|
|---|
| 83 | ;;; untranslated and return the second value true.
|
|---|
| 84 | ;;;
|
|---|
| [8428] | 85 | (defun translate-key (key &optional (result (make-array (length key)
|
|---|
| 86 | :fill-pointer 0
|
|---|
| [6] | 87 | :adjustable t))
|
|---|
| 88 | (temp (make-array 10 :fill-pointer 0 :adjustable t)))
|
|---|
| 89 | (let ((key-len (length key))
|
|---|
| 90 | (start 0)
|
|---|
| 91 | (try-pos 0)
|
|---|
| 92 | (prefix 0))
|
|---|
| 93 | (setf (fill-pointer temp) 0)
|
|---|
| 94 | (setf (fill-pointer result) 0)
|
|---|
| 95 | (loop
|
|---|
| 96 | (when (= try-pos key-len) (return))
|
|---|
| [8428] | 97 | (let ((key-event (aref key try-pos)))
|
|---|
| [6] | 98 | (vector-push-extend
|
|---|
| 99 | (make-key-event key-event (logior (key-event-bits key-event) prefix))
|
|---|
| 100 | temp)
|
|---|
| 101 | (setf prefix 0))
|
|---|
| 102 | (let ((entry (get-table-entry *key-translations* temp)))
|
|---|
| 103 | (cond ((hash-table-p entry)
|
|---|
| 104 | (incf try-pos))
|
|---|
| 105 | (t
|
|---|
| 106 | (etypecase entry
|
|---|
| 107 | (null
|
|---|
| 108 | (vector-push-extend (aref temp 0) result)
|
|---|
| 109 | (incf start))
|
|---|
| 110 | (simple-vector
|
|---|
| 111 | (dotimes (i (length entry))
|
|---|
| 112 | (vector-push-extend (aref entry i) result))
|
|---|
| 113 | (setf start (1+ try-pos)))
|
|---|
| 114 | (integer
|
|---|
| 115 | (setf start (1+ try-pos))
|
|---|
| 116 | (when (= start key-len) (return))
|
|---|
| 117 | (setf prefix (logior entry prefix))))
|
|---|
| 118 | (setq try-pos start)
|
|---|
| 119 | (setf (fill-pointer temp) 0)))))
|
|---|
| 120 | (dotimes (i (length temp))
|
|---|
| 121 | (vector-push-extend (aref temp i) result))
|
|---|
| 122 | (values result (not (zerop (length temp))))))
|
|---|
| 123 |
|
|---|
| 124 |
|
|---|
| 125 | ;;; KEY-TRANSLATION -- Public.
|
|---|
| 126 | ;;;
|
|---|
| 127 | (defun key-translation (key)
|
|---|
| 128 | "Return the key translation for Key, or NIL if there is none. If Key is a
|
|---|
| 129 | prefix of a translation, then :Prefix is returned. Whenever Key appears as a
|
|---|
| 130 | subsequence of a key argument to the binding manipulation functions, that
|
|---|
| 131 | portion will be replaced with the translation. A key translation may also be
|
|---|
| 132 | a list (:Bits {Bit-Name}*). In this case, the named bits will be set in the
|
|---|
| 133 | next character in the key being translated."
|
|---|
| 134 | (let ((entry (get-table-entry *key-translations* (crunch-key key))))
|
|---|
| 135 | (etypecase entry
|
|---|
| 136 | (hash-table :prefix)
|
|---|
| [8428] | 137 | ((or simple-vector null) entry)
|
|---|
| [6] | 138 | (integer
|
|---|
| 139 | (cons :bits (key-event-bits-modifiers entry))))))
|
|---|
| 140 |
|
|---|
| 141 | ;;; %SET-KEY-TRANSLATION -- Internal
|
|---|
| 142 | ;;;
|
|---|
| [8428] | 143 | (defun %set-key-translation (key new-value)
|
|---|
| [6] | 144 | (let ((entry (cond ((and (consp new-value) (eq (car new-value) :bits))
|
|---|
| 145 | (apply #'make-key-event-bits (cdr new-value)))
|
|---|
| 146 | (new-value (crunch-key new-value))
|
|---|
| 147 | (t new-value))))
|
|---|
| 148 | (set-table-entry *key-translations* (crunch-key key) entry)
|
|---|
| 149 | new-value))
|
|---|
| 150 | ;;;
|
|---|
| 151 | (defsetf key-translation %set-key-translation
|
|---|
| 152 | "Set the key translation for a key. If set to null, deletes any
|
|---|
| 153 | translation.")
|
|---|
| 154 |
|
|---|
| 155 |
|
|---|
| 156 | |
|---|
| 157 |
|
|---|
| 158 | ;;;; Interface Utility Functions:
|
|---|
| 159 |
|
|---|
| 160 | (defvar *global-command-table* (make-hash-table)
|
|---|
| 161 | "The command table for global key bindings.")
|
|---|
| 162 |
|
|---|
| 163 | ;;; GET-RIGHT-TABLE -- Internal
|
|---|
| 164 | ;;;
|
|---|
| 165 | ;;; Return a hash-table depending on "kind" and checking for errors.
|
|---|
| 166 | ;;;
|
|---|
| 167 | (defun get-right-table (kind where)
|
|---|
| 168 | (case kind
|
|---|
| 169 | (:global
|
|---|
| 170 | (when where
|
|---|
| 171 | (error "Where argument ~S is meaningless for :global bindings."
|
|---|
| 172 | where))
|
|---|
| 173 | *global-command-table*)
|
|---|
| 174 | (:mode (let ((mode (getstring where *mode-names*)))
|
|---|
| 175 | (unless mode
|
|---|
| 176 | (error "~S is not a defined mode." where))
|
|---|
| 177 | (mode-object-bindings mode)))
|
|---|
| 178 | (:buffer (unless (bufferp where)
|
|---|
| 179 | (error "~S is not a buffer." where))
|
|---|
| 180 | (buffer-bindings where))
|
|---|
| 181 | (t (error "~S is not a valid binding type." kind))))
|
|---|
| 182 |
|
|---|
| 183 |
|
|---|
| 184 | ;;; CRUNCH-KEY -- Internal.
|
|---|
| 185 | ;;;
|
|---|
| 186 | ;;; Take a key in one of the various specifications and turn it into the
|
|---|
| 187 | ;;; standard one: a simple-vector of characters.
|
|---|
| [8428] | 188 | ;;;
|
|---|
| [6] | 189 | (defun crunch-key (key)
|
|---|
| 190 | (typecase key
|
|---|
| 191 | (key-event (vector key))
|
|---|
| [8428] | 192 | ((or list vector) ;List thrown in gratuitously.
|
|---|
| [6] | 193 | (when (zerop (length key))
|
|---|
| 194 | (error "A zero length key is illegal."))
|
|---|
| 195 | (unless (every #'key-event-p key)
|
|---|
| 196 | (error "A Key ~S must contain only key-events." key))
|
|---|
| 197 | (coerce key 'simple-vector))
|
|---|
| 198 | (t
|
|---|
| 199 | (error "Key ~S is not a key-event or sequence of key-events." key))))
|
|---|
| 200 |
|
|---|
| 201 |
|
|---|
| 202 | |
|---|
| 203 |
|
|---|
| 204 | ;;;; Exported Primitives:
|
|---|
| 205 |
|
|---|
| 206 | (declaim (special *command-names*))
|
|---|
| 207 |
|
|---|
| 208 | ;;; BIND-KEY -- Public.
|
|---|
| 209 | ;;;
|
|---|
| 210 | (defun bind-key (name key &optional (kind :global) where)
|
|---|
| 211 | "Bind a Hemlock command to some key somewhere. Name is the string name
|
|---|
| 212 | of a Hemlock command, Key is either a key-event or a vector of key-events.
|
|---|
| 213 | Kind is one of :Global, :Mode or :Buffer, and where is the mode name or
|
|---|
| 214 | buffer concerned. Kind defaults to :Global."
|
|---|
| 215 | ;;(with-simple-restart (continue "Go on, ignoring binding attempt."))
|
|---|
| 216 | (handler-bind ((error
|
|---|
| [8428] | 217 | #'(lambda (condition)
|
|---|
| 218 | (format *error-output*
|
|---|
| 219 | "~&Error while trying to bind key ~A: ~A~%"
|
|---|
| [6] | 220 | key condition)
|
|---|
| 221 | (message (format nil "~a" condition))
|
|---|
| 222 | #-GZ (return-from bind-key nil)
|
|---|
| 223 | )))
|
|---|
| 224 | (let ((cmd (getstring name *command-names*))
|
|---|
| 225 | (table (get-right-table kind where))
|
|---|
| 226 | (key (copy-seq (translate-key (crunch-key key)))))
|
|---|
| 227 | (cond (cmd
|
|---|
| 228 | (set-table-entry table key cmd)
|
|---|
| 229 | (push (list key kind where) (command-%bindings cmd))
|
|---|
| 230 | cmd)
|
|---|
| 231 | (t
|
|---|
| 232 | (error "~S is not a defined command." name))))))
|
|---|
| 233 |
|
|---|
| 234 |
|
|---|
| 235 | ;;; DELETE-KEY-BINDING -- Public
|
|---|
| 236 | ;;;
|
|---|
| 237 | ;;; Stick NIL in the key table specified.
|
|---|
| 238 | ;;;
|
|---|
| 239 | (defun delete-key-binding (key &optional (kind :global) where)
|
|---|
| 240 | "Remove a Hemlock key binding somewhere. Key is either a key-event or a
|
|---|
| 241 | vector of key-events. Kind is one of :Global, :Mode or :Buffer, andl where
|
|---|
| 242 | is the mode name or buffer concerned. Kind defaults to :Global."
|
|---|
| 243 | (set-table-entry (get-right-table kind where)
|
|---|
| 244 | (translate-key (crunch-key key))
|
|---|
| 245 | nil))
|
|---|
| 246 |
|
|---|
| 247 |
|
|---|
| 248 | ;;; GET-CURRENT-BINDING -- Internal
|
|---|
| [16082] | 249 | ;;;
|
|---|
| [8428] | 250 | ;;; Look up a key in the current environment.
|
|---|
| 251 | ;;;
|
|---|
| 252 | (defun get-current-binding (key)
|
|---|
| 253 | (let ((buffer (current-buffer))
|
|---|
| 254 | (t-bindings nil) res t-res)
|
|---|
| 255 | (multiple-value-setq (res t-res) (get-binding-in-buffer key buffer))
|
|---|
| 256 | (when t-res (push t-res t-bindings))
|
|---|
| 257 | (loop while (null res)
|
|---|
| 258 | for mode in (buffer-minor-mode-objects buffer)
|
|---|
| 259 | do (multiple-value-setq (res t-res) (get-binding-in-mode key mode))
|
|---|
| 260 | do (when t-res (push t-res t-bindings)))
|
|---|
| 261 | (when (null res)
|
|---|
| 262 | (multiple-value-setq (res t-res)
|
|---|
| [6] | 263 | (get-binding-in-mode key (buffer-major-mode-object buffer)))
|
|---|
| [8428] | 264 | (when t-res (push t-res t-bindings)))
|
|---|
| 265 | (values (or res (get-table-entry *global-command-table* key))
|
|---|
| 266 | (nreverse t-bindings))))
|
|---|
| 267 |
|
|---|
| 268 | (defun get-binding-in-buffer (key buffer)
|
|---|
| 269 | (let ((res (get-table-entry (buffer-bindings buffer) key)))
|
|---|
| [6] | 270 | (when res
|
|---|
| [8428] | 271 | (if (and (commandp res) (command-transparent-p res))
|
|---|
| 272 | (values nil res)
|
|---|
| 273 | (values res nil)))))
|
|---|
| 274 |
|
|---|
| 275 | (defun get-binding-in-mode (key mode)
|
|---|
| 276 | (let* ((res (or (get-table-entry (mode-object-bindings mode) key)
|
|---|
| 277 | (let ((default (mode-object-default-command mode)))
|
|---|
| 278 | (and default (getstring default *command-names*))))))
|
|---|
| 279 | (when res
|
|---|
| 280 | (if (or (mode-object-transparent-p mode)
|
|---|
| 281 | (and (commandp res) (command-transparent-p res)))
|
|---|
| [6] | 282 | (values nil res)
|
|---|
| 283 | (values res nil)))))
|
|---|
| 284 |
|
|---|
| 285 |
|
|---|
| 286 | ;;; GET-COMMAND -- Public.
|
|---|
| 287 | ;;;
|
|---|
| 288 | (defun get-command (key &optional (kind :global) where)
|
|---|
| 289 | "Return the command object for the command bound to key somewhere.
|
|---|
| 290 | If key is not bound, return nil. Key is either a key-event or a vector of
|
|---|
| 291 | key-events. If key is a prefix of a key-binding, then return :prefix.
|
|---|
| 292 | Kind is one of :global, :mode or :buffer, and where is the mode name or
|
|---|
| 293 | buffer concerned. Kind defaults to :Global."
|
|---|
| 294 | (multiple-value-bind (key prefix-p)
|
|---|
| 295 | (translate-key (crunch-key key))
|
|---|
| 296 | (let ((entry (if (eq kind :current)
|
|---|
| 297 | (get-current-binding key)
|
|---|
| 298 | (get-table-entry (get-right-table kind where) key))))
|
|---|
| 299 | (etypecase entry
|
|---|
| 300 | (null (if prefix-p :prefix nil))
|
|---|
| 301 | (command entry)
|
|---|
| 302 | (hash-table :prefix)))))
|
|---|
| 303 |
|
|---|
| 304 | (defvar *map-bindings-key* (make-array 5 :adjustable t :fill-pointer 0))
|
|---|
| 305 |
|
|---|
| 306 | ;;; MAP-BINDINGS -- Public.
|
|---|
| 307 | ;;;
|
|---|
| 308 | (defun map-bindings (function kind &optional where)
|
|---|
| 309 | "Map function over the bindings in some place. The function is passed the
|
|---|
| 310 | key and the command to which it is bound."
|
|---|
| 311 | (labels ((mapping-fun (hash-key hash-value)
|
|---|
| 312 | (vector-push-extend hash-key *map-bindings-key*)
|
|---|
| 313 | (etypecase hash-value
|
|---|
| 314 | (command (funcall function *map-bindings-key* hash-value))
|
|---|
| 315 | (hash-table (maphash #'mapping-fun hash-value)))
|
|---|
| 316 | (decf (fill-pointer *map-bindings-key*))))
|
|---|
| 317 | (setf (fill-pointer *map-bindings-key*) 0)
|
|---|
| 318 | (maphash #'mapping-fun (get-right-table kind where))))
|
|---|
| 319 |
|
|---|
| 320 | ;;; MAKE-COMMAND -- Public.
|
|---|
| [8428] | 321 | ;;;
|
|---|
| [6] | 322 | ;;; If the command is already defined, then alter the command object;
|
|---|
| 323 | ;;; otherwise, make a new command object and enter it into the *command-names*.
|
|---|
| 324 | ;;;
|
|---|
| 325 | (defun make-command (name documentation function &key transparent-p)
|
|---|
| 326 | "Create a new Hemlock command with Name and Documentation which is
|
|---|
| 327 | implemented by calling the function-value of the symbol Function"
|
|---|
| 328 | (let ((entry (getstring name *command-names*)))
|
|---|
| [8428] | 329 | (cond
|
|---|
| 330 | (entry
|
|---|
| [6] | 331 | (setf (command-name entry) name)
|
|---|
| 332 | (setf (command-documentation entry) documentation)
|
|---|
| [8428] | 333 | (setf (command-function entry) function)
|
|---|
| [6] | 334 | (setf (command-transparent-p entry) transparent-p))
|
|---|
| 335 | (t
|
|---|
| 336 | (setf (getstring name *command-names*)
|
|---|
| 337 | (internal-make-command name documentation function transparent-p))))))
|
|---|
| 338 |
|
|---|
| 339 |
|
|---|
| 340 | ;;; COMMAND-NAME, %SET-COMMAND-NAME -- Public.
|
|---|
| 341 | ;;;
|
|---|
| 342 | (defun command-name (command)
|
|---|
| 343 | "Returns the string which is the name of Command."
|
|---|
| 344 | (command-%name command))
|
|---|
| 345 | ;;;
|
|---|
| 346 | (defun %set-command-name (command new-name)
|
|---|
| 347 | (check-type command command)
|
|---|
| 348 | (check-type new-name string)
|
|---|
| 349 | (setq new-name (coerce new-name 'simple-string))
|
|---|
| 350 | (delete-string (command-%name command) *command-names*)
|
|---|
| 351 | (setf (getstring new-name *command-names*) command)
|
|---|
| 352 | (setf (command-%name command) new-name))
|
|---|
| 353 |
|
|---|
| 354 |
|
|---|
| 355 | ;;; COMMAND-BINDINGS -- Public.
|
|---|
| 356 | ;;;
|
|---|
| 357 | ;;; Check that all the supposed bindings really exists. Bindings which
|
|---|
| 358 | ;;; were once made may have been overwritten. It is easier to filter
|
|---|
| 359 | ;;; out bogus bindings here than to catch all the cases that can make a
|
|---|
| 360 | ;;; binding go away.
|
|---|
| 361 | ;;;
|
|---|
| 362 | (defun command-bindings (command)
|
|---|
| 363 | "Return a list of lists of the form (key kind where) describing
|
|---|
| 364 | all the places where Command is bound."
|
|---|
| 365 | (check-type command command)
|
|---|
| 366 | (let (result)
|
|---|
| 367 | (declare (list result))
|
|---|
| 368 | (dolist (place (command-%bindings command))
|
|---|
| 369 | (let ((table (case (cadr place)
|
|---|
| 370 | (:global *global-command-table*)
|
|---|
| 371 | (:mode
|
|---|
| 372 | (let ((m (getstring (caddr place) *mode-names*)))
|
|---|
| 373 | (when m (mode-object-bindings m))))
|
|---|
| 374 | (t
|
|---|
| 375 | (when (member (caddr place) *buffer-list*)
|
|---|
| 376 | (buffer-bindings (caddr place)))))))
|
|---|
| 377 | (when (and table
|
|---|
| 378 | (eq (get-table-entry table (car place)) command)
|
|---|
| [16082] | 379 | (not (member place result :test #'equalp)))
|
|---|
| 380 | (push place result))))
|
|---|
| 381 | result))
|
|---|
| 382 |
|
|---|
| 383 | ;;; COMMANDS-AND-BINDINGS -- Public
|
|---|
| 384 | ;;;
|
|---|
| 385 | ;;; Return a list of (command . key-bindings), for use in help. Looks only at bindings
|
|---|
| 386 | ;;; in modes in "Default Modes" variable, doesn't require current buffer.
|
|---|
| 387 | ;;;
|
|---|
| 388 | (defun commands-and-bindings (&optional (modes (value hemlock::default-modes)))
|
|---|
| 389 | (when (some #'stringp modes)
|
|---|
| 390 | (setq modes (mapcar (lambda (m) (if (stringp m) (get-mode-object m) m)) modes)))
|
|---|
| 391 | (loop for cmd in (string-table-values *command-names*)
|
|---|
| 392 | as bindings = (command-bindings cmd)
|
|---|
| 393 | ;; collect unshadowed bindings
|
|---|
| 394 | as keys = (loop for (key-seq) in bindings
|
|---|
| 395 | when (eq cmd (get-binding-with-modes key-seq modes))
|
|---|
| 396 | collect key-seq)
|
|---|
| 397 | unless (or (and bindings (not keys)) ;; ignore pseudo-commands like "I-Search whatever"
|
|---|
| 398 | (command-transparent-p cmd) ;; ignore addons like exit search mode.
|
|---|
| 399 | (eq cmd (get-default-command)) ;; ignore illegal
|
|---|
| 400 | (eq cmd (get-self-insert-command));; and self insert
|
|---|
| 401 | (> (length keys) 5)) ;; ignore commmands like "Digit"
|
|---|
| 402 | collect (cons cmd keys)))
|
|---|
| 403 |
|
|---|
| 404 | (defun get-binding-with-modes (key modes)
|
|---|
| 405 | (or (loop for mode in modes ;; first find minor mode binding
|
|---|
| 406 | do (when (stringp mode) (setq mode (get-mode-object mode)))
|
|---|
| 407 | thereis (and (not (mode-object-major-p mode)) (get-binding-in-mode key mode)))
|
|---|
| 408 | (loop for mode in modes ;; next try major mode
|
|---|
| 409 | do (when (stringp mode) (setq mode (get-mode-object mode)))
|
|---|
| 410 | thereis (and (mode-object-major-p mode) (get-binding-in-mode key mode)))
|
|---|
| [8428] | 411 | (get-table-entry *global-command-table* key)))
|
|---|
| [6] | 412 |
|
|---|
| 413 |
|
|---|
| 414 |
|
|---|
| 415 | (defvar *key-event-history* (make-ring 60))
|
|---|
| 416 |
|
|---|
| 417 | ;;; LAST-COMMAND-TYPE -- Public
|
|---|
| 418 | ;;;
|
|---|
| 419 | ;;;
|
|---|
| [8428] | 420 | (defun last-command-type ()
|
|---|
| [6] | 421 | "Return the command-type of the last command invoked.
|
|---|
| 422 | If no command-type has been set then return NIL. Setting this with
|
|---|
| 423 | Setf sets the value for the next command."
|
|---|
| 424 | *last-last-command-type*)
|
|---|
| [8428] | 425 |
|
|---|
| [6] | 426 | ;;; %SET-LAST-COMMAND-TYPE -- Internal
|
|---|
| 427 | ;;;
|
|---|
| 428 | (defun %set-last-command-type (type)
|
|---|
| 429 | (setf (hemlock-last-command-type *current-view*) type))
|
|---|
| 430 |
|
|---|
| 431 |
|
|---|
| [8428] | 432 | ;;; PREFIX-ARGUMENT -- Public
|
|---|
| 433 | ;;;
|
|---|
| [6] | 434 | ;;;
|
|---|
| [8428] | 435 | (defun prefix-argument ()
|
|---|
| 436 | "Return the current value of prefix argument."
|
|---|
| 437 | *last-prefix-argument*)
|
|---|
| [6] | 438 |
|
|---|
| [8428] | 439 | (defun get-self-insert-command ()
|
|---|
| 440 | ;; Get the command used to implement normal character insertion in current buffer.
|
|---|
| 441 | (getstring (value hemlock::self-insert-command-name) *command-names*))
|
|---|
| [12422] | 442 |
|
|---|
| 443 | (defun get-default-command ()
|
|---|
| 444 | ;; Get the command used when no binding is present in current buffer.
|
|---|
| 445 | (getstring (value hemlock::default-command-name) *command-names*))
|
|---|
| [12430] | 446 |
|
|---|
| 447 | (defun get-system-default-behavior-command ()
|
|---|
| 448 | ;; Get the command used to invoke "System Default Behavior"
|
|---|
| 449 | (getstring (value hemlock::system-default-behavior-command-name) *command-names*))
|
|---|
| 450 |
|
|---|
| 451 | (defvar *native-key-events* (make-hash-table :test #'eq))
|
|---|
| 452 |
|
|---|
| 453 |
|
|---|
| 454 |
|
|---|
| 455 | (defun native-key-event-p (key)
|
|---|
| 456 | (check-type key key-event)
|
|---|
| 457 | (gethash key *native-key-events*))
|
|---|
| 458 |
|
|---|
| 459 |
|
|---|
| [16082] | 460 | (defun (setf native-key-event-p) (flag key)
|
|---|
| 461 | (check-type key key-event)
|
|---|
| 462 | (if flag
|
|---|
| 463 | (setf (gethash key *native-key-events*) flag)
|
|---|
| 464 | (remhash key *native-key-events*)))
|
|---|