
Gap Buffers Are Not Optimized for Multiple Cursors - signa11
http://nullprogram.com/blog/2017/09/07/
======
raphlinus
The first part of the article is true; gap buffers are not a data structure
particularly optimized for multiple cursor edits. The conclusion is
ridiculous. Of course you can provoke noticeable slowdown by doing an edit
with thousands of cursors, but most people are doing small edits to small
files, so the cost of the memmove operations is probably in the microseconds
per cursor range. If multiple cursors feel intuitive to use and gives
immediate visual feedback, why shouldn't people use them?

I say this as someone who has chosen a more sophisticated data structure
(ropes) in the editor I'm working on.

~~~
zypeh
Beside data structure based on B+ tree (ropes), what do you think about
Relaxed Radix Balanced Vector tree[0]? It is cache-friendly and immutable as
well.

[0]([https://icfp17.sigplan.org/event/icfp-2017-papers-
persistenc...](https://icfp17.sigplan.org/event/icfp-2017-papers-persistence-
for-the-masses-rrb-vectors-in-a-systems-language))

~~~
raphlinus
Looks pretty neat, thanks for the link. From a quick look, it seems like the
performance characteristics will be pretty similar to a xi-style rope (it
seems extremely unlikely to me that the time spent finding the child is
significant, so the radix trick can't save much time), and it's a bit more
complex. That said, I do expect it to perform nicely for read-only access to
large documents, which is definitely an important use case.

It would make a fun project for somebody to implement it and compare the
performance. I'd certainly take the PR for it if the performance was better :)

[edit: followup] The rope implementation in xi has an additional heuristic
that tries not to split lines across leaf boundaries (ie most leaves should
end in a newline). It also has a hard constraint of not splitting a unicode
codepoint. Thus, leaves and subtrees would have an unpredictable number of
elements (as opposed to being a clean power of two when full) and I think that
pretty much invalidates using the radix to select the child.

------
mannigfaltig
Come on now. The advantage of multiple cursors is _instant feedback_ by
cycling through the cursors and observing all the changes in real-time and by
being able to undo changes and interactively adapt to the observed problems,
without having to redefine the entire sequence of actions. Macros can achieve
the same, but in many cases it just takes much more time.

~~~
davexunit
Rectangle editing commands in Emacs take care of 99% of the applications of
multiple cursors. I have never had a use for them.

~~~
Veedrac
Rectangle edits are equivalent to a _tiny_ minority of what I use multiple
cursors for (and are generally just rare overall), so this doesn't make much
sense to me.

~~~
mcherm
> Rectangle edits are equivalent to a tiny minority of what I use multiple
> cursors for

Okay, now THAT is interesting. Can you comment on some of the other uses you
have for multiple cursors? Perhaps give some examples?

~~~
Veedrac
As an example, at the moment I'm juggling a large number of constants where
I'm still learning how to classify and group them. I can use alt-d and alt-
shift-d to select between local groups, either whole words or just suffixes,
and rename them locally. A multiselection is normally, say, 3 to 10 selections
of 3 to 10 characters, so the edits themselves are far too tiny and frequent
for macros to meaningfully help, yet far too irregular for column selection to
help. At the same time, multiple selections are acting as an incremental
search and a way to jump between places.

Frequently I do want to do regular operations, but columns are way too
restrictive. Say I had something like the anonymized code

    
    
        Salad foo;
        foo.fred   = chance(mulch, 4, 1);
        foo.fools  = chance(mulch, 7, 4);
        foo.cheese = chance(mulch, 10, 7);
    
        Salad bar;
        bar.run  = chance(mulch, 4, 1);
        bar.jump = chance(mulch, 7, 4);
        bar.fly  = chance(mulch, 12, 7);
    
        Salad crouton;
        crouton.crunch = chance(mulch, 4, 1);
        crouton.splat  = chance(mulch, 7, 4);
        crouton.swim   = chance(mulch, 12, 7);
    

and I wanted to subtract one from the middle argument to each call to
`chance`. Column selections aren't impossible here, because there is some
structure, but with multiple cursors I can just select all the relevant
`chance`, ctrl-right to the end of the relevant number, write "-1", ctrl-
shift-left so I select the expression, and press my evaluate key (ctrl-
shift-e) to run the subtraction.

Or say I have some Markdown and I want to give a correct-width underline to a
title. ctrl-d to duplicate and select the new line, shift-left to unselect the
newline character, alt-c to break the selection into characters, and then just
press "=" to replace them all.

Or say I want to reformat a function call so all the arguments are on new
lines, I will naturally gravitate to selecting a separator (the comma in all
likelihood) and just adding a newline there. I can keep some arguments
together by just skipping those.

This isn't to say multiple selections is the only way to do this stuff; this
is just the way I like doing it with my editor.

~~~
NoodleIncident
The "all hat and no cattle" link in the OP is a much better argument for
macros>multiple cursors:

[https://medium.com/@schtoeffel/you-don-t-need-more-than-
one-...](https://medium.com/@schtoeffel/you-don-t-need-more-than-one-cursor-
in-vim-2c44117d51db)

Editors without vim macros probably need multiple cursors, but the main
argument in favor of macros is that (for things like the markdown underline
macro), it's easy to save it for later, and you can see it happen to every
location even if some are offscreen.

~~~
sullyj3
The main argument for multiple cursors over macros is that they give a tighter
feedback loop. If the macro you record works for the section where you
recorded it, but doesn't generalise, without thinking hard about it
(undesirable) you won't know about it until you actually go and run the macro
in an incompatible spot. Once that happens, you either have to re-record it,
or dump it out and edit it manually. Neither of those options can be said to
be particular friction free. By contrast, with multiple cursors, if you do
something wrong (or right in some places, wrong in others) you know about it
immediately, and you can fix it immediately in a friction free manner.

I don't think multiple cursors can replace macros in all situations, but it
needs to be acknowledged that different tools have different strengths and
weaknesses, and when choosing which to use in a given situation you should
keep that in mind. Dismissing one because the other is more powerful is like
always using a sledgehammer to knock in your nails. Sometimes the other is
more convenient, or more user friendly, or less of a pain in the arse in some
other relevant way.

------
trishume
The two main reasons I use and love multiple cursors aren't mentioned here:

1\. I find it's easier to figure out what I want. If I use a command that
doesn't generalize, I see it immediately. When I use vim macros I find I
either have to redo my macro multiple times if I screw up, or spend a bunch of
time thinking about how to correctly generalize my commands while writing the
macro.

2\. There are less concepts to learn and think about applying. You can replace
multiple cursors with a combination of macros, rectangular selection and
find/replace. But, I find all that functionality easier to think about and
apply when it's all unified into one simple system.

~~~
falcolas
Why multiple cursors don't work (for me, of course):

1) I'm limited to what I can see. I can't see that a command does not
generalize unless it's on the screen. Most files I work on take up more than
the one screen I'm on.

