How can you repeat last shell command with a single shortcut (and no y/n prompts)? How to replace this sequence:

  1. C-u C-x s (or equivalent) to save all buffers
  2. M-! for (shell-command COMMAND &optional ...)
  3. M-p for (previous-history-element N)
  4. RET

Basically, how can you get this working:

(global-set-key (kbd "M-`") (lambda () (interactive)
              (save-some-buffers)  ;; 1.
              (shell-command nil)  ;; 2.
              (previous-history-element 1)  ;; 3.
              (<press RET>)))  ;; 4.

As is, it returns an error: shell-command: Wrong type argument: stringp, nil. What should a COMMAND be when calling (shell-command COMMAND ...) from ELISP?

Somewhat related question: Is there a (repeat-last-command) in Emacs?

  • 2
    Why don't you just record a keyboard macro and replay that? – wasamasa Jun 6 '15 at 6:19
  • You're right! I was overthinking it. And then just save the macro. – Blaz Jun 6 '15 at 6:24

If you wish to do this properly in elisp, here's a stab at it:

(defun my-repeat-last-shell-command ()
  (shell-command (cadr (assoc 'shell-command command-history))))
  • (save-some-buffers t) to prevent from prompting Save file <filepath>?. – Blaz Jun 6 '15 at 6:47
  • This might backfire. How to check that last (shell-command) did not start with a non-idempotent command like rm or mv? – Blaz Jun 6 '15 at 6:54
  • @courteous Well, I'm just transcribing your set of commands in a slightly less literal way. Not prompting on saving (the mere fact that a save is done is somewhat surprising, I wouldn't expect it from that kind of command) is one thing, filtering out unsafe candidates is beyond the scope of this question. – wasamasa Jun 6 '15 at 7:01

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.