60 Commits

Author SHA1 Message Date
Steve Purcell 48e1d3da5c Use lexical-binding instead of old lexical-let macro 2020-10-24 13:03:49 +13:00
Steve Purcell 1f3ccfbcd2 return-from should be cl-return-from 2020-10-24 13:01:21 +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
bb2020 1686630fd6 try to implement blacklist 2016-05-12 14:41:38 +03:00
15 changed files with 370 additions and 108 deletions
+1
View File
@@ -1,2 +1,3 @@
elpa elpa
*.elc *.elc
/.ecukes-failing-scenarios
+39 -8
View File
@@ -1,14 +1,31 @@
# multiple-cursors.el [![Build Status](https://secure.travis-ci.org/magnars/multiple-cursors.el.png)](http://travis-ci.org/magnars/multiple-cursors.el) # multiple-cursors.el [![Build Status](https://secure.travis-ci.org/magnars/multiple-cursors.el.png)](http://travis-ci.org/magnars/multiple-cursors.el)
Multiple cursors for Emacs. This is some pretty crazy functionality, so yes, 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. 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 ## Installation
I highly recommend installing multiple-cursors through `package.el`. I highly recommend installing multiple-cursors through `package.el`.
It's available on [melpa](http://melpa.milkbox.net/): It's available on [MELPA](http://melpa.org/) and [MELPA Stable](http://stable.melpa.org):
M-x package-install multiple-cursors M-x package-install multiple-cursors
@@ -43,6 +60,10 @@ 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 first disable multiple regions before disabling multiple cursors. If you want to
insert a newline in multiple-cursors-mode, use `C-j`. insert a newline in multiple-cursors-mode, use `C-j`.
## Important note
Multiple cursors does not do well when you invoke its commands with `M-x`. It needs to be bound to keys to work properly. Pull request to fix this is welcome.
## Video ## Video
You can [watch an intro to multiple-cursors at Emacs Rocks](http://emacsrocks.com/e13.html). You can [watch an intro to multiple-cursors at Emacs Rocks](http://emacsrocks.com/e13.html).
@@ -57,9 +78,11 @@ You can [watch an intro to multiple-cursors at Emacs Rocks](http://emacsrocks.co
- `mc/mark-next-word-like-this`: Like `mc/mark-next-like-this` but only for whole words. - `mc/mark-next-word-like-this`: Like `mc/mark-next-like-this` but only for whole words.
- `mc/mark-next-symbol-like-this`: Like `mc/mark-next-like-this` but only for whole symbols. - `mc/mark-next-symbol-like-this`: Like `mc/mark-next-like-this` but only for whole symbols.
- `mc/mark-previous-like-this`: Adds a cursor and region at the next part of the buffer backwards that matches the current region. - `mc/mark-previous-like-this`: Adds a cursor and region at the next part of the buffer backwards that matches the current region.
- `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-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-previous-symbol-like-this`: Like `mc/mark-previous-like-this` but only for whole symbols.
- `mc/mark-more-like-this-extended`: Use arrow keys to quickly mark/skip next/previous occurances. - `mc/mark-more-like-this-extended`: Use arrow keys to quickly mark/skip next/previous occurrences.
- `mc/add-cursor-on-click`: Bind to a mouse event to add cursors by clicking. See tips-section. - `mc/add-cursor-on-click`: Bind to a mouse event to add cursors by clicking. See tips-section.
- `mc/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. - `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.
@@ -67,9 +90,8 @@ You can [watch an intro to multiple-cursors at Emacs Rocks](http://emacsrocks.co
- `mc/unmark-next-like-this`: Remove the cursor furthest down in the buffer. - `mc/unmark-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/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 occurance down. - `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 occurance up. - `mc/skip-to-previous-like-this`: Remove the cursor furthest up, marking the next occurrence up.
- `mc/mark-next-like-this-extended`: Temporarily bind the arrow keys to mark/unmark/skip cursors.
### Mark many occurrences ### Mark many occurrences
@@ -100,6 +122,9 @@ You can [watch an intro to multiple-cursors at Emacs Rocks](http://emacsrocks.co
first disable multiple regions before disabling multiple cursors. If you want to first disable multiple regions before disabling multiple cursors. If you want to
insert a newline in multiple-cursors-mode, use `C-j`. 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 - 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 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. press `C-'` to hide all lines without a cursor, press `C-'` again to unhide.
@@ -109,7 +134,7 @@ You can [watch an intro to multiple-cursors at Emacs Rocks](http://emacsrocks.co
- Try pressing `mc/mark-next-like-this-word` or - Try pressing `mc/mark-next-like-this-word` or
`mc/mark-next-like-this-symbol` with no region selected. It will `mc/mark-next-like-this-symbol` with no region selected. It will
mark the word or symbol and add a cursor at the next occurance 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. - Try pressing `mc/mark-all-like-this-dwim` on a tagname in html-mode.
@@ -157,6 +182,11 @@ the location with:
NB! Make sure to do so before requiring multiple-cursors. 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 ## Known limitations
* isearch-forward and isearch-backward aren't supported with multiple cursors. * isearch-forward and isearch-backward aren't supported with multiple cursors.
@@ -198,12 +228,13 @@ Run the tests with:
* [Aleksey Fedotov](https://github.com/lexa) added `mc-hide-unmatched-lines-mode` * [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` * [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. * [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! Thanks!
## License ## License
Copyright (C) 2012 Magnar Sveen Copyright (C) 2012-2016 Magnar Sveen
Author: Magnar Sveen <magnars@gmail.com> Author: Magnar Sveen <magnars@gmail.com>
Keywords: editing cursors Keywords: editing cursors
+21
View File
@@ -17,3 +17,24 @@ Feature: Insert increasing numbers
When I press "C-u H-0" When I press "C-u H-0"
And I press "SPC" And I press "SPC"
Then I should see "This 4 text contains the word 5 text thrice (6 text)" 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)"
+16
View File
@@ -14,6 +14,14 @@ Feature: Marking multiple parts of the buffer
And I type "sentence" And I type "sentence"
Then I should see "This sentence has the word sentence in it" 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 Scenario: Skipping a mark
Given I turn on delete-selection-mode Given I turn on delete-selection-mode
When I insert "Here's text, text and text" When I insert "Here's text, text and text"
@@ -54,6 +62,14 @@ Feature: Marking multiple parts of the buffer
And I type "sentence" And I type "sentence"
Then I should see "This sentence has the word sentence in it" 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 Scenario: Skipping a prev mark
Given I turn on delete-selection-mode Given I turn on delete-selection-mode
When I insert "Here's text, text and text" When I insert "Here's text, text and text"
+37
View File
@@ -0,0 +1,37 @@
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 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 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)"
@@ -1,4 +1,4 @@
(require 'cl) ;; For lexical-let ;; -*- lexical-binding: t -*-
(When "^I mark next like this$" (When "^I mark next like this$"
(lambda () (call-interactively 'mc/mark-next-like-this))) (lambda () (call-interactively 'mc/mark-next-like-this)))
@@ -12,6 +12,12 @@
(When "^I mark previous like this$" (When "^I mark previous like this$"
(lambda () (call-interactively 'mc/mark-previous-like-this))) (lambda () (call-interactively 'mc/mark-previous-like-this)))
(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$" (When "^I mark all like this$"
(lambda () (call-interactively 'mc/mark-all-like-this))) (lambda () (call-interactively 'mc/mark-all-like-this)))
@@ -102,27 +108,23 @@
(When "^I copy \"\\(.+\\)\" in another program$" (When "^I copy \"\\(.+\\)\" in another program$"
(lambda (text) (lambda (text)
(lexical-let ((text text)) (setq interprogram-paste-function
(setq interprogram-paste-function #'(lambda () (let ((r text)) (setq text nil) r)))))
#'(lambda () (let ((r text)) (setq text nil) r))))))
(Given "^I have bound C-! to a lambda that inserts \"\\(.+\\)\"$" (Given "^I have bound C-! to a lambda that inserts \"\\(.+\\)\"$"
(lambda (ins) (lambda (ins)
(lexical-let ((ins ins)) (global-set-key (kbd "C-!") #'(lambda () (interactive) (insert ins)))))
(global-set-key (kbd "C-!") #'(lambda () (interactive) (insert ins))))))
(Given "^I have bound C-! to a new command that inserts \"\\(.+\\)\"$" (Given "^I have bound C-! to a new command that inserts \"\\(.+\\)\"$"
(lambda (ins) (lambda (ins)
(lexical-let ((ins ins)) (defun mc-test-temp-command () (interactive) (insert ins))
(defun mc-test-temp-command () (interactive) (insert ins)) (global-set-key (kbd "C-!") 'mc-test-temp-command)))
(global-set-key (kbd "C-!") 'mc-test-temp-command))))
(Given "^I have bound C-! to another new command that inserts \"\\(.+\\)\"$" (Given "^I have bound C-! to another new command that inserts \"\\(.+\\)\"$"
(lambda (ins) (lambda (ins)
(lexical-let ((ins ins)) (defun mc-test-temp-command-2 () (interactive) (insert ins))
(defun mc-test-temp-command-2 () (interactive) (insert ins)) (global-set-key (kbd "C-!") 'mc-test-temp-command-2)))
(global-set-key (kbd "C-!") 'mc-test-temp-command-2))))
(Given "^I have bound C-! to a keyboard macro that insert \"_\"$" (Given "^I have bound C-! to a keyboard macro that insert \"_\"$"
(lambda () (lambda ()
@@ -144,6 +146,12 @@
(cl-assert search nil message word (espuds-buffer-contents)) (cl-assert search nil message word (espuds-buffer-contents))
(if (string-equal "front" pos) (backward-word))))) (if (string-equal "front" pos) (backward-word)))))
(When "^I 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 \"\\(.+\\)\"$" (When "^I select the last \"\\(.+\\)\"$"
(lambda (text) (lambda (text)
(goto-char (point-max)) (goto-char (point-max))
+2
View File
@@ -24,6 +24,8 @@
(global-set-key (kbd "C-S-c C->") 'mc/mark-next-like-this-word) (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-S-c M->") 'mc/mark-next-like-this-symbol)
(global-set-key (kbd "C-<") 'mc/mark-previous-like-this) (global-set-key (kbd "C-<") 'mc/mark-previous-like-this)
(global-set-key (kbd "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)
(global-set-key (kbd "M-$") 'mc/mark-all-like-this-dwim) (global-set-key (kbd "M-$") 'mc/mark-all-like-this-dwim)
(global-set-key (kbd "C-$") 'mc/mark-all-dwim) (global-set-key (kbd "C-$") 'mc/mark-all-dwim)
+2 -2
View File
@@ -1,6 +1,6 @@
;;; mc-cycle-cursors.el ;;; mc-cycle-cursors.el
;; Copyright (C) 2012 Magnar Sveen ;; Copyright (C) 2012-2016 Magnar Sveen
;; Author: Magnar Sveen <magnars@gmail.com> ;; Author: Magnar Sveen <magnars@gmail.com>
;; Keywords: editing cursors ;; Keywords: editing cursors
@@ -88,7 +88,7 @@
(cl-defun mc/cycle (next-cursor fallback-cursor loop-message) (cl-defun mc/cycle (next-cursor fallback-cursor loop-message)
(when (null next-cursor) (when (null next-cursor)
(when (eql 'stop (mc/handle-loop-condition loop-message)) (when (eql 'stop (mc/handle-loop-condition loop-message))
(return-from mc/cycle nil)) (cl-return-from mc/cycle nil))
(setf next-cursor fallback-cursor)) (setf next-cursor fallback-cursor))
(mc/create-fake-cursor-at-point) (mc/create-fake-cursor-at-point)
(mc/pop-state-from-overlay next-cursor) (mc/pop-state-from-overlay next-cursor)
+4 -4
View File
@@ -1,6 +1,6 @@
;;; mc-edit-lines.el ;;; mc-edit-lines.el
;; Copyright (C) 2012 Magnar Sveen ;; Copyright (C) 2012-2016 Magnar Sveen
;; Author: Magnar Sveen <magnars@gmail.com> ;; Author: Magnar Sveen <magnars@gmail.com>
;; Keywords: editing cursors ;; Keywords: editing cursors
@@ -54,8 +54,8 @@ other non-nil value will cause short lines to be padded."
(error "Mark a set of lines first")) (error "Mark a set of lines first"))
(mc/remove-fake-cursors) (mc/remove-fake-cursors)
(let* ((col (current-column)) (let* ((col (current-column))
(point-line (line-number-at-pos)) (point-line (mc/line-number-at-pos))
(mark-line (progn (exchange-point-and-mark) (line-number-at-pos))) (mark-line (progn (exchange-point-and-mark) (mc/line-number-at-pos)))
(direction (if (< point-line mark-line) :up :down)) (direction (if (< point-line mark-line) :up :down))
(style (cond (style (cond
;; called from lisp ;; called from lisp
@@ -71,7 +71,7 @@ other non-nil value will cause short lines to be padded."
(previous-logical-line 1 nil) (previous-logical-line 1 nil)
(move-to-column col)) (move-to-column col))
;; Add the cursors ;; Add the cursors
(while (not (eq (line-number-at-pos) point-line)) (while (not (eq (mc/line-number-at-pos) point-line))
;; Pad the line ;; Pad the line
(when (eq style 'pad) (when (eq style 'pad)
(while (< (current-column) col) (while (< (current-column) col)
+4 -3
View File
@@ -1,4 +1,4 @@
;;; mc-hide-unmatched-lines.el ;;; mc-hide-unmatched-lines-mode.el
;; Copyright (C) 2014 Aleksey Fedotov ;; Copyright (C) 2014 Aleksey Fedotov
@@ -73,7 +73,7 @@ mode. To leave this mode press <return> or \"C-g\""
:group 'multiple-cursors) :group 'multiple-cursors)
(defcustom hum/placeholder "..." (defcustom hum/placeholder "..."
"Placeholder which will be placed insted of hiden text" "Placeholder which will be placed instead of hidden text"
:type '(string) :type '(string)
:group 'multiple-cursors) :group 'multiple-cursors)
@@ -103,5 +103,6 @@ mode. To leave this mode press <return> or \"C-g\""
(defun hum/unhide-unmatched-lines () (defun hum/unhide-unmatched-lines ()
(remove-overlays nil nil hum/invisible-overlay-name t)) (remove-overlays nil nil hum/invisible-overlay-name t))
(provide 'mc-hide-unmatched-lines-mode)
(define-key mc/keymap (kbd "C-'") 'mc-hide-unmatched-lines-mode) (define-key mc/keymap (kbd "C-'") 'mc-hide-unmatched-lines-mode)
(provide 'mc-hide-unmatched-lines-mode)
+85 -31
View File
@@ -1,6 +1,6 @@
;;; mc-mark-more.el ;;; mc-mark-more.el
;; Copyright (C) 2012 Magnar Sveen ;; Copyright (C) 2012-2016 Magnar Sveen
;; Author: Magnar Sveen <magnars@gmail.com> ;; Author: Magnar Sveen <magnars@gmail.com>
;; Keywords: editing cursors ;; Keywords: editing cursors
@@ -56,7 +56,7 @@
(defun mc/furthest-cursor-before-point () (defun mc/furthest-cursor-before-point ()
(let ((beg (if mark-active (min (mark) (point)) (point))) (let ((beg (if mark-active (min (mark) (point)) (point)))
furthest) furthest)
(mc/for-each-fake-cursor (mc/for-each-fake-cursor
(when (< (mc/cursor-beg cursor) beg) (when (< (mc/cursor-beg cursor) beg)
(setq beg (mc/cursor-beg cursor)) (setq beg (mc/cursor-beg cursor))
@@ -65,7 +65,7 @@
(defun mc/furthest-cursor-after-point () (defun mc/furthest-cursor-after-point ()
(let ((end (if mark-active (max (mark) (point)) (point))) (let ((end (if mark-active (max (mark) (point)) (point)))
furthest) furthest)
(mc/for-each-fake-cursor (mc/for-each-fake-cursor
(when (> (mc/cursor-end cursor) end) (when (> (mc/cursor-end cursor) end)
(setq end (mc/cursor-end cursor)) (setq end (mc/cursor-end cursor))
@@ -131,7 +131,7 @@ Use like case-fold-search, don't recommend setting it globally.")
(when point-out-of-order (when point-out-of-order
(exchange-point-and-mark)) (exchange-point-and-mark))
(mc/create-fake-cursor-at-point)) (mc/create-fake-cursor-at-point))
(error "no more matches found.")))))) (user-error "no more matches found."))))))
;;;###autoload ;;;###autoload
(defun mc/mark-next-like-this (arg) (defun mc/mark-next-like-this (arg)
@@ -142,9 +142,9 @@ With zero ARG, skip the last one and mark next."
(interactive "p") (interactive "p")
(if (< arg 0) (if (< arg 0)
(let ((cursor (mc/furthest-cursor-after-point))) (let ((cursor (mc/furthest-cursor-after-point)))
(if cursor (if cursor
(mc/remove-fake-cursor cursor) (mc/remove-fake-cursor cursor)
(error "No cursors to be unmarked"))) (error "No cursors to be unmarked")))
(if (region-active-p) (if (region-active-p)
(mc/mark-more-like-this (= arg 0) 'forwards) (mc/mark-more-like-this (= arg 0) 'forwards)
(mc/mark-lines arg 'forwards))) (mc/mark-lines arg 'forwards)))
@@ -159,9 +159,9 @@ With zero ARG, skip the last one and mark next."
(interactive "p") (interactive "p")
(if (< arg 0) (if (< arg 0)
(let ((cursor (mc/furthest-cursor-after-point))) (let ((cursor (mc/furthest-cursor-after-point)))
(if cursor (if cursor
(mc/remove-fake-cursor cursor) (mc/remove-fake-cursor cursor)
(error "No cursors to be unmarked"))) (error "No cursors to be unmarked")))
(if (region-active-p) (if (region-active-p)
(mc/mark-more-like-this (= arg 0) 'forwards) (mc/mark-more-like-this (= arg 0) 'forwards)
(mc--select-thing-at-point 'word) (mc--select-thing-at-point 'word)
@@ -176,9 +176,9 @@ With zero ARG, skip the last one and mark next."
(interactive "p") (interactive "p")
(if (< arg 0) (if (< arg 0)
(let ((cursor (mc/furthest-cursor-after-point))) (let ((cursor (mc/furthest-cursor-after-point)))
(if cursor (if cursor
(mc/remove-fake-cursor cursor) (mc/remove-fake-cursor cursor)
(error "No cursors to be unmarked"))) (error "No cursors to be unmarked")))
(if (region-active-p) (if (region-active-p)
(mc/mark-more-like-this (= arg 0) 'forwards) (mc/mark-more-like-this (= arg 0) 'forwards)
(mc--select-thing-at-point 'symbol) (mc--select-thing-at-point 'symbol)
@@ -188,12 +188,22 @@ With zero ARG, skip the last one and mark next."
;;;###autoload ;;;###autoload
(defun mc/mark-next-word-like-this (arg) (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") (interactive "p")
(let ((mc/enclose-search-term 'words)) (let ((mc/enclose-search-term 'words))
(mc/mark-next-like-this arg))) (mc/mark-next-like-this arg)))
;;;###autoload ;;;###autoload
(defun mc/mark-next-symbol-like-this (arg) (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") (interactive "p")
(let ((mc/enclose-search-term 'symbols)) (let ((mc/enclose-search-term 'symbols))
(mc/mark-next-like-this arg))) (mc/mark-next-like-this arg)))
@@ -201,27 +211,74 @@ With zero ARG, skip the last one and mark next."
;;;###autoload ;;;###autoload
(defun mc/mark-previous-like-this (arg) (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 negative ARG, delete the last one instead.
With zero ARG, skip the last one and mark next." With zero ARG, skip the last one and mark next."
(interactive "p") (interactive "p")
(if (< arg 0) (if (< arg 0)
(let ((cursor (mc/furthest-cursor-before-point))) (let ((cursor (mc/furthest-cursor-before-point)))
(if cursor (if cursor
(mc/remove-fake-cursor cursor) (mc/remove-fake-cursor cursor)
(error "No cursors to be unmarked"))) (error "No cursors to be unmarked")))
(if (region-active-p) (if (region-active-p)
(mc/mark-more-like-this (= arg 0) 'backwards) (mc/mark-more-like-this (= arg 0) 'backwards)
(mc/mark-lines arg 'backwards))) (mc/mark-lines arg 'backwards)))
(mc/maybe-multiple-cursors-mode)) (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 ;;;###autoload
(defun mc/mark-previous-word-like-this (arg) (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") (interactive "p")
(let ((mc/enclose-search-term 'words)) (let ((mc/enclose-search-term 'words))
(mc/mark-previous-like-this arg))) (mc/mark-previous-like-this arg)))
;;;###autoload ;;;###autoload
(defun mc/mark-previous-symbol-like-this (arg) (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") (interactive "p")
(let ((mc/enclose-search-term 'symbols)) (let ((mc/enclose-search-term 'symbols))
(mc/mark-previous-like-this arg))) (mc/mark-previous-like-this arg)))
@@ -230,8 +287,8 @@ With zero ARG, skip the last one and mark next."
(dotimes (i (if (= num-lines 0) 1 num-lines)) (dotimes (i (if (= num-lines 0) 1 num-lines))
(mc/save-excursion (mc/save-excursion
(let ((furthest-cursor (cl-ecase direction (let ((furthest-cursor (cl-ecase direction
(forwards (mc/furthest-cursor-after-point)) (forwards (mc/furthest-cursor-after-point))
(backwards (mc/furthest-cursor-before-point))))) (backwards (mc/furthest-cursor-before-point)))))
(when (overlayp furthest-cursor) (when (overlayp furthest-cursor)
(goto-char (overlay-get furthest-cursor 'point)) (goto-char (overlay-get furthest-cursor 'point))
(when (= num-lines 0) (when (= num-lines 0)
@@ -366,16 +423,13 @@ With zero ARG, skip the last one and mark next."
(setq lastmatch (point)) (setq lastmatch (point))
(when (= (point) (match-beginning 0)) (when (= (point) (match-beginning 0))
(forward-char))) (forward-char)))
(when lastmatch (goto-char lastmatch))) (unless lastmatch
(when (> (mc/num-cursors) 0) (error "Search failed for %S" search)))
(goto-char (match-end 0))) (goto-char (match-end 0))
(let ((first (mc/furthest-cursor-before-point))) (if (< (mc/num-cursors) 3)
(if (not first) (multiple-cursors-mode 0)
(error "Search failed for %S" search) (mc/pop-state-from-overlay (mc/furthest-cursor-before-point))
(mc/pop-state-from-overlay first))) (multiple-cursors-mode 1))))))
(if (> (mc/num-cursors) 1)
(multiple-cursors-mode 1)
(multiple-cursors-mode 0))))))
(when (not (fboundp 'set-temporary-overlay-map)) (when (not (fboundp 'set-temporary-overlay-map))
;; Backport this function from newer emacs versions ;; Backport this function from newer emacs versions
@@ -525,11 +579,11 @@ If the region is inactive or on a single line, it will behave like
(interactive "P") (interactive "P")
(if (and (use-region-p) (if (and (use-region-p)
(not (> (mc/num-cursors) 1)) (not (> (mc/num-cursors) 1))
(not (= (line-number-at-pos (region-beginning)) (not (= (mc/line-number-at-pos (region-beginning))
(line-number-at-pos (region-end))))) (mc/line-number-at-pos (region-end)))))
(if arg (if arg
(call-interactively 'mc/edit-lines) (call-interactively 'mc/edit-lines)
(call-interactively 'mc/mark-all-in-region)) (call-interactively 'mc/mark-all-in-region))
(progn (progn
(setq this-command 'mc/mark-all-like-this-dwim) (setq this-command 'mc/mark-all-like-this-dwim)
(mc/mark-all-like-this-dwim arg)))) (mc/mark-all-like-this-dwim arg))))
+26 -24
View File
@@ -1,6 +1,6 @@
;;; mc-separate-operations.el - functions that work differently on each cursor ;;; mc-separate-operations.el - functions that work differently on each cursor
;; Copyright (C) 2012 Magnar Sveen ;; Copyright (C) 2012-2016 Magnar Sveen
;; Author: Magnar Sveen <magnars@gmail.com> ;; Author: Magnar Sveen <magnars@gmail.com>
;; Keywords: editing cursors ;; Keywords: editing cursors
@@ -29,17 +29,24 @@
(require 'multiple-cursors-core) (require 'multiple-cursors-core)
;;;###autoload (defcustom mc/insert-numbers-default 0
(defun mc/insert-numbers (arg) "The default number at which to start counting for
"Insert increasing numbers for each cursor, starting at 0 or ARG." `mc/insert-numbers'"
(interactive "P") :type 'integer
(setq mc--insert-numbers-number (or (and arg (prefix-numeric-value arg)) :group 'multiple-cursors)
0))
(mc/for-each-cursor-ordered
(mc/execute-command-for-fake-cursor 'mc--insert-number-and-increase cursor)))
(defvar mc--insert-numbers-number 0) (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 () (defun mc--insert-number-and-increase ()
(interactive) (interactive)
(insert (number-to-string mc--insert-numbers-number)) (insert (number-to-string mc--insert-numbers-number))
@@ -54,6 +61,8 @@
(mc/cursor-end cursor)) strings)))) (mc/cursor-end cursor)) strings))))
(nreverse strings))) (nreverse strings)))
(defvar mc--insert-letters-number 0)
;;;###autoload ;;;###autoload
(defun mc/insert-letters (arg) (defun mc/insert-letters (arg)
"Insert increasing letters for each cursor, starting at 0 or ARG. "Insert increasing letters for each cursor, starting at 0 or ARG.
@@ -66,15 +75,13 @@
(defun mc--number-to-letters (number) (defun mc--number-to-letters (number)
(let ((letter (let ((letter
(char-to-string (char-to-string
(+ (mod number 26) ?a))) (+ (mod number 26) ?a)))
(number2 (/ number 26))) (number2 (/ number 26)))
(if (> number2 0) (if (> number2 0)
(concat (mc--number-to-letters (- number2 1)) letter) (concat (mc--number-to-letters (- number2 1)) letter)
letter))) letter)))
(defvar mc--insert-letters-number 0)
(defun mc--insert-letter-and-increase () (defun mc--insert-letter-and-increase ()
(interactive) (interactive)
(insert (mc--number-to-letters mc--insert-letters-number)) (insert (mc--number-to-letters mc--insert-letters-number))
@@ -117,7 +124,7 @@
;;;###autoload ;;;###autoload
(defun mc/vertical-align (character) (defun mc/vertical-align (character)
"Aligns all cursors vertically with a given CHARACTER to the one with the "Aligns all cursors vertically with a given CHARACTER to the one with the
highest colum number (the rightest). highest column number (the rightest).
Might not behave as intended if more than one cursors are on the same line." Might not behave as intended if more than one cursors are on the same line."
(interactive "c") (interactive "c")
(let ((rightest-column (current-column))) (let ((rightest-column (current-column)))
@@ -130,19 +137,14 @@ Might not behave as intended if more than one cursors are on the same line."
(lambda () (lambda ()
(interactive) (interactive)
(let ((missing-spaces (- rightest-column (current-column)))) (let ((missing-spaces (- rightest-column (current-column))))
(save-excursion (insert (make-string missing-spaces character))) (save-excursion (insert (make-string missing-spaces character)))
(forward-char missing-spaces) (forward-char missing-spaces))))))
)
))
)
)
;;;###autoload ;;;###autoload
(defun mc/vertical-align-with-space () (defun mc/vertical-align-with-space ()
"Aligns all cursors with whitespace like `mc/vertical-align' does" "Aligns all cursors with whitespace like `mc/vertical-align' does"
(interactive) (interactive)
(mc/vertical-align 32) (mc/vertical-align 32))
)
(provide 'mc-separate-operations) (provide 'mc-separate-operations)
;;; mc-separate-operations.el ends here ;;; mc-separate-operations.el ends here
+100 -13
View File
@@ -1,6 +1,6 @@
;;; multiple-cursors-core.el --- An experiment in multiple cursors for emacs. ;;; multiple-cursors-core.el --- An experiment in multiple cursors for emacs.
;; Copyright (C) 2012 Magnar Sveen ;; Copyright (C) 2012-2016 Magnar Sveen
;; Author: Magnar Sveen <magnars@gmail.com> ;; Author: Magnar Sveen <magnars@gmail.com>
;; Keywords: editing cursors ;; Keywords: editing cursors
@@ -35,6 +35,11 @@
"The face used for fake cursors" "The face used for fake cursors"
:group 'multiple-cursors) :group 'multiple-cursors)
(defface mc/cursor-bar-face
`((t (:height 1 :background ,(face-attribute 'cursor :background))))
"The face used for fake cursors if the cursor-type is bar"
:group 'multiple-cursors)
(defface mc/region-face (defface mc/region-face
'((t :inherit region)) '((t :inherit region))
"The face used for fake regions" "The face used for fake regions"
@@ -98,16 +103,39 @@
(set-marker ,p nil) (set-marker ,p nil)
(set-marker ,s nil)))) (set-marker ,s nil))))
(defun mc/cursor-is-bar ()
"Return non-nil if the cursor is a bar."
(or (eq cursor-type 'bar)
(and (listp cursor-type)
(eq (car cursor-type) 'bar))))
(defun mc/line-number-at-pos (&optional pos absolute)
"Faster implementation of `line-number-at-pos'."
(if pos
(save-excursion
(if absolute
(save-restriction
(widen)
(goto-char pos)
(string-to-number (format-mode-line "%l")))
(goto-char pos)
(string-to-number (format-mode-line "%l"))))
(string-to-number (format-mode-line "%l"))))
(defun mc/make-cursor-overlay-at-eol (pos) (defun mc/make-cursor-overlay-at-eol (pos)
"Create overlay to look like cursor at end of line." "Create overlay to look like cursor at end of line."
(let ((overlay (make-overlay pos pos nil nil nil))) (let ((overlay (make-overlay pos pos nil nil nil)))
(overlay-put overlay 'after-string (propertize " " 'face 'mc/cursor-face)) (if (mc/cursor-is-bar)
(overlay-put overlay 'before-string (propertize "|" 'face 'mc/cursor-bar-face))
(overlay-put overlay 'after-string (propertize " " 'face 'mc/cursor-face)))
overlay)) overlay))
(defun mc/make-cursor-overlay-inline (pos) (defun mc/make-cursor-overlay-inline (pos)
"Create overlay to look like cursor inside text." "Create overlay to look like cursor inside text."
(let ((overlay (make-overlay pos (1+ pos) nil nil nil))) (let ((overlay (make-overlay pos (1+ pos) nil nil nil)))
(overlay-put overlay 'face 'mc/cursor-face) (if (mc/cursor-is-bar)
(overlay-put overlay 'before-string (propertize "|" 'face 'mc/cursor-bar-face))
(overlay-put overlay 'face 'mc/cursor-face))
overlay)) overlay))
(defun mc/make-cursor-overlay-at-point () (defun mc/make-cursor-overlay-at-point ()
@@ -133,13 +161,27 @@ highlights the entire width of the window."
yank-undo-function yank-undo-function
autopair-action autopair-action
autopair-wrap-action autopair-wrap-action
er/history) temporary-goal-column
er/history
dabbrev--abbrev-char-regexp
dabbrev--check-other-buffers
dabbrev--friend-buffer-list
dabbrev--last-abbrev-location
dabbrev--last-abbreviation
dabbrev--last-buffer
dabbrev--last-buffer-found
dabbrev--last-direction
dabbrev--last-expansion
dabbrev--last-expansion-location
dabbrev--last-table)
"A list of vars that need to be tracked on a per-cursor basis.") "A list of vars that need to be tracked on a per-cursor basis.")
(defun mc/store-current-state-in-overlay (o) (defun mc/store-current-state-in-overlay (o)
"Store relevant info about point and mark in the given overlay." "Store relevant info about point and mark in the given overlay."
(overlay-put o 'point (set-marker (make-marker) (point))) (overlay-put o 'point (set-marker (make-marker) (point)))
(overlay-put o 'mark (set-marker (make-marker) (mark))) (overlay-put o 'mark (set-marker (make-marker)
(let ((mark-even-if-inactive t))
(mark))))
(dolist (var mc/cursor-specific-vars) (dolist (var mc/cursor-specific-vars)
(when (boundp var) (overlay-put o var (symbol-value var)))) (when (boundp var) (overlay-put o var (symbol-value var))))
o) o)
@@ -310,6 +352,16 @@ cursor with updated info."
(mc/pop-state-from-overlay mc--stored-state-for-undo) (mc/pop-state-from-overlay mc--stored-state-for-undo)
(setq mc--stored-state-for-undo nil))) (setq mc--stored-state-for-undo nil)))
(defcustom mc/always-run-for-all nil
"Disables whitelisting and always executes commands for every fake cursor."
:type '(boolean)
:group 'multiple-cursors)
(defcustom mc/always-repeat-command nil
"Disables confirmation for `mc/repeat-command' command."
:type '(boolean)
:group 'multiple-cursors)
(defun mc/prompt-for-inclusion-in-whitelist (original-command) (defun mc/prompt-for-inclusion-in-whitelist (original-command)
"Asks the user, then adds the command either to the once-list or the all-list." "Asks the user, then adds the command either to the once-list or the all-list."
(let ((all-p (y-or-n-p (format "Do %S for all cursors?" original-command)))) (let ((all-p (y-or-n-p (format "Do %S for all cursors?" original-command))))
@@ -396,10 +448,15 @@ the original cursor, to inform about the lack of support."
(message "%S is not supported with multiple cursors%s" (message "%S is not supported with multiple cursors%s"
original-command original-command
(get original-command 'mc--unsupported)) (get original-command 'mc--unsupported))
;; lazy-load the user's list file
(mc/load-lists)
(when (and original-command (when (and original-command
(not (memq original-command mc--default-cmds-to-run-once)) (not (memq original-command mc--default-cmds-to-run-once))
(not (memq original-command mc/cmds-to-run-once)) (not (memq original-command mc/cmds-to-run-once))
(or (memq original-command mc--default-cmds-to-run-for-all) (or mc/always-run-for-all
(memq original-command mc--default-cmds-to-run-for-all)
(memq original-command mc/cmds-to-run-for-all) (memq original-command mc/cmds-to-run-for-all)
(mc/prompt-for-inclusion-in-whitelist original-command))) (mc/prompt-for-inclusion-in-whitelist original-command)))
(mc/execute-command-for-all-fake-cursors original-command)))))))))) (mc/execute-command-for-all-fake-cursors original-command))))))))))
@@ -421,6 +478,17 @@ you should disable multiple-cursors-mode."
(multiple-cursors-mode 0) (multiple-cursors-mode 0)
(deactivate-mark))) (deactivate-mark)))
(defun mc/repeat-command ()
"Run last command from `command-history' for every fake cursor."
(interactive)
(when (or mc/always-repeat-command
(y-or-n-p (format "[mc] repeat complex command: %s? " (caar command-history))))
(mc/execute-command-for-all-fake-cursors
(lambda () (interactive)
(cl-letf (((symbol-function 'read-from-minibuffer)
(lambda (p &optional i k r h d m) (read i))))
(repeat-complex-command 0))))))
(defvar mc/keymap nil (defvar mc/keymap nil
"Keymap while multiple cursors are active. "Keymap while multiple cursors are active.
Main goal of the keymap is to rebind C-g and <return> to conclude Main goal of the keymap is to rebind C-g and <return> to conclude
@@ -429,6 +497,7 @@ multiple cursors editing.")
(setq mc/keymap (make-sparse-keymap)) (setq mc/keymap (make-sparse-keymap))
(define-key mc/keymap (kbd "C-g") 'mc/keyboard-quit) (define-key mc/keymap (kbd "C-g") 'mc/keyboard-quit)
(define-key mc/keymap (kbd "<return>") 'multiple-cursors-mode) (define-key mc/keymap (kbd "<return>") 'multiple-cursors-mode)
(define-key mc/keymap (kbd "C-:") 'mc/repeat-command)
(when (fboundp 'phi-search) (when (fboundp 'phi-search)
(define-key mc/keymap (kbd "C-s") 'phi-search)) (define-key mc/keymap (kbd "C-s") 'phi-search))
(when (fboundp 'phi-search-backward) (when (fboundp 'phi-search-backward)
@@ -530,14 +599,15 @@ from being executed if in multiple-cursors-mode."
(unsupported-cmd isearch-backward ". Feel free to add a compatible version.") (unsupported-cmd isearch-backward ". Feel free to add a compatible version.")
;; Make sure pastes from other programs are added to all kill-rings when yanking ;; Make sure pastes from other programs are added to all kill-rings when yanking
(defadvice current-kill (before interprogram-paste-for-all-cursors activate) (defadvice current-kill (before interprogram-paste-for-all-cursors
(n &optional do-not-move) activate)
(let ((interprogram-paste (and (= n 0) (let ((interprogram-paste (and (= n 0)
interprogram-paste-function interprogram-paste-function
(funcall interprogram-paste-function)))) (funcall interprogram-paste-function))))
(when interprogram-paste (when interprogram-paste
;; Add interprogram-paste to normal kill ring, just ;; Add interprogram-paste to normal kill ring, just
;; like current-kill usually does for itself. ;; like current-kill usually does for itself.
;; We have to do the work for it tho, since the funcall only returns ;; We have to do the work for it though, since the funcall only returns
;; something once. It is not a pure function. ;; something once. It is not a pure function.
(let ((interprogram-cut-function nil)) (let ((interprogram-cut-function nil))
(if (listp interprogram-paste) (if (listp interprogram-paste)
@@ -554,9 +624,20 @@ from being executed if in multiple-cursors-mode."
(overlay-put cursor 'kill-ring kill-ring) (overlay-put cursor 'kill-ring kill-ring)
(overlay-put cursor 'kill-ring-yank-pointer kill-ring-yank-pointer))))))) (overlay-put cursor 'kill-ring-yank-pointer kill-ring-yank-pointer)))))))
(defvar mc/list-file (locate-user-emacs-file ".mc-lists.el") (defcustom mc/list-file (locate-user-emacs-file ".mc-lists.el")
"The position of the file that keeps track of your preferences "The position of the file that keeps track of your preferences
for running commands with multiple cursors.") for running commands with multiple cursors."
:type 'file
:group 'multiple-cursors)
(defvar mc--list-file-loaded nil
"Whether the list file has already been loaded.")
(defun mc/load-lists ()
"Loads preferences for running commands with multiple cursors from `mc/list-file'"
(unless mc--list-file-loaded
(load mc/list-file 'noerror 'nomessage)
(setq mc--list-file-loaded t)))
(defun mc/dump-list (list-symbol) (defun mc/dump-list (list-symbol)
"Insert (setq 'LIST-SYMBOL LIST-VALUE) to current buffer." "Insert (setq 'LIST-SYMBOL LIST-VALUE) to current buffer."
@@ -600,6 +681,8 @@ for running commands with multiple cursors.")
mc/mark-next-word-like-this mc/mark-next-word-like-this
mc/mark-next-symbol-like-this mc/mark-next-symbol-like-this
mc/mark-previous-like-this mc/mark-previous-like-this
mc/mark-previous-like-this-word
mc/mark-previous-like-this-symbol
mc/mark-previous-word-like-this mc/mark-previous-word-like-this
mc/mark-previous-symbol-like-this mc/mark-previous-symbol-like-this
mc/mark-all-like-this mc/mark-all-like-this
@@ -631,13 +714,16 @@ for running commands with multiple cursors.")
mc/skip-to-previous-like-this mc/skip-to-previous-like-this
rrm/switch-to-multiple-cursors rrm/switch-to-multiple-cursors
mc-hide-unmatched-lines-mode mc-hide-unmatched-lines-mode
mc/repeat-command
hum/keyboard-quit hum/keyboard-quit
hum/unhide-invisible-overlays hum/unhide-invisible-overlays
save-buffer save-buffer
ido-exit-minibuffer ido-exit-minibuffer
ivy-done
exit-minibuffer exit-minibuffer
minibuffer-complete-and-exit minibuffer-complete-and-exit
execute-extended-command execute-extended-command
eval-expression
undo undo
redo redo
undo-tree-undo undo-tree-undo
@@ -671,7 +757,8 @@ for running commands with multiple cursors.")
windmove-left windmove-left
windmove-right windmove-right
windmove-up windmove-up
windmove-down)) windmove-down
repeat-complex-command))
(defvar mc--default-cmds-to-run-for-all nil (defvar mc--default-cmds-to-run-for-all nil
"Default set of commands that should be mirrored by all cursors") "Default set of commands that should be mirrored by all cursors")
@@ -756,9 +843,9 @@ for running commands with multiple cursors.")
(defvar mc/cmds-to-run-for-all nil (defvar mc/cmds-to-run-for-all nil
"Commands to run for all cursors in multiple-cursors-mode") "Commands to run for all cursors in multiple-cursors-mode")
(load mc/list-file t) ;; load, but no errors if it does not exist yet please
(provide 'multiple-cursors-core) (provide 'multiple-cursors-core)
(require 'mc-cycle-cursors)
(require 'mc-hide-unmatched-lines-mode)
;; Local Variables: ;; Local Variables:
;; coding: utf-8 ;; coding: utf-8
+8 -6
View File
@@ -1,6 +1,6 @@
;;; multiple-cursors.el --- Multiple cursors for emacs. ;;; multiple-cursors.el --- Multiple cursors for emacs.
;; Copyright (C) 2012-2013 Magnar Sveen ;; Copyright (C) 2012-2016 Magnar Sveen
;; Author: Magnar Sveen <magnars@gmail.com> ;; Author: Magnar Sveen <magnars@gmail.com>
;; Version: 1.4.0 ;; Version: 1.4.0
@@ -22,7 +22,7 @@
;;; Commentary: ;;; Commentary:
;; Multiple cursors for Emacs. This is some pretty crazy functionality, so yes, ;; 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. ;; great success and much merriment.
;; ## Basic usage ;; ## Basic usage
@@ -68,7 +68,7 @@
;; - `mc/mark-previous-like-this`: Adds a cursor and region at the next part of the buffer backwards that matches the current region. ;; - `mc/mark-previous-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-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-previous-symbol-like-this`: Like `mc/mark-previous-like-this` but only for whole symbols.
;; - `mc/mark-more-like-this-extended`: Use arrow keys to quickly mark/skip next/previous occurances. ;; - `mc/mark-more-like-this-extended`: Use arrow keys to quickly mark/skip next/previous occurrences.
;; - `mc/add-cursor-on-click`: Bind to a mouse event to add cursors by clicking. See tips-section. ;; - `mc/add-cursor-on-click`: Bind to a mouse event to add cursors by clicking. See tips-section.
;; ### Mark many occurrences ;; ### Mark many occurrences
@@ -105,7 +105,7 @@
;; ;;
;; - Try pressing `mc/mark-next-like-this-word` or ;; - Try pressing `mc/mark-next-like-this-word` or
;; `mc/mark-next-like-this-symbol` with no region selected. It will ;; `mc/mark-next-like-this-symbol` with no region selected. It will
;; mark the symbol and add a cursor at the next occurance ;; mark the symbol and add a cursor at the next occurrence
;; ;;
;; - Try pressing `mc/mark-all-like-this-dwim` on a tagname in html-mode. ;; - Try pressing `mc/mark-all-like-this-dwim` on a tagname in html-mode.
;; ;;
@@ -186,13 +186,15 @@
;;; Code: ;;; Code:
(defgroup multiple-cursors nil
"Multiple cursors for emacs."
:group 'editing)
(require 'mc-edit-lines) (require 'mc-edit-lines)
(require 'mc-cycle-cursors)
(require 'mc-mark-more) (require 'mc-mark-more)
(require 'mc-mark-pop) (require 'mc-mark-pop)
(require 'rectangular-region-mode) (require 'rectangular-region-mode)
(require 'mc-separate-operations) (require 'mc-separate-operations)
(require 'mc-hide-unmatched-lines-mode)
(provide 'multiple-cursors) (provide 'multiple-cursors)
+4 -4
View File
@@ -1,6 +1,6 @@
;;; rectangular-region-mode.el ;;; rectangular-region-mode.el
;; Copyright (C) 2012 Magnar Sveen ;; Copyright (C) 2012-2016 Magnar Sveen
;; Author: Magnar Sveen <magnars@gmail.com> ;; Author: Magnar Sveen <magnars@gmail.com>
;; Keywords: editing cursors ;; Keywords: editing cursors
@@ -75,9 +75,9 @@ an exceedingly quick way of adding multiple cursors to multiple lines."
(rrm/remove-rectangular-region-overlays) (rrm/remove-rectangular-region-overlays)
(let* ((annoying-arrows-mode nil) (let* ((annoying-arrows-mode nil)
(point-column (current-column)) (point-column (current-column))
(point-line (line-number-at-pos)) (point-line (mc/line-number-at-pos))
(anchor-column (save-excursion (goto-char rrm/anchor) (current-column))) (anchor-column (save-excursion (goto-char rrm/anchor) (current-column)))
(anchor-line (save-excursion (goto-char rrm/anchor) (line-number-at-pos))) (anchor-line (save-excursion (goto-char rrm/anchor) (mc/line-number-at-pos)))
(left-column (if (< point-column anchor-column) point-column anchor-column)) (left-column (if (< point-column anchor-column) point-column anchor-column))
(right-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))) (navigation-step (if (< point-line anchor-line) 1 -1)))
@@ -85,7 +85,7 @@ an exceedingly quick way of adding multiple cursors to multiple lines."
(set-mark (point)) (set-mark (point))
(move-to-column point-column) (move-to-column point-column)
(mc/save-excursion (mc/save-excursion
(while (not (= anchor-line (line-number-at-pos))) (while (not (= anchor-line (mc/line-number-at-pos)))
(forward-line navigation-step) (forward-line navigation-step)
(move-to-column anchor-column) (move-to-column anchor-column)
(when (= anchor-column (current-column)) (when (= anchor-column (current-column))