2) Multiple cursors tend to have really limited flexibility - if it can't be
done easily with the available movement keys, often times it can't be done.
Macros, on the other hand, can easily move non-contiguously.

Yeah, macros do require a bit of extra thought around "how do I program the
text editor to do what I want", but they usually do the right thing. It helps
that macros are easy to record and use in vim, and that a macro can call
another macro.

Of course, I have used multiple cursors before, but usually only in data files
which follow strict columnar formats.

~~~
trishume
I don't encounter either problem: 1) If I'm editing things that don't fit on
one screen, I'll scroll and check them all after I'm done. This is no slower
than the scrolling needed during the step of applying a macro everywhere and
checking it. And I at least get feedback from one page while composing my
edits, with macros I get none. 2) I use multiple cursors with Vintageous in
Sublime, so I get most of the power of vim macros, but with multiple cursors
instead.

------
jawns
I am surprised at this:

> Somewhere around 99% of my multiple cursors usage was adding a common prefix
> to a contiguous [series] of lines.

I would say that it's somewhere around 25% of my usage.

More common -- probably 50% or more -- is finding all occurrences of a string
scattered throughout a file and making edits to that string that are more
sophisticated than a simple find-replace can handle (e.g. edits that involve
back-references). In many cases, I could probably write a regex, but using
multiple cursors is so much easier.

