Skip to content

Commit 48ec303

Browse files
committed
Refactor prompt input handling for clarity and maintainability
1 parent 761612d commit 48ec303

File tree

1 file changed

+37
-42
lines changed

1 file changed

+37
-42
lines changed

src/bun.js/webcore/prompt.zig

Lines changed: 37 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,32 @@ fn confirm(globalObject: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) bun.JSE
152152
}
153153

154154
pub const prompt = struct {
155+
const KEY_CTRL_C = 3;
156+
const KEY_CTRL_D = 4;
157+
const KEY_BACKSPACE = 8;
158+
const KEY_TAB = 9;
159+
const KEY_ENTER = 13;
160+
const KEY_ESC = 27;
161+
const KEY_DEL = 127;
162+
163+
fn handleBackspace(input: *std.ArrayList(u8), cursor_index: *usize) void {
164+
if (cursor_index.* > 0) {
165+
const old_cursor_index = cursor_index.*;
166+
const prev_codepoint_start = utf8Prev(input.items, old_cursor_index);
167+
168+
if (prev_codepoint_start) |start| {
169+
var i: usize = 0;
170+
while (i < old_cursor_index - start) : (i += 1) {
171+
_ = input.orderedRemove(start);
172+
}
173+
cursor_index.* = start;
174+
} else {
175+
_ = input.orderedRemove(old_cursor_index - 1);
176+
cursor_index.* -= 1;
177+
}
178+
}
179+
}
180+
155181
fn utf8Prev(slice: []const u8, index: usize) ?usize {
156182
if (index == 0) return null;
157183
var i = index - 1;
@@ -425,14 +451,13 @@ pub const prompt = struct {
425451
};
426452

427453
switch (byte) {
428-
// Tab (ASCII 9)
429-
9 => {
454+
KEY_TAB => {
430455
try input.insert(cursor_index, byte);
431456
cursor_index += 1;
432457
},
433458

434459
// End of input
435-
'\n', '\r' => {
460+
'\n', KEY_ENTER => {
436461
if (input.items.len == 0 and !has_default) return jsc.ZigString.init("").toJS(globalObject);
437462
if (input.items.len == 0) return default;
438463

@@ -441,53 +466,23 @@ pub const prompt = struct {
441466
return result.toJS(globalObject);
442467
},
443468

444-
// Backspace (ASCII 8) or DEL (ASCII 127)
445-
8, 127 => {
446-
if (cursor_index > 0) {
447-
const old_cursor_index = cursor_index;
448-
const prev_codepoint_start = utf8Prev(input.items, old_cursor_index);
449-
450-
if (prev_codepoint_start) |start| {
451-
// Remove the codepoint bytes
452-
var i: usize = 0;
453-
while (i < old_cursor_index - start) : (i += 1) {
454-
_ = input.orderedRemove(start);
455-
}
456-
cursor_index = start;
457-
} else {
458-
// Fallback for invalid UTF-8 or start of string: delete one byte
459-
_ = input.orderedRemove(old_cursor_index - 1);
460-
cursor_index -= 1;
461-
}
462-
}
463-
}, // Ctrl+C
464-
3 => {
469+
// Backspace
470+
KEY_BACKSPACE, KEY_DEL => handleBackspace(&input, &cursor_index),
471+
472+
// Ctrl+C
473+
KEY_CTRL_C => {
465474
// This will trigger the defer and restore terminal settings
466475
pending_sigint = true;
467476
return .null;
468477
},
469478

470479
// Escape sequence (e.g., arrow keys, alt+backspace)
471-
27 => block: {
480+
KEY_ESC => block: {
472481
const byte2 = reader.readByte() catch break :block;
473482

474483
// Alt+Backspace -> treat as regular backspace
475-
if (byte2 == 127 or byte2 == 8) {
476-
if (cursor_index > 0) {
477-
const old_cursor_index = cursor_index;
478-
const prev_codepoint_start = utf8Prev(input.items, old_cursor_index);
479-
480-
if (prev_codepoint_start) |start| {
481-
var i: usize = 0;
482-
while (i < old_cursor_index - start) : (i += 1) {
483-
_ = input.orderedRemove(start);
484-
}
485-
cursor_index = start;
486-
} else {
487-
_ = input.orderedRemove(old_cursor_index - 1);
488-
cursor_index -= 1;
489-
}
490-
}
484+
if (byte2 == KEY_DEL or byte2 == KEY_BACKSPACE) {
485+
handleBackspace(&input, &cursor_index);
491486
break :block; // Exit escape sequence handler to allow redraw
492487
}
493488

@@ -547,7 +542,7 @@ pub const prompt = struct {
547542
},
548543

549544
// Ctrl+D (EOT)
550-
4 => {
545+
KEY_CTRL_D => {
551546
return .null;
552547
},
553548

0 commit comments

Comments
 (0)