95 Commits

Author SHA1 Message Date
Jules Tamagnan b3bd49c756 Bump version to 1.4.0
The last version change was many years ago.
2016-05-19 16:41:48 -04:00
Magnar Sveen fb0e71a62a Remove mention of marmalade
Closes #200
2016-05-19 11:09:48 +02:00
Magnar Sveen 432a3fc8d6 Merge pull request #250 from nispio/mark-lines-allows-skip
Modified mc/mark-lines to allow skipping
2016-05-13 12:16:00 +02:00
Josh Hunsaker 9f4cdd0907 Modified mc/mark-lines to allow skipping 2016-04-29 12:22:07 -07:00
jtamagnan 6a62e60bf2 Fix issue #131 (#247)
* Fix issue #131

This issue would occur because the function was recieving a raw prefix
arg instead of a number. This commit fixes that.

* Fix issue with previous commit, add test cases
2016-04-28 14:33:15 +12:00
Magnar Sveen da069c88e5 Merge pull request #236 from jtamagnan/insert_letters_fix
Speedup mc--numbers-to-letters
2016-04-27 19:05:42 +02:00
Magnar Sveen d5b544ef9c Merge pull request #246 from purcell/cl-lib
Use cl-lib instead of shimming, which breaks in older emacsen
2016-04-27 06:58:07 +02:00
Steve Purcell 4bf9860bcc Use cl-lib instead of shimming, which breaks in older emacsen
Aliasing built-in (cl) functions to cl-lib versions when they are
available in older Emacs versions can seemingly lead to problems
including infinite loops during byte compilation.

Since cl-lib works with all Emacs versions supported by
multiple-cursors, just depend on this directly instead.

This commit makes the necessary changes, both to code, documentation and
package metadata.
2016-04-25 11:19:06 +12:00
Magnar Sveen 8297f1f210 Merge pull request #241 from YoungFrog/fix-#230
* mc-mark-more.el (mc/mark-all-in-region-regexp): Don't infloop when …
2016-03-04 15:59:52 +01:00
Nicolas Richard 06a2985db0 * mc-mark-more.el (mc/mark-all-in-region-regexp): Don't infloop when regexp matches empty string 2016-03-04 13:01:29 +01:00
Magnar Sveen 8ac4ad3e28 Update README.md 2016-03-03 06:59:47 +01:00
Magnar Sveen e31b1eb59c Merge pull request #240 from ilohmar/toggle-click-improvements
Fix click-toggling and make it robust (address all PR #239 comments)
2016-03-03 06:57:23 +01:00
Ingo Lohmar e17851efd3 Fix click-toggling and make it robust (address all PR #239 comments)
- use marker-position for cursor overlay's point
- new helper function finds fake cursor with its actual *point* where we
  want it
- this also eliminates any need for additional require statements
2016-03-02 21:28:45 +01:00
Magnar Sveen 4c52fb1e56 Merge pull request #239 from ilohmar/dwim-mouse-select
Extend mc/add-cursor-on-click to toggle fake cursors
2016-03-01 22:33:06 +01:00
Ingo Lohmar 40eb74e3e4 Extend mc/add-cursor-on-click to toggle fake cursors
- rename function accordingly and add alias
2016-03-01 20:31:47 +01:00
Magnar Sveen 54c05c3e24 Add more aliases for cl stuff
Issue #120
2016-02-29 06:49:59 +01:00
Magnar Sveen 68961b4cf3 Avoid requiring cl at runtime
Closes #120
2016-02-13 17:17:28 +01:00
Jules Tamagnan 55af65920b Speedup mc--numbers-to-letters 2016-01-28 18:01:47 -05:00
Magnar Sveen a393384b35 Merge pull request #227 from jtamagnan/insert_letters
Add mc/insert-letters function and test cases
2015-12-05 21:25:04 +01:00
Magnar Sveen 415e29f1d1 Add @jtamagnan to contributors list 2015-12-05 00:30:49 +01:00
Magnar Sveen dd07bc50ea Merge pull request #228 from jtamagnan/mark-next-like-this-word
Add alternative to mc/mark-next-like-this
2015-12-05 00:29:03 +01:00
Jules Tamagnan 8703b19872 Add mark-next-like-this-symbol function
* README.md: Update readme to include mark-next-like-this symbol
 * features/step-definitions/multiple-cursors-steps.el: Add phrase for
   mark-next-like-this-symbol
 * features/support/env.el: Add keyboard shortcut for
   mark-next-like-this-symbol and fix shortcut for
   mark-next-like-this-word
 * mc-mark-more.el: Add mc/mark-next-like-this-symbol function
 * multiple-cursors-core.el: Add mc/mark-next-like-this-symbol to
   functions to run only once
 * multiple-cursors.el: Add to readme section.
2015-12-04 16:56:50 -05:00
Jules Tamagnan bbbe90d274 Minor changes mark-next-like-this-word and readme
* README.md: Adjust read to no longer recommend extend region if user
   is using mark-next-like-this-word
 * mc-mark-more.el: mark-next-like-this-word makrs whole word and not
   only from point to the end of the word
2015-12-04 16:28:29 -05:00
Jules Tamagnan 36b7025a35 Add alternative to mc/mark-next-like-this
* README.md: Add mc/mark-next-like-this-word tidbits to readme.
 * features/step-definitions/multiple-cursors-steps.el: Add
   mc/mark-next-like-this-word call.
 * features/support/env.el: Add shortcut for mc/mark-next-like-this-word
   as "C-S-c C->".
 * mc-mark-more.el: Add to mc/mark-next-like-this description to explain
   what happens when no region is selected. Add
   mc/mark-next-like-this-word function.
 * multiple-cursors-core.el: Add mc/mark-next-like-this-word to commands
   to run once.
 * multiple-cursors.el: Add information about mc/mark-next-like-this-word.
2015-12-04 13:34:47 -05:00
Jules Tamagnan ca822cd0d0 Add mc/insert-letters function and test cases
* README.md: Add to readme, under special section.
 * features/insert-letters.feature: Add scenarios.
 * features/step-definitions/multiple-cursors-steps.el: Add call.
 * features/support/env.el: Add keybinding for insert-letters to H-3.
 * mc-separate-operations.el: Add function and helper functions.
 * multiple-cursors-core.el: Add insert-letters to functions that run once.
 * multiple-cursors.el: Add to readme.
2015-12-02 19:13:39 -05:00
Magnar Sveen 97e5db17c5 Merge pull request #207 from vermiculus/master
Add safety ceiling to cursor count at creation
2015-07-10 13:56:17 +02:00
Sean Allred 3f1611c7cb Factor out a superfluous variable
`mc--active-cursor-count' was effectively duplicating the purpose of
`mc/num-cursors'.  While the latter is necessarily slower (being a
function), it is well-tested and stable.
2015-06-27 09:38:02 -05:00
Magnar Sveen 9b53e892e6 Merge pull request #203 from dovej/master
Changed mc/furthest-cursor-after(before)-point to check if mark is active.
2015-06-27 10:48:00 +02:00
Sean Allred cd967e720f Small optimization
If we remove the ceiling entirely, we won't even enter the form that
checks values, etc.
2015-06-26 21:33:48 -05:00
Sean Allred 2e904a0be2 Add safety ceiling to cursor count at creation
The customizable option `mc/max-cursors' now provides a soft maximum for
the number of cursors allowable.  This is helpful for slower emacsen who
may freeze up when adding too many cursors (as in `mark-all' variants).

Fix: #206
2015-06-26 21:17:53 -05:00
Justin Dove 5d677f765c Unrevert "Support unmarking with no region. Change mc/mark-lines to preserve point."
This reverts commit 2588ccef69.
2015-06-08 09:20:46 -04:00
Justin Dove 49c9f7f6bf Merge remote-tracking branch 'upstream/master' 2015-06-08 09:18:33 -04:00
Justin Dove c90bb624db Changed mc/furthest-cursor-after(before)-point to check if mark is active. 2015-06-07 18:06:55 -04:00
Magnar Sveen 2588ccef69 Revert "Support unmarking with no region. Change mc/mark-lines to preserve point."
This reverts commit 2d6ffce4c9.

Fixes #201
2015-05-29 08:03:15 +02:00
Magnar Sveen 142fdd6534 Use locate-user-emacs-file to find directory for .mc-lists.el 2015-05-26 09:07:50 +02:00
Magnar Sveen 66b1127489 Merge pull request #192 from uk-ar/add_search_word
Enable to specify search word in mc/mark-all-in-region
2015-05-24 11:19:34 +02:00
Magnar Sveen 533e1576e3 Merge pull request #160 from P-Seebauer/master
Added whitespace functionality.
2015-05-24 11:17:45 +02:00
Magnar Sveen faf331dfae Merge pull request #183 from grettke/patch-1
Typo fixo.
2015-05-24 11:16:24 +02:00
Magnar Sveen 89e360e96c Merge pull request #193 from dovej/master
Support unmarking with no region. Change mc/mark-lines to preserve point...
2015-05-24 11:15:22 +02:00
Magnar Sveen 97f7b1d598 Merge pull request #197 from kissge/user-emacs-directory
Respect user-emacs-directory
2015-05-24 09:59:32 +02:00
kissge 4969d382de Move mc/list-file to the user-emacs-directory 2015-05-24 13:06:21 +09:00
Justin Dove 2d6ffce4c9 Support unmarking with no region. Change mc/mark-lines to preserve point. 2015-04-05 17:26:07 -04:00
uk-ar 72b4bf3911 Enable to specify search word in mc/mark-all-in-region 2015-04-04 06:29:46 +09:00
Magnar Sveen cec48cc78f Merge pull request #188 from iqbalansari/master
Add missing require to mc-hide-unmatched-lines-mode
2015-03-08 08:22:44 +01:00
Iqbal Ansari 7d843984b3 Add missing require to mc-hide-unmatched-lines-mode
The function `hum/hide-unmatched-lines` uses the function
`mc/cursor-beg`, defined in `mc-mark-more.el`, however the feature is
not required leading to failures in some edge case.  Fixes #187
2015-03-08 12:24:36 +05:30
Grant Rettke 7cf6374333 Typo fixo.
cursos -> cursors
2015-02-05 11:15:09 -06:00
Magnar Sveen dc1bfbf816 Add cua-delete-region to default run-for-all 2015-01-01 23:31:38 +01:00
Magnar Sveen 952877fc5b Revert undo-feature for multiple-cursors
re #169
2014-12-26 19:42:01 +01:00
Magnar Sveen f0dcd06c6f Merge pull request #175 from lexa/master
Add function to disable mc undo into undo-list.
2014-12-22 23:13:38 +01:00
Aleksei ff0ac1fc75 Add function to disable mc undo into undo-list.
When user enables mc mode we need to add function to disable mc mode
into undo-list. When users starts to hit 'undo' at some point mc-mode
will be disabled.
2014-12-23 00:26:21 +03:00
Magnar Sveen 82586a0f66 Consolidate contributor entries for Aleksey 2014-10-26 20:25:21 +01:00
Magnar Sveen adf86bd4c8 Add @lexa to list of contributors 2014-10-26 13:08:11 +01:00
Magnar Sveen 40b1bad8ac Merge pull request #169 from lexa/master
"Undo" after leaving mc mode will restore cursors as they was
2014-10-26 13:03:57 +01:00
lexa 19f842d60a Undo after leaving mc mode will restore cursors as they was 2014-10-26 12:35:39 +03:00
Magnar Sveen 66eefa2963 Add cperl-electric-backspace to default run-for-all list
See #87
2014-10-22 12:39:32 +02:00
Magnar Sveen 49fe803f3b Merge pull request #163 from Silex/master
Improve mc-hide-unmatched-lines-mode.el
2014-10-03 14:51:22 +02:00
Philippe Vaucher 912342ed85 Add missing ###autoload markers 2014-10-03 14:21:18 +02:00
Philippe Vaucher b46f79566e Fix style issues 2014-10-03 14:21:18 +02:00
Patrick Seebauer 715665129e fixed documentation 2014-09-05 18:45:34 +02:00
Patrick Seebauer 7ddda8527b Added vertical align commands
Squashed commit of the following:

commit 243a14e69501bf938eea54449782f43be2084ef2
Author: Patrick Seebauer <patrick.seebuaer@web.de>
Date:   Fri Sep 5 18:06:19 2014 +0200

    removed uniq line check and added warning in the docs about cursors on the same line.

commit 438658ef0358b0a1540c2663aedba0253150a007
Author: Patrick Seebauer <patrick.seebuaer@web.de>
Date:   Fri Sep 5 17:59:55 2014 +0200

    fixed tests for commands with character inputs

commit c565969c6bb01e37ec42cfe311ada87643e38ccc
Author: Patrick Seebauer <patrick.seebuaer@web.de>
Date:   Fri Sep 5 17:36:41 2014 +0200

    renamed to vertical align, added non-whitespace option

commit 941c40a319f571680017293681ff7d796ba4e1f4
Author: Patrick Seebauer <patrick.seebuaer@web.de>
Date:   Fri Sep 5 16:58:14 2014 +0200

    added test

commit d9a4a55ebde9b51c3f62b14948529759aaaa9bf6
Author: Patrick Seebauer <patrick.seebuaer@web.de>
Date:   Tue Sep 2 19:32:49 2014 +0200

    added interactives, added abort if cursors are on the same line

commit 12d01fe4db5109061533b0524d99177d1204eb85
Author: Patrick Seebauer <patrick.seebuaer@web.de>
Date:   Tue Sep 2 18:55:47 2014 +0200

    some adjustments

commit 9fddf98b6cd1bb68c334ab46fe1c9bcc08397796
Author: Patrick Seebauer <patrick.seebuaer@web.de>
Date:   Tue Sep 2 18:47:39 2014 +0200

    rough sketch
2014-09-05 18:36:04 +02:00
Magnar Sveen f3daf86bd6 Merge pull request #157 from lexa/master
Added mc-hide-unmatched-lines-mode
2014-08-05 00:27:52 +02:00
lexa 4b0e91239e Added description of mc-hide-unmached-mode to Readme 2014-08-04 23:45:21 +04:00
lexa bf9e8e95e0 Added testcase for mc-hide-unmatched-lines-mode 2014-08-04 23:45:21 +04:00
lexa 653d52352d Added mc-hide-unmatched-lines mode
This minor mode when enabled hides all lines where no cursors (and
also hum/lines-to-expand below and above) To make use of this mode
press "C-'" while multiple-cursor-mode is active. You can still
edit lines while you are in mc-hide-unmatched-lines mode. To leave
this mode press "<return>" or "C-g"
2014-08-04 23:45:14 +04:00
Magnar Sveen 38d6013d18 Merge pull request #156 from magnars/revert-152-master
Revert "Change file load timing"
2014-08-02 17:28:17 +02:00
Magnar Sveen b3fd49c1d9 Revert "Change file load timing" 2014-08-02 17:27:01 +02:00
Magnar Sveen 98f2346f03 Merge pull request #152 from ShingoFukuyama/master
Change file load timing
2014-07-29 15:04:18 +02:00
Shingo Fukuyama 9f4502b7bc Change file load timing 2014-07-29 10:45:01 +09:00
Magnar Sveen e94567c8e6 Add installation instructions 2014-06-30 19:23:39 +02:00
Magnar Sveen 4da58ea6dd Merge pull request #146 from bling/master
Add company-mode to the list of unsupported minor modes.
2014-05-27 12:59:22 +02:00
Bailey Ling d184f353ef Add company-mode to the list of unsupported minor modes. 2014-05-03 16:38:51 +00:00
Magnar Sveen 084714791b Merge pull request #143 from mjdarby/jedi-mode
Adds jedi-mode to list of unsupported minor modes
2014-04-18 17:15:19 +02:00
Matthew Darby fc39dab1cb Adds jedi-mode to list of unsupported minor modes
jedi-mode is a minor mode implemented by jedi.el, a Python auto-complete
package built on top of Jedi and auto-complete.el. The two primary
features of jedi-mode are:
1) Automatically start autocompletion when the dot key is pressed
2) Activate key bindings for moving to variable and function
definitions.

