Previously, we used to prevent the user from dragging the selection
further when the buffer was about to change. This was problematic
because any change in the buffer, even one that was performed
"automatically" by a package, would cancel the dragging action and
result in a confusing experience for the user.
On the other hand, we want to prevent users from accidentally selecting
text when they perform an edit (see #15217, #15405).
This commit addresses both concerns by canceling the dragging as soon as
the user interacts with the keyboard, instead of canceling the dragging
when the buffer is about to change.
One downside of this approach is that it changes the behavior of
pressing a keystroke that does not result in a buffer change, e.g.
Shift, Arrow Keys, etc.
Signed-off-by: Jason Rudolph <jasonrudolph@github.com>
* Restate the folding logic to not *use* the TextEditor, but instead to
*return* ranges which can be folded by the editor.
* Convert the LanguageMode spec to JS
In https://github.com/atom/atom/pull/15503 we mistakenly assumed
`marker.isValid` accounted only for the validity of the marker. However,
that method returns `false` also for markers that are valid but have
been destroyed. As a result, the editor component was mistakenly not
removing block decorations associated with such markers.
With this commit we will rely on the local `wasValid` variable instead.
If its value is `true`, it means that the block decoration has been
accounted for in the `lineTopIndex` and must, as a result, be cleaned up
in case the marker or the decoration gets destroyed.
This prevents the dummy scrollbars from resetting their position to `0`
when the editor element is moved elsewhere in the DOM (e.g. when
splitting a pane item).
Previously, when trying to use block decorations on non-empty markers,
Atom could sometimes throw an error if such markers ended or started at
a position that was not currently rendered.
In fact, even if we already restricted the decoration query to markers
that intersected the visible row range, markers that were only partially
visible would still be considered for rendering. If, depending on the
`reversed` property, we decided to render the tail or head of the marker
in question and this was outside the viewport, Atom would throw the
aforementioned exception.
This commit addresses the above issue by explicitly ignoring block
decorations that are located on rows that are not yet rendered.
Previously, we were hiding scrollbars when their height/width was 0. On
macOS, however, users can decide to only show scrollbars while
scrolling, which causes Atom to detect scrollbars as being invisible
during measurements. As a result, we were mistakenly setting the
visibility property to `hidden` when this setting was on, thus
preventing users from seeing the scrollbar on scroll.
With this commit we are changing the dummy scrollbar components to only
become invisible when the content is not scrollable rather than when the
scrollbars have zero width or height.
As part of this, we have also renamed the
`is{Horizontal,Vertical}ScrollbarVisible` functions to
`canScroll{Horizontally,Vertically}`, to better express their intent.
Previously, when a marker became invalid we would delete the
corresponding block decoration from the DOM, without however removing it
from the `lineTopIndex`. Also, we had a similar issue when decorating a
marker that was already invalid: we would account for it in the index
without adding it to the DOM.
This commit addresses the above problems by ensuring that block
decorations are never added for invalid markers. At the same time, the
editor component will still keep track of changes on the marker that was
decorated, so that it can detect when its validity changes and render it
appropriately.
This commit introduces a change in the way we respond to mousewheel
events. In particular, if `delta * scrollSensitivity` is less than 1 or
greater than -1, we will round it up or down in an attempt to honor the
user's scroll intent.
As a consequence of https://github.com/atom/atom/pull/15378, we are now
able to render highlight decorations in a separate div, as opposed to
having an highlight container for each tile.
Code-wise this is much simpler, because highlights spanning multiple
tiles can be represented via a single region and don't need to be split
across the tiles they span anymore. As a byproduct, performance should
improve as well, because the number of nodes that need to be managed
should decrease significantly.
This also fixes https://github.com/atom/atom/issues/15449, and other
similar rendering artifacts, because highlight decoration DOM nodes
won't need to move between tiles anymore when their position changes.
Previously, we were calculating the position preceding block decorations
for the row following the end of the highlighted range, but that's
actually wrong. We just want the position following block decorations of
the end of the highlighted range, plus one line height. This prevents us
from incorrectly rendering the end of highlight after block decorations
that immediately follow the end of the highlighted range.
When there are block decorations, we compute a `marginTop` style for
line numbers, so that they can be aligned correctly to the corresponding
line nodes.
This commit fixes a regression in the logic that calculated the
`marginTop` value, which was failing to correctly render line numbers
when block decorations were located right before the end of a tile, or
exactly at
the beginning of it.
This prevents the cursor from unexpectedly changing when approaching the
bottom/right corner of the editor with the mouse, even when no scrollbar
is being shown.
Previously, as soon as we decided to render linesToMeasure, we would
clear them out. However, if a second update interleaved with the update
that initially requested measurement, it could cause the requested lines
to not be present when the measurement phase from the first update
occurred. Now, any additional updates will only add to the set of lines
that need to be measured until the measurement phase actually happens.
Signed-off-by: Antonio Scandurra <as-cii@github.com>
When changing the editor styles, we force the component to remeasure
character dimensions. If they change, each line's height could change
too, causing the current scroll top position to not match the viewport
the user was observing. Thus, when detecting a line height change, we
try to show users the area of the screen they were looking prior to
tweaking the font size.
In trying to maintain the aforementioned logical position, however, we
were mistakenly scheduling a new update before actually finishing the
current one. This was problematic because if the first update detected
that the longest screen line changed and such line was off-screen, it
would try to render it. Before having the chance to measure it, though,
the new update would kick in and delete the new longest screen line
node, because it assumed it had already been measured. Finally, when
`measureContentDuringUpdateSync` fired, it would notice that the longest
screen line node did not exist and throw an exception as a result.
This commit changes the `updateSync` method to set the `updateScheduled`
flag only before returning control to the caller, as opposed to doing so
at the beginning. This prevents calls to `scheduleUpdate` made in
`updateSync` from scheduling new unwanted updates.
Previously, clicking on a block decoration to interact with it would
cause the editor to scroll to the line next to it. This is inconvenient,
especially if the decoration was designed to be interactive and
contained buttons or links. If the decoration was close to the bottom of
the screen, clicking on a button inside of it would make the editor
scroll down and abort the click.
This behavior regressed during the editor rendering layer rewrite and
with this commit we are restoring the original behavior by simply
ignoring clicks that land on block decorations.