Skip to content

Commit eaa66a9

Browse files
fix: [CLI-273] use negative offset for first() (#15)
### What changed? Changed the offset in `first()` to reflect that we are moving back by the rendered text length. ### Why? In the rendering code, cursorOffset is used after rendering the text to move the cursor into the desired position. On first() we were incorrectly using a offset of 0 which would not move the caret. This resulted in the caret being stuck where it was (at the end of the line). Used the script in the draft PR above to test: [prompts_testing.mov <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.stg.graphite.com/user-attachments/thumbnails/42757caa-0133-4e98-be5a-214e8ca54fe3.mov" />](https://app.stg.graphite.com/user-attachments/video/42757caa-0133-4e98-be5a-214e8ca54fe3.mov)
1 parent 5855b14 commit eaa66a9

File tree

2 files changed

+35
-11
lines changed

2 files changed

+35
-11
lines changed

lib/elements/text.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ class TextPrompt extends Prompt {
188188

189189
first() {
190190
this.cursor = 0;
191-
this.cursorOffset = 0;
191+
this.cursorOffset = -this.rendered.length;
192192
this.render();
193193
}
194194

test/text.js

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -92,39 +92,63 @@ test('deleteToStart', (t) => {
9292
});
9393

9494
test('first', (t) => {
95-
t.plan(3);
95+
t.plan(4);
9696

9797
const textPrompt = new TextPrompt();
9898
textPrompt.value = 'Hello, world!';
9999
textPrompt.last();
100100
textPrompt.render();
101101

102-
// Nudge left so offset is non-zero, then verify reset on first()
103-
textPrompt.left();
104-
t.same(textPrompt.cursorOffset, -1, 'precondition: cursorOffset moved left');
102+
// Move left repeatedly to the beginning to capture expected state
103+
const length = textPrompt.rendered.length;
104+
for (let i = 0; i < length; i++) {
105+
textPrompt.left();
106+
}
107+
108+
const expectedCursor = textPrompt.cursor;
109+
const expectedOffset = textPrompt.cursorOffset;
110+
111+
t.same(expectedCursor, 0, 'manual movement reaches start');
105112

113+
// Reset to end and use first()
114+
textPrompt.last();
115+
textPrompt.render();
106116
textPrompt.first();
117+
118+
t.same(textPrompt.cursor, expectedCursor, 'first() cursor matches manual movement');
119+
t.same(textPrompt.cursorOffset, expectedOffset, 'first() cursorOffset matches manual movement');
107120
t.same(textPrompt.cursor, 0, 'cursor moved to start');
108-
t.same(textPrompt.cursorOffset, 0, 'cursorOffset reset to 0');
109121

110122
t.end();
111123
});
112124

113125
test('last', (t) => {
114-
t.plan(3);
126+
t.plan(4);
115127

116128
const textPrompt = new TextPrompt();
117129
textPrompt.value = 'Hello, world!';
118130
textPrompt.first();
119131
textPrompt.render();
120132

121-
// Nudge right so offset is non-zero, then verify reset on last()
122-
textPrompt.right();
123-
t.same(textPrompt.cursorOffset, 1, 'precondition: cursorOffset moved right');
133+
// Move right repeatedly to the end to capture expected state
134+
const length = textPrompt.rendered.length;
135+
for (let i = 0; i < length; i++) {
136+
textPrompt.right();
137+
}
138+
139+
const expectedCursor = textPrompt.cursor;
140+
const expectedOffset = textPrompt.cursorOffset;
141+
142+
t.same(expectedCursor, textPrompt.rendered.length, 'manual movement reaches end');
124143

144+
// Reset to start and use last()
145+
textPrompt.first();
146+
textPrompt.render();
125147
textPrompt.last();
148+
149+
t.same(textPrompt.cursor, expectedCursor, 'last() cursor matches manual movement');
150+
t.same(textPrompt.cursorOffset, expectedOffset, 'last() cursorOffset matches manual movement');
126151
t.same(textPrompt.cursor, textPrompt.rendered.length, 'cursor moved to end');
127-
t.same(textPrompt.cursorOffset, 0, 'cursorOffset reset to 0');
128152

129153
t.end();
130154
});

0 commit comments

Comments
 (0)