comparison lisp/utils/edmacro.el @ 187:b405438285a2 r20-3b20

Import from CVS: tag r20-3b20
author cvs
date Mon, 13 Aug 2007 09:56:28 +0200
parents 8eaf7971accc
children
comparison
equal deleted inserted replaced
186:24ac94803b48 187:b405438285a2
1 ;;; edmacro.el --- keyboard macro editor 1 ;;; edmacro.el --- keyboard macro editor
2 2
3 ;; Copyright (C) 1993, 1994 Free Software Foundation, Inc. 3 ;; Copyright (C) 1993, 1994, 1997 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 rewrite
7 ;; Maintainer: Hrvoje Niksic <hniksic@srce.hr> 7 ;; Maintainer: Hrvoje Niksic <hniksic@srce.hr>
8 ;; Version: 3.17 8 ;; Version: 3.19
9 ;; Keywords: abbrev 9 ;; Keywords: abbrev, internal
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
14 ;; it under the terms of the GNU General Public License as published by 14 ;; it under the terms of the GNU General Public License as published by
24 ;; along with XEmacs; see the file COPYING. If not, write to the Free 24 ;; along with XEmacs; see the file COPYING. If not, write to the Free
25 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 25 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 ;; 02111-1307, USA. 26 ;; 02111-1307, USA.
27 27
28 ;;; Synched up with: FSF 19.34. 28 ;;; Synched up with: FSF 19.34.
29 ;;; The important parts of this file have been rewritten for XEmacs, 29 ;;; Most of this file has been rewritten for XEmacs, so the
30 ;;; so it's completely different from the FSF version. The original 30 ;;; implementations are out of synch. The original version depended
31 ;;; could not be used because it worked with the Emacs key 31 ;;; too closely on GNU Emacs key representation and the equivalence of
32 ;;; representation, and it mixed characters and integers too freely. 32 ;;; characters and integers to be usable.
33 33
34 ;;; Commentary: 34 ;;; Commentary:
35 35
36 ;;; Usage: 36 ;;; Usage:
37 ;; 37 ;;
80 ;; characters, the command-name comments will be wrong but that 80 ;; characters, the command-name comments will be wrong but that
81 ;; won't hurt anything. 81 ;; won't hurt anything.
82 82
83 ;; With a prefix argument, `edit-kbd-macro' will format the 83 ;; With a prefix argument, `edit-kbd-macro' will format the
84 ;; macro in a more concise way that omits the comments. 84 ;; macro in a more concise way that omits the comments.
85
86 ;; This package requires GNU Emacs 19 or later, and daveg's CL
87 ;; package 2.02 or later. (CL 2.02 comes standard starting with
88 ;; Emacs 19.18.) This package does not work with Emacs 18 or
89 ;; Lucid Emacs.
90
91 ;; Ported to XEmacs. This code will not run on GNU Emacs 19. -hniksic
92 85
93 ;;; Code: 86 ;;; Code:
94 87
95 (eval-when-compile 88 (eval-when-compile
96 (require 'cl)) 89 (require 'cl))
190 (insert ";; Original keys: " fmt "\n") 183 (insert ";; Original keys: " fmt "\n")
191 (unless store-hook 184 (unless store-hook
192 (insert "\nCommand: " (if cmd (symbol-name cmd) "none") "\n") 185 (insert "\nCommand: " (if cmd (symbol-name cmd) "none") "\n")
193 (let ((keys (where-is-internal (or cmd mac)))) 186 (let ((keys (where-is-internal (or cmd mac))))
194 (if keys 187 (if keys
195 (insert "Key: " (edmacro-format-keys (car keys)) "\n") 188 (dolist (key keys)
189 (insert "Key: " (edmacro-format-keys key) "\n"))
196 (insert "Key: none\n")))) 190 (insert "Key: none\n"))))
197 (insert "\nMacro:\n\n") 191 (insert "\nMacro:\n\n")
198 (save-excursion 192 (save-excursion
199 (insert fmtv "\n")) 193 (insert fmtv "\n"))
200 (recenter '(4)) 194 (recenter '(4))
218 ;;;###autoload 212 ;;;###autoload
219 (defun read-kbd-macro (start &optional end) 213 (defun read-kbd-macro (start &optional end)
220 "Read the region as a keyboard macro definition. 214 "Read the region as a keyboard macro definition.
221 The region is interpreted as spelled-out keystrokes, e.g., \"M-x abc RET\". 215 The region is interpreted as spelled-out keystrokes, e.g., \"M-x abc RET\".
222 See documentation for `edmacro-mode' for details. 216 See documentation for `edmacro-mode' for details.
223 Leading/trailing \"C-x (\" and \"C-x )\" in the text are allowed and ignored.
224 The resulting macro is installed as the \"current\" keyboard macro. 217 The resulting macro is installed as the \"current\" keyboard macro.
225 218
226 In Lisp, may also be called with a single STRING argument in which case 219 In Lisp, may also be called with a single STRING argument in which case
227 the result is returned rather than being installed as the current macro. 220 the result is returned rather than being installed as the current macro.
228 The result will be a string if possible, otherwise an event vector. 221 The result will be a vector of keystrokes."
229 Second argument NEED-VECTOR means to return an event vector always."
230 (interactive "r") 222 (interactive "r")
231 (if (stringp start) 223 (if (stringp start)
232 (edmacro-parse-keys start) 224 (edmacro-parse-keys start)
233 (setq last-kbd-macro (edmacro-parse-keys (buffer-substring start end))))) 225 (setq last-kbd-macro (edmacro-parse-keys (buffer-substring start end)))))
234 226
240 ;;;###autoload 232 ;;;###autoload
241 (defun format-kbd-macro (&optional macro verbose) 233 (defun format-kbd-macro (&optional macro verbose)
242 "Return the keyboard macro MACRO as a human-readable string. 234 "Return the keyboard macro MACRO as a human-readable string.
243 This string is suitable for passing to `read-kbd-macro'. 235 This string is suitable for passing to `read-kbd-macro'.
244 Second argument VERBOSE means to put one command per line with comments. 236 Second argument VERBOSE means to put one command per line with comments.
245 If VERBOSE is `1', put everything on one line. If VERBOSE is omitted 237 If VERBOSE is nil, put everything on one line."
246 or nil, use a compact 80-column format."
247 (and macro (symbolp macro) (setq macro (symbol-function macro))) 238 (and macro (symbolp macro) (setq macro (symbol-function macro)))
248 (edmacro-format-keys (or macro last-kbd-macro) verbose)) 239 (edmacro-format-keys (or macro last-kbd-macro) verbose))
249 240
250 241
251 ;;; Commands for *Edit Macro* buffer. 242 ;;; Commands for *Edit Macro* buffer.
458 ("H" . hyper) 449 ("H" . hyper)
459 ("s" . super))) 450 ("s" . super)))
460 451
461 ;;; Parsing a human-readable keyboard macro. 452 ;;; Parsing a human-readable keyboard macro.
462 453
463 ;; Changes for XEmacs -- these two functions re-written from scratch. 454 ;; In XEmacs version of edmacro, edmacro-parse-keys always returns a
464 ;; edmacro-parse-keys always returns a vector. edmacro-format-keys 455 ;; vector. edmacro-format-keys accepts a vector (but works with a
465 ;; accepts a vector (but works with a string too). Vector may contain 456 ;; string too).
466 ;; keypress events. -hniksic
467 (defun edmacro-parse-keys (string) 457 (defun edmacro-parse-keys (string)
468 (let* ((pos 0) 458 (let* ((pos 0)
469 (case-fold-search nil) 459 (case-fold-search nil)
470 res) 460 res)
471 (while (and (< pos (length string)) 461 (while (and (< pos (length string))
476 ;; Comment (discard to EOL) . 466 ;; Comment (discard to EOL) .
477 (setq pos (string-match "$" string pos)) 467 (setq pos (string-match "$" string pos))
478 (push (edmacro-parse-word word) res)))) 468 (push (edmacro-parse-word word) res))))
479 (mapvector 'identity (apply 'nconc (nreverse res))))) 469 (mapvector 'identity (apply 'nconc (nreverse res)))))
480 470
481 ;; Parse a word. 471 ;; Parse a "word".
482 (defun edmacro-parse-word (word) 472 (defun edmacro-parse-word (word)
483 (let ((force-sym nil) 473 (let ((force-sym nil)
484 (times 1) 474 (times 1)
485 abbr) 475 abbr)
486 (when (string-match "\\([0-9]+\\)\\*." word) 476 (when (string-match "\\([0-9]+\\)\\*." word)
533 ((setq abbr (assoc word word-to-sym)) 523 ((setq abbr (assoc word word-to-sym))
534 ;; Convert to symbol. 524 ;; Convert to symbol.
535 (list (cdr abbr))) 525 (list (cdr abbr)))
536 ((string-match "^\\^" word) 526 ((string-match "^\\^" word)
537 ;; ^X == C-x 527 ;; ^X == C-x
538 (if (/= (length word) 2) 528 (if (= (length word) 2)
539 (error "^ must be followed by one character")) 529 `((control ,(aref word 1)))
540 `((control ,(aref word 1)))) 530 (mapcar 'identity word)))
541 ((string-match "^M--?[0-9]+$" word) 531 ((string-match "^M--?[0-9]+$" word)
542 ;; Special case: M- followed by an optional hyphen and 532 ;; Special case: M- followed by an optional hyphen and
543 ;; one or more digits 533 ;; one or more digits
544 (mapcar (lambda (digit) 534 (mapcar (lambda (digit)
545 (list 'meta digit)) 535 (list 'meta digit))
546 (substring word 2))) 536 (substring word 2)))
547 ((string-match "^\\([MCSsAH]\\|Sh\\)-" word) 537 ((string-match "^\\([MCSsAH]\\|Sh\\)-" word)
548 ;; Parse C-* and stuff 538 ;; Parse C-* and stuff
549 (list 539 (let ((pos1 0)
550 (let ((pos1 0) 540 (r1 nil)
551 (r1 nil) 541 follow curpart prefix)
552 follow curpart prefix) 542 (while (progn (setq curpart (substring word pos1))
553 (while (progn (setq curpart (substring word pos1)) 543 (string-match "^\\([MCSsAH]\\|Sh\\)-"
554 (string-match "^\\([MCSsAH]\\|Sh\\)-" 544 curpart))
555 curpart)) 545 (setq prefix (assoc (match-string 1 curpart)
556 (setq prefix (assoc (match-string 1 curpart) 546 edmacro-modifiers))
557 edmacro-modifiers)) 547 (push (cdr prefix) r1)
558 (push (cdr prefix) r1) 548 (incf pos1 (1+ (length (car prefix)))))
559 (incf pos1 (1+ (length (car prefix))))) 549 (setq follow (substring word pos1))
560 (setq follow (substring word pos1)) 550 (if (equal follow "")
561 (if (equal follow "") 551 ;; we've got something like "C-M-" -- just let it be,
562 (error "%s must precede a string" 552 ;; because of the way `edmacro-format-keys' works.
563 (substring word 0 pos1))) 553 (mapcar 'identity word)
564 (nconc (nreverse r1) (list (funcall conv follow)))))) 554 (list (nconc (nreverse r1) (list (funcall conv follow)))))))
565 (force-sym 555 (force-sym
566 ;; This must be a symbol 556 ;; This must be a symbol
567 (list (intern word))) 557 (list (intern word)))
568 (t 558 (t
569 ;; Characters 559 ;; Characters
572 (loop repeat times do (setq new (append add new))) 562 (loop repeat times do (setq new (append add new)))
573 new))) 563 new)))
574 564
575 ;; Convert the keypress events in vector x to keys, and return a 565 ;; Convert the keypress events in vector x to keys, and return a
576 ;; vector of keys. If a list element is not a keypress event, ignore 566 ;; vector of keys. If a list element is not a keypress event, ignore
577 ;; it. 567 ;; it. `events-to-keys' won't quite cut it here, as it is buggy.
578 (defun edmacro-events-to-keys (x &optional list) 568 (defun edmacro-events-to-keys (x &optional list)
579 (let (new) 569 (let (new)
580 (mapc (lambda (el) 570 (mapc (lambda (el)
581 (cond ((key-press-event-p el) 571 (cond ((key-press-event-p el)
582 (push (let ((mods (event-modifiers el))) 572 (push (let ((mods (event-modifiers el)))
592 (setq new (nreverse new)) 582 (setq new (nreverse new))
593 (if list 583 (if list
594 new 584 new
595 (mapvector 'identity new)))) 585 (mapvector 'identity new))))
596 586
597 ;; Collapse a list of keys into a list of function keys, where 587 ;; Collapse a list of keys into a list of function keys, if any.
598 ;; applicable.
599 (defun edmacro-fkeys (keys) 588 (defun edmacro-fkeys (keys)
600 (let (new k lookup) 589 (let (new k lookup)
601 (while keys 590 (while keys
602 (setq k (nconc k (list (car keys)))) 591 (setq k (nconc k (list (car keys))))
603 (setq lookup (lookup-key function-key-map (mapvector 'identity k))) 592 (setq lookup (lookup-key function-key-map (mapvector 'identity k)))
614 (pop keys)) 603 (pop keys))
615 (when (keymapp lookup) 604 (when (keymapp lookup)
616 (push k new)) 605 (push k new))
617 (apply 'nconc (nreverse new)))) 606 (apply 'nconc (nreverse new))))
618 607
619 ;; Convert a character or symbol to string 608 ;; Convert a character or symbol to string.
620 (defun edmacro-conv (char-or-sym add-<>) 609 (defun edmacro-conv (char-or-sym add-<>)
621 (let ((char-to-word '((?\0 . "NUL") 610 (let ((char-to-word '((?\0 . "NUL")
622 (?\r . "RET") 611 (?\r . "RET")
623 (?\n . "LFD") 612 (?\n . "LFD")
624 (?\t . "TAB") 613 (?\t . "TAB")
657 (defun edmacro-format-1 (keys command times togetherp) 646 (defun edmacro-format-1 (keys command times togetherp)
658 (let ((res "") 647 (let ((res "")
659 (start keys) 648 (start keys)
660 el) 649 el)
661 (while keys 650 (while keys
662 (when (or (eq (car keys) ?-) 651 (when (not (or togetherp (eq start keys)))
663 (eq (car keys) '-)
664 (eq (car keys) ?>)
665 (not (or togetherp (eq start keys))))
666 (callf concat res " ")) 652 (callf concat res " "))
667 (if (> times 1) 653 (if (> times 1)
668 (setq res (concat (format "%d*" times) res))) 654 (setq res (concat (format "%d*" times) res)))
669 (setq el (car keys)) 655 (setq el (car keys))
670 (callf concat res 656 (callf concat res
685 (> times 1)) 671 (> times 1))
686 (concat "<" my ">") 672 (concat "<" my ">")
687 my))) 673 my)))
688 (t 674 (t
689 (cdr (edmacro-conv el t))))) 675 (cdr (edmacro-conv el t)))))
676 (and (cdr keys)
677 (memq (car keys) '(?- '- ?> ?^))
678 (callf concat res " "))
690 (pop keys)) 679 (pop keys))
691 (if command 680 (if command
692 (callf concat res 681 (callf concat res
693 (make-string (max (- 3 (/ (length res) tab-width)) 1) ?\t) 682 (make-string (max (- 3 (/ (length res) tab-width)) 1) ?\t)
694 ";; " 683 ";; "
704 (not seq1)) 693 (not seq1))
705 694
706 ;;; Formatting a keyboard macro as human-readable text. 695 ;;; Formatting a keyboard macro as human-readable text.
707 696
708 (defun edmacro-format-keys (macro &optional verbose) 697 (defun edmacro-format-keys (macro &optional verbose)
709 ;; XEmacs:
710 ;; If we're dealing with events, convert them to symbols first; 698 ;; If we're dealing with events, convert them to symbols first;
711 ;; also, deal with Fkeys. 699 ;; Then, collapse them into function keys, if possible.
712 (setq macro (edmacro-fkeys (edmacro-events-to-keys macro t))) 700 (setq macro (edmacro-fkeys (edmacro-events-to-keys macro t)))
713 (let ((res "")) 701 (let ((res ""))
714 (while macro 702 (while macro
715 (let (key lookup (times 1) self-insert-p) 703 (let (key lookup (times 1) self-insert-p)
716 (loop 704 (loop