diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0cb9410fc..6668cd7ce 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,9 +1,9 @@ # Plugin owners plugins/archlinux/ @ratijas -plugins/aws/ @maksyms plugins/genpass/ @atoponce plugins/git-lfs/ @hellovietduc plugins/gitfast/ @felipec +plugins/react-native @esthor plugins/sdk/ @rgoldberg plugins/shell-proxy/ @septs plugins/universalarchive/ @Konfekt diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 1abae8913..5c94caeb5 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -9,6 +9,7 @@ - [ ] The code is mine or it's from somewhere with an MIT-compatible license. - [ ] The code is efficient, to the best of my ability, and does not waste computer resources. - [ ] The code is stable and I have tested it myself, to the best of my abilities. +- [ ] If the code introduces new aliases, I provide a valid use case for all plugin users down below. ## Changes: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 50e00f9c9..8ee2df3d8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,13 +7,16 @@ on: branches: - master push: - branches: + branches: - master concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true +permissions: + contents: read # to fetch code (actions/checkout) + jobs: tests: name: Run tests @@ -24,7 +27,7 @@ jobs: os: [ubuntu-latest, macos-latest] steps: - name: Set up git repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install zsh if: runner.os == 'Linux' run: sudo apt-get update; sudo apt-get install zsh diff --git a/.github/workflows/project.yml b/.github/workflows/project.yml index b2219893d..1d961d8c0 100644 --- a/.github/workflows/project.yml +++ b/.github/workflows/project.yml @@ -9,6 +9,7 @@ concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true +permissions: {} jobs: add-to-project: name: Add to project @@ -26,24 +27,25 @@ jobs: gh api graphql -f query=' query($org: String!, $number: Int!) { organization(login: $org){ - projectNext(number: $number) { + projectV2(number: $number) { id fields(first:20) { nodes { - id - name + ... on ProjectV2Field { + id + name + } } } } } - } - ' -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json + }' -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json # Parse project data cat >> $GITHUB_ENV <> $GITHUB_ENV @@ -107,23 +109,27 @@ jobs: $theme_field: ID! $theme_value: String! ) { - set_plugin: updateProjectNextItemField(input: { + set_plugin: updateProjectV2ItemFieldValue(input: { projectId: $project itemId: $item fieldId: $plugin_field - value: $plugin_value + value: { + text: $plugin_value + } }) { - projectNextItem { + projectV2Item { id } } - set_theme: updateProjectNextItemField(input: { + set_theme: updateProjectV2ItemFieldValue(input: { projectId: $project itemId: $item fieldId: $theme_field - value: $theme_value + value: { + text: $theme_value + } }) { - projectNextItem { + projectV2Item { id } } @@ -132,4 +138,3 @@ jobs: -f plugin_field=$PLUGIN_FIELD_ID -f plugin_value=$PLUGIN \ -f theme_field=$THEME_FIELD_ID -f theme_value=$THEME \ --silent - diff --git a/.gitignore b/.gitignore index ad6800460..5d04a792b 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,7 @@ cache/ log/ *.swp .DS_Store + +# editor configs +.vscode +.idea diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..a8f5a14b0 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +{ + "printWidth": 110, + "proseWrap": "always" +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2bd877892..6c8b8446e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -35,13 +35,13 @@ you would make is not already covered. Please be so kind as to [search](#use-the-search-luke) for any open issue already covering your problem. -If you find one, comment on it so we can know there are more people experiencing it. +If you find one, comment on it, so we know more people are experiencing it. If not, look at the [Troubleshooting](https://github.com/ohmyzsh/ohmyzsh/wiki/Troubleshooting) page for instructions on how to gather data to better debug your problem. Then, you can go ahead and create an issue with as much detail as you can provide. -It should include the data gathered as indicated above, along with: +It should include the data gathered as indicated above, along with the following: 1. How to reproduce the problem 2. What the correct behavior should be @@ -57,7 +57,7 @@ We will do our very best to help you. Please be so kind as to [search](#use-the-search-luke) for any open issue already covering your suggestion. -If you find one, comment on it so we can know there are more people supporting it. +If you find one, comment on it, so we know more people are supporting it. If not, you can go ahead and create an issue. Please copy to anyone relevant (e.g. plugin maintainers) by mentioning their GitHub handle (starting with `@`) in your message. @@ -84,7 +84,7 @@ your [problem](#you-have-a-problem), and any pending/merged/rejected PR covering If the solution is already reported, try it out and +1 the pull request if the solution works ok. On the other hand, if you think your solution is better, post -it with a reference to the other one so we can have both solutions to compare. +it with reference to the other one so we can have both solutions to compare. If not, then go ahead and submit a PR. Please copy to anyone relevant (e.g. plugin maintainers) by mentioning their GitHub handle (starting with `@`) in your message. @@ -104,6 +104,27 @@ maintainers) by mentioning their GitHub handle (starting with `@`) in your messa For any extensive change, such as a new plugin, you will have to find testers to +1 your PR. +### New plugin aliases + +We acknowledge that aliases are a core part of Oh My Zsh. There are plugins that have +100 aliases! + +This has become an issue for two opposing reasons: + +- Some users want to have their personal aliases in Oh My Zsh. +- Some users don't want any aliases at all and feel that there are too many. + +Because of this, from now on, we require that new aliases follow these conditions: + +1. They will be used by many people, not just a few. +2. The aliases will be used many times and for common tasks. +3. Prefer one generic alias over many specific ones. +4. When justifying the need for an alias, talk about workflows where you'll use it, + preferably in combination with other aliases. +5. If a command with the same name exists, look for a different alias name. + +This list is not exhaustive! Please remember that your alias will be in the machines of many people, +so it should be justified why they should have it. + ---- ## Use the Search, Luke @@ -193,7 +214,7 @@ type(scope)!: subject ``` - `subject`: a brief description of the changes. This will be displayed in the changelog. If you need - to specify other details you can use the commit body but it won't be visible. + to specify other details, you can use the commit body, but it won't be visible. Formatting tricks: the commit subject may contain: @@ -210,9 +231,9 @@ type(scope)!: subject ### Style -Try to keep the first commit line short. This is harder to do using this commit style but try to be -concise and if you need more space, you can use the commit body. Try to make sure that the commit -subject is clear and precise enough that users will know what change by just looking at the changelog. +Try to keep the first commit line short. It's harder to do using this commit style but try to be +concise, and if you need more space, you can use the commit body. Try to make sure that the commit +subject is clear and precise enough that users will know what changed by just looking at the changelog. ---- diff --git a/README.md b/README.md index c1e7cc84d..0e9f1b693 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,9 @@ To learn more, visit [ohmyz.sh](https://ohmyz.sh), follow [@ohmyzsh](https://twi - [Manual Installation](#manual-installation) - [Installation Problems](#installation-problems) - [Custom Plugins and Themes](#custom-plugins-and-themes) + - [Skip aliases](#skip-aliases) - [Getting Updates](#getting-updates) + - [Updates verbosity](#updates-verbosity) - [Manual Updates](#manual-updates) - [Uninstalling Oh My Zsh](#uninstalling-oh-my-zsh) - [How do I contribute to Oh My Zsh?](#how-do-i-contribute-to-oh-my-zsh) @@ -303,6 +305,58 @@ 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 same name in the `custom/plugins/` directory and it will be loaded instead of the one in `plugins/`. +### Skip aliases + + + +If you want to skip default Oh My Zsh aliases (those defined in `lib/*` files) or plugin aliases, +you can use the settings below in your `~/.zshrc` file, **before Oh My Zsh is loaded**. Note that +there are many different ways to skip aliases, depending on your needs. + +```sh +# Skip all aliases, in lib files and enabled plugins +zstyle ':omz:*' aliases no + +# Skip all aliases in lib files +zstyle ':omz:lib:*' aliases no +# Skip only aliases defined in the directories.zsh lib file +zstyle ':omz:lib:directories' aliases no + +# Skip all plugin aliases +zstyle ':omz:plugins:*' aliases no +# Skip only the aliases from the git plugin +zstyle ':omz:plugins:git' aliases no +``` + +You can combine these in other ways taking into account that more specific scopes takes precedence: + +```sh +# Skip all plugin aliases, except for the git plugin +zstyle ':omz:plugins:*' aliases no +zstyle ':omz:plugins:git' aliases yes +``` + +A previous version of this feature was using the setting below, which has been removed: + +```sh +zstyle ':omz:directories' aliases no +``` + +Instead, you can now use the following: + +```sh +zstyle ':omz:lib:directories' aliases no +``` + +#### Notice + +> This feature is currently in a testing phase and it may be subject to change in the future. +> It is also not currently compatible with plugin managers such as zpm or zinit, which don't +> source the init script (`oh-my-zsh.sh`) where this feature is implemented in. + +> It is also not currently aware of "aliases" that are defined as functions. Example of such +> are `gccd`, `ggf`, or `ggl` functions from the git plugin. + ## Getting Updates By default, you will be prompted to check for updates every 2 weeks. You can choose other update modes by adding a line to your `~/.zshrc` file, **before Oh My Zsh is loaded**: @@ -334,6 +388,18 @@ zstyle ':omz:update' frequency 7 zstyle ':omz:update' frequency 0 ``` +### Updates verbosity + +You can also limit the update verbosity with the following settings: + +```sh +zstyle ':omz:update' verbose default # default update prompt + +zstyle ':omz:update' verbose minimal # only few lines + +zstyle ':omz:update' verbose silent # only errors +``` + ### Manual Updates If you'd like to update at any point in time (maybe someone just released a new plugin and you don't want to wait a week?) you just need to run: @@ -391,4 +457,4 @@ Oh My Zsh is released under the [MIT license](LICENSE.txt). ![Planet Argon](https://pa-github-assets.s3.amazonaws.com/PARGON_logo_digital_COL-small.jpg) -Oh My Zsh was started by the team at [Planet Argon](https://www.planetargon.com/?utm_source=github), a [Ruby on Rails development agency](https://www.planetargon.com/skills/ruby-on-rails-development?utm_source=github). Check out our [other open source projects](https://www.planetargon.com/open-source?utm_source=github). +Oh My Zsh was started by the team at [Planet Argon](https://www.planetargon.com/?utm_source=github), a [Ruby on Rails development agency](http://www.planetargon.com/services/ruby-on-rails-development?utm_source=github). Check out our [other open source projects](https://www.planetargon.com/open-source?utm_source=github). diff --git a/lib/cli.zsh b/lib/cli.zsh index b71f6d9ce..ba3e39eb5 100644 --- a/lib/cli.zsh +++ b/lib/cli.zsh @@ -241,21 +241,21 @@ function _omz::plugin::disable { # Remove plugins substitution awk script local awk_subst_plugins="\ - gsub(/\s+(${(j:|:)dis_plugins})/, \"\") # with spaces before - gsub(/(${(j:|:)dis_plugins})\s+/, \"\") # with spaces after + gsub(/[ \t]+(${(j:|:)dis_plugins})/, \"\") # with spaces before + gsub(/(${(j:|:)dis_plugins})[ \t]+/, \"\") # with spaces after gsub(/\((${(j:|:)dis_plugins})\)/, \"\") # without spaces (only plugin) " # Disable plugins awk script local awk_script=" # if plugins=() is in oneline form, substitute disabled plugins and go to next line -/^\s*plugins=\([^#]+\).*\$/ { +/^[ \t]*plugins=\([^#]+\).*\$/ { $awk_subst_plugins print \$0 next } # if plugins=() is in multiline form, enable multi flag and disable plugins if they're there -/^\s*plugins=\(/ { +/^[ \t]*plugins=\(/ { multi=1 $awk_subst_plugins print \$0 @@ -280,9 +280,10 @@ multi == 1 && length(\$0) > 0 { " local zdot="${ZDOTDIR:-$HOME}" - awk "$awk_script" "$zdot/.zshrc" > "$zdot/.zshrc.new" \ - && command mv -f "$zdot/.zshrc" "$zdot/.zshrc.bck" \ - && command mv -f "$zdot/.zshrc.new" "$zdot/.zshrc" + local zshrc="${${:-"${zdot}/.zshrc"}:A}" + awk "$awk_script" "$zshrc" > "$zdot/.zshrc.new" \ + && command cp -f "$zshrc" "$zdot/.zshrc.bck" \ + && command mv -f "$zdot/.zshrc.new" "$zshrc" # Exit if the new .zshrc file wasn't created correctly [[ $? -eq 0 ]] || { @@ -294,8 +295,7 @@ multi == 1 && length(\$0) > 0 { # Exit if the new .zshrc file has syntax errors if ! command zsh -n "$zdot/.zshrc"; then _omz::log error "broken syntax in '"${zdot/#$HOME/\~}/.zshrc"'. Rolling back changes..." - command mv -f "$zdot/.zshrc" "$zdot/.zshrc.new" - command mv -f "$zdot/.zshrc.bck" "$zdot/.zshrc" + command mv -f "$zdot/.zshrc.bck" "$zshrc" return 1 fi @@ -330,14 +330,14 @@ function _omz::plugin::enable { # Enable plugins awk script local awk_script=" # if plugins=() is in oneline form, substitute ) with new plugins and go to the next line -/^\s*plugins=\([^#]+\).*\$/ { +/^[ \t]*plugins=\([^#]+\).*\$/ { sub(/\)/, \" $add_plugins&\") print \$0 next } # if plugins=() is in multiline form, enable multi flag -/^\s*plugins=\(/ { +/^[ \t]*plugins=\(/ { multi=1 } @@ -354,9 +354,10 @@ multi == 1 && /^[^#]*\)/ { " local zdot="${ZDOTDIR:-$HOME}" - awk "$awk_script" "$zdot/.zshrc" > "$zdot/.zshrc.new" \ - && command mv -f "$zdot/.zshrc" "$zdot/.zshrc.bck" \ - && command mv -f "$zdot/.zshrc.new" "$zdot/.zshrc" + local zshrc="${${:-"${zdot}/.zshrc"}:A}" + awk "$awk_script" "$zshrc" > "$zdot/.zshrc.new" \ + && command cp -f "$zshrc" "$zdot/.zshrc.bck" \ + && command mv -f "$zdot/.zshrc.new" "$zshrc" # Exit if the new .zshrc file wasn't created correctly [[ $? -eq 0 ]] || { @@ -368,8 +369,7 @@ multi == 1 && /^[^#]*\)/ { # Exit if the new .zshrc file has syntax errors if ! command zsh -n "$zdot/.zshrc"; then _omz::log error "broken syntax in '"${zdot/#$HOME/\~}/.zshrc"'. Rolling back changes..." - command mv -f "$zdot/.zshrc" "$zdot/.zshrc.new" - command mv -f "$zdot/.zshrc.bck" "$zdot/.zshrc" + command mv -f "$zdot/.zshrc.bck" "$zshrc" return 1 fi @@ -416,14 +416,14 @@ function _omz::plugin::list { if (( ${#custom_plugins} )); then print -P "%U%BCustom plugins%b%u:" - print -l ${(q-)custom_plugins} | column -x + print -lac ${(q-)custom_plugins} fi if (( ${#builtin_plugins} )); then (( ${#custom_plugins} )) && echo # add a line of separation print -P "%U%BBuilt-in plugins%b%u:" - print -l ${(q-)builtin_plugins} | column -x + print -lac ${(q-)builtin_plugins} fi } @@ -674,13 +674,13 @@ function _omz::theme::list { # Print custom themes if there are any if (( ${#custom_themes} )); then print -P "%U%BCustom themes%b%u:" - print -l ${(q-)custom_themes} | column -x + print -lac ${(q-)custom_themes} echo fi # Print built-in themes print -P "%U%BBuilt-in themes%b%u:" - print -l ${(q-)builtin_themes} | column -x + print -lac ${(q-)builtin_themes} } function _omz::theme::set { @@ -699,9 +699,9 @@ function _omz::theme::set { # Enable theme in .zshrc local awk_script=' -!set && /^\s*ZSH_THEME=[^#]+.*$/ { +!set && /^[ \t]*ZSH_THEME=[^#]+.*$/ { set=1 - sub(/^\s*ZSH_THEME=[^#]+.*$/, "ZSH_THEME=\"'$1'\" # set by `omz`") + sub(/^[ \t]*ZSH_THEME=[^#]+.*$/, "ZSH_THEME=\"'$1'\" # set by `omz`") print $0 next } @@ -715,7 +715,8 @@ END { ' local zdot="${ZDOTDIR:-$HOME}" - awk "$awk_script" "$zdot/.zshrc" > "$zdot/.zshrc.new" \ + local zshrc="${${:-"${zdot}/.zshrc"}:A}" + awk "$awk_script" "$zshrc" > "$zdot/.zshrc.new" \ || { # Prepend ZSH_THEME= line to .zshrc if it doesn't exist cat < "$zdot/.zshrc.new" \ - && command mv -f "$zdot/.zshrc" "$zdot/.zshrc.bck" \ - && command mv -f "$zdot/.zshrc.new" "$zdot/.zshrc" + && command cp -f "$zshrc" "$zdot/.zshrc.bck" \ + && command mv -f "$zdot/.zshrc.new" "$zshrc" # Exit if the new .zshrc file wasn't created correctly [[ $? -eq 0 ]] || { @@ -737,8 +738,7 @@ EOF # Exit if the new .zshrc file has syntax errors if ! command zsh -n "$zdot/.zshrc"; then _omz::log error "broken syntax in '"${zdot/#$HOME/\~}/.zshrc"'. Rolling back changes..." - command mv -f "$zdot/.zshrc" "$zdot/.zshrc.new" - command mv -f "$zdot/.zshrc.bck" "$zdot/.zshrc" + command mv -f "$zdot/.zshrc.bck" "$zshrc" return 1 fi @@ -776,10 +776,11 @@ function _omz::update { local last_commit=$(builtin cd -q "$ZSH"; git rev-parse HEAD) # Run update script + zstyle -s ':omz:update' verbose verbose_mode || verbose_mode=default if [[ "$1" != --unattended ]]; then - ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" --interactive || return $? + ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" -i -v $verbose_mode || return $? else - ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" || return $? + ZSH="$ZSH" command zsh -f "$ZSH/tools/upgrade.sh" -v $verbose_mode || return $? fi # Update last updated file diff --git a/lib/clipboard.zsh b/lib/clipboard.zsh index 4e3ba0a45..2f3b6bcad 100644 --- a/lib/clipboard.zsh +++ b/lib/clipboard.zsh @@ -10,8 +10,8 @@ # - pbcopy, pbpaste (macOS) # - cygwin (Windows running Cygwin) # - wl-copy, wl-paste (if $WAYLAND_DISPLAY is set) -# - xclip (if $DISPLAY is set) # - xsel (if $DISPLAY is set) +# - xclip (if $DISPLAY is set) # - lemonade (for SSH) https://github.com/pocke/lemonade # - doitclient (for SSH) http://www.chiark.greenend.org.uk/~sgtatham/doit/ # - win32yank (Windows) @@ -52,38 +52,38 @@ function detect-clipboard() { emulate -L zsh if [[ "${OSTYPE}" == darwin* ]] && (( ${+commands[pbcopy]} )) && (( ${+commands[pbpaste]} )); then - function clipcopy() { pbcopy < "${1:-/dev/stdin}"; } + function clipcopy() { cat "${1:-/dev/stdin}" | pbcopy; } function clippaste() { pbpaste; } elif [[ "${OSTYPE}" == (cygwin|msys)* ]]; then function clipcopy() { cat "${1:-/dev/stdin}" > /dev/clipboard; } function clippaste() { cat /dev/clipboard; } + elif (( $+commands[clip.exe] )) && (( $+commands[powershell.exe] )); then + function clipcopy() { cat "${1:-/dev/stdin}" | clip.exe; } + function clippaste() { powershell.exe -noprofile -command Get-Clipboard; } elif [ -n "${WAYLAND_DISPLAY:-}" ] && (( ${+commands[wl-copy]} )) && (( ${+commands[wl-paste]} )); then - function clipcopy() { wl-copy < "${1:-/dev/stdin}"; } + function clipcopy() { cat "${1:-/dev/stdin}" | wl-copy &>/dev/null &|; } function clippaste() { wl-paste; } - elif [ -n "${DISPLAY:-}" ] && (( ${+commands[xclip]} )); then - function clipcopy() { xclip -in -selection clipboard < "${1:-/dev/stdin}"; } - function clippaste() { xclip -out -selection clipboard; } elif [ -n "${DISPLAY:-}" ] && (( ${+commands[xsel]} )); then - function clipcopy() { xsel --clipboard --input < "${1:-/dev/stdin}"; } + function clipcopy() { cat "${1:-/dev/stdin}" | xsel --clipboard --input; } function clippaste() { xsel --clipboard --output; } + elif [ -n "${DISPLAY:-}" ] && (( ${+commands[xclip]} )); then + function clipcopy() { cat "${1:-/dev/stdin}" | xclip -selection clipboard -in &>/dev/null &|; } + function clippaste() { xclip -out -selection clipboard; } elif (( ${+commands[lemonade]} )); then - function clipcopy() { lemonade copy < "${1:-/dev/stdin}"; } + function clipcopy() { cat "${1:-/dev/stdin}" | lemonade copy; } function clippaste() { lemonade paste; } elif (( ${+commands[doitclient]} )); then - function clipcopy() { doitclient wclip < "${1:-/dev/stdin}"; } + function clipcopy() { cat "${1:-/dev/stdin}" | doitclient wclip; } function clippaste() { doitclient wclip -r; } elif (( ${+commands[win32yank]} )); then - function clipcopy() { win32yank -i < "${1:-/dev/stdin}"; } + function clipcopy() { cat "${1:-/dev/stdin}" | win32yank -i; } function clippaste() { win32yank -o; } elif [[ $OSTYPE == linux-android* ]] && (( $+commands[termux-clipboard-set] )); then - function clipcopy() { termux-clipboard-set < "${1:-/dev/stdin}"; } + function clipcopy() { cat "${1:-/dev/stdin}" | termux-clipboard-set; } function clippaste() { termux-clipboard-get; } elif [ -n "${TMUX:-}" ] && (( ${+commands[tmux]} )); then function clipcopy() { tmux load-buffer "${1:--}"; } function clippaste() { tmux save-buffer -; } - elif [[ $(uname -r) = *icrosoft* ]]; then - function clipcopy() { clip.exe < "${1:-/dev/stdin}"; } - function clippaste() { powershell.exe -noprofile -command Get-Clipboard; } else function _retry_clipboard_detection_or_fail() { local clipcmd="${1}"; shift diff --git a/lib/completion.zsh b/lib/completion.zsh index 2c5695487..63379b53f 100644 --- a/lib/completion.zsh +++ b/lib/completion.zsh @@ -18,9 +18,9 @@ if [[ "$CASE_SENSITIVE" = true ]]; then zstyle ':completion:*' matcher-list 'r:|=*' 'l:|=* r:|=*' else if [[ "$HYPHEN_INSENSITIVE" = true ]]; then - zstyle ':completion:*' matcher-list 'm:{a-zA-Z-_}={A-Za-z_-}' 'r:|=*' 'l:|=* r:|=*' + zstyle ':completion:*' matcher-list 'm:{[:lower:][:upper:]-_}={[:upper:][:lower:]_-}' 'r:|=*' 'l:|=* r:|=*' else - zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|=*' 'l:|=* r:|=*' + zstyle ':completion:*' matcher-list 'm:{[:lower:][:upper:]}={[:upper:][:lower:]}' 'r:|=*' 'l:|=* r:|=*' fi fi unset CASE_SENSITIVE HYPHEN_INSENSITIVE diff --git a/lib/correction.zsh b/lib/correction.zsh index 4259d3418..ba9664fcb 100644 --- a/lib/correction.zsh +++ b/lib/correction.zsh @@ -1,13 +1,8 @@ if [[ "$ENABLE_CORRECTION" == "true" ]]; then alias cp='nocorrect cp' - alias ebuild='nocorrect ebuild' - alias gist='nocorrect gist' - alias heroku='nocorrect heroku' - alias hpodder='nocorrect hpodder' alias man='nocorrect man' alias mkdir='nocorrect mkdir' alias mv='nocorrect mv' - alias mysql='nocorrect mysql' alias sudo='nocorrect sudo' alias su='nocorrect su' diff --git a/lib/directories.zsh b/lib/directories.zsh index c62f56468..8927a56ad 100644 --- a/lib/directories.zsh +++ b/lib/directories.zsh @@ -1,8 +1,10 @@ # Changing/making/removing directory +setopt auto_cd setopt auto_pushd setopt pushd_ignore_dups setopt pushdminus + alias -g ...='../..' alias -g ....='../../..' alias -g .....='../../../..' diff --git a/lib/functions.zsh b/lib/functions.zsh index dfcc4d961..1d85ea38a 100644 --- a/lib/functions.zsh +++ b/lib/functions.zsh @@ -30,6 +30,13 @@ function open_command() { ;; esac + # If a URL is passed, $BROWSER might be set to a local browser within SSH. + # See https://github.com/ohmyzsh/ohmyzsh/issues/11098 + if [[ -n "$BROWSER" && "$1" = (http|https)://* ]]; then + "$BROWSER" "$@" + return + fi + ${=open_cmd} "$@" &>/dev/null } @@ -56,7 +63,7 @@ function takegit() { } function take() { - if [[ $1 =~ ^(https?|ftp).*\.tar\.(gz|bz2|xz)$ ]]; then + if [[ $1 =~ ^(https?|ftp).*\.(tar\.(gz|bz2|xz)|tgz)$ ]]; then takeurl "$1" elif [[ $1 =~ ^([A-Za-z0-9]\+@|https?|git|ssh|ftps?|rsync).*\.git/?$ ]]; then takegit "$1" diff --git a/lib/git.zsh b/lib/git.zsh index be9fa7e67..f049f73c2 100644 --- a/lib/git.zsh +++ b/lib/git.zsh @@ -19,6 +19,7 @@ function git_prompt_info() { local ref ref=$(__git_prompt_git symbolic-ref --short HEAD 2> /dev/null) \ + || ref=$(__git_prompt_git describe --tags --exact-match HEAD 2> /dev/null) \ || ref=$(__git_prompt_git rev-parse --short HEAD 2> /dev/null) \ || return 0 diff --git a/lib/grep.zsh b/lib/grep.zsh index a725e0f26..54e0f694e 100644 --- a/lib/grep.zsh +++ b/lib/grep.zsh @@ -24,8 +24,8 @@ else if [[ -n "$GREP_OPTIONS" ]]; then # export grep, egrep and fgrep settings alias grep="grep $GREP_OPTIONS" - alias egrep="egrep $GREP_OPTIONS" - alias fgrep="fgrep $GREP_OPTIONS" + alias egrep="grep -E $GREP_OPTIONS" + alias fgrep="grep -F $GREP_OPTIONS" # write to cache file if cache directory is writable if [[ -w "$ZSH_CACHE_DIR" ]]; then diff --git a/lib/misc.zsh b/lib/misc.zsh index a5d3af998..132f33551 100644 --- a/lib/misc.zsh +++ b/lib/misc.zsh @@ -15,8 +15,9 @@ if [[ $DISABLE_MAGIC_FUNCTIONS != true ]]; then done fi -## jobs -setopt long_list_jobs +setopt multios # enable redirect to multiple streams: echo >file1 >file2 +setopt long_list_jobs # show long list format job notifications +setopt interactivecomments # recognize comments env_default 'PAGER' 'less' env_default 'LESS' '-R' @@ -24,12 +25,9 @@ env_default 'LESS' '-R' ## super user alias alias _='sudo ' -## more intelligent acking for ubuntu users +## more intelligent acking for ubuntu users and no alias for users without ack if (( $+commands[ack-grep] )); then alias afind='ack-grep -il' -else +elif (( $+commands[ack] )); then alias afind='ack -il' fi - -# recognize comments -setopt interactivecomments diff --git a/lib/prompt_info_functions.zsh b/lib/prompt_info_functions.zsh index e5535848b..3dc9b6d10 100644 --- a/lib/prompt_info_functions.zsh +++ b/lib/prompt_info_functions.zsh @@ -18,6 +18,7 @@ function chruby_prompt_info \ vi_mode_prompt_info \ virtualenv_prompt_info \ jenv_prompt_info \ + azure_prompt_info \ tf_prompt_info \ { return 1 diff --git a/lib/termsupport.zsh b/lib/termsupport.zsh index 80ca7ef78..cf8f08741 100644 --- a/lib/termsupport.zsh +++ b/lib/termsupport.zsh @@ -17,7 +17,7 @@ function title { : ${2=$1} case "$TERM" in - cygwin|xterm*|putty*|rxvt*|konsole*|ansi|mlterm*|alacritty|st*|foot) + cygwin|xterm*|putty*|rxvt*|konsole*|ansi|mlterm*|alacritty|st*|foot|contour*) print -Pn "\e]2;${2:q}\a" # set window name print -Pn "\e]1;${1:q}\a" # set tab name ;; @@ -109,28 +109,52 @@ if [[ -z "$INSIDE_EMACS" || "$INSIDE_EMACS" = vterm ]]; then add-zsh-hook preexec omz_termsupport_preexec fi -# Keep Apple Terminal.app's current working directory updated -# Based on this answer: https://superuser.com/a/315029 -# With extra fixes to handle multibyte chars and non-UTF-8 locales +# Keep terminal emulator's current working directory correct, +# even if the current working directory path contains symbolic links +# +# References: +# - Apple's Terminal.app: https://superuser.com/a/315029 +# - iTerm2: https://iterm2.com/documentation-escape-codes.html (iTerm2 Extension / CurrentDir+RemoteHost) +# - Konsole: https://bugs.kde.org/show_bug.cgi?id=327720#c1 +# - libvte (gnome-terminal, mate-terminal, …): https://bugzilla.gnome.org/show_bug.cgi?id=675987#c14 +# Apparently it had a bug before ~2012 were it would display the unknown OSC 7 code +# +# As of May 2021 mlterm, PuTTY, rxvt, screen, termux & xterm simply ignore the unknown OSC. -if [[ "$TERM_PROGRAM" == "Apple_Terminal" ]] && [[ -z "$INSIDE_EMACS" ]]; then - # Emits the control sequence to notify Terminal.app of the cwd - # Identifies the directory using a file: URI scheme, including - # the host name to disambiguate local vs. remote paths. - function update_terminalapp_cwd() { - emulate -L zsh - - # Percent-encode the host and path names. - local URL_HOST URL_PATH - URL_HOST="$(omz_urlencode -P $HOST)" || return 1 - URL_PATH="$(omz_urlencode -P $PWD)" || return 1 - - # Undocumented Terminal.app-specific control sequence - printf '\e]7;%s\a' "file://$URL_HOST$URL_PATH" - } - - # Use a precmd hook instead of a chpwd hook to avoid contaminating output - add-zsh-hook precmd update_terminalapp_cwd - # Run once to get initial cwd set - update_terminalapp_cwd +# Don't define the function if we're inside Emacs +if [[ -n "$INSIDE_EMACS" ]]; then + return fi + +# Don't define the function if we're in an unsupported terminal +case "$TERM" in + # all of these either process OSC 7 correctly or ignore entirely + xterm*|putty*|rxvt*|konsole*|mlterm*|alacritty|screen*|tmux*) ;; + contour*|foot*) ;; + *) + # Terminal.app and iTerm2 process OSC 7 correctly + case "$TERM_PROGRAM" in + Apple_Terminal|iTerm.app) ;; + *) return ;; + esac ;; +esac + +# Emits the control sequence to notify many terminal emulators +# of the cwd +# +# Identifies the directory using a file: URI scheme, including +# the host name to disambiguate local vs. remote paths. +function omz_termsupport_cwd { + # Percent-encode the host and path names. + local URL_HOST URL_PATH + URL_HOST="$(omz_urlencode -P $HOST)" || return 1 + URL_PATH="$(omz_urlencode -P $PWD)" || return 1 + + # common control sequence (OSC 7) to set current host and path + printf "\e]7;%s\a" "file://${URL_HOST}${URL_PATH}" +} + +# Use a precmd hook instead of a chpwd hook to avoid contaminating output +# i.e. when a script or function changes directory without `cd -q`, chpwd +# will be called the output may be swallowed by the script or function. +add-zsh-hook precmd omz_termsupport_cwd diff --git a/lib/theme-and-appearance.zsh b/lib/theme-and-appearance.zsh index 00947f72d..d8859b04c 100644 --- a/lib/theme-and-appearance.zsh +++ b/lib/theme-and-appearance.zsh @@ -1,59 +1,83 @@ -# ls colors +# Sets color variable such as $fg, $bg, $color and $reset_color autoload -U colors && colors -# Enable ls colors -export LSCOLORS="Gxfxcxdxbxegedabagacad" - -# TODO organise this chaotic logic - -if [[ "$DISABLE_LS_COLORS" != "true" ]]; then - # Find the option for using colors in ls, depending on the version - if [[ "$OSTYPE" == netbsd* ]]; then - # On NetBSD, test if "gls" (GNU ls) is installed (this one supports colors); - # otherwise, leave ls as is, because NetBSD's ls doesn't support -G - gls --color -d . &>/dev/null && alias ls='gls --color=tty' - elif [[ "$OSTYPE" == openbsd* ]]; then - # On OpenBSD, "gls" (ls from GNU coreutils) and "colorls" (ls from base, - # with color and multibyte support) are available from ports. "colorls" - # will be installed on purpose and can't be pulled in by installing - # coreutils, so prefer it to "gls". - gls --color -d . &>/dev/null && alias ls='gls --color=tty' - colorls -G -d . &>/dev/null && alias ls='colorls -G' - elif [[ "$OSTYPE" == (darwin|freebsd)* ]]; then - # this is a good alias, it works by default just using $LSCOLORS - ls -G . &>/dev/null && alias ls='ls -G' - - # only use coreutils ls if there is a dircolors customization present ($LS_COLORS or .dircolors file) - # otherwise, gls will use the default color scheme which is ugly af - [[ -n "$LS_COLORS" || -f "$HOME/.dircolors" ]] && gls --color -d . &>/dev/null && alias ls='gls --color=tty' - else - # For GNU ls, we use the default ls color theme. They can later be overwritten by themes. - if [[ -z "$LS_COLORS" ]]; then - (( $+commands[dircolors] )) && eval "$(dircolors -b)" - fi - - ls --color -d . &>/dev/null && alias ls='ls --color=tty' || { ls -G . &>/dev/null && alias ls='ls -G' } - - # Take advantage of $LS_COLORS for completion as well. - zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}" - fi -fi - -# enable diff color if possible. -if command diff --color /dev/null /dev/null &>/dev/null; then - alias diff='diff --color' -fi - -setopt auto_cd -setopt multios +# Expand variables and commands in PROMPT variables setopt prompt_subst -[[ -n "$WINDOW" ]] && SCREEN_NO="%B$WINDOW%b " || SCREEN_NO="" - -# git theming default: Variables for theming the git info prompt -ZSH_THEME_GIT_PROMPT_PREFIX="git:(" # Prefix at the very beginning of the prompt, before the branch name -ZSH_THEME_GIT_PROMPT_SUFFIX=")" # At the very end of the prompt -ZSH_THEME_GIT_PROMPT_DIRTY="*" # Text to display if the branch is dirty -ZSH_THEME_GIT_PROMPT_CLEAN="" # Text to display if the branch is clean +# Prompt function theming defaults +ZSH_THEME_GIT_PROMPT_PREFIX="git:(" # Beginning of the git prompt, before the branch name +ZSH_THEME_GIT_PROMPT_SUFFIX=")" # End of the git prompt +ZSH_THEME_GIT_PROMPT_DIRTY="*" # Text to display if the branch is dirty +ZSH_THEME_GIT_PROMPT_CLEAN="" # Text to display if the branch is clean ZSH_THEME_RUBY_PROMPT_PREFIX="(" ZSH_THEME_RUBY_PROMPT_SUFFIX=")" + + +# Use diff --color if available +if command diff --color /dev/null{,} &>/dev/null; then + function diff { + command diff --color "$@" + } +fi + + +# Don't set ls coloring if disabled +[[ "$DISABLE_LS_COLORS" != true ]] || return 0 + +function test-ls-args { + local cmd="$1" # ls, gls, colorls, ... + local args="${@[2,-1]}" # arguments except the first one + command "$cmd" "$args" /dev/null &>/dev/null +} + +# Find the option for using colors in ls, depending on the version +case "$OSTYPE" in + netbsd*) + # On NetBSD, test if `gls` (GNU ls) is installed (this one supports colors); + # otherwise, leave ls as is, because NetBSD's ls doesn't support -G + test-ls-args gls --color && alias ls='gls --color=tty' + ;; + openbsd*) + # On OpenBSD, `gls` (ls from GNU coreutils) and `colorls` (ls from base, + # with color and multibyte support) are available from ports. + # `colorls` will be installed on purpose and can't be pulled in by installing + # coreutils (which might be installed for ), so prefer it to `gls`. + test-ls-args gls --color && alias ls='gls --color=tty' + test-ls-args colorls -G && alias ls='colorls -G' + ;; + (darwin|freebsd)*) + # This alias works by default just using $LSCOLORS + test-ls-args ls -G && alias ls='ls -G' + # Only use GNU ls if installed and there are user defaults for $LS_COLORS, + # as the default coloring scheme is not very pretty + [[ -n "$LS_COLORS" || -f "$HOME/.dircolors" ]] \ + && test-ls-args gls --color \ + && alias ls='gls --color=tty' + ;; + *) + if test-ls-args ls --color; then + alias ls='ls --color=tty' + elif test-ls-args ls -G; then + alias ls='ls -G' + fi + ;; +esac + +unfunction test-ls-args + + +# Default coloring for BSD-based ls +export LSCOLORS="Gxfxcxdxbxegedabagacad" + +# Default coloring for GNU-based ls +if [[ -z "$LS_COLORS" ]]; then + # Define LS_COLORS via dircolors if available. Otherwise, set a default + # equivalent to LSCOLORS (generated via https://geoff.greer.fm/lscolors) + if (( $+commands[dircolors] )); then + [[ -f "$HOME/.dircolors" ]] \ + && source <(dircolors -b "$HOME/.dircolors") \ + || source <(dircolors -b) + else + export LS_COLORS="di=1;36:ln=35:so=32:pi=33:ex=31:bd=34;46:cd=34;43:su=30;41:sg=30;46:tw=30;42:ow=30;43" + fi +fi diff --git a/lib/vcs_info.zsh b/lib/vcs_info.zsh index e60938c14..be6d32ee9 100644 --- a/lib/vcs_info.zsh +++ b/lib/vcs_info.zsh @@ -38,7 +38,7 @@ # due to malicious input as a consequence of CVE-2021-45444, which affects # zsh versions from 5.0.3 to 5.8. # -autoload -Uz +X regexp-replace VCS_INFO_formats 2>/dev/null || return +autoload -Uz +X regexp-replace VCS_INFO_formats 2>/dev/null || return 0 # We use $tmp here because it's already a local variable in VCS_INFO_formats typeset PATCH='for tmp (base base-name branch misc revision subdir) hook_com[$tmp]="${hook_com[$tmp]//\%/%%}"' diff --git a/oh-my-zsh.sh b/oh-my-zsh.sh index 925ee46aa..e047d4834 100644 --- a/oh-my-zsh.sh +++ b/oh-my-zsh.sh @@ -57,9 +57,7 @@ mkdir -p "$ZSH_CACHE_DIR/completions" (( ${fpath[(Ie)"$ZSH_CACHE_DIR/completions"]} )) || fpath=("$ZSH_CACHE_DIR/completions" $fpath) # Check for updates on initial load... -if [[ "$DISABLE_AUTO_UPDATE" != true ]]; then - source "$ZSH/tools/check_for_upgrade.sh" -fi +source "$ZSH/tools/check_for_upgrade.sh" # Initializes Oh My Zsh @@ -67,7 +65,7 @@ fi fpath=("$ZSH/functions" "$ZSH/completions" $fpath) # Load all stock functions (from $fpath files) called below. -autoload -U compaudit compinit +autoload -U compaudit compinit zrecompile # Set ZSH_CUSTOM to the path where your custom config files # and plugins exists, or else we will use the default custom/ @@ -142,22 +140,57 @@ EOF fi unset zcompdump_revision zcompdump_fpath zcompdump_refresh +# zcompile the completion dump file if the .zwc is older or missing. +if command mkdir "${ZSH_COMPDUMP}.lock" 2>/dev/null; then + zrecompile -q -p "$ZSH_COMPDUMP" + command rm -rf "$ZSH_COMPDUMP.zwc.old" "${ZSH_COMPDUMP}.lock" +fi + +_omz_source() { + local context filepath="$1" + + # Construct zstyle context based on path + case "$filepath" in + lib/*) context="lib:${filepath:t:r}" ;; # :t = lib_name.zsh, :r = lib_name + plugins/*) context="plugins:${filepath:h:t}" ;; # :h = plugins/plugin_name, :t = plugin_name + esac + + local disable_aliases=0 + zstyle -T ":omz:${context}" aliases || disable_aliases=1 + + # Back up alias names prior to sourcing + local -a aliases_pre galiases_pre + if (( disable_aliases )); then + aliases_pre=("${(@k)aliases}") + galiases_pre=("${(@k)galiases}") + fi + + # Source file from $ZSH_CUSTOM if it exists, otherwise from $ZSH + if [[ -f "$ZSH_CUSTOM/$filepath" ]]; then + source "$ZSH_CUSTOM/$filepath" + elif [[ -f "$ZSH/$filepath" ]]; then + source "$ZSH/$filepath" + fi + + # Unset all aliases that don't appear in the backed up list of aliases + if (( disable_aliases )); then + local -a disabled + # ${var:|array} gets the list of items in var not in array + disabled=("${(@k)aliases:|aliases_pre}" "${(@k)galiases:|galiases_pre}") + (( $#disabled == 0 )) || unalias "${(@)disabled}" + fi +} + # Load all of the config files in ~/oh-my-zsh that end in .zsh # TIP: Add files you don't want in git to .gitignore for config_file ("$ZSH"/lib/*.zsh); do - custom_config_file="$ZSH_CUSTOM/lib/${config_file:t}" - [[ -f "$custom_config_file" ]] && config_file="$custom_config_file" - source "$config_file" + _omz_source "lib/${config_file:t}" done unset custom_config_file # Load all of the plugins that were defined in ~/.zshrc for plugin ($plugins); do - if [[ -f "$ZSH_CUSTOM/plugins/$plugin/$plugin.plugin.zsh" ]]; then - source "$ZSH_CUSTOM/plugins/$plugin/$plugin.plugin.zsh" - elif [[ -f "$ZSH/plugins/$plugin/$plugin.plugin.zsh" ]]; then - source "$ZSH/plugins/$plugin/$plugin.plugin.zsh" - fi + _omz_source "plugins/$plugin/$plugin.plugin.zsh" done unset plugin @@ -185,3 +218,6 @@ if [[ -n "$ZSH_THEME" ]]; then echo "[oh-my-zsh] theme '$ZSH_THEME' not found" fi fi + +# set completion colors to be the same as `ls`, after theme has been loaded +[[ -z "$LS_COLORS" ]] || zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}" diff --git a/plugins/1password/README.md b/plugins/1password/README.md index f6854da53..ace6da8e1 100644 --- a/plugins/1password/README.md +++ b/plugins/1password/README.md @@ -14,16 +14,18 @@ clipboard. ## `opswd` The `opswd` command is a wrapper around the `op` command. It takes a service -name as an argument and copies the password for that service to the clipboard. +name as an argument and copies the username, then the password for that service +to the clipboard, after confirmation on the user part. -If the service also contains a TOTP, it is copied to the clipboard after 10 seconds. -Finally, after 20 seconds, the clipboard is cleared. +If the service also contains a TOTP, it is copied to the clipboard after confirmation +on the user part. Finally, after 20 seconds, the clipboard is cleared. -The function has completion support, so you can use tab completion to select -which service you want to get. +For example, `opswd github.com` will put your GitHub username into your clipboard. Then, +it will ask for confirmation to continue, and copy the password to your clipboard. Finally, +if a TOTP is available, it will be copied to the clipboard after your confirmation. -For example, `opswd github.com` will put your GitHub password into your clipboard, and if -a TOTP is available, it will be copied to the clipboard after 10 seconds. +This function has completion support, so you can use tab completion to select which +service you want to get. > NOTE: you need to be signed in for `opswd` to work. If you are using biometric unlock, > 1Password CLI will automatically prompt you to sign in. See: diff --git a/plugins/1password/opswd b/plugins/1password/opswd index 57672807e..0f667d2ff 100644 --- a/plugins/1password/opswd +++ b/plugins/1password/opswd @@ -14,6 +14,17 @@ function opswd() { # If not logged in, print error and return op user list > /dev/null || return + local username + # Copy the username to the clipboard + if ! username=$(op item get "$service" --fields username 2>/dev/null); then + echo "error: could not obtain username for $service" + return 1 + fi + + echo -n "$username" | clipcopy + echo "✔ username for service $service copied to the clipboard. Press Enter to continue" + read + local password # Copy the password to the clipboard if ! password=$(op item get "$service" --fields password 2>/dev/null); then @@ -22,12 +33,13 @@ function opswd() { fi echo -n "$password" | clipcopy - echo "✔ password for $service copied to clipboard" + echo "✔ password for $service copied to clipboard. Press Enter to continue" + read - # If there's a one time password, copy it to the clipboard after 10 seconds + # If there's a one time password, copy it to the clipboard local totp if totp=$(op item get --otp "$service" 2>/dev/null) && [[ -n "$totp" ]]; then - sleep 10 && echo -n "$totp" | clipcopy + echo -n "$totp" | clipcopy echo "✔ TOTP for $service copied to clipboard" fi diff --git a/plugins/aliases/README.md b/plugins/aliases/README.md index bfb6ab8c4..6a2da3d74 100644 --- a/plugins/aliases/README.md +++ b/plugins/aliases/README.md @@ -15,8 +15,14 @@ Requirements: Python needs to be installed. ## Usage -- `acs`: show all aliases by group. +- `acs`: show all aliases by group -- `acs `: filter aliases by `` and highlight. +- `acs -h/--help`: print help mesage + +- `acs `: filter and highlight aliases by `` + +- `acs -g /--group `: show only aliases for group ``. Multiple uses of the flag show all groups + +- `acs --groups`: show only group names ![screenshot](https://cloud.githubusercontent.com/assets/3602957/11581913/cb54fb8a-9a82-11e5-846b-5a67f67ad9ad.png) diff --git a/plugins/aliases/aliases.plugin.zsh b/plugins/aliases/aliases.plugin.zsh index 4e1e0558e..9864de957 100644 --- a/plugins/aliases/aliases.plugin.zsh +++ b/plugins/aliases/aliases.plugin.zsh @@ -1,11 +1,14 @@ -# with lots of 3rd-party amazing aliases installed, just need something to explore it quickly. -# -# - acs: alias cheatsheet -# group alias by command, pass addition argv to grep. -function acs(){ - (( $+commands[python3] )) || { - echo "[error] No python executable detected" - return +# Handle $0 according to the standard: +# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html +0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}" +0="${${(M)0:#/*}:-$PWD/$0}" + +eval ' + function acs(){ + (( $+commands[python3] )) || { + echo "[error] No python executable detected" + return + } + alias | python3 "'"${0:h}"'/cheatsheet.py" "$@" } - alias | python3 ${functions_source[$0]:h}/cheatsheet.py $@ -} +' diff --git a/plugins/aliases/cheatsheet.py b/plugins/aliases/cheatsheet.py index a7e3968b0..f742fba9e 100644 --- a/plugins/aliases/cheatsheet.py +++ b/plugins/aliases/cheatsheet.py @@ -2,6 +2,7 @@ import sys import itertools import termcolor +import argparse def parse(line): left = line[0:line.find('=')].strip() @@ -14,6 +15,7 @@ def parse(line): def cheatsheet(lines): exps = [ parse(line) for line in lines ] + exps.sort(key=lambda exp:exp[2]) cheatsheet = {'_default': []} for key, group in itertools.groupby(exps, lambda exp:exp[2]): group_list = [ item for item in group ] @@ -26,7 +28,7 @@ def cheatsheet(lines): target_aliases.extend(group_list) return cheatsheet -def pretty_print_group(key, aliases, highlight=None): +def pretty_print_group(key, aliases, highlight=None, only_groupname=False): if len(aliases) == 0: return group_hl_formatter = lambda g, hl: termcolor.colored(hl, 'yellow').join([termcolor.colored(part, 'red') for part in ('[%s]' % g).split(hl)]) @@ -35,21 +37,33 @@ def pretty_print_group(key, aliases, highlight=None): alias_formatter = lambda alias: termcolor.colored('\t%s = %s' % alias[0:2], 'green') if highlight and len(highlight)>0: print (group_hl_formatter(key, highlight)) - print ('\n'.join([alias_hl_formatter(alias, highlight) for alias in aliases])) + if not only_groupname: + print ('\n'.join([alias_hl_formatter(alias, highlight) for alias in aliases])) else: print (group_formatter(key)) - print ('\n'.join([alias_formatter(alias) for alias in aliases])) + if not only_groupname: + print ('\n'.join([alias_formatter(alias) for alias in aliases])) print ('') -def pretty_print(cheatsheet, wfilter): +def pretty_print(cheatsheet, wfilter, group_list=None, groups_only=False): sorted_key = sorted(cheatsheet.keys()) for key in sorted_key: + if group_list and key not in group_list: + continue aliases = cheatsheet.get(key) if not wfilter: - pretty_print_group(key, aliases, wfilter) + pretty_print_group(key, aliases, wfilter, groups_only) else: pretty_print_group(key, [ alias for alias in aliases if alias[0].find(wfilter)>-1 or alias[1].find(wfilter)>-1], wfilter) if __name__ == '__main__': + parser = argparse.ArgumentParser(description="Pretty print aliases.", prog="acs") + parser.add_argument('filter', nargs="*", metavar="", help="search aliases matching keywords") + parser.add_argument('-g', '--group', dest="group_list", action='append', help="only print aliases in given groups") + parser.add_argument('--groups', dest='groups_only', action='store_true', help="only print alias groups") + args = parser.parse_args() + lines = sys.stdin.readlines() - pretty_print(cheatsheet(lines), sys.argv[1] if len(sys.argv)>1 else None) + group_list = args.group_list or None + wfilter = " ".join(args.filter) or None + pretty_print(cheatsheet(lines), wfilter, group_list, args.groups_only) diff --git a/plugins/argocd/README.md b/plugins/argocd/README.md new file mode 100644 index 000000000..0f900ff22 --- /dev/null +++ b/plugins/argocd/README.md @@ -0,0 +1,20 @@ +# Argo CD plugin + +This plugin adds completion for the [Argo CD](https://argoproj.github.io/cd/) CLI. + +To use it, add `argocd` to the plugins array in your zshrc file: + +```zsh +plugins=(... argocd) +``` + +This plugin does not add any aliases. + +## Cache + +This plugin caches the completion script and is automatically updated asynchronously when the plugin is +loaded, which is usually when you start up a new terminal emulator. + +The cache is stored at: + +- `$ZSH_CACHE/completions/_argocd` completions script diff --git a/plugins/argocd/argocd.plugin.zsh b/plugins/argocd/argocd.plugin.zsh new file mode 100644 index 000000000..8de7b0238 --- /dev/null +++ b/plugins/argocd/argocd.plugin.zsh @@ -0,0 +1,14 @@ +# Autocompletion for argocd. +if (( ! $+commands[argocd] )); then + return +fi + +# If the completion file doesn't exist yet, we need to autoload it and +# bind it to `argocd`. Otherwise, compinit will have already done that. +if [[ ! -f "$ZSH_CACHE_DIR/completions/_argocd" ]]; then + typeset -g -A _comps + autoload -Uz _argocd + _comps[argocd]=_argocd +fi + +argocd completion zsh >| "$ZSH_CACHE_DIR/completions/_argocd" &| diff --git a/plugins/asdf/README.md b/plugins/asdf/README.md index e8aa976bc..f047860e2 100644 --- a/plugins/asdf/README.md +++ b/plugins/asdf/README.md @@ -6,22 +6,25 @@ Adds integration with [asdf](https://github.com/asdf-vm/asdf), the extendable ve ### Installation -1. Enable the plugin by adding it to your `plugins` definition in `~/.zshrc`. +1. [Download asdf](https://asdf-vm.com/guide/getting-started.html#_2-download-asdf) by running the following: + + ``` + git clone https://github.com/asdf-vm/asdf.git ~/.asdf + ``` + +2. [Enable asdf](https://asdf-vm.com/guide/getting-started.html#_3-install-asdf) by adding it to your `plugins` definition in `~/.zshrc`. ``` plugins=(asdf) ``` -2. [Install asdf](https://github.com/asdf-vm/asdf#setup) by running the following: - ``` - git clone https://github.com/asdf-vm/asdf.git ~/.asdf - ``` - ### Usage -See the [asdf usage documentation](https://github.com/asdf-vm/asdf#usage) for information on how to use asdf: +See the [asdf documentation](https://asdf-vm.com/guide/getting-started.html#_4-install-a-plugin) for information on how to use asdf: ``` -asdf plugin-add nodejs git@github.com:asdf-vm/asdf-nodejs.git -asdf install nodejs 5.9.1 +asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git +asdf install nodejs latest +asdf global nodejs latest +asdf local nodejs latest ``` diff --git a/plugins/autojump/autojump.plugin.zsh b/plugins/autojump/autojump.plugin.zsh index 8593353b2..1b868ee8d 100644 --- a/plugins/autojump/autojump.plugin.zsh +++ b/plugins/autojump/autojump.plugin.zsh @@ -1,17 +1,18 @@ declare -a autojump_paths autojump_paths=( - $HOME/.autojump/etc/profile.d/autojump.zsh # manual installation - $HOME/.autojump/share/autojump/autojump.zsh # manual installation - $HOME/.nix-profile/etc/profile.d/autojump.sh # NixOS installation - /run/current-system/sw/share/autojump/autojump.zsh # NixOS installation - /usr/share/autojump/autojump.zsh # Debian and Ubuntu package - /etc/profile.d/autojump.zsh # manual installation - /etc/profile.d/autojump.sh # Gentoo installation - /usr/local/share/autojump/autojump.zsh # FreeBSD installation - /usr/pkg/share/autojump/autojump.zsh # NetBSD installation - /opt/local/etc/profile.d/autojump.sh # macOS with MacPorts - /usr/local/etc/profile.d/autojump.sh # macOS with Homebrew (default) - /opt/homebrew/etc/profile.d/autojump.sh # macOS with Homebrew (default on M1 macs) + $HOME/.autojump/etc/profile.d/autojump.zsh # manual installation + $HOME/.autojump/share/autojump/autojump.zsh # manual installation + $HOME/.nix-profile/etc/profile.d/autojump.sh # NixOS installation + /run/current-system/sw/share/autojump/autojump.zsh # NixOS installation + /usr/share/autojump/autojump.zsh # Debian and Ubuntu package + /etc/profile.d/autojump.zsh # manual installation + /etc/profile.d/autojump.sh # Gentoo installation + /usr/local/share/autojump/autojump.zsh # FreeBSD installation + /usr/pkg/share/autojump/autojump.zsh # NetBSD installation + /opt/local/etc/profile.d/autojump.sh # macOS with MacPorts + /usr/local/etc/profile.d/autojump.sh # macOS with Homebrew (default) + /opt/homebrew/etc/profile.d/autojump.sh # macOS with Homebrew (default on M1 macs) + /etc/profiles/per-user/$USER/etc/profile.d/autojump.sh # macOS Nix, Home Manager and flakes ) for file in $autojump_paths; do diff --git a/plugins/aws/README.md b/plugins/aws/README.md index d6f4f4600..846bf1414 100644 --- a/plugins/aws/README.md +++ b/plugins/aws/README.md @@ -1,7 +1,7 @@ # aws This plugin provides completion support for [awscli](https://docs.aws.amazon.com/cli/latest/reference/index.html) -and a few utilities to manage AWS profiles and display them in the prompt. +and a few utilities to manage AWS profiles/regions and display them in the prompt. To use it, add `aws` to the plugins array in your zshrc file. @@ -12,10 +12,13 @@ plugins=(... aws) ## Plugin commands * `asp []`: sets `$AWS_PROFILE` and `$AWS_DEFAULT_PROFILE` (legacy) to ``. - It also sets `$AWS_EB_PROFILE` to `` for the Elastic Beanstalk CLI. + It also sets `$AWS_EB_PROFILE` to `` for the Elastic Beanstalk CLI. It sets `$AWS_PROFILE_REGION` for display in `aws_prompt_info`. Run `asp` without arguments to clear the profile. * `asp [] login`: If AWS SSO has been configured in your aws profile, it will run the `aws sso login` command following profile selection. +* `asr []`: sets `$AWS_REGION` and `$AWS_DEFAULT_REGION` (legacy) to ``. + Run `asr` without arguments to clear the profile. + * `acp [] []`: in addition to `asp` functionality, it actually changes the profile by assuming the role specified in the `` configuration. It supports MFA and sets `$AWS_ACCESS_KEY_ID`, `$AWS_SECRET_ACCESS_KEY` and `$AWS_SESSION_TOKEN`, if @@ -25,25 +28,34 @@ plugins=(... aws) * `agp`: gets the current value of `$AWS_PROFILE`. +* `agr`: gets the current value of `$AWS_REGION`. + * `aws_change_access_key`: changes the AWS access key of a profile. * `aws_profiles`: lists the available profiles in the `$AWS_CONFIG_FILE` (default: `~/.aws/config`). Used to provide completion for the `asp` function. +* `aws_regions`: lists the available regions. + Used to provide completion for the `asr` function. + ## Plugin options * Set `SHOW_AWS_PROMPT=false` in your zshrc file if you want to prevent the plugin from modifying your RPROMPT. Some themes might overwrite the value of RPROMPT instead of appending to it, so they'll need to be fixed to - see the AWS profile prompt. + see the AWS profile/region prompt. ## Theme The plugin creates an `aws_prompt_info` function that you can use in your theme, which displays -the current `$AWS_PROFILE`. It uses two variables to control how that is shown: +the current `$AWS_PROFILE` and `$AWS_REGION`. It uses four variables to control how that is shown: -* ZSH_THEME_AWS_PREFIX: sets the prefix of the AWS_PROFILE. Defaults to ``. +* ZSH_THEME_AWS_PROFILE_SUFFIX: sets the suffix of the AWS_PROFILE. Defaults to `>`. + +* ZSH_THEME_AWS_REGION_PREFIX: sets the prefix of the AWS_REGION. Defaults to ``. ## Configuration diff --git a/plugins/aws/aws.plugin.zsh b/plugins/aws/aws.plugin.zsh index b8625d7ac..a379eaa18 100644 --- a/plugins/aws/aws.plugin.zsh +++ b/plugins/aws/aws.plugin.zsh @@ -2,10 +2,14 @@ function agp() { echo $AWS_PROFILE } +function agr() { + echo $AWS_REGION +} + # AWS profile selection function asp() { if [[ -z "$1" ]]; then - unset AWS_DEFAULT_PROFILE AWS_PROFILE AWS_EB_PROFILE + unset AWS_DEFAULT_PROFILE AWS_PROFILE AWS_EB_PROFILE AWS_PROFILE_REGION echo AWS profile cleared. return fi @@ -22,11 +26,32 @@ function asp() { export AWS_PROFILE=$1 export AWS_EB_PROFILE=$1 + export AWS_PROFILE_REGION=$(aws configure get region) + if [[ "$2" == "login" ]]; then aws sso login fi } +# AWS region selection +function asr() { + if [[ -z "$1" ]]; then + unset AWS_DEFAULT_REGION AWS_REGION + echo AWS region cleared. + return + fi + + local -a available_regions + available_regions=($(aws_regions)) + if [[ -z "${available_regions[(r)$1]}" ]]; then + echo "${fg[red]}Available regions: \n$(aws_regions)" + return 1 + fi + + export AWS_REGION=$1 + export AWS_DEFAULT_REGION=$1 +} + # AWS profile switch function acp() { if [[ -z "$1" ]]; then @@ -145,11 +170,25 @@ function aws_change_access_key() { AWS_PAGER="" aws iam list-access-keys } -function aws_profiles() { - [[ -r "${AWS_CONFIG_FILE:-$HOME/.aws/config}" ]] || return 1 - grep --color=never -Eo '\[.*\]' "${AWS_CONFIG_FILE:-$HOME/.aws/config}" | sed -E 's/^[[:space:]]*\[(profile)?[[:space:]]*([-_[:alnum:]\.@]+)\][[:space:]]*$/\2/g' +function aws_regions() { + if [[ $AWS_DEFAULT_PROFILE || $AWS_PROFILE ]];then + aws ec2 describe-regions |grep RegionName | awk -F ':' '{gsub(/"/, "", $2);gsub(/,/, "", $2);gsub(/ /, "", $2); print $2}' + else + echo "You must specify a AWS profile." + fi } +function aws_profiles() { + aws --no-cli-pager configure list-profiles 2> /dev/null && return + [[ -r "${AWS_CONFIG_FILE:-$HOME/.aws/config}" ]] || return 1 + grep --color=never -Eo '\[.*\]' "${AWS_CONFIG_FILE:-$HOME/.aws/config}" | sed -E 's/^[[:space:]]*\[(profile)?[[:space:]]*([^[:space:]]+)\][[:space:]]*$/\2/g' +} + +function _aws_regions() { + reply=($(aws_regions)) +} +compctl -K _aws_regions asr + function _aws_profiles() { reply=($(aws_profiles)) } @@ -157,15 +196,22 @@ compctl -K _aws_profiles asp acp aws_change_access_key # AWS prompt function aws_prompt_info() { - [[ -n "$AWS_PROFILE" ]] || return - echo "${ZSH_THEME_AWS_PREFIX=}" + local _aws_to_show + local region="${AWS_REGION:-${AWS_DEFAULT_REGION:-$AWS_PROFILE_REGION}}" + if [[ -n $AWS_PROFILE ]];then + _aws_to_show+="${ZSH_THEME_AWS_PROFILE_PREFIX:=}" + fi + if [[ -n $AWS_REGION ]]; then + [[ -n $AWS_PROFILE ]] && _aws_to_show+=" " + _aws_to_show+="${ZSH_THEME_AWS_REGION_PREFIX:=}" + fi + echo "$_aws_to_show" } if [[ "$SHOW_AWS_PROMPT" != false && "$RPROMPT" != *'$(aws_prompt_info)'* ]]; then RPROMPT='$(aws_prompt_info)'"$RPROMPT" fi - # Load awscli completions # AWS CLI v2 comes with its own autocompletion. Check if that is there, otherwise fall back @@ -210,3 +256,4 @@ else [[ -r $_aws_zsh_completer_path ]] && source $_aws_zsh_completer_path unset _aws_zsh_completer_path _brew_prefix fi + diff --git a/plugins/azure/README.md b/plugins/azure/README.md new file mode 100644 index 000000000..f39930851 --- /dev/null +++ b/plugins/azure/README.md @@ -0,0 +1,49 @@ +# azure + +This plugin provides completion support for [azure cli](https://docs.microsoft.com/en-us/cli/azure/) +and a few utilities to manage azure subscriptions and display them in the prompt. + +To use it, add `azure` to the plugins array in your zshrc file. + +```zsh +plugins=(... azure) +``` + +## Plugin commands + + +* `az_subscriptions`: lists the available subscriptions in the `AZURE_CONFIG_DIR` (default: `~/.azure/`). + Used to provide completion for the `azss` function. + +* `azgs`: gets the current value of `$azure_subscription`. + +* `azss []`: sets the `$azure_subscription`. + + +NOTE : because azure keeps the state of active subscription in ${AZURE_CONFIG_DIR:-$HOME/.azure/azureProfile.json}, the prompt command requires `jq` to be enabled to parse the file. If jq is not in the path the prompt will show nothing + +## Theme + +The plugin creates an `azure_prompt_info` function that you can use in your theme, which displays +the current `$azure_subscription`. It uses two variables to control how that is shown: + +- ZSH_THEME_AZURE_PREFIX: sets the prefix of the azure_subscription. Defaults to ``. + + +``` +RPROMPT='$(azure_prompt_info)' +``` + +## Develop + +On ubuntu get a working environment with : + +` docker run -it -v $(pwd):/mnt -w /mnt ubuntu bash` + +``` +apt install -y curl jq zsh git vim +sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" +curl -sL https://aka.ms/InstallAzureCLIDeb | bash +``` \ No newline at end of file diff --git a/plugins/azure/azure.plugin.zsh b/plugins/azure/azure.plugin.zsh new file mode 100644 index 000000000..51b54dbc1 --- /dev/null +++ b/plugins/azure/azure.plugin.zsh @@ -0,0 +1,62 @@ +# AZ Get Subscritions +function azgs() { + az account show --output tsv --query 'name' 2>/dev/null +} + +# AZ Subscription Selection +alias azss="az account set --subscription" + + +function az_subscriptions() { + az account list --all --output tsv --query '[*].name' 2> /dev/null +} + +function _az_subscriptions() { + reply=($(az_subscriptions)) +} +compctl -K _az_subscriptions azss + +# Azure prompt +function azure_prompt_info() { + [[ ! -f "${AZURE_CONFIG_DIR:-$HOME/.azure/azureProfile.json}" ]] && return + # azgs is too expensive, if we have jq, we enable the prompt + (( $+commands[jq] )) || return 1 + azgs=$(jq -r '.subscriptions[] | select(.isDefault==true) .name' ${AZURE_CONFIG_DIR:-$HOME/.azure/azureProfile.json}) + echo "${ZSH_THEME_AZURE_PREFIX:=}" +} + + +# Load az completions +function _az-homebrew-installed() { + # check if Homebrew is installed + (( $+commands[brew] )) || return 1 + + # speculatively check default brew prefix + if [[ -d /usr/local ]]; then + _brew_prefix=/usr/local + elif [[ -d /opt/homebrew ]]; then + _brew_prefix=/opt/homebrew + else + # ok, it is not in the default prefix + # this call to brew is expensive (about 400 ms), so at least let's make it only once + _brew_prefix=$(brew --prefix) + fi +} + + +# get az.completion.sh location from $PATH +_az_zsh_completer_path="$commands[az_zsh_completer.sh]" + +# otherwise check common locations +if [[ -z $_az_zsh_completer_path ]]; then + # Homebrew + if _az-homebrew-installed; then + _az_zsh_completer_path=$_brew_prefix/etc/bash_completion.d/az + # Linux + else + _az_zsh_completer_path=/etc/bash_completion.d/azure-cli + fi +fi + +[[ -r $_az_zsh_completer_path ]] && autoload -U +X bashcompinit && bashcompinit && source $_az_zsh_completer_path +unset _az_zsh_completer_path _brew_prefix diff --git a/plugins/bgnotify/bgnotify.plugin.zsh b/plugins/bgnotify/bgnotify.plugin.zsh index 479796dbe..ed2653aa8 100644 --- a/plugins/bgnotify/bgnotify.plugin.zsh +++ b/plugins/bgnotify/bgnotify.plugin.zsh @@ -1,44 +1,79 @@ #!/usr/bin/env zsh -## setup ## +## Setup -[[ -o interactive ]] || return #interactive only! -zmodload zsh/datetime || { print "can't load zsh/datetime"; return } # faster than date() -autoload -Uz add-zsh-hook || { print "can't add zsh hook!"; return } +[[ -o interactive ]] || return # don't load on non-interactive shells +[[ -z "$SSH_CLIENT" && -z "$SSH_TTY" ]] || return # don't load on a SSH connection -(( ${+bgnotify_threshold} )) || bgnotify_threshold=5 #default 10 seconds +zmodload zsh/datetime # faster than `date` -## definitions ## +## Zsh Hooks -if ! (type bgnotify_formatted | grep -q 'function'); then ## allow custom function override - function bgnotify_formatted { ## args: (exit_status, command, elapsed_seconds) - elapsed="$(( $3 % 60 ))s" - (( $3 >= 60 )) && elapsed="$((( $3 % 3600) / 60 ))m $elapsed" - (( $3 >= 3600 )) && elapsed="$(( $3 / 3600 ))h $elapsed" - [ $1 -eq 0 ] && bgnotify "#win (took $elapsed)" "$2" || bgnotify "#fail (took $elapsed)" "$2" +function bgnotify_begin { + bgnotify_timestamp=$EPOCHSECONDS + bgnotify_lastcmd="${1:-$2}" +} + +function bgnotify_end { + { + local exit_status=$? + local elapsed=$(( EPOCHSECONDS - bgnotify_timestamp )) + + # check time elapsed + [[ $bgnotify_timestamp -gt 0 ]] || return + [[ $elapsed -ge $bgnotify_threshold ]] || return + + # check if Terminal app is not active + [[ $(bgnotify_appid) != "$bgnotify_termid" ]] || return + + printf '\a' # beep sound + bgnotify_formatted "$exit_status" "$bgnotify_lastcmd" "$elapsed" + } always { + bgnotify_timestamp=0 } -fi - -currentAppId () { - if (( $+commands[osascript] )); then - osascript -e 'tell application (path to frontmost application as text) to id' 2>/dev/null - fi } -currentWindowId () { - if hash osascript 2>/dev/null; then #osx - osascript -e 'tell application (path to frontmost application as text) to id of front window' 2&> /dev/null || echo "0" - elif (hash notify-send 2>/dev/null || hash kdialog 2>/dev/null); then #ubuntu! - xprop -root 2> /dev/null | awk '/NET_ACTIVE_WINDOW/{print $5;exit} END{exit !$5}' || echo "0" +autoload -Uz add-zsh-hook +add-zsh-hook preexec bgnotify_begin +add-zsh-hook precmd bgnotify_end + + +## Functions + +# allow custom function override +(( ${+functions[bgnotify_formatted]} )) || \ +function bgnotify_formatted { + local exit_status=$1 + local cmd="$2" + + # humanly readable elapsed time + local elapsed="$(( $3 % 60 ))s" + (( $3 < 60 )) || elapsed="$((( $3 % 3600) / 60 ))m $elapsed" + (( $3 < 3600 )) || elapsed="$(( $3 / 3600 ))h $elapsed" + + if [[ $1 -eq 0 ]]; then + bgnotify "#win (took $elapsed)" "$2" else - echo $EPOCHSECONDS #fallback for windows + bgnotify "#fail (took $elapsed)" "$2" fi } -bgnotify () { ## args: (title, subtitle) - if hash terminal-notifier 2>/dev/null; then #osx - local term_id="$bgnotify_appid" +# for macOS, output is "app ID, window ID" (com.googlecode.iterm2, 116) +function bgnotify_appid { + if (( ${+commands[osascript]} )); then + osascript -e 'tell application (path to frontmost application as text) to get the {id, id of front window}' 2>/dev/null + elif (( ${+commands[xprop]} )); then + xprop -root _NET_ACTIVE_WINDOW 2>/dev/null | cut -d' ' -f5 + else + echo $EPOCHSECONDS + fi +} + +function bgnotify { + # $1: title, $2: message + if (( ${+commands[terminal-notifier]} )); then # macOS + local term_id="${bgnotify_termid%%,*}" # remove window id if [[ -z "$term_id" ]]; then case "$TERM_PROGRAM" in iTerm.app) term_id='com.googlecode.iterm2' ;; @@ -46,48 +81,26 @@ bgnotify () { ## args: (title, subtitle) esac fi - ## now call terminal-notifier, (hopefully with $term_id!) if [[ -z "$term_id" ]]; then - terminal-notifier -message "$2" -title "$1" >/dev/null + terminal-notifier -message "$2" -title "$1" &>/dev/null else - terminal-notifier -message "$2" -title "$1" -activate "$term_id" -sender "$term_id" >/dev/null + terminal-notifier -message "$2" -title "$1" -activate "$term_id" -sender "$term_id" &>/dev/null fi - elif hash growlnotify 2>/dev/null; then #osx growl + elif (( ${+commands[growlnotify]} )); then # macOS growl growlnotify -m "$1" "$2" - elif hash notify-send 2>/dev/null; then #ubuntu gnome! + elif (( ${+commands[notify-send]} )); then # GNOME notify-send "$1" "$2" - elif hash kdialog 2>/dev/null; then #ubuntu kde! + elif (( ${+commands[kdialog]} )); then # KDE kdialog --title "$1" --passivepopup "$2" 5 - elif hash notifu 2>/dev/null; then #cygwyn support! + elif (( ${+commands[notifu]} )); then # cygwin notifu /m "$2" /p "$1" fi } +## Defaults -## Zsh hooks ## +# notify if command took longer than 5s by default +bgnotify_threshold=${bgnotify_threshold:-5} -bgnotify_begin() { - bgnotify_timestamp=$EPOCHSECONDS - bgnotify_lastcmd="${1:-$2}" - bgnotify_appid="$(currentAppId)" - bgnotify_windowid=$(currentWindowId) -} - -bgnotify_end() { - didexit=$? - elapsed=$(( EPOCHSECONDS - bgnotify_timestamp )) - past_threshold=$(( elapsed >= bgnotify_threshold )) - if (( bgnotify_timestamp > 0 )) && (( past_threshold )); then - if [[ $(currentAppId) != "$bgnotify_appid" || $(currentWindowId) != "$bgnotify_windowid" ]]; then - print -n "\a" - bgnotify_formatted "$didexit" "$bgnotify_lastcmd" "$elapsed" - fi - fi - bgnotify_timestamp=0 #reset it to 0! -} - -## only enable if a local (non-ssh) connection -if [ -z "$SSH_CLIENT" ] && [ -z "$SSH_TTY" ]; then - add-zsh-hook preexec bgnotify_begin - add-zsh-hook precmd bgnotify_end -fi +# bgnotify_appid is slow in macOS and the terminal ID won't change, so cache it at startup +bgnotify_termid="$(bgnotify_appid)" diff --git a/plugins/brew/README.md b/plugins/brew/README.md index bf952bf01..412daae63 100644 --- a/plugins/brew/README.md +++ b/plugins/brew/README.md @@ -8,19 +8,28 @@ To use it, add `brew` to the plugins array of your zshrc file: plugins=(... brew) ``` +## Shellenv + +If `brew` is not found in the PATH, this plugin will attempt to find it in common +locations, and execute `brew shellenv` to set the environment appropriately. +This plugin will also export `HOMEBREW_PREFIX="$(brew --prefix)"` if not previously +defined for convenience. + ## Aliases -| Alias | Command | Description | -|----------|---------------------------------------|---------------------------------------------------------------------| -| `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. | -| `brewsp` | `brew list --pinned` | List pinned formulae, or show the version of a given formula. | -| `bubo` | `brew update && brew outdated` | Update Homebrew data, then list outdated formulae and casks. | -| `bubc` | `brew upgrade && brew cleanup` | Upgrade outdated formulae and casks, then run cleanup. | -| `bubu` | `bubo && bubc` | Do the last two operations above. | -| `buf` | `brew upgrade --formula` | Upgrade only formulas (not casks). | -| `bcubo` | `brew update && brew outdated --cask` | Update Homebrew data, then list outdated casks. | -| `bcubc` | `brew upgrade --cask && brew cleanup` | Update outdated casks, then run cleanup. | +| Alias | Command | Description | +| -------- | --------------------------------------- | ------------------------------------------------------------------- | +| `bcubc` | `brew upgrade --cask && brew cleanup` | Update outdated casks, then run cleanup. | +| `bcubo` | `brew update && brew outdated --cask` | Update Homebrew data, then list outdated casks. | +| `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. | +| `brewsp` | `brew list --pinned` | List pinned formulae, or show the version of a given formula. | +| `bubc` | `brew upgrade && brew cleanup` | Upgrade outdated formulae and casks, then run cleanup. | +| `bugbc` | `brew upgrade --greedy && brew cleanup` | Upgrade outdated formulae and casks (greedy), then run cleanup. | +| `bubo` | `brew update && brew outdated` | Update Homebrew data, then list outdated formulae and casks. | +| `bubu` | `bubo && bubc` | Do the last two operations above. | +| `bfu` | `brew upgrade --formula` | Upgrade only formulas (not casks). | +| `buz` | `brew uninstall --zap` | Remove all files associated with a cask. | ## Completion diff --git a/plugins/brew/brew.plugin.zsh b/plugins/brew/brew.plugin.zsh index 070a083d0..f6abe0875 100644 --- a/plugins/brew/brew.plugin.zsh +++ b/plugins/brew/brew.plugin.zsh @@ -1,15 +1,46 @@ -alias brewp='brew pin' -alias brewsp='brew list --pinned' -alias bubo='brew update && brew outdated' -alias bubc='brew upgrade && brew cleanup' -alias bubu='bubo && bubc' -alias buf='brew upgrade --formula' +if (( ! $+commands[brew] )); then + if [[ -x /opt/homebrew/bin/brew ]]; then + BREW_LOCATION="/opt/homebrew/bin/brew" + elif [[ -x /usr/local/bin/brew ]]; then + BREW_LOCATION="/usr/local/bin/brew" + elif [[ -x /home/linuxbrew/.linuxbrew/bin/brew ]]; then + BREW_LOCATION="/home/linuxbrew/.linuxbrew/bin/brew" + elif [[ -x "$HOME/.linuxbrew/bin/brew" ]]; then + BREW_LOCATION="$HOME/.linuxbrew/bin/brew" + else + return + fi + + # Only add Homebrew installation to PATH, MANPATH, and INFOPATH if brew is + # not already on the path, to prevent duplicate entries. This aligns with + # the behavior of the brew installer.sh post-install steps. + eval "$("$BREW_LOCATION" shellenv)" + unset BREW_LOCATION +fi + +if [[ -z "$HOMEBREW_PREFIX" ]]; then + # Maintain compatability with potential custom user profiles, where we had + # previously relied on always sourcing shellenv. OMZ plugins should not rely + # on this to be defined due to out of order processing. + export HOMEBREW_PREFIX="$(brew --prefix)" +fi + +alias bcubc='brew upgrade --cask && brew cleanup' alias bcubo='brew update && brew outdated --cask' alias bcubc='brew upgrade --cask && brew cleanup' +alias brewp='brew pin' +alias brewsp='brew list --pinned' +alias bubc='brew upgrade && brew cleanup' +alias bugbc='brew upgrade --greedy && brew cleanup' +alias bubo='brew update && brew outdated' +alias bubu='bubo && bubc' +alias bubug='bubo && bugbc' +alias bfu='brew upgrade --formula' +alias buz='brew uninstall --zap' function brews() { local formulae="$(brew leaves | xargs brew deps --installed --for-each)" - local casks="$(brew list --cask)" + local casks="$(brew list --cask 2>/dev/null)" local blue="$(tput setaf 4)" local bold="$(tput bold)" diff --git a/plugins/bridgetown/README.md b/plugins/bridgetown/README.md new file mode 100644 index 000000000..0a41814ee --- /dev/null +++ b/plugins/bridgetown/README.md @@ -0,0 +1,26 @@ +# Bridgetown plugin + +This plugin adds some aliases and autocompletion for common [Bridgetown](https://bridgetownrb.com/) commands. + +To use it, add `bridgetown` to the plugins array in your zshrc file: + +```zsh +plugins=(... bridgetown) +``` + +## Aliases + +| Alias | Command | +|-------|----------------------------| +| br | `bridgetown` | +| bra | `bin/bridgetown apply` | +| brb | `bin/bridgetown build` | +| brc | `bin/bridgetown console` | +| brclean | `bin/bridgetown clean` | +| brd | `bin/bridgetown deploy` | +| brdoc | `bin/bridgetown doctor` | +| brh | `bin/bridgetown help` | +| brn | `bridgetown new` | +| brp | `bridgetown plugins` | +| brpl | `bridgetown plugins list` | +| brs | `bin/bridgetown start` | diff --git a/plugins/bridgetown/bridgetown.plugin.zsh b/plugins/bridgetown/bridgetown.plugin.zsh new file mode 100644 index 000000000..502e9dfe0 --- /dev/null +++ b/plugins/bridgetown/bridgetown.plugin.zsh @@ -0,0 +1,12 @@ +alias br='bridgetown' +alias bra='bin/bridgetown apply' +alias brb='bin/bridgetown build' +alias brc='bin/bridgetown console' +alias brclean='bin/bridgetown clean' +alias brd='bin/bridgetown deploy' +alias brdoc='bin/bridgetown doctor' +alias brh='bin/bridgetown help' +alias brn='bridgetown new' +alias brp='bridgetown plugins' +alias brpl='bridgetown plugins list' +alias brs='bin/bridgetown start' diff --git a/plugins/cakephp3/cakephp3.plugin.zsh b/plugins/cakephp3/cakephp3.plugin.zsh index dbfbeba3b..a1a289fd0 100644 --- a/plugins/cakephp3/cakephp3.plugin.zsh +++ b/plugins/cakephp3/cakephp3.plugin.zsh @@ -1,10 +1,10 @@ # CakePHP 3 basic command completion _cakephp3_get_command_list () { - bin/cake Completion commands + bin/cake completion commands } _cakephp3_get_sub_command_list () { - bin/cake Completion subcommands ${words[2]} + bin/cake completion subcommands ${words[2]} } _cakephp3_get_3rd_argument () { @@ -34,5 +34,5 @@ compdef _cakephp3 cake #Alias alias c3='bin/cake' -alias c3cache='bin/cake orm_cache clear' +alias c3cache='bin/cake schema_cache clear' alias c3migrate='bin/cake migrations migrate' diff --git a/plugins/cargo/README.md b/plugins/cargo/README.md deleted file mode 100644 index 93e69ae7f..000000000 --- a/plugins/cargo/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# cargo - -**Deprecated: use the [`rust`](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/rust) plugin instead.** diff --git a/plugins/cargo/cargo.plugin.zsh b/plugins/cargo/cargo.plugin.zsh deleted file mode 100644 index 692025e8f..000000000 --- a/plugins/cargo/cargo.plugin.zsh +++ /dev/null @@ -1,7 +0,0 @@ -print ${(%):-'%F{yellow}The `cargo` plugin is deprecated and has been moved to the `rust` plugin.'} -print ${(%):-'Please update your .zshrc to use the `%Brust%b` plugin instead.%f'} - -(( ${fpath[(Ie)$ZSH/plugins/rust]} )) || { - fpath=("$ZSH/plugins/rust" $fpath) - source "$ZSH/plugins/rust/rust.plugin.zsh" -} diff --git a/plugins/coffee/_coffee b/plugins/coffee/_coffee index e2814f7ba..a771f5204 100644 --- a/plugins/coffee/_coffee +++ b/plugins/coffee/_coffee @@ -1,6 +1,6 @@ #compdef coffee # ------------------------------------------------------------------------------ -# Copyright (c) 2011 Github zsh-users - https://github.com/zsh-users +# Copyright (c) 2011 GitHub zsh-users - https://github.com/zsh-users # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/plugins/colorize/colorize.plugin.zsh b/plugins/colorize/colorize.plugin.zsh index a9da6cf83..12841e0ee 100644 --- a/plugins/colorize/colorize.plugin.zsh +++ b/plugins/colorize/colorize.plugin.zsh @@ -23,7 +23,7 @@ colorize_check_requirements() { if [[ ${available_tools[(Ie)$ZSH_COLORIZE_TOOL]} -eq 0 ]]; then echo "ZSH_COLORIZE_TOOL '$ZSH_COLORIZE_TOOL' not recognized. Available options are 'pygmentize' and 'chroma'." >&2 return 1 - elif (( $+commands["$ZSH_COLORIZE_TOOL"] )); then + elif ! (( $+commands[$ZSH_COLORIZE_TOOL] )); then echo "Package '$ZSH_COLORIZE_TOOL' is not installed!" >&2 return 1 fi diff --git a/plugins/common-aliases/README.md b/plugins/common-aliases/README.md index 0354c7a3f..1417c3056 100644 --- a/plugins/common-aliases/README.md +++ b/plugins/common-aliases/README.md @@ -35,9 +35,11 @@ plugins=(... common-aliases) | mv | `mv -i` | Move a file | | zshrc | `${=EDITOR} ~/.zshrc` | Quickly access the ~/.zshrc file | | dud | `du -d 1 -h` | Display the size of files at depth 1 in current location in human-readable form | -| duf | `du -sh` | Display the size of files in current location in human-readable form | +| duf\* | `du -sh` | Display the size of files in current location in human-readable form | | t | `tail -f` | Shorthand for tail which outputs the last part of a file | +\* Only if the [`duf`](https://github.com/muesli/duf) command isn't installed. + ### find and grep | Alias | Command | Description | @@ -66,12 +68,15 @@ These aliases are expanded in any position in the command line, meaning you can end of the command you've typed. Examples: Quickly pipe to less: + ```zsh $ ls -l /var/log L # will run $ ls -l /var/log | less ``` + Silences stderr output: + ```zsh $ find . -type f NE # will run diff --git a/plugins/common-aliases/common-aliases.plugin.zsh b/plugins/common-aliases/common-aliases.plugin.zsh index 8b58b6310..3139b821a 100644 --- a/plugins/common-aliases/common-aliases.plugin.zsh +++ b/plugins/common-aliases/common-aliases.plugin.zsh @@ -35,7 +35,7 @@ alias -g NUL="> /dev/null 2>&1" alias -g P="2>&1| pygmentize -l pytb" alias dud='du -d 1 -h' -alias duf='du -sh *' +(( $+commands[duf] )) || alias duf='du -sh *' (( $+commands[fd] )) || alias fd='find . -type d -name' alias ff='find . -type f -name' diff --git a/plugins/copybuffer/README.md b/plugins/copybuffer/README.md index da138bdbd..a53d1c813 100644 --- a/plugins/copybuffer/README.md +++ b/plugins/copybuffer/README.md @@ -1,7 +1,7 @@ # `copybuffer` plugin -This plugin binds the ctrl-o keyboard shortcut to a command that copies the text -that is currently typed in the command line ($BUFFER) to the system clipboard. +This plugin adds the ctrl-o keyboard shortcut to copy the current text +in the command line to the system clipboard. This is useful if you type a command - and before you hit enter to execute it - want to copy it maybe so you can paste it into a script, gist or whatnot. diff --git a/plugins/copydir/README.md b/plugins/copydir/README.md deleted file mode 100644 index cf24b789f..000000000 --- a/plugins/copydir/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# copydir plugin - -This plugin is deprecated. Use the [`copypath` plugin](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/copypath) instead. diff --git a/plugins/copydir/copydir.plugin.zsh b/plugins/copydir/copydir.plugin.zsh deleted file mode 100644 index a2b489ec0..000000000 --- a/plugins/copydir/copydir.plugin.zsh +++ /dev/null @@ -1,7 +0,0 @@ -echo ${(%):-'%F{yellow}The `%Bcopydir%b` plugin is deprecated. Use the `%Bcopypath%b` plugin instead.%f'} -source "$ZSH/plugins/copypath/copypath.plugin.zsh" - -# TODO: 2022-02-22: Remove deprecated copydir function. -function copydir { - copypath -} diff --git a/plugins/debian/README.md b/plugins/debian/README.md index 2ce206cfb..c1ebe1c50 100644 --- a/plugins/debian/README.md +++ b/plugins/debian/README.md @@ -21,7 +21,7 @@ Set `$apt_pref` and `$apt_upgr` to whatever command you want (before sourcing Oh | ------ | ---------------------------------------------------------------------- | ---------------------------------------------------------- | | `age` | `apt-get` | Command line tool for handling packages | | `api` | `aptitude` | Same functionality as `apt-get`, provides extra options | -| `acs` | `apt-cache search` | Command line tool for searching apt software package cache | +| `acse` | `apt-cache search` | Command line tool for searching apt software package cache | | `aps` | `aptitude search` | Searches installed packages using aptitude | | `as` | `aptitude -F '* %p -> %d \n(%v/%V)' --no-gui --disable-columns search` | Print searched packages using a custom format | | `afs` | `apt-file search --regexp` | Search file in packages | @@ -30,26 +30,25 @@ Set `$apt_pref` and `$apt_upgr` to whatever command you want (before sourcing Oh ## Superuser Operations Aliases -| Alias | Command | Description | -| -------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | -| `aac` | `sudo $apt_pref autoclean` | Clears out the local repository of retrieved package files | -| `aar` | `sudo $apt_pref autoremove` | Removes packages installed automatically that are no longer needed | -| `abd` | `sudo $apt_pref build-dep` | Installs all dependencies for building packages | -| `ac` | `sudo $apt_pref clean` | Clears out the local repository of retrieved package files except lock files | -| `ad` | `sudo $apt_pref update` | Updates the package lists for upgrades for packages | -| `adg` | `sudo $apt_pref update && sudo $apt_pref $apt_upgr` | Update and upgrade packages | -| `ads` | `sudo apt-get dselect-upgrade` | Installs packages from list and removes all not in the list | -| `adu` | `sudo $apt_pref update && sudo $apt_pref dist-upgrade` | Smart upgrade that handles dependencies | -| `afu` | `sudo apt-file update` | Update the files in packages | -| `ai` | `sudo $apt_pref install` | Command-line tool to install package | -| `ail` | `sed -e 's/ */ /g' -e 's/ *//' \| cut -s -d ' ' -f 1 \| xargs sudo $apt_pref install` | Install all packages given on the command line while using only the first word of each line | -| `alu` | `sudo apt update && apt list -u && sudo apt upgrade` | Update, list and upgrade packages | -| `ap` | `sudo $apt_pref purge` | Removes packages along with configuration files | -| `ar` | `sudo $apt_pref remove` | Removes packages, keeps the configuration files | -| `au` | `sudo $apt_pref $apt_upgr` | Install package upgrades | -| `di` | `sudo dpkg -i` | Install all .deb files in the current directory | -| `dia` | `sudo dpkg -i ./*.deb` | Install all .deb files in the current directory | -| `kclean` | `sudo aptitude remove -P ?and(~i~nlinux-(ima\|hea) ?not(~n$(uname -r)))` | Remove ALL kernel images and headers EXCEPT the one in use | +| Alias | Command | Description | +| -------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | +| `aac` | `sudo $apt_pref autoclean` | Clears out the local repository of retrieved package files | +| `aar` | `sudo $apt_pref autoremove` | Removes packages installed automatically that are no longer needed | +| `abd` | `sudo $apt_pref build-dep` | Installs all dependencies for building packages | +| `ac` | `sudo $apt_pref clean` | Clears out the local repository of retrieved package files except lock files | +| `ad` | `sudo $apt_pref update` | Updates the package lists for upgrades for packages | +| `adg` | `sudo $apt_pref update && sudo $apt_pref $apt_upgr` | Update and upgrade packages | +| `ads` | `sudo apt-get dselect-upgrade` | Installs packages from list and removes all not in the list | +| `adu` | `sudo $apt_pref update && sudo $apt_pref dist-upgrade` | Smart upgrade that handles dependencies | +| `afu` | `sudo apt-file update` | Update the files in packages | +| `ai` | `sudo $apt_pref install` | Command-line tool to install package | +| `ail` | `sed -e 's/ */ /g' -e 's/ *//' \| cut -s -d ' ' -f 1 \| xargs sudo $apt_pref install` | Install all packages given on the command line while using only the first word of each line | +| `alu` | `sudo apt update && apt list -u && sudo apt upgrade` | Update, list and upgrade packages | +| `ap` | `sudo $apt_pref purge` | Removes packages along with configuration files | +| `au` | `sudo $apt_pref $apt_upgr` | Install package upgrades | +| `di` | `sudo dpkg -i` | Install all .deb files in the current directory | +| `dia` | `sudo dpkg -i ./*.deb` | Install all .deb files in the current directory | +| `kclean` | `sudo aptitude remove -P ?and(~i~nlinux-(ima\|hea) ?not(~n$(uname -r)))` | Remove ALL kernel images and headers EXCEPT the one in use | ## Aliases - Commands using `su` diff --git a/plugins/debian/debian.plugin.zsh b/plugins/debian/debian.plugin.zsh index e4db8fe33..bab1ae1c6 100644 --- a/plugins/debian/debian.plugin.zsh +++ b/plugins/debian/debian.plugin.zsh @@ -26,7 +26,7 @@ alias age='apt-get' alias api='aptitude' # Some self-explanatory aliases -alias acs="apt-cache search" +alias acse="apt-cache search" alias aps='aptitude search' alias as="aptitude -F '* %p -> %d \n(%v/%V)' --no-gui --disable-columns search" @@ -51,11 +51,10 @@ if [[ $use_sudo -eq 1 ]]; then alias au="sudo $apt_pref $apt_upgr" alias ai="sudo $apt_pref install" # Install all packages given on the command line while using only the first word of each line: - # acs ... | ail + # acse ... | ail alias ail="sed -e 's/ */ /g' -e 's/ *//' | cut -s -d ' ' -f 1 | xargs sudo $apt_pref install" alias ap="sudo $apt_pref purge" - alias ar="sudo $apt_pref remove" alias aar="sudo $apt_pref autoremove" # apt-get only @@ -89,22 +88,17 @@ else alias afu="su -lc '$apt-file update'" alias au="su -lc '$apt_pref $apt_upgr' root" function ai() { - cmd="su -lc 'aptitude -P install $@' root" + cmd="su -lc '$apt_pref install $@' root" print "$cmd" eval "$cmd" } function ap() { - cmd="su -lc '$apt_pref -P purge $@' root" - print "$cmd" - eval "$cmd" - } - function ar() { - cmd="su -lc '$apt_pref -P remove $@' root" + cmd="su -lc '$apt_pref purge $@' root" print "$cmd" eval "$cmd" } function aar() { - cmd="su -lc '$apt_pref -P autoremove $@' root" + cmd="su -lc '$apt_pref autoremove $@' root" print "$cmd" eval "$cmd" } @@ -147,7 +141,6 @@ apt_pref_compdef au "$apt_upgr" apt_pref_compdef ai "install" apt_pref_compdef ail "install" apt_pref_compdef ap "purge" -apt_pref_compdef ar "remove" apt_pref_compdef aar "autoremove" apt_pref_compdef ads "dselect-upgrade" diff --git a/plugins/dnote/README.md b/plugins/dnote/README.md index e1b9b7044..7b41b9027 100644 --- a/plugins/dnote/README.md +++ b/plugins/dnote/README.md @@ -1,6 +1,6 @@ # Dnote Plugin -This plugin adds auto-completion for [Dnote](https://dnote.io) project. +This plugin adds auto-completion for [Dnote](https://www.getdnote.com/), a simple command line notebook. To use it, add `dnote` to the plugins array in your zshrc file: diff --git a/plugins/docker-compose/README.md b/plugins/docker-compose/README.md index 13f3c2cea..bbcff2e0c 100644 --- a/plugins/docker-compose/README.md +++ b/plugins/docker-compose/README.md @@ -11,22 +11,23 @@ plugins=(... docker-compose) ## Aliases -| Alias | Command | Description | -|-----------|--------------------------------|------------------------------------------------------------------| -| dco | `docker-compose` | Docker-compose main command | -| dcb | `docker-compose build` | Build containers | -| dce | `docker-compose exec` | Execute command inside a container | -| dcps | `docker-compose ps` | List containers | -| dcrestart | `docker-compose restart` | Restart container | -| dcrm | `docker-compose rm` | Remove container | -| dcr | `docker-compose run` | Run a command in container | -| dcstop | `docker-compose stop` | Stop a container | -| dcup | `docker-compose up` | Build, (re)create, start, and attach to containers for a service | -| dcupb | `docker-compose up --build` | Same as `dcup`, but build images before starting containers | -| dcupd | `docker-compose up -d` | Same as `dcup`, but starts as daemon | -| dcdn | `docker-compose down` | Stop and remove containers | -| dcl | `docker-compose logs` | Show logs of container | -| dclf | `docker-compose logs -f` | Show logs and follow output | -| dcpull | `docker-compose pull` | Pull image of a service | -| dcstart | `docker-compose start` | Start a container | -| dck | `docker-compose kill` | Kills containers | +| Alias | Command | Description | +|-----------|--------------------------------|----------------------------------------------------------------------------------| +| dco | `docker-compose` | Docker-compose main command | +| dcb | `docker-compose build` | Build containers | +| dce | `docker-compose exec` | Execute command inside a container | +| dcps | `docker-compose ps` | List containers | +| dcrestart | `docker-compose restart` | Restart container | +| dcrm | `docker-compose rm` | Remove container | +| dcr | `docker-compose run` | Run a command in container | +| dcstop | `docker-compose stop` | Stop a container | +| dcup | `docker-compose up` | Build, (re)create, start, and attach to containers for a service | +| dcupb | `docker-compose up --build` | Same as `dcup`, but build images before starting containers | +| dcupd | `docker-compose up -d` | Same as `dcup`, but starts as daemon | +| dcupdb | `docker-compose up -d --build` | Same as `dcup`, but build images before starting containers and starts as daemon | +| dcdn | `docker-compose down` | Stop and remove containers | +| dcl | `docker-compose logs` | Show logs of container | +| dclf | `docker-compose logs -f` | Show logs and follow output | +| dcpull | `docker-compose pull` | Pull image of a service | +| dcstart | `docker-compose start` | Start a container | +| dck | `docker-compose kill` | Kills containers | diff --git a/plugins/docker-compose/docker-compose.plugin.zsh b/plugins/docker-compose/docker-compose.plugin.zsh index b8a4b067d..7a8bf4a03 100644 --- a/plugins/docker-compose/docker-compose.plugin.zsh +++ b/plugins/docker-compose/docker-compose.plugin.zsh @@ -12,6 +12,7 @@ alias dcstop="$dccmd stop" alias dcup="$dccmd up" alias dcupb="$dccmd up --build" alias dcupd="$dccmd up -d" +alias dcupdb="$dccmd up -d --build" alias dcdn="$dccmd down" alias dcl="$dccmd logs" alias dclf="$dccmd logs -f" diff --git a/plugins/docker-machine/_docker-machine b/plugins/docker-machine/_docker-machine index fbd36d7c6..17bcd3598 100644 --- a/plugins/docker-machine/_docker-machine +++ b/plugins/docker-machine/_docker-machine @@ -335,9 +335,9 @@ _docker-machine() { '--tls-ca-key[Private key to generate certificates]:file:_files' \ '--tls-client-cert[Client cert to use for TLS]:file:_files' \ '--tls-client-key[Private key used in client TLS auth]:file:_files' \ - '--github-api-token[Token to use for requests to the Github API]' \ + '--github-api-token[Token to use for requests to the GitHub API]' \ '--native-ssh[Use the native (Go-based) SSH implementation.]' \ - '--bugsnag-api-token[BugSnag API token for crash reporting]' \ + '--bugsnag-api-token[Bugsnag API token for crash reporting]' \ '(- :)'{-v,--version}'[Print the version]' \ "(-): :->command" \ "(-)*:: :->option-or-argument" && ret=0 diff --git a/plugins/docker/README.md b/plugins/docker/README.md index 2b721c770..512b5d17c 100644 --- a/plugins/docker/README.md +++ b/plugins/docker/README.md @@ -13,18 +13,15 @@ https://github.com/docker/cli/blob/master/contrib/completion/zsh/_docker ## Settings -By default, the completion doesn't allow option-stacking, meaning if you try to -complete `docker run -it ` it won't work, because you're _stacking_ the -`-i` and `-t` options. +By default, the completion doesn't allow option-stacking, meaning if you try to complete +`docker run -it ` it won't work, because you're _stacking_ the `-i` and `-t` options. -[You can enable it](https://github.com/docker/cli/commit/b10fb43048) by **adding -the lines below to your zshrc file**, but be aware of the side effects: +[You can enable it](https://github.com/docker/cli/commit/b10fb43048) by **adding the lines below to your zshrc +file**, but be aware of the side effects: -> This enables Zsh to understand commands like `docker run -it -> ubuntu`. However, by enabling this, this also makes Zsh complete -> `docker run -u` with `docker run -uapprox` which is not valid. The -> users have to put the space or the equal sign themselves before trying -> to complete. +> This enables Zsh to understand commands like `docker run -it ubuntu`. However, by enabling this, this also +> makes Zsh complete `docker run -u` with `docker run -uapprox` which is not valid. The users have to put +> the space or the equal sign themselves before trying to complete. > > Therefore, this behavior is disabled by default. To enable it: > @@ -35,39 +32,38 @@ the lines below to your zshrc file**, but be aware of the side effects: ## Aliases -| Alias | Command | Description | -| :------ | :-------------------------- | :--------------------------------------------------------------------------------------- | -| dbl | `docker build` | Build an image from a Dockerfile | -| dcin | `docker container inspect` | Display detailed information on one or more containers | -| dlo | `docker container logs` | Fetch the logs of a docker container | -| dcls | `docker container ls` | List all the running docker containers | -| dclsa | `docker container ls -a` | List all running and stopped containers | -| dpo | `docker container port` | List port mappings or a specific mapping for the container | -| dpu | `docker pull` | Pull an image or a repository from a registry | -| dr | `docker container run` | Create a new container and start it using the specified command | -| 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 -f` | Force the removal of a running container (uses SIGKILL) | -| dst | `docker container start` | Start one or more stopped containers | -| dstp | `docker container stop` | Stop one or more running containers | -| dtop | `docker top` | Display the running processes of a container | -| dxc | `docker container exec` | Run a new command in a running container | -| dxcit | `docker container exec -it` | Run a new command in a running container in an interactive shell | -| | | **Docker Images** | -| 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 | -| dils | `docker image ls` | List docker images | -| dip | `docker image push` | Push an image or repository to a remote registry | -| dirm | `docker image rm` | Remove one or more images | -| dit | `docker image tag` | Add a name and tag to a particular image | -| | | **Docker Network** | -| dnc | `docker network create` | Create a new network | -| dncn | `docker network connect` | Connect a container to a network | -| dndcn | `docker network disconnect` | Disconnect a container from a network | -| 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 | -| dnrm | `docker network rm` | Remove one or more networks | -| | | **Docker Volume** | -| dvi | `docker volume inspect` | Display detailed information about one or more volumes | -| dvls | `docker volume ls` | List all the volumes known to docker | -| dvprune | `docker volume prune` | Cleanup dangling volumes | +| Alias | Command | Description | +| :------ | :---------------------------- | :--------------------------------------------------------------------------------------- | +| dbl | `docker build` | Build an image from a Dockerfile | +| dcin | `docker container inspect` | Display detailed information on one or more containers | +| dcls | `docker container ls` | List all the running docker containers | +| dclsa | `docker container ls -a` | List all running and stopped containers | +| 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 | +| dils | `docker image ls` | List docker images | +| dipu | `docker image push` | Push an image or repository to a remote registry | +| dirm | `docker image rm` | Remove one or more images | +| dit | `docker image tag` | Add a name and tag to a particular image | +| dlo | `docker container logs` | Fetch the logs of a docker container | +| dnc | `docker network create` | Create a new network | +| dncn | `docker network connect` | Connect a container to a network | +| dndcn | `docker network disconnect` | Disconnect a container from a network | +| 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 | +| dnrm | `docker network rm` | Remove one or more networks | +| dpo | `docker container port` | List port mappings or a specific mapping for the container | +| dpu | `docker pull` | Pull an image or a repository from a registry | +| dr | `docker container run` | Create a new container and start it using the specified command | +| 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 -f` | Force the removal of a running container (uses SIGKILL) | +| dst | `docker container start` | Start one or more stopped containers | +| drs | `docker container restart` | Restart one or more containers +| dsta | `docker stop $(docker ps -q)` | Stop all running containers | +| dstp | `docker container stop` | Stop one or more running containers | +| dtop | `docker top` | Display the running processes of a container | +| dvi | `docker volume inspect` | Display detailed information about one or more volumes | +| dvls | `docker volume ls` | List all the volumes known to docker | +| dvprune | `docker volume prune` | Cleanup dangling volumes | +| dxc | `docker container exec` | Run a new command in a running container | +| dxcit | `docker container exec -it` | Run a new command in a running container in an interactive shell | diff --git a/plugins/docker/_docker b/plugins/docker/_docker index 8ee35abcf..e6a12d774 100644 --- a/plugins/docker/_docker +++ b/plugins/docker/_docker @@ -567,7 +567,7 @@ __docker_container_commands() { "cp:Copy files/folders between a container and the local filesystem" "create:Create a new container" "diff:Inspect changes on a container's filesystem" - "exec:Run a command in a running container" + "exec:Execute a command in a running container" "export:Export a container's filesystem as a tar archive" "inspect:Display detailed information on one or more containers" "kill:Kill one or more running containers" @@ -579,7 +579,7 @@ __docker_container_commands() { "rename:Rename a container" "restart:Restart one or more containers" "rm:Remove one or more containers" - "run:Run a command in a new container" + "run:Create and run a new container from an image" "start:Start one or more stopped containers" "stats:Display a live stream of container(s) resource usage statistics" "stop:Stop one or more running containers" @@ -650,6 +650,7 @@ __docker_container_subcommand() { "($help)*"{-p=,--publish=}"[Expose a container's port to the host]:port:_ports" "($help)--pid=[PID namespace to use]:PID namespace:__docker_complete_pid" "($help)--privileged[Give extended privileges to this container]" + "($help -q --quiet)"{-q,--quiet}"[Suppress the pull output]" "($help)--read-only[Mount the container's root filesystem as read only]" "($help)*--security-opt=[Security options]:security option: " "($help)*--shm-size=[Size of '/dev/shm' (format is '')]:shm size: " @@ -802,7 +803,7 @@ __docker_container_subcommand() { "($help -a --all)"{-a,--all}"[Show all containers]" \ "($help)--before=[Show only container created before...]:containers:__docker_complete_containers" \ "($help)*"{-f=,--filter=}"[Filter values]:filter:__docker_complete_ps_filters" \ - "($help)--format=[Pretty-print containers using a Go template]:template: " \ + "($help)--format=[Format the output using the given Go template]:template: " \ "($help -l --latest)"{-l,--latest}"[Show only the latest created container]" \ "($help -n --last)"{-n=,--last=}"[Show n last created containers (includes all states)]:n:(1 5 10 25 50)" \ "($help)--no-trunc[Do not truncate output]" \ @@ -907,7 +908,7 @@ __docker_container_subcommand() { _arguments $(__docker_arguments) \ $opts_help \ "($help -a --all)"{-a,--all}"[Show all containers (default shows just running)]" \ - "($help)--format=[Pretty-print images using a Go template]:template: " \ + "($help)--format=[Format the output using the given Go template]:template: " \ "($help)--no-stream[Disable streaming stats and only pull the first result]" \ "($help)--no-trunc[Do not truncate output]" \ "($help -)*:containers:__docker_complete_running_containers" && ret=0 @@ -973,8 +974,8 @@ __docker_image_commands() { "load:Load an image from a tar archive or STDIN" "ls:List images" "prune:Remove unused images" - "pull:Pull an image or a repository from a registry" - "push:Push an image or a repository to a registry" + "pull:Download an image from a registry" + "push:Upload an image to a registry" "rm:Remove one or more images" "save:Save one or more images to a tar archive (streamed to STDOUT by default)" "tag:Tag an image into a repository" @@ -1060,7 +1061,7 @@ __docker_image_subcommand() { "($help -a --all)"{-a,--all}"[Show all images]" \ "($help)--digests[Show digests]" \ "($help)*"{-f=,--filter=}"[Filter values]:filter:__docker_complete_images_filters" \ - "($help)--format=[Pretty-print images using a Go template]:template: " \ + "($help)--format=[Format the output using the given Go template]:template: " \ "($help)--no-trunc[Do not truncate output]" \ "($help -q --quiet)"{-q,--quiet}"[Only show image IDs]" \ "($help -): :__docker_complete_repositories" && ret=0 @@ -1082,7 +1083,7 @@ __docker_image_subcommand() { (push) _arguments $(__docker_arguments) \ $opts_help \ - "($help -a --all-tags)"{-a,--all-tags}"[Push all tagged images in the repository]" \ + "($help -a --all-tags)"{-a,--all-tags}"[Push all tags of an image to the repository]" \ "($help)--disable-content-trust[Skip image signing]" \ "($help -): :__docker_complete_images" && ret=0 ;; @@ -1292,7 +1293,7 @@ __docker_network_subcommand() { $opts_help \ "($help)--no-trunc[Do not truncate the output]" \ "($help)*"{-f=,--filter=}"[Provide filter values]:filter:__docker_network_complete_ls_filters" \ - "($help)--format=[Pretty-print networks using a Go template]:template: " \ + "($help)--format=[Format the output using the given Go template]:template: " \ "($help -q --quiet)"{-q,--quiet}"[Only display network IDs]" && ret=0 ;; (prune) @@ -2050,7 +2051,7 @@ __docker_service_subcommand() { _arguments $(__docker_arguments) \ $opts_help \ "($help)*"{-f=,--filter=}"[Filter output based on conditions provided]:filter:__docker_service_complete_ls_filters" \ - "($help)--format=[Pretty-print services using a Go template]:template: " \ + "($help)--format=[Format the output using the given Go template]:template: " \ "($help -q --quiet)"{-q,--quiet}"[Only display IDs]" && ret=0 ;; (rm|remove) @@ -2253,7 +2254,7 @@ __docker_stack_subcommand() { _arguments $(__docker_arguments) \ $opts_help \ "($help)*"{-f=,--filter=}"[Filter output based on conditions provided]:filter:__docker_stack_complete_services_filters" \ - "($help)--format=[Pretty-print services using a Go template]:template: " \ + "($help)--format=[Format the output using the given Go template]:template: " \ "($help -q --quiet)"{-q,--quiet}"[Only display IDs]" \ "($help -):stack:__docker_complete_stacks" && ret=0 ;; @@ -2520,7 +2521,7 @@ __docker_volume_subcommand() { _arguments $(__docker_arguments) \ $opts_help \ "($help)*"{-f=,--filter=}"[Provide filter values]:filter:__docker_volume_complete_ls_filters" \ - "($help)--format=[Pretty-print volumes using a Go template]:template: " \ + "($help)--format=[Format the output using the given Go template]:template: " \ "($help -q --quiet)"{-q,--quiet}"[Only display volume names]" && ret=0 ;; (prune) @@ -2582,10 +2583,8 @@ __docker_context_subcommand() { (create) _arguments $(__docker_arguments) \ $opts_help \ - "($help)--default-stack-orchestrator=[Default orchestrator for stack operations to use with this context]:default-stack-orchestrator:(swarm kubernetes all)" \ "($help)--description=[Description of the context]:description:" \ "($help)--docker=[Set the docker endpoint]:docker:" \ - "($help)--kubernetes=[Set the kubernetes endpoint]:kubernetes:" \ "($help)--from=[Create context from a named context]:from:__docker_complete_contexts" \ "($help -):name: " && ret=0 ;; @@ -2607,10 +2606,8 @@ __docker_context_subcommand() { (update) _arguments $(__docker_arguments) \ $opts_help \ - "($help)--default-stack-orchestrator=[Default orchestrator for stack operations to use with this context]:default-stack-orchestrator:(swarm kubernetes all)" \ "($help)--description=[Description of the context]:description:" \ "($help)--docker=[Set the docker endpoint]:docker:" \ - "($help)--kubernetes=[Set the kubernetes endpoint]:kubernetes:" \ "($help -):name:" && ret=0 ;; esac @@ -2734,9 +2731,6 @@ __docker_subcommand() { "($help -b --bridge)"{-b=,--bridge=}"[Attach containers to a network bridge]:bridge:_net_interfaces" \ "($help)--bip=[Network bridge IP]:IP address: " \ "($help)--cgroup-parent=[Parent cgroup for all containers]:cgroup: " \ - "($help)--cluster-advertise=[Address or interface name to advertise]:Instance to advertise (host\:port): " \ - "($help)--cluster-store=[URL of the distributed storage backend]:Cluster Store:->cluster-store" \ - "($help)*--cluster-store-opt=[Cluster store options]:Cluster options:->cluster-store-options" \ "($help)--config-file=[Path to daemon configuration file]:Config File:_files" \ "($help)--containerd=[Path to containerd socket]:socket:_files -g \"*.sock\"" \ "($help)--containerd-namespace=[Containerd namespace to use]:containerd namespace:" \ @@ -2778,7 +2772,7 @@ __docker_subcommand() { "($help)--oom-score-adjust=[Set the oom_score_adj for the daemon]:oom-score:(-500)" \ "($help -p --pidfile)"{-p=,--pidfile=}"[Path to use for daemon PID file]:PID file:_files" \ "($help)--raw-logs[Full timestamps without ANSI coloring]" \ - "($help)*--registry-mirror=[Preferred Docker registry mirror]:registry mirror: " \ + "($help)*--registry-mirror=[Preferred registry mirror]:registry mirror: " \ "($help)--seccomp-profile=[Path to seccomp profile]:path:_files -g \"*.json\"" \ "($help -s --storage-driver)"{-s=,--storage-driver=}"[Storage driver to use]:driver:(aufs btrfs devicemapper overlay overlay2 vfs zfs)" \ "($help)--selinux-enabled[Enable selinux support]" \ @@ -2795,22 +2789,6 @@ __docker_subcommand() { "($help)--validate[Validate daemon configuration and exit]" && ret=0 case $state in - (cluster-store) - if compset -P '*://'; then - _message 'host:port' && ret=0 - else - store=('consul' 'etcd' 'zk') - _describe -t cluster-store "Cluster Store" store -qS "://" && ret=0 - fi - ;; - (cluster-store-options) - if compset -P '*='; then - _files && ret=0 - else - opts=('discovery.heartbeat' 'discovery.ttl' 'kv.cacertfile' 'kv.certfile' 'kv.keyfile' 'kv.path') - _describe -t cluster-store-opts "Cluster Store Options" opts -qS "=" && ret=0 - fi - ;; (users-groups) if compset -P '*:'; then _groups && ret=0 @@ -3095,6 +3073,7 @@ _docker() { _arguments $(__docker_arguments) -C \ "(: -)"{-h,--help}"[Print usage]" \ "($help)--config[Location of client config files]:path:_directories" \ + "($help -c --context)"{-c=,--context=}"[Execute the command in a docker context]:context:__docker_complete_contexts" \ "($help -D --debug)"{-D,--debug}"[Enable debug mode]" \ "($help -H --host)"{-H=,--host=}"[tcp://host:port to bind/connect to]:host: " \ "($help -l --log-level)"{-l=,--log-level=}"[Logging level]:level:(debug info warn error fatal)" \ @@ -3110,7 +3089,8 @@ _docker() { local host=${opt_args[-H]}${opt_args[--host]} local config=${opt_args[--config]} - local docker_options="${host:+--host $host} ${config:+--config $config}" + local context=${opt_args[-c]}${opt_args[--context]} + local docker_options="${host:+--host $host} ${config:+--config $config} ${context:+--context $context} " case $state in (command) diff --git a/plugins/docker/docker.plugin.zsh b/plugins/docker/docker.plugin.zsh index 843c8e241..8684a9785 100644 --- a/plugins/docker/docker.plugin.zsh +++ b/plugins/docker/docker.plugin.zsh @@ -1,39 +1,33 @@ alias dbl='docker build' -alias dpu='docker pull' -alias dtop='docker top' - -# docker containers alias dcin='docker container inspect' -alias dlo='docker container logs' alias dcls='docker container ls' alias dclsa='docker container ls -a' -alias dpo='docker container port' -alias dr='docker container run' -alias drit='docker container run -it' -alias drm='docker container rm' -alias 'drm!'='docker container rm -f' -alias dst='docker container start' -alias dstp='docker container stop' -alias dxc='docker container exec' -alias dxcit='docker container exec -it' - -# docker images alias dib='docker image build' alias dii='docker image inspect' alias dils='docker image ls' -alias dip='docker image push' +alias dipu='docker image push' alias dirm='docker image rm' alias dit='docker image tag' - -# docker network +alias dlo='docker container logs' alias dnc='docker network create' alias dncn='docker network connect' alias dndcn='docker network disconnect' alias dni='docker network inspect' alias dnls='docker network ls' alias dnrm='docker network rm' - -# docker volume +alias dpo='docker container port' +alias dpu='docker pull' +alias dr='docker container run' +alias drit='docker container run -it' +alias drm='docker container rm' +alias 'drm!'='docker container rm -f' +alias dst='docker container start' +alias drs='docker container restart' +alias dsta='docker stop $(docker ps -q)' +alias dstp='docker container stop' +alias dtop='docker top' alias dvi='docker volume inspect' alias dvls='docker volume ls' alias dvprune='docker volume prune' +alias dxc='docker container exec' +alias dxcit='docker container exec -it' diff --git a/plugins/doctl/doctl.plugin.zsh b/plugins/doctl/doctl.plugin.zsh index d23ed085c..7b3a384a9 100644 --- a/plugins/doctl/doctl.plugin.zsh +++ b/plugins/doctl/doctl.plugin.zsh @@ -4,6 +4,14 @@ # # Author: https://github.com/HalisCz -if [ $commands[doctl] ]; then - source <(doctl completion zsh) +if (( ! $+commands[doctl] )); then + return fi + +if [[ ! -f "$ZSH_CACHE_DIR/completions/_doctl" ]]; then + typeset -g -A _comps + autoload -Uz _doctl + _comps[doctl]=_doctl +fi + +doctl completion zsh >| "$ZSH_CACHE_DIR/completions/_doctl" &| diff --git a/plugins/dotnet/README.md b/plugins/dotnet/README.md index 87dfd8f8d..a15e80577 100644 --- a/plugins/dotnet/README.md +++ b/plugins/dotnet/README.md @@ -17,6 +17,7 @@ plugins=(... dotnet) | dt | dotnet test | Run unit tests using the test runner specified in a .NET project. | | dw | dotnet watch | Watch for source file changes and restart the dotnet command. | | dwr | dotnet watch run | Watch for source file changes and restart the `run` command. | +| dwt | dotnet watch test| Watch for source file changes and restart the `test` command. | | ds | dotnet sln | Modify Visual Studio solution files. | | da | dotnet add | Add a package or reference to a .NET project. | | dp | dotnet pack | Create a NuGet package. | diff --git a/plugins/dotnet/dotnet.plugin.zsh b/plugins/dotnet/dotnet.plugin.zsh index 8ea31cdbd..89d464670 100644 --- a/plugins/dotnet/dotnet.plugin.zsh +++ b/plugins/dotnet/dotnet.plugin.zsh @@ -26,6 +26,7 @@ alias dr='dotnet run' alias dt='dotnet test' alias dw='dotnet watch' alias dwr='dotnet watch run' +alias dwt='dotnet watch test' alias ds='dotnet sln' alias da='dotnet add' alias dp='dotnet pack' diff --git a/plugins/emacs/README.md b/plugins/emacs/README.md index c8e33b5ab..8ed4a1473 100644 --- a/plugins/emacs/README.md +++ b/plugins/emacs/README.md @@ -25,6 +25,6 @@ The plugin uses a custom launcher (which we'll call here `$EMACS_LAUNCHER`) that | e | `emacs` | Same as emacs alias | | te | `$EMACS_LAUNCHER -nw` | Open terminal emacsclient | | eeval | `$EMACS_LAUNCHER --eval` | Same as `M-x eval` but from outside Emacs | -| eframe | `emacsclient --alternate-editor "" --create-frame` | Create new X frame | +| eframe | `emacsclient --alternate-editor="" --create-frame` | Create new X frame | | efile | - | Print the path to the file open in the current buffer | | ecd | - | Print the directory of the file open in the the current buffer | diff --git a/plugins/emacs/emacs.plugin.zsh b/plugins/emacs/emacs.plugin.zsh index fede5b0c4..4747f035b 100644 --- a/plugins/emacs/emacs.plugin.zsh +++ b/plugins/emacs/emacs.plugin.zsh @@ -32,7 +32,7 @@ alias te="$EMACS_PLUGIN_LAUNCHER -nw" # same than M-x eval but from outside Emacs. alias eeval="$EMACS_PLUGIN_LAUNCHER --eval" # create a new X frame -alias eframe='emacsclient --alternate-editor "" --create-frame' +alias eframe='emacsclient --alternate-editor="" --create-frame' # Emacs ANSI Term tracking if [[ -n "$INSIDE_EMACS" ]]; then diff --git a/plugins/emacs/emacsclient.sh b/plugins/emacs/emacsclient.sh index 25efe0d68..172c0ae96 100755 --- a/plugins/emacs/emacsclient.sh +++ b/plugins/emacs/emacsclient.sh @@ -11,15 +11,15 @@ emacsfun() { esac # Check if there are suitable frames - frames="$(emacsclient -a '' -n -e "$cmd" 2>/dev/null)" + frames="$(emacsclient -a '' -n -e "$cmd" 2>/dev/null |sed 's/.*\x07//g' )" # Only create another X frame if there isn't one present if [ -z "$frames" -o "$frames" = nil ]; then - emacsclient --alternate-editor "" --create-frame "$@" + emacsclient --alternate-editor="" --create-frame "$@" return $? fi - emacsclient --alternate-editor "" "$@" + emacsclient --alternate-editor="" "$@" } # Adapted from https://github.com/davidshepherd7/emacs-read-stdin/blob/master/emacs-read-stdin.sh diff --git a/plugins/emoji/update_emoji.py b/plugins/emoji/update_emoji.py index eb945b9ef..18b3c060d 100644 --- a/plugins/emoji/update_emoji.py +++ b/plugins/emoji/update_emoji.py @@ -56,7 +56,7 @@ typeset -gAH emoji_groups # def country_iso(_all_names, _omz_name): # """ Using the external library country_converter, -# this funciton can detect the ISO2 and ISO3 codes +# this function can detect the ISO2 and ISO3 codes # of the country. It takes as argument the array # with all the names of the emoji, and returns that array.""" # omz_no_underscore = re.sub(r'_', r' ', _omz_name) @@ -96,7 +96,7 @@ def name_to_omz(_name, _group, _subgroup, _status): # Special treatment by status # Enables us to have every emoji combination, # even the one that are not officially sanctionned - # and are implemeted by, say, only one vendor + # and are implemented by, say, only one vendor if _status == "unqualified": shortname += "_unqualified" elif _status == "minimally-qualified": diff --git a/plugins/encode64/README.md b/plugins/encode64/README.md index 86320cffb..7cdf8c3f3 100644 --- a/plugins/encode64/README.md +++ b/plugins/encode64/README.md @@ -10,10 +10,11 @@ plugins=(... encode64) ## Functions and Aliases -| Function | Alias | Description | -| ---------- | ----- | ------------------------------ | -| `encode64` | `e64` | Encodes given data to base64 | -| `decode64` | `d64` | Decodes given data from base64 | +| Function | Alias | Description | +| -------------- | ------ | -------------------------------------- | +| `encode64` | `e64` | Encodes given data to base64 | +| `encodefile64` | `ef64` | Encodes given file's content to base64 | +| `decode64` | `d64` | Decodes given data from base64 | ## Usage and examples @@ -37,6 +38,20 @@ plugins=(... encode64) b2gtbXktenNo== ``` +### Encoding a file + +Encode a file's contents to base64 and save output to text file. +**NOTE:** Takes provided file and saves encoded content as new file with `.txt` extension + +- From parameter + + ```console + $ encodefile64 ohmyzsh.icn + ohmyzsh.icn's content encoded in base64 and saved as ohmyzsh.icn.txt + $ ef64 "oh-my-zsh" + ohmyzsh.icn's content encoded in base64 and saved as ohmyzsh.icn.txt + ``` + ### Decoding - From parameter diff --git a/plugins/encode64/encode64.plugin.zsh b/plugins/encode64/encode64.plugin.zsh index 979e06742..6927f5216 100644 --- a/plugins/encode64/encode64.plugin.zsh +++ b/plugins/encode64/encode64.plugin.zsh @@ -6,6 +6,15 @@ encode64() { fi } +encodefile64() { + if [[ $# -eq 0 ]]; then + echo "You must provide a filename" + else + base64 -i $1 -o $1.txt + echo "${1}'s content encoded in base64 and saved as ${1}.txt" + fi +} + decode64() { if [[ $# -eq 0 ]]; then cat | base64 --decode @@ -14,4 +23,5 @@ decode64() { fi } alias e64=encode64 +alias ef64=encodefile64 alias d64=decode64 diff --git a/plugins/extract/README.md b/plugins/extract/README.md index 44f0b05a1..ac4a8e197 100644 --- a/plugins/extract/README.md +++ b/plugins/extract/README.md @@ -1,10 +1,10 @@ # extract plugin -This plugin defines a function called `extract` that extracts the archive file -you pass it, and it supports a wide variety of archive filetypes. +This plugin defines a function called `extract` that extracts the archive file you pass it, and it supports a +wide variety of archive filetypes. -This way you don't have to know what specific command extracts a file, you just -do `extract ` and the function takes care of the rest. +This way you don't have to know what specific command extracts a file, you just do `extract ` and +the function takes care of the rest. To use it, add `extract` to the plugins array in your zshrc file: @@ -15,7 +15,7 @@ plugins=(... extract) ## Supported file extensions | Extension | Description | -|:------------------|:-------------------------------------| +| :---------------- | :----------------------------------- | | `7z` | 7zip file | | `Z` | Z archive (LZW) | | `apk` | Android app file | @@ -32,6 +32,7 @@ plugins=(... extract) | `lrz` | LRZ archive | | `lz4` | LZ4 archive | | `lzma` | LZMA archive | +| `obscpio` | cpio archive used on OBS | | `rar` | WinRAR archive | | `rpm` | RPM package | | `sublime-package` | Sublime Text package | @@ -55,6 +56,7 @@ plugins=(... extract) | `xz` | LZMA2 archive | | `zip` | Zip archive | | `zst` | Zstandard file (zstd) | +| `zpaq` | Zpaq file | -See [list of archive formats](https://en.wikipedia.org/wiki/List_of_archive_formats) for -more information regarding archive formats. +See [list of archive formats](https://en.wikipedia.org/wiki/List_of_archive_formats) for more information +regarding archive formats. diff --git a/plugins/extract/_extract b/plugins/extract/_extract index 27b099c9e..56b17058f 100644 --- a/plugins/extract/_extract +++ b/plugins/extract/_extract @@ -3,5 +3,5 @@ _arguments \ '(-r --remove)'{-r,--remove}'[Remove archive.]' \ - "*::archive file:_files -g '(#i)*.(7z|Z|apk|aar|bz2|cab|cpio|deb|ear|gz|ipa|ipsw|jar|lrz|lz4|lzma|rar|rpm|sublime-package|tar|tar.bz2|tar.gz|tar.lrz|tar.lz|tar.lz4|tar.xz|tar.zma|tar.zst|tbz|tbz2|tgz|tlz|txz|tzst|war|whl|xpi|xz|zip|zst)(-.)'" \ + "*::archive file:_files -g '(#i)*.(7z|Z|apk|aar|bz2|cab|cpio|deb|ear|gz|ipa|ipsw|jar|lrz|lz4|lzma|obscpio|rar|rpm|sublime-package|tar|tar.bz2|tar.gz|tar.lrz|tar.lz|tar.lz4|tar.xz|tar.zma|tar.zst|tbz|tbz2|tgz|tlz|txz|tzst|war|whl|xpi|xz|zip|zst|zpaq)(-.)'" \ && return 0 diff --git a/plugins/extract/extract.plugin.zsh b/plugins/extract/extract.plugin.zsh index 1112dd52f..34c080653 100644 --- a/plugins/extract/extract.plugin.zsh +++ b/plugins/extract/extract.plugin.zsh @@ -29,57 +29,93 @@ EOF local success=0 local extract_dir="${1:t:r}" local file="$1" full_path="${1:A}" + + # Create an extraction directory based on the file name + command mkdir -p "$extract_dir" + builtin cd -q "$extract_dir" + case "${file:l}" in - (*.tar.gz|*.tgz) (( $+commands[pigz] )) && { pigz -dc "$file" | tar xv } || tar zxvf "$file" ;; - (*.tar.bz2|*.tbz|*.tbz2) tar xvjf "$file" ;; + (*.tar.gz|*.tgz) + (( $+commands[pigz] )) && { tar -I pigz -xvf "$full_path" } || tar zxvf "$full_path" ;; + (*.tar.bz2|*.tbz|*.tbz2) + (( $+commands[pbzip2] )) && { tar -I pbzip2 -xvf "$full_path" } || tar xvjf "$full_path" ;; (*.tar.xz|*.txz) + (( $+commands[pixz] )) && { tar -I pixz -xvf "$full_path" } || { tar --xz --help &> /dev/null \ - && tar --xz -xvf "$file" \ - || xzcat "$file" | tar xvf - ;; + && tar --xz -xvf "$full_path" \ + || xzcat "$full_path" | tar xvf - } ;; (*.tar.zma|*.tlz) tar --lzma --help &> /dev/null \ - && tar --lzma -xvf "$file" \ - || lzcat "$file" | tar xvf - ;; + && tar --lzma -xvf "$full_path" \ + || lzcat "$full_path" | tar xvf - ;; (*.tar.zst|*.tzst) tar --zstd --help &> /dev/null \ - && tar --zstd -xvf "$file" \ - || zstdcat "$file" | tar xvf - ;; - (*.tar) tar xvf "$file" ;; - (*.tar.lz) (( $+commands[lzip] )) && tar xvf "$file" ;; - (*.tar.lz4) lz4 -c -d "$file" | tar xvf - ;; - (*.tar.lrz) (( $+commands[lrzuntar] )) && lrzuntar "$file" ;; - (*.gz) (( $+commands[pigz] )) && pigz -dk "$file" || gunzip -k "$file" ;; - (*.bz2) bunzip2 "$file" ;; - (*.xz) unxz "$file" ;; - (*.lrz) (( $+commands[lrunzip] )) && lrunzip "$file" ;; - (*.lz4) lz4 -d "$file" ;; - (*.lzma) unlzma "$file" ;; - (*.z) uncompress "$file" ;; - (*.zip|*.war|*.jar|*.ear|*.sublime-package|*.ipa|*.ipsw|*.xpi|*.apk|*.aar|*.whl) unzip "$file" -d "$extract_dir" ;; - (*.rar) unrar x -ad "$file" ;; + && tar --zstd -xvf "$full_path" \ + || zstdcat "$full_path" | tar xvf - ;; + (*.tar) tar xvf "$full_path" ;; + (*.tar.lz) (( $+commands[lzip] )) && tar xvf "$full_path" ;; + (*.tar.lz4) lz4 -c -d "$full_path" | tar xvf - ;; + (*.tar.lrz) (( $+commands[lrzuntar] )) && lrzuntar "$full_path" ;; + (*.gz) (( $+commands[pigz] )) && pigz -dk "$full_path" || gunzip -k "$full_path" ;; + (*.bz2) bunzip2 "$full_path" ;; + (*.xz) unxz "$full_path" ;; + (*.lrz) (( $+commands[lrunzip] )) && lrunzip "$full_path" ;; + (*.lz4) lz4 -d "$full_path" ;; + (*.lzma) unlzma "$full_path" ;; + (*.z) uncompress "$full_path" ;; + (*.zip|*.war|*.jar|*.ear|*.sublime-package|*.ipa|*.ipsw|*.xpi|*.apk|*.aar|*.whl) unzip "$full_path" ;; + (*.rar) unrar x -ad "$full_path" ;; (*.rpm) - command mkdir -p "$extract_dir" && builtin cd -q "$extract_dir" \ - && rpm2cpio "$full_path" | cpio --quiet -id ;; - (*.7z) 7za x "$file" ;; + rpm2cpio "$full_path" | cpio --quiet -id ;; + (*.7z) 7za x "$full_path" ;; (*.deb) - command mkdir -p "$extract_dir/control" "$extract_dir/data" - builtin cd -q "$extract_dir"; ar vx "$full_path" > /dev/null + command mkdir -p "control" "data" + ar vx "$full_path" > /dev/null builtin cd -q control; extract ../control.tar.* builtin cd -q ../data; extract ../data.tar.* builtin cd -q ..; command rm *.tar.* debian-binary ;; - (*.zst) unzstd "$file" ;; - (*.cab) cabextract -d "$extract_dir" "$file" ;; - (*.cpio) cpio -idmvF "$file" ;; + (*.zst) unzstd "$full_path" ;; + (*.cab) cabextract "$full_path" ;; + (*.cpio|*.obscpio) cpio -idmvF "$full_path" ;; + (*.zpaq) zpaq x "$full_path" ;; (*) echo "extract: '$file' cannot be extracted" >&2 success=1 ;; esac (( success = success > 0 ? success : $? )) - (( success == 0 && remove_archive == 0 )) && rm "$full_path" + (( success == 0 && remove_archive == 0 )) && command rm "$full_path" shift - # Go back to original working directory in case we ran cd previously + # Go back to original working directory builtin cd -q "$pwd" + + # If content of extract dir is a single directory, move its contents up + # Glob flags: + # - D: include files starting with . + # - N: no error if directory is empty + # - Y2: at most give 2 files + local -a content + content=("${extract_dir}"/*(DNY2)) + if [[ ${#content} -eq 1 && -d "${content[1]}" ]]; then + # The extracted folder (${content[1]}) may have the same name as $extract_dir + # If so, we need to rename it to avoid conflicts in a 3-step process + # + # 1. Move and rename the extracted folder to a temporary random name + # 2. Delete the empty folder + # 3. Rename the extracted folder to the original name + if [[ "${content[1]:t}" == "$extract_dir" ]]; then + # =(:) gives /tmp/zsh, with :t it gives zsh + local tmp_dir==(:); tmp_dir="${tmp_dir:t}" + command mv -f "${content[1]}" "$tmp_dir" \ + && command rmdir "$extract_dir" \ + && command mv -f "$tmp_dir" "$extract_dir" + else + command mv -f "${content[1]}" . \ + && command rmdir "$extract_dir" + fi + elif [[ ${#content} -eq 0 ]]; then + command rmdir "$extract_dir" + fi done } diff --git a/plugins/fasd/README.md b/plugins/fasd/README.md index a5c74e5b8..7c44ac84d 100644 --- a/plugins/fasd/README.md +++ b/plugins/fasd/README.md @@ -10,7 +10,7 @@ plugins=(... fasd) ## Installation -Please find detailed installation guide [`here`](https://github.com/clvv/fasd#install) +Please find detailed installation guide [`here`](https://github.com/whjvenyl/fasd#install) ## Aliases diff --git a/plugins/flutter/_flutter b/plugins/flutter/_flutter deleted file mode 100644 index ab6ce4265..000000000 --- a/plugins/flutter/_flutter +++ /dev/null @@ -1,37 +0,0 @@ -#compdef flutter -#autoload - -local -a _1st_arguments -_1st_arguments=( - "analyze":"Analyze the project's Dart code." - "assemble":"Assemble and build flutter resources." - "attach":"Attach to a running application." - "build":"Flutter build commands." - "channel":"List or switch flutter channels." - "clean":"Delete the build/ and .dart_tool/ directories." - "config":"Configure Flutter settings." - "create":"Create a new Flutter project." - "devices":"List all connected devices." - "doctor":"Show information about the installed tooling." - "drive":"Runs Flutter Driver tests for the current project." - "emulators":"List, launch and create emulators." - "format":" Format one or more dart files." - "help":"Display help information for flutter." - "install":"Install a Flutter app on an attached device." - "logs":"Show log output for running Flutter apps." - "make-host-app-editable":"Moves host apps from generated directories to non-generated directories so that they can be edited by developers." - "precache":"Populates the Flutter tool's cache of binary artifacts." - "pub":"Commands for managing Flutter packages." - "run":"Run your Flutter app on an attached device." - "screenshot":"Take a screenshot from a connected device." - "test":"Run Flutter unit tests for the current project." - "upgrade":"Upgrade your copy of Flutter." - "version":"List or switch flutter versions." -) - -_arguments -C '*:: :->subcmds' - -if (( CURRENT == 1 )); then - _describe -t commands "flutter command" _1st_arguments - return -fi diff --git a/plugins/flutter/flutter.plugin.zsh b/plugins/flutter/flutter.plugin.zsh index 80b74f64a..44d196cd4 100644 --- a/plugins/flutter/flutter.plugin.zsh +++ b/plugins/flutter/flutter.plugin.zsh @@ -12,3 +12,18 @@ alias flrd="flutter run --debug" alias flrp="flutter run --profile" alias flrr="flutter run --release" alias flupgrd="flutter upgrade" + +# COMPLETION FUNCTION +if (( ! $+commands[flutter] )); then + return +fi + +# If the completion file doesn't exist yet, we need to autoload it and +# bind it to `flutter`. Otherwise, compinit will have already done that. +if [[ ! -f "$ZSH_CACHE_DIR/completions/_flutter" ]]; then + typeset -g -A _comps + autoload -Uz _flutter + _comps[flutter]=_flutter +fi + +flutter zsh-completion >| "$ZSH_CACHE_DIR/completions/_flutter" &| \ No newline at end of file diff --git a/plugins/fluxcd/README.md b/plugins/fluxcd/README.md new file mode 100644 index 000000000..9723fcc6b --- /dev/null +++ b/plugins/fluxcd/README.md @@ -0,0 +1,9 @@ +# FluxCD plugin + +This plugin adds completion for [FluxCD](https://fluxcd.io), an open and extensible continuous delivery solution for Kubernetes. Powered by GitOps Toolkit. + +To use it, add `fluxcd` to the plugins array in your zshrc file: + +```zsh +plugins=(... fluxcd) +``` diff --git a/plugins/fluxcd/fluxcd.plugin.zsh b/plugins/fluxcd/fluxcd.plugin.zsh new file mode 100644 index 000000000..d30866a06 --- /dev/null +++ b/plugins/fluxcd/fluxcd.plugin.zsh @@ -0,0 +1,14 @@ +# Autocompletion for the FluxCD CLI (flux). +if (( ! $+commands[flux] )); then + return +fi + +# If the completion file doesn't exist yet, we need to autoload it and +# bind it to `flux`. Otherwise, compinit will have already done that. +if [[ ! -f "$ZSH_CACHE_DIR/completions/_flux" ]]; then + typeset -g -A _comps + autoload -Uz _flux + _comps[flux]=_flux +fi + +flux completion zsh >| "$ZSH_CACHE_DIR/completions/_flux" &| diff --git a/plugins/fossil/fossil.plugin.zsh b/plugins/fossil/fossil.plugin.zsh index a2123f415..fadf6095d 100644 --- a/plugins/fossil/fossil.plugin.zsh +++ b/plugins/fossil/fossil.plugin.zsh @@ -13,12 +13,11 @@ ZSH_THEME_FOSSIL_PROMPT_DIRTY=" %{$fg_bold[red]%}✖" ZSH_THEME_FOSSIL_PROMPT_CLEAN=" %{$fg_bold[green]%}✔" function fossil_prompt_info() { - local info=$(fossil branch 2>&1) + local branch=$(fossil branch current 2>&1) # if we're not in a fossil repo, don't show anything - ! command grep -q "use --repo" <<< "$info" || return + ! command grep -q "use --repo" <<< "$branch" || return - local branch=$(echo $info | grep "* " | sed 's/* //g') local changes=$(fossil changes) local dirty="$ZSH_THEME_FOSSIL_PROMPT_CLEAN" diff --git a/plugins/frontend-search/_frontend b/plugins/frontend-search/_frontend index 15f8d239d..aca4920d7 100644 --- a/plugins/frontend-search/_frontend +++ b/plugins/frontend-search/_frontend @@ -37,7 +37,7 @@ function _frontend() { 'lodash: Search in Lo-Dash website' 'mdn: Search in MDN website' 'nodejs: Search in NodeJS website' - 'npmjs: Search in NPMJS website' + 'npmjs: Search in npmjs website' 'packagephobia: Search in Packagephobia website' 'qunit: Search in Qunit website' 'reactjs: Search in React website' diff --git a/plugins/fzf/fzf.plugin.zsh b/plugins/fzf/fzf.plugin.zsh index a946cf762..b253a23d2 100644 --- a/plugins/fzf/fzf.plugin.zsh +++ b/plugins/fzf/fzf.plugin.zsh @@ -9,6 +9,7 @@ function fzf_setup_using_base_dir() { "${HOME}/.nix-profile/share/fzf" "${XDG_DATA_HOME:-$HOME/.local/share}/fzf" "/usr/local/opt/fzf" + "/opt/homebrew/opt/fzf" "/usr/share/fzf" "/usr/local/share/examples/fzf" ) @@ -59,8 +60,8 @@ function fzf_setup_using_base_dir() { function fzf_setup_using_debian() { - if (( ! $+commands[dpkg] )) || ! dpkg -s fzf &>/dev/null; then - # Either not a debian based distro, or no fzf installed + if (( ! $+commands[apt] && ! $+commands[apt-get] )); then + # Not a debian based distro return 1 fi @@ -71,11 +72,19 @@ function fzf_setup_using_debian() { case $PREFIX in *com.termux*) + if [[ ! -f "${PREFIX}/bin/fzf" ]]; then + # fzf not installed + return 1 + fi # Support Termux package completions="${PREFIX}/share/fzf/completion.zsh" key_bindings="${PREFIX}/share/fzf/key-bindings.zsh" ;; *) + if [[ ! -d /usr/share/doc/fzf/examples ]]; then + # fzf not installed + return 1 + fi # Determine completion file path: first bullseye/sid, then buster/stretch completions="/usr/share/doc/fzf/examples/completion.zsh" [[ -f "$completions" ]] || completions="/usr/share/zsh/vendor-completions/_fzf" @@ -178,7 +187,7 @@ function fzf_setup_using_macports() { (( $+commands[fzf] )) || return 1 # The fzf-zsh-completion package installs the auto-completion in - local completions="/opt/local/share/zsh/site-functions/fzf" + local completions="/opt/local/share/fzf/shell/completion.zsh" # The fzf-zsh-completion package installs the key-bindings file in local key_bindings="/opt/local/share/fzf/shell/key-bindings.zsh" diff --git a/plugins/gb/README.md b/plugins/gb/README.md deleted file mode 100644 index 822c29aaa..000000000 --- a/plugins/gb/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# `gb` plugin - -> A project based build tool for the Go programming language. - -See https://getgb.io for the full `gb` documentation - -* * * * - -- Adds completion support for all `gb` commands. -- Also supports completion for the [`gb-vendor` plugin](https://godoc.org/github.com/constabulary/gb/cmd/gb-vendor). - -To use it, add `gb` to your plugins array: -```sh -plugins=(... gb) -``` - -## Caveats - -The `git` plugin defines an alias `gb` that usually conflicts with the `gb` program. -If you're having trouble with it, remove it by adding `unalias gb` at the end of your -zshrc file. diff --git a/plugins/gb/_gb b/plugins/gb/_gb deleted file mode 100644 index 8148adf16..000000000 --- a/plugins/gb/_gb +++ /dev/null @@ -1,111 +0,0 @@ -#compdef gb -#autoload - -_gb () { - local ret=1 state - _arguments -C ':command:->command' '*::options:->options' && ret=0 - - case $state in - (command) - local -a subcommands - subcommands=( - "build:build a package" - "doc:show documentation for a package or symbol" - "env:print project environment variables" - "generate:generate Go files by processing source" - "help:displays the help" - "info:info returns information about this project" - "list:list the packages named by the importpaths" - "test:test packages" - "vendor:manage your vendored dependencies" - ) - _describe -t subcommands 'gb subcommands' subcommands && ret=0 - ;; - (options) - case $line[1] in - (build) - _arguments \ - -f'[ignore cached packages]' \ - -F'[do not cache packages]' \ - -q'[decreases verbosity]' \ - -P'[the number of build jobs to run in parallel]' \ - -R'[sets the base of the project root search path]' \ - -dotfile'[output a dot formatted file of the build steps]' \ - -ldflags'["flag list" arguments to pass to the linker]' \ - -gcflags'["arg list" arguments to pass to the compiler]' \ - -race'[enable data race detection]' \ - -tags'["tag list" additional build tags]' - ;; - (list) - _arguments \ - -f'[alternate format for the list, using the syntax of package template]' \ - -s'[read format template from STDIN]' \ - -json'[prints output in structured JSON format]' - ;; - (test) - _arguments \ - -v'[print output from test subprocess]' \ - -ldflags'["flag list" arguments to pass to the linker]' \ - -gcflags'["arg list" arguments to pass to the compiler]' \ - -race'[enable data race detection]' \ - -tags'["tag list" additional build tags]' - ;; - (vendor) - _gb-vendor - esac - ;; - esac - - return ret -} - -_gb-vendor () { - local curcontext="$curcontext" state line - _arguments -C ':command:->command' '*::options:->options' - - case $state in - (command) - local -a subcommands - subcommands=( - 'delete:deletes a local dependency' - 'fetch:fetch a remote dependency' - 'list:lists dependencies, one per line' - 'purge:remove all unreferenced dependencies' - 'restore:restore dependencies from the manifest' - 'update:update a local dependency' - ) - _describe -t subcommands 'gb vendor subcommands' subcommands && ret=0 - ;; - (options) - case $line[1] in - (delete) - _arguments \ - -all'[remove all dependencies]' - ;; - (fetch) - _arguments \ - -branch'[fetch from a particular branch]' \ - -no-recurse'[do not fetch recursively]' \ - -tag'[fetch the specified tag]' \ - -revision'[fetch the specific revision from the branch (if supplied)]' \ - -precaire'[allow the use of insecure protocols]' \ - ;; - (list) - _arguments \ - -f'[controls the template used for printing each manifest entry]' - ;; - (restore) - _arguments \ - -precaire'[allow the use of insecure protocols]' - ;; - (update) - _arguments \ - -all'[update all dependencies in the manifest or supply a given dependency]' \ - -precaire'[allow the use of insecure protocols]' - ;; - esac - ;; - esac -} - -_gb diff --git a/plugins/gcloud/gcloud.plugin.zsh b/plugins/gcloud/gcloud.plugin.zsh index 7368eb3a6..30f1dba8f 100644 --- a/plugins/gcloud/gcloud.plugin.zsh +++ b/plugins/gcloud/gcloud.plugin.zsh @@ -10,8 +10,11 @@ if [[ -z "${CLOUDSDK_HOME}" ]]; then "/opt/homebrew/Caskroom/google-cloud-sdk/latest/google-cloud-sdk" "/usr/share/google-cloud-sdk" "/snap/google-cloud-sdk/current" - "/usr/lib64/google-cloud-sdk/" + "/snap/google-cloud-cli/current" + "/usr/lib/google-cloud-sdk" + "/usr/lib64/google-cloud-sdk" "/opt/google-cloud-sdk" + "/opt/local/libexec/google-cloud-sdk" ) for gcloud_sdk_location in $search_locations; do @@ -20,15 +23,28 @@ if [[ -z "${CLOUDSDK_HOME}" ]]; then break fi done + unset search_locations gcloud_sdk_location fi if (( ${+CLOUDSDK_HOME} )); then + # Only source this if gcloud isn't already on the path if (( ! $+commands[gcloud] )); then - # Only source this if GCloud isn't already on the path if [[ -f "${CLOUDSDK_HOME}/path.zsh.inc" ]]; then source "${CLOUDSDK_HOME}/path.zsh.inc" fi fi - source "${CLOUDSDK_HOME}/completion.zsh.inc" + + # Look for completion file in different paths + for comp_file ( + "${CLOUDSDK_HOME}/completion.zsh.inc" # default location + "/usr/share/google-cloud-sdk/completion.zsh.inc" # apt-based location + ); do + if [[ -f "${comp_file}" ]]; then + source "${comp_file}" + break + fi + done + unset comp_file + export CLOUDSDK_HOME fi diff --git a/plugins/git-auto-fetch/git-auto-fetch.plugin.zsh b/plugins/git-auto-fetch/git-auto-fetch.plugin.zsh index efe8cbe66..2df34bb7b 100644 --- a/plugins/git-auto-fetch/git-auto-fetch.plugin.zsh +++ b/plugins/git-auto-fetch/git-auto-fetch.plugin.zsh @@ -2,7 +2,8 @@ : ${GIT_AUTO_FETCH_INTERVAL:=60} # Necessary for the git-fetch-all function -zmodload zsh/datetime zsh/stat +zmodload zsh/datetime +zmodload -F zsh/stat b:zstat # only zstat command, not stat command function git-fetch-all { ( @@ -27,6 +28,7 @@ function git-fetch-all { # Fetch all remotes (avoid ssh passphrase prompt) date -R &>! "$gitdir/FETCH_LOG" GIT_SSH_COMMAND="command ssh -o BatchMode=yes" \ + GIT_TERMINAL_PROMPT=0 \ command git fetch --all 2>/dev/null &>> "$gitdir/FETCH_LOG" ) &| } diff --git a/plugins/git-extras/git-extras.plugin.zsh b/plugins/git-extras/git-extras.plugin.zsh index b86d7c5b6..6b96e12af 100644 --- a/plugins/git-extras/git-extras.plugin.zsh +++ b/plugins/git-extras/git-extras.plugin.zsh @@ -51,7 +51,7 @@ __gitex_remote_names() { local expl declare -a remote_names remote_names=(${(f)"$(_call_program remotes git remote 2>/dev/null)"}) - __git_command_successful || return + __gitex_command_successful || return _wanted remote-names expl remote-name compadd $* - $remote_names } @@ -59,7 +59,7 @@ __gitex_tag_names() { local expl declare -a tag_names tag_names=(${${(f)"$(_call_program tags git for-each-ref --format='"%(refname)"' refs/tags 2>/dev/null)"}#refs/tags/}) - __git_command_successful || return + __gitex_command_successful || return _wanted tag-names expl tag-name compadd $* - $tag_names } @@ -68,7 +68,7 @@ __gitex_branch_names() { local expl declare -a branch_names branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads 2>/dev/null)"}#refs/heads/}) - __git_command_successful || return + __gitex_command_successful || return _wanted branch-names expl branch-name compadd $* - $branch_names } @@ -76,7 +76,7 @@ __gitex_specific_branch_names() { local expl declare -a branch_names branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads/"$1" 2>/dev/null)"}#refs/heads/$1/}) - __git_command_successful || return + __gitex_command_successful || return _wanted branch-names expl branch-name compadd - $branch_names } @@ -100,7 +100,7 @@ __gitex_submodule_names() { local expl declare -a submodule_names submodule_names=(${(f)"$(_call_program branchrefs git submodule status | awk '{print $2}')"}) # ' - __git_command_successful || return + __gitex_command_successful || return _wanted submodule-names expl submodule-name compadd $* - $submodule_names } @@ -109,7 +109,7 @@ __gitex_author_names() { local expl declare -a author_names author_names=(${(f)"$(_call_program branchrefs git log --format='%aN' | sort -u)"}) - __git_command_successful || return + __gitex_command_successful || return _wanted author-names expl author-name compadd $* - $author_names } diff --git a/plugins/git-prompt/README.md b/plugins/git-prompt/README.md index 8775af893..05208d72f 100644 --- a/plugins/git-prompt/README.md +++ b/plugins/git-prompt/README.md @@ -45,6 +45,7 @@ The symbols are as follows: | ●n | there are `n` staged files | | ✖n | there are `n` unmerged files | | ✚n | there are `n` unstaged files | +| -n | there are `n` deleted files | | ⚑n | there are `n` stashed changes | | … | there are some untracked files | @@ -59,6 +60,7 @@ The symbols are as follows: ## Customisation - Set the variable `ZSH_THEME_GIT_PROMPT_CACHE` to any value in order to enable caching. +- Set the variable `ZSH_THEME_GIT_SHOW_UPSTREAM` to any value to display the upstream branch. - You may also change a number of variables (whose name start with `ZSH_THEME_GIT_PROMPT_`) to change the appearance of the prompt. Take a look at the bottom of the [plugin file](git-prompt.plugin.zsh)` to see what variables are available. diff --git a/plugins/git-prompt/git-prompt.plugin.zsh b/plugins/git-prompt/git-prompt.plugin.zsh index 0485e317c..487332028 100644 --- a/plugins/git-prompt/git-prompt.plugin.zsh +++ b/plugins/git-prompt/git-prompt.plugin.zsh @@ -47,12 +47,19 @@ function update_current_git_vars() { GIT_UNTRACKED=$__CURRENT_GIT_STATUS[7] GIT_STASHED=$__CURRENT_GIT_STATUS[8] GIT_CLEAN=$__CURRENT_GIT_STATUS[9] + GIT_DELETED=$__CURRENT_GIT_STATUS[10] + + if [ -z ${ZSH_THEME_GIT_SHOW_UPSTREAM+x} ]; then + GIT_UPSTREAM= + else + GIT_UPSTREAM=$(git rev-parse --abbrev-ref --symbolic-full-name "@{upstream}" 2>/dev/null) && GIT_UPSTREAM="${ZSH_THEME_GIT_PROMPT_UPSTREAM_SEPARATOR}${GIT_UPSTREAM}" + fi } git_super_status() { precmd_update_git_vars if [ -n "$__CURRENT_GIT_STATUS" ]; then - STATUS="$ZSH_THEME_GIT_PROMPT_PREFIX$ZSH_THEME_GIT_PROMPT_BRANCH$GIT_BRANCH%{${reset_color}%}" + STATUS="$ZSH_THEME_GIT_PROMPT_PREFIX$ZSH_THEME_GIT_PROMPT_BRANCH$GIT_BRANCH$GIT_UPSTREAM%{${reset_color}%}" if [ "$GIT_BEHIND" -ne "0" ]; then STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_BEHIND$GIT_BEHIND%{${reset_color}%}" fi @@ -69,6 +76,9 @@ git_super_status() { if [ "$GIT_CHANGED" -ne "0" ]; then STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CHANGED$GIT_CHANGED%{${reset_color}%}" fi + if [ "$GIT_DELETED" -ne "0" ]; then + STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_DELETED$GIT_DELETED%{${reset_color}%}" + fi if [ "$GIT_UNTRACKED" -ne "0" ]; then STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_UNTRACKED$GIT_UNTRACKED%{${reset_color}%}" fi @@ -91,11 +101,13 @@ ZSH_THEME_GIT_PROMPT_BRANCH="%{$fg_bold[magenta]%}" ZSH_THEME_GIT_PROMPT_STAGED="%{$fg[red]%}%{●%G%}" ZSH_THEME_GIT_PROMPT_CONFLICTS="%{$fg[red]%}%{✖%G%}" ZSH_THEME_GIT_PROMPT_CHANGED="%{$fg[blue]%}%{✚%G%}" +ZSH_THEME_GIT_PROMPT_DELETED="%{$fg[blue]%}%{-%G%}" ZSH_THEME_GIT_PROMPT_BEHIND="%{↓%G%}" ZSH_THEME_GIT_PROMPT_AHEAD="%{↑%G%}" ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[cyan]%}%{…%G%}" ZSH_THEME_GIT_PROMPT_STASHED="%{$fg_bold[blue]%}%{⚑%G%}" ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg_bold[green]%}%{✔%G%}" +ZSH_THEME_GIT_PROMPT_UPSTREAM_SEPARATOR="->" # Set the prompt. RPROMPT='$(git_super_status)' diff --git a/plugins/git-prompt/gitstatus.py b/plugins/git-prompt/gitstatus.py index b5c3c9a0c..94774d828 100644 --- a/plugins/git-prompt/gitstatus.py +++ b/plugins/git-prompt/gitstatus.py @@ -44,7 +44,7 @@ if po.returncode != 0: sys.exit(0) # Not a git repository # collect git status information -untracked, staged, changed, conflicts = [], [], [], [] +untracked, staged, changed, deleted, conflicts = [], [], [], [], [] ahead, behind = 0, 0 status = [(line[0], line[1], line[2:]) for line in stdout.decode('utf-8').splitlines()] for st in status: @@ -75,13 +75,15 @@ for st in status: else: if st[1] == 'M': changed.append(st) + if st[1] == 'D': + deleted.append(st) if st[0] == 'U': conflicts.append(st) elif st[0] != ' ': staged.append(st) stashed = get_stash() -if not changed and not staged and not conflicts and not untracked: +if not changed and not deleted and not staged and not conflicts and not untracked: clean = 1 else: clean = 0 @@ -95,6 +97,7 @@ out = ' '.join([ str(len(changed)), str(len(untracked)), str(stashed), - str(clean) + str(clean), + str(len(deleted)) ]) print(out, end='') diff --git a/plugins/git/README.md b/plugins/git/README.md index b9af3488f..0895ce39c 100644 --- a/plugins/git/README.md +++ b/plugins/git/README.md @@ -10,185 +10,201 @@ plugins=(... git) ## Aliases -| Alias | Command | -|:---------------------|:---------------------------------------------------------------------------------------------------------------------------------| -| g | git | -| ga | git add | -| gaa | git add --all | -| gapa | git add --patch | -| gau | git add --update | -| gav | git add --verbose | -| gap | git apply | -| gapt | git apply --3way | -| gb | git branch | -| gba | git branch -a | -| gbd | git branch -d | -| gbda | git branch --no-color --merged \| grep -vE "^([+*]\|\s*($(git_main_branch)\|$(git_develop_branch))\s*$)" \| xargs git branch -d 2>/dev/null | -| gbD | git branch -D | -| gbl | git blame -b -w | -| gbnm | git branch --no-merged | -| gbr | git branch --remote | -| gbs | git bisect | -| gbsb | git bisect bad | -| gbsg | git bisect good | -| gbsr | git bisect reset | -| gbss | git bisect start | -| gc | git commit -v | -| gc! | git commit -v --amend | -| gcn! | git commit -v --no-edit --amend | -| gca | git commit -v -a | -| gca! | git commit -v -a --amend | -| gcan! | git commit -v -a --no-edit --amend | -| gcans! | git commit -v -a -s --no-edit --amend | -| gcam | git commit -a -m | -| gcas | git commit -a -s | -| gcasm | git commit -a -s -m | -| gcsm | git commit -s -m | -| gcb | git checkout -b | -| gcf | git config --list | -| gcl | git clone --recurse-submodules | -| gccd | git clone --recurse-submodules "$@" && cd "$(basename $_ .git)" | -| gclean | git clean -id | -| gpristine | git reset --hard && git clean -dffx | -| gcm | git checkout $(git_main_branch) | -| gcd | git checkout $(git_develop_branch) | -| gcmsg | git commit -m | -| gco | git checkout | -| gcor | git checkout --recurse-submodules | -| gcount | git shortlog -sn | -| gcp | git cherry-pick | -| gcpa | git cherry-pick --abort | -| gcpc | git cherry-pick --continue | -| gcs | git commit -S | -| gd | git diff | -| gdca | git diff --cached | -| gdcw | git diff --cached --word-diff | -| gdct | git describe --tags $(git rev-list --tags --max-count=1) | -| gds | git diff --staged | -| gdt | git diff-tree --no-commit-id --name-only -r | -| gdnolock | git diff $@ ":(exclude)package-lock.json" ":(exclude)*.lock" | -| gdup | git diff @{upstream} | -| gdv | git diff -w $@ \| view - | -| gdw | git diff --word-diff | -| gf | git fetch | -| gfa | git fetch --all --prune | -| gfg | git ls-files \| grep | -| gfo | git fetch origin | -| gg | git gui citool | -| gga | git gui citool --amend | -| ggf | git push --force origin $(current_branch) | -| ggfl | git push --force-with-lease origin $(current_branch) | -| ggl | git pull origin $(current_branch) | -| ggp | git push origin $(current_branch) | -| ggpnp | ggl && ggp | -| ggpull | git pull origin "$(git_current_branch)" | -| ggpur | ggu | -| ggpush | git push origin "$(git_current_branch)" | -| ggsup | git branch --set-upstream-to=origin/$(git_current_branch) | -| ggu | git pull --rebase origin $(current_branch) | -| gpsup | git push --set-upstream origin $(git_current_branch) | -| ghh | git help | -| gignore | git update-index --assume-unchanged | -| gignored | git ls-files -v \| grep "^[[:lower:]]" | -| git-svn-dcommit-push | git svn dcommit && git push github $(git_main_branch):svntrunk | -| gk | gitk --all --branches &! | -| gke | gitk --all $(git log -g --pretty=%h) &! | -| gl | git pull | -| glg | git log --stat | -| glgp | git log --stat -p | -| glgg | git log --graph | -| glgga | git log --graph --decorate --all | -| glgm | git log --graph --max-count=10 | -| glo | git log --oneline --decorate | -| glol | git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset' | -| glols | git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset' --stat | -| glod | git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ad) %C(bold blue)<%an>%Creset' | -| glods | git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ad) %C(bold blue)<%an>%Creset' --date=short | -| glola | git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset' --all | -| glog | git log --oneline --decorate --graph | -| gloga | git log --oneline --decorate --graph --all | -| glp | git log --pretty=\ | -| gm | git merge | -| gmom | git merge origin/$(git_main_branch) | -| gmtl | git mergetool --no-prompt | -| gmtlvim | git mergetool --no-prompt --tool=vimdiff | -| gmum | git merge upstream/$(git_main_branch) | -| gma | git merge --abort | -| gp | git push | -| gpd | git push --dry-run | -| gpf | git push --force-with-lease | -| gpf! | git push --force | -| gpoat | git push origin --all && git push origin --tags | -| gpr | git pull --rebase | -| gpu | git push upstream | -| gpv | git push -v | -| gr | git remote | -| gra | git remote add | -| grb | git rebase | -| grba | git rebase --abort | -| grbc | git rebase --continue | -| grbd | git rebase $(git_develop_branch) | -| grbi | git rebase -i | -| grbm | git rebase $(git_main_branch) | -| grbom | git rebase origin/$(git_main_branch) | -| grbo | git rebase --onto | -| grbs | git rebase --skip | -| grev | git revert | -| grh | git reset | -| grhh | git reset --hard | -| groh | git reset origin/$(git_current_branch) --hard | -| grm | git rm | -| grmc | git rm --cached | -| grmv | git remote rename | -| grrm | git remote remove | -| grs | git restore | -| grset | git remote set-url | -| grss | git restore --source | -| grst | git restore --staged | -| grt | cd "$(git rev-parse --show-toplevel \|\| echo .)" | -| gru | git reset -- | -| grup | git remote update | -| grv | git remote -v | -| gsb | git status -sb | -| gsd | git svn dcommit | -| gsh | git show | -| gsi | git submodule init | -| gsps | git show --pretty=short --show-signature | -| gsr | git svn rebase | -| gss | git status -s | -| gst | git status | -| gsta | git stash push | -| gsta | git stash save | -| gstaa | git stash apply | -| gstc | git stash clear | -| gstd | git stash drop | -| gstl | git stash list | -| gstp | git stash pop | -| gsts | git stash show --text | -| gstu | git stash --include-untracked | -| gstall | git stash --all | -| gsu | git submodule update | -| gsw | git switch | -| gswc | git switch -c | -| gswm | git switch $(git_main_branch) | -| gswd | git switch $(git_develop_branch) | -| gts | git tag -s | -| gtv | git tag \| sort -V | -| gtl | gtl(){ git tag --sort=-v:refname -n -l ${1}* }; noglob gtl | -| gunignore | git update-index --no-assume-unchanged | -| gunwip | git log -n 1 \| grep -q -c "\-\-wip\-\-" && git reset HEAD~1 | -| gup | git pull --rebase | -| gupv | git pull --rebase -v | -| gupa | git pull --rebase --autostash | -| gupav | git pull --rebase --autostash -v | -| glum | git pull upstream $(git_main_branch) | -| gwch | git whatchanged -p --abbrev-commit --pretty=medium | -| gwip | git add -A; git rm $(git ls-files --deleted) 2> /dev/null; git commit --no-verify --no-gpg-sign -m "--wip-- [skip ci]" | -| gam | git am | -| gamc | git am --continue | -| gams | git am --skip | -| gama | git am --abort | -| gamscp | git am --show-current-patch | +| Alias | Command | +| :------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| g | git | +| ga | git add | +| gaa | git add --all | +| gapa | git add --patch | +| gau | git add --update | +| gav | git add --verbose | +| gap | git apply | +| gapt | git apply --3way | +| gb | git branch | +| gba | git branch --all | +| gbd | git branch --delete | +| gbda | git branch --no-color --merged \| grep -vE "^([+*]\|\s*($(git_main_branch)\|$(git_develop_branch))\s*$)" \| xargs git branch --delete 2>/dev/null | +| gbD | git branch --delete --force | +| gbg | git branch -vv | grep ": gone\]" | +| gbgd | local res=$(git branch -vv | grep ": gone\]" | awk '{print $1}') && [[ $res ]] && echo $res | xargs git branch -d | +| gbgD | local res=$(git branch -vv | grep ": gone\]" | awk '{print $1}') && [[ $res ]] && echo $res | xargs git branch -D | +| gbl | git blame -b -w | +| gbnm | git branch --no-merged | +| gbr | git branch --remote | +| gbs | git bisect | +| gbsb | git bisect bad | +| gbsg | git bisect good | +| gbsr | git bisect reset | +| gbss | git bisect start | +| gc | git commit --verbose | +| gc! | git commit --verbose --amend | +| gcn! | git commit --verbose --no-edit --amend | +| gca | git commit --verbose --all | +| gca! | git commit --verbose --all --amend | +| gcan! | git commit --verbose --all --no-edit --amend | +| gcans! | git commit --verbose --all --signoff --no-edit --amend | +| gcam | git commit --all --message | +| gcas | git commit --all --signoff | +| gcasm | git commit --all --signoff --message | +| gcsm | git commit --signoff --message | +| gcb | git checkout -b | +| gcf | git config --list | +| gcl | git clone --recurse-submodules | +| gccd | git clone --recurse-submodules "$@" && cd "$(basename $\_ .git)" | +| gclean | git clean --interactive -d | +| gpristine | git reset --hard && git clean -dffx | +| gcm | git checkout $(git_main_branch) | +| gcd | git checkout $(git_develop_branch) | +| gcmsg | git commit --message | +| gco | git checkout | +| gcor | git checkout --recurse-submodules | +| gcount | git shortlog --summary -n | +| gcp | git cherry-pick | +| gcpa | git cherry-pick --abort | +| gcpc | git cherry-pick --continue | +| gcs | git commit -S | +| gcss | git commit -S -s | +| gcssm | git commit -S -s -m | +| gd | git diff | +| gdca | git diff --cached | +| gdcw | git diff --cached --word-diff | +| gdct | git describe --tags $(git rev-list --tags --max-count=1) | +| gds | git diff --staged | +| gdt | git diff-tree --no-commit-id --name-only -r | +| gdnolock | git diff $@ ":(exclude)package-lock.json" ":(exclude)\*.lock" | +| gdup | git diff @{upstream} | +| gdv | git diff -w $@ \| view - | +| gdw | git diff --word-diff | +| gf | git fetch | +| gfa | git fetch --all --prune | +| gfg | git ls-files \| grep | +| gfo | git fetch origin | +| gg | git gui citool | +| gga | git gui citool --amend | +| ggf | git push --force origin $(current_branch) | +| ggfl | git push --force-with-lease origin $(current_branch) | +| ggl | git pull origin $(current_branch) | +| ggp | git push origin $(current_branch) | +| ggpnp | ggl && ggp | +| ggpull | git pull origin "$(git_current_branch)" | +| ggpur | ggu | +| ggpush | git push origin "$(git_current_branch)" | +| ggsup | git branch --set-upstream-to=origin/$(git_current_branch) | +| ggu | git pull --rebase origin $(current_branch) | +| gpsup | git push --set-upstream origin $(git_current_branch) | +| gpsupf | git push --set-upstream origin $(git_current_branch) --force-with-lease --force-if-includes (git version >= 2.30) | +| gpsupf | git push --set-upstream origin $(git_current_branch) --force-with-lease (git version < 2.30) | +| ghh | git help | +| gignore | git update-index --assume-unchanged | +| gignored | git ls-files -v \| grep "^[[:lower:]]" | +| git-svn-dcommit-push | git svn dcommit && git push github $(git_main_branch):svntrunk | +| gk | gitk --all --branches &! | +| gke | gitk --all $(git log --walk-reflogs --pretty=%h) &! | +| gl | git pull | +| glg | git log --stat | +| glgp | git log --stat --patch | +| glgg | git log --graph | +| glgga | git log --graph --decorate --all | +| glgm | git log --graph --max-count=10 | +| glo | git log --oneline --decorate | +| glol | git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset' | +| glols | git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset' --stat | +| glod | git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ad) %C(bold blue)<%an>%Creset' | +| glods | git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ad) %C(bold blue)<%an>%Creset' --date=short | +| glola | git log --graph --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset' --all | +| glog | git log --oneline --decorate --graph | +| gloga | git log --oneline --decorate --graph --all | +| glp | git log --pretty=\ | +| gm | git merge | +| gmom | git merge origin/$(git_main_branch) | +| gmtl | git mergetool --no-prompt | +| gmtlvim | git mergetool --no-prompt --tool=vimdiff | +| gmum | git merge upstream/$(git_main_branch) | +| gma | git merge --abort | +| gp | git push | +| gpd | git push --dry-run | +| gpf | git push --force-with-lease --force-if-includes (git version >= 2.30) | +| gpf | git push --force-with-lease (git version < 2.30) | +| gpf! | git push --force | +| gpoat | git push origin --all && git push origin --tags | +| gpod | git push origin --delete | +| gpr | git pull --rebase | +| gpu | git push upstream | +| gpv | git push --verbose | +| gr | git remote | +| gra | git remote add | +| grb | git rebase | +| grba | git rebase --abort | +| grbc | git rebase --continue | +| grbd | git rebase $(git_develop_branch) | +| grbi | git rebase --interactive | +| grbm | git rebase $(git_main_branch) | +| grbom | git rebase origin/$(git_main_branch) | +| grbo | git rebase --onto | +| grbs | git rebase --skip | +| grev | git revert | +| grh | git reset | +| grhh | git reset --hard | +| groh | git reset origin/$(git_current_branch) --hard | +| grm | git rm | +| grmc | git rm --cached | +| grmv | git remote rename | +| grrm | git remote remove | +| grs | git restore | +| grset | git remote set-url | +| grss | git restore --source | +| grst | git restore --staged | +| grt | cd "$(git rev-parse --show-toplevel \|\| echo .)" | +| gru | git reset -- | +| grup | git remote update | +| grv | git remote --verbose | +| gsb | git status --short -b | +| gsd | git svn dcommit | +| gsh | git show | +| gsi | git submodule init | +| gsps | git show --pretty=short --show-signature | +| gsr | git svn rebase | +| gss | git status --short | +| gst | git status | +| gsta | git stash push (git version >= 2.13) | +| gsta | git stash save (git version < 2.13) | +| gstaa | git stash apply | +| gstc | git stash clear | +| gstd | git stash drop | +| gstl | git stash list | +| gstp | git stash pop | +| gsts | git stash show --text | +| gstu | git stash --include-untracked | +| gstall | git stash --all | +| gsu | git submodule update | +| gsw | git switch | +| gswc | git switch -c | +| gswm | git switch $(git_main_branch) | +| gswd | git switch $(git_develop_branch) | +| gts | git tag -s | +| gtv | git tag \| sort -V | +| gtl | gtl(){ git tag --sort=-v:refname -n --list ${1}\* }; noglob gtl | +| gunignore | git update-index --no-assume-unchanged | +| gunwip | git log --max-count=1 \| grep -q -c "\-\-wip\-\-" && git reset HEAD~1 | +| gup | git pull --rebase | +| gupv | git pull --rebase --verbose | +| gupa | git pull --rebase --autostash | +| gupav | git pull --rebase --autostash --verbose | +| gupom | git pull --rebase origin $(git_main_branch) | +| gupomi | git pull --rebase=interactive origin $(git_main_branch) | +| glum | git pull upstream $(git_main_branch) | +| gluc | git pull upstream $(git_current_branch) | +| gwch | git whatchanged -p --abbrev-commit --pretty=medium | +| gwip | git add -A; git rm $(git ls-files --deleted) 2> /dev/null; git commit --no-verify --no-gpg-sign --message "--wip-- [skip ci]" | +| gam | git am | +| gamc | git am --continue | +| gams | git am --skip | +| gama | git am --abort | +| gamscp | git am --show-current-patch | +| gwt | git worktree | +| gwtls | git worktree list | +| gwtmv | git worktree move | +| gwtrm | git worktree remove | ### Main branch preference @@ -220,7 +236,7 @@ These are aliases that have been removed, renamed, or otherwise modified in a wa ### Current | Command | Description | -|:-----------------------|:---------------------------------------------------------------------------------------------------------| +| :--------------------- | :------------------------------------------------------------------------------------------------------- | | `grename ` | Rename `old` branch to `new`, including in origin remote | | current_branch | Return the name of the current branch | | git_current_user_name | Returns the `user.name` config value | @@ -233,13 +249,13 @@ These are aliases that have been removed, renamed, or otherwise modified in a wa These features allow to pause a branch development and switch to another one (_"Work in Progress"_, or wip). When you want to go back to work, just unwip it. | Command | Description | -|:-----------------|:------------------------------------------------| +| :--------------- | :---------------------------------------------- | | work_in_progress | Echoes a warning if the current branch is a wip | | gwip | Commit wip branch | | gunwip | Uncommit wip branch | ### Deprecated functions -| Command | Description | Reason | -|:-----------------------|:----------------------------------------|:----------------------------------------------------------------| -| current_repository | Return the names of the current remotes | Didn't work properly. Use `git remote -v` instead (`grv` alias) | +| Command | Description | Reason | +| :----------------- | :-------------------------------------- | :-------------------------------------------------------------- | +| current_repository | Return the names of the current remotes | Didn't work properly. Use `git remote -v` instead (`grv` alias) | diff --git a/plugins/git/git.plugin.zsh b/plugins/git/git.plugin.zsh index 8f7e623ec..ed17436e8 100644 --- a/plugins/git/git.plugin.zsh +++ b/plugins/git/git.plugin.zsh @@ -31,7 +31,7 @@ function work_in_progress() { function git_main_branch() { command git rev-parse --git-dir &>/dev/null || return local ref - for ref in refs/{heads,remotes/{origin,upstream}}/{main,trunk}; do + for ref in refs/{heads,remotes/{origin,upstream}}/{main,trunk,mainline,default}; do if command git show-ref -q --verify $ref; then echo ${ref:t} return @@ -69,10 +69,13 @@ alias gap='git apply' alias gapt='git apply --3way' alias gb='git branch' -alias gba='git branch -a' -alias gbd='git branch -d' -alias gbda='git branch --no-color --merged | command grep -vE "^([+*]|\s*($(git_main_branch)|$(git_develop_branch))\s*$)" | command xargs git branch -d 2>/dev/null' -alias gbD='git branch -D' +alias gba='git branch --all' +alias gbd='git branch --delete' +alias gbda='git branch --no-color --merged | command grep -vE "^([+*]|\s*($(git_main_branch)|$(git_develop_branch))\s*$)" | command xargs git branch --delete 2>/dev/null' +alias gbD='git branch --delete --force' +alias gbg='git branch -vv | grep ": gone\]"' +alias gbgd='local res=$(gbg | awk '"'"'{print $1}'"'"') && [[ $res ]] && echo $res | xargs git branch -d' +alias gbgD='local res=$(gbg | awk '"'"'{print $1}'"'"') && [[ $res ]] && echo $res | xargs git branch -D' alias gbl='git blame -b -w' alias gbnm='git branch --no-merged' alias gbr='git branch --remote' @@ -82,17 +85,17 @@ alias gbsg='git bisect good' alias gbsr='git bisect reset' alias gbss='git bisect start' -alias gc='git commit -v' -alias gc!='git commit -v --amend' -alias gcn!='git commit -v --no-edit --amend' -alias gca='git commit -v -a' -alias gca!='git commit -v -a --amend' -alias gcan!='git commit -v -a --no-edit --amend' -alias gcans!='git commit -v -a -s --no-edit --amend' -alias gcam='git commit -a -m' -alias gcsm='git commit -s -m' -alias gcas='git commit -a -s' -alias gcasm='git commit -a -s -m' +alias gc='git commit --verbose' +alias gc!='git commit --verbose --amend' +alias gcn!='git commit --verbose --no-edit --amend' +alias gca='git commit --verbose --all' +alias gca!='git commit --verbose --all --amend' +alias gcan!='git commit --verbose --all --no-edit --amend' +alias gcans!='git commit --verbose --all --signoff --no-edit --amend' +alias gcam='git commit --all --message' +alias gcsm='git commit --signoff --message' +alias gcas='git commit --all --signoff' +alias gcasm='git commit --all --signoff --message' alias gcb='git checkout -b' alias gcf='git config --list' @@ -103,20 +106,20 @@ function gccd() { compdef _git gccd=git-clone alias gcl='git clone --recurse-submodules' -alias gclean='git clean -id' -alias gpristine='git reset --hard && git clean -dffx' +alias gclean='git clean --interactive -d' +alias gpristine='git reset --hard && git clean --force -dfx' alias gcm='git checkout $(git_main_branch)' alias gcd='git checkout $(git_develop_branch)' -alias gcmsg='git commit -m' +alias gcmsg='git commit --message' alias gco='git checkout' alias gcor='git checkout --recurse-submodules' -alias gcount='git shortlog -sn' +alias gcount='git shortlog --summary --numbered' alias gcp='git cherry-pick' alias gcpa='git cherry-pick --abort' alias gcpc='git cherry-pick --continue' -alias gcs='git commit -S' -alias gcss='git commit -S -s' -alias gcssm='git commit -S -s -m' +alias gcs='git commit --gpg-sign' +alias gcss='git commit --gpg-sign --signoff' +alias gcssm='git commit --gpg-sign --signoff --message' alias gd='git diff' alias gdca='git diff --cached' @@ -199,6 +202,9 @@ alias ggpush='git push origin "$(git_current_branch)"' alias ggsup='git branch --set-upstream-to=origin/$(git_current_branch)' alias gpsup='git push --set-upstream origin $(git_current_branch)' +is-at-least 2.30 "$git_version" \ + && alias gpsupf='git push --set-upstream origin $(git_current_branch) --force-with-lease --force-if-includes' \ + || alias gpsupf='git push --set-upstream origin $(git_current_branch) --force-with-lease' alias ghh='git help' @@ -207,11 +213,11 @@ alias gignored='git ls-files -v | grep "^[[:lower:]]"' alias git-svn-dcommit-push='git svn dcommit && git push github $(git_main_branch):svntrunk' alias gk='\gitk --all --branches &!' -alias gke='\gitk --all $(git log -g --pretty=%h) &!' +alias gke='\gitk --all $(git log --walk-reflogs --pretty=%h) &!' alias gl='git pull' alias glg='git log --stat' -alias glgp='git log --stat -p' +alias glgp='git log --stat --patch' alias glgg='git log --graph' alias glgga='git log --graph --decorate --all' alias glgm='git log --graph --max-count=10' @@ -234,12 +240,15 @@ alias gma='git merge --abort' alias gp='git push' alias gpd='git push --dry-run' -alias gpf='git push --force-with-lease' +is-at-least 2.30 "$git_version" \ + && alias gpf='git push --force-with-lease --force-if-includes' \ + || alias gpf='git push --force-with-lease' alias gpf!='git push --force' alias gpoat='git push origin --all && git push origin --tags' +alias gpod='git push origin --delete' alias gpr='git pull --rebase' alias gpu='git push upstream' -alias gpv='git push -v' +alias gpv='git push --verbose' alias gr='git remote' alias gra='git remote add' @@ -247,7 +256,7 @@ alias grb='git rebase' alias grba='git rebase --abort' alias grbc='git rebase --continue' alias grbd='git rebase $(git_develop_branch)' -alias grbi='git rebase -i' +alias grbi='git rebase --interactive' alias grbm='git rebase $(git_main_branch)' alias grbom='git rebase origin/$(git_main_branch)' alias grbo='git rebase --onto' @@ -267,15 +276,15 @@ alias grst='git restore --staged' alias grt='cd "$(git rev-parse --show-toplevel || echo .)"' alias gru='git reset --' alias grup='git remote update' -alias grv='git remote -v' +alias grv='git remote --verbose' -alias gsb='git status -sb' +alias gsb='git status --short --branch' alias gsd='git svn dcommit' alias gsh='git show' alias gsi='git submodule init' alias gsps='git show --pretty=short --show-signature' alias gsr='git svn rebase' -alias gss='git status -s' +alias gss='git status --short' alias gst='git status' # use the default stash push on git 2.13 and newer @@ -293,24 +302,33 @@ alias gstu='gsta --include-untracked' alias gstall='git stash --all' alias gsu='git submodule update' alias gsw='git switch' -alias gswc='git switch -c' +alias gswc='git switch --create' alias gswm='git switch $(git_main_branch)' alias gswd='git switch $(git_develop_branch)' -alias gts='git tag -s' +alias gts='git tag --sign' alias gtv='git tag | sort -V' -alias gtl='gtl(){ git tag --sort=-v:refname -n -l "${1}*" }; noglob gtl' +alias gtl='gtl(){ git tag --sort=-v:refname -n --list "${1}*" }; noglob gtl' alias gunignore='git update-index --no-assume-unchanged' -alias gunwip='git log -n 1 | grep -q -c "\-\-wip\-\-" && git reset HEAD~1' +alias gunwip='git log --max-count=1 | grep -q -c "\--wip--" && git reset HEAD~1' alias gup='git pull --rebase' -alias gupv='git pull --rebase -v' +alias gupv='git pull --rebase --verbose' alias gupa='git pull --rebase --autostash' -alias gupav='git pull --rebase --autostash -v' +alias gupav='git pull --rebase --autostash --verbose' +alias gupom='git pull --rebase origin $(git_main_branch)' +alias gupomi='git pull --rebase=interactive origin $(git_main_branch)' alias glum='git pull upstream $(git_main_branch)' +alias gluc='git pull upstream $(git_current_branch)' alias gwch='git whatchanged -p --abbrev-commit --pretty=medium' -alias gwip='git add -A; git rm $(git ls-files --deleted) 2> /dev/null; git commit --no-verify --no-gpg-sign -m "--wip-- [skip ci]"' +alias gwip='git add -A; git rm $(git ls-files --deleted) 2> /dev/null; git commit --no-verify --no-gpg-sign --message "--wip-- [skip ci]"' + +alias gwt='git worktree' +alias gwta='git worktree add' +alias gwtls='git worktree list' +alias gwtmv='git worktree move' +alias gwtrm='git worktree remove' alias gam='git am' alias gamc='git am --continue' diff --git a/plugins/gitfast/git-completion.bash b/plugins/gitfast/git-completion.bash index 2603ba7bb..dd06b5048 100644 --- a/plugins/gitfast/git-completion.bash +++ b/plugins/gitfast/git-completion.bash @@ -49,6 +49,11 @@ # and git-switch completion (e.g., completing "foo" when "origin/foo" # exists). # +# GIT_COMPLETION_SHOW_ALL_COMMANDS +# +# When set to "1" suggest all commands, including plumbing commands +# which are hidden by default (e.g. "cat-file" on "git ca"). +# # GIT_COMPLETION_SHOW_ALL # # When set to "1" suggest all options, including options which are @@ -321,19 +326,19 @@ __gitcomp_builtin_apply_default=" --exclude= --include= --no-add --stat --numsta __gitcomp_builtin_archive_default=" --output= --remote= --exec= --no-output -- --no-remote --no-exec" __gitcomp_builtin_bisect__helper_default=" --bisect-reset --bisect-next-check --bisect-terms --bisect-start --bisect-next --bisect-state --bisect-log --bisect-replay --bisect-skip --bisect-visualize --bisect-run --no-log --log" __gitcomp_builtin_blame_default=" --incremental --root --show-stats --progress --score-debug --show-name --show-number --porcelain --line-porcelain --show-email --ignore-rev= --ignore-revs-file= --color-lines --color-by-age --minimal --contents= --abbrev --no-incremental -- --no-root --no-show-stats --no-progress --no-score-debug --no-show-name --no-show-number --no-porcelain --no-line-porcelain --no-show-email --no-ignore-rev --no-ignore-revs-file --no-color-lines --no-color-by-age --no-minimal --no-contents --no-abbrev" -__gitcomp_builtin_branch_default=" --verbose --quiet --track --set-upstream-to= --unset-upstream --color --remotes --contains --no-contains --abbrev --all --delete --move --copy --list --show-current --create-reflog --edit-description --merged --no-merged --column --sort= --points-at= --ignore-case --format= -- --no-verbose --no-quiet --no-track --no-set-upstream-to --no-unset-upstream --no-color --no-remotes --no-abbrev --no-all --no-delete --no-move --no-copy --no-list --no-show-current --no-create-reflog --no-edit-description --no-column --no-sort --no-points-at --no-ignore-case --no-format" +__gitcomp_builtin_branch_default=" --verbose --quiet --track --set-upstream-to= --unset-upstream --color --remotes --contains --no-contains --abbrev --all --delete --move --copy --list --show-current --create-reflog --edit-description --merged --no-merged --column --sort= --points-at= --ignore-case --recurse-submodules --format= -- --no-verbose --no-quiet --no-track --no-set-upstream-to --no-unset-upstream --no-color --no-remotes --no-abbrev --no-all --no-delete --no-move --no-copy --no-list --no-show-current --no-create-reflog --no-edit-description --no-column --no-sort --no-points-at --no-ignore-case --no-recurse-submodules --no-format" __gitcomp_builtin_bugreport_default=" --output-directory= --suffix= --no-output-directory -- --no-suffix" -__gitcomp_builtin_cat_file_default=" --textconv --filters --path= --allow-unknown-type --buffer --batch --batch-check --follow-symlinks --batch-all-objects --unordered --no-path -- --no-allow-unknown-type --no-buffer --no-follow-symlinks --no-batch-all-objects --no-unordered" +__gitcomp_builtin_cat_file_default=" --allow-unknown-type --batch --batch-check --batch-command --batch-all-objects --buffer --follow-symlinks --unordered --textconv --filters --path= --no-allow-unknown-type -- --no-buffer --no-follow-symlinks --no-unordered --no-path" __gitcomp_builtin_check_attr_default=" --all --cached --stdin --no-all -- --no-cached --no-stdin" __gitcomp_builtin_check_ignore_default=" --quiet --verbose --stdin --non-matching --no-index --index -- --no-quiet --no-verbose --no-stdin --no-non-matching" __gitcomp_builtin_check_mailmap_default=" --stdin --no-stdin" __gitcomp_builtin_checkout_default=" --guess --overlay --quiet --recurse-submodules --progress --merge --conflict= --detach --track --orphan= --ignore-other-worktrees --ours --theirs --patch --ignore-skip-worktree-bits --pathspec-from-file= --pathspec-file-nul --no-guess -- --no-overlay --no-quiet --no-recurse-submodules --no-progress --no-merge --no-conflict --no-detach --no-track --no-orphan --no-ignore-other-worktrees --no-patch --no-ignore-skip-worktree-bits --no-pathspec-from-file --no-pathspec-file-nul" __gitcomp_builtin_checkout__worker_default=" --prefix= --no-prefix" -__gitcomp_builtin_checkout_index_default=" --all --force --quiet --no-create --index --stdin --temp --prefix= --stage= --create -- --no-all --no-force --no-quiet --no-index --no-stdin --no-temp --no-prefix" +__gitcomp_builtin_checkout_index_default=" --all --ignore-skip-worktree-bits --force --quiet --no-create --index --stdin --temp --prefix= --stage= --create -- --no-all --no-ignore-skip-worktree-bits --no-force --no-quiet --no-index --no-stdin --no-temp --no-prefix" __gitcomp_builtin_cherry_default=" --abbrev --verbose --no-abbrev -- --no-verbose" __gitcomp_builtin_cherry_pick_default=" --quit --continue --abort --skip --cleanup= --no-commit --edit --signoff --mainline= --rerere-autoupdate --strategy= --strategy-option= --gpg-sign --ff --allow-empty --allow-empty-message --keep-redundant-commits --commit -- --no-cleanup --no-edit --no-signoff --no-mainline --no-rerere-autoupdate --no-strategy --no-strategy-option --no-gpg-sign --no-ff --no-allow-empty --no-allow-empty-message --no-keep-redundant-commits" __gitcomp_builtin_clean_default=" --quiet --dry-run --interactive --exclude= --no-quiet -- --no-dry-run --no-interactive" -__gitcomp_builtin_clone_default=" --verbose --quiet --progress --reject-shallow --no-checkout --bare --mirror --local --no-hardlinks --shared --recurse-submodules --jobs= --template= --reference= --reference-if-able= --dissociate --origin= --branch= --upload-pack= --depth= --shallow-since= --shallow-exclude= --single-branch --no-tags --shallow-submodules --separate-git-dir= --config= --server-option= --ipv4 --ipv6 --filter= --remote-submodules --sparse --checkout --hardlinks --tags -- --no-verbose --no-quiet --no-progress --no-reject-shallow --no-bare --no-mirror --no-local --no-shared --no-recurse-submodules --no-recursive --no-jobs --no-template --no-reference --no-reference-if-able --no-dissociate --no-origin --no-branch --no-upload-pack --no-depth --no-shallow-since --no-shallow-exclude --no-single-branch --no-shallow-submodules --no-separate-git-dir --no-config --no-server-option --no-ipv4 --no-ipv6 --no-filter --no-remote-submodules --no-sparse" +__gitcomp_builtin_clone_default=" --verbose --quiet --progress --reject-shallow --no-checkout --bare --mirror --local --no-hardlinks --shared --recurse-submodules --jobs= --template= --reference= --reference-if-able= --dissociate --origin= --branch= --upload-pack= --depth= --shallow-since= --shallow-exclude= --single-branch --no-tags --shallow-submodules --separate-git-dir= --config= --server-option= --ipv4 --ipv6 --filter= --also-filter-submodules --remote-submodules --sparse --checkout --hardlinks --tags -- --no-verbose --no-quiet --no-progress --no-reject-shallow --no-bare --no-mirror --no-local --no-shared --no-recurse-submodules --no-recursive --no-jobs --no-template --no-reference --no-reference-if-able --no-dissociate --no-origin --no-branch --no-upload-pack --no-depth --no-shallow-since --no-shallow-exclude --no-single-branch --no-shallow-submodules --no-separate-git-dir --no-config --no-server-option --no-ipv4 --no-ipv6 --no-filter --no-also-filter-submodules --no-remote-submodules --no-sparse" __gitcomp_builtin_column_default=" --command= --mode --raw-mode= --width= --indent= --nl= --padding= --no-command -- --no-mode --no-raw-mode --no-width --no-indent --no-nl --no-padding" __gitcomp_builtin_commit_default=" --quiet --verbose --file= --author= --date= --message= --reedit-message= --reuse-message= --fixup= --squash= --reset-author --trailer= --signoff --template= --edit --cleanup= --status --gpg-sign --all --include --interactive --patch --only --no-verify --dry-run --short --branch --ahead-behind --porcelain --long --null --amend --no-post-rewrite --untracked-files --pathspec-from-file= --pathspec-file-nul --verify --post-rewrite -- --no-quiet --no-verbose --no-file --no-author --no-date --no-message --no-reedit-message --no-reuse-message --no-fixup --no-squash --no-reset-author --no-signoff --no-template --no-edit --no-cleanup --no-status --no-gpg-sign --no-all --no-include --no-interactive --no-patch --no-only --no-dry-run --no-short --no-branch --no-ahead-behind --no-porcelain --no-long --no-null --no-amend --no-untracked-files --no-pathspec-from-file --no-pathspec-file-nul" __gitcomp_builtin_commit_graph_default=" --object-dir= --no-object-dir" @@ -346,31 +351,33 @@ __gitcomp_builtin_describe_default=" --contains --debug --all --tags --long --fi __gitcomp_builtin_difftool_default=" --gui --dir-diff --no-prompt --symlinks --tool= --tool-help --trust-exit-code --extcmd= --no-index --index -- --no-gui --no-dir-diff --no-symlinks --no-tool --no-tool-help --no-trust-exit-code --no-extcmd" __gitcomp_builtin_env__helper_default=" --type= --default= --exit-code --no-default -- --no-exit-code" __gitcomp_builtin_fast_export_default=" --progress= --signed-tags= --tag-of-filtered-object= --reencode= --export-marks= --import-marks= --import-marks-if-exists= --fake-missing-tagger --full-tree --use-done-feature --no-data --refspec= --anonymize --anonymize-map= --reference-excluded-parents --show-original-ids --mark-tags --data -- --no-progress --no-signed-tags --no-tag-of-filtered-object --no-reencode --no-export-marks --no-import-marks --no-import-marks-if-exists --no-fake-missing-tagger --no-full-tree --no-use-done-feature --no-refspec --no-anonymize --no-reference-excluded-parents --no-show-original-ids --no-mark-tags" -__gitcomp_builtin_fetch_default=" --verbose --quiet --all --set-upstream --append --atomic --upload-pack= --force --multiple --tags --jobs= --prefetch --prune --prune-tags --recurse-submodules --dry-run --write-fetch-head --keep --update-head-ok --progress --depth= --shallow-since= --shallow-exclude= --deepen= --unshallow --update-shallow --refmap= --server-option= --ipv4 --ipv6 --negotiation-tip= --negotiate-only --filter= --auto-maintenance --auto-gc --show-forced-updates --write-commit-graph --stdin --no-verbose -- --no-quiet --no-all --no-set-upstream --no-append --no-atomic --no-upload-pack --no-force --no-multiple --no-tags --no-jobs --no-prefetch --no-prune --no-prune-tags --no-recurse-submodules --no-dry-run --no-write-fetch-head --no-keep --no-update-head-ok --no-progress --no-depth --no-shallow-since --no-shallow-exclude --no-deepen --no-update-shallow --no-server-option --no-ipv4 --no-ipv6 --no-negotiation-tip --no-negotiate-only --no-filter --no-auto-maintenance --no-auto-gc --no-show-forced-updates --no-write-commit-graph --no-stdin" +__gitcomp_builtin_fetch_default=" --verbose --quiet --all --set-upstream --append --atomic --upload-pack= --force --multiple --tags --jobs= --prefetch --prune --prune-tags --recurse-submodules --dry-run --write-fetch-head --keep --update-head-ok --progress --depth= --shallow-since= --shallow-exclude= --deepen= --unshallow --refetch --update-shallow --refmap= --server-option= --ipv4 --ipv6 --negotiation-tip= --negotiate-only --filter= --auto-maintenance --auto-gc --show-forced-updates --write-commit-graph --stdin --no-verbose -- --no-quiet --no-all --no-set-upstream --no-append --no-atomic --no-upload-pack --no-force --no-multiple --no-tags --no-jobs --no-prefetch --no-prune --no-prune-tags --no-recurse-submodules --no-dry-run --no-write-fetch-head --no-keep --no-update-head-ok --no-progress --no-depth --no-shallow-since --no-shallow-exclude --no-deepen --no-update-shallow --no-server-option --no-ipv4 --no-ipv6 --no-negotiation-tip --no-negotiate-only --no-filter --no-auto-maintenance --no-auto-gc --no-show-forced-updates --no-write-commit-graph --no-stdin" __gitcomp_builtin_fmt_merge_msg_default=" --log --message= --into-name= --file= --no-log -- --no-message --no-into-name --no-file" __gitcomp_builtin_for_each_ref_default=" --shell --perl --python --tcl --count= --format= --color --sort= --points-at= --merged --no-merged --contains --no-contains --ignore-case -- --no-shell --no-perl --no-python --no-tcl --no-count --no-format --no-color --no-sort --no-points-at --no-ignore-case" __gitcomp_builtin_for_each_repo_default=" --config= --no-config" __gitcomp_builtin_format_patch_default=" --numbered --no-numbered --signoff --stdout --cover-letter --numbered-files --suffix= --start-number= --reroll-count= --filename-max-length= --rfc --cover-from-description= --subject-prefix= --output-directory= --keep-subject --no-binary --zero-commit --ignore-if-in-upstream --no-stat --add-header= --to= --cc= --from --in-reply-to= --attach --inline --thread --signature= --base= --signature-file= --quiet --progress --interdiff= --range-diff= --creation-factor= --binary -- --no-numbered --no-signoff --no-stdout --no-cover-letter --no-numbered-files --no-suffix --no-start-number --no-reroll-count --no-filename-max-length --no-cover-from-description --no-zero-commit --no-ignore-if-in-upstream --no-add-header --no-to --no-cc --no-from --no-in-reply-to --no-attach --no-thread --no-signature --no-base --no-signature-file --no-quiet --no-progress --no-interdiff --no-range-diff --no-creation-factor" __gitcomp_builtin_fsck_default=" --verbose --unreachable --dangling --tags --root --cache --reflogs --full --connectivity-only --strict --lost-found --progress --name-objects --no-verbose -- --no-unreachable --no-dangling --no-tags --no-root --no-cache --no-reflogs --no-full --no-connectivity-only --no-strict --no-lost-found --no-progress --no-name-objects" __gitcomp_builtin_fsck_objects_default=" --verbose --unreachable --dangling --tags --root --cache --reflogs --full --connectivity-only --strict --lost-found --progress --name-objects --no-verbose -- --no-unreachable --no-dangling --no-tags --no-root --no-cache --no-reflogs --no-full --no-connectivity-only --no-strict --no-lost-found --no-progress --no-name-objects" +__gitcomp_builtin_fsmonitor__daemon_default="" __gitcomp_builtin_gc_default=" --quiet --prune --aggressive --keep-largest-pack --no-quiet -- --no-prune --no-aggressive --no-keep-largest-pack" __gitcomp_builtin_grep_default=" --cached --no-index --untracked --exclude-standard --recurse-submodules --invert-match --ignore-case --word-regexp --text --textconv --recursive --max-depth= --extended-regexp --basic-regexp --fixed-strings --perl-regexp --line-number --column --full-name --files-with-matches --name-only --files-without-match --only-matching --count --color --break --heading --context= --before-context= --after-context= --threads= --show-function --function-context --and --or --not --quiet --all-match --index -- --no-cached --no-untracked --no-exclude-standard --no-recurse-submodules --no-invert-match --no-ignore-case --no-word-regexp --no-text --no-textconv --no-recursive --no-extended-regexp --no-basic-regexp --no-fixed-strings --no-perl-regexp --no-line-number --no-column --no-full-name --no-files-with-matches --no-name-only --no-files-without-match --no-only-matching --no-count --no-color --no-break --no-heading --no-context --no-before-context --no-after-context --no-threads --no-show-function --no-function-context --no-or --no-quiet --no-all-match" __gitcomp_builtin_hash_object_default=" --stdin --stdin-paths --no-filters --literally --path= --filters -- --no-stdin --no-stdin-paths --no-literally --no-path" -__gitcomp_builtin_help_default=" --all --man --web --info --verbose --guides --config --no-man -- --no-web --no-info --no-verbose" +__gitcomp_builtin_help_default=" --all --external-commands --aliases --man --web --info --verbose --guides --config --no-external-commands -- --no-aliases --no-man --no-web --no-info --no-verbose" +__gitcomp_builtin_hook_default="" __gitcomp_builtin_init_default=" --template= --bare --shared --quiet --separate-git-dir= --initial-branch= --object-format= --no-template -- --no-bare --no-quiet --no-separate-git-dir --no-initial-branch --no-object-format" __gitcomp_builtin_init_db_default=" --template= --bare --shared --quiet --separate-git-dir= --initial-branch= --object-format= --no-template -- --no-bare --no-quiet --no-separate-git-dir --no-initial-branch --no-object-format" __gitcomp_builtin_interpret_trailers_default=" --in-place --trim-empty --where= --if-exists= --if-missing= --only-trailers --only-input --unfold --parse --no-divider --trailer= --divider -- --no-in-place --no-trim-empty --no-where --no-if-exists --no-if-missing --no-only-trailers --no-only-input --no-unfold --no-trailer" __gitcomp_builtin_log_default=" --quiet --source --use-mailmap --decorate-refs= --decorate-refs-exclude= --decorate --no-quiet -- --no-source --no-use-mailmap --no-mailmap --no-decorate-refs --no-decorate-refs-exclude --no-decorate" __gitcomp_builtin_ls_files_default=" --cached --deleted --modified --others --ignored --stage --killed --directory --eol --empty-directory --unmerged --resolve-undo --exclude= --exclude-from= --exclude-per-directory= --exclude-standard --full-name --recurse-submodules --error-unmatch --with-tree= --abbrev --debug --deduplicate --sparse --no-cached -- --no-deleted --no-modified --no-others --no-ignored --no-stage --no-killed --no-directory --no-eol --no-empty-directory --no-unmerged --no-resolve-undo --no-exclude-per-directory --no-recurse-submodules --no-error-unmatch --no-with-tree --no-abbrev --no-debug --no-deduplicate --no-sparse" __gitcomp_builtin_ls_remote_default=" --quiet --upload-pack= --tags --heads --refs --get-url --sort= --symref --server-option= --no-quiet -- --no-upload-pack --no-tags --no-heads --no-refs --no-get-url --no-sort --no-symref --no-server-option" -__gitcomp_builtin_ls_tree_default=" --long --name-only --name-status --full-name --full-tree --abbrev --no-long -- --no-name-only --no-name-status --no-full-name --no-full-tree --no-abbrev" +__gitcomp_builtin_ls_tree_default=" --long --name-only --name-status --object-only --full-name --full-tree --format= --abbrev --no-full-name -- --no-full-tree --no-abbrev" __gitcomp_builtin_merge_default=" --stat --summary --log --squash --commit --edit --cleanup= --ff --ff-only --rerere-autoupdate --verify-signatures --strategy= --strategy-option= --message= --file --into-name= --verbose --quiet --abort --quit --continue --allow-unrelated-histories --progress --gpg-sign --autostash --overwrite-ignore --signoff --no-verify --verify -- --no-stat --no-summary --no-log --no-squash --no-commit --no-edit --no-cleanup --no-ff --no-rerere-autoupdate --no-verify-signatures --no-strategy --no-strategy-option --no-message --no-into-name --no-verbose --no-quiet --no-abort --no-quit --no-continue --no-allow-unrelated-histories --no-progress --no-gpg-sign --no-autostash --no-overwrite-ignore --no-signoff" __gitcomp_builtin_merge_base_default=" --all --octopus --independent --is-ancestor --fork-point --no-all" __gitcomp_builtin_merge_file_default=" --stdout --diff3 --zdiff3 --ours --theirs --union --marker-size= --quiet --no-stdout -- --no-diff3 --no-zdiff3 --no-ours --no-theirs --no-union --no-marker-size --no-quiet" __gitcomp_builtin_mktree_default=" --missing --batch --no-missing -- --no-batch" __gitcomp_builtin_multi_pack_index_default=" --object-dir= --no-object-dir" __gitcomp_builtin_mv_default=" --verbose --dry-run --sparse --no-verbose -- --no-dry-run --no-sparse" -__gitcomp_builtin_name_rev_default=" --name-only --tags --refs= --exclude= --all --stdin --undefined --always --no-name-only -- --no-tags --no-refs --no-exclude --no-all --no-stdin --no-undefined --no-always" +__gitcomp_builtin_name_rev_default=" --name-only --tags --refs= --exclude= --all --stdin --annotate-stdin --undefined --always --no-name-only -- --no-tags --no-refs --no-exclude --no-all --no-stdin --no-annotate-stdin --no-undefined --no-always" __gitcomp_builtin_notes_default=" --ref= --no-ref" __gitcomp_builtin_pack_objects_default=" --quiet --progress --all-progress --all-progress-implied --index-version= --max-pack-size= --local --incremental --window= --window-memory= --depth= --reuse-delta --reuse-object --delta-base-offset --threads= --non-empty --revs --unpacked --all --reflog --indexed-objects --stdin-packs --stdout --include-tag --keep-unreachable --pack-loose-unreachable --unpack-unreachable --sparse --thin --shallow --honor-pack-keep --keep-pack= --compression= --keep-true-parents --use-bitmap-index --write-bitmap-index --filter= --missing= --exclude-promisor-objects --delta-islands --uri-protocol= --no-quiet -- --no-progress --no-all-progress --no-all-progress-implied --no-local --no-incremental --no-window --no-depth --no-reuse-delta --no-reuse-object --no-delta-base-offset --no-threads --no-non-empty --no-revs --no-stdin-packs --no-stdout --no-include-tag --no-keep-unreachable --no-pack-loose-unreachable --no-unpack-unreachable --no-sparse --no-thin --no-shallow --no-honor-pack-keep --no-keep-pack --no-compression --no-keep-true-parents --no-use-bitmap-index --no-write-bitmap-index --no-filter --no-exclude-promisor-objects --no-delta-islands --no-uri-protocol" __gitcomp_builtin_pack_refs_default=" --all --prune --no-all -- --no-prune" @@ -383,12 +390,12 @@ __gitcomp_builtin_range_diff_default=" --creation-factor= --no-dual-color --note __gitcomp_builtin_read_tree_default=" --index-output= --empty --verbose --trivial --aggressive --reset --prefix= --exclude-per-directory= --dry-run --no-sparse-checkout --debug-unpack --recurse-submodules --quiet --sparse-checkout -- --no-empty --no-verbose --no-trivial --no-aggressive --no-reset --no-dry-run --no-debug-unpack --no-recurse-submodules --no-quiet" __gitcomp_builtin_rebase_default=" --onto= --keep-base --no-verify --quiet --verbose --no-stat --signoff --committer-date-is-author-date --reset-author-date --ignore-whitespace --whitespace= --force-rebase --no-ff --continue --skip --abort --quit --edit-todo --show-current-patch --apply --merge --interactive --rerere-autoupdate --empty= --autosquash --gpg-sign --autostash --exec= --rebase-merges --fork-point --strategy= --strategy-option= --root --reschedule-failed-exec --reapply-cherry-picks --verify --stat --ff -- --no-onto --no-keep-base --no-quiet --no-verbose --no-signoff --no-committer-date-is-author-date --no-reset-author-date --no-ignore-whitespace --no-whitespace --no-force-rebase --no-rerere-autoupdate --no-autosquash --no-gpg-sign --no-autostash --no-exec --no-rebase-merges --no-fork-point --no-strategy --no-strategy-option --no-root --no-reschedule-failed-exec --no-reapply-cherry-picks" __gitcomp_builtin_receive_pack_default=" --quiet --no-quiet" -__gitcomp_builtin_reflog_default=" --quiet --source --use-mailmap --decorate-refs= --decorate-refs-exclude= --decorate --no-quiet -- --no-source --no-use-mailmap --no-mailmap --no-decorate-refs --no-decorate-refs-exclude --no-decorate" +__gitcomp_builtin_reflog_default="" __gitcomp_builtin_remote_default=" --verbose --no-verbose" __gitcomp_builtin_repack_default=" --quiet --local --write-bitmap-index --delta-islands --unpack-unreachable= --keep-unreachable --window= --window-memory= --depth= --threads= --max-pack-size= --pack-kept-objects --keep-pack= --geometric= --write-midx --no-quiet -- --no-local --no-write-bitmap-index --no-delta-islands --no-unpack-unreachable --no-keep-unreachable --no-window --no-window-memory --no-depth --no-threads --no-max-pack-size --no-pack-kept-objects --no-keep-pack --no-geometric --no-write-midx" __gitcomp_builtin_replace_default=" --list --delete --edit --graft --convert-graft-file --raw --format= --no-raw -- --no-format" __gitcomp_builtin_rerere_default=" --rerere-autoupdate --no-rerere-autoupdate" -__gitcomp_builtin_reset_default=" --quiet --mixed --soft --hard --merge --keep --recurse-submodules --patch --intent-to-add --pathspec-from-file= --pathspec-file-nul --no-quiet -- --no-mixed --no-soft --no-hard --no-merge --no-keep --no-recurse-submodules --no-patch --no-intent-to-add --no-pathspec-from-file --no-pathspec-file-nul" +__gitcomp_builtin_reset_default=" --quiet --no-refresh --mixed --soft --hard --merge --keep --recurse-submodules --patch --intent-to-add --pathspec-from-file= --pathspec-file-nul --refresh -- --no-quiet --no-mixed --no-soft --no-hard --no-merge --no-keep --no-recurse-submodules --no-patch --no-intent-to-add --no-pathspec-from-file --no-pathspec-file-nul" __gitcomp_builtin_restore_default=" --source= --staged --worktree --ignore-unmerged --overlay --quiet --recurse-submodules --progress --merge --conflict= --ours --theirs --patch --ignore-skip-worktree-bits --pathspec-from-file= --pathspec-file-nul --no-source -- --no-staged --no-worktree --no-ignore-unmerged --no-overlay --no-quiet --no-recurse-submodules --no-progress --no-merge --no-conflict --no-patch --no-ignore-skip-worktree-bits --no-pathspec-from-file --no-pathspec-file-nul" __gitcomp_builtin_revert_default=" --quit --continue --abort --skip --cleanup= --no-commit --edit --signoff --mainline= --rerere-autoupdate --strategy= --strategy-option= --gpg-sign --commit -- --no-cleanup --no-edit --no-signoff --no-mainline --no-rerere-autoupdate --no-strategy --no-strategy-option --no-gpg-sign" __gitcomp_builtin_rm_default=" --dry-run --quiet --cached --ignore-unmatch --sparse --pathspec-from-file= --pathspec-file-nul --no-dry-run -- --no-quiet --no-cached --no-ignore-unmatch --no-sparse --no-pathspec-from-file --no-pathspec-file-nul" @@ -416,7 +423,7 @@ __gitcomp_builtin_verify_tag_default=" --verbose --raw --format= --no-verbose -- __gitcomp_builtin_version_default=" --build-options --no-build-options" __gitcomp_builtin_whatchanged_default=" --quiet --source --use-mailmap --decorate-refs= --decorate-refs-exclude= --decorate --no-quiet -- --no-source --no-use-mailmap --no-mailmap --no-decorate-refs --no-decorate-refs-exclude --no-decorate" __gitcomp_builtin_write_tree_default=" --missing-ok --prefix= --no-missing-ok -- --no-prefix" -__gitcomp_builtin_send_email_default="--cc= --smtp-server= --identity= --smtp-ssl --sender= --from= --cc-cover --no-to-cover --sendmail-cmd= --signed-off-cc --signed-off-by-cc --in-reply-to= --no-cc --confirm= --no-bcc --to= --annotate --smtp-encryption= --relogin-delay= --to-cmd= --smtp-domain= --smtp-auth= --bcc= --quiet --subject= --chain-reply-to --cc-cmd= --no-format-patch --transfer-encoding= --smtp-user= --reply-to= --force --dry-run --no-identity --no-validate --8bit-encoding= --to-cover --compose --thread --format-patch --no-thread --smtp-server-option= --compose-encoding= --smtp-server-port= --no-smtp-auth --no-signed-off-cc --no-signed-off-by-cc --smtp-debug= --no-suppress-from --suppress-from --no-to --dump-aliases --xmailer --no-annotate --no-cc-cover --smtp-pass= --smtp-ssl-cert-path= --no-chain-reply-to --suppress-cc= --validate --batch-size= --envelope-sender= --no-xmailer --numbered --no-numbered --signoff --stdout --cover-letter --numbered-files --suffix= --start-number= --reroll-count= --filename-max-length= --rfc --cover-from-description= --subject-prefix= --output-directory= --keep-subject --no-binary --zero-commit --ignore-if-in-upstream --no-stat --add-header= --from --attach --inline --signature= --base= --signature-file= --progress --interdiff= --range-diff= --creation-factor= --binary -- --no-signoff --no-stdout --no-cover-letter --no-numbered-files --no-suffix --no-start-number --no-reroll-count --no-filename-max-length --no-cover-from-description --no-zero-commit --no-ignore-if-in-upstream --no-add-header --no-from --no-in-reply-to --no-attach --no-signature --no-base --no-signature-file --no-quiet --no-progress --no-interdiff --no-range-diff --no-creation-factor" +__gitcomp_builtin_send_email_default="--sender= --from= --smtp-auth= --8bit-encoding= --no-format-patch --no-bcc --no-suppress-from --no-annotate --relogin-delay= --no-cc --no-signed-off-cc --no-signed-off-by-cc --no-chain-reply-to --smtp-debug= --smtp-domain= --chain-reply-to --dry-run --compose --bcc= --smtp-user= --thread --cc-cover --identity= --to= --reply-to= --no-cc-cover --suppress-cc= --to-cmd= --smtp-server= --smtp-ssl-cert-path= --no-thread --smtp-server-option= --quiet --batch-size= --envelope-sender= --smtp-ssl --no-to --validate --format-patch --suppress-from --cc= --compose-encoding= --to-cover --in-reply-to= --annotate --smtp-encryption= --cc-cmd= --smtp-server-port= --smtp-pass= --signed-off-cc --signed-off-by-cc --no-xmailer --subject= --no-to-cover --confirm= --transfer-encoding= --no-smtp-auth --sendmail-cmd= --no-validate --no-identity --dump-aliases --xmailer --force --numbered --no-numbered --signoff --stdout --cover-letter --numbered-files --suffix= --start-number= --reroll-count= --filename-max-length= --rfc --cover-from-description= --subject-prefix= --output-directory= --keep-subject --no-binary --zero-commit --ignore-if-in-upstream --no-stat --add-header= --from --attach --inline --signature= --base= --signature-file= --progress --interdiff= --range-diff= --creation-factor= --binary -- --no-signoff --no-stdout --no-cover-letter --no-numbered-files --no-suffix --no-start-number --no-reroll-count --no-filename-max-length --no-cover-from-description --no-zero-commit --no-ignore-if-in-upstream --no-add-header --no-from --no-in-reply-to --no-attach --no-signature --no-base --no-signature-file --no-quiet --no-progress --no-interdiff --no-range-diff --no-creation-factor" __gitcomp_builtin_get_default () { @@ -2841,6 +2848,10 @@ _git_restore () --*) __gitcomp_builtin restore ;; + *) + if __git rev-parse --verify --quiet HEAD >/dev/null; then + __git_complete_index_file "--modified" + fi esac } @@ -2942,9 +2953,37 @@ _git_show_branch () __git_complete_revlist } +__gitcomp_directories () +{ + local _tmp_dir _tmp_completions _found=0 + + # Get the directory of the current token; this differs from dirname + # in that it keeps up to the final trailing slash. If no slash found + # that's fine too. + [[ "$cur" =~ .*/ ]] + _tmp_dir=$BASH_REMATCH + + # Find possible directory completions, adding trailing '/' characters, + # de-quoting, and handling unusual characters. + while IFS= read -r -d $'\0' c ; do + # If there are directory completions, find ones that start + # with "$cur", the current token, and put those in COMPREPLY + if [[ $c == "$cur"* ]]; then + COMPREPLY+=("$c/") + _found=1 + fi + done < <(git ls-tree -z -d --name-only HEAD $_tmp_dir) + + if [[ $_found == 0 ]] && [[ "$cur" =~ /$ ]]; then + # No possible further completions any deeper, so assume we're at + # a leaf directory and just consider it complete + __gitcomp_direct_append "$cur " + fi +} + _git_sparse_checkout () { - local subcommands="list init set disable" + local subcommands="list init set disable add reapply" local subcommand="$(__git_find_on_cmdline "$subcommands")" if [ -z "$subcommand" ]; then __gitcomp "$subcommands" @@ -2952,14 +2991,14 @@ _git_sparse_checkout () fi case "$subcommand,$cur" in - init,--*) - __gitcomp_opts "--cone" - ;; - set,--*) - __gitcomp_opts "--stdin" - ;; - *) + *,--*) + __gitcomp_builtin sparse-checkout_$subcommand "" "--" ;; + set,*|add,*) + if [ "$(__git config core.sparseCheckoutCone)" == "true" ] || + [ -n "$(__git_find_on_cmdline --cone)" ]; then + __gitcomp_directories + fi esac } @@ -3411,7 +3450,13 @@ __git_main () then __gitcomp "$GIT_TESTING_PORCELAIN_COMMAND_LIST" else - __gitcomp_nl "$(__git --list-cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config)" + local list_cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config + + if test "${GIT_COMPLETION_SHOW_ALL_COMMANDS-}" = "1" + then + list_cmds=builtins,$list_cmds + fi + __gitcomp_nl "$(__git --list-cmds=$list_cmds)" fi ;; esac @@ -3589,9 +3634,9 @@ if ! git --list-cmds=main >/dev/null 2>&1; then __git_cmds[list-complete]="apply blame cherry config difftool fsck help instaweb mergetool prune reflog remote repack replace request-pull send-email show-branch stage whatchanged" __git_cmds[list-guide]="attributes cli core-tutorial credentials cvs-migration diffcore everyday faq glossary hooks ignore mailmap modules namespaces remote-helpers repository-layout revisions submodules tutorial tutorial-2 workflows" __git_cmds[list-mainporcelain]="add am archive bisect branch bundle checkout cherry-pick citool clean clone commit describe diff fetch format-patch gc grep gui init log maintenance merge mv notes pull push range-diff rebase reset restore revert rm shortlog show sparse-checkout stash status submodule switch tag worktree gitk" - __git_cmds[main]="add add--interactive am annotate apply archimport archive bisect bisect--helper blame branch bugreport bundle cat-file check-attr check-ignore check-mailmap check-ref-format checkout checkout--worker checkout-index cherry cherry-pick citool clean clone column commit commit-graph commit-tree config count-objects credential credential-cache credential-cache--daemon credential-gnome-keyring credential-libsecret credential-store cvsexportcommit cvsimport cvsserver daemon describe diff diff-files diff-index diff-tree difftool difftool--helper env--helper fast-export fast-import fetch fetch-pack filter-branch fmt-merge-msg for-each-ref for-each-repo format-patch fsck fsck-objects gc get-tar-commit-id grep gui gui--askpass hash-object help http-backend http-fetch http-push imap-send index-pack init init-db instaweb interpret-trailers log ls-files ls-remote ls-tree mailinfo mailsplit maintenance merge merge-base merge-file merge-index merge-octopus merge-one-file merge-ours merge-recursive merge-recursive-ours merge-recursive-theirs merge-resolve merge-subtree merge-tree mergetool mktag mktree multi-pack-index mv mw name-rev notes p4 pack-objects pack-redundant pack-refs patch-id pickaxe prune prune-packed pull push quiltimport range-diff read-tree rebase receive-pack reflog remote remote-ext remote-fd remote-ftp remote-ftps remote-http remote-https remote-mediawiki repack replace request-pull rerere reset restore rev-list rev-parse revert rm send-email send-pack sh-i18n--envsubst shell shortlog show show-branch show-index show-ref sparse-checkout stage stash status stripspace submodule submodule--helper subtree svn switch symbolic-ref tag unpack-file unpack-objects update-index update-ref update-server-info upload-archive upload-archive--writer upload-pack var verify-commit verify-pack verify-tag version web--browse whatchanged worktree write-tree" + __git_cmds[main]="add add--interactive am annotate apply archimport archive bisect bisect--helper blame branch bugreport bundle cat-file check-attr check-ignore check-mailmap check-ref-format checkout checkout--worker checkout-index cherry cherry-pick citool clean clone column commit commit-graph commit-tree config count-objects credential credential-cache credential-cache--daemon credential-store cvsexportcommit cvsimport cvsserver daemon describe diff diff-files diff-index diff-tree difftool difftool--helper env--helper fast-export fast-import fetch fetch-pack filter-branch fmt-merge-msg for-each-ref for-each-repo format-patch fsck fsck-objects fsmonitor--daemon gc get-tar-commit-id grep gui gui--askpass hash-object help hook http-backend http-fetch http-push imap-send index-pack init init-db instaweb interpret-trailers legacy-rebase legacy-stash log ls-files ls-remote ls-tree mailinfo mailsplit maintenance merge merge-base merge-file merge-index merge-octopus merge-one-file merge-ours merge-recursive merge-recursive-ours merge-recursive-theirs merge-resolve merge-subtree merge-tree mergetool mktag mktree multi-pack-index mv name-rev notes p4 pack-objects pack-redundant pack-refs patch-id pickaxe prune prune-packed pull push quiltimport range-diff read-tree rebase rebase--helper receive-pack reflog relink remote remote-ext remote-fd remote-ftp remote-ftps remote-http remote-https remote-testsvn repack replace request-pull rerere reset restore rev-list rev-parse revert rm send-email send-pack serve sh-i18n--envsubst shell shortlog show show-branch show-index show-ref sparse-checkout stage stash status stripspace submodule submodule--helper svn switch symbolic-ref tag unpack-file unpack-objects update-index update-ref update-server-info upload-archive upload-archive--writer upload-pack var verify-commit verify-pack verify-tag version web--browse whatchanged worktree write-tree" __git_cmds[others]="" - __git_cmds[parseopt]="add am apply archive bisect--helper blame branch bugreport cat-file check-attr check-ignore check-mailmap checkout checkout--worker checkout-index cherry cherry-pick clean clone column commit commit-graph config count-objects credential-cache credential-cache--daemon credential-store describe difftool env--helper fast-export fetch fmt-merge-msg for-each-ref for-each-repo format-patch fsck fsck-objects gc grep hash-object help init init-db interpret-trailers log ls-files ls-remote ls-tree merge merge-base merge-file mktree multi-pack-index mv name-rev notes pack-objects pack-refs pickaxe prune prune-packed pull push range-diff read-tree rebase receive-pack reflog remote repack replace rerere reset restore revert rm send-pack shortlog show show-branch show-index show-ref sparse-checkout stage stash status stripspace switch symbolic-ref tag update-index update-ref update-server-info upload-pack verify-commit verify-pack verify-tag version whatchanged write-tree " + __git_cmds[parseopt]="add am apply archive bisect--helper blame branch bugreport cat-file check-attr check-ignore check-mailmap checkout checkout--worker checkout-index cherry cherry-pick clean clone column commit commit-graph config count-objects credential-cache credential-cache--daemon credential-store describe difftool env--helper fast-export fetch fmt-merge-msg for-each-ref for-each-repo format-patch fsck fsck-objects fsmonitor--daemon gc grep hash-object help hook init init-db interpret-trailers log ls-files ls-remote ls-tree merge merge-base merge-file mktree multi-pack-index mv name-rev notes pack-objects pack-refs pickaxe prune prune-packed pull push range-diff read-tree rebase receive-pack reflog remote repack replace rerere reset restore revert rm send-pack shortlog show show-branch show-index show-ref sparse-checkout stage stash status stripspace switch symbolic-ref tag update-index update-ref update-server-info upload-pack verify-commit verify-pack verify-tag version whatchanged write-tree " # Override __git __git () diff --git a/plugins/gitfast/git-prompt.sh b/plugins/gitfast/git-prompt.sh index db7c0068f..1435548e0 100644 --- a/plugins/gitfast/git-prompt.sh +++ b/plugins/gitfast/git-prompt.sh @@ -66,6 +66,11 @@ # git always compare HEAD to @{upstream} # svn always compare HEAD to your SVN upstream # +# By default, __git_ps1 will compare HEAD to your SVN upstream if it can +# find one, or @{upstream} otherwise. Once you have set +# GIT_PS1_SHOWUPSTREAM, you can override it on a per-repository basis by +# setting the bash.showUpstream config variable. +# # You can change the separator between the branch name and the above # state symbols by setting GIT_PS1_STATESEPARATOR. The default separator # is SP. @@ -79,11 +84,6 @@ # single '?' character by setting GIT_PS1_COMPRESSSPARSESTATE, or omitted # by setting GIT_PS1_OMITSPARSESTATE. # -# By default, __git_ps1 will compare HEAD to your SVN upstream if it can -# find one, or @{upstream} otherwise. Once you have set -# GIT_PS1_SHOWUPSTREAM, you can override it on a per-repository basis by -# setting the bash.showUpstream config variable. -# # If you would like to see more information about the identity of # commits checked out as a detached HEAD, set GIT_PS1_DESCRIBE_STYLE # to one of these values: @@ -115,7 +115,7 @@ __git_ps1_show_upstream () { local key value local svn_remote svn_url_pattern count n - local upstream=git legacy="" verbose="" name="" + local upstream_type=git legacy="" verbose="" name="" svn_remote=() # get some config options from git-config @@ -132,7 +132,7 @@ __git_ps1_show_upstream () svn-remote.*.url) svn_remote[$((${#svn_remote[@]} + 1))]="$value" svn_url_pattern="$svn_url_pattern\\|$value" - upstream=svn+git # default upstream is SVN if available, else git + upstream_type=svn+git # default upstream type is SVN if available, else git ;; esac done <<< "$output" @@ -141,16 +141,16 @@ __git_ps1_show_upstream () local option for option in ${GIT_PS1_SHOWUPSTREAM}; do case "$option" in - git|svn) upstream="$option" ;; + git|svn) upstream_type="$option" ;; verbose) verbose=1 ;; legacy) legacy=1 ;; name) name=1 ;; esac done - # Find our upstream - case "$upstream" in - git) upstream="@{upstream}" ;; + # Find our upstream type + case "$upstream_type" in + git) upstream_type="@{upstream}" ;; svn*) # get the upstream from the "git-svn-id: ..." in a commit message # (git-svn uses essentially the same procedure internally) @@ -167,12 +167,12 @@ __git_ps1_show_upstream () if [[ -z "$svn_upstream" ]]; then # default branch name for checkouts with no layout: - upstream=${GIT_SVN_ID:-git-svn} + upstream_type=${GIT_SVN_ID:-git-svn} else - upstream=${svn_upstream#/} + upstream_type=${svn_upstream#/} fi - elif [[ "svn+git" = "$upstream" ]]; then - upstream="@{upstream}" + elif [[ "svn+git" = "$upstream_type" ]]; then + upstream_type="@{upstream}" fi ;; esac @@ -180,11 +180,11 @@ __git_ps1_show_upstream () # Find how many commits we are ahead/behind our upstream if [[ -z "$legacy" ]]; then count="$(git rev-list --count --left-right \ - "$upstream"...HEAD 2>/dev/null)" + "$upstream_type"...HEAD 2>/dev/null)" else # produce equivalent output to --count for older versions of git local commits - if commits="$(git rev-list --left-right "$upstream"...HEAD 2>/dev/null)" + if commits="$(git rev-list --left-right "$upstream_type"...HEAD 2>/dev/null)" then local commit behind=0 ahead=0 for commit in $commits @@ -214,26 +214,26 @@ __git_ps1_show_upstream () *) # diverged from upstream p="<>" ;; esac - else + else # verbose, set upstream instead of p case "$count" in "") # no upstream - p="" ;; + upstream="" ;; "0 0") # equal to upstream - p=" u=" ;; + upstream="|u=" ;; "0 "*) # ahead of upstream - p=" u+${count#0 }" ;; + upstream="|u+${count#0 }" ;; *" 0") # behind upstream - p=" u-${count% 0}" ;; + upstream="|u-${count% 0}" ;; *) # diverged from upstream - p=" u+${count#* }-${count% *}" ;; + upstream="|u+${count#* }-${count% *}" ;; esac if [[ -n "$count" && -n "$name" ]]; then __git_ps1_upstream_name=$(git rev-parse \ - --abbrev-ref "$upstream" 2>/dev/null) + --abbrev-ref "$upstream_type" 2>/dev/null) if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then - p="$p \${__git_ps1_upstream_name}" + upstream="$upstream \${__git_ps1_upstream_name}" else - p="$p ${__git_ps1_upstream_name}" + upstream="$upstream ${__git_ps1_upstream_name}" # not needed anymore; keep user's # environment clean unset __git_ps1_upstream_name @@ -245,7 +245,8 @@ __git_ps1_show_upstream () # Helper function that is meant to be called from __git_ps1. It # injects color codes into the appropriate gitstring variables used -# to build a gitstring. +# to build a gitstring. Colored variables are responsible for clearing +# their own color. __git_ps1_colorize_gitstring () { if [[ -n ${ZSH_VERSION-} ]]; then @@ -271,22 +272,23 @@ __git_ps1_colorize_gitstring () else branch_color="$bad_color" fi - c="$branch_color$c" + if [ -n "$c" ]; then + c="$branch_color$c$c_clear" + fi + b="$branch_color$b$c_clear" - z="$c_clear$z" - if [ "$w" = "*" ]; then - w="$bad_color$w" + if [ -n "$w" ]; then + w="$bad_color$w$c_clear" fi if [ -n "$i" ]; then - i="$ok_color$i" + i="$ok_color$i$c_clear" fi if [ -n "$s" ]; then - s="$flags_color$s" + s="$flags_color$s$c_clear" fi if [ -n "$u" ]; then - u="$bad_color$u" + u="$bad_color$u$c_clear" fi - r="$c_clear$r" } # Helper function to read the first line of a file into a variable. @@ -512,7 +514,8 @@ __git_ps1 () local u="" local h="" local c="" - local p="" + local p="" # short version of upstream state indicator + local upstream="" # verbose version of upstream state indicator if [ "true" = "$inside_gitdir" ]; then if [ "true" = "$bare_repo" ]; then @@ -555,6 +558,12 @@ __git_ps1 () local z="${GIT_PS1_STATESEPARATOR-" "}" + b=${b##refs/heads/} + if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then + __git_ps1_branch_name=$b + b="\${__git_ps1_branch_name}" + fi + # NO color option unless in PROMPT_COMMAND mode or it's Zsh if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then if [ $pcmode = yes ] || [ -n "${ZSH_VERSION-}" ]; then @@ -562,14 +571,8 @@ __git_ps1 () fi fi - b=${b##refs/heads/} - if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then - __git_ps1_branch_name=$b - b="\${__git_ps1_branch_name}" - fi - - local f="$h$w$i$s$u" - local gitstring="$c$b${f:+$z$f}${sparse}$r$p" + local f="$h$w$i$s$u$p" + local gitstring="$c$b${f:+$z$f}${sparse}$r${upstream}" if [ $pcmode = yes ]; then if [ "${__git_printf_supports_v-}" != yes ]; then diff --git a/plugins/gitfast/update b/plugins/gitfast/update index 5ebaaef3d..feb13ff7e 100755 --- a/plugins/gitfast/update +++ b/plugins/gitfast/update @@ -1,7 +1,7 @@ #!/bin/sh url="https://raw.githubusercontent.com/felipec/git-completion" -version="1.3.6" +version="1.3.7" curl -s -o _git "${url}/v${version}/git-completion.zsh" && curl -s -o git-completion.bash "${url}/v${version}/git-completion.bash" && diff --git a/plugins/github/README.md b/plugins/github/README.md index af2b8a4e7..5d8b62501 100644 --- a/plugins/github/README.md +++ b/plugins/github/README.md @@ -11,7 +11,6 @@ This plugin supports working with GitHub from the command line. It provides a fe * `empty_gh` - Creates a new empty repo (with a `README.md`) and pushes it to GitHub * `new_gh` - Initializes an existing directory as a repo and pushes it to GitHub * `exist_gh` - Takes an existing repo and pushes it to GitHub -* `git.io` - Shortens a URL using [git.io](https://git.io) ## Installation diff --git a/plugins/github/github.plugin.zsh b/plugins/github/github.plugin.zsh index 8e4b97352..79114ff69 100644 --- a/plugins/github/github.plugin.zsh +++ b/plugins/github/github.plugin.zsh @@ -68,8 +68,9 @@ exist_gh() { # [DIRECTORY] # documentation: https://github.com/blog/985-git-io-github-url-shortener # git.io() { - emulate -L zsh - curl -i -s https://git.io -F "url=$1" | grep "Location" | cut -f 2 -d " " + # emulate -L zsh + # curl -i -s https://git.io -F "url=$1" | grep "Location" | cut -f 2 -d " " + print -u2 ${(%):-"%F{yellow}%BThe \`git.io\` is deprecated.%b\nView the announcement made by GitHub: https://github.blog/changelog/2022-01-11-git-io-no-longer-accepts-new-urls/%f"} } # End Functions ############################################################# diff --git a/plugins/gnu-utils/gnu-utils.plugin.zsh b/plugins/gnu-utils/gnu-utils.plugin.zsh index 9419127d8..6023bf2b4 100644 --- a/plugins/gnu-utils/gnu-utils.plugin.zsh +++ b/plugins/gnu-utils/gnu-utils.plugin.zsh @@ -19,7 +19,7 @@ __gnu_utils() { 'gchown' 'gchroot' 'gcksum' 'gcomm' 'gcp' 'gcsplit' 'gcut' 'gdate' 'gdd' 'gdf' 'gdir' 'gdircolors' 'gdirname' 'gdu' 'gecho' 'genv' 'gexpand' 'gexpr' 'gfactor' 'gfalse' 'gfmt' 'gfold' 'ggroups' 'ghead' 'ghostid' - 'gid' 'ginstall' 'gjoin' 'gkill' 'glink' 'gln' 'glogname' 'gls' 'gmd5sum' + 'gid' 'gindent' 'ginstall' 'gjoin' 'gkill' 'glink' 'gln' 'glogname' 'gls' 'gmd5sum' 'gmkdir' 'gmkfifo' 'gmknod' 'gmktemp' 'gmv' 'gnice' 'gnl' 'gnohup' 'gnproc' 'god' 'gpaste' 'gpathchk' 'gpinky' 'gpr' 'gprintenv' 'gprintf' 'gptx' 'gpwd' 'greadlink' 'grm' 'grmdir' 'gruncon' 'gseq' 'gsha1sum' 'gsha224sum' @@ -61,3 +61,14 @@ __gnu_utils_preexec() { autoload -Uz add-zsh-hook add-zsh-hook preexec __gnu_utils_preexec + +# lib/theme-and-appearance.zsh sets the alias for ls not knowing that +# we'll be using GNU ls. We'll reset this to use GNU ls --color. +# See https://github.com/ohmyzsh/ohmyzsh/issues/11503 +# +# The ls alias might look like: +# - ls='ls -G' +# - ls='gls --color=tty' +if [[ -x "${commands[gls]}" && "${aliases[ls]}" = (*-G*|gls*) ]]; then + alias ls='ls --color=tty' +fi diff --git a/plugins/golang/README.md b/plugins/golang/README.md index 979c89010..128cc7fbb 100644 --- a/plugins/golang/README.md +++ b/plugins/golang/README.md @@ -16,11 +16,12 @@ plugins=(... golang) | gob | `go build` | Build your code | | goc | `go clean` | Removes object files from package source directories | | god | `go doc` | Prints documentation comments | +| goe | `go env` | Prints Go environment information | | gof | `go fmt` | Gofmt formats (aligns and indents) Go programs. | | gofa | `go fmt ./...` | Run go fmt for all packages in current directory, recursively | | gofx | `go fix` | Update packages to use a new API | | gog | `go get` | Downloads packages and then installs them to $GOPATH | -| gog | `go get ./...` | Installs all dependencies in current directory, recursively | +| goga | `go get ./...` | Installs all dependencies in current directory, recursively | | goi | `go install` | Compiles and installs packages to $GOPATH | | gol | `go list` | Lists Go packages | | gom | `go mod` | Access to operations on modules | @@ -35,3 +36,5 @@ plugins=(... golang) | gotod | `go tool dist` | Utility to bootstrap, build and test go runtime | | gotofx | `go tool fix` | Fixes an application to use newer features | | gov | `go vet` | Vet examines Go source code and reports suspicious constructs | +| gove | `go version` | Prints Go version | +| gow | `go work` | Work provides access to operations on workspaces | diff --git a/plugins/golang/golang.plugin.zsh b/plugins/golang/golang.plugin.zsh index 4dafecd86..45ccd3a1c 100644 --- a/plugins/golang/golang.plugin.zsh +++ b/plugins/golang/golang.plugin.zsh @@ -13,6 +13,7 @@ unset p alias gob='go build' alias goc='go clean' alias god='go doc' +alias goe='go env' alias gof='go fmt' alias gofa='go fmt ./...' alias gofx='go fix' @@ -32,3 +33,5 @@ alias gotoc='go tool compile' alias gotod='go tool dist' alias gotofx='go tool fix' alias gov='go vet' +alias gove='go version' +alias gow='go work' diff --git a/plugins/gradle/_gradle b/plugins/gradle/_gradle index e77b23cdb..f8df928b4 100644 --- a/plugins/gradle/_gradle +++ b/plugins/gradle/_gradle @@ -1,4 +1,6 @@ #compdef gradle gradlew gw +# THE LINE ABOVE MUST BE THE FIRST LINE OF THIS FILE IN ORDER FOR COMPLETION TO WORK + # # Taken from https://github.com/gradle/gradle-completion # Copyright (c) 2017 Eric Wendelin @@ -116,9 +118,9 @@ __gradle-generate-tasks-cache() { # Reuse Gradle Daemon if IDLE but don't start a new one. local gradle_tasks_output if [[ ! -z "$($gradle_cmd --status 2>/dev/null | grep IDLE)" ]]; then - gradle_tasks_output="$($gradle_cmd --daemon --build-file $gradle_build_file --console plain -q tasks --all 2>/dev/null)" + gradle_tasks_output="$($gradle_cmd --daemon --no-scan --build-file $gradle_build_file --console=plain -q tasks --all 2>/dev/null)" else - gradle_tasks_output="$($gradle_cmd --no-daemon --build-file $gradle_build_file --console plain -q tasks --all 2>/dev/null)" + gradle_tasks_output="$($gradle_cmd --no-daemon --no-scan --build-file $gradle_build_file --console=plain -q tasks --all 2>/dev/null)" fi local gradle_all_tasks="" root_tasks="" subproject_tasks="" output_line local -a match @@ -180,7 +182,7 @@ __gradle_tasks() { local cached_checksum="$(cat $cache_dir/$cache_name.md5)" local -a cached_tasks if [[ -z $cur ]]; then - cached_tasks=(${(f)"$(cat $cache_dir/$cached_checksum)"}) + cached_tasks=(${(f)"$(grep -v "^\\\:" $cache_dir/$cached_checksum)"}) else cached_tasks=(${(f)"$(grep "^${cur//:/\\\\:}" $cache_dir/$cached_checksum)"}) fi @@ -191,7 +193,7 @@ __gradle_tasks() { # Regenerate tasks cache in the background if [[ $gradle_files_checksum != "$(cat $cache_dir/$cache_name.md5)" || ! -f $cache_dir/$gradle_files_checksum || $(wc -c < $cache_dir/$gradle_files_checksum) -le 1 ]]; then - $(__gradle-generate-tasks-cache 1>&2 2>/dev/null &) + $(__gradle-generate-tasks-cache &> /dev/null &) fi else _describe 'built-in tasks' '( @@ -262,7 +264,10 @@ __gradle_subcommand() { {-b,--build-file}'[Specifies the build file.]:build script:_files -g \*.gradle' \ {-C,--cache}'[Specifies how compiled build scripts should be cached.]:cache policy:(on rebuild)' \ {-c,--settings-file}'[Specifies the settings file.]:settings file:_files -g \*.gradle' \ + '(--configuration-cache)--no-configuration-cache[Disables the configuration cache. Gradle will not reuse the build configuration from previous builds.]' \ + '--configuration-cache-problems=[Configures how the configuration cache handles problems]:problem handling:(fail warn)' \ '(--no-configure-on-demand)--configure-on-demand[Only relevant projects are configured in this build run.]' \ + '(--no-configuration-cache)--configuration-cache[Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds.]' \ '--console=[Specifies which type of console output to generate.]:console output type:(plain auto rich verbose)' \ '--continue[Continues task execution after a task failure.]' \ '-Dorg.gradle.cache.reserved.mb=[Reserve Gradle Daemon memory for operations.]' \ @@ -276,6 +281,7 @@ __gradle_subcommand() { '-Dorg.gradle.logging.level=[Set default Gradle log level.]:log level:(quiet warn lifecycle info debug)' \ '-Dorg.gradle.parallel=[Set true to enable parallel project builds.]:enable parallel build:(true false)' \ '-Dorg.gradle.priority=[Set priority for Gradle worker processes.]:priority:(low normal)' \ + '-Dorg.gradle.unsafe.watch-fs=[Set true to enable Gradle file watcher.]:enable watcher:(true false)' \ '-Dorg.gradle.warning.mode=[Set types of warnings to log.]:warning level:(all summary none)' \ '-Dorg.gradle.workers.max=[Set the number of workers Gradle is allowed to use.]' \ '(-i --info -w --warn -q --quiet)'{-d,--debug}'[Log in debug mode (includes normal stacktrace).]' \ @@ -314,6 +320,7 @@ __gradle_subcommand() { '(--write-locks)--update-locks[Perform a partial update of the dependency lock.]' \ '(-d --debug -q --quiet -i --info)'{-w,--warn}'[Log warnings and errors only.]' \ '--warning-mode=[Set types of warnings to log.]:warning mode:(all summary none)' \ + '(--no-watch-fs)--watch-fs[Gradle watches filesystem for incremental builds.]' \ '(--update-locks)--write-locks[Persists dependency resolution for locked configurations.]' \ {-x,--exclude-task}'[Specify a task to be excluded from execution.]' && ret=0 ;; @@ -347,6 +354,9 @@ _gradle() { {-b,--build-file}'[Specifies the build file.]:build script:_files -g \*.gradle' \ {-C,--cache}'[Specifies how compiled build scripts should be cached.]:cache policy:(on rebuild)' \ {-c,--settings-file}'[Specifies the settings file.]:settings file:_files -g \*.gradle:->argument-expected' \ + '(--no-configuration-cache)--configuration-cache[Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds.]' \ + '(--configuration-cache)--no-configuration-cache[Disables the configuration cache. Gradle will not reuse the build configuration from previous builds.]' \ + '--configuration-cache-problems=[Configures how the configuration cache handles problems]:problem handling:(fail warn)' \ '(--no-configure-on-demand)--configure-on-demand[Only relevant projects are configured in this build run.]' \ '--console=[Specifies which type of console output to generate.]:console output type:(plain auto rich verbose)' \ '--continue[Continues task execution after a task failure.]' \ @@ -361,6 +371,7 @@ _gradle() { '-Dorg.gradle.logging.level=[Set default Gradle log level.]:log level:(quiet warn lifecycle info debug)' \ '-Dorg.gradle.parallel=[Set true to enable parallel project builds.]:(true false)' \ '-Dorg.gradle.priority=[Set priority for Gradle worker processes.]:priority:(low normal)' \ + '-Dorg.gradle.unsafe.watch-fs=[Set true to enable Gradle file watcher.]:enable watcher:(true false)' \ '-Dorg.gradle.warning.mode=[Set types of warnings to log.]:warning level:(all summary none)' \ '-Dorg.gradle.workers.max=[Set the number of workers Gradle is allowed to use.]' \ '(-i --info -w --warn -q --quiet)'{-d,--debug}'[Log in debug mode (includes normal stacktrace).]' \ @@ -404,6 +415,7 @@ _gradle() { '(-d --debug -q --quiet -i --info)'{-w,--warn}'[Log warnings and errors only.]' \ '--warning-mode=[Set types of warnings to log.]:warning mode:(all summary none)' \ '(--update-locks)--write-locks[Persists dependency resolution for locked configurations.]' \ + '(--no-watch-fs)--watch-fs[Gradle watches filesystem for incremental builds.]' \ {-x,--exclude-task}'[Specify a task to be excluded from execution.]' \ '(-)*:: :->task-or-option' && ret=0 diff --git a/plugins/hasura/README.md b/plugins/hasura/README.md new file mode 100644 index 000000000..d7db9ed92 --- /dev/null +++ b/plugins/hasura/README.md @@ -0,0 +1,9 @@ +# Hasura plugin + +This plugin adds completion for [the Hasura CLI](https://hasura.io/docs/latest/hasura-cli/index/). + +To use it, add `hasura` to the plugins array in your zshrc file: + +```zsh +plugins=(... hasura) +``` diff --git a/plugins/hasura/hasura.plugin.zsh b/plugins/hasura/hasura.plugin.zsh new file mode 100644 index 000000000..18254c43b --- /dev/null +++ b/plugins/hasura/hasura.plugin.zsh @@ -0,0 +1,13 @@ +if (( ! $+commands[hasura] )); then + return +fi + +# If the completion file does not exist, generate it and then source it +# Otherwise, source it and regenerate in the background +if [[ ! -f "$ZSH_CACHE_DIR/completions/_hasura" ]]; then + hasura completion zsh --file "$ZSH_CACHE_DIR/completions/_hasura" >/dev/null + source "$ZSH_CACHE_DIR/completions/_hasura" +else + source "$ZSH_CACHE_DIR/completions/_hasura" + hasura completion zsh --file "$ZSH_CACHE_DIR/completions/_hasura" >/dev/null &| +fi diff --git a/plugins/helm/README.md b/plugins/helm/README.md index 49844c78f..8be024bfb 100644 --- a/plugins/helm/README.md +++ b/plugins/helm/README.md @@ -1,9 +1,18 @@ # Helm plugin -This plugin adds completion for [Helm](https://helm.sh/), the Kubernetes package manager. +This plugin adds completion and aliases for [Helm](https://helm.sh/), the Kubernetes package manager. To use it, add `helm` to the plugins array in your zshrc file: ```zsh plugins=(... helm) ``` + +## Aliases + +| Alias | Full command | +| ----- | ------------ | +| h | helm | +| hin | helm install | +| hse | helm search | +| hup | helm upgrade | diff --git a/plugins/helm/helm.plugin.zsh b/plugins/helm/helm.plugin.zsh index 151c43d88..7fc05be98 100644 --- a/plugins/helm/helm.plugin.zsh +++ b/plugins/helm/helm.plugin.zsh @@ -11,3 +11,8 @@ else source "$ZSH_CACHE_DIR/completions/_helm" helm completion zsh | tee "$ZSH_CACHE_DIR/completions/_helm" >/dev/null &| fi + +alias h='helm' +alias hin='helm install' +alias hse='helm search' +alias hup='helm upgrade' diff --git a/plugins/heroku-alias/README.md b/plugins/heroku-alias/README.md new file mode 100644 index 000000000..4b7b953fd --- /dev/null +++ b/plugins/heroku-alias/README.md @@ -0,0 +1,127 @@ +# heroku-alias +🧬 Full alias for heroku cli + +|🚀 last maj|📡 source| +|---|---| +|02/06/2020|[heroku cli doc](https://devcenter.heroku.com/articles/heroku-cli-commands)| + +# Alias list + +## general +| Alias | Command | +| ------------- | ------------- | +| h | heroku | +| hauto | heroku autocomplete $(echo $SHELL) | +| hl | heroku local | + +## config +| Alias | Command | +| ------------- | ------------- | +| hc | heroku config | +| hca | heroku config -a | +| hcr | heroku config -r | +| hcs | heroku config:set | +| hcu | heroku config:unset | +| hcfile | function hcfile bellow | + +```sh +hcfile() { + echo " Which platform [-r/a name] ? " + read platform + echo " Which file ? " + read file + while read line; + do heroku config:set "$platform" "$line"; + done < "$file" +} +``` + +## apps and favorites +| Alias | Command | +| ------------- | ------------- | +| ha | heroku apps | +| hpop | heroku create | +| hkill | heroku apps:destroy | +| hlog | heroku apps:errors | +| hfav | heroku apps:favorites | +| hfava | heroku apps:favorites:add | +| hfavr | heroku apps:favorites:remove | +| hai | heroku apps:info | +| hair | heroku apps:info -r | +| haia | heroku apps:info -a | + +# auth +| Alias | Command | +| ------------- | ------------- | +| h2fa | heroku auth:2fa | +| h2far | heroku auth:2fa:disable | + +# access +| Alias | Command | +| ------------- | ------------- | +| hac | heroku access | +| hacr | heroku access -r | +| haca | heroku access -a | +| hadd | heroku access:add | +| hdel | heroku access:remove | +| hup | heroku access:update | + +## addons +| Alias | Command | +| ------------- | ------------- | +| hads | heroku addons -A | +| hada | heroku addons -a | +| hadr | heroku addons -r | +| hadat | heroku addons:attach | +| hadc | heroku addons:create | +| hadel | heroku addons:destroy | +| hadde | heroku addons:detach | +| hadoc | heroku addons:docs | + +## login +| Alias | Command | +| ------------- | ------------- | +| hin | heroku login | +| hout | heroku logout | +| hi | heroku login -i | +| hwho | heroku auth:whoami | + +## authorizations +| Alias | Command | +| ------------- | ------------- | +| hth | heroku authorizations | +| hthadd | heroku authorizations:create | +| hthif | heroku authorizations:info | +| hthdel | heroku authorizations:revoke | +| hthrot | heroku authorizations:rotate | +| hthup | heroku authorizations:update | + +## plugins +| Alias | Command | +| ------------- | ------------- | +| hp | heroku plugins | + +# log +| Alias | Command | +| ------------- | ------------- | +|hg | heroku logs| +| hgt | heroku log tail | + +# database +| Alias | Command | +| ------------- | ------------- | +| hpg | heroku pg | +| hpsql | heroku pg:psql | +| hpb | heroku pg:backups | +| hpbc | heroku pg:backups:capture | +| hpbd | heroku pg:backups:download | +| hpbr | heroku pg:backups:restore | + +# certs +| Alias | Command | +| ------------- | ------------- | +| hssl | heroku certs | +| hssli | heroku certs:info | +| hssla | heroku certs:add | +| hsslu | heroku certs:update | +| hsslr | heroku certs:remove | diff --git a/plugins/heroku-alias/heroku.alias.sh b/plugins/heroku-alias/heroku.alias.sh new file mode 100644 index 000000000..7daf715b5 --- /dev/null +++ b/plugins/heroku-alias/heroku.alias.sh @@ -0,0 +1,92 @@ +# general +alias h='heroku' +alias hauto='heroku autocomplete $(echo $SHELL)' +alias hl='heroku local' + +# log +alias hg='heroku logs' +alias hgt='heroku log tail' + +# database +alias hpg='heroku pg' +alias hpsql='heroku pg:psql' +alias hpb='heroku pg:backups' +alias hpbc='heroku pg:backups:capture' +alias hpbd='heroku pg:backups:download' +alias hpbr='heroku pg:backups:restore' + +# config +alias hc='heroku config' +alias hca='heroku config -a' +alias hcr='heroku config -r' +alias hcs='heroku config:set' +alias hcu='heroku config:unset' + +# this function allow to load multi env set in a file +hcfile() { + echo 'Which platform [-r/a name] ?' + read platform + echo 'Which file ?' + read file + while read line; + do heroku config:set "$platform" "$line"; + done < "$file" +} + +# apps and favorites +alias ha='heroku apps' +alias hpop='heroku create' +alias hkill='heroku apps:destroy' +alias hlog='heroku apps:errors' +alias hfav='heroku apps:favorites' +alias hfava='heroku apps:favorites:add' +alias hfavr='heroku apps:favorites:remove' +alias hai='heroku apps:info' +alias hair='heroku apps:info -r' +alias haia='heroku apps:info -a' + +# auth +alias h2fa='heroku auth:2fa' +alias h2far='heroku auth:2fa:disable' + +# access +alias hac='heroku access' +alias hacr='heroku access -r' +alias haca='heroku access -a' +alias hadd='heroku access:add' +alias hdel='heroku access:remove' +alias hup='heroku access:update' + +# addons +alias hads='heroku addons -A' +alias hada='heroku addons -a' +alias hadr='heroku addons -r' +alias hadat='heroku addons:attach' +alias hadc='heroku addons:create' +alias hadel='heroku addons:destroy' +alias hadde='heroku addons:detach' +alias hadoc='heroku addons:docs' + +# login +alias hin='heroku login' +alias hout='heroku logout' +alias hi='heroku login -i' +alias hwho='heroku auth:whoami' + +# authorizations +alias hth='heroku authorizations' +alias hthadd='heroku authorizations:create' +alias hthif='heroku authorizations:info' +alias hthdel='heroku authorizations:revoke' +alias hthrot='heroku authorizations:rotate' +alias hthup='heroku authorizations:update' + +# plugins +alias hp='heroku plugins' + +# cert +alias hssl='heroku certs' +alias hssli='heroku certs:info' +alias hssla='heroku certs:add' +alias hsslu='heroku certs:update' +alias hsslr='heroku certs:remove' diff --git a/plugins/httpie/_httpie b/plugins/httpie/_httpie index 4d702ef60..11bc8e1f8 100644 --- a/plugins/httpie/_httpie +++ b/plugins/httpie/_httpie @@ -1,6 +1,6 @@ #compdef http # ------------------------------------------------------------------------------ -# Copyright (c) 2015 Github zsh-users - http://github.com/zsh-users +# Copyright (c) 2015 GitHub zsh-users - http://github.com/zsh-users # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/plugins/iterm2/README.md b/plugins/iterm2/README.md index 50cdebf5e..3d11622df 100644 --- a/plugins/iterm2/README.md +++ b/plugins/iterm2/README.md @@ -2,11 +2,20 @@ This plugin adds a few functions that are useful when using [iTerm2](https://www.iterm2.com/). + To use it, add _iterm2_ to the plugins array of your zshrc file: ``` plugins=(... iterm2) ``` +Optionally, the plugin also applies the [Shell Integration Script for iTerm2](https://iterm2.com/documentation-shell-integration.html). +You can enable the integration with zstyle. It's important to add this line +before the line sourcing oh-my-zsh: + +``` +zstyle :omz:plugins:iterm2 shell-integration yes +``` + ## Plugin commands * `_iterm2_command ` @@ -24,6 +33,9 @@ plugins=(... iterm2) * `iterm2_tab_color_reset` resets the color of iTerm2's current tab back to default. + +For shell integration features see the [official documentation](https://iterm2.com/documentation-shell-integration.html). + ## Contributors - [Aviv Rosenberg](https://github.com/avivrosenberg) diff --git a/plugins/iterm2/iterm2.plugin.zsh b/plugins/iterm2/iterm2.plugin.zsh index 9d8e40bf6..d00232a30 100644 --- a/plugins/iterm2/iterm2.plugin.zsh +++ b/plugins/iterm2/iterm2.plugin.zsh @@ -7,6 +7,17 @@ # This plugin is only relevant if the terminal is iTerm2 on OSX. if [[ "$OSTYPE" == darwin* ]] && [[ -n "$ITERM_SESSION_ID" ]] ; then + # maybe make it the default in the future and allow opting out? + if zstyle -t ':omz:plugins:iterm2' shell-integration; then + # Handle $0 according to the standard: + # https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html + 0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}" + 0="${${(M)0:#/*}:-$PWD/$0}" + + # See official docs: https://iterm2.com/documentation-shell-integration.html + source "${0:A:h}/iterm2_shell_integration.zsh" + fi + ### # Executes an arbitrary iTerm2 command via an escape code sequence. # See https://iterm2.com/documentation-escape-codes.html for all supported commands. diff --git a/plugins/iterm2/iterm2_shell_integration.zsh b/plugins/iterm2/iterm2_shell_integration.zsh new file mode 100644 index 000000000..7871ddded --- /dev/null +++ b/plugins/iterm2/iterm2_shell_integration.zsh @@ -0,0 +1,178 @@ +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +if [[ -o interactive ]]; then + if [ "${ITERM_ENABLE_SHELL_INTEGRATION_WITH_TMUX-}""$TERM" != "tmux-256color" -a "${ITERM_ENABLE_SHELL_INTEGRATION_WITH_TMUX-}""$TERM" != "screen" -a "${ITERM_SHELL_INTEGRATION_INSTALLED-}" = "" -a "$TERM" != linux -a "$TERM" != dumb ]; then + ITERM_SHELL_INTEGRATION_INSTALLED=Yes + ITERM2_SHOULD_DECORATE_PROMPT="1" + # Indicates start of command output. Runs just before command executes. + iterm2_before_cmd_executes() { + if [ "$TERM_PROGRAM" = "iTerm.app" ]; then + printf "\033]133;C;\r\007" + else + printf "\033]133;C;\007" + fi + } + + iterm2_set_user_var() { + printf "\033]1337;SetUserVar=%s=%s\007" "$1" $(printf "%s" "$2" | base64 | tr -d '\n') + } + + # Users can write their own version of this method. It should call + # iterm2_set_user_var but not produce any other output. + # e.g., iterm2_set_user_var currentDirectory $PWD + # Accessible in iTerm2 (in a badge now, elsewhere in the future) as + # \(user.currentDirectory). + whence -v iterm2_print_user_vars > /dev/null 2>&1 + if [ $? -ne 0 ]; then + iterm2_print_user_vars() { + true + } + fi + + iterm2_print_state_data() { + local _iterm2_hostname="${iterm2_hostname-}" + if [ -z "${iterm2_hostname:-}" ]; then + _iterm2_hostname=$(hostname -f 2>/dev/null) + fi + printf "\033]1337;RemoteHost=%s@%s\007" "$USER" "${_iterm2_hostname-}" + printf "\033]1337;CurrentDir=%s\007" "$PWD" + iterm2_print_user_vars + } + + # Report return code of command; runs after command finishes but before prompt + iterm2_after_cmd_executes() { + printf "\033]133;D;%s\007" "$STATUS" + iterm2_print_state_data + } + + # Mark start of prompt + iterm2_prompt_mark() { + printf "\033]133;A\007" + } + + # Mark end of prompt + iterm2_prompt_end() { + printf "\033]133;B\007" + } + + # There are three possible paths in life. + # + # 1) A command is entered at the prompt and you press return. + # The following steps happen: + # * iterm2_preexec is invoked + # * PS1 is set to ITERM2_PRECMD_PS1 + # * ITERM2_SHOULD_DECORATE_PROMPT is set to 1 + # * The command executes (possibly reading or modifying PS1) + # * iterm2_precmd is invoked + # * ITERM2_PRECMD_PS1 is set to PS1 (as modified by command execution) + # * PS1 gets our escape sequences added to it + # * zsh displays your prompt + # * You start entering a command + # + # 2) You press ^C while entering a command at the prompt. + # The following steps happen: + # * (iterm2_preexec is NOT invoked) + # * iterm2_precmd is invoked + # * iterm2_before_cmd_executes is called since we detected that iterm2_preexec was not run + # * (ITERM2_PRECMD_PS1 and PS1 are not messed with, since PS1 already has our escape + # sequences and ITERM2_PRECMD_PS1 already has PS1's original value) + # * zsh displays your prompt + # * You start entering a command + # + # 3) A new shell is born. + # * PS1 has some initial value, either zsh's default or a value set before this script is sourced. + # * iterm2_precmd is invoked + # * ITERM2_SHOULD_DECORATE_PROMPT is initialized to 1 + # * ITERM2_PRECMD_PS1 is set to the initial value of PS1 + # * PS1 gets our escape sequences added to it + # * Your prompt is shown and you may begin entering a command. + # + # Invariants: + # * ITERM2_SHOULD_DECORATE_PROMPT is 1 during and just after command execution, and "" while the prompt is + # shown and until you enter a command and press return. + # * PS1 does not have our escape sequences during command execution + # * After the command executes but before a new one begins, PS1 has escape sequences and + # ITERM2_PRECMD_PS1 has PS1's original value. + iterm2_decorate_prompt() { + # This should be a raw PS1 without iTerm2's stuff. It could be changed during command + # execution. + ITERM2_PRECMD_PS1="$PS1" + ITERM2_SHOULD_DECORATE_PROMPT="" + + # Add our escape sequences just before the prompt is shown. + # Use ITERM2_SQUELCH_MARK for people who can't mdoify PS1 directly, like powerlevel9k users. + # This is gross but I had a heck of a time writing a correct if statetment for zsh 5.0.2. + local PREFIX="" + if [[ $PS1 == *"$(iterm2_prompt_mark)"* ]]; then + PREFIX="" + elif [[ "${ITERM2_SQUELCH_MARK-}" != "" ]]; then + PREFIX="" + else + PREFIX="%{$(iterm2_prompt_mark)%}" + fi + PS1="$PREFIX$PS1%{$(iterm2_prompt_end)%}" + ITERM2_DECORATED_PS1="$PS1" + } + + iterm2_precmd() { + local STATUS="$?" + if [ -z "${ITERM2_SHOULD_DECORATE_PROMPT-}" ]; then + # You pressed ^C while entering a command (iterm2_preexec did not run) + iterm2_before_cmd_executes + if [ "$PS1" != "${ITERM2_DECORATED_PS1-}" ]; then + # PS1 changed, perhaps in another precmd. See issue 9938. + ITERM2_SHOULD_DECORATE_PROMPT="1" + fi + fi + + iterm2_after_cmd_executes "$STATUS" + + if [ -n "$ITERM2_SHOULD_DECORATE_PROMPT" ]; then + iterm2_decorate_prompt + fi + } + + # This is not run if you press ^C while entering a command. + iterm2_preexec() { + # Set PS1 back to its raw value prior to executing the command. + PS1="$ITERM2_PRECMD_PS1" + ITERM2_SHOULD_DECORATE_PROMPT="1" + iterm2_before_cmd_executes + } + + # If hostname -f is slow on your system set iterm2_hostname prior to + # sourcing this script. We know it is fast on macOS so we don't cache + # it. That lets us handle the hostname changing like when you attach + # to a VPN. + if [ -z "${iterm2_hostname-}" ]; then + if [ "$(uname)" != "Darwin" ]; then + iterm2_hostname=`hostname -f 2>/dev/null` + # Some flavors of BSD (i.e. NetBSD and OpenBSD) don't have the -f option. + if [ $? -ne 0 ]; then + iterm2_hostname=`hostname` + fi + fi + fi + + [[ -z ${precmd_functions-} ]] && precmd_functions=() + precmd_functions=($precmd_functions iterm2_precmd) + + [[ -z ${preexec_functions-} ]] && preexec_functions=() + preexec_functions=($preexec_functions iterm2_preexec) + + iterm2_print_state_data + printf "\033]1337;ShellIntegrationVersion=14;shell=zsh\007" + fi +fi diff --git a/plugins/iterm2/update b/plugins/iterm2/update new file mode 100755 index 000000000..da8dae690 --- /dev/null +++ b/plugins/iterm2/update @@ -0,0 +1,4 @@ +#!/bin/sh + +curl -s -L https://iterm2.com/shell_integration/zsh \ + -o iterm2_shell_integration.zsh diff --git a/plugins/jira/README.md b/plugins/jira/README.md index a5633af77..d78ea15a4 100644 --- a/plugins/jira/README.md +++ b/plugins/jira/README.md @@ -14,22 +14,31 @@ In this document, "JIRA" refers to the JIRA issue tracking server, and `jira` re This plugin supplies one command, `jira`, through which all its features are exposed. Most forms of this command open a JIRA page in your web browser. -``` -jira # performs the default action +## Commands + +| Command | Description | +| :------------ | :-------------------------------------------------------- | +| `jira` | Performs the default action | +| `jira new` | Opens a new Jira issue dialogue | +| `jira ABC-123` | Opens an existing issue | +| `jira ABC-123 m` | Opens an existing issue for adding a comment | +| `jira dashboard [rapid_view]` | # opens your JIRA dashboard | +| `jira mine` | Queries for your own issues | +| `jira tempo` | Opens your JIRA Tempo | +| `jira reported [username]` | Queries for issues reported by a user | +| `jira assigned [username]` | Queries for issues assigned to a user | +| `jira branch` | Opens an existing issue matching the current branch name | + + +### Jira Branch usage notes + +The branch name may have prefixes ending in "/": "feature/MP-1234", and also suffixes +starting with "_": "MP-1234_fix_dashboard". In both these cases, the issue opened will be "MP-1234" + +This is also checks if the prefix is in the name, and adds it if not, so: "MP-1234" opens the issue "MP-1234", +"mp-1234" opens the issue "mp-1234", and "1234" opens the issue "MP-1234". + -jira new # opens a new issue -jira dashboard # opens your JIRA dashboard -jira tempo # opens your JIRA Tempo -jira reported [username] # queries for issues reported by a user -jira assigned [username] # queries for issues assigned to a user -jira myissues # queries for you own issues -jira branch # opens an existing issue matching the current branch name - # The branch name may have prefixes ending in "/": "feature/MP-1234", - # and also suffixes starting with "_": "MP-1234_fix_dashboard" - # In both these cases, the issue opened will be "MP-1234" -jira ABC-123 # opens an existing issue -jira ABC-123 m # opens an existing issue for adding a comment -``` #### Debugging usage #### @@ -62,7 +71,9 @@ echo "https://jira.atlassian.com" >> .jira-url * `$JIRA_NAME` - Your JIRA username; used as the default user for `assigned`/`reported` searches * `$JIRA_PREFIX` - Prefix added to issue ID arguments * `$JIRA_RAPID_BOARD` - Set to `true` if you use Rapid Board +* `$JIRA_RAPID_VIEW` - Set the default rapid view; it doesn't work if `$JIRA_RAPID_BOARD` is set to false * `$JIRA_DEFAULT_ACTION` - Action to do when `jira` is called with no arguments; defaults to "new" +* `$JIRA_TEMPO_PATH` - Your JIRA tempo url path; defaults to "/secure/Tempo.jspa" ### Browser ### diff --git a/plugins/jira/_jira b/plugins/jira/_jira index 1ac3eeda3..0e37b7e9d 100644 --- a/plugins/jira/_jira +++ b/plugins/jira/_jira @@ -4,6 +4,7 @@ local -a _1st_arguments _1st_arguments=( 'new:create a new issue' + 'mine:open my issues' 'dashboard:open the dashboard' 'tempo:open the tempo' 'reported:search for issues reported by a user' diff --git a/plugins/jira/jira.plugin.zsh b/plugins/jira/jira.plugin.zsh index 22807e0ae..e789fce92 100644 --- a/plugins/jira/jira.plugin.zsh +++ b/plugins/jira/jira.plugin.zsh @@ -44,25 +44,31 @@ function jira() { open_command "${jira_url}/secure/CreateIssue!default.jspa" elif [[ "$action" == "assigned" || "$action" == "reported" ]]; then _jira_query ${@:-$action} - elif [[ "$action" == "myissues" ]]; then + elif [[ "$action" == "mine" ]]; then echo "Opening my issues" open_command "${jira_url}/issues/?filter=-1" elif [[ "$action" == "dashboard" ]]; then echo "Opening dashboard" if [[ "$JIRA_RAPID_BOARD" == "true" ]]; then - open_command "${jira_url}/secure/RapidBoard.jspa" + _jira_rapid_board ${@} else open_command "${jira_url}/secure/Dashboard.jspa" fi elif [[ "$action" == "tempo" ]]; then echo "Opening tempo" - open_command "${jira_url}/secure/Tempo.jspa" + if [[ -n "$JIRA_TEMPO_PATH" ]]; then + open_command "${jira_url}${JIRA_TEMPO_PATH}" + else + open_command "${jira_url}/secure/Tempo.jspa" + fi elif [[ "$action" == "dumpconfig" ]]; then echo "JIRA_URL=$jira_url" echo "JIRA_PREFIX=$jira_prefix" echo "JIRA_NAME=$JIRA_NAME" + echo "JIRA_RAPID_VIEW=$JIRA_RAPID_VIEW" echo "JIRA_RAPID_BOARD=$JIRA_RAPID_BOARD" echo "JIRA_DEFAULT_ACTION=$JIRA_DEFAULT_ACTION" + echo "JIRA_TEMPO_PATH=$JIRA_TEMPO_PATH" else # Anything that doesn't match a special action is considered an issue name # but `branch` is a special case that will parse the current git branch @@ -75,7 +81,7 @@ function jira() { # Strip suffixes starting with _ issue_arg=(${(s:_:)issue_arg}) issue_arg=${issue_arg[1]} - if [[ "$issue_arg" = ${jira_prefix}* ]]; then + if [[ "${issue_arg:l}" = ${jira_prefix:l}* ]]; then issue="${issue_arg}" else issue="${jira_prefix}${issue_arg}" @@ -107,6 +113,16 @@ Valid options, in order of precedence: EOF } +function _jira_rapid_board() { + rapid_view=${2:=$JIRA_RAPID_VIEW} + + if [[ -z $rapid_view ]]; then + open_command "${jira_url}/secure/RapidBoard.jspa" + else + open_command "${jira_url}/secure/RapidBoard.jspa?rapidView=$rapid_view" + fi +} + function _jira_query() { emulate -L zsh local verb="$1" diff --git a/plugins/juju/README.md b/plugins/juju/README.md index f0c65309c..6ee333f50 100644 --- a/plugins/juju/README.md +++ b/plugins/juju/README.md @@ -126,5 +126,7 @@ Naming convention: - `jaddr [unit_num]`: display app or unit IP address. - `jreld `: display app and unit relation data. - `jclean`: destroy all controllers +- `jcontroller`: display the controller your are connected to. +- `jmodel`: display the model your are connected to. - `wjst [interval_secs] [args_for_watch]`: watch juju status, with optional interval (default: 5s); you may pass additional arguments to `watch`. diff --git a/plugins/juju/juju.plugin.zsh b/plugins/juju/juju.plugin.zsh index be8a2c7ae..0c60e35ce 100644 --- a/plugins/juju/juju.plugin.zsh +++ b/plugins/juju/juju.plugin.zsh @@ -163,10 +163,40 @@ jreld() { juju run "relation-get -r $relid - $2" --unit $2/$3 } +# Return Juju current controller +jcontroller() { + local controller="$(awk '/current-controller/ {print $2}' ~/.local/share/juju/controllers.yaml)" + if [[ -z "$controller" ]]; then + return 1 + fi + + echo $controller + return 0 +} + +# Return Juju current model +jmodel() { + local yqbin="$(whereis yq | awk '{print $2}')" + + if [[ -z "$yqbin" ]]; then + echo "--" + return 1 + fi + + local model="$(yq e ".controllers.$(jcontroller).current-model" < ~/.local/share/juju/models.yaml | cut -d/ -f2)" + + if [[ -z "$model" ]]; then + echo "--" + return 1 + fi + + echo $model + return 0 +} + # Watch juju status, with optional interval (default: 5 sec) wjst() { local interval="${1:-5}" shift $(( $# > 0 )) watch -n "$interval" --color juju status --relations --color "$@" } - diff --git a/plugins/kitchen/_kitchen b/plugins/kitchen/_kitchen index d93d93d78..64c01e395 100644 --- a/plugins/kitchen/_kitchen +++ b/plugins/kitchen/_kitchen @@ -1,6 +1,6 @@ #compdef kitchen # ------------------------------------------------------------------------------ -# Copyright (c) 2014 Github zsh-users - https://github.com/zsh-users +# Copyright (c) 2014 GitHub zsh-users - https://github.com/zsh-users # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/plugins/kube-ps1/README.md b/plugins/kube-ps1/README.md index b08997b0f..1ed3e4438 100644 --- a/plugins/kube-ps1/README.md +++ b/plugins/kube-ps1/README.md @@ -128,6 +128,7 @@ the following environment variables: | `KUBE_PS1_NS_ENABLE` | `true` | Display the namespace. If set to `false`, this will also disable `KUBE_PS1_DIVIDER` | | `KUBE_PS1_PREFIX` | `(` | Prompt opening character | | `KUBE_PS1_SYMBOL_ENABLE` | `true ` | Display the prompt Symbol. If set to `false`, this will also disable `KUBE_PS1_SEPARATOR` | +| `KUBE_PS1_SYMBOL_PADDING` | `false` | Adds a space (padding) after the symbol to prevent clobbering prompt characters | | `KUBE_PS1_SYMBOL_DEFAULT` | `⎈ ` | Default prompt symbol. Unicode `\u2388` | | `KUBE_PS1_SYMBOL_USE_IMG` | `false` | ☸️ , Unicode `\u2638` as the prompt symbol | | `KUBE_PS1_SEPARATOR` | | | Separator between symbol and context name | @@ -151,8 +152,10 @@ The default colors are set with the following environment variables: | Variable | Default | Meaning | | :------- | :-----: | ------- | +| `KUBE_PS1_PREFIX_COLOR` | `null` | Set default color of the prompt prefix | | `KUBE_PS1_SYMBOL_COLOR` | `blue` | Set default color of the Kubernetes symbol | | `KUBE_PS1_CTX_COLOR` | `red` | Set default color of the context | +| `KUBE_PS1_SUFFIX_COLOR` | `null` | Set default color of the prompt suffix | | `KUBE_PS1_NS_COLOR` | `cyan` | Set default color of the namespace | | `KUBE_PS1_BG_COLOR` | `null` | Set default color of the prompt background | diff --git a/plugins/kube-ps1/kube-ps1.plugin.zsh b/plugins/kube-ps1/kube-ps1.plugin.zsh index 9e77cbc19..894e0f7f0 100644 --- a/plugins/kube-ps1/kube-ps1.plugin.zsh +++ b/plugins/kube-ps1/kube-ps1.plugin.zsh @@ -1,9 +1,9 @@ -#!/bin/bash +#!/usr/bin/env bash # Kubernetes prompt helper for bash/zsh # Displays current context and namespace -# Copyright 2019 Jon Mosco +# Copyright 2021 Jon Mosco # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -24,7 +24,8 @@ # Override these values in ~/.zshrc or ~/.bashrc KUBE_PS1_BINARY="${KUBE_PS1_BINARY:-kubectl}" KUBE_PS1_SYMBOL_ENABLE="${KUBE_PS1_SYMBOL_ENABLE:-true}" -KUBE_PS1_SYMBOL_DEFAULT=${KUBE_PS1_SYMBOL_DEFAULT:-$'\u2388 '} +KUBE_PS1_SYMBOL_DEFAULT=${KUBE_PS1_SYMBOL_DEFAULT:-$'\u2388'} +KUBE_PS1_SYMBOL_PADDING="${KUBE_PS1_SYMBOL_PADDING:-false}" KUBE_PS1_SYMBOL_USE_IMG="${KUBE_PS1_SYMBOL_USE_IMG:-false}" KUBE_PS1_NS_ENABLE="${KUBE_PS1_NS_ENABLE:-true}" KUBE_PS1_CONTEXT_ENABLE="${KUBE_PS1_CONTEXT_ENABLE:-true}" @@ -32,10 +33,12 @@ KUBE_PS1_PREFIX="${KUBE_PS1_PREFIX-(}" KUBE_PS1_SEPARATOR="${KUBE_PS1_SEPARATOR-|}" KUBE_PS1_DIVIDER="${KUBE_PS1_DIVIDER-:}" KUBE_PS1_SUFFIX="${KUBE_PS1_SUFFIX-)}" + KUBE_PS1_SYMBOL_COLOR="${KUBE_PS1_SYMBOL_COLOR-blue}" KUBE_PS1_CTX_COLOR="${KUBE_PS1_CTX_COLOR-red}" KUBE_PS1_NS_COLOR="${KUBE_PS1_NS_COLOR-cyan}" KUBE_PS1_BG_COLOR="${KUBE_PS1_BG_COLOR}" + KUBE_PS1_KUBECONFIG_CACHE="${KUBECONFIG}" KUBE_PS1_DISABLE_PATH="${HOME}/.kube/kube-ps1/disabled" KUBE_PS1_LAST_TIME=0 @@ -149,18 +152,17 @@ _kube_ps1_symbol() { case "${KUBE_PS1_SHELL}" in bash) - if ((BASH_VERSINFO[0] >= 4)) && [[ $'\u2388 ' != "\\u2388 " ]]; then + if ((BASH_VERSINFO[0] >= 4)) && [[ $'\u2388' != "\\u2388" ]]; then KUBE_PS1_SYMBOL="${KUBE_PS1_SYMBOL_DEFAULT}" - # KUBE_PS1_SYMBOL=$'\u2388 ' - KUBE_PS1_SYMBOL_IMG=$'\u2638 ' + KUBE_PS1_SYMBOL_IMG=$'\u2638\ufe0f' else - KUBE_PS1_SYMBOL=$'\xE2\x8E\x88 ' - KUBE_PS1_SYMBOL_IMG=$'\xE2\x98\xB8 ' + KUBE_PS1_SYMBOL=$'\xE2\x8E\x88' + KUBE_PS1_SYMBOL_IMG=$'\xE2\x98\xB8' fi ;; zsh) KUBE_PS1_SYMBOL="${KUBE_PS1_SYMBOL_DEFAULT}" - KUBE_PS1_SYMBOL_IMG="\u2638 ";; + KUBE_PS1_SYMBOL_IMG="\u2638";; *) KUBE_PS1_SYMBOL="k8s" esac @@ -169,7 +171,12 @@ _kube_ps1_symbol() { KUBE_PS1_SYMBOL="${KUBE_PS1_SYMBOL_IMG}" fi - echo "${KUBE_PS1_SYMBOL}" + if [[ "${KUBE_PS1_SYMBOL_PADDING}" == true ]]; then + echo "${KUBE_PS1_SYMBOL} " + else + echo "${KUBE_PS1_SYMBOL}" + fi + } _kube_ps1_split() { @@ -339,7 +346,11 @@ kube_ps1() { [[ -n "${KUBE_PS1_BG_COLOR}" ]] && KUBE_PS1+="$(_kube_ps1_color_bg ${KUBE_PS1_BG_COLOR})" # Prefix - [[ -n "${KUBE_PS1_PREFIX}" ]] && KUBE_PS1+="${KUBE_PS1_PREFIX}" + if [[ -z "${KUBE_PS1_PREFIX_COLOR:-}" ]] && [[ -n "${KUBE_PS1_PREFIX}" ]]; then + KUBE_PS1+="${KUBE_PS1_PREFIX}" + else + KUBE_PS1+="$(_kube_ps1_color_fg $KUBE_PS1_PREFIX_COLOR)${KUBE_PS1_PREFIX}${KUBE_PS1_RESET_COLOR}" + fi # Symbol KUBE_PS1+="$(_kube_ps1_color_fg $KUBE_PS1_SYMBOL_COLOR)$(_kube_ps1_symbol)${KUBE_PS1_RESET_COLOR}" @@ -362,7 +373,11 @@ kube_ps1() { fi # Suffix - [[ -n "${KUBE_PS1_SUFFIX}" ]] && KUBE_PS1+="${KUBE_PS1_SUFFIX}" + if [[ -z "${KUBE_PS1_SUFFIX_COLOR:-}" ]] && [[ -n "${KUBE_PS1_SUFFIX}" ]]; then + KUBE_PS1+="${KUBE_PS1_SUFFIX}" + else + KUBE_PS1+="$(_kube_ps1_color_fg $KUBE_PS1_SUFFIX_COLOR)${KUBE_PS1_SUFFIX}${KUBE_PS1_RESET_COLOR}" + fi # Close Background color if defined [[ -n "${KUBE_PS1_BG_COLOR}" ]] && KUBE_PS1+="${_KUBE_PS1_OPEN_ESC}${_KUBE_PS1_DEFAULT_BG}${_KUBE_PS1_CLOSE_ESC}" diff --git a/plugins/kubectl/kubectl.plugin.zsh b/plugins/kubectl/kubectl.plugin.zsh index 095d2b328..315d3ce93 100644 --- a/plugins/kubectl/kubectl.plugin.zsh +++ b/plugins/kubectl/kubectl.plugin.zsh @@ -1,15 +1,17 @@ -if (( $+commands[kubectl] )); then - # If the completion file does not exist, generate it and then source it - # Otherwise, source it and regenerate in the background - if [[ ! -f "$ZSH_CACHE_DIR/completions/_kubectl" ]]; then - kubectl completion zsh | tee "$ZSH_CACHE_DIR/completions/_kubectl" >/dev/null - source "$ZSH_CACHE_DIR/completions/_kubectl" - else - source "$ZSH_CACHE_DIR/completions/_kubectl" - kubectl completion zsh | tee "$ZSH_CACHE_DIR/completions/_kubectl" >/dev/null &| - fi +if (( ! $+commands[kubectl] )); then + return fi +# If the completion file doesn't exist yet, we need to autoload it and +# bind it to `kubectl`. Otherwise, compinit will have already done that. +if [[ ! -f "$ZSH_CACHE_DIR/completions/_kubectl" ]]; then + typeset -g -A _comps + autoload -Uz _kubectl + _comps[kubectl]=_kubectl +fi + +kubectl completion zsh 2> /dev/null >| "$ZSH_CACHE_DIR/completions/_kubectl" &| + # This command is used a LOT both below and in daily life alias k=kubectl diff --git a/plugins/lando/README.md b/plugins/lando/README.md index 928a42bca..6daeae4e4 100644 --- a/plugins/lando/README.md +++ b/plugins/lando/README.md @@ -17,6 +17,7 @@ plugins=(... lando) | `drush` | `lando drush` | | `gulp` | `lando gulp` | | `npm` | `lando npm` | +| `php` | `lando php` | | `wp` | `lando wp` | | `yarn` | `lando yarn` | diff --git a/plugins/last-working-dir/last-working-dir.plugin.zsh b/plugins/last-working-dir/last-working-dir.plugin.zsh index 905a02a70..684972cc1 100644 --- a/plugins/last-working-dir/last-working-dir.plugin.zsh +++ b/plugins/last-working-dir/last-working-dir.plugin.zsh @@ -9,7 +9,7 @@ chpwd_last_working_dir() { [[ "$ZSH_SUBSHELL" -eq 0 ]] || return 0 # Add ".$SSH_USER" suffix to cache file if $SSH_USER is set and non-empty local cache_file="$ZSH_CACHE_DIR/last-working-dir${SSH_USER:+.$SSH_USER}" - pwd >| "$cache_file" + builtin pwd >| "$cache_file" } # Changes directory to the last working directory diff --git a/plugins/lol/README.md b/plugins/lol/README.md index ea6b0c3b8..b45513b35 100644 --- a/plugins/lol/README.md +++ b/plugins/lol/README.md @@ -49,7 +49,7 @@ plugins=(... lol) | `violenz` | `git rebase` | | `visible` | `echo` | | `wtf` | `dmesg` | -| `yolo` | `git commit -m "$(curl -s http://whatthecommit.com/index.txt)"` | +| `yolo` | `git commit -m "$(curl -s https://whatthecommit.com/index.txt)"` | ## Usage Examples @@ -66,6 +66,6 @@ nowai u=r,go= some.file # ssh root@catserver.org pwned root@catserver.org -# git commit -m "$(curl -s http://whatthecommit.com/index.txt)" +# git commit -m "$(curl -s https://whatthecommit.com/index.txt)" yolo ``` diff --git a/plugins/lol/lol.plugin.zsh b/plugins/lol/lol.plugin.zsh index 3c30259a1..585f96e4f 100644 --- a/plugins/lol/lol.plugin.zsh +++ b/plugins/lol/lol.plugin.zsh @@ -45,7 +45,7 @@ alias bringz='git pull' alias chicken='git add' alias oanward='git commit -m' alias ooanward='git commit -am' -alias yolo='git commit -m "$(curl -s http://whatthecommit.com/index.txt)"' +alias yolo='git commit -m "$(curl -s https://whatthecommit.com/index.txt)"' alias letcat='git checkout' alias violenz='git rebase' diff --git a/plugins/lpass/_lpass b/plugins/lpass/_lpass index e6193a22d..621a7bcd7 100644 --- a/plugins/lpass/_lpass +++ b/plugins/lpass/_lpass @@ -106,7 +106,7 @@ _lpass() { generic_options+=('--color=[Color: auto | never | always]') fi if [ "$has_interactive" -eq 1 ]; then - generic_options+=("--non-interactive[Use stardard input instead of $EDITOR]") + generic_options+=("--non-interactive[Use standard input instead of $EDITOR]") fi _arguments $generic_options fi diff --git a/plugins/macos/README.md b/plugins/macos/README.md index 1bc4244a4..1cb9b395d 100644 --- a/plugins/macos/README.md +++ b/plugins/macos/README.md @@ -25,7 +25,7 @@ Original author: [Sorin Ionescu](https://github.com/sorin-ionescu) | `pxd` | Return the current Xcode project directory | | `cdx` | `cd` to the current Xcode project directory | | `quick-look` | Quick-Look a specified file | -| `man-preview` | Open a specified man page in Preview app | +| `man-preview` | Open man pages in Preview app | | `showfiles` | Show hidden files in Finder | | `hidefiles` | Hide the hidden files in Finder | | `itunes` | _DEPRECATED_. Use `music` from macOS Catalina on | diff --git a/plugins/macos/macos.plugin.zsh b/plugins/macos/macos.plugin.zsh index b540eecb5..e27d412c8 100644 --- a/plugins/macos/macos.plugin.zsh +++ b/plugins/macos/macos.plugin.zsh @@ -224,8 +224,10 @@ function quick-look() { } function man-preview() { - # Don't let Preview.app steal focus if the man page doesn't exist - man -w "$@" &>/dev/null && man -t "$@" | open -f -a Preview || man "$@" + local page + for page in "${(@f)"$(man -w $@)"}"; do + command mandoc -Tpdf $page | open -f -a Preview + done } compdef _man man-preview diff --git a/plugins/macos/spotify b/plugins/macos/spotify index 491a60686..5fb40517c 100644 --- a/plugins/macos/spotify +++ b/plugins/macos/spotify @@ -43,7 +43,7 @@ showAPIHelp() { echo " find music by name. It is very likely you want this feature!"; echo; echo " To get this to work, you need to sign up (or in) and create an 'Application' at:"; - echo " https://developer.spotify.com/my-applications/#!/applications/create"; + echo " https://developer.spotify.com/dashboard/create"; echo; echo " Once you've created an application, find the 'Client ID' and 'Client Secret'"; echo " values, and enter them into your shpotify config file at '${USER_CONFIG_FILE}'"; diff --git a/plugins/marked2/marked2.plugin.zsh b/plugins/marked2/marked2.plugin.zsh index 56863ade5..45f4b65c1 100644 --- a/plugins/marked2/marked2.plugin.zsh +++ b/plugins/marked2/marked2.plugin.zsh @@ -3,10 +3,5 @@ # If marked is passed a file, open it in Marked # function marked() { - if [ "$1" ] - then - open -a "marked 2.app" "$1" - else - open -a "marked 2.app" - fi + open -a "marked 2.app" "$1" } diff --git a/plugins/marktext/README.md b/plugins/marktext/README.md new file mode 100644 index 000000000..71d287451 --- /dev/null +++ b/plugins/marktext/README.md @@ -0,0 +1,17 @@ +## marktext + +Plugin for MarkText, a previewer for Markdown files on Mac OS X + +### Requirements + + * [MarkText](https://github.com/marktext/marktext) + +### Usage + + * If `marktext` is called without an argument, open MarkText + + * If `marktext` is passed a file, open it in MarkText + +### Credits + + * just copied from plugins/marked2, all credits to marked2 plugin author diff --git a/plugins/marktext/marktext.plugin.zsh b/plugins/marktext/marktext.plugin.zsh new file mode 100644 index 000000000..1da85bcca --- /dev/null +++ b/plugins/marktext/marktext.plugin.zsh @@ -0,0 +1,7 @@ +# +# If marktext is called without an argument, open MarkText +# If marktext is passed a file, open it in MarkText +# +function marktext() { + open -a "MarkText.app" "$1" +} diff --git a/plugins/mongo-atlas/README.md b/plugins/mongo-atlas/README.md new file mode 100644 index 000000000..ef1b5e0d2 --- /dev/null +++ b/plugins/mongo-atlas/README.md @@ -0,0 +1,10 @@ +# MongoDB Atlas plugin + +This plugin adds completion for [Atlas](https://www.mongodb.com/docs/atlas/cli/stable/) a command line interface built specifically for +MongoDB Atlas. + +To use it, add `mongo-atlas` to the plugins array in your zshrc file: + +```zsh +plugins=(... mongo-atlas) +``` diff --git a/plugins/mongo-atlas/mongo-atlas.plugin.zsh b/plugins/mongo-atlas/mongo-atlas.plugin.zsh new file mode 100644 index 000000000..6762c909e --- /dev/null +++ b/plugins/mongo-atlas/mongo-atlas.plugin.zsh @@ -0,0 +1,14 @@ +# Autocompletion for the Mongo Atlas CLI (atlas). +if (( ! $+commands[atlas] )); then + return +fi + +# If the completion file doesn't exist yet, we need to autoload it and +# bind it to `atlas`. Otherwise, compinit will have already done that. +if [[ ! -f "$ZSH_CACHE_DIR/completions/_atlas" ]]; then + typeset -g -A _comps + autoload -Uz _atlas + _comps[atlas]=_atlas +fi + +atlas completion zsh >| "$ZSH_CACHE_DIR/completions/atlas" &| diff --git a/plugins/mvn/mvn.plugin.zsh b/plugins/mvn/mvn.plugin.zsh index 1b9141f21..da51f74df 100644 --- a/plugins/mvn/mvn.plugin.zsh +++ b/plugins/mvn/mvn.plugin.zsh @@ -196,7 +196,7 @@ function listMavenCompletions { # spring-boot spring-boot:run spring-boot:repackage # quarkus - quarkus:dev quarkus:list-extensions quarkus:add-extension quarkus:add-extensions quarkus:generate-config quarkus:help + quarkus:dev quarkus:list-extensions quarkus:add-extension quarkus:add-extensions quarkus:remove-extension quarkus:remove-extensions quarkus:generate-config quarkus:help # exec exec:exec exec:java # versions @@ -283,9 +283,11 @@ function listMavenCompletions { toolchain:toolchain #liberty liberty:clean-server liberty:compile-jsp liberty:configure-arquillian liberty:create-server liberty:debug liberty:debug-server liberty:deploy liberty:dev liberty:display-url liberty:dump-server liberty:install-apps liberty:install-feature liberty:install-server liberty:java-dump-server liberty:package-server liberty:run liberty:run-server liberty:server-status liberty:start liberty:start-server liberty:status liberty:stop liberty:stop-server liberty:test-start-server liberty:test-stop-server liberty:undeploy liberty:uninstall-feature + # vaadin + vaadin:prepare-frontend vaadin:build-frontend vaadin:clean-frontend vaadin:dance # options - "-Dmaven.test.skip=true" -DskipTests -DskipITs -Dmaven.surefire.debug -DenableCiProfile "-Dpmd.skip=true" "-Dcheckstyle.skip=true" "-Dtycho.mode=maven" "-Dmaven.test.failure.ignore=true" "-DgroupId=" "-DartifactId=" "-Dversion=" "-Dpackaging=jar" "-Dfile=" + "-Dmaven.test.skip=true" -DskipTests -DskipITs -Dmaven.surefire.debug -DenableCiProfile "-Dpmd.skip=true" "-Dcheckstyle.skip=true" "-Dtycho.mode=maven" "-Dmaven.test.failure.ignore=true" "-DgroupId=" "-DartifactId=" "-Dversion=" "-Dpackaging=jar" "-Dfile=" "-Dextensions=" # arguments -am --also-make diff --git a/plugins/nats/README.md b/plugins/nats/README.md new file mode 100644 index 000000000..0ea26fca1 --- /dev/null +++ b/plugins/nats/README.md @@ -0,0 +1,14 @@ +# NATS plugin + +This plugin adds completion for several tools from [NATS](https://nats.io/). + +- [`nsc`](https://github.com/nats-io/nsc) +- [`natscli`](https://github.com/nats-io/natscli) + +To use it, add `nats` to the plugins array in your zshrc file: + +```zsh +plugins=(... nats) +``` + +This plugin does not add any aliases. diff --git a/plugins/nats/nats.plugin.zsh b/plugins/nats/nats.plugin.zsh new file mode 100644 index 000000000..8b95b07c6 --- /dev/null +++ b/plugins/nats/nats.plugin.zsh @@ -0,0 +1,23 @@ +if (( $+commands[nsc] )); then + # If the completion file doesn't exist yet, we need to autoload it and + # bind it to `nsc`. Otherwise, compinit will have already done that. + if [[ ! -f "$ZSH_CACHE_DIR/completions/_nsc" ]]; then + typeset -g -A _comps + autoload -Uz _nsc + _comps[nsc]=_nsc + fi + + nsc completion zsh >| "$ZSH_CACHE_DIR/completions/_nsc" &| +fi + +if (( $+commands[nats] )); then + # If the completion file doesn't exist yet, we need to autoload it and + # bind it to `nats`. Otherwise, compinit will have already done that. + if [[ ! -f "$ZSH_CACHE_DIR/completions/_nats" ]]; then + typeset -g -A _comps + autoload -Uz _nats + _comps[nats]=_nats + fi + + nats --completion-script-zsh >| "$ZSH_CACHE_DIR/completions/_nats" &| +fi diff --git a/plugins/ng/_ng b/plugins/ng/_ng index 9c96cf7e3..86c6ce187 100644 --- a/plugins/ng/_ng +++ b/plugins/ng/_ng @@ -46,7 +46,7 @@ elif (( CURRENT == 3 )); then # ... # } # } - # In abscence of a proper JSON parser, just grab the lines with + # In absence of a proper JSON parser, just grab the lines with # a 2-space indentation and only the stuff inside quotes local -a projects projects=(${(@f)"$(ng config projects 2>/dev/null | sed -n 's/^ "\([^"]\+\)".*$/\1/p')"}) diff --git a/plugins/nodenv/README.md b/plugins/nodenv/README.md new file mode 100644 index 000000000..550597025 --- /dev/null +++ b/plugins/nodenv/README.md @@ -0,0 +1,20 @@ +# nodenv plugin + +The primary job of this plugin is to provide `nodenv_prompt_info` which can be added to your theme to include Node +version information into your prompt. + +To use it, add `nodenv` to the plugins array in your zshrc file: + +```zsh +plugins=(... nodenv) +``` + +## Functions + +* `nodenv_prompt_info`: displays the Node version in use by nodenv; or the global Node + version, if nodenv wasn't found. You can use this function in your prompt by adding + `$(nodenv_prompt_info)` to PROMPT or RPROMPT: + + ```zsh + RPROMPT='$(nodenv_prompt_info)' + ``` diff --git a/plugins/nodenv/nodenv.plugin.zsh b/plugins/nodenv/nodenv.plugin.zsh new file mode 100644 index 000000000..79a4ffbb5 --- /dev/null +++ b/plugins/nodenv/nodenv.plugin.zsh @@ -0,0 +1,43 @@ +# This plugin loads nodenv into the current shell and provides prompt info via +# the 'nodenv_prompt_info' function. + +FOUND_NODENV=${+commands[nodenv]} + +if [[ $FOUND_NODENV -ne 1 ]]; then + nodenvdirs=( + "$HOME/.nodenv" + "/usr/local/nodenv" + "/opt/nodenv" + "/usr/local/opt/nodenv" + ) + for dir in $nodenvdirs; do + if [[ -d "${dir}/bin" ]]; then + export PATH="$PATH:${dir}/bin" + FOUND_NODENV=1 + break + fi + done + + if [[ $FOUND_NODENV -ne 1 ]]; then + if (( $+commands[brew] )) && dir=$(brew --prefix nodenv 2>/dev/null); then + if [[ -d "${dir}/bin" ]]; then + export PATH="$PATH:${dir}/bin" + FOUND_NODENV=1 + fi + fi + fi +fi + +if [[ $FOUND_NODENV -eq 1 ]]; then + eval "$(nodenv init --no-rehash - zsh)" + function nodenv_prompt_info() { + nodenv version-name 2>/dev/null + } +else + # fallback to system node + function nodenv_prompt_info() { + echo "system: $(node -v 2>&1 | cut -c 2-)" + } +fi + +unset FOUND_NODENV nodenvdirs dir diff --git a/plugins/npm/npm.plugin.zsh b/plugins/npm/npm.plugin.zsh index 6c768d614..e0dcbf142 100644 --- a/plugins/npm/npm.plugin.zsh +++ b/plugins/npm/npm.plugin.zsh @@ -1,5 +1,5 @@ (( $+commands[npm] )) && { - rm -f "${ZSH_CACHE_DIR:-$ZSH/cache}/npm_completion" + command rm -f "${ZSH_CACHE_DIR:-$ZSH/cache}/npm_completion" _npm_completion() { local si=$IFS diff --git a/plugins/npx/README.md b/plugins/npx/README.md deleted file mode 100644 index 4b2aba8f0..000000000 --- a/plugins/npx/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# npx plugin - -## Deprecation - -Since npm v7, `npx` has been moved to `npm exec`. With the move, [the `--shell-auto-fallback` argument -for `npx` has been removed](https://github.com/npm/cli/blob/v7.0.0/docs/content/cli-commands/npm-exec.md#compatibility-with-older-npx-versions): - -> Shell fallback functionality is removed, as it is not advisable. - -When using npm v7, you'll get this error: - -> npx: the --shell-auto-fallback argument has been removed - -If you get this error, just disable the plugin by removing it from the plugins array in your zshrc file. -This plugin will no longer be maintained and will be removed in the future, when the older `npx` versions -are no longer available. diff --git a/plugins/npx/npx.plugin.zsh b/plugins/npx/npx.plugin.zsh deleted file mode 100644 index c1e2eca98..000000000 --- a/plugins/npx/npx.plugin.zsh +++ /dev/null @@ -1,12 +0,0 @@ -if (( ! $+commands[npx] )); then - return -fi - -if ! npx_fallback_script="$(npx --shell-auto-fallback zsh 2>/dev/null)"; then - print -u2 ${(%):-"%F{yellow}This \`npx\` version ($(npx --version)) is not supported.%f"} -else - source <(<<< "$npx_fallback_script") -fi - -print -u2 ${(%):-"%F{yellow}The \`npx\` plugin is deprecated and will be removed soon. %BPlease disable it%b.%f"} -unset npx_fallback_script diff --git a/plugins/nvm/README.md b/plugins/nvm/README.md index a8bc34ae7..d3fd980be 100644 --- a/plugins/nvm/README.md +++ b/plugins/nvm/README.md @@ -1,7 +1,7 @@ # nvm plugin -This plugin adds autocompletions for [nvm](https://github.com/nvm-sh/nvm) — a Node.js version manager. -It also automatically sources nvm, so you don't need to do it manually in your `.zshrc`. +This plugin adds autocompletions for [nvm](https://github.com/nvm-sh/nvm) — a Node.js version manager. It also +automatically sources nvm, so you don't need to do it manually in your `.zshrc`. To use it, add `nvm` to the plugins array of your zshrc file: @@ -21,14 +21,40 @@ These settings should go in your zshrc file, before Oh My Zsh is sourced: [Homebrew is installed in `/opt/homebrew`](https://docs.brew.sh/Installation). To get the directory where nvm has been installed, regardless of chip architecture, use `NVM_HOMEBREW=$(brew --prefix nvm)`. -- **`NVM_LAZY`**: if you want the plugin to defer the load of nvm to speed-up the start of your zsh session, - set `NVM_LAZY` to `1`. This will use the `--no-use` parameter when loading nvm, and will create a function - for `node`, `npm`, `yarn`, and the command(s) specified by `NVM_LAZY_CMD`, so when you call either of them, - nvm will load with `nvm use default`. +## Customization -- **`NVM_LAZY_CMD`**: if you want additional command(s) to trigger lazy loading of nvm, set `NVM_LAZY_CMD` to - the command or an array of the commands. +#### Lazy startup -- **`NVM_AUTOLOAD`**: if `NVM_AUTOLOAD` is set to `1`, the plugin will automatically load a node version when - if finds a [`.nvmrc` file](https://github.com/nvm-sh/nvm#nvmrc) in the current working directory indicating - which node version to load. +This option will help you to defer nvm's load until you use it to speed-up your zsh startup. This will source +nvm script only when using it, and will create a function for `node`, `npm`, `pnpm`, `yarn`, and the +command(s) specified by `lazy-cmd` option, so when you call either of them, nvm will be loaded and run with +default version. To enable it, you can add this snippet to your zshrc, before Oh My Zsh is sourced: + +```zsh +zstyle ':omz:plugins:nvm' lazy yes +``` + +Then, to define extra commands that will also trigger nvm load, you can use a similar syntax, adding as many +as you want: + +```zsh +zstyle ':omz:plugins:nvm' lazy-cmd eslint prettier typescript ... +``` + +#### `.nvmrc` autoload + +If set, the plugin will automatically load a node version when if finds a +[`.nvmrc` file](https://github.com/nvm-sh/nvm#nvmrc) in the current working directory indicating which node +version to load. This can be done, similar as previous options, adding: + +```zsh +zstyle ':omz:plugins:nvm' autoload yes +``` + +To remove the output generated by NVM when autoloading, you can set the following option: + +```zsh +zstyle ':omz:plugins:nvm' silent-autoload yes +``` + +Note: _this will not remove regular `nvm` output_ diff --git a/plugins/nvm/nvm.plugin.zsh b/plugins/nvm/nvm.plugin.zsh index 630854a71..20697d67d 100644 --- a/plugins/nvm/nvm.plugin.zsh +++ b/plugins/nvm/nvm.plugin.zsh @@ -4,57 +4,83 @@ if [[ -z "$NVM_DIR" ]]; then export NVM_DIR="$HOME/.nvm" elif [[ -d "${XDG_CONFIG_HOME:-$HOME/.config}/nvm" ]]; then export NVM_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/nvm" + elif (( $+commands[brew] )); then + NVM_HOMEBREW="${NVM_HOMEBREW:-${HOMEBREW_PREFIX:-$(brew --prefix)}/opt/nvm}" + if [[ -d "$NVM_HOMEBREW" ]]; then + export NVM_DIR="$NVM_HOMEBREW" + fi fi fi # Don't try to load nvm if command already available # Note: nvm is a function so we need to use `which` -! which nvm &>/dev/null || return +which nvm &>/dev/null && return -if [[ -f "$NVM_DIR/nvm.sh" ]]; then - # Load nvm if it exists in $NVM_DIR - source "$NVM_DIR/nvm.sh" ${NVM_LAZY+"--no-use"} -elif (( $+commands[brew] )); then - # Otherwise try to load nvm installed via Homebrew - # User can set this if they have an unusual Homebrew setup - NVM_HOMEBREW="${NVM_HOMEBREW:-${HOMEBREW_PREFIX:-$(brew --prefix)}/opt/nvm}" - # Load nvm from Homebrew location if it exists - if [[ -f "$NVM_HOMEBREW/nvm.sh" ]]; then - source "$NVM_HOMEBREW/nvm.sh" ${NVM_LAZY+"--no-use"} - else - return +# TODO: 2022-11-11: Remove soft-deprecate options +if (( ${+NVM_LAZY} + ${+NVM_LAZY_CMD} + ${+NVM_AUTOLOAD} )); then + # Get list of NVM_* variable settings defined + local -a used_vars + used_vars=(${(o)parameters[(I)NVM_(AUTOLOAD|LAZY|LAZY_CMD)]}) + # Nicely print the list in the style `var1, var2 and var3` + echo "${fg[yellow]}[nvm plugin] Variable-style settings are deprecated. Instead of ${(j:, :)used_vars[1,-2]}${used_vars[-2]+ and }${used_vars[-1]}, use:\n" + if (( $+NVM_AUTOLOAD )); then + echo " zstyle ':omz:plugins:nvm' autoload yes" + zstyle ':omz:plugins:nvm' autoload yes fi + if (( $+NVM_LAZY )); then + echo " zstyle ':omz:plugins:nvm' lazy yes" + zstyle ':omz:plugins:nvm' lazy yes + fi + if (( $+NVM_LAZY_CMD )); then + echo " zstyle ':omz:plugins:nvm' lazy-cmd $NVM_LAZY_CMD" + zstyle ':omz:plugins:nvm' lazy-cmd $NVM_LAZY_CMD + fi + echo "$reset_color" + unset used_vars NVM_AUTOLOAD NVM_LAZY NVM_LAZY_CMD +fi + +if zstyle -t ':omz:plugins:nvm' lazy; then + # Call nvm when first using nvm, node, npm, pnpm, yarn or other commands in lazy-cmd + zstyle -a ':omz:plugins:nvm' lazy-cmd nvm_lazy_cmd + eval " + function nvm node npm pnpm yarn $nvm_lazy_cmd { + unfunction nvm node npm pnpm yarn $nvm_lazy_cmd + # Load nvm if it exists in \$NVM_DIR + [[ -f \"\$NVM_DIR/nvm.sh\" ]] && source \"\$NVM_DIR/nvm.sh\" + \"\$0\" \"\$@\" + } + " + unset nvm_lazy_cmd +elif [[ -f "$NVM_DIR/nvm.sh" ]]; then + # Load nvm if it exists in $NVM_DIR + source "$NVM_DIR/nvm.sh" else return fi -# Call nvm when first using node, npm or yarn -if (( $+NVM_LAZY )); then - function node npm yarn $NVM_LAZY_CMD { - unfunction node npm yarn $NVM_LAZY_CMD - nvm use default - command "$0" "$@" - } -fi - # Autoload nvm when finding a .nvmrc file in the current directory # Adapted from: https://github.com/nvm-sh/nvm#zsh -if (( $+NVM_AUTOLOAD )); then - load-nvmrc() { +if zstyle -t ':omz:plugins:nvm' autoload; then + function load-nvmrc { local node_version="$(nvm version)" local nvmrc_path="$(nvm_find_nvmrc)" + local nvm_silent="" + zstyle -t ':omz:plugins:nvm' silent-autoload && nvm_silent="--silent" if [[ -n "$nvmrc_path" ]]; then - local nvmrc_node_version=$(nvm version "$(cat "${nvmrc_path}")") + local nvmrc_node_version=$(nvm version $(cat "$nvmrc_path" | tr -dc '[:print:]')) if [[ "$nvmrc_node_version" = "N/A" ]]; then nvm install elif [[ "$nvmrc_node_version" != "$node_version" ]]; then - nvm use + nvm use $nvm_silent fi elif [[ "$node_version" != "$(nvm version default)" ]]; then - echo "Reverting to nvm default version" - nvm use default + if [[ -z $nvm_silent ]]; then + echo "Reverting to nvm default version" + fi + + nvm use default $nvm_silent fi } @@ -76,4 +102,4 @@ for nvm_completion in "$NVM_DIR/bash_completion" "$NVM_HOMEBREW/etc/bash_complet fi done -unset NVM_HOMEBREW NVM_LAZY NVM_AUTOLOAD nvm_completion +unset NVM_HOMEBREW nvm_completion diff --git a/plugins/oc/oc.plugin.zsh b/plugins/oc/oc.plugin.zsh index b968c4bd4..f0e2fc3bc 100644 --- a/plugins/oc/oc.plugin.zsh +++ b/plugins/oc/oc.plugin.zsh @@ -4,4 +4,5 @@ if [ $commands[oc] ]; then source <(oc completion zsh) + compdef _oc oc fi diff --git a/plugins/osx/README.md b/plugins/osx/README.md deleted file mode 100644 index 98d859545..000000000 --- a/plugins/osx/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# osx plugin - -**Deprecated: use the [`macos`](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/macos) plugin instead.** diff --git a/plugins/osx/osx.plugin.zsh b/plugins/osx/osx.plugin.zsh deleted file mode 100644 index 3b0935981..000000000 --- a/plugins/osx/osx.plugin.zsh +++ /dev/null @@ -1,5 +0,0 @@ -print -u2 ${(%):-'%F{yellow}The `osx` plugin is deprecated and has been renamed to `macos`.'} -print -u2 ${(%):-'Please update your .zshrc to use the `%Bmacos%b` plugin instead.%f'} - -(( ${fpath[(Ie)$ZSH/plugins/macos]} )) || fpath=("$ZSH/plugins/macos" $fpath) -source "$ZSH/plugins/macos/macos.plugin.zsh" diff --git a/plugins/perms/README.md b/plugins/perms/README.md index ae7a36b9d..ae10fa659 100644 --- a/plugins/perms/README.md +++ b/plugins/perms/README.md @@ -10,6 +10,16 @@ plugins=(... perms) ## Usage -* `set755` recursively sets all given directories (default to .) to octal 755. -* `set644` recursively sets all given files (default to .) to octal 644. -* `fixperms` is a wrapper around `set755` and `set644` applied to a specified directory or the current directory otherwise. It also prompts prior to execution unlike the other two aliases. +> **CAUTION:** these functions are harmful if you don't know what they do. + +- `set755`: sets the permission to octal 755 for all given directories and their child directories (by default, starting from the current directory). + +- `set644`: sets the permission to octal 644 for all files of the given directory (by default, the current directory), recursively. It will only affect regular files (no symlinks). + +- `resetperms` is a wrapper around `set755` and `set644` applied to a specified directory or the current directory otherwise. + It will set the permissions to 755 for directories, and 644 for files. + +## Reference + +- octal 644: _read and write_ for the owner, _read_ for the group and others users. +- octal 755: _read, write and execute_ permissions for the owner, and _read and execute_ for the group and others users. diff --git a/plugins/perms/perms.plugin.zsh b/plugins/perms/perms.plugin.zsh index 1a7472c1c..353b58411 100644 --- a/plugins/perms/perms.plugin.zsh +++ b/plugins/perms/perms.plugin.zsh @@ -6,25 +6,25 @@ ### Aliases # Set all files' permissions to 644 recursively in a directory -set644() { +function set644 { find "${@:-.}" -type f ! -perm 644 -print0 | xargs -0 chmod 644 } # Set all directories' permissions to 755 recursively in a directory -set755() { +function set755 { find "${@:-.}" -type d ! -perm 755 -print0 | xargs -0 chmod 755 } ### Functions -# fixperms - fix permissions on files and directories, with confirmation +# resetperms - fix permissions on files and directories, with confirmation # Returns 0 on success, nonzero if any errors occurred -fixperms () { +function resetperms { local opts confirm target exit_status chmod_opts use_slow_mode zparseopts -E -D -a opts -help -slow v+=chmod_opts if [[ $# > 1 || -n "${opts[(r)--help]}" ]]; then cat </dev/null | grep -q GNU || xargs="xargs" - pip list --outdated --format freeze | cut -d= -f1 | ${=xargs} pip install --upgrade + pip list --outdated | awk 'NR > 2 { print $1 }' | ${=xargs} pip install --upgrade } -# Uninstalled all installed packages +# Uninstall all installed packages function pipunall { # non-GNU xargs does not support nor need `--no-run-if-empty` local xargs="xargs --no-run-if-empty" xargs --version 2>/dev/null | grep -q GNU || xargs="xargs" pip list --format freeze | cut -d= -f1 | ${=xargs} pip uninstall } + +# Install from GitHub repository +function pipig { + pip install "git+https://github.com/$1.git" +} +compdef _pip pipig + +# Install from GitHub branch +function pipigb { + pip install "git+https://github.com/$1.git@$2" +} +compdef _pip pipigb + +# Install from GitHub pull request +function pipigp { + pip install "git+https://github.com/$1.git@refs/pull/$2/head" +} +compdef _pip pipigp diff --git a/plugins/pipenv/pipenv.plugin.zsh b/plugins/pipenv/pipenv.plugin.zsh index 4be61a920..244bd6b7c 100644 --- a/plugins/pipenv/pipenv.plugin.zsh +++ b/plugins/pipenv/pipenv.plugin.zsh @@ -1,8 +1,16 @@ -# Pipenv completion -_pipenv() { - eval $(env COMMANDLINE="${words[1,$CURRENT]}" _PIPENV_COMPLETE=complete-zsh pipenv) -} -compdef _pipenv pipenv +if (( ! $+commands[pipenv] )); then + return +fi + +# If the completion file doesn't exist yet, we need to autoload it and +# bind it to `pipenv`. Otherwise, compinit will have already done that. +if [[ ! -f "$ZSH_CACHE_DIR/completions/_pipenv" ]]; then + typeset -g -A _comps + autoload -Uz _pipenv + _comps[pipenv]=_pipenv +fi + +_PIPENV_COMPLETE=zsh_source pipenv >| "$ZSH_CACHE_DIR/completions/_pipenv" &| # Automatic pipenv shell activation/deactivation _togglePipenvShell() { diff --git a/plugins/pm2/_pm2 b/plugins/pm2/_pm2 index 86412aef1..faa6a3404 100644 --- a/plugins/pm2/_pm2 +++ b/plugins/pm2/_pm2 @@ -118,7 +118,7 @@ start_options=( ) logs_options=( '--json[json log output]' - '--format[formated log output]' + '--format[formatted log output]' '--raw[raw output]' '--err[only shows error output]' '--out[only shows standard output]' diff --git a/plugins/pod/_pod b/plugins/pod/_pod index 80d23daad..d560129db 100644 --- a/plugins/pod/_pod +++ b/plugins/pod/_pod @@ -6,7 +6,7 @@ # ----------------------------------------------------------------------------- # FILE: _pod -# DESCRIPTION: Cocoapods (0.33.1) autocomplete plugin for Oh-My-Zsh +# DESCRIPTION: CocoaPods (0.33.1) autocomplete plugin for Oh-My-Zsh # https://cocoapods.org # Generated with `pod --completion-script # AUTHOR: Alexandre Joly (alexandre.joly@mekanics.ch) diff --git a/plugins/pre-commit/README.md b/plugins/pre-commit/README.md new file mode 100644 index 000000000..e6d80d369 --- /dev/null +++ b/plugins/pre-commit/README.md @@ -0,0 +1,19 @@ +# Pre-commit plugin + +This plugin adds aliases for common commands of [pre-commit](https://pre-commit.com/). + +To use this plugin, add it to the plugins array in your zshrc file: + +```zsh +plugins=(... pre-commit) +``` + +## Aliases + +| Alias | Command | Description | +| ------- | -------------------------------------- | ------------------------------------------------------ | +| prc | `pre-commit` | The `pre-commit` command | +| prcau | `pre-commit autoupdate` | Update hooks automatically | +| prcr | `pre-commit run` | The `pre-commit run` command | +| prcra | `pre-commit run --all-files` | Run pre-commit hooks on all files | +| prcrf | `pre-commit run --files` | Run pre-commit hooks on a given list of files | diff --git a/plugins/pre-commit/pre-commit.plugin.zsh b/plugins/pre-commit/pre-commit.plugin.zsh new file mode 100644 index 000000000..c3d0c6290 --- /dev/null +++ b/plugins/pre-commit/pre-commit.plugin.zsh @@ -0,0 +1,8 @@ +# Aliases for pre-commit +alias prc='pre-commit' + +alias prcau='pre-commit autoupdate' + +alias prcr='pre-commit run' +alias prcra='pre-commit run --all-files' +alias prcrf='pre-commit run --files' diff --git a/plugins/pyenv/pyenv.plugin.zsh b/plugins/pyenv/pyenv.plugin.zsh index 7fbd1589e..48c8ffaf5 100644 --- a/plugins/pyenv/pyenv.plugin.zsh +++ b/plugins/pyenv/pyenv.plugin.zsh @@ -78,7 +78,7 @@ if [[ $FOUND_PYENV -eq 1 ]]; then eval "$(pyenv init - --no-rehash zsh)" # If pyenv-virtualenv exists, load it - if [[ "$(pyenv commands)" =~ "virtualenv-init" && "$ZSH_PYENV_VIRTUALENV" != false ]]; then + if [[ "$ZSH_PYENV_VIRTUALENV" != false && "$(pyenv commands)" =~ "virtualenv-init" ]]; then eval "$(pyenv virtualenv-init - zsh)" fi diff --git a/plugins/qrcode/README.md b/plugins/qrcode/README.md new file mode 100644 index 000000000..442838947 --- /dev/null +++ b/plugins/qrcode/README.md @@ -0,0 +1,8 @@ +# QRCode plugin + +Generate a QR Code from the command line. Uses [QRcode.show](https://qrcode.show) via curl. + +alias | command +--------------- | -------- +`qrcode [text]` | `curl -d "text" qrcode.show` +`qrsvg [text]` | `curl -d "text" qrcode.show -H "Accept: image/svg+xml"` diff --git a/plugins/qrcode/qrcode.plugin.zsh b/plugins/qrcode/qrcode.plugin.zsh new file mode 100644 index 000000000..d757e135e --- /dev/null +++ b/plugins/qrcode/qrcode.plugin.zsh @@ -0,0 +1,17 @@ +# Imported and improved from https://qrcode.show/, section SHELL FUNCTIONS + +_qrcode_show_message() { + echo "Type or paste your text, add a new blank line, and press ^d" +} + +qrcode () { + local input="$*" + [ -z "$input" ] && _qrcode_show_message && local input="@/dev/stdin" + curl -d "$input" https://qrcode.show +} + +qrsvg () { + local input="$*" + [ -z "$input" ] && _qrcode_show_message && local input="@/dev/stdin" + curl -d "$input" https://qrcode.show -H "Accept: image/svg+xml" +} diff --git a/plugins/rails/README.md b/plugins/rails/README.md index fa66750f0..b2425aabc 100644 --- a/plugins/rails/README.md +++ b/plugins/rails/README.md @@ -47,6 +47,7 @@ plugins=(... rails) | `rsp` | `rails server --port` | Launch a web server and specify the listening port | | `rsts` | `rails stats` | Print code statistics | | `rt` | `rails test` | Run Rails tests | +| `rta` | `rails test:all` | Runs all Rails tests, including system tests | | `ru` | `rails runner` | Run Ruby code in the context of Rails | ### Foreman diff --git a/plugins/rails/_rails b/plugins/rails/_rails index 6dc85d458..ac90d45cc 100644 --- a/plugins/rails/_rails +++ b/plugins/rails/_rails @@ -1,6 +1,6 @@ #compdef rails # ------------------------------------------------------------------------------ -# Copyright (c) 2016 Github zsh-users - http://github.com/zsh-users +# Copyright (c) 2016 GitHub zsh-users - http://github.com/zsh-users # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/plugins/rails/rails.plugin.zsh b/plugins/rails/rails.plugin.zsh index b11cbb5c7..015dc9ecb 100644 --- a/plugins/rails/rails.plugin.zsh +++ b/plugins/rails/rails.plugin.zsh @@ -75,6 +75,7 @@ alias rsd='rails server --debugger' alias rsp='rails server --port' alias rsts='rails stats' alias rt='rails test' +alias rta='rails test:all' alias ru='rails runner' # Foreman aliases diff --git a/plugins/react-native/README.md b/plugins/react-native/README.md index d0a53b8d7..807c063a5 100644 --- a/plugins/react-native/README.md +++ b/plugins/react-native/README.md @@ -11,66 +11,78 @@ plugins=(... react-native) ## Aliases -| Alias | React Native command | -| :------------ | :------------------------------------------------- | -| **rn** | `react-native` | -| **rns** | `react-native start` | -| **rnlink** | `react-native link` | -| _Logging_ | | -| **rnland** | `react-native log-android` | -| **rnlios** | `react-native log-ios` | -| _App Testing_ | | -| **rnand** | `react-native run-android` | -| **rnios** | `react-native run-ios` | -| _iPhone_ | | -| **rnios4s** | `react-native run-ios --simulator "iPhone 4s"` | -| **rnios5** | `react-native run-ios --simulator "iPhone 5"` | -| **rnios5s** | `react-native run-ios --simulator "iPhone 5s"` | -| **rnios6** | `react-native run-ios --simulator "iPhone 6"` | -| **rnios6s** | `react-native run-ios --simulator "iPhone 6s"` | -| **rnios6p** | `react-native run-ios --simulator "iPhone 6 Plus"` | -| **rnios6sp** | `react-native run-ios --simulator "iPhone 6s Plus"` | -| **rnios7** | `react-native run-ios --simulator "iPhone 7"` | -| **rnios7p** | `react-native run-ios --simulator "iPhone 7 Plus"` | -| **rnios8** | `react-native run-ios --simulator "iPhone 8"` | -| **rnios8p** | `react-native run-ios --simulator "iPhone 8 Plus"` | -| **rniosse** | `react-native run-ios --simulator "iPhone SE"` | -| **rniosx** | `react-native run-ios --simulator "iPhone X"` | -| **rniosxs** | `react-native run-ios --simulator "iPhone Xs"` | -| **rniosxsm** | `react-native run-ios --simulator "iPhone Xs Max"` | -| **rniosxr** | `react-native run-ios --simulator "iPhone Xʀ"` | -| **rnios11** | `react-native run-ios --simulator "iPhone 11"` | -| **rnios11p** | `react-native run-ios --simulator "iPhone 11 Pro"` | -| **rnios11pm** | `react-native run-ios --simulator "iPhone 11 Pro Max"` | -| _iPad_ | | -| **rnipad2** | `react-native run-ios --simulator "iPad 2"` | -| **rnipad5** | `react-native run-ios --simulator "iPad (5th generation)"` | -| **rnipad6** | `react-native run-ios --simulator "iPad (6th generation)"` | -| **rnipadr** | `react-native run-ios --simulator "iPad Retina"` | -| **rnipada** | `react-native run-ios --simulator "iPad Air"` | -| **rnipada2** | `react-native run-ios --simulator "iPad Air 2"` | -| **rnipada3** | `react-native run-ios --simulator "iPad Air (3rd generation)"` | -| **rnipadm2** | `react-native run-ios --simulator "iPad mini 2"` | -| **rnipadm3** | `react-native run-ios --simulator "iPad mini 3"` | -| **rnipadm4** | `react-native run-ios --simulator "iPad mini 4"` | -| **rnipadm5** | `react-native run-ios --simulator "iPad mini (5th generation)"` | -| **rnipadp9** | `react-native run-ios --simulator "iPad Pro (9.7-inch)"` | -| **rnipadp12** | `react-native run-ios --simulator "iPad Pro (12.9-inch)"` | -| **rnipadp122** | `react-native run-ios --simulator "iPad Pro (12.9-inch) (2nd generation)"` | -| **rnipadp10** | `react-native run-ios --simulator "iPad Pro (10.5-inch)"` | -| **rnipad11** | `react-native run-ios --simulator "iPad Pro (11-inch)"` | -| **rnipad123** | `react-native run-ios --simulator "iPad Pro (12.9-inch) (3rd generation)"` | -| _Apple TV_ | | -| **rnatv** | `react-native run-ios --simulator "Apple TV"` | -| **rnatv4k** | `react-native run-ios --simulator "Apple TV 4K"` | -| **rnatv4k1080**| `react-native run-ios --simulator "Apple TV 4K (at 1080p)"` | -| **rnipad123** | `react-native run-ios --simulator "iPad Pro (12.9-inch) (3rd generation)"` | -| _Apple Watch_ | | -| **rnaw38** | `react-native run-ios --simulator "Apple Watch - 38mm"` | -| **rnaw42** | `react-native run-ios --simulator "Apple Watch - 42mm"` | -| **rnaws238** | `react-native run-ios --simulator "Apple Watch Series 2 - 38mm"` | -| **rnaws242** | `react-native run-ios --simulator "Apple Watch Series 2 - 42mm"` | -| **rnaws338** | `react-native run-ios --simulator "Apple Watch Series 3 - 38mm"` | -| **rnaws342** | `react-native run-ios --simulator "Apple Watch Series 3 - 42mm"` | -| **rnaws440** | `react-native run-ios --simulator "Apple Watch Series 4 - 40mm"` | -| **rnaws444** | `react-native run-ios --simulator "Apple Watch Series 4 - 44mm"` | +| Alias | React Native command | +| :-------------- | :------------------------------------------------------------------------- | +| **rn** | `react-native` | +| **rns** | `react-native start` | +| **rnlink** | `react-native link` | +| _Logging_ | | +| **rnland** | `react-native log-android` | +| **rnlios** | `react-native log-ios` | +| _App Testing_ | | +| **rnand** | `react-native run-android` | +| **rnios** | `react-native run-ios` | +| _iPhone_ | | +| **rnios4s** | `react-native run-ios --simulator "iPhone 4s"` | +| **rnios5** | `react-native run-ios --simulator "iPhone 5"` | +| **rnios5s** | `react-native run-ios --simulator "iPhone 5s"` | +| **rnios6** | `react-native run-ios --simulator "iPhone 6"` | +| **rnios6s** | `react-native run-ios --simulator "iPhone 6s"` | +| **rnios6p** | `react-native run-ios --simulator "iPhone 6 Plus"` | +| **rnios6sp** | `react-native run-ios --simulator "iPhone 6s Plus"` | +| **rnios7** | `react-native run-ios --simulator "iPhone 7"` | +| **rnios7p** | `react-native run-ios --simulator "iPhone 7 Plus"` | +| **rnios8** | `react-native run-ios --simulator "iPhone 8"` | +| **rnios8p** | `react-native run-ios --simulator "iPhone 8 Plus"` | +| **rniosse** | `react-native run-ios --simulator "iPhone SE"` | +| **rniosx** | `react-native run-ios --simulator "iPhone X"` | +| **rniosxs** | `react-native run-ios --simulator "iPhone Xs"` | +| **rniosxsm** | `react-native run-ios --simulator "iPhone Xs Max"` | +| **rniosxr** | `react-native run-ios --simulator "iPhone Xʀ"` | +| **rnios11** | `react-native run-ios --simulator "iPhone 11"` | +| **rnios11p** | `react-native run-ios --simulator "iPhone 11 Pro"` | +| **rnios11pm** | `react-native run-ios --simulator "iPhone 11 Pro Max"` | +| **rnios12** | `react-native run-ios --simulator "iPhone 12"` | +| **rnios12m** | `react-native run-ios --simulator "iPhone 12 mini"` | +| **rnios12p** | `react-native run-ios --simulator "iPhone 12 Pro"` | +| **rnios12pm** | `react-native run-ios --simulator "iPhone 12 Pro Max"` | +| **rnios13** | `react-native run-ios --simulator "iPhone 13"` | +| **rnios13m** | `react-native run-ios --simulator "iPhone 13 mini"` | +| **rnios13p** | `react-native run-ios --simulator "iPhone 13 Pro"` | +| **rnios13pm** | `react-native run-ios --simulator "iPhone 13 Pro Max"` | +| **rnios14** | `react-native run-ios --simulator "iPhone 14"` | +| **rnios14pl** | `react-native run-ios --simulator "iPhone 14 Plus"` | +| **rnios14p** | `react-native run-ios --simulator "iPhone 14 Pro"` | +| **rnios14pm** | `react-native run-ios --simulator "iPhone 14 Pro Max"` | +| _iPad_ | | +| **rnipad2** | `react-native run-ios --simulator "iPad 2"` | +| **rnipad5** | `react-native run-ios --simulator "iPad (5th generation)"` | +| **rnipad6** | `react-native run-ios --simulator "iPad (6th generation)"` | +| **rnipadr** | `react-native run-ios --simulator "iPad Retina"` | +| **rnipada** | `react-native run-ios --simulator "iPad Air"` | +| **rnipada2** | `react-native run-ios --simulator "iPad Air 2"` | +| **rnipada3** | `react-native run-ios --simulator "iPad Air (3rd generation)"` | +| **rnipadm2** | `react-native run-ios --simulator "iPad mini 2"` | +| **rnipadm3** | `react-native run-ios --simulator "iPad mini 3"` | +| **rnipadm4** | `react-native run-ios --simulator "iPad mini 4"` | +| **rnipadm5** | `react-native run-ios --simulator "iPad mini (5th generation)"` | +| **rnipadp9** | `react-native run-ios --simulator "iPad Pro (9.7-inch)"` | +| **rnipadp12** | `react-native run-ios --simulator "iPad Pro (12.9-inch)"` | +| **rnipadp122** | `react-native run-ios --simulator "iPad Pro (12.9-inch) (2nd generation)"` | +| **rnipadp10** | `react-native run-ios --simulator "iPad Pro (10.5-inch)"` | +| **rnipad11** | `react-native run-ios --simulator "iPad Pro (11-inch)"` | +| **rnipad123** | `react-native run-ios --simulator "iPad Pro (12.9-inch) (3rd generation)"` | +| _Apple TV_ | | +| **rnatv** | `react-native run-ios --simulator "Apple TV"` | +| **rnatv4k** | `react-native run-ios --simulator "Apple TV 4K"` | +| **rnatv4k1080** | `react-native run-ios --simulator "Apple TV 4K (at 1080p)"` | +| **rnipad123** | `react-native run-ios --simulator "iPad Pro (12.9-inch) (3rd generation)"` | +| _Apple Watch_ | | +| **rnaw38** | `react-native run-ios --simulator "Apple Watch - 38mm"` | +| **rnaw42** | `react-native run-ios --simulator "Apple Watch - 42mm"` | +| **rnaws238** | `react-native run-ios --simulator "Apple Watch Series 2 - 38mm"` | +| **rnaws242** | `react-native run-ios --simulator "Apple Watch Series 2 - 42mm"` | +| **rnaws338** | `react-native run-ios --simulator "Apple Watch Series 3 - 38mm"` | +| **rnaws342** | `react-native run-ios --simulator "Apple Watch Series 3 - 42mm"` | +| **rnaws440** | `react-native run-ios --simulator "Apple Watch Series 4 - 40mm"` | +| **rnaws444** | `react-native run-ios --simulator "Apple Watch Series 4 - 44mm"` | diff --git a/plugins/react-native/react-native.plugin.zsh b/plugins/react-native/react-native.plugin.zsh index 8323c27bd..afeaab4fd 100644 --- a/plugins/react-native/react-native.plugin.zsh +++ b/plugins/react-native/react-native.plugin.zsh @@ -28,9 +28,17 @@ alias rnios11='react-native run-ios --simulator "iPhone 11"' alias rnios11p='react-native run-ios --simulator "iPhone 11 Pro"' alias rnios11pm='react-native run-ios --simulator "iPhone 11 Pro Max"' alias rnios12='react-native run-ios --simulator "iPhone 12"' +alias rnios12m='react-native run-ios --simulator "iPhone 12 mini"' alias rnios12p='react-native run-ios --simulator "iPhone 12 Pro"' alias rnios12pm='react-native run-ios --simulator "iPhone 12 Pro Max"' - +alias rnios13='react-native run-ios --simulator "iPhone 13"' +alias rnios13m='react-native run-ios --simulator "iPhone 13 mini"' +alias rnios13p='react-native run-ios --simulator "iPhone 13 Pro"' +alias rnios13pm='react-native run-ios --simulator "iPhone 13 Pro Max"' +alias rnios14='react-native run-ios --simulator "iPhone 14"' +alias rnios14pl='react-native run-ios --simulator "iPhone 14 Plus"' +alias rnios14p='react-native run-ios --simulator "iPhone 14 Pro"' +alias rnios14pm='react-native run-ios --simulator "iPhone 14 Pro Max"' # iPad alias rnipad2='react-native run-ios --simulator "iPad 2"' diff --git a/plugins/ripgrep/_ripgrep b/plugins/ripgrep/_ripgrep index 31bc697c7..a93a8b8eb 100644 --- a/plugins/ripgrep/_ripgrep +++ b/plugins/ripgrep/_ripgrep @@ -591,7 +591,7 @@ _rg "$@" ################################################################################ # ------------------------------------------------------------------------------ -# Copyright (c) 2011 Github zsh-users - http://github.com/zsh-users +# Copyright (c) 2011 GitHub zsh-users - http://github.com/zsh-users # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/plugins/rustup/README.md b/plugins/rustup/README.md deleted file mode 100644 index c620e72a8..000000000 --- a/plugins/rustup/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# rustup - -**Deprecated: use the [`rust`](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/rust) plugin instead.** diff --git a/plugins/rustup/rustup.plugin.zsh b/plugins/rustup/rustup.plugin.zsh deleted file mode 100644 index ef141cf8f..000000000 --- a/plugins/rustup/rustup.plugin.zsh +++ /dev/null @@ -1,7 +0,0 @@ -print ${(%):-'%F{yellow}The `rustup` plugin is deprecated and has been moved to the `rust` plugin.'} -print ${(%):-'Please update your .zshrc to use the `%Brust%b` plugin instead.%f'} - -(( ${fpath[(Ie)$ZSH/plugins/rust]} )) || { - fpath=("$ZSH/plugins/rust" $fpath) - source "$ZSH/plugins/rust/rust.plugin.zsh" -} diff --git a/plugins/rvm/README.md b/plugins/rvm/README.md index 576b037b0..410bd60c0 100644 --- a/plugins/rvm/README.md +++ b/plugins/rvm/README.md @@ -24,6 +24,7 @@ plugins=(... rvm) | `rb27` | `rvm use ruby-2.7` | | `rb30` | `rvm use ruby-3.0` | | `rb31` | `rvm use ruby-3.1` | +| `rb32` | `rvm use ruby-3.2` | | `rvm-update` | `rvm get head` | | `gems` | `gem list` | | `rvms` | `rvm gemset` | diff --git a/plugins/rvm/rvm.plugin.zsh b/plugins/rvm/rvm.plugin.zsh index 2a091d019..3ddf04176 100644 --- a/plugins/rvm/rvm.plugin.zsh +++ b/plugins/rvm/rvm.plugin.zsh @@ -27,6 +27,7 @@ rubies=( 27 'ruby-2.7' 30 'ruby-3.0' 31 'ruby-3.1' + 32 'ruby-3.2' ) for v in ${(k)rubies}; do diff --git a/plugins/salt/_salt b/plugins/salt/_salt index a1c55f350..589d21d8b 100644 --- a/plugins/salt/_salt +++ b/plugins/salt/_salt @@ -9,7 +9,7 @@ # zstyle ':completion::complete:salt(|-call):modules:' use-cache true # zstyle ':completion::complete:salt(|-cp|-call|-run|-key):salt_dir:' use-cache true # -# cache validation can be controled with the style cache-ttl. +# cache validation can be controlled with the style cache-ttl. # it expects two arguments: number (days|hours|weeks|months) # to invalidate the minion cache after four days: # zstyle ':completion::complete:salt(|-cp|-call):minions:' cache-ttl 4 days diff --git a/plugins/scala/_scala b/plugins/scala/_scala index ba7ac3874..b4e834e2f 100644 --- a/plugins/scala/_scala +++ b/plugins/scala/_scala @@ -1,6 +1,6 @@ #compdef scala scalac # ------------------------------------------------------------------------------ -# Copyright (c) 2012 Github zsh-users - https://github.com/zsh-users +# Copyright (c) 2012 GitHub zsh-users - https://github.com/zsh-users # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/plugins/shell-proxy/shell-proxy.plugin.zsh b/plugins/shell-proxy/shell-proxy.plugin.zsh index 9d45b5269..4fdbe9322 100644 --- a/plugins/shell-proxy/shell-proxy.plugin.zsh +++ b/plugins/shell-proxy/shell-proxy.plugin.zsh @@ -1,32 +1,39 @@ #!/usr/bin/bash # shellcheck disable=SC1090,SC2154 -proxy() { - # deprecate $DEFAULT_PROXY, use SHELLPROXY_URL instead - if [[ -n "$DEFAULT_PROXY" && -z "$SHELLPROXY_URL" ]]; then - echo >&2 "proxy: DEFAULT_PROXY is deprecated, use SHELLPROXY_URL instead" - SHELLPROXY_URL="$DEFAULT_PROXY" - unset DEFAULT_PROXY - fi +# Handle $0 according to the standard: +# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html +0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}" +0="${${(M)0:#/*}:-$PWD/$0}" - # deprecate CONFIG_PROXY, use SHELLPROXY_CONFIG instead - if [[ -n "$CONFIG_PROXY" && -z "$SHELLPROXY_CONFIG" ]]; then - echo >&2 "proxy: CONFIG_PROXY is deprecated, use SHELLPROXY_CONFIG instead" - SHELLPROXY_CONFIG="$CONFIG_PROXY" - unset CONFIG_PROXY - fi +eval ' + proxy() { + # deprecate $DEFAULT_PROXY, use SHELLPROXY_URL instead + if [[ -n "$DEFAULT_PROXY" && -z "$SHELLPROXY_URL" ]]; then + echo >&2 "proxy: DEFAULT_PROXY is deprecated, use SHELLPROXY_URL instead" + SHELLPROXY_URL="$DEFAULT_PROXY" + unset DEFAULT_PROXY + fi - # the proxy.py script is in the same directory as this function - local proxy="${functions_source[$0]:A:h}/proxy.py" + # deprecate CONFIG_PROXY, use SHELLPROXY_CONFIG instead + if [[ -n "$CONFIG_PROXY" && -z "$SHELLPROXY_CONFIG" ]]; then + echo >&2 "proxy: CONFIG_PROXY is deprecated, use SHELLPROXY_CONFIG instead" + SHELLPROXY_CONFIG="$CONFIG_PROXY" + unset CONFIG_PROXY + fi - # capture the output of the proxy script and bail out if it fails - local output - output="$(SHELLPROXY_URL="$SHELLPROXY_URL" SHELLPROXY_CONFIG="$SHELLPROXY_CONFIG" "$proxy" "$1")" || - return $? + # the proxy.py script is in the same directory as this function + local proxy="'"${0:h}"'/proxy.py" - # evaluate the output generated by the proxy script - source <(echo "$output") -} + # capture the output of the proxy script and bail out if it fails + local output + output="$(SHELLPROXY_URL="$SHELLPROXY_URL" SHELLPROXY_CONFIG="$SHELLPROXY_CONFIG" "$proxy" "$1")" || + return $? + + # evaluate the output generated by the proxy script + source <(echo "$output") + } +' _proxy() { local -r commands=('enable' 'disable' 'status') diff --git a/plugins/sigstore/README.md b/plugins/sigstore/README.md new file mode 100644 index 000000000..00e83c8c2 --- /dev/null +++ b/plugins/sigstore/README.md @@ -0,0 +1,13 @@ +# Sigstore plugin + +This plugin sets up completion for the following [Sigstore](https://sigstore.dev/) CLI tools. + +- [Cosign](https://docs.sigstore.dev/cosign/overview) +- [Sget](https://docs.sigstore.dev/cosign/installation#alpine-linux) +- [Rekor](https://docs.sigstore.dev/rekor/overview) + +To use it, add `sigstore` to the plugins array in your zshrc file: + +```zsh +plugins=(... sigstore) +``` diff --git a/plugins/sigstore/sigstore.plugin.zsh b/plugins/sigstore/sigstore.plugin.zsh new file mode 100644 index 000000000..1f9d77c11 --- /dev/null +++ b/plugins/sigstore/sigstore.plugin.zsh @@ -0,0 +1,22 @@ +function install_autocompletion { + if (( ! $+commands[$1] )); then + return + fi + + # If the completion file doesn't exist yet, we need to autoload it and + # bind it to `$1` (cosign, sget, rekor-cli). Otherwise, compinit will + # have already done that + if [[ ! -f "$ZSH_CACHE_DIR/completions/_$1" ]]; then + autoload -Uz _$1 + typeset -g -A _comps + _comps[$1]=_$1 + fi + + $1 completion zsh >| "$ZSH_CACHE_DIR/completions/_$1" &| +} + +install_autocompletion cosign +install_autocompletion sget +install_autocompletion rekor-cli + +unfunction install_autocompletion diff --git a/plugins/skaffold/README.md b/plugins/skaffold/README.md new file mode 100644 index 000000000..4ee12c666 --- /dev/null +++ b/plugins/skaffold/README.md @@ -0,0 +1,9 @@ +# Skaffold plugin (Autocompletion) + +This plugin adds completion for [Skaffold](https://skaffold.dev) + +To use it, add `skaffold` to the plugins array in your zshrc file: + +```zsh +plugins=(... skaffold) +``` diff --git a/plugins/skaffold/skaffold.plugin.zsh b/plugins/skaffold/skaffold.plugin.zsh new file mode 100644 index 000000000..8296c450c --- /dev/null +++ b/plugins/skaffold/skaffold.plugin.zsh @@ -0,0 +1,14 @@ +# Autocompletion for skaffold +if (( ! $+commands[skaffold] )); then + return +fi + +# If the completion file doesn't exist yet, we need to autoload it and +# bind it to `skaffold`. Otherwise, compinit will have already done that. +if [[ ! -f "$ZSH_CACHE_DIR/completions/_skaffold" ]]; then + typeset -g -A _comps + autoload -Uz _skaffold + _comps[skaffold]=_skaffold +fi + +skaffold completion zsh >| "$ZSH_CACHE_DIR/completions/_skaffold" &| diff --git a/plugins/ssh-agent/ssh-agent.plugin.zsh b/plugins/ssh-agent/ssh-agent.plugin.zsh index 0d6a35b35..78ac46b13 100644 --- a/plugins/ssh-agent/ssh-agent.plugin.zsh +++ b/plugins/ssh-agent/ssh-agent.plugin.zsh @@ -72,6 +72,9 @@ function _add_identities() { local args zstyle -a :omz:plugins:ssh-agent ssh-add-args args + # if ssh-agent quiet mode, pass -q to ssh-add + zstyle -t :omz:plugins:ssh-agent quiet && args=(-q $args) + # use user specified helper to ask for password (ksshaskpass, etc) local helper zstyle -s :omz:plugins:ssh-agent helper helper diff --git a/plugins/sudo/sudo.plugin.zsh b/plugins/sudo/sudo.plugin.zsh index 2a0b3bfc4..66b253fe7 100644 --- a/plugins/sudo/sudo.plugin.zsh +++ b/plugins/sudo/sudo.plugin.zsh @@ -96,7 +96,7 @@ sudo-command-line() { LBUFFER="${WHITESPACE}${LBUFFER}" # Redisplay edit buffer (compatibility with zsh-syntax-highlighting) - zle redisplay + zle && zle redisplay # only run redisplay if zle is enabled } } diff --git a/plugins/swiftpm/README.md b/plugins/swiftpm/README.md index a722c03e4..223a607c1 100644 --- a/plugins/swiftpm/README.md +++ b/plugins/swiftpm/README.md @@ -2,7 +2,7 @@ ## Description -This plugin provides a few utilities that make you faster on your daily work with the [Swift Package Manager](https://github.com/apple/swift-package-manager), as well as autocompletion for Swift 5.1. +This plugin provides a few utilities that make you faster on your daily work with the [Swift Package Manager](https://github.com/apple/swift-package-manager), as well as autocompletion for Swift 5.7. To start using it, add the `swiftpm` plugin to your `plugins` array in `~/.zshrc`: diff --git a/plugins/swiftpm/_swift b/plugins/swiftpm/_swift index fe6f1c9aa..51c9fffa0 100644 --- a/plugins/swiftpm/_swift +++ b/plugins/swiftpm/_swift @@ -1,474 +1,876 @@ #compdef swift local context state state_descr line +_swift_commandname=$words[1] typeset -A opt_args _swift() { - _arguments -C \ - '(- :)--help[prints the synopsis and a list of the most commonly used commands]: :->arg' \ - '(-): :->command' \ - '(-)*:: :->arg' && return - + integer ret=1 + local -a args + args+=( + '(-h --help)'{-h,--help}'[Show help information.]' + '(-): :->command' + '(-)*:: :->arg' + ) + _arguments -w -s -S $args[@] && ret=0 case $state in (command) - local tools - tools=( - 'build:build sources into binary products' - 'run:build and run an executable product' - 'package:perform operations on Swift packages' - 'test:build and run tests' + local subcommands + subcommands=( + 'run:Build and run an executable product' + 'build:Build sources into binary products' + 'test:Build and run tests' + 'package:Perform operations on Swift packages' + 'help:Show subcommand help information.' ) - _alternative \ - 'tools:common:{_describe "tool" tools }' \ - 'compiler: :_swift_compiler' && _ret=0 + _describe "subcommand" subcommands ;; (arg) case ${words[1]} in - (build) - _swift_build - ;; (run) _swift_run ;; - (package) - _swift_package + (build) + _swift_build ;; (test) _swift_test ;; - (*) - _swift_compiler + (package) + _swift_package + ;; + (help) + _swift_help ;; esac ;; esac + + return ret } -_swift_dependency() { - local dependencies - dependencies=( $(swift package completion-tool list-dependencies) ) - _describe '' dependencies -} - -_swift_executable() { - local executables - executables=( $(swift package completion-tool list-executables) ) - _describe '' executables -} - -# Generates completions for swift build -# -# In the final compdef file, set the following file header: -# -# #compdef _swift_build -# local context state state_descr line -# typeset -A opt_args -_swift_build() { - arguments=( - "-Xcc[Pass flag through to all C compiler invocations]:Pass flag through to all C compiler invocations: " - "-Xswiftc[Pass flag through to all Swift compiler invocations]:Pass flag through to all Swift compiler invocations: " - "-Xlinker[Pass flag through to all linker invocations]:Pass flag through to all linker invocations: " - "-Xcxx[Pass flag through to all C++ compiler invocations]:Pass flag through to all C++ compiler invocations: " - "(--configuration -c)"{--configuration,-c}"[Build with configuration (debug|release) ]: :{_values '' 'debug[build with DEBUG configuration]' 'release[build with RELEASE configuration]'}" - "--build-path[Specify build/cache directory ]:Specify build/cache directory :_files" - "(--chdir -C)"{--chdir,-C}"[]: :_files" - "--package-path[Change working directory before any other operation]:Change working directory before any other operation:_files" - "--sanitize[Turn on runtime checks for erroneous behavior]: :{_values '' 'address[enable Address sanitizer]' 'thread[enable Thread sanitizer]' 'undefined[enable Undefined Behavior sanitizer]'}" - "--disable-prefetching[]" - "--skip-update[Skip updating dependencies from their remote during a resolution]" - "--disable-sandbox[Disable using the sandbox when executing subprocesses]" - "--disable-package-manifest-caching[Disable caching Package.swift manifests]" - "--version[]" - "--destination[]: :_files" - "(--verbose -v)"{--verbose,-v}"[Increase verbosity of informational output]" - "--no-static-swift-stdlib[Do not link Swift stdlib statically \[default\]]" - "--static-swift-stdlib[Link Swift stdlib statically]" - "--force-resolved-versions[]" - "--disable-automatic-resolution[Disable automatic resolution if Package.resolved file is out-of-date]" - "--enable-index-store[Enable indexing-while-building feature]" - "--disable-index-store[Disable indexing-while-building feature]" - "--enable-pubgrub-resolver[\[Experimental\] Enable the new Pubgrub dependency resolver]" - "--enable-parseable-module-interfaces[]" - "--trace-resolver[]" - "(--jobs -j)"{--jobs,-j}"[The number of jobs to spawn in parallel during the build process]:The number of jobs to spawn in parallel during the build process: " - "--enable-test-discovery[Enable test discovery on platforms without Objective-C runtime]" - "--build-tests[Build both source and test targets]" - "--product[Build the specified product]:Build the specified product: " - "--target[Build the specified target]:Build the specified target: " - "--show-bin-path[Print the binary output path]" - ) - _arguments $arguments && return -} - -# Generates completions for swift run -# -# In the final compdef file, set the following file header: -# -# #compdef _swift_run -# local context state state_descr line -# typeset -A opt_args _swift_run() { - arguments=( - ":The executable to run:_swift_executable" - "-Xcc[Pass flag through to all C compiler invocations]:Pass flag through to all C compiler invocations: " - "-Xswiftc[Pass flag through to all Swift compiler invocations]:Pass flag through to all Swift compiler invocations: " - "-Xlinker[Pass flag through to all linker invocations]:Pass flag through to all linker invocations: " - "-Xcxx[Pass flag through to all C++ compiler invocations]:Pass flag through to all C++ compiler invocations: " - "(--configuration -c)"{--configuration,-c}"[Build with configuration (debug|release) ]: :{_values '' 'debug[build with DEBUG configuration]' 'release[build with RELEASE configuration]'}" - "--build-path[Specify build/cache directory ]:Specify build/cache directory :_files" - "(--chdir -C)"{--chdir,-C}"[]: :_files" - "--package-path[Change working directory before any other operation]:Change working directory before any other operation:_files" - "--sanitize[Turn on runtime checks for erroneous behavior]: :{_values '' 'address[enable Address sanitizer]' 'thread[enable Thread sanitizer]' 'undefined[enable Undefined Behavior sanitizer]'}" - "--disable-prefetching[]" - "--skip-update[Skip updating dependencies from their remote during a resolution]" - "--disable-sandbox[Disable using the sandbox when executing subprocesses]" - "--disable-package-manifest-caching[Disable caching Package.swift manifests]" - "--version[]" - "--destination[]: :_files" - "(--verbose -v)"{--verbose,-v}"[Increase verbosity of informational output]" - "--no-static-swift-stdlib[Do not link Swift stdlib statically \[default\]]" - "--static-swift-stdlib[Link Swift stdlib statically]" - "--force-resolved-versions[]" - "--disable-automatic-resolution[Disable automatic resolution if Package.resolved file is out-of-date]" - "--enable-index-store[Enable indexing-while-building feature]" - "--disable-index-store[Disable indexing-while-building feature]" - "--enable-pubgrub-resolver[\[Experimental\] Enable the new Pubgrub dependency resolver]" - "--enable-parseable-module-interfaces[]" - "--trace-resolver[]" - "(--jobs -j)"{--jobs,-j}"[The number of jobs to spawn in parallel during the build process]:The number of jobs to spawn in parallel during the build process: " - "--enable-test-discovery[Enable test discovery on platforms without Objective-C runtime]" - "--skip-build[Skip building the executable product]" - "--build-tests[Build both source and test targets]" - "--repl[Launch Swift REPL for the package]" + integer ret=1 + local -a args + args+=( + '--package-path[Specify the package path to operate on (default current directory). This changes the working directory before any other operation]:package-path:_files -/' + '--cache-path[Specify the shared cache directory path]:cache-path:_files -/' + '--config-path[Specify the shared configuration directory path]:config-path:_files -/' + '--security-path[Specify the shared security directory path]:security-path:_files -/' + '--scratch-path[Specify a custom scratch directory path (default .build)]:scratch-path:_files -/' + '--enable-dependency-cache[Use a shared cache when fetching dependencies]' + '--disable-dependency-cache[Use a shared cache when fetching dependencies]' + '--enable-build-manifest-caching' + '--disable-build-manifest-caching' + '--manifest-cache[Caching mode of Package.swift manifests (shared: shared cache, local: package'"'"'s build directory, none: disabled]:manifest-cache:' + '(--verbose -v)'{--verbose,-v}'[Increase verbosity to include informational output]' + '(--very-verbose --vv)'{--very-verbose,--vv}'[Increase verbosity to include debug output]' + '--disable-sandbox[Disable using the sandbox when executing subprocesses]' + '--enable-netrc[Load credentials from a .netrc file]' + '--disable-netrc[Load credentials from a .netrc file]' + '--netrc-file[Specify the .netrc file path.]:netrc-file:_files' + '--enable-keychain[Search credentials in macOS keychain]' + '--disable-keychain[Search credentials in macOS keychain]' + '--resolver-fingerprint-checking:resolver-fingerprint-checking:' + '--enable-prefetching' + '--disable-prefetching' + '(--force-resolved-versions --disable-automatic-resolution --only-use-versions-from-resolved-file)'{--force-resolved-versions,--disable-automatic-resolution,--only-use-versions-from-resolved-file}'[Only use versions from the Package.resolved file and fail resolution if it is out-of-date]' + '--skip-update[Skip updating dependencies from their remote during a resolution]' + '--disable-scm-to-registry-transformation[disable source control to registry transformation]' + '--use-registry-identity-for-scm[look up source control dependencies in the registry and use their registry identity when possible to help deduplicate across the two origins]' + '--replace-scm-with-registry[look up source control dependencies in the registry and use the registry to retrieve them instead of source control when possible]' + '(--configuration -c)'{--configuration,-c}'[Build with configuration]:configuration:(debug release)' + '-Xcc[Pass flag through to all C compiler invocations]:Xcc:' + '-Xswiftc[Pass flag through to all Swift compiler invocations]:Xswiftc:' + '-Xlinker[Pass flag through to all linker invocations]:Xlinker:' + '-Xcxx[Pass flag through to all C++ compiler invocations]:Xcxx:' + '--triple:triple:' + '--sdk:sdk:_files -/' + '--toolchain:toolchain:_files -/' + '--sanitize[Turn on runtime checks for erroneous behavior, possible values: address, thread, undefined, scudo]:sanitize:' + '--auto-index-store[Enable or disable indexing-while-building feature]' + '--enable-index-store[Enable or disable indexing-while-building feature]' + '--disable-index-store[Enable or disable indexing-while-building feature]' + '--enable-parseable-module-interfaces' + '(--jobs -j)'{--jobs,-j}'[The number of jobs to spawn in parallel during the build process]:jobs:' + '--emit-swift-module-separately' + '--use-integrated-swift-driver' + '--experimental-explicit-module-build' + '--print-manifest-job-graph[Write the command graph for the build manifest as a graphviz file]' + '--build-system:build-system:(native xcode)' + '--enable-dead-strip[Disable/enable dead code stripping by the linker]' + '--disable-dead-strip[Disable/enable dead code stripping by the linker]' + '--static-swift-stdlib[Link Swift stdlib statically]' + '--no-static-swift-stdlib[Link Swift stdlib statically]' + '--repl[Launch Swift REPL for the package]' + '--debugger[Launch the executable in a debugger session]' + '--run[Launch the executable with the provided arguments]' + '--skip-build[Skip building the executable product]' + '--build-tests[Build both source and test targets]' + ':executable:{local -a list; list=(${(f)"$(swift package completion-tool list-executables)"}); _describe '''' list}' + ':arguments:' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' ) - _arguments $arguments && return + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + +_swift_build() { + integer ret=1 + local -a args + args+=( + '--package-path[Specify the package path to operate on (default current directory). This changes the working directory before any other operation]:package-path:_files -/' + '--cache-path[Specify the shared cache directory path]:cache-path:_files -/' + '--config-path[Specify the shared configuration directory path]:config-path:_files -/' + '--security-path[Specify the shared security directory path]:security-path:_files -/' + '--scratch-path[Specify a custom scratch directory path (default .build)]:scratch-path:_files -/' + '--enable-dependency-cache[Use a shared cache when fetching dependencies]' + '--disable-dependency-cache[Use a shared cache when fetching dependencies]' + '--enable-build-manifest-caching' + '--disable-build-manifest-caching' + '--manifest-cache[Caching mode of Package.swift manifests (shared: shared cache, local: package'"'"'s build directory, none: disabled]:manifest-cache:' + '(--verbose -v)'{--verbose,-v}'[Increase verbosity to include informational output]' + '(--very-verbose --vv)'{--very-verbose,--vv}'[Increase verbosity to include debug output]' + '--disable-sandbox[Disable using the sandbox when executing subprocesses]' + '--enable-netrc[Load credentials from a .netrc file]' + '--disable-netrc[Load credentials from a .netrc file]' + '--netrc-file[Specify the .netrc file path.]:netrc-file:_files' + '--enable-keychain[Search credentials in macOS keychain]' + '--disable-keychain[Search credentials in macOS keychain]' + '--resolver-fingerprint-checking:resolver-fingerprint-checking:' + '--enable-prefetching' + '--disable-prefetching' + '(--force-resolved-versions --disable-automatic-resolution --only-use-versions-from-resolved-file)'{--force-resolved-versions,--disable-automatic-resolution,--only-use-versions-from-resolved-file}'[Only use versions from the Package.resolved file and fail resolution if it is out-of-date]' + '--skip-update[Skip updating dependencies from their remote during a resolution]' + '--disable-scm-to-registry-transformation[disable source control to registry transformation]' + '--use-registry-identity-for-scm[look up source control dependencies in the registry and use their registry identity when possible to help deduplicate across the two origins]' + '--replace-scm-with-registry[look up source control dependencies in the registry and use the registry to retrieve them instead of source control when possible]' + '(--configuration -c)'{--configuration,-c}'[Build with configuration]:configuration:(debug release)' + '-Xcc[Pass flag through to all C compiler invocations]:Xcc:' + '-Xswiftc[Pass flag through to all Swift compiler invocations]:Xswiftc:' + '-Xlinker[Pass flag through to all linker invocations]:Xlinker:' + '-Xcxx[Pass flag through to all C++ compiler invocations]:Xcxx:' + '--triple:triple:' + '--sdk:sdk:_files -/' + '--toolchain:toolchain:_files -/' + '--sanitize[Turn on runtime checks for erroneous behavior, possible values: address, thread, undefined, scudo]:sanitize:' + '--auto-index-store[Enable or disable indexing-while-building feature]' + '--enable-index-store[Enable or disable indexing-while-building feature]' + '--disable-index-store[Enable or disable indexing-while-building feature]' + '--enable-parseable-module-interfaces' + '(--jobs -j)'{--jobs,-j}'[The number of jobs to spawn in parallel during the build process]:jobs:' + '--emit-swift-module-separately' + '--use-integrated-swift-driver' + '--experimental-explicit-module-build' + '--print-manifest-job-graph[Write the command graph for the build manifest as a graphviz file]' + '--build-system:build-system:(native xcode)' + '--enable-dead-strip[Disable/enable dead code stripping by the linker]' + '--disable-dead-strip[Disable/enable dead code stripping by the linker]' + '--static-swift-stdlib[Link Swift stdlib statically]' + '--no-static-swift-stdlib[Link Swift stdlib statically]' + '--build-tests[Build both source and test targets]' + '--show-bin-path[Print the binary output path]' + '--target[Build the specified target]:target:' + '--product[Build the specified product]:product:' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + +_swift_test() { + integer ret=1 + local -a args + args+=( + '--package-path[Specify the package path to operate on (default current directory). This changes the working directory before any other operation]:package-path:_files -/' + '--cache-path[Specify the shared cache directory path]:cache-path:_files -/' + '--config-path[Specify the shared configuration directory path]:config-path:_files -/' + '--security-path[Specify the shared security directory path]:security-path:_files -/' + '--scratch-path[Specify a custom scratch directory path (default .build)]:scratch-path:_files -/' + '--enable-dependency-cache[Use a shared cache when fetching dependencies]' + '--disable-dependency-cache[Use a shared cache when fetching dependencies]' + '--enable-build-manifest-caching' + '--disable-build-manifest-caching' + '--manifest-cache[Caching mode of Package.swift manifests (shared: shared cache, local: package'"'"'s build directory, none: disabled]:manifest-cache:' + '(--verbose -v)'{--verbose,-v}'[Increase verbosity to include informational output]' + '(--very-verbose --vv)'{--very-verbose,--vv}'[Increase verbosity to include debug output]' + '--disable-sandbox[Disable using the sandbox when executing subprocesses]' + '--enable-netrc[Load credentials from a .netrc file]' + '--disable-netrc[Load credentials from a .netrc file]' + '--netrc-file[Specify the .netrc file path.]:netrc-file:_files' + '--enable-keychain[Search credentials in macOS keychain]' + '--disable-keychain[Search credentials in macOS keychain]' + '--resolver-fingerprint-checking:resolver-fingerprint-checking:' + '--enable-prefetching' + '--disable-prefetching' + '(--force-resolved-versions --disable-automatic-resolution --only-use-versions-from-resolved-file)'{--force-resolved-versions,--disable-automatic-resolution,--only-use-versions-from-resolved-file}'[Only use versions from the Package.resolved file and fail resolution if it is out-of-date]' + '--skip-update[Skip updating dependencies from their remote during a resolution]' + '--disable-scm-to-registry-transformation[disable source control to registry transformation]' + '--use-registry-identity-for-scm[look up source control dependencies in the registry and use their registry identity when possible to help deduplicate across the two origins]' + '--replace-scm-with-registry[look up source control dependencies in the registry and use the registry to retrieve them instead of source control when possible]' + '(--configuration -c)'{--configuration,-c}'[Build with configuration]:configuration:(debug release)' + '-Xcc[Pass flag through to all C compiler invocations]:Xcc:' + '-Xswiftc[Pass flag through to all Swift compiler invocations]:Xswiftc:' + '-Xlinker[Pass flag through to all linker invocations]:Xlinker:' + '-Xcxx[Pass flag through to all C++ compiler invocations]:Xcxx:' + '--triple:triple:' + '--sdk:sdk:_files -/' + '--toolchain:toolchain:_files -/' + '--sanitize[Turn on runtime checks for erroneous behavior, possible values: address, thread, undefined, scudo]:sanitize:' + '--auto-index-store[Enable or disable indexing-while-building feature]' + '--enable-index-store[Enable or disable indexing-while-building feature]' + '--disable-index-store[Enable or disable indexing-while-building feature]' + '--enable-parseable-module-interfaces' + '(--jobs -j)'{--jobs,-j}'[The number of jobs to spawn in parallel during the build process]:jobs:' + '--emit-swift-module-separately' + '--use-integrated-swift-driver' + '--experimental-explicit-module-build' + '--print-manifest-job-graph[Write the command graph for the build manifest as a graphviz file]' + '--build-system:build-system:(native xcode)' + '--enable-dead-strip[Disable/enable dead code stripping by the linker]' + '--disable-dead-strip[Disable/enable dead code stripping by the linker]' + '--static-swift-stdlib[Link Swift stdlib statically]' + '--no-static-swift-stdlib[Link Swift stdlib statically]' + '--skip-build[Skip building the test target]' + '--parallel[Run the tests in parallel.]' + '--num-workers[Number of tests to execute in parallel.]:num-workers:' + '(--list-tests -l)'{--list-tests,-l}'[Lists test methods in specifier format]' + '--show-codecov-path[Print the path of the exported code coverage JSON file]' + '(-s --specifier)'{-s,--specifier}':specifier:' + '--filter[Run test cases matching regular expression, Format: . or ./]:filter:' + '--skip[Skip test cases matching regular expression, Example: --skip PerformanceTests]:skip:' + '--xunit-output[Path where the xUnit xml file should be generated.]:xunit-output:_files -/' + '--test-product[Test the specified product.]:test-product:' + '--enable-testable-imports[Enable or disable testable imports. Enabled by default.]' + '--disable-testable-imports[Enable or disable testable imports. Enabled by default.]' + '--enable-code-coverage[Enable code coverage]' + '--disable-code-coverage[Enable code coverage]' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret } -# Generates completions for swift package -# -# In the final compdef file, set the following file header: -# -# #compdef _swift_package -# local context state state_descr line -# typeset -A opt_args _swift_package() { - arguments=( - "-Xcc[Pass flag through to all C compiler invocations]:Pass flag through to all C compiler invocations: " - "-Xswiftc[Pass flag through to all Swift compiler invocations]:Pass flag through to all Swift compiler invocations: " - "-Xlinker[Pass flag through to all linker invocations]:Pass flag through to all linker invocations: " - "-Xcxx[Pass flag through to all C++ compiler invocations]:Pass flag through to all C++ compiler invocations: " - "(--configuration -c)"{--configuration,-c}"[Build with configuration (debug|release) ]: :{_values '' 'debug[build with DEBUG configuration]' 'release[build with RELEASE configuration]'}" - "--build-path[Specify build/cache directory ]:Specify build/cache directory :_files" - "(--chdir -C)"{--chdir,-C}"[]: :_files" - "--package-path[Change working directory before any other operation]:Change working directory before any other operation:_files" - "--sanitize[Turn on runtime checks for erroneous behavior]: :{_values '' 'address[enable Address sanitizer]' 'thread[enable Thread sanitizer]' 'undefined[enable Undefined Behavior sanitizer]'}" - "--disable-prefetching[]" - "--skip-update[Skip updating dependencies from their remote during a resolution]" - "--disable-sandbox[Disable using the sandbox when executing subprocesses]" - "--disable-package-manifest-caching[Disable caching Package.swift manifests]" - "--version[]" - "--destination[]: :_files" - "(--verbose -v)"{--verbose,-v}"[Increase verbosity of informational output]" - "--no-static-swift-stdlib[Do not link Swift stdlib statically \[default\]]" - "--static-swift-stdlib[Link Swift stdlib statically]" - "--force-resolved-versions[]" - "--disable-automatic-resolution[Disable automatic resolution if Package.resolved file is out-of-date]" - "--enable-index-store[Enable indexing-while-building feature]" - "--disable-index-store[Disable indexing-while-building feature]" - "--enable-pubgrub-resolver[\[Experimental\] Enable the new Pubgrub dependency resolver]" - "--enable-parseable-module-interfaces[]" - "--trace-resolver[]" - "(--jobs -j)"{--jobs,-j}"[The number of jobs to spawn in parallel during the build process]:The number of jobs to spawn in parallel during the build process: " - "--enable-test-discovery[Enable test discovery on platforms without Objective-C runtime]" + integer ret=1 + local -a args + args+=( + '--package-path[Specify the package path to operate on (default current directory). This changes the working directory before any other operation]:package-path:_files -/' + '--cache-path[Specify the shared cache directory path]:cache-path:_files -/' + '--config-path[Specify the shared configuration directory path]:config-path:_files -/' + '--security-path[Specify the shared security directory path]:security-path:_files -/' + '--scratch-path[Specify a custom scratch directory path (default .build)]:scratch-path:_files -/' + '--enable-dependency-cache[Use a shared cache when fetching dependencies]' + '--disable-dependency-cache[Use a shared cache when fetching dependencies]' + '--enable-build-manifest-caching' + '--disable-build-manifest-caching' + '--manifest-cache[Caching mode of Package.swift manifests (shared: shared cache, local: package'"'"'s build directory, none: disabled]:manifest-cache:' + '(--verbose -v)'{--verbose,-v}'[Increase verbosity to include informational output]' + '(--very-verbose --vv)'{--very-verbose,--vv}'[Increase verbosity to include debug output]' + '--disable-sandbox[Disable using the sandbox when executing subprocesses]' + '--enable-netrc[Load credentials from a .netrc file]' + '--disable-netrc[Load credentials from a .netrc file]' + '--netrc-file[Specify the .netrc file path.]:netrc-file:_files' + '--enable-keychain[Search credentials in macOS keychain]' + '--disable-keychain[Search credentials in macOS keychain]' + '--resolver-fingerprint-checking:resolver-fingerprint-checking:' + '--enable-prefetching' + '--disable-prefetching' + '(--force-resolved-versions --disable-automatic-resolution --only-use-versions-from-resolved-file)'{--force-resolved-versions,--disable-automatic-resolution,--only-use-versions-from-resolved-file}'[Only use versions from the Package.resolved file and fail resolution if it is out-of-date]' + '--skip-update[Skip updating dependencies from their remote during a resolution]' + '--disable-scm-to-registry-transformation[disable source control to registry transformation]' + '--use-registry-identity-for-scm[look up source control dependencies in the registry and use their registry identity when possible to help deduplicate across the two origins]' + '--replace-scm-with-registry[look up source control dependencies in the registry and use the registry to retrieve them instead of source control when possible]' + '(--configuration -c)'{--configuration,-c}'[Build with configuration]:configuration:(debug release)' + '-Xcc[Pass flag through to all C compiler invocations]:Xcc:' + '-Xswiftc[Pass flag through to all Swift compiler invocations]:Xswiftc:' + '-Xlinker[Pass flag through to all linker invocations]:Xlinker:' + '-Xcxx[Pass flag through to all C++ compiler invocations]:Xcxx:' + '--triple:triple:' + '--sdk:sdk:_files -/' + '--toolchain:toolchain:_files -/' + '--sanitize[Turn on runtime checks for erroneous behavior, possible values: address, thread, undefined, scudo]:sanitize:' + '--auto-index-store[Enable or disable indexing-while-building feature]' + '--enable-index-store[Enable or disable indexing-while-building feature]' + '--disable-index-store[Enable or disable indexing-while-building feature]' + '--enable-parseable-module-interfaces' + '(--jobs -j)'{--jobs,-j}'[The number of jobs to spawn in parallel during the build process]:jobs:' + '--emit-swift-module-separately' + '--use-integrated-swift-driver' + '--experimental-explicit-module-build' + '--print-manifest-job-graph[Write the command graph for the build manifest as a graphviz file]' + '--build-system:build-system:(native xcode)' + '--enable-dead-strip[Disable/enable dead code stripping by the linker]' + '--disable-dead-strip[Disable/enable dead code stripping by the linker]' + '--static-swift-stdlib[Link Swift stdlib statically]' + '--no-static-swift-stdlib[Link Swift stdlib statically]' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' '(-): :->command' '(-)*:: :->arg' ) - _arguments $arguments && return + _arguments -w -s -S $args[@] && ret=0 case $state in (command) - local modes - modes=( - 'completion-tool:Completion tool (for shell completions)' - 'dump-package:Print parsed Package.swift as JSON' - 'describe:Describe the current package' + local subcommands + subcommands=( 'clean:Delete build artifacts' - 'show-dependencies:Print the resolved dependency graph' - 'init:Initialize a new package' - 'unedit:Remove a package from editable mode' - 'tools-version:Manipulate tools version of the current package' - 'fetch:' - 'resolve:Resolve package dependencies' + 'purge-cache:Purge the global repository cache.' 'reset:Reset the complete cache/build directory' - 'generate-xcodeproj:Generates an Xcode project' - 'edit:Put a package in editable mode' - 'config:Manipulate configuration of the package' 'update:Update package dependencies' + 'describe:Describe the current package' + 'init:Initialize a new package' + '_format:' + 'diagnose-api-breaking-changes:Diagnose API-breaking changes to Swift modules in a package' + 'experimental-api-diff:Deprecated - use `swift package diagnose-api-breaking-changes` instead' + 'dump-symbol-graph:Dump Symbol Graph' + 'dump-pif:' + 'dump-package:Print parsed Package.swift as JSON' + 'edit:Put a package in editable mode' + 'unedit:Remove a package from editable mode' + 'config:Manipulate configuration of the package' + 'resolve:Resolve package dependencies' + 'fetch:' + 'show-dependencies:Print the resolved dependency graph' + 'tools-version:Manipulate tools version of the current package' + 'generate-xcodeproj:Generates an Xcode project. This command will be deprecated soon.' + 'compute-checksum:Compute the checksum for a binary artifact.' + 'archive-source:Create a source archive for the package' + 'completion-tool:Completion tool (for shell completions)' + 'plugin:Invoke a command plugin or perform other actions on command plugins' + 'default-command:' ) - _describe "mode" modes + _describe "subcommand" subcommands ;; (arg) case ${words[1]} in - (completion-tool) - _swift_package_completion-tool - ;; - (dump-package) - _swift_package_dump-package - ;; - (describe) - _swift_package_describe - ;; (clean) _swift_package_clean ;; - (show-dependencies) - _swift_package_show-dependencies - ;; - (init) - _swift_package_init - ;; - (unedit) - _swift_package_unedit - ;; - (tools-version) - _swift_package_tools-version - ;; - (fetch) - _swift_package_fetch - ;; - (resolve) - _swift_package_resolve + (purge-cache) + _swift_package_purge-cache ;; (reset) _swift_package_reset ;; - (generate-xcodeproj) - _swift_package_generate-xcodeproj + (update) + _swift_package_update + ;; + (describe) + _swift_package_describe + ;; + (init) + _swift_package_init + ;; + (_format) + _swift_package__format + ;; + (diagnose-api-breaking-changes) + _swift_package_diagnose-api-breaking-changes + ;; + (experimental-api-diff) + _swift_package_experimental-api-diff + ;; + (dump-symbol-graph) + _swift_package_dump-symbol-graph + ;; + (dump-pif) + _swift_package_dump-pif + ;; + (dump-package) + _swift_package_dump-package ;; (edit) _swift_package_edit ;; + (unedit) + _swift_package_unedit + ;; (config) _swift_package_config ;; - (update) - _swift_package_update + (resolve) + _swift_package_resolve + ;; + (fetch) + _swift_package_fetch + ;; + (show-dependencies) + _swift_package_show-dependencies + ;; + (tools-version) + _swift_package_tools-version + ;; + (generate-xcodeproj) + _swift_package_generate-xcodeproj + ;; + (compute-checksum) + _swift_package_compute-checksum + ;; + (archive-source) + _swift_package_archive-source + ;; + (completion-tool) + _swift_package_completion-tool + ;; + (plugin) + _swift_package_plugin + ;; + (default-command) + _swift_package_default-command ;; esac ;; esac -} -_swift_package_completion-tool() { - arguments=( - ": :{_values '' 'generate-bash-script[generate Bash completion script]' 'generate-zsh-script[generate Bash completion script]' 'list-dependencies[list all dependencies' names]' 'list-executables[list all executables' names]'}" - ) - _arguments $arguments && return -} - -_swift_package_dump-package() { - arguments=( - ) - _arguments $arguments && return -} - -_swift_package_describe() { - arguments=( - "--type[json|text]: :{_values '' 'text[describe using text format]' 'json[describe using JSON format]'}" - ) - _arguments $arguments && return + return ret } _swift_package_clean() { - arguments=( + integer ret=1 + local -a args + args+=( + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' ) - _arguments $arguments && return + _arguments -w -s -S $args[@] && ret=0 + + return ret } -_swift_package_show-dependencies() { - arguments=( - "--format[text|dot|json|flatlist]: :{_values '' 'text[list dependencies using text format]' 'dot[list dependencies using dot format]' 'json[list dependencies using JSON format]'}" +_swift_package_purge-cache() { + integer ret=1 + local -a args + args+=( + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' ) - _arguments $arguments && return -} + _arguments -w -s -S $args[@] && ret=0 -_swift_package_init() { - arguments=( - "--type[empty|library|executable|system-module|manifest]: :{_values '' 'empty[generates an empty project]' 'library[generates project for a dynamic library]' 'executable[generates a project for a cli executable]' 'system-module[generates a project for a system module]'}" - "--name[Provide custom package name]:Provide custom package name: " - ) - _arguments $arguments && return -} - -_swift_package_unedit() { - arguments=( - ":The name of the package to unedit:_swift_dependency" - "--force[Unedit the package even if it has uncommited and unpushed changes.]" - ) - _arguments $arguments && return -} - -_swift_package_tools-version() { - arguments=( - "--set[Set tools version of package to the given value]:Set tools version of package to the given value: " - "--set-current[Set tools version of package to the current tools version in use]" - ) - _arguments $arguments && return -} - -_swift_package_fetch() { - arguments=( - ) - _arguments $arguments && return -} - -_swift_package_resolve() { - arguments=( - ":The name of the package to resolve:_swift_dependency" - "--version[The version to resolve at]:The version to resolve at: " - "--branch[The branch to resolve at]:The branch to resolve at: " - "--revision[The revision to resolve at]:The revision to resolve at: " - ) - _arguments $arguments && return + return ret } _swift_package_reset() { - arguments=( + integer ret=1 + local -a args + args+=( + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' ) - _arguments $arguments && return + _arguments -w -s -S $args[@] && ret=0 + + return ret } -_swift_package_generate-xcodeproj() { - arguments=( - "--xcconfig-overrides[Path to xcconfig file]:Path to xcconfig file:_files" - "--enable-code-coverage[Enable code coverage in the generated project]" - "--output[Path where the Xcode project should be generated]:Path where the Xcode project should be generated:_files" - "--legacy-scheme-generator[Use the legacy scheme generator]" - "--watch[Watch for changes to the Package manifest to regenerate the Xcode project]" - "--skip-extra-files[Do not add file references for extra files to the generated Xcode project]" +_swift_package_update() { + integer ret=1 + local -a args + args+=( + '(--dry-run -n)'{--dry-run,-n}'[Display the list of dependencies that can be updated]' + ':packages:' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' ) - _arguments $arguments && return + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + +_swift_package_describe() { + integer ret=1 + local -a args + args+=( + '--type[json | text]:type:' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + +_swift_package_init() { + integer ret=1 + local -a args + args+=( + '--type[Package type: empty | library | executable | system-module | manifest]:type:' + '--name[Provide custom package name]:name:' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + +_swift_package__format() { + integer ret=1 + local -a args + args+=( + ':swift-format-flags:' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + +_swift_package_diagnose-api-breaking-changes() { + integer ret=1 + local -a args + args+=( + '--breakage-allowlist-path[The path to a text file containing breaking changes which should be ignored by the API comparison. Each ignored breaking change in the file should appear on its own line and contain the exact message to be ignored (e.g. '"'"'API breakage: func foo() has been removed'"'"').]:breakage-allowlist-path:_files -/' + ':treeish:' + '--products[One or more products to include in the API comparison. If present, only the specified products (and any targets specified using `--targets`) will be compared.]:products:' + '--targets[One or more targets to include in the API comparison. If present, only the specified targets (and any products specified using `--products`) will be compared.]:targets:' + '--baseline-dir[The path to a directory used to store API baseline files. If unspecified, a temporary directory will be used.]:baseline-dir:_files -/' + '--regenerate-baseline[Regenerate the API baseline, even if an existing one is available.]' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + +_swift_package_experimental-api-diff() { + integer ret=1 + local -a args + args+=( + ':args:' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + +_swift_package_dump-symbol-graph() { + integer ret=1 + local -a args + args+=( + '--pretty-print[Pretty-print the output JSON.]' + '--skip-synthesized-members[Skip members inherited through classes or default implementations.]' + '--minimum-access-level[Include symbols with this access level or more. Possible values: private | fileprivate | internal | public | open]:minimum-access-level:(private fileprivate internal public open)' + '--skip-inherited-docs[Skip emitting doc comments for members inherited through classes or default implementations.]' + '--include-spi-symbols[Add symbols with SPI information to the symbol graph.]' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + +_swift_package_dump-pif() { + integer ret=1 + local -a args + args+=( + '--preserve-structure[Preserve the internal structure of PIF]' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + +_swift_package_dump-package() { + integer ret=1 + local -a args + args+=( + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret } _swift_package_edit() { - arguments=( - ":The name of the package to edit:_swift_dependency" - "--revision[The revision to edit]:The revision to edit: " - "--branch[The branch to create]:The branch to create: " - "--path[Create or use the checkout at this path]:Create or use the checkout at this path:_files" + integer ret=1 + local -a args + args+=( + '--revision[The revision to edit]:revision:' + '--branch[The branch to create]:branch:' + '--path[Create or use the checkout at this path]:path:_files -/' + ':package-name:' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' ) - _arguments $arguments && return + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + +_swift_package_unedit() { + integer ret=1 + local -a args + args+=( + '--force[Unedit the package even if it has uncommitted and unpushed changes]' + ':package-name:' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret } _swift_package_config() { - arguments=( + integer ret=1 + local -a args + args+=( + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' '(-): :->command' '(-)*:: :->arg' ) - _arguments $arguments && return + _arguments -w -s -S $args[@] && ret=0 case $state in (command) - local modes - modes=( + local subcommands + subcommands=( + 'set-mirror:Set a mirror for a dependency' 'unset-mirror:Remove an existing mirror' 'get-mirror:Print mirror configuration for the given package dependency' - 'set-mirror:Set a mirror for a dependency' ) - _describe "mode" modes + _describe "subcommand" subcommands ;; (arg) case ${words[1]} in + (set-mirror) + _swift_package_config_set-mirror + ;; (unset-mirror) _swift_package_config_unset-mirror ;; (get-mirror) _swift_package_config_get-mirror ;; - (set-mirror) - _swift_package_config_set-mirror - ;; esac ;; esac -} -_swift_package_config_unset-mirror() { - arguments=( - "--package-url[The package dependency url]:The package dependency url: " - "--mirror-url[The mirror url]:The mirror url: " - ) - _arguments $arguments && return -} - -_swift_package_config_get-mirror() { - arguments=( - "--package-url[The package dependency url]:The package dependency url: " - ) - _arguments $arguments && return + return ret } _swift_package_config_set-mirror() { - arguments=( - "--package-url[The package dependency url]:The package dependency url: " - "--mirror-url[The mirror url]:The mirror url: " + integer ret=1 + local -a args + args+=( + '--package-url[The package dependency url]:package-url:' + '--original-url[The original url]:original-url:' + '--mirror-url[The mirror url]:mirror-url:' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' ) - _arguments $arguments && return + _arguments -w -s -S $args[@] && ret=0 + + return ret } -_swift_package_update() { - arguments=( +_swift_package_config_unset-mirror() { + integer ret=1 + local -a args + args+=( + '--package-url[The package dependency url]:package-url:' + '--original-url[The original url]:original-url:' + '--mirror-url[The mirror url]:mirror-url:' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' ) - _arguments $arguments && return + _arguments -w -s -S $args[@] && ret=0 + + return ret } -# Generates completions for swift test -# -# In the final compdef file, set the following file header: -# -# #compdef _swift_test -# local context state state_descr line -# typeset -A opt_args -_swift_test() { - arguments=( - "-Xcc[Pass flag through to all C compiler invocations]:Pass flag through to all C compiler invocations: " - "-Xswiftc[Pass flag through to all Swift compiler invocations]:Pass flag through to all Swift compiler invocations: " - "-Xlinker[Pass flag through to all linker invocations]:Pass flag through to all linker invocations: " - "-Xcxx[Pass flag through to all C++ compiler invocations]:Pass flag through to all C++ compiler invocations: " - "(--configuration -c)"{--configuration,-c}"[Build with configuration (debug|release) ]: :{_values '' 'debug[build with DEBUG configuration]' 'release[build with RELEASE configuration]'}" - "--build-path[Specify build/cache directory ]:Specify build/cache directory :_files" - "(--chdir -C)"{--chdir,-C}"[]: :_files" - "--package-path[Change working directory before any other operation]:Change working directory before any other operation:_files" - "--sanitize[Turn on runtime checks for erroneous behavior]: :{_values '' 'address[enable Address sanitizer]' 'thread[enable Thread sanitizer]' 'undefined[enable Undefined Behavior sanitizer]'}" - "--disable-prefetching[]" - "--skip-update[Skip updating dependencies from their remote during a resolution]" - "--disable-sandbox[Disable using the sandbox when executing subprocesses]" - "--disable-package-manifest-caching[Disable caching Package.swift manifests]" - "--version[]" - "--destination[]: :_files" - "(--verbose -v)"{--verbose,-v}"[Increase verbosity of informational output]" - "--no-static-swift-stdlib[Do not link Swift stdlib statically \[default\]]" - "--static-swift-stdlib[Link Swift stdlib statically]" - "--force-resolved-versions[]" - "--disable-automatic-resolution[Disable automatic resolution if Package.resolved file is out-of-date]" - "--enable-index-store[Enable indexing-while-building feature]" - "--disable-index-store[Disable indexing-while-building feature]" - "--enable-pubgrub-resolver[\[Experimental\] Enable the new Pubgrub dependency resolver]" - "--enable-parseable-module-interfaces[]" - "--trace-resolver[]" - "(--jobs -j)"{--jobs,-j}"[The number of jobs to spawn in parallel during the build process]:The number of jobs to spawn in parallel during the build process: " - "--enable-test-discovery[Enable test discovery on platforms without Objective-C runtime]" - "--skip-build[Skip building the test target]" - "(--list-tests -l)"{--list-tests,-l}"[Lists test methods in specifier format]" - "--generate-linuxmain[Generate LinuxMain.swift entries for the package]" - "--parallel[Run the tests in parallel.]" - "--num-workers[Number of tests to execute in parallel.]:Number of tests to execute in parallel.: " - "(--specifier -s)"{--specifier,-s}"[]: : " - "--xunit-output[]: :_files" - "--filter[Run test cases matching regular expression, Format: . or ./]:Run test cases matching regular expression, Format: . or ./: " - "--enable-code-coverage[Test with code coverage enabled]" +_swift_package_config_get-mirror() { + integer ret=1 + local -a args + args+=( + '--package-url[The package dependency url]:package-url:' + '--original-url[The original url]:original-url:' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' ) - _arguments $arguments && return + _arguments -w -s -S $args[@] && ret=0 + + return ret } -_swift_compiler() { +_swift_package_resolve() { + integer ret=1 + local -a args + args+=( + '--version[The version to resolve at]:version:' + '--branch[The branch to resolve at]:branch:' + '--revision[The revision to resolve at]:revision:' + ':package-name:' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + +_swift_package_fetch() { + integer ret=1 + local -a args + args+=( + '--version[The version to resolve at]:version:' + '--branch[The branch to resolve at]:branch:' + '--revision[The revision to resolve at]:revision:' + ':package-name:' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + +_swift_package_show-dependencies() { + integer ret=1 + local -a args + args+=( + '--format[text | dot | json | flatlist]:format:' + '(--output-path -o)'{--output-path,-o}'[The absolute or relative path to output the resolved dependency graph.]:output-path:_files -/' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + +_swift_package_tools-version() { + integer ret=1 + local -a args + args+=( + '--set-current[Set tools version of package to the current tools version in use]' + '--set[Set tools version of package to the given value]:set:' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + +_swift_package_generate-xcodeproj() { + integer ret=1 + local -a args + args+=( + '--xcconfig-overrides[Path to xcconfig file]:xcconfig-overrides:_files' + '--output[Path where the Xcode project should be generated]:output:_files -/' + '--legacy-scheme-generator[Use the legacy scheme generator]' + '--watch[Watch for changes to the Package manifest to regenerate the Xcode project]' + '--skip-extra-files[Do not add file references for extra files to the generated Xcode project]' + '--enable-code-coverage[Enable code coverage]' + '--disable-code-coverage[Enable code coverage]' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + +_swift_package_compute-checksum() { + integer ret=1 + local -a args + args+=( + ':path:_files -/' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + +_swift_package_archive-source() { + integer ret=1 + local -a args + args+=( + '(-o --output)'{-o,--output}'[The absolute or relative path for the generated source archive]:output:_files -/' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + +_swift_package_completion-tool() { + integer ret=1 + local -a args + args+=( + ':mode:(generate-bash-script generate-zsh-script generate-fish-script list-dependencies list-executables list-snippets)' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + +_swift_package_plugin() { + integer ret=1 + local -a args + args+=( + '--list[List the available command plugins]' + '--allow-writing-to-package-directory[Allow the plugin to write to the package directory]' + '--allow-writing-to-directory[Allow the plugin to write to an additional directory]:allow-writing-to-directory:' + ':command:' + ':arguments:' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + +_swift_package_default-command() { + integer ret=1 + local -a args + args+=( + '--allow-writing-to-package-directory[Allow the plugin to write to the package directory]' + '--allow-writing-to-directory[Allow the plugin to write to an additional directory]:allow-writing-to-directory:' + ':remaining:' + '--version[Show the version.]' + '(-help -h --help)'{-help,-h,--help}'[Show help information.]' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + +_swift_help() { + integer ret=1 + local -a args + args+=( + ':subcommands:' + ) + _arguments -w -s -S $args[@] && ret=0 + + return ret +} + + +_custom_completion() { + local completions=("${(@f)$($*)}") + _describe '' completions } _swift diff --git a/plugins/systemadmin/README.md b/plugins/systemadmin/README.md index 146b58605..3a9d9de66 100644 --- a/plugins/systemadmin/README.md +++ b/plugins/systemadmin/README.md @@ -41,7 +41,7 @@ plugins=(... systemadmin) | accessip10 | List the top 10 accesses to the ip address in the nginx/access.log file or another log file if specified | | visitpage20 | List the top 20 most visited files or pages in the nginx/access.log file or another log file if specified | | consume100 | List the 100 most time-consuming Page lists (more than 60 seconds) as well as the corresponding number of occurrences | -| webtraffic | List website traffic statistics in GB from tne nginx/access.log file or another log file if specified | +| webtraffic | List website traffic statistics in GB from the nginx/access.log file or another log file if specified | | c404 | List statistics on 404 connections in the nginx/access.log file or another log file if specified | | httpstatus | List statistics based on http status in the nginx/access.log file or another log file if specified | | d0 | Delete 0 byte files recursively in the current directory or another if specified | diff --git a/plugins/systemadmin/systemadmin.plugin.zsh b/plugins/systemadmin/systemadmin.plugin.zsh index 8e5e0af71..7ce62bac1 100644 --- a/plugins/systemadmin/systemadmin.plugin.zsh +++ b/plugins/systemadmin/systemadmin.plugin.zsh @@ -33,6 +33,14 @@ alias pscpu10='ps -e -o pcpu,cpu,nice,state,cputime,args|sort -k1,1n -nr | head # top10 of the history alias hist10='print -l ${(o)history%% *} | uniq -c | sort -nr | head -n 10' +function ip() { + if [ -t 1 ]; then + command ip -color "$@" + else + command ip "$@" + fi +} + # directory LS function dls() { print -l *(/) @@ -132,7 +140,13 @@ function d0() { # gather external ip address function geteip() { curl -s -S -4 https://icanhazip.com - curl -s -S -6 https://icanhazip.com + + # handle case when there is no IPv6 external IP, which shows error + # curl: (7) Couldn't connect to server + curl -s -S -6 https://icanhazip.com 2>/dev/null + local ret=$? + (( ret == 7 )) && print -P -u2 "%F{red}error: no IPv6 route to host%f" + return $ret } # determine local IP address(es) diff --git a/plugins/systemd/systemd.plugin.zsh b/plugins/systemd/systemd.plugin.zsh index 7afd2be58..1270bea0e 100644 --- a/plugins/systemd/systemd.plugin.zsh +++ b/plugins/systemd/systemd.plugin.zsh @@ -107,6 +107,8 @@ function systemd_prompt_info { if systemctl is-active "$unit" &>/dev/null; then echo -n "$ZSH_THEME_SYSTEMD_PROMPT_ACTIVE" + elif systemctl --user is-active "$unit" &>/dev/null; then + echo -n "$ZSH_THEME_SYSTEMD_PROMPT_ACTIVE" else echo -n "$ZSH_THEME_SYSTEMD_PROMPT_NOTACTIVE" fi diff --git a/plugins/term_tab/README b/plugins/term_tab/README deleted file mode 100644 index 316062e73..000000000 --- a/plugins/term_tab/README +++ /dev/null @@ -1,16 +0,0 @@ - -term_tab - 'cwd' for all open zsh sessions -****************************************** - -What it does: -************* -This plugin allows to complete the 'cwd' of other Zsh sessions. Sounds -complicated but is rather simple. E.g. if you have three zsh sessions open, in -each session you are in a different folder, you can hit Ctrl+v in one session -to show you the current working directory of the other open zsh sessions. - -How it works: -************* -* It uses 'pidof zsh' to determine all zsh PIDs -* It reads procfs to get the current working directory of this session -* Everything is fed into zsh's completion magic diff --git a/plugins/term_tab/README.md b/plugins/term_tab/README.md new file mode 100644 index 000000000..59462a825 --- /dev/null +++ b/plugins/term_tab/README.md @@ -0,0 +1,18 @@ +# term_tab plugin + +This plugin only works for Solaris and linux. + +term_tab - `cwd` for all open zsh sessions + +## What it does: + +This plugin allows to complete the `cwd` of other Zsh sessions. Sounds +complicated but is rather simple. E.g. if you have three zsh sessions open, in +each session you are in a different folder, you can hit `Ctrl+V` in one session +to show you the current working directory of the other open zsh sessions. + +## How it works: + +* It uses `pidof zsh` to determine all zsh PIDs +* It reads procfs to get the current working directory of this session +* Everything is fed into zsh's completion magic diff --git a/plugins/term_tab/term_tab.plugin.zsh b/plugins/term_tab/term_tab.plugin.zsh index 1b612df68..89acd9103 100644 --- a/plugins/term_tab/term_tab.plugin.zsh +++ b/plugins/term_tab/term_tab.plugin.zsh @@ -28,6 +28,7 @@ function _term_list(){ case $OSTYPE in solaris*) dirs=( ${(M)${${(f)"$(pgrep -U $UID -x zsh|xargs pwdx)"}:#$$:*}%%/*} ) ;; linux*) dirs=( /proc/${^$(pidof zsh):#$$}/cwd(N:A) ) ;; + darwin*) dirs=( $( lsof -d cwd -c zsh -a -w -Fn | sed -n 's/^n//p' ) ) ;; esac dirs=( ${(D)dirs} ) diff --git a/plugins/terraform/README.md b/plugins/terraform/README.md index 59c6e7f2a..c19f2ad1c 100644 --- a/plugins/terraform/README.md +++ b/plugins/terraform/README.md @@ -19,6 +19,7 @@ plugins=(... terraform) | ----- | -------------------- | | `tf` | `terraform` | | `tfa` | `terraform apply` | +| `tfc` | `terraform console` | | `tfd` | `terraform destroy` | | `tff` | `terraform fmt` | | `tfi` | `terraform init` | diff --git a/plugins/terraform/_terraform b/plugins/terraform/_terraform index a19e50670..625834563 100644 --- a/plugins/terraform/_terraform +++ b/plugins/terraform/_terraform @@ -47,7 +47,7 @@ __apply() { '-lock=[(true) Lock the state file when locking is supported.]:lock:(true false)' \ '-lock-timeout=[(0s) Duration to retry a state lock.]' \ '-input=[(true) Ask for input for variables if not directly set.]' \ - '-no-color[If specified, output wil be colorless.]' \ + '-no-color[If specified, output will be colorless.]' \ '-parallelism=[(10) Limit the number of parallel resource operations.]' \ '-refresh=[(true) Update state prior to checking for differences. This has no effect if a plan file is given to apply.]' \ '-state=[(terraform.tfstate) Path to read and save state (unless state-out is specified).]:statefile:_files -g "*.tfstate"' \ diff --git a/plugins/terraform/terraform.plugin.zsh b/plugins/terraform/terraform.plugin.zsh index d9e39e6ac..7006f204b 100644 --- a/plugins/terraform/terraform.plugin.zsh +++ b/plugins/terraform/terraform.plugin.zsh @@ -10,6 +10,7 @@ function tf_prompt_info() { alias tf='terraform' alias tfa='terraform apply' +alias tfc='terraform console' alias tfd='terraform destroy' alias tff='terraform fmt' alias tfi='terraform init' diff --git a/plugins/tmux/tmux.plugin.zsh b/plugins/tmux/tmux.plugin.zsh index b9bb66d59..311c2e6a9 100644 --- a/plugins/tmux/tmux.plugin.zsh +++ b/plugins/tmux/tmux.plugin.zsh @@ -73,7 +73,11 @@ function _zsh_tmux_plugin_run() { [[ "$ZSH_TMUX_UNICODE" == "true" ]] && tmux_cmd+=(-u) # Try to connect to an existing session. - [[ "$ZSH_TMUX_AUTOCONNECT" == "true" ]] && $tmux_cmd attach + if [[ -n "$ZSH_TMUX_DEFAULT_SESSION_NAME" ]]; then + [[ "$ZSH_TMUX_AUTOCONNECT" == "true" ]] && $tmux_cmd attach -t $ZSH_TMUX_DEFAULT_SESSION_NAME + else + [[ "$ZSH_TMUX_AUTOCONNECT" == "true" ]] && $tmux_cmd attach + fi # If failed, just run tmux, fixing the TERM variable if requested. if [[ $? -ne 0 ]]; then @@ -83,9 +87,9 @@ function _zsh_tmux_plugin_run() { tmux_cmd+=(-f "$ZSH_TMUX_CONFIG") fi if [[ -n "$ZSH_TMUX_DEFAULT_SESSION_NAME" ]]; then - $tmux_cmd new-session -s $ZSH_TMUX_DEFAULT_SESSION_NAME + $tmux_cmd new-session -s $ZSH_TMUX_DEFAULT_SESSION_NAME else - $tmux_cmd new-session + $tmux_cmd new-session fi fi diff --git a/plugins/toolbox/README.md b/plugins/toolbox/README.md index aac2bb3b0..bc04a906b 100644 --- a/plugins/toolbox/README.md +++ b/plugins/toolbox/README.md @@ -17,3 +17,10 @@ You can use it by adding `$(toolbox_prompt_info)` to your `PROMPT` or `RPROMPT` ```zsh RPROMPT='$(toolbox_prompt_info)' ``` + +## Aliases + +| Alias | Command | Description | +|-------|----------------------|----------------------------------------| +| tbe | `toolbox enter` | Enters the toolbox environment | +| tbr | `toolbox run` | Run a command in an existing toolbox | diff --git a/plugins/toolbox/kubectx.plugin.zsh b/plugins/toolbox/toolbox.plugin.zsh similarity index 60% rename from plugins/toolbox/kubectx.plugin.zsh rename to plugins/toolbox/toolbox.plugin.zsh index 8b6bf5ecd..377e498cd 100644 --- a/plugins/toolbox/kubectx.plugin.zsh +++ b/plugins/toolbox/toolbox.plugin.zsh @@ -1,3 +1,6 @@ function toolbox_prompt_info() { [[ -f /run/.toolboxenv ]] && echo "⬢" } + +alias tbe="toolbox enter" +alias tbr="toolbox run" diff --git a/plugins/ubuntu/README.md b/plugins/ubuntu/README.md index 20f5c65ee..2401c102b 100644 --- a/plugins/ubuntu/README.md +++ b/plugins/ubuntu/README.md @@ -15,7 +15,7 @@ Commands that use `$APT` will use `apt` if installed or defer to `apt-get` other | Alias | Command | Description | |---------|--------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------| | age | `sudo $APT` | Run apt-get with sudo | -| acs | `apt-cache search` | Search the apt-cache with the specified criteria | +| acse | `apt-cache search` | Search the apt-cache with the specified criteria | | acsp | `apt-cache showpkg` | Shows information about the listed packages | | acp | `apt-cache policy` | Display the package source priorities | | afs | `apt-file search --regexp` | Perform a regular expression apt-file search | diff --git a/plugins/ubuntu/ubuntu.plugin.zsh b/plugins/ubuntu/ubuntu.plugin.zsh index 7b765a406..4d35da2ac 100644 --- a/plugins/ubuntu/ubuntu.plugin.zsh +++ b/plugins/ubuntu/ubuntu.plugin.zsh @@ -1,6 +1,6 @@ (( $+commands[apt] )) && APT=apt || APT=apt-get -alias acs='apt-cache search' +alias acse='apt-cache search' alias afs='apt-file search --regexp' diff --git a/plugins/vi-mode/README.md b/plugins/vi-mode/README.md index 476666bf6..0cb516751 100644 --- a/plugins/vi-mode/README.md +++ b/plugins/vi-mode/README.md @@ -29,6 +29,8 @@ plugins=(... vi-mode) VI_MODE_SET_CURSOR=true ``` + See [Cursor Styles](#cursor-styles) for controlling how the cursor looks in different modes + - `MODE_INDICATOR`: controls the string displayed when the shell is in normal mode. See [Mode indicators](#mode-indicators) for details. @@ -49,8 +51,42 @@ MODE_INDICATOR="%F{white}+%f" INSERT_MODE_INDICATOR="%F{yellow}+%f" ``` -You can also use the `vi_mode_prompt_info` function in your prompt, which will display -this mode indicator. +### Adding mode indicators to your prompt + +`Vi-mode` by default will add mode indicators to `RPROMPT` **unless** that is defined by +a preceding plugin. + +If `PROMPT` or `RPROMPT` is not defined to your liking, you can add mode info manually. The `vi_mode_prompt_info` function is available to insert mode indicator information. + +Here are some examples: + +```bash +source $ZSH/oh-my-zsh.sh + +PROMPT="$PROMPT\$(vi_mode_prompt_info)" +RPROMPT="\$(vi_mode_prompt_info)$RPROMPT" +``` + +Note the `\$` here, which importantly prevents interpolation at the time of defining, but allows it to be executed for each prompt update event. + +## Cursor Styles + +You can control the cursor style used in each active vim mode by changing the values of the following variables. + +```zsh +# defaults +VI_MODE_CURSOR_NORMAL=2 +VI_MODE_CURSOR_VISUAL=6 +VI_MODE_CURSOR_INSERT=6 +VI_MODE_CURSOR_OPPEND=0 +``` + +- 0, 1 - Blinking block +- 2 - Solid block +- 3 - Blinking underline +- 4 - Solid underline +- 5 - Blinking line +- 6 - Solid line ## Key bindings diff --git a/plugins/vi-mode/vi-mode.plugin.zsh b/plugins/vi-mode/vi-mode.plugin.zsh index 149d6bbd5..cc9817a74 100644 --- a/plugins/vi-mode/vi-mode.plugin.zsh +++ b/plugins/vi-mode/vi-mode.plugin.zsh @@ -14,6 +14,15 @@ typeset -g VI_MODE_RESET_PROMPT_ON_MODE_CHANGE # Unset or set to any other value to do the opposite. typeset -g VI_MODE_SET_CURSOR +# Control how the cursor appears in the various vim modes. This only applies +# if $VI_MODE_SET_CURSOR=true. +# +# See https://vt100.net/docs/vt510-rm/DECSCUSR for cursor styles +typeset -g VI_MODE_CURSOR_NORMAL=2 +typeset -g VI_MODE_CURSOR_VISUAL=6 +typeset -g VI_MODE_CURSOR_INSERT=6 +typeset -g VI_MODE_CURSOR_OPPEND=0 + typeset -g VI_KEYMAP=main function _vi-mode-set-cursor-shape-for-keymap() { @@ -22,24 +31,44 @@ function _vi-mode-set-cursor-shape-for-keymap() { # https://vt100.net/docs/vt510-rm/DECSCUSR local _shape=0 case "${1:-${VI_KEYMAP:-main}}" in - main) _shape=6 ;; # vi insert: line - viins) _shape=6 ;; # vi insert: line - isearch) _shape=6 ;; # inc search: line - command) _shape=6 ;; # read a command name - vicmd) _shape=2 ;; # vi cmd: block - visual) _shape=2 ;; # vi visual mode: block - viopp) _shape=0 ;; # vi operation pending: blinking block + main) _shape=$VI_MODE_CURSOR_INSERT ;; # vi insert: line + viins) _shape=$VI_MODE_CURSOR_INSERT ;; # vi insert: line + isearch) _shape=$VI_MODE_CURSOR_INSERT ;; # inc search: line + command) _shape=$VI_MODE_CURSOR_INSERT ;; # read a command name + vicmd) _shape=$VI_MODE_CURSOR_NORMAL ;; # vi cmd: block + visual) _shape=$VI_MODE_CURSOR_VISUAL ;; # vi visual mode: block + viopp) _shape=$VI_MODE_CURSOR_OPPEND ;; # vi operation pending: blinking block *) _shape=0 ;; esac printf $'\e[%d q' "${_shape}" } +function _visual-mode { + typeset -g VI_KEYMAP=visual + _vi-mode-set-cursor-shape-for-keymap "$VI_KEYMAP" + zle .visual-mode +} +zle -N visual-mode _visual-mode + +function _vi-mode-should-reset-prompt() { + # If $VI_MODE_RESET_PROMPT_ON_MODE_CHANGE is unset (default), dynamically + # check whether we're using the prompt to display vi-mode info + if [[ -z "${VI_MODE_RESET_PROMPT_ON_MODE_CHANGE:-}" ]]; then + [[ "${PS1} ${RPS1}" = *'$(vi_mode_prompt_info)'* ]] + return $? + fi + + # If $VI_MODE_RESET_PROMPT_ON_MODE_CHANGE was manually set, let's check + # if it was specifically set to true or it was disabled with any other value + [[ "${VI_MODE_RESET_PROMPT_ON_MODE_CHANGE}" = true ]] +} + # Updates editor information when the keymap changes. function zle-keymap-select() { # update keymap variable for the prompt typeset -g VI_KEYMAP=$KEYMAP - if [[ "${VI_MODE_RESET_PROMPT_ON_MODE_CHANGE:-}" = true ]]; then + if _vi-mode-should-reset-prompt; then zle reset-prompt zle -R fi @@ -50,10 +79,9 @@ zle -N zle-keymap-select # These "echoti" statements were originally set in lib/key-bindings.zsh # Not sure the best way to extend without overriding. function zle-line-init() { - local prev_vi_keymap - prev_vi_keymap="${VI_KEYMAP:-}" + local prev_vi_keymap="${VI_KEYMAP:-}" typeset -g VI_KEYMAP=main - [[ "$prev_vi_keymap" != 'main' ]] && [[ "${VI_MODE_RESET_PROMPT_ON_MODE_CHANGE:-}" = true ]] && zle reset-prompt + [[ "$prev_vi_keymap" != 'main' ]] && _vi-mode-should-reset-prompt && zle reset-prompt (( ! ${+terminfo[smkx]} )) || echoti smkx _vi-mode-set-cursor-shape-for-keymap "${VI_KEYMAP}" } @@ -129,13 +157,6 @@ if [[ -z "$MODE_INDICATOR" ]]; then fi function vi_mode_prompt_info() { - # If we're using the prompt to display mode info, and we haven't explicitly - # disabled "reset prompt on mode change", then set it here. - # - # We do that here instead of the `if` statement below because the user may - # set RPS1/RPROMPT to something else in their custom config. - : "${VI_MODE_RESET_PROMPT_ON_MODE_CHANGE:=true}" - echo "${${VI_KEYMAP/vicmd/$MODE_INDICATOR}/(main|viins)/$INSERT_MODE_INDICATOR}" } diff --git a/plugins/watson/README.md b/plugins/watson/README.md new file mode 100644 index 000000000..ef734ec63 --- /dev/null +++ b/plugins/watson/README.md @@ -0,0 +1,9 @@ +# Watson + +This plugin provides completion for [Watson](https://tailordev.github.io/Watson/). + +To use it add `watson` to the plugins array in your zshrc file. + +```zsh +plugins=(... watson) +``` diff --git a/plugins/watson/_watson b/plugins/watson/_watson new file mode 100644 index 000000000..0f599bd66 --- /dev/null +++ b/plugins/watson/_watson @@ -0,0 +1,34 @@ +#compdef watson + +_watson_completion() { + local -a completions + local -a completions_with_descriptions + local -a response + (( ! $+commands[watson] )) && return 1 + + response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) _WATSON_COMPLETE=zsh_complete watson)}") + + for type key descr in ${response}; do + if [[ "$type" == "plain" ]]; then + if [[ "$descr" == "_" ]]; then + completions+=("$key") + else + completions_with_descriptions+=("$key":"$descr") + fi + elif [[ "$type" == "dir" ]]; then + _path_files -/ + elif [[ "$type" == "file" ]]; then + _path_files -f + fi + done + + if [ -n "$completions_with_descriptions" ]; then + _describe -V unsorted completions_with_descriptions -U + fi + + if [ -n "$completions" ]; then + compadd -U -V unsorted -a completions + fi +} + +compdef _watson_completion watson; diff --git a/plugins/wd/README.md b/plugins/wd/README.md index 8791f9f0e..1d1980632 100644 --- a/plugins/wd/README.md +++ b/plugins/wd/README.md @@ -1,12 +1,12 @@ # wd -[![Build Status](https://travis-ci.org/mfaerevaag/wd.png?branch=master)](https://travis-ci.org/mfaerevaag/wd) +[![Build Status](https://github.com/mfaerevaag/wd/actions/workflows/test.yml/badge.svg)](https://github.com/mfaerevaag/wd/actions) `wd` (*warp directory*) lets you jump to custom directories in zsh, without using `cd`. Why? Because `cd` seems inefficient when the folder is frequently visited or has a long path. -![tty.gif](https://raw.githubusercontent.com/mfaerevaag/wd/master/tty.gif) +![Demo](https://raw.githubusercontent.com/mfaerevaag/wd/master/tty.gif) ## Setup @@ -36,6 +36,10 @@ In your `.zshrc`: antibody bundle mfaerevaag/wd ``` +### [Fig](https://fig.io) + +Install `wd` here: [![Fig plugin store](https://fig.io/badges/install-with-fig.svg)](https://fig.io/plugins/other/wd_mfaerevaag) + ### Arch ([AUR](https://aur.archlinux.org/packages/zsh-plugin-wd-git/)) 1. Install from the AUR diff --git a/plugins/wd/wd.sh b/plugins/wd/wd.sh index 9085c5b7b..e51cf906a 100644 --- a/plugins/wd/wd.sh +++ b/plugins/wd/wd.sh @@ -163,6 +163,7 @@ wd_add() { local point=$1 local force=$2 + cmdnames=(add rm show list ls path clean help) if [[ $point == "" ]] then @@ -178,6 +179,9 @@ wd_add() elif [[ $point =~ : ]] || [[ $point =~ / ]] then wd_exit_fail "Warp point contains illegal character (:/)" + elif (($cmdnames[(Ie)$point])) + then + wd_exit_fail "Warp point name cannot be a wd command (see wd -h for a full list)" elif [[ ${points[$point]} == "" ]] || [ ! -z "$force" ] then wd_remove "$point" > /dev/null @@ -185,7 +189,7 @@ wd_add() if (whence sort >/dev/null); then local config_tmp=$(mktemp "${TMPDIR:-/tmp}/wd.XXXXXXXXXX") # use 'cat' below to ensure we respect $WD_CONFIG as a symlink - command sort -o "${config_tmp}" "$WD_CONFIG" && command cat "${config_tmp}" > "$WD_CONFIG" && command rm "${config_tmp}" + command sort -o "${config_tmp}" "$WD_CONFIG" && command cat "${config_tmp}" >| "$WD_CONFIG" && command rm "${config_tmp}" fi wd_export_static_named_directories @@ -214,7 +218,7 @@ wd_remove() then local config_tmp=$(mktemp "${TMPDIR:-/tmp}/wd.XXXXXXXXXX") # Copy and delete in two steps in order to preserve symlinks - if sed -n "/^${point_name}:.*$/!p" "$WD_CONFIG" > "$config_tmp" && command cp "$config_tmp" "$WD_CONFIG" && command rm "$config_tmp" + if sed -n "/^${point_name}:.*$/!p" "$WD_CONFIG" >| "$config_tmp" && command cp "$config_tmp" "$WD_CONFIG" && command rm "$config_tmp" then wd_print_msg "$WD_GREEN" "Warp point removed" else @@ -251,7 +255,7 @@ wd_list_all() then arr=(${(s,:,)line}) key=${arr[1]} - val=${arr[2]} + val=${line#"${arr[1]}:"} if [[ -z $wd_quiet_mode ]] then @@ -389,6 +393,11 @@ else wd_export_static_named_directories fi +# disable extendedglob for the complete wd execution time +setopt | grep -q extendedglob +wd_extglob_is_set=$? +[[ $wd_extglob_is_set ]] && setopt noextendedglob + # load warp points typeset -A points while read -r line @@ -475,6 +484,9 @@ fi # if not, next time warp will pick up variables from this run # remember, there's no sub shell +[[ $wd_extglob_is_set ]] && setopt extendedglob + +unset wd_extglob_is_set unset wd_warp unset wd_add unset wd_remove diff --git a/plugins/web-search/README.md b/plugins/web-search/README.md index da90f90a0..0bf9f26ad 100644 --- a/plugins/web-search/README.md +++ b/plugins/web-search/README.md @@ -25,9 +25,10 @@ $ google oh-my-zsh Available search contexts are: | Context | URL | -|-----------------------|------------------------------------------| +| --------------------- | ---------------------------------------- | | `bing` | `https://www.bing.com/search?q=` | | `google` | `https://www.google.com/search?q=` | +| `brs` or `brave` | `https://search.brave.com/search?q=` | | `yahoo` | `https://search.yahoo.com/search?p=` | | `ddg` or `duckduckgo` | `https://www.duckduckgo.com/?q=` | | `sp` or `startpage` | `https://www.startpage.com/do/search?q=` | @@ -42,6 +43,7 @@ Available search contexts are: | `wolframalpha` | `https://wolframalpha.com/input?i=` | | `archive` | `https://web.archive.org/web/*/` | | `scholar` | `https://scholar.google.com/scholar?q=` | +| `ask` | `https://www.ask.com/web?q=` | Also there are aliases for bang-searching DuckDuckGo: diff --git a/plugins/web-search/web-search.plugin.zsh b/plugins/web-search/web-search.plugin.zsh index 229948894..ec176dd68 100644 --- a/plugins/web-search/web-search.plugin.zsh +++ b/plugins/web-search/web-search.plugin.zsh @@ -7,22 +7,24 @@ function web_search() { typeset -A urls urls=( $ZSH_WEB_SEARCH_ENGINES - google "https://www.google.com/search?q=" - bing "https://www.bing.com/search?q=" - yahoo "https://search.yahoo.com/search?p=" - duckduckgo "https://www.duckduckgo.com/?q=" - startpage "https://www.startpage.com/do/search?q=" - yandex "https://yandex.ru/yandsearch?text=" - github "https://github.com/search?q=" - baidu "https://www.baidu.com/s?wd=" - ecosia "https://www.ecosia.org/search?q=" - goodreads "https://www.goodreads.com/search?q=" - qwant "https://www.qwant.com/?q=" - givero "https://www.givero.com/search?q=" - stackoverflow "https://stackoverflow.com/search?q=" - wolframalpha "https://www.wolframalpha.com/input/?i=" - archive "https://web.archive.org/web/*/" - scholar "https://scholar.google.com/scholar?q=" + google "https://www.google.com/search?q=" + bing "https://www.bing.com/search?q=" + brave "https://search.brave.com/search?q=" + yahoo "https://search.yahoo.com/search?p=" + duckduckgo "https://www.duckduckgo.com/?q=" + startpage "https://www.startpage.com/do/search?q=" + yandex "https://yandex.ru/yandsearch?text=" + github "https://github.com/search?q=" + baidu "https://www.baidu.com/s?wd=" + ecosia "https://www.ecosia.org/search?q=" + goodreads "https://www.goodreads.com/search?q=" + qwant "https://www.qwant.com/?q=" + givero "https://www.givero.com/search?q=" + stackoverflow "https://stackoverflow.com/search?q=" + wolframalpha "https://www.wolframalpha.com/input/?i=" + archive "https://web.archive.org/web/*/" + scholar "https://scholar.google.com/scholar?q=" + ask "https://www.ask.com/web?q=" ) # check whether the search engine is supported @@ -47,6 +49,7 @@ function web_search() { alias bing='web_search bing' +alias brs='web_search brave' alias google='web_search google' alias yahoo='web_search yahoo' alias ddg='web_search duckduckgo' @@ -62,6 +65,7 @@ alias stackoverflow='web_search stackoverflow' alias wolframalpha='web_search wolframalpha' alias archive='web_search archive' alias scholar='web_search scholar' +alias ask='web_search ask' #add your own !bang searches here alias wiki='web_search duckduckgo \!w' diff --git a/plugins/xcode/xcode.plugin.zsh b/plugins/xcode/xcode.plugin.zsh index 3bd12cdec..5d1f901a3 100644 --- a/plugins/xcode/xcode.plugin.zsh +++ b/plugins/xcode/xcode.plugin.zsh @@ -31,7 +31,7 @@ function xx { open -a "Xcode.app" "$@" } -# "XCode-SELect by Version" - select Xcode by just version number +# "Xcode-Select by Version" - select Xcode by just version number # Uses naming convention: # - different versions of Xcode are named Xcode-.app or stored # in a folder named Xcode- diff --git a/plugins/yarn/README.md b/plugins/yarn/README.md index 9c16ff2c3..5c7c7f323 100644 --- a/plugins/yarn/README.md +++ b/plugins/yarn/README.md @@ -15,7 +15,7 @@ It also adds `yarn` global scripts dir (commonly `~/.yarn/bin`) to the `$PATH`. To disable this feature, set the following style in your `.zshrc`: ```zsh -zstyle ':omz:plugins:yarn' global-path false +zstyle ':omz:plugins:yarn' global-path no ``` ## Aliases @@ -29,6 +29,7 @@ zstyle ':omz:plugins:yarn' global-path false | yb | `yarn build` | Run the build script defined in `package.json` | | ycc | `yarn cache clean` | Clean yarn's global cache of packages | | yd | `yarn dev` | Run the dev script defined in `package.json` | +| yf | `yarn format` | Run the dev script defined in `package.json` | | yga | `yarn global add` | Install packages globally on your operating system | | ygls | `yarn global list` | Lists global installed packages | | ygrm | `yarn global remove` | Remove global installed packages from your OS | @@ -54,3 +55,4 @@ zstyle ':omz:plugins:yarn' global-path false | yv | `yarn version` | Update the version of your package | | yw | `yarn workspace` | Run a command within a single workspace. | | yws | `yarn workspaces` | Run a command within all defined workspaces. | +| yy | `yarn why` | Show why a package has been installed, detailing which other packages depend on it | diff --git a/plugins/yarn/yarn.plugin.zsh b/plugins/yarn/yarn.plugin.zsh index bcb8661cf..157044d71 100644 --- a/plugins/yarn/yarn.plugin.zsh +++ b/plugins/yarn/yarn.plugin.zsh @@ -17,6 +17,7 @@ alias yap="yarn add --peer" alias yb="yarn build" alias ycc="yarn cache clean" alias yd="yarn dev" +alias yf="yarn format" alias yga="yarn global add" alias ygls="yarn global list" alias ygrm="yarn global remove" @@ -42,3 +43,4 @@ alias yup="yarn upgrade" alias yv="yarn version" alias yw="yarn workspace" alias yws="yarn workspaces" +alias yy="yarn why" diff --git a/plugins/z/LICENSE b/plugins/z/LICENSE new file mode 100644 index 000000000..d1cca7ae5 --- /dev/null +++ b/plugins/z/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018-2022 Alexandros Kozak + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/plugins/z/MANUAL.md b/plugins/z/MANUAL.md new file mode 100644 index 000000000..dcca3c452 --- /dev/null +++ b/plugins/z/MANUAL.md @@ -0,0 +1,343 @@ +# Zsh-z + +Zsh-z is a command line tool that allows you to jump quickly to directories that you have visited frequently in the past, or recently -- but most often a combination of the two (a concept known as ["frecency"](https://en.wikipedia.org/wiki/Frecency)). It works by keeping track of when you go to directories and how much time you spend in them. It is then in the position to guess where you want to go when you type a partial string, e.g., `z src` might take you to `~/src/zsh`. `z zsh` might also get you there, and `z c/z` might prove to be even more specific -- it all depends on your habits and how much time you have been using Zsh-z to build up a database. After using Zsh-z for a little while, you will get to where you want to be by typing considerably less than you would need if you were using `cd`. + +Zsh-z is a native Zsh port of [rupa/z](https://github.com/rupa/z), a tool written for `bash` and Zsh that uses embedded `awk` scripts to do the heavy lifting. It was quite possibly my most used command line tool for a couple of years. I decided to translate it, `awk` parts and all, into pure Zsh script, to see if by eliminating calls to external tools (`awk`, `sort`, `date`, `sed`, `mv`, `rm`, and `chown`) and reducing forking through subshells I could make it faster. The performance increase is impressive, particularly on systems where forking is slow, such as Cygwin, MSYS2, and WSL. I have found that, in those environments, switching directories using Zsh-z can be over 100% faster than it is using `rupa/z`. + +There is a noteworthy stability increase as well. Race conditions have always been a problem with `rupa/z`, and users of that utility will occasionally lose their `.z` databases. By having Zsh-z only use Zsh (`rupa/z` uses a hybrid shell code that works on `bash` as well), I have been able to implement a `zsh/system`-based file-locking mechanism similar to [the one @mafredri once proposed for `rupa/z`](https://github.com/rupa/z/pull/199). It is now nearly impossible to crash the database, even through extreme testing. + +There are other, smaller improvements which I try to document in [Improvements and Fixes](#improvements-and-fixes). These include the new default behavior of sorting your tab completions by frecency rather than just letting Zsh sort the raw results alphabetically (a behavior which can be restored if you like it -- [see below](#settings)). + +Zsh-z is a drop-in replacement for `rupa/z` and will, by default, use the same database (`~/.z`), so you can go on using `rupa/z` when you launch `bash`. + +## Table of Contents +- [News](#news) +- [Installation](#installation) +- [Command Line Options](#command-line-options) +- [Settings](#settings) +- [Case Sensitivity](#case-sensitivity) +- [`ZSHZ_UNCOMMON`](#zshz_uncommon) +- [Making `--add` work for you](#making---add-work-for-you) +- [Other Improvements and Fixes](#other-improvements-and-fixes) +- [Migrating from Other Tools](#migrating-from-other-tools) +- [`COMPLETE_ALIASES`](#complete_aliases) +- [Known Bugs](#known-bugs) + +## News + +
+ Here are the latest features and updates. + +- June 29, 2022 + + Zsh-z is less likely to leave temporary files sitting around (props @mafredri). +- June 27, 2022 + + A bug was fixed which was preventing paths with spaces in them from being updated ([#61](https://github.com/agkozak/zsh-z/issues/61)). + + If writing to the temporary database file fails, the database will not be clobbered (props @mafredri). +- December 19, 2021 + + ZSH-z will now display tildes for `HOME` during completion when `ZSHZ_TILDE=1` has been set. +- November 11, 2021 + + A bug was fixed which was preventing ranks from being incremented. + + `--add` has been made to work with relative paths and has been documented for the user. +- October 14, 2021 + + Completions were being sorted alphabetically, rather than by rank; this error has been fixed. +- September 25, 2021 + + Orthographical change: "Zsh," not "ZSH." +- September 23, 2021 + + `z -xR` will now remove a directory *and its subdirectories* from the database. + + `z -x` and `z -xR` can now take an argument; without one, `PWD` is assumed. +- September 7, 2021 + + Fixed the unload function so that it removes the `$ZSHZ_CMD` alias (default: `z`). +- August 27, 2021 + + Using `print -v ... -f` instead of `print -v` to work around longstanding bug in Zsh involving `print -v` and multibyte strings. +- August 13, 2021 + + Fixed the explanation string printed during completion so that it may be formatted with `zstyle`. + + Zsh-z now declares `ZSHZ_EXCLUDE_DIRS` as an array with unique elements so that you do not have to. +- July 29, 2021 + + Temporarily disabling use of `print -v`, which seems to be mangling CJK multibyte strings. +- July 27, 2021 + + Internal escaping of path names now works with older versions of ZSH. + + Zsh-z now detects and discards any incomplete or incorrectly formattted database entries. +- July 10, 2021 + + Setting `ZSHZ_TRAILING_SLASH=1` makes it so that a search pattern ending in `/` can match the end of a path; e.g. `z foo/` can match `/path/to/foo`. +- June 25, 2021 + + Setting `ZSHZ_TILDE=1` displays the `HOME` directory as `~`. +- May 7, 2021 + + Setting `ZSHZ_ECHO=1` will cause Zsh-z to display the new path when you change directories. + + Better escaping of path names to deal paths containing the characters ``\`()[]``. +- February 15, 2021 + + Ranks are displayed the way `rupa/z` now displays them, i.e. as large integers. This should help Zsh-z to integrate with other tools. +- January 31, 2021 + + Zsh-z is now efficient enough that, on MSYS2 and Cygwin, it is faster to run it in the foreground than it is to fork a subshell for it. + + `_zshz_precmd` simply returns if `PWD` is `HOME` or in `ZSH_EXCLUDE_DIRS`, rather than waiting for `zshz` to do that. +- January 17, 2021 + + Made sure that the `PUSHD_IGNORE_DUPS` option is respected. +- January 14, 2021 + + The `z -h` help text now breaks at spaces. + + `z -l` was not working for Zsh version < 5. +- January 11, 2021 + + Major refactoring of the code. + + `z -lr` and `z -lt` work as expected. + + `EXTENDED_GLOB` has been disabled within the plugin to accomodate old-fashioned Windows directories with names such as `Progra~1`. + + Removed `zshelldoc` documentation. +- January 6, 2021 + + I have corrected the frecency routine so that it matches `rupa/z`'s math, but for the present, Zsh-z will continue to display ranks as 1/10000th of what they are in `rupa/z` -- [they had to multiply theirs by 10000](https://github.com/rupa/z/commit/f1f113d9bae9effaef6b1e15853b5eeb445e0712) to work around `bash`'s inadequacies at dealing with decimal fractions. +- January 5, 2021 + + If you try `z foo`, and `foo` is not in the database but `${PWD}/foo` is a valid directory, Zsh-z will `cd` to it. +- December 22, 2020 + + `ZSHZ_CASE`: when set to `ignore`, pattern matching is case-insensitive; when set to `smart`, patterns are matched case-insensitively when they are all lowercase and case-sensitively when they have uppercase characters in them (a behavior very much like Vim's `smartcase` setting). + + `ZSHZ_KEEP_DIRS` is an array of directory names that should not be removed from the database, even if they are not currently available (useful when a drive is not always mounted). + + Symlinked datafiles were having their symlinks overwritten; this bug has been fixed. + +
+ +## Installation + +### General observations + +This script can be installed simply by downloading it and sourcing it from your `.zshrc`: + + source /path/to/zsh-z.plugin.zsh + +For tab completion to work, you will want to have loaded `compinit`. The frameworks handle this themselves. If you are not using a framework, put + + autoload -U compinit && compinit + +in your .zshrc somewhere below where you source `zsh-z.plugin.zsh`. + +If you add + + zstyle ':completion:*' menu select + +to your `.zshrc`, your completion menus will look very nice. This `zstyle` invocation should work with any of the frameworks below as well. + +### For [antigen](https://github.com/zsh-users/antigen) users + +Add the line + + antigen bundle agkozak/zsh-z + +to your `.zshrc`, somewhere above the line that says `antigen apply`. + +### For [oh-my-zsh](http://ohmyz.sh/) users + +Execute the following command: + + git clone https://github.com/agkozak/zsh-z ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-z + +and add `zsh-z` to the line of your `.zshrc` that specifies `plugins=()`, e.g., `plugins=( git zsh-z )`. + +### For [prezto](https://github.com/sorin-ionescu/prezto) users + +Execute the following command: + + git clone https://github.com/agkozak/zsh-z.git ~/.zprezto-contrib/zsh-z + +Then edit your `~/.zpreztorc` file. Make sure the line that says + + zstyle ':prezto:load' pmodule-dirs $HOME/.zprezto-contrib + +is uncommented. Then find the section that specifies which modules are to be loaded; it should look something like this: + + zstyle ':prezto:load' pmodule \ + 'environment' \ + 'terminal' \ + 'editor' \ + 'history' \ + 'directory' \ + 'spectrum' \ + 'utility' \ + 'completion' \ + 'prompt' + +Add a backslash to the end of the last line add `'zsh-z'` to the list, e.g., + + zstyle ':prezto:load' pmodule \ + 'environment' \ + 'terminal' \ + 'editor' \ + 'history' \ + 'directory' \ + 'spectrum' \ + 'utility' \ + 'completion' \ + 'prompt' \ + 'zsh-z' + +Then relaunch `zsh`. + +### For [zcomet](https://github.com/agkozak/zcomet) users + +Simply add + + zcomet load agkozak/zsh-z + +to your `.zshrc` (below where you source `zcomet.zsh` and above where you run `zcomet compinit`). + +### For [zgen](https://github.com/tarjoilija/zgen) users + +Add the line + + zgen load agkozak/zsh-z + +somewhere above the line that says `zgen save`. Then run + + zgen reset + zsh + +to refresh your init script. + +### For [Zim](https://github.com/zimfw/zimfw) + +Add the following line to your `.zimrc`: + + zmodule https://github.com/agkozak/zsh-z + +Then run + + zimfw install + +and restart your shell. + +### For [Zinit](https://github.com/zdharma-continuum/zinit) users + +Add the line + + zinit load agkozak/zsh-z + +to your `.zshrc`. + +`zsh-z` supports `zinit`'s `unload` feature; just run `zinit unload agkozak/zshz` to restore the shell to its state before `zsh-z` was loaded. + +### For [Znap](https://github.com/marlonrichert/zsh-snap) users + +Add the line + + znap source agkozak/zsh-z + +somewhere below the line where you `source` Znap itself. + +### For [zplug](https://github.com/zplug/zplug) users + +Add the line + + zplug "agkozak/zsh-z" + +somewhere above the line that says `zplug load`. Then run + + zplug install + zplug load + +to install `zsh-z`. + +## Command Line Options + +- `--add` Add a directory to the database +- `-c` Only match subdirectories of the current directory +- `-e` Echo the best match without going to it +- `-h` Display help +- `-l` List all matches without going to them +- `-r` Match by rank (i.e. how much time you spend in directories) +- `-t` Time -- match by how recently you have been to directories +- `-x` Remove a directory (by default, the current directory) from the database +- `-xR` Remove a directory (by default, the current directory) and its subdirectories from the database + +# Settings + +Zsh-z has environment variables (they all begin with `ZSHZ_`) that change its behavior if you set them; you can also keep your old ones if you have been using `rupa/z` (they begin with `_Z_`). + +* `ZSHZ_CMD` changes the command name (default: `z`) +* `ZSHZ_COMPLETION` can be `'frecent'` (default) or `'legacy'`, depending on whether you want your completion results sorted according to frecency or simply sorted alphabetically +* `ZSHZ_DATA` changes the database file (default: `~/.z`) +* `ZSHZ_ECHO` displays the new path name when changing directories (default: `0`) +* `ZSHZ_EXCLUDE_DIRS` is an array of directories to keep out of the database (default: empty) +* `ZSHZ_KEEP_DIRS` is an array of directories that should not be removed from the database, even if they are not currently available (useful when a drive is not always mounted) (default: empty) +* `ZSHZ_MAX_SCORE` is the maximum combined score the database entries can have before they begin to age and potentially drop out of the database (default: 9000) +* `ZSHZ_NO_RESOLVE_SYMLINKS` prevents symlink resolution (default: `0`) +* `ZSHZ_OWNER` allows usage when in `sudo -s` mode (default: empty) +* `ZSHZ_TILDE` displays the name of the `HOME` directory as a `~` (default: `0`) +* `ZSHZ_TRAILING_SLASH` makes it so that a search pattern ending in `/` can match the final element in a path; e.g., `z foo/` can match `/path/to/foo` (default: `0`) +* `ZSHZ_UNCOMMON` changes the logic used to calculate the directory jumped to; [see below](#zshz_uncommon`) (default: `0`) + +## Case sensitivity + +The default behavior of Zsh-z is to try to find a case-sensitive match. If there is none, then Zsh-z tries to find a case-insensitive match. + +Some users prefer simple case-insensitivity; this behavior can be enabled by setting + + ZSHZ_CASE=ignore + +If you like Vim's `smartcase` setting, where lowercase patterns are case-insensitive while patterns with any uppercase characters are treated case-sensitively, try setting + + ZSHZ_CASE=smart + +## `ZSHZ_UNCOMMON` + +A common complaint about the default behavior of `rupa/z` and Zsh-z involves "common prefixes." If you type `z code` and the best matches, in increasing order, are + + /home/me/code/foo + /home/me/code/bar + /home/me/code/bat + +Zsh-z will see that all possible matches share a common prefix and will send you to that directory -- `/home/me/code` -- which is often a desirable result. But if the possible matches are + + /home/me/.vscode/foo + /home/me/code/foo + /home/me/code/bar + /home/me/code/bat + +then there is no common prefix. In this case, `z code` will simply send you to the highest-ranking match, `/home/me/code/bat`. + +You may enable an alternate, experimental behavior by setting `ZSHZ_UNCOMMON=1`. If you do that, Zsh-z will not jump to a common prefix, even if one exists. Instead, it chooses the highest-ranking match -- but it drops any subdirectories that do not include the search term. So if you type `z bat` and `/home/me/code/bat` is the best match, that is exactly where you will end up. If, however, you had typed `z code` and the best match was also `/home/me/code/bat`, you would have ended up in `/home/me/code` (because `code` was what you had searched for). This feature is still in development, and feedback is welcome. + +## Making `--add` Work for You + +Zsh-z internally uses the `--add` option to add paths to its database. @zachriggle pointed out to me that users might want to use `--add` themselves, so I have altered it a little to make it more user-friendly. + +A good example might involve a directory tree that has Git repositories within it. The working directories could be added to the Zsh-z database as a batch with + + for i in $(find $PWD -maxdepth 3 -name .git -type d); do + z --add ${i:h} + done + +(As a Zsh user, I tend to use `**` instead of `find`, but it is good to see how deep your directory trees go before doing that.) + + +## Other Improvements and Fixes + +* `z -x` works, with the help of `chpwd_functions`. +* Zsh-z works on Solaris. +* Zsh-z uses the "new" `zshcompsys` completion system instead of the old `compctl` one. +* There is no error message when the database file has not yet been created. +* There is support for special characters (e.g., `[`) in directory names. +* If `z -l` only returns one match, a common root is not printed. +* Exit status codes increasingly make sense. +* Completions work with options `-c`, `-r`, and `-t`. +* If `~/foo` and `~/foob` are matches, `~/foo` is *not* the common root. Only a common parent directory can be a common root. +* `z -x` and the new, recursive `z -xR` can take an argument so that you can remove directories other than `PWD` from the database. + +## Migrating from Other Tools + +Zsh-z's database format is identical to that of `rupa/z`. You may switch freely between the two tools (I still use `rupa/z` for `bash`). `fasd` also uses that database format, but it stores it by default in `~/.fasd`, so you will have to `cp ~/.fasd ~/.z` if you want to use your old directory history. + +If you are coming to Zsh-z (or even to the original `rupa/z`, for that matter) from `autojump`, try using my [`jumpstart-z`](https://github.com/agkozak/jumpstart-z/blob/master/jumpstart-z) tool to convert your old database to the Zsh-z format, or simply run + + awk -F "\t" '{printf("%s|%0.f|%s\n", $2, $1, '"$(date +%s)"')}' < /path/to/autojump.txt > ~/.z + +## `COMPLETE_ALIASES` + +`z`, or any alternative you set up using `$ZSH_CMD` or `$_Z_CMD`, is an alias. `setopt COMPLETE_ALIASES` divorces the tab completion for aliases from the underlying commands they invoke, so if you enable `COMPLETE_ALIASES`, tab completion for Zsh-z will be broken. You can get it working again, however, by adding under + + setopt COMPLETE_ALIASES + +the line + + compdef _zshz ${ZSHZ_CMD:-${_Z_CMD:-z}} + +That will re-bind `z` or the command of your choice to the underlying Zsh-z function. + +## Known Bugs +It is possible to run a completion on a string with spaces in it, e.g., `z us bi` might take you to `/usr/local/bin`. This works, but as things stand, after the completion the command line reads + + z us /usr/local/bin. + +You get where you want to go, but the detritus on the command line is annoying. This is also a problem in `rupa/z`, but I am keen on eventually eliminating this glitch. Advice is welcome. diff --git a/plugins/z/Makefile b/plugins/z/Makefile deleted file mode 100644 index dcf433d40..000000000 --- a/plugins/z/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -readme: - @groff -man -Tascii z.1 | col -bx - -.PHONY: readme diff --git a/plugins/z/README b/plugins/z/README deleted file mode 100644 index 47e54c57a..000000000 --- a/plugins/z/README +++ /dev/null @@ -1,148 +0,0 @@ -Z(1) User Commands Z(1) - - - -NAME - z - jump around - -SYNOPSIS - z [-chlrtx] [regex1 regex2 ... regexn] - -AVAILABILITY - bash, zsh - -DESCRIPTION - Tracks your most used directories, based on 'frecency'. - - After a short learning phase, z will take you to the most 'frecent' - directory that matches ALL of the regexes given on the command line, in - order. - - For example, z foo bar would match /foo/bar but not /bar/foo. - -OPTIONS - -c restrict matches to subdirectories of the current directory - - -e echo the best match, don't cd - - -h show a brief help message - - -l list only - - -r match by rank only - - -t match by recent access only - - -x remove the current directory from the datafile - -EXAMPLES - z foo cd to most frecent dir matching foo - - z foo bar cd to most frecent dir matching foo, then bar - - z -r foo cd to highest ranked dir matching foo - - z -t foo cd to most recently accessed dir matching foo - - z -l foo list all dirs matching foo (by frecency) - -NOTES - Installation: - Put something like this in your $HOME/.bashrc or $HOME/.zshrc: - - . /path/to/z.sh - - cd around for a while to build up the db. - - PROFIT!! - - Optionally: - Set $_Z_CMD to change the command name (default z). - Set $_Z_DATA to change the datafile (default $HOME/.z). - Set $_Z_MAX_SCORE lower to age entries out faster (default - 9000). - Set $_Z_NO_RESOLVE_SYMLINKS to prevent symlink resolution. - Set $_Z_NO_PROMPT_COMMAND to handle PROMPT_COMMAND/precmd your- - self. - Set $_Z_EXCLUDE_DIRS to an array of directory trees to exclude. - Set $_Z_OWNER to allow usage when in 'sudo -s' mode. - (These settings should go in .bashrc/.zshrc before the line - added above.) - Install the provided man page z.1 somewhere in your MANPATH, - like /usr/local/man/man1. - - Aging: - The rank of directories maintained by z undergoes aging based on a sim- - ple formula. The rank of each entry is incremented every time it is - accessed. When the sum of ranks is over 9000, all ranks are multiplied - by 0.99. Entries with a rank lower than 1 are forgotten. - - Frecency: - Frecency is a portmanteau of 'recent' and 'frequency'. It is a weighted - rank that depends on how often and how recently something occurred. As - far as I know, Mozilla came up with the term. - - To z, a directory that has low ranking but has been accessed recently - will quickly have higher rank than a directory accessed frequently a - long time ago. - - Frecency is determined at runtime. - - Common: - When multiple directories match all queries, and they all have a common - prefix, z will cd to the shortest matching directory, without regard to - priority. This has been in effect, if undocumented, for quite some - time, but should probably be configurable or reconsidered. - - Tab Completion: - z supports tab completion. After any number of arguments, press TAB to - complete on directories that match each argument. Due to limitations of - the completion implementations, only the last argument will be com- - pleted in the shell. - - Internally, z decides you've requested a completion if the last argu- - ment passed is an absolute path to an existing directory. This may - cause unexpected behavior if the last argument to z begins with /. - -ENVIRONMENT - A function _z() is defined. - - The contents of the variable $_Z_CMD is aliased to _z 2>&1. If not set, - $_Z_CMD defaults to z. - - The environment variable $_Z_DATA can be used to control the datafile - location. If it is not defined, the location defaults to $HOME/.z. - - The environment variable $_Z_NO_RESOLVE_SYMLINKS can be set to prevent - resolving of symlinks. If it is not set, symbolic links will be - resolved when added to the datafile. - - In bash, z appends a command to the PROMPT_COMMAND environment variable - to maintain its database. In zsh, z appends a function _z_precmd to the - precmd_functions array. - - The environment variable $_Z_NO_PROMPT_COMMAND can be set if you want - to handle PROMPT_COMMAND or precmd yourself. - - The environment variable $_Z_EXCLUDE_DIRS can be set to an array of - directory trees to exclude from tracking. $HOME is always excluded. - Directories must be full paths without trailing slashes. - - The environment variable $_Z_OWNER can be set to your username, to - allow usage of z when your sudo environment keeps $HOME set. - -FILES - Data is stored in $HOME/.z. This can be overridden by setting the - $_Z_DATA environment variable. When initialized, z will raise an error - if this path is a directory, and not function correctly. - - A man page (z.1) is provided. - -SEE ALSO - regex(7), pushd, popd, autojump, cdargs - - Please file bugs at https://github.com/rupa/z/ - - - -z January 2013 Z(1) diff --git a/plugins/z/README.md b/plugins/z/README.md index ea8d4610a..5b7d6f649 100644 --- a/plugins/z/README.md +++ b/plugins/z/README.md @@ -1,8 +1,9 @@ # z - jump around -This plugin defines the [z command](https://github.com/rupa/z) that tracks your most visited directories and allows you to access them with very few keystrokes. +This plugin defines the [z command](https://github.com/agkozak/zsh-z) that tracks your most visited directories and allows you to access them with very few keystrokes. ### Example + Assume that you have previously visited directory `~/.oh-my-zsh/plugins`. From any folder in your command line, you can quickly access it by using a regex match to this folder: ```bash @@ -11,6 +12,7 @@ Assume that you have previously visited directory `~/.oh-my-zsh/plugins`. From a ``` ### Setup + To enable z, add `z` to your `plugins` array in your zshrc file: ```zsh @@ -19,5 +21,4 @@ plugins=(... z) ### Further reading -For advanced usage and details of z, see [README](./README) (in man page format, copied from [rupa/z](https://github.com/rupa/z)). - +For advanced usage and details of z, see [MANUAL](./MANUAL.md) (copied from [agkozak/zsh-z](https://github.com/agkozak/zsh-z)). diff --git a/plugins/z/_z b/plugins/z/_z new file mode 100644 index 000000000..9891a52ed --- /dev/null +++ b/plugins/z/_z @@ -0,0 +1,82 @@ +#compdef zshz ${ZSHZ_CMD:-${_Z_CMD:-z}} +# +# Zsh-z - jump around with Zsh - A native Zsh version of z without awk, sort, +# date, or sed +# +# https://github.com/agkozak/zsh-z +# +# Copyright (c) 2018-2022 Alexandros Kozak +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# z (https://github.com/rupa/z) is copyright (c) 2009 rupa deadwyler and +# licensed under the WTFPL license, Version 2.a +# +# shellcheck shell=ksh + +############################################################ +# Zsh-z COMPLETIONS +############################################################ +emulate -L zsh +(( ZSHZ_DEBUG )) && + setopt LOCAL_OPTIONS WARN_CREATE_GLOBAL NO_WARN_NESTED_VAR 2> /dev/null + +# TODO: This routine currently reproduces z's feature of allowing spaces to be +# used as wildcards in completions, so that +# +# z us lo bi +# +# can expand to +# +# z /usr/local/bin +# +# but it also reproduces z's buggy display on the commandline, viz. +# +# z us lo /usr/local/bin +# +# Address. + +local completions expl completion +local -a completion_list + +completions=$(zshz --complete ${(@)words:1}) +[[ -z $completions ]] && return 1 + +for completion in ${(f)completions[@]}; do + if (( ZSHZ_TILDE )) && [[ $completion == ${HOME}* ]]; then + completion="~${(q)${completion#${HOME}}}" + else + completion="${(q)completion}" + fi + completion_list+=( $completion ) +done + +_description -V completion_list expl 'directories' + +if [[ $ZSHZ_COMPLETION == 'legacy' ]]; then + compadd "${expl[@]}" -QU -- "${completion_list[@]}" +else + compadd "${expl[@]}" -QU -V zsh-z -- "${completion_list[@]}" +fi + +compstate[insert]=menu + +return 0 + +# vim: ft=zsh:fdm=indent:ts=2:et:sts=2:sw=2: diff --git a/plugins/z/z.1 b/plugins/z/z.1 deleted file mode 100644 index 182f98176..000000000 --- a/plugins/z/z.1 +++ /dev/null @@ -1,173 +0,0 @@ -.TH "Z" "1" "January 2013" "z" "User Commands" -.SH -NAME -z \- jump around -.SH -SYNOPSIS -z [\-chlrtx] [regex1 regex2 ... regexn] -.SH -AVAILABILITY -bash, zsh -.SH -DESCRIPTION -Tracks your most used directories, based on 'frecency'. -.P -After a short learning phase, \fBz\fR will take you to the most 'frecent' -directory that matches ALL of the regexes given on the command line, in order. - -For example, \fBz foo bar\fR would match \fB/foo/bar\fR but not \fB/bar/foo\fR. -.SH -OPTIONS -.TP -\fB\-c\fR -restrict matches to subdirectories of the current directory -.TP -\fB\-e\fR -echo the best match, don't cd -.TP -\fB\-h\fR -show a brief help message -.TP -\fB\-l\fR -list only -.TP -\fB\-r\fR -match by rank only -.TP -\fB\-t\fR -match by recent access only -.TP -\fB\-x\fR -remove the current directory from the datafile -.SH EXAMPLES -.TP 14 -\fBz foo\fR -cd to most frecent dir matching foo -.TP 14 -\fBz foo bar\fR -cd to most frecent dir matching foo, then bar -.TP 14 -\fBz -r foo\fR -cd to highest ranked dir matching foo -.TP 14 -\fBz -t foo\fR -cd to most recently accessed dir matching foo -.TP 14 -\fBz -l foo\fR -list all dirs matching foo (by frecency) -.SH -NOTES -.SS -Installation: -.P -Put something like this in your \fB$HOME/.bashrc\fR or \fB$HOME/.zshrc\fR: -.RS -.P -\fB. /path/to/z.sh\fR -.RE -.P -\fBcd\fR around for a while to build up the db. -.P -PROFIT!! -.P -Optionally: -.RS -Set \fB$_Z_CMD\fR to change the command name (default \fBz\fR). -.RE -.RS -Set \fB$_Z_DATA\fR to change the datafile (default \fB$HOME/.z\fR). -.RE -.RS -Set \fB$_Z_MAX_SCORE\fR lower to age entries out faster (default \fB9000\fR). -.RE -.RS -Set \fB$_Z_NO_RESOLVE_SYMLINKS\fR to prevent symlink resolution. -.RE -.RS -Set \fB$_Z_NO_PROMPT_COMMAND\fR to handle \fBPROMPT_COMMAND/precmd\fR yourself. -.RE -.RS -Set \fB$_Z_EXCLUDE_DIRS\fR to an array of directory trees to exclude. -.RE -.RS -Set \fB$_Z_OWNER\fR to allow usage when in 'sudo -s' mode. -.RE -.RS -(These settings should go in .bashrc/.zshrc before the line added above.) -.RE -.RS -Install the provided man page \fBz.1\fR somewhere in your \f$MANPATH, like -\fB/usr/local/man/man1\fR. -.RE -.SS -Aging: -The rank of directories maintained by \fBz\fR undergoes aging based on a simple -formula. The rank of each entry is incremented every time it is accessed. When -the sum of ranks is over 9000, all ranks are multiplied by 0.99. Entries with a -rank lower than 1 are forgotten. -.SS -Frecency: -Frecency is a portmanteau of 'recent' and 'frequency'. It is a weighted rank -that depends on how often and how recently something occurred. As far as I -know, Mozilla came up with the term. -.P -To \fBz\fR, a directory that has low ranking but has been accessed recently -will quickly have higher rank than a directory accessed frequently a long time -ago. -.P -Frecency is determined at runtime. -.SS -Common: -When multiple directories match all queries, and they all have a common prefix, -\fBz\fR will cd to the shortest matching directory, without regard to priority. -This has been in effect, if undocumented, for quite some time, but should -probably be configurable or reconsidered. -.SS -Tab Completion: -\fBz\fR supports tab completion. After any number of arguments, press TAB to -complete on directories that match each argument. Due to limitations of the -completion implementations, only the last argument will be completed in the -shell. -.P -Internally, \fBz\fR decides you've requested a completion if the last argument -passed is an absolute path to an existing directory. This may cause unexpected -behavior if the last argument to \fBz\fR begins with \fB/\fR. -.SH -ENVIRONMENT -A function \fB_z()\fR is defined. -.P -The contents of the variable \fB$_Z_CMD\fR is aliased to \fB_z 2>&1\fR. If not -set, \fB$_Z_CMD\fR defaults to \fBz\fR. -.P -The environment variable \fB$_Z_DATA\fR can be used to control the datafile -location. If it is not defined, the location defaults to \fB$HOME/.z\fR. -.P -The environment variable \fB$_Z_NO_RESOLVE_SYMLINKS\fR can be set to prevent -resolving of symlinks. If it is not set, symbolic links will be resolved when -added to the datafile. -.P -In bash, \fBz\fR appends a command to the \fBPROMPT_COMMAND\fR environment -variable to maintain its database. In zsh, \fBz\fR appends a function -\fB_z_precmd\fR to the \fBprecmd_functions\fR array. -.P -The environment variable \fB$_Z_NO_PROMPT_COMMAND\fR can be set if you want to -handle \fBPROMPT_COMMAND\fR or \fBprecmd\fR yourself. -.P -The environment variable \fB$_Z_EXCLUDE_DIRS\fR can be set to an array of -directory trees to exclude from tracking. \fB$HOME\fR is always excluded. -Directories must be full paths without trailing slashes. -.P -The environment variable \fB$_Z_OWNER\fR can be set to your username, to -allow usage of \fBz\fR when your sudo environment keeps \fB$HOME\fR set. -.SH -FILES -Data is stored in \fB$HOME/.z\fR. This can be overridden by setting the -\fB$_Z_DATA\fR environment variable. When initialized, \fBz\fR will raise an -error if this path is a directory, and not function correctly. -.P -A man page (\fBz.1\fR) is provided. -.SH -SEE ALSO -regex(7), pushd, popd, autojump, cdargs -.P -Please file bugs at https://github.com/rupa/z/ diff --git a/plugins/z/z.plugin.zsh b/plugins/z/z.plugin.zsh index 7d3eacac0..209edfea7 100644 --- a/plugins/z/z.plugin.zsh +++ b/plugins/z/z.plugin.zsh @@ -1,6 +1,968 @@ -# Handle $0 according to the standard: -# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html -0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}" -0="${${(M)0:#/*}:-$PWD/$0}" +################################################################################ +# Zsh-z - jump around with Zsh - A native Zsh version of z without awk, sort, +# date, or sed +# +# https://github.com/agkozak/zsh-z +# +# Copyright (c) 2018-2022 Alexandros Kozak +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# z (https://github.com/rupa/z) is copyright (c) 2009 rupa deadwyler and +# licensed under the WTFPL license, Version 2. +# +# Zsh-z maintains a jump-list of the directories you actually use. +# +# INSTALL: +# * put something like this in your .zshrc: +# source /path/to/zsh-z.plugin.zsh +# * cd around for a while to build up the database +# +# USAGE: +# * z foo cd to the most frecent directory matching foo +# * z foo bar cd to the most frecent directory matching both foo and bar +# (e.g. /foo/bat/bar/quux) +# * z -r foo cd to the highest ranked directory matching foo +# * z -t foo cd to most recently accessed directory matching foo +# * z -l foo List matches instead of changing directories +# * z -e foo Echo the best match without changing directories +# * z -c foo Restrict matches to subdirectories of PWD +# * z -x Remove a directory (default: PWD) from the database +# * z -xR Remove a directory (default: PWD) and its subdirectories from +# the database +# +# ENVIRONMENT VARIABLES: +# +# ZSHZ_CASE -> if `ignore', pattern matching is case-insensitive; if `smart', +# pattern matching is case-insensitive only when the pattern is all +# lowercase +# ZSHZ_CMD -> name of command (default: z) +# ZSHZ_COMPLETION -> completion method (default: 'frecent'; 'legacy' for +# alphabetic sorting) +# ZSHZ_DATA -> name of datafile (default: ~/.z) +# ZSHZ_EXCLUDE_DIRS -> array of directories to exclude from your database +# (default: empty) +# ZSHZ_KEEP_DIRS -> array of directories that should not be removed from the +# database, even if they are not currently available (default: empty) +# ZSHZ_MAX_SCORE -> maximum combined score the database entries can have +# before beginning to age (default: 9000) +# ZSHZ_NO_RESOLVE_SYMLINKS -> '1' prevents symlink resolution +# ZSHZ_OWNER -> your username (if you want use Zsh-z while using sudo -s) +# ZSHZ_UNCOMMON -> if 1, do not jump to "common directories," but rather drop +# subdirectories based on what the search string was (default: 0) +################################################################################ -source "${0:h}/z.sh" +autoload -U is-at-least + +if ! is-at-least 4.3.11; then + print "Zsh-z requires Zsh v4.3.11 or higher." >&2 && exit +fi + +############################################################ +# The help message +# +# Globals: +# ZSHZ_CMD +############################################################ +_zshz_usage() { + print "Usage: ${ZSHZ_CMD:-${_Z_CMD:-z}} [OPTION]... [ARGUMENT] +Jump to a directory that you have visited frequently or recently, or a bit of both, based on the partial string ARGUMENT. + +With no ARGUMENT, list the directory history in ascending rank. + + --add Add a directory to the database + -c Only match subdirectories of the current directory + -e Echo the best match without going to it + -h Display this help and exit + -l List all matches without going to them + -r Match by rank + -t Match by recent access + -x Remove a directory from the database (by default, the current directory) + -xR Remove a directory and its subdirectories from the database (by default, the current directory)" | + fold -s -w $COLUMNS >&2 +} + +# Load zsh/datetime module, if necessary +(( $+EPOCHSECONDS )) || zmodload zsh/datetime + +# Load zsh/files, if necessary +[[ ${builtins[zf_chown]} == 'defined' && + ${builtins[zf_mv]} == 'defined' && + ${builtins[zf_rm]} == 'defined' ]] || + zmodload -F zsh/files b:zf_chown b:zf_mv b:zf_rm + +# Load zsh/system, if necessary +[[ ${modules[zsh/system]} == 'loaded' ]] || zmodload zsh/system &> /dev/null + +# Global associative array for internal use +typeset -gA ZSHZ + +# Make sure ZSHZ_EXCLUDE_DIRS has been declared so that other scripts can +# simply append to it +(( ${+ZSHZ_EXCLUDE_DIRS} )) || typeset -gUa ZSHZ_EXCLUDE_DIRS + +# Determine if zsystem flock is available +zsystem supports flock &> /dev/null && ZSHZ[USE_FLOCK]=1 + +# Determine if `print -v' is supported +is-at-least 5.3.0 && ZSHZ[PRINTV]=1 + +############################################################ +# The Zsh-z Command +# +# Globals: +# ZSHZ +# ZSHZ_CASE +# ZSHZ_COMPLETION +# ZSHZ_DATA +# ZSHZ_DEBUG +# ZSHZ_EXCLUDE_DIRS +# ZSHZ_KEEP_DIRS +# ZSHZ_MAX_SCORE +# ZSHZ_OWNER +# +# Arguments: +# $* Command options and arguments +############################################################ +zshz() { + + # Don't use `emulate -L zsh' - it breaks PUSHD_IGNORE_DUPS + setopt LOCAL_OPTIONS NO_KSH_ARRAYS NO_SH_WORD_SPLIT EXTENDED_GLOB + (( ZSHZ_DEBUG )) && setopt LOCAL_OPTIONS WARN_CREATE_GLOBAL + + local REPLY + local -a lines + + # Allow the user to specify the datafile name in $ZSHZ_DATA (default: ~/.z) + # If the datafile is a symlink, it gets dereferenced + local datafile=${${ZSHZ_DATA:-${_Z_DATA:-${HOME}/.z}}:A} + + # If the datafile is a directory, print a warning and exit + if [[ -d $datafile ]]; then + print "ERROR: Zsh-z's datafile (${datafile}) is a directory." >&2 + exit + fi + + # Make sure that the datafile exists before attempting to read it or lock it + # for writing + [[ -f $datafile ]] || touch "$datafile" + + # Bail if we don't own the datafile and $ZSHZ_OWNER is not set + [[ -z ${ZSHZ_OWNER:-${_Z_OWNER}} && -f $datafile && ! -O $datafile ]] && + return + + # Load the datafile into an array and parse it + lines=( ${(f)"$(< $datafile)"} ) + # Discard entries that are incomplete or incorrectly formatted + lines=( ${(M)lines:#/*\|[[:digit:]]##[.,]#[[:digit:]]#\|[[:digit:]]##} ) + + ############################################################ + # Add a path to or remove one from the datafile + # + # Globals: + # ZSHZ + # ZSHZ_EXCLUDE_DIRS + # ZSHZ_OWNER + # + # Arguments: + # $1 Which action to perform (--add/--remove) + # $2 The path to add + ############################################################ + _zshz_add_or_remove_path() { + local action=${1} + shift + + if [[ $action == '--add' ]]; then + + # TODO: The following tasks are now handled by _agkozak_precmd. Dead code? + + # Don't add $HOME + [[ $* == $HOME ]] && return + + # Don't track directory trees excluded in ZSHZ_EXCLUDE_DIRS + local exclude + for exclude in ${(@)ZSHZ_EXCLUDE_DIRS:-${(@)_Z_EXCLUDE_DIRS}}; do + case $* in + ${exclude}|${exclude}/*) return ;; + esac + done + fi + + # A temporary file that gets copied over the datafile if all goes well + local tempfile="${datafile}.${RANDOM}" + + # See https://github.com/rupa/z/pull/199/commits/ed6eeed9b70d27c1582e3dd050e72ebfe246341c + if (( ZSHZ[USE_FLOCK] )); then + + local lockfd + + # Grab exclusive lock (released when function exits) + zsystem flock -f lockfd "$datafile" 2> /dev/null || return + + fi + + integer tmpfd + case $action in + --add) + exec {tmpfd}>|"$tempfile" # Open up tempfile for writing + _zshz_update_datafile $tmpfd "$*" + local ret=$? + ;; + --remove) + local xdir # Directory to be removed + + if (( ${ZSHZ_NO_RESOLVE_SYMLINKS:-${_Z_NO_RESOLVE_SYMLINKS}} )); then + [[ -d ${${*:-${PWD}}:a} ]] && xdir=${${*:-${PWD}}:a} + else + [[ -d ${${*:-${PWD}}:A} ]] && xdir=${${*:-${PWD}}:a} + fi + + local -a lines_to_keep + if (( ${+opts[-R]} )); then + # Prompt user before deleting entire database + if [[ $xdir == '/' ]] && ! read -q "?Delete entire Zsh-z database? "; then + print && return 1 + fi + # All of the lines that don't match the directory to be deleted + lines_to_keep=( ${lines:#${xdir}\|*} ) + # Or its subdirectories + lines_to_keep=( ${lines_to_keep:#${xdir%/}/**} ) + else + # All of the lines that don't match the directory to be deleted + lines_to_keep=( ${lines:#${xdir}\|*} ) + fi + if [[ $lines != "$lines_to_keep" ]]; then + lines=( $lines_to_keep ) + else + return 1 # The $PWD isn't in the datafile + fi + exec {tmpfd}>|"$tempfile" # Open up tempfile for writing + print -u $tmpfd -l -- $lines + local ret=$? + ;; + esac + + if (( tmpfd != 0 )); then + # Close tempfile + exec {tmpfd}>&- + fi + + if (( ret != 0 )); then + # Avoid clobbering the datafile if the write to tempfile failed + zf_rm -f "$tempfile" + return $ret + fi + + local owner + owner=${ZSHZ_OWNER:-${_Z_OWNER}} + + if (( ZSHZ[USE_FLOCK] )); then + zf_mv "$tempfile" "$datafile" 2> /dev/null || zf_rm -f "$tempfile" + + if [[ -n $owner ]]; then + zf_chown ${owner}:"$(id -ng ${owner})" "$datafile" + fi + else + if [[ -n $owner ]]; then + zf_chown "${owner}":"$(id -ng "${owner}")" "$tempfile" + fi + zf_mv -f "$tempfile" "$datafile" 2> /dev/null || zf_rm -f "$tempfile" + fi + + # In order to make z -x work, we have to disable zsh-z's adding + # to the database until the user changes directory and the + # chpwd_functions are run + if [[ $action == '--remove' ]]; then + ZSHZ[DIRECTORY_REMOVED]=1 + fi + } + + ############################################################ + # Read the curent datafile contents, update them, "age" them + # when the total rank gets high enough, and print the new + # contents to STDOUT. + # + # Globals: + # ZSHZ_KEEP_DIRS + # ZSHZ_MAX_SCORE + # + # Arguments: + # $1 File descriptor linked to tempfile + # $2 Path to be added to datafile + ############################################################ + _zshz_update_datafile() { + + integer fd=$1 + local -A rank time + + # Characters special to the shell (such as '[]') are quoted with backslashes + # See https://github.com/rupa/z/issues/246 + local add_path=${(q)2} + + local -a existing_paths + local now=$EPOCHSECONDS line dir + local path_field rank_field time_field count x + + rank[$add_path]=1 + time[$add_path]=$now + + # Remove paths from database if they no longer exist + for line in $lines; do + if [[ ! -d ${line%%\|*} ]]; then + for dir in ${(@)ZSHZ_KEEP_DIRS}; do + if [[ ${line%%\|*} == ${dir}/* || + ${line%%\|*} == $dir || + $dir == '/' ]]; then + existing_paths+=( $line ) + fi + done + else + existing_paths+=( $line ) + fi + done + lines=( $existing_paths ) + + for line in $lines; do + path_field=${(q)line%%\|*} + rank_field=${${line%\|*}#*\|} + time_field=${line##*\|} + + # When a rank drops below 1, drop the path from the database + (( rank_field < 1 )) && continue + + if [[ $path_field == $add_path ]]; then + rank[$path_field]=$rank_field + (( rank[$path_field]++ )) + time[$path_field]=$now + else + rank[$path_field]=$rank_field + time[$path_field]=$time_field + fi + (( count += rank_field )) + done + if (( count > ${ZSHZ_MAX_SCORE:-${_Z_MAX_SCORE:-9000}} )); then + # Aging + for x in ${(k)rank}; do + print -u $fd -- "$x|$(( 0.99 * rank[$x] ))|${time[$x]}" || return 1 + done + else + for x in ${(k)rank}; do + print -u $fd -- "$x|${rank[$x]}|${time[$x]}" || return 1 + done + fi + } + + ############################################################ + # The original tab completion method + # + # String processing is smartcase -- case-insensitive if the + # search string is lowercase, case-sensitive if there are + # any uppercase letters. Spaces in the search string are + # treated as *'s in globbing. Read the contents of the + # datafile and print matches to STDOUT. + # + # Arguments: + # $1 The string to be completed + ############################################################ + _zshz_legacy_complete() { + + local line path_field path_field_normalized + + # Replace spaces in the search string with asterisks for globbing + 1=${1//[[:space:]]/*} + + for line in $lines; do + + path_field=${line%%\|*} + + path_field_normalized=$path_field + if (( ZSHZ_TRAILING_SLASH )); then + path_field_normalized=${path_field%/}/ + fi + + # If the search string is all lowercase, the search will be case-insensitive + if [[ $1 == "${1:l}" && ${path_field_normalized:l} == *${~1}* ]]; then + print -- $path_field + # Otherwise, case-sensitive + elif [[ $path_field_normalized == *${~1}* ]]; then + print -- $path_field + fi + + done + # TODO: Search strings with spaces in them are currently treated case- + # insensitively. + } + + ############################################################ + # `print' or `printf' to REPLY + # + # Variable assignment through command substitution, of the + # form + # + # foo=$( bar ) + # + # requires forking a subshell; on Cygwin/MSYS2/WSL1 that can + # be surprisingly slow. Zsh-z avoids doing that by printing + # values to the variable REPLY. Since Zsh v5.3.0 that has + # been possible with `print -v'; for earlier versions of the + # shell, the values are placed on the editing buffer stack + # and then `read' into REPLY. + # + # Globals: + # ZSHZ + # + # Arguments: + # Options and parameters for `print' + ############################################################ + _zshz_printv() { + # NOTE: For a long time, ZSH's `print -v' had a tendency + # to mangle multibyte strings: + # + # https://www.zsh.org/mla/workers/2020/msg00307.html + # + # The bug was fixed in late 2020: + # + # https://github.com/zsh-users/zsh/commit/b6ba74cd4eaec2b6cb515748cf1b74a19133d4a4#diff-32bbef18e126b837c87b06f11bfc61fafdaa0ed99fcb009ec53f4767e246b129 + # + # In order to support shells with the bug, we must use a form of `printf`, + # which does not exhibit the undesired behavior. See + # + # https://www.zsh.org/mla/workers/2020/msg00308.html + + if (( ZSHZ[PRINTV] )); then + builtin print -v REPLY -f %s $@ + else + builtin print -z $@ + builtin read -rz REPLY + fi + } + + ############################################################ + # If matches share a common root, find it, and put it in + # REPLY for _zshz_output to use. + # + # Arguments: + # $1 Name of associative array of matches and ranks + ############################################################ + _zshz_find_common_root() { + local -a common_matches + local x short + + common_matches=( ${(@Pk)1} ) + + for x in ${(@)common_matches}; do + if [[ -z $short ]] || (( $#x < $#short )) || [[ $x != ${short}/* ]]; then + short=$x + fi + done + + [[ $short == '/' ]] && return + + for x in ${(@)common_matches}; do + [[ $x != $short* ]] && return + done + + _zshz_printv -- $short + } + + ############################################################ + # Calculate a common root, if there is one. Then do one of + # the following: + # + # 1) Print a list of completions in frecent order; + # 2) List them (z -l) to STDOUT; or + # 3) Put a common root or best match into REPLY + # + # Globals: + # ZSHZ_UNCOMMON + # + # Arguments: + # $1 Name of an associative array of matches and ranks + # $2 The best match or best case-insensitive match + # $3 Whether to produce a completion, a list, or a root or + # match + ############################################################ + _zshz_output() { + + local match_array=$1 match=$2 format=$3 + local common k x + local -a descending_list output + local -A output_matches + + output_matches=( ${(Pkv)match_array} ) + + _zshz_find_common_root $match_array + common=$REPLY + + case $format in + + completion) + for k in ${(@k)output_matches}; do + _zshz_printv -f "%.2f|%s" ${output_matches[$k]} $k + descending_list+=( ${(f)REPLY} ) + REPLY='' + done + descending_list=( ${${(@On)descending_list}#*\|} ) + print -l $descending_list + ;; + + list) + local path_to_display + for x in ${(k)output_matches}; do + if (( ${output_matches[$x]} )); then + path_to_display=$x + (( ZSHZ_TILDE )) && + path_to_display=${path_to_display/#${HOME}/\~} + _zshz_printv -f "%-10d %s\n" ${output_matches[$x]} $path_to_display + output+=( ${(f)REPLY} ) + REPLY='' + fi + done + if [[ -n $common ]]; then + (( ZSHZ_TILDE )) && common=${common/#${HOME}/\~} + (( $#output > 1 )) && printf "%-10s %s\n" 'common:' $common + fi + # -lt + if (( $+opts[-t] )); then + for x in ${(@On)output}; do + print -- $x + done + # -lr + elif (( $+opts[-r] )); then + for x in ${(@on)output}; do + print -- $x + done + # -l + else + for x in ${(@on)output}; do + print $x + done + fi + ;; + + *) + if (( ! ZSHZ_UNCOMMON )) && [[ -n $common ]]; then + _zshz_printv -- $common + else + _zshz_printv -- ${(P)match} + fi + ;; + esac + } + + ############################################################ + # Match a pattern by rank, time, or a combination of the + # two, and output the results as completions, a list, or a + # best match. + # + # Globals: + # ZSHZ + # ZSHZ_CASE + # ZSHZ_KEEP_DIRS + # ZSHZ_OWNER + # + # Arguments: + # #1 Pattern to match + # $2 Matching method (rank, time, or [default] frecency) + # $3 Output format (completion, list, or [default] store + # in REPLY + ############################################################ + _zshz_find_matches() { + setopt LOCAL_OPTIONS NO_EXTENDED_GLOB + + local fnd=$1 method=$2 format=$3 + + local -a existing_paths + local line dir path_field rank_field time_field rank dx escaped_path_field + local -A matches imatches + local best_match ibest_match hi_rank=-9999999999 ihi_rank=-9999999999 + + # Remove paths from database if they no longer exist + for line in $lines; do + if [[ ! -d ${line%%\|*} ]]; then + for dir in ${(@)ZSHZ_KEEP_DIRS}; do + if [[ ${line%%\|*} == ${dir}/* || + ${line%%\|*} == $dir || + $dir == '/' ]]; then + existing_paths+=( $line ) + fi + done + else + existing_paths+=( $line ) + fi + done + lines=( $existing_paths ) + + for line in $lines; do + path_field=${line%%\|*} + rank_field=${${line%\|*}#*\|} + time_field=${line##*\|} + + case $method in + rank) rank=$rank_field ;; + time) (( rank = time_field - EPOCHSECONDS )) ;; + *) + # Frecency routine + (( dx = EPOCHSECONDS - time_field )) + rank=$(( 10000 * rank_field * (3.75/((0.0001 * dx + 1) + 0.25)) )) + ;; + esac + + # Use spaces as wildcards + local q=${fnd//[[:space:]]/\*} + + # If $ZSHZ_TRAILING_SLASH is set, use path_field with a trailing slash for matching. + local path_field_normalized=$path_field + if (( ZSHZ_TRAILING_SLASH )); then + path_field_normalized=${path_field%/}/ + fi + + # If $ZSHZ_CASE is 'ignore', be case-insensitive. + # + # If it's 'smart', be case-insensitive unless the string to be matched + # includes capital letters. + # + # Otherwise, the default behavior of Zsh-z is to match case-sensitively if + # possible, then to fall back on a case-insensitive match if possible. + if [[ $ZSHZ_CASE == 'smart' && ${1:l} == $1 && + ${path_field_normalized:l} == ${~q:l} ]]; then + imatches[$path_field]=$rank + elif [[ $ZSHZ_CASE != 'ignore' && $path_field_normalized == ${~q} ]]; then + matches[$path_field]=$rank + elif [[ $ZSHZ_CASE != 'smart' && ${path_field_normalized:l} == ${~q:l} ]]; then + imatches[$path_field]=$rank + fi + + # Escape characters that would cause "invalid subscript" errors + # when accessing the associative array. + escaped_path_field=${path_field//'\'/'\\'} + escaped_path_field=${escaped_path_field//'`'/'\`'} + escaped_path_field=${escaped_path_field//'('/'\('} + escaped_path_field=${escaped_path_field//')'/'\)'} + escaped_path_field=${escaped_path_field//'['/'\['} + escaped_path_field=${escaped_path_field//']'/'\]'} + + if (( matches[$escaped_path_field] )) && + (( matches[$escaped_path_field] > hi_rank )); then + best_match=$path_field + hi_rank=${matches[$escaped_path_field]} + elif (( imatches[$escaped_path_field] )) && + (( imatches[$escaped_path_field] > ihi_rank )); then + ibest_match=$path_field + ihi_rank=${imatches[$escaped_path_field]} + ZSHZ[CASE_INSENSITIVE]=1 + fi + done + + # Return 1 when there are no matches + [[ -z $best_match && -z $ibest_match ]] && return 1 + + if [[ -n $best_match ]]; then + _zshz_output matches best_match $format + elif [[ -n $ibest_match ]]; then + _zshz_output imatches ibest_match $format + fi + } + + # THE MAIN ROUTINE + + local -A opts + + zparseopts -E -D -A opts -- \ + -add \ + -complete \ + c \ + e \ + h \ + -help \ + l \ + r \ + R \ + t \ + x + + if [[ $1 == '--' ]]; then + shift + elif [[ -n ${(M)@:#-*} && -z $compstate ]]; then + print "Improper option(s) given." + _zshz_usage + return 1 + fi + + local opt output_format method='frecency' fnd prefix req + + for opt in ${(k)opts}; do + case $opt in + --add) + [[ ! -d $* ]] && return 1 + local dir + # Cygwin and MSYS2 have a hard time with relative paths expressed from / + if [[ $OSTYPE == (cygwin|msys) && $PWD == '/' && $* != /* ]]; then + set -- "/$*" + fi + if (( ${ZSHZ_NO_RESOLVE_SYMLINKS:-${_Z_NO_RESOLVE_SYMLINKS}} )); then + dir=${*:a} + else + dir=${*:A} + fi + _zshz_add_or_remove_path --add "$dir" + return + ;; + --complete) + if [[ -s $datafile && ${ZSHZ_COMPLETION:-frecent} == 'legacy' ]]; then + _zshz_legacy_complete "$1" + return + fi + output_format='completion' + ;; + -c) [[ $* == ${PWD}/* || $PWD == '/' ]] || prefix="$PWD " ;; + -h|--help) + _zshz_usage + return + ;; + -l) output_format='list' ;; + -r) method='rank' ;; + -t) method='time' ;; + -x) + # Cygwin and MSYS2 have a hard time with relative paths expressed from / + if [[ $OSTYPE == (cygwin|msys) && $PWD == '/' && $* != /* ]]; then + set -- "/$*" + fi + _zshz_add_or_remove_path --remove $* + return + ;; + esac + done + req="$*" + fnd="$prefix$*" + + [[ -n $fnd && $fnd != "$PWD " ]] || { + [[ $output_format != 'completion' ]] && output_format='list' + } + + ######################################################### + # If $ZSHZ_ECHO == 1, display paths as you jump to them. + # If it is also the case that $ZSHZ_TILDE == 1, display + # the home directory as a tilde. + ######################################################### + _zshz_echo() { + if (( ZSHZ_ECHO )); then + if (( ZSHZ_TILDE )); then + print ${PWD/#${HOME}/\~} + else + print $PWD + fi + fi + } + + if [[ ${@: -1} == /* ]] && (( ! $+opts[-e] && ! $+opts[-l] )); then + # cd if possible; echo the new path if $ZSHZ_ECHO == 1 + [[ -d ${@: -1} ]] && builtin cd ${@: -1} && _zshz_echo && return + fi + + # With option -c, make sure query string matches beginning of matches; + # otherwise look for matches anywhere in paths + + # zpm-zsh/colors has a global $c, so we'll avoid math expressions here + if [[ ! -z ${(tP)opts[-c]} ]]; then + _zshz_find_matches "$fnd*" $method $output_format + else + _zshz_find_matches "*$fnd*" $method $output_format + fi + + local ret2=$? + + local cd + cd=$REPLY + + # New experimental "uncommon" behavior + # + # If the best choice at this point is something like /foo/bar/foo/bar, and the # search pattern is `bar', go to /foo/bar/foo/bar; but if the search pattern + # is `foo', go to /foo/bar/foo + if (( ZSHZ_UNCOMMON )) && [[ -n $cd ]]; then + if [[ -n $cd ]]; then + + # In the search pattern, replace spaces with * + local q=${fnd//[[:space:]]/\*} + q=${q%/} # Trailing slash has to be removed + + # As long as the best match is not case-insensitive + if (( ! ZSHZ[CASE_INSENSITIVE] )); then + # Count the number of characters in $cd that $q matches + local q_chars=$(( ${#cd} - ${#${cd//${~q}/}} )) + # Try dropping directory elements from the right; stop when it affects + # how many times the search pattern appears + until (( ( ${#cd:h} - ${#${${cd:h}//${~q}/}} ) != q_chars )); do + cd=${cd:h} + done + + # If the best match is case-insensitive + else + local q_chars=$(( ${#cd} - ${#${${cd:l}//${~${q:l}}/}} )) + until (( ( ${#cd:h} - ${#${${${cd:h}:l}//${~${q:l}}/}} ) != q_chars )); do + cd=${cd:h} + done + fi + + ZSHZ[CASE_INSENSITIVE]=0 + fi + fi + + if (( ret2 == 0 )) && [[ -n $cd ]]; then + if (( $+opts[-e] )); then # echo + (( ZSHZ_TILDE )) && cd=${cd/#${HOME}/\~} + print -- "$cd" + else + # cd if possible; echo the new path if $ZSHZ_ECHO == 1 + [[ -d $cd ]] && builtin cd "$cd" && _zshz_echo + fi + else + # if $req is a valid path, cd to it; echo the new path if $ZSHZ_ECHO == 1 + if ! (( $+opts[-e] || $+opts[-l] )) && [[ -d $req ]]; then + builtin cd "$req" && _zshz_echo + else + return $ret2 + fi + fi +} + +alias ${ZSHZ_CMD:-${_Z_CMD:-z}}='zshz 2>&1' + +############################################################ +# precmd - add path to datafile unless `z -x' has just been +# run +# +# Globals: +# ZSHZ +############################################################ +_zshz_precmd() { + # Do not add PWD to datafile when in HOME directory, or + # if `z -x' has just been run + [[ $PWD == "$HOME" ]] || (( ZSHZ[DIRECTORY_REMOVED] )) && return + + # Don't track directory trees excluded in ZSHZ_EXCLUDE_DIRS + local exclude + for exclude in ${(@)ZSHZ_EXCLUDE_DIRS:-${(@)_Z_EXCLUDE_DIRS}}; do + case $PWD in + ${exclude}|${exclude}/*) return ;; + esac + done + + # It appears that forking a subshell is so slow in Windows that it is better + # just to add the PWD to the datafile in the foreground + if [[ $OSTYPE == (cygwin|msys) ]]; then + zshz --add "$PWD" + else + (zshz --add "$PWD" &) + fi + + # See https://github.com/rupa/z/pull/247/commits/081406117ea42ccb8d159f7630cfc7658db054b6 + : $RANDOM +} + +############################################################ +# chpwd +# +# When the $PWD is removed from the datafile with `z -x', +# Zsh-z refrains from adding it again until the user has +# left the directory. +# +# Globals: +# ZSHZ +############################################################ +_zshz_chpwd() { + ZSHZ[DIRECTORY_REMOVED]=0 +} + +autoload -Uz add-zsh-hook + +add-zsh-hook precmd _zshz_precmd +add-zsh-hook chpwd _zshz_chpwd + +############################################################ +# Completion +############################################################ + +# Standarized $0 handling +# (See https://github.com/agkozak/Zsh-100-Commits-Club/blob/master/Zsh-Plugin-Standard.adoc) +0=${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}} +0=${${(M)0:#/*}:-$PWD/$0} + +(( ${fpath[(ie)${0:A:h}]} <= ${#fpath} )) || fpath=( "${0:A:h}" "${fpath[@]}" ) + +############################################################ +# zsh-z functions +############################################################ +ZSHZ[FUNCTIONS]='_zshz_usage + _zshz_add_or_remove_path + _zshz_update_datafile + _zshz_legacy_complete + _zshz_printv + _zshz_find_common_root + _zshz_output + _zshz_find_matches + zshz + _zshz_precmd + _zshz_chpwd + _zshz' + +############################################################ +# Enable WARN_NESTED_VAR for functions listed in +# ZSHZ[FUNCTIONS] +############################################################ +(( ZSHZ_DEBUG )) && () { + if is-at-least 5.4.0; then + local x + for x in ${=ZSHZ[FUNCTIONS]}; do + functions -W $x + done + fi +} + +############################################################ +# Unload function +# +# See https://github.com/agkozak/Zsh-100-Commits-Club/blob/master/Zsh-Plugin-Standard.adoc#unload-fun +# +# Globals: +# ZSHZ +# ZSHZ_CMD +############################################################ +zsh-z_plugin_unload() { + emulate -L zsh + + add-zsh-hook -D precmd _zshz_precmd + add-zsh-hook -d chpwd _zshz_chpwd + + local x + for x in ${=ZSHZ[FUNCTIONS]}; do + (( ${+functions[$x]} )) && unfunction $x + done + + unset ZSHZ + + fpath=( "${(@)fpath:#${0:A:h}}" ) + + (( ${+aliases[${ZSHZ_CMD:-${_Z_CMD:-z}}]} )) && + unalias ${ZSHZ_CMD:-${_Z_CMD:-z}} + + unfunction $0 +} + +# vim: fdm=indent:ts=2:et:sts=2:sw=2: diff --git a/plugins/z/z.sh b/plugins/z/z.sh deleted file mode 100644 index 67f504e27..000000000 --- a/plugins/z/z.sh +++ /dev/null @@ -1,267 +0,0 @@ -# Copyright (c) 2009 rupa deadwyler. Licensed under the WTFPL license, Version 2 - -# maintains a jump-list of the directories you actually use -# -# INSTALL: -# * put something like this in your .bashrc/.zshrc: -# . /path/to/z.sh -# * cd around for a while to build up the db -# * PROFIT!! -# * optionally: -# set $_Z_CMD in .bashrc/.zshrc to change the command (default z). -# set $_Z_DATA in .bashrc/.zshrc to change the datafile (default ~/.z). -# set $_Z_MAX_SCORE lower to age entries out faster (default 9000). -# set $_Z_NO_RESOLVE_SYMLINKS to prevent symlink resolution. -# set $_Z_NO_PROMPT_COMMAND if you're handling PROMPT_COMMAND yourself. -# set $_Z_EXCLUDE_DIRS to an array of directories to exclude. -# set $_Z_OWNER to your username if you want use z while sudo with $HOME kept -# -# USE: -# * z foo # cd to most frecent dir matching foo -# * z foo bar # cd to most frecent dir matching foo and bar -# * z -r foo # cd to highest ranked dir matching foo -# * z -t foo # cd to most recently accessed dir matching foo -# * z -l foo # list matches instead of cd -# * z -e foo # echo the best match, don't cd -# * z -c foo # restrict matches to subdirs of $PWD -# * z -x # remove the current directory from the datafile -# * z -h # show a brief help message - -[ -d "${_Z_DATA:-$HOME/.z}" ] && { - echo "ERROR: z.sh's datafile (${_Z_DATA:-$HOME/.z}) is a directory." -} - -_z() { - - local datafile="${_Z_DATA:-$HOME/.z}" - - # if symlink, dereference - [ -h "$datafile" ] && datafile=$(readlink "$datafile") - - # bail if we don't own ~/.z and $_Z_OWNER not set - [ -z "$_Z_OWNER" -a -f "$datafile" -a ! -O "$datafile" ] && return - - _z_dirs () { - [ -f "$datafile" ] || return - - local line - while read line; do - # only count directories - [ -d "${line%%\|*}" ] && echo "$line" - done < "$datafile" - return 0 - } - - # add entries - if [ "$1" = "--add" ]; then - shift - - # $HOME and / aren't worth matching - [ "$*" = "$HOME" -o "$*" = '/' ] && return - - # don't track excluded directory trees - if [ ${#_Z_EXCLUDE_DIRS[@]} -gt 0 ]; then - local exclude - for exclude in "${_Z_EXCLUDE_DIRS[@]}"; do - case "$*" in "$exclude"*) return;; esac - done - fi - - # maintain the data file - local tempfile="$datafile.$RANDOM" - local score=${_Z_MAX_SCORE:-9000} - _z_dirs | awk -v path="$*" -v now="$(date +%s)" -v score=$score -F"|" ' - BEGIN { - rank[path] = 1 - time[path] = now - } - $2 >= 1 { - # drop ranks below 1 - if( $1 == path ) { - rank[$1] = $2 + 1 - time[$1] = now - } else { - rank[$1] = $2 - time[$1] = $3 - } - count += $2 - } - END { - if( count > score ) { - # aging - for( x in rank ) print x "|" 0.99*rank[x] "|" time[x] - } else for( x in rank ) print x "|" rank[x] "|" time[x] - } - ' 2>/dev/null >| "$tempfile" - # do our best to avoid clobbering the datafile in a race condition. - if [ $? -ne 0 -a -f "$datafile" ]; then - env rm -f "$tempfile" - else - [ "$_Z_OWNER" ] && chown $_Z_OWNER:"$(id -ng $_Z_OWNER)" "$tempfile" - env mv -f "$tempfile" "$datafile" || env rm -f "$tempfile" - fi - - # tab completion - elif [ "$1" = "--complete" -a -s "$datafile" ]; then - _z_dirs | awk -v q="$2" -F"|" ' - BEGIN { - q = substr(q, 3) - if( q == tolower(q) ) imatch = 1 - gsub(/ /, ".*", q) - } - { - if( imatch ) { - if( tolower($1) ~ q ) print $1 - } else if( $1 ~ q ) print $1 - } - ' 2>/dev/null - - else - # list/go - local echo fnd last list opt typ - while [ "$1" ]; do case "$1" in - --) while [ "$1" ]; do shift; fnd="$fnd${fnd:+ }$1";done;; - -*) opt=${1:1}; while [ "$opt" ]; do case ${opt:0:1} in - c) fnd="^$PWD $fnd";; - e) echo=1;; - h) echo "${_Z_CMD:-z} [-cehlrtx] args" >&2; return;; - l) list=1;; - r) typ="rank";; - t) typ="recent";; - x) sed -i -e "\:^${PWD}|.*:d" "$datafile";; - esac; opt=${opt:1}; done;; - *) fnd="$fnd${fnd:+ }$1";; - esac; last=$1; [ "$#" -gt 0 ] && shift; done - [ "$fnd" -a "$fnd" != "^$PWD " ] || list=1 - - # if we hit enter on a completion just go there - case "$last" in - # completions will always start with / - /*) [ -z "$list" -a -d "$last" ] && builtin cd "$last" && return;; - esac - - # no file yet - [ -f "$datafile" ] || return - - local cd - cd="$( < <( _z_dirs ) awk -v t="$(date +%s)" -v list="$list" -v typ="$typ" -v q="$fnd" -F"|" ' - function frecent(rank, time) { - # relate frequency and time - dx = t - time - return int(10000 * rank * (3.75/((0.0001 * dx + 1) + 0.25))) - } - function output(matches, best_match, common) { - # list or return the desired directory - if( list ) { - if( common ) { - printf "%-10s %s\n", "common:", common > "/dev/stderr" - } - cmd = "sort -n >&2" - for( x in matches ) { - if( matches[x] ) { - printf "%-10s %s\n", matches[x], x | cmd - } - } - } else { - if( common && !typ ) best_match = common - print best_match - } - } - function common(matches) { - # find the common root of a list of matches, if it exists - for( x in matches ) { - if( matches[x] && (!short || length(x) < length(short)) ) { - short = x - } - } - if( short == "/" ) return - for( x in matches ) if( matches[x] && index(x, short) != 1 ) { - return - } - return short - } - BEGIN { - gsub(" ", ".*", q) - hi_rank = ihi_rank = -9999999999 - } - { - if( typ == "rank" ) { - rank = $2 - } else if( typ == "recent" ) { - rank = $3 - t - } else rank = frecent($2, $3) - if( $1 ~ q ) { - matches[$1] = rank - } else if( tolower($1) ~ tolower(q) ) imatches[$1] = rank - if( matches[$1] && matches[$1] > hi_rank ) { - best_match = $1 - hi_rank = matches[$1] - } else if( imatches[$1] && imatches[$1] > ihi_rank ) { - ibest_match = $1 - ihi_rank = imatches[$1] - } - } - END { - # prefer case sensitive - if( best_match ) { - output(matches, best_match, common(matches)) - exit - } else if( ibest_match ) { - output(imatches, ibest_match, common(imatches)) - exit - } - exit(1) - } - ')" - - if [ "$?" -eq 0 ]; then - if [ "$cd" ]; then - if [ "$echo" ]; then echo "$cd"; else builtin cd "$cd"; fi - fi - else - return $? - fi - fi -} - -alias ${_Z_CMD:-z}='_z 2>&1' - -[ "$_Z_NO_RESOLVE_SYMLINKS" ] || _Z_RESOLVE_SYMLINKS="-P" - -if type compctl >/dev/null 2>&1; then - # zsh - [ "$_Z_NO_PROMPT_COMMAND" ] || { - # populate directory list, avoid clobbering any other precmds. - if [ "$_Z_NO_RESOLVE_SYMLINKS" ]; then - _z_precmd() { - (_z --add "${PWD:a}" &) - : $RANDOM - } - else - _z_precmd() { - (_z --add "${PWD:A}" &) - : $RANDOM - } - fi - [[ -n "${precmd_functions[(r)_z_precmd]}" ]] || { - precmd_functions[$(($#precmd_functions+1))]=_z_precmd - } - } - _z_zsh_tab_completion() { - # tab completion - local compl - read -l compl - reply=(${(f)"$(_z --complete "$compl")"}) - } - compctl -U -K _z_zsh_tab_completion _z -elif type complete >/dev/null 2>&1; then - # bash - # tab completion - complete -o filenames -C '_z --complete "$COMP_LINE"' ${_Z_CMD:-z} - [ "$_Z_NO_PROMPT_COMMAND" ] || { - # populate directory list. avoid clobbering other PROMPT_COMMANDs. - grep "_z --add" <<< "$PROMPT_COMMAND" >/dev/null || { - PROMPT_COMMAND="$PROMPT_COMMAND"$'\n''(_z --add "$(command pwd '$_Z_RESOLVE_SYMLINKS' 2>/dev/null)" 2>/dev/null &);' - } - } -fi diff --git a/plugins/zsh-interactive-cd/LICENSE b/plugins/zsh-interactive-cd/LICENSE new file mode 100644 index 000000000..40b3f8d7a --- /dev/null +++ b/plugins/zsh-interactive-cd/LICENSE @@ -0,0 +1,375 @@ +Copyright 2017-2018 Henry Chang + +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/plugins/zsh-interactive-cd/README.md b/plugins/zsh-interactive-cd/README.md index c8337fbc8..4bffbf04a 100644 --- a/plugins/zsh-interactive-cd/README.md +++ b/plugins/zsh-interactive-cd/README.md @@ -1,23 +1,15 @@ # zsh-interactive-cd -This plugin adds a fish-like interactive tab completion for the `cd` command. +## Demo -To use it, add `zsh-interactive-cd` to the plugins array of your zshrc file: -```zsh -plugins=(... zsh-interactive-cd) -``` +![demo](demo.gif) -![demo](https://user-images.githubusercontent.com/1441704/74360670-cb202900-4dc5-11ea-9734-f60caf726e85.gif) +## Installation + +1. Install [fzf](https://github.com/junegunn/fzf) by following its [installation instruction](https://github.com/junegunn/fzf#installation). + +2. Source `zsh-interactive-cd.plugin.zsh` in `.zshrc`. ## Usage Press tab for completion as usual, it'll launch fzf automatically. Check fzf’s [readme](https://github.com/junegunn/fzf#search-syntax) for more search syntax usage. - -## Requirements - -This plugin requires [fzf](https://github.com/junegunn/fzf). Install it by following -its [installation instructions](https://github.com/junegunn/fzf#installation). - -## Author - -[Henry Chang](https://github.com/changyuheng) diff --git a/plugins/zsh-interactive-cd/demo.gif b/plugins/zsh-interactive-cd/demo.gif new file mode 100644 index 000000000..3568ecf95 Binary files /dev/null and b/plugins/zsh-interactive-cd/demo.gif differ diff --git a/plugins/zsh-interactive-cd/zsh-interactive-cd.plugin.zsh b/plugins/zsh-interactive-cd/zsh-interactive-cd.plugin.zsh index b0520c239..0ae9d50a7 100644 --- a/plugins/zsh-interactive-cd/zsh-interactive-cd.plugin.zsh +++ b/plugins/zsh-interactive-cd/zsh-interactive-cd.plugin.zsh @@ -1,4 +1,10 @@ -# Copyright (c) 2017 Henry Chang +#!/usr/bin/env zsh +# +# Copyright 2017-2018 Henry Chang +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. __zic_fzf_prog() { [ -n "$TMUX_PANE" ] && [ "${FZF_TMUX:-0}" != 0 ] && [ ${LINES:-40} -gt 15 ] \ @@ -17,7 +23,7 @@ __zic_matched_subdir_list() { length=0 fi find -L "$dir" -mindepth 1 -maxdepth 1 -type d 2>/dev/null \ - | cut -b $(( ${length} + 2 ))- | sed '/^$/d' | while read -r line; do + | cut -b $(( ${length} + 2 ))- | command sed '/^$/d' | while read -r line; do if [[ "${line[1]}" == "." ]]; then continue fi @@ -32,13 +38,19 @@ __zic_matched_subdir_list() { seg=$(basename -- "$1") starts_with_dir=$( \ find -L "$dir" -mindepth 1 -maxdepth 1 -type d \ - 2>/dev/null | cut -b $(( ${length} + 2 ))- | sed '/^$/d' \ + 2>/dev/null | cut -b $(( ${length} + 2 ))- | command sed '/^$/d' \ | while read -r line; do if [[ "${seg[1]}" != "." && "${line[1]}" == "." ]]; then continue fi - if [[ "$line" == "$seg"* ]]; then - echo "$line" + if [ "$zic_case_insensitive" = "true" ]; then + if [[ "$line:u" == "$seg:u"* ]]; then + echo "$line" + fi + else + if [[ "$line" == "$seg"* ]]; then + echo "$line" + fi fi done ) @@ -46,19 +58,36 @@ __zic_matched_subdir_list() { echo "$starts_with_dir" else find -L "$dir" -mindepth 1 -maxdepth 1 -type d \ - 2>/dev/null | cut -b $(( ${length} + 2 ))- | sed '/^$/d' \ + 2>/dev/null | cut -b $(( ${length} + 2 ))- | command sed '/^$/d' \ | while read -r line; do if [[ "${seg[1]}" != "." && "${line[1]}" == "." ]]; then continue fi - if [[ "$line" == *"$seg"* ]]; then - echo "$line" + if [ "$zic_case_insensitive" = "true" ]; then + if [[ "$line:u" == *"$seg:u"* ]]; then + echo "$line" + fi + else + if [[ "$line" == *"$seg"* ]]; then + echo "$line" + fi fi done fi fi } +__zic_fzf_bindings() { + autoload is-at-least + fzf=$(__zic_fzf_prog) + + if $(is-at-least '0.21.0' $(${=fzf} --version)); then + echo 'shift-tab:up,tab:down,bspace:backward-delete-char/eof' + else + echo 'shift-tab:up,tab:down' + fi +} + _zic_list_generator() { __zic_matched_subdir_list "${(Q)@[-1]}" | sort } @@ -75,6 +104,7 @@ _zic_complete() { fi fzf=$(__zic_fzf_prog) + fzf_bindings=$(__zic_fzf_bindings) if [ $(echo $l | wc -l) -eq 1 ]; then matches=${(q)l} @@ -82,7 +112,7 @@ _zic_complete() { matches=$(echo $l \ | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} \ --reverse $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS \ - --bind 'shift-tab:up,tab:down'" ${=fzf} \ + --bind '${fzf_bindings}'" ${=fzf} \ | while read -r item; do echo -n "${(q)item} " done) @@ -144,5 +174,7 @@ zic-completion() { } zle -N zic-completion -bindkey -M emacs '^I' zic-completion -bindkey -M viins '^I' zic-completion +if [ -z $zic_custom_binding ]; then + zic_custom_binding='^I' +fi +bindkey "${zic_custom_binding}" zic-completion diff --git a/themes/af-magic.zsh-theme b/themes/af-magic.zsh-theme index 2ef9b02d7..70549d01f 100644 --- a/themes/af-magic.zsh-theme +++ b/themes/af-magic.zsh-theme @@ -6,11 +6,12 @@ # dashed separator size function afmagic_dashes { # check either virtualenv or condaenv variables - local python_env="${VIRTUAL_ENV:-$CONDA_DEFAULT_ENV}" + local python_env_dir="${VIRTUAL_ENV:-$CONDA_DEFAULT_ENV}" + local python_env="${python_env_dir##*/}" # if there is a python virtual environment and it is displayed in # the prompt, account for it when returning the number of dashes - if [[ -n "$python_env" && "$PS1" = \(* ]]; then + if [[ -n "$python_env" && "$PS1" = *\(${python_env}\)* ]]; then echo $(( COLUMNS - ${#python_env} - 3 )) else echo $COLUMNS diff --git a/themes/agnoster.zsh-theme b/themes/agnoster.zsh-theme index 5f4efe813..88854eccd 100644 --- a/themes/agnoster.zsh-theme +++ b/themes/agnoster.zsh-theme @@ -116,6 +116,17 @@ prompt_git() { prompt_segment green $CURRENT_FG fi + local ahead behind + ahead=$(git log --oneline @{upstream}.. 2>/dev/null) + behind=$(git log --oneline ..@{upstream} 2>/dev/null) + if [[ -n "$ahead" ]] && [[ -n "$behind" ]]; then + PL_BRANCH_CHAR=$'\u21c5' + elif [[ -n "$ahead" ]]; then + PL_BRANCH_CHAR=$'\u21b1' + elif [[ -n "$behind" ]]; then + PL_BRANCH_CHAR=$'\u21b0' + fi + if [[ -e "${repo_path}/BISECT_LOG" ]]; then mode=" " elif [[ -e "${repo_path}/MERGE_HEAD" ]]; then diff --git a/themes/amuse.zsh-theme b/themes/amuse.zsh-theme index 3f7ec0bc5..d787fdaa4 100644 --- a/themes/amuse.zsh-theme +++ b/themes/amuse.zsh-theme @@ -11,8 +11,14 @@ ZSH_THEME_RUBY_PROMPT_PREFIX="%{$fg_bold[red]%}‹" ZSH_THEME_RUBY_PROMPT_SUFFIX="›%{$reset_color%}" PROMPT=' -%{$fg_bold[green]%}%~%{$reset_color%}$(git_prompt_info) ⌚ %{$fg_bold[red]%}%*%{$reset_color%} +%{$fg_bold[green]%}%~%{$reset_color%}$(git_prompt_info)$(virtualenv_prompt_info) ⌚ %{$fg_bold[red]%}%*%{$reset_color%} $ ' RPROMPT='$(ruby_prompt_info)' +VIRTUAL_ENV_DISABLE_PROMPT=0 +ZSH_THEME_VIRTUAL_ENV_PROMPT_PREFIX=" %{$fg[green]%}🐍" +ZSH_THEME_VIRTUAL_ENV_PROMPT_SUFFIX="%{$reset_color%}" +ZSH_THEME_VIRTUALENV_PREFIX=$ZSH_THEME_VIRTUAL_ENV_PROMPT_PREFIX +ZSH_THEME_VIRTUALENV_SUFFIX=$ZSH_THEME_VIRTUAL_ENV_PROMPT_SUFFIX + diff --git a/themes/avit.zsh-theme b/themes/avit.zsh-theme index f90ba331b..1279ea919 100644 --- a/themes/avit.zsh-theme +++ b/themes/avit.zsh-theme @@ -82,4 +82,4 @@ ZSH_THEME_GIT_TIME_SINCE_COMMIT_NEUTRAL="%{$fg[white]%}" # LS colors, made with https://geoff.greer.fm/lscolors/ export LSCOLORS="exfxcxdxbxegedabagacad" export LS_COLORS='di=34;40:ln=35;40:so=32;40:pi=33;40:ex=31;40:bd=34;46:cd=34;43:su=0;41:sg=0;46:tw=0;42:ow=0;43:' -export GREP_COLOR='1;33' +export GREP_COLORS='mt=1;33' diff --git a/themes/frontcube.zsh-theme b/themes/frontcube.zsh-theme index f9488d0ac..de6348329 100644 --- a/themes/frontcube.zsh-theme +++ b/themes/frontcube.zsh-theme @@ -1,7 +1,7 @@ PROMPT=' %{$fg_bold[gray]%}%~%{$fg_bold[blue]%}%{$fg_bold[blue]%} % %{$reset_color%} -%{$fg[green]%}➞ %{$reset_color%' +%{$fg[green]%}➞ %{$reset_color%}' RPROMPT='$(git_prompt_info) $(ruby_prompt_info)' diff --git a/themes/mlh.zsh-theme b/themes/mlh.zsh-theme index baff3fb63..c059bf850 100644 --- a/themes/mlh.zsh-theme +++ b/themes/mlh.zsh-theme @@ -47,6 +47,10 @@ if [ -z "$MLH_SHELL_SYMBOL" ]; then MLH_SHELL_SYMBOL="$ " fi +if [ -z "$MLH_SHELL_SYMBOL_ROOT" ]; then + MLH_SHELL_SYMBOL_ROOT="# " +fi + # colors USER_COLOR="%F{001}" DEVICE_COLOR="%F{033}" @@ -83,7 +87,11 @@ exit_code() { } prompt_end() { - printf "\n$MLH_SHELL_SYMBOL" + if [ "$UID" -eq 0 ]; then + printf "\n$MLH_SHELL_SYMBOL_ROOT" + else + printf "\n$MLH_SHELL_SYMBOL" + fi } # Set git_prompt_info text diff --git a/themes/refined.zsh-theme b/themes/refined.zsh-theme index 5e2de7a87..2b55cfb0c 100644 --- a/themes/refined.zsh-theme +++ b/themes/refined.zsh-theme @@ -11,11 +11,11 @@ # more about both of these fantastic two people here: # # Sindre Sorhus -# Github: https://github.com/sindresorhus +# GitHub: https://github.com/sindresorhus # Twitter: https://twitter.com/sindresorhus # # Julien Nicoulaud -# Github: https://github.com/nicoulaj +# GitHub: https://github.com/nicoulaj # Twitter: https://twitter.com/nicoulaj # # ------------------------------------------------------------------------------ diff --git a/tools/changelog.sh b/tools/changelog.sh index 6489a3cb2..1af74e42d 100755 --- a/tools/changelog.sh +++ b/tools/changelog.sh @@ -106,6 +106,9 @@ function parse-commit { message="${match[1]}" # remove CR characters (might be inserted in GitHub UI commit description form) message="${message//$'\r'/}" + # remove lines containing only whitespace + local nlnl=$'\n\n' + message="${message//$'\n'[[:space:]]##$'\n'/$nlnl}" # skip next paragraphs (separated by two newlines or more) message="${message%%$'\n\n'*}" # ... and replace newlines with spaces @@ -157,6 +160,89 @@ function parse-commit { fi } +################################ +# SUPPORTS HYPERLINKS FUNCTION # +################################ + +# The code for checking if a terminal supports hyperlinks is copied from install.sh + +# The [ -t 1 ] check only works when the function is not called from +# a subshell (like in `$(...)` or `(...)`, so this hack redefines the +# function at the top level to always return false when stdout is not +# a tty. +if [ -t 1 ]; then + is_tty() { + true + } +else + is_tty() { + false + } +fi + +# This function uses the logic from supports-hyperlinks[1][2], which is +# made by Kat Marchán (@zkat) and licensed under the Apache License 2.0. +# [1] https://github.com/zkat/supports-hyperlinks +# [2] https://crates.io/crates/supports-hyperlinks +# +# Copyright (c) 2021 Kat Marchán +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +supports_hyperlinks() { + # $FORCE_HYPERLINK must be set and be non-zero (this acts as a logic bypass) + if [ -n "$FORCE_HYPERLINK" ]; then + [ "$FORCE_HYPERLINK" != 0 ] + return $? + fi + + # If stdout is not a tty, it doesn't support hyperlinks + is_tty || return 1 + + # DomTerm terminal emulator (domterm.org) + if [ -n "$DOMTERM" ]; then + return 0 + fi + + # VTE-based terminals above v0.50 (Gnome Terminal, Guake, ROXTerm, etc) + if [ -n "$VTE_VERSION" ]; then + [ $VTE_VERSION -ge 5000 ] + return $? + fi + + # If $TERM_PROGRAM is set, these terminals support hyperlinks + case "$TERM_PROGRAM" in + Hyper|iTerm.app|terminology|WezTerm) return 0 ;; + esac + + # kitty supports hyperlinks + if [ "$TERM" = xterm-kitty ]; then + return 0 + fi + + # Windows Terminal also supports hyperlinks + if [ -n "$WT_SESSION" ]; then + return 0 + fi + + # Konsole supports hyperlinks, but it's an opt-in setting that can't be detected + # https://github.com/ohmyzsh/ohmyzsh/issues/10964 + # if [ -n "$KONSOLE_VERSION" ]; then + # return 0 + # fi + + return 1 +} + ############################# # RELEASE CHANGELOG DISPLAY # ############################# @@ -208,8 +294,14 @@ function display-release { local hash="${1:-$hash}" case "$output" in raw) printf '%s' "$hash" ;; - text) printf '\e[33m%s\e[0m' "$hash" ;; # red - md) printf '[`%s`](https://github.com/ohmyzsh/ohmyzsh/commit/%s)' "$hash" ;; + text) + local text="\e[33m$hash\e[0m"; # red + if supports_hyperlinks; then + printf "\e]8;;%s\a%s\e]8;;\a" "https://github.com/ohmyzsh/ohmyzsh/commit/$hash" $text; + else + echo $text; + fi ;; + md) printf '[`%s`](https://github.com/ohmyzsh/ohmyzsh/commit/%s)' "$hash" "$hash" ;; esac } @@ -272,7 +364,12 @@ function display-release { case "$output" in raw) printf '%s' "$subject" ;; # In text mode, highlight (#) and dim text between `backticks` - text) sed -E $'s|#([0-9]+)|\e[32m#\\1\e[0m|g;s|`([^`]+)`|`\e[2m\\1\e[0m`|g' <<< "$subject" ;; + text) + if supports_hyperlinks; then + sed -E $'s|#([0-9]+)|\e]8;;https://github.com/ohmyzsh/ohmyzsh/issues/\\1\a\e[32m#\\1\e[0m\e]8;;\a|g' <<< "$subject" + else + sed -E $'s|#([0-9]+)|\e[32m#\\1\e[0m|g;s|`([^`]+)`|`\e[2m\\1\e[0m`|g' <<< "$subject" + fi ;; # In markdown mode, link to (#) issues md) sed -E 's|#([0-9]+)|[#\1](https://github.com/ohmyzsh/ohmyzsh/issues/\1)|g' <<< "$subject" ;; esac diff --git a/tools/check_for_upgrade.sh b/tools/check_for_upgrade.sh index 149500aa9..81c371b3f 100755 --- a/tools/check_for_upgrade.sh +++ b/tools/check_for_upgrade.sh @@ -21,10 +21,12 @@ zstyle -s ':omz:update' mode update_mode || { # Cancel update if: # - the automatic update is disabled. # - the current user doesn't have write permissions nor owns the $ZSH directory. +# - is not run from a tty # - git is unavailable on the system. if [[ "$update_mode" = disabled ]] \ || [[ ! -w "$ZSH" || ! -O "$ZSH" ]] \ - || ! command -v git &>/dev/null; then + || [[ ! -t 1 ]] \ + || ! command git --version 2>&1 >/dev/null; then unset update_mode return fi @@ -65,7 +67,7 @@ function is_update_available() { local remote_head remote_head=$( if (( ${+commands[curl]} )); then - curl -m 2 -fsSL -H 'Accept: application/vnd.github.v3.sha' $api_url 2>/dev/null + curl --connect-timeout 2 -fsSL -H 'Accept: application/vnd.github.v3.sha' $api_url 2>/dev/null elif (( ${+commands[wget]} )); then wget -T 2 -O- --header='Accept: application/vnd.github.v3.sha' $api_url 2>/dev/null elif (( ${+commands[fetch]} )); then @@ -93,7 +95,8 @@ function update_last_updated_file() { } function update_ohmyzsh() { - if ZSH="$ZSH" zsh -f "$ZSH/tools/upgrade.sh" --interactive; then + zstyle -s ':omz:update' verbose verbose_mode || verbose_mode=default + if ZSH="$ZSH" zsh -f "$ZSH/tools/upgrade.sh" -i -v $verbose_mode; then update_last_updated_file fi } diff --git a/tools/install.sh b/tools/install.sh index 1d9708406..4422ca5f3 100755 --- a/tools/install.sh +++ b/tools/install.sh @@ -16,6 +16,9 @@ # ZSH=~/.zsh sh install.sh # # Respects the following environment variables: +# ZDOTDIR - path to Zsh dotfiles directory (default: unset). See [1][2] +# [1] https://zsh.sourceforge.io/Doc/Release/Parameters.html#index-ZDOTDIR +# [2] https://zsh.sourceforge.io/Doc/Release/Files.html#index-ZDOTDIR_002c-use-of # ZSH - path to the Oh My Zsh repository folder (default: $HOME/.oh-my-zsh) # REPO - name of the GitHub repo to install from (default: ohmyzsh/ohmyzsh) # REMOTE - full remote URL of the git repo to install (default: GitHub via HTTPS) @@ -53,7 +56,14 @@ HOME="${HOME:-$(eval echo ~$USER)}" # Track if $ZSH was provided custom_zsh=${ZSH:+yes} -# Default settings +# Use $zdot to keep track of where the directory is for zsh dotfiles +# To check if $ZDOTDIR was provided, explicitly check for $ZDOTDIR +zdot="${ZDOTDIR:-$HOME}" + +# Default value for $ZSH +# a) if $ZDOTDIR is supplied and not $HOME: $ZDOTDIR/ohmyzsh +# b) otherwise, $HOME/.oh-my-zsh +[ "$ZDOTDIR" = "$HOME" ] || ZSH="${ZSH:-${ZDOTDIR:+$ZDOTDIR/ohmyzsh}}" ZSH="${ZSH:-$HOME/.oh-my-zsh}" REPO=${REPO:-snakewarhead/oh-my-zsh} REMOTE=${REMOTE:-https://github.com/${REPO}.git} @@ -72,6 +82,10 @@ command_exists() { user_can_sudo() { # Check if sudo is installed command_exists sudo || return 1 + # Termux can't run sudo, so we can detect it and exit the function early. + case "$PREFIX" in + *com.termux*) return 1 ;; + esac # The following command has 3 parts: # # 1. Run `sudo` with `-v`. Does the following: @@ -156,11 +170,17 @@ supports_hyperlinks() { return 0 fi - # Windows Terminal or Konsole also support hyperlinks - if [ -n "$WT_SESSION" ] || [ -n "$KONSOLE_VERSION" ]; then + # Windows Terminal also supports hyperlinks + if [ -n "$WT_SESSION" ]; then return 0 fi + # Konsole supports hyperlinks, but it's an opt-in setting that can't be detected + # https://github.com/ohmyzsh/ohmyzsh/issues/10964 + # if [ -n "$KONSOLE_VERSION" ]; then + # return 0 + # fi + return 1 } @@ -185,7 +205,7 @@ supports_truecolor() { fmt_link() { # $1: text, $2: url, $3: fallback mode if supports_hyperlinks; then - printf '\033]8;;%s\a%s\033]8;;\a\n' "$2" "$1" + printf '\033]8;;%s\033\\%s\033]8;;\033\\\n' "$2" "$1" return fi @@ -267,7 +287,7 @@ setup_ohmyzsh() { } ostype=$(uname) - if [ -z "${ostype%CYGWIN*}" ] && git --version | grep -q msysgit; then + if [ -z "${ostype%CYGWIN*}" ] && git --version | grep -Eq 'msysgit|windows'; then fmt_error "Windows/MSYS Git is not supported on Cygwin" fmt_error "Make sure the Cygwin git package is installed and is first on the \$PATH" exit 1 @@ -305,11 +325,11 @@ setup_zshrc() { echo "${FMT_BLUE}Looking for an existing zsh config...${FMT_RESET}" # Must use this exact name so uninstall.sh can find it - OLD_ZSHRC=~/.zshrc.pre-oh-my-zsh - if [ -f ~/.zshrc ] || [ -h ~/.zshrc ]; then + OLD_ZSHRC="$zdot/.zshrc.pre-oh-my-zsh" + if [ -f "$zdot/.zshrc" ] || [ -h "$zdot/.zshrc" ]; then # Skip this if the user doesn't want to replace an existing .zshrc if [ "$KEEP_ZSHRC" = yes ]; then - echo "${FMT_YELLOW}Found ~/.zshrc.${FMT_RESET} ${FMT_GREEN}Keeping...${FMT_RESET}" + echo "${FMT_YELLOW}Found ${zdot}/.zshrc.${FMT_RESET} ${FMT_GREEN}Keeping...${FMT_RESET}" return fi if [ -e "$OLD_ZSHRC" ]; then @@ -321,19 +341,24 @@ setup_zshrc() { fi mv "$OLD_ZSHRC" "${OLD_OLD_ZSHRC}" - echo "${FMT_YELLOW}Found old ~/.zshrc.pre-oh-my-zsh." \ + echo "${FMT_YELLOW}Found old .zshrc.pre-oh-my-zsh." \ "${FMT_GREEN}Backing up to ${OLD_OLD_ZSHRC}${FMT_RESET}" fi - echo "${FMT_YELLOW}Found ~/.zshrc.${FMT_RESET} ${FMT_GREEN}Backing up to ${OLD_ZSHRC}${FMT_RESET}" - mv ~/.zshrc "$OLD_ZSHRC" + echo "${FMT_YELLOW}Found ${zdot}/.zshrc.${FMT_RESET} ${FMT_GREEN}Backing up to ${OLD_ZSHRC}${FMT_RESET}" + mv "$zdot/.zshrc" "$OLD_ZSHRC" fi - echo "${FMT_GREEN}Using the Oh My Zsh template file and adding it to ~/.zshrc.${FMT_RESET}" + echo "${FMT_GREEN}Using the Oh My Zsh template file and adding it to $zdot/.zshrc.${FMT_RESET}" - # Replace $HOME path with '$HOME' in $ZSH variable in .zshrc file - omz=$(echo "$ZSH" | sed "s|^$HOME/|\$HOME/|") - sed "s|^export ZSH=.*$|export ZSH=\"${omz}\"|" "$ZSH/templates/zshrc.zsh-template" > ~/.zshrc-omztemp - mv -f ~/.zshrc-omztemp ~/.zshrc + # Modify $ZSH variable in .zshrc directory to use the literal $ZDOTDIR or $HOME + omz="$ZSH" + if [ -n "$ZDOTDIR" ] && [ "$ZDOTDIR" != "$HOME" ]; then + omz=$(echo "$omz" | sed "s|^$ZDOTDIR/|\$ZDOTDIR/|") + fi + omz=$(echo "$omz" | sed "s|^$HOME/|\$HOME/|") + + sed "s|^export ZSH=.*$|export ZSH=\"${omz}\"|" "$ZSH/templates/zshrc.zsh-template" > "$zdot/.zshrc-omztemp" + mv -f "$zdot/.zshrc-omztemp" "$zdot/.zshrc" # create ~/.zshrc_custom touch ~/.zshrc_custom @@ -404,9 +429,9 @@ EOF # We're going to change the default shell, so back up the current one if [ -n "$SHELL" ]; then - echo "$SHELL" > ~/.shell.pre-oh-my-zsh + echo "$SHELL" > "$zdot/.shell.pre-oh-my-zsh" else - grep "^$USER:" /etc/passwd | awk -F: '{print $7}' > ~/.shell.pre-oh-my-zsh + grep "^$USER:" /etc/passwd | awk -F: '{print $7}' > "$zdot/.shell.pre-oh-my-zsh" fi echo "Changing your shell to $zsh..." @@ -448,7 +473,7 @@ print_success() { printf '\n' printf '\n' printf "%s %s %s\n" "Before you scream ${FMT_BOLD}${FMT_YELLOW}Oh My Zsh!${FMT_RESET} look over the" \ - "$(fmt_code "$(fmt_link ".zshrc" "file://$HOME/.zshrc" --text)")" \ + "$(fmt_code "$(fmt_link ".zshrc" "file://$zdot/.zshrc" --text)")" \ "file to select plugins, themes, and options." printf '\n' printf '%s\n' "• Follow us on Twitter: $(fmt_link @ohmyzsh https://twitter.com/ohmyzsh)" @@ -503,6 +528,11 @@ EOF exit 1 fi + # Create ZDOTDIR folder structure if it doesn't exist + if [ -n "$ZDOTDIR" ]; then + mkdir -p "$ZDOTDIR" + fi + setup_ohmyzsh setup_zshrc setup_shell diff --git a/tools/require_tool.sh b/tools/require_tool.sh index 1fa77f77a..19c5f6fa9 100755 --- a/tools/require_tool.sh +++ b/tools/require_tool.sh @@ -107,7 +107,7 @@ usage() { NAME require_tool.sh - Ensure version of a tool is greater than the one expected -SYNOPSYS +SYNOPSIS require_tool.sh [ -h ] [ --help ] [ TOOL MIN_VERSION ] diff --git a/tools/uninstall.sh b/tools/uninstall.sh index 6a0e7b4c7..6e3df7aca 100644 --- a/tools/uninstall.sh +++ b/tools/uninstall.sh @@ -1,3 +1,15 @@ +if hash chsh >/dev/null 2>&1 && [ -f ~/.shell.pre-oh-my-zsh ]; then + old_shell=$(cat ~/.shell.pre-oh-my-zsh) + echo "Switching your shell back to '$old_shell':" + if chsh -s "$old_shell"; then + rm -f ~/.shell.pre-oh-my-zsh + else + echo "Could not change default shell. Change it manually by running chsh" + echo "or editing the /etc/passwd file." + exit + fi +fi + read -r -p "Are you sure you want to remove Oh My Zsh? [y/N] " confirmation if [ "$confirmation" != y ] && [ "$confirmation" != Y ]; then echo "Uninstall cancelled" @@ -25,16 +37,5 @@ else echo "No original zsh config found" fi -if hash chsh >/dev/null 2>&1 && [ -f ~/.shell.pre-oh-my-zsh ]; then - old_shell=$(cat ~/.shell.pre-oh-my-zsh) - echo "Switching your shell back to '$old_shell':" - if chsh -s "$old_shell"; then - rm -f ~/.shell.pre-oh-my-zsh - else - echo "Could not change default shell. Change it manually by running chsh" - echo "or editing the /etc/passwd file." - fi -fi - echo "Thanks for trying out Oh My Zsh. It's been uninstalled." echo "Don't forget to restart your terminal!" diff --git a/tools/upgrade.sh b/tools/upgrade.sh index 5eab74f83..6786bda32 100755 --- a/tools/upgrade.sh +++ b/tools/upgrade.sh @@ -1,5 +1,7 @@ #!/usr/bin/env zsh +local ret=0 # exit code + # Protect against running with shells other than zsh if [ -z "$ZSH_VERSION" ]; then exec zsh "$0" "$@" @@ -12,6 +14,23 @@ esac cd "$ZSH" +verbose_mode="default" +interactive=false + +while getopts "v:i" opt; do + case $opt in + v) + if [[ $OPTARG == default || $OPTARG == minimal || $OPTARG == silent ]]; then + verbose_mode=$OPTARG + else + echo "[oh-my-zsh] update verbosity '$OPTARG' is not valid" + echo "[oh-my-zsh] valid options are 'default', 'minimal' and 'silent'" + fi + ;; + i) interactive=true ;; + esac +done + # Use colors, but only if connected to a terminal # and that terminal supports them. @@ -78,11 +97,17 @@ supports_hyperlinks() { return 0 fi - # Windows Terminal or Konsole also support hyperlinks - if [ -n "$WT_SESSION" ] || [ -n "$KONSOLE_VERSION" ]; then + # Windows Terminal also supports hyperlinks + if [ -n "$WT_SESSION" ]; then return 0 fi + # Konsole supports hyperlinks, but it's an opt-in setting that can't be detected + # https://github.com/ohmyzsh/ohmyzsh/issues/10964 + # if [ -n "$KONSOLE_VERSION" ]; then + # return 0 + # fi + return 1 } @@ -107,7 +132,7 @@ supports_truecolor() { fmt_link() { # $1: text, $2: url, $3: fallback mode if supports_hyperlinks; then - printf '\033]8;;%s\a%s\033]8;;\a\n' "$2" "$1" + printf '\033]8;;%s\033\\%s\033]8;;\033\\\n' "$2" "$1" return fi @@ -197,7 +222,9 @@ git checkout -q "$branch" -- || exit 1 last_commit=$(git rev-parse "$branch") # Update Oh My Zsh -printf "${BLUE}%s${RESET}\n" "Updating Oh My Zsh" +if [[ $verbose_mode != silent ]]; then + printf "${BLUE}%s${RESET}\n" "Updating Oh My Zsh" +fi if LANG= git pull --quiet --rebase $remote $branch; then # Check if it was really updated or not if [[ "$(git rev-parse HEAD)" = "$last_commit" ]]; then @@ -209,24 +236,30 @@ if LANG= git pull --quiet --rebase $remote $branch; then git config oh-my-zsh.lastVersion "$last_commit" # Print changelog to the terminal - if [[ "$1" = --interactive ]]; then + if [[ $interactive == true && $verbose_mode == default ]]; then "$ZSH/tools/changelog.sh" HEAD "$last_commit" fi - printf "${BLUE}%s \`${BOLD}%s${RESET}${BLUE}\`${RESET}\n" "You can see the changelog with" "omz changelog" + if [[ $verbose_mode != silent ]]; then + printf "${BLUE}%s \`${BOLD}%s${RESET}${BLUE}\`${RESET}\n" "You can see the changelog with" "omz changelog" + fi fi - printf '%s %s__ %s %s %s %s %s__ %s\n' $RAINBOW $RESET - printf '%s ____ %s/ /_ %s ____ ___ %s__ __ %s ____ %s_____%s/ /_ %s\n' $RAINBOW $RESET - printf '%s / __ \\%s/ __ \\ %s / __ `__ \\%s/ / / / %s /_ / %s/ ___/%s __ \\ %s\n' $RAINBOW $RESET - printf '%s/ /_/ /%s / / / %s / / / / / /%s /_/ / %s / /_%s(__ )%s / / / %s\n' $RAINBOW $RESET - printf '%s\\____/%s_/ /_/ %s /_/ /_/ /_/%s\\__, / %s /___/%s____/%s_/ /_/ %s\n' $RAINBOW $RESET - printf '%s %s %s %s /____/ %s %s %s %s\n' $RAINBOW $RESET - printf '\n' - printf "${BLUE}%s${RESET}\n\n" "$message" - printf "${BLUE}${BOLD}%s %s${RESET}\n" "To keep up with the latest news and updates, follow us on Twitter:" "$(fmt_link @ohmyzsh https://twitter.com/ohmyzsh)" - printf "${BLUE}${BOLD}%s %s${RESET}\n" "Want to get involved in the community? Join our Discord:" "$(fmt_link "Discord server" https://discord.gg/ohmyzsh)" - printf "${BLUE}${BOLD}%s %s${RESET}\n" "Get your Oh My Zsh swag at:" "$(fmt_link "Planet Argon Shop" https://shop.planetargon.com/collections/oh-my-zsh)" + if [[ $verbose_mode == default ]]; then + printf '%s %s__ %s %s %s %s %s__ %s\n' $RAINBOW $RESET + printf '%s ____ %s/ /_ %s ____ ___ %s__ __ %s ____ %s_____%s/ /_ %s\n' $RAINBOW $RESET + printf '%s / __ \\%s/ __ \\ %s / __ `__ \\%s/ / / / %s /_ / %s/ ___/%s __ \\ %s\n' $RAINBOW $RESET + printf '%s/ /_/ /%s / / / %s / / / / / /%s /_/ / %s / /_%s(__ )%s / / / %s\n' $RAINBOW $RESET + printf '%s\\____/%s_/ /_/ %s /_/ /_/ /_/%s\\__, / %s /___/%s____/%s_/ /_/ %s\n' $RAINBOW $RESET + printf '%s %s %s %s /____/ %s %s %s %s\n' $RAINBOW $RESET + printf '\n' + printf "${BLUE}%s${RESET}\n\n" "$message" + printf "${BLUE}${BOLD}%s %s${RESET}\n" "To keep up with the latest news and updates, follow us on Twitter:" "$(fmt_link @ohmyzsh https://twitter.com/ohmyzsh)" + printf "${BLUE}${BOLD}%s %s${RESET}\n" "Want to get involved in the community? Join our Discord:" "$(fmt_link "Discord server" https://discord.gg/ohmyzsh)" + printf "${BLUE}${BOLD}%s %s${RESET}\n" "Get your Oh My Zsh swag at:" "$(fmt_link "Planet Argon Shop" https://shop.planetargon.com/collections/oh-my-zsh)" + elif [[ $verbose_mode == minimal ]]; then + printf "${BLUE}%s${RESET}\n" "$message" + fi else ret=$? printf "${RED}%s${RESET}\n" 'There was an error updating. Try again later?'