mc-edit-lines.el (3924B)
1 ;;; mc-edit-lines.el 2 3 ;; Copyright (C) 2012 Magnar Sveen 4 5 ;; Author: Magnar Sveen <magnars@gmail.com> 6 ;; Keywords: editing cursors 7 8 ;; This program is free software; you can redistribute it and/or modify 9 ;; it under the terms of the GNU General Public License as published by 10 ;; the Free Software Foundation, either version 3 of the License, or 11 ;; (at your option) any later version. 12 13 ;; This program is distributed in the hope that it will be useful, 14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 ;; GNU General Public License for more details. 17 18 ;; You should have received a copy of the GNU General Public License 19 ;; along with this program. If not, see <http://www.gnu.org/licenses/>. 20 21 ;;; Commentary: 22 23 ;; This file contains functions to add multiple cursors to consecutive lines 24 ;; given an active region. 25 26 ;; Please see multiple-cursors.el for more commentary. 27 28 ;;; Code: 29 30 (require 'multiple-cursors-core) 31 32 (defcustom mc/edit-lines-empty-lines nil 33 "What should be done by `mc/edit-lines' when a line is not long enough." 34 :type '(radio (const :tag "Pad the line with spaces." pad) 35 (const :tag "Ignore the line." ignore) 36 (const :tag "Signal an error." error) 37 (const :tag "Nothing. Cursor is at end of line." nil)) 38 :group 'multiple-cursors) 39 40 ;;;###autoload 41 (defun mc/edit-lines (&optional arg) 42 "Add one cursor to each line of the active region. 43 Starts from mark and moves in straight down or up towards the 44 line point is on. 45 46 What is done with lines which are not long enough is governed by 47 `mc/edit-lines-empty-lines'. The prefix argument ARG can be used 48 to override this. If ARG is a symbol (when called from Lisp), 49 that symbol is used instead of `mc/edit-lines-empty-lines'. 50 Otherwise, if ARG negative, short lines will be ignored. Any 51 other non-nil value will cause short lines to be padded." 52 (interactive "P") 53 (when (not (and mark-active (/= (point) (mark)))) 54 (error "Mark a set of lines first")) 55 (mc/remove-fake-cursors) 56 (let* ((col (current-column)) 57 (point-line (line-number-at-pos)) 58 (mark-line (progn (exchange-point-and-mark) (line-number-at-pos))) 59 (direction (if (< point-line mark-line) :up :down)) 60 (style (cond 61 ;; called from lisp 62 ((and arg (symbolp arg)) 63 arg) 64 ;; negative argument 65 ((< (prefix-numeric-value arg) 0) 66 'ignore) 67 (arg 'pad) 68 (t mc/edit-lines-empty-lines)))) 69 (deactivate-mark) 70 (when (and (eq direction :up) (bolp)) 71 (previous-logical-line 1 nil) 72 (move-to-column col)) 73 ;; Add the cursors 74 (while (not (eq (line-number-at-pos) point-line)) 75 ;; Pad the line 76 (when (eq style 'pad) 77 (while (< (current-column) col) 78 (insert " "))) 79 ;; Error 80 (when (and (eq style 'error) 81 (not (equal col (current-column)))) 82 (error "Short line encountered in `mc/edit-lines'")) 83 ;; create the cursor 84 (unless (and (eq style 'ignore) 85 (not (equal col (current-column)))) 86 (mc/create-fake-cursor-at-point)) 87 ;; proceed to next 88 (if (eq direction :up) 89 (previous-logical-line 1 nil) 90 (next-logical-line 1 nil)) 91 (move-to-column col)) 92 (multiple-cursors-mode))) 93 94 ;;;###autoload 95 (defun mc/edit-ends-of-lines () 96 "Add one cursor to the end of each line in the active region." 97 (interactive) 98 (mc/edit-lines) 99 (mc/execute-command-for-all-cursors 'end-of-line)) 100 101 ;;;###autoload 102 (defun mc/edit-beginnings-of-lines () 103 "Add one cursor to the beginning of each line in the active region." 104 (interactive) 105 (mc/edit-lines) 106 (mc/execute-command-for-all-cursors 'beginning-of-line)) 107 108 (provide 'mc-edit-lines) 109 110 ;;; mc-edit-lines.el ends here