├── .gitignore ├── LICENSE ├── README.md ├── demo.gif ├── getScripts.js └── zsh-npm-scripts-autocomplete.plugin.zsh /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_store 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Grigorii Zander 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # zsh-npm-scripts-autocomplete 2 | This plugin shows autocomplete suggestions for `npm` scripts from `package.json` at current working directory. 3 | Works with `npm`, `yarn`, `bun` and `pnpm`. 4 | 5 | ![](demo.gif) 6 | 7 | ## Installation 8 | ### oh-my-zsh 9 | 10 | #### Step 1 11 | Clone this repository to your oh-my-zsh plugins folder 12 | (by default `~/.oh-my-zsh/custom/plugins`): 13 | ```shell 14 | git clone \ 15 | git@github.com:grigorii-zander/zsh-npm-scripts-autocomplete.git \ 16 | ~/.oh-my-zsh/custom/plugins/zsh-npm-scripts-autocomplete 17 | ``` 18 | 19 | #### Step 2 20 | Add plugin to your `.zshrc` config: 21 | ```shell 22 | plugins=( 23 | zsh-npm-scripts-autocomplete 24 | ) 25 | ``` 26 | 27 | #### Step 3 28 | Restart your terminal or reload `.zshrc` config with the following command: 29 | ```shell 30 | source ~/.zshrc 31 | ``` 32 | 33 | #### Step 4 (optional) 34 | Invoke selected script with a single hit of `Enter/Return`. 35 | ```shell 36 | zmodload -i zsh/complist 37 | bindkey -M menuselect '^M' .accept-line 38 | ``` 39 | https://superuser.com/questions/1498187/zsh-select-menu-auto-completion-with-single-enter-return-press 40 | -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grigorii-zander/zsh-npm-scripts-autocomplete/5d145e13150acf5dbb01dac6e57e57c357a47a4b/demo.gif -------------------------------------------------------------------------------- /getScripts.js: -------------------------------------------------------------------------------- 1 | 2 | const pkg = require(process.argv[2]) 3 | 4 | const result = Object 5 | .entries(pkg.scripts || {}) 6 | .filter(entry => /^\w/.test(entry[0])) 7 | .map(entry => { 8 | entry[0] = entry[0].replace(/([$:])/ig, '\\$1') 9 | entry[1] = entry[1].replace(/([$:])/ig, '\\$1') 10 | return entry 11 | }) 12 | .map(entry => `${entry[0]}:$ ${entry[1]}`) 13 | .join('\n') 14 | 15 | console.log(result) 16 | -------------------------------------------------------------------------------- /zsh-npm-scripts-autocomplete.plugin.zsh: -------------------------------------------------------------------------------- 1 | local _plugin_path=$0 2 | local _PWD=`echo $_plugin_path | sed -e 's/\/zsh-npm-scripts-autocomplete\.plugin\.zsh//'` 3 | __zna_pwd="$_PWD" 4 | __znsaGetScripts() { 5 | local pkgJson="$1" 6 | node "$__zna_pwd/getScripts.js" "$pkgJson" 2>/dev/null 7 | } 8 | 9 | __znsaFindFile() { 10 | local filename="$1" 11 | local dir=$PWD 12 | while [ ! -e "$dir/$filename" ]; do 13 | dir=${dir%/*} 14 | [[ "$dir" = "" ]] && break 15 | done 16 | [[ ! "$dir" = "" ]] && echo "$dir/$filename" 17 | } 18 | 19 | __znsaArgsLength() { 20 | echo "$#words" 21 | } 22 | 23 | __znsaYarnRunCompletion() { 24 | [[ ! "$(__znsaArgsLength)" = "2" ]] && return 25 | local pkgJson="$(__znsaFindFile package.json)" 26 | [[ "$pkgJson" = "" ]] && return 27 | local -a options 28 | options=(${(f)"$(__znsaGetScripts $pkgJson)"}) 29 | [[ "$#options" = 0 ]] && return 30 | _describe 'values' options 31 | } 32 | 33 | ## to lazy to handler different number of arguments 34 | ## just copy and paste it 35 | __znsaNpmRunCompletion() { 36 | [[ ! "$(__znsaArgsLength)" = "3" ]] && return 37 | local pkgJson="$(__znsaFindFile package.json)" 38 | [[ "$pkgJson" = "" ]] && return 39 | local -a options 40 | options=(${(f)"$(__znsaGetScripts $pkgJson)"}) 41 | [[ "$#options" = 0 ]] && return 42 | _describe 'values' options 43 | } 44 | 45 | __znsaHandleYarn() { 46 | __znsaYarnRunCompletion 47 | } 48 | 49 | __znsaHandleNpm(){ 50 | case "${words[2]}" in 51 | run) 52 | __znsaNpmRunCompletion 53 | ;; 54 | esac 55 | } 56 | 57 | alias nr="npm run" 58 | compdef __znsaYarnRunCompletion yarn 59 | compdef __znsaYarnRunCompletion nr 60 | compdef __znsaYarnRunCompletion pnpm 61 | compdef __znsaHandleNpm npm 62 | compdef __znsaHandleNpm bun 63 | --------------------------------------------------------------------------------