├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── .markdownlint.json ├── .vscode └── zpm.code-workspace ├── LICENSE ├── Makefile ├── README.md ├── bin └── @zpm-plugin-helper ├── functions ├── @zpm-add-autoload ├── @zpm-addfpath ├── @zpm-addpath ├── @zpm-async-source ├── @zpm-background-initialization ├── @zpm-clean ├── @zpm-compile ├── @zpm-get-plugin-autoload ├── @zpm-get-plugin-basename ├── @zpm-get-plugin-bin-path ├── @zpm-get-plugin-destination-path ├── @zpm-get-plugin-documentation-hyperlink ├── @zpm-get-plugin-documentation-link ├── @zpm-get-plugin-file-path ├── @zpm-get-plugin-functions-path ├── @zpm-get-plugin-name ├── @zpm-get-plugin-origin ├── @zpm-get-plugin-origin-type ├── @zpm-get-plugin-path ├── @zpm-get-plugin-type ├── @zpm-initialize-plugin ├── @zpm-launch-plugin-helper ├── @zpm-load-plugins ├── @zpm-log ├── @zpm-no-source ├── @zpm-source ├── @zpm-upgrade ├── _zpm └── zpm ├── images ├── demo.gif ├── logo.png └── logo.svg ├── lib ├── imperative.zsh └── init.zsh ├── plugins └── .gitkeep ├── tests └── startup │ ├── bash │ └── zsh ├── zpm.zsh └── zshrc /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | 12 | **To Reproduce** 13 | 14 | **Expected behavior** 15 | 16 | **Additional context** 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | 12 | **Describe the solution you'd like** 13 | 14 | **Describe alternatives you've considered** 15 | 16 | **Additional context** 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | tests/_output/* 2 | !tests/_output/.gitkeep 3 | 4 | plugins/* 5 | !plugins/.gitkeep 6 | 7 | .directory 8 | *.zwc 9 | *.old 10 | *.bak 11 | *~ 12 | -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "MD033": false, 3 | "MD004": false, 4 | "MD013": false, 5 | "MD041": false 6 | } 7 | -------------------------------------------------------------------------------- /.vscode/zpm.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": ".." 5 | } 6 | ], 7 | "settings": {} 8 | } 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | 167 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | clean: 2 | @rm -f functions/*.zwc 3 | @rm -f lib/*.zwc 4 | 5 | all: clean 6 | @for file in functions/* ; do \ 7 | beautysh --indent-size 2 --force-function-style fnpar $$file ; \ 8 | done 9 | 10 | @for file in lib/* ; do \ 11 | beautysh --indent-size 2 --force-function-style fnpar $$file ; \ 12 | done 13 | 14 | @beautysh --indent-size 2 --force-function-style fnpar zpm.zsh 15 | @beautysh --indent-size 2 --force-function-style fnpar bin/@zpm-plugin-helper 16 | 17 | test: 18 | zsh tests/base.test.zsh 19 | 20 | .PHONY: all clean test 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Logo 3 |

ZPM - Zsh Plugin Manager

4 |

5 | Fastest, configurable and extensible zsh plugin manager 6 |

7 |

8 | 9 | Software License 10 | 11 | Travis 12 | Go Report Card 13 |

14 |

15 | 16 | Zpm is a plugin manager for ZSH who combines the imperative and declarative approach. At first run, zpm will do complex logic and generate cache, after that will be used cache only, so it makes this framework to be very fast. 17 | 18 |

19 | 20 |

21 | 22 | ## Features 23 | 24 | - **Speed**. Fastest plugin manager (Really, after the first run, zpm will not be used at all) 25 | - **Compatibility**. Zpm plugins are compatible with [oh-my-zsh](https://github.com/ohmyzsh/ohmyzsh) 26 | - **Portability**. Zpm runs on Linux, Android, OpenWrt, FreeBSD and macOS 27 | - Support for async loading 28 | - Dependencies between packages 29 | - Hooks 30 | - Function autoloading 31 | - Extensible 32 | - Possibility to use github/gitlab/bitbucket mirrors (useful for China) 33 | 34 | ## Table of Contents 35 | 36 | - [Features](#features) 37 | - [Table of Contents](#table-of-contents) 38 | - [Stats](#stats) 39 | - [Base dependences](#base-dependences) 40 | - [Installation](#installation) 41 | - [How to use](#how-to-use) 42 | - [Load plugin](#load-plugin) 43 | - [Plugin name](#plugin-name) 44 | - [Plugin tags](#plugin-tags) 45 | - [`if` and `if-not` conditions](#if-and-if-not-conditions) 46 | - [Upgrade](#upgrade) 47 | - [Clean](#clean) 48 | - [Configuration](#configuration) 49 | - [Troubleshooting](#troubleshooting) 50 | - [Developing process](#developing-process) 51 | - [TODO](#todo) 52 | - [Changelog](#changelog) 53 | 54 | ## Stats 55 | 56 |
57 | Test on Intel I7-8750H, SanDisk SD7SN6S, 16GB RAM 58 |

59 | 60 | ```sh 61 | zsh -i -c exit 0.00s user 0.00s system 102% cpu 0.006 total 62 | zsh -i -c exit 0.01s user 0.00s system 101% cpu 0.006 total 63 | zsh -i -c exit 0.00s user 0.01s system 99% cpu 0.006 total 64 | zsh -i -c exit 0.01s user 0.00s system 102% cpu 0.007 total 65 | zsh -i -c exit 0.00s user 0.00s system 100% cpu 0.007 total 66 | zsh -i -c exit 0.01s user 0.00s system 100% cpu 0.007 total 67 | zsh -i -c exit 0.00s user 0.00s system 101% cpu 0.007 total 68 | zsh -i -c exit 0.00s user 0.00s system 100% cpu 0.006 total 69 | zsh -i -c exit 0.00s user 0.00s system 101% cpu 0.007 total 70 | zsh -i -c exit 0.00s user 0.00s system 100% cpu 0.008 total 71 | ``` 72 | 73 |

74 |
75 | 76 |
77 | Test on Raspberry Pi Zero W, Raspbian 10, 1GHz Broadcom BCM2835 ARMv6, 512MB RAM 78 |

79 | 80 | ```sh 81 | zsh -i -c exit 0.14s user 0.05s system 85% cpu 0.219 total 82 | zsh -i -c exit 0.14s user 0.05s system 43% cpu 0.436 total 83 | zsh -i -c exit 0.14s user 0.05s system 58% cpu 0.325 total 84 | zsh -i -c exit 0.12s user 0.07s system 90% cpu 0.206 total 85 | zsh -i -c exit 0.15s user 0.05s system 84% cpu 0.231 total 86 | zsh -i -c exit 0.15s user 0.04s system 46% cpu 0.407 total 87 | zsh -i -c exit 0.13s user 0.06s system 62% cpu 0.306 total 88 | zsh -i -c exit 0.11s user 0.08s system 83% cpu 0.227 total 89 | zsh -i -c exit 0.14s user 0.05s system 47% cpu 0.403 total 90 | zsh -i -c exit 0.11s user 0.08s system 62% cpu 0.307 total 91 | ``` 92 | 93 |

94 |
95 | 96 |
97 | Test on MikroTik RouterBOARD 951Ui-2HnD, OpenWrt 19.07.7, 600MHz Atheros AR9344 MIPS, 128MB RAM 98 |

99 | 100 | ```sh 101 | zsh -i -c exit 0.09s user 0.03s system 83% cpu 0.144 total 102 | zsh -i -c exit 0.10s user 0.02s system 29% cpu 0.412 total 103 | zsh -i -c exit 0.10s user 0.02s system 69% cpu 0.173 total 104 | zsh -i -c exit 0.10s user 0.03s system 73% cpu 0.165 total 105 | zsh -i -c exit 0.10s user 0.02s system 81% cpu 0.150 total 106 | zsh -i -c exit 0.10s user 0.02s system 71% cpu 0.170 total 107 | zsh -i -c exit 0.10s user 0.02s system 85% cpu 0.141 total 108 | zsh -i -c exit 0.10s user 0.02s system 42% cpu 0.283 total 109 | zsh -i -c exit 0.11s user 0.02s system 68% cpu 0.176 total 110 | zsh -i -c exit 0.10s user 0.02s system 75% cpu 0.161 total 111 | ``` 112 | 113 |

114 |
115 | 116 |
117 | With this set of plugins. 51 total 118 |

119 | 120 | ```sh 121 | zpm-zsh/helpers 122 | zpm-zsh/colors 123 | zpm-zsh/tmux 124 | zpm-zsh/vte 125 | zpm-zsh/core-config 126 | zpm-zsh/ignored-users 127 | zpm-zsh/check-deps 128 | zpm-zsh/minimal-theme 129 | zpm-zsh/material-colors 130 | zpm-zsh/pr-is-root 131 | zpm-zsh/pr-user 132 | zpm-zsh/pr-return 133 | zpm-zsh/pr-exec-time 134 | zpm-zsh/pretty-time-zsh 135 | zpm-zsh/pr-git 136 | zpm-zsh/pr-cwd 137 | zpm-zsh/pr-php 138 | zpm-zsh/pr-rust 139 | zpm-zsh/pr-node 140 | zpm-zsh/pr-2 141 | zpm-zsh/pr-eol 142 | zpm-zsh/pr-zcalc 143 | zpm-zsh/pr-correct 144 | zpm-zsh/ls 145 | zpm-zsh/colorize 146 | zpm-zsh/ssh 147 | zpm-zsh/dot 148 | zpm-zsh/undollar 149 | zpm-zsh/dropbox 150 | lukechilds/zsh-better-npm-completion 151 | zpm-zsh/clipboard 152 | zpm-zsh/mysql-colorize 153 | zpm-zsh/zshmarks 154 | voronkovich/gitignore.plugin.zsh 155 | zpm-zsh/autoenv 156 | mdumitru/fancy-ctrl-z 157 | zsh-users/zsh-history-substring-search 158 | zdharma/fast-syntax-highlighting 159 | zsh-users/zsh-autosuggestions 160 | psprint/history-search-multi-word 161 | zpm-zsh/zpm-readme 162 | zpm-zsh/zpm-info 163 | zpm-zsh/zpm-telemetry 164 | zpm-zsh/zpm-link 165 | @omz/extract 166 | @omz/command-not-found 167 | @omz/pip 168 | @empty/npm 169 | @empty/rustup 170 | zpm-zsh/create-zsh-plugin 171 | ``` 172 | 173 |

174 |
175 | 176 | ## Base dependences 177 | 178 | - [zsh](https://www.zsh.org/) 179 | - [git](https://git-scm.com/) 180 | - One of these: 181 | - [GNU Parallel](https://www.gnu.org/software/parallel/) for fastest parallel execution. 182 | - [Rush](https://github.com/shenwei356/rush) for fastest parallel execution. 183 | - [xargs](https://www.gnu.org/software/findutils/) as fallback 184 | - [curl](https://curl.se/) for GitHub Gists 185 | - [Termux](http://termux.com/) for Android 186 | - [cli-html](https://www.npmjs.com/package/cli-html) view html in terminal. _Optional_ 187 | - [cli-markdown](https://www.npmjs.com/package/cli-markdown) view markdown in terminal. _Optional_ 188 | 189 | ## Installation 190 | 191 | Add the following text into `.zshrc` 192 | 193 | ```sh 194 | if [[ ! -f ~/.zpm/zpm.zsh ]]; then 195 | git clone --recursive https://github.com/zpm-zsh/zpm "${XDG_DATA_HOME:-$HOME/.local/share}/zsh/plugins/@zpm" 196 | fi 197 | source "${XDG_DATA_HOME:-$HOME/.local/share}/zsh/plugins/@zpm/zpm.zsh" 198 | # Or source our zshrc 199 | # source "${XDG_DATA_HOME:-$HOME/.local/share}/zsh/plugins/@zpm/zshrc" 200 | ``` 201 | 202 | If you don't have `.zshrc` copy example of `.zshrc` from zpm 203 | 204 | ```sh 205 | ln -sf ~/.zpm/zshrc ~/.zshrc 206 | ``` 207 | 208 | ## How to use 209 | 210 | Currently zpm has following commands 211 | 212 | - load - will download and load plugin [See](#load-plugin) 213 | - if/if-not - conditions for following command [See](#if-and-if-not-conditions) 214 | - upgrade - will upgrade plugin, without parameters will upgrade all plugins [See](#upgrade) 215 | - clean - will clean zpm cache [See](#clean) 216 | 217 | The set of commands can be expanded extended using plugins 218 | 219 |
220 | Plugins for zpm itself 221 |

222 | 223 | - [zpm-readme](https://github.com/zpm-zsh/zpm-readme) - Show plugin readme in terminal 224 | - [zpm-info](https://github.com/zpm-zsh/zpm-info) - Show plugin info in terminal 225 | - [zpm-telemetry](https://github.com/zpm-zsh/zpm-telemetry) - Send telemetry data. Keep calm. Data is sent using GitHub and you can see it before sending. 226 | 227 |

228 |
229 | 230 | ### Load plugin 231 | 232 | **Important** 233 | 234 | > Be carefully, zpm doesn't guarantee loading order in call. So if you need to load a plugin **before** antoher, you should do 2 separate `zpm load` calls. 235 | > This is very important for oh-my-zsh plugins, because @omz-core should be loaded before 236 | 237 | Plugin name must have next form: `@plugin-type/user/plugin-name`. This plugin can be enabled using 238 | 239 | ```sh 240 | # Add to `~/.zshrc` after zpm initialization: 241 | zpm load @plugin-type/user/plugin-name 242 | ``` 243 | 244 | > Notice: if you change `~/.zshrc`, you need to remove zpm cache using: `zpm clean` 245 | 246 | Additionaly they can have some tags. Tags must be separated by commas `,` without spaces, tag parameters must be separated from tag names or another tag parameters by `:` 247 | 248 | ```sh 249 | # plugin type 250 | # | plugin name 251 | # | | tag 252 | # | | | tag parameters, 253 | # | | | divided by `:` boolean tag 254 | # | | | | | 255 | # ↓ ↓ ↓ ↓ ↓ 256 | @type/some/plugin,apply:source:path:fpath,async 257 | ``` 258 | 259 | ### Plugin name 260 | 261 | If plugin name starts with `@word`, this word will be used as plugin type. Plugin name will be used to detect plugin origin url. 262 | 263 | - `@github/` or `@gh/` - plugin will be cloned from GitHub, this is default value, so you don't need to set it 264 | - `@gitlab/` or `@gl/` - plugin will be cloned from GitLab 265 | - `@bitbucket/` or `@bb/` - plugin will be cloned from Bitbucket 266 | - `@git/` - plugin will be cloned via git. Be careful, zpm can't detect origin for this plugin type, you must specify origin using tag `origin:` 267 | - `@gist/` - plugin will be downloaded from GitHub Gist 268 | - `@omz/` - zpm will use a plugin from oh-my-zsh, oh-my-zsh will be download if not installed. **Important**: you shoud load `@omz` before any other plugin from on-my-zsh: `zpm load @omz`. 269 | 270 | - `@omz/theme/` - will load a theme from omz dir: `/themes/*.zsh-theme` 271 | - `@omz/lib/` - will load a lib from omz dir: `/lib/*.zsh` 272 | -
273 | 274 | Example: 275 | 276 |

277 | 278 | See: 279 | 280 | ```sh 281 | # Pull in OMZ (doesn't actually source anything) 282 | zpm load @omz 283 | 284 | # Load any OMZ libraries we want or our OMZ plugins require 285 | zpm load \ 286 | @omz/lib/compfix \ 287 | @omz/lib/completion \ 288 | @omz/lib/directories \ 289 | @omz/lib/functions \ 290 | @omz/lib/git \ 291 | @omz/lib/grep \ 292 | @omz/lib/history \ 293 | @omz/lib/key-bindings \ 294 | @omz/lib/misc \ 295 | @omz/lib/spectrum \ 296 | @omz/lib/theme-and-appearance 297 | 298 | # Load some OMZ plugins and theme 299 | zpm load \ 300 | @omz/virtualenv \ 301 | @omz/git 302 | 303 | zpm load @omz/theme/robbyrussell 304 | ``` 305 | 306 |

307 |
308 | 309 | - `@dir` - special type, zpm will create a symlink to local directory from `origin` tag 310 | - `@file` - special type, zpm will create a symlink to file from `origin` tag. Should be used for plugins that are written in single file, without additional dependencies 311 | - `@remote/` - plugin will be downloaded using curl, for example from an HTTP site. Be careful, zpm can't detect origin for this plugin type, you must specify origin using tag `origin:` 312 | - `@exec/` - special type, zpm will create plugin, completion or binary via executing of `origin` tag content. See `destination` tag 313 | - `@empty/` - special type, zpm will create empty dir without files. Useful with `hook` tag. 314 | 315 | ```sh 316 | plugin-from/github # @github doesn't necessary 317 | @gitlab/plugin-from/gitlab 318 | @bitbucket/plugin-from/bitbucket 319 | @omz/some-plugin 320 | @empty/custom/empty-plugin 321 | @empty/another-empty-plugin 322 | ``` 323 | 324 | ### Plugin tags 325 | 326 | #### `apply` tag 327 | 328 | This tag has 3 possible arguments divided by `:` 329 | 330 | - `source` - load zsh plugin file, enabled by default. File name can be changed using `source` tag 331 | - `path` - add directory to your `$PATH`, by default - `/bin` dir, enabled by default. Directory name can be changed using `path` tag 332 | - `fpath` - add directory to your `$fpath`, by default or `/functions` dir if it exists, or plugin root dir if exist at least one `_*` file, enabled by default. Directory name can be changed using `fpath` tag 333 | 334 | ```sh 335 | zpm load some/plugin,apply:source:path:fpath 336 | zpm load another/plugin,apply:path # zpm will only add /bin dir to $PATH, plugin will not be sourced, nor be added to $fpath 337 | ``` 338 | 339 | #### `async` tag 340 | 341 | If this tag is present, zsh plugin will be loaded async 342 | 343 | #### `source` tag 344 | 345 | Define own file that will be loaded 346 | 347 | ```sh 348 | zpm some/plugin,source:/other.file.zsh 349 | ``` 350 | 351 | #### `path` and `fpath` tags 352 | 353 | Using these tags you can change the destination of folders which will be added to `$PATH` or `$fpath` 354 | 355 | ```sh 356 | zpm some/plugin,path:/executables 357 | zpm another/plugin,fpath:/completions 358 | ``` 359 | 360 | #### `autoload` tag 361 | 362 | This tag defines functions that will be autoloaded by zpm (using `autoload -Uz`) divided by `:` 363 | 364 | ```sh 365 | zpm load some/plugin,autoload:one:two:three 366 | ``` 367 | 368 | #### `origin` tag 369 | 370 | All plugins have internal origin type property, like: git, dir, file, remote. 371 | You can define own origin, but you can't mix different types of origin types. 372 | So, you can define Gitlab origin for GitHub plugin, or different origin for GitHub Gist plugin. 373 | 374 | - Git plugins: `@github`, `@gitlab`, `@bitbucket`, `@git` 375 | 376 | ```sh 377 | zpm load some/plugin,origin:https://github.com/another/origin # This plugin will be loaded from https://github.com/another/origin, but will have internal name some/plugin 378 | 379 | zpm load @git/my-plugin,git://my.site/plugin.git # This plugin will be loaded from 3-party origin 380 | ``` 381 | 382 | - Remote: `@gist`, `@remote` 383 | 384 | ```sh 385 | zpm load @gist/user/hash,origin:https://another-site/file.zsh # This file will be downloaded instead of gist 386 | zpm load @remote/plugin,origin:https://mysite.com/plugin.zsh # In this case origin should be declared, because zpm can't detect origin 387 | ``` 388 | 389 | - Dir: `@dir` 390 | 391 | ```sh 392 | zpm load @dir/plugin,origin:/home/user/Projects/plugin # Internal plugin directory will be linked to your local directory 393 | ``` 394 | 395 | - File: `@file` 396 | 397 | ```sh 398 | zpm load @file/plugin-file,origin:/home/user/Projects/plugin.zsh # Internal plugin file will be linked to your local file 399 | ``` 400 | 401 | - Some special types, like: `@empty`, `@omz`, `@omz/theme`, `@omz/lib` 402 | 403 | Do not declare own `origin:`, because this can produce side effects 404 | 405 | #### `hook` tag 406 | 407 | This tag parameter contains command who will be run in the plugin directory after instalation or upgrade 408 | 409 | ```sh 410 | zpm plugin/name,hook:"make; make install" 411 | ``` 412 | 413 | ### `if` and `if-not` conditions 414 | 415 | If condition allows you to run the following commands only if the condition is true 416 | 417 | ```sh 418 | zpm if some-condition (another commands) 419 | ``` 420 | 421 | Conditions: 422 | 423 | - `linux` - if current OS is Linux 424 | - `bsd` - if current OS is \*BSD 425 | - `openwrt` - if current OS is OpenWrt 426 | - `macos` - if current OS is macOS 427 | - `termux` - if current session run in [Termux](http://termux.com/) 428 | - `ssh` - if session run on remote host 429 | - `vte` - if session run on VTE based terminal emulator 430 | 431 | Result of condition can be negated using `if-not` tag 432 | 433 | The condition can be combined `zpm if macos if-not ssh load repo/plugin` 434 | 435 | > Notice: conditions will be verified only at first run, after that will be used generated cache 436 | 437 | ### Upgrade 438 | 439 | Run `zpm upgrade` for upgrading, or run `zpm upgrade some-plugin another-plugin` if you want to upgrade only these plugins 440 | 441 | ### Clean 442 | 443 | By default zpm will generate cache file at first run, but if you will change `~/.zshrc` this cache should be removed using `zpm clean` command 444 | 445 | ## Configuration 446 | 447 | You can use another mirror for GitHub/Gitlab/Bitbucket: 448 | 449 | ```sh 450 | # Declare this before zpm load 451 | GITHUB_MIRROR="https://hub.fastgit.org" 452 | GITLAB_MIRROR="Some url" 453 | BITBUCKET_MIRROR="Some url" 454 | ``` 455 | 456 | ## Troubleshooting 457 | 458 | ### Powerlevel10k 459 | 460 | Powerlevel10k loads extra modules in its installation directory, which it [automatically detects by taking the file containing its init code, making it absolute, and taking its directory](https://github.com/romkatv/powerlevel10k/blob/0cc19ac2ede35fd8accff590fa71df580dc7e109/powerlevel10k.zsh-theme#L20). However, as zpm combines plugins into one fast-loading cache file, this automatic detection would break. 461 | 462 | As a workaround, you have to explicitly tell Powerlevel10k where it is installed. This needs to be done before the cache file is loaded, which means before zpm itself is loaded, like this: 463 | 464 | ```sh 465 | # Adjust the path accordingly if your zpm is not installed at `~/.zpm` or you're 466 | # using a powerlevel10k fork 467 | export POWERLEVEL9K_INSTALLATION_DIR=~/.zpm/plugins/romkatv---powerlevel10k 468 | source ~/.zpm/zpm.zsh 469 | 470 | # ... 471 | 472 | zpm load romkatv/powerlevel10k 473 | ``` 474 | 475 | ### Update to latest zpm 476 | 477 | If you have problems with `zpm` try updating: 478 | 479 | ```sh 480 | rm -rf "${TMPDIR:-/tmp}/zsh-${UID:-user}" # clear the cache 481 | cd ~/.zpm 482 | git pull 483 | ``` 484 | 485 | ## Developing process 486 | 487 | > You can see debug information by setting the system variable `DEBUG=zpm` 488 | 489 | When you make changes, add information about them to the change log in **next** section. Also add link to pr and link to your GitHub profile. 490 | 491 | ## TODO 492 | 493 | - [x] Create logo 494 | - [ ] Improve readme 495 | - [ ] Describe installation process 496 | - [ ] Improve completions 497 | - [ ] Now `zpm load`, `zpm upgrade` or `zpm subcommand` will complete only one argument 498 | 499 | ## Changelog 500 | 501 | - 7.0 502 | 503 | - Move zpm to `$XDG_DATA_HOME/zsh/plugins/zpm` 504 | 505 | - 6.0 506 | 507 | - Add workarouds for powerlevel10k, zsh-syntax-highlighting, zsh-history-substring-search, sindresorhus/pure 508 | 509 | - 5.3 510 | 511 | - Change plugin file path detector 512 | 513 | - 5.2 514 | 515 | - Remove old omz tag 516 | 517 | - 5.1 518 | 519 | - Change internal functions 520 | 521 | - 5.0 522 | 523 | - Removed `gen-plugin` and `gen-completion` tags 524 | - `@omz-theme/` and `@omz-lib/` changed to `@omz/theme/` and `@omz/lib/` 525 | 526 | - 4.2 527 | 528 | - Replace `$ZERO` with `$0`. Fixed [#43](https://github.com/zpm-zsh/zpm/issues/43) 529 | - Update README. [#44](https://github.com/zpm-zsh/zpm/pull/44) 530 | 531 | - 4.1 532 | 533 | - Added possibility to change parallel runner, e.g. GNU Parallel, Rush, Xargs 534 | - Optimize plugin load 535 | - Change some plugin urls 536 | 537 | - 4.0 538 | 539 | - Refactoring of internal logic 540 | - Added new plugin types: `@gist`, `@remote` 541 | 542 | - 3.6 543 | 544 | - Added new plugin types `@dir` and `@file` 545 | - `@link` now is an alias for `@dir` 546 | - Fixed [#35](https://github.com/zpm-zsh/zpm/issues/35) 547 | 548 | - 3.5 549 | 550 | - Added new logo 551 | - Added possibility to use mirrors for GitHub/Gitlab/Bitbucket. See [issue](https://github.com/zpm-zsh/zpm/issues/31) 552 | 553 | - 3.4 554 | 555 | - Added GNU Parallel 556 | 557 | - 3.3 558 | 559 | - Added `origin` tag 560 | - Removed `autoload-all` tag 561 | 562 | - 3.2 563 | 564 | - Fix plugin load order 565 | - Use sched for background run 566 | 567 | - 3.1 568 | 569 | - Fix completions 570 | - Add example for @omz 571 | 572 | - 3.0 573 | 574 | - Remove unused `@link` 575 | - Remove `tr` calls 576 | - Deprecate `type:` tag 577 | - Internal changes for basename/name,hyperlink 578 | - Add support for oh-my-zsh themes and libs 579 | - `zpm load @omz-theme/theme-name` 580 | - `zpm load @omz-lib/lib` 581 | - Upgrade from 2.x: 582 | - Add `zpm load @omz` if you use at least one oh-my-zsh plugin. 583 | - Replace `type:plugin-type` with `@plugin-type/plugin/name` 584 | 585 | - 2.3 586 | 587 | - Improve **README** 588 | - Remove suppot for `zsh_loaded_plugins` 589 | - Add config for Markdownlint 590 | 591 | - 2.2 592 | 593 | - Add support for OpenWrt 594 | - Improve oh-my-zsh-support [@igetgames](https://github.com/igetgames) 595 | - Support for calling plugin functions from command tags [@igetgames](https://github.com/igetgames) 596 | - Fix autoload option processing [@igetgames](https://github.com/igetgames) 597 | 598 | - 2.1 599 | 600 | - Optimizations 601 | - Now all content of `/functions` and `/bin` will be copied into single dir, in zpm cache dir 602 | - Change `zpm` to `@zpm` 603 | - Remove unused vars 604 | - Some vars will be loaded async 605 | - Fixed colors 606 | - Notes 607 | - Now for update zpm need to run `zpm u @zpm` 608 | 609 | - 2.0 610 | - `omz/` prefix replaced by `@omz/` 611 | - Added plugin type `empty` 612 | - Added `autoload` and `autoload-all` tags 613 | - Added `gen-plugin` and `gen-completion` tags 614 | - Notes: 615 | - Replace `omz/` to `@omz/` in your `.zshrc` 616 | -------------------------------------------------------------------------------- /bin/@zpm-plugin-helper: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | fpath+=("${_ZPM_DIR}/functions" "${ZSH_TMP_DIR}/functions") 4 | 5 | function _msg() { 6 | local msg 7 | local color 8 | 9 | if [[ "$Command" == "install" ]]; then 10 | if [[ "$1" == "skip" ]]; then 11 | msg="Skip install" 12 | color="${c[yellow]}${c[bold]}" 13 | symbol='✗' 14 | elif [[ "$1" == "0" ]]; then 15 | msg="Install" 16 | color="${c[green]}${c[bold]}" 17 | symbol='✓' 18 | else 19 | msg="Can't install" 20 | color="${c[red]}${c[bold]}" 21 | symbol='✗' 22 | fi 23 | elif [[ "$Command" == "upgrade" ]]; then 24 | if [[ "$1" == "skip" ]]; then 25 | msg='Skip upgrade' 26 | color="${c[yellow]}${c[bold]}" 27 | symbol='✗' 28 | elif [[ "$1" == "0" ]]; then 29 | msg='Upgrade' 30 | color="${c[green]}${c[bold]}" 31 | symbol='✓' 32 | else 33 | msg="Can't upgrade" 34 | color="${c[red]}${c[bold]}" 35 | symbol='✗' 36 | fi 37 | fi 38 | 39 | echo "${color}${c[bold]}${msg}${c[reset]} ${Plugin_documentation_hyperlink} ${color}${symbol}${c[reset]}" 40 | } 41 | 42 | if [[ "$CLICOLOR" != "0" ]]; then 43 | typeset -gA c=( 44 | reset "" 45 | bold "" 46 | 47 | black "" 48 | red "" 49 | green "" 50 | yellow "" 51 | blue "" 52 | magenta "" 53 | cyan "" 54 | white "" 55 | ) 56 | fi 57 | 58 | autoload -Uz \ 59 | @zpm-get-plugin-basename \ 60 | @zpm-get-plugin-documentation-hyperlink \ 61 | @zpm-get-plugin-documentation-link \ 62 | @zpm-get-plugin-name \ 63 | @zpm-get-plugin-origin \ 64 | @zpm-get-plugin-origin-type \ 65 | @zpm-get-plugin-path \ 66 | @zpm-get-plugin-type \ 67 | @zpm-get-plugin-vcs-root-path \ 68 | @zpm-get-plugin-destination-path \ 69 | @zpm-log 70 | 71 | 72 | (( $#_ZPM_autoload )) && autoload -Uz -- ${(z)_ZPM_autoload} 73 | 74 | local Command="$1" 75 | local Plugin="$2" 76 | local Plugin_name=$(@zpm-get-plugin-name "$Plugin") 77 | local Plugin_type=$(@zpm-get-plugin-type "$Plugin_name") 78 | local Plugin_basename=$(@zpm-get-plugin-basename "$Plugin_name") 79 | local Plugin_path=$(@zpm-get-plugin-path "$Plugin_name" "$Plugin_type") 80 | local Plugin_origin_type=$(@zpm-get-plugin-origin-type "$Plugin_name") 81 | local Plugin_origin=$(@zpm-get-plugin-origin "$Plugin" "$Plugin_name" "$Plugin_basename" "$Plugin_type" "$Plugin_origin_type") 82 | local Plugin_documentation_link=$(@zpm-get-plugin-documentation-link "$Plugin_name" "$Plugin_type" "$Plugin_origin") 83 | local Plugin_documentation_hyperlink=$(@zpm-get-plugin-documentation-hyperlink "$Plugin_name" "$Plugin_documentation_link" "$Plugin_origin") 84 | local Plugin_destination_path=$(@zpm-get-plugin-destination-path "$Plugin" "$Plugin_path" "$Plugin_basename" "$Plugin_origin_type") 85 | 86 | if [[ "$Command" == "upgrade" ]]; then 87 | @zpm-log zpm:upgrade "Upgrade '${Plugin}'" 88 | elif [[ "$Command" == "install" ]]; then 89 | @zpm-log zpm:install "Install '${Plugin}'" 90 | else 91 | echo Unknown command 92 | fi 93 | 94 | if [[ "$Plugin_origin_type" == 'git' ]]; then 95 | if [[ "$Command" == 'install' ]]; then 96 | mkdir -p "${Plugin_destination_path}/.." 97 | git clone --recursive "${Plugin_origin}" --depth 1 --single-branch "${Plugin_destination_path}" /dev/null 2>/dev/null 98 | else 99 | git --git-dir="${Plugin_destination_path}/.git/" --work-tree="${Plugin_destination_path}" pull /dev/null 2>/dev/null 100 | fi 101 | _msg $? 102 | elif [[ "$Plugin_origin_type" == 'remote' ]]; then 103 | mkdir -p "${Plugin_destination_path:h}" 104 | curl -fSL --silent "${Plugin_origin}" --output "${Plugin_destination_path}" 2>/dev/null 105 | _msg $? 106 | elif [[ "$Plugin_origin_type" == 'dir-link' ]]; then 107 | if [[ "$Command" == 'install' ]]; then 108 | ln -sf "${Plugin_origin}" "${Plugin_destination_path}" 2>/dev/null 109 | fi 110 | _msg $? 111 | elif [[ "$Plugin_origin_type" == 'file-link' ]]; then 112 | if [[ "$Command" == 'install' ]]; then 113 | mkdir -p "${Plugin_destination_path:h}" 114 | ln -sf "${Plugin_origin}" "${Plugin_destination_path}" 2>/dev/null 115 | fi 116 | _msg $? 117 | elif [[ "$Plugin_origin_type" == 'exec' ]]; then 118 | mkdir -p "${Plugin_destination_path:h}" 119 | cd "${Plugin_destination_path:h}" 120 | eval "$Plugin_origin" 1>! "${Plugin_destination_path}" 2>/dev/null 121 | _msg $? 122 | elif [[ "$Plugin_origin_type" == 'empty' ]]; then 123 | mkdir -p "${Plugin_path}" 124 | _msg $? 125 | else 126 | _msg skip 127 | fi 128 | 129 | if [[ "$Plugin" == *',destination:bin'* ]]; then 130 | chmod +x "${Plugin_destination_path}" >/dev/null 2>/dev/null 131 | fi 132 | 133 | if [[ "$Plugin" == *',hook:'* && -e "$Plugin_path" ]]; then 134 | cd "$Plugin_path" 135 | eval "${${Plugin##*,hook:}%%\,*}" >/dev/null 136 | 137 | echo "${c[green]}${c[bold]}Run hook for${c[reset]} ${Plugin_documentation_hyperlink} ${c[green]}✓${c[reset]}" 138 | fi 139 | -------------------------------------------------------------------------------- /functions/@zpm-add-autoload: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | for autoload_file in ${(s.:.)1}; do 4 | _ZPM_autoload+=("${autoload_file}") 5 | autoload -Uz -- "${autoload_file}" 6 | done 7 | -------------------------------------------------------------------------------- /functions/@zpm-addfpath: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | cp -RpLf "${1}/." "${ZSH_TMP_DIR}/functions" 4 | -------------------------------------------------------------------------------- /functions/@zpm-addpath: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | cp -RpLf "${1}/." "${ZSH_TMP_DIR}/bin" 4 | -------------------------------------------------------------------------------- /functions/@zpm-async-source: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | @zpm-log zpm:init:source "Source '${_ZPM_plugin_file_path}', async" 3 | 4 | ZERO="$2" 5 | 6 | source "$2" 7 | 8 | unset ZERO 9 | 10 | _ZPM_plugins_for_async_source+=("$1") 11 | _ZPM_file_for_async_source["$1"]="${2}" 12 | -------------------------------------------------------------------------------- /functions/@zpm-background-initialization: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | rehash 4 | compinit -i -d "${_ZPM_COMPDUMP}" 5 | unfunction source 2>/dev/null 6 | 7 | echo "$is" >! $ZSH_TMP_DIR/is 8 | 9 | local _ZPM_TMP="$(mktemp)" 10 | local _ZPM_TMP_ASYNC="$(mktemp)" 11 | 12 | echo "autoload -Uz -- @zpm-clean $_ZPM_autoload" >> "$_ZPM_TMP" 13 | echo >> "$_ZPM_TMP" 14 | 15 | echo 'compinit -i -C -d "${_ZPM_COMPDUMP}"' >> "$_ZPM_TMP" 16 | echo >> "$_ZPM_TMP" 17 | 18 | for plugin in ${_ZPM_plugins_for_source}; do 19 | local file="$_ZPM_file_for_source["$plugin"]" 20 | echo "(){" >> "$_ZPM_TMP" 21 | echo "0='${file}'" >> "$_ZPM_TMP" 22 | 23 | # Workaround for powerlevel10k 24 | if [[ "$plugin" == "romkatv/powerlevel10k" ]]; then 25 | echo "export POWERLEVEL9K_INSTALLATION_DIR='$(@zpm-get-plugin-path $plugin)'" >> "$_ZPM_TMP" 26 | fi 27 | 28 | cat "${file}" >> "$_ZPM_TMP" 29 | echo "}" >> "$_ZPM_TMP" 30 | echo >> "$_ZPM_TMP" 31 | done 32 | 33 | echo "sched +0 source '$_ZPM_CACHE_ASYNC'" >> "$_ZPM_TMP" 34 | echo >> "$_ZPM_TMP" 35 | 36 | echo 'if [[ -s $ZSH_TMP_DIR/is ]]; then' >> "$_ZPM_TMP" 37 | echo ' if [[ "$is" != "$(<$ZSH_TMP_DIR/is)" ]]; then' >> "$_ZPM_TMP" 38 | echo ' @zpm-clean' >> "$_ZPM_TMP" 39 | echo ' fi' >> "$_ZPM_TMP" 40 | echo 'fi' >> "$_ZPM_TMP" 41 | 42 | echo >> "$_ZPM_TMP" 43 | 44 | echo >> "$_ZPM_TMP" 45 | echo 'zpm () {}' >> "$_ZPM_TMP" 46 | 47 | echo "$(typeset -p _ZPM_plugins_full)" >> "$_ZPM_TMP_ASYNC" 48 | echo 'unfunction zpm' >> "$_ZPM_TMP_ASYNC" 49 | echo "$(typeset -p _zpm_parallel_format)" >> "$_ZPM_TMP_ASYNC" 50 | echo "$(typeset -p _zpm_parallel_launcher)" >> "$_ZPM_TMP_ASYNC" 51 | echo "$(typeset -p _zpm_parallel_item)" >> "$_ZPM_TMP_ASYNC" 52 | 53 | echo >> "$_ZPM_TMP_ASYNC" 54 | 55 | for plugin in ${_ZPM_plugins_for_async_source}; do 56 | local file="$_ZPM_file_for_async_source["$plugin"]" 57 | echo "(){" >> "$_ZPM_TMP_ASYNC" 58 | echo "0='${file}'" >> "$_ZPM_TMP_ASYNC" 59 | 60 | # Workaround for powerlevel10k 61 | if [[ "$plugin" == "romkatv/powerlevel10k" ]]; then 62 | echo "export POWERLEVEL9K_INSTALLATION_DIR='$(@zpm-get-plugin-path $plugin)'" >> "$_ZPM_TMP_ASYNC" 63 | fi 64 | 65 | cat "${file}" >> "$_ZPM_TMP_ASYNC" 66 | echo "}" >> "$_ZPM_TMP_ASYNC" 67 | echo >> "$_ZPM_TMP_ASYNC" 68 | done 69 | 70 | echo "zle && zle reset-prompt" >> "$_ZPM_TMP_ASYNC" 71 | echo "sched +0 source ${_ZPM_DIR}/lib/init.zsh" >> "$_ZPM_TMP_ASYNC" 72 | 73 | mv "$_ZPM_TMP" "$_ZPM_CACHE" 74 | mv "$_ZPM_TMP_ASYNC" "$_ZPM_CACHE_ASYNC" 75 | 76 | (@zpm-compile 2>/dev/null &) 77 | -------------------------------------------------------------------------------- /functions/@zpm-clean: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | rm -rf "${ZSH_TMP_DIR}" 2>/dev/null 4 | exec zsh 5 | -------------------------------------------------------------------------------- /functions/@zpm-compile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | zcompile "$_ZPM_CACHE" 2>/dev/null 4 | zcompile "$_ZPM_CACHE_ASYNC" 2>/dev/null 5 | zcompile "${_ZPM_COMPDUMP}" 2>/dev/null 6 | zcompile "${HOME}/.zshrc" 2>/dev/null 7 | zcompile "${HOME}/.zshrc.local" 2>/dev/null 8 | zcompile "${_ZPM_DIR}/zpm.zsh" 2>/dev/null 9 | zcompile "${_ZPM_DIR}/lib/init.zsh" 2>/dev/null 10 | zcompile "${_ZPM_DIR}/lib/imperative.zsh" 2>/dev/null 11 | 12 | for dir in $fpath; do 13 | if [[ -w "$dir" ]]; then 14 | for i in "${dir}"/**/*; do 15 | if [[ "${i}" != *".zwc" && ! "${i}.zwc" -nt "${i}" ]]; then 16 | zcompile -- "${i}" 2>/dev/null 17 | fi 18 | done 19 | fi 20 | done 21 | 22 | return 0 23 | -------------------------------------------------------------------------------- /functions/@zpm-get-plugin-autoload: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | local Plugin="$1" 4 | local Autoload_files="$2" 5 | 6 | if [[ "$Plugin" == *",autoload:"* ]]; then 7 | local _ZPM_autoload_str=${Plugin##*,autoload} 8 | _ZPM_autoload_str=${_ZPM_autoload_str%%\,*} 9 | Autoload_files="${Autoload_files}${_ZPM_autoload_str}" 10 | fi 11 | 12 | echo "$Autoload_files" 13 | -------------------------------------------------------------------------------- /functions/@zpm-get-plugin-basename: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | local Plugin_name="$1" 4 | 5 | echo "${Plugin_name##*\/}" 6 | -------------------------------------------------------------------------------- /functions/@zpm-get-plugin-bin-path: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | local Plugin="$1" 4 | local Plugin_path="$2" 5 | 6 | if [[ "$Plugin" == *",path:"* ]]; then 7 | local zpm_path="${Plugin_path}/${${1##*,path:}%%,*}" 8 | echo "${zpm_path:a}" 9 | elif [[ -d "${Plugin_path}/bin" ]]; then 10 | zpm_path="${Plugin_path}/bin" 11 | echo "${zpm_path:a}" 12 | fi 13 | -------------------------------------------------------------------------------- /functions/@zpm-get-plugin-destination-path: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | local Plugin="$1" 4 | local Plugin_path="$2" 5 | local Plugin_basename="$3" 6 | local Plugin_origin_type="$4" 7 | 8 | local destination='plugin' 9 | if [[ "$Plugin" == *",destination:"* ]]; then 10 | destination="${${Plugin##*,destination:}%%,*}" 11 | fi 12 | 13 | if [[ "$Plugin_origin_type" == 'git' || "$Plugin_origin_type" == 'dir-link' ]]; then 14 | echo "${Plugin_path}" 15 | elif [[ "$Plugin_origin_type" == 'remote' || "$Plugin_origin_type" == 'file-link' || "$Plugin_origin_type" == 'exec' ]]; then 16 | if [[ "$destination" == 'completion' ]]; then 17 | echo "${Plugin_path}/functions/_${Plugin_basename}" 18 | elif [[ "$destination" == 'bin' ]]; then 19 | echo "${Plugin_path}/bin/${Plugin_basename}" 20 | else 21 | echo "${Plugin_path}/${Plugin_basename}.zsh" 22 | fi 23 | else 24 | echo "${Plugin_path}" 25 | fi 26 | -------------------------------------------------------------------------------- /functions/@zpm-get-plugin-documentation-hyperlink: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | local Plugin_name="$1" 4 | local Plugin_link="$2" 5 | local status_string 6 | 7 | function join() { # usage: join ', ' "${array[@]}" 8 | local sep=$1 arg 9 | printf %s "$2" 10 | shift 2 11 | for arg do 12 | printf %s%s "$sep" "$arg" 13 | done 14 | printf '\n' 15 | } 16 | 17 | plugin_name_arr= 18 | local -a plugin_name_arr_color 19 | 20 | for plugin in ${(s./.)Plugin_name}; do 21 | if [[ "$plugin" == "@"* ]]; then 22 | plugin_name_arr_color=($plugin_name_arr_color "${c[cyan]}${c[bold]}${plugin}" ) 23 | else 24 | plugin_name_arr_color=($plugin_name_arr_color "${c[blue]}${c[bold]}${plugin}" ) 25 | fi 26 | done 27 | 28 | if [[ -z "$Plugin_link" ]]; then 29 | status_string="$(join "${c[red]}${c[bold]}/" $plugin_name_arr_color)" 30 | else 31 | status_string="\033]8;;${Plugin_link}\a" 32 | status_string+="$(join "${c[red]}${c[bold]}/" $plugin_name_arr_color)" 33 | status_string+="\033]8;;\a${c[reset]}" 34 | fi 35 | 36 | echo $status_string 37 | -------------------------------------------------------------------------------- /functions/@zpm-get-plugin-documentation-link: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | local Plugin_name="$1" 4 | local Plugin_type="$2" 5 | local Plugin_origin="$3" 6 | 7 | if [[ "$Plugin_type" == 'github' ]]; then 8 | echo "https://github.com/${Plugin_name}" 9 | elif [[ "$Plugin_type" == 'gitlab' ]]; then 10 | echo "https://gitlab.com/${Plugin_name}" 11 | elif [[ "$Plugin_type" == 'bitbucket' ]]; then 12 | echo "https://bitbucket.com/${Plugin_name}" 13 | elif [[ "$Plugin_type" == 'zpm' ]]; then 14 | echo "https://github.com/zpm-zsh/zpm" 15 | elif [[ "$Plugin_type" == 'omz-core' ]]; then 16 | echo "https://github.com/ohmyzsh/ohmyzsh" 17 | elif [[ "$Plugin_type" == 'omz' ]]; then 18 | echo "https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/${Plugin_name#*/}" 19 | elif [[ "$Plugin_type" == 'omz-lib' ]]; then 20 | echo "https://github.com/ohmyzsh/ohmyzsh/tree/master/lib/${Plugin_name#*/}.zsh" 21 | elif [[ "$Plugin_type" == 'omz-theme' ]]; then 22 | echo "https://github.com/ohmyzsh/ohmyzsh/tree/master/themes/${Plugin_name#*/}.zsh-theme" 23 | elif [[ "$Plugin_type" == 'gist' ]]; then 24 | echo "https://gist.githubusercontent.com/${Plugin_striped_name}" 25 | elif [[ "$Plugin_type" == 'dir' ]]; then 26 | echo "file://${Plugin_origin}" 27 | elif [[ "$Plugin_type" == 'file' ]]; then 28 | echo "file://${Plugin_origin}" 29 | else 30 | return -1 31 | fi 32 | -------------------------------------------------------------------------------- /functions/@zpm-get-plugin-file-path: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | local Plugin="${1}" 4 | local Plugin_path="${2}" 5 | local Plugin_basename="${3}" 6 | 7 | # Workaround for zsh-syntax-highlighting 8 | if [[ "$Plugin" == 'zsh-users/zsh-syntax-highlighting' ]]; then 9 | echo "${Plugin_path}/zsh-syntax-highlighting.zsh" 10 | return 0 11 | fi 12 | 13 | # Workaround for zsh-history-substring-search 14 | if [[ "$Plugin" == 'zsh-users/zsh-history-substring-search' ]]; then 15 | echo "${Plugin_path}/zsh-history-substring-search.zsh" 16 | return 0 17 | fi 18 | 19 | local Plugin_basename_clean=$Plugin_basename 20 | Plugin_basename_clean=${Plugin_basename_clean##oh-my-zsh-} 21 | Plugin_basename_clean=${Plugin_basename_clean##zsh-} 22 | Plugin_basename_clean=${Plugin_basename_clean%%.plugin} 23 | Plugin_basename_clean=${Plugin_basename_clean%%-plugin} 24 | Plugin_basename_clean=${Plugin_basename_clean%%.zsh} 25 | Plugin_basename_clean=${Plugin_basename_clean%%-zsh} 26 | Plugin_basename_clean=${Plugin_basename_clean%%.plugin} 27 | Plugin_basename_clean=${Plugin_basename_clean%%-plugin} 28 | 29 | if [[ "$Plugin" == *",source:"* ]]; then 30 | local Plugin_sourcefile="${${Plugin##*,source:}%%,*}" 31 | if [[ -n "${Plugin_sourcefile}" && -e "${Plugin_path}/${Plugin_sourcefile}" ]]; then 32 | echo "${Plugin_path}/${Plugin_sourcefile}" 33 | return 0 34 | else 35 | return -1 36 | fi 37 | elif [[ -e "${Plugin_path}/${Plugin_basename_clean}.zsh" ]]; then 38 | echo "${Plugin_path}/${Plugin_basename_clean}.zsh" 39 | elif [[ -e "${Plugin_path}/zsh-${Plugin_basename_clean}.zsh" ]]; then 40 | echo "${Plugin_path}/zsh-${Plugin_basename_clean}.zsh" 41 | elif [[ -e "${Plugin_path}/${Plugin_basename_clean}.plugin.zsh" ]]; then 42 | echo "${Plugin_path}/${Plugin_basename_clean}.plugin.zsh" 43 | elif [[ -e "${Plugin_path}/zsh-${Plugin_basename_clean}.plugin.zsh" ]]; then 44 | echo "${Plugin_path}/zsh-${Plugin_basename_clean}.plugin.zsh" 45 | elif [[ -e "${Plugin_path}/${Plugin_basename_clean}.zsh-theme" ]]; then 46 | echo "${Plugin_path}/${Plugin_basename_clean}.zsh-theme" 47 | elif [[ -e "${Plugin_path}/init.zsh" ]]; then 48 | echo "${Plugin_path}/init.zsh" 49 | else 50 | return -1 51 | fi 52 | -------------------------------------------------------------------------------- /functions/@zpm-get-plugin-functions-path: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | local Plugin="$1" 4 | local Plugin_path="$2" 5 | 6 | # Workaround for sindresorhus/pure 7 | if [[ "$Plugin" == 'sindresorhus/pure' ]]; then 8 | echo "${Plugin_path:a}" 9 | return 10 | fi 11 | 12 | if [[ "$Plugin" == *",fpath:"* ]]; then 13 | local zpm_fpath="${Plugin_path}/${${1##*,fpath:}%%,*}" 14 | echo "${zpm_fpath:a}" 15 | elif [[ -d "${Plugin_path}/functions" ]]; then 16 | zpm_fpath="${Plugin_path}/functions" 17 | echo "${zpm_fpath:a}" 18 | else 19 | for file in "${Plugin_path}/_"*(N); do 20 | echo "${Plugin_path:a}" 21 | return 22 | done 23 | fi 24 | -------------------------------------------------------------------------------- /functions/@zpm-get-plugin-name: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | echo "${1%%,*}" 4 | -------------------------------------------------------------------------------- /functions/@zpm-get-plugin-origin: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | local Plugin="$1" 4 | local Plugin_name="$2" 5 | local Plugin_basename="$3" 6 | local Plugin_type="$4" 7 | local Plugin_origin_type="$5" 8 | 9 | local Plugin_striped_name="${Plugin_name#@*/}" 10 | 11 | if [[ "$Plugin" == *",origin:"* ]]; then 12 | echo "${${Plugin##*,origin:}%%,*}" 13 | return 0 14 | fi 15 | 16 | GITHUB_URL=${GITHUB_MIRROR:-'https://github.com'} 17 | GITLAB_URL=${GITLAB_MIRROR:-'https://gitlab.com'} 18 | BITBUCKET_URL=${BITBUCKET_MIRROR:-'https://bitbucket.com'} 19 | 20 | if [[ "$Plugin_type" == 'github' ]]; then 21 | echo "${GITHUB_URL}/${Plugin_striped_name}" 22 | elif [[ "$Plugin_type" == 'gitlab' ]]; then 23 | echo "${GITLAB_URL}/${Plugin_striped_name}" 24 | elif [[ "$Plugin_type" == 'bitbucket' ]]; then 25 | echo "${BITBUCKET_URL}/${Plugin_striped_name}" 26 | elif [[ "$Plugin_type" == 'omz-core' ]]; then 27 | echo "${GITHUB_URL}/ohmyzsh/ohmyzsh" 28 | elif [[ "$Plugin_type" == 'omz' ]]; then 29 | echo "$(@zpm-get-plugin-path @omz)/plugins/${Plugin_basename}" 30 | elif [[ "$Plugin_type" == 'omz-theme' ]]; then 31 | echo "$(@zpm-get-plugin-path @omz)/themes/${Plugin_basename}.zsh-theme" 32 | elif [[ "$Plugin_type" == 'omz-lib' ]]; then 33 | echo "$(@zpm-get-plugin-path @omz)/lib/${Plugin_basename}.zsh" 34 | elif [[ "$Plugin_type" == 'omz-theme-old' ]]; then 35 | echo "$(@zpm-get-plugin-path @omz)/themes/${Plugin_basename}.zsh-theme" 36 | elif [[ "$Plugin_type" == 'omz-lib-old' ]]; then 37 | echo "$(@zpm-get-plugin-path @omz)/lib/${Plugin_basename}.zsh" 38 | elif [[ "$Plugin_type" == 'gist' ]]; then 39 | echo "https://gist.githubusercontent.com/${Plugin_striped_name}/raw" 40 | else 41 | return -1 42 | fi 43 | -------------------------------------------------------------------------------- /functions/@zpm-get-plugin-origin-type: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | local Plugin_name="$1" 4 | declare -ag plugin_origin_types=( 5 | empty,empty 6 | 7 | gh,git 8 | github,git 9 | gl,git 10 | gitlab,git 11 | bb,git 12 | bitbucket,git 13 | git,git 14 | 15 | file,file-link 16 | omz/theme,file-link 17 | omz/lib,file-link 18 | 19 | dir,dir-link 20 | link,dir-link 21 | omz,dir-link 22 | 23 | remote,remote 24 | gist,remote 25 | 26 | exec,exec 27 | ) 28 | 29 | if [[ "$Plugin_name" == "@"* ]]; then 30 | if [[ "$Plugin_name" == '@zpm' ]]; then 31 | echo 'git' 32 | return 0 33 | fi 34 | 35 | if [[ "$Plugin_name" == '@omz' ]]; then 36 | echo 'git' 37 | return 0 38 | fi 39 | 40 | for plugin_origin_type in ${plugin_origin_types}; do 41 | local plugin_origin_type_key="${plugin_origin_type%%\,*}" 42 | local plugin_origin_type="${plugin_origin_type#*,}" 43 | if [[ "$Plugin_name" == "@${plugin_origin_type_key}/"* ]]; then 44 | echo "$plugin_origin_type" 45 | return 0 46 | fi 47 | done 48 | 49 | return -1 50 | fi 51 | 52 | if [[ "$Plugin_name" = *'/'* && "$Plugin_name" != *'/'*'/'* ]]; then 53 | echo 'git' 54 | return 0 55 | fi 56 | 57 | return -1 58 | -------------------------------------------------------------------------------- /functions/@zpm-get-plugin-path: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | local Plugin_name="$1" 4 | 5 | if [[ "$Plugin_name" == "@zpm" ]]; then 6 | echo "${_ZPM_DIR}" 7 | return 0 8 | fi 9 | 10 | echo "${_ZPM_PLUGINS_DIR}/${Plugin_name//\//---}" 11 | -------------------------------------------------------------------------------- /functions/@zpm-get-plugin-type: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | local Plugin_name="$1" 4 | 5 | declare -ag plugin_types=( 6 | empty,empty 7 | 8 | gh,github 9 | github,github 10 | 11 | gl,gitlab 12 | gitlab,gitlab 13 | 14 | bb,bitbucket 15 | bitbucket,bitbucket 16 | 17 | git,git 18 | 19 | file,file 20 | 21 | dir,dir 22 | link,dir 23 | 24 | omz/theme,omz-theme 25 | omz/lib,omz-lib 26 | omz,omz 27 | 28 | remote,remote 29 | gist,gist 30 | 31 | exec,exec 32 | omz-theme,omz-theme-old 33 | omz-lib,omz-lib-old 34 | ) 35 | 36 | if [[ "$Plugin_name" == "@"* ]]; then 37 | if [[ "$Plugin_name" == '@zpm' ]]; then 38 | echo 'zpm' 39 | return 0 40 | fi 41 | 42 | if [[ "$Plugin_name" == '@omz' ]]; then 43 | echo 'omz-core' 44 | return 0 45 | fi 46 | 47 | for plugin_type in ${plugin_types}; do 48 | local plugin_type_key="${plugin_type%%\,*}" 49 | local plugin_type="${plugin_type#*,}" 50 | if [[ "$Plugin_name" == "@${plugin_type_key}/"* ]];then 51 | echo "$plugin_type" 52 | return 0 53 | fi 54 | done 55 | 56 | return -1 57 | fi 58 | 59 | if [[ "$Plugin_name" = *'/'* && "$Plugin_name" != *'/'*'/'* ]]; then 60 | echo 'github' 61 | return 0 62 | fi 63 | 64 | return -1 65 | -------------------------------------------------------------------------------- /functions/@zpm-initialize-plugin: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | local Plugin="$1" 4 | local Plugin_name="$2" 5 | local Plugin_basename=$(@zpm-get-plugin-basename "$Plugin_name") 6 | local Plugin_path=$(@zpm-get-plugin-path "$Plugin_name") 7 | 8 | local zpm_plugin_source=true 9 | local zpm_plugin_async=false 10 | local zpm_plugin_bin_path=true 11 | local zpm_plugin_functions_path=true 12 | local zpm_plugin_autoload='' 13 | 14 | if [[ -f "${Plugin_path}/plugin-options.zsh" ]]; then 15 | source "${Plugin_path}/plugin-options.zsh" 16 | fi 17 | 18 | @zpm-log zpm:init "Initialize '${Plugin_name}'" 19 | 20 | # Config 21 | if [[ "$Plugin" == *",apply:"* ]]; then 22 | local _ZPM_tag_str=${Plugin##*,apply} 23 | _ZPM_tag_str=${_ZPM_tag_str%%\,*} 24 | 25 | if [[ "$_ZPM_tag_str" != *':source'* ]]; then 26 | zpm_plugin_source=false 27 | fi 28 | 29 | if [[ "$_ZPM_tag_str" != *':path'* ]]; then 30 | zpm_plugin_bin_path=false 31 | fi 32 | 33 | if [[ "$_ZPM_tag_str" != *':fpath'* ]]; then 34 | zpm_plugin_functions_path=false 35 | fi 36 | fi 37 | 38 | if [[ "$Plugin" == *",async"* ]]; then 39 | zpm_plugin_async=true 40 | fi 41 | 42 | # Fpath 43 | if [[ "$zpm_plugin_functions_path" == "true" ]]; then 44 | local Plugin_functions_path=$(@zpm-get-plugin-functions-path "$Plugin" "$Plugin_path") 45 | if [[ -d "${Plugin_functions_path}" ]]; then 46 | @zpm-log zpm:init:fpath "Add to \$fpath '${Plugin_functions_path}'" 47 | @zpm-addfpath "${Plugin_functions_path}" 48 | fi 49 | fi 50 | 51 | # Bin path 52 | if [[ "$zpm_plugin_bin_path" == "true" ]]; then 53 | local Plugin_bin_path=$(@zpm-get-plugin-bin-path "$Plugin" "$Plugin_path") 54 | if [[ -d "$Plugin_bin_path" ]]; then 55 | @zpm-log zpm:init:path "Add to \$PATH '${Plugin_bin_path}'" 56 | @zpm-addpath "${Plugin_bin_path}" 57 | fi 58 | fi 59 | 60 | # Source plugin 61 | if [[ "$zpm_plugin_source" == "true" ]]; then 62 | local _ZPM_plugin_file_path=$( @zpm-get-plugin-file-path "${Plugin}" "${Plugin_path}" "${Plugin_basename}" ) 63 | if [[ -n "$_ZPM_plugin_file_path" ]]; then 64 | if [[ "$zpm_plugin_async" == "true" ]]; then 65 | @zpm-async-source "${Plugin_name}" "${_ZPM_plugin_file_path}" 66 | else 67 | @zpm-source "${Plugin_name}" "${_ZPM_plugin_file_path}" 68 | fi 69 | else 70 | @zpm-no-source "${Plugin_name}" 'missing' 71 | fi 72 | else 73 | @zpm-no-source "${Plugin_name}" 'disabled' 74 | fi 75 | 76 | # Autoload 77 | local Plugin_autoload_files=$(@zpm-get-plugin-autoload "$Plugin" "$zpm_plugin_autoload") 78 | if [[ -n "$Plugin_autoload_files" ]]; then 79 | @zpm-log zpm:init:autoload "Autoload ${Plugin_autoload_files}" 80 | @zpm-add-autoload "$Plugin_autoload_files" 81 | fi 82 | -------------------------------------------------------------------------------- /functions/@zpm-launch-plugin-helper: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | local Command="$1" 4 | 5 | shift 6 | 7 | printf $_zpm_parallel_format "$@" | \ 8 | ZSH_TMP_DIR="$ZSH_TMP_DIR" \ 9 | _ZPM_PLUGINS_DIR="$_ZPM_PLUGINS_DIR" \ 10 | _ZPM_autoload="$_ZPM_autoload" \ 11 | ${(z)_zpm_parallel_launcher} "${_ZPM_DIR}/bin/@zpm-plugin-helper" $Command $_zpm_parallel_item 12 | -------------------------------------------------------------------------------- /functions/@zpm-load-plugins: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | # Check if plugin isn't loaded 4 | local -a Plugins_Install 5 | local -a Plugins_Load_Order 6 | local -A Plugins_Load 7 | 8 | for plugin in $@; do 9 | local Plugin_name=$(@zpm-get-plugin-name "$plugin") 10 | 11 | if [[ ! -z $_ZPM_plugins_full[$Plugin_name] ]]; then 12 | @zpm-log zpm:init:skip "Skip initialization '$Plugin_name', plugin already loaded" 13 | else 14 | _ZPM_plugins_full[$Plugin_name]="$plugin" 15 | 16 | local Plugin_path=$(@zpm-get-plugin-path "$Plugin_name") 17 | 18 | if [[ ! -e $Plugin_path ]]; then 19 | Plugins_Install+=("$plugin") 20 | fi 21 | 22 | Plugins_Load_Order+=($Plugin_name) 23 | Plugins_Load[$Plugin_name]="$plugin" 24 | fi 25 | done 26 | 27 | if [[ -n "$Plugins_Install[@]" ]]; then; 28 | @zpm-launch-plugin-helper install "${Plugins_Install[@]}" 29 | fi 30 | 31 | for plugin_name in $Plugins_Load_Order; do 32 | @zpm-initialize-plugin "${Plugins_Load[$plugin_name]}" "$plugin_name" 33 | done 34 | -------------------------------------------------------------------------------- /functions/@zpm-log: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | if [[ -n "$DEBUG" && "${1}:" == "${DEBUG}:"* ]]; then 4 | local num=0 5 | local i=0 6 | 7 | while [[ $i -lt $(( ${#1} + 1 )) ]]; do 8 | num=$(( $num + $(LC_CTYPE=C printf '%d' "'${1[$i]})") )) 9 | i=$(( $i + 1)) 10 | done 11 | 12 | color=$(( $num % 6 + 1 )) 13 | 14 | echo -n "[1;3${color}m$1 " 15 | shift 16 | echo "$@" 17 | fi 18 | -------------------------------------------------------------------------------- /functions/@zpm-no-source: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | local Plugin_cause="$2" 4 | if [[ "$Plugin_cause" == 'missing' ]]; then 5 | @zpm-log zpm:init:source "Plugin file for ${Plugin_name} is missing" 6 | else 7 | @zpm-log zpm:init:source "Sourcing for ${Plugin_name} is disabled" 8 | fi 9 | 10 | _ZPM_plugins_no_source+=("$1") 11 | -------------------------------------------------------------------------------- /functions/@zpm-source: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | @zpm-log zpm:init:source "Source '${_ZPM_plugin_file_path}', sync" 3 | 4 | ZERO="$2" 5 | 6 | source "$2" 7 | 8 | unset ZERO 9 | 10 | _ZPM_plugins_for_source+=("$1") 11 | _ZPM_file_for_source["$1"]="${2}" 12 | -------------------------------------------------------------------------------- /functions/@zpm-upgrade: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | typeset -a _Plugins_Upgrade=($@) 4 | typeset -a _Plugins_Upgrade_full=() 5 | 6 | if [[ -z $@ ]]; then 7 | _Plugins_Upgrade=("${(k)_ZPM_plugins_full[@]}") 8 | fi 9 | 10 | for plugin in $_Plugins_Upgrade; do 11 | _Plugins_Upgrade_full+=($_ZPM_plugins_full[$plugin]) 12 | done 13 | 14 | @zpm-launch-plugin-helper upgrade "${_Plugins_Upgrade_full[@]}" 15 | 16 | @zpm-clean 17 | -------------------------------------------------------------------------------- /functions/_zpm: -------------------------------------------------------------------------------- 1 | #compdef zpm 2 | #autoload 3 | 4 | local _zpm_completions_plugins_local=( @zpm ) 5 | for plugin in "${_ZPM_PLUGINS_DIR}/"*; do 6 | _zpm_completions_plugins_local+=( ${${plugin:t}//---/\/} ) 7 | done 8 | 9 | if [[ -e "${_ZPM_PLUGINS_DIR}/@omz" ]]; then 10 | for omz_plugin in "${_ZPM_PLUGINS_DIR}/@omz/plugins/"*; do 11 | _zpm_completions_plugins_local+=( "@omz/${omz_plugin:t}" ) 12 | done 13 | 14 | for omz_lib in "${_ZPM_PLUGINS_DIR}/@omz/lib/"*; do 15 | _zpm_completions_plugins_local+=( "@omz/lib/${${omz_lib:t}%.zsh}" ) 16 | done 17 | 18 | for omz_theme in "${_ZPM_PLUGINS_DIR}/@omz/themes/"*; do 19 | _zpm_completions_plugins_local+=( "@omz/theme/${${omz_theme:t}%.zsh-theme}" ) 20 | done 21 | fi 22 | 23 | local _zpm_completions_plugins_installed=($( 24 | printf '%s\n%s\n' "${_zpm_completions_plugins_local[@]}" | sort | uniq 25 | )) 26 | 27 | local _zpm_completions_plugins_loadable=($( 28 | printf '%s\n%s\n' "${_zpm_completions_plugins_installed[@]}" "${(k)_ZPM_plugins_full[@]}" | sort | uniq -u 29 | )) 30 | 31 | local _zpm_upgrade_plugins=(@zpm ${(k)_ZPM_plugins_full}) 32 | 33 | local _load_args=( 34 | 'load:Load plugin' 35 | 'if:Load plugin if condition true' 36 | 'if-not:Load plugin if condition false' 37 | ) 38 | 39 | local _zpm_all_args=( 40 | $_load_args 41 | 'clean:Remove zpm cache' 42 | 'upgrade:Upgrade plugin' 43 | $_zpm_extend_commands 44 | ) 45 | 46 | local _zpm_completions_if_args=( 47 | 'linux:Linux OS' 48 | 'bsd:BSD OS' 49 | 'macos:MacOS' 50 | 'android:Android OS' 51 | 'termux:Termux app' 52 | 'ssh:SSH session' 53 | 'vte:VTE based terminal emulator' 54 | ) 55 | local _zpm_loaded_plugins=(${(k)_ZPM_plugins_full}) 56 | 57 | _arguments '*:: :->subcmds' && return 0 58 | 59 | if (( CURRENT == 1 )); then 60 | _describe -t commands "zpm subcommand" _zpm_all_args 61 | return 62 | fi 63 | 64 | if (( CURRENT > 1 )); then 65 | PRE=$((CURRENT - 1)) 66 | PRE2=$((CURRENT - 2)) 67 | 68 | if [[ "$words[$PRE]" == 'load' ]]; then 69 | _describe -t commands "zpm load" _zpm_completions_plugins_loadable 70 | return 71 | elif [[ "$words[$PRE]" == 'if' || "$words[$PRE]" == 'if-not' ]]; then 72 | _describe -t commands "zpm condition" _zpm_completions_if_args 73 | return 74 | elif [[ "$words[$PRE2]" == 'if' || "$words[$PRE2]" == 'if-not' ]]; then 75 | _describe -t commands "zpm next condition" _load_args 76 | return 77 | elif [[ "$words[$PRE]" == 'clean' ]]; then 78 | return 79 | elif [[ "$words[$PRE]" == 'u' || "$words[$PRE]" == 'up' || "$words[$PRE]" == 'upgrade' ]]; then 80 | _describe -t commands "zpm upgrade plugins" _zpm_upgrade_plugins 81 | return 82 | elif is-callable "_zpm_${words[$PRE]}_completion"; then 83 | "_zpm_${words[$PRE]}_completion" 84 | return 85 | else 86 | return 87 | fi 88 | fi 89 | 90 | return 91 | -------------------------------------------------------------------------------- /functions/zpm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | if [[ "$1" == 'load' ]]; then 4 | shift 5 | @zpm-load-plugins "$@" 6 | return 0 7 | fi 8 | 9 | if [[ "$1" == 'if' ]]; then 10 | if [[ "${is[$2]}" == '1' ]] ; then 11 | shift 2 12 | zpm "$@" 13 | fi 14 | return 0 15 | fi 16 | 17 | if [[ "$1" == 'if-not' ]]; then 18 | if [[ "${is[$2]}" == '0' ]]; then 19 | shift 2 20 | zpm "$@" 21 | fi 22 | return 0 23 | fi 24 | 25 | if [[ "$1" == 'u' || "$1" == 'up' || "$1" == 'upgrade' ]]; then 26 | shift 27 | @zpm-upgrade "$@" 28 | return 0 29 | fi 30 | 31 | if [[ "$1" == 'c' || "$1" == 'cl' || "$1" == 'clean' ]]; then 32 | @zpm-clean 33 | fi 34 | 35 | if is-callable "zpm-$1"; then 36 | local call_fn=$1 37 | shift 38 | "zpm-${call_fn}" $@ 39 | return 0 40 | fi 41 | 42 | echo 'Unknown command `zpm '"$@"'`, treat as `zpm load '"$@"'`' 43 | @zpm-load-plugins "$@" 44 | -------------------------------------------------------------------------------- /images/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zpm-zsh/zpm/926ce79a14edf3b6fe64a1be873543c58ba8782a/images/demo.gif -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zpm-zsh/zpm/926ce79a14edf3b6fe64a1be873543c58ba8782a/images/logo.png -------------------------------------------------------------------------------- /images/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | -------------------------------------------------------------------------------- /lib/imperative.zsh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | mkdir -p "${ZSH_TMP_DIR}" "${ZSH_TMP_DIR}/functions" "${ZSH_TMP_DIR}/bin" "${ZSH_DATA_HOME}" "${ZSH_DATA_HOME}/plugins" "${ZSH_DATA_HOME}/plugins/" "${ZSH_DATA_HOME}/functions" "${ZSH_DATA_HOME}/scripts" "${ZSH_DATA_HOME}/site-functions" "${ZSH_CACHE_HOME}" 4 | 5 | compinit -i -C -d "${_ZPM_COMPDUMP}" 6 | 7 | typeset -g _zpm_parallel_format 8 | typeset -g _zpm_parallel_launcher 9 | typeset -g _zpm_parallel_item 10 | 11 | function _zpm_use_parallel_runner() { 12 | _zpm_parallel_format='%s\n' 13 | _zpm_parallel_launcher="parallel" 14 | _zpm_parallel_item='{1}' 15 | } 16 | 17 | function _zpm_use_rush_runner() { 18 | _zpm_parallel_format='%s\n' 19 | _zpm_parallel_launcher="rush" 20 | _zpm_parallel_item='"{}"' 21 | } 22 | 23 | function _zpm_use_xargs_runner() { 24 | _zpm_parallel_format='%s\0' 25 | _zpm_parallel_launcher="xargs -0 -P12 -I{}" 26 | _zpm_parallel_item='{}' 27 | } 28 | 29 | if [[ -n "$_ZPM_PARALLEL_RUNNER" ]]; then 30 | if [[ "$_ZPM_PARALLEL_RUNNER" = 'parallel' ]]; then 31 | _zpm_use_parallel_runner 32 | elif [[ "$_ZPM_PARALLEL_RUNNER" = 'rush' ]]; then 33 | _zpm_use_rush_runner 34 | elif [[ "$_ZPM_PARALLEL_RUNNER" = 'xargs' ]]; then 35 | _zpm_use_xargs_runner 36 | else 37 | echo "Can't detect parallel runner" 38 | return 0 39 | fi 40 | else 41 | if (( $+commands[parallel] )); then 42 | _zpm_use_parallel_runner 43 | elif (( $+commands[rush] )); then 44 | _zpm_use_rush_runner 45 | else 46 | _zpm_use_xargs_runner 47 | fi 48 | fi 49 | 50 | declare -Ag _ZPM_plugins_full=( '@zpm' '@zpm' ) 51 | @zpm-load-plugins zpm-zsh/helpers 52 | 53 | sched +1 @zpm-background-initialization 54 | 55 | function source() { 56 | if [[ ! "${1}.zwc" -nt "${1}" ]]; then 57 | zcompile "${1}" 2>/dev/null 58 | fi 59 | 60 | builtin source "$1" 61 | } 62 | -------------------------------------------------------------------------------- /lib/init.zsh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | typeset -g _ZPM_autoload=() 3 | 4 | typeset -ag _ZPM_plugins_for_source 5 | typeset -ag _ZPM_plugins_for_async_source 6 | typeset -ag _ZPM_plugins_no_source 7 | 8 | typeset -Ag _ZPM_file_for_source 9 | typeset -Ag _ZPM_file_for_async_source 10 | 11 | 12 | autoload -Uz \ 13 | zpm \ 14 | @zpm-add-autoload \ 15 | @zpm-addfpath \ 16 | @zpm-addpath \ 17 | @zpm-async-source \ 18 | @zpm-background-initialization \ 19 | @zpm-clean \ 20 | @zpm-compile \ 21 | @zpm-get-plugin-autoload \ 22 | @zpm-get-plugin-basename \ 23 | @zpm-get-plugin-bin-path \ 24 | @zpm-get-plugin-file-path \ 25 | @zpm-get-plugin-functions-path \ 26 | @zpm-get-plugin-name \ 27 | @zpm-get-plugin-origin-type \ 28 | @zpm-get-plugin-path \ 29 | @zpm-initialize-plugin \ 30 | @zpm-launch-plugin-helper \ 31 | @zpm-load-plugins \ 32 | @zpm-log \ 33 | @zpm-no-source \ 34 | @zpm-source \ 35 | @zpm-upgrade 36 | -------------------------------------------------------------------------------- /plugins/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zpm-zsh/zpm/926ce79a14edf3b6fe64a1be873543c58ba8782a/plugins/.gitkeep -------------------------------------------------------------------------------- /tests/startup/bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | for i in $(seq 1 10); do time bash -i -c exit; done 3 | 4 | -------------------------------------------------------------------------------- /tests/startup/zsh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | for i in $(seq 1 10); do time zsh -i -c exit; done 3 | 4 | -------------------------------------------------------------------------------- /zpm.zsh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | # Zsh Plugin Standard compatibility 3 | # 0 – the plugin manager provides the ZERO parameter, 4 | # f - … supports the functions subdirectory, 5 | # b - … supports the bin subdirectory, 6 | # u - … the unload function, 7 | # U - … the @zsh-plugin-run-on-unload call, 8 | # p – … the @zsh-plugin-run-on-update call, 9 | # i – … the zsh_loaded_plugins activity indicator, 10 | # P – … the ZPFX global parameter, 11 | # s – … the PMSPEC global parameter itself (i.e.: should be always present). 12 | export PMSPEC="0fbs" 13 | 14 | 0="${${(M)0:#/*}:-$PWD/$0}" 15 | export _ZPM_DIR="${0:h}" 16 | 17 | export ZSH_TMP_DIR="${ZSH_TMP_DIR:-${TMPDIR:-/tmp}/zsh-${UID:-user}}" 18 | _ZPM_CACHE="${ZSH_TMP_DIR}/zpm-cache.zsh" 19 | _ZPM_CACHE_ASYNC="${ZSH_TMP_DIR}/zpm-cache-async.zsh" 20 | 21 | export ZSH_DATA_HOME="${ZSH_DATA_HOME:-${XDG_DATA_HOME:-$HOME/.local/share}/zsh}" 22 | _ZPM_PLUGINS_DIR="${ZSH_DATA_HOME}/plugins" 23 | _ZPM_PLUGIN_DIR="${ZSH_DATA_HOME}/plugins/zpm" 24 | 25 | export ZSH_CACHE_HOME="${ZSH_CACHE_HOME:-${XDG_CACHE_HOME:-$HOME/.cache}/zsh}" 26 | _ZPM_COMPDUMP="${ZSH_CACHE_HOME}/zcompdump-${ZSH_VERSION}" 27 | 28 | fpath=("${_ZPM_DIR}/functions" "${ZSH_TMP_DIR}/functions" $fpath) 29 | export PATH="${ZSH_TMP_DIR}/bin:$PATH" 30 | typeset -gaU path fpath 31 | 32 | autoload -Uz compinit 33 | 34 | if [[ -f "${_ZPM_CACHE}" ]]; then 35 | source "${_ZPM_CACHE}" 36 | else 37 | eval "$(<${_ZPM_DIR}/lib/init.zsh)" 38 | eval "$(<${_ZPM_DIR}/lib/imperative.zsh)" 39 | fi 40 | -------------------------------------------------------------------------------- /zshrc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | # Set xdg param XDG_DATA_HOME 4 | 5 | _ZPM_PLUGIN_FILE="${XDG_DATA_HOME:-$HOME/.local/share}/zsh/plugins/@zpm/zpm.zsh" 6 | source "$_ZPM_PLUGIN_FILE" 7 | 8 | ### OpenWrt 9 | zpm if openwrt load zpm-zsh/openwrt 10 | 11 | ### Termux 12 | zpm if termux load zpm-zsh/termux 13 | 14 | ### Tmux 15 | zpm if ssh load zpm-zsh/tmux 16 | zpm if-not ssh load zpm-zsh/tmux,apply:path 17 | 18 | ### VTE 19 | zpm if vte load zpm-zsh/vte 20 | 21 | ### MSYS 22 | zpm if msys load zpm-zsh/msys 23 | 24 | ### VSCode 25 | zpm if vscode load zpm-zsh/vscode 26 | 27 | ### iTerm2 28 | zpm if iterm load zpm-zsh/iterm 29 | 30 | ### 3party plugins 31 | zpm load \ 32 | zpm-zsh/core-config \ 33 | zpm-zsh/ignored-users,async \ 34 | zpm-zsh/check-deps,async \ 35 | zpm-zsh/minimal-theme \ 36 | zpm-zsh/dircolors-neutral,async \ 37 | zpm-zsh/fsh-theme-neutral,async \ 38 | zpm-zsh/ls,async \ 39 | zpm-zsh/colorize,async \ 40 | zpm-zsh/ssh,async \ 41 | zpm-zsh/dot,async \ 42 | zpm-zsh/undollar,async 43 | 44 | ### Plugins for local host 45 | zpm if-not ssh load \ 46 | mdumitru/fancy-ctrl-z,async \ 47 | voronkovich/gitignore.plugin.zsh,async \ 48 | zpm-zsh/autoenv,async \ 49 | zpm-zsh/bookmarks,async \ 50 | zpm-zsh/clipboard \ 51 | zpm-zsh/command-not-found,async \ 52 | zpm-zsh/dropbox,apply:path:fpath \ 53 | zpm-zsh/extract,async \ 54 | zpm-zsh/history-search-multi-word,async \ 55 | zpm-zsh/mysql-colorize,async \ 56 | zpm-zsh/rehash-on-usr1,async \ 57 | zpm-zsh/tmux-keys \ 58 | zpm-zsh/zsh-better-npm-completion,async \ 59 | zpm-zsh/zsh-completions \ 60 | zpm-zsh/zsh-history-substring-search,async \ 61 | zsh-users/zsh-autosuggestions,async \ 62 | zpm-zsh/fast-syntax-highlighting,async 63 | --------------------------------------------------------------------------------