Mercurial > emacs
comparison lisp/wid-edit.el @ 68005:3d987bde3a79
(key-sequence): Rework widget to read key binding
using `kbd' syntax. Use C-q to insert literal key, event, or code.
(widget-key-sequence-default-value): Default value for empty sequence.
(widget-key-sequence-map): New map for reading key binding. Bind C-q.
(widget-key-sequence-read-event): New command for C-q.
(widget-key-sequence-validate, widget-key-sequence-value-to-internal)
(widget-key-sequence-value-to-external): New functions.
author | Kim F. Storm <storm@cua.dk> |
---|---|
date | Tue, 03 Jan 2006 23:31:51 +0000 |
parents | c0dbbeb95cd3 |
children | d8acae190ef7 |
comparison
equal
deleted
inserted
replaced
68004:1a9ccbce1b6e | 68005:3d987bde3a79 |
---|---|
3159 t))) | 3159 t))) |
3160 (widget-value-set widget answer) | 3160 (widget-value-set widget answer) |
3161 (widget-apply widget :notify widget event) | 3161 (widget-apply widget :notify widget event) |
3162 (widget-setup))) | 3162 (widget-setup))) |
3163 | 3163 |
3164 ;;; I'm not sure about what this is good for? KFS. | |
3164 (defvar widget-key-sequence-prompt-value-history nil | 3165 (defvar widget-key-sequence-prompt-value-history nil |
3165 "History of input to `widget-key-sequence-prompt-value'.") | 3166 "History of input to `widget-key-sequence-prompt-value'.") |
3166 | 3167 |
3167 ;; This mostly works, but I am pretty sure it needs more change | 3168 (defvar widget-key-sequence-default-value [ignore] |
3168 ;; to be 100% correct. I don't know what the change should be -- rms. | 3169 "Default value for an empty key sequence.") |
3170 | |
3171 (defvar widget-key-sequence-map | |
3172 (let ((map (make-sparse-keymap))) | |
3173 (set-keymap-parent map widget-field-keymap) | |
3174 (define-key map [(control ?q)] 'widget-key-sequence-read-event) | |
3175 map)) | |
3169 | 3176 |
3170 (define-widget 'key-sequence 'restricted-sexp | 3177 (define-widget 'key-sequence 'restricted-sexp |
3171 "A Lisp function." | 3178 "A key sequence." |
3172 :prompt-value 'widget-field-prompt-value | 3179 :prompt-value 'widget-field-prompt-value |
3173 :prompt-internal 'widget-symbol-prompt-internal | 3180 :prompt-internal 'widget-symbol-prompt-internal |
3174 :prompt-match 'fboundp | 3181 ; :prompt-match 'fboundp ;; What was this good for? KFS |
3175 :prompt-history 'widget-key-sequence-prompt-value-history | 3182 :prompt-history 'widget-key-sequence-prompt-value-history |
3176 :action 'widget-field-action | 3183 :action 'widget-field-action |
3177 :match-alternatives '(stringp vectorp) | 3184 :match-alternatives '(stringp vectorp) |
3178 :validate (lambda (widget) | 3185 :format "%{%t%}: %v" |
3179 (unless (or (stringp (widget-value widget)) | 3186 :validate 'widget-key-sequence-validate |
3180 (vectorp (widget-value widget))) | 3187 :value-to-internal 'widget-key-sequence-value-to-internal |
3181 (widget-put widget :error (format "Invalid key sequence: %S" | 3188 :value-to-external 'widget-key-sequence-value-to-external |
3182 (widget-value widget))) | 3189 :value widget-key-sequence-default-value |
3183 widget)) | 3190 :keymap widget-key-sequence-map |
3184 :value 'ignore | 3191 :help-echo "C-q: insert KEY, EVENT, or CODE; RET: enter value" |
3185 :tag "Key sequence") | 3192 :tag "Key sequence") |
3193 | |
3194 (defun widget-key-sequence-read-event (ev) | |
3195 (interactive (list | |
3196 (let ((inhibit-quit t) quit-flag) | |
3197 (read-event "Insert KEY, EVENT, or CODE: ")))) | |
3198 (let ((ev2 (and (memq 'down (event-modifiers ev)) | |
3199 (read-event))) | |
3200 (tr (and (keymapp function-key-map) | |
3201 (lookup-key function-key-map (vector ev))))) | |
3202 (when (and (integerp ev) | |
3203 (or (and (<= ?0 ev) (< ev (+ ?0 (min 10 read-quoted-char-radix)))) | |
3204 (and (<= ?a (downcase ev)) | |
3205 (< (downcase ev) (+ ?a -10 (min 36 read-quoted-char-radix)))))) | |
3206 (setq unread-command-events (cons ev unread-command-events) | |
3207 ev (read-quoted-char (format "Enter code (radix %d)" read-quoted-char-radix)) | |
3208 tr nil) | |
3209 (if (and (integerp ev) (not (char-valid-p ev))) | |
3210 (insert (char-to-string ev)))) ;; throw invalid char error | |
3211 (setq ev (key-description (list ev))) | |
3212 (when (arrayp tr) | |
3213 (setq tr (key-description (list (aref tr 0)))) | |
3214 (if (y-or-n-p (format "Key %s is translated to %s -- use %s? " ev tr tr)) | |
3215 (setq ev tr ev2 nil))) | |
3216 (insert (if (= (char-before) ?\s) "" " ") ev " ") | |
3217 (if ev2 | |
3218 (insert (key-description (list ev2)) " ")))) | |
3219 | |
3220 (defun widget-key-sequence-validate (widget) | |
3221 (unless (or (stringp (widget-value widget)) | |
3222 (vectorp (widget-value widget))) | |
3223 (widget-put widget :error (format "Invalid key sequence: %S" | |
3224 (widget-value widget))) | |
3225 widget)) | |
3226 | |
3227 (defun widget-key-sequence-value-to-internal (widget value) | |
3228 (if (widget-apply widget :match value) | |
3229 (if (equal value widget-key-sequence-default-value) | |
3230 "" | |
3231 (key-description value)) | |
3232 value)) | |
3233 | |
3234 (defun widget-key-sequence-value-to-external (widget value) | |
3235 (if (stringp value) | |
3236 (if (string-match "\\`[[:space:]]*\\'" value) | |
3237 widget-key-sequence-default-value | |
3238 (read-kbd-macro value)) | |
3239 value)) | |
3240 | |
3186 | 3241 |
3187 (define-widget 'sexp 'editable-field | 3242 (define-widget 'sexp 'editable-field |
3188 "An arbitrary Lisp expression." | 3243 "An arbitrary Lisp expression." |
3189 :tag "Lisp expression" | 3244 :tag "Lisp expression" |
3190 :format "%{%t%}: %v" | 3245 :format "%{%t%}: %v" |