diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..8f6423fa --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +test-vm/.vagrant diff --git a/README.md b/README.md index dc8798fe..71dfceb2 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,61 @@ -## powerlevel9k Theme for Oh-My-Zsh +## powerlevel9k Theme for ZSH -This is a theme for [Oh-My-Zsh](https://github.com/robbyrussell/oh-my-zsh). This -theme uses [Powerline Fonts](https://github.com/Lokaltog/powerline-fonts), thus -giving you the most epic terminal styling in the universe. +Powerlevel9k is a theme for ZSH which uses [Powerline +Fonts](https://github.com/Lokaltog/powerline-fonts). It can be used with vanilla +ZSH, [Oh-My-Zsh](https://github.com/robbyrussell/oh-my-zsh), or +[Prezto](https://github.com/sorin-ionescu/prezto), and can also be installed +using [antigen](https://github.com/zsh-users/antigen). Look like a bad-ass. Impress everyone in 'Screenshot Your Desktop' threads. Use powerlevel9k. -In addition to looking amazing, this theme actually provides a lot of useful -information in configurable prompt segments. +![](http://bhilburn.org/content/images/2015/01/pl9k-improved.png) + +There are a number of Powerline ZSH themes available, now. The developers of +this theme focus on three primary goals: + +1. Give users a great out-of-the-box configuration with no additional + configuration required. +2. Make customization easy for users who do want to tweak their prompt. +3. Provide useful segments that you can enable to make your prompt even more + effective and helpful. We have prompt segments for everything from unit test + coverage to your AWS instance. + + + +**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* + +- [Features](#features) +- [Installation](#installation) + - [Step 1: Install Powerlevel9k](#step-1-install-powerlevel9k) + - [Option 1: Install for Vanilla ZSH](#option-1-install-for-vanilla-zsh) + - [Option 2: Install for Oh-My-ZSH](#option-2-install-for-oh-my-zsh) + - [Option 3: Install for Prezto](#option-3-install-for-prezto) + - [Option 4: Install for antigen](#option-4-install-for-antigen) + - [Step 2: Install Powerline Fonts](#step-2-install-powerline-fonts) + - [Option 1: Install Powerline Fonts](#option-1-install-powerline-fonts) + - [Option 2: Install Awesome Powerline Fonts](#option-2-install-awesome-powerline-fonts) + - [Option 3: Compatible Mode](#option-3-compatible-mode) +- [Segment Customization](#segment-customization) + - [The AWS Profile Segment](#the-aws-profile-segment) + - [The 'context' Segment](#the-context-segment) + - [The 'dir' segment](#the-dir-segment) + - [The 'time' segment](#the-time-segment) + - [Unit Test Ratios](#unit-test-ratios) + - [The 'vcs' Segment](#the-vcs-segment) + - [Symbols](#symbols) +- [Styling](#styling) + - [Double-Lined Prompt](#double-lined-prompt) + - [Light Color Theme](#light-color-theme) + - [Segment Color Customization](#segment-color-customization) + - [Special Segment Colors](#special-segment-colors) +- [Troubleshooting](#troubleshooting) + - [Gaps Between Segments](#gaps-between-segments) +- [Meta](#meta) + - [Kudos](#kudos) + - [Developing](#developing) + - [Contributions / Bugs / Contact](#contributions--bugs--contact) + + ### Features @@ -21,7 +69,7 @@ information in configurable prompt segments. * various working tree statuses (e.g., unstaged, staged, etc.,) * Shows return-code of the last command if it is an error code * Indicates background jobs with a gear icon -* Can conditionally display the `user@host` string when needed +* Can conditionally display the `user@host` string when needed (e.g., SSH) * Provides segment for command history (so you can `$ !` to re-run) * Plenty of additional segments to choose from (e.g., AWS, ruby) * Can be used as a single or double-lined prompt (see screenshots below) @@ -31,22 +79,92 @@ information in configurable prompt segments. doesn't require Powerline fonts, check out the sister font, [hackersaurus](https://github.com/bhilburn/hackersaurus).** -Here are some screenshots of `powerlevel9k` with default settings: +Here is a detailed screenshot showing `powerlevel9k` with default settings and +varying terminal status indicators: ![](http://bhilburn.org/content/images/2014/12/powerlevel9k.png) -![](http://bhilburn.org/content/images/2015/01/pl9k-improved.png) +### Installation +There are two steps to start using this theme: +1. Install the Powerlevel9k theme. +2. Install Powerline-patched fonts. +3. [Optional] Configuration -### Installation +To get the most out of Powerlevel9k, you need to install both the theme as well +as Powerline-patched fonts, if you don't have them installed already. If you +cannot install Powerline-patched fonts for some reason, follow the instructions +below for a `compatible` install. + +No configuration is necessary post-installation if you like the default +settings, but there is plenty of segment configuration available if you are +interested. + +#### Step 1: Install Powerlevel9k +There are four ways to install and use the Powerlevel9k theme: vanilla ZSH, +Oh-My-Zsh, Prezto, and antigen. Do one of the following: + +##### Option 1: Install for Vanilla ZSH + +If you use just a vanilla ZSH install, simply clone this repository and +reference it in your `~/.zshrc`: + + $ git clone https://github.com/bhilburn/powerlevel9k.git + $ echo 'source powerlevel9k/powerlevel9k.zsh-theme' >> ~/.zshrc + +##### Option 2: Install for Oh-My-ZSH + +To install this theme for +[Oh-My-Zsh](https://github.com/robbyrussell/oh-my-zsh), clone this repository +into your OMZ `custom/themes` directory. + + $ cd ~/.oh-my-zsh/custom + $ git clone https://github.com/bhilburn/powerlevel9k.git themes/powerlevel9k + +You then need to select this theme in your `~/.zshrc`: + + ZSH_THEME="powerlevel9k/powerlevel9k" -There are two things you need to make this theme work correctly: Powerline -fonts, and the theme itself. +##### Option 3: Install for Prezto -#### Install Powerline Fonts -First, you need to install Powerline Fonts. You can find the [installation -instructions -here](https://powerline.readthedocs.org/en/latest/installation/linux.html#fonts-installation). +To install this theme for use in Prezto, clone this repository into your +[Prezto](https://github.com/sorin-ionescu/prezto) `prompt/external` directory. + + $ cd ~.zprezto/modules/prompt/external + $ git clone https://github.com/bhilburn/powerlevel9k.git + $ ln -s powerlevel9k/powerlevel9k.zsh-theme ../functions/prompt_powerlevel9k_setup + +You then need to select this theme in your `~/.zpreztorc`: + + zstyle ':prezto:module:prompt' theme 'powerlevel9k' + +##### Option 4: Install for antigen + +If you prefer [antigen](https://github.com/zsh-users/antigen), just add this +theme to the antigen config in your `~/.zshrc`: + + $ echo 'antigen theme bhilburn/powerlevel9k powerlevel9k' >> ~/.zshrc + $ echo 'antigen apply' >> ~/.zshrc + +Note that you should define any customizations before calling `antigen theme` +(i.e. setting the `POWERLEVEL9K_*` variables) in your `.zshrc`. + +#### Step 2: Install Powerline Fonts +Technically, you don't *have* to install Powerline fonts. If you are using +a font that has some of the basic glyphs we need, you can use the theme in +`compatible` mode - see the third option, below. + +To get the most out of theme, though, you'll want Powerline-patched fonts. There +are two varieties of these: 'Powerline Fonts' and 'Awesome Powerline +Fonts'. The latter includes additional glyphs that aren't required for a normal +install. + +Do one of the following: + +##### Option 1: Install Powerline Fonts + +You can find the [installation instructions for Powerline Fonts here] +(https://powerline.readthedocs.org/en/latest/installation/linux.html#fonts-installation). You can also find the raw font files [in this Github repository](https://github.com/powerline/fonts) if you want to manually install them for your OS. @@ -54,17 +172,51 @@ them for your OS. After you have installed Powerline fonts, make the default font in your terminal emulator the Powerline font you want to use. -#### Install Powerlevel9k +This is the default mode for `Powerlevel9k`, and no further configuration is +necessary. -To install this theme, clone this repository into your Oh-My-Zsh `custom/themes` -directory. +**N.B.:** If Powerlevel9k is not working properly, it is almost always the case +that the fonts were not properly installed, or you have not configured your +terminal to use a Powerline-patched font! - $ cd ~/.oh-my-zsh/custom - $ git clone https://github.com/bhilburn/powerlevel9k.git themes/powerlevel9k +##### Option 2: Install Awesome Powerline Fonts -You then need to select this theme in your `~/.zshrc`: +Alternatively, you can install [Awesome Powerline +Fonts](https://github.com/gabrielelana/awesome-terminal-fonts), which provide +a number of additional glyphs. - ZSH_THEME="powerlevel9k/powerlevel9k" +You then need to indicate that you wish to use the additional glyphs by defining +the following in your `~/.zshrc`: + + POWERLEVEL9K_MODE='awesome-patched' + +If you choose to make use of this, your prompt will look something like this: + +![](https://cloud.githubusercontent.com/assets/1544760/7959660/67612918-09fb-11e5-9ef2-2308363c3c51.png) + +Note that if you prefer flat segment transitions, you can use the following with +`Awesome Powerline Fonts` installed: + + POWERLEVEL9K_MODE='flat' + +Which looks like this: + +![](https://cloud.githubusercontent.com/assets/1544760/7981324/76d0eb5a-0aae-11e5-9608-d662123d0b0a.png) + +##### Option 3: Compatible Mode + +This option is best if you prefer not to install additional fonts. This option +will work out-of-the-box if your your terminal font supports the segment +separator characters `\uE0B0` (left segment separator) and `\uE0B2` (right +segment separator). + +All you need to do to in this case is install the `Powerlevel9k` theme itself, +as explained above, and then define the following in your `~/.zshrc`: + + POWERLEVEL9K_MODE='compatible' + +Note that depending on your terminal font, this may still not render +appropriately. This configuration should be used as a back-up. ### Segment Customization @@ -76,10 +228,12 @@ currently available are: * **context** - Your username and host (more info below) * **dir** - Your current working directory. * **history** - The command number for the current line. +* **node_version** - Show the version number of the installed Node.js. * **rbenv** - Ruby environment information (if one is active). * **rspec_stats** - Show a ratio of test classes vs code classes for RSpec. * **status** - The return code of the previous command, and status of background jobs. * **symfony2_tests** - Show a ratio of test classes vs code classes for Symfony2. +* **symfony2_version** - Show the current Symfony2 version, if you are in a Symfony2-Project dir. * **time** - System time. * **virtualenv** - Your Python [VirtualEnv](https://virtualenv.pypa.io/en/latest/). * **vcs** - Information about this `git` or `hg` repository (if you are in one). @@ -110,6 +264,14 @@ elements (it is by default), and define a `DEFAULT_USER` in your `~/.zshrc`: export DEFAULT_USER= +#### The 'dir' segment + +The `dir` segment shows the current working directory. You can limit the output +to a certain length: + + # Limit to the last two folders + POWERLEVEL9K_SHORTEN_DIR_LENGTH=2 + #### The 'time' segment By default the time is show in 'H:M:S' format. If you want to change it, @@ -133,26 +295,39 @@ By default, the `vcs` segment will provide quite a bit of information. If you would also like for it to display the current hash / changeset, simply define `POWERLEVEL9K_SHOW_CHANGESET` in your `~/.zshrc`. If activated, it will show the first 12 characters of the changeset id. To change the amount of characters, -set `POWERLEVEL9K_CHANGESET_HASH_LENTH` to any value you want. -Example: +set `POWERLEVEL9K_CHANGESET_HASH_LENGTH` to any value you want. # enable the vcs segment in general POWERLEVEL9K_SHOW_CHANGESET=true # just show the 6 first characters of changeset POWERLEVEL9K_CHANGESET_HASH_LENGTH=6 -##### Symbols +You can also disable the branch icon in your prompt by setting +`POWERLEVEL9K_HIDE_BRANCH_ICON` to `true`: -The `vcs` segment uses various symbols to tell you the state of your repository: + # Hide the branch icon + POWERLEVEL9K_HIDE_BRANCH_ICON=true + +##### Symbols -* `↑4` - The number of commits your repository is ahead of your remote branch -* `↓5` - The number of commits your repository is behind of your remote branch -* `⍟3` - The number of stashes, here 3. -* `●` - There are unstaged changes in your working copy -* `✚` - There are staged changes in your working copy -* `?` - There are files in your working copy, that are unknown to your repository -* `→` - The name of your branch differs from its tracking branch. -* `☿` - A mercurial bookmark is active. +The `vcs` segment uses various symbols to tell you the state of your repository. +These symbols depend on your installed font and selected `POWERLEVEL9K_MODE` +from the [Installation](#Installation) section above. + +| `Compatible` | `Powerline` | `Awesome Powerline` | Explanation +|--------------|---------------------|-------------------|-------------------------- +| `↑4` | `↑4` | ![icon_outgoing](https://cloud.githubusercontent.com/assets/1544760/7976089/b5904d6e-0a76-11e5-8147-5e873ac52d79.gif)4 | Number of commits your repository is ahead of your remote branch +| `↓5` | `↓5` | ![icon_incoming](https://cloud.githubusercontent.com/assets/1544760/7976091/b5909c9c-0a76-11e5-9cad-9bf0a28a897c.gif)5 | Number of commits your repository is behind of your remote branch +| `⍟3` | `⍟3` | ![icon_stash](https://cloud.githubusercontent.com/assets/1544760/7976094/b5ae9346-0a76-11e5-8cc7-e98b81824118.gif)3 | Number of stashes, here 3. +| `●` | `●` | ![icon_unstaged](https://cloud.githubusercontent.com/assets/1544760/7976096/b5aefa98-0a76-11e5-9408-985440471215.gif) | There are unstaged changes in your working copy +| `✚` | `✚` | ![icon_staged](https://cloud.githubusercontent.com/assets/1544760/7976095/b5aecc8a-0a76-11e5-8988-221afc6e8982.gif) | There are staged changes in your working copy +| `?` | `?` | ![icon_untracked](https://cloud.githubusercontent.com/assets/1544760/7976098/b5c7a2e6-0a76-11e5-8c5b-315b595b2bc4.gif) | There are files in your working copy, that are unknown to your repository +| `→` | `→` | ![icon_remote_tracking_branch](https://cloud.githubusercontent.com/assets/1544760/7976093/b5ad2c0e-0a76-11e5-9cd3-62a077b1b0c7.gif) | The name of your branch differs from its tracking branch. +| `☿` | `☿` | ![icon_bookmark](https://cloud.githubusercontent.com/assets/1544760/7976197/546cfac6-0a78-11e5-88a6-ce3a1e0a174e.gif) | A mercurial bookmark is active. +| `@` | ![icon_branch_powerline](https://cloud.githubusercontent.com/assets/1544760/8000852/e7e8d8a0-0b5f-11e5-9834-de9b25c92284.gif) | ![](https://cloud.githubusercontent.com/assets/1544760/7976087/b58bbe3e-0a76-11e5-8d0d-7a5c1bc7f730.gif) | Branch Icon +| None | None | ![icon_commit](https://cloud.githubusercontent.com/assets/1544760/7976088/b58f4e50-0a76-11e5-9e70-86450d937030.gif)2c3705 | The current commit hash. Here "2c3705" +| None | None | ![icon_git](https://cloud.githubusercontent.com/assets/1544760/7976092/b5909f80-0a76-11e5-9950-1438b9d72465.gif) | Repository is a git repository +| None | None | ![icon_mercurial](https://cloud.githubusercontent.com/assets/1544760/7976090/b5908da6-0a76-11e5-8c91-452b6e73f631.gif) | Repository is a Mercurial repository ### Styling @@ -171,6 +346,12 @@ Here is what it looks like: ![](http://bhilburn.org/content/images/2015/03/double-line.png) +You can customize the icons used to draw the multiline prompt by setting the +following variables in your `~/.zshrc`: + + POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX="↱" + POWERLEVEL9K_MULTILINE_SECOND_PROMPT_PREFIX="↳ " + #### Light Color Theme If you prefer to use "light" colors, simply set `POWERLEVEL9K_COLOR_SCHEME` @@ -183,20 +364,36 @@ Light'](https://github.com/altercation/solarized) users. Check it out: ![](http://bhilburn.org/content/images/2015/03/solarized-light.png) -#### Further color customizations +#### Segment Color Customization For each segment in your prompt, you can specify a foreground and background -color by setting them in your `~/.zshrc`. For example, to change the appearance -of the `time` segment, you would use: +color by setting them in your `~/.zshrc`. Use the segment names from the above +section `Segment Customization`. For example, to change the appearance of the +`time` segment, you would use: POWERLEVEL9K_TIME_FOREGROUND='red' POWERLEVEL9K_TIME_BACKGROUND='blue' -Use the segment names from the above section `Segment Customization`. Some of -the Segments have special color variables, as they change the colors according -to some internal rules. These Segments are `vcs`, `rspec_stats`, `symfony2_tests`: +Note that you can also use a colorcode value. Example: + + POWERLEVEL9K_VCS_FOREGROUND='021' # Dark blue + +For a full list of supported colors, run the `spectrum_ls` program in your +terminal. + +#### Special Segment Colors + +Some segments have additional color options if you want to customize the look of +your prompt even further. These Segments are `context`, `vcs`, `rspec_stats`, +`symfony2_tests`: - # General VCS color segments: + # Customizing `context` colors for root and non-root users + POWERLEVEL9K_CONTEXT_DEFAULT_BACKGROUND="green" + POWERLEVEL9K_CONTEXT_DEFAULT_FOREGROUND="cyan" + POWERLEVEL9K_CONTEXT_ROOT_BACKGROUND="red" + POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND="blue" + + # Advanced `vcs` color customization POWERLEVEL9K_VCS_FOREGROUND='blue' POWERLEVEL9K_VCS_DARK_FOREGROUND='black' POWERLEVEL9K_VCS_BACKGROUND='green' @@ -224,13 +421,6 @@ to some internal rules. These Segments are `vcs`, `rspec_stats`, `symfony2_tests POWERLEVEL9K_SYMFONY2_TESTS_BAD_FOREGROUND='red' POWERLEVEL9K_SYMFONY2_TESTS_BAD_BACKGROUND='white' -You could also use a colorcode value. Example: - - POWERLEVEL9K_VCS_FOREGROUND='021' # Dark blue - -For a full list of supported colors, run the `spectrum_ls` program in your -terminal. - ### Troubleshooting Here are some fixes to some common problems. @@ -245,14 +435,30 @@ Thankfully, this is easy to fix. This happens if you have successfully installed Powerline fonts, but did not make a Powerline font the default font in your terminal emulator (e.g., 'terminator', 'gnome-terminal', 'konsole', etc.,). -### Contributions / Bugs / Contact +### Meta + +#### Kudos + +This theme wouldn't have happened without inspiration from the original +[agnoster](https://gist.github.com/agnoster/3712874) Oh-My-ZSH theme. + +Before creating this theme, I also tried [jeremyFreeAgent's +theme](https://github.com/jeremyFreeAgent/oh-my-zsh-powerline-theme) and +[maverick2000's theme, ZSH2000](https://github.com/maverick2000/zsh2000). + +#### Developing + +Documentation for developers is kept on the [Powerlevel9k Github +wiki](https://github.com/bhilburn/powerlevel9k/wiki/Developer's-Guide). + +#### Contributions / Bugs / Contact If you have any requests or bug reports, please use the tracker in this Github repository. -I'm happy to accept code contributions from anyone who has an improvement! -Please submit your contribution as a Github pull-request. +I'm happy to accept code contributions from anyone who has a bug fix, new +feature, or just a general improvement! Please submit your contribution as +a Github pull-request. If you would like to contact me directly, you can find my e-mail address on my [Github profile page](https://github.com/bhilburn). - diff --git a/powerlevel9k.zsh-theme b/powerlevel9k.zsh-theme index 699a8195..d48b40b6 100644 --- a/powerlevel9k.zsh-theme +++ b/powerlevel9k.zsh-theme @@ -1,4 +1,4 @@ -# vim:ft=zsh ts=2 sw=2 sts=2 +# vim:ft=zsh ts=2 sw=2 sts=2 et fenc=utf-8 ################################################################ # powerlevel9k Theme # https://github.com/bhilburn/powerlevel9k @@ -8,9 +8,6 @@ # # The `vcs_info` hooks in this file are from Tom Upton: # https://github.com/tupton/dotfiles/blob/master/zsh/zshrc -# -# In order for this theme to render correctly, you will need a Powerline-patched font: -# https://github.com/Lokaltog/powerline-fonts ################################################################ ################################################################ @@ -43,6 +40,10 @@ # POWERLEVEL9K_COLOR_SCHEME='light' ################################################################ +## Debugging +#zstyle ':vcs_info:*+*:*' debug true +#set -o xtrace + # OS detection, default to Linux case $(uname) in FreeBSD) OS=FreeBSD ;; @@ -59,18 +60,135 @@ esac CURRENT_BG='NONE' # These characters require the Powerline fonts to work properly. If see boxes or -# bizarre characters below, your fonts are not correctly installed. -LEFT_SEGMENT_SEPARATOR='' -RIGHT_SEGMENT_SEPARATOR='' -VCS_UNSTAGED_ICON='●' -VCS_STAGED_ICON='✚' +# bizarre characters below, your fonts are not correctly installed. If you +# do not want to install a special font, you can set `POWERLEVEL9K_MODE` to +# `compatible`. This shows all icons in regular symbols. +case $POWERLEVEL9K_MODE in + 'flat') + # Awesome-Patched Font required! + # See https://github.com/gabrielelana/awesome-terminal-fonts/tree/patching-strategy/patched + LEFT_SEGMENT_SEPARATOR='' + RIGHT_SEGMENT_SEPARATOR='' + ROOT_ICON="\uE801" #  + RUBY_ICON="\uE847" #  + AWS_ICON="\uE895" #  + BACKGROUND_JOBS_ICON="\uE82F " #  + TEST_ICON="\uE891" #  + OK_ICON="\u2713" # ✓ + FAIL_ICON="\u2718" # ✘ + SYMFONY_ICON="SF" + VCS_UNTRACKED_ICON="\uE16C" #  + VCS_UNSTAGED_ICON="\uE17C" #  + VCS_STAGED_ICON="\uE168" #  + VCS_STASH_ICON="\uE133 " #  + #VCS_INCOMING_CHANGES="\uE1EB " #  + #VCS_INCOMING_CHANGES="\uE80D " #  + VCS_INCOMING_CHANGES="\uE131 " #  + #VCS_OUTGOING_CHANGES="\uE1EC " #  + #VCS_OUTGOING_CHANGES="\uE80E " #  + VCS_OUTGOING_CHANGES="\uE132 " #  + VCS_TAG_ICON="\uE817 " #  + VCS_BOOKMARK_ICON="\uE87B" #  + VCS_COMMIT_ICON="\uE821 " #  + VCS_BRANCH_ICON="\uE220" #  + VCS_REMOTE_BRANCH_ICON=" \uE804 " #  + VCS_GIT_ICON="\uE20E " #  + VCS_HG_ICON="\uE1C3 " #  + ;; + 'compatible') + LEFT_SEGMENT_SEPARATOR="\u2B80" # ⮀ + RIGHT_SEGMENT_SEPARATOR="\u2B82" # ⮂ + ROOT_ICON="\u26A1" # ⚡ + RUBY_ICON='' + AWS_ICON="AWS:" + BACKGROUND_JOBS_ICON="\u2699" # ⚙ + TEST_ICON='' + OK_ICON="\u2713" # ✓ + FAIL_ICON="\u2718" # ✘ + SYMFONY_ICON="SF" + VCS_UNTRACKED_ICON='?' + VCS_UNSTAGED_ICON="\u25CF" # ● + VCS_STAGED_ICON="\u271A" # ✚ + VCS_STASH_ICON="\u235F" # ⍟ + VCS_INCOMING_CHANGES="\u2193" # ↓ + VCS_OUTGOING_CHANGES="\u2191" # ↑ + VCS_TAG_ICON='' + VCS_BOOKMARK_ICON="\u263F" # ☿ + VCS_COMMIT_ICON='' + VCS_BRANCH_ICON='@' + VCS_REMOTE_BRANCH_ICON="\u2192" # → + VCS_GIT_ICON='Git' + VCS_HG_ICON='HG' + ;; + 'awesome-patched') + # Awesome-Patched Font required! + # See https://github.com/gabrielelana/awesome-terminal-fonts/tree/patching-strategy/patched + LEFT_SEGMENT_SEPARATOR="\uE0B0" #  + RIGHT_SEGMENT_SEPARATOR="\uE0B2" #  + ROOT_ICON="\u26A1" # ⚡ + RUBY_ICON="\uE847" #  + AWS_ICON="\uE895" #  + BACKGROUND_JOBS_ICON="\uE82F " #  + TEST_ICON="\uE891" #  + OK_ICON="\u2713" # ✓ + FAIL_ICON="\u2718" # ✘ + SYMFONY_ICON="SF" + VCS_UNTRACKED_ICON="\uE16C" #  + VCS_UNSTAGED_ICON="\uE17C" #  + VCS_STAGED_ICON="\uE168" #  + VCS_STASH_ICON="\uE133 " #  + #VCS_INCOMING_CHANGES="\uE1EB " #  + #VCS_INCOMING_CHANGES="\uE80D " #  + VCS_INCOMING_CHANGES="\uE131 " #  + #VCS_OUTGOING_CHANGES="\uE1EC " #  + #VCS_OUTGOING_CHANGES="\uE80E " #  + VCS_OUTGOING_CHANGES="\uE132 " #  + VCS_TAG_ICON="\uE817 " #  + VCS_BOOKMARK_ICON="\uE87B" #  + VCS_COMMIT_ICON="\uE821 " #  + VCS_BRANCH_ICON="\uE220" #  + VCS_REMOTE_BRANCH_ICON=" \uE804 " #  + VCS_GIT_ICON="\uE20E " #  + VCS_HG_ICON="\uE1C3 " #  + ;; + *) + # Powerline-Patched Font required! + # See https://github.com/Lokaltog/powerline-fonts + LEFT_SEGMENT_SEPARATOR="\uE0B0" #  + RIGHT_SEGMENT_SEPARATOR="\uE0B2" #  + ROOT_ICON="\u26A1" # ⚡ + RUBY_ICON='' + AWS_ICON="AWS:" + BACKGROUND_JOBS_ICON="\u2699" # ⚙ + TEST_ICON='' + OK_ICON="\u2713" # ✓ + FAIL_ICON="\u2718" # ✘ + SYMFONY_ICON="SF" + VCS_UNTRACKED_ICON='?' + VCS_UNSTAGED_ICON="\u25CF" # ● + VCS_STAGED_ICON="\u271A" # ✚ + VCS_STASH_ICON="\u235F" # ⍟ + VCS_INCOMING_CHANGES="\u2193" # ↓ + VCS_OUTGOING_CHANGES="\u2191" # ↑ + VCS_TAG_ICON='' + VCS_BOOKMARK_ICON="\u263F" # ☿ + VCS_COMMIT_ICON='' + VCS_BRANCH_ICON="\uE0A0 " #  + VCS_REMOTE_BRANCH_ICON="\u2192" # → + VCS_GIT_ICON="" + VCS_HG_ICON="" + ;; +esac + +if [[ "$POWERLEVEL9K_HIDE_BRANCH_ICON" == true ]]; then + VCS_BRANCH_ICON='' +fi ################################################################ # color scheme ################################################################ -local DEFAULT_COLOR DEFAULT_COLOR_INVERTED DEFAULT_COLOR_DARK -if [[ $POWERLEVEL9K_COLOR_SCHEME == "light" ]]; then +if [[ "$POWERLEVEL9K_COLOR_SCHEME" == "light" ]]; then DEFAULT_COLOR=white DEFAULT_COLOR_INVERTED=black DEFAULT_COLOR_DARK="252" @@ -80,8 +198,8 @@ else DEFAULT_COLOR_DARK="236" fi -local VCS_FOREGROUND_COLOR=$DEFAULT_COLOR -local VCS_FOREGROUND_COLOR_DARK=$DEFAULT_COLOR_DARK +VCS_FOREGROUND_COLOR=$DEFAULT_COLOR +VCS_FOREGROUND_COLOR_DARK=$DEFAULT_COLOR_DARK # If user has defined custom colors for the `vcs` segment, override the defaults if [[ -n $POWERLEVEL9K_VCS_FOREGROUND ]]; then @@ -98,31 +216,35 @@ fi setopt prompt_subst autoload -Uz vcs_info -local VCS_WORKDIR_DIRTY=false -local VCS_CHANGESET_PREFIX='' +VCS_WORKDIR_DIRTY=false +VCS_CHANGESET_PREFIX='' if [[ "$POWERLEVEL9K_SHOW_CHANGESET" == true ]]; then # Default: Just display the first 12 characters of our changeset-ID. local VCS_CHANGESET_HASH_LENGTH=12 - if [[ -n $POWERLEVEL9K_CHANGESET_HASH_LENGTH ]]; then - VCS_CHANGESET_HASH_LENGTH=$POWERLEVEL9K_CHANGESET_HASH_LENGTH + if [[ -n "$POWERLEVEL9K_CHANGESET_HASH_LENGTH" ]]; then + VCS_CHANGESET_HASH_LENGTH="$POWERLEVEL9K_CHANGESET_HASH_LENGTH" fi - VCS_CHANGESET_PREFIX="%F{$VCS_FOREGROUND_COLOR_DARK}%0.$VCS_CHANGESET_HASH_LENGTH""i@%f" + VCS_CHANGESET_PREFIX="%F{$VCS_FOREGROUND_COLOR_DARK}$VCS_COMMIT_ICON%0.$VCS_CHANGESET_HASH_LENGTH""i%f " fi zstyle ':vcs_info:*' enable git hg zstyle ':vcs_info:*' check-for-changes true -zstyle ':vcs_info:*' formats " $VCS_CHANGESET_PREFIX%F{$VCS_FOREGROUND_COLOR}%b%c%u%m%f" +VCS_DEFAULT_FORMAT="$VCS_CHANGESET_PREFIX%F{$VCS_FOREGROUND_COLOR}%b%c%u%m%f" +zstyle ':vcs_info:git:*' formats "%F{$VCS_FOREGROUND_COLOR}$VCS_GIT_ICON%f$VCS_DEFAULT_FORMAT" +zstyle ':vcs_info:hg:*' formats "%F{$VCS_FOREGROUND_COLOR}$VCS_HG_ICON%f$VCS_DEFAULT_FORMAT" + zstyle ':vcs_info:*' actionformats " %b %F{red}| %a%f" zstyle ':vcs_info:*' stagedstr " %F{$VCS_FOREGROUND_COLOR}$VCS_STAGED_ICON%f" zstyle ':vcs_info:*' unstagedstr " %F{$VCS_FOREGROUND_COLOR}$VCS_UNSTAGED_ICON%f" -zstyle ':vcs_info:git*+set-message:*' hooks git-untracked git-aheadbehind git-stash git-remotebranch git-tagname +zstyle ':vcs_info:git*+set-message:*' hooks vcs-detect-changes git-untracked git-aheadbehind git-stash git-remotebranch git-tagname +zstyle ':vcs_info:hg*+set-message:*' hooks vcs-detect-changes # For Hg, only show the branch name -zstyle ':vcs_info:hg*:*' branchformat "%b" +zstyle ':vcs_info:hg*:*' branchformat "$VCS_BRANCH_ICON%b" # The `get-revision` function must be turned on for dirty-check to work for Hg zstyle ':vcs_info:hg*:*' get-revision true zstyle ':vcs_info:hg*:*' get-bookmarks true @@ -130,23 +252,20 @@ zstyle ':vcs_info:hg*+gen-hg-bookmark-string:*' hooks hg-bookmarks if [[ "$POWERLEVEL9K_SHOW_CHANGESET" == true ]]; then zstyle ':vcs_info:*' get-revision true -else - # A little performance-boost for large repositories (especially Hg). If we - # don't show the changeset, we can switch to simple mode. - zstyle ':vcs_info:*' use-simple true fi -## Debugging -#zstyle ':vcs_info:*+*:*' debug true -#set -o xtrace - ################################################################ # Prompt Segment Constructors ################################################################ # Begin a left prompt segment -# Takes two arguments, background and foreground. Both can be omitted, -# rendering default background/foreground. +# Takes four arguments: +# * $1: Name of the function that was orginally invoked (mandatory). +# Necessary, to make the dynamic color-overwrite mechanism work. +# * $2: Background color +# * $3: Foreground color +# * $4: The segment content +# The latter three can be omitted, left_prompt_segment() { # Overwrite given background-color by user defined variable for this segment. # We get as first Parameter the function name, which called this function. @@ -167,29 +286,35 @@ left_prompt_segment() { [[ -n $2 ]] && bg="%K{$2}" || bg="%k" [[ -n $3 ]] && fg="%F{$3}" || fg="%f" if [[ $CURRENT_BG != 'NONE' && $2 != $CURRENT_BG ]]; then + # Middle segment echo -n "%{$bg%F{$CURRENT_BG}%}$LEFT_SEGMENT_SEPARATOR%{$fg%} " else + # First segment echo -n "%{$bg%}%{$fg%} " fi CURRENT_BG=$2 - [[ -n $4 ]] && echo -n $4 + [[ -n $4 ]] && echo -n "$4 " } # End the left prompt, closing any open segments left_prompt_end() { if [[ -n $CURRENT_BG ]]; then - echo -n " %{%k%F{$CURRENT_BG}%}$LEFT_SEGMENT_SEPARATOR" + echo -n "%{%k%F{$CURRENT_BG}%}$LEFT_SEGMENT_SEPARATOR" else - echo -n " %{%k%}" + echo -n "%{%k%}" fi - echo -n "%{%f%}" + echo -n "%{%f%} " CURRENT_BG='' } # Begin a right prompt segment -# Takes two arguments, background and foreground. Both can be omitted, -# rendering default background/foreground. No ending for the right prompt -# segment is needed (unlike the left prompt, above). +# Takes four arguments: +# * $1: Name of the function that was orginally invoked (mandatory). +# Necessary, to make the dynamic color-overwrite mechanism work. +# * $2: Background color +# * $3: Foreground color +# * $4: The segment content +# No ending for the right prompt segment is needed (unlike the left prompt, above). right_prompt_segment() { # Overwrite given background-color by user defined variable for this segment. local BACKGROUND_USER_VARIABLE=POWERLEVEL9K_${(U)1#prompt_}_BACKGROUND @@ -204,8 +329,8 @@ right_prompt_segment() { local bg fg [[ -n $2 ]] && bg="%K{$2}" || bg="%k" [[ -n $3 ]] && fg="%F{$3}" || fg="%f" - echo -n " %f%F{$2}$RIGHT_SEGMENT_SEPARATOR%f%{$bg%}%{$fg%} " - [[ -n $4 ]] && echo -n $4 + echo -n "%f%F{$2}$RIGHT_SEGMENT_SEPARATOR%f%{$bg%}%{$fg%} " + [[ -n $4 ]] && echo -n "$4 " } ################################################################ @@ -214,21 +339,21 @@ right_prompt_segment() { prompt_vcs() { local vcs_prompt="${vcs_info_msg_0_}" - if [[ -n $vcs_prompt ]]; then + if [[ -n "$vcs_prompt" ]]; then if [[ "$VCS_WORKDIR_DIRTY" == true ]]; then - $1_prompt_segment $0_MODIFIED yellow $DEFAULT_COLOR + $1_prompt_segment "$0_MODIFIED" "yellow" "$DEFAULT_COLOR" else - $1_prompt_segment $0 green $DEFAULT_COLOR + $1_prompt_segment "$0" "green" "$DEFAULT_COLOR" fi - echo -n "%F{$VCS_FOREGROUND_COLOR}%f$vcs_prompt" + echo -n "%F{$VCS_FOREGROUND_COLOR}%f$vcs_prompt " fi } function +vi-git-untracked() { if [[ $(git rev-parse --is-inside-work-tree 2> /dev/null) == 'true' && \ - $(git ls-files --others --exclude-standard | sed q | wc -l | tr -d ' ') != 0 ]]; then - hook_com[unstaged]+=" %F{$VCS_FOREGROUND_COLOR}?%f" + ${$(git ls-files --others --exclude-standard | sed q | wc -l)// /} != 0 ]]; then + hook_com[unstaged]+=" %F{$VCS_FOREGROUND_COLOR}$VCS_UNTRACKED_ICON%f" fi } @@ -240,13 +365,13 @@ function +vi-git-aheadbehind() { # for git prior to 1.7 # ahead=$(git rev-list origin/${branch_name}..HEAD | wc -l) - ahead=$(git rev-list ${branch_name}@{upstream}..HEAD 2>/dev/null | wc -l | tr -d ' ') - (( $ahead )) && gitstatus+=( " %F{$VCS_FOREGROUND_COLOR}↑${ahead// /}%f" ) + ahead=$(git rev-list ${branch_name}@{upstream}..HEAD 2>/dev/null | wc -l) + (( $ahead )) && gitstatus+=( " %F{$VCS_FOREGROUND_COLOR}$VCS_OUTGOING_CHANGES${ahead// /}%f" ) # for git prior to 1.7 # behind=$(git rev-list HEAD..origin/${branch_name} | wc -l) - behind=$(git rev-list HEAD..${branch_name}@{upstream} 2>/dev/null | wc -l | tr -d ' ') - (( $behind )) && gitstatus+=( " %F{$VCS_FOREGROUND_COLOR}↓${behind// /}%f" ) + behind=$(git rev-list HEAD..${branch_name}@{upstream} 2>/dev/null | wc -l) + (( $behind )) && gitstatus+=( " %F{$VCS_FOREGROUND_COLOR}$VCS_INCOMING_CHANGES${behind// /}%f" ) hook_com[misc]+=${(j::)gitstatus} } @@ -258,12 +383,12 @@ function +vi-git-remotebranch() { remote=${$(git rev-parse --verify HEAD@{upstream} --symbolic-full-name 2>/dev/null)/refs\/(remotes|heads)\/} branch_name=${$(git symbolic-ref --short HEAD 2>/dev/null)} - hook_com[branch]="%F{$VCS_FOREGROUND_COLOR}${hook_com[branch]}%f" + hook_com[branch]="%F{$VCS_FOREGROUND_COLOR}$VCS_BRANCH_ICON${hook_com[branch]}%f" # Always show the remote #if [[ -n ${remote} ]] ; then # Only show the remote if it differs from the local if [[ -n ${remote} && ${remote#*/} != ${branch_name} ]] ; then - hook_com[branch]+="%F{$VCS_FOREGROUND_COLOR}→%f%F{$VCS_FOREGROUND_COLOR}${remote// /}%f" + hook_com[branch]+="%F{$VCS_FOREGROUND_COLOR}$VCS_REMOTE_BRANCH_ICON%f%F{$VCS_FOREGROUND_COLOR}${remote// /}%f" fi } @@ -271,7 +396,7 @@ function +vi-git-tagname() { local tag tag=$(git describe --tags --exact-match HEAD 2>/dev/null) - [[ -n ${tag} ]] && hook_com[branch]=" %F{$VCS_FOREGROUND_COLOR}${tag}%f" + [[ -n "${tag}" ]] && hook_com[branch]=" %F{$VCS_FOREGROUND_COLOR}$VCS_TAG_ICON${tag}%f" } # Show count of stashed changes @@ -281,13 +406,13 @@ function +vi-git-stash() { if [[ -s $(git rev-parse --git-dir)/refs/stash ]] ; then stashes=$(git stash list 2>/dev/null | wc -l) - hook_com[misc]+=" %F{$VCS_FOREGROUND_COLOR}⍟${stashes// /}%f" + hook_com[misc]+=" %F{$VCS_FOREGROUND_COLOR}$VCS_STASH_ICON${stashes// /}%f" fi } function +vi-hg-bookmarks() { if [[ -n "${hgbmarks[@]}" ]]; then - hook_com[hg-bookmark-string]=" ☿ ${hgbmarks[@]}" + hook_com[hg-bookmark-string]=" %F{$VCS_FOREGROUND_COLOR}$VCS_BOOKMARK_ICON${hgbmarks[@]}%f" # And to signal, that we want to use the sting we just generated, # set the special variable `ret' to something other than the default @@ -298,7 +423,7 @@ function +vi-hg-bookmarks() { } function +vi-vcs-detect-changes() { - if [[ -n ${hook_com[staged]} ]] || [[ -n ${hook_com[unstaged]} ]]; then + if [[ -n "${hook_com[staged]}" ]] || [[ -n "${hook_com[unstaged]}" ]]; then VCS_WORKDIR_DIRTY=true else VCS_WORKDIR_DIRTY=false @@ -309,12 +434,17 @@ function +vi-vcs-detect-changes() { # Prompt Segments ################################################################ +# The `CURRENT_BG` variable is used to remember what the last BG color used was +# when building the left-hand prompt. Because the RPROMPT is created from +# right-left but reads the opposite, this isn't necessary for the other side. +CURRENT_BG='NONE' + # AWS Profile prompt_aws() { - local aws_profile=$AWS_DEFAULT_PROFILE - if [[ -n $aws_profile ]]; + local aws_profile="$AWS_DEFAULT_PROFILE" + if [[ -n "$aws_profile" ]]; then - $1_prompt_segment $0 red white "AWS: $aws_profile" + $1_prompt_segment "$0" red white "$AWS_ICON $aws_profile" fi } @@ -322,18 +452,29 @@ prompt_aws() { # Note that if $DEFAULT_USER is not set, this prompt segment will always print prompt_context() { if [[ "$USER" != "$DEFAULT_USER" || -n "$SSH_CLIENT" ]]; then - $1_prompt_segment $0 $DEFAULT_COLOR "011" "%(!.%{%F{yellow}%}.)$USER@%m" + if [[ $(print -P "%#") == '#' ]]; then + # Shell runs as root + $1_prompt_segment "$0_ROOT" "$DEFAULT_COLOR" "yellow" "$USER@%m" + else + $1_prompt_segment "$0_DEFAULT" "$DEFAULT_COLOR" "011" "$USER@%m" + fi fi } # Dir: current working directory prompt_dir() { - $1_prompt_segment $0 blue $DEFAULT_COLOR '%~' + local current_path='%~' + if [[ -n "$POWERLEVEL9K_SHORTEN_DIR_LENGTH" ]]; then + # shorten path to $POWERLEVEL9K_SHORTEN_DIR_LENGTH + current_path="%$((POWERLEVEL9K_SHORTEN_DIR_LENGTH+1))(c:.../:)%${POWERLEVEL9K_SHORTEN_DIR_LENGTH}c" + fi + + $1_prompt_segment "$0" "blue" "$DEFAULT_COLOR" "$current_path" } # Command number (in local history) prompt_history() { - $1_prompt_segment $0 "244" $DEFAULT_COLOR '%h' + $1_prompt_segment "$0" "244" "$DEFAULT_COLOR" '%h' } # Right Status: (return code, root status, background jobs) @@ -343,18 +484,27 @@ prompt_longstatus() { local symbols bg symbols=() - if [[ $RETVAL -ne 0 ]]; then - symbols+="%{%F{"226"}%}%? ↵" + if [[ "$RETVAL" -ne 0 ]]; then + symbols+="%F{226}%? ↵" bg="009" else - symbols+="%{%F{"046"}%}✓" + symbols+="%{%F{"046"}%}$OK_ICON" bg="008" fi - [[ $UID -eq 0 ]] && symbols+="%{%F{yellow}%}⚡" - [[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{cyan}%}⚙" + [[ "$UID" -eq 0 ]] && symbols+="%{%F{yellow}%} $ROOT_ICON" + [[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{cyan}%}$BACKGROUND_JOBS_ICON" + + [[ -n "$symbols" ]] && $1_prompt_segment "$0" "$bg" "$DEFAULT_COLOR" "$symbols" +} + +# Node version +prompt_node_version() { + local nvm_prompt=$(node -v 2>/dev/null) + [[ -z "${nvm_prompt}" ]] && return + NODE_ICON=$'\u2B22' # ⬢ - [[ -n "$symbols" ]] && $1_prompt_segment $0 $bg $DEFAULT_COLOR "$symbols" + $1_prompt_segment "$0" "green" "white" "${nvm_prompt:1} $NODE_ICON" } # print a little OS icon @@ -373,7 +523,7 @@ prompt_os_icon() { # rbenv information prompt_rbenv() { if [[ -n "$RBENV_VERSION" ]]; then - $1_prompt_segment $0 red $DEFAULT_COLOR "$RBENV_VERSION" + $1_prompt_segment "$0" "red" "$DEFAULT_COLOR" "$RBENV_VERSION" fi } @@ -383,7 +533,7 @@ prompt_rspec_stats() { local code_amount=$(ls -1 app/**/*.rb | wc -l) local tests_amount=$(ls -1 spec/**/*.rb | wc -l) - build_test_stats $1 $0 $code_amount $tests_amount "RSpec" + build_test_stats "$1" $0 "$code_amount" $tests_amount "RSpec $TEST_ICON" fi } @@ -392,7 +542,7 @@ prompt_rvm() { local rvm_prompt rvm_prompt=`rvm-prompt` if [ "$rvm_prompt" != "" ]; then - $1_prompt_segment $0 "240" $DEFAULT_COLOR "$rvm_prompt " + $1_prompt_segment "$0" "240" "$DEFAULT_COLOR" "$rvm_prompt $RUBY_ICON " fi } @@ -401,11 +551,11 @@ prompt_rvm() { prompt_status() { local symbols symbols=() - [[ $RETVAL -ne 0 ]] && symbols+="%{%F{red}%}✘" - [[ $UID -eq 0 ]] && symbols+="%{%F{yellow}%}⚡" - [[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{cyan}%}⚙" + [[ "$RETVAL" -ne 0 ]] && symbols+="%{%F{red}%}$FAIL_ICON" + [[ "$UID" -eq 0 ]] && symbols+="%{%F{yellow}%} $ROOT_ICON" + [[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{cyan}%}$BACKGROUND_JOBS_ICON" - [[ -n "$symbols" ]] && $1_prompt_segment $0 $DEFAULT_COLOR default "$symbols" + [[ -n "$symbols" ]] && $1_prompt_segment "$0" "$DEFAULT_COLOR" "default" "$symbols" } # Symfony2-PHPUnit test ratio @@ -414,33 +564,41 @@ prompt_symfony2_tests() { local code_amount=$(ls -1 src/**/*.php | grep -v Tests | wc -l) local tests_amount=$(ls -1 src/**/*.php | grep Tests | wc -l) - build_test_stats $1 $0 $code_amount $tests_amount "SF2-Tests" + build_test_stats "$1" "$0" "$code_amount" "$tests_amount" "SF2 $TEST_ICON" + fi +} + +# Symfony2-Version +prompt_symfony2_version() { + if [[ -f app/bootstrap.php.cache ]]; then + local symfony2_version=$(grep " VERSION " app/bootstrap.php.cache | sed -e 's/[^.0-9]*//g') + $1_prompt_segment "$0" "240" "$DEFAULT_COLOR" "$SYMFONY_ICON $symfony2_version" fi } # Show a ratio of tests vs code build_test_stats() { - local code_amount=$3 - local tests_amount=$4+0.00001 - local headline=$5 + local code_amount="$3" + local tests_amount="$4"+0.00001 + local headline="$5" # Set float precision to 2 digits: typeset -F 2 ratio local ratio=$(( (tests_amount/code_amount) * 100 )) - [[ ratio -ge 0.75 ]] && $1_prompt_segment ${2}_GOOD cyan $DEFAULT_COLOR "$headline: $ratio%%" - [[ ratio -ge 0.5 && ratio -lt 0.75 ]] && $1_prompt_segment $2_AVG yellow $DEFAULT_COLOR "$headline: $ratio%%" - [[ ratio -lt 0.5 ]] && $1_prompt_segment $2_BAD red $DEFAULT_COLOR "$headline: $ratio%%" + [[ ratio -ge 0.75 ]] && $1_prompt_segment "${2}_GOOD" "cyan" "$DEFAULT_COLOR" "$headline: $ratio%%" + [[ ratio -ge 0.5 && ratio -lt 0.75 ]] && $1_prompt_segment "$2_AVG" "yellow" "$DEFAULT_COLOR" "$headline: $ratio%%" + [[ ratio -lt 0.5 ]] && $1_prompt_segment "$2_BAD" "red" "$DEFAULT_COLOR" "$headline: $ratio%%" } # System time prompt_time() { - local time_format='%D{%H:%M:%S}' - if [[ -n $POWERLEVEL9K_TIME_FORMAT ]]; then - time_format=$POWERLEVEL9K_TIME_FORMAT + local time_format="%D{%H:%M:%S}" + if [[ -n "$POWERLEVEL9K_TIME_FORMAT" ]]; then + time_format="$POWERLEVEL9K_TIME_FORMAT" fi - $1_prompt_segment $0 $DEFAULT_COLOR_INVERTED $DEFAULT_COLOR "$time_format " + $1_prompt_segment "$0" "$DEFAULT_COLOR_INVERTED" "$DEFAULT_COLOR" "$time_format" } # Virtualenv: current working virtualenv @@ -448,8 +606,8 @@ prompt_time() { # https://virtualenv.pypa.io/en/latest/ prompt_virtualenv() { local virtualenv_path="$VIRTUAL_ENV" - if [[ -n $virtualenv_path && -n $VIRTUAL_ENV_DISABLE_PROMPT ]]; then - $1_prompt_segment $0 blue $DEFAULT_COLOR "(`basename $virtualenv_path`)" + if [[ -n "$virtualenv_path" && -n "$VIRTUAL_ENV_DISABLE_PROMPT" ]]; then + $1_prompt_segment "$0" "blue" "$DEFAULT_COLOR" "(`basename $virtualenv_path`)" fi } @@ -459,7 +617,7 @@ prompt_virtualenv() { # Main prompt build_left_prompt() { - if [[ ${#POWERLEVEL9K_LEFT_PROMPT_ELEMENTS} == 0 ]]; then + if [[ "${#POWERLEVEL9K_LEFT_PROMPT_ELEMENTS}" == 0 ]]; then POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(context dir rbenv vcs) fi @@ -474,7 +632,7 @@ build_left_prompt() { build_right_prompt() { RETVAL=$? - if [[ ${#POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS} == 0 ]]; then + if [[ "${#POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS}" == 0 ]]; then POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(longstatus history time) fi @@ -483,25 +641,39 @@ build_right_prompt() { done } -precmd() { - vcs_info +powerlevel9k_init() { + setopt LOCAL_OPTIONS + unsetopt XTRACE KSH_ARRAYS + prompt_opts=(cr percent subst) + + # initialize colors + autoload -U colors && colors + + # initialize VCS + autoload -Uz add-zsh-hook + + add-zsh-hook precmd vcs_info + + if [[ "$POWERLEVEL9K_PROMPT_ON_NEWLINE" == true ]]; then + [[ -n $POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX ]] || POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX="╭─" + [[ -n $POWERLEVEL9K_MULTILINE_SECOND_PROMPT_PREFIX ]] || POWERLEVEL9K_MULTILINE_SECOND_PROMPT_PREFIX="╰─ " + + PROMPT="$POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX%{%f%b%k%}"'$(build_left_prompt)'" +$POWERLEVEL9K_MULTILINE_SECOND_PROMPT_PREFIX" + # The right prompt should be on the same line as the first line of the left + # prompt. To do so, there is just a quite ugly workaround: Before zsh draws + # the RPROMPT, we advise it, to go one line up. At the end of RPROMPT, we + # advise it to go one line down. See: + # http://superuser.com/questions/357107/zsh-right-justify-in-ps1 + RPROMPT_PREFIX='%{'$'\e[1A''%}' # one line up + RPROMPT_SUFFIX='%{'$'\e[1B''%}' # one line down + else + PROMPT="%{%f%b%k%}"'$(build_left_prompt)' + RPROMPT_PREFIX='' + RPROMPT_SUFFIX='' + fi + RPROMPT=$RPROMPT_PREFIX"%{%f%b%k%}"'$(build_right_prompt)'"%{$reset_color%}"$RPROMPT_SUFFIX - # Add a static hook to examine staged/unstaged changes. - vcs_info_hookadd set-message vcs-detect-changes } -if [[ "$POWERLEVEL9K_PROMPT_ON_NEWLINE" == true ]]; then - PROMPT='╭─%{%f%b%k%}$(build_left_prompt) -╰─ ' - # The right prompt should be on the same line as the first line of the left prompt. - # To do so, there is just a quite ugly workaround: Before zsh draws the RPROMPT, - # we advise it, to go one line up. At the end of RPROMPT, we advise it to go one - # line down. See http://superuser.com/questions/357107/zsh-right-justify-in-ps1 - RPROMPT_PREFIX='%{'$'\e[1A''%}' # one line up - RPROMPT_SUFFIX='%{'$'\e[1B''%}' # one line down -else - PROMPT='%{%f%b%k%}$(build_left_prompt) ' - RPROMPT_PREFIX='' - RPROMPT_SUFFIX='' -fi -RPROMPT=$RPROMPT_PREFIX'%{%f%b%k%}$(build_right_prompt)%{$reset_color%}'$RPROMPT_SUFFIX +powerlevel9k_init "$@" diff --git a/test-vm/README.md b/test-vm/README.md new file mode 100644 index 00000000..9f0861e9 --- /dev/null +++ b/test-vm/README.md @@ -0,0 +1,25 @@ +# Test-VM for powerlevel9k + +In this virtual machine you will find a recent ubuntu with preinstalled ZSH, oh-my-zsh, antigen, prezto and - of course - powerlevel9k. The main use-case is to test the powerlevel9k theme. + +## Installation + +In order to run this virtual machine, you need [vagrant](https://www.vagrantup.com/) and [VirtualBox](http://www.virtualbox.org/). + +## Running + +`vagrant` is a quite easy to use command line tool to configure a virtual machine. To fire the machine up, just run `vagrant up`. At the first run, it will install a whole ubuntu. With `vagrant ssh` you can log in into the machine. + +## Testing + +Once you have SSH'd into the machine, you'll see a plain ZSH. To test the other frameworks, you just have to switch to one of the following users: + + * `vagrant-antigen` + * `vagrant-prezto` + * `vagrant-omz` + +To switch use `sudo -i -H -u `. `-i` stands for "simulate initial login", `-H` sets the "$HOME" variable to the directory of the user , `-u` for the username. + +All users have `vagrant` as password and are in the /etc/sudoers. + +The regular `vagrant` user has a plain ZSH with the powerlevel9k theme. diff --git a/test-vm/Vagrantfile b/test-vm/Vagrantfile new file mode 100644 index 00000000..ee53fcdf --- /dev/null +++ b/test-vm/Vagrantfile @@ -0,0 +1,82 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# All Vagrant configuration is done below. The "2" in Vagrant.configure +# configures the configuration version (we support older styles for +# backwards compatibility). Please don't change it unless you know what +# you're doing. +Vagrant.configure(2) do |config| + # The most common configuration options are documented and commented below. + # For a complete reference, please see the online documentation at + # https://docs.vagrantup.com. + + # Every Vagrant development environment requires a box. You can search for + # boxes at https://atlas.hashicorp.com/search. + config.vm.box = "ubuntu/precise64" + + # Bootstrap + config.vm.provision :shell, path: "bootstrap.sh", privileged: false + config.vm.provision :shell, path: "plain.sh", privileged: false + config.vm.provision :shell, path: "antigen.sh" + config.vm.provision :shell, path: "prezto.sh" + config.vm.provision :shell, path: "omz.sh" + + # Disable automatic box update checking. If you disable this, then + # boxes will only be checked for updates when the user runs + # `vagrant box outdated`. This is not recommended. + # config.vm.box_check_update = false + + # Create a forwarded port mapping which allows access to a specific port + # within the machine from a port on the host machine. In the example below, + # accessing "localhost:8080" will access port 80 on the guest machine. + # config.vm.network "forwarded_port", guest: 80, host: 8080 + + # Create a private network, which allows host-only access to the machine + # using a specific IP. + # config.vm.network "private_network", ip: "192.168.33.10" + + # Create a public network, which generally matched to bridged network. + # Bridged networks make the machine appear as another physical device on + # your network. + # config.vm.network "public_network" + + # Share an additional folder to the guest VM. The first argument is + # the path on the host to the actual folder. The second argument is + # the path on the guest to mount the folder. And the optional third + # argument is a set of non-required options. + config.vm.synced_folder "..", "/vagrant_data" + + # Provider-specific configuration so you can fine-tune various + # backing providers for Vagrant. These expose provider-specific options. + # Example for VirtualBox: + + config.vm.provider "virtualbox" do |vb| + + # Change name to "powerlevel9k" + vb.name = "powerlevel9k" + + # Display the VirtualBox GUI when booting the machine + #vb.gui = true + + # Customize the amount of memory on the VM: + vb.memory = "256" + end + # + # View the documentation for the provider you are using for more + # information on available options. + + # Define a Vagrant Push strategy for pushing to Atlas. Other push strategies + # such as FTP and Heroku are also available. See the documentation at + # https://docs.vagrantup.com/v2/push/atlas.html for more information. + # config.push.define "atlas" do |push| + # push.app = "YOUR_ATLAS_USERNAME/YOUR_APPLICATION_NAME" + # end + + # Enable provisioning with a shell script. Additional provisioners such as + # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the + # documentation for more information about their specific syntax and use. + # config.vm.provision "shell", inline: <<-SHELL + # sudo apt-get update + # sudo apt-get install -y apache2 + # SHELL +end diff --git a/test-vm/antigen.sh b/test-vm/antigen.sh new file mode 100644 index 00000000..0f44c6ca --- /dev/null +++ b/test-vm/antigen.sh @@ -0,0 +1,27 @@ +#!/usr/bin/zsh +# We need to run this script in ZSH, so that switching user works! +NEW_USER=vagrant-antigen +# Create User +PASSWORD='$6$OgLg9v2Z$Db38Jr9inZG7y8BzL8kqFK23fF5jZ7FU1oiIBLFjNYR9XVX03fwQayMgA6Rm1rzLbXaf.gkZaTWhB9pv5XLq11' +useradd -p $PASSWORD -g vagrant -s $(which zsh) -m $NEW_USER +echo "$NEW_USER ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/$NEW_USER +chmod 440 /etc/sudoers.d/$NEW_USER + +( + # Change User (See http://unix.stackexchange.com/questions/86778/why-cant-we-execute-a-list-of-commands-as-different-user-without-sudo) + USERNAME=$NEW_USER + #UID=$(id -u $NEW_USER) + #EUID=$(id -u $NEW_USER) + HOME=/home/$NEW_USER + + echo " +source ~/antigen/antigen.zsh\n +antigen theme /vagrant_data powerlevel9k --no-local-clone\n +antigen apply +" > ~/.zshrc + + # install antigen + mkdir ~/antigen + curl -qL https://raw.githubusercontent.com/zsh-users/antigen/master/antigen.zsh > ~/antigen/antigen.zsh + source ~/antigen/antigen.zsh +) diff --git a/test-vm/bootstrap.sh b/test-vm/bootstrap.sh new file mode 100644 index 00000000..9651c4eb --- /dev/null +++ b/test-vm/bootstrap.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +#sudo apt-get update + +sudo apt-get install -y curl +sudo apt-get install -y git + +sudo apt-get install -y zsh +sudo chsh -s $(which zsh) vagrant diff --git a/test-vm/omz.sh b/test-vm/omz.sh new file mode 100644 index 00000000..953f5c8f --- /dev/null +++ b/test-vm/omz.sh @@ -0,0 +1,31 @@ +#!/usr/bin/zsh +# We need to run this script in ZSH, so that switching user works! +NEW_USER=vagrant-omz +# Create User +PASSWORD='$6$OgLg9v2Z$Db38Jr9inZG7y8BzL8kqFK23fF5jZ7FU1oiIBLFjNYR9XVX03fwQayMgA6Rm1rzLbXaf.gkZaTWhB9pv5XLq11' +useradd -p $PASSWORD -g vagrant -s $(which zsh) -m $NEW_USER +echo "$NEW_USER ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/$NEW_USER +chmod 440 /etc/sudoers.d/$NEW_USER + +( + # Change User (See http://unix.stackexchange.com/questions/86778/why-cant-we-execute-a-list-of-commands-as-different-user-without-sudo) + USERNAME=$NEW_USER + #UID=$(id -u $NEW_USER) + #EUID=$(id -u $NEW_USER) + HOME=/home/$NEW_USER + SHELL=$(which zsh) + + sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" + + mkdir -p ~/.oh-my-zsh/custom/themes + ln -s /vagrant_data ~/.oh-my-zsh/custom/themes/powerlevel9k + + echo ' +export ZSH=$HOME/.oh-my-zsh +ZSH_THEME="powerlevel9k/powerlevel9k" +plugins=(git rake ruby) + +source $ZSH/oh-my-zsh.sh +' > $HOME/.zshrc + +) diff --git a/test-vm/plain.sh b/test-vm/plain.sh new file mode 100644 index 00000000..9c8445f4 --- /dev/null +++ b/test-vm/plain.sh @@ -0,0 +1,3 @@ +#!/usr/bin/zsh + +echo 'source /vagrant_data/powerlevel9k.zsh-theme' > ~/.zshrc diff --git a/test-vm/prezto.sh b/test-vm/prezto.sh new file mode 100644 index 00000000..af4e7454 --- /dev/null +++ b/test-vm/prezto.sh @@ -0,0 +1,26 @@ +#!/usr/bin/zsh +# We need to run this script in ZSH, so that switching user works! +NEW_USER=vagrant-prezto +# Create User +PASSWORD='$6$OgLg9v2Z$Db38Jr9inZG7y8BzL8kqFK23fF5jZ7FU1oiIBLFjNYR9XVX03fwQayMgA6Rm1rzLbXaf.gkZaTWhB9pv5XLq11' +useradd -p $PASSWORD -g vagrant -s $(which zsh) -m $NEW_USER +echo "$NEW_USER ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/$NEW_USER +chmod 440 /etc/sudoers.d/$NEW_USER + +( + # Change User (See http://unix.stackexchange.com/questions/86778/why-cant-we-execute-a-list-of-commands-as-different-user-without-sudo) + USERNAME=$NEW_USER + #UID=$(id -u $NEW_USER) + #EUID=$(id -u $NEW_USER) + HOME=/home/$NEW_USER + + git clone --recursive https://github.com/sorin-ionescu/prezto.git "${ZDOTDIR:-$HOME}/.zprezto" + + setopt EXTENDED_GLOB + for rcfile in "${ZDOTDIR:-$HOME}"/.zprezto/runcoms/^README.md(.N); do + ln -s "$rcfile" "${ZDOTDIR:-$HOME}/.${rcfile:t}" + done + + ln -s /vagrant_data/powerlevel9k.zsh-theme ~/.zprezto/modules/prompt/functions/prompt_powerlevel9k_setup + sed -i "s/theme\ 'sorin'/theme\ 'powerlevel9k'/g" ~/.zpreztorc +)