From 1d3046e6fe0ec08dd388018a5f636656803273d8 Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Sun, 23 Nov 2025 18:17:20 +0330 Subject: [PATCH 01/19] use pwsh stop parsing operator --- src/powershell.ts | 48 +++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/powershell.ts b/src/powershell.ts index a2337c3..44da379 100644 --- a/src/powershell.ts +++ b/src/powershell.ts @@ -3,30 +3,30 @@ import { ShellCompDirective } from './t'; // TODO: issue with -- -- completions export function generate( - name: string, - exec: string, - includeDesc = false + name: string, + exec: string, + includeDesc = false ): string { - // Replace '-' and ':' with '_' for variable names - const nameForVar = name.replace(/[-:]/g, '_'); - - // Determine the completion command - // const compCmd = includeDesc ? "complete" : "complete"; - - // Shell completion directives - const ShellCompDirectiveError = ShellCompDirective.ShellCompDirectiveError; - const ShellCompDirectiveNoSpace = - ShellCompDirective.ShellCompDirectiveNoSpace; - const ShellCompDirectiveNoFileComp = - ShellCompDirective.ShellCompDirectiveNoFileComp; - const ShellCompDirectiveFilterFileExt = - ShellCompDirective.ShellCompDirectiveFilterFileExt; - const ShellCompDirectiveFilterDirs = - ShellCompDirective.ShellCompDirectiveFilterDirs; - const ShellCompDirectiveKeepOrder = - ShellCompDirective.ShellCompDirectiveKeepOrder; - - return `# powershell completion for ${name} -*- shell-script -*- + // Replace '-' and ':' with '_' for variable names + const nameForVar = name.replace(/[-:]/g, '_'); + + // Determine the completion command + // const compCmd = includeDesc ? "complete" : "complete"; + + // Shell completion directives + const ShellCompDirectiveError = ShellCompDirective.ShellCompDirectiveError; + const ShellCompDirectiveNoSpace = + ShellCompDirective.ShellCompDirectiveNoSpace; + const ShellCompDirectiveNoFileComp = + ShellCompDirective.ShellCompDirectiveNoFileComp; + const ShellCompDirectiveFilterFileExt = + ShellCompDirective.ShellCompDirectiveFilterFileExt; + const ShellCompDirectiveFilterDirs = + ShellCompDirective.ShellCompDirectiveFilterDirs; + const ShellCompDirectiveKeepOrder = + ShellCompDirective.ShellCompDirectiveKeepOrder; + + return `# powershell completion for ${name} -*- shell-script -*- [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 function __${name}_debug { @@ -75,7 +75,7 @@ export function generate( # Split the command at the first space to separate the program and arguments. $Program, $Arguments = $Command.Split(" ", 2) - $RequestComp = "& ${exec} complete -- $Arguments" + $RequestComp = "& ${exec} complete --% -- $Arguments" __${name}_debug "RequestComp: $RequestComp" # we cannot use $WordToComplete because it From 76fcd526f88645c13cb115eecd874394889eb1e5 Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Sun, 23 Nov 2025 22:15:13 +0330 Subject: [PATCH 02/19] fix: cli detect pwsh --- bin/cli.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bin/cli.ts b/bin/cli.ts index b860f22..cfad28f 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -9,6 +9,10 @@ const shells = ['zsh', 'bash', 'fish', 'powershell']; async function main() { const args = process.argv.slice(2); + const isPwsh = process.platform === 'win32' && !!process.env.PSModulePath; + if ( isPwsh && args.length >= 2 && args[1] === 'complete' && process.argv.indexOf('--') === -1 ) { + process.argv.push('--'); + } // complete -- if (args.length >= 2 && args[1] === 'complete') { @@ -57,7 +61,7 @@ async function main() { process.exit(0); } - console.error('Usage: tab '); + console.error('Usages: tab '); console.error(` tab complete -- `); process.exit(1); } From 7e03793ccfb95bba892be88107fa43f87763ce49 Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Sun, 23 Nov 2025 22:28:44 +0330 Subject: [PATCH 03/19] remove operator --- src/powershell.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/powershell.ts b/src/powershell.ts index 44da379..4c2acd5 100644 --- a/src/powershell.ts +++ b/src/powershell.ts @@ -75,7 +75,7 @@ export function generate( # Split the command at the first space to separate the program and arguments. $Program, $Arguments = $Command.Split(" ", 2) - $RequestComp = "& ${exec} complete --% -- $Arguments" + $RequestComp = "& ${exec} complete -- $Arguments" __${name}_debug "RequestComp: $RequestComp" # we cannot use $WordToComplete because it From 8e7e4452216f89226f10c1bf72f879745c62dbe3 Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Sun, 23 Nov 2025 22:51:04 +0330 Subject: [PATCH 04/19] add debug log --- bin/cli.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bin/cli.ts b/bin/cli.ts index cfad28f..f04cb3c 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -14,6 +14,10 @@ async function main() { process.argv.push('--'); } + if (process.env.TAB_DEBUG) { + console.error("RAW ARGS:", process.argv); + } + // complete -- if (args.length >= 2 && args[1] === 'complete') { const packageManager = args[0]; @@ -68,6 +72,8 @@ async function main() { function generateCompletionScript(packageManager: string, shell: string) { const name = packageManager; + console.log(process.argv); + const isLocalDev = process.argv[1].endsWith('dist/bin/cli.js'); From b7872344453c8e706e2072b6c99bc293a5713fbd Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Mon, 24 Nov 2025 00:55:43 +0330 Subject: [PATCH 05/19] exclude pwsh from having -- required --- bin/cli.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/bin/cli.ts b/bin/cli.ts index f04cb3c..92adfd5 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -9,10 +9,6 @@ const shells = ['zsh', 'bash', 'fish', 'powershell']; async function main() { const args = process.argv.slice(2); - const isPwsh = process.platform === 'win32' && !!process.env.PSModulePath; - if ( isPwsh && args.length >= 2 && args[1] === 'complete' && process.argv.indexOf('--') === -1 ) { - process.argv.push('--'); - } if (process.env.TAB_DEBUG) { console.error("RAW ARGS:", process.argv); @@ -31,12 +27,22 @@ async function main() { } const dashIndex = process.argv.indexOf('--'); + const isPowerShell = process.platform === 'win32' && process.env.PSModulePath !== undefined; + if (dashIndex !== -1) { + // POSIX shells or explicit -- usage const completion = new PackageManagerCompletion(packageManager); await setupCompletionForPackageManager(packageManager, completion); const toComplete = process.argv.slice(dashIndex + 1); await completion.parse(toComplete); process.exit(0); + } else if (isPowerShell && args.length > 2) { + // PowerShell: -- was stripped, everything after 'complete' is what we want + const completion = new PackageManagerCompletion(packageManager); + await setupCompletionForPackageManager(packageManager, completion); + const toComplete = args.slice(2); + await completion.parse(toComplete); + process.exit(0); } else { console.error(`Error: Expected '--' followed by command to complete`); process.exit(1); From cfe36d096fe1e7b5998e1ff1bdb0affa35eea961 Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Mon, 24 Nov 2025 00:58:04 +0330 Subject: [PATCH 06/19] update --- bin/cli.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/cli.ts b/bin/cli.ts index 92adfd5..2eed7a9 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -36,7 +36,7 @@ async function main() { const toComplete = process.argv.slice(dashIndex + 1); await completion.parse(toComplete); process.exit(0); - } else if (isPowerShell && args.length > 2) { + } else if (isPowerShell) { // PowerShell: -- was stripped, everything after 'complete' is what we want const completion = new PackageManagerCompletion(packageManager); await setupCompletionForPackageManager(packageManager, completion); From c3d924a532827c74b580b9b7cf2073b32ab5efcd Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Mon, 24 Nov 2025 01:06:09 +0330 Subject: [PATCH 07/19] add -- manually --- bin/cli.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bin/cli.ts b/bin/cli.ts index 2eed7a9..e086046 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -40,7 +40,10 @@ async function main() { // PowerShell: -- was stripped, everything after 'complete' is what we want const completion = new PackageManagerCompletion(packageManager); await setupCompletionForPackageManager(packageManager, completion); - const toComplete = args.slice(2); + let toComplete = args.slice(2); + // Always append -- for PowerShell (it was stripped from the input) + // This ensures option completion works correctly + toComplete.push('--'); await completion.parse(toComplete); process.exit(0); } else { From 2a7ec8a6b806704dad8c1881561f76248d729db8 Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Mon, 24 Nov 2025 01:10:35 +0330 Subject: [PATCH 08/19] add -- manually --- bin/cli.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/bin/cli.ts b/bin/cli.ts index e086046..2be2fb8 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -41,9 +41,10 @@ async function main() { const completion = new PackageManagerCompletion(packageManager); await setupCompletionForPackageManager(packageManager, completion); let toComplete = args.slice(2); - // Always append -- for PowerShell (it was stripped from the input) - // This ensures option completion works correctly - toComplete.push('--'); + // Only append -- if there are actual args (PowerShell stripped the trailing --) + if (toComplete.length > 0) { + toComplete.push('--'); + } await completion.parse(toComplete); process.exit(0); } else { From b7dd1aad31587c84fa874a787a5dd9cd2b233174 Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Mon, 24 Nov 2025 01:15:05 +0330 Subject: [PATCH 09/19] fix partial command detection --- bin/cli.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/bin/cli.ts b/bin/cli.ts index 2be2fb8..0a26450 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -41,9 +41,10 @@ async function main() { const completion = new PackageManagerCompletion(packageManager); await setupCompletionForPackageManager(packageManager, completion); let toComplete = args.slice(2); - // Only append -- if there are actual args (PowerShell stripped the trailing --) - if (toComplete.length > 0) { - toComplete.push('--'); + // In PowerShell, -- is stripped. Only append it if the last arg is a flag + // (starts with -), meaning we want flag/option completion + if (toComplete.length > 0 && toComplete[toComplete.length - 1].startsWith('-')) { + toComplete = [...toComplete, '--']; } await completion.parse(toComplete); process.exit(0); From 5371795d6ac975021c1615a470a8d826d285736f Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Mon, 24 Nov 2025 01:20:22 +0330 Subject: [PATCH 10/19] test empty string --- bin/cli.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/cli.ts b/bin/cli.ts index 0a26450..0588d22 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -41,10 +41,10 @@ async function main() { const completion = new PackageManagerCompletion(packageManager); await setupCompletionForPackageManager(packageManager, completion); let toComplete = args.slice(2); - // In PowerShell, -- is stripped. Only append it if the last arg is a flag - // (starts with -), meaning we want flag/option completion - if (toComplete.length > 0 && toComplete[toComplete.length - 1].startsWith('-')) { - toComplete = [...toComplete, '--']; + // In PowerShell, -- is stripped. Append empty string to simulate space at end + // This lets the parser know we want completions for what comes after the last arg + if (toComplete.length > 0) { + toComplete = [...toComplete, '']; } await completion.parse(toComplete); process.exit(0); From c8a6b7e56ba68ba314246446ccd2fb23b25c2ed6 Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Mon, 24 Nov 2025 01:25:18 +0330 Subject: [PATCH 11/19] i bet this will work --- bin/cli.ts | 15 --------------- src/powershell.ts | 2 +- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/bin/cli.ts b/bin/cli.ts index 0588d22..45901bd 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -27,27 +27,12 @@ async function main() { } const dashIndex = process.argv.indexOf('--'); - const isPowerShell = process.platform === 'win32' && process.env.PSModulePath !== undefined; - if (dashIndex !== -1) { - // POSIX shells or explicit -- usage const completion = new PackageManagerCompletion(packageManager); await setupCompletionForPackageManager(packageManager, completion); const toComplete = process.argv.slice(dashIndex + 1); await completion.parse(toComplete); process.exit(0); - } else if (isPowerShell) { - // PowerShell: -- was stripped, everything after 'complete' is what we want - const completion = new PackageManagerCompletion(packageManager); - await setupCompletionForPackageManager(packageManager, completion); - let toComplete = args.slice(2); - // In PowerShell, -- is stripped. Append empty string to simulate space at end - // This lets the parser know we want completions for what comes after the last arg - if (toComplete.length > 0) { - toComplete = [...toComplete, '']; - } - await completion.parse(toComplete); - process.exit(0); } else { console.error(`Error: Expected '--' followed by command to complete`); process.exit(1); diff --git a/src/powershell.ts b/src/powershell.ts index 4c2acd5..9c7da1e 100644 --- a/src/powershell.ts +++ b/src/powershell.ts @@ -75,7 +75,7 @@ export function generate( # Split the command at the first space to separate the program and arguments. $Program, $Arguments = $Command.Split(" ", 2) - $RequestComp = "& ${exec} complete -- $Arguments" + $RequestComp = "& ${exec} complete '--' $Arguments" __${name}_debug "RequestComp: $RequestComp" # we cannot use $WordToComplete because it From 80703778e4487fa77145846ab41ce1a763591a49 Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Sun, 30 Nov 2025 23:48:54 +0330 Subject: [PATCH 12/19] test --- bin/cli.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/bin/cli.ts b/bin/cli.ts index 45901bd..de517ba 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -34,8 +34,20 @@ async function main() { await completion.parse(toComplete); process.exit(0); } else { - console.error(`Error: Expected '--' followed by command to complete`); - process.exit(1); + // Handle PowerShell case where trailing '--' gets stripped by npm.cmd + // In PowerShell, args after 'complete' should be treated as completion args + const isPowerShell = process.platform === 'win32' && process.env.PSModulePath; + if (isPowerShell) { + const completion = new PackageManagerCompletion(packageManager); + await setupCompletionForPackageManager(packageManager, completion); + // Take args after 'complete' (args[2..]) as the completion args + const toComplete = args.slice(2); + await completion.parse(toComplete); + process.exit(0); + } else { + console.error(`Error: Expected '--' followed by command to complete`); + process.exit(1); + } } } From 657e6848c93b305c72f9984590aaf0511c1a9116 Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Sat, 6 Dec 2025 16:54:12 +0330 Subject: [PATCH 13/19] test --- bin/cli.ts | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/bin/cli.ts b/bin/cli.ts index de517ba..0e998d1 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -9,9 +9,10 @@ const shells = ['zsh', 'bash', 'fish', 'powershell']; async function main() { const args = process.argv.slice(2); + const isPowerShell = process.platform === 'win32' && process.env.PSModulePath; if (process.env.TAB_DEBUG) { - console.error("RAW ARGS:", process.argv); + console.error('RAW ARGS:', process.argv); } // complete -- @@ -27,28 +28,24 @@ async function main() { } const dashIndex = process.argv.indexOf('--'); - if (dashIndex !== -1) { - const completion = new PackageManagerCompletion(packageManager); - await setupCompletionForPackageManager(packageManager, completion); - const toComplete = process.argv.slice(dashIndex + 1); - await completion.parse(toComplete); - process.exit(0); - } else { - // Handle PowerShell case where trailing '--' gets stripped by npm.cmd - // In PowerShell, args after 'complete' should be treated as completion args - const isPowerShell = process.platform === 'win32' && process.env.PSModulePath; - if (isPowerShell) { - const completion = new PackageManagerCompletion(packageManager); - await setupCompletionForPackageManager(packageManager, completion); - // Take args after 'complete' (args[2..]) as the completion args - const toComplete = args.slice(2); - await completion.parse(toComplete); - process.exit(0); - } else { - console.error(`Error: Expected '--' followed by command to complete`); - process.exit(1); - } + // When PowerShell shims drop the literal '--', fall back to treating + // everything after "complete" as the completion payload. + const completionArgs = + dashIndex !== -1 + ? process.argv.slice(dashIndex + 1) + : isPowerShell + ? args.slice(2) + : null; + + if (!completionArgs) { + console.error(`Error: Expected '--' followed by command to complete`); + process.exit(1); } + + const completion = new PackageManagerCompletion(packageManager); + await setupCompletionForPackageManager(packageManager, completion); + await completion.parse(completionArgs); + process.exit(0); } // From b9fa951978887cac343620d9d5d2d40765500425 Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Sat, 6 Dec 2025 17:03:15 +0330 Subject: [PATCH 14/19] separator --- bin/cli.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bin/cli.ts b/bin/cli.ts index 0e998d1..961c88b 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -31,9 +31,11 @@ async function main() { // When PowerShell shims drop the literal '--', fall back to treating // everything after "complete" as the completion payload. const completionArgs = - dashIndex !== -1 + // POSIX or already-present separator + (dashIndex !== -1 && (!isPowerShell || dashIndex < process.argv.length - 1)) ? process.argv.slice(dashIndex + 1) : isPowerShell + // PowerShell shims may drop the first '--' and leave only a trailing one ? args.slice(2) : null; From cc5202bedc29dce95ac8cc423fee3f25d0aef933 Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Sat, 6 Dec 2025 17:10:27 +0330 Subject: [PATCH 15/19] add changeset --- .changeset/curvy-clouds-hide.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/curvy-clouds-hide.md diff --git a/.changeset/curvy-clouds-hide.md b/.changeset/curvy-clouds-hide.md new file mode 100644 index 0000000..ce812a9 --- /dev/null +++ b/.changeset/curvy-clouds-hide.md @@ -0,0 +1,5 @@ +--- +'@bomb.sh/tab': patch +--- + +Fix PowerShell completion argument parsing From 839464a5a6fbddf3d62f2463ef60ad59a9700474 Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Sat, 6 Dec 2025 17:13:25 +0330 Subject: [PATCH 16/19] prettier --- bin/cli.ts | 7 +++---- src/powershell.ts | 46 +++++++++++++++++++++++----------------------- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/bin/cli.ts b/bin/cli.ts index 961c88b..135c055 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -32,11 +32,11 @@ async function main() { // everything after "complete" as the completion payload. const completionArgs = // POSIX or already-present separator - (dashIndex !== -1 && (!isPowerShell || dashIndex < process.argv.length - 1)) + dashIndex !== -1 && (!isPowerShell || dashIndex < process.argv.length - 1) ? process.argv.slice(dashIndex + 1) : isPowerShell - // PowerShell shims may drop the first '--' and leave only a trailing one - ? args.slice(2) + ? // PowerShell shims may drop the first '--' and leave only a trailing one + args.slice(2) : null; if (!completionArgs) { @@ -81,7 +81,6 @@ function generateCompletionScript(packageManager: string, shell: string) { const name = packageManager; console.log(process.argv); - const isLocalDev = process.argv[1].endsWith('dist/bin/cli.js'); const executable = isLocalDev diff --git a/src/powershell.ts b/src/powershell.ts index 9c7da1e..107195a 100644 --- a/src/powershell.ts +++ b/src/powershell.ts @@ -3,30 +3,30 @@ import { ShellCompDirective } from './t'; // TODO: issue with -- -- completions export function generate( - name: string, - exec: string, - includeDesc = false + name: string, + exec: string, + includeDesc = false ): string { - // Replace '-' and ':' with '_' for variable names - const nameForVar = name.replace(/[-:]/g, '_'); - - // Determine the completion command - // const compCmd = includeDesc ? "complete" : "complete"; - - // Shell completion directives - const ShellCompDirectiveError = ShellCompDirective.ShellCompDirectiveError; - const ShellCompDirectiveNoSpace = - ShellCompDirective.ShellCompDirectiveNoSpace; - const ShellCompDirectiveNoFileComp = - ShellCompDirective.ShellCompDirectiveNoFileComp; - const ShellCompDirectiveFilterFileExt = - ShellCompDirective.ShellCompDirectiveFilterFileExt; - const ShellCompDirectiveFilterDirs = - ShellCompDirective.ShellCompDirectiveFilterDirs; - const ShellCompDirectiveKeepOrder = - ShellCompDirective.ShellCompDirectiveKeepOrder; - - return `# powershell completion for ${name} -*- shell-script -*- + // Replace '-' and ':' with '_' for variable names + const nameForVar = name.replace(/[-:]/g, '_'); + + // Determine the completion command + // const compCmd = includeDesc ? "complete" : "complete"; + + // Shell completion directives + const ShellCompDirectiveError = ShellCompDirective.ShellCompDirectiveError; + const ShellCompDirectiveNoSpace = + ShellCompDirective.ShellCompDirectiveNoSpace; + const ShellCompDirectiveNoFileComp = + ShellCompDirective.ShellCompDirectiveNoFileComp; + const ShellCompDirectiveFilterFileExt = + ShellCompDirective.ShellCompDirectiveFilterFileExt; + const ShellCompDirectiveFilterDirs = + ShellCompDirective.ShellCompDirectiveFilterDirs; + const ShellCompDirectiveKeepOrder = + ShellCompDirective.ShellCompDirectiveKeepOrder; + + return `# powershell completion for ${name} -*- shell-script -*- [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 function __${name}_debug { From 47f0397b50abc2f8776a7318ae70ccd5fb0960db Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Sat, 6 Dec 2025 17:18:54 +0330 Subject: [PATCH 17/19] update --- bin/cli.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/bin/cli.ts b/bin/cli.ts index 135c055..dba8859 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -28,15 +28,16 @@ async function main() { } const dashIndex = process.argv.indexOf('--'); - // When PowerShell shims drop the literal '--', fall back to treating - // everything after "complete" as the completion payload. + // PowerShell's argument parsing can normalize or drop a `--` + // our " complete -- " POSIX-style contract doesn't work the same way. + // so we need to handle the PowerShell case separately. + // gh issue discussion: https://github.com/bombshell-dev/tab/issues/82 + const completionArgs = - // POSIX or already-present separator dashIndex !== -1 && (!isPowerShell || dashIndex < process.argv.length - 1) ? process.argv.slice(dashIndex + 1) : isPowerShell - ? // PowerShell shims may drop the first '--' and leave only a trailing one - args.slice(2) + ? args.slice(2) : null; if (!completionArgs) { From 9928dfb27fae1cf2e06a0d08eab10eeb23e59bdc Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Sat, 6 Dec 2025 17:21:08 +0330 Subject: [PATCH 18/19] pwsh.ts --- bin/cli.ts | 2 +- src/powershell.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/cli.ts b/bin/cli.ts index dba8859..f3f3a6b 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -73,7 +73,7 @@ async function main() { process.exit(0); } - console.error('Usages: tab '); + console.error('Usage: tab '); console.error(` tab complete -- `); process.exit(1); } diff --git a/src/powershell.ts b/src/powershell.ts index 107195a..a2337c3 100644 --- a/src/powershell.ts +++ b/src/powershell.ts @@ -75,7 +75,7 @@ export function generate( # Split the command at the first space to separate the program and arguments. $Program, $Arguments = $Command.Split(" ", 2) - $RequestComp = "& ${exec} complete '--' $Arguments" + $RequestComp = "& ${exec} complete -- $Arguments" __${name}_debug "RequestComp: $RequestComp" # we cannot use $WordToComplete because it From 05792c9f7bbc8bbfab73c358df0c7c212fb4cca5 Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Sat, 6 Dec 2025 17:28:54 +0330 Subject: [PATCH 19/19] rm log --- bin/cli.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/bin/cli.ts b/bin/cli.ts index f3f3a6b..cf5dfc1 100644 --- a/bin/cli.ts +++ b/bin/cli.ts @@ -80,7 +80,6 @@ async function main() { function generateCompletionScript(packageManager: string, shell: string) { const name = packageManager; - console.log(process.argv); const isLocalDev = process.argv[1].endsWith('dist/bin/cli.js');