GitHub - hlissner/evil-multiedit: Multiple cursors for evil-mode, based on iedit
source link: https://github.com/hlissner/evil-multiedit
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
evil-multiedit
This plugin was an answer to the lack of proper multiple cursor support in
Emacs+evil. It allows you to select and edit matches interactively, integrating
iedit-mode
into evil-mode with an attempt at sensible defaults.
Since then, evil-mc has matured, and now that I use both I've found they can coexist, filling different niches, complimenting evil's built-in column/line-wise editing operations.
Thanks to syl20bnr for his evil-iedit-state plugin, which this plugin was heavily inspired by.
Installation
The package is available on MELPA.
M-x package-install RET evil-multiedit
Then load it up with the default keybinds:
(require 'evil-multiedit)
(evil-multiedit-default-keybinds)
Doom Emacs
This package comes pre-configured with Doom Emacs, in its :editor multiple-cursors
module. Enable this
module
and you're good to go!
Usage
Evil-multiedit does not automatically bind any keys. Call
(evil-multiedit-default-keybinds)
to bind my recommended configuration:
;; Highlights all matches of the selection in the buffer.
(define-key evil-visual-state-map "R" 'evil-multiedit-match-all)
;; Match the word under cursor (i.e. make it an edit region). Consecutive presses will
;; incrementally add the next unmatched match.
(define-key evil-normal-state-map (kbd "M-d") 'evil-multiedit-match-and-next)
;; Match selected region.
(define-key evil-visual-state-map (kbd "M-d") 'evil-multiedit-match-and-next)
;; Insert marker at point
(define-key evil-insert-state-map (kbd "M-d") 'evil-multiedit-toggle-marker-here)
;; Same as M-d but in reverse.
(define-key evil-normal-state-map (kbd "M-D") 'evil-multiedit-match-and-prev)
(define-key evil-visual-state-map (kbd "M-D") 'evil-multiedit-match-and-prev)
;; OPTIONAL: If you prefer to grab symbols rather than words, use
;; `evil-multiedit-match-symbol-and-next` (or prev).
;; Restore the last group of multiedit regions.
(define-key evil-visual-state-map (kbd "C-M-D") 'evil-multiedit-restore)
;; RET will toggle the region under the cursor
(define-key evil-multiedit-state-map (kbd "RET") 'evil-multiedit-toggle-or-restrict-region)
;; ...and in visual mode, RET will disable all fields outside the selected region
(define-key evil-motion-state-map (kbd "RET") 'evil-multiedit-toggle-or-restrict-region)
;; For moving between edit regions
(define-key evil-multiedit-state-map (kbd "C-n") 'evil-multiedit-next)
(define-key evil-multiedit-state-map (kbd "C-p") 'evil-multiedit-prev)
(define-key evil-multiedit-insert-state-map (kbd "C-n") 'evil-multiedit-next)
(define-key evil-multiedit-insert-state-map (kbd "C-p") 'evil-multiedit-prev)
;; Ex command that allows you to invoke evil-multiedit with a regular expression, e.g.
(evil-ex-define-cmd "ie[dit]" 'evil-multiedit-ex-match)
Once regions are highlighted, changes are mirrored across them all.
Many evil-mode motions/operators will have slightly different behavior while evil-multiedit is active or the cursor is in an iedit region:
D
: clear the regionC
: clear to end-of-region and go into insert modeA
: go into insert mode at end-of-regionI
: go into insert mode at start-of-regionV
: select the regionP
: replace the iedit region with the contents of the clipboard$
: go to end-of-region0
/^
: go to start-of-regiongg
/G
: go to the first/last region
To disable these, set evil-multiedit-dwim-motion-keys
to nil
before loading
evil-multiedit.
NOTE: No need to bind a key for evil-multiedit-abort
, pressing ESC
in normal mode will invoke it.
Ex Command
:iedit [REGEXP]
is available for invoking multiedit from the ex command line.
Commands
evil-multiedit-restore
: Restore the last evil-multiedit session.evil-multiedit-match-all
: Create iedit regions of all matches of the current selection (or symbol at point) as multiedit regions.evil-multiedit-match-and-next
:evil-multiedit-match-and-prev
evil-multiedit-match-symbol-and-next
evil-multiedit-match-symbol-and-prev
evil-multiedit-toggle-marker-here
evil-multiedit-toggle-or-restrict-region
evil-multiedit-next
evil-multiedit-prev
evil-multiedit-abort
evil-multiedit-ex-match
Options
evil-multiedit-dwim-motion-keys
(default:t
): If non-nil, evil's motion keys behave differently when the point is inside a multiedit region. Must be set before evil-multiedit is loaded.evil-multiedit-ignore-indent-and-trailing
(default:t
): If non-nil, skip over indentation and trailing whitespace in iedit matches.evil-multiedit-scope
(defaultnil
): How far evil-multiedit should look for incremental matches (doesn't affectevil-multiedit-match-all
orevil-multiedit-ex-match
). Accepts anything thatbounds-of-thing-at-point
accepts, such as'defun
,'sexp
,'email
or the default,'buffer
.evil-multiedit-smart-match-boundaries
(defaultt
): If non-nil, multiedit will treat matches as atoms when invoked from normal mode. E.g.evil-multiedit-match
will not matchevil-multiedit-match-all
i
will only matchi
and not every individual i inignition
.- NOTE: If evil-multiedit is invoked from visual mode, this is ignored.
evil-multiedit-store-in-search-history
(defaultnil
): If non-nil, highlighted occurrences are stored inregexp-search-ring
, so that after exiting ieditevil-search-next
andevil-search-previous
(usually n and N) use the last occurrence as if it were the last string in the search history.evil-multiedit-follow-matches
(defaultnil
): If non-nil, the cursor will jump to each additional match, rather than remain in its original position.
Co-existing with evil-mc
How the two plugins mingle is entirely personal preference. I often reach for evil-mc for more complex operations and evil-multiedit for simpler ones.
My strategy is to bind evil-multiedit to M-d/M-D, and evil-mc to a bunch of keys prefixed with gz:
;; evil-multiedit
(evil-define-key 'normal 'global
(kbd "M-d") #'evil-multiedit-match-symbol-and-next
(kbd "M-D") #'evil-multiedit-match-symbol-and-prev)
(evil-define-key 'visual 'global
"R" #'evil-multiedit-match-all
(kbd "M-d") #'evil-multiedit-match-and-next
(kbd "M-D") #'evil-multiedit-match-and-prev)
(evil-define-key '(visual normal) 'global
(kbd "C-M-d") #'evil-multiedit-restore)
(with-eval-after-load 'evil-mutliedit
(evil-define-key 'multiedit 'global
(kbd "M-d") #'evil-multiedit-match-and-next
(kbd "M-S-d") #'evil-multiedit-match-and-prev
(kbd "RET") #'evil-multiedit-toggle-or-restrict-region)
(evil-define-key '(multiedit multiedit-insert) 'global
(kbd "C-n") #'evil-multiedit-next
(kbd "C-p") #'evil-multiedit-prev))
;; evil-mc
(evil-define-key '(normal visual) 'global
"gzm" #'evil-mc-make-all-cursors
"gzu" #'evil-mc-undo-all-cursors
"gzz" #'+evil/mc-toggle-cursors
"gzc" #'+evil/mc-make-cursor-here
"gzn" #'evil-mc-make-and-goto-next-cursor
"gzp" #'evil-mc-make-and-goto-prev-cursor
"gzN" #'evil-mc-make-and-goto-last-cursor
"gzP" #'evil-mc-make-and-goto-first-cursor)
(with-eval-after-load 'evil-mc
(evil-define-key '(normal visual) evil-mc-key-map
(kbd "C-n") #'evil-mc-make-and-goto-next-cursor
(kbd "C-N") #'evil-mc-make-and-goto-last-cursor
(kbd "C-p") #'evil-mc-make-and-goto-prev-cursor
(kbd "C-P") #'evil-mc-make-and-goto-first-cursor))
NOTE: These are the default keybindings on Doom Emacs. Doom users don't need to bind these.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK