(args)
| 61 | } |
| 62 | |
| 63 | async exec (args) { |
| 64 | if (isWindowsShell) { |
| 65 | const msg = 'npm completion supported only in MINGW / Git bash on Windows' |
| 66 | throw Object.assign(new Error(msg), { |
| 67 | code: 'ENOTSUP', |
| 68 | }) |
| 69 | } |
| 70 | |
| 71 | const { COMP_CWORD, COMP_LINE, COMP_POINT, COMP_FISH } = process.env |
| 72 | |
| 73 | // if the COMP_* isn't in the env, then just dump the script. |
| 74 | if (COMP_CWORD === undefined || COMP_LINE === undefined || COMP_POINT === undefined) { |
| 75 | return dumpScript(resolve(this.npm.npmRoot, 'lib', 'utils', 'completion.sh')) |
| 76 | } |
| 77 | |
| 78 | // ok we're actually looking at the envs and outputting the suggestions get the partial line and partial word, if the point isn't at the end. |
| 79 | // ie, tabbing at: npm foo b|ar |
| 80 | const w = +COMP_CWORD |
| 81 | const line = COMP_LINE |
| 82 | // Use COMP_LINE to get words if args doesn't include flags (e.g., in tests) |
| 83 | const hasFlags = line.includes(' -') && !args.some(arg => arg.startsWith('-')) |
| 84 | const words = (hasFlags ? line.split(/\s+/) : args).map(unescape) |
| 85 | const word = words[w] || '' |
| 86 | const point = +COMP_POINT |
| 87 | const partialLine = line.slice(0, point) |
| 88 | const partialWords = words.slice(0, w) |
| 89 | |
| 90 | // figure out where in that last word the point is. |
| 91 | const partialWordRaw = args[w] || '' |
| 92 | let i = partialWordRaw.length |
| 93 | while (partialWordRaw.slice(0, i) !== partialLine.slice(-1 * i) && i > 0) { |
| 94 | i-- |
| 95 | } |
| 96 | |
| 97 | const partialWord = unescape(partialWordRaw.slice(0, i)) |
| 98 | partialWords.push(partialWord) |
| 99 | |
| 100 | const opts = { |
| 101 | isFish: COMP_FISH === 'true', |
| 102 | words, |
| 103 | w, |
| 104 | word, |
| 105 | line, |
| 106 | lineLength: line.length, |
| 107 | point, |
| 108 | partialLine, |
| 109 | partialWords, |
| 110 | partialWord, |
| 111 | raw: args, |
| 112 | } |
| 113 | |
| 114 | // try to find the npm command and subcommand early for flag completion this helps with custom command definitions from subcommands |
| 115 | const types = Object.entries(definitions).reduce((acc, [key, def]) => { |
| 116 | acc[key] = def.type |
| 117 | return acc |
| 118 | }, {}) |
| 119 | const parsed = opts.conf = |
| 120 | nopt(types, shorthands, partialWords.slice(0, -1), 0) |
nothing calls this directly
no test coverage detected