Skip to content

Commit

Permalink
Bugfix replace setting wrong caretIndex
Browse files Browse the repository at this point in the history
  • Loading branch information
ArthaTi committed Oct 22, 2024
1 parent 5e6561c commit d77b111
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 2 deletions.
3 changes: 3 additions & 0 deletions source/fluid/text.d
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,9 @@ struct StyledText(StyleRange = TextStyleSlice[]) {
/// value = Value to insert.
void replace(size_t start, size_t end, Rope value) {

// Ignore if there's no change
if (start == end && value.length == 0) return;

const startInterval = positionOf(start);
const oldInterval = positionOf(end)
.dropHead(startInterval);
Expand Down
53 changes: 51 additions & 2 deletions source/fluid/text_input.d
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,9 @@ class TextInput : InputNode!Node, FluidScrollable {

}

// Nothing changed, ignore this request
if (start == end && newValue.length == 0) return;

const oldValue = contentLabel.value[start..end];

contentLabel.replace(start, end, newValue);
Expand All @@ -465,7 +468,7 @@ class TextInput : InputNode!Node, FluidScrollable {
if (caretIndex <= end)
caretIndex = start + newValue.length;
else
caretIndex = caretIndex + newValue.length - end;
caretIndex = caretIndex + start + newValue.length - end;

updateCaretPosition();
horizontalAnchor = caretPosition.x;
Expand All @@ -479,6 +482,13 @@ class TextInput : InputNode!Node, FluidScrollable {
onReplace(start, oldValue, newValue);

}

/// ditto
void replace(size_t start, size_t end, string newValue) {

replace(start, end, Rope(newValue));

}

/// ditto
auto replace() {
Expand Down Expand Up @@ -511,6 +521,45 @@ class TextInput : InputNode!Node, FluidScrollable {

}

@("TextInput.replace correctly sets cursor position (caret inside selection)")
unittest {

auto root = textInput();
root.value = "foo bar baz";
root.caretIndex = "foo ba".length;
root.replace("foo ".length, "foo bar".length, "bazinga");

assert(root.value == "foo bazinga baz");
assert(root.valueBeforeCaret == "foo bazinga");

}

@("TextInput.replace correctly sets cursor position (caret after selection)")
unittest {

auto root = textInput();
root.value = "foo bar baz";
root.caretIndex = "foo bar ".length;
root.replace("foo ".length, "foo bar".length, "bazinga");

assert(root.value == "foo bazinga baz");
assert(root.valueBeforeCaret == "foo bazinga ");

}

@("TextInput.replace correctly sets cursor position (caret before selection)")
unittest {

auto root = textInput();
root.value = "foo bar baz";
root.caretIndex = "foo ".length;
root.replace("foo ".length, "foo bar".length, "bazinga");

assert(root.value == "foo bazinga baz");
assert(root.valueBeforeCaret == "foo ");

}

/// Insert text at the given position.
void insert(size_t position, Rope value) {

Expand Down Expand Up @@ -2588,7 +2637,7 @@ class TextInput : InputNode!Node, FluidScrollable {
auto stop = yield(lineStart, front);

// Update indices in case the line has changed
if (front !is originalFront) {
if (front.chomp !is originalFront) {
setLine(originalFront, front);
}

Expand Down

0 comments on commit d77b111

Please sign in to comment.