13 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
10 changed files with 91 additions and 44 deletions
+22 -5
View File
@@ -1,9 +1,26 @@
# 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,
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`.
@@ -65,7 +82,7 @@ You can [watch an intro to multiple-cursors at Emacs Rocks](http://emacsrocks.co
- `mc/mark-previous-like-this-symbol`: Adds a cursor and region at the next part of the buffer backwards that matches the current region, if no region is selected it selects the symbol at the point.
- `mc/mark-previous-word-like-this`: Like `mc/mark-previous-like-this` but only for whole words.
- `mc/mark-previous-symbol-like-this`: Like `mc/mark-previous-like-this` but only for whole symbols.
- `mc/mark-more-like-this-extended`: Use arrow keys to quickly mark/skip next/previous 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/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.
@@ -73,8 +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-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-previous-like-this`: Remove the cursor furthest up, marking the next occurance up.
- `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.
### Mark many occurrences
@@ -117,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
`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.
@@ -1,4 +1,4 @@
(require 'cl) ;; For lexical-let
;; -*- lexical-binding: t -*-
(When "^I mark next like this$"
(lambda () (call-interactively 'mc/mark-next-like-this)))
@@ -109,26 +109,22 @@
(When "^I copy \"\\(.+\\)\" in another program$"
(lambda (text)
(lexical-let ((text text))
(setq interprogram-paste-function
#'(lambda () (let ((r text)) (setq text nil) r))))))
#'(lambda () (let ((r text)) (setq text nil) r)))))
(Given "^I have bound C-! to a lambda that inserts \"\\(.+\\)\"$"
(lambda (ins)
(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 \"\\(.+\\)\"$"
(lambda (ins)
(lexical-let ((ins ins))
(defun mc-test-temp-command () (interactive) (insert ins))
(global-set-key (kbd "C-!") 'mc-test-temp-command))))
(global-set-key (kbd "C-!") 'mc-test-temp-command)))
(Given "^I have bound C-! to another new command that inserts \"\\(.+\\)\"$"
(lambda (ins)
(lexical-let ((ins ins))
(defun mc-test-temp-command-2 () (interactive) (insert ins))
(global-set-key (kbd "C-!") 'mc-test-temp-command-2))))
(global-set-key (kbd "C-!") 'mc-test-temp-command-2)))
(Given "^I have bound C-! to a keyboard macro that insert \"_\"$"
(lambda ()
+1 -1
View File
@@ -88,7 +88,7 @@
(cl-defun mc/cycle (next-cursor fallback-cursor loop-message)
(when (null next-cursor)
(when (eql 'stop (mc/handle-loop-condition loop-message))
(return-from mc/cycle nil))
(cl-return-from mc/cycle nil))
(setf next-cursor fallback-cursor))
(mc/create-fake-cursor-at-point)
(mc/pop-state-from-overlay next-cursor)
+3 -3
View File
@@ -54,8 +54,8 @@ other non-nil value will cause short lines to be padded."
(error "Mark a set of lines first"))
(mc/remove-fake-cursors)
(let* ((col (current-column))
(point-line (line-number-at-pos))
(mark-line (progn (exchange-point-and-mark) (line-number-at-pos)))
(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
@@ -71,7 +71,7 @@ other non-nil value will cause short lines to be padded."
(previous-logical-line 1 nil)
(move-to-column col))
;; Add the cursors
(while (not (eq (line-number-at-pos) point-line))
(while (not (eq (mc/line-number-at-pos) point-line))
;; Pad the line
(when (eq style 'pad)
(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
@@ -73,7 +73,7 @@ mode. To leave this mode press <return> or \"C-g\""
:group 'multiple-cursors)
(defcustom hum/placeholder "..."
"Placeholder which will be placed insted of hiden text"
"Placeholder which will be placed instead of hidden text"
:type '(string)
:group 'multiple-cursors)
@@ -103,5 +103,6 @@ mode. To leave this mode press <return> or \"C-g\""
(defun hum/unhide-unmatched-lines ()
(remove-overlays nil nil hum/invisible-overlay-name t))
(provide 'mc-hide-unmatched-lines-mode)
(define-key mc/keymap (kbd "C-'") 'mc-hide-unmatched-lines-mode)
(provide 'mc-hide-unmatched-lines-mode)
+4 -4
View File
@@ -190,7 +190,7 @@ With zero ARG, skip the last one and mark next."
(defun mc/mark-next-word-like-this (arg)
"Find and mark the next word of the buffer matching the currently active region
The matching region must be a whole word to be a match
If no region is active, mark the symbol at the point and find the next 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")
@@ -201,7 +201,7 @@ With zero ARG, skip the last one and mark next."
(defun mc/mark-next-symbol-like-this (arg)
"Find and mark the next symbol of the buffer matching the currently active region
The matching region must be a whole symbol to be a match
If no region is active, mark the symbol at the point and find the next 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")
@@ -579,8 +579,8 @@ If the region is inactive or on a single line, it will behave like
(interactive "P")
(if (and (use-region-p)
(not (> (mc/num-cursors) 1))
(not (= (line-number-at-pos (region-beginning))
(line-number-at-pos (region-end)))))
(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))
+1 -1
View File
@@ -124,7 +124,7 @@
;;;###autoload
(defun mc/vertical-align (character)
"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."
(interactive "c")
(let ((rightest-column (current-column)))
+41 -6
View File
@@ -109,6 +109,19 @@
(and (listp cursor-type)
(eq (car cursor-type) 'bar))))
(defun mc/line-number-at-pos (&optional pos absolute)
"Faster implementation of `line-number-at-pos'."
(if pos
(save-excursion
(if absolute
(save-restriction
(widen)
(goto-char pos)
(string-to-number (format-mode-line "%l")))
(goto-char pos)
(string-to-number (format-mode-line "%l"))))
(string-to-number (format-mode-line "%l"))))
(defun mc/make-cursor-overlay-at-eol (pos)
"Create overlay to look like cursor at end of line."
(let ((overlay (make-overlay pos pos nil nil nil)))
@@ -149,7 +162,18 @@ highlights the entire width of the window."
autopair-action
autopair-wrap-action
temporary-goal-column
er/history)
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.")
(defun mc/store-current-state-in-overlay (o)
@@ -424,6 +448,10 @@ the original cursor, to inform about the lack of support."
(message "%S is not supported with multiple cursors%s"
original-command
(get original-command 'mc--unsupported))
;; lazy-load the user's list file
(mc/load-lists)
(when (and original-command
(not (memq original-command mc--default-cmds-to-run-once))
(not (memq original-command mc/cmds-to-run-once))
@@ -579,7 +607,7 @@ from being executed if in multiple-cursors-mode."
(when interprogram-paste
;; Add interprogram-paste to normal kill ring, just
;; like current-kill usually does for itself.
;; We have to do the work for it 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.
(let ((interprogram-cut-function nil))
(if (listp interprogram-paste)
@@ -602,6 +630,15 @@ for running commands with multiple cursors."
:type 'file
:group 'multiple-cursors)
(defvar mc--list-file-loaded nil
"Whether the list file has already been loaded.")
(defun mc/load-lists ()
"Loads preferences for running commands with multiple cursors from `mc/list-file'"
(unless mc--list-file-loaded
(load mc/list-file 'noerror 'nomessage)
(setq mc--list-file-loaded t)))
(defun mc/dump-list (list-symbol)
"Insert (setq 'LIST-SYMBOL LIST-VALUE) to current buffer."
(cl-symbol-macrolet ((value (symbol-value list-symbol)))
@@ -806,11 +843,9 @@ for running commands with multiple cursors."
(defvar mc/cmds-to-run-for-all nil
"Commands to run for all cursors in multiple-cursors-mode")
;; load, but no errors if it does not exist yet please, and no message
;; while loading
(load mc/list-file 'noerror 'nomessage)
(provide 'multiple-cursors-core)
(require 'mc-cycle-cursors)
(require 'mc-hide-unmatched-lines-mode)
;; Local Variables:
;; coding: utf-8
+3 -5
View File
@@ -22,7 +22,7 @@
;;; 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
@@ -68,7 +68,7 @@
;; - `mc/mark-previous-like-this`: Adds a cursor and region at the next part of the buffer backwards that matches the current region.
;; - `mc/mark-previous-word-like-this`: Like `mc/mark-previous-like-this` but only for whole words.
;; - `mc/mark-previous-symbol-like-this`: Like `mc/mark-previous-like-this` but only for whole symbols.
;; - `mc/mark-more-like-this-extended`: Use arrow keys to quickly mark/skip next/previous 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.
;; ### Mark many occurrences
@@ -105,7 +105,7 @@
;;
;; - Try pressing `mc/mark-next-like-this-word` or
;; `mc/mark-next-like-this-symbol` with no region selected. It will
;; mark the symbol and add a cursor at the next 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.
;;
@@ -191,12 +191,10 @@
:group 'editing)
(require 'mc-edit-lines)
(require 'mc-cycle-cursors)
(require 'mc-mark-more)
(require 'mc-mark-pop)
(require 'rectangular-region-mode)
(require 'mc-separate-operations)
(require 'mc-hide-unmatched-lines-mode)
(provide 'multiple-cursors)
+3 -3
View File
@@ -75,9 +75,9 @@ an exceedingly quick way of adding multiple cursors to multiple lines."
(rrm/remove-rectangular-region-overlays)
(let* ((annoying-arrows-mode nil)
(point-column (current-column))
(point-line (line-number-at-pos))
(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) (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))
(right-column (if (> point-column anchor-column) point-column anchor-column))
(navigation-step (if (< point-line anchor-line) 1 -1)))
@@ -85,7 +85,7 @@ an exceedingly quick way of adding multiple cursors to multiple lines."
(set-mark (point))
(move-to-column point-column)
(mc/save-excursion
(while (not (= anchor-line (line-number-at-pos)))
(while (not (= anchor-line (mc/line-number-at-pos)))
(forward-line navigation-step)
(move-to-column anchor-column)
(when (= anchor-column (current-column))