Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimizations, move functions to functions/ dir #20

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.directory
*.zwc
*.old
*~
Binary file removed demo.gif
Binary file not shown.
7 changes: 7 additions & 0 deletions functions/zbnc_default_npm_completion
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env zsh

compadd -- $(COMP_CWORD=$((CURRENT-1)) \
COMP_LINE=$BUFFER \
COMP_POINT=0 \
npm completion -- "${words[@]}" \
2>/dev/null)
8 changes: 8 additions & 0 deletions functions/zbnc_get_package_json_property_object
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env zsh

local package_json="$1"
local property="$2"
cat "$package_json" |
sed -nE "/^ \"$property\": \{$/,/^ \},?$/p" | # Grab scripts object
sed '1d;$d' | # Remove first/last lines
sed -E 's/ "([^"]+)": "(.+)",?/\1=>\2/' # Parse into key=>value
5 changes: 5 additions & 0 deletions functions/zbnc_get_package_json_property_object_keys
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env zsh

local package_json="$1"
local property="$2"
zbnc_get_package_json_property_object "$package_json" "$property" | cut -f 1 -d "="
3 changes: 3 additions & 0 deletions functions/zbnc_list_cached_modules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env zsh

ls ~/.npm 2>/dev/null
3 changes: 3 additions & 0 deletions functions/zbnc_no_of_npm_args
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env zsh

echo "$#words"
3 changes: 3 additions & 0 deletions functions/zbnc_npm_command
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env zsh

echo "${words[2]}"
3 changes: 3 additions & 0 deletions functions/zbnc_npm_command_arg
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env zsh

echo "${words[3]}"
13 changes: 13 additions & 0 deletions functions/zbnc_npm_install_completion
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env zsh

# Only run on `npm install ?`
[[ ! "$(zbnc_no_of_npm_args)" = "3" ]] && return

# Return if we don't have any cached modules
[[ "$(zbnc_list_cached_modules)" = "" ]] && return

# If we do, recommend them
_values $(zbnc_list_cached_modules)

# Make sure we don't run default completion
custom_completion=true
23 changes: 23 additions & 0 deletions functions/zbnc_npm_run_completion
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env zsh

# Only run on `npm run ?`
[[ ! "$(zbnc_no_of_npm_args)" = "3" ]] && return

# Look for a package.json file
local package_json="$(zbnc_recursively_look_for package.json)"

# Return if we can't find package.json
[[ "$package_json" = "" ]] && return

# Parse scripts in package.json
local -a options
options=(${(f)"$(zbnc_parse_package_json_for_script_suggestions $package_json)"})

# Return if we can't parse it
[[ "$#options" = 0 ]] && return

# Load the completions
_describe 'values' options

# Make sure we don't run default completion
custom_completion=true
15 changes: 15 additions & 0 deletions functions/zbnc_npm_uninstall_completion
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env zsh

# Use default npm completion to recommend global modules
[[ "$(zbnc_npm_command_arg)" = "-g" ]] || [[ "$(zbnc_npm_command_arg)" = "--global" ]] && return

# Look for a package.json file
local package_json="$(zbnc_recursively_look_for package.json)"

# Return if we can't find package.json
[[ "$package_json" = "" ]] && return

_values $(zbnc_parse_package_json_for_deps "$package_json")

# Make sure we don't run default completion
custom_completion=true
13 changes: 13 additions & 0 deletions functions/zbnc_npx_list_executables
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
local package_json="$1"
local node_modules="$(dirname package_json)/node_modules"
local bindir="$node_modules/.bin"

# Return if there's no node_modules
[[ ! -e "$node_modules" ]] && return

# Return if there's no .bin in node_modules
[[ ! -e "$bindir" ]] && return

