@shell-shock/plugin-completions 0.2.22 → 0.2.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,15 +1,15 @@
1
- import { exec } from "../helpers/complete-command.mjs";
1
+ import { EXEC_COMMAND } from "../helpers/complete-command.mjs";
2
2
  import { CompletionDirective } from "../helpers/completion-directive-constants.mjs";
3
3
  import { createComponent, memo } from "@alloy-js/core/jsx-runtime";
4
4
  import { getAppBin, getAppTitle } from "@shell-shock/core/plugin-utils";
5
- import { joinPaths } from "@stryke/path";
6
- import { code } from "@alloy-js/core";
5
+ import { code, computed } from "@alloy-js/core";
7
6
  import { FunctionDeclaration, IfStatement, InterfaceDeclaration, VarDeclaration } from "@alloy-js/typescript";
8
7
  import { ReflectionKind } from "@powerlines/deepkit/vendor/type";
9
8
  import { Spacing } from "@powerlines/plugin-alloy/core";
10
9
  import { usePowerlines } from "@powerlines/plugin-alloy/core/contexts/context";
11
10
  import { InterfaceMember, TypescriptFile } from "@powerlines/plugin-alloy/typescript";
12
11
  import { TSDoc, TSDocDefaultValue, TSDocRemarks } from "@powerlines/plugin-alloy/typescript/components/tsdoc";
12
+ import { joinPaths } from "@stryke/path";
13
13
  import { snakeCase } from "@stryke/string-format";
14
14
 
15
15
  //#region src/components/zsh-command.tsx
@@ -18,12 +18,15 @@ import { snakeCase } from "@stryke/string-format";
18
18
  */
