Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,39 @@ Then source it in your `.zshrc`
source ~/.zsh-better-npm-completion/zsh-better-npm-completion.plugin.zsh
```

## Module Install Cache

When running `npm install <tab>`, it will look in your local npm cache directory for package suggestions.
However building this list is still relatively slow. This completion makes use of the zsh completion
caching mechanism to cache the module list if you have caching enabled.

Caching can be enabled for all completions like this:

```zsh
zstyle ':completion:*' use-cache on
```

Or specifically for the npm completion like this:

```zsh
zstyle ':completion::complete:npm::' use-cache on
```

By default the cache will be valid for 1 hour. But can be modified by setting a cache policy like this:

```zsh
_npm_install_cache_policy() {
# rebuild if cache is more than 24 hours old
local -a oldp
# See http://zsh.sourceforge.net/Doc/Release/Expansion.html#Glob-Qualifiers
# Nmh+24 ... N == NULL_GLOB, m == modified time, h == hour, +24 == +24 units (i.e. [M]onth, [w]weeks, [h]ours, [m]inutes, [s]econds)
oldp=( "$1"(Nmh+24) )
(( $#oldp ))
}
zstyle ':completion::complete:npm::' cache-policy _npm_install_cache_policy
```


## Related

- [`zsh-nvm`](https://github.com/lukechilds/zsh-nvm) - Zsh plugin for installing, updating and loading `nvm`
Expand Down
51 changes: 50 additions & 1 deletion zsh-better-npm-completion.plugin.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,56 @@ _zbnc_no_of_npm_args() {
}

_zbnc_list_cached_modules() {
ls ~/.npm 2>/dev/null
local update_policy
zstyle -s ":completion:${curcontext}:" cache-policy update_policy
if [[ -z "$update_policy" ]]; then
zstyle ":completion:${curcontext}:" cache-policy _zbnc_list_cached_modules_policy
fi

if _cache_invalid zbnc_cached_modules || ! _retrieve_cache zbnc_cached_modules; then
_modules=$(_zbnc_list_cached_modules_no_cache)

if [ $? -eq 0 ]; then
_store_cache zbnc_cached_modules _modules
else
# some error occurred, the user is probably not logged in
# set _modules to an empty string so that no completion is attempted
_modules=""
fi
else
_retrieve_cache zbnc_cached_modules
fi
echo $_modules
}

_zbnc_list_cached_modules_policy() {
# rebuild if cache is more than an hour old
local -a oldp
# See http://zsh.sourceforge.net/Doc/Release/Expansion.html#Glob-Qualifiers
oldp=( "$1"(Nmh+1) )
(( $#oldp ))
}

_zbnc_list_cached_modules_no_cache() {
local cache_dir="$(npm config get cache)/_cacache"
export NODE_PATH="${NODE_PATH}:$(npm prefix -g)/lib/node_modules"
node --eval="require('cacache');" &>/dev/null || npm install -g cacache &>/dev/null
if [ -d "${cache_dir}" ]; then
node <<CACHE_LS 2>/dev/null
const cacache = require('cacache');
cacache.ls('${cache_dir}').then(cache => {
const packages = Object.values(cache).forEach(entry => {
const id = ((entry || {}).metadata || {}).id;
if (id) {
console.log(id.substr(0, id.lastIndexOf('@')));
}
});
});
CACHE_LS
else
# Fallback to older cache location ... i think node < 10
ls --color=never ~/.npm 2>/dev/null
fi
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure the structure of the cache directory before, but at some point i'd like to see if we can actually search via npm (i.e. npm search --parseable @babel | awk '{ print $1 }') rather than using the local cache. This way we'd get completion even for packages we've never installed. But i'd like to see how we can incorporate the zsh cache stuff into that.

And looks like we'd only be able to search with 3+ characters. So any tab completion below that would have to come from cache.

}

_zbnc_recursively_look_for() {
Expand Down