Neither make much sense in the context of multiple cursors. In fact,
because multiple-cursors disables auto-complete-mode, jedi-mode's
complete-on-dot function will fail to run correctly. The end result is
that typing a dot with multiple cursors active results in only one
cursor producing the dot.

Because of this bug, and that jedi-mode as a whole doesn't make much
sense with multiple cursors, I have added jedi-mode to the list of
unsupported minor modes.
2014-04-18 12:58:06 +01:00
Magnar Sveen da2a9abfd8 Add mc/mark-all-in-region-regexp
Thanks to Gabriel Antonioli :-)
2014-04-16 20:07:26 +02:00
Magnar Sveen a3e6ec7c93 Merge pull request #135 from jistr/gitignore_elc
Gitignore *.elc
2014-02-17 05:03:02 +01:00
Jiří Stránský d1ad51f1a6 Gitignore *.elc
When using this multiple-cursors.el repository as a submodule and
using compilation from .el to .elc, git will report the .elc files as
untracked changes in the submodule. Ignoring *.elc files fixes that.
2014-02-16 22:47:42 +01:00
Magnar Sveen 7b4dd88a69 Merge pull request #129 from jistr/readme_typo
Fix typo in readme
2014-01-08 12:34:32 -08:00
Jiří Stránský f5866d62d9 Fix typo in readme
`mc/pop-mark` should be `mc/mark-pop`.
2014-01-05 13:13:23 +01:00
Magnar Sveen 5cd6ddf788 Merge pull request #125 from kyanagi/fix-cycle-cursors-on-edge
Fix cycle-cursor behavior
2014-01-05 02:59:22 -08:00
Kouhei Yanagita 38e590ce06 Fix cycle-cursor behavior.
mc/cycle-forward had been skipping a cursor on (point-max).
mc/cycle-backward had been skipping a cursor on (point-min).
2014-01-05 14:51:38 +09:00
Kouhei Yanagita 238fb970f9 Add edge case scenarios which test behavior of mc/cycle-forward and mc/cycle-backward 2014-01-05 14:50:00 +09:00
Magnar Sveen 3cfae1dac2 Merge pull request #122 from kyanagi/appropriate-error-messages-when-no-fake-cursors-exist
Show appropriate error messages on trying skipping/unmarking commands with no fake cursors
2014-01-03 03:14:01 -08:00
Kouhei Yanagita 00aea4c9d7 Show appropriate error messages on trying skipping/unmarking commands with no fake cursors 2014-01-03 13:00:13 +09:00
Magnar Sveen 75ece6884b Merge pull request #118 from aspiers/fix-compile-warnings
fix compilation warnings
2013-12-15 10:47:17 -08:00
Adam Spiers aed5d592cf fix compilation warnings (#66)
Fixes #66.
2013-12-15 12:31:31 +00:00
Magnar Sveen 5fead7d83e Update README with @gvol contribution. 2013-11-28 10:54:31 +01:00
Magnar Sveen 2682e48204 Merge pull request #116 from gvol/master
Added mc/edit-lines-empty-lines
2013-11-28 01:49:41 -08:00
Ivan Andrus 2d639b0f45 Added tests for new mc/edit-lines 2013-11-27 17:53:11 -07:00
Ivan Andrus 2b536cb8b6 Added mc/edit-lines-empty-lines
This allows mc/edit-lines to behave differently for short lines

Fixes #27
2013-11-26 23:20:59 -07:00
Magnar Sveen c69be0e672 Travis CI: Update location of cask install 2013-10-31 22:05:27 +01:00
Magnar Sveen 239acbfbc8 Skip folded lines with mc/edit-lines
Fixes #99
2013-10-31 21:38:53 +01:00
Magnar Sveen cfe4bd9eb3 Add python-indent-dedent-line-backspace to run-for-all
- avoid confusion about delete keys
2013-10-16 11:20:41 +02:00
Magnar Sveen 54e408fc68 Update README.md 2013-09-22 11:56:15 +02:00
Magnar Sveen 17c48f972a Merge pull request #111 from mathrick/mark-all-dwim
Add mc/mark-all-dwim to autoloads
2013-09-13 11:48:11 -07:00
Maciej Katafiasz 6467fe251d Add mc/mark-all-dwim to autoloads 2013-09-13 18:29:22 +02:00
20 changed files with 775 additions and 114 deletions
+2 -1
View File
@@ -1 +1,2 @@
elpa elpa
*.elc
+1 -1
View File
@@ -12,7 +12,7 @@ before_install:
sudo apt-get install -qq sudo apt-get install -qq
emacs24 emacs24-el emacs24-common-non-dfsg; emacs24 emacs24-el emacs24-common-non-dfsg;
fi fi
- curl -fsSkL https://raw.github.com/rejeep/cask.el/master/go | sh - curl -fsSkL https://raw.github.com/cask/cask/master/go | python
- export PATH="/home/travis/.cask/bin:$PATH" - export PATH="/home/travis/.cask/bin:$PATH"
- cask - cask
env: env:
+31 -4
View File
@@ -4,6 +4,18 @@ Multiple cursors for Emacs. This is some pretty crazy functionality, so yes,
there are kinks. Don't be afraid tho, 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. great success and much merriment.
## Installation
I highly recommend installing multiple-cursors through `package.el`.
It's available on [melpa](http://melpa.milkbox.net/):
M-x package-install multiple-cursors
The package depends on the `cl-lib` package, so if you do not use
`package.el` or have a recent Emacs, you would need to install that
too: see [GNU ELPA](http://elpa.gnu.org/packages/cl-lib.html).
## Basic usage ## Basic usage
Start out with: Start out with:
@@ -40,6 +52,8 @@ You can [watch an intro to multiple-cursors at Emacs Rocks](http://emacsrocks.co
### Mark one more occurrence ### Mark one more occurrence
- `mc/mark-next-like-this`: Adds a cursor and region at the next part of the buffer forwards that matches the current region. - `mc/mark-next-like-this`: Adds a cursor and region at the next part of the buffer forwards that matches the current region.
- `mc/mark-next-like-this-word`: Adds a cursor and region at the next part of the buffer forwards that matches the current region, if no region is selected it selects the word at the point.
- `mc/mark-next-like-this-symbol`: Adds a cursor and region at the next part of the buffer forwards that matches the current region, if no region is selected it selects the symbol at the point.
- `mc/mark-next-word-like-this`: Like `mc/mark-next-like-this` but only for whole words. - `mc/mark-next-word-like-this`: Like `mc/mark-next-like-this` but only for whole words.
- `mc/mark-next-symbol-like-this`: Like `mc/mark-next-like-this` but only for whole symbols. - `mc/mark-next-symbol-like-this`: Like `mc/mark-next-like-this` but only for whole symbols.
- `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-like-this`: Adds a cursor and region at the next part of the buffer backwards that matches the current region.
@@ -47,7 +61,7 @@ You can [watch an intro to multiple-cursors at Emacs Rocks](http://emacsrocks.co
- `mc/mark-previous-symbol-like-this`: Like `mc/mark-previous-like-this` but only for whole symbols. - `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 occurances. - `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/add-cursor-on-click`: Bind to a mouse event to add cursors by clicking. See tips-section.
- `mc/pop-mark`: 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. - `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.
### Juggle around with the current cursors ### Juggle around with the current cursors
@@ -76,6 +90,7 @@ You can [watch an intro to multiple-cursors at Emacs Rocks](http://emacsrocks.co
- `set-rectangular-region-anchor`: Think of this one as `set-mark` except you're marking a rectangular region. - `set-rectangular-region-anchor`: Think of this one as `set-mark` except you're marking a rectangular region.
- `mc/mark-sgml-tag-pair`: Mark the current opening and closing tag. - `mc/mark-sgml-tag-pair`: Mark the current opening and closing tag.
- `mc/insert-numbers`: Insert increasing numbers for each cursor, top to bottom. - `mc/insert-numbers`: Insert increasing numbers for each cursor, top to bottom.
- `mc/insert-letters`: Insert increasing letters for each cursor, top to bottom.
- `mc/sort-regions`: Sort the marked regions alphabetically. - `mc/sort-regions`: Sort the marked regions alphabetically.
- `mc/reverse-regions`: Reverse the order of the marked regions. - `mc/reverse-regions`: Reverse the order of the marked regions.
@@ -86,11 +101,16 @@ You can [watch an intro to multiple-cursors at Emacs Rocks](http://emacsrocks.co
insert a newline in multiple-cursors-mode, use `C-j`. insert a newline in multiple-cursors-mode, use `C-j`.
- Sometimes you end up with cursors outside of your view. You can - Sometimes you end up with cursors outside of your view. You can
scroll the screen to center on each cursor with `C-v` and `M-v`. scroll the screen to center on each cursor with `C-v` and `M-v` or you can
press `C-'` to hide all lines without a cursor, press `C-'` again to unhide.
- Try pressing `mc/mark-next-like-this` with no region selected. It - Try pressing `mc/mark-next-like-this` with no region selected. It
will just add a cursor on the next line. will just add a cursor on the next line.
- 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 occurance
- Try pressing `mc/mark-all-like-this-dwim` on a tagname in html-mode. - Try pressing `mc/mark-all-like-this-dwim` on a tagname in html-mode.
- Notice that the number of cursors active can be seen in the modeline. - Notice that the number of cursors active can be seen in the modeline.
@@ -102,6 +122,9 @@ You can [watch an intro to multiple-cursors at Emacs Rocks](http://emacsrocks.co
- You can use `mc/reverse-regions` with nothing selected and just one cursor. - You can use `mc/reverse-regions` with nothing selected and just one cursor.
It will then flip the sexp at point and the one below it. It will then flip the sexp at point and the one below it.
- When you use `mc/edit-lines`, you can give it a positive or negative
prefix to change how it behaves on too short lines.
- If you would like to keep the global bindings clean, and get custom keybindings - If you would like to keep the global bindings clean, and get custom keybindings
when the region is active, you can try [region-bindings-mode](https://github.com/fgallina/region-bindings-mode). when the region is active, you can try [region-bindings-mode](https://github.com/fgallina/region-bindings-mode).
@@ -132,6 +155,7 @@ the location with:
(setq mc/list-file "/my/preferred/file") (setq mc/list-file "/my/preferred/file")
NB! Make sure to do so before requiring multiple-cursors.
## Known limitations ## Known limitations
@@ -166,11 +190,14 @@ Run the tests with:
## Contributors ## Contributors
* [Takafumi Arakaki](https://github.com/tkf) has contributed several small improvements * [Takafumi Arakaki](https://github.com/tkf) has contributed several small improvements
* [Marco Baringer](https://github.com/segv) contributed looping to mc/cycle and adding cursors without region for mark-more. * [Marco Baringer](https://github.com/segv) contributed looping to `mc/cycle` and adding cursors without region for mark-more.
* [Ivan Andrus](https://github.com/gvol) added showing number of cursors in mode-line * [Ivan Andrus](https://github.com/gvol) added showing number of cursors in mode-line, and different options for how to handle short lines in `mc/edit-lines`.
* [Fuco](https://github.com/Fuco1) added the first version of `mc/mark-all-like-this-dwim` * [Fuco](https://github.com/Fuco1) added the first version of `mc/mark-all-like-this-dwim`
* [Zach Kost-Smith](https://github.com/smithzvk) added `mc/mark-pop` * [Zach Kost-Smith](https://github.com/smithzvk) added `mc/mark-pop`
* [Maciej Katafiasz](https://github.com/mathrick) added `mc/mark-all-dwim` * [Maciej Katafiasz](https://github.com/mathrick) added `mc/mark-all-dwim`
* [Aleksey Fedotov](https://github.com/lexa) added `mc-hide-unmatched-lines-mode`
* [Jules Tamagnan](https://github.com/jtamagnan) added `mc/mark-next-like-this-word` and `mc/mark-next-like-this-symbol`
* [Ingo Lohmar](https://github.com/ilohmar) extended `mc/add-cursor-on-click` to toggle cursors.
Thanks! Thanks!
+83
View File
@@ -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 go to the front of the word "there"
And I press "C-S-c C-S-c" And I press "C-S-c C-S-c"
Then I should have 2 cursors 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
"""
+73
View File
@@ -0,0 +1,73 @@
Feature: Hiding lines without cursor
Scenario: Hiding lines when three cursor active
Given I have cursors at "line" in :
"""
0
line
2
3
line
5
6
7
8
9
10
11
line
13
14
15
"""
And I press "C-'"
Then I should have 3 cursors
Then I should see exactly:
"""
0
line
2
3
line
5
6
10
11
line
13
14
"""
Scenario: Hiding lines when only two cursor active
When I insert:
"""
1
2
3
4
5
text
6
7
8
9
10
"""
And I go to the front of the word "text"
And I press "C->"
And I press "C-'"
Then I should have 2 cursors
Then I should see exactly:
"""
4
5
text
6
7
8
"""
+25
View File
@@ -0,0 +1,25 @@
Feature: Insert increasing letters
Scenario: Three cursors, a-b-c
Given I have cursors at "text" in "This text contains the word text thrice (text)"
When I press "H-3"
And I press "SPC"
Then I should see "This a text contains the word b text thrice (c text)"
Scenario: Three cursors, j-k-l
Given I have cursors at "text" in "This text contains the word text thrice (text)"
When I press "C-9 H-3"
And I press "SPC"
Then I should see "This j text contains the word k text thrice (l text)"
Scenario: Three cursors, z-aa-ab
Given I have cursors at "text" in "This text contains the word text thrice (text)"
When I press "C-u 2 5 H-3"
And I press "SPC"
Then I should see "This z text contains the word aa text thrice (ab text)"
Scenario: Three cursors, a-b-c
Given I have cursors at "text" in "This text contains the word text thrice (text)"
When I press "C-u H-3"
And I press "SPC"
Then I should see "This e text contains the word f text thrice (g text)"
+6
View File
@@ -11,3 +11,9 @@ Feature: Insert increasing numbers
When I press "C-9 H-0" When I press "C-9 H-0"
And I press "SPC" And I press "SPC"
Then I should see "This 9 text contains the word 10 text thrice (11 text)" Then I should see "This 9 text contains the word 10 text thrice (11 text)"
Scenario: Three cursors, 9-10-11
Given I have cursors at "text" in "This text contains the word text thrice (text)"
When I press "C-u H-0"
And I press "SPC"
Then I should see "This 4 text contains the word 5 text thrice (6 text)"
+14
View File
@@ -166,9 +166,23 @@ Feature: Multiple cursors core
And I press "C-v" And I press "C-v"
Then the cursor should be at point "8" Then the cursor should be at point "8"
Scenario: Looping forwards around cursors including one at point-max
Given I have cursors at "_" in "1_34_67_"
And I press "C-f"
And I press "C-v"
And I press "C-v"
And I press "C-v"
Then the cursor should be at point "3"
Scenario: Looping backwards around cursors Scenario: Looping backwards around cursors
Given I have cursors at "_" in "1_34567_9" Given I have cursors at "_" in "1_34567_9"
And I press "M-v" And I press "M-v"
And I press "M-v" And I press "M-v"
Then the cursor should be at point "2" Then the cursor should be at point "2"
Scenario: Looping backwards around cursors including one at point-min
Given I have cursors at "_" in "_234_67_9"
And I press "M-v"
And I press "M-v"
And I press "M-v"
Then the cursor should be at point "1"
@@ -1,6 +1,14 @@
(require 'cl) ;; For lexical-let
(When "^I mark next like this$" (When "^I mark next like this$"
(lambda () (call-interactively 'mc/mark-next-like-this))) (lambda () (call-interactively 'mc/mark-next-like-this)))
(When "^I mark next like this word$"
(lambda () (call-interactively 'mc/mark-next-like-this-word)))
(When "^I mark next like this symbol$"
(lambda () (call-interactively 'mc/mark-next-like-this-symbol)))
(When "^I mark previous like this$" (When "^I mark previous like this$"
(lambda () (call-interactively 'mc/mark-previous-like-this))) (lambda () (call-interactively 'mc/mark-previous-like-this)))
@@ -16,6 +24,9 @@
(When "^I insert numbers$" (When "^I insert numbers$"
(lambda () (call-interactively 'mc/insert-numbers))) (lambda () (call-interactively 'mc/insert-numbers)))
(When "^I insert letters$"
(lambda () (call-interactively 'mc/insert-letters)))
(When "^I reverse regions$" (When "^I reverse regions$"
(lambda () (call-interactively 'mc/reverse-regions))) (lambda () (call-interactively 'mc/reverse-regions)))
@@ -39,25 +50,25 @@
(Then "^I should have \\([0-9]+\\) cursors$" (Then "^I should have \\([0-9]+\\) cursors$"
(lambda (num) (lambda (num)
(let ((actual (mc/num-cursors))) (let ((actual (mc/num-cursors)))
(assert (eq (string-to-number num) actual) nil (cl-assert (eq (string-to-number num) actual) nil
"Expected to have %s cursors, but was %d." num actual)))) "Expected to have %s cursors, but was %d." num actual))))
(Then "^I should have one cursor$" (Then "^I should have one cursor$"
(lambda () (lambda ()
(assert (not multiple-cursors-mode) nil (cl-assert (not multiple-cursors-mode) nil
"Expected to have one cursor, but multiple-cursors-mode is still active.") "Expected to have one cursor, but multiple-cursors-mode is still active.")
(assert (eq 1 (mc/num-cursors)) nil (cl-assert (eq 1 (mc/num-cursors)) nil
"Expected to have one cursor, but there are still fake cursor overlays."))) "Expected to have one cursor, but there are still fake cursor overlays.")))
(Then "^rectangular-region-mode should be off$" (Then "^rectangular-region-mode should be off$"
(lambda () (lambda ()
(assert (not rectangular-region-mode) nil (cl-assert (not rectangular-region-mode) nil
"Expected rectangular-region-mode mode to be off, but wasn't."))) "Expected rectangular-region-mode mode to be off, but wasn't.")))
(Then "^rectangular-region-mode should be on$" (Then "^rectangular-region-mode should be on$"
(lambda () (lambda ()
(assert rectangular-region-mode nil (cl-assert rectangular-region-mode nil
"Expected rectangular-region-mode mode to be on, but wasn't."))) "Expected rectangular-region-mode mode to be on, but wasn't.")))
(When "^I press \"\\(.+\\)\"$" (When "^I press \"\\(.+\\)\"$"
(lambda (keybinding) (lambda (keybinding)
@@ -79,6 +90,17 @@
(mc/mark-all-like-this) (mc/mark-all-like-this)
(mc/keyboard-quit))) (mc/keyboard-quit)))
(Given "^I have cursors at \"\\(.+\\)\" in \\(?: \"\\(.+\\)\"\\|:\\)$"
(lambda (needle haystack)
(insert haystack)
(goto-char (point-min))
(search-forward needle)
(set-mark (point))
(goto-char (match-beginning 0))
(mc/mark-all-like-this)
(mc/keyboard-quit)))
(When "^I copy \"\\(.+\\)\" in another program$" (When "^I copy \"\\(.+\\)\" in another program$"
(lambda (text) (lambda (text)
(lexical-let ((text text)) (lexical-let ((text text))
@@ -112,21 +134,21 @@
(goto-char (point-min)) (goto-char (point-min))
(let ((search (re-search-forward (format "%s" char) nil t)) (let ((search (re-search-forward (format "%s" char) nil t))
(message "Can not go to character '%s' since it does not exist in the current buffer: %s")) (message "Can not go to character '%s' since it does not exist in the current buffer: %s"))
(assert search nil message char (espuds-buffer-contents))))) (cl-assert search nil message char (espuds-buffer-contents)))))
(When "^I go to the \\(front\\|end\\) of the word \"\\(.+\\)\"$" (When "^I go to the \\(front\\|end\\) of the word \"\\(.+\\)\"$"
(lambda (pos word) (lambda (pos word)
(goto-char (point-min)) (goto-char (point-min))
(let ((search (re-search-forward (format "%s" word) nil t)) (let ((search (re-search-forward (format "%s" word) nil t))
(message "Can not go to character '%s' since it does not exist in the current buffer: %s")) (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)) (cl-assert search nil message word (espuds-buffer-contents))
(if (string-equal "front" pos) (backward-word))))) (if (string-equal "front" pos) (backward-word)))))
(When "^I select the last \"\\(.+\\)\"$" (When "^I select the last \"\\(.+\\)\"$"
(lambda (text) (lambda (text)
(goto-char (point-max)) (goto-char (point-max))
(let ((search (re-search-backward text nil t))) (let ((search (re-search-backward text nil t)))
(assert search nil "The text '%s' was not found in the current buffer." text)) (cl-assert search nil "The text '%s' was not found in the current buffer." text))
(set-mark (point)) (set-mark (point))
(re-search-forward text))) (re-search-forward text)))
@@ -137,3 +159,24 @@
(split-string rest)) (split-string rest))
"-")))) "-"))))
(call-interactively func)))) (call-interactively func))))
(Then "^I should see exactly\\(?: \"\\(.+\\)\"\\|:\\)$"
"Asserts that the current buffer does not include some text with
respect of text hidden by overlays"
(lambda (expected)
(let ((p (point-min))
(visible-text "")
(message "Expected '%s' to be part of '%s', but was not found in current buffer.")
)
(while (not (= p (point-max)))
(if (not (invisible-p p))
(setq visible-text (concat visible-text (buffer-substring p (1+ p))))
)
(setq p (1+ p))
)
(cl-assert (s-equals? expected visible-text) nil message expected visible-text))))
;; Local Variables:
;; byte-compile-warnings: (not cl-functions)
;; End:
+3
View File
@@ -21,12 +21,15 @@
(multiple-cursors-mode 0) (multiple-cursors-mode 0)
(rectangular-region-mode 0) (rectangular-region-mode 0)
(global-set-key (kbd "C->") 'mc/mark-next-like-this) (global-set-key (kbd "C->") 'mc/mark-next-like-this)
(global-set-key (kbd "C-S-c C->") 'mc/mark-next-like-this-word)
(global-set-key (kbd "C-S-c M->") 'mc/mark-next-like-this-symbol)
(global-set-key (kbd "C-<") 'mc/mark-previous-like-this) (global-set-key (kbd "C-<") 'mc/mark-previous-like-this)
(global-set-key (kbd "M-!") 'mc/mark-all-like-this) (global-set-key (kbd "M-!") 'mc/mark-all-like-this)
(global-set-key (kbd "M-$") 'mc/mark-all-like-this-dwim) (global-set-key (kbd "M-$") 'mc/mark-all-like-this-dwim)
(global-set-key (kbd "C-$") 'mc/mark-all-dwim) (global-set-key (kbd "C-$") 'mc/mark-all-dwim)
(global-set-key (kbd "M-#") 'mc/mark-all-in-region) (global-set-key (kbd "M-#") 'mc/mark-all-in-region)
(global-set-key (kbd "H-0") 'mc/insert-numbers) (global-set-key (kbd "H-0") 'mc/insert-numbers)
(global-set-key (kbd "H-3") 'mc/insert-letters)
(global-set-key (kbd "H-1") 'mc/reverse-regions) (global-set-key (kbd "H-1") 'mc/reverse-regions)
(global-set-key (kbd "H-2") 'mc/sort-regions) (global-set-key (kbd "H-2") 'mc/sort-regions)
(global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines) (global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines)
+27
View File
@@ -0,0 +1,27 @@
Feature: Align cursors with whitespaces
Scenario: Vertical aligning with `x'
Given I have cursors at "word" in :
"""
One word
Another word
"""
And I press "<<mc/vertical-align>> \170"
Then I should see:
"""
One xxxxword
Another word
"""
Scenario: Vertical aligning with space
Given I have cursors at "word" in :
"""
One word
Another word
"""
And I press "<<mc/vertical-align-with-space>>"
Then I should see:
"""
One word
Another word
"""
+14 -17
View File
@@ -28,11 +28,9 @@
(require 'multiple-cursors-core) (require 'multiple-cursors-core)
(eval-when-compile (require 'cl))
(defun mc/next-fake-cursor-after-point () (defun mc/next-fake-cursor-after-point ()
(let ((pos (point)) (let ((pos (point))
(next-pos (point-max)) (next-pos (1+ (point-max)))
next) next)
(mc/for-each-fake-cursor (mc/for-each-fake-cursor
(let ((cursor-pos (overlay-get cursor 'point))) (let ((cursor-pos (overlay-get cursor 'point)))
@@ -44,7 +42,7 @@
(defun mc/prev-fake-cursor-before-point () (defun mc/prev-fake-cursor-before-point ()
(let ((pos (point)) (let ((pos (point))
(prev-pos (point-min)) (prev-pos (1- (point-min)))
prev) prev)
(mc/for-each-fake-cursor (mc/for-each-fake-cursor
(let ((cursor-pos (overlay-get cursor 'point))) (let ((cursor-pos (overlay-get cursor 'point)))
@@ -63,7 +61,7 @@
:group 'multiple-cursors) :group 'multiple-cursors)
(defun mc/handle-loop-condition (error-message) (defun mc/handle-loop-condition (error-message)
(ecase mc/cycle-looping-behaviour (cl-ecase mc/cycle-looping-behaviour
(error (error error-message)) (error (error error-message))
(warn (message error-message)) (warn (message error-message))
(continue 'continue) (continue 'continue)
@@ -72,22 +70,22 @@
(defun mc/first-fake-cursor-after (point) (defun mc/first-fake-cursor-after (point)
"Very similar to mc/furthest-cursor-before-point, but ignores (mark) and (point)." "Very similar to mc/furthest-cursor-before-point, but ignores (mark) and (point)."
(let* ((cursors (mc/all-fake-cursors)) (let* ((cursors (mc/all-fake-cursors))
(cursors-after-point (remove-if (lambda (cursor) (cursors-after-point (cl-remove-if (lambda (cursor)
(< (mc/cursor-beg cursor) point)) (< (mc/cursor-beg cursor) point))
cursors)) cursors))
(cursors-in-order (sort* cursors-after-point '< :key 'mc/cursor-beg))) (cursors-in-order (cl-sort cursors-after-point '< :key 'mc/cursor-beg)))
(first cursors-in-order))) (car cursors-in-order)))
(defun mc/last-fake-cursor-before (point) (defun mc/last-fake-cursor-before (point)
"Very similar to mc/furthest-cursor-before-point, but ignores (mark) and (point)." "Very similar to mc/furthest-cursor-before-point, but ignores (mark) and (point)."
(let* ((cursors (mc/all-fake-cursors)) (let* ((cursors (mc/all-fake-cursors))
(cursors-before-point (remove-if (lambda (cursor) (cursors-before-point (cl-remove-if (lambda (cursor)
(> (mc/cursor-end cursor) point)) (> (mc/cursor-end cursor) point))
cursors)) cursors))
(cursors-in-order (sort* cursors-before-point '> :key 'mc/cursor-end))) (cursors-in-order (cl-sort cursors-before-point '> :key 'mc/cursor-end)))
(first cursors-in-order))) (car cursors-in-order)))
(defun* mc/cycle (next-cursor fallback-cursor loop-message) (cl-defun mc/cycle (next-cursor fallback-cursor loop-message)
(when (null next-cursor) (when (null next-cursor)
(when (eql 'stop (mc/handle-loop-condition loop-message)) (when (eql 'stop (mc/handle-loop-condition loop-message))
(return-from mc/cycle nil)) (return-from mc/cycle nil))
@@ -116,7 +114,6 @@
;; Local Variables: ;; Local Variables:
;; coding: utf-8 ;; coding: utf-8
;; byte-compile-warnings: (not cl-functions)
;; End: ;; End:
;;; mc-cycle-cursors.el ends here ;;; mc-cycle-cursors.el ends here
+47 -8
View File
@@ -29,26 +29,65 @@
(require 'multiple-cursors-core) (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 ;;;###autoload
(defun mc/edit-lines () (defun mc/edit-lines (&optional arg)
"Add one cursor to each line of the active region. "Add one cursor to each line of the active region.
Starts from mark and moves in straight down or up towards the Starts from mark and moves in straight down or up towards the
line point is on." line point is on.
(interactive)
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)))) (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) (mc/remove-fake-cursors)
(let* ((col (current-column)) (let* ((col (current-column))
(point-line (line-number-at-pos)) (point-line (line-number-at-pos))
(mark-line (progn (exchange-point-and-mark) (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) (deactivate-mark)
(when (and (eq direction :up) (bolp)) (when (and (eq direction :up) (bolp))
(forward-line -1) (previous-logical-line 1 nil)
(move-to-column col)) (move-to-column col))
;; Add the cursors
(while (not (eq (line-number-at-pos) point-line)) (while (not (eq (line-number-at-pos) point-line))
(mc/create-fake-cursor-at-point) ;; Pad the line
(if (eq direction :up) (forward-line -1) (forward-line 1)) (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))
(move-to-column col)) (move-to-column col))
(multiple-cursors-mode))) (multiple-cursors-mode)))
+107
View File
@@ -0,0 +1,107 @@
;;; mc-hide-unmatched-lines.el
;; Copyright (C) 2014 Aleksey Fedotov
;; Author: Aleksey Fedotov <lexa@cfotr.com>
;; Keywords: editing cursors
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; This minor mode when enabled hides all lines where no cursors (and
;; also hum/lines-to-expand below and above) To make use of this mode
;; press "C-'" while multiple-cursor-mode is active. You can still
;; edit lines while you are in mc-hide-unmatched-lines mode. To leave
;; this mode press "<return>" or "C-g"
;;
;;; Code:
(require 'multiple-cursors-core)
(require 'mc-mark-more)
(defvar hum/hide-unmatched-lines-mode-map (make-sparse-keymap)
"Keymap for hide unmatched lines is mainly for rebinding C-g")
(define-key hum/hide-unmatched-lines-mode-map (kbd "C-g") 'hum/keyboard-quit)
(define-key hum/hide-unmatched-lines-mode-map (kbd "<return>") 'hum/keyboard-quit)
(defun hum/keyboard-quit ()
"Leave hide-unmatched-lines mode"
(interactive)
(mc-hide-unmatched-lines-mode 0))
;; used only in in multiple-cursors-mode-disabled-hook
(defun hum/disable-hum-mode ()
(mc-hide-unmatched-lines-mode 0))
;;;###autoload
(define-minor-mode mc-hide-unmatched-lines-mode
"Minor mode when enabled hides all lines where no cursors (and
also hum/lines-to-expand below and above) To make use of this
mode press \"C-'\" while multiple-cursor-mode is active. You can
still edit lines while you are in mc-hide-unmatched-lines
mode. To leave this mode press <return> or \"C-g\""
nil " hu"
hum/hide-unmatched-lines-mode-map
(if mc-hide-unmatched-lines-mode
;;just in case if mc mode will be disabled while hide-unmatched-lines is active
(progn
(hum/hide-unmatched-lines)
(add-hook 'multiple-cursors-mode-disabled-hook 'hum/disable-hum-mode t t))
(progn
(hum/unhide-unmatched-lines)
(remove-hook 'multiple-cursors-mode-disabled-hook 'hum/disable-hum-mode))))
(defconst hum/invisible-overlay-name 'hum/invisible-overlay-name)
(defcustom hum/lines-to-expand 2
"How many lines below and above cursor to show"
:type '(integer)
:group 'multiple-cursors)
(defcustom hum/placeholder "..."
"Placeholder which will be placed insted of hiden text"
:type '(string)
:group 'multiple-cursors)
(defun hum/add-invisible-overlay (begin end)
(let ((overlay (make-overlay begin
end
(current-buffer)
t
nil
)))
(overlay-put overlay hum/invisible-overlay-name t)
(overlay-put overlay 'invisible t)
(overlay-put overlay 'intangible t)
(overlay-put overlay 'evaporate t)
(overlay-put overlay 'after-string hum/placeholder)))
(defun hum/hide-unmatched-lines ()
(let ((begin (point-min)))
(mc/for-each-cursor-ordered
(save-excursion
(goto-char (mc/cursor-beg cursor))
(if (< begin (line-beginning-position (- hum/lines-to-expand)))
(hum/add-invisible-overlay begin (line-end-position (- hum/lines-to-expand))))
(setq begin (line-beginning-position (+ 2 hum/lines-to-expand)))))
(hum/add-invisible-overlay begin (point-max))))
(defun hum/unhide-unmatched-lines ()
(remove-overlays nil nil hum/invisible-overlay-name t))
(provide 'mc-hide-unmatched-lines-mode)
(define-key mc/keymap (kbd "C-'") 'mc-hide-unmatched-lines-mode)
+149 -46
View File
@@ -55,8 +55,8 @@
beg)) beg))
(defun mc/furthest-cursor-before-point () (defun mc/furthest-cursor-before-point ()
(let ((beg (min (mark) (point))) (let ((beg (if mark-active (min (mark) (point)) (point)))
furthest) furthest)
(mc/for-each-fake-cursor (mc/for-each-fake-cursor
(when (< (mc/cursor-beg cursor) beg) (when (< (mc/cursor-beg cursor) beg)
(setq beg (mc/cursor-beg cursor)) (setq beg (mc/cursor-beg cursor))
@@ -64,14 +64,26 @@
furthest)) furthest))
(defun mc/furthest-cursor-after-point () (defun mc/furthest-cursor-after-point ()
(let ((end (max (mark) (point))) (let ((end (if mark-active (max (mark) (point)) (point)))
furthest) furthest)
(mc/for-each-fake-cursor (mc/for-each-fake-cursor
(when (> (mc/cursor-end cursor) end) (when (> (mc/cursor-end cursor) end)
(setq end (mc/cursor-end cursor)) (setq end (mc/cursor-end cursor))
(setq furthest cursor))) (setq furthest cursor)))
furthest)) furthest))
(defun mc/fake-cursor-at-point (&optional point)
"Return the fake cursor with its point right at POINT (defaults
to (point)), or nil."
(setq point (or point (point)))
(let ((cursors (mc/all-fake-cursors))
(c nil))
(catch 'found
(while (setq c (pop cursors))
(when (eq (marker-position (overlay-get c 'point))
point)
(throw 'found c))))))
(defun mc/region-strings () (defun mc/region-strings ()
(let ((strings (list (buffer-substring-no-properties (point) (mark))))) (let ((strings (list (buffer-substring-no-properties (point) (mark)))))
(mc/for-each-fake-cursor (mc/for-each-fake-cursor
@@ -92,46 +104,88 @@ Use like case-fold-search, don't recommend setting it globally.")
(defun mc/mark-more-like-this (skip-last direction) (defun mc/mark-more-like-this (skip-last direction)
(let ((case-fold-search nil) (let ((case-fold-search nil)
(re (regexp-opt (mc/region-strings) mc/enclose-search-term)) (re (regexp-opt (mc/region-strings) mc/enclose-search-term))
(point-out-of-order (ecase direction (point-out-of-order (cl-ecase direction
(forwards (< (point) (mark))) (forwards (< (point) (mark)))
(backwards (not (< (point) (mark)))))) (backwards (not (< (point) (mark))))))
(furthest-cursor (ecase direction (furthest-cursor (cl-ecase direction
(forwards (mc/furthest-cursor-after-point)) (forwards (mc/furthest-cursor-after-point))
(backwards (mc/furthest-cursor-before-point)))) (backwards (mc/furthest-cursor-before-point))))
(start-char (ecase direction (start-char (cl-ecase direction
(forwards (mc/furthest-region-end)) (forwards (mc/furthest-region-end))
(backwards (mc/first-region-start)))) (backwards (mc/first-region-start))))
(search-function (ecase direction (search-function (cl-ecase direction
(forwards 'search-forward-regexp) (forwards 'search-forward-regexp)
(backwards 'search-backward-regexp))) (backwards 'search-backward-regexp)))
(match-point-getter (ecase direction (match-point-getter (cl-ecase direction
(forwards 'match-beginning) (forwards 'match-beginning)
(backwards 'match-end)))) (backwards 'match-end))))
(mc/save-excursion (if (and skip-last (not furthest-cursor))
(goto-char start-char) (error "No cursors to be skipped")
(when skip-last (mc/save-excursion
(mc/remove-fake-cursor furthest-cursor)) (goto-char start-char)
(if (funcall search-function re nil t) (when skip-last
(progn (mc/remove-fake-cursor furthest-cursor))
(push-mark (funcall match-point-getter 0)) (if (funcall search-function re nil t)
(when point-out-of-order (progn
(exchange-point-and-mark)) (push-mark (funcall match-point-getter 0))
(mc/create-fake-cursor-at-point)) (when point-out-of-order
(error "no more matches found."))))) (exchange-point-and-mark))
(mc/create-fake-cursor-at-point))
(error "no more matches found."))))))
;;;###autoload ;;;###autoload
(defun mc/mark-next-like-this (arg) (defun mc/mark-next-like-this (arg)
"Find and mark the next part of the buffer matching the currently active region "Find and mark the next part of the buffer matching the currently active region
If no region is active add a cursor on the next line
With negative ARG, delete the last one instead. With negative ARG, delete the last one instead.
With zero ARG, skip the last one and mark next." With zero ARG, skip the last one and mark next."
(interactive "p") (interactive "p")
(if (region-active-p) (if (< arg 0)
(if (< arg 0) (let ((cursor (mc/furthest-cursor-after-point)))
(mc/remove-fake-cursor (mc/furthest-cursor-after-point)) (if cursor
(mc/mark-more-like-this (= arg 0) 'forwards)) (mc/remove-fake-cursor cursor)
(mc/mark-lines arg 'forwards)) (error "No cursors to be unmarked")))
(if (region-active-p)
(mc/mark-more-like-this (= arg 0) 'forwards)
(mc/mark-lines arg 'forwards)))
(mc/maybe-multiple-cursors-mode)) (mc/maybe-multiple-cursors-mode))
;;;###autoload
(defun mc/mark-next-like-this-word (arg)
"Find and mark the next part of the buffer matching the currently active region
If no region is active, mark the word 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")
(if (< arg 0)
(let ((cursor (mc/furthest-cursor-after-point)))
(if cursor
(mc/remove-fake-cursor cursor)
(error "No cursors to be unmarked")))
(if (region-active-p)
(mc/mark-more-like-this (= arg 0) 'forwards)
(mc--select-thing-at-point 'word)
(mc/mark-more-like-this (= arg 0) 'forwards)))
(mc/maybe-multiple-cursors-mode))
(defun mc/mark-next-like-this-symbol (arg)
"Find and mark the next part of the buffer matching the currently active region
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")
(if (< arg 0)
(let ((cursor (mc/furthest-cursor-after-point)))
(if cursor
(mc/remove-fake-cursor cursor)
(error "No cursors to be unmarked")))
(if (region-active-p)
(mc/mark-more-like-this (= arg 0) 'forwards)
(mc--select-thing-at-point 'symbol)
(mc/mark-more-like-this (= arg 0) 'forwards)))
(mc/maybe-multiple-cursors-mode))
;;;###autoload ;;;###autoload
(defun mc/mark-next-word-like-this (arg) (defun mc/mark-next-word-like-this (arg)
(interactive "p") (interactive "p")
@@ -150,11 +204,14 @@ With zero ARG, skip the last one and mark next."
With negative ARG, delete the last one instead. With negative ARG, delete the last one instead.
With zero ARG, skip the last one and mark next." With zero ARG, skip the last one and mark next."
(interactive "p") (interactive "p")
(if (region-active-p) (if (< arg 0)
(if (< arg 0) (let ((cursor (mc/furthest-cursor-before-point)))
(mc/remove-fake-cursor (mc/furthest-cursor-before-point)) (if cursor
(mc/mark-more-like-this (= arg 0) 'backwards)) (mc/remove-fake-cursor cursor)
(mc/mark-lines arg 'backwards)) (error "No cursors to be unmarked")))
(if (region-active-p)
(mc/mark-more-like-this (= arg 0) 'backwards)
(mc/mark-lines arg 'backwards)))
(mc/maybe-multiple-cursors-mode)) (mc/maybe-multiple-cursors-mode))
;;;###autoload ;;;###autoload
@@ -170,13 +227,19 @@ With zero ARG, skip the last one and mark next."
(mc/mark-previous-like-this arg))) (mc/mark-previous-like-this arg)))
(defun mc/mark-lines (num-lines direction) (defun mc/mark-lines (num-lines direction)
(dotimes (i num-lines) (dotimes (i (if (= num-lines 0) 1 num-lines))
(mc/create-fake-cursor-at-point) (mc/save-excursion
(ecase direction (let ((furthest-cursor (cl-ecase direction
(forwards (loop do (next-logical-line 1 nil) (forwards (mc/furthest-cursor-after-point))
while (mc/all-fake-cursors (point) (1+ (point))))) (backwards (mc/furthest-cursor-before-point)))))
(backwards (loop do (previous-logical-line 1 nil) (when (overlayp furthest-cursor)
while (mc/all-fake-cursors (point) (1+ (point)))))))) (goto-char (overlay-get furthest-cursor 'point))
(when (= num-lines 0)
(mc/remove-fake-cursor furthest-cursor))))
(cl-ecase direction
(forwards (next-logical-line 1 nil))
(backwards (previous-logical-line 1 nil)))
(mc/create-fake-cursor-at-point))))
;;;###autoload ;;;###autoload
(defun mc/mark-next-lines (arg) (defun mc/mark-next-lines (arg)
@@ -263,10 +326,10 @@ With zero ARG, skip the last one and mark next."
(mc/mark-all-like-this))) (mc/mark-all-like-this)))
;;;###autoload ;;;###autoload
(defun mc/mark-all-in-region (beg end) (defun mc/mark-all-in-region (beg end &optional search)
"Find and mark all the parts in the region matching the given search" "Find and mark all the parts in the region matching the given search"
(interactive "r") (interactive "r")
(let ((search (read-from-minibuffer "Mark all in region: ")) (let ((search (or search (read-from-minibuffer "Mark all in region: ")))
(case-fold-search nil)) (case-fold-search nil))
(if (string= search "") (if (string= search "")
(message "Mark aborted") (message "Mark aborted")
@@ -284,6 +347,36 @@ With zero ARG, skip the last one and mark next."
(multiple-cursors-mode 1) (multiple-cursors-mode 1)
(multiple-cursors-mode 0)))))) (multiple-cursors-mode 0))))))
;;;###autoload
(defun mc/mark-all-in-region-regexp (beg end)
"Find and mark all the parts in the region matching the given regexp."
(interactive "r")
(let ((search (read-regexp "Mark regexp in region: "))
(case-fold-search nil))
(if (string= search "")
(message "Mark aborted")
(progn
(mc/remove-fake-cursors)
(goto-char beg)
(let ((lastmatch))
(while (and (< (point) end) ; can happen because of (forward-char)
(search-forward-regexp search end t))
(push-mark (match-beginning 0))
(mc/create-fake-cursor-at-point)
(setq lastmatch (point))
(when (= (point) (match-beginning 0))
(forward-char)))
(when lastmatch (goto-char lastmatch)))
(when (> (mc/num-cursors) 0)
(goto-char (match-end 0)))
(let ((first (mc/furthest-cursor-before-point)))
(if (not first)
(error "Search failed for %S" search)
(mc/pop-state-from-overlay first)))
(if (> (mc/num-cursors) 1)
(multiple-cursors-mode 1)
(multiple-cursors-mode 0))))))
(when (not (fboundp 'set-temporary-overlay-map)) (when (not (fboundp 'set-temporary-overlay-map))
;; Backport this function from newer emacs versions ;; Backport this function from newer emacs versions
(defun set-temporary-overlay-map (map &optional keep-pred) (defun set-temporary-overlay-map (map &optional keep-pred)
@@ -419,6 +512,7 @@ With prefix, it behaves the same as original `mc/mark-all-like-this'"
(when (<= (mc/num-cursors) before) (when (<= (mc/num-cursors) before)
(mc/mark-all-like-this)))))) (mc/mark-all-like-this))))))
;;;###autoload
(defun mc/mark-all-dwim (arg) (defun mc/mark-all-dwim (arg)
"Tries even harder to guess what you want to mark all of. "Tries even harder to guess what you want to mark all of.
@@ -426,7 +520,7 @@ If the region is active and spans multiple lines, it will behave
as if `mc/mark-all-in-region'. With the prefix ARG, it will call as if `mc/mark-all-in-region'. With the prefix ARG, it will call
`mc/edit-lines' instead. `mc/edit-lines' instead.
If the region is inactive or on a single line, it will behave like If the region is inactive or on a single line, it will behave like
`mc/mark-all-like-this-dwim'." `mc/mark-all-like-this-dwim'."
(interactive "P") (interactive "P")
(if (and (use-region-p) (if (and (use-region-p)
@@ -504,8 +598,9 @@ If the region is inactive or on a single line, it will behave like
(<= (point) end)))) (<= (point) end))))
;;;###autoload ;;;###autoload
(defun mc/add-cursor-on-click (event) (defun mc/toggle-cursor-on-click (event)
"Add a cursor where you click." "Add a cursor where you click, or remove a fake cursor that is
already there."
(interactive "e") (interactive "e")
(mouse-minibuffer-check event) (mouse-minibuffer-check event)
;; Use event-end in case called from mouse-drag-region. ;; Use event-end in case called from mouse-drag-region.
@@ -514,12 +609,20 @@ If the region is inactive or on a single line, it will behave like
(if (not (windowp (posn-window position))) (if (not (windowp (posn-window position)))
(error "Position not in text area of window")) (error "Position not in text area of window"))
(select-window (posn-window position)) (select-window (posn-window position))
(if (numberp (posn-point position)) (let ((pt (posn-point position)))
(save-excursion (if (numberp pt)
(goto-char (posn-point position)) ;; is there a fake cursor with the actual *point* right where we are?
(mc/create-fake-cursor-at-point))) (let ((existing (mc/fake-cursor-at-point pt)))
(if existing
(mc/remove-fake-cursor existing)
(save-excursion
(goto-char pt)
(mc/create-fake-cursor-at-point))))))
(mc/maybe-multiple-cursors-mode))) (mc/maybe-multiple-cursors-mode)))
;;;###autoload
(defalias 'mc/add-cursor-on-click 'mc/toggle-cursor-on-click)
;;;###autoload ;;;###autoload
(defun mc/mark-sgml-tag-pair () (defun mc/mark-sgml-tag-pair ()
"Mark the tag we're in and its pair for renaming." "Mark the tag we're in and its pair for renaming."
+59 -1
View File
@@ -33,7 +33,8 @@
(defun mc/insert-numbers (arg) (defun mc/insert-numbers (arg)
"Insert increasing numbers for each cursor, starting at 0 or ARG." "Insert increasing numbers for each cursor, starting at 0 or ARG."
(interactive "P") (interactive "P")
(setq mc--insert-numbers-number (or arg 0)) (setq mc--insert-numbers-number (or (and arg (prefix-numeric-value arg))
0))
(mc/for-each-cursor-ordered (mc/for-each-cursor-ordered
(mc/execute-command-for-fake-cursor 'mc--insert-number-and-increase cursor))) (mc/execute-command-for-fake-cursor 'mc--insert-number-and-increase cursor)))
@@ -53,6 +54,32 @@
(mc/cursor-end cursor)) strings)))) (mc/cursor-end cursor)) strings))))
(nreverse strings))) (nreverse strings)))
;;;###autoload
(defun mc/insert-letters (arg)
"Insert increasing letters for each cursor, starting at 0 or ARG.
Where letter[0]=a letter[2]=c letter[26]=aa"
(interactive "P")
(setq mc--insert-letters-number (or (and arg (prefix-numeric-value arg))
0))
(mc/for-each-cursor-ordered
(mc/execute-command-for-fake-cursor 'mc--insert-letter-and-increase cursor)))
(defun mc--number-to-letters (number)
(let ((letter
(char-to-string
(+ (mod number 26) ?a)))
(number2 (/ number 26)))
(if (> number2 0)
(concat (mc--number-to-letters (- number2 1)) letter)
letter)))
(defvar mc--insert-letters-number 0)
(defun mc--insert-letter-and-increase ()
(interactive)
(insert (mc--number-to-letters mc--insert-letters-number))
(setq mc--insert-letters-number (1+ mc--insert-letters-number)))
(defvar mc--strings-to-replace nil) (defvar mc--strings-to-replace nil)
(defun mc--replace-region-strings-1 () (defun mc--replace-region-strings-1 ()
@@ -86,5 +113,36 @@
(setq mc--strings-to-replace (sort (mc--ordered-region-strings) 'string<)) (setq mc--strings-to-replace (sort (mc--ordered-region-strings) 'string<))
(mc--replace-region-strings)) (mc--replace-region-strings))
;;;###autoload
(defun mc/vertical-align (character)
"Aligns all cursors vertically with a given CHARACTER to the one with the
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)))
(mc/execute-command-for-all-cursors
(lambda () "get the rightest cursor"
(interactive)
(setq rightest-column (max (current-column) rightest-column))
))
(mc/execute-command-for-all-cursors
(lambda ()
(interactive)
(let ((missing-spaces (- rightest-column (current-column))))
(save-excursion (insert (make-string missing-spaces character)))
(forward-char missing-spaces)
)
))
)
)
;;;###autoload
(defun mc/vertical-align-with-space ()
"Aligns all cursors with whitespace like `mc/vertical-align' does"
(interactive)
(mc/vertical-align 32)
)
(provide 'mc-separate-operations) (provide 'mc-separate-operations)
;;; mc-separate-operations.el ends here ;;; mc-separate-operations.el ends here
+62 -19
View File
@@ -25,10 +25,11 @@
;;; Code: ;;; Code:
(require 'cl) (require 'cl-lib)
(require 'rect) (require 'rect)
(defvar mc--read-char)
(defface mc/cursor-face (defface mc/cursor-face
'((t (:inverse-video t))) '((t (:inverse-video t)))
"The face used for fake cursors" "The face used for fake cursors"
@@ -51,9 +52,9 @@
(cons (cons 'apply (cons 'activate-cursor-for-undo (list id))) buffer-undo-list)))))) (cons (cons 'apply (cons 'activate-cursor-for-undo (list id))) buffer-undo-list))))))
(defun mc/all-fake-cursors (&optional start end) (defun mc/all-fake-cursors (&optional start end)
(remove-if-not 'mc/fake-cursor-p (cl-remove-if-not 'mc/fake-cursor-p
(overlays-in (or start (point-min)) (overlays-in (or start (point-min))
(or end (point-max))))) (or end (point-max)))))
(defmacro mc/for-each-fake-cursor (&rest forms) (defmacro mc/for-each-fake-cursor (&rest forms)
"Runs the body for each fake cursor, bound to the name cursor" "Runs the body for each fake cursor, bound to the name cursor"
@@ -130,7 +131,6 @@ highlights the entire width of the window."
mark-ring mark-ring
mark-active mark-active
yank-undo-function yank-undo-function
kill-ring-yank-pointer
autopair-action autopair-action
autopair-wrap-action autopair-wrap-action
er/history) er/history)
@@ -173,11 +173,39 @@ highlights the entire width of the window."
(defun mc/create-cursor-id () (defun mc/create-cursor-id ()
"Returns a unique cursor id" "Returns a unique cursor id"
(incf mc--current-cursor-id)) (cl-incf mc--current-cursor-id))
(defvar mc--max-cursors-original nil
"This variable maintains the original maximum number of cursors.
When `mc/create-fake-cursor-at-point' is called and
`mc/max-cursors' is overridden, this value serves as a backup so
that `mc/max-cursors' can take on a new value. When
`mc/remove-fake-cursors' is called, the values are reset.")
(defcustom mc/max-cursors nil
"Safety ceiling for the number of active cursors.
If your emacs slows down or freezes when using too many cursors,
customize this value appropriately.
Cursors will be added until this value is reached, at which point
you can either temporarily override the value or abort the
operation entirely.
If this value is nil, there is no ceiling."
:type '(integer)
:group 'multiple-cursors)
(defun mc/create-fake-cursor-at-point (&optional id) (defun mc/create-fake-cursor-at-point (&optional id)
"Add a fake cursor and possibly a fake active region overlay based on point and mark. "Add a fake cursor and possibly a fake active region overlay based on point and mark.
Saves the current state in the overlay to be restored later." Saves the current state in the overlay to be restored later."
(unless mc--max-cursors-original
(setq mc--max-cursors-original mc/max-cursors))
(when mc/max-cursors
(unless (< (mc/num-cursors) mc/max-cursors)
(if (yes-or-no-p (format "%d active cursors. Continue? " (mc/num-cursors)))
(setq mc/max-cursors (read-number "Enter a new, temporary maximum: "))
(mc/remove-fake-cursors)
(error "Aborted: too many cursors"))))
(let ((overlay (mc/make-cursor-overlay-at-point))) (let ((overlay (mc/make-cursor-overlay-at-point)))
(overlay-put overlay 'mc-id (or id (mc/create-cursor-id))) (overlay-put overlay 'mc-id (or id (mc/create-cursor-id)))
(overlay-put overlay 'type 'fake-cursor) (overlay-put overlay 'type 'fake-cursor)
@@ -231,6 +259,8 @@ cursor with updated info."
;; Intercept some reading commands so you won't have to ;; Intercept some reading commands so you won't have to
;; answer them for every single cursor ;; answer them for every single cursor
(defvar mc--read-char nil)
(defvar multiple-cursors-mode nil)
(defadvice read-char (around mc-support activate) (defadvice read-char (around mc-support activate)
(if (not multiple-cursors-mode) (if (not multiple-cursors-mode)
ad-do-it ad-do-it
@@ -238,6 +268,7 @@ cursor with updated info."
(setq mc--read-char ad-do-it)) (setq mc--read-char ad-do-it))
(setq ad-return-value mc--read-char))) (setq ad-return-value mc--read-char)))
(defvar mc--read-quoted-char nil)
(defadvice read-quoted-char (around mc-support activate) (defadvice read-quoted-char (around mc-support activate)
(if (not multiple-cursors-mode) (if (not multiple-cursors-mode)
ad-do-it ad-do-it
@@ -257,9 +288,9 @@ cursor with updated info."
(defun mc/cursor-with-id (id) (defun mc/cursor-with-id (id)
"Find the first cursor with the given id, or nil" "Find the first cursor with the given id, or nil"
(find-if #'(lambda (o) (and (mc/fake-cursor-p o) (cl-find-if #'(lambda (o) (and (mc/fake-cursor-p o)
(= id (overlay-get o 'mc-id)))) (= id (overlay-get o 'mc-id))))
(overlays-in (point-min) (point-max)))) (overlays-in (point-min) (point-max))))
(defvar mc--stored-state-for-undo nil (defvar mc--stored-state-for-undo nil
"Variable to keep the state of the real cursor while undoing a fake one") "Variable to keep the state of the real cursor while undoing a fake one")
@@ -290,8 +321,8 @@ cursor with updated info."
(defun mc/num-cursors () (defun mc/num-cursors ()
"The number of cursors (real and fake) in the buffer." "The number of cursors (real and fake) in the buffer."
(1+ (count-if 'mc/fake-cursor-p (1+ (cl-count-if 'mc/fake-cursor-p
(overlays-in (point-min) (point-max))))) (overlays-in (point-min) (point-max)))))
(defvar mc--this-command nil (defvar mc--this-command nil
"Used to store the original command being run.") "Used to store the original command being run.")
@@ -378,7 +409,10 @@ the original cursor, to inform about the lack of support."
Do not use to conclude editing with multiple cursors. For that Do not use to conclude editing with multiple cursors. For that
you should disable multiple-cursors-mode." you should disable multiple-cursors-mode."
(mc/for-each-fake-cursor (mc/for-each-fake-cursor
(mc/remove-fake-cursor cursor))) (mc/remove-fake-cursor cursor))
(when mc--max-cursors-original
(setq mc/max-cursors mc--max-cursors-original))
(setq mc--max-cursors-original nil))
(defun mc/keyboard-quit () (defun mc/keyboard-quit ()
"Deactivate mark if there are any active, otherwise exit multiple-cursors-mode." "Deactivate mark if there are any active, otherwise exit multiple-cursors-mode."
@@ -420,11 +454,11 @@ The entries are returned in the order they are found in the buffer."
(defun mc--maybe-set-killed-rectangle () (defun mc--maybe-set-killed-rectangle ()
"Add the latest kill-ring entry for each cursor to killed-rectangle. "Add the latest kill-ring entry for each cursor to killed-rectangle.
So you can paste it in later with `yank-rectangle'." So you can paste it in later with `yank-rectangle'."
(let ((entries (mc--kill-ring-entries))) (let ((entries (let (mc/max-cursors) (mc--kill-ring-entries))))
(unless (mc--all-equal entries) (unless (mc--all-equal entries)
(setq killed-rectangle entries)))) (setq killed-rectangle entries))))
(defvar mc/unsupported-minor-modes '(auto-complete-mode flyspell-mode) (defvar mc/unsupported-minor-modes '(company-mode auto-complete-mode flyspell-mode jedi-mode)
"List of minor-modes that does not play well with multiple-cursors. "List of minor-modes that does not play well with multiple-cursors.
They are temporarily disabled when multiple-cursors are active.") They are temporarily disabled when multiple-cursors are active.")
@@ -455,6 +489,7 @@ They are temporarily disabled when multiple-cursors are active.")
:group 'multiple-cursors) :group 'multiple-cursors)
(put 'mc/mode-line 'risky-local-variable t) (put 'mc/mode-line 'risky-local-variable t)
;;;###autoload
(define-minor-mode multiple-cursors-mode (define-minor-mode multiple-cursors-mode
"Mode while multiple cursors are active." "Mode while multiple cursors are active."
nil mc/mode-line mc/keymap nil mc/mode-line mc/keymap
@@ -519,19 +554,19 @@ from being executed if in multiple-cursors-mode."
(overlay-put cursor 'kill-ring kill-ring) (overlay-put cursor 'kill-ring kill-ring)
(overlay-put cursor 'kill-ring-yank-pointer kill-ring-yank-pointer))))))) (overlay-put cursor 'kill-ring-yank-pointer kill-ring-yank-pointer)))))))
(defvar mc/list-file "~/.emacs.d/.mc-lists.el" (defvar mc/list-file (locate-user-emacs-file ".mc-lists.el")
"The position of the file that keeps track of your preferences "The position of the file that keeps track of your preferences
for running commands with multiple cursors.") for running commands with multiple cursors.")
(defun mc/dump-list (list-symbol) (defun mc/dump-list (list-symbol)
"Insert (setq 'LIST-SYMBOL LIST-VALUE) to current buffer." "Insert (setq 'LIST-SYMBOL LIST-VALUE) to current buffer."
(symbol-macrolet ((value (symbol-value list-symbol))) (cl-symbol-macrolet ((value (symbol-value list-symbol)))
(insert "(setq " (symbol-name list-symbol) "\n" (insert "(setq " (symbol-name list-symbol) "\n"
" '(") " '(")
(newline-and-indent) (newline-and-indent)
(set list-symbol (set list-symbol
(sort value (lambda (x y) (string-lessp (symbol-name x) (sort value (lambda (x y) (string-lessp (symbol-name x)
(symbol-name y))))) (symbol-name y)))))
(mapc #'(lambda (cmd) (insert (format "%S" cmd)) (newline-and-indent)) (mapc #'(lambda (cmd) (insert (format "%S" cmd)) (newline-and-indent))
value) value)
(insert "))") (insert "))")
@@ -560,6 +595,8 @@ for running commands with multiple cursors.")
mc/edit-ends-of-lines mc/edit-ends-of-lines
mc/edit-beginnings-of-lines mc/edit-beginnings-of-lines
mc/mark-next-like-this mc/mark-next-like-this
mc/mark-next-like-this-word
mc/mark-next-like-this-symbol
mc/mark-next-word-like-this mc/mark-next-word-like-this
mc/mark-next-symbol-like-this mc/mark-next-symbol-like-this
mc/mark-previous-like-this mc/mark-previous-like-this
@@ -576,6 +613,7 @@ for running commands with multiple cursors.")
mc/mark-all-dwim mc/mark-all-dwim
mc/mark-sgml-tag-pair mc/mark-sgml-tag-pair
mc/insert-numbers mc/insert-numbers
mc/insert-letters
mc/sort-regions mc/sort-regions
mc/reverse-regions mc/reverse-regions
mc/cycle-forward mc/cycle-forward
@@ -592,6 +630,9 @@ for running commands with multiple cursors.")
mc/skip-to-next-like-this mc/skip-to-next-like-this
mc/skip-to-previous-like-this mc/skip-to-previous-like-this
rrm/switch-to-multiple-cursors rrm/switch-to-multiple-cursors
mc-hide-unmatched-lines-mode
hum/keyboard-quit
hum/unhide-invisible-overlays
save-buffer save-buffer
ido-exit-minibuffer ido-exit-minibuffer
exit-minibuffer exit-minibuffer
@@ -679,6 +720,8 @@ for running commands with multiple cursors.")
py-electric-backspace py-electric-backspace
c-electric-backspace c-electric-backspace
org-delete-backward-char org-delete-backward-char
cperl-electric-backspace
python-indent-dedent-line-backspace
paredit-backward-delete paredit-backward-delete
autopair-backspace autopair-backspace
just-one-space just-one-space
@@ -688,6 +731,7 @@ for running commands with multiple cursors.")
exchange-point-and-mark exchange-point-and-mark
cua-set-mark cua-set-mark
cua-replace-region cua-replace-region
cua-delete-region
move-end-of-line move-end-of-line
beginning-of-line beginning-of-line
move-beginning-of-line move-beginning-of-line
@@ -718,7 +762,6 @@ for running commands with multiple cursors.")
;; Local Variables: ;; Local Variables:
;; coding: utf-8 ;; coding: utf-8
;; byte-compile-warnings: (not cl-functions)
;; End: ;; End:
;;; multiple-cursors-core.el ends here ;;; multiple-cursors-core.el ends here
+2 -1
View File
@@ -1,2 +1,3 @@
(define-package "multiple-cursors" "1.3.0" (define-package "multiple-cursors" "1.3.0"
"Multiple cursors for Emacs.") "Multiple cursors for Emacs."
'((cl-lib "0.5")))
+9 -1
View File
@@ -3,7 +3,7 @@
;; Copyright (C) 2012-2013 Magnar Sveen ;; Copyright (C) 2012-2013 Magnar Sveen
;; Author: Magnar Sveen <magnars@gmail.com> ;; Author: Magnar Sveen <magnars@gmail.com>
;; Version: 1.2.2 ;; Version: 1.4.0
;; Keywords: editing cursors ;; Keywords: editing cursors
;; This program is free software; you can redistribute it and/or modify ;; This program is free software; you can redistribute it and/or modify
@@ -61,6 +61,8 @@
;; ### Mark one more occurrence ;; ### Mark one more occurrence
;; - `mc/mark-next-like-this`: Adds a cursor and region at the next part of the buffer forwards that matches the current region. ;; - `mc/mark-next-like-this`: Adds a cursor and region at the next part of the buffer forwards that matches the current region.
;; - `mc/mark-next-like-this-word`: Adds a cursor and region at the next part of the buffer forwards that matches the current region, if no region is selected it selects the word at the point.
;; - `mc/mark-next-like-this-symbol`: Adds a cursor and region at the next part of the buffer forwards that matches the current region, if no region is selected it selects the symbol at the point.
;; - `mc/mark-next-word-like-this`: Like `mc/mark-next-like-this` but only for whole words. ;; - `mc/mark-next-word-like-this`: Like `mc/mark-next-like-this` but only for whole words.
;; - `mc/mark-next-symbol-like-this`: Like `mc/mark-next-like-this` but only for whole symbols. ;; - `mc/mark-next-symbol-like-this`: Like `mc/mark-next-like-this` but only for whole symbols.
;; - `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-like-this`: Adds a cursor and region at the next part of the buffer backwards that matches the current region.
@@ -85,6 +87,7 @@
;; - `set-rectangular-region-anchor`: Think of this one as `set-mark` except you're marking a rectangular region. ;; - `set-rectangular-region-anchor`: Think of this one as `set-mark` except you're marking a rectangular region.
;; - `mc/mark-sgml-tag-pair`: Mark the current opening and closing tag. ;; - `mc/mark-sgml-tag-pair`: Mark the current opening and closing tag.
;; - `mc/insert-numbers`: Insert increasing numbers for each cursor, top to bottom. ;; - `mc/insert-numbers`: Insert increasing numbers for each cursor, top to bottom.
;; - `mc/insert-letters`: Insert increasing letters for each cursor, top to bottom.
;; - `mc/sort-regions`: Sort the marked regions alphabetically. ;; - `mc/sort-regions`: Sort the marked regions alphabetically.
;; - `mc/reverse-regions`: Reverse the order of the marked regions. ;; - `mc/reverse-regions`: Reverse the order of the marked regions.
@@ -100,6 +103,10 @@
;; - Try pressing `mc/mark-next-like-this` with no region selected. It will just add a cursor ;; - Try pressing `mc/mark-next-like-this` with no region selected. It will just add a cursor
;; on the next line. ;; on the next line.
;; ;;
;; - 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 occurance
;;
;; - Try pressing `mc/mark-all-like-this-dwim` on a tagname in html-mode. ;; - Try pressing `mc/mark-all-like-this-dwim` on a tagname in html-mode.
;; ;;
;; - Notice that the number of cursors active can be seen in the modeline. ;; - Notice that the number of cursors active can be seen in the modeline.
@@ -185,6 +192,7 @@
(require 'mc-mark-pop) (require 'mc-mark-pop)
(require 'rectangular-region-mode) (require 'rectangular-region-mode)
(require 'mc-separate-operations) (require 'mc-separate-operations)
(require 'mc-hide-unmatched-lines-mode)
(provide 'multiple-cursors) (provide 'multiple-cursors)
+3
View File
@@ -38,6 +38,8 @@
(define-key rectangular-region-mode-map (kbd "C-g") 'rrm/keyboard-quit) (define-key rectangular-region-mode-map (kbd "C-g") 'rrm/keyboard-quit)
(define-key rectangular-region-mode-map (kbd "<return>") 'rrm/switch-to-multiple-cursors) (define-key rectangular-region-mode-map (kbd "<return>") 'rrm/switch-to-multiple-cursors)
(defvar rectangular-region-mode nil)
(defun rrm/keyboard-quit () (defun rrm/keyboard-quit ()
"Exit rectangular-region-mode." "Exit rectangular-region-mode."
(interactive) (interactive)
@@ -106,6 +108,7 @@ an exceedingly quick way of adding multiple cursors to multiple lines."
(when rectangular-region-mode (when rectangular-region-mode
(rrm/switch-to-multiple-cursors))) (rrm/switch-to-multiple-cursors)))
;;;###autoload
(define-minor-mode rectangular-region-mode (define-minor-mode rectangular-region-mode
"A mode for creating a rectangular region to edit" "A mode for creating a rectangular region to edit"
nil " rr" rectangular-region-mode-map nil " rr" rectangular-region-mode-map