19
19
  function ZshCompletionsCommand() {
20
20
  const context = usePowerlines();
21
+ const bin = computed(() => getAppBin(context));
22
+ const name = computed(() => snakeCase(bin.value));
21
23
  return createComponent(TypescriptFile, {
22
24
  get path() {
23
25
  return joinPaths(context.entryPath, "completions", "zsh", "command.ts");
24
26
  },
25
27
  imports: {
26
- "node:os": ["os"],
28
+ "node:os": "os",
29
+ "node:path": ["join"],
27
30
  "node:fs/promises": ["readFile", "writeFile"]
28
31
  },
29
32
  builtinImports: { "shell-shock:console": [
@@ -49,7 +52,7 @@ function ZshCompletionsCommand() {
49
52
  return ReflectionKind.string;
50
53
  },
51
54
  get defaultValue() {
52
- return `${getAppBin(context)}-completions.zsh`;
55
+ return `${bin.value}-completions.zsh`;
53
56
  }
54
57
  })];
55
58
  }
@@ -97,19 +100,19 @@ function ZshCompletionsCommand() {
97
100
  name: "completions",
98
101
  type: "string",
99
102
  get initializer() {
100
- return code`#compdef ${getAppBin(context)}
101
- compdef _${snakeCase(getAppBin(context))} ${getAppBin(context)}
103
+ return code` \`#compdef ${bin.value}
104
+ compdef _${name.value} ${bin.value}
102
105
 
103
106
  # zsh completion for ${getAppTitle(context)} -*- shell-script -*-
104
107
 
105
- __${snakeCase(getAppBin(context))}_debug() {
108
+ __${name.value}_debug() {
106
109
  local file="$BASH_COMP_DEBUG_FILE"
107
- if [[ -n \${file} ]]; then
108
- echo "$*" >> "\${file}"
110
+ if [[ -n \\\${file} ]]; then
111
+ echo "$*" >> "\\\${file}"
109
112
  fi
110
113
  }
111
114
 
112
- _${getAppBin(context)}() {
115
+ _${name.value}() {
113
116
  local shellCompDirectiveError=${CompletionDirective.CompletionDirectiveError}
114
117
  local shellCompDirectiveNoSpace=${CompletionDirective.CompletionDirectiveNoSpace}
115
118
  local shellCompDirectiveNoFileComp=${CompletionDirective.CompletionDirectiveNoFileComp}
@@ -120,88 +123,88 @@ _${getAppBin(context)}() {
120
123
  local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace keepOrder
121
124
  local -a completions
122
125
 
123
- __${snakeCase(getAppBin(context))}_debug "\\n========= starting completion logic =========="
124
- __${snakeCase(getAppBin(context))}_debug "CURRENT: \${CURRENT}, words[*]: \${words[*]}"
126
+ __${name.value}_debug "\\n========= starting completion logic =========="
127
+ __${name.value}_debug "CURRENT: \\\${CURRENT}, words[*]: \\\${words[*]}"
125
128
 
126
129
  # The user could have moved the cursor backwards on the command-line.
127
130
  # We need to trigger completion from the $CURRENT location, so we need
128
131
  # to truncate the command-line ($words) up to the $CURRENT location.
129
132
  # (We cannot use $CURSOR as its value does not work when a command is an alias.)
130
- words=( "\${=words[1,CURRENT]}" )
131
- __${snakeCase(getAppBin(context))}_debug "Truncated words[*]: \${words[*]},"
133
+ words=( "\\\${=words[1,CURRENT]}" )
134
+ __${name.value}_debug "Truncated words[*]: \\\${words[*]},"
132
135
 
133
- lastParam=\${words[-1]}
134
- lastChar=\${lastParam[-1]}
135
- __${snakeCase(getAppBin(context))}_debug "lastParam: \${lastParam}, lastChar: \${lastChar}"
136
- # For zsh, when completing a flag with an = (e.g., ${getAppBin(context)} -n=<TAB>)
136
+ lastParam=\\\${words[-1]}
137
+ lastChar=\\\${lastParam[-1]}
138
+ __${name.value}_debug "lastParam: \\\${lastParam}, lastChar: \\\${lastChar}"
139
+ # For zsh, when completing a flag with an = (e.g., ${bin.value} -n=<TAB>)
137
140
  # completions must be prefixed with the flag
138
141
  setopt local_options BASH_REMATCH
139
- if [[ "\${lastParam}" =~ '-.*=' ]]; then
142
+ if [[ "\\\${lastParam}" =~ '-.*=' ]]; then
140
143
  # We are dealing with a flag with an =
141
- flagPrefix="-P \${BASH_REMATCH}"
144
+ flagPrefix="-P \\\${BASH_REMATCH}"
142
145
  fi
143
146
 
144
147
  # Prepare the command to obtain completions, ensuring arguments are quoted for eval
145
- local -a args_to_quote=("\${(@)words[2,-1]}")
146
- if [ "\${lastChar}" = "" ]; then
148
+ local -a args_to_quote=("\\\${(@)words[2,-1]}")
149
+ if [ "\\\${lastChar}" = "" ]; then
147
150
  # If the last parameter is complete (there is a space following it)
148
151
  # We add an extra empty parameter so we can indicate this to the go completion code.
149
- __${snakeCase(getAppBin(context))}_debug "Adding extra empty parameter"
152
+ __${name.value}_debug "Adding extra empty parameter"
150
153
  args_to_quote+=("")
151
154
  fi
152
155
 
153
156
  # Use Zsh's (q) flag to quote each argument safely for eval
154
- local quoted_args=("\${(@q)args_to_quote}")
157
+ local quoted_args=("\\\${(@q)args_to_quote}")
155
158
 
156
159
  # Join the main command and the quoted arguments into a single string for eval
157
- requestComp="${exec} complete -- \${quoted_args[*]}"
160
+ requestComp="${EXEC_COMMAND} complete -- \\\${quoted_args[*]}"
158
161
 
159
- __${snakeCase(getAppBin(context))}_debug "About to call: eval \${requestComp}"
162
+ __${name.value}_debug "About to call: eval \\\${requestComp}"
160
163
 
161
164
  # Use eval to handle any environment variables and such
162
- out=$(eval \${requestComp} 2>/dev/null)
163
- __${snakeCase(getAppBin(context))}_debug "completion output: \${out}"
165
+ out=$(eval \\\${requestComp} 2>/dev/null)
166
+ __${name.value}_debug "completion output: \\\${out}"
164
167
 
165
168
  # Extract the directive integer following a : from the last line
166
169
  local lastLine
167
170
  while IFS='\n' read -r line; do
168
- lastLine=\${line}
169
- done < <(printf "%s\n" "\${out[@]}")
170
- __${snakeCase(getAppBin(context))}_debug "last line: \${lastLine}"
171
+ lastLine=\\\${line}
172
+ done < <(printf "%s\n" "\\\${out[@]}")
173
+ __${name.value}_debug "last line: \\\${lastLine}"
171
174
 
172
- if [ "\${lastLine[1]}" = : ]; then
173
- directive=\${lastLine[2,-1]}
175
+ if [ "\\\${lastLine[1]}" = : ]; then
176
+ directive=\\\${lastLine[2,-1]}
174
177
  # Remove the directive including the : and the newline
175
178
  local suffix
176
- (( suffix=\${#lastLine}+2))
177
- out=\${out[1,-$suffix]}
179
+ (( suffix=\\\${#lastLine}+2))
180
+ out=\\\${out[1,-$suffix]}
178
181
  else
179
182
  # There is no directive specified. Leave $out as is.
180
- __${snakeCase(getAppBin(context))}_debug "No directive found. Setting to default"
183
+ __${name.value}_debug "No directive found. Setting to default"
181
184
  directive=0
182
185
  fi
183
186
 
184
- __${snakeCase(getAppBin(context))}_debug "directive: \${directive}"
185
- __${snakeCase(getAppBin(context))}_debug "completions: \${out}"
186
- __${snakeCase(getAppBin(context))}_debug "flagPrefix: \${flagPrefix}"
187
+ __${name.value}_debug "directive: \\\${directive}"
188
+ __${name.value}_debug "completions: \\\${out}"
189
+ __${name.value}_debug "flagPrefix: \\\${flagPrefix}"
187
190
 
188
191
  if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then
189
- __${snakeCase(getAppBin(context))}_debug "Completion received error. Ignoring completions."
192
+ __${name.value}_debug "Completion received error. Ignoring completions."
190
193
  return
191
194
  fi
192
195
 
193
196
  local activeHelpMarker="%"
194
- local endIndex=\${#activeHelpMarker}
195
- local startIndex=$((\${#activeHelpMarker}+1))
197
+ local endIndex=\\\${#activeHelpMarker}
198
+ local startIndex=$((\\\${#activeHelpMarker}+1))
196
199
  local hasActiveHelp=0
197
200
  while IFS='\n' read -r comp; do
198
201
  # Check if this is an activeHelp statement (i.e., prefixed with $activeHelpMarker)
199
- if [ "\${comp[1,$endIndex]}" = "$activeHelpMarker" ];then
200
- __${snakeCase(getAppBin(context))}_debug "ActiveHelp found: $comp"
201
- comp="\${comp[$startIndex,-1]}"
202
+ if [ "\\\${comp[1,$endIndex]}" = "$activeHelpMarker" ];then
203
+ __${name.value}_debug "ActiveHelp found: $comp"
204
+ comp="\\\${comp[$startIndex,-1]}"
202
205
  if [ -n "$comp" ]; then
203
- compadd -x "\${comp}"
204
- __${snakeCase(getAppBin(context))}_debug "ActiveHelp will need delimiter"
206
+ compadd -x "\\\${comp}"
207
+ __${name.value}_debug "ActiveHelp will need delimiter"
205
208
  hasActiveHelp=1
206
209
  fi
207
210
  continue
@@ -212,35 +215,35 @@ _${getAppBin(context)}() {
212
215
  # The description is preceded by a TAB character.
213
216
  # For zsh's _describe, we need to use a : instead of a TAB.
214
217
  # We first need to escape any : as part of the completion itself.
215
- comp=\${comp//:/\\:}
218
+ comp=\\\${comp//:/\\:}
216
219
 
217
220
  local tab="$(printf '\\t')"
218
- comp=\${comp//$tab/:}
221
+ comp=\\\${comp//$tab/:}
219
222
 
220
- __${snakeCase(getAppBin(context))}_debug "Adding completion: \${comp}"
221
- completions+=\${comp}
223
+ __${name.value}_debug "Adding completion: \\\${comp}"
224
+ completions+=\\\${comp}
222
225
  lastComp=$comp
223
226
  fi
224
- done < <(printf "%s\n" "\${out[@]}")
227
+ done < <(printf "%s\n" "\\\${out[@]}")
225
228
 
226
229
  # Add a delimiter after the activeHelp statements, but only if:
227
230
  # - there are completions following the activeHelp statements, or
228
231
  # - file completion will be performed (so there will be choices after the activeHelp)
229
232
  if [ $hasActiveHelp -eq 1 ]; then
230
- if [ \${#completions} -ne 0 ] || [ $((directive & shellCompDirectiveNoFileComp)) -eq 0 ]; then
231
- __${snakeCase(getAppBin(context))}_debug "Adding activeHelp delimiter"
233
+ if [ \\\${#completions} -ne 0 ] || [ $((directive & shellCompDirectiveNoFileComp)) -eq 0 ]; then
234
+ __${name.value}_debug "Adding activeHelp delimiter"
232
235
  compadd -x "--"
233
236
  hasActiveHelp=0
234
237
  fi
235
238
  fi
236
239
 
237
240
  if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then
238
- __${snakeCase(getAppBin(context))}_debug "Activating nospace."
241
+ __${name.value}_debug "Activating nospace."
239
242
  noSpace="-S ''"
240
243
  fi
241
244
 
242
245
  if [ $((directive & shellCompDirectiveKeepOrder)) -ne 0 ]; then
243
- __${snakeCase(getAppBin(context))}_debug "Activating keep order."
246
+ __${name.value}_debug "Activating keep order."
244
247
  keepOrder="-V"
245
248
  fi
246
249
 
@@ -248,47 +251,47 @@ _${getAppBin(context)}() {
248
251
  # File extension filtering
249
252
  local filteringCmd
250
253
  filteringCmd='_files'
251
- for filter in \${completions[@]}; do
252
- if [ \${filter[1]} != '*' ]; then
254
+ for filter in \\\${completions[@]}; do
255
+ if [ \\\${filter[1]} != '*' ]; then
253
256
  # zsh requires a glob pattern to do file filtering
254
257
  filter="\\*.$filter"
255
258
  fi
256
259
  filteringCmd+=" -g $filter"
257
260
  done
258
- filteringCmd+=" \${flagPrefix}"
261
+ filteringCmd+=" \\\${flagPrefix}"
259
262
 
260
- __${snakeCase(getAppBin(context))}_debug "File filtering command: $filteringCmd"
263
+ __${name.value}_debug "File filtering command: $filteringCmd"
261
264
  _arguments '*:filename:'"$filteringCmd"
262
265
  elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then
263
266
  # File completion for directories only
264
267
  local subdir
265
- subdir="\${completions[1]}"
268
+ subdir="\\\${completions[1]}"
266
269
  if [ -n "$subdir" ]; then
267
- __${snakeCase(getAppBin(context))}_debug "Listing directories in $subdir"
268
- pushd "\${subdir}" >/dev/null 2>&1
270
+ __${name.value}_debug "Listing directories in $subdir"
271
+ pushd "\\\${subdir}" >/dev/null 2>&1
269
272
  else
270
- __${snakeCase(getAppBin(context))}_debug "Listing directories in ."
273
+ __${name.value}_debug "Listing directories in ."
271
274
  fi
272
275
 
273
276
  local result
274
- _arguments '*:dirname:_files -/'" \${flagPrefix}"
277
+ _arguments '*:dirname:_files -/'" \\\${flagPrefix}"
275
278
  result=$?
276
279
  if [ -n "$subdir" ]; then
277
280
  popd >/dev/null 2>&1
278
281
  fi
279
282
  return $result
280
283
  else
281
- __${snakeCase(getAppBin(context))}_debug "Calling _describe"
282
- if eval _describe $keepOrder "completions" completions -Q \${flagPrefix} \${noSpace}; then
283
- __${snakeCase(getAppBin(context))}_debug "_describe found some completions"
284
+ __${name.value}_debug "Calling _describe"
285
+ if eval _describe $keepOrder "completions" completions -Q \\\${flagPrefix} \\\${noSpace}; then
286
+ __${name.value}_debug "_describe found some completions"
284
287
 
285
288
  # Return the success of having called _describe
286
289
  return 0
287
290
  else
288
- __${snakeCase(getAppBin(context))}_debug "_describe did not find completions."
289
- __${snakeCase(getAppBin(context))}_debug "Checking if we should do file completion."
291
+ __${name.value}_debug "_describe did not find completions."
292
+ __${name.value}_debug "Checking if we should do file completion."
290
293
  if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then
291
- __${snakeCase(getAppBin(context))}_debug "deactivating file completion"
294
+ __${name.value}_debug "deactivating file completion"
292
295
 
293
296
  # Return 0 to indicate completion is finished and prevent zsh from
294
297
  # trying other completion algorithms (which could cause hanging).
@@ -296,21 +299,21 @@ _${getAppBin(context)}() {
296
299
  return 0
297
300
  else
298
301
  # Perform file completion
299
- __${snakeCase(getAppBin(context))}_debug "Activating file completion"
302
+ __${name.value}_debug "Activating file completion"
300
303
 
301
304
  # We must return the result of this command, so it must be the
302
305
  # last command, or else we must store its result to return it.
303
- _arguments '*:filename:_files'" \${flagPrefix}"
306
+ _arguments '*:filename:_files'" \\\${flagPrefix}"
304
307
  fi
305
308
  fi
306
309
  fi
307
310
  }
308
311
 
309
312
  # don't run the completion function when being sourced or eval-ed
310
- if [ "\${funcstack[1]}" = "_${snakeCase(getAppBin(context))}" ]; then
311
- _${snakeCase(getAppBin(context))}
313
+ if [ "\\\${funcstack[1]}" = "_${name.value}" ]; then
314
+ _${name.value}
312
315
  fi
313
- \`);`;
316
+ \`; `;
314
317
  }
315
318
  }),
