comparison lisp/utils/edmacro.el @ 134:34a5b81f86ba r20-2b1

Import from CVS: tag r20-2b1
author cvs
date Mon, 13 Aug 2007 09:30:11 +0200
parents 7d55a9ba150c
children b980b6286996
comparison
equal deleted inserted replaced
133:b27e67717092 134:34a5b81f86ba
3 ;; Copyright (C) 1993, 1994 Free Software Foundation, Inc. 3 ;; Copyright (C) 1993, 1994 Free Software Foundation, Inc.
4 4
5 ;; Author: Dave Gillespie <daveg@synaptics.com> 5 ;; Author: Dave Gillespie <daveg@synaptics.com>
6 ;; Hrvoje Niksic <hniksic@srce.hr> -- XEmacs port 6 ;; Hrvoje Niksic <hniksic@srce.hr> -- XEmacs port
7 ;; Maintainer: Hrvoje Niksic <hniksic@srce.hr> 7 ;; Maintainer: Hrvoje Niksic <hniksic@srce.hr>
8 ;; Version: 3.07 8 ;; Version: 3.09
9 ;; Keywords: abbrev 9 ;; Keywords: abbrev
10 10
11 ;; This file is part of XEmacs. 11 ;; This file is part of XEmacs.
12 12
13 ;; XEmacs is free software; you can redistribute it and/or modify 13 ;; XEmacs is free software; you can redistribute it and/or modify
52 ;; Also, the `read-kbd-macro' command parses the region as 52 ;; Also, the `read-kbd-macro' command parses the region as
53 ;; a keyboard macro, and installs it as the "current" macro. 53 ;; a keyboard macro, and installs it as the "current" macro.
54 ;; This and `format-kbd-macro' can also be called directly as 54 ;; This and `format-kbd-macro' can also be called directly as
55 ;; Lisp functions. 55 ;; Lisp functions.
56 56
57 ;; The `kbd' macro calls `read-kbd-macro', but it is evaluated at 57 ;; The `kbd' function is a shorter name for `read-kbd-macro'. It is
58 ;; compile-time. It is good to use in your programs and 58 ;; good to use in your programs and initializations, as you needn't
59 ;; initializations, as you needn't know the internal keysym 59 ;; know the internal keysym representation. For example:
60 ;; representation. For example:
61 ;; 60 ;;
62 ;; (define-key foo-mode-map (kbd "C-c <up>") 'foo-up) 61 ;; (define-key foo-mode-map (kbd "C-c <up>") 'foo-up)
62 ;;
63 ;; is the equivalent of 63 ;; is the equivalent of
64 ;;
64 ;; (define-key foo-mode-map [(control ?c) up] 'foo-up) 65 ;; (define-key foo-mode-map [(control ?c) up] 'foo-up)
66 ;;
65 67
66 ;; Type `C-h m', or see the documentation for `edmacro-mode' below, 68 ;; Type `C-h m', or see the documentation for `edmacro-mode' below,
67 ;; for information about the format of written keyboard macros. 69 ;; for information about the format of written keyboard macros.
68 70
69 ;; `edit-kbd-macro' formats the macro with one command per line, 71 ;; `edit-kbd-macro' formats the macro with one command per line,
78 ;; This package requires GNU Emacs 19 or later, and daveg's CL 80 ;; This package requires GNU Emacs 19 or later, and daveg's CL
79 ;; package 2.02 or later. (CL 2.02 comes standard starting with 81 ;; package 2.02 or later. (CL 2.02 comes standard starting with
80 ;; Emacs 19.18.) This package does not work with Emacs 18 or 82 ;; Emacs 19.18.) This package does not work with Emacs 18 or
81 ;; Lucid Emacs. 83 ;; Lucid Emacs.
82 84
83 ;; But it works with XEmacs. At least the modified version. -hniksic 85 ;; Ported to XEmacs. -hniksic
84 86
85 ;;; Code: 87 ;;; Code:
86 88
87 (eval-when-compile 89 (eval-when-compile
88 (require 'cl)) 90 (require 'cl))
93 95
94 ;;;###autoload 96 ;;;###autoload
95 (defvar edmacro-eight-bits nil 97 (defvar edmacro-eight-bits nil
96 "*Non-nil if edit-kbd-macro should leave 8-bit characters intact. 98 "*Non-nil if edit-kbd-macro should leave 8-bit characters intact.
97 Default nil means to write characters above \\177 in octal notation.") 99 Default nil means to write characters above \\177 in octal notation.")
100
101 (if (fboundp 'mapvector)
102 (defalias 'edmacro-mapvector 'mapvector)
103 (defun edmacro-mapvector (fun seq)
104 (map 'vector fun seq)))
98 105
99 (defvar edmacro-mode-map nil) 106 (defvar edmacro-mode-map nil)
100 (unless edmacro-mode-map 107 (unless edmacro-mode-map
101 (setq edmacro-mode-map (make-sparse-keymap)) 108 (setq edmacro-mode-map (make-sparse-keymap))
102 (define-key edmacro-mode-map "\C-c\C-c" 'edmacro-finish-edit) 109 (define-key edmacro-mode-map "\C-c\C-c" 'edmacro-finish-edit)
104 111
105 (defvar edmacro-store-hook) 112 (defvar edmacro-store-hook)
106 (defvar edmacro-finish-hook) 113 (defvar edmacro-finish-hook)
107 (defvar edmacro-original-buffer) 114 (defvar edmacro-original-buffer)
108 115
116 ;; A lot of cruft here, but I got it to work eventually. Could use
117 ;; some cleaning up.
109 ;;;###autoload 118 ;;;###autoload
110 (defun edit-kbd-macro (keys &optional prefix finish-hook store-hook) 119 (defun edit-kbd-macro (keys &optional prefix finish-hook store-hook)
111 "Edit a keyboard macro. 120 "Edit a keyboard macro.
112 At the prompt, type any key sequence which is bound to a keyboard macro. 121 At the prompt, type any key sequence which is bound to a keyboard macro.
113 Or, type `C-x e' or RET to edit the last keyboard macro, `C-h l' to edit 122 Or, type `C-x e' or RET to edit the last keyboard macro, `C-h l' to edit
215 (if (stringp start) 224 (if (stringp start)
216 (edmacro-parse-keys start end) 225 (edmacro-parse-keys start end)
217 (setq last-kbd-macro (edmacro-parse-keys (buffer-substring start end))))) 226 (setq last-kbd-macro (edmacro-parse-keys (buffer-substring start end)))))
218 227
219 ;;;###autoload 228 ;;;###autoload
220 (defmacro kbd (keys) 229 (defun kbd (keys)
221 "Convert KEYS to the internal Emacs key representation." 230 "Convert KEYS to the internal Emacs key representation."
222 `(eval-when-compile 231 (read-kbd-macro keys))
223 (read-kbd-macro ,keys)))
224 232
225 ;;;###autoload 233 ;;;###autoload
226 (defun format-kbd-macro (&optional macro verbose) 234 (defun format-kbd-macro (&optional macro verbose)
227 "Return the keyboard macro MACRO as a human-readable string. 235 "Return the keyboard macro MACRO as a human-readable string.
228 This string is suitable for passing to `read-kbd-macro'. 236 This string is suitable for passing to `read-kbd-macro'.
419 ;; Changes for XEmacs -- these two functions re-written from scratch. 427 ;; Changes for XEmacs -- these two functions re-written from scratch.
420 ;; edmacro-parse-keys always returns a vector. edmacro-format-keys 428 ;; edmacro-parse-keys always returns a vector. edmacro-format-keys
421 ;; accepts a vector (but works with a string too). Vector may contain 429 ;; accepts a vector (but works with a string too). Vector may contain
422 ;; keypress events. -hniksic 430 ;; keypress events. -hniksic
423 (defun edmacro-parse-keys (string &optional ignored) 431 (defun edmacro-parse-keys (string &optional ignored)
424 (let ((pos 0) 432 (let* ((pos 0)
425 (case-fold-search nil) 433 (case-fold-search nil)
426 (word-to-sym '(("NUL" . (control space)) 434 (word-to-sym '(("NUL" . (control space))
427 ("RET" . return) 435 ("RET" . return)
428 ("LFD" . linefeed) 436 ("LFD" . linefeed)
429 ("TAB" . tab) 437 ("TAB" . tab)
430 ("ESC" . escape) 438 ("ESC" . escape)
431 ("SPC" . space) 439 ("SPC" . space)
432 ("BS" . backspace) 440 ("BS" . backspace)
433 ("DEL" . delete))) 441 ("DEL" . delete)))
434 (char-to-word '((?\0 . "NUL") 442 (char-to-word '((?\0 . "NUL")
435 (?\r . "RET") 443 (?\r . "RET")
436 (?\n . "LFD") 444 (?\n . "LFD")
437 (?\t . "TAB") 445 (?\t . "TAB")
438 (?\e . "ESC") 446 (?\e . "ESC")
439 (?\ . "SPC") 447 (?\ . "SPC")
440 (?\C-? . "DEL"))) 448 (?\C-? . "DEL")))
441 (modifier-prefix-alist '(("C" . control) 449 (modifier-prefix-alist '(("C" . control)
442 ("M" . meta) 450 ("M" . meta)
443 ("S" . shift) 451 ("S" . shift)
444 ("Sh" . shift) 452 ("Sh" . shift)
445 ("A" . alt) 453 ("A" . alt)
446 ("H" . hyper) 454 ("H" . hyper)
447 ("s" . super))) 455 ("s" . super)))
448 ;; string-to-symbol-or-char converter 456 ;; string-to-symbol-or-char converter
449 (conv #'(lambda (arg) 457 (conv (lambda (arg)
450 (if (= (length arg) 1) 458 (if (= (length arg) 1)
451 (aref arg 0) 459 (aref arg 0)
452 (if (string-match "^<\\([^>]+\\)>$" arg) 460 (if (string-match "^<\\([^>]+\\)>$" arg)
453 (setq arg (match-string 1 arg))) 461 (setq arg (match-string 1 arg)))
454 (let ((match (assoc arg word-to-sym))) 462 (let ((match (assoc arg word-to-sym)))
455 (if match 463 (if match
456 (cdr match) 464 (cdr match)
457 (intern arg)))))) 465 (intern arg))))))
458 (conv-chars #'(lambda (arg) 466 (conv-chars (lambda (arg)
459 (let ((match (assoc arg char-to-word))) 467 (let ((match (assoc arg char-to-word)))
460 (if match 468 (if match
461 (cdr (assoc (cdr match) word-to-sym)) 469 (cdr (assoc (cdr match) word-to-sym))
462 arg)))) 470 arg))))
463 res) 471 res)
464 (while (and (< pos (length string)) 472 (while (and (< pos (length string))
465 (string-match "[^ \t\n\f]+" string pos)) 473 (string-match "[^ \t\n\f]+" string pos))
466 (let ((word (substring string (match-beginning 0) (match-end 0))) 474 (let ((word (substring string (match-beginning 0) (match-end 0)))
467 (times 1) 475 (times 1)
468 (force-sym nil) 476 (force-sym nil)
469 (add nil)) 477 (add nil)
478 match)
470 (setq pos (match-end 0)) 479 (setq pos (match-end 0))
471 (when (string-match "\\([0-9]+\\)\\*." word) 480 (when (string-match "\\([0-9]+\\)\\*." word)
472 (setq times (string-to-int (substring word 0 (match-end 1)))) 481 (setq times (string-to-int (substring word 0 (match-end 1))))
473 (setq word (substring word (1+ (match-end 1))))) 482 (setq word (substring word (1+ (match-end 1)))))
474 (when (string-match "^<\\([^<>]+\\)>$" word) 483 (when (string-match "^<\\([^<>]+\\)>$" word)
475 (setq word (match-string 1 word)) 484 (setq word (match-string 1 word))
476 (setq force-sym t)) 485 (setq force-sym t))
477 (setq match (assoc word word-to-sym)) 486 (setq match (assoc word word-to-sym))
478 ;; Add an element. 487 ;; Add an element; `add' holds the list of elements to be
488 ;; added.
479 (cond ((string-match "^\\\\[0-7]+" word) 489 (cond ((string-match "^\\\\[0-7]+" word)
480 ;; Octal value of character. 490 ;; Octal value of character.
481 (setq add 491 (setq add
482 (list 492 (list
483 (edmacro-int-char 493 (edmacro-int-char
494 'execute-extended-command)) 504 'execute-extended-command))
495 '(meta x)))) 505 '(meta x))))
496 (mapcar conv-chars (concat (substring word 2 -2) "\r"))) 506 (mapcar conv-chars (concat (substring word 2 -2) "\r")))
497 )) 507 ))
498 ((or (equal word "REM") (string-match "^;;" word)) 508 ((or (equal word "REM") (string-match "^;;" word))
499 ;; Comment. 509 ;; Comment (discard to EOL) .
500 (setq pos (string-match "$" string pos))) 510 (setq pos (string-match "$" string pos)))
501 (match 511 (match
502 ;; Convert to symbol. 512 ;; Convert to symbol.
503 (setq add (list (cdr match)))) 513 (setq add (list (cdr match))))
504 ((string-match "^\\^" word) 514 ((string-match "^\\^" word)
534 (setq add (mapcar conv-chars word)))) 544 (setq add (mapcar conv-chars word))))
535 (let ((new nil)) 545 (let ((new nil))
536 (loop repeat times do (setq new (append new add))) 546 (loop repeat times do (setq new (append new add)))
537 (setq add new)) 547 (setq add new))
538 (setq res (nconc res add)))) 548 (setq res (nconc res add))))
539 (mapvector 'identity res))) 549 (edmacro-mapvector 'identity res)))
540 550
541 (defun edmacro-conv (char-or-sym add-<>) 551 (defun edmacro-conv (char-or-sym add-<>)
542 (let ((char-to-word '((?\0 . "NUL") 552 (let ((char-to-word '((?\0 . "NUL")
543 (?\r . "RET") 553 (?\r . "RET")
544 (?\n . "LFD") 554 (?\n . "LFD")
567 (let ((found (assq char-or-sym char-to-word))) 577 (let ((found (assq char-or-sym char-to-word)))
568 (cond (found 578 (cond (found
569 (cdr found)) 579 (cdr found))
570 ((< char-or-sym 128) 580 ((< char-or-sym 128)
571 (single-key-description char-or-sym)) 581 (single-key-description char-or-sym))
582 ((and edmacro-eight-bits
583 (>= char-or-sym 128))
584 (char-to-string char-or-sym))
572 (t 585 (t
573 (format "\\%o" (edmacro-int-char char-or-sym))))))))) 586 (format "\\%o" (edmacro-int-char char-or-sym)))))))))
574 587
575 (defun edmacro-format-1 (keys command times togetherp) 588 (defun edmacro-format-1 (keys command times togetherp)
576 (let ((res "") 589 (let ((res "")
636 (t 649 (t
637 nil)) ; leave it be. 650 nil)) ; leave it be.
638 (if el 651 (if el
639 (setq new (nconc new (list el)))) 652 (setq new (nconc new (list el))))
640 (incf cnt)) 653 (incf cnt))
641 (mapvector 'identity new)))) 654 (edmacro-mapvector 'identity new))))
642 655
643 ;; Collapse a list of keys into a list of function keys, where 656 ;; Collapse a list of keys into a list of function keys, where
644 ;; applicable. 657 ;; applicable.
645 (defun edmacro-fkeys (keys) 658 (defun edmacro-fkeys (keys)
646 (let (new k) 659 (let (new k lookup)
647 (while keys 660 (while keys
648 (setq k (nconc k (list (car keys)))) 661 (setq k (nconc k (list (car keys))))
649 (setq lookup (lookup-key function-key-map (mapvector 'identity k))) 662 (setq lookup (lookup-key function-key-map (edmacro-mapvector 'identity k)))
650 (cond ((vectorp lookup) 663 (cond ((vectorp lookup)
651 (setq new (nconc new (mapcar 'identity lookup))) 664 (setq new (nconc new (mapcar 'identity lookup)))
652 (setq k nil)) 665 (setq k nil))
653 ((keymapp lookup) 666 ((keymapp lookup)
654 nil) 667 nil)
672 ;; I'm not sure I understand the original code, but this seems to 685 ;; I'm not sure I understand the original code, but this seems to
673 ;; work. 686 ;; work.
674 (and (eq verbose 1) 687 (and (eq verbose 1)
675 (setq verbose nil)) 688 (setq verbose nil))
676 689
677 ;; Oh come on -- I want a list! Much easier to process... 690 ;; We prefer a list -- much easier to process...
678 (setq macro (mapcar 'identity macro)) 691 (setq macro (mapcar 'identity macro))
679 (setq macro (edmacro-fkeys macro)) 692 (setq macro (edmacro-fkeys macro))
680 (while macro 693 (while macro
681 (let (key lookup (times 1) self-insert-p) 694 (let (key lookup (times 1) self-insert-p)
682 (loop do 695 (loop do
683 (setq key (nconc key (list (car macro))) 696 (setq key (nconc key (list (car macro)))
684 macro (cdr macro) 697 macro (cdr macro)
685 lookup (lookup-key global-map (mapvector 'identity key))) 698 lookup (lookup-key global-map (edmacro-mapvector
699 'identity key)))
686 while 700 while
687 (and lookup (not (commandp lookup)))) 701 (and macro lookup (not (commandp lookup))))
688 ;; (lookup-key [?\C-x ?e]) seems to return a vector! 702 ;; keyboard macro
689 (if (vectorp lookup) 703 (if (vectorp lookup)
690 (setq lookup nil)) 704 (setq lookup nil))
691 (if (and (eq lookup 'self-insert-command) 705 (if (and (eq lookup 'self-insert-command)
692 (= (length key) 1) 706 (= (length key) 1)
693 (not (memq (car key) 707 (not (memq (car key)
749 (when (vectorp macro) 763 (when (vectorp macro)
750 (let ((i 0) ev) 764 (let ((i 0) ev)
751 (while (< i (length macro)) 765 (while (< i (length macro))
752 (when (and (consp (setq ev (aref macro i))) 766 (when (and (consp (setq ev (aref macro i)))
753 (not (memq (car ev) ; ha ha 767 (not (memq (car ev) ; ha ha
754 '(hyper super control meta alt control shift)))) 768 '(hyper super meta alt control shift))))
755 (cond ((equal (cadadr ev) '(menu-bar)) 769 (cond ((equal (cadadr ev) '(menu-bar))
756 (setq macro (vconcat (edmacro-subseq macro 0 i) 770 (setq macro (vconcat (edmacro-subseq macro 0 i)
757 (vector 'menu-bar (car ev)) 771 (vector 'menu-bar (car ev))
758 (edmacro-subseq macro (1+ i)))) 772 (edmacro-subseq macro (1+ i))))
759 (incf i)) 773 (incf i))