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.
Creating a fold in one pane now has no effect on an edit session
for the same buffer in another pane. Before they were polluting each
other by sharing the same fold markers.
Previously any non-null value would be used as the target
column in the wrap guide and autoflow packages when really
80 should have been used if the value was non-postive.
Now config.getPositiveInt() is called with a default value
of 80 if the current value isn't already positive.
This event comes from initially setting the text for the current
config value on the editor and was causing the config to be
immediately saved multiple times when opened.
Previously if an integer or float field was empty it would
default to zero instead of undefined which made it inconsistent
with string value fields.
Now the config value is only set as a Number when it can be
parsed as one.
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.
Previously, we were attempting to preserve the fold and adjust in an
intuitive way in the face of changes that straddled the beginning or
the end of the fold. That added complexity… we would have to add a new
marker invalidation strategy to support it and I'm not convinced it's
actually a big deal to destroy folds in the face of straddling changes.
So that's what we do now.
Stop relying on setInterval to trigger the scroll events in the spec. Instead simulate the mouse moving at the top of the screen. I found
testing the setInterval approach required so much mocking that it
wasn't worth it.
Still a couple of specs failing on this for changes that straddle the
start / end of a fold. We need a new marker invalidation strategy for
these cases.
Instead of marker-added and marker-removed events which are emitted
when markers are created/invalidated/revalidated/destroyed, we now
just have marker-created events that are triggered *only* when markers
are created for the first time. The marker itself emits a 'destroyed'
event when it is destroyed. The marker already notifies observers when
its validation status changes, so that's covered.
I deleted a bunch of documented methods. I haven't added any new
undocumented methods, but now there are fewer overall documented
methods, which is breaking the docs threshold spec. I don't think it
makes sense to start documenting non-related methods in this branch
right now.
The previous API revolved around methods on TextBuffer for querying
and manipulating markers based on their id. Now marker creation
methods return marker objects. These are still retrievable by id so
they can be dealt with across serialization boundaries in the future,
but you deal with them directly as objects.
It was not possible to click on the lower part of the last line
when the editor was scrollable and listening for mousedown events on renderedLines.
Closes#464
Previously Rails classes would infinitly loop if the Ruby on Rails
grammar was loaded but the Ruby grammar had not been. This occurred
because a rule was continually pushing itself on the stack but never
advancing.
Now if the position does not advance and the last two rules in the
stack have the same scope the last rule is popped and the entire line
is tokenized with the current scopes.
Closes#524#486
When you give a config field a `name` attribute based on a config key
path, such as 'editor.fontSize', it is automatically kept in sync with
the config value. You can also specify a `type` attribute of 'int' or
'float' to automatically convert the field value to a numeric type.
Specifying a type of 'string' is optional to signal no conversion.
This is part of an effort to disentangle LanguageMode, DisplayBuffer,
and TokenizedBuffer. It should be easy to create a DisplayBuffer
without creating an EditSession… let's get the dependencies flowing
in a single direction.
DisplayBuffer should just focus on providing basic support for folding.
Scanning the structure of the code, looking at scopes, etc is more the
domain of the LanguageMode object.
Structural folding should really be handled at the edit session level
so that the DisplayBuffer doesn't need access to the LanguageMode. It
should only be concerned with the raw ability to create folds.
If the Ruby on Rails grammar depends on HTML, but it isn't loaded, its
syntax highlighting won't include HTMl tokens. If we later load HTML,
we should update any buffer with the Rails grammar to reflect the
change. This commit changes grammars to memoize their initial rule and
repository. If an included grammar is added or removed, we clear the
memoized rules and emit a 'grammar-updated' event. Any tokenized
buffer that points to this grammar can then retokenize to reflect the
newly available/unavailable included grammar.
This spec was previously in the TokenizeBuffer spec which
required having a PHP fixture and setting up an edit session
to verify a line could be tokenized which was unnecessary.
Previously only the capture's name was considered when processing
tokens for capture indices.
Now the capture's patterns are matched against the captured region
if they exist.
Build scope selectors and patterns when setting up the grammar
for all entries under the grammar's injection object.
Include the injection patterns in the scanner when the injection's
scope selector matches the current rule stack.
Moving an item that extended the jQuery object between panes
was previously wiping out all jQuery data since remove() was being
called on the view item instead of detach().
This corrects a regression where closing an edit session that
is opened somewhere else should not prompt to save since it
won't be lost if closed immediately since it is still open in
another pane.
The redrawOnReattach flag will now be set when update
display is called on an invisible editor so that if the
editor is detached or hidden before the next update was
processed it will be performed when reattached.
The binding uses the `!important` selector to ensure that the editor
always gets a chance to clear multiple selections before other bindings
for escape are processed.
Just like the cursor clears its goal column when it is moved in any
way other than vertically, the selection clears its goal range (the
range it will attempt to use when adding a selection below) when it
is changed in any way.
Previously, if a selection was added and removed before the editor got
a chance to update its display, it would try to add a selection view
for the destroyed selection. Now we check the new selections and
cursors to make sure they aren't destroyed before we add views for
them.
Just like the cursor tries to stay in its "goal column" when moving
vertically, here we try to keep the same selection even when adding
across shorter lines.
This required changing text-buffer to support having a
path but not underlying file that exists yet.
Now calling RootView.open() with a non-existed path will
open a dirty empty editor to the path and the file will be
created on first save.
Previously EditSession.backspaceToBeginningOfLine() would do nothing
if at the beginning of the line.
Now it selects left and does a delete so it can be used to delete
multiple lines continuously without having to move the cursor.
Refs #134