~~~
ensiferum
Spend a day on writing a regex woah. Most editors have a find + replace
feature which jumps to each location and allows it to be nicely reviewed
before making the edit.

------
KirinDave
As an emacs user about to hit my 25 year mark:

Maybe we'd all use macros if the UX for them we're no so atrociously bad? It's
only recently having tried out some obscure but good packages in spacemacs
that we start to see some great UX for macros and other bulk line editing
operations.

What's more, macros are often only valid on lines of exactly the type you
specified them on, and Emacs's best way to handle this (if they're contiguous)
is narrowing and widening, an operation so famously confusing that the buttons
are walled off with an apology in standard emacs.

I use multiple editors for non-trivial operations (instead of say, whitespace
tuning) when I'm doing quick but high value non-contigous work (e.g., adding
an exporting decl to several functions).

I didn't know emacs was using a gap buffer, but if so I have 0 sympathy. Vim
sounds like it's using a clearly superior and modern solution. Maybe I should
finally got over to that dark side?

~~~
Olreich
Modal editing does make macros far easier to work with...

~~~
thomastjeffery
Absolutely. In Vim, since every command is a keystroke you can save a string
of keystrokes to a buffer, and "run" that buffer as a macro. You can even
paste the buffer instead, edit it as plain text, and put the new version back
into the buffer and run it.

~~~
KirinDave
Personally I don't see how that is ebttee. Why is it better? Macros would be
better if they were less invisible.

Spacemacs/viper has this great copy of a vim feature where :/ and :s/ commands
actually show a diff view interactively in the buffer. It turned an old
useful-but-opaque feature into an equally useful but interactive and novice-
friendly feature. We need more of that in code editing.

~~~
KirinDave
I'm still waiting for this new phone to pick up on my typing... :/

------
mcphage
This article has it exactly backwards: you shouldn't use technical
implementations to rule out features—instead, you should use features to rule
out technical implementations. The users care about what your program can do,
not how you implemented it—and certainly won't be sympathetic if how you
implemented it hinders them from accomplishing what they're trying to do.

~~~
masklinn
The author's point is that "smart" editors (Vim or Emacs for instance) already
have macro systems and block/rect edition features which subsume and go far
beyond multiple cursors, and _furthermore_ ("if you don’t buy my arguments
about multiple cursors being tasteless") multiple cursors play hell on gap
buffer editors, therefore:

> get more comfortable with your editor’s macro feature. If your editor
> doesn’t have a good macro feature, get a new editor.

They also link to an essay[0] pointing out numerous ways in which multiple
cursors don't play well with advanced editor features (using Vim for the
demonstration but the point likely works just as well for Emacs).

Sure you can also take the inverse tack and switch to an editor implemented in
such a way that multiple cursors is efficient, but… is multiple cursors really
the feature you want to stop at?

[0] [https://medium.com/@schtoeffel/you-don-t-need-more-than-
one-...](https://medium.com/@schtoeffel/you-don-t-need-more-than-one-cursor-
in-vim-2c44117d51db)

~~~
mcphage
Reading the "why you don't need more than one cursor" article reminds me a lot
of people who say things like "why would you need anonymous functions in a
language? If you're making a function, then define it, and call it." Where the
author says:

> The ultimate feature that comes with vim is, that you can edit and save
> these macros for your next vim session and even add a key mapping.

They almost entirely miss the point of the feature. 99% of the time when
you're editing with multiple cursors, you're doing a unique thing which would
be meaningless outside the context of where you're doing it. The ability to
save the macro misinterprets the flexibility to do exactly what is needed at
the moment.

~~~
carussell
Two things:

