├── LICENSE ├── README.md ├── completion └── _fnm └── zsh-fnm.plugin.zsh /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright © 2022 Dominik Schwabe 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the "Software"), 7 | to deal in the Software without restriction, including without limitation 8 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | and/or sell copies of the Software, and to permit persons to whom the 10 | Software is furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included 13 | in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 21 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ZSH Plugin - Fast Node Manager (fnm) 2 | 3 | ZSH Plugin to install and load the [Fast Node Manager (fnm)](https://github.com/Schniz/fnm). 4 | 5 | ## Installation 6 | 7 | ### [Zi](https://github.com/z-shell/zi) 8 | 9 | add the following to your `.zshrc` 10 | 11 | ```zsh 12 | zi light "dominik-schwabe/zsh-fnm" 13 | ``` 14 | 15 | with configurations 16 | 17 | ```zsh 18 | zi ice atinit'ZSH_FNM_NODE_VERSION=15.0.0' 19 | zi light "dominik-schwabe/zsh-fnm" 20 | ``` 21 | 22 | with configurations + turbo mode 23 | 24 | ```zsh 25 | zi ice wait lucid atinit'ZSH_FNM_NODE_VERSION=15.0.0' 26 | zi light "dominik-schwabe/zsh-fnm" 27 | ``` 28 | 29 | ## Configuration 30 | 31 | ### ZSH_FNM_NODE_VERSION 32 | 33 | Set this environment variable to automatically install a node version and use it. 34 | e.g. 35 | 36 | ```zsh 37 | export ZSH_FNM_NODE_VERSION="15.0.0" 38 | ``` 39 | 40 | ### ZSH_FNM_ENV_EXTRA_ARGS 41 | 42 | Pass extra arguments to `fnm env`. 43 | e.g. 44 | 45 | ```zsh 46 | export ZSH_FNM_ENV_EXTRA_ARGS="--use-on-cd" 47 | ``` 48 | 49 | ### ZSH_FNM_INSTALL_DIR 50 | 51 | Set a fixed location where fnm gets installed. 52 | e.g. 53 | 54 | ```zsh 55 | export ZSH_FNM_INSTALL_DIR="$HOME/.fnm" 56 | ``` 57 | 58 | ## Similar Projects 59 | 60 | - [zsh-nvm](https://github.com/lukechilds/zsh-nvm) 61 | 62 | ## Contributions 63 | 64 | I don't use fnm anymore (i use [asdf](https://github.com/asdf-vm/asdf)) but since this project is so small and easy to maintain, any contributions are welcome. 65 | -------------------------------------------------------------------------------- /completion/_fnm: -------------------------------------------------------------------------------- 1 | #compdef fnm 2 | 3 | autoload -U is-at-least 4 | 5 | _fnm() { 6 | typeset -A opt_args 7 | typeset -a _arguments_options 8 | local ret=1 9 | 10 | if is-at-least 5.2; then 11 | _arguments_options=(-s -S -C) 12 | else 13 | _arguments_options=(-s -C) 14 | fi 15 | 16 | local context curcontext="$curcontext" state line 17 | _arguments "${_arguments_options[@]}" \ 18 | '--node-dist-mirror=[https://nodejs.org/dist/ mirror]:NODE_DIST_MIRROR: ' \ 19 | '--fnm-dir=[The root directory of fnm installations]:BASE_DIR: ' \ 20 | '--multishell-path=[Where the current node version link is stored. This value will be populated automatically by evaluating `fnm env` in your shell profile. Read more about it using `fnm help env`]:MULTISHELL_PATH: ' \ 21 | '--log-level=[The log level of fnm commands]:LOG_LEVEL:(quiet info all error)' \ 22 | '--arch=[Override the architecture of the installed Node binary. Defaults to arch of fnm binary]:ARCH: ' \ 23 | '--version-file-strategy=[A strategy for how to resolve the Node version. Used whenever `fnm use` or `fnm install` is called without a version, or when `--use-on-cd` is configured on evaluation]:VERSION_FILE_STRATEGY:(local recursive)' \ 24 | '--help[Print help information]' \ 25 | '--version[Print version information]' \ 26 | ":: :_fnm_commands" \ 27 | "*::: :->fnm" \ 28 | && ret=0 29 | case $state in 30 | (fnm) 31 | words=($line[1] "${words[@]}") 32 | (( CURRENT += 1 )) 33 | curcontext="${curcontext%:*:*}:fnm-command-$line[1]:" 34 | case $line[1] in 35 | (list-remote) 36 | _arguments "${_arguments_options[@]}" \ 37 | '--help[Print help information]' \ 38 | '--version[Print version information]' \ 39 | && ret=0 40 | ;; 41 | (list) 42 | _arguments "${_arguments_options[@]}" \ 43 | '--help[Print help information]' \ 44 | '--version[Print version information]' \ 45 | && ret=0 46 | ;; 47 | (install) 48 | _arguments "${_arguments_options[@]}" \ 49 | '--help[Print help information]' \ 50 | '--version[Print version information]' \ 51 | '(--version)--lts[Install latest LTS]' \ 52 | '::version -- A version string. Can be a partial semver or a LTS version name by the format lts/NAME:' \ 53 | && ret=0 54 | ;; 55 | (use) 56 | _arguments "${_arguments_options[@]}" \ 57 | '--help[Print help information]' \ 58 | '--version[Print version information]' \ 59 | '--install-if-missing[Install the version if it isn'\''t installed yet]' \ 60 | '--silent-if-unchanged[Don'\''t output a message identifying the version being used if it will not change due to execution of this command]' \ 61 | '::version:' \ 62 | && ret=0 63 | ;; 64 | (env) 65 | _arguments "${_arguments_options[@]}" \ 66 | '--shell=[The shell syntax to use. Infers when missing]:SHELL:(bash zsh fish powershell)' \ 67 | '--help[Print help information]' \ 68 | '--version[Print version information]' \ 69 | '--multi[Deprecated. This is the default now]' \ 70 | '--use-on-cd[Print the script to change Node versions every directory change]' \ 71 | && ret=0 72 | ;; 73 | (completions) 74 | _arguments "${_arguments_options[@]}" \ 75 | '--shell=[The shell syntax to use. Infers when missing]:SHELL: ' \ 76 | '--help[Print help information]' \ 77 | '--version[Print version information]' \ 78 | && ret=0 79 | ;; 80 | (alias) 81 | _arguments "${_arguments_options[@]}" \ 82 | '--help[Print help information]' \ 83 | '--version[Print version information]' \ 84 | ':to-version:' \ 85 | ':name:' \ 86 | && ret=0 87 | ;; 88 | (unalias) 89 | _arguments "${_arguments_options[@]}" \ 90 | '--help[Print help information]' \ 91 | '--version[Print version information]' \ 92 | ':requested-alias:' \ 93 | && ret=0 94 | ;; 95 | (default) 96 | _arguments "${_arguments_options[@]}" \ 97 | '--help[Print help information]' \ 98 | '--version[Print version information]' \ 99 | ':version:' \ 100 | && ret=0 101 | ;; 102 | (current) 103 | _arguments "${_arguments_options[@]}" \ 104 | '--help[Print help information]' \ 105 | '--version[Print version information]' \ 106 | && ret=0 107 | ;; 108 | (exec) 109 | _arguments "${_arguments_options[@]}" \ 110 | '--using=[Either an explicit version, or a filename with the version written in it]:VERSION: ' \ 111 | '--help[Print help information]' \ 112 | '--version[Print version information]' \ 113 | '--using-file[Deprecated. This is the default now]' \ 114 | '*::arguments -- The command to run:' \ 115 | && ret=0 116 | ;; 117 | (uninstall) 118 | _arguments "${_arguments_options[@]}" \ 119 | '--help[Print help information]' \ 120 | '--version[Print version information]' \ 121 | '::version:' \ 122 | && ret=0 123 | ;; 124 | esac 125 | ;; 126 | esac 127 | } 128 | 129 | (( $+functions[_fnm_commands] )) || 130 | _fnm_commands() { 131 | local commands; commands=( 132 | 'list-remote:List all remote Node.js versions' \ 133 | 'ls-remote:List all remote Node.js versions' \ 134 | 'list:List all locally installed Node.js versions' \ 135 | 'ls:List all locally installed Node.js versions' \ 136 | 'install:Install a new Node.js version' \ 137 | 'use:Change Node.js version' \ 138 | 'env:Print and set up required environment variables for fnm' \ 139 | 'completions:Print shell completions to stdout' \ 140 | 'alias:Alias a version to a common name' \ 141 | 'unalias:Remove an alias definition' \ 142 | 'default:Set a version as the default version' \ 143 | 'current:Print the current Node.js version' \ 144 | 'exec:Run a command within fnm context' \ 145 | 'uninstall:Uninstall a Node.js version' \ 146 | ) 147 | _describe -t commands 'fnm commands' commands "$@" 148 | } 149 | (( $+functions[_alias_commands] )) || 150 | _alias_commands() { 151 | local commands; commands=() 152 | _describe -t commands 'alias commands' commands "$@" 153 | } 154 | (( $+functions[_completions_commands] )) || 155 | _completions_commands() { 156 | local commands; commands=() 157 | _describe -t commands 'completions commands' commands "$@" 158 | } 159 | (( $+functions[_current_commands] )) || 160 | _current_commands() { 161 | local commands; commands=() 162 | _describe -t commands 'current commands' commands "$@" 163 | } 164 | (( $+functions[_default_commands] )) || 165 | _default_commands() { 166 | local commands; commands=() 167 | _describe -t commands 'default commands' commands "$@" 168 | } 169 | (( $+functions[_env_commands] )) || 170 | _env_commands() { 171 | local commands; commands=() 172 | _describe -t commands 'env commands' commands "$@" 173 | } 174 | (( $+functions[_exec_commands] )) || 175 | _exec_commands() { 176 | local commands; commands=() 177 | _describe -t commands 'exec commands' commands "$@" 178 | } 179 | (( $+functions[_install_commands] )) || 180 | _install_commands() { 181 | local commands; commands=() 182 | _describe -t commands 'install commands' commands "$@" 183 | } 184 | (( $+functions[_list_commands] )) || 185 | _list_commands() { 186 | local commands; commands=() 187 | _describe -t commands 'list commands' commands "$@" 188 | } 189 | (( $+functions[_list-remote_commands] )) || 190 | _list-remote_commands() { 191 | local commands; commands=() 192 | _describe -t commands 'list-remote commands' commands "$@" 193 | } 194 | (( $+functions[_unalias_commands] )) || 195 | _unalias_commands() { 196 | local commands; commands=() 197 | _describe -t commands 'unalias commands' commands "$@" 198 | } 199 | (( $+functions[_uninstall_commands] )) || 200 | _uninstall_commands() { 201 | local commands; commands=() 202 | _describe -t commands 'uninstall commands' commands "$@" 203 | } 204 | (( $+functions[_use_commands] )) || 205 | _use_commands() { 206 | local commands; commands=() 207 | _describe -t commands 'use commands' commands "$@" 208 | } 209 | 210 | _fnm "$@" 211 | -------------------------------------------------------------------------------- /zsh-fnm.plugin.zsh: -------------------------------------------------------------------------------- 1 | # this is copied from the install script: https://fnm.vercel.app/install 2 | if [ -z $ZSH_FNM_INSTALL_DIR ]; then 3 | if [ -d "$HOME/.fnm" ]; then 4 | ZSH_FNM_INSTALL_DIR="$HOME/.fnm" 5 | elif [ -n "$XDG_DATA_HOME" ]; then 6 | ZSH_FNM_INSTALL_DIR="$XDG_DATA_HOME/fnm" 7 | elif [ "$(uname -s)" = "Darwin" ]; then 8 | ZSH_FNM_INSTALL_DIR="$HOME/Library/Application Support/fnm" 9 | else 10 | ZSH_FNM_INSTALL_DIR="$HOME/.local/share/fnm" 11 | fi 12 | fi 13 | 14 | _install_fnm() { 15 | FNM_INSTALL_URL="https://fnm.vercel.app/install" 16 | 17 | FNM_INSTALL_SCRIPT=$(curl -fsSL $FNM_INSTALL_URL 2>/dev/null) \ 18 | || FNM_INSTALL_SCRIPT=$(wget -qO- $FNM_INSTALL_URL 2>/dev/null) \ 19 | || {echo "curl or wget required to install fnm"; return 1} 20 | 21 | bash -s -- --skip-shell --install-dir "$ZSH_FNM_INSTALL_DIR" <<< $FNM_INSTALL_SCRIPT || return 1 22 | return 0 23 | } 24 | 25 | command -v fnm &>/dev/null || { 26 | export PATH=$ZSH_FNM_INSTALL_DIR:$PATH 27 | command -v fnm &>/dev/null || _install_fnm 28 | } 29 | 30 | eval "$(fnm env $ZSH_FNM_ENV_EXTRA_ARGS)" 31 | 32 | if [ -n "$ZSH_FNM_NODE_VERSION" ]; then 33 | if ! fnm use $ZSH_FNM_NODE_VERSION &>/dev/null; then 34 | echo "node version $ZSH_FNM_NODE_VERSION not present" 35 | echo "trying to install version $ZSH_FNM_NODE_VERSION" 36 | if fnm install $ZSH_FNM_NODE_VERSION; then 37 | if ! fnm use $ZSH_FNM_NODE_VERSION; then 38 | echo "$ZSH_FNM_NODE_VERSION not found" 39 | fi 40 | fi 41 | fi 42 | fi 43 | 44 | fpath+="${0:h}/completion" 45 | --------------------------------------------------------------------------------