Skip to content

Commit 054f2b1

Browse files
Megan RoggeMegan Rogge
authored andcommitted
Fix parseCommandHead to skip leading long flags
git --no-pager diff was being parsed as sub=--no-pager and missing the gitDiffFilter. Now long flags after the head are skipped.
1 parent e580aa9 commit 054f2b1

2 files changed

Lines changed: 28 additions & 4 deletions

File tree

src/extension/tools/node/compressors/terminalOutputCompressor.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ interface ITerminalInput {
1616

1717
/**
1818
* Returns the "head" of a shell command — the first executable word, after
19-
* skipping common env-var assignments like `FOO=bar baz`. Returns `undefined`
20-
* when the command can't be parsed.
19+
* skipping common env-var assignments like `FOO=bar baz`. `sub` is the first
20+
* non-long-flag token after the head, so `git --no-pager diff` yields
21+
* `{ head: 'git', sub: 'diff' }`. Returns `undefined` when the command can't
22+
* be parsed.
2123
*/
2224
export function parseCommandHead(command: string | undefined): { head: string; sub: string | undefined } | undefined {
2325
if (!command) {
@@ -30,8 +32,21 @@ export function parseCommandHead(command: string | undefined): { head: string; s
3032
}
3133
const tokens = firstSegment.split(/\s+/).filter(t => !/^[A-Z_][A-Z0-9_]*=/.test(t));
3234
const head = tokens[0];
33-
const sub = tokens[1];
34-
return head ? { head, sub } : undefined;
35+
if (!head) {
36+
return undefined;
37+
}
38+
// Skip leading long flags like `--no-pager` so `git --no-pager diff` parses
39+
// as `{ head: 'git', sub: 'diff' }`. Short flags (`-la`) stay as the sub
40+
// because for tools like `ls` they're the entire intent.
41+
let sub: string | undefined;
42+
for (let i = 1; i < tokens.length; i++) {
43+
if (tokens[i].startsWith('--')) {
44+
continue;
45+
}
46+
sub = tokens[i];
47+
break;
48+
}
49+
return { head, sub };
3550
}
3651

3752
function isTerminalInput(input: unknown): input is ITerminalInput {

src/extension/tools/node/test/terminalOutputCompressor.spec.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ describe('parseCommandHead', () => {
2222
it('uses only first pipeline segment', () => {
2323
expect(parseCommandHead('git diff | cat')).toEqual({ head: 'git', sub: 'diff' });
2424
});
25+
it('skips leading long flags before the subcommand', () => {
26+
expect(parseCommandHead('git --no-pager diff src/foo.ts')).toEqual({ head: 'git', sub: 'diff' });
27+
});
28+
it('skips short flag plus value before the subcommand', () => {
29+
expect(parseCommandHead('git -C /tmp/repo diff')).toEqual({ head: 'git', sub: '-C' });
30+
});
2531
});
2632

2733
describe('gitDiffFilter', () => {
@@ -30,6 +36,9 @@ describe('gitDiffFilter', () => {
3036
it('matches git diff', () => {
3137
expect(gitDiffFilter.matches('run_in_terminal', input)).toBe(true);
3238
});
39+
it('matches git --no-pager diff', () => {
40+
expect(gitDiffFilter.matches('run_in_terminal', { command: 'git --no-pager diff src/foo.ts' })).toBe(true);
41+
});
3342
it('does not match git status', () => {
3443
expect(gitDiffFilter.matches('run_in_terminal', { command: 'git status' })).toBe(false);
3544
});

0 commit comments

Comments
 (0)