From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.devel Subject: Re: Bug with S-Tab in keymaps Date: Tue, 6 May 2008 21:26:29 +0000 Message-ID: <20080506212629.GA4534@muc.de> References: <20080505141152.GA1365@muc.de> <20080505205411.GB1365@muc.de> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1210108141 24398 80.91.229.12 (6 May 2008 21:09:01 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 6 May 2008 21:09:01 +0000 (UTC) Cc: emacs-devel@gnu.org To: Stefan Monnier , Drew Adams Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Tue May 06 23:09:36 2008 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1JtUPh-0008B6-66 for ged-emacs-devel@m.gmane.org; Tue, 06 May 2008 23:09:29 +0200 Original-Received: from localhost ([127.0.0.1]:53235 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JtUOy-0001Zz-QT for ged-emacs-devel@m.gmane.org; Tue, 06 May 2008 17:08:44 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1JtUOs-0001Zl-GM for emacs-devel@gnu.org; Tue, 06 May 2008 17:08:38 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1JtUOq-0001ZZ-LT for emacs-devel@gnu.org; Tue, 06 May 2008 17:08:36 -0400 Original-Received: from [199.232.76.173] (port=46834 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JtUOq-0001ZW-G7 for emacs-devel@gnu.org; Tue, 06 May 2008 17:08:36 -0400 Original-Received: from colin.muc.de ([193.149.48.1] helo=mail.muc.de) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1JtUOp-0003wQ-RI for emacs-devel@gnu.org; Tue, 06 May 2008 17:08:36 -0400 Original-Received: (qmail 48342 invoked by uid 3782); 6 May 2008 21:06:58 -0000 Original-Received: from acm.muc.de (p57AF4B1B.dip.t-dialin.net [87.175.75.27]) by colin2.muc.de (tmda-ofmipd) with ESMTP; Tue, 06 May 2008 23:06:55 +0200 Original-Received: (qmail 4829 invoked by uid 1000); 6 May 2008 21:26:29 -0000 Content-Disposition: inline In-Reply-To: <20080505205411.GB1365@muc.de> User-Agent: Mutt/1.5.9i X-Delivery-Agent: TMDA/1.1.5 (Fettercairn) X-Primary-Address: acm@muc.de X-detected-kernel: by monty-python.gnu.org: FreeBSD 4.6-4.9 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:96614 Archived-At: Hi, Stefan and Drew! On Mon, May 05, 2008 at 08:54:11PM +0000, Alan Mackenzie wrote: > Hi, Stefan! > On Mon, May 05, 2008 at 02:07:53PM -0400, Stefan Monnier wrote: > > > Should S-Tab be stored in a keymap as a symbol or a number? Or are > > > both valid? Which is the canonical form? Where should the > > > conversion from the uncanonical form to the canonical be done? [ .... ] > My own opinion, for what it's worth, is that read_key_sequence (in > keyboard.c) and lookup-key (in keymap.c) should both massage the > differences between #x2000009 and 'S-tab and 'S-TAB, somehow. I suppose > even #x4000049 (&I + the control bucky bit) for the same thing is > conceivable. Maybe `define-key' should canonicalise the key-sequences > it's given before writing them into a keymap. > in fact, `canonicalise-key-sequence' would be easy to write in lisp, and > could be called from all of read_key_sequence, lookup-key and > define-key. what do you think? here's an embryonic `canonicalize-event' (note the American spelling ;-). It works, e.g. for (canonicalize-event 'TaB) (canonicalize-event 'C-Tab) (canonicalize-event 'C-PgUp) (canonicalize-event #x4000049) (canonicalize-event 'M-C-prior) . ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defconst non-canon-key-symbs '((tab . 9) (bs . 127) (pgup . "prior")) "An alist mapping non-standard keynames to canonical ones") (defun canonicalize-event (evt) "Turn the event EVT into its canonical equivalent. EVT is typically a single key press after being massaged by the function-key-map, or a mouse action. In the following, the \"base-key\" means the key event without its modifiers. If EVT is an integer, the base-key is its bottom 8 bits; if EVT's a symbol, the base-key is the symbol name without the modifiers, a string. The rules for a key event's canonicity are, in order of decreasing priority: \(i) it is a number (character, perhaps including bucky bits) if possible. \(ii) if it contains control and a low ASCII character (?@, ?a, ...., ?z, ?{, ..., ~, del), the base key is the corresponding control character. \(iii) Upper and lower case letters will be represented as such in the base key, rather than by use of the shift bucky bit. \(iv) if it can't be represented by a number, it is a symbol containing the modifiers, e.g. 'C-M-up. \(v) Any attached modifiers are case significant, and appear in the canonical order, A-C-H-M-S-s-. \(vi) The base key part of the symbol name is in lower case, and is the canonical name." (let ((M-bit #x8000000) (C-bit #x4000000) (S-bit #x2000000) ; shift (H-bit #x1000000) (s-bit #x800000) ; super (A-bit #x400000) (base-mask #x3fffff) base-key ; key without modifiers; number or string. got-M got-C got-S got-H got-s got-A ; are explicit modifiers present? is-C is-upper-case ; is it a control/upper-case key? is-CC ; is it a "double" ctrl key, e.g. C-TAB? (char-mod-alist '((?M . got-M) (?C . got-C) (?S . got-S) (?H . got-H) (?s . got-s) (?A . got-A))) key-string canon-symb ch pos ) ;;;; Analyse the argument (cond ((numberp evt) (setq base-key (logand evt base-mask) ; Unchanged until the "Synthesize" bit. got-M (/= 0 (logand evt M-bit)) got-C (/= 0 (logand evt C-bit)) got-S (/= 0 (logand evt S-bit)) got-H (/= 0 (logand evt H-bit)) got-s (/= 0 (logand evt s-bit)) got-A (/= 0 (logand evt A-bit))) ;; Have we got a "double ", e.g. C-TAB? (setq is-CC (and got-C (< base-key 32)))) ((symbolp evt) (setq key-string (symbol-name evt)) ;; get the modifiers. (setq pos 0) (while (eq (string-match "[MCSHsA]-." key-string pos) pos) (setq ch (aref key-string pos)) (set (cdr (assq ch char-mod-alist)) t) (setq pos (+ 2 pos))) ;; get the base "key" (might be a mouse event). (or (string-match "[^-]+$" key-string pos) (error "canonicalize-event: invalid symbol: %s" evt)) (setq base-key (substring key-string pos))) (t (error "canonicalize-event: argument not number or symbol: %s" evt))) ;;;; Synthesize the result (when (stringp base-key) (if (eq (length base-key) 1) ; must be a letter or digit. (setq base-key (aref base-key 0)) (setq base-key (downcase base-key)) (if (setq canon-symb (assoc (intern base-key) non-canon-key-symbs)) (setq base-key (cdr canon-symb))))) ; symbol or number ;; Can we transform base-key into an ASCII control sequnce (0 - 31)? (when (and got-C (numberp base-key)) (cond ;; Convert got-C with (e.g.) ?A -> shift + ?\C-a ((and (>= base-key ?A) (<= base-key ?Z)) (setq base-key (- base-key ?A -1) got-C nil got-S t)) ;; got-C with (e.g.) ?@ -> ?\C-@ ((or (eq base-key ?@) (and (>= base-key ?\[) (<= base-key ?_))) (setq base-key (- base-key ?@) got-C nil)) ;; got-C with (e.g.) ?a -> ?\C-a ((and (>= base-key ?a) (<= base-key ?z)) (setq base-key (- base-key ?a -1) got-C nil)))) (if (numberp base-key) (logior base-key (if got-M M-bit 0) (if (or got-C is-CC) C-bit 0) (if got-S S-bit 0) (if got-H H-bit 0) (if got-M M-bit 0) (if got-M M-bit 0)) (intern (concat (if got-A "A-" "") (if got-C "C-" "") (if got-H "H-" "") (if got-M "M-" "") (if got-S "S-" "") (if got-s "s-" "") base-key))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -- Alan Mackenzie (Nuremberg, Germany).