fix(ux) bug in replaceRange dealing with newLines that was breaking vim support (#5320)

This commit is contained in:
Jacob Richman
2025-07-31 16:16:29 -07:00
committed by GitHub
parent 150a2568b4
commit 750e647988
7 changed files with 204 additions and 98 deletions

View File

@@ -0,0 +1,63 @@
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/// <reference types="vitest/globals" />
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { expect } from 'vitest';
import type { TextBuffer } from '../ui/components/shared/text-buffer.js';
// RegExp to detect invalid characters: backspace, and ANSI escape codes
// eslint-disable-next-line no-control-regex
const invalidCharsRegex = /[\b\x1b]/;
function toHaveOnlyValidCharacters(this: vi.Assertion, buffer: TextBuffer) {
const { isNot } = this;
let pass = true;
const invalidLines: Array<{ line: number; content: string }> = [];
for (let i = 0; i < buffer.lines.length; i++) {
const line = buffer.lines[i];
if (line.includes('\n')) {
pass = false;
invalidLines.push({ line: i, content: line });
break; // Fail fast on newlines
}
if (invalidCharsRegex.test(line)) {
pass = false;
invalidLines.push({ line: i, content: line });
}
}
return {
pass,
message: () =>
`Expected buffer ${isNot ? 'not ' : ''}to have only valid characters, but found invalid characters in lines:\n${invalidLines
.map((l) => ` [${l.line}]: "${l.content}"`) /* This line was changed */
.join('\n')}`,
actual: buffer.lines,
expected: 'Lines with no line breaks, backspaces, or escape codes.',
};
}
expect.extend({
toHaveOnlyValidCharacters,
});
// Extend Vitest's `expect` interface with the custom matcher's type definition.
declare module 'vitest' {
interface Assertion<T> {
toHaveOnlyValidCharacters(): T;
}
interface AsymmetricMatchersContaining {
toHaveOnlyValidCharacters(): void;
}
}

View File

@@ -53,8 +53,10 @@ export const createMockCommandContext = (
setPendingItem: vi.fn(),
loadHistory: vi.fn(),
toggleCorgiMode: vi.fn(),
toggleVimEnabled: vi.fn(),
},
session: {
sessionShellAllowlist: new Set<string>(),
stats: {
sessionStartTime: new Date(),
lastPromptTokenCount: 0,