File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff 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 */
2224export 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 - Z 0 - 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
3752function isTerminalInput ( input : unknown ) : input is ITerminalInput {
Original file line number Diff line number Diff 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
2733describe ( '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 } ) ;
You can’t perform that action at this time.
0 commit comments