;-*- mode:lisp; package:steve; readtable:cl; -*- ;Copyright (c) May 1983 by Christopher Eliot ; and Massachusetts Institute of Technology. ;Permission to copy all or part of this material is granted, provided ; that the copies are not made or distributed for resale, the MIT ; copyright notice and reference to the source file and the software ; distribution version appear, and that notice is given that copying ; is by permission of Massachusetts Institute of Technology. ; ;Keyboard macros. ; ; (defvar kbd-macro-iterations 0) (defvar kbd-macro-to-iterate nil) (editor-bind-key '(#\control-x #\() start-kbd-macro) (defun start-kbd-macro () (when (memq '|Def| *minor-modes*) (ed-lose "Already defining a keyboard macro")) (push '|Def| *minor-modes*) (setup-mode-area) (setq save-chars-for-keyboard-macros t keyboard-macro-char-list nil) nil) (editor-bind-key '(#\control-x #\)) end-kbd-macro) (defun end-kbd-macro () (cond ((not (null save-chars-for-keyboard-macros)) (setq keyboard-macro-char-list (nreverse keyboard-macro-char-list)) (setq save-chars-for-keyboard-macros nil) (setq *minor-modes* (delq '|Def| *minor-modes*)) (setup-mode-area)) ((zerop (setq kbd-macro-iterations (sub1 kbd-macro-iterations))) nil) (t (setq executing-keyboard-macro kbd-macro-to-iterate))) nil) (editor-bind-key '(#\control-x #\E) call-last-kbd-macro) (defun call-last-kbd-macro () (when (not (null keyboard-macro-char-list)) ;;For safety sake we turn off passall in a keyboard macro. ;;it is automatically reset when the KBD macro finishes. ;;With-no-passall knows about KBD macros, and leaves passall off when ;;executing one. (send terminal-io :set-device-mode :passall nil) (setq executing-keyboard-macro keyboard-macro-char-list) (setq kbd-macro-to-iterate keyboard-macro-char-list) (setq kbd-macro-iterations *argument*)) nil) (bindmetax name-kbd-macro name-kbd-macro) (defun name-kbd-macro (&optional (name nil)) (when (null keyboard-macro-char-list) (ed-lose "No Kbd Macro to name")) (when (null name) (setq name (mx-prompter #'read-symbol "Macro Name: "))) (let ((keystrokes (with-query-line (format terminal-io "Key: ") (read-key))) (function (eval `(lambda () (send terminal-io :set-device-mode :passall nil) (setq kbd-macro-iterations *argument*) (setq kbd-macro-to-iterate (setq executing-keyboard-macro ',(copy-list keyboard-macro-char-list))) nil)))) (fset-carefully name function) (defcommand (string name) meta-x-command-table name) (with-query-line (format terminal-io "Bind Kbd macro to key ~s? " keystrokes) (when (ed-y-or-n-p "Type Y to bind current macro to key ~s" keystrokes) (internal-bindery keystrokes function))))) (editor-bind-key '(#\control-x #\Q) Kbd-Macro-query) (defun Kbd-Macro-query () (cond ((not (null save-chars-for-keyboard-macros))) ((argument?) (cond ((null (recursive-edit "Kbd Macro Query" '(executing-keyboard-macro) nil)) (ed-warn "Aborted Kbd Macro")) (t (with-notify-line-remaining (format terminal-io "Continuing Kbd Macro ~a" executing-keyboard-macro))))) ((with-query-line (oustr "Kbd Macro Query (y or n): " terminal-io) (ed-y-or-n-p "Type Y to Continue, N to abort Keyboard macro"))) (t (ed-warn "Aborted Kbd Macro"))) nil) (bindmetax view-kbd-macro view-kbd-macro) (defun view-kbd-macro (&optional (name nil)) (setq name (if (null name) keyboard-macro-char-list (try-to-extract-kbd-macro-definition name))) (if (null name) (ed-warn "Definition Inaccessible") (with-notify-line-remaining (oustr "Defining Key Sequence: " terminal-io) (mapc #'(lambda (x) (princ x terminal-io) (princ " " terminal-io)) name)))) (defun try-to-extract-kbd-macro-definition (name) (when (setq name (intern-soft (string-upcase name) 'steve)) (when (setq name (si:symbol-function-definition name)) (when (setq name (fourth name)) (when (setq name (third name)) (when (setq name (second name)) name))))))