@@ -152,6 +152,32 @@ fn confirm(globalObject: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) bun.JSE
152152}
153153
154154pub 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