Your comparison to anonymous functions is not apt. A language that implements
higher order concepts like anonymous functions adds more power to the
language. But on the spectrum of power, multiple cursors are not a more
powerful form of macros. Macros—Vim's, at least—are higher order than multiple
cursors. (Note that when I say "macros" here, I'm going along with the premise
of the Medium article where the ability to replay the last edit using `.` is
also considered macro use.)

Second, the ability to save a macro doesn't make macros less flexible. It's
not as if you have to pay for it whether you use it or not. If you don't want
to save it, then don't; but it's there if you want the option.

~~~
detaro
The claim wasn't that it makes macros less flexible. Just that the "ultimate
feature" isn't very important to many people, and thus no reason to weigh
macros over the (to some people) more intuitive workflow using multiple
cursors. It's great that macros are a thing and have their benefits, I
wouldn't want to remove them from editors, but "you don't need intuitive
feature X, just use Y which is even more powerful instead" isn't a great
message to users.

(Something I've been missing in this discussion: are multi-cursors to slow for
users in practice, or is this technically slower/"less efficient"?)

(and for the side-discussion about the function example: Doesn't the extra
power in the function case comes from being able to pass and dynamically
create functions, not from the fact that they are anonymous? E.g. in Python,
lambda functions really just save a few characters over using local named
functions? Am I missing something?)

~~~
carussell
The exact remark I'm responding to was this:

> The ability to save the macro misinterprets the flexibility to do exactly
> what is needed at the moment.

This makes it sound like a +1 for multiple cursors and and a plus null for
macros/replay. You could argue that the wording is just so and doesn't
actually claim that macros are less flexible. But the reality of the situation
is that macros are +1 and multiple cursors is plus null, and the gestalt of
comment I responded to doesn't convey that. That is, in all the cases where
multiple cursors shine, Vim's native features are, at worst, on equal footing,
and there's a non-zero count of cases where the inverse is not true. However,
someone who hears the argument in the message I responded to might come away
feeling that the opposite is true.

> "you don't need intuitive feature X, just use Y which is even more powerful
> instead" isn't a great message to users.

This, too, sounds like a crafted message—that Vim's native approach is missing
something, and that advocating for e.g. repeat instead multiple cursors is
shortsighted (somewhat reminiscent of [1]). The implication tends to be that
the alternative might be more powerful but less intuitive or require
orthogonal thinking. And there are cases in computing like that. Plenty. But
using repeat instead of multiple cursors is not one of them.

