fix(tui): address PR review feedback

Fixes from OutThisLife review:
1. Restore Linux Alt+Enter newline: textInput.tsx now uses
   k.shift || (isMac ? isActionMod(k) : k.meta) so Alt+Enter
   inserts a newline on Linux (was broken by isMac guard).
2. Fix image.attach response type: useComposerState.ts now uses
   ImageAttachResponse (which already has remainder) instead of
   InputDetectDropResponse with intersection.
3. Expand looksLikeDroppedPath test coverage with edge cases for
   image extensions, file:// URIs, spaces, empty input, and
   non-file URLs.
4. Make terminalParity.test.ts hermetic: terminalParityHints() now
   accepts optional fileOps/homeDir and passes them through to
   shouldPromptForTerminalSetup(), so tests inject mock readFile
   instead of hitting the real filesystem.

Fixes from Copilot inline review:
5. Remove unused options.now parameter from configureTerminalKeybindings.
6. Replace naive stripJsonComments (full-line // only) with a proper
   JSONC stripper that handles inline // comments, block comments,
   trailing commas, and preserves comment-like sequences in strings.
7. Move backupFile() call from immediately after read to right before
   write - backups are only created when changes will actually be
   written, not on every /terminal-setup invocation.
This commit is contained in:
kshitijk4poor 2026-04-21 20:05:18 +05:30 committed by kshitij
parent 9556fef5a1
commit bc9927dc50
7 changed files with 160 additions and 13 deletions

View file

@ -30,6 +30,21 @@ describe('terminalSetup helpers', () => {
it('strips line comments from keybindings JSON', () => {
expect(stripJsonComments('// comment\n[{"key":"shift+enter"}]')).toBe('\n[{"key":"shift+enter"}]')
})
it('strips inline comments and block comments', () => {
expect(stripJsonComments('[{"key":"a"} // inline\n]')).toBe('[{"key":"a"} \n]')
expect(stripJsonComments('[/* block */{"key":"a"}]')).toBe('[{"key":"a"}]')
})
it('removes trailing commas before ] or }', () => {
expect(JSON.parse(stripJsonComments('[{"key":"a"},]'))).toEqual([{ key: 'a' }])
expect(JSON.parse(stripJsonComments('[{"key":"a",}]'))).toEqual([{ key: 'a' }])
})
it('preserves comment-like sequences inside strings', () => {
const input = '[{"key":"a","args":{"text":"// not a comment"}}]'
expect(JSON.parse(stripJsonComments(input))).toEqual([{ key: 'a', args: { text: '// not a comment' } }])
})
})
describe('configureTerminalKeybindings', () => {
@ -48,6 +63,7 @@ describe('configureTerminalKeybindings', () => {
expect(result.success).toBe(true)
expect(result.requiresRestart).toBe(true)
expect(writeFile).toHaveBeenCalledTimes(1)
expect(copyFile).not.toHaveBeenCalled() // no existing file to back up
const written = writeFile.mock.calls[0]?.[1] as string
expect(written).toContain('shift+enter')
expect(written).toContain('cmd+enter')
@ -78,6 +94,24 @@ describe('configureTerminalKeybindings', () => {
expect(result.success).toBe(false)
expect(result.message).toContain('cmd+z')
expect(writeFile).not.toHaveBeenCalled()
expect(copyFile).not.toHaveBeenCalled() // no backup when not writing
})
it('backs up existing keybindings.json only when writing changes', async () => {
const mkdir = vi.fn().mockResolvedValue(undefined)
const readFile = vi.fn().mockResolvedValue(JSON.stringify([]))
const writeFile = vi.fn().mockResolvedValue(undefined)
const copyFile = vi.fn().mockResolvedValue(undefined)
const result = await configureTerminalKeybindings('vscode', {
fileOps: { copyFile, mkdir, readFile, writeFile },
homeDir: '/Users/me',
platform: 'darwin'
})
expect(result.success).toBe(true)
expect(writeFile).toHaveBeenCalledTimes(1)
expect(copyFile).toHaveBeenCalledTimes(1) // backup created before writing
})
it('auto-detects the current IDE terminal', async () => {