MCPcopy Index your code
hub / github.com/codeaashu/claude-code / setupShellCompletion

Function setupShellCompletion

src/utils/completionCache.ts:75–134  ·  view source on GitHub ↗
(theme: ThemeName)

Source from the content-addressed store, hash-verified

73 * shell's rc file. Returns a user-facing status message.
74 */
75export async function setupShellCompletion(theme: ThemeName): Promise<string> {
76 const shell = detectShell()
77 if (!shell) {
78 return ''
79 }
80
81 // Ensure the cache directory exists
82 try {
83 await mkdir(dirname(shell.cacheFile), { recursive: true })
84 } catch (e: unknown) {
85 logError(e)
86 return `${EOL}${color('warning', theme)(`Could not write ${shell.name} completion cache`)}${EOL}${chalk.dim(`Run manually: claude completion ${shell.shellFlag} > ${shell.cacheFile}`)}${EOL}`
87 }
88
89 // Generate the completion script by writing directly to the cache file.
90 // Using --output avoids piping through stdout where process.exit() can
91 // truncate output before the pipe buffer drains.
92 const claudeBin = process.argv[1] || 'claude'
93 const result = await execFileNoThrow(claudeBin, [
94 'completion',
95 shell.shellFlag,
96 '--output',
97 shell.cacheFile,
98 ])
99 if (result.code !== 0) {
100 return `${EOL}${color('warning', theme)(`Could not generate ${shell.name} shell completions`)}${EOL}${chalk.dim(`Run manually: claude completion ${shell.shellFlag} > ${shell.cacheFile}`)}${EOL}`
101 }
102
103 // Check if rc file already sources completions
104 let existing = ''
105 try {
106 existing = await readFile(shell.rcFile, { encoding: 'utf-8' })
107 if (
108 existing.includes('claude completion') ||
109 existing.includes(shell.cacheFile)
110 ) {
111 return `${EOL}${color('success', theme)(`Shell completions updated for ${shell.name}`)}${EOL}${chalk.dim(`See ${formatPathLink(shell.rcFile)}`)}${EOL}`
112 }
113 } catch (e: unknown) {
114 if (!isENOENT(e)) {
115 logError(e)
116 return `${EOL}${color('warning', theme)(`Could not install ${shell.name} shell completions`)}${EOL}${chalk.dim(`Add this to ${formatPathLink(shell.rcFile)}:`)}${EOL}${chalk.dim(shell.completionLine)}${EOL}`
117 }
118 }
119
120 // Append source line to rc file
121 try {
122 const configDir = dirname(shell.rcFile)
123 await mkdir(configDir, { recursive: true })
124
125 const separator = existing && !existing.endsWith('\n') ? '\n' : ''
126 const content = `${existing}${separator}\n# Claude Code shell completions\n${shell.completionLine}\n`
127 await writeFile(shell.rcFile, content, { encoding: 'utf-8' })
128
129 return `${EOL}${color('success', theme)(`Installed ${shell.name} shell completions`)}${EOL}${chalk.dim(`Added to ${formatPathLink(shell.rcFile)}`)}${EOL}${chalk.dim(`Run: source ${shell.rcFile}`)}${EOL}`
130 } catch (error) {
131 logError(error)
132 return `${EOL}${color('warning', theme)(`Could not install ${shell.name} shell completions`)}${EOL}${chalk.dim(`Add this to ${formatPathLink(shell.rcFile)}:`)}${EOL}${chalk.dim(shell.completionLine)}${EOL}`

Callers 1

setupTerminalFunction · 0.85

Calls 8

detectShellFunction · 0.85
mkdirFunction · 0.85
colorFunction · 0.85
execFileNoThrowFunction · 0.85
readFileFunction · 0.85
isENOENTFunction · 0.85
logErrorFunction · 0.70
formatPathLinkFunction · 0.70

Tested by

no test coverage detected