emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Customizing key bindings (was: Re: [CVS] f7, f8 bound..)


From: Per Abrahamsen
Subject: Re: Customizing key bindings (was: Re: [CVS] f7, f8 bound..)
Date: Tue, 03 Sep 2002 14:27:18 +0200
User-agent: Gnus/5.090007 (Oort Gnus v0.07) Emacs/21.1 (sparc-sun-solaris2.8)

Alex Schroeder <address@hidden> writes:

> How about this addition.

A big help.  I don't think C-q should be rebound globally, the user
may want to enter literal control characters in string values for
other variables.  So I made it specific to the field, end encapsulated
it into a new 'key-sequence' widget.  I also added a [Key sequence]
button, and a new 'command' widget.

> A side note: Why is the default value for function types the string
> "ignore"?

I don't know.  It is supposed to be the symbol `ignore'.  Using the
widget package directly with (widget-create 'function) works, so I
guess somehow customize convert the value twice.  Somehow, now it just
ignores the default value, and use nil.  Strange.

;;; cus-key.el -- Customize support for changing key bindings.

(require 'wid-edit)

(defvar custom-global-keymap (let ((map (make-sparse-keymap)))
                               (set-keymap-parent map global-map)
                               map)
  "Global keymap for use by Customize.

This is automatically generated from `global-key-bindings', you should 
never change this manually.  Instead, change either `global-map' from Lisp 
or `global-key-bindings' from Customize.")

(defun quoted-key-insert (key)
  "Insert a string representation of the next key typed.
The string representation is a representation understood
by `read-kbd-macro'."
  (interactive "KPress a key: ")
  (insert (edmacro-format-keys key)))

(defvar key-sequence-widget-map 
  (let ((map (make-sparse-keymap)))
    (set-keymap-parent map widget-field-keymap)
    (define-key map (kbd "C-q") 'quoted-key-insert)
    map)
    "Keymap for the `key-sequence' widget.")
    
(define-widget 'key-sequence-field 'string
  "Field for entering key bindings."
  :tag "Key sequence"
  :keymap key-sequence-widget-map)

(define-widget 'key-sequence-button 'push-button
  "Button for entering key bindings."
  :tag "Key sequence"
  :action 'key-sequence-button-action)

(defun key-sequence-button-action (widget &optional event)
  (let ((key (read-key-sequence "Press key sequence: ")))
    (widget-value-set (widget-get widget :parent)
                      (edmacro-format-keys key))
    (widget-setup)))

(define-widget 'key-sequence 'group
  "Widget for entering key bindings."
  :tag "Read key sequence"
  :value ""
  :value-create 'key-sequence-value-create
  :value-delete 'widget-children-value-delete
  :value-get 'widget-choice-value-get)

(defun key-sequence-value-create (widget)
  (let ((button (widget-create-child widget '(key-sequence-button)))
        (field (widget-create-child-value widget 
                                          '(key-sequence-field
                                            :format " %v")
                                          (widget-get widget :value))))
    (widget-put widget :children (list field))
    (widget-put widget :buttons (list button))))

(define-widget 'command 'function
  "An interactive Lisp function."
  :complete-function (lambda ()
                       (interactive)
                       (lisp-complete-symbol 'commandp))
  :prompt-match 'commandp
  :match-alternatives '(commandp)
  :validate (lambda (widget)
              (unless (commandp (widget-value widget))
                (widget-put widget :error (format "Invalid function: %S"
                                                  (widget-value widget)))
                widget))
  :value 'ignore
  :tag "Command")

(defcustom global-key-bindings nil
  "Global keybindings defined through customize.

While entering the name of a key, you can either type keys yourself
just as they appear in the manual, as in C-c a.  You must use angle
brackets for function keys, as in <f7>.  You can also hit C-q and type
the key.  C-q will insert the correct string representation for you.
For longer sequences, you can also invoke the [Key sequence] button, 
and type the entire key sequence directly.

While entering the name of a command, you can use M-TAB to comlete
the function name."
  ;; Note that we cannot use \\[quoted-key-insert] because the keymap
  ;; is not the same.
  :type '(repeat
          (group key-sequence command))
  :set (lambda (sym val)
         (set-default sym val)
         (setq custom-global-keymap (make-sparse-keymap))
         (set-keymap-parent custom-global-keymap global-map)
         (mapc (lambda (bind)
                 (define-key custom-global-keymap (read-kbd-macro (car bind))
                   (cadr bind)))
               val)
         (use-global-map custom-global-keymap)
         val))

(provide 'cus-key)

;;; cus-key.el ends here




reply via email to

[Prev in Thread] Current Thread [Next in Thread]