mirror of
https://github.com/magnars/multiple-cursors.el.git
synced 2026-05-10 09:28:18 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 340ff672a5 |
@@ -1,26 +1,9 @@
|
||||
# multiple-cursors.el [](http://travis-ci.org/magnars/multiple-cursors.el)
|
||||
|
||||
Multiple cursors for Emacs. This is some pretty crazy functionality, so yes,
|
||||
there are kinks. Don't be afraid though, I've been using it since 2011 with
|
||||
there are kinks. Don't be afraid tho, I've been using it since 2011 with
|
||||
great success and much merriment.
|
||||
|
||||
## Maintenance warning
|
||||
|
||||
I use this package every day, and have been doing so for years. It just works.
|
||||
At least, it works for all my use cases. And if it breaks somehow, I fix it.
|
||||
|
||||
However, it has become painfully clear to me that I don't have time to fix
|
||||
problems I don't have. It's been years since I could keep pace with the issues
|
||||
and pull requests. Whenever I try, I keep getting feedback that my fix isn't
|
||||
good enough by some standard I don't particularly care about.
|
||||
|
||||
So, I have closed the issue tracker and the pull requests. I hope you can
|
||||
happily use this package, just like I do. If it doesn't work for you, then I'm
|
||||
sorry. Thankfully Emacs is infinitely malleable, you can probably fix it
|
||||
yourself.
|
||||
|
||||
TLDR: *I am still maintaining this package*, but I am no longer crowdsourcing a list of issues.
|
||||
|
||||
## Installation
|
||||
|
||||
I highly recommend installing multiple-cursors through `package.el`.
|
||||
@@ -82,7 +65,7 @@ You can [watch an intro to multiple-cursors at Emacs Rocks](http://emacsrocks.co
|
||||
- `mc/mark-previous-like-this-symbol`: Adds a cursor and region at the next part of the buffer backwards that matches the current region, if no region is selected it selects the symbol at the point.
|
||||
- `mc/mark-previous-word-like-this`: Like `mc/mark-previous-like-this` but only for whole words.
|
||||
- `mc/mark-previous-symbol-like-this`: Like `mc/mark-previous-like-this` but only for whole symbols.
|
||||
- `mc/mark-more-like-this-extended`: Use arrow keys to quickly mark/skip next/previous occurrences.
|
||||
- `mc/mark-more-like-this-extended`: Use arrow keys to quickly mark/skip next/previous occurances.
|
||||
- `mc/add-cursor-on-click`: Bind to a mouse event to add cursors by clicking. See tips-section.
|
||||
- `mc/mark-pop`: Set a cursor at the current point and move to the next (different) position on the mark stack. This allows for fine grained control over the placement of cursors.
|
||||
|
||||
@@ -90,8 +73,8 @@ You can [watch an intro to multiple-cursors at Emacs Rocks](http://emacsrocks.co
|
||||
|
||||
- `mc/unmark-next-like-this`: Remove the cursor furthest down in the buffer.
|
||||
- `mc/unmark-previous-like-this`: Remove the cursor furthest up in the buffer.
|
||||
- `mc/skip-to-next-like-this`: Remove the cursor furthest down, marking the next occurrence down.
|
||||
- `mc/skip-to-previous-like-this`: Remove the cursor furthest up, marking the next occurrence up.
|
||||
- `mc/skip-to-next-like-this`: Remove the cursor furthest down, marking the next occurance down.
|
||||
- `mc/skip-to-previous-like-this`: Remove the cursor furthest up, marking the next occurance up.
|
||||
|
||||
### Mark many occurrences
|
||||
|
||||
@@ -134,7 +117,7 @@ You can [watch an intro to multiple-cursors at Emacs Rocks](http://emacsrocks.co
|
||||
|
||||
- Try pressing `mc/mark-next-like-this-word` or
|
||||
`mc/mark-next-like-this-symbol` with no region selected. It will
|
||||
mark the word or symbol and add a cursor at the next occurrence
|
||||
mark the word or symbol and add a cursor at the next occurance
|
||||
|
||||
- Try pressing `mc/mark-all-like-this-dwim` on a tagname in html-mode.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- lexical-binding: t -*-
|
||||
(require 'cl) ;; For lexical-let
|
||||
|
||||
(When "^I mark next like this$"
|
||||
(lambda () (call-interactively 'mc/mark-next-like-this)))
|
||||
@@ -109,22 +109,26 @@
|
||||
|
||||
(When "^I copy \"\\(.+\\)\" in another program$"
|
||||
(lambda (text)
|
||||
(lexical-let ((text text))
|
||||
(setq interprogram-paste-function
|
||||
#'(lambda () (let ((r text)) (setq text nil) r)))))
|
||||
#'(lambda () (let ((r text)) (setq text nil) r))))))
|
||||
|
||||
(Given "^I have bound C-! to a lambda that inserts \"\\(.+\\)\"$"
|
||||
(lambda (ins)
|
||||
(global-set-key (kbd "C-!") #'(lambda () (interactive) (insert ins)))))
|
||||
(lexical-let ((ins ins))
|
||||
(global-set-key (kbd "C-!") #'(lambda () (interactive) (insert ins))))))
|
||||
|
||||
(Given "^I have bound C-! to a new command that inserts \"\\(.+\\)\"$"
|
||||
(lambda (ins)
|
||||
(lexical-let ((ins ins))
|
||||
(defun mc-test-temp-command () (interactive) (insert ins))
|
||||
(global-set-key (kbd "C-!") 'mc-test-temp-command)))
|
||||
(global-set-key (kbd "C-!") 'mc-test-temp-command))))
|
||||
|
||||
(Given "^I have bound C-! to another new command that inserts \"\\(.+\\)\"$"
|
||||
(lambda (ins)
|
||||
(lexical-let ((ins ins))
|
||||
(defun mc-test-temp-command-2 () (interactive) (insert ins))
|
||||
(global-set-key (kbd "C-!") 'mc-test-temp-command-2)))
|
||||
(global-set-key (kbd "C-!") 'mc-test-temp-command-2))))
|
||||
|
||||
(Given "^I have bound C-! to a keyboard macro that insert \"_\"$"
|
||||
(lambda ()
|
||||
|
||||
+1
-1
@@ -88,7 +88,7 @@
|
||||
(cl-defun mc/cycle (next-cursor fallback-cursor loop-message)
|
||||
(when (null next-cursor)
|
||||
(when (eql 'stop (mc/handle-loop-condition loop-message))
|
||||
(cl-return-from mc/cycle nil))
|
||||
(return-from mc/cycle nil))
|
||||
(setf next-cursor fallback-cursor))
|
||||
(mc/create-fake-cursor-at-point)
|
||||
(mc/pop-state-from-overlay next-cursor)
|
||||
|
||||
+3
-3
@@ -54,8 +54,8 @@ other non-nil value will cause short lines to be padded."
|
||||
(error "Mark a set of lines first"))
|
||||
(mc/remove-fake-cursors)
|
||||
(let* ((col (current-column))
|
||||
(point-line (mc/line-number-at-pos))
|
||||
(mark-line (progn (exchange-point-and-mark) (mc/line-number-at-pos)))
|
||||
(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))
|
||||
(style (cond
|
||||
;; called from lisp
|
||||
@@ -71,7 +71,7 @@ other non-nil value will cause short lines to be padded."
|
||||
(previous-logical-line 1 nil)
|
||||
(move-to-column col))
|
||||
;; Add the cursors
|
||||
(while (not (eq (mc/line-number-at-pos) point-line))
|
||||
(while (not (eq (line-number-at-pos) point-line))
|
||||
;; Pad the line
|
||||
(when (eq style 'pad)
|
||||
(while (< (current-column) col)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;;; mc-hide-unmatched-lines-mode.el
|
||||
;;; mc-hide-unmatched-lines.el
|
||||
|
||||
;; Copyright (C) 2014 Aleksey Fedotov
|
||||
|
||||
@@ -73,7 +73,7 @@ mode. To leave this mode press <return> or \"C-g\""
|
||||
:group 'multiple-cursors)
|
||||
|
||||
(defcustom hum/placeholder "..."
|
||||
"Placeholder which will be placed instead of hidden text"
|
||||
"Placeholder which will be placed insted of hiden text"
|
||||
:type '(string)
|
||||
:group 'multiple-cursors)
|
||||
|
||||
@@ -103,6 +103,5 @@ mode. To leave this mode press <return> or \"C-g\""
|
||||
(defun hum/unhide-unmatched-lines ()
|
||||
(remove-overlays nil nil hum/invisible-overlay-name t))
|
||||
|
||||
(define-key mc/keymap (kbd "C-'") 'mc-hide-unmatched-lines-mode)
|
||||
|
||||
(provide 'mc-hide-unmatched-lines-mode)
|
||||
(define-key mc/keymap (kbd "C-'") 'mc-hide-unmatched-lines-mode)
|
||||
|
||||
+28
-4
@@ -190,7 +190,7 @@ With zero ARG, skip the last one and mark next."
|
||||
(defun mc/mark-next-word-like-this (arg)
|
||||
"Find and mark the next word of the buffer matching the currently active region
|
||||
The matching region must be a whole word to be a match
|
||||
If no region is active add a cursor on the next line
|
||||
If no region is active, mark the symbol at the point and find the next match
|
||||
With negative ARG, delete the last one instead.
|
||||
With zero ARG, skip the last one and mark next."
|
||||
(interactive "p")
|
||||
@@ -201,7 +201,7 @@ With zero ARG, skip the last one and mark next."
|
||||
(defun mc/mark-next-symbol-like-this (arg)
|
||||
"Find and mark the next symbol of the buffer matching the currently active region
|
||||
The matching region must be a whole symbol to be a match
|
||||
If no region is active add a cursor on the next line
|
||||
If no region is active, mark the symbol at the point and find the next match
|
||||
With negative ARG, delete the last one instead.
|
||||
With zero ARG, skip the last one and mark next."
|
||||
(interactive "p")
|
||||
@@ -579,8 +579,8 @@ If the region is inactive or on a single line, it will behave like
|
||||
(interactive "P")
|
||||
(if (and (use-region-p)
|
||||
(not (> (mc/num-cursors) 1))
|
||||
(not (= (mc/line-number-at-pos (region-beginning))
|
||||
(mc/line-number-at-pos (region-end)))))
|
||||
(not (= (line-number-at-pos (region-beginning))
|
||||
(line-number-at-pos (region-end)))))
|
||||
(if arg
|
||||
(call-interactively 'mc/edit-lines)
|
||||
(call-interactively 'mc/mark-all-in-region))
|
||||
@@ -704,6 +704,30 @@ already there."
|
||||
(save-excursion
|
||||
(not (null (sgml-get-context)))))
|
||||
|
||||
(defun mc/split-region (beg end search)
|
||||
"Split region each time SEARCH occurs in the buffer.
|
||||
|
||||
This can be thought of as an inverse to `mc/mark-all-in-region'."
|
||||
(interactive "r\nsSplit on: ")
|
||||
(let ((case-fold-search nil))
|
||||
(if (string= search "")
|
||||
(user-error "Empty search term")
|
||||
(progn
|
||||
(mc/remove-fake-cursors)
|
||||
(goto-char beg)
|
||||
(push-mark beg)
|
||||
(while (search-forward search end t)
|
||||
(save-excursion
|
||||
(goto-char (match-beginning 0))
|
||||
(mc/create-fake-cursor-at-point))
|
||||
(push-mark (match-end 0)))
|
||||
(unless (= (point) end)
|
||||
(goto-char end))
|
||||
(mc/create-fake-cursor-at-point)
|
||||
(if (> (mc/num-cursors) 1)
|
||||
(multiple-cursors-mode 1)
|
||||
(multiple-cursors-mode 0))))))
|
||||
|
||||
(provide 'mc-mark-more)
|
||||
|
||||
;;; mc-mark-more.el ends here
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
;;;###autoload
|
||||
(defun mc/vertical-align (character)
|
||||
"Aligns all cursors vertically with a given CHARACTER to the one with the
|
||||
highest column number (the rightest).
|
||||
highest colum number (the rightest).
|
||||
Might not behave as intended if more than one cursors are on the same line."
|
||||
(interactive "c")
|
||||
(let ((rightest-column (current-column)))
|
||||
|
||||
@@ -109,19 +109,6 @@
|
||||
(and (listp cursor-type)
|
||||
(eq (car cursor-type) 'bar))))
|
||||
|
||||
(defun mc/line-number-at-pos (&optional pos absolute)
|
||||
"Faster implementation of `line-number-at-pos'."
|
||||
(if pos
|
||||
(save-excursion
|
||||
(if absolute
|
||||
(save-restriction
|
||||
(widen)
|
||||
(goto-char pos)
|
||||
(string-to-number (format-mode-line "%l")))
|
||||
(goto-char pos)
|
||||
(string-to-number (format-mode-line "%l"))))
|
||||
(string-to-number (format-mode-line "%l"))))
|
||||
|
||||
(defun mc/make-cursor-overlay-at-eol (pos)
|
||||
"Create overlay to look like cursor at end of line."
|
||||
(let ((overlay (make-overlay pos pos nil nil nil)))
|
||||
@@ -162,18 +149,7 @@ highlights the entire width of the window."
|
||||
autopair-action
|
||||
autopair-wrap-action
|
||||
temporary-goal-column
|
||||
er/history
|
||||
dabbrev--abbrev-char-regexp
|
||||
dabbrev--check-other-buffers
|
||||
dabbrev--friend-buffer-list
|
||||
dabbrev--last-abbrev-location
|
||||
dabbrev--last-abbreviation
|
||||
dabbrev--last-buffer
|
||||
dabbrev--last-buffer-found
|
||||
dabbrev--last-direction
|
||||
dabbrev--last-expansion
|
||||
dabbrev--last-expansion-location
|
||||
dabbrev--last-table)
|
||||
er/history)
|
||||
"A list of vars that need to be tracked on a per-cursor basis.")
|
||||
|
||||
(defun mc/store-current-state-in-overlay (o)
|
||||
@@ -448,10 +424,6 @@ the original cursor, to inform about the lack of support."
|
||||
(message "%S is not supported with multiple cursors%s"
|
||||
original-command
|
||||
(get original-command 'mc--unsupported))
|
||||
|
||||
;; lazy-load the user's list file
|
||||
(mc/load-lists)
|
||||
|
||||
(when (and original-command
|
||||
(not (memq original-command mc--default-cmds-to-run-once))
|
||||
(not (memq original-command mc/cmds-to-run-once))
|
||||
@@ -607,7 +579,7 @@ from being executed if in multiple-cursors-mode."
|
||||
(when interprogram-paste
|
||||
;; Add interprogram-paste to normal kill ring, just
|
||||
;; like current-kill usually does for itself.
|
||||
;; We have to do the work for it though, since the funcall only returns
|
||||
;; We have to do the work for it tho, since the funcall only returns
|
||||
;; something once. It is not a pure function.
|
||||
(let ((interprogram-cut-function nil))
|
||||
(if (listp interprogram-paste)
|
||||
@@ -630,15 +602,6 @@ for running commands with multiple cursors."
|
||||
:type 'file
|
||||
:group 'multiple-cursors)
|
||||
|
||||
(defvar mc--list-file-loaded nil
|
||||
"Whether the list file has already been loaded.")
|
||||
|
||||
(defun mc/load-lists ()
|
||||
"Loads preferences for running commands with multiple cursors from `mc/list-file'"
|
||||
(unless mc--list-file-loaded
|
||||
(load mc/list-file 'noerror 'nomessage)
|
||||
(setq mc--list-file-loaded t)))
|
||||
|
||||
(defun mc/dump-list (list-symbol)
|
||||
"Insert (setq 'LIST-SYMBOL LIST-VALUE) to current buffer."
|
||||
(cl-symbol-macrolet ((value (symbol-value list-symbol)))
|
||||
@@ -843,9 +806,11 @@ for running commands with multiple cursors."
|
||||
(defvar mc/cmds-to-run-for-all nil
|
||||
"Commands to run for all cursors in multiple-cursors-mode")
|
||||
|
||||
;; load, but no errors if it does not exist yet please, and no message
|
||||
;; while loading
|
||||
(load mc/list-file 'noerror 'nomessage)
|
||||
|
||||
(provide 'multiple-cursors-core)
|
||||
(require 'mc-cycle-cursors)
|
||||
(require 'mc-hide-unmatched-lines-mode)
|
||||
|
||||
;; Local Variables:
|
||||
;; coding: utf-8
|
||||
|
||||
+5
-3
@@ -22,7 +22,7 @@
|
||||
;;; Commentary:
|
||||
|
||||
;; Multiple cursors for Emacs. This is some pretty crazy functionality, so yes,
|
||||
;; there are kinks. Don't be afraid though, I've been using it since 2011 with
|
||||
;; there are kinks. Don't be afraid tho, I've been using it since 2011 with
|
||||
;; great success and much merriment.
|
||||
|
||||
;; ## Basic usage
|
||||
@@ -68,7 +68,7 @@
|
||||
;; - `mc/mark-previous-like-this`: Adds a cursor and region at the next part of the buffer backwards that matches the current region.
|
||||
;; - `mc/mark-previous-word-like-this`: Like `mc/mark-previous-like-this` but only for whole words.
|
||||
;; - `mc/mark-previous-symbol-like-this`: Like `mc/mark-previous-like-this` but only for whole symbols.
|
||||
;; - `mc/mark-more-like-this-extended`: Use arrow keys to quickly mark/skip next/previous occurrences.
|
||||
;; - `mc/mark-more-like-this-extended`: Use arrow keys to quickly mark/skip next/previous occurances.
|
||||
;; - `mc/add-cursor-on-click`: Bind to a mouse event to add cursors by clicking. See tips-section.
|
||||
|
||||
;; ### Mark many occurrences
|
||||
@@ -105,7 +105,7 @@
|
||||
;;
|
||||
;; - Try pressing `mc/mark-next-like-this-word` or
|
||||
;; `mc/mark-next-like-this-symbol` with no region selected. It will
|
||||
;; mark the symbol and add a cursor at the next occurrence
|
||||
;; mark the symbol and add a cursor at the next occurance
|
||||
;;
|
||||
;; - Try pressing `mc/mark-all-like-this-dwim` on a tagname in html-mode.
|
||||
;;
|
||||
@@ -191,10 +191,12 @@
|
||||
:group 'editing)
|
||||
|
||||
(require 'mc-edit-lines)
|
||||
(require 'mc-cycle-cursors)
|
||||
(require 'mc-mark-more)
|
||||
(require 'mc-mark-pop)
|
||||
(require 'rectangular-region-mode)
|
||||
(require 'mc-separate-operations)
|
||||
(require 'mc-hide-unmatched-lines-mode)
|
||||
|
||||
(provide 'multiple-cursors)
|
||||
|
||||
|
||||
@@ -75,9 +75,9 @@ an exceedingly quick way of adding multiple cursors to multiple lines."
|
||||
(rrm/remove-rectangular-region-overlays)
|
||||
(let* ((annoying-arrows-mode nil)
|
||||
(point-column (current-column))
|
||||
(point-line (mc/line-number-at-pos))
|
||||
(point-line (line-number-at-pos))
|
||||
(anchor-column (save-excursion (goto-char rrm/anchor) (current-column)))
|
||||
(anchor-line (save-excursion (goto-char rrm/anchor) (mc/line-number-at-pos)))
|
||||
(anchor-line (save-excursion (goto-char rrm/anchor) (line-number-at-pos)))
|
||||
(left-column (if (< point-column anchor-column) point-column anchor-column))
|
||||
(right-column (if (> point-column anchor-column) point-column anchor-column))
|
||||
(navigation-step (if (< point-line anchor-line) 1 -1)))
|
||||
@@ -85,7 +85,7 @@ an exceedingly quick way of adding multiple cursors to multiple lines."
|
||||
(set-mark (point))
|
||||
(move-to-column point-column)
|
||||
(mc/save-excursion
|
||||
(while (not (= anchor-line (mc/line-number-at-pos)))
|
||||
(while (not (= anchor-line (line-number-at-pos)))
|
||||
(forward-line navigation-step)
|
||||
(move-to-column anchor-column)
|
||||
(when (= anchor-column (current-column))
|
||||
|
||||
Reference in New Issue
Block a user