1\. [https://xkcd.com/974/](https://xkcd.com/974/)

~~~
detaro
Fair enough, on re-reading I guess your interpretation of that line is just as
likely as mine.

I still argue that macros are missing something UX wise. It's a matter of
preference which style you like better for specific problems, and I haven't
seen a good argument for why only one of the two should be present. I don't
think the fact that macros can fulfill the same function is a good argument.
Them being more powerful IMHO isn't either, it just means that when multi-
cursor editing fails someone preferring it, they still have the option to use
macros then.

I haven't actually tried multi-cursor editing in emacs - if it is
unusably/annoyingly slow, then the article would be interesting as an
explanation for _why_ that's the case, but its failing to establish that
context.

If it's not, it's still interesting from a theoretical perspective. I think it
shouldn't argue against multi-cursor editing the way it does.

Presenting the option of using a macro is fine, explaining the benefits of it
is great, dismissing multi-cursor editing as

> _tacky and modern_

is totally unnecessary. And unrelated to an article about implementation
details. Write "Why you should consider learning about macros", make a case
for them that's unrelated to "our datastructure doesn't like the alternative
as much".

EDIT: to address the quoting: It wasn't my intention to look like I'm making
up quotes, I need to think about a different way of marking these up it seems.
I try to put actual quotes on new lines.

------
omtose
It's funny how you see these articles about fancy text editor buffer
representation (gap buffer, ropes) but meanwhile, the editor with the best
feature/performance ratio (including multiple cursors) I've found[1] "simply"
represents a buffer as a vector of strings.

[1]: [https://github.com/mawww/kakoune](https://github.com/mawww/kakoune)

~~~
aktau
So does vim, by the way.

------
robin_reala
Because of course users should fit to algorithms instead of the other way
around.

~~~
krallja
Agreed. If your editor requires you to keep track of the number of calls to
memmove, you need a better editor.

~~~
hn_throwaway_99
But, of course, it doesn't. I find the conclusions of these types of articles
totally baffling. "But it's not pretty under the covers!!" Who cares? It gets
the job done fast enough for 99.9% of real world users who will never know it
wasn't implemented in an "elegant" manner.

------
todd8
To me, this really needs to be benchmarked. The advantage of the gap buffer
architecture is that it is simple; opening and closing the gap should be very
fast. I believe that moving a contiguous memory block (to close or relocate
the gap) in a source file should take far less than a millisecond. Fast
memmove implementations take advantage of a number of hardware optimizations
and should run over 2GB per second by my estimation.

Multiple cursors don't require more bytes to be moved than working with two
cursors, it just divides the distance from the first to the last cursor into
smaller blocks. The total number of bytes moved remains the same. 100 cursors
in a 10MB file requires 100 blocks averaging less than 100KB in size to be
moved, and moving this number of bytes (that will be less than 10MB) will take
roughly .005 seconds. That would mean maybe .005 seconds of latency per
keystroke while using 100 multiple cursors in a large file would come from the
gap buffer.

The benefits of the gap buffer are simplicity and the concomitant reliability
that can come from a simpler design. Low level operations inside the editor
like multi-byte characters, memory-mapped I/O, memory allocation, regular-
expression searching, incremental backups, diffs etc. are all easier with the
ability to close the gap and just work on a single contiguous block.

I've heard the argument before that editors should be using more complex data
structures, but the simplicity and additional benefits of cache friendly
designs make me hesitant to accept this reasoning without actual benchmarks.

------
taeric
For Emacs, being able to edit in the "occur" window is borderline magical, and
gets this use case fairly well.

------
philsnow
I think the author's conclusion is a little "throw out the baby with the
bathwater".

I do want to plug a couple of my favorite kmacro-related emacs features
though:

    
    
        M-x kmacro-edit-macro "edit the last defined keyboard macro"
        M-x kmacro-edit-lossage "edit the last 300 keystrokes as a keyboard macro"
    

Both bring up a buffer with a keyboard macro expressed as an s-expression, and
you can edit it and then press C-c C-c to save it.

The first is useful when you need to tweak a keyboard macro but don't want to
completely re-record it. The second is sometimes useful for deciding that that
thing you just did, you want to do it N times instead of 1.

[https://www.gnu.org/software/emacs/manual/html_node/emacs/Ed...](https://www.gnu.org/software/emacs/manual/html_node/emacs/Edit-
Keyboard-Macro.html)

------
ioquatix
I didn't know about this, and it was visualised well. Perhaps a multi-gap gap
buffer would help solve the problem of multiple cursors.

~~~
raphlinus
If you really want to solve the problem, use a rope. The advantage of gap
buffers is simplicity (accounting for the gap is a simple compare with a
couple of numbers). Ropes are definitely more complicated, but they have
massive advantages in worst-case complexity (most edit and query operations
have O(log n) cost).

~~~
blt
The simplicity argument is absurd to me. Text editors are some of the most
important programs to get right. The complex but high performance data
structure is worth the effort. It's like arguing that a GIS program shouldn't
use a quadtree.

~~~
raphlinus
You don't need to convince me, but you'd be surprised some of the pushback
I've gotten[0].

I don't have a lot of experience with GIS, but you're telling me that a linear
scan through all the features on a map _isn 't_ good enough? :)

[0]
[https://news.ycombinator.com/item?id=14129543](https://news.ycombinator.com/item?id=14129543)

------
mattnewton
Yeah, macros can do everything multiple cursors can do, but if multiple
cursors is easier for people to use it's worth supporting.

Gap buffers are an implementation detail I don't care about as a user, I care
about the features of my editor, so it is strange to suggest that I can't have
a feature in order to preserve an implementation detail. A better argument
would have been that speed is a more important feature, but the article didn't
argue that multiple cursors are necesarily slower, just that a gap buffer
would be slower with multiple cursors.

~~~
Veedrac
> Yeah, macros can do everything multiple cursors can do

Not everything. You can perform set operations on multiple selections, or
filter them, eg. by keeping every nth or removing those on blank lines. You
can save and restore selections, or use them as jump points. You can find
their covering range, globally or on a line-by-line basis. You can count them
or run scripts across them. Most importantly perhaps is you can copy them.

Similarly, macros can do things multiple selections struggle with, largely
because macros apply sequentially so the start to one can depend on the end of
another.

------
jmull
This makes no sense.

I think the author actually just wanted to play with and show off the gap-
buffer animations but for some reason only came up with this weak excuse to do
so.

I do quite like the gap buffer animations.

------
taejo
Poe's Law is strong with this one. I can't tell if it's serious or a parody.

------
Filligree
This might be a little off-topic, but one of the most common operations I use
multiple cursors for (in Emacs) is refactoring. Specifically, renaming things,
which is the only kind of refactoring it seems I can automate.

Are there any good refactoring packages out there? For Java, Kotlin, Python,
Rust etc.

------
tombert
I took a bit of time learning how to use Vim macros a few years ago, and then
never envied SublimeText programmers again. The fact that I could compose and
store the macros meant that I can effectively augment the editor without
having to muck about with Python, Vimscript, or Emacs Lisp.

~~~
gumby
You can save emacs macros in a file as well. No need to rewrite them in emacs
lisp.

This feature has existed in Emacs since before GNU Emacs.

~~~
kryptiskt
Emacs = Editor MACroS

It started out as bunch of TECO macros.

~~~
gumby
They were, but programming in TECO (although they were just strings of edit
commands) was more complex than emacs lisp, believe me. I wrote a lot of MIT
TECO back in the day and don't miss it!

~~~
todd8
Thinking back, its hard to believe that I spent a fair amount of time teaching
students the ins and outs of TECO because that was a more effective way to do
the coding required in my class. The alternative was punching cards. It was a
second semester university course for CS students.

------
GlennS
Honestly, I'm pretty sure that for most people's use any slowness with
multiple cursors in Emacs is nothing to do with the data structure used to
store the edits.

The noticable delay is due to highlighting closing parentheses.

------
gumby
Don't forget the Emacs point stack. I very frequently jump between the current
and previous point.

You can also manipulate the point stack explicitly though I got out of this
habit over the last decade or so.

------
kaushalmodi
It just seems that the author hasn't fully understood the application of
multiple cursors.

\- Create multiple cursors using mouse clicks. Now the locations you click
need not be (1) in a vertical alignment -- if vertically aligned, rectangle
edits make sense (2) on identical symbols -- if identical, search/replace
makes sense. \- Also you don't need to precisely on start or end of symbols.
After clicking, I can do `M-b` or `M-f` (or whatever) to bring all cursors at
identical syntactic locations. \- Even when not using mouse clicks, using
multiple cursor is a much lesser cognitive load. If I want to refactor the
symbol where the cursor is, I simply select the whole symbol (expand-region
package), hit a binding to create multiple cursors at all identical symbol
locations in the _buffer_ (not in just the visible region). The OP now counted
that as a disadvantage which was odd. I count myself proficient in using
multiple cursors and I am confident that each time I do the above, the cursors
would be created exactly where they should be (even when those are created
outside the visible region). Then I simply type in the new symbol name to
replace the selections. If I use search/replace, I need to type in the symbol
name and possible regexp to denote the symbol begins and ends. With multiple
cursors, no matter what symbol I am on, the action is the same (1) select
current symbol (2) create cursors everywhere on such symbols .. no need to
type in a specific regexp each time! \- Talking about the extra processing the
CPU needs to do because of multiple cursors, I have created around 100 cursors
in extreme cases and even then it was fine. In regular use, I need to create
under a dozen multiple cursors. \- Finally the real-time visual feedback
completely beats whatever little CPU gains we get by not using the multiple
cursors and the extra time wasted in thinking what regexp to type, what macro
to define, how big a rectangle selection to make etc. \- Also so much more is
possible[1]: interactively adding/removing cursors, aligning, inserting
numbers, etc. which would be much less efficient the conventional way.

[1]: [https://github.com/kaushalmodi/.emacs.d/blob/master/setup-
fi...](https://github.com/kaushalmodi/.emacs.d/blob/master/setup-files/setup-
multiple-cursors.el)

------
tejasmanohar
The author completely undermines multiple cursors. This is what happens when
you evaluate something without mastering it. I even use multiple cursors for
navigation. Multiple cursors feel far more natural than any sort of macro.

------
JetSpiegel
For search and replace, while NeoVim doesn't have multiple cursors out of the
box (there's a plugin for that), recent versions support

> set inccommand=nosplit

To do search and replaces interactively.

------
solomatov
IMO, the speed of modern computers and limited size of file being edited makes
gap buffers unnecessary. You can get by with a simple array of characters.

------
archagon
Content aside, thumbs up for a really nice blog design and article-tailored
animations! Very nice to read.

------
ndh2
Genuinely curious why people upvoted this.

A saner conclusion would be: If you want multi-cursor editing in your editor,
don't use a gap buffer.

------
epanasyuk
I use both - multiple cursors and keyboard macros. It is not only esthetic
difference, but practical as well.

For multiple cursors you have instant feedback on multiple edge cases, and
more importantly - you can undo and fix mistake immediately. While with
keyboard macros you have to either: redo all from scratch or edit macro as
text or execute stepwise editing - and none of them is as convenient as
instant multi-undo-fix. Moreover, for multiple cursors phases of places
selection and actual editing are distinctly separated, while with keyboard
macros you are doing both movement and editing in single iteration, and it is
possible to catch interference between place-movement and editing-movement

On another hand, keyboard macros are very powerful. They are not limited to
"for each" workflow - steps of iterations can sequentially depend one on
another. They are also not limited to "edit/manipulate multiple places"
workflow. With them you can jump between buffers/windows/frames, For instance
I used this to emulate "debug step into" in source files based on extraction
of file:line from trace log output in separate buffer.

Regarding performance - with Emacs I am usually working with source files,
which are not big, and taking into account today's memory throughput (RAM:
order of 10 GiB/s for single core; Cache order of 100 GiB/s) - sequential
multi-tossing of several MiB gap buffers is not a bottleneck. Even if it would
be real bottleneck - that means that bottleneck should be fixed, but not
abandonment of multiple cursors. (for instance it can be fixed by switching to
other data structure - multi-gap, rope, etc or maybe postpone execution for
out-of-screen cursors). That being said, I have to admit that in some cases
Emacs is not fast in doing movements, editing, maybe it is related to
complexity of some of major modes or maybe some other under-the-hood stuff -
and this affects both keyboard macros and multiple cursors. And here, what
really matters performance-wise - is that with keyboard macros you can fire-
and-drink-coffee batch execution, while with multiple cursors you have to
suffer multiplied latency for each single step. But multiple cursors are so
connivent, that I am ready to pay occasional price of switching to keyboard
macros or even to shell-command-on-region.

I understand, it can be appealing to stick to single tool and single approach,
but what I observed from my experience - it is counterproductive to
artificially limit yourself to single tool, and trying to find contrived
excuse for not using other which is more appropriate for particular problem. I
do use and even combine Linux and Windows; statically typed and dynamically
typed languages; scoped-based lifetime and garbage collection, Emacs and Vim.
I do use and even combine keyboard macros and multiple cursors.

------
davexunit
As usual HN just loves to take a dig at Emacs and people that like it.

~~~
detaro
I don't see how criticizing/disagreeing with the article is equal to

> _take a dig at Emacs and people that like it_

~~~
davexunit
HN is consistently negative when it comes to this subject.

~~~
detaro
For every editor there are people negative on it, Emacs doesn't particularly
stand out. This thread is remarkable in how _little_ editor flamewar is going
on.

