Compare commits

...

324 Commits

Author SHA1 Message Date
Pedro A. Aranda Gutiérrez
9017f3be6b
Add lexical binding cookies (#389)
* Add lexical binding cookies

* multiple-cursors-core.el: Pacify lexical-binding frenzy in master

* multiple-cursors-core.el: when saving mc/list-file, prepend a
lexical binding flag to avoid emacs master from screaming.  When
inserting strings, use `\\n' instead of (newline).
2025-10-06 13:38:27 -07:00
Magnar Sveen
89f1a8df9b Release 1.5.0 2025-02-10 19:13:49 +01:00
Magnar Sveen
758223c45b
Merge pull request #388 from emacsmirror/expkg
Move metadata from multiple-cursors-pkg.el to multiple-cursors.el
2025-02-10 19:12:54 +01:00
Jonas Bernoulli
bb07ffee68
Move metadata from multiple-cursors-pkg.el to multiple-cursors.el 2024-12-26 17:55:18 +01:00
Magnar Sveen
dd10cf2334
Merge pull request #387 from arialdomartini/tables
List of commands in a table
2024-12-02 17:31:03 +01:00
Arialdo Martini
3317246070 List of commands in a table, to improve readability 2024-12-02 15:55:39 +01:00
Magnar Sveen
46635e7f69
Merge pull request #386 from AjaiKN/symbol-value
Use symbol-value instead of eval
2024-12-01 19:41:18 +01:00
Ajai Nelson
e315120117
Use symbol-value instead of eval
The Emacs Lisp manual says, "to get the value of a variable, while eval
works, symbol-value is preferable".
2024-11-27 08:40:16 -05:00
Leo Gaskin
c870c18462
Merge pull request #383 from LaurenceWarne/fix-byte-comp-warnings
Fix byte compilation warnings
2024-02-23 12:34:45 +01:00
Laurence Warne
ba7852f192 Move mc/mark-more-like-this-extended-keymap defvar location 2024-02-13 21:03:23 +00:00
Leo Gaskin
d36c62aa71
Merge pull request #384 from cryptorick/fix-version
Align version numbers
2024-02-13 18:34:26 +01:00
cryptorick
5ab154b09e align version numbers 2024-02-12 23:45:40 -05:00
Laurence Warne
25b0dca82e Fix byte compilation warnings
Fix the byte compilation warnings:

In mc--read-char:
multiple-cursors-core.el:347:2: Warning: reference to free variable ‘multiple-cursors-mode’

In mc--read-quoted-char:
multiple-cursors-core.el:348:2: Warning: reference to free variable ‘multiple-cursors-mode’

In mc--register-read-with-preview:
multiple-cursors-core.el:349:2: Warning: reference to free variable ‘multiple-cursors-mode’

In mc--read-char-from-minibuffer:
multiple-cursors-core.el:350:2: Warning: reference to free variable ‘multiple-cursors-mode’

In toplevel form:
mc-mark-more.el:95:2: Warning: defvar `mc/enclose-search-term' docstring has wrong usage of unescaped single quotes (use \= or different quoting)

In mc/mark-more-like-this-extended:
mc-mark-more.el:501:2: Warning: docstring has wrong usage of unescaped single quotes (use \= or different quoting)
mc-mark-more.el:522:22: Warning: reference to free variable ‘mc/mark-more-like-this-extended-keymap’

In end of data:
mc-mark-more.el:724:27: Warning: the function ‘sgml-skip-tag-forward’ is not known to be defined.
mc-mark-more.el:673:8: Warning: the function ‘sgml-get-context’ is not known to be defined.

In end of data:
mc-hide-unmatched-lines-mode.el:110:1: Warning: the function ‘sgml-skip-tag-forward’ is not known to be defined.
mc-hide-unmatched-lines-mode.el:110:1: Warning: the function ‘sgml-get-context’ is not known to be defined.

In end of data:
multiple-cursors-core.el:567:43: Warning: the function ‘sgml-skip-tag-forward’ is not known to be defined.
multiple-cursors-core.el:535:25: Warning: the function ‘sgml-get-context’ is not known to be defined.

In end of data:
mc-cycle-cursors.el:124:1: Warning: the function ‘sgml-skip-tag-forward’ is not known to be defined.
mc-cycle-cursors.el:124:1: Warning: the function ‘sgml-get-context’ is not known to be defined.
2024-02-11 20:35:00 +00:00
Magnar Sveen
234806c832
Merge pull request #382 from ayyess/master
Support commands with multiple read-chars
2023-07-28 07:18:59 +02:00
Andrew Scott
25b98b940c
Support commands with multiple read-chars
This change fixes commands that read-chars multiple times. Previously, two
stage commands like embrace-change would read the same char twice immediately
and avy-goto-char-timer would never stop reading input as a cached value was
always provided during the timer. Instead, the read-char prompt is included in
the cache key so that multiple different calls are cached separately and
accessible by the fake cursors.
2023-07-28 00:05:13 +01:00
Magnar Sveen
6956e8e12e
Add autoload to activate-cursor-for-undo
This solves an issue where packages are loaded mid undo-session with undo-fu
2023-03-09 13:04:31 +01:00
Leo Gaskin
16223efc2d Fix byte compiler warnings by moving variable declarations 2023-01-13 09:35:03 +01:00
Leo Gaskin
7f255ce696 Remove notes saying that "M-x" isn't properly supported 2022-12-24 13:26:12 +01:00
Leo Gaskin
351eb6cbb5 Add multiple-cursors support to execute-extended-command
Also add three new tests for this functionality and adapt some existing
tests as well as the testing harness.
2022-12-24 13:26:12 +01:00
Leo Gaskin
558198239e Disable CI support for old versions of Emacs
Cask has seemingly stopped properly supporting these versions as
indicated by the commit cask/cask@685c4c1.
2022-12-23 16:22:43 +01:00
Leo Gaskin
817a7a8d25 Fix problem aborting mc/edit-lines when not in transient-mark-mode 2022-12-23 16:22:43 +01:00
Leo Gaskin
c9ea562bd5 Fix regression with determining the current sgml context
This problem seems to have been introduced in commit aae47ae by adding
"100" as an argument to "looking-back" instead of the correct "1".
2022-12-23 16:22:43 +01:00
Leo Gaskin
72de6a4ec4 Use latest major version of actions/checkout for CI 2022-12-23 16:22:43 +01:00
Leo Gaskin
03bc44e093 Use new recommended Cask installation method 2022-12-23 16:22:43 +01:00
Troy Brown
fe0d516745 Detect cursor bar type when specified by the frame.
When the 'cursor-type' for the buffer is specified by the frame, this
was not detected by the current logic as 'cursor-type' will be set to
't' and thus not explicitly match 'bar'.  This update checks to see if
'cursor-type' is specified by the frame and will pull the parameter
from the frame if it is, prior to subsequent checks.
2022-11-26 08:43:42 +01:00
Seungheon Oh
1e4842d129 Fix mc/mark-all-in-region leaving fake cursor.
Previously this function left a remain of fake function if there was
only one matching string in selected region.
2022-08-21 11:32:12 +02:00
Ryan Davis
225fc0e889 Extend advising functions for read-char and quoted-read-char w/ macro
Add register-read-with-preview and read-char-from-minibuffer to cover
insert-register and zap-to-char, respectively.

Also add mc--reset-read-variables to for mc--reset-read-prompts to use
dynamically so these can be further extended via the macro.
2022-06-13 23:22:50 +02:00
Will B Chang
fd8441bfc8 support undo-fu commands
https://github.com/emacsmirror/undo-fu
2022-05-28 14:15:14 +02:00
Steve Purcell
2f003612b7
Use GitHub Actions in place of Travis, and test more Emacs versions (#365)
* Use GitHub Actions in place of Travis, and test more Emacs versions

* Run tests in Actions via `script` to fake a TTY

* Add newer emacs versions to CI matrix
2022-05-22 23:54:21 +12:00
Jason May
aae47aebc0 eliminate byte-compilation warnings
- long docstrings
- "defcustom fails to specify type" - use '(sexp)
- keyword arguments in define-minor-mode
- deprecations
2022-03-28 19:24:00 +02:00
Johannes Lippmann
8a60fc7ef0 Document multiple-cursors-mode-disabled-hook in Readme 2021-11-12 23:23:42 +01:00
Johannes Lippmann
b139bb6b30 introduce function mc/disable-multiple-cursors-mode 2021-11-12 23:23:42 +01:00
Johannes Lippmann
4975afedb3 Run hook when mc is disabled 2021-11-12 23:23:42 +01:00
Philip K
588daf8c52 Mention NonGNU ELPA
Hi,

multiple-cursors has recently been added to [NonGNU ELPA](https://elpa.nongnu.org/), allowing Emacs 28+ users to install it without any additional configuration.

This patch mentions NonGNU in the README, so that users know that it can be installed by default.

Otherwise, the only thing worth noting is that NonGNU ELPA distributes stable versions by default, and these are identified by commits that modify the version tag in the package header. I'm not sure if new versions are to be expected, but in case there is an update, please remember to update the version tag too.
2021-08-08 13:05:02 +02:00
Kaligule
616fbdd369 Document existing functions in Readme
mc/vertical-align
mc/vertical-align-with-space

I have wanted that functions for so long, only to find out now that they have existed for 7 years!
2021-04-21 11:11:19 +02:00
Amory Meltzer
7b13b03c99 Add homepage 2021-03-23 12:28:43 +01:00
Vedang Manerikar
cb93501ec7 Minor backward compatibility fix to remove warning
This removes the deprecation warning around `return-from'
2021-03-22 19:44:31 +01:00
Zach Kost-Smith
a9d7764f80
Add option to disable bar-style fake cursors (#367) 2020-12-15 07:59:00 -08:00
Jen-Chieh Shen
83abb0533a
Add badges to README (#363)
* Add badges to README

* Update README.md

Co-authored-by: Steve Purcell <steve@sanityinc.com>

Co-authored-by: Steve Purcell <steve@sanityinc.com>
2020-10-25 13:27:10 +13:00
Masahiro Nakamura
7763f4f9d7 Load mc-cycle-cursors and mc-hide-unmatched-lines-mode after loading multiple-cursors-core
This is useful with autoloaded commands.
2020-10-18 07:38:52 +02:00
Masahiro Nakamura
6a04a147ce Fix docstrings
Fix wrong docstrings of mc/mark-next-word-like-this and
mc/mark-next-symbol-like-this.
2020-10-18 07:37:54 +02:00
Damien Cassou
b880554d04 Fix typos (#359)
Typos found with codespell.
2019-12-10 09:59:45 -08:00
Magnar Sveen
b9b851a767
Merge pull request #358 from renatofdds/master
Faster line-number-at-pos calculation
2019-08-20 09:49:53 +02:00
Renato Ferreira
b39e9631d6 Faster line-number-at-pos calculation 2019-08-18 13:44:55 -03:00
Magnar Sveen
5ffb19af48
Update README.md 2019-03-21 06:57:00 +01:00
Magnar Sveen
a730c414b1
Update README.md 2019-03-20 18:12:37 +01:00
Magnar Sveen
fc6a6a7462
Merge pull request #355 from flatwhatson/lazy-list-file
Load mc/list-file as late as possible
2019-03-17 13:11:44 +01:00
Andrew Whatson
d27870dff3 Load mc/list-file as late as possible
Previously the list file was loaded immediately upon loading
`multiple-cursors-core`.  This doesn't work well with modern autoloading
emacs configurations, where customisation is mostly done in
`eval-after-load` hooks; the default file location is loaded, *then*
the value of `mc/list-file` is changed, and everyone is confused.
2019-03-13 13:40:58 +10:00
Magnar Sveen
5ff2071fac
Merge pull request #351 from jrosdahl/dabbrev-expand
Add dabbrev state variables to mc/cursor-specific-vars
2019-02-24 13:46:09 +01:00
Joel Rosdahl
9980faa21f Add dabbrev state variables to mc/cursor-specific-vars
Fixes #142.
2019-02-24 13:28:36 +01:00
Matus Goljer
6a7c3c0853 Fix whitespace 2018-09-13 14:37:07 +02:00
Matus Goljer
8172edd05a Realign the file according to Elisp conventions 2018-09-13 14:26:58 +02:00
Matus Goljer
3f382d2c8f Move variables before first use 2018-09-13 14:26:38 +02:00
Magnar Sveen
9c49874fa4
Merge pull request #333 from drrlvn/patch-1
Make "no more matches found." user-error, fix #218
2018-06-15 14:18:37 +02:00
Dror Levin
038815b2b9
Make "no more matches found." user-error, fix #218 2018-06-06 22:33:08 +03:00
Magnar Sveen
75dd6bf83a
Merge pull request #327 from notetiene/master
Add customization group definition
2018-04-06 22:50:01 +02:00
Etienne
35ff8b5ef1 Add customization group definition
* multiple-cursors.el (multiple-cursors): Add the multiple-cursor
  group definition.
2018-04-06 15:31:54 -04:00
Magnar Sveen
e419903612
Merge pull request #324 from mkcms/master
Always call `mark` with `mark-even-if-inactive` set to t
2018-04-06 14:47:29 +02:00
Magnar Sveen
0e49fecc18
Merge pull request #326 from pstray/issue325
Add temporary-goal-column to mc/cursor-specific-vars
2018-03-20 15:47:49 +01:00
Peder Stray
eba10208fc Add temporary-goal-column to mc/cursor-specific-vars 2018-03-20 11:25:08 +01:00
Michał K
f628df72a1 Always call mark with mark-even-if-inactive set to t 2018-03-12 16:18:22 +01:00
bb2020
1075270008 Added mc/interactive-repeating-commands (#303)
* Added mc/interactive-repeating-commands

* simplify mc/interactive-repeating-commands

* simplify mc/interactive-repeating-commands

* removed mc/interactive-repeating-commands

* added mc/repeat-command

* rebound mc/repeat-command

* blacklisted repeat-complex-command

* added mc/always-repeat-command

* added mc/repeat-command tests
2017-09-08 14:52:47 -07:00
Jules Tamagnan
e048e04bd8 Fix #271: The command yank can't work
It seems that this may be a windows specific issue given the version
strings that @moyotar and @dertuxmalwieder have posted. As a
workaround it should be safe to add the arguments that current-kill
needs to the defadvice. current-kill has had the same arguments for
the past 25 years, since it was first added.
2017-08-31 16:33:49 -07:00
Magnar Sveen
6f183a1e82 Merge pull request #304 from angadgill92/master
Fix minor error
2017-08-30 06:48:45 +02:00
Angad Pal
f33cdd4935 Fix minor error
- replace "... does not well ..." with "... does not do well ..."
2017-08-30 07:48:31 +05:30
Magnar Sveen
18f992bff5 Merge pull request #290 from raxod502/feat/silent-load
Don't display message while loading mc/list-file
2017-08-13 09:38:48 +02:00
Magnar Sveen
f6bac949a0 Add note about M-x 2017-08-11 13:29:04 +02:00
Magnar Sveen
e14fdb77a1 Merge pull request #298 from Quasilyte/update_readme
README: added a note about newlines in "tips and tricks"
2017-07-30 16:46:20 +02:00
quasilyte
d2766bc215 tips and tricks: add note about <return> and newlines; if it is not default, let it at least be more discoverable 2017-07-30 17:36:16 +03:00
Josh Hunsaker
c94566597a Merge pull request #294 from nispio/fix-293
Fix bug in mc/mark-all-in-region-regexp. Fixes #293
2017-07-13 18:47:10 -07:00
Josh Hunsaker
7cb18b8aec Fix bug in mc/mark-all-in-region-regexp. Fixes #293 2017-06-29 16:30:04 -07:00
Radon Rosborough
fa91dfb9bd Don't display message while loading mc/list-file 2017-06-15 16:12:28 -07:00
Magnar Sveen
ddbe3ae932 Merge pull request #278 from shlomme/master
Add ivy-done to the commands that are only executed once by default
2017-02-15 14:52:02 +01:00
Torsten Marek
616fd84891 Add ivy-done (from ivy) to the list of commands that are only executed once by default.
ivy-done is the value of this-original-command when invoking mc/ functions when ivy mode is active.
2017-02-14 17:40:47 +01:00
Jules Tamangan
632768113d Merge pull request #267 from Fuco1/master
Make mc/list-file into defcustom
2016-10-21 14:31:53 -07:00
Matus Goljer
277aef4f0b Make mc/list-file into defcustom 2016-09-22 17:56:48 +02:00
Jules Tamagnan
dfaf6215fc Fix #254; remove mc/mark-next-like-this-extended 2016-08-01 23:55:09 -04:00
Magnar Sveen
95f2e41fab Add @AndreaOrru to list of contributors 2016-07-19 11:18:12 +02:00
Magnar Sveen
8e59a8a226 Merge pull request #262 from AndreaOrru/master
mark-previous-like-this-word/symbol.
2016-07-19 11:16:38 +02:00
Andrea Orru
6d8c6fcc83 Pass tests. 2016-07-18 14:56:26 +02:00
Andrea Orru
67d6579eab Updated tests, README. 2016-07-17 16:40:56 +02:00
Andrea Orru
21e48250ec mc/mark-previous-like-this-word/symbol. 2016-07-17 02:56:48 +02:00
jules tamagnan
ad95d287c7 Update docstring of mc/cursor-is-bar 2016-07-05 10:07:06 -04:00
jules tamagnan
60b9ef8347 Updated readme according to `mc/always-run-for-all
Related to #256 by @bb2020
2016-07-05 06:26:07 -04:00
jules tamagnan
d9a6047d1a Fix mc/cursor-is-bar as per @cpitclaudel 2016-07-05 06:07:57 -04:00
Jules Tamangan
8413969a97 Merge pull request #253 from jtamagnan/fake-bar-cursor
When cursor-type is bar, mc/cursors appear as bars
2016-06-16 17:04:58 -04:00
Jules Tamangan
2ccfc74bf4 Merge pull request #252 from bb2020/master
Add defcustom boolean `mc/always-run-for-all`. When non-nil every command will be run for every cursor
2016-06-09 16:11:55 -04:00
bb2020
d26cecd53a added always-run-for-all 2016-06-09 23:06:48 +03:00
bb2020
2329611a41 Merge remote-tracking branch 'upstream/master' 2016-06-09 22:45:19 +03:00
bb2020
fd847ae6e7 added mc/always-run-for-all 2016-06-09 22:41:51 +03:00
Jules Tamagnan
be149f9121 Create customizable mc/insert-numbers-default
This commit fulfills the feature request from #248 and creates a
customizable variable called mc/insert-numbers-default which is the
starting value for mc/insert-numbers if no arg is passed
2016-05-23 15:43:08 -04:00
Jules Tamagnan
3112e61824 When cursor-type is bar, mc/cursors appear as bars 2016-05-20 15:36:13 -04:00
Jules Tamagnan
a508978cd9 Add /.ecukes-failing-scenarios to gitignore 2016-05-20 08:58:06 -04:00
Jules Tamagnan
a9daac129a Add/fix docstring to functions. fix #161
functions documented added:
 - mc/mark-next-word-like-this,
 - mc/mark-next-symbol-like-this
 - mc/mark-previous-word-like-this
 - mc/mark-previous-symbol-like-this

functions documented fixed:
 - mc/mark-previous-like-this
2016-05-20 08:51:09 -04:00
Bozhidar Batsov
741eec6766 Update some copyright years 2016-05-19 20:29:36 -07:00
Bozhidar Batsov
be4fbc702e Mention MELPA Stable 2016-05-19 20:28:01 -07:00
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
bb2020
1686630fd6 try to implement blacklist 2016-05-12 14:41:38 +03: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 2588ccef6939b77896105f23642483c30c4a4e06.
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 2d6ffce4c94cdbec1ea8ec086ea346423bafcdf1.

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
Magnar Sveen
d17c89e418 Release 1.3.0 2013-09-06 22:21:57 +02:00
Magnar Sveen
65c0c0c6fe Merge pull request #104 from mathrick/mark-all-dwim
Add new command, mark-all-dwim
2013-09-06 12:57:31 -07:00
Maciej Katafiasz
ec4781394c Derp, multiple cursors means > 1, not > 0. 2013-09-06 19:44:31 +02:00
Maciej Katafiasz
ad79ad8b52 Mention only 'mc/mark-all-dwim' in README to prevent confusing redundancy 2013-09-06 14:53:35 +02:00
Maciej Katafiasz
18d858f0de Fall straight through in 'mc/mark-all-dwim' if multiple cursors are already active, as that means we can't sensibly edit lines or mark all in region 2013-09-06 14:52:16 +02:00
Magnar Sveen
68dfa461f1 Merge pull request #109 from mathrick/fix-mark-all-in-region-hang
Guard against empty search pattern in 'mc/mark-all-in-region', otherwise...
2013-09-06 03:09:25 -07:00
Maciej Katafiasz
a86daa79ce Guard with 'if' rather than defun*/return-from 2013-09-06 09:33:37 +02:00
Maciej Katafiasz
8dfe725c4f Abort immediately when empty search pattern is passed to 'mc/mark-all-in-region' 2013-09-05 23:53:59 +02:00
Magnar Sveen
d8c5227443 Merge pull request #103 from mathrick/compat-24.2
Add gnu repo to Cask, which is needed for cl-lib on Emacs <24.3
2013-09-05 11:52:11 -07:00
Maciej Katafiasz
9f91a0455d Add 'mc/mark-all-dwim' to README 2013-09-05 18:51:51 +02:00
Maciej Katafiasz
bf4b0c669b Refactor mark-dwim tests to share a common background 2013-09-05 18:42:16 +02:00
Maciej Katafiasz
45ed43e1f8 Test edit-lines functionality in 'mc/mark-all-dwim' 2013-09-05 18:22:12 +02:00
Maciej Katafiasz
af66635a05 Make 'mc/mark-all-dwim' into 'mc/edit-lines' if prefix arg is passed 2013-09-05 18:16:39 +02:00
Maciej Katafiasz
61388fedef Add 'mark-all-dwim' tests for selection 2013-09-05 18:07:52 +02:00
Maciej Katafiasz
49027c6717 Add basic tests for 'mc/mark-all-dwim' 2013-09-05 17:51:19 +02:00
Maciej Katafiasz
5e879f9b5c Guard against empty search pattern in 'mc/mark-all-in-region', otherwise it will enter an infinite loop 2013-09-05 17:42:36 +02:00
Magnar Sveen
23459589eb Run ecukes tests in --no-win mode
Fixes #108
2013-09-05 14:00:21 +02:00
Magnar Sveen
e28090d635 Merge pull request #106 from porterjamesj/patch-1
Update README to note that there is a mode allowing search in multiple-c...
2013-09-03 21:48:25 -07:00
James Porter
be7905d9e0 Update README to note that there is a mode allowing search in multiple-cursors. 2013-09-03 21:17:18 -04:00
Maciej Katafiasz
a37403178f Add gnu repo to Cask, which is needed for cl-lib on Emacs <24.3 2013-08-30 22:38:37 +02:00
Maciej Katafiasz
45c6cd0be4 Add mc/mark-all-dwim 2013-08-30 22:36:01 +02:00
Magnar Sveen
186cb3b63f Release 1.2.3 2013-08-24 20:39:50 +02:00
Magnar Sveen
c94eca57ae Fix broken let binding 2013-08-24 20:39:50 +02:00
Magnar Sveen
725369c445 Merge pull request #97 from knu/fix-mc-mark-pop-doc
Fix the doc string of mc/mark-pop, which was not updated after a copy.
2013-08-20 23:18:36 -07:00
Akinori MUSHA
e8d734452e Fix the doc string of mc/mark-pop, which was not updated after a copy. 2013-08-21 12:55:22 +09:00
Magnar Sveen
398cc9e466 Merge pull request #92 from knu/mark_by_logical_lines
mc/mark-lines: Mark by logical lines.
2013-08-15 21:10:47 -07:00
Magnar Sveen
6745142d87 Move from Carton to Cask 2013-08-11 21:18:04 +02:00
Magnar Sveen
47e03d54f4 Release 1.2.2 2013-08-11 20:51:37 +02:00
Magnar Sveen
39f17258b8 Add support for god-mode
@chrisdone
2013-08-11 20:51:09 +02:00
Akinori MUSHA
2186e1b6e5 mc/mark-lines: Mark by logical lines. 2013-08-01 17:00:03 +09:00
Magnar Sveen
66ceb0b0d4 Revert cursor specific pre- & post-command-hooks
- makes for problems with global post-command-hooks
 - doesn't really solve the problem they set out to do
2013-07-30 22:11:47 +02:00
Magnar Sveen
6cff0c2ebd Add pre- & post-command-hook to be cursor specific 2013-07-14 14:07:07 +02:00
Magnar Sveen
4c293c46fd Disable snapshot CI 2013-07-11 10:34:22 +02:00
Magnar Sveen
754de4e63b Backport set-temporary-overlay-map to emacs <24.3
Fixes #88
2013-07-11 09:14:06 +02:00
Magnar Sveen
1cb894d119 Add more mc-specific commands to the run-once list
#84
2013-06-08 10:31:49 +02:00
Magnar Sveen
cc45842384 Improved mc/mark-more-like-this-extended
- support for terminal
 - more instructive message
 - keymap that can be rebound

Fixes #84
2013-06-07 23:18:19 +02:00
Magnar Sveen
94af07453d Add some readability enhancing step definitions 2013-06-07 08:03:05 +02:00
Magnar Sveen
cb848b2a39 Add @smithzvk to contributors list
Closes #80
2013-05-27 05:52:38 +02:00
Magnar Sveen
474838666a Make mc/mark-pop only run once per invocation 2013-05-27 05:51:59 +02:00
Zach Kost-Smith
53db250b43 Added a mark-pop.feature file. 2013-05-26 16:08:21 -05:00
Zach Kost-Smith
75df47fc4a Added mention of mc/mark-pop to README.md 2013-05-26 16:07:27 -05:00
Zach Kost-Smith
4535033952 Added a new function mc/mark-pop that sets cursors by popping marks off the mark stack. 2013-05-26 14:34:58 -05:00
Magnar Sveen
69c99618f9 Use Carton for dev dependencies 2013-05-18 08:16:23 +02:00
Magnar Sveen
7a236d174e Add flyspell-mode to unsupported minor modes 2013-05-08 11:00:42 +02:00
Magnar Sveen
374244b66e Add support for C-s and C-r when phi-search is installed 2013-05-08 11:00:10 +02:00
Magnar Sveen
8b91e4788c Add py-electric-backspace to run-for-all list
- backspace = no in the prompt, causing people not to notice the prompt
2013-04-08 08:42:23 +02:00
Magnar Sveen
bf0177205e Use phi-search for C-s in mc-mode when available. 2013-03-28 19:41:08 +01:00
Magnar Sveen
6e159238b2 Use uninterned symbols in macros to avoid surprising local vars 2013-03-21 10:17:50 +01:00
Magnar Sveen
9dac934bce Fix scrolling behavior in Emacs 24. 2013-03-21 10:09:41 +01:00
Magnar Sveen
ccb42b5d70 Inline defun for better readability. 2013-03-15 20:21:34 +01:00
Magnar Sveen
8a53db8a39 Merge pull request #64 from tarsius/master
add .nosearch to directory with bundled libraries
2013-03-12 13:52:35 -07:00
Jonas Bernoulli
72ba43a08e add .nosearch to directory with bundled libraries
And move ert.el to that directory.
2013-03-12 21:40:43 +01:00
Magnar Sveen
16589a5af2 Update README.md 2013-03-10 07:58:04 +01:00
Magnar Sveen
980a8808dd Merge pull request #63 from tkf/select-thing-at-point
Automatically select word/symbol
2013-03-09 22:54:22 -08:00
Magnar Sveen
ed18fa49c1 Merge pull request #62 from tkf/export-ECUKES_EMACS
Export $ECUKES_EMACS
2013-03-09 22:41:12 -08:00
Takafumi Arakaki
1cdd73037f Automatically select word/symbol 2013-03-10 06:53:53 +01:00
Takafumi Arakaki
aa9a1ece7b Add failing scenarios for mark-all-symbols/words 2013-03-10 06:52:12 +01:00
Takafumi Arakaki
25dd14d350 Add more scenarios for mark-all-*-like-this 2013-03-10 06:49:25 +01:00
Takafumi Arakaki
373dcbe002 Add a scenario for mc/mark-all-symbols-like-this 2013-03-10 06:44:18 +01:00
Takafumi Arakaki
d24ddc53ea Default ECUKES_EMACS to $EMACS
Otherwise, $EMACS set on .travis.yml is not used in test.
2013-03-10 06:17:30 +01:00
Takafumi Arakaki
5c60757080 export ECUKES_EMACS in run-travis-ci.sh 2013-03-10 06:12:07 +01:00
Magnar Sveen
a6e0ccb22f mc/add-cursor-on-click should not run per cursor
Fixes #60
2013-02-26 21:38:26 +01:00
Magnar Sveen
0ee76bfad1 Add mc/add-cursor-on-click 2013-02-20 07:05:18 +01:00
Magnar Sveen
e7a5fe61c4 Release 1.2.1 2013-02-11 07:32:09 +01:00
Magnar Sveen
641eb680ca Can use mc/reverse-regions w/o region or cursors
- will flip sexp at point with the one below it
2013-02-11 07:29:17 +01:00
Magnar Sveen
16add89d29 Bugfix for sort/reverse regions w/similar contents 2013-02-11 07:28:26 +01:00
Magnar Sveen
cb7a145153 Release 1.2.0 2013-02-10 21:15:35 +01:00
Magnar Sveen
82a1fe3746 Add mc/sort-regions and mc/reverse-regions 2013-02-10 21:04:09 +01:00
Magnar Sveen
56839dfdca Update docs with mc/edit-*-lines 2013-02-07 05:36:22 +01:00
Magnar Sveen
3f3cdc6c92 Merge pull request #56 from paradoxxxzero/transient-mark-mode
Add transient-mark-mode to mc/cursor-specific-vars to fix other selections than C-SPC.
2013-02-01 02:57:19 -08:00
Florian Mounier
5190e0cdc6 Add test case for shift-select-mode 2013-02-01 11:52:21 +01:00
Florian Mounier
a4f6ea179a Add transient-mark-mode to mc/cursor-specific-vars to fix other selections than C-SPC. Fixes #55 2013-01-30 16:34:48 +01:00
Magnar Sveen
9582c7220b Add mc/insert-numbers
- adds increasing numbers for each cursor, top to bottom
2013-01-23 12:05:18 +01:00
Magnar Sveen
a6984a1141 Merge pull request #53 from oneself/master
Adding support for using mc/edit-lines without transient mark mode.
2013-01-23 00:31:28 -08:00
Eyal Erez
6a5969e14a Adding support for using mc/edit-lines without transient mark mode. 2013-01-22 15:30:01 -05:00
Magnar Sveen
9a376a6fa2 Add note about yank-rectangle
- thanks to @snosov1 for the text
2013-01-19 08:29:31 +01:00
Magnar Sveen
bfb293f200 Merge pull request #48 from tkf/smartrep
Avoid strange behavior with smartrep
2012-12-12 13:12:51 -08:00
Takafumi Arakaki
3ce6e4a670 Avoid strange behavior with smartrep
smartrep `intern`s commands into own obarray to help
`describe-bindings`, but this is bad for multiple-cursors as it makes
impossible to compare command with `memq` (`eq`).  This patch
re-`intern's the command to make the command comparable by `eq'.
2012-12-12 20:55:51 +01:00
Magnar Sveen
424e0667a4 1.1.5 2012-12-02 08:29:52 +01:00
Magnar Sveen
f1a5a39b48 Merge pull request #46 from tkf/fix-dump-list-take-2
Fix mc/dump-list (take 2): it looses old setting
2012-12-01 22:34:14 -08:00
Takafumi Arakaki
84ab4ee26a Fix mc/dump-list (take 2): it looses old setting
In the old code, heading part of `value` may lost due to in-place
modification by the `sort` function. ``(symbol-value list-symbol)``
must be re-evaluated before passing it to `mapc`.  To do that,
simply replacing `let` to `symbol-macrolet` works.

See also: #40
2012-12-01 22:01:02 +01:00
Magnar Sveen
07b88080b1 Merge pull request #43 from purcell/travis-script
Simplify travis script, and make it work when ECUKES_EMACS has spaces
2012-11-27 11:03:38 -08:00
Magnar Sveen
e7605bbd7c Merge pull request #42 from purcell/cleanup
Fix byte-compilation warnings, and avoid unnecessary use of "eval"
2012-11-27 11:03:22 -08:00
Steve Purcell
dc0aa99459 Simplify travis run script, and make it work when ECUKES_EMACS has a space in the path
Yes, on OS X, one might have:

ECUKES_EMACS='/Applications/Emacs 23.app/Contents/MacOS/Emacs'
2012-11-27 16:35:43 +00:00
Steve Purcell
6339657440 Fix byte-compilation warnings, and avoid unnecessary use of "eval"
multiple-cursors-core.el:28:1:Warning: cl package required at runtime

In mc/store-cursor-specific-var:
multiple-cursors-core.el:127:35:Warning: reference to free variable `o'

In mc/restore-cursor-specific-var:
multiple-cursors-core.el:130:44:Warning: reference to free variable `o'
2012-11-27 14:04:36 +00:00
Magnar Sveen
94164f706a Merge pull request #41 from purcell/patch-1
Prevent byte-compilation warnings 'cl functions
2012-11-26 03:28:46 -08:00
Steve Purcell
52300ff852 Prevent byte-compilation warnings 'cl functions
Prevents the following senseless warnings:

    In mc/first-fake-cursor-after:
    mc-cycle-cursors.el:76:70:Warning: function `remove-if' from cl package called
        at runtime
    mc-cycle-cursors.el:78:64:Warning: function `sort*' from cl package called at
        runtime

    In mc/last-fake-cursor-before:
    mc-cycle-cursors.el:85:71:Warning: function `remove-if' from cl package called
        at runtime
    mc-cycle-cursors.el:87:65:Warning: function `sort*' from cl package called at
        runtime
2012-11-26 11:21:27 +00:00
Magnar Sveen
129ea778cc 1.1.4 2012-11-25 09:23:14 +01:00
Magnar Sveen
0b9aae12ca Merge pull request #40 from tkf/fix-dump-list
Fix: mc/dump-list loosing old setting
2012-11-25 00:12:57 -08:00
Takafumi Arakaki
fa753aa587 Fix: mc/dump-list loosing old setting 2012-11-24 23:27:46 +01:00
Magnar Sveen
bc8af45bfe Use derived-mode-p to check for sgml-mode-ishness. 2012-11-21 13:22:27 +01:00
Magnar Sveen
b218a13cf7 Run tests in Emacs 23, Emacs 24 and snapshot. 2012-11-19 20:12:09 +01:00
Magnar Sveen
0a081a7c5f Move mc/maybe-multiple-cursors-mode to core. 2012-11-18 21:10:09 +01:00
Magnar Sveen
839c6ef077 Update README with command overview and tips-n-tricks. 2012-11-18 16:36:45 +01:00
Magnar Sveen
7d79b983ea Autoload new functions. 2012-11-18 16:08:10 +01:00
Magnar Sveen
717c97e32b Added Fuco to list of contributors 2012-11-18 14:47:48 +01:00
Magnar Sveen
c010afbbef Rename mc/mark-sgml-tags to mc/mark-sgml-tag-pair 2012-11-18 14:45:25 +01:00
Magnar Sveen
f721308591 Tweak mc/mark-all-like-this-dwim and add tests 2012-11-18 14:43:39 +01:00
unknown
1074c88c99 Added mc/mark-all-like-this-dwim 2012-10-27 20:33:51 +02:00
Magnar Sveen
a37e02b907 Add new mc-commands to default run-once list.
Fixes #36
2012-10-27 09:13:09 +02:00
Magnar Sveen
fe211c018c Add word/symbol limiting mark-more functions:
- mc/mark-next-word-like-this
 - mc/mark-next-symbol-like-this
 - mc/mark-previous-word-like-this
 - mc/mark-previous-symbol-like-this
 - mc/mark-all-words-like-this
 - mc/mark-all-symbols-like-this

Fixes #24
2012-10-26 22:51:40 +02:00
Magnar Sveen
1afbb9317c Add mc/cycle-looping-behaviour to multiple-cursors custom group. 2012-10-26 22:15:12 +02:00
Magnar Sveen
dce6c00fab Add mc/cursor-specific-vars to handle vars that need to be tracked per cursor.
- also add autopair-vars to this list.

Fixes #32
2012-10-25 10:57:58 +02:00
Magnar Sveen
5f7c92bb74 Add more backward-delete commands to run-for-all 2012-10-25 10:22:25 +02:00
Magnar Sveen
6b09b9c73f Add some more basic commands to the run-all and run-once lists. 2012-10-24 19:20:03 +02:00
Magnar Sveen
b3ca408f52 Have to require 'cl for now, because of count-if. 2012-10-24 08:10:22 +02:00
Magnar Sveen
7382b462b2 Merge pull request #30 from gvol/master
Fixed mode-line not showing up
2012-10-20 15:27:38 -07:00
Ivan Andrus
be4067da45 Fixed mode-line not showing up 2012-10-21 00:24:00 +02:00
Magnar Sveen
65d4f873fe Added Ivan Andrus to list of contributors 2012-10-21 00:54:04 +03:00
Magnar Sveen
dce196ce9f Merge pull request #28 from gvol/master
Show number of cursors in mode-line
2012-10-20 14:49:04 -07:00
Ivan Andrus
bb546b11d8 Display number of cursors in mode-line 2012-10-20 22:01:34 +02:00
Magnar Sveen
796fb640e1 Added segv to contributors list 2012-10-13 09:24:18 +03:00
Magnar Sveen
c3b2d8483b Merge pull request #23 from segv/master
Improve mc/cycle and mc/mark-next/prev
2012-10-12 10:26:46 -07:00
Marco Baringer
2818d9e7ef Rename mc/(first|last)-cursor-(before|after)-point to mention that they operate on fake cursors 2012-10-12 17:07:55 +02:00
Marco Baringer
1ec78e195f Don't let mc/mark-lines create 'double' cursors.
Previously using mc/mark-lines in a fowards/backwards/forwards
combination would cause multiple cursors to be placed at the same
point of the same line. This is not useful behaviour.

Noted while implementing magnars suggestion: https://github.com/magnars/multiple-cursors.el/pull/23#commitcomment-1983183
2012-10-12 17:04:36 +02:00
Marco Baringer
038c9a7f03 Added stop as a possible value for mc/cycle-looping-behaviour.
Simply disables looping (no warning either).
2012-10-12 16:56:01 +02:00
Marco Baringer
19b1a83925 Refactor mc/first-cursor-after and mc/last-cursor-before to not use extreme.
Sometimes imperative code is more readable.
Suggested by magnars (https://github.com/magnars/multiple-cursors.el/pull/23#commitcomment-1983268)
2012-10-12 16:51:01 +02:00
Marco Baringer
a8b632386d Remove superfluous lambda.
Caught by magnars (https://github.com/magnars/multiple-cursors.el/pull/23#commitcomment-1983191)
2012-10-12 16:27:39 +02:00
Marco Baringer
e4adefc04e Fix issues with mc/cycle-(backward|forward) where the cycling was dependent on not having an active mark.
This patch also adds two utility functions mc/first-cursor-after and mc/last-cursor-before.
2012-10-10 13:39:28 +02:00
Marco Baringer
324d9354b5 Split macro mc/for-each-fake-cursor into a function returning all the cursor overlays and a macro to loop over this list. 2012-10-10 13:38:47 +02:00
Marco Baringer
80ebdbb35b Added test for mc/mark-(next|previous)-like-this when there is no active region. 2012-10-10 13:37:40 +02:00
Marco Baringer
9ac7675c78 Added tests for mc/cycle-forward and mc/cycle-backward with their new looping behaviour 2012-10-10 13:36:45 +02:00
Marco Baringer
3f20fc15a7 When no region is active mc/mark-next-like-this and mc/mark-previous-like-this should create a cursor one like up (or down).
Added the functions mc/mark-next-lines and mc/mark-previous-lines
which create cursors one line above and below point.

Refactored common mc/mark-previous-like-this and
mc/mark-next-like-this functionality into mc/mark-more-like-this.

Changed mc/mark-next-like-this and mc/mark-more-like-this to call
mc/mark-next-lines and mc/mark-previous-lines when there is no
active region (instead of erroring).
2012-10-10 11:15:22 +02:00
Marco Baringer
876937bfa3 Use (interactive "P") instead of the weird (but equivalent) (interactive (list prefix-arg)) 2012-10-10 10:04:22 +02:00
Marco Baringer
fcbb7a4df9 Make mc/cycle-forward and mc/cycle-backward loop around by default.
Instead of erroring if there is no next (respectively previous) cursor
mc/cycle-forward (respectively mc/cycle-backward) will just loop back
to the first (respectively last) cursor.
2012-10-10 09:24:19 +02:00
Magnar Sveen
a0f771f3e4 Include interactive commands for deselecting prev/next
Fixes #21
2012-10-04 07:47:31 +02:00
Magnar Sveen
879ddb0e97 Add Takafumi Arakaki to list of contributors 2012-10-03 20:12:56 +03:00
Magnar Sveen
6e9ea1ae52 Merge pull request #20 from tkf/diff-friendly-save-lists
Diff friendly .mc-lists.el
2012-10-03 10:10:41 -07:00
Magnar Sveen
8a12e97b7d Mention region-bindings-mode in README 2012-10-03 20:06:15 +03:00
Takafumi Arakaki
f4d5aea860 Sort before saving list in mc/save-lists 2012-10-03 18:50:29 +02:00
Takafumi Arakaki
00f905549e Add mc/dump-list to make mc/save-lists diff-friendly 2012-10-03 18:47:31 +02:00
Magnar Sveen
7a6eb0df90 Never execute keyboard macros for fake cursors.
- The real cursor will execute the keyboard macro, resulting in new
   commands in the command loop, and the fake cursors can pick up on
   those instead.

Fixes #18
2012-10-02 12:19:00 +02:00
37 changed files with 2978 additions and 3185 deletions

36
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,36 @@
name: CI
on:
pull_request:
push:
paths-ignore:
- '**.md'
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
emacs_version:
- 25.1
- 25.2
- 25.3
- 26.1
- 26.2
- 26.3
- 27.2
- 28.1
- snapshot
steps:
- uses: purcell/setup-emacs@master
with:
version: ${{ matrix.emacs_version }}
- name: Install Cask
run: git clone https://github.com/cask/cask ~/.cask
- name: Add Cask to PATH
run: echo "$HOME/.cask/bin" >> $GITHUB_PATH
- uses: actions/checkout@v3
- name: Install dependencies with Cask
run: cask
- name: Run tests
run: script -e -c /bin/bash -c 'TERM=xterm ./run-tests.sh'

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
elpa
*.elc
/.ecukes-failing-scenarios

6
.gitmodules vendored
View File

@ -1,6 +0,0 @@
[submodule "util/ecukes"]
path = util/ecukes
url = git://github.com/rejeep/ecukes.git
[submodule "util/espuds"]
path = util/espuds
url = git://github.com/rejeep/espuds.git

View File

@ -1,12 +0,0 @@
language: emacs-lisp
before_install:
- if [ "$ECUKES_EMACS" = 'emacs-snapshot' ]; then
sudo add-apt-repository -y ppa:cassou/emacs &&
sudo apt-get update -qq &&
sudo apt-get install -qq
emacs-snapshot-el emacs-snapshot-gtk emacs-snapshot;
fi
env:
- ECUKES_EMACS=emacs
script:
./run-travis-ci.sh

9
Cask Normal file
View File

@ -0,0 +1,9 @@
(source gnu)
(source melpa)
(package-file "multiple-cursors.el")
(development
(depends-on "ecukes")
(depends-on "espuds")
(depends-on "wrap-region"))

198
README.md
View File

@ -1,9 +1,45 @@
# multiple-cursors.el [![Build Status](https://secure.travis-ci.org/magnars/multiple-cursors.el.png)](http://travis-ci.org/magnars/multiple-cursors.el)
[![Build Status](https://github.com/magnars/multiple-cursors.el/workflows/CI/badge.svg)](https://github.com/magnars/multiple-cursors.el/actions)
[![MELPA](https://melpa.org/packages/multiple-cursors-badge.svg)](https://melpa.org/#/multiple-cursors)
[![MELPA Stable](https://stable.melpa.org/packages/multiple-cursors-badge.svg)](https://stable.melpa.org/#/multiple-cursors)
[![NonGNU ELPA](https://elpa.nongnu.org/nongnu/multiple-cursors.svg)](https://elpa.nongnu.org/nongnu/multiple-cursors.html)
# multiple-cursors.el
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 though, 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`.
It's available on [MELPA](http://melpa.org/), [MELPA Stable](http://stable.melpa.org) and
[NonGNU ELPA](https://elpa.nongnu.org/nongnu/multiple-cursors.html) (enabled by default
from Emacs 28 onwards):
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
Start out with:
@ -35,42 +71,119 @@ insert a newline in multiple-cursors-mode, use `C-j`.
You can [watch an intro to multiple-cursors at Emacs Rocks](http://emacsrocks.com/e13.html).
## More commands to play around with
## Command overview
I've set up my key-bindings like so:
### Mark one more occurrence
;; From active region to multiple cursors:
(global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines)
(global-set-key (kbd "C-S-c C-e") 'mc/edit-ends-of-lines)
(global-set-key (kbd "C-S-c C-a") 'mc/edit-beginnings-of-lines)
| Command | Description |
|-------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `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-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-word` | 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 word at the point. |
| `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/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. |
When you have an active region that spans multiple lines, the preceeding three
commands will add one cursor to each line.
### Juggle around with the current cursors
;; Rectangular region mode
(global-set-key (kbd "H-SPC") 'set-rectangular-region-anchor)
| Command | Description |
|---------------------------------|--------------------------------------------------------------------|
| `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. |
Think of this one as `set-mark` except you're marking a rectangular region. It is
an exceedingly quick way of adding multiple cursors to multiple lines.
### Mark many occurrences
;; Mark more like this
(global-set-key (kbd "M-æ") 'mc/mark-all-like-this)
(global-set-key (kbd "C-å") 'mc/mark-previous-like-this)
(global-set-key (kbd "C-æ") 'mc/mark-next-like-this)
(global-set-key (kbd "C-Æ") 'mc/mark-more-like-this-extended)
(global-set-key (kbd "M-å") 'mc/mark-all-in-region)
| Command | Description |
|------------------------------------------|-------------------------------------------------------------------------------------|
| `mc/edit-lines` | Adds one cursor to each line in the current region. |
| `mc/edit-beginnings-of-lines` | Adds a cursor at the start of each line in the current region. |
| `mc/edit-ends-of-lines` | Adds a cursor at the end of each line in the current region. |
| `mc/mark-all-like-this` | Marks all parts of the buffer that matches the current region. |
| `mc/mark-all-words-like-this` | Like `mc/mark-all-like-this` but only for whole words. |
| `mc/mark-all-symbols-like-this` | Like `mc/mark-all-like-this` but only for whole symbols. |
| `mc/mark-all-in-region` | Prompts for a string to match in the region, adding cursors to all of them. |
| `mc/mark-all-like-this-in-defun` | Marks all parts of the current defun that matches the current region. |
| `mc/mark-all-words-like-this-in-defun` | Like `mc/mark-all-like-this-in-defun` but only for whole words. |
| `mc/mark-all-symbols-like-this-in-defun` | Like `mc/mark-all-like-this-in-defun` but only for whole symbols. |
| `mc/mark-all-dwim` | Tries to be smart about marking everything you want. Can be pressed multiple times. |
Okay, yes, I have a crazy norwegian keyboard. Regardless, these will look at
whatever you've got selected at the moment, and mark more places like that in
the buffer.
### Special
| Command | Description |
|---------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `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/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/reverse-regions` | Reverse the order of the marked regions. |
| `mc/vertical-align` | Aligns all cursors vertically with a given CHARACTER to the one with the highest column number (the rightest). (Might not behave as intended if more than one cursors are on the same line.) |
| `mc/vertical-align-with-space` | Aligns all cursors with whitespace like `mc/vertical-align` does. |
## Tips and tricks
- To get out of multiple-cursors-mode, press `<return>` or `C-g`. The latter will
first disable multiple regions before disabling multiple cursors. If you want to
insert a newline in multiple-cursors-mode, use `C-j`.
- `(define-key mc/keymap (kbd "<return>") nil)` will make `<return>` insert a
newline; multiple-cursors-mode can still be disabled with `C-g`.
- 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` 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
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 occurrence
- 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.
- If you get out of multiple-cursors-mode and yank - it will yank only
from the kill-ring of main cursor. To yank from the kill-rings of
every cursor use yank-rectangle, normally found at C-x r y.
- 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.
- 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
when the region is active, you can try [region-bindings-mode](https://github.com/fgallina/region-bindings-mode).
- There is a special hook that is run when the mode is diabled
(which is equivalent to the number of cursors going back to 1):
`multiple-cursors-mode-disabled-hook`
BTW, I highly recommend adding `mc/mark-next-like-this` to a key binding that's
right next to the key for `er/expand-region`.
## Scrolling
### Binding mouse events
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`.
To override a mouse event, you will likely have to also unbind the
`down-mouse` part of the event. Like this:
(global-unset-key (kbd "M-<down-mouse-1>"))
(global-set-key (kbd "M-<mouse-1>") 'mc/add-cursor-on-click)
Or you can do like me and find an unused, but less convenient, binding:
(global-set-key (kbd "C-S-<mouse-1>") 'mc/add-cursor-on-click)
## Unknown commands
@ -84,12 +197,17 @@ the location with:
(setq mc/list-file "/my/preferred/file")
NB! Make sure to do so before requiring multiple-cursors.
It is possible to set multiple-cursors to "run-for-all" for every
command except for those that are listed in `mc/cmds-to-run-once`. To
enable this set `mc/always-run-for-all` to non-nil. Add commands to be
run once to `mc/cmds-to-run-once` in ".mc-lists.el".
## Known limitations
* isearch-forward and isearch-backward aren't supported with multiple cursors.
You should feel free to add a simplified version that can work with it.
* Commands run with `M-x` won't be repeated for all cursors.
If you want this functionality, you can use [phi-search](https://github.com/zk-phi/phi-search).
* All key bindings that refer to lambdas are always run for all cursors. If you
need to limit it, you will have to give it a name.
* Redo might screw with your cursors. Undo works very well.
@ -104,19 +222,35 @@ You'll find the repo at:
https://github.com/magnars/multiple-cursors.el
To fetch the test dependencies:
To fetch the test dependencies, install
[cask](https://github.com/rejeep/cask.el) if you haven't already,
then:
$ cd /path/to/multiple-cursors
$ git submodule update --init
$ cask
Run the tests with:
$ ./util/ecukes/ecukes --graphical
$ ./run-tests.sh
## Contributors
* [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.
* [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`
* [Zach Kost-Smith](https://github.com/smithzvk) added `mc/mark-pop`
* [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.
* [Andrea Orru](https://github.com/AndreaOrru) added `mc/mark-previous-like-this-word`/`-symbol`
Thanks!
## License
Copyright (C) 2012 Magnar Sveen
Copyright (C) 2012-2016 Magnar Sveen
Author: Magnar Sveen <magnars@gmail.com>
Keywords: editing cursors

View File

@ -42,3 +42,99 @@ Feature: Switching from a multiline region to multiple cursors
And I go to the front of the word "long"
And I press "C-S-c C-S-c"
Then I should have 2 cursors
Scenario: Edit without using transient mark mode
Given I turn off transient-mark-mode
And I insert:
"""
hello
there
"""
And I go to the front of the word "hello"
And I set the mark
And I go to the front of the word "there"
And I press "C-S-c C-S-c"
Then I should have 2 cursors
Scenario: Edit default short lines
When I insert:
"""
hello
there
"""
And I go to the end of the word "hello"
And I set the mark
And I go to the end of the word "there"
And I press "C-S-c C-S-c"
And I press "you"
Then I should see:
"""
helloyou
you
thereyou
"""
Scenario: Pad short lines
When I insert:
"""
hello
there
"""
And I go to the end of the word "hello"
And I set the mark
And I go to the end of the word "there"
And I press "M-1 C-S-c C-S-c"
Then I should have 3 cursors
Scenario: Edit padding short lines
When I insert:
"""
hello
there
"""
And I go to the end of the word "hello"
And I set the mark
And I go to the end of the word "there"
And I press "M-1 C-S-c C-S-c"
And I press "you"
Then I should see:
"""
helloyou
you
thereyou
"""
Scenario: Skip short lines
When I insert:
"""
hello
there
"""
And I go to the end of the word "hello"
And I set the mark
And I go to the end of the word "there"
And I press "M-- M-1 C-S-c C-S-c"
Then I should have 2 cursors
Scenario: Edit skipping short lines
When I insert:
"""
hello
there
"""
And I go to the end of the word "hello"
And I set the mark
And I go to the end of the word "there"
And I press "M-- M-1 C-S-c C-S-c"
And I press "you"
Then I should see:
"""
helloyou
thereyou
"""

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
"""

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)"

View File

@ -0,0 +1,40 @@
Feature: Insert increasing numbers
Scenario: Three cursors, 0-1-2
Given I have cursors at "text" in "This text contains the word text thrice (text)"
When I press "H-0"
And I press "SPC"
Then I should see "This 0 text contains the word 1 text thrice (2 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-9 H-0"
And I press "SPC"
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)"
Scenario: Three cursors, 0-1-2, default
Given I have cursors at "text" in "This text contains the word text thrice (text)"
When I set mc/insert-numbers-default to 1
And I press "H-0"
And I press "SPC"
Then I should see "This 1 text contains the word 2 text thrice (3 text)"
Scenario: Three cursors, 9-10-11, default
Given I have cursors at "text" in "This text contains the word text thrice (text)"
When I set mc/insert-numbers-default to 1
And I press "C-9 H-0"
And I press "SPC"
Then I should see "This 9 text contains the word 10 text thrice (11 text)"
Scenario: Three cursors, 9-10-11, default
Given I have cursors at "text" in "This text contains the word text thrice (text)"
When I set mc/insert-numbers-default to 1
And 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)"

View File

@ -0,0 +1,94 @@
Feature: Mark all do-what-I-mean (html)
Background:
Given I turn on html-mode
And I turn on delete-selection-mode
And I insert:
"""
<body>
<div class="abc"> def </div>
<div class="ghi"> jkl </div>
</body>
"""
Scenario: Marks tags in html-mode, from front
When I go to the front of the word "abc"
And I press "M-b"
And I press "M-b"
And I press "M-$"
And I type "h1"
Then I should see:
"""
<body>
<h1 class="abc"> def </h1>
<div class="ghi"> jkl </div>
</body>
"""
Scenario: Marks tags in html-mode, from back
When I go to the end of the word "jkl"
And I press "M-f"
And I press "M-$"
And I type "h1"
Then I should see:
"""
<body>
<div class="abc"> def </div>
<h1 class="ghi"> jkl </h1>
</body>
"""
Scenario: Marks tags in html-mode, from outside front
When I go to the front of the word "abc"
And I press "M-b"
And I press "M-b"
And I press "C-b"
And I press "M-$"
And I type "h1"
Then I should see:
"""
<body>
<h1 class="abc"> def </h1>
<div class="ghi"> jkl </div>
</body>
"""
Scenario: Marks tags in html-mode, from outside back
When I go to the end of the word "jkl"
And I press "M-f"
And I press "C-f"
And I press "M-$"
And I type "h1"
Then I should see:
"""
<body>
<div class="abc"> def </div>
<h1 class="ghi"> jkl </h1>
</body>
"""
Scenario: Marks words in html-mode
When I go to the front of the word "abc"
And I press "M-$"
And I type "def"
Then I should see:
"""
<body>
<div class="def"> def </div>
<div class="ghi"> jkl </div>
</body>
"""
Scenario: Marks words in html-mode
When I go to the front of the word "abc"
And I press "M-$"
And I type "def"
And I press "M-$"
And I type "hah"
Then I should see:
"""
<body>
<div class="hah"> hah </div>
<div class="ghi"> jkl </div>
</body>
"""

View File

@ -0,0 +1,90 @@
Feature: Mark all do-what-I-mean
Background:
Given I turn on emacs-lisp-mode
And I turn on delete-selection-mode
And I insert:
"""
(defun abc (ghi) (message ghi))
(defun def (ghi) (message some-other-ghi))
"""
Scenario: Mark symbols in defun
When I go to the end of the word "abc"
And I press "M-f"
And I press "M-$"
And I type "hmm"
Then I should see:
"""
(defun abc (hmm) (message hmm))
(defun def (ghi) (message some-other-ghi))
"""
When I press "C-g"
And I go to the front of the word "hmm"
And I press "C-$"
And I type "foo"
Then I should see:
"""
(defun abc (foo) (message foo))
(defun def (ghi) (message some-other-ghi))
"""
Scenario: Mark all symbols by pressing twice
When I go to the end of the word "abc"
And I press "M-f"
And I press "M-$"
And I press "M-$"
And I type "hmm"
Then I should see:
"""
(defun abc (hmm) (message hmm))
(defun def (hmm) (message some-other-hmm))
"""
When I press "C-g"
And I press "M->"
And I insert:
"""
(defun def (hmm-hmm) (message hmm))
"""
And I go to the front of the word "hmm"
And I press "C-$"
And I press "C-$"
And I type "humm"
Then I should see:
"""
(defun abc (humm) (message humm))
(defun def (humm) (message some-other-humm))
(defun def (humm-humm) (message humm))
"""
Scenario: Mark dwim from selection
When I press "M-<"
And I press "S-M->"
And I press "C-$ ghi RET"
And I type "xyz"
Then I should see:
"""
(defun abc (xyz) (message xyz))
(defun def (xyz) (message some-other-xyz))
"""
When I press "C-g"
And I go to the front of the word "xyz"
And I press "C-M-SPC"
And I press "C-$"
And I type "foo"
Then I should see:
"""
(defun abc (foo) (message foo))
(defun def (xyz) (message some-other-xyz))
"""
When I press "C-g"
And I press "M-<"
And I press "S-M->"
And I press "C-u C-$"
And I type ";;"
Then I should see:
"""
;;(defun abc (foo) (message foo))
;;(defun def (xyz) (message some-other-xyz))
"""

View File

@ -14,6 +14,14 @@ Feature: Marking multiple parts of the buffer
And I type "sentence"
Then I should see "This sentence has the word sentence in it"
Scenario: Marking next like this, word
Given I turn on delete-selection-mode
When I insert "This text has the word text in it"
And I go to word "text"
And I press "C-S-c C->"
And I type "sentence"
Then I should see "This sentence has the word sentence in it"
Scenario: Skipping a mark
Given I turn on delete-selection-mode
When I insert "Here's text, text and text"
@ -54,6 +62,14 @@ Feature: Marking multiple parts of the buffer
And I type "sentence"
Then I should see "This sentence has the word sentence in it"
Scenario: Marking prev like this, word
Given I turn on delete-selection-mode
When I insert "This text has the word text in it"
And I go to last word "text"
And I press "C-S-c C-<"
And I type "sentence"
Then I should see "This sentence has the word sentence in it"
Scenario: Skipping a prev mark
Given I turn on delete-selection-mode
When I insert "Here's text, text and text"
@ -94,3 +110,51 @@ Feature: Marking multiple parts of the buffer
And I type "more"
Then I should have 2 cursors
And I should see "Here's more, more and text"
Scenario: Marking without an active region
When I insert:
"""
aaa
bbb
ccc
"""
And I go to the front of the word "bbb"
And I press "C->"
And I type "_"
Then I should have 2 cursors
And I should see:
"""
aaa
_bbb
_ccc
"""
Scenario: Increasing number of cursors without an active region
When I insert:
"""
aaa
bbb
ccc
"""
And I go to the front of the word "bbb"
And I press "C->"
And I press "C-<"
And i press "C-f"
And I type "_"
Then I should have 3 cursors
And I should see:
"""
a_aa
b_bb
c_cc
"""
Scenario: Multiple cursor with shift selection
When I insert "This text contains the word text twice"
And I go to the front of the word "text"
And I press "M-S-f"
And I press "C->"
And I press "C-f"
And I press "<deletechar>"
Then I should see "This text ontains the word text wice"

88
features/mark-pop.feature Normal file
View File

@ -0,0 +1,88 @@
Feature: Popping cursors off of the mark stack
Scenario: Single pop
Given I turn off transient-mark-mode
And I insert:
"""
hello
there
"""
And I go to the front of the word "hello"
And I set the mark
And I go to the front of the word "there"
And I press "M-x mc/mark-pop"
Then I should have 2 cursors
Scenario: Multiple pops
Given I turn off transient-mark-mode
And I insert:
"""
hello
there, my friend
"""
And I go to the front of the word "hello"
And I set the mark
And I go to the front of the word "my"
And I set the mark
And I go to the front of the word "friend"
And I press "M-x mc/mark-pop"
And I press "M-x mc/mark-pop"
Then I should have 3 cursors
Scenario: Discard identical mark and point
Given I turn off transient-mark-mode
And I insert:
"""
hello
there, my friend
"""
And I go to the front of the word "hello"
And I set the mark
And I go to the front of the word "my"
And I set the mark
And I go to the front of the word "friend"
And I set the mark
And I press "M-x mc/mark-pop"
And I press "M-x mc/mark-pop"
Then I should have 3 cursors
Scenario: Changing the text
Given I turn off transient-mark-mode
And I insert:
"""
hello
there, my friend
"""
And I go to the front of the word "hello"
And I set the mark
And I go to the front of the word "my"
And I set the mark
And I go to the front of the word "friend"
And I press "M-x mc/mark-pop"
And I press "M-x mc/mark-pop"
And I type "!"
Then I should see:
"""
!hello
there, !my !friend
"""
Scenario: With transient-mark-mode
And I insert:
"""
hello
there, my friend
"""
And I go to the front of the word "hello"
And I press "C-@ C-@"
And I go to the front of the word "my"
And I press "C-@ C-@"
And I go to the front of the word "friend"
And I press "M-x mc/mark-pop"
And I press "M-x mc/mark-pop"
And I type "!"
Then I should see:
"""
!hello
there, !my !friend
"""

View File

@ -0,0 +1,137 @@
Feature: Mark things
Scenario: Mark all symbols like this with select
Given I turn on emacs-lisp-mode
And I turn on delete-selection-mode
And I insert:
"""
(defun abc (ghi) (message ghi))
(defun def (ghi) (message some-other-ghi))
"""
When I select "ghi"
And I mark all symbols like this
And I type "hmm"
Then I should see:
"""
(defun abc (hmm) (message hmm))
(defun def (hmm) (message some-other-ghi))
"""
Scenario: Mark all words like this with select
Given I turn on emacs-lisp-mode
And I turn on delete-selection-mode
And I insert:
"""
(defun abc (ghi) (message ghi))
(defun def (ghi) (message some-other-ghi))
"""
When I select "ghi"
And I mark all words like this
And I type "hmm"
Then I should see:
"""
(defun abc (hmm) (message hmm))
(defun def (hmm) (message some-other-hmm))
"""
Scenario: Mark all symbols like this in defun with select
Given I turn on emacs-lisp-mode
And I turn on delete-selection-mode
And I insert:
"""
(defun abc (ghi) (message ghi))
(defun def (ghi) (message some-other-ghi))
"""
When I select "ghi"
And I mark all symbols like this in defun
And I type "hmm"
Then I should see:
"""
(defun abc (hmm) (message hmm))
(defun def (ghi) (message some-other-ghi))
"""
Scenario: Mark all words like this in defun with select
Given I turn on emacs-lisp-mode
And I turn on delete-selection-mode
And I insert:
"""
(defun abc (ghi) (message ghi))
(defun def (ghi) (message some-other-ghi))
"""
When I select "ghi"
And I mark all words like this in defun
And I type "hmm"
Then I should see:
"""
(defun abc (hmm) (message hmm))
(defun def (ghi) (message some-other-ghi))
"""
Scenario: Mark all symbols like this with no select
Given I turn on emacs-lisp-mode
And I turn on delete-selection-mode
And I insert:
"""
(defun abc (ghi) (message ghi))
(defun def (ghi) (message some-other-ghi))
"""
When I go to word "ghi"
And I mark all symbols like this
And I type "hmm"
Then I should see:
"""
(defun abc (hmm) (message hmm))
(defun def (hmm) (message some-other-ghi))
"""
Scenario: Mark all words like this with no select
Given I turn on emacs-lisp-mode
And I turn on delete-selection-mode
And I insert:
"""
(defun abc (ghi) (message ghi))
(defun def (ghi) (message some-other-ghi))
"""
When I go to word "ghi"
And I mark all words like this
And I type "hmm"
Then I should see:
"""
(defun abc (hmm) (message hmm))
(defun def (hmm) (message some-other-hmm))
"""
Scenario: Mark all symbols like this in defun with no select
Given I turn on emacs-lisp-mode
And I turn on delete-selection-mode
And I insert:
"""
(defun abc (ghi) (message ghi))
(defun def (ghi) (message some-other-ghi))
"""
When I go to word "ghi"
And I mark all symbols like this in defun
And I type "hmm"
Then I should see:
"""
(defun abc (hmm) (message hmm))
(defun def (ghi) (message some-other-ghi))
"""
Scenario: Mark all words like this in defun with no select
Given I turn on emacs-lisp-mode
And I turn on delete-selection-mode
And I insert:
"""
(defun abc (ghi) (message ghi))
(defun def (ghi) (message some-other-ghi))
"""
When I go to word "ghi"
And I mark all words like this in defun
And I type "hmm"
Then I should see:
"""
(defun abc (hmm) (message hmm))
(defun def (ghi) (message some-other-ghi))
"""

View File

@ -50,6 +50,13 @@ Feature: Multiple cursors core
And I press "C-!"
Then I should see "This aatext contains the word aatext twice"
Scenario: Unknown command with multiple read: yes, do for all
Given I have bound C-! to a new command that inserts two read-chars
And I have cursors at "text" in "This text contains the word text twice"
When I press "C-! b c y"
And I press "C-! d e"
Then I should see "This bcdetext contains the word bcdetext twice"
Scenario: Unknown command: no, don't do for all
Given I have bound C-! to another new command that inserts "a"
And I have cursors at "text" in "This text contains the word text twice"
@ -57,6 +64,28 @@ Feature: Multiple cursors core
And I press "C-!"
Then I should see "This aatext contains the word text twice"
Scenario: Multiple supported M-x command (forward-word in this case)
Given I have cursors at "text" in "This text contains the word text twice"
And I type "("
And I press "M-x forward-word"
And I press "M-x forward-word"
And I type ")"
Then I should see "This (text contains) the word (text twice)"
Scenario: Unknown M-x command: yes, do for all
Given I have cursors at "text" in "This text contains the word text twice"
And I press "C-SPC"
And I press "M-f"
And I press "M-x upcase-dwim RET y"
Then I should see "This TEXT contains the word TEXT twice"
Scenario: Unknown M-x command: no, don't do for all
Given I have cursors at "text" in "This text contains the word text twice"
And I press "C-SPC"
And I press "M-f"
And I press "M-x upcase-dwim RET n"
Then I should see "This TEXT contains the word text twice"
Scenario: Undo
Given I have cursors at "text" in "This text contains the word text twice"
When I press "M-f"
@ -115,10 +144,20 @@ Feature: Multiple cursors core
And I go to the front of the word "text"
And I press "C-SPC"
And I press "M-f"
And I press "C->"
And I mark next like this
And I type "!"
Then I should see "This ! contains the word ! twice"
Scenario: wrap-region (function turns to keyboard macros)
Given I turn on wrap-region-mode
And I insert "This text contains the word text twice"
And I go to the front of the word "text"
And I press "C-M-SPC"
And I mark next like this
And I press "C-g"
And I type "("
Then I should see "This (text contains the word (text twice"
Scenario: Bound keyboard macros
Given I have bound C-! to a keyboard macro that insert "_"
And I have cursors at "text" in "This text contains the word text twice"
@ -148,3 +187,31 @@ Feature: Multiple cursors core
contains
twice
"""
Scenario: Looping forwards around cursors
Given I have cursors at "_" in "1_34567_9"
And I press "C-v"
And I press "C-v"
And I press "C-v"
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
Given I have cursors at "_" in "1_34567_9"
And I press "M-v"
And I press "M-v"
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"

View File

@ -0,0 +1,39 @@
Feature: Repeat last interactive command for fake cursors (mc/repeat-command)
Scenario: Clone insert-char from M-x
Given I have cursors at "text" in "This text contains the word text thrice (text)"
When I start an action chain
When I press "M-x"
And I type "insert-char"
And I press "RET"
And I type "21"
And I press "RET"
And I type "n"
And I press "C-:"
And I press "y"
And I execute the action chain
Then I should see "This !text contains the word !text thrice (!text)"
Scenario: Clone insert-char from M-:
Given I have cursors at "text" in "This text contains the word text thrice (text)"
When I start an action chain
When I press "M-:"
And I type "(insert-char (+ 40 2))"
And I press "RET"
And I press "C-:"
And I press "y"
And I execute the action chain
Then I should see "This *text contains the word *text thrice (*text)"
Scenario: Disable prompt
Given I have cursors at "text" in "This text/0000 contains the word text/1111 thrice (text/2222)"
When I set mc/always-repeat-command to t
When I set mc/always-run-for-all to t
When I start an action chain
And I press "M-x"
And I type "zap-to-char"
And I press "RET"
And I press "/"
And I press "C-:"
And I execute the action chain
Then I should see "This 0000 contains the word 1111 thrice (2222)"

View File

@ -0,0 +1,19 @@
Feature: Sorting and reversing cursor regions
Scenario: Reversing regions
Given I have cursors at "text" in "This text contains the word text thrice (text here)"
When I press "M-f"
And I press "C-f"
And I press "C-SPC"
And I press "M-f"
And I press "H-1"
Then I should see "This text here the word text thrice (text contains)"
Scenario: Sorting regions
Given I have cursors at "text" in "This text contains the word text thrice (text here)"
When I press "M-f"
And I press "C-f"
And I press "C-SPC"
And I press "M-f"
And I press "H-2"
Then I should see "This text contains the word text here (text thrice)"

View File

@ -1,29 +1,80 @@
(require 'cl) ;; For lexical-let
(When "^I 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$"
(lambda () (call-interactively 'mc/mark-previous-like-this)))
(When "^I mark previous like this word$"
(lambda () (call-interactively 'mc/mark-previous-like-this-word)))
(When "^I mark previous like this symbol$"
(lambda () (call-interactively 'mc/mark-previous-like-this-symbol)))
(When "^I mark all like this$"
(lambda () (call-interactively 'mc/mark-all-like-this)))
(When "^I mark all like this dwim$"
(lambda () (call-interactively 'mc/mark-all-like-this-dwim)))
(When "^I mark all in region$"
(lambda () (call-interactively 'mc/mark-all-in-region)))
(When "^I insert numbers$"
(lambda () (call-interactively 'mc/insert-numbers)))
(When "^I insert letters$"
(lambda () (call-interactively 'mc/insert-letters)))
(When "^I reverse regions$"
(lambda () (call-interactively 'mc/reverse-regions)))
(When "^I sort regions$"
(lambda () (call-interactively 'mc/sort-regions)))
(When "^I edit lines$"
(lambda () (call-interactively 'mc/edit-lines)))
(When "^I set rectangular region anchor$"
(lambda () (call-interactively 'set-rectangular-region-anchor)))
(And "^delete-selection-mode is active$"
(lambda ()
(delete-selection-mode 1)))
(Given "^I turn off transient-mark-mode$"
(lambda ()
(transient-mark-mode -1)))
(Then "^I should have \\([0-9]+\\) cursors$"
(lambda (num)
(let ((actual (mc/num-cursors)))
(assert (eq (string-to-number num) actual) nil
"Expected to have %s cursors, but was %d." num actual))))
(cl-assert (eq (string-to-number num) actual) nil
"Expected to have %s cursors, but was %d." num actual))))
(Then "^I should have one cursor$"
(lambda ()
(assert (not multiple-cursors-mode) nil
"Expected to have one cursor, but multiple-cursors-mode is still active.")
(assert (eq 1 (mc/num-cursors)) nil
"Expected to have one cursor, but there are still fake cursor overlays.")))
(cl-assert (not multiple-cursors-mode) nil
"Expected to have one cursor, but multiple-cursors-mode is still active.")
(cl-assert (eq 1 (mc/num-cursors)) nil
"Expected to have one cursor, but there are still fake cursor overlays.")))
(Then "^rectangular-region-mode should be off$"
(lambda ()
(assert (not rectangular-region-mode) nil
"Expected rectangular-region-mode mode to be off, but wasn't.")))
(lambda ()
(cl-assert (not rectangular-region-mode) nil
"Expected rectangular-region-mode mode to be off, but wasn't.")))
(Then "^rectangular-region-mode should be on$"
(lambda ()
(assert rectangular-region-mode nil
"Expected rectangular-region-mode mode to be on, but wasn't.")))
(lambda ()
(cl-assert rectangular-region-mode nil
"Expected rectangular-region-mode mode to be on, but wasn't.")))
(When "^I press \"\\(.+\\)\"$"
(lambda (keybinding)
@ -45,6 +96,17 @@
(mc/mark-all-like-this)
(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$"
(lambda (text)
(lexical-let ((text text))
@ -68,6 +130,11 @@
(defun mc-test-temp-command-2 () (interactive) (insert ins))
(global-set-key (kbd "C-!") 'mc-test-temp-command-2))))
(Given "^I have bound C-! to a new command that inserts two read-chars$"
(lambda ()
(defun mc-test-temp-command-3 () (interactive) (insert (read-char "first: ")) (insert (read-char "second: ")))
(global-set-key (kbd "C-!") 'mc-test-temp-command-3)))
(Given "^I have bound C-! to a keyboard macro that insert \"_\"$"
(lambda ()
(fset 'mc-test-temp-kmacro "\C-q_")
@ -78,20 +145,55 @@
(goto-char (point-min))
(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"))
(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 \"\\(.+\\)\"$"
(lambda (pos word)
(goto-char (point-min))
(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"))
(assert search nil message word (espuds-buffer-contents))
(cl-assert search nil message word (espuds-buffer-contents))
(if (string-equal "front" pos) (backward-word)))))
(When "^I go to last word \"\\(.+\\)\"$"
(lambda (text)
(goto-char (point-max))
(let ((search (re-search-backward text nil t)))
(cl-assert search nil "The text '%s' was not found in the current buffer." text))))
(When "^I select the last \"\\(.+\\)\"$"
(lambda (text)
(goto-char (point-max))
(let ((search (re-search-backward text nil t)))
(assert search nil "The text '%s' was not found in the current buffer." text))
(cl-assert search nil "The text '%s' was not found in the current buffer." text))
(set-mark (point))
(re-search-forward text)))
(When "^I mark all \\(.+\\)$"
(lambda (rest)
(let ((func (intern (mapconcat 'identity
(cons "mc/mark-all"
(split-string rest))
"-"))))
(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:

View File

@ -7,10 +7,12 @@
(add-to-list 'load-path multiple-cursors-root-path)
(add-to-list 'load-path multiple-cursors-util-path)
(add-to-list 'load-path (expand-file-name "espuds" multiple-cursors-util-path))
(add-to-list 'load-path (expand-file-name "vendor" multiple-cursors-util-path))
(require 'multiple-cursors)
(require 'espuds)
(require 'ert)
(require 'wrap-region)
(defun mc/save-lists ()) ;; redefine to do nothing when running tests
@ -19,9 +21,19 @@
(multiple-cursors-mode 0)
(rectangular-region-mode 0)
(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-S-c C-<") 'mc/mark-previous-like-this-word)
(global-set-key (kbd "C-S-c M-<") 'mc/mark-previous-like-this-symbol)
(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 "C-$") 'mc/mark-all-dwim)
(global-set-key (kbd "M-#") 'mc/mark-all-in-region)
(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-2") 'mc/sort-regions)
(global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines)
(global-set-key (kbd "H-SPC") 'set-rectangular-region-anchor)
(switch-to-buffer
@ -31,7 +43,10 @@
(cua-mode 0)
(delete-selection-mode 0)
(subword-mode 0)
(wrap-region-mode 0)
(setq set-mark-default-inactive nil)
(deactivate-mark))
(deactivate-mark)
(setq mc/cmds-to-run-for-all nil)
(setq mc/cmds-to-run-once nil))
(After)

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
"""

View File

@ -1,6 +1,6 @@
;;; mc-cycle-cursors.el
;;; mc-cycle-cursors.el -*- lexical-binding: t; -*-
;; Copyright (C) 2012 Magnar Sveen
;; Copyright (C) 2012-2016 Magnar Sveen
;; Author: Magnar Sveen <magnars@gmail.com>
;; Keywords: editing cursors
@ -28,11 +28,9 @@
(require 'multiple-cursors-core)
(eval-when-compile (require 'cl))
(defun mc/next-cursor-after-point ()
(defun mc/next-fake-cursor-after-point ()
(let ((pos (point))
(next-pos (point-max))
(next-pos (1+ (point-max)))
next)
(mc/for-each-fake-cursor
(let ((cursor-pos (overlay-get cursor 'point)))
@ -42,9 +40,9 @@
(setq next cursor))))
next))
(defun mc/prev-cursor-before-point ()
(defun mc/prev-fake-cursor-before-point ()
(let ((pos (point))
(prev-pos (point-min))
(prev-pos (1- (point-min)))
prev)
(mc/for-each-fake-cursor
(let ((cursor-pos (overlay-get cursor 'point)))
@ -54,27 +52,72 @@
(setq prev cursor))))
prev))
(defcustom mc/cycle-looping-behaviour 'continue
"What to do if asked to cycle beyond the last cursor or before the first cursor."
:type '(radio (const :tag "Loop around to beginning/end of document." continue)
(const :tag "Warn and then loop around." warn)
(const :tag "Signal an error." error)
(const :tag "Don't loop." stop))
:group 'multiple-cursors)
(defun mc/handle-loop-condition (error-message)
(cl-ecase mc/cycle-looping-behaviour
(error (error error-message))
(warn (message error-message))
(continue 'continue)
(stop 'stop)))
(defun mc/first-fake-cursor-after (point)
"Very similar to mc/furthest-cursor-before-point, but ignores (mark) and (point)."
(let* ((cursors (mc/all-fake-cursors))
(cursors-after-point (cl-remove-if (lambda (cursor)
(< (mc/cursor-beg cursor) point))
cursors))
(cursors-in-order (cl-sort cursors-after-point '< :key 'mc/cursor-beg)))
(car cursors-in-order)))
(defun mc/last-fake-cursor-before (point)
"Very similar to mc/furthest-cursor-before-point, but ignores (mark) and (point)."
(let* ((cursors (mc/all-fake-cursors))
(cursors-before-point (cl-remove-if (lambda (cursor)
(> (mc/cursor-end cursor) point))
cursors))
(cursors-in-order (cl-sort cursors-before-point '> :key 'mc/cursor-end)))
(car cursors-in-order)))
(cl-defun mc/cycle (next-cursor fallback-cursor loop-message)
(when (null next-cursor)
(when (eql 'stop (mc/handle-loop-condition loop-message))
(cond
((fboundp 'cl-return-from)
(cl-return-from mc/cycle nil))
((fboundp 'return-from)
(cl-return-from mc/cycle nil))))
(setf next-cursor fallback-cursor))
(mc/create-fake-cursor-at-point)
(mc/pop-state-from-overlay next-cursor)
(recenter))
(defun mc/cycle-forward ()
(interactive)
(let ((next-cursor (mc/next-cursor-after-point)))
(unless next-cursor
(error "We're already at the last cursor"))
(mc/create-fake-cursor-at-point)
(mc/pop-state-from-overlay next-cursor)
(recenter)))
(mc/cycle (mc/next-fake-cursor-after-point)
(mc/first-fake-cursor-after (point-min))
"We're already at the last cursor."))
(defun mc/cycle-backward ()
(interactive)
(let ((prev-cursor (mc/prev-cursor-before-point)))
(unless prev-cursor
(error "We're already at the first cursor"))
(mc/create-fake-cursor-at-point)
(mc/pop-state-from-overlay prev-cursor)
(recenter)))
(mc/cycle (mc/prev-fake-cursor-before-point)
(mc/last-fake-cursor-before (point-max))
"We're already at the last cursor"))
(define-key mc/keymap (kbd "C-v") 'mc/cycle-forward)
(define-key mc/keymap (kbd "M-v") 'mc/cycle-backward)
(provide 'mc-cycle-cursors)
;; Local Variables:
;; coding: utf-8
;; End:
;;; mc-cycle-cursors.el ends here

View File

@ -1,6 +1,6 @@
;;; mc-edit-lines.el
;;; mc-edit-lines.el -*- lexical-binding: t; -*-
;; Copyright (C) 2012 Magnar Sveen
;; Copyright (C) 2012-2016 Magnar Sveen
;; Author: Magnar Sveen <magnars@gmail.com>
;; Keywords: editing cursors
@ -29,26 +29,65 @@
(require 'multiple-cursors-core)
(defcustom mc/edit-lines-empty-lines nil
"What should be done by `mc/edit-lines' when a line is not long enough."
:type '(radio (const :tag "Pad the line with spaces." pad)
(const :tag "Ignore the line." ignore)
(const :tag "Signal an error." error)
(const :tag "Nothing. Cursor is at end of line." nil))
:group 'multiple-cursors)
;;;###autoload
(defun mc/edit-lines ()
(defun mc/edit-lines (&optional arg)
"Add one cursor to each line of the active region.
Starts from mark and moves in straight down or up towards the
line point is on."
(interactive)
(when (not (use-region-p))
(error "Mark a set of lines first."))
line point is on.
What is done with lines which are not long enough is governed by
`mc/edit-lines-empty-lines'. The prefix argument ARG can be used
to override this. If ARG is a symbol (when called from Lisp),
that symbol is used instead of `mc/edit-lines-empty-lines'.
Otherwise, if ARG negative, short lines will be ignored. Any
other non-nil value will cause short lines to be padded."
(interactive "P")
(unless mark-active
(error "Mark a set of lines first"))
(mc/remove-fake-cursors)
(let* ((col (current-column))
(point-line (line-number-at-pos))
(mark-line (progn (exchange-point-and-mark) (line-number-at-pos)))
(direction (if (< point-line mark-line) :up :down)))
(point-line (mc/line-number-at-pos))
(mark-line (progn (exchange-point-and-mark) (mc/line-number-at-pos)))
(direction (if (< point-line mark-line) :up :down))
(style (cond
;; called from lisp
((and arg (symbolp arg))
arg)
;; negative argument
((< (prefix-numeric-value arg) 0)
'ignore)
(arg 'pad)
(t mc/edit-lines-empty-lines))))
(deactivate-mark)
(when (and (eq direction :up) (bolp))
(forward-line -1)
(previous-logical-line 1 nil)
(move-to-column col))
(while (not (eq (line-number-at-pos) point-line))
(mc/create-fake-cursor-at-point)
(if (eq direction :up) (forward-line -1) (forward-line 1))
;; Add the cursors
(while (not (eq (mc/line-number-at-pos) point-line))
;; Pad the line
(when (eq style 'pad)
(while (< (current-column) col)
(insert " ")))
;; Error
(when (and (eq style 'error)
(not (equal col (current-column))))
(error "Short line encountered in `mc/edit-lines'"))
;; create the cursor
(unless (and (eq style 'ignore)
(not (equal col (current-column))))
(mc/create-fake-cursor-at-point))
;; proceed to next
(if (eq direction :up)
(previous-logical-line 1 nil)
(next-logical-line 1 nil))
(move-to-column col))
(multiple-cursors-mode)))
@ -57,16 +96,14 @@ line point is on."
"Add one cursor to the end of each line in the active region."
(interactive)
(mc/edit-lines)
(mc/execute-command-for-all-fake-cursors 'end-of-line)
(end-of-line))
(mc/execute-command-for-all-cursors 'end-of-line))
;;;###autoload
(defun mc/edit-beginnings-of-lines ()
"Add one cursor to the beginning of each line in the active region."
(interactive)
(mc/edit-lines)
(mc/execute-command-for-all-fake-cursors 'beginning-of-line)
(beginning-of-line))
(mc/execute-command-for-all-cursors 'beginning-of-line))
(provide 'mc-edit-lines)

View File

@ -0,0 +1,109 @@
;;; mc-hide-unmatched-lines-mode.el -*- lexical-binding: t; -*-
;; 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\""
:init-value nil
:lighter " hu"
:keymap 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 instead of hidden 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))
(define-key mc/keymap (kbd "C-'") 'mc-hide-unmatched-lines-mode)
(provide 'mc-hide-unmatched-lines-mode)

View File

@ -1,6 +1,6 @@
;;; mc-mark-more.el
;;; mc-mark-more.el -*- lexical-binding: t; -*-
;; Copyright (C) 2012 Magnar Sveen
;; Copyright (C) 2012-2016 Magnar Sveen
;; Author: Magnar Sveen <magnars@gmail.com>
;; Keywords: editing cursors
@ -28,6 +28,8 @@
;;; Code:
(require 'multiple-cursors-core)
(require 'thingatpt)
(require 'sgml-mode)
(defun mc/cursor-end (cursor)
(if (overlay-get cursor 'mark-active)
@ -54,7 +56,7 @@
beg))
(defun mc/furthest-cursor-before-point ()
(let ((beg (min (mark) (point)))
(let ((beg (if mark-active (min (mark) (point)) (point)))
furthest)
(mc/for-each-fake-cursor
(when (< (mc/cursor-beg cursor) beg)
@ -63,7 +65,7 @@
furthest))
(defun mc/furthest-cursor-after-point ()
(let ((end (max (mark) (point)))
(let ((end (if mark-active (max (mark) (point)) (point)))
furthest)
(mc/for-each-fake-cursor
(when (> (mc/cursor-end cursor) end)
@ -71,6 +73,18 @@
(setq furthest cursor)))
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 ()
(let ((strings (list (buffer-substring-no-properties (point) (mark)))))
(mc/for-each-fake-cursor
@ -79,63 +93,273 @@
(mc/cursor-end cursor))))
strings))
(defvar mc/enclose-search-term nil
"How should mc/mark-more-* search for more matches?
Match everything: nil
Match only whole words: \\='words
Match only whole symbols: \\='symbols
Use like case-fold-search, don't recommend setting it globally.")
(defun mc/mark-more-like-this (skip-last direction)
(let ((case-fold-search nil)
(re (regexp-opt (mc/region-strings) mc/enclose-search-term))
(point-out-of-order (cl-ecase direction
(forwards (< (point) (mark)))
(backwards (not (< (point) (mark))))))
(furthest-cursor (cl-ecase direction
(forwards (mc/furthest-cursor-after-point))
(backwards (mc/furthest-cursor-before-point))))
(start-char (cl-ecase direction
(forwards (mc/furthest-region-end))
(backwards (mc/first-region-start))))
(search-function (cl-ecase direction
(forwards 'search-forward-regexp)
(backwards 'search-backward-regexp)))
(match-point-getter (cl-ecase direction
(forwards 'match-beginning)
(backwards 'match-end))))
(if (and skip-last (not furthest-cursor))
(error "No cursors to be skipped")
(mc/save-excursion
(goto-char start-char)
(when skip-last
(mc/remove-fake-cursor furthest-cursor))
(if (funcall search-function re nil t)
(progn
(push-mark (funcall match-point-getter 0))
(when point-out-of-order
(exchange-point-and-mark))
(mc/create-fake-cursor-at-point))
(user-error "no more matches found."))))))
;;;###autoload
(defun mc/mark-next-like-this (arg)
"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 zero ARG, skip the last one and mark next."
(interactive "p")
(unless (region-active-p)
(error "Mark a region to match first."))
(when (< arg 0)
(mc/remove-fake-cursor (mc/furthest-cursor-after-point)))
(when (>= arg 0)
(let ((case-fold-search nil)
(point-first (< (point) (mark)))
(re (regexp-opt (mc/region-strings)))
(furthest-cursor (mc/furthest-cursor-after-point)))
(mc/save-excursion
(goto-char (mc/furthest-region-end))
(when (= arg 0)
(mc/remove-fake-cursor furthest-cursor))
(if (search-forward-regexp re nil t)
(progn
(push-mark (match-beginning 0))
(when point-first (exchange-point-and-mark))
(mc/create-fake-cursor-at-point))
(error "no more found forward")))))
(if (> (mc/num-cursors) 1)
(multiple-cursors-mode 1)
(multiple-cursors-mode 0)))
(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/mark-lines arg 'forwards)))
(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
(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
With negative ARG, delete the last one instead.
With zero ARG, skip the last one and mark next."
(interactive "p")
(let ((mc/enclose-search-term 'words))
(mc/mark-next-like-this arg)))
;;;###autoload
(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
With negative ARG, delete the last one instead.
With zero ARG, skip the last one and mark next."
(interactive "p")
(let ((mc/enclose-search-term 'symbols))
(mc/mark-next-like-this arg)))
;;;###autoload
(defun mc/mark-previous-like-this (arg)
"Find and mark the previous part of the buffer matching the currently active region
"Find and mark the previous part of the buffer matching the
currently active region.
If no region is active ,add a cursor on the previous line.
With negative ARG, delete the last one instead.
With zero ARG, skip the last one and mark next."
(interactive "p")
(unless (region-active-p)
(error "Mark a region to match first."))
(when (< arg 0)
(mc/remove-fake-cursor (mc/furthest-cursor-before-point)))
(when (>= arg 0)
(let ((case-fold-search nil)
(point-first (< (point) (mark)))
(re (regexp-opt (mc/region-strings)))
(furthest-cursor (mc/furthest-cursor-before-point)))
(mc/save-excursion
(goto-char (mc/first-region-start))
(when (= arg 0)
(mc/remove-fake-cursor furthest-cursor))
(if (search-backward-regexp re nil t)
(progn
(push-mark (match-end 0))
(unless point-first (exchange-point-and-mark))
(mc/create-fake-cursor-at-point))
(error "no more found backward")))))
(if (> (mc/num-cursors) 1)
(multiple-cursors-mode 1)
(multiple-cursors-mode 0)))
(if (< arg 0)
(let ((cursor (mc/furthest-cursor-before-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) 'backwards)
(mc/mark-lines arg 'backwards)))
(mc/maybe-multiple-cursors-mode))
;;;###autoload
(defun mc/mark-previous-like-this-word (arg)
"Find and mark the previous part of the buffer matching the
currently active region.
If no region is active, mark the word at the point and find the
previous match.
With negative ARG, delete the last one instead.
With zero ARG, skip the last one and mark previous."
(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) 'backwards)
(mc--select-thing-at-point 'word)
(mc/mark-more-like-this (= arg 0) 'backwards)))
(mc/maybe-multiple-cursors-mode))
(defun mc/mark-previous-like-this-symbol (arg)
"Find and mark the previous part of the buffer matching the
currently active region.
If no region is active, mark the symbol at the point and find the
previous match.
With negative ARG, delete the last one instead.
With zero ARG, skip the last one and mark previous."
(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) 'backwards)
(mc--select-thing-at-point 'symbol)
(mc/mark-more-like-this (= arg 0) 'backwards)))
(mc/maybe-multiple-cursors-mode))
;;;###autoload
(defun mc/mark-previous-word-like-this (arg)
"Find and mark the previous part 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 previous line.
With negative ARG, delete the last one instead.
With zero ARG, skip the last one and mark next."
(interactive "p")
(let ((mc/enclose-search-term 'words))
(mc/mark-previous-like-this arg)))
;;;###autoload
(defun mc/mark-previous-symbol-like-this (arg)
"Find and mark the previous part 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 previous line.
With negative ARG, delete the last one instead.
With zero ARG, skip the last one and mark next."
(interactive "p")
(let ((mc/enclose-search-term 'symbols))
(mc/mark-previous-like-this arg)))
(defun mc/mark-lines (num-lines direction)
(dotimes (i (if (= num-lines 0) 1 num-lines))
(mc/save-excursion
(let ((furthest-cursor (cl-ecase direction
(forwards (mc/furthest-cursor-after-point))
(backwards (mc/furthest-cursor-before-point)))))
(when (overlayp furthest-cursor)
(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
(defun mc/mark-next-lines (arg)
(interactive "p")
(mc/mark-lines arg 'forwards)
(mc/maybe-multiple-cursors-mode))
;;;###autoload
(defun mc/mark-previous-lines (arg)
(interactive "p")
(mc/mark-lines arg 'backwards)
(mc/maybe-multiple-cursors-mode))
;;;###autoload
(defun mc/unmark-next-like-this ()
"Deselect next part of the buffer matching the currently active region."
(interactive)
(mc/mark-next-like-this -1))
;;;###autoload
(defun mc/unmark-previous-like-this ()
"Deselect prev part of the buffer matching the currently active region."
(interactive)
(mc/mark-previous-like-this -1))
;;;###autoload
(defun mc/skip-to-next-like-this ()
"Skip the current one and select the next part of the buffer
matching the currently active region."
(interactive)
(mc/mark-next-like-this 0))
;;;###autoload
(defun mc/skip-to-previous-like-this ()
"Skip the current one and select the prev part of the buffer
matching the currently active region."
(interactive)
(mc/mark-previous-like-this 0))
;;;###autoload
(defun mc/mark-all-like-this ()
@ -147,7 +371,7 @@ With zero ARG, skip the last one and mark next."
(let ((master (point))
(case-fold-search nil)
(point-first (< (point) (mark)))
(re (regexp-opt (mc/region-strings))))
(re (regexp-opt (mc/region-strings) mc/enclose-search-term)))
(mc/save-excursion
(goto-char 0)
(while (search-forward-regexp re nil t)
@ -158,73 +382,358 @@ With zero ARG, skip the last one and mark next."
(when point-first (exchange-point-and-mark)))))
(if (> (mc/num-cursors) 1)
(multiple-cursors-mode 1)
(multiple-cursors-mode 0)))
(mc/disable-multiple-cursors-mode)))
(defun mc--select-thing-at-point (thing)
(let ((bound (bounds-of-thing-at-point thing)))
(when bound
(set-mark (car bound))
(goto-char (cdr bound))
bound)))
(defun mc--select-thing-at-point-or-bark (thing)
(unless (or (region-active-p) (mc--select-thing-at-point thing))
(error "Mark a region or set cursor on a %s." thing)))
;;;###autoload
(defun mc/mark-all-in-region (beg end)
(defun mc/mark-all-words-like-this ()
(interactive)
(mc--select-thing-at-point-or-bark 'word)
(let ((mc/enclose-search-term 'words))
(mc/mark-all-like-this)))
;;;###autoload
(defun mc/mark-all-symbols-like-this ()
(interactive)
(mc--select-thing-at-point-or-bark 'symbol)
(let ((mc/enclose-search-term 'symbols))
(mc/mark-all-like-this)))
;;;###autoload
(defun mc/mark-all-in-region (beg end &optional search)
"Find and mark all the parts in the region matching the given search"
(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))
(mc/remove-fake-cursors)
(goto-char beg)
(while (search-forward search end t)
(push-mark (match-beginning 0))
(mc/create-fake-cursor-at-point))
(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)))
(if (string= search "")
(message "Mark aborted")
(progn
(mc/remove-fake-cursors)
(goto-char beg)
(let ((lastmatch))
(while (search-forward search end t)
(push-mark (match-beginning 0))
(mc/create-fake-cursor-at-point)
(setq lastmatch t))
(unless lastmatch
(error "Search failed for %S" search)))
(goto-char (match-end 0))
(if (< (mc/num-cursors) 3)
(mc/disable-multiple-cursors-mode)
(mc/pop-state-from-overlay (mc/furthest-cursor-before-point))
(multiple-cursors-mode 1))))))
;;;###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)))
(unless lastmatch
(error "Search failed for %S" search)))
(goto-char (match-end 0))
(if (< (mc/num-cursors) 3)
(mc/disable-multiple-cursors-mode)
(mc/pop-state-from-overlay (mc/furthest-cursor-before-point))
(multiple-cursors-mode 1))))))
(when (not (fboundp 'set-temporary-overlay-map))
;; Backport this function from newer emacs versions
(defun set-temporary-overlay-map (map &optional keep-pred)
"Set a new keymap that will only exist for a short period of time.
The new keymap to use must be given in the MAP variable. When to
remove the keymap depends on user input and KEEP-PRED:
- if KEEP-PRED is nil (the default), the keymap disappears as
soon as any key is pressed, whether or not the key is in MAP;
- if KEEP-PRED is t, the keymap disappears as soon as a key *not*
in MAP is pressed;
- otherwise, KEEP-PRED must be a 0-arguments predicate that will
decide if the keymap should be removed (if predicate returns
nil) or kept (otherwise). The predicate will be called after
each key sequence."
(let* ((clearfunsym (make-symbol "clear-temporary-overlay-map"))
(overlaysym (make-symbol "t"))
(alist (list (cons overlaysym map)))
(clearfun
`(lambda ()
(unless ,(cond ((null keep-pred) nil)
((eq t keep-pred)
`(eq this-command
(lookup-key ',map
(this-command-keys-vector))))
(t `(funcall ',keep-pred)))
(remove-hook 'pre-command-hook ',clearfunsym)
(setq emulation-mode-map-alists
(delq ',alist emulation-mode-map-alists))))))
(set overlaysym overlaysym)
(fset clearfunsym clearfun)
(add-hook 'pre-command-hook clearfunsym)
(push alist emulation-mode-map-alists))))
(defvar mc/mark-more-like-this-extended-keymap (make-sparse-keymap))
(define-key mc/mark-more-like-this-extended-keymap (kbd "<up>") 'mc/mmlte--up)
(define-key mc/mark-more-like-this-extended-keymap (kbd "<down>") 'mc/mmlte--down)
(define-key mc/mark-more-like-this-extended-keymap (kbd "<left>") 'mc/mmlte--left)
(define-key mc/mark-more-like-this-extended-keymap (kbd "<right>") 'mc/mmlte--right)
;;;###autoload
(defun mc/mark-more-like-this-extended ()
"Like mark-more-like-this, but then lets you adjust with arrows key.
The actual adjustment made depends on the final component of the
key-binding used to invoke the command, with all modifiers removed:
"Like mark-more-like-this, but then lets you adjust with arrow keys.
The adjustments work like this:
<up> Mark previous like this
<down> Mark next like this
<left> If last was previous, skip it
If last was next, remove it
<right> If last was next, skip it
If last was previous, remove it
<up> Mark previous like this and set direction to \\='up
<down> Mark next like this and set direction to \\='down
Then, continue to read input events and further add or move marks
as long as the input event read (with all modifiers removed)
is one of the above."
If direction is \\='up:
<left> Skip past the cursor furthest up
<right> Remove the cursor furthest up
If direction is \\='down:
<left> Remove the cursor furthest down
<right> Skip past the cursor furthest down
The bindings for these commands can be changed.
See `mc/mark-more-like-this-extended-keymap'."
(interactive)
(let ((first t)
(ev last-command-event)
(cmd 'mc/mark-next-like-this)
(arg 1)
last echo-keystrokes)
(while cmd
(let ((base (event-basic-type ev)))
(cond ((eq base 'left)
(if (eq last 'mc/mark-previous-like-this)
(setq cmd last arg 0)
(setq cmd 'mc/mark-next-like-this arg -1)))
((eq base 'up)
(setq cmd 'mc/mark-previous-like-this arg 1))
((eq base 'right)
(if (eq last 'mc/mark-next-like-this)
(setq cmd last arg 0)
(setq cmd 'mc/mark-previous-like-this arg -1)))
((eq base 'down)
(setq cmd 'mc/mark-next-like-this arg 1))
(first
(setq cmd 'mc/mark-next-like-this arg 1))
(t
(setq cmd nil))))
(when cmd
(ignore-errors
(funcall cmd arg))
(setq first nil last cmd)
(setq ev (read-event "Use arrow keys for more marks: "))))
(push ev unread-command-events)))
(mc/mmlte--down)
(set-transient-map mc/mark-more-like-this-extended-keymap t))
(defvar mc/mark-more-like-this-extended-direction nil
"When using mc/mark-more-like-this-extended
are we working on the next or previous cursors?")
(make-variable-buffer-local 'mc/mark-more-like-this-extended)
(defun mc/mmlte--message ()
(if (eq mc/mark-more-like-this-extended-direction 'up)
(message "<up> to mark previous, <left> to skip, <right> to remove, <down> to mark next")
(message "<down> to mark next, <right> to skip, <left> to remove, <up> to mark previous")))
(defun mc/mmlte--up ()
(interactive)
(mc/mark-previous-like-this 1)
(setq mc/mark-more-like-this-extended-direction 'up)
(mc/mmlte--message))
(defun mc/mmlte--down ()
(interactive)
(mc/mark-next-like-this 1)
(setq mc/mark-more-like-this-extended-direction 'down)
(mc/mmlte--message))
(defun mc/mmlte--left ()
(interactive)
(if (eq mc/mark-more-like-this-extended-direction 'down)
(mc/unmark-next-like-this)
(mc/skip-to-previous-like-this))
(mc/mmlte--message))
(defun mc/mmlte--right ()
(interactive)
(if (eq mc/mark-more-like-this-extended-direction 'up)
(mc/unmark-previous-like-this)
(mc/skip-to-next-like-this))
(mc/mmlte--message))
(defvar mc--restrict-mark-all-to-symbols nil)
;;;###autoload
(defun mc/mark-all-like-this-dwim (arg)
"Tries to guess what you want to mark all of.
Can be pressed multiple times to increase selection.
With prefix, it behaves the same as original `mc/mark-all-like-this'"
(interactive "P")
(if arg
(mc/mark-all-like-this)
(if (and (not (use-region-p))
(derived-mode-p 'sgml-mode)
(mc--on-tag-name-p))
(mc/mark-sgml-tag-pair)
(let ((before (mc/num-cursors)))
(unless (eq last-command 'mc/mark-all-like-this-dwim)
(setq mc--restrict-mark-all-to-symbols nil))
(unless (use-region-p)
(mc--mark-symbol-at-point)
(setq mc--restrict-mark-all-to-symbols t))
(if mc--restrict-mark-all-to-symbols
(mc/mark-all-symbols-like-this-in-defun)
(mc/mark-all-like-this-in-defun))
(when (<= (mc/num-cursors) before)
(if mc--restrict-mark-all-to-symbols
(mc/mark-all-symbols-like-this)
(mc/mark-all-like-this)))
(when (<= (mc/num-cursors) before)
(mc/mark-all-like-this))))))
;;;###autoload
(defun mc/mark-all-dwim (arg)
"Tries even harder to guess what you want to mark all of.
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
`mc/edit-lines' instead.
If the region is inactive or on a single line, it will behave like
`mc/mark-all-like-this-dwim'."
(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)))))
(if arg
(call-interactively 'mc/edit-lines)
(call-interactively 'mc/mark-all-in-region))
(progn
(setq this-command 'mc/mark-all-like-this-dwim)
(mc/mark-all-like-this-dwim arg))))
(defun mc--in-defun ()
(bounds-of-thing-at-point 'defun))
;;;###autoload
(defun mc/mark-all-like-this-in-defun ()
"Mark all like this in defun."
(interactive)
(if (mc--in-defun)
(save-restriction
(widen)
(narrow-to-defun)
(mc/mark-all-like-this))
(mc/mark-all-like-this)))
;;;###autoload
(defun mc/mark-all-words-like-this-in-defun ()
"Mark all words like this in defun."
(interactive)
(mc--select-thing-at-point-or-bark 'word)
(if (mc--in-defun)
(save-restriction
(widen)
(narrow-to-defun)
(mc/mark-all-words-like-this))
(mc/mark-all-words-like-this)))
;;;###autoload
(defun mc/mark-all-symbols-like-this-in-defun ()
"Mark all symbols like this in defun."
(interactive)
(mc--select-thing-at-point-or-bark 'symbol)
(if (mc--in-defun)
(save-restriction
(widen)
(narrow-to-defun)
(mc/mark-all-symbols-like-this))
(mc/mark-all-symbols-like-this)))
(defun mc--mark-symbol-at-point ()
"Select the symbol under cursor"
(interactive)
(when (not (use-region-p))
(let ((b (bounds-of-thing-at-point 'symbol)))
(goto-char (car b))
(set-mark (cdr b)))))
(defun mc--get-nice-sgml-context ()
(car
(last
(progn
(when (looking-at "<") (forward-char 1))
(when (looking-back ">" 1) (forward-char -1))
(sgml-get-context)))))
(defun mc--on-tag-name-p ()
(let* ((context (save-excursion (mc--get-nice-sgml-context)))
(tag-name-len (length (aref context 4)))
(beg (aref context 2))
(end (+ beg tag-name-len (if (eq 'open (aref context 1)) 1 3))))
(and context
(>= (point) beg)
(<= (point) end))))
;;;###autoload
(defun mc/toggle-cursor-on-click (event)
"Add a cursor where you click, or remove a fake cursor that is
already there."
(interactive "e")
(mouse-minibuffer-check event)
;; Use event-end in case called from mouse-drag-region.
;; If EVENT is a click, event-end and event-start give same value.
(let ((position (event-end event)))
(if (not (windowp (posn-window position)))
(error "Position not in text area of window"))
(select-window (posn-window position))
(let ((pt (posn-point position)))
(if (numberp pt)
;; is there a fake cursor with the actual *point* right where we are?
(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)))
;;;###autoload
(defalias 'mc/add-cursor-on-click 'mc/toggle-cursor-on-click)
;;;###autoload
(defun mc/mark-sgml-tag-pair ()
"Mark the tag we're in and its pair for renaming."
(interactive)
(when (not (mc--inside-tag-p))
(error "Place point inside tag to rename."))
(let ((context (mc--get-nice-sgml-context)))
(if (looking-at "</")
(setq context (car (last (sgml-get-context)))))
(goto-char (aref context 2))
(let* ((tag-name (aref context 4))
(num-chars (length tag-name))
(master-start (1+ (point)))
(mirror-end (save-excursion
(sgml-skip-tag-forward 1)
(1- (point)))))
(goto-char (- mirror-end num-chars))
(set-mark mirror-end)
(mc/create-fake-cursor-at-point)
(goto-char master-start)
(set-mark (+ (point) num-chars))))
(mc/maybe-multiple-cursors-mode))
(defun mc--inside-tag-p ()
(save-excursion
(not (null (sgml-get-context)))))
(provide 'mc-mark-more)

22
mc-mark-pop.el Normal file
View File

@ -0,0 +1,22 @@
;;; mc-mark-pop.el --- Pop cursors off of the mark stack -*- lexical-binding: t; -*-
(require 'multiple-cursors-core)
;;;###autoload
(defun mc/mark-pop ()
"Add a cursor at the current point, pop off mark ring and jump
to the popped mark."
(interactive)
;; If the mark happens to be at the current point, just pop that one off.
(while (eql (mark) (point))
(pop-mark))
(mc/create-fake-cursor-at-point)
(exchange-point-and-mark)
(pop-mark)
(mc/maybe-multiple-cursors-mode))
;; A good key binding for this feature is perhaps "C-S-p" ('p' for pop).
(provide 'mc-mark-pop)
;;; mc-mark-pop.el ends here

151
mc-separate-operations.el Normal file
View File

@ -0,0 +1,151 @@
;;; mc-separate-operations.el - functions that work differently on each cursor -*- lexical-binding: t; -*-
;; Copyright (C) 2012-2016 Magnar Sveen
;; Author: Magnar Sveen <magnars@gmail.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 file contains functions that work differently on each cursor,
;; instead of treating all of them the same.
;; Please see multiple-cursors.el for more commentary.
;;; Code:
(require 'multiple-cursors-core)
(defcustom mc/insert-numbers-default 0
"The default number at which to start counting for
`mc/insert-numbers'"
:type 'integer
:group 'multiple-cursors)
(defvar mc--insert-numbers-number 0)
;;;###autoload
(defun mc/insert-numbers (arg)
"Insert increasing numbers for each cursor, starting at
`mc/insert-numbers-default' or ARG."
(interactive "P")
(setq mc--insert-numbers-number (or (and arg (prefix-numeric-value arg))
mc/insert-numbers-default))
(mc/for-each-cursor-ordered
(mc/execute-command-for-fake-cursor 'mc--insert-number-and-increase cursor)))
(defun mc--insert-number-and-increase ()
(interactive)
(insert (number-to-string mc--insert-numbers-number))
(setq mc--insert-numbers-number (1+ mc--insert-numbers-number)))
(defun mc--ordered-region-strings ()
(let (strings)
(save-excursion
(mc/for-each-cursor-ordered
(setq strings (cons (buffer-substring-no-properties
(mc/cursor-beg cursor)
(mc/cursor-end cursor)) strings))))
(nreverse strings)))
(defvar mc--insert-letters-number 0)
;;;###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)))
(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)
(defun mc--replace-region-strings-1 ()
(interactive)
(delete-region (region-beginning) (region-end))
(save-excursion (insert (car mc--strings-to-replace)))
(setq mc--strings-to-replace (cdr mc--strings-to-replace)))
(defun mc--replace-region-strings ()
(mc/for-each-cursor-ordered
(mc/execute-command-for-fake-cursor 'mc--replace-region-strings-1 cursor)))
;;;###autoload
(defun mc/reverse-regions ()
(interactive)
(if (not multiple-cursors-mode)
(progn
(mc/mark-next-lines 1)
(mc/reverse-regions)
(mc/disable-multiple-cursors-mode)
)
(unless (use-region-p)
(mc/execute-command-for-all-cursors 'mark-sexp))
(setq mc--strings-to-replace (nreverse (mc--ordered-region-strings)))
(mc--replace-region-strings)))
;;;###autoload
(defun mc/sort-regions ()
(interactive)
(unless (use-region-p)
(mc/execute-command-for-all-cursors 'mark-sexp))
(setq mc--strings-to-replace (sort (mc--ordered-region-strings) 'string<))
(mc--replace-region-strings))
;;;###autoload
(defun mc/vertical-align (character)
"Aligns all cursors vertically with a given CHARACTER to the one with the
highest column 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)
;;; mc-separate-operations.el ends here

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +0,0 @@
(define-package "multiple-cursors" "1.1.3"
"Multiple cursors for Emacs.")

View File

@ -1,9 +1,12 @@
;;; multiple-cursors.el --- An experiment in multiple cursors for emacs.
;;; multiple-cursors.el --- Multiple cursors for emacs. -*- lexical-binding: t; -*-
;; Copyright (C) 2012 Magnar Sveen
;; Copyright (C) 2012-2016 Magnar Sveen
;; Author: Magnar Sveen <magnars@gmail.com>
;; Package-Version: 1.5.0
;; Package-Requires: ((cl-lib "0.5"))
;; Keywords: editing cursors
;; Homepage: https://github.com/magnars/multiple-cursors.el
;; 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
@ -21,114 +24,178 @@
;;; Commentary:
;; 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 though, I've been using it since 2011 with
;; great success and much merriment.
;;
;; ## Basic usage
;;
;; Start out with:
;;
;; (require 'multiple-cursors)
;;
;; Then you have to set up your keybindings - multiple-cursors doesn't presume to
;; know how you'd like them laid out. Here are some examples:
;; When you have an active region that spans multiple lines, the following will
;; add a cursor to each line:
;;
;; (global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines)
;;
;; When you want to add multiple cursors not based on continuous lines, but based on
;; keywords in the buffer, use:
;;
;; (global-set-key (kbd "C->") 'mc/mark-next-like-this)
;; (global-set-key (kbd "C-<") 'mc/mark-previous-like-this)
;; (global-set-key (kbd "C-c C-<") 'mc/mark-all-like-this)
;;
;; First mark the word, then add more cursors.
;;
;; To get out of multiple-cursors-mode, press `<return>` or `C-g`. The latter will
;; first disable multiple regions before disabling multiple cursors. If you want to
;; insert a newline in multiple-cursors-mode, use `C-j`.
;; ## Video
;; You can [watch an intro to multiple-cursors at Emacs Rocks](http://emacsrocks.com/e13.html).
;; ## Command overview
;; ### 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-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-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-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/add-cursor-on-click`: Bind to a mouse event to add cursors by clicking. See tips-section.
;; ### Mark many occurrences
;; - `mc/mark-all-like-this`: Marks all parts of the buffer that matches the current region.
;; - `mc/mark-all-words-like-this`: Like `mc/mark-all-like-this` but only for whole words.
;; - `mc/mark-all-symbols-like-this`: Like `mc/mark-all-like-this` but only for whole symbols.
;; - `mc/mark-all-in-region`: Prompts for a string to match in the region, adding cursors to all of them.
;; - `mc/mark-all-like-this-in-defun`: Marks all parts of the current defun that matches the current region.
;; - `mc/mark-all-words-like-this-in-defun`: Like `mc/mark-all-like-this-in-defun` but only for whole words.
;; - `mc/mark-all-symbols-like-this-in-defun`: Like `mc/mark-all-like-this-in-defun` but only for whole symbols.
;; - `mc/mark-all-like-this-dwim`: Tries to be smart about marking everything you want. Can be pressed multiple times.
;; ### Special
;; - `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/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/reverse-regions`: Reverse the order of the marked regions.
;; ## Tips and tricks
;; - To get out of multiple-cursors-mode, press `<return>` or `C-g`. The latter will
;; first disable multiple regions before disabling multiple cursors. If you want to
;; insert a newline in multiple-cursors-mode, use `C-j`.
;;
;; - 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`.
;;
;; ## More commands to play around with
;; - Try pressing `mc/mark-next-like-this` with no region selected. It will just add a cursor
;; on the next line.
;;
;; I've set up my key-bindings like so:
;; - 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
;;
;; ;; From active region to multiple cursors:
;; (global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines)
;; (global-set-key (kbd "C-S-c C-e") 'mc/edit-ends-of-lines)
;; (global-set-key (kbd "C-S-c C-a") 'mc/edit-beginnings-of-lines)
;; - Try pressing `mc/mark-all-like-this-dwim` on a tagname in html-mode.
;;
;; When you have an active region that spans multiple lines, the preceeding three
;; commands will add one cursor to each line.
;; - Notice that the number of cursors active can be seen in the modeline.
;;
;; ;; Rectangular region mode
;; (global-set-key (kbd "H-SPC") 'set-rectangular-region-anchor)
;; - If you get out of multiple-cursors-mode and yank - it will yank only
;; from the kill-ring of main cursor. To yank from the kill-rings of
;; every cursor use yank-rectangle, normally found at C-x r y.
;;
;; Think of this one as `set-mark` except you're marking a rectangular region. It is
;; an exceedingly quick way of adding multiple cursors to multiple lines.
;; - 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.
;;
;; ;; Mark more like this
;; (global-set-key (kbd "M-æ") 'mc/mark-all-like-this)
;; (global-set-key (kbd "C-å") 'mc/mark-previous-like-this)
;; (global-set-key (kbd "C-æ") 'mc/mark-next-like-this)
;; (global-set-key (kbd "C-Æ") 'mc/mark-more-like-this-extended)
;; (global-set-key (kbd "M-å") 'mc/mark-all-in-region)
;;
;; Okay, yes, I have a crazy norwegian keyboard. Regardless, these will look at
;; whatever you've got selected at the moment, and mark more places like that in
;; the buffer.
;; - 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).
;;
;; BTW, I highly recommend adding `mc/mark-next-like-this` to a key binding that's
;; right next to the key for `er/expand-region`.
;; ### Binding mouse events
;; To override a mouse event, you will likely have to also unbind the
;; `down-mouse` part of the event. Like this:
;;
;; (global-unset-key (kbd "M-<down-mouse-1>"))
;; (global-set-key (kbd "M-<mouse-1>") 'mc/add-cursor-on-click)
;;
;; Or you can do like me and find an unused, but less convenient, binding:
;;
;; (global-set-key (kbd "C-S-<mouse-1>") 'mc/add-cursor-on-click)
;; ## Unknown commands
;;
;; Multiple-cursors uses two lists of commands to know what to do: the run-once list
;; and the run-for-all list. It comes with a set of defaults, but it would be beyond silly
;; to try and include all the known Emacs commands.
;;
;; So that's why multiple-cursors occasionally asks what to do about a command. It will
;; then remember your choice by saving it in `~/.emacs.d/.mc-lists.el`. You can change
;; the location with:
;;
;; (setq mc/list-file "/my/preferred/file")
;;
;;
;; ## Known limitations
;;
;; * isearch-forward and isearch-backward aren't supported with multiple cursors.
;; You should feel free to add a simplified version that can work with it.
;; * Commands run with `M-x` won't be repeated for all cursors.
;; * All key bindings that refer to lambdas are always run for all cursors. If you
;; need to limit it, you will have to give it a name.
;; * Redo might screw with your cursors. Undo works very well.
;;
;;
;; ## Contribute
;;
;; Yes, please do. There's a suite of tests, so remember to add tests for your
;; specific feature, or I might break it later.
;;
;; You'll find the repo at:
;;
;; https://github.com/magnars/multiple-cursors.el
;;
;; To fetch the test dependencies:
;;
;; $ cd /path/to/multiple-cursors
;; $ git submodule update --init
;;
;; Run the tests with:
;;
;; $ ./util/ecukes/ecukes --graphical
;;
;; ## Contributors
;; * [Takafumi Arakaki](https://github.com/tkf) made .mc-lists.el diff friendly
;; * [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
;; * [Fuco](https://github.com/Fuco1) added the first version of `mc/mark-all-like-this-dwim`
;; Thanks!
;;; Code:
(defgroup multiple-cursors nil
"Multiple cursors for emacs."
: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)
(provide 'multiple-cursors)

View File

@ -1,6 +1,6 @@
;;; rectangular-region-mode.el
;;; rectangular-region-mode.el -*- lexical-binding: t; -*-
;; Copyright (C) 2012 Magnar Sveen
;; Copyright (C) 2012-2016 Magnar Sveen
;; Author: Magnar Sveen <magnars@gmail.com>
;; Keywords: editing cursors
@ -38,6 +38,8 @@
(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)
(defvar rectangular-region-mode nil)
(defun rrm/keyboard-quit ()
"Exit rectangular-region-mode."
(interactive)
@ -50,8 +52,9 @@
(defun set-rectangular-region-anchor ()
"Anchors the rectangular region at point.
Think of this one as `set-mark' except you're marking a rectangular region. It is
an exceedingly quick way of adding multiple cursors to multiple lines."
Think of this one as `set-mark' except you're marking a
rectangular region. It is an exceedingly quick way of adding
multiple cursors to multiple lines."
(interactive)
(set-marker rrm/anchor (point))
(push-mark (point))
@ -67,27 +70,30 @@ an exceedingly quick way of adding multiple cursors to multiple lines."
(defun rrm/repaint ()
"Start from the anchor and draw a rectangle between it and point."
(rrm/remove-rectangular-region-overlays)
(let* ((annoying-arrows-mode nil)
(point-column (current-column))
(point-line (line-number-at-pos))
(anchor-column (save-excursion (goto-char rrm/anchor) (current-column)))
(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)))
(move-to-column anchor-column)
(set-mark (point))
(move-to-column point-column)
(mc/save-excursion
(while (not (= anchor-line (line-number-at-pos)))
(forward-line navigation-step)
(move-to-column anchor-column)
(when (= anchor-column (current-column))
(set-mark (point))
(move-to-column point-column)
(when (= point-column (current-column))
(mc/create-fake-cursor-at-point)))))))
(if (not rectangular-region-mode)
(remove-hook 'post-command-hook 'rrm/repaint t)
;; else
(rrm/remove-rectangular-region-overlays)
(let* ((annoying-arrows-mode nil)
(point-column (current-column))
(point-line (mc/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)))
(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)))
(move-to-column anchor-column)
(set-mark (point))
(move-to-column point-column)
(mc/save-excursion
(while (not (= anchor-line (mc/line-number-at-pos)))
(forward-line navigation-step)
(move-to-column anchor-column)
(when (= anchor-column (current-column))
(set-mark (point))
(move-to-column point-column)
(when (= point-column (current-column))
(mc/create-fake-cursor-at-point))))))))
(defun rrm/switch-to-multiple-cursors (&rest forms)
"Switch from rectangular-region-mode to multiple-cursors-mode."
@ -103,9 +109,12 @@ an exceedingly quick way of adding multiple cursors to multiple lines."
(when rectangular-region-mode
(rrm/switch-to-multiple-cursors)))
;;;###autoload
(define-minor-mode rectangular-region-mode
"A mode for creating a rectangular region to edit"
nil " rr" rectangular-region-mode-map
:init-value nil
:lighter " rr"
:keymap rectangular-region-mode-map
(if rectangular-region-mode
(progn
(add-hook 'after-change-functions 'rrm/switch-to-multiple-cursors t t)

2
run-tests.sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/sh -e
cask exec ecukes "$@" --no-win

View File

@ -1,20 +0,0 @@
#!/bin/sh
cd "$(dirname "$0")"
set_default () {
eval "
if [ -z \$$1 ]; then
$1=$2
fi
"
}
set_default ECUKES_EMACS "$(which emacs)"
echo "*** Emacs version ***"
echo "ECUKES_EMACS =" $(which $ECUKES_EMACS)
$ECUKES_EMACS --version
echo
exec ./util/ecukes/ecukes --graphical

@ -1 +0,0 @@
Subproject commit b2c449cf01163df3aa41f401b9aeac4887b3177c

File diff suppressed because it is too large Load Diff

@ -1 +0,0 @@
Subproject commit 62ef75cb51eef76c547d33a81cb2b6b6e384aefc

View File

@ -7,13 +7,13 @@ end
def run_all_tests
system('clear')
result = run "./util/ecukes/ecukes --graphical"
result = run "./run-tests.sh"
puts result
end
def run_test(file)
system('clear')
result = run "./util/ecukes/ecukes --graphical #{file}"
result = run "./run-tests.sh #{file} --verbose"
puts result
end