Mercurial > hg > xemacs-beta
diff lisp/hyperbole/hib-kbd.el @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/hyperbole/hib-kbd.el Mon Aug 13 08:45:50 2007 +0200 @@ -0,0 +1,154 @@ +;;!emacs +;; +;; FILE: hib-kbd.el +;; SUMMARY: Implicit button type for key sequences delimited with {}. +;; USAGE: GNU Emacs Lisp Library +;; KEYWORDS: extensions, hypermedia +;; +;; AUTHOR: Bob Weiner +;; ORG: Brown U. +;; +;; ORIG-DATE: 22-Nov-91 at 01:37:57 +;; LAST-MOD: 23-Oct-95 at 05:02:49 by Bob Weiner +;; +;; This file is part of Hyperbole. +;; Available for use and distribution under the same terms as GNU Emacs. +;; +;; Copyright (C) 1991-1995, Free Software Foundation, Inc. +;; Developed with support from Motorola Inc. +;; +;; DESCRIPTION: +;; +;; A click of the Hyperbole execution key on a key sequence executes its +;; command binding. +;; +;; A click of the Hyperbole help key on a key sequence displays the +;; documentation for its command binding. +;; +;; Key sequences should be in human readable form, e.g. {C-b}. +;; Forms such as {\C-b}, {\^b}, and {^b} will not be recognized. +;; +;; DESCRIP-END. + +;;; ************************************************************************ +;;; Public implicit button types +;;; ************************************************************************ + +(defact kbd-key (key-sequence) + "Executes the function binding for KEY-SEQUENCE, delimited by {}. +Returns t if a KEY-SEQUENCE has a binding, else nil." + (interactive "kKeyboard key to execute (no {}): ") + (kbd-key:act key-sequence)) + +(defib kbd-key () + "Executes a key sequence delimited by curly braces. +Key sequences should be in human readable form, e.g. {C-b}. +Forms such as {\C-b}, {\^b}, and {^b} will not be recognized." + (if (br-in-browser) + nil + (let* ((seq-and-pos (or (hbut:label-p t "{`" "'}" t) + (hbut:label-p t "{" "}" t))) + (key-sequence (car seq-and-pos)) + (binding (and (stringp key-sequence) + (key-binding (kbd-key:normalize key-sequence))))) + (and binding (not (integerp binding)) + (ibut:label-set seq-and-pos) + (hact 'kbd-key key-sequence))))) + +;;; ************************************************************************ +;;; Public functions +;;; ************************************************************************ + +(defun kbd-key:act (key-sequence) + "Executes the command binding for KEY-SEQUENCE. +Returns t if KEY-SEQUENCE has a binding, else nil." + (interactive "kKeyboard key to execute (no {}): ") + (setq current-prefix-arg nil) ;; kbd-key:normalize below sets it. + (let ((binding (key-binding (kbd-key:normalize key-sequence)))) + (cond ((null binding) nil) + ((memq binding '(action-key action-mouse-key hkey-either)) + (beep) + (message "(kbd-key:act): This key does what the Action Key does.") + t) + (t (call-interactively binding) t)))) + +(defun kbd-key:doc (key &optional full) + "Shows first line of doc for binding of keyboard KEY in minibuffer. +With optional FULL, displays full documentation for command." + (interactive "kKey sequence: \nP") + (let* ((cmd (let ((cmd (key-binding (kbd-key:normalize key)))) + (if (not (integerp cmd)) cmd))) + (doc (and cmd (documentation cmd))) + (end-line)) + (if doc + (or full + (setq end-line (string-match "[\n]" doc) + doc (substitute-command-keys (substring doc 0 end-line)))) + (setq doc (format "No documentation for {%s} %s" key (or cmd "")))) + (if (and cmd doc) + (if full + (describe-function cmd) + (message doc))))) + +(defun kbd-key:help (but) + "Display documentation for binding of keyboard key given by BUT's label." + (let ((kbd-key (hbut:key-to-label (hattr:get but 'lbl-key)))) + (and kbd-key (kbd-key:doc kbd-key 'full)))) + +(defun kbd-key:normalize (key-sequence) + "Returns KEY-SEQUENCE normalized into a form that can be parsed by commands." + (interactive "kKeyboard key sequence to normalize (no {}): ") + (let ((norm-key-seq (copy-sequence key-sequence)) + (case-fold-search nil) (case-replace t)) + ;; Quote Control and Meta key names + (setq norm-key-seq (hypb:replace-match-string + "[ \t\n\^M]+" norm-key-seq "" t) + norm-key-seq (hypb:replace-match-string + "@key{SPC}\\|SPC" norm-key-seq "\040" t) + norm-key-seq (hypb:replace-match-string + "@key{DEL}\\|DEL" norm-key-seq "\177" t) + norm-key-seq (hypb:replace-match-string + "@key{RET}\\|@key{RTN}\\|RET\\|RTN" + norm-key-seq "\015" t) + norm-key-seq (hypb:replace-match-string + "ESCESC" norm-key-seq "\233" t) + norm-key-seq (hypb:replace-match-string + "@key{ESC}\\|ESC" norm-key-seq "M-" t) + ;; Unqote special {} chars. + norm-key-seq (hypb:replace-match-string "\\\\\\([{}]\\)" + norm-key-seq "\\1") + ) + (while (string-match "\\`\\(C-u\\|M-\\)\\(-?[0-9]+\\)" norm-key-seq) + (setq current-prefix-arg + (string-to-int (substring norm-key-seq (match-beginning 2) + (match-end 2))) + norm-key-seq (substring norm-key-seq (match-end 0)))) + (let (arg-val) + (while (string-match "\\`C-u" norm-key-seq) + (if (or (not (listp current-prefix-arg)) + (not (integerp (setq arg-val (car current-prefix-arg))))) + (setq current-prefix-arg '(1) + arg-val 1)) + (setq arg-val (* arg-val 4) + current-prefix-arg (cons arg-val nil) + norm-key-seq (substring norm-key-seq (match-end 0))))) + (setq norm-key-seq (hypb:replace-match-string + "C-\\(.\\)" norm-key-seq + (function + (lambda (str) + (char-to-string + (1+ (- (downcase + (string-to-char + (substring str (match-beginning 1) + (1+ (match-beginning 1))))) + ?a))))))) + (hypb:replace-match-string + "M-\\(.\\)" norm-key-seq + (function + (lambda (str) + (char-to-string (+ (downcase (string-to-char + (substring str (match-beginning 1) + (1+ (match-beginning 1))))) + 128))))))) + +(provide 'hib-kbd)