diff --git a/features/mark-more.feature b/features/mark-more.feature index 6317823..9e35a30 100644 --- a/features/mark-more.feature +++ b/features/mark-more.feature @@ -39,3 +39,43 @@ Feature: Marking multiple parts of the buffer And I press "C-- M->" And I type "more" Then I should see "Here's more, more and text" + + Scenario: Marking prev like this, cursors + When I insert "This text has the word text in it" + And I select the last "text" + And I press "M-<" + Then I should have 2 cursors + + Scenario: Marking prev like this, region + Given I turn on delete-selection-mode + When I insert "This text has the word text in it" + And I select the last "text" + And I press "M-<" + And I type "sentence" + Then I should see "This sentence has the word sentence in it" + + Scenario: Skipping a prev mark + Given I turn on delete-selection-mode + When I insert "Here's text, text and text" + And I select the last "text" + And I press "M-<" + And I press "C-0 M-<" + And I type "more" + Then I should see "Here's more, text and more" + + Scenario: Removing first fake + When I insert "Here's text, text and text" + And I select the last "text" + And I press "M-<" + And I press "C-- M-<" + Then I should have one cursor + + Scenario: Removing first mark + Given I turn on delete-selection-mode + When I insert "Here's text, text and text" + And I select the last "text" + And I press "M-<" + And I press "M-<" + And I press "C-- M-<" + And I type "more" + Then I should see "Here's text, more and more" diff --git a/features/step-definitions/multiple-cursors-steps.el b/features/step-definitions/multiple-cursors-steps.el index 3ecc367..fb4c075 100644 --- a/features/step-definitions/multiple-cursors-steps.el +++ b/features/step-definitions/multiple-cursors-steps.el @@ -82,3 +82,11 @@ (message "Can not go to character '%s' since it does not exist in the current buffer: %s")) (assert search nil message word (espuds-buffer-contents)) (if (string-equal "front" pos) (backward-word))))) + +(When "^I select the last \"\\(.+\\)\"$" + (lambda (text) + (goto-char (point-max)) + (let ((search (re-search-backward text nil t))) + (assert search nil "The text '%s' was not found in the current buffer." text)) + (set-mark (point)) + (re-search-forward text))) diff --git a/features/support/env.el b/features/support/env.el index 108e0b2..ac605b0 100644 --- a/features/support/env.el +++ b/features/support/env.el @@ -21,6 +21,7 @@ (mm/clear-all) (global-set-key (kbd "C->") 'mark-next-like-this) (global-set-key (kbd "M->") 'mc/mark-next-like-this) + (global-set-key (kbd "M-<") 'mc/mark-previous-like-this) (global-set-key (kbd "H-SPC") 'set-rectangular-region-anchor) (switch-to-buffer (get-buffer-create "*multiple-cursors*")) diff --git a/mc-mark-more.el b/mc-mark-more.el index 75e93f7..e57f7ab 100644 --- a/mc-mark-more.el +++ b/mc-mark-more.el @@ -16,6 +16,21 @@ (setq end (max end (mc/cursor-end cursor)))) end)) +(defun mc/first-region-start () + (let ((beg (min (mark) (point)))) + (mc/for-each-fake-cursor + (setq beg (min beg (mc/cursor-beg cursor)))) + beg)) + +(defun mc/furthest-cursor-before-point () + (let ((beg (min (mark) (point))) + furthest) + (mc/for-each-fake-cursor + (when (< (mc/cursor-beg cursor) beg) + (setq beg (mc/cursor-beg cursor)) + (setq furthest cursor))) + furthest)) + (defun mc/furthest-cursor-after-point () (let ((end (max (mark) (point))) furthest) @@ -33,6 +48,7 @@ (mc/cursor-end cursor)))) strings)) +;;;###autoload (defun mc/mark-next-like-this (arg) "Find and mark the next part of the buffer matching the currently active region With negative ARG, delete the last one instead. @@ -61,4 +77,33 @@ With zero ARG, skip the last one and mark next." (multiple-cursors-mode 1) (multiple-cursors-mode 0))) +;;;###autoload +(defun mc/mark-previous-like-this (arg) + "Find and mark the previous part of the buffer matching the currently active region +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark next." + (interactive "p") + (unless (region-active-p) + (error "Mark a region to match first.")) + (when (< arg 0) + (mc/remove-fake-cursor (mc/furthest-cursor-before-point))) + (when (>= arg 0) + (let ((case-fold-search nil) + (point-first (< (point) (mark))) + (re (regexp-opt (mc/region-strings))) + (furthest-cursor (mc/furthest-cursor-before-point))) + (mc/save-excursion + (goto-char (mc/first-region-start)) + (when (= arg 0) + (mc/remove-fake-cursor furthest-cursor)) + (if (search-backward-regexp re nil t) + (progn + (push-mark (match-end 0)) + (unless point-first (exchange-point-and-mark)) + (mc/create-fake-cursor-at-point)) + (error "no more found backward"))))) + (if (> (mc/num-cursors) 1) + (multiple-cursors-mode 1) + (multiple-cursors-mode 0))) + (provide 'mc-mark-more) diff --git a/multiple-cursors-core.el b/multiple-cursors-core.el index a24ebc7..fffacbb 100644 --- a/multiple-cursors-core.el +++ b/multiple-cursors-core.el @@ -333,6 +333,7 @@ for running commands with multiple cursors.") mc/edit-ends-of-lines mc/edit-beginnings-of-lines mc/mark-next-like-this + mc/mark-previous-like-this mc/cycle-forward mc/cycle-backward rrm/switch-to-multiple-cursors