4

I need to be able to parse a string like the following:

M-: (forward-word 4) RET

and execute it from elisp.

For that purpose I'm trying to use execute-kbd-macro and edmacro-parse-keys but I'm a little bit surprised as these functions won't be executed in the current buffer (with current buffer, i.e. using with-current-buffer), please take a look:

(defun execute-macro-in-the-current-buffer ()
    (interactive)
    (with-current-buffer (get-buffer-create "*test-buffer*")
        (erase-buffer)
        (insert "Lorem Ipsum is simply dummy text of the printing and typesetting industry.")
        (goto-char 0)
        (execute-kbd-macro
          (edmacro-parse-keys "M->") t)))

When I execute it then my point moves to the end of the current buffer but not of the buffer *test-buffer* as I was expected. But why? What is wrong?

May be I need another way to parse a string and execute it? Which one?

  • 1
    To be clear, is this an example of a (Lisp) string you want to parse: "M-: (forward-word 4) RET"? Out of curiosity, why? What are you really trying to do? – Drew May 20 '15 at 0:57
  • Yes, this is just an example of a string which I would like to parse. There are can be endless variants: M-x replace-string RET foo RET bar RET, C-c g t C-n C-n C-l book RET, C-SPC M-> M-x delete-region RET etc. I.e. any possible command. I'm currently experimenting with a new package. Purpose of it is the integration testing for Emacs packages. Now I'm parsing an instruction and would like to apply it to another buffer but that doesn't work for me. – Andriy Tykhonov May 20 '15 at 8:10
  • There is not position 0 in buffer, first pos is 1. Beside - rather call functions, not kbd-macro here. Kbd-macros deliver useful short-cuts in certain circumstances, not general tools. – Andreas Röhler May 20 '15 at 10:26
  • 1
    The code for M-x (execute-extended-command) parses M-x input. The code for M-: (eval-expression) parses M-: input. They parse different syntax. You need to specify the syntax of the various strings you want to parse, otherwise this question is too broad (or unclear), IMO, and risks being closed. "I need to be able to parse* a string like the following" means nothing, unless you specify what "like" means here. – Drew May 20 '15 at 15:16
  • 2
    It's an interactive feature that simulates keyboard presses. Keyboard presses usually go to the active window, so you would have to put the relevant buffer there first. – angus May 20 '15 at 19:35
5

You need to select a window that shows the buffer, too. Here's an example :

(defun execute-macro-in-the-current-buffer ()
  (interactive)
  (let ((win (selected-window)))
    (unwind-protect
        (with-current-buffer (get-buffer-create "*test-buffer*")
          (set-window-buffer win (current-buffer) t)
          (erase-buffer)
          (insert "Lorem Ipsum is simply dummy text of the printing and typesetting industry.")
          (goto-char 0)
          (execute-kbd-macro (edmacro-parse-keys "M->")))
      (set-window-buffer win (current-buffer) t))))

Please note that, for this to work, the test buffer should not be shown in any window. This is is because each window has its own value of (point). If you wanted to avoid this, you could first check whether the test buffer is shown in any window. But then you have to think about what you want to happen if there are more than one windows (i.e. in which one should the macro run ?).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.