diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6668cd7ce..0c5f3acee 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -9,3 +9,5 @@ plugins/shell-proxy/ @septs plugins/universalarchive/ @Konfekt plugins/wp-cli/ @joshmedeski plugins/zoxide/ @ajeetdsouza +plugins/starship/ @axieax +plugins/dbt/ @msempere diff --git a/.github/workflows/installer.yml b/.github/workflows/installer.yml new file mode 100644 index 000000000..ac88d10b0 --- /dev/null +++ b/.github/workflows/installer.yml @@ -0,0 +1,55 @@ +name: Test and Deploy installer +on: + workflow_dispatch: {} + push: + paths: + - tools/install.sh + - .github/workflows/installer + - .github/workflows/installer.yml + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: false + +permissions: + contents: read # to checkout + +jobs: + test: + name: Test installer + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: + - ubuntu-latest + - macos-latest + steps: + - name: Set up git repository + uses: actions/checkout@v3 + - name: Install zsh + if: runner.os == 'Linux' + run: sudo apt-get update; sudo apt-get install zsh + - name: Test installer + run: sh ./tools/install.sh + + deploy: + name: Deploy installer in install.ohmyz.sh + if: github.ref == 'refs/heads/master' + runs-on: ubuntu-latest + environment: vercel + needs: + - test + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Install Vercel CLI + run: npm install -g vercel + - name: Setup project and deploy + env: + VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} + VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} + run: | + cp tools/install.sh .github/workflows/installer/install.sh + cd .github/workflows/installer + vc link --yes -t ${{ secrets.VERCEL_TOKEN }} + vc deploy --prod -t ${{ secrets.VERCEL_TOKEN }} diff --git a/.github/workflows/installer/.gitignore b/.github/workflows/installer/.gitignore new file mode 100644 index 000000000..f66fce310 --- /dev/null +++ b/.github/workflows/installer/.gitignore @@ -0,0 +1 @@ +install.sh diff --git a/.github/workflows/installer/.vercelignore b/.github/workflows/installer/.vercelignore new file mode 100644 index 000000000..41b233364 --- /dev/null +++ b/.github/workflows/installer/.vercelignore @@ -0,0 +1,2 @@ +/* +!/install.sh diff --git a/.github/workflows/installer/vercel.json b/.github/workflows/installer/vercel.json new file mode 100644 index 000000000..8c5aec5e0 --- /dev/null +++ b/.github/workflows/installer/vercel.json @@ -0,0 +1,14 @@ +{ + "headers": [ + { + "source": "/((?!favicon.ico).*)", + "headers": [{ "key": "Content-Type", "value": "text/plain" }] + } + ], + "rewrites": [ + { + "source": "/((?!favicon.ico|install.sh).*)", + "destination": "/install.sh" + } + ] +} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8ee2df3d8..57403629c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -31,8 +31,6 @@ jobs: - name: Install zsh if: runner.os == 'Linux' run: sudo apt-get update; sudo apt-get install zsh - - name: Test installer - run: sh ./tools/install.sh - name: Check syntax run: | for file in ./oh-my-zsh.sh \ diff --git a/README.md b/README.md index 0e9f1b693..ac62288e4 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ 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) + - [Enable GNU ls in macOS and freeBSD systems](#enable-gnu-ls) - [Skip aliases](#skip-aliases) - [Getting Updates](#getting-updates) - [Updates verbosity](#updates-verbosity) @@ -305,6 +306,20 @@ 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/`. +### Enable GNU ls in macOS and freeBSD systems + + + +The default behaviour in Oh My Zsh is to use BSD `ls` in macOS and freeBSD systems. If GNU `ls` is installed +(as `gls` command), you can choose to use it instead. To do it, you can use zstyle-based config before +sourcing `oh-my-zsh.sh`: + +```zsh +zstyle ':omz:lib:theme-and-appearance' gnu-ls yes +``` + +_Note: this is not compatible with `DISABLE_LS_COLORS=true`_ + ### Skip aliases diff --git a/custom/example.zsh b/custom/example.zsh index c505a9673..21a8d8be7 100644 --- a/custom/example.zsh +++ b/custom/example.zsh @@ -1,10 +1,12 @@ -# You can put files here to add functionality separated per file, which -# will be ignored by git. -# Files on the custom/ directory will be automatically loaded by the init -# script, in alphabetical order. - -# For example: add yourself some shortcuts to projects you often work on. -# +# Put files in this folder to add your own custom functionality. +# See: https://github.com/ohmyzsh/ohmyzsh/wiki/Customization +# +# Files in the custom/ directory will be: +# - loaded automatically by the init script, in alphabetical order +# - loaded last, after all built-ins in the lib/ directory, to override them +# - ignored by git by default +# +# Example: add custom/shortcuts.zsh for shortcuts to your local projects +# # brainstormr=~/Projects/development/planetargon/brainstormr # cd $brainstormr -# diff --git a/custom/plugins/example/example.plugin.zsh b/custom/plugins/example/example.plugin.zsh index 406f27445..83611fe3f 100644 --- a/custom/plugins/example/example.plugin.zsh +++ b/custom/plugins/example/example.plugin.zsh @@ -1,2 +1,3 @@ # Add your own custom plugins in the custom/plugins directory. Plugins placed # here will override ones with the same name in the main plugins directory. +# See: https://github.com/ohmyzsh/ohmyzsh/wiki/Customization#overriding-and-adding-plugins diff --git a/custom/themes/example.zsh-theme b/custom/themes/example.zsh-theme index ef8f1c630..494d029e8 100644 --- a/custom/themes/example.zsh-theme +++ b/custom/themes/example.zsh-theme @@ -1,4 +1,6 @@ # Put your custom themes in this folder. +# See: https://github.com/ohmyzsh/ohmyzsh/wiki/Customization#overriding-and-adding-themes +# # Example: PROMPT="%{$fg[red]%}%n%{$reset_color%}@%{$fg[blue]%}%m %{$fg[yellow]%}%~ %{$reset_color%}%% " diff --git a/lib/cli.zsh b/lib/cli.zsh index ba3e39eb5..561c1b98b 100644 --- a/lib/cli.zsh +++ b/lib/cli.zsh @@ -11,7 +11,7 @@ function omz { # Subcommand functions start with _ so that they don't # appear as completion entries when looking for `omz` - (( $+functions[_omz::$command] )) || { + (( ${+functions[_omz::$command]} )) || { _omz::help return 1 } diff --git a/lib/functions.zsh b/lib/functions.zsh index 1d85ea38a..a252d0a33 100644 --- a/lib/functions.zsh +++ b/lib/functions.zsh @@ -5,7 +5,7 @@ function zsh_stats() { } function uninstall_oh_my_zsh() { - env ZSH="$ZSH" sh "$ZSH/tools/uninstall.sh" + command env ZSH="$ZSH" sh "$ZSH/tools/uninstall.sh" } function upgrade_oh_my_zsh() { diff --git a/lib/theme-and-appearance.zsh b/lib/theme-and-appearance.zsh index d8859b04c..585e969d8 100644 --- a/lib/theme-and-appearance.zsh +++ b/lib/theme-and-appearance.zsh @@ -20,10 +20,25 @@ if command diff --color /dev/null{,} &>/dev/null; then } fi - # Don't set ls coloring if disabled [[ "$DISABLE_LS_COLORS" != true ]] || return 0 +# 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 + function test-ls-args { local cmd="$1" # ls, gls, colorls, ... local args="${@[2,-1]}" # arguments except the first one @@ -50,7 +65,7 @@ case "$OSTYPE" in 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" ]] \ + zstyle -t ':omz:lib:theme-and-appearance' gnu-ls \ && test-ls-args gls --color \ && alias ls='gls --color=tty' ;; @@ -64,20 +79,3 @@ case "$OSTYPE" in 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/oh-my-zsh.sh b/oh-my-zsh.sh index e047d4834..a577c1f41 100644 --- a/oh-my-zsh.sh +++ b/oh-my-zsh.sh @@ -159,10 +159,10 @@ _omz_source() { zstyle -T ":omz:${context}" aliases || disable_aliases=1 # Back up alias names prior to sourcing - local -a aliases_pre galiases_pre + local -A aliases_pre galiases_pre if (( disable_aliases )); then - aliases_pre=("${(@k)aliases}") - galiases_pre=("${(@k)galiases}") + aliases_pre=("${(@kv)aliases}") + galiases_pre=("${(@kv)galiases}") fi # Source file from $ZSH_CUSTOM if it exists, otherwise from $ZSH @@ -174,10 +174,16 @@ _omz_source() { # 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}" + if (( #aliases_pre )); then + aliases=("${(@kv)aliases_pre}") + else + (( #aliases )) && unalias "${(@k)aliases}" + fi + if (( #galiases_pre )); then + galiases=("${(@kv)galiases_pre}") + else + (( #galiases )) && unalias "${(@k)galiases}" + fi fi } diff --git a/plugins/archlinux/README.md b/plugins/archlinux/README.md index fd772c61a..5e015dbaa 100644 --- a/plugins/archlinux/README.md +++ b/plugins/archlinux/README.md @@ -181,3 +181,4 @@ whether the package manager is installed, checked in the following order: - Ybalrid (Arthur Brainville) - ybalrid@ybalrid.info - Jeff M. Hubbard - jeffmhubbard@gmail.com - K. Harishankar(harishnkr) - hari2menon1234@gmail.com +- WH-2099 - wh2099@outlook.com \ No newline at end of file diff --git a/plugins/archlinux/archlinux.plugin.zsh b/plugins/archlinux/archlinux.plugin.zsh index 4f1364779..796ff7adf 100644 --- a/plugins/archlinux/archlinux.plugin.zsh +++ b/plugins/archlinux/archlinux.plugin.zsh @@ -23,30 +23,30 @@ alias pacfiles='pacman -F' alias pacls='pacman -Ql' alias pacown='pacman -Qo' alias pacupd="sudo pacman -Sy" -alias upgrade='sudo pacman -Syu' function paclist() { - # Based on https://bbs.archlinux.org/viewtopic.php?id=93683 - pacman -Qqe | \ - xargs -I '{}' \ - expac "${bold_color}% 20n ${fg_no_bold[white]}%d${reset_color}" '{}' + local pkgs=$(LC_ALL=C pacman -Qqe) + for pkg in ${(f)pkgs}; do + pacman -Qs --color=auto "^${pkg}\$" || break + done } function pacdisowned() { - local tmp db fs - tmp=${TMPDIR-/tmp}/pacman-disowned-$UID-$$ - db=$tmp/db - fs=$tmp/fs + local tmp_dir db fs + tmp_dir=$(mktemp --directory) + db=$tmp_dir/db + fs=$tmp_dir/fs - mkdir "$tmp" - trap 'rm -rf "$tmp"' EXIT + trap "rm -rf $tmp_dir" EXIT pacman -Qlq | sort -u > "$db" - find /bin /etc /lib /sbin /usr ! -name lost+found \ + find /etc /usr ! -name lost+found \ \( -type d -printf '%p/\n' -o -print \) | sort > "$fs" comm -23 "$fs" "$db" + + rm -rf $tmp_dir } alias pacmanallkeys='sudo pacman-key --refresh-keys' @@ -109,7 +109,6 @@ if (( $+commands[aura] )); then alias auupd="sudo aura -Sy" alias auupg='sudo sh -c "aura -Syu && aura -Au"' alias ausu='sudo sh -c "aura -Syu --no-confirm && aura -Au --no-confirm"' - alias upgrade='sudo aura -Syu' # extra bonus specially for aura alias auown="aura -Qqo" @@ -136,7 +135,6 @@ if (( $+commands[pacaur] )); then alias painsd='pacaur -S --asdeps' alias pamir='pacaur -Syy' alias paupd="pacaur -Sy" - alias upgrade='pacaur -Syu' fi if (( $+commands[trizen] )); then @@ -158,7 +156,6 @@ if (( $+commands[trizen] )); then alias trinsd='trizen -S --asdeps' alias trmir='trizen -Syy' alias trupd="trizen -Sy" - alias upgrade='trizen -Syu' fi if (( $+commands[yay] )); then @@ -180,5 +177,30 @@ if (( $+commands[yay] )); then alias yainsd='yay -S --asdeps' alias yamir='yay -Syy' alias yaupd="yay -Sy" - alias upgrade='yay -Syu' fi + +# Check Arch Linux PGP Keyring before System Upgrade to prevent failure. +function upgrade() { + echo ":: Checking Arch Linux PGP Keyring..." + local installedver="$(sudo pacman -Qi archlinux-keyring | grep -Po '(?<=Version : ).*')" + local currentver="$(sudo pacman -Si archlinux-keyring | grep -Po '(?<=Version : ).*')" + if [ $installedver != $currentver ]; then + echo " Arch Linux PGP Keyring is out of date." + echo " Updating before full system upgrade." + sudo pacman -Sy --needed --noconfirm archlinux-keyring + else + echo " Arch Linux PGP Keyring is up to date." + echo " Proceeding with full system upgrade." + fi + if (( $+commands[yay] )); then + yay -Syu + elif (( $+commands[trizen] )); then + trizen -Syu + elif (( $+commands[pacaur] )); then + pacaur -Syu + elif (( $+commands[aura] )); then + sudo aura -Syu + else + sudo pacman -Syu + fi +} diff --git a/plugins/autoenv/autoenv.plugin.zsh b/plugins/autoenv/autoenv.plugin.zsh index 229a8a834..2f84f0acf 100644 --- a/plugins/autoenv/autoenv.plugin.zsh +++ b/plugins/autoenv/autoenv.plugin.zsh @@ -17,9 +17,13 @@ if ! type autoenv_init >/dev/null; then /usr/local/bin /usr/share/autoenv-git ~/Library/Python/bin + .venv/bin + venv/bin + env/bin + .env/bin ) for d ( $install_locations ); do - if [[ -e $d/activate.sh ]]; then + if [[ -e $d/activate || -e $d/activate.sh ]]; then autoenv_dir=$d break fi @@ -29,13 +33,13 @@ if ! type autoenv_init >/dev/null; then # Look for Homebrew path as a last resort if [[ -z "$autoenv_dir" ]] && (( $+commands[brew] )); then d=$(brew --prefix)/opt/autoenv - if [[ -e $d/activate.sh ]]; then + if [[ -e $d/activate || -e $d/activate.sh ]]; then autoenv_dir=$d fi fi # Complain if autoenv is not installed - if [[ -z $autoenv_dir ]]; then + if [[ -z $autoenv_dir ]]; then cat <&2 -------- AUTOENV --------- Could not locate autoenv installation. @@ -46,7 +50,11 @@ END return 1 fi # Load autoenv - source $autoenv_dir/activate.sh + if [[ -e $autoenv_dir/activate ]]; then + source $autoenv_dir/activate + else + source $autoenv_dir/activate.sh + fi fi } [[ $? != 0 ]] && return $? diff --git a/plugins/aws/README.md b/plugins/aws/README.md index 846bf1414..9e1e055b8 100644 --- a/plugins/aws/README.md +++ b/plugins/aws/README.md @@ -1,7 +1,8 @@ # aws -This plugin provides completion support for [awscli](https://docs.aws.amazon.com/cli/latest/reference/index.html) +This plugin provides completion support for [awscli v2](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/index.html) and a few utilities to manage AWS profiles/regions and display them in the prompt. +[awscli v1](https://docs.aws.amazon.com/cli/latest/userguide/cliv2-migration.html) is no longer supported. To use it, add `aws` to the plugins array in your zshrc file. @@ -12,9 +13,9 @@ 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 sets `$AWS_PROFILE_REGION` for display in `aws_prompt_info`. + 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. +* `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. @@ -57,6 +58,8 @@ the current `$AWS_PROFILE` and `$AWS_REGION`. It uses four variables to control * ZSH_THEME_AWS_REGION_SUFFIX: sets the suffix of the AWS_REGION. Defaults to `>`. +* ZSH_THEME_AWS_DIVIDER: sets the divider between ZSH_THEME_AWS_PROFILE_SUFFIX and ZSH_THEME_AWS_REGION_PREFIX. Defaults to ` ` (single space). + ## Configuration [Configuration and credential file settings](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html) by AWS @@ -65,7 +68,7 @@ the current `$AWS_PROFILE` and `$AWS_REGION`. It uses four variables to control Source profile credentials in `~/.aws/credentials`: -``` +```ini [source-profile-name] aws_access_key_id = ... aws_secret_access_key = ... @@ -73,7 +76,7 @@ aws_secret_access_key = ... Role configuration in `~/.aws/config`: -``` +```ini [profile source-profile-name] mfa_serial = arn:aws:iam::111111111111:mfa/myuser region = us-east-1 diff --git a/plugins/aws/aws.plugin.zsh b/plugins/aws/aws.plugin.zsh index a379eaa18..c946515be 100644 --- a/plugins/aws/aws.plugin.zsh +++ b/plugins/aws/aws.plugin.zsh @@ -160,14 +160,39 @@ function aws_change_access_key() { return 1 fi - echo "Insert the credentials when asked." - asp "$1" || return 1 - AWS_PAGER="" aws iam create-access-key - AWS_PAGER="" aws configure --profile "$1" + local profile="$1" + # Get current access key + local original_aws_access_key_id="$(aws configure get aws_access_key_id --profile $profile)" - echo "You can now safely delete the old access key running \`aws iam delete-access-key --access-key-id ID\`" + asp "$profile" || return 1 + echo "Generating a new access key pair for you now." + if aws --no-cli-pager iam create-access-key; then + echo "Insert the newly generated credentials when asked." + aws --no-cli-pager configure --profile $profile + else + echo "Current access keys:" + aws --no-cli-pager iam list-access-keys + echo "Profile \"${profile}\" is currently using the $original_aws_access_key_id key. You can delete an old access key by running \`aws --profile $profile iam delete-access-key --access-key-id AccessKeyId\`" + return 1 + fi + + read -q "yn?Would you like to disable your previous access key (${original_aws_access_key_id}) now? " + case $yn in + [Yy]*) + echo -n "\nDisabling access key ${original_aws_access_key_id}..." + if aws --no-cli-pager iam update-access-key --access-key-id ${original_aws_access_key_id} --status Inactive; then + echo "done." + else + echo "\nFailed to disable ${original_aws_access_key_id} key." + fi + ;; + *) + echo "" + ;; + esac + echo "You can now safely delete the old access key by running \`aws --profile $profile iam delete-access-key --access-key-id ${original_aws_access_key_id}\`" echo "Your current keys are:" - AWS_PAGER="" aws iam list-access-keys + aws --no-cli-pager iam list-access-keys } function aws_regions() { @@ -198,13 +223,16 @@ compctl -K _aws_profiles asp acp aws_change_access_key function aws_prompt_info() { 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:=}" + + 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:=}" + + if [[ -n "$region" ]]; then + [[ -n "$_aws_to_show" ]] && _aws_to_show+="${ZSH_THEME_AWS_DIVIDER=" "}" + _aws_to_show+="${ZSH_THEME_AWS_REGION_PREFIX=""}" fi + echo "$_aws_to_show" } diff --git a/plugins/azure/azure.plugin.zsh b/plugins/azure/azure.plugin.zsh index 51b54dbc1..b33b0f805 100644 --- a/plugins/azure/azure.plugin.zsh +++ b/plugins/azure/azure.plugin.zsh @@ -1,4 +1,4 @@ -# AZ Get Subscritions +# AZ Get Subscriptions function azgs() { az account show --output tsv --query 'name' 2>/dev/null } @@ -18,10 +18,10 @@ compctl -K _az_subscriptions azss # Azure prompt function azure_prompt_info() { - [[ ! -f "${AZURE_CONFIG_DIR:-$HOME/.azure/azureProfile.json}" ]] && return + [[ ! -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}) + azgs=$(jq -r '.subscriptions[] | select(.isDefault==true) .name' "${AZURE_CONFIG_DIR:-$HOME/.azure}/azureProfile.json") echo "${ZSH_THEME_AZURE_PREFIX:=}" } @@ -31,11 +31,9 @@ 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 + # if so, we assume it's default way to install brew + if [[ ${commands[brew]:t2} == bin/brew ]]; then + _brew_prefix="${commands[brew]:h:h}" # remove trailing /bin/brew 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 diff --git a/plugins/dbt/README.md b/plugins/dbt/README.md new file mode 100644 index 000000000..e05d79cc3 --- /dev/null +++ b/plugins/dbt/README.md @@ -0,0 +1,29 @@ +# dbt plugin + +## Introduction + +The `dbt plugin` adds several aliases for useful [dbt](https://docs.getdbt.com/) commands and +[aliases](#aliases). + +To use it, add `dbt` to the plugins array of your zshrc file: + +``` +plugins=(... dbt) +``` + +## Aliases + +| Alias | Command | Description | +| ------ | ------------------------------------------------ | ---------------------------------------------------- | +| dbtlm | `dbt ls -s state:modified` | List modified models only | +| dbtrm | `dbt run -s state:modified` | Run modified models only | +| dbttm | `dbt test -m state:modified` | Test modified models only | +| dbtrtm | `dbtrm && dbttm` | Run and test modified models only | +| dbtrs | `dbt clean; dbt deps; dbt seed` | Re-seed data | +| dbtfrt | `dbtrs; dbt run --full-refresh; dbt test` | Perform a full fresh run with tests | +| dbtcds | `dbt docs generate; dbt docs serve` | Generate docs without compiling | +| dbtds | `dbt docs generate --no-compile; dbt docs serve` | Generate and serve docs skipping doc. re-compilation | + +## Maintainer + +### [msempere](https://github.com/msempere) diff --git a/plugins/dbt/dbt.plugin.zsh b/plugins/dbt/dbt.plugin.zsh new file mode 100644 index 000000000..6fcc2eecf --- /dev/null +++ b/plugins/dbt/dbt.plugin.zsh @@ -0,0 +1,23 @@ +# list modified models only +alias dbtlm="dbt ls -s state:modified" + +# run modified models only +alias dbtrm="dbt run -s state:modified" + +# test modified models only +alias dbttm="dbt test -m state:modified" + +# run and test modified models only +alias dbtrtm="dbtrm && dbttm" + +# re-seed data +alias dbtrs="dbt clean; dbt deps; dbt seed" + +# perform a full fresh run with tests +alias dbtfrt="dbtrs; dbt run --full-refresh; dbt test" + +# generate and serve docs +alias dbtcds="dbt docs generate; dbt docs serve" + +# generate and serve docs skipping doc. re-compilation +alias dbtds="dbt docs generate --no-compile; dbt docs serve" diff --git a/plugins/deno/README.md b/plugins/deno/README.md index 691318397..38f9f2033 100644 --- a/plugins/deno/README.md +++ b/plugins/deno/README.md @@ -4,16 +4,17 @@ This plugin sets up completion and aliases for [Deno](https://deno.land). ## Aliases -| Alias | Full command | -| ----- | ---------------- | -| db | deno bundle | -| dc | deno compile | -| dca | deno cache | -| dfmt | deno fmt | -| dh | deno help | -| dli | deno lint | -| drn | deno run | -| drA | deno run -A | -| drw | deno run --watch | -| dts | deno test | -| dup | deno upgrade | +| Alias | Full command | +| ----- | ------------------- | +| db | deno bundle | +| dc | deno compile | +| dca | deno cache | +| dfmt | deno fmt | +| dh | deno help | +| dli | deno lint | +| drn | deno run | +| drA | deno run -A | +| drw | deno run --watch | +| dru | deno run --unstable | +| dts | deno test | +| dup | deno upgrade | diff --git a/plugins/deno/deno.plugin.zsh b/plugins/deno/deno.plugin.zsh index 7708f84df..bf97d6f03 100644 --- a/plugins/deno/deno.plugin.zsh +++ b/plugins/deno/deno.plugin.zsh @@ -8,6 +8,7 @@ alias dli='deno lint' alias drn='deno run' alias drA='deno run -A' alias drw='deno run --watch' +alias dru='deno run --unstable' alias dts='deno test' alias dup='deno upgrade' diff --git a/plugins/dirhistory/dirhistory.plugin.zsh b/plugins/dirhistory/dirhistory.plugin.zsh index 7021fc03a..8d67c6188 100644 --- a/plugins/dirhistory/dirhistory.plugin.zsh +++ b/plugins/dirhistory/dirhistory.plugin.zsh @@ -19,15 +19,17 @@ export DIRHISTORY_SIZE=30 # Returns the element if the array was not empty, # otherwise returns empty string. function pop_past() { - typeset -g $1="${dirhistory_past[$#dirhistory_past]}" + setopt localoptions no_ksh_arrays if [[ $#dirhistory_past -gt 0 ]]; then + typeset -g $1="${dirhistory_past[$#dirhistory_past]}" dirhistory_past[$#dirhistory_past]=() fi } function pop_future() { - typeset -g $1="${dirhistory_future[$#dirhistory_future]}" + setopt localoptions no_ksh_arrays if [[ $#dirhistory_future -gt 0 ]]; then + typeset -g $1="${dirhistory_future[$#dirhistory_future]}" dirhistory_future[$#dirhistory_future]=() fi } @@ -35,6 +37,7 @@ function pop_future() { # Push a new element onto the end of dirhistory_past. If the size of the array # is >= DIRHISTORY_SIZE, the array is shifted function push_past() { + setopt localoptions no_ksh_arrays if [[ $#dirhistory_past -ge $DIRHISTORY_SIZE ]]; then shift dirhistory_past fi @@ -44,6 +47,7 @@ function push_past() { } function push_future() { + setopt localoptions no_ksh_arrays if [[ $#dirhistory_future -ge $DIRHISTORY_SIZE ]]; then shift dirhistory_future fi diff --git a/plugins/extract/README.md b/plugins/extract/README.md index ac4a8e197..c8d98b229 100644 --- a/plugins/extract/README.md +++ b/plugins/extract/README.md @@ -25,6 +25,7 @@ plugins=(... extract) | `cpio` | Cpio archive | | `deb` | Debian package | | `ear` | Enterprise Application aRchive | +| `exe` | Windows executable file | | `gz` | Gzip file | | `ipa` | iOS app package | | `ipsw` | iOS firmware file | @@ -52,9 +53,11 @@ plugins=(... extract) | `txz` | Tarball with lzma2 compression | | `tzst` | Tarball with zstd compression | | `war` | Web Application archive (Java-based) | +| `whl` | Python wheel file | | `xpi` | Mozilla XPI module file | | `xz` | LZMA2 archive | | `zip` | Zip archive | +| `zlib` | zlib archive | | `zst` | Zstandard file (zstd) | | `zpaq` | Zpaq file | diff --git a/plugins/extract/extract.plugin.zsh b/plugins/extract/extract.plugin.zsh index 34c080653..b7a823c9f 100644 --- a/plugins/extract/extract.plugin.zsh +++ b/plugins/extract/extract.plugin.zsh @@ -27,12 +27,20 @@ EOF fi local success=0 - local extract_dir="${1:t:r}" local file="$1" full_path="${1:A}" + local extract_dir="${1:t:r}" + + # If there's a file or directory with the same name as the archive + # add a random string to the end of the extract directory + if [[ -e "$extract_dir" ]]; then + local rnd="${(L)"${$(( [##36]$RANDOM*$RANDOM ))}":1:5}" + extract_dir="${extract_dir}-${rnd}" + fi # Create an extraction directory based on the file name command mkdir -p "$extract_dir" builtin cd -q "$extract_dir" + echo "extract: extracting to $extract_dir" >&2 case "${file:l}" in (*.tar.gz|*.tgz) @@ -75,9 +83,10 @@ EOF builtin cd -q ../data; extract ../data.tar.* builtin cd -q ..; command rm *.tar.* debian-binary ;; (*.zst) unzstd "$full_path" ;; - (*.cab) cabextract "$full_path" ;; + (*.cab|*.exe) cabextract "$full_path" ;; (*.cpio|*.obscpio) cpio -idmvF "$full_path" ;; (*.zpaq) zpaq x "$full_path" ;; + (*.zlib) zlib-flate -uncompress < "$full_path" > "${file:r}" ;; (*) echo "extract: '$file' cannot be extracted" >&2 success=1 ;; @@ -107,11 +116,13 @@ EOF 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 mv "${content[1]}" "$tmp_dir" \ && command rmdir "$extract_dir" \ - && command mv -f "$tmp_dir" "$extract_dir" - else - command mv -f "${content[1]}" . \ + && command mv "$tmp_dir" "$extract_dir" + # Otherwise, if the extracted folder name already exists in the current + # directory (because of a previous file / folder), keep the extract_dir + elif [[ ! -e "${content[1]:t}" ]]; then + command mv "${content[1]}" . \ && command rmdir "$extract_dir" fi elif [[ ${#content} -eq 0 ]]; then diff --git a/plugins/gcloud/gcloud.plugin.zsh b/plugins/gcloud/gcloud.plugin.zsh index 30f1dba8f..9c26aea10 100644 --- a/plugins/gcloud/gcloud.plugin.zsh +++ b/plugins/gcloud/gcloud.plugin.zsh @@ -14,6 +14,7 @@ if [[ -z "${CLOUDSDK_HOME}" ]]; then "/usr/lib/google-cloud-sdk" "/usr/lib64/google-cloud-sdk" "/opt/google-cloud-sdk" + "/opt/google-cloud-cli" "/opt/local/libexec/google-cloud-sdk" ) diff --git a/plugins/git/README.md b/plugins/git/README.md index 0895ce39c..bf4b19f39 100644 --- a/plugins/git/README.md +++ b/plugins/git/README.md @@ -116,6 +116,7 @@ plugins=(... git) | gloga | git log --oneline --decorate --graph --all | | glp | git log --pretty=\ | | gm | git merge | +| gms | git merge --squash | | gmom | git merge origin/$(git_main_branch) | | gmtl | git mergetool --no-prompt | | gmtlvim | git mergetool --no-prompt --tool=vimdiff | @@ -185,7 +186,7 @@ plugins=(... git) | 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 | +| gunwip | git rev-list --max-count=1 --format="%s" HEAD \| grep -q "\-\-wip\-\-" && git reset HEAD~1 | | gup | git pull --rebase | | gupv | git pull --rebase --verbose | | gupa | git pull --rebase --autostash | @@ -253,6 +254,7 @@ These features allow to pause a branch development and switch to another one (_" | work_in_progress | Echoes a warning if the current branch is a wip | | gwip | Commit wip branch | | gunwip | Uncommit wip branch | +| gunwipall | Uncommit `--wip--` commits recursively | ### Deprecated functions diff --git a/plugins/git/git.plugin.zsh b/plugins/git/git.plugin.zsh index ed17436e8..192124301 100644 --- a/plugins/git/git.plugin.zsh +++ b/plugins/git/git.plugin.zsh @@ -27,6 +27,20 @@ function work_in_progress() { command git -c log.showSignature=false log -n 1 2>/dev/null | grep -q -- "--wip--" && echo "WIP!!" } +# Same as `gunwip` but recursive +# "Unwips" all recent `--wip--` commits in loop until there is no left +function gunwipall() { + while true; do + commit_message=$(git rev-list --max-count=1 --format="%s" HEAD) + if [[ $commit_message =~ "--wip--" ]]; then + git reset "HEAD~1" + (( $? )) && return 1 + else + break + fi + done +} + # Check if main exists and use instead of master function git_main_branch() { command git rev-parse --git-dir &>/dev/null || return @@ -237,6 +251,7 @@ alias gmtl='git mergetool --no-prompt' alias gmtlvim='git mergetool --no-prompt --tool=vimdiff' alias gmum='git merge upstream/$(git_main_branch)' alias gma='git merge --abort' +alias gms="git merge --squash" alias gp='git push' alias gpd='git push --dry-run' @@ -311,7 +326,7 @@ alias gtv='git tag | sort -V' 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 --max-count=1 | grep -q -c "\--wip--" && git reset HEAD~1' +alias gunwip='git rev-list --max-count=1 --format="%s" HEAD | grep -q "\--wip--" && git reset HEAD~1' alias gup='git pull --rebase' alias gupv='git pull --rebase --verbose' alias gupa='git pull --rebase --autostash' diff --git a/plugins/jump/jump.plugin.zsh b/plugins/jump/jump.plugin.zsh index c2da1144e..829c9d9cb 100644 --- a/plugins/jump/jump.plugin.zsh +++ b/plugins/jump/jump.plugin.zsh @@ -35,12 +35,11 @@ marks() { max=${#link:t} fi done - local printf_markname_template="$(printf -- "%%%us " "$max")" + local printf_markname_template="$(printf -- "%%%us" "$max")" for link in $MARKPATH/{,.}*(@N); do - local markname="$fg[cyan]${link:t}$reset_color" + local markname="$fg[cyan]$(printf -- "$printf_markname_template" "${link:t}")$reset_color" local markpath="$fg[blue]$(readlink $link)$reset_color" - printf -- "$printf_markname_template" "$markname" - printf -- "-> %s\n" "$markpath" + printf -- "%s -> %s\n" "$markname" "$markpath" done } diff --git a/plugins/npm/README.md b/plugins/npm/README.md index 8eafc6d61..420dd710a 100644 --- a/plugins/npm/README.md +++ b/plugins/npm/README.md @@ -29,6 +29,7 @@ plugins=(... npm) | `npmI` | `npm init` | Run npm init | | `npmi` | `npm info` | Run npm info | | `npmSe` | `npm search` | Run npm search | +| `npmrd` | `npm run dev` | Run npm run dev | ## `npm install` / `npm uninstall` toggle diff --git a/plugins/npm/npm.plugin.zsh b/plugins/npm/npm.plugin.zsh index e0dcbf142..3cba18f6c 100644 --- a/plugins/npm/npm.plugin.zsh +++ b/plugins/npm/npm.plugin.zsh @@ -70,6 +70,9 @@ alias npmi="npm info" # Run npm search alias npmSe="npm search" +# Run npm run dev +alias npmrd="npm run dev" + npm_toggle_install_uninstall() { # Look up to the previous 2 history commands local line diff --git a/plugins/pipenv/README.md b/plugins/pipenv/README.md index ab1c1e442..4329feb32 100644 --- a/plugins/pipenv/README.md +++ b/plugins/pipenv/README.md @@ -23,6 +23,7 @@ This plugin provides some features to simplify the use of Pipenv while working o - `psh` is aliased to `pipenv shell` - `psy` is aliased to `pipenv sync` - `pu` is aliased to `pipenv uninstall` + - `pupd` is aliased to `pipenv update` - `pwh` is aliased to `pipenv --where` - `pvenv` is aliased to `pipenv --venv` - `ppy` is aliased to `pipenv --py` diff --git a/plugins/pipenv/pipenv.plugin.zsh b/plugins/pipenv/pipenv.plugin.zsh index 244bd6b7c..22d1a3131 100644 --- a/plugins/pipenv/pipenv.plugin.zsh +++ b/plugins/pipenv/pipenv.plugin.zsh @@ -47,6 +47,7 @@ alias prun="pipenv run" alias psh="pipenv shell" alias psy="pipenv sync" alias pu="pipenv uninstall" +alias pupd="pipenv update" alias pwh="pipenv --where" alias pvenv="pipenv --venv" alias ppy="pipenv --py" diff --git a/plugins/pyenv/README.md b/plugins/pyenv/README.md index b9ee937b7..f1ca3d288 100644 --- a/plugins/pyenv/README.md +++ b/plugins/pyenv/README.md @@ -10,6 +10,14 @@ To use it, add `pyenv` to the plugins array in your zshrc file: plugins=(... pyenv) ``` +If you receive a `Found pyenv, but it is badly configured.` error on startup, you may need to ensure that `pyenv` is initialized before the oh-my-zsh pyenv plugin is loaded. This can be achived by adding the following earlier in the `.zshrc` file than the `plugins=(...)` line: + +```zsh +export PYENV_ROOT="$HOME/.pyenv" +export PATH="$PYENV_ROOT/bin:$PATH" +eval "$(pyenv init --path)" +``` + ## Settings - `ZSH_PYENV_QUIET`: if set to `true`, the plugin will not print any messages if it diff --git a/plugins/rake-fast/rake-fast.plugin.zsh b/plugins/rake-fast/rake-fast.plugin.zsh index 19dab154b..86e5ed586 100644 --- a/plugins/rake-fast/rake-fast.plugin.zsh +++ b/plugins/rake-fast/rake-fast.plugin.zsh @@ -1,5 +1,28 @@ +# The version of the format of .rake_tasks. If the output of _rake_generate +# changes, incrementing this number will force it to regenerate +_rake_tasks_version=2 + _rake_does_task_list_need_generating () { - [[ ! -f .rake_tasks ]] || [[ Rakefile -nt .rake_tasks ]] || { _is_rails_app && _tasks_changed } + _rake_tasks_missing || _rake_tasks_version_changed || _rakefile_has_changes || { _is_rails_app && _tasks_changed } +} + +_rake_tasks_missing () { + [[ ! -f .rake_tasks ]] +} + +_rake_tasks_version_changed () { + local -a file_version + file_version=`head -n 1 .rake_tasks | sed "s/^version\://"` + + if ! [[ $file_version =~ '^[0-9]*$' ]]; then + return true + fi + + [[ $file_version -ne $_rake_tasks_version ]] +} + +_rakefile_has_changes () { + [[ Rakefile -nt .rake_tasks ]] } _is_rails_app () { @@ -20,7 +43,14 @@ _tasks_changed () { } _rake_generate () { - rake --silent --tasks | cut -d " " -f 2 | sed 's/\[.*\]//g' > .rake_tasks + echo "version:$_rake_tasks_version" > .rake_tasks + + rake --silent --tasks --all \ + | sed "s/^rake //" | sed "s/\:/\\\:/g" \ + | sed "s/\[[^]]*\]//g" \ + | sed "s/ *# /\:/" \ + | sed "s/\:$//" \ + >> .rake_tasks } _rake () { @@ -29,7 +59,10 @@ _rake () { echo "\nGenerating .rake_tasks..." >&2 _rake_generate fi - compadd $(cat .rake_tasks) + local -a rake_options + rake_options=("${(@f)$(cat .rake_tasks)}") + shift rake_options + _describe 'rake tasks' rake_options fi } compdef _rake rake diff --git a/plugins/ssh-agent/README.md b/plugins/ssh-agent/README.md index fa6a996d4..8c118e65b 100644 --- a/plugins/ssh-agent/README.md +++ b/plugins/ssh-agent/README.md @@ -99,6 +99,33 @@ ssh-add -K -c -a /run/user/1000/ssh-auth For valid `ssh-add` arguments run `ssh-add --help` or `man ssh-add`. +### Powerline 10k specific settings + +Powerline10k has an instant prompt setting that doesn't like when this plugin +writes to the console. Consider using the following settings if you're using +p10k (documented above): + +``` +zstyle :omz:plugins:ssh-agent quiet yes +zstyle :omz:plugins:ssh-agent lazy yes +``` + +### macOS specific settings + +macOS supports using passphrases stored in the keychain when adding identities +to the ssh-agent. + +``` +ssh-add --apple-use-keychain ~/.ssh/id_rsa ... +``` + + +This plugin can be configured to use the keychain when loading using the following: + +``` +zstyle :omz:plugins:ssh-agent ssh-add-args --apple-load-keychain +``` + ## Credits Based on code from Joseph M. Reagle: https://www.cygwin.com/ml/cygwin/2001-06/msg00537.html diff --git a/plugins/starship/README.md b/plugins/starship/README.md new file mode 100644 index 000000000..0e66c5294 --- /dev/null +++ b/plugins/starship/README.md @@ -0,0 +1,21 @@ +# starship plugin + +Initializes [starship prompt](https://starship.rs) - a minimal, blazing-fast and infinitely customizable cross-shell prompt. + +[Demo](https://user-images.githubusercontent.com/62098008/169764279-50b48262-9506-4651-ba89-f6611a88ebf0.mp4) + +[External repository](https://github.com/axieax/zsh-starship) for this zsh plugin. + +# Installation + +**Note:** you have to [install starship](https://starship.rs/guide/#%F0%9F%9A%80-installation) first. + +## [oh-my-zsh](https://github.com/ohmyzsh/ohmyzsh) + +Add `starship` to the plugins array in your `.zshrc` file: + +```zsh +plugins=(... starship) +``` + +## ⚠️ ENABLING THIS PLUGIN WILL UNSET YOUR ZSH_THEME VARIABLE diff --git a/plugins/starship/starship.plugin.zsh b/plugins/starship/starship.plugin.zsh new file mode 100644 index 000000000..8c5d9135e --- /dev/null +++ b/plugins/starship/starship.plugin.zsh @@ -0,0 +1,8 @@ +# ignore oh-my-zsh theme +unset ZSH_THEME + +if (( $+commands[starship] )); then + eval "$(starship init zsh)" +else + echo '[oh-my-zsh] starship not found, please install it from https://starship.rs' +fi diff --git a/plugins/z/LICENSE b/plugins/z/LICENSE index d1cca7ae5..6af13b9e0 100644 --- a/plugins/z/LICENSE +++ b/plugins/z/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018-2022 Alexandros Kozak +Copyright (c) 2018-2023 Alexandros Kozak Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/plugins/z/MANUAL.md b/plugins/z/MANUAL.md index dcca3c452..d367c3026 100644 --- a/plugins/z/MANUAL.md +++ b/plugins/z/MANUAL.md @@ -1,5 +1,9 @@ # Zsh-z +[![MIT License](img/mit_license.svg)](https://opensource.org/licenses/MIT) +![Zsh version 4.3.11 and higher](img/zsh_4.3.11_plus.svg) +[![GitHub stars](https://img.shields.io/github/stars/agkozak/zsh-z.svg)](https://github.com/agkozak/zsh-z/stargazers) + 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`. @@ -28,6 +32,10 @@ Zsh-z is a drop-in replacement for `rupa/z` and will, by default, use the same d
Here are the latest features and updates. +- April 27, 2023 + + Zsh-z now allows the user to specify the directory-changing command using the `ZSHZ_CD` environment variable (default: `builtin cd`; props @basnijholt). +- January 27, 2023 + + If the datafile directory specified by `ZSHZ_DATA` or `_Z_DATA` does not already exist, create it (props @mattmc3). - June 29, 2022 + Zsh-z is less likely to leave temporary files sitting around (props @mafredri). - June 27, 2022 @@ -118,13 +126,19 @@ Add the line to your `.zshrc`, somewhere above the line that says `antigen apply`. -### For [oh-my-zsh](http://ohmyz.sh/) users +### For [Oh My Zsh](http://ohmyz.sh/) users -Execute the following command: +Zsh-z is now included as part of Oh My Zsh! As long as you are using an up-to-date installation of Oh My Zsh, you can activate Zsh-z simply by adding `z` to your `plugins` array in your `.zshrc`, e.g., + + plugins=( git z ) + +It is as simple as that. + +If, however, you prefer always to use the latest version of Zsh-z from the `agkozak/zsh-z` repo, you may install it thus: 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 )`. +and activate it by adding `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 @@ -246,6 +260,7 @@ to install `zsh-z`. Zsh-z has environment variables (they all begin with `ZSHZ_`) that change its behavior if you set them; you can also keep your old ones if you have been using `rupa/z` (they begin with `_Z_`). * `ZSHZ_CMD` changes the command name (default: `z`) +* `ZSHZ_CD` specifies the default directory-changing command (default: `builtin cd`) * `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`) diff --git a/plugins/z/_z b/plugins/z/_z index 9891a52ed..a493f35ba 100644 --- a/plugins/z/_z +++ b/plugins/z/_z @@ -5,7 +5,7 @@ # # https://github.com/agkozak/zsh-z # -# Copyright (c) 2018-2022 Alexandros Kozak +# Copyright (c) 2018-2023 Alexandros Kozak # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal diff --git a/plugins/z/img/mit_license.svg b/plugins/z/img/mit_license.svg new file mode 100644 index 000000000..1c02079d7 --- /dev/null +++ b/plugins/z/img/mit_license.svg @@ -0,0 +1 @@ +licenselicenseMITMIT \ No newline at end of file diff --git a/plugins/z/img/zsh_4.3.11_plus.svg b/plugins/z/img/zsh_4.3.11_plus.svg new file mode 100644 index 000000000..f46d947d0 --- /dev/null +++ b/plugins/z/img/zsh_4.3.11_plus.svg @@ -0,0 +1 @@ +zshzsh4.3.11+4.3.11+ \ No newline at end of file diff --git a/plugins/z/z.plugin.zsh b/plugins/z/z.plugin.zsh index 209edfea7..60a630624 100644 --- a/plugins/z/z.plugin.zsh +++ b/plugins/z/z.plugin.zsh @@ -4,7 +4,7 @@ # # https://github.com/agkozak/zsh-z # -# Copyright (c) 2018-2022 Alexandros Kozak +# Copyright (c) 2018-2023 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 @@ -52,6 +52,7 @@ # ZSHZ_CASE -> if `ignore', pattern matching is case-insensitive; if `smart', # pattern matching is case-insensitive only when the pattern is all # lowercase +# ZSHZ_CD -> the directory-changing command that is used (default: builtin cd) # ZSHZ_CMD -> name of command (default: z) # ZSHZ_COMPLETION -> completion method (default: 'frecent'; 'legacy' for # alphabetic sorting) @@ -129,6 +130,7 @@ is-at-least 5.3.0 && ZSHZ[PRINTV]=1 # Globals: # ZSHZ # ZSHZ_CASE +# ZSHZ_CD # ZSHZ_COMPLETION # ZSHZ_DATA # ZSHZ_DEBUG @@ -149,9 +151,19 @@ zshz() { local REPLY local -a lines - # Allow the user to specify the datafile name in $ZSHZ_DATA (default: ~/.z) + # Allow the user to specify a custom datafile in $ZSHZ_DATA (or legacy $_Z_DATA) + local custom_datafile="${ZSHZ_DATA:-$_Z_DATA}" + + # If a datafile was provided as a standalone file without a directory path + # print a warning and exit + if [[ -n ${custom_datafile} && ${custom_datafile} != */* ]]; then + print "ERROR: You configured a custom Zsh-z datafile (${custom_datafile}), but have not specified its directory." >&2 + exit + fi + + # If the user specified a datafile, use that or default to ~/.z # If the datafile is a symlink, it gets dereferenced - local datafile=${${ZSHZ_DATA:-${_Z_DATA:-${HOME}/.z}}:A} + local datafile=${${custom_datafile:-$HOME/.z}:A} # If the datafile is a directory, print a warning and exit if [[ -d $datafile ]]; then @@ -161,7 +173,7 @@ zshz() { # Make sure that the datafile exists before attempting to read it or lock it # for writing - [[ -f $datafile ]] || touch "$datafile" + [[ -f $datafile ]] || { mkdir -p "${datafile:h}" && 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 ]] && @@ -620,7 +632,7 @@ zshz() { *) # Frecency routine (( dx = EPOCHSECONDS - time_field )) - rank=$(( 10000 * rank_field * (3.75/((0.0001 * dx + 1) + 0.25)) )) + rank=$(( 10000 * rank_field * (3.75/( (0.0001 * dx + 1) + 0.25)) )) ;; esac @@ -756,6 +768,26 @@ zshz() { [[ $output_format != 'completion' ]] && output_format='list' } + ######################################################### + # Allow the user to specify directory-changing command + # using $ZSHZ_CD (default: builtin cd). + # + # Globals: + # ZSHZ_CD + # + # Arguments: + # $* Path + ######################################################### + zshz_cd() { + setopt LOCAL_OPTIONS NO_WARN_CREATE_GLOBAL + + if [[ -z $ZSHZ_CD ]]; then + builtin cd "$*" + else + ${=ZSHZ_CD} "$*" + fi + } + ######################################################### # If $ZSHZ_ECHO == 1, display paths as you jump to them. # If it is also the case that $ZSHZ_TILDE == 1, display @@ -773,7 +805,7 @@ zshz() { 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 + [[ -d ${@: -1} ]] && zshz_cd ${@: -1} && _zshz_echo && return fi # With option -c, make sure query string matches beginning of matches; @@ -830,12 +862,12 @@ zshz() { print -- "$cd" else # cd if possible; echo the new path if $ZSHZ_ECHO == 1 - [[ -d $cd ]] && builtin cd "$cd" && _zshz_echo + [[ -d $cd ]] && zshz_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 + zshz_cd "$req" && _zshz_echo else return $ret2 fi @@ -900,9 +932,9 @@ add-zsh-hook chpwd _zshz_chpwd ############################################################ # 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} +# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html +0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}" +0="${${(M)0:#/*}:-$PWD/$0}" (( ${fpath[(ie)${0:A:h}]} <= ${#fpath} )) || fpath=( "${0:A:h}" "${fpath[@]}" ) diff --git a/themes/bureau.zsh-theme b/themes/bureau.zsh-theme index 698aa2ff8..e87a594cd 100644 --- a/themes/bureau.zsh-theme +++ b/themes/bureau.zsh-theme @@ -15,6 +15,7 @@ ZSH_THEME_GIT_PROMPT_BEHIND="%{$fg[magenta]%}▾%{$reset_color%}" ZSH_THEME_GIT_PROMPT_STAGED="%{$fg_bold[green]%}●%{$reset_color%}" ZSH_THEME_GIT_PROMPT_UNSTAGED="%{$fg_bold[yellow]%}●%{$reset_color%}" ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg_bold[red]%}●%{$reset_color%}" +ZSH_THEME_GIT_PROMPT_STASHED="(%{$fg_bold[blue]%}✹%{$reset_color%})" bureau_git_info () { local ref @@ -67,6 +68,12 @@ bureau_git_status() { } bureau_git_prompt() { + # ignore non git folders and hidden repos (adapted from lib/git.zsh) + if ! command git rev-parse --git-dir &> /dev/null \ + || [[ "$(command git config --get oh-my-zsh.hide-info 2>/dev/null)" == 1 ]]; then + return + fi + # check git information local gitinfo=$(bureau_git_info) if [[ -z "$gitinfo" ]]; then diff --git a/themes/half-life.zsh-theme b/themes/half-life.zsh-theme index c4d785126..2ad84ac83 100644 --- a/themes/half-life.zsh-theme +++ b/themes/half-life.zsh-theme @@ -89,5 +89,9 @@ ZSH_THEME_RUBY_PROMPT_PREFIX="with%F{red} " ZSH_THEME_RUBY_PROMPT_SUFFIX="%{$reset_color%}" ZSH_THEME_RVM_PROMPT_OPTIONS="v g" +# virtualenv prompt settings +ZSH_THEME_VIRTUALENV_PREFIX=" with%F{red} " +ZSH_THEME_VIRTUALENV_SUFFIX="%{$reset_color%}" + setopt prompt_subst -PROMPT="${purple}%n%{$reset_color%} in ${limegreen}%~%{$reset_color%}\$(ruby_prompt_info)\$vcs_info_msg_0_${orange} λ%{$reset_color%} " +PROMPT="${purple}%n%{$reset_color%} in ${limegreen}%~%{$reset_color%}\$(virtualenv_prompt_info)\$(ruby_prompt_info)\$vcs_info_msg_0_${orange} λ%{$reset_color%} " diff --git a/themes/robbyrussell.zsh-theme b/themes/robbyrussell.zsh-theme index 2fd5f2cdc..173e6d579 100644 --- a/themes/robbyrussell.zsh-theme +++ b/themes/robbyrussell.zsh-theme @@ -1,5 +1,5 @@ -PROMPT="%(?:%{$fg_bold[green]%}➜ :%{$fg_bold[red]%}➜ )" -PROMPT+=' %{$fg[cyan]%}%c%{$reset_color%} $(git_prompt_info)' +PROMPT="%(?:%{$fg_bold[green]%}➜ :%{$fg_bold[red]%}➜ ) %{$fg[cyan]%}%c%{$reset_color%}" +PROMPT+=' $(git_prompt_info)' ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[blue]%}git:(%{$fg[red]%}" ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} " diff --git a/tools/check_for_upgrade.sh b/tools/check_for_upgrade.sh index 81c371b3f..3210e4375 100755 --- a/tools/check_for_upgrade.sh +++ b/tools/check_for_upgrade.sh @@ -180,6 +180,7 @@ function has_typed_input() { # Check if there are updates available before proceeding if ! is_update_available; then + update_last_updated_file return fi