diff --git a/features/edit-lines.feature b/features/edit-lines.feature index 814f784..080eaee 100644 --- a/features/edit-lines.feature +++ b/features/edit-lines.feature @@ -55,3 +55,86 @@ Feature: Switching from a multiline region to multiple cursors And I go to the front of the word "there" And I press "C-S-c C-S-c" Then I should have 2 cursors + + Scenario: Edit default short lines + When I insert: + """ + hello + + there + """ + And I go to the end of the word "hello" + And I set the mark + And I go to the end of the word "there" + And I press "C-S-c C-S-c" + And I press "you" + Then I should see: + """ + helloyou + you + thereyou + """ + + Scenario: Pad short lines + When I insert: + """ + hello + + there + """ + And I go to the end of the word "hello" + And I set the mark + And I go to the end of the word "there" + And I press "M-1 C-S-c C-S-c" + Then I should have 3 cursors + + Scenario: Edit padding short lines + When I insert: + """ + hello + + there + """ + And I go to the end of the word "hello" + And I set the mark + And I go to the end of the word "there" + And I press "M-1 C-S-c C-S-c" + And I press "you" + Then I should see: + """ + helloyou + you + thereyou + """ + + Scenario: Skip short lines + When I insert: + """ + hello + + there + """ + And I go to the end of the word "hello" + And I set the mark + And I go to the end of the word "there" + And I press "M-- M-1 C-S-c C-S-c" + Then I should have 2 cursors + + Scenario: Edit skipping short lines + When I insert: + """ + hello + + there + """ + And I go to the end of the word "hello" + And I set the mark + And I go to the end of the word "there" + And I press "M-- M-1 C-S-c C-S-c" + And I press "you" + Then I should see: + """ + helloyou + + thereyou + """ diff --git a/mc-edit-lines.el b/mc-edit-lines.el index 3303620..20668cf 100644 --- a/mc-edit-lines.el +++ b/mc-edit-lines.el @@ -29,25 +29,62 @@ (require 'multiple-cursors-core) +(defcustom mc/edit-lines-empty-lines nil + "What should be done by `mc/edit-lines' when a line is not long enough." + :type '(radio (const :tag "Pad the line with spaces." pad) + (const :tag "Ignore the line." ignore) + (const :tag "Signal an error." error) + (const :tag "Nothing. Cursor is at end of line." nil)) + :group 'multiple-cursors) + ;;;###autoload -(defun mc/edit-lines () +(defun mc/edit-lines (&optional arg) "Add one cursor to each line of the active region. Starts from mark and moves in straight down or up towards the -line point is on." - (interactive) +line point is on. + +What is done with lines which are not long enough is governed by +`mc/edit-lines-empty-lines'. The prefix argument ARG can be used +to override this. If ARG is a symbol (when called from Lisp), +that symbol is used instead of `mc/edit-lines-empty-lines'. +Otherwise, if ARG negative, short lines will be ignored. Any +other non-nil value will cause short lines to be padded." + (interactive "P") (when (not (and mark-active (/= (point) (mark)))) - (error "Mark a set of lines first.")) + (error "Mark a set of lines first")) (mc/remove-fake-cursors) (let* ((col (current-column)) (point-line (line-number-at-pos)) (mark-line (progn (exchange-point-and-mark) (line-number-at-pos))) - (direction (if (< point-line mark-line) :up :down))) + (direction (if (< point-line mark-line) :up :down)) + (style (cond + ;; called from lisp + ((and arg (symbolp arg)) + arg) + ;; negative argument + ((< (prefix-numeric-value arg) 0) + 'ignore) + (arg 'pad) + (t mc/edit-lines-empty-lines)))) (deactivate-mark) (when (and (eq direction :up) (bolp)) (previous-logical-line 1 nil) (move-to-column col)) + ;; Add the cursors (while (not (eq (line-number-at-pos) point-line)) - (mc/create-fake-cursor-at-point) + ;; Pad the line + (when (eq style 'pad) + (while (< (current-column) col) + (insert " "))) + ;; Error + (when (and (eq style 'error) + (not (equal col (current-column)))) + (error "Short line encountered in `mc/edit-lines'")) + ;; create the cursor + (unless (and (eq style 'ignore) + (not (equal col (current-column)))) + (mc/create-fake-cursor-at-point)) + ;; proceed to next (if (eq direction :up) (previous-logical-line 1 nil) (next-logical-line 1 nil))