Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Added file/url completion for "install" command. #2612

Closed
wants to merge 4 commits into from

4 participants

@deestan

Tried to implement according to the function comment block.

@isaacs
Owner

Sorry, I know it's been a while.

Would you mind rebasing onto the current master branch?

@isaacs isaacs closed this
@isaacs isaacs reopened this
@deestan
@luk-

@isaacs this still something we want?

@othiym23
Owner

At long last, this has been rebased, squashed, tweaked, and landed as d7b7853. Thank you very much for putting this together back when we were all younger, more innocent, and hopeful for the future.

@othiym23 othiym23 closed this
@deestan

Oh wow, I had completely forgotten about this. Much embarrassed. Excellent work on the rebase! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 61 additions and 18 deletions.
  1. +60 −17 lib/install.js
  2. +1 −1  lib/utils/completion.sh
View
77 lib/install.js
@@ -25,16 +25,74 @@ install.usage = "npm install <tarball file>"
+ "\npresent, installs dependencies specified in the shrinkwrap."
+ "\nOtherwise, installs dependencies from ./package.json."
+var npm = require("./npm.js")
+ , semver = require("semver")
+ , readJson = require("read-package-json")
+ , log = require("npmlog")
+ , path = require("path")
+ , fs = require("graceful-fs")
+ , cache = require("./cache.js")
+ , asyncMap = require("slide").asyncMap
+ , chain = require("slide").chain
+ , output
+ , url = require("url")
+ , mkdir = require("mkdirp")
+ , lifecycle = require("./utils/lifecycle.js")
+ , archy = require("archy")
+
install.completion = function (opts, cb) {
// install can complete to a folder with a package.json, or any package.
// if it has a slash, then it's gotta be a folder
// if it starts with https?://, then just give up, because it's a url
- // for now, not yet implemented.
+ if (/^https?:\/\//.test(opts.partialWord)) {
+ // do not complete to URLs
+ return cb(null, [])
+ }
+
+ if (/\//.test(opts.partialWord)) {
+ // Complete fully to folder if there is exactly one match and it
+ // is a folder containing a package.json file. If that is not the
+ // case we return 0 matches, which will trigger the default bash
+ // complete.
+ var lastSlashIdx = opts.partialWord.lastIndexOf("/")
+ var partialName = opts.partialWord.slice(lastSlashIdx + 1)
+ var partialPath = opts.partialWord.slice(0, lastSlashIdx)
+ if (partialPath === "")
+ partialPath = "/"
+ function annotatePackageDirMatch (sibling, cb) {
+ var fullPath = path.join(partialPath, sibling)
+ if (sibling.slice(0, partialName.length) !== partialName)
+ return cb(null, null) // not name match
+ fs.readdir(fullPath, function (err, contents) {
+ if (err) return cb(null, { isPackage: false })
+ cb(null, { fullPath: fullPath
+ , isPackage: contents.indexOf("package.json") !== -1})
+ })
+ }
+ fs.readdir(partialPath, function (err, siblings) {
+ if (err) return cb(null, []) // invalid dir: no matching
+ asyncMap( siblings
+ , annotatePackageDirMatch
+ , function (err, matches) {
+ if (err) return cb(err)
+ var cleaned = matches.filter(function (x) { return x !== null })
+ if (cleaned.length !== 1)
+ return cb(null, [])
+ if (!cleaned[0].isPackage)
+ return cb(null, [])
+ // Success - only one match and it is a package dir
+ return cb(null, [cleaned[0].fullPath])
+ })
+ })
+ return
+ }
+
+ // complete to registry
var registry = npm.registry
registry.get("/-/short", function (er, pkgs) {
if (er) return cb()
if (!opts.partialWord) return cb(null, pkgs)
-
+
var name = opts.partialWord.split("@").shift()
pkgs = pkgs.filter(function (p) {
return p.indexOf(name) === 0
@@ -55,21 +113,6 @@ install.completion = function (opts, cb) {
})
}
-var npm = require("./npm.js")
- , semver = require("semver")
- , readJson = require("read-package-json")
- , log = require("npmlog")
- , path = require("path")
- , fs = require("graceful-fs")
- , cache = require("./cache.js")
- , asyncMap = require("slide").asyncMap
- , chain = require("slide").chain
- , output
- , url = require("url")
- , mkdir = require("mkdirp")
- , lifecycle = require("./utils/lifecycle.js")
- , archy = require("archy")
-
function install (args, cb_) {
function cb (er, installed) {
View
2  lib/utils/completion.sh
@@ -21,7 +21,7 @@ if type complete &>/dev/null; then
2>/dev/null)) || return $?
IFS="$si"
}
- complete -F _npm_completion npm
+ complete -o default -F _npm_completion npm
elif type compdef &>/dev/null; then
_npm_completion() {
si=$IFS
Something went wrong with that request. Please try again.