diff --git a/features/repeat-command.feature b/features/repeat-command.feature new file mode 100644 index 0000000..b49c859 --- /dev/null +++ b/features/repeat-command.feature @@ -0,0 +1,37 @@ +Feature: Repeat last interactive command for fake cursors (mc/repeat-command) + + Scenario: Clone insert-char from M-x + Given I have cursors at "text" in "This text contains the word text thrice (text)" + When I start an action chain + When I press "M-x" + And I type "insert-char" + And I press "RET" + And I type "21" + And I press "RET" + And I press "C-:" + And I press "y" + And I execute the action chain + Then I should see "This !text contains the word !text thrice (!text)" + + Scenario: Clone insert-char from M-: + Given I have cursors at "text" in "This text contains the word text thrice (text)" + When I start an action chain + When I press "M-:" + And I type "(insert-char (+ 40 2))" + And I press "RET" + And I press "C-:" + And I press "y" + And I execute the action chain + Then I should see "This *text contains the word *text thrice (*text)" + + Scenario: Disable prompt + Given I have cursors at "text" in "This text/0000 contains the word text/1111 thrice (text/2222)" + When I set mc/always-repeat-command to t + When I start an action chain + And I press "M-x" + And I type "zap-to-char" + And I press "RET" + And I press "/" + And I press "C-:" + And I execute the action chain + Then I should see "This 0000 contains the word 1111 thrice (2222)" diff --git a/multiple-cursors-core.el b/multiple-cursors-core.el index a60c9db..d448617 100644 --- a/multiple-cursors-core.el +++ b/multiple-cursors-core.el @@ -330,6 +330,11 @@ cursor with updated info." :type '(boolean) :group 'multiple-cursors) +(defcustom mc/always-repeat-command nil + "Disables confirmation for `mc/repeat-command' command." + :type '(boolean) + :group 'multiple-cursors) + (defun mc/prompt-for-inclusion-in-whitelist (original-command) "Asks the user, then adds the command either to the once-list or the all-list." (let ((all-p (y-or-n-p (format "Do %S for all cursors?" original-command)))) @@ -442,6 +447,17 @@ you should disable multiple-cursors-mode." (multiple-cursors-mode 0) (deactivate-mark))) +(defun mc/repeat-command () + "Run last command from `command-history' for every fake cursor." + (interactive) + (when (or mc/always-repeat-command + (y-or-n-p (format "[mc] repeat complex command: %s? " (caar command-history)))) + (mc/execute-command-for-all-fake-cursors + (lambda () (interactive) + (cl-letf (((symbol-function 'read-from-minibuffer) + (lambda (p &optional i k r h d m) (read i)))) + (repeat-complex-command 0)))))) + (defvar mc/keymap nil "Keymap while multiple cursors are active. Main goal of the keymap is to rebind C-g and to conclude @@ -450,6 +466,7 @@ multiple cursors editing.") (setq mc/keymap (make-sparse-keymap)) (define-key mc/keymap (kbd "C-g") 'mc/keyboard-quit) (define-key mc/keymap (kbd "") 'multiple-cursors-mode) + (define-key mc/keymap (kbd "C-:") 'mc/repeat-command) (when (fboundp 'phi-search) (define-key mc/keymap (kbd "C-s") 'phi-search)) (when (fboundp 'phi-search-backward) @@ -657,6 +674,7 @@ for running commands with multiple cursors." mc/skip-to-previous-like-this rrm/switch-to-multiple-cursors mc-hide-unmatched-lines-mode + mc/repeat-command hum/keyboard-quit hum/unhide-invisible-overlays save-buffer @@ -665,6 +683,7 @@ for running commands with multiple cursors." exit-minibuffer minibuffer-complete-and-exit execute-extended-command + eval-expression undo redo undo-tree-undo @@ -698,7 +717,8 @@ for running commands with multiple cursors." windmove-left windmove-right windmove-up - windmove-down)) + windmove-down + repeat-complex-command)) (defvar mc--default-cmds-to-run-for-all nil "Default set of commands that should be mirrored by all cursors")