+ (let ((key-seq (read-key-sequence "Bind last macro to key: "))
+ ok cmd)
+ (when (= (length key-seq) 1)
+ (let ((ch (aref key-seq 0)))
+ (if (or (and (>= ch ?0) (<= ch ?9))
+ (and (>= ch ?A) (<= ch ?Z)))
+ (setq key-seq (concat "\C-x\C-k" key-seq)
+ ok t))))
+ (when (and (not (equal key-seq "\a"))
+ (or ok
+ (not (setq cmd (key-binding key-seq)))
+ (stringp cmd)
+ (vectorp cmd)
+ (yes-or-no-p (format "%s runs command %S. Bind anyway? "
+ (format-kbd-macro key-seq)
+ cmd))))
+ (define-key global-map key-seq
+ (kmacro-lambda-form (kmacro-ring-head)))
+ (message "Keyboard macro bound to %s" (format-kbd-macro key-seq))))))
+
+
+(defun kmacro-name-last-macro (symbol)
+ "Assign a name to the last keyboard macro defined.
+Argument SYMBOL is the name to define.
+The symbol's function definition becomes the keyboard macro string.
+Such a \"function\" cannot be called from Lisp, but it is a valid editor command."
+ (interactive "SName for last kbd macro: ")
+ (or last-kbd-macro
+ (error "No keyboard macro defined"))
+ (and (fboundp symbol)
+ (not (get symbol 'kmacro))
+ (not (stringp (symbol-function symbol)))
+ (not (vectorp (symbol-function symbol)))
+ (error "Function %s is already defined and not a keyboard macro"
+ symbol))
+ (if (string-equal symbol "")
+ (error "No command name given"))
+ (fset symbol (kmacro-lambda-form (kmacro-ring-head)))
+ (put symbol 'kmacro t))