fix(input): count code points when clearing prompts

This commit is contained in:
DodgyBadger
2026-09-20 07:18:49 +00:00
parent 0761de3dae
commit a220c28a14
4 changed files with 20 additions and 8 deletions
+3 -3
View File
@@ -1156,13 +1156,13 @@ const KeyboardAccessoryBar = {
const pending = app._localEchoOverlay.pendingText || ''; const pending = app._localEchoOverlay.pendingText || '';
const overlayFlushed = app._localEchoOverlay.getFlushed?.() || {}; const overlayFlushed = app._localEchoOverlay.getFlushed?.() || {};
const flushedText = overlayFlushed.text || app._flushedTexts?.get(sessionId) || ''; const flushedText = overlayFlushed.text || app._flushedTexts?.get(sessionId) || '';
const flushedCount = overlayFlushed.count || app._flushedOffsets?.get(sessionId) || 0; const flushedLength = Array.from(flushedText).length;
app._localEchoOverlay.clear(); app._localEchoOverlay.clear();
app._localEchoOverlay.suppressBufferDetection?.(); app._localEchoOverlay.suppressBufferDetection?.();
app._flushedOffsets?.delete(sessionId); app._flushedOffsets?.delete(sessionId);
app._flushedTexts?.delete(sessionId); app._flushedTexts?.delete(sessionId);
if (flushedCount > 0) { if (flushedLength > 0) {
app._sendInputAsync(sessionId, '\x7f'.repeat(flushedCount), { useMux: true }); app._sendInputAsync(sessionId, '\x7f'.repeat(flushedLength), { useMux: true });
} }
return flushedText + pending; return flushedText + pending;
}, },
+3 -2
View File
@@ -4069,8 +4069,9 @@ Object.assign(CodemanApp.prototype, {
this._localEchoOverlay.suppressBufferDetection(); this._localEchoOverlay.suppressBufferDetection();
this._flushedOffsets?.delete(this.activeSessionId); this._flushedOffsets?.delete(this.activeSessionId);
this._flushedTexts?.delete(this.activeSessionId); this._flushedTexts?.delete(this.activeSessionId);
if (flushed.count > 0) { const flushedLength = Array.from(flushed.text || '').length;
this.sendInput('\x7f'.repeat(flushed.count)).catch(() => {}); if (flushedLength > 0) {
this.sendInput('\x7f'.repeat(flushedLength)).catch(() => {});
} }
} else { } else {
// In non-local-echo mode the TUI already owns the editable buffer. Ctrl+U // In non-local-echo mode the TUI already owns the editable buffer. Ctrl+U
+11
View File
@@ -152,6 +152,17 @@ describe('mobile prompt composer', () => {
expect(app._flushedTexts.has('session-1')).toBe(false); expect(app._flushedTexts.has('session-1')).toBe(false);
}); });
it('uses Unicode code points when erasing flushed text', () => {
const { app, bar, document } = loadComposer();
app._flushedOffsets.set('session-1', 3);
app._flushedTexts.set('session-1', 'a😀');
bar.composePrompt();
expect(textarea(document).value).toBe('a😀');
expect(app._sendInputAsync).toHaveBeenCalledWith('session-1', '\x7f'.repeat(2), { useMux: true });
});
it('closes on tab switch and keeps drafts isolated by session', () => { it('closes on tab switch and keeps drafts isolated by session', () => {
const { app, bar, document } = loadComposer(); const { app, bar, document } = loadComposer();
const composeButton = mountComposeButton(bar, document); const composeButton = mountComposeButton(bar, document);
+3 -3
View File
@@ -200,12 +200,12 @@ describe('mobile filesystem picker actions', () => {
_pendingInput: 'pending text', _pendingInput: 'pending text',
_localEchoEnabled: true, _localEchoEnabled: true,
_localEchoOverlay: { _localEchoOverlay: {
getFlushed: () => ({ count: 4, text: 'sent' }), getFlushed: () => ({ count: 4, text: 'a😀b' }),
clear, clear,
suppressBufferDetection, suppressBufferDetection,
}, },
_flushedOffsets: new Map([['session-1', 4]]), _flushedOffsets: new Map([['session-1', 4]]),
_flushedTexts: new Map([['session-1', 'sent']]), _flushedTexts: new Map([['session-1', 'a😀b']]),
sendInput, sendInput,
showToast, showToast,
terminal: { focus }, terminal: { focus },
@@ -216,7 +216,7 @@ describe('mobile filesystem picker actions', () => {
expect(app._pendingInput).toBe(''); expect(app._pendingInput).toBe('');
expect(clear).toHaveBeenCalledOnce(); expect(clear).toHaveBeenCalledOnce();
expect(suppressBufferDetection).toHaveBeenCalledOnce(); expect(suppressBufferDetection).toHaveBeenCalledOnce();
expect(sendInput).toHaveBeenCalledWith('\x7f'.repeat(4)); expect(sendInput).toHaveBeenCalledWith('\x7f'.repeat(3));
expect(sendInput).not.toHaveBeenCalledWith('/clear'); expect(sendInput).not.toHaveBeenCalledWith('/clear');
expect(app._flushedOffsets.size).toBe(0); expect(app._flushedOffsets.size).toBe(0);
expect(app._flushedTexts.size).toBe(0); expect(app._flushedTexts.size).toBe(0);