diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..416cfaac --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.zwc diff --git a/EXTENDED_CONFIGURATION.md b/EXTENDED_CONFIGURATION.md deleted file mode 100644 index 048f3bf2..00000000 --- a/EXTENDED_CONFIGURATION.md +++ /dev/null @@ -1,82 +0,0 @@ -# Powerlevel10k Extended Configuration - -Powerlevel10k has configuration options that Powerlevel9k doesn't. These options have `POWERLEVEL9K` -prefix just like the rest. - -`POWERLEVEL9K_VCS_MAX_SYNC_LATENCY_SECONDS (FLOAT) [default=0.05]` - -If it takes longer than this to fetch git repo status, display the prompt with a greyed out -vcs segment and fix it asynchronously when the results come it. - -`POWERLEVEL9K_VCS_BACKENDS (ARRAY) [default=(git)]` - -The list of VCS backends to use. Supported values are `git`, `svn` and `hg`. Note that adding -anything other than git will make prompt slower even when your current directory isn't a repo. - -`POWERLEVEL9K_GITSTATUS_DIR (STRING) [default=$POWERLEVEL9K_INSTALLATION_DIR/gitstatus]` - -Directory with gitstatus plugin. By default uses a copy bundled with Powerlevel10k. - -`POWERLEVEL9K_DISABLE_GITSTATUS (STRING) [default="false"]` - -If set to `"true"`, Powerlevel10k won't use its fast git backend and will fall back to -`vcs_info` like Powerlevel9k. - -`POWERLEVEL9K_MAX_CACHE_SIZE (INT) [default=10000]` - -The maximum number of elements that can be stored in the cache. When the cache grows over this -limit, it gets cleared. - -`POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY (INT) [default=-1]` - -Don't scan for dirty files in git repos with more files in the index than this. Instead, show -them with the "dirty" color (yellow by default) whether they are dirty or not. This makes git -prompt much faster on huge repositories. - -`POWERLEVEL9K_EXPERIMENTAL_TIME_REALTIME (STRING) [default="false"]` - -If set to `"true"`, `time` segment will update every second, turning into a realtime clock. -This option triggers a -[bug in completion menu](https://www.zsh.org/mla/workers//2019/msg00161.html) in zsh, and -another -[bug in history](https://github.com/bhilburn/powerlevel9k/commit/fb1ef540228ec7b4394cf2f6860137074c5838a6#commitcomment-32779672). -You can pick up a fix for the latter from -[a fork of zsh](https://github.com/romkatv/zsh/tree/gentle-reset-prompt). - -When using gitstatus, there is an extra state called `LOADING` that is used by `vcs` prompt -segment when it's waiting for git status in the background. You can define styling for this -state the same way as for the other states -- `CLEAN`, `UNTRACKED` and `MODIFIED`. You can -also define the icon and the text that will be used when `LOADING` state is triggered for a -git repository for which no prior status is known. If both `POWERLEVEL9K_VCS_LOADING_ICON` -and `POWERLEVEL9K_VCS_LOADING_TEXT` are empty, `vcs` segment in such cases won't be shown. - - * `POWERLEVEL9K_VCS_LOADING_ICON (STRING) [default=""]` - - Icon shown while waiting for git status for a repo for the first time. - * `POWERLEVEL9K_VCS_LOADING_TEXT (STRING) [default="loading"]` - - Text shown while waiting for git status for a repo for the first time. - * `POWERLEVEL9K_VCS_LOADING_BACKGROUND (STRING) [default="grey"]` - - Background color for `LOADING` state. - * `POWERLEVEL9K_VCS_LOADING_FOREGROUND (STRING) [default="$DEFAULT_COLOR"]` - - Foreground color for `LOADING` state. - * `POWERLEVEL9K_VCS_LOADING_VISUAL_IDENTIFIER_COLOR (STRING) [default=$POWERLEVEL9K_VCS_LOADING_FOREGROUND]` - - Foreground color for `POWERLEVEL9K_VCS_LOADING_ICON`. - -When using gitstatus, components of `vcs` segment can be colored individually by setting -`POWERLEVEL9K_VCS_${STATE}_${COMPONENT}FORMAT_FOREGROUND`. `${STATE}` should be one of `CLEAN`, -`UNTRACKED`, `MODIFIED` or `LOADING`. `${COMPONENT}` should be one of `REMOTE_URL`, `COMMIT`, -`BRANCH`, `TAG`, `REMOTE_BRANCH`, `STAGED`, `UNSTAGED`, `UNTRACKED`, `OUTGOING_CHANGES`, -`INCOMING_CHANGES`, `STASH` or `ACTION`. If -`POWERLEVEL9K_VCS_${STATE}_${COMPONENT}FORMAT_FOREGROUND` isn't set for some combination of -`${STATE}` and `${COMPONENT}`, the component is colored with -`POWERLEVEL9K_VCS_${COMPONENT}FORMAT_FOREGROUND`. If that one isn't set either, the component is -colored with `POWERLEVEL9K_VCS_${STATE}_FOREGROUND`. The fallback logic is consistent with -Powerlevel9k, meaning that your `vcs` prompt will look the same in Powerlevel10k and -Powerlevel9k if you don't define any `POWERLEVEL9K_VCS_${STATE}_${COMPONENT}_FOREGROUND` -parameters. Note that both the icon and the text in each component always have the same color. -There is currently no `POWERLEVEL9K_VCS_${STATE}_${COMPONENT}FORMAT_VISUAL_IDENTIFIER_COLOR`, -although it's easy to implement if desired. diff --git a/README.md b/README.md index 551a0ee7..af7c767f 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,12 @@ # Powerlevel10k -Powerlevel10k is a theme for ZSH. It's a backward-compatible modern reimplementation of -[Powerlevel9k](https://github.com/bhilburn/powerlevel9k) with lower latency, better -prompt responsiveness and scores of extra features. +Powerlevel10k is a theme for ZSH. It's fast, flexible and easy to install and configure. -Powerlevel10k can be used as a drop-in replacement for Powerlevel9k. When given the same -configuration options it will generate -[the same](#does-powerlevel10k-always-render-exactly-the-same-prompt-as-powerlevel9k-given-the-same-config) -prompt. It will be [much faster](#is-it-really-fast) though. +Powerlevel10k can be used as a [fast](#is-it-really-fast) drop-in replacement for +[Powerlevel9k](https://github.com/bhilburn/powerlevel9k). When given the same configuration options +it will generate the same prompt. -![p10k-lean](https://raw.githubusercontent.com/romkatv/powerlevel10k/master/config/p10k-lean.png) +![Powerlevel10k](https://raw.githubusercontent.com/romkatv/powerlevel10k/master/powerlevel10k.png) ## Table of Contents @@ -21,14 +18,21 @@ prompt. It will be [much faster](#is-it-really-fast) though. 1. [Zplug](#zplug) 1. [Zgen](#zgen) 1. [Antibody](#antibody) + 1. [Zplugin](#zplugin) 1. [Configuration](#configuration) 1. [For new users](#for-new-users) - 1. [For existing users](#for-existing-users) + 1. [For Powerlevel9k users](#for-powerlevel9k-users) 1. [Fonts](#fonts) + 1. [Recommended: Meslo Nerd Font patched for Powerlevel10k](#recommended-meslo-nerd-font-patched-for-powerlevel10k) 1. [Try it in Docker](#try-it-in-docker) -1. [Is it really faster?](#is-it-really-fast) +1. [Is it really fast?](#is-it-really-fast) 1. [License](#license) 1. [FAQ](#faq) + 1. [Why my icons and/or powerline symbols look bad?](#why-my-icons-andor-powerline-symbols-look-bad) + 1. [Why is my cursor in the wrong place?](#why-is-my-cursor-in-the-wrong-place) + 1. [Why is my right prompt wrapping around in a weird way?](#why-is-my-right-prompt-wrapping-around-in-a-weird-way) + 1. [I cannot install the recommended font. Help!](#i-cannot-install-the-recommended-font-help) + 1. [Why do I have a question mark symbol in my prompt? Is my font broken?](#why-do-i-have-a-question-mark-symbol-in-my-prompt-is-my-font-broken) 1. [Why does Powerlevel10k spawn extra processes?](#why-does-powerlevel10k-spawn-extra-processes) 1. [Are there configuration options that make Powerlevel10k slow?](#are-there-configuration-options-that-make-powerlevel10k-slow) 1. [Is Powerlevel10k fast to load?](#is-powerlevel10k-fast-to-load) @@ -42,7 +46,7 @@ prompt. It will be [much faster](#is-it-really-fast) though. ### Manual ```zsh -git clone https://github.com/romkatv/powerlevel10k.git ~/powerlevel10k +git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ~/powerlevel10k echo 'source ~/powerlevel10k/powerlevel10k.zsh-theme' >>! ~/.zshrc ``` @@ -69,7 +73,7 @@ somewhere after it. ### Zplug -Add `zplug romkatv/powerlevel10k, use:powerlevel10k.zsh-theme` to your `~/.zshrc`. +Add `zplug romkatv/powerlevel10k, as:theme, depth:1` to your `~/.zshrc`. ### Zgen @@ -79,50 +83,72 @@ Add `zgen load romkatv/powerlevel10k powerlevel10k` to your `~/.zshrc`. Add `antibody bundle romkatv/powerlevel10k` to your `~/.zshrc`. +### Zplugin + +Add `zplugin ice depth=1; zplugin light romkatv/powerlevel10k` to your `~/.zshrc`. + +The use of `depth` ice is optional. Other types of ice are neither recommended nor officially +supported by Powerlevel10k. + ## Configuration ### For new users On the first run Powerlevel10k configuration wizard will ask you a few questions and configure -your prompt. If it doesn't trigger automatically, type `p9k_configure`. +your prompt. If it doesn't trigger automatically, type `p10k configure`. -### For existing users +### For Powerlevel9k users If you've been using Powerlevel9k before, **do not remove the configuration options**. Powerlevel10k will pick them up and provide you with the same prompt UI you are used to. Powerlevel10k recognized all configuration options used by Powerlevel9k. See Powerlevel9k -[configuration guide](https://github.com/bhilburn/powerlevel9k#prompt-customization). +[configuration guide](https://github.com/Powerlevel9k/powerlevel9k/blob/master/README.md#prompt-customization). -To go beyond the functionality of Powerlevel9k, type `p9k_configure` and explore unique styles and -features Powerlevel10k has to offer. +To go beyond the functionality of Powerlevel9k, type `p10k configure` and explore the unique styles +and features Powerlevel10k has to offer. ## Fonts -Powerlevel10k doesn't require custom fonts but it can take advantage of them if they are available. +Powerlevel10k doesn't require custom fonts but can take advantage of them if they are available. It works well with [Nerd Fonts](https://github.com/ryanoasis/nerd-fonts), [Source Code Pro](https://github.com/adobe-fonts/source-code-pro), [Font Awesome](https://fontawesome.com/), [Powerline](https://github.com/powerline/fonts), and even the default system fonts. The full choice of style options is available only when using [Nerd Fonts](https://github.com/ryanoasis/nerd-fonts). -Overwhelmed? Try the beautiful and powerful Meslo from Nerd Fonts. Download these -[four ttf files](https://github.com/romkatv/dotfiles-public/tree/master/.local/share/fonts/NerdFonts), -double-click on each and press "Install". This will make `MesloLGS NF` font available to all -applications on your system. Configure your terminal to use `MesloLGS NF`: +### Recommended: Meslo Nerd Font patched for Powerlevel10k -- **iTerm2**: Open *iTerm2 → Preferences → Profiles → Text → Change Font* and set *Family* to `MesloLGS NF`. -- **Visual Studio Code**: Open *File → Preferences → Settings*, enter - `terminal.integrated.fontFamily` in the search box and set value to `MesloLGS NF`. -- **Windows Command Prompt**: Use - [this script](https://gist.github.com/romkatv/aa7a70fe656d8b655e3c324eb10f6a8b). -- **Linux/GNOME** (all terminals): Type this command: -```zsh -sudo apt install libglib2.0-bin -gsettings set org.gnome.desktop.interface monospace-font-name 'MesloLGS NF 11' -``` +Download these four ttf files: +- [MesloLGS NF Regular.ttf](https://github.com/romkatv/dotfiles-public/raw/master/.local/share/fonts/NerdFonts/MesloLGS%20NF%20Regular.ttf) +- [MesloLGS NF Bold.ttf](https://github.com/romkatv/dotfiles-public/raw/master/.local/share/fonts/NerdFonts/MesloLGS%20NF%20Bold.ttf) +- [MesloLGS NF Italic.ttf](https://github.com/romkatv/dotfiles-public/raw/master/.local/share/fonts/NerdFonts/MesloLGS%20NF%20Italic.ttf) +- [MesloLGS NF Bold Italic.ttf](https://github.com/romkatv/dotfiles-public/raw/master/.local/share/fonts/NerdFonts/MesloLGS%20NF%20Bold%20Italic.ttf) -(Using a different terminal and know how to set font for it? Share your knowledge by sending a PR -to expand the list!) +Double-click on each file and press "Install". This will make `MesloLGS NF` font available to all +applications on your system. Configure your terminal to use this font: + +- **iTerm2**: Open *iTerm2 → Preferences → Profiles → Text* and set *Font* to `MesloLGS NF`. +- **Hyper**: Open *Hyper → Edit → Preferences* and change the value of `fontFamily` under + `module.exports.config` to `MesloLGS NF`. +- **Visual Studio Code**: Open *File → Preferences → Settings*, enter + `terminal.integrated.fontFamily` in the search box and set the value to `MesloLGS NF`. +- **GNOME Terminal** (the default Ubuntu terminal): Open *Terminal → Preferences* and click on the + selected profile under *Profiles*. Check *Custom font* under *Text Appearance* and select + `MesloLGS NF Regular`. +- **Konsole**: Open *Settings → Edit Current Profile → Appearance*, click *Select Font* and select + `MesloLGS NF Regular`. +- **Tilix**: Open *Tilix → Preferences* and click on the selected profile under *Profiles*. Check + *Custom font* under *Text Appearance* and select `MesloLGS NF Regular`. +- **Windows Console Host** (the old thing): Click the icon in the top left corner, then + *Properties → Font* and set *Font* to `MesloLGS NF`. +- **Windows Terminal** (the new thing): Open *Settings* (`Ctrl+,`), search for `fontFace` and set + value to `MesloLGS NF` for every profile. +- **Termux**: Type `p10k configure` and answer `Yes` when asked whether to install *Meslo Nerd Font*. + +Run `p10k configure` to pick the best style for your new font. + +_Using a different terminal and know how to set font for it? Share your knowledge by sending a PR +to expand the list!_ ## Try it in Docker @@ -130,9 +156,9 @@ Try Powerlevel10k in Docker. You can safely make any changes to the file system the theme. Once you exit zsh, the image is deleted. ```zsh -docker run -e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 -e TERM -it --rm ubuntu bash -uexc ' - cd && apt update && apt install -y zsh git - git clone https://github.com/romkatv/powerlevel10k.git +docker run -e LANG=en_US.utf8 -e TERM -it --rm archlinux/base bash -uexc ' + pacman -Sy --noconfirm zsh git + git clone https://github.com/romkatv/powerlevel10k.git ~/powerlevel10k echo "source ~/powerlevel10k/powerlevel10k.zsh-theme" >>~/.zshrc cd ~/powerlevel10k exec zsh' @@ -173,6 +199,54 @@ covered by the same license. ## FAQ +### Why my icons and/or powerline symbols look bad? + +It's likely your font's fault. +[Install the recommended font](#recommended-meslo-nerd-font-patched-for-powerlevel10k) and run +`p10k configure`. + +### Why is my cursor in the wrong place? + +It's likely your font's fault. +[Install the recommended font](#recommended-meslo-nerd-font-patched-for-powerlevel10k) and run +`p10k configure`. + +If this doesn't help, type `unset ZLE_RPROMPT_INDENT`. If it fixes the issue, make the change +permanent: + +```zsh +echo 'unset ZLE_RPROMPT_INDENT' >>! ~/.zshrc +``` + +### Why is my right prompt wrapping around in a weird way? + +It's likely your font's fault. +[Install the recommended font](#recommended-meslo-nerd-font-patched-for-powerlevel10k) and run +`p10k configure`. + +If this doesn't help, type `unset ZLE_RPROMPT_INDENT`. If it fixes the issue, make the change +permanent: + +```zsh +echo 'unset ZLE_RPROMPT_INDENT' >>! ~/.zshrc +``` + +### I cannot install the recommended font. Help! + +Once you download [the recommended font](#recommended-meslo-nerd-font-patched-for-powerlevel10k), +you can install it just like any other font. Google "how to install fonts on *your-OS*". + +### Why do I have a question mark symbol in my prompt? Is my font broken? + +If it looks like a regular `?`, that's normal. It means you have untracked files in the current Git +repository. Type `git status` to see these files. You can change this symbol or disable the display +of untracked files altogether. Search for `untracked files` in `~/.p10k.zsh`. + +You can also get a weird-looking question mark in your prompt if your terminal's font is missing +some glyphs. To fix this problem, +[install the recommended font](#recommended-meslo-nerd-font-patched-for-powerlevel10k) and run +`p10k configure`. + ### Why does Powerlevel10k spawn extra processes? Powerlevel10k uses [gitstatus](https://github.com/romkatv/gitstatus) as the backend behind `vcs` @@ -189,22 +263,17 @@ prompt latency when using Powerlevel10k, please ### Is Powerlevel10k fast to load? -The short answer is no. The amount of time it takes for Powerlevel10k to render the first prompt -is in the same ballpark as for Powerlevel9k. +Yes, provided that you are using ZSH >= 5.4. -Time to first prompt can be measured with the following benchmark: +Loading time, or time to first prompt, can be measured with the following benchmark: ```zsh -time (repeat 100 zsh -dfis <<< 'source ~/powerlevel10k/powerlevel10k.zsh-theme') +time (repeat 1000 zsh -dfis <<< 'source ~/powerlevel10k/powerlevel10k.zsh-theme') ``` -On the same machine as in the [prompt benchmark](#is-it-really-fast) this results in 147 ms per -invocation when executed in a small git repository (I used the `powerlevel10k` repo itself). For -comparison, the same benchmark gives 170 ms for powerlevel9k/master and 505 ms for -powerlevel9k/next. - -If your workflow requires that you open a terminal tab, type a command or two and close the tab, -Powerlevel10k isn't the best choice. Powerlevel10k is optimized for long-lived ZSH sessions. +Running this command with `~/powerlevel10k` as the current directory on the same machine as in the +[prompt benchmark](#is-it-really-fast) takes 29 seconds (29 ms per invocation). This is about 6 +times faster than powerlevel9k/master and 17 times faster than powerlevel9k/next. ### Does Powerlevel10k always render exactly the same prompt as Powerlevel9k given the same config? @@ -212,17 +281,18 @@ This is the goal. You should be able to switch from Powerlevel9k to Powerlevel10 visible changes except for performance. There are, however, several differences. - By default only `git` vcs backend is enabled in Powerlevel10k. If you need `svn` and `hg`, you'll - need to set `POWERLEVEL9K_VCS_BACKENDS`. -- Powerlevel10k is bug-compatible with Powerlevel9k except for egregious bugs. If you accidentally - rely on these bugs, your prompt will differ between Powerlevel9k and Powerlevel10k. Some examples: + need to add them to `POWERLEVEL9K_VCS_BACKENDS`. +- Powerlevel10k strives to be bug-compatible with Powerlevel9k but not when it comes to egregious + bugs. If you accidentally rely on these bugs, your prompt will differ between Powerlevel9k and + Powerlevel10k. Some examples: - Powerlevel9k doesn't respect `ZLE_RPROMPT_INDENT`. As a result, right prompt in Powerlevel10k - can have an extra space compared to Powerlevel9k. Set `ZLE_RPROMPT_INDENT=0` if you don't want - that space. - - Powerlevel9k ignores some options that are set after the theme is sources while Powerlevel10k + can have an extra space at the end compared to Powerlevel9k. Set `ZLE_RPROMPT_INDENT=0` if you + don't want that space. + - Powerlevel9k ignores some options that are set after the theme is sourced while Powerlevel10k respects all options. If you see different icons in Powerlevel9k and Powerlevel10k, you've probably defined `POWERLEVEL9K_MODE` before sourcing the theme. This parameter gets ignored - by Powerlevel9k but not Powerlevel10k. If you want your prompt to look in Powerlevel10k the same - as in Powerlevel9k, remove `POWERLEVEL9K_MODE`. + by Powerlevel9k but honored by Powerlevel10k. If you want your prompt to look in Powerlevel10k + the same as in Powerlevel9k, remove `POWERLEVEL9K_MODE`. - There are [dozens more bugs](https://github.com/Powerlevel9k/powerlevel9k/issues/created_by/romkatv) in Powerlevel9k that don't exist in Powerlevel10k. @@ -250,7 +320,7 @@ theme (so that you end up with no theme) and then installing Powerlevel10k manua - **oh-my-zsh:** Open `~/.zshrc` and remove the line that sets `ZSH_THEME`, such as `ZSH_THEME=powerlevel9k/powerlevel9k`. - **antigen:** Open `~/.zshrc` and remove the line that sets `antigen theme`, such as - `antigen theme bhilburn/powerlevel9k powerlevel9k`. + `antigen theme powerlevel9k/powerlevel9k`. 2. Install Powerlevel10k manually. diff --git a/config/p10k-classic.zsh b/config/p10k-classic.zsh index 66416a53..88b8ec88 100644 --- a/config/p10k-classic.zsh +++ b/config/p10k-classic.zsh @@ -1,36 +1,33 @@ -# Config for Powerlevel10k with classic powerline prompt style. Requires a powerline font. -# The color scheme is suitable for dark terminal background. -# -# Once you've installed Powerlevel10k, run these commands to apply classic style. -# -# curl -fsSL -o ~/p10k-classic.zsh https://raw.githubusercontent.com/romkatv/powerlevel10k/master/config/p10k-classic.zsh -# echo 'source ~/p10k-classic.zsh' >>! ~/.zshrc -# -# To customize your prompt, open ~/p10k-classic.zsh in your favorite text editor, change it and -# restart ZSH. The file is well-documented. +# Config for Powerlevel10k with classic powerline prompt style. Type `p10k configure` to generate +# your own config based on it. # # Tip: Looking for a nice color? Here's a one-liner to print colormap. # # for i in {0..255}; do print -Pn "%${i}F${(l:3::0:)i}%f " ${${(M)$((i%8)):#7}:+$'\n'}; done -if [[ -o 'aliases' ]]; then - 'builtin' 'unsetopt' 'aliases' - local p9k_classic_restore_aliases=1 -else - local p9k_classic_restore_aliases=0 -fi +# Temporarily change options. +'builtin' 'local' '-a' 'p10k_config_opts' +[[ ! -o 'aliases' ]] || p10k_config_opts+=('aliases') +[[ ! -o 'sh_glob' ]] || p10k_config_opts+=('sh_glob') +[[ ! -o 'no_brace_expand' ]] || p10k_config_opts+=('no_brace_expand') +'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand' () { emulate -L zsh - setopt no_unset + setopt no_unset extended_glob + zmodload zsh/langinfo + if [[ ${langinfo[CODESET]:-} != (utf|UTF)(-|)8 ]]; then + local LC_ALL=${${(@M)$(locale -a):#*.(utf|UTF)(-|)8}[1]:-en_US.UTF-8} + fi # Unset all configuration options. This allows you to apply configiguration changes without # restarting zsh. Edit ~/.p10k.zsh and type `source ~/.p10k.zsh`. unset -m 'POWERLEVEL9K_*' # The list of segments shown on the left. Fill it with the most important segments. - typeset -ga POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=( + typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=( # =========================[ Line #1 ]========================= + # os_icon # os identifier dir # current directory vcs # git status # =========================[ Line #2 ]========================= @@ -54,15 +51,28 @@ fi nvm # node.js version from nvm (https://github.com/nvm-sh/nvm) nodeenv # node.js environment (https://github.com/ekalinin/nodeenv) # node_version # node.js version - # go_version # golang version + # go_version # go version (https://golang.org) + # rust_version # rustc version (https://www.rust-lang.org) + # dotnet_version # .NET version (https://dotnet.microsoft.com) + rbenv # ruby version from rbenv (https://github.com/rbenv/rbenv) + rvm # ruby version from rvm (https://rvm.io) kubecontext # current kubernetes context (https://kubernetes.io/) - context # user@host + terraform # terraform workspace (https://www.terraform.io) + aws # aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) + # aws_eb_env # aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) + # azure # azure account name (https://docs.microsoft.com/en-us/cli/azure) + context # user@hostname + nordvpn # nordvpn connection status, linux only (https://nordvpn.com/) + ranger # ranger shell (https://github.com/ranger/ranger) + # vpn_ip # virtual private network indicator + # ram # free RAM + # load # CPU load + # time # current time # =========================[ Line #2 ]========================= newline - # nordvpn # nordvpn connection status, linux only (https://nordvpn.com/) # public_ip # public IP address + # proxy # system-wide http/https/ftp proxy # battery # internal battery - # time # current time # example # example user-defined segment (see prompt_example function below) ) @@ -105,11 +115,12 @@ fi # Awesome-Terminal Fonts (regular) | awesome-fontconfig # Awesome-Terminal Fonts (patched) | awesome-patched # Nerd Fonts | nerdfont-complete + # Other | compatible # - # If this looks overwhelming, install a font from https://github.com/ryanoasis/nerd-fonts - # and set POWERLEVEL9K_MODE=nerdfont-complete. "Meslo LG S Regular Nerd Font Complete Mono" from - # https://github.com/ryanoasis/nerd-fonts/tree/master/patched-fonts/Meslo/S/Regular/complete is - # very good. + # If this looks overwhelming, either stick with a preinstalled system font and set + # POWERLEVEL9K_MODE=compatible, or install the recommended Powerlevel10k font from + # https://github.com/romkatv/powerlevel10k/#recommended-meslo-nerd-font-patched-for-powerlevel10k + # and set POWERLEVEL9K_MODE=nerdfont-complete. typeset -g POWERLEVEL9K_MODE=nerdfont-complete # When set to true, icons appear before content on both sides of the prompt. When set @@ -158,9 +169,9 @@ fi typeset -g POWERLEVEL9K_BACKGROUND=238 # Separator between same-color segments on the left. - typeset -g POWERLEVEL9K_LEFT_SUBSEGMENT_SEPARATOR='%244F\uE0B1' + typeset -g POWERLEVEL9K_LEFT_SUBSEGMENT_SEPARATOR='%246F\uE0B1' # Separator between same-color segments on the right. - typeset -g POWERLEVEL9K_RIGHT_SUBSEGMENT_SEPARATOR='%244F\uE0B3' + typeset -g POWERLEVEL9K_RIGHT_SUBSEGMENT_SEPARATOR='%246F\uE0B3' # Separator between different-color segments on the left. typeset -g POWERLEVEL9K_LEFT_SEGMENT_SEPARATOR='\uE0B0' # Separator between different-color segments on the right. @@ -177,10 +188,10 @@ fi typeset -g POWERLEVEL9K_EMPTY_LINE_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL= #################################[ os_icon: os identifier ]################################## - # Foreground color. - typeset -g POWERLEVEL9K_OS_ICON_FOREGROUND=7 - # Display this icon instead of the default. - # typeset -g POWERLEVEL9K_OS_ICON_CONTENT_EXPANSION='⭐' + # OS identifier color. + typeset -g POWERLEVEL9K_OS_ICON_FOREGROUND=255 + # Make the icon bold. + typeset -g POWERLEVEL9K_OS_ICON_CONTENT_EXPANSION='%B${P9K_CONTENT}' ################################[ prompt_char: prompt symbol ]################################ # Transparent background. @@ -195,6 +206,9 @@ fi typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VICMD_CONTENT_EXPANSION='❮' # Prompt symbol in visual vi mode. typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIVIS_CONTENT_EXPANSION='Ⅴ' + # Prompt symbol in overwrite vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIOWR_CONTENT_EXPANSION='▶' + typeset -g POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE=true # No line terminator if prompt_char is the last segment. typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL= # No line introducer if prompt_char is the first segment. @@ -217,14 +231,38 @@ fi typeset -g POWERLEVEL9K_DIR_ANCHOR_FOREGROUND=39 # Display anchor directory segments in bold. typeset -g POWERLEVEL9K_DIR_ANCHOR_BOLD=true - # Don't shorten directories that contain files matching this pattern. They are anchors. - typeset -g POWERLEVEL9K_SHORTEN_FOLDER_MARKER='(.shorten_folder_marker|.bzr|CVS|.git|.hg|.svn|.terraform|.citc)' + # Don't shorten directories that contain any of these files. They are anchors. + local anchor_files=( + .bzr + .citc + .git + .hg + .node-version + .python-version + .ruby-version + .shorten_folder_marker + .svn + .terraform + CVS + Cargo.toml + composer.json + go.mod + package.json + ) + typeset -g POWERLEVEL9K_SHORTEN_FOLDER_MARKER="(${(j:|:)anchor_files})" # Don't shorten this many last directory segments. They are anchors. typeset -g POWERLEVEL9K_SHORTEN_DIR_LENGTH=1 # Shorten directory if it's longer than this even if there is space for it. The value can # be either absolute (e.g., '80') or a percentage of terminal width (e.g, '50%'). If empty, - # directory will be shortened only when prompt doesn't fit. + # directory will be shortened only when prompt doesn't fit or when other parameters demand it + # (see POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS and POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT below). typeset -g POWERLEVEL9K_DIR_MAX_LENGTH=80 + # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least this + # many columns for typing commands. + typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS=40 + # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least + # COLUMNS * POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT * 0.01 columns for typing commands. + typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT=50 # If set to true, embed a hyperlink into the directory. Useful for quickly # opening a directory in the file manager simply by clicking the link. # Can also be handy when the directory is shortened, as it allows you to see @@ -233,7 +271,8 @@ fi # Enable special styling for non-writable directories. typeset -g POWERLEVEL9K_DIR_SHOW_WRITABLE=true - # Show this icon when the current directory is not writable. Empty for no icon. + # Show this icon when the current directory is not writable. POWERLEVEL9K_DIR_SHOW_WRITABLE + # above must be set to true for this parameter to have effect. # typeset -g POWERLEVEL9K_DIR_NOT_WRITABLE_VISUAL_IDENTIFIER_EXPANSION='⭐' # Custom prefix. @@ -269,57 +308,114 @@ fi # FOREGROUND, SHORTENED_FOREGROUND and ANCHOR_FOREGROUND for every directory class that you wish # to have its own color. # - # typeset -g POWERLEVEL9K_DIR_WORK_FOREGROUND=12 - # typeset -g POWERLEVEL9K_DIR_WORK_SHORTENED_FOREGROUND=4 + # typeset -g POWERLEVEL9K_DIR_WORK_FOREGROUND=31 + # typeset -g POWERLEVEL9K_DIR_WORK_SHORTENED_FOREGROUND=103 # typeset -g POWERLEVEL9K_DIR_WORK_ANCHOR_FOREGROUND=39 # # typeset -g POWERLEVEL9K_DIR_CLASSES=() #####################################[ vcs: git status ]###################################### - # Git status: feature:master#tag ⇣42⇡42 *42 merge ~42 +42 !42 ?42. - # We are using parameters defined by the gitstatus plugin. See reference: - # https://github.com/romkatv/gitstatus/blob/master/gitstatus.plugin.zsh. - local vcs='' - # 'feature' or '@72f5c8a' if not on a branch. - vcs+='${${VCS_STATUS_LOCAL_BRANCH:+%76F${(g::)POWERLEVEL9K_VCS_BRANCH_ICON}${VCS_STATUS_LOCAL_BRANCH//\%/%%}}' - vcs+=':-%f@%76F${VCS_STATUS_COMMIT[1,8]}}' - # ':master' if the tracking branch name differs from local branch. - vcs+='${${VCS_STATUS_REMOTE_BRANCH:#$VCS_STATUS_LOCAL_BRANCH}:+%f:%76F${VCS_STATUS_REMOTE_BRANCH//\%/%%}}' - # '#tag' if on a tag. - vcs+='${VCS_STATUS_TAG:+%f#%76F${VCS_STATUS_TAG//\%/%%}}' - # ⇣42 if behind the remote. - vcs+='${${VCS_STATUS_COMMITS_BEHIND:#0}:+ %76F⇣${VCS_STATUS_COMMITS_BEHIND}}' - # ⇡42 if ahead of the remote; no leading space if also behind the remote: ⇣42⇡42. - # If you want '⇣42 ⇡42' instead, replace '${${(M)VCS_STATUS_COMMITS_BEHIND:#0}:+ }' with ' '. - vcs+='${${VCS_STATUS_COMMITS_AHEAD:#0}:+${${(M)VCS_STATUS_COMMITS_BEHIND:#0}:+ }%76F⇡${VCS_STATUS_COMMITS_AHEAD}}' - # *42 if have stashes. - vcs+='${${VCS_STATUS_STASHES:#0}:+ %76F*${VCS_STATUS_STASHES}}' - # 'merge' if the repo is in an unusual state. - vcs+='${VCS_STATUS_ACTION:+ %196F${VCS_STATUS_ACTION//\%/%%}}' - # ~42 if have merge conflicts. - vcs+='${${VCS_STATUS_NUM_CONFLICTED:#0}:+ %196F~${VCS_STATUS_NUM_CONFLICTED}}' - # +42 if have staged changes. - vcs+='${${VCS_STATUS_NUM_STAGED:#0}:+ %227F+${VCS_STATUS_NUM_STAGED}}' - # !42 if have unstaged changes. - vcs+='${${VCS_STATUS_NUM_UNSTAGED:#0}:+ %227F!${VCS_STATUS_NUM_UNSTAGED}}' - # ?42 if have untracked files. - vcs+='${${VCS_STATUS_NUM_UNTRACKED:#0}:+ %39F?${VCS_STATUS_NUM_UNTRACKED}}' - # If P9K_CONTENT is not empty, leave it unchanged. It's either "loading" or from vcs_info. - vcs="\${P9K_CONTENT:-$vcs}" - - # Branch icon. Set this parameter to $'\uF126' for the popular Powerline branch icon. + # Branch icon. Set this parameter to '\uF126 ' for the popular Powerline branch icon. typeset -g POWERLEVEL9K_VCS_BRANCH_ICON= + POWERLEVEL9K_VCS_BRANCH_ICON=${(g::)POWERLEVEL9K_VCS_BRANCH_ICON} + + # Untracked files icon. It's really a question mark, your font isn't broken. + # Change the value of this parameter to show a different icon. + typeset -g POWERLEVEL9K_VCS_UNTRACKED_ICON='?' + POWERLEVEL9K_VCS_UNTRACKED_ICON=${(g::)POWERLEVEL9K_VCS_UNTRACKED_ICON} + + # Formatter for Git status. + # + # Example output: master ⇣42⇡42 *42 merge ~42 +42 !42 ?42. + # + # You can edit the function to customize how Git status looks. + # + # VCS_STATUS_* parameters are set by gitstatus plugin. See reference: + # https://github.com/romkatv/gitstatus/blob/master/gitstatus.plugin.zsh. + function my_git_formatter() { + emulate -L zsh + + if [[ -n $P9K_CONTENT ]]; then + # If P9K_CONTENT is not empty, use it. It's either "loading" or from vcs_info (not from + # gitstatus plugin). VCS_STATUS_* parameters are not available in this case. + typeset -g my_git_format=$P9K_CONTENT + return + fi + + if (( $1 )); then + # Styling for up-to-date Git status. + local meta='%248F' # grey foreground + local clean='%76F' # green foreground + local modified='%178F' # yellow foreground + local untracked='%39F' # blue foreground + local conflicted='%196F' # red foreground + else + # Styling for incomplete and stale Git status. + local meta='%244F' # grey foreground + local clean='%244F' # grey foreground + local modified='%244F' # grey foreground + local untracked='%244F' # grey foreground + local conflicted='%244F' # grey foreground + fi + + local res + local where # branch name, tag or commit + if [[ -n $VCS_STATUS_LOCAL_BRANCH ]]; then + res+="${clean}${POWERLEVEL9K_VCS_BRANCH_ICON}" + where=${(V)VCS_STATUS_LOCAL_BRANCH} + elif [[ -n $VCS_STATUS_TAG ]]; then + res+="${meta}#" + where=${(V)VCS_STATUS_TAG} + else + res+="${meta}@" + where=${VCS_STATUS_COMMIT[1,8]} + fi + + # If local branch name or tag is at most 32 characters long, show it in full. + # Otherwise show the first 12 … the last 12. + (( $#where > 32 )) && where[13,-13]="…" + res+="${clean}${where//\%/%%}" # escape % + + # Show tracking branch name if it differs from local branch. + if [[ -n ${VCS_STATUS_REMOTE_BRANCH:#$VCS_STATUS_LOCAL_BRANCH} ]]; then + res+="${meta}:${clean}${(V)VCS_STATUS_REMOTE_BRANCH//\%/%%}" # escape % + fi + + # ⇣42 if behind the remote. + (( VCS_STATUS_COMMITS_BEHIND )) && res+=" ${clean}⇣${VCS_STATUS_COMMITS_BEHIND}" + # ⇡42 if ahead of the remote; no leading space if also behind the remote: ⇣42⇡42. + (( VCS_STATUS_COMMITS_AHEAD && !VCS_STATUS_COMMITS_BEHIND )) && res+=" " + (( VCS_STATUS_COMMITS_AHEAD )) && res+="${clean}⇡${VCS_STATUS_COMMITS_AHEAD}" + # *42 if have stashes. + (( VCS_STATUS_STASHES )) && res+=" ${clean}*${VCS_STATUS_STASHES}" + # 'merge' if the repo is in an unusual state. + [[ -n $VCS_STATUS_ACTION ]] && res+=" ${conflicted}${VCS_STATUS_ACTION}" + # ~42 if have merge conflicts. + (( VCS_STATUS_NUM_CONFLICTED )) && res+=" ${conflicted}~${VCS_STATUS_NUM_CONFLICTED}" + # +42 if have staged changes. + (( VCS_STATUS_NUM_STAGED )) && res+=" ${modified}+${VCS_STATUS_NUM_STAGED}" + # !42 if have unstaged changes. + (( VCS_STATUS_NUM_UNSTAGED )) && res+=" ${modified}!${VCS_STATUS_NUM_UNSTAGED}" + # ?42 if have untracked files. It's really a question mark, your font isn't broken. + # See POWERLEVEL9K_VCS_UNTRACKED_ICON above if you want to use a different icon. + # Remove the next line if you don't want to see untracked files at all. + (( VCS_STATUS_NUM_UNTRACKED )) && res+=" ${untracked}${POWERLEVEL9K_VCS_UNTRACKED_ICON}${VCS_STATUS_NUM_UNTRACKED}" + + typeset -g my_git_format=$res + } + functions -M my_git_formatter 2>/dev/null # Disable the default Git status formatting. typeset -g POWERLEVEL9K_VCS_DISABLE_GITSTATUS_FORMATTING=true # Install our own Git status formatter. - typeset -g POWERLEVEL9K_VCS_{CLEAN,UNTRACKED,MODIFIED}_CONTENT_EXPANSION=$vcs - # When Git status is being refreshed asynchronously, display the last known repo status in grey. - typeset -g POWERLEVEL9K_VCS_LOADING_CONTENT_EXPANSION=${${vcs//\%f}//\%<->F} - typeset -g POWERLEVEL9K_VCS_LOADING_FOREGROUND=244 + typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION='${$((my_git_formatter(1)))+${my_git_format}}' + typeset -g POWERLEVEL9K_VCS_LOADING_CONTENT_EXPANSION='${$((my_git_formatter(0)))+${my_git_format}}' # Enable counters for staged, unstaged, etc. - typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED,COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=-1 + typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED,CONFLICTED,COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=-1 + # Icon color. + typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_COLOR=76 + typeset -g POWERLEVEL9K_VCS_LOADING_VISUAL_IDENTIFIER_COLOR=244 # Custom icon. # typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_EXPANSION='⭐' # Custom prefix. @@ -332,16 +428,9 @@ fi # These settings are used for respositories other than Git or when gitstatusd fails and # Powerlevel10k has to fall back to using vcs_info. - typeset -g POWERLEVEL9K_VCS_{CLEAN,MODIFIED,UNTRACKED}_FOREGROUND=76 - typeset -g POWERLEVEL9K_VCS_REMOTE_BRANCH_ICON=':' - typeset -g POWERLEVEL9K_VCS_COMMIT_ICON='@' - typeset -g POWERLEVEL9K_VCS_INCOMING_CHANGES_ICON='⇣' - typeset -g POWERLEVEL9K_VCS_OUTGOING_CHANGES_ICON='⇡' - typeset -g POWERLEVEL9K_VCS_STASH_ICON='*' - typeset -g POWERLEVEL9K_VCS_TAG_ICON=$'%{\b#%}' - typeset -g POWERLEVEL9K_VCS_UNTRACKED_ICON=$'%{\b?%}' - typeset -g POWERLEVEL9K_VCS_UNSTAGED_ICON=$'%{\b!%}' - typeset -g POWERLEVEL9K_VCS_STAGED_ICON=$'%{\b+%}' + typeset -g POWERLEVEL9K_VCS_CLEAN_FOREGROUND=76 + typeset -g POWERLEVEL9K_VCS_UNTRACKED_FOREGROUND=76 + typeset -g POWERLEVEL9K_VCS_MODIFIED_FOREGROUND=178 ##########################[ status: exit code of the last command ]########################### # Enable OK_PIPE, ERROR_PIPE and ERROR_SIGNAL status states to allow us to enable, disable and @@ -380,7 +469,6 @@ fi typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_VISUAL_IDENTIFIER_EXPANSION='↵' ###################[ command_execution_time: duration of the last command ]################### - # Background color. # Show duration of the last command if takes longer than this many seconds. typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=3 # Show this many fractional digits. Zero means round to seconds. @@ -411,20 +499,44 @@ fi # Custom icon. # typeset -g POWERLEVEL9K_NORDVPN_VISUAL_IDENTIFIER_EXPANSION='⭐' - ####################################[ context: user@host ]#################################### + #################[ ranger: ranger shell (https://github.com/ranger/ranger) ]################## + # Ranger shell color. + typeset -g POWERLEVEL9K_RANGER_FOREGROUND=178 + # Custom icon. + # typeset -g POWERLEVEL9K_RANGER_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################################[ ram: free RAM ]####################################### + # RAM color. + typeset -g POWERLEVEL9K_RAM_FOREGROUND=66 + # Custom icon. + # typeset -g POWERLEVEL9K_RAM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################################[ load: CPU load ]###################################### + # Show average CPU load over this many last minutes. Valid values are 1, 5 and 15. + typeset -g POWERLEVEL9K_LOAD_WHICH=5 + # Load color when load is under 50%. + typeset -g POWERLEVEL9K_LOAD_NORMAL_FOREGROUND=66 + # Load color when load is between 50% and 70%. + typeset -g POWERLEVEL9K_LOAD_WARNING_FOREGROUND=178 + # Load color when load is over 70%. + typeset -g POWERLEVEL9K_LOAD_CRITICAL_FOREGROUND=166 + # Custom icon. + # typeset -g POWERLEVEL9K_LOAD_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##################################[ context: user@hostname ]################################## # Default context color. typeset -g POWERLEVEL9K_CONTEXT_FOREGROUND=180 # Default context format: %n is username, %m is hostname. typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE='%n@%m' # Context color when running with privileges. - typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND=227 - # Context format when running with privileges: %n is username, %m is hostname. - typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE='%n@%m' + typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND=178 + # Context format when running with privileges: %n is username, %m is hostname, %B for bold. + typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE='%B%n@%m' - # Don't show context unless running with privileges on in SSH. + # Don't show context unless running with privileges or in SSH. + # Tip: Remove the next line to always show context. typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_{CONTENT,VISUAL_IDENTIFIER}_EXPANSION= - typeset -g POWERLEVEL9K_ALWAYS_SHOW_CONTEXT=true # Custom icon. # typeset -g POWERLEVEL9K_CONTEXT_VISUAL_IDENTIFIER_EXPANSION='⭐' @@ -491,12 +603,72 @@ fi # Custom icon. # typeset -g POWERLEVEL9K_NODE_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' - ################################[ go_version: golang version ]################################ - # Golang version color. + #######################[ go_version: go version (https://golang.org) ]######################## + # Go version color. typeset -g POWERLEVEL9K_GO_VERSION_FOREGROUND=37 + # Show go version only when in a go project subdirectory. + typeset -g POWERLEVEL9K_GO_VERSION_PROJECT_ONLY=true # Custom icon. # typeset -g POWERLEVEL9K_GO_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + #################[ rust_version: rustc version (https://www.rust-lang.org) ]################## + # Rust version color. + typeset -g POWERLEVEL9K_RUST_VERSION_FOREGROUND=37 + # Show rust version only when in a rust project subdirectory. + typeset -g POWERLEVEL9K_RUST_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_RUST_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ dotnet_version: .NET version (https://dotnet.microsoft.com) ]################ + # .NET version color. + typeset -g POWERLEVEL9K_DOTNET_VERSION_FOREGROUND=134 + # Show .NET version only when in a .NET project subdirectory. + typeset -g POWERLEVEL9K_DOTNET_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_DOTNET_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #############[ rbenv: ruby version from rbenv (https://github.com/rbenv/rbenv) ]############## + # Rbenv color. + typeset -g POWERLEVEL9K_RBENV_FOREGROUND=168 + # Don't show ruby version if it's the same as global: $(rbenv version-name) == $(rbenv global). + typeset -g POWERLEVEL9K_RBENV_PROMPT_ALWAYS_SHOW=false + # Custom icon. + # typeset -g POWERLEVEL9K_RBENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ rvm: ruby version from rvm (https://rvm.io) ]######################## + # Rvm color. + typeset -g POWERLEVEL9K_RVM_FOREGROUND=168 + # Don't show @gemset at the end. + typeset -g POWERLEVEL9K_RVM_SHOW_GEMSET=false + # Don't show ruby- at the front. + typeset -g POWERLEVEL9K_RVM_SHOW_PREFIX=false + # Custom icon. + # typeset -g POWERLEVEL9K_RVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ terraform: terraform workspace (https://www.terraform.io) ]################# + # Terraform color. + typeset -g POWERLEVEL9K_TERRAFORM_FOREGROUND=38 + # Custom icon. + # typeset -g POWERLEVEL9K_TERRAFORM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ aws: aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) ]# + # AWS profile color. + typeset -g POWERLEVEL9K_AWS_FOREGROUND=208 + # Custom icon. + # typeset -g POWERLEVEL9K_AWS_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ aws_eb_env: aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) ]# + # AWS Elastic Beanstalk environment color. + typeset -g POWERLEVEL9K_AWS_EB_ENV_FOREGROUND=70 + # Custom icon. + # typeset -g POWERLEVEL9K_AWS_EB_ENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ azure: azure account name (https://docs.microsoft.com/en-us/cli/azure) ]########## + # Azure account name color. + typeset -g POWERLEVEL9K_AZURE_FOREGROUND=32 + # Custom icon. + # typeset -g POWERLEVEL9K_AZURE_VISUAL_IDENTIFIER_EXPANSION='⭐' + #############[ kubecontext: current kubernetes context (https://kubernetes.io/) ]############# # Kubernetes context classes for the purpose of using different colors, icons and expansions with # different contexts. @@ -509,12 +681,19 @@ fi # POWERLEVEL9K_KUBECONTEXT_CLASSES defines the context class. Patterns are tried in order. The # first match wins. # - # For example, if your current kubernetes context is "deathray-testing/default", its class is TEST + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=( + # '*prod*' PROD + # '*test*' TEST + # '*' DEFAULT) + # + # If your current kubernetes context is "deathray-testing/default", its class is TEST # because "deathray-testing/default" doesn't match the pattern '*prod*' but does match '*test*'. # # You can define different colors, icons and content expansions for different classes: # - # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_FOREGROUND=2 + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_FOREGROUND=28 # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=( @@ -525,7 +704,8 @@ fi # typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' # Use POWERLEVEL9K_KUBECONTEXT_CONTENT_EXPANSION to specify the content displayed by kubecontext - # segment. + # segment. Parameter expansions are very flexible and fast, too. See reference: + # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion. # # Within the expansion the following parameters are always available: # @@ -539,7 +719,8 @@ fi # in the output of `kubectl config get-contexts`. If there is no # namespace, the parameter is set to "default". # - # If the context points to GKE or EKS, the following extra parameters are available: + # If the context points to Google Kubernetes Engine (GKE) or Elastic Kubernetes Service (EKS), + # the following extra parameters are available: # # - P9K_KUBECONTEXT_CLOUD_NAME Either "gke" or "eks". # - P9K_KUBECONTEXT_CLOUD_ACCOUNT Account/project ID. @@ -560,11 +741,11 @@ fi # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=123456789012 # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east-1 # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01 - # - # The expansion below will show P9K_KUBECONTEXT_CLOUD_CLUSTER if it's not empty and fall back - # to P9K_KUBECONTEXT_NAME. Parameter expansions are very flexible and fast, too. See reference: - # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion. - typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION='${P9K_KUBECONTEXT_CLOUD_CLUSTER:-${P9K_KUBECONTEXT_NAME}}' + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION= + # Show P9K_KUBECONTEXT_CLOUD_CLUSTER if it's not empty and fall back to P9K_KUBECONTEXT_NAME. + POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${P9K_KUBECONTEXT_CLOUD_CLUSTER:-${P9K_KUBECONTEXT_NAME}}' + # Append the current context's namespace if it's not "default". + POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${${:-/$P9K_KUBECONTEXT_NAMESPACE}:#/default}' # Custom prefix. # typeset -g POWERLEVEL9K_KUBECONTEXT_PREFIX='%248Fat ' @@ -575,20 +756,33 @@ fi # Custom icon. # typeset -g POWERLEVEL9K_PUBLIC_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + ########################[ vpn_ip: virtual private network indicator ]######################### + # VPN IP color. + typeset -g POWERLEVEL9K_VPN_IP_FOREGROUND=81 + # When on VPN, show just an icon without the IP address. + typeset -g POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION= + # Regular expression for the VPN network interface. Run ifconfig while on VPN to see the + # name of the interface. + typeset -g POWERLEVEL9K_VPN_IP_INTERFACE='(wg|(.*tun))[0-9]*' + # Icon to show when on VPN. + typeset -g POWERLEVEL9K_VPN_IP_VISUAL_IDENTIFIER_EXPANSION='${P9K_VISUAL_IDENTIFIER}' + + #########################[ proxy: system-wide http/https/ftp proxy ]########################## + # Proxy color. + typeset -g POWERLEVEL9K_PROXY_FOREGROUND=68 + # Custom icon. + # typeset -g POWERLEVEL9K_PROXY_VISUAL_IDENTIFIER_EXPANSION='⭐' + ################################[ battery: internal battery ]################################# # Show battery in red when it's below this level and not connected to power supply. typeset -g POWERLEVEL9K_BATTERY_LOW_THRESHOLD=20 - typeset -g POWERLEVEL9K_BATTERY_LOW_FOREGROUND=1 - # Show battery in green when it's charging. - typeset -g POWERLEVEL9K_BATTERY_CHARGING_FOREGROUND=2 - # Show battery in yellow when not connected to power supply. + typeset -g POWERLEVEL9K_BATTERY_LOW_FOREGROUND=160 + # Show battery in green when it's charging or fully charged. + typeset -g POWERLEVEL9K_BATTERY_{CHARGING,CHARGED}_FOREGROUND=70 + # Show battery in yellow when it's discharging. typeset -g POWERLEVEL9K_BATTERY_DISCONNECTED_FOREGROUND=178 # Battery pictograms going from low to high level of charge. - typeset -g POWERLEVEL9K_BATTERY_STAGES='▁▂▃▄▅▆▇' - # Display battery pictogram without background. - typeset -g POWERLEVEL9K_BATTERY_VISUAL_IDENTIFIER_EXPANSION='%k${P9K_VISUAL_IDENTIFIER}' - # Don't show battery when it's fully charged and connected to power supply. - typeset -g POWERLEVEL9K_BATTERY_CHARGED_{CONTENT,VISUAL_IDENTIFIER}_EXPANSION= + typeset -g POWERLEVEL9K_BATTERY_STAGES=('%K{232}▁' '%K{232}▂' '%K{232}▃' '%K{232}▄' '%K{232}▅' '%K{232}▆' '%K{232}▇' '%K{232}█') # Don't show the remaining time to charge/discharge. typeset -g POWERLEVEL9K_BATTERY_VERBOSE=false @@ -610,9 +804,9 @@ fi # prompt if `example` prompt segment is added to POWERLEVEL9K_LEFT_PROMPT_ELEMENTS or # POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS. It displays an icon and orange text greeting the user. # - # Type `p9k_prompt_segment -h` for documentation and a more sophisticated example. + # Type `p10k help segment` for documentation and a more sophisticated example. function prompt_example() { - p9k_prompt_segment -f 208 -i '⭐' -t 'hello, %n' + p10k segment -f 208 -i '⭐' -t 'hello, %n' } # User-defined prompt segments can be customized the same way as built-in segments. @@ -620,5 +814,5 @@ fi typeset -g POWERLEVEL9K_EXAMPLE_VISUAL_IDENTIFIER_EXPANSION='${P9K_VISUAL_IDENTIFIER}' } -(( ! p9k_classic_restore_aliases )) || setopt aliases -'builtin' 'unset' 'p9k_classic_restore_aliases' +(( ${#p10k_config_opts} )) && setopt ${p10k_config_opts[@]} +'builtin' 'unset' 'p10k_config_opts' diff --git a/config/p10k-lean.png b/config/p10k-lean.png deleted file mode 100644 index 933b781a..00000000 Binary files a/config/p10k-lean.png and /dev/null differ diff --git a/config/p10k-lean.zsh b/config/p10k-lean.zsh index 81a3f40d..b57a9094 100644 --- a/config/p10k-lean.zsh +++ b/config/p10k-lean.zsh @@ -1,29 +1,24 @@ -# Config for Powerlevel10k with lean prompt style. Doesn't require a custom font but can take -# advantage of it if available. The color scheme is suitable for dark terminal background. -# -# Once you've installed Powerlevel10k, run these commands to apply lean style. -# -# curl -fsSL -o ~/p10k-lean.zsh https://raw.githubusercontent.com/romkatv/powerlevel10k/master/config/p10k-lean.zsh -# echo 'source ~/p10k-lean.zsh' >>! ~/.zshrc -# -# To customize your prompt, open ~/p10k-lean.zsh in your favorite text editor, change it and -# restart ZSH. The file is well-documented. +# Config for Powerlevel10k with lean prompt style. Type `p10k configure` to generate +# your own config based on it. # # Tip: Looking for a nice color? Here's a one-liner to print colormap. # # for i in {0..255}; do print -Pn "%${i}F${(l:3::0:)i}%f " ${${(M)$((i%8)):#7}:+$'\n'}; done -if [[ -o 'aliases' ]]; then - # Temporarily disable aliases. - 'builtin' 'unsetopt' 'aliases' - local p10k_lean_restore_aliases=1 -else - local p10k_lean_restore_aliases=0 -fi +# Temporarily change options. +'builtin' 'local' '-a' 'p10k_config_opts' +[[ ! -o 'aliases' ]] || p10k_config_opts+=('aliases') +[[ ! -o 'sh_glob' ]] || p10k_config_opts+=('sh_glob') +[[ ! -o 'no_brace_expand' ]] || p10k_config_opts+=('no_brace_expand') +'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand' () { emulate -L zsh - setopt no_unset + setopt no_unset extended_glob + zmodload zsh/langinfo + if [[ ${langinfo[CODESET]:-} != (utf|UTF)(-|)8 ]]; then + local LC_ALL=${${(@M)$(locale -a):#*.(utf|UTF)(-|)8}[1]:-en_US.UTF-8} + fi # Unset all configuration options. This allows you to apply configiguration changes without # restarting zsh. Edit ~/.p10k.zsh and type `source ~/.p10k.zsh`. @@ -56,15 +51,28 @@ fi nvm # node.js version from nvm (https://github.com/nvm-sh/nvm) nodeenv # node.js environment (https://github.com/ekalinin/nodeenv) # node_version # node.js version - # go_version # golang version + # go_version # go version (https://golang.org) + # rust_version # rustc version (https://www.rust-lang.org) + # dotnet_version # .NET version (https://dotnet.microsoft.com) + rbenv # ruby version from rbenv (https://github.com/rbenv/rbenv) + rvm # ruby version from rvm (https://rvm.io) kubecontext # current kubernetes context (https://kubernetes.io/) - context # user@host + terraform # terraform workspace (https://www.terraform.io) + aws # aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) + # aws_eb_env # aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) + # azure # azure account name (https://docs.microsoft.com/en-us/cli/azure) + context # user@hostname + nordvpn # nordvpn connection status, linux only (https://nordvpn.com/) + ranger # ranger shell (https://github.com/ranger/ranger) + # vpn_ip # virtual private network indicator + # ram # free RAM + # load # CPU load + # time # current time # =========================[ Line #2 ]========================= newline - # nordvpn # nordvpn connection status, linux only (https://nordvpn.com/) # public_ip # public IP address + # proxy # system-wide http/https/ftp proxy # battery # internal battery - # time # current time # example # example user-defined segment (see prompt_example function below) ) @@ -118,10 +126,9 @@ fi # Other | compatible # # If this looks overwhelming, either stick with a preinstalled system font and set - # POWERLEVEL9K_MODE=compatible, or install a font from https://github.com/ryanoasis/nerd-fonts - # and set POWERLEVEL9K_MODE=nerdfont-complete. "Meslo LG S Regular Nerd Font Complete Mono" from - # https://github.com/ryanoasis/nerd-fonts/tree/master/patched-fonts/Meslo/S/Regular/complete is - # very good. + # POWERLEVEL9K_MODE=compatible, or install the recommended Powerlevel10k font from + # https://github.com/romkatv/powerlevel10k/#recommended-meslo-nerd-font-patched-for-powerlevel10k + # and set POWERLEVEL9K_MODE=nerdfont-complete. typeset -g POWERLEVEL9K_MODE=nerdfont-complete # When set to true, icons appear before content on both sides of the prompt. When set @@ -169,9 +176,9 @@ fi #################################[ os_icon: os identifier ]################################## # OS identifier color. - typeset -g POWERLEVEL9K_OS_ICON_FOREGROUND=212 - # Display this icon instead of the default. - # typeset -g POWERLEVEL9K_OS_ICON_CONTENT_EXPANSION='⭐' + typeset -g POWERLEVEL9K_OS_ICON_FOREGROUND= + # Make the icon bold. + typeset -g POWERLEVEL9K_OS_ICON_CONTENT_EXPANSION='%B${P9K_CONTENT}' ################################[ prompt_char: prompt symbol ]################################ # Green prompt symbol if the last command succeeded. @@ -184,6 +191,9 @@ fi typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VICMD_CONTENT_EXPANSION='❮' # Prompt symbol in visual vi mode. typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIVIS_CONTENT_EXPANSION='Ⅴ' + # Prompt symbol in overwrite vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIOWR_CONTENT_EXPANSION='▶' + typeset -g POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE=true typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL='' ##################################[ dir: current directory ]################################## @@ -201,14 +211,38 @@ fi typeset -g POWERLEVEL9K_DIR_ANCHOR_FOREGROUND=39 # Display anchor directory segments in bold. typeset -g POWERLEVEL9K_DIR_ANCHOR_BOLD=true - # Don't shorten directories that contain files matching this pattern. They are anchors. - typeset -g POWERLEVEL9K_SHORTEN_FOLDER_MARKER='(.shorten_folder_marker|.bzr|CVS|.git|.hg|.svn|.terraform|.citc)' + # Don't shorten directories that contain any of these files. They are anchors. + local anchor_files=( + .bzr + .citc + .git + .hg + .node-version + .python-version + .ruby-version + .shorten_folder_marker + .svn + .terraform + CVS + Cargo.toml + composer.json + go.mod + package.json + ) + typeset -g POWERLEVEL9K_SHORTEN_FOLDER_MARKER="(${(j:|:)anchor_files})" # Don't shorten this many last directory segments. They are anchors. typeset -g POWERLEVEL9K_SHORTEN_DIR_LENGTH=1 # Shorten directory if it's longer than this even if there is space for it. The value can # be either absolute (e.g., '80') or a percentage of terminal width (e.g, '50%'). If empty, - # directory will be shortened only when prompt doesn't fit. + # directory will be shortened only when prompt doesn't fit or when other parameters demand it + # (see POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS and POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT below). typeset -g POWERLEVEL9K_DIR_MAX_LENGTH=80 + # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least this + # many columns for typing commands. + typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS=40 + # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least + # COLUMNS * POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT * 0.01 columns for typing commands. + typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT=50 # If set to true, embed a hyperlink into the directory. Useful for quickly # opening a directory in the file manager simply by clicking the link. # Can also be handy when the directory is shortened, as it allows you to see @@ -219,7 +253,7 @@ fi typeset -g POWERLEVEL9K_DIR_SHOW_WRITABLE=true # Show this icon when the current directory is not writable. POWERLEVEL9K_DIR_SHOW_WRITABLE # above must be set to true for this parameter to have effect. - # POWERLEVEL9K_DIR_NOT_WRITABLE_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_DIR_NOT_WRITABLE_VISUAL_IDENTIFIER_EXPANSION='⭐' # Custom prefix. # typeset -g POWERLEVEL9K_DIR_PREFIX='%fin ' @@ -254,57 +288,114 @@ fi # FOREGROUND, SHORTENED_FOREGROUND and ANCHOR_FOREGROUND for every directory class that you wish # to have its own color. # - # typeset -g POWERLEVEL9K_DIR_WORK_FOREGROUND=12 - # typeset -g POWERLEVEL9K_DIR_WORK_SHORTENED_FOREGROUND=4 + # typeset -g POWERLEVEL9K_DIR_WORK_FOREGROUND=31 + # typeset -g POWERLEVEL9K_DIR_WORK_SHORTENED_FOREGROUND=103 # typeset -g POWERLEVEL9K_DIR_WORK_ANCHOR_FOREGROUND=39 # # typeset -g POWERLEVEL9K_DIR_CLASSES=() #####################################[ vcs: git status ]###################################### - # Git status: feature:master#tag ⇣42⇡42 *42 merge ~42 +42 !42 ?42. - # We are using parameters defined by the gitstatus plugin. See reference: - # https://github.com/romkatv/gitstatus/blob/master/gitstatus.plugin.zsh. - local vcs='' - # 'feature' or '@72f5c8a' if not on a branch. - vcs+='${${VCS_STATUS_LOCAL_BRANCH:+%76F${(g::)POWERLEVEL9K_VCS_BRANCH_ICON}${VCS_STATUS_LOCAL_BRANCH//\%/%%}}' - vcs+=':-%f@%76F${VCS_STATUS_COMMIT[1,8]}}' - # ':master' if the tracking branch name differs from local branch. - vcs+='${${VCS_STATUS_REMOTE_BRANCH:#$VCS_STATUS_LOCAL_BRANCH}:+%f:%76F${VCS_STATUS_REMOTE_BRANCH//\%/%%}}' - # '#tag' if on a tag. - vcs+='${VCS_STATUS_TAG:+%f#%76F${VCS_STATUS_TAG//\%/%%}}' - # ⇣42 if behind the remote. - vcs+='${${VCS_STATUS_COMMITS_BEHIND:#0}:+ %76F⇣${VCS_STATUS_COMMITS_BEHIND}}' - # ⇡42 if ahead of the remote; no leading space if also behind the remote: ⇣42⇡42. - # If you want '⇣42 ⇡42' instead, replace '${${(M)VCS_STATUS_COMMITS_BEHIND:#0}:+ }' with ' '. - vcs+='${${VCS_STATUS_COMMITS_AHEAD:#0}:+${${(M)VCS_STATUS_COMMITS_BEHIND:#0}:+ }%76F⇡${VCS_STATUS_COMMITS_AHEAD}}' - # *42 if have stashes. - vcs+='${${VCS_STATUS_STASHES:#0}:+ %76F*${VCS_STATUS_STASHES}}' - # 'merge' if the repo is in an unusual state. - vcs+='${VCS_STATUS_ACTION:+ %196F${VCS_STATUS_ACTION//\%/%%}}' - # ~42 if have merge conflicts. - vcs+='${${VCS_STATUS_NUM_CONFLICTED:#0}:+ %196F~${VCS_STATUS_NUM_CONFLICTED}}' - # +42 if have staged changes. - vcs+='${${VCS_STATUS_NUM_STAGED:#0}:+ %227F+${VCS_STATUS_NUM_STAGED}}' - # !42 if have unstaged changes. - vcs+='${${VCS_STATUS_NUM_UNSTAGED:#0}:+ %227F!${VCS_STATUS_NUM_UNSTAGED}}' - # ?42 if have untracked files. - vcs+='${${VCS_STATUS_NUM_UNTRACKED:#0}:+ %39F?${VCS_STATUS_NUM_UNTRACKED}}' - # If P9K_CONTENT is not empty, leave it unchanged. It's either "loading" or from vcs_info. - vcs="\${P9K_CONTENT:-$vcs}" - - # Branch icon. Set this parameter to $'\uF126' for the popular Powerline branch icon. + # Branch icon. Set this parameter to '\uF126 ' for the popular Powerline branch icon. typeset -g POWERLEVEL9K_VCS_BRANCH_ICON= + POWERLEVEL9K_VCS_BRANCH_ICON=${(g::)POWERLEVEL9K_VCS_BRANCH_ICON} + + # Untracked files icon. It's really a question mark, your font isn't broken. + # Change the value of this parameter to show a different icon. + typeset -g POWERLEVEL9K_VCS_UNTRACKED_ICON='?' + POWERLEVEL9K_VCS_UNTRACKED_ICON=${(g::)POWERLEVEL9K_VCS_UNTRACKED_ICON} + + # Formatter for Git status. + # + # Example output: master ⇣42⇡42 *42 merge ~42 +42 !42 ?42. + # + # You can edit the function to customize how Git status looks. + # + # VCS_STATUS_* parameters are set by gitstatus plugin. See reference: + # https://github.com/romkatv/gitstatus/blob/master/gitstatus.plugin.zsh. + function my_git_formatter() { + emulate -L zsh + + if [[ -n $P9K_CONTENT ]]; then + # If P9K_CONTENT is not empty, use it. It's either "loading" or from vcs_info (not from + # gitstatus plugin). VCS_STATUS_* parameters are not available in this case. + typeset -g my_git_format=$P9K_CONTENT + return + fi + + if (( $1 )); then + # Styling for up-to-date Git status. + local meta='%f' # default foreground + local clean='%76F' # green foreground + local modified='%178F' # yellow foreground + local untracked='%39F' # blue foreground + local conflicted='%196F' # red foreground + else + # Styling for incomplete and stale Git status. + local meta='%244F' # grey foreground + local clean='%244F' # grey foreground + local modified='%244F' # grey foreground + local untracked='%244F' # grey foreground + local conflicted='%244F' # grey foreground + fi + + local res + local where # branch name, tag or commit + if [[ -n $VCS_STATUS_LOCAL_BRANCH ]]; then + res+="${clean}${POWERLEVEL9K_VCS_BRANCH_ICON}" + where=${(V)VCS_STATUS_LOCAL_BRANCH} + elif [[ -n $VCS_STATUS_TAG ]]; then + res+="${meta}#" + where=${(V)VCS_STATUS_TAG} + else + res+="${meta}@" + where=${VCS_STATUS_COMMIT[1,8]} + fi + + # If local branch name or tag is at most 32 characters long, show it in full. + # Otherwise show the first 12 … the last 12. + (( $#where > 32 )) && where[13,-13]="…" + res+="${clean}${where//\%/%%}" # escape % + + # Show tracking branch name if it differs from local branch. + if [[ -n ${VCS_STATUS_REMOTE_BRANCH:#$VCS_STATUS_LOCAL_BRANCH} ]]; then + res+="${meta}:${clean}${(V)VCS_STATUS_REMOTE_BRANCH//\%/%%}" # escape % + fi + + # ⇣42 if behind the remote. + (( VCS_STATUS_COMMITS_BEHIND )) && res+=" ${clean}⇣${VCS_STATUS_COMMITS_BEHIND}" + # ⇡42 if ahead of the remote; no leading space if also behind the remote: ⇣42⇡42. + (( VCS_STATUS_COMMITS_AHEAD && !VCS_STATUS_COMMITS_BEHIND )) && res+=" " + (( VCS_STATUS_COMMITS_AHEAD )) && res+="${clean}⇡${VCS_STATUS_COMMITS_AHEAD}" + # *42 if have stashes. + (( VCS_STATUS_STASHES )) && res+=" ${clean}*${VCS_STATUS_STASHES}" + # 'merge' if the repo is in an unusual state. + [[ -n $VCS_STATUS_ACTION ]] && res+=" ${conflicted}${VCS_STATUS_ACTION}" + # ~42 if have merge conflicts. + (( VCS_STATUS_NUM_CONFLICTED )) && res+=" ${conflicted}~${VCS_STATUS_NUM_CONFLICTED}" + # +42 if have staged changes. + (( VCS_STATUS_NUM_STAGED )) && res+=" ${modified}+${VCS_STATUS_NUM_STAGED}" + # !42 if have unstaged changes. + (( VCS_STATUS_NUM_UNSTAGED )) && res+=" ${modified}!${VCS_STATUS_NUM_UNSTAGED}" + # ?42 if have untracked files. It's really a question mark, your font isn't broken. + # See POWERLEVEL9K_VCS_UNTRACKED_ICON above if you want to use a different icon. + # Remove the next line if you don't want to see untracked files at all. + (( VCS_STATUS_NUM_UNTRACKED )) && res+=" ${untracked}${POWERLEVEL9K_VCS_UNTRACKED_ICON}${VCS_STATUS_NUM_UNTRACKED}" + + typeset -g my_git_format=$res + } + functions -M my_git_formatter 2>/dev/null # Disable the default Git status formatting. typeset -g POWERLEVEL9K_VCS_DISABLE_GITSTATUS_FORMATTING=true # Install our own Git status formatter. - typeset -g POWERLEVEL9K_VCS_{CLEAN,UNTRACKED,MODIFIED}_CONTENT_EXPANSION=$vcs - # When Git status is being refreshed asynchronously, display the last known repo status in grey. - typeset -g POWERLEVEL9K_VCS_LOADING_CONTENT_EXPANSION=${${vcs//\%f}//\%<->F} - typeset -g POWERLEVEL9K_VCS_LOADING_FOREGROUND=244 + typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION='${$((my_git_formatter(1)))+${my_git_format}}' + typeset -g POWERLEVEL9K_VCS_LOADING_CONTENT_EXPANSION='${$((my_git_formatter(0)))+${my_git_format}}' # Enable counters for staged, unstaged, etc. - typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED,COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=-1 + typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED,CONFLICTED,COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=-1 + # Icon color. + typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_COLOR=76 + typeset -g POWERLEVEL9K_VCS_LOADING_VISUAL_IDENTIFIER_COLOR=244 # Custom icon. # typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_EXPANSION='⭐' # Custom prefix. @@ -317,19 +408,11 @@ fi # These settings are used for respositories other than Git or when gitstatusd fails and # Powerlevel10k has to fall back to using vcs_info. - typeset -g POWERLEVEL9K_VCS_{CLEAN,MODIFIED,UNTRACKED}_FOREGROUND=76 - typeset -g POWERLEVEL9K_VCS_REMOTE_BRANCH_ICON=':' - typeset -g POWERLEVEL9K_VCS_COMMIT_ICON='@' - typeset -g POWERLEVEL9K_VCS_INCOMING_CHANGES_ICON='⇣' - typeset -g POWERLEVEL9K_VCS_OUTGOING_CHANGES_ICON='⇡' - typeset -g POWERLEVEL9K_VCS_STASH_ICON='*' - typeset -g POWERLEVEL9K_VCS_TAG_ICON=$'%{\b#%}' - typeset -g POWERLEVEL9K_VCS_UNTRACKED_ICON=$'%{\b?%}' - typeset -g POWERLEVEL9K_VCS_UNSTAGED_ICON=$'%{\b!%}' - typeset -g POWERLEVEL9K_VCS_STAGED_ICON=$'%{\b+%}' + typeset -g POWERLEVEL9K_VCS_CLEAN_FOREGROUND=76 + typeset -g POWERLEVEL9K_VCS_UNTRACKED_FOREGROUND=76 + typeset -g POWERLEVEL9K_VCS_MODIFIED_FOREGROUND=178 ##########################[ status: exit code of the last command ]########################### - # Status on success. No content, just an icon. # Enable OK_PIPE, ERROR_PIPE and ERROR_SIGNAL status states to allow us to enable, disable and # style them independently from the regular OK and ERROR state. typeset -g POWERLEVEL9K_STATUS_EXTENDED_STATES=true @@ -396,20 +479,44 @@ fi # Custom icon. # typeset -g POWERLEVEL9K_NORDVPN_VISUAL_IDENTIFIER_EXPANSION='⭐' - ####################################[ context: user@host ]#################################### + #################[ ranger: ranger shell (https://github.com/ranger/ranger) ]################## + # Ranger shell color. + typeset -g POWERLEVEL9K_RANGER_FOREGROUND=178 + # Custom icon. + # typeset -g POWERLEVEL9K_RANGER_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################################[ ram: free RAM ]####################################### + # RAM color. + typeset -g POWERLEVEL9K_RAM_FOREGROUND=66 + # Custom icon. + # typeset -g POWERLEVEL9K_RAM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################################[ load: CPU load ]###################################### + # Show average CPU load over this many last minutes. Valid values are 1, 5 and 15. + typeset -g POWERLEVEL9K_LOAD_WHICH=5 + # Load color when load is under 50%. + typeset -g POWERLEVEL9K_LOAD_NORMAL_FOREGROUND=66 + # Load color when load is between 50% and 70%. + typeset -g POWERLEVEL9K_LOAD_WARNING_FOREGROUND=178 + # Load color when load is over 70%. + typeset -g POWERLEVEL9K_LOAD_CRITICAL_FOREGROUND=166 + # Custom icon. + # typeset -g POWERLEVEL9K_LOAD_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##################################[ context: user@hostname ]################################## # Default context color. typeset -g POWERLEVEL9K_CONTEXT_FOREGROUND=180 # Default context format: %n is username, %m is hostname. typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE='%n@%m' # Context color when running with privileges. - typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND=227 - # Context format when running with privileges: %n is username, %m is hostname. - typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE='%n@%m' + typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND=178 + # Context format when running with privileges: bold user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE='%B%n@%m' - # Don't show context unless running with privileges on in SSH. + # Don't show context unless running with privileges or in SSH. + # Tip: Remove the next line to always show context. typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_{CONTENT,VISUAL_IDENTIFIER}_EXPANSION= - typeset -g POWERLEVEL9K_ALWAYS_SHOW_CONTEXT=true # Custom icon. # typeset -g POWERLEVEL9K_CONTEXT_VISUAL_IDENTIFIER_EXPANSION='⭐' @@ -476,12 +583,48 @@ fi # Custom icon. # typeset -g POWERLEVEL9K_NODE_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' - ################################[ go_version: golang version ]################################ - # Golang version color. + #######################[ go_version: go version (https://golang.org) ]######################## + # Go version color. typeset -g POWERLEVEL9K_GO_VERSION_FOREGROUND=37 + # Show go version only when in a go project subdirectory. + typeset -g POWERLEVEL9K_GO_VERSION_PROJECT_ONLY=true # Custom icon. # typeset -g POWERLEVEL9K_GO_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + #################[ rust_version: rustc version (https://www.rust-lang.org) ]################## + # Rust version color. + typeset -g POWERLEVEL9K_RUST_VERSION_FOREGROUND=37 + # Show rust version only when in a rust project subdirectory. + typeset -g POWERLEVEL9K_RUST_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_RUST_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ dotnet_version: .NET version (https://dotnet.microsoft.com) ]################ + # .NET version color. + typeset -g POWERLEVEL9K_DOTNET_VERSION_FOREGROUND=134 + # Show .NET version only when in a .NET project subdirectory. + typeset -g POWERLEVEL9K_DOTNET_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_DOTNET_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #############[ rbenv: ruby version from rbenv (https://github.com/rbenv/rbenv) ]############## + # Rbenv color. + typeset -g POWERLEVEL9K_RBENV_FOREGROUND=168 + # Don't show ruby version if it's the same as global: $(rbenv version-name) == $(rbenv global). + typeset -g POWERLEVEL9K_RBENV_PROMPT_ALWAYS_SHOW=false + # Custom icon. + # typeset -g POWERLEVEL9K_RBENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ rvm: ruby version from rvm (https://rvm.io) ]######################## + # Rvm color. + typeset -g POWERLEVEL9K_RVM_FOREGROUND=168 + # Don't show @gemset at the end. + typeset -g POWERLEVEL9K_RVM_SHOW_GEMSET=false + # Don't show ruby- at the front. + typeset -g POWERLEVEL9K_RVM_SHOW_PREFIX=false + # Custom icon. + # typeset -g POWERLEVEL9K_RVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + #############[ kubecontext: current kubernetes context (https://kubernetes.io/) ]############# # Kubernetes context classes for the purpose of using different colors, icons and expansions with # different contexts. @@ -494,12 +637,19 @@ fi # POWERLEVEL9K_KUBECONTEXT_CLASSES defines the context class. Patterns are tried in order. The # first match wins. # - # For example, if your current kubernetes context is "deathray-testing/default", its class is TEST + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=( + # '*prod*' PROD + # '*test*' TEST + # '*' DEFAULT) + # + # If your current kubernetes context is "deathray-testing/default", its class is TEST # because "deathray-testing/default" doesn't match the pattern '*prod*' but does match '*test*'. # # You can define different colors, icons and content expansions for different classes: # - # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_FOREGROUND=2 + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_FOREGROUND=28 # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=( @@ -510,7 +660,8 @@ fi # typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' # Use POWERLEVEL9K_KUBECONTEXT_CONTENT_EXPANSION to specify the content displayed by kubecontext - # segment. + # segment. Parameter expansions are very flexible and fast, too. See reference: + # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion. # # Within the expansion the following parameters are always available: # @@ -524,7 +675,8 @@ fi # in the output of `kubectl config get-contexts`. If there is no # namespace, the parameter is set to "default". # - # If the context points to GKE or EKS, the following extra parameters are available: + # If the context points to Google Kubernetes Engine (GKE) or Elastic Kubernetes Service (EKS), + # the following extra parameters are available: # # - P9K_KUBECONTEXT_CLOUD_NAME Either "gke" or "eks". # - P9K_KUBECONTEXT_CLOUD_ACCOUNT Account/project ID. @@ -545,35 +697,72 @@ fi # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=123456789012 # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east-1 # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01 - # - # The expansion below will show P9K_KUBECONTEXT_CLOUD_CLUSTER if it's not empty and fall back - # to P9K_KUBECONTEXT_NAME. Parameter expansions are very flexible and fast, too. See reference: - # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion. - typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION='${P9K_KUBECONTEXT_CLOUD_CLUSTER:-${P9K_KUBECONTEXT_NAME}}' + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION= + # Show P9K_KUBECONTEXT_CLOUD_CLUSTER if it's not empty and fall back to P9K_KUBECONTEXT_NAME. + POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${P9K_KUBECONTEXT_CLOUD_CLUSTER:-${P9K_KUBECONTEXT_NAME}}' + # Append the current context's namespace if it's not "default". + POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${${:-/$P9K_KUBECONTEXT_NAMESPACE}:#/default}' # Custom prefix. # typeset -g POWERLEVEL9K_KUBECONTEXT_PREFIX='%fat ' + ################[ terraform: terraform workspace (https://www.terraform.io) ]################# + # Terraform color. + typeset -g POWERLEVEL9K_TERRAFORM_FOREGROUND=38 + # Custom icon. + # typeset -g POWERLEVEL9K_TERRAFORM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ aws: aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) ]# + # AWS profile color. + typeset -g POWERLEVEL9K_AWS_FOREGROUND=208 + # Custom icon. + # typeset -g POWERLEVEL9K_AWS_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ aws_eb_env: aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) ]# + # AWS Elastic Beanstalk environment color. + typeset -g POWERLEVEL9K_AWS_EB_ENV_FOREGROUND=70 + # Custom icon. + # typeset -g POWERLEVEL9K_AWS_EB_ENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ azure: azure account name (https://docs.microsoft.com/en-us/cli/azure) ]########## + # Azure account name color. + typeset -g POWERLEVEL9K_AZURE_FOREGROUND=32 + # Custom icon. + # typeset -g POWERLEVEL9K_AZURE_VISUAL_IDENTIFIER_EXPANSION='⭐' + ###############################[ public_ip: public IP address ]############################### # Public IP color. typeset -g POWERLEVEL9K_PUBLIC_IP_FOREGROUND=94 # Custom icon. # typeset -g POWERLEVEL9K_PUBLIC_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + ########################[ vpn_ip: virtual private network indicator ]######################### + # VPN IP color. + typeset -g POWERLEVEL9K_VPN_IP_FOREGROUND=81 + # When on VPN, show just an icon without the IP address. + typeset -g POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION= + # Regular expression for the VPN network interface. Run ifconfig while on VPN to see the + # name of the interface. + typeset -g POWERLEVEL9K_VPN_IP_INTERFACE='(wg|(.*tun))[0-9]*' + # Icon to show when on VPN. + typeset -g POWERLEVEL9K_VPN_IP_VISUAL_IDENTIFIER_EXPANSION='${P9K_VISUAL_IDENTIFIER}' + + #########################[ proxy: system-wide http/https/ftp proxy ]########################## + # Proxy color. + typeset -g POWERLEVEL9K_PROXY_FOREGROUND=68 + # Custom icon. + # typeset -g POWERLEVEL9K_PROXY_VISUAL_IDENTIFIER_EXPANSION='⭐' + ################################[ battery: internal battery ]################################# # Show battery in red when it's below this level and not connected to power supply. typeset -g POWERLEVEL9K_BATTERY_LOW_THRESHOLD=20 - typeset -g POWERLEVEL9K_BATTERY_LOW_FOREGROUND=1 - # Show battery in green when it's charging. - typeset -g POWERLEVEL9K_BATTERY_CHARGING_FOREGROUND=70 - # Show battery in yellow when not connected to power supply. + typeset -g POWERLEVEL9K_BATTERY_LOW_FOREGROUND=160 + # Show battery in green when it's charging or fully charged. + typeset -g POWERLEVEL9K_BATTERY_{CHARGING,CHARGED}_FOREGROUND=70 + # Show battery in yellow when it's discharging. typeset -g POWERLEVEL9K_BATTERY_DISCONNECTED_FOREGROUND=178 # Battery pictograms going from low to high level of charge. - typeset -g POWERLEVEL9K_BATTERY_STAGES='▁▂▃▄▅▆▇' - # Display battery pictogram on black background. - typeset -g POWERLEVEL9K_BATTERY_VISUAL_IDENTIFIER_EXPANSION='%K{232}${P9K_VISUAL_IDENTIFIER}%k' - # Don't show battery when it's fully charged and connected to power supply. - typeset -g POWERLEVEL9K_BATTERY_CHARGED_{CONTENT,VISUAL_IDENTIFIER}_EXPANSION= + typeset -g POWERLEVEL9K_BATTERY_STAGES=('%K{232}▁' '%K{232}▂' '%K{232}▃' '%K{232}▄' '%K{232}▅' '%K{232}▆' '%K{232}▇' '%K{232}█') # Don't show the remaining time to charge/discharge. typeset -g POWERLEVEL9K_BATTERY_VERBOSE=false @@ -595,9 +784,9 @@ fi # prompt if `example` prompt segment is added to POWERLEVEL9K_LEFT_PROMPT_ELEMENTS or # POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS. It displays an icon and orange text greeting the user. # - # Type `p9k_prompt_segment -h` for documentation and a more sophisticated example. + # Type `p10k help segment` for documentation and a more sophisticated example. function prompt_example() { - p9k_prompt_segment -f 208 -i '⭐' -t 'hello, %n' + p10k segment -f 208 -i '⭐' -t 'hello, %n' } # User-defined prompt segments can be customized the same way as built-in segments. @@ -605,5 +794,5 @@ fi typeset -g POWERLEVEL9K_EXAMPLE_VISUAL_IDENTIFIER_EXPANSION='${P9K_VISUAL_IDENTIFIER}' } -(( ! p10k_lean_restore_aliases )) || setopt aliases -'builtin' 'unset' 'p10k_lean_restore_aliases' +(( ${#p10k_config_opts} )) && setopt ${p10k_config_opts[@]} +'builtin' 'unset' 'p10k_config_opts' diff --git a/config/p10k-pure.zsh b/config/p10k-pure.zsh index 271504e2..20f5b3f2 100644 --- a/config/p10k-pure.zsh +++ b/config/p10k-pure.zsh @@ -6,25 +6,29 @@ # - `@c4d3ec2c` instead of something like `v1.4.0~11` when in detached HEAD state. # - No automatic `git fetch` (the same as in Pure with `PURE_GIT_PULL=0`). # -# The replication of Pure prompt achieved with this config is almost exact. Apart from the -# differences listed above, prompt is identical to Pure. This includes even the bad parts. -# For example, just like in Pure, prompt will provide no indication of Git status being stale. -# This is likely to make user experience worse than with any other Powerlevel10k config. If -# you like the general style of Pure but not particularly attached to all its quirks, type -# `p9k_configure` while having Powerlevel10k theme active and pick lean style. - -# Temporarily disable aliases. -if [[ -o 'aliases' ]]; then - 'builtin' 'unsetopt' 'aliases' - local p10k_pure_restore_aliases=1 -else - local p10k_pure_restore_aliases=0 -fi +# Apart from the differences listed above, the replication of Pure prompt is exact. This includes +# even the questionable parts. For example, just like in Pure, there is no indication of Git status +# being stale; prompt symbol is the same in command, visual and overwrite vi modes; when prompt +# doesn't fit on one line, it wraps around with no attempt to shorten it. +# +# If you like the general style of Pure but not particularly attached to all its quirks, type +# `p10k configure` while having Powerlevel10k theme active and pick "Lean" style. + +# Temporarily change options. +'builtin' 'local' '-a' 'p10k_config_opts' +[[ ! -o 'aliases' ]] || p10k_config_opts+=('aliases') +[[ ! -o 'sh_glob' ]] || p10k_config_opts+=('sh_glob') +[[ ! -o 'no_brace_expand' ]] || p10k_config_opts+=('no_brace_expand') +'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand' () { emulate -L zsh setopt no_unset + # Unset all configuration options. + unset -m 'POWERLEVEL9K_*' + + # Left prompt segments. typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=( dir # current directory vcs # git status @@ -34,16 +38,19 @@ fi virtualenv # python virtual environment prompt_char # prompt symbol ) + + # Right prompt segments. typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=() - # Basic style options that define the overall look of your prompt. + # Basic style options that define the overall prompt look. typeset -g POWERLEVEL9K_BACKGROUND= # transparent background typeset -g POWERLEVEL9K_{LEFT,RIGHT}_{LEFT,RIGHT}_WHITESPACE= # no surrounding whitespace typeset -g POWERLEVEL9K_{LEFT,RIGHT}_SUBSEGMENT_SEPARATOR=' ' # separate segments with a space typeset -g POWERLEVEL9K_{LEFT,RIGHT}_SEGMENT_SEPARATOR= # no end-of-line symbol - typeset -g POWERLEVEL9K_VISUAL_IDENTIFIER_EXPANSION= # disable segment icons + typeset -g POWERLEVEL9K_VISUAL_IDENTIFIER_EXPANSION= # no segment icons - # Add an empty line before each prompt. + # Add an empty line before each prompt except the first. This doesn't emulate the bug + # in Pure that makes prompt drift down whenever you use the ALT-C binding from fzf or similar. typeset -g POWERLEVEL9K_PROMPT_ADD_NEWLINE=true # Magenta prompt symbol if the last command succeeded. @@ -57,38 +64,25 @@ fi # Prompt symbol in visual vi mode is the same as in command mode. This is unlikely # to be desired by anyone but that's how Pure does it. typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIVIS_CONTENT_EXPANSION='❮' + # Prompt symbol in overwrite vi mode is the same as in command mode. This is unlikely + # to be desired by anyone but that's how Pure does it. + typeset -g POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE=false # Grey Python Virtual Environment. typeset -g POWERLEVEL9K_VIRTUALENV_FOREGROUND=242 + # Don't show Python version. + typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_PYTHON_VERSION=false + typeset -g POWERLEVEL9K_VIRTUALENV_{LEFT,RIGHT}_DELIMITER= # Blue current directory. typeset -g POWERLEVEL9K_DIR_FOREGROUND=blue - # Make Git prompt grey in all states. Also make stale prompts appear indistinguishable from - # fresh ones. This is unlikely to be desired by anyone but that's how Pure does it. - typeset -g POWERLEVEL9K_VCS_FOREGROUND=242 - - # Disable async loading indicator to make directories that aren't Git repositories - # indistinguishable from large Git repositories without known state. This is unlikely - # to be desired by anyone but that's how Pure does it. - local vcs='${${P9K_CONTENT:#loading}:+' - # 'feature' or '@72f5c8a' if not on a branch. - vcs+='${${VCS_STATUS_LOCAL_BRANCH//\%/%%}:-%f@${VCS_STATUS_COMMIT[1,8]}}' - # '*' if dirty. - vcs+='${${${:-$VCS_STATUS_HAS_STAGED$VCS_STATUS_HAS_UNSTAGED$VCS_STATUS_HAS_UNTRACKED}:#000}:+*}' - # ⇣ if behind the remote. - vcs+='${${VCS_STATUS_COMMITS_BEHIND:#0}:+ %6F⇣}' - # ⇡ if ahead of the remote; no leading space if also behind the remote: ⇣⇡. - vcs+='${${VCS_STATUS_COMMITS_AHEAD:#0}:+${${(M)VCS_STATUS_COMMITS_BEHIND:#0}:+ }%6F⇡}}' - typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION=$vcs - # Context format when root: user@host. The first part white, the rest grey. - typeset -g POWERLEVEL9K_CONTEXT_ROOT_CONTENT_EXPANSION='%7F%n%f%242F@%m%f' - # Context format when connected over SSH: user@host. The whole thing grey. - typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_CONTENT_EXPANSION='%242F%n@%m%f' - # Don't show context when not rood and not connected over SSH. - typeset -g POWERLEVEL9K_CONTEXT_CONTENT_EXPANSION= - typeset -g POWERLEVEL9K_ALWAYS_SHOW_CONTEXT=true + typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE='%7F%n%f%242F@%m%f' + # Context format when not root: user@host. The whole thing grey. + typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE='%242F%n@%m%f' + # Don't show context unless root or in SSH. + typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_CONTENT_EXPANSION= # Show previous command duration only if it's >= 5s. typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=5 @@ -98,7 +92,39 @@ fi typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FORMAT='d h m s' # Yellow previous command duration. typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FOREGROUND=yellow + + # Grey Git prompt. This makes stale prompts indistinguishable from up-to-date ones. + typeset -g POWERLEVEL9K_VCS_FOREGROUND=242 + + # Disable async loading indicator to make directories that aren't Git repositories + # indistinguishable from large Git repositories without known state. + typeset -g POWERLEVEL9K_VCS_LOADING_TEXT= + + # Don't wait for Git status even for a millisecond, so that prompt always updates + # asynchronously when Git state changes. + typeset -g POWERLEVEL9K_VCS_MAX_SYNC_LATENCY_SECONDS=0 + + # Cyan ahead/behind arrows. + typeset -g POWERLEVEL9K_VCS_{INCOMING,OUTGOING}_CHANGESFORMAT_FOREGROUND=cyan + # Don't show remote branch, current tag or stashes. + typeset -g POWERLEVEL9K_VCS_GIT_HOOKS=(vcs-detect-changes git-untracked git-aheadbehind) + # Don't show the branh icon. + typeset -g POWERLEVEL9K_VCS_BRANCH_ICON= + # When in detached HEAD state, show @commit where branch normally goes. + typeset -g POWERLEVEL9K_VCS_COMMIT_ICON='@' + # Don't show staged, unstaged, untracked indicators. + typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED}_ICON=$'\b' + # Show '*' when there are staged, unstaged or untracked files. + typeset -g POWERLEVEL9K_VCS_DIRTY_ICON='*' + # Show '⇣' if local branch is behind remote. + typeset -g POWERLEVEL9K_VCS_INCOMING_CHANGES_ICON='⇣' + # Show '⇡' if local branch is ahead of remote. + typeset -g POWERLEVEL9K_VCS_OUTGOING_CHANGES_ICON='⇡' + # Don't show the number of commits next to the ahead/behind arrows. + typeset -g POWERLEVEL9K_VCS_{COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=1 + # Remove space between '⇣' and '⇡', and get rid of $' \b'. + typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION=$'${${P9K_CONTENT/⇣* ⇡/⇣⇡}// \b}' } -(( ! p10k_pure_restore_aliases )) || setopt aliases -'builtin' 'unset' 'p10k_pure_restore_aliases' +(( ${#p10k_config_opts} )) && setopt ${p10k_config_opts[@]} +'builtin' 'unset' 'p10k_config_opts' diff --git a/config/p10k-rainbow.zsh b/config/p10k-rainbow.zsh new file mode 100644 index 00000000..49f6ffba --- /dev/null +++ b/config/p10k-rainbow.zsh @@ -0,0 +1,844 @@ +# Config for Powerlevel10k with powerline prompt style with colorful background. +# Type `p10k configure` to generate your own config based on it. +# +# Tip: Looking for a nice color? Here's a one-liner to print colormap. +# +# for i in {0..255}; do print -Pn "%${i}F${(l:3::0:)i}%f " ${${(M)$((i%8)):#7}:+$'\n'}; done + +# Temporarily change options. +'builtin' 'local' '-a' 'p10k_config_opts' +[[ ! -o 'aliases' ]] || p10k_config_opts+=('aliases') +[[ ! -o 'sh_glob' ]] || p10k_config_opts+=('sh_glob') +[[ ! -o 'no_brace_expand' ]] || p10k_config_opts+=('no_brace_expand') +'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand' + +() { + emulate -L zsh + setopt no_unset extended_glob + zmodload zsh/langinfo + if [[ ${langinfo[CODESET]:-} != (utf|UTF)(-|)8 ]]; then + local LC_ALL=${${(@M)$(locale -a):#*.(utf|UTF)(-|)8}[1]:-en_US.UTF-8} + fi + + # Unset all configuration options. This allows you to apply configiguration changes without + # restarting zsh. Edit ~/.p10k.zsh and type `source ~/.p10k.zsh`. + unset -m 'POWERLEVEL9K_*' + + # The list of segments shown on the left. Fill it with the most important segments. + typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=( + # =========================[ Line #1 ]========================= + # os_icon # os identifier + dir # current directory + vcs # git status + # =========================[ Line #2 ]========================= + newline + # prompt_char # prompt symbol + ) + + # The list of segments shown on the right. Fill it with less important segments. + # Right prompt on the last prompt line (where you are typing your commands) gets + # automatically hidden when the input line reaches it. Right prompt above the + # last prompt line gets hidden if it would overlap with left prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=( + # =========================[ Line #1 ]========================= + status # exit code of the last command + command_execution_time # duration of the last command + background_jobs # presence of background jobs + virtualenv # python virtual environment (https://docs.python.org/3/library/venv.html) + anaconda # conda environment (https://conda.io/) + pyenv # python environment (https://github.com/pyenv/pyenv) + nodenv # node.js version from nodenv (https://github.com/nodenv/nodenv) + nvm # node.js version from nvm (https://github.com/nvm-sh/nvm) + nodeenv # node.js environment (https://github.com/ekalinin/nodeenv) + # node_version # node.js version + # go_version # go version (https://golang.org) + # rust_version # rustc version (https://www.rust-lang.org) + # dotnet_version # .NET version (https://dotnet.microsoft.com) + rbenv # ruby version from rbenv (https://github.com/rbenv/rbenv) + rvm # ruby version from rvm (https://rvm.io) + kubecontext # current kubernetes context (https://kubernetes.io/) + terraform # terraform workspace (https://www.terraform.io) + aws # aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) + # aws_eb_env # aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) + # azure # azure account name (https://docs.microsoft.com/en-us/cli/azure) + context # user@hostname + nordvpn # nordvpn connection status, linux only (https://nordvpn.com/) + ranger # ranger shell (https://github.com/ranger/ranger) + # vpn_ip # virtual private network indicator + # ram # free RAM + # load # CPU load + # time # current time + # =========================[ Line #2 ]========================= + newline + # public_ip # public IP address + # proxy # system-wide http/https/ftp proxy + # battery # internal battery + # example # example user-defined segment (see prompt_example function below) + ) + + # To disable default icons for all segments, set POWERLEVEL9K_VISUAL_IDENTIFIER_EXPANSION=''. + # + # To enable default icons for all segments, don't define POWERLEVEL9K_VISUAL_IDENTIFIER_EXPANSION + # or set it to '${P9K_VISUAL_IDENTIFIER}'. + # + # To remove trailing space from all default icons, set POWERLEVEL9K_VISUAL_IDENTIFIER_EXPANSION + # to '${P9K_VISUAL_IDENTIFIER% }'. + # + # To enable default icons for one segment (e.g., dir), set + # POWERLEVEL9K_DIR_VISUAL_IDENTIFIER_EXPANSION='${P9K_VISUAL_IDENTIFIER}'. + # + # To assign a specific icon to one segment (e.g., dir), set + # POWERLEVEL9K_DIR_VISUAL_IDENTIFIER_EXPANSION='⭐'. + # + # To assign a specific icon to a segment in a given state (e.g., dir in state NOT_WRITABLE), + # set POWERLEVEL9K_DIR_NOT_WRITABLE_VISUAL_IDENTIFIER_EXPANSION='⭐'. + # + # Note: You can use $'\u2B50' instead of '⭐'. It's especially convenient when specifying + # icons that your text editor cannot render. Don't forget to put $ and use single quotes when + # defining icons via Unicode codepoints. + # + # Note: Many default icons cannot be displayed with system fonts. You'll need to install a + # capable font to use them. See POWERLEVEL9K_MODE below. + typeset -g POWERLEVEL9K_VISUAL_IDENTIFIER_EXPANSION='${P9K_VISUAL_IDENTIFIER}' + + # This option makes a difference only when default icons are enabled for all or some prompt + # segments (see POWERLEVEL9K_VISUAL_IDENTIFIER_EXPANSION above). LOCK_ICON can be printed as + # $'\uE0A2', $'\uE138' or $'\uF023' depending on POWERLEVEL9K_MODE. The correct value of this + # parameter depends on the provider of the font your terminal is using. + # + # Font Provider | POWERLEVEL9K_MODE + # ---------------------------------+------------------- + # Powerline | powerline + # Font Awesome | awesome-fontconfig + # Adobe Source Code Pro | awesome-fontconfig + # Source Code Pro | awesome-fontconfig + # Awesome-Terminal Fonts (regular) | awesome-fontconfig + # Awesome-Terminal Fonts (patched) | awesome-patched + # Nerd Fonts | nerdfont-complete + # Other | compatible + # + # If this looks overwhelming, either stick with a preinstalled system font and set + # POWERLEVEL9K_MODE=compatible, or install the recommended Powerlevel10k font from + # https://github.com/romkatv/powerlevel10k/#recommended-meslo-nerd-font-patched-for-powerlevel10k + # and set POWERLEVEL9K_MODE=nerdfont-complete. + typeset -g POWERLEVEL9K_MODE=nerdfont-complete + + # When set to true, icons appear before content on both sides of the prompt. When set + # to false, icons go after content. If empty or not set, icons go before content in the left + # prompt and after content in the right prompt. + # + # You can also override it for a specific segment: + # + # POWERLEVEL9K_STATUS_ICON_BEFORE_CONTENT=false + # + # Or for a specific segment in specific state: + # + # POWERLEVEL9K_DIR_NOT_WRITABLE_ICON_BEFORE_CONTENT=false + typeset -g POWERLEVEL9K_ICON_BEFORE_CONTENT= + + # Add an empty line before each prompt. + typeset -g POWERLEVEL9K_PROMPT_ADD_NEWLINE=true + + # Connect left prompt lines with these symbols. You'll probably want to use the same color + # as POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_FOREGROUND below. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX='%242F╭─' + typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_PREFIX='%242F├─' + typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX='%242F╰─' + # Connect right prompt lines with these symbols. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_SUFFIX='%242F─╮' + typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_SUFFIX='%242F─┤' + typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_SUFFIX='%242F─╯' + + # Filler between left and right prompt on the first prompt line. You can set it to ' ', '·' or + # '─'. The last two make it easier to see the alignment between left and right prompt and to + # separate prompt from command output. You might want to set POWERLEVEL9K_PROMPT_ADD_NEWLINE=false + # for more compact prompt if using using this option. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR=' ' + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_BACKGROUND= + if [[ $POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR != ' ' ]]; then + # The color of the filler. You'll probably want to match the color of POWERLEVEL9K_MULTILINE + # ornaments defined above. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_FOREGROUND=242 + # Start filler from the edge of the screen if there are no left segments on the first line. + typeset -g POWERLEVEL9K_EMPTY_LINE_LEFT_PROMPT_FIRST_SEGMENT_END_SYMBOL='%{%}' + # End filler on the edge of the screen if there are no right segments on the first line. + typeset -g POWERLEVEL9K_EMPTY_LINE_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL='%{%}' + fi + + # Separator between same-color segments on the left. + typeset -g POWERLEVEL9K_LEFT_SUBSEGMENT_SEPARATOR='\uE0B1' + # Separator between same-color segments on the right. + typeset -g POWERLEVEL9K_RIGHT_SUBSEGMENT_SEPARATOR='\uE0B3' + # Separator between different-color segments on the left. + typeset -g POWERLEVEL9K_LEFT_SEGMENT_SEPARATOR='\uE0B0' + # Separator between different-color segments on the right. + typeset -g POWERLEVEL9K_RIGHT_SEGMENT_SEPARATOR='\uE0B2' + # The right end of left prompt. + typeset -g POWERLEVEL9K_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL='\uE0B0' + # The left end of right prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL='\uE0B2' + # The left end of left prompt. + typeset -g POWERLEVEL9K_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL= + # The right end of right prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL= + # Left prompt terminator for lines without any segments. + typeset -g POWERLEVEL9K_EMPTY_LINE_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL= + + #################################[ os_icon: os identifier ]################################## + # OS identifier color. + typeset -g POWERLEVEL9K_OS_ICON_FOREGROUND=255 + # typeset -g POWERLEVEL9K_OS_ICON_BACKGROUND=0 + # Make the icon bold. + typeset -g POWERLEVEL9K_OS_ICON_CONTENT_EXPANSION='%B${P9K_CONTENT}' + + ################################[ prompt_char: prompt symbol ]################################ + # Transparent background. + typeset -g POWERLEVEL9K_PROMPT_CHAR_BACKGROUND= + # Green prompt symbol if the last command succeeded. + typeset -g POWERLEVEL9K_PROMPT_CHAR_OK_{VIINS,VICMD,VIVIS}_FOREGROUND=76 + # Red prompt symbol if the last command failed. + typeset -g POWERLEVEL9K_PROMPT_CHAR_ERROR_{VIINS,VICMD,VIVIS}_FOREGROUND=196 + # Default prompt symbol. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIINS_CONTENT_EXPANSION='❯' + # Prompt symbol in command vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VICMD_CONTENT_EXPANSION='❮' + # Prompt symbol in visual vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIVIS_CONTENT_EXPANSION='Ⅴ' + # Prompt symbol in overwrite vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIOWR_CONTENT_EXPANSION='▶' + typeset -g POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE=true + # No line terminator if prompt_char is the last segment. + typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL= + # No line introducer if prompt_char is the first segment. + typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL= + # No surrounding whitespace. + typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_{LEFT,RIGHT}_WHITESPACE= + + ##################################[ dir: current directory ]################################## + # Current directory background color. + # typeset -g POWERLEVEL9K_DIR_BACKGROUND=4 + # Default current directory foreground color. + typeset -g POWERLEVEL9K_DIR_FOREGROUND=254 + # If directory is too long, shorten some of its segments to the shortest possible unique + # prefix. The shortened directory can be tab-completed to the original. + typeset -g POWERLEVEL9K_SHORTEN_STRATEGY=truncate_to_unique + # Replace removed segment suffixes with this symbol. + typeset -g POWERLEVEL9K_SHORTEN_DELIMITER= + # Color of the shortened directory segments. + typeset -g POWERLEVEL9K_DIR_SHORTENED_FOREGROUND=250 + # Color of the anchor directory segments. Anchor segments are never shortened. The first + # segment is always an anchor. + typeset -g POWERLEVEL9K_DIR_ANCHOR_FOREGROUND=255 + # Display anchor directory segments in bold. + typeset -g POWERLEVEL9K_DIR_ANCHOR_BOLD=true + # Don't shorten directories that contain any of these files. They are anchors. + local anchor_files=( + .bzr + .citc + .git + .hg + .node-version + .python-version + .ruby-version + .shorten_folder_marker + .svn + .terraform + CVS + Cargo.toml + composer.json + go.mod + package.json + ) + typeset -g POWERLEVEL9K_SHORTEN_FOLDER_MARKER="(${(j:|:)anchor_files})" + # Don't shorten this many last directory segments. They are anchors. + typeset -g POWERLEVEL9K_SHORTEN_DIR_LENGTH=1 + # Shorten directory if it's longer than this even if there is space for it. The value can + # be either absolute (e.g., '80') or a percentage of terminal width (e.g, '50%'). If empty, + # directory will be shortened only when prompt doesn't fit or when other parameters demand it + # (see POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS and POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT below). + typeset -g POWERLEVEL9K_DIR_MAX_LENGTH=80 + # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least this + # many columns for typing commands. + typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS=40 + # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least + # COLUMNS * POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT * 0.01 columns for typing commands. + typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT=50 + # If set to true, embed a hyperlink into the directory. Useful for quickly + # opening a directory in the file manager simply by clicking the link. + # Can also be handy when the directory is shortened, as it allows you to see + # the full directory that was used in previous commands. + typeset -g POWERLEVEL9K_DIR_HYPERLINK=false + + # Enable special styling for non-writable directories. + typeset -g POWERLEVEL9K_DIR_SHOW_WRITABLE=true + # Show this icon when the current directory is not writable. POWERLEVEL9K_DIR_SHOW_WRITABLE + # above must be set to true for this parameter to have effect. + # typeset -g POWERLEVEL9K_DIR_NOT_WRITABLE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Custom prefix. + # typeset -g POWERLEVEL9K_DIR_PREFIX='in ' + + # POWERLEVEL9K_DIR_CLASSES allows you to specify custom icons for different directories. + # It must be an array with 3 * N elements. Each triplet consists of: + # + # 1. A pattern against which the current directory is matched. Matching is done with + # extended_glob option enabled. + # 2. Directory class for the purpose of styling. + # 3. Icon. + # + # Triplets are tried in order. The first triplet whose pattern matches $PWD wins. If there + # are no matches, the directory will have no icon. + # + # Example: + # + # typeset -g POWERLEVEL9K_DIR_CLASSES=( + # '~/work(/*)#' WORK '(╯°□°)╯︵ ┻━┻' + # '~(/*)#' HOME '⌂' + # '*' DEFAULT '') + # + # With these settings, the current directory in the prompt may look like this: + # + # (╯°□°)╯︵ ┻━┻ ~/work/projects/important/urgent + # + # Or like this: + # + # ⌂ ~/best/powerlevel10k + # + # You can also set different colors for directories of different classes. Remember to override + # FOREGROUND, SHORTENED_FOREGROUND and ANCHOR_FOREGROUND for every directory class that you wish + # to have its own color. + # + # typeset -g POWERLEVEL9K_DIR_WORK_BACKGROUND=4 + # typeset -g POWERLEVEL9K_DIR_WORK_FOREGROUND=254 + # typeset -g POWERLEVEL9K_DIR_WORK_SHORTENED_FOREGROUND=250 + # typeset -g POWERLEVEL9K_DIR_WORK_ANCHOR_FOREGROUND=255 + # + # typeset -g POWERLEVEL9K_DIR_CLASSES=() + + #####################################[ vcs: git status ]###################################### + # Versio control system colors. + # typeset -g POWERLEVEL9K_VCS_CLEAN_BACKGROUND=2 + # typeset -g POWERLEVEL9K_VCS_MODIFIED_BACKGROUND=3 + # typeset -g POWERLEVEL9K_VCS_UNTRACKED_BACKGROUND=2 + # typeset -g POWERLEVEL9K_VCS_CONFLICTED_BACKGROUND=3 + # typeset -g POWERLEVEL9K_VCS_LOADING_BACKGROUND=8 + + # Branch icon. Set this parameter to '\uF126 ' for the popular Powerline branch icon. + typeset -g POWERLEVEL9K_VCS_BRANCH_ICON= + POWERLEVEL9K_VCS_BRANCH_ICON=${(g::)POWERLEVEL9K_VCS_BRANCH_ICON} + + # Untracked files icon. It's really a question mark, your font isn't broken. + # Change the value of this parameter to show a different icon. + typeset -g POWERLEVEL9K_VCS_UNTRACKED_ICON='?' + POWERLEVEL9K_VCS_UNTRACKED_ICON=${(g::)POWERLEVEL9K_VCS_UNTRACKED_ICON} + + # Formatter for Git status. + # + # Example output: master ⇣42⇡42 *42 merge ~42 +42 !42 ?42. + # + # You can edit the function to customize how Git status looks. + # + # VCS_STATUS_* parameters are set by gitstatus plugin. See reference: + # https://github.com/romkatv/gitstatus/blob/master/gitstatus.plugin.zsh. + function my_git_formatter() { + emulate -L zsh + + if [[ -n $P9K_CONTENT ]]; then + # If P9K_CONTENT is not empty, use it. It's either "loading" or from vcs_info (not from + # gitstatus plugin). VCS_STATUS_* parameters are not available in this case. + typeset -g my_git_format=$P9K_CONTENT + return + fi + + # Styling for different parts of Git status. + local meta='%7F' # white foreground + local clean='%0F' # black foreground + local modified='%0F' # black foreground + local untracked='%0F' # black foreground + local conflicted='%1F' # red foreground + + local res + local where # branch name, tag or commit + if [[ -n $VCS_STATUS_LOCAL_BRANCH ]]; then + res+="${clean}${POWERLEVEL9K_VCS_BRANCH_ICON}" + where=${(V)VCS_STATUS_LOCAL_BRANCH} + elif [[ -n $VCS_STATUS_TAG ]]; then + res+="${meta}#" + where=${(V)VCS_STATUS_TAG} + else + res+="${meta}@" + where=${VCS_STATUS_COMMIT[1,8]} + fi + + # If local branch name or tag is at most 32 characters long, show it in full. + # Otherwise show the first 12 … the last 12. + (( $#where > 32 )) && where[13,-13]="…" + res+="${clean}${where//\%/%%}" # escape % + + # Show tracking branch name if it differs from local branch. + if [[ -n ${VCS_STATUS_REMOTE_BRANCH:#$VCS_STATUS_LOCAL_BRANCH} ]]; then + res+="${meta}:${clean}${(V)VCS_STATUS_REMOTE_BRANCH//\%/%%}" # escape % + fi + + # ⇣42 if behind the remote. + (( VCS_STATUS_COMMITS_BEHIND )) && res+=" ${clean}⇣${VCS_STATUS_COMMITS_BEHIND}" + # ⇡42 if ahead of the remote; no leading space if also behind the remote: ⇣42⇡42. + (( VCS_STATUS_COMMITS_AHEAD && !VCS_STATUS_COMMITS_BEHIND )) && res+=" " + (( VCS_STATUS_COMMITS_AHEAD )) && res+="${clean}⇡${VCS_STATUS_COMMITS_AHEAD}" + # *42 if have stashes. + (( VCS_STATUS_STASHES )) && res+=" ${clean}*${VCS_STATUS_STASHES}" + # 'merge' if the repo is in an unusual state. + [[ -n $VCS_STATUS_ACTION ]] && res+=" ${conflicted}${VCS_STATUS_ACTION}" + # ~42 if have merge conflicts. + (( VCS_STATUS_NUM_CONFLICTED )) && res+=" ${conflicted}~${VCS_STATUS_NUM_CONFLICTED}" + # +42 if have staged changes. + (( VCS_STATUS_NUM_STAGED )) && res+=" ${modified}+${VCS_STATUS_NUM_STAGED}" + # !42 if have unstaged changes. + (( VCS_STATUS_NUM_UNSTAGED )) && res+=" ${modified}!${VCS_STATUS_NUM_UNSTAGED}" + # ?42 if have untracked files. It's really a question mark, your font isn't broken. + # See POWERLEVEL9K_VCS_UNTRACKED_ICON above if you want to use a different icon. + # Remove the next line if you don't want to see untracked files at all. + (( VCS_STATUS_NUM_UNTRACKED )) && res+=" ${untracked}${POWERLEVEL9K_VCS_UNTRACKED_ICON}${VCS_STATUS_NUM_UNTRACKED}" + + typeset -g my_git_format=$res + } + functions -M my_git_formatter 2>/dev/null + + # Disable the default Git status formatting. + typeset -g POWERLEVEL9K_VCS_DISABLE_GITSTATUS_FORMATTING=true + # Install our own Git status formatter. + typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION='${$((my_git_formatter(1)))+${my_git_format}}' + # Enable counters for staged, unstaged, etc. + typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED,CONFLICTED,COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=-1 + + # Custom icon. + # typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_VCS_PREFIX='on ' + + # Show status of repositories of these types. You can add svn and/or hg if you are + # using them. If you do, your prompt may become slow even when your current directory + # isn't in an svn or hg reposotiry. + typeset -g POWERLEVEL9K_VCS_BACKENDS=(git) + + ##########################[ status: exit code of the last command ]########################### + # Enable OK_PIPE, ERROR_PIPE and ERROR_SIGNAL status states to allow us to enable, disable and + # style them independently from the regular OK and ERROR state. + typeset -g POWERLEVEL9K_STATUS_EXTENDED_STATES=true + + # Status on success. No content, just an icon. No need to show it if prompt_char is enabled as + # it will signify success by turning green. + typeset -g POWERLEVEL9K_STATUS_OK=true + typeset -g POWERLEVEL9K_STATUS_OK_VISUAL_IDENTIFIER_EXPANSION='✔' + # typeset -g POWERLEVEL9K_STATUS_OK_FOREGROUND=2 + # typeset -g POWERLEVEL9K_STATUS_OK_BACKGROUND=0 + + # Status when some part of a pipe command fails but the overall exit status is zero. It may look + # like this: 1|0. + typeset -g POWERLEVEL9K_STATUS_OK_PIPE=true + typeset -g POWERLEVEL9K_STATUS_OK_PIPE_VISUAL_IDENTIFIER_EXPANSION='✔' + # typeset -g POWERLEVEL9K_STATUS_OK_PIPE_FOREGROUND=2 + # typeset -g POWERLEVEL9K_STATUS_OK_PIPE_BACKGROUND=0 + + # Status when it's just an error code (e.g., '1'). No need to show it if prompt_char is enabled as + # it will signify error by turning red. + typeset -g POWERLEVEL9K_STATUS_ERROR=true + typeset -g POWERLEVEL9K_STATUS_ERROR_VISUAL_IDENTIFIER_EXPANSION='↵' + # typeset -g POWERLEVEL9K_STATUS_ERROR_FOREGROUND=3 + # typeset -g POWERLEVEL9K_STATUS_ERROR_BACKGROUND=1 + + # Status when the last command was terminated by a signal. + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL=true + # Use terse signal names: "INT" instead of "SIGINT(2)". + typeset -g POWERLEVEL9K_STATUS_VERBOSE_SIGNAME=false + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_VISUAL_IDENTIFIER_EXPANSION='↵' + # typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_FOREGROUND=3 + # typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_BACKGROUND=1 + + # Status when some part of a pipe command fails and the overall exit status is also non-zero. + # It may look like this: 1|0. + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE=true + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_VISUAL_IDENTIFIER_EXPANSION='↵' + # typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_FOREGROUND=3 + # typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_BACKGROUND=1 + + ###################[ command_execution_time: duration of the last command ]################### + # Execution time color. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FOREGROUND=0 + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_BACKGROUND=3 + # Show duration of the last command if takes longer than this many seconds. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=3 + # Show this many fractional digits. Zero means round to seconds. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PRECISION=0 + # Duration format: 1d 2h 3m 4s. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FORMAT='d h m s' + # Custom icon. + # typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PREFIX='took ' + + #######################[ background_jobs: presence of background jobs ]####################### + # Background jobs color. + # typeset -g POWERLEVEL9K_BACKGROUND_JOBS_FOREGROUND=6 + # typeset -g POWERLEVEL9K_BACKGROUND_JOBS_BACKGROUND=0 + # Don't show the number of background jobs. + typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VERBOSE=false + # Icon to show when there are background jobs. + typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VISUAL_IDENTIFIER_EXPANSION='${P9K_VISUAL_IDENTIFIER}' + + ##########[ nordvpn: nordvpn connection status, linux only (https://nordvpn.com/) ]########### + # NordVPN connection indicator color. + # typeset -g POWERLEVEL9K_NORDVPN_FOREGROUND=7 + # typeset -g POWERLEVEL9K_NORDVPN_BACKGROUND=4 + # Hide NordVPN connection indicator when not connected. + typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_CONTENT_EXPANSION= + typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_VISUAL_IDENTIFIER_EXPANSION= + # Custom icon. + # typeset -g POWERLEVEL9K_NORDVPN_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #################[ ranger: ranger shell (https://github.com/ranger/ranger) ]################## + # Ranger shell color. + # typeset -g POWERLEVEL9K_RANGER_FOREGROUND=3 + # typeset -g POWERLEVEL9K_RANGER_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_RANGER_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################################[ ram: free RAM ]####################################### + # RAM color. + # typeset -g POWERLEVEL9K_RAM_FOREGROUND=0 + # typeset -g POWERLEVEL9K_RAM_BACKGROUND=3 + # Custom icon. + # typeset -g POWERLEVEL9K_RAM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################################[ load: CPU load ]###################################### + # Show average CPU load over this many last minutes. Valid values are 1, 5 and 15. + typeset -g POWERLEVEL9K_LOAD_WHICH=5 + # Load color when load is under 50%. + # typeset -g POWERLEVEL9K_LOAD_NORMAL_FOREGROUND=0 + # typeset -g POWERLEVEL9K_LOAD_NORMAL_BACKGROUND=2 + # Load color when load is between 50% and 70%. + # typeset -g POWERLEVEL9K_LOAD_WARNING_FOREGROUND=0 + # typeset -g POWERLEVEL9K_LOAD_WARNING_BACKGROUND=3 + # Load color when load is over 70%. + # typeset -g POWERLEVEL9K_LOAD_CRITICAL_FOREGROUND=0 + # typeset -g POWERLEVEL9K_LOAD_CRITICAL_BACKGROUND=1 + # Custom icon. + # typeset -g POWERLEVEL9K_LOAD_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##################################[ context: user@hostname ]################################## + # Default context color. + typeset -g POWERLEVEL9K_CONTEXT_FOREGROUND=3 + typeset -g POWERLEVEL9K_CONTEXT_BACKGROUND=0 + # Default context format: %n is username, %m is hostname. + typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE='%n@%m' + + # Context color when running with privileges. + typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND=1 + typeset -g POWERLEVEL9K_CONTEXT_ROOT_BACKGROUND=0 + # Context format when running with privileges: %n is username, %m is hostname. + typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE='%n@%m' + + # Don't show context unless running with privileges or in SSH. + # Tip: Remove the next line to always show context. + typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_{CONTENT,VISUAL_IDENTIFIER}_EXPANSION= + + # Custom icon. + # typeset -g POWERLEVEL9K_CONTEXT_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_CONTEXT_PREFIX='with ' + + ###[ virtualenv: python virtual environment (https://docs.python.org/3/library/venv.html) ]### + # Python virtual environment color. + # typeset -g POWERLEVEL9K_VIRTUALENV_FOREGROUND=0 + # typeset -g POWERLEVEL9K_VIRTUALENV_BACKGROUND=4 + # Don't show Python version next to the virtual environment name. + typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_PYTHON_VERSION=false + # Separate environment name from Python version only with a space. + typeset -g POWERLEVEL9K_VIRTUALENV_{LEFT,RIGHT}_DELIMITER= + # Custom icon. + # typeset -g POWERLEVEL9K_VIRTUALENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #####################[ anaconda: conda environment (https://conda.io/) ]###################### + # Anaconda environment color. + # typeset -g POWERLEVEL9K_ANACONDA_FOREGROUND=0 + # typeset -g POWERLEVEL9K_ANACONDA_BACKGROUND=4 + # Don't show Python version next to the anaconda environment name. + typeset -g POWERLEVEL9K_ANACONDA_SHOW_PYTHON_VERSION=false + # Separate environment name from Python version only with a space. + typeset -g POWERLEVEL9K_ANACONDA_{LEFT,RIGHT}_DELIMITER= + # Custom icon. + # typeset -g POWERLEVEL9K_ANACONDA_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ pyenv: python environment (https://github.com/pyenv/pyenv) ]################ + # Pyenv color. + # typeset -g POWERLEVEL9K_PYENV_FOREGROUND=0 + # typeset -g POWERLEVEL9K_PYENV_BACKGROUND=4 + # Don't show the current Python version if it's the same as global. + typeset -g POWERLEVEL9K_PYENV_PROMPT_ALWAYS_SHOW=false + # Custom icon. + # typeset -g POWERLEVEL9K_PYENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ nodenv: node.js version from nodenv (https://github.com/nodenv/nodenv) ]########## + # Nodenv color. + # typeset -g POWERLEVEL9K_NODENV_FOREGROUND=2 + # typeset -g POWERLEVEL9K_NODENV_BACKGROUND=0 + # Don't show node version if it's the same as global: $(nodenv version-name) == $(nodenv global). + typeset -g POWERLEVEL9K_NODENV_PROMPT_ALWAYS_SHOW=false + # Custom icon. + # typeset -g POWERLEVEL9K_NODENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############[ nvm: node.js version from nvm (https://github.com/nvm-sh/nvm) ]############### + # Nvm color. + # typeset -g POWERLEVEL9K_NVM_FOREGROUND=70 + # Custom icon. + # typeset -g POWERLEVEL9K_NVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ############[ nodeenv: node.js environment (https://github.com/ekalinin/nodeenv) ]############ + # Nodeenv color. + # typeset -g POWERLEVEL9K_NODEENV_FOREGROUND=2 + # typeset -g POWERLEVEL9K_NODEENV_BACKGROUND=0 + # Don't show Node version next to the environment name. + typeset -g POWERLEVEL9K_NODEENV_SHOW_NODE_VERSION=false + # Separate environment name from Node version only with a space. + typeset -g POWERLEVEL9K_NODEENV_{LEFT,RIGHT}_DELIMITER= + # Custom icon. + # typeset -g POWERLEVEL9K_NODEENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############################[ node_version: node.js version ]############################### + # Node version color. + # typeset -g POWERLEVEL9K_NODE_VERSION_FOREGROUND=7 + # typeset -g POWERLEVEL9K_NODE_VERSION_BACKGROUND=2 + # Show node version only when in a directory tree containing package.json. + typeset -g POWERLEVEL9K_NODE_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_NODE_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ go_version: go version (https://golang.org) ]######################## + # Go version color. + # typeset -g POWERLEVEL9K_GO_VERSION_FOREGROUND=255 + # typeset -g POWERLEVEL9K_GO_VERSION_BACKGROUND=2 + # Show go version only when in a go project subdirectory. + typeset -g POWERLEVEL9K_GO_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_GO_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #################[ rust_version: rustc version (https://www.rust-lang.org) ]################## + # Rust version color. + # typeset -g POWERLEVEL9K_RUST_VERSION_FOREGROUND=0 + # typeset -g POWERLEVEL9K_RUST_VERSION_BACKGROUND=208 + # Show rust version only when in a rust project subdirectory. + typeset -g POWERLEVEL9K_RUST_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_RUST_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ dotnet_version: .NET version (https://dotnet.microsoft.com) ]################ + # .NET version color. + # typeset -g POWERLEVEL9K_DOTNET_VERSION_FOREGROUND=7 + # typeset -g POWERLEVEL9K_DOTNET_VERSION_BACKGROUND=5 + # Show .NET version only when in a .NET project subdirectory. + typeset -g POWERLEVEL9K_DOTNET_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_DOTNET_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #############[ rbenv: ruby version from rbenv (https://github.com/rbenv/rbenv) ]############## + # Rbenv color. + # typeset -g POWERLEVEL9K_RBENV_FOREGROUND=0 + # typeset -g POWERLEVEL9K_RBENV_BACKGROUND=1 + # Don't show ruby version if it's the same as global: $(rbenv version-name) == $(rbenv global). + typeset -g POWERLEVEL9K_RBENV_PROMPT_ALWAYS_SHOW=false + # Custom icon. + # typeset -g POWERLEVEL9K_RBENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ rvm: ruby version from rvm (https://rvm.io) ]######################## + # Rvm color. + # typeset -g POWERLEVEL9K_RVM_FOREGROUND=0 + # typeset -g POWERLEVEL9K_RVM_BACKGROUND=240 + # Don't show @gemset at the end. + typeset -g POWERLEVEL9K_RVM_SHOW_GEMSET=false + # Don't show ruby- at the front. + typeset -g POWERLEVEL9K_RVM_SHOW_PREFIX=false + # Custom icon. + # typeset -g POWERLEVEL9K_RVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ terraform: terraform workspace (https://www.terraform.io) ]################# + # Terraform color. + # typeset -g POWERLEVEL9K_TERRAFORM_FOREGROUND=4 + # typeset -g POWERLEVEL9K_TERRAFORM_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_TERRAFORM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ aws: aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) ]# + # AWS profile color. + # typeset -g POWERLEVEL9K_AWS_FOREGROUND=7 + # typeset -g POWERLEVEL9K_AWS_BACKGROUND=1 + # Custom icon. + # typeset -g POWERLEVEL9K_AWS_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ aws_eb_env: aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) ]# + # AWS Elastic Beanstalk environment color. + # typeset -g POWERLEVEL9K_AWS_EB_ENV_FOREGROUND=2 + # typeset -g POWERLEVEL9K_AWS_EB_ENV_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_AWS_EB_ENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ azure: azure account name (https://docs.microsoft.com/en-us/cli/azure) ]########## + # Azure account name color. + # typeset -g POWERLEVEL9K_AZURE_FOREGROUND=7 + # typeset -g POWERLEVEL9K_AZURE_BACKGROUND=4 + # Custom icon. + # typeset -g POWERLEVEL9K_AZURE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #############[ kubecontext: current kubernetes context (https://kubernetes.io/) ]############# + # Kubernetes context classes for the purpose of using different colors, icons and expansions with + # different contexts. + # + # POWERLEVEL9K_KUBECONTEXT_CLASSES is an array with even number of elements. The first element + # in each pair defines a pattern against which the current kubernetes context gets matched. + # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below) + # that gets matched. If you unset all POWERLEVEL9K_KUBECONTEXT_*CONTENT_EXPANSION parameters, + # you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_KUBECONTEXT_CLASSES defines the context class. Patterns are tried in order. The + # first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=( + # '*prod*' PROD + # '*test*' TEST + # '*' DEFAULT) + # + # If your current kubernetes context is "deathray-testing/default", its class is TEST + # because "deathray-testing/default" doesn't match the pattern '*prod*' but does match '*test*'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_FOREGROUND=0 + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_BACKGROUND=2 + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' + typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=( + # '*prod*' PROD # These values are examples that are unlikely + # '*test*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_FOREGROUND=7 + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_BACKGROUND=5 + # typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Use POWERLEVEL9K_KUBECONTEXT_CONTENT_EXPANSION to specify the content displayed by kubecontext + # segment. Parameter expansions are very flexible and fast, too. See reference: + # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion. + # + # Within the expansion the following parameters are always available: + # + # - P9K_CONTENT The content that would've been displayed if there was no content + # expansion defined. + # - P9K_KUBECONTEXT_NAME The current context's name. Corresponds to column NAME in the + # output of `kubectl config get-contexts`. + # - P9K_KUBECONTEXT_CLUSTER The current context's cluster. Corresponds to column CLUSTER in the + # output of `kubectl config get-contexts`. + # - P9K_KUBECONTEXT_NAMESPACE The current context's namespace. Corresponds to column NAMESPACE + # in the output of `kubectl config get-contexts`. If there is no + # namespace, the parameter is set to "default". + # + # If the context points to Google Kubernetes Engine (GKE) or Elastic Kubernetes Service (EKS), + # the following extra parameters are available: + # + # - P9K_KUBECONTEXT_CLOUD_NAME Either "gke" or "eks". + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT Account/project ID. + # - P9K_KUBECONTEXT_CLOUD_ZONE Availability zone. + # - P9K_KUBECONTEXT_CLOUD_CLUSTER Cluster. + # + # P9K_KUBECONTEXT_CLOUD_* parameters are derived from P9K_KUBECONTEXT_CLUSTER. For example, + # if P9K_KUBECONTEXT_CLUSTER is "gke_my-account_us-east1-a_my-cluster-01": + # + # - P9K_KUBECONTEXT_CLOUD_NAME=gke + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=my-account + # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east1-a + # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01 + # + # If P9K_KUBECONTEXT_CLUSTER is "arn:aws:eks:us-east-1:123456789012:cluster/my-cluster-01": + # + # - P9K_KUBECONTEXT_CLOUD_NAME=eks + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=123456789012 + # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east-1 + # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01 + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION= + # Show P9K_KUBECONTEXT_CLOUD_CLUSTER if it's not empty and fall back to P9K_KUBECONTEXT_NAME. + POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${P9K_KUBECONTEXT_CLOUD_CLUSTER:-${P9K_KUBECONTEXT_NAME}}' + # Append the current context's namespace if it's not "default". + POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${${:-/$P9K_KUBECONTEXT_NAMESPACE}:#/default}' + + # Custom prefix. + # typeset -g POWERLEVEL9K_KUBECONTEXT_PREFIX='at ' + + ###############################[ public_ip: public IP address ]############################### + # Public IP color. + # typeset -g POWERLEVEL9K_PUBLIC_IP_FOREGROUND=7 + # typeset -g POWERLEVEL9K_PUBLIC_IP_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_PUBLIC_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ########################[ vpn_ip: virtual private network indicator ]######################### + # VPN IP color. + # typeset -g POWERLEVEL9K_VPN_IP_FOREGROUND=0 + # typeset -g POWERLEVEL9K_VPN_IP_BACKGROUND=6 + # When on VPN, show just an icon without the IP address. + typeset -g POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION= + # Regular expression for the VPN network interface. Run ifconfig while on VPN to see the + # name of the interface. + typeset -g POWERLEVEL9K_VPN_IP_INTERFACE='(wg|(.*tun))[0-9]*' + # Icon to show when on VPN. + typeset -g POWERLEVEL9K_VPN_IP_VISUAL_IDENTIFIER_EXPANSION='${P9K_VISUAL_IDENTIFIER}' + + #########################[ proxy: system-wide http/https/ftp proxy ]########################## + # Proxy color. + # typeset -g POWERLEVEL9K_PROXY_FOREGROUND=4 + # typeset -g POWERLEVEL9K_PROXY_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_PROXY_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################################[ battery: internal battery ]################################# + # Show battery in red when it's below this level and not connected to power supply. + typeset -g POWERLEVEL9K_BATTERY_LOW_THRESHOLD=20 + typeset -g POWERLEVEL9K_BATTERY_LOW_FOREGROUND=1 + # Show battery in green when it's charging or fully charged. + typeset -g POWERLEVEL9K_BATTERY_{CHARGING,CHARGED}_FOREGROUND=2 + # Show battery in yellow when it's discharging. + typeset -g POWERLEVEL9K_BATTERY_DISCONNECTED_FOREGROUND=3 + # Battery pictograms going from low to high level of charge. + typeset -g POWERLEVEL9K_BATTERY_STAGES=('%K{232}▁' '%K{232}▂' '%K{232}▃' '%K{232}▄' '%K{232}▅' '%K{232}▆' '%K{232}▇' '%K{232}█') + # Don't show the remaining time to charge/discharge. + typeset -g POWERLEVEL9K_BATTERY_VERBOSE=false + # typeset -g POWERLEVEL9K_BATTERY_BACKGROUND=0 + + ####################################[ time: current time ]#################################### + # Current time color. + # typeset -g POWERLEVEL9K_TIME_FOREGROUND=0 + # typeset -g POWERLEVEL9K_TIME_BACKGROUND=7 + # Format for the current time: 09:51:02. See `man 3 strftime`. + typeset -g POWERLEVEL9K_TIME_FORMAT='%D{%H:%M:%S}' + # If set to true, time will update when you hit enter. This way prompts for the past + # commands will contain the start times of their commands as opposed to the default + # behavior where they contain the end times of their preceding commands. + typeset -g POWERLEVEL9K_TIME_UPDATE_ON_COMMAND=false + # Custom icon. + # typeset -g POWERLEVEL9K_TIME_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_TIME_PREFIX='at ' + + # Example of a user-defined prompt segment. Function prompt_example will be called on every + # prompt if `example` prompt segment is added to POWERLEVEL9K_LEFT_PROMPT_ELEMENTS or + # POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS. It displays an icon and orange text greeting the user. + # + # Type `p10k help segment` for documentation and a more sophisticated example. + function prompt_example() { + p10k segment -b red -f yellow -i '⭐' -t 'hello, %n' + } + + # User-defined prompt segments can be customized the same way as built-in segments. + # typeset -g POWERLEVEL9K_EXAMPLE_FOREGROUND=4 + typeset -g POWERLEVEL9K_EXAMPLE_VISUAL_IDENTIFIER_EXPANSION='${P9K_VISUAL_IDENTIFIER}' +} + +(( ${#p10k_config_opts} )) && setopt ${p10k_config_opts[@]} +'builtin' 'unset' 'p10k_config_opts' diff --git a/demo.png b/demo.png deleted file mode 100644 index 9a9cf16e..00000000 Binary files a/demo.png and /dev/null differ diff --git a/gitstatus/README.md b/gitstatus/README.md index 2196d30f..bfe8c3e3 100644 --- a/gitstatus/README.md +++ b/gitstatus/README.md @@ -1,2 +1 @@ This is a bundled copy of [gitstatus](https://github.com/romkatv/gitstatus) ZSH plugin. - diff --git a/gitstatus/bin/gitstatusd-android-aarch64 b/gitstatus/bin/gitstatusd-android-aarch64 index 3da517d3..e9b22e72 100755 Binary files a/gitstatus/bin/gitstatusd-android-aarch64 and b/gitstatus/bin/gitstatusd-android-aarch64 differ diff --git a/gitstatus/bin/gitstatusd-cygwin_nt-10.0-x86_64 b/gitstatus/bin/gitstatusd-cygwin_nt-10.0-x86_64 index 51a1f0a0..a1baa948 100755 Binary files a/gitstatus/bin/gitstatusd-cygwin_nt-10.0-x86_64 and b/gitstatus/bin/gitstatusd-cygwin_nt-10.0-x86_64 differ diff --git a/gitstatus/bin/gitstatusd-darwin-x86_64 b/gitstatus/bin/gitstatusd-darwin-x86_64 index 31eb9db3..fb4e4a02 100755 Binary files a/gitstatus/bin/gitstatusd-darwin-x86_64 and b/gitstatus/bin/gitstatusd-darwin-x86_64 differ diff --git a/gitstatus/bin/gitstatusd-freebsd-amd64 b/gitstatus/bin/gitstatusd-freebsd-amd64 index 20d77a41..de7e0f24 100755 Binary files a/gitstatus/bin/gitstatusd-freebsd-amd64 and b/gitstatus/bin/gitstatusd-freebsd-amd64 differ diff --git a/gitstatus/bin/gitstatusd-linux-aarch64 b/gitstatus/bin/gitstatusd-linux-aarch64 index ebae869a..b99ecfee 100755 Binary files a/gitstatus/bin/gitstatusd-linux-aarch64 and b/gitstatus/bin/gitstatusd-linux-aarch64 differ diff --git a/gitstatus/bin/gitstatusd-linux-armv7l b/gitstatus/bin/gitstatusd-linux-armv7l index 89b59a74..3d301aa9 100755 Binary files a/gitstatus/bin/gitstatusd-linux-armv7l and b/gitstatus/bin/gitstatusd-linux-armv7l differ diff --git a/gitstatus/bin/gitstatusd-linux-x86_64 b/gitstatus/bin/gitstatusd-linux-x86_64 index 802f71ac..36691cf4 100755 Binary files a/gitstatus/bin/gitstatusd-linux-x86_64 and b/gitstatus/bin/gitstatusd-linux-x86_64 differ diff --git a/gitstatus/bin/gitstatusd-linux-x86_64-static b/gitstatus/bin/gitstatusd-linux-x86_64-static index 8eee5b55..b561edd9 100755 Binary files a/gitstatus/bin/gitstatusd-linux-x86_64-static and b/gitstatus/bin/gitstatusd-linux-x86_64-static differ diff --git a/gitstatus/gitstatus.plugin.zsh b/gitstatus/gitstatus.plugin.zsh index 6750aa4a..6e603ae3 100644 --- a/gitstatus/gitstatus.plugin.zsh +++ b/gitstatus/gitstatus.plugin.zsh @@ -19,51 +19,56 @@ # # Example: Start gitstatusd, send it a request, wait for response and print it. # -# source gitstatus.plugin.zsh +# source ~/gitstatus/gitstatus.plugin.zsh # gitstatus_start MY # gitstatus_query -d $PWD MY -# set | egrep '^VCS_STATUS' +# typeset -m 'VCS_STATUS_*' # # Output: # # VCS_STATUS_ACTION='' -# VCS_STATUS_COMMIT=6e86ec135bf77875e222463cbac8ef72a7e8d823 +# VCS_STATUS_COMMIT=c000eddcff0fb38df2d0137efe24d9d2d900f209 # VCS_STATUS_COMMITS_AHEAD=0 # VCS_STATUS_COMMITS_BEHIND=0 -# VCS_STATUS_INDEX_SIZE=42 -# VCS_STATUS_NUM_STAGED=0 -# VCS_STATUS_NUM_UNSTAGED=2 -# VCS_STATUS_NUM_UNTRACKED=3 +# VCS_STATUS_HAS_CONFLICTED=0 # VCS_STATUS_HAS_STAGED=0 # VCS_STATUS_HAS_UNSTAGED=1 # VCS_STATUS_HAS_UNTRACKED=1 +# VCS_STATUS_INDEX_SIZE=33 # VCS_STATUS_LOCAL_BRANCH=master +# VCS_STATUS_NUM_CONFLICTED=0 +# VCS_STATUS_NUM_STAGED=0 +# VCS_STATUS_NUM_UNSTAGED=1 +# VCS_STATUS_NUM_UNSTAGED_DELETED=0 +# VCS_STATUS_NUM_UNTRACKED=1 # VCS_STATUS_REMOTE_BRANCH=master # VCS_STATUS_REMOTE_NAME=origin # VCS_STATUS_REMOTE_URL=git@github.com:romkatv/powerlevel10k.git # VCS_STATUS_RESULT=ok-sync # VCS_STATUS_STASHES=0 # VCS_STATUS_TAG='' -# VCS_STATUS_WORKDIR=/home/romka/.oh-my-zsh/custom/themes/powerlevel10k +# VCS_STATUS_WORKDIR=/home/romka/powerlevel10k [[ -o 'interactive' ]] || 'return' -# Temporarily disable aliases. -if [[ -o 'aliases' ]]; then - 'builtin' 'unsetopt' 'aliases' - local _gitstatus_restore_aliases=1 -else - local _gitstatus_restore_aliases=0 -fi +# Temporarily change options. +'builtin' 'local' '-a' '_gitstatus_opts' +[[ ! -o 'aliases' ]] || _gitstatus_opts+=('aliases') +[[ ! -o 'sh_glob' ]] || _gitstatus_opts+=('sh_glob') +[[ ! -o 'no_brace_expand' ]] || _gitstatus_opts+=('no_brace_expand') +'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand' autoload -Uz add-zsh-hook zmodload zsh/datetime zsh/system +typeset -g _gitstatus_plugin_dir=${${(%):-%x}:A:h} + # Retrives status of a git repo from a directory under its working tree. # ## Usage: gitstatus_query [OPTION]... NAME # -# -d STR Directory to query. Defaults to ${${GIT_DIR:-$PWD}:a}. Must be absolute. +# -d STR Directory to query. Must be absolute. Defaults to $GIT_DIR or the current +# directory if GIT_DIR is not set. # -c STR Callback function to call once the results are available. Called only after # gitstatus_query returns 0 with VCS_STATUS_RESULT=tout. # -t FLOAT Timeout in seconds. Will block for at most this long. If no results are @@ -71,7 +76,7 @@ zmodload zsh/datetime zsh/system # VCS_STATUS_RESULT=tout and return 0. # -p Don't compute anything that requires reading Git index. If this option is used, # the following parameters will be 0: VCS_STATUS_INDEX_SIZE, -# VCS_STATUS_{NUM,HAS}_{STAGED,UNSTAGED,UNTRACKED}. +# VCS_STATUS_{NUM,HAS}_{STAGED,UNSTAGED,UNTRACKED,CONFLICTED}. # # On success sets VCS_STATUS_RESULT to one of the following values: # @@ -86,33 +91,37 @@ zmodload zsh/datetime zsh/system # # If VCS_STATUS_RESULT is ok-sync or ok-async, additional variables are set: # -# VCS_STATUS_WORKDIR Git repo working directory. Not empty. -# VCS_STATUS_COMMIT Commit hash that HEAD is pointing to. Either 40 hex digits or empty -# if there is no HEAD (empty repo). -# VCS_STATUS_LOCAL_BRANCH Local branch name or empty if not on a branch. -# VCS_STATUS_REMOTE_NAME The remote name, e.g. "upstream" or "origin". -# VCS_STATUS_REMOTE_BRANCH Upstream branch name. Can be empty. -# VCS_STATUS_REMOTE_URL Remote URL. Can be empty. -# VCS_STATUS_ACTION Repository state, A.K.A. action. Can be empty. -# VCS_STATUS_INDEX_SIZE The number of files in the index. -# VCS_STATUS_NUM_STAGED The number of staged changes. -# VCS_STATUS_NUM_CONFLICTED The number of unstaged changes. -# VCS_STATUS_NUM_UNSTAGED The number of unstaged changes. -# VCS_STATUS_NUM_UNTRACKED The number of untracked files. -# VCS_STATUS_HAS_STAGED 1 if there are staged changes, 0 otherwise. -# VCS_STATUS_HAS_CONFLICTED 1 if there are conflicted changes, 0 otherwise. -# VCS_STATUS_HAS_UNSTAGED 1 if there are unstaged changes, 0 if there aren't, -1 if unknown. -# VCS_STATUS_HAS_UNTRACKED 1 if there are untracked files, 0 if there aren't, -1 if unknown. -# VCS_STATUS_COMMITS_AHEAD Number of commits the current branch is ahead of upstream. -# Non-negative integer. -# VCS_STATUS_COMMITS_BEHIND Number of commits the current branch is behind upstream. Non-negative -# integer. -# VCS_STATUS_STASHES Number of stashes. Non-negative integer. -# VCS_STATUS_TAG The last tag (in lexicographical order) that points to the same -# commit as HEAD. +# VCS_STATUS_WORKDIR Git repo working directory. Not empty. +# VCS_STATUS_COMMIT Commit hash that HEAD is pointing to. Either 40 hex digits or +# empty if there is no HEAD (empty repo). +# VCS_STATUS_LOCAL_BRANCH Local branch name or empty if not on a branch. +# VCS_STATUS_REMOTE_NAME The remote name, e.g. "upstream" or "origin". +# VCS_STATUS_REMOTE_BRANCH Upstream branch name. Can be empty. +# VCS_STATUS_REMOTE_URL Remote URL. Can be empty. +# VCS_STATUS_ACTION Repository state, A.K.A. action. Can be empty. +# VCS_STATUS_INDEX_SIZE The number of files in the index. +# VCS_STATUS_NUM_STAGED The number of staged changes. +# VCS_STATUS_NUM_CONFLICTED The number of conflicted changes. +# VCS_STATUS_NUM_UNSTAGED The number of unstaged changes. +# VCS_STATUS_NUM_UNTRACKED The number of untracked files. +# VCS_STATUS_HAS_STAGED 1 if there are staged changes, 0 otherwise. +# VCS_STATUS_HAS_CONFLICTED 1 if there are conflicted changes, 0 otherwise. +# VCS_STATUS_HAS_UNSTAGED 1 if there are unstaged changes, 0 if there aren't, -1 if +# unknown. +# VCS_STATUS_NUM_UNSTAGED_DELETED The number of unstaged deleted files. Note that renamed files +# are reported as deleted plus added. +# VCS_STATUS_HAS_UNTRACKED 1 if there are untracked files, 0 if there aren't, -1 if +# unknown. +# VCS_STATUS_COMMITS_AHEAD Number of commits the current branch is ahead of upstream. +# Non-negative integer. +# VCS_STATUS_COMMITS_BEHIND Number of commits the current branch is behind upstream. +# Non-negative integer. +# VCS_STATUS_STASHES Number of stashes. Non-negative integer. +# VCS_STATUS_TAG The last tag (in lexicographical order) that points to the same +# commit as HEAD. # -# The point of reporting -1 as unstaged and untracked is to allow the command to skip scanning -# files in large repos. See -m flag of gitstatus_start. +# The point of reporting -1 via VCS_STATUS_HAS_* is to allow the command to skip scanning files in +# large repos. See -m flag of gitstatus_start. # # gitstatus_query returns an error if gitstatus_start hasn't been called in the same shell or # the call had failed. @@ -126,8 +135,8 @@ function gitstatus_query() { setopt err_return no_unset local opt - local dir=${${GIT_DIR:-$PWD}:a} - local callback='' + local dir=${GIT_DIR:-} + local callback local -F timeout=-1 local no_diff=0 while true; do @@ -144,12 +153,15 @@ function gitstatus_query() { (( OPTIND == ARGC )) || { echo "usage: gitstatus_query [OPTION]... NAME" >&2; return 1 } local name=${*[$OPTIND]} - [[ -n ${(P)${:-GITSTATUS_DAEMON_PID_${name}}:-} ]] + local daemon_pid_var=GITSTATUS_DAEMON_PID_${name} + (( ${(P)daemon_pid_var:-0} > 0 )) # Verify that gitstatus_query is running in the same process that ran gitstatus_start. local client_pid_var=_GITSTATUS_CLIENT_PID_${name} [[ ${(P)client_pid_var} == $$ ]] + [[ $dir == /* ]] || dir=${(%):-%/}/$dir + local req_fd_var=_GITSTATUS_REQ_FD_${name} local -i req_fd=${(P)req_fd_var} local -r req_id="$EPOCHREALTIME" @@ -203,6 +215,7 @@ function _gitstatus_process_response() { typeset -gi VCS_STATUS_COMMITS_BEHIND="${resp[16]}" typeset -gi VCS_STATUS_STASHES="${resp[17]}" typeset -g VCS_STATUS_TAG="${resp[18]}" + typeset -gi VCS_STATUS_NUM_UNSTAGED_DELETED="${resp[19]:-0}" typeset -gi VCS_STATUS_HAS_STAGED=$((VCS_STATUS_NUM_STAGED > 0)) (( dirty_max_index_size >= 0 && VCS_STATUS_INDEX_SIZE > dirty_max_index_size )) && { typeset -gi VCS_STATUS_HAS_UNSTAGED=-1 @@ -235,6 +248,7 @@ function _gitstatus_process_response() { unset VCS_STATUS_COMMITS_BEHIND unset VCS_STATUS_STASHES unset VCS_STATUS_TAG + unset VCS_STATUS_NUM_UNSTAGED_DELETED } (( ! ours )) && (( #header )) && emulate -L zsh && "${header[@]}" || true @@ -261,6 +275,8 @@ function _gitstatus_process_response() { # # -m INT If a repo has more files in its index than this, override -u and -d (but not -s) # with zeros. Negative value means infinity. Defaults to -1. +# +# -e Count files within untracked directories like `git status --untracked-files`. function gitstatus_start() { emulate -L zsh setopt err_return no_unset no_bg_nice @@ -272,15 +288,20 @@ function gitstatus_start() { local -i max_num_conflicted=1 local -i max_num_untracked=1 local -i dirty_max_index_size=-1 + local -i async + local recurse_untracked_dirs while true; do - getopts "t:s:u:d:m:" opt || break + getopts "t:s:u:c:d:m:ea" opt || break case $opt in + a) async=1;; t) timeout=$OPTARG;; s) max_num_staged=$OPTARG;; u) max_num_unstaged=$OPTARG;; c) max_num_conflicted=$OPTARG;; d) max_num_untracked=$OPTARG;; m) dirty_max_index_size=$OPTARG;; + e) recurse_untracked_dirs='--recurse-untracked-dirs';; + +e) recurse_untracked_dirs=;; ?) return 1;; esac done @@ -289,139 +310,170 @@ function gitstatus_start() { (( OPTIND == ARGC )) || { echo "usage: gitstatus_start [OPTION]... NAME" >&2; return 1 } local name=${*[$OPTIND]} - [[ -z ${(P)${:-GITSTATUS_DAEMON_PID_${name}}:-} ]] || return 0 - - local dir && dir=${${(%):-%x}:A:h} - local xtrace_file lock_file req_fifo resp_fifo log_file - local -i stderr_fd=-1 lock_fd=-1 req_fd=-1 resp_fd=-1 daemon_pid=-1 - - function gitstatus_start_impl() { - local log_level=${GITSTATUS_LOG_LEVEL:-} + local lock_file req_fifo resp_fifo log_level + local log_file=/dev/null xtrace_file=/dev/null + local -i stderr_fd lock_fd req_fd resp_fd daemon_pid + local daemon_pid_var=GITSTATUS_DAEMON_PID_${name} + (( $+parameters[$daemon_pid_var] )) && { + (( ! async )) || return 0 + daemon_pid=${(P)daemon_pid_var} + (( daemon_pid == -1 )) || return 0 + local resp_fd_var=_GITSTATUS_RESP_FD_${name} + local log_file_var=GITSTATUS_DAEMON_LOG_${name} + local xtrace_file_var=GITSTATUS_XTRACE_${name} + resp_fd=${(P)resp_fd_var} + log_file=${(P)log_file_var} + xtrace_file=${(P)xtrace_file_var} + } || { + log_level=${GITSTATUS_LOG_LEVEL:-} [[ -n $log_level || ${GITSTATUS_ENABLE_LOGGING:-0} != 1 ]] || log_level=INFO - [[ -z $log_level ]] || { - xtrace_file=$(mktemp "${TMPDIR:-/tmp}"/gitstatus.$$.xtrace.XXXXXXXXXX) - typeset -g GITSTATUS_XTRACE_${name}=$xtrace_file - exec {stderr_fd}>&2 2>$xtrace_file - setopt xtrace + log_file=${TMPDIR:-/tmp}/gitstatus.$$.daemon-log.$EPOCHREALTIME.$RANDOM + xtrace_file=${TMPDIR:-/tmp}/gitstatus.$$.xtrace.$EPOCHREALTIME.$RANDOM } - - local os && os=$(uname -s) && [[ -n $os ]] - [[ $os != Linux || $(uname -o) != Android ]] || os=Android - local arch && arch=$(uname -m) && [[ -n $arch ]] - - local daemon=${GITSTATUS_DAEMON:-$dir/bin/gitstatusd-${os:l}-${arch:l}} - [[ -f $daemon ]] - - lock_file=$(mktemp "${TMPDIR:-/tmp}"/gitstatus.$$.lock.XXXXXXXXXX) - zsystem flock -f lock_fd $lock_file - - req_fifo=$(mktemp -u "${TMPDIR:-/tmp}"/gitstatus.$$.pipe.req.XXXXXXXXXX) - mkfifo $req_fifo - - resp_fifo=$(mktemp -u "${TMPDIR:-/tmp}"/gitstatus.$$.pipe.resp.XXXXXXXXXX) - mkfifo $resp_fifo - - [[ -n $log_level ]] && - log_file=$(mktemp "${TMPDIR:-/tmp}"/gitstatus.$$.daemon-log.XXXXXXXXXX) || - log_file=/dev/null typeset -g GITSTATUS_DAEMON_LOG_${name}=$log_file + typeset -g GITSTATUS_XTRACE_${name}=$xtrace_file + } - local -i threads=${GITSTATUS_NUM_THREADS:-0} - (( threads > 0)) || { - threads=8 - case $os in - FreeBSD) (( ! $+commands[sysctl] )) || threads=$(( 2 * $(sysctl -n hw.ncpu) ));; - *) (( ! $+commands[getconf] )) || threads=$(( 2 * $(getconf _NPROCESSORS_ONLN) ));; - esac - (( threads <= 32 )) || threads=32 + function gitstatus_start_impl() { + [[ $xtrace_file == /dev/null ]] || { + exec {stderr_fd}>&2 2>>$xtrace_file + setopt xtrace } - local -a daemon_args=( - --lock-fd=3 - --parent-pid=${(q)$} - --num-threads=${(q)threads} - --max-num-staged=${(q)max_num_staged} - --max-num-unstaged=${(q)max_num_unstaged} - --max-num-conflicted=${(q)max_num_conflicted} - --max-num-untracked=${(q)max_num_untracked} - --dirty-max-index-size=${(q)dirty_max_index_size} - ${${log_level:#INFO}:+--log-level=$log_level}) - - local cmd=" - echo \$\$ - ${(q)daemon} $daemon_args - if [[ \$? != (0|10) && \$? -le 128 && - -z ${(q)GITSTATUS_DAEMON:-} && - -f ${(q)daemon}-static ]]; then - ${(q)daemon}-static $daemon_args - fi - echo -nE $'bye\x1f0\x1e'" - local setsid=${commands[setsid]:-/usr/local/opt/util-linux/bin/setsid} - [[ -f $setsid ]] && setsid=${(q)setsid} || setsid= - cmd="$setsid zsh -dfxc ${(q)cmd} &!" - # We use `zsh -c` instead of plain {} or () to work around bugs in zplug. It hangs on startup. - # Double fork is to daemonize. Some macOS users had issues when gitstatusd was a child process - # of the interactive zsh. For example, https://github.com/romkatv/powerlevel10k/issues/123 - # and https://github.com/romkatv/powerlevel10k/issues/97. Note that on macOS setsid has to - # be installed manually by running `brew install util-linux`. Unfortunately, none of these - # helped to resolve https://github.com/romkatv/powerlevel10k/issues/123. - zsh -dfmxc $cmd <$req_fifo >$resp_fifo 2>$log_file 3<$lock_file &! - - sysopen -w -o cloexec,sync -u req_fd $req_fifo - sysopen -r -o cloexec -u resp_fd $resp_fifo - - read -u $resp_fd daemon_pid - - rm -f $req_fifo $resp_fifo $lock_file - - function _gitstatus_process_response_${name}() { - _gitstatus_process_response ${${(%)${:-%N}}#_gitstatus_process_response_} 0 '' + (( daemon_pid == -1 )) || { + local daemon=${GITSTATUS_DAEMON:-} os + [[ -n $daemon ]] || { + os="$(uname -s)" && [[ -n $os ]] + [[ $os != Linux || "$(uname -o)" != Android ]] || os=Android + local arch && arch="$(uname -m)" && [[ -n $arch ]] + daemon=$_gitstatus_plugin_dir/bin/gitstatusd-${os:l}-${arch:l} + } + [[ -x $daemon ]] + + lock_file=${TMPDIR:-/tmp}/gitstatus.$$.lock.$EPOCHREALTIME.$RANDOM + echo -n >$lock_file + zsystem flock -f lock_fd $lock_file + + req_fifo=${TMPDIR:-/tmp}/gitstatus.$$.req.$EPOCHREALTIME.$RANDOM + resp_fifo=${TMPDIR:-/tmp}/gitstatus.$$.resp.$EPOCHREALTIME.$RANDOM + mkfifo $req_fifo $resp_fifo + + local -i threads=${GITSTATUS_NUM_THREADS:-0} + (( threads > 0)) || { + threads=8 + [[ -n $os ]] || { os="$(uname -s)" && [[ -n $os ]] } + case $os in + FreeBSD) (( ! $+commands[sysctl] )) || threads=$(( 2 * $(sysctl -n hw.ncpu) ));; + *) (( ! $+commands[getconf] )) || threads=$(( 2 * $(getconf _NPROCESSORS_ONLN) ));; + esac + (( threads <= 32 )) || threads=32 + } + + local -a daemon_args=( + --lock-fd=3 + --parent-pid=${(q)$} + --num-threads=${(q)threads} + --max-num-staged=${(q)max_num_staged} + --max-num-unstaged=${(q)max_num_unstaged} + --max-num-conflicted=${(q)max_num_conflicted} + --max-num-untracked=${(q)max_num_untracked} + --dirty-max-index-size=${(q)dirty_max_index_size} + --log-level=${(q)log_level:-INFO} + $recurse_untracked_dirs) + + local cmd=" + echo \$\$ + ${(q)daemon} $daemon_args + if [[ \$? != (0|10) && \$? -le 128 && -f ${(q)daemon}-static ]]; then + ${(q)daemon}-static $daemon_args + fi + echo -nE $'bye\x1f0\x1e'" + local setsid=${commands[setsid]:-/usr/local/opt/util-linux/bin/setsid} + [[ -x $setsid ]] && setsid=${(q)setsid} || setsid= + cmd="cd /; read; $setsid zsh -dfxc ${(q)cmd} &!; rm -f ${(q)req_fifo} ${(q)resp_fifo} ${(q)lock_file}" + # We use `zsh -c` instead of plain {} or () to work around bugs in zplug (it hangs on + # startup). Double fork is to daemonize, and so is `setsid`. Note that on macOS `setsid` has + # to be installed manually by running `brew install util-linux`. + zsh -dfmxc $cmd <$req_fifo >$resp_fifo 2>$log_file 3<$lock_file &! + + sysopen -w -o cloexec,sync -u req_fd $req_fifo + sysopen -r -o cloexec -u resp_fd $resp_fifo + echo -nE $'0\nhello\x1f\x1e' >&$req_fd } - zle -F $resp_fd _gitstatus_process_response_${name} - - local reply IFS='' - echo -nE $'hello\x1f\x1e' >&$req_fd - read -r -d $'\x1e' -u $resp_fd -t $timeout reply - [[ $reply == $'hello\x1f0' ]] - - function _gitstatus_cleanup_${ZSH_SUBSHELL}_${daemon_pid}() { - emulate -L zsh - setopt err_return no_unset - local fname=${(%):-%N} - local prefix=_gitstatus_cleanup_${ZSH_SUBSHELL}_ - [[ $fname == ${prefix}* ]] || return 0 - local -i daemon_pid=${fname#$prefix} - kill -- -$daemon_pid &>/dev/null || true + + (( async )) && { + daemon_pid=-1 + } || { + read -u $resp_fd daemon_pid + + function _gitstatus_process_response_${name}() { + local name=${${(%):-%N}#_gitstatus_process_response_} + (( ARGC == 1 )) && { + _gitstatus_process_response $name 0 '' + true + } || { + gitstatus_stop $name + } + } + zle -F $resp_fd _gitstatus_process_response_${name} + + local reply IFS='' + read -r -d $'\x1e' -u $resp_fd -t $timeout reply + [[ $reply == $'hello\x1f0' ]] + + function _gitstatus_cleanup_$$_${ZSH_SUBSHELL}_${daemon_pid}() { + emulate -L zsh + setopt err_return no_unset + local fname=${(%):-%N} + local prefix=_gitstatus_cleanup_$$_${ZSH_SUBSHELL}_ + [[ $fname == ${prefix}* ]] || return 0 + local -i daemon_pid=${fname#$prefix} + kill -- -$daemon_pid &>/dev/null || true + } + add-zsh-hook zshexit _gitstatus_cleanup_$$_${ZSH_SUBSHELL}_${daemon_pid} } - add-zsh-hook zshexit _gitstatus_cleanup_${ZSH_SUBSHELL}_${daemon_pid} - [[ $stderr_fd == -1 ]] || { + (( ! stderr_fd )) || { unsetopt xtrace exec 2>&$stderr_fd {stderr_fd}>&- - stderr_fd=-1 + stderr_fd=0 } } gitstatus_start_impl && { typeset -gi GITSTATUS_DAEMON_PID_${name}=$daemon_pid - typeset -gi _GITSTATUS_REQ_FD_${name}=$req_fd - typeset -gi _GITSTATUS_RESP_FD_${name}=$resp_fd - typeset -gi _GITSTATUS_LOCK_FD_${name}=$lock_fd - typeset -gi _GITSTATUS_CLIENT_PID_${name}=$$ - typeset -gi _GITSTATUS_DIRTY_MAX_INDEX_SIZE_${name}=$dirty_max_index_size + (( ! req_fd )) || { + typeset -gi _GITSTATUS_REQ_FD_${name}=$req_fd + typeset -gi _GITSTATUS_RESP_FD_${name}=$resp_fd + typeset -gi _GITSTATUS_LOCK_FD_${name}=$lock_fd + typeset -gi _GITSTATUS_CLIENT_PID_${name}=$$ + typeset -gi _GITSTATUS_DIRTY_MAX_INDEX_SIZE_${name}=$dirty_max_index_size + } unset -f gitstatus_start_impl } || { unsetopt err_return - add-zsh-hook -d zshexit _gitstatus_cleanup_${ZSH_SUBSHELL}_${daemon_pid} - [[ $daemon_pid -gt 0 ]] && kill -- -$daemon_pid &>/dev/null - [[ $stderr_fd -ge 0 ]] && { exec 2>&$stderr_fd {stderr_fd}>&- } - [[ $lock_fd -ge 0 ]] && zsystem flock -u $lock_fd - [[ $req_fd -ge 0 ]] && exec {req_fd}>&- - [[ $resp_fd -ge 0 ]] && { zle -F $resp_fd; exec {resp_fd}>&- } + add-zsh-hook -d zshexit _gitstatus_cleanup_$$_${ZSH_SUBSHELL}_${daemon_pid} + (( $+functions[_gitstatus_process_response_${name}] )) && { + zle -F $resp_fd + unfunction _gitstatus_process_response_${name} + } + (( resp_fd )) && exec {resp_fd}>&- + (( req_fd )) && exec {req_fd}>&- + (( lock_fd )) && zsystem flock -u $lock_fd + (( stderr_fd )) && { exec 2>&$stderr_fd {stderr_fd}>&- } + (( daemon_pid > 0 )) && kill -- -$daemon_pid &>/dev/null + rm -f $lock_file $req_fifo $resp_fifo unset -f gitstatus_start_impl + unset GITSTATUS_DAEMON_PID_${name} + unset _GITSTATUS_REQ_FD_${name} + unset _GITSTATUS_RESP_FD_${name} + unset _GITSTATUS_LOCK_FD_${name} + unset _GITSTATUS_CLIENT_PID_${name} + unset _GITSTATUS_DIRTY_MAX_INDEX_SIZE_${name} + >&2 print -P '[%F{red}ERROR%f]: gitstatus failed to initialize.' >&2 echo -E '' >&2 echo -E ' Your git prompt may disappear or become slow.' @@ -439,7 +491,7 @@ function gitstatus_start() { >&2 awk '{print " " $0}' <$log_file >&2 print -nP '%f' fi - if [[ -n ${GITSTATUS_LOG_LEVEL:-} || ${GITSTATUS_ENABLE_LOGGING:-0} == 1 ]]; then + if [[ ${GITSTATUS_LOG_LEVEL:-} == DEBUG ]]; then >&2 echo -E '' >&2 echo -E ' Your system information:' >&2 print -P '%F{yellow}' @@ -476,20 +528,28 @@ function gitstatus_stop() { local lock_fd_var=_GITSTATUS_LOCK_FD_${name} local daemon_pid_var=GITSTATUS_DAEMON_PID_${name} local client_pid_var=_GITSTATUS_CLIENT_PID_${name} + local dirty_size_var=_GITSTATUS_DIRTY_MAX_INDEX_SIZE_${name} + + [[ ${(P)daemon_pid_var:-} != -1 ]] || gitstatus_start -t 0 "$name" 2>/dev/null local req_fd=${(P)req_fd_var:-} local resp_fd=${(P)resp_fd_var:-} local lock_fd=${(P)lock_fd_var:-} - local daemon_pid=${(P)daemon_pid_var:-} + local daemon_pid=${(P)daemon_pid_var:-0} + + local cleanup_func=_gitstatus_cleanup_$$_${ZSH_SUBSHELL}_${daemon_pid} - local cleanup_func=_gitstatus_cleanup_${ZSH_SUBSHELL}_${daemon_pid} + (( $+functions[_gitstatus_process_response_${name}] )) && { + zle -F $resp_fd + unfunction _gitstatus_process_response_${name} + } - [[ -n $daemon_pid ]] && kill -- -$daemon_pid &>/dev/null - [[ -n $req_fd ]] && exec {req_fd}>&- - [[ -n $resp_fd ]] && { zle -F $resp_fd; exec {resp_fd}>&- } - [[ -n $lock_fd ]] && zsystem flock -u $lock_fd + (( resp_fd )) && exec {resp_fd}>&- + (( req_fd )) && exec {req_fd}>&- + (( lock_fd )) && zsystem flock -u $lock_fd + (( daemon_pid > 0 )) && kill -- -$daemon_pid &>/dev/null - unset $req_fd_var $resp_fd_var $lock_fd_var $daemon_pid_var $client_pid_var + unset $req_fd_var $resp_fd_var $lock_fd_var $daemon_pid_var $client_pid_var $dirty_size_var if (( $+functions[$cleanup_func] )); then add-zsh-hook -d zshexit $cleanup_func @@ -506,8 +566,9 @@ function gitstatus_stop() { function gitstatus_check() { emulate -L zsh (( ARGC == 1 )) || { echo "usage: gitstatus_check NAME" >&2; return 1 } - [[ -n ${(P)${:-GITSTATUS_DAEMON_PID_${1}}} ]] + local daemon_pid_var=GITSTATUS_DAEMON_PID_${1} + (( ${(P)daemon_pid_var:-0} > 0 )) } -(( ! _gitstatus_restore_aliases )) || setopt aliases -'builtin' 'unset' '_gitstatus_restore_aliases' +(( ${#_gitstatus_opts} )) && setopt ${_gitstatus_opts[@]} +'builtin' 'unset' '_gitstatus_opts' diff --git a/gitstatus/pull-upstream.zsh b/gitstatus/pull-upstream.zsh index 2cb758a5..0ec22438 100755 --- a/gitstatus/pull-upstream.zsh +++ b/gitstatus/pull-upstream.zsh @@ -9,10 +9,10 @@ setopt err_exit no_unset pipe_fail extended_glob xtrace readonly GITSTATUS_DIR GITSTATUS_URL readonly -a IGNORE=(pull-upstream.zsh README.md) -function pull() { - local repo && repo=$(mktemp -d ${TMPDIR:-/tmp}/gitstatus-pull-upstream.XXXXXXXXXX) +() { + local repo && repo="$(mktemp -d ${TMPDIR:-/tmp}/gitstatus-pull-upstream.XXXXXXXXXX)" trap "rm -rf ${(q)repo}" EXIT - git clone $GITSTATUS_URL $repo + git clone --depth 1 $GITSTATUS_URL $repo local dst for dst in $GITSTATUS_DIR/**/*(.,@); do @@ -22,9 +22,7 @@ function pull() { [[ -f $src ]] && { mkdir -p ${dst:h} && cp -f $src $dst || return } || { - rm $dst + rm -f $dst } done } - -pull diff --git a/internal/configure.zsh b/internal/configure.zsh index 924a75d1..202978f6 100644 --- a/internal/configure.zsh +++ b/internal/configure.zsh @@ -1,51 +1,77 @@ -typeset -gr __p9k_wizard_columns=70 # DO NOT SUBMIT: 76 -typeset -gr __p9k_wizard_lines=20 # DO NOT SUBMIT: 21 -typeset -gr __p9k_zd=${${ZDOTDIR:-$HOME}:A} -typeset -gr __p9k_zd_u=${${(q-)__p9k_zd}/#(#b)$HOME(|\/*)/'~'$match[1]} +typeset -gr __p9k_wizard_columns=55 +typeset -gr __p9k_wizard_lines=21 +typeset -gr __p9k_zd=${ZDOTDIR:-$HOME} +typeset -gr __p9k_zd_u=${${${(q)__p9k_zd}/#(#b)${(q)HOME}(|\/*)/'~'$match[1]}//\%/%%} typeset -gr __p9k_cfg_basename=.p10k.zsh typeset -gr __p9k_cfg_path=$__p9k_zd/$__p9k_cfg_basename typeset -gr __p9k_cfg_path_u=$__p9k_zd_u/$__p9k_cfg_basename typeset -gr __p9k_zshrc=$__p9k_zd/.zshrc typeset -gr __p9k_zshrc_u=$__p9k_zd_u/.zshrc -typeset -gr __p9k_root_dir_u=${${(q-)__p9k_root_dir}/#(#b)$HOME(|\/*)/'~'$match[1]} +typeset -gr __p9k_root_dir_u=${${${(q)__p9k_root_dir}/#(#b)${(q)HOME}(|\/*)/'~'$match[1]}//\%/%%} function _p9k_can_configure() { emulate -L zsh - setopt err_return extended_glob no_prompt_{bang,subst} prompt_{cr,percent,sp} + setopt extended_glob no_prompt_{bang,subst} prompt_percent [[ $1 == '-q' ]] && local -i q=1 || local -i q=0 function $0_error() { - (( q )) || print -P "%1F[ERROR]%f %Bp9k_configure%b: $1" >&2 - return 1 + (( q )) || print -rP "%1F[ERROR]%f %Bp10k configure%b: $1" >&2 } { - [[ -t 0 && -t 1 ]] || $0_error "no TTY" - [[ -o multibyte ]] || $0_error "multibyte option is not set" - [[ "${#$(print -P '\u276F' 2>/dev/null)}" == 1 ]] || $0_error "shell doesn't support unicode" - [[ -w $__p9k_zd ]] || $0_error "$__p9k_zd_u is not writable" - [[ ! -d $__p9k_cfg_path ]] || $0_error "$__p9k_cfg_path_u is a directory" - [[ ! -d $__p9k_zshrc ]] || $0_error "$__p9k_zshrc_u is a directory" + [[ -t 0 && -t 1 ]] || { $0_error "no TTY"; return 1 } + [[ -o multibyte ]] || { $0_error "multibyte option is not set"; return 1 } + [[ -e $__p9k_zd ]] || { $0_error "$__p9k_zd_u does not exist"; return 1 } + [[ -d $__p9k_zd ]] || { $0_error "$__p9k_zd_u is not a directory"; return 1 } + [[ -w $__p9k_zd ]] || { $0_error "$__p9k_zd_u is not writable"; return 1 } + [[ ! -d $__p9k_cfg_path ]] || { $0_error "$__p9k_cfg_path_u is a directory"; return 1 } + [[ ! -d $__p9k_zshrc ]] || { $0_error "$__p9k_zshrc_u is a directory"; return 1 } - [[ ! -e $__p9k_cfg_path || -f $__p9k_cfg_path || -h $__p9k_cfg_path ]] || + [[ ! -e $__p9k_cfg_path || -f $__p9k_cfg_path || -h $__p9k_cfg_path ]] || { $0_error "$__p9k_cfg_path_u is a special file" - [[ -r $__p9k_root_dir/config/p10k-lean.zsh ]] || + return 1 + } + [[ -r $__p9k_root_dir/config/p10k-lean.zsh ]] || { $0_error "cannot read $__p9k_root_dir_u/config/p10k-lean.zsh" - [[ -r $__p9k_root_dir/config/p10k-classic.zsh ]] || + return 1 + } + [[ -r $__p9k_root_dir/config/p10k-classic.zsh ]] || { $0_error "cannot read $__p9k_root_dir_u/config/p10k-classic.zsh" - [[ ! -e $__p9k_zshrc || -f $__p9k_zshrc || -h $__p9k_zshrc ]] || + return 1 + } + [[ ! -e $__p9k_zshrc || -f $__p9k_zshrc || -h $__p9k_zshrc ]] || { $0_error "$__p9k_zshrc_u a special file" - [[ ! -e $__p9k_zshrc || -r $__p9k_zshrc ]] || + return 1 + } + [[ ! -e $__p9k_zshrc || -r $__p9k_zshrc ]] || { $0_error "$__p9k_zshrc_u is not readable" - [[ ! -e $__p9k_zshrc || -w $__p9k_zshrc ]] || + return 1 + } + [[ ! -e $__p9k_zshrc || -w $__p9k_zshrc ]] || { $0_error "$__p9k_zshrc_u is not writable" - (( LINES >= __p9k_wizard_lines && COLUMNS >= __p9k_wizard_columns )) || + return 1 + } + (( LINES >= __p9k_wizard_lines && COLUMNS >= __p9k_wizard_columns )) || { $0_error "terminal size too small; must be at least $__p9k_wizard_columns x $__p9k_wizard_lines" + return 1 + } } always { unfunction $0_error } } function p9k_configure() { - emulate -L zsh && setopt no_hist_expand extended_glob - $__p9k_root_dir/internal/wizard.zsh -d $__p9k_root_dir -f || return - source $__p9k_cfg_path + emulate -L zsh + setopt no_hist_expand extended_glob + ( + local p=("${(@)parameters[(I)AWESOME_*|CODEPOINT_*]}") + if (( $#p )); then + typeset -x -- $p + fi + $__p9k_root_dir/internal/wizard.zsh -d $__p9k_root_dir -f + ) + local ret=$? + case $ret in + 0) source $__p9k_cfg_path;; + 69) return 0;; + *) return $ret;; + esac } diff --git a/internal/icons.zsh b/internal/icons.zsh old mode 100755 new mode 100644 index 57eb8ad8..b93bbb53 --- a/internal/icons.zsh +++ b/internal/icons.zsh @@ -3,6 +3,12 @@ typeset -gA icons function _p9k_init_icons() { [[ $+_p9k_icon_mode == 1 && $_p9k_icon_mode == $POWERLEVEL9K_MODE ]] && return typeset -g _p9k_icon_mode=$POWERLEVEL9K_MODE + zmodload zsh/langinfo + if [[ ${langinfo[CODESET]:-} != (utf|UTF)(-|)8 ]]; then + typeset -g _p9k_locale=${${(@M)$(locale -a):#*.(utf|UTF)(-|)8}[1]:-en_US.UTF-8} + else + typeset -g _p9k_locale= + fi case $POWERLEVEL9K_MODE in 'flat'|'awesome-patched') @@ -15,61 +21,61 @@ function _p9k_init_icons() { LEFT_SEGMENT_END_SEPARATOR ' ' # Whitespace LEFT_SUBSEGMENT_SEPARATOR '\uE0B1' #  RIGHT_SUBSEGMENT_SEPARATOR '\uE0B3' #  - CARRIAGE_RETURN_ICON '\u21B5' # ↵ + CARRIAGE_RETURN_ICON '\u21B5 ' # ↵ ROOT_ICON '\uE801' #  - SUDO_ICON '\uF09C' #  + SUDO_ICON '\uE0A2' #  RUBY_ICON '\uE847 ' #  - AWS_ICON '\uE895' #  - AWS_EB_ICON '\U1F331 ' # 🌱 + AWS_ICON '\uE895 ' #  + AWS_EB_ICON '\U1F331' # 🌱 BACKGROUND_JOBS_ICON '\uE82F ' #  - TEST_ICON '\uE891' #  + TEST_ICON '\uE891 ' #  TODO_ICON '\u2611' # ☑ - BATTERY_ICON '\uE894' #  + BATTERY_ICON '\uE894 ' #  DISK_ICON '\uE1AE ' #  OK_ICON '\u2714' # ✔ FAIL_ICON '\u2718' # ✘ SYMFONY_ICON 'SF' - NODE_ICON '\u2B22' # ⬢ + NODE_ICON '\u2B22 ' # ⬢ MULTILINE_FIRST_PROMPT_PREFIX '\u256D\U2500' # ╭─ MULTILINE_NEWLINE_PROMPT_PREFIX '\u251C\U2500' # ├─ MULTILINE_LAST_PROMPT_PREFIX '\u2570\U2500 ' # ╰─ - APPLE_ICON '\uE26E' #  - WINDOWS_ICON '\uE26F' #  - FREEBSD_ICON '\U1F608 ' # 😈 - ANDROID_ICON '\uE270' #  - LINUX_ICON '\uE271' #  - LINUX_ARCH_ICON '\uE271' #  - LINUX_DEBIAN_ICON '\uE271' #  - LINUX_RASPBIAN_ICON '\uE271' #  - LINUX_UBUNTU_ICON '\uE271' #  - LINUX_CENTOS_ICON '\uE271' #  - LINUX_COREOS_ICON '\uE271' #  - LINUX_ELEMENTARY_ICON '\uE271' #  - LINUX_MINT_ICON '\uE271' #  - LINUX_FEDORA_ICON '\uE271' #  - LINUX_GENTOO_ICON '\uE271' #  - LINUX_MAGEIA_ICON '\uE271' #  - LINUX_NIXOS_ICON '\uE271' #  - LINUX_MANJARO_ICON '\uE271' #  - LINUX_DEVUAN_ICON '\uE271' #  - LINUX_ALPINE_ICON '\uE271' #  - LINUX_AOSC_ICON '\uE271' #  - LINUX_OPENSUSE_ICON '\uE271' #  - LINUX_SABAYON_ICON '\uE271' #  - LINUX_SLACKWARE_ICON '\uE271' #  - SUNOS_ICON '\U1F31E ' # 🌞 - HOME_ICON '\uE12C' #  - HOME_SUB_ICON '\uE18D' #  - FOLDER_ICON '\uE818' #  - NETWORK_ICON '\uE1AD' #  - ETC_ICON '\uE82F' #  + APPLE_ICON '\uE26E ' #  + WINDOWS_ICON '\uE26F ' #  + FREEBSD_ICON '\U1F608' # 😈 + ANDROID_ICON '\uE270 ' #  + LINUX_ICON '\uE271 ' #  + LINUX_ARCH_ICON '\uE271 ' #  + LINUX_DEBIAN_ICON '\uE271 ' #  + LINUX_RASPBIAN_ICON '\uE271 ' #  + LINUX_UBUNTU_ICON '\uE271 ' #  + LINUX_CENTOS_ICON '\uE271 ' #  + LINUX_COREOS_ICON '\uE271 ' #  + LINUX_ELEMENTARY_ICON '\uE271 ' #  + LINUX_MINT_ICON '\uE271 ' #  + LINUX_FEDORA_ICON '\uE271 ' #  + LINUX_GENTOO_ICON '\uE271 ' #  + LINUX_MAGEIA_ICON '\uE271 ' #  + LINUX_NIXOS_ICON '\uE271 ' #  + LINUX_MANJARO_ICON '\uE271 ' #  + LINUX_DEVUAN_ICON '\uE271 ' #  + LINUX_ALPINE_ICON '\uE271 ' #  + LINUX_AOSC_ICON '\uE271 ' #  + LINUX_OPENSUSE_ICON '\uE271 ' #  + LINUX_SABAYON_ICON '\uE271 ' #  + LINUX_SLACKWARE_ICON '\uE271 ' #  + SUNOS_ICON '\U1F31E' # 🌞 + HOME_ICON '\uE12C ' #  + HOME_SUB_ICON '\uE18D ' #  + FOLDER_ICON '\uE818 ' #  + NETWORK_ICON '\uE1AD ' #  + ETC_ICON '\uE82F ' #  LOAD_ICON '\uE190 ' #  - SWAP_ICON '\uE87D' #  + SWAP_ICON '\uE87D ' #  RAM_ICON '\uE1E2 ' #  - SERVER_ICON '\uE895' #  - VCS_UNTRACKED_ICON '\uE16C' #  - VCS_UNSTAGED_ICON '\uE17C' #  - VCS_STAGED_ICON '\uE168' #  + SERVER_ICON '\uE895 ' #  + VCS_UNTRACKED_ICON '\uE16C ' #  + VCS_UNSTAGED_ICON '\uE17C ' #  + VCS_STAGED_ICON '\uE168 ' #  VCS_STASH_ICON '\uE133 ' #  #VCS_INCOMING_CHANGES_ICON '\uE1EB ' #  #VCS_INCOMING_CHANGES_ICON '\uE80D ' #  @@ -88,22 +94,27 @@ function _p9k_init_icons() { VCS_GIT_BITBUCKET_ICON '\uE20E ' # VCS_GIT_GITLAB_ICON '\uE20E ' # VCS_HG_ICON '\uE1C3 ' #  - VCS_SVN_ICON '(svn) ' - RUST_ICON '(rust)' # TODO: try 𝗥. - PYTHON_ICON '\ue63c' #  - SWIFT_ICON '' - GO_ICON '' - PUBLIC_IP_ICON '' + VCS_SVN_ICON 'svn' + RUST_ICON 'R' + PYTHON_ICON '\uE63C ' #  (doesn't always work) + SWIFT_ICON 'Swift' + GO_ICON 'Go' + PUBLIC_IP_ICON 'IP' LOCK_ICON '\UE138' #  - EXECUTION_TIME_ICON '\UE89C' #  - SSH_ICON '(ssh)' - VPN_ICON '(vpn)' - KUBERNETES_ICON '\U2388' # ⎈ - DROPBOX_ICON '\UF16B' #  - DATE_ICON '\uE184' #  - TIME_ICON '\uE12E' #  + EXECUTION_TIME_ICON '\UE89C ' #  + SSH_ICON 'ssh' + VPN_ICON '\UE138' + KUBERNETES_ICON '\U2388 ' # ⎈ + DROPBOX_ICON '\UF16B ' #  (doesn't always work) + DATE_ICON '\uE184 ' #  + TIME_ICON '\uE12E ' #  JAVA_ICON '\U2615' # ☕︎ LARAVEL_ICON '' + RANGER_ICON '\u2B50' # ⭐ + TERRAFORM_ICON '\U1F6E0\u00A0' # 🛠️ + PROXY_ICON '\u2B82' # ⮂ + DOTNET_ICON '.NET' + AZURE_ICON '\u2601' # ☁ ) ;; 'awesome-fontconfig') @@ -117,13 +128,13 @@ function _p9k_init_icons() { LEFT_SUBSEGMENT_SEPARATOR '\uE0B1' #  RIGHT_SUBSEGMENT_SEPARATOR '\uE0B3' #  CARRIAGE_RETURN_ICON '\u21B5' # ↵ - ROOT_ICON '\uF201' #  - SUDO_ICON '\uF09C' #  + ROOT_ICON '\uF201 ' #  + SUDO_ICON '\uF09C ' #  RUBY_ICON '\uF219 ' #  - AWS_ICON '\uF270' #  - AWS_EB_ICON '\U1F331 ' # 🌱 + AWS_ICON '\uF270 ' #  + AWS_EB_ICON '\U1F331' # 🌱 BACKGROUND_JOBS_ICON '\uF013 ' #  - TEST_ICON '\uF291' #  + TEST_ICON '\uF291 ' #  TODO_ICON '\u2611' # ☑ BATTERY_ICON '\U1F50B' # 🔋 DISK_ICON '\uF0A0 ' #  @@ -134,48 +145,48 @@ function _p9k_init_icons() { MULTILINE_FIRST_PROMPT_PREFIX '\u256D\U2500' # ╭─ MULTILINE_NEWLINE_PROMPT_PREFIX '\u251C\U2500' # ├─ MULTILINE_LAST_PROMPT_PREFIX '\u2570\U2500 ' # ╰─ - APPLE_ICON '\uF179' #  - WINDOWS_ICON '\uF17A' #  - FREEBSD_ICON '\U1F608 ' # 😈 - ANDROID_ICON '\uE17B' #  - LINUX_ICON '\uF17C' #  - LINUX_ARCH_ICON '\uF17C' #  - LINUX_DEBIAN_ICON '\uF17C' #  - LINUX_RASPBIAN_ICON '\uF17C' #  - LINUX_UBUNTU_ICON '\uF17C' #  - LINUX_CENTOS_ICON '\uF17C' #  - LINUX_COREOS_ICON '\uF17C' #  - LINUX_ELEMENTARY_ICON '\uF17C' #  - LINUX_MINT_ICON '\uF17C' #  - LINUX_FEDORA_ICON '\uF17C' #  - LINUX_GENTOO_ICON '\uF17C' #  - LINUX_MAGEIA_ICON '\uF17C' #  - LINUX_NIXOS_ICON '\uF17C' #  - LINUX_MANJARO_ICON '\uF17C' #  - LINUX_DEVUAN_ICON '\uF17C' #  - LINUX_ALPINE_ICON '\uF17C' #  - LINUX_AOSC_ICON '\uF17C' #  - LINUX_OPENSUSE_ICON '\uF17C' #  - LINUX_SABAYON_ICON '\uF17C' #  - LINUX_SLACKWARE_ICON '\uF17C' #  + APPLE_ICON '\uF179 ' #  + WINDOWS_ICON '\uF17A ' #  + FREEBSD_ICON '\U1F608' # 😈 + ANDROID_ICON '\uE17B ' #  (doesn't always work) + LINUX_ICON '\uF17C ' #  + LINUX_ARCH_ICON '\uF17C ' #  + LINUX_DEBIAN_ICON '\uF17C ' #  + LINUX_RASPBIAN_ICON '\uF17C ' #  + LINUX_UBUNTU_ICON '\uF17C ' #  + LINUX_CENTOS_ICON '\uF17C ' #  + LINUX_COREOS_ICON '\uF17C ' #  + LINUX_ELEMENTARY_ICON '\uF17C ' #  + LINUX_MINT_ICON '\uF17C ' #  + LINUX_FEDORA_ICON '\uF17C ' #  + LINUX_GENTOO_ICON '\uF17C ' #  + LINUX_MAGEIA_ICON '\uF17C ' #  + LINUX_NIXOS_ICON '\uF17C ' #  + LINUX_MANJARO_ICON '\uF17C ' #  + LINUX_DEVUAN_ICON '\uF17C ' #  + LINUX_ALPINE_ICON '\uF17C ' #  + LINUX_AOSC_ICON '\uF17C ' #  + LINUX_OPENSUSE_ICON '\uF17C ' #  + LINUX_SABAYON_ICON '\uF17C ' #  + LINUX_SLACKWARE_ICON '\uF17C ' #  SUNOS_ICON '\uF185 ' #  - HOME_ICON '\uF015' #  - HOME_SUB_ICON '\uF07C' #  - FOLDER_ICON '\uF115' #  + HOME_ICON '\uF015 ' #  + HOME_SUB_ICON '\uF07C ' #  + FOLDER_ICON '\uF115 ' #  ETC_ICON '\uF013 ' #  - NETWORK_ICON '\uF09E' #  + NETWORK_ICON '\uF09E ' #  LOAD_ICON '\uF080 ' #  - SWAP_ICON '\uF0E4' #  - RAM_ICON '\uF0E4' #  - SERVER_ICON '\uF233' #  - VCS_UNTRACKED_ICON '\uF059' #  - VCS_UNSTAGED_ICON '\uF06A' #  - VCS_STAGED_ICON '\uF055' #  + SWAP_ICON '\uF0E4 ' #  + RAM_ICON '\uF0E4 ' #  + SERVER_ICON '\uF233 ' #  + VCS_UNTRACKED_ICON '\uF059 ' #  + VCS_UNSTAGED_ICON '\uF06A ' #  + VCS_STAGED_ICON '\uF055 ' #  VCS_STASH_ICON '\uF01C ' #  VCS_INCOMING_CHANGES_ICON '\uF01A ' #  VCS_OUTGOING_CHANGES_ICON '\uF01B ' #  VCS_TAG_ICON '\uF217 ' #  - VCS_BOOKMARK_ICON '\uF27B' #  + VCS_BOOKMARK_ICON '\uF27B ' #  VCS_COMMIT_ICON '\uF221 ' #  VCS_BRANCH_ICON '\uF126 ' #  VCS_REMOTE_BRANCH_ICON '\u2192' # → @@ -185,22 +196,27 @@ function _p9k_init_icons() { VCS_GIT_BITBUCKET_ICON '\uF171 ' #  VCS_GIT_GITLAB_ICON '\uF296 ' #  VCS_HG_ICON '\uF0C3 ' #  - VCS_SVN_ICON '(svn) ' - RUST_ICON '\uE6A8' #  - PYTHON_ICON '\ue63c' #  - SWIFT_ICON '' - GO_ICON '' - PUBLIC_IP_ICON '' + VCS_SVN_ICON 'svn' + RUST_ICON '\uE6A8' #  + PYTHON_ICON '\uE63C ' #  + SWIFT_ICON 'Swift' + GO_ICON 'Go' + PUBLIC_IP_ICON 'IP' LOCK_ICON '\UF023' #  - EXECUTION_TIME_ICON '\uF253' - SSH_ICON '(ssh)' + EXECUTION_TIME_ICON '\uF253 ' #  + SSH_ICON 'ssh' VPN_ICON '\uF023' KUBERNETES_ICON '\U2388' # ⎈ - DROPBOX_ICON '\UF16B' #  + DROPBOX_ICON '\UF16B ' #  DATE_ICON '\uF073 ' #  TIME_ICON '\uF017 ' #  JAVA_ICON '\U2615' # ☕︎ LARAVEL_ICON '' + RANGER_ICON '\u2B50' # ⭐ + TERRAFORM_ICON '\U1F6E0\u00A0' # 🛠️ + PROXY_ICON '\u2B82' # ⮂ + DOTNET_ICON '.NET' + AZURE_ICON '\u2601' # ☁ ) ;; 'awesome-mapped-fontconfig') @@ -222,57 +238,57 @@ function _p9k_init_icons() { RIGHT_SUBSEGMENT_SEPARATOR '\uE0B3' #  CARRIAGE_RETURN_ICON '\u21B5' # ↵ ROOT_ICON '\u'$CODEPOINT_OF_OCTICONS_ZAP #  - SUDO_ICON '\u'$CODEPOINT_OF_AWESOME_UNLOCK #  + SUDO_ICON '\u'$CODEPOINT_OF_AWESOME_UNLOCK' ' #  RUBY_ICON '\u'$CODEPOINT_OF_OCTICONS_RUBY' ' #  - AWS_ICON '\u'$CODEPOINT_OF_AWESOME_SERVER #  - AWS_EB_ICON '\U1F331 ' # 🌱 + AWS_ICON '\u'$CODEPOINT_OF_AWESOME_SERVER' ' #  + AWS_EB_ICON '\U1F331' # 🌱 BACKGROUND_JOBS_ICON '\u'$CODEPOINT_OF_AWESOME_COG' ' #  - TEST_ICON '\u'$CODEPOINT_OF_AWESOME_BUG #  - TODO_ICON '\u'$CODEPOINT_OF_AWESOME_CHECK_SQUARE_O #  - BATTERY_ICON '\U'$CODEPOINT_OF_AWESOME_BATTERY_FULL #  + TEST_ICON '\u'$CODEPOINT_OF_AWESOME_BUG' ' #  + TODO_ICON '\u'$CODEPOINT_OF_AWESOME_CHECK_SQUARE_O' ' #  + BATTERY_ICON '\U'$CODEPOINT_OF_AWESOME_BATTERY_FULL' ' #  DISK_ICON '\u'$CODEPOINT_OF_AWESOME_HDD_O' ' #  - OK_ICON '\u'$CODEPOINT_OF_AWESOME_CHECK #  - FAIL_ICON '\u'$CODEPOINT_OF_AWESOME_TIMES #  + OK_ICON '\u'$CODEPOINT_OF_AWESOME_CHECK' ' #  + FAIL_ICON '\u'$CODEPOINT_OF_AWESOME_TIMES #  SYMFONY_ICON 'SF' NODE_ICON '\u2B22' # ⬢ MULTILINE_FIRST_PROMPT_PREFIX '\u256D\U2500' # ╭─ MULTILINE_NEWLINE_PROMPT_PREFIX '\u251C\U2500' # ├─ MULTILINE_LAST_PROMPT_PREFIX '\u2570\U2500 ' # ╰─ - APPLE_ICON '\u'$CODEPOINT_OF_AWESOME_APPLE #  - FREEBSD_ICON '\U1F608 ' # 😈 - LINUX_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX #  - LINUX_ARCH_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX #  - LINUX_DEBIAN_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX #  - LINUX_RASPBIAN_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX #  - LINUX_UBUNTU_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX #  - LINUX_CENTOS_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX #  - LINUX_COREOS_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX #  - LINUX_ELEMENTARY_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX #  - LINUX_MINT_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX #  - LINUX_FEDORA_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX #  - LINUX_GENTOO_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX #  - LINUX_MAGEIA_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX #  - LINUX_NIXOS_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX #  - LINUX_MANJARO_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX #  - LINUX_DEVUAN_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX #  - LINUX_ALPINE_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX #  - LINUX_AOSC_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX #  - LINUX_OPENSUSE_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX #  - LINUX_SABAYON_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX #  - LINUX_SLACKWARE_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX #  + APPLE_ICON '\u'$CODEPOINT_OF_AWESOME_APPLE' ' #  + FREEBSD_ICON '\U1F608' # 😈 + LINUX_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' #  + LINUX_ARCH_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' #  + LINUX_DEBIAN_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' #  + LINUX_RASPBIAN_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' #  + LINUX_UBUNTU_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' #  + LINUX_CENTOS_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' #  + LINUX_COREOS_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' #  + LINUX_ELEMENTARY_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' #  + LINUX_MINT_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' #  + LINUX_FEDORA_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' #  + LINUX_GENTOO_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' #  + LINUX_MAGEIA_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' #  + LINUX_NIXOS_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' #  + LINUX_MANJARO_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' #  + LINUX_DEVUAN_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' #  + LINUX_ALPINE_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' #  + LINUX_AOSC_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' #  + LINUX_OPENSUSE_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' #  + LINUX_SABAYON_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' #  + LINUX_SLACKWARE_ICON '\u'$CODEPOINT_OF_AWESOME_LINUX' ' #  SUNOS_ICON '\u'$CODEPOINT_OF_AWESOME_SUN_O' ' #  - HOME_ICON '\u'$CODEPOINT_OF_AWESOME_HOME #  - HOME_SUB_ICON '\u'$CODEPOINT_OF_AWESOME_FOLDER_OPEN #  - FOLDER_ICON '\u'$CODEPOINT_OF_AWESOME_FOLDER_O #  + HOME_ICON '\u'$CODEPOINT_OF_AWESOME_HOME' ' #  + HOME_SUB_ICON '\u'$CODEPOINT_OF_AWESOME_FOLDER_OPEN' ' #  + FOLDER_ICON '\u'$CODEPOINT_OF_AWESOME_FOLDER_O' ' #  ETC_ICON '\u'$CODEPOINT_OF_AWESOME_COG' ' #  - NETWORK_ICON '\u'$CODEPOINT_OF_AWESOME_RSS #  + NETWORK_ICON '\u'$CODEPOINT_OF_AWESOME_RSS' ' #  LOAD_ICON '\u'$CODEPOINT_OF_AWESOME_BAR_CHART' ' #  - SWAP_ICON '\u'$CODEPOINT_OF_AWESOME_DASHBOARD #  - RAM_ICON '\u'$CODEPOINT_OF_AWESOME_DASHBOARD #  - SERVER_ICON '\u'$CODEPOINT_OF_AWESOME_SERVER #  - VCS_UNTRACKED_ICON '\u'$CODEPOINT_OF_AWESOME_QUESTION_CIRCLE #  - VCS_UNSTAGED_ICON '\u'$CODEPOINT_OF_AWESOME_EXCLAMATION_CIRCLE #  - VCS_STAGED_ICON '\u'$CODEPOINT_OF_AWESOME_PLUS_CIRCLE #  + SWAP_ICON '\u'$CODEPOINT_OF_AWESOME_DASHBOARD' ' #  + RAM_ICON '\u'$CODEPOINT_OF_AWESOME_DASHBOARD' ' #  + SERVER_ICON '\u'$CODEPOINT_OF_AWESOME_SERVER' ' #  + VCS_UNTRACKED_ICON '\u'$CODEPOINT_OF_AWESOME_QUESTION_CIRCLE' ' #  + VCS_UNSTAGED_ICON '\u'$CODEPOINT_OF_AWESOME_EXCLAMATION_CIRCLE' ' #  + VCS_STAGED_ICON '\u'$CODEPOINT_OF_AWESOME_PLUS_CIRCLE' ' #  VCS_STASH_ICON '\u'$CODEPOINT_OF_AWESOME_INBOX' ' #  VCS_INCOMING_CHANGES_ICON '\u'$CODEPOINT_OF_AWESOME_ARROW_CIRCLE_DOWN' ' #  VCS_OUTGOING_CHANGES_ICON '\u'$CODEPOINT_OF_AWESOME_ARROW_CIRCLE_UP' ' #  @@ -280,28 +296,33 @@ function _p9k_init_icons() { VCS_BOOKMARK_ICON '\u'$CODEPOINT_OF_OCTICONS_BOOKMARK #  VCS_COMMIT_ICON '\u'$CODEPOINT_OF_OCTICONS_GIT_COMMIT' ' #  VCS_BRANCH_ICON '\u'$CODEPOINT_OF_OCTICONS_GIT_BRANCH' ' #  - VCS_REMOTE_BRANCH_ICON '\u'$CODEPOINT_OF_OCTICONS_REPO_PUSH #  + VCS_REMOTE_BRANCH_ICON '\u'$CODEPOINT_OF_OCTICONS_REPO_PUSH' ' #  VCS_LOADING_ICON '' VCS_GIT_ICON '\u'$CODEPOINT_OF_AWESOME_GIT' ' #  VCS_GIT_GITHUB_ICON '\u'$CODEPOINT_OF_AWESOME_GITHUB_ALT' ' #  VCS_GIT_BITBUCKET_ICON '\u'$CODEPOINT_OF_AWESOME_BITBUCKET' ' #  VCS_GIT_GITLAB_ICON '\u'$CODEPOINT_OF_AWESOME_GITLAB' ' #  VCS_HG_ICON '\u'$CODEPOINT_OF_AWESOME_FLASK' ' #  - VCS_SVN_ICON '(svn) ' + VCS_SVN_ICON 'svn' RUST_ICON '\uE6A8' #  PYTHON_ICON '\U1F40D' # 🐍 - SWIFT_ICON '\uE655' #  - PUBLIC_IP_ICON '\u'$CODEPOINT_OF_AWESOME_GLOBE #  + SWIFT_ICON '\uE655 ' #  + PUBLIC_IP_ICON '\u'$CODEPOINT_OF_AWESOME_GLOBE' ' #  LOCK_ICON '\u'$CODEPOINT_OF_AWESOME_LOCK #  - EXECUTION_TIME_ICON '\u'$CODEPOINT_OF_AWESOME_HOURGLASS_END #  - SSH_ICON '(ssh)' + EXECUTION_TIME_ICON '\u'$CODEPOINT_OF_AWESOME_HOURGLASS_END' ' #  + SSH_ICON 'ssh' VPN_ICON '\u'$CODEPOINT_OF_AWESOME_LOCK KUBERNETES_ICON '\U2388' # ⎈ - DROPBOX_ICON '\u'$CODEPOINT_OF_AWESOME_DROPBOX #  + DROPBOX_ICON '\u'$CODEPOINT_OF_AWESOME_DROPBOX' ' #  DATE_ICON '\uF073 ' #  TIME_ICON '\uF017 ' #  JAVA_ICON '\U2615' # ☕︎ LARAVEL_ICON '' + RANGER_ICON '\u2B50' # ⭐ + TERRAFORM_ICON '\U1F6E0\u00A0' # 🛠️ + PROXY_ICON '\u2B82' # ⮂ + DOTNET_ICON '.NET' + AZURE_ICON '\u2601' # ☁ ) ;; 'nerdfont-complete'|'nerdfont-fontconfig') @@ -316,17 +337,17 @@ function _p9k_init_icons() { LEFT_SUBSEGMENT_SEPARATOR '\uE0B1' #  RIGHT_SUBSEGMENT_SEPARATOR '\uE0B3' #  CARRIAGE_RETURN_ICON '\u21B5' # ↵ - ROOT_ICON '\uE614 ' #  - SUDO_ICON '\uF09C' #  + ROOT_ICON '\uE614' #  + SUDO_ICON '\uF09C ' #  RUBY_ICON '\uF219 ' #  - AWS_ICON '\uF270' #  - AWS_EB_ICON '\UF1BD ' #  + AWS_ICON '\uF270 ' #  + AWS_EB_ICON '\UF1BD' #  BACKGROUND_JOBS_ICON '\uF013 ' #  - TEST_ICON '\uF188' #  - TODO_ICON '\uF133' #  + TEST_ICON '\uF188 ' #  + TODO_ICON '\uF133 ' #  BATTERY_ICON '\UF240 ' #  - DISK_ICON '\uF0A0' #  - OK_ICON '\uF00C' #  + DISK_ICON '\uF0A0 ' #  + OK_ICON '\uF00C ' #  FAIL_ICON '\uF00D' #  SYMFONY_ICON '\uE757' #  NODE_ICON '\uE617 ' #  @@ -334,42 +355,42 @@ function _p9k_init_icons() { MULTILINE_NEWLINE_PROMPT_PREFIX '\u251C\U2500' # ├─ MULTILINE_LAST_PROMPT_PREFIX '\u2570\U2500 ' # ╰─ APPLE_ICON '\uF179' #  - WINDOWS_ICON '\uF17A' #  + WINDOWS_ICON '\uF17A ' #  FREEBSD_ICON '\UF30C ' #  ANDROID_ICON '\uF17B' #  LINUX_ARCH_ICON '\uF303' #  - LINUX_CENTOS_ICON '\uF304' #  - LINUX_COREOS_ICON '\uF305' #  + LINUX_CENTOS_ICON '\uF304 ' #  + LINUX_COREOS_ICON '\uF305 ' #  LINUX_DEBIAN_ICON '\uF306' #  LINUX_RASPBIAN_ICON '\uF315' #  - LINUX_ELEMENTARY_ICON '\uF309' #  - LINUX_FEDORA_ICON '\uF30a' #  - LINUX_GENTOO_ICON '\uF30d' #  + LINUX_ELEMENTARY_ICON '\uF309 ' #  + LINUX_FEDORA_ICON '\uF30a ' #  + LINUX_GENTOO_ICON '\uF30d ' #  LINUX_MAGEIA_ICON '\uF310' #  - LINUX_MINT_ICON '\uF30e' #  - LINUX_NIXOS_ICON '\uF313' #  - LINUX_MANJARO_ICON '\uF312' #  - LINUX_DEVUAN_ICON '\uF307' #  - LINUX_ALPINE_ICON '\uF300' #  - LINUX_AOSC_ICON '\uF301' #  - LINUX_OPENSUSE_ICON '\uF314' #  - LINUX_SABAYON_ICON '\uF317' #  - LINUX_SLACKWARE_ICON '\uF319' #  - LINUX_UBUNTU_ICON '\uF31b' #  + LINUX_MINT_ICON '\uF30e ' #  + LINUX_NIXOS_ICON '\uF313 ' #  + LINUX_MANJARO_ICON '\uF312 ' #  + LINUX_DEVUAN_ICON '\uF307 ' #  + LINUX_ALPINE_ICON '\uF300 ' #  + LINUX_AOSC_ICON '\uF301 ' #  + LINUX_OPENSUSE_ICON '\uF314 ' #  + LINUX_SABAYON_ICON '\uF317 ' #  + LINUX_SLACKWARE_ICON '\uF319 ' #  + LINUX_UBUNTU_ICON '\uF31b ' #  LINUX_ICON '\uF17C' #  SUNOS_ICON '\uF185 ' #  - HOME_ICON '\uF015' #  - HOME_SUB_ICON '\uF07C' #  - FOLDER_ICON '\uF115' #  - ETC_ICON '\uF013' #  - NETWORK_ICON '\uF1EB' #  + HOME_ICON '\uF015 ' #  + HOME_SUB_ICON '\uF07C ' #  + FOLDER_ICON '\uF115 ' #  + ETC_ICON '\uF013 ' #  + NETWORK_ICON '\uF1EB ' #  LOAD_ICON '\uF080 ' #  - SWAP_ICON '\uF464' #  - RAM_ICON '\uF0E4' #  - SERVER_ICON '\uF0AE' #  - VCS_UNTRACKED_ICON '\uF059' #  - VCS_UNSTAGED_ICON '\uF06A' #  - VCS_STAGED_ICON '\uF055' #  + SWAP_ICON '\uF464 ' #  + RAM_ICON '\uF0E4 ' #  + SERVER_ICON '\uF0AE ' #  + VCS_UNTRACKED_ICON '\uF059 ' #  + VCS_UNSTAGED_ICON '\uF06A ' #  + VCS_STAGED_ICON '\uF055 ' #  VCS_STASH_ICON '\uF01C ' #  VCS_INCOMING_CHANGES_ICON '\uF01A ' #  VCS_OUTGOING_CHANGES_ICON '\uF01B ' #  @@ -384,22 +405,27 @@ function _p9k_init_icons() { VCS_GIT_BITBUCKET_ICON '\uE703 ' #  VCS_GIT_GITLAB_ICON '\uF296 ' #  VCS_HG_ICON '\uF0C3 ' #  - VCS_SVN_ICON '\uE72D ' #  - RUST_ICON '\uE7A8 ' #  + VCS_SVN_ICON '\uE72D' #  + RUST_ICON '\uE7A8' #  PYTHON_ICON '\UE73C ' #  SWIFT_ICON '\uE755' #  GO_ICON '\uE626' #  - PUBLIC_IP_ICON '\UF0AC' #  + PUBLIC_IP_ICON '\UF0AC ' #  LOCK_ICON '\UF023' #  - EXECUTION_TIME_ICON '\uF252' #  - SSH_ICON '\uF489' #  - VPN_ICON '(vpn)' + EXECUTION_TIME_ICON '\uF252 ' #  + SSH_ICON '\uF489 ' #  + VPN_ICON '\UF023' KUBERNETES_ICON '\U2388' # ⎈ - DROPBOX_ICON '\UF16B' #  + DROPBOX_ICON '\UF16B ' #  DATE_ICON '\uF073 ' #  TIME_ICON '\uF017 ' #  JAVA_ICON '\U2615' # ☕︎ - LARAVEL_ICON '\ue73f ' #  + LARAVEL_ICON '\ue73f' #  + RANGER_ICON '\u2B50' # ⭐ + TERRAFORM_ICON '\U1F6E0\u00A0' # 🛠️ + PROXY_ICON '\u2B82' # ⮂ + DOTNET_ICON '\uE77F' #  + AZURE_ICON '\uFD03' # ﴃ ) ;; *) @@ -414,10 +440,10 @@ function _p9k_init_icons() { RIGHT_SUBSEGMENT_SEPARATOR '\uE0B3' #  CARRIAGE_RETURN_ICON '\u21B5' # ↵ ROOT_ICON '\u26A1' # ⚡ - SUDO_ICON '\uE0A2' #  + SUDO_ICON '' RUBY_ICON 'Ruby' AWS_ICON 'AWS' - AWS_EB_ICON '\U1F331 ' # 🌱 + AWS_EB_ICON '\U1F331' # 🌱 BACKGROUND_JOBS_ICON '\u2699' # ⚙ TEST_ICON '' TODO_ICON '\u2611' # ☑ @@ -482,11 +508,11 @@ function _p9k_init_icons() { VCS_GIT_GITLAB_ICON '' VCS_HG_ICON '' VCS_SVN_ICON '' - RUST_ICON 'Rust' # TODO: try 𝗥. + RUST_ICON 'R' PYTHON_ICON 'Py' SWIFT_ICON 'Swift' GO_ICON 'Go' - PUBLIC_IP_ICON '' + PUBLIC_IP_ICON 'IP' LOCK_ICON '\UE0A2' EXECUTION_TIME_ICON '' SSH_ICON 'ssh' @@ -497,6 +523,11 @@ function _p9k_init_icons() { TIME_ICON '' JAVA_ICON '\U2615' # ☕︎ LARAVEL_ICON '' + RANGER_ICON '\u2B50' # ⭐ + TERRAFORM_ICON '\U1F6E0\u00A0' # 🛠️ + PROXY_ICON '\u2B82' # ⮂ + DOTNET_ICON '.NET' + AZURE_ICON '\u2601' # ☁ ) ;; esac @@ -518,9 +549,11 @@ function _p9k_init_icons() { } # Sadly, this is a part of public API. Its use is emphatically discouraged. -function print_icon() { +function _p9k_print_icon() { emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} _p9k_init_icons + [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale local icon_name=$1 local var_name=POWERLEVEL9K_${icon_name} if [[ -n "${(tP)var_name}" ]]; then @@ -535,9 +568,11 @@ function print_icon() { # * $1 string - If "original", then the original icons are printed, # otherwise "print_icon" is used, which takes the users # overrides into account. -function get_icon_names() { +function _p9k_get_icon_names() { emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} _p9k_init_icons + [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale # Iterate over a ordered list of keys of the icons array for key in ${(@kon)icons}; do echo -n "POWERLEVEL9K_$key: " diff --git a/internal/p10k.zsh b/internal/p10k.zsh old mode 100755 new mode 100644 index b37fa2d0..144f1a33 --- a/internal/p10k.zsh +++ b/internal/p10k.zsh @@ -27,7 +27,6 @@ if ! autoload -Uz is-at-least || ! is-at-least 5.1; then return 1 fi -source "${__p9k_root_dir}/internal/icons.zsh" source "${__p9k_root_dir}/internal/configure.zsh" # For compatibility with Powerlevel9k. It's not recommended to use mnemonic color @@ -89,14 +88,15 @@ typeset -grA __p9k_colors=( # # Type `getColorCode background` or `getColorCode foreground` to see the list of predefined colors. function getColorCode() { - emulate -L zsh && setopt no_hist_expand extended_glob + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} if (( ARGC == 1 )); then case $1 in foreground) local k for k in "${(k@)__p9k_colors}"; do local v=${__p9k_colors[$k]} - print -P "%F{$v}$v - $k%f" + print -rP -- "%F{$v}$v - $k%f" done return ;; @@ -104,7 +104,7 @@ function getColorCode() { local k for k in "${(k@)__p9k_colors}"; do local v=${__p9k_colors[$k]} - print -P "%K{$v}$v - $k%k" + print -rP -- "%K{$v}$v - $k%k" done return ;; @@ -114,6 +114,26 @@ function getColorCode() { return 1 } +# Sadly, this is a part of public API. Its use is emphatically discouraged. +function print_icon() { + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} no_aliases + (( $+functions[_p9k_print_icon] )) || source "${__p9k_root_dir}/internal/icons.zsh" + _p9k_print_icon "$@" +} + +# Prints a list of configured icons. +# +# * $1 string - If "original", then the original icons are printed, +# otherwise "print_icon" is used, which takes the users +# overrides into account. +function get_icon_names() { + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} no_aliases + (( $+functions[_p9k_get_icon_names] )) || source "${__p9k_root_dir}/internal/icons.zsh" + _p9k_get_icon_names "$@" +} + # _p9k_declare [default]... function _p9k_declare() { local -i set=$+parameters[$2] @@ -147,6 +167,7 @@ function _p9k_declare() { (( set )) && typeset -g _$2=${(P)2} || typeset -g _$2=$3 ;; -e) + [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale if (( set )); then local v=${(P)2} typeset -g _$2=${(g::)v} @@ -169,7 +190,6 @@ function _p9k_declare() { # _p9k_prompt_length '%F{red}abc' => 3 # _p9k_prompt_length $'%{a\b%Gb%}' => 1 function _p9k_prompt_length() { - emulate -L zsh && setopt no_hist_expand extended_glob local COLUMNS=1024 local -i x y=$#1 m if (( y )); then @@ -211,44 +231,13 @@ _p9k_segment_in_use() { } function _p9k_parse_ip() { - local desiredInterface=${1:-'^[^ ]+'} - - if [[ $_p9k_os == OSX ]]; then - [[ -x /sbin/ifconfig ]] || return - local rawInterfaces && rawInterfaces="$(/sbin/ifconfig -l 2>/dev/null)" || return - local -a interfaces=(${(A)=rawInterfaces}) - local pattern="${desiredInterface}[^ ]?" - local -a relevantInterfaces - for rawInterface in $interfaces; do - [[ "$rawInterface" =~ $pattern ]] && relevantInterfaces+=$MATCH - done - local newline=$'\n' - local interfaceName interface - for interfaceName in $relevantInterfaces; do - interface="$(/sbin/ifconfig $interfaceName 2>/dev/null)" || continue - [[ "${interface}" =~ "lo[0-9]*" ]] && continue - if [[ "${interface//${newline}/}" =~ "<([^>]*)>(.*)inet[ ]+([^ ]*)" ]]; then - local ipFound="${match[3]}" - local -a interfaceStates=(${(s:,:)match[1]}) - if (( ${interfaceStates[(I)UP]} )); then - _p9k_ret=$ipFound - return - fi - fi - done - else - [[ -x /sbin/ip ]] || return - local -a interfaces=( "${(f)$(/sbin/ip -brief -4 a show 2>/dev/null)}" ) - local pattern="^${desiredInterface}[[:space:]]+UP[[:space:]]+([^/ ]+)" - local interface - for interface in "${(@)interfaces}"; do - if [[ "$interface" =~ $pattern ]]; then - _p9k_ret=$match[1] - return - fi - done - fi - + local iface_regex="^${1:-.*}\$" iface ip + for iface ip in "${(@kv)_p9k_iface}"; do + if [[ $iface =~ $iface_regex ]]; then + _p9k_ret=$ip + return 0 + fi + done return 1 } @@ -271,6 +260,7 @@ _p9k_cache_set() { # echo "caching: ${(@0q)_p9k_cache_key} => (${(q)@})" >&2 _p9k_cache[$_p9k_cache_key]="${(pj:\0:)*}0" _p9k_cache_val=("$@") + _p9k_dump_scheduled=1 } _p9k_cache_get() { @@ -279,6 +269,63 @@ _p9k_cache_get() { [[ -n $v ]] && _p9k_cache_val=("${(@0)${v[1,-2]}}") } +_p9k_cache_stat_get() { + local -H stat + local label=$1 f + shift + + _p9k_cache_stat_meta= + _p9k_cache_stat_fprint= + + for f; do + if zstat -H stat -- $f 2>/dev/null; then + _p9k_cache_stat_meta+="${(q)f} $stat[inode] $stat[mtime] $stat[size] $stat[mode]; " + fi + done + + if _p9k_cache_get $0 $label meta "$@" && [[ $_p9k_cache_val[1] == $_p9k_cache_stat_meta ]]; then + _p9k_cache_stat_fprint=$_p9k_cache_val[2] + local -a key=($0 $label fprint "$@" "$_p9k_cache_stat_fprint") + _p9k_cache_fprint_key="${(pj:\0:)key}" + shift 2 _p9k_cache_val + return + fi + + if (( $+commands[md5] )); then + local -a md5=(md5) + elif (( $+commands[md5sum] )); then + local -a md5=(md5sum -b) + else + return 1 + fi + + local fprint + for f; do + if fprint="$($md5 $f 2>/dev/null)"; then + _p9k_cache_stat_fprint+="${(q)fprint} " + fi + done + + local meta_key=$_p9k_cache_key + if _p9k_cache_get $0 $label fprint "$@" "$_p9k_cache_stat_fprint"; then + _p9k_cache_fprint_key=$_p9k_cache_key + _p9k_cache_key=$meta_key + _p9k_cache_set "$_p9k_cache_stat_meta" "$_p9k_cache_stat_fprint" "$_p9k_cache_val[@]" + shift 2 _p9k_cache_val + return + fi + + _p9k_cache_fprint_key=$_p9k_cache_key + _p9k_cache_key=$meta_key + return 1 +} + +_p9k_cache_stat_set() { + _p9k_cache_set "$_p9k_cache_stat_meta" "$_p9k_cache_stat_fprint" "$@" + _p9k_cache_key=$_p9k_cache_fprint_key + _p9k_cache_set "$@" +} + # _p9k_param prompt_foo_BAR BACKGROUND red _p9k_param() { local key="_p9k_param ${(pj:\0:)*}" @@ -329,6 +376,7 @@ _p9k_get_icon() { if [[ $_p9k_ret == $'\1'* ]]; then _p9k_ret=${_p9k_ret[2,-1]} else + [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale _p9k_ret=${(g::)_p9k_ret} [[ $_p9k_ret != $'\b'? ]] || _p9k_ret="%{$_p9k_ret%}" # penance for past sins fi @@ -339,9 +387,9 @@ _p9k_get_icon() { _p9k_translate_color() { if [[ $1 == <-> ]]; then # decimal color code: 255 - _p9k_ret=$1 + _p9k_ret=${(l.3..0.)1} elif [[ $1 == '#'[[:xdigit:]]## ]]; then # hexademical color code: #ffffff - _p9k_ret=$1 + _p9k_ret=${(L)1} else # named color: red # Strip prifixes if there are any. _p9k_ret=$__p9k_colors[${${${1#bg-}#fg-}#br}] @@ -375,16 +423,16 @@ _p9k_vcs_style() { local var=POWERLEVEL9K_VCS_${1}_${2}FORMAT_FOREGROUND if (( $+parameters[$var] )); then - _p9k_ret=${(P)var} + _p9k_translate_color "${(P)var}" else var=POWERLEVEL9K_VCS_${2}FORMAT_FOREGROUND if (( $+parameters[$var] )); then - _p9k_ret=${(P)var} + _p9k_translate_color "${(P)var}" else _p9k_color prompt_vcs_$1 FOREGROUND "$_p9k_color1" fi fi - + _p9k_foreground $_p9k_ret _p9k_ret=$style$_p9k_ret _p9k_cache[$key]=${_p9k_ret}. @@ -485,7 +533,7 @@ _p9k_left_prompt_segment() { # 4 # fi - local t=$#_p9k_t + local t=$(($#_p9k_t - __p9k_ksh_arrays)) _p9k_t+=$start_sep$style$left_space # 1 _p9k_t+=$style # 2 if [[ -n $fg_color && $fg_color == $bg_color ]]; then @@ -506,10 +554,15 @@ _p9k_left_prompt_segment() { local p= p+="\${_p9k_n::=}" - p+="\${\${\${_p9k_bg:-0}:#NONE}:-\${_p9k_n::=$((t+1))}}" # 1 - p+="\${_p9k_n:=\${\${\$(($join)):#0}:+$((t+2))}}" # 2 - p+="\${_p9k_n:=\${\${(M)\${:-x$bg_color}:#x(\$_p9k_bg|\${_p9k_bg:-0})}:+$((t+3))}}" # 3 - p+="\${_p9k_n:=$((t+4))}" # 4 + p+="\${\${\${_p9k_bg:-0}:#NONE}:-\${_p9k_n::=$((t+1))}}" # 1 + p+="\${_p9k_n:=\${\${\$(($join)):#0}:+$((t+2))}}" # 2 + if (( __p9k_sh_glob )); then + p+="\${_p9k_n:=\${\${(M)\${:-x$bg_color}:#x\$_p9k_bg}:+$((t+3))}}" # 3 + p+="\${_p9k_n:=\${\${(M)\${:-x$bg_color}:#x\$${_p9k_bg:-0}}:+$((t+3))}}" # 3 + else + p+="\${_p9k_n:=\${\${(M)\${:-x$bg_color}:#x(\$_p9k_bg|\${_p9k_bg:-0})}:+$((t+3))}}" # 3 + fi + p+="\${_p9k_n:=$((t+4))}" # 4 _p9k_param $1 VISUAL_IDENTIFIER_EXPANSION '${P9K_VISUAL_IDENTIFIER}' local icon_exp_=${_p9k_ret:+\"$_p9k_ret\"} @@ -549,6 +602,7 @@ _p9k_left_prompt_segment() { p+='${${_p9k_e:#00}:+${${_p9k_t[$_p9k_n]/'$ss'/$_p9k_ss}/'$s'/$_p9k_s}' + [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale _p9k_param $1 ICON_BEFORE_CONTENT '' if [[ $_p9k_ret != false ]]; then _p9k_param $1 PREFIX '' @@ -694,7 +748,7 @@ _p9k_right_prompt_segment() { # 4 # fi - local t=$#_p9k_t + local t=$(($#_p9k_t - __p9k_ksh_arrays)) _p9k_t+=$start_sep$style$left_space # 1 _p9k_t+=$w$style # 2 _p9k_t+=$w$subsep$style$left_space # 3 @@ -706,10 +760,15 @@ _p9k_right_prompt_segment() { local p= p+="\${_p9k_n::=}" - p+="\${\${\${_p9k_bg:-0}:#NONE}:-\${_p9k_n::=$((t+1))}}" # 1 - p+="\${_p9k_n:=\${\${\$(($join)):#0}:+$((t+2))}}" # 2 - p+="\${_p9k_n:=\${\${(M)\${:-x\$_p9k_bg}:#x(${(b)bg_color}|${(b)bg_color:-0})}:+$((t+3))}}" # 3 - p+="\${_p9k_n:=$((t+4))}" # 4 + p+="\${\${\${_p9k_bg:-0}:#NONE}:-\${_p9k_n::=$((t+1))}}" # 1 + p+="\${_p9k_n:=\${\${\$(($join)):#0}:+$((t+2))}}" # 2 + if (( __p9k_sh_glob )); then + p+="\${_p9k_n:=\${\${(M)\${:-x\$_p9k_bg}:#x${(b)bg_color}}:+$((t+3))}}" # 3 + p+="\${_p9k_n:=\${\${(M)\${:-x\$_p9k_bg}:#x${(b)bg_color:-0}}:+$((t+3))}}" # 3 + else + p+="\${_p9k_n:=\${\${(M)\${:-x\$_p9k_bg}:#x(${(b)bg_color}|${(b)bg_color:-0})}:+$((t+3))}}" # 3 + fi + p+="\${_p9k_n:=$((t+4))}" # 4 _p9k_param $1 VISUAL_IDENTIFIER_EXPANSION '${P9K_VISUAL_IDENTIFIER}' local icon_exp_=${_p9k_ret:+\"$_p9k_ret\"} @@ -749,6 +808,7 @@ _p9k_right_prompt_segment() { p+='${${_p9k_e:#00}:+${_p9k_t[$_p9k_n]/'$w'/$_p9k_w}' + [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale _p9k_param $1 ICON_BEFORE_CONTENT '' if [[ $_p9k_ret != true ]]; then _p9k_param $1 PREFIX '' @@ -847,104 +907,7 @@ _p9k_right_prompt_segment() { } function _p9k_prompt_segment() { "_p9k_${_p9k_prompt_side}_prompt_segment" "$@" } - -typeset -gr __p9k_prompt_segment_usage="Usage: p9k_prompt_segment [{+|-}re] [-s state] [-b bg] [-f fg] [-i icon] [-c cond] [-t text] - -Options: - -t text segment's main content; will undergo prompt expansion: '%F{blue}%T%f' will - show as blue current time; default is empty - -i icon segment's icon; default is empty - -r icon is a symbolic reference that needs to be resolved; for example, 'LOCK_ICON' - +r icon is already resolved and should be printed literally; for example, '⭐'; - this is the default; you can also use $'\u2B50' if you don't want to have - non-ascii characters in source code - -b bg background color; for example, 'blue', '4', or '#0000ff'; empty value means - transparent background, as in '%k'; default is black - -f fg foreground color; for example, 'blue', '4', or '#0000ff'; empty value means - default foreground color, as in '%f'; default is empty - -s state segment's state for the purpose of applying styling options; if you want to - to be able to use POWERLEVEL9K parameters to specify different colors or icons - depending on some property, use different states for different values of that - property - -c condition; if empty after parameter expansion and process substitution, the - segment is hidden; this is an advanced feature, use with caution; default is '1' - -e segment's main content will undergo parameter expansion and process - substitution; the content will be surrounded with double quotes and thus - should quote its own double quotes; this is an advanced feature, use with - caution - +e segment's main content should not undergo parameter expansion and process - substitution; this is the default - -h print this help message and return - -Example: 'core' segment tells you if there is a file name 'core' in the current directory. - -- Segment's icon is '⭐'. -- Segment's text is the file's size in bytes. -- If you have permissions to delete the file, state is DELETABLE. If not, it's PROTECTED. - - zmodload -F zsh/stat b:zstat - - function prompt_core() { - local size=() - if ! zstat -A size +size core 2>/dev/null; then - # No 'core' file in the current directory. - return - fi - if [[ -w . ]]; then - local state=DELETABLE - else - local state=PROTECTED - fi - p9k_prompt_segment -s \$state -i '⭐' -b black -f blue -t \${size[1]}b - } - -To enable this segment, add 'core' to POWERLEVEL9K_LEFT_PROMPT_ELEMENTS or -POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS. - -Example customizations: - - # Override foreground. - POWERLEVEL9K_CORE_FOREGROUND=red - - # Override background when DELETABLE. - POWERLEVEL9K_CORE_DELETABLE_BACKGROUND=green - - # Override icon when PROTECTED. - POWERLEVEL9K_CORE_PROTECTED_VISUAL_IDENTIFIER_EXPANSION='❎' - - # Don't show file size when PROTECTED. - POWERLEVEL9K_CORE_PROTECTED_CONTENT_EXPANSION=''" - -# Type `p9k_prompt_segment -h` for usage. -function p9k_prompt_segment() { - emulate -L zsh && setopt no_hist_expand extended_glob - local opt state bg=0 fg icon cond text ref=0 expand=0 - while getopts ':s:b:f:i:c:t:re' opt; do - case $opt in - s) state=$OPTARG;; - b) bg=$OPTARG;; - f) fg=$OPTARG;; - i) icon=$OPTARG;; - c) cond=${OPTARG:-'${:-}'};; - t) text=$OPTARG;; - r) ref=1;; - e) expand=1;; - +r) ref=0;; - +e) expand=0;; - ?) echo -E - $__p9k_prompt_segment_usage >&2; return 1;; - esac - done - if (( OPTIND <= ARGC )); then - echo -E - $__p9k_prompt_segment_usage >&2 - return 1 - fi - if [[ -n $_p9k_prompt_side ]]; then - (( ref )) || icon=$'\1'$icon - "_p9k_${_p9k_prompt_side}_prompt_segment" "prompt_${_p9k_segment_name}${state:+_${(U)state}}" \ - "$bg" "${fg:-$_p9k_color1}" "$icon" "$expand" "$cond" "$text" - fi - return 0 -} +function p9k_prompt_segment() { p10k segment "$@" } function _p9k_python_version() { _p9k_cached_cmd_stdout_stderr python --version || return @@ -971,8 +934,8 @@ prompt_anaconda() { ################################################################ # AWS Profile prompt_aws() { - local aws_profile="${AWS_PROFILE:-$AWS_DEFAULT_PROFILE}" - if [[ -n "$aws_profile" ]]; then + local aws_profile="${AWS_VAULT:-${AWS_PROFILE:-$AWS_DEFAULT_PROFILE}}" + if [[ "$aws_profile" != (default|) ]]; then _p9k_prompt_segment "$0" red white 'AWS_ICON' 0 '' "${aws_profile//\%/%%}" fi } @@ -980,10 +943,23 @@ prompt_aws() { ################################################################ # Current Elastic Beanstalk environment prompt_aws_eb_env() { - [[ -r .elasticbeanstalk/config.yml ]] || return - local v=($(grep environment .elasticbeanstalk/config.yml 2>/dev/null)) - [[ $#v > 1 && -n $v[2] ]] || return - [[ -n $v ]] && _p9k_prompt_segment "$0" black green 'AWS_EB_ICON' 0 '' "${v[2]//\%/%%}" + (( $+commands[eb] )) || return + + local dir=$_p9k_pwd + while true; do + [[ $dir == / ]] && return + [[ -d $dir/.elasticbeanstalk ]] && break + dir=${dir:h} + done + + if ! _p9k_cache_stat_get $0 $dir/.elasticbeanstalk/config.yml; then + local env + env="$(command eb list 2>/dev/null)" || env= + env="${${(@M)${(@f)env}:#\* *}#\* }" + _p9k_cache_stat_set "$env" + fi + [[ -n $_p9k_cache_val[1] ]] || return + _p9k_prompt_segment "$0" black green 'AWS_EB_ICON' 0 '' "${_p9k_cache_val[1]//\%/%%}" } ################################################################ @@ -1025,7 +1001,7 @@ prompt_disk_usage() { function _p9k_read_file() { _p9k_ret='' - [[ -n $1 ]] && read -r _p9k_ret <$1 + [[ -n $1 ]] && IFS='' read -r _p9k_ret <$1 [[ -n $_p9k_ret ]] } @@ -1046,7 +1022,12 @@ prompt_battery() { case "${${(s:; :)raw_data}[2]}" in 'charging'|'finishing charge'|'AC attached') - state=CHARGING + if (( bat_percent == 100 )); then + state=CHARGED + remain='' + else + state=CHARGING + fi ;; 'discharging') (( bat_percent < _POWERLEVEL9K_BATTERY_LOW_THRESHOLD )) && state=LOW || state=DISCONNECTED @@ -1134,7 +1115,14 @@ prompt_battery() { bg=$_POWERLEVEL9K_BATTERY_LEVEL_BACKGROUND[idx] fi - _p9k_prompt_segment $0_$state "$bg" "$_p9k_battery_states[$state]" $icon 0 '' $msg + local fg=$_p9k_battery_states[$state] + if (( $#_POWERLEVEL9K_BATTERY_LEVEL_FOREGROUND )); then + local -i idx=$#_POWERLEVEL9K_BATTERY_LEVEL_FOREGROUND + (( bat_percent < 100 )) && idx=$((bat_percent * $#_POWERLEVEL9K_BATTERY_LEVEL_FOREGROUND / 100 + 1)) + fg=$_POWERLEVEL9K_BATTERY_LEVEL_FOREGROUND[idx] + fi + + _p9k_prompt_segment $0_$state "$bg" "$fg" $icon 0 '' $msg } ################################################################ @@ -1155,7 +1143,7 @@ prompt_context() { if ! _p9k_cache_get $0 "${(%):-%#}"; then local -i enabled=1 local content - if [[ $_POWERLEVEL9K_ALWAYS_SHOW_CONTEXT == 0 && -n $DEFAULT_USER && $_P9K_SSH == 0 ]]; then + if [[ $_POWERLEVEL9K_ALWAYS_SHOW_CONTEXT == 0 && -n $DEFAULT_USER && $P9K_SSH == 0 ]]; then local user="$(whoami)" if [[ $user == $DEFAULT_USER ]]; then if (( _POWERLEVEL9K_ALWAYS_SHOW_USER )); then @@ -1171,7 +1159,7 @@ prompt_context() { state="DEFAULT" if [[ "${(%):-%#}" == '#' ]]; then state="ROOT" - elif (( _P9K_SSH )); then + elif (( P9K_SSH )); then if [[ -n "$SUDO_COMMAND" ]]; then state="REMOTE_SUDO" else @@ -1184,6 +1172,7 @@ prompt_context() { if [[ -z $content ]]; then local var=POWERLEVEL9K_CONTEXT_${state}_TEMPLATE if (( $+parameters[$var] )); then + [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale content=${(P)var} content=${(g::)content} else @@ -1220,7 +1209,7 @@ prompt_user() { ################################################################ # Host: machine (where am I) prompt_host() { - if (( _P9K_SSH )); then + if (( P9K_SSH )); then _p9k_prompt_segment "$0_REMOTE" "${_p9k_color1}" yellow SSH_ICON 0 '' "$_POWERLEVEL9K_HOST_TEMPLATE" else _p9k_prompt_segment "$0_LOCAL" "${_p9k_color1}" yellow HOST_ICON 0 '' "$_POWERLEVEL9K_HOST_TEMPLATE" @@ -1233,9 +1222,10 @@ prompt_host() { _p9k_custom_prompt() { local segment_name=${1:u} local command=POWERLEVEL9K_CUSTOM_${segment_name} - local -a cmd=("${(@Q)${(z)${(P)command}}}") - whence $cmd[1] &>/dev/null || return - local content="$("$cmd[@]")" + command=${(P)command} + local cmd="${(Q)${(Az)command}[1]}" + (( $+functions[$cmd] || $+commands[$cmd] )) || return + local content="$(eval $command)" [[ -n $content ]] || return _p9k_prompt_segment "prompt_custom_$segment_name" $_p9k_color2 $_p9k_color1 "CUSTOM_${segment_name}_ICON" 0 '' "$content" } @@ -1243,8 +1233,7 @@ _p9k_custom_prompt() { ################################################################ # Display the duration the command needed to run. prompt_command_execution_time() { - (( _p9k_timer_start )) || return - P9K_COMMAND_DURATION_SECONDS=$((_p9k_timer_end - _p9k_timer_start)) + (( $+P9K_COMMAND_DURATION_SECONDS )) || return (( P9K_COMMAND_DURATION_SECONDS >= _POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD )) || return if (( P9K_COMMAND_DURATION_SECONDS < 60 )); then @@ -1292,33 +1281,41 @@ function _p9k_shorten_delim_len() { ################################################################ # Dir: current working directory prompt_dir() { - (( _POWERLEVEL9K_DIR_PATH_ABSOLUTE )) && local p=$PWD || local p=${(%):-%~} - - if [[ $p == '~['* ]]; then - # If "${(%):-%~}" expands to "~[a]/]/b", is the first component "~[a]" or "~[a]/]"? - # One would expect "${(%):-%-1~}" to give the right answer but alas it always simply - # gives the segment before the first slash, which would be "~[a]" in this case. Worse, - # for "~[a/b]" it'll give the nonsensical "~[a". To solve this problem we have to - # repeat what "${(%):-%~}" does and hope that it produces the same result. - local func='' - local -a parts=() - for func in zsh_directory_name $zsh_directory_name_functions; do - if (( $+functions[$func] )) && $func d $PWD && [[ $p == '~['$reply[1]']'* ]]; then - parts+='~['$reply[1]']' - break + if (( _POWERLEVEL9K_DIR_PATH_ABSOLUTE )); then + local p=$_p9k_pwd + local -a parts=("${(s:/:)p}") + elif [[ -o auto_name_dirs ]]; then + local p=${_p9k_pwd/#(#b)$HOME(|\/*)/'~'$match[1]} + local -a parts=("${(s:/:)p}") + else + local p=${(%):-%~} + if [[ $p == '~['* ]]; then + # If "${(%):-%~}" expands to "~[a]/]/b", is the first component "~[a]" or "~[a]/]"? + # One would expect "${(%):-%-1~}" to give the right answer but alas it always simply + # gives the segment before the first slash, which would be "~[a]" in this case. Worse, + # for "~[a/b]" it'll give the nonsensical "~[a". To solve this problem we have to + # repeat what "${(%):-%~}" does and hope that it produces the same result. + local func='' + local -a parts=() + for func in zsh_directory_name $zsh_directory_name_functions; do + if (( $+functions[$func] )) && $func d $_p9k_pwd && [[ $p == '~['$reply[1]']'* ]]; then + parts+='~['$reply[1]']' + break + fi + done + if (( $#parts )); then + parts+=(${(s:/:)${p#$parts[1]}}) + else + p=$_p9k_pwd + parts=("${(s:/:)p}") fi - done - if (( $#parts )); then - parts+=(${(s:/:)${p#$parts[1]}}) else - p=$PWD - parts=("${(s:/:)p}") + local -a parts=("${(s:/:)p}") fi - else - local -a parts=("${(s:/:)p}") fi local -i fake_first=0 expand=0 + [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale local delim=${_POWERLEVEL9K_SHORTEN_DELIMITER-$'\u2026'} local -i shortenlen=${_POWERLEVEL9K_SHORTEN_DIR_LENGTH:--1} @@ -1348,24 +1345,28 @@ prompt_dir() { () { [[ $_POWERLEVEL9K_SHORTEN_STRATEGY == truncate_with_package_name && $+commands[jq] == 1 && $#_POWERLEVEL9K_DIR_PACKAGE_FILES > 0 ]] || return - local pat="(${(j:|:)_POWERLEVEL9K_DIR_PACKAGE_FILES})" + local pats="(${(j:|:)_POWERLEVEL9K_DIR_PACKAGE_FILES})" local -i i=$#parts - local dir=$PWD + local dir=$_p9k_pwd for (( ; i > 0; --i )); do - local pkg_file='' - for pkg_file in $dir/${~pat}(N); do - local -H stat=() - zstat -H stat -- $pkg_file 2>/dev/null || return - if ! _p9k_cache_get $0_pkg $stat[inode] $stat[mtime] $stat[size]; then - local pkg_name='' - pkg_name="$(jq -j '.name' <$pkg_file 2>/dev/null)" || pkg_name='' - _p9k_cache_set "$pkg_name" - fi - [[ -n $_p9k_cache_val[1] ]] || return - parts[1,i]=($_p9k_cache_val[1]) - fake_first=1 - return - done + local markers=($dir/${~pats}(N)) + if (( $#markers )); then + local pat= pkg_file= + for pat in $_POWERLEVEL9K_DIR_PACKAGE_FILES; do + for pkg_file in $markers; do + [[ $pkg_file == $dir/${~pat} ]] || continue + if ! _p9k_cache_stat_get $0_pkg $pkg_file; then + local pkg_name='' + pkg_name="$(jq -j '.name | select(. != null)' <$pkg_file 2>/dev/null)" || pkg_name='' + _p9k_cache_stat_set "$pkg_name" + fi + [[ -n $_p9k_cache_val[1] ]] || continue + parts[1,i]=($_p9k_cache_val[1]) + fake_first=1 + return + done + done + fi dir=${dir:h} done } @@ -1400,7 +1401,7 @@ prompt_dir() { delim=${_POWERLEVEL9K_SHORTEN_DELIMITER-'*'} local -i i=2 [[ $p[1] == / ]] && (( ++i )) - local parent="${PWD%/${(pj./.)parts[i,-1]}}" + local parent="${_p9k_pwd%/${(pj./.)parts[i,-1]}}" if (( i <= $#parts )); then local mtime=() zstat -A mtime +mtime -- ${(@)${:-{$i..$#parts}}/(#b)(*)/$parent/${(pj./.)parts[i,$match[1]]}} 2>/dev/null || mtime=() @@ -1454,7 +1455,7 @@ prompt_dir() { ;; truncate_with_folder_marker) if [[ -n $_POWERLEVEL9K_SHORTEN_FOLDER_MARKER ]]; then - local dir=$PWD + local dir=$_p9k_pwd local -a m=() local -i i=$(($#parts - 1)) for (( ; i > 1; --i )); do @@ -1478,9 +1479,9 @@ prompt_dir() { ;; esac - [[ $_POWERLEVEL9K_DIR_SHOW_WRITABLE == 1 && ! -w $PWD ]] + [[ $_POWERLEVEL9K_DIR_SHOW_WRITABLE == 1 && ! -w $_p9k_pwd ]] local w=$? - if ! _p9k_cache_get $0 $PWD $w $fake_first "${parts[@]}"; then + if ! _p9k_cache_get $0 $_p9k_pwd $p $w $fake_first "${parts[@]}"; then local state=$0 local icon='' if (( ! w )); then @@ -1489,7 +1490,7 @@ prompt_dir() { else local a='' b='' c='' for a b c in "${_POWERLEVEL9K_DIR_CLASSES[@]}"; do - if [[ $PWD == ${~a} ]]; then + if [[ $_p9k_pwd == ${~a} ]]; then [[ -n $b ]] && state+=_${(U)b} icon=$'\1'$c break @@ -1577,7 +1578,7 @@ prompt_dir() { local content="${(pj.$sep.)parts}" if (( _POWERLEVEL9K_DIR_HYPERLINK )); then - local pref=$'%{\e]8;;file://'${${PWD//\%/%%25}//'#'/%%23}$'\a%}' + local pref=$'%{\e]8;;file://'${${_p9k_pwd//\%/%%25}//'#'/%%23}$'\a%}' local suf=$'%{\e]8;;\a%}' if (( expand )); then _p9k_escape $pref @@ -1588,7 +1589,7 @@ prompt_dir() { content=$pref$content$suf fi - (( expand )) && eval "_p9k_prompt_length \"\${\${_p9k_d::=0}+}$content\"" || _p9k_ret= + (( expand )) && _p9k_prompt_length "${(e):-"\${\${_p9k_d::=0}+}$content"}" || _p9k_ret= _p9k_cache_set "$state" "$icon" "$expand" "$content" $_p9k_ret fi @@ -1619,20 +1620,23 @@ prompt_go_version() { local -a match [[ $_p9k_ret == (#b)*go([[:digit:].]##)* ]] || return local v=$match[1] - local p=$GOPATH - if [[ -z $p ]]; then - if [[ -d $HOME/go ]]; then - p=$HOME/go - else - p="$(go env GOPATH 2>/dev/null)" && [[ -n $p ]] || return + if (( _POWERLEVEL9K_GO_VERSION_PROJECT_ONLY )); then + local p=$GOPATH + if [[ -z $p ]]; then + if [[ -d $HOME/go ]]; then + p=$HOME/go + else + p="$(go env GOPATH 2>/dev/null)" && [[ -n $p ]] || return + fi + fi + if [[ $_p9k_pwd/ != $p/* && $_p9k_pwd_a/ != $p/* ]]; then + local dir=$_p9k_pwd_a + while true; do + [[ $dir == / ]] && return + [[ -e $dir/go.mod ]] && break + dir=${dir:h} + done fi - fi - if [[ $PWD/ != $p/* ]]; then - local dir=$PWD - while [[ ! -e $dir/go.mod ]]; do - [[ $dir == / ]] && return - dir=${dir:h} - done fi _p9k_prompt_segment "$0" "green" "grey93" "GO_ICON" 0 '' "${v//\%/%%}" } @@ -1708,41 +1712,37 @@ prompt_load() { (( _p9k_num_cpus )) || return if (( load > 0.7 * _p9k_num_cpus )); then - local state=critical bg=red + local state=CRITICAL bg=red elif (( load > 0.5 * _p9k_num_cpus )); then - local state=warning bg=yellow + local state=WARNING bg=yellow else - local state=normal bg=green + local state=NORMAL bg=green fi _p9k_prompt_segment $0_$state $bg "$_p9k_color1" LOAD_ICON 0 '' $load } function _p9k_cached_cmd_stdout() { - local cmd=$commands[$1] + local cmd=${commands[$1]:A} [[ -n $cmd ]] || return shift - local -H stat - zstat -H stat -- $cmd 2>/dev/null || return - if ! _p9k_cache_get $0 $stat[inode] $stat[mtime] $stat[size] $stat[mode] $cmd "$@"; then + if ! _p9k_cache_stat_get $0" ${(q)*}" $cmd; then local out out="$($cmd "$@" 2>/dev/null)" - _p9k_cache_set $(( ! $? )) "$out" + _p9k_cache_stat_set $(( ! $? )) "$out" fi (( $_p9k_cache_val[1] )) || return _p9k_ret=$_p9k_cache_val[2] } function _p9k_cached_cmd_stdout_stderr() { - local cmd=$commands[$1] + local cmd=${commands[$1]:A} [[ -n $cmd ]] || return shift - local -H stat - zstat -H stat -- $cmd 2>/dev/null || return - if ! _p9k_cache_get $0 $stat[inode] $stat[mtime] $stat[size] $stat[mode] $cmd "$@"; then + if ! _p9k_cache_stat_get $0" ${(q)*}" $cmd; then local out out="$($cmd "$@" 2>&1)" # this line is the only diff with _p9k_cached_cmd_stdout - _p9k_cache_set $(( ! $? )) "$out" + _p9k_cache_stat_set $(( ! $? )) "$out" fi (( $_p9k_cache_val[1] )) || return _p9k_ret=$_p9k_cache_val[2] @@ -1754,7 +1754,7 @@ prompt_node_version() { (( $+commands[node] )) || return if (( _POWERLEVEL9K_NODE_VERSION_PROJECT_ONLY )); then - local dir=$PWD + local dir=$_p9k_pwd while true; do [[ $dir == / ]] && return [[ -e $dir/package.json ]] && break @@ -1771,9 +1771,11 @@ prompt_node_version() { function _p9k_nvm_ls_default() { local v=default local -a seen=($v) - local target - while [[ -r $NVM_DIR/alias/$v ]] && read target <$NVM_DIR/alias/$v; do - [[ -n $target && ${seen[(I)$target]} == 0 ]] || return + while [[ -r $NVM_DIR/alias/$v ]]; do + local target= + IFS='' read -r target <$NVM_DIR/alias/$v + [[ -z $target ]] && break + (( $seen[(I)$target] )) && return seen+=$target v=$target done @@ -1864,7 +1866,7 @@ _p9k_nvm_ls_current() { # Segment to display Node version from NVM # Only prints the segment if different than the default value prompt_nvm() { - (( $+commands[nvm] )) || return + (( $+commands[nvm] || $+functions[nvm] )) || return [[ -n $NVM_DIR ]] && _p9k_nvm_ls_current || return local current=$_p9k_ret ! _p9k_nvm_ls_default || [[ $_p9k_ret != $current ]] || return @@ -1908,10 +1910,10 @@ function _p9k_nodenv_global_version() { # Segment to display nodenv information # https://github.com/nodenv/nodenv prompt_nodenv() { - (( $+commands[nodenv] )) || return + (( $+commands[nodenv] || $+functions[nodenv] )) || return _p9k_ret=$NODENV_VERSION if [[ -z $_p9k_ret ]]; then - [[ $NODENV_DIR == /* ]] && local dir=$NODENV_DIR || local dir="$PWD/$NODENV_DIR" + [[ $NODENV_DIR == /* ]] && local dir=$NODENV_DIR || local dir="$_p9k_pwd_a/$NODENV_DIR" while [[ $dir != //[^/]# ]]; do _p9k_read_nodenv_version_file $dir/.node-version && break [[ $dir == / ]] && break @@ -1934,6 +1936,23 @@ prompt_nodenv() { _p9k_prompt_segment "$0" "black" "green" 'NODE_ICON' 0 '' "${v//\%/%%}" } +prompt_dotnet_version() { + (( $+commands[dotnet] )) || return + + if (( _POWERLEVEL9K_DOTNET_VERSION_PROJECT_ONLY )); then + local dir=$_p9k_pwd + while true; do + [[ $dir == / ]] && return + [[ -n $dir/(project.json|global.json|packet.dependencies|*.csproj|*.fsproj|*.xproj|*.sln)(#qN^/) ]] && break + dir=${dir:h} + done + fi + + _p9k_cached_cmd_stdout dotnet --version || return + _p9k_prompt_segment "$0" "magenta" "white" 'DOTNET_ICON' 0 '' "$_p9k_ret" +} + + ################################################################ # Segment to print a little OS icon prompt_os_icon() { @@ -1983,9 +2002,8 @@ prompt_ram() { function _p9k_read_rbenv_version_file() { [[ -r $1 ]] || return - local content - read -r content <$1 2>/dev/null - _p9k_ret="${${(A)=content}[1]}" + local rest + read _p9k_ret rest <$1 2>/dev/null [[ -n $_p9k_ret ]] } @@ -1997,10 +2015,10 @@ function _p9k_rbenv_global_version() { # Segment to display rbenv information # https://github.com/rbenv/rbenv#choosing-the-ruby-version prompt_rbenv() { - (( $+commands[rbenv] )) || return + (( $+commands[rbenv] || $+functions[rbenv] )) || return local v=$RBENV_VERSION if [[ -z $v ]]; then - [[ $RBENV_DIR == /* ]] && local dir=$RBENV_DIR || local dir="$PWD/$RBENV_DIR" + [[ $RBENV_DIR == /* ]] && local dir=$RBENV_DIR || local dir="$_p9k_pwd_a/$RBENV_DIR" while true; do if _p9k_read_rbenv_version_file $dir/.ruby-version; then v=$_p9k_ret @@ -2047,6 +2065,14 @@ prompt_rust_version() { _p9k_cached_cmd_stdout rustc --version || return local v=${${_p9k_ret#rustc }%% *} [[ -n $v ]] || return + if (( _POWERLEVEL9K_RUST_VERSION_PROJECT_ONLY )); then + local dir=$_p9k_pwd_a + while true; do + [[ $dir == / ]] && return + [[ -e $dir/Cargo.toml ]] && break + dir=${dir:h} + done + fi _p9k_prompt_segment "$0" "darkorange" "$_p9k_color1" 'RUST_ICON' 0 '' "${v//\%/%%}" } @@ -2063,9 +2089,11 @@ prompt_rspec_stats() { ################################################################ # Segment to display Ruby Version Manager information prompt_rvm() { - (( $+commands[rvm-prompt] )) || return + (( $+commands[rvm-prompt] || $+functions[rvm-prompt] )) || return [[ $GEM_HOME == *rvm* && $ruby_string != $rvm_path/bin/ruby ]] || return - local v=${${${GEM_HOME:t}%%${rvm_gemset_separator:-@}*}#*-} + local v=${GEM_HOME:t} + (( _POWERLEVEL9K_RVM_SHOW_GEMSET )) || v=${v%%${rvm_gemset_separator:-@}*} + (( _POWERLEVEL9K_RVM_SHOW_PREFIX )) || v=${v#*-} [[ -n $v ]] || return _p9k_prompt_segment "$0" "240" "$_p9k_color1" 'RUBY_ICON' 0 '' "${v//\%/%%}" } @@ -2073,7 +2101,7 @@ prompt_rvm() { ################################################################ # Segment to display SSH icon when connected prompt_ssh() { - if [[ -n "$SSH_CLIENT" || -n "$SSH_TTY" ]]; then + if (( P9K_SSH )); then _p9k_prompt_segment "$0" "$_p9k_color1" "yellow" 'SSH_ICON' 0 '' '' fi } @@ -2121,14 +2149,46 @@ prompt_status() { } prompt_prompt_char() { - if (( _p9k_status )); then - _p9k_prompt_segment $0_ERROR_VIINS "$_p9k_color1" 196 '' 0 '${${KEYMAP:-0}:#(vicmd|vivis|vivli)}' '❯' - _p9k_prompt_segment $0_ERROR_VICMD "$_p9k_color1" 196 '' 0 '${(M)${:-$KEYMAP$_p9k_region_active}:#vicmd0}' '❮' - _p9k_prompt_segment $0_ERROR_VIVIS "$_p9k_color1" 196 '' 0 '${(M)${:-$KEYMAP$_p9k_region_active}:#(vicmd1|vivis?|vivli?)}' 'Ⅴ' + if (( __p9k_sh_glob )); then + if (( _p9k_status )); then + if (( _POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE )); then + _p9k_prompt_segment $0_ERROR_VIINS "$_p9k_color1" 196 '' 0 '${${${${${${:-$_p9k_keymap.$_p9k_zle_state}:#vicmd.*}:#vivis.*}:#vivli.*}:#*.*overwrite*}}' '❯' + _p9k_prompt_segment $0_ERROR_VIOWR "$_p9k_color1" 196 '' 0 '${${${${${${:-$_p9k_keymap.$_p9k_zle_state}:#vicmd.*}:#vivis.*}:#vivli.*}:#*.*insert*}}' '▶' + else + _p9k_prompt_segment $0_ERROR_VIINS "$_p9k_color1" 196 '' 0 '${${${${_p9k_keymap:#vicmd}:#vivis}:#vivli}}' '❯' + fi + _p9k_prompt_segment $0_ERROR_VICMD "$_p9k_color1" 196 '' 0 '${(M)${:-$_p9k_keymap$_p9k_region_active}:#vicmd0}' '❮' + _p9k_prompt_segment $0_ERROR_VIVIS "$_p9k_color1" 196 '' 0 '${$((! ${#${${${${:-$_p9k_keymap$_p9k_region_active}:#vicmd1}:#vivis?}:#vivli?}})):#0}' 'Ⅴ' + else + if (( _POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE )); then + _p9k_prompt_segment $0_OK_VIINS "$_p9k_color1" 76 '' 0 '${${${${${${:-$_p9k_keymap.$_p9k_zle_state}:#vicmd.*}:#vivis.*}:#vivli.*}:#*.*overwrite*}}' '❯' + _p9k_prompt_segment $0_OK_VIOWR "$_p9k_color1" 76 '' 0 '${${${${${${:-$_p9k_keymap.$_p9k_zle_state}:#vicmd.*}:#vivis.*}:#vivli.*}:#*.*insert*}}' '▶' + else + _p9k_prompt_segment $0_OK_VIINS "$_p9k_color1" 76 '' 0 '${${${${_p9k_keymap:#vicmd}:#vivis}:#vivli}}' '❯' + fi + _p9k_prompt_segment $0_OK_VICMD "$_p9k_color1" 76 '' 0 '${(M)${:-$_p9k_keymap$_p9k_region_active}:#vicmd0}' '❮' + _p9k_prompt_segment $0_OK_VIVIS "$_p9k_color1" 76 '' 0 '${$((! ${#${${${${:-$_p9k_keymap$_p9k_region_active}:#vicmd1}:#vivis?}:#vivli?}})):#0}' 'Ⅴ' + fi else - _p9k_prompt_segment $0_OK_VIINS "$_p9k_color1" 76 '' 0 '${${KEYMAP:-0}:#(vicmd|vivis|vivli)}' '❯' - _p9k_prompt_segment $0_OK_VICMD "$_p9k_color1" 76 '' 0 '${(M)${:-$KEYMAP$_p9k_region_active}:#vicmd0}' '❮' - _p9k_prompt_segment $0_OK_VIVIS "$_p9k_color1" 76 '' 0 '${(M)${:-$KEYMAP$_p9k_region_active}:#(vicmd1|vivis?|vivli?)}' 'Ⅴ' + if (( _p9k_status )); then + if (( _POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE )); then + _p9k_prompt_segment $0_ERROR_VIINS "$_p9k_color1" 196 '' 0 '${${:-$_p9k_keymap.$_p9k_zle_state}:#(vicmd.*|vivis.*|vivli.*|*.*overwrite*)}' '❯' + _p9k_prompt_segment $0_ERROR_VIOWR "$_p9k_color1" 196 '' 0 '${${:-$_p9k_keymap.$_p9k_zle_state}:#(vicmd.*|vivis.*|vivli.*|*.*insert*)}' '▶' + else + _p9k_prompt_segment $0_ERROR_VIINS "$_p9k_color1" 196 '' 0 '${_p9k_keymap:#(vicmd|vivis|vivli)}' '❯' + fi + _p9k_prompt_segment $0_ERROR_VICMD "$_p9k_color1" 196 '' 0 '${(M)${:-$_p9k_keymap$_p9k_region_active}:#vicmd0}' '❮' + _p9k_prompt_segment $0_ERROR_VIVIS "$_p9k_color1" 196 '' 0 '${(M)${:-$_p9k_keymap$_p9k_region_active}:#(vicmd1|vivis?|vivli?)}' 'Ⅴ' + else + if (( _POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE )); then + _p9k_prompt_segment $0_OK_VIINS "$_p9k_color1" 76 '' 0 '${${:-$_p9k_keymap.$_p9k_zle_state}:#(vicmd.*|vivis.*|vivli.*|*.*overwrite*)}' '❯' + _p9k_prompt_segment $0_OK_VIOWR "$_p9k_color1" 76 '' 0 '${${:-$_p9k_keymap.$_p9k_zle_state}:#(vicmd.*|vivis.*|vivli.*|*.*insert*)}' '▶' + else + _p9k_prompt_segment $0_OK_VIINS "$_p9k_color1" 76 '' 0 '${_p9k_keymap:#(vicmd|vivis|vivli)}' '❯' + fi + _p9k_prompt_segment $0_OK_VICMD "$_p9k_color1" 76 '' 0 '${(M)${:-$_p9k_keymap$_p9k_region_active}:#vicmd0}' '❮' + _p9k_prompt_segment $0_OK_VIVIS "$_p9k_color1" 76 '' 0 '${(M)${:-$_p9k_keymap$_p9k_region_active}:#(vicmd1|vivis?|vivli?)}' 'Ⅴ' + fi fi } @@ -2227,14 +2287,12 @@ prompt_date() { prompt_todo() { local todo=$commands[todo.sh] [[ -n $todo && -r $_p9k_todo_file ]] || return - local -H stat - zstat -H stat -- $_p9k_todo_file 2>/dev/null || return - if ! _p9k_cache_get $0 $stat[inode] $stat[mtime] $stat[size]; then + if ! _p9k_cache_stat_get $0 $_p9k_todo_file; then local count="$($todo -p ls | tail -1)" if [[ $count == (#b)'TODO: '[[:digit:]]##' of '([[:digit:]]##)' '* ]]; then - _p9k_cache_set 1 $match[1] + _p9k_cache_stat_set 1 $match[1] else - _p9k_cache_set 0 0 + _p9k_cache_stat_set 0 0 fi fi (( $_p9k_cache_val[1] )) || return @@ -2251,6 +2309,7 @@ typeset -gA __p9k_vcs_states=( 'MODIFIED' '3' 'UNTRACKED' '2' 'LOADING' '8' + 'CONFLICTED' '3' ) function +vi-git-untracked() { @@ -2465,13 +2524,13 @@ _p9k_vcs_info_init() { function _p9k_vcs_status_save() { local z=$'\0' - _p9k_last_git_prompt[$VCS_STATUS_WORKDIR]=$VCS_STATUS_ACTION$z$VCS_STATUS_COMMIT\ + _p9k_gitstatus_last[$VCS_STATUS_WORKDIR]=$VCS_STATUS_ACTION$z$VCS_STATUS_COMMIT\ $z$VCS_STATUS_COMMITS_AHEAD$z$VCS_STATUS_COMMITS_BEHIND$z$VCS_STATUS_HAS_CONFLICTED\ $z$VCS_STATUS_HAS_STAGED$z$VCS_STATUS_HAS_UNSTAGED$z$VCS_STATUS_HAS_UNTRACKED\ $z$VCS_STATUS_INDEX_SIZE$z$VCS_STATUS_LOCAL_BRANCH$z$VCS_STATUS_NUM_CONFLICTED\ $z$VCS_STATUS_NUM_STAGED$z$VCS_STATUS_NUM_UNSTAGED$z$VCS_STATUS_NUM_UNTRACKED\ $z$VCS_STATUS_REMOTE_BRANCH$z$VCS_STATUS_REMOTE_NAME$z$VCS_STATUS_REMOTE_URL\ -$z$VCS_STATUS_RESULT$z$VCS_STATUS_STASHES$z$VCS_STATUS_TAG +$z$VCS_STATUS_RESULT$z$VCS_STATUS_STASHES$z$VCS_STATUS_TAG$z$VCS_STATUS_NUM_UNSTAGED_DELETED } function _p9k_vcs_status_restore() { @@ -2481,13 +2540,14 @@ function _p9k_vcs_status_restore() { VCS_STATUS_NUM_CONFLICTED VCS_STATUS_NUM_STAGED VCS_STATUS_NUM_UNSTAGED \ VCS_STATUS_NUM_UNTRACKED VCS_STATUS_REMOTE_BRANCH VCS_STATUS_REMOTE_NAME \ VCS_STATUS_REMOTE_URL VCS_STATUS_RESULT VCS_STATUS_STASHES VCS_STATUS_TAG \ + VCS_STATUS_NUM_UNSTAGED_DELETED in "${(@0)1}"; do done } function _p9k_vcs_status_for_dir() { local dir=$1 while true; do - _p9k_ret=$_p9k_last_git_prompt[$dir] + _p9k_ret=$_p9k_gitstatus_last[$dir] [[ -n $_p9k_ret ]] && return 0 [[ $dir == / ]] && return 1 dir=${dir:h} @@ -2498,7 +2558,7 @@ function _p9k_vcs_status_purge() { local dir=$1 while true; do # unset doesn't work if $dir contains weird shit - _p9k_last_git_prompt[$dir]="" + _p9k_gitstatus_last[$dir]="" _p9k_git_slow[$dir]="" [[ $dir == / ]] && break dir=${dir:h} @@ -2518,8 +2578,8 @@ function _p9k_vcs_icon() { function _p9k_vcs_render() { local state - if (( $+_p9k_next_vcs_dir )); then - if _p9k_vcs_status_for_dir ${${GIT_DIR:a}:-$PWD}; then + if (( $+_p9k_gitstatus_next_dir )); then + if _p9k_vcs_status_for_dir ${${GIT_DIR:A}:-$_p9k_pwd_a}; then _p9k_vcs_status_restore $_p9k_ret state=LOADING else @@ -2532,7 +2592,9 @@ function _p9k_vcs_render() { if (( _POWERLEVEL9K_VCS_DISABLE_GITSTATUS_FORMATTING )); then if [[ -z $state ]]; then - if [[ $VCS_STATUS_HAS_STAGED != 0 || $VCS_STATUS_HAS_UNSTAGED != 0 ]]; then + if [[ $VCS_STATUS_HAS_CONFLICTED == 1 && $_POWERLEVEL9K_VCS_CONFLICTED_STATE == 1 ]]; then + state=CONFLICTED + elif [[ $VCS_STATUS_HAS_STAGED != 0 || $VCS_STATUS_HAS_UNSTAGED != 0 ]]; then state=MODIFIED elif [[ $VCS_STATUS_HAS_UNTRACKED != 0 ]]; then state=UNTRACKED @@ -2565,6 +2627,7 @@ function _p9k_vcs_render() { "$VCS_STATUS_NUM_STAGED" "$VCS_STATUS_NUM_UNSTAGED" "$VCS_STATUS_NUM_UNTRACKED" + "$VCS_STATUS_HAS_CONFLICTED" "$VCS_STATUS_HAS_STAGED" "$VCS_STATUS_HAS_UNSTAGED" "$VCS_STATUS_HAS_UNTRACKED" @@ -2572,6 +2635,7 @@ function _p9k_vcs_render() { "$VCS_STATUS_COMMITS_BEHIND" "$VCS_STATUS_STASHES" "$VCS_STATUS_TAG" + "$VCS_STATUS_NUM_UNSTAGED_DELETED" ) if [[ $_POWERLEVEL9K_SHOW_CHANGESET == 1 || -z $VCS_STATUS_LOCAL_BRANCH ]]; then cache_key+=$VCS_STATUS_COMMIT @@ -2582,7 +2646,9 @@ function _p9k_vcs_render() { local content if (( ${_POWERLEVEL9K_VCS_GIT_HOOKS[(I)vcs-detect-changes]} )); then - if [[ $VCS_STATUS_HAS_STAGED != 0 || $VCS_STATUS_HAS_UNSTAGED != 0 ]]; then + if [[ $VCS_STATUS_HAS_CONFLICTED == 1 && $_POWERLEVEL9K_VCS_CONFLICTED_STATE == 1 ]]; then + : ${state:=CONFLICTED} + elif [[ $VCS_STATUS_HAS_STAGED != 0 || $VCS_STATUS_HAS_UNSTAGED != 0 ]]; then : ${state:=MODIFIED} elif [[ $VCS_STATUS_HAS_UNTRACKED != 0 ]]; then : ${state:=UNTRACKED} @@ -2614,8 +2680,24 @@ function _p9k_vcs_render() { fi if [[ -n $VCS_STATUS_LOCAL_BRANCH ]]; then - (( _POWERLEVEL9K_HIDE_BRANCH_ICON )) && _p9k_ret='' || _p9k_get_icon prompt_vcs_$state VCS_BRANCH_ICON - _$0_fmt BRANCH "$ws$_p9k_ret${VCS_STATUS_LOCAL_BRANCH//\%/%%}" + local branch=$ws + if (( !_POWERLEVEL9K_HIDE_BRANCH_ICON )); then + _p9k_get_icon prompt_vcs_$state VCS_BRANCH_ICON + branch+=$_p9k_ret + fi + if (( $+_POWERLEVEL9K_VCS_SHORTEN_LENGTH && $+_POWERLEVEL9K_VCS_SHORTEN_MIN_LENGTH && + $#VCS_STATUS_LOCAL_BRANCH > _POWERLEVEL9K_VCS_SHORTEN_MIN_LENGTH && + $#VCS_STATUS_LOCAL_BRANCH > _POWERLEVEL9K_VCS_SHORTEN_LENGTH )) && + [[ $_POWERLEVEL9K_VCS_SHORTEN_STRATEGY == (truncate_middle|truncate_from_right) ]]; then + branch+=${VCS_STATUS_LOCAL_BRANCH[1,_POWERLEVEL9K_VCS_SHORTEN_LENGTH]//\%/%%}${_POWERLEVEL9K_VCS_SHORTEN_DELIMITER} + if [[ $_POWERLEVEL9K_VCS_SHORTEN_STRATEGY == truncate_middle ]]; then + _p9k_vcs_style $state BRANCH + branch+=${_p9k_ret}${VCS_STATUS_LOCAL_BRANCH[-_POWERLEVEL9K_VCS_SHORTEN_LENGTH,-1]//\%/%%} + fi + else + branch+=${VCS_STATUS_LOCAL_BRANCH//\%/%%} + fi + _$0_fmt BRANCH $branch fi if [[ $_POWERLEVEL9K_VCS_HIDE_TAGS == 0 && -n $VCS_STATUS_TAG ]]; then @@ -2674,7 +2756,8 @@ function _p9k_vcs_render() { } function _p9k_vcs_resume() { - emulate -L zsh && setopt no_hist_expand extended_glob + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} if [[ $VCS_STATUS_RESULT == ok-async ]]; then local latency=$((EPOCHREALTIME - _p9k_gitstatus_start_time)) @@ -2686,23 +2769,23 @@ function _p9k_vcs_resume() { _p9k_vcs_status_save fi - if [[ -z $_p9k_next_vcs_dir ]]; then - unset _p9k_next_vcs_dir + if [[ -z $_p9k_gitstatus_next_dir ]]; then + unset _p9k_gitstatus_next_dir case $VCS_STATUS_RESULT in - norepo-async) (( $1 )) && _p9k_vcs_status_purge ${${GIT_DIR:a}:-$PWD};; - ok-async) (( $1 )) || _p9k_next_vcs_dir=${${GIT_DIR:a}:-$PWD};; + norepo-async) (( $1 )) && _p9k_vcs_status_purge ${${GIT_DIR:A}:-$_p9k_pwd_a};; + ok-async) (( $1 )) || _p9k_gitstatus_next_dir=${${GIT_DIR:A}:-$_p9k_pwd_a};; esac fi - if [[ -n $_p9k_next_vcs_dir ]]; then - if ! gitstatus_query -d $_p9k_next_vcs_dir -t 0 -c '_p9k_vcs_resume 1' POWERLEVEL9K; then - unset _p9k_next_vcs_dir + if [[ -n $_p9k_gitstatus_next_dir ]]; then + if ! gitstatus_query -d $_p9k_gitstatus_next_dir -t 0 -c '_p9k_vcs_resume 1' POWERLEVEL9K; then + unset _p9k_gitstatus_next_dir unset VCS_STATUS_RESULT else case $VCS_STATUS_RESULT in - tout) _p9k_next_vcs_dir=''; _p9k_gitstatus_start_time=$EPOCHREALTIME;; - norepo-sync) _p9k_vcs_status_purge $_p9k_next_vcs_dir; unset _p9k_next_vcs_dir;; - ok-sync) _p9k_vcs_status_save; unset _p9k_next_vcs_dir;; + tout) _p9k_gitstatus_next_dir=''; _p9k_gitstatus_start_time=$EPOCHREALTIME;; + norepo-sync) _p9k_vcs_status_purge $_p9k_gitstatus_next_dir; unset _p9k_gitstatus_next_dir;; + ok-sync) _p9k_vcs_status_save; unset _p9k_gitstatus_next_dir;; esac fi fi @@ -2711,17 +2794,16 @@ function _p9k_vcs_resume() { } function _p9k_vcs_gitstatus() { - (( _POWERLEVEL9K_DISABLE_GITSTATUS )) && return 1 if [[ $_p9k_refresh_reason == precmd ]]; then - if (( $+_p9k_next_vcs_dir )); then - _p9k_next_vcs_dir=${${GIT_DIR:a}:-$PWD} + if (( $+_p9k_gitstatus_next_dir )); then + _p9k_gitstatus_next_dir=${${GIT_DIR:A}:-$_p9k_pwd_a} else - local dir=${${GIT_DIR:a}:-$PWD} + local dir=${${GIT_DIR:A}:-$_p9k_pwd_a} local -F timeout=_POWERLEVEL9K_VCS_MAX_SYNC_LATENCY_SECONDS if ! _p9k_vcs_status_for_dir $dir; then gitstatus_query -d $dir -t $timeout -p -c '_p9k_vcs_resume 0' POWERLEVEL9K || return 1 case $VCS_STATUS_RESULT in - tout) _p9k_next_vcs_dir=''; _p9k_gitstatus_start_time=$EPOCHREALTIME; return 0;; + tout) _p9k_gitstatus_next_dir=''; _p9k_gitstatus_start_time=$EPOCHREALTIME; return 0;; norepo-sync) return 0;; ok-sync) _p9k_vcs_status_save;; esac @@ -2733,14 +2815,15 @@ function _p9k_vcs_gitstatus() { 1) timeout=0; break;; esac done - dir=${${GIT_DIR:a}:-$PWD} + dir=${${GIT_DIR:A}:-$_p9k_pwd_a} fi + (( _p9k_prompt_idx == 1 )) && timeout=0 if ! gitstatus_query -d $dir -t $timeout -c '_p9k_vcs_resume 1' POWERLEVEL9K; then unset VCS_STATUS_RESULT return 1 fi case $VCS_STATUS_RESULT in - tout) _p9k_next_vcs_dir=''; _p9k_gitstatus_start_time=$EPOCHREALTIME;; + tout) _p9k_gitstatus_next_dir=''; _p9k_gitstatus_start_time=$EPOCHREALTIME;; norepo-sync) _p9k_vcs_status_purge $dir;; ok-sync) _p9k_vcs_status_save;; esac @@ -2754,7 +2837,7 @@ function _p9k_vcs_gitstatus() { prompt_vcs() { local -a backends=($_POWERLEVEL9K_VCS_BACKENDS) - if (( ${backends[(I)git]} )) && _p9k_vcs_gitstatus; then + if (( ${backends[(I)git]} && !_p9k_gitstatus_disabled )) && _p9k_vcs_gitstatus; then _p9k_vcs_render && return backends=(${backends:#git}) fi @@ -2786,14 +2869,42 @@ prompt_vcs() { ################################################################ # Vi Mode: show editing mode (NORMAL|INSERT|VISUAL) prompt_vi_mode() { - if [[ -n $_POWERLEVEL9K_VI_INSERT_MODE_STRING ]]; then - _p9k_prompt_segment $0_INSERT "$_p9k_color1" blue '' 0 '${${KEYMAP:-0}:#(vicmd|vivis|vivli)}' "$_POWERLEVEL9K_VI_INSERT_MODE_STRING" - fi - if (( $+_POWERLEVEL9K_VI_VISUAL_MODE_STRING )); then - _p9k_prompt_segment $0_NORMAL "$_p9k_color1" white '' 0 '${(M)${:-$KEYMAP$_p9k_region_active}:#vicmd0}' "$_POWERLEVEL9K_VI_COMMAND_MODE_STRING" - _p9k_prompt_segment $0_VISUAL "$_p9k_color1" white '' 0 '${(M)${:-$KEYMAP$_p9k_region_active}:#(vicmd1|vivis?|vivli?)}' "$_POWERLEVEL9K_VI_VISUAL_MODE_STRING" + if (( __p9k_sh_glob )); then + if (( $+_POWERLEVEL9K_VI_OVERWRITE_MODE_STRING )); then + if [[ -n $_POWERLEVEL9K_VI_INSERT_MODE_STRING ]]; then + _p9k_prompt_segment $0_INSERT "$_p9k_color1" blue '' 0 '${${${${${${:-$_p9k_keymap.$_p9k_zle_state}:#vicmd.*}:#vivis.*}:#vivli.*}:#*.*overwrite*}}' "$_POWERLEVEL9K_VI_INSERT_MODE_STRING" + fi + _p9k_prompt_segment $0_OVERWRITE "$_p9k_color1" blue '' 0 '${${${${${${:-$_p9k_keymap.$_p9k_zle_state}:#vicmd.*}:#vivis.*}:#vivli.*}:#*.*insert*}}' "$_POWERLEVEL9K_VI_OVERWRITE_MODE_STRING" + else + if [[ -n $_POWERLEVEL9K_VI_INSERT_MODE_STRING ]]; then + _p9k_prompt_segment $0_INSERT "$_p9k_color1" blue '' 0 '${${${${_p9k_keymap:#vicmd}:#vivis}:#vivli}}' "$_POWERLEVEL9K_VI_INSERT_MODE_STRING" + fi + fi + + if (( $+_POWERLEVEL9K_VI_VISUAL_MODE_STRING )); then + _p9k_prompt_segment $0_NORMAL "$_p9k_color1" white '' 0 '${(M)${:-$_p9k_keymap$_p9k_region_active}:#vicmd0}' "$_POWERLEVEL9K_VI_COMMAND_MODE_STRING" + _p9k_prompt_segment $0_VISUAL "$_p9k_color1" white '' 0 '${$((! ${#${${${${:-$_p9k_keymap$_p9k_region_active}:#vicmd1}:#vivis?}:#vivli?}})):#0}' "$_POWERLEVEL9K_VI_VISUAL_MODE_STRING" + else + _p9k_prompt_segment $0_NORMAL "$_p9k_color1" white '' 0 '${$((! ${#${${${_p9k_keymap:#vicmd}:#vivis}:#vivli}})):#0}' "$_POWERLEVEL9K_VI_COMMAND_MODE_STRING" + fi else - _p9k_prompt_segment $0_NORMAL "$_p9k_color1" white '' 0 '${(M)KEYMAP:#(vicmd|vivis|vivli)}' "$_POWERLEVEL9K_VI_COMMAND_MODE_STRING" + if (( $+_POWERLEVEL9K_VI_OVERWRITE_MODE_STRING )); then + if [[ -n $_POWERLEVEL9K_VI_INSERT_MODE_STRING ]]; then + _p9k_prompt_segment $0_INSERT "$_p9k_color1" blue '' 0 '${${:-$_p9k_keymap.$_p9k_zle_state}:#(vicmd.*|vivis.*|vivli.*|*.*overwrite*)}' "$_POWERLEVEL9K_VI_INSERT_MODE_STRING" + fi + _p9k_prompt_segment $0_OVERWRITE "$_p9k_color1" blue '' 0 '${${:-$_p9k_keymap.$_p9k_zle_state}:#(vicmd.*|vivis.*|vivli.*|*.*insert*)}' "$_POWERLEVEL9K_VI_OVERWRITE_MODE_STRING" + else + if [[ -n $_POWERLEVEL9K_VI_INSERT_MODE_STRING ]]; then + _p9k_prompt_segment $0_INSERT "$_p9k_color1" blue '' 0 '${_p9k_keymap:#(vicmd|vivis|vivli)}' "$_POWERLEVEL9K_VI_INSERT_MODE_STRING" + fi + fi + + if (( $+_POWERLEVEL9K_VI_VISUAL_MODE_STRING )); then + _p9k_prompt_segment $0_NORMAL "$_p9k_color1" white '' 0 '${(M)${:-$_p9k_keymap$_p9k_region_active}:#vicmd0}' "$_POWERLEVEL9K_VI_COMMAND_MODE_STRING" + _p9k_prompt_segment $0_VISUAL "$_p9k_color1" white '' 0 '${(M)${:-$_p9k_keymap$_p9k_region_active}:#(vicmd1|vivis?|vivli?)}' "$_POWERLEVEL9K_VI_VISUAL_MODE_STRING" + else + _p9k_prompt_segment $0_NORMAL "$_p9k_color1" white '' 0 '${(M)_p9k_keymap:#(vicmd|vivis|vivli)}' "$_POWERLEVEL9K_VI_COMMAND_MODE_STRING" + fi fi } @@ -2814,7 +2925,7 @@ prompt_virtualenv() { function _p9k_read_pyenv_version_file() { [[ -r $1 ]] || return local content - read -rd $'\0' content <$1 2>/dev/null + IFS='' read -rd $'\0' content <$1 2>/dev/null _p9k_ret=${${(j.:.)${(@)${=content}#python-}:-system}} } @@ -2826,10 +2937,10 @@ function _p9k_pyenv_global_version() { # Segment to display pyenv information # https://github.com/pyenv/pyenv#choosing-the-python-version prompt_pyenv() { - (( $+commands[pyenv] )) || return + (( $+commands[pyenv] || $+functions[pyenv] )) || return local v=${(j.:.)${(@)${(s.:.)PYENV_VERSION}#python-}} if [[ -z $v ]]; then - [[ $PYENV_DIR == /* ]] && local dir=$PYENV_DIR || local dir="$PWD/$PYENV_DIR" + [[ $PYENV_DIR == /* ]] && local dir=$PYENV_DIR || local dir="$_p9k_pwd_a/$PYENV_DIR" while true; do if _p9k_read_pyenv_version_file $dir/.python-version; then v=$_p9k_ret @@ -2876,7 +2987,7 @@ prompt_swift_version() { ################################################################ # dir_writable: Display information about the user's permission to write in the current directory prompt_dir_writable() { - if [[ ! -w "$PWD" ]]; then + if [[ ! -w "$_p9k_pwd" ]]; then _p9k_prompt_segment "$0_FORBIDDEN" "red" "yellow1" 'LOCK_ICON' 0 '' '' fi } @@ -2886,15 +2997,7 @@ prompt_dir_writable() { prompt_kubecontext() { (( $+commands[kubectl] )) || return - local cfg - local -a key - for cfg in ${(s.:.)${KUBECONFIG:-$HOME/.kube/config}}; do - local -H stat - zstat -H stat -- $cfg 2>/dev/null || continue - key+=($cfg $stat[inode] $stat[mtime] $stat[size] $stat[mode]) - done - - if ! _p9k_cache_get $0 "${key[@]}"; then + if ! _p9k_cache_stat_get $0 ${(s.:.)${KUBECONFIG:-$HOME/.kube/config}}; then local name namespace cluster cloud_name cloud_account cloud_zone cloud_cluster text state () { local cfg && cfg=(${(f)"$(kubectl config view -o=yaml 2>/dev/null)"}) || return @@ -2954,7 +3057,7 @@ prompt_kubecontext() { fi done fi - _p9k_cache_set "$name" "$namespace" "$cluster" "$cloud_name" "$cloud_account" "$cloud_zone" "$cloud_cluster" "$text" "$state" + _p9k_cache_stat_set "$name" "$namespace" "$cluster" "$cloud_name" "$cloud_account" "$cloud_zone" "$cloud_cluster" "$text" "$state" fi typeset -g P9K_KUBECONTEXT_NAME=$_p9k_cache_val[1] @@ -2996,8 +3099,25 @@ prompt_java_version() { _p9k_prompt_segment "$0" "red" "white" "JAVA_ICON" 0 '' "${v//\%/%%}" } +prompt_azure() { + (( $+commands[az] )) || return + local cfg=${AZURE_CONFIG_DIR:-$HOME/.azure}/azureProfile.json + if ! _p9k_cache_stat_get $0 $cfg; then + local name + if (( $+commands[jq] )) && name="$(jq -r '[.subscriptions[]|select(.isDefault==true)|.name][]|strings' $cfg 2>/dev/null)"; then + name=${name%%$'\n'*} + elif ! name="$(az account show --query name --output tsv 2>/dev/null)"; then + name= + fi + _p9k_cache_stat_set "$name" + fi + [[ -n $_p9k_cache_val[1] ]] || return + _p9k_prompt_segment "$0" "blue" "white" "AZURE_ICON" 0 '' "${_p9k_cache_val[1]//\%/%%}" +} + typeset -gra __p9k_nordvpn_tag=( P9K_NORDVPN_STATUS + P9K_NORDVPN_TECHNOLOGY P9K_NORDVPN_PROTOCOL P9K_NORDVPN_IP_ADDRESS P9K_NORDVPN_SERVER @@ -3017,12 +3137,11 @@ function _p9k_fetch_nordvpn_status() { IFS='' read -t 0.25 -r tag <&3 tag=$'\015' while true; do - tag=${__p9k_char2byte[${(q+)tag}]:-0} + tag=$((#tag)) (( (tag >>= 3) && tag <= $#__p9k_nordvpn_tag )) || break tag=$__p9k_nordvpn_tag[tag] sysread -c n -s 1 -t 0.25 len <&3 - len=${__p9k_char2byte[${(q+)len}]} - [[ -n $len ]] + len=$((#len)) val= (( ! len )) || { sysread -c n -s $len -t 0.25 val <&3 @@ -3052,6 +3171,7 @@ function _p9k_fetch_nordvpn_status() { # # - P9K_NORDVPN_STATUS # - P9K_NORDVPN_PROTOCOL +# - P9K_NORDVPN_TECHNOLOGY # - P9K_NORDVPN_IP_ADDRESS # - P9K_NORDVPN_SERVER # - P9K_NORDVPN_COUNTRY @@ -3096,6 +3216,34 @@ function prompt_nordvpn() { esac } +function prompt_ranger() { + [[ -n $RANGER_LEVEL ]] || return + _p9k_prompt_segment $0 $_p9k_color1 yellow RANGER_ICON 0 '' $RANGER_LEVEL +} + +function prompt_terraform() { + (( $+commands[terraform] )) || return + local ws=default + if [[ -n $TF_WORKSPACE ]]; then + ws=$TF_WORKSPACE + else + local f=${TF_DATA_DIR:-.terraform}/environment + [[ -r $f ]] && _p9k_read_file $f && ws=$_p9k_ret + fi + ws=${${ws##[[:space:]]#}%%[[:space:]]#} + [[ $ws == default ]] || _p9k_prompt_segment $0 $_p9k_color1 blue TERRAFORM_ICON 0 '' $ws +} + +function prompt_proxy() { + local -U p=( + $all_proxy $http_proxy $https_proxy $ftp_proxy + $ALL_PROXY $HTTP_PROXY $HTTPS_PROXY $FTP_PROXY) + p=(${(@)${(@)${(@)p#*://}##*@}%%/*}) + (( $#p )) || return + (( $#p == 1 )) || p=("") + _p9k_prompt_segment $0 $_p9k_color1 blue PROXY_ICON 0 '' "$p[1]" +} + _p9k_preexec() { if (( $+_p9k_real_zle_rprompt_indent )); then if [[ -n $_p9k_real_zle_rprompt_indent ]]; then @@ -3109,6 +3257,21 @@ _p9k_preexec() { _p9k_timer_start=EPOCHREALTIME } +function _p9k_set_iface() { + _p9k_iface=() + [[ -x /sbin/ifconfig ]] || return + local line + local iface + for line in ${(f)"$(/sbin/ifconfig 2>/dev/null)"}; do + if [[ $line == (#b)([^[:space:]]##):[[:space:]]##flags=(<->)'<'* ]]; then + [[ $match[2] == *[13579] ]] && iface=$match[1] || iface= + elif [[ -n $iface && $line == (#b)[[:space:]]##inet[[:space:]]##([0-9.]##)* ]]; then + _p9k_iface[$iface]=$match[1] + iface= + fi + done +} + function _p9k_build_segment() { _p9k_segment_name=${_p9k_segment_name%_joined} if [[ $_p9k_segment_name == custom_* ]]; then @@ -3120,9 +3283,15 @@ function _p9k_build_segment() { } function _p9k_set_prompt() { + local ifs=$IFS + IFS=$' \t\n\0' + _p9k_pwd=${(%):-%/} + _p9k_pwd_a=${_p9k_pwd:A} PROMPT=$_p9k_prompt_prefix_left RPROMPT= + (( _p9k_fetch_iface )) && _p9k_set_iface + local -i left_idx=1 right_idx=1 num_lines=$#_p9k_line_segments_left i for i in {1..$num_lines}; do local right= @@ -3162,7 +3331,7 @@ function _p9k_set_prompt() { PROMPT+='${${_p9k_g::=0}+}' fi if [[ $_POWERLEVEL9K_DIR_MAX_LENGTH == <->('%'|) ]]; then - local lim + local lim= if [[ $_POWERLEVEL9K_DIR_MAX_LENGTH[-1] == '%' ]]; then lim="$_p9k_dir_len-$((0.01*$_POWERLEVEL9K_DIR_MAX_LENGTH[1,-2]))*_p9k_clm" else @@ -3198,17 +3367,19 @@ function _p9k_set_prompt() { _p9k_prompt_side= (( $#_p9k_cache < _POWERLEVEL9K_MAX_CACHE_SIZE )) || _p9k_cache=() + IFS=$ifs } function _p9k_update_prompt() { _p9k_refresh_reason=$1 _p9k_set_prompt _p9k_refresh_reason='' - zle && zle .reset-prompt && zle -R + _p9k_reset_prompt } powerlevel9k_refresh_prompt_inplace() { - emulate -L zsh && setopt no_hist_expand extended_glob + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} (( __p9k_enabled )) || return _p9k_refresh_reason=precmd _p9k_set_prompt @@ -3217,11 +3388,12 @@ powerlevel9k_refresh_prompt_inplace() { p9k_refresh_prompt_inplace() { powerlevel9k_refresh_prompt_inplace } +typeset -gi __p9k_sh_glob +typeset -gi __p9k_ksh_arrays typeset -gi __p9k_new_status typeset -ga __p9k_new_pipestatus _p9k_save_status() { - emulate -L zsh && setopt no_hist_expand extended_glob local -i pipe if (( !$+_p9k_line_finished )); then : # SIGINT @@ -3265,51 +3437,157 @@ _p9k_save_status() { fi } -_p9k_precmd() { - __p9k_new_status=$? - __p9k_new_pipestatus=($pipestatus) +function _p9k_dump_state() { + is-at-least 5.4 || return # `typeset -g` doesn't roundtrip in zsh prior to 5.4. + local dir=${__p9k_dump_file:h} + [[ -d $dir ]] || mkdir -pm 0700 $dir || return + [[ -w $dir ]] || return + local tmp=$__p9k_dump_file.$$-$EPOCHREALTIME-$RANDOM + local -i fd + sysopen -a -m 600 -o creat,trunc -u fd $tmp || return + { + local include='_POWERLEVEL9K_*|_p9k_*|icons|OS|DEFAULT_COLOR|DEFAULT_COLOR_INVERTED' + local exclude='_p9k_gitstatus_*|_p9k_cache_stat_meta|_p9k_cache_stat_fprint|_p9k_cache_fprint_key|_p9k_param_sig|_p9k_public_ip|_p9k_prompt|_p9k_prompt_idx|_p9k_dump_pid|_p9k_dump_scheduled|_p9k_line_finished|_p9k_preexec_cmd|_p9k_status|_p9k_pipestatus|_p9k_timer_start|_p9k_region_active|_p9k_keymap|_p9k_zle_state|_p9k_async_pump_*' + typeset -g __p9k_cached_param_sig=$_p9k_param_sig + typeset -p __p9k_cached_param_sig >&$fd || return + unset __p9k_cached_param_sig + (( $+_p9k_preinit )) && { print -r -- $_p9k_preinit >&$fd || return } + print -r -- '_p9k_restore_state_impl() {' >&$fd || return + typeset -pm "($include)~($exclude)" >&$fd || return + print -r -- '}' >&$fd || return + } always { + exec {fd}>&- + } + zf_mv -f $tmp $__p9k_dump_file || return + if [[ ${(%):-%#} == % ]]; then + zcompile $__p9k_dump_file || zf_rm -f $__p9k_dump_file.zwc + fi +} - if (( $+_p9k_real_zle_rprompt_indent )); then - if [[ -n $_p9k_real_zle_rprompt_indent ]]; then - ZLE_RPROMPT_INDENT=$_p9k_real_zle_rprompt_indent - else - unset ZLE_RPROMPT_INDENT +function _p9k_restore_state() { + { + [[ $__p9k_cached_param_sig == $_p9k_param_sig ]] || return + (( $+functions[_p9k_restore_state_impl] )) || return + _p9k_restore_state_impl + _p9k_state_restored=1 + } always { + unset __p9k_cached_param_sig + if (( !_p9k_state_restored && $+functions[_p9k_preinit] )); then + unfunction _p9k_preinit + (( $+functions[gitstatus_stop] )) && gitstatus_stop POWERLEVEL9K + fi + } +} + +_p9k_precmd_impl() { + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} + + (( __p9k_enabled )) || return + + if ! zle || [[ -z $_p9k_param_sig ]]; then + if zle; then + __p9k_new_status=0 + __p9k_new_pipestatus=(0) fi - unset _p9k_real_zle_rprompt_indent - fi - if _p9k_must_init; then - if (( !__p9k_configured )); then - __p9k_configured=1 - if [[ "${parameters[(I)POWERLEVEL9K_*]}" == (POWERLEVEL9K_MODE|) ]] && _p9k_can_configure -q; then - if $__p9k_root_dir/internal/wizard.zsh -d $__p9k_root_dir; then - source $__p9k_cfg_path - _p9k_must_init + print -rn "${_p9k_prompt_newline:-}" + + if (( $+_p9k_real_zle_rprompt_indent )); then + if [[ -n $_p9k_real_zle_rprompt_indent ]]; then + ZLE_RPROMPT_INDENT=$_p9k_real_zle_rprompt_indent + else + unset ZLE_RPROMPT_INDENT + fi + unset _p9k_real_zle_rprompt_indent + fi + + if _p9k_must_init; then + if (( !__p9k_configured )); then + __p9k_configured=1 + if [[ "${parameters[(I)POWERLEVEL9K_*]}" == (POWERLEVEL9K_MODE|) ]] && _p9k_can_configure -q; then + ( + local p=("${(@)parameters[(I)AWESOME_*|CODEPOINT_*]}") + if (( $#p )); then + typeset -x -- "$p" + fi + "$__p9k_root_dir"/internal/wizard.zsh -d "$__p9k_root_dir" + ) + if (( ! $? )); then + source "$__p9k_cfg_path" + _p9k_must_init + fi fi fi + _p9k_init + fi + + if (( _p9k_timer_start )); then + typeset -gF P9K_COMMAND_DURATION_SECONDS=$((EPOCHREALTIME - _p9k_timer_start)) + else + unset P9K_COMMAND_DURATION_SECONDS + fi + _p9k_save_status + + _p9k_timer_start=0 + _p9k_region_active=0 + + unset _p9k_line_finished + unset _p9k_preexec_cmd + _p9k_keymap=main + _p9k_zle_state=insert + + if ! zle; then + (( ++_p9k_prompt_idx )) fi - _p9k_init fi - unsetopt localoptions - prompt_opts=(cr percent sp subst) - setopt nopromptbang prompt{cr,percent,sp,subst} + _p9k_refresh_reason=precmd + _p9k_set_prompt + _p9k_refresh_reason='' - _p9k_timer_end=EPOCHREALTIME - _p9k_save_status + if ! zle && { (( ! _p9k_dump_pid )) || ! kill -0 $_p9k_dump_pid 2>/dev/null }; then + _p9k_dump_pid=0 + if (( _p9k_prompt_idx == 1 && !_p9k_state_restored )); then + _p9k_dump_state + _p9k_dump_scheduled=0 + elif (( _p9k_dump_scheduled )); then + _p9k_dump_state &! + _p9k_dump_pid=$! + _p9k_dump_scheduled=0 + fi + fi +} - powerlevel9k_refresh_prompt_inplace +_p9k_precmd() { + __p9k_new_status=$? + __p9k_new_pipestatus=($pipestatus) + [[ -o ksh_arrays ]] && __p9k_ksh_arrays=1 || __p9k_ksh_arrays=0 + [[ -o sh_glob ]] && __p9k_sh_glob=1 || __p9k_sh_glob=0 - unset _p9k_line_finished - unset _p9k_preexec_cmd - _p9k_timer_start=0 - _p9k_region_active=0 + unsetopt localoptions + prompt_opts=(percent subst) + [[ ! -o prompt_sp ]] || prompt_opts+=sp + [[ ! -o prompt_cr ]] || prompt_opts+=cr + setopt nopromptbang prompt_percent prompt_subst + + _p9k_precmd_impl } -function _p9k_zle_keymap_select() { +function _p9k_reset_prompt() { + (( __p9k_ksh_arrays )) && setopt ksh_arrays + (( __p9k_sh_glob )) && setopt sh_glob zle && zle .reset-prompt && zle -R } +function _p9k_zle_keymap_select() { + _p9k_reset_prompt +} + +function _p9k_zle_state_changed() { + _p9k_reset_prompt +} + _p9k_deinit_async_pump() { if (( _p9k_async_pump_lock_fd )); then zsystem flock -u $_p9k_async_pump_lock_fd @@ -3332,12 +3610,18 @@ _p9k_deinit_async_pump() { rm -f $_p9k_async_pump_lock _p9k_async_pump_lock='' fi + _p9k_async_pump_subshell=-1 + _p9k_async_pump_shell_pid=-1 add-zsh-hook -D zshexit _p9k_kill_async_pump } function _p9k_on_async_message() { - emulate -L zsh && setopt no_hist_expand extended_glob - (( ARGC == 1 )) || return + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} + if (( ARGC != 1 )); then + _p9k_deinit_async_pump + return + fi local msg='' IFS='' while read -r -t -u $1 msg; do [[ $__p9k_enabled == 1 && $1 == $_p9k_async_pump_fd ]] && eval $_p9k_async_pump_line$msg @@ -3345,12 +3629,13 @@ function _p9k_on_async_message() { msg= done _p9k_async_pump_line+=$msg - [[ $__p9k_enabled == 1 && $1 == $_p9k_async_pump_fd ]] && zle && zle .reset-prompt && zle -R + [[ $__p9k_enabled == 1 && $1 == $_p9k_async_pump_fd ]] && _p9k_reset_prompt } function _p9k_async_pump() { emulate -L zsh || return - setopt noaliases no_hist_expand extended_glob || return + setopt no_aliases no_hist_expand extended_glob || return + setopt no_prompt_bang prompt_{percent,subst} || return zmodload zsh/system zsh/datetime || return echo $$ || return @@ -3411,8 +3696,9 @@ function _p9k_async_pump() { } function _p9k_kill_async_pump() { - emulate -L zsh && setopt no_hist_expand extended_glob - if (( ZSH_SUBSHELL == _p9k_async_pump_subshell )); then + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} + if [[ $ZSH_SUBSHELL == $_p9k_async_pump_subshell && $$ == $_p9k_async_pump_shell_pid ]]; then _p9k_deinit_async_pump fi } @@ -3426,8 +3712,9 @@ _p9k_init_async_pump() { _p9k_start_async_pump() { setopt err_return no_bg_nice - _p9k_async_pump_lock="$(mktemp ${TMPDIR:-/tmp}/p9k-$$-async-pump-lock.XXXXXXXXXX)" - _p9k_async_pump_fifo="$(mktemp -u ${TMPDIR:-/tmp}/p9k-$$-async-pump-fifo.XXXXXXXXXX)" + _p9k_async_pump_lock=${TMPDIR:-/tmp}/p9k-$$-async-pump-lock.$EPOCHREALTIME.$RANDOM + _p9k_async_pump_fifo=${TMPDIR:-/tmp}/p9k-$$-async-pump-fifo.$EPOCHREALTIME.$RANDOM + echo -n >$_p9k_async_pump_lock mkfifo $_p9k_async_pump_fifo sysopen -rw -o cloexec,sync -u _p9k_async_pump_fd $_p9k_async_pump_fifo zle -F $_p9k_async_pump_fd _p9k_on_async_message @@ -3447,16 +3734,17 @@ _p9k_init_async_pump() { cmd="$setsid zsh -dfxc ${(q)cmd} &!" zsh -dfmxc $cmd &$_p9k_async_pump_fd 2>/dev/null &! - read -t 5 -r -u $_p9k_async_pump_fd _p9k_async_pump_pid && (( _p9k_async_pump_pid )) + IFS='' read -t 5 -r -u $_p9k_async_pump_fd _p9k_async_pump_pid && (( _p9k_async_pump_pid )) _p9k_async_pump_subshell=$ZSH_SUBSHELL + _p9k_async_pump_shell_pid=$$ add-zsh-hook zshexit _p9k_kill_async_pump } if ! _p9k_start_async_pump ; then - >&2 print -P "%F{red}[ERROR]%f Powerlevel10k failed to start async worker. The following segments may malfunction: " - (( public_ip )) && >&2 print -P " - %F{green}public_ip%f" - (( time_realtime )) && >&2 print -P " - %F{green}time%f" + >&2 print -rP -- "%F{red}[ERROR]%f Powerlevel10k failed to start async worker. The following segments may malfunction: " + (( public_ip )) && >&2 print -rP -- " - %F{green}public_ip%f" + (( time_realtime )) && >&2 print -rP -- " - %F{green}time%f" _p9k_deinit_async_pump fi } @@ -3478,15 +3766,21 @@ function _p9k_prompt_overflow_bug() { } _p9k_init_vars() { + typeset -gi _p9k_dump_scheduled + typeset -gi _p9k_dump_pid + typeset -gi _p9k_prompt_idx + typeset -gi _p9k_state_restored typeset -gi _p9k_reset_on_line_finish typeset -gF _p9k_timer_start - typeset -gF _p9k_timer_end typeset -gi _p9k_status typeset -ga _p9k_pipestatus typeset -g _p9k_param_sig typeset -g _p9k_ret typeset -g _p9k_cache_key typeset -ga _p9k_cache_val + typeset -g _p9k_cache_stat_meta + typeset -g _p9k_cache_stat_fprint + typeset -g _p9k_cache_fprint_key typeset -gA _p9k_cache typeset -ga _p9k_t typeset -g _p9k_n @@ -3496,10 +3790,11 @@ _p9k_init_vars() { typeset -ga _p9k_right_join typeset -g _p9k_public_ip typeset -g _p9k_todo_file - # git workdir => the last prompt we've shown for it - typeset -gA _p9k_last_git_prompt # git workdir => 1 if gitstatus is slow on it, 0 if it's fast. typeset -gA _p9k_git_slow + # git workdir => the last state we've seen for it + typeset -gA _p9k_gitstatus_last + typeset -gi _p9k_gitstatus_disabled typeset -gF _p9k_gitstatus_start_time typeset -g _p9k_prompt typeset -g _p9k_rprompt @@ -3516,6 +3811,7 @@ _p9k_init_vars() { typeset -gi _p9k_async_pump_fd typeset -gi _p9k_async_pump_pid typeset -gi _p9k_async_pump_subshell + typeset -gi _p9k_async_pump_shell_pid typeset -ga _p9k_line_segments_left typeset -ga _p9k_line_segments_right typeset -ga _p9k_line_prefix_left @@ -3534,6 +3830,7 @@ _p9k_init_vars() { typeset -gi _p9k_g typeset -gi _p9k_ind typeset -g _p9k_gap_pre + typeset -g _p9k_prompt_newline typeset -g _p9k_prompt_prefix_left typeset -g _p9k_prompt_prefix_right typeset -g _p9k_prompt_suffix_left @@ -3553,8 +3850,16 @@ _p9k_init_vars() { typeset -g _p9k_w typeset -gi _p9k_dir_len typeset -gi _p9k_num_cpus + typeset -g _p9k_pwd + typeset -g _p9k_pwd_a + typeset -gA _p9k_iface + typeset -gi _p9k_fetch_iface + typeset -g _p9k_keymap + typeset -g _p9k_zle_state + typeset -g _p9k_uname + typeset -g _p9k_uname_o + typeset -g _p9k_uname_m - typeset -gF P9K_COMMAND_DURATION_SECONDS typeset -g P9K_VISUAL_IDENTIFIER typeset -g P9K_CONTENT typeset -g P9K_GAP @@ -3575,7 +3880,8 @@ _p9k_init_params() { _p9k_declare -i POWERLEVEL9K_VCS_SHORTEN_LENGTH _p9k_declare -i POWERLEVEL9K_VCS_SHORTEN_MIN_LENGTH _p9k_declare -s POWERLEVEL9K_VCS_SHORTEN_STRATEGY - _p9k_declare -s POWERLEVEL9K_VCS_SHORTEN_DELIMITER + _p9k_declare -e POWERLEVEL9K_VCS_SHORTEN_DELIMITER '\u2026' + _p9k_declare -b POWERLEVEL9K_VCS_CONFLICTED_STATE 0 _p9k_declare -b POWERLEVEL9K_HIDE_BRANCH_ICON 0 _p9k_declare -b POWERLEVEL9K_VCS_HIDE_TAGS 0 _p9k_declare -i POWERLEVEL9K_CHANGESET_HASH_LENGTH 8 @@ -3594,10 +3900,12 @@ _p9k_init_params() { _p9k_declare -i POWERLEVEL9K_BATTERY_LOW_THRESHOLD 10 _p9k_declare -i POWERLEVEL9K_BATTERY_HIDE_ABOVE_THRESHOLD 999 _p9k_declare -a POWERLEVEL9K_BATTERY_LEVEL_BACKGROUND -- + _p9k_declare -a POWERLEVEL9K_BATTERY_LEVEL_FOREGROUND -- _p9k_declare -b POWERLEVEL9K_BATTERY_VERBOSE 1 if [[ $parameters[POWERLEVEL9K_BATTERY_STAGES] == scalar ]]; then _p9k_declare -e POWERLEVEL9K_BATTERY_STAGES else + [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale _p9k_declare -a POWERLEVEL9K_BATTERY_STAGES -- _POWERLEVEL9K_BATTERY_STAGES=("${(@g::)_POWERLEVEL9K_BATTERY_STAGES}") fi @@ -3618,7 +3926,7 @@ _p9k_init_params() { _p9k_declare -e POWERLEVEL9K_DIR_PATH_SEPARATOR "/" _p9k_declare -e POWERLEVEL9K_HOME_FOLDER_ABBREVIATION "~" _p9k_declare -b POWERLEVEL9K_DIR_PATH_HIGHLIGHT_BOLD 0 - _p9k_declare -b POWERLEVEL9K_DIR_ANCHORS_BOLD 0 + _p9k_declare -b POWERLEVEL9K_DIR_ANCHOR_BOLD 0 _p9k_declare -b POWERLEVEL9K_DIR_PATH_ABSOLUTE 0 _p9k_declare -b POWERLEVEL9K_DIR_SHOW_WRITABLE 0 _p9k_declare -b POWERLEVEL9K_DIR_OMIT_FIRST_CHARACTER 0 @@ -3628,7 +3936,24 @@ _p9k_init_params() { _p9k_declare -s POWERLEVEL9K_DIR_PATH_HIGHLIGHT_FOREGROUND _p9k_declare -s POWERLEVEL9K_DIR_ANCHOR_FOREGROUND _p9k_declare -s POWERLEVEL9K_DIR_SHORTENED_FOREGROUND - _p9k_declare -s POWERLEVEL9K_SHORTEN_FOLDER_MARKER "(.shorten_folder_marker|.bzr|CVS|.git|.hg|.svn|.terraform|.citc)" + local markers=( + .bzr + .citc + .git + .hg + .node-version + .python-version + .ruby-version + .shorten_folder_marker + .svn + .terraform + CVS + Cargo.toml + composer.json + go.mod + package.json + ) + _p9k_declare -s POWERLEVEL9K_SHORTEN_FOLDER_MARKER "(${(j:|:)markers})" # Shorten directory if it's longer than this even if there is space for it. # The value can be either absolute (e.g., '80') or a percentage of terminal # width (e.g, '50%'). If empty, directory will be shortened only when prompt @@ -3678,12 +4003,17 @@ _p9k_init_params() { _p9k_declare -i POWERLEVEL9K_SHORTEN_DELIMITER_LENGTH _p9k_declare -e POWERLEVEL9K_SHORTEN_DELIMITER _p9k_declare -i POWERLEVEL9K_SHORTEN_DIR_LENGTH - _p9k_declare -s POWERLEVEL9K_IP_INTERFACE "^[^ ]+" - _p9k_declare -s POWERLEVEL9K_VPN_IP_INTERFACE "tun" + _p9k_declare -s POWERLEVEL9K_IP_INTERFACE "" + _p9k_declare -s POWERLEVEL9K_VPN_IP_INTERFACE "(wg|(.*tun))[0-9]*" _p9k_declare -i POWERLEVEL9K_LOAD_WHICH 5 _p9k_declare -b POWERLEVEL9K_NODENV_PROMPT_ALWAYS_SHOW 0 _p9k_declare -b POWERLEVEL9K_NODE_VERSION_PROJECT_ONLY 0 + _p9k_declare -b POWERLEVEL9K_DOTNET_VERSION_PROJECT_ONLY 1 + _p9k_declare -b POWERLEVEL9K_GO_VERSION_PROJECT_ONLY 1 + _p9k_declare -b POWERLEVEL9K_RUST_VERSION_PROJECT_ONLY 1 _p9k_declare -b POWERLEVEL9K_RBENV_PROMPT_ALWAYS_SHOW 0 + _p9k_declare -b POWERLEVEL9K_RVM_SHOW_GEMSET 0 + _p9k_declare -b POWERLEVEL9K_RVM_SHOW_PREFIX 0 _p9k_declare -b POWERLEVEL9K_CHRUBY_SHOW_VERSION 1 _p9k_declare -b POWERLEVEL9K_CHRUBY_SHOW_ENGINE 1 _p9k_declare -b POWERLEVEL9K_STATUS_CROSS 0 @@ -3722,6 +4052,7 @@ _p9k_init_params() { _p9k_declare -i POWERLEVEL9K_VCS_STAGED_MAX_NUM 1 _p9k_declare -i POWERLEVEL9K_VCS_UNSTAGED_MAX_NUM 1 _p9k_declare -i POWERLEVEL9K_VCS_UNTRACKED_MAX_NUM 1 + _p9k_declare -i POWERLEVEL9K_VCS_CONFLICTED_MAX_NUM 1 _p9k_declare -i POWERLEVEL9K_VCS_COMMITS_AHEAD_MAX_NUM -1 _p9k_declare -i POWERLEVEL9K_VCS_COMMITS_BEHIND_MAX_NUM -1 _p9k_declare -b POWERLEVEL9K_DISABLE_GITSTATUS 0 @@ -3729,6 +4060,8 @@ _p9k_init_params() { _p9k_declare -e POWERLEVEL9K_VI_COMMAND_MODE_STRING "NORMAL" # VISUAL mode is shown as NORMAL unless POWERLEVEL9K_VI_VISUAL_MODE_STRING is explicitly set. _p9k_declare -e POWERLEVEL9K_VI_VISUAL_MODE_STRING + # OVERWRITE mode is shown as INSERT unless POWERLEVEL9K_VI_OVERWRITE_MODE_STRING is explicitly set. + _p9k_declare -e POWERLEVEL9K_VI_OVERWRITE_MODE_STRING _p9k_declare -b POWERLEVEL9K_VIRTUALENV_SHOW_PYTHON_VERSION 1 _p9k_declare -e POWERLEVEL9K_VIRTUALENV_LEFT_DELIMITER "(" _p9k_declare -e POWERLEVEL9K_VIRTUALENV_RIGHT_DELIMITER ")" @@ -3769,6 +4102,31 @@ _p9k_init_params() { # # These correspond to `java -fullversion` and `java -version` respectively. _p9k_declare -b POWERLEVEL9K_JAVA_VERSION_FULL 1 + _p9k_declare -b POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE 0 + + local -i i=1 + while (( i <= $#_POWERLEVEL9K_LEFT_PROMPT_ELEMENTS )); do + local segment=${(U)_POWERLEVEL9K_LEFT_PROMPT_ELEMENTS[i]} + local var=POWERLEVEL9K_${segment}_LEFT_DISABLED + (( $+parameters[$var] )) || var=POWERLEVEL9K_${segment}_DISABLED + if [[ ${(P)var} == true ]]; then + _POWERLEVEL9K_LEFT_PROMPT_ELEMENTS[i,i]=() + else + (( ++i )) + fi + done + + local -i i=1 + while (( i <= $#_POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS )); do + local segment=${(U)_POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS[i]} + local var=POWERLEVEL9K_${segment}_RIGHT_DISABLED + (( $+parameters[$var] )) || var=POWERLEVEL9K_${segment}_DISABLED + if [[ ${(P)var} == true ]]; then + _POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS[i,i]=() + else + (( ++i )) + fi + done } typeset -ga __p9k_wrapped_zle_widgets @@ -3792,7 +4150,9 @@ _p9k_wrap_zle_widget() { local wrapper=_p9k_wrapper_$widget_$hook eval "function ${(q)wrapper}() { - ${(q)hook} \"\$@\" + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} + (( __p9k_enabled )) && ${(q)hook} \"\$@\" (( \$+widgets[${(q)orig}] )) && zle ${(q)orig} -- \"\$@\" }" @@ -3800,18 +4160,18 @@ _p9k_wrap_zle_widget() { } function _p9k_zle_line_finish() { - (( __p9k_enabled )) || return _p9k_line_finished= - (( _p9k_reset_on_line_finish )) && zle && zle .reset-prompt && zle -R + if (( _p9k_reset_on_line_finish )); then + _p9k_reset_prompt + fi } function _p9k_zle_line_pre_redraw() { - (( __p9k_enabled )) || return [[ ${KEYMAP:-} == vicmd ]] || return 0 local region=${${REGION_ACTIVE:-0}/2/1} [[ $region != $_p9k_region_active ]] || return 0 _p9k_region_active=$region - zle && zle .reset-prompt && zle -R + _p9k_reset_prompt } prompt__p9k_internal_nothing() { @@ -3824,8 +4184,8 @@ _p9k_build_gap_post() { local char=${_p9k_ret:- } _p9k_prompt_length $char if (( _p9k_ret != 1 || $#char != 1 )); then - print -P "%F{red}WARNING!%f %BMULTILINE_${(U)1}_PROMPT_GAP_CHAR%b is not one character long. Will use ' '." - print -P "Either change the value of %BPOWERLEVEL9K_MULTILINE_${(U)1}_PROMPT_GAP_CHAR%b or remove it." + print -rP -- "%F{red}WARNING!%f %BMULTILINE_${(U)1}_PROMPT_GAP_CHAR%b is not one character long. Will use ' '." + print -rP -- "Either change the value of %BPOWERLEVEL9K_MULTILINE_${(U)1}_PROMPT_GAP_CHAR%b or remove it." char=' ' fi local style @@ -3846,11 +4206,16 @@ _p9k_build_gap_post() { _p9k_ret+='${:-"'$exp'"}' style=1 fi - _p9k_ret+=$'$_p9k_rprompt$_p9k_t[$((1+!_p9k_ind))]}:-\n}' + if (( __p9k_ksh_arrays )); then + _p9k_ret+=$'$_p9k_rprompt${_p9k_t[$((!_p9k_ind))]}}:-\n}' + else + _p9k_ret+=$'$_p9k_rprompt${_p9k_t[$((1+!_p9k_ind))]}}:-\n}' + fi [[ -n $style ]] && _p9k_ret+='%b%k%f' } _p9k_init_lines() { + [[ -z $_p9k_locale ]] || local LC_ALL=$_p9k_locale local -a left_segments=($_POWERLEVEL9K_LEFT_PROMPT_ELEMENTS) local -a right_segments=($_POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS) @@ -3963,6 +4328,13 @@ _p9k_init_lines() { fi } +_p9k_all_params_eq() { + local key + for key in ${parameters[(I)${~1}]}; do + [[ ${(P)key} == $2 ]] || return + done +} + _p9k_init_prompt() { _p9k_init_lines @@ -3981,15 +4353,24 @@ _p9k_init_prompt() { _p9k_prompt_suffix_left='${${COLUMNS::=$_p9k_clm}+}' _p9k_prompt_suffix_right='${${COLUMNS::=$_p9k_clm}+}' + if _p9k_segment_in_use vi_mode || _p9k_segment_in_use prompt_char; then + _p9k_prompt_prefix_left+='${${_p9k_keymap::=${KEYMAP:-$_p9k_keymap}}+}' + fi + if { _p9k_segment_in_use vi_mode && (( $+_POWERLEVEL9K_VI_OVERWRITE_MODE_STRING )) } || + { _p9k_segment_in_use prompt_char && (( _POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE )) }; then + _p9k_prompt_prefix_left+='${${_p9k_zle_state::=${ZLE_STATE:-$_p9k_zle_state}}+}' + fi _p9k_prompt_prefix_left+='%b%k%f' # Bug fixed in: https://github.com/zsh-users/zsh/commit/3eea35d0853bddae13fa6f122669935a01618bf9. # If affects most terminals when RPROMPT is non-empty and ZLE_RPROMPT_INDENT is zero. # We can work around it as long as RPROMPT ends with a space. if [[ -n $_p9k_line_segments_right[-1] && $_p9k_line_never_empty_right[-1] == 0 && - $ZLE_RPROMPT_INDENT == 0 && ${POWERLEVEL9K_WHITESPACE_BETWEEN_RIGHT_SEGMENTS:- } == ' ' && - -z "$(typeset -m 'POWERLEVEL9K_*(RIGHT_RIGHT_WHITESPACE|RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL)')" ]] && - ! is-at-least 5.7.2; then + $ZLE_RPROMPT_INDENT == 0 ]] && + _p9k_all_params_eq 'POWERLEVEL9K_*WHITESPACE_BETWEEN_RIGHT_SEGMENTS' ' ' && + _p9k_all_params_eq 'POWERLEVEL9K_*RIGHT_RIGHT_WHITESPACE' ' ' && + _p9k_all_params_eq 'POWERLEVEL9K_*RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL' '' && + ! is-at-least 5.7.2; then _p9k_emulate_zero_rprompt_indent=1 _p9k_prompt_prefix_left+='${${:-${_p9k_real_zle_rprompt_indent:=$ZLE_RPROMPT_INDENT}${ZLE_RPROMPT_INDENT::=1}${_p9k_ind::=0}}+}' _p9k_line_suffix_right[-1]='${_p9k_sss:+${_p9k_sss% }%E}' @@ -3999,7 +4380,7 @@ _p9k_init_prompt() { fi if (( _POWERLEVEL9K_PROMPT_ADD_NEWLINE )); then - repeat $_POWERLEVEL9K_PROMPT_ADD_NEWLINE_COUNT _p9k_prompt_prefix_left+=$'\n' + repeat $_POWERLEVEL9K_PROMPT_ADD_NEWLINE_COUNT _p9k_prompt_newline+=$'\n' fi _p9k_t=($'\n' '') @@ -4019,11 +4400,15 @@ _p9k_init_prompt() { [[ $ruler_char == '.' ]] && local sep=',' || local sep='.' local ruler_len='${$((_p9k_clm-_p9k_ind))/#-*/0}' _p9k_prompt_prefix_left+="\${(pl$sep$ruler_len$sep$sep${(q)ruler_char}$sep)}%k%f" - _p9k_prompt_prefix_left+='$_p9k_t[$((1+!_p9k_ind))]' + if (( __p9k_ksh_arrays )); then + _p9k_prompt_prefix_left+='${_p9k_t[$((!_p9k_ind))]}' + else + _p9k_prompt_prefix_left+='${_p9k_t[$((1+!_p9k_ind))]}' + fi else - print -P "%F{red}WARNING!%f %BPOWERLEVEL9K_RULER_CHAR%b is not one character long. Ruler won't be rendered." - print -P "Either change the value of %BPOWERLEVEL9K_RULER_CHAR%b or set %BPOWERLEVEL9K_SHOW_RULER=false%b to" - print -P "disable ruler." + print -rP -- "%F{red}WARNING!%f %BPOWERLEVEL9K_RULER_CHAR%b is not one character long. Ruler won't be rendered." + print -rP -- "Either change the value of %BPOWERLEVEL9K_RULER_CHAR%b or set %BPOWERLEVEL9K_SHOW_RULER=false%b to" + print -rP -- "disable ruler." fi fi @@ -4034,10 +4419,6 @@ _p9k_init_prompt() { [[ -o transient_rprompt && -n "$_p9k_line_segments_right[1,-2]" ]] || ( _p9k_segment_in_use time && (( _POWERLEVEL9K_TIME_UPDATE_ON_COMMAND )) ) _p9k_reset_on_line_finish=$((!$?)) - - if (( _p9k_reset_on_line_finish )) || _p9k_segment_in_use status; then - _p9k_wrap_zle_widget zle-line-finish _p9k_zle_line_finish - fi } _p9k_init_ssh() { @@ -4046,38 +4427,42 @@ _p9k_init_ssh() { # # License: https://github.com/sindresorhus/pure/blob/e8abf9d37185ec9b7b4398ca9c5eba555a1028eb/license. - [[ -n $_P9K_SSH ]] && return - export _P9K_SSH=0 + [[ -n $P9K_SSH ]] && return + typeset -gix P9K_SSH=0 if [[ -n $SSH_CLIENT || -n $SSH_TTY || -n $SSH_CONNECTION ]]; then - _P9K_SSH=1 + P9K_SSH=1 return fi # When changing user on a remote system, the $SSH_CONNECTION environment variable can be lost. # Attempt detection via `who`. (( $+commands[who] )) || return - local w && w="$(who -m 2>/dev/null)" || w=${(@M)${(f)"$(who 2>/dev/null)"}:#*[[:space:]]${TTY#/dev/}[[:space:]]*} local ipv6='(([0-9a-fA-F]+:)|:){2,}[0-9a-fA-F]+' # Simplified, only checks partial pattern. local ipv4='([0-9]{1,3}\.){3}[0-9]+' # Simplified, allows invalid ranges. # Assume two non-consecutive periods represents a hostname. Matches `x.y.z`, but not `x.y`. local hostname='([.][^. ]+){2}' + local w + w="$(who -m 2>/dev/null)" || w=${(@M)${(f)"$(who 2>/dev/null)"}:#*[[:space:]]${TTY#/dev/}[[:space:]]*} + # Usually the remote address is surrounded by parenthesis but not on all systems (e.g., Busybox). - [[ $w =~ "\(?($ipv4|$ipv6|$hostname)\)?\$" ]] && _P9K_SSH=1 + [[ $w =~ "\(?($ipv4|$ipv6|$hostname)\)?\$" ]] && P9K_SSH=1 } _p9k_must_init() { - emulate -L zsh && setopt no_hist_expand extended_glob - local -a param_keys=( - ${(o)parameters[(I)(POWERLEVEL9K_*|GITSTATUS_LOG_LEVEL|GITSTATUS_ENABLE_LOGGING|GITSTATUS_DAEMON|GITSTATUS_NUM_THREADS|DEFAULT_USER|ZLE_RPROMPT_INDENT)]}) + local -a param_keys=(${(o)parameters[(I)POWERLEVEL9K_*]}) local IFS param_sig IFS=$'\1' param_sig="${(@)param_keys:/(#b)(*)/$match[1]=\$$match[1]}" - IFS=$'\2' eval "param_sig=x\"$param_sig\"" - [[ -o transient_rprompt ]] && param_sig+=t + param_sig+=( + '${ZSH_VERSION}' '${ZSH_PATCHLEVEL}' '${(%):-%n}' '${GITSTATUS_LOG_LEVEL}' + '${GITSTATUS_ENABLE_LOGGING}' '${GITSTATUS_DAEMON}' '${GITSTATUS_NUM_THREADS}' + '${DEFAULT_USER}' '${ZLE_RPROMPT_INDENT}' '${P9K_SSH}' '${__p9k_ksh_arrays}' + '${__p9k_sh_glob}' '${parameters[transient_rprompt]}' 'v8') + IFS=$'\2' param_sig="${(e)param_sig}" [[ $param_sig == $_p9k_param_sig ]] && return 1 [[ -n $_p9k_param_sig ]] && _p9k_deinit - _p9k_param_sig=$param_sig + typeset -g _p9k_param_sig=$param_sig } function _p9k_set_os() { @@ -4086,20 +4471,23 @@ function _p9k_set_os() { _p9k_os_icon=$_p9k_ret } -_p9k_init() { - emulate -L zsh && setopt no_hist_expand extended_glob - +function _p9k_init_cacheable() { + (( $+functions[_p9k_init_icons] )) || { + setopt no_aliases + source "${__p9k_root_dir}/internal/icons.zsh" + } _p9k_init_icons - _p9k_init_vars _p9k_init_params _p9k_init_prompt - _p9k_init_ssh - local uname="$(uname)" - if [[ $uname == Linux && "$(uname -o 2>/dev/null)" == Android ]]; then + _p9k_uname="$(uname)" + [[ $_p9k_uname == Linux ]] && _p9k_uname_o="$(uname -o 2>/dev/null)" + _p9k_uname_m="$(uname -m)" + + if [[ $_p9k_uname == Linux && _p9k_uname_o == Android ]]; then _p9k_set_os Android ANDROID_ICON else - case $uname in + case $_p9k_uname in SunOS) _p9k_set_os Solaris SUNOS_ICON;; Darwin) _p9k_set_os OSX APPLE_ICON;; CYGWIN_NT-* | MSYS_NT-*) _p9k_set_os Windows WINDOWS_ICON;; @@ -4107,9 +4495,12 @@ _p9k_init() { Linux) _p9k_os='Linux' local os_release_id - [[ -f /etc/os-release && - "${(f)$((/dev/null)}" =~ "ID=([A-Za-z]+)" ]] && os_release_id="${match[1]}" - case "$os_release_id" in + if [[ -r /etc/os-release ]]; then + local lines=(${(f)"$(&2 echo -E - "${(%):-[%1FERROR%f]: %BPowerlevel10k%b is unable to use %Bgitstatus%b. Git prompt will be slow.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):-Reason: There is no %Bgitstatusd%b binary for i686 (32-bit Intel architecture).}" + >&2 echo -E - "" + >&2 echo -E - "${(%):-You can:}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- - Do nothing.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- * You %Bwill%b see this error message every time you start zsh.}" + >&2 echo -E - "${(%):- * Git prompt will be %Bslow%b.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- - Set %BPOWERLEVEL9K_DISABLE_GITSTATUS=true%b at the bottom of %B$__p9k_zshrc_u%b.}" + >&2 echo -E - "${(%):- You can do this by running the following command:}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- %2Fecho%f %3F'POWERLEVEL9K_DISABLE_GITSTATUS=true'%f >>! $__p9k_zshrc_u}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- * You %Bwill not%b see this error message again.}" + >&2 echo -E - "${(%):- * Git prompt will be %Bslow%b.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- - Upgrade to a 64-bit OS.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- * You %Bwill not%b see this error message again.}" + >&2 echo -E - "${(%):- * Git prompt will be %Bfast%b.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- - Compile %Bgitstatusd%b and set %BGITSTATUS_DAEMON=/path/to/gitstatusd%b at}" + >&2 echo -E - "${(%):- the bottom of %B$__p9k_zshrc_u%b. See instructions at}" + >&2 echo -E - "${(%):- https://github.com/romkatv/gitstatus/blob/master/README.md#compiling.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- * You %Bwill not%b see this error message again.}" + >&2 echo -E - "${(%):- * Git prompt will be %Bfast%b.}" + return + fi + + local daemon=${GITSTATUS_DAEMON} + if [[ -z $daemon ]]; then + daemon=$gitstatus_dir/bin/gitstatusd- + [[ $_p9k_uname_o == Android ]] && daemon+=android || daemon+=${_p9k_uname:l} + daemon+=-${_p9k_uname_m:l} + fi + local -i threads=${GITSTATUS_NUM_THREADS:-0} + if (( threads <= 0 )); then + threads=$(( _p9k_num_cpus * 2 )) + (( threads > 0 )) || threads=8 + (( threads <= 32 )) || threads=32 + fi + typeset -g _p9k_preinit="function _p9k_preinit() { + [[ -r ${(q)gitstatus_dir}/gitstatus.plugin.zsh ]] || return + source ${(q)gitstatus_dir}/gitstatus.plugin.zsh || return + GITSTATUS_DAEMON=${(q)daemon} GITSTATUS_NUM_THREADS=$threads \ + GITSTATUS_LOG_LEVEL=${(q)GITSTATUS_LOG_LEVEL} \ + GITSTATUS_ENABLE_LOGGING=${(q)GITSTATUS_ENABLE_LOGGING} gitstatus_start \ + -s $_POWERLEVEL9K_VCS_STAGED_MAX_NUM \ + -u $_POWERLEVEL9K_VCS_UNSTAGED_MAX_NUM \ + -d $_POWERLEVEL9K_VCS_UNTRACKED_MAX_NUM \ + -c $_POWERLEVEL9K_VCS_CONFLICTED_MAX_NUM \ + -m $_POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY \ + -a POWERLEVEL9K + }" + source ${gitstatus_dir}/gitstatus.plugin.zsh + GITSTATUS_DAEMON=$daemon GITSTATUS_NUM_THREADS=$threads gitstatus_start \ + -s $_POWERLEVEL9K_VCS_STAGED_MAX_NUM \ + -u $_POWERLEVEL9K_VCS_UNSTAGED_MAX_NUM \ + -d $_POWERLEVEL9K_VCS_UNTRACKED_MAX_NUM \ + -c $_POWERLEVEL9K_VCS_CONFLICTED_MAX_NUM \ + -m $_POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY \ + POWERLEVEL9K || _p9k_gitstatus_disabled=1 +} + +_p9k_init() { + _p9k_init_vars + _p9k_restore_state || _p9k_init_cacheable + if _p9k_segment_in_use todo; then local todo=$commands[todo.sh] if [[ -n $todo ]]; then @@ -4235,82 +4718,47 @@ _p9k_init() { fi fi - if _p9k_segment_in_use load; then - case $_p9k_os in - OSX) (( $+commands[sysctl] )) && _p9k_num_cpus="$(sysctl -n hw.logicalcpu 2>/dev/null)";; - BSD) (( $+commands[sysctl] )) && _p9k_num_cpus="$(sysctl -n hw.ncpu 2>/dev/null)";; - *) (( $+commands[nproc] )) && _p9k_num_cpus="$(nproc 2>/dev/null)";; - esac + if (( _p9k_reset_on_line_finish )) || _p9k_segment_in_use status; then + _p9k_wrap_zle_widget zle-line-finish _p9k_zle_line_finish fi - if _p9k_segment_in_use dir; then - if (( $+_POWERLEVEL9K_DIR_CLASSES )); then - local -i i=3 - for ((; i <= $#_POWERLEVEL9K_DIR_CLASSES; i+=3)); do - _POWERLEVEL9K_DIR_CLASSES[i]=${(g::)_POWERLEVEL9K_DIR_CLASSES[i]} - done - else - typeset -ga _POWERLEVEL9K_DIR_CLASSES=() - _p9k_get_icon prompt_dir_ETC ETC_ICON - _POWERLEVEL9K_DIR_CLASSES+=('/etc|/etc/*' ETC "$_p9k_ret") - _p9k_get_icon prompt_dir_HOME HOME_ICON - _POWERLEVEL9K_DIR_CLASSES+=('~' HOME "$_p9k_ret") - _p9k_get_icon prompt_dir_HOME_SUBFOLDER HOME_SUB_ICON - _POWERLEVEL9K_DIR_CLASSES+=('~/*' HOME_SUBFOLDER "$_p9k_ret") - _p9k_get_icon prompt_dir_DEFAULT FOLDER_ICON - _POWERLEVEL9K_DIR_CLASSES+=('*' DEFAULT "$_p9k_ret") - fi + if _p9k_segment_in_use vi_mode || _p9k_segment_in_use prompt_char; then + _p9k_wrap_zle_widget zle-keymap-select _p9k_zle_keymap_select fi - _p9k_init_async_pump - if _p9k_segment_in_use vi_mode && (( $+_POWERLEVEL9K_VI_VISUAL_MODE_STRING )) || _p9k_segment_in_use prompt_char; then _p9k_wrap_zle_widget zle-line-pre-redraw _p9k_zle_line_pre_redraw fi - if _p9k_segment_in_use dir && - [[ $_POWERLEVEL9K_SHORTEN_STRATEGY == truncate_with_package_name && $+commands[jq] == 0 ]]; then - >&2 print -P '%F{yellow}WARNING!%f %BPOWERLEVEL9K_SHORTEN_STRATEGY=truncate_with_package_name%b requires %F{green}jq%f.' - >&2 print -P 'Either install %F{green}jq%f or change the value of %BPOWERLEVEL9K_SHORTEN_STRATEGY%b.' + if { _p9k_segment_in_use vi_mode && (( $+_POWERLEVEL9K_VI_OVERWRITE_MODE_STRING )) } || + { _p9k_segment_in_use prompt_char && (( _POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE )) }; then + _p9k_wrap_zle_widget overwrite-mode _p9k_zle_state_changed + _p9k_wrap_zle_widget vi-replace _p9k_zle_state_changed fi - if (( !$+__p9k_char2byte )) && _p9k_segment_in_use nordvpn; then - typeset -gA __p9k_char2byte=() - local -i x=0 y=0 - for x in {0..7}; do - for y in {0..7}; do - __p9k_char2byte[${(q+)${(g:o:):-\\$x$y}}]=$((8*x+y)) - done - done - typeset -grA __p9k_char2byte - fi - - if _p9k_segment_in_use status; then - typeset -g _p9k_exitcode2str=({0..255}) - local -i i=2 - if (( !_POWERLEVEL9K_STATUS_HIDE_SIGNAME )); then - for ((; i <= $#signals; ++i)); do - local sig=$signals[i] - (( _POWERLEVEL9K_STATUS_VERBOSE_SIGNAME )) && sig="SIG${sig}($((i-1)))" - _p9k_exitcode2str[$((128+i))]=$sig - done - fi + if _p9k_segment_in_use dir && + [[ $_POWERLEVEL9K_SHORTEN_STRATEGY == truncate_with_package_name && $+commands[jq] == 0 ]]; then + print -rP -- '%F{yellow}WARNING!%f %BPOWERLEVEL9K_SHORTEN_STRATEGY=truncate_with_package_name%b requires %F{green}jq%f.' + print -rP -- 'Either install %F{green}jq%f or change the value of %BPOWERLEVEL9K_SHORTEN_STRATEGY%b.' fi - _p9k_wrap_zle_widget zle-keymap-select _p9k_zle_keymap_select + _p9k_init_async_pump + _p9k_init_vcs } _p9k_deinit() { (( $+functions[gitstatus_stop] )) && gitstatus_stop POWERLEVEL9K _p9k_deinit_async_pump - unset -m '(_POWERLEVEL9K_|P9K_|_p9k_)*' + (( _p9k_dump_pid )) && wait $_p9k_dump_pid 2>/dev/null + unset -m '(_POWERLEVEL9K_|P9K_|_p9k_)*~P9K_SSH' } typeset -gi __p9k_enabled=0 typeset -gi __p9k_configured=0 prompt_powerlevel9k_setup() { - emulate -L zsh && setopt no_hist_expand extended_glob + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} prompt_powerlevel9k_teardown __p9k_enabled=1 add-zsh-hook preexec _p9k_preexec @@ -4318,7 +4766,8 @@ prompt_powerlevel9k_setup() { } prompt_powerlevel9k_teardown() { - emulate -L zsh && setopt no_hist_expand extended_glob + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang prompt_{percent,subst} add-zsh-hook -D precmd '(_p9k_|powerlevel9k_)*' add-zsh-hook -D preexec '(_p9k_|powerlevel9k_)*' PROMPT='%m%# ' @@ -4329,13 +4778,175 @@ prompt_powerlevel9k_teardown() { fi } -autoload -Uz colors && colors +typeset -gr __p9k_p10k_usage="Usage: %2Fp10k%f %Bcommand%b [options] + +Commands: + + %Bconfigure%b run interactive configuration wizard + %Bsegment%b print a user-defined prompt segment + %Bhelp%b print this help message" + +typeset -gr __p9k_p10k_segment_usage="Usage: %2Fp10k%f %Bsegment%b [-h] [{+|-}re] [-s state] [-b bg] [-f fg] [-i icon] [-c cond] [-t text] + +Print a user-defined prompt segment. Can be called only during prompt rendering. + +Options: + -t text segment's main content; will undergo prompt expansion: '%%F{blue}%%*%%f' will + show as %F{blue}%*%f; default is empty + -i icon segment's icon; default is empty + -r icon is a symbolic reference that needs to be resolved; for example, 'LOCK_ICON' + +r icon is already resolved and should be printed literally; for example, '⭐'; + this is the default; you can also use \$'\u2B50' if you don't want to have + non-ascii characters in source code + -b bg background color; for example, 'blue', '4', or '#0000ff'; empty value means + transparent background, as in '%%k'; default is black + -f fg foreground color; for example, 'blue', '4', or '#0000ff'; empty value means + default foreground color, as in '%%f'; default is empty + -s state segment's state for the purpose of applying styling options; if you want to + to be able to use POWERLEVEL9K parameters to specify different colors or icons + depending on some property, use different states for different values of that + property + -c condition; if empty after parameter expansion and process substitution, the + segment is hidden; this is an advanced feature, use with caution; default is '1' + -e segment's main content will undergo parameter expansion and process + substitution; the content will be surrounded with double quotes and thus + should quote its own double quotes; this is an advanced feature, use with + caution + +e segment's main content should not undergo parameter expansion and process + substitution; this is the default + -h print this help message + +Example: 'core' segment tells you if there is a file name 'core' in the current directory. + +- Segment's icon is '⭐'. +- Segment's text is the file's size in bytes. +- If you have permissions to delete the file, state is DELETABLE. If not, it's PROTECTED. + + zmodload -F zsh/stat b:zstat + + function prompt_core() { + local size=() + if ! zstat -A size +size core 2>/dev/null; then + # No 'core' file in the current directory. + return + fi + if [[ -w . ]]; then + local state=DELETABLE + else + local state=PROTECTED + fi + p10k segment -s \\\$state -i '⭐' -f blue -t \\\${size[1]}b + } + +To enable this segment, add 'core' to POWERLEVEL9K_LEFT_PROMPT_ELEMENTS or +POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS. + +Example customizations: + + # Override default foreground. + POWERLEVEL9K_CORE_FOREGROUND=red + + # Override foreground when DELETABLE. + POWERLEVEL9K_CORE_DELETABLE_BACKGROUND=green + + # Override icon when PROTECTED. + POWERLEVEL9K_CORE_PROTECTED_VISUAL_IDENTIFIER_EXPANSION='❎' + + # Don't show file size when PROTECTED. + POWERLEVEL9K_CORE_PROTECTED_CONTENT_EXPANSION=''" + +typeset -gr __p9k_p10k_configure_usage="Usage: %2Fp10k%f %Bconfigure%b + +Run interactive configuration wizard." + +function p10k() { + emulate -L zsh + setopt no_hist_expand extended_glob prompt_percent prompt_subst + + if (( !ARGC )); then + print -rP -- $__p9k_p10k_usage >&2 + return 1 + fi + + case $1 in + segment) + shift + local -i num_opts=ARGC + local opt state bg=0 fg icon cond text ref=0 expand=0 + while getopts ':s:b:f:i:c:t:reh' opt; do + case $opt in + s) state=$OPTARG;; + b) bg=$OPTARG;; + f) fg=$OPTARG;; + i) icon=$OPTARG;; + c) cond=${OPTARG:-'${:-}'};; + t) text=$OPTARG;; + r) ref=1;; + e) expand=1;; + +r) ref=0;; + +e) expand=0;; + h) print -rP -- $__p9k_p10k_segment_usage; return 0;; + ?) print -rP -- $__p9k_p10k_segment_usage >&2; return 1;; + esac + done + if (( OPTIND <= ARGC )); then + print -rP -- $__p9k_p10k_segment_usage >&2 + return 1 + fi + if [[ -z $_p9k_prompt_side ]]; then + print -rP -- "%1F[ERROR]%f %Bp10k segment%b: can be called only during prompt rendering." >&2 + if (( !ARGC )); then + print -rP -- "" + print -rP -- "For help, type:" >&2 + print -rP -- "" + print -rP -- " %2Fp10k%f %Bhelp%b %Bsegment%b" >&2 + fi + return 1 + fi + (( ref )) || icon=$'\1'$icon + "_p9k_${_p9k_prompt_side}_prompt_segment" "prompt_${_p9k_segment_name}${state:+_${(U)state}}" \ + "$bg" "${fg:-$_p9k_color1}" "$icon" "$expand" "$cond" "$text" + return 0 + ;; + configure) + if (( ARGC > 1 )); then + print -rP -- $__p9k_p10k_configure_usage >&2 + return 1 + fi + p9k_configure "$@" + ;; + help) + local var=__p9k_p10k_$2_usage + if (( $+parameters[$var] )); then + print -rP -- ${(P)var} + return 0 + elif (( ARGC == 1 )); then + print -rP -- $__p9k_p10k_usage + return 0 + else + print -rP -- $__p9k_p10k_usage >&2 + return 1 + fi + ;; + *) + print -rP -- $__p9k_p10k_usage >&2 + return 1 + ;; + esac +} + +# Hook for zplugin. +powerlevel10k_plugin_unload() { prompt_powerlevel9k_teardown; } + autoload -Uz add-zsh-hook zmodload zsh/datetime zmodload zsh/mathfunc +zmodload zsh/parameter zmodload zsh/system zmodload -F zsh/stat b:zstat zmodload -F zsh/net/socket b:zsocket +zmodload -F zsh/files b:zf_mv b:zf_rm +_p9k_init_ssh prompt_powerlevel9k_setup diff --git a/internal/wizard.zsh b/internal/wizard.zsh index 7c94934d..77b72b2f 100755 --- a/internal/wizard.zsh +++ b/internal/wizard.zsh @@ -4,7 +4,11 @@ emulate -L zsh setopt noaliases () { -setopt extended_glob no_prompt_{bang,subst} prompt_{cr,percent,sp} +setopt extended_glob no_prompt_{bang,subst} prompt_percent typeset_silent +zmodload zsh/langinfo +if [[ ${langinfo[CODESET]:-} != (utf|UTF)(-|)8 ]]; then + local LC_ALL=${${(@M)$(locale -a):#*.(utf|UTF)(-|)8}[1]:-en_US.UTF-8} +fi typeset -g __p9k_root_dir typeset -gi force=0 @@ -15,7 +19,7 @@ while getopts 'd:f' opt; do d) __p9k_root_dir=$OPTARG;; f) force=1;; +f) force=0;; - '?') return 1;; + \?) return 1;; esac done @@ -31,14 +35,21 @@ typeset -gri force source $__p9k_root_dir/internal/configure.zsh || return +typeset -r font_base_url='https://github.com/romkatv/dotfiles-public/raw/master/.local/share/fonts/NerdFonts' +typeset -ri wizard_columns=$((COLUMNS < 80 ? COLUMNS : 80)) + typeset -i prompt_indent=2 typeset -i rprompt_indent=2 -typeset -ra bg_color=(238 236 234) -typeset -ra frame_color=(242 240 238) -typeset -ra sep_color=(246 244 242) -typeset -ra prefix_color=(248 246 244) +typeset -ra bg_color=(240 238 236 234) +typeset -ra frame_color=(244 242 240 238) +typeset -ra sep_color=(248 246 244 242) +typeset -ra prefix_color=(250 248 246 244) +typeset -r left_circle='\uE0B6' +typeset -r right_circle='\uE0B4' +typeset -r left_arc='\uE0B7' +typeset -r right_arc='\uE0B5' typeset -r left_triangle='\uE0B2' typeset -r right_triangle='\uE0B0' typeset -r left_angle='\uE0B3' @@ -51,22 +62,42 @@ typeset -r vertical_bar='|' typeset -r slanted_bar='\uE0BD' typeset -ra lean_left=( - '' '%31F$extra_icons[1]%B%39F~%b%31F/%B%39Fpowerlevel10k%b%f $prefixes[1]%76F$extra_icons[2]master ⇡2%f ' + '' '${extra_icons[1]:+$extra_icons[1] }%31F$extra_icons[2]%B%39F~%b%31F/%B%39Fsrc%b%f $prefixes[1]%76F$extra_icons[3]master%f ' '' '%76F❯%f █' ) typeset -ra lean_right=( - ' $prefixes[2]%134F⎈ minikube%f' '' + ' $prefixes[2]%101F$extra_icons[4]5s%f${show_time:+ $prefixes[3]%66F$extra_icons[5]16:23:42%f}' '' '' '' ) typeset -ra classic_left=( - '%$frame_color[$color]F╭─' '%F{$bg_color[$color]}$left_tail%K{$bg_color[$color]} %31F$extra_icons[1]%B%39F~%b%K{$bg_color[$color]}%31F/%B%39Fpowerlevel10k%b%K{$bg_color[$color]} %$sep_color[$color]F$left_subsep%f %$prefix_color[$color]F$prefixes[1]%76F$extra_icons[2]master ⇡2 %k%$bg_color[$color]F$left_head%f' + '%$frame_color[$color]F╭─' '%F{$bg_color[$color]}$left_tail%K{$bg_color[$color]} ${extra_icons[1]:+$extra_icons[1]%K{$bg_color[$color]\} %$sep_color[$color]F$left_subsep%f }%31F$extra_icons[2]%B%39F~%b%K{$bg_color[$color]}%31F/%B%39Fsrc%b%K{$bg_color[$color]} %$sep_color[$color]F$left_subsep%f %$prefix_color[$color]F$prefixes[1]%76F$extra_icons[3]master %k%$bg_color[$color]F$left_head%f' '%$frame_color[$color]F╰─' '%f █' ) typeset -ra classic_right=( - '%$bg_color[$color]F$right_head%K{$bg_color[$color]}%f %$prefix_color[$color]F$prefixes[2]%134Fminikube ⎈ %k%F{$bg_color[$color]}$right_tail%f' '%$frame_color[$color]F─╮%f' + '%$bg_color[$color]F$right_head%K{$bg_color[$color]}%f %$prefix_color[$color]F$prefixes[2]%101F5s $extra_icons[4]${show_time:+%$sep_color[$color]F$right_subsep %$prefix_color[$color]F$prefixes[3]%66F16:23:42 $extra_icons[5]}%k%F{$bg_color[$color]}$right_tail%f' '%$frame_color[$color]F─╮%f' + '' '%$frame_color[$color]F─╯%f' +) + +typeset -ra pure_left=( + '' '%4F~/src%f %242Fmaster%f %3F5s%f' + '' '%5F❯%f █' +) + +typeset -ra pure_right=( + '' '' + '' '' +) + +typeset -ra rainbow_left=( + '%$frame_color[$color]F╭─' '%F{${${extra_icons[1]:+0}:-4}}$left_tail${extra_icons[1]:+%K{0\} $extra_icons[1] %K{4\}%0F$left_sep}%K{4}%254F $extra_icons[2]%B%255F~%b%K{4}%254F/%B%255Fsrc%b%K{4} %K{2}%4F$left_sep %0F$prefixes[1]$extra_icons[3]master %k%2F$left_head%f' + '%$frame_color[$color]F╰─' '%f █' +) + +typeset -ra rainbow_right=( + '%3F$right_head%K{3} %0F$prefixes[2]5s $extra_icons[4]%3F${show_time:+%7F$right_sep%K{7\} %0F$prefixes[3]16:23:42 $extra_icons[5]%7F}%k$right_tail%f' '%$frame_color[$color]F─╮%f' '' '%$frame_color[$color]F─╯%f' ) @@ -101,11 +132,16 @@ function print_prompt() { (( left_frame )) || left=('' $left[2] '' '%76F❯%f █') (( right_frame )) || right=($right[1] '' '' '') fi + local -i right_indent=rprompt_indent + local -i width=$(prompt_length ${(g::):-$left[1]$left[2]$right[1]$right[2]}) + while (( wizard_columns - width <= prompt_indent + right_indent )); do + (( --right_indent )) + done local -i i for ((i = 1; i < $#left; i+=2)); do local l=${(g::):-$left[i]$left[i+1]} local r=${(g::):-$right[i]$right[i+1]} - local -i gap=$((__p9k_wizard_columns - prompt_indent - rprompt_indent - $(prompt_length $l$r))) + local -i gap=$((wizard_columns - prompt_indent - right_indent - $(prompt_length $l$r))) (( num_lines == 2 && i == 1 )) && local fill=$gap_char || local fill=' ' print -n -- ${(pl:$prompt_indent:: :)} print -nP -- $l @@ -118,10 +154,38 @@ function href() { print -r -- $'%{\e]8;;'${1//\%/%%}$'\a%}'${1//\%/%%}$'%{\e]8;;\a%}' } -function centered() { - local n=$(prompt_length ${(g::)1}) - print -n -- ${(pl:$(((__p9k_wizard_columns - n) / 2)):: :)} - print -P -- $1 +function flowing() { + local opt + local -i centered indentation + while getopts 'ci:' opt; do + case $opt in + i) indentation=$OPTARG;; + c) centered=1;; + +c) centered=0;; + \?) exit 1;; + esac + done + shift $((OPTIND-1)) + local line word lines=() + for word in "$@"; do + local n=$(prompt_length ${(g::):-"$line $word"}) + if (( n > wizard_columns )); then + [[ -z $line ]] || lines+=$line + line= + fi + if [[ -n $line ]]; then + line+=' ' + elif (( $#lines )); then + line=${(pl:$indentation:: :)} + fi + line+=$word + done + [[ -z $line ]] || lines+=$line + for line in $lines; do + local n=$(prompt_length ${(g::)line}) + (( centered && n < wizard_columns )) && print -n -- ${(pl:$(((wizard_columns - n) / 2)):: :)} + print -P -- $line + done } function clear() { @@ -135,11 +199,15 @@ function clear() { } function quit() { - clear + if [[ $1 == '-c' ]]; then + print -P "" + else + clear + fi if (( force )); then print -P "Powerlevel10k configuration wizard has been aborted. To run it again, type:" print -P "" - print -P " %2Fp9k_configure%f" + print -P " %2Fp10k%f %Bconfigure%b" print -P "" else print -P "Powerlevel10k configuration wizard has been aborted. It will run again" @@ -151,54 +219,212 @@ function quit() { print -P "" print -P "To run Powerlevel10k configuration wizard right now, type:" print -P "" - print -P " %2Fp9k_configure%f" + print -P " %2Fp10k%f %Bconfigure%b" print -P "" fi exit 1 } -function ask_diamond() { - while true; do - clear - if (( force )); then - print -P "This is %4FPowerlevel10k configuration wizard%f. It will ask you a few" - print -P "questions and configure your prompt." +local -i greeting_printed=0 + +function print_greeting() { + (( greeting_printed )) && return + if (( force )); then + flowing -c This is %4FPowerlevel10k configuration wizard%f. \ + It will ask you a few questions and configure your prompt. + else + flowing -c This is %4FPowerlevel10k configuration wizard%f. \ + You are seeing it because you haven\'t defined any \ + Powerlevel10k configuration options. It will ask \ + you a few questions and configure your prompt. + fi + print -P "" +} + +function iterm_get() { + /usr/libexec/PlistBuddy -c "Print :$1" ~/Library/Preferences/com.googlecode.iterm2.plist +} + +local terminal iterm2_font_size + +function can_install_font() { + [[ $P9K_SSH == 0 ]] || return + if [[ "$(uname)" == Linux && "$(uname -o)" == Android ]]; then + (( $+commands[termux-reload-settings] )) || return + (( $+commands[curl] )) || return + if [[ -f ~/.termux/font.ttf ]]; then + [[ -r ~/.termux/font.ttf ]] || return + [[ -w ~/.termux/font.ttf ]] || return + ! grep -q 'MesloLGS NF' ~/.termux/font.ttf 2>/dev/null || return + fi + if [[ -f ~/.termux ]]; then + [[ -d ~/.termux && -w ~/.termux ]] || return else - print -P "This is %4FPowerlevel10k configuration wizard%f. You are seeing it because" - print -P "you haven't defined any Powerlevel10k configuration options. It will" - print -P "ask you a few questions and configure your prompt." + [[ -w ~ ]] || return fi + terminal=Termux + return + fi + if [[ "$(uname)" == Darwin && $TERM_PROGRAM == iTerm.app ]]; then + (( $+commands[curl] )) || return + [[ $TERM_PROGRAM_VERSION == [2-9]* ]] || return + if [[ -f ~/Library/Fonts ]]; then + [[ -d ~/Library/Fonts && -w ~/Library/Fonts ]] || return + else + [[ -d ~/Library && -w ~/Library ]] || return + fi + [[ -x /usr/libexec/PlistBuddy ]] || return + [[ -x /usr/bin/plutil ]] || return + [[ -x /usr/bin/defaults ]] || return + [[ -f ~/Library/Preferences/com.googlecode.iterm2.plist ]] || return + [[ -r ~/Library/Preferences/com.googlecode.iterm2.plist ]] || return + [[ -w ~/Library/Preferences/com.googlecode.iterm2.plist ]] || return + local guid1 && guid1="$(iterm_get '"Default Bookmark Guid"' 2>/dev/null)" || return + local guid2 && guid2="$(iterm_get '"New Bookmarks":0:"Guid"' 2>/dev/null)" || return + local font && font="$(iterm_get '"New Bookmarks":0:"Normal Font"' 2>/dev/null)" || return + [[ $guid1 == $guid2 ]] || return + [[ $font != 'MesloLGSNer-Regular '<-> ]] || return + [[ $font == (#b)*' '(<->) ]] || return + iterm2_font_size=$match[1] + terminal=iTerm2 + return + fi + return 1 +} + +function run_command() { + local msg=$1 + shift + [[ -n $msg ]] && print -nP -- "$msg ..." + local err && err="$("$@" 2>&1)" || { + print -P " %1FERROR%f" + print -P "" + print -nP "%BCommand:%b " + print -r -- "${(@q)*}" + if [[ -n $err ]]; then + print -P "" + print -r -- $err + fi + quit -c + } + [[ -n $msg ]] && print -P " %2FOK%f" +} + +function install_font() { + clear + case $terminal in + Termux) + mkdir -p ~/.termux || quit -c + run_command "Downloading %BMesloLGS NF Regular.ttf%b" \ + curl -fsSL -o ~/.termux/font.ttf "$font_base_url/MesloLGS%20NF%20Regular.ttf" + run_command "Reloading %BTermux%b settings" termux-reload-settings + ;; + iTerm2) + mkdir -p ~/Library/Fonts || quit -c + local style + for style in Regular Bold Italic 'Bold Italic'; do + local file="MesloLGS NF ${style}.ttf" + run_command "Downloading %B$file%b" \ + curl -fsSL -o ~/Library/Fonts/$file "$font_base_url/${file// /%20}" + done + print -nP -- "Changing %BiTerm2%b settings ..." + local k v settings=( + '"Normal Font"' '"MesloLGSNer-Regular '$iterm2_font_size'"' + '"Horizontal Spacing"' 1 + '"Vertical Spacing"' 1 + '"Use Bold Font"' 1 + '"Use Bright Bold"' 1 + '"Use Italic Font"' 1 + '"Use Non-ASCII Font"' 0 + '"Ambiguous Double Width"' 0 + '"Terminal Type"' '"xterm-256color"' + ) + for k v in $settings; do + run_command "" /usr/libexec/PlistBuddy -c \ + "Set :\"New Bookmarks\":0:$k $v" ~/Library/Preferences/com.googlecode.iterm2.plist + done + print -P " %2FOK%f" + run_command "Updating %BiTerm2%b settings cache" /usr/bin/defaults read com.googlecode.iterm2 + clear + print -P "%2FMeslo Nerd Font%f successfully installed." + print -P "" + print -P "Please %Brestart iTerm2%b for the changes to take effect." + print -P "" + flowing +c -i 5 " 1. Click" "%BiTerm2 → Quit iTerm2%b" or press "%B⌘ Q%b." + flowing +c -i 5 " 2. Open %BiTerm2%b." + print -P "" + exit 69 + ;; + esac +} + +function ask_font() { + can_install_font || return 0 + while true; do + clear + print_greeting + flowing -c "%BInstall %b%2FMeslo Nerd Font%f%B?%b" + print -P "" + print -P "" + print -P "%B(y) Yes (recommended).%b" + print -P "" + print -P "%B(n) No. Use the current font.%b" print -P "" - centered "%BDoes this look like a %b%2Fdiamond%f%B (square rotated 45 degrees)?%b" - centered "reference: $(href https://graphemica.com/%E2%97%86)" + print -P "(q) Quit and do nothing." print -P "" - centered "---> \uE0B2\uE0B0 <---" + + local key= + read -k key${(%):-"?%BChoice [ynq]: %b"} || quit -c + case $key in + q) quit;; + y) install_font; break;; + n) break;; + esac + done + greeting_printed=1 +} + +function ask_diamond() { + while true; do + local extra= + clear + print_greeting + flowing -c "%BDoes this look like a %b%2Fdiamond%f%B (rotated square)?%b" + flowing -c "reference: $(href https://graphemica.com/%E2%97%86)" + print -P "" + flowing -c -- "---> \uE0B2\uE0B0 <---" print -P "" print -P "%B(y) Yes.%b" print -P "" print -P "%B(n) No.%b" print -P "" + if can_install_font; then + extra+=r + print -P "(r) Restart from the beginning." + fi print -P "(q) Quit and do nothing." print -P "" local key= - read -k key${(%):-"?%BChoice [ynq]: %b"} || quit + read -k key${(%):-"?%BChoice [yn${extra}q]: %b"} || quit -c case $key in q) quit;; + r) [[ $extra == *r* ]] && { greeting_printed=1; return 1 };; y) cap_diamond=1; break;; n) cap_diamond=0; break;; esac done + greeting_printed=1 } function ask_lock() { while true; do clear - [[ -n $2 ]] && centered "$2" - centered "%BDoes this look like a %b%2Flock%f%B?%b" - centered "reference: $(href https://fontawesome.com/icons/lock)" + [[ -n $2 ]] && flowing -c "$2" + flowing -c "%BDoes this look like a %b%2Flock%f%B?%b" + flowing -c "reference: $(href https://fontawesome.com/icons/lock)" print -P "" - centered "---> $1 <---" + flowing -c -- "---> $1 <---" print -P "" print -P "%B(y) Yes.%b" print -P "" @@ -209,7 +435,7 @@ function ask_lock() { print -P "" local key= - read -k key${(%):-"?%BChoice [ynrq]: %b"} || quit + read -k key${(%):-"?%BChoice [ynrq]: %b"} || quit -c case $key in q) quit;; r) return 1;; @@ -222,10 +448,10 @@ function ask_lock() { function ask_python() { while true; do clear - centered "%BDoes this look like a %b%2FPython logo%f%B?%b" - centered "reference: $(href https://fontawesome.com/icons/python)" + flowing -c "%BDoes this look like a %b%2FPython logo%f%B?%b" + flowing -c "reference: $(href https://fontawesome.com/icons/python)" print -P "" - centered "---> \uE63C <---" + flowing -c -- "---> \uE63C <---" print -P "" print -P "%B(y) Yes.%b" print -P "" @@ -236,7 +462,7 @@ function ask_python() { print -P "" local key= - read -k key${(%):-"?%BChoice [ynrq]: %b"} || quit + read -k key${(%):-"?%BChoice [ynrq]: %b"} || quit -c case $key in q) quit;; r) return 1;; @@ -246,6 +472,33 @@ function ask_python() { done } +function ask_debian() { + while true; do + clear + flowing -c "%BDoes this look like a %b%2FDebian logo%f%B (swirl/spiral)?%b" + flowing -c "reference: $(href https://debian.org/logos/openlogo-nd.svg)" + print -P "" + flowing -c -- "---> \uF306 <---" + print -P "" + print -P "%B(y) Yes.%b" + print -P "" + print -P "%B(n) No.%b" + print -P "" + print -P "(r) Restart from the beginning." + print -P "(q) Quit and do nothing." + print -P "" + + local key= + read -k key${(%):-"?%BChoice [ynrq]: %b"} || quit -c + case $key in + q) quit;; + r) return 1;; + y) cap_debian=1; break;; + n) cap_debian=0; break;; + esac + done +} + function ask_narrow_icons() { if [[ $POWERLEVEL9K_MODE == (powerline|compatible) ]]; then cap_narrow_icons=0 @@ -257,14 +510,17 @@ function ask_narrow_icons() { text+="%3F${icons[DATE_ICON]// }%fX" text+="%4F${icons[TIME_ICON]// }%fX" text+="%5F${icons[RUBY_ICON]// }%fX" - text+="%6F${icons[AWS_EB_ICON]// }%fX" + text+="%6F${icons[HOME_ICON]// }%fX" + text+="%1F${icons[HOME_SUB_ICON]// }%fX" + text+="%2F${icons[FOLDER_ICON]// }%fX" + text+="%3F${icons[RAM_ICON]// }%fX" while true; do clear - centered "%BDo all these icons %b%2Ffit between the crosses%f%B?%b" + flowing -c "%BDo all these icons %b%2Ffit between the crosses%f%B?%b" print -P "" - centered "---> $text <---" + flowing -c -- "---> $text <---" print -P "" - print -P "%B(y) Yes. Icons are very close to the crosses but there is %b%2Fno overlap%f%B.%b" + flowing +c -i 5 "%B(y) Yes." Icons are very close to the crosses but there is "%b%2Fno overlap%f%B.%b" print -P "" print -P "%B(n) No. Some icons %b%2Foverlap%f%B neighbouring crosses.%b" print -P "" @@ -273,98 +529,258 @@ function ask_narrow_icons() { print -P "" local key= - read -k key${(%):-"?%BChoice [ynrq]: %b"} || quit + read -k key${(%):-"?%BChoice [ynrq]: %b"} || quit -c case $key in q) quit;; r) return 1;; y) cap_narrow_icons=1; options+='small icons'; break;; - n) cap_narrow_icons=0; break;; + n) cap_narrow_icons=0; options+='large icons'; break;; esac done } function ask_style() { + if (( cap_diamond && LINES < 26 )); then + local nl='' + else + local nl=$'\n' + fi while true; do clear - centered "%BPrompt Style%b" - print -P "" + flowing -c "%BPrompt Style%b" + print -n $nl print -P "%B(1) Lean.%b" - print -P "" + print -n $nl style=lean print_prompt print -P "" print -P "%B(2) Classic.%b" - print -P "" + print -n $nl style=classic print_prompt print -P "" + print -P "%B(3) Rainbow.%b" + print -n $nl + style=rainbow print_prompt + print -P "" + print -P "%B(4) Pure.%b" + print -n $nl + style=pure print_prompt + print -P "" print -P "(r) Restart from the beginning." print -P "(q) Quit and do nothing." print -P "" local key= - read -k key${(%):-"?%BChoice [12rq]: %b"} || quit + read -k key${(%):-"?%BChoice [1234rq]: %b"} || quit -c case $key in q) quit;; r) return 1;; 1) style=lean; options+=lean; break;; 2) style=classic; options+=classic; break;; + 3) style=rainbow; options+=rainbow; break;; + 4) style=pure; empty_line=1; options+=pure; break;; esac done } function ask_color() { [[ $style != classic ]] && return + if [[ $LINES -lt 26 ]]; then + local nl='' + else + local nl=$'\n' + fi while true; do clear - centered "%BPrompt Color%b" + flowing -c "%BPrompt Color%b" + print -n $nl + print -P "%B(1) Lightest.%b" + print -n $nl + color=1 print_prompt + print -P "" + print -P "%B(2) Light.%b" + print -n $nl + color=2 print_prompt print -P "" - print -P "%B(1) Light.%b" + print -P "%B(3) Dark.%b" + print -n $nl + color=3 print_prompt print -P "" - color=1 print_prompt + print -P "%B(4) Darkest.%b" + print -n $nl + color=4 print_prompt print -P "" - print -P "%B(2) Medium.%b" + print -P "(r) Restart from the beginning." + print -P "(q) Quit and do nothing." print -P "" + + local key= + read -k key${(%):-"?%BChoice [1234rq]: %b"} || quit -c + case $key in + q) quit;; + r) return 1;; + 1) color=1; options+=lightest; break;; + 2) color=2; options+=light; break;; + 3) color=3; options+=dark; break;; + 4) color=4; options+=darkest; break;; + esac + done +} + +function ask_frame_color() { + [[ $style != rainbow || $num_lines == 1 ]] && return + [[ $gap_char == ' ' && $left_frame == 0 && $right_frame == 0 ]] && return + if [[ $LINES -lt 26 ]]; then + local nl='' + else + local nl=$'\n' + fi + while true; do + clear + flowing -c "%BFrame Color%b" + print -n $nl + print -P "%B(1) Lightest.%b" + print -n $nl + color=1 print_prompt + print -P "" + print -P "%B(2) Light.%b" + print -n $nl color=2 print_prompt print -P "" print -P "%B(3) Dark.%b" - print -P "" + print -n $nl color=3 print_prompt print -P "" + print -P "%B(4) Darkest.%b" + print -n $nl + color=4 print_prompt + print -P "" print -P "(r) Restart from the beginning." print -P "(q) Quit and do nothing." print -P "" local key= - read -k key${(%):-"?%BChoice [123rq]: %b"} || quit + read -k key${(%):-"?%BChoice [1234rq]: %b"} || quit -c case $key in q) quit;; r) return 1;; - 1) color=1; options+=light; break;; - 2) color=2; options+=medium; break;; + 1) color=1; options+=lightest; break;; + 2) color=2; options+=light; break;; 3) color=3; options+=dark; break;; + 4) color=4; options+=darkest; break;; + esac + done +} + +function ask_time() { + if (( wizard_columns < 80 )); then + show_time= + return + fi + + while true; do + clear + flowing -c "%BShow current time?%b" + print -P "" + print -P "%B(y) Yes.%b" + print -P "" + show_time=1 print_prompt + print -P "" + print -P "%B(n) No.%b" + print -P "" + show_time= print_prompt + print -P "" + print -P "(r) Restart from the beginning." + print -P "(q) Quit and do nothing." + print -P "" + + local key= + read -k key${(%):-"?%BChoice [ynrq]: %b"} || quit -c + case $key in + q) quit;; + r) return 1;; + y) show_time=1; options+=time; break;; + n) show_time=; break;; esac done } +function os_icon_name() { + local uname="$(uname)" + if [[ $uname == Linux && "$(uname -o 2>/dev/null)" == Android ]]; then + echo ANDROID_ICON + else + case $uname in + SunOS) echo SUNOS_ICON;; + Darwin) echo APPLE_ICON;; + CYGWIN_NT-* | MSYS_NT-*) echo WINDOWS_ICON;; + FreeBSD|OpenBSD|DragonFly) echo FREEBSD_ICON;; + Linux) + local os_release_id + if [[ -r /etc/os-release ]]; then + local lines=(${(f)"$(= 25 )); then + extra+=5 + print -P "%B(5) Round.%b" + print -n $nl + left_tail=$left_circle right_tail=$right_circle print_prompt + print -P "" + fi fi fi print -P "(r) Restart from the beginning." @@ -566,7 +1040,7 @@ function ask_tails() { print -P "" local key= - read -k key${(%):-"?%BChoice [12${extra}rq]: %b"} || quit + read -k key${(%):-"?%BChoice [12${extra}rq]: %b"} || quit -c case $key in q) quit;; r) return 1;; @@ -588,6 +1062,14 @@ function ask_tails() { break fi ;; + 5) + if [[ $extra == *5* ]]; then + left_tail=$left_circle + right_tail=$right_circle + options+='round tails' + break + fi + ;; esac done } @@ -595,7 +1077,7 @@ function ask_tails() { function ask_num_lines() { while true; do clear - centered "%BPrompt Height%b" + flowing -c "%BPrompt Height%b" print -P "" print -P "%B(1) One line.%b" print -P "" @@ -610,7 +1092,7 @@ function ask_num_lines() { print -P "" local key= - read -k key${(%):-"?%BChoice [12rq]: %b"} || quit + read -k key${(%):-"?%BChoice [12rq]: %b"} || quit -c case $key in q) quit;; r) return 1;; @@ -626,7 +1108,7 @@ function ask_gap_char() { fi while true; do clear - centered "%BPrompt Connection%b" + flowing -c "%BPrompt Connection%b" print -P "" print -P "%B(1) Disconnected.%b" print -P "" @@ -645,7 +1127,7 @@ function ask_gap_char() { print -P "" local key= - read -k key${(%):-"?%BChoice [123rq]: %b"} || quit + read -k key${(%):-"?%BChoice [123rq]: %b"} || quit -c case $key in q) quit;; r) return 1;; @@ -657,14 +1139,14 @@ function ask_gap_char() { } function ask_frame() { - if [[ $style != classic || $num_lines != 2 ]]; then + if [[ $style != (classic|rainbow) || $num_lines != 2 ]]; then return fi (( LINES >= 26 )) && local nl=$'\n' || local nl='' while true; do clear - centered "%BPrompt Frame%b" + flowing -c "%BPrompt Frame%b" print -n $nl print -P "%B(1) No frame.%b" print -n $nl @@ -687,7 +1169,7 @@ function ask_frame() { print -P "" local key= - read -k key${(%):-"?%BChoice [1234rq]: %b"} || quit + read -k key${(%):-"?%BChoice [1234rq]: %b"} || quit -c case $key in q) quit;; r) return 1;; @@ -702,7 +1184,7 @@ function ask_frame() { function ask_empty_line() { while true; do clear - centered "%BPrompt Spacing%b" + flowing -c "%BPrompt Spacing%b" print -P "" print -P "%B(1) Compact.%b" print -P "" @@ -720,7 +1202,7 @@ function ask_empty_line() { print -P "" local key= - read -k key${(%):-"?%BChoice [12rq]: %b"} || quit + read -k key${(%):-"?%BChoice [12rq]: %b"} || quit -c case $key in q) quit;; r) return 1;; @@ -733,7 +1215,7 @@ function ask_empty_line() { function ask_confirm() { while true; do clear - centered "%BLooks good?%b" + flowing -c "%BLooks good?%b" print -P "" print_prompt (( empty_line )) && print -P "" @@ -746,7 +1228,7 @@ function ask_confirm() { print -P "" local key= - read -k key${(%):-"?%BChoice [yrq]: %b"} || quit + read -k key${(%):-"?%BChoice [yrq]: %b"} || quit -c case $key in q) quit;; r) return 1;; @@ -763,8 +1245,8 @@ function ask_config_overwrite() { fi while true; do clear - centered "Powerlevel10k config file already exists." - centered "%BOverwrite %b%2F$__p9k_cfg_path_u%f%B?%b" + flowing -c "Powerlevel10k config file already exists." + flowing -c "%BOverwrite" "%b%2F${__p9k_cfg_path_u//\\/\\\\}%f%B?%b" print -P "" print -P "%B(y) Yes.%b" print -P "" @@ -773,13 +1255,14 @@ function ask_config_overwrite() { print -P "" local key= - read -k key${(%):-"?%BChoice [yrq]: %b"} || quit + read -k key${(%):-"?%BChoice [yrq]: %b"} || quit -c case $key in q) quit;; r) return 1;; y) - config_backup="$(mktemp ${TMPDIR:-/tmp}/$__p9k_cfg_basename.XXXXXXXXXX)" || return 1 - cp $__p9k_cfg_path $config_backup + config_backup="$(mktemp ${TMPDIR:-/tmp}/$__p9k_cfg_basename.XXXXXXXXXX)" || exit 1 + cp $__p9k_cfg_path $config_backup || exit 1 + config_backup_u=${${TMPDIR:+\$TMPDIR}:-/tmp}/${(q-)config_backup:t} write_config=1 break ;; @@ -788,6 +1271,14 @@ function ask_config_overwrite() { } function generate_config() { + if [[ $style == pure ]]; then + if [[ -e $__p9k_cfg_path ]]; then + unlink $__p9k_cfg_path || return + fi + cp $__p9k_root_dir/config/p10k-$style.zsh $__p9k_cfg_path || return + return + fi + local base && base="$(<$__p9k_root_dir/config/p10k-$style.zsh)" || return local lines=("${(@f)base}") @@ -799,23 +1290,57 @@ function generate_config() { lines=("${(@)lines/#(#b)([[:space:]]#)\# $1( |)/$match[1]$1$match[2]$match[2]}") } + function rep() { + lines=("${(@)lines//$1/$2}") + } + sub MODE $POWERLEVEL9K_MODE if (( cap_narrow_icons )); then + uncomment 'typeset -g POWERLEVEL9K_VISUAL_IDENTIFIER_EXPANSION' sub VISUAL_IDENTIFIER_EXPANSION "'\${P9K_VISUAL_IDENTIFIER// }'" sub BACKGROUND_JOBS_VISUAL_IDENTIFIER_EXPANSION "'\${P9K_VISUAL_IDENTIFIER// }'" + sub VPN_IP_VISUAL_IDENTIFIER_EXPANSION "'\${P9K_VISUAL_IDENTIFIER// }'" + sub OS_ICON_CONTENT_EXPANSION "'%B\${P9K_CONTENT// }'" else sub VISUAL_IDENTIFIER_EXPANSION "'\${P9K_VISUAL_IDENTIFIER}'" sub BACKGROUND_JOBS_VISUAL_IDENTIFIER_EXPANSION "'\${P9K_VISUAL_IDENTIFIER}'" + sub VPN_IP_VISUAL_IDENTIFIER_EXPANSION "'\${P9K_VISUAL_IDENTIFIER}'" fi if [[ $POWERLEVEL9K_MODE == compatible ]]; then - # Many fonts don't have the gear icon. + # Many fonts don't have the gear or the lock icon. sub BACKGROUND_JOBS_VISUAL_IDENTIFIER_EXPANSION "'⇶'" + uncomment 'typeset -g POWERLEVEL9K_DIR_NOT_WRITABLE_VISUAL_IDENTIFIER_EXPANSION' + sub DIR_NOT_WRITABLE_VISUAL_IDENTIFIER_EXPANSION "'∅'" + fi + + if [[ $POWERLEVEL9K_MODE == (awesome-patched|awesome-fontconfig) && $cap_python == 0 ]]; then + uncomment 'typeset -g POWERLEVEL9K_VIRTUALENV_VISUAL_IDENTIFIER_EXPANSION' + uncomment 'typeset -g POWERLEVEL9K_ANACONDA_VISUAL_IDENTIFIER_EXPANSION' + uncomment 'typeset -g POWERLEVEL9K_PYENV_VISUAL_IDENTIFIER_EXPANSION' + uncomment 'typeset -g POWERLEVEL9K_PYTHON_ICON' + sub VIRTUALENV_VISUAL_IDENTIFIER_EXPANSION "'🐍'" + sub ANACONDA_VISUAL_IDENTIFIER_EXPANSION "'🐍'" + sub PYENV_VISUAL_IDENTIFIER_EXPANSION "'🐍'" + sub PYTHON_ICON "'🐍'" + fi + + if [[ $POWERLEVEL9K_MODE == nerdfont-complete ]]; then + sub BATTERY_STAGES "\$'\uf58d\uf579\uf57a\uf57b\uf57c\uf57d\uf57e\uf57f\uf580\uf581\uf578'" fi - if [[ $style == classic ]]; then - sub BACKGROUND $bg_color[$color] + if [[ $style == (classic|rainbow) ]]; then + if [[ $style == classic ]]; then + sub BACKGROUND $bg_color[$color] + sub LEFT_SUBSEGMENT_SEPARATOR "'%$sep_color[$color]F$left_subsep'" + sub RIGHT_SUBSEGMENT_SEPARATOR "'%$sep_color[$color]F$right_subsep'" + sub VCS_LOADING_FOREGROUND $sep_color[$color] + rep '%248F' "%$prefix_color[$color]F" + else + sub LEFT_SUBSEGMENT_SEPARATOR "'$left_subsep'" + sub RIGHT_SUBSEGMENT_SEPARATOR "'$right_subsep'" + fi sub MULTILINE_FIRST_PROMPT_GAP_FOREGROUND $frame_color[$color] sub MULTILINE_FIRST_PROMPT_PREFIX "'%$frame_color[$color]F╭─'" sub MULTILINE_NEWLINE_PROMPT_PREFIX "'%$frame_color[$color]F├─'" @@ -823,8 +1348,6 @@ function generate_config() { sub MULTILINE_FIRST_PROMPT_SUFFIX "'%$frame_color[$color]F─╮'" sub MULTILINE_NEWLINE_PROMPT_SUFFIX "'%$frame_color[$color]F─┤'" sub MULTILINE_LAST_PROMPT_SUFFIX "'%$frame_color[$color]F─╯'" - sub LEFT_SUBSEGMENT_SEPARATOR "'%$sep_color[$color]F$left_subsep'" - sub RIGHT_SUBSEGMENT_SEPARATOR "'%$sep_color[$color]F$right_subsep'" sub LEFT_SEGMENT_SEPARATOR "'$left_sep'" sub RIGHT_SEGMENT_SEPARATOR "'$right_sep'" sub LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL "'$left_tail'" @@ -833,10 +1356,14 @@ function generate_config() { sub RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL "'$right_tail'" fi + if [[ -n $show_time ]]; then + uncomment time + fi + if [[ -n ${(j::)extra_icons} ]]; then - local branch_icon=$icons[VCS_BRANCH_ICON] - (( cap_narrow_icons )) && branch_icon=${branch_icon// } + local branch_icon=${icons[VCS_BRANCH_ICON]// } sub VCS_BRANCH_ICON "'$branch_icon '" + uncomment os_icon else uncomment 'typeset -g POWERLEVEL9K_DIR_CLASSES' uncomment 'typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_EXPANSION' @@ -853,14 +1380,19 @@ function generate_config() { uncomment 'typeset -g POWERLEVEL9K_CONTEXT_PREFIX' uncomment 'typeset -g POWERLEVEL9K_KUBECONTEXT_PREFIX' uncomment 'typeset -g POWERLEVEL9K_TIME_PREFIX' - [[ $style == classic ]] && local fg="%$prefix_color[$color]F" || local fg="%f" - sub VCS_PREFIX "'${fg}on '" - sub COMMAND_EXECUTION_TIME_PREFIX "'${fg}took '" - sub CONTEXT_PREFIX "'${fg}with '" - sub KUBECONTEXT_PREFIX "'${fg}at '" - sub TIME_PREFIX "'${fg}at '" - sub CONTEXT_TEMPLATE "'%n$fg at %180F%m'" - sub CONTEXT_ROOT_TEMPLATE "'%n$fg at %227F%m'" + if [[ $style == (lean|classic) ]]; then + [[ $style == classic ]] && local fg="%$prefix_color[$color]F" || local fg="%f" + sub VCS_PREFIX "'${fg}on '" + sub COMMAND_EXECUTION_TIME_PREFIX "'${fg}took '" + sub CONTEXT_PREFIX "'${fg}with '" + sub KUBECONTEXT_PREFIX "'${fg}at '" + sub TIME_PREFIX "'${fg}at '" + sub CONTEXT_TEMPLATE "'%n$fg at %180F%m'" + sub CONTEXT_ROOT_TEMPLATE "'%n$fg at %227F%m'" + else + sub CONTEXT_TEMPLATE "'%n at %m'" + sub CONTEXT_ROOT_TEMPLATE "'%n at %m'" + fi fi if (( num_lines == 1 )); then @@ -874,7 +1406,7 @@ function generate_config() { sub MULTILINE_FIRST_PROMPT_GAP_CHAR "'$gap_char'" - if [[ $style == classic && $num_lines == 2 ]]; then + if [[ $style == (classic|rainbow) && $num_lines == 2 ]]; then if (( ! right_frame )); then sub MULTILINE_FIRST_PROMPT_SUFFIX '' sub MULTILINE_NEWLINE_PROMPT_SUFFIX '' @@ -901,8 +1433,19 @@ function generate_config() { fi fi header+=$'.\n' - header+="# Wizard options: ${(j:, :)options}" - header+=$'.\n#' + local line="# Wizard options: $options[1]" + local opt + for opt in $options[2,-1]; do + if (( $#line + $#opt > 85 )); then + header+=$line + header+=$',\n' + line="# $opt" + else + line+=", $opt" + fi + done + header+=$line + header+=$'.\n# Type `p10k configure` to generate another config.\n#' if [[ -e $__p9k_cfg_path ]]; then unlink $__p9k_cfg_path || return 1 @@ -913,28 +1456,27 @@ function generate_config() { function write_zshrc() { if [[ -e $__p9k_zshrc ]]; then local lines=(${(f)"$(<$__p9k_zshrc)"}) - local f1=$__p9k_cfg_path - local f2=$__p9k_cfg_path_u - local f3=${__p9k_cfg_path_u/#\~\//\$HOME\/} - local f4=${__p9k_cfg_path_u/#\~\//\"\$HOME\"\/} - local f5="'$f1'" - local f6="\"$f1\"" - local f7="\"$f3\"" - if [[ -n ${(@M)lines:#(#b)source[[:space:]]##($f1|$f2|$f3|$f4|$f5|$f6|$f7)*} ]]; then - print -P "No changes have been made to %4F$__p9k_zshrc_u%f because it already sources %2F$__p9k_cfg_path_u%f." + local f0=$__p9k_cfg_path + local f1=${(q)f0} + local f2=${(q-)f0} + local f3=${(qq)f0} + local f4=${(qqq)f0} + local g1=${${(q)__p9k_cfg_path}/#(#b)${(q)HOME}\//'~/'} + if [[ -n ${(@M)lines:#(#b)[^#]#([^[:IDENT:]]|)source[[:space:]]##($f1|$f2|$f3|$f4|$g1)(|[[:space:]]*|'#'*)} ]]; then + flowing +c No changes have been made to %4F$__p9k_zshrc_u%f because it already sources %2F$__p9k_cfg_path_u%f. return fi fi local comments=( - "# To customize prompt, run \`p9k_configure\` or edit $__p9k_cfg_path_u." + "# To customize prompt, run \`p10k configure\` or edit $__p9k_cfg_path_u." ) - print -lr -- "" $comments "source $__p9k_cfg_path_u" >>$__p9k_zshrc + print -lrP -- "" $comments "[[ -f $__p9k_cfg_path_u ]] && source $__p9k_cfg_path_u" >>$__p9k_zshrc - print -P "" - print -P "The following lines have been appended to %4F$__p9k_zshrc_u%f:" - print -P "" - print -lP -- ' '${^comments} " %2Fsource%f %B$__p9k_cfg_path_u%b" + print -rP "" + flowing +c The following lines have been appended to %4F$__p9k_zshrc_u%f: + print -rP "" + print -lrP -- ' '${^comments} " %3F[[%f %B-f $__p9k_cfg_path_u%b %3F]]%f && %2Fsource%f %B$__p9k_cfg_path_u%b" } if (( force )); then @@ -946,31 +1488,42 @@ fi source $__p9k_root_dir/internal/icons.zsh || return while true; do - local POWERLEVEL9K_MODE= style= config_backup= gap_char=' ' - local left_subsep= right_subsep= left_tail= right_tail= left_head= right_head= - local -i num_lines=0 write_config=0 empty_line=0 color=1 left_frame=1 right_frame=1 - local -i cap_diamond=0 cap_python=0 cap_narrow_icons=0 cap_lock=0 - local -a extra_icons=('' '') + local POWERLEVEL9K_MODE= style= config_backup= config_backup_u= gap_char=' ' + local left_subsep= right_subsep= left_tail= right_tail= left_head= right_head= show_time= + local -i num_lines=0 write_config=0 empty_line=0 color=2 left_frame=1 right_frame=1 + local -i cap_diamond=0 cap_python=0 cap_debian=0 cap_narrow_icons=0 cap_lock=0 + local -a extra_icons=('' '' '') local -a prefixes=('' '') local -a options=() + ask_font || continue ask_diamond || continue - if [[ -n $AWESOME_GLYPHS_LOADED ]]; then + if [[ $AWESOME_GLYPHS_LOADED == 1 ]]; then POWERLEVEL9K_MODE=awesome-mapped-fontconfig else ask_lock '\uF023' || continue if (( ! cap_lock )); then ask_lock '\uE138' "Let's try another one." || continue if (( cap_lock )); then - (( cap_diamond )) && POWERLEVEL9K_MODE=awesome-patched || POWERLEVEL9K_MODE=flat + if (( cap_diamond )); then + POWERLEVEL9K_MODE=awesome-patched + ask_python || continue + else + POWERLEVEL9K_MODE=flat + fi else (( cap_diamond )) && POWERLEVEL9K_MODE=powerline || POWERLEVEL9K_MODE=compatible fi elif (( ! cap_diamond )); then POWERLEVEL9K_MODE=awesome-fontconfig else - ask_python || continue - (( cap_python )) && POWERLEVEL9K_MODE=awesome-fontconfig || POWERLEVEL9K_MODE=nerdfont-complete + ask_debian || continue + if (( cap_debian )); then + POWERLEVEL9K_MODE=nerdfont-complete + else + POWERLEVEL9K_MODE=awesome-fontconfig + ask_python || continue + fi fi fi if [[ $POWERLEVEL9K_MODE == powerline ]]; then @@ -980,12 +1533,17 @@ while true; do else options+="$POWERLEVEL9K_MODE" fi + (( cap_python )) && options[-1]+=' + python' if (( cap_diamond )); then + left_sep=$right_triangle + right_sep=$left_triangle left_subsep=$right_angle right_subsep=$left_angle left_head=$right_triangle right_head=$left_triangle else + left_sep= + right_sep= left_subsep=$vertical_bar right_subsep=$vertical_bar left_head=$fade_out @@ -1085,16 +1643,20 @@ while true; do return 1 ask_style || continue - ask_color || continue - ask_separators || continue - ask_heads || continue - ask_tails || continue - ask_num_lines || continue - ask_gap_char || continue - ask_frame || continue - ask_empty_line || continue - ask_extra_icons || continue - ask_prefixes || continue + if [[ $style != pure ]]; then + ask_color || continue + ask_time || continue + ask_separators || continue + ask_heads || continue + ask_tails || continue + ask_num_lines || continue + ask_gap_char || continue + ask_frame || continue + ask_frame_color || continue + ask_empty_line || continue + ask_extra_icons || continue + ask_prefixes || continue + fi ask_confirm || continue ask_config_overwrite || continue break @@ -1102,9 +1664,9 @@ done clear -print -P "Powerlevel10k configuration has been written to %2F$__p9k_cfg_path_u%f." +flowing +c Powerlevel10k configuration has been written to %2F$__p9k_cfg_path_u%f. if [[ -n $config_backup ]]; then - print -P "The backup of the previuos version is at %3F$config_backup%f." + flowing +c The backup of the previous version is at %3F$config_backup_u%f. fi if (( write_config )); then @@ -1113,9 +1675,8 @@ fi write_zshrc || return -print -P "" -print -P "File feature requests and bug reports at $(href https://github.com/romkatv/powerlevel10k/issues)." -print -P "Send praise and complaints to $(href https://www.reddit.com/r/zsh)." -print -P "" +print -rP "" +flowing +c File feature requests and bug reports at "$(href https://github.com/romkatv/powerlevel10k/issues)." +print -rP "" } "$@" diff --git a/powerlevel10k.zsh-theme b/powerlevel10k.zsh-theme deleted file mode 120000 index 311575f4..00000000 --- a/powerlevel10k.zsh-theme +++ /dev/null @@ -1 +0,0 @@ -powerlevel9k.zsh-theme \ No newline at end of file diff --git a/powerlevel10k.zsh-theme b/powerlevel10k.zsh-theme new file mode 100644 index 00000000..7bf59736 --- /dev/null +++ b/powerlevel10k.zsh-theme @@ -0,0 +1,44 @@ +# vim:ft=zsh ts=2 sw=2 sts=2 et fenc=utf-8 +################################################################ +# Powerlevel10k Theme +# https://github.com/romkatv/powerlevel10k +# +# Forked from Powerlevel9k Theme +# https://github.com/bhilburn/powerlevel9k +# +# Which in turn was forked from Agnoster Theme +# https://github.com/robbyrussell/oh-my-zsh/blob/74177c5320b2a1b2f8c4c695c05984b57fd7c6ea/themes/agnoster.zsh-theme +################################################################ + +# Temporarily change options. +'builtin' 'local' '-a' '__p9k_src_opts' +[[ ! -o 'aliases' ]] || __p9k_src_opts+=('aliases') +[[ ! -o 'sh_glob' ]] || __p9k_src_opts+=('sh_glob') +[[ ! -o 'no_brace_expand' ]] || __p9k_src_opts+=('no_brace_expand') +'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand' + +(( $+__p9k_root_dir )) || typeset -gr __p9k_root_dir=${POWERLEVEL9K_INSTALLATION_DIR:-${${(%):-%x}:A:h}} + +() { + emulate -L zsh + setopt no_hist_expand extended_glob no_prompt_bang no_prompt_subst prompt_percent no_aliases + if (( $+__p9k_sourced )); then + prompt_powerlevel9k_setup + return + fi + typeset -gr __p9k_dump_file=${XDG_CACHE_HOME:-~/.cache}/p10k-dump-${(%):-%n}.zsh + if [[ -z $__p9k_dump_file(.zwc|)(#qNW) ]] && source $__p9k_dump_file 2>/dev/null && (( $+functions[_p9k_preinit] )); then + _p9k_preinit + fi + typeset -gr __p9k_sourced=1 + if [[ -w $__p9k_root_dir && -w $__p9k_root_dir/internal && -w $__p9k_root_dir/gitstatus && ${(%):-%#} == % ]]; then + local f + for f in $__p9k_root_dir/{powerlevel9k.zsh-theme,powerlevel10k.zsh-theme,internal/p10k.zsh,internal/icons.zsh,internal/configure.zsh,gitstatus/gitstatus.plugin.zsh}; do + [[ $f.zwc -nt $f ]] || zcompile $f + done + fi + source $__p9k_root_dir/internal/p10k.zsh || true +} + +(( ${#__p9k_src_opts} )) && setopt ${__p9k_src_opts[@]} +'builtin' 'unset' '__p9k_src_opts' diff --git a/powerlevel9k.zsh-theme b/powerlevel9k.zsh-theme old mode 100755 new mode 100644 index 95bce71b..328cd838 --- a/powerlevel9k.zsh-theme +++ b/powerlevel9k.zsh-theme @@ -1,53 +1 @@ -# vim:ft=zsh ts=2 sw=2 sts=2 et fenc=utf-8 -################################################################ -# Powerlevel10k Theme -# https://github.com/romkatv/powerlevel10k -# -# Forked from Powerlevel9k Theme -# https://github.com/bhilburn/powerlevel9k -# -# Which in turn was forked from Agnoster Theme -# https://github.com/robbyrussell/oh-my-zsh/blob/74177c5320b2a1b2f8c4c695c05984b57fd7c6ea/themes/agnoster.zsh-theme -################################################################ - -if [[ -o 'aliases' ]]; then - 'builtin' 'unsetopt' 'aliases' - local __p9k_restore_aliases=1 -else - local __p9k_restore_aliases=0 -fi - -() { - emulate -L zsh - - if (( $+__p9k_sourced )); then - prompt_powerlevel9k_setup - return - fi - typeset -gr __p9k_sourced=1 - typeset -g __p9k_root_dir='' - - if [[ -n $POWERLEVEL9K_INSTALLATION_DIR ]]; then - __p9k_root_dir=${POWERLEVEL9K_INSTALLATION_DIR:A} - else - if [[ ${(%):-%N} == '(eval)' ]]; then - if [[ $0 == '-antigen-load' && -r powerlevel9k.zsh-theme ]]; then - # Antigen uses eval to load things so it can change the plugin (!!) - # https://github.com/zsh-users/antigen/issues/581 - __p9k_root_dir=$PWD - else - >&2 print -P '%F{red}[ERROR]%f Powerlevel10k cannot figure out its installation directory.' - >&2 print -P 'Please set %F{green}POWERLEVEL9K_INSTALLATION_DIR.%f' - return - fi - else - __p9k_root_dir=${${(%):-%x}:A:h} - fi - fi - - typeset -gr __p9k_root_dir - source $__p9k_root_dir/internal/p10k.zsh || true -} - -(( ! __p9k_restore_aliases )) || setopt aliases -'builtin' 'unset' '__p9k_restore_aliases' +'builtin' 'source' "${POWERLEVEL9K_INSTALLATION_DIR:-${${(%):-%x}:A:h}}/powerlevel10k.zsh-theme" diff --git a/prompt.png b/prompt.png deleted file mode 100644 index 104b550b..00000000 Binary files a/prompt.png and /dev/null differ diff --git a/prompt_powerlevel10k_setup b/prompt_powerlevel10k_setup deleted file mode 120000 index 866a1f4a..00000000 --- a/prompt_powerlevel10k_setup +++ /dev/null @@ -1 +0,0 @@ -prompt_powerlevel9k_setup \ No newline at end of file diff --git a/prompt_powerlevel10k_setup b/prompt_powerlevel10k_setup new file mode 100644 index 00000000..328cd838 --- /dev/null +++ b/prompt_powerlevel10k_setup @@ -0,0 +1 @@ +'builtin' 'source' "${POWERLEVEL9K_INSTALLATION_DIR:-${${(%):-%x}:A:h}}/powerlevel10k.zsh-theme" diff --git a/prompt_powerlevel9k_setup b/prompt_powerlevel9k_setup deleted file mode 120000 index 311575f4..00000000 --- a/prompt_powerlevel9k_setup +++ /dev/null @@ -1 +0,0 @@ -powerlevel9k.zsh-theme \ No newline at end of file diff --git a/prompt_powerlevel9k_setup b/prompt_powerlevel9k_setup new file mode 100644 index 00000000..328cd838 --- /dev/null +++ b/prompt_powerlevel9k_setup @@ -0,0 +1 @@ +'builtin' 'source' "${POWERLEVEL9K_INSTALLATION_DIR:-${${(%):-%x}:A:h}}/powerlevel10k.zsh-theme"