unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Alex Schroeder <alex@emacswiki.org>
Subject: Re: Customizing key bindings (was: Re: [CVS] f7, f8 bound..)
Date: Sat, 07 Sep 2002 11:15:27 +0200	[thread overview]
Message-ID: <87bs7ama8g.fsf@emacswiki.org> (raw)
In-Reply-To: <rj3csoic9w.fsf@zuse.dina.kvl.dk> (Per Abrahamsen's message of "Thu, 05 Sep 2002 19:20:27 +0200")

I think this does the right thing, now -- it modifies the keymap
directly.  It can restore bindings because it keeps a list of settings
it shadows.  Currently the documentation shown in the customize buffer
is from the global map, this still needs fixing.  See the FIXME
tags...  :)

Alex.

;;; 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"
  :error "Not a well-formed key sequence"
  ;; FIXME :validate 'key-sequence-widget-validate
  :keymap key-sequence-widget-map)

(defun key-sequence-widget-validate (widget value)
  (let ((value (widget-apply widget :value-get)))
    (condition-case nil
	(progn 
	  (read-kbd-macro value)
	  nil)
      (error widget))))

(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"
  :match 'key-sequence-match
  :format "%v"
  :value ""
  :value-create 'key-sequence-value-create
  :value-delete 'widget-children-value-delete
  :value-get 'widget-choice-value-get
  :notify 'key-sequence-notify)

(defun key-sequence-match (widget value)
  (stringp value))

(defun widget-ancestor-get (widget property)
  "Starting from WIDGET, return the value of PROPERTY.
If PROPERTY is not specified or nil in WIDGET and the :parent property is 
non-nil, call `widget-ancestor-get' recusively with the value of the :parent
property.  Otherwise, return nil."
  (cond ((widget-get widget property))
	((widget-get widget :parent)
	 (widget-ancestor-get (widget-get widget :parent) property))
	(nil)))

(defun key-sequence-describe (widget command)
  "Create a child to WIDGET that describes COMMAND.
The child widget is returned."
  (cond ((functionp command)
	 (widget-create-child-value 
	  widget '(function-item) command))
	((null command)
	 (widget-create-child-value
	  widget '(item) "Undefined"))
	((numberp command)
	 (widget-create-child-value
	  widget '(item) "Binding too long"))
	((keymapp command)
	 (widget-create-child-value
	  widget '(item) "Prefix key"))
	(t
	 (widget-create-child-value
	  widget '(item) "Dude, this is too weird"))))

(defun key-sequence-value-create (widget)
  (let ((value (widget-default-get widget))
	(map (or (widget-ancestor-get widget :keymap)
		 (current-global-map)));; FIXME
	(button (widget-create-child-and-convert
		 widget '(key-sequence-button)))
	(field (widget-create-child-value
		widget '(key-sequence-field :format " %vOld binding: ")
		(widget-get widget :value))))
    (let* ((command (condition-case nil
			(lookup-key map (read-kbd-macro value))
		      (error nil)))
	   (binding (key-sequence-describe widget command)))
      (widget-put widget :children (list field))
      (widget-put widget :buttons (list binding button)))))

(defun key-sequence-notify (widget child &optional event)
  "Update the old binding, and notify parent."
  (let* ((buttons (widget-get widget :buttons))
	 (binding (car buttons))
	 (children (widget-get widget :buttons))
	 (field (car children))
	 (value (widget-value child))
	 (map (or (widget-ancestor-get widget :keymap)
		  (current-global-map)));; FIXME
	 (command (condition-case nil
		      (lookup-key map (read-kbd-macro value))
		    (error nil))))
    (save-excursion
      (goto-char (widget-get binding :from))
      (widget-delete binding)
      (setcar buttons (key-sequence-describe widget command))))
  (widget-default-notify widget child event))

(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")

(defmacro defkeymap (symbol map doc &rest args)
  "Define SYMBOL to be a keymap with value MAP.
DOC is the keymap documentation."
  ;; It is better not to use backquote in this file,
  ;; because that makes a bootstrapping problem
  ;; if you need to recompile all the Lisp files using interpreted code.
  (nconc (list 'custom-declare-keymap
	       (list 'quote symbol)
	       (list 'quote map)
	       doc)
	 args))

(defun custom-declare-keymap (symbol map doc &rest args)
  "Like `defkeymap', but SYMBOL and MAP are evaluated as normal arguments.
MAP should be an expression to evaluate to compute the default value,
not the default value itself.  The DOC string will be expanded with
some standard instructions for customization."
  ;; Keymaps are variables.  The only difference is that we know lots
  ;; of defcustom properties already.
  (setq doc (concat doc
		    "\n
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 the command, you can use M-TAB to complete
it."))
  (apply 'custom-declare-variable symbol map doc 
	 :type '(repeat (group key-sequence command))
	 :set 'custom-set-keymap
	 :get 'custom-get-keymap
	 args))

(defun custom-set-keymap (sym bindings)
  "Update keymap SYM with BINDINGS.
This also does the necessary book-keeping to save away shadowed bindings
and restoring them if necessary."
  (let ((standard-bindings (eval (car (get sym 'standard-value))))
	(old-bindings (car (get sym 'custom-bindings))))
    ;; When defkeymap is called for the first time, BINDINGS is the
    ;; standard-value.  When customized, BINDINGS is no longer a
    ;; keymap but an alist of bindings.
    (if (equal bindings standard-bindings)
	(set-default sym standard-bindings)
      ;; remove all keys no longer in bindings
      (mapc (lambda (bind)
	      (unless (assoc (car bind) bindings)
		(custom-remove-key sym (read-kbd-macro (car bind)))))
	    old-bindings)
      ;; define all keys in bindings
      (mapc (lambda (bind)
	      (custom-add-key sym (read-kbd-macro (car bind)) (cadr bind)))
	    bindings)
      ;; store the current bindings away
      (put sym 'custom-bindings (list bindings)))))

(defun custom-get-keymap (sym)
  "Return the additions to the standard-value of keymap SYM.
These additions are stored in the custom-bindings property by
`custom-set-keymap'."
  (car (get sym 'custom-bindings)))

(defun custom-add-key (sym key def)
  "Add KEY to the keymap stored in SYM with definition DEF.
The shadowed binding is stored, if none has been stored before.  The
shadowed bindings are stored in the custom-bindings-shadow property."
  (let* ((map (symbol-value sym))
	 (old-binding (lookup-key map key))
	 (shadows (get sym 'custom-bindings-shadow))
	 (shadow-binding (cdr (assoc key shadows))))
    (when (and old-binding (not shadow-binding))
      (put sym 'custom-bindings-shadow (cons (cons key old-binding) shadows)))
    (define-key map key def)))

(defun custom-remove-key (sym key)
  "Remove KEY from the keymap stored in SYM.
The shadowed binding is restored, if there is one."
  (let ((def (cdr (assoc key (get sym 'custom-bindings-shadow))))
	(map (symbol-value sym)))
    ;; when DEF is nil, this is a valid binding
    (define-key map key def)))

;; Example:

(defkeymap my-keymap
  (let ((map (make-sparse-keymap)))
    (define-key map (read-kbd-macro "<f11>") 'bbdb)
    map)
  "Keymap to demonstrate `defkeymap'.")

;; my-keymap
;; (keymapp my-keymap)
;; (apropos "my-keymap")
;; (custom-get-keymap 'my-keymap)
;; (put 'my-keymap 'custom-bindings nil)
;; (get 'my-keymap 'standard-value)
;; (customize-option 'my-keymap)
;; (unintern 'my-keymap)

(provide 'cus-key)

;;; cus-key.el ends here

  parent reply	other threads:[~2002-09-07  9:15 UTC|newest]

Thread overview: 221+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-08-23 14:15 [CVS] f7, f8 bound D. Goel
2002-08-25 23:16 ` Kim F. Storm
2002-08-25 22:39   ` D. Goel
2002-08-26 15:26   ` Stefan Monnier
2002-08-27  2:02     ` Miles Bader
2002-08-27  8:56       ` Kim F. Storm
2002-08-27  8:55     ` Kim F. Storm
2002-08-27  8:55       ` Juanma Barranquero
2002-08-27 10:32         ` Kim F. Storm
2002-08-27 10:01           ` Juanma Barranquero
2002-08-27 11:55             ` Kim F. Storm
2002-08-27 11:07               ` Juanma Barranquero
2002-08-27 16:21       ` Stefan Monnier
2002-08-28  1:12         ` Miles Bader
2002-08-28  9:33           ` Kim F. Storm
2002-08-28  8:54             ` Miles Bader
2002-08-28  9:09               ` Juanma Barranquero
2002-08-28 10:58                 ` Kim F. Storm
2002-08-28 10:21                   ` Juanma Barranquero
2002-08-28  9:09               ` Miles Bader
2002-08-28 10:47                 ` Kim F. Storm
2002-08-28 14:13                   ` Stefan Monnier
2002-08-29 14:35                     ` Kim F. Storm
2002-08-29 17:24                       ` Stefan Monnier
2002-09-08 23:02                         ` Kim F. Storm
2002-09-09 10:49                           ` Francesco Potorti`
2002-09-09 13:43                           ` Miles Bader
2002-09-09 19:14                           ` Richard Stallman
2002-09-09 23:34                             ` Richard Stallman
2002-09-10 21:50                               ` Kim F. Storm
2002-09-09 23:45                             ` Kim F. Storm
2002-09-10 16:36                               ` Richard Stallman
2002-09-10 12:17                             ` Francesco Potorti`
2002-09-10 23:16                               ` Kim F. Storm
2002-09-11  9:03                                 ` Francesco Potorti`
2002-08-28 13:37                 ` Francesco Potorti`
2002-08-28 14:28                   ` Kai Großjohann
2002-08-28 14:41                     ` Francesco Potorti`
2002-08-28 23:33                   ` Richard Stallman
2002-08-29  9:25                     ` Kai Großjohann
2002-08-30  6:09                       ` Richard Stallman
2002-08-30 14:48                         ` Kim F. Storm
2002-08-30 23:55                           ` Miles Bader
2002-08-31 11:21                             ` Alex Schroeder
2002-09-01 13:14                               ` Richard Stallman
2002-09-01 14:22                                 ` Per Abrahamsen
2002-09-01 14:37                                   ` Per Abrahamsen
2002-09-02 17:05                                     ` Stefan Monnier
2002-09-02 17:54                                       ` Kai Großjohann
2002-09-02 23:24                                         ` Stefan Monnier
2002-09-03 10:55                                           ` Per Abrahamsen
2002-09-03 13:02                                             ` Miles Bader
2002-09-03 13:53                                               ` Per Abrahamsen
2002-09-03 15:04                                                 ` Stefan Monnier
2002-09-03 17:31                                                 ` Miles Bader
2002-09-03 19:27                                                   ` Andreas Schwab
2002-09-03 22:56                                                     ` Miles Bader
2002-09-03 23:53                                                       ` Miles Bader
2002-09-04 11:59                                                         ` Robert J. Chassell
2002-09-04 22:35                                                           ` Alex Schroeder
2002-09-03 23:23                                                     ` Robert J. Chassell
2002-09-04 10:31                                                       ` Per Abrahamsen
2002-09-04 15:30                                                         ` Robert J. Chassell
2002-09-04 22:25                                                           ` Alex Schroeder
2002-09-05 13:00                                                             ` Robert J. Chassell
2002-09-05 10:00                                                           ` Per Abrahamsen
2002-09-05 14:59                                                             ` Robert J. Chassell
2002-09-05 16:18                                                               ` Francesco Potorti`
2002-09-05 19:13                                                                 ` D. Goel
2002-09-05 15:05                                                             ` Robert J. Chassell
2002-09-05 18:03                                                           ` Richard Stallman
2002-09-04 22:00                                                         ` Alex Schroeder
2002-09-05 10:15                                                           ` Per Abrahamsen
2002-09-06  1:16                                                             ` Miles Bader
2002-09-06 10:07                                                               ` Per Abrahamsen
2002-09-06 22:19                                                                 ` Miles Bader
2002-09-07 12:40                                                                   ` Per Abrahamsen
2002-09-06 17:36                                                             ` Stefan Monnier
2002-09-06 22:21                                                               ` Miles Bader
2002-09-07  0:53                                                                 ` Kim F. Storm
2002-09-07  0:32                                                                   ` Miles Bader
2002-09-07  7:59                                                                     ` Alex Schroeder
2002-09-07 10:28                                                                   ` Richard Stallman
2002-09-09 13:35                                                                   ` Stefan Monnier
2002-09-09 15:45                                                                     ` Per Abrahamsen
2002-09-09 23:34                                                                     ` Richard Stallman
2002-09-07 10:28                                                                 ` Richard Stallman
2002-09-07  7:45                                                               ` Alex Schroeder
2002-09-07 14:08                                                               ` Customizing key bindings Alex Schroeder
2002-09-07 23:43                                                                 ` Miles Bader
2002-09-09  8:05                                                                   ` Per Abrahamsen
2002-09-09  9:19                                                                     ` Miles Bader
2002-09-09 12:20                                                                       ` Per Abrahamsen
2002-09-09 14:09                                                                         ` Miles Bader
2002-09-09 15:23                                                                           ` Per Abrahamsen
2002-09-09 17:25                                                                             ` Stefan Monnier
2002-09-09 14:33                                                                         ` Stefan Monnier
2002-09-09 23:34                                                                           ` Richard Stallman
2002-09-09 23:33                                                                       ` Richard Stallman
2002-09-10 10:29                                                                         ` Per Abrahamsen
2002-09-11  1:40                                                                           ` Richard Stallman
2002-09-10 17:57                                                                         ` Alex Schroeder
2002-09-11  3:05                                                                           ` Richard Stallman
2002-09-11  8:52                                                                             ` Per Abrahamsen
2002-09-09  0:21                                                                 ` Richard Stallman
2002-09-09  1:52                                                                   ` Miles Bader
2002-09-09 23:33                                                                     ` Richard Stallman
2002-09-05  2:47                                                         ` [CVS] f7, f8 bound Richard Stallman
2002-09-05  9:39                                                           ` Per Abrahamsen
2002-09-04 14:23                                                 ` Richard Stallman
2002-09-03 14:12                                               ` Kai Großjohann
2002-09-03 15:09                                                 ` Stefan Monnier
2002-09-03 15:17                                                   ` Kai Großjohann
2002-09-02 14:53                                   ` Richard Stallman
2002-09-02 16:40                                     ` Customizing key bindings (was: Re: [CVS] f7, f8 bound..) Per Abrahamsen
2002-09-02 21:55                                       ` Alex Schroeder
2002-09-03 12:27                                         ` Per Abrahamsen
2002-09-03 22:35                                           ` Alex Schroeder
2002-09-03 22:49                                             ` Alex Schroeder
2002-09-04  0:45                                               ` Alex Schroeder
2002-09-04 10:00                                                 ` Per Abrahamsen
2002-09-05  2:47                                                   ` Richard Stallman
2002-09-05  9:18                                                     ` Per Abrahamsen
2002-09-06  4:01                                                       ` Richard Stallman
2002-09-06  9:51                                                         ` Per Abrahamsen
2002-09-04 15:11                                                 ` Stefan Monnier
2002-09-05  9:26                                                   ` Per Abrahamsen
2002-09-06  4:01                                                     ` Richard Stallman
2002-09-06 22:30                                                       ` Kim F. Storm
2002-09-07 14:12                                                     ` Customizing key bindings Alex Schroeder
2002-09-05 18:03                                                   ` Customizing key bindings (was: Re: [CVS] f7, f8 bound..) Richard Stallman
2002-09-05 18:35                                                     ` Per Abrahamsen
2002-09-06 15:10                                                       ` Richard Stallman
2002-09-05  2:46                                               ` Richard Stallman
2002-09-05 16:17                                                 ` Alex Schroeder
2002-09-06  4:01                                                   ` Richard Stallman
2002-09-07 13:50                                                     ` Customizing key bindings Alex Schroeder
2002-09-05 16:47                                               ` Customizing key bindings (was: Re: [CVS] f7, f8 bound..) Kai Großjohann
2002-09-07 14:20                                                 ` use diff-list in Emacs Alex Schroeder
2002-09-07 15:52                                                   ` Kai Großjohann
2002-09-07 22:46                                                     ` Miles Bader
2002-09-08 19:22                                                       ` Kai Großjohann
2002-09-04 14:20                                           ` Customizing key bindings (was: Re: [CVS] f7, f8 bound..) Richard Stallman
2002-09-05 17:20                                             ` Per Abrahamsen
2002-09-06 17:28                                               ` Stefan Monnier
2002-09-06 22:03                                                 ` Miles Bader
2002-09-07 12:01                                                   ` Per Abrahamsen
2002-09-07 12:40                                                     ` Miles Bader
2002-09-07 13:07                                                     ` Per Abrahamsen
2002-09-07 14:17                                                       ` Robert J. Chassell
2002-09-07 17:48                                                         ` What custom is and does Alex Schroeder
2002-09-07 22:57                                                           ` Miles Bader
2002-09-09  7:49                                                           ` Per Abrahamsen
2002-09-07 18:58                                                         ` Customizing key bindings (was: Re: [CVS] f7, f8 bound..) Kai Großjohann
2002-09-09 13:53                                                       ` Stefan Monnier
2002-09-09 14:59                                                         ` Per Abrahamsen
2002-09-09 23:34                                                         ` Richard Stallman
2002-09-07  9:06                                               ` Alex Schroeder
2002-09-07 12:11                                                 ` Per Abrahamsen
2002-09-07  9:15                                               ` Alex Schroeder [this message]
2002-09-07 12:28                                                 ` Per Abrahamsen
2002-09-07 13:48                                                   ` Customizing key bindings Alex Schroeder
2002-09-07 13:56                                                   ` Alex Schroeder
2002-09-07 13:39                                                 ` Alex Schroeder
2002-09-07 15:10                                                   ` Per Abrahamsen
2002-09-09 22:06                                                     ` Alex Schroeder
2002-09-09 22:12                                                       ` Alex Schroeder
2002-09-09 22:49                                                         ` Alex Schroeder
2002-09-09 22:58                                                           ` Stefan Monnier
2002-09-10 10:19                                                           ` Per Abrahamsen
2002-09-08 12:54                                                 ` Customizing key bindings (was: Re: [CVS] f7, f8 bound..) Richard Stallman
2002-09-09  7:57                                                   ` Per Abrahamsen
2002-09-09 23:33                                                     ` Richard Stallman
2002-09-10 18:07                                                       ` Alex Schroeder
2002-09-11  3:04                                                         ` Richard Stallman
2002-09-11  8:49                                                         ` Per Abrahamsen
2002-09-11 20:03                                                           ` Richard Stallman
2002-09-09 21:09                                                   ` Alex Schroeder
     [not found]                             ` <m2it1qqmae.fsf@primate.xs4all.nl>
2002-09-01 10:36                               ` [CVS] f7, f8 bound Miles Bader
2002-09-01 13:02                               ` Eli Zaretskii
2002-09-01 13:45                                 ` Pavel Janík
2002-09-01 16:57                                   ` Eli Zaretskii
2002-09-01 16:57                                   ` Eli Zaretskii
2002-09-01 13:14                             ` Richard Stallman
2002-09-06 12:55                           ` Francesco Potorti`
     [not found]                         ` <m2r8geqole.fsf@primate.xs4all.nl>
2002-09-01  5:19                           ` Damien Elmes
2002-09-02  0:01                           ` Richard Stallman
2002-09-03  0:04                             ` David A. Cobb
2002-08-29 14:38                   ` Kim F. Storm
2002-08-29 13:47                     ` Francesco Potorti`
     [not found]                   ` <m2wuq6qpai.fsf@primate.xs4all.nl>
2002-09-01 10:45                     ` Miles Bader
2002-08-28 18:42               ` Edward O'Connor
2002-08-29  1:16                 ` Miles Bader
2002-08-28 23:32               ` Richard Stallman
2002-08-29  1:14                 ` Miles Bader
2002-08-30  6:10                   ` Richard Stallman
2002-08-30  6:22                     ` Miles Bader
2002-08-30 19:17                       ` Richard Stallman
2002-08-31  0:40                         ` Kim F. Storm
2002-08-31  2:16                       ` Miles Bader
2002-09-01 13:15                         ` Richard Stallman
2002-09-02  1:23                           ` Miles Bader
2002-09-02 10:22                             ` Kim F. Storm
2002-09-02  9:38                               ` Miles Bader
2002-09-03 13:26                             ` Richard Stallman
2002-09-03 14:39                               ` Kim F. Storm
2002-09-04 14:21                                 ` Richard Stallman
2002-09-08 22:51                                 ` Kim F. Storm
2002-08-30  6:10                   ` Richard Stallman
2002-08-30 14:35                     ` Stefan Monnier
2002-08-30 19:19                       ` Richard Stallman
2002-08-31  0:00                       ` Miles Bader
2002-08-31 11:28                         ` Alex Schroeder
2002-08-30 14:49                     ` Francesco Potorti`
2002-08-31  0:33                       ` Kim F. Storm
2002-08-31  6:07                         ` Eli Zaretskii
2002-08-29 14:42                 ` Kim F. Storm
2002-08-30  1:05                   ` Miles Bader
2002-08-30 12:07                     ` Kim F. Storm
2002-08-30  6:09                   ` Richard Stallman
2002-08-28  6:52       ` Richard Stallman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87bs7ama8g.fsf@emacswiki.org \
    --to=alex@emacswiki.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).