diff --git a/CHANGELOG.md b/CHANGELOG.md index 557f977b..7a3f7444 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ -## v0.4.0 (next) +## v0.4.0 + +### Development changes + +From now on, development makes use of a CI system "travis". ### `vcs` changes @@ -10,14 +14,68 @@ POWERLEVEL9K_VCS_CLEAN_FOREGROUND='cyan' POWERLEVEL9K_VCS_CLEAN_BACKGROUND='white' ``` -### `aws_eb_env` added +Additionaly the vcs segment now has an `untracked` state which +indicates that you have untracked files in your repository. -This segment displays the current Elastic Beanstalk environment. +The foreground color of actionformat is now configurable via: +```zsh +POWERLEVEL9K_VCS_ACTIONFORMAT_FOREGROUND='green' +``` + +Also, the vcs segment uses the foreground color it was configured to. +That said, the variables `POWERLEVEL9K_VCS_FOREGROUND` and +`POWERLEVEL9K_VCS_DARK_FOREGROUND` are no longer used. Instead use +the proper variable `POWERLEVEL9K_VCS__FOREGROUND` to change +foreground color. + +### `dir` Shortening Strategies + +There is now a path shortening strategy that will use the `package.json` file to +shorten your directory path. See the documentation for the `dir` segment for more +details. + +Also, the shorten delimiter was changed to an unicode ellipsis. It is configurable +via `POWERLEVEL9K_SHORTEN_DELIMITER`. + +### `rbenv` changes + +The `rbenv` segment now makes use of the full rbenv command, so the correct +ruby version is now shown if it differs from the globally one. + +### `node`, `nvm` Segments + +Improvements to speed / reliability. ### `ram` changes -The `ram` segment was split up into `ram` and `swap`. The `POWERLEVEL9K_RAM_ELEMENTS` -variable is void. +The `ram` segment was split up into `ram` and `swap`. The +`POWERLEVEL9K_RAM_ELEMENTS` variable is obsolete. + +### New segment `swap` added + +Due to the split up of the ram segment, this one was created. It +shows the currently used swap size. + +### New segment `nodeenv` added + +Added new `nodeenv` segment that shows the currently used node environment. + +### New segment `aws_eb_env` added + +This segment displays the current Elastic Beanstalk environment. + +### New segment `chruby` added + +Added new `chruby` segment to support this version manager. + +### New segment `docker_machine` added + +Added new `docker_machine` segment that will show your Docker machine. + +### New segment `anaconda` added + +A new segment `anaconda` was added that shows the current used +anaconda environment. ## v0.3.2 diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..5466ba8d --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2014-2016 Ben Hilburn + +MIT LICENSE + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index f9e48b05..8cdf7be2 100644 --- a/README.md +++ b/README.md @@ -83,37 +83,78 @@ your `~/.zshrc`: #### Available Prompt Segments The segments that are currently available are: -* [aws](#aws) - The current AWS profile, if active. -* **aws_eb_env** - The current Elastic Beanstalk Environment. -* [background_jobs](#background_jobs) - Indicator for background jobs. -* [battery](#battery) - Current battery status. -* [context](#context) - Your username and host. -* [custom_command](#custom_command) - A custom command to display the output of. -* [dir](#dir) - Your current working directory. -* **go_version** - Show the current GO version. -* **history** - The command number for the current line. -* [ip](#ip) - Shows the current IP address. -* **load** - Your machines 5 minute load average. -* **node_version** - Show the version number of the installed Node.js. -* **nodeenv** - [nodeenv](https://github.com/ekalinin/nodeenv) prompt for displaying node version and environment name. -* **nvm** - Show the version of Node that is currently active, if it differs from the version used by NVM -* **os_icon** - Display a nice little icon, depending on your operating system. -* **php_version** - Show the current PHP version. -* **ram** - Show free RAM -* [rbenv](#rbenv) - Ruby environment information (if one is active). -* **root_indicator** - An indicator if the user is root. -* [rspec_stats](#rspec_stats) - Show a ratio of test classes vs code classes for RSpec. -* **rust_version** - Display the current rust version. -* [status](#status) - The return code of the previous command. -* **swap** - Prints the current swap size. -* [symphony2_tests](#symphony2_tests) - Show a ratio of test classes vs code classes for Symfony2. -* **symphony2_version** - Show the current Symfony2 version, if you are in a Symfony2-Project dir. -* [time](#time) - System time. -* [todo](http://todotxt.com/) - Shows the number of tasks in your todo.txt tasks file. -* [vi_mode](#vi_mode)- Vi editing mode (NORMAL|INSERT). -* **virtualenv** - Your Python [VirtualEnv](https://virtualenv.pypa.io/en/latest/). -* [vcs](#vcs) - Information about this `git` or `hg` repository (if you are in one). +**System Status Segments:** +* [`background_jobs`](#background_jobs) - Indicator for background jobs. +* [`battery`](#battery) - Current battery status. +* [`context`](#context) - Your username and host. +* [`dir`](#dir) - Your current working directory. +* `history` - The command number for the current line. +* [`ip`](#ip) - Shows the current IP address. +* `load` - Your machine's load averages. +* `os_icon` - Display a nice little icon, depending on your operating system. +* `ram` - Show free RAM. +* `root_indicator` - An indicator if the user has superuser status. +* [`status`](#status) - The return code of the previous command. +* `swap` - Prints the current swap size. +* [`time`](#time) - System time. +* [`vi_mode`](#vi_mode)- Your prompt's Vi editing mode (NORMAL|INSERT). + +**Development Environment Segments:** +* [`vcs`](#vcs) - Information about this `git` or `hg` repository (if you are in one). + +**Language Segments:** +* **GoLang Segments:** + * `go_version` - Show the current GO version. +* **Javascript / Node.js Segments:** + * `node_version` - Show the version number of the installed Node.js. + * `nodeenv` - [nodeenv](https://github.com/ekalinin/nodeenv) prompt for displaying node version and environment name. + * `nvm` - Show the version of Node that is currently active, if it differs from the version used by NVM +* **PHP Segments:** + * `php_version` - Show the current PHP version. + * [`symfony2_tests`](#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. +* **Python Segments:** + * `virtualenv` - Your Python [VirtualEnv](https://virtualenv.pypa.io/en/latest/). + * [`anaconda`](#anaconda) - Your active [Anaconda](https://www.continuum.io/why-anaconda) environment. + * `pyenv` - Your active python version as reported by the first word of [`pyenv version`](https://github.com/yyuu/pyenv). Note that the segment is not displayed if that word is _system_ i.e. the segment is inactive if you are using system python. +* **Ruby Segments:** + * [`chruby`](#chruby) - Ruby environment information using `chruby` (if one is active). + * [`rbenv`](#rbenv) - Ruby environment information using `rbenv` (if one is active). + * [`rspec_stats`](#rspec_stats) - Show a ratio of test classes vs code classes for RSpec. +* **Rust Segments:** + * `rust_version` - Display the current rust version and [logo](https://www.rust-lang.org/logos/rust-logo-blk.svg). + +**Cloud Segments:** +* **AWS Segments:** + * [`aws`](#aws) - The current AWS profile, if active. + * `aws_eb_env` - The current Elastic Beanstalk Environment. +* `docker_machine` - The current Docker Machine. + +**Other:** +* [`custom_command`](#custom_command) - Create a custom segment to display the + output of an arbitrary command. +* [`todo`](http://todotxt.com/) - Shows the number of tasks in your todo.txt tasks file. + +--------------------------------------------------------------------------------- + + +##### anaconda + +This segment shows your active anaconda environment. It relies on either the +`CONDA_ENV_PATH` or the `CONDA_PREFIX` (depending on the `conda` version) +environment variable to be set which happens when you properly `source +activate` an environment. + +Special configuration variables: +| Variable | Default Value | Description | +|----------|---------------|-------------| +|`POWERLEVEL9K_ANACONDA_LEFT_DELIMITER`|"("|The left delimiter just before the environment name.| +|`POWERLEVEL9K_ANACONDA_RIGHT_DELIMITER`|")"|The right delimiter just after the environment name.| + +Additionally the following segment specific parameters can be used to customize +it: `POWERLEVEL9K_PYTHON_ICON`, `POWERLEVEL9K_ANACONDA_BACKGROUND`, and +`POWERLEVEL9K_ANACONDA_FOREGROUND`. ##### aws @@ -145,6 +186,7 @@ requires `acpi` on Linux). |`POWERLEVEL9K_BATTERY_DISCONNECTED`|`$DEFAULT_COLOR`|Color to indicate absence of battery.| |`POWERLEVEL9K_BATTERY_LOW_THRESHOLD`|`10`|Threshold to consider battery level critical.| |`POWERLEVEL9K_BATTERY_LOW_COLOR`|`"red"`|Color to indicate critically low charge level.| +|`POWERLEVEL9K_BATTERY_VERBOSE`|`true`|Display time remaining next to battery level.| Note that you can [modify the `_FOREGROUND` color](https://github.com/bhilburn/powerlevel9k/wiki/Stylizing-Your-Prompt#segment-color-customization) @@ -222,7 +264,7 @@ Customizations available are: | Variable | Default Value | Description | |----------|---------------|-------------| |`POWERLEVEL9K_SHORTEN_DIR_LENGTH`|`2`|If your shorten strategy, below, is entire directories, this field determines how many directories to leave at the end. If your shorten strategy is by character count, this field determines how many characters to allow per directory string.| -|`POWERLEVEL9K_SHORTEN_STRATEGY`|None|How the directory strings should be truncated. By default, it will truncate whole directories. Other options are `truncate_middle`, which leaves the start and end of the directory strings, and `truncate_from_right`, which cuts starting from the end of the string.| +|`POWERLEVEL9K_SHORTEN_STRATEGY`|None|How the directory strings should be truncated. By default, it will truncate whole directories. Other options are `truncate_middle`, which leaves the start and end of the directory strings, and `truncate_from_right`, which cuts starting from the end of the string. You can also use `truncate_with_package_name` to use the `package.json` `name` field to abbreviate the directory path.| |`POWERLEVEL9K_SHORTEN_DELIMITER`|`..`|Delimiter to use in truncated strings. This can be any string you choose, including an empty string if you wish to have no delimiter.| For example, if you wanted the truncation behavior of the `fish` shell, which @@ -236,6 +278,15 @@ In each case you have to specify the length you want to shorten the directory to. So in some cases `POWERLEVEL9K_SHORTEN_DIR_LENGTH` means characters, in others whole directories. +The `truncate_with_package_name` strategy gives your directory path relative to the root of your project. For example, if you have a project inside `$HOME/projects/my-project` with a `package.json` that looks like: + +```json +{ + "name": "my-cool-project" +} +``` + +the path shown would be `my-cool-project`. If you navigate to `$HOME/projects/my-project/src`, then the path shown would be `my-cool-project/src`. Please note that this currently looks for `.git` directory to determine the root of the project. ##### ip @@ -266,9 +317,16 @@ This segment shows the return code of the last command. | Variable | Default Value | Description | |----------|---------------|-------------| -|`POWERLEVEL9K_STATUS_VERBOSE`|`true`|Set to false if you wish to hide this segment when the last command completed successfully.| +|`POWERLEVEL9K_STATUS_VERBOSE`|`true`|Set to false if you wish to not show the error code when the last command returned an error and optionally hide this segment when the last command completed successfully by setting `POWERLEVEL9K_STATUS_OK_IN_NON_VERBOSE` to false.| +|`POWERLEVEL9K_STATUS_OK_IN_NON_VERBOSE`|`false`|Set to true if you wish to show this segment when the last command completed successfully in non-verbose mode.| -##### symphony2_tests +##### ram + +| Variable | Default Value | Description | +|----------|---------------|-------------| +|`POWERLEVEL9K_RAM_ELEMENTS`|Both|Specify `ram_free` or `swap_used` to only show one or the other rather than both.| + +##### symfony2_tests See [Unit Test Ratios](#unit-test-ratios), below. @@ -300,8 +358,10 @@ customization is provided via: |`POWERLEVEL9K_SHOW_CHANGESET`|`false`|Set to `true` to display the hash / changeset in the segment.| |`POWERLEVEL9K_CHANGESET_HASH_LENGTH`|`12`|How many characters of the hash / changeset to display in the segment.| |`POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY`|`true`|Set to `false` to not reflect submodule status in the top-level repository prompt.| +|`POWERLEVEL9K_VCS_HIDE_TAGS`|`false`|Set to `true` to stop tags being displayed in the segment.| -**vcs Symbols** + +##### vcs symbols 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` @@ -351,3 +411,6 @@ portion of the wiki to get going. [The Wiki also has a ton of other useful information!](https://github.com/bhilburn/powerlevel9k/wiki) + +### License +MIT diff --git a/functions/icons.zsh b/functions/icons.zsh index e7dc3bfa..2f30cff2 100644 --- a/functions/icons.zsh +++ b/functions/icons.zsh @@ -20,104 +20,112 @@ case $POWERLEVEL9K_MODE in # Set the right locale to protect special characters local LC_ALL="" LC_CTYPE="en_US.UTF-8" icons=( - LEFT_SEGMENT_SEPARATOR $'\UE0B0' #  - RIGHT_SEGMENT_SEPARATOR $'\UE0B2' #  + LEFT_SEGMENT_SEPARATOR $'\uE0B0' #  + RIGHT_SEGMENT_SEPARATOR $'\uE0B2' #  LEFT_SEGMENT_END_SEPARATOR ' ' # Whitespace - LEFT_SUBSEGMENT_SEPARATOR $'\UE0B1' #  - RIGHT_SUBSEGMENT_SEPARATOR $'\UE0B3' #  - CARRIAGE_RETURN_ICON $'\U21B5' # ↵ - ROOT_ICON $'\UE801' #  - RUBY_ICON $'\UE847 ' #  - AWS_ICON $'\UE895' #  + LEFT_SUBSEGMENT_SEPARATOR $'\uE0B1' #  + RIGHT_SUBSEGMENT_SEPARATOR $'\uE0B3' #  + CARRIAGE_RETURN_ICON $'\u21B5' # ↵ + ROOT_ICON $'\uE801' #  + RUBY_ICON $'\uE847 ' #  + AWS_ICON $'\uE895' #  AWS_EB_ICON $'\U1F331 ' # 🌱 - BACKGROUND_JOBS_ICON $'\UE82F ' #  - TEST_ICON $'\UE891' #  - TODO_ICON $'\U2611' # ☑ - BATTERY_ICON $'\UE894' #  - OK_ICON $'\U2713' # ✓ - FAIL_ICON $'\U2718' # ✘ + BACKGROUND_JOBS_ICON $'\uE82F ' #  + TEST_ICON $'\uE891' #  + TODO_ICON $'\u2611' # ☑ + BATTERY_ICON $'\uE894' #  + OK_ICON $'\u2713' # ✓ + FAIL_ICON $'\u2718' # ✘ SYMFONY_ICON 'SF' - NODE_ICON $'\U2B22' # ⬢ - MULTILINE_FIRST_PROMPT_PREFIX $'\U256D'$'\U2500' - MULTILINE_SECOND_PROMPT_PREFIX $'\U2570'$'\U2500 ' - APPLE_ICON $'\UE26E' #  + NODE_ICON $'\u2B22' # ⬢ + MULTILINE_FIRST_PROMPT_PREFIX $'\u256D'$'\U2500' + MULTILINE_SECOND_PROMPT_PREFIX $'\u2570'$'\U2500 ' + APPLE_ICON $'\uE26E' #  FREEBSD_ICON $'\U1F608 ' # 😈 - LINUX_ICON $'\UE271' #  + LINUX_ICON $'\uE271' #  SUNOS_ICON $'\U1F31E ' # 🌞 - HOME_ICON $'\UE12C' #  - HOME_SUB_ICON $'\UE18D' #  - FOLDER_ICON $'\UE818' #  - NETWORK_ICON $'\UE1AD' #  - LOAD_ICON $'\UE190 ' #  - SWAP_ICON $'\UE87D' #  - RAM_ICON $'\UE1E2 ' #  - 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 ' #  - VCS_INCOMING_CHANGES_ICON $'\UE131 ' #  - #VCS_OUTGOING_CHANGES_ICON $'\UE1EC ' #  - #VCS_OUTGOING_CHANGES_ICON $'\UE80E ' #  - VCS_OUTGOING_CHANGES_ICON $'\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 ' #  + HOME_ICON $'\uE12C' #  + HOME_SUB_ICON $'\uE18D' #  + FOLDER_ICON $'\uE818' #  + NETWORK_ICON $'\uE1AD' #  + LOAD_ICON $'\uE190 ' #  + SWAP_ICON $'\uE87D' #  + RAM_ICON $'\uE1E2 ' #  + 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 ' #  + VCS_INCOMING_CHANGES_ICON $'\uE131 ' #  + #VCS_OUTGOING_CHANGES_ICON $'\uE1EC ' #  + #VCS_OUTGOING_CHANGES_ICON $'\uE80E ' #  + VCS_OUTGOING_CHANGES_ICON $'\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 ' #  + VCS_SVN_ICON '(svn) ' + RUST_ICON '' + PYTHON_ICON $'\U1F40D' # 🐍 ) ;; 'awesome-fontconfig') # fontconfig with awesome-font required! See # https://github.com/gabrielelana/awesome-terminal-fonts icons=( - LEFT_SEGMENT_SEPARATOR $'\UE0B0' #  - RIGHT_SEGMENT_SEPARATOR $'\UE0B2' #  + LEFT_SEGMENT_SEPARATOR $'\uE0B0' #  + RIGHT_SEGMENT_SEPARATOR $'\uE0B2' #  LEFT_SEGMENT_END_SEPARATOR ' ' # Whitespace - LEFT_SUBSEGMENT_SEPARATOR $'\UE0B1' #  - RIGHT_SUBSEGMENT_SEPARATOR $'\UE0B3' #  - CARRIAGE_RETURN_ICON $'\U21B5' # ↵ + LEFT_SUBSEGMENT_SEPARATOR $'\uE0B1' #  + RIGHT_SUBSEGMENT_SEPARATOR $'\uE0B3' #  + CARRIAGE_RETURN_ICON $'\u21B5' # ↵ ROOT_ICON $'\uF201' #  - RUBY_ICON $'\UF219 ' #  - AWS_ICON $'\UF296' #  + RUBY_ICON $'\uF219 ' #  + AWS_ICON $'\uF296' #  AWS_EB_ICON $'\U1F331 ' # 🌱 - BACKGROUND_JOBS_ICON $'\UF013 ' #  - TEST_ICON $'\UF291' #  - TODO_ICON $'\U2611' # ☑ - BATTERY_ICON $'\u1F50B' # 🔋 - OK_ICON $'\UF23A' #  - FAIL_ICON $'\UF281' #  + BACKGROUND_JOBS_ICON $'\uF013 ' #  + TEST_ICON $'\uF291' #  + TODO_ICON $'\u2611' # ☑ + BATTERY_ICON $'\U1F50B' # 🔋 + OK_ICON $'\uF23A' #  + FAIL_ICON $'\uF281' #  SYMFONY_ICON 'SF' - NODE_ICON $'\U2B22' # ⬢ - MULTILINE_FIRST_PROMPT_PREFIX $'\U256D'$'\U2500' # ╭─ - MULTILINE_SECOND_PROMPT_PREFIX $'\U2570'$'\U2500 ' # ╰─ - APPLE_ICON $'\UF179' #  + NODE_ICON $'\u2B22' # ⬢ + MULTILINE_FIRST_PROMPT_PREFIX $'\u256D'$'\U2500' # ╭─ + MULTILINE_SECOND_PROMPT_PREFIX $'\u2570'$'\U2500 ' # ╰─ + APPLE_ICON $'\uF179' #  FREEBSD_ICON $'\U1F608 ' # 😈 - LINUX_ICON $'\UF17C' #  - SUNOS_ICON $'\UF185 ' #  - HOME_ICON $'\UF015' #  - HOME_SUB_ICON $'\UF07C' #  - FOLDER_ICON $'\UF115' #  - NETWORK_ICON $'\UF09E' #  - LOAD_ICON $'\UF080 ' #  - SWAP_ICON $'\UF0E4' #  - RAM_ICON $'\UF0E4' #  - 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_COMMIT_ICON $'\UF221 ' #  - VCS_BRANCH_ICON $'\UF126' #  - VCS_REMOTE_BRANCH_ICON ' '$'\UF204 ' #  - VCS_GIT_ICON $'\UF113 ' #  - VCS_HG_ICON $'\UF0C3 ' #  + LINUX_ICON $'\uF17C' #  + SUNOS_ICON $'\uF185 ' #  + HOME_ICON $'\uF015' #  + HOME_SUB_ICON $'\uF07C' #  + FOLDER_ICON $'\uF115' #  + NETWORK_ICON $'\uF09E' #  + LOAD_ICON $'\uF080 ' #  + SWAP_ICON $'\uF0E4' #  + RAM_ICON $'\uF0E4' #  + SERVER_ICON $'\uF296' #  + 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_COMMIT_ICON $'\uF221 ' #  + VCS_BRANCH_ICON $'\uF126' #  + VCS_REMOTE_BRANCH_ICON ' '$'\uF204 ' #  + VCS_GIT_ICON $'\uF113 ' #  + VCS_HG_ICON $'\uF0C3 ' #  + VCS_SVN_ICON '(svn) ' + RUST_ICON $'\uE6A8' #  + PYTHON_ICON $'\U1F40D' # 🐍 ) ;; *) @@ -127,17 +135,17 @@ case $POWERLEVEL9K_MODE in LEFT_SEGMENT_SEPARATOR $'\uE0B0' #  RIGHT_SEGMENT_SEPARATOR $'\uE0B2' #  LEFT_SEGMENT_END_SEPARATOR ' ' # Whitespace - LEFT_SUBSEGMENT_SEPARATOR $'\UE0B1' #  - RIGHT_SUBSEGMENT_SEPARATOR $'\UE0B3' #  - CARRIAGE_RETURN_ICON $'\U21B5' # ↵ + LEFT_SUBSEGMENT_SEPARATOR $'\uE0B1' #  + RIGHT_SUBSEGMENT_SEPARATOR $'\uE0B3' #  + CARRIAGE_RETURN_ICON $'\u21B5' # ↵ ROOT_ICON $'\u26A1' # ⚡ RUBY_ICON '' AWS_ICON 'AWS:' AWS_EB_ICON $'\U1F331 ' # 🌱 BACKGROUND_JOBS_ICON $'\u2699' # ⚙ TEST_ICON '' - TODO_ICON $'\U2611' # ☑ - BATTERY_ICON $'\u1F50B' # 🔋 + TODO_ICON $'\u2611' # ☑ + BATTERY_ICON $'\U1F50B' # 🔋 OK_ICON $'\u2713' # ✓ FAIL_ICON $'\u2718' # ✘ SYMFONY_ICON 'SF' @@ -155,6 +163,7 @@ case $POWERLEVEL9K_MODE in LOAD_ICON 'L' SWAP_ICON 'SWP' RAM_ICON 'RAM' + SERVER_ICON '' VCS_UNTRACKED_ICON '?' VCS_UNSTAGED_ICON $'\u25CF' # ● VCS_STAGED_ICON $'\u271A' # ✚ @@ -168,6 +177,9 @@ case $POWERLEVEL9K_MODE in VCS_REMOTE_BRANCH_ICON $'\u2192' # → VCS_GIT_ICON '' VCS_HG_ICON '' + VCS_SVN_ICON '' + RUST_ICON '' + PYTHON_ICON '' ) ;; esac diff --git a/functions/utilities.zsh b/functions/utilities.zsh index 5ca5b431..f27c7f99 100644 --- a/functions/utilities.zsh +++ b/functions/utilities.zsh @@ -122,6 +122,20 @@ if [[ "$OS" == 'OSX' ]]; then fi fi +# Determine if the passed segment is used in the prompt +# +# Pass the name of the segment to this function to test for its presence in +# either the LEFT or RIGHT prompt arrays. +# * $1: The segment to be tested. +segment_in_use() { + local key=$1 + if [[ -n "${POWERLEVEL9K_LEFT_PROMPT_ELEMENTS[(r)$key]}" ]] || [[ -n "${POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS[(r)$key]}" ]]; then + return 0 + else + return 1 + fi +} + # Print a deprecation warning if an old segment is in use. # Takes the name of an associative array that contains the # deprecated segments as keys, the values contain the new @@ -131,7 +145,7 @@ print_deprecation_warning() { raw_deprecated_segments=(${(kvP@)1}) for key in ${(@k)raw_deprecated_segments}; do - if [[ -n "${POWERLEVEL9K_LEFT_PROMPT_ELEMENTS[(r)$key]}" ]] || [[ -n "${POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS[(r)$key]}" ]]; then + if segment_in_use $key; then # segment is deprecated print -P "%F{yellow}Warning!%f The '$key' segment is deprecated. Use '%F{blue}${raw_deprecated_segments[$key]}%f' instead. For more informations, have a look at the CHANGELOG.md." fi @@ -186,3 +200,11 @@ function segmentShouldBeJoined() { return 1 fi } + +# Given a directory path, truncate it according to the settings for +# `truncate_from_right` +function truncatePathFromRight() { + local delim_len=${#POWERLEVEL9K_SHORTEN_DELIMITER} + echo $1 | sed $SED_EXTENDED_REGEX_PARAMETER \ + "s@(([^/]{$((POWERLEVEL9K_SHORTEN_DIR_LENGTH))})([^/]{$delim_len}))[^/]+/@\2$POWERLEVEL9K_SHORTEN_DELIMITER/@g" +} diff --git a/functions/vcs.zsh b/functions/vcs.zsh index 9d3883ca..93925f15 100644 --- a/functions/vcs.zsh +++ b/functions/vcs.zsh @@ -60,11 +60,30 @@ function +vi-git-remotebranch() { fi } +set_default POWERLEVEL9K_VCS_HIDE_TAGS false function +vi-git-tagname() { - local tag - - tag=$(git describe --tags --exact-match HEAD 2>/dev/null) - [[ -n "${tag}" ]] && hook_com[branch]="$(print_icon 'VCS_TAG_ICON')${tag}" + if [[ "$POWERLEVEL9K_VCS_HIDE_TAGS" == "false" ]]; then + # If we are on a tag, append the tagname to the current branch string. + local tag + tag=$(git describe --tags --exact-match HEAD 2>/dev/null) + + if [[ -n "${tag}" ]] ; then + # There is a tag that points to our current commit. Need to determine if we + # are also on a branch, or are in a DETACHED_HEAD state. + if [[ -z $(git symbolic-ref HEAD 2>/dev/null) ]]; then + # DETACHED_HEAD state. We want to append the tag name to the commit hash + # and print it. Unfortunately, `vcs_info` blows away the hash when a tag + # exists, so we have to manually retrieve it and clobber the branch + # string. + local revision + revision=$(git rev-list -n 1 --abbrev-commit --abbrev=${POWERLEVEL9K_VCS_INTERNAL_HASH_LENGTH} HEAD) + hook_com[branch]="$(print_icon 'VCS_BRANCH_ICON')${revision} $(print_icon 'VCS_TAG_ICON')${tag}" + else + # We are on both a tag and a branch; print both by appending the tag name. + hook_com[branch]+=" $(print_icon 'VCS_TAG_ICON')${tag}" + fi + fi + fi } # Show count of stashed changes @@ -94,6 +113,8 @@ function +vi-vcs-detect-changes() { vcs_visual_identifier='VCS_GIT_ICON' elif [[ "${hook_com[vcs]}" == "hg" ]]; then vcs_visual_identifier='VCS_HG_ICON' + elif [[ "${hook_com[vcs]}" == "svn" ]]; then + vcs_visual_identifier='VCS_SVN_ICON' fi if [[ -n "${hook_com[staged]}" ]] || [[ -n "${hook_com[unstaged]}" ]]; then @@ -102,3 +123,19 @@ function +vi-vcs-detect-changes() { VCS_WORKDIR_DIRTY=false fi } + +function +vi-svn-detect-changes() { + local svn_status="$(svn status)" + if [[ -n "$(echo "$svn_status" | grep \^\?)" ]]; then + hook_com[unstaged]+=" $(print_icon 'VCS_UNTRACKED_ICON')" + VCS_WORKDIR_HALF_DIRTY=true + fi + if [[ -n "$(echo "$svn_status" | grep \^\M)" ]]; then + hook_com[unstaged]+=" $(print_icon 'VCS_UNSTAGED_ICON')" + VCS_WORKDIR_DIRTY=true + fi + if [[ -n "$(echo "$svn_status" | grep \^\A)" ]]; then + hook_com[staged]+=" $(print_icon 'VCS_STAGED_ICON')" + VCS_WORKDIR_DIRTY=true + fi +} diff --git a/powerlevel9k.zsh-theme b/powerlevel9k.zsh-theme index 321c262d..da3639e1 100755 --- a/powerlevel9k.zsh-theme +++ b/powerlevel9k.zsh-theme @@ -20,43 +20,44 @@ #zstyle ':vcs_info:*+*:*' debug true #set -o xtrace -# Check if the theme was called as a function (e.g., from prezto) -if [[ $(whence -w prompt_powerlevel9k_setup) =~ "function" ]]; then +# Try to set the installation path +if [[ -n "$POWERLEVEL9K_INSTALLATION_PATH" ]]; then + # If an installation path was set manually, + # it should trump any other location found. + # Do nothing. This is all right, as we use the + # POWERLEVEL9K_INSTALLATION_PATH for further processing. +elif [[ $(whence -w prompt_powerlevel9k_setup) =~ "function" ]]; then + # Check if the theme was called as a function (e.g., from prezto) autoload -U is-at-least if is-at-least 5.0.8; then # Try to find the correct path of the script. - 0=$(whence -v $0 | sed "s/$0 is a shell function from //") + POWERLEVEL9K_INSTALLATION_PATH=$(whence -v $0 | sed "s/$0 is a shell function from //") elif [[ -f "${ZDOTDIR:-$HOME}/.zprezto/modules/prompt/init.zsh" ]]; then # If there is an prezto installation, we assume that powerlevel9k is linked there. - 0="${ZDOTDIR:-$HOME}/.zprezto/modules/prompt/functions/prompt_powerlevel9k_setup" - else - # Fallback: specify an installation path! - if [[ -z "$POWERLEVEL9K_INSTALLATION_PATH" ]]; then - print -P "%F{red}We could not locate the installation path of powerlevel9k.%f" - print -P "Please specify by setting %F{blue}POWERLEVEL9K_INSTALLATION_PATH%f (full path incl. file name) at the very beginning of your ~/.zshrc" - return 1 - elif [[ -L "$POWERLEVEL9K_INSTALLATION_PATH" ]]; then - # Symlink - 0="$POWERLEVEL9K_INSTALLATION_PATH" - elif [[ -f "$POWERLEVEL9K_INSTALLATION_PATH" ]]; then - # File - 0="$POWERLEVEL9K_INSTALLATION_PATH" - elif [[ -d "$POWERLEVEL9K_INSTALLATION_PATH" ]]; then - # Directory - 0="${POWERLEVEL9K_INSTALLATION_PATH}/powerlevel9k.zsh-theme" - fi + POWERLEVEL9K_INSTALLATION_PATH="${ZDOTDIR:-$HOME}/.zprezto/modules/prompt/functions/prompt_powerlevel9k_setup" fi +else + # Last resort: Set installation path is script path + POWERLEVEL9K_INSTALLATION_PATH="$0" fi -# If this theme is sourced as a symlink, we need to locate the true URL -if [[ -L $0 ]]; then - # Script is a symlink - filename="$(realpath -P $0 2>/dev/null || readlink -f $0 2>/dev/null || perl -MCwd=abs_path -le 'print abs_path readlink(shift);' $0 2>/dev/null)" -elif [[ -f $0 ]]; then +# Resolve the instllation path +if [[ -L "$POWERLEVEL9K_INSTALLATION_PATH" ]]; then + # If this theme is sourced as a symlink, we need to locate the real URL + filename="$(realpath -P $POWERLEVEL9K_INSTALLATION_PATH 2>/dev/null || readlink -f $POWERLEVEL9K_INSTALLATION_PATH 2>/dev/null || perl -MCwd=abs_path -le 'print abs_path readlink(shift);' $POWERLEVEL9K_INSTALLATION_PATH 2>/dev/null)" +elif [[ -d "$POWERLEVEL9K_INSTALLATION_PATH" ]]; then + # Directory + filename="${POWERLEVEL9K_INSTALLATION_PATH}/powerlevel9k.zsh-theme" +elif [[ -f "$POWERLEVEL9K_INSTALLATION_PATH" ]]; then # Script is a file - filename="$0" + filename="$POWERLEVEL9K_INSTALLATION_PATH" +elif [[ -z "$POWERLEVEL9K_INSTALLATION_PATH" ]]; then + # Fallback: specify an installation path! + print -P "%F{red}We could not locate the installation path of powerlevel9k.%f" + print -P "Please specify by setting %F{blue}POWERLEVEL9K_INSTALLATION_PATH%f (full path incl. file name) at the very beginning of your ~/.zshrc" + return 1 else - print -P "%F{red}Script location could not be found!%f" + print -P "%F{red}Script location could not be found! Maybe your %F{blue}POWERLEVEL9K_INSTALLATION_PATH%F{red} is not correct?%f" return 1 fi script_location="$(dirname $filename)" @@ -288,6 +289,19 @@ right_prompt_segment() { # right-left but reads the opposite, this isn't necessary for the other side. CURRENT_BG='NONE' +# Anaconda Environment +prompt_anaconda() { + # Depending on the conda version, either might be set. This + # variant works even if both are set. + _path=$CONDA_ENV_PATH$CONDA_PREFIX + if ! [ -z "$_path" ]; then + # config - can be overwritten in users' zshrc file. + set_default POWERLEVEL9K_ANACONDA_LEFT_DELIMITER "(" + set_default POWERLEVEL9K_ANACONDA_RIGHT_DELIMITER ")" + "$1_prompt_segment" "$0" "$2" "$3" "$4" "$POWERLEVEL9K_ANACONDA_LEFT_DELIMITER$(basename $_path)$POWERLEVEL9K_ANACONDA_RIGHT_DELIMITER" 'PYTHON_ICON' + fi +} + # AWS Profile prompt_aws() { local aws_profile="$AWS_DEFAULT_PROFILE" @@ -310,6 +324,10 @@ prompt_aws_eb_env() { set_default POWERLEVEL9K_BACKGROUND_JOBS_VERBOSE true prompt_background_jobs() { local background_jobs_number=${$(jobs -l | wc -l)// /} + local wrong_lines=`jobs -l | awk '/pwd now/{ count++ } END {print count}'` + if [[ wrong_lines -gt 0 ]]; then + background_jobs_number=$(( $background_jobs_number - $wrong_lines )) + fi if [[ background_jobs_number -gt 0 ]]; then local background_jobs_number_print="" if [[ "$POWERLEVEL9K_BACKGROUND_JOBS_VERBOSE" == "true" ]] && [[ "$background_jobs_number" -gt 1 ]]; then @@ -343,7 +361,7 @@ prompt_battery() { local time_remaining=$(echo $raw_data | grep TimeRemaining | awk '{ print $5 }') if [[ -n $time_remaining ]]; then # this value is set to a very high number when the system is calculating - [[ $time_remaining -gt 10000 ]] && local tstring="..." || local tstring=${(f)$(date -u -r $(($time_remaining * 60)) +%k:%M)} + [[ $time_remaining -gt 10000 ]] && local tstring="..." || local tstring=${(f)$(/bin/date -u -r $(($time_remaining * 60)) +%k:%M)} fi # Get charge values @@ -403,6 +421,8 @@ prompt_battery() { set_default POWERLEVEL9K_BATTERY_VERBOSE true if [[ "$POWERLEVEL9K_BATTERY_VERBOSE" == true ]]; then message="$bat_percent%%$remain" + else + message="$bat_percent%%" fi # Draw the prompt_segment @@ -428,8 +448,11 @@ prompt_context() { # the output in a segment. prompt_custom() { local command=POWERLEVEL9K_CUSTOM_$3:u + local segment_content="$(eval ${(P)command})" - "$1_prompt_segment" "${0}_${3:u}" "$2" $DEFAULT_COLOR_INVERTED $DEFAULT_COLOR "$(eval ${(P)command})" + if [[ -n $segment_content ]]; then + "$1_prompt_segment" "${0}_${3:u}" "$2" $DEFAULT_COLOR_INVERTED $DEFAULT_COLOR "$segment_content" + fi } # Dir: current working directory @@ -444,7 +467,35 @@ prompt_dir() { current_path=$(pwd | sed -e "s,^$HOME,~," | sed $SED_EXTENDED_REGEX_PARAMETER "s/([^/]{$POWERLEVEL9K_SHORTEN_DIR_LENGTH})[^/]+([^/]{$POWERLEVEL9K_SHORTEN_DIR_LENGTH})\//\1$POWERLEVEL9K_SHORTEN_DELIMITER\2\//g") ;; truncate_from_right) - current_path=$(pwd | sed -e "s,^$HOME,~," | sed $SED_EXTENDED_REGEX_PARAMETER "s/([^/]{$POWERLEVEL9K_SHORTEN_DIR_LENGTH})[^/]+\//\1$POWERLEVEL9K_SHORTEN_DELIMITER\//g") + current_path=$(truncatePathFromRight "$(pwd | sed -e "s,^$HOME,~,")" ) + ;; + truncate_with_package_name) + local name repo_path package_path current_dir zero + + # Get the path of the Git repo, which should have the package.json file + if [[ $(git rev-parse --is-inside-work-tree 2> /dev/null) == "true" ]]; then + package_path=$(git rev-parse --show-toplevel) + elif [[ $(git rev-parse --is-inside-git-dir 2> /dev/null) == "true" ]]; then + package_path=${$(pwd)%%/.git*} + fi + + zero='%([BSUbfksu]|([FB]|){*})' + current_dir=$(pwd) + # Then, find the length of the package_path string, and save the + # subdirectory path as a substring of the current directory's path from 0 + # to the length of the package path's string + subdirectory_path=$(truncatePathFromRight "${current_dir:${#${(S%%)package_path//$~zero/}}}") + # Parse the 'name' from the package.json; if there are any problems, just + # print the file path + if name=$( cat "$package_path/package.json" 2> /dev/null | grep -m 1 "\"name\""); then + name=$(echo $name | awk -F ':' '{print $2}' | awk -F '"' '{print $2}') + + # Instead of printing out the full path, print out the name of the package + # from the package.json and append the current subdirectory + current_path="`echo $name | tr -d '"'`$subdirectory_path" + else + current_path=$(truncatePathFromRight "$(pwd | sed -e "s,^$HOME,~,")" ) + fi ;; *) current_path="%$((POWERLEVEL9K_SHORTEN_DIR_LENGTH+1))(c:$POWERLEVEL9K_SHORTEN_DELIMITER/:)%${POWERLEVEL9K_SHORTEN_DIR_LENGTH}c" @@ -463,6 +514,15 @@ prompt_dir() { fi } +# Docker machine +prompt_docker_machine() { + local docker_machine="$DOCKER_MACHINE_NAME" + + if [[ -n "$docker_machine" ]]; then + "$1_prompt_segment" "$0" "$2" "magenta" "$DEFAULT_COLOR" "$docker_machine" 'SERVER_ICON' + fi +} + # GO prompt prompt_go_version() { local go_version @@ -521,30 +581,39 @@ prompt_ip() { prompt_load() { # The load segment can have three different states local current_state="unknown" + local cores + typeset -AH load_states load_states=( 'critical' 'red' 'warning' 'yellow' 'normal' 'green' ) - if [[ "$OS" == "OSX" ]]; then - load_avg_5min=$(sysctl vm.loadavg | grep -o -E '[0-9]+(\.|,)[0-9]+' | head -n 1) + + if [[ "$OS" == "OSX" ]] || [[ "$OS" == "BSD" ]]; then + load_avg_1min=$(sysctl vm.loadavg | grep -o -E '[0-9]+(\.|,)[0-9]+' | head -n 1) + if [[ "$OS" == "OSX" ]]; then + cores=$(sysctl -n hw.logicalcpu) + else + cores=$(sysctl -n hw.ncpu) + fi else - load_avg_5min=$(grep -o "[0-9.]*" /proc/loadavg | head -n 1) + load_avg_1min=$(grep -o "[0-9.]*" /proc/loadavg | head -n 1) + cores=$(nproc) fi # Replace comma - load_avg_5min=${load_avg_5min//,/.} + load_avg_1min=${load_avg_1min//,/.} - if [[ "$load_avg_5min" -gt 10 ]]; then + if [[ "$load_avg_1min" -gt $(bc -l <<< "${cores} * 0.7") ]]; then current_state="critical" - elif [[ "$load_avg_5min" -gt 3 ]]; then + elif [[ "$load_avg_1min" -gt $(bc -l <<< "${cores} * 0.5") ]]; then current_state="warning" else current_state="normal" fi - "$1_prompt_segment" "${0}_${current_state}" "$2" "${load_states[$current_state]}" "$DEFAULT_COLOR" "$load_avg_5min" 'LOAD_ICON' + "$1_prompt_segment" "${0}_${current_state}" "$2" "${load_states[$current_state]}" "$DEFAULT_COLOR" "$load_avg_1min" 'LOAD_ICON' } # Node version @@ -560,8 +629,8 @@ prompt_node_version() { prompt_nvm() { [[ ! $(type nvm) =~ 'nvm is a shell function'* ]] && return local node_version=$(nvm current) + [[ -z "${node_version}" ]] || [[ ${node_version} = "none" ]] && return local nvm_default=$(cat $NVM_DIR/alias/default) - [[ -z "${node_version}" ]] && return [[ "$node_version" =~ "$nvm_default" ]] && return $1_prompt_segment "$0" "$2" "green" "011" "${node_version:1}" 'NODE_ICON' @@ -572,7 +641,7 @@ prompt_nodeenv() { local nodeenv_path="$NODE_VIRTUAL_ENV" if [[ -n "$nodeenv_path" && "$NODE_VIRTUAL_ENV_DISABLE_PROMPT" != true ]]; then local info="$(node -v)[$(basename "$nodeenv_path")]" - "$1_prompt_segment" "$0" "$2" "black" "green" "$info" 'NODE_ICON' + "$1_prompt_segment" "$0" "$2" "black" "green" "$info" 'NODE_ICON' fi } @@ -600,8 +669,13 @@ prompt_ram() { # Convert pages into Bytes ramfree=$(( ramfree * 4096 )) else - ramfree=$(grep -o -E "MemFree:\s+[0-9]+" /proc/meminfo | grep -o "[0-9]*") - base='K' + if [[ "$OS" == "BSD" ]]; then + ramfree=$(vmstat | grep -E '([0-9]+\w+)+' | awk '{print $5}') + base='M' + else + ramfree=$(grep -o -E "MemFree:\s+[0-9]+" /proc/meminfo | grep -o "[0-9]*") + base='K' + fi fi "$1_prompt_segment" "$0" "$2" "yellow" "$DEFAULT_COLOR" "$(printSizeHumanReadable "$ramfree" $base)" 'RAM_ICON' @@ -622,6 +696,17 @@ prompt_rbenv() { fi } +# chruby information +# see https://github.com/postmodern/chruby/issues/245 for chruby_auto issue with ZSH +prompt_chruby() { + local chruby_env + chrb_env="$(chruby 2> /dev/null | grep \* | tr -d '* ')" + # Don't show anything if the chruby did not change the default ruby + if [[ "${chrb_env:-system}" != "system" ]]; then + "$1_prompt_segment" "$0" "$2" "red" "$DEFAULT_COLOR" "${chrb_env}" 'RUBY_ICON' + fi +} + # Print an icon if user is root. prompt_root_indicator() { if [[ "$UID" -eq 0 ]]; then @@ -635,7 +720,7 @@ prompt_rust_version() { rust_version=$(rustc --version 2>&1 | grep -oe "^rustc\s*[^ ]*" | grep -o '[0-9.a-z\\\-]*$') if [[ -n "$rust_version" ]]; then - "$1_prompt_segment" "$0" "$2" "208" "$DEFAULT_COLOR" "Rust $rust_version" + "$1_prompt_segment" "$0" "$2" "208" "$DEFAULT_COLOR" "Rust $rust_version" 'RUST_ICON' fi } # RSpec test ratio @@ -663,17 +748,16 @@ prompt_rvm() { # Status: return code if verbose, otherwise just an icon if an error occurred set_default POWERLEVEL9K_STATUS_VERBOSE true +set_default POWERLEVEL9K_STATUS_OK_IN_NON_VERBOSE false prompt_status() { - if [[ "$POWERLEVEL9K_STATUS_VERBOSE" == true ]]; then - if [[ "$RETVAL" -ne 0 ]]; then + if [[ "$RETVAL" -ne 0 ]]; then + if [[ "$POWERLEVEL9K_STATUS_VERBOSE" == true ]]; then "$1_prompt_segment" "$0_ERROR" "$2" "red" "226" "$RETVAL" 'CARRIAGE_RETURN_ICON' else - "$1_prompt_segment" "$0_OK" "$2" "$DEFAULT_COLOR" "046" "" 'OK_ICON' - fi - else - if [[ "$RETVAL" -ne 0 ]]; then "$1_prompt_segment" "$0_ERROR" "$2" "$DEFAULT_COLOR" "red" "" 'FAIL_ICON' fi + elif [[ "$POWERLEVEL9K_STATUS_VERBOSE" == true || "$POWERLEVEL9K_STATUS_OK_IN_NON_VERBOSE" == true ]]; then + "$1_prompt_segment" "$0_OK" "$2" "$DEFAULT_COLOR" "046" "" 'OK_ICON' fi } @@ -758,39 +842,40 @@ prompt_todo() { # VCS segment: shows the state of your repository, if you are in a folder under # version control -prompt_vcs() { +set_default POWERLEVEL9K_VCS_ACTIONFORMAT_FOREGROUND "red" +# Default: Just display the first 8 characters of our changeset-ID. +set_default POWERLEVEL9K_VCS_INTERNAL_HASH_LENGTH "8" +powerlevel9k_vcs_init() { + if [[ -n "$POWERLEVEL9K_CHANGESET_HASH_LENGTH" ]]; then + POWERLEVEL9K_VCS_INTERNAL_HASH_LENGTH="$POWERLEVEL9K_CHANGESET_HASH_LENGTH" + fi + + # Load VCS_INFO autoload -Uz vcs_info VCS_WORKDIR_DIRTY=false VCS_WORKDIR_HALF_DIRTY=false # The vcs segment can have three different states - defaults to 'clean'. - local current_state="" - typeset -AH vcs_states + typeset -gAH vcs_states vcs_states=( 'clean' 'green' - 'modified' 'red' - 'untracked' 'yellow' + 'modified' 'yellow' + 'untracked' 'green' ) 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" - fi - - VCS_CHANGESET_PREFIX="$(print_icon 'VCS_COMMIT_ICON')%0.$VCS_CHANGESET_HASH_LENGTH""i " + VCS_CHANGESET_PREFIX="$(print_icon 'VCS_COMMIT_ICON')%0.$POWERLEVEL9K_VCS_INTERNAL_HASH_LENGTH""i " fi - zstyle ':vcs_info:*' enable git hg + zstyle ':vcs_info:*' enable git hg svn zstyle ':vcs_info:*' check-for-changes true VCS_DEFAULT_FORMAT="$VCS_CHANGESET_PREFIX%b%c%u%m" zstyle ':vcs_info:*' formats "$VCS_DEFAULT_FORMAT" - zstyle ':vcs_info:*' actionformats "%b %F{red}| %a%f" + zstyle ':vcs_info:*' actionformats "%b %F{${POWERLEVEL9K_VCS_ACTIONFORMAT_FOREGROUND}}| %a%f" zstyle ':vcs_info:*' stagedstr " $(print_icon 'VCS_STAGED_ICON')" zstyle ':vcs_info:*' unstagedstr " $(print_icon 'VCS_UNSTAGED_ICON')" @@ -799,6 +884,8 @@ prompt_vcs() { zstyle ':vcs_info:git*+set-message:*' hooks $POWERLEVEL9K_VCS_GIT_HOOKS defined POWERLEVEL9K_VCS_HG_HOOKS || POWERLEVEL9K_VCS_HG_HOOKS=(vcs-detect-changes) zstyle ':vcs_info:hg*+set-message:*' hooks $POWERLEVEL9K_VCS_HG_HOOKS + defined POWERLEVEL9K_VCS_SVN_HOOKS || POWERLEVEL9K_VCS_SVN_HOOKS=(vcs-detect-changes svn-detect-changes) + zstyle ':vcs_info:svn*+set-message:*' hooks $POWERLEVEL9K_VCS_SVN_HOOKS # For Hg, only show the branch name zstyle ':vcs_info:hg*:*' branchformat "$(print_icon 'VCS_BRANCH_ICON')%b" @@ -810,6 +897,12 @@ prompt_vcs() { if [[ "$POWERLEVEL9K_SHOW_CHANGESET" == true ]]; then zstyle ':vcs_info:*' get-revision true fi +} + +prompt_vcs() { + VCS_WORKDIR_DIRTY=false + VCS_WORKDIR_HALF_DIRTY=false + current_state="" # Actually invoke vcs_info manually to gather all information. vcs_info @@ -851,18 +944,31 @@ prompt_vi_mode() { prompt_virtualenv() { local virtualenv_path="$VIRTUAL_ENV" if [[ -n "$virtualenv_path" && "$VIRTUAL_ENV_DISABLE_PROMPT" != true ]]; then - "$1_prompt_segment" "$0" "$2" "blue" "$DEFAULT_COLOR" "($(basename "$virtualenv_path"))" + "$1_prompt_segment" "$0" "$2" "blue" "$DEFAULT_COLOR" "$(basename "$virtualenv_path")" 'PYTHON_ICON' + fi +} + +# pyenv: current active python version (with restrictions) +# More information on pyenv (Python version manager like rbenv and rvm): +# https://github.com/yyuu/pyenv +# the prompt parses output of pyenv version and only displays the first word +prompt_pyenv() { + local pyenv_version="$(pyenv version 2>/dev/null)" + pyenv_version="${pyenv_version%% *}" + # XXX: The following should return the same as above. + # This reads better for devs familiar with sed/awk/grep/cut utilities + # Using shell expansion/substitution may hamper future maintainability + #local pyenv_version="$(pyenv version 2>/dev/null | head -n1 | cut -d' ' -f1)" + if [[ -n "$pyenv_version" && "$pyenv_version" != "system" ]]; then + "$1_prompt_segment" "$0" "$2" "blue" "$DEFAULT_COLOR" "$pyenv_version" 'PYTHON_ICON' fi } ################################################################ # Prompt processing and drawing ################################################################ - # Main prompt build_left_prompt() { - defined POWERLEVEL9K_LEFT_PROMPT_ELEMENTS || POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(context dir rbenv vcs) - local index=1 for element in "${POWERLEVEL9K_LEFT_PROMPT_ELEMENTS[@]}"; do # Remove joined information in direct calls @@ -884,8 +990,6 @@ build_left_prompt() { # Right prompt build_right_prompt() { - defined POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS || POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(status root_indicator background_jobs history time) - local index=1 for element in "${POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS[@]}"; do # Remove joined information in direct calls @@ -933,41 +1037,30 @@ $(print_icon 'MULTILINE_SECOND_PROMPT_PREFIX')" fi } -function zle-line-init { - powerlevel9k_prepare_prompts - if (( ${+terminfo[smkx]} )); then - printf '%s' ${terminfo[smkx]} - fi - zle reset-prompt - zle -R -} - -function zle-line-finish { - powerlevel9k_prepare_prompts - if (( ${+terminfo[rmkx]} )); then - printf '%s' ${terminfo[rmkx]} - fi - zle reset-prompt - zle -R -} - -function zle-keymap-select { - powerlevel9k_prepare_prompts - zle reset-prompt - zle -R -} - powerlevel9k_init() { # Display a warning if the terminal does not support 256 colors local term_colors term_colors=$(echotc Co) - if (( term_colors < 256 )); then + if (( $term_colors < 256 )); then print -P "%F{red}WARNING!%f Your terminal appears to support less than 256 colors!" print -P "If your terminal supports 256 colors, please export the appropriate environment variable" print -P "_before_ loading this theme in your \~\/.zshrc. In most terminal emulators, putting" print -P "%F{blue}export TERM=\"xterm-256color\"%f at the top of your \~\/.zshrc is sufficient." fi + # If the terminal `LANG` is set to `C`, this theme will not work at all. + local term_lang + term_lang=$(echo $LANG) + if [[ $term_lang == 'C' ]]; then + print -P "\t%F{red}WARNING!%f Your terminal's 'LANG' is set to 'C', which breaks this theme!" + print -P "\t%F{red}WARNING!%f Please set your 'LANG' to a UTF-8 language, like 'en_US.UTF-8'" + print -P "\t%F{red}WARNING!%f _before_ loading this theme in your \~\.zshrc. Putting" + print -P "\t%F{red}WARNING!%f %F{blue}export LANG=\"en_US.UTF-8\"%f at the top of your \~\/.zshrc is sufficient." + fi + + defined POWERLEVEL9K_LEFT_PROMPT_ELEMENTS || POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(context dir rbenv vcs) + defined POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS || POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(status root_indicator background_jobs history time) + # Display a warning if deprecated segments are in use. typeset -AH deprecated_segments # old => new @@ -985,15 +1078,15 @@ powerlevel9k_init() { # initialize colors autoload -U colors && colors + if segment_in_use "vcs"; then + powerlevel9k_vcs_init + fi + # initialize hooks autoload -Uz add-zsh-hook # prepare prompts add-zsh-hook precmd powerlevel9k_prepare_prompts - - zle -N zle-line-init - zle -N zle-line-finish - zle -N zle-keymap-select } powerlevel9k_init "$@" diff --git a/test/segments/dir.spec b/test/segments/dir.spec index 035addea..840a298b 100755 --- a/test/segments/dir.spec +++ b/test/segments/dir.spec @@ -60,7 +60,7 @@ function testTruncationFromRightWorks() { mkdir -p $FOLDER cd $FOLDER - assertEquals "%K{blue} %F{black}/tm…/po…/1/12/12…/12…/12…/12…/12…/12…/123456789 %k%F{blue}%f " "$(build_left_prompt)" + assertEquals "%K{blue} %F{black}/tmp/po…/1/12/123/12…/12…/12…/12…/12…/123456789 %k%F{blue}%f " "$(build_left_prompt)" cd - rm -fr /tmp/powerlevel9k-test