How can I repeat the previous Command easily? How can I repeat it, modifying it slightly?

‘C-x ESC ESC’ is the answer (Control-X, then Escape, then Escape). This places the Emacs Lisp code of your last command (or KeySequence) in the MiniBuffer - just hit ‘Enter’ (‘Return’) to execute the previous command again. Example:

        Redo: (describe-function (quote undo))
        Redo: (describe-function (quote forward-sexp))

This example isn’t very useful. But suppose you want to repeat the command ‘query-replace’ in several different windows (different buffers) with the same arguments, replacing “bush” with “kerry”. You execute it once, click in a different window, then type ‘C-x ESC ESC’ to execute it again:

        Redo: (query-replace "bush" "kerry" nil (if (and transient-mark-mode mark-active) (region-beginning)) (if (and transient-mark-mode mark-active) (region-end)))

The (query-replace "bush" "kerry" part makes immediate sense, but what’s all that other stuff? Don’t worry about it, just hit ‘Enter’.

But if you really want to know, how can you find out? Correct: ‘describe-function query-replace’ (‘C-h f’ query-replace). The help tells you that command ‘query-replace’ really takes five arguments:

You can read the help to understand each argument. Summary: The last two arguments define the limits of the query-replace search. They say in effect that if you have a region active (that is, if you have text selected), then the search is limited to the region. Otherwise, all of the buffer following the TextCursor is searched.

[What’s the implicit lesson here? If you become a little familiar with Emacs Lisp, it can help you use Emacs more effectively. And the more you learn, the more effective you can be.]

What if you had to do more than just click in another window to get to another buffer to reexecute your query-replace command? The previous command might then no longer be your query-replace; it might be something like switch-to-buffer another-buffer (command switch-to-buffer is bound to ‘C-x b’).

How can I execute a previous command that was not the last command?

Just use ‘C-x ESC ESC’, but then use ‘M-p’ to retrieve the next-to-last command, ‘M-p M-p’ to get the command previous to that, and so on. ‘M-p’ moves backward through all your previously executed commands; ‘M-n’ moves forward through them from some previous command.

See also RepeatLastCommand.