for i in $bindir/*; do
basename $i
done
5 changes: 5 additions & 0 deletions functions/zbnc_parse_package_json_for_deps
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env zsh

local package_json="$1"
zbnc_get_package_json_property_object_keys "$package_json" dependencies
zbnc_get_package_json_property_object_keys "$package_json" devDependencies
7 changes: 7 additions & 0 deletions functions/zbnc_parse_package_json_for_script_suggestions
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env zsh

local package_json="$1"
zbnc_get_package_json_property_object "$package_json" scripts |
sed -E 's/(.+)=>(.+)/\1:$ \2/' | # Parse commands into suggestions
sed 's/\(:\)[^$]/\\&/g' | # Escape ":" in commands
sed 's/\(:\)$[^ ]/\\&/g' # Escape ":$" without a space in commands
9 changes: 9 additions & 0 deletions functions/zbnc_recursively_look_for
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env zsh

local filename="$1"
local dir=$PWD
while [ ! -e "$dir/$filename" ]; do
dir=${dir%/*}
[[ "$dir" = "" ]] && break
done
[[ ! "$dir" = "" ]] && echo "$dir/$filename"
20 changes: 20 additions & 0 deletions functions/zbnc_zsh_better_npm_completion
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env zsh

# Store custom completion status
local custom_completion=false

# Load custom completion commands
case "$(zbnc_npm_command)" in
i|install)
zbnc_npm_install_completion
;;
r|uninstall)
zbnc_npm_uninstall_completion
;;
run)
zbnc_npm_run_completion
;;
esac

# Fall back to default completion if we haven't done a custom one
[[ $custom_completion = false ]] && zbnc_default_npm_completion
9 changes: 9 additions & 0 deletions functions/zbnc_zsh_better_npm_completion_npx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
local package_json="$(zbnc_recursively_look_for package.json)"

# Return if we can't find package.json
[[ "$package_json" = "" ]] && return

_values $(zbnc_npx_list_executables "$package_json")

# Make sure we don't run default completion
custom_completion=true
172 changes: 29 additions & 143 deletions zsh-better-npm-completion.plugin.zsh
Original file line number Diff line number Diff line change
@@ -1,143 +1,29 @@
_zbnc_npm_command() {
echo "${words[2]}"
}

_zbnc_npm_command_arg() {
echo "${words[3]}"
}

_zbnc_no_of_npm_args() {
echo "$#words"
}

_zbnc_list_cached_modules() {
ls ~/.npm 2>/dev/null
}

_zbnc_recursively_look_for() {
local filename="$1"
local dir=$PWD
while [ ! -e "$dir/$filename" ]; do
dir=${dir%/*}
[[ "$dir" = "" ]] && break
done
[[ ! "$dir" = "" ]] && echo "$dir/$filename"
}

_zbnc_get_package_json_property_object() {
local package_json="$1"
local property="$2"
cat "$package_json" |
sed -nE "/^ \"$property\": \{$/,/^ \},?$/p" | # Grab scripts object
sed '1d;$d' | # Remove first/last lines
sed -E 's/ "([^"]+)": "(.+)",?/\1=>\2/' # Parse into key=>value
}

_zbnc_get_package_json_property_object_keys() {
local package_json="$1"
local property="$2"
_zbnc_get_package_json_property_object "$package_json" "$property" | cut -f 1 -d "="
}

_zbnc_parse_package_json_for_script_suggestions() {
local package_json="$1"
_zbnc_get_package_json_property_object "$package_json" scripts |
sed -E 's/(.+)=>(.+)/\1:$ \2/' | # Parse commands into suggestions
sed 's/\(:\)[^$]/\\&/g' | # Escape ":" in commands
sed 's/\(:\)$[^ ]/\\&/g' # Escape ":$" without a space in commands
}

_zbnc_parse_package_json_for_deps() {
local package_json="$1"
_zbnc_get_package_json_property_object_keys "$package_json" dependencies
_zbnc_get_package_json_property_object_keys "$package_json" devDependencies
}

_zbnc_npm_install_completion() {

# Only run on `npm install ?`
[[ ! "$(_zbnc_no_of_npm_args)" = "3" ]] && return

# Return if we don't have any cached modules
[[ "$(_zbnc_list_cached_modules)" = "" ]] && return

# If we do, recommend them
_values $(_zbnc_list_cached_modules)

# Make sure we don't run default completion
custom_completion=true
}

_zbnc_npm_uninstall_completion() {

# Use default npm completion to recommend global modules
[[ "$(_zbnc_npm_command_arg)" = "-g" ]] || [[ "$(_zbnc_npm_command_arg)" = "--global" ]] && return

# Look for a package.json file
local package_json="$(_zbnc_recursively_look_for package.json)"

# Return if we can't find package.json
[[ "$package_json" = "" ]] && return

_values $(_zbnc_parse_package_json_for_deps "$package_json")

# Make sure we don't run default completion
custom_completion=true
}

_zbnc_npm_run_completion() {

# Only run on `npm run ?`
[[ ! "$(_zbnc_no_of_npm_args)" = "3" ]] && return

# Look for a package.json file
local package_json="$(_zbnc_recursively_look_for package.json)"

# Return if we can't find package.json
[[ "$package_json" = "" ]] && return

# Parse scripts in package.json
local -a options
options=(${(f)"$(_zbnc_parse_package_json_for_script_suggestions $package_json)"})

# Return if we can't parse it
[[ "$#options" = 0 ]] && return

# Load the completions
_describe 'values' options

# Make sure we don't run default completion
custom_completion=true
}

_zbnc_default_npm_completion() {
compadd -- $(COMP_CWORD=$((CURRENT-1)) \
COMP_LINE=$BUFFER \
COMP_POINT=0 \
npm completion -- "${words[@]}" \
2>/dev/null)
}

_zbnc_zsh_better_npm_completion() {

# Store custom completion status
local custom_completion=false

# Load custom completion commands
case "$(_zbnc_npm_command)" in
i|install)
_zbnc_npm_install_completion
;;
r|uninstall)
_zbnc_npm_uninstall_completion
;;
run)
_zbnc_npm_run_completion
;;
esac

# Fall back to default completion if we haven't done a custom one
[[ $custom_completion = false ]] && _zbnc_default_npm_completion
}

compdef _zbnc_zsh_better_npm_completion npm
# Standarized ZSH polyfills, following:
# https://github.com/zdharma/Zsh-100-Commits-Club/blob/master/Zsh-Plugin-Standard.adoc
0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
0="${${(M)0:#/*}:-$PWD/$0}"

if [[ $PMSPEC != *f* ]] {
fpath+=( "${0:h}/functions" )
}

autoload -Uz \
zbnc_default_npm_completion \
zbnc_get_package_json_property_object \
zbnc_get_package_json_property_object_keys \
zbnc_list_cached_modules \
zbnc_no_of_npm_args \
zbnc_npm_command \
zbnc_npm_command_arg \
zbnc_npm_install_completion \
zbnc_npm_run_completion \
zbnc_npm_uninstall_completion \
zbnc_parse_package_json_for_deps \
zbnc_parse_package_json_for_script_suggestions \
zbnc_recursively_look_for \
zbnc_zsh_better_npm_completion \
zbnc_zsh_better_npm_completion_npx \
zbnc_npx_list_executables

compdef zbnc_zsh_better_npm_completion npm
compdef zbnc_zsh_better_npm_completion_npx npx