We no longer need to restore selection ranges before and after
transactions now because selections are based on markers so they go
along for the ride for free. This allows us to delegate directly to
Buffer.transact from EditSession.
For a while, the goal has been to prevent marker update events from
firing until after the buffer change event. But at the same time, we
want all the markers to be updated when the buffer change fires. This
commit irons out some issues for markers that are invalidated or
revalidated by the change, making their behavior consistent with the
rest of marker updates.
This event now fires whenever the content of the buffer changes (after
a rate-limiting delay) with a single boolean indicating the modified
status of the buffer. There's now a separate event called
'modified-status-changed' to indicate events that change the boolean
value of the isModified method, so we don't need to fire
'contents-modified' when the underlying file is deleted for instance.
This prevents the editor from synchronously redrawing in specs with
cursors in invalid locations. Markers are always updated under the
hood before a change event is emitted from the Buffer or DisplayBuffer.
We still wait to trigger marker observers, but if their position gets
read, it is up to date.
A "marker" is basically like a persistent selection/cursor composite,
having a head and a tail. The "head" is like the cursor in a selection,
and the "tail" is like the part of the selection that doesn't move. My
goal is for markers to be the only construct used to track regions
in the buffer. I want to replace anchors with them.
BufferChangeOperation now takes an options hash that
can specify whether line endings should be normalized.
This option is set to false when Buffer.setText is called.
This replaces the previous assignment of lineEndings to []
with a more explicit mechanism.
For this to work, I needed to make the updating of anchors transactional. Now, all anchors are updated and *then* they emit their events. That way when the cursor moves based on the user typing, the tab stop they're in has a chance to expand before we handle the move event. This prevents spurious cancellation of the snippet when typing on a tab stop.
This will be used by the status bar and other expensive code that needs to respond to the buffer changing, but that we don't want running on every single keystroke when the user is typing quickly.
The buffer now emits a new event 'update-anchors-after-change' to signal that all the anchors have been updated, which is an appropriate time to merge cursors.