Skip to content

Commit

Permalink
Fix Cursor::previous_logical_word
Browse files Browse the repository at this point in the history
Currently, in `foo b|ar` where `|` indicates the cursor position,
`Cursor::previous_logical_word` will return `foo| bar`. This doesn't
match the behavior of `Cursor::{next_logical_word,
previous_visual_word}` which place the cursor at the boundary of the
current word. This happens because `Cluster::previous_logical_word` is
called from the upstream cluster (the "b") and the cursor then lands
between the "o" and the space.

This also renames "left", "right" -> "upstream", "downstream" (naming
copied from `Cursor::logical_clusters`) to make it clear we're operating
in logical order and not visual, and sets `moving_right` based on the
text direction we're jumping to, to affine the cursor towards the word
whose boundary it lands on.

(Note the behavior between `{previous, next}_logical_word` and
{previous, next}_visual_word` aren't quite the same yet: the `visual`
methods jump over whitespace, the `logical` ones don't.)
  • Loading branch information
tomcur committed Dec 9, 2024
1 parent 4fa6d9d commit 6ce41f8
Showing 1 changed file with 8 additions and 6 deletions.
14 changes: 8 additions & 6 deletions parley/src/layout/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,14 +243,15 @@ impl Cursor {
/// in logical order.
#[must_use]
pub fn next_logical_word<B: Brush>(&self, layout: &Layout<B>) -> Self {
let [left, right] = self.logical_clusters(layout);
if let Some(cluster) = right.or(left) {
let [upstream, downstream] = self.logical_clusters(layout);
if let Some(cluster) = downstream.or(upstream) {
let start = cluster.clone();
let cluster = cluster.next_logical_word().unwrap_or(cluster);
if cluster.path == start.path {
return Self::from_byte_index(layout, usize::MAX, Affinity::Downstream);
}
return Self::from_cluster(layout, cluster, true);
let moving_right = !cluster.is_rtl();
return Self::from_cluster(layout, cluster, moving_right);
}
*self
}
Expand All @@ -259,10 +260,11 @@ impl Cursor {
/// in logical order.
#[must_use]
pub fn previous_logical_word<B: Brush>(&self, layout: &Layout<B>) -> Self {
let [left, right] = self.logical_clusters(layout);
if let Some(cluster) = left.or(right) {
let [upstream, downstream] = self.logical_clusters(layout);
if let Some(cluster) = downstream.or(upstream) {
let cluster = cluster.previous_logical_word().unwrap_or(cluster);
return Self::from_cluster(layout, cluster, true);
let moving_right = cluster.is_rtl();
return Self::from_cluster(layout, cluster, moving_right);
}
*self
}
Expand Down

0 comments on commit 6ce41f8

Please sign in to comment.