diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 000000000..d3ad1a3a7
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,20 @@
+{
+ "image": "mcr.microsoft.com/devcontainers/base:noble",
+ "features": {
+ "ghcr.io/devcontainers/features/common-utils": {
+ "installZsh": true,
+ "configureZshAsDefaultShell": true,
+ "username": "vscode",
+ "userUid": 1000,
+ "userGid": 1000
+ }
+ },
+ "postCreateCommand": "dir=/workspaces/ohmyzsh; rm -rf $HOME/.oh-my-zsh && ln -s $dir $HOME/.oh-my-zsh && cp $dir/templates/minimal.zshrc $HOME/.zshrc && chgrp -R 1000 $dir && chmod g-w,o-w $dir",
+ "customizations": {
+ "codespaces": {
+ "openFiles": [
+ "README.md"
+ ]
+ }
+ }
+}
diff --git a/.editorconfig b/.editorconfig
index b349bcc42..797fb62d0 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -9,3 +9,7 @@ indent_style = space
[*.py]
indent_size = 4
+
+[devcontainer.json]
+indent_size = 4
+indent_style = tab
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 361ed624b..17e8b43cb 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -5,10 +5,15 @@ plugins/eza/ @pepoluan
plugins/genpass/ @atoponce
plugins/git-lfs/ @hellovietduc
plugins/gitfast/ @felipec
+plugins/kube-ps1/ @mcornella
+plugins/kubectl/ @mcornella
+plugins/kubectx/ @mcornella
+plugins/opentofu/ @mcornella
plugins/react-native @esthor
plugins/sdk/ @rgoldberg
plugins/shell-proxy/ @septs
plugins/starship/ @axieax
+plugins/terraform/ @mcornella
plugins/universalarchive/ @Konfekt
plugins/wp-cli/ @joshmedeski
plugins/zoxide/ @ajeetdsouza
diff --git a/.github/INCIDENT_RESPONSE_PLAN.md b/.github/INCIDENT_RESPONSE_PLAN.md
new file mode 100644
index 000000000..3f0b493c6
--- /dev/null
+++ b/.github/INCIDENT_RESPONSE_PLAN.md
@@ -0,0 +1,87 @@
+# Incident Response Plan
+
+## Reporting a Vulnerability
+
+Please see [the latest guidelines](https://github.com/ohmyzsh/ohmyzsh/blob/master/SECURITY.md) for instructions.
+
+## Phases
+
+### Triage
+
+1. Is this a valid security vulnerability?
+
+ - [ ] It affects our CI/CD or any of our repositories.
+ - [ ] For ohmyzsh/ohmyzsh, it affects the latest commit.
+ - [ ] For others, it affects the latest commit on the default branch.
+ - [ ] It affects a third-party dependency:
+ - [ ] Zsh or git
+ - [ ] For a plugin, the vulnerability is a result of our usage of the dependency.
+
+2. What's the scope of the vulnerability?
+
+ - [ ] Our codebase.
+ - [ ] A direct third-party dependency (Zsh, git, other plugins).
+ - [ ] An indirect third-party dependency.
+ - [ ] Out of scope, a third-party dependency that is the responsibility of the user.
+ - [ ] Out of scope, any other case (edit this plan and add the details).
+
+3. Is the vulnerability actionable?
+
+ - [ ] Yes, we can submit a fix.
+ - [ ] Yes, we can disable a feature.
+ - [ ] Yes, we can mitigate the risk.
+ - [ ] Yes, we can remove a vulnerable dependency.
+ - [ ] Yes, we can apply a workaround.
+ - [ ] Yes, we can apply a patch to a vulnerable dependency ([example for CVE-2021-45444](https://github.com/ohmyzsh/ohmyzsh/blob/cb72d7dcbf08b435c7f8a6470802b207b2aa02c3/lib/vcs_info.zsh)).
+ - [ ] No, the vulnerability is not actionable.
+
+4. What's the impact of the vulnerability?
+
+ Assess using the *CIA* triad:
+
+ - **Confidentiality**: example: report or sharing of secrets.
+ - **Integrity**: affects the integrity of the system (deletion, corruption or encryption of data, OS file corruption, etc.).
+ - **Availability**: denial of login, deletion of required files to boot / login, etc.
+
+5. What's the exploitability of the vulnerability?
+
+ Consider how easy it is to exploit, and if it affects all users or requires specific configurations.
+
+6. What's the severity of the vulnerability?
+
+ You can use the [CVSS v3.1](https://www.first.org/cvss/specification-document) to assess the severity of the vulnerability.
+
+7. When was the vulnerability introduced?
+
+ - Find the responsible code path.
+ - Find the commit or Pull Request that introduced the vulnerability.
+
+8. Who are our security contacts?
+
+ Assess upstream or downstream contacts, and their desired channels of security.
+
+ > TODO: add a list of contacts.
+
+### Mitigation
+
+- **Primary focus:** removing possibility of exploitation fast.
+- **Secondary focus:** addressing the root cause.
+
+> [!IMPORTANT]
+> Make sure to test that the mitigation works as expected, and does not introduce new vulnerabilities.
+> When deploying a patch, make sure not to disclose the vulnerability in the commit message or PR description.
+
+> TODO: introduce a fast-track update process for security patches.
+
+### Disclosure
+
+Primary goal: inform our users about the vulnerability, and whether they are affected or not affected based on information they should be able to check themselves in a straightforward way.
+
+> TODO: add a vulnerability disclosure template.
+
+### Learn
+
+- Document the vulnerability, steps performed, and lessons learned.
+- Document the timeline of events.
+- Document and address improvements on the Security Incident Response Plan.
+- Depending on the severity of the vulnerability, consider disclosing the root cause or not based on likely impact on users and estimated potential victims still affected.
diff --git a/.github/dependencies.yml b/.github/dependencies.yml
index be2d02cd8..b67a4c7ed 100644
--- a/.github/dependencies.yml
+++ b/.github/dependencies.yml
@@ -2,11 +2,13 @@ dependencies:
plugins/gitfast:
repo: felipec/git-completion
branch: master
- version: tag:v2.1
+ version: tag:v2.2
postcopy: |
set -e
- rm -rf git-completion.plugin.zsh Makefile README.adoc t tools
- test -e git-completion.zsh && mv -f git-completion.zsh _git
+ rm -rf git-completion.plugin.zsh Makefile t tools
+ mv README.adoc MANUAL.adoc
+ mv -f src/* .
+ rmdir src
plugins/gradle:
repo: gradle/gradle-completion
branch: master
@@ -28,7 +30,7 @@ dependencies:
plugins/wd:
repo: mfaerevaag/wd
branch: master
- version: tag:v0.7.1
+ version: tag:v0.10.1
precopy: |
set -e
rm -r test
@@ -36,7 +38,7 @@ dependencies:
plugins/z:
branch: master
repo: agkozak/zsh-z
- version: afaf2965b41fdc6ca66066e09382726aa0b6aa04
+ version: cf9225feebfae55e557e103e95ce20eca5eff270
precopy: |
set -e
test -e README.md && mv -f README.md MANUAL.md
diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml
index 6c7387089..0b8eeda93 100644
--- a/.github/workflows/dependencies.yml
+++ b/.github/workflows/dependencies.yml
@@ -4,6 +4,9 @@ on:
schedule:
- cron: "0 6 * * 0"
+permissions:
+ contents: read
+
jobs:
check:
name: Check for updates
@@ -15,11 +18,11 @@ jobs:
with:
fetch-depth: 0
- name: Authenticate as @ohmyzsh
- id: generate_token
- uses: ohmyzsh/github-app-token@v2
+ id: generate-token
+ uses: actions/create-github-app-token@v2
with:
- app_id: ${{ secrets.OHMYZSH_APP_ID }}
- private_key: ${{ secrets.OHMYZSH_APP_PRIVATE_KEY }}
+ app-id: ${{ secrets.OHMYZSH_APP_ID }}
+ private-key: ${{ secrets.OHMYZSH_APP_PRIVATE_KEY }}
- name: Setup Python
uses: actions/setup-python@v5
with:
@@ -27,7 +30,7 @@ jobs:
cache: "pip"
- name: Process dependencies
env:
- GH_TOKEN: ${{ steps.generate_token.outputs.token }}
+ GH_TOKEN: ${{ steps.generate-token.outputs.token }}
GIT_APP_NAME: ohmyzsh[bot]
GIT_APP_EMAIL: 54982679+ohmyzsh[bot]@users.noreply.github.com
TMP_DIR: ${{ runner.temp }}
diff --git a/.github/workflows/dependencies/requirements.txt b/.github/workflows/dependencies/requirements.txt
index f125da542..167f9df8f 100644
--- a/.github/workflows/dependencies/requirements.txt
+++ b/.github/workflows/dependencies/requirements.txt
@@ -1,7 +1,7 @@
-certifi==2024.7.4
-charset-normalizer==3.3.2
-idna==3.7
-PyYAML==6.0.1
-requests==2.32.3
-semver==3.0.2
-urllib3==2.2.2
+certifi==2025.7.14
+charset-normalizer==3.4.3
+idna==3.10
+PyYAML==6.0.2
+requests==2.32.4
+semver==3.0.4
+urllib3==2.5.0
diff --git a/.github/workflows/dependencies/updater.py b/.github/workflows/dependencies/updater.py
index f85c9eda7..02cff9030 100644
--- a/.github/workflows/dependencies/updater.py
+++ b/.github/workflows/dependencies/updater.py
@@ -228,7 +228,7 @@ class Dependency:
self.__apply_upstream_changes()
# Add all changes and commit
- has_new_commit = Git.add_and_commit(self.name, short_sha)
+ has_new_commit = Git.add_and_commit(self.name, new_version)
if has_new_commit:
# Push changes to remote
diff --git a/.github/workflows/installer/vercel.json b/.github/workflows/installer/vercel.json
index 524dc3c0f..88ec18725 100644
--- a/.github/workflows/installer/vercel.json
+++ b/.github/workflows/installer/vercel.json
@@ -1,7 +1,7 @@
{
"headers": [
{
- "source": "/((?!favicon.ico).*)",
+ "source": "/(|install.sh)",
"headers": [
{
"key": "Content-Type",
@@ -16,7 +16,7 @@
],
"rewrites": [
{
- "source": "/((?!favicon.ico|install.sh).*)",
+ "source": "/",
"destination": "/install.sh"
}
]
diff --git a/.github/workflows/project.yml b/.github/workflows/project.yml
index 2c2a1cdaa..8fd4e15d4 100644
--- a/.github/workflows/project.yml
+++ b/.github/workflows/project.yml
@@ -17,13 +17,13 @@ jobs:
if: github.repository == 'ohmyzsh/ohmyzsh'
steps:
- name: Authenticate as @ohmyzsh
- id: generate_token
- uses: ohmyzsh/github-app-token@v2
+ id: generate-token
+ uses: actions/create-github-app-token@v2
with:
- app_id: ${{ secrets.OHMYZSH_APP_ID }}
- private_key: ${{ secrets.OHMYZSH_APP_PRIVATE_KEY }}
+ app-id: ${{ secrets.OHMYZSH_APP_ID }}
+ private-key: ${{ secrets.OHMYZSH_APP_PRIVATE_KEY }}
- name: Store app token
- run: echo "GH_TOKEN=${{ steps.generate_token.outputs.token }}" >> "$GITHUB_ENV"
+ run: echo "GH_TOKEN=${{ steps.generate-token.outputs.token }}" >> "$GITHUB_ENV"
- name: Read project data
env:
ORGANIZATION: ohmyzsh
diff --git a/.gitignore b/.gitignore
index 10bd4bebc..a53da3b3e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,6 @@ log/
# editor configs
.vscode
.idea
+
+# zcompile cached files
+*.zwc
diff --git a/README.md b/README.md
index dc4f36864..7f57ed55e 100644
--- a/README.md
+++ b/README.md
@@ -1,16 +1,21 @@

-Oh My Zsh is an open source, community-driven framework for managing your [zsh](https://www.zsh.org/) configuration.
+Oh My Zsh is an open source, community-driven framework for managing your [zsh](https://www.zsh.org/)
+configuration.
Sounds boring. Let's try again.
**Oh My Zsh will not make you a 10x developer...but you may feel like one.**
-Once installed, your terminal shell will become the talk of the town _or your money back!_ With each keystroke in your command prompt, you'll take advantage of the hundreds of powerful plugins and beautiful themes. Strangers will come up to you in cafés and ask you, _"that is amazing! are you some sort of genius?"_
+Once installed, your terminal shell will become the talk of the town _or your money back!_ With each keystroke
+in your command prompt, you'll take advantage of the hundreds of powerful plugins and beautiful themes.
+Strangers will come up to you in cafés and ask you, _"that is amazing! are you some sort of genius?"_
-Finally, you'll begin to get the sort of attention that you have always felt you deserved. ...or maybe you'll use the time that you're saving to start flossing more often. 😬
+Finally, you'll begin to get the sort of attention that you have always felt you deserved. ...or maybe you'll
+use the time that you're saving to start flossing more often. 😬
-To learn more, visit [ohmyz.sh](https://ohmyz.sh), follow [@ohmyzsh](https://x.com/ohmyzsh) on X (formerly Twitter), and join us on [Discord](https://discord.gg/ohmyzsh).
+To learn more, visit [ohmyz.sh](https://ohmyz.sh), follow [@ohmyzsh](https://x.com/ohmyzsh) on X (formerly
+Twitter), and join us on [Discord](https://discord.gg/ohmyzsh).
[](https://github.com/ohmyzsh/ohmyzsh/actions?query=workflow%3ACI)
[](https://twitter.com/intent/follow?screen_name=ohmyzsh)
@@ -43,7 +48,7 @@ To learn more, visit [ohmyz.sh](https://ohmyz.sh), follow [@ohmyzsh](https://x.c
- [Custom Plugins And Themes](#custom-plugins-and-themes)
- [Enable GNU ls In macOS And freeBSD Systems](#enable-gnu-ls-in-macos-and-freebsd-systems)
- [Skip Aliases](#skip-aliases)
- - [Disable async git prompt](#disable-async-git-prompt)
+ - [Async git prompt](#async-git-prompt)
- [Getting Updates](#getting-updates)
- [Updates Verbosity](#updates-verbosity)
- [Manual Updates](#manual-updates)
@@ -62,26 +67,28 @@ To learn more, visit [ohmyz.sh](https://ohmyz.sh), follow [@ohmyzsh](https://x.c
### Operating System Compatibility
-| O/S | Status |
-| :------------- | :-----: |
-| Android | ✅ |
-| freeBSD | ✅ |
-| LCARS | 🛸 |
-| Linux | ✅ |
-| macOS | ✅ |
-| OS/2 Warp | ❌ |
-| Windows (WSL2) | ✅ |
-
+| O/S | Status |
+| :------------- | :----: |
+| Android | ✅ |
+| freeBSD | ✅ |
+| LCARS | 🛸 |
+| Linux | ✅ |
+| macOS | ✅ |
+| OS/2 Warp | ❌ |
+| Windows (WSL2) | ✅ |
### Prerequisites
-- [Zsh](https://www.zsh.org) should be installed (v4.3.9 or more recent is fine but we prefer 5.0.8 and newer). If not pre-installed (run `zsh --version` to confirm), check the following wiki instructions here: [Installing ZSH](https://github.com/ohmyzsh/ohmyzsh/wiki/Installing-ZSH)
+- [Zsh](https://www.zsh.org) should be installed (v4.3.9 or more recent is fine but we prefer 5.0.8 and
+ newer). If not pre-installed (run `zsh --version` to confirm), check the following wiki instructions here:
+ [Installing ZSH](https://github.com/ohmyzsh/ohmyzsh/wiki/Installing-ZSH)
- `curl` or `wget` should be installed
- `git` should be installed (recommended v2.4.11 or higher)
### Basic Installation
-Oh My Zsh is installed by running one of the following commands in your terminal. You can install this via the command-line with either `curl`, `wget` or another similar tool.
+Oh My Zsh is installed by running one of the following commands in your terminal. You can install this via the
+command-line with either `curl`, `wget` or another similar tool.
| Method | Command |
| :-------- | :------------------------------------------------------------------------------------------------ |
@@ -89,38 +96,44 @@ Oh My Zsh is installed by running one of the following commands in your terminal
| **wget** | `sh -c "$(wget -O- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"` |
| **fetch** | `sh -c "$(fetch -o - https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"` |
-Alternatively, the installer is also mirrored outside GitHub. Using this URL instead may be required if you're in a country like China or India (for certain ISPs), that blocks `raw.githubusercontent.com`:
+Alternatively, the installer is also mirrored outside GitHub. Using this URL instead may be required if you're
+in a country like China or India (for certain ISPs), that blocks `raw.githubusercontent.com`:
-| Method | Command |
-| :-------- | :------------------------------------------------------------------------------------------------ |
-| **curl** | `sh -c "$(curl -fsSL https://install.ohmyz.sh/)"` |
-| **wget** | `sh -c "$(wget -O- https://install.ohmyz.sh/)"` |
-| **fetch** | `sh -c "$(fetch -o - https://install.ohmyz.sh/)"` |
+| Method | Command |
+| :-------- | :------------------------------------------------ |
+| **curl** | `sh -c "$(curl -fsSL https://install.ohmyz.sh/)"` |
+| **wget** | `sh -c "$(wget -O- https://install.ohmyz.sh/)"` |
+| **fetch** | `sh -c "$(fetch -o - https://install.ohmyz.sh/)"` |
-_Note that any previous `.zshrc` will be renamed to `.zshrc.pre-oh-my-zsh`. After installation, you can move the configuration you want to preserve into the new `.zshrc`._
+_Note that any previous `.zshrc` will be renamed to `.zshrc.pre-oh-my-zsh`. After installation, you can move
+the configuration you want to preserve into the new `.zshrc`._
#### Manual Inspection
-It's a good idea to inspect the install script from projects you don't yet know. You can do
-that by downloading the install script first, looking through it so everything looks normal,
-then running it:
+It's a good idea to inspect the install script from projects you don't yet know. You can do that by
+downloading the install script first, looking through it so everything looks normal, then running it:
```sh
wget https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh
sh install.sh
```
-If the above URL times out or otherwise fails, you may have to substitute the URL for `https://install.ohmyz.sh` to be able to get the script.
+If the above URL times out or otherwise fails, you may have to substitute the URL for
+`https://install.ohmyz.sh` to be able to get the script.
## Using Oh My Zsh
### Plugins
-Oh My Zsh comes with a shitload of plugins for you to take advantage of. You can take a look in the [plugins](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins) directory and/or the [wiki](https://github.com/ohmyzsh/ohmyzsh/wiki/Plugins) to see what's currently available.
+Oh My Zsh comes with a shitload of plugins for you to take advantage of. You can take a look in the
+[plugins](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins) directory and/or the
+[wiki](https://github.com/ohmyzsh/ohmyzsh/wiki/Plugins) to see what's currently available.
#### Enabling Plugins
-Once you spot a plugin (or several) that you'd like to use with Oh My Zsh, you'll need to enable them in the `.zshrc` file. You'll find the zshrc file in your `$HOME` directory. Open it with your favorite text editor and you'll see a spot to list all the plugins you want to load.
+Once you spot a plugin (or several) that you'd like to use with Oh My Zsh, you'll need to enable them in the
+`.zshrc` file. You'll find the zshrc file in your `$HOME` directory. Open it with your favorite text editor
+and you'll see a spot to list all the plugins you want to load.
```sh
vi ~/.zshrc
@@ -140,21 +153,28 @@ plugins=(
)
```
-_Note that the plugins are separated by whitespace (spaces, tabs, new lines...). **Do not** use commas between them or it will break._
+_Note that the plugins are separated by whitespace (spaces, tabs, new lines...). **Do not** use commas between
+them or it will break._
#### Using Plugins
-Each built-in plugin includes a **README**, documenting it. This README should show the aliases (if the plugin adds any) and extra goodies that are included in that particular plugin.
+Each built-in plugin includes a **README**, documenting it. This README should show the aliases (if the plugin
+adds any) and extra goodies that are included in that particular plugin.
### Themes
-We'll admit it. Early in the Oh My Zsh world, we may have gotten a bit too theme happy. We have over one hundred and fifty themes now bundled. Most of them have [screenshots](https://github.com/ohmyzsh/ohmyzsh/wiki/Themes) on the wiki (We are working on updating this!). Check them out!
+We'll admit it. Early in the Oh My Zsh world, we may have gotten a bit too theme-happy. We have over one
+hundred and fifty themes now bundled. Most of them have
+[screenshots](https://github.com/ohmyzsh/ohmyzsh/wiki/Themes) on the wiki (We are working on updating this!).
+Check them out!
#### Selecting A Theme
-_Robby's theme is the default one. It's not the fanciest one. It's not the simplest one. It's just the right one (for him)._
+_Robby's theme is the default one. It's not the fanciest one. It's not the simplest one. It's just the right
+one (for him)._
-Once you find a theme that you'd like to use, you will need to edit the `~/.zshrc` file. You'll see an environment variable (all caps) in there that looks like:
+Once you find a theme that you'd like to use, you will need to edit the `~/.zshrc` file. You'll see an
+environment variable (all caps) in there that looks like:
```sh
ZSH_THEME="robbyrussell"
@@ -167,21 +187,38 @@ ZSH_THEME="agnoster" # (this is one of the fancy ones)
# see https://github.com/ohmyzsh/ohmyzsh/wiki/Themes#agnoster
```
-_Note: many themes require installing a [Powerline Font](https://github.com/powerline/fonts) or a [Nerd Font](https://github.com/ryanoasis/nerd-fonts) in order to render properly. Without them, these themes will render [weird prompt symbols](https://github.com/ohmyzsh/ohmyzsh/wiki/FAQ#i-have-a-weird-character-in-my-prompt)_
+
+> [!NOTE]
+> You will many times see screenshots for a zsh theme, and try it out, and find that it doesn't look the same for you.
+>
+> This is because many themes require installing a [Powerline Font](https://github.com/powerline/fonts) or a
+> [Nerd Font](https://github.com/ryanoasis/nerd-fonts) in order to render properly. Without them, these themes
+> will render weird prompt symbols. Check out
+> [the FAQ](https://github.com/ohmyzsh/ohmyzsh/wiki/FAQ#i-have-a-weird-character-in-my-prompt) for more
+> information.
+>
+> Also, beware that themes only control what your prompt looks like. This is, the text you see before or after
+> your cursor, where you'll type your commands. Themes don't control things such as the colors of your
+> terminal window (known as _color scheme_) or the font of your terminal. These are settings that you can
+> change in your terminal emulator. For more information, see
+> [what is a zsh theme](https://github.com/ohmyzsh/ohmyzsh/wiki/FAQ#what-is-a-zsh-theme).
+
Open up a new terminal window and your prompt should look something like this:

-In case you did not find a suitable theme for your needs, please have a look at the wiki for [more of them](https://github.com/ohmyzsh/ohmyzsh/wiki/External-themes).
+In case you did not find a suitable theme for your needs, please have a look at the wiki for
+[more of them](https://github.com/ohmyzsh/ohmyzsh/wiki/External-themes).
-If you're feeling feisty, you can let the computer select one randomly for you each time you open a new terminal window.
+If you're feeling feisty, you can let the computer select one randomly for you each time you open a new
+terminal window.
```sh
ZSH_THEME="random" # (...please let it be pie... please be some pie..)
```
-And if you want to pick random theme from a list of your favorite themes:
+And if you want to pick a random theme from a list of your favorite themes:
```sh
ZSH_THEME_RANDOM_CANDIDATES=(
@@ -198,7 +235,8 @@ ZSH_THEME_RANDOM_IGNORED=(pygmalion tjkirch_mod)
### FAQ
-If you have some more questions or issues, you might find a solution in our [FAQ](https://github.com/ohmyzsh/ohmyzsh/wiki/FAQ).
+If you have some more questions or issues, you might find a solution in our
+[FAQ](https://github.com/ohmyzsh/ohmyzsh/wiki/FAQ).
## Advanced Topics
@@ -206,16 +244,16 @@ If you're the type that likes to get their hands dirty, these sections might res
### Advanced Installation
-Some users may want to manually install Oh My Zsh, or change the default path or other settings that
-the installer accepts (these settings are also documented at the top of the install script).
+Some users may want to manually install Oh My Zsh, or change the default path or other settings that the
+installer accepts (these settings are also documented at the top of the install script).
#### Custom Directory
-The default location is `~/.oh-my-zsh` (hidden in your home directory, you can access it with `cd ~/.oh-my-zsh`)
+The default location is `~/.oh-my-zsh` (hidden in your home directory, you can access it with
+`cd ~/.oh-my-zsh`)
If you'd like to change the install directory with the `ZSH` environment variable, either by running
-`export ZSH=/your/path` before installing, or by setting it before the end of the install pipeline
-like this:
+`export ZSH=/your/path` before installing, or by setting it before the end of the install pipeline like this:
```sh
ZSH="$HOME/.dotfiles/oh-my-zsh" sh install.sh
@@ -223,32 +261,33 @@ ZSH="$HOME/.dotfiles/oh-my-zsh" sh install.sh
#### Unattended Install
-If you're running the Oh My Zsh install script as part of an automated install, you can pass the `--unattended`
-flag to the `install.sh` script. This will have the effect of not trying to change
-the default shell, and it also won't run `zsh` when the installation has finished.
+If you're running the Oh My Zsh install script as part of an automated install, you can pass the
+`--unattended` flag to the `install.sh` script. This will have the effect of not trying to change the default
+shell, and it also won't run `zsh` when the installation has finished.
```sh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended
```
-If you're in China, India, or another country that blocks `raw.githubusercontent.com`, you may have to substitute the URL for `https://install.ohmyz.sh` for it to install.
+If you're in China, India, or another country that blocks `raw.githubusercontent.com`, you may have to
+substitute the URL for `https://install.ohmyz.sh` for it to install.
#### Installing From A Forked Repository
The install script also accepts these variables to allow the installation of a different repository:
-- `REPO` (default: `ohmyzsh/ohmyzsh`): this takes the form of `owner/repository`. If you set
- this variable, the installer will look for a repository at `https://github.com/{owner}/{repository}`.
+- `REPO` (default: `ohmyzsh/ohmyzsh`): this takes the form of `owner/repository`. If you set this variable,
+ the installer will look for a repository at `https://github.com/{owner}/{repository}`.
-- `REMOTE` (default: `https://github.com/${REPO}.git`): this is the full URL of the git repository
- clone. You can use this setting if you want to install from a fork that is not on GitHub (GitLab,
- Bitbucket...) or if you want to clone with SSH instead of HTTPS (`git@github.com:user/project.git`).
+- `REMOTE` (default: `https://github.com/${REPO}.git`): this is the full URL of the git repository clone. You
+ can use this setting if you want to install from a fork that is not on GitHub (GitLab, Bitbucket...) or if
+ you want to clone with SSH instead of HTTPS (`git@github.com:user/project.git`).
_NOTE: it's incompatible with setting the `REPO` variable. This setting will take precedence._
- `BRANCH` (default: `master`): you can use this setting if you want to change the default branch to be
- checked out when cloning the repository. This might be useful for testing a Pull Request, or if you
- want to use a branch other than `master`.
+ checked out when cloning the repository. This might be useful for testing a Pull Request, or if you want to
+ use a branch other than `master`.
For example:
@@ -294,16 +333,21 @@ Once you open up a new terminal window, it should load zsh with Oh My Zsh's conf
If you have any hiccups installing, here are a few common fixes.
-- You _might_ need to modify your `PATH` in `~/.zshrc` if you're not able to find some commands after switching to `oh-my-zsh`.
-- If you installed manually or changed the install location, check the `ZSH` environment variable in `~/.zshrc`.
+- You _might_ need to modify your `PATH` in `~/.zshrc` if you're not able to find some commands after
+ switching to `oh-my-zsh`.
+- If you installed manually or changed the install location, check the `ZSH` environment variable in
+ `~/.zshrc`.
### Custom Plugins And Themes
-If you want to override any of the default behaviors, just add a new file (ending in `.zsh`) in the `custom/` directory.
+If you want to override any of the default behaviors, just add a new file (ending in `.zsh`) in the `custom/`
+directory.
-If you have many functions that go well together, you can put them as a `XYZ.plugin.zsh` file in the `custom/plugins/` directory and then enable this plugin.
+If you have many functions that go well together, you can put them as a `XYZ.plugin.zsh` file in the
+`custom/plugins/` directory and then enable this plugin.
-If you would like to override the functionality of a plugin distributed with Oh My Zsh, create a plugin of the same name in the `custom/plugins/` directory and it will be loaded instead of the one in `plugins/`.
+If you would like to override the functionality of a plugin distributed with Oh My Zsh, create a plugin of the
+same name in the `custom/plugins/` directory and it will be loaded instead of the one in `plugins/`.
### Enable GNU ls In macOS And freeBSD Systems
@@ -323,9 +367,9 @@ _Note: this is not compatible with `DISABLE_LS_COLORS=true`_
-If you want to skip default Oh My Zsh aliases (those defined in `lib/*` files) or plugin aliases,
-you can use the settings below in your `~/.zshrc` file, **before Oh My Zsh is loaded**. Note that
-there are many different ways to skip aliases, depending on your needs.
+If you want to skip default Oh My Zsh aliases (those defined in `lib/*` files) or plugin aliases, you can use
+the settings below in your `~/.zshrc` file, **before Oh My Zsh is loaded**. Note that there are many different
+ways to skip aliases, depending on your needs.
```sh
# Skip all aliases, in lib files and enabled plugins
@@ -364,27 +408,36 @@ zstyle ':omz:lib:directories' aliases no
#### Notice
-> This feature is currently in a testing phase and it may be subject to change in the future.
-> It is also not currently compatible with plugin managers such as zpm or zinit, which don't
-> source the init script (`oh-my-zsh.sh`) where this feature is implemented in.
+> This feature is currently in a testing phase and it may be subject to change in the future. It is also not
+> currently compatible with plugin managers such as zpm or zinit, which don't source the init script
+> (`oh-my-zsh.sh`) where this feature is implemented in.
-> It is also not currently aware of "aliases" that are defined as functions. Example of such
-> are `gccd`, `ggf`, or `ggl` functions from the git plugin.
+> It is also not currently aware of "aliases" that are defined as functions. Example of such are `gccd`,
+> `ggf`, or `ggl` functions from the git plugin.
-### Disable async git prompt
+### Async git prompt
-Async prompt functions are an experimental feature (included on April 3, 2024) that allows Oh My Zsh to render prompt information
-asynchronously. This can improve prompt rendering performance, but it might not work well with some setups. We hope that's not an
-issue, but if you're seeing problems with this new feature, you can turn it off by setting the following in your .zshrc file,
-before Oh My Zsh is sourced:
+Async prompt functions are an experimental feature (included on April 3, 2024) that allows Oh My Zsh to render
+prompt information asynchronously. This can improve prompt rendering performance, but it might not work well
+with some setups. We hope that's not an issue, but if you're seeing problems with this new feature, you can
+turn it off by setting the following in your .zshrc file, before Oh My Zsh is sourced:
```sh
zstyle ':omz:alpha:lib:git' async-prompt no
```
+If your problem is that the git prompt just stopped appearing, you can try to force it by setting the following
+configuration before `oh-my-zsh.sh` is sourced. If it still does not work, please open an issue with your
+case.
+
+```sh
+zstyle ':omz:alpha:lib:git' async-prompt force
+```
+
## Getting Updates
-By default, you will be prompted to check for updates every 2 weeks. You can choose other update modes by adding a line to your `~/.zshrc` file, **before Oh My Zsh is loaded**:
+By default, you will be prompted to check for updates every 2 weeks. You can choose other update modes by
+adding a line to your `~/.zshrc` file, **before Oh My Zsh is loaded**:
1. Automatic update without confirmation prompt:
@@ -427,37 +480,55 @@ zstyle ':omz:update' verbose silent # only errors
### Manual Updates
-If you'd like to update at any point in time (maybe someone just released a new plugin and you don't want to wait a week?) you just need to run:
+If you'd like to update at any point in time (maybe someone just released a new plugin and you don't want to
+wait a week?) you just need to run:
```sh
omz update
```
+> [!NOTE]
+> If you want to automate this process in a script, you should call directly the `upgrade` script, like this:
+>
+> ```sh
+> $ZSH/tools/upgrade.sh
+> ```
+>
+> See more options in the [FAQ: How do I update Oh My Zsh?](https://github.com/ohmyzsh/ohmyzsh/wiki/FAQ#how-do-i-update-oh-my-zsh).
+>
+> **USE OF `omz update --unattended` HAS BEEN REMOVED, AS IT HAS SIDE EFFECTS**.
+
Magic! 🎉
## Uninstalling Oh My Zsh
Oh My Zsh isn't for everyone. We'll miss you, but we want to make this an easy breakup.
-If you want to uninstall `oh-my-zsh`, just run `uninstall_oh_my_zsh` from the command-line. It will remove itself and revert your previous `bash` or `zsh` configuration.
+If you want to uninstall `oh-my-zsh`, just run `uninstall_oh_my_zsh` from the command-line. It will remove
+itself and revert your previous `bash` or `zsh` configuration.
## How Do I Contribute To Oh My Zsh?
Before you participate in our delightful community, please read the [code of conduct](CODE_OF_CONDUCT.md).
-I'm far from being a [Zsh](https://www.zsh.org/) expert and suspect there are many ways to improve – if you have ideas on how to make the configuration easier to maintain (and faster), don't hesitate to fork and send pull requests!
+I'm far from being a [Zsh](https://www.zsh.org/) expert and suspect there are many ways to improve – if you
+have ideas on how to make the configuration easier to maintain (and faster), don't hesitate to fork and send
+pull requests!
-We also need people to test out pull requests. So take a look through [the open issues](https://github.com/ohmyzsh/ohmyzsh/issues) and help where you can.
+We also need people to test out pull requests. So take a look through
+[the open issues](https://github.com/ohmyzsh/ohmyzsh/issues) and help where you can.
See [Contributing](CONTRIBUTING.md) for more details.
### Do Not Send Us Themes
-We have (more than) enough themes for the time being. Please add your theme to the [external themes](https://github.com/ohmyzsh/ohmyzsh/wiki/External-themes) wiki page.
+We have (more than) enough themes for the time being. Please add your theme to the
+[external themes](https://github.com/ohmyzsh/ohmyzsh/wiki/External-themes) wiki page.
## Contributors
-Oh My Zsh has a vibrant community of happy users and delightful contributors. Without all the time and help from our contributors, it wouldn't be so awesome.
+Oh My Zsh has a vibrant community of happy users and delightful contributors. Without all the time and help
+from our contributors, it wouldn't be so awesome.
Thank you so much!
@@ -476,7 +547,9 @@ We're on social media:
## Merchandise
-We have [stickers, shirts, and coffee mugs available](https://shop.planetargon.com/collections/oh-my-zsh?utm_source=github) for you to show off your love of Oh My Zsh. Again, you will become the talk of the town!
+We have
+[stickers, shirts, and coffee mugs available](https://shop.planetargon.com/collections/oh-my-zsh?utm_source=github)
+for you to show off your love of Oh My Zsh. Again, you will become the talk of the town!
## License
@@ -486,4 +559,6 @@ Oh My Zsh is released under the [MIT license](LICENSE.txt).

-Oh My Zsh was started by the team at [Planet Argon](https://www.planetargon.com/?utm_source=github), a [Ruby on Rails development agency](https://www.planetargon.com/services/ruby-on-rails-development?utm_source=github). Check out our [other open source projects](https://www.planetargon.com/open-source?utm_source=github).
+Oh My Zsh was started by the team at [Planet Argon](https://www.planetargon.com/?utm_source=github), a
+[Ruby on Rails development agency](https://www.planetargon.com/services/ruby-on-rails-development?utm_source=github).
+Check out our [other open source projects](https://www.planetargon.com/open-source?utm_source=github).
diff --git a/lib/async_prompt.zsh b/lib/async_prompt.zsh
index db48446e7..151e24b8c 100644
--- a/lib/async_prompt.zsh
+++ b/lib/async_prompt.zsh
@@ -26,7 +26,7 @@ autoload -Uz is-at-least
# This API is subject to change and optimization. Rely on it at your own risk.
function _omz_register_handler {
- setopt localoptions noksharrays
+ setopt localoptions noksharrays unset
typeset -ga _omz_async_functions
# we want to do nothing if there's no $1 function or we already set it up
if [[ -z "$1" ]] || (( ! ${+functions[$1]} )) \
@@ -44,6 +44,7 @@ function _omz_register_handler {
# Set up async handlers and callbacks
function _omz_async_request {
+ setopt localoptions noksharrays unset
local -i ret=$?
typeset -gA _OMZ_ASYNC_FDS _OMZ_ASYNC_PIDS _OMZ_ASYNC_OUTPUT
diff --git a/lib/bzr.zsh b/lib/bzr.zsh
index 005a16500..78273d578 100644
--- a/lib/bzr.zsh
+++ b/lib/bzr.zsh
@@ -1,10 +1,14 @@
## Bazaar integration
-## Just works with the GIT integration just add $(bzr_prompt_info) to the PROMPT
+## Just works with the GIT integration. Add $(bzr_prompt_info) to the PROMPT
function bzr_prompt_info() {
- BZR_CB=`bzr nick 2> /dev/null | grep -v "ERROR" | cut -d ":" -f2 | awk -F / '{print "bzr::"$1}'`
- if [ -n "$BZR_CB" ]; then
- BZR_DIRTY=""
- [[ -n `bzr status` ]] && BZR_DIRTY=" %{$fg[red]%} * %{$fg[green]%}"
- echo "$ZSH_THEME_SCM_PROMPT_PREFIX$BZR_CB$BZR_DIRTY$ZSH_THEME_GIT_PROMPT_SUFFIX"
- fi
-}
\ No newline at end of file
+ local bzr_branch
+ bzr_branch=$(bzr nick 2>/dev/null) || return
+
+ if [[ -n "$bzr_branch" ]]; then
+ local bzr_dirty=""
+ if [[ -n $(bzr status 2>/dev/null) ]]; then
+ bzr_dirty=" %{$fg[red]%}*%{$reset_color%}"
+ fi
+ printf "%s%s%s%s" "$ZSH_THEME_SCM_PROMPT_PREFIX" "bzr::${bzr_branch##*:}" "$bzr_dirty" "$ZSH_THEME_GIT_PROMPT_SUFFIX"
+ fi
+}
diff --git a/lib/cli.zsh b/lib/cli.zsh
index 383b0cfb0..0b144e4e7 100644
--- a/lib/cli.zsh
+++ b/lib/cli.zsh
@@ -1,6 +1,7 @@
#!/usr/bin/env zsh
function omz {
+ setopt localoptions noksharrays
[[ $# -gt 0 ]] || {
_omz::help
return 1
@@ -71,6 +72,10 @@ function _omz {
local -aU plugins
plugins=("$ZSH"/plugins/*/{_*,*.plugin.zsh}(-.N:h:t) "$ZSH_CUSTOM"/plugins/*/{_*,*.plugin.zsh}(-.N:h:t))
_describe 'plugin' plugins ;;
+ plugin::list)
+ local -a opts
+ opts=('--enabled:List enabled plugins only')
+ _describe -o 'options' opts ;;
theme::(set|use))
local -aU themes
themes=("$ZSH"/themes/*.zsh-theme(-.N:t:r) "$ZSH_CUSTOM"/**/*.zsh-theme(-.N:r:gs:"$ZSH_CUSTOM"/themes/:::gs:"$ZSH_CUSTOM"/:::))
@@ -192,7 +197,7 @@ EOF
return 1
fi
- "$ZSH/tools/changelog.sh" "$version" "${2:-}" "$format"
+ ZSH="$ZSH" command zsh -f "$ZSH/tools/changelog.sh" "$version" "${2:-}" "$format"
}
function _omz::plugin {
@@ -205,7 +210,7 @@ Available commands:
disable Disable plugin(s)
enable Enable plugin(s)
info Get information of a plugin
- list List all available Oh My Zsh plugins
+ list [--enabled] List Oh My Zsh plugins
load Load plugin(s)
EOF
@@ -344,20 +349,40 @@ function _omz::plugin::enable {
next
}
-# if plugins=() is in multiline form, enable multi flag
+# if plugins=() is in multiline form, enable multi flag and indent by default with 2 spaces
/^[ \t]*plugins=\(/ {
multi=1
+ indent=\" \"
+ print \$0
+ next
}
# if multi flag is enabled and we find a valid closing parenthesis,
-# add new plugins and disable multi flag
+# add new plugins with proper indent and disable multi flag
multi == 1 && /^[^#]*\)/ {
multi=0
- sub(/\)/, \" $add_plugins&\")
+ split(\"$add_plugins\",p,\" \")
+ for (i in p) {
+ print indent p[i]
+ }
print \$0
next
}
+# if multi flag is enabled and we didnt find a closing parenthesis,
+# get the indentation level to match when adding plugins
+multi == 1 && /^[^#]*/ {
+ indent=\"\"
+ for (i = 1; i <= length(\$0); i++) {
+ char=substr(\$0, i, 1)
+ if (char == \" \" || char == \"\t\") {
+ indent = indent char
+ } else {
+ break
+ }
+ }
+}
+
{ print \$0 }
"
@@ -397,8 +422,23 @@ function _omz::plugin::info {
local readme
for readme in "$ZSH_CUSTOM/plugins/$1/README.md" "$ZSH/plugins/$1/README.md"; do
if [[ -f "$readme" ]]; then
- (( ${+commands[less]} )) && less "$readme" || cat "$readme"
- return 0
+ # If being piped, just cat the README
+ if [[ ! -t 1 ]]; then
+ cat "$readme"
+ return $?
+ fi
+
+ # Enrich the README display depending on the tools we have
+ # - glow: https://github.com/charmbracelet/glow
+ # - bat: https://github.com/sharkdp/bat
+ # - less: typical pager command
+ case 1 in
+ ${+commands[glow]}) glow -p "$readme" ;;
+ ${+commands[bat]}) bat -l md --style plain "$readme" ;;
+ ${+commands[less]}) less "$readme" ;;
+ *) cat "$readme" ;;
+ esac
+ return $?
fi
done
@@ -413,8 +453,21 @@ function _omz::plugin::info {
function _omz::plugin::list {
local -a custom_plugins builtin_plugins
- custom_plugins=("$ZSH_CUSTOM"/plugins/*(-/N:t))
- builtin_plugins=("$ZSH"/plugins/*(-/N:t))
+
+ # If --enabled is provided, only list what's enabled
+ if [[ "$1" == "--enabled" ]]; then
+ local plugin
+ for plugin in "${plugins[@]}"; do
+ if [[ -d "${ZSH_CUSTOM}/plugins/${plugin}" ]]; then
+ custom_plugins+=("${plugin}")
+ elif [[ -d "${ZSH}/plugins/${plugin}" ]]; then
+ builtin_plugins+=("${plugin}")
+ fi
+ done
+ else
+ custom_plugins=("$ZSH_CUSTOM"/plugins/*(-/N:t))
+ builtin_plugins=("$ZSH"/plugins/*(-/N:t))
+ fi
# If the command is being piped, print all found line by line
if [[ ! -t 1 ]]; then
@@ -787,6 +840,13 @@ function _omz::update {
return 1
}
+ # Check if --unattended was passed
+ [[ "$1" != --unattended ]] || {
+ _omz::log error "the \`\e[2m--unattended\e[0m\` flag is no longer supported, use the \`\e[2mupgrade.sh\e[0m\` script instead."
+ _omz::log error "for more information see https://github.com/ohmyzsh/ohmyzsh/wiki/FAQ#how-do-i-update-oh-my-zsh"
+ return 1
+ }
+
local last_commit=$(builtin cd -q "$ZSH"; git rev-parse HEAD 2>/dev/null)
[[ $? -eq 0 ]] || {
_omz::log error "\`$ZSH\` is not a git directory. Aborting..."
@@ -795,11 +855,7 @@ function _omz::update {
# Run update script
zstyle -s ':omz:update' verbose verbose_mode || verbose_mode=default
- if [[ "$1" != --unattended ]]; then
- ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" -i -v $verbose_mode || return $?
- else
- ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" -v $verbose_mode || return $?
- fi
+ ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" -i -v $verbose_mode || return $?
# Update last updated file
zmodload zsh/datetime
@@ -808,7 +864,7 @@ function _omz::update {
command rm -rf "$ZSH/log/update.lock"
# Restart the zsh session if there were changes
- if [[ "$1" != --unattended && "$(builtin cd -q "$ZSH"; git rev-parse HEAD)" != "$last_commit" ]]; then
+ if [[ "$(builtin cd -q "$ZSH"; git rev-parse HEAD)" != "$last_commit" ]]; then
# Old zsh versions don't have ZSH_ARGZERO
local zsh="${ZSH_ARGZERO:-${functrace[-1]%:*}}"
# Check whether to run a login shell
diff --git a/lib/completion.zsh b/lib/completion.zsh
index 5a233a322..3823c2544 100644
--- a/lib/completion.zsh
+++ b/lib/completion.zsh
@@ -40,7 +40,7 @@ fi
# disable named-directories autocompletion
zstyle ':completion:*:cd:*' tag-order local-directories directory-stack path-directories
-# Use caching so that commands like apt and dpkg complete are useable
+# Use caching so that commands like apt and dpkg complete are usable
zstyle ':completion:*' use-cache yes
zstyle ':completion:*' cache-path $ZSH_CACHE_DIR
diff --git a/lib/functions.zsh b/lib/functions.zsh
index 2e667332e..330b0e3e9 100644
--- a/lib/functions.zsh
+++ b/lib/functions.zsh
@@ -23,6 +23,9 @@ function open_command() {
linux*) [[ "$(uname -r)" != *icrosoft* ]] && open_cmd='nohup xdg-open' || {
open_cmd='cmd.exe /c start ""'
[[ -e "$1" ]] && { 1="$(wslpath -w "${1:a}")" || return 1 }
+ [[ "$1" = (http|https)://* ]] && {
+ 1="$(echo "$1" | sed -E 's/([&|()<>^])/^\1/g')" || return 1
+ }
} ;;
msys*) open_cmd='start ""' ;;
*) echo "Platform $OSTYPE not supported"
@@ -57,6 +60,16 @@ function takeurl() {
cd "$thedir"
}
+function takezip() {
+ local data thedir
+ data="$(mktemp)"
+ curl -L "$1" > "$data"
+ unzip "$data" -d "./"
+ thedir="$(unzip -l "$data" | awk 'NR==4 {print $4}' | sed 's/\/.*//')"
+ rm "$data"
+ cd "$thedir"
+}
+
function takegit() {
git clone "$1"
cd "$(basename ${1%%.git})"
@@ -65,6 +78,8 @@ function takegit() {
function take() {
if [[ $1 =~ ^(https?|ftp).*\.(tar\.(gz|bz2|xz)|tgz)$ ]]; then
takeurl "$1"
+ elif [[ $1 =~ ^(https?|ftp).*\.(zip)$ ]]; then
+ takezip "$1"
elif [[ $1 =~ ^([A-Za-z0-9]\+@|https?|git|ssh|ftps?|rsync).*\.git/?$ ]]; then
takegit "$1"
else
diff --git a/lib/git.zsh b/lib/git.zsh
index db6c9174c..f4d4229cb 100644
--- a/lib/git.zsh
+++ b/lib/git.zsh
@@ -39,185 +39,6 @@ function _omz_git_prompt_info() {
echo "${ZSH_THEME_GIT_PROMPT_PREFIX}${ref:gs/%/%%}${upstream:gs/%/%%}$(parse_git_dirty)${ZSH_THEME_GIT_PROMPT_SUFFIX}"
}
-# Use async version if setting is enabled, or unset but zsh version is at least 5.0.6.
-# This avoids async prompt issues caused by previous zsh versions:
-# - https://github.com/ohmyzsh/ohmyzsh/issues/12331
-# - https://github.com/ohmyzsh/ohmyzsh/issues/12360
-# TODO(2024-06-12): @mcornella remove workaround when CentOS 7 reaches EOL
-if zstyle -t ':omz:alpha:lib:git' async-prompt \
- || { is-at-least 5.0.6 && zstyle -T ':omz:alpha:lib:git' async-prompt }; then
- function git_prompt_info() {
- if [[ -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_info]}" ]]; then
- echo -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_info]}"
- fi
- }
-
- function git_prompt_status() {
- if [[ -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_status]}" ]]; then
- echo -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_status]}"
- fi
- }
-
- # Conditionally register the async handler, only if it's needed in $PROMPT
- # or any of the other prompt variables
- function _defer_async_git_register() {
- # Check if git_prompt_info is used in a prompt variable
- case "${PS1}:${PS2}:${PS3}:${PS4}:${RPROMPT}:${RPS1}:${RPS2}:${RPS3}:${RPS4}" in
- *(\$\(git_prompt_info\)|\`git_prompt_info\`)*)
- _omz_register_handler _omz_git_prompt_info
- ;;
- esac
-
- case "${PS1}:${PS2}:${PS3}:${PS4}:${RPROMPT}:${RPS1}:${RPS2}:${RPS3}:${RPS4}" in
- *(\$\(git_prompt_status\)|\`git_prompt_status\`)*)
- _omz_register_handler _omz_git_prompt_status
- ;;
- esac
-
- add-zsh-hook -d precmd _defer_async_git_register
- unset -f _defer_async_git_register
- }
-
- # Register the async handler first. This needs to be done before
- # the async request prompt is run
- precmd_functions=(_defer_async_git_register $precmd_functions)
-else
- function git_prompt_info() {
- _omz_git_prompt_info
- }
- function git_prompt_status() {
- _omz_git_prompt_status
- }
-fi
-
-# Checks if working tree is dirty
-function parse_git_dirty() {
- local STATUS
- local -a FLAGS
- FLAGS=('--porcelain')
- if [[ "$(__git_prompt_git config --get oh-my-zsh.hide-dirty)" != "1" ]]; then
- if [[ "${DISABLE_UNTRACKED_FILES_DIRTY:-}" == "true" ]]; then
- FLAGS+='--untracked-files=no'
- fi
- case "${GIT_STATUS_IGNORE_SUBMODULES:-}" in
- git)
- # let git decide (this respects per-repo config in .gitmodules)
- ;;
- *)
- # if unset: ignore dirty submodules
- # other values are passed to --ignore-submodules
- FLAGS+="--ignore-submodules=${GIT_STATUS_IGNORE_SUBMODULES:-dirty}"
- ;;
- esac
- STATUS=$(__git_prompt_git status ${FLAGS} 2> /dev/null | tail -n 1)
- fi
- if [[ -n $STATUS ]]; then
- echo "$ZSH_THEME_GIT_PROMPT_DIRTY"
- else
- echo "$ZSH_THEME_GIT_PROMPT_CLEAN"
- fi
-}
-
-# Gets the difference between the local and remote branches
-function git_remote_status() {
- local remote ahead behind git_remote_status git_remote_status_detailed
- remote=${$(__git_prompt_git rev-parse --verify ${hook_com[branch]}@{upstream} --symbolic-full-name 2>/dev/null)/refs\/remotes\/}
- if [[ -n ${remote} ]]; then
- ahead=$(__git_prompt_git rev-list ${hook_com[branch]}@{upstream}..HEAD 2>/dev/null | wc -l)
- behind=$(__git_prompt_git rev-list HEAD..${hook_com[branch]}@{upstream} 2>/dev/null | wc -l)
-
- if [[ $ahead -eq 0 ]] && [[ $behind -eq 0 ]]; then
- git_remote_status="$ZSH_THEME_GIT_PROMPT_EQUAL_REMOTE"
- elif [[ $ahead -gt 0 ]] && [[ $behind -eq 0 ]]; then
- git_remote_status="$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE"
- git_remote_status_detailed="$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE_COLOR$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE$((ahead))%{$reset_color%}"
- elif [[ $behind -gt 0 ]] && [[ $ahead -eq 0 ]]; then
- git_remote_status="$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE"
- git_remote_status_detailed="$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE_COLOR$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE$((behind))%{$reset_color%}"
- elif [[ $ahead -gt 0 ]] && [[ $behind -gt 0 ]]; then
- git_remote_status="$ZSH_THEME_GIT_PROMPT_DIVERGED_REMOTE"
- git_remote_status_detailed="$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE_COLOR$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE$((ahead))%{$reset_color%}$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE_COLOR$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE$((behind))%{$reset_color%}"
- fi
-
- if [[ -n $ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_DETAILED ]]; then
- git_remote_status="$ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_PREFIX${remote:gs/%/%%}$git_remote_status_detailed$ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_SUFFIX"
- fi
-
- echo $git_remote_status
- fi
-}
-
-# Outputs the name of the current branch
-# Usage example: git pull origin $(git_current_branch)
-# Using '--quiet' with 'symbolic-ref' will not cause a fatal error (128) if
-# it's not a symbolic ref, but in a Git repo.
-function git_current_branch() {
- local ref
- ref=$(__git_prompt_git symbolic-ref --quiet HEAD 2> /dev/null)
- local ret=$?
- if [[ $ret != 0 ]]; then
- [[ $ret == 128 ]] && return # no git repo.
- ref=$(__git_prompt_git rev-parse --short HEAD 2> /dev/null) || return
- fi
- echo ${ref#refs/heads/}
-}
-
-
-# Gets the number of commits ahead from remote
-function git_commits_ahead() {
- if __git_prompt_git rev-parse --git-dir &>/dev/null; then
- local commits="$(__git_prompt_git rev-list --count @{upstream}..HEAD 2>/dev/null)"
- if [[ -n "$commits" && "$commits" != 0 ]]; then
- echo "$ZSH_THEME_GIT_COMMITS_AHEAD_PREFIX$commits$ZSH_THEME_GIT_COMMITS_AHEAD_SUFFIX"
- fi
- fi
-}
-
-# Gets the number of commits behind remote
-function git_commits_behind() {
- if __git_prompt_git rev-parse --git-dir &>/dev/null; then
- local commits="$(__git_prompt_git rev-list --count HEAD..@{upstream} 2>/dev/null)"
- if [[ -n "$commits" && "$commits" != 0 ]]; then
- echo "$ZSH_THEME_GIT_COMMITS_BEHIND_PREFIX$commits$ZSH_THEME_GIT_COMMITS_BEHIND_SUFFIX"
- fi
- fi
-}
-
-# Outputs if current branch is ahead of remote
-function git_prompt_ahead() {
- if [[ -n "$(__git_prompt_git rev-list origin/$(git_current_branch)..HEAD 2> /dev/null)" ]]; then
- echo "$ZSH_THEME_GIT_PROMPT_AHEAD"
- fi
-}
-
-# Outputs if current branch is behind remote
-function git_prompt_behind() {
- if [[ -n "$(__git_prompt_git rev-list HEAD..origin/$(git_current_branch) 2> /dev/null)" ]]; then
- echo "$ZSH_THEME_GIT_PROMPT_BEHIND"
- fi
-}
-
-# Outputs if current branch exists on remote or not
-function git_prompt_remote() {
- if [[ -n "$(__git_prompt_git show-ref origin/$(git_current_branch) 2> /dev/null)" ]]; then
- echo "$ZSH_THEME_GIT_PROMPT_REMOTE_EXISTS"
- else
- echo "$ZSH_THEME_GIT_PROMPT_REMOTE_MISSING"
- fi
-}
-
-# Formats prompt string for current git commit short SHA
-function git_prompt_short_sha() {
- local SHA
- SHA=$(__git_prompt_git rev-parse --short HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER"
-}
-
-# Formats prompt string for current git commit long SHA
-function git_prompt_long_sha() {
- local SHA
- SHA=$(__git_prompt_git rev-parse HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER"
-}
-
function _omz_git_prompt_status() {
[[ "$(__git_prompt_git config --get oh-my-zsh.hide-status 2>/dev/null)" = 1 ]] && return
@@ -227,7 +48,7 @@ function _omz_git_prompt_status() {
prefix_constant_map=(
'\?\? ' 'UNTRACKED'
'A ' 'ADDED'
- 'M ' 'ADDED'
+ 'M ' 'MODIFIED'
'MM ' 'MODIFIED'
' M ' 'MODIFIED'
'AM ' 'MODIFIED'
@@ -317,6 +138,213 @@ function _omz_git_prompt_status() {
echo $status_prompt
}
+# Use async version if setting is enabled, or unset but zsh version is at least 5.0.6.
+# This avoids async prompt issues caused by previous zsh versions:
+# - https://github.com/ohmyzsh/ohmyzsh/issues/12331
+# - https://github.com/ohmyzsh/ohmyzsh/issues/12360
+# TODO(2024-06-12): @mcornella remove workaround when CentOS 7 reaches EOL
+local _style
+if zstyle -t ':omz:alpha:lib:git' async-prompt \
+ || { is-at-least 5.0.6 && zstyle -T ':omz:alpha:lib:git' async-prompt }; then
+ function git_prompt_info() {
+ if [[ -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_info]}" ]]; then
+ echo -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_info]}"
+ fi
+ }
+
+ function git_prompt_status() {
+ if [[ -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_status]}" ]]; then
+ echo -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_status]}"
+ fi
+ }
+
+ # Conditionally register the async handler, only if it's needed in $PROMPT
+ # or any of the other prompt variables
+ function _defer_async_git_register() {
+ # Check if git_prompt_info is used in a prompt variable
+ case "${PS1}:${PS2}:${PS3}:${PS4}:${RPROMPT}:${RPS1}:${RPS2}:${RPS3}:${RPS4}" in
+ *(\$\(git_prompt_info\)|\`git_prompt_info\`)*)
+ _omz_register_handler _omz_git_prompt_info
+ ;;
+ esac
+
+ case "${PS1}:${PS2}:${PS3}:${PS4}:${RPROMPT}:${RPS1}:${RPS2}:${RPS3}:${RPS4}" in
+ *(\$\(git_prompt_status\)|\`git_prompt_status\`)*)
+ _omz_register_handler _omz_git_prompt_status
+ ;;
+ esac
+
+ add-zsh-hook -d precmd _defer_async_git_register
+ unset -f _defer_async_git_register
+ }
+
+ # Register the async handler first. This needs to be done before
+ # the async request prompt is run
+ precmd_functions=(_defer_async_git_register $precmd_functions)
+elif zstyle -s ':omz:alpha:lib:git' async-prompt _style && [[ $_style == "force" ]]; then
+ function git_prompt_info() {
+ if [[ -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_info]}" ]]; then
+ echo -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_info]}"
+ fi
+ }
+
+ function git_prompt_status() {
+ if [[ -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_status]}" ]]; then
+ echo -n "${_OMZ_ASYNC_OUTPUT[_omz_git_prompt_status]}"
+ fi
+ }
+
+ _omz_register_handler _omz_git_prompt_info
+ _omz_register_handler _omz_git_prompt_status
+else
+ function git_prompt_info() {
+ _omz_git_prompt_info
+ }
+ function git_prompt_status() {
+ _omz_git_prompt_status
+ }
+fi
+
+# Checks if working tree is dirty
+function parse_git_dirty() {
+ local STATUS
+ local -a FLAGS
+ FLAGS=('--porcelain')
+ if [[ "$(__git_prompt_git config --get oh-my-zsh.hide-dirty)" != "1" ]]; then
+ if [[ "${DISABLE_UNTRACKED_FILES_DIRTY:-}" == "true" ]]; then
+ FLAGS+='--untracked-files=no'
+ fi
+ case "${GIT_STATUS_IGNORE_SUBMODULES:-}" in
+ git)
+ # let git decide (this respects per-repo config in .gitmodules)
+ ;;
+ *)
+ # if unset: ignore dirty submodules
+ # other values are passed to --ignore-submodules
+ FLAGS+="--ignore-submodules=${GIT_STATUS_IGNORE_SUBMODULES:-dirty}"
+ ;;
+ esac
+ STATUS=$(__git_prompt_git status ${FLAGS} 2> /dev/null | tail -n 1)
+ fi
+ if [[ -n $STATUS ]]; then
+ echo "$ZSH_THEME_GIT_PROMPT_DIRTY"
+ else
+ echo "$ZSH_THEME_GIT_PROMPT_CLEAN"
+ fi
+}
+
+# Gets the difference between the local and remote branches
+function git_remote_status() {
+ local remote ahead behind git_remote_status git_remote_status_detailed
+ remote=${$(__git_prompt_git rev-parse --verify ${hook_com[branch]}@{upstream} --symbolic-full-name 2>/dev/null)/refs\/remotes\/}
+ if [[ -n ${remote} ]]; then
+ ahead=$(__git_prompt_git rev-list ${hook_com[branch]}@{upstream}..HEAD 2>/dev/null | wc -l)
+ behind=$(__git_prompt_git rev-list HEAD..${hook_com[branch]}@{upstream} 2>/dev/null | wc -l)
+
+ if [[ $ahead -eq 0 ]] && [[ $behind -eq 0 ]]; then
+ git_remote_status="$ZSH_THEME_GIT_PROMPT_EQUAL_REMOTE"
+ elif [[ $ahead -gt 0 ]] && [[ $behind -eq 0 ]]; then
+ git_remote_status="$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE"
+ git_remote_status_detailed="$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE_COLOR$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE$((ahead))%{$reset_color%}"
+ elif [[ $behind -gt 0 ]] && [[ $ahead -eq 0 ]]; then
+ git_remote_status="$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE"
+ git_remote_status_detailed="$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE_COLOR$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE$((behind))%{$reset_color%}"
+ elif [[ $ahead -gt 0 ]] && [[ $behind -gt 0 ]]; then
+ git_remote_status="$ZSH_THEME_GIT_PROMPT_DIVERGED_REMOTE"
+ git_remote_status_detailed="$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE_COLOR$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE$((ahead))%{$reset_color%}$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE_COLOR$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE$((behind))%{$reset_color%}"
+ fi
+
+ if [[ -n $ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_DETAILED ]]; then
+ git_remote_status="$ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_PREFIX${remote:gs/%/%%}$git_remote_status_detailed$ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_SUFFIX"
+ fi
+
+ echo $git_remote_status
+ fi
+}
+
+# Outputs the name of the current branch
+# Usage example: git pull origin $(git_current_branch)
+# Using '--quiet' with 'symbolic-ref' will not cause a fatal error (128) if
+# it's not a symbolic ref, but in a Git repo.
+function git_current_branch() {
+ local ref
+ ref=$(__git_prompt_git symbolic-ref --quiet HEAD 2> /dev/null)
+ local ret=$?
+ if [[ $ret != 0 ]]; then
+ [[ $ret == 128 ]] && return # no git repo.
+ ref=$(__git_prompt_git rev-parse --short HEAD 2> /dev/null) || return
+ fi
+ echo ${ref#refs/heads/}
+}
+
+# Outputs the name of the previously checked out branch
+# Usage example: git pull origin $(git_previous_branch)
+# rev-parse --symbolic-full-name @{-1} only prints if it is a branch
+function git_previous_branch() {
+ local ref
+ ref=$(__git_prompt_git rev-parse --quiet --symbolic-full-name @{-1} 2> /dev/null)
+ local ret=$?
+ if [[ $ret != 0 ]] || [[ -z $ref ]]; then
+ return # no git repo or non-branch previous ref
+ fi
+ echo ${ref#refs/heads/}
+}
+
+# Gets the number of commits ahead from remote
+function git_commits_ahead() {
+ if __git_prompt_git rev-parse --git-dir &>/dev/null; then
+ local commits="$(__git_prompt_git rev-list --count @{upstream}..HEAD 2>/dev/null)"
+ if [[ -n "$commits" && "$commits" != 0 ]]; then
+ echo "$ZSH_THEME_GIT_COMMITS_AHEAD_PREFIX$commits$ZSH_THEME_GIT_COMMITS_AHEAD_SUFFIX"
+ fi
+ fi
+}
+
+# Gets the number of commits behind remote
+function git_commits_behind() {
+ if __git_prompt_git rev-parse --git-dir &>/dev/null; then
+ local commits="$(__git_prompt_git rev-list --count HEAD..@{upstream} 2>/dev/null)"
+ if [[ -n "$commits" && "$commits" != 0 ]]; then
+ echo "$ZSH_THEME_GIT_COMMITS_BEHIND_PREFIX$commits$ZSH_THEME_GIT_COMMITS_BEHIND_SUFFIX"
+ fi
+ fi
+}
+
+# Outputs if current branch is ahead of remote
+function git_prompt_ahead() {
+ if [[ -n "$(__git_prompt_git rev-list origin/$(git_current_branch)..HEAD 2> /dev/null)" ]]; then
+ echo "$ZSH_THEME_GIT_PROMPT_AHEAD"
+ fi
+}
+
+# Outputs if current branch is behind remote
+function git_prompt_behind() {
+ if [[ -n "$(__git_prompt_git rev-list HEAD..origin/$(git_current_branch) 2> /dev/null)" ]]; then
+ echo "$ZSH_THEME_GIT_PROMPT_BEHIND"
+ fi
+}
+
+# Outputs if current branch exists on remote or not
+function git_prompt_remote() {
+ if [[ -n "$(__git_prompt_git show-ref origin/$(git_current_branch) 2> /dev/null)" ]]; then
+ echo "$ZSH_THEME_GIT_PROMPT_REMOTE_EXISTS"
+ else
+ echo "$ZSH_THEME_GIT_PROMPT_REMOTE_MISSING"
+ fi
+}
+
+# Formats prompt string for current git commit short SHA
+function git_prompt_short_sha() {
+ local SHA
+ SHA=$(__git_prompt_git rev-parse --short HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER"
+}
+
+# Formats prompt string for current git commit long SHA
+function git_prompt_long_sha() {
+ local SHA
+ SHA=$(__git_prompt_git rev-parse HEAD 2> /dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER"
+}
+
# Outputs the name of the current user
# Usage example: $(git_current_user_name)
function git_current_user_name() {
diff --git a/lib/grep.zsh b/lib/grep.zsh
index 54e0f694e..1a70de7e5 100644
--- a/lib/grep.zsh
+++ b/lib/grep.zsh
@@ -10,7 +10,7 @@ else
}
# Ignore these folders (if the necessary grep flags are available)
- EXC_FOLDERS="{.bzr,CVS,.git,.hg,.svn,.idea,.tox}"
+ EXC_FOLDERS="{.bzr,CVS,.git,.hg,.svn,.idea,.tox,.venv,venv}"
# Check for --exclude-dir, otherwise check for --exclude. If --exclude
# isn't available, --color won't be either (they were released at the same
@@ -24,8 +24,8 @@ else
if [[ -n "$GREP_OPTIONS" ]]; then
# export grep, egrep and fgrep settings
alias grep="grep $GREP_OPTIONS"
- alias egrep="grep -E $GREP_OPTIONS"
- alias fgrep="grep -F $GREP_OPTIONS"
+ alias egrep="grep -E"
+ alias fgrep="grep -F"
# write to cache file if cache directory is writable
if [[ -w "$ZSH_CACHE_DIR" ]]; then
diff --git a/lib/history.zsh b/lib/history.zsh
index 35da57de2..781a0e9de 100644
--- a/lib/history.zsh
+++ b/lib/history.zsh
@@ -18,10 +18,10 @@ function omz_history {
print -u2 History file deleted.
elif [[ $# -eq 0 ]]; then
# if no arguments provided, show full history starting from 1
- builtin fc $stamp -l 1
+ builtin fc "${stamp[@]}" -l 1
else
# otherwise, run `fc -l` with a custom format
- builtin fc $stamp -l "$@"
+ builtin fc "${stamp[@]}" -l "$@"
fi
}
diff --git a/lib/misc.zsh b/lib/misc.zsh
index ff2017713..054485f5a 100644
--- a/lib/misc.zsh
+++ b/lib/misc.zsh
@@ -19,7 +19,7 @@ setopt multios # enable redirect to multiple streams: echo >file1 >
setopt long_list_jobs # show long list format job notifications
setopt interactivecomments # recognize comments
-# define pager dependant on what is available (less or more)
+# define pager depending on what is available (less or more)
if (( ${+commands[less]} )); then
env_default 'PAGER' 'less'
env_default 'LESS' '-R'
diff --git a/lib/termsupport.zsh b/lib/termsupport.zsh
index 087bae9bb..852a543c5 100644
--- a/lib/termsupport.zsh
+++ b/lib/termsupport.zsh
@@ -17,7 +17,7 @@ function title {
: ${2=$1}
case "$TERM" in
- cygwin|xterm*|putty*|rxvt*|konsole*|ansi|mlterm*|alacritty*|st*|foot*|contour*)
+ cygwin|xterm*|putty*|rxvt*|konsole*|ansi|mlterm*|alacritty*|st*|foot*|contour*|wezterm*)
print -Pn "\e]2;${2:q}\a" # set window name
print -Pn "\e]1;${1:q}\a" # set tab name
;;
@@ -47,13 +47,13 @@ fi
# Runs before showing the prompt
function omz_termsupport_precmd {
- [[ "${DISABLE_AUTO_TITLE:-}" != true ]] || return
+ [[ "${DISABLE_AUTO_TITLE:-}" != true ]] || return 0
title "$ZSH_THEME_TERM_TAB_TITLE_IDLE" "$ZSH_THEME_TERM_TITLE_IDLE"
}
# Runs before executing the command
function omz_termsupport_preexec {
- [[ "${DISABLE_AUTO_TITLE:-}" != true ]] || return
+ [[ "${DISABLE_AUTO_TITLE:-}" != true ]] || return 0
emulate -L zsh
setopt extended_glob
@@ -145,6 +145,7 @@ esac
# Identifies the directory using a file: URI scheme, including
# the host name to disambiguate local vs. remote paths.
function omz_termsupport_cwd {
+ setopt localoptions unset
# Percent-encode the host and path names.
local URL_HOST URL_PATH
URL_HOST="$(omz_urlencode -P $HOST)" || return 1
diff --git a/oh-my-zsh.sh b/oh-my-zsh.sh
index b1032841c..3e547d358 100644
--- a/oh-my-zsh.sh
+++ b/oh-my-zsh.sh
@@ -99,8 +99,8 @@ done
# Figure out the SHORT hostname
if [[ "$OSTYPE" = darwin* ]]; then
- # macOS's $HOST changes with dhcp, etc. Use ComputerName if possible.
- SHORT_HOST=$(scutil --get ComputerName 2>/dev/null) || SHORT_HOST="${HOST/.*/}"
+ # macOS's $HOST changes with dhcp, etc. Use LocalHostName if possible.
+ SHORT_HOST=$(scutil --get LocalHostName 2>/dev/null) || SHORT_HOST="${HOST/.*/}"
else
SHORT_HOST="${HOST/.*/}"
fi
@@ -192,7 +192,7 @@ _omz_source() {
fi
}
-# Load all of the lib files in ~/oh-my-zsh/lib that end in .zsh
+# Load all of the lib files in ~/.oh-my-zsh/lib that end in .zsh
# TIP: Add files you don't want in git to .gitignore
for lib_file ("$ZSH"/lib/*.zsh); do
_omz_source "lib/${lib_file:t}"
diff --git a/plugins/1password/1password.plugin.zsh b/plugins/1password/1password.plugin.zsh
index 941523ca8..e8f91f8fe 100644
--- a/plugins/1password/1password.plugin.zsh
+++ b/plugins/1password/1password.plugin.zsh
@@ -1,9 +1,15 @@
# Do nothing if op is not installed
(( ${+commands[op]} )) || return
-# Load op completion
-eval "$(op completion zsh)"
-compdef _op op
+# If the completion file doesn't exist yet, we need to autoload it and
+# bind it to `op`. Otherwise, compinit will have already done that.
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_op" ]]; then
+ typeset -g -A _comps
+ autoload -Uz _op
+ _comps[op]=_op
+fi
+
+op completion zsh >| "$ZSH_CACHE_DIR/completions/_op" &|
# Load opswd function
autoload -Uz opswd
diff --git a/plugins/1password/opswd b/plugins/1password/opswd
index 0f667d2ff..753de9f99 100644
--- a/plugins/1password/opswd
+++ b/plugins/1password/opswd
@@ -27,7 +27,7 @@ function opswd() {
local password
# Copy the password to the clipboard
- if ! password=$(op item get "$service" --fields password 2>/dev/null); then
+ if ! password=$(op item get "$service" --reveal --fields password 2>/dev/null); then
echo "error: could not obtain password for $service"
return 1
fi
diff --git a/plugins/alias-finder/README.md b/plugins/alias-finder/README.md
index a9bbd0838..b24f8d4ac 100644
--- a/plugins/alias-finder/README.md
+++ b/plugins/alias-finder/README.md
@@ -11,6 +11,8 @@ plugins=(... alias-finder)
To enable it for every single command, set zstyle in your `~/.zshrc`.
+If the user has installed `rg`([ripgrep](https://github.com/BurntSushi/ripgrep)), it will be used because it's faster. Otherwise, it will use the `grep` command.
+
```zsh
# ~/.zshrc
@@ -28,7 +30,7 @@ When you execute a command alias finder will look at your defined aliases and su
Running the un-aliased `git status` command:
```sh
-╭─tim@fox ~/repo/gitopolis ‹main›
+╭─tim@fox ~/repo/gitopolis ‹main›
╰─$ git status
gst='git status' # <=== shorter suggestion from alias-finder
@@ -40,7 +42,7 @@ nothing to commit, working tree clean
Running a shorter `git st` alias from `.gitconfig` that it suggested :
```sh
-╭─tim@fox ~/repo/gitopolis ‹main›
+╭─tim@fox ~/repo/gitopolis ‹main›
╰─$ git st
gs='git st' # <=== shorter suggestion from alias-finder
## main...origin/main
@@ -48,7 +50,7 @@ gs='git st' # <=== shorter suggestion from alias-finder
Running the shortest `gs` shell alias that it found:
```sh
-╭─tim@fox ~/repo/gitopolis ‹main›
+╭─tim@fox ~/repo/gitopolis ‹main›
╰─$ gs
# <=== no suggestions alias-finder because this is the shortest
## main...origin/main
diff --git a/plugins/alias-finder/alias-finder.plugin.zsh b/plugins/alias-finder/alias-finder.plugin.zsh
index 5fdfbc835..6f24c7089 100644
--- a/plugins/alias-finder/alias-finder.plugin.zsh
+++ b/plugins/alias-finder/alias-finder.plugin.zsh
@@ -36,14 +36,22 @@ alias-finder() {
# make filter to find only shorter results than current cmd
if [[ $cheaper == true ]]; then
cmdLen=$(echo -n "$cmd" | wc -c)
- filter="^'{0,1}.{0,$((cmdLen - 1))}="
+ if [[ $cmdLen -le 1 ]]; then
+ return
+ fi
+
+ filter="^'?.{1,$((cmdLen - 1))}'?=" # some aliases is surrounded by single quotes
fi
- alias | grep -E "$filter" | grep -E "=$finder"
+ if (( $+commands[rg] )); then
+ alias | rg "$filter" | rg "=$finder"
+ else
+ alias | grep -E "$filter" | grep -E "=$finder"
+ fi
if [[ $exact == true ]]; then
break # because exact case is only one
- elif [[ $longer = true ]]; then
+ elif [[ $longer == true ]]; then
break # because above grep command already found every longer aliases during first cycle
fi
diff --git a/plugins/archlinux/archlinux.plugin.zsh b/plugins/archlinux/archlinux.plugin.zsh
index e20a31156..7abd7c2f6 100644
--- a/plugins/archlinux/archlinux.plugin.zsh
+++ b/plugins/archlinux/archlinux.plugin.zsh
@@ -178,26 +178,27 @@ fi
# Check Arch Linux PGP Keyring before System Upgrade to prevent failure.
function upgrade() {
+ sudo pacman -Sy
echo ":: Checking Arch Linux PGP Keyring..."
local installedver="$(LANG= sudo pacman -Qi archlinux-keyring | grep -Po '(?<=Version : ).*')"
local currentver="$(LANG= sudo pacman -Si archlinux-keyring | grep -Po '(?<=Version : ).*')"
if [ $installedver != $currentver ]; then
echo " Arch Linux PGP Keyring is out of date."
echo " Updating before full system upgrade."
- sudo pacman -Sy --needed --noconfirm archlinux-keyring
+ sudo pacman -S --needed --noconfirm archlinux-keyring
else
echo " Arch Linux PGP Keyring is up to date."
echo " Proceeding with full system upgrade."
fi
if (( $+commands[yay] )); then
- yay -Syu
+ yay -Su
elif (( $+commands[trizen] )); then
- trizen -Syu
+ trizen -Su
elif (( $+commands[pacaur] )); then
- pacaur -Syu
+ pacaur -Su
elif (( $+commands[aura] )); then
- sudo aura -Syu
+ sudo aura -Su
else
- sudo pacman -Syu
+ sudo pacman -Su
fi
}
diff --git a/plugins/asdf/README.md b/plugins/asdf/README.md
index 4af69a75c..69db6930a 100644
--- a/plugins/asdf/README.md
+++ b/plugins/asdf/README.md
@@ -1,32 +1,48 @@
-## asdf
+# asdf
Adds integration with [asdf](https://github.com/asdf-vm/asdf), the extendable version manager, with support for Ruby, Node.js, Elixir, Erlang and more.
-### Installation
+## Installation
-1. [Download asdf](https://asdf-vm.com/guide/getting-started.html#_2-download-asdf) by running the following:
-
- ```
- git clone https://github.com/asdf-vm/asdf.git ~/.asdf
- ```
-
-2. [Enable asdf](https://asdf-vm.com/guide/getting-started.html#_3-install-asdf) by adding it to your `plugins` definition in `~/.zshrc`.
-
- ```
- plugins=(asdf)
- ```
-
-### Usage
-
-See the [asdf documentation](https://asdf-vm.com/guide/getting-started.html#_4-install-a-plugin) for information on how to use asdf:
+1. [Install](https://asdf-vm.com/guide/getting-started.html#_1-install-asdf) asdf and ensure that's it's discoverable on `$PATH`;
+2. Enable it by adding it to your `plugins` definition in `~/.zshrc`:
+```sh
+plugins=(asdf)
```
-asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git
+
+## Usage
+
+Refer to the [asdf plugin documentation](https://asdf-vm.com/guide/getting-started.html#_4-install-a-plugin) for information on how to add a plugin and install the many runtime versions for it.
+
+Example for installing the nodejs plugin and the many runtimes for it:
+
+```sh
+# Add plugin to asdf
+asdf plugin add nodejs
+
+# Install the latest available version
asdf install nodejs latest
-asdf global nodejs latest
-asdf local nodejs latest
+
+# Uninstall the latest version
+asdf uninstall nodejs latest
+
+# Install a specific version
+asdf install nodejs 16.5.0
+
+# Set the latest version in .tool-versions of the `current directory`
+asdf set nodejs latest
+
+# Set a specific version in the `parent directory`
+asdf set -p nodejs 16.5.0 # -p is shorthand for --parent
+
+# Set a global version under `$HOME`
+asdf set -u nodejs 16.5.0 # -u is shorthand for --home
```
-### Maintainer
+For more commands, run `asdf help` or refer to the
+[asdf CLI documentation](https://asdf-vm.com/manage/commands.html#all-commands).
+
+## Maintainer
- [@RobLoach](https://github.com/RobLoach)
diff --git a/plugins/asdf/asdf.plugin.zsh b/plugins/asdf/asdf.plugin.zsh
index 7635d20c3..318267dcb 100644
--- a/plugins/asdf/asdf.plugin.zsh
+++ b/plugins/asdf/asdf.plugin.zsh
@@ -1,30 +1,13 @@
-# Find where asdf should be installed
-ASDF_DIR="${ASDF_DIR:-$HOME/.asdf}"
-ASDF_COMPLETIONS="$ASDF_DIR/completions"
+(( ! $+commands[asdf] )) && return
-if [[ ! -f "$ASDF_DIR/asdf.sh" || ! -f "$ASDF_COMPLETIONS/_asdf" ]]; then
- # If not found, check for archlinux/AUR package (/opt/asdf-vm/)
- if [[ -f "/opt/asdf-vm/asdf.sh" ]]; then
- ASDF_DIR="/opt/asdf-vm"
- ASDF_COMPLETIONS="$ASDF_DIR"
- # If not found, check for Homebrew package
- elif (( $+commands[brew] )); then
- _ASDF_PREFIX="$(brew --prefix asdf)"
- ASDF_DIR="${_ASDF_PREFIX}/libexec"
- ASDF_COMPLETIONS="${_ASDF_PREFIX}/share/zsh/site-functions"
- unset _ASDF_PREFIX
- else
- return
- fi
-fi
+export ASDF_DATA_DIR="${ASDF_DATA_DIR:-$HOME/.asdf}"
+path=("$ASDF_DATA_DIR/shims" $path)
-# Load command
-if [[ -f "$ASDF_DIR/asdf.sh" ]]; then
- source "$ASDF_DIR/asdf.sh"
- # Load completions
- if [[ -f "$ASDF_COMPLETIONS/_asdf" ]]; then
- fpath+=("$ASDF_COMPLETIONS")
- autoload -Uz _asdf
- compdef _asdf asdf # compdef is already loaded before loading plugins
- fi
+# If the completion file doesn't exist yet, we need to autoload it and
+# bind it to `asdf`. Otherwise, compinit will have already done that.
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_asdf" ]]; then
+ typeset -g -A _comps
+ autoload -Uz _asdf
+ _comps[asdf]=_asdf
fi
+asdf completion zsh >| "$ZSH_CACHE_DIR/completions/_asdf" &|
diff --git a/plugins/autojump/autojump.plugin.zsh b/plugins/autojump/autojump.plugin.zsh
index e385a2de8..a0668a415 100644
--- a/plugins/autojump/autojump.plugin.zsh
+++ b/plugins/autojump/autojump.plugin.zsh
@@ -6,6 +6,7 @@ autojump_paths=(
/run/current-system/sw/share/autojump/autojump.zsh # NixOS installation
/etc/profiles/per-user/$USER/share/autojump/autojump.zsh # Home Manager, NixOS with user-scoped packages
/usr/share/autojump/autojump.zsh # Debian and Ubuntu package
+ $PREFIX/share/autojump/autojump.zsh # Termux package
/etc/profile.d/autojump.zsh # manual installation
/etc/profile.d/autojump.sh # Gentoo installation
/usr/local/share/autojump/autojump.zsh # FreeBSD installation
diff --git a/plugins/bazel/README.md b/plugins/bazel/README.md
index eba4175bc..b0c34a15f 100644
--- a/plugins/bazel/README.md
+++ b/plugins/bazel/README.md
@@ -1,6 +1,7 @@
# Bazel plugin
-This plugin adds completion and aliases for [bazel](https://bazel.build), an open-source build and test tool that scalably supports multi-language and multi-platform projects.
+This plugin adds completion and aliases for [bazel](https://bazel.build), an open-source build and test tool
+that scalably supports multi-language and multi-platform projects.
To use it, add `bazel` to the plugins array in your zshrc file:
@@ -14,9 +15,15 @@ The plugin has a copy of [the completion script from the git repository][1].
## Aliases
-| Alias | Command | Description |
-| ------- | -------------------------------------- | ------------------------------------------------------ |
-| bzb | `bazel build` | The `bazel build` command |
-| bzt | `bazel test` | The `bazel test` command |
-| bzr | `bazel run` | The `bazel run` command |
-| bzq | `bazel query` | The `bazel query` command |
+| Alias | Command | Description |
+| ----- | ------------- | ------------------------- |
+| bzb | `bazel build` | The `bazel build` command |
+| bzt | `bazel test` | The `bazel test` command |
+| bzr | `bazel run` | The `bazel run` command |
+| bzq | `bazel query` | The `bazel query` command |
+
+## Functions
+
+| Function | Description |
+| -------- | -------------------------------- |
+| sri-hash | Generate SRI hash used by bzlmod |
diff --git a/plugins/bazel/bazel.plugin.zsh b/plugins/bazel/bazel.plugin.zsh
index d239a06b5..818d5652b 100644
--- a/plugins/bazel/bazel.plugin.zsh
+++ b/plugins/bazel/bazel.plugin.zsh
@@ -3,3 +3,7 @@ alias bzb='bazel build'
alias bzt='bazel test'
alias bzr='bazel run'
alias bzq='bazel query'
+
+sri-hash() {
+ openssl dgst -sha256 -binary $1 | openssl base64 -A | sed 's/^/sha256-/'
+}
diff --git a/plugins/bedtools/_bedtools b/plugins/bedtools/_bedtools
index ef6c4179a..15e3dc2ff 100644
--- a/plugins/bedtools/_bedtools
+++ b/plugins/bedtools/_bedtools
@@ -47,7 +47,7 @@ case $state in
"random[Generate random intervals in a genome.]" \
"reldist[Calculate the distribution of relative distances b/w two files.]" \
"sample[Sample random records from file using reservoir sampling.]" \
- "shuffle[Randomly redistrubute intervals in a genome.]" \
+ "shuffle[Randomly redistribute intervals in a genome.]" \
"slop[Adjust the size of intervals.]" \
"sort[Order the intervals in a file.]" \
"subtract[Remove intervals based on overlaps b/w two files.]" \
diff --git a/plugins/bgnotify/README.md b/plugins/bgnotify/README.md
index 33d529f15..1389def86 100644
--- a/plugins/bgnotify/README.md
+++ b/plugins/bgnotify/README.md
@@ -38,6 +38,7 @@ One can configure a few things:
- `bgnotify_bell` enabled or disables the terminal bell (default true)
- `bgnotify_threshold` sets the notification threshold time (default 6 seconds)
- `function bgnotify_formatted` lets you change the notification. You can for instance customize the message and pass in an icon.
+- `bgnotify_extraargs` appends extra args to notifier (e.g. `-e` for notify-send to create a transient notification)
Use these by adding a function definition before the your call to source. Example:
diff --git a/plugins/bgnotify/bgnotify.plugin.zsh b/plugins/bgnotify/bgnotify.plugin.zsh
index 7de6f9a91..dca8250be 100644
--- a/plugins/bgnotify/bgnotify.plugin.zsh
+++ b/plugins/bgnotify/bgnotify.plugin.zsh
@@ -62,7 +62,7 @@ function bgnotify_formatted {
function bgnotify_appid {
if (( ${+commands[osascript]} )); then
osascript -e "tell application id \"$(bgnotify_programid)\" to get the {id, frontmost, id of front window, visible of front window}" 2>/dev/null
- elif [[ -n $WAYLAND_DISPLAY ]] && (( ${+commands[swaymsg]} )); then # wayland+sway
+ elif [[ -n $WAYLAND_DISPLAY ]] && ([[ -n $SWAYSOCK ]] || [[ -n $I3SOCK ]]) && (( ${+commands[swaymsg]} )); then # wayland+sway
local app_id=$(bgnotify_find_sway_appid)
[[ -n "$app_id" ]] && echo "$app_id" || echo $EPOCHSECONDS
elif [[ -z $WAYLAND_DISPLAY ]] && [[ -n $DISPLAY ]] && (( ${+commands[xprop]} )); then
@@ -117,15 +117,15 @@ function bgnotify {
local icon="$3"
if (( ${+commands[terminal-notifier]} )); then # macOS
local term_id=$(bgnotify_programid)
- terminal-notifier -message "$message" -title "$title" ${=icon:+-appIcon "$icon"} ${=term_id:+-activate "$term_id"} &>/dev/null
+ terminal-notifier -message "$message" -title "$title" ${=icon:+-appIcon "$icon"} ${=term_id:+-activate "$term_id"} ${=bgnotify_extraargs:-} &>/dev/null
elif (( ${+commands[growlnotify]} )); then # macOS growl
- growlnotify -m "$title" "$message"
+ growlnotify -m "$title" "$message" ${=bgnotify_extraargs:-}
elif (( ${+commands[notify-send]} )); then
- notify-send "$title" "$message" ${=icon:+--icon "$icon"}
+ notify-send "$title" "$message" ${=icon:+--icon "$icon"} ${=bgnotify_extraargs:-}
elif (( ${+commands[kdialog]} )); then # KDE
- kdialog --title "$title" --passivepopup "$message" 5
+ kdialog --title "$title" --passivepopup "$message" 5 ${=bgnotify_extraargs:-}
elif (( ${+commands[notifu]} )); then # cygwin
- notifu /m "$message" /p "$title" ${=icon:+/i "$icon"}
+ notifu /m "$message" /p "$title" ${=icon:+/i "$icon"} ${=bgnotify_extraargs:-}
fi
}
diff --git a/plugins/branch/branch.plugin.zsh b/plugins/branch/branch.plugin.zsh
index dd5871fdc..c24f9098e 100644
--- a/plugins/branch/branch.plugin.zsh
+++ b/plugins/branch/branch.plugin.zsh
@@ -8,7 +8,7 @@ function branch_prompt_info() {
while [[ "$dir" != '/' ]]; do
# Found .git directory
if [[ -d "${dir}/.git" ]]; then
- branch="${"$(<"${dir}/.git/HEAD")"##*/}"
+ branch="${"$(<"${dir}/.git/HEAD")"##ref: refs/heads/}"
echo '±' "${branch:gs/%/%%}"
return
fi
diff --git a/plugins/brew/brew.plugin.zsh b/plugins/brew/brew.plugin.zsh
index a138a4827..4dab6f413 100644
--- a/plugins/brew/brew.plugin.zsh
+++ b/plugins/brew/brew.plugin.zsh
@@ -24,7 +24,7 @@ if (( ! $+commands[brew] )); then
fi
if [[ -z "$HOMEBREW_PREFIX" ]]; then
- # Maintain compatability with potential custom user profiles, where we had
+ # Maintain compatibility with potential custom user profiles, where we had
# previously relied on always sourcing shellenv. OMZ plugins should not rely
# on this to be defined due to out of order processing.
export HOMEBREW_PREFIX="$(brew --prefix)"
diff --git a/plugins/buf/README.md b/plugins/buf/README.md
new file mode 100644
index 000000000..946cf38dd
--- /dev/null
+++ b/plugins/buf/README.md
@@ -0,0 +1,9 @@
+# Buf plugin
+
+This plugin adds completion for [Buf CLI](https://github.com/bufbuild/buf), a tool working with Protocol Buffers.
+
+To use it, add `buf` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... buf)
+```
\ No newline at end of file
diff --git a/plugins/buf/buf.plugin.zsh b/plugins/buf/buf.plugin.zsh
new file mode 100644
index 000000000..0b251ac37
--- /dev/null
+++ b/plugins/buf/buf.plugin.zsh
@@ -0,0 +1,14 @@
+# Autocompletion for the Buf CLI (buf).
+if (( !$+commands[buf] )); then
+ return
+fi
+# If the completion file doesn't exist yet, we need to autoload it and
+# bind it to `buf`. Otherwise, compinit will have already done that.
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_buf" ]]; then
+ typeset -g -A _comps
+ autoload -Uz _buf
+ _comps[buf]=_buf
+fi
+
+# Generate and load buf completion
+buf completion zsh >! "$ZSH_CACHE_DIR/completions/_buf" &|
\ No newline at end of file
diff --git a/plugins/catimg/README.md b/plugins/catimg/README.md
index 68dc33c1f..4cfda0e25 100644
--- a/plugins/catimg/README.md
+++ b/plugins/catimg/README.md
@@ -1,6 +1,7 @@
# catimg
-Plugin for displaying images on the terminal using the `catimg.sh` script provided by [posva](https://github.com/posva/catimg)
+Plugin for displaying images on the terminal using the `catimg.sh` script provided by
+[posva](https://github.com/posva/catimg)
To use it, add `catimg` to the plugins array in your zshrc file:
@@ -10,7 +11,7 @@ plugins=(... catimg)
## Requirements
-- `convert` (ImageMagick)
+- `magick convert` (ImageMagick)
## Functions
diff --git a/plugins/catimg/catimg.plugin.zsh b/plugins/catimg/catimg.plugin.zsh
index f4ff6f856..ad10d8574 100644
--- a/plugins/catimg/catimg.plugin.zsh
+++ b/plugins/catimg/catimg.plugin.zsh
@@ -9,9 +9,11 @@
function catimg() {
- if [[ -x `which convert` ]]; then
- zsh $ZSH/plugins/catimg/catimg.sh $@
+ if (( $+commands[magick] )); then
+ CONVERT_CMD="magick" zsh $ZSH/plugins/catimg/catimg.sh $@
+ elif (( $+commands[convert] )); then
+ CONVERT_CMD="convert" zsh $ZSH/plugins/catimg/catimg.sh $@
else
- echo "catimg need convert (ImageMagick) to work)"
+ echo "catimg need magick/convert (ImageMagick) to work)"
fi
}
diff --git a/plugins/catimg/catimg.sh b/plugins/catimg/catimg.sh
index f58392428..7946ad16e 100644
--- a/plugins/catimg/catimg.sh
+++ b/plugins/catimg/catimg.sh
@@ -7,6 +7,10 @@
# GitHub: https://github.com/posva/catimg #
################################################################################
+# this should come from outside, either `magick` or `convert`
+# from imagemagick v7 and ahead `convert` is deprecated
+: ${CONVERT_CMD:=convert}
+
function help() {
echo "Usage catimg [-h] [-w width] [-c char] img"
echo "By default char is \" \" and w is the terminal width"
@@ -43,23 +47,23 @@ if [ ! "$WIDTH" ]; then
else
COLS=$(expr $WIDTH "/" $(echo -n "$CHAR" | wc -c))
fi
-WIDTH=$(convert "$IMG" -print "%w\n" /dev/null)
+WIDTH=$($CONVERT_CMD "$IMG" -print "%w\n" /dev/null)
if [ "$WIDTH" -gt "$COLS" ]; then
WIDTH=$COLS
fi
REMAP=""
-if convert "$IMG" -resize $COLS\> +dither -remap $COLOR_FILE /dev/null ; then
+if $CONVERT_CMD "$IMG" -resize $COLS\> +dither -remap $COLOR_FILE /dev/null ; then
REMAP="-remap $COLOR_FILE"
else
echo "The version of convert is too old, don't expect good results :(" >&2
- #convert "$IMG" -colors 256 PNG8:tmp.png
- #IMG="tmp.png"
+ # $CONVERT_CMD "$IMG" -colors 256 PNG8:tmp.png
+ # IMG="tmp.png"
fi
# Display the image
I=0
-convert "$IMG" -resize $COLS\> +dither `echo $REMAP` txt:- 2>/dev/null |
+$CONVERT_CMD "$IMG" -resize $COLS\> +dither `echo $REMAP` txt:- 2>/dev/null |
sed -e 's/.*none.*/NO NO NO/g' -e '1d;s/^.*(\(.*\)[,)].*$/\1/g;y/,/ /' |
while read R G B f; do
if [ ! "$R" = "NO" ]; then
diff --git a/plugins/chezmoi/README.md b/plugins/chezmoi/README.md
new file mode 100644
index 000000000..32aee73b2
--- /dev/null
+++ b/plugins/chezmoi/README.md
@@ -0,0 +1,11 @@
+# chezmoi Plugin
+
+## Introduction
+
+This `chezmoi` plugin sets up completion for [chezmoi](https://chezmoi.io).
+
+To use it, add `chezmoi` to the plugins array of your zshrc file:
+
+```bash
+plugins=(... chezmoi)
+```
diff --git a/plugins/chezmoi/chezmoi.plugin.zsh b/plugins/chezmoi/chezmoi.plugin.zsh
new file mode 100644
index 000000000..80e19fea1
--- /dev/null
+++ b/plugins/chezmoi/chezmoi.plugin.zsh
@@ -0,0 +1,14 @@
+# COMPLETION FUNCTION
+if (( ! $+commands[chezmoi] )); then
+ return
+fi
+
+# If the completion file doesn't exist yet, we need to autoload it and
+# bind it to `chezmoi`. Otherwise, compinit will have already done that.
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_chezmoi" ]]; then
+ typeset -g -A _comps
+ autoload -Uz _chezmoi
+ _comps[chezmoi]=_chezmoi
+fi
+
+chezmoi completion zsh >| "$ZSH_CACHE_DIR/completions/_chezmoi" &|
diff --git a/plugins/chruby/chruby.plugin.zsh b/plugins/chruby/chruby.plugin.zsh
index 1210897c4..06afef189 100644
--- a/plugins/chruby/chruby.plugin.zsh
+++ b/plugins/chruby/chruby.plugin.zsh
@@ -22,6 +22,8 @@ _source-from-homebrew() {
# check default brew prefix
if [[ -h /usr/local/opt/chruby ]];then
_brew_prefix="/usr/local/opt/chruby"
+ elif [[ -h /opt/homebrew/opt/chruby ]]; then
+ _brew_prefix="/opt/homebrew/opt/chruby"
else
# ok , it is not default prefix
# this call to brew is expensive ( about 400 ms ), so at least let's make it only once
diff --git a/plugins/chucknorris/README.md b/plugins/chucknorris/README.md
index 0562b3b59..655e7cf11 100644
--- a/plugins/chucknorris/README.md
+++ b/plugins/chucknorris/README.md
@@ -36,3 +36,10 @@ Last login: Fri Jan 30 23:12:26 on ttys001
- `cowsay` if using `chuck_cow`
Available via homebrew, apt, ...
+
+> [!NOTE]
+> In addition to installing `fortune`, it may be necessary to run:
+>
+> `strfile $ZSH/plugins/chucknorris/fortunes/chucknorris\n`
+>
+> (include the "\n" literally) to write the fortune data to the proper directory.
diff --git a/plugins/colorize/colorize.plugin.zsh b/plugins/colorize/colorize.plugin.zsh
index 12841e0ee..c49acd864 100644
--- a/plugins/colorize/colorize.plugin.zsh
+++ b/plugins/colorize/colorize.plugin.zsh
@@ -42,12 +42,12 @@ colorize_cat() {
ZSH_COLORIZE_STYLE="emacs"
fi
- # Use stdin if no arguments have been passed.
- if [ $# -eq 0 ]; then
+ # Use stdin if stdin is not attached to a terminal.
+ if [ ! -t 0 ]; then
if [[ "$ZSH_COLORIZE_TOOL" == "pygmentize" ]]; then
pygmentize -O style="$ZSH_COLORIZE_STYLE" -g
else
- chroma --style="$ZSH_COLORIZE_STYLE" --formatter="${ZSH_COLORIZE_CHROMA_FORMATTER:-terminal}"
+ chroma --style="$ZSH_COLORIZE_STYLE" --formatter="${ZSH_COLORIZE_CHROMA_FORMATTER:-terminal}" "$@"
fi
return $?
fi
diff --git a/plugins/conda/README.md b/plugins/conda/README.md
new file mode 100644
index 000000000..70530d01e
--- /dev/null
+++ b/plugins/conda/README.md
@@ -0,0 +1,37 @@
+# conda plugin
+
+The conda plugin provides [aliases](#aliases) for `conda`, usually installed via [anaconda](https://www.anaconda.com/) or [miniconda](https://docs.conda.io/en/latest/miniconda.html).
+
+To use it, add `conda` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... conda)
+```
+
+## Aliases
+
+| Alias | Command | Description |
+| :------- | :-------------------------------------- | :------------------------------------------------------------------------------ |
+| `cna` | `conda activate` | Activate the specified conda environment |
+| `cnab` | `conda activate base` | Activate the base conda environment |
+| `cncf` | `conda env create -f` | Create a new conda environment from a YAML file |
+| `cncn` | `conda create -y -n` | Create a new conda environment with the given name |
+| `cnconf` | `conda config` | View or modify conda configuration |
+| `cncp` | `conda create -y -p` | Create a new conda environment with the given prefix |
+| `cncr` | `conda create -n` | Create new virtual environment with given name |
+| `cncss` | `conda config --show-source` | Show the locations of conda configuration sources |
+| `cnde` | `conda deactivate` | Deactivate the current conda environment |
+| `cnel` | `conda env list` | List all available conda environments |
+| `cni` | `conda install` | Install given package |
+| `cniy` | `conda install -y` | Install given package without confirmation |
+| `cnl` | `conda list` | List installed packages in the current environment |
+| `cnle` | `conda list --export` | Export the list of installed packages in the current environment |
+| `cnles` | `conda list --explicit > spec-file.txt` | Export the list of installed packages in the current environment to a spec file |
+| `cnr` | `conda remove` | Remove given package |
+| `cnrn` | `conda remove -y -all -n` | Remove all packages in the specified environment |
+| `cnrp` | `conda remove -y -all -p` | Remove all packages in the specified prefix |
+| `cnry` | `conda remove -y` | Remove given package without confirmation |
+| `cnsr` | `conda search` | Search conda repositories for package |
+| `cnu` | `conda update` | Update conda package manager |
+| `cnua` | `conda update --all` | Update all installed packages |
+| `cnuc` | `conda update conda` | Update conda package manager |
diff --git a/plugins/conda/conda.plugin.zsh b/plugins/conda/conda.plugin.zsh
new file mode 100644
index 000000000..7a130ba7b
--- /dev/null
+++ b/plugins/conda/conda.plugin.zsh
@@ -0,0 +1,23 @@
+alias cna='conda activate'
+alias cnab='conda activate base'
+alias cncf='conda env create -f'
+alias cncn='conda create -y -n'
+alias cnconf='conda config'
+alias cncp='conda create -y -p'
+alias cncr='conda create -n'
+alias cncss='conda config --show-source'
+alias cnde='conda deactivate'
+alias cnel='conda env list'
+alias cni='conda install'
+alias cniy='conda install -y'
+alias cnl='conda list'
+alias cnle='conda list --export'
+alias cnles='conda list --explicit > spec-file.txt'
+alias cnr='conda remove'
+alias cnrn='conda remove -y --all -n'
+alias cnrp='conda remove -y --all -p'
+alias cnry='conda remove -y'
+alias cnsr='conda search'
+alias cnu='conda update'
+alias cnua='conda update --all'
+alias cnuc='conda update conda'
diff --git a/plugins/dash/dash.plugin.zsh b/plugins/dash/dash.plugin.zsh
index f6801a870..9abd691c7 100644
--- a/plugins/dash/dash.plugin.zsh
+++ b/plugins/dash/dash.plugin.zsh
@@ -1,5 +1,5 @@
# Usage: dash [keyword:]query
-dash() { open -a Dash.app dash://"$*" }
+dash() { open -a Dash.app "dash://$(omz_urlencode -r $*)" }
compdef _dash dash
_dash() {
diff --git a/plugins/debian/debian.plugin.zsh b/plugins/debian/debian.plugin.zsh
index 5ef4cfb67..980440c0f 100644
--- a/plugins/debian/debian.plugin.zsh
+++ b/plugins/debian/debian.plugin.zsh
@@ -83,9 +83,9 @@ else
}
alias ac="su -ls '$apt_pref clean' root"
alias ad="su -lc '$apt_pref update' root"
- alias adg="su -lc '$apt_pref update && aptitude $apt_upgr' root"
- alias adu="su -lc '$apt_pref update && aptitude dist-upgrade' root"
- alias afu="su -lc '$apt-file update'"
+ alias adg="su -lc '$apt_pref update && $apt_pref $apt_upgr' root"
+ alias adu="su -lc '$apt_pref update && $apt_pref dist-upgrade' root"
+ alias afu="su -lc 'apt-file update'"
alias au="su -lc '$apt_pref $apt_upgr' root"
function ai() {
cmd="su -lc '$apt_pref install $@' root"
diff --git a/plugins/direnv/direnv.plugin.zsh b/plugins/direnv/direnv.plugin.zsh
index 0a33194dd..c026dbe76 100644
--- a/plugins/direnv/direnv.plugin.zsh
+++ b/plugins/direnv/direnv.plugin.zsh
@@ -1,5 +1,8 @@
-# Don't continue if direnv is not found
-command -v direnv &>/dev/null || return
+# If direnv is not found, don't continue and print a warning
+if (( ! $+commands[direnv] )); then
+ echo "Warning: direnv not found. Please install direnv and ensure it's in your PATH before using this plugin."
+ return
+fi
_direnv_hook() {
trap -- '' SIGINT;
diff --git a/plugins/dirhistory/README.md b/plugins/dirhistory/README.md
index ede9b5410..66e3e0469 100644
--- a/plugins/dirhistory/README.md
+++ b/plugins/dirhistory/README.md
@@ -60,3 +60,46 @@ to `/usr` again.
After that, Alt + Down will probably go to `/usr/bin` if `bin` is the first directory in alphabetical
order (depends on your `/usr` folder structure). Alt + Up will return to `/usr`, and once more will get
you to the root folder (`/`).
+
+### cde
+
+This plugin also provides a `cde` alias that allows you to change to a directory without clearing the next directory stack.
+This changes the default behavior of `dirhistory`, which is to clear the next directory stack when changing directories.
+
+For example, if the shell was started, and the following commands were entered:
+
+```shell
+cd ~
+cd /usr
+cd share
+cd doc
+
+#
+#
+```
+
+The directory stack would look like this:
+
+```sh
+➜ /usr typeset -pm dirhistory_\*
+typeset -ax dirhistory_past=( /home/user /usr )
+typeset -ax dirhistory_future=( /usr/share/doc /usr/share )
+```
+
+This means that pressing Alt + Right, you'd go to `/usr/share` and `/usr/share/doc` (the "future" directories).
+
+If you run `cd /usr/bin`, the "future" directories will be removed, and you won't be able to access them with Alt + Right:
+
+```sh
+➜ /u/bin typeset -pm dirhistory_\*
+typeset -ax dirhistory_past=( /home/user /usr )
+typeset -ax dirhistory_future=( /usr/bin )
+```
+
+If you instead run `cde /usr/bin`, the "future" directories will be preserved:
+
+```sh
+➜ /u/bin typeset -pm dirhistory_\*
+typeset -ax dirhistory_past=( /home/user /usr /usr/bin )
+typeset -ax dirhistory_future=( /usr/share/doc /usr/share )
+```
diff --git a/plugins/dirhistory/dirhistory.plugin.zsh b/plugins/dirhistory/dirhistory.plugin.zsh
index 8d67c6188..706bb6fb2 100644
--- a/plugins/dirhistory/dirhistory.plugin.zsh
+++ b/plugins/dirhistory/dirhistory.plugin.zsh
@@ -11,9 +11,10 @@ dirhistory_past=($PWD)
dirhistory_future=()
export dirhistory_past
export dirhistory_future
-
export DIRHISTORY_SIZE=30
+alias cde='dirhistory_cd'
+
# Pop the last element of dirhistory_past.
# Pass the name of the variable to return the result in.
# Returns the element if the array was not empty,
@@ -136,7 +137,11 @@ for keymap in emacs vicmd viins; do
case "$TERM_PROGRAM" in
Apple_Terminal) bindkey -M $keymap "^[b" dirhistory_zle_dirhistory_back ;; # Terminal.app
- iTerm.app) bindkey -M $keymap "^[^[[D" dirhistory_zle_dirhistory_back ;; # iTerm2
+ ghostty) bindkey -M $keymap "^[b" dirhistory_zle_dirhistory_back ;; # ghostty
+ iTerm.app)
+ bindkey -M $keymap "^[^[[D" dirhistory_zle_dirhistory_back
+ bindkey -M $keymap "^[b" dirhistory_zle_dirhistory_back
+ ;;
esac
if (( ${+terminfo[kcub1]} )); then
@@ -151,7 +156,11 @@ for keymap in emacs vicmd viins; do
case "$TERM_PROGRAM" in
Apple_Terminal) bindkey -M $keymap "^[f" dirhistory_zle_dirhistory_future ;; # Terminal.app
- iTerm.app) bindkey -M $keymap "^[^[[C" dirhistory_zle_dirhistory_future ;; # iTerm2
+ ghostty) bindkey -M $keymap "^[f" dirhistory_zle_dirhistory_future ;; # ghostty
+ iTerm.app)
+ bindkey -M $keymap "^[^[[C" dirhistory_zle_dirhistory_future
+ bindkey -M $keymap "^[f" dirhistory_zle_dirhistory_future
+ ;;
esac
if (( ${+terminfo[kcuf1]} )); then
@@ -200,6 +209,7 @@ for keymap in emacs vicmd viins; do
case "$TERM_PROGRAM" in
Apple_Terminal) bindkey -M $keymap "^[[A" dirhistory_zle_dirhistory_up ;; # Terminal.app
iTerm.app) bindkey -M $keymap "^[^[[A" dirhistory_zle_dirhistory_up ;; # iTerm2
+ ghostty) bindkey -M $keymap "^[[1;3A" dirhistory_zle_dirhistory_up ;; # ghostty
esac
if (( ${+terminfo[kcuu1]} )); then
@@ -215,6 +225,7 @@ for keymap in emacs vicmd viins; do
case "$TERM_PROGRAM" in
Apple_Terminal) bindkey -M $keymap "^[[B" dirhistory_zle_dirhistory_down ;; # Terminal.app
iTerm.app) bindkey -M $keymap "^[^[[B" dirhistory_zle_dirhistory_down ;; # iTerm2
+ ghostty) bindkey -M $keymap "^[[1;3B" dirhistory_zle_dirhistory_down ;; # ghostty
esac
if (( ${+terminfo[kcud1]} )); then
diff --git a/plugins/dnf/_dnf5 b/plugins/dnf/_dnf5
new file mode 100644
index 000000000..3422fae32
--- /dev/null
+++ b/plugins/dnf/_dnf5
@@ -0,0 +1,570 @@
+#compdef dnf5
+# based on dnf-5.2.6.2
+
+# utility functions
+
+_dnf5_helper() {
+ _call_program specs $service "${(q-)@}" "${(q-)PREFIX}\*" \
+ -qC --assumeno --nogpgcheck 2>/dev/null command' '*:: :->cmd_args' && ret=0
+
+ case $state in
+ command) _dnf5_commands && ret=0 ;;
+ cmd_args) _dnf5_subcmds_opts && ret=0 ;;
+ esac
+ return ret
+}
+
+_dnf5 "$@"
diff --git a/plugins/docker/README.md b/plugins/docker/README.md
index 8619125a2..0bc24b54a 100644
--- a/plugins/docker/README.md
+++ b/plugins/docker/README.md
@@ -39,6 +39,10 @@ following setting. See https://github.com/ohmyzsh/ohmyzsh/issues/11789 for more
zstyle ':omz:plugins:docker' legacy-completion yes
```
+### For Podman's Docker wrapper users
+
+If you use Podman's Docker wrapper, you need to enable legacy completion. See above section.
+
## Aliases
| Alias | Command | Description |
@@ -73,6 +77,7 @@ zstyle ':omz:plugins:docker' legacy-completion yes
| drs | `docker container restart` | Restart one or more containers |
| dsta | `docker stop $(docker ps -q)` | Stop all running containers |
| dstp | `docker container stop` | Stop one or more running containers |
+| dsts | `docker stats` | Display real-time streaming statistics for containers |
| dtop | `docker top` | Display the running processes of a container |
| dvi | `docker volume inspect` | Display detailed information about one or more volumes |
| dvls | `docker volume ls` | List all the volumes known to docker |
diff --git a/plugins/docker/docker.plugin.zsh b/plugins/docker/docker.plugin.zsh
index 19269427e..5268f6cd6 100644
--- a/plugins/docker/docker.plugin.zsh
+++ b/plugins/docker/docker.plugin.zsh
@@ -28,6 +28,7 @@ alias dst='docker container start'
alias drs='docker container restart'
alias dsta='docker stop $(docker ps -q)'
alias dstp='docker container stop'
+alias dsts='docker stats'
alias dtop='docker top'
alias dvi='docker volume inspect'
alias dvls='docker volume ls'
@@ -39,7 +40,7 @@ if (( ! $+commands[docker] )); then
return
fi
-# Standarized $0 handling
+# Standardized $0 handling
# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
0="${${(M)0:#/*}:-$PWD/$0}"
diff --git a/plugins/dotnet/README.md b/plugins/dotnet/README.md
index a15e80577..217c46751 100644
--- a/plugins/dotnet/README.md
+++ b/plugins/dotnet/README.md
@@ -23,3 +23,4 @@ plugins=(... dotnet)
| dp | dotnet pack | Create a NuGet package. |
| dng | dotnet nuget | Provides additional NuGet commands. |
| db | dotnet build | Build a .NET project |
+| dres | dotnet restore | Restore dependencies and project-specific tools for a project. |
\ No newline at end of file
diff --git a/plugins/dotnet/dotnet.plugin.zsh b/plugins/dotnet/dotnet.plugin.zsh
index ed7c55024..2b7782474 100644
--- a/plugins/dotnet/dotnet.plugin.zsh
+++ b/plugins/dotnet/dotnet.plugin.zsh
@@ -10,7 +10,7 @@ _dotnet_completion() {
compdef _dotnet_completion dotnet
-# Aliases bellow are here for backwards compatibility
+# Aliases below are here for backwards compatibility
# added by Shaun Tabone (https://github.com/xontab)
alias dn='dotnet new'
@@ -24,3 +24,4 @@ alias da='dotnet add'
alias dp='dotnet pack'
alias dng='dotnet nuget'
alias db='dotnet build'
+alias dres='dotnet restore'
diff --git a/plugins/emacs/emacs.plugin.zsh b/plugins/emacs/emacs.plugin.zsh
index 5aa621803..3ed6cee19 100644
--- a/plugins/emacs/emacs.plugin.zsh
+++ b/plugins/emacs/emacs.plugin.zsh
@@ -35,7 +35,7 @@ alias eeval="$EMACS_PLUGIN_LAUNCHER --eval"
alias eframe='emacsclient --alternate-editor="" --create-frame'
# Emacs ANSI Term tracking
-if [[ -n "$INSIDE_EMACS" ]]; then
+if [[ -n "$INSIDE_EMACS" ]] && [[ "$INSIDE_EMACS" != "vterm" ]]; then
chpwd_emacs() { print -P "\033AnSiTc %d"; }
print -P "\033AnSiTc %d" # Track current working directory
print -P "\033AnSiTu %n" # Track username
diff --git a/plugins/ember-cli/README.md b/plugins/ember-cli/README.md
index 419704ade..1532eea9c 100644
--- a/plugins/ember-cli/README.md
+++ b/plugins/ember-cli/README.md
@@ -29,5 +29,5 @@ plugins=(... ember-cli)
- [BilalBudhani](https://github.com/BilalBudhani)
- [eubenesa](https://github.com/eubenesa)
-- [scottkidder](https://github.com/scottkidder]
+- [scottkidder](https://github.com/scottkidder)
- [t-sauer](https://www.github.com/t-sauer)
diff --git a/plugins/emoji/update_emoji.py b/plugins/emoji/update_emoji.py
index 18b3c060d..9e115a7fa 100644
--- a/plugins/emoji/update_emoji.py
+++ b/plugins/emoji/update_emoji.py
@@ -1,6 +1,6 @@
"""
Update Emoji.py
-Refeshes OMZ emoji database based on the latest Unicode spec
+Refreshes OMZ emoji database based on the latest Unicode spec
"""
import re
import json
@@ -95,7 +95,7 @@ def name_to_omz(_name, _group, _subgroup, _status):
shortname = snake_case(_name)
# Special treatment by status
# Enables us to have every emoji combination,
- # even the one that are not officially sanctionned
+ # even the one that are not officially sanctioned
# and are implemented by, say, only one vendor
if _status == "unqualified":
shortname += "_unqualified"
diff --git a/plugins/extract/README.md b/plugins/extract/README.md
index c8d98b229..7bedfb1c6 100644
--- a/plugins/extract/README.md
+++ b/plugins/extract/README.md
@@ -14,52 +14,56 @@ plugins=(... extract)
## Supported file extensions
-| Extension | Description |
-| :---------------- | :----------------------------------- |
-| `7z` | 7zip file |
-| `Z` | Z archive (LZW) |
-| `apk` | Android app file |
-| `aar` | Android library file |
-| `bz2` | Bzip2 file |
-| `cab` | Microsoft cabinet archive |
-| `cpio` | Cpio archive |
-| `deb` | Debian package |
-| `ear` | Enterprise Application aRchive |
-| `exe` | Windows executable file |
-| `gz` | Gzip file |
-| `ipa` | iOS app package |
-| `ipsw` | iOS firmware file |
-| `jar` | Java Archive |
-| `lrz` | LRZ archive |
-| `lz4` | LZ4 archive |
-| `lzma` | LZMA archive |
-| `obscpio` | cpio archive used on OBS |
-| `rar` | WinRAR archive |
-| `rpm` | RPM package |
-| `sublime-package` | Sublime Text package |
-| `tar` | Tarball |
-| `tar.bz2` | Tarball with bzip2 compression |
-| `tar.gz` | Tarball with gzip compression |
-| `tar.lrz` | Tarball with lrzip compression |
-| `tar.lz` | Tarball with lzip compression |
-| `tar.lz4` | Tarball with lz4 compression |
-| `tar.xz` | Tarball with lzma2 compression |
-| `tar.zma` | Tarball with lzma compression |
-| `tar.zst` | Tarball with zstd compression |
-| `tbz` | Tarball with bzip compression |
-| `tbz2` | Tarball with bzip2 compression |
-| `tgz` | Tarball with gzip compression |
-| `tlz` | Tarball with lzma compression |
-| `txz` | Tarball with lzma2 compression |
-| `tzst` | Tarball with zstd compression |
-| `war` | Web Application archive (Java-based) |
-| `whl` | Python wheel file |
-| `xpi` | Mozilla XPI module file |
-| `xz` | LZMA2 archive |
-| `zip` | Zip archive |
-| `zlib` | zlib archive |
-| `zst` | Zstandard file (zstd) |
-| `zpaq` | Zpaq file |
+| Extension | Description |
+| :---------------- | :-------------------------------------- |
+| `7z` | 7zip file |
+| `apk` | Android app file |
+| `aar` | Android library file |
+| `bz2` | Bzip2 file |
+| `cab` | Microsoft cabinet archive |
+| `cpio` | Cpio archive |
+| `deb` | Debian package |
+| `ear` | Enterprise Application aRchive |
+| `exe` | Windows executable file |
+| `gz` | Gzip file |
+| `ipa` | iOS app package |
+| `ipsw` | iOS firmware file |
+| `jar` | Java Archive |
+| `lrz` | LRZ archive |
+| `lz4` | LZ4 archive |
+| `lzma` | LZMA archive |
+| `obscpio` | cpio archive used on OBS |
+| `pk3` | Renamed Zip archive used by Quake games |
+| `pk4` | Renamed Zip archive used by Quake games |
+| `pk7` | Renamed 7zip file used by Quake games |
+| `rar` | WinRAR archive |
+| `rpm` | RPM package |
+| `sublime-package` | Sublime Text package |
+| `tar` | Tarball |
+| `tar.bz2` | Tarball with bzip2 compression |
+| `tar.gz` | Tarball with gzip compression |
+| `tar.lrz` | Tarball with lrzip compression |
+| `tar.lz` | Tarball with lzip compression |
+| `tar.lz4` | Tarball with lz4 compression |
+| `tar.xz` | Tarball with lzma2 compression |
+| `tar.zma` | Tarball with lzma compression |
+| `tar.zst` | Tarball with zstd compression |
+| `tbz` | Tarball with bzip compression |
+| `tbz2` | Tarball with bzip2 compression |
+| `tgz` | Tarball with gzip compression |
+| `tlz` | Tarball with lzma compression |
+| `txz` | Tarball with lzma2 compression |
+| `tzst` | Tarball with zstd compression |
+| `vsix` | VS Code extension zip file |
+| `war` | Web Application archive (Java-based) |
+| `whl` | Python wheel file |
+| `xpi` | Mozilla XPI module file |
+| `xz` | LZMA2 archive |
+| `Z` | Z archive (LZW) |
+| `zip` | Zip archive |
+| `zlib` | zlib archive |
+| `zst` | Zstandard file (zstd) |
+| `zpaq` | Zpaq file |
See [list of archive formats](https://en.wikipedia.org/wiki/List_of_archive_formats) for more information
regarding archive formats.
diff --git a/plugins/extract/_extract b/plugins/extract/_extract
index 56b17058f..6641443d3 100644
--- a/plugins/extract/_extract
+++ b/plugins/extract/_extract
@@ -1,7 +1,57 @@
#compdef extract
#autoload
+local -a exts=(
+ 7z
+ aar
+ apk
+ bz2
+ cab
+ cpio
+ crx
+ deb
+ ear
+ gz
+ ipa
+ ipsw
+ jar
+ lrz
+ lz4
+ lzma
+ obscpio
+ pk3
+ pk4
+ pk7
+ rar
+ rpm
+ sublime-package
+ tar
+ tar.bz2
+ tar.gz
+ tar.lrz
+ tar.lz
+ tar.lz4
+ tar.xz
+ tar.zma
+ tar.zst
+ tbz
+ tbz2
+ tgz
+ tlz
+ txz
+ tzst
+ vsix
+ war
+ whl
+ xpi
+ xz
+ Z
+ zip
+ zpaq
+ zst
+)
+
_arguments \
'(-r --remove)'{-r,--remove}'[Remove archive.]' \
- "*::archive file:_files -g '(#i)*.(7z|Z|apk|aar|bz2|cab|cpio|deb|ear|gz|ipa|ipsw|jar|lrz|lz4|lzma|obscpio|rar|rpm|sublime-package|tar|tar.bz2|tar.gz|tar.lrz|tar.lz|tar.lz4|tar.xz|tar.zma|tar.zst|tbz|tbz2|tgz|tlz|txz|tzst|war|whl|xpi|xz|zip|zst|zpaq)(-.)'" \
+ "*::archive file:_files -g '(#i)*.(${(j:|:)exts})(-.)'" \
&& return 0
diff --git a/plugins/extract/extract.plugin.zsh b/plugins/extract/extract.plugin.zsh
index e2b3111d5..d8cbc8b94 100644
--- a/plugins/extract/extract.plugin.zsh
+++ b/plugins/extract/extract.plugin.zsh
@@ -76,11 +76,11 @@ EOF
(*.lz4) lz4 -d "$full_path" ;;
(*.lzma) unlzma "$full_path" ;;
(*.z) uncompress "$full_path" ;;
- (*.zip|*.war|*.jar|*.ear|*.sublime-package|*.ipa|*.ipsw|*.xpi|*.apk|*.aar|*.whl) unzip "$full_path" ;;
+ (*.zip|*.war|*.jar|*.ear|*.sublime-package|*.ipa|*.ipsw|*.xpi|*.apk|*.aar|*.whl|*.vsix|*.crx|*.pk3|*.pk4) unzip "$full_path" ;;
(*.rar) unrar x -ad "$full_path" ;;
(*.rpm)
rpm2cpio "$full_path" | cpio --quiet -id ;;
- (*.7z | *.7z.[0-9]*) 7za x "$full_path" ;;
+ (*.7z | *.7z.[0-9]* | *.pk7) 7za x "$full_path" ;;
(*.deb)
command mkdir -p "control" "data"
ar vx "$full_path" > /dev/null
diff --git a/plugins/eza/README.md b/plugins/eza/README.md
index 90e549994..bec1f85cb 100644
--- a/plugins/eza/README.md
+++ b/plugins/eza/README.md
@@ -65,6 +65,29 @@ If `yes`, sets the `--icons` option of `eza`, adding icons for files and folders
Default: `no`
+### `color-scale`
+
+```zsh
+zstyle ':omz:plugins:eza' 'color-scale' all|age|size
+```
+
+Highlight levels of field(s) distinctly. Use comma(,) separated list of `all`, `age`, `size`
+
+Default: `none`
+
+### `color-scale-mode`
+
+```zsh
+zstyle ':omz:plugins:eza' 'color-scale-mode' gradient|fixed
+```
+
+Choose the mode for highlighting:
+
+- `gradient` (default) -- gradient coloring
+- `fixed` -- fixed coloring
+
+Default: `gradient`
+
### `size-prefix`
```zsh
diff --git a/plugins/eza/eza.plugin.zsh b/plugins/eza/eza.plugin.zsh
index f25f1c30b..60ed1eb27 100644
--- a/plugins/eza/eza.plugin.zsh
+++ b/plugins/eza/eza.plugin.zsh
@@ -34,6 +34,14 @@ function _configure_eza() {
if zstyle -t ':omz:plugins:eza' 'icons'; then
_EZA_TAIL+=("--icons=auto")
fi
+ zstyle -s ':omz:plugins:eza' 'color-scale' _val
+ if [[ $_val ]]; then
+ _EZA_TAIL+=("--color-scale=$_val")
+ fi
+ zstyle -s ':omz:plugins:eza' 'color-scale-mode' _val
+ if [[ $_val == (gradient|fixed) ]]; then
+ _EZA_TAIL+=("--color-scale-mode=$_val")
+ fi
zstyle -s ':omz:plugins:eza' 'time-style' _val
if [[ $_val ]]; then
_EZA_TAIL+=("--time-style='$_val'")
diff --git a/plugins/fastfile/fastfile.plugin.zsh b/plugins/fastfile/fastfile.plugin.zsh
index 896fed5f7..86f224b71 100644
--- a/plugins/fastfile/fastfile.plugin.zsh
+++ b/plugins/fastfile/fastfile.plugin.zsh
@@ -5,8 +5,8 @@
# If they are not set yet, they will be
# overwritten with their default values
-default fastfile_dir "${HOME}/.fastfile"
-default fastfile_var_prefix "§"
+fastfile_dir="${fastfile_dir:-${HOME}/.fastfile}"
+fastfile_var_prefix="${fastfile_var_prefix:-§}"
###########################
# Impl
diff --git a/plugins/foot/README.md b/plugins/foot/README.md
new file mode 100644
index 000000000..67777d9fa
--- /dev/null
+++ b/plugins/foot/README.md
@@ -0,0 +1,35 @@
+# foot
+
+This plugin adds shell integration for [foot, a fast, lightweight and
+minimalistic Wayland terminal emulator](https://codeberg.org/dnkl/foot).
+
+To use, add `foot` to the list of plugins in your `.zshrc` file:
+
+```zsh
+plugins=(... foot)
+```
+
+## Spawning new terminal instances in the current working directory
+
+When spawning a new terminal instance (with `ctrl+shift+n` by default), the new
+instance will start in the current working directory.
+
+## Jumping between prompts
+
+Foot can move the current viewport to focus prompts of already executed
+commands (bound to ctrl+shift+z/x by default).
+
+## Piping last command's output
+
+The key binding `pipe-command-output` can pipe the last command's output to an
+application of your choice (similar to the other `pipe-*` key bindings):
+
+```
+[key-bindings]
+pipe-command-output=[sh -c "f=$(mktemp); cat - > $f; footclient emacsclient -nw $f; rm $f"] Control+Shift+g
+```
+
+When pressing ctrl+shift+g, the last command's output is written to a
+temporary file, then an emacsclient is started in a new footclient instance.
+The temporary file is removed after the footclient instance has closed.
+
diff --git a/plugins/foot/foot.plugin.zsh b/plugins/foot/foot.plugin.zsh
new file mode 100644
index 000000000..c1d077e26
--- /dev/null
+++ b/plugins/foot/foot.plugin.zsh
@@ -0,0 +1,10 @@
+function precmd {
+ print -Pn "\e]133;A\e\\"
+ if ! builtin zle; then
+ print -n "\e]133;D\e\\"
+ fi
+}
+
+function preexec {
+ print -n "\e]133;C\e\\"
+}
diff --git a/plugins/gem/gem.plugin.zsh b/plugins/gem/gem.plugin.zsh
index b8a49fb56..41c434a09 100644
--- a/plugins/gem/gem.plugin.zsh
+++ b/plugins/gem/gem.plugin.zsh
@@ -11,7 +11,7 @@ function gemy {
if [[ ! -f "$ZSH_CACHE_DIR/completions/_gem" ]]; then
typeset -g -A _comps
autoload -Uz _gem
- _comps[docker]=_gem
+ _comps[gem]=_gem
fi
# zsh 5.5 already provides completion for `_gem`. With this we ensure that
@@ -23,7 +23,7 @@ if is-at-least 5.5; then
fi
{
- # Standarized $0 handling
+ # Standardized $0 handling
# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
0="${${(M)0:#/*}:-$PWD/$0}"
diff --git a/plugins/git-auto-fetch/README.md b/plugins/git-auto-fetch/README.md
index e96ab42a3..0d7431bba 100644
--- a/plugins/git-auto-fetch/README.md
+++ b/plugins/git-auto-fetch/README.md
@@ -18,7 +18,7 @@ You can change the fetch interval in your .zshrc:
GIT_AUTO_FETCH_INTERVAL=1200 # in seconds
```
-A log of `git fetch --all` will be saved in `.git/FETCH_LOG`.
+A log of `git-fetch-all` will be saved in `.git/FETCH_LOG`.
## Toggle auto-fetch per folder
diff --git a/plugins/git-prompt/gitstatus.py b/plugins/git-prompt/gitstatus.py
index 94774d828..7cd8f54e2 100644
--- a/plugins/git-prompt/gitstatus.py
+++ b/plugins/git-prompt/gitstatus.py
@@ -23,9 +23,10 @@ def get_tagname_or_hash():
return hash_
return None
-# Re-use method from https://github.com/magicmonty/bash-git-prompt to get stashs count
+# Re-use method from https://github.com/magicmonty/bash-git-prompt to get stash count
+# Use `--git-common-dir` to avoid problems with git worktrees, which don't have individual stashes
def get_stash():
- cmd = Popen(['git', 'rev-parse', '--git-dir'], stdout=PIPE, stderr=PIPE)
+ cmd = Popen(['git', 'rev-parse', '--git-common-dir'], stdout=PIPE, stderr=PIPE)
so, se = cmd.communicate()
stash_file = '%s%s' % (so.decode('utf-8').rstrip(), '/logs/refs/stash')
@@ -35,7 +36,6 @@ def get_stash():
except IOError:
return 0
-
# `git status --porcelain --branch` can collect all information
# branch, remote_branch, untracked, staged, changed, conflicts, ahead, behind
po = Popen(['git', 'status', '--porcelain', '--branch'], env=dict(os.environ, LANG="C"), stdout=PIPE, stderr=PIPE)
diff --git a/plugins/git/README.md b/plugins/git/README.md
index bcd9aca96..edddc8cd8 100644
--- a/plugins/git/README.md
+++ b/plugins/git/README.md
@@ -73,11 +73,13 @@ plugins=(... git)
| `gcans!` | `git commit --verbose --all --signoff --no-edit --amend` |
| `gcann!` | `git commit --verbose --all --date=now --no-edit --amend` |
| `gc!` | `git commit --verbose --amend` |
+| `gcn` | `git commit --verbose --no-edit` |
| `gcn!` | `git commit --verbose --no-edit --amend` |
| `gcs` | `git commit -S` |
| `gcss` | `git commit -S -s` |
| `gcssm` | `git commit -S -s -m` |
| `gcf` | `git config --list` |
+| `gcfu` | `git commit --fixup` |
| `gdct` | `git describe --tags $(git rev-list --tags --max-count=1)` |
| `gd` | `git diff` |
| `gdca` | `git diff --cached` |
@@ -114,6 +116,7 @@ plugins=(... git)
| `gma` | `git merge --abort` |
| `gmc` | `git merge --continue` |
| `gms` | `git merge --squash` |
+| `gmff` | `git merge --ff-only` |
| `gmom` | `git merge origin/$(git_main_branch)` |
| `gmum` | `git merge upstream/$(git_main_branch)` |
| `gmtl` | `git mergetool --no-prompt` |
@@ -125,6 +128,8 @@ plugins=(... git)
| `gprav` | `git pull --rebase --autostash -v` |
| `gprom` | `git pull --rebase origin $(git_main_branch)` |
| `gpromi` | `git pull --rebase=interactive origin $(git_main_branch)` |
+| `gprum` | `git pull --rebase upstream $(git_main_branch)` |
+| `gprumi` | `git pull --rebase=interactive upstream $(git_main_branch)` |
| `ggpull` | `git pull origin "$(git_current_branch)"` |
| `ggl` | `git pull origin $(current_branch)` |
| `gluc` | `git pull upstream $(git_current_branch)` |
@@ -154,6 +159,7 @@ plugins=(... git)
| `grbd` | `git rebase $(git_develop_branch)` |
| `grbm` | `git rebase $(git_main_branch)` |
| `grbom` | `git rebase origin/$(git_main_branch)` |
+| `grbum` | `git rebase upstream/$(git_main_branch)` |
| `grf` | `git reflog` |
| `gr` | `git remote` |
| `grv` | `git remote --verbose` |
diff --git a/plugins/git/git.plugin.zsh b/plugins/git/git.plugin.zsh
index 0a26399a2..335eaa8d0 100644
--- a/plugins/git/git.plugin.zsh
+++ b/plugins/git/git.plugin.zsh
@@ -86,7 +86,7 @@ function work_in_progress() {
# Aliases
# (sorted alphabetically by command)
# (order should follow README)
-# (in some cases force the alisas order to match README, like for example gke and gk)
+# (in some cases force the alias order to match README, like for example gke and gk)
#
alias grt='cd "$(git rev-parse --show-toplevel || echo .)"'
@@ -197,8 +197,10 @@ alias gcan!='git commit --verbose --all --no-edit --amend'
alias gcans!='git commit --verbose --all --signoff --no-edit --amend'
alias gcann!='git commit --verbose --all --date=now --no-edit --amend'
alias gc!='git commit --verbose --amend'
+alias gcn='git commit --verbose --no-edit'
alias gcn!='git commit --verbose --no-edit --amend'
alias gcf='git config --list'
+alias gcfu='git commit --fixup'
alias gdct='git describe --tags $(git rev-list --tags --max-count=1)'
alias gd='git diff'
alias gdca='git diff --cached'
@@ -255,6 +257,7 @@ alias gm='git merge'
alias gma='git merge --abort'
alias gmc='git merge --continue'
alias gms="git merge --squash"
+alias gmff="git merge --ff-only"
alias gmom='git merge origin/$(git_main_branch)'
alias gmum='git merge upstream/$(git_main_branch)'
alias gmtl='git mergetool --no-prompt'
@@ -274,6 +277,8 @@ compdef _git ggu=git-checkout
alias gprom='git pull --rebase origin $(git_main_branch)'
alias gpromi='git pull --rebase=interactive origin $(git_main_branch)'
+alias gprum='git pull --rebase upstream $(git_main_branch)'
+alias gprumi='git pull --rebase=interactive upstream $(git_main_branch)'
alias ggpull='git pull origin "$(git_current_branch)"'
function ggl() {
@@ -337,6 +342,7 @@ alias grbs='git rebase --skip'
alias grbd='git rebase $(git_develop_branch)'
alias grbm='git rebase $(git_main_branch)'
alias grbom='git rebase origin/$(git_main_branch)'
+alias grbum='git rebase upstream/$(git_main_branch)'
alias grf='git reflog'
alias gr='git remote'
alias grv='git remote --verbose'
diff --git a/plugins/gitfast/MANUAL.adoc b/plugins/gitfast/MANUAL.adoc
new file mode 100644
index 000000000..5333f5a2c
--- /dev/null
+++ b/plugins/gitfast/MANUAL.adoc
@@ -0,0 +1,40 @@
+This project is a friendly fork of the official Git completion
+(`contrib/completion`) and prompt scripts for Bash, Zsh, and possibly other
+shells.
+
+Most Git developers use the Bash shell, for which the completion scripts work
+rather well, however, Zsh is typically neglected. I've sent many patches to fix
+the issues, many have been merged, but many have been ignored, thus the need for
+a canonical location of a good, working Zsh completion.
+
+There are advantages for Bash users too. Currently the scripts under `contrib` are tied to the
+specific Git version, for example the completion scripts of version v2.40
+(https://git.kernel.org/pub/scm/git/git.git/plain/contrib/completion/git-completion.bash?h=v2.40.0[git-completion.bash])
+have issues with older versions of Git (e.g. v2.33); the ones in
+this project don't.
+
+With `git-completion` you can be sure you are using the latest completion that
+works in both shells, and any Git version.
+
+This is a sister project of the
+https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/gitfast[Oh My Zsh
+gitfast] plugin (that I also maintain), which has similar needs.
+
+== Installation ==
+
+* https://github.com/felipec/git-completion/wiki/Bash[Bash instructions]
+* https://github.com/felipec/git-completion/wiki/Zsh[Zsh instructions]
+
+== Improvements from upstream ==
+
+This is a short list of the benefits you get:
+
+* Easier installation
+* Tons of bug fixes
+* Works with older versions of git
+* Zsh: much more options
+* Zsh: quoting works properly
+* Zsh: automatic suffix removal
+
+For a full list of all the patches on top of upstream git check
+https://github.com/felipec/git-completion/wiki/Patches[Patches].
diff --git a/plugins/gitfast/_git b/plugins/gitfast/_git
index 31bf88c1c..1283c713e 100644
--- a/plugins/gitfast/_git
+++ b/plugins/gitfast/_git
@@ -2,23 +2,11 @@
# zsh completion wrapper for git
#
-# Copyright (c) 2012-2020 Felipe Contreras
+# Copyright (c) 2012-2024 Felipe Contreras
#
-# The recommended way to install this script is to make a copy of it as a
-# file named '_git' inside any directory in your fpath.
+# The recommended way to use this script is to prepend its location to your $fpath:
#
-# For example, create a directory '~/.zsh/', copy this file to '~/.zsh/_git',
-# and then add the following to your ~/.zshrc file:
-#
-# fpath=(~/.zsh $fpath)
-#
-# You need git's bash completion script installed. By default bash-completion's
-# location will be used (e.g. pkg-config --variable=completionsdir bash-completion).
-#
-# If your bash completion script is somewhere else, you can specify the
-# location in your ~/.zshrc:
-#
-# zstyle ':completion:*:*:git:*' script ~/.git-completion.bash
+# fpath=($git_completion_srcdir $fpath)
#
zstyle -T ':completion:*:*:git:*' tag-order && \
diff --git a/plugins/gitfast/git-completion.bash b/plugins/gitfast/git-completion.bash
index 9a2045f26..8a790ca69 100644
--- a/plugins/gitfast/git-completion.bash
+++ b/plugins/gitfast/git-completion.bash
@@ -1,6 +1,8 @@
# bash/zsh completion support for core Git.
#
# Copyright (C) 2006,2007 Shawn O. Pearce
+# Copyright (c) 2012-2024 Felipe Contreras
+#
# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
# Distributed under the GNU General Public License, version 2.0.
#
diff --git a/plugins/grc/grc.plugin.zsh b/plugins/grc/grc.plugin.zsh
index 55ffc1a1e..fc6ecc8ac 100644
--- a/plugins/grc/grc.plugin.zsh
+++ b/plugins/grc/grc.plugin.zsh
@@ -5,6 +5,7 @@ files=(
/etc/grc.zsh # default
/usr/local/etc/grc.zsh # homebrew darwin-x64
/opt/homebrew/etc/grc.zsh # homebrew darwin-arm64
+ /home/linuxbrew/.linuxbrew/etc/grc.zsh # linuxbrew
/usr/share/grc/grc.zsh # Gentoo Linux (app-misc/grc)
)
diff --git a/plugins/history-substring-search/history-substring-search.zsh b/plugins/history-substring-search/history-substring-search.zsh
index 2137b7950..9f0e0b0d5 100644
--- a/plugins/history-substring-search/history-substring-search.zsh
+++ b/plugins/history-substring-search/history-substring-search.zsh
@@ -295,8 +295,8 @@ _history-substring-search-begin() {
fi
#
- # Escape and join query parts with wildcard character '*' as seperator
- # `(j:CHAR:)` join array to string with CHAR as seperator
+ # Escape and join query parts with wildcard character '*' as separator
+ # `(j:CHAR:)` join array to string with CHAR as separator
#
local search_pattern="${(j:*:)_history_substring_search_query_parts[@]//(#m)[\][()|\\*?#<>~^]/\\$MATCH}*"
diff --git a/plugins/hitchhiker/fortunes/hitchhiker b/plugins/hitchhiker/fortunes/hitchhiker
index 94cc1c835..6620a2a4f 100644
--- a/plugins/hitchhiker/fortunes/hitchhiker
+++ b/plugins/hitchhiker/fortunes/hitchhiker
@@ -42,7 +42,7 @@
- Zaphod.
%
-"`In those days spirits were brave, the stakes were high, men were REAL men, women were REAL women, and small furry creatures from Alpha Centauri were REAL small furry creatures from Aplha Centauri.'"
+"`In those days spirits were brave, the stakes were high, men were REAL men, women were REAL women, and small furry creatures from Alpha Centauri were REAL small furry creatures from Alpha Centauri.'"
- The Book getting all nostalgic.
%
diff --git a/plugins/jira/README.md b/plugins/jira/README.md
index 7cfb81b19..f6e2e26f4 100644
--- a/plugins/jira/README.md
+++ b/plugins/jira/README.md
@@ -26,6 +26,7 @@ This plugin supplies one command, `jira`, through which all its features are exp
| `jira new` | Opens a new Jira issue dialogue |
| `jira ABC-123` | Opens an existing issue |
| `jira ABC-123 m` | Opens an existing issue for adding a comment |
+| `jira project ABC` | Opens JIRA project summary |
| `jira dashboard [rapid_view]` | Opens your JIRA dashboard |
| `jira mine` | Queries for your own issues |
| `jira tempo` | Opens your JIRA Tempo |
@@ -43,6 +44,22 @@ starting with "_": "MP-1234_fix_dashboard". In both these cases, the issue opene
This is also checks if the prefix is in the name, and adds it if not, so: "MP-1234" opens the issue "MP-1234",
"mp-1234" opens the issue "mp-1234", and "1234" opens the issue "MP-1234".
+If your branch naming convention deviates, you can overwrite the jira_branch function to determine and echo the Jira issue key yourself.
+Define a function `jira_branch` after sourcing `oh-my-zsh.sh` in your `.zshrc`.
+Example:
+```zsh
+# Determine branch name from naming convention 'type/KEY-123/description'.
+function jira_branch() {
+ # Get name of the branch
+ issue_arg=$(git rev-parse --abbrev-ref HEAD)
+ # Strip prefixes like feature/ or bugfix/
+ issue_arg=${issue_arg#*/}
+ # Strip suffixes like /some-branch-description
+ issue_arg=${issue_arg%%/*}
+ # Return the value
+ echo $issue_arg
+}
+```
#### Debugging usage
diff --git a/plugins/jira/_jira b/plugins/jira/_jira
index 5f7dcd09d..617a3e501 100644
--- a/plugins/jira/_jira
+++ b/plugins/jira/_jira
@@ -5,6 +5,7 @@ local -a _1st_arguments
_1st_arguments=(
'new:create a new issue'
'mine:open my issues'
+ 'project:open the project'
'dashboard:open the dashboard'
'tempo:open the tempo'
'reported:search for issues reported by a user'
diff --git a/plugins/jira/jira.plugin.zsh b/plugins/jira/jira.plugin.zsh
index 9bcf4cc7b..0c90544d5 100644
--- a/plugins/jira/jira.plugin.zsh
+++ b/plugins/jira/jira.plugin.zsh
@@ -8,6 +8,7 @@ jira Performs the default action
jira new Opens a new Jira issue dialogue
jira ABC-123 Opens an existing issue
jira ABC-123 m Opens an existing issue for adding a comment
+jira project ABC Opens JIRA project summary
jira dashboard [rapid_view] Opens your JIRA dashboard
jira mine Queries for your own issues
jira tempo Opens your JIRA Tempo
@@ -17,6 +18,30 @@ jira branch Opens an existing issue matching the current bra
EOF
}
+# If your branch naming convention deviates, you can partially override this plugin function
+# to determine the jira issue key based on your formatting.
+# See https://github.com/ohmyzsh/ohmyzsh/wiki/Customization#partially-overriding-an-existing-plugin
+function jira_branch() {
+ # Get name of the branch
+ issue_arg=$(git rev-parse --abbrev-ref HEAD)
+ # Strip prefixes like feature/ or bugfix/
+ issue_arg=${issue_arg##*/}
+ # Strip suffixes starting with _
+ issue_arg=(${(s:_:)issue_arg})
+ # If there is only one part, it means that there is a different delimiter. Try with -
+ if [[ ${#issue_arg[@]} = 1 && ${issue_arg} == *-* ]]; then
+ issue_arg=(${(s:-:)issue_arg})
+ issue_arg="${issue_arg[1]}-${issue_arg[2]}"
+ else
+ issue_arg=${issue_arg[1]}
+ fi
+ if [[ "${issue_arg:l}" = ${jira_prefix:l}* ]]; then
+ echo "${issue_arg}"
+ else
+ echo "${jira_prefix}${issue_arg}"
+ fi
+}
+
function jira() {
emulate -L zsh
local action jira_url jira_prefix
@@ -64,6 +89,9 @@ function jira() {
elif [[ "$action" == "mine" ]]; then
echo "Opening my issues"
open_command "${jira_url}/issues/?filter=-1"
+ elif [[ "$action" == "project" ]]; then
+ echo "Opening project"
+ open_command "${jira_url}/jira/software/c/projects/${2}/summary"
elif [[ "$action" == "dashboard" ]]; then
echo "Opening dashboard"
if [[ "$JIRA_RAPID_BOARD" == "true" ]]; then
@@ -91,24 +119,7 @@ function jira() {
# but `branch` is a special case that will parse the current git branch
local issue_arg issue
if [[ "$action" == "branch" ]]; then
- # Get name of the branch
- issue_arg=$(git rev-parse --abbrev-ref HEAD)
- # Strip prefixes like feature/ or bugfix/
- issue_arg=${issue_arg##*/}
- # Strip suffixes starting with _
- issue_arg=(${(s:_:)issue_arg})
- # If there is only one part, it means that there is a different delimiter. Try with -
- if [[ ${#issue_arg[@]} = 1 && ${issue_arg} == *-* ]]; then
- issue_arg=(${(s:-:)issue_arg})
- issue_arg="${issue_arg[1]}-${issue_arg[2]}"
- else
- issue_arg=${issue_arg[1]}
- fi
- if [[ "${issue_arg:l}" = ${jira_prefix:l}* ]]; then
- issue="${issue_arg}"
- else
- issue="${jira_prefix}${issue_arg}"
- fi
+ issue=$(jira_branch)
else
issue_arg=${(U)action}
issue="${jira_prefix}${issue_arg}"
diff --git a/plugins/jj/README.md b/plugins/jj/README.md
new file mode 100644
index 000000000..541b8f907
--- /dev/null
+++ b/plugins/jj/README.md
@@ -0,0 +1,90 @@
+# jj - Jujutsu CLI
+
+This plugin provides autocompletion for [jj](https://martinvonz.github.io/jj).
+
+To use it, add `jj` to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... jj)
+```
+
+## Aliases
+
+| Alias | Command |
+| ------ | ----------------------------- |
+| jjc | `jj commit` |
+| jjcmsg | `jj commit --message` |
+| jjd | `jj diff` |
+| jjdmsg | `jj desc --message` |
+| jjds | `jj desc` |
+| jje | `jj edit` |
+| jjgcl | `jj git clone` |
+| jjgf | `jj git fetch` |
+| jjgfa | `jj git fetch --all-remotes` |
+| jjgp | `jj git push` |
+| jjl | `jj log` |
+| jjla | `jj log -r "all()"` |
+| jjn | `jj new` |
+| jjrb | `jj rebase` |
+| jjrs | `jj restore` |
+| jjrt | `cd "$(jj root \|\| echo .)"` |
+| jjsp | `jj split` |
+| jjsq | `jj squash` |
+
+## Prompt usage
+
+Because `jj` has a very powerful [template syntax](https://martinvonz.github.io/jj/latest/templates/), this
+plugin only exposes a convenience function `jj_prompt_template` to read information from the current change.
+It is basically the same as `jj log --no-graph -r @ -T $1`:
+
+```sh
+_my_theme_jj_info() {
+ jj_prompt_template 'self.change_id().shortest(3)'
+}
+
+PROMPT='$(_my_theme_jj_info) $'
+```
+
+`jj_prompt_template` escapes `%` signs in the output. Use `jj_prompt_template_raw` if you don't want that
+(e.g. to colorize the output).
+
+However, because `jj` can be used inside a Git repository, some themes might clash with it. Generally, you can
+fix it with a wrapper function that tries `jj` first and then falls back to `git` if it didn't work:
+
+```sh
+_my_theme_vcs_info() {
+ jj_prompt_template 'self.change_id().shortest(3)' \
+ || git_prompt_info
+}
+
+PROMPT='$(_my_theme_vcs_info) $'
+```
+
+You can find an example
+[here](https://github.com/nasso/omzsh/blob/e439e494f22f4fd4ef1b6cb64626255f4b341c1b/themes/sunakayu.zsh-theme).
+
+### Performance
+
+Sometimes `jj` can be slower than `git`.
+
+If you feel slowdowns, consider using the following:
+
+```
+zstyle :omz:plugins:jj ignore-working-copy yes
+```
+
+This will add `--ignore-working-copy` to all `jj` commands executed by your prompt. The downside here is that
+your prompt might be out-of-sync until the next time `jj` gets a chance to _not_ ignore the working copy (i.e.
+you manually run a `jj` command).
+
+If you prefer to keep your prompt always up-to-date but still don't want to _feel_ the slowdown, you can make
+your prompt asynchronous. This plugin doesn't do this automatically so you'd have to hack your theme a bit for
+that.
+
+## See Also
+
+- [martinvonz/jj](https://github.com/martinvonz/jj)
+
+## Contributors
+
+- [nasso](https://github.com/nasso) - Plugin Author
diff --git a/plugins/jj/jj.plugin.zsh b/plugins/jj/jj.plugin.zsh
new file mode 100644
index 000000000..825460517
--- /dev/null
+++ b/plugins/jj/jj.plugin.zsh
@@ -0,0 +1,54 @@
+# if jj is not found, don't do the rest of the script
+if (( ! $+commands[jj] )); then
+ return
+fi
+
+# If the completion file doesn't exist yet, we need to autoload it and
+# bind it to `jj`. Otherwise, compinit will have already done that.
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_jj" ]]; then
+ typeset -g -A _comps
+ autoload -Uz _jj
+ _comps[jj]=_jj
+fi
+
+COMPLETE=zsh jj >| "$ZSH_CACHE_DIR/completions/_jj" &|
+
+function __jj_prompt_jj() {
+ local -a flags
+ flags=("--no-pager")
+ if zstyle -t ':omz:plugins:jj' ignore-working-copy; then
+ flags+=("--ignore-working-copy")
+ fi
+ command jj $flags "$@"
+}
+
+# convenience functions for themes
+function jj_prompt_template_raw() {
+ __jj_prompt_jj log --no-graph -r @ -T "$@" 2> /dev/null
+}
+
+function jj_prompt_template() {
+ local out
+ out=$(jj_prompt_template_raw "$@") || return 1
+ echo "${out:gs/%/%%}"
+}
+
+# Aliases (sorted alphabetically)
+alias jjc='jj commit'
+alias jjcmsg='jj commit --message'
+alias jjd='jj diff'
+alias jjdmsg='jj desc --message'
+alias jjds='jj desc'
+alias jje='jj edit'
+alias jjgcl='jj git clone'
+alias jjgf='jj git fetch'
+alias jjgfa='jj git fetch --all-remotes'
+alias jjgp='jj git push'
+alias jjl='jj log'
+alias jjla='jj log -r "all()"'
+alias jjn='jj new'
+alias jjrb='jj rebase'
+alias jjrs='jj restore'
+alias jjrt='cd "$(jj root || echo .)"'
+alias jjsp='jj split'
+alias jjsq='jj squash'
diff --git a/plugins/jsontools/README.md b/plugins/jsontools/README.md
index 6a2740014..804edba40 100644
--- a/plugins/jsontools/README.md
+++ b/plugins/jsontools/README.md
@@ -8,6 +8,17 @@ To use it, add `jsontools` to the plugins array in your zshrc file:
plugins=(... jsontools)
```
+## Requirements
+
+The plugin uses one of these tools to process JSON data, in the following order:
+
+- `node`
+- `python3`
+- `ruby`
+
+Any of these must be in `$PATH` before the plugin is loaded, otherwise the plugin exits
+prematurely and the functions will not be available.
+
## Usage
Usage is simple... just take your json data and pipe it into the appropriate jsontool:
@@ -19,7 +30,7 @@ Usage is simple... just take your json data and pipe it into the appropriate jso
### Supports NDJSON (Newline Delimited JSON)
-The plugin also supports [NDJSON](http://ndjson.org/) input, which means all functions
+The plugin also supports [NDJSON](https://github.com/ndjson/ndjson-spec) input, which means all functions
have an alternative function that reads and processes the input line by line. These
functions have the same name except using `ndjson` instead of `json`:
diff --git a/plugins/k9s/README.md b/plugins/k9s/README.md
new file mode 100644
index 000000000..275048cdb
--- /dev/null
+++ b/plugins/k9s/README.md
@@ -0,0 +1,9 @@
+# k9s plugin
+
+This plugin adds completion support for the [k9s](https://k9scli.io).
+
+To use it, add `k9s` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... k9s)
+```
diff --git a/plugins/k9s/k9s.plugin.zsh b/plugins/k9s/k9s.plugin.zsh
new file mode 100644
index 000000000..630d4f7d3
--- /dev/null
+++ b/plugins/k9s/k9s.plugin.zsh
@@ -0,0 +1,14 @@
+if (( ! $+commands[k9s] )); then
+ return
+fi
+
+# If the completion file does not exist, fake it and load it
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_k9s" ]]; then
+ typeset -g -A _comps
+ autoload -Uz _k9s
+ _comps[k9s]=_k9s
+fi
+
+# and then generate it in the background. On first completion,
+# the actual completion file will be loaded.
+k9s completion zsh >| "$ZSH_CACHE_DIR/completions/_k9s" &|
diff --git a/plugins/kamal/README.md b/plugins/kamal/README.md
new file mode 100644
index 000000000..af5716826
--- /dev/null
+++ b/plugins/kamal/README.md
@@ -0,0 +1,16 @@
+# Kamal
+
+This plugin provides completion for [Kamal](https://kamal-deploy.org/) as well as some
+aliases for frequent Kamal commands.
+
+To use it, add kamal to the plugins array of your zshrc file:
+
+```zsh
+plugins=(... kamal)
+```
+
+## Aliase
+
+| Alias | Command | Description |
+|-----------|----------------------------------|----------------------------------------------------------------------------------|
+| kad | `kamal deploy` | Deploy app to servers |
diff --git a/plugins/kamal/_kamal b/plugins/kamal/_kamal
new file mode 100644
index 000000000..52b29e814
--- /dev/null
+++ b/plugins/kamal/_kamal
@@ -0,0 +1,691 @@
+#compdef kamal
+
+# Description
+# -----------
+# zsh completion for Kamal (https://kamal-deploy.org/)
+# -------------------------------------------------------------------------
+# Authors
+# -------
+# * Igor Aleksandrov
+# -------------------------------------------------------------------------
+# Inspiration
+# -----------
+# * docker-compose ohmyzsh completion script by @sdurrheimer Steve Durrheimer
+# -------------------------------------------------------------------------
+
+# _kamal_commands() {
+# # Only initialize if empty
+# if (( ${#kamal_commands} == 0 )); then
+# kamal_commands=(
+# accessory
+# app
+# audit
+# build
+# config
+# deploy
+# details
+# docs
+# help
+# init
+# lock
+# proxy
+# prune
+# redeploy
+# registry
+# remove
+# rollback
+# secrets
+# server
+# setup
+# upgrade
+# version
+# )
+# fi
+
+# _values 'Kamal commands' $kamal_commands
+# }
+
+typeset -gr _kamal_commands=(
+ 'accessory:Control accessory services'
+ 'app:Control application deployment'
+ 'audit:Audit security of deployment'
+ 'build:Build and manage app images'
+ 'config:Show effective configuration'
+ 'deploy:Deploy app to servers'
+ 'details:Show details about deployment'
+ 'docs:Open documentation in browser'
+ 'help:Show command help'
+ 'init:Initialize new Kamal project'
+ 'lock:Manage deployment locks'
+ 'proxy:Control reverse proxy'
+ 'prune:Clean up containers and images'
+ 'redeploy:Redeploy current version'
+ 'registry:Manage Docker registry access'
+ 'remove:Remove app from servers'
+ 'rollback:Rollback to a previous version'
+ 'secrets:Manage deployment secrets'
+ 'server:Control server configuration'
+ 'setup:Setup initial deployment'
+ 'upgrade:Upgrade deployment'
+ 'version:Show Kamal version'
+)
+
+# Helper function to display messages
+_kamal_message() {
+ local msg="$1"
+ _kamal_message "==> $msg"
+}
+
+# Helper function to extract destination names from ./config/deploy.*.yml
+_kamal_destinations() {
+ local -a dests
+ local file
+
+ # Check if config directory exists
+ if [[ ! -d "config" ]]; then
+ _kamal_message "Cannot find Kamal configuration directory at ./config" && return 1
+ fi
+
+ for file in config/deploy.*.yml(N); do
+ [[ $file =~ config/deploy\.(.+)\.yml ]] && dests+=("${match[1]}")
+ done
+
+ _values 'Destination' $dests
+}
+
+# Define global _kamal_flags array
+typeset -ga _kamal_flags
+_kamal_flags=(
+ '(-v --verbose )'{-v,--verbose}'[Detailed logging]'
+ '(--no-verbose --skip-verbose)'{--no-verbose,--skip-verbose}'[No detailed logging]'
+ '(-q --quiet --no-quiet --skip-quiet)'{-q,--quiet}'[Minimal logging]'
+ '(-q --quiet --no-quiet --skip-quiet)'{--no-quiet,--skip-quiet}'[No minimal logging]'
+ '--version=[Run commands against a specific app version]:version'
+ '(-p --primary --no-primary --skip-primary)'{-p,--primary}'[Run commands only on primary host instead of all]'
+ '(-p --primary --no-primary --skip-primary)'{--no-primary,--skip-primary}'[Do not run commands only on primary host]'
+ '(-h --hosts)'{-h,--hosts=}'[Run commands on these hosts instead of all]:hosts'
+ '(-r --roles)'{-r,--roles=}'[Run commands on these roles instead of all]:roles'
+ '(-c --config-file)'{-c,--config-file=}'[Path to config file]:config file:_files'
+ '(-d --destination)'{-d,--destination=}'[Specify destination to be used for config file]:destination:_kamal_destinations'
+ '(-H --skip-hooks)'{-H,--skip-hooks}'[Do not run hooks]'
+)
+
+_kamal() {
+ local context state state_descr line curcontext="$curcontext"
+ typeset -A opt_args
+
+ local ret=1
+
+ _arguments -C \
+ $_kamal_flags \
+ '1: :->command' \
+ '*:: :->args' && ret=0
+
+ case $state in
+ (command)
+ # First argument - show available commands
+ _describe -t kamal-commands "Kamal commands" _kamal_commands && ret=0
+ ;;
+ (args)
+ # Subsequent arguments - handle based on the command
+ case $words[1] in
+ (accessory)
+ _kamal_accessory && ret=0
+ ;;
+ (app)
+ _kamal_app && ret=0
+ ;;
+ (audit)
+ _arguments $_kamal_flags && ret=0
+ ;;
+ (build)
+ _kamal_build && ret=0
+ ;;
+ (config)
+ _arguments $_kamal_flags && ret=0
+ ;;
+ (deploy)
+ _arguments $_kamal_flags && ret=0
+ ;;
+ (details)
+ _arguments $_kamal_flags && ret=0
+ ;;
+ (docs)
+ _arguments $_kamal_flags && ret=0
+ ;;
+ (help)
+ _kamal_help && ret=0
+ ;;
+ (init)
+ local -a init_flags
+ init_flags=(
+ $_kamal_flags
+ '(--bundle --no-bundle --skip-bundle)--bundle[Add Kamal to the Gemfile and create a bin/kamal binstub]'
+ '(--bundle --no-bundle --skip-bundle)--no-bundle[Do not add Kamal to the Gemfile and create a bin/kamal binstub]'
+ '(--bundle --no-bundle --skip-bundle)--skip-bundle[Skip add Kamal to the Gemfile and create a bin/kamal binstub]'
+ )
+ _arguments $init_flags && ret=0
+ ;;
+ (lock)
+ _kamal_lock && ret=0
+ ;;
+ (proxy)
+ _kamal_proxy && ret=0
+ ;;
+ (prune)
+ _kamal_prune && ret=0
+ ;;
+ (redeploy)
+ _arguments $_kamal_flags && ret=0
+ ;;
+ (registry)
+ _kamal_registry && ret=0
+ ;;
+ (remove)
+ local -a remove_flags
+ remove_flags=(
+ $_kamal_flags
+ '(-y --confirmed --no-confirmed --skip-confirmed)'{-y,--confirmed}'[Proceed without confirmation question]'
+ '(-y --confirmed --no-confirmed --skip-confirmed)--no-confirmed[Proceed without confirmation question]'
+ '(-y --confirmed --no-confirmed --skip-confirmed)--skip-confirmed[Proceed without confirmation question]'
+ )
+ _arguments $remove_flags && ret=0
+ ;;
+ (rollback)
+ if (( CURRENT == 2 )); then
+ _kamal_message "Enter the version to rollback to" && ret=0
+ else
+ _values $_kamal_flags && ret=0
+ fi
+ ;;
+ (secrets)
+ _kamal_secrets && ret=0
+ ;;
+ (server)
+ _kamal_server && ret=0
+ ;;
+ (setup)
+ local -a setup_flags
+ setup_flags=(
+ $_kamal_flags
+ '(-P --skip-push)'{-P,--skip-push}'[Skip image build and push]'
+ )
+ _arguments $setup_flags && ret=0
+ ;;
+ (upgrade)
+ local -a upgrade_flags
+ upgrade_flags=(
+ $_kamal_flags
+ '(-y --confirmed --no-confirmed --skip-confirmed)'{-y,--confirmed}'[Proceed without confirmation question]'
+ '(-y --confirmed --no-confirmed --skip-confirmed)--no-confirmed[Do not proceed without confirmation question]'
+ '(-y --confirmed --no-confirmed --skip-confirmed)--skip-confirmed[Skip confirmation question]'
+ '(--rolling --no-rolling --skip-rolling)--rolling[Upgrade one host at a time]'
+ '(--rolling --no-rolling --skip-rolling)--no-rolling[Do not upgrade one host at a time]'
+ '(--rolling --no-rolling --skip-rolling)--skip-rolling[Skip rolling upgrade]'
+ )
+ _arguments $upgrade_flags && ret=0
+ ;;
+ (version)
+ _arguments $_kamal_flags && ret=0
+ esac
+ ;;
+ esac
+
+ return ret
+}
+
+_kamal_accessory() {
+ local context state line
+ typeset -A opt_args
+ local ret=1
+
+ # Define accessory subcommands
+ local -a accessory_subcommands
+ accessory_subcommands=(
+ "boot:Boot new accessory service on host (use NAME=all to boot all accessories)"
+ "details:Show details about accessory on host (use NAME=all to show all accessories)"
+ "exec:Execute a custom command on servers within the accessory container (use --help to show options)"
+ "help:Describe subcommands or one specific subcommand"
+ "logs:Show log lines from accessory on host (use --help to show options)"
+ "reboot:Reboot existing accessory on host (stop container, remove container, start new container; use NAME=all to boot all accessories)"
+ "remove:Remove accessory container, image and data directory from host (use NAME=all to remove all accessories)"
+ "restart:Restart existing accessory container on host"
+ "start:Start existing accessory container on host"
+ "stop:Stop existing accessory container on host"
+ "upgrade:Upgrade accessories from Kamal 1.x to 2.0 (restart them in 'kamal' network)"
+ )
+
+ _arguments -C \
+ '1: :->subcmd' \
+ '*:: :->args' && ret=0
+
+ case $state in
+ (subcmd)
+ _describe -t accessory-commands "Kamal accessory commands" accessory_subcommands && ret=0
+ ;;
+ (args)
+ case $words[1] in
+ (boot|details|exec|logs|reboot|remove|restart|start|stop)
+ # These commands require a NAME parameter
+ if (( CURRENT == 2 )); then
+ # At the NAME position - we could add accessory name completion here
+ # if we had a way to list available accessories
+ _kamal_message "Specify an accessory name (or 'all' for all accessories)" && ret=0
+ elif [[ "$words[1]" == "exec" && CURRENT == 3 ]]; then
+ # For exec, the 3rd argument is a command
+ _kamal_message "Enter a command to execute" && ret=0
+ elif (( CURRENT > 2 )) && [[ "$words[1]" != "exec" || CURRENT > 3 ]]; then
+ _values $_kamal_flags && ret=0
+ fi
+ ;;
+ (help)
+ # Remove help itself from the list of commands
+ accessory_subcommands=("${(@)accessory_subcommands:#help*}")
+ _describe -t accessory-help-commands "Kamal accessory help commands" accessory_subcommands
+ ;;
+ (upgrade)
+ # For upgrade, show flags immediately
+ _arguments $_kamal_flags && ret=0
+ ;;
+ esac
+ ;;
+ esac
+
+ return ret
+}
+
+_kamal_app() {
+ local context state line
+ typeset -A opt_args
+ local ret=1
+
+ local -a app_subcommands
+ app_subcommands=(
+ "boot:Boot app on servers (or reboot app if already running)"
+ "containers:Show app containers on servers"
+ "details:Show details about app containers"
+ "exec:Execute a custom command on servers within the app container (use --help to show options)"
+ "help:Describe subcommands or one specific subcommand"
+ "images:Show app images on servers"
+ "logs:Show log lines from app on servers (use --help to show options)"
+ "remove:Remove app containers and images from servers"
+ "stale_containers:Detect app stale containers"
+ "start:Start existing app container on servers"
+ "stop:Stop app container on servers"
+ "version:Show app version currently running on servers"
+ )
+
+ _arguments -C \
+ '1: :->subcmd' \
+ '*:: :->args' && ret=0
+
+ case $state in
+ (subcmd)
+ _describe -t app-commands "Kamal app commands" app_subcommands && ret=0
+ ;;
+ (args)
+ case $words[1] in
+ (boot|containers|details|images|logs|remove|stale_containers|start|stop)
+ _arguments $_kamal_flags && ret=0
+ ;;
+ (exec)
+ # For exec, the next argument is a command
+ if (( CURRENT == 2 )); then
+ _kamal_message "Enter a command to execute" && ret=0
+ else
+ _values $_kamal_flags && ret=0
+ fi
+ ;;
+ (help)
+ # Remove help itself from the list of commands
+ app_subcommands=("${(@)app_subcommands:#help*}")
+ _describe -t app-help-commands "Kamal app help commands" app_subcommands
+ ;;
+ esac
+ ;;
+ esac
+
+ return ret
+}
+
+_kamal_build() {
+ local context state line
+ typeset -A opt_args
+ local ret=1
+
+ local -a build_subcommands
+ build_subcommands=(
+ "create:Create a build setup"
+ "deliver:Build app and push app image to registry then pull image on servers"
+ "details:Show build setup"
+ "dev:Build using the working directory, tag it as dirty, and push to local image store."
+ "help:Describe subcommands or one specific subcommand"
+ "pull:Pull app image from registry onto servers"
+ "push:Build and push app image to registry"
+ "remove:Remove build setup"
+ )
+
+ _arguments -C \
+ '1: :->subcmd' \
+ '*:: :->args' && ret=0
+
+ case $state in
+ (subcmd)
+ _describe -t build-commands "Kamal build commands" build_subcommands && ret=0
+ ;;
+ (args)
+ case $words[1] in
+ (create|deliver|details|dev|pull|push|remove)
+ _arguments $_kamal_flags && ret=0
+ ;;
+ (help)
+ # Remove help itself from the list of commands
+ build_subcommands=("${(@)build_subcommands:#help*}")
+ _describe -t build-help-commands "Kamal build help commands" build_subcommands
+ ;;
+ esac
+ ;;
+ esac
+
+ return ret
+}
+
+_kamal_help() {
+ local ret=1
+
+ # Make sure kamal_commands is initialized properly
+ # if (( ${#kamal_commands} == 0 )); then
+ # _kamal_commands >/dev/null
+ # fi
+
+ # If we already have a command after "help", return without suggestions
+ if (( CURRENT > 2 )); then
+ ret=0
+ else
+ local -a help_commands
+ # Filter out help from the list of commands
+ help_commands=("${(@)_kamal_commands:#help}")
+
+ _values 'Kamal help' $help_commands && ret=0
+ fi
+
+ return ret
+}
+
+_kamal_lock() {
+ local context state line
+ typeset -A opt_args
+ local ret=1
+
+ local -a lock_subcommands
+ lock_subcommands=(
+ "acquire:Acquire the deploy lock"
+ "help:Describe subcommands or one specific subcommand"
+ "release:Release the deploy lock"
+ "status:Report lock status"
+ )
+
+ _arguments -C \
+ '1: :->subcmd' \
+ '*:: :->args' && ret=0
+
+ case $state in
+ (subcmd)
+ _describe -t lock-commands "Kamal lock commands" lock_subcommands && ret=0
+ ;;
+ (args)
+ case $words[1] in
+ (acquire)
+ local -a acquire_flags
+ acquire_flags=(
+ $_kamal_flags
+ '(-m --message)'{-m,--message=}'[A lock message]:message:' # Required flag
+ )
+ _arguments $acquire_flags && ret=0
+ ;;
+ (release|status)
+ _arguments $_kamal_flags && ret=0
+ ;;
+ (help)
+ # Remove help itself from the list of commands
+ lock_subcommands=("${(@)lock_subcommands:#help*}")
+ _describe -t lock-help-commands "Kamal lock help commands" lock_subcommands
+ ;;
+ esac
+ ;;
+ esac
+
+ return ret
+}
+
+_kamal_proxy() {
+ local context state line
+ typeset -A opt_args
+ local ret=1
+
+ local -a proxy_subcommands
+ proxy_subcommands=(
+ "boot:Boot proxy on servers"
+ "boot_config:Manage kamal-proxy boot configuration"
+ "details:Show details about proxy container from servers"
+ "help:Describe subcommands or one specific subcommand"
+ "logs:Show log lines from proxy on servers"
+ "reboot:Reboot proxy on servers (stop container, remove container, start new container)"
+ "remove:Remove proxy container and image from servers"
+ "restart:Restart existing proxy container on servers"
+ "start:Start existing proxy container on servers"
+ "stop:Stop existing proxy container on servers"
+ )
+
+ _arguments -C \
+ '1: :->subcmd' \
+ '*:: :->args' && ret=0
+
+ case $state in
+ (subcmd)
+ _describe -t proxy-commands "Kamal proxy commands" proxy_subcommands && ret=0
+ ;;
+ (args)
+ case $words[1] in
+ (boot|details|logs|reboot|remove|restart|start|stop)
+ _arguments $_kamal_flags && ret=0
+ ;;
+ (boot_config)
+ if (( CURRENT == 2 )); then
+ local -a boot_config_commands=(
+ "set:Set boot configuration"
+ "get:Get boot configuration"
+ "reset:Reset boot configuration"
+ )
+ _describe -t boot-config-commands "Boot config commands" boot_config_commands && ret=0
+ else
+ _values $_kamal_flags && ret=0
+ fi
+ ;;
+ (help)
+ # Remove help itself from the list of commands
+ proxy_subcommands=("${(@)proxy_subcommands:#help*}")
+ _describe -t proxy-help-commands "Kamal proxy help commands" proxy_subcommands
+ ;;
+ esac
+ ;;
+ esac
+
+ return ret
+}
+
+_kamal_prune() {
+ local context state line
+ typeset -A opt_args
+ local ret=1
+
+ local -a prune_subcommands
+ prune_subcommands=(
+ "all:Prune unused images and stopped containers"
+ "containers:Prune all stopped containers, except the last n (default 5)"
+ "help:Describe subcommands or one specific subcommand"
+ "images:Prune unused images"
+ )
+
+ _arguments -C \
+ '1: :->subcmd' \
+ '*:: :->args' && ret=0
+
+ case $state in
+ (subcmd)
+ _describe -t prune-commands "Kamal prune commands" prune_subcommands && ret=0
+ ;;
+ (args)
+ case $words[1] in
+ (all|containers|images)
+ _arguments $_kamal_flags && ret=0
+ ;;
+ (help)
+ # Remove help itself from the list of commands
+ prune_subcommands=("${(@)prune_subcommands:#help*}")
+ _describe -t prune-help-commands "Kamal prune help commands" prune_subcommands
+ ;;
+ esac
+ ;;
+ esac
+
+ return ret
+}
+
+_kamal_registry() {
+ local context state line
+ typeset -A opt_args
+ local ret=1
+
+ local -a registry_subcommands
+ registry_subcommands=(
+ "help:Describe subcommands or one specific subcommand"
+ "login:Log in to registry locally and remotely"
+ "logout:Log out of registry locally and remotely"
+ )
+
+ _arguments -C \
+ '1: :->subcmd' \
+ '*:: :->args' && ret=0
+
+ case $state in
+ (subcmd)
+ _describe -t registry-commands "Kamal registry commands" registry_subcommands && ret=0
+ ;;
+ (args)
+ case $words[1] in
+ (help)
+ # Remove help itself from the list of commands
+ registry_subcommands=("${(@)registry_subcommands:#help*}")
+ _describe -t registry-help-commands "Kamal registry help commands" registry_subcommands
+ ;;
+ (login|logout)
+ _arguments $_kamal_flags && ret=0
+ ;;
+ esac
+ ;;
+ esac
+
+ return ret
+}
+
+_kamal_secrets() {
+ local context state line
+ typeset -A opt_args
+ local ret=1
+
+ local -a secrets_subcommands
+ secrets_subcommands=(
+ "extract:Extract a single secret from the results of a fetch call"
+ "fetch:Fetch secrets from a vault"
+ "help:Describe subcommands or one specific subcommand"
+ "print:Print the secrets (for debugging)"
+ )
+
+ _arguments -C \
+ '1: :->subcmd' \
+ '*:: :->args' && ret=0
+
+ case $state in
+ (subcmd)
+ _describe -t secrets-commands "Kamal secrets commands" secrets_subcommands && ret=0
+ ;;
+ (args)
+ case $words[1] in
+ (fetch)
+ local -a fetch_flags
+ fetch_flags=(
+ $_kamal_flags
+ '(-a --adapter)'{-a,--adapter=}'[Secret storage adapter]:adapter:(aws-parameter-store)'
+ )
+ _arguments $fetch_flags && ret=0
+ ;;
+ (extract|print)
+ _arguments $_kamal_flags && ret=0
+ ;;
+ (help)
+ # Remove help itself from the list of commands
+ secrets_subcommands=("${(@)secrets_subcommands:#help*}")
+ _describe -t secrets-help-commands "Kamal secrets help commands" secrets_subcommands
+ ;;
+ esac
+ ;;
+ esac
+
+ return ret
+}
+
+_kamal_server() {
+ local context state line
+ typeset -A opt_args
+ local ret=1
+
+ local -a server_subcommands
+ server_subcommands=(
+ "bootstrap:Set up Docker to run Kamal apps"
+ "exec:Run a custom command on the server (use --help to show options)"
+ "help:Describe subcommands or one specific subcommand"
+ )
+
+ local -a server_flags
+ server_flags=(
+ $_kamal_flags
+ '(-i --interactive --no-interactive --skip-interactive)'{-i,--interactive}'[Run the command interactively]'
+ '(-i --interactive --no-interactive --skip-interactive)--no-interactive[Do not run the command interactively]'
+ '(-i --interactive --no-interactive --skip-interactive)--skip-interactive[Skip interactive mode]'
+ )
+
+ _arguments -C \
+ '1: :->subcmd' \
+ '*:: :->args' && ret=0
+
+ case $state in
+ (subcmd)
+ _describe -t server-commands "Kamal server commands" server_subcommands && ret=0
+ ;;
+ (args)
+ case $words[1] in
+ (bootstrap)
+ _arguments $server_flags && ret=0
+ ;;
+ (exec)
+ if (( CURRENT == 2 )); then
+ # For exec, the next argument is a command
+ _kamal_message "Enter a command to execute" && ret=0
+ else
+ _values $server_flags && ret=0
+ fi
+ ;;
+ (help)
+ # Remove help itself from the list of commands
+ server_subcommands=("${(@)server_subcommands:#help*}")
+ _describe -t server-help-commands "Kamal server help commands" server_subcommands
+ ;;
+ esac
+ ;;
+ esac
+
+ return ret
+}
+
+_kamal "$@"
\ No newline at end of file
diff --git a/plugins/kamal/kamal.plugin.zsh b/plugins/kamal/kamal.plugin.zsh
new file mode 100644
index 000000000..e21ab4f92
--- /dev/null
+++ b/plugins/kamal/kamal.plugin.zsh
@@ -0,0 +1,25 @@
+# Find kamal binary (local ./bin/kamal or global)
+function _kamal_command () {
+ if [ -x "./bin/kamal" ]; then
+ ./bin/kamal "$@"
+ else
+ command kamal "$@"
+ fi
+}
+
+function which-kamal() {
+ if [ -x "./bin/kamal" ]; then
+ echo "Using local ./bin/kamal"
+ else
+ echo "Using global $(command -v kamal)"
+ fi
+}
+
+# Use `_kamal_command`` function for `kamal` command
+alias kamal='_kamal_command'
+
+# Aliases
+alias kad='kamal deploy'
+
+# Hook up completion
+compdef _kamal_command=kamal
diff --git a/plugins/keychain/keychain.plugin.zsh b/plugins/keychain/keychain.plugin.zsh
index f122f7982..ce5351bce 100644
--- a/plugins/keychain/keychain.plugin.zsh
+++ b/plugins/keychain/keychain.plugin.zsh
@@ -19,8 +19,15 @@ function {
# load additional options
zstyle -a :omz:plugins:keychain options options
- # start keychain...
- keychain ${^options:-} --agents ${agents:-gpg} ${^identities} --host $SHORT_HOST
+ # Check keychain version to decide whether to use --agents
+ local version_string=$(keychain --version 2>&1 | head -n 2 | tail -n 1 | cut -d ' ' -f 4)
+ # start keychain, only use --agents for versions below 2.9.0
+ autoload -Uz is-at-least
+ if is-at-least 2.9 "$version_string"; then
+ keychain ${^options:-} ${^identities} --host $SHORT_HOST
+ else
+ keychain ${^options:-} --agents ${agents:-gpg} ${^identities} --host $SHORT_HOST
+ fi
# Get the filenames to store/lookup the environment from
_keychain_env_sh="$HOME/.keychain/$SHORT_HOST-sh"
diff --git a/plugins/kubectl/README.md b/plugins/kubectl/README.md
index 579a90b3b..6f347a8ee 100644
--- a/plugins/kubectl/README.md
+++ b/plugins/kubectl/README.md
@@ -11,122 +11,126 @@ plugins=(... kubectl)
## Aliases
-| Alias | Command | Description |
-|:--------|:------------------------------------|:-------------------------------------------------------------------------------------------------|
-| k | `kubectl` | The kubectl command |
-| kca | `kubectl --all-namespaces` | The kubectl command targeting all namespaces |
-| kaf | `kubectl apply -f` | Apply a YML file |
-| keti | `kubectl exec -ti` | Drop into an interactive terminal on a container |
-| | | **Manage configuration quickly to switch contexts between local, dev and staging** |
-| kcuc | `kubectl config use-context` | Set the current-context in a kubeconfig file |
-| kcsc | `kubectl config set-context` | Set a context entry in kubeconfig |
-| kcdc | `kubectl config delete-context` | Delete the specified context from the kubeconfig |
-| kccc | `kubectl config current-context` | Display the current-context |
-| kcgc | `kubectl config get-contexts` | List of contexts available |
-| | | **General aliases** |
-| kdel | `kubectl delete` | Delete resources by filenames, stdin, resources and names, or by resources and label selector |
-| kdelf | `kubectl delete -f` | Delete a pod using the type and name specified in -f argument |
-| | | **Pod management** |
-| kgp | `kubectl get pods` | List all pods in ps output format |
-| kgpw | `kgp --watch` | After listing/getting the requested object, watch for changes |
-| kgpwide | `kgp -o wide` | Output in plain-text format with any additional information. For pods, the node name is included |
-| kep | `kubectl edit pods` | Edit pods from the default editor |
-| kdp | `kubectl describe pods` | Describe all pods |
-| kdelp | `kubectl delete pods` | Delete all pods matching passed arguments |
-| kgpl | `kgp -l` | Get pods by label. Example: `kgpl "app=myapp" -n myns` |
-| kgpn | `kgp -n` | Get pods by namespace. Example: `kgpn kube-system` |
-| | | **Service management** |
-| kgs | `kubectl get svc` | List all services in ps output format |
-| kgsw | `kgs --watch` | After listing all services, watch for changes |
-| kgswide | `kgs -o wide` | After listing all services, output in plain-text format with any additional information |
-| kes | `kubectl edit svc` | Edit services(svc) from the default editor |
-| kds | `kubectl describe svc` | Describe all services in detail |
-| kdels | `kubectl delete svc` | Delete all services matching passed argument |
-| | | **Ingress management** |
-| kgi | `kubectl get ingress` | List ingress resources in ps output format |
-| kei | `kubectl edit ingress` | Edit ingress resource from the default editor |
-| kdi | `kubectl describe ingress` | Describe ingress resource in detail |
-| kdeli | `kubectl delete ingress` | Delete ingress resources matching passed argument |
-| | | **Namespace management** |
-| kgns | `kubectl get namespaces` | List the current namespaces in a cluster |
-| kcn | `kubectl config set-context --current --namespace` | Change current namespace |
-| kens | `kubectl edit namespace` | Edit namespace resource from the default editor |
-| kdns | `kubectl describe namespace` | Describe namespace resource in detail |
-| kdelns | `kubectl delete namespace` | Delete the namespace. WARNING! This deletes everything in the namespace |
-| | | **ConfigMap management** |
-| kgcm | `kubectl get configmaps` | List the configmaps in ps output format |
-| kecm | `kubectl edit configmap` | Edit configmap resource from the default editor |
-| kdcm | `kubectl describe configmap` | Describe configmap resource in detail |
-| kdelcm | `kubectl delete configmap` | Delete the configmap |
-| | | **Secret management** |
-| kgsec | `kubectl get secret` | Get secret for decoding |
-| kdsec | `kubectl describe secret` | Describe secret resource in detail |
-| kdelsec | `kubectl delete secret` | Delete the secret |
-| | | **Deployment management** |
-| kgd | `kubectl get deployment` | Get the deployment |
-| kgdw | `kgd --watch` | After getting the deployment, watch for changes |
-| kgdwide | `kgd -o wide` | After getting the deployment, output in plain-text format with any additional information |
-| ked | `kubectl edit deployment` | Edit deployment resource from the default editor |
-| kdd | `kubectl describe deployment` | Describe deployment resource in detail |
-| kdeld | `kubectl delete deployment` | Delete the deployment |
-| ksd | `kubectl scale deployment` | Scale a deployment |
-| krsd | `kubectl rollout status deployment` | Check the rollout status of a deployment |
-| kres | `kubectl set env $@ REFRESHED_AT=...` | Recreate all pods in deployment with zero-downtime |
-| | | **Rollout management** |
-| kgrs | `kubectl get replicaset` | List all ReplicaSets `rs` created by the deployment |
-| kdrs | `kubectl describe replicaset` | Describe ReplicaSet in detail |
-| kers | `kubectl edit replicaset` | Edit ReplicaSet from the default editor |
-| krh | `kubectl rollout history` | Check the revisions of this deployment |
-| kru | `kubectl rollout undo` | Rollback to the previous revision |
-| | | **Port forwarding** |
-| kpf | `kubectl port-forward` | Forward one or more local ports to a pod |
-| | | **Tools for accessing all information** |
-| kga | `kubectl get all` | List all resources in ps format |
-| kgaa | `kubectl get all --all-namespaces` | List the requested object(s) across all namespaces |
-| | | **Logs** |
-| kl | `kubectl logs` | Print the logs for a container or resource |
-| klf | `kubectl logs -f` | Stream the logs for a container or resource (follow) |
-| | | **File copy** |
-| kcp | `kubectl cp` | Copy files and directories to and from containers |
-| | | **Node management** |
-| kgno | `kubectl get nodes` | List the nodes in ps output format |
-| keno | `kubectl edit node` | Edit nodes resource from the default editor |
-| kdno | `kubectl describe node` | Describe node resource in detail |
-| kdelno | `kubectl delete node` | Delete the node |
-| | | **Persistent Volume Claim management** |
-| kgpvc | `kubectl get pvc` | List all PVCs |
-| kgpvcw | `kgpvc --watch` | After listing/getting the requested object, watch for changes |
-| kepvc | `kubectl edit pvc` | Edit pvcs from the default editor |
-| kdpvc | `kubectl describe pvc` | Describe all pvcs |
-| kdelpvc | `kubectl delete pvc` | Delete all pvcs matching passed arguments |
-| | | **StatefulSets management** |
-| kgss | `kubectl get statefulset` | List the statefulsets in ps format |
-| kgssw | `kgss --watch` | After getting the list of statefulsets, watch for changes |
-| kgsswide| `kgss -o wide` | After getting the statefulsets, output in plain-text format with any additional information |
-| kess | `kubectl edit statefulset` | Edit statefulset resource from the default editor |
-| kdss | `kubectl describe statefulset` | Describe statefulset resource in detail |
-| kdelss | `kubectl delete statefulset` | Delete the statefulset |
-| ksss | `kubectl scale statefulset` | Scale a statefulset |
-| krsss | `kubectl rollout status statefulset`| Check the rollout status of a deployment |
-| | | **Service Accounts management** |
-| kdsa | `kubectl describe sa` | Describe a service account in details |
-| kdelsa | `kubectl delete sa` | Delete the service account |
-| | | **DaemonSet management** |
-| kgds | `kubectl get daemonset` | List all DaemonSets in ps output format |
-| kgdsw | `kgds --watch` | After listing all DaemonSets, watch for changes |
-| keds | `kubectl edit daemonset` | Edit DaemonSets from the default editor |
-| kdds | `kubectl describe daemonset` | Describe all DaemonSets in detail |
-| kdelds | `kubectl delete daemonset` | Delete all DaemonSets matching passed argument |
-| | | **CronJob management** |
-| kgcj | `kubectl get cronjob` | List all CronJobs in ps output format |
-| kecj | `kubectl edit cronjob` | Edit CronJob from the default editor |
-| kdcj | `kubectl describe cronjob` | Describe a CronJob in details |
-| kdelcj | `kubectl delete cronjob` | Delete the CronJob |
-| | | **Job management** |
-| kgj | `kubectl get job` | List all Job in ps output format |
-| kej | `kubectl edit job` | Edit a Job in details |
-| kdj | `kubectl describe job` | Describe the Job |
-| kdelj | `kubectl delete job` | Delete the Job |
+| Alias | Command | Description |
+| :------- | :------------------------------------------------------ | :----------------------------------------------------------------------------------------------- |
+| k | `kubectl` | The kubectl command |
+| kca | `kubectl --all-namespaces` | The kubectl command targeting all namespaces |
+| kaf | `kubectl apply -f` | Apply a YML file |
+| keti | `kubectl exec -ti` | Drop into an interactive terminal on a container |
+| | | **Manage configuration quickly to switch contexts between local, dev and staging** |
+| kcuc | `kubectl config use-context` | Set the current-context in a kubeconfig file |
+| kcsc | `kubectl config set-context` | Set a context entry in kubeconfig |
+| kcdc | `kubectl config delete-context` | Delete the specified context from the kubeconfig |
+| kccc | `kubectl config current-context` | Display the current-context |
+| kcgc | `kubectl config get-contexts` | List of contexts available |
+| | | **General aliases** |
+| kdel | `kubectl delete` | Delete resources by filenames, stdin, resources and names, or by resources and label selector |
+| kdelf | `kubectl delete -f` | Delete a pod using the type and name specified in -f argument |
+| kge | `kubectl get events --sort-by=".lastTimestamp"` | Get events (sorted by timestamp) |
+| kgew | `kubectl get events --watch --sort-by=".lastTimestamp"` | Get events and watch as they occur (sorted by timestamp) |
+| | | **Pod management** |
+| kgp | `kubectl get pods` | List all pods in ps output format |
+| kgpl | `kgp -l` | Get pods by label. Example: `kgpl "app=myapp" -n myns` |
+| kgpn | `kgp -n` | Get pods by namespace. Example: `kgpn kube-system` |
+| kgpsl | `kubectl get pods --show-labels` | List all pods in ps output format with labels |
+| kgpw | `kgp --watch` | After listing/getting the requested object, watch for changes |
+| kgpwide | `kgp -o wide` | Output in plain-text format with any additional information. For pods, the node name is included |
+| kep | `kubectl edit pods` | Edit pods from the default editor |
+| kdp | `kubectl describe pods` | Describe all pods |
+| kdelp | `kubectl delete pods` | Delete all pods matching passed arguments |
+| | | **Service management** |
+| kgs | `kubectl get svc` | List all services in ps output format |
+| kgsw | `kgs --watch` | After listing all services, watch for changes |
+| kgswide | `kgs -o wide` | After listing all services, output in plain-text format with any additional information |
+| kes | `kubectl edit svc` | Edit services(svc) from the default editor |
+| kds | `kubectl describe svc` | Describe all services in detail |
+| kdels | `kubectl delete svc` | Delete all services matching passed argument |
+| | | **Ingress management** |
+| kgi | `kubectl get ingress` | List ingress resources in ps output format |
+| kei | `kubectl edit ingress` | Edit ingress resource from the default editor |
+| kdi | `kubectl describe ingress` | Describe ingress resource in detail |
+| kdeli | `kubectl delete ingress` | Delete ingress resources matching passed argument |
+| | | **Namespace management** |
+| kgns | `kubectl get namespaces` | List the current namespaces in a cluster |
+| kcn | `kubectl config set-context --current --namespace` | Change current namespace |
+| kens | `kubectl edit namespace` | Edit namespace resource from the default editor |
+| kdns | `kubectl describe namespace` | Describe namespace resource in detail |
+| kdelns | `kubectl delete namespace` | Delete the namespace. WARNING! This deletes everything in the namespace |
+| | | **ConfigMap management** |
+| kgcm | `kubectl get configmaps` | List the configmaps in ps output format |
+| kecm | `kubectl edit configmap` | Edit configmap resource from the default editor |
+| kdcm | `kubectl describe configmap` | Describe configmap resource in detail |
+| kdelcm | `kubectl delete configmap` | Delete the configmap |
+| | | **Secret management** |
+| kgsec | `kubectl get secret` | Get secret for decoding |
+| kdsec | `kubectl describe secret` | Describe secret resource in detail |
+| kdelsec | `kubectl delete secret` | Delete the secret |
+| | | **Deployment management** |
+| kgd | `kubectl get deployment` | Get the deployment |
+| kgdw | `kgd --watch` | After getting the deployment, watch for changes |
+| kgdwide | `kgd -o wide` | After getting the deployment, output in plain-text format with any additional information |
+| ked | `kubectl edit deployment` | Edit deployment resource from the default editor |
+| kdd | `kubectl describe deployment` | Describe deployment resource in detail |
+| kdeld | `kubectl delete deployment` | Delete the deployment |
+| ksd | `kubectl scale deployment` | Scale a deployment |
+| krsd | `kubectl rollout status deployment` | Check the rollout status of a deployment |
+| kres | `kubectl set env $@ REFRESHED_AT=...` | Recreate all pods in deployment with zero-downtime |
+| | | **Rollout management** |
+| kgrs | `kubectl get replicaset` | List all ReplicaSets `rs` created by the deployment |
+| kdrs | `kubectl describe replicaset` | Describe ReplicaSet in detail |
+| kers | `kubectl edit replicaset` | Edit ReplicaSet from the default editor |
+| krh | `kubectl rollout history` | Check the revisions of this deployment |
+| kru | `kubectl rollout undo` | Rollback to the previous revision |
+| | | **Port forwarding** |
+| kpf | `kubectl port-forward` | Forward one or more local ports to a pod |
+| | | **Tools for accessing all information** |
+| kga | `kubectl get all` | List all resources in ps format |
+| kgaa | `kubectl get all --all-namespaces` | List the requested object(s) across all namespaces |
+| | | **Logs** |
+| kl | `kubectl logs` | Print the logs for a container or resource |
+| klf | `kubectl logs -f` | Stream the logs for a container or resource (follow) |
+| | | **File copy** |
+| kcp | `kubectl cp` | Copy files and directories to and from containers |
+| | | **Node management** |
+| kgno | `kubectl get nodes` | List the nodes in ps output format |
+| kgnosl | `kubectl get nodes --show-labels` | List the nodes in ps output format with labels |
+| keno | `kubectl edit node` | Edit nodes resource from the default editor |
+| kdno | `kubectl describe node` | Describe node resource in detail |
+| kdelno | `kubectl delete node` | Delete the node |
+| | | **Persistent Volume Claim management** |
+| kgpvc | `kubectl get pvc` | List all PVCs |
+| kgpvcw | `kgpvc --watch` | After listing/getting the requested object, watch for changes |
+| kepvc | `kubectl edit pvc` | Edit pvcs from the default editor |
+| kdpvc | `kubectl describe pvc` | Describe all pvcs |
+| kdelpvc | `kubectl delete pvc` | Delete all pvcs matching passed arguments |
+| | | **StatefulSets management** |
+| kgss | `kubectl get statefulset` | List the statefulsets in ps format |
+| kgssw | `kgss --watch` | After getting the list of statefulsets, watch for changes |
+| kgsswide | `kgss -o wide` | After getting the statefulsets, output in plain-text format with any additional information |
+| kess | `kubectl edit statefulset` | Edit statefulset resource from the default editor |
+| kdss | `kubectl describe statefulset` | Describe statefulset resource in detail |
+| kdelss | `kubectl delete statefulset` | Delete the statefulset |
+| ksss | `kubectl scale statefulset` | Scale a statefulset |
+| krsss | `kubectl rollout status statefulset` | Check the rollout status of a deployment |
+| | | **Service Accounts management** |
+| kdsa | `kubectl describe sa` | Describe a service account in details |
+| kdelsa | `kubectl delete sa` | Delete the service account |
+| | | **DaemonSet management** |
+| kgds | `kubectl get daemonset` | List all DaemonSets in ps output format |
+| kgdsw | `kgds --watch` | After listing all DaemonSets, watch for changes |
+| keds | `kubectl edit daemonset` | Edit DaemonSets from the default editor |
+| kdds | `kubectl describe daemonset` | Describe all DaemonSets in detail |
+| kdelds | `kubectl delete daemonset` | Delete all DaemonSets matching passed argument |
+| | | **CronJob management** |
+| kgcj | `kubectl get cronjob` | List all CronJobs in ps output format |
+| kecj | `kubectl edit cronjob` | Edit CronJob from the default editor |
+| kdcj | `kubectl describe cronjob` | Describe a CronJob in details |
+| kdelcj | `kubectl delete cronjob` | Delete the CronJob |
+| | | **Job management** |
+| kgj | `kubectl get job` | List all Job in ps output format |
+| kej | `kubectl edit job` | Edit a Job in details |
+| kdj | `kubectl describe job` | Describe the Job |
+| kdelj | `kubectl delete job` | Delete the Job |
## Wrappers
diff --git a/plugins/kubectl/kubectl.plugin.zsh b/plugins/kubectl/kubectl.plugin.zsh
index d1230f5f4..2ff9037fe 100644
--- a/plugins/kubectl/kubectl.plugin.zsh
+++ b/plugins/kubectl/kubectl.plugin.zsh
@@ -36,9 +36,14 @@ alias kcgc='kubectl config get-contexts'
# General aliases
alias kdel='kubectl delete'
alias kdelf='kubectl delete -f'
+alias kge='kubectl get events --sort-by=".lastTimestamp"'
+alias kgew='kubectl get events --sort-by=".lastTimestamp" --watch'
# Pod management.
alias kgp='kubectl get pods'
+alias kgpl='kgp -l'
+alias kgpn='kgp -n'
+alias kgpsl='kubectl get pods --show-labels'
alias kgpa='kubectl get pods --all-namespaces'
alias kgpw='kgp --watch'
alias kgpwide='kgp -o wide'
@@ -48,12 +53,6 @@ alias kdelp='kubectl delete pods'
alias kgpall='kubectl get pods --all-namespaces -o wide'
alias kclearevicted="kubectl get pods --all-namespaces -o json | jq '.items[] | select(.status.reason!=null) | select(.status.reason | contains(\"Evicted\")) | \"kubectl delete pods \(.metadata.name) -n \(.metadata.namespace)\"' | xargs -n 1 bash -c"
-# get pod by label: kgpl "app=myapp" -n myns
-alias kgpl='kgp -l'
-
-# get pod by namespace: kgpn kube-system"
-alias kgpn='kgp -n'
-
# Service management.
alias kgs='kubectl get svc'
alias kgsa='kubectl get svc --all-namespaces'
@@ -145,6 +144,7 @@ alias kcp='kubectl cp'
# Node Management
alias kgno='kubectl get nodes'
+alias kgnosl='kubectl get nodes --show-labels'
alias keno='kubectl edit node'
alias kdno='kubectl describe node'
alias kdelno='kubectl delete node'
diff --git a/plugins/laravel/README.md b/plugins/laravel/README.md
index 21eb89373..c5375f270 100644
--- a/plugins/laravel/README.md
+++ b/plugins/laravel/README.md
@@ -21,6 +21,7 @@ plugins=(... laravel)
| `pamfs` | `php artisan migrate:fresh --seed` |
| `pamr` | `php artisan migrate:rollback` |
| `pads` | `php artisan db:seed` |
+| `padw` | `php artisan db:wipe` |
## Makers
@@ -49,6 +50,7 @@ plugins=(... laravel)
| `pacoc` | `php artisan config:clear` |
| `pavic` | `php artisan view:clear` |
| `paroc` | `php artisan route:clear` |
+| `paopc` | `php artisan optimize:clear` |
## Queues
diff --git a/plugins/laravel/laravel.plugin.zsh b/plugins/laravel/laravel.plugin.zsh
index 86ae27299..20a1c473e 100644
--- a/plugins/laravel/laravel.plugin.zsh
+++ b/plugins/laravel/laravel.plugin.zsh
@@ -12,6 +12,7 @@ alias pamf='php artisan migrate:fresh'
alias pamfs='php artisan migrate:fresh --seed'
alias pamr='php artisan migrate:rollback'
alias pads='php artisan db:seed'
+alias padw='php artisan db:wipe'
# Makers
alias pamm='php artisan make:model'
@@ -36,6 +37,7 @@ alias pacac='php artisan cache:clear'
alias pacoc='php artisan config:clear'
alias pavic='php artisan view:clear'
alias paroc='php artisan route:clear'
+alias paopc='php artisan optimize:clear'
# queues
alias paqf='php artisan queue:failed'
diff --git a/plugins/last-working-dir/last-working-dir.plugin.zsh b/plugins/last-working-dir/last-working-dir.plugin.zsh
index 684972cc1..b816f6a8f 100644
--- a/plugins/last-working-dir/last-working-dir.plugin.zsh
+++ b/plugins/last-working-dir/last-working-dir.plugin.zsh
@@ -9,20 +9,23 @@ chpwd_last_working_dir() {
[[ "$ZSH_SUBSHELL" -eq 0 ]] || return 0
# Add ".$SSH_USER" suffix to cache file if $SSH_USER is set and non-empty
local cache_file="$ZSH_CACHE_DIR/last-working-dir${SSH_USER:+.$SSH_USER}"
- builtin pwd >| "$cache_file"
+ 'builtin' 'echo' '-E' "$PWD" >| "$cache_file"
}
# Changes directory to the last working directory
lwd() {
# Add ".$SSH_USER" suffix to cache file if $SSH_USER is set and non-empty
local cache_file="$ZSH_CACHE_DIR/last-working-dir${SSH_USER:+.$SSH_USER}"
- [[ -r "$cache_file" ]] && cd "$(cat "$cache_file")"
+ [[ -r "$cache_file" ]] && cd "$(<"$cache_file")"
}
# Jump to last directory automatically unless:
-# - this isn't the first time the plugin is loaded
-# - it's not in $HOME directory
-[[ -n "$ZSH_LAST_WORKING_DIRECTORY" ]] && return
-[[ "$PWD" != "$HOME" ]] && return
+#
+# - This isn't the first time the plugin is loaded
+# - We're not in the $HOME directory (e.g. if terminal opened a different folder)
+[[ -z "$ZSH_LAST_WORKING_DIRECTORY" ]] || return
+[[ "$PWD" == "$HOME" ]] || return
-lwd 2>/dev/null && ZSH_LAST_WORKING_DIRECTORY=1 || true
+if lwd 2>/dev/null; then
+ ZSH_LAST_WORKING_DIRECTORY=1
+fi
diff --git a/plugins/localstack/README.md b/plugins/localstack/README.md
new file mode 100644
index 000000000..2c71e9edf
--- /dev/null
+++ b/plugins/localstack/README.md
@@ -0,0 +1,24 @@
+# Localstack plugin #
+
+CLI support for LOCALSTACK interaction
+
+## Description ##
+To use it, add `localstack` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... localstack)
+```
+
+## Usage ##
+
+This plugin supplies one command, `lsk`, through which all its features are exposed.
+
+## Commands
+
+| Command | Description |
+| :------------ | :-------------------------------------------------------------------- |
+| `lsk sqs-send ` | sends a given message in sqs to a given queue |
+
+## Examples
+
+
diff --git a/plugins/localstack/localstack.plugin.zsh b/plugins/localstack/localstack.plugin.zsh
new file mode 100644
index 000000000..080b14a54
--- /dev/null
+++ b/plugins/localstack/localstack.plugin.zsh
@@ -0,0 +1,37 @@
+# CLI support for LOCALSTACK interaction
+#
+# See README.md for details
+lsk() {
+ case $1 in
+ sqs-send)
+ shift
+ sqs-send "$@"
+ ;;
+ *)
+ echo "Command not found: $1"
+ return 1
+ ;;
+ esac
+}
+
+# Send SQS function
+#
+# This function sends a given message in sqs to a given queue, when used Localstack
+#
+# Use:
+# sqs-send
+#
+# Parameters
+# A given queue
+# A content of message em json archive
+#
+# Example
+# sqs-send user user.json
+sqs-send(){
+ if [ -z "$1" ]; then
+ echo "Use: sqs-send "
+ return 1
+ fi
+
+ curl -X POST "http://localhost:4566/000000000000/$1" -d "Action=SendMessage" -d "MessageBody=$(cat $2)"
+}
\ No newline at end of file
diff --git a/plugins/localstack/sqs-send-result.png b/plugins/localstack/sqs-send-result.png
new file mode 100644
index 000000000..69eb2a640
Binary files /dev/null and b/plugins/localstack/sqs-send-result.png differ
diff --git a/plugins/lpass/_lpass b/plugins/lpass/_lpass
index 621a7bcd7..e312fb9a3 100644
--- a/plugins/lpass/_lpass
+++ b/plugins/lpass/_lpass
@@ -78,7 +78,7 @@ _lpass() {
has_sync=1
;;
status)
- _arguments : '(-q --quiet)'{-q,--quiet}'[Supress output to stdout]'
+ _arguments : '(-q --quiet)'{-q,--quiet}'[Suppress output to stdout]'
has_color=1
;;
sync)
diff --git a/plugins/macos/README.md b/plugins/macos/README.md
index 8245e211f..ccc4331e5 100644
--- a/plugins/macos/README.md
+++ b/plugins/macos/README.md
@@ -13,6 +13,7 @@ plugins=(... macos)
- [iTerm2](https://iterm2.com/)
- [Hyper](https://hyper.is/)
- [Tabby](https://tabby.sh/)
+- [Ghostty](https://ghostty.org)
## Commands
diff --git a/plugins/macos/macos.plugin.zsh b/plugins/macos/macos.plugin.zsh
index b951a289f..4d73d22c3 100644
--- a/plugins/macos/macos.plugin.zsh
+++ b/plugins/macos/macos.plugin.zsh
@@ -85,6 +85,12 @@ EOF
tell application "System Events"
tell process "Tabby" to keystroke "t" using command down
end tell
+EOF
+ elif [[ "$the_app" == 'ghostty' ]]; then
+ osascript >/dev/null <&2
@@ -139,6 +145,12 @@ EOF
tell application "System Events"
tell process "Tabby" to keystroke "D" using command down
end tell
+EOF
+ elif [[ "$the_app" == 'ghostty' ]]; then
+ osascript >/dev/null <&2
@@ -194,6 +206,12 @@ EOF
tell application "System Events"
tell process "Tabby" to keystroke "d" using command down
end tell
+EOF
+ elif [[ "$the_app" == 'ghostty' ]]; then
+ osascript >/dev/null <&2
@@ -253,7 +271,7 @@ function man-preview() {
[[ $# -eq 0 ]] && >&2 echo "Usage: $0 command1 [command2 ...]" && return 1
local page
- for page in "${(@f)"$(man -w $@)"}"; do
+ for page in "${(@f)"$(command man -w $@)"}"; do
command mandoc -Tpdf $page | open -f -a Preview
done
}
diff --git a/plugins/macports/README.md b/plugins/macports/README.md
index 09bd42df2..ffe3f973f 100644
--- a/plugins/macports/README.md
+++ b/plugins/macports/README.md
@@ -16,7 +16,7 @@ plugins=(... macports)
| pc | `sudo port clean --all installed` | Clean up intermediate installation files for installed ports |
| pi | `sudo port install` | Install package given as argument |
| pli | `port livecheck installed` | Check for updates for installed ports |
-| plm | `port-livecheck-maintainer` | Check for updates of ports mainained by the specified users |
+| plm | `port-livecheck-maintainer` | Check for updates of ports maintained by the specified users |
| psu | `sudo port selfupdate` | Update ports tree with MacPorts repository |
| puni | `sudo port uninstall inactive` | Uninstall inactive ports |
| puo | `sudo port upgrade outdated` | Upgrade ports with newer versions available |
diff --git a/plugins/mix/README.md b/plugins/mix/README.md
index f0258fe88..9bbe53a41 100644
--- a/plugins/mix/README.md
+++ b/plugins/mix/README.md
@@ -17,3 +17,4 @@ plugins=(... mix)
| Ecto | [Ecto](https://hexdocs.pm/ecto/Ecto.html) |
| Hex | [Hex](https://hex.pm/) |
| Nerves | [Nerves](https://nerves-project.org/) |
+| mix_test_watch | [mix_test_watch](https://hex.pm/packages/mix_test_watch) |
diff --git a/plugins/mix/_mix b/plugins/mix/_mix
index 7940ff1c9..346fc8c4f 100644
--- a/plugins/mix/_mix
+++ b/plugins/mix/_mix
@@ -109,6 +109,7 @@ _1st_arguments=(
'release.init:Generates sample files for releases'
'run:Run the given file or expression'
"test:Run a project's tests"
+ "test.watch:Run a project's tests continuously using hex package mix_test_watch"
'test.coverage:Build report from exported test coverage'
'xref:Prints cross reference information'
'--help:Describe available tasks'
@@ -120,7 +121,7 @@ __task_list ()
local expl
declare -a tasks
- tasks=(app.config app.start app.tree archive archive.build archive.install archive.uninstall clean cmd compile compile.protocols deps deps.clean deps.compile deps.get deps.tree deps.unlock deps.update do ecto.create ecto.drop ecto.dump ecto.gen.migration ecto.gen.repo ecto.load ecto.migrate ecto.migrations ecto.rollback escript escript.build escript.install escript.uninstall firmware firmware.burn firmware.image format help hex hex.audit hex.build hex.config hex.docs hex.info hex.organization hex.key hex.outdated hex.owner hex.package hex.publish hex.registry hex.repo hex.retire hex.search hex.sponsor hex.user loadconfig local local.hex local.phoenix local.phx local.public_keys local.rebar nerves.artifact nerves.artifact.get nerves.info nerves.new nerves.release.init new phoenix.digest phoenix.gen.channel phoenix.gen.html phoenix.gen.json phoenix.gen.model phoenix.gen.secret phoenix.new phoenix.routes phoenix.server phx.digest phx.digest.clean phx.gen.auth phx.gen.cert phx.gen.channel phx.gen.context phx.gen.embedded phx.gen.html phx.gen.json phx.gen.live phx.gen.notifier phx.gen.presence phx.gen.schema phx.gen.secret phx.gen.socket phx.new phx.new.ecto phx.new.web phx.routes phx.server profile.cprof profile.eprof profile.fprof release release.init run test test.coverage xref)
+ tasks=(app.config app.start app.tree archive archive.build archive.install archive.uninstall clean cmd compile compile.protocols deps deps.clean deps.compile deps.get deps.tree deps.unlock deps.update do ecto.create ecto.drop ecto.dump ecto.gen.migration ecto.gen.repo ecto.load ecto.migrate ecto.migrations ecto.rollback escript escript.build escript.install escript.uninstall firmware firmware.burn firmware.image format help hex hex.audit hex.build hex.config hex.docs hex.info hex.organization hex.key hex.outdated hex.owner hex.package hex.publish hex.registry hex.repo hex.retire hex.search hex.sponsor hex.user loadconfig local local.hex local.phoenix local.phx local.public_keys local.rebar nerves.artifact nerves.artifact.get nerves.info nerves.new nerves.release.init new phoenix.digest phoenix.gen.channel phoenix.gen.html phoenix.gen.json phoenix.gen.model phoenix.gen.secret phoenix.new phoenix.routes phoenix.server phx.digest phx.digest.clean phx.gen.auth phx.gen.cert phx.gen.channel phx.gen.context phx.gen.embedded phx.gen.html phx.gen.json phx.gen.live phx.gen.notifier phx.gen.presence phx.gen.schema phx.gen.secret phx.gen.socket phx.new phx.new.ecto phx.new.web phx.routes phx.server profile.cprof profile.eprof profile.fprof release release.init run test test.watch test.coverage xref)
_wanted tasks expl 'help' compadd $tasks
}
@@ -145,9 +146,22 @@ case $state in
(help)
_arguments ':feature:__task_list'
;;
+ (format)
+ _arguments -C \
+ '--check-formatted' \
+ '--dot-formatter' \
+ '--dry-run' \
+ '--force' \
+ '--migrate' \
+ '--no-exit' \
+ '*::file:_files'
+ ;;
(test)
_files
;;
+ (test.watch)
+ _files
+ ;;
(run)
_files
;;
diff --git a/plugins/mvn/README.md b/plugins/mvn/README.md
index 4181fedc5..bcb26482e 100644
--- a/plugins/mvn/README.md
+++ b/plugins/mvn/README.md
@@ -33,6 +33,8 @@ if it's found, or the mvn command otherwise.
| `mvnct` | `mvn clean test` |
| `mvncv` | `mvn clean verify` |
| `mvncvst` | `mvn clean verify -DskipTests` |
+| `mvnv` | `mvn verify` |
+| `mvnvst` | `mvn verify -DskipTests` |
| `mvndp` | `mvn deploy` |
| `mvndocs` | `mvn dependency:resolve -Dclassifier=javadoc` |
| `mvndt` | `mvn dependency:tree` |
diff --git a/plugins/mvn/mvn.plugin.zsh b/plugins/mvn/mvn.plugin.zsh
index a569a87fa..8477722b0 100644
--- a/plugins/mvn/mvn.plugin.zsh
+++ b/plugins/mvn/mvn.plugin.zsh
@@ -62,6 +62,8 @@ alias mvncp='mvn clean package'
alias mvnct='mvn clean test'
alias mvncv='mvn clean verify'
alias mvncvst='mvn clean verify -DskipTests'
+alias mvnv='mvn verify'
+alias mvnvst='mvn verify -DskipTests'
alias mvndp='mvn deploy'
alias mvndocs='mvn dependency:resolve -Dclassifier=javadoc'
alias mvndt='mvn dependency:tree'
@@ -101,8 +103,14 @@ function listMavenCompletions {
new_file="../pom.xml"
fi
- # if file doesn't exist break
file="${file:h}/${new_file}"
+
+ # if the file points to a directory, assume it is a pom.xml in that directory
+ if [[ -d "$file" ]]; then
+ file="${file}/pom.xml"
+ fi
+
+ # if file doesn't exist break
if ! [[ -e "$file" ]]; then
break
fi
diff --git a/plugins/ngrok/README.md b/plugins/ngrok/README.md
new file mode 100644
index 000000000..6c37b1905
--- /dev/null
+++ b/plugins/ngrok/README.md
@@ -0,0 +1,20 @@
+# ngrok plugin
+
+This plugin adds completion for the [ngrok](https://ngrok.com) CLI.
+
+To use it, add `ngrok` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... ngrok)
+```
+
+This plugin does not add any aliases.
+
+## Cache
+
+This plugin caches the completion script and is automatically updated asynchronously when the plugin is
+loaded, which is usually when you start up a new terminal emulator.
+
+The cache is stored at:
+
+- `$ZSH_CACHE/completions/_ngrok` completions script
diff --git a/plugins/ngrok/ngrok.plugin.zsh b/plugins/ngrok/ngrok.plugin.zsh
new file mode 100644
index 000000000..ca3c82db0
--- /dev/null
+++ b/plugins/ngrok/ngrok.plugin.zsh
@@ -0,0 +1,14 @@
+# Autocompletion for ngrok
+if (( ! $+commands[ngrok] )); then
+ return
+fi
+
+# If the completion file doesn't exist yet, we need to autoload it and
+# bind it to `ngrok`. Otherwise, compinit will have already done that.
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_ngrok" ]]; then
+ typeset -g -A _comps
+ autoload -Uz _ngrok
+ _comps[ngrok]=_ngrok
+fi
+
+ngrok completion zsh >| "$ZSH_CACHE_DIR/completions/_ngrok" &|
diff --git a/plugins/nvm/README.md b/plugins/nvm/README.md
index eb1e236ee..1245f66db 100644
--- a/plugins/nvm/README.md
+++ b/plugins/nvm/README.md
@@ -26,9 +26,10 @@ These settings should go in your zshrc file, before Oh My Zsh is sourced:
#### Lazy startup
This option will help you to defer nvm's load until you use it to speed-up your zsh startup. This will source
-nvm script only when using it, and will create a function for `node`, `npm`, `npx`, `pnpm`, `yarn`, `corepack`
-and the command(s) specified by `lazy-cmd` option, so when you call either of them, nvm will be loaded and run
-with default version. To enable it, you can add this snippet to your zshrc, before Oh My Zsh is sourced:
+nvm script only when using it, and will create a function for `node`, `npm`, `npx`, `pnpm`, `pnpx`, `yarn`,
+`corepack` and the command(s) specified by `lazy-cmd` option, so when you call either of them, nvm will be
+loaded and run with default version. To enable it, you can add this snippet to your zshrc, before Oh My Zsh is
+sourced:
```zsh
zstyle ':omz:plugins:nvm' lazy yes
@@ -41,6 +42,8 @@ as you want:
zstyle ':omz:plugins:nvm' lazy-cmd eslint prettier typescript ...
```
+There will be a function `_omz_nvm_load` available to load `nvm` without executing any other trigger command.
+
#### `.nvmrc` autoload
Note: _if used at the same time as `lazy`, `autoload` will start working only after nvm has been lazy-loaded_
diff --git a/plugins/nvm/nvm.plugin.zsh b/plugins/nvm/nvm.plugin.zsh
index f36182eda..682bddc47 100644
--- a/plugins/nvm/nvm.plugin.zsh
+++ b/plugins/nvm/nvm.plugin.zsh
@@ -20,7 +20,7 @@ if [[ -z "$NVM_DIR" ]] || [[ ! -f "$NVM_DIR/nvm.sh" ]]; then
return
fi
-function _omz_load_nvm_completion {
+function _omz_nvm_setup_completion {
local _nvm_completion
# Load nvm bash completion
for _nvm_completion in "$NVM_DIR/bash_completion" "$NVM_HOMEBREW/etc/bash_completion.d/nvm"; do
@@ -33,12 +33,12 @@ function _omz_load_nvm_completion {
break
fi
done
- unfunction _omz_load_nvm_completion
+ unfunction _omz_nvm_setup_completion
}
-function _omz_setup_autoload {
+function _omz_nvm_setup_autoload {
if ! zstyle -t ':omz:plugins:nvm' autoload; then
- unfunction _omz_setup_autoload
+ unfunction _omz_nvm_setup_autoload
return
fi
@@ -68,13 +68,13 @@ function _omz_setup_autoload {
add-zsh-hook chpwd load-nvmrc
load-nvmrc
- unfunction _omz_setup_autoload
+ unfunction _omz_nvm_setup_autoload
}
if zstyle -t ':omz:plugins:nvm' lazy; then
# Call nvm when first using nvm, node, npm, pnpm, yarn, corepack or other commands in lazy-cmd
zstyle -a ':omz:plugins:nvm' lazy-cmd nvm_lazy_cmd
- nvm_lazy_cmd=(nvm node npm npx pnpm yarn corepack $nvm_lazy_cmd) # default values
+ nvm_lazy_cmd=(_omz_nvm_load nvm node npm npx pnpm pnpx yarn corepack $nvm_lazy_cmd) # default values
eval "
function $nvm_lazy_cmd {
for func in $nvm_lazy_cmd; do
@@ -84,14 +84,16 @@ if zstyle -t ':omz:plugins:nvm' lazy; then
done
# Load nvm if it exists in \$NVM_DIR
[[ -f \"\$NVM_DIR/nvm.sh\" ]] && source \"\$NVM_DIR/nvm.sh\"
- _omz_load_nvm_completion
- _omz_setup_autoload
- \"\$0\" \"\$@\"
+ _omz_nvm_setup_completion
+ _omz_nvm_setup_autoload
+ if [[ \"\$0\" != _omz_nvm_load ]]; then
+ \"\$0\" \"\$@\"
+ fi
}
"
unset nvm_lazy_cmd
else
source "$NVM_DIR/nvm.sh"
- _omz_load_nvm_completion
- _omz_setup_autoload
+ _omz_nvm_setup_completion
+ _omz_nvm_setup_autoload
fi
diff --git a/plugins/opentofu/README.md b/plugins/opentofu/README.md
index 9c19501aa..45b98c3c9 100644
--- a/plugins/opentofu/README.md
+++ b/plugins/opentofu/README.md
@@ -15,29 +15,32 @@ plugins=(... opentofu)
## Aliases
-| Alias | Command |
-| ----- | --------------- |
-| `tt` | `tofu` |
-| `tta` | `tofu apply` |
-| `ttc` | `tofu console` |
-| `ttd` | `tofu destroy` |
-| `ttf` | `tofu fmt` |
-| `tti` | `tofu init` |
-| `tto` | `tofu output` |
-| `ttp` | `tofu plan` |
-| `ttv` | `tofu validate` |
-| `tts` | `tofu state` |
-| `ttsh`| `tofu show` |
-| `ttr` | `tofu refresh` |
-| `ttt` | `tofu test` |
-| `ttws`| `tofu workspace`|
+| Alias | Command |
+|--------|------------------------------|
+| `tt` | `tofu` |
+| `tta` | `tofu apply` |
+| `ttaa` | `tofu apply -auto-approve` |
+| `ttc` | `tofu console` |
+| `ttd` | `tofu destroy` |
+| `ttd!` | `tofu destroy -auto-approve` |
+| `ttf` | `tofu fmt` |
+| `ttfr` | `tofu fmt -recursive` |
+| `tti` | `tofu init` |
+| `tto` | `tofu output` |
+| `ttp` | `tofu plan` |
+| `ttv` | `tofu validate` |
+| `tts` | `tofu state` |
+| `ttsh` | `tofu show` |
+| `ttr` | `tofu refresh` |
+| `ttt` | `tofu test` |
+| `ttws` | `tofu workspace` |
## Prompt functions
- `tofu_prompt_info`: shows the current workspace when in an OpenTofu project directory.
-- `tofu_version_prompt_info`: shows the current version of the `tofu` commmand.
+- `tofu_version_prompt_info`: shows the current version of the `tofu` command.
To use them, add them to a `PROMPT` variable in your theme or `.zshrc` file:
diff --git a/plugins/opentofu/opentofu.plugin.zsh b/plugins/opentofu/opentofu.plugin.zsh
index c6844c84a..bb65c12e3 100644
--- a/plugins/opentofu/opentofu.plugin.zsh
+++ b/plugins/opentofu/opentofu.plugin.zsh
@@ -29,9 +29,12 @@ function tofu_version_prompt_info() {
alias tt='tofu'
alias tta='tofu apply'
+alias ttaa='tofu apply -auto-approve'
alias ttc='tofu console'
alias ttd='tofu destroy'
+alias ttd!='tofu destroy -auto-approve'
alias ttf='tofu fmt'
+alias ttfr='tofu fmt -recursive'
alias tti='tofu init'
alias tto='tofu output'
alias ttp='tofu plan'
diff --git a/plugins/per-directory-history/README.md b/plugins/per-directory-history/README.md
index 2816c11ba..c7d062a0c 100644
--- a/plugins/per-directory-history/README.md
+++ b/plugins/per-directory-history/README.md
@@ -35,6 +35,7 @@ toggle set the `PER_DIRECTORY_HISTORY_TOGGLE` environment variable.
function above (default `^G`)
* `PER_DIRECTORY_HISTORY_PRINT_MODE_CHANGE` is a variable which toggles whether
the current mode is printed to the screen following a mode change (default `true`)
+* `HISTORY_START_WITH_GLOBAL` is a global variable that defines how to start the plugin: global or local (default `false`)
## History
diff --git a/plugins/perl/README.md b/plugins/perl/README.md
index dd9b7dc75..a387455c1 100644
--- a/plugins/perl/README.md
+++ b/plugins/perl/README.md
@@ -8,30 +8,36 @@ To use it, add `perl` to the plugins array in your zshrc file:
plugins=(... perl)
```
+## Perlbrew activation
+
+If the plugin detects that `perlbrew` hasn't been activated, yet there is an installation of it in
+`$PERLBREW_ROOT`, it'll initialize by default. To avoid this behaviour, set `ZSH_PERLBREW_ACTIVATE=false`
+before `source oh-my-zsh.sh` in your zshrc.
+
## Aliases
-| Aliases | Command | Description |
-| :------------ | :----------------- | :------------------------------------- |
-| pbi | `perlbrew install` | Install specific perl version |
-| pbl | `perlbrew list` | List all perl version installed |
-| pbo | `perlbrew off` | Go back to the system perl |
-| pbs | `perlbrew switch` | Turn it back on |
-| pbu | `perlbrew use` | Use specific version of perl |
-| pd | `perldoc` | Show the perl documentation |
-| ple | `perl -wlne` | Use perl like awk/sed |
-| latest-perl | `curl ...` | Show the latest stable release of Perl |
+| Aliases | Command | Description |
+| :---------- | :----------------- | :------------------------------------- |
+| pbi | `perlbrew install` | Install specific perl version |
+| pbl | `perlbrew list` | List all perl version installed |
+| pbo | `perlbrew off` | Go back to the system perl |
+| pbs | `perlbrew switch` | Turn it back on |
+| pbu | `perlbrew use` | Use specific version of perl |
+| pd | `perldoc` | Show the perl documentation |
+| ple | `perl -wlne` | Use perl like awk/sed |
+| latest-perl | `curl ...` | Show the latest stable release of Perl |
## Functions
-* `newpl`: creates a basic Perl script file and opens it with $EDITOR.
+- `newpl`: creates a basic Perl script file and opens it with $EDITOR.
-* `pgs`: Perl Global Substitution: `pgs `
- Looks for `` and replaces it with `` in ``.
+- `pgs`: Perl Global Substitution: `pgs ` Looks for
+ `` and replaces it with `` in ``.
-* `prep`: Perl grep, because 'grep -P' is terrible: `prep []`
- Lets you work with pipes or files (if no `` provided, use stdin).
+- `prep`: Perl grep, because 'grep -P' is terrible: `prep []` Lets you work with pipes or
+ files (if no `` provided, use stdin).
## Requirements
-In order to make this work, you will need to have perl installed.
-More info on the usage and install: https://www.perl.org/get.html
+In order to make this work, you will need to have perl installed. More info on the usage and install:
+https://www.perl.org/get.html
diff --git a/plugins/perl/perl.plugin.zsh b/plugins/perl/perl.plugin.zsh
index 678e88d97..137fa252a 100644
--- a/plugins/perl/perl.plugin.zsh
+++ b/plugins/perl/perl.plugin.zsh
@@ -54,3 +54,12 @@ pgs() { # [find] [replace] [filename]
prep() { # [pattern] [filename unless STDOUT]
perl -nle 'print if /'"$1"'/;' $2
}
+
+# If the 'perlbrew' function isn't defined, perlbrew isn't setup.
+if [[ $ZSH_PERLBREW_ACTIVATE != false ]] && (( ! $+functions[perlbrew] )); then
+ local _perlbrew="${PERLBREW_ROOT:-${HOME}/perl5/perlbrew}"
+ if [[ -f "${_perlbrew}/etc/bashrc" ]]; then
+ source "${_perlbrew}/etc/bashrc"
+ fi
+ unset _perlbrew
+fi
diff --git a/plugins/pip/README.md b/plugins/pip/README.md
index 70d40c79f..9d1daca9f 100644
--- a/plugins/pip/README.md
+++ b/plugins/pip/README.md
@@ -20,17 +20,17 @@ the next time you autocomplete `pip install`.
## Aliases
-| Alias | Description |
-| :------- | :-------------------------------------------- |
-| pipi | Install packages |
-| pipig | Install package from GitHub repository |
-| pipigb | Install package from GitHub branch |
-| pipigp | Install package from GitHub pull request |
-| pipu | Upgrade packages |
-| pipun | Uninstall packages |
-| pipgi | Grep through installed packages |
-| piplo | List outdated packages |
-| pipreq | Create requirements file |
-| pipir | Install packages from `requirements.txt` file |
-| pipupall | Update all installed packages |
-| pipunall | Uninstall all installed packages |
+| Alias | Command | Description |
+| :--------|:----------------------------------------------------------------------------------|:--------------------------------------------- |
+| pipi | `pip install` | Install packages |
+| pipig | `pip install "git+https://github.com/user/repo.git"` | Install package from GitHub repository |
+| pipigb | `pip install "git+https://github.com/user/repo.git@branch"` | Install package from GitHub branch |
+| pipigp | `pip install "git+https://github.com/user/repo.git@refs/pull/PR_NUMBER/head"` | Install package from GitHub pull request |
+| pipu | `pip install --upgrade` | Upgrade packages |
+| pipun | `pip uninstall` | Uninstall packages |
+| pipgi | `pip freeze \| grep` | Grep through installed packages |
+| piplo | `pip list --outdated` | List outdated packages |
+| pipreq | `pip freeze > requirements.txt` | Create requirements file |
+| pipir | `pip install -r requirements.txt` | Install packages from `requirements.txt` file |
+| pipupall | `pip list --outdated \| awk 'NR > 2 { print $1 }' \| xargs pip install --upgrade` | Update all installed packages |
+| pipunall | `pip list --format freeze \| cut -d= -f1 \| xargs pip uninstall` | Uninstall all installed packages |
diff --git a/plugins/pipenv/pipenv.plugin.zsh b/plugins/pipenv/pipenv.plugin.zsh
index f81c266a4..76d66b301 100644
--- a/plugins/pipenv/pipenv.plugin.zsh
+++ b/plugins/pipenv/pipenv.plugin.zsh
@@ -19,7 +19,8 @@ if zstyle -T ':omz:plugins:pipenv' auto-shell; then
if [[ ! -f "$PWD/Pipfile" ]]; then
if [[ "$PIPENV_ACTIVE" == 1 ]]; then
if [[ "$PWD" != "$pipfile_dir"* ]]; then
- exit
+ unset PIPENV_ACTIVE pipfile_dir
+ deactivate
fi
fi
fi
@@ -28,7 +29,8 @@ if zstyle -T ':omz:plugins:pipenv' auto-shell; then
if [[ "$PIPENV_ACTIVE" != 1 ]]; then
if [[ -f "$PWD/Pipfile" ]]; then
export pipfile_dir="$PWD"
- pipenv shell
+ source "$(pipenv --venv)/bin/activate"
+ export PIPENV_ACTIVE=1
fi
fi
}
diff --git a/plugins/pm2/_pm2 b/plugins/pm2/_pm2
index 66320b810..afe4ae0db 100644
--- a/plugins/pm2/_pm2
+++ b/plugins/pm2/_pm2
@@ -1,16 +1,233 @@
-#!/bin/zsh -f
#compdef pm2
-#autoload
+# ------------------------------------------------------------------------------
+# Description
+# -----------
+#
+# Completion script for pm2 5.2.2 (https://pm2.keymetrics.io/).
+#
+# ------------------------------------------------------------------------------
+# Authors
+# -------
+#
+# * Myoungdo Park
+# * Shohei Yoshida
+#
+# ------------------------------------------------------------------------------
-local -a _1st_arguments
+_pm2() {
+ typeset -A opt_args
+ local context state line
-_1st_arguments=(
+ local curcontext="$curcontext"
+
+ local ret=1
+
+ _arguments -C \
+ '(- *)'{-v,-V,--version}'[print pm2 version]' \
+ '(-s --silent)'{-s,--silent}'[hide all messages]' \
+ '--ext[watch only this file extension]:extension' \
+ '(-n --name)'{-n,--name}'[set a name for the process in the process list]:name' \
+ '(-m --mini-list)'{-m,--mini-list}'[display a compacted list without formatting]' \
+ '--interpreter[set a specific interpreter to use for executing app(default: node)]:prog' \
+ '(--interpreter-args --node-args)'{--interpreter-args,--node-args}'[set arguments to pass to the interpreter]:args' \
+ '(-o --output)'{-o,--output}'[specify log file for stdout]: :_files' \
+ '(-e --error)'{-e,--error}'[specify log file for stderr]: :_files' \
+ '(-l --log)'{-l,--log}'[specify log file which gathers both stdout and stderr]' \
+ '--filter-env[filter out outgoing global values that contain provided strings]:envs' \
+ '--log-type[specify log output style]: :(raw json)' \
+ '--log-date-format[specify log output style]:format' \
+ '--time[enable time logging]' \
+ '--disable-logs[disable all logs storage]' \
+ '*--env[specify which set of environment variables from ecosystem file must be injected]:env' \
+ '(-a --update-env)'{-a,--update-env}'[force and update of the environment with restart/reload]' \
+ '(-f --force)'{-f,--force}'[force actions]' \
+ '(-i --instances)'{-i,--instances}'[launch number instances]:num' \
+ '--parallel[number of parallel actions]:num' \
+ '--shutdown-with-message[shutdown an application with process.send("shutdown") instead of process.kill(pid, SIGINT)]' \
+ '(-p --pid)'{-p,--pid}'[specify pid file]: :_files' \
+ '(-k --kill-timeout)'{-k,--kill-timeout}'[delay before sending final SIGKILL signal to process]:delay' \
+ '--listen-timeout[listen timeout an application reload]:delay' \
+ '--max-memory-restart[restart the app if an amount of memory is exceeded (in bytes)]:bytes' \
+ '--restart-delay[specify a delay between restarts(in milliseconds)]:delay' \
+ '--exp-backoff-restart-delay[specify a delay between restarts(in milliseconds)]:delay' \
+ '(-x --execute-command)'{-e,--execute-command}'[execute a program using fork system]' \
+ '--max-restarts[only start the script COUNT times]:count' \
+ '(-u --user)'{-u,--user}'[define user when generating startup script]:username' \
+ '--uid[run target script with rights]:uid' \
+ '--gid[run target script with rights]:gui' \
+ '--namespace[start application within specified namespace]:namespace' \
+ '--cwd[run target script from path ]:cwd:_paths -/' \
+ '--hp[define home path when generating startup script]: :_paths -/' \
+ '--wait-ip[override systemd script to wait for full internet connectivity to launch pm2]' \
+ '--service-name[define service name when generating startup script]' \
+ '(-c --cron --cron-restart)'{-c,--cron,--cron-restart}'[restart a running process based on a cron pattern]:pattern' \
+ '(-w --write)'{-w,--write}'[write configuration in local folder]' \
+ '--no-daemon[run pm2 daemon in the foreground if it does not exist already]' \
+ '(--disable-source-map-support --source-map-support)--source-map-support[force source map support]' \
+ '--only[with json declaration, allow to only act on one application]:app' \
+ '(--disable-source-map-support --source-map-support)--disable-source-map-support[force disable source map support]' \
+ '--wait-ready[ask pm2 to wait for ready event from your app]' \
+ '--merge-logs[merge logs from different instances but keep error and out separated]' \
+ '*--watch[watch application folder for changes]: :_files -/' \
+ '*--ignore-watch[list of paths to ignore]: :_files' \
+ '--no-color[skip colors]' \
+ '--no-vizion[start an app without vizion feature]' \
+ '--np-autorestart[start an app without automatic restart]' \
+ '--no-treekill[Only kill the main process, not detached children]' \
+ '--no-pmx[start an app without pmx]' \
+ '--no-automation[start an app without automation]' \
+ '(--disable-trace --trace)--trace[enable transaction tracing with km]' \
+ '(--disable-trace --trace)--disable-trace[disable transaction tracing with km]' \
+ "--sort[sort process according to field's]:field_name" \
+ '--attach[attach logging after your start/restart/stop/reload]' \
+ '--v8[enable v8 data collecting]' \
+ '--event-loop-inspector[enable event-loop-inspector dump in pmx]' \
+ '--deep-monitoring[enable all monitoring tools]' \
+ '(- *)'{-h,--help}'[output usage information]' \
+ '1: :_pm2_subcommands' \
+ '*:: :->subcmds' && return 0
+
+ case "$state" in
+ (subcmds)
+ case $words[1] in
+ (start)
+ _arguments \
+ '--watch[watch folder for changes]' \
+ '--fresh[Rebuild Dockerfile]' \
+ '--daemon[Run container in Daemon mode(debug purposes)]' \
+ '--container[Start application in container mode]' \
+ '--dist[--with-container; change local Dockerfile to containerize all files in current directory]' \
+ '--image-name[with --dist; set the exported image name]:name' \
+ '--node-version[with --container, set a specific major Node.js version]:version' \
+ '--dockerdaemon[for debugging purpose]' \
+ '(- *)'{-h,--help}'[output usage information]' \
+ '*: :_pm2_id_namespace_file' \
+ && ret=0
+ ;;
+ (trigger)
+ _arguments \
+ '(- *)'{-h,--help}'[output usage information]' \
+ '1: :_pm2_id_names' \
+ && ret=0
+ ;;
+ (deploy|startOrRestart|startOrReload|startOrGracefulReload)
+ _arguments \
+ '(- *)'{-h,--help}'[output usage information]' \
+ '1: :_files -g "*.json"' \
+ && ret=0
+ ;;
+ (stop|restart)
+ _arguments \
+ '(- *)'{-h,--help}'[output usage information]' \
+ '--watch[Stop watching folder for changes]' \
+ '*: :_pm2_id_namespace_all' \
+ && ret=0
+ ;;
+ (reload|delete|reset)
+ _arguments \
+ '(- *)'{-h,--help}'[output usage information]' \
+ '*: :_pm2_id_namespace_all' \
+ && ret=0
+ ;;
+ (module:install)
+ _arguments \
+ '(- *)'{-h,--help}'[output usage information]' \
+ '--tarball[is local tarball]' \
+ '--install[run yarn install before starting module]' \
+ '--docker[is docker container]' \
+ '--v1[install module in v1 manner(do not use it)]' \
+ '--safe[keep module backup, if new module fail = restore with previous]:time' \
+ && ret=0
+ ;;
+ (publish|module:publish)
+ _arguments \
+ '(- *)'{-h,--help}'[output usage information]' \
+ '--npm[publish on npm]' \
+ '*: :_files -/' \
+ && ret=0
+ ;;
+ (link)
+ _arguments \
+ '(- *)'{-h,--help}'[output usage information]' \
+ '--info-node[set url info node]:url' \
+ && ret=0
+ ;;
+ (plus)
+ _arguments \
+ '(- *)'{-h,--help}'[output usage information]' \
+ '--info-node[set url info node]:url' \
+ '(-d --discrete)'{-d,--discrete}'[silent mode]' \
+ '(-a --install-all)'{-a,--install-all}'[install all modules (force yes)]' \
+ && ret=0
+ ;;
+ (dump|save)
+ _arguments \
+ '(- *)'{-h,--help}'[output usage information]' \
+ '--force[force deletion of dump file even if empty]' \
+ && ret=0
+ ;;
+ (send|attach|describe|env)
+ _arguments \
+ '(- *)'{-h,--help}'[output usage information]' \
+ '1: :_pm2_id_names' \
+ && ret=0
+ ;;
+ (slist|sysinfos)
+ _arguments \
+ '(- *)'{-h,--help}'[output usage information]' \
+ '--tree[show as tree]' \
+ && ret=0
+ ;;
+ (logs)
+ _arguments \
+ '(- *)'{-h,--help}'[output usage information]' \
+ '--json[json log output]' \
+ '--format[formatted log output]' \
+ '--raw[raw output]' \
+ '--err[only shows error output]' \
+ '--out[only shows standard output]' \
+ '--line[output the last N lines, instead of the last 15 by default]:lines' \
+ '--timestamp[add timestamps(default format YYYY-MM-DD-HH:mm:ss)]:format' \
+ '--nostream[print logs without launching the log stream]' \
+ '*--highlight[highlights the given value]' \
+ '1: :_pm2_id_namespace' \
+ && ret=0
+ ;;
+ (serve)
+ _arguments \
+ '(- *)'{-h,--help}'[output usage information]' \
+ '--port[specify port to listen to]:port' \
+ '--spa[always serving index.html on inexistent sub path]' \
+ '--basic-auth-username[set basic auth username]:username' \
+ '--basic-auth-password[set basic auth password]:password' \
+ '--monitor[frontend app monitoring]:app' \
+ '*: :_files -/' \
+ && ret=0
+ ;;
+ (*)
+ _arguments \
+ '(- *)'{-h,--help}'[output usage information]' \
+ '*: :_files' \
+ && ret=0
+ ;;
+ esac
+ ;;
+ esac
+
+ return ret
+}
+
+(( $+functions[_pm2_subcommands] )) ||
+_pm2_subcommands() {
+ local -a subcommands=(
"start:start and daemonize an app"
"trigger:trigger process action"
"deploy:deploy your json"
"startOrRestart:start or restart JSON file"
"startOrReload:start or gracefully reload JSON file"
"pid:return pid of [app_name] or all"
+ "create:return pid of [app_name] or all"
+ "startOrGracefulReload:start or gracefully reload JSON file"
"stop:stop a process"
"restart:restart a process"
"scale:scale up/down a process in cluster mode depending on total_number param"
@@ -23,18 +240,23 @@ _1st_arguments=(
"sendSignal:send a system signal to the target process"
"ping:ping pm2 daemon - if not up it will launch it"
"updatePM2:update in-memory PM2 with local PM2"
+ "update:update in-memory PM2 with local PM2"
"install:install or update a module and run it forever"
+ "module\:install:install or update a module and run it forever"
"module\:update:update a module and run it forever"
"module\:generate:Generate a sample module in current folder"
"uninstall:stop and uninstall a module"
+ "module\:uninstall:stop and uninstall a module"
"package:Check & Package TAR type module"
"publish:Publish the module you are currently on"
+ "module\:publish:Publish the module you are currently on"
"set:sets the specified config "
"multiset:multiset eg \"key1 val1 key2 val2\""
"get:get value for "
+ "conf:get / set module config values"
"config:get / set module config values"
"unset:clears the specified config "
- "report:give a full pm2 report for https\://github.com/Unitech/pm2/issues"
+ "report:give a full pm2 report for https://github.com/Unitech/pm2/issues"
"link:link with the pm2 monitoring dashboard"
"unlink:unlink with the pm2 monitoring dashboard"
"monitor:monitor target process"
@@ -43,8 +265,8 @@ _1st_arguments=(
"plus:enable pm2 plus"
"login:Login to pm2 plus"
"logout:Logout from pm2 plus"
- "web:launch a health API on 0.0.0.0\:9615"
"dump:dump all processes for resurrecting them later"
+ "save:dump all processes for resurrecting them later"
"cleardump:Create empty dump file"
"send:send stdin to "
"attach:attach stdin/stdout to application identified by "
@@ -52,15 +274,27 @@ _1st_arguments=(
"unstartup:disable the pm2 startup hook"
"startup:enable the pm2 startup hook"
"logrotate:copy default logrotate configuration"
- "ecosystem:generate a process conf file. (mode = null or simple)"
+ "ecosystem:generate a process conf file"
+ "init:generate a process conf file"
"reset:reset counters for process"
- "describe:describe all parameters of a process id"
+ "describe:describe all parameters of a process"
+ "desc:describe all parameters of a process"
+ "info:describe all parameters of a process"
+ "show:describe all parameters of a process"
+ "env:list all environment variables of a process id"
"list:list all processes"
+ "l:list all processes"
+ "ps:list all processes"
+ "status:list all processes"
"jlist:list all processes in JSON format"
+ "sysmonit:start system monitoring daemon"
+ "slist:list system infos in JSON"
+ "sysinfos:list system infos in JSON"
"prettylist:print json in a prettified JSON"
"monit:launch termcaps monitoring"
"imonit:launch legacy termcaps monitoring"
"dashboard:launch dashboard with monitoring and logs"
+ "dash:launch dashboard with monitoring and logs"
"flush:flush logs"
"reloadLogs:reload all logs"
"logs:stream logs file. Default stream all logs"
@@ -70,99 +304,71 @@ _1st_arguments=(
"backward:downgrades repository to the previous commit for a given app"
"deepUpdate:performs a deep update of PM2"
"serve:serve a directory over http via port"
+ "autoinstall:auto install"
"examples:display pm2 usage examples"
-)
+ )
-local -a id_names
-
-_id_names() {
- local app_list
- app_list=`pm2 list -m`
-
- local -a names ids
- names=(`echo $app_list | grep '+---' | awk '{print $2}'`)
- ids=(`echo $app_list | grep 'pm2 id' | awk '{print $4}'`)
-
- if (( ${#ids} > 0 )); then
- for i in {1..${#ids}}; do
- id_names+=( "${ids[i]}:${names[i]}" )
- done
- fi
+ _describe -t subcommands 'subcommand' subcommands "$@"
}
-_arguments \
- '(-v --version)'{-v,--version}'[output version]' \
- '(-h --help)'{-h,--help}'[output usage information]' \
- '*:: :->subcmds' && return 0
+(( $+functions[_pm2_id_names] )) ||
+_pm2_id_names() {
+ local app_list=$(pm2 list -m)
+ local -a names=(${(@f)"$(echo $app_list | awk '/^\+---/{sub("+--- ", ""); print}')"})
+ local -a ids=(${(@f)"$(echo $app_list | awk '/^pm2 id/{sub("pm2 id :", ""); print}')"})
-if (( CURRENT == 1 )); then
- _describe "command" _1st_arguments
- return
+ if (( ${#ids} > 0 )); then
+ local -a id_names
+ for i in {1..${#ids}}; do
+ id_names+=( "${ids[i]}:${names[i]}" )
+ done
+
+ _describe 'id' id_names
+ fi
+}
+
+(( $+functions[_pm2_namespaces] )) ||
+_pm2_namespaces() {
+ local -a namespaces=(${(@f)"$(pm2 list -m | awk '/^namespace :/{ print $3 }')"})
+ if (( ${#namespaces} > 0 )); then
+ _values 'namespace' $namespaces
+ fi
+}
+
+(( $+functions[_pm2_id_namespace] )) ||
+_pm2_id_namespace() {
+ _alternative \
+ 'ids:id:_pm2_id_names' \
+ 'namespaces:namespace:_pm2_namespaces'
+}
+
+(( $+functions[_pm2_id_namespace_all] )) ||
+_pm2_id_namespace_all() {
+ _alternative \
+ 'ids:id:_pm2_id_names' \
+ 'namespaces:namespace:_pm2_namespaces' \
+ 'all:all:(all)'
+}
+
+(( $+functions[_pm2_id_namespace_file] )) ||
+_pm2_id_namespace_file() {
+ _alternative \
+ 'ids:id:_pm2_id_names' \
+ 'namespaces:namespace:_pm2_namespaces' \
+ 'files:file:_files'
+}
+
+if [ "$funcstack[1]" = "_pm2" ]; then
+ _pm2 "$@"
+else
+ compdef _pm2 pm2
fi
-local -a id_comp id_all_comp id_all_files_comp start_options logs_options
-id_comp=('1: :->id_comp')
-id_all_comp=('1: :->id_all_comp')
-id_all_files_comp=('1: :->id_all_files_comp')
-start_options=(
- '--watch[Watch folder for changes]'
- '--fresh[Rebuild Dockerfile]'
- '--daemon[Run container in Daemon mode (debug purposes)]'
- '--container[Start application in container mode]'
- '--dist[with --container; change local Dockerfile to containerize all files in current directory]'
- '--image-name[with --dist; set the exported image name]'
- '--node-version[with --container, set a specific major Node.js version]'
- '--dockerdaemon[for debugging purpose]'
- '(-h --help)'{-h,--help}'[output usage information]'
- $id_all_files_comp
-)
-logs_options=(
- '--json[json log output]'
- '--format[formatted log output]'
- '--raw[raw output]'
- '--err[only shows error output]'
- '--out[only shows standard output]'
- '--lines[output the last N lines, instead of the last 15 by default]'
- '--timestamp[add timestamps (default format YYYY-MM-DD-HH:mm:ss)]'
- '--nostream[print logs without launching the log stream]'
- '(-h --help)'{-h,--help}'[output usage information]'
- $id_all_comp
-)
+# Local Variables:
+# mode: Shell-Script
+# sh-indentation: 2
+# indent-tabs-mode: nil
+# sh-basic-offset: 2
+# End:
-case "$words[1]" in
- start)
- _arguments $start_options && return 0
- ;;
- logs)
- _arguments $logs_options && return 0
- ;;
- stop|restart|delete|reload|reset)
- _arguments $id_all_comp && return 0
- ;;
- env|inspect|monitor|unmonitor|describe)
- _arguments $id_comp && return 0
- ;;
- deploy|startOrRestart|startOrReload)
- _files ;;
-esac
-
-case "$state" in
- id_comp)
- _id_names
- _alternative \
- 'args:app args:(($id_names))'
- ;;
- id_all_comp)
- _id_names
- id_names+=(all)
- _alternative \
- 'args:app args:(($id_names))'
- ;;
- id_all_files_comp)
- _id_names
- id_names+=(all)
- _alternative \
- 'args:app args:(($id_names))' \
- 'files:filename:_files'
- ;;
-esac
+# vim: ft=zsh sw=2 ts=2 et
diff --git a/plugins/poetry-env/poetry-env.plugin.zsh b/plugins/poetry-env/poetry-env.plugin.zsh
index be46717d8..dca388dfe 100644
--- a/plugins/poetry-env/poetry-env.plugin.zsh
+++ b/plugins/poetry-env/poetry-env.plugin.zsh
@@ -6,10 +6,10 @@ _togglePoetryShell() {
fi
# Deactivate the current environment if moving out of a Poetry directory or into a different Poetry directory
- if [[ $poetry_active -eq 1 ]] && { [[ $in_poetry_dir -eq 0 ]] && [[ "$PWD" != "$poetry_dir"* ]]; }; then
+ if [[ $poetry_active -eq 1 ]] && { [[ $in_poetry_dir -eq 0 ]] || [[ "$PWD" != "$poetry_dir"* ]]; }; then
export poetry_active=0
unset poetry_dir
- deactivate
+ (( $+functions[deactivate] )) && deactivate
fi
# Activate the environment if in a Poetry directory and no environment is currently active
diff --git a/plugins/procs/procs.plugin.zsh b/plugins/procs/procs.plugin.zsh
index 332985bf9..8b15f1d5d 100644
--- a/plugins/procs/procs.plugin.zsh
+++ b/plugins/procs/procs.plugin.zsh
@@ -3,11 +3,19 @@ if (( ! $+commands[procs] )); then
fi
# If the completion file doesn't exist yet, we need to autoload it and
-# bind it to `minikube`. Otherwise, compinit will have already done that.
+# bind it to `procs`. Otherwise, compinit will have already done that.
if [[ ! -f "$ZSH_CACHE_DIR/completions/_procs" ]]; then
typeset -g -A _comps
autoload -Uz _procs
_comps[procs]=_procs
fi
-procs --gen-completion-out zsh >| "$ZSH_CACHE_DIR/completions/_procs" &|
+{
+ autoload -Uz is-at-least
+ local _version=$(procs --version)
+ if is-at-least "0.14" "${_version#procs }"; then
+ procs --gen-completion-out zsh >| "$ZSH_CACHE_DIR/completions/_procs"
+ else
+ procs --completion-out zsh >| "$ZSH_CACHE_DIR/completions/_procs"
+ fi
+} &|
diff --git a/plugins/pyenv/README.md b/plugins/pyenv/README.md
index 95d79cb52..2476bbd95 100644
--- a/plugins/pyenv/README.md
+++ b/plugins/pyenv/README.md
@@ -26,6 +26,14 @@ eval "$(pyenv init --path)"
- `ZSH_PYENV_VIRTUALENV`: if set to `false`, the plugin will not load pyenv-virtualenv
when it finds it.
+- `ZSH_THEME_PYENV_NO_SYSTEM`: if set to `true`, the plugin will not show the system or
+ default Python version when it finds it.
+- `ZSH_THEME_PYENV_PREFIX`: the prefix to display before the Python version in
+ the prompt.
+
+- `ZSH_THEME_PYENV_SUFFIX`: the prefix to display after the Python version in
+ the prompt.
+
## Functions
- `pyenv_prompt_info`: displays the Python version in use by pyenv; or the global Python
diff --git a/plugins/pyenv/pyenv.plugin.zsh b/plugins/pyenv/pyenv.plugin.zsh
index b5c9a7bd3..cd2a9e0ac 100644
--- a/plugins/pyenv/pyenv.plugin.zsh
+++ b/plugins/pyenv/pyenv.plugin.zsh
@@ -88,13 +88,19 @@ if [[ $FOUND_PYENV -eq 1 ]]; then
function pyenv_prompt_info() {
local version="$(pyenv version-name)"
- echo "${version:gs/%/%%}"
+ if [[ "$ZSH_THEME_PYENV_NO_SYSTEM" == "true" ]] && [[ "${version}" == "system" ]]; then
+ return
+ fi
+ echo "${ZSH_THEME_PYENV_PREFIX=}${version:gs/%/%%}${ZSH_THEME_PYENV_SUFFIX=}"
}
else
# Fall back to system python
function pyenv_prompt_info() {
+ if [[ "$ZSH_THEME_PYENV_NO_SYSTEM" == "true" ]]; then
+ return
+ fi
local version="$(python3 -V 2>&1 | cut -d' ' -f2)"
- echo "system: ${version:gs/%/%%}"
+ echo "${ZSH_THEME_PYENV_PREFIX=}system: ${version:gs/%/%%}${ZSH_THEME_PYENV_SUFFIX=}"
}
fi
diff --git a/plugins/python/README.md b/plugins/python/README.md
index b990a26b9..ca424ea55 100644
--- a/plugins/python/README.md
+++ b/plugins/python/README.md
@@ -13,7 +13,6 @@ plugins=(... python)
| Command | Description |
| ---------------- | -------------------------------------------------------------------------------------- |
| `py` | Runs `python3`. Only set if `py` is not installed. |
-| `ipython` | Runs the appropriate `ipython` version according to the activated virtualenv |
| `pyfind` | Finds .py files recursively in the current directory |
| `pyclean [dirs]` | Deletes byte-code and cache files from a list of directories or the current one |
| `pygrep ` | Looks for `text` in `*.py` files in the current directory, recursively |
@@ -25,16 +24,45 @@ plugins=(... python)
The plugin provides three utilities to manage Python 3.3+ [venv](https://docs.python.org/3/library/venv.html)
virtual environments:
-- `mkv [name]`: make a new virtual environment called `name` (default: if set `$PYTHON_VENV_NAME`, else
- `venv`) in the current directory.
+- `mkv [name]`: make a new virtual environment called `name` in the current directory.
+ **Default**: `$PYTHON_VENV_NAME` if set, otherwise `venv`.
-- `vrun [name]`: Activate the virtual environment called `name` (default: if set `$PYTHON_VENV_NAME`, else
- `venv`) in the current directory.
+- `vrun [name]`: activate the virtual environment called `name` in the current directory.
+ **Default**: the first existing in `$PYTHON_VENV_NAMES`.
-- `auto_vrun`: Automatically activate the venv virtual environment when entering a directory containing
+- `auto_vrun`: automatically activate the venv virtual environment when entering a directory containing
`/bin/activate`, and automatically deactivate it when navigating out of it (keeps venv activated
in subdirectories).
- - To enable the feature, set `export PYTHON_AUTO_VRUN=true` before sourcing oh-my-zsh.
- - Plugin activates first virtual environment in lexicographic order whose name begins with ``.
+ - To enable the feature, set `PYTHON_AUTO_VRUN=true` before sourcing oh-my-zsh.
+ - The plugin activates the first existing virtual environment, in order, appearing in `$PYTHON_VENV_NAMES`.
The default virtual environment name is `venv`. To use a different name, set
- `export PYTHON_VENV_NAME=`. For example: `export PYTHON_VENV_NAME=".venv"`
+ `PYTHON_VENV_NAME=`. For example: `PYTHON_VENV_NAME=".venv"`
+
+### Settings
+
+You can set these variables in your `.zshrc` file, before Oh My Zsh is sourced.
+For example:
+
+```sh
+PYTHON_VENV_NAME=".venv"
+PYTHON_VENV_NAMES=($PYTHON_VENV_NAME venv)
+...
+plugins=(... python)
+source "$ZSH/oh-my-zsh.sh"
+```
+
+
+## `$PYTHON_VENV_NAME`
+
+**Default**: `venv`.
+
+Preferred name for virtual environments, for example when creating via `mkv`.
+
+## `$PYTHON_VENV_NAMES`
+
+**Default**: `$PYTHON_VENV_NAME venv .venv`.
+
+Array of virtual environment names to be checked, in order, by `vrun` and `auto_vrun`.
+This means these functions will load the first existing virtual environment in this list.
+Duplicate names are ignored.
+
diff --git a/plugins/python/python.plugin.zsh b/plugins/python/python.plugin.zsh
index 6d7f440aa..2b139ddf0 100644
--- a/plugins/python/python.plugin.zsh
+++ b/plugins/python/python.plugin.zsh
@@ -43,19 +43,33 @@ function pyuserpaths() {
# Grep among .py files
alias pygrep='grep -nr --include="*.py"'
-# Run proper IPython regarding current virtualenv (if any)
-alias ipython='python3 -c "import sys; del sys.path[0]; import IPython; sys.exit(IPython.start_ipython())"'
-
# Share local directory as a HTTP server
alias pyserver="python3 -m http.server"
-## venv utilities
+## venv settings
: ${PYTHON_VENV_NAME:=venv}
+# Array of possible virtual environment names to look for, in order
+# -U for removing duplicates
+typeset -gaU PYTHON_VENV_NAMES
+[[ -n "$PYTHON_VENV_NAMES" ]] || PYTHON_VENV_NAMES=($PYTHON_VENV_NAME venv .venv)
+
# Activate a the python virtual environment specified.
-# If none specified, use $PYTHON_VENV_NAME, else 'venv'.
+# If none specified, use the first existing in $PYTHON_VENV_NAMES.
function vrun() {
+ if [[ -z "$1" ]]; then
+ local name
+ for name in $PYTHON_VENV_NAMES; do
+ local venvpath="${name:P}"
+ if [[ -d "$venvpath" ]]; then
+ vrun "$name"
+ return $?
+ fi
+ done
+ echo >&2 "Error: no virtual environment found in current directory"
+ fi
+
local name="${1:-$PYTHON_VENV_NAME}"
local venvpath="${name:P}"
@@ -74,7 +88,7 @@ function vrun() {
}
# Create a new virtual environment using the specified name.
-# If none specfied, use $PYTHON_VENV_NAME
+# If none specified, use $PYTHON_VENV_NAME
function mkv() {
local name="${1:-$PYTHON_VENV_NAME}"
local venvpath="${name:P}"
@@ -94,10 +108,11 @@ if [[ "$PYTHON_AUTO_VRUN" == "true" ]]; then
fi
if [[ $PWD != ${VIRTUAL_ENV:h} ]]; then
- for _file in "${PYTHON_VENV_NAME}"*/bin/activate(N.); do
+ local file
+ for file in "${^PYTHON_VENV_NAMES[@]}"/bin/activate(N.); do
# make sure we're not in a venv already
(( $+functions[deactivate] )) && deactivate > /dev/null 2>&1
- source $_file > /dev/null 2>&1
+ source $file > /dev/null 2>&1
break
done
fi
diff --git a/plugins/rails/_rails b/plugins/rails/_rails
index 48fd1909e..dbd843c80 100644
--- a/plugins/rails/_rails
+++ b/plugins/rails/_rails
@@ -366,10 +366,10 @@ _rails_generate() {
;|
(controller|job|model|resource|scaffold)
opts+=(
- '--parent=[The parent class for the generated controler]:parent class'
+ '--parent=[The parent class for the generated controller]:parent class'
)
;|
- (controler|mailer|resource|scaffold|scaffold_controller)
+ (controller|mailer|resource|scaffold|scaffold_controller)
opts+=(
'(-e --template-engine)'{-e,--template-engine=}'[Template engine to be invoked]:engine:(erb)'
)
diff --git a/plugins/rand-quote/rand-quote.plugin.zsh b/plugins/rand-quote/rand-quote.plugin.zsh
index 23c21dc8f..1eda54caa 100644
--- a/plugins/rand-quote/rand-quote.plugin.zsh
+++ b/plugins/rand-quote/rand-quote.plugin.zsh
@@ -8,7 +8,7 @@ function quote {
# Get random quote data
local data
- data="$(command curl -s --connect-timeout 2 "http://www.quotationspage.com/random.php" \
+ data="$(command curl -s --connect-timeout 2 "https://www.quotationspage.com/random.php" \
| iconv -c -f ISO-8859-1 -t UTF-8 \
| command grep -a -m 1 'dt class="quote"')"
diff --git a/plugins/rbw/rbw.plugin.zsh b/plugins/rbw/rbw.plugin.zsh
index b6cecf8b4..0b55e6e5f 100644
--- a/plugins/rbw/rbw.plugin.zsh
+++ b/plugins/rbw/rbw.plugin.zsh
@@ -29,9 +29,24 @@ function rbwpw {
echo "$service not found"
return 1
fi
+
+ # Generate a random identifier for this call to rbwpw
+ # so we can check if the clipboard content has changed
+ local _random="$RANDOM" _cache="$ZSH_CACHE_DIR/.rbwpw"
+ echo -n "$_random" > "$_cache"
+
+ # Use clipcopy to copy the password to the clipboard
echo -n $pw | clipcopy
echo "password for $service copied!"
- {sleep 20 && clipcopy /dev/null} &|
+
+ # Clear the clipboard after 20 seconds, but only if the clipboard hasn't
+ # changed (if rbwpw hasn't been called again)
+ {
+ sleep 20 \
+ && [[ "$(<"$_cache")" == "$_random" ]] \
+ && clipcopy /dev/null \
+ && command rm -f "$_cache" &>/dev/null
+ } &|
}
function _rbwpw {
diff --git a/plugins/rclone/README.md b/plugins/rclone/README.md
new file mode 100644
index 000000000..aa2ced94a
--- /dev/null
+++ b/plugins/rclone/README.md
@@ -0,0 +1,9 @@
+# Rclone plugin
+
+This plugin adds completion for [Rclone](https://rclone.org/), the command-line program to manage files on cloud storage.
+
+To use it, add `rclone` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... rclone)
+```
diff --git a/plugins/rclone/rclone.plugin.zsh b/plugins/rclone/rclone.plugin.zsh
new file mode 100644
index 000000000..a6676131c
--- /dev/null
+++ b/plugins/rclone/rclone.plugin.zsh
@@ -0,0 +1,14 @@
+# Completion
+if (( ! $+commands[rclone] )); then
+ return
+fi
+
+# If the completion file doesn't exist yet, we need to autoload it and
+# bind it to `rclone`. Otherwise, compinit will have already done that.
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_rclone" ]]; then
+ typeset -g -A _comps
+ autoload -Uz _rclone
+ _comps[rclone]=_rclone
+fi
+
+rclone completion zsh - >| "$ZSH_CACHE_DIR/completions/_rclone" &|
diff --git a/plugins/rsync/README.md b/plugins/rsync/README.md
index 032ee7f3b..04d16c88b 100644
--- a/plugins/rsync/README.md
+++ b/plugins/rsync/README.md
@@ -1,16 +1,26 @@
# rsync
-This plugin adds aliases for frequent [rsync](https://rsync.samba.org/) commands.
+This plugin adds aliases for frequent [rsync](https://rsync.samba.org/) commands, simplifying file transfer and synchronization tasks.
-To use it add `rsync` to the plugins array in you zshrc file.
+To use it add `rsync` to the plugins array in you `.zshrc` file.
```zsh
plugins=(... rsync)
```
-| Alias | Command |
-| ------------------- | ------------------------------------------------ |
-| *rsync-copy* | `rsync -avz --progress -h` |
-| *rsync-move* | `rsync -avz --progress -h --remove-source-files` |
-| *rsync-update* | `rsync -avzu --progress -h` |
-| *rsync-synchronize* | `rsync -avzu --delete --progress -h` |
+| Alias | Command | Description |
+| ------------------- | ------------------------------------------------ | ------------|
+| `rsync-copy` | `rsync -avz --progress -h` | Recursively copy files and directories, preserving permissions, timestamps, and symbolic links. Compression is enabled for faster transfers. Progress is displayed in a human-readable format. |
+| `rsync-move` | `rsync -avz --progress -h --remove-source-files` | Same as rsync-copy, but removes the source files after a successful transfer (effectively performing a move). |
+| `rsync-update` | `rsync -avzu --progress -h` | Like rsync-copy, but only updates files if the source is newer than the destination (or if the destination file is missing). |
+| `rsync-synchronize` | `rsync -avzu --delete --progress -h` | Performs bidirectional-style sync: updates files as in rsync-update and deletes files in the destination that no longer exist in the source. Useful for directory synchronization. |
+
+Explanation of Flags:
+ - -a: Archive mode; preserves symbolic links, permissions, timestamps, etc.
+ - -v: Verbose; shows details of the transfer process.
+ - -z: Compress file data during transfer for efficiency.
+ - -u: Skip files that are newer on the receiver.
+ - --progress: Show progress during file transfer.
+ - -h: Output numbers in human-readable format (e.g., 1K, 234M).
+ - --remove-source-files: Deletes source files after they are copied (used in rsync-move).
+ - --delete: Deletes files in the destination that are not present in the source (used in rsync-synchronize).
diff --git a/plugins/rust/rust.plugin.zsh b/plugins/rust/rust.plugin.zsh
index 858f14126..567cebc64 100644
--- a/plugins/rust/rust.plugin.zsh
+++ b/plugins/rust/rust.plugin.zsh
@@ -22,5 +22,5 @@ fi
rustup completions zsh >| "$ZSH_CACHE_DIR/completions/_rustup" &|
cat >| "$ZSH_CACHE_DIR/completions/_cargo" <<'EOF'
#compdef cargo
-source "$(rustc +${${(z)$(rustup default)}[1]} --print sysroot)"/share/zsh/site-functions/_cargo
+source "$(rustup run ${${(z)$(rustup default)}[1]} rustc --print sysroot)"/share/zsh/site-functions/_cargo
EOF
diff --git a/plugins/scd/scd b/plugins/scd/scd
index 7e9654b44..c79de4538 100755
--- a/plugins/scd/scd
+++ b/plugins/scd/scd
@@ -445,7 +445,7 @@ _scd_Y19oug_match() {
# build a list of matching directories reverse-sorted by their probabilities
dmatching=( ${(f)"$(
builtin printf "%s %s\n" ${(Oakv)drank} |
- /usr/bin/sort -grk1 )"}
+ command sort -grk1 )"}
)
dmatching=( ${dmatching#*[[:blank:]]} )
diff --git a/plugins/scw/README.md b/plugins/scw/README.md
index d2312c2e5..5dd630d64 100644
--- a/plugins/scw/README.md
+++ b/plugins/scw/README.md
@@ -1,7 +1,9 @@
-## Scaleway CLI autocomplete plugin
+## Scaleway CLI plugin
-[scw](https://github.com/scaleway/scaleway-cli): Manage Bare Metal servers from Command Line (as easily as with Docker)
+This plugin adds completion for [scw](https://github.com/scaleway/scaleway-cli), the command line interface for Scaleway.
-- Adds autocomplete options for all `scw` commands.
+To use it, add `scw` to the plugins array in your zshrc file:
-Maintainer : Manfred Touron ([@moul](https://github.com/moul))
+```zsh
+plugins=(... scw)
+```
diff --git a/plugins/scw/_scw b/plugins/scw/_scw
deleted file mode 100644
index 0eb125c65..000000000
--- a/plugins/scw/_scw
+++ /dev/null
@@ -1,333 +0,0 @@
-#compdef scw
-#
-# zsh completion for scw (https://www.scaleway.com)
-#
-# Inspired by https://github.com/felixr/docker-zsh-completion
-
-__scw_get_servers() {
- local expl
- declare -a servers
- servers=(${(f)"$(_call_program commands scw _completion servers-names)"})
- _describe -t servers "servers" servers
-}
-
-__scw_stoppedservers() {
- __scw_get_servers
-}
-
-__scw_runningservers() {
- __scw_get_servers
-}
-
-__scw_servers () {
- __scw_get_servers
-}
-
-__scw_images () {
- local expl
- declare -a images
- images=(${(f)"$(_call_program commands scw _completion images-names)"})
- _describe -t images "images" images
-}
-
-__scw_images_and_snapshots () {
- __scw_images
- __scw_snapshots
-}
-
-__scw_snapshots () {
- local expl
- declare -a snapshots
- snapshots=(${(f)"$(_call_program commands scw _completion --prefix snapshots-names)"})
- _describe -t snapshots "snapshots" snapshots
-}
-
-__scw_bootscripts () {
- local expl
- declare -a bootscripts
- bootscripts=(${(f)"$(_call_program commands scw _completion bootscripts-names)"})
- _describe -t bootscripts "bootscripts" bootscripts
-}
-
-__scw_tags() {
- __scw_images
-}
-
-__scw_repositories_with_tags() {
- __scw_images
-}
-
-__scw_search() {
- # declare -a scwsearch
- local cache_policy
- zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
- if [[ -z "$cache_policy" ]]; then
- zstyle ":completion:${curcontext}:" cache-policy __scw_caching_policy
- fi
-
- local searchterm cachename
- searchterm="${words[$CURRENT]%/}"
- cachename=_scw-search-$searchterm
-
- local expl
- local -a result
- if ( [[ ${(P)+cachename} -eq 0 ]] || _cache_invalid ${cachename#_} ) \
- && ! _retrieve_cache ${cachename#_}; then
- _message "Searching for ${searchterm}..."
- result=(${${${(f)"$(_call_program commands scw search ${searchterm})"}%% *}[2,-1]})
- _store_cache ${cachename#_} result
- fi
- _wanted scwsearch expl 'available images' compadd -a result
-}
-
-__scw_caching_policy()
-{
- oldp=( "$1"(Nmh+1) ) # 1 hour
- (( $#oldp ))
-}
-
-
-__scw_repositories () {
- __scw_images
-}
-
-__scw_commands () {
- # local -a _scw_subcommands
- local cache_policy
-
- zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
- if [[ -z "$cache_policy" ]]; then
- zstyle ":completion:${curcontext}:" cache-policy __scw_caching_policy
- fi
-
- if ( [[ ${+_scw_subcommands} -eq 0 ]] || _cache_invalid scw_subcommands) \
- && ! _retrieve_cache scw_subcommands;
- then
- local -a lines
- lines=(${(f)"$(_call_program commands scw 2>&1)"})
- _scw_subcommands=(${${${lines[$((${lines[(i)Commands:]} + 1)),${lines[(I) *]}]}## #}/ ##/:})
- _scw_subcommands=($_scw_subcommands 'help:Show help for a command')
- _store_cache scw_subcommands _scw_subcommands
- fi
- _describe -t scw-commands "scw command" _scw_subcommands
-}
-
-__scw_subcommand () {
- local -a _command_args
- case "$words[1]" in
- (attach)
- _arguments \
- '--no-stdin[Do not attach stdin]' \
- ':servers:__scw_runningservers'
- ;;
- (commit)
- _arguments \
- {-v,--volume=0}'[Volume slot]:volume: ' \
- ':server:__scw_servers' \
- ':repository:__scw_repositories_with_tags'
- ;;
- (cp)
- _arguments \
- ':server:->server' \
- ':hostpath:_files'
- case $state in
- (server)
- if compset -P '*:'; then
- _files
- else
- __scw_servers -qS ":"
- fi
- ;;
- esac
- ;;
- (exec)
- local state ret
- _arguments \
- {-T,--timeout=0}'[Set timeout values to seconds]' \
- {-w,--wait}'[Wait for SSH to be ready]' \
- ':servers:__scw_runningservers' \
- '*::command:->anycommand' && ret=0
-
- case $state in
- (anycommand)
- shift 1 words
- (( CURRENT-- ))
- _normal
- ;;
- esac
-
- return ret
- ;;
- (history)
- _arguments \
- '--no-trunc[Do not truncate output]' \
- {-q,--quiet}'[Only show numeric IDs]' \
- '*:images:__scw_images'
- ;;
- (images)
- _arguments \
- {-a,--all}'[Show all images]' \
- '--no-trunc[Do not truncate output]' \
- {-q,--quiet}'[Only show numeric IDs]' \
- ':repository:__scw_repositories'
- ;;
- (info)
- ;;
- (inspect)
- _arguments \
- {-f,--format=-}'[Format the output using the given go template]:template: ' \
- '*:servers:__scw_servers'
- ;;
- (kill)
- _arguments \
- '*:servers:__scw_runningservers'
- ;;
- (login)
- _arguments \
- {-o,--organization=-}'[Organization]:organization: ' \
- {-t,--token=-}'[Token]:token: ' \
- ':server: '
- ;;
- (logout)
- _arguments \
- ':server: '
- ;;
- (logs)
- _arguments \
- '*:servers:__scw_servers'
- ;;
- (port)
- _arguments \
- '1:servers:__scw_runningservers' \
- '2:port:_ports'
- ;;
- (start)
- _arguments \
- {-T,--timeout=0}'[Set timeout values to seconds]' \
- {-w,--wait}'[Wait for SSH to be ready]' \
- '*:servers:__scw_stoppedservers'
- ;;
- (rm)
- _arguments \
- '*:servers:__scw_stoppedservers'
- ;;
- (rmi)
- _arguments \
- '*:images:__scw_images'
- ;;
- (restart)
- _arguments \
- '*:servers:__scw_runningservers'
- ;;
- (stop)
- _arguments \
- {-t,--terminate}'[Stop and trash a server with its volumes]' \
- {-w,--wait}'[Synchronous stop. Wait for server to be stopped]' \
- '*:servers:__scw_runningservers'
- ;;
- (top)
- _arguments \
- '1:servers:__scw_runningservers' \
- '(-)*:: :->ps-arguments'
- case $state in
- (ps-arguments)
- _ps
- ;;
- esac
- ;;
- (ps)
- _arguments \
- {-a,--all}'[Show all servers. Only running servers are shown by default]' \
- {-l,--latest}'[Show only the latest created server]' \
- '-n[Show n last created servers, include non-running one]:n:(1 5 10 25 50)' \
- '--no-trunc[Do not truncate output]' \
- {-q,--quiet}'[Only show numeric IDs]'
- ;;
- (tag)
- _arguments \
- {-f,--force}'[force]'\
- ':image:__scw_images'\
- ':repository:__scw_repositories_with_tags'
- ;;
- (create|run)
- _arguments \
- {-a,--attach}'[Attach to stdin, stdout or stderr]' \
- '*'{-e,--environment=-}'[Set environment variables]:environment variable: ' \
- '--name=-[Server name]:name: ' \
- '--bootscript=-[Assign a bootscript]:bootscript:__scw_bootscripts ' \
- '*-v[Bind mount a volume]:volume: '\
- '(-):images:__scw_images_and_snapshots' \
- '(-):command: _command_names -e' \
- '*::arguments: _normal'
-
- case $state in
- (link)
- if compset -P '*:'; then
- _wanted alias expl 'Alias' compadd -E ""
- else
- __scw_runningservers -qS ":"
- fi
- ;;
- esac
- ;;
- (rename)
- _arguments \
- ':old name:__scw_servers' \
- ':new name: '
- ;;
- (search)
- _arguments \
- '--no-trunc[Do not truncate output]' \
- ':term: '
- ;;
- (wait)
- _arguments '*:servers:__scw_runningservers'
- ;;
- (help)
- _arguments ':subcommand:__scw_commands'
- ;;
- (*)
- _message 'Unknown sub command'
- esac
-
-}
-
-_scw () {
- # Support for subservices, which allows for `compdef _scw scw-shell=_scw_servers`.
- # Based on /usr/share/zsh/functions/Completion/Unix/_git without support for `ret`.
- if [[ $service != scw ]]; then
- _call_function - _$service
- return
- fi
-
- local curcontext="$curcontext" state line
- typeset -A opt_args
-
- _arguments -C \
- '-H[tcp://host:port to bind/connect to]:socket: ' \
- '(-): :->command' \
- '(-)*:: :->option-or-argument'
-
- if (( CURRENT == 1 )); then
-
- fi
- case $state in
- (command)
- __scw_commands
- ;;
- (option-or-argument)
- curcontext=${curcontext%:*:*}:scw-$words[1]:
- __scw_subcommand
- ;;
- esac
-}
-
-_scw "$@"
-
-# Local Variables:
-# mode: Shell-Script
-# sh-indentation: 4
-# indent-tabs-mode: nil
-# sh-basic-offset: 4
-# End:
-# vim: ft=zsh sw=4 ts=4 et
diff --git a/plugins/scw/scw.plugin.zsh b/plugins/scw/scw.plugin.zsh
new file mode 100644
index 000000000..cd8ed4ac7
--- /dev/null
+++ b/plugins/scw/scw.plugin.zsh
@@ -0,0 +1,14 @@
+if (( ! $+commands[scw] )); then
+ return
+fi
+
+_scw () {
+ output=($(scw autocomplete complete zsh -- ${CURRENT} ${words}))
+ opts=('-S' ' ')
+ if [[ $output == *= ]]; then
+ opts=('-S' '')
+ fi
+ compadd "${opts[@]}" -- "${output[@]}"
+}
+
+compdef _scw scw
diff --git a/plugins/ssh-agent/ssh-agent.plugin.zsh b/plugins/ssh-agent/ssh-agent.plugin.zsh
index 1da54d4dd..83548648b 100644
--- a/plugins/ssh-agent/ssh-agent.plugin.zsh
+++ b/plugins/ssh-agent/ssh-agent.plugin.zsh
@@ -43,7 +43,7 @@ function _add_identities() {
# this is to mimic the call to ssh-add with no identities
if [[ ${#identities} -eq 0 ]]; then
# key list found on `ssh-add` man page's DESCRIPTION section
- for id in id_rsa id_dsa id_ecdsa id_ed25519 identity; do
+ for id in id_rsa id_dsa id_ecdsa id_ed25519 id_ed25519_sk identity; do
# check if file exists
[[ -f "$HOME/.ssh/$id" ]] && identities+=($id)
done
@@ -100,7 +100,11 @@ function _add_identities() {
if zstyle -t :omz:plugins:ssh-agent agent-forwarding \
&& [[ -n "$SSH_AUTH_SOCK" ]]; then
if [[ ! -L "$SSH_AUTH_SOCK" ]]; then
- ln -sf "$SSH_AUTH_SOCK" /tmp/ssh-agent-$USERNAME-screen
+ if [[ -n "$TERMUX_VERSION" ]]; then
+ ln -sf "$SSH_AUTH_SOCK" "$PREFIX"/tmp/ssh-agent-$USERNAME-screen
+ else
+ ln -sf "$SSH_AUTH_SOCK" /tmp/ssh-agent-$USERNAME-screen
+ fi
fi
else
_start_agent
diff --git a/plugins/swiftpm/_swift b/plugins/swiftpm/_swift
index f9a603f58..358d1dcae 100644
--- a/plugins/swiftpm/_swift
+++ b/plugins/swiftpm/_swift
@@ -634,7 +634,7 @@ _swift_package_unedit() {
integer ret=1
local -a args
args+=(
- '--force[Unedit the package even if it has uncommited and unpushed changes]'
+ '--force[Unedit the package even if it has uncommitted and unpushed changes]'
':package-name:'
'--version[Show the version.]'
'(-help -h --help)'{-help,-h,--help}'[Show help information.]'
diff --git a/plugins/systemadmin/README.md b/plugins/systemadmin/README.md
index bd6b08760..7847e15e9 100644
--- a/plugins/systemadmin/README.md
+++ b/plugins/systemadmin/README.md
@@ -13,6 +13,7 @@ plugins=(... systemadmin)
| Alias | Command | Description |
|---------|----------------------------------------------------------------------------|--------------------------------------------------------------------|
| ping | `ping -c 5` | Sends only 5 ICMP Messages |
+| ping6 | `ping6 -c 5` | Sends only 5 ICMPv6 Messages |
| clr | `clear; echo Currently logged in on $TTY, as $USERNAME in directory $PWD.` | Clears the screen and prints the current user, TTY, and directory |
| path | `print -l $path` | Displays PATH with each entry on a separate line |
| mkdir | `mkdir -pv` | Automatically create parent directories and display verbose output |
@@ -48,4 +49,4 @@ plugins=(... systemadmin)
| geteip | Gather information regarding an external IP address using [icanhazip.com](https://icanhazip.com) |
| getip | Determine the local IP Address with `ip addr` or `ifconfig` |
| clrz | Clear zombie processes |
-| conssec | Show number of concurrent connections per second based on ngnix/access.log file or another log file if specified |
+| conssec | Show number of concurrent connections per second based on nginx/access.log file or another log file if specified |
diff --git a/plugins/systemadmin/systemadmin.plugin.zsh b/plugins/systemadmin/systemadmin.plugin.zsh
index 03dd995b6..fa7e5f786 100644
--- a/plugins/systemadmin/systemadmin.plugin.zsh
+++ b/plugins/systemadmin/systemadmin.plugin.zsh
@@ -21,6 +21,7 @@ function retlog() {
}
alias ping='ping -c 5'
+alias ping6='ping6 -c 5'
alias clr='clear; echo Currently logged in on $TTY, as $USERNAME in directory $PWD.'
alias path='print -l $path'
alias mkdir='mkdir -pv'
diff --git a/plugins/tailscale/README.md b/plugins/tailscale/README.md
new file mode 100644
index 000000000..be5a62137
--- /dev/null
+++ b/plugins/tailscale/README.md
@@ -0,0 +1,11 @@
+# tailscale
+
+This plugin provides completion for [tailscale](https://tailscale.com/) (Easy software-defined networks using an implementation of wireguard).
+
+To use it, add `tailscale` to the plugins array in your zshrc file.
+
+```
+plugins=(... tailscale)
+```
+
+**Author:** [@lukeab](https://github.com/lukeab)
diff --git a/plugins/tailscale/tailscale.plugin.zsh b/plugins/tailscale/tailscale.plugin.zsh
new file mode 100644
index 000000000..8b4e1e34d
--- /dev/null
+++ b/plugins/tailscale/tailscale.plugin.zsh
@@ -0,0 +1,25 @@
+if (( ! $+commands[tailscale] && ! $+aliases[tailscale] )); then
+ return
+fi
+
+# If the completion file doesn't exist yet, we need to autoload it and
+# bind it to `tailscale`. Otherwise, compinit will have already done that.
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_tailscale" ]]; then
+ typeset -g -A _comps
+ autoload -Uz _tailscale
+
+ if (( $+commands[tailscale] )); then
+ _comps[tailscale]=_tailscale
+ elif (( $+aliases[tailscale] )); then
+ _comps[${aliases[tailscale]:t}]=_tailscale
+ fi
+fi
+
+# If using the alias, let's make sure that the aliased executable is also bound
+# in case the alias points to "Tailscale" instead of "tailscale".
+# See https://github.com/ohmyzsh/ohmyzsh/discussions/12928
+if (( $+aliases[tailscale] )); then
+ _comps[${aliases[tailscale]:t}]=_tailscale
+fi
+
+tailscale completion zsh >| "$ZSH_CACHE_DIR/completions/_tailscale" &|
diff --git a/plugins/terraform/README.md b/plugins/terraform/README.md
index b5158b4e9..6c139ac51 100644
--- a/plugins/terraform/README.md
+++ b/plugins/terraform/README.md
@@ -15,22 +15,26 @@ plugins=(... terraform)
## Aliases
-| Alias | Command |
-| ------ | ------------------------- |
-| `tf` | `terraform` |
-| `tfa` | `terraform apply` |
-| `tfc` | `terraform console` |
-| `tfd` | `terraform destroy` |
-| `tff` | `terraform fmt` |
-| `tfi` | `terraform init` |
-| `tfiu` | `terraform init -upgrade` |
-| `tfo` | `terraform output` |
-| `tfp` | `terraform plan` |
-| `tfv` | `terraform validate` |
-| `tfs` | `terraform state` |
-| `tft` | `terraform test` |
-| `tfsh` | `terraform show` |
-
+| Alias | Command |
+| ------- | -------------------------------------- |
+| `tf` | `terraform` |
+| `tfa` | `terraform apply` |
+| `tfaa` | `terraform apply -auto-approve` |
+| `tfc` | `terraform console` |
+| `tfd` | `terraform destroy` |
+| `tfd!` | `terraform destroy -auto-approve` |
+| `tff` | `terraform fmt` |
+| `tffr` | `terraform fmt -recursive` |
+| `tfi` | `terraform init` |
+| `tfir` | `terraform init -reconfigure` |
+| `tfiu` | `terraform init -upgrade` |
+| `tfiur` | `terraform init -upgrade -reconfigure` |
+| `tfo` | `terraform output` |
+| `tfp` | `terraform plan` |
+| `tfv` | `terraform validate` |
+| `tfs` | `terraform state` |
+| `tft` | `terraform test` |
+| `tfsh` | `terraform show` |
## Prompt function
diff --git a/plugins/terraform/terraform.plugin.zsh b/plugins/terraform/terraform.plugin.zsh
index 71a58b939..0982fa193 100644
--- a/plugins/terraform/terraform.plugin.zsh
+++ b/plugins/terraform/terraform.plugin.zsh
@@ -2,9 +2,9 @@ function tf_prompt_info() {
# dont show 'default' workspace in home dir
[[ "$PWD" != ~ ]] || return
# check if in terraform dir and file exists
- [[ -d .terraform && -r .terraform/environment ]] || return
+ [[ -d "${TF_DATA_DIR:-.terraform}" && -r "${TF_DATA_DIR:-.terraform}/environment" ]] || return
- local workspace="$(< .terraform/environment)"
+ local workspace="$(< "${TF_DATA_DIR:-.terraform}/environment")"
echo "${ZSH_THEME_TF_PROMPT_PREFIX-[}${workspace:gs/%/%%}${ZSH_THEME_TF_PROMPT_SUFFIX-]}"
}
@@ -17,11 +17,16 @@ function tf_version_prompt_info() {
alias tf='terraform'
alias tfa='terraform apply'
+alias tfaa='terraform apply -auto-approve'
alias tfc='terraform console'
alias tfd='terraform destroy'
+alias 'tfd!'='terraform destroy -auto-approve'
alias tff='terraform fmt'
+alias tffr='terraform fmt -recursive'
alias tfi='terraform init'
+alias tfir='terraform init -reconfigure'
alias tfiu='terraform init -upgrade'
+alias tfiur='terraform init -upgrade -reconfigure'
alias tfo='terraform output'
alias tfp='terraform plan'
alias tfv='terraform validate'
diff --git a/plugins/timer/timer.plugin.zsh b/plugins/timer/timer.plugin.zsh
index d21d59989..6baf1f681 100644
--- a/plugins/timer/timer.plugin.zsh
+++ b/plugins/timer/timer.plugin.zsh
@@ -6,7 +6,7 @@ __timer_current_time() {
}
__timer_format_duration() {
- local mins=$(printf '%.0f' $(($1 / 60)))
+ local mins=$(printf '%.0f' $(($(IFS='.' read int dec <<< "$1"; echo $int) / 60)))
local secs=$(printf "%.${TIMER_PRECISION:-1}f" $(($1 - 60 * mins)))
local duration_str=$(echo "${mins}m${secs}s")
local format="${TIMER_FORMAT:-/%d}"
diff --git a/plugins/timoni/README.md b/plugins/timoni/README.md
new file mode 100644
index 000000000..8701ede48
--- /dev/null
+++ b/plugins/timoni/README.md
@@ -0,0 +1,9 @@
+# Timoni plugin
+
+This plugin adds completion for [Timoni](https://timoni.sh), a package manager for Kubernetes, powered by CUE and inspired by Helm.
+
+To use it, add `timoni` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... timoni)
+```
diff --git a/plugins/timoni/timoni.plugin.zsh b/plugins/timoni/timoni.plugin.zsh
new file mode 100644
index 000000000..971eda0b4
--- /dev/null
+++ b/plugins/timoni/timoni.plugin.zsh
@@ -0,0 +1,14 @@
+# Autocompletion for the Timoni CLI (timoni).
+if (( ! $+commands[timoni] )); then
+ return
+fi
+
+# If the completion file doesn't exist yet, we need to autoload it and
+# bind it to `timoni`. Otherwise, compinit will have already done that.
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_timoni" ]]; then
+ typeset -g -A _comps
+ autoload -Uz _timoni
+ _comps[timoni]=_timoni
+fi
+
+timoni completion zsh >| "$ZSH_CACHE_DIR/completions/_timoni" &|
diff --git a/plugins/tmux/README.md b/plugins/tmux/README.md
index 09952a9f5..39c57f846 100644
--- a/plugins/tmux/README.md
+++ b/plugins/tmux/README.md
@@ -29,18 +29,19 @@ The plugin also supports the following:
## Configuration Variables
-| Variable | Description |
-| ----------------------------------- | ----------------------------------------------------------------------------------------------------------- |
-| `ZSH_TMUX_AUTOSTART` | Automatically starts tmux (default: `false`) |
-| `ZSH_TMUX_AUTOSTART_ONCE` | Autostart only if tmux hasn't been started previously (default: `true`) |
-| `ZSH_TMUX_AUTOCONNECT` | Automatically connect to a previous session if it exits (default: `true`) |
-| `ZSH_TMUX_AUTOQUIT` | Automatically closes terminal once tmux exits (default: `ZSH_TMUX_AUTOSTART`) |
-| `ZSH_TMUX_CONFIG` | Set the configuration path (default: `$HOME/.tmux.conf`, `$XDG_CONFIG_HOME/tmux/tmux.conf`) |
-| `ZSH_TMUX_DEFAULT_SESSION_NAME` | Set tmux default session name when autostart is enabled |
-| `ZSH_TMUX_AUTONAME_SESSION` | Automatically name new sessions based on the basename of `$PWD` (default: `false`) |
-| `ZSH_TMUX_DETACHED` | Set the detached mode (default: `false`) |
-| `ZSH_TMUX_FIXTERM` | Sets `$TERM` to 256-color term or not based on current terminal support |
-| `ZSH_TMUX_FIXTERM_WITHOUT_256COLOR` | `$TERM` to use for non 256-color terminals (default: `tmux` if available, `screen` otherwise) |
-| `ZSH_TMUX_FIXTERM_WITH_256COLOR` | `$TERM` to use for 256-color terminals (default: `tmux-256color` if available, `screen-256color` otherwise) |
-| `ZSH_TMUX_ITERM2` | Sets the `-CC` option for iTerm2 tmux integration (default: `false`) |
-| `ZSH_TMUX_UNICODE` | Set `tmux -u` option to support unicode |
+| Variable | Description |
+| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
+| `ZSH_TMUX_AUTOREFRESH` | Automatically refresh global environments (default: `false`) |
+| `ZSH_TMUX_AUTOSTART` | Automatically starts tmux (default: `false`) |
+| `ZSH_TMUX_AUTOSTART_ONCE` | Autostart only if tmux hasn't been started previously (default: `true`) |
+| `ZSH_TMUX_AUTOCONNECT` | Automatically connect to a previous session if it exits (default: `true`) |
+| `ZSH_TMUX_AUTOQUIT` | Automatically closes terminal once tmux exits (default: `ZSH_TMUX_AUTOSTART`) |
+| `ZSH_TMUX_CONFIG` | Set the configuration path (default: `$HOME/.tmux.conf`, `$XDG_CONFIG_HOME/tmux/tmux.conf`) |
+| `ZSH_TMUX_DEFAULT_SESSION_NAME` | Set tmux default session name when autostart is enabled |
+| `ZSH_TMUX_AUTONAME_SESSION` | Automatically name new sessions based on the basename of `$PWD` (default: `false`) |
+| `ZSH_TMUX_DETACHED` | Set the detached mode (default: `false`) |
+| `ZSH_TMUX_FIXTERM` | Sets `$TERM` to 256-color term or not based on current terminal support |
+| `ZSH_TMUX_FIXTERM_WITHOUT_256COLOR` | `$TERM` to use for non 256-color terminals (default: `tmux` if available, `screen` otherwise) |
+| `ZSH_TMUX_FIXTERM_WITH_256COLOR` | `$TERM` to use for 256-color terminals (default: `tmux-256color` if available, `screen-256color` otherwise) |
+| `ZSH_TMUX_ITERM2` | Sets the `-CC` option for [iTerm2 tmux integration](https://iterm2.com/documentation-tmux-integration.html) (default: `false`) |
+| `ZSH_TMUX_UNICODE` | Set `tmux -u` option to support unicode |
diff --git a/plugins/tmux/tmux.plugin.zsh b/plugins/tmux/tmux.plugin.zsh
index 51cc7d6a5..4c184c2d0 100644
--- a/plugins/tmux/tmux.plugin.zsh
+++ b/plugins/tmux/tmux.plugin.zsh
@@ -15,6 +15,8 @@ fi
: ${ZSH_TMUX_AUTOQUIT:=$ZSH_TMUX_AUTOSTART}
# Automatically name the new session based on the basename of PWD
: ${ZSH_TMUX_AUTONAME_SESSION:=false}
+# Automatically pick up tmux environments
+: ${ZSH_TMUX_AUTOREFRESH:=false}
# Set term to screen or screen-256color based on current terminal support
: ${ZSH_TMUX_DETACHED:=false}
# Set detached mode
@@ -158,6 +160,15 @@ function _zsh_tmux_plugin_run() {
fi
}
+# Refresh tmux environment variables.
+function _zsh_tmux_plugin_preexec()
+{
+ local -a tmux_cmd
+ tmux_cmd=(command tmux)
+
+ eval $($tmux_cmd show-environment -s)
+}
+
# Use the completions for tmux for our function
compdef _tmux _zsh_tmux_plugin_run
# Alias tmux to our wrapper function.
@@ -177,10 +188,16 @@ function _tmux_directory_session() {
alias tds=_tmux_directory_session
# Autostart if not already in tmux and enabled.
-if [[ -z "$TMUX" && "$ZSH_TMUX_AUTOSTART" == "true" && -z "$INSIDE_EMACS" && -z "$EMACS" && -z "$VIM" && -z "$INTELLIJ_ENVIRONMENT_READER" ]]; then
+if [[ -z "$TMUX" && "$ZSH_TMUX_AUTOSTART" == "true" && -z "$INSIDE_EMACS" && -z "$EMACS" && -z "$VIM" && -z "$INTELLIJ_ENVIRONMENT_READER" && -z "$ZED_TERM" ]]; then
# Actually don't autostart if we already did and multiple autostarts are disabled.
if [[ "$ZSH_TMUX_AUTOSTART_ONCE" == "false" || "$ZSH_TMUX_AUTOSTARTED" != "true" ]]; then
export ZSH_TMUX_AUTOSTARTED=true
_zsh_tmux_plugin_run
fi
fi
+
+# Automatically refresh tmux environments if tmux is running.
+if [[ -n "$TMUX" && "$ZSH_TMUX_AUTOREFRESH" == "true" ]] && tmux ls >/dev/null 2>/dev/null; then
+ autoload -U add-zsh-hook
+ add-zsh-hook preexec _zsh_tmux_plugin_preexec
+fi
diff --git a/plugins/ubuntu/README.md b/plugins/ubuntu/README.md
index 20f5c65ee..4b09ba02b 100644
--- a/plugins/ubuntu/README.md
+++ b/plugins/ubuntu/README.md
@@ -10,10 +10,11 @@ plugins=(... ubuntu)
## Aliases
-Commands that use `$APT` will use `apt` if installed or defer to `apt-get` otherwise.
+Commands that use `$APT` will use `apt-fast` if installed, or `apt` if installed, or defer to `apt-get`
+otherwise.
| Alias | Command | Description |
-|---------|--------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|
+| ------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------- |
| age | `sudo $APT` | Run apt-get with sudo |
| acs | `apt-cache search` | Search the apt-cache with the specified criteria |
| acsp | `apt-cache showpkg` | Shows information about the listed packages |
@@ -26,7 +27,7 @@ Commands that use `$APT` will use `apt` if installed or defer to `apt-get` other
| agd | `sudo $APT dselect-upgrade` | Follows dselect choices for package installation |
| agi | `sudo $APT install ` | Install the specified package |
| agli | `apt list --installed` | List the installed packages |
-| aglu | `sudo apt-get -u upgrade --assume-no` | Run an apt-get upgrade assuming no to all prompts |
+| aglu | `apt list --upgradable` | List available updates only |
| agp | `sudo $APT purge ` | Remove a package including any configuration files |
| agr | `sudo $APT remove ` | Remove a package |
| ags | `$APT source ` | Fetch the source for the specified package |
@@ -36,21 +37,20 @@ Commands that use `$APT` will use `apt` if installed or defer to `apt-get` other
| agar | `sudo $APT autoremove` | Remove automatically installed packages no longer needed |
| aguu | `sudo $APT update && sudo $APT upgrade` | Update packages list and upgrade available packages |
| allpkgs | `dpkg --get-selections \| grep -v deinstall` | Print all installed packages |
-| kclean | `sudo aptitude remove -P ?and(~i~nlinux-(ima\|hea) ?not(~n$(uname -r)))` |Remove ALL kernel images and headers EXCEPT the one in use |
+| kclean | `sudo aptitude remove -P ?and(~i~nlinux-(ima\|hea) ?not(~n$(uname -r)))` | Remove ALL kernel images and headers EXCEPT the one in use |
| mydeb | `time dpkg-buildpackage -rfakeroot -us -uc` | Create a basic .deb package |
| ppap | `sudo ppa-purge ` | Remove the specified PPA |
-
## Functions
-| Function | Usage |Description |
-|-------------------|---------------------------------------|--------------------------------------------------------------------------|
+| Function | Usage | Description |
+| ----------------- | ------------------------------------- | ------------------------------------------------------------------------ |
| aar | `aar ppa:xxxxxx/xxxxxx [packagename]` | apt-add-repository with automatic install/upgrade of the desired package |
| apt-history | `apt-history ` | Prints the Apt history of the specified action |
| apt-list-packages | `apt-list-packages` | List packages by size |
| kerndeb | `kerndeb` | Kernel-package building shortcut |
-## Authors:
+## Authors
- [@AlexBio](https://github.com/AlexBio)
- [@dbb](https://github.com/dbb)
@@ -59,3 +59,4 @@ Commands that use `$APT` will use `apt` if installed or defer to `apt-get` other
- [Nicolas Jonas](https://nextgenthemes.com)
- [@loctauxphilippe](https://github.com/loctauxphilippe)
- [@HaraldNordgren](https://github.com/HaraldNordgren)
+- [@AmrElsayyad](https://github.com/AmrElsayyad)
diff --git a/plugins/ubuntu/ubuntu.plugin.zsh b/plugins/ubuntu/ubuntu.plugin.zsh
index 7b765a406..66e2d52cb 100644
--- a/plugins/ubuntu/ubuntu.plugin.zsh
+++ b/plugins/ubuntu/ubuntu.plugin.zsh
@@ -1,11 +1,22 @@
-(( $+commands[apt] )) && APT=apt || APT=apt-get
+# Detect available package manager (prefer apt-fast > apt > apt-get)
+if (( $+commands[apt-fast] )); then
+ APT=apt-fast
+elif (( $+commands[apt] )); then
+ APT=apt
+else
+ APT=apt-get
+fi
alias acs='apt-cache search'
alias afs='apt-file search --regexp'
# These are apt/apt-get only
-alias ags="$APT source"
+if (( $+commands[apt] )); then
+ alias ags="apt source"
+else
+ alias ags="apt-get source"
+fi
alias acp='apt-cache policy'
diff --git a/plugins/universalarchive/README.md b/plugins/universalarchive/README.md
index 93a1bd9fc..bcd33cea0 100644
--- a/plugins/universalarchive/README.md
+++ b/plugins/universalarchive/README.md
@@ -1,46 +1,76 @@
# universalarchive plugin
-Lets you compress files by a command `ua `, supporting various
-compression formats (e.g. 7z, tar.gz, lzma, ...).
+The `universalarchive` plugin provides a convenient command-line interface for archiving files and directories using a wide variety of compression formats - without having to remember the exact syntax for each tool.
-To enable it, add `universalarchive` to the plugins array in your zshrc file:
+To enable it, add `universalarchive` to the plugins array in your `.zshrc` file:
```zsh
plugins=(... universalarchive)
```
+## Features
+ - Compress files and directories using a simple, unified command: ua
+ - Automatically detects file/directory names to generate appropriate output names
+ - Supports fallback naming if an output file already exists
+ - Works with many common and advanced compression formats
+ - Designed for simplicity and quick use in the terminal
+
## Usage
-Run `ua ` to compress `` into an archive file using ``.
-For example:
-
+Basic command format:
```sh
-ua xz *.html
+ua
+```
+- ``: the archive format to use (e.g., `zip`, `tar.gz`, `xz`, `7z`, etc.)
+- ``: one or more files or directories to compress
+
+## Examples:
+
+Compresses `notes.txt` and `images` into `notes.zip`
+```sh
+ua zip notes.txt images/
```
-this command will compress all `.html` files in directory `folder` into `folder.xz`.
+Creates `myproject.tar.gz`
+```sh
+ua tar.gz myproject/
+```
-This plugin saves you from having to remember which command line arguments compress a file.
+Compresses all .log files into `current_folder.xz`
+```sh
+ua xz *.log
+```
-## Supported compression formats
+The plugin will generate a default archive filename based on the input:
+ - For a file, the output is derived from the file name without its extension.
+ - For a directory, it uses the directory name.
+ - For multiple files, it uses the name of the common parent directory.
-| Extension | Description |
-|:-----------------|:-------------------------------|
-| `7z` | 7zip file |
-| `bz2` | Bzip2 file |
-| `gz` | Gzip file |
-| `lzma` | LZMA archive |
-| `lzo` | LZO archive |
-| `rar` | WinRAR archive |
-| `tar` | Tarball |
-| `tbz`/`tar.bz2` | Tarball with bzip2 compression |
-| `tgz`/`tar.gz` | Tarball with gzip compression |
-| `tlz`/`tar.lzma` | Tarball with lzma compression |
-| `txz`/`tar.xz` | Tarball with lzma2 compression |
-| `tZ`/`tar.Z` | Tarball with LZW compression |
-| `xz` | LZMA2 archive |
-| `Z` | Z archive (LZW) |
-| `zip` | Zip archive |
-| `zst` | Zstd archive |
+ If the output file already exists, a unique filename is generated using `mktemp`.
-See [list of archive formats](https://en.wikipedia.org/wiki/List_of_archive_formats) for more information regarding the archive formats.
+## Supported Archive Formats
+
+| Format | Description | Tool Used |
+|:-----------------|:-------------------------------|:-----------------|
+| `7z` | 7zip archive | `7z` |
+| `bz2` | Bzip2-compressed file | `bzip2` |
+| `gz` | Gzip-compressed file | `gzip` |
+| `lzma` | LZMA-compressed file | `lzma` |
+| `lzo` | LZO-compressed file | `lzop` |
+| `rar` | WinRAR archive | `rar` |
+| `tar` | Uncompressed tarball | `tar` |
+| `tbz`,`tar.bz2` | Tarball compressed with Bzip2 | `tar + bzip2` |
+| `tgz`,`tar.gz` | Tarball compressed with Gzip | `tar + gzip` |
+| `tlz`,`tar.lzma` | Tarball compressed with LZMA | `tar + lzma` |
+| `txz`,`tar.xz` | Tarball compressed with LZMA2 | `tar + xz` |
+| `tZ`,`tar.Z` | Tarball compressed with LZW | `tar + compress` |
+| `xz` | XZ-compressed file | `xz` |
+| `Z` | LZW-compressed file | `compress` |
+| `zip` | Standard Zip archive | `zip` |
+| `zst` | Zstandard-compressed file | `zstd` |
+
+ > Note: Some formats may require specific tools to be installed on your system (e.g. `7z`, `rar`, `lzop`, `zstd`). Make sure these tools are available in your `$PATH`.
+
+## Auto-Completion
+
+The plugin provides tab-completion for supported formats and input files. Type `ua ` to see available formats, and `ua ` to browse files.
diff --git a/plugins/uv/README.md b/plugins/uv/README.md
new file mode 100644
index 000000000..1b99c1185
--- /dev/null
+++ b/plugins/uv/README.md
@@ -0,0 +1,28 @@
+# uv plugin
+
+This plugin automatically installs [uv](https://github.com/astral-sh/uv)'s completions for you, and keeps them up to date. It also adds convenient aliases for common usage.
+
+To use it, add `uv` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... uv)
+```
+
+## Aliases
+
+| Alias | Command | Description |
+|:----- |------------------------------------------------------------------------ |:-------------------------------------------------------------------- |
+| uva | `uv add` | Add packages to the project |
+| uvexp | `uv export --format requirements-txt --no-hashes --output-file requirements.txt --quiet` | Export the lock file to `requirements.txt` |
+| uvl | `uv lock` | Lock the dependencies |
+| uvlr | `uv lock --refresh` | Rebuild the lock file without upgrading dependencies |
+| uvlu | `uv lock --upgrade` | Lock the dependencies to the newest compatible versions |
+| uvp | `uv pip` | Manage pip packages |
+| uvpy | `uv python` | Manage Python installs |
+| uvr | `uv run` | Run commands within the project's environment |
+| uvrm | `uv remove` | Remove packages from the project |
+| uvs | `uv sync` | Sync the environment with the lock file |
+| uvsr | `uv sync --refresh` | "Force" sync the environment with the lock file (ignore cache) |
+| uvsu | `uv sync --upgrade` | Sync the environment, allowing upgrades and ignoring the lock file |
+| uvup | `uv self update` | Update the UV tool to the latest version |
+| uvv | `uv venv` | Manage virtual environments |
diff --git a/plugins/uv/uv.plugin.zsh b/plugins/uv/uv.plugin.zsh
new file mode 100644
index 000000000..abcbc117e
--- /dev/null
+++ b/plugins/uv/uv.plugin.zsh
@@ -0,0 +1,40 @@
+# Return immediately if uv is not found
+if (( ! ${+commands[uv]} )); then
+ return
+fi
+
+alias uv="noglob uv"
+
+alias uva='uv add'
+alias uvexp='uv export --format requirements-txt --no-hashes --output-file requirements.txt --quiet'
+alias uvl='uv lock'
+alias uvlr='uv lock --refresh'
+alias uvlu='uv lock --upgrade'
+alias uvp='uv pip'
+alias uvpy='uv python'
+alias uvr='uv run'
+alias uvrm='uv remove'
+alias uvs='uv sync'
+alias uvsr='uv sync --refresh'
+alias uvsu='uv sync --upgrade'
+alias uvup='uv self update'
+alias uvv='uv venv'
+
+# If the completion file doesn't exist yet, we need to autoload it and
+# bind it. Otherwise, compinit will have already done that.
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_uv" ]]; then
+ typeset -g -A _comps
+ autoload -Uz _uv
+ _comps[uv]=_uv
+fi
+
+if [[ ! -f "$ZSH_CACHE_DIR/completions/_uvx" ]]; then
+ typeset -g -A _comps
+ autoload -Uz _uvx
+ _comps[uvx]=_uvx
+fi
+
+# uv and uvx are installed together (uvx is an alias to `uv tool run`)
+# Overwrites the file each time as completions might change with uv versions.
+uv generate-shell-completion zsh >| "$ZSH_CACHE_DIR/completions/_uv" &|
+uvx --generate-shell-completion zsh >| "$ZSH_CACHE_DIR/completions/_uvx" &|
diff --git a/plugins/vagrant-prompt/README.md b/plugins/vagrant-prompt/README.md
index 0720f4bde..f7bfce4f3 100644
--- a/plugins/vagrant-prompt/README.md
+++ b/plugins/vagrant-prompt/README.md
@@ -17,11 +17,15 @@ To display Vagrant info on your prompt add the `vagrant_prompt_info` to the
`$PROMPT` or `$RPROMPT` variable in your theme. Example:
```zsh
-PROMPT='%{$fg[$NCOLOR]%}%B%n%b%{$reset_color%}:%{$fg[blue]%}%B%c/%b%{$reset_color%} $(vagrant_prompt_info)$(svn_prompt_info)$(git_prompt_info)%(!.#.$) '
+PROMPT="$PROMPT"' $(vagrant_prompt_info)'
+# or
+RPROMPT='$(vagrant_prompt_info)'
```
-`vagrant_prompt_info` makes use of some custom variables. This is an example
-definition:
+### Customization
+
+`vagrant_prompt_info` makes use of the following custom variables, which can be set in your
+`.zshrc` file:
```zsh
ZSH_THEME_VAGRANT_PROMPT_PREFIX="%{$fg_bold[blue]%}["
@@ -31,3 +35,18 @@ ZSH_THEME_VAGRANT_PROMPT_POWEROFF="%{$fg_no_bold[red]%}●"
ZSH_THEME_VAGRANT_PROMPT_SUSPENDED="%{$fg_no_bold[yellow]%}●"
ZSH_THEME_VAGRANT_PROMPT_NOT_CREATED="%{$fg_no_bold[white]%}○"
```
+
+### State to variable mapping
+
+The plugin uses the output reported by `vagrant status` to print whichever symbol matches,
+according to the following table:
+
+| State | Symbol |
+| ----------- | -------------------------------------- |
+| running | `ZSH_THEME_VAGRANT_PROMPT_RUNNING` |
+| not running | `ZSH_THEME_VAGRANT_PROMPT_POWEROFF` |
+| poweroff | `ZSH_THEME_VAGRANT_PROMPT_POWEROFF` |
+| paused | `ZSH_THEME_VAGRANT_PROMPT_SUSPENDED` |
+| saved | `ZSH_THEME_VAGRANT_PROMPT_SUSPENDED` |
+| suspended | `ZSH_THEME_VAGRANT_PROMPT_SUSPENDED` |
+| not created | `ZSH_THEME_VAGRANT_PROMPT_NOT_CREATED` |
diff --git a/plugins/vagrant-prompt/vagrant-prompt.plugin.zsh b/plugins/vagrant-prompt/vagrant-prompt.plugin.zsh
index 29f4038c5..2d8455a53 100644
--- a/plugins/vagrant-prompt/vagrant-prompt.plugin.zsh
+++ b/plugins/vagrant-prompt/vagrant-prompt.plugin.zsh
@@ -1,16 +1,18 @@
function vagrant_prompt_info() {
- local vm_states vm_state
- if [[ -d .vagrant && -f Vagrantfile ]]; then
- vm_states=(${(f)"$(vagrant status 2> /dev/null | sed -nE 's/^.*(saved|poweroff|running|not created) \([[:alnum:]_]+\)$/\1/p')"})
- printf '%s' $ZSH_THEME_VAGRANT_PROMPT_PREFIX
- for vm_state in $vm_states; do
- case "$vm_state" in
- saved) printf '%s' $ZSH_THEME_VAGRANT_PROMPT_SUSPENDED ;;
- running) printf '%s' $ZSH_THEME_VAGRANT_PROMPT_RUNNING ;;
- poweroff) printf '%s' $ZSH_THEME_VAGRANT_PROMPT_POWEROFF ;;
- "not created") printf '%s' $ZSH_THEME_VAGRANT_PROMPT_NOT_CREATED ;;
- esac
- done
- printf '%s' $ZSH_THEME_VAGRANT_PROMPT_SUFFIX
+ if [[ ! -d .vagrant || ! -f Vagrantfile ]]; then
+ return
fi
+
+ local vm_states vm_state
+ vm_states=(${(f)"$(vagrant status 2> /dev/null | sed -nE 's/^[^ ]* *([[:alnum:] ]*) \([[:alnum:]_]+\)$/\1/p')"})
+ printf '%s' $ZSH_THEME_VAGRANT_PROMPT_PREFIX
+ for vm_state in $vm_states; do
+ case "$vm_state" in
+ running) printf '%s' $ZSH_THEME_VAGRANT_PROMPT_RUNNING ;;
+ "not running"|poweroff) printf '%s' $ZSH_THEME_VAGRANT_PROMPT_POWEROFF ;;
+ paused|saved|suspended) printf '%s' $ZSH_THEME_VAGRANT_PROMPT_SUSPENDED ;;
+ "not created") printf '%s' $ZSH_THEME_VAGRANT_PROMPT_NOT_CREATED ;;
+ esac
+ done
+ printf '%s' $ZSH_THEME_VAGRANT_PROMPT_SUFFIX
}
diff --git a/plugins/vault/README.md b/plugins/vault/README.md
new file mode 100644
index 000000000..cc270a385
--- /dev/null
+++ b/plugins/vault/README.md
@@ -0,0 +1,9 @@
+# Vault plugin
+
+This plugin adds completion for [Vault](https://www.vaultproject.io/), the secrets and sensitive data manager.
+
+To use it, add `vault` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... vault)
+```
diff --git a/plugins/vault/vault.plugin.zsh b/plugins/vault/vault.plugin.zsh
new file mode 100644
index 000000000..996cd12ad
--- /dev/null
+++ b/plugins/vault/vault.plugin.zsh
@@ -0,0 +1,7 @@
+# Completion
+if (( ! $+commands[vault] )); then
+ return
+fi
+
+autoload -Uz bashcompinit && bashcompinit
+complete -o nospace -C vault vault
diff --git a/plugins/vi-mode/README.md b/plugins/vi-mode/README.md
index 6e781f296..bc78cfa3d 100644
--- a/plugins/vi-mode/README.md
+++ b/plugins/vi-mode/README.md
@@ -46,7 +46,7 @@ hasn't been defined by theme, *Insert mode* is not displayed by default.
You can change these indicators by setting the `MODE_INDICATOR` (*Normal mode*) and
`INSERT_MODE_INDICATORS` (*Insert mode*) variables.
-This settings support Prompt Expansion sequences. For example:
+These settings support Prompt Expansion sequences. For example:
```zsh
MODE_INDICATOR="%F{white}+%f"
@@ -157,6 +157,27 @@ NOTE: delete/kill commands (`dd`, `D`, `c{motion}`, `C`, `x`,`X`) and yank comma
(`y`, `Y`) will copy to the clipboard. Contents can then be put back using paste commands
(`P`, `p`).
+## Text objects
+
+Standard text objects are supported with `i` ("inside") and `a` ("around"), e.g., for words; thus, you can select the word the cursor is in with `viw`, or delete the current word, including surrounding spaces, with `daw`.
+
+For other text objects, you can rely on the built-in functionality of Zsh and enable it accordingly.
+For example, for quoted strings, you can copy the commented snippet of : place this in your `.zsrhc` file, e.g., after sourcing oh-my-zsh:
+
+```sh
+autoload -U select-quoted
+zle -N select-quoted
+for m in visual viopp; do
+ for c in {a,i}{\',\",\`}; do
+ bindkey -M $m $c select-quoted
+ done
+done
+```
+
+Now, in normal mode, you can select everything inside a double-quoted string with `vi"`.
+Note that this works even if you're not already inside a quoted string.
+For example, you can replace everything inside a single-quoted string in the current line, from wherever the cursor is, with `ci'`.
+
## Known issues
### Low `$KEYTIMEOUT`
diff --git a/plugins/volta/volta.plugin.zsh b/plugins/volta/volta.plugin.zsh
index ab05ed5df..173b9c871 100644
--- a/plugins/volta/volta.plugin.zsh
+++ b/plugins/volta/volta.plugin.zsh
@@ -4,7 +4,7 @@ if (( ! $+commands[volta] )); then
fi
# If the completion file doesn't exist yet, we need to autoload it and
-# bind it to `deno`. Otherwise, compinit will have already done that.
+# bind it to `volta`. Otherwise, compinit will have already done that.
if [[ ! -f "$ZSH_CACHE_DIR/completions/_volta" ]]; then
typeset -g -A _comps
autoload -Uz _volta
diff --git a/plugins/wd/README.md b/plugins/wd/README.md
index bf19031f8..1240afe57 100644
--- a/plugins/wd/README.md
+++ b/plugins/wd/README.md
@@ -65,12 +65,9 @@ Add the following to your `home.nix` then run `home-manager switch`:
programs.zsh.plugins = [
{
name = "wd";
- src = pkgs.fetchFromGitHub {
- owner = "mfaerevaag";
- repo = "wd";
- rev = "v0.5.2";
- sha256 = "sha256-4yJ1qhqhNULbQmt6Z9G22gURfDLe30uV1ascbzqgdhg=";
- };
+ src = pkgs.zsh-wd;
+ file = "share/wd/wd.plugin.zsh";
+ completions = [ "share/zsh/site-functions" ];
}
];
```
@@ -115,9 +112,11 @@ wd() {
3. Install manpage (optional):
+Move manpage into an appropriate directory, then trigger `mandb` to discover it
+
```zsh
-sudo cp ~/.local/wd/wd.1 /usr/share/man/man1/wd.1
-sudo chmod 644 /usr/share/man/man1/wd.1
+sudo install -m 644 ~/.local/wd/wd.1 /usr/share/man/man1/wd.1
+sudo mandb /usr/share/man/man1
```
**Note:** when pulling and updating `wd`, you'll need to repeat step 3 should the manpage change
@@ -139,10 +138,11 @@ rm -f ~/.zcompdump; compinit
## Browse
-If you want to make use of the `fzf`-powered browse feature to fuzzy search through all your warp points, set up a keybind in your `.zshrc`:
+`wd` comes with an `fzf`-powered browse feature to fuzzy search through all your warp points. It's available through the `wd browse` command. For quick access you can set up an alias or keybind in your `.zshrc`:
```zsh
-bindkey ${FZF_WD_BINDKEY:-'^B'} fuzzy_wd_widget
+# ctrl-b to open the fzf browser
+bindkey ${FZF_WD_BINDKEY:-'^B'} wd_browse_widget
```
## Usage
@@ -255,12 +255,6 @@ wd --version
wd --config ./file
```
-* Force `exit` with return code after running. This is not default, as it will *exit your terminal*, though required for testing/debugging.
-
-```zsh
-wd --debug
-```
-
* Silence all output:
```zsh
diff --git a/plugins/wd/_wd.sh b/plugins/wd/_wd.sh
index 46b032f78..7c416086d 100644
--- a/plugins/wd/_wd.sh
+++ b/plugins/wd/_wd.sh
@@ -37,6 +37,7 @@ function _wd() {
'rm:Removes the given warp point'
'list:Outputs all stored warp points'
'ls:Show files from given warp point'
+ 'open:Open warp point in the default file explorer'
'path:Show path to given warp point'
'show:Outputs all warp points that point to the current directory or shows a specific target directory for a point'
'help:Show this extremely helpful text'
@@ -73,6 +74,9 @@ function _wd() {
ls)
_describe -t points "Warp points" warp_points && ret=0
;;
+ open)
+ _describe -t points "Warp points" warp_points && ret=0
+ ;;
path)
_describe -t points "Warp points" warp_points && ret=0
;;
diff --git a/plugins/wd/wd.plugin.zsh b/plugins/wd/wd.plugin.zsh
index 9910cb968..2397e6f31 100644
--- a/plugins/wd/wd.plugin.zsh
+++ b/plugins/wd/wd.plugin.zsh
@@ -1,4 +1,4 @@
-#!/bin/zsh
+#!/usr/bin/env zsh
# WARP DIRECTORY
# ==============
@@ -18,4 +18,3 @@ zle -N wd_browse_widget
zle -N wd_restore_buffer
autoload -Uz add-zle-hook-widget
add-zle-hook-widget line-init wd_restore_buffer
-bindkey ${FZF_WD_BINDKEY:-'^B'} wd_browse_widget
diff --git a/plugins/wd/wd.sh b/plugins/wd/wd.sh
index 34f887a0e..56c029252 100755
--- a/plugins/wd/wd.sh
+++ b/plugins/wd/wd.sh
@@ -1,4 +1,4 @@
-#!/bin/zsh
+#!/usr/bin/env zsh
# WARP DIRECTORY
# ==============
@@ -8,7 +8,7 @@
# @github.com/mfaerevaag/wd
# version
-readonly WD_VERSION=0.7.0
+readonly WD_VERSION=0.10.1
# colors
readonly WD_BLUE="\033[96m"
@@ -59,7 +59,7 @@ wd_print_msg()
then
local color="${1:-$WD_BLUE}" # Default to blue if no color is provided
local msg="$2"
-
+
if [[ -z "$msg" ]]; then
print "${WD_RED}*${WD_NOC} Could not print message. Sorry!"
else
@@ -86,11 +86,11 @@ Commands:
show Print warp points to current directory
list Print all stored warp points
ls Show files from given warp point (ls)
+ open Open the warp point in the default file explorer (open / xdg-open)
path Show the path to given warp point (pwd)
clean Remove points warping to nonexistent directories (will prompt unless --force is used)
-v | --version Print version
- -d | --debug Exit after execution with exit codes (for testing)
-c | --config Specify config file (default ~/.warprc)
-q | --quiet Suppress all output
-f | --force Allows overwriting without warning (for add & clean)
@@ -146,14 +146,17 @@ wd_warp()
else
(( n = $#1 - 1 ))
cd -$n > /dev/null
+ WD_EXIT_CODE=$?
fi
elif [[ ${points[$point]} != "" ]]
then
if [[ $sub != "" ]]
then
cd ${points[$point]/#\~/$HOME}/$sub
+ WD_EXIT_CODE=$?
else
cd ${points[$point]/#\~/$HOME}
+ WD_EXIT_CODE=$?
fi
else
wd_exit_fail "Unknown warp point '${point}'"
@@ -171,6 +174,11 @@ wd_add()
point=$(basename "$PWD")
fi
+ if [ ! -w "$wd_config_file" ]; then
+ wd_exit_fail "\'$wd_config_file\' is not writeable."
+ return
+ fi
+
if [[ $point =~ "^[\.]+$" ]]
then
wd_exit_fail "Warp point cannot be just dots"
@@ -186,11 +194,11 @@ wd_add()
elif [[ ${points[$point]} == "" ]] || [ ! -z "$force" ]
then
wd_remove "$point" > /dev/null
- printf "%q:%s\n" "${point}" "${PWD/#$HOME/~}" >> "$WD_CONFIG"
+ printf "%q:%s\n" "${point}" "${PWD/#$HOME/~}" >> "$wd_config_file"
if (whence sort >/dev/null); then
local config_tmp=$(mktemp "${TMPDIR:-/tmp}/wd.XXXXXXXXXX")
- # use 'cat' below to ensure we respect $WD_CONFIG as a symlink
- command sort -o "${config_tmp}" "$WD_CONFIG" && command cat "${config_tmp}" >| "$WD_CONFIG" && command rm "${config_tmp}"
+ # use 'cat' below to ensure we respect $wd_config_file as a symlink
+ command sort -o "${config_tmp}" "$wd_config_file" && command cat "${config_tmp}" >| "$wd_config_file" && command rm "${config_tmp}"
fi
wd_export_static_named_directories
@@ -236,12 +244,17 @@ wd_remove()
point_list=$(basename "$PWD")
fi
+ if [ ! -w "$wd_config_file" ]; then
+ wd_exit_fail "\'$wd_config_file\' is not writeable."
+ return
+ fi
+
for point_name in $point_list ; do
if [[ ${points[$point_name]} != "" ]]
then
local config_tmp=$(mktemp "${TMPDIR:-/tmp}/wd.XXXXXXXXXX")
# Copy and delete in two steps in order to preserve symlinks
- if sed -n "/^${point_name}:.*$/!p" "$WD_CONFIG" >| "$config_tmp" && command cp "$config_tmp" "$WD_CONFIG" && command rm "$config_tmp"
+ if sed -n "/^${point_name}:.*$/!p" "$wd_config_file" >| "$config_tmp" && command cp "$config_tmp" "$wd_config_file" && command rm "$config_tmp"
then
wd_print_msg "$WD_GREEN" "Warp point removed"
else
@@ -254,20 +267,47 @@ wd_remove()
}
wd_browse() {
+ # Check if fzf is installed
if ! command -v fzf >/dev/null; then
- echo "This functionality requires fzf. Please install fzf first."
+ wd_print_msg "$WD_RED" "This functionality requires fzf. Please install fzf first."
return 1
fi
- local entries=("${(@f)$(sed "s:${HOME}:~:g" "$WD_CONFIG" | awk -F ':' '{print $1 " -> " $2}')}")
+
+ # Ensure wd_config_file is properly set
+ if [[ -z $wd_config_file ]]; then
+ wd_config_file="${WD_CONFIG:-$HOME/.warprc}"
+ fi
+
+ # Check if config file exists
+ if [[ ! -f $wd_config_file ]]; then
+ wd_print_msg "$WD_RED" "Config file $wd_config_file does not exist. Please create it first."
+ return 1
+ fi
+
+ # Read entries from the config file
+ local entries=("${(@f)$(sed "s:${HOME}:~:g" "$wd_config_file" | awk -F ':' '{print $1 " -> " $2}')}")
+ if [[ -z $entries ]]; then
+ wd_print_msg "$WD_YELLOW" "You don't have any warp points to browse"
+ return 1
+ fi
+
+ # Temp file for remove operations
local script_path="${${(%):-%x}:h}"
local wd_remove_output=$(mktemp "${TMPDIR:-/tmp}/wd.XXXXXXXXXX")
+
+ # Create fzf bindings
entries=("All warp points:" "Press enter to select. Press delete to remove" "${entries[@]}")
- local fzf_bind="delete:execute(echo {} | awk -F ' -> ' '{print \$1}' | xargs -I {} "$script_path/wd.sh" rm {} > "$wd_remove_output")+abort"
+ local fzf_bind="delete:execute(echo {} | awk -F ' -> ' '{print \$1}' | xargs -I {} \"$script_path/wd.sh\" rm {} > \"$wd_remove_output\")+abort"
+
+ # Run fzf
local selected_entry=$(printf '%s\n' "${entries[@]}" | fzf --height 100% --reverse --header-lines=2 --bind="$fzf_bind")
+
+ # Handle selection
if [[ -e $wd_remove_output ]]; then
cat "$wd_remove_output"
- rm "$wd_remove_output"
+ rm -f "$wd_remove_output"
fi
+
if [[ -n $selected_entry ]]; then
local selected_point="${selected_entry%% ->*}"
selected_point=$(echo "$selected_point" | xargs)
@@ -276,14 +316,26 @@ wd_browse() {
}
wd_browse_widget() {
- if [[ -e $WD_CONFIG ]]; then
+ # Ensure wd_config_file is properly set
+ if [[ -z $wd_config_file ]]; then
+ wd_config_file="${WD_CONFIG:-$HOME/.warprc}"
+ fi
+
+ # Check if config file exists
+ if [[ ! -f $wd_config_file ]]; then
+ wd_print_msg "$WD_RED" "Config file $wd_config_file does not exist. Please create it first."
+ return 1
+ fi
+
+ # Call wd_browse to handle the selection
wd_browse
+
+ # Restore the zsh buffer and cursor after running wd_browse
saved_buffer=$BUFFER
saved_cursor=$CURSOR
BUFFER=
zle redisplay
zle accept-line
- fi
}
wd_restore_buffer() {
@@ -299,7 +351,7 @@ wd_list_all()
{
wd_print_msg "$WD_BLUE" "All warp points:"
- entries=$(sed "s:${HOME}:~:g" "$WD_CONFIG")
+ entries=$(sed "s:${HOME}:~:g" "$wd_config_file")
max_warp_point_length=0
while IFS= read -r line
@@ -336,6 +388,21 @@ wd_ls()
ls "${dir/#\~/$HOME}"
}
+wd_open()
+{
+ wd_getdir "$1"
+ if command -v open >/dev/null 2>&1; then
+ # MacOS, Ubuntu (alias)
+ open "${dir/#\~/$HOME}"
+ elif command -v xdg-open >/dev/null 2>&1; then
+ # Most Linux desktops
+ xdg-open "${dir/#\~/$HOME}"
+ else
+ echo "No known file opener found (need 'open' or 'xdg-open')." >&2
+ exit 1
+ fi
+}
+
wd_path()
{
wd_getdir "$1"
@@ -345,6 +412,7 @@ wd_path()
wd_show()
{
local name_arg=$1
+ local show_pwd
# if there's an argument we look up the value
if [[ -n $name_arg ]]
then
@@ -359,12 +427,12 @@ wd_show()
local wd_matches
wd_matches=()
# do a reverse lookup to check whether PWD is in $points
- PWD="${PWD/$HOME/~}"
- if [[ ${points[(r)$PWD]} == "$PWD" ]]
+ show_pwd="${PWD/$HOME/~}"
+ if [[ ${points[(r)$show_pwd]} == "$show_pwd" ]]
then
for name in ${(k)points}
do
- if [[ $points[$name] == "$PWD" ]]
+ if [[ $points[$name] == "$show_pwd" ]]
then
wd_matches[$(($#wd_matches+1))]=$name
fi
@@ -372,7 +440,7 @@ wd_show()
wd_print_msg "$WD_BLUE" "$#wd_matches warp point(s) to current directory: ${WD_GREEN}$wd_matches${WD_NOC}"
else
- wd_print_msg "$WD_YELLOW" "No warp point to $(echo "$PWD" | sed "s:$HOME:~:")"
+ wd_print_msg "$WD_YELLOW" "No warp point to $show_pwd"
fi
fi
}
@@ -382,6 +450,11 @@ wd_clean() {
local count=0
local wd_tmp=""
+ if [ ! -w "$wd_config_file" ]; then
+ wd_exit_fail "\'$wd_config_file\' is not writeable."
+ return
+ fi
+
while read -r line
do
if [[ $line != "" ]]
@@ -398,7 +471,7 @@ wd_clean() {
count=$((count+1))
fi
fi
- done < "$WD_CONFIG"
+ done < "$wd_config_file"
if [[ $count -eq 0 ]]
then
@@ -406,7 +479,7 @@ wd_clean() {
else
if [ ! -z "$force" ] || wd_yesorno "Removing ${count} warp points. Continue? (y/n)"
then
- echo "$wd_tmp" >! "$WD_CONFIG"
+ echo "$wd_tmp" >! "$wd_config_file"
wd_print_msg "$WD_GREEN" "Cleanup complete. ${count} warp point(s) removed"
else
wd_print_msg "$WD_BLUE" "Cleanup aborted"
@@ -417,7 +490,7 @@ wd_clean() {
wd_export_static_named_directories() {
if [[ ! -z $WD_EXPORT ]]
then
- command grep '^[0-9a-zA-Z_-]\+:' "$WD_CONFIG" | sed -e "s,~,$HOME," -e 's/:/=/' | while read -r warpdir ; do
+ command grep '^[0-9a-zA-Z_-]\+:' "$wd_config_file" | sed -e "s,~,$HOME," -e 's/:/=/' | while read -r warpdir ; do
hash -d "$warpdir"
done
fi
@@ -426,7 +499,6 @@ wd_export_static_named_directories() {
WD_CONFIG=${WD_CONFIG:-$HOME/.warprc}
local WD_QUIET=0
local WD_EXIT_CODE=0
-local WD_DEBUG=0
# Parse 'meta' options first to avoid the need to have them before
# other commands. The `-D` flag consumes recognized options so that
@@ -436,7 +508,6 @@ zparseopts -D -E \
c:=wd_alt_config -config:=wd_alt_config \
q=wd_quiet_mode -quiet=wd_quiet_mode \
v=wd_print_version -version=wd_print_version \
- d=wd_debug_mode -debug=wd_debug_mode \
f=wd_force_mode -force=wd_force_mode
if [[ ! -z $wd_print_version ]]
@@ -444,16 +515,19 @@ then
echo "wd version $WD_VERSION"
fi
+# set the config file from variable or default
+typeset wd_config_file=${WD_CONFIG:-$HOME/.warprc}
if [[ ! -z $wd_alt_config ]]
then
- WD_CONFIG=$wd_alt_config[2]
+ # prefer the flag if provided
+ wd_config_file=$wd_alt_config[2]
fi
# check if config file exists
-if [ ! -e "$WD_CONFIG" ]
+if [ ! -e "$wd_config_file" ]
then
# if not, create config file
- touch "$WD_CONFIG"
+ touch "$wd_config_file"
else
wd_export_static_named_directories
fi
@@ -475,23 +549,15 @@ do
val=${(j,:,)arr[2,-1]}
points[$key]=$val
-done < "$WD_CONFIG"
+done < "$wd_config_file"
# get opts
-args=$(getopt -o a:r:c:lhs -l add:,rm:,clean,list,ls:,path:,help,show -- $*)
+args=$(getopt -o a:r:c:lhs -l add:,rm:,clean,list,ls:,open:,path:,help,show -- $*)
# check if no arguments were given, and that version is not set
if [[ ($? -ne 0 || $#* -eq 0) && -z $wd_print_version ]]
then
wd_print_usage
-
-# check if config file is writeable
-elif [ ! -w "$WD_CONFIG" ]
-then
- # do nothing
- # can't run `exit`, as this would exit the executing shell
- wd_exit_fail "\'$WD_CONFIG\' is not writeable."
-
else
# parse rest of options
local wd_o
@@ -528,6 +594,10 @@ else
wd_ls "$2"
break
;;
+ "-o"|"--open"|"open")
+ wd_open "$2"
+ break
+ ;;
"-p"|"--path"|"path")
wd_path "$2"
break
@@ -574,8 +644,10 @@ unset wd_print_msg
unset wd_yesorno
unset wd_print_usage
unset wd_alt_config
+#unset wd_config_file do not unset this - breaks keybind
unset wd_quiet_mode
unset wd_print_version
+unset wd_force_mode
unset wd_export_static_named_directories
unset wd_o
@@ -583,9 +655,4 @@ unset args
unset points
unset val &> /dev/null # fixes issue #1
-if [[ -n $wd_debug_mode ]]
-then
- exit $WD_EXIT_CODE
-else
- unset wd_debug_mode
-fi
+return $WD_EXIT_CODE
diff --git a/plugins/web-search/README.md b/plugins/web-search/README.md
index d21c81ca9..bc017a1f1 100644
--- a/plugins/web-search/README.md
+++ b/plugins/web-search/README.md
@@ -47,19 +47,25 @@ Available search contexts are:
| `youtube` | `https://www.youtube.com/results?search_query=` |
| `deepl` | `https://www.deepl.com/translator#auto/auto/` |
| `dockerhub` | `https://hub.docker.com/search?q=` |
+| `gems` | `https://rubygems.org/search?query=` |
| `npmpkg` | `https://www.npmjs.com/search?q=` |
| `packagist` | `https://packagist.org/?query=` |
| `gopkg` | `https://pkg.go.dev/search?m=package&q=` |
+| `chatgpt` | `https://chatgpt.com/?q=` |
+| `claudeai` | `https://claude.ai/new?q=` |
+| `grok` | `https://grok.com/?q=` |
+| `reddit` | `https://www.reddit.com/search/?q=` |
+| `ppai` | `https://www.perplexity.ai/search/new?q=` |
Also there are aliases for bang-searching DuckDuckGo:
-| Context | Bang |
-| --------- | ----- |
-| `wiki` | `!w` |
-| `news` | `!n` |
-| `map` | `!m` |
-| `image` | `!i` |
-| `ducky` | `!` |
+| Context | Bang |
+| ------- | ---- |
+| `wiki` | `!w` |
+| `news` | `!n` |
+| `map` | `!m` |
+| `image` | `!i` |
+| `ducky` | `!` |
### Custom search engines
diff --git a/plugins/web-search/web-search.plugin.zsh b/plugins/web-search/web-search.plugin.zsh
index c602e0623..93237f4e2 100644
--- a/plugins/web-search/web-search.plugin.zsh
+++ b/plugins/web-search/web-search.plugin.zsh
@@ -28,9 +28,17 @@ function web_search() {
youtube "https://www.youtube.com/results?search_query="
deepl "https://www.deepl.com/translator#auto/auto/"
dockerhub "https://hub.docker.com/search?q="
+ gems "https://rubygems.org/search?query="
npmpkg "https://www.npmjs.com/search?q="
packagist "https://packagist.org/?query="
gopkg "https://pkg.go.dev/search?m=package&q="
+ chatgpt "https://chatgpt.com/?q="
+ grok "https://grok.com/?q="
+ claudeai "https://claude.ai/new?q="
+ reddit "https://www.reddit.com/search/?q="
+ ppai "https://www.perplexity.ai/search/new?q="
+ rscrate "https://crates.io/search?q="
+ rsdoc "https://docs.rs/releases/search?query="
)
# check whether the search engine is supported
@@ -48,7 +56,7 @@ function web_search() {
# build search url:
# join arguments passed with '+', then append to search engine URL
- url="${urls[$1]}$(omz_urlencode $param ${@[2,-1]})"
+ url="${urls[$1]}$(omz_urlencode $param ${(s: :)@[2,-1]})"
else
# build main page url:
# split by '/', then rejoin protocol (1) and domain (2) parts with '//'
@@ -80,9 +88,17 @@ alias ask='web_search ask'
alias youtube='web_search youtube'
alias deepl='web_search deepl'
alias dockerhub='web_search dockerhub'
+alias gems='web_search gems'
alias npmpkg='web_search npmpkg'
alias packagist='web_search packagist'
alias gopkg='web_search gopkg'
+alias chatgpt='web_search chatgpt'
+alias grok='web_search grok'
+alias claudeai='web_search claudeai'
+alias reddit='web_search reddit'
+alias ppai='web_search ppai'
+alias rscrate='web_search rscrate'
+alias rsdoc='web_search rsdoc'
#add your own !bang searches here
alias wiki='web_search duckduckgo \!w'
@@ -100,3 +116,4 @@ if [[ ${#ZSH_WEB_SEARCH_ENGINES} -gt 0 ]]; then
done
unset engines key
fi
+
diff --git a/plugins/z/LICENSE b/plugins/z/LICENSE
index 6af13b9e0..b36aeb408 100644
--- a/plugins/z/LICENSE
+++ b/plugins/z/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2018-2023 Alexandros Kozak
+Copyright (c) 2018-2025 Alexandros Kozak
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/plugins/z/MANUAL.md b/plugins/z/MANUAL.md
index 106d8c107..eddf787dd 100644
--- a/plugins/z/MANUAL.md
+++ b/plugins/z/MANUAL.md
@@ -6,15 +6,15 @@

-Zsh-z is a command line tool that allows you to jump quickly to directories that you have visited frequently in the past, or recently -- but most often a combination of the two (a concept known as ["frecency"](https://en.wikipedia.org/wiki/Frecency)). It works by keeping track of when you go to directories and how much time you spend in them. It is then in the position to guess where you want to go when you type a partial string, e.g., `z src` might take you to `~/src/zsh`. `z zsh` might also get you there, and `z c/z` might prove to be even more specific -- it all depends on your habits and how much time you have been using Zsh-z to build up a database. After using Zsh-z for a little while, you will get to where you want to be by typing considerably less than you would need if you were using `cd`.
+Zsh-z is a command-line tool that allows you to jump quickly to directories that you have visited frequently or recently -- but most often a combination of the two (a concept known as ["frecency"](https://en.wikipedia.org/wiki/Frecency)). It works by keeping track of when you go to directories and how much time you spend in them. Based on this data, it predicts where you want to go when you type a partial string. For example, `z src` might take you to `~/src/zsh`. `z zsh` might also get you there, and `z c/z` might prove to be even more specific -- it all depends on your habits and how long you have been using Zsh-z to build up a database. After using Zsh-z for a little while, you will get to where you want to be by typing considerably less than you would need to if you were using `cd`.
-Zsh-z is a native Zsh port of [rupa/z](https://github.com/rupa/z), a tool written for `bash` and Zsh that uses embedded `awk` scripts to do the heavy lifting. It was quite possibly my most used command line tool for a couple of years. I decided to translate it, `awk` parts and all, into pure Zsh script, to see if by eliminating calls to external tools (`awk`, `sort`, `date`, `sed`, `mv`, `rm`, and `chown`) and reducing forking through subshells I could make it faster. The performance increase is impressive, particularly on systems where forking is slow, such as Cygwin, MSYS2, and WSL. I have found that, in those environments, switching directories using Zsh-z can be over 100% faster than it is using `rupa/z`.
+Zsh-z is a native Zsh port of [`rupa/z`](https://github.com/rupa/z), a tool written for `bash` and Zsh that uses embedded `awk` scripts to do the heavy lifting. `rupa/z` was my most used command-line tool for a couple of years. I decided to translate it, `awk` parts and all, into pure Zsh script, to see if by eliminating calls to external tools (`awk`, `sort`, `date`, `sed`, `mv`, `rm`, and `chown`) and reducing forking through subshells I could make it faster. The performance increase is impressive, particularly on systems where forking is slow, such as Cygwin, MSYS2, and WSL. I have found that in those environments, switching directories using Zsh-z can be over 100% faster than it is using `rupa/z`.
-There is a noteworthy stability increase as well. Race conditions have always been a problem with `rupa/z`, and users of that utility will occasionally lose their `.z` databases. By having Zsh-z only use Zsh (`rupa/z` uses a hybrid shell code that works on `bash` as well), I have been able to implement a `zsh/system`-based file-locking mechanism similar to [the one @mafredri once proposed for `rupa/z`](https://github.com/rupa/z/pull/199). It is now nearly impossible to crash the database, even through extreme testing.
+There is also a significant stability improvement. Race conditions have always been a problem with `rupa/z`, and users of that utility occasionally lose their `~/.z` databases. By having Zsh-z only use Zsh (`rupa/z` uses a hybrid shell code standard that works on `bash` as well), I have been able to implement a `zsh/system`-based file-locking mechanism similar to [the one @mafredri once proposed for `rupa/z`](https://github.com/rupa/z/pull/199). It is now nearly impossible to crash the database.
-There are other, smaller improvements which I try to document in [Improvements and Fixes](#improvements-and-fixes). These include the new default behavior of sorting your tab completions by frecency rather than just letting Zsh sort the raw results alphabetically (a behavior which can be restored if you like it -- [see below](#settings)).
+There are other, smaller improvements which I document below in [Improvements and Fixes](#improvements-and-fixes). For instance, tab completions are now sorted by frecency by default rather than alphabetically (the latter behavior can be restored if you like it -- [see below](#settings)).
-Zsh-z is a drop-in replacement for `rupa/z` and will, by default, use the same database (`~/.z`), so you can go on using `rupa/z` when you launch `bash`.
+Zsh-z is a drop-in replacement for `rupa/z` and will, by default, use the same database (`~/.z`, or whatever database file you specify), so you can go on using `rupa/z` when you launch `bash`.
## Table of Contents
- [News](#news)
@@ -37,13 +37,13 @@ Zsh-z is a drop-in replacement for `rupa/z` and will, by default, use the same d
- August 24, 2023
+ Zsh-z will now run when `setopt NO_UNSET` has been enabled (props @ntninja).
- August 23, 2023
- + Better logic for loading `zsh/files` (props @z0rc)
+ + Better logic for loading `zsh/files` (props @z0rc).
- August 2, 2023
- + Zsh-z still uses the `zsh/files` module when possible, but will fall back on the standard `chown`, `mv`, and `rm` commands in its absence.
+ + Zsh-z still uses the `zsh/files` module when possible but will fall back on the standard `chown`, `mv`, and `rm` commands in its absence.
- April 27, 2023
+ Zsh-z now allows the user to specify the directory-changing command using the `ZSHZ_CD` environment variable (default: `builtin cd`; props @basnijholt).
- January 27, 2023
- + If the datafile directory specified by `ZSHZ_DATA` or `_Z_DATA` does not already exist, create it (props @mattmc3).
+ + If the database file directory specified by `ZSHZ_DATA` or `_Z_DATA` does not already exist, create it (props @mattmc3).
- June 29, 2022
+ Zsh-z is less likely to leave temporary files sitting around (props @mafredri).
- June 27, 2022
@@ -69,7 +69,7 @@ Zsh-z is a drop-in replacement for `rupa/z` and will, by default, use the same d
+ Fixed the explanation string printed during completion so that it may be formatted with `zstyle`.
+ Zsh-z now declares `ZSHZ_EXCLUDE_DIRS` as an array with unique elements so that you do not have to.
- July 29, 2021
- + Temporarily disabling use of `print -v`, which seems to be mangling CJK multibyte strings.
+ + Temporarily disabling the use of `print -v`, which was mangling CJK multibyte strings.
- July 27, 2021
+ Internal escaping of path names now works with older versions of ZSH.
+ Zsh-z now detects and discards any incomplete or incorrectly formatted database entries.
@@ -102,7 +102,7 @@ Zsh-z is a drop-in replacement for `rupa/z` and will, by default, use the same d
- December 22, 2020
+ `ZSHZ_CASE`: when set to `ignore`, pattern matching is case-insensitive; when set to `smart`, patterns are matched case-insensitively when they are all lowercase and case-sensitively when they have uppercase characters in them (a behavior very much like Vim's `smartcase` setting).
+ `ZSHZ_KEEP_DIRS` is an array of directory names that should not be removed from the database, even if they are not currently available (useful when a drive is not always mounted).
- + Symlinked datafiles were having their symlinks overwritten; this bug has been fixed.
+ + Symlinked database files were having their symlinks overwritten; this bug has been fixed.
@@ -118,7 +118,7 @@ For tab completion to work, `_zshz` *must* be in the same directory as `zsh-z.pl
autoload -U compinit; compinit
-in your .zshrc somewhere below where you source `zsh-z.plugin.zsh`.
+in your `.zshrc` somewhere below where you source `zsh-z.plugin.zsh`.
If you add
@@ -188,7 +188,7 @@ Add a backslash to the end of the last line add `'zsh-z'` to the list, e.g.,
Then relaunch `zsh`.
### For [zcomet](https://github.com/agkozak/zcomet) users
-
+
Simply add
zcomet load agkozak/zsh-z
@@ -228,7 +228,7 @@ Add the line
to your `.zshrc`.
-`zsh-z` supports `zinit`'s `unload` feature; just run `zinit unload agkozak/zshz` to restore the shell to its state before `zsh-z` was loaded.
+Zsh-z supports `zinit`'s `unload` feature; just run `zinit unload agkozak/zsh-z` to restore the shell to its state before Zsh-z was loaded.
### For [Znap](https://github.com/marlonrichert/zsh-snap) users
@@ -249,7 +249,7 @@ somewhere above the line that says `zplug load`. Then run
zplug install
zplug load
-to install `zsh-z`.
+to install Zsh-z.
## Command Line Options
@@ -263,9 +263,9 @@ to install `zsh-z`.
- `-x` Remove a directory (by default, the current directory) from the database
- `-xR` Remove a directory (by default, the current directory) and its subdirectories from the database
-# Settings
+## Settings
-Zsh-z has environment variables (they all begin with `ZSHZ_`) that change its behavior if you set them; you can also keep your old ones if you have been using `rupa/z` (they begin with `_Z_`).
+Zsh-z has environment variables (they all begin with `ZSHZ_`) that change its behavior if you set them. You can also keep your old ones if you have been using `rupa/z` (whose environment variables begin with `_Z_`).
* `ZSHZ_CMD` changes the command name (default: `z`)
* `ZSHZ_CD` specifies the default directory-changing command (default: `builtin cd`)
@@ -324,19 +324,18 @@ A good example might involve a directory tree that has Git repositories within i
(As a Zsh user, I tend to use `**` instead of `find`, but it is good to see how deep your directory trees go before doing that.)
-
## Other Improvements and Fixes
* `z -x` works, with the help of `chpwd_functions`.
-* Zsh-z works on Solaris.
+* Zsh-z is compatible with Solaris.
* Zsh-z uses the "new" `zshcompsys` completion system instead of the old `compctl` one.
-* There is no error message when the database file has not yet been created.
-* There is support for special characters (e.g., `[`) in directory names.
-* If `z -l` only returns one match, a common root is not printed.
-* Exit status codes increasingly make sense.
-* Completions work with options `-c`, `-r`, and `-t`.
-* If `~/foo` and `~/foob` are matches, `~/foo` is *not* the common root. Only a common parent directory can be a common root.
-* `z -x` and the new, recursive `z -xR` can take an argument so that you can remove directories other than `PWD` from the database.
+* No error message is displayed when the database file has not yet been created.
+* Special characters (e.g., `[`) in directory names are now supported.
+* If `z -l` returns only one match, a common root is not printed.
+* Exit status codes are more logical.
+* Completions now work with options `-c`, `-r`, and `-t`.
+* If `~/foo` and `~/foob` are matches, `~/foo` is no longer considered the common root. Only a common parent directory can be a common root.
+* `z -x` and the new, recursive `z -xR` can now accept an argument so that you can remove directories other than `PWD` from the database.
## Migrating from Other Tools
@@ -358,7 +357,7 @@ the line
That will re-bind `z` or the command of your choice to the underlying Zsh-z function.
-## Known Bugs
+## Known Bug
It is possible to run a completion on a string with spaces in it, e.g., `z us bi` might take you to `/usr/local/bin`. This works, but as things stand, after the completion the command line reads
z us /usr/local/bin.
diff --git a/plugins/z/z.plugin.zsh b/plugins/z/z.plugin.zsh
index a41a4ae25..39b832292 100644
--- a/plugins/z/z.plugin.zsh
+++ b/plugins/z/z.plugin.zsh
@@ -4,7 +4,7 @@
#
# https://github.com/agkozak/zsh-z
#
-# Copyright (c) 2018-2023 Alexandros Kozak
+# Copyright (c) 2018-2025 Alexandros Kozak
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -120,7 +120,6 @@ fi
[[ ${builtins[zf_mv]-} == 'defined' ]] && ZSHZ[MV]='zf_mv'
[[ ${builtins[zf_rm]-} == 'defined' ]] && ZSHZ[RM]='zf_rm'
-
# Load zsh/system, if necessary
[[ ${modules[zsh/system]-} == 'loaded' ]] || zmodload zsh/system &> /dev/null
@@ -295,7 +294,16 @@ zshz() {
owner=${ZSHZ_OWNER:-${_Z_OWNER}}
if (( ZSHZ[USE_FLOCK] )); then
- ${ZSHZ[MV]} "$tempfile" "$datafile" 2> /dev/null || ${ZSHZ[RM]} -f "$tempfile"
+ # An unsual case: if inside Docker container where datafile could be bind
+ # mounted
+ if [[ -r '/proc/1/cgroup' && "$(< '/proc/1/cgroup')" == *docker* ]]; then
+ print "$(< "$tempfile")" > "$datafile" 2> /dev/null
+ ${ZSHZ[RM]} -f "$tempfile"
+ # All other cases
+ else
+ ${ZSHZ[MV]} "$tempfile" "$datafile" 2> /dev/null ||
+ ${ZSHZ[RM]} -f "$tempfile"
+ fi
if [[ -n $owner ]]; then
${ZSHZ[CHOWN]} ${owner}:"$(id -ng ${owner})" "$datafile"
diff --git a/plugins/zsh-navigation-tools/README.md b/plugins/zsh-navigation-tools/README.md
index 4dc9cdba2..6d6c22f4f 100644
--- a/plugins/zsh-navigation-tools/README.md
+++ b/plugins/zsh-navigation-tools/README.md
@@ -185,7 +185,7 @@ Result is stored as `$reply[REPLY]` (`$` isn't needed before `REPLY` because
of arithmetic context inside `[]`). The returned array might be different from
input arguments as `n-list` can process them via incremental search or uniq
mode. `$REPLY` is the index in that possibly processed array. If `$REPLY`
-equals `-1` it means that no selection have been made (user quitted via `q`
+equals `-1` it means that no selection have been made (user quit via `q`
key).
To set up entries that can be jumped to with `[`,`]` keys add their indices to
diff --git a/plugins/zsh-navigation-tools/doc/n-preview b/plugins/zsh-navigation-tools/doc/n-preview
index 2d8eea3fb..bcbbb88c7 100644
--- a/plugins/zsh-navigation-tools/doc/n-preview
+++ b/plugins/zsh-navigation-tools/doc/n-preview
@@ -170,7 +170,7 @@ while (( 1 )); do
elif [ -n "$keypad" ]; then
final_key="$keypad"
else
- _vpreview_status_msg "Inproper input detected"
+ _vpreview_status_msg "Improper input detected"
zcurses refresh status
fi
diff --git a/templates/minimal.zshrc b/templates/minimal.zshrc
new file mode 100644
index 000000000..6d4cd9a71
--- /dev/null
+++ b/templates/minimal.zshrc
@@ -0,0 +1,5 @@
+export ZSH="$HOME/.oh-my-zsh"
+ZSH_THEME="robbyrussell"
+plugins=(git)
+
+source $ZSH/oh-my-zsh.sh
diff --git a/templates/zshrc.zsh-template b/templates/zshrc.zsh-template
index 930015798..fa83cc0c6 100644
--- a/templates/zshrc.zsh-template
+++ b/templates/zshrc.zsh-template
@@ -2,7 +2,7 @@
# export PATH=$HOME/bin:$HOME/.local/bin:/usr/local/bin:$PATH
# Path to your Oh My Zsh installation.
-export ZSH=$HOME/.oh-my-zsh
+export ZSH="$HOME/.oh-my-zsh"
# Set name of the theme to load --- if set to "random", it will
# load a random theme each time Oh My Zsh is loaded, in which case,
@@ -85,7 +85,7 @@ source $ZSH/oh-my-zsh.sh
# if [[ -n $SSH_CONNECTION ]]; then
# export EDITOR='vim'
# else
-# export EDITOR='mvim'
+# export EDITOR='nvim'
# fi
# Compilation flags
diff --git a/themes/af-magic.zsh-theme b/themes/af-magic.zsh-theme
index 70549d01f..f47d37340 100644
--- a/themes/af-magic.zsh-theme
+++ b/themes/af-magic.zsh-theme
@@ -13,6 +13,8 @@ function afmagic_dashes {
# the prompt, account for it when returning the number of dashes
if [[ -n "$python_env" && "$PS1" = *\(${python_env}\)* ]]; then
echo $(( COLUMNS - ${#python_env} - 3 ))
+ elif [[ -n "$VIRTUAL_ENV_PROMPT" && "$PS1" = *${VIRTUAL_ENV_PROMPT}* ]]; then
+ echo $(( COLUMNS - ${#VIRTUAL_ENV_PROMPT} - 3 ))
else
echo $COLUMNS
fi
diff --git a/themes/agnoster.zsh-theme b/themes/agnoster.zsh-theme
index c2a542163..63452378d 100644
--- a/themes/agnoster.zsh-theme
+++ b/themes/agnoster.zsh-theme
@@ -35,10 +35,74 @@
CURRENT_BG='NONE'
case ${SOLARIZED_THEME:-dark} in
- light) CURRENT_FG='white';;
- *) CURRENT_FG='black';;
+ light)
+ CURRENT_FG=${CURRENT_FG:-'white'}
+ CURRENT_DEFAULT_FG=${CURRENT_DEFAULT_FG:-'white'}
+ ;;
+ *)
+ CURRENT_FG=${CURRENT_FG:-'black'}
+ CURRENT_DEFAULT_FG=${CURRENT_DEFAULT_FG:-'default'}
+ ;;
esac
+### Theme Configuration Initialization
+#
+# Override these settings in your ~/.zshrc
+
+# Current working directory
+: ${AGNOSTER_DIR_FG:=${CURRENT_FG}}
+: ${AGNOSTER_DIR_BG:=blue}
+
+# user@host
+: ${AGNOSTER_CONTEXT_FG:=${CURRENT_DEFAULT_FG}}
+: ${AGNOSTER_CONTEXT_BG:=black}
+
+# Git related
+: ${AGNOSTER_GIT_CLEAN_FG:=${CURRENT_FG}}
+: ${AGNOSTER_GIT_CLEAN_BG:=green}
+: ${AGNOSTER_GIT_DIRTY_FG:=black}
+: ${AGNOSTER_GIT_DIRTY_BG:=yellow}
+
+# Bazaar related
+: ${AGNOSTER_BZR_CLEAN_FG:=${CURRENT_FG}}
+: ${AGNOSTER_BZR_CLEAN_BG:=green}
+: ${AGNOSTER_BZR_DIRTY_FG:=black}
+: ${AGNOSTER_BZR_DIRTY_BG:=yellow}
+
+# Mercurial related
+: ${AGNOSTER_HG_NEWFILE_FG:=white}
+: ${AGNOSTER_HG_NEWFILE_BG:=red}
+: ${AGNOSTER_HG_CHANGED_FG:=black}
+: ${AGNOSTER_HG_CHANGED_BG:=yellow}
+: ${AGNOSTER_HG_CLEAN_FG:=${CURRENT_FG}}
+: ${AGNOSTER_HG_CLEAN_BG:=green}
+
+# VirtualEnv colors
+: ${AGNOSTER_VENV_FG:=black}
+: ${AGNOSTER_VENV_BG:=blue}
+
+# AWS Profile colors
+: ${AGNOSTER_AWS_PROD_FG:=yellow}
+: ${AGNOSTER_AWS_PROD_BG:=red}
+: ${AGNOSTER_AWS_FG:=black}
+: ${AGNOSTER_AWS_BG:=green}
+
+# Status symbols
+: ${AGNOSTER_STATUS_RETVAL_FG:=red}
+: ${AGNOSTER_STATUS_ROOT_FG:=yellow}
+: ${AGNOSTER_STATUS_JOB_FG:=cyan}
+: ${AGNOSTER_STATUS_FG:=${CURRENT_DEFAULT_FG}}
+: ${AGNOSTER_STATUS_BG:=black}
+
+## Non-Color settings - set to 'true' to enable
+# Show the actual numeric return value rather than a cross symbol.
+: ${AGNOSTER_STATUS_RETVAL_NUMERIC:=false}
+# Show git working dir in the style "/git/root master relative/dir" instead of "/git/root/relative/dir master"
+: ${AGNOSTER_GIT_INLINE:=false}
+# Show the git branch status in the prompt rather than the generic branch symbol
+: ${AGNOSTER_GIT_BRANCH_STATUS:=true}
+
+
# Special Powerline characters
() {
@@ -83,16 +147,36 @@ prompt_end() {
CURRENT_BG=''
}
+git_toplevel() {
+ local repo_root=$(git rev-parse --show-toplevel)
+ if [[ $repo_root = '' ]]; then
+ # We are in a bare repo. Use git dir as root
+ repo_root=$(git rev-parse --git-dir)
+ if [[ $repo_root = '.' ]]; then
+ repo_root=$PWD
+ fi
+ fi
+ echo -n $repo_root
+}
+
### Prompt components
# Each component will draw itself, and hide itself if no information needs to be shown
# Context: user@hostname (who am I and where am I)
prompt_context() {
if [[ "$USERNAME" != "$DEFAULT_USER" || -n "$SSH_CLIENT" ]]; then
- prompt_segment black default "%(!.%{%F{yellow}%}.)%n@%m"
+ prompt_segment "$AGNOSTER_CONTEXT_BG" "$AGNOSTER_CONTEXT_FG" "%(!.%{%F{$AGNOSTER_STATUS_ROOT_FG}%}.)%n@%m"
fi
}
+prompt_git_relative() {
+ local repo_root=$(git_toplevel)
+ local path_in_repo=$(pwd | sed "s/^$(echo "$repo_root" | sed 's:/:\\/:g;s/\$/\\$/g')//;s:^/::;s:/$::;")
+ if [[ $path_in_repo != '' ]]; then
+ prompt_segment "$AGNOSTER_DIR_BG" "$AGNOSTER_DIR_FG" "$path_in_repo"
+ fi;
+}
+
# Git: branch/detached head, dirty status
prompt_git() {
(( $+commands[git] )) || return
@@ -113,20 +197,22 @@ prompt_git() {
ref="◈ $(command git describe --exact-match --tags HEAD 2> /dev/null)" || \
ref="➦ $(command git rev-parse --short HEAD 2> /dev/null)"
if [[ -n $dirty ]]; then
- prompt_segment yellow black
+ prompt_segment "$AGNOSTER_GIT_DIRTY_BG" "$AGNOSTER_GIT_DIRTY_FG"
else
- prompt_segment green $CURRENT_FG
+ prompt_segment "$AGNOSTER_GIT_CLEAN_BG" "$AGNOSTER_GIT_CLEAN_FG"
fi
- local ahead behind
- ahead=$(command git log --oneline @{upstream}.. 2>/dev/null)
- behind=$(command git log --oneline ..@{upstream} 2>/dev/null)
- if [[ -n "$ahead" ]] && [[ -n "$behind" ]]; then
- PL_BRANCH_CHAR=$'\u21c5'
- elif [[ -n "$ahead" ]]; then
- PL_BRANCH_CHAR=$'\u21b1'
- elif [[ -n "$behind" ]]; then
- PL_BRANCH_CHAR=$'\u21b0'
+ if [[ $AGNOSTER_GIT_BRANCH_STATUS == 'true' ]]; then
+ local ahead behind
+ ahead=$(command git log --oneline @{upstream}.. 2>/dev/null)
+ behind=$(command git log --oneline ..@{upstream} 2>/dev/null)
+ if [[ -n "$ahead" ]] && [[ -n "$behind" ]]; then
+ PL_BRANCH_CHAR=$'\u21c5'
+ elif [[ -n "$ahead" ]]; then
+ PL_BRANCH_CHAR=$'\u21b1'
+ elif [[ -n "$behind" ]]; then
+ PL_BRANCH_CHAR=$'\u21b0'
+ fi
fi
if [[ -e "${repo_path}/BISECT_LOG" ]]; then
@@ -149,6 +235,7 @@ prompt_git() {
zstyle ':vcs_info:*' actionformats ' %u%c'
vcs_info
echo -n "${${ref:gs/%/%%}/refs\/heads\//$PL_BRANCH_CHAR }${vcs_info_msg_0_%% }${mode}"
+ [[ $AGNOSTER_GIT_INLINE == 'true' ]] && prompt_git_relative
fi
}
@@ -168,12 +255,12 @@ prompt_bzr() {
status_all=$(echo -n "$bzr_status" | head -n1 | wc -m)
revision=${$(command bzr log -r-1 --log-format line | cut -d: -f1):gs/%/%%}
if [[ $status_mod -gt 0 ]] ; then
- prompt_segment yellow black "bzr@$revision ✚"
+ prompt_segment "$AGNOSTER_BZR_DIRTY_BG" "$AGNOSTER_BZR_DIRTY_FG" "bzr@$revision ✚"
else
if [[ $status_all -gt 0 ]] ; then
- prompt_segment yellow black "bzr@$revision"
+ prompt_segment "$AGNOSTER_BZR_DIRTY_BG" "$AGNOSTER_BZR_DIRTY_FG" "bzr@$revision"
else
- prompt_segment green black "bzr@$revision"
+ prompt_segment "$AGNOSTER_BZR_CLEAN_BG" "$AGNOSTER_BZR_CLEAN_FG" "bzr@$revision"
fi
fi
fi
@@ -186,15 +273,15 @@ prompt_hg() {
if $(command hg prompt >/dev/null 2>&1); then
if [[ $(command hg prompt "{status|unknown}") = "?" ]]; then
# if files are not added
- prompt_segment red white
+ prompt_segment "$AGNOSTER_HG_NEWFILE_BG" "$AGNOSTER_HG_NEWFILE_FG"
st='±'
elif [[ -n $(command hg prompt "{status|modified}") ]]; then
# if any modification
- prompt_segment yellow black
+ prompt_segment "$AGNOSTER_HG_CHANGED_BG" "$AGNOSTER_HG_CHANGED_FG"
st='±'
else
# if working copy is clean
- prompt_segment green $CURRENT_FG
+ prompt_segment "$AGNOSTER_HG_CLEAN_BG" "$AGNOSTER_HG_CLEAN_FG"
fi
echo -n ${$(command hg prompt "☿ {rev}@{branch}"):gs/%/%%} $st
else
@@ -202,13 +289,13 @@ prompt_hg() {
rev=$(command hg id -n 2>/dev/null | sed 's/[^-0-9]//g')
branch=$(command hg id -b 2>/dev/null)
if command hg st | command grep -q "^\?"; then
- prompt_segment red black
+ prompt_segment "$AGNOSTER_HG_NEWFILE_BG" "$AGNOSTER_HG_NEWFILE_FG"
st='±'
elif command hg st | command grep -q "^[MA]"; then
- prompt_segment yellow black
+ prompt_segment "$AGNOSTER_HG_CHANGED_BG" "$AGNOSTER_HG_CHANGED_FG"
st='±'
else
- prompt_segment green $CURRENT_FG
+ prompt_segment "$AGNOSTER_HG_CLEAN_BG" "$AGNOSTER_HG_CLEAN_FG"
fi
echo -n "☿ ${rev:gs/%/%%}@${branch:gs/%/%%}" $st
fi
@@ -217,13 +304,21 @@ prompt_hg() {
# Dir: current working directory
prompt_dir() {
- prompt_segment blue $CURRENT_FG '%~'
+ if [[ $AGNOSTER_GIT_INLINE == 'true' ]] && $(git rev-parse --is-inside-work-tree >/dev/null 2>&1); then
+ # Git repo and inline path enabled, hence only show the git root
+ prompt_segment "$AGNOSTER_DIR_BG" "$AGNOSTER_DIR_FG" "$(git_toplevel | sed "s:^$HOME:~:")"
+ else
+ prompt_segment "$AGNOSTER_DIR_BG" "$AGNOSTER_DIR_FG" '%~'
+ fi
}
# Virtualenv: current working virtualenv
prompt_virtualenv() {
+ if [ -n "$CONDA_DEFAULT_ENV" ]; then
+ prompt_segment magenta $CURRENT_FG "🐍 $CONDA_DEFAULT_ENV"
+ fi
if [[ -n "$VIRTUAL_ENV" && -n "$VIRTUAL_ENV_DISABLE_PROMPT" ]]; then
- prompt_segment blue black "(${VIRTUAL_ENV:t:gs/%/%%})"
+ prompt_segment "$AGNOSTER_VENV_BG" "$AGNOSTER_VENV_FG" "(${VIRTUAL_ENV:t:gs/%/%%})"
fi
}
@@ -234,11 +329,15 @@ prompt_virtualenv() {
prompt_status() {
local -a symbols
- [[ $RETVAL -ne 0 ]] && symbols+="%{%F{red}%}✘"
- [[ $UID -eq 0 ]] && symbols+="%{%F{yellow}%}⚡"
- [[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{cyan}%}⚙"
+ if [[ $AGNOSTER_STATUS_RETVAL_NUMERIC == 'true' ]]; then
+ [[ $RETVAL -ne 0 ]] && symbols+="%{%F{$AGNOSTER_STATUS_RETVAL_FG}%}$RETVAL"
+ else
+ [[ $RETVAL -ne 0 ]] && symbols+="%{%F{$AGNOSTER_STATUS_RETVAL_FG}%}✘"
+ fi
+ [[ $UID -eq 0 ]] && symbols+="%{%F{$AGNOSTER_STATUS_ROOT_FG}%}⚡"
+ [[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{$AGNOSTER_STATUS_JOB_FG}%}⚙"
- [[ -n "$symbols" ]] && prompt_segment black default "$symbols"
+ [[ -n "$symbols" ]] && prompt_segment "$AGNOSTER_STATUS_BG" "$AGNOSTER_STATUS_FG" "$symbols"
}
#AWS Profile:
@@ -249,17 +348,24 @@ prompt_status() {
prompt_aws() {
[[ -z "$AWS_PROFILE" || "$SHOW_AWS_PROMPT" = false ]] && return
case "$AWS_PROFILE" in
- *-prod|*production*) prompt_segment red yellow "AWS: ${AWS_PROFILE:gs/%/%%}" ;;
- *) prompt_segment green black "AWS: ${AWS_PROFILE:gs/%/%%}" ;;
+ *-prod|*production*) prompt_segment "$AGNOSTER_AWS_PROD_BG" "$AGNOSTER_AWS_PROD_FG" "AWS: ${AWS_PROFILE:gs/%/%%}" ;;
+ *) prompt_segment "$AGNOSTER_AWS_BG" "$AGNOSTER_AWS_FG" "AWS: ${AWS_PROFILE:gs/%/%%}" ;;
esac
}
+prompt_terraform() {
+ local terraform_info=$(tf_prompt_info)
+ [[ -z "$terraform_info" ]] && return
+ prompt_segment magenta yellow "TF: $terraform_info"
+}
+
## Main prompt
build_prompt() {
RETVAL=$?
prompt_status
prompt_virtualenv
prompt_aws
+ prompt_terraform
prompt_context
prompt_dir
prompt_git
diff --git a/themes/aussiegeek.zsh-theme b/themes/aussiegeek.zsh-theme
index 2ded5c157..9ea6662b6 100644
--- a/themes/aussiegeek.zsh-theme
+++ b/themes/aussiegeek.zsh-theme
@@ -1,8 +1,8 @@
+PROMPT="%{${fg_bold[blue]}%}[ %{${fg[red]}%}%t %{${fg_bold[blue]}%}] %{${fg_bold[blue]}%} [ %{${fg[red]}%}%n@%m:%~\$(git_prompt_info)%{${fg[yellow]}%}\$(ruby_prompt_info)%{${fg_bold[blue]}%} ]%{$reset_color%}
+ $ "
-PROMPT='$fg_bold[blue][ $fg[red]%t $fg_bold[blue]] $fg_bold[blue] [ $fg[red]%n@%m:%~$(git_prompt_info)$fg[yellow]$(ruby_prompt_info)$fg_bold[blue] ]$reset_color
- $ '
# git theming
-ZSH_THEME_GIT_PROMPT_PREFIX="$fg_bold[green]("
-ZSH_THEME_GIT_PROMPT_SUFFIX=")"
+ZSH_THEME_GIT_PROMPT_PREFIX="%{${fg_bold[green]}%}("
+ZSH_THEME_GIT_PROMPT_SUFFIX=")%{$reset_color%}"
ZSH_THEME_GIT_PROMPT_CLEAN="✔"
ZSH_THEME_GIT_PROMPT_DIRTY="✗"
diff --git a/themes/awesomepanda.zsh-theme b/themes/awesomepanda.zsh-theme
index 000697397..85036e4ac 100644
--- a/themes/awesomepanda.zsh-theme
+++ b/themes/awesomepanda.zsh-theme
@@ -1,6 +1,6 @@
# the svn plugin has to be activated for this to work.
local ret_status="%(?:%{$fg_bold[green]%}➜ :%{$fg_bold[red]%}➜ %s)"
-PROMPT='%{${ret_status}%}%{$fg_bold[green]%} %{$fg[cyan]%}%c %{$fg_bold[blue]%}$(git_prompt_info)%{$fg_bold[blue]%}$(svn_prompt_info)%{$reset_color%}'
+PROMPT='${ret_status}%{$fg_bold[green]%} %{$fg[cyan]%}%c %{$fg_bold[blue]%}$(git_prompt_info)%{$fg_bold[blue]%}$(svn_prompt_info)%{$reset_color%}'
ZSH_THEME_GIT_PROMPT_PREFIX="git:(%{$fg[red]%}"
ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
diff --git a/themes/blinks.zsh-theme b/themes/blinks.zsh-theme
index ddb32f7c3..736683c9a 100644
--- a/themes/blinks.zsh-theme
+++ b/themes/blinks.zsh-theme
@@ -11,11 +11,11 @@ function _prompt_char() {
# This theme works with both the "dark" and "light" variants of the
# Solarized color schema. Set the SOLARIZED_THEME variable to one of
# these two values to choose. If you don't specify, we'll assume you're
-# using the "dark" variant.
+# using neither variant.
case ${SOLARIZED_THEME:-dark} in
light) bkg=white;;
- *) bkg=black;;
+ *) bkg=default;;
esac
ZSH_THEME_GIT_PROMPT_PREFIX=" [%{%B%F{blue}%}"
diff --git a/themes/gnzh.zsh-theme b/themes/gnzh.zsh-theme
index ca62320e2..0297a6f6f 100644
--- a/themes/gnzh.zsh-theme
+++ b/themes/gnzh.zsh-theme
@@ -30,8 +30,9 @@ local return_code="%(?..%F{red}%? ↵%f)"
local user_host="${PR_USER}%F{cyan}@${PR_HOST}"
local current_dir="%B%F{blue}%~%f%b"
local git_branch='$(git_prompt_info)'
+local venv_prompt='$(virtualenv_prompt_info)'
-PROMPT="╭─${user_host} ${current_dir} \$(ruby_prompt_info) ${git_branch}
+PROMPT="╭─${venv_prompt}${user_host} ${current_dir} \$(ruby_prompt_info) ${git_branch}
╰─$PR_PROMPT "
RPROMPT="${return_code}"
@@ -39,5 +40,7 @@ ZSH_THEME_GIT_PROMPT_PREFIX="%F{yellow}‹"
ZSH_THEME_GIT_PROMPT_SUFFIX="› %f"
ZSH_THEME_RUBY_PROMPT_PREFIX="%F{red}‹"
ZSH_THEME_RUBY_PROMPT_SUFFIX="›%f"
+ZSH_THEME_VIRTUALENV_PREFIX="%F{red}("
+ZSH_THEME_VIRTUALENV_SUFFIX=")%f "
}
diff --git a/themes/jonathan.zsh-theme b/themes/jonathan.zsh-theme
index e8c490884..5185ebf77 100644
--- a/themes/jonathan.zsh-theme
+++ b/themes/jonathan.zsh-theme
@@ -7,14 +7,16 @@ function theme_precmd {
local promptsize=${#${(%):---(%n@%m:%l)---()--}}
local rubypromptsize=${#${(%)$(ruby_prompt_info)}}
local pwdsize=${#${(%):-%~}}
+ local venvpromptsize=$((${#$(virtualenv_prompt_info)}))
+ local condapromptsize=$((${#$(conda_prompt_info)}))
# Truncate the path if it's too long.
- if (( promptsize + rubypromptsize + pwdsize > TERMWIDTH )); then
+ if (( promptsize + rubypromptsize + pwdsize + venvpromptsize + condapromptsize > TERMWIDTH )); then
(( PR_PWDLEN = TERMWIDTH - promptsize ))
elif [[ "${langinfo[CODESET]}" = UTF-8 ]]; then
- PR_FILLBAR="\${(l:$(( TERMWIDTH - (promptsize + rubypromptsize + pwdsize) ))::${PR_HBAR}:)}"
+ PR_FILLBAR="\${(l:$(( TERMWIDTH - (promptsize + rubypromptsize + pwdsize + venvpromptsize + condapromptsize ) ))::${PR_HBAR}:)}"
else
- PR_FILLBAR="${PR_SHIFT_IN}\${(l:$(( TERMWIDTH - (promptsize + rubypromptsize + pwdsize) ))::${altchar[q]:--}:)}${PR_SHIFT_OUT}"
+ PR_FILLBAR="${PR_SHIFT_IN}\${(l:$(( TERMWIDTH - (promptsize + rubypromptsize + pwdsize + venvpromptsize + condapromptsize ) ))::${altchar[q]:--}:)}${PR_SHIFT_OUT}"
fi
}
@@ -103,7 +105,7 @@ fi
PROMPT='${PR_SET_CHARSET}${PR_STITLE}${(e)PR_TITLEBAR}\
${PR_CYAN}${PR_ULCORNER}${PR_HBAR}${PR_GREY}(\
${PR_GREEN}%${PR_PWDLEN}<...<%~%<<\
-${PR_GREY})$(ruby_prompt_info)${PR_CYAN}${PR_HBAR}${PR_HBAR}${(e)PR_FILLBAR}${PR_HBAR}${PR_GREY}(\
+${PR_GREY})$(virtualenv_prompt_info)$(ruby_prompt_info)$(conda_prompt_info)${PR_CYAN}${PR_HBAR}${PR_HBAR}${(e)PR_FILLBAR}${PR_HBAR}${PR_GREY}(\
${PR_CYAN}%(!.%SROOT%s.%n)${PR_GREY}@${PR_GREEN}%m:%l\
${PR_GREY})${PR_CYAN}${PR_HBAR}${PR_URCORNER}\
diff --git a/themes/nicoulaj.zsh-theme b/themes/nicoulaj.zsh-theme
old mode 100644
new mode 100755
index 685cd1ade..6435c3833
--- a/themes/nicoulaj.zsh-theme
+++ b/themes/nicoulaj.zsh-theme
@@ -12,12 +12,12 @@
# ------------------------------------------------------------------------------
# Customizable parameters.
-PROMPT_PATH_MAX_LENGTH=30
-PROMPT_DEFAULT_END=❯
-PROMPT_ROOT_END=❯❯❯
-PROMPT_SUCCESS_COLOR=$FG[071]
-PROMPT_FAILURE_COLOR=$FG[124]
-PROMPT_VCS_INFO_COLOR=$FG[242]
+PROMPT_PATH_MAX_LENGTH=${PROMPT_PATH_MAX_LENGTH:-30}
+PROMPT_DEFAULT_END=${PROMPT_DEFAULT_END:-❯}
+PROMPT_ROOT_END=${PROMPT_ROOT_END:-❯❯❯}
+PROMPT_SUCCESS_COLOR=${PROMPT_SUCCESS_COLOR:-$FG[071]}
+PROMPT_FAILURE_COLOR=${PROMPT_FAILURE_COLOR:-$FG[124]}
+PROMPT_VCS_INFO_COLOR=${PROMPT_VCS_INFO_COLOR:-$FG[242]}
# Set required options.
setopt promptsubst
diff --git a/themes/sonicradish.zsh-theme b/themes/sonicradish.zsh-theme
index db6170969..11d66a27e 100644
--- a/themes/sonicradish.zsh-theme
+++ b/themes/sonicradish.zsh-theme
@@ -29,7 +29,7 @@ ZSH_THEME_GIT_PROMPT_SUFFIX="%{$GIT_PROMPT_INFO%} :"
ZSH_THEME_GIT_PROMPT_DIRTY=" %{$GIT_DIRTY_COLOR%}✘"
ZSH_THEME_GIT_PROMPT_CLEAN=" %{$GIT_CLEAN_COLOR%}✔"
-ZSH_THEME_GIT_PROMPT_ADDED="%{$FG[103]%}✚%{$rset_color%}"
+ZSH_THEME_GIT_PROMPT_ADDED="%{$FG[103]%}✚%{$reset_color%}"
ZSH_THEME_GIT_PROMPT_MODIFIED="%{$FG[103]%}✹%{$reset_color%}"
ZSH_THEME_GIT_PROMPT_DELETED="%{$FG[103]%}✖%{$reset_color%}"
ZSH_THEME_GIT_PROMPT_RENAMED="%{$FG[103]%}➜%{$reset_color%}"
diff --git a/tools/changelog.sh b/tools/changelog.sh
index c4b26079e..ff409115f 100755
--- a/tools/changelog.sh
+++ b/tools/changelog.sh
@@ -400,6 +400,9 @@ function display-release {
function display:breaking {
(( $#breaking != 0 )) || return 0
+ # If we reach here we have shown commits, set flag
+ shown_commits=1
+
case "$output" in
text) printf '\e[31m'; fmt:header "BREAKING CHANGES" 3 ;;
raw) fmt:header "BREAKING CHANGES" 3 ;;
@@ -427,6 +430,9 @@ function display-release {
# If no commits found of type $type, go to next type
(( $#hashes != 0 )) || return 0
+ # If we reach here we have shown commits, set flag
+ shown_commits=1
+
fmt:header "${TYPES[$type]}" 3
for hash in $hashes; do
echo " - $(fmt:hash) $(fmt:scope)$(fmt:subject)"
@@ -444,6 +450,9 @@ function display-release {
# If no commits found under "other" types, don't display anything
(( $#changes != 0 )) || return 0
+ # If we reach here we have shown commits, set flag
+ shown_commits=1
+
fmt:header "Other changes" 3
for hash type in ${(kv)changes}; do
case "$type" in
@@ -498,7 +507,7 @@ function main {
# Commit classification arrays
local -A types subjects scopes breaking reverts
- local truncate=0 read_commits=0
+ local truncate=0 read_commits=0 shown_commits=0
local version tag
local hash refs subject body
@@ -569,6 +578,10 @@ function main {
echo " ...more commits omitted"
echo
fi
+
+ if (( ! shown_commits )); then
+ echo "No changes to mention."
+ fi
}
# Use raw output if stdout is not a tty
diff --git a/tools/check_for_upgrade.sh b/tools/check_for_upgrade.sh
index 1ecab5c0b..35391ea70 100644
--- a/tools/check_for_upgrade.sh
+++ b/tools/check_for_upgrade.sh
@@ -27,7 +27,7 @@ zstyle -s ':omz:update' mode update_mode || {
# - $ZSH is not a git repository
if [[ "$update_mode" = disabled ]] \
|| [[ ! -w "$ZSH" || ! -O "$ZSH" ]] \
- || [[ ! -t 1 ]] \
+ || [[ ! -t 1 && ${POWERLEVEL9K_INSTANT_PROMPT:-off} == off ]] \
|| ! command git --version 2>&1 >/dev/null \
|| (builtin cd -q "$ZSH"; ! command git rev-parse --is-inside-work-tree &>/dev/null); then
unset update_mode
@@ -112,6 +112,11 @@ function update_ohmyzsh() {
local verbose_mode
zstyle -s ':omz:update' verbose verbose_mode || verbose_mode=default
+ # Force verbose mode to silent if p10k instant prompt is enabled
+ if [[ ${POWERLEVEL9K_INSTANT_PROMPT:-off} != "off" ]]; then
+ verbose_mode=silent
+ fi
+
if [[ "$update_mode" != background-alpha ]] \
&& LANG= ZSH="$ZSH" zsh -f "$ZSH/tools/upgrade.sh" -i -v $verbose_mode; then
update_last_updated_file
diff --git a/tools/install.sh b/tools/install.sh
index e5f126915..5c9b2c18d 100755
--- a/tools/install.sh
+++ b/tools/install.sh
@@ -399,8 +399,8 @@ EOF
"$FMT_YELLOW" "$FMT_RESET"
read -r opt
case $opt in
- y*|Y*|"") ;;
- n*|N*) echo "Shell change skipped."; return ;;
+ [Yy]*|"") ;;
+ [Nn]*) echo "Shell change skipped."; return ;;
*) echo "Invalid choice. Shell change skipped."; return ;;
esac
diff --git a/tools/theme_chooser.sh b/tools/theme_chooser.sh
index 3883f1d37..ab270e8e1 100755
--- a/tools/theme_chooser.sh
+++ b/tools/theme_chooser.sh
@@ -1,4 +1,4 @@
-#!/bin/zsh
+#!/usr/bin/env zsh
# Zsh Theme Chooser by fox (fox91 at anche dot no)
# This program is free software. It comes without any warranty, to
diff --git a/tools/upgrade.sh b/tools/upgrade.sh
index c586610c4..1aa3d8af4 100755
--- a/tools/upgrade.sh
+++ b/tools/upgrade.sh
@@ -254,7 +254,7 @@ if LANG= git pull --quiet --rebase $remote $branch; then
# Print changelog to the terminal
if [[ $interactive == true && $verbose_mode == default ]]; then
- "$ZSH/tools/changelog.sh" HEAD "$last_commit"
+ ZSH="$ZSH" command zsh -f "$ZSH/tools/changelog.sh" HEAD "$last_commit"
fi
if [[ $verbose_mode != silent ]]; then