From 3a957784ebfca6e416e5c9022ab459c2ba1007bc Mon Sep 17 00:00:00 2001 From: Symeon94 Date: Tue, 23 Dec 2025 14:10:34 +0100 Subject: [PATCH 1/7] Refactoring --- .../java/org/fxmisc/richtext/CaretNode.java | 2 +- .../fxmisc/richtext/CaretPositionChange.java | 74 +++++++++------ .../org/fxmisc/richtext/SelectionChange.java | 92 +++++++++++-------- .../org/fxmisc/richtext/SelectionImpl.java | 2 +- .../richtext/CaretPositionChangeTest.java | 2 +- .../fxmisc/richtext/SelectionChangeTest.java | 2 +- 6 files changed, 101 insertions(+), 73 deletions(-) diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/CaretNode.java b/richtextfx/src/main/java/org/fxmisc/richtext/CaretNode.java index 94c2bf21..bcf10026 100644 --- a/richtextfx/src/main/java/org/fxmisc/richtext/CaretNode.java +++ b/richtextfx/src/main/java/org/fxmisc/richtext/CaretNode.java @@ -216,7 +216,7 @@ public CaretNode(String name, GenericStyledArea area, SuspendableNo dep } private void handleContentChange(List list) { - int newPosition = new CaretPositionChange().apply(getPosition(), list); + int newPosition = new CaretPositionChange(getPosition()).apply(list); if (newPosition != getPosition()) { moveTo(newPosition); } diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java b/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java index b6da7714..36618672 100644 --- a/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java +++ b/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java @@ -5,40 +5,54 @@ import java.util.List; class CaretPositionChange { + private int position; + + /** @param position the current caret position */ + public CaretPositionChange(int position) { + this.position = position; + } + /** * Goes through the list of change and update the caret position accordingly - * @param position the current caret position - * @param list the list of changes * @return the new caret position */ - public int apply(int position, List list) { - for (PlainTextChange plainTextChange : list) { - int netLength = plainTextChange.getNetLength(); - if (netLength != 0) { - int indexOfChange = plainTextChange.getPosition(); - // in case of a replacement: "hello there" -> "hi." - int endOfChange = indexOfChange + Math.abs(netLength); - - /* - "->" means add (positive) netLength to position - "<-" means add (negative) netLength to position - "x" means don't update position - - "+c" means caret was included in the deleted portion of content - "-c" means caret was not included in the deleted portion of content - Before/At/After means indexOfChange "<" / "==" / ">" position - - | Before +c | Before -c | At | After - -------+---------------+-----------+----+------ - Add | N/A | -> | -> | x - Delete | indexOfChange | <- | x | x - */ - if (indexOfChange == position && netLength > 0) { - position = position + netLength; - } else if (indexOfChange < position) { - position = position < endOfChange ? indexOfChange : position + netLength; - } - } + public int apply(List changes) { + changes.forEach(this::applyFor); + return position; + } + + + /* + "->" means add (positive) netLength to position + "<-" means add (negative) netLength to position + "x" means don't update position + + "+c" means caret was included in the deleted portion of content + "-c" means caret was not included in the deleted portion of content + Before/At/After means indexOfChange "<" / "==" / ">" position + + | Before +c | Before -c | At | After + -------+---------------+-----------+----+------ + Add | N/A | -> | -> | x + Delete | indexOfChange | <- | x | x + */ + private void applyFor(PlainTextChange plainTextChange) { + int netLength = plainTextChange.getNetLength(); + if (netLength != 0) { + int indexOfChange = plainTextChange.getPosition(); + // in case of a replacement: "hello there" -> "hi." + int endOfChange = indexOfChange + Math.abs(netLength); + position = evaluatePosition(indexOfChange, netLength, endOfChange, position); + } + } + + // TODO SMA duplicate with selection change -> it seems the code is simply + private int evaluatePosition(int indexOfChange, int netLength, int endOfChange, int position) { + if (indexOfChange == position && netLength > 0) { + position = position + netLength; + } + else if (indexOfChange < position) { + position = position < endOfChange ? indexOfChange : position + netLength; } return position; } diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java b/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java index da354952..b9575a71 100644 --- a/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java +++ b/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java @@ -4,7 +4,10 @@ import java.util.List; +// TODO SMA can it be that CaretPositionChange is the same as this one but for start == end ? class SelectionChange { + private Range range; + // TODO -> to be replaced by state of this class start(), end() public static class Range { private final int start, end; @@ -23,45 +26,56 @@ public int end() { } } - public Range apply(List list, int selectStart, int selectEnd) { - for (PlainTextChange plainTextChange : list) { - int changeLength = plainTextChange.getNetLength(); - int indexOfChange = plainTextChange.getPosition(); - // in case of a replacement: "hello there" -> "hi." - int endOfChange = indexOfChange + Math.abs(changeLength); - - /* - "->" means add (positive) netLength to position - "<-" means add (negative) netLength to position - "x" means don't update position - - "start / end" means what should be done in each case for each anchor if they differ - - "+a" means one of the anchors was included in the deleted portion of content - "-a" means one of the anchors was not included in the deleted portion of content - Before/At/After means indexOfChange "<" / "==" / ">" position - - | Before +a | Before -a | At | After - -------+---------------+-----------+--------+------ - Add | N/A | -> | -> / x | x - Delete | indexOfChange | <- | x | x - */ - if (indexOfChange == selectStart && changeLength > 0) { - selectStart = selectStart + changeLength; - } else if (indexOfChange < selectStart) { - selectStart = selectStart < endOfChange - ? indexOfChange - : selectStart + changeLength; - } - if (indexOfChange < selectEnd) { - selectEnd = selectEnd < endOfChange - ? indexOfChange - : selectEnd + changeLength; - } - if (selectStart > selectEnd) { - selectStart = selectEnd; - } + public SelectionChange(int start, int end) { + this.range = new Range(start, end); + } + + /* + "->" means add (positive) netLength to position + "<-" means add (negative) netLength to position + "x" means don't update position + + "start / end" means what should be done in each case for each anchor if they differ + + "+a" means one of the anchors was included in the deleted portion of content + "-a" means one of the anchors was not included in the deleted portion of content + Before/At/After means indexOfChange "<" / "==" / ">" position + + | Before +a | Before -a | At | After + -------+---------------+-----------+--------+------ + Add | N/A | -> | -> / x | x + Delete | indexOfChange | <- | x | x + */ + public Range applyFor(List changes) { + changes.forEach(this::applyFor); + return range; + } + + private void applyFor(PlainTextChange plainTextChange) { + int start = range.start(); + int end = range.end(); + + int netLength = plainTextChange.getNetLength(); + int indexOfChange = plainTextChange.getPosition(); + // in case of a replacement: "hello there" -> "hi." + int endOfChange = indexOfChange + Math.abs(netLength); + + start = evaluatePosition(indexOfChange, netLength, endOfChange, start); + + if (indexOfChange < end) { + end = end < endOfChange ? indexOfChange : end + netLength; + } + start = Math.min(start, end); + this.range = new Range(start, end); + } + + private int evaluatePosition(int indexOfChange, int netLength, int endOfChange, int position) { + if (indexOfChange == position && netLength > 0) { + position = position + netLength; + } + else if (indexOfChange < position) { + position = position < endOfChange ? indexOfChange : position + netLength; } - return new Range(selectStart, selectEnd); + return position; } } diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/SelectionImpl.java b/richtextfx/src/main/java/org/fxmisc/richtext/SelectionImpl.java index 40e0859f..e44eee83 100644 --- a/richtextfx/src/main/java/org/fxmisc/richtext/SelectionImpl.java +++ b/richtextfx/src/main/java/org/fxmisc/richtext/SelectionImpl.java @@ -238,7 +238,7 @@ public SelectionImpl(String name, GenericStyledArea area, int startP } private void handleChange(List list) { - SelectionChange.Range newSelection = new SelectionChange().apply(list, getStartPosition(), getEndPosition()); + SelectionChange.Range newSelection = new SelectionChange(getStartPosition(), getEndPosition()).applyFor(list); selectRange(newSelection.start(), newSelection.end()); } diff --git a/richtextfx/src/test/java/org/fxmisc/richtext/CaretPositionChangeTest.java b/richtextfx/src/test/java/org/fxmisc/richtext/CaretPositionChangeTest.java index 837e8052..98976021 100644 --- a/richtextfx/src/test/java/org/fxmisc/richtext/CaretPositionChangeTest.java +++ b/richtextfx/src/test/java/org/fxmisc/richtext/CaretPositionChangeTest.java @@ -12,7 +12,7 @@ public class CaretPositionChangeTest { private void checkChange(int before, int after, PlainTextChange... changes) { List changeList = Arrays.stream(changes).collect(Collectors.toList()); - assertEquals(after, new CaretPositionChange().apply(before, changeList)); + assertEquals(after, new CaretPositionChange(before).apply(changeList)); } @Test diff --git a/richtextfx/src/test/java/org/fxmisc/richtext/SelectionChangeTest.java b/richtextfx/src/test/java/org/fxmisc/richtext/SelectionChangeTest.java index 0068086c..d733a140 100644 --- a/richtextfx/src/test/java/org/fxmisc/richtext/SelectionChangeTest.java +++ b/richtextfx/src/test/java/org/fxmisc/richtext/SelectionChangeTest.java @@ -12,7 +12,7 @@ public class SelectionChangeTest { private void checkChange(int startBefore, int endBefore, int startAfter, int endAfter, PlainTextChange... changes) { List changeList = Arrays.stream(changes).collect(Collectors.toList()); - SelectionChange.Range range = new SelectionChange().apply(changeList, startBefore, endBefore); + SelectionChange.Range range = new SelectionChange(startBefore, endBefore).applyFor(changeList); assertEquals("Start does not match", startAfter, range.start()); assertEquals("End does not match", endAfter, range.end()); } From 6d7fa0ac6389b88a053e11046329f65991c4e47b Mon Sep 17 00:00:00 2001 From: Symeon94 Date: Tue, 23 Dec 2025 14:24:12 +0100 Subject: [PATCH 2/7] Refactoring --- .../fxmisc/richtext/CaretPositionChange.java | 31 ++++++------- .../org/fxmisc/richtext/SelectionChange.java | 43 ++++++++++--------- 2 files changed, 39 insertions(+), 35 deletions(-) diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java b/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java index 36618672..d32af76f 100644 --- a/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java +++ b/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java @@ -39,21 +39,22 @@ public int apply(List changes) { private void applyFor(PlainTextChange plainTextChange) { int netLength = plainTextChange.getNetLength(); if (netLength != 0) { - int indexOfChange = plainTextChange.getPosition(); - // in case of a replacement: "hello there" -> "hi." - int endOfChange = indexOfChange + Math.abs(netLength); - position = evaluatePosition(indexOfChange, netLength, endOfChange, position); + int changePosition = plainTextChange.getPosition(); + if (position == changePosition) { + // If it's net removal, we don't change anything + position += Math.max(0, netLength); + } + else if (position > changePosition) { + // If the caret is within the change, we set it to the start of the change + if(position < changePosition + Math.abs(netLength)) { + position = changePosition; + } + // Else we move the caret depending on the length variation + else { + position += netLength; + } + } + // If caretPosition < changeIndex, there is no movement as the changes happens after the current position } } - - // TODO SMA duplicate with selection change -> it seems the code is simply - private int evaluatePosition(int indexOfChange, int netLength, int endOfChange, int position) { - if (indexOfChange == position && netLength > 0) { - position = position + netLength; - } - else if (indexOfChange < position) { - position = position < endOfChange ? indexOfChange : position + netLength; - } - return position; - } } diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java b/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java index b9575a71..fcfbafbc 100644 --- a/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java +++ b/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java @@ -6,7 +6,7 @@ // TODO SMA can it be that CaretPositionChange is the same as this one but for start == end ? class SelectionChange { - private Range range; + private int start, end; // TODO -> to be replaced by state of this class start(), end() public static class Range { @@ -27,7 +27,8 @@ public int end() { } public SelectionChange(int start, int end) { - this.range = new Range(start, end); + this.start = start; + this.end = end; } /* @@ -48,34 +49,36 @@ public SelectionChange(int start, int end) { */ public Range applyFor(List changes) { changes.forEach(this::applyFor); - return range; + return new Range(start, end); } private void applyFor(PlainTextChange plainTextChange) { - int start = range.start(); - int end = range.end(); - int netLength = plainTextChange.getNetLength(); int indexOfChange = plainTextChange.getPosition(); // in case of a replacement: "hello there" -> "hi." int endOfChange = indexOfChange + Math.abs(netLength); - start = evaluatePosition(indexOfChange, netLength, endOfChange, start); - - if (indexOfChange < end) { - end = end < endOfChange ? indexOfChange : end + netLength; + if (start == indexOfChange) { + start = start + Math.max(netLength, 0); } - start = Math.min(start, end); - this.range = new Range(start, end); - } - - private int evaluatePosition(int indexOfChange, int netLength, int endOfChange, int position) { - if (indexOfChange == position && netLength > 0) { - position = position + netLength; + else if (start > indexOfChange) { + if(start < endOfChange) { + start = indexOfChange; + } + else { + start += netLength; + } } - else if (indexOfChange < position) { - position = position < endOfChange ? indexOfChange : position + netLength; + + // Adapting the end based on the change + if (end > indexOfChange) { + if(end < endOfChange) { + end = indexOfChange; + } + else { + end += netLength; + } } - return position; + start = Math.min(start, end); } } From 6c1f288ccde874a742378cb08a3413bec3654f01 Mon Sep 17 00:00:00 2001 From: Symeon94 Date: Tue, 23 Dec 2025 14:32:39 +0100 Subject: [PATCH 3/7] Cleanup --- .../fxmisc/richtext/CaretPositionChange.java | 25 ++++++----- .../org/fxmisc/richtext/SelectionChange.java | 41 +++++++++++-------- 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java b/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java index d32af76f..bce0b45e 100644 --- a/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java +++ b/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java @@ -44,17 +44,22 @@ private void applyFor(PlainTextChange plainTextChange) { // If it's net removal, we don't change anything position += Math.max(0, netLength); } - else if (position > changePosition) { - // If the caret is within the change, we set it to the start of the change - if(position < changePosition + Math.abs(netLength)) { - position = changePosition; - } - // Else we move the caret depending on the length variation - else { - position += netLength; - } + else { + position = applyChange(position, changePosition, netLength); } - // If caretPosition < changeIndex, there is no movement as the changes happens after the current position } } + + private static int applyChange(int position, int changeStart, int netLength) { + // Position is after the end of the change + if(position >= changeStart + Math.abs(netLength)) { + position += netLength; + } + // Position is before the end but after the start + else if(position > changeStart) { + position = changeStart; + } + // Else position is before the change + return position; + } } diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java b/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java index fcfbafbc..9255df42 100644 --- a/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java +++ b/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java @@ -54,31 +54,38 @@ public Range applyFor(List changes) { private void applyFor(PlainTextChange plainTextChange) { int netLength = plainTextChange.getNetLength(); - int indexOfChange = plainTextChange.getPosition(); + int changeStart = plainTextChange.getPosition(); // in case of a replacement: "hello there" -> "hi." - int endOfChange = indexOfChange + Math.abs(netLength); + int changeEnd = changeStart + Math.abs(netLength); - if (start == indexOfChange) { + if (start == changeStart) { start = start + Math.max(netLength, 0); } - else if (start > indexOfChange) { - if(start < endOfChange) { - start = indexOfChange; - } - else { - start += netLength; - } + else { + start = applyChange(start, changeStart, changeEnd, netLength); } + end = applyChange(end, changeStart, changeEnd, netLength); + + start = Math.min(start, end); + } - // Adapting the end based on the change - if (end > indexOfChange) { - if(end < endOfChange) { - end = indexOfChange; + private static int applyChange(int position, int changeStart, int changeEnd, int netLength) { + if(position >= changeEnd) { + position += netLength; + } + else if(position > changeStart) { + position = changeStart; + } + /* + if (position > changeStart) { + // Is within the change interval + if(position < changeEnd) { + position = changeStart; } else { - end += netLength; + position += netLength; } - } - start = Math.min(start, end); + }*/ + return position; } } From 7c3d0358e7c0bfc89252a9d838679d6ab360919c Mon Sep 17 00:00:00 2001 From: Symeon94 Date: Tue, 23 Dec 2025 14:34:49 +0100 Subject: [PATCH 4/7] Refactoring --- .../org/fxmisc/richtext/CaretPositionChange.java | 14 ++++++-------- .../java/org/fxmisc/richtext/SelectionChange.java | 12 ------------ 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java b/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java index bce0b45e..8cd53969 100644 --- a/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java +++ b/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java @@ -39,27 +39,25 @@ public int apply(List changes) { private void applyFor(PlainTextChange plainTextChange) { int netLength = plainTextChange.getNetLength(); if (netLength != 0) { - int changePosition = plainTextChange.getPosition(); - if (position == changePosition) { + int changeStart = plainTextChange.getPosition(); + if (position == changeStart) { // If it's net removal, we don't change anything position += Math.max(0, netLength); } else { - position = applyChange(position, changePosition, netLength); + int changeEnd = changeStart + Math.abs(netLength); + position = applyChange(position, changeStart, changeEnd, netLength); } } } - private static int applyChange(int position, int changeStart, int netLength) { - // Position is after the end of the change - if(position >= changeStart + Math.abs(netLength)) { + private static int applyChange(int position, int changeStart, int changeEnd, int netLength) { + if(position >= changeEnd) { position += netLength; } - // Position is before the end but after the start else if(position > changeStart) { position = changeStart; } - // Else position is before the change return position; } } diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java b/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java index 9255df42..c45ed042 100644 --- a/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java +++ b/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java @@ -57,7 +57,6 @@ private void applyFor(PlainTextChange plainTextChange) { int changeStart = plainTextChange.getPosition(); // in case of a replacement: "hello there" -> "hi." int changeEnd = changeStart + Math.abs(netLength); - if (start == changeStart) { start = start + Math.max(netLength, 0); } @@ -65,7 +64,6 @@ private void applyFor(PlainTextChange plainTextChange) { start = applyChange(start, changeStart, changeEnd, netLength); } end = applyChange(end, changeStart, changeEnd, netLength); - start = Math.min(start, end); } @@ -76,16 +74,6 @@ private static int applyChange(int position, int changeStart, int changeEnd, int else if(position > changeStart) { position = changeStart; } - /* - if (position > changeStart) { - // Is within the change interval - if(position < changeEnd) { - position = changeStart; - } - else { - position += netLength; - } - }*/ return position; } } From 258f005f7d7a025a0ad77ecaa80cc308ecf4e1ce Mon Sep 17 00:00:00 2001 From: Symeon94 Date: Tue, 23 Dec 2025 14:41:40 +0100 Subject: [PATCH 5/7] Refactor --- .../src/main/java/org/fxmisc/richtext/SelectionChange.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java b/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java index c45ed042..ec79b335 100644 --- a/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java +++ b/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java @@ -58,7 +58,7 @@ private void applyFor(PlainTextChange plainTextChange) { // in case of a replacement: "hello there" -> "hi." int changeEnd = changeStart + Math.abs(netLength); if (start == changeStart) { - start = start + Math.max(netLength, 0); + start += Math.max(netLength, 0); } else { start = applyChange(start, changeStart, changeEnd, netLength); From 6c28a0743393886b173686708c1647c6233c88ad Mon Sep 17 00:00:00 2001 From: Symeon94 Date: Tue, 23 Dec 2025 14:49:08 +0100 Subject: [PATCH 6/7] Improving clarity --- .../org/fxmisc/richtext/CaretPositionChange.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java b/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java index 8cd53969..d2e823bf 100644 --- a/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java +++ b/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java @@ -40,14 +40,8 @@ private void applyFor(PlainTextChange plainTextChange) { int netLength = plainTextChange.getNetLength(); if (netLength != 0) { int changeStart = plainTextChange.getPosition(); - if (position == changeStart) { - // If it's net removal, we don't change anything - position += Math.max(0, netLength); - } - else { - int changeEnd = changeStart + Math.abs(netLength); - position = applyChange(position, changeStart, changeEnd, netLength); - } + int changeEnd = changeStart + Math.abs(netLength); + position = applyChange(position, changeStart, changeEnd, netLength); } } @@ -58,6 +52,9 @@ private static int applyChange(int position, int changeStart, int changeEnd, int else if(position > changeStart) { position = changeStart; } + else if(position == changeStart) { + position += Math.max(0, netLength); + } return position; } } From 122e7a4fc266e4003263b7a6e7af4ae895586408 Mon Sep 17 00:00:00 2001 From: Symeon94 Date: Tue, 23 Dec 2025 15:01:03 +0100 Subject: [PATCH 7/7] Refactor --- .../fxmisc/richtext/CaretPositionChange.java | 23 +++++++------------ .../org/fxmisc/richtext/SelectionChange.java | 17 -------------- 2 files changed, 8 insertions(+), 32 deletions(-) diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java b/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java index d2e823bf..ff968b87 100644 --- a/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java +++ b/richtextfx/src/main/java/org/fxmisc/richtext/CaretPositionChange.java @@ -21,21 +21,6 @@ public int apply(List changes) { return position; } - - /* - "->" means add (positive) netLength to position - "<-" means add (negative) netLength to position - "x" means don't update position - - "+c" means caret was included in the deleted portion of content - "-c" means caret was not included in the deleted portion of content - Before/At/After means indexOfChange "<" / "==" / ">" position - - | Before +c | Before -c | At | After - -------+---------------+-----------+----+------ - Add | N/A | -> | -> | x - Delete | indexOfChange | <- | x | x - */ private void applyFor(PlainTextChange plainTextChange) { int netLength = plainTextChange.getNetLength(); if (netLength != 0) { @@ -45,6 +30,14 @@ private void applyFor(PlainTextChange plainTextChange) { } } + /** + *
    + *
  • If the position is after the interval of the change, the caret moves left/right if it's a net removal/addition.
  • + *
  • If it's within the change interval, the caret move back at the start of the change.
  • + *
  • If it's equal to the start position, the caret is moved at the end of the changed (it cannot be moved backwards + * if it's a removal of text, hence capping to 0).
  • + *
+ */ private static int applyChange(int position, int changeStart, int changeEnd, int netLength) { if(position >= changeEnd) { position += netLength; diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java b/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java index ec79b335..bd804929 100644 --- a/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java +++ b/richtextfx/src/main/java/org/fxmisc/richtext/SelectionChange.java @@ -31,22 +31,6 @@ public SelectionChange(int start, int end) { this.end = end; } - /* - "->" means add (positive) netLength to position - "<-" means add (negative) netLength to position - "x" means don't update position - - "start / end" means what should be done in each case for each anchor if they differ - - "+a" means one of the anchors was included in the deleted portion of content - "-a" means one of the anchors was not included in the deleted portion of content - Before/At/After means indexOfChange "<" / "==" / ">" position - - | Before +a | Before -a | At | After - -------+---------------+-----------+--------+------ - Add | N/A | -> | -> / x | x - Delete | indexOfChange | <- | x | x - */ public Range applyFor(List changes) { changes.forEach(this::applyFor); return new Range(start, end); @@ -55,7 +39,6 @@ public Range applyFor(List changes) { private void applyFor(PlainTextChange plainTextChange) { int netLength = plainTextChange.getNetLength(); int changeStart = plainTextChange.getPosition(); - // in case of a replacement: "hello there" -> "hi." int changeEnd = changeStart + Math.abs(netLength); if (start == changeStart) { start += Math.max(netLength, 0);