{"id":13836987,"url":"https://github.com/hlissner/evil-multiedit","last_synced_at":"2025-04-07T05:12:23.953Z","repository":{"id":46002464,"uuid":"52172632","full_name":"hlissner/evil-multiedit","owner":"hlissner","description":"Multiple cursors for evil-mode, based on iedit","archived":false,"fork":false,"pushed_at":"2022-08-29T20:08:04.000Z","size":4947,"stargazers_count":335,"open_issues_count":16,"forks_count":12,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-05-01T19:48:27.577Z","etag":null,"topics":["emacs","emacs-packages","evil","melpa"],"latest_commit_sha":null,"homepage":"","language":"Emacs Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hlissner.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-02-20T19:58:51.000Z","updated_at":"2024-04-29T01:44:21.000Z","dependencies_parsed_at":"2022-09-16T15:51:02.571Z","dependency_job_id":null,"html_url":"https://github.com/hlissner/evil-multiedit","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hlissner%2Fevil-multiedit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hlissner%2Fevil-multiedit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hlissner%2Fevil-multiedit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hlissner%2Fevil-multiedit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hlissner","download_url":"https://codeload.github.com/hlissner/evil-multiedit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247595335,"owners_count":20963943,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["emacs","emacs-packages","evil","melpa"],"created_at":"2024-08-04T15:00:58.714Z","updated_at":"2025-04-07T05:12:23.935Z","avatar_url":"https://github.com/hlissner.png","language":"Emacs Lisp","funding_links":[],"categories":["Emacs Lisp"],"sub_categories":[],"readme":"[![Made with Doom Emacs](https://img.shields.io/badge/Made_with-Doom_Emacs-blueviolet.svg?style=flat-square\u0026logo=GNU%20Emacs\u0026logoColor=white)][Doom Emacs]\n![evil-multiedit](https://img.shields.io/badge/evil--multiedit-v1.3.8-blue.svg)\n[![MIT](https://img.shields.io/badge/license-MIT-green.svg)](./LICENSE)\n[![MELPA](http://melpa.org/packages/evil-multiedit-badge.svg)](http://melpa.org/#/evil-multiedit)\n[![MELPA Stable](http://stable.melpa.org/packages/evil-multiedit-badge.svg)](http://stable.melpa.org/#/evil-multiedit)\n[![Build Status](https://travis-ci.org/hlissner/evil-multiedit.png?branch=master)](https://travis-ci.org/hlissner/evil-multiedit)\n\n# evil-multiedit\n\nThis plugin was an answer to the lack of proper multiple cursor support in\nEmacs+evil. It allows you to select and edit matches interactively, integrating\n`iedit-mode` into evil-mode with an attempt at sensible defaults.\n\nSince then, [evil-mc] has matured, and now that I use both I've found they can\ncoexist, filling different niches, complimenting evil's built-in\ncolumn/line-wise editing operations.\n\n![evil-multiedit](../screenshots/main.gif?raw=true)\n\n\u003e Thanks to [syl20bnr] for his [evil-iedit-state] plugin, which this plugin was\n\u003e heavily inspired by.\n\n## Installation\n\nThe package is available on MELPA.\n\n`M-x package-install RET evil-multiedit`\n\nThen load it up with the default keybinds:\n\n```lisp\n(require 'evil-multiedit)\n(evil-multiedit-default-keybinds)\n```\n\n### Doom Emacs\n\nThis package comes pre-configured with [Doom Emacs], in its `:editor\nmultiple-cursors` module. [Enable this\nmodule](https://github.com/hlissner/doom-emacs/blob/develop/docs/getting_started.org#modules)\nand you're good to go!\n\n## Usage\n\nEvil-multiedit does not automatically bind any keys. Call\n`(evil-multiedit-default-keybinds)` to bind my recommended configuration:\n\n```elisp\n;; Highlights all matches of the selection in the buffer.\n(define-key evil-visual-state-map \"R\" 'evil-multiedit-match-all)\n\n;; Match the word under cursor (i.e. make it an edit region). Consecutive presses will\n;; incrementally add the next unmatched match.\n(define-key evil-normal-state-map (kbd \"M-d\") 'evil-multiedit-match-and-next)\n;; Match selected region.\n(define-key evil-visual-state-map (kbd \"M-d\") 'evil-multiedit-match-and-next)\n;; Insert marker at point\n(define-key evil-insert-state-map (kbd \"M-d\") 'evil-multiedit-toggle-marker-here)\n\n;; Same as M-d but in reverse.\n(define-key evil-normal-state-map (kbd \"M-D\") 'evil-multiedit-match-and-prev)\n(define-key evil-visual-state-map (kbd \"M-D\") 'evil-multiedit-match-and-prev)\n\n;; OPTIONAL: If you prefer to grab symbols rather than words, use\n;; `evil-multiedit-match-symbol-and-next` (or prev).\n\n;; Restore the last group of multiedit regions.\n(define-key evil-visual-state-map (kbd \"C-M-D\") 'evil-multiedit-restore)\n\n;; RET will toggle the region under the cursor\n(define-key evil-multiedit-state-map (kbd \"RET\") 'evil-multiedit-toggle-or-restrict-region)\n\n;; ...and in visual mode, RET will disable all fields outside the selected region\n(define-key evil-motion-state-map (kbd \"RET\") 'evil-multiedit-toggle-or-restrict-region)\n\n;; For moving between edit regions\n(define-key evil-multiedit-state-map (kbd \"C-n\") 'evil-multiedit-next)\n(define-key evil-multiedit-state-map (kbd \"C-p\") 'evil-multiedit-prev)\n(define-key evil-multiedit-insert-state-map (kbd \"C-n\") 'evil-multiedit-next)\n(define-key evil-multiedit-insert-state-map (kbd \"C-p\") 'evil-multiedit-prev)\n\n;; Ex command that allows you to invoke evil-multiedit with a regular expression, e.g.\n(evil-ex-define-cmd \"ie[dit]\" 'evil-multiedit-ex-match)\n```\n\nOnce regions are highlighted, changes are mirrored across them all.\n\nMany evil-mode motions/operators will have slightly different behavior while\nevil-multiedit is active or the cursor is in an iedit region:\n\n* `D`: clear the region\n* `C`: clear to end-of-region and go into insert mode\n* `A`: go into insert mode at end-of-region\n* `I`: go into insert mode at start-of-region\n* `V`: select the region\n* `P`: replace the iedit region with the contents of the clipboard\n* `$`: go to end-of-region\n* `0`/`^`: go to start-of-region\n* `gg`/`G`: go to the first/last region\n\nTo disable these, set `evil-multiedit-dwim-motion-keys` to `nil` before loading\nevil-multiedit.\n\nNOTE: No need to bind a key for `evil-multiedit-abort`, pressing \u003ckbd\u003eESC\u003c/kbd\u003e\nin normal mode will invoke it.\n\n### Ex Command\n\n`:iedit [REGEXP]` is available for invoking multiedit from the ex command line.\n\n### Commands\n\n* `evil-multiedit-restore`: Restore the last evil-multiedit session.\n* `evil-multiedit-match-all`: Create iedit regions of all matches of the current\n  selection (or symbol at point) as multiedit regions.\n* `evil-multiedit-match-and-next`:\n* `evil-multiedit-match-and-prev`\n* `evil-multiedit-match-symbol-and-next`\n* `evil-multiedit-match-symbol-and-prev`\n* `evil-multiedit-toggle-marker-here`\n* `evil-multiedit-toggle-or-restrict-region`\n* `evil-multiedit-next`\n* `evil-multiedit-prev`\n* `evil-multiedit-abort`\n* `evil-multiedit-ex-match`\n\n### Options\n\n* `evil-multiedit-dwim-motion-keys` (default: `t`): If non-nil, evil's motion\n  keys behave differently when the point is inside a multiedit region. Must be\n  set before evil-multiedit is loaded.\n* `evil-multiedit-ignore-indent-and-trailing` (default: `t`): If non-nil, skip\n  over indentation and trailing whitespace in iedit matches.\n* `evil-multiedit-scope` (default `nil`): How far evil-multiedit should look for\n  incremental matches (doesn't affect `evil-multiedit-match-all` or\n  `evil-multiedit-ex-match`). Accepts anything that `bounds-of-thing-at-point`\n  accepts, such as `'defun`, `'sexp`, `'email` or the default, `'buffer`.\n* `evil-multiedit-smart-match-boundaries` (default `t`): If non-nil, multiedit\n  will treat matches as atoms when invoked from normal mode. E.g.\n  * `evil-multiedit-match` will not match `evil-multiedit-match-all`\n  * `i` will only match `i` and not every individual i in `ignition`.\n  * **NOTE:** If evil-multiedit is invoked from visual mode, this is ignored.\n* `evil-multiedit-store-in-search-history` (default `nil`): If non-nil,\n  highlighted occurrences are stored in `regexp-search-ring`, so that after\n  exiting iedit `evil-search-next` and `evil-search-previous` (usually n and N)\n  use the last occurrence as if it were the last string in the search history.\n* `evil-multiedit-follow-matches` (default `nil`): If non-nil, the cursor will\n  jump to each additional match, rather than remain in its original position.\n\n### Co-existing with evil-mc\n\nHow the two plugins mingle is entirely personal preference. I often reach for\nevil-mc for more complex operations and evil-multiedit for simpler ones.\n\nMy strategy is to bind evil-multiedit to \u003ckbd\u003eM-d\u003c/kbd\u003e/\u003ckbd\u003eM-D\u003c/kbd\u003e, and\nevil-mc to a bunch of keys prefixed with \u003ckbd\u003egz\u003c/kbd\u003e:\n\n```emacs-lisp\n;; evil-multiedit\n(evil-define-key 'normal 'global\n  (kbd \"M-d\")   #'evil-multiedit-match-symbol-and-next\n  (kbd \"M-D\")   #'evil-multiedit-match-symbol-and-prev)\n(evil-define-key 'visual 'global\n  \"R\"           #'evil-multiedit-match-all\n  (kbd \"M-d\")   #'evil-multiedit-match-and-next\n  (kbd \"M-D\")   #'evil-multiedit-match-and-prev)\n(evil-define-key '(visual normal) 'global\n  (kbd \"C-M-d\") #'evil-multiedit-restore)\n\n(with-eval-after-load 'evil-mutliedit\n  (evil-define-key 'multiedit 'global\n    (kbd \"M-d\")   #'evil-multiedit-match-and-next\n    (kbd \"M-S-d\") #'evil-multiedit-match-and-prev\n    (kbd \"RET\")   #'evil-multiedit-toggle-or-restrict-region)\n  (evil-define-key '(multiedit multiedit-insert) 'global\n    (kbd \"C-n\")   #'evil-multiedit-next\n    (kbd \"C-p\")   #'evil-multiedit-prev))\n\n;; evil-mc\n(evil-define-key '(normal visual) 'global\n  \"gzm\" #'evil-mc-make-all-cursors\n  \"gzu\" #'evil-mc-undo-all-cursors\n  \"gzz\" #'+evil/mc-toggle-cursors\n  \"gzc\" #'+evil/mc-make-cursor-here\n  \"gzn\" #'evil-mc-make-and-goto-next-cursor\n  \"gzp\" #'evil-mc-make-and-goto-prev-cursor\n  \"gzN\" #'evil-mc-make-and-goto-last-cursor\n  \"gzP\" #'evil-mc-make-and-goto-first-cursor)\n(with-eval-after-load 'evil-mc\n  (evil-define-key '(normal visual) evil-mc-key-map\n    (kbd \"C-n\") #'evil-mc-make-and-goto-next-cursor\n    (kbd \"C-N\") #'evil-mc-make-and-goto-last-cursor\n    (kbd \"C-p\") #'evil-mc-make-and-goto-prev-cursor\n    (kbd \"C-P\") #'evil-mc-make-and-goto-first-cursor))\n```\n\nNOTE: These are the default keybindings on [Doom Emacs]. Doom users don't need\nto bind these.\n\n\n[Doom Emacs]: https://github.com/hlissner/doom-emacs\n[evil-iedit-state]: https://github.com/syl20bnr/evil-iedit-state\n[evil-mc]: https://github.com/gabesoft/evil-mc\n[evil-mode]: https://bitbucket.org/lyro/evil/wiki/Home\n[syl20bnr]: https://github.com/syl20bnr\n[vim-multiedit]: https://github.com/hlissner/vim-multiedit\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhlissner%2Fevil-multiedit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhlissner%2Fevil-multiedit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhlissner%2Fevil-multiedit/lists"}