316
319
  createComponent(Spacing, {}),
@@ -340,7 +343,7 @@ fi
340
343
  memo(() => code`try {
341
344
  configFileContent = await readFile(configFilePath, "utf8");
342
345
  } catch (error) {
343
- if (error.code === "ENOENT") {
346
+ if (Error.isError(error) && error.code === "ENOENT") {
344
347
  // If the file doesn't exist, we can create it later when writing the completion script.
345
348
  warn(\`Configuration file \${colors.bold(configFilePath)} does not exist. It will be created when the completion script is written.\`);
346
349
  } else {
@@ -358,7 +361,7 @@ fi
358
361
  createComponent(IfStatement, {
359
362
  condition: code`options.script`,
360
363
  get children() {
361
- return code`const outputPath = options.script === true ? "${getAppBin(context)}-completions.zsh" : options.script;
364
+ return code`const outputPath = options.script === true ? "${name.value}-completions.zsh" : options.script;
362
365
  await writeFile(outputPath, stripAnsi(completions));
363
366
 
364
367
  success(\`${getAppTitle(context)} Zsh completion script has been generated at \${colors.bold(outputPath)}.\`);`;
@@ -1 +1 @@
1
- {"version":3,"file":"zsh-command.mjs","names":[],"sources":["../../src/components/zsh-command.tsx"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Shell Shock\n\n This code was released as part of the Shell Shock project. Shell Shock\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/shell-shock.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/shell-shock\n Documentation: https://docs.stormsoftware.com/projects/shell-shock\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { code } from \"@alloy-js/core\";\nimport {\n FunctionDeclaration,\n IfStatement,\n InterfaceDeclaration,\n VarDeclaration\n} from \"@alloy-js/typescript\";\nimport { ReflectionKind } from \"@powerlines/deepkit/vendor/type\";\nimport { Spacing } from \"@powerlines/plugin-alloy/core\";\nimport { usePowerlines } from \"@powerlines/plugin-alloy/core/contexts/context\";\nimport {\n InterfaceMember,\n TypescriptFile\n} from \"@powerlines/plugin-alloy/typescript\";\nimport {\n TSDoc,\n TSDocDefaultValue,\n TSDocRemarks\n} from \"@powerlines/plugin-alloy/typescript/components/tsdoc\";\nimport { getAppBin, getAppTitle } from \"@shell-shock/core/plugin-utils\";\nimport { joinPaths } from \"@stryke/path\";\nimport { snakeCase } from \"@stryke/string-format\";\nimport { exec } from \"../helpers/complete-command\";\nimport { CompletionDirective } from \"../helpers/completion-directive-constants\";\nimport type { CompletionsPluginContext } from \"../types/plugin\";\n\n/**\n * The Zsh Completions commands' handler wrapper for the Shell Shock project.\n */\nexport function ZshCompletionsCommand() {\n const context = usePowerlines<CompletionsPluginContext>();\n\n return (\n <TypescriptFile\n path={joinPaths(context.entryPath, \"completions\", \"zsh\", \"command.ts\")}\n imports={{\n \"node:os\": [\"os\"],\n \"node:fs/promises\": [\"readFile\", \"writeFile\"]\n }}\n builtinImports={{\n \"shell-shock:console\": [\n \"colors\",\n \"writeLine\",\n \"success\",\n \"warn\",\n \"stripAnsi\"\n ]\n }}>\n <TSDoc heading=\"Options for the Zsh completions command.\" />\n <InterfaceDeclaration export name=\"ZshCompletionsOptions\">\n <TSDoc heading=\"The path to write the completion script to.\">\n <TSDocRemarks>{`If no extension is provided, the \\`.zsh\\` extension will be used.`}</TSDocRemarks>\n <TSDocDefaultValue\n type={ReflectionKind.string}\n defaultValue={`${getAppBin(context)}-completions.zsh`}\n />\n </TSDoc>\n <InterfaceMember name=\"script\" optional type=\"string | true\" />\n <Spacing />\n <TSDoc heading=\"The Zsh configuration file to append the completion script to.\">\n <TSDocRemarks>{`The generated completion script will be appended to the specified configuration file. Possible values for the Zsh configuration file include: \\\\n- \\`~/.zshrc\\` \\\\n- \\`~/.zprofile\\``}</TSDocRemarks>\n <TSDocDefaultValue\n type={ReflectionKind.string}\n defaultValue=\"~/.zshrc\"\n />\n </TSDoc>\n <InterfaceMember name=\"config\" optional type=\"string | true\" />\n </InterfaceDeclaration>\n <Spacing />\n <TSDoc heading=\"Handler logic for the \\`completions zsh\\` command.\"></TSDoc>\n <FunctionDeclaration\n export\n default\n async\n name=\"handler\"\n parameters={[{ name: \"options\", type: \"ZshCompletionsOptions\" }]}>\n <VarDeclaration\n const\n name=\"completions\"\n type=\"string\"\n initializer={code`#compdef ${getAppBin(context)}\ncompdef _${snakeCase(getAppBin(context))} ${getAppBin(context)}\n\n# zsh completion for ${getAppTitle(context)} -*- shell-script -*-\n\n__${snakeCase(getAppBin(context))}_debug() {\n local file=\"$BASH_COMP_DEBUG_FILE\"\n if [[ -n \\${file} ]]; then\n echo \"$*\" >> \"\\${file}\"\n fi\n}\n\n_${getAppBin(context)}() {\n local shellCompDirectiveError=${\n CompletionDirective.CompletionDirectiveError\n }\n local shellCompDirectiveNoSpace=${\n CompletionDirective.CompletionDirectiveNoSpace\n }\n local shellCompDirectiveNoFileComp=${\n CompletionDirective.CompletionDirectiveNoFileComp\n }\n local shellCompDirectiveFilterFileExt=${\n CompletionDirective.CompletionDirectiveFilterFileExt\n }\n local shellCompDirectiveFilterDirs=${\n CompletionDirective.CompletionDirectiveFilterDirs\n }\n local shellCompDirectiveKeepOrder=${\n CompletionDirective.CompletionDirectiveKeepOrder\n }\n\n local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace keepOrder\n local -a completions\n\n __${snakeCase(getAppBin(context))}_debug \"\\\\n========= starting completion logic ==========\"\n __${snakeCase(getAppBin(context))}_debug \"CURRENT: \\${CURRENT}, words[*]: \\${words[*]}\"\n\n # The user could have moved the cursor backwards on the command-line.\n # We need to trigger completion from the $CURRENT location, so we need\n # to truncate the command-line ($words) up to the $CURRENT location.\n # (We cannot use $CURSOR as its value does not work when a command is an alias.)\n words=( \"\\${=words[1,CURRENT]}\" )\n __${snakeCase(getAppBin(context))}_debug \"Truncated words[*]: \\${words[*]},\"\n\n lastParam=\\${words[-1]}\n lastChar=\\${lastParam[-1]}\n __${snakeCase(getAppBin(context))}_debug \"lastParam: \\${lastParam}, lastChar: \\${lastChar}\"\n # For zsh, when completing a flag with an = (e.g., ${getAppBin(\n context\n )} -n=<TAB>)\n # completions must be prefixed with the flag\n setopt local_options BASH_REMATCH\n if [[ \"\\${lastParam}\" =~ '-.*=' ]]; then\n # We are dealing with a flag with an =\n flagPrefix=\"-P \\${BASH_REMATCH}\"\n fi\n\n # Prepare the command to obtain completions, ensuring arguments are quoted for eval\n local -a args_to_quote=(\"\\${(@)words[2,-1]}\")\n if [ \"\\${lastChar}\" = \"\" ]; then\n # If the last parameter is complete (there is a space following it)\n # We add an extra empty parameter so we can indicate this to the go completion code.\n __${snakeCase(getAppBin(context))}_debug \"Adding extra empty parameter\"\n args_to_quote+=(\"\")\n fi\n\n # Use Zsh's (q) flag to quote each argument safely for eval\n local quoted_args=(\"\\${(@q)args_to_quote}\")\n\n # Join the main command and the quoted arguments into a single string for eval\n requestComp=\"${exec} complete -- \\${quoted_args[*]}\"\n\n __${snakeCase(getAppBin(context))}_debug \"About to call: eval \\${requestComp}\"\n\n # Use eval to handle any environment variables and such\n out=$(eval \\${requestComp} 2>/dev/null)\n __${snakeCase(getAppBin(context))}_debug \"completion output: \\${out}\"\n\n # Extract the directive integer following a : from the last line\n local lastLine\n while IFS='\\n' read -r line; do\n lastLine=\\${line}\n done < <(printf \"%s\\n\" \"\\${out[@]}\")\n __${snakeCase(getAppBin(context))}_debug \"last line: \\${lastLine}\"\n\n if [ \"\\${lastLine[1]}\" = : ]; then\n directive=\\${lastLine[2,-1]}\n # Remove the directive including the : and the newline\n local suffix\n (( suffix=\\${#lastLine}+2))\n out=\\${out[1,-$suffix]}\n else\n # There is no directive specified. Leave $out as is.\n __${snakeCase(getAppBin(context))}_debug \"No directive found. Setting to default\"\n directive=0\n fi\n\n __${snakeCase(getAppBin(context))}_debug \"directive: \\${directive}\"\n __${snakeCase(getAppBin(context))}_debug \"completions: \\${out}\"\n __${snakeCase(getAppBin(context))}_debug \"flagPrefix: \\${flagPrefix}\"\n\n if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then\n __${snakeCase(getAppBin(context))}_debug \"Completion received error. Ignoring completions.\"\n return\n fi\n\n local activeHelpMarker=\"%\"\n local endIndex=\\${#activeHelpMarker}\n local startIndex=$((\\${#activeHelpMarker}+1))\n local hasActiveHelp=0\n while IFS='\\n' read -r comp; do\n # Check if this is an activeHelp statement (i.e., prefixed with $activeHelpMarker)\n if [ \"\\${comp[1,$endIndex]}\" = \"$activeHelpMarker\" ];then\n __${snakeCase(getAppBin(context))}_debug \"ActiveHelp found: $comp\"\n comp=\"\\${comp[$startIndex,-1]}\"\n if [ -n \"$comp\" ]; then\n compadd -x \"\\${comp}\"\n __${snakeCase(getAppBin(context))}_debug \"ActiveHelp will need delimiter\"\n hasActiveHelp=1\n fi\n continue\n fi\n\n if [ -n \"$comp\" ]; then\n # If requested, completions are returned with a description.\n # The description is preceded by a TAB character.\n # For zsh's _describe, we need to use a : instead of a TAB.\n # We first need to escape any : as part of the completion itself.\n comp=\\${comp//:/\\\\:}\n\n local tab=\"$(printf '\\\\t')\"\n comp=\\${comp//$tab/:}\n\n __${snakeCase(getAppBin(context))}_debug \"Adding completion: \\${comp}\"\n completions+=\\${comp}\n lastComp=$comp\n fi\n done < <(printf \"%s\\n\" \"\\${out[@]}\")\n\n # Add a delimiter after the activeHelp statements, but only if:\n # - there are completions following the activeHelp statements, or\n # - file completion will be performed (so there will be choices after the activeHelp)\n if [ $hasActiveHelp -eq 1 ]; then\n if [ \\${#completions} -ne 0 ] || [ $((directive & shellCompDirectiveNoFileComp)) -eq 0 ]; then\n __${snakeCase(getAppBin(context))}_debug \"Adding activeHelp delimiter\"\n compadd -x \"--\"\n hasActiveHelp=0\n fi\n fi\n\n if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then\n __${snakeCase(getAppBin(context))}_debug \"Activating nospace.\"\n noSpace=\"-S ''\"\n fi\n\n if [ $((directive & shellCompDirectiveKeepOrder)) -ne 0 ]; then\n __${snakeCase(getAppBin(context))}_debug \"Activating keep order.\"\n keepOrder=\"-V\"\n fi\n\n if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then\n # File extension filtering\n local filteringCmd\n filteringCmd='_files'\n for filter in \\${completions[@]}; do\n if [ \\${filter[1]} != '*' ]; then\n # zsh requires a glob pattern to do file filtering\n filter=\"\\\\*.$filter\"\n fi\n filteringCmd+=\" -g $filter\"\n done\n filteringCmd+=\" \\${flagPrefix}\"\n\n __${snakeCase(getAppBin(context))}_debug \"File filtering command: $filteringCmd\"\n _arguments '*:filename:'\"$filteringCmd\"\n elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then\n # File completion for directories only\n local subdir\n subdir=\"\\${completions[1]}\"\n if [ -n \"$subdir\" ]; then\n __${snakeCase(getAppBin(context))}_debug \"Listing directories in $subdir\"\n pushd \"\\${subdir}\" >/dev/null 2>&1\n else\n __${snakeCase(getAppBin(context))}_debug \"Listing directories in .\"\n fi\n\n local result\n _arguments '*:dirname:_files -/'\" \\${flagPrefix}\"\n result=$?\n if [ -n \"$subdir\" ]; then\n popd >/dev/null 2>&1\n fi\n return $result\n else\n __${snakeCase(getAppBin(context))}_debug \"Calling _describe\"\n if eval _describe $keepOrder \"completions\" completions -Q \\${flagPrefix} \\${noSpace}; then\n __${snakeCase(getAppBin(context))}_debug \"_describe found some completions\"\n\n # Return the success of having called _describe\n return 0\n else\n __${snakeCase(getAppBin(context))}_debug \"_describe did not find completions.\"\n __${snakeCase(getAppBin(context))}_debug \"Checking if we should do file completion.\"\n if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then\n __${snakeCase(getAppBin(context))}_debug \"deactivating file completion\"\n\n # Return 0 to indicate completion is finished and prevent zsh from\n # trying other completion algorithms (which could cause hanging).\n # We use NoFileComp directive to explicitly disable file completion.\n return 0\n else\n # Perform file completion\n __${snakeCase(getAppBin(context))}_debug \"Activating file completion\"\n\n # We must return the result of this command, so it must be the\n # last command, or else we must store its result to return it.\n _arguments '*:filename:_files'\" \\${flagPrefix}\"\n fi\n fi\n fi\n}\n\n# don't run the completion function when being sourced or eval-ed\nif [ \"\\${funcstack[1]}\" = \"_${snakeCase(getAppBin(context))}\" ]; then\n _${snakeCase(getAppBin(context))}\nfi\n\\`);`}\n />\n <Spacing />\n <IfStatement condition={code`options.config`}>\n <VarDeclaration\n let\n name=\"configFilePath\"\n type=\"string\"\n initializer={code`options.config === true ? \"~/.zshrc\" : options.config`}\n />\n <Spacing />\n <IfStatement condition={code`configFilePath.startsWith(\"~\")`}>\n {code`configFilePath = join(os.homedir(), configFilePath.replace(\"~\", \"\")); `}\n </IfStatement>\n <Spacing />\n <VarDeclaration\n let\n name=\"configFileContent\"\n type=\"string\"\n initializer={code`\"\";`}\n />\n <Spacing />\n {code`try {\n configFileContent = await readFile(configFilePath, \"utf8\");\n } catch (error) {\n if (error.code === \"ENOENT\") {\n // If the file doesn't exist, we can create it later when writing the completion script.\n warn(\\`Configuration file \\${colors.bold(configFilePath)} does not exist. It will be created when the completion script is written.\\`);\n } else {\n return { error };\n }\n }\n\n await writeFile(configFilePath, \\`\\${configFileContent}\\\\n\\\\n\\${stripAnsi(completions)}\\`);\n\n success(\\`${getAppTitle(context)} Zsh completion script has been generated and appended to \\${colors.bold(configFilePath)}. Please restart your terminal or run \\`source \\${configFilePath}\\` to apply the changes.\\`); `}\n </IfStatement>\n <Spacing />\n <IfStatement condition={code`options.script`}>\n {code`const outputPath = options.script === true ? \"${getAppBin(context)}-completions.zsh\" : options.script;\n await writeFile(outputPath, stripAnsi(completions));\n\n success(\\`${getAppTitle(context)} Zsh completion script has been generated at \\${colors.bold(outputPath)}.\\`);`}\n </IfStatement>\n <Spacing />\n <IfStatement condition={code`!options.config && !options.script`}>\n {code`writeLine(\" ------------------------------------------------- \");\n writeLine(completions);\n writeLine(\" ------------------------------------------------- \");`}\n </IfStatement>\n </FunctionDeclaration>\n </TypescriptFile>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"zsh-command.mjs","names":[],"sources":["../../src/components/zsh-command.tsx"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Shell Shock\n\n This code was released as part of the Shell Shock project. Shell Shock\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/shell-shock.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/shell-shock\n Documentation: https://docs.stormsoftware.com/projects/shell-shock\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { code, computed } from \"@alloy-js/core\";\nimport {\n FunctionDeclaration,\n IfStatement,\n InterfaceDeclaration,\n VarDeclaration\n} from \"@alloy-js/typescript\";\nimport { ReflectionKind } from \"@powerlines/deepkit/vendor/type\";\nimport { Spacing } from \"@powerlines/plugin-alloy/core\";\nimport { usePowerlines } from \"@powerlines/plugin-alloy/core/contexts/context\";\nimport {\n InterfaceMember,\n TypescriptFile\n} from \"@powerlines/plugin-alloy/typescript\";\nimport {\n TSDoc,\n TSDocDefaultValue,\n TSDocRemarks\n} from \"@powerlines/plugin-alloy/typescript/components/tsdoc\";\nimport { getAppBin, getAppTitle } from \"@shell-shock/core/plugin-utils\";\nimport { joinPaths } from \"@stryke/path\";\nimport { snakeCase } from \"@stryke/string-format\";\nimport { EXEC_COMMAND } from \"../helpers/complete-command\";\nimport { CompletionDirective } from \"../helpers/completion-directive-constants\";\nimport type { CompletionsPluginContext } from \"../types/plugin\";\n\n/**\n * The Zsh Completions commands' handler wrapper for the Shell Shock project.\n */\nexport function ZshCompletionsCommand() {\n const context = usePowerlines<CompletionsPluginContext>();\n\n const bin = computed(() => getAppBin(context));\n const name = computed(() => snakeCase(bin.value));\n\n return (\n <TypescriptFile\n path={joinPaths(context.entryPath, \"completions\", \"zsh\", \"command.ts\")}\n imports={{\n \"node:os\": \"os\",\n \"node:path\": [\"join\"],\n \"node:fs/promises\": [\"readFile\", \"writeFile\"]\n }}\n builtinImports={{\n \"shell-shock:console\": [\n \"colors\",\n \"writeLine\",\n \"success\",\n \"warn\",\n \"stripAnsi\"\n ]\n }}>\n <TSDoc heading=\"Options for the Zsh completions command.\" />\n <InterfaceDeclaration export name=\"ZshCompletionsOptions\">\n <TSDoc heading=\"The path to write the completion script to.\">\n <TSDocRemarks>{`If no extension is provided, the \\`.zsh\\` extension will be used.`}</TSDocRemarks>\n <TSDocDefaultValue\n type={ReflectionKind.string}\n defaultValue={`${bin.value}-completions.zsh`}\n />\n </TSDoc>\n <InterfaceMember name=\"script\" optional type=\"string | true\" />\n <Spacing />\n <TSDoc heading=\"The Zsh configuration file to append the completion script to.\">\n <TSDocRemarks>{`The generated completion script will be appended to the specified configuration file. Possible values for the Zsh configuration file include: \\\\n- \\`~/.zshrc\\` \\\\n- \\`~/.zprofile\\``}</TSDocRemarks>\n <TSDocDefaultValue\n type={ReflectionKind.string}\n defaultValue=\"~/.zshrc\"\n />\n </TSDoc>\n <InterfaceMember name=\"config\" optional type=\"string | true\" />\n </InterfaceDeclaration>\n <Spacing />\n <TSDoc heading=\"Handler logic for the \\`completions zsh\\` command.\"></TSDoc>\n <FunctionDeclaration\n export\n default\n async\n name=\"handler\"\n parameters={[{ name: \"options\", type: \"ZshCompletionsOptions\" }]}>\n <VarDeclaration\n const\n name=\"completions\"\n type=\"string\"\n initializer={code` \\`#compdef ${bin.value}\ncompdef _${name.value} ${bin.value}\n\n# zsh completion for ${getAppTitle(context)} -*- shell-script -*-\n\n__${name.value}_debug() {\n local file=\"$BASH_COMP_DEBUG_FILE\"\n if [[ -n \\\\\\${file} ]]; then\n echo \"$*\" >> \"\\\\\\${file}\"\n fi\n}\n\n_${name.value}() {\n local shellCompDirectiveError=${\n CompletionDirective.CompletionDirectiveError\n }\n local shellCompDirectiveNoSpace=${\n CompletionDirective.CompletionDirectiveNoSpace\n }\n local shellCompDirectiveNoFileComp=${\n CompletionDirective.CompletionDirectiveNoFileComp\n }\n local shellCompDirectiveFilterFileExt=${\n CompletionDirective.CompletionDirectiveFilterFileExt\n }\n local shellCompDirectiveFilterDirs=${\n CompletionDirective.CompletionDirectiveFilterDirs\n }\n local shellCompDirectiveKeepOrder=${\n CompletionDirective.CompletionDirectiveKeepOrder\n }\n\n local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace keepOrder\n local -a completions\n\n __${name.value}_debug \"\\\\n========= starting completion logic ==========\"\n __${name.value}_debug \"CURRENT: \\\\\\${CURRENT}, words[*]: \\\\\\${words[*]}\"\n\n # The user could have moved the cursor backwards on the command-line.\n # We need to trigger completion from the $CURRENT location, so we need\n # to truncate the command-line ($words) up to the $CURRENT location.\n # (We cannot use $CURSOR as its value does not work when a command is an alias.)\n words=( \"\\\\\\${=words[1,CURRENT]}\" )\n __${name.value}_debug \"Truncated words[*]: \\\\\\${words[*]},\"\n\n lastParam=\\\\\\${words[-1]}\n lastChar=\\\\\\${lastParam[-1]}\n __${name.value}_debug \"lastParam: \\\\\\${lastParam}, lastChar: \\\\\\${lastChar}\"\n # For zsh, when completing a flag with an = (e.g., ${bin.value} -n=<TAB>)\n # completions must be prefixed with the flag\n setopt local_options BASH_REMATCH\n if [[ \"\\\\\\${lastParam}\" =~ '-.*=' ]]; then\n # We are dealing with a flag with an =\n flagPrefix=\"-P \\\\\\${BASH_REMATCH}\"\n fi\n\n # Prepare the command to obtain completions, ensuring arguments are quoted for eval\n local -a args_to_quote=(\"\\\\\\${(@)words[2,-1]}\")\n if [ \"\\\\\\${lastChar}\" = \"\" ]; then\n # If the last parameter is complete (there is a space following it)\n # We add an extra empty parameter so we can indicate this to the go completion code.\n __${name.value}_debug \"Adding extra empty parameter\"\n args_to_quote+=(\"\")\n fi\n\n # Use Zsh's (q) flag to quote each argument safely for eval\n local quoted_args=(\"\\\\\\${(@q)args_to_quote}\")\n\n # Join the main command and the quoted arguments into a single string for eval\n requestComp=\"${EXEC_COMMAND} complete -- \\\\\\${quoted_args[*]}\"\n\n __${name.value}_debug \"About to call: eval \\\\\\${requestComp}\"\n\n # Use eval to handle any environment variables and such\n out=$(eval \\\\\\${requestComp} 2>/dev/null)\n __${name.value}_debug \"completion output: \\\\\\${out}\"\n\n # Extract the directive integer following a : from the last line\n local lastLine\n while IFS='\\n' read -r line; do\n lastLine=\\\\\\${line}\n done < <(printf \"%s\\n\" \"\\\\\\${out[@]}\")\n __${name.value}_debug \"last line: \\\\\\${lastLine}\"\n\n if [ \"\\\\\\${lastLine[1]}\" = : ]; then\n directive=\\\\\\${lastLine[2,-1]}\n # Remove the directive including the : and the newline\n local suffix\n (( suffix=\\\\\\${#lastLine}+2))\n out=\\\\\\${out[1,-$suffix]}\n else\n # There is no directive specified. Leave $out as is.\n __${name.value}_debug \"No directive found. Setting to default\"\n directive=0\n fi\n\n __${name.value}_debug \"directive: \\\\\\${directive}\"\n __${name.value}_debug \"completions: \\\\\\${out}\"\n __${name.value}_debug \"flagPrefix: \\\\\\${flagPrefix}\"\n\n if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then\n __${name.value}_debug \"Completion received error. Ignoring completions.\"\n return\n fi\n\n local activeHelpMarker=\"%\"\n local endIndex=\\\\\\${#activeHelpMarker}\n local startIndex=$((\\\\\\${#activeHelpMarker}+1))\n local hasActiveHelp=0\n while IFS='\\n' read -r comp; do\n # Check if this is an activeHelp statement (i.e., prefixed with $activeHelpMarker)\n if [ \"\\\\\\${comp[1,$endIndex]}\" = \"$activeHelpMarker\" ];then\n __${name.value}_debug \"ActiveHelp found: $comp\"\n comp=\"\\\\\\${comp[$startIndex,-1]}\"\n if [ -n \"$comp\" ]; then\n compadd -x \"\\\\\\${comp}\"\n __${name.value}_debug \"ActiveHelp will need delimiter\"\n hasActiveHelp=1\n fi\n continue\n fi\n\n if [ -n \"$comp\" ]; then\n # If requested, completions are returned with a description.\n # The description is preceded by a TAB character.\n # For zsh's _describe, we need to use a : instead of a TAB.\n # We first need to escape any : as part of the completion itself.\n comp=\\\\\\${comp//:/\\\\:}\n\n local tab=\"$(printf '\\\\t')\"\n comp=\\\\\\${comp//$tab/:}\n\n __${name.value}_debug \"Adding completion: \\\\\\${comp}\"\n completions+=\\\\\\${comp}\n lastComp=$comp\n fi\n done < <(printf \"%s\\n\" \"\\\\\\${out[@]}\")\n\n # Add a delimiter after the activeHelp statements, but only if:\n # - there are completions following the activeHelp statements, or\n # - file completion will be performed (so there will be choices after the activeHelp)\n if [ $hasActiveHelp -eq 1 ]; then\n if [ \\\\\\${#completions} -ne 0 ] || [ $((directive & shellCompDirectiveNoFileComp)) -eq 0 ]; then\n __${name.value}_debug \"Adding activeHelp delimiter\"\n compadd -x \"--\"\n hasActiveHelp=0\n fi\n fi\n\n if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then\n __${name.value}_debug \"Activating nospace.\"\n noSpace=\"-S ''\"\n fi\n\n if [ $((directive & shellCompDirectiveKeepOrder)) -ne 0 ]; then\n __${name.value}_debug \"Activating keep order.\"\n keepOrder=\"-V\"\n fi\n\n if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then\n # File extension filtering\n local filteringCmd\n filteringCmd='_files'\n for filter in \\\\\\${completions[@]}; do\n if [ \\\\\\${filter[1]} != '*' ]; then\n # zsh requires a glob pattern to do file filtering\n filter=\"\\\\*.$filter\"\n fi\n filteringCmd+=\" -g $filter\"\n done\n filteringCmd+=\" \\\\\\${flagPrefix}\"\n\n __${name.value}_debug \"File filtering command: $filteringCmd\"\n _arguments '*:filename:'\"$filteringCmd\"\n elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then\n # File completion for directories only\n local subdir\n subdir=\"\\\\\\${completions[1]}\"\n if [ -n \"$subdir\" ]; then\n __${name.value}_debug \"Listing directories in $subdir\"\n pushd \"\\\\\\${subdir}\" >/dev/null 2>&1\n else\n __${name.value}_debug \"Listing directories in .\"\n fi\n\n local result\n _arguments '*:dirname:_files -/'\" \\\\\\${flagPrefix}\"\n result=$?\n if [ -n \"$subdir\" ]; then\n popd >/dev/null 2>&1\n fi\n return $result\n else\n __${name.value}_debug \"Calling _describe\"\n if eval _describe $keepOrder \"completions\" completions -Q \\\\\\${flagPrefix} \\\\\\${noSpace}; then\n __${name.value}_debug \"_describe found some completions\"\n\n # Return the success of having called _describe\n return 0\n else\n __${name.value}_debug \"_describe did not find completions.\"\n __${name.value}_debug \"Checking if we should do file completion.\"\n if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then\n __${name.value}_debug \"deactivating file completion\"\n\n # Return 0 to indicate completion is finished and prevent zsh from\n # trying other completion algorithms (which could cause hanging).\n # We use NoFileComp directive to explicitly disable file completion.\n return 0\n else\n # Perform file completion\n __${name.value}_debug \"Activating file completion\"\n\n # We must return the result of this command, so it must be the\n # last command, or else we must store its result to return it.\n _arguments '*:filename:_files'\" \\\\\\${flagPrefix}\"\n fi\n fi\n fi\n}\n\n# don't run the completion function when being sourced or eval-ed\nif [ \"\\\\\\${funcstack[1]}\" = \"_${name.value}\" ]; then\n _${name.value}\nfi\n\\`; `}\n />\n <Spacing />\n <IfStatement condition={code`options.config`}>\n <VarDeclaration\n let\n name=\"configFilePath\"\n type=\"string\"\n initializer={code`options.config === true ? \"~/.zshrc\" : options.config`}\n />\n <Spacing />\n <IfStatement condition={code`configFilePath.startsWith(\"~\")`}>\n {code`configFilePath = join(os.homedir(), configFilePath.replace(\"~\", \"\")); `}\n </IfStatement>\n <Spacing />\n <VarDeclaration\n let\n name=\"configFileContent\"\n type=\"string\"\n initializer={code`\"\";`}\n />\n <Spacing />\n {code`try {\n configFileContent = await readFile(configFilePath, \"utf8\");\n } catch (error) {\n if (Error.isError(error) && error.code === \"ENOENT\") {\n // If the file doesn't exist, we can create it later when writing the completion script.\n warn(\\`Configuration file \\${colors.bold(configFilePath)} does not exist. It will be created when the completion script is written.\\`);\n } else {\n return { error };\n }\n }\n\n await writeFile(configFilePath, \\`\\${configFileContent}\\\\n\\\\n\\${stripAnsi(completions)}\\`);\n\n success(\\`${getAppTitle(context)} Zsh completion script has been generated and appended to \\${colors.bold(configFilePath)}. Please restart your terminal or run \\`source \\${configFilePath}\\` to apply the changes.\\`); `}\n </IfStatement>\n <Spacing />\n <IfStatement condition={code`options.script`}>\n {code`const outputPath = options.script === true ? \"${\n name.value\n }-completions.zsh\" : options.script;\n await writeFile(outputPath, stripAnsi(completions));\n\n success(\\`${getAppTitle(context)} Zsh completion script has been generated at \\${colors.bold(outputPath)}.\\`);`}\n </IfStatement>\n <Spacing />\n <IfStatement condition={code`!options.config && !options.script`}>\n {code`writeLine(\" ------------------------------------------------- \");\n writeLine(completions);\n writeLine(\" ------------------------------------------------- \");`}\n </IfStatement>\n </FunctionDeclaration>\n </TypescriptFile>\n );\n}\n"],"mappings":"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"}
@@ -4,12 +4,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
4
  function quoteIfNeeded(path) {
5
5
  return path.includes(" ") ? `'${path}'` : path;
6
6
  }
7
- const execPath = process.execPath;
8
- const processArgs = process.argv.slice(1);
9
- const quotedExecPath = quoteIfNeeded(execPath);
10
- const quotedProcessArgs = processArgs.map(quoteIfNeeded);
11
- const quotedProcessExecArgs = process.execArgv.map(quoteIfNeeded);
12
- const exec = `${quotedExecPath} ${quotedProcessExecArgs.join(" ")} ${quotedProcessArgs[0]}`;
7
+ const EXEC_COMMAND = `${quoteIfNeeded(process.execPath)} ${process.execArgv.map(quoteIfNeeded).join(" ")} ${process.argv.slice(1).map(quoteIfNeeded)[0]}`;
13
8
 
14
9
  //#endregion
15
- exports.exec = exec;
10
+ exports.EXEC_COMMAND = EXEC_COMMAND;
@@ -1,5 +1,5 @@
1
1
  //#region src/helpers/complete-command.d.ts
2
- declare const exec: string;
2
+ declare const EXEC_COMMAND: string;
3
3
  //#endregion
4
- export { exec };
4
+ export { EXEC_COMMAND };
5
5
  //# sourceMappingURL=complete-command.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"complete-command.d.cts","names":[],"sources":["../../src/helpers/complete-command.ts"],"mappings":";cA4Ba,IAAA"}
1
+ {"version":3,"file":"complete-command.d.cts","names":[],"sources":["../../src/helpers/complete-command.ts"],"mappings":";cAsBa,YAAA"}
@@ -1,5 +1,5 @@
1
1
  //#region src/helpers/complete-command.d.ts
2
- declare const exec: string;
2
+ declare const EXEC_COMMAND: string;
3
3
  //#endregion
4
- export { exec };
4
+ export { EXEC_COMMAND };
5
5
  //# sourceMappingURL=complete-command.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"complete-command.d.mts","names":[],"sources":["../../src/helpers/complete-command.ts"],"mappings":";cA4Ba,IAAA"}
1
+ {"version":3,"file":"complete-command.d.mts","names":[],"sources":["../../src/helpers/complete-command.ts"],"mappings":";cAsBa,YAAA"}
@@ -2,13 +2,8 @@
2
2
  function quoteIfNeeded(path) {
3
3
  return path.includes(" ") ? `'${path}'` : path;
4
4
  }
5
- const execPath = process.execPath;
6
- const processArgs = process.argv.slice(1);
7
- const quotedExecPath = quoteIfNeeded(execPath);
8
- const quotedProcessArgs = processArgs.map(quoteIfNeeded);
9
- const quotedProcessExecArgs = process.execArgv.map(quoteIfNeeded);
10
- const exec = `${quotedExecPath} ${quotedProcessExecArgs.join(" ")} ${quotedProcessArgs[0]}`;
5
+ const EXEC_COMMAND = `${quoteIfNeeded(process.execPath)} ${process.execArgv.map(quoteIfNeeded).join(" ")} ${process.argv.slice(1).map(quoteIfNeeded)[0]}`;
11
6
 
12
7
  //#endregion
13
- export { exec };
8
+ export { EXEC_COMMAND };
14
9
  //# sourceMappingURL=complete-command.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"complete-command.mjs","names":[],"sources":["../../src/helpers/complete-command.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Shell Shock\n\n This code was released as part of the Shell Shock project. Shell Shock\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/shell-shock.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/shell-shock\n Documentation: https://docs.stormsoftware.com/projects/shell-shock\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nfunction quoteIfNeeded(path: string): string {\n return path.includes(\" \") ? `'${path}'` : path;\n}\n\nconst execPath = process.execPath;\nconst processArgs = process.argv.slice(1);\nconst quotedExecPath = quoteIfNeeded(execPath);\nconst quotedProcessArgs = processArgs.map(quoteIfNeeded);\nconst quotedProcessExecArgs = process.execArgv.map(quoteIfNeeded);\n\nexport const exec = `${quotedExecPath} ${quotedProcessExecArgs.join(\" \")} ${\n quotedProcessArgs[0]\n}`;\n"],"mappings":";AAkBA,SAAS,cAAc,MAAsB;AAC3C,QAAO,KAAK,SAAS,IAAI,GAAG,IAAI,KAAK,KAAK;;AAG5C,MAAM,WAAW,QAAQ;AACzB,MAAM,cAAc,QAAQ,KAAK,MAAM,EAAE;AACzC,MAAM,iBAAiB,cAAc,SAAS;AAC9C,MAAM,oBAAoB,YAAY,IAAI,cAAc;AACxD,MAAM,wBAAwB,QAAQ,SAAS,IAAI,cAAc;AAEjE,MAAa,OAAO,GAAG,eAAe,GAAG,sBAAsB,KAAK,IAAI,CAAC,GACvE,kBAAkB"}
1
+ {"version":3,"file":"complete-command.mjs","names":[],"sources":["../../src/helpers/complete-command.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Shell Shock\n\n This code was released as part of the Shell Shock project. Shell Shock\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/shell-shock.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/shell-shock\n Documentation: https://docs.stormsoftware.com/projects/shell-shock\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nfunction quoteIfNeeded(path: string): string {\n return path.includes(\" \") ? `'${path}'` : path;\n}\n\nexport const EXEC_COMMAND = `${quoteIfNeeded(process.execPath)} ${process.execArgv\n .map(quoteIfNeeded)\n .join(\" \")} ${process.argv.slice(1).map(quoteIfNeeded)[0]}`;\n"],"mappings":";AAkBA,SAAS,cAAc,MAAsB;AAC3C,QAAO,KAAK,SAAS,IAAI,GAAG,IAAI,KAAK,KAAK;;AAG5C,MAAa,eAAe,GAAG,cAAc,QAAQ,SAAS,CAAC,GAAG,QAAQ,SACvE,IAAI,cAAc,CAClB,KAAK,IAAI,CAAC,GAAG,QAAQ,KAAK,MAAM,EAAE,CAAC,IAAI,cAAc,CAAC"}
@@ -3,4 +3,4 @@ const require_helpers_complete_command = require('./complete-command.cjs');
3
3
  const require_helpers_completion_directive_constants = require('./completion-directive-constants.cjs');
4
4
 
5
5
  exports.CompletionDirective = require_helpers_completion_directive_constants.CompletionDirective;
6
- exports.exec = require_helpers_complete_command.exec;
6
+ exports.EXEC_COMMAND = require_helpers_complete_command.EXEC_COMMAND;
@@ -1,3 +1,3 @@
1
- import { exec } from "./complete-command.cjs";
1
+ import { EXEC_COMMAND } from "./complete-command.cjs";
2
2
  import { CompletionDirective } from "./completion-directive-constants.cjs";
3
- export { CompletionDirective, exec };
3
+ export { CompletionDirective, EXEC_COMMAND };
@@ -1,3 +1,3 @@
1
- import { exec } from "./complete-command.mjs";
1
+ import { EXEC_COMMAND } from "./complete-command.mjs";
2
2
  import { CompletionDirective } from "./completion-directive-constants.mjs";
3
- export { CompletionDirective, exec };
3
+ export { CompletionDirective, EXEC_COMMAND };
@@ -1,4 +1,4 @@
1
- import { exec } from "./complete-command.mjs";
1
+ import { EXEC_COMMAND } from "./complete-command.mjs";
2
2
  import { CompletionDirective } from "./completion-directive-constants.mjs";
3
3
 
4
- export { CompletionDirective, exec };
4
+ export { CompletionDirective, EXEC_COMMAND };