reddit / emacs

Multiple Cursor functionality with Vanilla Emacs

pudentia · 2022-08-29 10:25
Is there a way to get Emacs to use its built in functionality to do what multiple cursors do, but without installing any packages? I am thinking esp. of the following: \- delete lines that match a searched string
vifon · 2022-08-29 10:40
Check the commands `delete-matching-lines` and `delete-non-matching-lines`. For a more general functionality, you may want to read my post about these matters: https://blog.einval.eu/2022/03/multiple-cursors-considered-suboptimal/
bestlem · 2022-08-29 11:09
Before I came across multiple-cursors and iedit I used keyboard macros for this sort of thing. Start recording a macro search-forward for the string move to beginning of line kill line stop recording Then you can run the macro repeatably.
NDcodes · 2022-08-29 11:28
You could just use replace-regexp for your specific case. Just replace this regexp: ^.*\(your-string\).*$ With an empty string “”.
nu0or · 2022-08-29 11:44
do you guys actually use multiple cursors? its one of those things that looks good but after a few times it becomes a useless distraction
dharris · 2022-08-29 12:04
The videos on that page aren’t playing for me. Known issue?
mickeyp · 2022-08-29 12:10
In addition to what /u/vifon says about `M-x flush/keep-lines`, you can generalise it further and use editable occur to match against a regexp and then commit the changes back to the source file(s): https://www.masteringemacs.org/article/searching-buffers-occur-mode
ispinfx · 2022-08-29 12:12
What's the font in the video?
ramin-honary-xc · 2022-08-29 12:57
I prefer the `occur` mode, which I think is by default bound to `M-s o` (the `M-s` key prefix binds to a few miscelanous search commands). [Mickey Peterson has an article](https://www.masteringemacs.org/article/searching-buffers-occur-mode ) on how to do this. What Occur mode does is prompts for a Regex, then it displays an interactive buffer for all lines that contain matches for that regex. The Occur mode buffer starts out in "read only" minor mode, but you can press `e` to switch to "edit" minor mode. In "edit" minor mode, you can make any changes to any of the lines you see, including using commands like `query-replace` (bound to `M-%`), or `query-replace-regexp` (bound to `C-M-%`), or `string-rectangle` (`C-x r t`), to edit many lines at once. And yes, you can just delete all the lines. Once you are done making changes to the Occur Mode buffer, type `C-c C-c` to commit the changes to your buffer, and this also switches you back to "read-only" minor mode.
pudentia · 2022-08-29 13:00
>Thank you. That's great!
ocodo · 2022-08-29 13:11
M-x flush-lines.
ocodo · 2022-08-29 13:13
Yep, +1 for occur in fresh from the box Emacs. I'd reach for iedit but occur/occur edit get their fair share of use. Should we mention wgrep mode too? (edit all files lines matching a grep.) /u/pudentia
pudentia · 2022-08-29 13:15
If I delete an entire line using this approach, the line in the document remains blank instead of deleted.
ocodo · 2022-08-29 13:19
With mentions of M-x query-replace-regexp we need to mention `match-string` and its interactive equivalents `\1`,`\2` etc (which aren't that alien to regexps in the large.) - `\&` use the whole match in replacement - elisp: `(match-string 0)` - `\N` use sub match (i.e. regexp group) number `N` in the replacement. - in elisp `(match-string N)` - `\#N` as with `\N` treating the value as a number. - in elisp `(string-to-number (match-string N))` - `\#&` as with `\&` treating the value as a number. - in elisp `(string-to-number (match-string 0))` - `\?` replace interactively, letting you edit at that point during replacement. - in elisp ... **I don't know!** - `\#` replacement counter - in elisp the `replace-count` variable. Emacs also lets you replace with a function/lisp code, which I always like. The real magic... \,(any-lisp-code (format "%s and you can include \1 and \& and \# in the code." \2) (If you need to do this in "proper" emacs lisp, `\&` is `(match-string 0)` `\1` is `(match-string 1)` etc. ... anyone know what `\#` is in emacs-lisp? I'd just `let` a counter and increment... ) ~~**Edit:** looking at the source: `\#` counter. When you're using a function based replacement, in lisp code, you can use the `replace-count` variable.~~ added to the list above ~~###### `\?` - edit replacement interactively.~~ ~~I forgot completely about this. In the replacement string using `\?` lets you edit during the actual interactive replacement.~~ added above.
pudentia · 2022-08-29 13:46
>iedit I had not heard of this before. Thanks.
vifon · 2022-08-29 13:56
JetBrains Mono
vifon · 2022-08-29 13:57
They work just fine for me. What browser are you using? Firefox on my side.
[deleted] · 2022-08-29 14:23
[removed]
remillard · 2022-08-29 14:52
I use it pretty regularly. I keep my constraints and code beautified (VHDL Mode in Emacs) and sometimes need to add or subtract prefix namespaces or suffix descriptions to batches of signals. When everything is lined up perfectly, it's pretty handy. I don't really use a lot of the larger functionality though. Just extending a cursor up or down in a column is sufficient.
ocodo · 2022-08-29 15:07
I use it daily since ... pfft I don't know, years.
ieure · 2022-08-29 15:51
I fairly often use rectangular selections as a poor man's multiple cursors. If you have, say, a bunch of variables aligned on the same column, you can C-RET on the first column, type in the new name, and delete the old one.
No-Command-791 · 2022-08-29 15:56
Yes, all the time. My most common use case is bulk editing org timestamps, but I find them handy in a variety of contexts. Not sure how they're distracting.
xtifr · 2022-08-29 18:43
I may be missing something (wouldn't be the first time), but that sounds like a job for the rectangle-mode commands, esp. delete-rectangle (`C-x r d`) and string-rectangle (`C-x r t`). Or, of course, query-replace-regexp or occur. (Good mnemonic for `C-x r t` is "rectangle text".)
amareshjoshi · 2022-08-29 18:46
what's the command that commits the changes. `C-h m` in occur mode lists ``` C-c C-c occur-mode-goto-occurrence ``` I can't see any command that commits the changes.
ruscaire · 2022-08-29 19:10
Have you switched to edit mode with ‘e’?
scruffie · 2022-08-29 19:45
I usually do this with `narrow-to-region` (`C-x n n`), then `query-replace` (`M-%`) or `query-replace-regexp`, followed by applying the replacement to all (`!`) if it looks right. Narrowing makes it easier to use less ... selective ... techniques, without damaging the rest of the buffer (e.g., replacing all semicolons with another string).
remillard · 2022-08-29 20:49
Well, there's probably multiple ways to skin this cat. I have used the rectangle mode before, but not regularly and while I can mark corners of a rectangle, for me it feels more contextually for kill/yank of the space rather than operating on just the leading edge of the rectangle. Meanwhile the multiple cursors contextually shows exactly what I mean to do, emplacing multiple points and inserting or deleting text at those points. So it makes more sense to me. Both modes to me have specific use cases that works in my brain.
amareshjoshi · 2022-08-30 01:47
yeah, i can switch to edit mode with `e` and edit the `*Occur*` buffer, but `C-c C-c` just switches me back to occur mode. but original file is unchanged. the mode help `C-h m` doesn't seem to have any "commit changes to buffer command". I also tried with `emacs -q` to make sure none of my customizations were interfering, same behavior. I checked command aprops and couldn't find any likely `occur-*` command.
da-g · 2022-08-30 02:20
I use it all the time in combination with expand-region. For example, selecting a word and then creating different cursors at different locations. It's a bit more versatile than rectangles and query-replaces, since it plays well with things like smartparens, and I like that I can capitalize on muscle memory instead of having to craft a regexp to get things done.
pudentia · 2022-08-30 04:30
That is a helpful tip. Will use!
pudentia · 2022-08-30 04:31
With rectangular selections and macros and query-replace, it seems I am covered. Thank you.
chrinto · 2022-08-30 05:18
Macros are extremely powerful, you can also run a macro multiple times by using a prefix number (C-u 1000 F4). A macro can for instance search for a specific text and delete the entire line F3 C-s my-text C-a C-k C-k F4
ramin-honary-xc · 2022-08-30 06:38
Oh, that's rights, it doesn't get rid of the trailing line break. Sorry about that. In that case, I recommend you use the `flush-lines` command, which deletes all lines in the buffer that match a regex. It works exactly like `grep -ve <regex>`. The inverse is `keep-lines` which deletes all lines that do not match a regex.
ramin-honary-xc · 2022-08-30 06:42
That is odd, my Occur-mode does not behave this way. I switch to `occur-edit` mode with `e`, I press `C-c C-c` to go back to ordinary read-only `occur` mode. The `C-c C-c` command in ordinary read-only `occur-mode` does do `occur-mode-goto-occurrence`. When you press `e`, makes sure the modeline says `Occur-Edit` as the major mode, and try it again. That is all I can think of now.
amareshjoshi · 2022-08-30 14:06
thanks. it does change to occur-edit in the mode line when i press "e". ans occur mode is still pretty useful on it's own. i'll keep playing with it.
amareshjoshi · 2022-08-30 15:45
i figured it out. you can't delete the entire line. you need to go past the ":" after the line number and delete the rest of the line (or do any other editing). that works.
harizvi · 2022-08-30 16:55
Good reminder that you can use arbitrary lisp code incl format in query-replace-regexp. I mostly forget it, and do a shell-commmand-on-region (somewhat with prefix for in-place substitution) to use cut or awk externally. Other than that, occur and grep / wgrep combo also come in handy as others have commented.
pudentia · 2022-08-30 20:17
Thanks again.