diff options
-rw-r--r-- | .gitattributes | 19 | ||||
-rw-r--r-- | .gitignore | 7 | ||||
-rw-r--r-- | LICENSE | 696 | ||||
-rw-r--r-- | README.md | 2127 | ||||
-rw-r--r-- | config/p10k-classic.zsh | 1533 | ||||
-rw-r--r-- | config/p10k-lean-8colors.zsh | 1510 | ||||
-rw-r--r-- | config/p10k-lean.zsh | 1510 | ||||
-rw-r--r-- | config/p10k-pure.zsh | 193 | ||||
-rw-r--r-- | config/p10k-rainbow.zsh | 1609 | ||||
-rw-r--r-- | config/p10k-robbyrussell.zsh | 111 | ||||
-rw-r--r-- | gitstatus/.clang-format (renamed from .clang-format) | 0 | ||||
-rw-r--r-- | gitstatus/.gitattributes | 16 | ||||
-rw-r--r-- | gitstatus/.gitignore | 8 | ||||
-rw-r--r-- | gitstatus/.vscode/c_cpp_properties.json (renamed from .vscode/c_cpp_properties.json) | 0 | ||||
-rw-r--r-- | gitstatus/.vscode/settings.json (renamed from .vscode/settings.json) | 0 | ||||
-rw-r--r-- | gitstatus/LICENSE | 674 | ||||
-rw-r--r-- | gitstatus/Makefile (renamed from Makefile) | 0 | ||||
-rw-r--r-- | gitstatus/README.md | 595 | ||||
-rwxr-xr-x | gitstatus/build (renamed from build) | 0 | ||||
-rw-r--r-- | gitstatus/build.info (renamed from build.info) | 0 | ||||
-rw-r--r-- | gitstatus/deps/.gitkeep (renamed from deps/.gitkeep) | 0 | ||||
-rw-r--r-- | gitstatus/docs/listdir.md (renamed from docs/listdir.md) | 0 | ||||
-rw-r--r-- | gitstatus/gitstatus.plugin.sh (renamed from gitstatus.plugin.sh) | 0 | ||||
-rw-r--r-- | gitstatus/gitstatus.plugin.zsh (renamed from gitstatus.plugin.zsh) | 0 | ||||
-rw-r--r-- | gitstatus/gitstatus.prompt.sh (renamed from gitstatus.prompt.sh) | 0 | ||||
-rw-r--r-- | gitstatus/gitstatus.prompt.zsh (renamed from gitstatus.prompt.zsh) | 0 | ||||
-rwxr-xr-x | gitstatus/install (renamed from install) | 0 | ||||
-rw-r--r-- | gitstatus/install.info (renamed from install.info) | 0 | ||||
-rwxr-xr-x | gitstatus/mbuild (renamed from mbuild) | 0 | ||||
-rw-r--r-- | gitstatus/src/algorithm.h (renamed from src/algorithm.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/arena.cc (renamed from src/arena.cc) | 0 | ||||
-rw-r--r-- | gitstatus/src/arena.h (renamed from src/arena.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/bits.h (renamed from src/bits.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/check.h (renamed from src/check.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/check_dir_mtime.cc (renamed from src/check_dir_mtime.cc) | 0 | ||||
-rw-r--r-- | gitstatus/src/check_dir_mtime.h (renamed from src/check_dir_mtime.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/dir.cc (renamed from src/dir.cc) | 0 | ||||
-rw-r--r-- | gitstatus/src/dir.h (renamed from src/dir.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/git.cc (renamed from src/git.cc) | 0 | ||||
-rw-r--r-- | gitstatus/src/git.h (renamed from src/git.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/gitstatus.cc (renamed from src/gitstatus.cc) | 0 | ||||
-rw-r--r-- | gitstatus/src/index.cc (renamed from src/index.cc) | 0 | ||||
-rw-r--r-- | gitstatus/src/index.h (renamed from src/index.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/logging.cc (renamed from src/logging.cc) | 0 | ||||
-rw-r--r-- | gitstatus/src/logging.h (renamed from src/logging.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/options.cc (renamed from src/options.cc) | 0 | ||||
-rw-r--r-- | gitstatus/src/options.h (renamed from src/options.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/print.h (renamed from src/print.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/repo.cc (renamed from src/repo.cc) | 0 | ||||
-rw-r--r-- | gitstatus/src/repo.h (renamed from src/repo.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/repo_cache.cc (renamed from src/repo_cache.cc) | 0 | ||||
-rw-r--r-- | gitstatus/src/repo_cache.h (renamed from src/repo_cache.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/request.cc (renamed from src/request.cc) | 0 | ||||
-rw-r--r-- | gitstatus/src/request.h (renamed from src/request.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/response.cc (renamed from src/response.cc) | 0 | ||||
-rw-r--r-- | gitstatus/src/response.h (renamed from src/response.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/scope_guard.h (renamed from src/scope_guard.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/serialization.h (renamed from src/serialization.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/stat.h (renamed from src/stat.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/string_cmp.h (renamed from src/string_cmp.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/string_view.h (renamed from src/string_view.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/strings.cc (renamed from src/strings.cc) | 0 | ||||
-rw-r--r-- | gitstatus/src/strings.h (renamed from src/strings.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/tag_db.cc (renamed from src/tag_db.cc) | 0 | ||||
-rw-r--r-- | gitstatus/src/tag_db.h (renamed from src/tag_db.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/thread_pool.cc (renamed from src/thread_pool.cc) | 0 | ||||
-rw-r--r-- | gitstatus/src/thread_pool.h (renamed from src/thread_pool.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/time.h (renamed from src/time.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/timer.cc (renamed from src/timer.cc) | 0 | ||||
-rw-r--r-- | gitstatus/src/timer.h (renamed from src/timer.h) | 0 | ||||
-rw-r--r-- | gitstatus/src/tribool.h (renamed from src/tribool.h) | 0 | ||||
-rw-r--r-- | gitstatus/usrbin/.gitkeep (renamed from usrbin/.gitkeep) | 0 | ||||
-rw-r--r-- | internal/configure.zsh | 70 | ||||
-rw-r--r-- | internal/icons.zsh | 831 | ||||
-rw-r--r-- | internal/notes.md | 236 | ||||
-rw-r--r-- | internal/p10k.zsh | 8485 | ||||
-rw-r--r-- | internal/parser.zsh | 382 | ||||
-rwxr-xr-x | internal/wizard.zsh | 2068 | ||||
-rw-r--r-- | internal/worker.zsh | 210 | ||||
-rw-r--r-- | powerlevel10k.png | bin | 0 -> 62099 bytes | |||
-rw-r--r-- | powerlevel10k.zsh-theme | 83 | ||||
-rw-r--r-- | powerlevel9k.zsh-theme | 1 | ||||
-rw-r--r-- | prompt_powerlevel10k_setup | 1 | ||||
-rw-r--r-- | prompt_powerlevel9k_setup | 1 |
84 files changed, 21815 insertions, 1161 deletions
diff --git a/.gitattributes b/.gitattributes index 5c1135cb..41b2d3a8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,16 +1,5 @@ * text=auto - -*.cc text eol=lf -*.h text eol=lf -*.info text eol=lf -*.json text eol=lf -*.md text eol=lf -*.sh text eol=lf -*.zsh text eol=lf - -/.clang-format text eol=lf -/LICENSE text eol=lf -/Makefile text eol=lf -/build text eol=lf -/install text eol=lf -/mbuild text eol=lf +*.zsh text eol=lf +*.zsh-theme text eol=lf +/prompt_powerlevel9k_setup text eol=lf +/prompt_powerlevel10k_setup text eol=lf @@ -1,8 +1 @@ *.zwc -/core -/deps/libgit2-*.tar.gz -/locks -/logs -/obj -/usrbin/gitstatusd* -/.vscode/ipch @@ -1,674 +1,22 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - <program> Copyright (C) <year> <name of author> - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -<https://www.gnu.org/licenses/>. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -<https://www.gnu.org/licenses/why-not-lgpl.html>. +Copyright (c) 2009-2014 Robby Russell and contributors (see https://github.com/robbyrussell/oh-my-zsh/contributors) +Copyright (c) 2014-2017 Ben Hilburn <bhilburn@gmail.com> +Copyright (c) 2019 Roman Perepelitsa <roman.perepelitsa@gmail.com> and contributors (see https://github.com/romkatv/powerlevel10k/contributors) + +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. @@ -1,540 +1,1154 @@ -# gitstatus +# Powerlevel10k +[![Gitter](https://badges.gitter.im/powerlevel10k/community.svg)]( + https://gitter.im/powerlevel10k/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) -**gitstatus** is a 10x faster alternative to `git status` and `git describe`. Its primary use -case is to enable fast git prompt in interactive shells. +Powerlevel10k is a theme for Zsh. It emphasizes [speed](#uncompromising-performance), +[flexibility](#extremely-customizable) and [out-of-the-box experience](#configuration-wizard). -Heavy lifting is done by **gitstatusd** -- a custom binary written in C++. It comes with Zsh and -Bash bindings for integration with shell. +![Powerlevel10k]( +https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/prompt-styles-high-contrast.png) -## Table of Contents +Ready to [get started](#get-started)? See below. -1. [Using from Zsh](#using-from-zsh) -1. [Using from Bash](#using-from-bash) -2. [Using from other shells](#using-from-other-shells) -1. [How it works](#how-it-works) -1. [Benchmarks](#benchmarks) -1. [Why fast](#why-fast) -1. [Requirements](#requirements) -1. [Compiling](#compiling) -1. [License](#license) +To see what Powerlevel10k is about go to [features](#features). -## Using from Zsh +Powerlevel9k users, go [here](#powerlevel9k-compatibility). -The easiest way to take advantage of gitstatus from Zsh is to use a theme that's already integrated -with it. For example, [Powerlevel10k](https://github.com/romkatv/powerlevel10k) is a flexible and -fast theme with first-class gitstatus integration. +See the [table of contents](#table-of-contents) at the bottom. -![Powerlevel10k Zsh Theme]( - https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/prompt-styles-high-contrast.png) +## Get Started -For those who wish to use gitstatus without a theme, there is -[gitstatus.prompt.zsh](gitstatus.prompt.zsh). Install it as follows: +1. Install [the recommended font](#meslo-nerd-font-patched-for-powerlevel10k). *Optional but highly + recommended.* +1. Install Powerlevel10k for your plugin manager. + - [Manual](#manual) 👈 **choose this if confused or uncertain** + - [Oh My Zsh](#oh-my-zsh) + - [Prezto](#prezto) + - [Zim](#zim) + - [Antibody](#antibody) + - [Antigen](#antigen) + - [Zplug](#zplug) + - [Zgen](#zgen) + - [Zplugin](#zplugin) + - [Zinit](#zinit) + - [Homebrew](#homebrew) + - [Arch Linux](#arch-linux) +1. Restart Zsh. +1. Type `p10k configure` if the configuration wizard doesn't start automatically. + +## Features + +### Configuration wizard + +Type `p10k configure` to access the builtin configuration wizard right from your terminal. + +![Powerlevel10k Configuration Wizard]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/configuration-wizard.gif) + +All styles except [Pure](#pure-compatibility) are functionally equivalent. They display the same +information and differ only in presentation. + +Configuration wizard creates `~/.p10k.zsh` based on your preferences. Additional prompt +customization can be done by editing this file. It has plenty of comments to help you navigate +through configuration options. + +*Tip*: Install [the recommended font](#meslo-nerd-font-patched-for-powerlevel10k) before +running `p10k configure` to unlock all prompt styles. + +*FAQ:* + +- [What is the best prompt style in the configuration wizard?]( + #what-is-the-best-prompt-style-in-the-configuration-wizard) +- [What do different symbols in Git status mean?]( + #what-do-different-symbols-in-git-status-mean) +- [How do I change prompt colors?](#how-do-i-change-prompt-colors) + +*Troubleshooting*: + +- [Some prompt styles are missing from the configuration wizard]( + #some-prompt-styles-are-missing-from-the-configuration-wizard). +- [Question mark in prompt](#question-mark-in-prompt). +- [Icons, glyphs or powerline symbols don't render](#icons-glyphs-or-powerline-symbols-dont-render). +- [Sub-pixel imperfections around powerline symbols]( + #sub-pixel-imperfections-around-powerline-symbols). +- [Directory is difficult to see in prompt when using Rainbow style]( + #directory-is-difficult-to-see-in-prompt-when-using-rainbow-style). + +### Uncompromising performance + +When you hit *ENTER*, the next prompt appears instantly. With Powerlevel10k there is no prompt lag. +If you install Cygwin on Raspberry Pi, `cd` into a Linux Git repository and activate enough prompt +segments to fill four prompt lines on both sides of the screen... wait, that's just crazy and no +one ever does that. Probably impossible, too. The point is, Powerlevel10k prompt is always fast, no +matter what you do! + +![Powerlevel10k Performance]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/performance.gif) + +Note how the effect of every command is instantly reflected by the very next prompt. + +| Command | Prompt Indicator | Meaning | +|-------------------------------|:----------------:|----------------------------------------------------------------------:| +| `timew start hack linux` | `🛡️ hack linux` | time tracking enabled in [timewarrior](https://timewarrior.net/) | +| `touch x y` | `?2` | 2 untracked files in the Git repo | +| `rm COPYING` | `!1` | 1 unstaged change in the Git repo | +| `echo 2.7.3 >.python-version` | `🐍 2.7.3` | the current python version in [pyenv](https://github.com/pyenv/pyenv) | + +Other Zsh themes capable of displaying the same information either produce prompt lag or print +prompt that doesn't reflect the current state of the system and then refresh it later. With +Powerlevel10k you get fast prompt *and* up-to-date information. + +*FAQ*: [Is it really fast?](#is-it-really-fast) + +### Powerlevel9k compatibility + +Powerlevel10k understands all [Powerlevel9k](https://github.com/Powerlevel9k/powerlevel9k) +configuration parameters. + +![Powerlevel10k Compatibility with 9k]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/9k-compatibility.gif) + +[Migration](#installation) from Powerlevel9k to Powerlevel10k is a straightforward process. All +your `POWERLEVEL9K` configuration parameters will still work. Prompt will look the same as before +([almost]( + #does-powerlevel10k-always-render-exactly-the-same-prompt-as-powerlevel9k-given-the-same-config)) +but it will be [much faster](#uncompromising-performance) ([certainly](#is-it-really-fast)). + +*FAQ*: + +- [I'm using Powerlevel9k with Oh My Zsh. How do I migrate?]( + #im-using-powerlevel9k-with-oh-my-zsh-how-do-i-migrate) +- [Does Powerlevel10k always render exactly the same prompt as Powerlevel9k given the same config?]( + #does-powerlevel10k-always-render-exactly-the-same-prompt-as-powerlevel9k-given-the-same-config) +- [What is the relationship between Powerlevel9k and Powerlevel10k?]( + #What-is-the-relationship-between-powerlevel9k-and-powerlevel10k) + +### Pure compatibility + +Powerlevel10k can produce the same prompt as [Pure](https://github.com/sindresorhus/pure). Type +`p10k configure` and select *Pure* style. + +![Powerlevel10k Pure Style]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/pure-style.gif) + +You can still use Powerlevel10k features such as [transient prompt](#transient-prompt) or +[instant prompt](#instant-prompt) when sporting Pure style. + +To customize prompt, edit `~/.p10k.zsh`. Powerlevel10k doesn't recognize Pure configuration +parameters, so you'll need to use `POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=3` instead of +`PURE_CMD_MAX_EXEC_TIME=3`, etc. All relevant parameters are in `~/.p10k.zsh`. This file has +plenty of comments to help you navigate through it. + +*FAQ:* [What is the best prompt style in the configuration wizard?]( + #what-is-the-best-prompt-style-in-the-configuration-wizard) + +### <a name='what-is-instant-prompt'></a>Instant prompt + +If your `~/.zshrc` loads many plugins, or perhaps just a few slow ones +(for example, [pyenv](https://github.com/pyenv/pyenv) or [nvm](https://github.com/nvm-sh/nvm)), you +may have noticed that it takes some time for Zsh to start. + +![Powerlevel10k No Instant Prompt]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/no-instant-prompt.gif) + +Powerlevel10k can remove Zsh startup lag **even if it's not caused by a theme**. + +![Powerlevel10k Instant Prompt]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/instant-prompt.gif) + +This feature is called *Instant Prompt*. You need to explicitly enable it through `p10k configure` +or [manually](#how-do-i-enable-instant-prompt). It does what it says on the tin -- prints prompt +instantly upon Zsh startup allowing you to start typing while plugins are still loading. + +Other themes *increase* Zsh startup lag -- some by a lot, others by a just a little. Powerlevel10k +*removes* it outright. + +*FAQ:* [How do I enable instant prompt?](#how-do-i-enable-instant-prompt) + +### Show on command + +The behavior of some commands depends on global environment. For example, `kubectl run ...` runs an +image on the cluster defined by the current kubernetes context. If you frequently change context +between "prod" and "testing", you might want to display the current context in Zsh prompt. If you do +likewise for AWS, Azure and Google Cloud credentials, prompt will get pretty crowded. + +Enter *Show On Command*. This feature makes prompt segments appear only when they are relevant to +the command you are currently typing. + +![Powerlevel10k Show On Command]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/show-on-command.gif) + +Configs created by `p10k configure` enable show on command for several prompt segments by default. +Here's the relevant parameter for kubernetes context: + +```zsh +# Show prompt segment "kubecontext" only when the command you are typing +# invokes kubectl, helm, kubens, kubectx, oc, istioctl or kogito. +typeset -g POWERLEVEL9K_KUBECONTEXT_SHOW_ON_COMMAND='kubectl|helm|kubens|kubectx|oc|istioctl|kogito' +``` + +To customize when different prompt segments are shown, open `~/.p10k.zsh`, search for +`SHOW_ON_COMMAND` and either remove these parameters to display affected segments unconditionally, +or change their values. + +### Transient prompt + +When *Transient Prompt* is enabled through `p10k configure`, Powerlevel10k will trim down every +prompt when accepting a command line. + +![Powerlevel10k Transient Prompt]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/transient-prompt.gif) + +Transient prompt makes it much easier to copy-paste series of commands from the terminal scrollback. + +*Tip*: If you enable transient prompt, take advantage of two-line prompt. You'll get the benefit of +extra space for typing commands without the usual drawback of reduced scrollback density. Sparse +prompt (with an empty line before prompt) also works great in combination with transient prompt. + +### Current directory that just works + +The current working directory is perhaps the most important prompt segment. Powerlevel10k goes to +great length to highlight its important parts and to truncate it with the least loss of information +when horizontal space gets scarce. + +![Powerlevel10k Directory Truncation]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/directory-truncation.gif) + +When the full directory doesn't fit, the leftmost segment gets truncated to its shortest unique +prefix. In the screencast, `~/work` becomes `~/wo`. It couldn't be truncated to `~/w` because it +would be ambiguous (there was `~/wireguard` when the session was recorded). The next segment -- +`projects` -- turns into `p` as there was nothing else that started with `p` in `~/work/`. + +Directory segments are shown in one of three colors: + +- Truncated segments are bleak. +- Important segments are bright and never truncated. These include the first and the last segment, + roots of Git repositories, etc. +- Regular segments (not truncated but can be) use in-between color. + +*Tip*: If you copy-paste a truncated directory and hit *TAB*, it'll complete to the original. + +*Troubleshooting*: [Directory is difficult to see in prompt when using Rainbow style.]( + #directory-is-difficult-to-see-in-prompt-when-using-rainbow-style) + +### Extremely customizable + +Powerlevel10k can be configured to look like any other Zsh theme out there. + +![Powerlevel10k Other Theme Emulation]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/other-theme-emulation.gif) + +[Pure](#pure-compatibility), [Powerlevel9k](#powerlevel9k-compatibility) and [robbyrussell]( + #how-to-make-powerlevel10k-look-like-robbyrussell-oh-my-zsh-theme) emulations are built-in. +To emulate the appearance of other themes, you'll need to write a suitable configuration file. The +best way to go about it is to run `p10k configure`, select the style that is the closest to your +goal and then edit `~/.p10k.zsh`. + +The full range of Powerlevel10k appearance spans from spartan: + +![Powerlevel10k Spartan Style]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/spartan-style.png) + +To ~~ridiculous~~ extravagant: + +![Powerlevel10k Extravagant Style]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/extravagant-style.png) + +### Batteries included + +Powerlevel10k comes with dozens of built-in high quality segments. When you run `p10k configure` +and choose any style except [Pure](#pure-compatibility), many of these segments get enabled by +default while others be manually enabled by opening `~/.p10k.zsh` and uncommenting them. You can +enable as many segments as you like. It won't slow down your prompt or Zsh startup. + +| Segment | Meaning | +|--------:|---------| +| `os_icon` | your OS logo (apple for macOS, swirl for debian, etc.) | +| `dir` | current working directory | +| `vcs` | Git repository status | +| `prompt_char` | multi-functional prompt symbol; changes depending on vi mode: `❯`, `❮`, `Ⅴ`, `▶` for insert, command, visual and replace mode respectively; turns red on error | +| `context` | user@hostname | +| `status` | exit code of the last command | +| `command_execution_time` | duration (wall time) of the last command | +| `background_jobs` | presence of background jobs | +| `time` | current time | +| `direnv` | [direnv](https://direnv.net/) status | +| `asdf` | tool versions from [asdf](https://github.com/asdf-vm/asdf) | +| `virtualenv` | python environment from [venv](https://docs.python.org/3/library/venv.html) | +| `anaconda` | virtual environment from [conda](https://conda.io/) | +| `pyenv` | python environment from [pyenv](https://github.com/pyenv/pyenv) | +| `goenv` | go environment from [goenv](https://github.com/syndbg/goenv) | +| `nodenv` | node.js environment from [nodenv](https://github.com/nodenv/nodenv) | +| `nvm` | node.js environment from [nvm](https://github.com/nvm-sh/nvm) | +| `nodeenv` | node.js environment from [nodeenv](https://github.com/ekalinin/nodeenv) | +| `rbenv` | ruby environment from [rbenv](https://github.com/rbenv/rbenv) | +| `rvm` | ruby environment from [rvm](https://rvm.io) | +| `fvm` | flutter environment from [fvm](https://github.com/leoafarias/fvm) | +| `luaenv` | lua environment from [luaenv](https://github.com/cehoffman/luaenv) | +| `jenv` | java environment from [jenv](https://github.com/jenv/jenv) | +| `plenv` | perl environment from [plenv](https://github.com/tokuhirom/plenv) | +| `phpenv` | php environment from [phpenv](https://github.com/phpenv/phpenv) | +| `haskell_stack` | haskell version from [stack](https://haskellstack.org/) | +| `node_version` | [node.js](https://nodejs.org/) version | +| `go_version` | [go](https://golang.org) version | +| `rust_version` | [rustc](https://www.rust-lang.org) version | +| `dotnet_version` | [dotnet](https://dotnet.microsoft.com) version | +| `php_version` | [php](https://www.php.net/) version | +| `laravel_version` | [laravel php framework](https://laravel.com/) version | +| `java_version` | [java](https://www.java.com/) version | +| `package` | `name@version` from [package.json](https://docs.npmjs.com/files/package.json) | +| `kubecontext` | current [kubernetes](https://kubernetes.io/) context | +| `terraform` | [terraform](https://www.terraform.io) workspace | +| `aws` | [aws profile](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) | +| `aws_eb_env` | [aws elastic beanstalk](https://aws.amazon.com/elasticbeanstalk/) environment | +| `azure` | [azure](https://docs.microsoft.com/en-us/cli/azure) account name | +| `gcloud` | [google cloud](https://cloud.google.com/) cli account and project | +| `google_app_cred` | [google application credentials](https://cloud.google.com/docs/authentication/production) | +| `nordvpn` | [nordvpn](https://nordvpn.com/) connection status | +| `ranger` | [ranger](https://github.com/ranger/ranger) shell | +| `nnn` | [nnn](https://github.com/jarun/nnn) shell | +| `vim_shell` | [vim](https://www.vim.org/) shell (`:sh`) | +| `midnight_commander` | [midnight commander](https://midnight-commander.org/) shell | +| `nix_shell` | [nix shell](https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html) indicator | +| `todo` | [todo](https://github.com/todotxt/todo.txt-cli) items | +| `timewarrior` | [timewarrior](https://timewarrior.net/) tracking status | +| `taskwarrior` | [taskwarrior](https://taskwarrior.org/) task count | +| `vpn_ip` | virtual private network indicator | +| `ip` | IP address and bandwidth usage for a specified network interface | +| `load` | CPU load | +| `disk_usage` | disk usage | +| `ram` | free RAM | +| `swap` | used swap | +| `public_ip` | public IP address | +| `proxy` | system-wide http/https/ftp proxy | +| `wifi` | WiFi speed | +| `battery` | internal battery state and charge level (yep, batteries *literally* included) | + +### Extensible + +If there is no prompt segment that does what you need, implement your own. Powerlevel10k provides +public API for defining segments that are as fast and as flexible as built-in ones. + +![Powerlevel10k Custom Segment]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/custom-segment.gif) + +On Linux you can fetch current CPU temperature by reading `/sys/class/thermal/thermal_zone0/temp`. +The screencast shows how to define a prompt segment to display this value. Once the segment is +defined, you can use it like any other segment. All standard customization parameters will work for +it out of the box. + +Type `p10k help segment` for reference. + +*Tip*: Prefix names of your own segments with `my_` to avoid clashes with future versions of +Powerlevel10k. + +## Installation + +### Manual ```zsh -git clone --depth=1 https://github.com/romkatv/gitstatus.git ~/gitstatus -echo 'source ~/gitstatus/gitstatus.prompt.zsh' >>! ~/.zshrc +git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ~/powerlevel10k +echo 'source ~/powerlevel10k/powerlevel10k.zsh-theme' >>! ~/.zshrc ``` Users in mainland China can use the official mirror on gitee.com for faster download.<br> 中国大陆用户可以使用 gitee.com 上的官方镜像加速下载. ```zsh -git clone --depth=1 https://gitee.com/romkatv/gitstatus.git ~/gitstatus -echo 'source ~/gitstatus/gitstatus.prompt.zsh' >>! ~/.zshrc +git clone --depth=1 https://gitee.com/romkatv/powerlevel10k.git ~/powerlevel10k +echo 'source ~/powerlevel10k/powerlevel10k.zsh-theme' >>! ~/.zshrc +``` + +This is the simplest kind of installation and it works even if you are using a plugin manager. Just +make sure to disable the current theme in your plugin manager. See +[troubleshooting](#cannot-make-powerlevel10k-work-with-my-plugin-manager) for help. + +### Oh My Zsh + +```zsh +git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/themes/powerlevel10k ``` -Alternatively, on macOS you can install with Homebrew: +Users in mainland China can use the official mirror on gitee.com for faster download.<br> +中国大陆用户可以使用 gitee.com 上的官方镜像加速下载. ```zsh -brew install romkatv/gitstatus/gitstatus -echo 'source /usr/local/opt/gitstatus/gitstatus.prompt.zsh' >>! ~/.zshrc +git clone --depth=1 https://gitee.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/themes/powerlevel10k ``` -(If you choose this option, replace `~/gitstatus` with `/usr/local/opt/gitstatus` in all code -snippets below.) +Set `ZSH_THEME="powerlevel10k/powerlevel10k"` in `~/.zshrc`. + +### Prezto + +Add `zstyle :prezto:module:prompt theme powerlevel10k` to `~/.zpreztorc`. + +### Zim + +Add `zmodule romkatv/powerlevel10k` to `~/.zimrc` and run `zimfw install`. + +### Antibody + +Add `antibody bundle romkatv/powerlevel10k` to `~/.zshrc`. + +### Antigen + +Add `antigen theme romkatv/powerlevel10k` to `~/.zshrc`. Make sure you have `antigen apply` +somewhere after it. + +### Zplug + +Add `zplug romkatv/powerlevel10k, as:theme, depth:1` to `~/.zshrc`. + +### Zgen + +Add `zgen load romkatv/powerlevel10k powerlevel10k` to `~/.zshrc`. + +### Zplugin + +Add `zplugin ice depth=1; zplugin light romkatv/powerlevel10k` to `~/.zshrc`. -_Make sure to disable your current theme if you have one._ +The use of `depth=1` ice is optional. Other types of ice are neither recommended nor officially +supported by Powerlevel10k. -This will give you a basic yet functional prompt with git status in it. It's -[over 10x faster](#benchmarks) than any alternative that can give you comparable prompt. In order -to customize it, set `PROMPT` and/or `RPROMPT` at the end of `~/.zshrc` after sourcing -`gitstatus.prompt.zsh`. Insert `${GITSTATUS_PROMPT}` where you want git status to go. For example: +### Zinit + +Add `zinit ice depth=1; zinit light romkatv/powerlevel10k` to `~/.zshrc`. + +The use of `depth=1` ice is optional. Other types of ice are neither recommended nor officially +supported by Powerlevel10k. + +### Homebrew ```zsh -source ~/gitstatus/gitstatus.prompt.zsh - -PROMPT='%~%# ' # left prompt: directory followed by %/# (normal/root) -RPROMPT='$GITSTATUS_PROMPT' # right prompt: git status -``` - -The expansion of `${GITSTATUS_PROMPT}` can contain the following bits: - -| segment | meaning | -|-------------|-------------------------------------------------------| -| `master` | current branch | -| `#v1` | HEAD is tagged with `v1`; not shown when on a branch | -| `@5fc6fca4` | current commit; not shown when on a branch or tag | -| `⇣1` | local branch is behind the remote by 1 commit | -| `⇡2` | local branch is ahead of the remote by 2 commits | -| `⇠3` | local branch is behind the push remote by 3 commits | -| `⇢4` | local branch is ahead of the push remote by 4 commits | -| `*5` | there are 5 stashes | -| `merge` | merge is in progress (could be some other action) | -| `~6` | there are 6 merge conflicts | -| `+7` | there are 7 staged changes | -| `!8` | there are 8 unstaged changes | -| `?9` | there are 9 untracked files | - -`$GITSTATUS_PROMPT_LEN` tells you how long `$GITSTATUS_PROMPT` is when printed to the console. -[gitstatus.prompt.zsh](gitstatus.prompt.zsh) has an example of using it to truncate the current -directory. - -If you'd like to change the format of git status, or want to have greater control over the -process of assembling `PROMPT`, you can copy and modify parts of -[gitstatus.prompt.zsh](gitstatus.prompt.zsh) instead of sourcing the script. Your `~/.zshrc` -might look something like this: +brew install romkatv/powerlevel10k/powerlevel10k +echo 'source /usr/local/opt/powerlevel10k/powerlevel10k.zsh-theme' >>! ~/.zshrc +``` + +### Arch Linux ```zsh -source ~/gitstatus/gitstatus.plugin.zsh +pacman -S --noconfirm zsh-theme-powerlevel10k +echo 'source /usr/share/zsh-theme-powerlevel10k/powerlevel10k.zsh-theme' >>! ~/.zshrc +``` -function my_set_prompt() { - PROMPT='%~%# ' - RPROMPT='' +## Configuration - if gitstatus_query MY && [[ $VCS_STATUS_RESULT == ok-sync ]]; then - RPROMPT=${${VCS_STATUS_LOCAL_BRANCH:-@${VCS_STATUS_COMMIT}}//\%/%%} # escape % - (( $VCS_STATUS_NUM_STAGED )) && RPROMPT+='+' - (( $VCS_STATUS_NUM_UNSTAGED )) && RPROMPT+='!' - (( $VCS_STATUS_NUM_UNTRACKED )) && RPROMPT+='?' - fi +### For new users - setopt no_prompt_{bang,subst} prompt_percent # enable/disable correct prompt expansions -} +On the first run, Powerlevel10k [configuration wizard](#configuration-wizard) will ask you a few +questions and configure your prompt. If it doesn't trigger automatically, type `p10k configure`. +Configuration wizard creates `~/.p10k.zsh` based on your preferences. Additional prompt +customization can be done by editing this file. It has plenty of comments to help you navigate +through configuration options. + +*FAQ*: + +- [What is the best prompt style in the configuration wizard?]( + #what-is-the-best-prompt-style-in-the-configuration-wizard) +- [What do different symbols in Git status mean?]( + #what-do-different-symbols-in-git-status-mean) +- [How do I change the format of Git status?](#how-do-i-change-the-format-of-git-status) +- [How do I add username and/or hostname to prompt?]( + #how-do-i-add-username-andor-hostname-to-prompt) +- [How do I change prompt colors?](#how-do-i-change-prompt-colors) +- [Why some prompt segments appear and disappear as I'm typing?]( + #why-some-prompt-segments-appear-and-disappear-as-im-typing) + +*Troubleshooting*: + +- [Question mark in prompt](#question-mark-in-prompt). +- [Icons, glyphs or powerline symbols don't render](#icons-glyphs-or-powerline-symbols-dont-render). +- [Sub-pixel imperfections around powerline symbols]( + #sub-pixel-imperfections-around-powerline-symbols). +- [Directory is difficult to see in prompt when using Rainbow style]( + #directory-is-difficult-to-see-in-prompt-when-using-rainbow-style). + +### For Powerlevel9k users + +If you've been using Powerlevel9k before, **do not remove the configuration options**. Powerlevel10k +will pick them up and provide you with the same prompt UI you are used to. See +[Powerlevel9k compatibility](#powerlevel9k-compatibility). + +*FAQ*: + +- [I'm using Powerlevel9k with Oh My Zsh. How do I migrate?]( + #im-using-powerlevel9k-with-oh-my-zsh-how-do-i-migrate) +- [What is the relationship between Powerlevel9k and Powerlevel10k?]( + #what-is-the-relationship-between-powerlevel9k-and-powerlevel10k) +- [Does Powerlevel10k always render exactly the same prompt as Powerlevel9k given the same config?]( + #does-powerlevel10k-always-render-exactly-the-same-prompt-as-powerlevel9k-given-the-same-config) + +*Troubleshooting*: [Extra or missing spaces in prompt compared to Powerlevel9k]( + #extra-or-missing-spaces-in-prompt-compared-to-powerlevel9k). + +## Fonts + +Powerlevel10k doesn't require custom fonts but can take advantage of them if they are available. +It works well with [Nerd Fonts](https://github.com/ryanoasis/nerd-fonts), +[Source Code Pro](https://github.com/adobe-fonts/source-code-pro), +[Font Awesome](https://fontawesome.com/), [Powerline](https://github.com/powerline/fonts), and even +the default system fonts. The full choice of style options is available only when using +[Nerd Fonts](https://github.com/ryanoasis/nerd-fonts). + +👇 **Recommended font**: Meslo Nerd Font patched for Powerlevel10k. 👇 + +### <a name='recommended-meslo-nerd-font-patched-for-powerlevel10k'></a>Meslo Nerd Font patched for Powerlevel10k + +Gorgeous monospace font designed by Jim Lyles for Bitstream, customized by the same for Apple, +further customized by André Berg, and finally patched by yours truly with customized scripts +originally developed by Ryan L McIntyre of Nerd Fonts. Contains all glyphs and symbols that +Powerlevel10k may need. Battle-tested in dozens of different terminals on all major operating +systems. + +*FAQ*: [How was the recommended font created?](#how-was-the-recommended-font-created) + +#### Automatic font installation + +If you are using iTerm2 or Termux, `p10k configure` can install the recommended font for you. +Simply answer `Yes` when asked whether to install *Meslo Nerd Font*. + +If you are using a different terminal, proceed with manual font installation. 👇 + +#### Manual font installation + +Download these four ttf files: + +- [MesloLGS NF Regular.ttf]( + https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Regular.ttf) +- [MesloLGS NF Bold.ttf]( + https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Bold.ttf) +- [MesloLGS NF Italic.ttf]( + https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Italic.ttf) +- [MesloLGS NF Bold Italic.ttf]( + https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Bold%20Italic.ttf) + +Double-click on each file and click "Install". This will make `MesloLGS NF` font available to all +applications on your system. Configure your terminal to use this font: + +- **iTerm2**: Open *iTerm2 → Preferences → Profiles → Text* and set *Font* to `MesloLGS NF`. + Alternatively, type `p10k configure` and answer `Yes` when asked whether to install + *Meslo Nerd Font*. +- **Apple Terminal** Open *Terminal → Preferences → Profiles → Text*, click *Change* under *Font* + and select `MesloLGS NF` family. +- **Hyper**: Open *Hyper → Edit → Preferences* and change the value of `fontFamily` under + `module.exports.config` to `MesloLGS NF`. +- **Visual Studio Code**: Open *File → Preferences → Settings*, enter + `terminal.integrated.fontFamily` in the search box and set the value to `MesloLGS NF`. +- **GNOME Terminal** (the default Ubuntu terminal): Open *Terminal → Preferences* and click on the + selected profile under *Profiles*. Check *Custom font* under *Text Appearance* and select + `MesloLGS NF Regular`. +- **Konsole**: Open *Settings → Edit Current Profile → Appearance*, click *Select Font* and select + `MesloLGS NF Regular`. +- **Tilix**: Open *Tilix → Preferences* and click on the selected profile under *Profiles*. Check + *Custom font* under *Text Appearance* and select `MesloLGS NF Regular`. +- **Windows Console Host** (the old thing): Click the icon in the top left corner, then + *Properties → Font* and set *Font* to `MesloLGS NF`. +- **Windows Terminal** (the new thing): Open *Settings* (`Ctrl+,`), search for `fontFace` and set + value to `MesloLGS NF` for every profile. +- **Termux**: Type `p10k configure` and answer `Yes` when asked whether to install + *Meslo Nerd Font*. +- **Blink** Type `config`, go to *Appearance*, tap *Add a new font*, tap *Open Gallery*, select + *MesloLGS NF.css*, tap *import* and type `exit` in the home view to reload the font. +- **Terminus**: Open *Settings → Appearance* and set *Font* to `MesloLGS NF`. + +**IMPORTANT:** Run `p10k configure` after changing terminal font. The old `~/.p10k.zsh` may work +incorrectly with the new font. + +_Using a different terminal and know how to set the font for it? Share your knowledge by sending a +PR to expand the list!_ + +## Try it in Docker + +Try Powerlevel10k in Docker. You can safely make any changes to the file system while trying out +the theme. Once you exit Zsh, the image is deleted. + +```zsh +docker run -e TERM -e COLORTERM -it --rm alpine sh -uec ' + apk update + apk add git zsh nano vim + git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ~/powerlevel10k + echo "source ~/powerlevel10k/powerlevel10k.zsh-theme" >>~/.zshrc + cd ~/powerlevel10k + exec zsh' +``` + +*Tip*: Install [the recommended font](#meslo-nerd-font-patched-for-powerlevel10k) before +running the Docker command to get access to all prompt styles. + +*Tip*: Run `p10k configure` while in Docker to try a different prompt style. + +## License + +Powerlevel10k is released under the +[MIT license](https://github.com/romkatv/powerlevel10k/blob/master/LICENSE). + +## FAQ + +### How do I update Powerlevel10k? + +The command to update Powerlevel10k depends on how it was installed. + +| Installation | Update command | +|-------------------------|------------------------------------------------| +| [Manual](#manual) | `git -C ~/powerlevel10k pull` | +| [Oh My Zsh](#oh-my-zsh) | `git -C $ZSH_CUSTOM/themes/powerlevel10k pull` | +| [Prezto](#prezto) | `zprezto-update` | +| [Zim](#zim) | `zimfw update` | +| [Antigen](#antigen) | `antigen update` | +| [Zplug](#zplug) | `zplug update` | +| [Zgen](#zgen) | `zgen update` | +| [Zplugin](#zplugin) | `zplugin update` | +| [Zinit](#zinit) | `zinit update` | +| [Homebrew](#homebrew) | `brew update && brew upgrade` | + +**IMPORTANT**: Restart Zsh after updating Powerlevel10k. [Do not use `source ~/.zshrc`]( + #weird-things-happen-after-typing-source-zshrc). + +### Where can I ask for help and report bugs? -gitstatus_stop 'MY' && gitstatus_start -s -1 -u -1 -c -1 -d -1 'MY' -autoload -Uz add-zsh-hook -add-zsh-hook precmd my_set_prompt +The best way to ask for help and to report bugs is to [open an issue]( + https://github.com/romkatv/powerlevel10k/issues). + +[Gitter]( + https://gitter.im/powerlevel10k/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) +is another option. + +If all else fails, email roman.perepelitsa@gmail.com. + +If necessary, encrypt your communication with [this PGP key]( + https://api.github.com/users/romkatv/gpg_keys). + +### Which aspects of shell and terminal does Powerlevel10k affect? + +Powerlevel10k defines prompt and nothing else. It sets [prompt-related options]( + http://zsh.sourceforge.net/Doc/Release/Options.html#Prompting), and parameters `PS1` and `RPS1`. + +![Prompt Highlight]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/prompt-highlight.png) + +Everything within the highlighted areas on the screenshot is produced by Powerlevel10k. +Powerlevel10k has no control over the terminal content or color outside these areas. + +Powerlevel10k does not affect: + +- Terminal window title. +- Colors used by `ls`. +- Content and style of command completions. +- Command line colors (syntax highlighting, autosuggestions, etc.). +- Prompt parameters other than `PS1` and `RPS1`. +- Zsh options other than those [related to prompt]( + http://zsh.sourceforge.net/Doc/Release/Options.html#Prompting). + +### I'm using Powerlevel9k with Oh My Zsh. How do I migrate? + +1. Run this command: +```zsh +# Add powerlevel10k to the list of Oh My Zsh themes. +git clone --depth=1 https://github.com/romkatv/powerlevel10k.git $ZSH_CUSTOM/themes/powerlevel10k +# Replace ZSH_THEME="powerlevel9k/powerlevel9k" with ZSH_THEME="powerlevel10k/powerlevel10k". +sed 's/powerlevel9k/powerlevel10k/g' -i ~/.zshrc +# Restart Zsh. +exec zsh ``` +2. *Optional but highly recommended:* + 1. Install [the recommended font](#meslo-nerd-font-patched-for-powerlevel10k). + 1. Type `p10k configure` and choose your favorite prompt style. -This snippet is sourcing `gitstatus.plugin.zsh` rather than `gitstatus.prompt.zsh`. The former -defines low-level bindings that communicate with gitstatusd over pipes. The latter is a simple -script that uses these bindings to assemble git prompt. +*Related:* + - [Powerlevel9k compatibility.](#powerlevel9k-compatibility) + - [Does Powerlevel10k always render exactly the same prompt as Powerlevel9k given the same config?]( + #does-powerlevel10k-always-render-exactly-the-same-prompt-as-powerlevel9k-given-the-same-config) + - [Extra or missing spaces in prompt compared to Powerlevel9k.]( + #extra-or-missing-spaces-in-prompt-compared-to-powerlevel9k) + - [Configuration wizard.](#configuration-wizard) -Unlike [Powerlevel10k](https://github.com/romkatv/powerlevel10k), code based on -[gitstatus.prompt.zsh](gitstatus.prompt.zsh) is communicating with gitstatusd synchronously. This -can make your prompt slow when working in a large git repository or on a slow machine. To avoid -this problem, call `gitstatus_query` asynchronously as documented in -[gitstatus.plugin.zsh](gitstatus.plugin.zsh). This can be quite challenging. +### Is it really fast? -## Using from Bash +Yes. -The easiest way to take advantage of gitstatus from Bash is via -[gitstatus.prompt.sh](gitstatus.prompt.sh). Install it as follows: +[![asciicast](https://asciinema.org/a/NHRjK3BMePw66jtRVY2livHwZ.svg)]( + https://asciinema.org/a/NHRjK3BMePw66jtRVY2livHwZ) -```bash -git clone --depth=1 https://github.com/romkatv/gitstatus.git ~/gitstatus -echo 'source ~/gitstatus/gitstatus.prompt.sh' >> ~/.bashrc +Benchmark results obtained with +[zsh-prompt-benchmark](https://github.com/romkatv/zsh-prompt-benchmark) on an Intel i9-7900X +running Ubuntu 18.04 with the config from the demo. + +| Theme | Prompt Latency | +|---------------------|---------------:| +| powerlevel9k/master | 1046 ms | +| powerlevel9k/next | 1005 ms | +| **powerlevel10k** | **8.7 ms** | + +Powerlevel10k is over 100 times faster than Powerlevel9k in this benchmark. + +In fairness, Powerlevel9k has acceptable latency when given a spartan configuration. If all you need +is the current directory without truncation or shortening, Powerlevel9k can render it for you in +17 ms. Powerlevel10k can do the same 30 times faster but it won't matter in practice because 17 ms +is fast enough (the threshold where latency becomes noticeable is around 50 ms). You have to be +careful with Powerlevel9k configuration as it's all too easy to make prompt frustratingly slow. +Powerlevel10k, on the other hand, doesn't require trading latency for utility -- it's virtually +instant with any configuration. It stays well below the 50 ms mark, leaving most of the latency +budget for other plugins you might install. + +### How do I enable instant prompt? + +See [instant prompt](#instant-prompt) to learn about instant prompt. This section explains how you +can enable it and lists caveats that you should be aware of. + +Instant prompt can be enabled either through `p10k configure` or by manually adding the following +code snippet at the top of `~/.zshrc`: + +```zsh +# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc. +# Initialization code that may require console input (password prompts, [y/n] +# confirmations, etc.) must go above this block; everything else may go below. +if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then + source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" +fi ``` -Users in mainland China can use the official mirror on gitee.com for faster download.<br> -中国大陆用户可以使用 gitee.com 上的官方镜像加速下载. +It's important that you copy the lines verbatim. Don't replace `source` with something else, don't +call `zcompile`, don't redirect output, etc. + +When instant prompt is enabled, for the duration of Zsh initialization standard input is redirected +to `/dev/null` and standard output with standard error are redirected to a temporary file. Once Zsh +is fully initialized, standard file descriptors are restored and the content of the temporary file +is printed out. -```bash -git clone --depth=1 https://gitee.com/romkatv/gitstatus.git ~/gitstatus -echo 'source ~/gitstatus/gitstatus.prompt.sh' >> ~/.bashrc +When using instant prompt, you should carefully check any output that appears on Zsh startup as it +may indicate that initialization has been altered, or perhaps even broken, by instant prompt. +Initialization code that may require console input, such as asking for a keyring password or for a +*[y/n]* confirmation, must be moved above the instant prompt preamble in `~/.zshrc`. Initialization +code that merely prints to console but never reads from it will work correctly with instant prompt, +although output that normally has colors may appear uncolored. You can either leave it be, suppress +the output, or move it above the instant prompt preamble. + +Here's an example of `~/.zshrc` that breaks when instant prompt is enabled: + +```zsh +if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then + source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" +fi + +keychain id_rsa --agents ssh # asks for password +chatty-script # spams to stdout even when everything is fine +# ... ``` -Alternatively, on macOS you can install with Homebrew: +Fixed version: ```zsh -brew install romkatv/gitstatus/gitstatus -echo 'source /usr/local/opt/gitstatus/gitstatus.prompt.sh' >> ~/.bashrc -``` - -(If you choose this option, replace `~/gitstatus` with `/usr/local/opt/gitstatus` in all code -snippets below.) - -This will give you a basic yet functional prompt with git status in it. It's -[over 10x faster](#benchmarks) than any alternative that can give you comparable prompt. - -![Bash Prompt with GitStatus]( - https://raw.githubusercontent.com/romkatv/gitstatus/1ac366952366d89980b3f3484f270b4fa5ae4293/bash-prompt.png) - -In order to customize your prompt, set `PS1` at the end of `~/.bashrc` after sourcing -`gitstatus.prompt.sh`. Insert `${GITSTATUS_PROMPT}` where you want git status to go. For example: - -```bash -source ~/gitstatus/gitstatus.prompt.sh - -PS1='\w ${GITSTATUS_PROMPT}\n\$ ' # directory followed by git status and $/# (normal/root) -``` - -The expansion of `${GITSTATUS_PROMPT}` can contain the following bits: - -| segment | meaning | -|-------------|-------------------------------------------------------| -| `master` | current branch | -| `#v1` | HEAD is tagged with `v1`; not shown when on a branch | -| `@5fc6fca4` | current commit; not shown when on a branch or tag | -| `⇣1` | local branch is behind the remote by 1 commit | -| `⇡2` | local branch is ahead of the remote by 2 commits | -| `⇠3` | local branch is behind the push remote by 3 commits | -| `⇢4` | local branch is ahead of the push remote by 4 commits | -| `*5` | there are 5 stashes | -| `merge` | merge is in progress (could be some other action) | -| `~6` | there are 6 merge conflicts | -| `+7` | there are 7 staged changes | -| `!8` | there are 8 unstaged changes | -| `?9` | there are 9 untracked files | - -If you'd like to change the format of git status, or want to have greater control over the -process of assembling `PS1`, you can copy and modify parts of -[gitstatus.prompt.sh](gitstatus.prompt.sh) instead of sourcing the script. Your `~/.bashrc` might -look something like this: - -```bash -source ~/gitstatus/gitstatus.plugin.sh - -function my_set_prompt() { - PS1='\w' - - if gitstatus_query && [[ "$VCS_STATUS_RESULT" == ok-sync ]]; then - if [[ -n "$VCS_STATUS_LOCAL_BRANCH" ]]; then - PS1+=" ${VCS_STATUS_LOCAL_BRANCH//\\/\\\\}" # escape backslash - else - PS1+=" @${VCS_STATUS_COMMIT//\\/\\\\}" # escape backslash - fi - [[ "$VCS_STATUS_HAS_STAGED" == 1 ]] && PS1+='+' - [[ "$VCS_STATUS_HAS_UNSTAGED" == 1 ]] && PS1+='!' - [[ "$VCS_STATUS_HAS_UNTRACKED" == 1 ]] && PS1+='?' - fi +keychain id_rsa --agents ssh # moved before instant prompt - PS1+='\n\$ ' +# OK to perform console I/O before this point. +if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then + source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" +fi +# From this point on, until zsh is fully initialized, console input won't work and +# console output may appear uncolored. - shopt -u promptvars # disable expansion of '$(...)' and the like -} +chatty-script >/dev/null # spam output suppressed +# ... +``` + +If `POWERLEVEL9K_INSTANT_PROMPT` is unset or set to `verbose`, Powerlevel10k will print a warning +when it detects console output during initialization to bring attention to potential issues. You can +silence this warning (without suppressing console output) with `POWERLEVEL9K_INSTANT_PROMPT=quiet`. +This is recommended if some initialization code in `~/.zshrc` prints to console and it's infeasible +to move it above the instant prompt preamble or to suppress its output. You can completely disable +instant prompt with `POWERLEVEL9K_INSTANT_PROMPT=off`. Do this if instant prompt breaks Zsh +initialization and you don't know how to fix it. + +*Note*: Instant prompt requires Zsh >= 5.4. It's OK to enable it even when using an older version of +Zsh but it won't do anything. + +### What do different symbols in Git status mean? + +When using Lean, Classic or Rainbow style, Git status may look like this: -gitstatus_stop && gitstatus_start -PROMPT_COMMAND=my_set_prompt +```text +feature:master ⇣42⇡42 ⇠42⇢42 *42 merge ~42 +42 !42 ?42 ``` -This snippet is sourcing `gitstatus.plugin.sh` rather than `gitstatus.prompt.sh`. The former -defines low-level bindings that communicate with gitstatusd over pipes. The latter is a simple -script that uses these bindings to assemble git prompt. +| Symbol | Meaning | Source | +| --------- | -------------------------------------------------------------------- | ------------------------------------------------------ | +| `feature` | current branch; replaced with `#tag` or `@commit` if not on a branch | `git status --ignore-submodules=dirty` | +| `master` | remote tracking branch; only shown if different from local branch | `git rev-parse --abbrev-ref --symbolic-full-name @{u}` | +| `⇣42` | this many commits behind the remote | `git status --ignore-submodules=dirty` | +| `⇡42` | this many commits ahead of the remote | `git status --ignore-submodules=dirty` | +| `⇠42` | this many commits behind the push remote | `git rev-list --left-right --count HEAD...@{push}` | +| `⇢42` | this many commits ahead of the push remote | `git rev-list --left-right --count HEAD...@{push}` | +| `*42` | this many stashes | `git stash list` | +| `merge` | repository state | `git status --ignore-submodules=dirty` | +| `~42` | this many merge conflicts | `git status --ignore-submodules=dirty` | +| `+42` | this many staged changes | `git status --ignore-submodules=dirty` | +| `!42` | this many unstaged changes | `git status --ignore-submodules=dirty` | +| `?42` | this many untracked files | `git status --ignore-submodules=dirty` | +| `─` | the number of staged, unstaged or untracked files is unknown | `echo $POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY` or `git config --get bash.showDirtyState` | + +*Related*: [How do I change the format of Git status?](#how-do-i-change-the-format-of-git-status) + +### How do I change the format of Git status? + +To change the format of Git status, open `~/.p10k.zsh`, search for `my_git_formatter` and edit its +source code. + +*Related*: [What do different symbols in Git status mean?]( + #what-do-different-symbols-in-git-status-mean) + +### Why is Git status from `$HOME/.git` not displayed in prompt? + +When using Lean, Classic or Rainbow style, `~/.p10k.zsh` contains the following parameter: + +```zsh +# Don't show Git status in prompt for repositories whose workdir matches this pattern. +# For example, if set to '~', the Git repository at $HOME/.git will be ignored. +# Multiple patterns can be combined with '|': '~(|/foo)|/bar/baz/*'. +typeset -g POWERLEVEL9K_VCS_DISABLED_WORKDIR_PATTERN='~' +``` + +To see Git status for `$HOME/.git` in prompt, open `~/.p10k.zsh` and remove +`POWERLEVEL9K_VCS_DISABLED_WORKDIR_PATTERN`. + +### Why does Git status sometimes appear grey and then gets colored after a short period of time? -Note: Bash bindings, unlike Zsh bindings, don't support asynchronous calls. +tl;dr: When Git status in prompt is greyed out, it means Powerlevel10k is currently computing +up-to-date Git status in the background. Prompt will get automatically refreshed when this +computation completes. -## Using from other shells +When your current directory is within a Git repository, Powerlevel10k computes up-to-date Git +status after every command. If the repository is large, or the machine is slow, this computation +can take quite a bit of time. If it takes longer than 20 milliseconds (configurable via +`POWERLEVEL9K_VCS_MAX_SYNC_LATENCY_SECONDS`), Powerlevel10k displays the last known Git status in +grey and continues to compute up-to-date Git status in the background. When the computation +completes, Powerlevel10k refreshes prompt with new information, this time with colored Git status. -If there are no gitstatusd bindings for your shell, you'll need to get your hands dirty. -Use the existing bindings for inspiration; run `gitstatusd --help` or read the same thing in -[options.cc](src/options.cc). +### How do I add username and/or hostname to prompt? -## How it works +When using Lean, Classic or Rainbow style, prompt shows `username@hostname` when you are logged in +as root or via SSH. There is little value in showing `username` or `hostname` when you are logged in +to your local machine as a normal user. So the absence of `username@hostname` in your prompt is an +indication that you are working locally and that you aren't root. You can change it, however. -gitstatusd reads requests from stdin and prints responses to stdout. Requests contain an ID and -a directory. Responses contain the same ID and machine-readable git status for the directory. -gitstatusd keeps some state in memory for the directories it has seen in order to serve future -requests faster. +Open `~/.p10k.zsh`. Close to the top you can see the most important parameters that define which +segments are shown in your prompt. All generally useful prompt segments are listed in there. Some of +them are enabled, others are commented out. One of them is of interest to you. -[Zsh bindings](gitstatus.plugin.zsh) and [Bash bindings](gitstatus.plugin.sh) start gitstatusd in -the background and communicate with it via pipes. Themes such as -[Powerlevel10k](https://github.com/romkatv/powerlevel10k) use these bindings to put git status in -`PROMPT`. +```zsh +typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=( + ... + context # user@hostname + ... +) +``` -Note that gitstatus cannot be used as a drop-in replacement for `git status` command as it doesn't -produce output in the same format. It does perform the same computation though. +Search for `context` to find the section in the config that lists parameters specific to this prompt +segment. You should see the following lines: -## Benchmarks +```zsh +# Don't show context unless running with privileges or in SSH. +# Tip: Remove the next line to always show context. +typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_{CONTENT,VISUAL_IDENTIFIER}_EXPANSION= +``` -The following benchmark results were obtained on Intel i9-7900X running Ubuntu 18.04 in -a clean [chromium](https://github.com/chromium/chromium) repository synced to `9394e49a`. The -repository was checked out to an ext4 filesystem on M.2 SSD. +If you follow the tip and remove (or comment out) the last line, you'll always see +`username@hostname` in prompt. You can change the format to just `username`, or change the color, by +adjusting the values of parameters nearby. There are plenty of comments to help you navigate. -Three functionally equivalent tools for computing git status were benchmarked: +You can also move `context` to a different position in `POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS` or even +to `POWERLEVEL9K_LEFT_PROMPT_ELEMENTS`. -* `gitstatusd` -* `git` with untracked cache enabled -* `lg2` -- a demo/example executable from [libgit2](https://github.com/romkatv/libgit2) that - implements a subset of `git` functionality on top of libgit2 API; for the purposes of this - benchmark the subset is sufficient to generate the same data as the other tools +### Why some prompt segments appear and disappear as I'm typing? -Every tool was benchmark in cold and hot conditions. For `git` the first run in a repository was -considered cold, with the following runs considered hot. `lg2` was patched to compute results twice -in a single invocation without freeing the repository in between; the second run was considered hot. -The same patching was not done for `git` because `git` cannot be easily modified to refresh inmemory -index state between invocations; in fact, this limitation is one of the primary reasons developers -use libgit2. `gitstatusd` was benchmarked similarly to `lg2` with two result computations in the -same invocation. +Prompt segments can be configured to be shown only when the current command you are typing invokes +a relevant tool. -Two commands were benchmarked: `status` and `describe`. +```zsh +# Show prompt segment "kubecontext" only when the command you are typing +# invokes kubectl, helm, kubens, kubectx, oc, istioctl or kogito. +typeset -g POWERLEVEL9K_KUBECONTEXT_SHOW_ON_COMMAND='kubectl|helm|kubens|kubectx|oc|istioctl|kogito' +``` -### Status +Configs created by `p10k configure` may contain parameters of this kind. To customize when different +prompt segments are shown, open `~/.p10k.zsh`, search for `SHOW_ON_COMMAND` and either remove these +parameters or change their values. -In this benchmark all tools were computing the equivalent of `git status`. Lower numbers are better. +You can also define a function in `~/.zshrc` to toggle the display of a prompt segment between +*always* and *on command*. This is similar to `kubeon`/`kubeoff` from +[kube-ps1](https://github.com/jonmosco/kube-ps1). -| Tool | Cold | Hot | -|---------------|-----------:|------------:| -| **gitstatus** | **291 ms** | **30.9 ms** | -| git | 876 ms | 295 ms | -| lg2 | 1730 ms | 1310 ms | +```zsh +function kube-toggle() { + if (( ${+POWERLEVEL9K_KUBECONTEXT_SHOW_ON_COMMAND} )); then + unset POWERLEVEL9K_KUBECONTEXT_SHOW_ON_COMMAND + else + POWERLEVEL9K_KUBECONTEXT_SHOW_ON_COMMAND='kubectl|helm|kubens|kubectx|oc|istioctl|kogito' + fi + p10k reload + if zle; then + zle push-input + zle accept-line + fi +} +``` -gitstatusd is substantially faster than the alternatives, especially on hot runs. Note that hot runs -are of primary importance to the main use case of gitstatus in interactive shells. +Invoke this function by typing `kube-toggle`. You can also bind it to a key by adding two more lines +to `~/.zshrc`: -The performance of `git status` fluctuated wildly in this benchmarks for reasons unknown to the -author. Moreover, performance is sticky -- once `git status` settles around a number, it stays -there for a long time. Numbers as diverse as 295, 352, 663 and 730 had been observed on hot runs on -the same repository. The number in the table is the lowest (fastest or best) that `git status` had -shown. +```zsh +zle -N kube-toggle +bindkey '^]' kube-toggle # ctrl-] to toggle kubecontext in powerlevel10k prompt +``` + +### How do I change prompt colors? + +You can either [change the color palette used by your terminal]( + #change-the-color-palette-used-by-your-terminal) or +[set colors through Powerlevel10k configuration parameters]( + #set-colors-through-Powerlevel10k-configuration-parameters). -### Describe +#### Change the color palette used by your terminal -In this benchmark all tools were computing the equivalent of `git describe --tags --exact-match` -to find tags that resolve to the same commit as `HEAD`. Lower numbers are better. +How exactly you change the terminal color palette (a.k.a. color scheme, or theme) depends on the +kind of terminal you are using. Look around in terminal's settings/preferences or consult +documentation. -| Tool | Cold | Hot | -|---------------|------------:|--------------:| -| **gitstatus** | **4.04 ms** | **0.0345 ms** | -| git | 18.0 ms | 14.5 ms | -| lg2 | 185 ms | 45.2 ms | +When you change the terminal color palette, it usually affects only the first 16 colors, numbered +from 0 to 15. In order to see any effect on Powerlevel10k prompt, you need to use prompt style that +utilizes these low-numbered colors. Type `p10k configure` and select *Rainbow*, *Lean* → *8 colors* +or *Pure* → *Original*. Other styles use higher-numbered colors, so they look the same in any +terminal color palette. -gitstatusd is once again faster than the alternatives, more so on hot runs. +#### Set colors through Powerlevel10k configuration parameters -## Why fast +Open `~/.p10k.zsh`, search for "color", "foreground" and "background" and change values of +appropriate parameters. For example, here's how you can set the foreground of `time` prompt segment +to bright red: + +```zsh +typeset -g POWERLEVEL9K_TIME_FOREGROUND=160 +``` -Since gitstatusd doesn't have to print all staged/unstaged/untracked files but only report -whether there are any, it can terminate repository scan early. It can also remember which files -were dirty on the previous run and check them first on the next run to avoid the scan entirely if -the files are still dirty. However, the benchmarks above were performed in a clean repository where -these shortcuts do not trigger. All benchmarked tools had to do the same work -- check the status -of every file in the index to see if it has changed, check every directory for newly created files, -etc. And yet, gitstatusd came ahead by a large margin. This section describes what it does that -makes it so fast. - -Most of the following comparisons are done against libgit2 rather than git because of the author's -familiarity with the former but not the with latter. libgit2 has clean, well-documented APIs and an -elegant implementation, which makes it so much easier to work with and to analyze performance -bottlenecks. - -### Summary for the impatient - -Under the benchmark conditions described above, the equivalent of libgit2's -`git_diff_index_to_workdir` (the most expensive part of `status` command) is 46.3 times faster in -gitstatusd. The speedup comes from the following sources. - -* gitstatusd uses more efficient data structures and algorithms and employs performance-conscious -coding style throughout the codebase. This reduces CPU time in userspace by 32x compared to libgit2. -* gitstatusd uses less expensive system calls and makes fewer of them. This reduces CPU time spent -in kernel by 1.9x. -* gitstatusd can utilize multiple cores to scan index and workdir in parallel with almost perfect -scaling. This reduces total run time by 12.4x while having virtually no effect on total CPU time. - -### Problem statement - -The most resource-intensive part of the `status` command is finding the difference between _index_ -and _workdir_ (`git_diff_index_to_workdir` in libgit2). Index is a list of all files in the git -repository with their last modification times. This is an obvious simplification but it suffices for -this exposition. On disk, index is stored sorted by file path. Here's an example of git index: - -| File | Last modification time | -|-------------|-----------------------:| -| Makefile | 2019-04-01T14:12:32Z | -| src/hello.c | 2019-04-01T14:12:00Z | -| src/hello.h | 2019-04-01T14:12:32Z | - -This list needs to be compared to the list of files in the working directory. If any of the files -listed in the index are missing from the workdir or have different last modification time, they are -"unstaged" in gitstatusd parlance. If you run `git status`, they'll be shown as "changes not staged -for commit". Thus, any implementation of `status` command has to call `stat()` or one of its -variants on every file in the index. - -In addition, all files in the working directory for which there is no entry in the index at all are -"untracked". `git status` will show them as "untracked files". Finding untracked files requires some -form of work directory traversal. - -### Single-threaded scan - -Let's see how `git_diff_index_to_workdir` from libgit2 accomplishes these tasks. Here's its CPU -profile from 200 hot runs over chromium repository. - -![libgit2 CPU profile (hot)]( - https://raw.githubusercontent.com/romkatv/gitstatus/1ac366952366d89980b3f3484f270b4fa5ae4293/cpu-profile-libgit2.png) - -(The CPU profile was created with [gperftools](https://github.com/gperftools/gperftools) and -rendered with [pprof](https://github.com/google/pprof)). - -We can see `__GI__lxstat` taking a lot of time. This is the `stat()` call for every file in the -index. We can also identify `__opendir`, `__readdir` and `__GI___close_nocancel` -- glibc wrappers -for reading the contents of a directory. This is for finding untracked files. Out of the total 232 -seconds, 111 seconds -- or 47.7% -- was spent on these calls. The rest is computation -- comparing -strings, sorting arrays, etc. - -Now let's take a look at the CPU profile of gitstatusd on the same task. - -![gitstatusd CPU profile (hot)]( - https://raw.githubusercontent.com/romkatv/gitstatus/1ac366952366d89980b3f3484f270b4fa5ae4293/cpu-profile-gitstatusd-hot.png) - -The first impression is that this profile looks pruned. This isn't an artifact. The profile was -generated with the same tools and the same flags as the profile of libgit2. - -Since both profiles were generated from the same workload, absolute numbers can be compared. We can -see that gitstatusd took 62 seconds in total compared to libgit2's 232 seconds. System calls at the -core of the algorithm are cleary visible. `__GI___fxstatat` is a flavor of `stat()`, and the other -three calls -- `__libc_openat64`, `__libc_close` and `__GI___fxstat` are responsible for opening -directories and finding untracked files. Notice that there is almost nothing else in the profile -apart from these calls. The rest of the code accounts for 3.77 seconds of CPU time -- 32 times less -than in libgit2. - -So, one reason gitstatusd is fast is that it has efficient diffing code -- very little time is spent -outside of kernel. However, if we look closely, we can notice that system calls in gitstatusd are -_also_ faster than in libgit2. For example, libgit2 spent 72.07 seconds in `__GI__lxstat` while -gitstatusd spent only 48.82 seconds in `__GI___fxstatat`. There are two reasons for this difference. -First, libgit2 makes more `stat()` calls than is strictly required. It's not necessary to stat -directories because index only has files. There are 25k directories in chromium repository (and 300k -files) -- that's 25k `stat()` calls that could be avoided. The second reason is that libgit2 and -gitstatusd use different flavors of `stat()`. libgit2 uses `lstat()`, which takes a path to the file -as input. Its performance is linear in the number of subdirectories in the path because it needs to -perform a lookup for every one of them and to check permissions. gitstatusd uses `fstatat()`, which -takes a file descriptor to the parent directory and a name of the file. Just a single lookup, less -CPU time. - -Similarly to `lstat()` vs `fstatat()`, it's faster to open files and directories with `openat()` -from the parent directory file descriptor than with regular `open()` that accepts full file path. -gitstatusd takes advantage of `openat()` to open directories as fast as possible. It opens about 90% -of the directories (this depends on the actual directory structure of the repository) from the -immediate parent -- the most efficient way -- and the remaining 10% it opens from the repository's -root directory. The reason it's done this way is to keep the maximum number of simultaneously open -file descriptors bounded. libgit2 can have O(repository depth) simultaneously open file descriptors, -which may be OK for a single-threaded application but can balloon to a large number when scans are -done by many threads simultaneously, like in gitstatusd. - -There is no equivalent to `__opendir` or `__readdir` in the gitstatusd profile because it uses the -equivalent of [untracked cache](https://git-scm.com/docs/git-update-index#_untracked_cache) from -git. On the first scan of the workdir gitstatusd lists all files just like libgit2. But, unlike -libgit2, it remembers the last modification time of every directory along with the list of -untracked files under it. On the next scan, gitstatusd can skip listing files in directories whose -last modification time hasn't changed. - -To summarize, here's what gitstatusd was doing when the CPU profile was captured: - -1. `__libc_openat64`: Open every directory for which there are files in the index. -2. `__GI___fxstat`: Check last modification time of the directory. Since it's the same as on the - last scan, this directory has the same list of untracked files as before, which is empty (the - repository is clean). -3. `__GI___fxstatat`: Check last modification time for every file in the index that belongs to this - directory. -4. `__libc_close`: Close the file descriptor to the directory. - -Here's how the very first scan of a repository looks like in gitstatusd: - -![gitstatusd CPU profile (cold)]( - https://raw.githubusercontent.com/romkatv/gitstatus/1ac366952366d89980b3f3484f270b4fa5ae4293/cpu-profile-gitstatusd-cold.png) - -(Some glibc functions are mislabel on this profile. `explicit_bzero` and `__nss_passwd_lookup` are -in reality `strcmp` and `memcmp`.) - -This is a superset of the previous -- hot -- profile, with an extra `syscall` and string sorting for -directory listing. gitstatusd uses `getdents64` Linux system call directly, bypassing the glibc -wrapper that libgit2 uses. This is 23% faster. The details of this optimization can be found in a -[separate document](docs/listdir.md). - -### Multithreading - -The diffing algorithm in gitstatusd was designed from the ground up with the intention of using it -concurrently from multiple threads. With a fast SSD, `status` is CPU bound, so taking advantage of -all available CPU cores is an obvious way to yield results faster. - -gitstatusd exhibits almost perfect scaling from multithreading. Engaging all cores allows it to -produce results 12.4 times faster than in single-threaded execution. This is on Intel i9-7900X with -10 cores (20 with hyperthreading) with single-core frequency of 4.3GHz and all-core frequency of -4.0GHz. - -Note: `git status` also uses all available cores in some parts of its algorithm while `lg2` does -everything in a single thread. +Colors are specified using numbers from 0 to 255. Colors from 0 to 15 look differently in different +terminals. Many terminals also support customization of these colors through color palettes +(a.k.a. color schemes, or themes). Colors from 16 to 255 always look the same. -### Postprocessing +Type `source ~/.p10k.zsh` to apply your changes to the current Zsh session. -Once the difference between the index and the workdir is found, we have a list of _candidates_ -- -files that may be unstaged or untracked. To make the final judgement, these files need to be checked -against `.gitignore` rules and a few other things. - -gitstatusd uses [patched libgit2](https://github.com/romkatv/libgit2) for this step. This fork -adds several optimizations that make libgit2 faster. The patched libgit2 performs more than twice -as fast in the benchmark as the original even without changes in the user code (that is, in the -code that uses the libgit2 APIs). The fork also adds several API extensions, most notable of which -is the support for multi-threaded scans. If `lg2 status` is modified to take advantage of these -extensions, it outperforms the original libgit2 by a factor of 18. Lastly, the fork fixes a score of -bugs, most of which become apparent only when using libgit2 from multiple threads. - -_WARNING: Changes to libgit2 are extensive but the testing they underwent isn't. It is -**not recommended** to use the patched libgit2 in production._ - -## Requirements - -* To compile: binutils, cmake, gcc, g++, git and GNU make. -* To run: Linux, macOS, FreeBSD, Android, WSL, Cygwin or MSYS2. - -## Compiling - -There are prebuilt `gitstatusd` binaries in [releases]( - https://github.com/romkatv/gitstatus/releases). When using the official shell bindings -provided by gitstatus, the right binary for your architecture gets downloaded automatically. - -If prebuilt binaries don't work for you, you'll need to get your hands dirty. - -### Compiling for personal use +To see how different colors look in your terminal, run the following command: ```zsh -git clone --depth=1 https://github.com/romkatv/gitstatus.git -cd gitstatus -./build -w -s -d docker +for i in {0..255}; do print -Pn "%K{$i} %k%F{$i}${(l:3::0:)i}%f " ${${(M)$((i%6)):#3}:+$'\n'}; done ``` -Users in mainland China can use the official mirror on gitee.com for faster download.<br> -中国大陆用户可以使用 gitee.com 上的官方镜像加速下载. +### Why does Powerlevel10k spawn extra processes? + +Powerlevel10k uses [gitstatus](https://github.com/romkatv/gitstatus) as the backend behind `vcs` +prompt; gitstatus spawns `gitstatusd` and `zsh`. See +[gitstatus](https://github.com/romkatv/gitstatus) for details. Powerlevel10k may also spawn `zsh` +to perform computation without blocking prompt. To avoid security hazard, these background processes +aren't shared by different interactive shells. They terminate automatically when the parent `zsh` +process terminates or runs `exec(3)`. + +### Are there configuration options that make Powerlevel10k slow? + +No, Powerlevel10k is always fast, with any configuration you throw at it. If you have noticeable +prompt latency when using Powerlevel10k, please +[open an issue](https://github.com/romkatv/powerlevel10k/issues). + +### Is Powerlevel10k fast to load? + +Yes, provided that you are using Zsh >= 5.4. + +Loading time, or time to first prompt, can be measured with the following benchmark: ```zsh -git clone --depth=1 https://gitee.com/romkatv/gitstatus.git -cd gitstatus -./build -w -s -d docker +time (repeat 1000 zsh -dfis <<< 'source ~/powerlevel10k/powerlevel10k.zsh-theme') ``` -- If it says that `-d docker` is not supported on your OS, remove this flag. -- If it says that `-s` is not supported on your OS, remove this flag. -- If it tell you to install docker but you cannot or don't want to, remove `-d docker`. -- If it says that some command is missing, install it. +*Note:* This measures time to first complete prompt. Powerlevel10k can also display a +[limited prompt](#instant-prompt) before the full-featured prompt is ready. + +Running this command with `~/powerlevel10k` as the current directory on the same machine as in the +[prompt benchmark](#is-it-really-fast) takes 29 seconds (29 ms per invocation). This is about 6 +times faster than powerlevel9k/master and 17 times faster than powerlevel9k/next. + +### What is the relationship between Powerlevel9k and Powerlevel10k? + +Powerlevel10k was forked from Powerlevel9k in March 2019 after a week-long discussion in +[powerlevel9k#1170](https://github.com/Powerlevel9k/powerlevel9k/issues/1170). Powerlevel9k was +already a mature project with large user base and release cycle measured in months. Powerlevel10k +was spun off to iterate on performance improvements and new features at much higher pace. + +Powerlevel9k and Powerlevel10k are independent projects. When using one, you shouldn't install the +other. Issues should be filed against the project that you actually use. There are no individuals +that have commit rights in both repositories. All bug fixes and new features committed to +Powerlevel9k repository get ported to Powerlevel10k. + +Over time, virtually all code in Powerlevel10k has been rewritten. There is currently no meaningful +overlap between the implementations of Powerlevel9k and Powerlevel10k. + +Powerlevel10k is committed to maintaining backward compatibility with all configs indefinitely. This +commitment covers all configuration parameters recognized by Powerlevel9k (see +[Powerlevel9k compatibility](#powerlevel9k-compatibility)) and additional parameters that only +Powerlevel10k understands. Names of all parameters in Powerlevel10k start with `POWERLEVEL9K_` for +consistency. + +### Does Powerlevel10k always render exactly the same prompt as Powerlevel9k given the same config? + +Almost. There are a few differences. + +- By default only `git` vcs backend is enabled in Powerlevel10k. If you need `svn` and `hg`, add + them to `POWERLEVEL9K_VCS_BACKENDS`. These backends aren't yet optimized in Powerlevel10k, so + enabling them will make prompt *very slow*. +- Powerlevel10k doesn't support `POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY=true`. +- Powerlevel10k strives to be bug-compatible with Powerlevel9k but not when it comes to egregious + bugs. If you accidentally rely on these bugs, your prompt will differ between Powerlevel9k and + Powerlevel10k. Some examples: + - Powerlevel9k ignores some options that are set after the theme is sourced while Powerlevel10k + respects all options. If you see different icons in Powerlevel9k and Powerlevel10k, you've + probably defined `POWERLEVEL9K_MODE` before sourcing the theme. This parameter gets ignored + by Powerlevel9k but honored by Powerlevel10k. If you want your prompt to look in Powerlevel10k + the same as in Powerlevel9k, remove `POWERLEVEL9K_MODE`. + - Powerlevel9k doesn't respect `ZLE_RPROMPT_INDENT`. As a result, right prompt in Powerlevel10k + can have an extra space at the end compared to Powerlevel9k. Set `ZLE_RPROMPT_INDENT=0` if you + don't want that space. More details in + [troubleshooting](#extra-space-without-background-on-the-right-side-of-right-prompt). + - Powerlevel9k has inconsistent spacing around icons. This was fixed in Powerlevel10k. Set + `POWERLEVEL9K_LEGACY_ICON_SPACING=true` to get the same spacing as in Powerlevel9k. More + details in [troubleshooting](#extra-or-missing-spaces-around-icons). + - There are dozens more bugs in Powerlevel9k that don't exist in Powerlevel10k. + +If you notice any other changes in prompt appearance when switching from Powerlevel9k to +Powerlevel10k, please [open an issue](https://github.com/romkatv/powerlevel10k/issues). + +### What is the best prompt style in the configuration wizard? + +There are as many opinions on what constitutes the best prompt as there are people. It mostly comes +down to personal preference. There are, however, a few hidden implications of different choices. + +Pure style is an exact replication of [Pure Zsh theme](https://github.com/sindresorhus/pure). It +exists to ease the migration for users of this theme. Unless you are one of them, choose Lean +style over Pure. + +If you want to confine prompt colors to the selected terminal color palette (say, *Solarized Dark*), +use *Rainbow*, *Lean* → *8 colors* or *Pure* → *Original*. Other styles use fixed colors and thus +look the same in any terminal color palette. + +All styles except Pure have an option to use *ASCII* charset. Prompt will look less pretty but will +render correctly with all fonts and in all locales. + +If you enable transient prompt, take advantage of two-line prompt. You'll get the benefit of +extra space for typing commands without the usual drawback of reduced scrollback density. Having +all commands start from the same offset is also nice. + +Similarly, if you enable transient prompt, sparse prompt (with an empty line before prompt) is a +great choice. + +If you are using vi keymap, choose prompt with `prompt_char` in it (shown as green `❯` in the +wizard). This symbol changes depending on vi mode: `❯`, `❮`, `Ⅴ`, `▶` for insert, command, visual +and replace mode respectively. When a command fails, the symbol turns red. *Lean* style always has +`prompt_char` in it. *Rainbow* and *Classic* styles have it only in the two-line configuration +without left frame. + +If you value horizontal space or prefer minimalist aesthetics: + +- Use a monospace font, such as [the recommended font](#meslo-nerd-font-patched-for-powerlevel10k). + Non-monospace fonts require extra space after icons that are larger than a single column. +- Use Lean style. Compared to Classic and Rainbow, it saves two characters per prompt segment. +- Disable *current time* and *frame*. +- Use *few icons*. The extra icons enabled by the *many icons* option primarily serve decorative + function. Informative icons, such as background job indicator, will be shown either way. -If everything goes well, the newly built binary will appear in `./usrbin`. It'll be picked up -by shell bindings automatically. +*Note*: You can run configuration wizard as many times as you like. Type `p10k configure` to try new +prompt style. -When you update shell bindings, they may refuse to work with the binary you've built earlier. In -this case you'll need to rebuild. +### How to make Powerlevel10k look like robbyrussell Oh My Zsh theme? -### Compiling for distribution +Use [this config]( + https://github.com/romkatv/powerlevel10k/blob/master/config/p10k-robbyrussell.zsh). -If you want to package gitstatus, it's best to do it based off [releases]( - https://github.com/romkatv/gitstatus/releases). +You can either download it, save as `~/.p10k.zsh` and `source ~/.p10k.zsh` from `~/.zshrc`, or +source `p10k-robbyrussell.zsh` directly from your cloned `powerlevel10k` repository. -The following code should work without patching anything in gitstatus sources. If it doesn't, please -open an issue. +### Can prompts for completed commands display error status for *those* commands instead of the commands preceding them? + +No. When you hit *ENTER* and the command you've typed starts running, its error status isn't yet +known, so it cannot be shown in prompt. When the command completes, the error status gets known but +it's no longer possible to update prompt for *that* command. This is why the error status for every +command is reflected in the *next* prompt. + +For details, see [this post on /r/zsh]( +https://www.reddit.com/r/zsh/comments/eg49ff/powerlevel10k_prompt_history_exit_code_colors/fc5huku). + +### Is there an AUR package for Powerlevel10k? + +There is [zsh-theme-powerlevel10k-git]( + https://aur.archlinux.org/packages/zsh-theme-powerlevel10k-git/). It's owned by an unaffiliated +volunteer. + +There is also an [official Powerlevel10k package](#arch-linux) for Pacman. + +### What is the minimum supported Zsh version? + +Zsh 5.1 or newer should work. Fast startup requires Zsh >= 5.4. + +### How were these screenshots and animated gifs created? + +All screenshots and animated gifs were recorded in GNOME Terminal with +[the recommended font](#meslo-nerd-font-patched-for-powerlevel10k) and Tango Dark color palette with +custom background color (`#171A1B` instead of `#2E3436` -- twice as dark). + +![GNOME Terminal Color Settings]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/gnome-terminal-colors.png) + +Syntax highlighting, where present, was provided by [zsh-syntax-highlighting]( + https://github.com/zsh-users/zsh-syntax-highlighting). + +### How was the recommended font created? + +[The recommended font](#meslo-nerd-font-patched-for-powerlevel10k) is the product of many +individuals. Its origin is *Bitstream Vera Sans Mono*, which has given birth to *Menlo*, which in +turn has spawned *Meslo*. Finally, extra glyphs have been added to *Meslo* with scripts forked +from Nerd Fonts. The final font is released under the terms of +[Apache License]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/MesloLGS%20NF%20License.txt). + + +MesloLGS NF font can be recreated with the following command (requires `git` and `docker`): + +```zsh +git clone --depth=1 https://github.com/romkatv/nerd-fonts.git +cd nerd-fonts +./build 'Meslo/S/*' +``` + +If everything goes well, four `ttf` files will appear in `./out`. + +### How to package Powerlevel10k for distribution? + +If you want to package Powerlevel10k, it's best to do it based off [releases]( + https://github.com/romkatv/powerlevel10k/releases). + +The following code should work without patching anything in Powerlevel10k sources. If it doesn't, +please open an issue. **IMPORTANT:** *Change version to what you want to package. This example doesn't get updated when new versions are released.* ```zsh -# Download and extract gitstatus tarball. -gitstatus_version=1.1.0 # IMPORTANT: CHANGE VERSION TO WHAT YOU WANT -wget https://github.com/romkatv/gitstatus/archive/v"$gitstatus_version".tar.gz -tar -xzf v"$gitstatus_version".tar.gz -cd gitstatus-"$gitstatus_version" +# Download and extract Powerlevel10k tarball. +powerlevel10k_version=1.9.0 # IMPORTANT: CHANGE VERSION TO WHAT YOU WANT +wget https://github.com/romkatv/powerlevel10k/archive/v"$powerlevel10k_version".tar.gz +tar -xzf v"$powerlevel10k_version".tar.gz +cd powerlevel10k-"$powerlevel10k_version" # Download libgit2 tarball and compile gitstatusd. -./build -w +./gitstatus/build -w # Post-process. -rm ./deps/libgit2-*.tar.gz -for file in *.zsh install; do +rm ./gitstatus/deps/libgit2-*.tar.gz +for file in *.zsh-theme internal/*.zsh gitstatus/*.zsh gitstatus/install; do zsh -fc "emulate zsh -o no_aliases && zcompile -R -- $file.zwc $file" done ``` @@ -544,52 +1158,635 @@ This needs binutils, cmake, gcc, g++, git, GNU make, wget, zsh and either shasum Once build completes, *do not delete or move any files*. Package the whole directory as is. Don't add the directory or any of its subdirectories to `PATH`. -You probably don't want to build in docker, so don't pass `-d` to `./build`. +You probably don't want to build in docker, so don't pass `-d` to `./gitstatus/build`. gitstatus depends on a [custom fork of libgit2](https://github.com/romkatv/libgit2/). When you run -`./build -w`, it'll automatically download the appropriate libgit2 tarball and verify its sha256. -If you want to separate the downloading of source tarballs from compilation, you can download the -libgit2 tarball manually and invoke `./build` without `-w`. +`./gitstatus/build -w`, it'll automatically download the appropriate libgit2 tarball and verify its +sha256. If you want to separate the downloading of source tarballs from compilation, you can +download the libgit2 tarball manually and invoke `./gitstatus/build` without `-w`. ```zsh -# Download and extract gitstatus tarball. -gitstatus_version=1.1.0 # IMPORTANT: CHANGE VERSION TO WHAT YOU WANT -wget https://github.com/romkatv/gitstatus/archive/v"$gitstatus_version".tar.gz -tar -xzf v"$gitstatus_version".tar.gz -cd gitstatus-"$gitstatus_version" - -# Download libgit2 tarball and place it where ./build expects it. -. ./build.info -libgit2_path=./deps/libgit2-"$libgit2_version".tar.gz +# Download and extract Powerlevel10k tarball. +powerlevel10k_version=1.9.0 # IMPORTANT: CHANGE VERSION TO WHAT YOU WANT +wget https://github.com/romkatv/powerlevel10k/archive/v"$powerlevel10k_version".tar.gz +tar -xzf v"$powerlevel10k_version".tar.gz +cd powerlevel10k-"$powerlevel10k_version" + +# Download libgit2 tarball and place it where ./gitstatus/build expects it. +. ./gitstatus/build.info +libgit2_path=./gitstatus/deps/libgit2-"$libgit2_version".tar.gz libgit2_url=https://github.com/romkatv/libgit2/archive/"$libgit2_version".tar.gz wget -O "$libgit2_path" "$libgit2_url" # Compile gitstatusd. -./build +./gitstatus/build # Post-process. -rm ./deps/libgit2-*.tar.gz -for file in *.zsh install; do +rm ./gitstatus/deps/libgit2-*.tar.gz +for file in *.zsh-theme internal/*.zsh gitstatus/*.zsh gitstatus/install; do zsh -fc "emulate zsh -o no_aliases && zcompile -R -- $file.zwc $file" done ``` -Note that the URL and the content of the libgit2 tarball are fully defined by the main gitstatus +Note that the URL and the content of the libgit2 tarball are fully defined by the main Powerlevel10k tarball. Thus, you can set URLs and sha256 checksums of the two tarball in the same place (package definition) and update them at the same time when bumping package version. In other words, you don't have to extract `libgit2_version` programmatically. You can manually copy it from [build.info]( - https://github.com/romkatv/gitstatus/blob/master/build.info) to your package definition, if you -prefer. + https://github.com/romkatv/powerlevel10k/blob/master/gitstatus/build.info) to your package +definition, if you prefer. -[Powerlevel10k](https://github.com/romkatv/powerlevel10k) has an embedded version of gitstatus. It -must stay that way. If you decide to package both of them, follow the respective instructions from -each project. The embedded gitstatus in Powerlevel10k won't conflict with the standalone gitstatus. -They can have different versions and can coexist within the same Zsh process. Do not attempt to +Powerlevel10k has an embedded version of [gitstatus](https://github.com/romkatv/gitstatus). It must +stay that way. If you decide to package both of them, follow the respective instructions from each +project. The embedded gitstatus in Powerlevel10k won't conflict with the standalone gitstatus. They +can have different versions and can coexist within the same Zsh process. Do not attempt to surgically remove gitstatus from Powerlevel10k, package the result and then force Powerlevel10k to use a separately packaged gitstatus. Instead, treat Powerlevel10k and gitstatus as independent projects that don't depend on each other. -## License +## Troubleshooting + +### Question mark in prompt + +If it looks like a regular `?`, that's normal. It means you have untracked files in the current Git +repository. Type `git status` to see these files. You can change this symbol or disable the display +of untracked files altogether. Search for `untracked files` in `~/.p10k.zsh`. + +*FAQ*: [What do different symbols in Git status mean?]( + #what-do-different-symbols-in-git-status-mean) + +You can also get a weird-looking question mark in your prompt if your terminal's font is missing +some glyphs. See [icons, glyphs or powerline symbols don't render]( + #icons-glyphs-or-powerline-symbols-dont-render). + +### Icons, glyphs or powerline symbols don't render + +Restart your terminal, [install the recommended font](#meslo-nerd-font-patched-for-powerlevel10k) +and run `p10k configure`. + +### Sub-pixel imperfections around powerline symbols + +![Powerline Prompt Imperfections]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/powerline-imperfections.png) + +There are three imperfections on the screenshot. From left to right: + +1. A thin blue line (a sub-pixel gap) between the content of a prompt segment and the following +powerline connection. +1. Incorrect alignment of a powerline connection and the following prompt segment. The connection +appears shifted to the right. +1. A thin red line below a powerline connection. The connection appears shifted up. + +Zsh themes don't have down-to-pixel control over the terminal content. Everything you see on the +screen is made of monospace characters. A white powerline prompt segment is made of text on white +background followed by U+E0B0 (a right-pointing triangle). + +![Powerline Prompt Imperfections]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/powerline-anatomy.png) + +If Powerlevel10k prompt has imperfections around powerline symbols, you'll see exactly the same +imperfections with all powerline themes (Agnoster, Powerlevel9k, Powerline, etc.) + +There are several things you can try to deal with these imperfections: + +- Try [the recommended font](#meslo-nerd-font-patched-for-powerlevel10k). If you are already using + it, switching to another font may help but is unlikely. +- Change terminal font size one point up or down. For example, in iTerm2 powerline prompt looks + perfect at font sizes 11 and 13 but breaks down at 12. +- Enable builtin powerline glyphs in terminal settings if your terminal supports it (iTerm2 does). +- Change font hinting and/or anti-aliasing mode in the terminal settings. +- Shift all text one pixel up/down/left/right if your terminal has an option to do so. +- Try a different terminal. + +A more radical solution is to switch to prompt style without background. Type `p10k configure` and +select *Lean*. This style has a modern lightweight look. As a bonus, it doesn't suffer from +rendering imperfections that afflict powerline-style prompt. + +### Error: character not in range + +Type `echo '\u276F'`. If you get an error saying "zsh: character not in range", your locale +doesn't support UTF-8. You need to fix it. If you are running Zsh over SSH, see +[this](https://github.com/romkatv/powerlevel10k/issues/153#issuecomment-518347833). If you are +running Zsh locally, Google "set UTF-8 locale in *your OS*". + +### Cursor is in the wrong place + +Type `echo '\u276F'`. If you get an error saying "zsh: character not in range", see the +[previous section](#zsh-character-not-in-range). + +If the `echo` command prints `❯` but the cursor is still in the wrong place, install +[the recommended font](#meslo-nerd-font-patched-for-powerlevel10k) and run +`p10k configure`. + +If this doesn't help, add `unset ZLE_RPROMPT_INDENT` at the bottom of `~/.zshrc`. + +Still having issues? Run the following command to diagnose the problem: + +```zsh +() { + emulate -L zsh + setopt err_return no_unset + local text + print -rl -- 'Select a part of your prompt from the terminal window and paste it below.' '' + read -r '?Prompt: ' text + local -i len=${(m)#text} + local frame="+-${(pl.$len..-.):-}-+" + print -lr -- $frame "| $text |" $frame +} +``` + +#### If the prompt line aligns with the frame + +```text ++------------------------------+ +| romka@adam ✓ ~/powerlevel10k | ++------------------------------+ +``` + +If the output of the command is aligned for every part of your prompt (left and right), this +indicates a bug in the theme or your config. Use this command to diagnose it: + +```zsh +print -rl -- ${(eq+)PROMPT} ${(eq+)RPROMPT} +``` + +Look for `%{...%}` and backslash escapes in the output. If there are any, they are the likely +culprits. Open an issue if you get stuck. + +#### If the prompt line is longer than the frame + +```text ++-----------------------------+ +| romka@adam ✓ ~/powerlevel10k | ++-----------------------------+ +``` + +This is usually caused by a terminal bug or misconfiguration that makes it print ambiguous-width +characters as double-width instead of single width. For example, +[this issue](https://github.com/romkatv/powerlevel10k/issues/165). + +#### If the prompt line is shorter than the frame and is mangled + +```text ++------------------------------+ +| romka@adam ✓~/powerlevel10k | ++------------------------------+ +``` + +Note that this prompt is different from the original as it's missing a space after the check mark. + +This can be caused by a low-level bug in macOS. See +[this issue](https://github.com/romkatv/powerlevel10k/issues/241). + +This can also happen if prompt contains glyphs designated as "wide" in the Unicode standard and your +terminal incorrectly displays them as non-wide. Terminals suffering from this limitation include +Konsole, Hyper and the integrated VSCode Terminal. The solution is to use a different terminal or +remove all wide glyphs from prompt. + +#### If the prompt line is shorter than the frame and is not mangled + +```text ++--------------------------------+ +| romka@adam ✓ ~/powerlevel10k | ++--------------------------------+ +``` + +This can be caused by misconfigured locale. See +[this issue](https://github.com/romkatv/powerlevel10k/issues/251). + +### Prompt wrapping around in a weird way + +See [cursor is in the wrong place](#cursor-is-in-the-wrong-place). + +### Right prompt is in the wrong place + +See [cursor is in the wrong place](#cursor-is-in-the-wrong-place). + +### Configuration wizard runs automatically every time Zsh is started + +When Powerlevel10k starts, it automatically runs `p10k configure` if no `POWERLEVEL9K_*` +parameters are defined. Based on your prompt style choices, the configuration wizard creates +`~/.p10k.zsh` with a bunch of `POWERLEVEL9K_*` parameters in it and adds a line to `~/.zshrc` to +source this file. The next time you start Zsh, the configuration wizard shouldn't run automatically. +If it does, this means the evaluation of `~/.zshrc` terminates prematurely before it reaches the +line that sources `~/.p10k.zsh`. This most often happens due to syntax errors in `~/.zshrc`. These +errors get hidden by the configuration wizard screen, so you don't notice them. When you exit +configuration wizard, look for error messages. You can also use +`POWERLEVEL9K_DISABLE_CONFIGURATION_WIZARD=true zsh` to start Zsh without automatically running the +configuration wizard. Once you can see the errors, fix `~/.zshrc` to get rid of them. + +### Some prompt styles are missing from the configuration wizard + +If Zsh version is below 5.7.1 or `COLORTERM` environment variable is neither `24bit` nor +`truecolor`, configuration wizard won't offer Pure style with Snazzy color scheme. *Fix*: Install +Zsh >= 5.7.1 and use a terminal with truecolor support. Verify with `print -P '%F{#ff0000}red%f'`. + +If the terminal can display fewer than 256 colors, configuration wizard preselects Lean style with +8 colors. All other styles require at least 256 colors. *Fix*: Use a terminal with 256 color support +and make sure that `TERM` environment variable is set correctly. Verify with +`print $terminfo[colors]`. + +If there is no UTF-8 locale on the system, configuration wizard won't offer prompt styles that use +Unicode characters. *Fix*: Install a UTF-8 locale. Verify with `locale -a`. + +When a UTF-8 locale is available, the first few questions asked by the configuration wizard assess +capabilities of the terminal font. If your answers indicate that some glyphs don't render correctly, +configuration wizard won't offer prompt styles that use them. *Fix*: Restart your terminal and +install [the recommended font](#meslo-nerd-font-patched-for-powerlevel10k). Verify by running +`p10k configure` and checking that all glyphs render correctly. + +The minimum screen size at which configuration wizard can function is 55 columns by 21 lines. +However, not all prompt styles are offered at such small screen size as there is simply not enough +space to present them. *Fix*: Resize your terminal to at least 84 columns by 25 lines prior to +running `p10k configure`. Verify with `print ${COLUMNS}x${LINES}`. + +### Cannot install the recommended font + +Once you download [the recommended font](#meslo-nerd-font-patched-for-powerlevel10k), +you can install it just like any other font. Google "how to install fonts on *your OS*". + +### Extra or missing spaces in prompt compared to Powerlevel9k + +tl;dr: Add `ZLE_RPROMPT_INDENT=0` and `POWERLEVEL9K_LEGACY_ICON_SPACING=true` to `~/.zshrc` to get +the same prompt spacing as in Powerlevel9k. + +When using Powerlevel10k with a Powerlevel9k config, you might get additional spaces in prompt here +and there. These come in two flavors. + +#### Extra space without background on the right side of right prompt + +tl;dr: Add `ZLE_RPROMPT_INDENT=0` to `~/.zshrc` to get rid of that space. + +From [Zsh documentation]( + http://zsh.sourceforge.net/Doc/Release/Parameters.html#index-ZLE_005fRPROMPT_005fINDENT): + +> `ZLE_RPROMPT_INDENT <S>` +> +> If set, used to give the indentation between the right hand side of the right prompt in the line +> editor as given by `RPS1` or `RPROMPT` and the right hand side of the screen. If not set, the +> value `1` is used. +> +> Typically this will be used to set the value to `0` so that the prompt appears flush with the +> right hand side of the screen. + +Powerlevel10k respects this parameter. If you set `ZLE_RPROMPT_INDENT=1` (or leave it unset, which +is the same thing as setting it to `1`), you'll get an empty space to the right of right prompt. If +you set `ZLE_RPROMPT_INDENT=0`, your prompt will go to the edge of the terminal. This is how it +works in every theme except Powerlevel9k. + +![ZLE_RPROMPT_INDENT: Powerlevel10k vs Powerlevel9k]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/p9k-vs-p10k-zle-rprompt-indent.png) + +Powerlevel9k issue: [powerlevel9k#1292](https://github.com/Powerlevel9k/powerlevel9k/issues/1292). +It's been fixed in the development branch of Powerlevel9k but the fix hasn't yet made it to +`master`. + +Add `ZLE_RPROMPT_INDENT=0` to `~/.zshrc` to get the same spacing on the right edge of prompt as in +Powerlevel9k. + +*Note:* Several versions of Zsh have bugs that get triggered when you set `ZLE_RPROMPT_INDENT=0`. +Powerlevel10k can work around these bugs when using powerline prompt style. If you notice visual +artifacts in prompt, or wrong cursor position, try removing `ZLE_RPROMPT_INDENT` from `~/.zshrc`. + +#### Extra or missing spaces around icons + +tl;dr: Add `POWERLEVEL9K_LEGACY_ICON_SPACING=true` to `~/.zshrc` to get the same spacing around +icons as in Powerlevel9k. + +Spacing around icons in Powerlevel9k is inconsistent. + +![ZLE_RPROMPT_INDENT: Powerlevel10k vs Powerlevel9k]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/p9k-vs-p10k-icon-spacing.png) + +This inconsistency is a constant source of annoyance, so it was fixed in Powerlevel10k. You can add +`POWERLEVEL9K_LEGACY_ICON_SPACING=true` to `~/.zshrc` to get the same spacing around icons as in +Powerlevel9k. + +*Note:* It's not a good idea to define `POWERLEVEL9K_LEGACY_ICON_SPACING` when using +`p10k configure`. + +### Weird things happen after typing `source ~/.zshrc` + +It's almost always a bad idea to run `source ~/.zshrc`, whether you are using Powerlevel10k or not. +This command may result in random errors, misbehaving code and progressive slowdown of Zsh. + +If you've made changes to `~/.zshrc` or to files sourced by it, restart Zsh to apply them. The most +reliable way to do this is to type `exit` and then start a new Zsh session. You can also use +`exec zsh`. While not exactly equivalent to complete Zsh restart, this command is much more reliable +than `source ~/.zshrc`. + +### Transient prompt stops working after some time + +See [weird things happen after typing `source ~/.zshrc`]( + #weird-things-happen-after-typing-source-zshrc). + +### Cannot make Powerlevel10k work with my plugin manager + +If the [installation instructions](#installation) didn't work for you, try disabling your current +theme (so that you end up with no theme) and then installing Powerlevel10k manually. + +1. Disable the current theme in your framework / plugin manager. + +- **oh-my-zsh:** Open `~/.zshrc` and remove the line that sets `ZSH_THEME`. It might look like this: + `ZSH_THEME="powerlevel9k/powerlevel9k"`. +- **zplug:** Open `~/.zshrc` and remove the `zplug` command that refers to your current theme. For + example, if you are currently using Powerlevel9k, look for + `zplug bhilburn/powerlevel9k, use:powerlevel9k.zsh-theme`. +- **prezto:** Open `~/.zpreztorc` and put `zstyle :prezto:module:prompt theme off` in it. Remove + any other command that sets `theme` such as `zstyle :prezto:module:prompt theme powerlevel9k`. +- **antigen:** Open `~/.zshrc` and remove the line that sets `antigen theme`. It might look like + this: `antigen theme powerlevel9k/powerlevel9k`. + +2. Install Powerlevel10k manually. + +```zsh +git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ~/powerlevel10k +echo 'source ~/powerlevel10k/powerlevel10k.zsh-theme' >>! ~/.zshrc +``` + +This method of installation won't make anything slower or otherwise sub-par. + +### Directory is difficult to see in prompt when using Rainbow style + +In Rainbow style the current working directory is shown with bright white text on blue background. +The white is fixed and always looks the same but the appearance of "blue" is defined by your +terminal color palette. If it's very light, it may be difficult to see white text on it. + +There are several ways to fix this. + +- Type `p10k configure` and choose a more readable prompt style. +- [Change terminal color palette](#change-the-color-palette-used-by-your-terminal). Try Tango Dark + or Solarized Dark, or change just the "blue" color. +- [Change directory background and/or foreground color](#set-colors-through-Powerlevel10k-configuration-parameters). + The parameters you are looking for are called `POWERLEVEL9K_DIR_BACKGROUND`, + `POWERLEVEL9K_DIR_FOREGROUND`, `POWERLEVEL9K_DIR_SHORTENED_FOREGROUND`, + `POWERLEVEL9K_DIR_ANCHOR_FOREGROUND` and `POWERLEVEL9K_DIR_ANCHOR_BOLD`. You can find them in + in `~/.p10k.zsh`. + +### Horrific mess when resizing terminal window + +When you resize terminal window horizontally back and forth a few times, you might see this ugly +picture. + +![Powerlevel10k Resizing Mess]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/resizing-mess.png) + +tl;dr: This is a bug in Zsh that isn't specific to Powerlevel10k. See [mitigation](#mitigation). + +#### Zsh bug + +This issue is caused by a bug in Zsh that gets triggered when the vertical distance between the +start of the current prompt and the cursor (henceforth `VD`) changes when the terminal window is +resized. This bug is not specific to Powerlevel10k. + +When a terminal window gets shrunk horizontally, there are two ways for a terminal to handle long +lines that no longer fit: *reflow* or *truncate*. + +Terminal content before shrinking: + +![Terminal Content Before Shrinking]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/resize-original.png) + +Terminal reflows text when shrinking: + +![Terminal Reflows Text When Shrinking]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/resize-reflow.png) + +Terminal truncates text when shrinking: + +![Terminal Truncates Text When Shrinking]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/resize-truncate.png) + +Reflowing strategy can change the height of terminal content. If such content happens to be between +the start of the current prompt and the cursor, Zsh will print prompt on the wrong line. Truncation +strategy never changes the height of terminal content, so it doesn't trigger this bug in Zsh. + +Let's see how the bug plays out in slow motion. We'll start by launching `zsh -df` and pasting +the following code: + +```zsh +function pause() { read -s } +functions -M pause 0 + +reset +print -l {1..3} +setopt prompt_subst +PROMPT=$'${$((pause()))+}left>${(pl.$((COLUMNS-12))..-.)}<right\n> ' +``` + +When `PROMPT` gets expanded, it calls `pause` to let us observe the state of the terminal. Here's +the initial state: + +![Zsh Resizing Bug 1]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/resize-bug-1.png) + +Zsh keeps track of the cursor position relative to the start of the current prompt. In this case it +knows that the cursor is one line below. When we shrink the terminal window, it looks like this: + +![Zsh Resizing Bug 2]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/resize-bug-2.png) + +At this point the terminal sends `SIGWINCH` to Zsh to notify it about changes in the terminal +dimensions. Note that this signal is sent *after* the content of the terminal has been reflown. + +When Zsh receives `SIGWINCH`, it attempts to erase the current prompt and print it anew. It goes to +the position where it *thinks* the current prompt is -- one line above the cursor (!) -- erases all +terminal content that follows and prints reexpanded prompt there. However, after resizing prompt is +no longer one line above the cursor. It's two lines above! Zsh ends up printing new prompt one line +too low. + +![Zsh Resizing Bug 3]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/resize-bug-3.png) + +In this case we ended up with unwanted junk content because `VD` has *increased*. When you make +terminal window wider, `VD` can also *decrease*, which would result in the new prompt being printed +higher than intended, potentially erasing useful content in the process. + +Here are a few more examples where shrinking terminal window increased `VD`. + +Simple one-line left prompt with right prompt. No `prompt_subst`. Note that the cursor is below the +prompt line (hit *ESC-ENTER* to get it there). + +![Zsh Prompt That Breaks on Terminal Shrinking 1]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/resize-breakable-1.png) + +Simple one-line left prompt. No `prompt_subst`, no right prompt. Here `VD` is bound to increase +upon terminal shrinking due to the command line wrapping around. + +![Zsh Prompt That Breaks on Terminal Shrinking 2]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/resize-breakable-2.png) + +#### Zsh patch + +The bug described above has been fixed in [this branch]( + https://github.com/romkatv/zsh/tree/fix-winchanged). The idea behind the fix is to use `sc` (save +cursor) terminal capability before printing prompt and `rc` (restore cursor) to move cursor back +to the same position when prompt needs to be refreshed. + +*Note*: The patch doesn't work on Alacritty. On the plus side, it doesn't make things worse. + +There are two alternative approaches to fixing the bug that may seem to work at fight glance but in +fact don't: + +- Instead of `sc`, use `u7` terminal capability to query the current cursor position and then `cup` + to go back to it. This doesn't work because the absolute position of the start of the current + prompt changes when text gets reflown. +- Recompute `VD` based on new terminal dimensions before attempting to refresh prompt. This doesn't + work because Zsh doesn't know whether terminal reflows text or truncates it. If Zsh could somehow + know that the terminal reflows text, this approach still wouldn't work on terminals that + continuously reflow text and rapid-fire `SIGWINCH` when the window is being resized. In such + environment real terminal dimensions go out of sync with what Zsh thinks the dimensions are. + +There is no ETA for the patch making its way into upstream Zsh. See [discussion]( + https://www.zsh.org/mla/workers//2019/msg00561.html). + +#### Mitigation + +There are a few mitigation options for this issue. + +- Apply [the patch](#zsh-patch) and [rebuild Zsh from source]( + https://github.com/zsh-users/zsh/blob/master/INSTALL). It won't help if you are using Alacritty. +- Disable text reflowing on window resize in terminal settings. If your terminal doesn't have this + setting, try a different terminal. +- Avoid long lines between the start of prompt and cursor. + 1. Disable ruler with `POWERLEVEL9K_SHOW_RULER=false`. + 1. Disable prompt connection with `POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR=' '`. + 1. Disable right frame with `POWERLEVEL9K_MULTILINE_FIRST_PROMPT_SUFFIX=` and + `POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_SUFFIX=` and + `POWERLEVEL9K_MULTILINE_LAST_PROMPT_SUFFIX=`. + 1. Remove all elements from `POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS`. Right prompt on the last prompt + line will cause resizing issues only when the cursor is below it. This isn't very common, so + you might want to keep some elements in `POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS` provided that + none of them are succeeded by `newline`. + +### Icons cut off in Konsole + +When using Konsole with a non-monospace font, icons may be cut off on the right side. Here +"non-monospace" refers to any font with glyphs wider than a single column, or wider than two columns +for glyphs designated as "wide" in the Unicode standard. + +![Icons cut off in Konsole]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/konsole-non-monospace-font.png) + +The last line on the screenshot shows a cut off Arch Linux logo. + +There are several mitigation options for this issue. + +1. Use a different terminal. Konsole is the only terminal that exhibits this behavior. +2. Use a monospace font. +3. Manually add an extra space after the icon that gets cut off. For example, if the content of + `os_icon` prompt segment gets cut off, open `~/.p10k.zsh`, search for + `POWERLEVEL9K_OS_ICON_CONTENT_EXPANSION` and change it as follows: +```zsh +typeset -g POWERLEVEL9K_OS_ICON_CONTENT_EXPANSION='${P9K_CONTENT} ' # extra space at the end +``` +4. Use a different icon that is monospace. For example, if Arch Linux logo gets cut off, add + the following parameter to `~/.p10k.zsh`: +```zsh +typeset -g POWERLEVEL9K_LINUX_ARCH_ICON='Arch' # plain "Arch" in place of a logo +``` +5. Disable the display of the icon that gets cut off. For example, if the content of + `os_icon` prompt segment gets cut off, open `~/.p10k.zsh` and remove `os_icon` from + `POWERLEVEL9K_LEFT_PROMPT_ELEMENTS` and `POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS`. + +*Note*: [Non-monospace fonts are not officially supported by Konsole]( + https://bugs.kde.org/show_bug.cgi?id=418553#c5). + +### Arch Linux logo has a dot in the bottom right corner + +![Arch Linux Logo with a dot]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/arch-linux-logo-dot.png) + +Some fonts have this incorrect dotted icon in bold typeface. There are two ways to fix this issue. + +1. Use a font with a correct Arch Linux logo in bold typeface. For example, + [the recommended Powerlevel10k font](#meslo-nerd-font-patched-for-powerlevel10k). +2. Display the icon in regular (non-bold) typeface. To do this, open `~/.p10k.zsh`, search for + `POWERLEVEL9K_OS_ICON_CONTENT_EXPANSION` and remove `%B` from its value. +```zsh +typeset -g POWERLEVEL9K_OS_ICON_CONTENT_EXPANSION='${P9K_CONTENT}' # not bold +``` -GNU General Public License v3.0. See [LICENSE](LICENSE). Contributions are covered by the same -license. +## Table of contents + +- [Features](#features) + - [Configuration wizard](#configuration-wizard) + - [Uncompromising performance](#uncompromising-performance) + - [Powerlevel9k compatibility](#powerlevel9k-compatibility) + - [Pure compatibility](#pure-compatibility) + - [Instant prompt](#instant-prompt) + - [Show on command](#show-on-command) + - [Transient prompt](#transient-prompt) + - [Current directory that just works](#current-directory-that-just-works) + - [Extremely customizable](#extremely-customizable) + - [Batteries included](#batteries-included) + - [Extensible](#extensible) +- [Installation](#installation) + - [Manual](#manual) + - [Oh My Zsh](#oh-my-zsh) + - [Prezto](#prezto) + - [Zim](#zim) + - [Antibody](#antibody) + - [Antigen](#antigen) + - [Zplug](#zplug) + - [Zgen](#zgen) + - [Zplugin](#zplugin) + - [Zinit](#zinit) + - [Homebrew](#homebrew) + - [Arch Linux](#arch-linux) +- [Configuration](#configuration) + - [For new users](#for-new-users) + - [For Powerlevel9k users](#for-powerlevel9k-users) +- [Fonts](#fonts) + - [Meslo Nerd Font patched for Powerlevel10k](#meslo-nerd-font-patched-for-powerlevel10k) + - [Automatic font installation](#automatic-font-installation) + - [Manual font installation](#manual-font-installation) +- [Try it in Docker](#try-it-in-docker) +- [License](#license) +- [FAQ](#faq) + - [How do I update Powerlevel10k?](#how-do-i-update-powerlevel10k) + - [Where can I ask for help and report bugs?](#where-can-i-ask-for-help-and-report-bugs) + - [Which aspects of shell and terminal does Powerlevel10k affect?](#which-aspects-of-shell-and-terminal-does-powerlevel10k-affect) + - [I'm using Powerlevel9k with Oh My Zsh. How do I migrate?](#im-using-powerlevel9k-with-oh-my-zsh-how-do-i-migrate) + - [Is it really fast?](#is-it-really-fast) + - [How do I enable instant prompt?](#how-do-i-enable-instant-prompt) + - [What do different symbols in Git status mean?](#what-do-different-symbols-in-git-status-mean) + - [How do I change the format of Git status?](#how-do-i-change-the-format-of-git-status) + - [Why is Git status from `$HOME/.git` not displayed in prompt?](#why-is-git-status-from-homegit-not-displayed-in-prompt) + - [Why does Git status sometimes appear grey and then gets colored after a short period of time?](#why-does-git-status-sometimes-appear-grey-and-then-gets-colored-after-a-short-period-of-time) + - [How do I add username and/or hostname to prompt?](#how-do-i-add-username-andor-hostname-to-prompt) + - [Why some prompt segments appear and disappear as I'm typing?](#why-some-prompt-segments-appear-and-disappear-as-im-typing) + - [How do I change prompt colors?](#how-do-i-change-prompt-colors) + - [Why does Powerlevel10k spawn extra processes?](#why-does-powerlevel10k-spawn-extra-processes) + - [Are there configuration options that make Powerlevel10k slow?](#are-there-configuration-options-that-make-powerlevel10k-slow) + - [Is Powerlevel10k fast to load?](#is-powerlevel10k-fast-to-load) + - [What is the relationship between Powerlevel9k and Powerlevel10k?](#what-is-the-relationship-between-powerlevel9k-and-powerlevel10k) + - [Does Powerlevel10k always render exactly the same prompt as Powerlevel9k given the same config?](#does-powerlevel10k-always-render-exactly-the-same-prompt-as-powerlevel9k-given-the-same-config) + - [What is the best prompt style in the configuration wizard?](#what-is-the-best-prompt-style-in-the-configuration-wizard) + - [How to make Powerlevel10k look like robbyrussell Oh My Zsh theme?](#how-to-make-powerlevel10k-look-like-robbyrussell-oh-my-zsh-theme) + - [Can prompts for completed commands display error status for *those* commands instead of the commands preceding them?](#can-prompts-for-completed-commands-display-error-status-for-those-commands-instead-of-the-commands-preceding-them) + - [Is there an AUR package for Powerlevel10k?](#is-there-an-aur-package-for-powerlevel10k) + - [What is the minimum supported Zsh version?](#what-is-the-minimum-supported-zsh-version) + - [How were these screenshots and animated gifs created?](#how-were-these-screenshots-and-animated-gifs-created) + - [How was the recommended font created?](#how-was-the-recommended-font-created) + - [How to package Powerlevel10k for distribution?](#how-to-package-powerlevel10k-for-distribution) +- [Troubleshooting](#troubleshooting) + - [Question mark in prompt](#question-mark-in-prompt) + - [Icons, glyphs or powerline symbols don't render](#icons-glyphs-or-powerline-symbols-dont-render) + - [Sub-pixel imperfections around powerline symbols](#sub-pixel-imperfections-around-powerline-symbols) + - [Error: character not in range](#error-character-not-in-range) + - [Cursor is in the wrong place](#cursor-is-in-the-wrong-place) + - [Prompt wrapping around in a weird way](#prompt-wrapping-around-in-a-weird-way) + - [Right prompt is in the wrong place](#right-prompt-is-in-the-wrong-place) + - [Configuration wizard runs automatically every time Zsh is started](#configuration-wizard-runs-automatically-every-time-zsh-is-started) + - [Some prompt styles are missing from the configuration wizard](#some-prompt-styles-are-missing-from-the-configuration-wizard) + - [Cannot install the recommended font](#cannot-install-the-recommended-font) + - [Extra or missing spaces in prompt compared to Powerlevel9k](#extra-or-missing-spaces-in-prompt-compared-to-powerlevel9k) + - [Extra space without background on the right side of right prompt](#extra-space-without-background-on-the-right-side-of-right-prompt) + - [Extra or missing spaces around icons](#extra-or-missing-spaces-around-icons) + - [Weird things happen after typing `source ~/.zshrc`](#weird-things-happen-after-typing-source-zshrc) + - [Transient prompt stops working after some time](#transient-prompt-stops-working-after-some-time) + - [Cannot make Powerlevel10k work with my plugin manager](#cannot-make-powerlevel10k-work-with-my-plugin-manager) + - [Directory is difficult to see in prompt when using Rainbow style](#directory-is-difficult-to-see-in-prompt-when-using-rainbow-style) + - [Horrific mess when resizing terminal window](#horrific-mess-when-resizing-terminal-window) + - [Icons cut off in Konsole](#icons-cut-off-in-konsole) + - [Arch Linux logo has a dot in the bottom right corner](#arch-linux-logo-has-a-dot-in-the-bottom-right-corner) diff --git a/config/p10k-classic.zsh b/config/p10k-classic.zsh new file mode 100644 index 00000000..4682db14 --- /dev/null +++ b/config/p10k-classic.zsh @@ -0,0 +1,1533 @@ +# Config for Powerlevel10k with classic powerline prompt style. Type `p10k configure` to generate +# your own config based on it. +# +# Tip: Looking for a nice color? Here's a one-liner to print colormap. +# +# for i in {0..255}; do print -Pn "%K{$i} %k%F{$i}${(l:3::0:)i}%f " ${${(M)$((i%6)):#3}:+$'\n'}; done + +# Temporarily change options. +'builtin' 'local' '-a' 'p10k_config_opts' +[[ ! -o 'aliases' ]] || p10k_config_opts+=('aliases') +[[ ! -o 'sh_glob' ]] || p10k_config_opts+=('sh_glob') +[[ ! -o 'no_brace_expand' ]] || p10k_config_opts+=('no_brace_expand') +'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand' + +() { + emulate -L zsh -o extended_glob + + # Unset all configuration options. This allows you to apply configuration changes without + # restarting zsh. Edit ~/.p10k.zsh and type `source ~/.p10k.zsh`. + unset -m 'POWERLEVEL9K_*|DEFAULT_USER' + + # Zsh >= 5.1 is required. + autoload -Uz is-at-least && is-at-least 5.1 || return + + # The list of segments shown on the left. Fill it with the most important segments. + typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=( + # =========================[ Line #1 ]========================= + # os_icon # os identifier + dir # current directory + vcs # git status + # =========================[ Line #2 ]========================= + newline # \n + # prompt_char # prompt symbol + ) + + # The list of segments shown on the right. Fill it with less important segments. + # Right prompt on the last prompt line (where you are typing your commands) gets + # automatically hidden when the input line reaches it. Right prompt above the + # last prompt line gets hidden if it would overlap with left prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=( + # =========================[ Line #1 ]========================= + status # exit code of the last command + command_execution_time # duration of the last command + background_jobs # presence of background jobs + direnv # direnv status (https://direnv.net/) + asdf # asdf version manager (https://github.com/asdf-vm/asdf) + virtualenv # python virtual environment (https://docs.python.org/3/library/venv.html) + anaconda # conda environment (https://conda.io/) + pyenv # python environment (https://github.com/pyenv/pyenv) + goenv # go environment (https://github.com/syndbg/goenv) + nodenv # node.js version from nodenv (https://github.com/nodenv/nodenv) + nvm # node.js version from nvm (https://github.com/nvm-sh/nvm) + nodeenv # node.js environment (https://github.com/ekalinin/nodeenv) + # node_version # node.js version + # go_version # go version (https://golang.org) + # rust_version # rustc version (https://www.rust-lang.org) + # dotnet_version # .NET version (https://dotnet.microsoft.com) + # php_version # php version (https://www.php.net/) + # laravel_version # laravel php framework version (https://laravel.com/) + # java_version # java version (https://www.java.com/) + # package # name@version from package.json (https://docs.npmjs.com/files/package.json) + rbenv # ruby version from rbenv (https://github.com/rbenv/rbenv) + rvm # ruby version from rvm (https://rvm.io) + fvm # flutter version management (https://github.com/leoafarias/fvm) + luaenv # lua version from luaenv (https://github.com/cehoffman/luaenv) + jenv # java version from jenv (https://github.com/jenv/jenv) + plenv # perl version from plenv (https://github.com/tokuhirom/plenv) + phpenv # php version from phpenv (https://github.com/phpenv/phpenv) + haskell_stack # haskell version from stack (https://haskellstack.org/) + kubecontext # current kubernetes context (https://kubernetes.io/) + terraform # terraform workspace (https://www.terraform.io) + aws # aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) + aws_eb_env # aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) + azure # azure account name (https://docs.microsoft.com/en-us/cli/azure) + gcloud # google cloud cli account and project (https://cloud.google.com/) + google_app_cred # google application credentials (https://cloud.google.com/docs/authentication/production) + context # user@hostname + nordvpn # nordvpn connection status, linux only (https://nordvpn.com/) + ranger # ranger shell (https://github.com/ranger/ranger) + nnn # nnn shell (https://github.com/jarun/nnn) + vim_shell # vim shell indicator (:sh) + midnight_commander # midnight commander shell (https://midnight-commander.org/) + nix_shell # nix shell (https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html) + # vi_mode # vi mode (you don't need this if you've enabled prompt_char) + # vpn_ip # virtual private network indicator + # load # CPU load + # disk_usage # disk usage + # ram # free RAM + # swap # used swap + todo # todo items (https://github.com/todotxt/todo.txt-cli) + timewarrior # timewarrior tracking status (https://timewarrior.net/) + taskwarrior # taskwarrior task count (https://taskwarrior.org/) + # time # current time + # =========================[ Line #2 ]========================= + newline # \n + # ip # ip address and bandwidth usage for a specified network interface + # public_ip # public IP address + # proxy # system-wide http/https/ftp proxy + # battery # internal battery + # wifi # wifi speed + # example # example user-defined segment (see prompt_example function below) + ) + + # Defines character set used by powerlevel10k. It's best to let `p10k configure` set it for you. + typeset -g POWERLEVEL9K_MODE=nerdfont-complete + # When set to `moderate`, some icons will have an extra space after them. This is meant to avoid + # icon overlap when using non-monospace fonts. When set to `none`, spaces are not added. + typeset -g POWERLEVEL9K_ICON_PADDING=none + + # When set to true, icons appear before content on both sides of the prompt. When set + # to false, icons go after content. If empty or not set, icons go before content in the left + # prompt and after content in the right prompt. + # + # You can also override it for a specific segment: + # + # POWERLEVEL9K_STATUS_ICON_BEFORE_CONTENT=false + # + # Or for a specific segment in specific state: + # + # POWERLEVEL9K_DIR_NOT_WRITABLE_ICON_BEFORE_CONTENT=false + typeset -g POWERLEVEL9K_ICON_BEFORE_CONTENT= + + # Add an empty line before each prompt. + typeset -g POWERLEVEL9K_PROMPT_ADD_NEWLINE=true + + # Connect left prompt lines with these symbols. You'll probably want to use the same color + # as POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_FOREGROUND below. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX='%242F╭─' + typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_PREFIX='%242F├─' + typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX='%242F╰─' + # Connect right prompt lines with these symbols. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_SUFFIX='%242F─╮' + typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_SUFFIX='%242F─┤' + typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_SUFFIX='%242F─╯' + + # Filler between left and right prompt on the first prompt line. You can set it to ' ', '·' or + # '─'. The last two make it easier to see the alignment between left and right prompt and to + # separate prompt from command output. You might want to set POWERLEVEL9K_PROMPT_ADD_NEWLINE=false + # for more compact prompt if using using this option. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR=' ' + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_BACKGROUND= + typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_GAP_BACKGROUND= + if [[ $POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR != ' ' ]]; then + # The color of the filler. You'll probably want to match the color of POWERLEVEL9K_MULTILINE + # ornaments defined above. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_FOREGROUND=242 + # Start filler from the edge of the screen if there are no left segments on the first line. + typeset -g POWERLEVEL9K_EMPTY_LINE_LEFT_PROMPT_FIRST_SEGMENT_END_SYMBOL='%{%}' + # End filler on the edge of the screen if there are no right segments on the first line. + typeset -g POWERLEVEL9K_EMPTY_LINE_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL='%{%}' + fi + + # Default background color. + typeset -g POWERLEVEL9K_BACKGROUND=238 + + # Separator between same-color segments on the left. + typeset -g POWERLEVEL9K_LEFT_SUBSEGMENT_SEPARATOR='%246F\uE0B1' + # Separator between same-color segments on the right. + typeset -g POWERLEVEL9K_RIGHT_SUBSEGMENT_SEPARATOR='%246F\uE0B3' + # Separator between different-color segments on the left. + typeset -g POWERLEVEL9K_LEFT_SEGMENT_SEPARATOR='\uE0B0' + # Separator between different-color segments on the right. + typeset -g POWERLEVEL9K_RIGHT_SEGMENT_SEPARATOR='\uE0B2' + # The right end of left prompt. + typeset -g POWERLEVEL9K_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL='\uE0B0' + # The left end of right prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL='\uE0B2' + # The left end of left prompt. + typeset -g POWERLEVEL9K_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL= + # The right end of right prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL= + # Left prompt terminator for lines without any segments. + typeset -g POWERLEVEL9K_EMPTY_LINE_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL= + + #################################[ os_icon: os identifier ]################################## + # OS identifier color. + typeset -g POWERLEVEL9K_OS_ICON_FOREGROUND=255 + # Custom icon. + # typeset -g POWERLEVEL9K_OS_ICON_CONTENT_EXPANSION='⭐' + + ################################[ prompt_char: prompt symbol ]################################ + # Transparent background. + typeset -g POWERLEVEL9K_PROMPT_CHAR_BACKGROUND= + # Green prompt symbol if the last command succeeded. + typeset -g POWERLEVEL9K_PROMPT_CHAR_OK_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=76 + # Red prompt symbol if the last command failed. + typeset -g POWERLEVEL9K_PROMPT_CHAR_ERROR_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=196 + # Default prompt symbol. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIINS_CONTENT_EXPANSION='❯' + # Prompt symbol in command vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VICMD_CONTENT_EXPANSION='❮' + # Prompt symbol in visual vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIVIS_CONTENT_EXPANSION='Ⅴ' + # Prompt symbol in overwrite vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIOWR_CONTENT_EXPANSION='▶' + typeset -g POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE=true + # No line terminator if prompt_char is the last segment. + typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL= + # No line introducer if prompt_char is the first segment. + typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL= + # No surrounding whitespace. + typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_{LEFT,RIGHT}_WHITESPACE= + + ##################################[ dir: current directory ]################################## + # Default current directory color. + typeset -g POWERLEVEL9K_DIR_FOREGROUND=31 + # If directory is too long, shorten some of its segments to the shortest possible unique + # prefix. The shortened directory can be tab-completed to the original. + typeset -g POWERLEVEL9K_SHORTEN_STRATEGY=truncate_to_unique + # Replace removed segment suffixes with this symbol. + typeset -g POWERLEVEL9K_SHORTEN_DELIMITER= + # Color of the shortened directory segments. + typeset -g POWERLEVEL9K_DIR_SHORTENED_FOREGROUND=103 + # Color of the anchor directory segments. Anchor segments are never shortened. The first + # segment is always an anchor. + typeset -g POWERLEVEL9K_DIR_ANCHOR_FOREGROUND=39 + # Display anchor directory segments in bold. + typeset -g POWERLEVEL9K_DIR_ANCHOR_BOLD=true + # Don't shorten directories that contain any of these files. They are anchors. + local anchor_files=( + .bzr + .citc + .git + .hg + .node-version + .python-version + .go-version + .ruby-version + .lua-version + .java-version + .perl-version + .php-version + .tool-version + .shorten_folder_marker + .svn + .terraform + CVS + Cargo.toml + composer.json + go.mod + package.json + stack.yaml + ) + typeset -g POWERLEVEL9K_SHORTEN_FOLDER_MARKER="(${(j:|:)anchor_files})" + # If set to "first" ("last"), remove everything before the first (last) subdirectory that contains + # files matching $POWERLEVEL9K_SHORTEN_FOLDER_MARKER. For example, when the current directory is + # /foo/bar/git_repo/nested_git_repo/baz, prompt will display git_repo/nested_git_repo/baz (first) + # or nested_git_repo/baz (last). This assumes that git_repo and nested_git_repo contain markers + # and other directories don't. + typeset -g POWERLEVEL9K_DIR_TRUNCATE_BEFORE_MARKER=false + # Don't shorten this many last directory segments. They are anchors. + typeset -g POWERLEVEL9K_SHORTEN_DIR_LENGTH=1 + # Shorten directory if it's longer than this even if there is space for it. The value can + # be either absolute (e.g., '80') or a percentage of terminal width (e.g, '50%'). If empty, + # directory will be shortened only when prompt doesn't fit or when other parameters demand it + # (see POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS and POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT below). + # If set to `0`, directory will always be shortened to its minimum length. + typeset -g POWERLEVEL9K_DIR_MAX_LENGTH=80 + # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least this + # many columns for typing commands. + typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS=40 + # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least + # COLUMNS * POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT * 0.01 columns for typing commands. + typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT=50 + # If set to true, embed a hyperlink into the directory. Useful for quickly + # opening a directory in the file manager simply by clicking the link. + # Can also be handy when the directory is shortened, as it allows you to see + # the full directory that was used in previous commands. + typeset -g POWERLEVEL9K_DIR_HYPERLINK=false + + # Enable special styling for non-writable directories. See POWERLEVEL9K_LOCK_ICON and + # POWERLEVEL9K_DIR_CLASSES below. + typeset -g POWERLEVEL9K_DIR_SHOW_WRITABLE=v2 + + # The default icon shown next to non-writable directories when POWERLEVEL9K_DIR_SHOW_WRITABLE is + # set to v2. + # typeset -g POWERLEVEL9K_LOCK_ICON='⭐' + + # POWERLEVEL9K_DIR_CLASSES allows you to specify custom icons and colors for different + # directories. It must be an array with 3 * N elements. Each triplet consists of: + # + # 1. A pattern against which the current directory ($PWD) is matched. Matching is done with + # extended_glob option enabled. + # 2. Directory class for the purpose of styling. + # 3. An empty string. + # + # Triplets are tried in order. The first triplet whose pattern matches $PWD wins. + # + # If POWERLEVEL9K_DIR_SHOW_WRITABLE is set to v2 and the current directory is not writable, + # its class gets suffix _NOT_WRITABLE. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_DIR_CLASSES=( + # '~/work(|/*)' WORK '' + # '~(|/*)' HOME '' + # '*' DEFAULT '') + # + # Whenever the current directory is ~/work or a subdirectory of ~/work, it gets styled with class + # WORK or WORK_NOT_WRITABLE. + # + # Simply assigning classes to directories don't have any visible effects. It merely gives you an + # option to define custom colors and icons for different directory classes. + # + # # Styling for WORK. + # typeset -g POWERLEVEL9K_DIR_WORK_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_DIR_WORK_FOREGROUND=31 + # typeset -g POWERLEVEL9K_DIR_WORK_SHORTENED_FOREGROUND=103 + # typeset -g POWERLEVEL9K_DIR_WORK_ANCHOR_FOREGROUND=39 + # + # # Styling for WORK_NOT_WRITABLE. + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_FOREGROUND=31 + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_SHORTENED_FOREGROUND=103 + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_ANCHOR_FOREGROUND=39 + # + # If a styling parameter isn't explicitly defined for some class, it falls back to the classless + # parameter. For example, if POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_FOREGROUND is not set, it falls + # back to POWERLEVEL9K_DIR_FOREGROUND. + # + # typeset -g POWERLEVEL9K_DIR_CLASSES=() + + # Custom prefix. + # typeset -g POWERLEVEL9K_DIR_PREFIX='%248Fin ' + + #####################################[ vcs: git status ]###################################### + # Branch icon. Set this parameter to '\uF126 ' for the popular Powerline branch icon. + typeset -g POWERLEVEL9K_VCS_BRANCH_ICON= + + # Untracked files icon. It's really a question mark, your font isn't broken. + # Change the value of this parameter to show a different icon. + typeset -g POWERLEVEL9K_VCS_UNTRACKED_ICON='?' + + # Formatter for Git status. + # + # Example output: master ⇣42⇡42 *42 merge ~42 +42 !42 ?42. + # + # You can edit the function to customize how Git status looks. + # + # VCS_STATUS_* parameters are set by gitstatus plugin. See reference: + # https://github.com/romkatv/gitstatus/blob/master/gitstatus.plugin.zsh. + function my_git_formatter() { + emulate -L zsh + + if [[ -n $P9K_CONTENT ]]; then + # If P9K_CONTENT is not empty, use it. It's either "loading" or from vcs_info (not from + # gitstatus plugin). VCS_STATUS_* parameters are not available in this case. + typeset -g my_git_format=$P9K_CONTENT + return + fi + + if (( $1 )); then + # Styling for up-to-date Git status. + local meta='%248F' # grey foreground + local clean='%76F' # green foreground + local modified='%178F' # yellow foreground + local untracked='%39F' # blue foreground + local conflicted='%196F' # red foreground + else + # Styling for incomplete and stale Git status. + local meta='%244F' # grey foreground + local clean='%244F' # grey foreground + local modified='%244F' # grey foreground + local untracked='%244F' # grey foreground + local conflicted='%244F' # grey foreground + fi + + local res + local where # branch or tag + if [[ -n $VCS_STATUS_LOCAL_BRANCH ]]; then + res+="${clean}${(g::)POWERLEVEL9K_VCS_BRANCH_ICON}" + where=${(V)VCS_STATUS_LOCAL_BRANCH} + elif [[ -n $VCS_STATUS_TAG ]]; then + res+="${meta}#" + where=${(V)VCS_STATUS_TAG} + fi + + # If local branch name or tag is at most 32 characters long, show it in full. + # Otherwise show the first 12 … the last 12. + # Tip: To always show local branch name in full without truncation, delete the next line. + (( $#where > 32 )) && where[13,-13]="…" + res+="${clean}${where//\%/%%}" # escape % + + # Display the current Git commit if there is no branch or tag. + # Tip: To always display the current Git commit, remove `[[ -z $where ]] &&` from the next line. + [[ -z $where ]] && res+="${meta}@${clean}${VCS_STATUS_COMMIT[1,8]}" + + # Show tracking branch name if it differs from local branch. + if [[ -n ${VCS_STATUS_REMOTE_BRANCH:#$VCS_STATUS_LOCAL_BRANCH} ]]; then + res+="${meta}:${clean}${(V)VCS_STATUS_REMOTE_BRANCH//\%/%%}" # escape % + fi + + # ⇣42 if behind the remote. + (( VCS_STATUS_COMMITS_BEHIND )) && res+=" ${clean}⇣${VCS_STATUS_COMMITS_BEHIND}" + # ⇡42 if ahead of the remote; no leading space if also behind the remote: ⇣42⇡42. + (( VCS_STATUS_COMMITS_AHEAD && !VCS_STATUS_COMMITS_BEHIND )) && res+=" " + (( VCS_STATUS_COMMITS_AHEAD )) && res+="${clean}⇡${VCS_STATUS_COMMITS_AHEAD}" + # ⇠42 if behind the push remote. + (( VCS_STATUS_PUSH_COMMITS_BEHIND )) && res+=" ${clean}⇠${VCS_STATUS_PUSH_COMMITS_BEHIND}" + (( VCS_STATUS_PUSH_COMMITS_AHEAD && !VCS_STATUS_PUSH_COMMITS_BEHIND )) && res+=" " + # ⇢42 if ahead of the push remote; no leading space if also behind: ⇠42⇢42. + (( VCS_STATUS_PUSH_COMMITS_AHEAD )) && res+="${clean}⇢${VCS_STATUS_PUSH_COMMITS_AHEAD}" + # *42 if have stashes. + (( VCS_STATUS_STASHES )) && res+=" ${clean}*${VCS_STATUS_STASHES}" + # 'merge' if the repo is in an unusual state. + [[ -n $VCS_STATUS_ACTION ]] && res+=" ${conflicted}${VCS_STATUS_ACTION}" + # ~42 if have merge conflicts. + (( VCS_STATUS_NUM_CONFLICTED )) && res+=" ${conflicted}~${VCS_STATUS_NUM_CONFLICTED}" + # +42 if have staged changes. + (( VCS_STATUS_NUM_STAGED )) && res+=" ${modified}+${VCS_STATUS_NUM_STAGED}" + # !42 if have unstaged changes. + (( VCS_STATUS_NUM_UNSTAGED )) && res+=" ${modified}!${VCS_STATUS_NUM_UNSTAGED}" + # ?42 if have untracked files. It's really a question mark, your font isn't broken. + # See POWERLEVEL9K_VCS_UNTRACKED_ICON above if you want to use a different icon. + # Remove the next line if you don't want to see untracked files at all. + (( VCS_STATUS_NUM_UNTRACKED )) && res+=" ${untracked}${(g::)POWERLEVEL9K_VCS_UNTRACKED_ICON}${VCS_STATUS_NUM_UNTRACKED}" + # "─" if the number of unstaged files is unknown. This can happen due to + # POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY (see below) being set to a non-negative number lower + # than the number of files in the Git index, or due to bash.showDirtyState being set to false + # in the repository config. The number of staged and untracked files may also be unknown + # in this case. + (( VCS_STATUS_HAS_UNSTAGED == -1 )) && res+=" ${modified}─" + + typeset -g my_git_format=$res + } + functions -M my_git_formatter 2>/dev/null + + # Don't count the number of unstaged, untracked and conflicted files in Git repositories with + # more than this many files in the index. Negative value means infinity. + # + # If you are working in Git repositories with tens of millions of files and seeing performance + # sagging, try setting POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY to a number lower than the output + # of `git ls-files | wc -l`. Alternatively, add `bash.showDirtyState = false` to the repository's + # config: `git config bash.showDirtyState false`. + typeset -g POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY=-1 + + # Don't show Git status in prompt for repositories whose workdir matches this pattern. + # For example, if set to '~', the Git repository at $HOME/.git will be ignored. + # Multiple patterns can be combined with '|': '~(|/foo)|/bar/baz/*'. + typeset -g POWERLEVEL9K_VCS_DISABLED_WORKDIR_PATTERN='~' + + # Disable the default Git status formatting. + typeset -g POWERLEVEL9K_VCS_DISABLE_GITSTATUS_FORMATTING=true + # Install our own Git status formatter. + typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION='${$((my_git_formatter(1)))+${my_git_format}}' + typeset -g POWERLEVEL9K_VCS_LOADING_CONTENT_EXPANSION='${$((my_git_formatter(0)))+${my_git_format}}' + # Enable counters for staged, unstaged, etc. + typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED,CONFLICTED,COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=-1 + + # Icon color. + typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_COLOR=76 + typeset -g POWERLEVEL9K_VCS_LOADING_VISUAL_IDENTIFIER_COLOR=244 + # Custom icon. + # typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_VCS_PREFIX='%248Fon ' + + # Show status of repositories of these types. You can add svn and/or hg if you are + # using them. If you do, your prompt may become slow even when your current directory + # isn't in an svn or hg reposotiry. + typeset -g POWERLEVEL9K_VCS_BACKENDS=(git) + + # These settings are used for respositories other than Git or when gitstatusd fails and + # Powerlevel10k has to fall back to using vcs_info. + typeset -g POWERLEVEL9K_VCS_CLEAN_FOREGROUND=76 + typeset -g POWERLEVEL9K_VCS_UNTRACKED_FOREGROUND=76 + typeset -g POWERLEVEL9K_VCS_MODIFIED_FOREGROUND=178 + + ##########################[ status: exit code of the last command ]########################### + # Enable OK_PIPE, ERROR_PIPE and ERROR_SIGNAL status states to allow us to enable, disable and + # style them independently from the regular OK and ERROR state. + typeset -g POWERLEVEL9K_STATUS_EXTENDED_STATES=true + + # Status on success. No content, just an icon. No need to show it if prompt_char is enabled as + # it will signify success by turning green. + typeset -g POWERLEVEL9K_STATUS_OK=true + typeset -g POWERLEVEL9K_STATUS_OK_FOREGROUND=70 + typeset -g POWERLEVEL9K_STATUS_OK_VISUAL_IDENTIFIER_EXPANSION='✔' + + # Status when some part of a pipe command fails but the overall exit status is zero. It may look + # like this: 1|0. + typeset -g POWERLEVEL9K_STATUS_OK_PIPE=true + typeset -g POWERLEVEL9K_STATUS_OK_PIPE_FOREGROUND=70 + typeset -g POWERLEVEL9K_STATUS_OK_PIPE_VISUAL_IDENTIFIER_EXPANSION='✔' + + # Status when it's just an error code (e.g., '1'). No need to show it if prompt_char is enabled as + # it will signify error by turning red. + typeset -g POWERLEVEL9K_STATUS_ERROR=true + typeset -g POWERLEVEL9K_STATUS_ERROR_FOREGROUND=160 + typeset -g POWERLEVEL9K_STATUS_ERROR_VISUAL_IDENTIFIER_EXPANSION='✘' + + # Status when the last command was terminated by a signal. + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL=true + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_FOREGROUND=160 + # Use terse signal names: "INT" instead of "SIGINT(2)". + typeset -g POWERLEVEL9K_STATUS_VERBOSE_SIGNAME=false + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_VISUAL_IDENTIFIER_EXPANSION='✘' + + # Status when some part of a pipe command fails and the overall exit status is also non-zero. + # It may look like this: 1|0. + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE=true + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_FOREGROUND=160 + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_VISUAL_IDENTIFIER_EXPANSION='✘' + + ###################[ command_execution_time: duration of the last command ]################### + # Show duration of the last command if takes longer than this many seconds. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=3 + # Show this many fractional digits. Zero means round to seconds. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PRECISION=0 + # Execution time color. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FOREGROUND=248 + # Duration format: 1d 2h 3m 4s. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FORMAT='d h m s' + # Custom icon. + # typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PREFIX='%248Ftook ' + + #######################[ background_jobs: presence of background jobs ]####################### + # Don't show the number of background jobs. + typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VERBOSE=false + # Background jobs color. + typeset -g POWERLEVEL9K_BACKGROUND_JOBS_FOREGROUND=37 + # Custom icon. + # typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ direnv: direnv status (https://direnv.net/) ]######################## + # Direnv color. + typeset -g POWERLEVEL9K_DIRENV_FOREGROUND=178 + # Custom icon. + # typeset -g POWERLEVEL9K_DIRENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ asdf: asdf version manager (https://github.com/asdf-vm/asdf) ]############### + # Default asdf color. Only used to display tools for which there is no color override (see below). + typeset -g POWERLEVEL9K_ASDF_FOREGROUND=66 + + # There are four parameters that can be used to hide asdf tools. Each parameter describes + # conditions under which a tool gets hidden. Parameters can hide tools but not unhide them. If at + # least one parameter decides to hide a tool, that tool gets hidden. If no parameter decides to + # hide a tool, it gets shown. + # + # Special note on the difference between POWERLEVEL9K_ASDF_SOURCES and + # POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW. Consider the effect of the following commands: + # + # asdf local python 3.8.1 + # asdf global python 3.8.1 + # + # After running both commands the current python version is 3.8.1 and its source is "local" as + # it takes precedence over "global". If POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW is set to false, + # it'll hide python version in this case because 3.8.1 is the same as the global version. + # POWERLEVEL9K_ASDF_SOURCES will hide python version only if the value of this parameter doesn't + # contain "local". + + # Hide tool versions that don't come from one of these sources. + # + # Available sources: + # + # - shell `asdf current` says "set by ASDF_${TOOL}_VERSION environment variable" + # - local `asdf current` says "set by /some/not/home/directory/file" + # - global `asdf current` says "set by /home/username/file" + # + # Note: If this parameter is set to (shell local global), it won't hide tools. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SOURCES. + typeset -g POWERLEVEL9K_ASDF_SOURCES=(shell local global) + + # If set to false, hide tool versions that are the same as global. + # + # Note: The name of this parameter doesn't reflect its meaning at all. + # Note: If this parameter is set to true, it won't hide tools. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_PROMPT_ALWAYS_SHOW. + typeset -g POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW=false + + # If set to false, hide tool versions that are equal to "system". + # + # Note: If this parameter is set to true, it won't hide tools. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SHOW_SYSTEM. + typeset -g POWERLEVEL9K_ASDF_SHOW_SYSTEM=true + + # If set to non-empty value, hide tools unless there is a file matching the specified file pattern + # in the current directory, or its parent diretory, or its grandparent directory, and so on. + # + # Note: If this parameter is set to empty value, it won't hide tools. + # Note: SHOW_ON_UPGLOB isn't specific to asdf. It works with all prompt segments. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SHOW_ON_UPGLOB. + # + # Example: Hide nodejs version when there is no package.json and no *.js files in the current + # directory, in `..`, in `../..` and so on. + # + # typeset -g POWERLEVEL9K_ASDF_NODEJS_SHOW_ON_UPGLOB='*.js|package.json' + typeset -g POWERLEVEL9K_ASDF_SHOW_ON_UPGLOB= + + # Ruby version from asdf. + typeset -g POWERLEVEL9K_ASDF_RUBY_FOREGROUND=168 + # typeset -g POWERLEVEL9K_ASDF_RUBY_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_RUBY_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Python version from asdf. + typeset -g POWERLEVEL9K_ASDF_PYTHON_FOREGROUND=37 + # typeset -g POWERLEVEL9K_ASDF_PYTHON_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_PYTHON_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Go version from asdf. + typeset -g POWERLEVEL9K_ASDF_GOLANG_FOREGROUND=37 + # typeset -g POWERLEVEL9K_ASDF_GOLANG_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_GOLANG_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Node.js version from asdf. + typeset -g POWERLEVEL9K_ASDF_NODEJS_FOREGROUND=70 + # typeset -g POWERLEVEL9K_ASDF_NODEJS_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_NODEJS_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Rust version from asdf. + typeset -g POWERLEVEL9K_ASDF_RUST_FOREGROUND=37 + # typeset -g POWERLEVEL9K_ASDF_RUST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_RUST_SHOW_ON_UPGLOB='*.foo|*.bar' + + # .NET Core version from asdf. + typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_FOREGROUND=134 + # typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Flutter version from asdf. + typeset -g POWERLEVEL9K_ASDF_FLUTTER_FOREGROUND=38 + # typeset -g POWERLEVEL9K_ASDF_FLUTTER_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_FLUTTER_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Lua version from asdf. + typeset -g POWERLEVEL9K_ASDF_LUA_FOREGROUND=32 + # typeset -g POWERLEVEL9K_ASDF_LUA_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_LUA_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Java version from asdf. + typeset -g POWERLEVEL9K_ASDF_JAVA_FOREGROUND=32 + # typeset -g POWERLEVEL9K_ASDF_JAVA_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_JAVA_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Perl version from asdf. + typeset -g POWERLEVEL9K_ASDF_PERL_FOREGROUND=67 + # typeset -g POWERLEVEL9K_ASDF_PERL_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_PERL_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Erlang version from asdf. + typeset -g POWERLEVEL9K_ASDF_ERLANG_FOREGROUND=125 + # typeset -g POWERLEVEL9K_ASDF_ERLANG_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_ERLANG_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Elixir version from asdf. + typeset -g POWERLEVEL9K_ASDF_ELIXIR_FOREGROUND=129 + # typeset -g POWERLEVEL9K_ASDF_ELIXIR_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_ELIXIR_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Postgres version from asdf. + typeset -g POWERLEVEL9K_ASDF_POSTGRES_FOREGROUND=31 + # typeset -g POWERLEVEL9K_ASDF_POSTGRES_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_POSTGRES_SHOW_ON_UPGLOB='*.foo|*.bar' + + # PHP version from asdf. + typeset -g POWERLEVEL9K_ASDF_PHP_FOREGROUND=99 + # typeset -g POWERLEVEL9K_ASDF_PHP_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_PHP_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Haskell version from asdf. + typeset -g POWERLEVEL9K_ASDF_HASKELL_FOREGROUND=172 + # typeset -g POWERLEVEL9K_ASDF_HASKELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_HASKELL_SHOW_ON_UPGLOB='*.foo|*.bar' + + ##########[ nordvpn: nordvpn connection status, linux only (https://nordvpn.com/) ]########### + # NordVPN connection indicator color. + typeset -g POWERLEVEL9K_NORDVPN_FOREGROUND=39 + # Hide NordVPN connection indicator when not connected. + typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_CONTENT_EXPANSION= + typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_VISUAL_IDENTIFIER_EXPANSION= + # Custom icon. + # typeset -g POWERLEVEL9K_NORDVPN_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #################[ ranger: ranger shell (https://github.com/ranger/ranger) ]################## + # Ranger shell color. + typeset -g POWERLEVEL9K_RANGER_FOREGROUND=178 + # Custom icon. + # typeset -g POWERLEVEL9K_RANGER_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################[ nnn: nnn shell (https://github.com/jarun/nnn) ]####################### + # Nnn shell color. + typeset -g POWERLEVEL9K_NNN_FOREGROUND=72 + # Custom icon. + # typeset -g POWERLEVEL9K_NNN_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########################[ vim_shell: vim shell indicator (:sh) ]########################### + # Vim shell indicator color. + typeset -g POWERLEVEL9K_VIM_SHELL_FOREGROUND=34 + # Custom icon. + # typeset -g POWERLEVEL9K_VIM_SHELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######[ midnight_commander: midnight commander shell (https://midnight-commander.org/) ]###### + # Midnight Commander shell color. + typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_FOREGROUND=178 + # Custom icon. + # typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ nix_shell: nix shell (https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html) ]## + # Nix shell color. + typeset -g POWERLEVEL9K_NIX_SHELL_FOREGROUND=74 + + # Tip: If you want to see just the icon without "pure" and "impure", uncomment the next line. + # typeset -g POWERLEVEL9K_NIX_SHELL_CONTENT_EXPANSION= + + # Custom icon. + # typeset -g POWERLEVEL9K_NIX_SHELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##################################[ disk_usage: disk usage ]################################## + # Colors for different levels of disk usage. + typeset -g POWERLEVEL9K_DISK_USAGE_NORMAL_FOREGROUND=35 + typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_FOREGROUND=220 + typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_FOREGROUND=160 + # Thresholds for different levels of disk usage (percentage points). + typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL=90 + typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_LEVEL=95 + # If set to true, hide disk usage when below $POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL percent. + typeset -g POWERLEVEL9K_DISK_USAGE_ONLY_WARNING=false + # Custom icon. + # typeset -g POWERLEVEL9K_DISK_USAGE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ vi_mode: vi mode (you don't need this if you've enabled prompt_char) ]########### + # Text and color for normal (a.k.a. command) vi mode. + typeset -g POWERLEVEL9K_VI_COMMAND_MODE_STRING=NORMAL + typeset -g POWERLEVEL9K_VI_MODE_NORMAL_FOREGROUND=106 + # Text and color for visual vi mode. + typeset -g POWERLEVEL9K_VI_VISUAL_MODE_STRING=VISUAL + typeset -g POWERLEVEL9K_VI_MODE_VISUAL_FOREGROUND=68 + # Text and color for overtype (a.k.a. overwrite and replace) vi mode. + typeset -g POWERLEVEL9K_VI_OVERWRITE_MODE_STRING=OVERTYPE + typeset -g POWERLEVEL9K_VI_MODE_OVERWRITE_FOREGROUND=172 + # Text and color for insert vi mode. + typeset -g POWERLEVEL9K_VI_INSERT_MODE_STRING= + typeset -g POWERLEVEL9K_VI_MODE_INSERT_FOREGROUND=66 + + # Custom icon. + # typeset -g POWERLEVEL9K_RANGER_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################################[ ram: free RAM ]####################################### + # RAM color. + typeset -g POWERLEVEL9K_RAM_FOREGROUND=66 + # Custom icon. + # typeset -g POWERLEVEL9K_RAM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #####################################[ swap: used swap ]###################################### + # Swap color. + typeset -g POWERLEVEL9K_SWAP_FOREGROUND=96 + # Custom icon. + # typeset -g POWERLEVEL9K_SWAP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################################[ load: CPU load ]###################################### + # Show average CPU load over this many last minutes. Valid values are 1, 5 and 15. + typeset -g POWERLEVEL9K_LOAD_WHICH=5 + # Load color when load is under 50%. + typeset -g POWERLEVEL9K_LOAD_NORMAL_FOREGROUND=66 + # Load color when load is between 50% and 70%. + typeset -g POWERLEVEL9K_LOAD_WARNING_FOREGROUND=178 + # Load color when load is over 70%. + typeset -g POWERLEVEL9K_LOAD_CRITICAL_FOREGROUND=166 + # Custom icon. + # typeset -g POWERLEVEL9K_LOAD_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ todo: todo items (https://github.com/todotxt/todo.txt-cli) ]################ + # Todo color. + typeset -g POWERLEVEL9K_TODO_FOREGROUND=110 + # Hide todo when the total number of tasks is zero. + typeset -g POWERLEVEL9K_TODO_HIDE_ZERO_TOTAL=true + # Hide todo when the number of tasks after filtering is zero. + typeset -g POWERLEVEL9K_TODO_HIDE_ZERO_FILTERED=false + + # Todo format. The following parameters are available within the expansion. + # + # - P9K_TODO_TOTAL_TASK_COUNT The total number of tasks. + # - P9K_TODO_FILTERED_TASK_COUNT The number of tasks after filtering. + # + # These variables correspond to the last line of the output of `todo.sh -p ls`: + # + # TODO: 24 of 42 tasks shown + # + # Here 24 is P9K_TODO_FILTERED_TASK_COUNT and 42 is P9K_TODO_TOTAL_TASK_COUNT. + # + # typeset -g POWERLEVEL9K_TODO_CONTENT_EXPANSION='$P9K_TODO_FILTERED_TASK_COUNT' + + # Custom icon. + # typeset -g POWERLEVEL9K_TODO_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ timewarrior: timewarrior tracking status (https://timewarrior.net/) ]############ + # Timewarrior color. + typeset -g POWERLEVEL9K_TIMEWARRIOR_FOREGROUND=110 + # If the tracked task is longer than 24 characters, truncate and append "…". + # Tip: To always display tasks without truncation, delete the following parameter. + # Tip: To hide task names and display just the icon when time tracking is enabled, set the + # value of the following parameter to "". + typeset -g POWERLEVEL9K_TIMEWARRIOR_CONTENT_EXPANSION='${P9K_CONTENT:0:24}${${P9K_CONTENT:24}:+…}' + + # Custom icon. + # typeset -g POWERLEVEL9K_TIMEWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############[ taskwarrior: taskwarrior task count (https://taskwarrior.org/) ]############## + # Taskwarrior color. + typeset -g POWERLEVEL9K_TASKWARRIOR_FOREGROUND=74 + + # Taskwarrior segment format. The following parameters are available within the expansion. + # + # - P9K_TASKWARRIOR_PENDING_COUNT The number of pending tasks: `task +PENDING count`. + # - P9K_TASKWARRIOR_OVERDUE_COUNT The number of overdue tasks: `task +OVERDUE count`. + # + # Zero values are represented as empty parameters. + # + # The default format: + # + # '${P9K_TASKWARRIOR_OVERDUE_COUNT:+"!$P9K_TASKWARRIOR_OVERDUE_COUNT/"}$P9K_TASKWARRIOR_PENDING_COUNT' + # + # typeset -g POWERLEVEL9K_TASKWARRIOR_CONTENT_EXPANSION='$P9K_TASKWARRIOR_PENDING_COUNT' + + # Custom icon. + # typeset -g POWERLEVEL9K_TASKWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##################################[ context: user@hostname ]################################## + # Context color when running with privileges. + typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND=178 + # Context color in SSH without privileges. + typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_FOREGROUND=180 + # Default context color (no privileges, no SSH). + typeset -g POWERLEVEL9K_CONTEXT_FOREGROUND=180 + + # Context format when running with privileges: bold user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE='%B%n@%m' + # Context format when in SSH without privileges: user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_TEMPLATE='%n@%m' + # Default context format (no privileges, no SSH): user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE='%n@%m' + + # Don't show context unless running with privileges or in SSH. + # Tip: Remove the next line to always show context. + typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_{CONTENT,VISUAL_IDENTIFIER}_EXPANSION= + + # Custom icon. + # typeset -g POWERLEVEL9K_CONTEXT_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_CONTEXT_PREFIX='%248Fwith ' + + ###[ virtualenv: python virtual environment (https://docs.python.org/3/library/venv.html) ]### + # Python virtual environment color. + typeset -g POWERLEVEL9K_VIRTUALENV_FOREGROUND=37 + # Don't show Python version next to the virtual environment name. + typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_PYTHON_VERSION=false + # Don't show virtualenv if pyenv is already shown. + typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_WITH_PYENV=false + # Separate environment name from Python version only with a space. + typeset -g POWERLEVEL9K_VIRTUALENV_{LEFT,RIGHT}_DELIMITER= + # Custom icon. + # typeset -g POWERLEVEL9K_VIRTUALENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #####################[ anaconda: conda environment (https://conda.io/) ]###################### + # Anaconda environment color. + typeset -g POWERLEVEL9K_ANACONDA_FOREGROUND=37 + # Don't show Python version next to the anaconda environment name. + typeset -g POWERLEVEL9K_ANACONDA_SHOW_PYTHON_VERSION=false + # Separate environment name from Python version only with a space. + typeset -g POWERLEVEL9K_ANACONDA_{LEFT,RIGHT}_DELIMITER= + # Custom icon. + # typeset -g POWERLEVEL9K_ANACONDA_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ pyenv: python environment (https://github.com/pyenv/pyenv) ]################ + # Pyenv color. + typeset -g POWERLEVEL9K_PYENV_FOREGROUND=37 + # Hide python version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_PYENV_SOURCES=(shell local global) + # If set to false, hide python version if it's the same as global: + # $(pyenv version-name) == $(pyenv global). + typeset -g POWERLEVEL9K_PYENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide python version if it's equal to "system". + typeset -g POWERLEVEL9K_PYENV_SHOW_SYSTEM=true + + # Pyenv segment format. The following parameters are available within the expansion. + # + # - P9K_CONTENT Current pyenv environment (pyenv version-name). + # - P9K_PYENV_PYTHON_VERSION Current python version (python --version). + # + # The default format has the following logic: + # + # 1. Display "$P9K_CONTENT $P9K_PYENV_PYTHON_VERSION" if $P9K_PYENV_PYTHON_VERSION is not + # empty and unequal to $P9K_CONTENT. + # 2. Otherwise display just "$P9K_CONTENT". + typeset -g POWERLEVEL9K_PYENV_CONTENT_EXPANSION='${P9K_CONTENT}${${P9K_PYENV_PYTHON_VERSION:#$P9K_CONTENT}:+ $P9K_PYENV_PYTHON_VERSION}' + + # Custom icon. + # typeset -g POWERLEVEL9K_PYENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ goenv: go environment (https://github.com/syndbg/goenv) ]################ + # Goenv color. + typeset -g POWERLEVEL9K_GOENV_FOREGROUND=37 + # Hide go version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_GOENV_SOURCES=(shell local global) + # If set to false, hide go version if it's the same as global: + # $(goenv version-name) == $(goenv global). + typeset -g POWERLEVEL9K_GOENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide go version if it's equal to "system". + typeset -g POWERLEVEL9K_GOENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_GOENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ nodenv: node.js version from nodenv (https://github.com/nodenv/nodenv) ]########## + # Nodenv color. + typeset -g POWERLEVEL9K_NODENV_FOREGROUND=70 + # Hide node version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_NODENV_SOURCES=(shell local global) + # If set to false, hide node version if it's the same as global: + # $(nodenv version-name) == $(nodenv global). + typeset -g POWERLEVEL9K_NODENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide node version if it's equal to "system". + typeset -g POWERLEVEL9K_NODENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_NODENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############[ nvm: node.js version from nvm (https://github.com/nvm-sh/nvm) ]############### + # Nvm color. + typeset -g POWERLEVEL9K_NVM_FOREGROUND=70 + # Custom icon. + # typeset -g POWERLEVEL9K_NVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ############[ nodeenv: node.js environment (https://github.com/ekalinin/nodeenv) ]############ + # Nodeenv color. + typeset -g POWERLEVEL9K_NODEENV_FOREGROUND=70 + # Don't show Node version next to the environment name. + typeset -g POWERLEVEL9K_NODEENV_SHOW_NODE_VERSION=false + # Separate environment name from Node version only with a space. + typeset -g POWERLEVEL9K_NODEENV_{LEFT,RIGHT}_DELIMITER= + # Custom icon. + # typeset -g POWERLEVEL9K_NODEENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############################[ node_version: node.js version ]############################### + # Node version color. + typeset -g POWERLEVEL9K_NODE_VERSION_FOREGROUND=70 + # Show node version only when in a directory tree containing package.json. + typeset -g POWERLEVEL9K_NODE_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_NODE_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ go_version: go version (https://golang.org) ]######################## + # Go version color. + typeset -g POWERLEVEL9K_GO_VERSION_FOREGROUND=37 + # Show go version only when in a go project subdirectory. + typeset -g POWERLEVEL9K_GO_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_GO_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #################[ rust_version: rustc version (https://www.rust-lang.org) ]################## + # Rust version color. + typeset -g POWERLEVEL9K_RUST_VERSION_FOREGROUND=37 + # Show rust version only when in a rust project subdirectory. + typeset -g POWERLEVEL9K_RUST_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_RUST_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ dotnet_version: .NET version (https://dotnet.microsoft.com) ]################ + # .NET version color. + typeset -g POWERLEVEL9K_DOTNET_VERSION_FOREGROUND=134 + # Show .NET version only when in a .NET project subdirectory. + typeset -g POWERLEVEL9K_DOTNET_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_DOTNET_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #####################[ php_version: php version (https://www.php.net/) ]###################### + # PHP version color. + typeset -g POWERLEVEL9K_PHP_VERSION_FOREGROUND=99 + # Show PHP version only when in a PHP project subdirectory. + typeset -g POWERLEVEL9K_PHP_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_PHP_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ laravel_version: laravel php framework version (https://laravel.com/) ]########### + # Laravel version color. + typeset -g POWERLEVEL9K_LARAVEL_VERSION_FOREGROUND=161 + # Custom icon. + # typeset -g POWERLEVEL9K_LARAVEL_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ####################[ java_version: java version (https://www.java.com/) ]#################### + # Java version color. + typeset -g POWERLEVEL9K_JAVA_VERSION_FOREGROUND=32 + # Show java version only when in a java project subdirectory. + typeset -g POWERLEVEL9K_JAVA_VERSION_PROJECT_ONLY=true + # Show brief version. + typeset -g POWERLEVEL9K_JAVA_VERSION_FULL=false + # Custom icon. + # typeset -g POWERLEVEL9K_JAVA_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###[ package: name@version from package.json (https://docs.npmjs.com/files/package.json) ]#### + # Package color. + typeset -g POWERLEVEL9K_PACKAGE_FOREGROUND=117 + # Package format. The following parameters are available within the expansion. + # + # - P9K_PACKAGE_NAME The value of `name` field in package.json. + # - P9K_PACKAGE_VERSION The value of `version` field in package.json. + # + # typeset -g POWERLEVEL9K_PACKAGE_CONTENT_EXPANSION='${P9K_PACKAGE_NAME//\%/%%}@${P9K_PACKAGE_VERSION//\%/%%}' + # Custom icon. + # typeset -g POWERLEVEL9K_PACKAGE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #############[ rbenv: ruby version from rbenv (https://github.com/rbenv/rbenv) ]############## + # Rbenv color. + typeset -g POWERLEVEL9K_RBENV_FOREGROUND=168 + # Hide ruby version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_RBENV_SOURCES=(shell local global) + # If set to false, hide ruby version if it's the same as global: + # $(rbenv version-name) == $(rbenv global). + typeset -g POWERLEVEL9K_RBENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide ruby version if it's equal to "system". + typeset -g POWERLEVEL9K_RBENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_RBENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ rvm: ruby version from rvm (https://rvm.io) ]######################## + # Rvm color. + typeset -g POWERLEVEL9K_RVM_FOREGROUND=168 + # Don't show @gemset at the end. + typeset -g POWERLEVEL9K_RVM_SHOW_GEMSET=false + # Don't show ruby- at the front. + typeset -g POWERLEVEL9K_RVM_SHOW_PREFIX=false + # Custom icon. + # typeset -g POWERLEVEL9K_RVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ fvm: flutter version management (https://github.com/leoafarias/fvm) ]############ + # Fvm color. + typeset -g POWERLEVEL9K_FVM_FOREGROUND=38 + # Custom icon. + # typeset -g POWERLEVEL9K_FVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ luaenv: lua version from luaenv (https://github.com/cehoffman/luaenv) ]########### + # Lua color. + typeset -g POWERLEVEL9K_LUAENV_FOREGROUND=32 + # Hide lua version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_LUAENV_SOURCES=(shell local global) + # If set to false, hide lua version if it's the same as global: + # $(luaenv version-name) == $(luaenv global). + typeset -g POWERLEVEL9K_LUAENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide lua version if it's equal to "system". + typeset -g POWERLEVEL9K_LUAENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_LUAENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ jenv: java version from jenv (https://github.com/jenv/jenv) ]################ + # Java color. + typeset -g POWERLEVEL9K_JENV_FOREGROUND=32 + # Hide java version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_JENV_SOURCES=(shell local global) + # If set to false, hide java version if it's the same as global: + # $(jenv version-name) == $(jenv global). + typeset -g POWERLEVEL9K_JENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide java version if it's equal to "system". + typeset -g POWERLEVEL9K_JENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_JENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ plenv: perl version from plenv (https://github.com/tokuhirom/plenv) ]############ + # Perl color. + typeset -g POWERLEVEL9K_PLENV_FOREGROUND=67 + # Hide perl version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_PLENV_SOURCES=(shell local global) + # If set to false, hide perl version if it's the same as global: + # $(plenv version-name) == $(plenv global). + typeset -g POWERLEVEL9K_PLENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide perl version if it's equal to "system". + typeset -g POWERLEVEL9K_PLENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_PLENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ############[ phpenv: php version from phpenv (https://github.com/phpenv/phpenv) ]############ + # PHP color. + typeset -g POWERLEVEL9K_PHPENV_FOREGROUND=99 + # Hide php version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_PHPENV_SOURCES=(shell local global) + # If set to false, hide php version if it's the same as global: + # $(phpenv version-name) == $(phpenv global). + typeset -g POWERLEVEL9K_PHPENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide php version if it's equal to "system". + typeset -g POWERLEVEL9K_PHPENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_PHPENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ haskell_stack: haskell version from stack (https://haskellstack.org/) ]########### + # Haskell color. + typeset -g POWERLEVEL9K_HASKELL_STACK_FOREGROUND=172 + # Hide haskell version if it doesn't come from one of these sources. + # + # shell: version is set by STACK_YAML + # local: version is set by stack.yaml up the directory tree + # global: version is set by the implicit global project (~/.stack/global-project/stack.yaml) + typeset -g POWERLEVEL9K_HASKELL_STACK_SOURCES=(shell local) + # If set to false, hide haskell version if it's the same as in the implicit global project. + typeset -g POWERLEVEL9K_HASKELL_STACK_ALWAYS_SHOW=true + # Custom icon. + # typeset -g POWERLEVEL9K_HASKELL_STACK_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ terraform: terraform workspace (https://www.terraform.io) ]################# + # POWERLEVEL9K_TERRAFORM_CLASSES is an array with even number of elements. The first element + # in each pair defines a pattern against which the current terraform workspace gets matched. + # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below) + # that gets matched. If you unset all POWERLEVEL9K_TERRAFORM_*CONTENT_EXPANSION parameters, + # you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_TERRAFORM_CLASSES defines the workspace class. Patterns are tried in order. The + # first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_TERRAFORM_CLASSES=( + # '*prod*' PROD + # '*test*' TEST + # '*' DEFAULT) + # + # If your current terraform workspace is "project_test", its class is TEST because "project_test" + # doesn't match the pattern '*prod*' but does match '*test*'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_FOREGROUND=28 + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' + typeset -g POWERLEVEL9K_TERRAFORM_CLASSES=( + # '*prod*' PROD # These values are examples that are unlikely + # '*test*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_TERRAFORM_DEFAULT_FOREGROUND=38 + # typeset -g POWERLEVEL9K_TERRAFORM_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #############[ kubecontext: current kubernetes context (https://kubernetes.io/) ]############# + # Show kubecontext only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show kubecontext. + typeset -g POWERLEVEL9K_KUBECONTEXT_SHOW_ON_COMMAND='kubectl|helm|kubens|kubectx|oc|istioctl|kogito' + + # Kubernetes context classes for the purpose of using different colors, icons and expansions with + # different contexts. + # + # POWERLEVEL9K_KUBECONTEXT_CLASSES is an array with even number of elements. The first element + # in each pair defines a pattern against which the current kubernetes context gets matched. + # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below) + # that gets matched. If you unset all POWERLEVEL9K_KUBECONTEXT_*CONTENT_EXPANSION parameters, + # you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_KUBECONTEXT_CLASSES defines the context class. Patterns are tried in order. The + # first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=( + # '*prod*' PROD + # '*test*' TEST + # '*' DEFAULT) + # + # If your current kubernetes context is "deathray-testing/default", its class is TEST + # because "deathray-testing/default" doesn't match the pattern '*prod*' but does match '*test*'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_FOREGROUND=28 + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' + typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=( + # '*prod*' PROD # These values are examples that are unlikely + # '*test*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_FOREGROUND=134 + # typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Use POWERLEVEL9K_KUBECONTEXT_CONTENT_EXPANSION to specify the content displayed by kubecontext + # segment. Parameter expansions are very flexible and fast, too. See reference: + # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion. + # + # Within the expansion the following parameters are always available: + # + # - P9K_CONTENT The content that would've been displayed if there was no content + # expansion defined. + # - P9K_KUBECONTEXT_NAME The current context's name. Corresponds to column NAME in the + # output of `kubectl config get-contexts`. + # - P9K_KUBECONTEXT_CLUSTER The current context's cluster. Corresponds to column CLUSTER in the + # output of `kubectl config get-contexts`. + # - P9K_KUBECONTEXT_NAMESPACE The current context's namespace. Corresponds to column NAMESPACE + # in the output of `kubectl config get-contexts`. If there is no + # namespace, the parameter is set to "default". + # - P9K_KUBECONTEXT_USER The current context's user. Corresponds to column AUTHINFO in the + # output of `kubectl config get-contexts`. + # + # If the context points to Google Kubernetes Engine (GKE) or Elastic Kubernetes Service (EKS), + # the following extra parameters are available: + # + # - P9K_KUBECONTEXT_CLOUD_NAME Either "gke" or "eks". + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT Account/project ID. + # - P9K_KUBECONTEXT_CLOUD_ZONE Availability zone. + # - P9K_KUBECONTEXT_CLOUD_CLUSTER Cluster. + # + # P9K_KUBECONTEXT_CLOUD_* parameters are derived from P9K_KUBECONTEXT_CLUSTER. For example, + # if P9K_KUBECONTEXT_CLUSTER is "gke_my-account_us-east1-a_my-cluster-01": + # + # - P9K_KUBECONTEXT_CLOUD_NAME=gke + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=my-account + # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east1-a + # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01 + # + # If P9K_KUBECONTEXT_CLUSTER is "arn:aws:eks:us-east-1:123456789012:cluster/my-cluster-01": + # + # - P9K_KUBECONTEXT_CLOUD_NAME=eks + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=123456789012 + # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east-1 + # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01 + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION= + # Show P9K_KUBECONTEXT_CLOUD_CLUSTER if it's not empty and fall back to P9K_KUBECONTEXT_NAME. + POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${P9K_KUBECONTEXT_CLOUD_CLUSTER:-${P9K_KUBECONTEXT_NAME}}' + # Append the current context's namespace if it's not "default". + POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${${:-/$P9K_KUBECONTEXT_NAMESPACE}:#/default}' + + # Custom prefix. + # typeset -g POWERLEVEL9K_KUBECONTEXT_PREFIX='%248Fat ' + + #[ aws: aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) ]# + # Show aws only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show aws. + typeset -g POWERLEVEL9K_AWS_SHOW_ON_COMMAND='aws|awless|terraform|pulumi' + + # POWERLEVEL9K_AWS_CLASSES is an array with even number of elements. The first element + # in each pair defines a pattern against which the current AWS profile gets matched. + # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below) + # that gets matched. If you unset all POWERLEVEL9K_AWS_*CONTENT_EXPANSION parameters, + # you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_AWS_CLASSES defines the profile class. Patterns are tried in order. The + # first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_AWS_CLASSES=( + # '*prod*' PROD + # '*test*' TEST + # '*' DEFAULT) + # + # If your current AWS profile is "company_test", its class is TEST + # because "company_test" doesn't match the pattern '*prod*' but does match '*test*'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_AWS_TEST_FOREGROUND=28 + # typeset -g POWERLEVEL9K_AWS_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_AWS_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' + typeset -g POWERLEVEL9K_AWS_CLASSES=( + # '*prod*' PROD # These values are examples that are unlikely + # '*test*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_AWS_DEFAULT_FOREGROUND=208 + # typeset -g POWERLEVEL9K_AWS_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ aws_eb_env: aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) ]# + # AWS Elastic Beanstalk environment color. + typeset -g POWERLEVEL9K_AWS_EB_ENV_FOREGROUND=70 + # Custom icon. + # typeset -g POWERLEVEL9K_AWS_EB_ENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ azure: azure account name (https://docs.microsoft.com/en-us/cli/azure) ]########## + # Show azure only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show azure. + typeset -g POWERLEVEL9K_AZURE_SHOW_ON_COMMAND='az|terraform|pulumi' + # Azure account name color. + typeset -g POWERLEVEL9K_AZURE_FOREGROUND=32 + # Custom icon. + # typeset -g POWERLEVEL9K_AZURE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ gcloud: google cloud account and project (https://cloud.google.com/) ]########### + # Show gcloud only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show gcloud. + typeset -g POWERLEVEL9K_GCLOUD_SHOW_ON_COMMAND='gcloud|gcs' + # Google cloud color. + typeset -g POWERLEVEL9K_GCLOUD_FOREGROUND=32 + + # Google cloud format. Change the value of POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION and/or + # POWERLEVEL9K_GCLOUD_COMPLETE_CONTENT_EXPANSION if the default is too verbose or not informative + # enough. You can use the following parameters in the expansions. Each of them corresponds to the + # output of `gcloud` tool. + # + # Parameter | Source + # -------------------------|-------------------------------------------------------------------- + # P9K_GCLOUD_CONFIGURATION | gcloud config configurations list --format='value(name)' + # P9K_GCLOUD_ACCOUNT | gcloud config get-value account + # P9K_GCLOUD_PROJECT_ID | gcloud config get-value project + # P9K_GCLOUD_PROJECT_NAME | gcloud projects describe $P9K_GCLOUD_PROJECT_ID --format='value(name)' + # + # Note: ${VARIABLE//\%/%%} expands to ${VARIABLE} with all occurences of '%' replaced with '%%'. + # + # Obtaining project name requires sending a request to Google servers. This can take a long time + # and even fail. When project name is unknown, P9K_GCLOUD_PROJECT_NAME is not set and gcloud + # prompt segment is in state PARTIAL. When project name gets known, P9K_GCLOUD_PROJECT_NAME gets + # set and gcloud prompt segment transitions to state COMPLETE. + # + # You can customize the format, icon and colors of gcloud segment separately for states PARTIAL + # and COMPLETE. You can also hide gcloud in state PARTIAL by setting + # POWERLEVEL9K_GCLOUD_PARTIAL_VISUAL_IDENTIFIER_EXPANSION and + # POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION to empty. + typeset -g POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION='${P9K_GCLOUD_PROJECT_ID//\%/%%}' + typeset -g POWERLEVEL9K_GCLOUD_COMPLETE_CONTENT_EXPANSION='${P9K_GCLOUD_PROJECT_NAME//\%/%%}' + + # Send a request to Google (by means of `gcloud projects describe ...`) to obtain project name + # this often. Negative value disables periodic polling. In this mode project name is retrieved + # only when the current configuration, account or project id changes. + typeset -g POWERLEVEL9K_GCLOUD_REFRESH_PROJECT_NAME_SECONDS=60 + + # Custom icon. + # typeset -g POWERLEVEL9K_GCLOUD_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ google_app_cred: google application credentials (https://cloud.google.com/docs/authentication/production) ]# + # Show google_app_cred only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show google_app_cred. + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_SHOW_ON_COMMAND='terraform|pulumi' + + # Google application credentials classes for the purpose of using different colors, icons and + # expansions with different credentials. + # + # POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES is an array with even number of elements. The first + # element in each pair defines a pattern against which the current kubernetes context gets + # matched. More specifically, it's P9K_CONTENT prior to the application of context expansion + # (see below) that gets matched. If you unset all POWERLEVEL9K_GOOGLE_APP_CRED_*CONTENT_EXPANSION + # parameters, you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES defines the context class. Patterns are tried in order. + # The first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES=( + # '*:*prod*:*' PROD + # '*:*test*:*' TEST + # '*' DEFAULT) + # + # If your current Google application credentials is "service_account deathray-testing x@y.com", + # its class is TEST because it doesn't match the pattern '* *prod* *' but does match '* *test* *'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_FOREGROUND=28 + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_CONTENT_EXPANSION='$P9K_GOOGLE_APP_CRED_PROJECT_ID' + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES=( + # '*:*prod*:*' PROD # These values are examples that are unlikely + # '*:*test*:*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_FOREGROUND=32 + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Use POWERLEVEL9K_GOOGLE_APP_CRED_CONTENT_EXPANSION to specify the content displayed by + # google_app_cred segment. Parameter expansions are very flexible and fast, too. See reference: + # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion. + # + # You can use the following parameters in the expansion. Each of them corresponds to one of the + # fields in the JSON file pointed to by GOOGLE_APPLICATION_CREDENTIALS. + # + # Parameter | JSON key file field + # ---------------------------------+--------------- + # P9K_GOOGLE_APP_CRED_TYPE | type + # P9K_GOOGLE_APP_CRED_PROJECT_ID | project_id + # P9K_GOOGLE_APP_CRED_CLIENT_EMAIL | client_email + # + # Note: ${VARIABLE//\%/%%} expands to ${VARIABLE} with all occurences of '%' replaced by '%%'. + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_CONTENT_EXPANSION='${P9K_GOOGLE_APP_CRED_PROJECT_ID//\%/%%}' + + ###############################[ public_ip: public IP address ]############################### + # Public IP color. + typeset -g POWERLEVEL9K_PUBLIC_IP_FOREGROUND=94 + # Custom icon. + # typeset -g POWERLEVEL9K_PUBLIC_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ########################[ vpn_ip: virtual private network indicator ]######################### + # VPN IP color. + typeset -g POWERLEVEL9K_VPN_IP_FOREGROUND=81 + # When on VPN, show just an icon without the IP address. + # Tip: To display the private IP address when on VPN, remove the next line. + typeset -g POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION= + # Regular expression for the VPN network interface. Run `ifconfig` or `ip -4 a show` while on VPN + # to see the name of the interface. + typeset -g POWERLEVEL9K_VPN_IP_INTERFACE='(wg|(.*tun))[0-9]*' + # If set to true, show one segment per matching network interface. If set to false, show only + # one segment corresponding to the first matching network interface. + # Tip: If you set it to true, you'll probably want to unset POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION. + typeset -g POWERLEVEL9K_VPN_IP_SHOW_ALL=false + # Custom icon. + # typeset -g POWERLEVEL9K_VPN_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ ip: ip address and bandwidth usage for a specified network interface ]########### + # IP color. + typeset -g POWERLEVEL9K_IP_FOREGROUND=38 + # The following parameters are accessible within the expansion: + # + # Parameter | Meaning + # ----------------------+--------------- + # P9K_IP_IP | IP address + # P9K_IP_INTERFACE | network interface + # P9K_IP_RX_BYTES | total number of bytes received + # P9K_IP_TX_BYTES | total number of bytes sent + # P9K_IP_RX_RATE | receive rate (since last prompt) + # P9K_IP_TX_RATE | send rate (since last prompt) + typeset -g POWERLEVEL9K_IP_CONTENT_EXPANSION='${P9K_IP_RX_RATE:+%70F⇣$P9K_IP_RX_RATE }${P9K_IP_TX_RATE:+%215F⇡$P9K_IP_TX_RATE }%38F$P9K_IP_IP' + # Show information for the first network interface whose name matches this regular expression. + # Run `ifconfig` or `ip -4 a show` to see the names of all network interfaces. + typeset -g POWERLEVEL9K_IP_INTERFACE='e.*' + # Custom icon. + # typeset -g POWERLEVEL9K_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #########################[ proxy: system-wide http/https/ftp proxy ]########################## + # Proxy color. + typeset -g POWERLEVEL9K_PROXY_FOREGROUND=68 + # Custom icon. + # typeset -g POWERLEVEL9K_PROXY_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################################[ battery: internal battery ]################################# + # Show battery in red when it's below this level and not connected to power supply. + typeset -g POWERLEVEL9K_BATTERY_LOW_THRESHOLD=20 + typeset -g POWERLEVEL9K_BATTERY_LOW_FOREGROUND=160 + # Show battery in green when it's charging or fully charged. + typeset -g POWERLEVEL9K_BATTERY_{CHARGING,CHARGED}_FOREGROUND=70 + # Show battery in yellow when it's discharging. + typeset -g POWERLEVEL9K_BATTERY_DISCONNECTED_FOREGROUND=178 + # Battery pictograms going from low to high level of charge. + typeset -g POWERLEVEL9K_BATTERY_STAGES=('%K{232}▁' '%K{232}▂' '%K{232}▃' '%K{232}▄' '%K{232}▅' '%K{232}▆' '%K{232}▇' '%K{232}█') + # Don't show the remaining time to charge/discharge. + typeset -g POWERLEVEL9K_BATTERY_VERBOSE=false + + #####################################[ wifi: wifi speed ]##################################### + # WiFi color. + typeset -g POWERLEVEL9K_WIFI_FOREGROUND=68 + # Custom icon. + # typeset -g POWERLEVEL9K_WIFI_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Use different colors and icons depending on signal strength ($P9K_WIFI_BARS). + # + # # Wifi colors and icons for different signal strength levels (low to high). + # typeset -g my_wifi_fg=(68 68 68 68 68) # <-- change these values + # typeset -g my_wifi_icon=('WiFi' 'WiFi' 'WiFi' 'WiFi' 'WiFi') # <-- change these values + # + # typeset -g POWERLEVEL9K_WIFI_CONTENT_EXPANSION='%F{${my_wifi_fg[P9K_WIFI_BARS+1]}}$P9K_WIFI_LAST_TX_RATE Mbps' + # typeset -g POWERLEVEL9K_WIFI_VISUAL_IDENTIFIER_EXPANSION='%F{${my_wifi_fg[P9K_WIFI_BARS+1]}}${my_wifi_icon[P9K_WIFI_BARS+1]}' + # + # The following parameters are accessible within the expansions: + # + # Parameter | Meaning + # ----------------------+--------------- + # P9K_WIFI_SSID | service set identifier, a.k.a. network name + # P9K_WIFI_LINK_AUTH | authentication protocol such as "wpa2-psk" or "none" + # P9K_WIFI_LAST_TX_RATE | wireless transmit rate in megabits per second + # P9K_WIFI_RSSI | signal strength in dBm, from -120 to 0 + # P9K_WIFI_NOISE | noise in dBm, from -120 to 0 + # P9K_WIFI_BARS | signal strength in bars, from 0 to 4 (derived from P9K_WIFI_RSSI and P9K_WIFI_NOISE) + # + # All parameters except P9K_WIFI_BARS are extracted from the output of the following command: + # + # /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I + + ####################################[ time: current time ]#################################### + # Current time color. + typeset -g POWERLEVEL9K_TIME_FOREGROUND=66 + # Format for the current time: 09:51:02. See `man 3 strftime`. + typeset -g POWERLEVEL9K_TIME_FORMAT='%D{%H:%M:%S}' + # If set to true, time will update when you hit enter. This way prompts for the past + # commands will contain the start times of their commands as opposed to the default + # behavior where they contain the end times of their preceding commands. + typeset -g POWERLEVEL9K_TIME_UPDATE_ON_COMMAND=false + # Custom icon. + # typeset -g POWERLEVEL9K_TIME_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_TIME_PREFIX='%248Fat ' + + # Example of a user-defined prompt segment. Function prompt_example will be called on every + # prompt if `example` prompt segment is added to POWERLEVEL9K_LEFT_PROMPT_ELEMENTS or + # POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS. It displays an icon and orange text greeting the user. + # + # Type `p10k help segment` for documentation and a more sophisticated example. + function prompt_example() { + p10k segment -f 208 -i '⭐' -t 'hello, %n' + } + + # User-defined prompt segments may optionally provide an instant_prompt_* function. Its job + # is to generate the prompt segment for display in instant prompt. See + # https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt. + # + # Powerlevel10k will call instant_prompt_* at the same time as the regular prompt_* function + # and will record all `p10k segment` calls it makes. When displaying instant prompt, Powerlevel10k + # will replay these calls without actually calling instant_prompt_*. It is imperative that + # instant_prompt_* always makes the same `p10k segment` calls regardless of environment. If this + # rule is not observed, the content of instant prompt will be incorrect. + # + # Usually, you should either not define instant_prompt_* or simply call prompt_* from it. If + # instant_prompt_* is not defined for a segment, the segment won't be shown in instant prompt. + function instant_prompt_example() { + # Since prompt_example always makes the same `p10k segment` calls, we can call it from + # instant_prompt_example. This will give us the same `example` prompt segment in the instant + # and regular prompts. + prompt_example + } + + # User-defined prompt segments can be customized the same way as built-in segments. + # typeset -g POWERLEVEL9K_EXAMPLE_FOREGROUND=208 + # typeset -g POWERLEVEL9K_EXAMPLE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Transient prompt works similarly to the builtin transient_rprompt option. It trims down prompt + # when accepting a command line. Supported values: + # + # - off: Don't change prompt when accepting a command line. + # - always: Trim down prompt when accepting a command line. + # - same-dir: Trim down prompt when accepting a command line unless this is the first command + # typed after changing current working directory. + typeset -g POWERLEVEL9K_TRANSIENT_PROMPT=off + + # Instant prompt mode. + # + # - off: Disable instant prompt. Choose this if you've tried instant prompt and found + # it incompatible with your zsh configuration files. + # - quiet: Enable instant prompt and don't print warnings when detecting console output + # during zsh initialization. Choose this if you've read and understood + # https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt. + # - verbose: Enable instant prompt and print a warning when detecting console output during + # zsh initialization. Choose this if you've never tried instant prompt, haven't + # seen the warning, or if you are unsure what this all means. + typeset -g POWERLEVEL9K_INSTANT_PROMPT=verbose + + # Hot reload allows you to change POWERLEVEL9K options after Powerlevel10k has been initialized. + # For example, you can type POWERLEVEL9K_BACKGROUND=red and see your prompt turn red. Hot reload + # can slow down prompt by 1-2 milliseconds, so it's better to keep it turned off unless you + # really need it. + typeset -g POWERLEVEL9K_DISABLE_HOT_RELOAD=true + + # If p10k is already loaded, reload configuration. + # This works even with POWERLEVEL9K_DISABLE_HOT_RELOAD=true. + (( ! $+functions[p10k] )) || p10k reload +} + +# Tell `p10k configure` which file it should overwrite. +typeset -g POWERLEVEL9K_CONFIG_FILE=${${(%):-%x}:a} + +(( ${#p10k_config_opts} )) && setopt ${p10k_config_opts[@]} +'builtin' 'unset' 'p10k_config_opts' diff --git a/config/p10k-lean-8colors.zsh b/config/p10k-lean-8colors.zsh new file mode 100644 index 00000000..240009a3 --- /dev/null +++ b/config/p10k-lean-8colors.zsh @@ -0,0 +1,1510 @@ +# Config for Powerlevel10k with 8-color lean prompt style. Type `p10k configure` to generate +# your own config based on it. +# +# Tip: Looking for a nice color? Here's a one-liner to print colormap. +# +# for i in {0..255}; do print -Pn "%K{$i} %k%F{$i}${(l:3::0:)i}%f " ${${(M)$((i%6)):#3}:+$'\n'}; done + +# Temporarily change options. +'builtin' 'local' '-a' 'p10k_config_opts' +[[ ! -o 'aliases' ]] || p10k_config_opts+=('aliases') +[[ ! -o 'sh_glob' ]] || p10k_config_opts+=('sh_glob') +[[ ! -o 'no_brace_expand' ]] || p10k_config_opts+=('no_brace_expand') +'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand' + +() { + emulate -L zsh -o extended_glob + + # Unset all configuration options. This allows you to apply configuration changes without + # restarting zsh. Edit ~/.p10k.zsh and type `source ~/.p10k.zsh`. + unset -m 'POWERLEVEL9K_*|DEFAULT_USER' + + # Zsh >= 5.1 is required. + autoload -Uz is-at-least && is-at-least 5.1 || return + + # The list of segments shown on the left. Fill it with the most important segments. + typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=( + # =========================[ Line #1 ]========================= + # os_icon # os identifier + dir # current directory + vcs # git status + # =========================[ Line #2 ]========================= + newline # \n + prompt_char # prompt symbol + ) + + # The list of segments shown on the right. Fill it with less important segments. + # Right prompt on the last prompt line (where you are typing your commands) gets + # automatically hidden when the input line reaches it. Right prompt above the + # last prompt line gets hidden if it would overlap with left prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=( + # =========================[ Line #1 ]========================= + status # exit code of the last command + command_execution_time # duration of the last command + background_jobs # presence of background jobs + direnv # direnv status (https://direnv.net/) + asdf # asdf version manager (https://github.com/asdf-vm/asdf) + virtualenv # python virtual environment (https://docs.python.org/3/library/venv.html) + anaconda # conda environment (https://conda.io/) + pyenv # python environment (https://github.com/pyenv/pyenv) + goenv # go environment (https://github.com/syndbg/goenv) + nodenv # node.js version from nodenv (https://github.com/nodenv/nodenv) + nvm # node.js version from nvm (https://github.com/nvm-sh/nvm) + nodeenv # node.js environment (https://github.com/ekalinin/nodeenv) + # node_version # node.js version + # go_version # go version (https://golang.org) + # rust_version # rustc version (https://www.rust-lang.org) + # dotnet_version # .NET version (https://dotnet.microsoft.com) + # php_version # php version (https://www.php.net/) + # laravel_version # laravel php framework version (https://laravel.com/) + # java_version # java version (https://www.java.com/) + # package # name@version from package.json (https://docs.npmjs.com/files/package.json) + rbenv # ruby version from rbenv (https://github.com/rbenv/rbenv) + rvm # ruby version from rvm (https://rvm.io) + fvm # flutter version management (https://github.com/leoafarias/fvm) + luaenv # lua version from luaenv (https://github.com/cehoffman/luaenv) + jenv # java version from jenv (https://github.com/jenv/jenv) + plenv # perl version from plenv (https://github.com/tokuhirom/plenv) + phpenv # php version from phpenv (https://github.com/phpenv/phpenv) + haskell_stack # haskell version from stack (https://haskellstack.org/) + kubecontext # current kubernetes context (https://kubernetes.io/) + terraform # terraform workspace (https://www.terraform.io) + aws # aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) + aws_eb_env # aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) + azure # azure account name (https://docs.microsoft.com/en-us/cli/azure) + gcloud # google cloud cli account and project (https://cloud.google.com/) + google_app_cred # google application credentials (https://cloud.google.com/docs/authentication/production) + context # user@hostname + nordvpn # nordvpn connection status, linux only (https://nordvpn.com/) + ranger # ranger shell (https://github.com/ranger/ranger) + nnn # nnn shell (https://github.com/jarun/nnn) + vim_shell # vim shell indicator (:sh) + midnight_commander # midnight commander shell (https://midnight-commander.org/) + nix_shell # nix shell (https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html) + # vpn_ip # virtual private network indicator + # load # CPU load + # disk_usage # disk usage + # ram # free RAM + # swap # used swap + todo # todo items (https://github.com/todotxt/todo.txt-cli) + timewarrior # timewarrior tracking status (https://timewarrior.net/) + taskwarrior # taskwarrior task count (https://taskwarrior.org/) + # time # current time + # =========================[ Line #2 ]========================= + newline # \n + # ip # ip address and bandwidth usage for a specified network interface + # public_ip # public IP address + # proxy # system-wide http/https/ftp proxy + # battery # internal battery + # wifi # wifi speed + # example # example user-defined segment (see prompt_example function below) + ) + + # Defines character set used by powerlevel10k. It's best to let `p10k configure` set it for you. + typeset -g POWERLEVEL9K_MODE=nerdfont-complete + # When set to `moderate`, some icons will have an extra space after them. This is meant to avoid + # icon overlap when using non-monospace fonts. When set to `none`, spaces are not added. + typeset -g POWERLEVEL9K_ICON_PADDING=none + + # Basic style options that define the overall look of your prompt. You probably don't want to + # change them. + typeset -g POWERLEVEL9K_BACKGROUND= # transparent background + typeset -g POWERLEVEL9K_{LEFT,RIGHT}_{LEFT,RIGHT}_WHITESPACE= # no surrounding whitespace + typeset -g POWERLEVEL9K_{LEFT,RIGHT}_SUBSEGMENT_SEPARATOR=' ' # separate segments with a space + typeset -g POWERLEVEL9K_{LEFT,RIGHT}_SEGMENT_SEPARATOR= # no end-of-line symbol + + # When set to true, icons appear before content on both sides of the prompt. When set + # to false, icons go after content. If empty or not set, icons go before content in the left + # prompt and after content in the right prompt. + # + # You can also override it for a specific segment: + # + # POWERLEVEL9K_STATUS_ICON_BEFORE_CONTENT=false + # + # Or for a specific segment in specific state: + # + # POWERLEVEL9K_DIR_NOT_WRITABLE_ICON_BEFORE_CONTENT=false + typeset -g POWERLEVEL9K_ICON_BEFORE_CONTENT=true + + # Add an empty line before each prompt. + typeset -g POWERLEVEL9K_PROMPT_ADD_NEWLINE=true + + # Connect left prompt lines with these symbols. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX= + typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_PREFIX= + typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX= + # Connect right prompt lines with these symbols. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_SUFFIX= + typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_SUFFIX= + typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_SUFFIX= + + # The left end of left prompt. + typeset -g POWERLEVEL9K_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL= + # The right end of right prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL= + + # Ruler, a.k.a. the horizontal line before each prompt. If you set it to true, you'll + # probably want to set POWERLEVEL9K_PROMPT_ADD_NEWLINE=false above and + # POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR=' ' below. + typeset -g POWERLEVEL9K_SHOW_RULER=false + typeset -g POWERLEVEL9K_RULER_CHAR='─' # reasonable alternative: '·' + typeset -g POWERLEVEL9K_RULER_FOREGROUND=7 + + # Filler between left and right prompt on the first prompt line. You can set it to '·' or '─' + # to make it easier to see the alignment between left and right prompt and to separate prompt + # from command output. It serves the same purpose as ruler (see above) without increasing + # the number of prompt lines. You'll probably want to set POWERLEVEL9K_SHOW_RULER=false + # if using this. You might also like POWERLEVEL9K_PROMPT_ADD_NEWLINE=false for more compact + # prompt. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR=' ' + if [[ $POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR != ' ' ]]; then + # The color of the filler. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_FOREGROUND=7 + # Add a space between the end of left prompt and the filler. + typeset -g POWERLEVEL9K_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL=' ' + # Add a space between the filler and the start of right prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL=' ' + # Start filler from the edge of the screen if there are no left segments on the first line. + typeset -g POWERLEVEL9K_EMPTY_LINE_LEFT_PROMPT_FIRST_SEGMENT_END_SYMBOL='%{%}' + # End filler on the edge of the screen if there are no right segments on the first line. + typeset -g POWERLEVEL9K_EMPTY_LINE_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL='%{%}' + fi + + #################################[ os_icon: os identifier ]################################## + # OS identifier color. + typeset -g POWERLEVEL9K_OS_ICON_FOREGROUND= + # Custom icon. + # typeset -g POWERLEVEL9K_OS_ICON_CONTENT_EXPANSION='⭐' + + ################################[ prompt_char: prompt symbol ]################################ + # Green prompt symbol if the last command succeeded. + typeset -g POWERLEVEL9K_PROMPT_CHAR_OK_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=2 + # Red prompt symbol if the last command failed. + typeset -g POWERLEVEL9K_PROMPT_CHAR_ERROR_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=1 + # Default prompt symbol. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIINS_CONTENT_EXPANSION='❯' + # Prompt symbol in command vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VICMD_CONTENT_EXPANSION='❮' + # Prompt symbol in visual vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIVIS_CONTENT_EXPANSION='Ⅴ' + # Prompt symbol in overwrite vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIOWR_CONTENT_EXPANSION='▶' + typeset -g POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE=true + # No line terminator if prompt_char is the last segment. + typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL='' + # No line introducer if prompt_char is the first segment. + typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL= + + ##################################[ dir: current directory ]################################## + # Default current directory color. + typeset -g POWERLEVEL9K_DIR_FOREGROUND=4 + # If directory is too long, shorten some of its segments to the shortest possible unique + # prefix. The shortened directory can be tab-completed to the original. + typeset -g POWERLEVEL9K_SHORTEN_STRATEGY=truncate_to_unique + # Replace removed segment suffixes with this symbol. + typeset -g POWERLEVEL9K_SHORTEN_DELIMITER= + # Color of the shortened directory segments. + typeset -g POWERLEVEL9K_DIR_SHORTENED_FOREGROUND=4 + # Color of the anchor directory segments. Anchor segments are never shortened. The first + # segment is always an anchor. + typeset -g POWERLEVEL9K_DIR_ANCHOR_FOREGROUND=4 + # Set to true to display anchor directory segments in bold. + typeset -g POWERLEVEL9K_DIR_ANCHOR_BOLD=false + # Don't shorten directories that contain any of these files. They are anchors. + local anchor_files=( + .bzr + .citc + .git + .hg + .node-version + .python-version + .go-version + .ruby-version + .lua-version + .java-version + .perl-version + .php-version + .tool-version + .shorten_folder_marker + .svn + .terraform + CVS + Cargo.toml + composer.json + go.mod + package.json + stack.yaml + ) + typeset -g POWERLEVEL9K_SHORTEN_FOLDER_MARKER="(${(j:|:)anchor_files})" + # If set to "first" ("last"), remove everything before the first (last) subdirectory that contains + # files matching $POWERLEVEL9K_SHORTEN_FOLDER_MARKER. For example, when the current directory is + # /foo/bar/git_repo/nested_git_repo/baz, prompt will display git_repo/nested_git_repo/baz (first) + # or nested_git_repo/baz (last). This assumes that git_repo and nested_git_repo contain markers + # and other directories don't. + typeset -g POWERLEVEL9K_DIR_TRUNCATE_BEFORE_MARKER=false + # Don't shorten this many last directory segments. They are anchors. + typeset -g POWERLEVEL9K_SHORTEN_DIR_LENGTH=1 + # Shorten directory if it's longer than this even if there is space for it. The value can + # be either absolute (e.g., '80') or a percentage of terminal width (e.g, '50%'). If empty, + # directory will be shortened only when prompt doesn't fit or when other parameters demand it + # (see POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS and POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT below). + # If set to `0`, directory will always be shortened to its minimum length. + typeset -g POWERLEVEL9K_DIR_MAX_LENGTH=80 + # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least this + # many columns for typing commands. + typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS=40 + # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least + # COLUMNS * POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT * 0.01 columns for typing commands. + typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT=50 + # If set to true, embed a hyperlink into the directory. Useful for quickly + # opening a directory in the file manager simply by clicking the link. + # Can also be handy when the directory is shortened, as it allows you to see + # the full directory that was used in previous commands. + typeset -g POWERLEVEL9K_DIR_HYPERLINK=false + + # Enable special styling for non-writable directories. See POWERLEVEL9K_LOCK_ICON and + # POWERLEVEL9K_DIR_CLASSES below. + typeset -g POWERLEVEL9K_DIR_SHOW_WRITABLE=v2 + + # The default icon shown next to non-writable directories when POWERLEVEL9K_DIR_SHOW_WRITABLE is + # set to v2. + # typeset -g POWERLEVEL9K_LOCK_ICON='⭐' + + # POWERLEVEL9K_DIR_CLASSES allows you to specify custom icons and colors for different + # directories. It must be an array with 3 * N elements. Each triplet consists of: + # + # 1. A pattern against which the current directory ($PWD) is matched. Matching is done with + # extended_glob option enabled. + # 2. Directory class for the purpose of styling. + # 3. An empty string. + # + # Triplets are tried in order. The first triplet whose pattern matches $PWD wins. + # + # If POWERLEVEL9K_DIR_SHOW_WRITABLE is set to v2 and the current directory is not writable, + # its class gets suffix _NOT_WRITABLE. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_DIR_CLASSES=( + # '~/work(|/*)' WORK '' + # '~(|/*)' HOME '' + # '*' DEFAULT '') + # + # Whenever the current directory is ~/work or a subdirectory of ~/work, it gets styled with class + # WORK or WORK_NOT_WRITABLE. + # + # Simply assigning classes to directories don't have any visible effects. It merely gives you an + # option to define custom colors and icons for different directory classes. + # + # # Styling for WORK. + # typeset -g POWERLEVEL9K_DIR_WORK_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_DIR_WORK_FOREGROUND=4 + # typeset -g POWERLEVEL9K_DIR_WORK_SHORTENED_FOREGROUND=4 + # typeset -g POWERLEVEL9K_DIR_WORK_ANCHOR_FOREGROUND=4 + # + # # Styling for WORK_NOT_WRITABLE. + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_FOREGROUND=4 + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_SHORTENED_FOREGROUND=4 + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_ANCHOR_FOREGROUND=4 + # + # If a styling parameter isn't explicitly defined for some class, it falls back to the classless + # parameter. For example, if POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_FOREGROUND is not set, it falls + # back to POWERLEVEL9K_DIR_FOREGROUND. + # + # typeset -g POWERLEVEL9K_DIR_CLASSES=() + + # Custom prefix. + # typeset -g POWERLEVEL9K_DIR_PREFIX='%fin ' + + #####################################[ vcs: git status ]###################################### + # Branch icon. Set this parameter to '\uF126 ' for the popular Powerline branch icon. + typeset -g POWERLEVEL9K_VCS_BRANCH_ICON= + + # Untracked files icon. It's really a question mark, your font isn't broken. + # Change the value of this parameter to show a different icon. + typeset -g POWERLEVEL9K_VCS_UNTRACKED_ICON='?' + + # Formatter for Git status. + # + # Example output: master ⇣42⇡42 *42 merge ~42 +42 !42 ?42. + # + # You can edit the function to customize how Git status looks. + # + # VCS_STATUS_* parameters are set by gitstatus plugin. See reference: + # https://github.com/romkatv/gitstatus/blob/master/gitstatus.plugin.zsh. + function my_git_formatter() { + emulate -L zsh + + if [[ -n $P9K_CONTENT ]]; then + # If P9K_CONTENT is not empty, use it. It's either "loading" or from vcs_info (not from + # gitstatus plugin). VCS_STATUS_* parameters are not available in this case. + typeset -g my_git_format=$P9K_CONTENT + return + fi + + if (( $1 )); then + # Styling for up-to-date Git status. + local meta='%f' # default foreground + local clean='%2F' # green foreground + local modified='%3F' # yellow foreground + local untracked='%4F' # blue foreground + local conflicted='%1F' # red foreground + else + # Styling for incomplete and stale Git status. + local meta='%f' # default foreground + local clean='%f' # default foreground + local modified='%f' # default foreground + local untracked='%f' # default foreground + local conflicted='%f' # default foreground + fi + + local res + local where # branch or tag + if [[ -n $VCS_STATUS_LOCAL_BRANCH ]]; then + res+="${clean}${(g::)POWERLEVEL9K_VCS_BRANCH_ICON}" + where=${(V)VCS_STATUS_LOCAL_BRANCH} + elif [[ -n $VCS_STATUS_TAG ]]; then + res+="${meta}#" + where=${(V)VCS_STATUS_TAG} + fi + + # If local branch name or tag is at most 32 characters long, show it in full. + # Otherwise show the first 12 … the last 12. + # Tip: To always show local branch name in full without truncation, delete the next line. + (( $#where > 32 )) && where[13,-13]="…" + res+="${clean}${where//\%/%%}" # escape % + + # Display the current Git commit if there is no branch or tag. + # Tip: To always display the current Git commit, remove `[[ -z $where ]] &&` from the next line. + [[ -z $where ]] && res+="${meta}@${clean}${VCS_STATUS_COMMIT[1,8]}" + + # Show tracking branch name if it differs from local branch. + if [[ -n ${VCS_STATUS_REMOTE_BRANCH:#$VCS_STATUS_LOCAL_BRANCH} ]]; then + res+="${meta}:${clean}${(V)VCS_STATUS_REMOTE_BRANCH//\%/%%}" # escape % + fi + + # ⇣42 if behind the remote. + (( VCS_STATUS_COMMITS_BEHIND )) && res+=" ${clean}⇣${VCS_STATUS_COMMITS_BEHIND}" + # ⇡42 if ahead of the remote; no leading space if also behind the remote: ⇣42⇡42. + (( VCS_STATUS_COMMITS_AHEAD && !VCS_STATUS_COMMITS_BEHIND )) && res+=" " + (( VCS_STATUS_COMMITS_AHEAD )) && res+="${clean}⇡${VCS_STATUS_COMMITS_AHEAD}" + # ⇠42 if behind the push remote. + (( VCS_STATUS_PUSH_COMMITS_BEHIND )) && res+=" ${clean}⇠${VCS_STATUS_PUSH_COMMITS_BEHIND}" + (( VCS_STATUS_PUSH_COMMITS_AHEAD && !VCS_STATUS_PUSH_COMMITS_BEHIND )) && res+=" " + # ⇢42 if ahead of the push remote; no leading space if also behind: ⇠42⇢42. + (( VCS_STATUS_PUSH_COMMITS_AHEAD )) && res+="${clean}⇢${VCS_STATUS_PUSH_COMMITS_AHEAD}" + # *42 if have stashes. + (( VCS_STATUS_STASHES )) && res+=" ${clean}*${VCS_STATUS_STASHES}" + # 'merge' if the repo is in an unusual state. + [[ -n $VCS_STATUS_ACTION ]] && res+=" ${conflicted}${VCS_STATUS_ACTION}" + # ~42 if have merge conflicts. + (( VCS_STATUS_NUM_CONFLICTED )) && res+=" ${conflicted}~${VCS_STATUS_NUM_CONFLICTED}" + # +42 if have staged changes. + (( VCS_STATUS_NUM_STAGED )) && res+=" ${modified}+${VCS_STATUS_NUM_STAGED}" + # !42 if have unstaged changes. + (( VCS_STATUS_NUM_UNSTAGED )) && res+=" ${modified}!${VCS_STATUS_NUM_UNSTAGED}" + # ?42 if have untracked files. It's really a question mark, your font isn't broken. + # See POWERLEVEL9K_VCS_UNTRACKED_ICON above if you want to use a different icon. + # Remove the next line if you don't want to see untracked files at all. + (( VCS_STATUS_NUM_UNTRACKED )) && res+=" ${untracked}${(g::)POWERLEVEL9K_VCS_UNTRACKED_ICON}${VCS_STATUS_NUM_UNTRACKED}" + # "─" if the number of unstaged files is unknown. This can happen due to + # POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY (see below) being set to a non-negative number lower + # than the number of files in the Git index, or due to bash.showDirtyState being set to false + # in the repository config. The number of staged and untracked files may also be unknown + # in this case. + (( VCS_STATUS_HAS_UNSTAGED == -1 )) && res+=" ${modified}─" + + typeset -g my_git_format=$res + } + functions -M my_git_formatter 2>/dev/null + + # Don't count the number of unstaged, untracked and conflicted files in Git repositories with + # more than this many files in the index. Negative value means infinity. + # + # If you are working in Git repositories with tens of millions of files and seeing performance + # sagging, try setting POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY to a number lower than the output + # of `git ls-files | wc -l`. Alternatively, add `bash.showDirtyState = false` to the repository's + # config: `git config bash.showDirtyState false`. + typeset -g POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY=-1 + + # Don't show Git status in prompt for repositories whose workdir matches this pattern. + # For example, if set to '~', the Git repository at $HOME/.git will be ignored. + # Multiple patterns can be combined with '|': '~(|/foo)|/bar/baz/*'. + typeset -g POWERLEVEL9K_VCS_DISABLED_WORKDIR_PATTERN='~' + + # Disable the default Git status formatting. + typeset -g POWERLEVEL9K_VCS_DISABLE_GITSTATUS_FORMATTING=true + # Install our own Git status formatter. + typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION='${$((my_git_formatter(1)))+${my_git_format}}' + typeset -g POWERLEVEL9K_VCS_LOADING_CONTENT_EXPANSION='${$((my_git_formatter(0)))+${my_git_format}}' + # Enable counters for staged, unstaged, etc. + typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED,CONFLICTED,COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=-1 + + # Icon color. + typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_COLOR=2 + typeset -g POWERLEVEL9K_VCS_LOADING_VISUAL_IDENTIFIER_COLOR= + # Custom icon. + # typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_VCS_PREFIX='%fon ' + + # Show status of repositories of these types. You can add svn and/or hg if you are + # using them. If you do, your prompt may become slow even when your current directory + # isn't in an svn or hg reposotiry. + typeset -g POWERLEVEL9K_VCS_BACKENDS=(git) + + # These settings are used for respositories other than Git or when gitstatusd fails and + # Powerlevel10k has to fall back to using vcs_info. + typeset -g POWERLEVEL9K_VCS_CLEAN_FOREGROUND=2 + typeset -g POWERLEVEL9K_VCS_UNTRACKED_FOREGROUND=2 + typeset -g POWERLEVEL9K_VCS_MODIFIED_FOREGROUND=3 + + ##########################[ status: exit code of the last command ]########################### + # Enable OK_PIPE, ERROR_PIPE and ERROR_SIGNAL status states to allow us to enable, disable and + # style them independently from the regular OK and ERROR state. + typeset -g POWERLEVEL9K_STATUS_EXTENDED_STATES=true + + # Status on success. No content, just an icon. No need to show it if prompt_char is enabled as + # it will signify success by turning green. + typeset -g POWERLEVEL9K_STATUS_OK=false + typeset -g POWERLEVEL9K_STATUS_OK_FOREGROUND=2 + typeset -g POWERLEVEL9K_STATUS_OK_VISUAL_IDENTIFIER_EXPANSION='✔' + + # Status when some part of a pipe command fails but the overall exit status is zero. It may look + # like this: 1|0. + typeset -g POWERLEVEL9K_STATUS_OK_PIPE=true + typeset -g POWERLEVEL9K_STATUS_OK_PIPE_FOREGROUND=2 + typeset -g POWERLEVEL9K_STATUS_OK_PIPE_VISUAL_IDENTIFIER_EXPANSION='✔' + + # Status when it's just an error code (e.g., '1'). No need to show it if prompt_char is enabled as + # it will signify error by turning red. + typeset -g POWERLEVEL9K_STATUS_ERROR=false + typeset -g POWERLEVEL9K_STATUS_ERROR_FOREGROUND=1 + typeset -g POWERLEVEL9K_STATUS_ERROR_VISUAL_IDENTIFIER_EXPANSION='✘' + + # Status when the last command was terminated by a signal. + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL=true + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_FOREGROUND=1 + # Use terse signal names: "INT" instead of "SIGINT(2)". + typeset -g POWERLEVEL9K_STATUS_VERBOSE_SIGNAME=false + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_VISUAL_IDENTIFIER_EXPANSION='✘' + + # Status when some part of a pipe command fails and the overall exit status is also non-zero. + # It may look like this: 1|0. + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE=true + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_FOREGROUND=1 + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_VISUAL_IDENTIFIER_EXPANSION='✘' + + ###################[ command_execution_time: duration of the last command ]################### + # Show duration of the last command if takes longer than this many seconds. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=3 + # Show this many fractional digits. Zero means round to seconds. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PRECISION=0 + # Execution time color. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FOREGROUND=3 + # Duration format: 1d 2h 3m 4s. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FORMAT='d h m s' + # Custom icon. + # typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PREFIX='%ftook ' + + #######################[ background_jobs: presence of background jobs ]####################### + # Don't show the number of background jobs. + typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VERBOSE=false + # Background jobs color. + typeset -g POWERLEVEL9K_BACKGROUND_JOBS_FOREGROUND=1 + # Custom icon. + # typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ direnv: direnv status (https://direnv.net/) ]######################## + # Direnv color. + typeset -g POWERLEVEL9K_DIRENV_FOREGROUND=3 + # Custom icon. + # typeset -g POWERLEVEL9K_DIRENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ asdf: asdf version manager (https://github.com/asdf-vm/asdf) ]############### + # Default asdf color. Only used to display tools for which there is no color override (see below). + typeset -g POWERLEVEL9K_ASDF_FOREGROUND=6 + + # There are four parameters that can be used to hide asdf tools. Each parameter describes + # conditions under which a tool gets hidden. Parameters can hide tools but not unhide them. If at + # least one parameter decides to hide a tool, that tool gets hidden. If no parameter decides to + # hide a tool, it gets shown. + # + # Special note on the difference between POWERLEVEL9K_ASDF_SOURCES and + # POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW. Consider the effect of the following commands: + # + # asdf local python 3.8.1 + # asdf global python 3.8.1 + # + # After running both commands the current python version is 3.8.1 and its source is "local" as + # it takes precedence over "global". If POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW is set to false, + # it'll hide python version in this case because 3.8.1 is the same as the global version. + # POWERLEVEL9K_ASDF_SOURCES will hide python version only if the value of this parameter doesn't + # contain "local". + + # Hide tool versions that don't come from one of these sources. + # + # Available sources: + # + # - shell `asdf current` says "set by ASDF_${TOOL}_VERSION environment variable" + # - local `asdf current` says "set by /some/not/home/directory/file" + # - global `asdf current` says "set by /home/username/file" + # + # Note: If this parameter is set to (shell local global), it won't hide tools. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SOURCES. + typeset -g POWERLEVEL9K_ASDF_SOURCES=(shell local global) + + # If set to false, hide tool versions that are the same as global. + # + # Note: The name of this parameter doesn't reflect its meaning at all. + # Note: If this parameter is set to true, it won't hide tools. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_PROMPT_ALWAYS_SHOW. + typeset -g POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW=false + + # If set to false, hide tool versions that are equal to "system". + # + # Note: If this parameter is set to true, it won't hide tools. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SHOW_SYSTEM. + typeset -g POWERLEVEL9K_ASDF_SHOW_SYSTEM=true + + # If set to non-empty value, hide tools unless there is a file matching the specified file pattern + # in the current directory, or its parent diretory, or its grandparent directory, and so on. + # + # Note: If this parameter is set to empty value, it won't hide tools. + # Note: SHOW_ON_UPGLOB isn't specific to asdf. It works with all prompt segments. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SHOW_ON_UPGLOB. + # + # Example: Hide nodejs version when there is no package.json and no *.js files in the current + # directory, in `..`, in `../..` and so on. + # + # typeset -g POWERLEVEL9K_ASDF_NODEJS_SHOW_ON_UPGLOB='*.js|package.json' + typeset -g POWERLEVEL9K_ASDF_SHOW_ON_UPGLOB= + + # Ruby version from asdf. + typeset -g POWERLEVEL9K_ASDF_RUBY_FOREGROUND=1 + # typeset -g POWERLEVEL9K_ASDF_RUBY_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_RUBY_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Python version from asdf. + typeset -g POWERLEVEL9K_ASDF_PYTHON_FOREGROUND=6 + # typeset -g POWERLEVEL9K_ASDF_PYTHON_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_PYTHON_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Go version from asdf. + typeset -g POWERLEVEL9K_ASDF_GOLANG_FOREGROUND=6 + # typeset -g POWERLEVEL9K_ASDF_GOLANG_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_GOLANG_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Node.js version from asdf. + typeset -g POWERLEVEL9K_ASDF_NODEJS_FOREGROUND=2 + # typeset -g POWERLEVEL9K_ASDF_NODEJS_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_NODEJS_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Rust version from asdf. + typeset -g POWERLEVEL9K_ASDF_RUST_FOREGROUND=4 + # typeset -g POWERLEVEL9K_ASDF_RUST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_RUST_SHOW_ON_UPGLOB='*.foo|*.bar' + + # .NET Core version from asdf. + typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_FOREGROUND=5 + # typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Flutter version from asdf. + typeset -g POWERLEVEL9K_ASDF_FLUTTER_FOREGROUND=4 + # typeset -g POWERLEVEL9K_ASDF_FLUTTER_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_FLUTTER_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Lua version from asdf. + typeset -g POWERLEVEL9K_ASDF_LUA_FOREGROUND=4 + # typeset -g POWERLEVEL9K_ASDF_LUA_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_LUA_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Java version from asdf. + typeset -g POWERLEVEL9K_ASDF_JAVA_FOREGROUND=4 + # typeset -g POWERLEVEL9K_ASDF_JAVA_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_JAVA_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Perl version from asdf. + typeset -g POWERLEVEL9K_ASDF_PERL_FOREGROUND=6 + # typeset -g POWERLEVEL9K_ASDF_PERL_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_PERL_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Erlang version from asdf. + typeset -g POWERLEVEL9K_ASDF_ERLANG_FOREGROUND=1 + # typeset -g POWERLEVEL9K_ASDF_ERLANG_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_ERLANG_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Elixir version from asdf. + typeset -g POWERLEVEL9K_ASDF_ELIXIR_FOREGROUND=5 + # typeset -g POWERLEVEL9K_ASDF_ELIXIR_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_ELIXIR_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Postgres version from asdf. + typeset -g POWERLEVEL9K_ASDF_POSTGRES_FOREGROUND=6 + # typeset -g POWERLEVEL9K_ASDF_POSTGRES_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_POSTGRES_SHOW_ON_UPGLOB='*.foo|*.bar' + + # PHP version from asdf. + typeset -g POWERLEVEL9K_ASDF_PHP_FOREGROUND=5 + # typeset -g POWERLEVEL9K_ASDF_PHP_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_PHP_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Haskell version from asdf. + typeset -g POWERLEVEL9K_ASDF_HASKELL_FOREGROUND=3 + # typeset -g POWERLEVEL9K_ASDF_HASKELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_HASKELL_SHOW_ON_UPGLOB='*.foo|*.bar' + + ##########[ nordvpn: nordvpn connection status, linux only (https://nordvpn.com/) ]########### + # NordVPN connection indicator color. + typeset -g POWERLEVEL9K_NORDVPN_FOREGROUND=6 + # Hide NordVPN connection indicator when not connected. + typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_CONTENT_EXPANSION= + typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_VISUAL_IDENTIFIER_EXPANSION= + # Custom icon. + # typeset -g POWERLEVEL9K_NORDVPN_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #################[ ranger: ranger shell (https://github.com/ranger/ranger) ]################## + # Ranger shell color. + typeset -g POWERLEVEL9K_RANGER_FOREGROUND=3 + # Custom icon. + # typeset -g POWERLEVEL9K_RANGER_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################[ nnn: nnn shell (https://github.com/jarun/nnn) ]####################### + # Nnn shell color. + typeset -g POWERLEVEL9K_NNN_FOREGROUND=3 + # Custom icon. + # typeset -g POWERLEVEL9K_NNN_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########################[ vim_shell: vim shell indicator (:sh) ]########################### + # Vim shell indicator color. + typeset -g POWERLEVEL9K_VIM_SHELL_FOREGROUND=3 + # Custom icon. + # typeset -g POWERLEVEL9K_VIM_SHELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######[ midnight_commander: midnight commander shell (https://midnight-commander.org/) ]###### + # Midnight Commander shell color. + typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_FOREGROUND=3 + # Custom icon. + # typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ nix_shell: nix shell (https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html) ]## + # Nix shell color. + typeset -g POWERLEVEL9K_NIX_SHELL_FOREGROUND=4 + + # Tip: If you want to see just the icon without "pure" and "impure", uncomment the next line. + # typeset -g POWERLEVEL9K_NIX_SHELL_CONTENT_EXPANSION= + + # Custom icon. + # typeset -g POWERLEVEL9K_NIX_SHELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##################################[ disk_usage: disk usage ]################################## + # Colors for different levels of disk usage. + typeset -g POWERLEVEL9K_DISK_USAGE_NORMAL_FOREGROUND=2 + typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_FOREGROUND=3 + typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_FOREGROUND=1 + # Thresholds for different levels of disk usage (percentage points). + typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL=90 + typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_LEVEL=95 + # If set to true, hide disk usage when below $POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL percent. + typeset -g POWERLEVEL9K_DISK_USAGE_ONLY_WARNING=false + # Custom icon. + # typeset -g POWERLEVEL9K_DISK_USAGE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################################[ ram: free RAM ]####################################### + # RAM color. + typeset -g POWERLEVEL9K_RAM_FOREGROUND=2 + # Custom icon. + # typeset -g POWERLEVEL9K_RAM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #####################################[ swap: used swap ]###################################### + # Swap color. + typeset -g POWERLEVEL9K_SWAP_FOREGROUND=3 + # Custom icon. + # typeset -g POWERLEVEL9K_SWAP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################################[ load: CPU load ]###################################### + # Show average CPU load over this many last minutes. Valid values are 1, 5 and 15. + typeset -g POWERLEVEL9K_LOAD_WHICH=5 + # Load color when load is under 50%. + typeset -g POWERLEVEL9K_LOAD_NORMAL_FOREGROUND=2 + # Load color when load is between 50% and 70%. + typeset -g POWERLEVEL9K_LOAD_WARNING_FOREGROUND=3 + # Load color when load is over 70%. + typeset -g POWERLEVEL9K_LOAD_CRITICAL_FOREGROUND=1 + # Custom icon. + # typeset -g POWERLEVEL9K_LOAD_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ todo: todo items (https://github.com/todotxt/todo.txt-cli) ]################ + # Todo color. + typeset -g POWERLEVEL9K_TODO_FOREGROUND=4 + # Hide todo when the total number of tasks is zero. + typeset -g POWERLEVEL9K_TODO_HIDE_ZERO_TOTAL=true + # Hide todo when the number of tasks after filtering is zero. + typeset -g POWERLEVEL9K_TODO_HIDE_ZERO_FILTERED=false + + # Todo format. The following parameters are available within the expansion. + # + # - P9K_TODO_TOTAL_TASK_COUNT The total number of tasks. + # - P9K_TODO_FILTERED_TASK_COUNT The number of tasks after filtering. + # + # These variables correspond to the last line of the output of `todo.sh -p ls`: + # + # TODO: 24 of 42 tasks shown + # + # Here 24 is P9K_TODO_FILTERED_TASK_COUNT and 42 is P9K_TODO_TOTAL_TASK_COUNT. + # + # typeset -g POWERLEVEL9K_TODO_CONTENT_EXPANSION='$P9K_TODO_FILTERED_TASK_COUNT' + + # Custom icon. + # typeset -g POWERLEVEL9K_TODO_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ timewarrior: timewarrior tracking status (https://timewarrior.net/) ]############ + # Timewarrior color. + typeset -g POWERLEVEL9K_TIMEWARRIOR_FOREGROUND=4 + # If the tracked task is longer than 24 characters, truncate and append "…". + # Tip: To always display tasks without truncation, delete the following parameter. + # Tip: To hide task names and display just the icon when time tracking is enabled, set the + # value of the following parameter to "". + typeset -g POWERLEVEL9K_TIMEWARRIOR_CONTENT_EXPANSION='${P9K_CONTENT:0:24}${${P9K_CONTENT:24}:+…}' + + # Custom icon. + # typeset -g POWERLEVEL9K_TIMEWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############[ taskwarrior: taskwarrior task count (https://taskwarrior.org/) ]############## + # Taskwarrior color. + typeset -g POWERLEVEL9K_TASKWARRIOR_FOREGROUND=6 + + # Taskwarrior segment format. The following parameters are available within the expansion. + # + # - P9K_TASKWARRIOR_PENDING_COUNT The number of pending tasks: `task +PENDING count`. + # - P9K_TASKWARRIOR_OVERDUE_COUNT The number of overdue tasks: `task +OVERDUE count`. + # + # Zero values are represented as empty parameters. + # + # The default format: + # + # '${P9K_TASKWARRIOR_OVERDUE_COUNT:+"!$P9K_TASKWARRIOR_OVERDUE_COUNT/"}$P9K_TASKWARRIOR_PENDING_COUNT' + # + # typeset -g POWERLEVEL9K_TASKWARRIOR_CONTENT_EXPANSION='$P9K_TASKWARRIOR_PENDING_COUNT' + + # Custom icon. + # typeset -g POWERLEVEL9K_TASKWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##################################[ context: user@hostname ]################################## + # Context color when running with privileges. + typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND=1 + # Context color in SSH without privileges. + typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_FOREGROUND=7 + # Default context color (no privileges, no SSH). + typeset -g POWERLEVEL9K_CONTEXT_FOREGROUND=7 + + # Context format when running with privileges: bold user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE='%B%n@%m' + # Context format when in SSH without privileges: user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_TEMPLATE='%n@%m' + # Default context format (no privileges, no SSH): user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE='%n@%m' + + # Don't show context unless running with privileges or in SSH. + # Tip: Remove the next line to always show context. + typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_{CONTENT,VISUAL_IDENTIFIER}_EXPANSION= + + # Custom icon. + # typeset -g POWERLEVEL9K_CONTEXT_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_CONTEXT_PREFIX='%fwith ' + + ###[ virtualenv: python virtual environment (https://docs.python.org/3/library/venv.html) ]### + # Python virtual environment color. + typeset -g POWERLEVEL9K_VIRTUALENV_FOREGROUND=6 + # Don't show Python version next to the virtual environment name. + typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_PYTHON_VERSION=false + # Don't show virtualenv if pyenv is already shown. + typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_WITH_PYENV=false + # Separate environment name from Python version only with a space. + typeset -g POWERLEVEL9K_VIRTUALENV_{LEFT,RIGHT}_DELIMITER= + # Custom icon. + # typeset -g POWERLEVEL9K_VIRTUALENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #####################[ anaconda: conda environment (https://conda.io/) ]###################### + # Anaconda environment color. + typeset -g POWERLEVEL9K_ANACONDA_FOREGROUND=6 + # Don't show Python version next to the anaconda environment name. + typeset -g POWERLEVEL9K_ANACONDA_SHOW_PYTHON_VERSION=false + # Separate environment name from Python version only with a space. + typeset -g POWERLEVEL9K_ANACONDA_{LEFT,RIGHT}_DELIMITER= + # Custom icon. + # typeset -g POWERLEVEL9K_ANACONDA_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ pyenv: python environment (https://github.com/pyenv/pyenv) ]################ + # Pyenv color. + typeset -g POWERLEVEL9K_PYENV_FOREGROUND=6 + # Hide python version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_PYENV_SOURCES=(shell local global) + # If set to false, hide python version if it's the same as global: + # $(pyenv version-name) == $(pyenv global). + typeset -g POWERLEVEL9K_PYENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide python version if it's equal to "system". + typeset -g POWERLEVEL9K_PYENV_SHOW_SYSTEM=true + + # Pyenv segment format. The following parameters are available within the expansion. + # + # - P9K_CONTENT Current pyenv environment (pyenv version-name). + # - P9K_PYENV_PYTHON_VERSION Current python version (python --version). + # + # The default format has the following logic: + # + # 1. Display "$P9K_CONTENT $P9K_PYENV_PYTHON_VERSION" if $P9K_PYENV_PYTHON_VERSION is not + # empty and unequal to $P9K_CONTENT. + # 2. Otherwise display just "$P9K_CONTENT". + typeset -g POWERLEVEL9K_PYENV_CONTENT_EXPANSION='${P9K_CONTENT}${${P9K_PYENV_PYTHON_VERSION:#$P9K_CONTENT}:+ $P9K_PYENV_PYTHON_VERSION}' + + # Custom icon. + # typeset -g POWERLEVEL9K_PYENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ goenv: go environment (https://github.com/syndbg/goenv) ]################ + # Goenv color. + typeset -g POWERLEVEL9K_GOENV_FOREGROUND=6 + # Hide go version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_GOENV_SOURCES=(shell local global) + # If set to false, hide go version if it's the same as global: + # $(goenv version-name) == $(goenv global). + typeset -g POWERLEVEL9K_GOENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide go version if it's equal to "system". + typeset -g POWERLEVEL9K_GOENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_GOENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ nodenv: node.js version from nodenv (https://github.com/nodenv/nodenv) ]########## + # Nodenv color. + typeset -g POWERLEVEL9K_NODENV_FOREGROUND=2 + # Hide node version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_NODENV_SOURCES=(shell local global) + # If set to false, hide node version if it's the same as global: + # $(nodenv version-name) == $(nodenv global). + typeset -g POWERLEVEL9K_NODENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide node version if it's equal to "system". + typeset -g POWERLEVEL9K_NODENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_NODENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############[ nvm: node.js version from nvm (https://github.com/nvm-sh/nvm) ]############### + # Nvm color. + typeset -g POWERLEVEL9K_NVM_FOREGROUND=2 + # Custom icon. + # typeset -g POWERLEVEL9K_NVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ############[ nodeenv: node.js environment (https://github.com/ekalinin/nodeenv) ]############ + # Nodeenv color. + typeset -g POWERLEVEL9K_NODEENV_FOREGROUND=2 + # Don't show Node version next to the environment name. + typeset -g POWERLEVEL9K_NODEENV_SHOW_NODE_VERSION=false + # Separate environment name from Node version only with a space. + typeset -g POWERLEVEL9K_NODEENV_{LEFT,RIGHT}_DELIMITER= + # Custom icon. + # typeset -g POWERLEVEL9K_NODEENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############################[ node_version: node.js version ]############################### + # Node version color. + typeset -g POWERLEVEL9K_NODE_VERSION_FOREGROUND=2 + # Show node version only when in a directory tree containing package.json. + typeset -g POWERLEVEL9K_NODE_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_NODE_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ go_version: go version (https://golang.org) ]######################## + # Go version color. + typeset -g POWERLEVEL9K_GO_VERSION_FOREGROUND=6 + # Show go version only when in a go project subdirectory. + typeset -g POWERLEVEL9K_GO_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_GO_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #################[ rust_version: rustc version (https://www.rust-lang.org) ]################## + # Rust version color. + typeset -g POWERLEVEL9K_RUST_VERSION_FOREGROUND=4 + # Show rust version only when in a rust project subdirectory. + typeset -g POWERLEVEL9K_RUST_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_RUST_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ dotnet_version: .NET version (https://dotnet.microsoft.com) ]################ + # .NET version color. + typeset -g POWERLEVEL9K_DOTNET_VERSION_FOREGROUND=5 + # Show .NET version only when in a .NET project subdirectory. + typeset -g POWERLEVEL9K_DOTNET_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_DOTNET_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #####################[ php_version: php version (https://www.php.net/) ]###################### + # PHP version color. + typeset -g POWERLEVEL9K_PHP_VERSION_FOREGROUND=5 + # Show PHP version only when in a PHP project subdirectory. + typeset -g POWERLEVEL9K_PHP_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_PHP_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ laravel_version: laravel php framework version (https://laravel.com/) ]########### + # Laravel version color. + typeset -g POWERLEVEL9K_LARAVEL_VERSION_FOREGROUND=1 + # Custom icon. + # typeset -g POWERLEVEL9K_LARAVEL_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ####################[ java_version: java version (https://www.java.com/) ]#################### + # Java version color. + typeset -g POWERLEVEL9K_JAVA_VERSION_FOREGROUND=4 + # Show java version only when in a java project subdirectory. + typeset -g POWERLEVEL9K_JAVA_VERSION_PROJECT_ONLY=true + # Show brief version. + typeset -g POWERLEVEL9K_JAVA_VERSION_FULL=false + # Custom icon. + # typeset -g POWERLEVEL9K_JAVA_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###[ package: name@version from package.json (https://docs.npmjs.com/files/package.json) ]#### + # Package color. + typeset -g POWERLEVEL9K_PACKAGE_FOREGROUND=6 + # Package format. The following parameters are available within the expansion. + # + # - P9K_PACKAGE_NAME The value of `name` field in package.json. + # - P9K_PACKAGE_VERSION The value of `version` field in package.json. + # + # typeset -g POWERLEVEL9K_PACKAGE_CONTENT_EXPANSION='${P9K_PACKAGE_NAME//\%/%%}@${P9K_PACKAGE_VERSION//\%/%%}' + # Custom icon. + # typeset -g POWERLEVEL9K_PACKAGE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #############[ rbenv: ruby version from rbenv (https://github.com/rbenv/rbenv) ]############## + # Rbenv color. + typeset -g POWERLEVEL9K_RBENV_FOREGROUND=1 + # Hide ruby version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_RBENV_SOURCES=(shell local global) + # If set to false, hide ruby version if it's the same as global: + # $(rbenv version-name) == $(rbenv global). + typeset -g POWERLEVEL9K_RBENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide ruby version if it's equal to "system". + typeset -g POWERLEVEL9K_RBENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_RBENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ rvm: ruby version from rvm (https://rvm.io) ]######################## + # Rvm color. + typeset -g POWERLEVEL9K_RVM_FOREGROUND=1 + # Don't show @gemset at the end. + typeset -g POWERLEVEL9K_RVM_SHOW_GEMSET=false + # Don't show ruby- at the front. + typeset -g POWERLEVEL9K_RVM_SHOW_PREFIX=false + # Custom icon. + # typeset -g POWERLEVEL9K_RVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ fvm: flutter version management (https://github.com/leoafarias/fvm) ]############ + # Fvm color. + typeset -g POWERLEVEL9K_FVM_FOREGROUND=4 + # Custom icon. + # typeset -g POWERLEVEL9K_FVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ luaenv: lua version from luaenv (https://github.com/cehoffman/luaenv) ]########### + # Lua color. + typeset -g POWERLEVEL9K_LUAENV_FOREGROUND=4 + # Hide lua version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_LUAENV_SOURCES=(shell local global) + # If set to false, hide lua version if it's the same as global: + # $(luaenv version-name) == $(luaenv global). + typeset -g POWERLEVEL9K_LUAENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide lua version if it's equal to "system". + typeset -g POWERLEVEL9K_LUAENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_LUAENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ jenv: java version from jenv (https://github.com/jenv/jenv) ]################ + # Java color. + typeset -g POWERLEVEL9K_JENV_FOREGROUND=4 + # Hide java version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_JENV_SOURCES=(shell local global) + # If set to false, hide java version if it's the same as global: + # $(jenv version-name) == $(jenv global). + typeset -g POWERLEVEL9K_JENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide java version if it's equal to "system". + typeset -g POWERLEVEL9K_JENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_JENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ plenv: perl version from plenv (https://github.com/tokuhirom/plenv) ]############ + # Perl color. + typeset -g POWERLEVEL9K_PLENV_FOREGROUND=6 + # Hide perl version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_PLENV_SOURCES=(shell local global) + # If set to false, hide perl version if it's the same as global: + # $(plenv version-name) == $(plenv global). + typeset -g POWERLEVEL9K_PLENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide perl version if it's equal to "system". + typeset -g POWERLEVEL9K_PLENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_PLENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ############[ phpenv: php version from phpenv (https://github.com/phpenv/phpenv) ]############ + # PHP color. + typeset -g POWERLEVEL9K_PHPENV_FOREGROUND=5 + # Hide php version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_PHPENV_SOURCES=(shell local global) + # If set to false, hide php version if it's the same as global: + # $(phpenv version-name) == $(phpenv global). + typeset -g POWERLEVEL9K_PHPENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide php version if it's equal to "system". + typeset -g POWERLEVEL9K_PHPENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_PHPENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ haskell_stack: haskell version from stack (https://haskellstack.org/) ]########### + # Haskell color. + typeset -g POWERLEVEL9K_HASKELL_STACK_FOREGROUND=3 + # Hide haskell version if it doesn't come from one of these sources. + # + # shell: version is set by STACK_YAML + # local: version is set by stack.yaml up the directory tree + # global: version is set by the implicit global project (~/.stack/global-project/stack.yaml) + typeset -g POWERLEVEL9K_HASKELL_STACK_SOURCES=(shell local) + # If set to false, hide haskell version if it's the same as in the implicit global project. + typeset -g POWERLEVEL9K_HASKELL_STACK_ALWAYS_SHOW=true + # Custom icon. + # typeset -g POWERLEVEL9K_HASKELL_STACK_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #############[ kubecontext: current kubernetes context (https://kubernetes.io/) ]############# + # Show kubecontext only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show kubecontext. + typeset -g POWERLEVEL9K_KUBECONTEXT_SHOW_ON_COMMAND='kubectl|helm|kubens|kubectx|oc|istioctl|kogito' + + # Kubernetes context classes for the purpose of using different colors, icons and expansions with + # different contexts. + # + # POWERLEVEL9K_KUBECONTEXT_CLASSES is an array with even number of elements. The first element + # in each pair defines a pattern against which the current kubernetes context gets matched. + # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below) + # that gets matched. If you unset all POWERLEVEL9K_KUBECONTEXT_*CONTENT_EXPANSION parameters, + # you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_KUBECONTEXT_CLASSES defines the context class. Patterns are tried in order. The + # first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=( + # '*prod*' PROD + # '*test*' TEST + # '*' DEFAULT) + # + # If your current kubernetes context is "deathray-testing/default", its class is TEST + # because "deathray-testing/default" doesn't match the pattern '*prod*' but does match '*test*'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_FOREGROUND=3 + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' + typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=( + # '*prod*' PROD # These values are examples that are unlikely + # '*test*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_FOREGROUND=5 + # typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Use POWERLEVEL9K_KUBECONTEXT_CONTENT_EXPANSION to specify the content displayed by kubecontext + # segment. Parameter expansions are very flexible and fast, too. See reference: + # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion. + # + # Within the expansion the following parameters are always available: + # + # - P9K_CONTENT The content that would've been displayed if there was no content + # expansion defined. + # - P9K_KUBECONTEXT_NAME The current context's name. Corresponds to column NAME in the + # output of `kubectl config get-contexts`. + # - P9K_KUBECONTEXT_CLUSTER The current context's cluster. Corresponds to column CLUSTER in the + # output of `kubectl config get-contexts`. + # - P9K_KUBECONTEXT_NAMESPACE The current context's namespace. Corresponds to column NAMESPACE + # in the output of `kubectl config get-contexts`. If there is no + # namespace, the parameter is set to "default". + # - P9K_KUBECONTEXT_USER The current context's user. Corresponds to column AUTHINFO in the + # output of `kubectl config get-contexts`. + # + # If the context points to Google Kubernetes Engine (GKE) or Elastic Kubernetes Service (EKS), + # the following extra parameters are available: + # + # - P9K_KUBECONTEXT_CLOUD_NAME Either "gke" or "eks". + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT Account/project ID. + # - P9K_KUBECONTEXT_CLOUD_ZONE Availability zone. + # - P9K_KUBECONTEXT_CLOUD_CLUSTER Cluster. + # + # P9K_KUBECONTEXT_CLOUD_* parameters are derived from P9K_KUBECONTEXT_CLUSTER. For example, + # if P9K_KUBECONTEXT_CLUSTER is "gke_my-account_us-east1-a_my-cluster-01": + # + # - P9K_KUBECONTEXT_CLOUD_NAME=gke + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=my-account + # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east1-a + # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01 + # + # If P9K_KUBECONTEXT_CLUSTER is "arn:aws:eks:us-east-1:123456789012:cluster/my-cluster-01": + # + # - P9K_KUBECONTEXT_CLOUD_NAME=eks + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=123456789012 + # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east-1 + # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01 + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION= + # Show P9K_KUBECONTEXT_CLOUD_CLUSTER if it's not empty and fall back to P9K_KUBECONTEXT_NAME. + POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${P9K_KUBECONTEXT_CLOUD_CLUSTER:-${P9K_KUBECONTEXT_NAME}}' + # Append the current context's namespace if it's not "default". + POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${${:-/$P9K_KUBECONTEXT_NAMESPACE}:#/default}' + + # Custom prefix. + # typeset -g POWERLEVEL9K_KUBECONTEXT_PREFIX='%fat ' + + ################[ terraform: terraform workspace (https://www.terraform.io) ]################# + # POWERLEVEL9K_TERRAFORM_CLASSES is an array with even number of elements. The first element + # in each pair defines a pattern against which the current terraform workspace gets matched. + # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below) + # that gets matched. If you unset all POWERLEVEL9K_TERRAFORM_*CONTENT_EXPANSION parameters, + # you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_TERRAFORM_CLASSES defines the workspace class. Patterns are tried in order. The + # first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_TERRAFORM_CLASSES=( + # '*prod*' PROD + # '*test*' TEST + # '*' DEFAULT) + # + # If your current terraform workspace is "project_test", its class is TEST because "project_test" + # doesn't match the pattern '*prod*' but does match '*test*'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_FOREGROUND=2 + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' + typeset -g POWERLEVEL9K_TERRAFORM_CLASSES=( + # '*prod*' PROD # These values are examples that are unlikely + # '*test*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_TERRAFORM_DEFAULT_FOREGROUND=4 + # typeset -g POWERLEVEL9K_TERRAFORM_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ aws: aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) ]# + # Show aws only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show aws. + typeset -g POWERLEVEL9K_AWS_SHOW_ON_COMMAND='aws|awless|terraform|pulumi' + + # POWERLEVEL9K_AWS_CLASSES is an array with even number of elements. The first element + # in each pair defines a pattern against which the current AWS profile gets matched. + # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below) + # that gets matched. If you unset all POWERLEVEL9K_AWS_*CONTENT_EXPANSION parameters, + # you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_AWS_CLASSES defines the profile class. Patterns are tried in order. The + # first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_AWS_CLASSES=( + # '*prod*' PROD + # '*test*' TEST + # '*' DEFAULT) + # + # If your current AWS profile is "company_test", its class is TEST + # because "company_test" doesn't match the pattern '*prod*' but does match '*test*'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_AWS_TEST_FOREGROUND=2 + # typeset -g POWERLEVEL9K_AWS_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_AWS_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' + typeset -g POWERLEVEL9K_AWS_CLASSES=( + # '*prod*' PROD # These values are examples that are unlikely + # '*test*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_AWS_DEFAULT_FOREGROUND=3 + # typeset -g POWERLEVEL9K_AWS_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ aws_eb_env: aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) ]# + # AWS Elastic Beanstalk environment color. + typeset -g POWERLEVEL9K_AWS_EB_ENV_FOREGROUND=2 + # Custom icon. + # typeset -g POWERLEVEL9K_AWS_EB_ENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ azure: azure account name (https://docs.microsoft.com/en-us/cli/azure) ]########## + # Show azure only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show azure. + typeset -g POWERLEVEL9K_AZURE_SHOW_ON_COMMAND='az|terraform|pulumi' + # Azure account name color. + typeset -g POWERLEVEL9K_AZURE_FOREGROUND=4 + # Custom icon. + # typeset -g POWERLEVEL9K_AZURE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ gcloud: google cloud account and project (https://cloud.google.com/) ]########### + # Show gcloud only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show gcloud. + typeset -g POWERLEVEL9K_GCLOUD_SHOW_ON_COMMAND='gcloud|gcs' + # Google cloud color. + typeset -g POWERLEVEL9K_GCLOUD_FOREGROUND=4 + + # Google cloud format. Change the value of POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION and/or + # POWERLEVEL9K_GCLOUD_COMPLETE_CONTENT_EXPANSION if the default is too verbose or not informative + # enough. You can use the following parameters in the expansions. Each of them corresponds to the + # output of `gcloud` tool. + # + # Parameter | Source + # -------------------------|-------------------------------------------------------------------- + # P9K_GCLOUD_CONFIGURATION | gcloud config configurations list --format='value(name)' + # P9K_GCLOUD_ACCOUNT | gcloud config get-value account + # P9K_GCLOUD_PROJECT_ID | gcloud config get-value project + # P9K_GCLOUD_PROJECT_NAME | gcloud projects describe $P9K_GCLOUD_PROJECT_ID --format='value(name)' + # + # Note: ${VARIABLE//\%/%%} expands to ${VARIABLE} with all occurences of '%' replaced with '%%'. + # + # Obtaining project name requires sending a request to Google servers. This can take a long time + # and even fail. When project name is unknown, P9K_GCLOUD_PROJECT_NAME is not set and gcloud + # prompt segment is in state PARTIAL. When project name gets known, P9K_GCLOUD_PROJECT_NAME gets + # set and gcloud prompt segment transitions to state COMPLETE. + # + # You can customize the format, icon and colors of gcloud segment separately for states PARTIAL + # and COMPLETE. You can also hide gcloud in state PARTIAL by setting + # POWERLEVEL9K_GCLOUD_PARTIAL_VISUAL_IDENTIFIER_EXPANSION and + # POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION to empty. + typeset -g POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION='${P9K_GCLOUD_PROJECT_ID//\%/%%}' + typeset -g POWERLEVEL9K_GCLOUD_COMPLETE_CONTENT_EXPANSION='${P9K_GCLOUD_PROJECT_NAME//\%/%%}' + + # Send a request to Google (by means of `gcloud projects describe ...`) to obtain project name + # this often. Negative value disables periodic polling. In this mode project name is retrieved + # only when the current configuration, account or project id changes. + typeset -g POWERLEVEL9K_GCLOUD_REFRESH_PROJECT_NAME_SECONDS=60 + + # Custom icon. + # typeset -g POWERLEVEL9K_GCLOUD_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ google_app_cred: google application credentials (https://cloud.google.com/docs/authentication/production) ]# + # Show google_app_cred only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show google_app_cred. + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_SHOW_ON_COMMAND='terraform|pulumi' + + # Google application credentials classes for the purpose of using different colors, icons and + # expansions with different credentials. + # + # POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES is an array with even number of elements. The first + # element in each pair defines a pattern against which the current kubernetes context gets + # matched. More specifically, it's P9K_CONTENT prior to the application of context expansion + # (see below) that gets matched. If you unset all POWERLEVEL9K_GOOGLE_APP_CRED_*CONTENT_EXPANSION + # parameters, you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES defines the context class. Patterns are tried in order. + # The first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES=( + # '*:*prod*:*' PROD + # '*:*test*:*' TEST + # '*' DEFAULT) + # + # If your current Google application credentials is "service_account deathray-testing x@y.com", + # its class is TEST because it doesn't match the pattern '* *prod* *' but does match '* *test* *'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_FOREGROUND=3 + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_CONTENT_EXPANSION='$P9K_GOOGLE_APP_CRED_PROJECT_ID' + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES=( + # '*:*prod*:*' PROD # These values are examples that are unlikely + # '*:*test*:*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_FOREGROUND=5 + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Use POWERLEVEL9K_GOOGLE_APP_CRED_CONTENT_EXPANSION to specify the content displayed by + # google_app_cred segment. Parameter expansions are very flexible and fast, too. See reference: + # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion. + # + # You can use the following parameters in the expansion. Each of them corresponds to one of the + # fields in the JSON file pointed to by GOOGLE_APPLICATION_CREDENTIALS. + # + # Parameter | JSON key file field + # ---------------------------------+--------------- + # P9K_GOOGLE_APP_CRED_TYPE | type + # P9K_GOOGLE_APP_CRED_PROJECT_ID | project_id + # P9K_GOOGLE_APP_CRED_CLIENT_EMAIL | client_email + # + # Note: ${VARIABLE//\%/%%} expands to ${VARIABLE} with all occurences of '%' replaced by '%%'. + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_CONTENT_EXPANSION='${P9K_GOOGLE_APP_CRED_PROJECT_ID//\%/%%}' + + ###############################[ public_ip: public IP address ]############################### + # Public IP color. + typeset -g POWERLEVEL9K_PUBLIC_IP_FOREGROUND=6 + # Custom icon. + # typeset -g POWERLEVEL9K_PUBLIC_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ########################[ vpn_ip: virtual private network indicator ]######################### + # VPN IP color. + typeset -g POWERLEVEL9K_VPN_IP_FOREGROUND=3 + # When on VPN, show just an icon without the IP address. + # Tip: To display the private IP address when on VPN, remove the next line. + typeset -g POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION= + # Regular expression for the VPN network interface. Run `ifconfig` or `ip -4 a show` while on VPN + # to see the name of the interface. + typeset -g POWERLEVEL9K_VPN_IP_INTERFACE='(wg|(.*tun))[0-9]*' + # If set to true, show one segment per matching network interface. If set to false, show only + # one segment corresponding to the first matching network interface. + # Tip: If you set it to true, you'll probably want to unset POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION. + typeset -g POWERLEVEL9K_VPN_IP_SHOW_ALL=false + # Custom icon. + # typeset -g POWERLEVEL9K_VPN_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ ip: ip address and bandwidth usage for a specified network interface ]########### + # IP color. + typeset -g POWERLEVEL9K_IP_FOREGROUND=4 + # The following parameters are accessible within the expansion: + # + # Parameter | Meaning + # ----------------------+--------------- + # P9K_IP_IP | IP address + # P9K_IP_INTERFACE | network interface + # P9K_IP_RX_BYTES | total number of bytes received + # P9K_IP_TX_BYTES | total number of bytes sent + # P9K_IP_RX_RATE | receive rate (since last prompt) + # P9K_IP_TX_RATE | send rate (since last prompt) + typeset -g POWERLEVEL9K_IP_CONTENT_EXPANSION='$P9K_IP_IP${P9K_IP_RX_RATE:+ %2F⇣$P9K_IP_RX_RATE}${P9K_IP_TX_RATE:+ %3F⇡$P9K_IP_TX_RATE}' + # Show information for the first network interface whose name matches this regular expression. + # Run `ifconfig` or `ip -4 a show` to see the names of all network interfaces. + typeset -g POWERLEVEL9K_IP_INTERFACE='e.*' + # Custom icon. + # typeset -g POWERLEVEL9K_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #########################[ proxy: system-wide http/https/ftp proxy ]########################## + # Proxy color. + typeset -g POWERLEVEL9K_PROXY_FOREGROUND=2 + # Custom icon. + # typeset -g POWERLEVEL9K_PROXY_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################################[ battery: internal battery ]################################# + # Show battery in red when it's below this level and not connected to power supply. + typeset -g POWERLEVEL9K_BATTERY_LOW_THRESHOLD=20 + typeset -g POWERLEVEL9K_BATTERY_LOW_FOREGROUND=1 + # Show battery in green when it's charging or fully charged. + typeset -g POWERLEVEL9K_BATTERY_{CHARGING,CHARGED}_FOREGROUND=2 + # Show battery in yellow when it's discharging. + typeset -g POWERLEVEL9K_BATTERY_DISCONNECTED_FOREGROUND=3 + # Battery pictograms going from low to high level of charge. + typeset -g POWERLEVEL9K_BATTERY_STAGES=('%K{0}▁' '%K{0}▂' '%K{0}▃' '%K{0}▄' '%K{0}▅' '%K{0}▆' '%K{0}▇' '%K{0}█') + # Don't show the remaining time to charge/discharge. + typeset -g POWERLEVEL9K_BATTERY_VERBOSE=false + + #####################################[ wifi: wifi speed ]##################################### + # WiFi color. + typeset -g POWERLEVEL9K_WIFI_FOREGROUND=4 + # Custom icon. + # typeset -g POWERLEVEL9K_WIFI_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Use different colors and icons depending on signal strength ($P9K_WIFI_BARS). + # + # # Wifi colors and icons for different signal strength levels (low to high). + # typeset -g my_wifi_fg=(4 4 4 4 4) # <-- change these values + # typeset -g my_wifi_icon=('WiFi' 'WiFi' 'WiFi' 'WiFi' 'WiFi') # <-- change these values + # + # typeset -g POWERLEVEL9K_WIFI_CONTENT_EXPANSION='%F{${my_wifi_fg[P9K_WIFI_BARS+1]}}$P9K_WIFI_LAST_TX_RATE Mbps' + # typeset -g POWERLEVEL9K_WIFI_VISUAL_IDENTIFIER_EXPANSION='%F{${my_wifi_fg[P9K_WIFI_BARS+1]}}${my_wifi_icon[P9K_WIFI_BARS+1]}' + # + # The following parameters are accessible within the expansions: + # + # Parameter | Meaning + # ----------------------+--------------- + # P9K_WIFI_SSID | service set identifier, a.k.a. network name + # P9K_WIFI_LINK_AUTH | authentication protocol such as "wpa2-psk" or "none" + # P9K_WIFI_LAST_TX_RATE | wireless transmit rate in megabits per second + # P9K_WIFI_RSSI | signal strength in dBm, from -120 to 0 + # P9K_WIFI_NOISE | noise in dBm, from -120 to 0 + # P9K_WIFI_BARS | signal strength in bars, from 0 to 4 (derived from P9K_WIFI_RSSI and P9K_WIFI_NOISE) + # + # All parameters except P9K_WIFI_BARS are extracted from the output of the following command: + # + # /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I + + ####################################[ time: current time ]#################################### + # Current time color. + typeset -g POWERLEVEL9K_TIME_FOREGROUND=6 + # Format for the current time: 09:51:02. See `man 3 strftime`. + typeset -g POWERLEVEL9K_TIME_FORMAT='%D{%H:%M:%S}' + # If set to true, time will update when you hit enter. This way prompts for the past + # commands will contain the start times of their commands as opposed to the default + # behavior where they contain the end times of their preceding commands. + typeset -g POWERLEVEL9K_TIME_UPDATE_ON_COMMAND=false + # Custom icon. + # typeset -g POWERLEVEL9K_TIME_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_TIME_PREFIX='%fat ' + + # Example of a user-defined prompt segment. Function prompt_example will be called on every + # prompt if `example` prompt segment is added to POWERLEVEL9K_LEFT_PROMPT_ELEMENTS or + # POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS. It displays an icon and green text greeting the user. + # + # Type `p10k help segment` for documentation and a more sophisticated example. + function prompt_example() { + p10k segment -f 2 -i '⭐' -t 'hello, %n' + } + + # User-defined prompt segments may optionally provide an instant_prompt_* function. Its job + # is to generate the prompt segment for display in instant prompt. See + # https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt. + # + # Powerlevel10k will call instant_prompt_* at the same time as the regular prompt_* function + # and will record all `p10k segment` calls it makes. When displaying instant prompt, Powerlevel10k + # will replay these calls without actually calling instant_prompt_*. It is imperative that + # instant_prompt_* always makes the same `p10k segment` calls regardless of environment. If this + # rule is not observed, the content of instant prompt will be incorrect. + # + # Usually, you should either not define instant_prompt_* or simply call prompt_* from it. If + # instant_prompt_* is not defined for a segment, the segment won't be shown in instant prompt. + function instant_prompt_example() { + # Since prompt_example always makes the same `p10k segment` calls, we can call it from + # instant_prompt_example. This will give us the same `example` prompt segment in the instant + # and regular prompts. + prompt_example + } + + # User-defined prompt segments can be customized the same way as built-in segments. + # typeset -g POWERLEVEL9K_EXAMPLE_FOREGROUND=208 + # typeset -g POWERLEVEL9K_EXAMPLE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Transient prompt works similarly to the builtin transient_rprompt option. It trims down prompt + # when accepting a command line. Supported values: + # + # - off: Don't change prompt when accepting a command line. + # - always: Trim down prompt when accepting a command line. + # - same-dir: Trim down prompt when accepting a command line unless this is the first command + # typed after changing current working directory. + typeset -g POWERLEVEL9K_TRANSIENT_PROMPT=off + + # Instant prompt mode. + # + # - off: Disable instant prompt. Choose this if you've tried instant prompt and found + # it incompatible with your zsh configuration files. + # - quiet: Enable instant prompt and don't print warnings when detecting console output + # during zsh initialization. Choose this if you've read and understood + # https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt. + # - verbose: Enable instant prompt and print a warning when detecting console output during + # zsh initialization. Choose this if you've never tried instant prompt, haven't + # seen the warning, or if you are unsure what this all means. + typeset -g POWERLEVEL9K_INSTANT_PROMPT=verbose + + # Hot reload allows you to change POWERLEVEL9K options after Powerlevel10k has been initialized. + # For example, you can type POWERLEVEL9K_BACKGROUND=red and see your prompt turn red. Hot reload + # can slow down prompt by 1-2 milliseconds, so it's better to keep it turned off unless you + # really need it. + typeset -g POWERLEVEL9K_DISABLE_HOT_RELOAD=true + + # If p10k is already loaded, reload configuration. + # This works even with POWERLEVEL9K_DISABLE_HOT_RELOAD=true. + (( ! $+functions[p10k] )) || p10k reload +} + +# Tell `p10k configure` which file it should overwrite. +typeset -g POWERLEVEL9K_CONFIG_FILE=${${(%):-%x}:a} + +(( ${#p10k_config_opts} )) && setopt ${p10k_config_opts[@]} +'builtin' 'unset' 'p10k_config_opts' diff --git a/config/p10k-lean.zsh b/config/p10k-lean.zsh new file mode 100644 index 00000000..ea78f5ce --- /dev/null +++ b/config/p10k-lean.zsh @@ -0,0 +1,1510 @@ +# Config for Powerlevel10k with lean prompt style. Type `p10k configure` to generate +# your own config based on it. +# +# Tip: Looking for a nice color? Here's a one-liner to print colormap. +# +# for i in {0..255}; do print -Pn "%K{$i} %k%F{$i}${(l:3::0:)i}%f " ${${(M)$((i%6)):#3}:+$'\n'}; done + +# Temporarily change options. +'builtin' 'local' '-a' 'p10k_config_opts' +[[ ! -o 'aliases' ]] || p10k_config_opts+=('aliases') +[[ ! -o 'sh_glob' ]] || p10k_config_opts+=('sh_glob') +[[ ! -o 'no_brace_expand' ]] || p10k_config_opts+=('no_brace_expand') +'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand' + +() { + emulate -L zsh -o extended_glob + + # Unset all configuration options. This allows you to apply configuration changes without + # restarting zsh. Edit ~/.p10k.zsh and type `source ~/.p10k.zsh`. + unset -m 'POWERLEVEL9K_*|DEFAULT_USER' + + # Zsh >= 5.1 is required. + autoload -Uz is-at-least && is-at-least 5.1 || return + + # The list of segments shown on the left. Fill it with the most important segments. + typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=( + # =========================[ Line #1 ]========================= + # os_icon # os identifier + dir # current directory + vcs # git status + # =========================[ Line #2 ]========================= + newline # \n + prompt_char # prompt symbol + ) + + # The list of segments shown on the right. Fill it with less important segments. + # Right prompt on the last prompt line (where you are typing your commands) gets + # automatically hidden when the input line reaches it. Right prompt above the + # last prompt line gets hidden if it would overlap with left prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=( + # =========================[ Line #1 ]========================= + status # exit code of the last command + command_execution_time # duration of the last command + background_jobs # presence of background jobs + direnv # direnv status (https://direnv.net/) + asdf # asdf version manager (https://github.com/asdf-vm/asdf) + virtualenv # python virtual environment (https://docs.python.org/3/library/venv.html) + anaconda # conda environment (https://conda.io/) + pyenv # python environment (https://github.com/pyenv/pyenv) + goenv # go environment (https://github.com/syndbg/goenv) + nodenv # node.js version from nodenv (https://github.com/nodenv/nodenv) + nvm # node.js version from nvm (https://github.com/nvm-sh/nvm) + nodeenv # node.js environment (https://github.com/ekalinin/nodeenv) + # node_version # node.js version + # go_version # go version (https://golang.org) + # rust_version # rustc version (https://www.rust-lang.org) + # dotnet_version # .NET version (https://dotnet.microsoft.com) + # php_version # php version (https://www.php.net/) + # laravel_version # laravel php framework version (https://laravel.com/) + # java_version # java version (https://www.java.com/) + # package # name@version from package.json (https://docs.npmjs.com/files/package.json) + rbenv # ruby version from rbenv (https://github.com/rbenv/rbenv) + rvm # ruby version from rvm (https://rvm.io) + fvm # flutter version management (https://github.com/leoafarias/fvm) + luaenv # lua version from luaenv (https://github.com/cehoffman/luaenv) + jenv # java version from jenv (https://github.com/jenv/jenv) + plenv # perl version from plenv (https://github.com/tokuhirom/plenv) + phpenv # php version from phpenv (https://github.com/phpenv/phpenv) + haskell_stack # haskell version from stack (https://haskellstack.org/) + kubecontext # current kubernetes context (https://kubernetes.io/) + terraform # terraform workspace (https://www.terraform.io) + aws # aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) + aws_eb_env # aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) + azure # azure account name (https://docs.microsoft.com/en-us/cli/azure) + gcloud # google cloud cli account and project (https://cloud.google.com/) + google_app_cred # google application credentials (https://cloud.google.com/docs/authentication/production) + context # user@hostname + nordvpn # nordvpn connection status, linux only (https://nordvpn.com/) + ranger # ranger shell (https://github.com/ranger/ranger) + nnn # nnn shell (https://github.com/jarun/nnn) + vim_shell # vim shell indicator (:sh) + midnight_commander # midnight commander shell (https://midnight-commander.org/) + nix_shell # nix shell (https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html) + # vpn_ip # virtual private network indicator + # load # CPU load + # disk_usage # disk usage + # ram # free RAM + # swap # used swap + todo # todo items (https://github.com/todotxt/todo.txt-cli) + timewarrior # timewarrior tracking status (https://timewarrior.net/) + taskwarrior # taskwarrior task count (https://taskwarrior.org/) + # time # current time + # =========================[ Line #2 ]========================= + newline + # ip # ip address and bandwidth usage for a specified network interface + # public_ip # public IP address + # proxy # system-wide http/https/ftp proxy + # battery # internal battery + # wifi # wifi speed + # example # example user-defined segment (see prompt_example function below) + ) + + # Defines character set used by powerlevel10k. It's best to let `p10k configure` set it for you. + typeset -g POWERLEVEL9K_MODE=nerdfont-complete + # When set to `moderate`, some icons will have an extra space after them. This is meant to avoid + # icon overlap when using non-monospace fonts. When set to `none`, spaces are not added. + typeset -g POWERLEVEL9K_ICON_PADDING=none + + # Basic style options that define the overall look of your prompt. You probably don't want to + # change them. + typeset -g POWERLEVEL9K_BACKGROUND= # transparent background + typeset -g POWERLEVEL9K_{LEFT,RIGHT}_{LEFT,RIGHT}_WHITESPACE= # no surrounding whitespace + typeset -g POWERLEVEL9K_{LEFT,RIGHT}_SUBSEGMENT_SEPARATOR=' ' # separate segments with a space + typeset -g POWERLEVEL9K_{LEFT,RIGHT}_SEGMENT_SEPARATOR= # no end-of-line symbol + + # When set to true, icons appear before content on both sides of the prompt. When set + # to false, icons go after content. If empty or not set, icons go before content in the left + # prompt and after content in the right prompt. + # + # You can also override it for a specific segment: + # + # POWERLEVEL9K_STATUS_ICON_BEFORE_CONTENT=false + # + # Or for a specific segment in specific state: + # + # POWERLEVEL9K_DIR_NOT_WRITABLE_ICON_BEFORE_CONTENT=false + typeset -g POWERLEVEL9K_ICON_BEFORE_CONTENT=true + + # Add an empty line before each prompt. + typeset -g POWERLEVEL9K_PROMPT_ADD_NEWLINE=true + + # Connect left prompt lines with these symbols. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX= + typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_PREFIX= + typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX= + # Connect right prompt lines with these symbols. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_SUFFIX= + typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_SUFFIX= + typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_SUFFIX= + + # The left end of left prompt. + typeset -g POWERLEVEL9K_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL= + # The right end of right prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL= + + # Ruler, a.k.a. the horizontal line before each prompt. If you set it to true, you'll + # probably want to set POWERLEVEL9K_PROMPT_ADD_NEWLINE=false above and + # POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR=' ' below. + typeset -g POWERLEVEL9K_SHOW_RULER=false + typeset -g POWERLEVEL9K_RULER_CHAR='─' # reasonable alternative: '·' + typeset -g POWERLEVEL9K_RULER_FOREGROUND=240 + + # Filler between left and right prompt on the first prompt line. You can set it to '·' or '─' + # to make it easier to see the alignment between left and right prompt and to separate prompt + # from command output. It serves the same purpose as ruler (see above) without increasing + # the number of prompt lines. You'll probably want to set POWERLEVEL9K_SHOW_RULER=false + # if using this. You might also like POWERLEVEL9K_PROMPT_ADD_NEWLINE=false for more compact + # prompt. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR=' ' + if [[ $POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR != ' ' ]]; then + # The color of the filler. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_FOREGROUND=240 + # Add a space between the end of left prompt and the filler. + typeset -g POWERLEVEL9K_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL=' ' + # Add a space between the filler and the start of right prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL=' ' + # Start filler from the edge of the screen if there are no left segments on the first line. + typeset -g POWERLEVEL9K_EMPTY_LINE_LEFT_PROMPT_FIRST_SEGMENT_END_SYMBOL='%{%}' + # End filler on the edge of the screen if there are no right segments on the first line. + typeset -g POWERLEVEL9K_EMPTY_LINE_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL='%{%}' + fi + + #################################[ os_icon: os identifier ]################################## + # OS identifier color. + typeset -g POWERLEVEL9K_OS_ICON_FOREGROUND= + # Make the icon bold. + typeset -g POWERLEVEL9K_OS_ICON_CONTENT_EXPANSION='${P9K_CONTENT}' + + ################################[ prompt_char: prompt symbol ]################################ + # Green prompt symbol if the last command succeeded. + typeset -g POWERLEVEL9K_PROMPT_CHAR_OK_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=76 + # Red prompt symbol if the last command failed. + typeset -g POWERLEVEL9K_PROMPT_CHAR_ERROR_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=196 + # Default prompt symbol. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIINS_CONTENT_EXPANSION='❯' + # Prompt symbol in command vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VICMD_CONTENT_EXPANSION='❮' + # Prompt symbol in visual vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIVIS_CONTENT_EXPANSION='Ⅴ' + # Prompt symbol in overwrite vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIOWR_CONTENT_EXPANSION='▶' + typeset -g POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE=true + # No line terminator if prompt_char is the last segment. + typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL='' + # No line introducer if prompt_char is the first segment. + typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL= + + ##################################[ dir: current directory ]################################## + # Default current directory color. + typeset -g POWERLEVEL9K_DIR_FOREGROUND=31 + # If directory is too long, shorten some of its segments to the shortest possible unique + # prefix. The shortened directory can be tab-completed to the original. + typeset -g POWERLEVEL9K_SHORTEN_STRATEGY=truncate_to_unique + # Replace removed segment suffixes with this symbol. + typeset -g POWERLEVEL9K_SHORTEN_DELIMITER= + # Color of the shortened directory segments. + typeset -g POWERLEVEL9K_DIR_SHORTENED_FOREGROUND=103 + # Color of the anchor directory segments. Anchor segments are never shortened. The first + # segment is always an anchor. + typeset -g POWERLEVEL9K_DIR_ANCHOR_FOREGROUND=39 + # Display anchor directory segments in bold. + typeset -g POWERLEVEL9K_DIR_ANCHOR_BOLD=true + # Don't shorten directories that contain any of these files. They are anchors. + local anchor_files=( + .bzr + .citc + .git + .hg + .node-version + .python-version + .go-version + .ruby-version + .lua-version + .java-version + .perl-version + .php-version + .tool-version + .shorten_folder_marker + .svn + .terraform + CVS + Cargo.toml + composer.json + go.mod + package.json + stack.yaml + ) + typeset -g POWERLEVEL9K_SHORTEN_FOLDER_MARKER="(${(j:|:)anchor_files})" + # If set to "first" ("last"), remove everything before the first (last) subdirectory that contains + # files matching $POWERLEVEL9K_SHORTEN_FOLDER_MARKER. For example, when the current directory is + # /foo/bar/git_repo/nested_git_repo/baz, prompt will display git_repo/nested_git_repo/baz (first) + # or nested_git_repo/baz (last). This assumes that git_repo and nested_git_repo contain markers + # and other directories don't. + typeset -g POWERLEVEL9K_DIR_TRUNCATE_BEFORE_MARKER=false + # Don't shorten this many last directory segments. They are anchors. + typeset -g POWERLEVEL9K_SHORTEN_DIR_LENGTH=1 + # Shorten directory if it's longer than this even if there is space for it. The value can + # be either absolute (e.g., '80') or a percentage of terminal width (e.g, '50%'). If empty, + # directory will be shortened only when prompt doesn't fit or when other parameters demand it + # (see POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS and POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT below). + # If set to `0`, directory will always be shortened to its minimum length. + typeset -g POWERLEVEL9K_DIR_MAX_LENGTH=80 + # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least this + # many columns for typing commands. + typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS=40 + # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least + # COLUMNS * POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT * 0.01 columns for typing commands. + typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT=50 + # If set to true, embed a hyperlink into the directory. Useful for quickly + # opening a directory in the file manager simply by clicking the link. + # Can also be handy when the directory is shortened, as it allows you to see + # the full directory that was used in previous commands. + typeset -g POWERLEVEL9K_DIR_HYPERLINK=false + + # Enable special styling for non-writable directories. See POWERLEVEL9K_LOCK_ICON and + # POWERLEVEL9K_DIR_CLASSES below. + typeset -g POWERLEVEL9K_DIR_SHOW_WRITABLE=v2 + + # The default icon shown next to non-writable directories when POWERLEVEL9K_DIR_SHOW_WRITABLE is + # set to v2. + # typeset -g POWERLEVEL9K_LOCK_ICON='⭐' + + # POWERLEVEL9K_DIR_CLASSES allows you to specify custom icons and colors for different + # directories. It must be an array with 3 * N elements. Each triplet consists of: + # + # 1. A pattern against which the current directory ($PWD) is matched. Matching is done with + # extended_glob option enabled. + # 2. Directory class for the purpose of styling. + # 3. An empty string. + # + # Triplets are tried in order. The first triplet whose pattern matches $PWD wins. + # + # If POWERLEVEL9K_DIR_SHOW_WRITABLE is set to v2 and the current directory is not writable, + # its class gets suffix _NOT_WRITABLE. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_DIR_CLASSES=( + # '~/work(|/*)' WORK '' + # '~(|/*)' HOME '' + # '*' DEFAULT '') + # + # Whenever the current directory is ~/work or a subdirectory of ~/work, it gets styled with class + # WORK or WORK_NOT_WRITABLE. + # + # Simply assigning classes to directories don't have any visible effects. It merely gives you an + # option to define custom colors and icons for different directory classes. + # + # # Styling for WORK. + # typeset -g POWERLEVEL9K_DIR_WORK_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_DIR_WORK_FOREGROUND=31 + # typeset -g POWERLEVEL9K_DIR_WORK_SHORTENED_FOREGROUND=103 + # typeset -g POWERLEVEL9K_DIR_WORK_ANCHOR_FOREGROUND=39 + # + # # Styling for WORK_NOT_WRITABLE. + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_FOREGROUND=31 + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_SHORTENED_FOREGROUND=103 + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_ANCHOR_FOREGROUND=39 + # + # If a styling parameter isn't explicitly defined for some class, it falls back to the classless + # parameter. For example, if POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_FOREGROUND is not set, it falls + # back to POWERLEVEL9K_DIR_FOREGROUND. + # + # typeset -g POWERLEVEL9K_DIR_CLASSES=() + + # Custom prefix. + # typeset -g POWERLEVEL9K_DIR_PREFIX='%fin ' + + #####################################[ vcs: git status ]###################################### + # Branch icon. Set this parameter to '\uF126 ' for the popular Powerline branch icon. + typeset -g POWERLEVEL9K_VCS_BRANCH_ICON= + + # Untracked files icon. It's really a question mark, your font isn't broken. + # Change the value of this parameter to show a different icon. + typeset -g POWERLEVEL9K_VCS_UNTRACKED_ICON='?' + + # Formatter for Git status. + # + # Example output: master ⇣42⇡42 *42 merge ~42 +42 !42 ?42. + # + # You can edit the function to customize how Git status looks. + # + # VCS_STATUS_* parameters are set by gitstatus plugin. See reference: + # https://github.com/romkatv/gitstatus/blob/master/gitstatus.plugin.zsh. + function my_git_formatter() { + emulate -L zsh + + if [[ -n $P9K_CONTENT ]]; then + # If P9K_CONTENT is not empty, use it. It's either "loading" or from vcs_info (not from + # gitstatus plugin). VCS_STATUS_* parameters are not available in this case. + typeset -g my_git_format=$P9K_CONTENT + return + fi + + if (( $1 )); then + # Styling for up-to-date Git status. + local meta='%f' # default foreground + local clean='%76F' # green foreground + local modified='%178F' # yellow foreground + local untracked='%39F' # blue foreground + local conflicted='%196F' # red foreground + else + # Styling for incomplete and stale Git status. + local meta='%244F' # grey foreground + local clean='%244F' # grey foreground + local modified='%244F' # grey foreground + local untracked='%244F' # grey foreground + local conflicted='%244F' # grey foreground + fi + + local res + local where # branch or tag + if [[ -n $VCS_STATUS_LOCAL_BRANCH ]]; then + res+="${clean}${(g::)POWERLEVEL9K_VCS_BRANCH_ICON}" + where=${(V)VCS_STATUS_LOCAL_BRANCH} + elif [[ -n $VCS_STATUS_TAG ]]; then + res+="${meta}#" + where=${(V)VCS_STATUS_TAG} + fi + + # If local branch name or tag is at most 32 characters long, show it in full. + # Otherwise show the first 12 … the last 12. + # Tip: To always show local branch name in full without truncation, delete the next line. + (( $#where > 32 )) && where[13,-13]="…" + res+="${clean}${where//\%/%%}" # escape % + + # Display the current Git commit if there is no branch or tag. + # Tip: To always display the current Git commit, remove `[[ -z $where ]] &&` from the next line. + [[ -z $where ]] && res+="${meta}@${clean}${VCS_STATUS_COMMIT[1,8]}" + + # Show tracking branch name if it differs from local branch. + if [[ -n ${VCS_STATUS_REMOTE_BRANCH:#$VCS_STATUS_LOCAL_BRANCH} ]]; then + res+="${meta}:${clean}${(V)VCS_STATUS_REMOTE_BRANCH//\%/%%}" # escape % + fi + + # ⇣42 if behind the remote. + (( VCS_STATUS_COMMITS_BEHIND )) && res+=" ${clean}⇣${VCS_STATUS_COMMITS_BEHIND}" + # ⇡42 if ahead of the remote; no leading space if also behind the remote: ⇣42⇡42. + (( VCS_STATUS_COMMITS_AHEAD && !VCS_STATUS_COMMITS_BEHIND )) && res+=" " + (( VCS_STATUS_COMMITS_AHEAD )) && res+="${clean}⇡${VCS_STATUS_COMMITS_AHEAD}" + # ⇠42 if behind the push remote. + (( VCS_STATUS_PUSH_COMMITS_BEHIND )) && res+=" ${clean}⇠${VCS_STATUS_PUSH_COMMITS_BEHIND}" + (( VCS_STATUS_PUSH_COMMITS_AHEAD && !VCS_STATUS_PUSH_COMMITS_BEHIND )) && res+=" " + # ⇢42 if ahead of the push remote; no leading space if also behind: ⇠42⇢42. + (( VCS_STATUS_PUSH_COMMITS_AHEAD )) && res+="${clean}⇢${VCS_STATUS_PUSH_COMMITS_AHEAD}" + # *42 if have stashes. + (( VCS_STATUS_STASHES )) && res+=" ${clean}*${VCS_STATUS_STASHES}" + # 'merge' if the repo is in an unusual state. + [[ -n $VCS_STATUS_ACTION ]] && res+=" ${conflicted}${VCS_STATUS_ACTION}" + # ~42 if have merge conflicts. + (( VCS_STATUS_NUM_CONFLICTED )) && res+=" ${conflicted}~${VCS_STATUS_NUM_CONFLICTED}" + # +42 if have staged changes. + (( VCS_STATUS_NUM_STAGED )) && res+=" ${modified}+${VCS_STATUS_NUM_STAGED}" + # !42 if have unstaged changes. + (( VCS_STATUS_NUM_UNSTAGED )) && res+=" ${modified}!${VCS_STATUS_NUM_UNSTAGED}" + # ?42 if have untracked files. It's really a question mark, your font isn't broken. + # See POWERLEVEL9K_VCS_UNTRACKED_ICON above if you want to use a different icon. + # Remove the next line if you don't want to see untracked files at all. + (( VCS_STATUS_NUM_UNTRACKED )) && res+=" ${untracked}${(g::)POWERLEVEL9K_VCS_UNTRACKED_ICON}${VCS_STATUS_NUM_UNTRACKED}" + # "─" if the number of unstaged files is unknown. This can happen due to + # POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY (see below) being set to a non-negative number lower + # than the number of files in the Git index, or due to bash.showDirtyState being set to false + # in the repository config. The number of staged and untracked files may also be unknown + # in this case. + (( VCS_STATUS_HAS_UNSTAGED == -1 )) && res+=" ${modified}─" + + typeset -g my_git_format=$res + } + functions -M my_git_formatter 2>/dev/null + + # Don't count the number of unstaged, untracked and conflicted files in Git repositories with + # more than this many files in the index. Negative value means infinity. + # + # If you are working in Git repositories with tens of millions of files and seeing performance + # sagging, try setting POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY to a number lower than the output + # of `git ls-files | wc -l`. Alternatively, add `bash.showDirtyState = false` to the repository's + # config: `git config bash.showDirtyState false`. + typeset -g POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY=-1 + + # Don't show Git status in prompt for repositories whose workdir matches this pattern. + # For example, if set to '~', the Git repository at $HOME/.git will be ignored. + # Multiple patterns can be combined with '|': '~(|/foo)|/bar/baz/*'. + typeset -g POWERLEVEL9K_VCS_DISABLED_WORKDIR_PATTERN='~' + + # Disable the default Git status formatting. + typeset -g POWERLEVEL9K_VCS_DISABLE_GITSTATUS_FORMATTING=true + # Install our own Git status formatter. + typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION='${$((my_git_formatter(1)))+${my_git_format}}' + typeset -g POWERLEVEL9K_VCS_LOADING_CONTENT_EXPANSION='${$((my_git_formatter(0)))+${my_git_format}}' + # Enable counters for staged, unstaged, etc. + typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED,CONFLICTED,COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=-1 + + # Icon color. + typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_COLOR=76 + typeset -g POWERLEVEL9K_VCS_LOADING_VISUAL_IDENTIFIER_COLOR=244 + # Custom icon. + # typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_VCS_PREFIX='%fon ' + + # Show status of repositories of these types. You can add svn and/or hg if you are + # using them. If you do, your prompt may become slow even when your current directory + # isn't in an svn or hg reposotiry. + typeset -g POWERLEVEL9K_VCS_BACKENDS=(git) + + # These settings are used for respositories other than Git or when gitstatusd fails and + # Powerlevel10k has to fall back to using vcs_info. + typeset -g POWERLEVEL9K_VCS_CLEAN_FOREGROUND=76 + typeset -g POWERLEVEL9K_VCS_UNTRACKED_FOREGROUND=76 + typeset -g POWERLEVEL9K_VCS_MODIFIED_FOREGROUND=178 + + ##########################[ status: exit code of the last command ]########################### + # Enable OK_PIPE, ERROR_PIPE and ERROR_SIGNAL status states to allow us to enable, disable and + # style them independently from the regular OK and ERROR state. + typeset -g POWERLEVEL9K_STATUS_EXTENDED_STATES=true + + # Status on success. No content, just an icon. No need to show it if prompt_char is enabled as + # it will signify success by turning green. + typeset -g POWERLEVEL9K_STATUS_OK=false + typeset -g POWERLEVEL9K_STATUS_OK_FOREGROUND=70 + typeset -g POWERLEVEL9K_STATUS_OK_VISUAL_IDENTIFIER_EXPANSION='✔' + + # Status when some part of a pipe command fails but the overall exit status is zero. It may look + # like this: 1|0. + typeset -g POWERLEVEL9K_STATUS_OK_PIPE=true + typeset -g POWERLEVEL9K_STATUS_OK_PIPE_FOREGROUND=70 + typeset -g POWERLEVEL9K_STATUS_OK_PIPE_VISUAL_IDENTIFIER_EXPANSION='✔' + + # Status when it's just an error code (e.g., '1'). No need to show it if prompt_char is enabled as + # it will signify error by turning red. + typeset -g POWERLEVEL9K_STATUS_ERROR=false + typeset -g POWERLEVEL9K_STATUS_ERROR_FOREGROUND=160 + typeset -g POWERLEVEL9K_STATUS_ERROR_VISUAL_IDENTIFIER_EXPANSION='✘' + + # Status when the last command was terminated by a signal. + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL=true + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_FOREGROUND=160 + # Use terse signal names: "INT" instead of "SIGINT(2)". + typeset -g POWERLEVEL9K_STATUS_VERBOSE_SIGNAME=false + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_VISUAL_IDENTIFIER_EXPANSION='✘' + + # Status when some part of a pipe command fails and the overall exit status is also non-zero. + # It may look like this: 1|0. + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE=true + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_FOREGROUND=160 + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_VISUAL_IDENTIFIER_EXPANSION='✘' + + ###################[ command_execution_time: duration of the last command ]################### + # Show duration of the last command if takes longer than this many seconds. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=3 + # Show this many fractional digits. Zero means round to seconds. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PRECISION=0 + # Execution time color. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FOREGROUND=101 + # Duration format: 1d 2h 3m 4s. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FORMAT='d h m s' + # Custom icon. + # typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PREFIX='%ftook ' + + #######################[ background_jobs: presence of background jobs ]####################### + # Don't show the number of background jobs. + typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VERBOSE=false + # Background jobs color. + typeset -g POWERLEVEL9K_BACKGROUND_JOBS_FOREGROUND=70 + # Custom icon. + # typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ direnv: direnv status (https://direnv.net/) ]######################## + # Direnv color. + typeset -g POWERLEVEL9K_DIRENV_FOREGROUND=178 + # Custom icon. + # typeset -g POWERLEVEL9K_DIRENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ asdf: asdf version manager (https://github.com/asdf-vm/asdf) ]############### + # Default asdf color. Only used to display tools for which there is no color override (see below). + typeset -g POWERLEVEL9K_ASDF_FOREGROUND=66 + + # There are four parameters that can be used to hide asdf tools. Each parameter describes + # conditions under which a tool gets hidden. Parameters can hide tools but not unhide them. If at + # least one parameter decides to hide a tool, that tool gets hidden. If no parameter decides to + # hide a tool, it gets shown. + # + # Special note on the difference between POWERLEVEL9K_ASDF_SOURCES and + # POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW. Consider the effect of the following commands: + # + # asdf local python 3.8.1 + # asdf global python 3.8.1 + # + # After running both commands the current python version is 3.8.1 and its source is "local" as + # it takes precedence over "global". If POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW is set to false, + # it'll hide python version in this case because 3.8.1 is the same as the global version. + # POWERLEVEL9K_ASDF_SOURCES will hide python version only if the value of this parameter doesn't + # contain "local". + + # Hide tool versions that don't come from one of these sources. + # + # Available sources: + # + # - shell `asdf current` says "set by ASDF_${TOOL}_VERSION environment variable" + # - local `asdf current` says "set by /some/not/home/directory/file" + # - global `asdf current` says "set by /home/username/file" + # + # Note: If this parameter is set to (shell local global), it won't hide tools. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SOURCES. + typeset -g POWERLEVEL9K_ASDF_SOURCES=(shell local global) + + # If set to false, hide tool versions that are the same as global. + # + # Note: The name of this parameter doesn't reflect its meaning at all. + # Note: If this parameter is set to true, it won't hide tools. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_PROMPT_ALWAYS_SHOW. + typeset -g POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW=false + + # If set to false, hide tool versions that are equal to "system". + # + # Note: If this parameter is set to true, it won't hide tools. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SHOW_SYSTEM. + typeset -g POWERLEVEL9K_ASDF_SHOW_SYSTEM=true + + # If set to non-empty value, hide tools unless there is a file matching the specified file pattern + # in the current directory, or its parent diretory, or its grandparent directory, and so on. + # + # Note: If this parameter is set to empty value, it won't hide tools. + # Note: SHOW_ON_UPGLOB isn't specific to asdf. It works with all prompt segments. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SHOW_ON_UPGLOB. + # + # Example: Hide nodejs version when there is no package.json and no *.js files in the current + # directory, in `..`, in `../..` and so on. + # + # typeset -g POWERLEVEL9K_ASDF_NODEJS_SHOW_ON_UPGLOB='*.js|package.json' + typeset -g POWERLEVEL9K_ASDF_SHOW_ON_UPGLOB= + + # Ruby version from asdf. + typeset -g POWERLEVEL9K_ASDF_RUBY_FOREGROUND=168 + # typeset -g POWERLEVEL9K_ASDF_RUBY_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_RUBY_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Python version from asdf. + typeset -g POWERLEVEL9K_ASDF_PYTHON_FOREGROUND=37 + # typeset -g POWERLEVEL9K_ASDF_PYTHON_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_PYTHON_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Go version from asdf. + typeset -g POWERLEVEL9K_ASDF_GOLANG_FOREGROUND=37 + # typeset -g POWERLEVEL9K_ASDF_GOLANG_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_GOLANG_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Node.js version from asdf. + typeset -g POWERLEVEL9K_ASDF_NODEJS_FOREGROUND=70 + # typeset -g POWERLEVEL9K_ASDF_NODEJS_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_NODEJS_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Rust version from asdf. + typeset -g POWERLEVEL9K_ASDF_RUST_FOREGROUND=37 + # typeset -g POWERLEVEL9K_ASDF_RUST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_RUST_SHOW_ON_UPGLOB='*.foo|*.bar' + + # .NET Core version from asdf. + typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_FOREGROUND=134 + # typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_DOTNET_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Flutter version from asdf. + typeset -g POWERLEVEL9K_ASDF_FLUTTER_FOREGROUND=38 + # typeset -g POWERLEVEL9K_ASDF_FLUTTER_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_FLUTTER_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Lua version from asdf. + typeset -g POWERLEVEL9K_ASDF_LUA_FOREGROUND=32 + # typeset -g POWERLEVEL9K_ASDF_LUA_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_LUA_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Java version from asdf. + typeset -g POWERLEVEL9K_ASDF_JAVA_FOREGROUND=32 + # typeset -g POWERLEVEL9K_ASDF_JAVA_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_JAVA_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Perl version from asdf. + typeset -g POWERLEVEL9K_ASDF_PERL_FOREGROUND=67 + # typeset -g POWERLEVEL9K_ASDF_PERL_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_PERL_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Erlang version from asdf. + typeset -g POWERLEVEL9K_ASDF_ERLANG_FOREGROUND=125 + # typeset -g POWERLEVEL9K_ASDF_ERLANG_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_ERLANG_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Elixir version from asdf. + typeset -g POWERLEVEL9K_ASDF_ELIXIR_FOREGROUND=129 + # typeset -g POWERLEVEL9K_ASDF_ELIXIR_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_ELIXIR_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Postgres version from asdf. + typeset -g POWERLEVEL9K_ASDF_POSTGRES_FOREGROUND=31 + # typeset -g POWERLEVEL9K_ASDF_POSTGRES_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_POSTGRES_SHOW_ON_UPGLOB='*.foo|*.bar' + + # PHP version from asdf. + typeset -g POWERLEVEL9K_ASDF_PHP_FOREGROUND=99 + # typeset -g POWERLEVEL9K_ASDF_PHP_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_PHP_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Haskell version from asdf. + typeset -g POWERLEVEL9K_ASDF_HASKELL_FOREGROUND=172 + # typeset -g POWERLEVEL9K_ASDF_HASKELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_HASKELL_SHOW_ON_UPGLOB='*.foo|*.bar' + + ##########[ nordvpn: nordvpn connection status, linux only (https://nordvpn.com/) ]########### + # NordVPN connection indicator color. + typeset -g POWERLEVEL9K_NORDVPN_FOREGROUND=39 + # Hide NordVPN connection indicator when not connected. + typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_CONTENT_EXPANSION= + typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_VISUAL_IDENTIFIER_EXPANSION= + # Custom icon. + # typeset -g POWERLEVEL9K_NORDVPN_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #################[ ranger: ranger shell (https://github.com/ranger/ranger) ]################## + # Ranger shell color. + typeset -g POWERLEVEL9K_RANGER_FOREGROUND=178 + # Custom icon. + # typeset -g POWERLEVEL9K_RANGER_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################[ nnn: nnn shell (https://github.com/jarun/nnn) ]####################### + # Nnn shell color. + typeset -g POWERLEVEL9K_NNN_FOREGROUND=72 + # Custom icon. + # typeset -g POWERLEVEL9K_NNN_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########################[ vim_shell: vim shell indicator (:sh) ]########################### + # Vim shell indicator color. + typeset -g POWERLEVEL9K_VIM_SHELL_FOREGROUND=34 + # Custom icon. + # typeset -g POWERLEVEL9K_VIM_SHELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######[ midnight_commander: midnight commander shell (https://midnight-commander.org/) ]###### + # Midnight Commander shell color. + typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_FOREGROUND=178 + # Custom icon. + # typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ nix_shell: nix shell (https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html) ]## + # Nix shell color. + typeset -g POWERLEVEL9K_NIX_SHELL_FOREGROUND=74 + + # Tip: If you want to see just the icon without "pure" and "impure", uncomment the next line. + # typeset -g POWERLEVEL9K_NIX_SHELL_CONTENT_EXPANSION= + + # Custom icon. + # typeset -g POWERLEVEL9K_NIX_SHELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##################################[ disk_usage: disk usage ]################################## + # Colors for different levels of disk usage. + typeset -g POWERLEVEL9K_DISK_USAGE_NORMAL_FOREGROUND=35 + typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_FOREGROUND=220 + typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_FOREGROUND=160 + # Thresholds for different levels of disk usage (percentage points). + typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL=90 + typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_LEVEL=95 + # If set to true, hide disk usage when below $POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL percent. + typeset -g POWERLEVEL9K_DISK_USAGE_ONLY_WARNING=false + # Custom icon. + # typeset -g POWERLEVEL9K_DISK_USAGE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################################[ ram: free RAM ]####################################### + # RAM color. + typeset -g POWERLEVEL9K_RAM_FOREGROUND=66 + # Custom icon. + # typeset -g POWERLEVEL9K_RAM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #####################################[ swap: used swap ]###################################### + # Swap color. + typeset -g POWERLEVEL9K_SWAP_FOREGROUND=96 + # Custom icon. + # typeset -g POWERLEVEL9K_SWAP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################################[ load: CPU load ]###################################### + # Show average CPU load over this many last minutes. Valid values are 1, 5 and 15. + typeset -g POWERLEVEL9K_LOAD_WHICH=5 + # Load color when load is under 50%. + typeset -g POWERLEVEL9K_LOAD_NORMAL_FOREGROUND=66 + # Load color when load is between 50% and 70%. + typeset -g POWERLEVEL9K_LOAD_WARNING_FOREGROUND=178 + # Load color when load is over 70%. + typeset -g POWERLEVEL9K_LOAD_CRITICAL_FOREGROUND=166 + # Custom icon. + # typeset -g POWERLEVEL9K_LOAD_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ todo: todo items (https://github.com/todotxt/todo.txt-cli) ]################ + # Todo color. + typeset -g POWERLEVEL9K_TODO_FOREGROUND=110 + # Hide todo when the total number of tasks is zero. + typeset -g POWERLEVEL9K_TODO_HIDE_ZERO_TOTAL=true + # Hide todo when the number of tasks after filtering is zero. + typeset -g POWERLEVEL9K_TODO_HIDE_ZERO_FILTERED=false + + # Todo format. The following parameters are available within the expansion. + # + # - P9K_TODO_TOTAL_TASK_COUNT The total number of tasks. + # - P9K_TODO_FILTERED_TASK_COUNT The number of tasks after filtering. + # + # These variables correspond to the last line of the output of `todo.sh -p ls`: + # + # TODO: 24 of 42 tasks shown + # + # Here 24 is P9K_TODO_FILTERED_TASK_COUNT and 42 is P9K_TODO_TOTAL_TASK_COUNT. + # + # typeset -g POWERLEVEL9K_TODO_CONTENT_EXPANSION='$P9K_TODO_FILTERED_TASK_COUNT' + + # Custom icon. + # typeset -g POWERLEVEL9K_TODO_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ timewarrior: timewarrior tracking status (https://timewarrior.net/) ]############ + # Timewarrior color. + typeset -g POWERLEVEL9K_TIMEWARRIOR_FOREGROUND=110 + # If the tracked task is longer than 24 characters, truncate and append "…". + # Tip: To always display tasks without truncation, delete the following parameter. + # Tip: To hide task names and display just the icon when time tracking is enabled, set the + # value of the following parameter to "". + typeset -g POWERLEVEL9K_TIMEWARRIOR_CONTENT_EXPANSION='${P9K_CONTENT:0:24}${${P9K_CONTENT:24}:+…}' + + # Custom icon. + # typeset -g POWERLEVEL9K_TIMEWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############[ taskwarrior: taskwarrior task count (https://taskwarrior.org/) ]############## + # Taskwarrior color. + typeset -g POWERLEVEL9K_TASKWARRIOR_FOREGROUND=74 + + # Taskwarrior segment format. The following parameters are available within the expansion. + # + # - P9K_TASKWARRIOR_PENDING_COUNT The number of pending tasks: `task +PENDING count`. + # - P9K_TASKWARRIOR_OVERDUE_COUNT The number of overdue tasks: `task +OVERDUE count`. + # + # Zero values are represented as empty parameters. + # + # The default format: + # + # '${P9K_TASKWARRIOR_OVERDUE_COUNT:+"!$P9K_TASKWARRIOR_OVERDUE_COUNT/"}$P9K_TASKWARRIOR_PENDING_COUNT' + # + # typeset -g POWERLEVEL9K_TASKWARRIOR_CONTENT_EXPANSION='$P9K_TASKWARRIOR_PENDING_COUNT' + + # Custom icon. + # typeset -g POWERLEVEL9K_TASKWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##################################[ context: user@hostname ]################################## + # Context color when running with privileges. + typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND=178 + # Context color in SSH without privileges. + typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_FOREGROUND=180 + # Default context color (no privileges, no SSH). + typeset -g POWERLEVEL9K_CONTEXT_FOREGROUND=180 + + # Context format when running with privileges: bold user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE='%B%n@%m' + # Context format when in SSH without privileges: user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_TEMPLATE='%n@%m' + # Default context format (no privileges, no SSH): user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE='%n@%m' + + # Don't show context unless running with privileges or in SSH. + # Tip: Remove the next line to always show context. + typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_{CONTENT,VISUAL_IDENTIFIER}_EXPANSION= + + # Custom icon. + # typeset -g POWERLEVEL9K_CONTEXT_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_CONTEXT_PREFIX='%fwith ' + + ###[ virtualenv: python virtual environment (https://docs.python.org/3/library/venv.html) ]### + # Python virtual environment color. + typeset -g POWERLEVEL9K_VIRTUALENV_FOREGROUND=37 + # Don't show Python version next to the virtual environment name. + typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_PYTHON_VERSION=false + # Don't show virtualenv if pyenv is already shown. + typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_WITH_PYENV=false + # Separate environment name from Python version only with a space. + typeset -g POWERLEVEL9K_VIRTUALENV_{LEFT,RIGHT}_DELIMITER= + # Custom icon. + # typeset -g POWERLEVEL9K_VIRTUALENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #####################[ anaconda: conda environment (https://conda.io/) ]###################### + # Anaconda environment color. + typeset -g POWERLEVEL9K_ANACONDA_FOREGROUND=37 + # Don't show Python version next to the anaconda environment name. + typeset -g POWERLEVEL9K_ANACONDA_SHOW_PYTHON_VERSION=false + # Separate environment name from Python version only with a space. + typeset -g POWERLEVEL9K_ANACONDA_{LEFT,RIGHT}_DELIMITER= + # Custom icon. + # typeset -g POWERLEVEL9K_ANACONDA_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ pyenv: python environment (https://github.com/pyenv/pyenv) ]################ + # Pyenv color. + typeset -g POWERLEVEL9K_PYENV_FOREGROUND=37 + # Hide python version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_PYENV_SOURCES=(shell local global) + # If set to false, hide python version if it's the same as global: + # $(pyenv version-name) == $(pyenv global). + typeset -g POWERLEVEL9K_PYENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide python version if it's equal to "system". + typeset -g POWERLEVEL9K_PYENV_SHOW_SYSTEM=true + + # Pyenv segment format. The following parameters are available within the expansion. + # + # - P9K_CONTENT Current pyenv environment (pyenv version-name). + # - P9K_PYENV_PYTHON_VERSION Current python version (python --version). + # + # The default format has the following logic: + # + # 1. Display "$P9K_CONTENT $P9K_PYENV_PYTHON_VERSION" if $P9K_PYENV_PYTHON_VERSION is not + # empty and unequal to $P9K_CONTENT. + # 2. Otherwise display just "$P9K_CONTENT". + typeset -g POWERLEVEL9K_PYENV_CONTENT_EXPANSION='${P9K_CONTENT}${${P9K_PYENV_PYTHON_VERSION:#$P9K_CONTENT}:+ $P9K_PYENV_PYTHON_VERSION}' + + # Custom icon. + # typeset -g POWERLEVEL9K_PYENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ goenv: go environment (https://github.com/syndbg/goenv) ]################ + # Goenv color. + typeset -g POWERLEVEL9K_GOENV_FOREGROUND=37 + # Hide go version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_GOENV_SOURCES=(shell local global) + # If set to false, hide go version if it's the same as global: + # $(goenv version-name) == $(goenv global). + typeset -g POWERLEVEL9K_GOENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide go version if it's equal to "system". + typeset -g POWERLEVEL9K_GOENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_GOENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ nodenv: node.js version from nodenv (https://github.com/nodenv/nodenv) ]########## + # Nodenv color. + typeset -g POWERLEVEL9K_NODENV_FOREGROUND=70 + # Hide node version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_NODENV_SOURCES=(shell local global) + # If set to false, hide node version if it's the same as global: + # $(nodenv version-name) == $(nodenv global). + typeset -g POWERLEVEL9K_NODENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide node version if it's equal to "system". + typeset -g POWERLEVEL9K_NODENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_NODENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############[ nvm: node.js version from nvm (https://github.com/nvm-sh/nvm) ]############### + # Nvm color. + typeset -g POWERLEVEL9K_NVM_FOREGROUND=70 + # Custom icon. + # typeset -g POWERLEVEL9K_NVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ############[ nodeenv: node.js environment (https://github.com/ekalinin/nodeenv) ]############ + # Nodeenv color. + typeset -g POWERLEVEL9K_NODEENV_FOREGROUND=70 + # Don't show Node version next to the environment name. + typeset -g POWERLEVEL9K_NODEENV_SHOW_NODE_VERSION=false + # Separate environment name from Node version only with a space. + typeset -g POWERLEVEL9K_NODEENV_{LEFT,RIGHT}_DELIMITER= + # Custom icon. + # typeset -g POWERLEVEL9K_NODEENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############################[ node_version: node.js version ]############################### + # Node version color. + typeset -g POWERLEVEL9K_NODE_VERSION_FOREGROUND=70 + # Show node version only when in a directory tree containing package.json. + typeset -g POWERLEVEL9K_NODE_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_NODE_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ go_version: go version (https://golang.org) ]######################## + # Go version color. + typeset -g POWERLEVEL9K_GO_VERSION_FOREGROUND=37 + # Show go version only when in a go project subdirectory. + typeset -g POWERLEVEL9K_GO_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_GO_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #################[ rust_version: rustc version (https://www.rust-lang.org) ]################## + # Rust version color. + typeset -g POWERLEVEL9K_RUST_VERSION_FOREGROUND=37 + # Show rust version only when in a rust project subdirectory. + typeset -g POWERLEVEL9K_RUST_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_RUST_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ dotnet_version: .NET version (https://dotnet.microsoft.com) ]################ + # .NET version color. + typeset -g POWERLEVEL9K_DOTNET_VERSION_FOREGROUND=134 + # Show .NET version only when in a .NET project subdirectory. + typeset -g POWERLEVEL9K_DOTNET_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_DOTNET_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #####################[ php_version: php version (https://www.php.net/) ]###################### + # PHP version color. + typeset -g POWERLEVEL9K_PHP_VERSION_FOREGROUND=99 + # Show PHP version only when in a PHP project subdirectory. + typeset -g POWERLEVEL9K_PHP_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_PHP_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ laravel_version: laravel php framework version (https://laravel.com/) ]########### + # Laravel version color. + typeset -g POWERLEVEL9K_LARAVEL_VERSION_FOREGROUND=161 + # Custom icon. + # typeset -g POWERLEVEL9K_LARAVEL_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ####################[ java_version: java version (https://www.java.com/) ]#################### + # Java version color. + typeset -g POWERLEVEL9K_JAVA_VERSION_FOREGROUND=32 + # Show java version only when in a java project subdirectory. + typeset -g POWERLEVEL9K_JAVA_VERSION_PROJECT_ONLY=true + # Show brief version. + typeset -g POWERLEVEL9K_JAVA_VERSION_FULL=false + # Custom icon. + # typeset -g POWERLEVEL9K_JAVA_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###[ package: name@version from package.json (https://docs.npmjs.com/files/package.json) ]#### + # Package color. + typeset -g POWERLEVEL9K_PACKAGE_FOREGROUND=117 + # Package format. The following parameters are available within the expansion. + # + # - P9K_PACKAGE_NAME The value of `name` field in package.json. + # - P9K_PACKAGE_VERSION The value of `version` field in package.json. + # + # typeset -g POWERLEVEL9K_PACKAGE_CONTENT_EXPANSION='${P9K_PACKAGE_NAME//\%/%%}@${P9K_PACKAGE_VERSION//\%/%%}' + # Custom icon. + # typeset -g POWERLEVEL9K_PACKAGE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #############[ rbenv: ruby version from rbenv (https://github.com/rbenv/rbenv) ]############## + # Rbenv color. + typeset -g POWERLEVEL9K_RBENV_FOREGROUND=168 + # Hide ruby version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_RBENV_SOURCES=(shell local global) + # If set to false, hide ruby version if it's the same as global: + # $(rbenv version-name) == $(rbenv global). + typeset -g POWERLEVEL9K_RBENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide ruby version if it's equal to "system". + typeset -g POWERLEVEL9K_RBENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_RBENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ rvm: ruby version from rvm (https://rvm.io) ]######################## + # Rvm color. + typeset -g POWERLEVEL9K_RVM_FOREGROUND=168 + # Don't show @gemset at the end. + typeset -g POWERLEVEL9K_RVM_SHOW_GEMSET=false + # Don't show ruby- at the front. + typeset -g POWERLEVEL9K_RVM_SHOW_PREFIX=false + # Custom icon. + # typeset -g POWERLEVEL9K_RVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ fvm: flutter version management (https://github.com/leoafarias/fvm) ]############ + # Fvm color. + typeset -g POWERLEVEL9K_FVM_FOREGROUND=38 + # Custom icon. + # typeset -g POWERLEVEL9K_FVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ luaenv: lua version from luaenv (https://github.com/cehoffman/luaenv) ]########### + # Lua color. + typeset -g POWERLEVEL9K_LUAENV_FOREGROUND=32 + # Hide lua version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_LUAENV_SOURCES=(shell local global) + # If set to false, hide lua version if it's the same as global: + # $(luaenv version-name) == $(luaenv global). + typeset -g POWERLEVEL9K_LUAENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide lua version if it's equal to "system". + typeset -g POWERLEVEL9K_LUAENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_LUAENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ jenv: java version from jenv (https://github.com/jenv/jenv) ]################ + # Java color. + typeset -g POWERLEVEL9K_JENV_FOREGROUND=32 + # Hide java version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_JENV_SOURCES=(shell local global) + # If set to false, hide java version if it's the same as global: + # $(jenv version-name) == $(jenv global). + typeset -g POWERLEVEL9K_JENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide java version if it's equal to "system". + typeset -g POWERLEVEL9K_JENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_JENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ plenv: perl version from plenv (https://github.com/tokuhirom/plenv) ]############ + # Perl color. + typeset -g POWERLEVEL9K_PLENV_FOREGROUND=67 + # Hide perl version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_PLENV_SOURCES=(shell local global) + # If set to false, hide perl version if it's the same as global: + # $(plenv version-name) == $(plenv global). + typeset -g POWERLEVEL9K_PLENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide perl version if it's equal to "system". + typeset -g POWERLEVEL9K_PLENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_PLENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ############[ phpenv: php version from phpenv (https://github.com/phpenv/phpenv) ]############ + # PHP color. + typeset -g POWERLEVEL9K_PHPENV_FOREGROUND=99 + # Hide php version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_PHPENV_SOURCES=(shell local global) + # If set to false, hide php version if it's the same as global: + # $(phpenv version-name) == $(phpenv global). + typeset -g POWERLEVEL9K_PHPENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide php version if it's equal to "system". + typeset -g POWERLEVEL9K_PHPENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_PHPENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ haskell_stack: haskell version from stack (https://haskellstack.org/) ]########### + # Haskell color. + typeset -g POWERLEVEL9K_HASKELL_STACK_FOREGROUND=172 + # Hide haskell version if it doesn't come from one of these sources. + # + # shell: version is set by STACK_YAML + # local: version is set by stack.yaml up the directory tree + # global: version is set by the implicit global project (~/.stack/global-project/stack.yaml) + typeset -g POWERLEVEL9K_HASKELL_STACK_SOURCES=(shell local) + # If set to false, hide haskell version if it's the same as in the implicit global project. + typeset -g POWERLEVEL9K_HASKELL_STACK_ALWAYS_SHOW=true + # Custom icon. + # typeset -g POWERLEVEL9K_HASKELL_STACK_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #############[ kubecontext: current kubernetes context (https://kubernetes.io/) ]############# + # Show kubecontext only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show kubecontext. + typeset -g POWERLEVEL9K_KUBECONTEXT_SHOW_ON_COMMAND='kubectl|helm|kubens|kubectx|oc|istioctl|kogito' + + # Kubernetes context classes for the purpose of using different colors, icons and expansions with + # different contexts. + # + # POWERLEVEL9K_KUBECONTEXT_CLASSES is an array with even number of elements. The first element + # in each pair defines a pattern against which the current kubernetes context gets matched. + # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below) + # that gets matched. If you unset all POWERLEVEL9K_KUBECONTEXT_*CONTENT_EXPANSION parameters, + # you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_KUBECONTEXT_CLASSES defines the context class. Patterns are tried in order. The + # first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=( + # '*prod*' PROD + # '*test*' TEST + # '*' DEFAULT) + # + # If your current kubernetes context is "deathray-testing/default", its class is TEST + # because "deathray-testing/default" doesn't match the pattern '*prod*' but does match '*test*'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_FOREGROUND=28 + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' + typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=( + # '*prod*' PROD # These values are examples that are unlikely + # '*test*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_FOREGROUND=134 + # typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Use POWERLEVEL9K_KUBECONTEXT_CONTENT_EXPANSION to specify the content displayed by kubecontext + # segment. Parameter expansions are very flexible and fast, too. See reference: + # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion. + # + # Within the expansion the following parameters are always available: + # + # - P9K_CONTENT The content that would've been displayed if there was no content + # expansion defined. + # - P9K_KUBECONTEXT_NAME The current context's name. Corresponds to column NAME in the + # output of `kubectl config get-contexts`. + # - P9K_KUBECONTEXT_CLUSTER The current context's cluster. Corresponds to column CLUSTER in the + # output of `kubectl config get-contexts`. + # - P9K_KUBECONTEXT_NAMESPACE The current context's namespace. Corresponds to column NAMESPACE + # in the output of `kubectl config get-contexts`. If there is no + # namespace, the parameter is set to "default". + # - P9K_KUBECONTEXT_USER The current context's user. Corresponds to column AUTHINFO in the + # output of `kubectl config get-contexts`. + # + # If the context points to Google Kubernetes Engine (GKE) or Elastic Kubernetes Service (EKS), + # the following extra parameters are available: + # + # - P9K_KUBECONTEXT_CLOUD_NAME Either "gke" or "eks". + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT Account/project ID. + # - P9K_KUBECONTEXT_CLOUD_ZONE Availability zone. + # - P9K_KUBECONTEXT_CLOUD_CLUSTER Cluster. + # + # P9K_KUBECONTEXT_CLOUD_* parameters are derived from P9K_KUBECONTEXT_CLUSTER. For example, + # if P9K_KUBECONTEXT_CLUSTER is "gke_my-account_us-east1-a_my-cluster-01": + # + # - P9K_KUBECONTEXT_CLOUD_NAME=gke + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=my-account + # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east1-a + # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01 + # + # If P9K_KUBECONTEXT_CLUSTER is "arn:aws:eks:us-east-1:123456789012:cluster/my-cluster-01": + # + # - P9K_KUBECONTEXT_CLOUD_NAME=eks + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=123456789012 + # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east-1 + # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01 + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION= + # Show P9K_KUBECONTEXT_CLOUD_CLUSTER if it's not empty and fall back to P9K_KUBECONTEXT_NAME. + POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${P9K_KUBECONTEXT_CLOUD_CLUSTER:-${P9K_KUBECONTEXT_NAME}}' + # Append the current context's namespace if it's not "default". + POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${${:-/$P9K_KUBECONTEXT_NAMESPACE}:#/default}' + + # Custom prefix. + # typeset -g POWERLEVEL9K_KUBECONTEXT_PREFIX='%fat ' + + ################[ terraform: terraform workspace (https://www.terraform.io) ]################# + # POWERLEVEL9K_TERRAFORM_CLASSES is an array with even number of elements. The first element + # in each pair defines a pattern against which the current terraform workspace gets matched. + # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below) + # that gets matched. If you unset all POWERLEVEL9K_TERRAFORM_*CONTENT_EXPANSION parameters, + # you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_TERRAFORM_CLASSES defines the workspace class. Patterns are tried in order. The + # first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_TERRAFORM_CLASSES=( + # '*prod*' PROD + # '*test*' TEST + # '*' DEFAULT) + # + # If your current terraform workspace is "project_test", its class is TEST because "project_test" + # doesn't match the pattern '*prod*' but does match '*test*'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_FOREGROUND=28 + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' + typeset -g POWERLEVEL9K_TERRAFORM_CLASSES=( + # '*prod*' PROD # These values are examples that are unlikely + # '*test*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_TERRAFORM_DEFAULT_FOREGROUND=38 + # typeset -g POWERLEVEL9K_TERRAFORM_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ aws: aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) ]# + # Show aws only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show aws. + typeset -g POWERLEVEL9K_AWS_SHOW_ON_COMMAND='aws|awless|terraform|pulumi' + + # POWERLEVEL9K_AWS_CLASSES is an array with even number of elements. The first element + # in each pair defines a pattern against which the current AWS profile gets matched. + # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below) + # that gets matched. If you unset all POWERLEVEL9K_AWS_*CONTENT_EXPANSION parameters, + # you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_AWS_CLASSES defines the profile class. Patterns are tried in order. The + # first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_AWS_CLASSES=( + # '*prod*' PROD + # '*test*' TEST + # '*' DEFAULT) + # + # If your current AWS profile is "company_test", its class is TEST + # because "company_test" doesn't match the pattern '*prod*' but does match '*test*'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_AWS_TEST_FOREGROUND=28 + # typeset -g POWERLEVEL9K_AWS_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_AWS_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' + typeset -g POWERLEVEL9K_AWS_CLASSES=( + # '*prod*' PROD # These values are examples that are unlikely + # '*test*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_AWS_DEFAULT_FOREGROUND=208 + # typeset -g POWERLEVEL9K_AWS_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ aws_eb_env: aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) ]# + # AWS Elastic Beanstalk environment color. + typeset -g POWERLEVEL9K_AWS_EB_ENV_FOREGROUND=70 + # Custom icon. + # typeset -g POWERLEVEL9K_AWS_EB_ENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ azure: azure account name (https://docs.microsoft.com/en-us/cli/azure) ]########## + # Show azure only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show azure. + typeset -g POWERLEVEL9K_AZURE_SHOW_ON_COMMAND='az|terraform|pulumi' + # Azure account name color. + typeset -g POWERLEVEL9K_AZURE_FOREGROUND=32 + # Custom icon. + # typeset -g POWERLEVEL9K_AZURE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ gcloud: google cloud account and project (https://cloud.google.com/) ]########### + # Show gcloud only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show gcloud. + typeset -g POWERLEVEL9K_GCLOUD_SHOW_ON_COMMAND='gcloud|gcs' + # Google cloud color. + typeset -g POWERLEVEL9K_GCLOUD_FOREGROUND=32 + + # Google cloud format. Change the value of POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION and/or + # POWERLEVEL9K_GCLOUD_COMPLETE_CONTENT_EXPANSION if the default is too verbose or not informative + # enough. You can use the following parameters in the expansions. Each of them corresponds to the + # output of `gcloud` tool. + # + # Parameter | Source + # -------------------------|-------------------------------------------------------------------- + # P9K_GCLOUD_CONFIGURATION | gcloud config configurations list --format='value(name)' + # P9K_GCLOUD_ACCOUNT | gcloud config get-value account + # P9K_GCLOUD_PROJECT_ID | gcloud config get-value project + # P9K_GCLOUD_PROJECT_NAME | gcloud projects describe $P9K_GCLOUD_PROJECT_ID --format='value(name)' + # + # Note: ${VARIABLE//\%/%%} expands to ${VARIABLE} with all occurences of '%' replaced with '%%'. + # + # Obtaining project name requires sending a request to Google servers. This can take a long time + # and even fail. When project name is unknown, P9K_GCLOUD_PROJECT_NAME is not set and gcloud + # prompt segment is in state PARTIAL. When project name gets known, P9K_GCLOUD_PROJECT_NAME gets + # set and gcloud prompt segment transitions to state COMPLETE. + # + # You can customize the format, icon and colors of gcloud segment separately for states PARTIAL + # and COMPLETE. You can also hide gcloud in state PARTIAL by setting + # POWERLEVEL9K_GCLOUD_PARTIAL_VISUAL_IDENTIFIER_EXPANSION and + # POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION to empty. + typeset -g POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION='${P9K_GCLOUD_PROJECT_ID//\%/%%}' + typeset -g POWERLEVEL9K_GCLOUD_COMPLETE_CONTENT_EXPANSION='${P9K_GCLOUD_PROJECT_NAME//\%/%%}' + + # Send a request to Google (by means of `gcloud projects describe ...`) to obtain project name + # this often. Negative value disables periodic polling. In this mode project name is retrieved + # only when the current configuration, account or project id changes. + typeset -g POWERLEVEL9K_GCLOUD_REFRESH_PROJECT_NAME_SECONDS=60 + + # Custom icon. + # typeset -g POWERLEVEL9K_GCLOUD_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ google_app_cred: google application credentials (https://cloud.google.com/docs/authentication/production) ]# + # Show google_app_cred only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show google_app_cred. + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_SHOW_ON_COMMAND='terraform|pulumi' + + # Google application credentials classes for the purpose of using different colors, icons and + # expansions with different credentials. + # + # POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES is an array with even number of elements. The first + # element in each pair defines a pattern against which the current kubernetes context gets + # matched. More specifically, it's P9K_CONTENT prior to the application of context expansion + # (see below) that gets matched. If you unset all POWERLEVEL9K_GOOGLE_APP_CRED_*CONTENT_EXPANSION + # parameters, you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES defines the context class. Patterns are tried in order. + # The first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES=( + # '*:*prod*:*' PROD + # '*:*test*:*' TEST + # '*' DEFAULT) + # + # If your current Google application credentials is "service_account deathray-testing x@y.com", + # its class is TEST because it doesn't match the pattern '* *prod* *' but does match '* *test* *'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_FOREGROUND=28 + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_CONTENT_EXPANSION='$P9K_GOOGLE_APP_CRED_PROJECT_ID' + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES=( + # '*:*prod*:*' PROD # These values are examples that are unlikely + # '*:*test*:*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_FOREGROUND=32 + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Use POWERLEVEL9K_GOOGLE_APP_CRED_CONTENT_EXPANSION to specify the content displayed by + # google_app_cred segment. Parameter expansions are very flexible and fast, too. See reference: + # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion. + # + # You can use the following parameters in the expansion. Each of them corresponds to one of the + # fields in the JSON file pointed to by GOOGLE_APPLICATION_CREDENTIALS. + # + # Parameter | JSON key file field + # ---------------------------------+--------------- + # P9K_GOOGLE_APP_CRED_TYPE | type + # P9K_GOOGLE_APP_CRED_PROJECT_ID | project_id + # P9K_GOOGLE_APP_CRED_CLIENT_EMAIL | client_email + # + # Note: ${VARIABLE//\%/%%} expands to ${VARIABLE} with all occurences of '%' replaced by '%%'. + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_CONTENT_EXPANSION='${P9K_GOOGLE_APP_CRED_PROJECT_ID//\%/%%}' + + ###############################[ public_ip: public IP address ]############################### + # Public IP color. + typeset -g POWERLEVEL9K_PUBLIC_IP_FOREGROUND=94 + # Custom icon. + # typeset -g POWERLEVEL9K_PUBLIC_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ########################[ vpn_ip: virtual private network indicator ]######################### + # VPN IP color. + typeset -g POWERLEVEL9K_VPN_IP_FOREGROUND=81 + # When on VPN, show just an icon without the IP address. + # Tip: To display the private IP address when on VPN, remove the next line. + typeset -g POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION= + # Regular expression for the VPN network interface. Run `ifconfig` or `ip -4 a show` while on VPN + # to see the name of the interface. + typeset -g POWERLEVEL9K_VPN_IP_INTERFACE='(wg|(.*tun))[0-9]*' + # If set to true, show one segment per matching network interface. If set to false, show only + # one segment corresponding to the first matching network interface. + # Tip: If you set it to true, you'll probably want to unset POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION. + typeset -g POWERLEVEL9K_VPN_IP_SHOW_ALL=false + # Custom icon. + # typeset -g POWERLEVEL9K_VPN_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ ip: ip address and bandwidth usage for a specified network interface ]########### + # IP color. + typeset -g POWERLEVEL9K_IP_FOREGROUND=38 + # The following parameters are accessible within the expansion: + # + # Parameter | Meaning + # ----------------------+--------------- + # P9K_IP_IP | IP address + # P9K_IP_INTERFACE | network interface + # P9K_IP_RX_BYTES | total number of bytes received + # P9K_IP_TX_BYTES | total number of bytes sent + # P9K_IP_RX_RATE | receive rate (since last prompt) + # P9K_IP_TX_RATE | send rate (since last prompt) + typeset -g POWERLEVEL9K_IP_CONTENT_EXPANSION='$P9K_IP_IP${P9K_IP_RX_RATE:+ %70F⇣$P9K_IP_RX_RATE}${P9K_IP_TX_RATE:+ %215F⇡$P9K_IP_TX_RATE}' + # Show information for the first network interface whose name matches this regular expression. + # Run `ifconfig` or `ip -4 a show` to see the names of all network interfaces. + typeset -g POWERLEVEL9K_IP_INTERFACE='e.*' + # Custom icon. + # typeset -g POWERLEVEL9K_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #########################[ proxy: system-wide http/https/ftp proxy ]########################## + # Proxy color. + typeset -g POWERLEVEL9K_PROXY_FOREGROUND=68 + # Custom icon. + # typeset -g POWERLEVEL9K_PROXY_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################################[ battery: internal battery ]################################# + # Show battery in red when it's below this level and not connected to power supply. + typeset -g POWERLEVEL9K_BATTERY_LOW_THRESHOLD=20 + typeset -g POWERLEVEL9K_BATTERY_LOW_FOREGROUND=160 + # Show battery in green when it's charging or fully charged. + typeset -g POWERLEVEL9K_BATTERY_{CHARGING,CHARGED}_FOREGROUND=70 + # Show battery in yellow when it's discharging. + typeset -g POWERLEVEL9K_BATTERY_DISCONNECTED_FOREGROUND=178 + # Battery pictograms going from low to high level of charge. + typeset -g POWERLEVEL9K_BATTERY_STAGES=('%K{232}▁' '%K{232}▂' '%K{232}▃' '%K{232}▄' '%K{232}▅' '%K{232}▆' '%K{232}▇' '%K{232}█') + # Don't show the remaining time to charge/discharge. + typeset -g POWERLEVEL9K_BATTERY_VERBOSE=false + + #####################################[ wifi: wifi speed ]##################################### + # WiFi color. + typeset -g POWERLEVEL9K_WIFI_FOREGROUND=68 + # Custom icon. + # typeset -g POWERLEVEL9K_WIFI_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Use different colors and icons depending on signal strength ($P9K_WIFI_BARS). + # + # # Wifi colors and icons for different signal strength levels (low to high). + # typeset -g my_wifi_fg=(68 68 68 68 68) # <-- change these values + # typeset -g my_wifi_icon=('WiFi' 'WiFi' 'WiFi' 'WiFi' 'WiFi') # <-- change these values + # + # typeset -g POWERLEVEL9K_WIFI_CONTENT_EXPANSION='%F{${my_wifi_fg[P9K_WIFI_BARS+1]}}$P9K_WIFI_LAST_TX_RATE Mbps' + # typeset -g POWERLEVEL9K_WIFI_VISUAL_IDENTIFIER_EXPANSION='%F{${my_wifi_fg[P9K_WIFI_BARS+1]}}${my_wifi_icon[P9K_WIFI_BARS+1]}' + # + # The following parameters are accessible within the expansions: + # + # Parameter | Meaning + # ----------------------+--------------- + # P9K_WIFI_SSID | service set identifier, a.k.a. network name + # P9K_WIFI_LINK_AUTH | authentication protocol such as "wpa2-psk" or "none" + # P9K_WIFI_LAST_TX_RATE | wireless transmit rate in megabits per second + # P9K_WIFI_RSSI | signal strength in dBm, from -120 to 0 + # P9K_WIFI_NOISE | noise in dBm, from -120 to 0 + # P9K_WIFI_BARS | signal strength in bars, from 0 to 4 (derived from P9K_WIFI_RSSI and P9K_WIFI_NOISE) + # + # All parameters except P9K_WIFI_BARS are extracted from the output of the following command: + # + # /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I + + ####################################[ time: current time ]#################################### + # Current time color. + typeset -g POWERLEVEL9K_TIME_FOREGROUND=66 + # Format for the current time: 09:51:02. See `man 3 strftime`. + typeset -g POWERLEVEL9K_TIME_FORMAT='%D{%H:%M:%S}' + # If set to true, time will update when you hit enter. This way prompts for the past + # commands will contain the start times of their commands as opposed to the default + # behavior where they contain the end times of their preceding commands. + typeset -g POWERLEVEL9K_TIME_UPDATE_ON_COMMAND=false + # Custom icon. + # typeset -g POWERLEVEL9K_TIME_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_TIME_PREFIX='%fat ' + + # Example of a user-defined prompt segment. Function prompt_example will be called on every + # prompt if `example` prompt segment is added to POWERLEVEL9K_LEFT_PROMPT_ELEMENTS or + # POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS. It displays an icon and orange text greeting the user. + # + # Type `p10k help segment` for documentation and a more sophisticated example. + function prompt_example() { + p10k segment -f 208 -i '⭐' -t 'hello, %n' + } + + # User-defined prompt segments may optionally provide an instant_prompt_* function. Its job + # is to generate the prompt segment for display in instant prompt. See + # https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt. + # + # Powerlevel10k will call instant_prompt_* at the same time as the regular prompt_* function + # and will record all `p10k segment` calls it makes. When displaying instant prompt, Powerlevel10k + # will replay these calls without actually calling instant_prompt_*. It is imperative that + # instant_prompt_* always makes the same `p10k segment` calls regardless of environment. If this + # rule is not observed, the content of instant prompt will be incorrect. + # + # Usually, you should either not define instant_prompt_* or simply call prompt_* from it. If + # instant_prompt_* is not defined for a segment, the segment won't be shown in instant prompt. + function instant_prompt_example() { + # Since prompt_example always makes the same `p10k segment` calls, we can call it from + # instant_prompt_example. This will give us the same `example` prompt segment in the instant + # and regular prompts. + prompt_example + } + + # User-defined prompt segments can be customized the same way as built-in segments. + # typeset -g POWERLEVEL9K_EXAMPLE_FOREGROUND=208 + # typeset -g POWERLEVEL9K_EXAMPLE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Transient prompt works similarly to the builtin transient_rprompt option. It trims down prompt + # when accepting a command line. Supported values: + # + # - off: Don't change prompt when accepting a command line. + # - always: Trim down prompt when accepting a command line. + # - same-dir: Trim down prompt when accepting a command line unless this is the first command + # typed after changing current working directory. + typeset -g POWERLEVEL9K_TRANSIENT_PROMPT=off + + # Instant prompt mode. + # + # - off: Disable instant prompt. Choose this if you've tried instant prompt and found + # it incompatible with your zsh configuration files. + # - quiet: Enable instant prompt and don't print warnings when detecting console output + # during zsh initialization. Choose this if you've read and understood + # https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt. + # - verbose: Enable instant prompt and print a warning when detecting console output during + # zsh initialization. Choose this if you've never tried instant prompt, haven't + # seen the warning, or if you are unsure what this all means. + typeset -g POWERLEVEL9K_INSTANT_PROMPT=verbose + + # Hot reload allows you to change POWERLEVEL9K options after Powerlevel10k has been initialized. + # For example, you can type POWERLEVEL9K_BACKGROUND=red and see your prompt turn red. Hot reload + # can slow down prompt by 1-2 milliseconds, so it's better to keep it turned off unless you + # really need it. + typeset -g POWERLEVEL9K_DISABLE_HOT_RELOAD=true + + # If p10k is already loaded, reload configuration. + # This works even with POWERLEVEL9K_DISABLE_HOT_RELOAD=true. + (( ! $+functions[p10k] )) || p10k reload +} + +# Tell `p10k configure` which file it should overwrite. +typeset -g POWERLEVEL9K_CONFIG_FILE=${${(%):-%x}:a} + +(( ${#p10k_config_opts} )) && setopt ${p10k_config_opts[@]} +'builtin' 'unset' 'p10k_config_opts' diff --git a/config/p10k-pure.zsh b/config/p10k-pure.zsh new file mode 100644 index 00000000..2ab4369f --- /dev/null +++ b/config/p10k-pure.zsh @@ -0,0 +1,193 @@ +# Config file for Powerlevel10k with the style of Pure (https://github.com/sindresorhus/pure). +# +# Differences from Pure: +# +# - Git: +# - `@c4d3ec2c` instead of something like `v1.4.0~11` when in detached HEAD state. +# - No automatic `git fetch` (the same as in Pure with `PURE_GIT_PULL=0`). +# +# Apart from the differences listed above, the replication of Pure prompt is exact. This includes +# even the questionable parts. For example, just like in Pure, there is no indication of Git status +# being stale; prompt symbol is the same in command, visual and overwrite vi modes; when prompt +# doesn't fit on one line, it wraps around with no attempt to shorten it. +# +# If you like the general style of Pure but not particularly attached to all its quirks, type +# `p10k configure` and pick "Lean" style. This will give you slick minimalist prompt while taking +# advantage of Powerlevel10k features that aren't present in Pure. + +# Temporarily change options. +'builtin' 'local' '-a' 'p10k_config_opts' +[[ ! -o 'aliases' ]] || p10k_config_opts+=('aliases') +[[ ! -o 'sh_glob' ]] || p10k_config_opts+=('sh_glob') +[[ ! -o 'no_brace_expand' ]] || p10k_config_opts+=('no_brace_expand') +'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand' + +() { + emulate -L zsh + + # Unset all configuration options. + unset -m 'POWERLEVEL9K_*|DEFAULT_USER' + + # Zsh >= 5.1 is required. + autoload -Uz is-at-least && is-at-least 5.1 || return + + # Prompt colors. + local grey=242 + local red=1 + local yellow=3 + local blue=4 + local magenta=5 + local cyan=6 + local white=7 + + # Left prompt segments. + typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=( + # =========================[ Line #1 ]========================= + context # user@host + dir # current directory + vcs # git status + command_execution_time # previous command duration + # =========================[ Line #2 ]========================= + newline # \n + virtualenv # python virtual environment + prompt_char # prompt symbol + ) + + # Right prompt segments. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=( + # =========================[ Line #1 ]========================= + # command_execution_time # previous command duration + # virtualenv # python virtual environment + # context # user@host + # time # current time + # =========================[ Line #2 ]========================= + newline # \n + ) + + # Basic style options that define the overall prompt look. + typeset -g POWERLEVEL9K_BACKGROUND= # transparent background + typeset -g POWERLEVEL9K_{LEFT,RIGHT}_{LEFT,RIGHT}_WHITESPACE= # no surrounding whitespace + typeset -g POWERLEVEL9K_{LEFT,RIGHT}_SUBSEGMENT_SEPARATOR=' ' # separate segments with a space + typeset -g POWERLEVEL9K_{LEFT,RIGHT}_SEGMENT_SEPARATOR= # no end-of-line symbol + typeset -g POWERLEVEL9K_VISUAL_IDENTIFIER_EXPANSION= # no segment icons + + # Add an empty line before each prompt except the first. This doesn't emulate the bug + # in Pure that makes prompt drift down whenever you use the Alt-C binding from fzf or similar. + typeset -g POWERLEVEL9K_PROMPT_ADD_NEWLINE=true + + # Magenta prompt symbol if the last command succeeded. + typeset -g POWERLEVEL9K_PROMPT_CHAR_OK_{VIINS,VICMD,VIVIS}_FOREGROUND=$magenta + # Red prompt symbol if the last command failed. + typeset -g POWERLEVEL9K_PROMPT_CHAR_ERROR_{VIINS,VICMD,VIVIS}_FOREGROUND=$red + # Default prompt symbol. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIINS_CONTENT_EXPANSION='❯' + # Prompt symbol in command vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VICMD_CONTENT_EXPANSION='❮' + # Prompt symbol in visual vi mode is the same as in command mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIVIS_CONTENT_EXPANSION='❮' + # Prompt symbol in overwrite vi mode is the same as in command mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE=false + + # Grey Python Virtual Environment. + typeset -g POWERLEVEL9K_VIRTUALENV_FOREGROUND=$grey + # Don't show Python version. + typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_PYTHON_VERSION=false + typeset -g POWERLEVEL9K_VIRTUALENV_{LEFT,RIGHT}_DELIMITER= + + # Blue current directory. + typeset -g POWERLEVEL9K_DIR_FOREGROUND=$blue + + # Context format when root: user@host. The first part white, the rest grey. + typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE="%F{$white}%n%f%F{$grey}@%m%f" + # Context format when not root: user@host. The whole thing grey. + typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE="%F{$grey}%n@%m%f" + # Don't show context unless root or in SSH. + typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_CONTENT_EXPANSION= + + # Show previous command duration only if it's >= 5s. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=5 + # Don't show fractional seconds. Thus, 7s rather than 7.3s. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PRECISION=0 + # Duration format: 1d 2h 3m 4s. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FORMAT='d h m s' + # Yellow previous command duration. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FOREGROUND=$yellow + + # Grey Git prompt. This makes stale prompts indistinguishable from up-to-date ones. + typeset -g POWERLEVEL9K_VCS_FOREGROUND=$grey + + # Disable async loading indicator to make directories that aren't Git repositories + # indistinguishable from large Git repositories without known state. + typeset -g POWERLEVEL9K_VCS_LOADING_TEXT= + + # Don't wait for Git status even for a millisecond, so that prompt always updates + # asynchronously when Git state changes. + typeset -g POWERLEVEL9K_VCS_MAX_SYNC_LATENCY_SECONDS=0 + + # Cyan ahead/behind arrows. + typeset -g POWERLEVEL9K_VCS_{INCOMING,OUTGOING}_CHANGESFORMAT_FOREGROUND=$cyan + # Don't show remote branch, current tag or stashes. + typeset -g POWERLEVEL9K_VCS_GIT_HOOKS=(vcs-detect-changes git-untracked git-aheadbehind) + # Don't show the branch icon. + typeset -g POWERLEVEL9K_VCS_BRANCH_ICON= + # When in detached HEAD state, show @commit where branch normally goes. + typeset -g POWERLEVEL9K_VCS_COMMIT_ICON='@' + # Don't show staged, unstaged, untracked indicators. + typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED}_ICON= + # Show '*' when there are staged, unstaged or untracked files. + typeset -g POWERLEVEL9K_VCS_DIRTY_ICON='*' + # Show '⇣' if local branch is behind remote. + typeset -g POWERLEVEL9K_VCS_INCOMING_CHANGES_ICON=':⇣' + # Show '⇡' if local branch is ahead of remote. + typeset -g POWERLEVEL9K_VCS_OUTGOING_CHANGES_ICON=':⇡' + # Don't show the number of commits next to the ahead/behind arrows. + typeset -g POWERLEVEL9K_VCS_{COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=1 + # Remove space between '⇣' and '⇡' and all trailing spaces. + typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION='${${${P9K_CONTENT/⇣* :⇡/⇣⇡}// }//:/ }' + + # Grey current time. + typeset -g POWERLEVEL9K_TIME_FOREGROUND=$grey + # Format for the current time: 09:51:02. See `man 3 strftime`. + typeset -g POWERLEVEL9K_TIME_FORMAT='%D{%H:%M:%S}' + # If set to true, time will update when you hit enter. This way prompts for the past + # commands will contain the start times of their commands rather than the end times of + # their preceding commands. + typeset -g POWERLEVEL9K_TIME_UPDATE_ON_COMMAND=false + + # Transient prompt works similarly to the builtin transient_rprompt option. It trims down prompt + # when accepting a command line. Supported values: + # + # - off: Don't change prompt when accepting a command line. + # - always: Trim down prompt when accepting a command line. + # - same-dir: Trim down prompt when accepting a command line unless this is the first command + # typed after changing current working directory. + typeset -g POWERLEVEL9K_TRANSIENT_PROMPT=off + + # Instant prompt mode. + # + # - off: Disable instant prompt. Choose this if you've tried instant prompt and found + # it incompatible with your zsh configuration files. + # - quiet: Enable instant prompt and don't print warnings when detecting console output + # during zsh initialization. Choose this if you've read and understood + # https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt. + # - verbose: Enable instant prompt and print a warning when detecting console output during + # zsh initialization. Choose this if you've never tried instant prompt, haven't + # seen the warning, or if you are unsure what this all means. + typeset -g POWERLEVEL9K_INSTANT_PROMPT=verbose + + # Hot reload allows you to change POWERLEVEL9K options after Powerlevel10k has been initialized. + # For example, you can type POWERLEVEL9K_BACKGROUND=red and see your prompt turn red. Hot reload + # can slow down prompt by 1-2 milliseconds, so it's better to keep it turned off unless you + # really need it. + typeset -g POWERLEVEL9K_DISABLE_HOT_RELOAD=true + + # If p10k is already loaded, reload configuration. + # This works even with POWERLEVEL9K_DISABLE_HOT_RELOAD=true. + (( ! $+functions[p10k] )) || p10k reload +} + +# Tell `p10k configure` which file it should overwrite. +typeset -g POWERLEVEL9K_CONFIG_FILE=${${(%):-%x}:a} + +(( ${#p10k_config_opts} )) && setopt ${p10k_config_opts[@]} +'builtin' 'unset' 'p10k_config_opts' diff --git a/config/p10k-rainbow.zsh b/config/p10k-rainbow.zsh new file mode 100644 index 00000000..2d8c751f --- /dev/null +++ b/config/p10k-rainbow.zsh @@ -0,0 +1,1609 @@ +# Config for Powerlevel10k with powerline prompt style with colorful background. +# Type `p10k configure` to generate your own config based on it. +# +# Tip: Looking for a nice color? Here's a one-liner to print colormap. +# +# for i in {0..255}; do print -Pn "%K{$i} %k%F{$i}${(l:3::0:)i}%f " ${${(M)$((i%6)):#3}:+$'\n'}; done + +# Temporarily change options. +'builtin' 'local' '-a' 'p10k_config_opts' +[[ ! -o 'aliases' ]] || p10k_config_opts+=('aliases') +[[ ! -o 'sh_glob' ]] || p10k_config_opts+=('sh_glob') +[[ ! -o 'no_brace_expand' ]] || p10k_config_opts+=('no_brace_expand') +'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand' + +() { + emulate -L zsh -o extended_glob + + # Unset all configuration options. This allows you to apply configuration changes without + # restarting zsh. Edit ~/.p10k.zsh and type `source ~/.p10k.zsh`. + unset -m 'POWERLEVEL9K_*|DEFAULT_USER' + + # Zsh >= 5.1 is required. + autoload -Uz is-at-least && is-at-least 5.1 || return + + # The list of segments shown on the left. Fill it with the most important segments. + typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=( + # =========================[ Line #1 ]========================= + # os_icon # os identifier + dir # current directory + vcs # git status + # =========================[ Line #2 ]========================= + newline # \n + # prompt_char # prompt symbol + ) + + # The list of segments shown on the right. Fill it with less important segments. + # Right prompt on the last prompt line (where you are typing your commands) gets + # automatically hidden when the input line reaches it. Right prompt above the + # last prompt line gets hidden if it would overlap with left prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=( + # =========================[ Line #1 ]========================= + status # exit code of the last command + command_execution_time # duration of the last command + background_jobs # presence of background jobs + direnv # direnv status (https://direnv.net/) + asdf # asdf version manager (https://github.com/asdf-vm/asdf) + virtualenv # python virtual environment (https://docs.python.org/3/library/venv.html) + anaconda # conda environment (https://conda.io/) + pyenv # python environment (https://github.com/pyenv/pyenv) + goenv # go environment (https://github.com/syndbg/goenv) + nodenv # node.js version from nodenv (https://github.com/nodenv/nodenv) + nvm # node.js version from nvm (https://github.com/nvm-sh/nvm) + nodeenv # node.js environment (https://github.com/ekalinin/nodeenv) + # node_version # node.js version + # go_version # go version (https://golang.org) + # rust_version # rustc version (https://www.rust-lang.org) + # dotnet_version # .NET version (https://dotnet.microsoft.com) + # php_version # php version (https://www.php.net/) + # laravel_version # laravel php framework version (https://laravel.com/) + # java_version # java version (https://www.java.com/) + # package # name@version from package.json (https://docs.npmjs.com/files/package.json) + rbenv # ruby version from rbenv (https://github.com/rbenv/rbenv) + rvm # ruby version from rvm (https://rvm.io) + fvm # flutter version management (https://github.com/leoafarias/fvm) + luaenv # lua version from luaenv (https://github.com/cehoffman/luaenv) + jenv # java version from jenv (https://github.com/jenv/jenv) + plenv # perl version from plenv (https://github.com/tokuhirom/plenv) + phpenv # php version from phpenv (https://github.com/phpenv/phpenv) + haskell_stack # haskell version from stack (https://haskellstack.org/) + kubecontext # current kubernetes context (https://kubernetes.io/) + terraform # terraform workspace (https://www.terraform.io) + aws # aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) + aws_eb_env # aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) + azure # azure account name (https://docs.microsoft.com/en-us/cli/azure) + gcloud # google cloud cli account and project (https://cloud.google.com/) + google_app_cred # google application credentials (https://cloud.google.com/docs/authentication/production) + context # user@hostname + nordvpn # nordvpn connection status, linux only (https://nordvpn.com/) + ranger # ranger shell (https://github.com/ranger/ranger) + nnn # nnn shell (https://github.com/jarun/nnn) + vim_shell # vim shell indicator (:sh) + midnight_commander # midnight commander shell (https://midnight-commander.org/) + nix_shell # nix shell (https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html) + # vi_mode # vi mode (you don't need this if you've enabled prompt_char) + # vpn_ip # virtual private network indicator + # load # CPU load + # disk_usage # disk usage + # ram # free RAM + # swap # used swap + todo # todo items (https://github.com/todotxt/todo.txt-cli) + timewarrior # timewarrior tracking status (https://timewarrior.net/) + taskwarrior # taskwarrior task count (https://taskwarrior.org/) + # time # current time + # =========================[ Line #2 ]========================= + newline + # ip # ip address and bandwidth usage for a specified network interface + # public_ip # public IP address + # proxy # system-wide http/https/ftp proxy + # battery # internal battery + # wifi # wifi speed + # example # example user-defined segment (see prompt_example function below) + ) + + # Defines character set used by powerlevel10k. It's best to let `p10k configure` set it for you. + typeset -g POWERLEVEL9K_MODE=nerdfont-complete + # When set to `moderate`, some icons will have an extra space after them. This is meant to avoid + # icon overlap when using non-monospace fonts. When set to `none`, spaces are not added. + typeset -g POWERLEVEL9K_ICON_PADDING=none + + # When set to true, icons appear before content on both sides of the prompt. When set + # to false, icons go after content. If empty or not set, icons go before content in the left + # prompt and after content in the right prompt. + # + # You can also override it for a specific segment: + # + # POWERLEVEL9K_STATUS_ICON_BEFORE_CONTENT=false + # + # Or for a specific segment in specific state: + # + # POWERLEVEL9K_DIR_NOT_WRITABLE_ICON_BEFORE_CONTENT=false + typeset -g POWERLEVEL9K_ICON_BEFORE_CONTENT= + + # Add an empty line before each prompt. + typeset -g POWERLEVEL9K_PROMPT_ADD_NEWLINE=true + + # Connect left prompt lines with these symbols. You'll probably want to use the same color + # as POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_FOREGROUND below. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX='%242F╭─' + typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_PREFIX='%242F├─' + typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX='%242F╰─' + # Connect right prompt lines with these symbols. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_SUFFIX='%242F─╮' + typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_SUFFIX='%242F─┤' + typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_SUFFIX='%242F─╯' + + # Filler between left and right prompt on the first prompt line. You can set it to ' ', '·' or + # '─'. The last two make it easier to see the alignment between left and right prompt and to + # separate prompt from command output. You might want to set POWERLEVEL9K_PROMPT_ADD_NEWLINE=false + # for more compact prompt if using using this option. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR=' ' + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_BACKGROUND= + typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_GAP_BACKGROUND= + if [[ $POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR != ' ' ]]; then + # The color of the filler. You'll probably want to match the color of POWERLEVEL9K_MULTILINE + # ornaments defined above. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_FOREGROUND=242 + # Start filler from the edge of the screen if there are no left segments on the first line. + typeset -g POWERLEVEL9K_EMPTY_LINE_LEFT_PROMPT_FIRST_SEGMENT_END_SYMBOL='%{%}' + # End filler on the edge of the screen if there are no right segments on the first line. + typeset -g POWERLEVEL9K_EMPTY_LINE_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL='%{%}' + fi + + # Separator between same-color segments on the left. + typeset -g POWERLEVEL9K_LEFT_SUBSEGMENT_SEPARATOR='\uE0B1' + # Separator between same-color segments on the right. + typeset -g POWERLEVEL9K_RIGHT_SUBSEGMENT_SEPARATOR='\uE0B3' + # Separator between different-color segments on the left. + typeset -g POWERLEVEL9K_LEFT_SEGMENT_SEPARATOR='\uE0B0' + # Separator between different-color segments on the right. + typeset -g POWERLEVEL9K_RIGHT_SEGMENT_SEPARATOR='\uE0B2' + # The right end of left prompt. + typeset -g POWERLEVEL9K_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL='\uE0B0' + # The left end of right prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL='\uE0B2' + # The left end of left prompt. + typeset -g POWERLEVEL9K_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL= + # The right end of right prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL= + # Left prompt terminator for lines without any segments. + typeset -g POWERLEVEL9K_EMPTY_LINE_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL= + + #################################[ os_icon: os identifier ]################################## + # OS identifier color. + typeset -g POWERLEVEL9K_OS_ICON_FOREGROUND=232 + typeset -g POWERLEVEL9K_OS_ICON_BACKGROUND=7 + # Custom icon. + # typeset -g POWERLEVEL9K_OS_ICON_CONTENT_EXPANSION='⭐' + + ################################[ prompt_char: prompt symbol ]################################ + # Transparent background. + typeset -g POWERLEVEL9K_PROMPT_CHAR_BACKGROUND= + # Green prompt symbol if the last command succeeded. + typeset -g POWERLEVEL9K_PROMPT_CHAR_OK_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=76 + # Red prompt symbol if the last command failed. + typeset -g POWERLEVEL9K_PROMPT_CHAR_ERROR_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=196 + # Default prompt symbol. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIINS_CONTENT_EXPANSION='❯' + # Prompt symbol in command vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VICMD_CONTENT_EXPANSION='❮' + # Prompt symbol in visual vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIVIS_CONTENT_EXPANSION='Ⅴ' + # Prompt symbol in overwrite vi mode. + typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIOWR_CONTENT_EXPANSION='▶' + typeset -g POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE=true + # No line terminator if prompt_char is the last segment. + typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL= + # No line introducer if prompt_char is the first segment. + typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL= + # No surrounding whitespace. + typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_{LEFT,RIGHT}_WHITESPACE= + + ##################################[ dir: current directory ]################################## + # Current directory background color. + typeset -g POWERLEVEL9K_DIR_BACKGROUND=4 + # Default current directory foreground color. + typeset -g POWERLEVEL9K_DIR_FOREGROUND=254 + # If directory is too long, shorten some of its segments to the shortest possible unique + # prefix. The shortened directory can be tab-completed to the original. + typeset -g POWERLEVEL9K_SHORTEN_STRATEGY=truncate_to_unique + # Replace removed segment suffixes with this symbol. + typeset -g POWERLEVEL9K_SHORTEN_DELIMITER= + # Color of the shortened directory segments. + typeset -g POWERLEVEL9K_DIR_SHORTENED_FOREGROUND=250 + # Color of the anchor directory segments. Anchor segments are never shortened. The first + # segment is always an anchor. + typeset -g POWERLEVEL9K_DIR_ANCHOR_FOREGROUND=255 + # Display anchor directory segments in bold. + typeset -g POWERLEVEL9K_DIR_ANCHOR_BOLD=true + # Don't shorten directories that contain any of these files. They are anchors. + local anchor_files=( + .bzr + .citc + .git + .hg + .node-version + .python-version + .go-version + .ruby-version + .lua-version + .java-version + .perl-version + .php-version + .tool-version + .shorten_folder_marker + .svn + .terraform + CVS + Cargo.toml + composer.json + go.mod + package.json + stack.yaml + ) + typeset -g POWERLEVEL9K_SHORTEN_FOLDER_MARKER="(${(j:|:)anchor_files})" + # If set to "first" ("last"), remove everything before the first (last) subdirectory that contains + # files matching $POWERLEVEL9K_SHORTEN_FOLDER_MARKER. For example, when the current directory is + # /foo/bar/git_repo/nested_git_repo/baz, prompt will display git_repo/nested_git_repo/baz (first) + # or nested_git_repo/baz (last). This assumes that git_repo and nested_git_repo contain markers + # and other directories don't. + typeset -g POWERLEVEL9K_DIR_TRUNCATE_BEFORE_MARKER=false + # Don't shorten this many last directory segments. They are anchors. + typeset -g POWERLEVEL9K_SHORTEN_DIR_LENGTH=1 + # Shorten directory if it's longer than this even if there is space for it. The value can + # be either absolute (e.g., '80') or a percentage of terminal width (e.g, '50%'). If empty, + # directory will be shortened only when prompt doesn't fit or when other parameters demand it + # (see POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS and POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT below). + # If set to `0`, directory will always be shortened to its minimum length. + typeset -g POWERLEVEL9K_DIR_MAX_LENGTH=80 + # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least this + # many columns for typing commands. + typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS=40 + # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least + # COLUMNS * POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT * 0.01 columns for typing commands. + typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT=50 + # If set to true, embed a hyperlink into the directory. Useful for quickly + # opening a directory in the file manager simply by clicking the link. + # Can also be handy when the directory is shortened, as it allows you to see + # the full directory that was used in previous commands. + typeset -g POWERLEVEL9K_DIR_HYPERLINK=false + + # Enable special styling for non-writable directories. See POWERLEVEL9K_LOCK_ICON and + # POWERLEVEL9K_DIR_CLASSES below. + typeset -g POWERLEVEL9K_DIR_SHOW_WRITABLE=v2 + + # The default icon shown next to non-writable directories when POWERLEVEL9K_DIR_SHOW_WRITABLE is + # set to v2. + # typeset -g POWERLEVEL9K_LOCK_ICON='⭐' + + # POWERLEVEL9K_DIR_CLASSES allows you to specify custom icons and colors for different + # directories. It must be an array with 3 * N elements. Each triplet consists of: + # + # 1. A pattern against which the current directory ($PWD) is matched. Matching is done with + # extended_glob option enabled. + # 2. Directory class for the purpose of styling. + # 3. An empty string. + # + # Triplets are tried in order. The first triplet whose pattern matches $PWD wins. + # + # If POWERLEVEL9K_DIR_SHOW_WRITABLE is set to v2 and the current directory is not writable, + # its class gets suffix _NOT_WRITABLE. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_DIR_CLASSES=( + # '~/work(|/*)' WORK '' + # '~(|/*)' HOME '' + # '*' DEFAULT '') + # + # Whenever the current directory is ~/work or a subdirectory of ~/work, it gets styled with class + # WORK or WORK_NOT_WRITABLE. + # + # Simply assigning classes to directories don't have any visible effects. It merely gives you an + # option to define custom colors and icons for different directory classes. + # + # # Styling for WORK. + # typeset -g POWERLEVEL9K_DIR_WORK_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_DIR_WORK_BACKGROUND=4 + # typeset -g POWERLEVEL9K_DIR_WORK_FOREGROUND=254 + # typeset -g POWERLEVEL9K_DIR_WORK_SHORTENED_FOREGROUND=250 + # typeset -g POWERLEVEL9K_DIR_WORK_ANCHOR_FOREGROUND=255 + # + # # Styling for WORK_NOT_WRITABLE. + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_BACKGROUND=4 + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_FOREGROUND=254 + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_SHORTENED_FOREGROUND=250 + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_ANCHOR_FOREGROUND=255 + # + # If a styling parameter isn't explicitly defined for some class, it falls back to the classless + # parameter. For example, if POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_FOREGROUND is not set, it falls + # back to POWERLEVEL9K_DIR_FOREGROUND. + # + # typeset -g POWERLEVEL9K_DIR_CLASSES=() + + # Custom prefix. + # typeset -g POWERLEVEL9K_DIR_PREFIX='in ' + + #####################################[ vcs: git status ]###################################### + # Version control system colors. + # typeset -g POWERLEVEL9K_VCS_CLEAN_BACKGROUND=2 + # typeset -g POWERLEVEL9K_VCS_MODIFIED_BACKGROUND=3 + # typeset -g POWERLEVEL9K_VCS_UNTRACKED_BACKGROUND=2 + # typeset -g POWERLEVEL9K_VCS_CONFLICTED_BACKGROUND=3 + # typeset -g POWERLEVEL9K_VCS_LOADING_BACKGROUND=8 + + # Branch icon. Set this parameter to '\uF126 ' for the popular Powerline branch icon. + typeset -g POWERLEVEL9K_VCS_BRANCH_ICON= + + # Untracked files icon. It's really a question mark, your font isn't broken. + # Change the value of this parameter to show a different icon. + typeset -g POWERLEVEL9K_VCS_UNTRACKED_ICON='?' + + # Formatter for Git status. + # + # Example output: master ⇣42⇡42 *42 merge ~42 +42 !42 ?42. + # + # You can edit the function to customize how Git status looks. + # + # VCS_STATUS_* parameters are set by gitstatus plugin. See reference: + # https://github.com/romkatv/gitstatus/blob/master/gitstatus.plugin.zsh. + function my_git_formatter() { + emulate -L zsh + + if [[ -n $P9K_CONTENT ]]; then + # If P9K_CONTENT is not empty, use it. It's either "loading" or from vcs_info (not from + # gitstatus plugin). VCS_STATUS_* parameters are not available in this case. + typeset -g my_git_format=$P9K_CONTENT + return + fi + + # Styling for different parts of Git status. + local meta='%7F' # white foreground + local clean='%0F' # black foreground + local modified='%0F' # black foreground + local untracked='%0F' # black foreground + local conflicted='%1F' # red foreground + + local res + local where # branch or tag + if [[ -n $VCS_STATUS_LOCAL_BRANCH ]]; then + res+="${clean}${(g::)POWERLEVEL9K_VCS_BRANCH_ICON}" + where=${(V)VCS_STATUS_LOCAL_BRANCH} + elif [[ -n $VCS_STATUS_TAG ]]; then + res+="${meta}#" + where=${(V)VCS_STATUS_TAG} + fi + + # If local branch name or tag is at most 32 characters long, show it in full. + # Otherwise show the first 12 … the last 12. + # Tip: To always show local branch name in full without truncation, delete the next line. + (( $#where > 32 )) && where[13,-13]="…" + res+="${clean}${where//\%/%%}" # escape % + + # Display the current Git commit if there is no branch or tag. + # Tip: To always display the current Git commit, remove `[[ -z $where ]] &&` from the next line. + [[ -z $where ]] && res+="${meta}@${clean}${VCS_STATUS_COMMIT[1,8]}" + + # Show tracking branch name if it differs from local branch. + if [[ -n ${VCS_STATUS_REMOTE_BRANCH:#$VCS_STATUS_LOCAL_BRANCH} ]]; then + res+="${meta}:${clean}${(V)VCS_STATUS_REMOTE_BRANCH//\%/%%}" # escape % + fi + + # ⇣42 if behind the remote. + (( VCS_STATUS_COMMITS_BEHIND )) && res+=" ${clean}⇣${VCS_STATUS_COMMITS_BEHIND}" + # ⇡42 if ahead of the remote; no leading space if also behind the remote: ⇣42⇡42. + (( VCS_STATUS_COMMITS_AHEAD && !VCS_STATUS_COMMITS_BEHIND )) && res+=" " + (( VCS_STATUS_COMMITS_AHEAD )) && res+="${clean}⇡${VCS_STATUS_COMMITS_AHEAD}" + # ⇠42 if behind the push remote. + (( VCS_STATUS_PUSH_COMMITS_BEHIND )) && res+=" ${clean}⇠${VCS_STATUS_PUSH_COMMITS_BEHIND}" + (( VCS_STATUS_PUSH_COMMITS_AHEAD && !VCS_STATUS_PUSH_COMMITS_BEHIND )) && res+=" " + # ⇢42 if ahead of the push remote; no leading space if also behind: ⇠42⇢42. + (( VCS_STATUS_PUSH_COMMITS_AHEAD )) && res+="${clean}⇢${VCS_STATUS_PUSH_COMMITS_AHEAD}" + # *42 if have stashes. + (( VCS_STATUS_STASHES )) && res+=" ${clean}*${VCS_STATUS_STASHES}" + # 'merge' if the repo is in an unusual state. + [[ -n $VCS_STATUS_ACTION ]] && res+=" ${conflicted}${VCS_STATUS_ACTION}" + # ~42 if have merge conflicts. + (( VCS_STATUS_NUM_CONFLICTED )) && res+=" ${conflicted}~${VCS_STATUS_NUM_CONFLICTED}" + # +42 if have staged changes. + (( VCS_STATUS_NUM_STAGED )) && res+=" ${modified}+${VCS_STATUS_NUM_STAGED}" + # !42 if have unstaged changes. + (( VCS_STATUS_NUM_UNSTAGED )) && res+=" ${modified}!${VCS_STATUS_NUM_UNSTAGED}" + # ?42 if have untracked files. It's really a question mark, your font isn't broken. + # See POWERLEVEL9K_VCS_UNTRACKED_ICON above if you want to use a different icon. + # Remove the next line if you don't want to see untracked files at all. + (( VCS_STATUS_NUM_UNTRACKED )) && res+=" ${untracked}${(g::)POWERLEVEL9K_VCS_UNTRACKED_ICON}${VCS_STATUS_NUM_UNTRACKED}" + # "─" if the number of unstaged files is unknown. This can happen due to + # POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY (see below) being set to a non-negative number lower + # than the number of files in the Git index, or due to bash.showDirtyState being set to false + # in the repository config. The number of staged and untracked files may also be unknown + # in this case. + (( VCS_STATUS_HAS_UNSTAGED == -1 )) && res+=" ${modified}─" + + typeset -g my_git_format=$res + } + functions -M my_git_formatter 2>/dev/null + + # Don't count the number of unstaged, untracked and conflicted files in Git repositories with + # more than this many files in the index. Negative value means infinity. + # + # If you are working in Git repositories with tens of millions of files and seeing performance + # sagging, try setting POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY to a number lower than the output + # of `git ls-files | wc -l`. Alternatively, add `bash.showDirtyState = false` to the repository's + # config: `git config bash.showDirtyState false`. + typeset -g POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY=-1 + + # Don't show Git status in prompt for repositories whose workdir matches this pattern. + # For example, if set to '~', the Git repository at $HOME/.git will be ignored. + # Multiple patterns can be combined with '|': '~(|/foo)|/bar/baz/*'. + typeset -g POWERLEVEL9K_VCS_DISABLED_WORKDIR_PATTERN='~' + + # Disable the default Git status formatting. + typeset -g POWERLEVEL9K_VCS_DISABLE_GITSTATUS_FORMATTING=true + # Install our own Git status formatter. + typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION='${$((my_git_formatter()))+${my_git_format}}' + # Enable counters for staged, unstaged, etc. + typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED,CONFLICTED,COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=-1 + + # Custom icon. + # typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_VCS_PREFIX='on ' + + # Show status of repositories of these types. You can add svn and/or hg if you are + # using them. If you do, your prompt may become slow even when your current directory + # isn't in an svn or hg reposotiry. + typeset -g POWERLEVEL9K_VCS_BACKENDS=(git) + + ##########################[ status: exit code of the last command ]########################### + # Enable OK_PIPE, ERROR_PIPE and ERROR_SIGNAL status states to allow us to enable, disable and + # style them independently from the regular OK and ERROR state. + typeset -g POWERLEVEL9K_STATUS_EXTENDED_STATES=true + + # Status on success. No content, just an icon. No need to show it if prompt_char is enabled as + # it will signify success by turning green. + typeset -g POWERLEVEL9K_STATUS_OK=true + typeset -g POWERLEVEL9K_STATUS_OK_VISUAL_IDENTIFIER_EXPANSION='✔' + # typeset -g POWERLEVEL9K_STATUS_OK_FOREGROUND=2 + # typeset -g POWERLEVEL9K_STATUS_OK_BACKGROUND=0 + + # Status when some part of a pipe command fails but the overall exit status is zero. It may look + # like this: 1|0. + typeset -g POWERLEVEL9K_STATUS_OK_PIPE=true + typeset -g POWERLEVEL9K_STATUS_OK_PIPE_VISUAL_IDENTIFIER_EXPANSION='✔' + # typeset -g POWERLEVEL9K_STATUS_OK_PIPE_FOREGROUND=2 + # typeset -g POWERLEVEL9K_STATUS_OK_PIPE_BACKGROUND=0 + + # Status when it's just an error code (e.g., '1'). No need to show it if prompt_char is enabled as + # it will signify error by turning red. + typeset -g POWERLEVEL9K_STATUS_ERROR=true + typeset -g POWERLEVEL9K_STATUS_ERROR_VISUAL_IDENTIFIER_EXPANSION='✘' + # typeset -g POWERLEVEL9K_STATUS_ERROR_FOREGROUND=3 + # typeset -g POWERLEVEL9K_STATUS_ERROR_BACKGROUND=1 + + # Status when the last command was terminated by a signal. + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL=true + # Use terse signal names: "INT" instead of "SIGINT(2)". + typeset -g POWERLEVEL9K_STATUS_VERBOSE_SIGNAME=false + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_VISUAL_IDENTIFIER_EXPANSION='✘' + # typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_FOREGROUND=3 + # typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_BACKGROUND=1 + + # Status when some part of a pipe command fails and the overall exit status is also non-zero. + # It may look like this: 1|0. + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE=true + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_VISUAL_IDENTIFIER_EXPANSION='✘' + # typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_FOREGROUND=3 + # typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_BACKGROUND=1 + + ###################[ command_execution_time: duration of the last command ]################### + # Execution time color. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FOREGROUND=0 + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_BACKGROUND=3 + # Show duration of the last command if takes longer than this many seconds. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=3 + # Show this many fractional digits. Zero means round to seconds. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PRECISION=0 + # Duration format: 1d 2h 3m 4s. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FORMAT='d h m s' + # Custom icon. + # typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PREFIX='took ' + + #######################[ background_jobs: presence of background jobs ]####################### + # Background jobs color. + # typeset -g POWERLEVEL9K_BACKGROUND_JOBS_FOREGROUND=6 + # typeset -g POWERLEVEL9K_BACKGROUND_JOBS_BACKGROUND=0 + # Don't show the number of background jobs. + typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VERBOSE=false + # Custom icon. + # typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ direnv: direnv status (https://direnv.net/) ]######################## + # Direnv color. + # typeset -g POWERLEVEL9K_DIRENV_FOREGROUND=3 + # typeset -g POWERLEVEL9K_DIRENV_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_DIRENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ asdf: asdf version manager (https://github.com/asdf-vm/asdf) ]############### + # Default asdf color. Only used to display tools for which there is no color override (see below). + typeset -g POWERLEVEL9K_ASDF_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_BACKGROUND=7 + + # There are four parameters that can be used to hide asdf tools. Each parameter describes + # conditions under which a tool gets hidden. Parameters can hide tools but not unhide them. If at + # least one parameter decides to hide a tool, that tool gets hidden. If no parameter decides to + # hide a tool, it gets shown. + # + # Special note on the difference between POWERLEVEL9K_ASDF_SOURCES and + # POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW. Consider the effect of the following commands: + # + # asdf local python 3.8.1 + # asdf global python 3.8.1 + # + # After running both commands the current python version is 3.8.1 and its source is "local" as + # it takes precedence over "global". If POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW is set to false, + # it'll hide python version in this case because 3.8.1 is the same as the global version. + # POWERLEVEL9K_ASDF_SOURCES will hide python version only if the value of this parameter doesn't + # contain "local". + + # Hide tool versions that don't come from one of these sources. + # + # Available sources: + # + # - shell `asdf current` says "set by ASDF_${TOOL}_VERSION environment variable" + # - local `asdf current` says "set by /some/not/home/directory/file" + # - global `asdf current` says "set by /home/username/file" + # + # Note: If this parameter is set to (shell local global), it won't hide tools. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SOURCES. + typeset -g POWERLEVEL9K_ASDF_SOURCES=(shell local global) + + # If set to false, hide tool versions that are the same as global. + # + # Note: The name of this parameter doesn't reflect its meaning at all. + # Note: If this parameter is set to true, it won't hide tools. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_PROMPT_ALWAYS_SHOW. + typeset -g POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW=false + + # If set to false, hide tool versions that are equal to "system". + # + # Note: If this parameter is set to true, it won't hide tools. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SHOW_SYSTEM. + typeset -g POWERLEVEL9K_ASDF_SHOW_SYSTEM=true + + # If set to non-empty value, hide tools unless there is a file matching the specified file pattern + # in the current directory, or its parent diretory, or its grandparent directory, and so on. + # + # Note: If this parameter is set to empty value, it won't hide tools. + # Note: SHOW_ON_UPGLOB isn't specific to asdf. It works with all prompt segments. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SHOW_ON_UPGLOB. + # + # Example: Hide nodejs version when there is no package.json and no *.js files in the current + # directory, in `..`, in `../..` and so on. + # + # typeset -g POWERLEVEL9K_ASDF_NODEJS_SHOW_ON_UPGLOB='*.js|package.json' + typeset -g POWERLEVEL9K_ASDF_SHOW_ON_UPGLOB= + + # Ruby version from asdf. + typeset -g POWERLEVEL9K_ASDF_RUBY_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_RUBY_BACKGROUND=1 + # typeset -g POWERLEVEL9K_ASDF_RUBY_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_RUBY_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Python version from asdf. + typeset -g POWERLEVEL9K_ASDF_PYTHON_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_PYTHON_BACKGROUND=4 + # typeset -g POWERLEVEL9K_ASDF_PYTHON_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_PYTHON_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Go version from asdf. + typeset -g POWERLEVEL9K_ASDF_GOLANG_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_GOLANG_BACKGROUND=4 + # typeset -g POWERLEVEL9K_ASDF_GOLANG_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_GOLANG_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Node.js version from asdf. + typeset -g POWERLEVEL9K_ASDF_NODEJS_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_NODEJS_BACKGROUND=2 + # typeset -g POWERLEVEL9K_ASDF_NODEJS_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_NODEJS_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Rust version from asdf. + typeset -g POWERLEVEL9K_ASDF_RUST_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_RUST_BACKGROUND=208 + # typeset -g POWERLEVEL9K_ASDF_RUST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_RUST_SHOW_ON_UPGLOB='*.foo|*.bar' + + # .NET Core version from asdf. + typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_BACKGROUND=5 + # typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Flutter version from asdf. + typeset -g POWERLEVEL9K_ASDF_FLUTTER_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_FLUTTER_BACKGROUND=4 + # typeset -g POWERLEVEL9K_ASDF_FLUTTER_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_FLUTTER_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Lua version from asdf. + typeset -g POWERLEVEL9K_ASDF_LUA_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_LUA_BACKGROUND=4 + # typeset -g POWERLEVEL9K_ASDF_LUA_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_LUA_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Java version from asdf. + typeset -g POWERLEVEL9K_ASDF_JAVA_FOREGROUND=1 + typeset -g POWERLEVEL9K_ASDF_JAVA_BACKGROUND=7 + # typeset -g POWERLEVEL9K_ASDF_JAVA_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_JAVA_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Perl version from asdf. + typeset -g POWERLEVEL9K_ASDF_PERL_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_PERL_BACKGROUND=4 + # typeset -g POWERLEVEL9K_ASDF_PERL_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_PERL_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Erlang version from asdf. + typeset -g POWERLEVEL9K_ASDF_ERLANG_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_ERLANG_BACKGROUND=1 + # typeset -g POWERLEVEL9K_ASDF_ERLANG_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_ERLANG_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Elixir version from asdf. + typeset -g POWERLEVEL9K_ASDF_ELIXIR_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_ELIXIR_BACKGROUND=5 + # typeset -g POWERLEVEL9K_ASDF_ELIXIR_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_ELIXIR_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Postgres version from asdf. + typeset -g POWERLEVEL9K_ASDF_POSTGRES_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_POSTGRES_BACKGROUND=6 + # typeset -g POWERLEVEL9K_ASDF_POSTGRES_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_POSTGRES_SHOW_ON_UPGLOB='*.foo|*.bar' + + # PHP version from asdf. + typeset -g POWERLEVEL9K_ASDF_PHP_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_PHP_BACKGROUND=5 + # typeset -g POWERLEVEL9K_ASDF_PHP_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_PHP_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Haskell version from asdf. + typeset -g POWERLEVEL9K_ASDF_HASKELL_FOREGROUND=0 + typeset -g POWERLEVEL9K_ASDF_HASKELL_BACKGROUND=3 + # typeset -g POWERLEVEL9K_ASDF_HASKELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_HASKELL_SHOW_ON_UPGLOB='*.foo|*.bar' + + ##########[ nordvpn: nordvpn connection status, linux only (https://nordvpn.com/) ]########### + # NordVPN connection indicator color. + # typeset -g POWERLEVEL9K_NORDVPN_FOREGROUND=7 + # typeset -g POWERLEVEL9K_NORDVPN_BACKGROUND=4 + # Hide NordVPN connection indicator when not connected. + typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_CONTENT_EXPANSION= + typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_VISUAL_IDENTIFIER_EXPANSION= + # Custom icon. + # typeset -g POWERLEVEL9K_NORDVPN_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #################[ ranger: ranger shell (https://github.com/ranger/ranger) ]################## + # Ranger shell color. + # typeset -g POWERLEVEL9K_RANGER_FOREGROUND=3 + # typeset -g POWERLEVEL9K_RANGER_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_RANGER_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################[ nnn: nnn shell (https://github.com/jarun/nnn) ]####################### + # Nnn shell color. + # typeset -g POWERLEVEL9K_NNN_FOREGROUND=0 + # typeset -g POWERLEVEL9K_NNN_BACKGROUND=6 + # Custom icon. + # typeset -g POWERLEVEL9K_NNN_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########################[ vim_shell: vim shell indicator (:sh) ]########################### + # Vim shell indicator color. + # typeset -g POWERLEVEL9K_VIM_SHELL_FOREGROUND=0 + # typeset -g POWERLEVEL9K_VIM_SHELL_BACKGROUND=2 + # Custom icon. + # typeset -g POWERLEVEL9K_VIM_SHELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######[ midnight_commander: midnight commander shell (https://midnight-commander.org/) ]###### + # Midnight Commander shell color. + # typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_FOREGROUND=3 + # typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ nix_shell: nix shell (https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html) ]## + # Nix shell color. + # typeset -g POWERLEVEL9K_NIX_SHELL_FOREGROUND=0 + # typeset -g POWERLEVEL9K_NIX_SHELL_BACKGROUND=4 + + # Tip: If you want to see just the icon without "pure" and "impure", uncomment the next line. + # typeset -g POWERLEVEL9K_NIX_SHELL_CONTENT_EXPANSION= + + # Custom icon. + # typeset -g POWERLEVEL9K_NIX_SHELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##################################[ disk_usage: disk usage ]################################## + # Colors for different levels of disk usage. + # typeset -g POWERLEVEL9K_DISK_USAGE_NORMAL_FOREGROUND=3 + # typeset -g POWERLEVEL9K_DISK_USAGE_NORMAL_BACKGROUND=0 + # typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_FOREGROUND=0 + # typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_BACKGROUND=3 + # typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_FOREGROUND=7 + # typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_BACKGROUND=1 + # Thresholds for different levels of disk usage (percentage points). + typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL=90 + typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_LEVEL=95 + # If set to true, hide disk usage when below $POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL percent. + typeset -g POWERLEVEL9K_DISK_USAGE_ONLY_WARNING=false + # Custom icon. + # typeset -g POWERLEVEL9K_DISK_USAGE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ vi_mode: vi mode (you don't need this if you've enabled prompt_char) ]########### + # Foreground color. + typeset -g POWERLEVEL9K_VI_MODE_FOREGROUND=0 + # Text and color for normal (a.k.a. command) vi mode. + typeset -g POWERLEVEL9K_VI_COMMAND_MODE_STRING=NORMAL + typeset -g POWERLEVEL9K_VI_MODE_NORMAL_BACKGROUND=2 + # Text and color for visual vi mode. + typeset -g POWERLEVEL9K_VI_VISUAL_MODE_STRING=VISUAL + typeset -g POWERLEVEL9K_VI_MODE_VISUAL_BACKGROUND=4 + # Text and color for overtype (a.k.a. overwrite and replace) vi mode. + typeset -g POWERLEVEL9K_VI_OVERWRITE_MODE_STRING=OVERTYPE + typeset -g POWERLEVEL9K_VI_MODE_OVERWRITE_BACKGROUND=3 + # Text and color for insert vi mode. + typeset -g POWERLEVEL9K_VI_INSERT_MODE_STRING= + typeset -g POWERLEVEL9K_VI_MODE_INSERT_FOREGROUND=8 + + ######################################[ ram: free RAM ]####################################### + # RAM color. + # typeset -g POWERLEVEL9K_RAM_FOREGROUND=0 + # typeset -g POWERLEVEL9K_RAM_BACKGROUND=3 + # Custom icon. + # typeset -g POWERLEVEL9K_RAM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #####################################[ swap: used swap ]###################################### + # Swap color. + # typeset -g POWERLEVEL9K_SWAP_FOREGROUND=0 + # typeset -g POWERLEVEL9K_SWAP_BACKGROUND=3 + # Custom icon. + # typeset -g POWERLEVEL9K_SWAP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################################[ load: CPU load ]###################################### + # Show average CPU load over this many last minutes. Valid values are 1, 5 and 15. + typeset -g POWERLEVEL9K_LOAD_WHICH=5 + # Load color when load is under 50%. + # typeset -g POWERLEVEL9K_LOAD_NORMAL_FOREGROUND=0 + # typeset -g POWERLEVEL9K_LOAD_NORMAL_BACKGROUND=2 + # Load color when load is between 50% and 70%. + # typeset -g POWERLEVEL9K_LOAD_WARNING_FOREGROUND=0 + # typeset -g POWERLEVEL9K_LOAD_WARNING_BACKGROUND=3 + # Load color when load is over 70%. + # typeset -g POWERLEVEL9K_LOAD_CRITICAL_FOREGROUND=0 + # typeset -g POWERLEVEL9K_LOAD_CRITICAL_BACKGROUND=1 + # Custom icon. + # typeset -g POWERLEVEL9K_LOAD_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ todo: todo items (https://github.com/todotxt/todo.txt-cli) ]################ + # Todo color. + # typeset -g POWERLEVEL9K_TODO_FOREGROUND=0 + # typeset -g POWERLEVEL9K_TODO_BACKGROUND=8 + # Hide todo when the total number of tasks is zero. + typeset -g POWERLEVEL9K_TODO_HIDE_ZERO_TOTAL=true + # Hide todo when the number of tasks after filtering is zero. + typeset -g POWERLEVEL9K_TODO_HIDE_ZERO_FILTERED=false + + # Todo format. The following parameters are available within the expansion. + # + # - P9K_TODO_TOTAL_TASK_COUNT The total number of tasks. + # - P9K_TODO_FILTERED_TASK_COUNT The number of tasks after filtering. + # + # These variables correspond to the last line of the output of `todo.sh -p ls`: + # + # TODO: 24 of 42 tasks shown + # + # Here 24 is P9K_TODO_FILTERED_TASK_COUNT and 42 is P9K_TODO_TOTAL_TASK_COUNT. + # + # typeset -g POWERLEVEL9K_TODO_CONTENT_EXPANSION='$P9K_TODO_FILTERED_TASK_COUNT' + + # Custom icon. + # typeset -g POWERLEVEL9K_TODO_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ timewarrior: timewarrior tracking status (https://timewarrior.net/) ]############ + # Timewarrior color. + # typeset -g POWERLEVEL9K_TIMEWARRIOR_FOREGROUND=255 + # typeset -g POWERLEVEL9K_TIMEWARRIOR_BACKGROUND=8 + + # If the tracked task is longer than 24 characters, truncate and append "…". + # Tip: To always display tasks without truncation, delete the following parameter. + # Tip: To hide task names and display just the icon when time tracking is enabled, set the + # value of the following parameter to "". + typeset -g POWERLEVEL9K_TIMEWARRIOR_CONTENT_EXPANSION='${P9K_CONTENT:0:24}${${P9K_CONTENT:24}:+…}' + + # Custom icon. + # typeset -g POWERLEVEL9K_TIMEWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############[ taskwarrior: taskwarrior task count (https://taskwarrior.org/) ]############## + # Taskwarrior color. + # typeset -g POWERLEVEL9K_TASKWARRIOR_FOREGROUND=0 + # typeset -g POWERLEVEL9K_TASKWARRIOR_BACKGROUND=6 + + # Taskwarrior segment format. The following parameters are available within the expansion. + # + # - P9K_TASKWARRIOR_PENDING_COUNT The number of pending tasks: `task +PENDING count`. + # - P9K_TASKWARRIOR_OVERDUE_COUNT The number of overdue tasks: `task +OVERDUE count`. + # + # Zero values are represented as empty parameters. + # + # The default format: + # + # '${P9K_TASKWARRIOR_OVERDUE_COUNT:+"!$P9K_TASKWARRIOR_OVERDUE_COUNT/"}$P9K_TASKWARRIOR_PENDING_COUNT' + # + # typeset -g POWERLEVEL9K_TASKWARRIOR_CONTENT_EXPANSION='$P9K_TASKWARRIOR_PENDING_COUNT' + + # Custom icon. + # typeset -g POWERLEVEL9K_TASKWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##################################[ context: user@hostname ]################################## + # Context color when running with privileges. + typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND=1 + typeset -g POWERLEVEL9K_CONTEXT_ROOT_BACKGROUND=0 + # Context color in SSH without privileges. + typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_FOREGROUND=3 + typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_BACKGROUND=0 + # Default context color (no privileges, no SSH). + typeset -g POWERLEVEL9K_CONTEXT_FOREGROUND=3 + typeset -g POWERLEVEL9K_CONTEXT_BACKGROUND=0 + + # Context format when running with privileges: user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE='%n@%m' + # Context format when in SSH without privileges: user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_TEMPLATE='%n@%m' + # Default context format (no privileges, no SSH): user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE='%n@%m' + + # Don't show context unless running with privileges or in SSH. + # Tip: Remove the next line to always show context. + typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_{CONTENT,VISUAL_IDENTIFIER}_EXPANSION= + + # Custom icon. + # typeset -g POWERLEVEL9K_CONTEXT_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_CONTEXT_PREFIX='with ' + + ###[ virtualenv: python virtual environment (https://docs.python.org/3/library/venv.html) ]### + # Python virtual environment color. + # typeset -g POWERLEVEL9K_VIRTUALENV_FOREGROUND=0 + # typeset -g POWERLEVEL9K_VIRTUALENV_BACKGROUND=4 + # Don't show Python version next to the virtual environment name. + typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_PYTHON_VERSION=false + # Don't show virtualenv if pyenv is already shown. + typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_WITH_PYENV=false + # Separate environment name from Python version only with a space. + typeset -g POWERLEVEL9K_VIRTUALENV_{LEFT,RIGHT}_DELIMITER= + # Custom icon. + # typeset -g POWERLEVEL9K_VIRTUALENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #####################[ anaconda: conda environment (https://conda.io/) ]###################### + # Anaconda environment color. + # typeset -g POWERLEVEL9K_ANACONDA_FOREGROUND=0 + # typeset -g POWERLEVEL9K_ANACONDA_BACKGROUND=4 + # Don't show Python version next to the anaconda environment name. + typeset -g POWERLEVEL9K_ANACONDA_SHOW_PYTHON_VERSION=false + # Separate environment name from Python version only with a space. + typeset -g POWERLEVEL9K_ANACONDA_{LEFT,RIGHT}_DELIMITER= + # Custom icon. + # typeset -g POWERLEVEL9K_ANACONDA_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ pyenv: python environment (https://github.com/pyenv/pyenv) ]################ + # Pyenv color. + # typeset -g POWERLEVEL9K_PYENV_FOREGROUND=0 + # typeset -g POWERLEVEL9K_PYENV_BACKGROUND=4 + # Hide python version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_PYENV_SOURCES=(shell local global) + # If set to false, hide python version if it's the same as global: + # $(pyenv version-name) == $(pyenv global). + typeset -g POWERLEVEL9K_PYENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide python version if it's equal to "system". + typeset -g POWERLEVEL9K_PYENV_SHOW_SYSTEM=true + + # Pyenv segment format. The following parameters are available within the expansion. + # + # - P9K_CONTENT Current pyenv environment (pyenv version-name). + # - P9K_PYENV_PYTHON_VERSION Current python version (python --version). + # + # The default format has the following logic: + # + # 1. Display "$P9K_CONTENT $P9K_PYENV_PYTHON_VERSION" if $P9K_PYENV_PYTHON_VERSION is not + # empty and unequal to $P9K_CONTENT. + # 2. Otherwise display just "$P9K_CONTENT". + typeset -g POWERLEVEL9K_PYENV_CONTENT_EXPANSION='${P9K_CONTENT}${${P9K_PYENV_PYTHON_VERSION:#$P9K_CONTENT}:+ $P9K_PYENV_PYTHON_VERSION}' + + # Custom icon. + # typeset -g POWERLEVEL9K_PYENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ goenv: go environment (https://github.com/syndbg/goenv) ]################ + # Goenv color. + # typeset -g POWERLEVEL9K_GOENV_FOREGROUND=0 + # typeset -g POWERLEVEL9K_GOENV_BACKGROUND=4 + # Hide go version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_GOENV_SOURCES=(shell local global) + # If set to false, hide go version if it's the same as global: + # $(goenv version-name) == $(goenv global). + typeset -g POWERLEVEL9K_GOENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide go version if it's equal to "system". + typeset -g POWERLEVEL9K_GOENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_GOENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ nodenv: node.js version from nodenv (https://github.com/nodenv/nodenv) ]########## + # Nodenv color. + # typeset -g POWERLEVEL9K_NODENV_FOREGROUND=2 + # typeset -g POWERLEVEL9K_NODENV_BACKGROUND=0 + # Hide node version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_NODENV_SOURCES=(shell local global) + # If set to false, hide node version if it's the same as global: + # $(nodenv version-name) == $(nodenv global). + typeset -g POWERLEVEL9K_NODENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide node version if it's equal to "system". + typeset -g POWERLEVEL9K_NODENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_NODENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############[ nvm: node.js version from nvm (https://github.com/nvm-sh/nvm) ]############### + # Nvm color. + # typeset -g POWERLEVEL9K_NVM_FOREGROUND=0 + # typeset -g POWERLEVEL9K_NVM_BACKGROUND=5 + # Custom icon. + # typeset -g POWERLEVEL9K_NVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ############[ nodeenv: node.js environment (https://github.com/ekalinin/nodeenv) ]############ + # Nodeenv color. + # typeset -g POWERLEVEL9K_NODEENV_FOREGROUND=2 + # typeset -g POWERLEVEL9K_NODEENV_BACKGROUND=0 + # Don't show Node version next to the environment name. + typeset -g POWERLEVEL9K_NODEENV_SHOW_NODE_VERSION=false + # Separate environment name from Node version only with a space. + typeset -g POWERLEVEL9K_NODEENV_{LEFT,RIGHT}_DELIMITER= + # Custom icon. + # typeset -g POWERLEVEL9K_NODEENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############################[ node_version: node.js version ]############################### + # Node version color. + # typeset -g POWERLEVEL9K_NODE_VERSION_FOREGROUND=7 + # typeset -g POWERLEVEL9K_NODE_VERSION_BACKGROUND=2 + # Show node version only when in a directory tree containing package.json. + typeset -g POWERLEVEL9K_NODE_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_NODE_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ go_version: go version (https://golang.org) ]######################## + # Go version color. + # typeset -g POWERLEVEL9K_GO_VERSION_FOREGROUND=255 + # typeset -g POWERLEVEL9K_GO_VERSION_BACKGROUND=2 + # Show go version only when in a go project subdirectory. + typeset -g POWERLEVEL9K_GO_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_GO_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #################[ rust_version: rustc version (https://www.rust-lang.org) ]################## + # Rust version color. + # typeset -g POWERLEVEL9K_RUST_VERSION_FOREGROUND=0 + # typeset -g POWERLEVEL9K_RUST_VERSION_BACKGROUND=208 + # Show rust version only when in a rust project subdirectory. + typeset -g POWERLEVEL9K_RUST_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_RUST_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ dotnet_version: .NET version (https://dotnet.microsoft.com) ]################ + # .NET version color. + # typeset -g POWERLEVEL9K_DOTNET_VERSION_FOREGROUND=7 + # typeset -g POWERLEVEL9K_DOTNET_VERSION_BACKGROUND=5 + # Show .NET version only when in a .NET project subdirectory. + typeset -g POWERLEVEL9K_DOTNET_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_DOTNET_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #####################[ php_version: php version (https://www.php.net/) ]###################### + # PHP version color. + typeset -g POWERLEVEL9K_PHP_VERSION_FOREGROUND=0 + typeset -g POWERLEVEL9K_PHP_VERSION_BACKGROUND=5 + # Show PHP version only when in a PHP project subdirectory. + typeset -g POWERLEVEL9K_PHP_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_PHP_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ laravel_version: laravel php framework version (https://laravel.com/) ]########### + # Laravel version color. + typeset -g POWERLEVEL9K_LARAVEL_VERSION_FOREGROUND=1 + typeset -g POWERLEVEL9K_LARAVEL_VERSION_BACKGROUND=7 + # Custom icon. + # typeset -g POWERLEVEL9K_LARAVEL_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #############[ rbenv: ruby version from rbenv (https://github.com/rbenv/rbenv) ]############## + # Rbenv color. + # typeset -g POWERLEVEL9K_RBENV_FOREGROUND=0 + # typeset -g POWERLEVEL9K_RBENV_BACKGROUND=1 + # Hide ruby version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_RBENV_SOURCES=(shell local global) + # If set to false, hide ruby version if it's the same as global: + # $(rbenv version-name) == $(rbenv global). + typeset -g POWERLEVEL9K_RBENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide ruby version if it's equal to "system". + typeset -g POWERLEVEL9K_RBENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_RBENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ####################[ java_version: java version (https://www.java.com/) ]#################### + # Java version color. + typeset -g POWERLEVEL9K_JAVA_VERSION_FOREGROUND=1 + typeset -g POWERLEVEL9K_JAVA_VERSION_BACKGROUND=7 + # Show java version only when in a java project subdirectory. + typeset -g POWERLEVEL9K_JAVA_VERSION_PROJECT_ONLY=true + # Show brief version. + typeset -g POWERLEVEL9K_JAVA_VERSION_FULL=false + # Custom icon. + # typeset -g POWERLEVEL9K_JAVA_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###[ package: name@version from package.json (https://docs.npmjs.com/files/package.json) ]#### + # Package color. + # typeset -g POWERLEVEL9K_PACKAGE_FOREGROUND=0 + # typeset -g POWERLEVEL9K_PACKAGE_BACKGROUND=6 + + # Package format. The following parameters are available within the expansion. + # + # - P9K_PACKAGE_NAME The value of `name` field in package.json. + # - P9K_PACKAGE_VERSION The value of `version` field in package.json. + # + # typeset -g POWERLEVEL9K_PACKAGE_CONTENT_EXPANSION='${P9K_PACKAGE_NAME//\%/%%}@${P9K_PACKAGE_VERSION//\%/%%}' + + # Custom icon. + # typeset -g POWERLEVEL9K_PACKAGE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ rvm: ruby version from rvm (https://rvm.io) ]######################## + # Rvm color. + # typeset -g POWERLEVEL9K_RVM_FOREGROUND=0 + # typeset -g POWERLEVEL9K_RVM_BACKGROUND=240 + # Don't show @gemset at the end. + typeset -g POWERLEVEL9K_RVM_SHOW_GEMSET=false + # Don't show ruby- at the front. + typeset -g POWERLEVEL9K_RVM_SHOW_PREFIX=false + # Custom icon. + # typeset -g POWERLEVEL9K_RVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ fvm: flutter version management (https://github.com/leoafarias/fvm) ]############ + # Fvm color. + # typeset -g POWERLEVEL9K_FVM_FOREGROUND=0 + # typeset -g POWERLEVEL9K_FVM_BACKGROUND=4 + # Custom icon. + # typeset -g POWERLEVEL9K_FVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ luaenv: lua version from luaenv (https://github.com/cehoffman/luaenv) ]########### + # Lua color. + # typeset -g POWERLEVEL9K_LUAENV_FOREGROUND=0 + # typeset -g POWERLEVEL9K_LUAENV_BACKGROUND=4 + # Hide lua version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_LUAENV_SOURCES=(shell local global) + # If set to false, hide lua version if it's the same as global: + # $(luaenv version-name) == $(luaenv global). + typeset -g POWERLEVEL9K_LUAENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide lua version if it's equal to "system". + typeset -g POWERLEVEL9K_LUAENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_LUAENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ jenv: java version from jenv (https://github.com/jenv/jenv) ]################ + # Java color. + # typeset -g POWERLEVEL9K_JENV_FOREGROUND=1 + # typeset -g POWERLEVEL9K_JENV_BACKGROUND=7 + # Hide java version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_JENV_SOURCES=(shell local global) + # If set to false, hide java version if it's the same as global: + # $(jenv version-name) == $(jenv global). + typeset -g POWERLEVEL9K_JENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide java version if it's equal to "system". + typeset -g POWERLEVEL9K_JENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_JENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ plenv: perl version from plenv (https://github.com/tokuhirom/plenv) ]############ + # Perl color. + # typeset -g POWERLEVEL9K_PLENV_FOREGROUND=0 + # typeset -g POWERLEVEL9K_PLENV_BACKGROUND=4 + # Hide perl version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_PLENV_SOURCES=(shell local global) + # If set to false, hide perl version if it's the same as global: + # $(plenv version-name) == $(plenv global). + typeset -g POWERLEVEL9K_PLENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide perl version if it's equal to "system". + typeset -g POWERLEVEL9K_PLENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_PLENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ############[ phpenv: php version from phpenv (https://github.com/phpenv/phpenv) ]############ + # PHP color. + # typeset -g POWERLEVEL9K_PHPENV_FOREGROUND=0 + # typeset -g POWERLEVEL9K_PHPENV_BACKGROUND=5 + # Hide php version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_PHPENV_SOURCES=(shell local global) + # If set to false, hide php version if it's the same as global: + # $(phpenv version-name) == $(phpenv global). + typeset -g POWERLEVEL9K_PHPENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide PHP version if it's equal to "system". + typeset -g POWERLEVEL9K_PHPENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_PHPENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ haskell_stack: haskell version from stack (https://haskellstack.org/) ]########### + # Haskell color. + # typeset -g POWERLEVEL9K_HASKELL_STACK_FOREGROUND=0 + # typeset -g POWERLEVEL9K_HASKELL_STACK_BACKGROUND=3 + + # Hide haskell version if it doesn't come from one of these sources. + # + # shell: version is set by STACK_YAML + # local: version is set by stack.yaml up the directory tree + # global: version is set by the implicit global project (~/.stack/global-project/stack.yaml) + typeset -g POWERLEVEL9K_HASKELL_STACK_SOURCES=(shell local) + # If set to false, hide haskell version if it's the same as in the implicit global project. + typeset -g POWERLEVEL9K_HASKELL_STACK_ALWAYS_SHOW=true + # Custom icon. + # typeset -g POWERLEVEL9K_HASKELL_STACK_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ terraform: terraform workspace (https://www.terraform.io) ]################# + # POWERLEVEL9K_TERRAFORM_CLASSES is an array with even number of elements. The first element + # in each pair defines a pattern against which the current terraform workspace gets matched. + # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below) + # that gets matched. If you unset all POWERLEVEL9K_TERRAFORM_*CONTENT_EXPANSION parameters, + # you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_TERRAFORM_CLASSES defines the workspace class. Patterns are tried in order. The + # first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_TERRAFORM_CLASSES=( + # '*prod*' PROD + # '*test*' TEST + # '*' DEFAULT) + # + # If your current terraform workspace is "project_test", its class is TEST because "project_test" + # doesn't match the pattern '*prod*' but does match '*test*'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_FOREGROUND=2 + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' + typeset -g POWERLEVEL9K_TERRAFORM_CLASSES=( + # '*prod*' PROD # These values are examples that are unlikely + # '*test*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_TERRAFORM_DEFAULT_FOREGROUND=4 + typeset -g POWERLEVEL9K_TERRAFORM_DEFAULT_BACKGROUND=0 + # typeset -g POWERLEVEL9K_TERRAFORM_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #############[ kubecontext: current kubernetes context (https://kubernetes.io/) ]############# + # Show kubecontext only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show kubecontext. + typeset -g POWERLEVEL9K_KUBECONTEXT_SHOW_ON_COMMAND='kubectl|helm|kubens|kubectx|oc|istioctl|kogito' + + # Kubernetes context classes for the purpose of using different colors, icons and expansions with + # different contexts. + # + # POWERLEVEL9K_KUBECONTEXT_CLASSES is an array with even number of elements. The first element + # in each pair defines a pattern against which the current kubernetes context gets matched. + # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below) + # that gets matched. If you unset all POWERLEVEL9K_KUBECONTEXT_*CONTENT_EXPANSION parameters, + # you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_KUBECONTEXT_CLASSES defines the context class. Patterns are tried in order. The + # first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=( + # '*prod*' PROD + # '*test*' TEST + # '*' DEFAULT) + # + # If your current kubernetes context is "deathray-testing/default", its class is TEST + # because "deathray-testing/default" doesn't match the pattern '*prod*' but does match '*test*'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_FOREGROUND=0 + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_BACKGROUND=2 + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' + typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=( + # '*prod*' PROD # These values are examples that are unlikely + # '*test*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_FOREGROUND=7 + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_BACKGROUND=5 + # typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Use POWERLEVEL9K_KUBECONTEXT_CONTENT_EXPANSION to specify the content displayed by kubecontext + # segment. Parameter expansions are very flexible and fast, too. See reference: + # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion. + # + # Within the expansion the following parameters are always available: + # + # - P9K_CONTENT The content that would've been displayed if there was no content + # expansion defined. + # - P9K_KUBECONTEXT_NAME The current context's name. Corresponds to column NAME in the + # output of `kubectl config get-contexts`. + # - P9K_KUBECONTEXT_CLUSTER The current context's cluster. Corresponds to column CLUSTER in the + # output of `kubectl config get-contexts`. + # - P9K_KUBECONTEXT_NAMESPACE The current context's namespace. Corresponds to column NAMESPACE + # in the output of `kubectl config get-contexts`. If there is no + # namespace, the parameter is set to "default". + # - P9K_KUBECONTEXT_USER The current context's user. Corresponds to column AUTHINFO in the + # output of `kubectl config get-contexts`. + # + # If the context points to Google Kubernetes Engine (GKE) or Elastic Kubernetes Service (EKS), + # the following extra parameters are available: + # + # - P9K_KUBECONTEXT_CLOUD_NAME Either "gke" or "eks". + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT Account/project ID. + # - P9K_KUBECONTEXT_CLOUD_ZONE Availability zone. + # - P9K_KUBECONTEXT_CLOUD_CLUSTER Cluster. + # + # P9K_KUBECONTEXT_CLOUD_* parameters are derived from P9K_KUBECONTEXT_CLUSTER. For example, + # if P9K_KUBECONTEXT_CLUSTER is "gke_my-account_us-east1-a_my-cluster-01": + # + # - P9K_KUBECONTEXT_CLOUD_NAME=gke + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=my-account + # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east1-a + # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01 + # + # If P9K_KUBECONTEXT_CLUSTER is "arn:aws:eks:us-east-1:123456789012:cluster/my-cluster-01": + # + # - P9K_KUBECONTEXT_CLOUD_NAME=eks + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=123456789012 + # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east-1 + # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01 + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION= + # Show P9K_KUBECONTEXT_CLOUD_CLUSTER if it's not empty and fall back to P9K_KUBECONTEXT_NAME. + POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${P9K_KUBECONTEXT_CLOUD_CLUSTER:-${P9K_KUBECONTEXT_NAME}}' + # Append the current context's namespace if it's not "default". + POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${${:-/$P9K_KUBECONTEXT_NAMESPACE}:#/default}' + + # Custom prefix. + # typeset -g POWERLEVEL9K_KUBECONTEXT_PREFIX='at ' + + #[ aws: aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) ]# + # Show aws only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show aws. + typeset -g POWERLEVEL9K_AWS_SHOW_ON_COMMAND='aws|awless|terraform|pulumi' + + # POWERLEVEL9K_AWS_CLASSES is an array with even number of elements. The first element + # in each pair defines a pattern against which the current AWS profile gets matched. + # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below) + # that gets matched. If you unset all POWERLEVEL9K_AWS_*CONTENT_EXPANSION parameters, + # you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_AWS_CLASSES defines the profile class. Patterns are tried in order. The + # first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_AWS_CLASSES=( + # '*prod*' PROD + # '*test*' TEST + # '*' DEFAULT) + # + # If your current AWS profile is "company_test", its class is TEST + # because "company_test" doesn't match the pattern '*prod*' but does match '*test*'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_AWS_TEST_FOREGROUND=28 + # typeset -g POWERLEVEL9K_AWS_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_AWS_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' + typeset -g POWERLEVEL9K_AWS_CLASSES=( + # '*prod*' PROD # These values are examples that are unlikely + # '*test*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + # typeset -g POWERLEVEL9K_AWS_DEFAULT_FOREGROUND=7 + # typeset -g POWERLEVEL9K_AWS_DEFAULT_BACKGROUND=1 + # typeset -g POWERLEVEL9K_AWS_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ aws_eb_env: aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) ]# + # AWS Elastic Beanstalk environment color. + # typeset -g POWERLEVEL9K_AWS_EB_ENV_FOREGROUND=2 + # typeset -g POWERLEVEL9K_AWS_EB_ENV_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_AWS_EB_ENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ azure: azure account name (https://docs.microsoft.com/en-us/cli/azure) ]########## + # Show azure only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show azure. + typeset -g POWERLEVEL9K_AZURE_SHOW_ON_COMMAND='az|terraform|pulumi' + # Azure account name color. + # typeset -g POWERLEVEL9K_AZURE_FOREGROUND=7 + # typeset -g POWERLEVEL9K_AZURE_BACKGROUND=4 + # Custom icon. + # typeset -g POWERLEVEL9K_AZURE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ gcloud: google cloud account and project (https://cloud.google.com/) ]########### + # Show gcloud only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show gcloud. + typeset -g POWERLEVEL9K_GCLOUD_SHOW_ON_COMMAND='gcloud|gcs' + # Google cloud color. + # typeset -g POWERLEVEL9K_GCLOUD_FOREGROUND=7 + # typeset -g POWERLEVEL9K_GCLOUD_BACKGROUND=4 + + # Google cloud format. Change the value of POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION and/or + # POWERLEVEL9K_GCLOUD_COMPLETE_CONTENT_EXPANSION if the default is too verbose or not informative + # enough. You can use the following parameters in the expansions. Each of them corresponds to the + # output of `gcloud` tool. + # + # Parameter | Source + # -------------------------|-------------------------------------------------------------------- + # P9K_GCLOUD_CONFIGURATION | gcloud config configurations list --format='value(name)' + # P9K_GCLOUD_ACCOUNT | gcloud config get-value account + # P9K_GCLOUD_PROJECT_ID | gcloud config get-value project + # P9K_GCLOUD_PROJECT_NAME | gcloud projects describe $P9K_GCLOUD_PROJECT_ID --format='value(name)' + # + # Note: ${VARIABLE//\%/%%} expands to ${VARIABLE} with all occurences of '%' replaced with '%%'. + # + # Obtaining project name requires sending a request to Google servers. This can take a long time + # and even fail. When project name is unknown, P9K_GCLOUD_PROJECT_NAME is not set and gcloud + # prompt segment is in state PARTIAL. When project name gets known, P9K_GCLOUD_PROJECT_NAME gets + # set and gcloud prompt segment transitions to state COMPLETE. + # + # You can customize the format, icon and colors of gcloud segment separately for states PARTIAL + # and COMPLETE. You can also hide gcloud in state PARTIAL by setting + # POWERLEVEL9K_GCLOUD_PARTIAL_VISUAL_IDENTIFIER_EXPANSION and + # POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION to empty. + typeset -g POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION='${P9K_GCLOUD_PROJECT_ID//\%/%%}' + typeset -g POWERLEVEL9K_GCLOUD_COMPLETE_CONTENT_EXPANSION='${P9K_GCLOUD_PROJECT_NAME//\%/%%}' + + # Send a request to Google (by means of `gcloud projects describe ...`) to obtain project name + # this often. Negative value disables periodic polling. In this mode project name is retrieved + # only when the current configuration, account or project id changes. + typeset -g POWERLEVEL9K_GCLOUD_REFRESH_PROJECT_NAME_SECONDS=60 + + # Custom icon. + # typeset -g POWERLEVEL9K_GCLOUD_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ google_app_cred: google application credentials (https://cloud.google.com/docs/authentication/production) ]# + # Show google_app_cred only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show google_app_cred. + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_SHOW_ON_COMMAND='terraform|pulumi' + + # Google application credentials classes for the purpose of using different colors, icons and + # expansions with different credentials. + # + # POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES is an array with even number of elements. The first + # element in each pair defines a pattern against which the current kubernetes context gets + # matched. More specifically, it's P9K_CONTENT prior to the application of context expansion + # (see below) that gets matched. If you unset all POWERLEVEL9K_GOOGLE_APP_CRED_*CONTENT_EXPANSION + # parameters, you'll see this value in your prompt. The second element of each pair in + # POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES defines the context class. Patterns are tried in order. + # The first match wins. + # + # For example, given these settings: + # + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES=( + # '*:*prod*:*' PROD + # '*:*test*:*' TEST + # '*' DEFAULT) + # + # If your current Google application credentials is "service_account deathray-testing x@y.com", + # its class is TEST because it doesn't match the pattern '* *prod* *' but does match '* *test* *'. + # + # You can define different colors, icons and content expansions for different classes: + # + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_FOREGROUND=28 + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_CONTENT_EXPANSION='$P9K_GOOGLE_APP_CRED_PROJECT_ID' + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES=( + # '*:*prod*:*' PROD # These values are examples that are unlikely + # '*:*test*:*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_FOREGROUND=7 + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_BACKGROUND=4 + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Use POWERLEVEL9K_GOOGLE_APP_CRED_CONTENT_EXPANSION to specify the content displayed by + # google_app_cred segment. Parameter expansions are very flexible and fast, too. See reference: + # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion. + # + # You can use the following parameters in the expansion. Each of them corresponds to one of the + # fields in the JSON file pointed to by GOOGLE_APPLICATION_CREDENTIALS. + # + # Parameter | JSON key file field + # ---------------------------------+--------------- + # P9K_GOOGLE_APP_CRED_TYPE | type + # P9K_GOOGLE_APP_CRED_PROJECT_ID | project_id + # P9K_GOOGLE_APP_CRED_CLIENT_EMAIL | client_email + # + # Note: ${VARIABLE//\%/%%} expands to ${VARIABLE} with all occurences of '%' replaced by '%%'. + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_CONTENT_EXPANSION='${P9K_GOOGLE_APP_CRED_PROJECT_ID//\%/%%}' + + ###############################[ public_ip: public IP address ]############################### + # Public IP color. + # typeset -g POWERLEVEL9K_PUBLIC_IP_FOREGROUND=7 + # typeset -g POWERLEVEL9K_PUBLIC_IP_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_PUBLIC_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ########################[ vpn_ip: virtual private network indicator ]######################### + # VPN IP color. + # typeset -g POWERLEVEL9K_VPN_IP_FOREGROUND=0 + # typeset -g POWERLEVEL9K_VPN_IP_BACKGROUND=6 + # When on VPN, show just an icon without the IP address. + # Tip: To display the private IP address when on VPN, remove the next line. + typeset -g POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION= + # Regular expression for the VPN network interface. Run `ifconfig` or `ip -4 a show` while on VPN + # to see the name of the interface. + typeset -g POWERLEVEL9K_VPN_IP_INTERFACE='(wg|(.*tun))[0-9]*' + # If set to true, show one segment per matching network interface. If set to false, show only + # one segment corresponding to the first matching network interface. + # Tip: If you set it to true, you'll probably want to unset POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION. + typeset -g POWERLEVEL9K_VPN_IP_SHOW_ALL=false + # Custom icon. + # typeset -g POWERLEVEL9K_VPN_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ ip: ip address and bandwidth usage for a specified network interface ]########### + # IP color. + typeset -g POWERLEVEL9K_IP_BACKGROUND=4 + typeset -g POWERLEVEL9K_IP_FOREGROUND=0 + # The following parameters are accessible within the expansion: + # + # Parameter | Meaning + # ----------------------+--------------- + # P9K_IP_IP | IP address + # P9K_IP_INTERFACE | network interface + # P9K_IP_RX_BYTES | total number of bytes received + # P9K_IP_TX_BYTES | total number of bytes sent + # P9K_IP_RX_RATE | receive rate (since last prompt) + # P9K_IP_TX_RATE | send rate (since last prompt) + typeset -g POWERLEVEL9K_IP_CONTENT_EXPANSION='${P9K_IP_RX_RATE:+⇣$P9K_IP_RX_RATE }${P9K_IP_TX_RATE:+⇡$P9K_IP_TX_RATE }$P9K_IP_IP' + # Show information for the first network interface whose name matches this regular expression. + # Run `ifconfig` or `ip -4 a show` to see the names of all network interfaces. + typeset -g POWERLEVEL9K_IP_INTERFACE='e.*' + # Custom icon. + # typeset -g POWERLEVEL9K_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #########################[ proxy: system-wide http/https/ftp proxy ]########################## + # Proxy color. + # typeset -g POWERLEVEL9K_PROXY_FOREGROUND=4 + # typeset -g POWERLEVEL9K_PROXY_BACKGROUND=0 + # Custom icon. + # typeset -g POWERLEVEL9K_PROXY_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################################[ battery: internal battery ]################################# + # Show battery in red when it's below this level and not connected to power supply. + typeset -g POWERLEVEL9K_BATTERY_LOW_THRESHOLD=20 + typeset -g POWERLEVEL9K_BATTERY_LOW_FOREGROUND=1 + # Show battery in green when it's charging or fully charged. + typeset -g POWERLEVEL9K_BATTERY_{CHARGING,CHARGED}_FOREGROUND=2 + # Show battery in yellow when it's discharging. + typeset -g POWERLEVEL9K_BATTERY_DISCONNECTED_FOREGROUND=3 + # Battery pictograms going from low to high level of charge. + typeset -g POWERLEVEL9K_BATTERY_STAGES=('%K{232}▁' '%K{232}▂' '%K{232}▃' '%K{232}▄' '%K{232}▅' '%K{232}▆' '%K{232}▇' '%K{232}█') + # Don't show the remaining time to charge/discharge. + typeset -g POWERLEVEL9K_BATTERY_VERBOSE=false + # typeset -g POWERLEVEL9K_BATTERY_BACKGROUND=0 + + #####################################[ wifi: wifi speed ]##################################### + # WiFi color. + # typeset -g POWERLEVEL9K_WIFI_FOREGROUND=0 + # typeset -g POWERLEVEL9K_WIFI_BACKGROUND=4 + # Custom icon. + # typeset -g POWERLEVEL9K_WIFI_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Use different colors and icons depending on signal strength ($P9K_WIFI_BARS). + # + # # Wifi colors and icons for different signal strength levels (low to high). + # typeset -g my_wifi_fg=(0 0 0 0 0) # <-- change these values + # typeset -g my_wifi_icon=('WiFi' 'WiFi' 'WiFi' 'WiFi' 'WiFi') # <-- change these values + # + # typeset -g POWERLEVEL9K_WIFI_CONTENT_EXPANSION='%F{${my_wifi_fg[P9K_WIFI_BARS+1]}}$P9K_WIFI_LAST_TX_RATE Mbps' + # typeset -g POWERLEVEL9K_WIFI_VISUAL_IDENTIFIER_EXPANSION='%F{${my_wifi_fg[P9K_WIFI_BARS+1]}}${my_wifi_icon[P9K_WIFI_BARS+1]}' + # + # The following parameters are accessible within the expansions: + # + # Parameter | Meaning + # ----------------------+--------------- + # P9K_WIFI_SSID | service set identifier, a.k.a. network name + # P9K_WIFI_LINK_AUTH | authentication protocol such as "wpa2-psk" or "none" + # P9K_WIFI_LAST_TX_RATE | wireless transmit rate in megabits per second + # P9K_WIFI_RSSI | signal strength in dBm, from -120 to 0 + # P9K_WIFI_NOISE | noise in dBm, from -120 to 0 + # P9K_WIFI_BARS | signal strength in bars, from 0 to 4 (derived from P9K_WIFI_RSSI and P9K_WIFI_NOISE) + # + # All parameters except P9K_WIFI_BARS are extracted from the output of the following command: + # + # /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I + + ####################################[ time: current time ]#################################### + # Current time color. + # typeset -g POWERLEVEL9K_TIME_FOREGROUND=0 + # typeset -g POWERLEVEL9K_TIME_BACKGROUND=7 + # Format for the current time: 09:51:02. See `man 3 strftime`. + typeset -g POWERLEVEL9K_TIME_FORMAT='%D{%H:%M:%S}' + # If set to true, time will update when you hit enter. This way prompts for the past + # commands will contain the start times of their commands as opposed to the default + # behavior where they contain the end times of their preceding commands. + typeset -g POWERLEVEL9K_TIME_UPDATE_ON_COMMAND=false + # Custom icon. + # typeset -g POWERLEVEL9K_TIME_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_TIME_PREFIX='at ' + + # Example of a user-defined prompt segment. Function prompt_example will be called on every + # prompt if `example` prompt segment is added to POWERLEVEL9K_LEFT_PROMPT_ELEMENTS or + # POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS. It displays an icon and yellow text on red background + # greeting the user. + # + # Type `p10k help segment` for documentation and a more sophisticated example. + function prompt_example() { + p10k segment -b 1 -f 3 -i '⭐' -t 'hello, %n' + } + + # User-defined prompt segments may optionally provide an instant_prompt_* function. Its job + # is to generate the prompt segment for display in instant prompt. See + # https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt. + # + # Powerlevel10k will call instant_prompt_* at the same time as the regular prompt_* function + # and will record all `p10k segment` calls it makes. When displaying instant prompt, Powerlevel10k + # will replay these calls without actually calling instant_prompt_*. It is imperative that + # instant_prompt_* always makes the same `p10k segment` calls regardless of environment. If this + # rule is not observed, the content of instant prompt will be incorrect. + # + # Usually, you should either not define instant_prompt_* or simply call prompt_* from it. If + # instant_prompt_* is not defined for a segment, the segment won't be shown in instant prompt. + function instant_prompt_example() { + # Since prompt_example always makes the same `p10k segment` calls, we can call it from + # instant_prompt_example. This will give us the same `example` prompt segment in the instant + # and regular prompts. + prompt_example + } + + # User-defined prompt segments can be customized the same way as built-in segments. + # typeset -g POWERLEVEL9K_EXAMPLE_FOREGROUND=3 + # typeset -g POWERLEVEL9K_EXAMPLE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Transient prompt works similarly to the builtin transient_rprompt option. It trims down prompt + # when accepting a command line. Supported values: + # + # - off: Don't change prompt when accepting a command line. + # - always: Trim down prompt when accepting a command line. + # - same-dir: Trim down prompt when accepting a command line unless this is the first command + # typed after changing current working directory. + typeset -g POWERLEVEL9K_TRANSIENT_PROMPT=off + + # Instant prompt mode. + # + # - off: Disable instant prompt. Choose this if you've tried instant prompt and found + # it incompatible with your zsh configuration files. + # - quiet: Enable instant prompt and don't print warnings when detecting console output + # during zsh initialization. Choose this if you've read and understood + # https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt. + # - verbose: Enable instant prompt and print a warning when detecting console output during + # zsh initialization. Choose this if you've never tried instant prompt, haven't + # seen the warning, or if you are unsure what this all means. + typeset -g POWERLEVEL9K_INSTANT_PROMPT=verbose + + # Hot reload allows you to change POWERLEVEL9K options after Powerlevel10k has been initialized. + # For example, you can type POWERLEVEL9K_BACKGROUND=red and see your prompt turn red. Hot reload + # can slow down prompt by 1-2 milliseconds, so it's better to keep it turned off unless you + # really need it. + typeset -g POWERLEVEL9K_DISABLE_HOT_RELOAD=true + + # If p10k is already loaded, reload configuration. + # This works even with POWERLEVEL9K_DISABLE_HOT_RELOAD=true. + (( ! $+functions[p10k] )) || p10k reload +} + +# Tell `p10k configure` which file it should overwrite. +typeset -g POWERLEVEL9K_CONFIG_FILE=${${(%):-%x}:a} + +(( ${#p10k_config_opts} )) && setopt ${p10k_config_opts[@]} +'builtin' 'unset' 'p10k_config_opts' diff --git a/config/p10k-robbyrussell.zsh b/config/p10k-robbyrussell.zsh new file mode 100644 index 00000000..7703350e --- /dev/null +++ b/config/p10k-robbyrussell.zsh @@ -0,0 +1,111 @@ +# Config file for Powerlevel10k with the style of robbyrussell theme from Oh My Zsh. +# +# Original: https://github.com/ohmyzsh/ohmyzsh/wiki/Themes#robbyrussell. +# +# Replication of robbyrussell theme is exact. The only observable difference is in +# performance. Powerlevel10k prompt is very fast everywhere, even in large Git repositories. +# +# Usage: Source this file either before or after loading Powerlevel10k. +# +# source ~/powerlevel10k/config/p10k-robbyrussell.zsh +# source ~/powerlevel10k/powerlevel10k.zsh-theme + +# Temporarily change options. +'builtin' 'local' '-a' 'p10k_config_opts' +[[ ! -o 'aliases' ]] || p10k_config_opts+=('aliases') +[[ ! -o 'sh_glob' ]] || p10k_config_opts+=('sh_glob') +[[ ! -o 'no_brace_expand' ]] || p10k_config_opts+=('no_brace_expand') +'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand' + +() { + emulate -L zsh + + # Unset all configuration options. + unset -m 'POWERLEVEL9K_*|DEFAULT_USER' + + # Zsh >= 5.1 is required. + autoload -Uz is-at-least && is-at-least 5.1 || return + + # Left prompt segments. + typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(prompt_char dir vcs) + # Right prompt segments. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=() + + # Basic style options that define the overall prompt look. + typeset -g POWERLEVEL9K_BACKGROUND= # transparent background + typeset -g POWERLEVEL9K_{LEFT,RIGHT}_{LEFT,RIGHT}_WHITESPACE= # no surrounding whitespace + typeset -g POWERLEVEL9K_{LEFT,RIGHT}_SUBSEGMENT_SEPARATOR=' ' # separate segments with a space + typeset -g POWERLEVEL9K_{LEFT,RIGHT}_SEGMENT_SEPARATOR= # no end-of-line symbol + typeset -g POWERLEVEL9K_VISUAL_IDENTIFIER_EXPANSION= # no segment icons + + # Green prompt symbol if the last command succeeded. + typeset -g POWERLEVEL9K_PROMPT_CHAR_OK_{VIINS,VICMD,VIVIS}_FOREGROUND=green + # Red prompt symbol if the last command failed. + typeset -g POWERLEVEL9K_PROMPT_CHAR_ERROR_{VIINS,VICMD,VIVIS}_FOREGROUND=red + # Prompt symbol: bold arrow. + typeset -g POWERLEVEL9K_PROMPT_CHAR_CONTENT_EXPANSION='%B➜ ' + + # Cyan current directory. + typeset -g POWERLEVEL9K_DIR_FOREGROUND=cyan + # Show only the last segment of the current directory. + typeset -g POWERLEVEL9K_SHORTEN_STRATEGY=truncate_to_last + # Bold directory. + typeset -g POWERLEVEL9K_DIR_CONTENT_EXPANSION='%B$P9K_CONTENT' + + # Git status formatter. + function my_git_formatter() { + emulate -L zsh + if [[ -n $P9K_CONTENT ]]; then + # If P9K_CONTENT is not empty, it's either "loading" or from vcs_info (not from + # gitstatus plugin). VCS_STATUS_* parameters are not available in this case. + typeset -g my_git_format=$P9K_CONTENT + else + # Use VCS_STATUS_* parameters to assemble Git status. See reference: + # https://github.com/romkatv/gitstatus/blob/master/gitstatus.plugin.zsh. + typeset -g my_git_format="${1+%B%4F}git:(${1+%1F}" + my_git_format+=${${VCS_STATUS_LOCAL_BRANCH:-${VCS_STATUS_COMMIT[1,8]}}//\%/%%} + my_git_format+="${1+%4F})" + if (( VCS_STATUS_NUM_CONFLICTED || VCS_STATUS_NUM_STAGED || + VCS_STATUS_NUM_UNSTAGED || VCS_STATUS_NUM_UNTRACKED )); then + my_git_format+=" ${1+%3F}✗" + fi + fi + } + functions -M my_git_formatter 2>/dev/null + + # Disable the default Git status formatting. + typeset -g POWERLEVEL9K_VCS_DISABLE_GITSTATUS_FORMATTING=true + # Install our own Git status formatter. + typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION='${$((my_git_formatter(1)))+${my_git_format}}' + typeset -g POWERLEVEL9K_VCS_LOADING_CONTENT_EXPANSION='${$((my_git_formatter()))+${my_git_format}}' + # Grey Git status when loading. + typeset -g POWERLEVEL9K_VCS_LOADING_FOREGROUND=246 + + # Instant prompt mode. + # + # - off: Disable instant prompt. Choose this if you've tried instant prompt and found + # it incompatible with your zsh configuration files. + # - quiet: Enable instant prompt and don't print warnings when detecting console output + # during zsh initialization. Choose this if you've read and understood + # https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt. + # - verbose: Enable instant prompt and print a warning when detecting console output during + # zsh initialization. Choose this if you've never tried instant prompt, haven't + # seen the warning, or if you are unsure what this all means. + typeset -g POWERLEVEL9K_INSTANT_PROMPT=verbose + + # Hot reload allows you to change POWERLEVEL9K options after Powerlevel10k has been initialized. + # For example, you can type POWERLEVEL9K_BACKGROUND=red and see your prompt turn red. Hot reload + # can slow down prompt by 1-2 milliseconds, so it's better to keep it turned off unless you + # really need it. + typeset -g POWERLEVEL9K_DISABLE_HOT_RELOAD=true + + # If p10k is already loaded, reload configuration. + # This works even with POWERLEVEL9K_DISABLE_HOT_RELOAD=true. + (( ! $+functions[p10k] )) || p10k reload +} + +# Tell `p10k configure` which file it should overwrite. +typeset -g POWERLEVEL9K_CONFIG_FILE=${${(%):-%x}:a} + +(( ${#p10k_config_opts} )) && setopt ${p10k_config_opts[@]} +'builtin' 'unset' 'p10k_config_opts' diff --git a/.clang-format b/gitstatus/.clang-format index f5e3c53f..f5e3c53f 100644 --- a/.clang-format +++ b/gitstatus/.clang-format diff --git a/gitstatus/.gitattributes b/gitstatus/.gitattributes new file mode 100644 index 00000000..5c1135cb --- /dev/null +++ b/gitstatus/.gitattributes @@ -0,0 +1,16 @@ +* text=auto + +*.cc text eol=lf +*.h text eol=lf +*.info text eol=lf +*.json text eol=lf +*.md text eol=lf +*.sh text eol=lf +*.zsh text eol=lf + +/.clang-format text eol=lf +/LICENSE text eol=lf +/Makefile text eol=lf +/build text eol=lf +/install text eol=lf +/mbuild text eol=lf diff --git a/gitstatus/.gitignore b/gitstatus/.gitignore new file mode 100644 index 00000000..4915fe60 --- /dev/null +++ b/gitstatus/.gitignore @@ -0,0 +1,8 @@ +*.zwc +/core +/deps/libgit2-*.tar.gz +/locks +/logs +/obj +/usrbin/gitstatusd* +/.vscode/ipch diff --git a/.vscode/c_cpp_properties.json b/gitstatus/.vscode/c_cpp_properties.json index 323a6cde..323a6cde 100644 --- a/.vscode/c_cpp_properties.json +++ b/gitstatus/.vscode/c_cpp_properties.json diff --git a/.vscode/settings.json b/gitstatus/.vscode/settings.json index bec79f94..bec79f94 100644 --- a/.vscode/settings.json +++ b/gitstatus/.vscode/settings.json diff --git a/gitstatus/LICENSE b/gitstatus/LICENSE new file mode 100644 index 00000000..f288702d --- /dev/null +++ b/gitstatus/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<https://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<https://www.gnu.org/licenses/why-not-lgpl.html>. diff --git a/Makefile b/gitstatus/Makefile index d665af1f..d665af1f 100644 --- a/Makefile +++ b/gitstatus/Makefile diff --git a/gitstatus/README.md b/gitstatus/README.md new file mode 100644 index 00000000..24ebf75d --- /dev/null +++ b/gitstatus/README.md @@ -0,0 +1,595 @@ +# gitstatus + +**gitstatus** is a 10x faster alternative to `git status` and `git describe`. Its primary use +case is to enable fast git prompt in interactive shells. + +Heavy lifting is done by **gitstatusd** -- a custom binary written in C++. It comes with Zsh and +Bash bindings for integration with shell. + +## Table of Contents + +1. [Using from Zsh](#using-from-zsh) +1. [Using from Bash](#using-from-bash) +2. [Using from other shells](#using-from-other-shells) +1. [How it works](#how-it-works) +1. [Benchmarks](#benchmarks) +1. [Why fast](#why-fast) +1. [Requirements](#requirements) +1. [Compiling](#compiling) +1. [License](#license) + +## Using from Zsh + +The easiest way to take advantage of gitstatus from Zsh is to use a theme that's already integrated +with it. For example, [Powerlevel10k](https://github.com/romkatv/powerlevel10k) is a flexible and +fast theme with first-class gitstatus integration. + +![Powerlevel10k Zsh Theme]( + https://raw.githubusercontent.com/romkatv/powerlevel10k-media/master/prompt-styles-high-contrast.png) + +For those who wish to use gitstatus without a theme, there is +[gitstatus.prompt.zsh](gitstatus.prompt.zsh). Install it as follows: + +```zsh +git clone --depth=1 https://github.com/romkatv/gitstatus.git ~/gitstatus +echo 'source ~/gitstatus/gitstatus.prompt.zsh' >>! ~/.zshrc +``` + +Users in mainland China can use the official mirror on gitee.com for faster download.<br> +中国大陆用户可以使用 gitee.com 上的官方镜像加速下载. + +```zsh +git clone --depth=1 https://gitee.com/romkatv/gitstatus.git ~/gitstatus +echo 'source ~/gitstatus/gitstatus.prompt.zsh' >>! ~/.zshrc +``` + +Alternatively, on macOS you can install with Homebrew: + +```zsh +brew install romkatv/gitstatus/gitstatus +echo 'source /usr/local/opt/gitstatus/gitstatus.prompt.zsh' >>! ~/.zshrc +``` + +(If you choose this option, replace `~/gitstatus` with `/usr/local/opt/gitstatus` in all code +snippets below.) + +_Make sure to disable your current theme if you have one._ + +This will give you a basic yet functional prompt with git status in it. It's +[over 10x faster](#benchmarks) than any alternative that can give you comparable prompt. In order +to customize it, set `PROMPT` and/or `RPROMPT` at the end of `~/.zshrc` after sourcing +`gitstatus.prompt.zsh`. Insert `${GITSTATUS_PROMPT}` where you want git status to go. For example: + +```zsh +source ~/gitstatus/gitstatus.prompt.zsh + +PROMPT='%~%# ' # left prompt: directory followed by %/# (normal/root) +RPROMPT='$GITSTATUS_PROMPT' # right prompt: git status +``` + +The expansion of `${GITSTATUS_PROMPT}` can contain the following bits: + +| segment | meaning | +|-------------|-------------------------------------------------------| +| `master` | current branch | +| `#v1` | HEAD is tagged with `v1`; not shown when on a branch | +| `@5fc6fca4` | current commit; not shown when on a branch or tag | +| `⇣1` | local branch is behind the remote by 1 commit | +| `⇡2` | local branch is ahead of the remote by 2 commits | +| `⇠3` | local branch is behind the push remote by 3 commits | +| `⇢4` | local branch is ahead of the push remote by 4 commits | +| `*5` | there are 5 stashes | +| `merge` | merge is in progress (could be some other action) | +| `~6` | there are 6 merge conflicts | +| `+7` | there are 7 staged changes | +| `!8` | there are 8 unstaged changes | +| `?9` | there are 9 untracked files | + +`$GITSTATUS_PROMPT_LEN` tells you how long `$GITSTATUS_PROMPT` is when printed to the console. +[gitstatus.prompt.zsh](gitstatus.prompt.zsh) has an example of using it to truncate the current +directory. + +If you'd like to change the format of git status, or want to have greater control over the +process of assembling `PROMPT`, you can copy and modify parts of +[gitstatus.prompt.zsh](gitstatus.prompt.zsh) instead of sourcing the script. Your `~/.zshrc` +might look something like this: + +```zsh +source ~/gitstatus/gitstatus.plugin.zsh + +function my_set_prompt() { + PROMPT='%~%# ' + RPROMPT='' + + if gitstatus_query MY && [[ $VCS_STATUS_RESULT == ok-sync ]]; then + RPROMPT=${${VCS_STATUS_LOCAL_BRANCH:-@${VCS_STATUS_COMMIT}}//\%/%%} # escape % + (( $VCS_STATUS_NUM_STAGED )) && RPROMPT+='+' + (( $VCS_STATUS_NUM_UNSTAGED )) && RPROMPT+='!' + (( $VCS_STATUS_NUM_UNTRACKED )) && RPROMPT+='?' + fi + + setopt no_prompt_{bang,subst} prompt_percent # enable/disable correct prompt expansions +} + +gitstatus_stop 'MY' && gitstatus_start -s -1 -u -1 -c -1 -d -1 'MY' +autoload -Uz add-zsh-hook +add-zsh-hook precmd my_set_prompt +``` + +This snippet is sourcing `gitstatus.plugin.zsh` rather than `gitstatus.prompt.zsh`. The former +defines low-level bindings that communicate with gitstatusd over pipes. The latter is a simple +script that uses these bindings to assemble git prompt. + +Unlike [Powerlevel10k](https://github.com/romkatv/powerlevel10k), code based on +[gitstatus.prompt.zsh](gitstatus.prompt.zsh) is communicating with gitstatusd synchronously. This +can make your prompt slow when working in a large git repository or on a slow machine. To avoid +this problem, call `gitstatus_query` asynchronously as documented in +[gitstatus.plugin.zsh](gitstatus.plugin.zsh). This can be quite challenging. + +## Using from Bash + +The easiest way to take advantage of gitstatus from Bash is via +[gitstatus.prompt.sh](gitstatus.prompt.sh). Install it as follows: + +```bash +git clone --depth=1 https://github.com/romkatv/gitstatus.git ~/gitstatus +echo 'source ~/gitstatus/gitstatus.prompt.sh' >> ~/.bashrc +``` + +Users in mainland China can use the official mirror on gitee.com for faster download.<br> +中国大陆用户可以使用 gitee.com 上的官方镜像加速下载. + +```bash +git clone --depth=1 https://gitee.com/romkatv/gitstatus.git ~/gitstatus +echo 'source ~/gitstatus/gitstatus.prompt.sh' >> ~/.bashrc +``` + +Alternatively, on macOS you can install with Homebrew: + +```zsh +brew install romkatv/gitstatus/gitstatus +echo 'source /usr/local/opt/gitstatus/gitstatus.prompt.sh' >> ~/.bashrc +``` + +(If you choose this option, replace `~/gitstatus` with `/usr/local/opt/gitstatus` in all code +snippets below.) + +This will give you a basic yet functional prompt with git status in it. It's +[over 10x faster](#benchmarks) than any alternative that can give you comparable prompt. + +![Bash Prompt with GitStatus]( + https://raw.githubusercontent.com/romkatv/gitstatus/1ac366952366d89980b3f3484f270b4fa5ae4293/bash-prompt.png) + +In order to customize your prompt, set `PS1` at the end of `~/.bashrc` after sourcing +`gitstatus.prompt.sh`. Insert `${GITSTATUS_PROMPT}` where you want git status to go. For example: + +```bash +source ~/gitstatus/gitstatus.prompt.sh + +PS1='\w ${GITSTATUS_PROMPT}\n\$ ' # directory followed by git status and $/# (normal/root) +``` + +The expansion of `${GITSTATUS_PROMPT}` can contain the following bits: + +| segment | meaning | +|-------------|-------------------------------------------------------| +| `master` | current branch | +| `#v1` | HEAD is tagged with `v1`; not shown when on a branch | +| `@5fc6fca4` | current commit; not shown when on a branch or tag | +| `⇣1` | local branch is behind the remote by 1 commit | +| `⇡2` | local branch is ahead of the remote by 2 commits | +| `⇠3` | local branch is behind the push remote by 3 commits | +| `⇢4` | local branch is ahead of the push remote by 4 commits | +| `*5` | there are 5 stashes | +| `merge` | merge is in progress (could be some other action) | +| `~6` | there are 6 merge conflicts | +| `+7` | there are 7 staged changes | +| `!8` | there are 8 unstaged changes | +| `?9` | there are 9 untracked files | + +If you'd like to change the format of git status, or want to have greater control over the +process of assembling `PS1`, you can copy and modify parts of +[gitstatus.prompt.sh](gitstatus.prompt.sh) instead of sourcing the script. Your `~/.bashrc` might +look something like this: + +```bash +source ~/gitstatus/gitstatus.plugin.sh + +function my_set_prompt() { + PS1='\w' + + if gitstatus_query && [[ "$VCS_STATUS_RESULT" == ok-sync ]]; then + if [[ -n "$VCS_STATUS_LOCAL_BRANCH" ]]; then + PS1+=" ${VCS_STATUS_LOCAL_BRANCH//\\/\\\\}" # escape backslash + else + PS1+=" @${VCS_STATUS_COMMIT//\\/\\\\}" # escape backslash + fi + [[ "$VCS_STATUS_HAS_STAGED" == 1 ]] && PS1+='+' + [[ "$VCS_STATUS_HAS_UNSTAGED" == 1 ]] && PS1+='!' + [[ "$VCS_STATUS_HAS_UNTRACKED" == 1 ]] && PS1+='?' + fi + + PS1+='\n\$ ' + + shopt -u promptvars # disable expansion of '$(...)' and the like +} + +gitstatus_stop && gitstatus_start +PROMPT_COMMAND=my_set_prompt +``` + +This snippet is sourcing `gitstatus.plugin.sh` rather than `gitstatus.prompt.sh`. The former +defines low-level bindings that communicate with gitstatusd over pipes. The latter is a simple +script that uses these bindings to assemble git prompt. + +Note: Bash bindings, unlike Zsh bindings, don't support asynchronous calls. + +## Using from other shells + +If there are no gitstatusd bindings for your shell, you'll need to get your hands dirty. +Use the existing bindings for inspiration; run `gitstatusd --help` or read the same thing in +[options.cc](src/options.cc). + +## How it works + +gitstatusd reads requests from stdin and prints responses to stdout. Requests contain an ID and +a directory. Responses contain the same ID and machine-readable git status for the directory. +gitstatusd keeps some state in memory for the directories it has seen in order to serve future +requests faster. + +[Zsh bindings](gitstatus.plugin.zsh) and [Bash bindings](gitstatus.plugin.sh) start gitstatusd in +the background and communicate with it via pipes. Themes such as +[Powerlevel10k](https://github.com/romkatv/powerlevel10k) use these bindings to put git status in +`PROMPT`. + +Note that gitstatus cannot be used as a drop-in replacement for `git status` command as it doesn't +produce output in the same format. It does perform the same computation though. + +## Benchmarks + +The following benchmark results were obtained on Intel i9-7900X running Ubuntu 18.04 in +a clean [chromium](https://github.com/chromium/chromium) repository synced to `9394e49a`. The +repository was checked out to an ext4 filesystem on M.2 SSD. + +Three functionally equivalent tools for computing git status were benchmarked: + +* `gitstatusd` +* `git` with untracked cache enabled +* `lg2` -- a demo/example executable from [libgit2](https://github.com/romkatv/libgit2) that + implements a subset of `git` functionality on top of libgit2 API; for the purposes of this + benchmark the subset is sufficient to generate the same data as the other tools + +Every tool was benchmark in cold and hot conditions. For `git` the first run in a repository was +considered cold, with the following runs considered hot. `lg2` was patched to compute results twice +in a single invocation without freeing the repository in between; the second run was considered hot. +The same patching was not done for `git` because `git` cannot be easily modified to refresh inmemory +index state between invocations; in fact, this limitation is one of the primary reasons developers +use libgit2. `gitstatusd` was benchmarked similarly to `lg2` with two result computations in the +same invocation. + +Two commands were benchmarked: `status` and `describe`. + +### Status + +In this benchmark all tools were computing the equivalent of `git status`. Lower numbers are better. + +| Tool | Cold | Hot | +|---------------|-----------:|------------:| +| **gitstatus** | **291 ms** | **30.9 ms** | +| git | 876 ms | 295 ms | +| lg2 | 1730 ms | 1310 ms | + +gitstatusd is substantially faster than the alternatives, especially on hot runs. Note that hot runs +are of primary importance to the main use case of gitstatus in interactive shells. + +The performance of `git status` fluctuated wildly in this benchmarks for reasons unknown to the +author. Moreover, performance is sticky -- once `git status` settles around a number, it stays +there for a long time. Numbers as diverse as 295, 352, 663 and 730 had been observed on hot runs on +the same repository. The number in the table is the lowest (fastest or best) that `git status` had +shown. + +### Describe + +In this benchmark all tools were computing the equivalent of `git describe --tags --exact-match` +to find tags that resolve to the same commit as `HEAD`. Lower numbers are better. + +| Tool | Cold | Hot | +|---------------|------------:|--------------:| +| **gitstatus** | **4.04 ms** | **0.0345 ms** | +| git | 18.0 ms | 14.5 ms | +| lg2 | 185 ms | 45.2 ms | + +gitstatusd is once again faster than the alternatives, more so on hot runs. + +## Why fast + +Since gitstatusd doesn't have to print all staged/unstaged/untracked files but only report +whether there are any, it can terminate repository scan early. It can also remember which files +were dirty on the previous run and check them first on the next run to avoid the scan entirely if +the files are still dirty. However, the benchmarks above were performed in a clean repository where +these shortcuts do not trigger. All benchmarked tools had to do the same work -- check the status +of every file in the index to see if it has changed, check every directory for newly created files, +etc. And yet, gitstatusd came ahead by a large margin. This section describes what it does that +makes it so fast. + +Most of the following comparisons are done against libgit2 rather than git because of the author's +familiarity with the former but not the with latter. libgit2 has clean, well-documented APIs and an +elegant implementation, which makes it so much easier to work with and to analyze performance +bottlenecks. + +### Summary for the impatient + +Under the benchmark conditions described above, the equivalent of libgit2's +`git_diff_index_to_workdir` (the most expensive part of `status` command) is 46.3 times faster in +gitstatusd. The speedup comes from the following sources. + +* gitstatusd uses more efficient data structures and algorithms and employs performance-conscious +coding style throughout the codebase. This reduces CPU time in userspace by 32x compared to libgit2. +* gitstatusd uses less expensive system calls and makes fewer of them. This reduces CPU time spent +in kernel by 1.9x. +* gitstatusd can utilize multiple cores to scan index and workdir in parallel with almost perfect +scaling. This reduces total run time by 12.4x while having virtually no effect on total CPU time. + +### Problem statement + +The most resource-intensive part of the `status` command is finding the difference between _index_ +and _workdir_ (`git_diff_index_to_workdir` in libgit2). Index is a list of all files in the git +repository with their last modification times. This is an obvious simplification but it suffices for +this exposition. On disk, index is stored sorted by file path. Here's an example of git index: + +| File | Last modification time | +|-------------|-----------------------:| +| Makefile | 2019-04-01T14:12:32Z | +| src/hello.c | 2019-04-01T14:12:00Z | +| src/hello.h | 2019-04-01T14:12:32Z | + +This list needs to be compared to the list of files in the working directory. If any of the files +listed in the index are missing from the workdir or have different last modification time, they are +"unstaged" in gitstatusd parlance. If you run `git status`, they'll be shown as "changes not staged +for commit". Thus, any implementation of `status` command has to call `stat()` or one of its +variants on every file in the index. + +In addition, all files in the working directory for which there is no entry in the index at all are +"untracked". `git status` will show them as "untracked files". Finding untracked files requires some +form of work directory traversal. + +### Single-threaded scan + +Let's see how `git_diff_index_to_workdir` from libgit2 accomplishes these tasks. Here's its CPU +profile from 200 hot runs over chromium repository. + +![libgit2 CPU profile (hot)]( + https://raw.githubusercontent.com/romkatv/gitstatus/1ac366952366d89980b3f3484f270b4fa5ae4293/cpu-profile-libgit2.png) + +(The CPU profile was created with [gperftools](https://github.com/gperftools/gperftools) and +rendered with [pprof](https://github.com/google/pprof)). + +We can see `__GI__lxstat` taking a lot of time. This is the `stat()` call for every file in the +index. We can also identify `__opendir`, `__readdir` and `__GI___close_nocancel` -- glibc wrappers +for reading the contents of a directory. This is for finding untracked files. Out of the total 232 +seconds, 111 seconds -- or 47.7% -- was spent on these calls. The rest is computation -- comparing +strings, sorting arrays, etc. + +Now let's take a look at the CPU profile of gitstatusd on the same task. + +![gitstatusd CPU profile (hot)]( + https://raw.githubusercontent.com/romkatv/gitstatus/1ac366952366d89980b3f3484f270b4fa5ae4293/cpu-profile-gitstatusd-hot.png) + +The first impression is that this profile looks pruned. This isn't an artifact. The profile was +generated with the same tools and the same flags as the profile of libgit2. + +Since both profiles were generated from the same workload, absolute numbers can be compared. We can +see that gitstatusd took 62 seconds in total compared to libgit2's 232 seconds. System calls at the +core of the algorithm are cleary visible. `__GI___fxstatat` is a flavor of `stat()`, and the other +three calls -- `__libc_openat64`, `__libc_close` and `__GI___fxstat` are responsible for opening +directories and finding untracked files. Notice that there is almost nothing else in the profile +apart from these calls. The rest of the code accounts for 3.77 seconds of CPU time -- 32 times less +than in libgit2. + +So, one reason gitstatusd is fast is that it has efficient diffing code -- very little time is spent +outside of kernel. However, if we look closely, we can notice that system calls in gitstatusd are +_also_ faster than in libgit2. For example, libgit2 spent 72.07 seconds in `__GI__lxstat` while +gitstatusd spent only 48.82 seconds in `__GI___fxstatat`. There are two reasons for this difference. +First, libgit2 makes more `stat()` calls than is strictly required. It's not necessary to stat +directories because index only has files. There are 25k directories in chromium repository (and 300k +files) -- that's 25k `stat()` calls that could be avoided. The second reason is that libgit2 and +gitstatusd use different flavors of `stat()`. libgit2 uses `lstat()`, which takes a path to the file +as input. Its performance is linear in the number of subdirectories in the path because it needs to +perform a lookup for every one of them and to check permissions. gitstatusd uses `fstatat()`, which +takes a file descriptor to the parent directory and a name of the file. Just a single lookup, less +CPU time. + +Similarly to `lstat()` vs `fstatat()`, it's faster to open files and directories with `openat()` +from the parent directory file descriptor than with regular `open()` that accepts full file path. +gitstatusd takes advantage of `openat()` to open directories as fast as possible. It opens about 90% +of the directories (this depends on the actual directory structure of the repository) from the +immediate parent -- the most efficient way -- and the remaining 10% it opens from the repository's +root directory. The reason it's done this way is to keep the maximum number of simultaneously open +file descriptors bounded. libgit2 can have O(repository depth) simultaneously open file descriptors, +which may be OK for a single-threaded application but can balloon to a large number when scans are +done by many threads simultaneously, like in gitstatusd. + +There is no equivalent to `__opendir` or `__readdir` in the gitstatusd profile because it uses the +equivalent of [untracked cache](https://git-scm.com/docs/git-update-index#_untracked_cache) from +git. On the first scan of the workdir gitstatusd lists all files just like libgit2. But, unlike +libgit2, it remembers the last modification time of every directory along with the list of +untracked files under it. On the next scan, gitstatusd can skip listing files in directories whose +last modification time hasn't changed. + +To summarize, here's what gitstatusd was doing when the CPU profile was captured: + +1. `__libc_openat64`: Open every directory for which there are files in the index. +2. `__GI___fxstat`: Check last modification time of the directory. Since it's the same as on the + last scan, this directory has the same list of untracked files as before, which is empty (the + repository is clean). +3. `__GI___fxstatat`: Check last modification time for every file in the index that belongs to this + directory. +4. `__libc_close`: Close the file descriptor to the directory. + +Here's how the very first scan of a repository looks like in gitstatusd: + +![gitstatusd CPU profile (cold)]( + https://raw.githubusercontent.com/romkatv/gitstatus/1ac366952366d89980b3f3484f270b4fa5ae4293/cpu-profile-gitstatusd-cold.png) + +(Some glibc functions are mislabel on this profile. `explicit_bzero` and `__nss_passwd_lookup` are +in reality `strcmp` and `memcmp`.) + +This is a superset of the previous -- hot -- profile, with an extra `syscall` and string sorting for +directory listing. gitstatusd uses `getdents64` Linux system call directly, bypassing the glibc +wrapper that libgit2 uses. This is 23% faster. The details of this optimization can be found in a +[separate document](docs/listdir.md). + +### Multithreading + +The diffing algorithm in gitstatusd was designed from the ground up with the intention of using it +concurrently from multiple threads. With a fast SSD, `status` is CPU bound, so taking advantage of +all available CPU cores is an obvious way to yield results faster. + +gitstatusd exhibits almost perfect scaling from multithreading. Engaging all cores allows it to +produce results 12.4 times faster than in single-threaded execution. This is on Intel i9-7900X with +10 cores (20 with hyperthreading) with single-core frequency of 4.3GHz and all-core frequency of +4.0GHz. + +Note: `git status` also uses all available cores in some parts of its algorithm while `lg2` does +everything in a single thread. + +### Postprocessing + +Once the difference between the index and the workdir is found, we have a list of _candidates_ -- +files that may be unstaged or untracked. To make the final judgement, these files need to be checked +against `.gitignore` rules and a few other things. + +gitstatusd uses [patched libgit2](https://github.com/romkatv/libgit2) for this step. This fork +adds several optimizations that make libgit2 faster. The patched libgit2 performs more than twice +as fast in the benchmark as the original even without changes in the user code (that is, in the +code that uses the libgit2 APIs). The fork also adds several API extensions, most notable of which +is the support for multi-threaded scans. If `lg2 status` is modified to take advantage of these +extensions, it outperforms the original libgit2 by a factor of 18. Lastly, the fork fixes a score of +bugs, most of which become apparent only when using libgit2 from multiple threads. + +_WARNING: Changes to libgit2 are extensive but the testing they underwent isn't. It is +**not recommended** to use the patched libgit2 in production._ + +## Requirements + +* To compile: binutils, cmake, gcc, g++, git and GNU make. +* To run: Linux, macOS, FreeBSD, Android, WSL, Cygwin or MSYS2. + +## Compiling + +There are prebuilt `gitstatusd` binaries in [releases]( + https://github.com/romkatv/gitstatus/releases). When using the official shell bindings +provided by gitstatus, the right binary for your architecture gets downloaded automatically. + +If prebuilt binaries don't work for you, you'll need to get your hands dirty. + +### Compiling for personal use + +```zsh +git clone --depth=1 https://github.com/romkatv/gitstatus.git +cd gitstatus +./build -w -s -d docker +``` + +Users in mainland China can use the official mirror on gitee.com for faster download.<br> +中国大陆用户可以使用 gitee.com 上的官方镜像加速下载. + +```zsh +git clone --depth=1 https://gitee.com/romkatv/gitstatus.git +cd gitstatus +./build -w -s -d docker +``` + +- If it says that `-d docker` is not supported on your OS, remove this flag. +- If it says that `-s` is not supported on your OS, remove this flag. +- If it tell you to install docker but you cannot or don't want to, remove `-d docker`. +- If it says that some command is missing, install it. + +If everything goes well, the newly built binary will appear in `./usrbin`. It'll be picked up +by shell bindings automatically. + +When you update shell bindings, they may refuse to work with the binary you've built earlier. In +this case you'll need to rebuild. + +### Compiling for distribution + +If you want to package gitstatus, it's best to do it based off [releases]( + https://github.com/romkatv/gitstatus/releases). + +The following code should work without patching anything in gitstatus sources. If it doesn't, please +open an issue. + +**IMPORTANT:** *Change version to what you want to package. This example doesn't get updated when +new versions are released.* + +```zsh +# Download and extract gitstatus tarball. +gitstatus_version=1.1.0 # IMPORTANT: CHANGE VERSION TO WHAT YOU WANT +wget https://github.com/romkatv/gitstatus/archive/v"$gitstatus_version".tar.gz +tar -xzf v"$gitstatus_version".tar.gz +cd gitstatus-"$gitstatus_version" + +# Download libgit2 tarball and compile gitstatusd. +./build -w + +# Post-process. +rm ./deps/libgit2-*.tar.gz +for file in *.zsh install; do + zsh -fc "emulate zsh -o no_aliases && zcompile -R -- $file.zwc $file" +done +``` + +This needs binutils, cmake, gcc, g++, git, GNU make, wget, zsh and either shasum or sha256sum. + +Once build completes, *do not delete or move any files*. Package the whole directory as is. Don't +add the directory or any of its subdirectories to `PATH`. + +You probably don't want to build in docker, so don't pass `-d` to `./build`. + +gitstatus depends on a [custom fork of libgit2](https://github.com/romkatv/libgit2/). When you run +`./build -w`, it'll automatically download the appropriate libgit2 tarball and verify its sha256. +If you want to separate the downloading of source tarballs from compilation, you can download the +libgit2 tarball manually and invoke `./build` without `-w`. + +```zsh +# Download and extract gitstatus tarball. +gitstatus_version=1.1.0 # IMPORTANT: CHANGE VERSION TO WHAT YOU WANT +wget https://github.com/romkatv/gitstatus/archive/v"$gitstatus_version".tar.gz +tar -xzf v"$gitstatus_version".tar.gz +cd gitstatus-"$gitstatus_version" + +# Download libgit2 tarball and place it where ./build expects it. +. ./build.info +libgit2_path=./deps/libgit2-"$libgit2_version".tar.gz +libgit2_url=https://github.com/romkatv/libgit2/archive/"$libgit2_version".tar.gz +wget -O "$libgit2_path" "$libgit2_url" + +# Compile gitstatusd. +./build + +# Post-process. +rm ./deps/libgit2-*.tar.gz +for file in *.zsh install; do + zsh -fc "emulate zsh -o no_aliases && zcompile -R -- $file.zwc $file" +done +``` + +Note that the URL and the content of the libgit2 tarball are fully defined by the main gitstatus +tarball. Thus, you can set URLs and sha256 checksums of the two tarball in the same place (package +definition) and update them at the same time when bumping package version. In other words, you don't +have to extract `libgit2_version` programmatically. You can manually copy it from [build.info]( + https://github.com/romkatv/gitstatus/blob/master/build.info) to your package definition, if you +prefer. + +[Powerlevel10k](https://github.com/romkatv/powerlevel10k) has an embedded version of gitstatus. It +must stay that way. If you decide to package both of them, follow the respective instructions from +each project. The embedded gitstatus in Powerlevel10k won't conflict with the standalone gitstatus. +They can have different versions and can coexist within the same Zsh process. Do not attempt to +surgically remove gitstatus from Powerlevel10k, package the result and then force Powerlevel10k to +use a separately packaged gitstatus. Instead, treat Powerlevel10k and gitstatus as independent +projects that don't depend on each other. + +## License + +GNU General Public License v3.0. See [LICENSE](LICENSE). Contributions are covered by the same +license. diff --git a/build.info b/gitstatus/build.info index 80dbc452..80dbc452 100644 --- a/build.info +++ b/gitstatus/build.info diff --git a/deps/.gitkeep b/gitstatus/deps/.gitkeep index e69de29b..e69de29b 100644 --- a/deps/.gitkeep +++ b/gitstatus/deps/.gitkeep diff --git a/docs/listdir.md b/gitstatus/docs/listdir.md index 0939cc18..0939cc18 100644 --- a/docs/listdir.md +++ b/gitstatus/docs/listdir.md diff --git a/gitstatus.plugin.sh b/gitstatus/gitstatus.plugin.sh index 4c9b70f0..4c9b70f0 100644 --- a/gitstatus.plugin.sh +++ b/gitstatus/gitstatus.plugin.sh diff --git a/gitstatus.plugin.zsh b/gitstatus/gitstatus.plugin.zsh index 1fe219e9..1fe219e9 100644 --- a/gitstatus.plugin.zsh +++ b/gitstatus/gitstatus.plugin.zsh diff --git a/gitstatus.prompt.sh b/gitstatus/gitstatus.prompt.sh index b2c67c8d..b2c67c8d 100644 --- a/gitstatus.prompt.sh +++ b/gitstatus/gitstatus.prompt.sh diff --git a/gitstatus.prompt.zsh b/gitstatus/gitstatus.prompt.zsh index 6ad64856..6ad64856 100644 --- a/gitstatus.prompt.zsh +++ b/gitstatus/gitstatus.prompt.zsh diff --git a/install b/gitstatus/install index 126b8339..126b8339 100755 --- a/install +++ b/gitstatus/install diff --git a/install.info b/gitstatus/install.info index 35260b7f..35260b7f 100644 --- a/install.info +++ b/gitstatus/install.info diff --git a/mbuild b/gitstatus/mbuild index c5d5c87f..c5d5c87f 100755 --- a/mbuild +++ b/gitstatus/mbuild diff --git a/src/algorithm.h b/gitstatus/src/algorithm.h index b87b13f0..b87b13f0 100644 --- a/src/algorithm.h +++ b/gitstatus/src/algorithm.h diff --git a/src/arena.cc b/gitstatus/src/arena.cc index 4c137639..4c137639 100644 --- a/src/arena.cc +++ b/gitstatus/src/arena.cc diff --git a/src/arena.h b/gitstatus/src/arena.h index 0bad0bfa..0bad0bfa 100644 --- a/src/arena.h +++ b/gitstatus/src/arena.h diff --git a/src/bits.h b/gitstatus/src/bits.h index c1a7dcb6..c1a7dcb6 100644 --- a/src/bits.h +++ b/gitstatus/src/bits.h diff --git a/src/check.h b/gitstatus/src/check.h index 82dceae1..82dceae1 100644 --- a/src/check.h +++ b/gitstatus/src/check.h diff --git a/src/check_dir_mtime.cc b/gitstatus/src/check_dir_mtime.cc index bb60ffe5..bb60ffe5 100644 --- a/src/check_dir_mtime.cc +++ b/gitstatus/src/check_dir_mtime.cc diff --git a/src/check_dir_mtime.h b/gitstatus/src/check_dir_mtime.h index c9204e95..c9204e95 100644 --- a/src/check_dir_mtime.h +++ b/gitstatus/src/check_dir_mtime.h diff --git a/src/dir.cc b/gitstatus/src/dir.cc index 14bc6ac4..14bc6ac4 100644 --- a/src/dir.cc +++ b/gitstatus/src/dir.cc diff --git a/src/dir.h b/gitstatus/src/dir.h index 42ab29bb..42ab29bb 100644 --- a/src/dir.h +++ b/gitstatus/src/dir.h diff --git a/src/git.cc b/gitstatus/src/git.cc index 029b02bf..029b02bf 100644 --- a/src/git.cc +++ b/gitstatus/src/git.cc diff --git a/src/git.h b/gitstatus/src/git.h index 7e5a6f9d..7e5a6f9d 100644 --- a/src/git.h +++ b/gitstatus/src/git.h diff --git a/src/gitstatus.cc b/gitstatus/src/gitstatus.cc index 35351b85..35351b85 100644 --- a/src/gitstatus.cc +++ b/gitstatus/src/gitstatus.cc diff --git a/src/index.cc b/gitstatus/src/index.cc index ae8ca54c..ae8ca54c 100644 --- a/src/index.cc +++ b/gitstatus/src/index.cc diff --git a/src/index.h b/gitstatus/src/index.h index bbf95673..bbf95673 100644 --- a/src/index.h +++ b/gitstatus/src/index.h diff --git a/src/logging.cc b/gitstatus/src/logging.cc index fb9ac9ea..fb9ac9ea 100644 --- a/src/logging.cc +++ b/gitstatus/src/logging.cc diff --git a/src/logging.h b/gitstatus/src/logging.h index 6ddb2e16..6ddb2e16 100644 --- a/src/logging.h +++ b/gitstatus/src/logging.h diff --git a/src/options.cc b/gitstatus/src/options.cc index 421e5854..421e5854 100644 --- a/src/options.cc +++ b/gitstatus/src/options.cc diff --git a/src/options.h b/gitstatus/src/options.h index 7cbfeed8..7cbfeed8 100644 --- a/src/options.h +++ b/gitstatus/src/options.h diff --git a/src/print.h b/gitstatus/src/print.h index 949f946b..949f946b 100644 --- a/src/print.h +++ b/gitstatus/src/print.h diff --git a/src/repo.cc b/gitstatus/src/repo.cc index d7ea7d3e..d7ea7d3e 100644 --- a/src/repo.cc +++ b/gitstatus/src/repo.cc diff --git a/src/repo.h b/gitstatus/src/repo.h index f243f86e..f243f86e 100644 --- a/src/repo.h +++ b/gitstatus/src/repo.h diff --git a/src/repo_cache.cc b/gitstatus/src/repo_cache.cc index d7f5f9ad..d7f5f9ad 100644 --- a/src/repo_cache.cc +++ b/gitstatus/src/repo_cache.cc diff --git a/src/repo_cache.h b/gitstatus/src/repo_cache.h index 9d14ec06..9d14ec06 100644 --- a/src/repo_cache.h +++ b/gitstatus/src/repo_cache.h diff --git a/src/request.cc b/gitstatus/src/request.cc index 1a81bffb..1a81bffb 100644 --- a/src/request.cc +++ b/gitstatus/src/request.cc diff --git a/src/request.h b/gitstatus/src/request.h index 2cc8baf9..2cc8baf9 100644 --- a/src/request.h +++ b/gitstatus/src/request.h diff --git a/src/response.cc b/gitstatus/src/response.cc index eeb89c44..eeb89c44 100644 --- a/src/response.cc +++ b/gitstatus/src/response.cc diff --git a/src/response.h b/gitstatus/src/response.h index 12de765a..12de765a 100644 --- a/src/response.h +++ b/gitstatus/src/response.h diff --git a/src/scope_guard.h b/gitstatus/src/scope_guard.h index 3a7aa01b..3a7aa01b 100644 --- a/src/scope_guard.h +++ b/gitstatus/src/scope_guard.h diff --git a/src/serialization.h b/gitstatus/src/serialization.h index 42b24098..42b24098 100644 --- a/src/serialization.h +++ b/gitstatus/src/serialization.h diff --git a/src/stat.h b/gitstatus/src/stat.h index 4f3195a7..4f3195a7 100644 --- a/src/stat.h +++ b/gitstatus/src/stat.h diff --git a/src/string_cmp.h b/gitstatus/src/string_cmp.h index 621c724c..621c724c 100644 --- a/src/string_cmp.h +++ b/gitstatus/src/string_cmp.h diff --git a/src/string_view.h b/gitstatus/src/string_view.h index e29414b5..e29414b5 100644 --- a/src/string_view.h +++ b/gitstatus/src/string_view.h diff --git a/src/strings.cc b/gitstatus/src/strings.cc index a68835d7..a68835d7 100644 --- a/src/strings.cc +++ b/gitstatus/src/strings.cc diff --git a/src/strings.h b/gitstatus/src/strings.h index a57cf20d..a57cf20d 100644 --- a/src/strings.h +++ b/gitstatus/src/strings.h diff --git a/src/tag_db.cc b/gitstatus/src/tag_db.cc index 0e440791..0e440791 100644 --- a/src/tag_db.cc +++ b/gitstatus/src/tag_db.cc diff --git a/src/tag_db.h b/gitstatus/src/tag_db.h index b5b14a48..b5b14a48 100644 --- a/src/tag_db.h +++ b/gitstatus/src/tag_db.h diff --git a/src/thread_pool.cc b/gitstatus/src/thread_pool.cc index b37eb203..b37eb203 100644 --- a/src/thread_pool.cc +++ b/gitstatus/src/thread_pool.cc diff --git a/src/thread_pool.h b/gitstatus/src/thread_pool.h index 1e39b915..1e39b915 100644 --- a/src/thread_pool.h +++ b/gitstatus/src/thread_pool.h diff --git a/src/time.h b/gitstatus/src/time.h index cdd5fa27..cdd5fa27 100644 --- a/src/time.h +++ b/gitstatus/src/time.h diff --git a/src/timer.cc b/gitstatus/src/timer.cc index 0e9f64e9..0e9f64e9 100644 --- a/src/timer.cc +++ b/gitstatus/src/timer.cc diff --git a/src/timer.h b/gitstatus/src/timer.h index 51c557ca..51c557ca 100644 --- a/src/timer.h +++ b/gitstatus/src/timer.h diff --git a/src/tribool.h b/gitstatus/src/tribool.h index f06daf30..f06daf30 100644 --- a/src/tribool.h +++ b/gitstatus/src/tribool.h diff --git a/usrbin/.gitkeep b/gitstatus/usrbin/.gitkeep index e69de29b..e69de29b 100644 --- a/usrbin/.gitkeep +++ b/gitstatus/usrbin/.gitkeep diff --git a/internal/configure.zsh b/internal/configure.zsh new file mode 100644 index 00000000..5b3df9ad --- /dev/null +++ b/internal/configure.zsh @@ -0,0 +1,70 @@ +typeset -gr __p9k_wizard_columns=51 +typeset -gr __p9k_wizard_lines=12 +typeset -gr __p9k_zd=${ZDOTDIR:-$HOME} +typeset -gr __p9k_zd_u=${${${(q)__p9k_zd}/#(#b)${(q)HOME}(|\/*)/'~'$match[1]}//\%/%%} +typeset -gr __p9k_zshrc=${${:-$__p9k_zd/.zshrc}:A} +typeset -gr __p9k_zshrc_u=$__p9k_zd_u/.zshrc +typeset -gr __p9k_root_dir_u=${${${(q)__p9k_root_dir}/#(#b)${(q)HOME}(|\/*)/'~'$match[1]}//\%/%%} + +function _p9k_can_configure() { + [[ $1 == '-q' ]] && local -i q=1 || local -i q=0 + function $0_error() { + (( q )) || print -rP "%1F[ERROR]%f %Bp10k configure%b: $1" >&2 + } + typeset -g __p9k_cfg_path_o=${POWERLEVEL9K_CONFIG_FILE:=${ZDOTDIR:-~}/.p10k.zsh} + typeset -g __p9k_cfg_basename=${__p9k_cfg_path_o:t} + typeset -g __p9k_cfg_path=${__p9k_cfg_path_o:A} + typeset -g __p9k_cfg_path_u=${${${(q)__p9k_cfg_path_o}/#(#b)${(q)HOME}(|\/*)/'~'$match[1]}//\%/%%} + { + [[ -o multibyte ]] || { $0_error "multibyte option is not set"; return 1 } + [[ -e $__p9k_zd ]] || { $0_error "$__p9k_zd_u does not exist"; return 1 } + [[ -d $__p9k_zd ]] || { $0_error "$__p9k_zd_u is not a directory"; return 1 } + [[ -w $__p9k_zd ]] || { $0_error "$__p9k_zd_u is not writable"; return 1 } + [[ ! -d $__p9k_cfg_path ]] || { $0_error "$__p9k_cfg_path_u is a directory"; return 1 } + [[ ! -d $__p9k_zshrc ]] || { $0_error "$__p9k_zshrc_u is a directory"; return 1 } + + [[ ! -e $__p9k_cfg_path || -f $__p9k_cfg_path || -h $__p9k_cfg_path ]] || { + $0_error "$__p9k_cfg_path_u is a special file" + return 1 + } + [[ ! -e $__p9k_zshrc || -f $__p9k_zshrc || -h $__p9k_zshrc ]] || { + $0_error "$__p9k_zshrc_u a special file" + return 1 + } + [[ ! -e $__p9k_zshrc || -r $__p9k_zshrc ]] || { + $0_error "$__p9k_zshrc_u is not readable" + return 1 + } + local style + for style in lean lean-8colors classic rainbow pure; do + [[ -r $__p9k_root_dir/config/p10k-$style.zsh ]] || { + $0_error "$__p9k_root_dir_u/config/p10k-$style.zsh is not readable" + return 1 + } + done + + (( LINES >= __p9k_wizard_lines && COLUMNS >= __p9k_wizard_columns )) || { + $0_error "terminal size too small; must be at least $__p9k_wizard_columns x $__p9k_wizard_lines" + return 1 + } + [[ -t 0 && -t 1 ]] || { $0_error "no TTY"; return 2 } + return 0 + } always { + unfunction $0_error + } +} + +function p9k_configure() { + eval "$__p9k_intro" + _p9k_can_configure || return + ( + set -- -f + source $__p9k_root_dir/internal/wizard.zsh + ) + local ret=$? + case $ret in + 0) source $__p9k_cfg_path; _p9k__force_must_init=1;; + 69) return 0;; + *) return $ret;; + esac +} diff --git a/internal/icons.zsh b/internal/icons.zsh new file mode 100644 index 00000000..403beea6 --- /dev/null +++ b/internal/icons.zsh @@ -0,0 +1,831 @@ +typeset -gA icons + +function _p9k_init_icons() { + [[ $_p9k__icon_mode == $POWERLEVEL9K_MODE/$POWERLEVEL9K_LEGACY_ICON_SPACING/$POWERLEVEL9K_ICON_PADDING ]] && return + typeset -g _p9k__icon_mode=$POWERLEVEL9K_MODE/$POWERLEVEL9K_LEGACY_ICON_SPACING/$POWERLEVEL9K_ICON_PADDING + + if [[ $POWERLEVEL9K_LEGACY_ICON_SPACING == true ]]; then + local s= + local q=' ' + else + local s=' ' + local q= + fi + + case $POWERLEVEL9K_MODE in + 'flat'|'awesome-patched') + # Awesome-Patched Font required! See: + # https://github.com/gabrielelana/awesome-terminal-fonts/tree/patching-strategy/patched + icons=( + RULER_CHAR '\u2500' # ─ + 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'$s # ↵ + ROOT_ICON '\uE801' # + SUDO_ICON '\uE0A2' # + RUBY_ICON '\uE847 ' # + AWS_ICON '\uE895'$s # + AWS_EB_ICON '\U1F331'$q # 🌱 + BACKGROUND_JOBS_ICON '\uE82F ' # + TEST_ICON '\uE891'$s # + TODO_ICON '\u2611' # ☑ + BATTERY_ICON '\uE894'$s # + DISK_ICON '\uE1AE ' # + OK_ICON '\u2714' # ✔ + FAIL_ICON '\u2718' # ✘ + SYMFONY_ICON 'SF' + NODE_ICON '\u2B22'$s # ⬢ + NODEJS_ICON '\u2B22'$s # ⬢ + MULTILINE_FIRST_PROMPT_PREFIX '\u256D\U2500' # ╭─ + MULTILINE_NEWLINE_PROMPT_PREFIX '\u251C\U2500' # ├─ + MULTILINE_LAST_PROMPT_PREFIX '\u2570\U2500 ' # ╰─ + APPLE_ICON '\uE26E'$s # + WINDOWS_ICON '\uE26F'$s # + FREEBSD_ICON '\U1F608'$q # 😈 + ANDROID_ICON '\uE270'$s # + LINUX_ICON '\uE271'$s # + LINUX_ARCH_ICON '\uE271'$s # + LINUX_DEBIAN_ICON '\uE271'$s # + LINUX_RASPBIAN_ICON '\uE271'$s # + LINUX_UBUNTU_ICON '\uE271'$s # + LINUX_CENTOS_ICON '\uE271'$s # + LINUX_COREOS_ICON '\uE271'$s # + LINUX_ELEMENTARY_ICON '\uE271'$s # + LINUX_MINT_ICON '\uE271'$s # + LINUX_FEDORA_ICON '\uE271'$s # + LINUX_GENTOO_ICON '\uE271'$s # + LINUX_MAGEIA_ICON '\uE271'$s # + LINUX_NIXOS_ICON '\uE271'$s # + LINUX_MANJARO_ICON '\uE271'$s # + LINUX_DEVUAN_ICON '\uE271'$s # + LINUX_ALPINE_ICON '\uE271'$s # + LINUX_AOSC_ICON '\uE271'$s # + LINUX_OPENSUSE_ICON '\uE271'$s # + LINUX_SABAYON_ICON '\uE271'$s # + LINUX_SLACKWARE_ICON '\uE271'$s # + LINUX_VOID_ICON '\uE271'$s # + SUNOS_ICON '\U1F31E'$q # 🌞 + HOME_ICON '\uE12C'$s # + HOME_SUB_ICON '\uE18D'$s # + FOLDER_ICON '\uE818'$s # + NETWORK_ICON '\uE1AD'$s # + ETC_ICON '\uE82F'$s # + LOAD_ICON '\uE190 ' # + SWAP_ICON '\uE87D'$s # + RAM_ICON '\uE1E2 ' # + SERVER_ICON '\uE895'$s # + VCS_UNTRACKED_ICON '\uE16C'$s # + VCS_UNSTAGED_ICON '\uE17C'$s # + VCS_STAGED_ICON '\uE168'$s # + 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 '\u2192' # → + VCS_LOADING_ICON '' + VCS_GIT_ICON '\uE20E ' # + VCS_GIT_GITHUB_ICON '\uE20E ' # + VCS_GIT_BITBUCKET_ICON '\uE20E ' # + VCS_GIT_GITLAB_ICON '\uE20E ' # + VCS_HG_ICON '\uE1C3 ' # + VCS_SVN_ICON 'svn'$q + RUST_ICON 'R' + PYTHON_ICON '\uE63C'$s # (doesn't always work) + SWIFT_ICON 'Swift' + GO_ICON 'Go' + GOLANG_ICON 'Go' + PUBLIC_IP_ICON 'IP' + LOCK_ICON '\UE138' # + NORDVPN_ICON '\UE138' # + EXECUTION_TIME_ICON '\UE89C'$s # + SSH_ICON 'ssh' + VPN_ICON '\UE138' + KUBERNETES_ICON '\U2388'$s # ⎈ + DROPBOX_ICON '\UF16B'$s # (doesn't always work) + DATE_ICON '\uE184'$s # + TIME_ICON '\uE12E'$s # + JAVA_ICON '\U2615' # ☕︎ + LARAVEL_ICON '' + RANGER_ICON '\u2B50' # ⭐ + MIDNIGHT_COMMANDER_ICON 'mc' + VIM_ICON 'vim' + TERRAFORM_ICON 'tf' + PROXY_ICON '\u2194' # ↔ + DOTNET_ICON '.NET' + DOTNET_CORE_ICON '.NET' + AZURE_ICON '\u2601' # ☁ + DIRENV_ICON '\u25BC' # ▼ + FLUTTER_ICON 'F' + GCLOUD_ICON 'G' + LUA_ICON 'lua' + PERL_ICON 'perl' + NNN_ICON 'nnn' + TIMEWARRIOR_ICON 'tw' + TASKWARRIOR_ICON 'task' + NIX_SHELL_ICON 'nix' + WIFI_ICON 'WiFi' + ERLANG_ICON 'erl' + ELIXIR_ICON 'elixir' + POSTGRES_ICON 'postgres' + PHP_ICON 'php' + HASKELL_ICON 'hs' + PACKAGE_ICON 'pkg' + ) + ;; + 'awesome-fontconfig') + # fontconfig with awesome-font required! See + # https://github.com/gabrielelana/awesome-terminal-fonts + icons=( + RULER_CHAR '\u2500' # ─ + 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 '\uF201'$s # + SUDO_ICON '\uF09C'$s # + RUBY_ICON '\uF219 ' # + AWS_ICON '\uF270'$s # + AWS_EB_ICON '\U1F331'$q # 🌱 + BACKGROUND_JOBS_ICON '\uF013 ' # + TEST_ICON '\uF291'$s # + TODO_ICON '\u2611' # ☑ + BATTERY_ICON '\U1F50B' # 🔋 + DISK_ICON '\uF0A0 ' # + OK_ICON '\u2714' # ✔ + FAIL_ICON '\u2718' # ✘ + SYMFONY_ICON 'SF' + NODE_ICON '\u2B22' # ⬢ + NODEJS_ICON '\u2B22' # ⬢ + MULTILINE_FIRST_PROMPT_PREFIX '\u256D\U2500' # ╭─ + MULTILINE_NEWLINE_PROMPT_PREFIX '\u251C\U2500' # ├─ + MULTILINE_LAST_PROMPT_PREFIX '\u2570\U2500 ' # ╰─ + APPLE_ICON '\uF179'$s # + WINDOWS_ICON '\uF17A'$s # + FREEBSD_ICON '\U1F608'$q # 😈 + ANDROID_ICON '\uE17B'$s # (doesn't always work) + LINUX_ICON '\uF17C'$s # + LINUX_ARCH_ICON '\uF17C'$s # + LINUX_DEBIAN_ICON '\uF17C'$s # + LINUX_RASPBIAN_ICON '\uF17C'$s # + LINUX_UBUNTU_ICON '\uF17C'$s # + LINUX_CENTOS_ICON '\uF17C'$s # + LINUX_COREOS_ICON '\uF17C'$s # + LINUX_ELEMENTARY_ICON '\uF17C'$s # + LINUX_MINT_ICON '\uF17C'$s # + LINUX_FEDORA_ICON '\uF17C'$s # + LINUX_GENTOO_ICON '\uF17C'$s # + LINUX_MAGEIA_ICON '\uF17C'$s # + LINUX_NIXOS_ICON '\uF17C'$s # + LINUX_MANJARO_ICON '\uF17C'$s # + LINUX_DEVUAN_ICON '\uF17C'$s # + LINUX_ALPINE_ICON '\uF17C'$s # + LINUX_AOSC_ICON '\uF17C'$s # + LINUX_OPENSUSE_ICON '\uF17C'$s # + LINUX_SABAYON_ICON '\uF17C'$s # + LINUX_SLACKWARE_ICON '\uF17C'$s # + LINUX_VOID_ICON '\uF17C'$s # + SUNOS_ICON '\uF185 ' # + HOME_ICON '\uF015'$s # + HOME_SUB_ICON '\uF07C'$s # + FOLDER_ICON '\uF115'$s # + ETC_ICON '\uF013 ' # + NETWORK_ICON '\uF09E'$s # + LOAD_ICON '\uF080 ' # + SWAP_ICON '\uF0E4'$s # + RAM_ICON '\uF0E4'$s # + SERVER_ICON '\uF233'$s # + VCS_UNTRACKED_ICON '\uF059'$s # + VCS_UNSTAGED_ICON '\uF06A'$s # + VCS_STAGED_ICON '\uF055'$s # + 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 '\u2192' # → + VCS_LOADING_ICON '' + VCS_GIT_ICON '\uF1D3 ' # + VCS_GIT_GITHUB_ICON '\uF113 ' # + VCS_GIT_BITBUCKET_ICON '\uF171 ' # + VCS_GIT_GITLAB_ICON '\uF296 ' # + VCS_HG_ICON '\uF0C3 ' # + VCS_SVN_ICON 'svn'$q + RUST_ICON '\uE6A8' # + PYTHON_ICON '\uE63C'$s # + SWIFT_ICON 'Swift' + GO_ICON 'Go' + GOLANG_ICON 'Go' + PUBLIC_IP_ICON 'IP' + LOCK_ICON '\UF023' # + NORDVPN_ICON '\UF023' # + EXECUTION_TIME_ICON '\uF253'$s # + SSH_ICON 'ssh' + VPN_ICON '\uF023' + KUBERNETES_ICON '\U2388' # ⎈ + DROPBOX_ICON '\UF16B'$s # + DATE_ICON '\uF073 ' # + TIME_ICON '\uF017 ' # + JAVA_ICON '\U2615' # ☕︎ + LARAVEL_ICON '' + RANGER_ICON '\u2B50' # ⭐ + MIDNIGHT_COMMANDER_ICON 'mc' + VIM_ICON 'vim' + TERRAFORM_ICON 'tf' + PROXY_ICON '\u2194' # ↔ + DOTNET_ICON '.NET' + DOTNET_CORE_ICON '.NET' + AZURE_ICON '\u2601' # ☁ + DIRENV_ICON '\u25BC' # ▼ + FLUTTER_ICON 'F' + GCLOUD_ICON 'G' + LUA_ICON 'lua' + PERL_ICON 'perl' + NNN_ICON 'nnn' + TIMEWARRIOR_ICON 'tw' + TASKWARRIOR_ICON 'task' + NIX_SHELL_ICON 'nix' + WIFI_ICON 'WiFi' + ERLANG_ICON 'erl' + ELIXIR_ICON 'elixir' + POSTGRES_ICON 'postgres' + PHP_ICON 'php' + HASKELL_ICON 'hs' + PACKAGE_ICON 'pkg' + ) + ;; + 'awesome-mapped-fontconfig') + # mapped fontconfig with awesome-font required! See + # https://github.com/gabrielelana/awesome-terminal-fonts + # don't forget to source the font maps in your startup script + if [ -z "$AWESOME_GLYPHS_LOADED" ]; then + echo "Powerlevel9k warning: Awesome-Font mappings have not been loaded. + Source a font mapping in your shell config, per the Awesome-Font docs + (https://github.com/gabrielelana/awesome-terminal-fonts), + Or use a different Powerlevel9k font configuration."; + fi + icons=( + RULER_CHAR '\u2500' # ─ + 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 "${CODEPOINT_OF_OCTICONS_ZAP:+\\u$CODEPOINT_OF_OCTICONS_ZAP}" + SUDO_ICON "${CODEPOINT_OF_AWESOME_UNLOCK:+\\u$CODEPOINT_OF_AWESOME_UNLOCK$s}" + RUBY_ICON "${CODEPOINT_OF_OCTICONS_RUBY:+\\u$CODEPOINT_OF_OCTICONS_RUBY }" + AWS_ICON "${CODEPOINT_OF_AWESOME_SERVER:+\\u$CODEPOINT_OF_AWESOME_SERVER$s}" + AWS_EB_ICON '\U1F331'$q # 🌱 + BACKGROUND_JOBS_ICON "${CODEPOINT_OF_AWESOME_COG:+\\u$CODEPOINT_OF_AWESOME_COG }" + TEST_ICON "${CODEPOINT_OF_AWESOME_BUG:+\\u$CODEPOINT_OF_AWESOME_BUG$s}" + TODO_ICON "${CODEPOINT_OF_AWESOME_CHECK_SQUARE_O:+\\u$CODEPOINT_OF_AWESOME_CHECK_SQUARE_O$s}" + BATTERY_ICON "${CODEPOINT_OF_AWESOME_BATTERY_FULL:+\\U$CODEPOINT_OF_AWESOME_BATTERY_FULL$s}" + DISK_ICON "${CODEPOINT_OF_AWESOME_HDD_O:+\\u$CODEPOINT_OF_AWESOME_HDD_O }" + OK_ICON "${CODEPOINT_OF_AWESOME_CHECK:+\\u$CODEPOINT_OF_AWESOME_CHECK$s}" + FAIL_ICON "${CODEPOINT_OF_AWESOME_TIMES:+\\u$CODEPOINT_OF_AWESOME_TIMES}" + SYMFONY_ICON 'SF' + NODE_ICON '\u2B22' # ⬢ + NODEJS_ICON '\u2B22' # ⬢ + MULTILINE_FIRST_PROMPT_PREFIX '\u256D\U2500' # ╭─ + MULTILINE_NEWLINE_PROMPT_PREFIX '\u251C\U2500' # ├─ + MULTILINE_LAST_PROMPT_PREFIX '\u2570\U2500 ' # ╰─ + APPLE_ICON "${CODEPOINT_OF_AWESOME_APPLE:+\\u$CODEPOINT_OF_AWESOME_APPLE$s}" + FREEBSD_ICON '\U1F608'$q # 😈 + LINUX_ICON "${CODEPOINT_OF_AWESOME_LINUX:+\\u$CODEPOINT_OF_AWESOME_LINUX$s}" + LINUX_ARCH_ICON "${CODEPOINT_OF_AWESOME_LINUX:+\\u$CODEPOINT_OF_AWESOME_LINUX$s}" + LINUX_DEBIAN_ICON "${CODEPOINT_OF_AWESOME_LINUX:+\\u$CODEPOINT_OF_AWESOME_LINUX$s}" + LINUX_RASPBIAN_ICON "${CODEPOINT_OF_AWESOME_LINUX:+\\u$CODEPOINT_OF_AWESOME_LINUX$s}" + LINUX_UBUNTU_ICON "${CODEPOINT_OF_AWESOME_LINUX:+\\u$CODEPOINT_OF_AWESOME_LINUX$s}" + LINUX_CENTOS_ICON "${CODEPOINT_OF_AWESOME_LINUX:+\\u$CODEPOINT_OF_AWESOME_LINUX$s}" + LINUX_COREOS_ICON "${CODEPOINT_OF_AWESOME_LINUX:+\\u$CODEPOINT_OF_AWESOME_LINUX$s}" + LINUX_ELEMENTARY_ICON "${CODEPOINT_OF_AWESOME_LINUX:+\\u$CODEPOINT_OF_AWESOME_LINUX$s}" + LINUX_MINT_ICON "${CODEPOINT_OF_AWESOME_LINUX:+\\u$CODEPOINT_OF_AWESOME_LINUX$s}" + LINUX_FEDORA_ICON "${CODEPOINT_OF_AWESOME_LINUX:+\\u$CODEPOINT_OF_AWESOME_LINUX$s}" + LINUX_GENTOO_ICON "${CODEPOINT_OF_AWESOME_LINUX:+\\u$CODEPOINT_OF_AWESOME_LINUX$s}" + LINUX_MAGEIA_ICON "${CODEPOINT_OF_AWESOME_LINUX:+\\u$CODEPOINT_OF_AWESOME_LINUX$s}" + LINUX_NIXOS_ICON "${CODEPOINT_OF_AWESOME_LINUX:+\\u$CODEPOINT_OF_AWESOME_LINUX$s}" + LINUX_MANJARO_ICON "${CODEPOINT_OF_AWESOME_LINUX:+\\u$CODEPOINT_OF_AWESOME_LINUX$s}" + LINUX_DEVUAN_ICON "${CODEPOINT_OF_AWESOME_LINUX:+\\u$CODEPOINT_OF_AWESOME_LINUX$s}" + LINUX_ALPINE_ICON "${CODEPOINT_OF_AWESOME_LINUX:+\\u$CODEPOINT_OF_AWESOME_LINUX$s}" + LINUX_AOSC_ICON "${CODEPOINT_OF_AWESOME_LINUX:+\\u$CODEPOINT_OF_AWESOME_LINUX$s}" + LINUX_OPENSUSE_ICON "${CODEPOINT_OF_AWESOME_LINUX:+\\u$CODEPOINT_OF_AWESOME_LINUX$s}" + LINUX_SABAYON_ICON "${CODEPOINT_OF_AWESOME_LINUX:+\\u$CODEPOINT_OF_AWESOME_LINUX$s}" + LINUX_SLACKWARE_ICON "${CODEPOINT_OF_AWESOME_LINUX:+\\u$CODEPOINT_OF_AWESOME_LINUX$s}" + LINUX_VOID_ICON "${CODEPOINT_OF_AWESOME_LINUX:+\\u$CODEPOINT_OF_AWESOME_LINUX$s}" + SUNOS_ICON "${CODEPOINT_OF_AWESOME_SUN_O:+\\u$CODEPOINT_OF_AWESOME_SUN_O }" + HOME_ICON "${CODEPOINT_OF_AWESOME_HOME:+\\u$CODEPOINT_OF_AWESOME_HOME$s}" + HOME_SUB_ICON "${CODEPOINT_OF_AWESOME_FOLDER_OPEN:+\\u$CODEPOINT_OF_AWESOME_FOLDER_OPEN$s}" + FOLDER_ICON "${CODEPOINT_OF_AWESOME_FOLDER_O:+\\u$CODEPOINT_OF_AWESOME_FOLDER_O$s}" + ETC_ICON "${CODEPOINT_OF_AWESOME_COG:+\\u$CODEPOINT_OF_AWESOME_COG }" + NETWORK_ICON "${CODEPOINT_OF_AWESOME_RSS:+\\u$CODEPOINT_OF_AWESOME_RSS$s}" + LOAD_ICON "${CODEPOINT_OF_AWESOME_BAR_CHART:+\\u$CODEPOINT_OF_AWESOME_BAR_CHART }" + SWAP_ICON "${CODEPOINT_OF_AWESOME_DASHBOARD:+\\u$CODEPOINT_OF_AWESOME_DASHBOARD$s}" + RAM_ICON "${CODEPOINT_OF_AWESOME_DASHBOARD:+\\u$CODEPOINT_OF_AWESOME_DASHBOARD$s}" + SERVER_ICON "${CODEPOINT_OF_AWESOME_SERVER:+\\u$CODEPOINT_OF_AWESOME_SERVER$s}" + VCS_UNTRACKED_ICON "${CODEPOINT_OF_AWESOME_QUESTION_CIRCLE:+\\u$CODEPOINT_OF_AWESOME_QUESTION_CIRCLE$s}" + VCS_UNSTAGED_ICON "${CODEPOINT_OF_AWESOME_EXCLAMATION_CIRCLE:+\\u$CODEPOINT_OF_AWESOME_EXCLAMATION_CIRCLE$s}" + VCS_STAGED_ICON "${CODEPOINT_OF_AWESOME_PLUS_CIRCLE:+\\u$CODEPOINT_OF_AWESOME_PLUS_CIRCLE$s}" + VCS_STASH_ICON "${CODEPOINT_OF_AWESOME_INBOX:+\\u$CODEPOINT_OF_AWESOME_INBOX }" + VCS_INCOMING_CHANGES_ICON "${CODEPOINT_OF_AWESOME_ARROW_CIRCLE_DOWN:+\\u$CODEPOINT_OF_AWESOME_ARROW_CIRCLE_DOWN }" + VCS_OUTGOING_CHANGES_ICON "${CODEPOINT_OF_AWESOME_ARROW_CIRCLE_UP:+\\u$CODEPOINT_OF_AWESOME_ARROW_CIRCLE_UP }" + VCS_TAG_ICON "${CODEPOINT_OF_AWESOME_TAG:+\\u$CODEPOINT_OF_AWESOME_TAG }" + VCS_BOOKMARK_ICON "${CODEPOINT_OF_OCTICONS_BOOKMARK:+\\u$CODEPOINT_OF_OCTICONS_BOOKMARK}" + VCS_COMMIT_ICON "${CODEPOINT_OF_OCTICONS_GIT_COMMIT:+\\u$CODEPOINT_OF_OCTICONS_GIT_COMMIT }" + VCS_BRANCH_ICON "${CODEPOINT_OF_OCTICONS_GIT_BRANCH:+\\u$CODEPOINT_OF_OCTICONS_GIT_BRANCH }" + VCS_REMOTE_BRANCH_ICON "${CODEPOINT_OF_OCTICONS_REPO_PUSH:+\\u$CODEPOINT_OF_OCTICONS_REPO_PUSH$s}" + VCS_LOADING_ICON '' + VCS_GIT_ICON "${CODEPOINT_OF_AWESOME_GIT:+\\u$CODEPOINT_OF_AWESOME_GIT }" + VCS_GIT_GITHUB_ICON "${CODEPOINT_OF_AWESOME_GITHUB_ALT:+\\u$CODEPOINT_OF_AWESOME_GITHUB_ALT }" + VCS_GIT_BITBUCKET_ICON "${CODEPOINT_OF_AWESOME_BITBUCKET:+\\u$CODEPOINT_OF_AWESOME_BITBUCKET }" + VCS_GIT_GITLAB_ICON "${CODEPOINT_OF_AWESOME_GITLAB:+\\u$CODEPOINT_OF_AWESOME_GITLAB }" + VCS_HG_ICON "${CODEPOINT_OF_AWESOME_FLASK:+\\u$CODEPOINT_OF_AWESOME_FLASK }" + VCS_SVN_ICON 'svn'$q + RUST_ICON '\uE6A8' # + PYTHON_ICON '\U1F40D' # 🐍 + SWIFT_ICON '\uE655'$s # + PUBLIC_IP_ICON "${CODEPOINT_OF_AWESOME_GLOBE:+\\u$CODEPOINT_OF_AWESOME_GLOBE$s}" + LOCK_ICON "${CODEPOINT_OF_AWESOME_LOCK:+\\u$CODEPOINT_OF_AWESOME_LOCK}" + NORDVPN_ICON "${CODEPOINT_OF_AWESOME_LOCK:+\\u$CODEPOINT_OF_AWESOME_LOCK}" + EXECUTION_TIME_ICON "${CODEPOINT_OF_AWESOME_HOURGLASS_END:+\\u$CODEPOINT_OF_AWESOME_HOURGLASS_END$s}" + SSH_ICON 'ssh' + VPN_ICON "${CODEPOINT_OF_AWESOME_LOCK:+\\u$CODEPOINT_OF_AWESOME_LOCK}" + KUBERNETES_ICON '\U2388' # ⎈ + DROPBOX_ICON "${CODEPOINT_OF_AWESOME_DROPBOX:+\\u$CODEPOINT_OF_AWESOME_DROPBOX$s}" + DATE_ICON '\uF073 ' # + TIME_ICON '\uF017 ' # + JAVA_ICON '\U2615' # ☕︎ + LARAVEL_ICON '' + RANGER_ICON '\u2B50' # ⭐ + MIDNIGHT_COMMANDER_ICON 'mc' + VIM_ICON 'vim' + TERRAFORM_ICON 'tf' + PROXY_ICON '\u2194' # ↔ + DOTNET_ICON '.NET' + DOTNET_CORE_ICON '.NET' + AZURE_ICON '\u2601' # ☁ + DIRENV_ICON '\u25BC' # ▼ + FLUTTER_ICON 'F' + GCLOUD_ICON 'G' + LUA_ICON 'lua' + PERL_ICON 'perl' + NNN_ICON 'nnn' + TIMEWARRIOR_ICON 'tw' + TASKWARRIOR_ICON 'task' + NIX_SHELL_ICON 'nix' + WIFI_ICON 'WiFi' + ERLANG_ICON 'erl' + ELIXIR_ICON 'elixir' + POSTGRES_ICON 'postgres' + PHP_ICON 'php' + HASKELL_ICON 'hs' + PACKAGE_ICON 'pkg' + ) + ;; + 'nerdfont-complete'|'nerdfont-fontconfig') + # nerd-font patched (complete) font required! See + # https://github.com/ryanoasis/nerd-fonts + # http://nerdfonts.com/#cheat-sheet + icons=( + RULER_CHAR '\u2500' # ─ + 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 '\uE614'$q # + SUDO_ICON '\uF09C'$s # + RUBY_ICON '\uF219 ' # + AWS_ICON '\uF270'$s # + AWS_EB_ICON '\UF1BD'$q$q # + BACKGROUND_JOBS_ICON '\uF013 ' # + TEST_ICON '\uF188'$s # + TODO_ICON '\u2611' # ☑ + BATTERY_ICON '\UF240 ' # + DISK_ICON '\uF0A0'$s # + OK_ICON '\uF00C'$s # + FAIL_ICON '\uF00D' # + SYMFONY_ICON '\uE757' # + NODE_ICON '\uE617 ' # + NODEJS_ICON '\uE617 ' # + MULTILINE_FIRST_PROMPT_PREFIX '\u256D\U2500' # ╭─ + MULTILINE_NEWLINE_PROMPT_PREFIX '\u251C\U2500' # ├─ + MULTILINE_LAST_PROMPT_PREFIX '\u2570\U2500 ' # ╰─ + APPLE_ICON '\uF179' # + WINDOWS_ICON '\uF17A'$s # + FREEBSD_ICON '\UF30C ' # + ANDROID_ICON '\uF17B' # + LINUX_ARCH_ICON '\uF303' # + LINUX_CENTOS_ICON '\uF304'$s # + LINUX_COREOS_ICON '\uF305'$s # + LINUX_DEBIAN_ICON '\uF306' # + LINUX_RASPBIAN_ICON '\uF315' # + LINUX_ELEMENTARY_ICON '\uF309'$s # + LINUX_FEDORA_ICON '\uF30a'$s # + LINUX_GENTOO_ICON '\uF30d'$s # + LINUX_MAGEIA_ICON '\uF310' # + LINUX_MINT_ICON '\uF30e'$s # + LINUX_NIXOS_ICON '\uF313'$s # + LINUX_MANJARO_ICON '\uF312'$s # + LINUX_DEVUAN_ICON '\uF307'$s # + LINUX_ALPINE_ICON '\uF300'$s # + LINUX_AOSC_ICON '\uF301'$s # + LINUX_OPENSUSE_ICON '\uF314'$s # + LINUX_SABAYON_ICON '\uF317'$s # + LINUX_SLACKWARE_ICON '\uF319'$s # + LINUX_VOID_ICON '\uF17C' # + LINUX_UBUNTU_ICON '\uF31b'$s # + LINUX_ICON '\uF17C' # + SUNOS_ICON '\uF185 ' # + HOME_ICON '\uF015'$s # + HOME_SUB_ICON '\uF07C'$s # + FOLDER_ICON '\uF115'$s # + ETC_ICON '\uF013'$s # + NETWORK_ICON '\uFBF1'$s # ﯱ + LOAD_ICON '\uF080 ' # + SWAP_ICON '\uF464'$s # + RAM_ICON '\uF0E4'$s # + SERVER_ICON '\uF0AE'$s # + VCS_UNTRACKED_ICON '\uF059'$s # + VCS_UNSTAGED_ICON '\uF06A'$s # + VCS_STAGED_ICON '\uF055'$s # + VCS_STASH_ICON '\uF01C ' # + VCS_INCOMING_CHANGES_ICON '\uF01A ' # + VCS_OUTGOING_CHANGES_ICON '\uF01B ' # + VCS_TAG_ICON '\uF02B ' # + VCS_BOOKMARK_ICON '\uF461 ' # + VCS_COMMIT_ICON '\uE729 ' # + VCS_BRANCH_ICON '\uF126 ' # + VCS_REMOTE_BRANCH_ICON '\uE728 ' # + VCS_LOADING_ICON '' + VCS_GIT_ICON '\uF1D3 ' # + VCS_GIT_GITHUB_ICON '\uF113 ' # + VCS_GIT_BITBUCKET_ICON '\uE703 ' # + VCS_GIT_GITLAB_ICON '\uF296 ' # + VCS_HG_ICON '\uF0C3 ' # + VCS_SVN_ICON '\uE72D'$q # + RUST_ICON '\uE7A8'$q # + PYTHON_ICON '\UE73C ' # + SWIFT_ICON '\uE755' # + GO_ICON '\uE626' # + GOLANG_ICON '\uE626' # + PUBLIC_IP_ICON '\UF0AC'$s # + LOCK_ICON '\UF023' # + NORDVPN_ICON '\UF023' # + EXECUTION_TIME_ICON '\uF252'$s # + SSH_ICON '\uF489'$s # + VPN_ICON '\UF023' + KUBERNETES_ICON '\U2388' # ⎈ + DROPBOX_ICON '\UF16B'$s # + DATE_ICON '\uF073 ' # + TIME_ICON '\uF017 ' # + JAVA_ICON '\uE738' # + LARAVEL_ICON '\ue73f'$q # + RANGER_ICON '\uF00b ' # + MIDNIGHT_COMMANDER_ICON 'mc' + VIM_ICON '\uE62B' # + TERRAFORM_ICON '\uF1BB ' # + PROXY_ICON '\u2194' # ↔ + DOTNET_ICON '\uE77F' # + DOTNET_CORE_ICON '\uE77F' # + AZURE_ICON '\uFD03' # ﴃ + DIRENV_ICON '\u25BC' # ▼ + FLUTTER_ICON 'F' + GCLOUD_ICON '\uF7B7' # + LUA_ICON '\uE620' # + PERL_ICON '\uE769' # + NNN_ICON 'nnn' + TIMEWARRIOR_ICON '\uF49B' # + TASKWARRIOR_ICON '\uF4A0 ' # + NIX_SHELL_ICON '\uF313 ' # + WIFI_ICON '\uF1EB ' # + ERLANG_ICON '\uE7B1 ' # + ELIXIR_ICON '\uE62D' # + POSTGRES_ICON '\uE76E' # + PHP_ICON '\uE608' # + HASKELL_ICON '\uE61F' # + PACKAGE_ICON '\uF8D6' # + ) + ;; + ascii) + icons=( + RULER_CHAR '-' + LEFT_SEGMENT_SEPARATOR '' + RIGHT_SEGMENT_SEPARATOR '' + LEFT_SEGMENT_END_SEPARATOR ' ' + LEFT_SUBSEGMENT_SEPARATOR '|' + RIGHT_SUBSEGMENT_SEPARATOR '|' + CARRIAGE_RETURN_ICON '' + ROOT_ICON '#' + SUDO_ICON '' + RUBY_ICON 'rb' + AWS_ICON 'aws' + AWS_EB_ICON 'eb' + BACKGROUND_JOBS_ICON '%%' + TEST_ICON '' + TODO_ICON 'todo' + BATTERY_ICON 'battery' + DISK_ICON 'disk' + OK_ICON 'ok' + FAIL_ICON 'err' + SYMFONY_ICON 'symphony' + NODE_ICON 'node' + NODEJS_ICON 'node' + MULTILINE_FIRST_PROMPT_PREFIX '' + MULTILINE_NEWLINE_PROMPT_PREFIX '' + MULTILINE_LAST_PROMPT_PREFIX '' + APPLE_ICON 'mac' + WINDOWS_ICON 'win' + FREEBSD_ICON 'bsd' + ANDROID_ICON 'android' + LINUX_ICON 'linux' + LINUX_ARCH_ICON 'arch' + LINUX_DEBIAN_ICON 'debian' + LINUX_RASPBIAN_ICON 'pi' + LINUX_UBUNTU_ICON 'ubuntu' + LINUX_CENTOS_ICON 'centos' + LINUX_COREOS_ICON 'coreos' + LINUX_ELEMENTARY_ICON 'elementary' + LINUX_MINT_ICON 'mint' + LINUX_FEDORA_ICON 'fedora' + LINUX_GENTOO_ICON 'gentoo' + LINUX_MAGEIA_ICON 'mageia' + LINUX_NIXOS_ICON 'nixos' + LINUX_MANJARO_ICON 'manjaro' + LINUX_DEVUAN_ICON 'devuan' + LINUX_ALPINE_ICON 'alpine' + LINUX_AOSC_ICON 'aosc' + LINUX_OPENSUSE_ICON 'suse' + LINUX_SABAYON_ICON 'sabayon' + LINUX_SLACKWARE_ICON 'slack' + LINUX_VOID_ICON 'void' + SUNOS_ICON 'sunos' + HOME_ICON '' + HOME_SUB_ICON '' + FOLDER_ICON '' + ETC_ICON '' + NETWORK_ICON 'ip' + LOAD_ICON 'cpu' + SWAP_ICON 'swap' + RAM_ICON 'ram' + SERVER_ICON '' + VCS_UNTRACKED_ICON '?' + VCS_UNSTAGED_ICON '!' + VCS_STAGED_ICON '+' + VCS_STASH_ICON '#' + VCS_INCOMING_CHANGES_ICON '<' + VCS_OUTGOING_CHANGES_ICON '>' + VCS_TAG_ICON '' + VCS_BOOKMARK_ICON '^' + VCS_COMMIT_ICON '@' + VCS_BRANCH_ICON '' + VCS_REMOTE_BRANCH_ICON ':' + VCS_LOADING_ICON '' + VCS_GIT_ICON '' + VCS_GIT_GITHUB_ICON '' + VCS_GIT_BITBUCKET_ICON '' + VCS_GIT_GITLAB_ICON '' + VCS_HG_ICON '' + VCS_SVN_ICON '' + RUST_ICON 'rust' + PYTHON_ICON 'py' + SWIFT_ICON 'swift' + GO_ICON 'go' + GOLANG_ICON 'go' + PUBLIC_IP_ICON 'ip' + LOCK_ICON '!w' + NORDVPN_ICON 'nordvpn' + EXECUTION_TIME_ICON '' + SSH_ICON 'ssh' + VPN_ICON 'vpn' + KUBERNETES_ICON 'kube' + DROPBOX_ICON 'dropbox' + DATE_ICON '' + TIME_ICON '' + JAVA_ICON 'java' + LARAVEL_ICON '' + RANGER_ICON 'ranger' + MIDNIGHT_COMMANDER_ICON 'mc' + VIM_ICON 'vim' + TERRAFORM_ICON 'tf' + PROXY_ICON 'proxy' + DOTNET_ICON '.net' + DOTNET_CORE_ICON '.net' + AZURE_ICON 'az' + DIRENV_ICON 'direnv' + FLUTTER_ICON 'flutter' + GCLOUD_ICON 'gcloud' + LUA_ICON 'lua' + PERL_ICON 'perl' + NNN_ICON 'nnn' + TIMEWARRIOR_ICON 'tw' + TASKWARRIOR_ICON 'task' + NIX_SHELL_ICON 'nix' + WIFI_ICON 'wifi' + ERLANG_ICON 'erlang' + ELIXIR_ICON 'elixir' + POSTGRES_ICON 'postgres' + PHP_ICON 'php' + HASKELL_ICON 'hs' + PACKAGE_ICON 'pkg' + ) + ;; + *) + # Powerline-Patched Font required! + # See https://github.com/Lokaltog/powerline-fonts + icons=( + RULER_CHAR '\u2500' # ─ + 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 '\u26A1' # ⚡ + SUDO_ICON '' + RUBY_ICON 'Ruby' + AWS_ICON 'AWS' + AWS_EB_ICON '\U1F331'$q # 🌱 + BACKGROUND_JOBS_ICON '\u2699' # ⚙ + TEST_ICON '' + TODO_ICON '\u2206' # ∆ + BATTERY_ICON '\U1F50B' # 🔋 + DISK_ICON 'hdd' + OK_ICON '\u2714' # ✔ + FAIL_ICON '\u2718' # ✘ + SYMFONY_ICON 'SF' + NODE_ICON 'Node' + NODEJS_ICON 'Node' + MULTILINE_FIRST_PROMPT_PREFIX '\u256D\U2500' # ╭─ + MULTILINE_NEWLINE_PROMPT_PREFIX '\u251C\U2500' # ├─ + MULTILINE_LAST_PROMPT_PREFIX '\u2570\U2500 ' # ╰─ + APPLE_ICON 'OSX' + WINDOWS_ICON 'WIN' + FREEBSD_ICON 'BSD' + ANDROID_ICON 'And' + LINUX_ICON 'Lx' + LINUX_ARCH_ICON 'Arc' + LINUX_DEBIAN_ICON 'Deb' + LINUX_RASPBIAN_ICON 'RPi' + LINUX_UBUNTU_ICON 'Ubu' + LINUX_CENTOS_ICON 'Cen' + LINUX_COREOS_ICON 'Cor' + LINUX_ELEMENTARY_ICON 'Elm' + LINUX_MINT_ICON 'LMi' + LINUX_FEDORA_ICON 'Fed' + LINUX_GENTOO_ICON 'Gen' + LINUX_MAGEIA_ICON 'Mag' + LINUX_NIXOS_ICON 'Nix' + LINUX_MANJARO_ICON 'Man' + LINUX_DEVUAN_ICON 'Dev' + LINUX_ALPINE_ICON 'Alp' + LINUX_AOSC_ICON 'Aos' + LINUX_OPENSUSE_ICON 'OSu' + LINUX_SABAYON_ICON 'Sab' + LINUX_SLACKWARE_ICON 'Sla' + LINUX_VOID_ICON 'Vo' + SUNOS_ICON 'Sun' + HOME_ICON '' + HOME_SUB_ICON '' + FOLDER_ICON '' + ETC_ICON '\u2699' # ⚙ + NETWORK_ICON 'IP' + LOAD_ICON 'L' + SWAP_ICON 'SWP' + RAM_ICON 'RAM' + SERVER_ICON '' + VCS_UNTRACKED_ICON '?' + VCS_UNSTAGED_ICON '\u25CF' # ● + VCS_STAGED_ICON '\u271A' # ✚ + VCS_STASH_ICON '\u235F' # ⍟ + VCS_INCOMING_CHANGES_ICON '\u2193' # ↓ + VCS_OUTGOING_CHANGES_ICON '\u2191' # ↑ + VCS_TAG_ICON '' + VCS_BOOKMARK_ICON '\u263F' # ☿ + VCS_COMMIT_ICON '' + VCS_BRANCH_ICON '\uE0A0 ' # + VCS_REMOTE_BRANCH_ICON '\u2192' # → + VCS_LOADING_ICON '' + VCS_GIT_ICON '' + VCS_GIT_GITHUB_ICON '' + VCS_GIT_BITBUCKET_ICON '' + VCS_GIT_GITLAB_ICON '' + VCS_HG_ICON '' + VCS_SVN_ICON '' + RUST_ICON 'R' + PYTHON_ICON 'Py' + SWIFT_ICON 'Swift' + GO_ICON 'Go' + GOLANG_ICON 'Go' + PUBLIC_IP_ICON 'IP' + LOCK_ICON '\UE0A2' + NORDVPN_ICON '\UE0A2' + EXECUTION_TIME_ICON '' + SSH_ICON 'ssh' + VPN_ICON 'vpn' + KUBERNETES_ICON '\U2388' # ⎈ + DROPBOX_ICON 'Dropbox' + DATE_ICON '' + TIME_ICON '' + JAVA_ICON '\U2615' # ☕︎ + LARAVEL_ICON '' + RANGER_ICON '\u2B50' # ⭐ + MIDNIGHT_COMMANDER_ICON 'mc' + VIM_ICON 'vim' + TERRAFORM_ICON 'tf' + PROXY_ICON '\u2194' # ↔ + DOTNET_ICON '.NET' + DOTNET_CORE_ICON '.NET' + AZURE_ICON '\u2601' # ☁ + DIRENV_ICON '\u25BC' # ▼ + FLUTTER_ICON 'F' + GCLOUD_ICON 'G' + LUA_ICON 'lua' + PERL_ICON 'perl' + NNN_ICON 'nnn' + TIMEWARRIOR_ICON 'tw' + TASKWARRIOR_ICON 'task' + NIX_SHELL_ICON 'nix' + WIFI_ICON 'WiFi' + ERLANG_ICON 'erl' + ELIXIR_ICON 'elixir' + POSTGRES_ICON 'postgres' + PHP_ICON 'php' + HASKELL_ICON 'hs' + PACKAGE_ICON 'pkg' + ) + ;; + esac + + # Override the above icon settings with any user-defined variables. + case $POWERLEVEL9K_MODE in + 'flat') + icons[LEFT_SEGMENT_SEPARATOR]='' + icons[RIGHT_SEGMENT_SEPARATOR]='' + icons[LEFT_SUBSEGMENT_SEPARATOR]='|' + icons[RIGHT_SUBSEGMENT_SEPARATOR]='|' + ;; + 'compatible') + icons[LEFT_SEGMENT_SEPARATOR]='\u2B80' # ⮀ + icons[RIGHT_SEGMENT_SEPARATOR]='\u2B82' # ⮂ + icons[VCS_BRANCH_ICON]='@' + ;; + esac + + if [[ $POWERLEVEL9K_ICON_PADDING == none && $POWERLEVEL9K_MODE != ascii ]]; then + icons=("${(@kv)icons%% #}") + icons[LEFT_SEGMENT_END_SEPARATOR]+=' ' + icons[MULTILINE_LAST_PROMPT_PREFIX]+=' ' + icons[VCS_TAG_ICON]+=' ' + icons[VCS_COMMIT_ICON]+=' ' + icons[VCS_BRANCH_ICON]+=' ' + icons[VCS_REMOTE_BRANCH_ICON]+=' ' + fi +} + +# Sadly, this is a part of public API. Its use is emphatically discouraged. +function print_icon() { + eval "$__p9k_intro" + _p9k_init_icons + local var=POWERLEVEL9K_$1 + if (( $+parameters[$var] )); then + echo -n - ${(P)var} + else + echo -n - $icons[$1] + fi +} + +# Prints a list of configured icons. +# +# * $1 string - If "original", then the original icons are printed, +# otherwise "print_icon" is used, which takes the users +# overrides into account. +function get_icon_names() { + eval "$__p9k_intro" + _p9k_init_icons + local key + for key in ${(@kon)icons}; do + echo -n - "POWERLEVEL9K_$key: " + print -nP "%K{red} %k" + if [[ $1 == original ]]; then + echo -n - $icons[$key] + else + print_icon $key + fi + print -P "%K{red} %k" + done +} diff --git a/internal/notes.md b/internal/notes.md new file mode 100644 index 00000000..3ef3a828 --- /dev/null +++ b/internal/notes.md @@ -0,0 +1,236 @@ +battery: use the same technique as in vpn_ip to avoid reset=2. + +--- + +implement fake gitstatus api on top of vcs_info (or plain git?) + worker and use it if there is no +gitstatus. + +--- + +- call vcs_info on worker. the tricky question is what to display while "loading". + +--- + +- add _SHOW_SYSTEM to all *env segments. + +--- + +- support states in SHOW_ON_COMMAND: POWERLEVEL9K_SEGMENT_STATE_SHOW_ON_COMMAND='...' + +--- + +add POWERLEVEL9K_${SEGMENT}_${STATE}_SHOW_IN_DIR='pwd_pattern'; implement the same way as +SHOW_ON_UPGLOB. how should it interact with POWERLEVEL9K_${SEGMENT}_DISABLED_DIR_PATTERN? + +--- + +add `p10k upglob`; returns 0 on match and sets REPLY to the directory where match was found. + +--- + +when directory cannot be shortened any further, start chopping off segments from the left and +replacing the chopped off part with `…`. e.g., `…/x/anchor/y/anchor`. the shortest dir +representation is thus `…/last` or `…/last` depending on whether the last segment is an anchor. +the replacement parameter's value is `…/` (with a slash) to allow for `x/anchor/y/anchor`. + +--- + +- add to faq: how do i display an environment variable in prompt? link it from "extensible" + +--- + +- add to faq: how do i display an icon in prompt? link it from "extensible" + +--- + +- add root_indicator to config templates + +--- + +- test chruby and add it to config templates + +--- + +- add ssh to config templates + +--- + +- add swift version to config templates; see if there is a good pattern for PROJECT_ONLY + +--- + +- add swiftenv + +--- + +- add faq: how to customize directory shortening? mention POWERLEVEL9K_DIR_TRUNCATE_BEFORE_MARKER, +POWERLEVEL9K_DIR_MAX_LENGTH and co., and truncate_to_last. + +--- + +fix a bug in zsh: https://github.com/romkatv/powerlevel10k/issues/502. to reproduce: + +```zsh +emulate zsh -o prompt_percent -c 'print -P "%F{#ff0000}red%F{green}%B bold green"' +``` + +--- + +bug: open a new tab and hit ctrl-p. an empty line will appear before prompt. + +--- + +take a look at https://github.com/skywind3000/z.lua. it claims to have fzf support. would be nice +if alt-down showed two groups -- one for subdirs and another for directory history (sorted by +frequency of use? by last use? three sections? more key bindings?). + +--- + +add `p10k explain` that prints something like this: + +```text +segment icons meaning + +--- + +--- + +--- + +--- + +--- + +--- + +--- + +--- +-- +status ✔ ✘ exit code of the last command +``` + +implement it the hard way: for every enabled segment go over all its {state,icon} pairs, resolve +the icon (if not absolute), apply VISUAL_IDENTIFIER_EXPANSION, remove leading and trailing +whitespace and print without formatting (sort of like `print -P | cat`); print segment names in +green and icons in bold; battery can have an unlimited number of icons, so `...` would be needed +(based on total length of concatenated icons rather than the number of icons); user-defined +segments would have "unknown" icons by default (yellow and not bold); can allow them to +participate by defining `explainprompt_foo` that populates array `reply` with strings like this: +'-s STATE -i LOCK_ICON +r'; the first element must be segment description. + +--- + +add `docker_context` prompt segment; similar to `kubecontext`; the data should come from +`currentContext` field in `~/.docker/config.json` (according to +https://github.com/starship/starship/issues/995); there is also `DOCKER_CONTEXT`; more info: +https://docs.docker.com/engine/reference/commandline/context_use; also +https://github.com/starship/starship/pull/996. + +--- + +support `env`, `ionice` and `strace` precommands in `parser.zsh`. + +--- + +Add ruler to configuration wizard. Options: `─`, `·`, `╌`, `┄`, `▁`, `═`. + +--- + +Add frame styles to the wizard. + +```text +╭─ +╰─ + +┌─ +└─ + +┏━ +┗━ + +╔═ +╚═ + +▛▀ +▙▄ +``` + +Prompt connection should have matching options. + +--- + +Add `POWERLEVEL9K_{LEFT,RIGHT}_SEGMENT_MIRROR_SEPARATOR`. If set, left segments get separated with +`POWERLEVEL9K_LEFT_SEGMENT_SEPARATOR` followed by `POWERLEVEL9K_LEFT_SEGMENT_MIRROR_SEPARATOR`. +Each is drawn without background. The first with the foreground of left segment, the second with +the background of right segment. To insert space in between, embed it in one of these parameters. +`POWERLEVEL9K_{LEFT,RIGHT}_SUBSEGMENT_SEPARATOR` is unused. + +--- + +Add *Segment Connection* screen to configuration wizard with options *Fused*, *Touching* and +*Disjoint*. The last two differ by the absence/presence of space between `SEGMENT_SEPARATOR` and +`SEGMENT_MIRROR_SEPARATOR`. + +*Fused* requires line separator (there is already a screen for it) but the other two options require +two filled separators similar to heads and tail. Figure out how to present this choice. + +--- + +Get rid of `saved_columns` in the wizard and always present all options as if horizontal space was +unlimited. `print_prompt` should print something like this if prompt is too wide: + + Terminal window too narrow to display prompt. + Make it wider and press ENTER to refresh. + +Terminal dimensions will need to be checked more often. + +Try getting rid of the "press ENTER" requirement by trapping `SIGWINCH`. Might need to run `read -k` +with timeout in a loop. + +Print all text with a helper function that keeps track of the number of lines remaining on screen. +`print_prompt` will then be able to show a similar message for Terminal window being too short. This +makes sense only for two-line prompts. This is probably OK. + +If `print_prompt` can be told in advance how many prompts we are going to display, it might be able +to insert or avoid inserting `\n` in between, depending on terminal height. There is one screen +where one prompt is a one-liner while another is a two-liner. This is fine because there are only +two options. `print_prompt` can assume that all options will use the current prompt height. + +Don't use `print_prompt` directly. Create `ask_prompt` and use it like this: + +```zsh +ask_prompt \ + 1 "No frame" "left_frame=0 right_frame=0" \ + 2 "Left frame" "left_frame=1 right_frame=0" \ + ... +``` + +There are two prompt questions that don't fit this pattern: `ask_empty_line` and +`ask_transient_prompt`. The first is easy to adapt (`print_prompt` can print prompt twice if +`empty_line=1`) but the second will probably have to be hand-coded. + +--- + +Optimize auto-wizard check. + +```text +time ( repeat 1000 [[ -z "${parameters[(I)POWERLEVEL9K_*~(POWERLEVEL9K_MODE|POWERLEVEL9K_CONFIG_FILE)]}" ]] ) +user=0.21s system=0.05s cpu=99% total=0.264 + +time ( repeat 1000 [[ -z "${parameters[(I)POWERLEVEL9K_*]}" ]] ) +user=0.17s system=0.00s cpu=99% total=0.175 +``` + +--- + +Add the equivalent of `P9K_PYTHON_VERSION` to all `*env` segments where it makes sense. + +--- + +Define `P9K_ICON` on initialization. Fill it with `$icon`. Duplicate every key that ends in `_ICON`. +Respect `POWERLEVEL9K_VCS_STASH_ICON` overrides but not anything with segment name or state. + +Define `POWERLEVEL9K_VCS_*` parameters in config templates for all symbols used in +`my_git_formatter`. Add missing entries to `icons`. Use `$P9K_ICON[...]` within `my_git_formatter`. +Add a screen to the wizard to choose between clear and circled icons. diff --git a/internal/p10k.zsh b/internal/p10k.zsh new file mode 100644 index 00000000..a3503615 --- /dev/null +++ b/internal/p10k.zsh @@ -0,0 +1,8485 @@ +if [[ $__p9k_sourced != 12 ]]; then + >&2 print -P "" + >&2 print -P "[%F{1}ERROR%f]: Corrupted powerlevel10k installation." + >&2 print -P "" + if (( ${+functions[antigen]} )); then + >&2 print -P "If using %Bantigen%b, run the folowing command to fix:" + >&2 print -P "" + >&2 print -P " %F{2}antigen%f reset" + if [[ -d ~/.antigen ]]; then + >&2 print -P "" + >&2 print -P "If it doesn't help, try this:" + >&2 print -P "" + >&2 print -P " %F{2}rm%f -rf %U~/.antigen%u" + fi + else + >&2 print -P "Try resetting cache in your plugin manager or" + >&2 print -P "reinstalling powerlevel10k from scratch." + fi + >&2 print -P "" + return 1 +fi + +if ! autoload -Uz is-at-least || ! is-at-least 5.1; then + () { + >&2 echo -E "You are using ZSH version $ZSH_VERSION. The minimum required version for Powerlevel10k is 5.1." + >&2 echo -E "Type 'echo \$ZSH_VERSION' to see your current zsh version." + local def=${SHELL:c:A} + local cur=${${ZSH_ARGZERO#-}:c:A} + local cur_v="$($cur -c 'echo -E $ZSH_VERSION' 2>/dev/null)" + if [[ $cur_v == $ZSH_VERSION && $cur != $def ]]; then + >&2 echo -E "The shell you are currently running is likely $cur." + fi + local other=${${:-zsh}:c} + if [[ -n $other ]] && $other -c 'autoload -Uz is-at-least && is-at-least 5.1' &>/dev/null; then + local other_v="$($other -c 'echo -E $ZSH_VERSION' 2>/dev/null)" + if [[ -n $other_v && $other_v != $ZSH_VERSION ]]; then + >&2 echo -E "You have $other with version $other_v but this is not what you are using." + if [[ -n $def && $def != ${other:A} ]]; then + >&2 echo -E "To change your user shell, type the following command:" + >&2 echo -E "" + if [[ "$(grep -F $other /etc/shells 2>/dev/null)" != $other ]]; then + >&2 echo -E " echo ${(q-)other} | sudo tee -a /etc/shells" + fi + >&2 echo -E " chsh -s ${(q-)other}" + fi + fi + fi + } + return 1 +fi + +source "${__p9k_root_dir}/internal/configure.zsh" +source "${__p9k_root_dir}/internal/worker.zsh" +source "${__p9k_root_dir}/internal/parser.zsh" +source "${__p9k_root_dir}/internal/icons.zsh" + +# For compatibility with Powerlevel9k. It's not recommended to use mnemonic color +# names in the configuration except for colors 0-7 as these are standard. +typeset -grA __p9k_colors=( + black 000 red 001 green 002 yellow 003 + blue 004 magenta 005 cyan 006 white 007 + grey 008 maroon 009 lime 010 olive 011 + navy 012 fuchsia 013 aqua 014 teal 014 + silver 015 grey0 016 navyblue 017 darkblue 018 + blue3 020 blue1 021 darkgreen 022 deepskyblue4 025 + dodgerblue3 026 dodgerblue2 027 green4 028 springgreen4 029 + turquoise4 030 deepskyblue3 032 dodgerblue1 033 darkcyan 036 + lightseagreen 037 deepskyblue2 038 deepskyblue1 039 green3 040 + springgreen3 041 cyan3 043 darkturquoise 044 turquoise2 045 + green1 046 springgreen2 047 springgreen1 048 mediumspringgreen 049 + cyan2 050 cyan1 051 purple4 055 purple3 056 + blueviolet 057 grey37 059 mediumpurple4 060 slateblue3 062 + royalblue1 063 chartreuse4 064 paleturquoise4 066 steelblue 067 + steelblue3 068 cornflowerblue 069 darkseagreen4 071 cadetblue 073 + skyblue3 074 chartreuse3 076 seagreen3 078 aquamarine3 079 + mediumturquoise 080 steelblue1 081 seagreen2 083 seagreen1 085 + darkslategray2 087 darkred 088 darkmagenta 091 orange4 094 + lightpink4 095 plum4 096 mediumpurple3 098 slateblue1 099 + wheat4 101 grey53 102 lightslategrey 103 mediumpurple 104 + lightslateblue 105 yellow4 106 darkseagreen 108 lightskyblue3 110 + skyblue2 111 chartreuse2 112 palegreen3 114 darkslategray3 116 + skyblue1 117 chartreuse1 118 lightgreen 120 aquamarine1 122 + darkslategray1 123 deeppink4 125 mediumvioletred 126 darkviolet 128 + purple 129 mediumorchid3 133 mediumorchid 134 darkgoldenrod 136 + rosybrown 138 grey63 139 mediumpurple2 140 mediumpurple1 141 + darkkhaki 143 navajowhite3 144 grey69 145 lightsteelblue3 146 + lightsteelblue 147 darkolivegreen3 149 darkseagreen3 150 lightcyan3 152 + lightskyblue1 153 greenyellow 154 darkolivegreen2 155 palegreen1 156 + darkseagreen2 157 paleturquoise1 159 red3 160 deeppink3 162 + magenta3 164 darkorange3 166 indianred 167 hotpink3 168 + hotpink2 169 orchid 170 orange3 172 lightsalmon3 173 + lightpink3 174 pink3 175 plum3 176 violet 177 + gold3 178 lightgoldenrod3 179 tan 180 mistyrose3 181 + thistle3 182 plum2 183 yellow3 184 khaki3 185 + lightyellow3 187 grey84 188 lightsteelblue1 189 yellow2 190 + darkolivegreen1 192 darkseagreen1 193 honeydew2 194 lightcyan1 195 + red1 196 deeppink2 197 deeppink1 199 magenta2 200 + magenta1 201 orangered1 202 indianred1 204 hotpink 206 + mediumorchid1 207 darkorange 208 salmon1 209 lightcoral 210 + palevioletred1 211 orchid2 212 orchid1 213 orange1 214 + sandybrown 215 lightsalmon1 216 lightpink1 217 pink1 218 + plum1 219 gold1 220 lightgoldenrod2 222 navajowhite1 223 + mistyrose1 224 thistle1 225 yellow1 226 lightgoldenrod1 227 + khaki1 228 wheat1 229 cornsilk1 230 grey100 231 + grey3 232 grey7 233 grey11 234 grey15 235 + grey19 236 grey23 237 grey27 238 grey30 239 + grey35 240 grey39 241 grey42 242 grey46 243 + grey50 244 grey54 245 grey58 246 grey62 247 + grey66 248 grey70 249 grey74 250 grey78 251 + grey82 252 grey85 253 grey89 254 grey93 255) + +# For compatibility with Powerlevel9k. +# +# Type `getColorCode background` or `getColorCode foreground` to see the list of predefined colors. +function getColorCode() { + eval "$__p9k_intro" + if (( ARGC == 1 )); then + case $1 in + foreground) + local k + for k in "${(k@)__p9k_colors}"; do + local v=${__p9k_colors[$k]} + print -rP -- "%F{$v}$v - $k%f" + done + return 0 + ;; + background) + local k + for k in "${(k@)__p9k_colors}"; do + local v=${__p9k_colors[$k]} + print -rP -- "%K{$v}$v - $k%k" + done + return 0 + ;; + esac + fi + echo "Usage: getColorCode background|foreground" >&2 + return 1 +} + +# _p9k_declare <type> <uppercase-name> [default]... +function _p9k_declare() { + local -i set=$+parameters[$2] + (( ARGC > 2 || set )) || return 0 + case $1 in + -b) + if (( set )); then + [[ ${(P)2} == true ]] && typeset -gi _$2=1 || typeset -gi _$2=0 + else + typeset -gi _$2=$3 + fi + ;; + -a) + local -a v=("${(@P)2}") + if (( set )); then + eval "typeset -ga _${(q)2}=(${(@qq)v})"; + else + if [[ $3 != '--' ]]; then + echo "internal error in _p9k_declare " "${(qqq)@}" >&2 + fi + eval "typeset -ga _${(q)2}=(${(@qq)*[4,-1]})" + fi + ;; + -i) + (( set )) && typeset -gi _$2=$2 || typeset -gi _$2=$3 + ;; + -F) + (( set )) && typeset -gF _$2=$2 || typeset -gF _$2=$3 + ;; + -s) + (( set )) && typeset -g _$2=${(P)2} || typeset -g _$2=$3 + ;; + -e) + if (( set )); then + local v=${(P)2} + typeset -g _$2=${(g::)v} + else + typeset -g _$2=${(g::)3} + fi + ;; + *) + echo "internal error in _p9k_declare " "${(qqq)@}" >&2 + esac +} + +function _p9k_read_word() { + local -a stat + zstat -A stat +mtime -- $1 2>/dev/null || stat=(-1) + local cached=$_p9k__read_word_cache[$1] + if [[ $cached == $stat[1]:* ]]; then + _p9k__ret=${cached#*:} + else + local rest + _p9k__ret= + { read _p9k__ret rest <$1 } 2>/dev/null + _p9k__read_word_cache[$1]=$stat[1]:$_p9k__ret + fi + [[ -n $_p9k__ret ]] +} + +function _p9k_fetch_cwd() { + _p9k__cwd=${(%):-%/} + _p9k__cwd_a=${_p9k__cwd:A} + + case $_p9k__cwd in + ~|/) + _p9k__parent_dirs=() + _p9k__parent_mtimes=() + _p9k__parent_mtimes_i=() + _p9k__parent_mtimes_s= + return + ;; + ~/*) + local parent=~/ + local parts=(${(s./.)_p9k__cwd#$parent}) + ;; + *) + local parent=/ + local parts=(${(s./.)_p9k__cwd}) + ;; + esac + local MATCH + _p9k__parent_dirs=(${(@)${:-{$#parts..1}}/(#m)*/$parent${(pj./.)parts[1,MATCH]}}) + if ! zstat -A _p9k__parent_mtimes +mtime -- $_p9k__parent_dirs 2>/dev/null; then + _p9k__parent_mtimes=(${(@)parts/*/-1}) + fi + _p9k__parent_mtimes_i=(${(@)${:-{1..$#parts}}/(#m)*/$MATCH:$_p9k__parent_mtimes[MATCH]}) + _p9k__parent_mtimes_s="$_p9k__parent_mtimes_i" +} + +# Usage: _p9k_glob parent_dir_index pattern +# +# parent_dir_index indexes _p9k__parent_dirs. +# +# Returns the number of matches. +# +# Pattern cannot have slashes. +# +# Example: _p9k_glob 3 '*.csproj' +function _p9k_glob() { + local dir=$_p9k__parent_dirs[$1] + local cached=$_p9k__glob_cache[$dir/$2] + if [[ $cached == $_p9k__parent_mtimes[$1]:* ]]; then + return ${cached##*:} + fi + local -a stat + zstat -A stat +mtime -- $dir 2>/dev/null || stat=(-1) + local files=($dir/$~2(N:t)) + _p9k__glob_cache[$dir/$2]="$stat[1]:$#files" + return $#files +} + +# Usage: _p9k_upglob pattern +# +# Returns index within _p9k__parent_dirs or 0 if there is no match. +# +# Pattern cannot have slashes. Never matches in / or ~. Search stops before reaching / or ~. +# +# Example: _p9k_upglob '*.csproj' +function _p9k_upglob() { + local cached=$_p9k__upsearch_cache[$_p9k__cwd/$1] + if [[ -n $cached ]]; then + if [[ $_p9k__parent_mtimes_s == ${cached% *}(| *) ]]; then + return ${cached##* } + fi + cached=(${(s: :)cached}) + local last_idx=$cached[-1] + cached[-1]=() + local -i i + for i in ${(@)${cached:|_p9k__parent_mtimes_i}%:*}; do + _p9k_glob $i $1 && continue + _p9k__upsearch_cache[$_p9k__cwd/$1]="${_p9k__parent_mtimes_i[1,i]} $i" + return i + done + if (( i != last_idx )); then + _p9k__upsearch_cache[$_p9k__cwd/$1]="${_p9k__parent_mtimes_i[1,$#cached]} $last_idx" + return last_idx + fi + i=$(($#cached + 1)) + else + local -i i=1 + fi + for ((; i <= $#_p9k__parent_mtimes; ++i)); do + _p9k_glob $i $1 && continue + _p9k__upsearch_cache[$_p9k__cwd/$1]="${_p9k__parent_mtimes_i[1,i]} $i" + return i + done + _p9k__upsearch_cache[$_p9k__cwd/$1]="$_p9k__parent_mtimes_s 0" + return 0 +} + +# If we execute `print -P $1`, how many characters will be printed on the last line? +# Assumes that `%{%}` and `%G` don't lie. +# +# _p9k_prompt_length '' => 0 +# _p9k_prompt_length 'abc' => 3 +# _p9k_prompt_length $'abc\nxy' => 2 +# _p9k_prompt_length $'\t' => 8 +# _p9k_prompt_length '%F{red}abc' => 3 +# _p9k_prompt_length $'%{a\b%Gb%}' => 1 +function _p9k_prompt_length() { + local COLUMNS=1024 + local -i x y=$#1 m + if (( y )); then + while (( ${${(%):-$1%$y(l.1.0)}[-1]} )); do + x=y + (( y *= 2 )); + done + local xy + while (( y > x + 1 )); do + m=$(( x + (y - x) / 2 )) + typeset ${${(%):-$1%$m(l.x.y)}[-1]}=$m + done + fi + _p9k__ret=$x +} + +typeset -gr __p9k_byte_suffix=('B' 'K' 'M' 'G' 'T' 'P' 'E' 'Z' 'Y') + +# 42 => 42B +# 1536 => 1.5K +function _p9k_human_readable_bytes() { + typeset -F 2 n=$1 + local suf + for suf in $__p9k_byte_suffix; do + (( n < 100 )) && break + (( n /= 1024 )) + done + _p9k__ret=${${n%%0#}%.}$suf +} + +if is-at-least 5.4; then + function _p9k_print_params() { typeset -p -- "$@" } +else + # Cannot use `typeset -p` unconditionally because of bugs in zsh. + function _p9k_print_params() { + local name + for name; do + case $parameters[$name] in + array*) + print -r -- "$name=(" "${(@q)${(@P)name}}" ")" + ;; + association*) + # Cannot use "${(@q)${(@kvP)name}}" because of bugs in zsh. + local kv=("${(@kvP)name}") + print -r -- "$name=(" "${(@q)kv}" ")" + ;; + *) + print -r -- "$name=${(q)${(P)name}}" + ;; + esac + done + } +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. +_p9k_segment_in_use() { + (( $_POWERLEVEL9K_LEFT_PROMPT_ELEMENTS[(I)$1(|_joined)] || + $_POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS[(I)$1(|_joined)] )) +} + +# Caching allows storing array-to-array associations. It should be used like this: +# +# if ! _p9k_cache_get "$key1" "$key2"; then +# # Compute val1 and val2 and then store them in the cache. +# _p9k_cache_set "$val1" "$val2" +# fi +# # Here ${_p9k__cache_val[1]} and ${_p9k__cache_val[2]} are $val1 and $val2 respectively. +# +# Limitations: +# +# * Calling _p9k_cache_set without arguments clears the cache entry. Subsequent calls to +# _p9k_cache_get for the same key will return an error. +# * There must be no intervening _p9k_cache_get calls between the associated _p9k_cache_get +# and _p9k_cache_set. +_p9k_cache_set() { + # Uncomment to see cache misses. + # echo "caching: ${(@0q)_p9k__cache_key} => (${(q)@})" >&2 + _p9k_cache[$_p9k__cache_key]="${(pj:\0:)*}0" + _p9k__cache_val=("$@") + _p9k__state_dump_scheduled=1 +} + +_p9k_cache_get() { + _p9k__cache_key="${(pj:\0:)*}" + local v=$_p9k_cache[$_p9k__cache_key] + [[ -n $v ]] && _p9k__cache_val=("${(@0)${v[1,-2]}}") +} + +_p9k_cache_ephemeral_set() { + # Uncomment to see cache misses. + # echo "caching: ${(@0q)_p9k__cache_key} => (${(q)@})" >&2 + _p9k__cache_ephemeral[$_p9k__cache_key]="${(pj:\0:)*}0" + _p9k__cache_val=("$@") +} + +_p9k_cache_ephemeral_get() { + _p9k__cache_key="${(pj:\0:)*}" + local v=$_p9k__cache_ephemeral[$_p9k__cache_key] + [[ -n $v ]] && _p9k__cache_val=("${(@0)${v[1,-2]}}") +} + +_p9k_cache_stat_get() { + local -H stat + local label=$1 f + shift + + _p9k__cache_stat_meta= + _p9k__cache_stat_fprint= + + for f; do + if zstat -H stat -- $f 2>/dev/null; then + _p9k__cache_stat_meta+="${(q)f} $stat[inode] $stat[mtime] $stat[size] $stat[mode]; " + fi + done + + if _p9k_cache_get $0 $label meta "$@"; then + if [[ $_p9k__cache_val[1] == $_p9k__cache_stat_meta ]]; then + _p9k__cache_stat_fprint=$_p9k__cache_val[2] + local -a key=($0 $label fprint "$@" "$_p9k__cache_stat_fprint") + _p9k__cache_fprint_key="${(pj:\0:)key}" + shift 2 _p9k__cache_val + return 0 + else + local -a key=($0 $label fprint "$@" "$_p9k__cache_val[2]") + _p9k__cache_ephemeral[${(pj:\0:)key}]="${(pj:\0:)_p9k__cache_val[3,-1]}0" + fi + fi + + if (( $+commands[md5] )); then + _p9k__cache_stat_fprint="$(md5 -- $* 2>&1)" + elif (( $+commands[md5sum] )); then + _p9k__cache_stat_fprint="$(md5sum -b -- $* 2>&1)" + else + return 1 + fi + + local meta_key=$_p9k__cache_key + if _p9k_cache_ephemeral_get $0 $label fprint "$@" "$_p9k__cache_stat_fprint"; then + _p9k__cache_fprint_key=$_p9k__cache_key + _p9k__cache_key=$meta_key + _p9k_cache_set "$_p9k__cache_stat_meta" "$_p9k__cache_stat_fprint" "$_p9k__cache_val[@]" + shift 2 _p9k__cache_val + return 0 + fi + + _p9k__cache_fprint_key=$_p9k__cache_key + _p9k__cache_key=$meta_key + return 1 +} + +_p9k_cache_stat_set() { + _p9k_cache_set "$_p9k__cache_stat_meta" "$_p9k__cache_stat_fprint" "$@" + _p9k__cache_key=$_p9k__cache_fprint_key + _p9k_cache_ephemeral_set "$@" +} + +# _p9k_param prompt_foo_BAR BACKGROUND red +_p9k_param() { + local key="_p9k_param ${(pj:\0:)*}" + _p9k__ret=$_p9k_cache[$key] + if [[ -n $_p9k__ret ]]; then + _p9k__ret[-1,-1]='' + else + if [[ $1 == (#b)prompt_([a-z0-9_]#)(*) ]]; then + local var=_POWERLEVEL9K_${(U)match[1]}$match[2]_$2 + if (( $+parameters[$var] )); then + _p9k__ret=${(P)var} + else + var=_POWERLEVEL9K_${(U)match[1]%_}_$2 + if (( $+parameters[$var] )); then + _p9k__ret=${(P)var} + else + var=_POWERLEVEL9K_$2 + if (( $+parameters[$var] )); then + _p9k__ret=${(P)var} + else + _p9k__ret=$3 + fi + fi + fi + else + local var=_POWERLEVEL9K_$2 + if (( $+parameters[$var] )); then + _p9k__ret=${(P)var} + else + _p9k__ret=$3 + fi + fi + _p9k_cache[$key]=${_p9k__ret}. + fi +} + +# _p9k_get_icon prompt_foo_BAR BAZ_ICON quix +_p9k_get_icon() { + local key="_p9k_get_icon ${(pj:\0:)*}" + _p9k__ret=$_p9k_cache[$key] + if [[ -n $_p9k__ret ]]; then + _p9k__ret[-1,-1]='' + else + if [[ $2 == $'\1'* ]]; then + _p9k__ret=${2[2,-1]} + else + _p9k_param "$1" "$2" ${icons[$2]-$'\1'$3} + if [[ $_p9k__ret == $'\1'* ]]; then + _p9k__ret=${_p9k__ret[2,-1]} + else + _p9k__ret=${(g::)_p9k__ret} + [[ $_p9k__ret != $'\b'? ]] || _p9k__ret="%{$_p9k__ret%}" # penance for past sins + fi + fi + _p9k_cache[$key]=${_p9k__ret}. + fi +} + +_p9k_translate_color() { + if [[ $1 == <-> ]]; then # decimal color code: 255 + _p9k__ret=${(l.3..0.)1} + elif [[ $1 == '#'[[:xdigit:]]## ]]; then # hexademical color code: #ffffff + _p9k__ret=${(L)1} + else # named color: red + # Strip prifixes if there are any. + _p9k__ret=$__p9k_colors[${${${1#bg-}#fg-}#br}] + fi +} + +# _p9k_color prompt_foo_BAR BACKGROUND red +_p9k_color() { + local key="_p9k_color ${(pj:\0:)*}" + _p9k__ret=$_p9k_cache[$key] + if [[ -n $_p9k__ret ]]; then + _p9k__ret[-1,-1]='' + else + _p9k_param "$@" + _p9k_translate_color $_p9k__ret + _p9k_cache[$key]=${_p9k__ret}. + fi +} + +# _p9k_vcs_style CLEAN REMOTE_BRANCH +_p9k_vcs_style() { + local key="$0 ${(pj:\0:)*}" + _p9k__ret=$_p9k_cache[$key] + if [[ -n $_p9k__ret ]]; then + _p9k__ret[-1,-1]='' + else + local style=%b # TODO: support bold + _p9k_color prompt_vcs_$1 BACKGROUND "${__p9k_vcs_states[$1]}" + _p9k_background $_p9k__ret + style+=$_p9k__ret + + local var=_POWERLEVEL9K_VCS_${1}_${2}FORMAT_FOREGROUND + if (( $+parameters[$var] )); then + _p9k_translate_color "${(P)var}" + else + var=_POWERLEVEL9K_VCS_${2}FORMAT_FOREGROUND + if (( $+parameters[$var] )); then + _p9k_translate_color "${(P)var}" + else + _p9k_color prompt_vcs_$1 FOREGROUND "$_p9k_color1" + fi + fi + + _p9k_foreground $_p9k__ret + _p9k__ret=$style$_p9k__ret + _p9k_cache[$key]=${_p9k__ret}. + fi +} + +_p9k_background() { + [[ -n $1 ]] && _p9k__ret="%K{$1}" || _p9k__ret="%k" +} + +_p9k_foreground() { + # Note: This code used to produce `%1F` instead of `%F{1}` because it's more efficient. + # Unfortunately, this triggers a bug in zsh. Namely, `%1F{2}` gets percent-expanded as if + # it was `%F{2}`. + [[ -n $1 ]] && _p9k__ret="%F{$1}" || _p9k__ret="%f" +} + +_p9k_escape_style() { + [[ $1 == *'}'* ]] && _p9k__ret='${:-"'$1'"}' || _p9k__ret=$1 +} + +_p9k_escape() { + [[ $1 == *["~!#\`\$^&*()\\\"'<>?{}[]"]* ]] && _p9k__ret="\${(Q)\${:-${(qqq)${(q)1}}}}" || _p9k__ret=$1 +} + +# * $1: Name of the function that was originally invoked. +# Necessary, to make the dynamic color-overwrite mechanism work. +# * $2: Background color. +# * $3: Foreground color. +# * $4: An identifying icon. +# * $5: 1 to to perform parameter expansion and process substitution. +# * $6: If not empty but becomes empty after parameter expansion and process substitution, +# the segment isn't rendered. +# * $7: Content. +_p9k_left_prompt_segment() { + if ! _p9k_cache_get "$0" "$1" "$2" "$3" "$4" "$_p9k__segment_index"; then + _p9k_color $1 BACKGROUND $2 + local bg_color=$_p9k__ret + _p9k_background $bg_color + local bg=$_p9k__ret + + _p9k_color $1 FOREGROUND $3 + local fg_color=$_p9k__ret + _p9k_foreground $fg_color + local fg=$_p9k__ret + + local style=%b$bg$fg + local style_=${style//\}/\\\}} + + _p9k_get_icon $1 LEFT_SEGMENT_SEPARATOR + local sep=$_p9k__ret + _p9k_escape $_p9k__ret + local sep_=$_p9k__ret + + _p9k_get_icon $1 LEFT_SUBSEGMENT_SEPARATOR + _p9k_escape $_p9k__ret + local subsep_=$_p9k__ret + + local icon_ + if [[ -n $4 ]]; then + _p9k_get_icon $1 $4 + _p9k_escape $_p9k__ret + icon_=$_p9k__ret + fi + + _p9k_get_icon $1 LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL + local start_sep=$_p9k__ret + [[ -n $start_sep ]] && start_sep="%b%k%F{$bg_color}$start_sep" + + _p9k_get_icon $1 LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL $sep + _p9k_escape $_p9k__ret + local end_sep_=$_p9k__ret + + _p9k_get_icon $1 WHITESPACE_BETWEEN_LEFT_SEGMENTS ' ' + local space=$_p9k__ret + + _p9k_get_icon $1 LEFT_LEFT_WHITESPACE $space + local left_space=$_p9k__ret + [[ $left_space == *%* ]] && left_space+=$style + + _p9k_get_icon $1 LEFT_RIGHT_WHITESPACE $space + _p9k_escape $_p9k__ret + local right_space_=$_p9k__ret + [[ $right_space_ == *%* ]] && right_space_+=$style_ + + local s='<_p9k__s>' ss='<_p9k__ss>' + + local -i non_hermetic=0 + + # Segment separator logic: + # + # if [[ $_p9k__bg == NONE ]]; then + # 1 + # elif (( joined )); then + # 2 + # elif [[ $bg_color == (${_p9k__bg}|${_p9k__bg:-0}) ]]; then + # 3 + # else + # 4 + # fi + + local t=$(($#_p9k_t - __p9k_ksh_arrays)) + _p9k_t+=$start_sep$style$left_space # 1 + _p9k_t+=$style # 2 + if [[ -n $fg_color && $fg_color == $bg_color ]]; then + if [[ $fg_color == $_p9k_color1 ]]; then + _p9k_foreground $_p9k_color2 + else + _p9k_foreground $_p9k_color1 + fi + _p9k_t+=%b$bg$_p9k__ret$ss$style$left_space # 3 + else + _p9k_t+=%b$bg$ss$style$left_space # 3 + fi + _p9k_t+=%b$bg$s$style$left_space # 4 + + local join="_p9k__i>=$_p9k_left_join[$_p9k__segment_index]" + _p9k_param $1 SELF_JOINED false + if [[ $_p9k__ret == false ]]; then + if (( _p9k__segment_index > $_p9k_left_join[$_p9k__segment_index] )); then + join+="&&_p9k__i<$_p9k__segment_index" + else + join= + fi + fi + + local p= + p+="\${_p9k__n::=}" + p+="\${\${\${_p9k__bg:-0}:#NONE}:-\${_p9k__n::=$((t+1))}}" # 1 + if [[ -n $join ]]; then + p+="\${_p9k__n:=\${\${\$(($join)):#0}:+$((t+2))}}" # 2 + fi + if (( __p9k_sh_glob )); then + p+="\${_p9k__n:=\${\${(M)\${:-x$bg_color}:#x\$_p9k__bg}:+$((t+3))}}" # 3 + p+="\${_p9k__n:=\${\${(M)\${:-x$bg_color}:#x\$${_p9k__bg:-0}}:+$((t+3))}}" # 3 + else + p+="\${_p9k__n:=\${\${(M)\${:-x$bg_color}:#x(\$_p9k__bg|\${_p9k__bg:-0})}:+$((t+3))}}" # 3 + fi + p+="\${_p9k__n:=$((t+4))}" # 4 + + _p9k_param $1 VISUAL_IDENTIFIER_EXPANSION '${P9K_VISUAL_IDENTIFIER}' + [[ $_p9k__ret == (|*[^\\])'$('* ]] && non_hermetic=1 + local icon_exp_=${_p9k__ret:+\"$_p9k__ret\"} + + _p9k_param $1 CONTENT_EXPANSION '${P9K_CONTENT}' + [[ $_p9k__ret == (|*[^\\])'$('* ]] && non_hermetic=1 + local content_exp_=${_p9k__ret:+\"$_p9k__ret\"} + + if [[ ( $icon_exp_ != '"${P9K_VISUAL_IDENTIFIER}"' && $icon_exp_ == *'$'* ) || + ( $content_exp_ != '"${P9K_CONTENT}"' && $content_exp_ == *'$'* ) ]]; then + p+="\${P9K_VISUAL_IDENTIFIER::=$icon_}" + fi + + local -i has_icon=-1 # maybe + + if [[ $icon_exp_ != '"${P9K_VISUAL_IDENTIFIER}"' && $icon_exp_ == *'$'* ]]; then + p+='${_p9k__v::='$icon_exp_$style_'}' + else + [[ $icon_exp_ == '"${P9K_VISUAL_IDENTIFIER}"' ]] && _p9k__ret=$icon_ || _p9k__ret=$icon_exp_ + if [[ -n $_p9k__ret ]]; then + p+="\${_p9k__v::=$_p9k__ret" + [[ $_p9k__ret == *%* ]] && p+=$style_ + p+="}" + has_icon=1 # definitely yes + else + has_icon=0 # definitely no + fi + fi + + p+="\${_p9k__c::=$content_exp_}" + p+='${_p9k__e::=${${_p9k__'${_p9k__line_index}l${${1#prompt_}%%[A-Z_]#}'+00}:-' + if (( has_icon == -1 )); then + p+='${${(%):-$_p9k__c%1(l.1.0)}[-1]}${${(%):-$_p9k__v%1(l.1.0)}[-1]}}' + else + p+='${${(%):-$_p9k__c%1(l.1.0)}[-1]}'$has_icon'}' + fi + + p+='}}+}' + + p+='${${_p9k__e:#00}:+${${_p9k_t[$_p9k__n]/'$ss'/$_p9k__ss}/'$s'/$_p9k__s}' + + _p9k_param $1 ICON_BEFORE_CONTENT '' + if [[ $_p9k__ret != false ]]; then + _p9k_param $1 PREFIX '' + _p9k__ret=${(g::)_p9k__ret} + _p9k_escape $_p9k__ret + p+=$_p9k__ret + [[ $_p9k__ret == *%* ]] && local -i need_style=1 || local -i need_style=0 + + if (( has_icon != 0 )); then + _p9k_color $1 VISUAL_IDENTIFIER_COLOR $fg_color + _p9k_foreground $_p9k__ret + _p9k__ret=%b$bg$_p9k__ret + _p9k__ret=${_p9k__ret//\}/\\\}} + [[ $_p9k__ret != $style_ || $need_style == 1 ]] && p+=$_p9k__ret + p+='${_p9k__v}' + + _p9k_get_icon $1 LEFT_MIDDLE_WHITESPACE ' ' + if [[ -n $_p9k__ret ]]; then + _p9k_escape $_p9k__ret + [[ _p9k__ret == *%* ]] && _p9k__ret+=$style_ + p+='${${(M)_p9k__e:#11}:+'$_p9k__ret'}' + fi + elif (( need_style )); then + p+=$style_ + fi + + p+='${_p9k__c}'$style_ + else + _p9k_param $1 PREFIX '' + _p9k__ret=${(g::)_p9k__ret} + _p9k_escape $_p9k__ret + p+=$_p9k__ret + [[ $_p9k__ret == *%* ]] && p+=$style_ + + p+='${_p9k__c}'$style_ + + if (( has_icon != 0 )); then + local -i need_style=0 + _p9k_get_icon $1 LEFT_MIDDLE_WHITESPACE ' ' + if [[ -n $_p9k__ret ]]; then + _p9k_escape $_p9k__ret + [[ $_p9k__ret == *%* ]] && need_style=1 + p+='${${(M)_p9k__e:#11}:+'$_p9k__ret'}' + fi + + _p9k_color $1 VISUAL_IDENTIFIER_COLOR $fg_color + _p9k_foreground $_p9k__ret + _p9k__ret=%b$bg$_p9k__ret + _p9k__ret=${_p9k__ret//\}/\\\}} + [[ $_p9k__ret != $style_ || $need_style == 1 ]] && p+=$_p9k__ret + p+='$_p9k__v' + fi + fi + + _p9k_param $1 SUFFIX '' + _p9k__ret=${(g::)_p9k__ret} + _p9k_escape $_p9k__ret + p+=$_p9k__ret + [[ $_p9k__ret == *%* && -n $right_space_ ]] && p+=$style_ + p+=$right_space_ + + p+='${${:-' + p+="\${_p9k__s::=%F{$bg_color\}$sep_}\${_p9k__ss::=$subsep_}\${_p9k__sss::=%F{$bg_color\}$end_sep_}" + p+="\${_p9k__i::=$_p9k__segment_index}\${_p9k__bg::=$bg_color}" + p+='}+}' + + p+='}' + + _p9k_param $1 SHOW_ON_UPGLOB '' + _p9k_cache_set "$p" $non_hermetic $_p9k__ret + fi + + if [[ -n $_p9k__cache_val[3] ]]; then + _p9k__has_upglob=1 + _p9k_upglob $_p9k__cache_val[3] && return + fi + + _p9k__non_hermetic_expansion=$_p9k__cache_val[2] + + (( $5 )) && _p9k__ret=\"$7\" || _p9k_escape $7 + if [[ -z $6 ]]; then + _p9k__prompt+="\${\${:-\${P9K_CONTENT::=$_p9k__ret}$_p9k__cache_val[1]" + else + _p9k__prompt+="\${\${:-\"$6\"}:+\${\${:-\${P9K_CONTENT::=$_p9k__ret}$_p9k__cache_val[1]}" + fi +} + +# The same as _p9k_left_prompt_segment above but for the right prompt. +_p9k_right_prompt_segment() { + if ! _p9k_cache_get "$0" "$1" "$2" "$3" "$4" "$_p9k__segment_index"; then + _p9k_color $1 BACKGROUND $2 + local bg_color=$_p9k__ret + _p9k_background $bg_color + local bg=$_p9k__ret + local bg_=${_p9k__ret//\}/\\\}} + + _p9k_color $1 FOREGROUND $3 + local fg_color=$_p9k__ret + _p9k_foreground $fg_color + local fg=$_p9k__ret + + local style=%b$bg$fg + local style_=${style//\}/\\\}} + + _p9k_get_icon $1 RIGHT_SEGMENT_SEPARATOR + local sep=$_p9k__ret + _p9k_escape $_p9k__ret + local sep_=$_p9k__ret + + _p9k_get_icon $1 RIGHT_SUBSEGMENT_SEPARATOR + local subsep=$_p9k__ret + [[ $subsep == *%* ]] && subsep+=$style + + local icon_ + if [[ -n $4 ]]; then + _p9k_get_icon $1 $4 + _p9k_escape $_p9k__ret + icon_=$_p9k__ret + fi + + _p9k_get_icon $1 RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL $sep + local start_sep=$_p9k__ret + [[ -n $start_sep ]] && start_sep="%b%k%F{$bg_color}$start_sep" + + _p9k_get_icon $1 RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL + _p9k_escape $_p9k__ret + local end_sep_=$_p9k__ret + + _p9k_get_icon $1 WHITESPACE_BETWEEN_RIGHT_SEGMENTS ' ' + local space=$_p9k__ret + + _p9k_get_icon $1 RIGHT_LEFT_WHITESPACE $space + local left_space=$_p9k__ret + [[ $left_space == *%* ]] && left_space+=$style + + _p9k_get_icon $1 RIGHT_RIGHT_WHITESPACE $space + _p9k_escape $_p9k__ret + local right_space_=$_p9k__ret + [[ $right_space_ == *%* ]] && right_space_+=$style_ + + local w='<_p9k__w>' s='<_p9k__s>' + + local -i non_hermetic=0 + + # Segment separator logic: + # + # if [[ $_p9k__bg == NONE ]]; then + # 1 + # elif (( joined )); then + # 2 + # elif [[ $_p9k__bg == (${bg_color}|${bg_color:-0}) ]]; then + # 3 + # else + # 4 + # fi + + local t=$(($#_p9k_t - __p9k_ksh_arrays)) + _p9k_t+=$start_sep$style$left_space # 1 + _p9k_t+=$w$style # 2 + _p9k_t+=$w$style$subsep$left_space # 3 + _p9k_t+=$w%F{$bg_color}$sep$style$left_space # 4 + + local join="_p9k__i>=$_p9k_right_join[$_p9k__segment_index]" + _p9k_param $1 SELF_JOINED false + if [[ $_p9k__ret == false ]]; then + if (( _p9k__segment_index > $_p9k_right_join[$_p9k__segment_index] )); then + join+="&&_p9k__i<$_p9k__segment_index" + else + join= + fi + fi + + local p= + p+="\${_p9k__n::=}" + p+="\${\${\${_p9k__bg:-0}:#NONE}:-\${_p9k__n::=$((t+1))}}" # 1 + if [[ -n $join ]]; then + p+="\${_p9k__n:=\${\${\$(($join)):#0}:+$((t+2))}}" # 2 + fi + if (( __p9k_sh_glob )); then + p+="\${_p9k__n:=\${\${(M)\${:-x\$_p9k__bg}:#x${(b)bg_color}}:+$((t+3))}}" # 3 + p+="\${_p9k__n:=\${\${(M)\${:-x\$_p9k__bg}:#x${(b)bg_color:-0}}:+$((t+3))}}" # 3 + else + p+="\${_p9k__n:=\${\${(M)\${:-x\$_p9k__bg}:#x(${(b)bg_color}|${(b)bg_color:-0})}:+$((t+3))}}" # 3 + fi + p+="\${_p9k__n:=$((t+4))}" # 4 + + _p9k_param $1 VISUAL_IDENTIFIER_EXPANSION '${P9K_VISUAL_IDENTIFIER}' + [[ $_p9k__ret == (|*[^\\])'$('* ]] && non_hermetic=1 + local icon_exp_=${_p9k__ret:+\"$_p9k__ret\"} + + _p9k_param $1 CONTENT_EXPANSION '${P9K_CONTENT}' + [[ $_p9k__ret == (|*[^\\])'$('* ]] && non_hermetic=1 + local content_exp_=${_p9k__ret:+\"$_p9k__ret\"} + + if [[ ( $icon_exp_ != '"${P9K_VISUAL_IDENTIFIER}"' && $icon_exp_ == *'$'* ) || + ( $content_exp_ != '"${P9K_CONTENT}"' && $content_exp_ == *'$'* ) ]]; then + p+="\${P9K_VISUAL_IDENTIFIER::=$icon_}" + fi + + local -i has_icon=-1 # maybe + + if [[ $icon_exp_ != '"${P9K_VISUAL_IDENTIFIER}"' && $icon_exp_ == *'$'* ]]; then + p+="\${_p9k__v::=$icon_exp_$style_}" + else + [[ $icon_exp_ == '"${P9K_VISUAL_IDENTIFIER}"' ]] && _p9k__ret=$icon_ || _p9k__ret=$icon_exp_ + if [[ -n $_p9k__ret ]]; then + p+="\${_p9k__v::=$_p9k__ret" + [[ $_p9k__ret == *%* ]] && p+=$style_ + p+="}" + has_icon=1 # definitely yes + else + has_icon=0 # definitely no + fi + fi + + p+="\${_p9k__c::=$content_exp_}" + p+='${_p9k__e::=${${_p9k__'${_p9k__line_index}r${${1#prompt_}%%[A-Z_]#}'+00}:-' + if (( has_icon == -1 )); then + p+='${${(%):-$_p9k__c%1(l.1.0)}[-1]}${${(%):-$_p9k__v%1(l.1.0)}[-1]}}' + else + p+='${${(%):-$_p9k__c%1(l.1.0)}[-1]}'$has_icon'}' + fi + + p+='}}+}' + + p+='${${_p9k__e:#00}:+${_p9k_t[$_p9k__n]/'$w'/$_p9k__w}' + + _p9k_param $1 ICON_BEFORE_CONTENT '' + if [[ $_p9k__ret != true ]]; then + _p9k_param $1 PREFIX '' + _p9k__ret=${(g::)_p9k__ret} + _p9k_escape $_p9k__ret + p+=$_p9k__ret + [[ $_p9k__ret == *%* ]] && p+=$style_ + + p+='${_p9k__c}'$style_ + + if (( has_icon != 0 )); then + local -i need_style=0 + _p9k_get_icon $1 RIGHT_MIDDLE_WHITESPACE ' ' + if [[ -n $_p9k__ret ]]; then + _p9k_escape $_p9k__ret + [[ $_p9k__ret == *%* ]] && need_style=1 + p+='${${(M)_p9k__e:#11}:+'$_p9k__ret'}' + fi + + _p9k_color $1 VISUAL_IDENTIFIER_COLOR $fg_color + _p9k_foreground $_p9k__ret + _p9k__ret=%b$bg$_p9k__ret + _p9k__ret=${_p9k__ret//\}/\\\}} + [[ $_p9k__ret != $style_ || $need_style == 1 ]] && p+=$_p9k__ret + p+='$_p9k__v' + fi + else + _p9k_param $1 PREFIX '' + _p9k__ret=${(g::)_p9k__ret} + _p9k_escape $_p9k__ret + p+=$_p9k__ret + [[ $_p9k__ret == *%* ]] && local -i need_style=1 || local -i need_style=0 + + if (( has_icon != 0 )); then + _p9k_color $1 VISUAL_IDENTIFIER_COLOR $fg_color + _p9k_foreground $_p9k__ret + _p9k__ret=%b$bg$_p9k__ret + _p9k__ret=${_p9k__ret//\}/\\\}} + [[ $_p9k__ret != $style_ || $need_style == 1 ]] && p+=$_p9k__ret + p+='${_p9k__v}' + + _p9k_get_icon $1 RIGHT_MIDDLE_WHITESPACE ' ' + if [[ -n $_p9k__ret ]]; then + _p9k_escape $_p9k__ret + [[ _p9k__ret == *%* ]] && _p9k__ret+=$style_ + p+='${${(M)_p9k__e:#11}:+'$_p9k__ret'}' + fi + elif (( need_style )); then + p+=$style_ + fi + + p+='${_p9k__c}'$style_ + fi + + _p9k_param $1 SUFFIX '' + _p9k__ret=${(g::)_p9k__ret} + _p9k_escape $_p9k__ret + p+=$_p9k__ret + + p+='${${:-' + + if [[ -n $fg_color && $fg_color == $bg_color ]]; then + if [[ $fg_color == $_p9k_color1 ]]; then + _p9k_foreground $_p9k_color2 + else + _p9k_foreground $_p9k_color1 + fi + else + _p9k__ret=$fg + fi + _p9k__ret=${_p9k__ret//\}/\\\}} + p+="\${_p9k__w::=${right_space_:+$style_}$right_space_%b$bg_$_p9k__ret}" + + p+='${_p9k__sss::=' + p+=$style_$right_space_ + [[ $right_space_ == *%* ]] && p+=$style_ + if [[ -n $end_sep_ ]]; then + p+="%k%F{$bg_color\}$end_sep_$style_" + fi + p+='}' + + p+="\${_p9k__i::=$_p9k__segment_index}\${_p9k__bg::=$bg_color}" + + p+='}+}' + p+='}' + + _p9k_param $1 SHOW_ON_UPGLOB '' + _p9k_cache_set "$p" $non_hermetic $_p9k__ret + fi + + if [[ -n $_p9k__cache_val[3] ]]; then + _p9k__has_upglob=1 + _p9k_upglob $_p9k__cache_val[3] && return + fi + + _p9k__non_hermetic_expansion=$_p9k__cache_val[2] + + (( $5 )) && _p9k__ret=\"$7\" || _p9k_escape $7 + if [[ -z $6 ]]; then + _p9k__prompt+="\${\${:-\${P9K_CONTENT::=$_p9k__ret}$_p9k__cache_val[1]" + else + _p9k__prompt+="\${\${:-\"$6\"}:+\${\${:-\${P9K_CONTENT::=$_p9k__ret}$_p9k__cache_val[1]}" + fi +} + +function _p9k_prompt_segment() { "_p9k_${_p9k__prompt_side}_prompt_segment" "$@" } +function p9k_prompt_segment() { p10k segment "$@" } + +function _p9k_python_version() { + _p9k_cached_cmd 1 python --version || return + [[ $_p9k__ret == (#b)Python\ ([[:digit:].]##)* ]] && _p9k__ret=$match[1] +} + +################################################################ +# Prompt Segment Definitions +################################################################ + +################################################################ +# Anaconda Environment +prompt_anaconda() { + local p=${CONDA_PREFIX:-$CONDA_ENV_PATH} + local msg='' + if (( _POWERLEVEL9K_ANACONDA_SHOW_PYTHON_VERSION )) && _p9k_python_version; then + msg="${_p9k__ret//\%//%%} " + fi + msg+="$_POWERLEVEL9K_ANACONDA_LEFT_DELIMITER${${p:t}//\%/%%}$_POWERLEVEL9K_ANACONDA_RIGHT_DELIMITER" + _p9k_prompt_segment "$0" "blue" "$_p9k_color1" 'PYTHON_ICON' 0 '' "$msg" +} + +_p9k_prompt_anaconda_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${CONDA_PREFIX:-$CONDA_ENV_PATH}' +} + +################################################################ +# AWS Profile +prompt_aws() { + local aws_profile="${AWS_VAULT:-${AWSUME_PROFILE:-${AWS_PROFILE:-$AWS_DEFAULT_PROFILE}}}" + local pat class + for pat class in "${_POWERLEVEL9K_AWS_CLASSES[@]}"; do + if [[ $aws_profile == ${~pat} ]]; then + [[ -n $class ]] && state=_${(U)class} + break + fi + done + _p9k_prompt_segment "$0$state" red white 'AWS_ICON' 0 '' "${aws_profile//\%/%%}" +} + +_p9k_prompt_aws_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${AWS_VAULT:-${AWSUME_PROFILE:-${AWS_PROFILE:-$AWS_DEFAULT_PROFILE}}}' +} + +################################################################ +# Current Elastic Beanstalk environment +prompt_aws_eb_env() { + _p9k_upglob .elasticbeanstalk && return + local dir=$_p9k__parent_dirs[$?] + + if ! _p9k_cache_stat_get $0 $dir/.elasticbeanstalk/config.yml; then + local env + env="$(command eb list 2>/dev/null)" || env= + env="${${(@M)${(@f)env}:#\* *}#\* }" + _p9k_cache_stat_set "$env" + fi + [[ -n $_p9k__cache_val[1] ]] || return + _p9k_prompt_segment "$0" black green 'AWS_EB_ICON' 0 '' "${_p9k__cache_val[1]//\%/%%}" +} + +_p9k_prompt_aws_eb_env_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$commands[eb]' +} + +################################################################ +# Segment to indicate background jobs with an icon. +prompt_background_jobs() { + local -i len=$#_p9k__prompt _p9k__has_upglob + local msg + if (( _POWERLEVEL9K_BACKGROUND_JOBS_VERBOSE )); then + if (( _POWERLEVEL9K_BACKGROUND_JOBS_VERBOSE_ALWAYS )); then + msg='${(%):-%j}' + else + msg='${${(%):-%j}:#1}' + fi + fi + _p9k_prompt_segment $0 "$_p9k_color1" cyan BACKGROUND_JOBS_ICON 1 '${${(%):-%j}:#0}' "$msg" + (( _p9k__has_upglob )) || typeset -g "_p9k__segment_val_${_p9k__prompt_side}[_p9k__segment_index]"=$_p9k__prompt[len+1,-1] +} + +################################################################ +# Segment that indicates usage level of current partition. +prompt_disk_usage() { + local -i len=$#_p9k__prompt _p9k__has_upglob + _p9k_prompt_segment $0_CRITICAL red white DISK_ICON 1 '$_p9k__disk_usage_critical' '$_p9k__disk_usage_pct%%' + _p9k_prompt_segment $0_WARNING yellow $_p9k_color1 DISK_ICON 1 '$_p9k__disk_usage_warning' '$_p9k__disk_usage_pct%%' + if (( ! _POWERLEVEL9K_DISK_USAGE_ONLY_WARNING )); then + _p9k_prompt_segment $0_NORMAL $_p9k_color1 yellow DISK_ICON 1 '$_p9k__disk_usage_normal' '$_p9k__disk_usage_pct%%' + fi + (( _p9k__has_upglob )) || typeset -g "_p9k__segment_val_${_p9k__prompt_side}[_p9k__segment_index]"=$_p9k__prompt[len+1,-1] +} + +_p9k_prompt_disk_usage_init() { + typeset -g _p9k__disk_usage_pct= + typeset -g _p9k__disk_usage_normal= + typeset -g _p9k__disk_usage_warning= + typeset -g _p9k__disk_usage_critical= + _p9k__async_segments_compute+='_p9k_worker_invoke disk_usage "_p9k_prompt_disk_usage_compute ${(q)_p9k__cwd_a}"' +} + +_p9k_prompt_disk_usage_compute() { + (( $+commands[df] )) || return + _p9k_worker_async "_p9k_prompt_disk_usage_async ${(q)1}" _p9k_prompt_disk_usage_sync +} + +_p9k_prompt_disk_usage_async() { + local pct=${${=${(f)"$(df -P $1 2>/dev/null)"}[2]}[5]%%%} + [[ $pct == <0-100> && $pct != $_p9k__disk_usage_pct ]] || return + _p9k__disk_usage_pct=$pct + _p9k__disk_usage_normal= + _p9k__disk_usage_warning= + _p9k__disk_usage_critical= + if (( _p9k__disk_usage_pct >= _POWERLEVEL9K_DISK_USAGE_CRITICAL_LEVEL )); then + _p9k__disk_usage_critical=1 + elif (( _p9k__disk_usage_pct >= _POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL )); then + _p9k__disk_usage_warning=1 + elif (( ! _POWERLEVEL9K_DISK_USAGE_ONLY_WARNING )); then + _p9k__disk_usage_normal=1 + fi + _p9k_print_params \ + _p9k__disk_usage_pct \ + _p9k__disk_usage_normal \ + _p9k__disk_usage_warning \ + _p9k__disk_usage_critical + echo -E - 'reset=1' +} + +_p9k_prompt_disk_usage_sync() { + eval $REPLY + _p9k_worker_reply $REPLY +} + +function _p9k_read_file() { + _p9k__ret='' + [[ -n $1 ]] && IFS='' read -r _p9k__ret <$1 + [[ -n $_p9k__ret ]] +} + +prompt_fvm() { + _p9k_upglob fvm && return + local link=$_p9k__parent_dirs[$?]/fvm + if [[ -L $link ]]; then + if [[ ${link:A} == (#b)*/versions/([^/]##)/bin/flutter ]]; then + _p9k_prompt_segment $0 blue $_p9k_color1 FLUTTER_ICON 0 '' ${match[1]//\%/%%} + fi + fi +} + +_p9k_prompt_fvm_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$commands[fvm]' +} + +################################################################ +# Segment that displays the battery status in levels and colors +prompt_battery() { + [[ $_p9k_os == (Linux|Android) ]] && _p9k_prompt_battery_set_args + (( $#_p9k__battery_args )) && _p9k_prompt_segment "${_p9k__battery_args[@]}" +} + +_p9k_prompt_battery_init() { + typeset -ga _p9k__battery_args=() + if [[ $_p9k_os == OSX && $+commands[pmset] == 1 ]]; then + _p9k__async_segments_compute+='_p9k_worker_invoke battery _p9k_prompt_battery_compute' + return + fi + if [[ $_p9k_os != (Linux|Android) || + -z /sys/class/power_supply/(BAT*|battery)/(energy_full|charge_full|charge_counter)(#qN) ]]; then + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${:-}' + fi +} + +_p9k_prompt_battery_compute() { + _p9k_worker_async _p9k_prompt_battery_async _p9k_prompt_battery_sync +} + +_p9k_prompt_battery_async() { + local prev="${(pj:\0:)_p9k__battery_args}" + _p9k_prompt_battery_set_args + [[ "${(pj:\0:)_p9k__battery_args}" == $prev ]] && return 1 + _p9k_print_params _p9k__battery_args + echo -E - 'reset=2' +} + +_p9k_prompt_battery_sync() { + eval $REPLY + _p9k_worker_reply $REPLY +} + +_p9k_prompt_battery_set_args() { + _p9k__battery_args=() + + local state remain + local -i bat_percent + + case $_p9k_os in + OSX) + (( $+commands[pmset] )) || return + local raw_data=${${(Af)"$(pmset -g batt 2>/dev/null)"}[2]} + [[ $raw_data == *InternalBattery* ]] || return + remain=${${(s: :)${${(s:; :)raw_data}[3]}}[1]} + [[ $remain == *no* ]] && remain="..." + [[ $raw_data =~ '([0-9]+)%' ]] && bat_percent=$match[1] + + case "${${(s:; :)raw_data}[2]}" in + 'charging'|'finishing charge'|'AC attached') + if (( bat_percent == 100 )); then + state=CHARGED + remain='' + else + state=CHARGING + fi + ;; + 'discharging') + (( bat_percent < _POWERLEVEL9K_BATTERY_LOW_THRESHOLD )) && state=LOW || state=DISCONNECTED + ;; + *) + state=CHARGED + remain='' + ;; + esac + ;; + + Linux|Android) + # See https://sourceforge.net/projects/acpiclient. + local -a bats=( /sys/class/power_supply/(BAT*|battery)/(FN) ) + (( $#bats )) || return + + local -i energy_now energy_full power_now + local -i is_full=1 is_calculating is_charching + local dir + for dir in $bats; do + local -i pow=0 full=0 + if _p9k_read_file $dir/(energy_full|charge_full|charge_counter)(N); then + (( energy_full += ${full::=_p9k__ret} )) + fi + if _p9k_read_file $dir/(power|current)_now(N) && (( $#_p9k__ret < 9 )); then + (( power_now += ${pow::=$_p9k__ret} )) + fi + if _p9k_read_file $dir/(energy|charge)_now(N); then + (( energy_now += _p9k__ret )) + elif _p9k_read_file $dir/capacity(N); then + (( energy_now += _p9k__ret * full / 100. + 0.5 )) + fi + _p9k_read_file $dir/status(N) && local bat_status=$_p9k__ret || continue + [[ $bat_status != Full ]] && is_full=0 + [[ $bat_status == Charging ]] && is_charching=1 + [[ $bat_status == (Charging|Discharging) && $pow == 0 ]] && is_calculating=1 + done + + (( energy_full )) || return + + bat_percent=$(( 100. * energy_now / energy_full + 0.5 )) + (( bat_percent > 100 )) && bat_percent=100 + + if (( is_full || (bat_percent == 100 && is_charching) )); then + state=CHARGED + else + if (( is_charching )); then + state=CHARGING + elif (( bat_percent < _POWERLEVEL9K_BATTERY_LOW_THRESHOLD )); then + state=LOW + else + state=DISCONNECTED + fi + + if (( power_now > 0 )); then + (( is_charching )) && local -i e=$((energy_full - energy_now)) || local -i e=energy_now + local -i minutes=$(( 60 * e / power_now )) + (( minutes > 0 )) && remain=$((minutes/60)):${(l#2##0#)$((minutes%60))} + elif (( is_calculating )); then + remain="..." + fi + fi + ;; + + *) + return 0 + ;; + esac + + (( bat_percent >= _POWERLEVEL9K_BATTERY_HIDE_ABOVE_THRESHOLD )) && return + + local msg="$bat_percent%%" + [[ $_POWERLEVEL9K_BATTERY_VERBOSE == 1 && -n $remain ]] && msg+=" ($remain)" + + local icon=BATTERY_ICON + local var=_POWERLEVEL9K_BATTERY_${state}_STAGES + local -i idx="${#${(@P)var}}" + if (( idx )); then + (( bat_percent < 100 )) && idx=$((bat_percent * idx / 100 + 1)) + icon=$'\1'"${${(@P)var}[idx]}" + fi + + local bg=$_p9k_color1 + local var=_POWERLEVEL9K_BATTERY_${state}_LEVEL_BACKGROUND + local -i idx="${#${(@P)var}}" + if (( idx )); then + (( bat_percent < 100 )) && idx=$((bat_percent * idx / 100 + 1)) + bg="${${(@P)var}[idx]}" + fi + + local fg=$_p9k_battery_states[$state] + local var=_POWERLEVEL9K_BATTERY_${state}_LEVEL_FOREGROUND + local -i idx="${#${(@P)var}}" + if (( idx )); then + (( bat_percent < 100 )) && idx=$((bat_percent * idx / 100 + 1)) + fg="${${(@P)var}[idx]}" + fi + + _p9k__battery_args=(prompt_battery_$state "$bg" "$fg" $icon 0 '' $msg) +} + +################################################################ +# Public IP segment +prompt_public_ip() { + local -i len=$#_p9k__prompt _p9k__has_upglob + local ip='${_p9k__public_ip:-$_POWERLEVEL9K_PUBLIC_IP_NONE}' + if [[ -n $_POWERLEVEL9K_PUBLIC_IP_VPN_INTERFACE ]]; then + _p9k_prompt_segment "$0" "$_p9k_color1" "$_p9k_color2" PUBLIC_IP_ICON 1 '${_p9k__public_ip_not_vpn:+'$ip'}' $ip + _p9k_prompt_segment "$0" "$_p9k_color1" "$_p9k_color2" VPN_ICON 1 '${_p9k__public_ip_vpn:+'$ip'}' $ip + else + _p9k_prompt_segment "$0" "$_p9k_color1" "$_p9k_color2" PUBLIC_IP_ICON 1 $ip $ip + fi + (( _p9k__has_upglob )) || typeset -g "_p9k__segment_val_${_p9k__prompt_side}[_p9k__segment_index]"=$_p9k__prompt[len+1,-1] +} + +_p9k_prompt_public_ip_init() { + typeset -g _p9k__public_ip= + typeset -gF _p9k__public_ip_next_time=0 + _p9k__async_segments_compute+='_p9k_worker_invoke public_ip _p9k_prompt_public_ip_compute' +} + +_p9k_prompt_public_ip_compute() { + (( EPOCHREALTIME >= _p9k__public_ip_next_time )) || return + _p9k_worker_async _p9k_prompt_public_ip_async _p9k_prompt_public_ip_sync +} + +_p9k_prompt_public_ip_async() { + local ip method + local -F start=EPOCHREALTIME + local -F next='start + 5' + for method in $_POWERLEVEL9K_PUBLIC_IP_METHODS $_POWERLEVEL9K_PUBLIC_IP_METHODS; do + case $method in + dig) + if (( $+commands[dig] )); then + ip="$(dig +tries=1 +short -4 A myip.opendns.com @resolver1.opendns.com 2>/dev/null)" + [[ $ip == ';'* ]] && ip= + if [[ -z $ip ]]; then + ip="$(dig +tries=1 +short -6 AAAA myip.opendns.com @resolver1.opendns.com 2>/dev/null)" + [[ $ip == ';'* ]] && ip= + fi + fi + ;; + curl) + if (( $+commands[curl] )); then + ip="$(curl --max-time 5 -w '\n' "$_POWERLEVEL9K_PUBLIC_IP_HOST" 2>/dev/null)" + fi + ;; + wget) + if (( $+commands[wget] )); then + ip="$(wget -T 5 -qO- "$_POWERLEVEL9K_PUBLIC_IP_HOST" 2>/dev/null)" + fi + ;; + esac + [[ $ip =~ '^[0-9a-f.:]+$' ]] || ip='' + if [[ -n $ip ]]; then + next=$((start + _POWERLEVEL9K_PUBLIC_IP_TIMEOUT)) + break + fi + done + _p9k__public_ip_next_time=$next + _p9k_print_params _p9k__public_ip_next_time + [[ $_p9k__public_ip == $ip ]] && return + _p9k__public_ip=$ip + _p9k_print_params _p9k__public_ip + echo -E - 'reset=1' +} + +_p9k_prompt_public_ip_sync() { + eval $REPLY + _p9k_worker_reply $REPLY +} + +################################################################ +# Context: user@hostname (who am I and where am I) +prompt_context() { + local -i len=$#_p9k__prompt _p9k__has_upglob + + local content + if [[ $_POWERLEVEL9K_ALWAYS_SHOW_CONTEXT == 0 && -n $DEFAULT_USER && $P9K_SSH == 0 ]]; then + local user="${(%):-%n}" + if [[ $user == $DEFAULT_USER ]]; then + content="${user//\%/%%}" + fi + fi + + local state + if (( P9K_SSH )); then + if [[ -n "$SUDO_COMMAND" ]]; then + state="REMOTE_SUDO" + else + state="REMOTE" + fi + elif [[ -n "$SUDO_COMMAND" ]]; then + state="SUDO" + else + state="DEFAULT" + fi + + local cond + for state cond in $state '${${(%):-%#}:#\#}' ROOT '${${(%):-%#}:#\%}'; do + local text=$content + if [[ -z $text ]]; then + local var=_POWERLEVEL9K_CONTEXT_${state}_TEMPLATE + if (( $+parameters[$var] )); then + text=${(P)var} + text=${(g::)text} + else + text=$_POWERLEVEL9K_CONTEXT_TEMPLATE + fi + fi + _p9k_prompt_segment "$0_$state" "$_p9k_color1" yellow '' 0 "$cond" "$text" + done + + (( _p9k__has_upglob )) || typeset -g "_p9k__segment_val_${_p9k__prompt_side}[_p9k__segment_index]"=$_p9k__prompt[len+1,-1] +} + +instant_prompt_context() { + if [[ $_POWERLEVEL9K_ALWAYS_SHOW_CONTEXT == 0 && -n $DEFAULT_USER && $P9K_SSH == 0 ]]; then + if [[ ${(%):-%n} == $DEFAULT_USER ]]; then + if (( ! _POWERLEVEL9K_ALWAYS_SHOW_USER )); then + return + fi + fi + fi + prompt_context +} + +_p9k_prompt_context_init() { + if [[ $_POWERLEVEL9K_ALWAYS_SHOW_CONTEXT == 0 && -n $DEFAULT_USER && $P9K_SSH == 0 ]]; then + if [[ ${(%):-%n} == $DEFAULT_USER ]]; then + if (( ! _POWERLEVEL9K_ALWAYS_SHOW_USER )); then + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${:-}' + fi + fi + fi +} + +################################################################ +# User: user (who am I) +prompt_user() { + local -i len=$#_p9k__prompt _p9k__has_upglob + _p9k_prompt_segment "${0}_ROOT" "${_p9k_color1}" yellow ROOT_ICON 0 '${${(%):-%#}:#\%}' "$_POWERLEVEL9K_USER_TEMPLATE" + if [[ -n "$SUDO_COMMAND" ]]; then + _p9k_prompt_segment "${0}_SUDO" "${_p9k_color1}" yellow SUDO_ICON 0 '${${(%):-%#}:#\#}' "$_POWERLEVEL9K_USER_TEMPLATE" + else + _p9k_prompt_segment "${0}_DEFAULT" "${_p9k_color1}" yellow USER_ICON 0 '${${(%):-%#}:#\#}' "%n" + fi + (( _p9k__has_upglob )) || typeset -g "_p9k__segment_val_${_p9k__prompt_side}[_p9k__segment_index]"=$_p9k__prompt[len+1,-1] +} + +instant_prompt_user() { + if [[ $_POWERLEVEL9K_ALWAYS_SHOW_USER == 0 && "${(%):-%n}" == $DEFAULT_USER ]]; then + return + fi + prompt_user +} + +_p9k_prompt_user_init() { + if [[ $_POWERLEVEL9K_ALWAYS_SHOW_USER == 0 && "${(%):-%n}" == $DEFAULT_USER ]]; then + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${:-}' + fi +} + +################################################################ +# Host: machine (where am I) +prompt_host() { + local -i len=$#_p9k__prompt _p9k__has_upglob + if (( P9K_SSH )); then + _p9k_prompt_segment "$0_REMOTE" "${_p9k_color1}" yellow SSH_ICON 0 '' "$_POWERLEVEL9K_HOST_TEMPLATE" + else + _p9k_prompt_segment "$0_LOCAL" "${_p9k_color1}" yellow HOST_ICON 0 '' "$_POWERLEVEL9K_HOST_TEMPLATE" + fi + (( _p9k__has_upglob )) || typeset -g "_p9k__segment_val_${_p9k__prompt_side}[_p9k__segment_index]"=$_p9k__prompt[len+1,-1] +} + +instant_prompt_host() { prompt_host; } + +################################################################ +# The 'custom` prompt provides a way for users to invoke commands and display +# the output in a segment. +_p9k_custom_prompt() { + local segment_name=${1:u} + local command=_POWERLEVEL9K_CUSTOM_${segment_name} + command=${(P)command} + local parts=("${(@z)command}") + local cmd="${(Q)parts[1]}" + (( $+functions[$cmd] || $+commands[$cmd] )) || return + local content="$(eval $command)" + [[ -n $content ]] || return + _p9k_prompt_segment "prompt_custom_$1" $_p9k_color2 $_p9k_color1 "CUSTOM_${segment_name}_ICON" 0 '' "$content" +} + +################################################################ +# Display the duration the command needed to run. +prompt_command_execution_time() { + (( $+P9K_COMMAND_DURATION_SECONDS )) || return + (( P9K_COMMAND_DURATION_SECONDS >= _POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD )) || return + + if (( P9K_COMMAND_DURATION_SECONDS < 60 )); then + if (( !_POWERLEVEL9K_COMMAND_EXECUTION_TIME_PRECISION )); then + local -i sec=$((P9K_COMMAND_DURATION_SECONDS + 0.5)) + else + local -F $_POWERLEVEL9K_COMMAND_EXECUTION_TIME_PRECISION sec=P9K_COMMAND_DURATION_SECONDS + fi + local text=${sec}s + else + local -i d=$((P9K_COMMAND_DURATION_SECONDS + 0.5)) + if [[ $_POWERLEVEL9K_COMMAND_EXECUTION_TIME_FORMAT == "H:M:S" ]]; then + local text=${(l.2..0.)$((d % 60))} + if (( d >= 60 )); then + text=${(l.2..0.)$((d / 60 % 60))}:$text + if (( d >= 36000 )); then + text=$((d / 3600)):$text + elif (( d >= 3600 )); then + text=0$((d / 3600)):$text + fi + fi + else + local text="$((d % 60))s" + if (( d >= 60 )); then + text="$((d / 60 % 60))m $text" + if (( d >= 3600 )); then + text="$((d / 3600 % 24))h $text" + if (( d >= 86400 )); then + text="$((d / 86400))d $text" + fi + fi + fi + fi + fi + + _p9k_prompt_segment "$0" "red" "yellow1" 'EXECUTION_TIME_ICON' 0 '' $text +} + +function _p9k_shorten_delim_len() { + local def=$1 + _p9k__ret=${_POWERLEVEL9K_SHORTEN_DELIMITER_LENGTH:--1} + (( _p9k__ret >= 0 )) || _p9k_prompt_length $1 +} + +################################################################ +# Dir: current working directory +prompt_dir() { + if (( _POWERLEVEL9K_DIR_PATH_ABSOLUTE )); then + local p=$_p9k__cwd + local -a parts=("${(s:/:)p}") + elif [[ -o auto_name_dirs ]]; then + local p=${_p9k__cwd/#(#b)$HOME(|\/*)/'~'$match[1]} + local -a parts=("${(s:/:)p}") + else + local p=${(%):-%~} + if [[ $p == '~['* ]]; then + # If "${(%):-%~}" expands to "~[a]/]/b", is the first component "~[a]" or "~[a]/]"? + # One would expect "${(%):-%-1~}" to give the right answer but alas it always simply + # gives the segment before the first slash, which would be "~[a]" in this case. Worse, + # for "~[a/b]" it'll give the nonsensical "~[a". To solve this problem we have to + # repeat what "${(%):-%~}" does and hope that it produces the same result. + local func='' + local -a parts=() + for func in zsh_directory_name $zsh_directory_name_functions; do + local reply=() + if (( $+functions[$func] )) && $func d $_p9k__cwd && [[ $p == '~['$reply[1]']'* ]]; then + parts+='~['$reply[1]']' + break + fi + done + if (( $#parts )); then + parts+=(${(s:/:)${p#$parts[1]}}) + else + p=$_p9k__cwd + parts=("${(s:/:)p}") + fi + else + local -a parts=("${(s:/:)p}") + fi + fi + + local -i fake_first=0 expand=0 shortenlen=${_POWERLEVEL9K_SHORTEN_DIR_LENGTH:--1} + + if (( $+_POWERLEVEL9K_SHORTEN_DELIMITER )); then + local delim=$_POWERLEVEL9K_SHORTEN_DELIMITER + else + if [[ $langinfo[CODESET] == (utf|UTF)(-|)8 ]]; then + local delim=$'\u2026' + else + local delim='..' + fi + fi + + case $_POWERLEVEL9K_SHORTEN_STRATEGY in + truncate_absolute|truncate_absolute_chars) + if (( shortenlen > 0 && $#p > shortenlen )); then + _p9k_shorten_delim_len $delim + if (( $#p > shortenlen + $_p9k__ret )); then + local -i n=shortenlen + local -i i=$#parts + while true; do + local dir=$parts[i] + local -i len=$(( $#dir + (i > 1) )) + if (( len <= n )); then + (( n -= len )) + (( --i )) + else + parts[i]=$'\1'$dir[-n,-1] + parts[1,i-1]=() + break + fi + done + fi + fi + ;; + truncate_with_package_name|truncate_middle|truncate_from_right) + () { + [[ $_POWERLEVEL9K_SHORTEN_STRATEGY == truncate_with_package_name && + $+commands[jq] == 1 && $#_POWERLEVEL9K_DIR_PACKAGE_FILES > 0 ]] || return + local pats="(${(j:|:)_POWERLEVEL9K_DIR_PACKAGE_FILES})" + local -i i=$#parts + local dir=$_p9k__cwd + for (( ; i > 0; --i )); do + local markers=($dir/${~pats}(N)) + if (( $#markers )); then + local pat= pkg_file= + for pat in $_POWERLEVEL9K_DIR_PACKAGE_FILES; do + for pkg_file in $markers; do + [[ $pkg_file == $dir/${~pat} ]] || continue + if ! _p9k_cache_stat_get $0_pkg $pkg_file; then + local pkg_name='' + pkg_name="$(jq -j '.name | select(. != null)' <$pkg_file 2>/dev/null)" || pkg_name='' + _p9k_cache_stat_set "$pkg_name" + fi + [[ -n $_p9k__cache_val[1] ]] || continue + parts[1,i]=($_p9k__cache_val[1]) + fake_first=1 + return 0 + done + done + fi + dir=${dir:h} + done + } + if (( shortenlen > 0 )); then + _p9k_shorten_delim_len $delim + local -i d=_p9k__ret pref=shortenlen suf=0 i=2 + [[ $_POWERLEVEL9K_SHORTEN_STRATEGY == truncate_middle ]] && suf=pref + for (( ; i < $#parts; ++i )); do + local dir=$parts[i] + if (( $#dir > pref + suf + d )); then + dir[pref+1,-suf-1]=$'\1' + parts[i]=$dir + fi + done + fi + ;; + truncate_to_last) + if [[ $#parts -gt 2 || $p[1] != / && $#parts -gt 1 ]]; then + fake_first=1 + parts[1,-2]=() + fi + ;; + truncate_to_first_and_last) + if (( shortenlen > 0 )); then + local -i i=$(( shortenlen + 1 )) + [[ $p == /* ]] && (( ++i )) + for (( ; i <= $#parts - shortenlen; ++i )); do + parts[i]=$'\1' + done + fi + ;; + truncate_to_unique) + expand=1 + delim=${_POWERLEVEL9K_SHORTEN_DELIMITER-'*'} + shortenlen=${_POWERLEVEL9K_SHORTEN_DIR_LENGTH:-1} + (( shortenlen >= 0 )) || shortenlen=1 + local -i i=2 e=$(($#parts - shortenlen)) + if [[ -n $_POWERLEVEL9K_DIR_TRUNCATE_BEFORE_MARKER ]]; then + (( e += shortenlen )) + local orig=("$parts[2]" "${(@)parts[$((shortenlen > $#parts ? -$#parts : -shortenlen)),-1]}") + elif [[ $p[1] == / ]]; then + (( ++i )) + fi + if (( i <= e )); then + local mtimes=(${(Oa)_p9k__parent_mtimes:$(($#parts-e)):$((e-i+1))}) + local key="${(pj.:.)mtimes}" + else + local key= + fi + if ! _p9k_cache_ephemeral_get $0 $e $i $_p9k__cwd || [[ $key != $_p9k__cache_val[1] ]]; then + local tail=${(j./.)parts[i,-1]} + local parent=$_p9k__cwd[1,-2-$#tail] + _p9k_prompt_length $delim + local -i real_delim_len=_p9k__ret + [[ -n $parts[i-1] ]] && parts[i-1]="\${(Q)\${:-${(qqq)${(q)parts[i-1]}}}}"$'\2' + local -i d=${_POWERLEVEL9K_SHORTEN_DELIMITER_LENGTH:--1} + (( d >= 0 )) || d=real_delim_len + local -i m=1 + for (( ; i <= e; ++i, ++m )); do + local sub=$parts[i] + local dir=$parent/$sub mtime=$mtimes[m] + local pair=$_p9k__dir_stat_cache[$dir] + if [[ $pair == ${mtime:-x}:* ]]; then + parts[i]=${pair#*:} + else + [[ $sub != *["~!#\`\$^&*()\\\"'<>?{}[]"]* ]] + local -i q=$? + if [[ -n $_POWERLEVEL9K_SHORTEN_FOLDER_MARKER && + -n $parent/$sub/${~_POWERLEVEL9K_SHORTEN_FOLDER_MARKER}(#qN) ]]; then + (( q )) && parts[i]="\${(Q)\${:-${(qqq)${(q)sub}}}}" + parts[i]+=$'\2' + else + local -i j=$sub[(i)[^.]] + for (( ; j + d < $#sub; ++j )); do + local -a matching=($parent/$sub[1,j]*/(N)) + (( $#matching == 1 )) && break + done + local -i saved=$(($#sub - j - d)) + if (( saved > 0 )); then + if (( q )); then + parts[i]='${${${_p9k__d:#-*}:+${(Q)${:-'${(qqq)${(q)sub}}'}}}:-${(Q)${:-' + parts[i]+=$'\3'${(qqq)${(q)sub[1,j]}}$'}}\1\3''${$((_p9k__d+='$saved'))+}}' + else + parts[i]='${${${_p9k__d:#-*}:+'$sub$'}:-\3'$sub[1,j]$'\1\3''${$((_p9k__d+='$saved'))+}}' + fi + else + (( q )) && parts[i]="\${(Q)\${:-${(qqq)${(q)sub}}}}" + fi + fi + [[ -n $mtime ]] && _p9k__dir_stat_cache[$dir]="$mtime:$parts[i]" + fi + parent+=/$sub + done + if [[ -n $_POWERLEVEL9K_DIR_TRUNCATE_BEFORE_MARKER ]]; then + local _2=$'\2' + if [[ $_POWERLEVEL9K_DIR_TRUNCATE_BEFORE_MARKER == last ]]; then + (( e = ${parts[(I)*$_2]} )) + else + (( e = ${parts[(ib:2:)*$_2]} )) + fi + if (( e > 1 && e <= $#parts )); then + parts[1,e-1]=() + fake_first=1 + elif [[ $p == /?* ]]; then + parts[2]="\${(Q)\${:-${(qqq)${(q)orig[1]}}}}"$'\2' + fi + for ((i = $#parts < shortenlen ? $#parts : shortenlen; i > 0; --i)); do + [[ $#parts[-i] == *$'\2' ]] && continue + if [[ $orig[-i] == *["~!#\`\$^&*()\\\"'<>?{}[]"]* ]]; then + parts[-i]='${(Q)${:-'${(qqq)${(q)orig[-i]}}'}}'$'\2' + else + parts[-i]=${orig[-i]}$'\2' + fi + done + else + for ((; i <= $#parts; ++i)); do + [[ $parts[i] == *["~!#\`\$^&*()\\\"'<>?{}[]"]* ]] && parts[i]='${(Q)${:-'${(qqq)${(q)parts[i]}}'}}' + parts[i]+=$'\2' + done + fi + _p9k_cache_ephemeral_set "$key" "${parts[@]}" + fi + parts=("${(@)_p9k__cache_val[2,-1]}") + ;; + truncate_with_folder_marker) + if [[ -n $_POWERLEVEL9K_SHORTEN_FOLDER_MARKER ]]; then + local dir=$_p9k__cwd + local -a m=() + local -i i=$(($#parts - 1)) + for (( ; i > 1; --i )); do + dir=${dir:h} + [[ -n $dir/${~_POWERLEVEL9K_SHORTEN_FOLDER_MARKER}(#qN) ]] && m+=$i + done + m+=1 + for (( i=1; i < $#m; ++i )); do + (( m[i] - m[i+1] > 2 )) && parts[m[i+1]+1,m[i]-1]=($'\1') + done + fi + ;; + *) + if (( shortenlen > 0 )); then + local -i len=$#parts + [[ -z $parts[1] ]] && (( --len )) + if (( len > shortenlen )); then + parts[1,-shortenlen-1]=($'\1') + fi + fi + ;; + esac + + [[ $_POWERLEVEL9K_DIR_SHOW_WRITABLE != 0 && ! -w $_p9k__cwd ]] + local w=$? + if ! _p9k_cache_ephemeral_get $0 $_p9k__cwd $p $w $fake_first "${parts[@]}"; then + local state=$0 + local icon='' + local a='' b='' c='' + for a b c in "${_POWERLEVEL9K_DIR_CLASSES[@]}"; do + if [[ $_p9k__cwd == ${~a} ]]; then + [[ -n $b ]] && state+=_${(U)b} + icon=$'\1'$c + break + fi + done + if (( ! w )); then + if (( _POWERLEVEL9K_DIR_SHOW_WRITABLE == 1 )); then + state=${0}_NOT_WRITABLE + else + state+=_NOT_WRITABLE + fi + icon=LOCK_ICON + fi + + local style=%b + _p9k_color $state BACKGROUND blue + _p9k_background $_p9k__ret + style+=$_p9k__ret + _p9k_color $state FOREGROUND "$_p9k_color1" + _p9k_foreground $_p9k__ret + style+=$_p9k__ret + if (( expand )); then + _p9k_escape_style $style + style=$_p9k__ret + fi + + parts=("${(@)parts//\%/%%}") + if [[ $_POWERLEVEL9K_HOME_FOLDER_ABBREVIATION != '~' && $fake_first == 0 && $p == ('~'|'~/'*) ]]; then + (( expand )) && _p9k_escape $_POWERLEVEL9K_HOME_FOLDER_ABBREVIATION || _p9k__ret=$_POWERLEVEL9K_HOME_FOLDER_ABBREVIATION + parts[1]=$_p9k__ret + [[ $_p9k__ret == *%* ]] && parts[1]+=$style + elif [[ $_POWERLEVEL9K_DIR_OMIT_FIRST_CHARACTER == 1 && $fake_first == 0 && $#parts > 1 && -z $parts[1] && -n $parts[2] ]]; then + parts[1]=() + fi + + local last_style= + _p9k_param $state PATH_HIGHLIGHT_BOLD '' + [[ $_p9k__ret == true ]] && last_style+=%B + if (( $+parameters[_POWERLEVEL9K_DIR_PATH_HIGHLIGHT_FOREGROUND] || + $+parameters[_POWERLEVEL9K_${(U)state}_PATH_HIGHLIGHT_FOREGROUND] )); then + _p9k_color $state PATH_HIGHLIGHT_FOREGROUND '' + _p9k_foreground $_p9k__ret + last_style+=$_p9k__ret + fi + if [[ -n $last_style ]]; then + (( expand )) && _p9k_escape_style $last_style || _p9k__ret=$last_style + parts[-1]=$_p9k__ret${parts[-1]//$'\1'/$'\1'$_p9k__ret}$style + fi + + local anchor_style= + _p9k_param $state ANCHOR_BOLD '' + [[ $_p9k__ret == true ]] && anchor_style+=%B + if (( $+parameters[_POWERLEVEL9K_DIR_ANCHOR_FOREGROUND] || + $+parameters[_POWERLEVEL9K_${(U)state}_ANCHOR_FOREGROUND] )); then + _p9k_color $state ANCHOR_FOREGROUND '' + _p9k_foreground $_p9k__ret + anchor_style+=$_p9k__ret + fi + if [[ -n $anchor_style ]]; then + (( expand )) && _p9k_escape_style $anchor_style || _p9k__ret=$anchor_style + if [[ -z $last_style ]]; then + parts=("${(@)parts/%(#b)(*)$'\2'/$_p9k__ret$match[1]$style}") + else + (( $#parts > 1 )) && parts[1,-2]=("${(@)parts[1,-2]/%(#b)(*)$'\2'/$_p9k__ret$match[1]$style}") + parts[-1]=${parts[-1]/$'\2'} + fi + else + parts=("${(@)parts/$'\2'}") + fi + + if (( $+parameters[_POWERLEVEL9K_DIR_SHORTENED_FOREGROUND] || + $+parameters[_POWERLEVEL9K_${(U)state}_SHORTENED_FOREGROUND] )); then + _p9k_color $state SHORTENED_FOREGROUND '' + _p9k_foreground $_p9k__ret + (( expand )) && _p9k_escape_style $_p9k__ret + local shortened_fg=$_p9k__ret + (( expand )) && _p9k_escape $delim || _p9k__ret=$delim + [[ $_p9k__ret == *%* ]] && _p9k__ret+=$style$shortened_fg + parts=("${(@)parts/(#b)$'\3'(*)$'\1'(*)$'\3'/$shortened_fg$match[1]$_p9k__ret$match[2]$style}") + parts=("${(@)parts/(#b)(*)$'\1'(*)/$shortened_fg$match[1]$_p9k__ret$match[2]$style}") + else + (( expand )) && _p9k_escape $delim || _p9k__ret=$delim + [[ $_p9k__ret == *%* ]] && _p9k__ret+=$style + parts=("${(@)parts/$'\1'/$_p9k__ret}") + parts=("${(@)parts//$'\3'}") + fi + + local sep='' + if (( $+parameters[_POWERLEVEL9K_DIR_PATH_SEPARATOR_FOREGROUND] || + $+parameters[_POWERLEVEL9K_${(U)state}_PATH_SEPARATOR_FOREGROUND] )); then + _p9k_color $state PATH_SEPARATOR_FOREGROUND '' + _p9k_foreground $_p9k__ret + (( expand )) && _p9k_escape_style $_p9k__ret + sep=$_p9k__ret + fi + _p9k_param $state PATH_SEPARATOR / + (( expand )) && _p9k_escape $_p9k__ret + sep+=$_p9k__ret + [[ $sep == *%* ]] && sep+=$style + + local content="${(pj.$sep.)parts}" + if (( _POWERLEVEL9K_DIR_HYPERLINK && _p9k_term_has_href )); then + local header=$'%{\e]8;;file://'${${_p9k__cwd//\%/%%25}//'#'/%%23}$'\a%}' + local footer=$'%{\e]8;;\a%}' + if (( expand )); then + _p9k_escape $header + header=$_p9k__ret + _p9k_escape $footer + footer=$_p9k__ret + fi + content=$header$content$footer + fi + + (( expand )) && _p9k_prompt_length "${(e):-"\${\${_p9k__d::=0}+}$content"}" || _p9k__ret= + _p9k_cache_ephemeral_set "$state" "$icon" "$expand" "$content" $_p9k__ret + fi + + if (( _p9k__cache_val[3] )); then + if (( $+_p9k__dir )); then + _p9k__cache_val[4]='${${_p9k__d::=-1024}+}'$_p9k__cache_val[4] + else + _p9k__dir=$_p9k__cache_val[4] + _p9k__dir_len=$_p9k__cache_val[5] + _p9k__cache_val[4]='%{d%}'$_p9k__cache_val[4]'%{d%}' + fi + fi + _p9k_prompt_segment "$_p9k__cache_val[1]" "blue" "$_p9k_color1" "$_p9k__cache_val[2]" "$_p9k__cache_val[3]" "" "$_p9k__cache_val[4]" +} + +instant_prompt_dir() { prompt_dir; } + +################################################################ +# Docker machine +prompt_docker_machine() { + _p9k_prompt_segment "$0" "magenta" "$_p9k_color1" 'SERVER_ICON' 0 '' "${DOCKER_MACHINE_NAME//\%/%%}" +} + +_p9k_prompt_docker_machine_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$DOCKER_MACHINE_NAME' +} + +################################################################ +# GO prompt +prompt_go_version() { + _p9k_cached_cmd 0 go version || return + [[ $_p9k__ret == (#b)*go([[:digit:].]##)* ]] || return + local v=$match[1] + if (( _POWERLEVEL9K_GO_VERSION_PROJECT_ONLY )); then + local p=$GOPATH + if [[ -z $p ]]; then + if [[ -d $HOME/go ]]; then + p=$HOME/go + else + p="$(go env GOPATH 2>/dev/null)" && [[ -n $p ]] || return + fi + fi + if [[ $_p9k__cwd/ != $p/* && $_p9k__cwd_a/ != $p/* ]]; then + _p9k_upglob go.mod && return + fi + fi + _p9k_prompt_segment "$0" "green" "grey93" "GO_ICON" 0 '' "${v//\%/%%}" +} + +_p9k_prompt_go_version_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$commands[go]' +} + +################################################################ +# Command number (in local history) +prompt_history() { + local -i len=$#_p9k__prompt _p9k__has_upglob + _p9k_prompt_segment "$0" "grey50" "$_p9k_color1" '' 0 '' '%h' + (( _p9k__has_upglob )) || typeset -g "_p9k__segment_val_${_p9k__prompt_side}[_p9k__segment_index]"=$_p9k__prompt[len+1,-1] +} + +prompt_package() { + unset P9K_PACKAGE_NAME P9K_PACKAGE_VERSION + _p9k_upglob package.json && return + + local file=$_p9k__parent_dirs[$?]/package.json + if ! _p9k_cache_stat_get $0 $file; then + () { + local data field + local -A found + # Redneck json parsing. Yields correct results for any well-formed json document. + # Produces random garbage for invalid json. + { data="$(<$file)" || return } 2>/dev/null + data=${data##[[:space:]]#} + [[ $data == '{'* ]] || return + data[1]= + local -i depth=1 + while true; do + data=${data##[[:space:]]#} + [[ -n $data ]] || return + case $data[1] in + '{'|'[') data[1]=; (( ++depth ));; + '}'|']') data[1]=; (( --depth > 0 )) || return;; + ':') data[1]=;; + ',') data[1]=; field=;; + [[:alnum:].]) data=${data##[[:alnum:].]#};; + '"') + local tail=${data##\"([^\"\\]|\\?)#} + [[ $tail == '"'* ]] || return + local s=${data:1:-$#tail} + data=${tail:1} + (( depth == 1 )) || continue + if [[ -z $field ]]; then + field=${s:-x} + elif [[ $field == (name|version) ]]; then + (( ! $+found[$field] )) || return + [[ -n $s ]] || return + [[ $s != *($'\n'|'\')* ]] || return + found[$field]=$s + (( $#found == 2 )) && break + fi + ;; + *) return 1;; + esac + done + _p9k_cache_stat_set 1 $found[name] $found[version] + return 0 + } || _p9k_cache_stat_set 0 + fi + (( _p9k__cache_val[1] )) || return + + P9K_PACKAGE_NAME=$_p9k__cache_val[2] + P9K_PACKAGE_VERSION=$_p9k__cache_val[3] + _p9k_prompt_segment "$0" "cyan" "$_p9k_color1" PACKAGE_ICON 0 '' ${P9K_PACKAGE_VERSION//\%/%%} +} + +################################################################ +# Detection for virtualization (systemd based systems only) +prompt_detect_virt() { + local virt="$(systemd-detect-virt 2>/dev/null)" + if [[ "$virt" == "none" ]]; then + local -a inode + if zstat -A inode +inode / 2>/dev/null && [[ $inode[1] != 2 ]]; then + virt="chroot" + fi + fi + if [[ -n "${virt}" ]]; then + _p9k_prompt_segment "$0" "$_p9k_color1" "yellow" '' 0 '' "${virt//\%/%%}" + fi +} + +_p9k_prompt_detect_virt_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$commands[systemd-detect-virt]' +} + +################################################################ +# Segment to display the current IP address +prompt_ip() { + local -i len=$#_p9k__prompt _p9k__has_upglob + _p9k_prompt_segment "$0" "cyan" "$_p9k_color1" 'NETWORK_ICON' 1 '$P9K_IP_IP' '$P9K_IP_IP' + (( _p9k__has_upglob )) || typeset -g "_p9k__segment_val_${_p9k__prompt_side}[_p9k__segment_index]"=$_p9k__prompt[len+1,-1] +} + +################################################################ +# Segment to display if VPN is active +prompt_vpn_ip() { + typeset -ga _p9k__vpn_ip_segments + _p9k__vpn_ip_segments+=($_p9k__prompt_side $_p9k__line_index $_p9k__segment_index) + local p='${(e)_p9k__vpn_ip_'$_p9k__prompt_side$_p9k__segment_index'}' + _p9k__prompt+=$p + typeset -g "_p9k__segment_val_${_p9k__prompt_side}[_p9k__segment_index]"=$p +} + +_p9k_vpn_ip_render() { + local _p9k__segment_name=vpn_ip _p9k__prompt_side ip + local -i _p9k__has_upglob _p9k__segment_index + for _p9k__prompt_side _p9k__line_index _p9k__segment_index in $_p9k__vpn_ip_segments; do + local _p9k__prompt= + for ip in $_p9k__vpn_ip_ips; do + _p9k_prompt_segment prompt_vpn_ip "cyan" "$_p9k_color1" 'VPN_ICON' 0 '' $ip + done + typeset -g _p9k__vpn_ip_$_p9k__prompt_side$_p9k__segment_index=$_p9k__prompt + done +} + +################################################################ +# Segment to display laravel version +prompt_laravel_version() { + _p9k_upglob artisan && return + local dir=$_p9k__parent_dirs[$?] + local app=$dir/vendor/laravel/framework/src/Illuminate/Foundation/Application.php + [[ -r $app ]] || return + if ! _p9k_cache_stat_get $0 $dir/artisan $app; then + local v="$(php $dir/artisan --version 2> /dev/null)" + _p9k_cache_stat_set "${${(M)v:#Laravel Framework *}#Laravel Framework }" + fi + [[ -n $_p9k__cache_val[1] ]] || return + _p9k_prompt_segment "$0" "maroon" "white" 'LARAVEL_ICON' 0 '' "${_p9k__cache_val[1]//\%/%%}" +} + +_p9k_prompt_laravel_version_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$commands[php]' +} + +################################################################ +# Segment to display load +prompt_load() { + if [[ $_p9k_os == (OSX|BSD) ]]; then + local -i len=$#_p9k__prompt _p9k__has_upglob + _p9k_prompt_segment $0_CRITICAL red "$_p9k_color1" LOAD_ICON 1 '$_p9k__load_critical' '$_p9k__load_value' + _p9k_prompt_segment $0_WARNING yellow "$_p9k_color1" LOAD_ICON 1 '$_p9k__load_warning' '$_p9k__load_value' + _p9k_prompt_segment $0_NORMAL green "$_p9k_color1" LOAD_ICON 1 '$_p9k__load_normal' '$_p9k__load_value' + (( _p9k__has_upglob )) || typeset -g "_p9k__segment_val_${_p9k__prompt_side}[_p9k__segment_index]"=$_p9k__prompt[len+1,-1] + return + fi + + [[ -r /proc/loadavg ]] || return + _p9k_read_file /proc/loadavg || return + local load=${${(A)=_p9k__ret}[_POWERLEVEL9K_LOAD_WHICH]//,/.} + local -F pct='100. * load / _p9k_num_cpus' + if (( pct > 70 )); then + _p9k_prompt_segment $0_CRITICAL red "$_p9k_color1" LOAD_ICON 0 '' $load + elif (( pct > 50 )); then + _p9k_prompt_segment $0_WARNING yellow "$_p9k_color1" LOAD_ICON 0 '' $load + else + _p9k_prompt_segment $0_NORMAL green "$_p9k_color1" LOAD_ICON 0 '' $load + fi +} + +_p9k_prompt_load_init() { + if [[ $_p9k_os == (OSX|BSD) ]]; then + typeset -g _p9k__load_value= + typeset -g _p9k__load_normal= + typeset -g _p9k__load_warning= + typeset -g _p9k__load_critical= + _p9k__async_segments_compute+='_p9k_worker_invoke load _p9k_prompt_load_compute' + elif [[ ! -r /proc/loadavg ]]; then + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${:-}' + fi +} + +_p9k_prompt_load_compute() { + (( $+commands[sysctl] )) || return + _p9k_worker_async _p9k_prompt_load_async _p9k_prompt_load_sync +} + +_p9k_prompt_load_async() { + local load="$(sysctl -n vm.loadavg 2>/dev/null)" || return + load=${${(A)=load}[_POWERLEVEL9K_LOAD_WHICH+1]//,/.} + [[ $load == <->(|.<->) && $load != $_p9k__load_value ]] || return + _p9k__load_value=$load + _p9k__load_normal= + _p9k__load_warning= + _p9k__load_critical= + local -F pct='100. * _p9k__load_value / _p9k_num_cpus' + if (( pct > 70 )); then + _p9k__load_critical=1 + elif (( pct > 50 )); then + _p9k__load_warning=1 + else + _p9k__load_normal=1 + fi + _p9k_print_params \ + _p9k__load_value \ + _p9k__load_normal \ + _p9k__load_warning \ + _p9k__load_critical + echo -E - 'reset=1' +} + +_p9k_prompt_load_sync() { + eval $REPLY + _p9k_worker_reply $REPLY +} + +# Usage: _p9k_cached_cmd <0|1> <cmd> [args...] +# +# The first argument says whether to capture stderr (1) or ignore it (0). +function _p9k_cached_cmd() { + local cmd=$commands[$2] + [[ -n $cmd ]] || return + if ! _p9k_cache_stat_get $0" ${(q)*}" $cmd; then + local out + if (( $1 )); then + out="$($cmd "${@:3}" 2>&1)" + else + out="$($cmd "${@:3}" 2>/dev/null)" + fi + _p9k_cache_stat_set $(( ! $? )) "$out" + fi + (( $_p9k__cache_val[1] )) || return + _p9k__ret=$_p9k__cache_val[2] +} + +################################################################ +# Segment to diplay Node version +prompt_node_version() { + if (( _POWERLEVEL9K_NODE_VERSION_PROJECT_ONLY )); then + _p9k_upglob package.json && return + fi + _p9k_cached_cmd 0 node --version && [[ $_p9k__ret == v?* ]] || return + _p9k_prompt_segment "$0" "green" "white" 'NODE_ICON' 0 '' "${_p9k__ret#v}" +} + +_p9k_prompt_node_version_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$commands[node]' +} + +# Almost the same as `nvm_version default` but faster. The differences shouldn't affect +# the observable behavior of Powerlevel10k. +function _p9k_nvm_ls_default() { + local v=default + local -a seen=($v) + while [[ -r $NVM_DIR/alias/$v ]]; do + local target= + IFS='' read -r target <$NVM_DIR/alias/$v + [[ -z $target ]] && break + (( $seen[(I)$target] )) && return + seen+=$target + v=$target + done + + case $v in + default|N/A) + return 1 + ;; + system|v) + _p9k__ret=system + return 0 + ;; + iojs-[0-9]*) + v=iojs-v${v#iojs-} + ;; + [0-9]*) + v=v$v + ;; + esac + + if [[ $v == v*.*.* ]]; then + if [[ -x $NVM_DIR/versions/node/$v/bin/node || -x $NVM_DIR/$v/bin/node ]]; then + _p9k__ret=$v + return 0 + elif [[ -x $NVM_DIR/versions/io.js/$v/bin/node ]]; then + _p9k__ret=iojs-$v + return 0 + else + return 1 + fi + fi + + local -a dirs=() + case $v in + node|node-|stable) + dirs=($NVM_DIR/versions/node $NVM_DIR) + v='(v[1-9]*|v0.*[02468].*)' + ;; + unstable) + dirs=($NVM_DIR/versions/node $NVM_DIR) + v='v0.*[13579].*' + ;; + iojs*) + dirs=($NVM_DIR/versions/io.js) + v=v${${${v#iojs}#-}#v}'*' + ;; + *) + dirs=($NVM_DIR/versions/node $NVM_DIR $NVM_DIR/versions/io.js) + v=v${v#v}'*' + ;; + esac + + local -a matches=(${^dirs}/${~v}(/N)) + (( $#matches )) || return + + local max path + for path in ${(Oa)matches}; do + [[ ${path:t} == (#b)v(*).(*).(*) ]] || continue + v=${(j::)${(@l:6::0:)match}} + [[ $v > $max ]] || continue + max=$v + _p9k__ret=${path:t} + [[ ${path:h:t} != io.js ]] || _p9k__ret=iojs-$_p9k__ret + done + + [[ -n $max ]] +} + +# The same as `nvm_version current` but faster. +_p9k_nvm_ls_current() { + local node_path=${commands[node]:A} + [[ -n $node_path ]] || return + + local nvm_dir=${NVM_DIR:A} + if [[ -n $nvm_dir && $node_path == $nvm_dir/versions/io.js/* ]]; then + _p9k_cached_cmd 0 iojs --version || return + _p9k__ret=iojs-v${_p9k__ret#v} + elif [[ -n $nvm_dir && $node_path == $nvm_dir/* ]]; then + _p9k_cached_cmd 0 node --version || return + _p9k__ret=v${_p9k__ret#v} + else + _p9k__ret=system + fi +} + +################################################################ +# Segment to display Node version from NVM +# Only prints the segment if different than the default value +prompt_nvm() { + [[ -n $NVM_DIR ]] && _p9k_nvm_ls_current || return + local current=$_p9k__ret + ! _p9k_nvm_ls_default || [[ $_p9k__ret != $current ]] || return + _p9k_prompt_segment "$0" "magenta" "black" 'NODE_ICON' 0 '' "${${current#v}//\%/%%}" +} + +_p9k_prompt_nvm_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${commands[nvm]:-${${+functions[nvm]}:#0}}' +} + +################################################################ +# Segment to display NodeEnv +prompt_nodeenv() { + local msg + if (( _POWERLEVEL9K_NODEENV_SHOW_NODE_VERSION )) && _p9k_cached_cmd 0 node --version; then + msg="${_p9k__ret//\%/%%} " + fi + msg+="$_POWERLEVEL9K_NODEENV_LEFT_DELIMITER${${NODE_VIRTUAL_ENV:t}//\%/%%}$_POWERLEVEL9K_NODEENV_RIGHT_DELIMITER" + _p9k_prompt_segment "$0" "black" "green" 'NODE_ICON' 0 '' "$msg" +} + +_p9k_prompt_nodeenv_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$NODE_VIRTUAL_ENV' +} + +function _p9k_nodeenv_version_transform() { + local dir=${NODENV_ROOT:-$HOME/.nodenv}/versions + [[ -z $1 || $1 == system ]] && _p9k__ret=$1 && return + [[ -d $dir/$1 ]] && _p9k__ret=$1 && return + [[ -d $dir/${1/v} ]] && _p9k__ret=${1/v} && return + [[ -d $dir/${1#node-} ]] && _p9k__ret=${1#node-} && return + [[ -d $dir/${1#node-v} ]] && _p9k__ret=${1#node-v} && return + return 1 +} + +function _p9k_nodenv_global_version() { + _p9k_read_word ${NODENV_ROOT:-$HOME/.nodenv}/version || _p9k__ret=system +} + +################################################################ +# Segment to display nodenv information +# https://github.com/nodenv/nodenv +prompt_nodenv() { + if [[ -n $NODENV_VERSION ]]; then + (( ${_POWERLEVEL9K_NODENV_SOURCES[(I)shell]} )) || return + local v=$NODENV_VERSION + else + (( ${_POWERLEVEL9K_NODENV_SOURCES[(I)local|global]} )) || return + _p9k__ret= + if [[ $NODENV_DIR != (|.) ]]; then + [[ $NODENV_DIR == /* ]] && local dir=$NODENV_DIR || local dir="$_p9k__cwd_a/$NODENV_DIR" + dir=${dir:A} + if [[ $dir != $_p9k__cwd_a ]]; then + while true; do + if _p9k_read_word $dir/.node-version; then + (( ${_POWERLEVEL9K_NODENV_SOURCES[(I)local]} )) || return + break + fi + [[ $dir == / ]] && break + dir=${dir:h} + done + fi + fi + if [[ -z $_p9k__ret ]]; then + _p9k_upglob .node-version + local -i idx=$? + if (( idx )) && _p9k_read_word $_p9k__parent_dirs[idx]/.node-version; then + (( ${_POWERLEVEL9K_NODENV_SOURCES[(I)local]} )) || return + else + _p9k__ret= + fi + fi + if [[ -z $_p9k__ret ]]; then + (( _POWERLEVEL9K_NODENV_PROMPT_ALWAYS_SHOW )) || return + (( ${_POWERLEVEL9K_NODENV_SOURCES[(I)global]} )) || return + _p9k_nodenv_global_version + fi + + _p9k_nodeenv_version_transform $_p9k__ret || return + local v=$_p9k__ret + fi + + if (( !_POWERLEVEL9K_NODENV_PROMPT_ALWAYS_SHOW )); then + _p9k_nodenv_global_version + _p9k_nodeenv_version_transform $_p9k__ret && [[ $v == $_p9k__ret ]] && return + fi + + if (( !_POWERLEVEL9K_NODENV_SHOW_SYSTEM )); then + [[ $v == system ]] && return + fi + + _p9k_prompt_segment "$0" "black" "green" 'NODE_ICON' 0 '' "${v//\%/%%}" +} + +_p9k_prompt_nodenv_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${commands[nodenv]:-${${+functions[nodenv]}:#0}}' +} + +prompt_dotnet_version() { + if (( _POWERLEVEL9K_DOTNET_VERSION_PROJECT_ONLY )); then + _p9k_upglob 'project.json|global.json|packet.dependencies|*.csproj|*.fsproj|*.xproj|*.sln' && return + fi + _p9k_cached_cmd 0 dotnet --version || return + _p9k_prompt_segment "$0" "magenta" "white" 'DOTNET_ICON' 0 '' "$_p9k__ret" +} + +_p9k_prompt_dotnet_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$commands[dotnet]' +} + +################################################################ +# Segment to print a little OS icon +prompt_os_icon() { + local -i len=$#_p9k__prompt _p9k__has_upglob + _p9k_prompt_segment "$0" "black" "white" '' 0 '' "$_p9k_os_icon" + (( _p9k__has_upglob )) || typeset -g "_p9k__segment_val_${_p9k__prompt_side}[_p9k__segment_index]"=$_p9k__prompt[len+1,-1] +} + +instant_prompt_os_icon() { prompt_os_icon; } + +################################################################ +# Segment to display PHP version number +prompt_php_version() { + if (( _POWERLEVEL9K_PHP_VERSION_PROJECT_ONLY )); then + _p9k_upglob 'composer.json|*.php' && return + fi + _p9k_cached_cmd 0 php --version || return + [[ $_p9k__ret == (#b)(*$'\n')#'PHP '([[:digit:].]##)* ]] || return + local v=$match[2] + _p9k_prompt_segment "$0" "fuchsia" "grey93" 'PHP_ICON' 0 '' "${v//\%/%%}" +} + +_p9k_prompt_php_version_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$commands[php]' +} + +################################################################ +# Segment to display free RAM and used Swap +prompt_ram() { + local -i len=$#_p9k__prompt _p9k__has_upglob + _p9k_prompt_segment $0 yellow "$_p9k_color1" RAM_ICON 1 '$_p9k__ram_free' '$_p9k__ram_free' + (( _p9k__has_upglob )) || typeset -g "_p9k__segment_val_${_p9k__prompt_side}[_p9k__segment_index]"=$_p9k__prompt[len+1,-1] +} + +function _p9k_prompt_ram_init() { + if [[ $_p9k_os == OSX && $+commands[vm_stat] == 0 || + $_p9k_os == BSD && ! -r /var/run/dmesg.boot || + $_p9k_os != (OSX|BSD) && ! -r /proc/meminfo ]]; then + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${:-}' + return + fi + typeset -g _p9k__ram_free= + _p9k__async_segments_compute+='_p9k_worker_invoke ram _p9k_prompt_ram_compute' +} + +_p9k_prompt_ram_compute() { + _p9k_worker_async _p9k_prompt_ram_async _p9k_prompt_ram_sync +} + +_p9k_prompt_ram_async() { + local -F free_bytes + + case $_p9k_os in + OSX) + (( $+commands[vm_stat] )) || return + local stat && stat="$(vm_stat 2>/dev/null)" || return + [[ $stat =~ 'Pages free:[[:space:]]+([0-9]+)' ]] || return + (( free_bytes += match[1] )) + [[ $stat =~ 'Pages inactive:[[:space:]]+([0-9]+)' ]] || return + (( free_bytes += match[1] )) + (( free_bytes *= 4096 )) + ;; + BSD) + local stat && stat="$(grep -F 'avail memory' /var/run/dmesg.boot 2>/dev/null)" || return + free_bytes=${${(A)=stat}[4]} + ;; + *) + [[ -r /proc/meminfo ]] || return + local stat && stat="$(</proc/meminfo)" || return + [[ $stat == (#b)*(MemAvailable:|MemFree:)[[:space:]]#(<->)* ]] || return + free_bytes=$(( $match[2] * 1024 )) + ;; + esac + + _p9k_human_readable_bytes $free_bytes + [[ $_p9k__ret != $_p9k__ram_free ]] || return + _p9k__ram_free=$_p9k__ret + _p9k_print_params _p9k__ram_free + echo -E - 'reset=1' +} + +_p9k_prompt_ram_sync() { + eval $REPLY + _p9k_worker_reply $REPLY +} + +function _p9k_rbenv_global_version() { + _p9k_read_word ${RBENV_ROOT:-$HOME/.rbenv}/version || _p9k__ret=system +} + +################################################################ +# Segment to display rbenv information +# https://github.com/rbenv/rbenv#choosing-the-ruby-version +prompt_rbenv() { + if [[ -n $RBENV_VERSION ]]; then + (( ${_POWERLEVEL9K_RBENV_SOURCES[(I)shell]} )) || return + local v=$RBENV_VERSION + else + (( ${_POWERLEVEL9K_RBENV_SOURCES[(I)local|global]} )) || return + _p9k__ret= + if [[ $RBENV_DIR != (|.) ]]; then + [[ $RBENV_DIR == /* ]] && local dir=$RBENV_DIR || local dir="$_p9k__cwd_a/$RBENV_DIR" + dir=${dir:A} + if [[ $dir != $_p9k__cwd_a ]]; then + while true; do + if _p9k_read_word $dir/.ruby-version; then + (( ${_POWERLEVEL9K_RBENV_SOURCES[(I)local]} )) || return + break + fi + [[ $dir == / ]] && break + dir=${dir:h} + done + fi + fi + if [[ -z $_p9k__ret ]]; then + _p9k_upglob .ruby-version + local -i idx=$? + if (( idx )) && _p9k_read_word $_p9k__parent_dirs[idx]/.ruby-version; then + (( ${_POWERLEVEL9K_RBENV_SOURCES[(I)local]} )) || return + else + _p9k__ret= + fi + fi + if [[ -z $_p9k__ret ]]; then + (( _POWERLEVEL9K_RBENV_PROMPT_ALWAYS_SHOW )) || return + (( ${_POWERLEVEL9K_RBENV_SOURCES[(I)global]} )) || return + _p9k_rbenv_global_version + fi + local v=$_p9k__ret + fi + + if (( !_POWERLEVEL9K_RBENV_PROMPT_ALWAYS_SHOW )); then + _p9k_rbenv_global_version + [[ $v == $_p9k__ret ]] && return + fi + + if (( !_POWERLEVEL9K_RBENV_SHOW_SYSTEM )); then + [[ $v == system ]] && return + fi + + _p9k_prompt_segment "$0" "red" "$_p9k_color1" 'RUBY_ICON' 0 '' "${v//\%/%%}" +} + +_p9k_prompt_rbenv_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${commands[rbenv]:-${${+functions[rbenv]}:#0}}' +} + +function _p9k_phpenv_global_version() { + _p9k_read_word ${PHPENV_ROOT:-$HOME/.phpenv}/version || _p9k__ret=system +} + +prompt_phpenv() { + if [[ -n $PHPENV_VERSION ]]; then + (( ${_POWERLEVEL9K_PHPENV_SOURCES[(I)shell]} )) || return + local v=$PHPENV_VERSION + else + (( ${_POWERLEVEL9K_PHPENV_SOURCES[(I)local|global]} )) || return + _p9k__ret= + if [[ $PHPENV_DIR != (|.) ]]; then + [[ $PHPENV_DIR == /* ]] && local dir=$PHPENV_DIR || local dir="$_p9k__cwd_a/$PHPENV_DIR" + dir=${dir:A} + if [[ $dir != $_p9k__cwd_a ]]; then + while true; do + if _p9k_read_word $dir/.php-version; then + (( ${_POWERLEVEL9K_PHPENV_SOURCES[(I)local]} )) || return + break + fi + [[ $dir == / ]] && break + dir=${dir:h} + done + fi + fi + if [[ -z $_p9k__ret ]]; then + _p9k_upglob .php-version + local -i idx=$? + if (( idx )) && _p9k_read_word $_p9k__parent_dirs[idx]/.php-version; then + (( ${_POWERLEVEL9K_PHPENV_SOURCES[(I)local]} )) || return + else + _p9k__ret= + fi + fi + if [[ -z $_p9k__ret ]]; then + (( _POWERLEVEL9K_PHPENV_PROMPT_ALWAYS_SHOW )) || return + (( ${_POWERLEVEL9K_PHPENV_SOURCES[(I)global]} )) || return + _p9k_phpenv_global_version + fi + local v=$_p9k__ret + fi + + if (( !_POWERLEVEL9K_PHPENV_PROMPT_ALWAYS_SHOW )); then + _p9k_phpenv_global_version + [[ $v == $_p9k__ret ]] && return + fi + + if (( !_POWERLEVEL9K_PHPENV_SHOW_SYSTEM )); then + [[ $v == system ]] && return + fi + + _p9k_prompt_segment "$0" "magenta" "$_p9k_color1" 'PHP_ICON' 0 '' "${v//\%/%%}" +} + +_p9k_prompt_phpenv_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${commands[phpenv]:-${${+functions[phpenv]}:#0}}' +} + +function _p9k_luaenv_global_version() { + _p9k_read_word ${LUAENV_ROOT:-$HOME/.luaenv}/version || _p9k__ret=system +} + +################################################################ +# Segment to display luaenv information +# https://github.com/cehoffman/luaenv +prompt_luaenv() { + if [[ -n $LUAENV_VERSION ]]; then + (( ${_POWERLEVEL9K_LUAENV_SOURCES[(I)shell]} )) || return + local v=$LUAENV_VERSION + else + (( ${_POWERLEVEL9K_LUAENV_SOURCES[(I)local|global]} )) || return + _p9k__ret= + if [[ $LUAENV_DIR != (|.) ]]; then + [[ $LUAENV_DIR == /* ]] && local dir=$LUAENV_DIR || local dir="$_p9k__cwd_a/$LUAENV_DIR" + dir=${dir:A} + if [[ $dir != $_p9k__cwd_a ]]; then + while true; do + if _p9k_read_word $dir/.lua-version; then + (( ${_POWERLEVEL9K_LUAENV_SOURCES[(I)local]} )) || return + break + fi + [[ $dir == / ]] && break + dir=${dir:h} + done + fi + fi + if [[ -z $_p9k__ret ]]; then + _p9k_upglob .lua-version + local -i idx=$? + if (( idx )) && _p9k_read_word $_p9k__parent_dirs[idx]/.lua-version; then + (( ${_POWERLEVEL9K_LUAENV_SOURCES[(I)local]} )) || return + else + _p9k__ret= + fi + fi + if [[ -z $_p9k__ret ]]; then + (( _POWERLEVEL9K_LUAENV_PROMPT_ALWAYS_SHOW )) || return + (( ${_POWERLEVEL9K_LUAENV_SOURCES[(I)global]} )) || return + _p9k_luaenv_global_version + fi + local v=$_p9k__ret + fi + + if (( !_POWERLEVEL9K_LUAENV_PROMPT_ALWAYS_SHOW )); then + _p9k_luaenv_global_version + [[ $v == $_p9k__ret ]] && return + fi + + if (( !_POWERLEVEL9K_LUAENV_SHOW_SYSTEM )); then + [[ $v == system ]] && return + fi + + _p9k_prompt_segment "$0" blue "$_p9k_color1" 'LUA_ICON' 0 '' "${v//\%/%%}" +} + +_p9k_prompt_luaenv_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${commands[luaenv]:-${${+functions[luaenv]}:#0}}' +} + +function _p9k_jenv_global_version() { + _p9k_read_word ${JENV_ROOT:-$HOME/.jenv}/version || _p9k__ret=system +} + +################################################################ +# Segment to display jenv information +# https://github.com/jenv/jenv +prompt_jenv() { + if [[ -n $JENV_VERSION ]]; then + (( ${_POWERLEVEL9K_JENV_SOURCES[(I)shell]} )) || return + local v=$JENV_VERSION + else + (( ${_POWERLEVEL9K_JENV_SOURCES[(I)local|global]} )) || return + _p9k__ret= + if [[ $JENV_DIR != (|.) ]]; then + [[ $JENV_DIR == /* ]] && local dir=$JENV_DIR || local dir="$_p9k__cwd_a/$JENV_DIR" + dir=${dir:A} + if [[ $dir != $_p9k__cwd_a ]]; then + while true; do + if _p9k_read_word $dir/.java-version; then + (( ${_POWERLEVEL9K_JENV_SOURCES[(I)local]} )) || return + break + fi + [[ $dir == / ]] && break + dir=${dir:h} + done + fi + fi + if [[ -z $_p9k__ret ]]; then + _p9k_upglob .java-version + local -i idx=$? + if (( idx )) && _p9k_read_word $_p9k__parent_dirs[idx]/.java-version; then + (( ${_POWERLEVEL9K_JENV_SOURCES[(I)local]} )) || return + else + _p9k__ret= + fi + fi + if [[ -z $_p9k__ret ]]; then + (( _POWERLEVEL9K_JENV_PROMPT_ALWAYS_SHOW )) || return + (( ${_POWERLEVEL9K_JENV_SOURCES[(I)global]} )) || return + _p9k_jenv_global_version + fi + local v=$_p9k__ret + fi + + if (( !_POWERLEVEL9K_JENV_PROMPT_ALWAYS_SHOW )); then + _p9k_jenv_global_version + [[ $v == $_p9k__ret ]] && return + fi + + if (( !_POWERLEVEL9K_JENV_SHOW_SYSTEM )); then + [[ $v == system ]] && return + fi + + _p9k_prompt_segment "$0" white red 'JAVA_ICON' 0 '' "${v//\%/%%}" +} + +_p9k_prompt_jenv_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${commands[jenv]:-${${+functions[jenv]}:#0}}' +} + +function _p9k_plenv_global_version() { + _p9k_read_word ${PLENV_ROOT:-$HOME/.plenv}/version || _p9k__ret=system +} + +################################################################ +# Segment to display plenv information +# https://github.com/plenv/plenv#choosing-the-perl-version +prompt_plenv() { + if [[ -n $PLENV_VERSION ]]; then + (( ${_POWERLEVEL9K_PLENV_SOURCES[(I)shell]} )) || return + local v=$PLENV_VERSION + else + (( ${_POWERLEVEL9K_PLENV_SOURCES[(I)local|global]} )) || return + _p9k__ret= + if [[ $PLENV_DIR != (|.) ]]; then + [[ $PLENV_DIR == /* ]] && local dir=$PLENV_DIR || local dir="$_p9k__cwd_a/$PLENV_DIR" + dir=${dir:A} + if [[ $dir != $_p9k__cwd_a ]]; then + while true; do + if _p9k_read_word $dir/.perl-version; then + (( ${_POWERLEVEL9K_PLENV_SOURCES[(I)local]} )) || return + break + fi + [[ $dir == / ]] && break + dir=${dir:h} + done + fi + fi + if [[ -z $_p9k__ret ]]; then + _p9k_upglob .perl-version + local -i idx=$? + if (( idx )) && _p9k_read_word $_p9k__parent_dirs[idx]/.perl-version; then + (( ${_POWERLEVEL9K_PLENV_SOURCES[(I)local]} )) || return + else + _p9k__ret= + fi + fi + if [[ -z $_p9k__ret ]]; then + (( _POWERLEVEL9K_PLENV_PROMPT_ALWAYS_SHOW )) || return + (( ${_POWERLEVEL9K_PLENV_SOURCES[(I)global]} )) || return + _p9k_plenv_global_version + fi + local v=$_p9k__ret + fi + + if (( !_POWERLEVEL9K_PLENV_PROMPT_ALWAYS_SHOW )); then + _p9k_plenv_global_version + [[ $v == $_p9k__ret ]] && return + fi + + if (( !_POWERLEVEL9K_PLENV_SHOW_SYSTEM )); then + [[ $v == system ]] && return + fi + + _p9k_prompt_segment "$0" "blue" "$_p9k_color1" 'PERL_ICON' 0 '' "${v//\%/%%}" +} + +_p9k_prompt_plenv_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${commands[plenv]:-${${+functions[plenv]}:#0}}' +} + +################################################################ +# Segment to display chruby information +# see https://github.com/postmodern/chruby/issues/245 for chruby_auto issue with ZSH +prompt_chruby() { + local v + (( _POWERLEVEL9K_CHRUBY_SHOW_ENGINE )) && v=$RUBY_ENGINE + if [[ $_POWERLEVEL9K_CHRUBY_SHOW_VERSION == 1 && -n $RUBY_VERSION ]] && v+=${v:+ }$RUBY_VERSION + _p9k_prompt_segment "$0" "red" "$_p9k_color1" 'RUBY_ICON' 0 '' "${v//\%/%%}" +} + +_p9k_prompt_chruby_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$RUBY_ENGINE' +} + +################################################################ +# Segment to print an icon if user is root. +prompt_root_indicator() { + local -i len=$#_p9k__prompt _p9k__has_upglob + _p9k_prompt_segment "$0" "$_p9k_color1" "yellow" 'ROOT_ICON' 0 '${${(%):-%#}:#\%}' '' + (( _p9k__has_upglob )) || typeset -g "_p9k__segment_val_${_p9k__prompt_side}[_p9k__segment_index]"=$_p9k__prompt[len+1,-1] +} + +instant_prompt_root_indicator() { prompt_root_indicator; } + +################################################################ +# Segment to display Rust version number +prompt_rust_version() { + unset P9K_RUST_VERSION + if (( _POWERLEVEL9K_RUST_VERSION_PROJECT_ONLY )); then + _p9k_upglob Cargo.toml && return + fi + local rustc=$commands[rustc] toolchain deps=() + if (( $+commands[ldd] )); then + if ! _p9k_cache_stat_get $0_so $rustc; then + local line so + for line in "${(@f)$(ldd $rustc 2>/dev/null)}"; do + [[ $line == (#b)[[:space:]]#librustc_driver[^[:space:]]#.so' => '(*)' (0x'[[:xdigit:]]#')' ]] || continue + so=$match[1] + break + done + _p9k_cache_stat_set "$so" + fi + deps+=$_p9k__cache_val[1] + fi + if (( $+commands[rustup] )); then + local rustup=$commands[rustup] + local rustup_home=${RUSTUP_HOME:-~/.rustup} + local cfg=($rustup_home/settings.toml(.N)) + deps+=($cfg $rustup_home/update-hashes/*(.N)) + if [[ -z ${toolchain::=$RUSTUP_TOOLCHAIN} ]]; then + if ! _p9k_cache_stat_get $0_overrides $rustup $cfg; then + local lines=(${(f)"$(rustup override list 2>/dev/null)"}) + if [[ $lines[1] == "no overrides" ]]; then + _p9k_cache_stat_set + else + local MATCH + local keys=(${(@)${lines%%[[:space:]]#[^[:space:]]#}/(#m)*/${(b)MATCH}/}) + local vals=(${(@)lines/(#m)*/$MATCH[(I)/] ${MATCH##*[[:space:]]}}) + _p9k_cache_stat_set ${keys:^vals} + fi + fi + local -A overrides=($_p9k__cache_val) + _p9k_upglob rust-toolchain + local dir=$_p9k__parent_dirs[$?] + local -i n m=${dir[(I)/]} + local pair + for pair in ${overrides[(K)$_p9k__cwd/]}; do + n=${pair%% *} + (( n <= m )) && continue + m=n + toolchain=${pair#* } + done + if [[ -z $toolchain && -n $dir ]]; then + _p9k_read_word $dir/rust-toolchain + toolchain=$_p9k__ret + fi + fi + fi + if ! _p9k_cache_stat_get $0_v$toolchain $rustc $deps; then + _p9k_cache_stat_set "$($rustc --version 2>/dev/null)" + fi + local v=${${_p9k__cache_val[1]#rustc }%% *} + [[ -n $v ]] || return + typeset -g P9K_RUST_VERSION=$_p9k__cache_val[1] + _p9k_prompt_segment "$0" "darkorange" "$_p9k_color1" 'RUST_ICON' 0 '' "${v//\%/%%}" +} + +_p9k_prompt_rust_version_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$commands[rustc]' +} + +# RSpec test ratio +prompt_rspec_stats() { + if [[ -d app && -d spec ]]; then + local -a code=(app/**/*.rb(N)) + (( $#code )) || return + local tests=(spec/**/*.rb(N)) + _p9k_build_test_stats "$0" "$#code" "$#tests" "RSpec" 'TEST_ICON' + fi +} + +################################################################ +# Segment to display Ruby Version Manager information +prompt_rvm() { + [[ $GEM_HOME == *rvm* && $ruby_string != $rvm_path/bin/ruby ]] || return + local v=${GEM_HOME:t} + (( _POWERLEVEL9K_RVM_SHOW_GEMSET )) || v=${v%%${rvm_gemset_separator:-@}*} + (( _POWERLEVEL9K_RVM_SHOW_PREFIX )) || v=${v#*-} + [[ -n $v ]] || return + _p9k_prompt_segment "$0" "240" "$_p9k_color1" 'RUBY_ICON' 0 '' "${v//\%/%%}" +} + +_p9k_prompt_rvm_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${commands[rvm-prompt]:-${${+functions[rvm-prompt]}:#0}}' +} + +################################################################ +# Segment to display SSH icon when connected +prompt_ssh() { + local -i len=$#_p9k__prompt _p9k__has_upglob + _p9k_prompt_segment "$0" "$_p9k_color1" "yellow" 'SSH_ICON' 0 '' '' + (( _p9k__has_upglob )) || typeset -g "_p9k__segment_val_${_p9k__prompt_side}[_p9k__segment_index]"=$_p9k__prompt[len+1,-1] +} + +_p9k_prompt_ssh_init() { + if (( ! P9K_SSH )); then + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${:-}' + fi +} + +instant_prompt_ssh() { + if (( ! P9K_SSH )); then + return + fi + prompt_ssh +} + +################################################################ +# Status: When an error occur, return the error code, or a cross icon if option is set +# Display an ok icon when no error occur, or hide the segment if option is set to false +prompt_status() { + if ! _p9k_cache_get $0 $_p9k__status $_p9k__pipestatus; then + (( _p9k__status )) && local state=ERROR || local state=OK + if (( _POWERLEVEL9K_STATUS_EXTENDED_STATES )); then + if (( _p9k__status )); then + if (( $#_p9k__pipestatus > 1 )); then + state+=_PIPE + elif (( _p9k__status > 128 )); then + state+=_SIGNAL + fi + elif [[ "$_p9k__pipestatus" == *[1-9]* ]]; then + state+=_PIPE + fi + fi + _p9k__cache_val=(:) + if (( _POWERLEVEL9K_STATUS_$state )); then + if (( _POWERLEVEL9K_STATUS_SHOW_PIPESTATUS )); then + local text=${(j:|:)${(@)_p9k__pipestatus:/(#b)(*)/$_p9k_exitcode2str[$match[1]+1]}} + else + local text=$_p9k_exitcode2str[_p9k__status+1] + fi + if (( _p9k__status )); then + if (( !_POWERLEVEL9K_STATUS_CROSS && _POWERLEVEL9K_STATUS_VERBOSE )); then + _p9k__cache_val=($0_$state red yellow1 CARRIAGE_RETURN_ICON 0 '' "$text") + else + _p9k__cache_val=($0_$state $_p9k_color1 red FAIL_ICON 0 '' '') + fi + elif (( _POWERLEVEL9K_STATUS_VERBOSE || _POWERLEVEL9K_STATUS_OK_IN_NON_VERBOSE )); then + [[ $state == OK ]] && text='' + _p9k__cache_val=($0_$state "$_p9k_color1" green OK_ICON 0 '' "$text") + fi + fi + if (( $#_p9k__pipestatus < 3 )); then + _p9k_cache_set "${(@)_p9k__cache_val}" + fi + fi + _p9k_prompt_segment "${(@)_p9k__cache_val}" +} + +instant_prompt_status() { + if (( _POWERLEVEL9K_STATUS_OK )); then + _p9k_prompt_segment prompt_status_OK "$_p9k_color1" green OK_ICON 0 '' '' + fi +} + +prompt_prompt_char() { + local saved=$_p9k__prompt_char_saved[$_p9k__prompt_side$_p9k__segment_index$((!_p9k__status))] + if [[ -n $saved ]]; then + _p9k__prompt+=$saved + return + fi + local -i len=$#_p9k__prompt _p9k__has_upglob + if (( __p9k_sh_glob )); then + if (( _p9k__status )); then + if (( _POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE )); then + _p9k_prompt_segment $0_ERROR_VIINS "$_p9k_color1" 196 '' 0 '${${${${${${:-$_p9k__keymap.$_p9k__zle_state}:#vicmd.*}:#vivis.*}:#vivli.*}:#*.*overwrite*}}' '❯' + _p9k_prompt_segment $0_ERROR_VIOWR "$_p9k_color1" 196 '' 0 '${${${${${${:-$_p9k__keymap.$_p9k__zle_state}:#vicmd.*}:#vivis.*}:#vivli.*}:#*.*insert*}}' '▶' + else + _p9k_prompt_segment $0_ERROR_VIINS "$_p9k_color1" 196 '' 0 '${${${${_p9k__keymap:#vicmd}:#vivis}:#vivli}}' '❯' + fi + _p9k_prompt_segment $0_ERROR_VICMD "$_p9k_color1" 196 '' 0 '${(M)${:-$_p9k__keymap$_p9k__region_active}:#vicmd0}' '❮' + _p9k_prompt_segment $0_ERROR_VIVIS "$_p9k_color1" 196 '' 0 '${$((! ${#${${${${:-$_p9k__keymap$_p9k__region_active}:#vicmd1}:#vivis?}:#vivli?}})):#0}' 'Ⅴ' + else + if (( _POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE )); then + _p9k_prompt_segment $0_OK_VIINS "$_p9k_color1" 76 '' 0 '${${${${${${:-$_p9k__keymap.$_p9k__zle_state}:#vicmd.*}:#vivis.*}:#vivli.*}:#*.*overwrite*}}' '❯' + _p9k_prompt_segment $0_OK_VIOWR "$_p9k_color1" 76 '' 0 '${${${${${${:-$_p9k__keymap.$_p9k__zle_state}:#vicmd.*}:#vivis.*}:#vivli.*}:#*.*insert*}}' '▶' + else + _p9k_prompt_segment $0_OK_VIINS "$_p9k_color1" 76 '' 0 '${${${${_p9k__keymap:#vicmd}:#vivis}:#vivli}}' '❯' + fi + _p9k_prompt_segment $0_OK_VICMD "$_p9k_color1" 76 '' 0 '${(M)${:-$_p9k__keymap$_p9k__region_active}:#vicmd0}' '❮' + _p9k_prompt_segment $0_OK_VIVIS "$_p9k_color1" 76 '' 0 '${$((! ${#${${${${:-$_p9k__keymap$_p9k__region_active}:#vicmd1}:#vivis?}:#vivli?}})):#0}' 'Ⅴ' + fi + else + if (( _p9k__status )); then + if (( _POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE )); then + _p9k_prompt_segment $0_ERROR_VIINS "$_p9k_color1" 196 '' 0 '${${:-$_p9k__keymap.$_p9k__zle_state}:#(vicmd.*|vivis.*|vivli.*|*.*overwrite*)}' '❯' + _p9k_prompt_segment $0_ERROR_VIOWR "$_p9k_color1" 196 '' 0 '${${:-$_p9k__keymap.$_p9k__zle_state}:#(vicmd.*|vivis.*|vivli.*|*.*insert*)}' '▶' + else + _p9k_prompt_segment $0_ERROR_VIINS "$_p9k_color1" 196 '' 0 '${_p9k__keymap:#(vicmd|vivis|vivli)}' '❯' + fi + _p9k_prompt_segment $0_ERROR_VICMD "$_p9k_color1" 196 '' 0 '${(M)${:-$_p9k__keymap$_p9k__region_active}:#vicmd0}' '❮' + _p9k_prompt_segment $0_ERROR_VIVIS "$_p9k_color1" 196 '' 0 '${(M)${:-$_p9k__keymap$_p9k__region_active}:#(vicmd1|vivis?|vivli?)}' 'Ⅴ' + else + if (( _POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE )); then + _p9k_prompt_segment $0_OK_VIINS "$_p9k_color1" 76 '' 0 '${${:-$_p9k__keymap.$_p9k__zle_state}:#(vicmd.*|vivis.*|vivli.*|*.*overwrite*)}' '❯' + _p9k_prompt_segment $0_OK_VIOWR "$_p9k_color1" 76 '' 0 '${${:-$_p9k__keymap.$_p9k__zle_state}:#(vicmd.*|vivis.*|vivli.*|*.*insert*)}' '▶' + else + _p9k_prompt_segment $0_OK_VIINS "$_p9k_color1" 76 '' 0 '${_p9k__keymap:#(vicmd|vivis|vivli)}' '❯' + fi + _p9k_prompt_segment $0_OK_VICMD "$_p9k_color1" 76 '' 0 '${(M)${:-$_p9k__keymap$_p9k__region_active}:#vicmd0}' '❮' + _p9k_prompt_segment $0_OK_VIVIS "$_p9k_color1" 76 '' 0 '${(M)${:-$_p9k__keymap$_p9k__region_active}:#(vicmd1|vivis?|vivli?)}' 'Ⅴ' + fi + fi + (( _p9k__has_upglob )) || _p9k__prompt_char_saved[$_p9k__prompt_side$_p9k__segment_index$((!_p9k__status))]=$_p9k__prompt[len+1,-1] +} + +instant_prompt_prompt_char() { + _p9k_prompt_segment prompt_prompt_char_OK_VIINS "$_p9k_color1" 76 '' 0 '' '❯' +} + +################################################################ +# Segment to display Swap information +prompt_swap() { + local -i len=$#_p9k__prompt _p9k__has_upglob + _p9k_prompt_segment $0 yellow "$_p9k_color1" SWAP_ICON 1 '$_p9k__swap_used' '$_p9k__swap_used' + (( _p9k__has_upglob )) || typeset -g "_p9k__segment_val_${_p9k__prompt_side}[_p9k__segment_index]"=$_p9k__prompt[len+1,-1] +} + +function _p9k_prompt_swap_init() { + if [[ $_p9k_os == OSX && $+commands[sysctl] == 0 || $_p9k_os != OSX && ! -r /proc/meminfo ]]; then + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${:-}' + return + fi + typeset -g _p9k__swap_used= + _p9k__async_segments_compute+='_p9k_worker_invoke swap _p9k_prompt_swap_compute' +} + +_p9k_prompt_swap_compute() { + _p9k_worker_async _p9k_prompt_swap_async _p9k_prompt_swap_sync +} + +_p9k_prompt_swap_async() { + local -F used_bytes + + if [[ "$_p9k_os" == "OSX" ]]; then + (( $+commands[sysctl] )) || return + [[ "$(sysctl vm.swapusage 2>/dev/null)" =~ "used = ([0-9,.]+)([A-Z]+)" ]] || return + used_bytes=${match[1]//,/.} + case ${match[2]} in + 'K') (( used_bytes *= 1024 ));; + 'M') (( used_bytes *= 1048576 ));; + 'G') (( used_bytes *= 1073741824 ));; + 'T') (( used_bytes *= 1099511627776 ));; + *) return 0;; + esac + else + local meminfo && meminfo="$(grep -F 'Swap' /proc/meminfo 2>/dev/null)" || return + [[ $meminfo =~ 'SwapTotal:[[:space:]]+([0-9]+)' ]] || return + (( used_bytes+=match[1] )) + [[ $meminfo =~ 'SwapFree:[[:space:]]+([0-9]+)' ]] || return + (( used_bytes-=match[1] )) + (( used_bytes *= 1024 )) + fi + + _p9k_human_readable_bytes $used_bytes + [[ $_p9k__ret != $_p9k__swap_used ]] || return + _p9k__swap_used=$_p9k__ret + _p9k_print_params _p9k__swap_used + echo -E - 'reset=1' +} + +_p9k_prompt_swap_sync() { + eval $REPLY + _p9k_worker_reply $REPLY +} + +################################################################ +# Symfony2-PHPUnit test ratio +prompt_symfony2_tests() { + if [[ -d src && -d app && -f app/AppKernel.php ]]; then + local -a all=(src/**/*.php(N)) + local -a code=(${(@)all##*Tests*}) + (( $#code )) || return + _p9k_build_test_stats "$0" "$#code" "$(($#all - $#code))" "SF2" 'TEST_ICON' + fi +} + +################################################################ +# Segment to display Symfony2-Version +prompt_symfony2_version() { + if [[ -r app/bootstrap.php.cache ]]; then + local v="${$(grep -F " VERSION " app/bootstrap.php.cache 2>/dev/null)//[![:digit:].]}" + _p9k_prompt_segment "$0" "grey35" "$_p9k_color1" 'SYMFONY_ICON' 0 '' "${v//\%/%%}" + fi +} + +################################################################ +# Show a ratio of tests vs code +_p9k_build_test_stats() { + local code_amount="$2" + local tests_amount="$3" + local headline="$4" + + (( code_amount > 0 )) || return + local -F 2 ratio=$(( 100. * tests_amount / code_amount )) + + (( ratio >= 75 )) && _p9k_prompt_segment "${1}_GOOD" "cyan" "$_p9k_color1" "$5" 0 '' "$headline: $ratio%%" + (( ratio >= 50 && ratio < 75 )) && _p9k_prompt_segment "$1_AVG" "yellow" "$_p9k_color1" "$5" 0 '' "$headline: $ratio%%" + (( ratio < 50 )) && _p9k_prompt_segment "$1_BAD" "red" "$_p9k_color1" "$5" 0 '' "$headline: $ratio%%" +} + +################################################################ +# System time +prompt_time() { + if (( _POWERLEVEL9K_EXPERIMENTAL_TIME_REALTIME )); then + _p9k_prompt_segment "$0" "$_p9k_color2" "$_p9k_color1" "TIME_ICON" 0 '' "$_POWERLEVEL9K_TIME_FORMAT" + else + if [[ $_p9k__refresh_reason == precmd ]]; then + if [[ $+__p9k_instant_prompt_active == 1 && $__p9k_instant_prompt_time_format == $_POWERLEVEL9K_TIME_FORMAT ]]; then + _p9k__time=${__p9k_instant_prompt_time//\%/%%} + else + _p9k__time=${${(%)_POWERLEVEL9K_TIME_FORMAT}//\%/%%} + fi + fi + if (( _POWERLEVEL9K_TIME_UPDATE_ON_COMMAND )); then + _p9k_escape $_p9k__time + local t=$_p9k__ret + _p9k_escape $_POWERLEVEL9K_TIME_FORMAT + _p9k_prompt_segment "$0" "$_p9k_color2" "$_p9k_color1" "TIME_ICON" 1 '' \ + "\${_p9k__line_finished-$t}\${_p9k__line_finished+$_p9k__ret}" + else + _p9k_prompt_segment "$0" "$_p9k_color2" "$_p9k_color1" "TIME_ICON" 0 '' $_p9k__time + fi + fi +} + +instant_prompt_time() { + _p9k_escape $_POWERLEVEL9K_TIME_FORMAT + local stash='${${__p9k_instant_prompt_time::=${(%)${__p9k_instant_prompt_time_format::='$_p9k__ret'}}}+}' + _p9k_escape $_POWERLEVEL9K_TIME_FORMAT + _p9k_prompt_segment prompt_time "$_p9k_color2" "$_p9k_color1" "TIME_ICON" 1 '' $stash$_p9k__ret +} + +_p9k_prompt_time_init() { + (( _POWERLEVEL9K_EXPERIMENTAL_TIME_REALTIME )) || return + _p9k__async_segments_compute+='_p9k_worker_invoke time _p9k_prompt_time_compute' +} + +_p9k_prompt_time_compute() { + _p9k_worker_async _p9k_prompt_time_async _p9k_prompt_time_sync +} + +_p9k_prompt_time_async() { + sleep 1 || true +} + +_p9k_prompt_time_sync() { + _p9k_worker_reply '_p9k_worker_invoke _p9k_prompt_time_compute _p9k_prompt_time_compute; reset=1' +} + +################################################################ +# System date +prompt_date() { + if [[ $_p9k__refresh_reason == precmd ]]; then + if [[ $+__p9k_instant_prompt_active == 1 && $__p9k_instant_prompt_date_format == $_POWERLEVEL9K_DATE_FORMAT ]]; then + _p9k__date=${__p9k_instant_prompt_date//\%/%%} + else + _p9k__date=${${(%)_POWERLEVEL9K_DATE_FORMAT}//\%/%%} + fi + fi + _p9k_prompt_segment "$0" "$_p9k_color2" "$_p9k_color1" "DATE_ICON" 0 '' "$_p9k__date" +} + +instant_prompt_date() { + _p9k_escape $_POWERLEVEL9K_DATE_FORMAT + local stash='${${__p9k_instant_prompt_date::=${(%)${__p9k_instant_prompt_date_format::='$_p9k__ret'}}}+}' + _p9k_escape $_POWERLEVEL9K_DATE_FORMAT + _p9k_prompt_segment prompt_date "$_p9k_color2" "$_p9k_color1" "DATE_ICON" 1 '' $stash$_p9k__ret +} + +################################################################ +# todo.sh: shows the number of tasks in your todo.sh file +prompt_todo() { + unset P9K_TODO_TOTAL_TASK_COUNT P9K_TODO_FILTERED_TASK_COUNT + [[ -r $_p9k__todo_file ]] || return + local todo=$commands[todo.sh] + if ! _p9k_cache_stat_get $0 $_p9k__todo_file; then + local count="$($todo -p ls | tail -1)" + if [[ $count == (#b)'TODO: '([[:digit:]]##)' of '([[:digit:]]##)' '* ]]; then + _p9k_cache_stat_set 1 $match[1] $match[2] + else + _p9k_cache_stat_set 0 + fi + fi + (( $_p9k__cache_val[1] )) || return + typeset -gi P9K_TODO_FILTERED_TASK_COUNT=$_p9k__cache_val[2] + typeset -gi P9K_TODO_TOTAL_TASK_COUNT=$_p9k__cache_val[3] + if (( (P9K_TODO_TOTAL_TASK_COUNT || !_POWERLEVEL9K_TODO_HIDE_ZERO_TOTAL) && + (P9K_TODO_FILTERED_TASK_COUNT || !_POWERLEVEL9K_TODO_HIDE_ZERO_FILTERED) )); then + if (( P9K_TODO_TOTAL_TASK_COUNT == P9K_TODO_FILTERED_TASK_COUNT )); then + local text=$P9K_TODO_TOTAL_TASK_COUNT + else + local text="$P9K_TODO_FILTERED_TASK_COUNT/$P9K_TODO_TOTAL_TASK_COUNT" + fi + _p9k_prompt_segment "$0" "grey50" "$_p9k_color1" 'TODO_ICON' 0 '' "$text" + fi +} + +_p9k_prompt_todo_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$commands[todo.sh]' +} + +################################################################ +# VCS segment: shows the state of your repository, if you are in a folder under +# version control + +# The vcs segment can have 4 different states - defaults to 'CLEAN'. +typeset -gA __p9k_vcs_states=( + 'CLEAN' '2' + 'MODIFIED' '3' + 'UNTRACKED' '2' + 'LOADING' '8' + 'CONFLICTED' '3' +) + +function +vi-git-untracked() { + [[ -z "${vcs_comm[gitdir]}" || "${vcs_comm[gitdir]}" == "." ]] && return + + # get the root for the current repo or submodule + local repoTopLevel="$(git rev-parse --show-toplevel 2> /dev/null)" + # dump out if we're outside a git repository (which includes being in the .git folder) + [[ $? != 0 || -z $repoTopLevel ]] && return + + local untrackedFiles="$(git ls-files --others --exclude-standard "${repoTopLevel}" 2> /dev/null)" + + if [[ -z $untrackedFiles && $_POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY == 1 ]]; then + untrackedFiles+="$(git submodule foreach --quiet --recursive 'git ls-files --others --exclude-standard' 2> /dev/null)" + fi + + [[ -z $untrackedFiles ]] && return + + hook_com[unstaged]+=" $(print_icon 'VCS_UNTRACKED_ICON')" + VCS_WORKDIR_HALF_DIRTY=true +} + +function +vi-git-aheadbehind() { + local ahead behind + local -a gitstatus + + # for git prior to 1.7 + # ahead=$(git rev-list origin/${hook_com[branch]}..HEAD | wc -l) + ahead="$(git rev-list --count "${hook_com[branch]}"@{upstream}..HEAD 2>/dev/null)" + (( ahead )) && gitstatus+=( " $(print_icon 'VCS_OUTGOING_CHANGES_ICON')${ahead// /}" ) + + # for git prior to 1.7 + # behind=$(git rev-list HEAD..origin/${hook_com[branch]} | wc -l) + behind="$(git rev-list --count HEAD.."${hook_com[branch]}"@{upstream} 2>/dev/null)" + (( behind )) && gitstatus+=( " $(print_icon 'VCS_INCOMING_CHANGES_ICON')${behind// /}" ) + + hook_com[misc]+=${(j::)gitstatus} +} + +function +vi-git-remotebranch() { + local remote + local branch_name="${hook_com[branch]}" + + # Are we on a remote-tracking branch? + remote="$(git rev-parse --verify HEAD@{upstream} --symbolic-full-name 2>/dev/null)" + remote=${remote/refs\/(remotes|heads)\/} + + if (( $+_POWERLEVEL9K_VCS_SHORTEN_LENGTH && $+_POWERLEVEL9K_VCS_SHORTEN_MIN_LENGTH )); then + if (( ${#hook_com[branch]} > _POWERLEVEL9K_VCS_SHORTEN_MIN_LENGTH && ${#hook_com[branch]} > _POWERLEVEL9K_VCS_SHORTEN_LENGTH )); then + case $_POWERLEVEL9K_VCS_SHORTEN_STRATEGY in + truncate_middle) + hook_com[branch]="${branch_name:0:$_POWERLEVEL9K_VCS_SHORTEN_LENGTH}${_POWERLEVEL9K_VCS_SHORTEN_DELIMITER}${branch_name: -$_POWERLEVEL9K_VCS_SHORTEN_LENGTH}" + ;; + truncate_from_right) + hook_com[branch]="${branch_name:0:$_POWERLEVEL9K_VCS_SHORTEN_LENGTH}${_POWERLEVEL9K_VCS_SHORTEN_DELIMITER}" + ;; + esac + fi + fi + + if (( _POWERLEVEL9K_HIDE_BRANCH_ICON )); then + hook_com[branch]="${hook_com[branch]}" + else + hook_com[branch]="$(print_icon 'VCS_BRANCH_ICON')${hook_com[branch]}" + fi + # 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]+="$(print_icon 'VCS_REMOTE_BRANCH_ICON')${remote// /}" + fi +} + +function +vi-git-tagname() { + if (( !_POWERLEVEL9K_VCS_HIDE_TAGS )); 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_CHANGESET_HASH_LENGTH} HEAD)" + if (( _POWERLEVEL9K_HIDE_BRANCH_ICON )); then + hook_com[branch]="${revision} $(print_icon 'VCS_TAG_ICON')${tag}" + else + hook_com[branch]="$(print_icon 'VCS_BRANCH_ICON')${revision} $(print_icon 'VCS_TAG_ICON')${tag}" + fi + 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 +# Port from https://github.com/whiteinge/dotfiles/blob/5dfd08d30f7f2749cfc60bc55564c6ea239624d9/.zsh_shouse_prompt#L268 +function +vi-git-stash() { + if [[ -s "${vcs_comm[gitdir]}/logs/refs/stash" ]] ; then + local -a stashes=( "${(@f)"$(<${vcs_comm[gitdir]}/logs/refs/stash)"}" ) + hook_com[misc]+=" $(print_icon 'VCS_STASH_ICON')${#stashes}" + fi +} + +function +vi-hg-bookmarks() { + if [[ -n "${hgbmarks[@]}" ]]; then + hook_com[hg-bookmark-string]=" $(print_icon 'VCS_BOOKMARK_ICON')${hgbmarks[@]}" + + # To signal that we want to use the sting we just generated, set the special + # variable `ret' to something other than the default zero: + ret=1 + return 0 + fi +} + +function +vi-vcs-detect-changes() { + if [[ "${hook_com[vcs]}" == "git" ]]; then + + local remote="$(git ls-remote --get-url 2> /dev/null)" + if [[ "$remote" =~ "github" ]] then + vcs_visual_identifier='VCS_GIT_GITHUB_ICON' + elif [[ "$remote" =~ "bitbucket" ]] then + vcs_visual_identifier='VCS_GIT_BITBUCKET_ICON' + elif [[ "$remote" =~ "stash" ]] then + vcs_visual_identifier='VCS_GIT_BITBUCKET_ICON' + elif [[ "$remote" =~ "gitlab" ]] then + vcs_visual_identifier='VCS_GIT_GITLAB_ICON' + else + vcs_visual_identifier='VCS_GIT_ICON' + fi + + 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 + VCS_WORKDIR_DIRTY=true + else + 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 +} + +_p9k_vcs_info_init() { + autoload -Uz vcs_info + + local prefix='' + if (( _POWERLEVEL9K_SHOW_CHANGESET )); then + _p9k_get_icon '' VCS_COMMIT_ICON + prefix="$_p9k__ret%0.${_POWERLEVEL9K_CHANGESET_HASH_LENGTH}i " + fi + + zstyle ':vcs_info:*' check-for-changes true + + zstyle ':vcs_info:*' formats "$prefix%b%c%u%m" + zstyle ':vcs_info:*' actionformats "%b %F{$_POWERLEVEL9K_VCS_ACTIONFORMAT_FOREGROUND}| %a%f" + _p9k_get_icon '' VCS_STAGED_ICON + zstyle ':vcs_info:*' stagedstr " $_p9k__ret" + _p9k_get_icon '' VCS_UNSTAGED_ICON + zstyle ':vcs_info:*' unstagedstr " $_p9k__ret" + zstyle ':vcs_info:git*+set-message:*' hooks $_POWERLEVEL9K_VCS_GIT_HOOKS + zstyle ':vcs_info:hg*+set-message:*' hooks $_POWERLEVEL9K_VCS_HG_HOOKS + zstyle ':vcs_info:svn*+set-message:*' hooks $_POWERLEVEL9K_VCS_SVN_HOOKS + + # For Hg, only show the branch name + if (( _POWERLEVEL9K_HIDE_BRANCH_ICON )); then + zstyle ':vcs_info:hg*:*' branchformat "%b" + else + _p9k_get_icon '' VCS_BRANCH_ICON + zstyle ':vcs_info:hg*:*' branchformat "$_p9k__ret%b" + fi + # 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 + zstyle ':vcs_info:hg*+gen-hg-bookmark-string:*' hooks hg-bookmarks + + # TODO: fix the %b (branch) format for svn. Using %b breaks color-encoding of the foreground + # for the rest of the powerline. + zstyle ':vcs_info:svn*:*' formats "$prefix%c%u" + zstyle ':vcs_info:svn*:*' actionformats "$prefix%c%u %F{$_POWERLEVEL9K_VCS_ACTIONFORMAT_FOREGROUND}| %a%f" + + if (( _POWERLEVEL9K_SHOW_CHANGESET )); then + zstyle ':vcs_info:*' get-revision true + else + zstyle ':vcs_info:*' get-revision false + fi +} + +function _p9k_vcs_status_save() { + local z=$'\0' + _p9k__gitstatus_last[${${_p9k__git_dir:+GIT_DIR:$_p9k__git_dir}:-$VCS_STATUS_WORKDIR}]=\ +$VCS_STATUS_COMMIT$z$VCS_STATUS_LOCAL_BRANCH$z$VCS_STATUS_REMOTE_BRANCH$z$VCS_STATUS_REMOTE_NAME$z\ +$VCS_STATUS_REMOTE_URL$z$VCS_STATUS_ACTION$z$VCS_STATUS_INDEX_SIZE$z$VCS_STATUS_NUM_STAGED$z\ +$VCS_STATUS_NUM_UNSTAGED$z$VCS_STATUS_NUM_CONFLICTED$z$VCS_STATUS_NUM_UNTRACKED$z\ +$VCS_STATUS_HAS_STAGED$z$VCS_STATUS_HAS_UNSTAGED$z$VCS_STATUS_HAS_CONFLICTED$z\ +$VCS_STATUS_HAS_UNTRACKED$z$VCS_STATUS_COMMITS_AHEAD$z$VCS_STATUS_COMMITS_BEHIND$z\ +$VCS_STATUS_STASHES$z$VCS_STATUS_TAG$z$VCS_STATUS_NUM_UNSTAGED_DELETED$z\ +$VCS_STATUS_NUM_STAGED_NEW$z$VCS_STATUS_NUM_STAGED_DELETED$z$VCS_STATUS_PUSH_REMOTE_NAME$z\ +$VCS_STATUS_PUSH_REMOTE_URL$z$VCS_STATUS_PUSH_COMMITS_AHEAD$z$VCS_STATUS_PUSH_COMMITS_BEHIND$z\ +$VCS_STATUS_NUM_SKIP_WORKTREE$z$VCS_STATUS_NUM_ASSUME_UNCHANGED +} + +function _p9k_vcs_status_restore() { + for VCS_STATUS_COMMIT VCS_STATUS_LOCAL_BRANCH VCS_STATUS_REMOTE_BRANCH VCS_STATUS_REMOTE_NAME \ + VCS_STATUS_REMOTE_URL VCS_STATUS_ACTION VCS_STATUS_INDEX_SIZE VCS_STATUS_NUM_STAGED \ + VCS_STATUS_NUM_UNSTAGED VCS_STATUS_NUM_CONFLICTED VCS_STATUS_NUM_UNTRACKED \ + VCS_STATUS_HAS_STAGED VCS_STATUS_HAS_UNSTAGED VCS_STATUS_HAS_CONFLICTED \ + VCS_STATUS_HAS_UNTRACKED VCS_STATUS_COMMITS_AHEAD VCS_STATUS_COMMITS_BEHIND \ + VCS_STATUS_STASHES VCS_STATUS_TAG VCS_STATUS_NUM_UNSTAGED_DELETED VCS_STATUS_NUM_STAGED_NEW \ + VCS_STATUS_NUM_STAGED_DELETED VCS_STATUS_PUSH_REMOTE_NAME VCS_STATUS_PUSH_REMOTE_URL \ + VCS_STATUS_PUSH_COMMITS_AHEAD VCS_STATUS_PUSH_COMMITS_BEHIND VCS_STATUS_NUM_SKIP_WORKTREE \ + VCS_STATUS_NUM_ASSUME_UNCHANGED + in "${(@0)1}"; do done +} + +function _p9k_vcs_status_for_dir() { + if [[ -n $GIT_DIR ]]; then + _p9k__ret=$_p9k__gitstatus_last[GIT_DIR:$GIT_DIR] + [[ -n $_p9k__ret ]] + else + local dir=$_p9k__cwd_a + while true; do + _p9k__ret=$_p9k__gitstatus_last[$dir] + [[ -n $_p9k__ret ]] && return 0 + [[ $dir == / ]] && return 1 + dir=${dir:h} + done + fi +} + +function _p9k_vcs_status_purge() { + if [[ -n $_p9k__git_dir ]]; then + _p9k__gitstatus_last[GIT_DIR:$_p9k__git_dir]="" + else + local dir=$1 + while true; do + # unset doesn't work if $dir contains weird shit + _p9k__gitstatus_last[$dir]="" + _p9k_git_slow[$dir]="" + [[ $dir == / ]] && break + dir=${dir:h} + done + fi +} + +function _p9k_vcs_icon() { + case "$VCS_STATUS_REMOTE_URL" in + *github*) _p9k__ret=VCS_GIT_GITHUB_ICON;; + *bitbucket*) _p9k__ret=VCS_GIT_BITBUCKET_ICON;; + *stash*) _p9k__ret=VCS_GIT_GITHUB_ICON;; + *gitlab*) _p9k__ret=VCS_GIT_GITLAB_ICON;; + *) _p9k__ret=VCS_GIT_ICON;; + esac +} + +function _p9k_vcs_render() { + local state + + if (( $+_p9k__gitstatus_next_dir )); then + if _p9k_vcs_status_for_dir; then + _p9k_vcs_status_restore $_p9k__ret + state=LOADING + else + _p9k_prompt_segment prompt_vcs_LOADING "${__p9k_vcs_states[LOADING]}" "$_p9k_color1" VCS_LOADING_ICON 0 '' "$_POWERLEVEL9K_VCS_LOADING_TEXT" + return 0 + fi + elif [[ $VCS_STATUS_RESULT != ok-* ]]; then + return 1 + fi + + if (( _POWERLEVEL9K_VCS_DISABLE_GITSTATUS_FORMATTING )); then + if [[ -z $state ]]; then + if [[ $VCS_STATUS_HAS_CONFLICTED == 1 && $_POWERLEVEL9K_VCS_CONFLICTED_STATE == 1 ]]; then + state=CONFLICTED + elif [[ $VCS_STATUS_HAS_STAGED != 0 || $VCS_STATUS_HAS_UNSTAGED != 0 ]]; then + state=MODIFIED + elif [[ $VCS_STATUS_HAS_UNTRACKED != 0 ]]; then + state=UNTRACKED + else + state=CLEAN + fi + fi + _p9k_vcs_icon + _p9k_prompt_segment prompt_vcs_$state "${__p9k_vcs_states[$state]}" "$_p9k_color1" "$_p9k__ret" 0 '' "" + return 0 + fi + + (( ${_POWERLEVEL9K_VCS_GIT_HOOKS[(I)git-untracked]} )) || VCS_STATUS_HAS_UNTRACKED=0 + (( ${_POWERLEVEL9K_VCS_GIT_HOOKS[(I)git-aheadbehind]} )) || { VCS_STATUS_COMMITS_AHEAD=0 && VCS_STATUS_COMMITS_BEHIND=0 } + (( ${_POWERLEVEL9K_VCS_GIT_HOOKS[(I)git-stash]} )) || VCS_STATUS_STASHES=0 + (( ${_POWERLEVEL9K_VCS_GIT_HOOKS[(I)git-remotebranch]} )) || VCS_STATUS_REMOTE_BRANCH="" + (( ${_POWERLEVEL9K_VCS_GIT_HOOKS[(I)git-tagname]} )) || VCS_STATUS_TAG="" + + (( _POWERLEVEL9K_VCS_COMMITS_AHEAD_MAX_NUM >= 0 && VCS_STATUS_COMMITS_AHEAD > _POWERLEVEL9K_VCS_COMMITS_AHEAD_MAX_NUM )) && + VCS_STATUS_COMMITS_AHEAD=$_POWERLEVEL9K_VCS_COMMITS_AHEAD_MAX_NUM + + (( _POWERLEVEL9K_VCS_COMMITS_BEHIND_MAX_NUM >= 0 && VCS_STATUS_COMMITS_BEHIND > _POWERLEVEL9K_VCS_COMMITS_BEHIND_MAX_NUM )) && + VCS_STATUS_COMMITS_BEHIND=$_POWERLEVEL9K_VCS_COMMITS_BEHIND_MAX_NUM + + local -a cache_key=( + "$VCS_STATUS_LOCAL_BRANCH" + "$VCS_STATUS_REMOTE_BRANCH" + "$VCS_STATUS_REMOTE_URL" + "$VCS_STATUS_ACTION" + "$VCS_STATUS_NUM_STAGED" + "$VCS_STATUS_NUM_UNSTAGED" + "$VCS_STATUS_NUM_UNTRACKED" + "$VCS_STATUS_HAS_CONFLICTED" + "$VCS_STATUS_HAS_STAGED" + "$VCS_STATUS_HAS_UNSTAGED" + "$VCS_STATUS_HAS_UNTRACKED" + "$VCS_STATUS_COMMITS_AHEAD" + "$VCS_STATUS_COMMITS_BEHIND" + "$VCS_STATUS_STASHES" + "$VCS_STATUS_TAG" + "$VCS_STATUS_NUM_UNSTAGED_DELETED" + ) + if [[ $_POWERLEVEL9K_SHOW_CHANGESET == 1 || -z $VCS_STATUS_LOCAL_BRANCH ]]; then + cache_key+=$VCS_STATUS_COMMIT + fi + + if ! _p9k_cache_ephemeral_get "$state" "${(@)cache_key}"; then + local icon + local content + + if (( ${_POWERLEVEL9K_VCS_GIT_HOOKS[(I)vcs-detect-changes]} )); then + if [[ $VCS_STATUS_HAS_CONFLICTED == 1 && $_POWERLEVEL9K_VCS_CONFLICTED_STATE == 1 ]]; then + : ${state:=CONFLICTED} + elif [[ $VCS_STATUS_HAS_STAGED != 0 || $VCS_STATUS_HAS_UNSTAGED != 0 ]]; then + : ${state:=MODIFIED} + elif [[ $VCS_STATUS_HAS_UNTRACKED != 0 ]]; then + : ${state:=UNTRACKED} + fi + + # It's weird that removing vcs-detect-changes from POWERLEVEL9K_VCS_GIT_HOOKS gets rid + # of the GIT icon. That's what vcs_info does, so we do the same in the name of compatiblity. + case "$VCS_STATUS_REMOTE_URL" in + *github*) icon=VCS_GIT_GITHUB_ICON;; + *bitbucket*) icon=VCS_GIT_BITBUCKET_ICON;; + *stash*) icon=VCS_GIT_GITHUB_ICON;; + *gitlab*) icon=VCS_GIT_GITLAB_ICON;; + *) icon=VCS_GIT_ICON;; + esac + fi + + : ${state:=CLEAN} + + function _$0_fmt() { + _p9k_vcs_style $state $1 + content+="$_p9k__ret$2" + } + + local ws + if [[ $_POWERLEVEL9K_SHOW_CHANGESET == 1 || -z $VCS_STATUS_LOCAL_BRANCH ]]; then + _p9k_get_icon prompt_vcs_$state VCS_COMMIT_ICON + _$0_fmt COMMIT "$_p9k__ret${${VCS_STATUS_COMMIT:0:$_POWERLEVEL9K_CHANGESET_HASH_LENGTH}:-HEAD}" + ws=' ' + fi + + if [[ -n $VCS_STATUS_LOCAL_BRANCH ]]; then + local branch=$ws + if (( !_POWERLEVEL9K_HIDE_BRANCH_ICON )); then + _p9k_get_icon prompt_vcs_$state VCS_BRANCH_ICON + branch+=$_p9k__ret + fi + if (( $+_POWERLEVEL9K_VCS_SHORTEN_LENGTH && $+_POWERLEVEL9K_VCS_SHORTEN_MIN_LENGTH && + $#VCS_STATUS_LOCAL_BRANCH > _POWERLEVEL9K_VCS_SHORTEN_MIN_LENGTH && + $#VCS_STATUS_LOCAL_BRANCH > _POWERLEVEL9K_VCS_SHORTEN_LENGTH )) && + [[ $_POWERLEVEL9K_VCS_SHORTEN_STRATEGY == (truncate_middle|truncate_from_right) ]]; then + branch+=${VCS_STATUS_LOCAL_BRANCH[1,_POWERLEVEL9K_VCS_SHORTEN_LENGTH]//\%/%%}${_POWERLEVEL9K_VCS_SHORTEN_DELIMITER} + if [[ $_POWERLEVEL9K_VCS_SHORTEN_STRATEGY == truncate_middle ]]; then + _p9k_vcs_style $state BRANCH + branch+=${_p9k__ret}${VCS_STATUS_LOCAL_BRANCH[-_POWERLEVEL9K_VCS_SHORTEN_LENGTH,-1]//\%/%%} + fi + else + branch+=${VCS_STATUS_LOCAL_BRANCH//\%/%%} + fi + _$0_fmt BRANCH $branch + fi + + if [[ $_POWERLEVEL9K_VCS_HIDE_TAGS == 0 && -n $VCS_STATUS_TAG ]]; then + _p9k_get_icon prompt_vcs_$state VCS_TAG_ICON + _$0_fmt TAG " $_p9k__ret${VCS_STATUS_TAG//\%/%%}" + fi + + if [[ -n $VCS_STATUS_ACTION ]]; then + _$0_fmt ACTION " | ${VCS_STATUS_ACTION//\%/%%}" + else + if [[ -n $VCS_STATUS_REMOTE_BRANCH && + $VCS_STATUS_LOCAL_BRANCH != $VCS_STATUS_REMOTE_BRANCH ]]; then + _p9k_get_icon prompt_vcs_$state VCS_REMOTE_BRANCH_ICON + _$0_fmt REMOTE_BRANCH " $_p9k__ret${VCS_STATUS_REMOTE_BRANCH//\%/%%}" + fi + if [[ $VCS_STATUS_HAS_STAGED == 1 || $VCS_STATUS_HAS_UNSTAGED == 1 || $VCS_STATUS_HAS_UNTRACKED == 1 ]]; then + _p9k_get_icon prompt_vcs_$state VCS_DIRTY_ICON + _$0_fmt DIRTY "$_p9k__ret" + if [[ $VCS_STATUS_HAS_STAGED == 1 ]]; then + _p9k_get_icon prompt_vcs_$state VCS_STAGED_ICON + (( _POWERLEVEL9K_VCS_STAGED_MAX_NUM != 1 )) && _p9k__ret+=$VCS_STATUS_NUM_STAGED + _$0_fmt STAGED " $_p9k__ret" + fi + if [[ $VCS_STATUS_HAS_UNSTAGED == 1 ]]; then + _p9k_get_icon prompt_vcs_$state VCS_UNSTAGED_ICON + (( _POWERLEVEL9K_VCS_UNSTAGED_MAX_NUM != 1 )) && _p9k__ret+=$VCS_STATUS_NUM_UNSTAGED + _$0_fmt UNSTAGED " $_p9k__ret" + fi + if [[ $VCS_STATUS_HAS_UNTRACKED == 1 ]]; then + _p9k_get_icon prompt_vcs_$state VCS_UNTRACKED_ICON + (( _POWERLEVEL9K_VCS_UNTRACKED_MAX_NUM != 1 )) && _p9k__ret+=$VCS_STATUS_NUM_UNTRACKED + _$0_fmt UNTRACKED " $_p9k__ret" + fi + fi + if [[ $VCS_STATUS_COMMITS_BEHIND -gt 0 ]]; then + _p9k_get_icon prompt_vcs_$state VCS_INCOMING_CHANGES_ICON + (( _POWERLEVEL9K_VCS_COMMITS_BEHIND_MAX_NUM != 1 )) && _p9k__ret+=$VCS_STATUS_COMMITS_BEHIND + _$0_fmt INCOMING_CHANGES " $_p9k__ret" + fi + if [[ $VCS_STATUS_COMMITS_AHEAD -gt 0 ]]; then + _p9k_get_icon prompt_vcs_$state VCS_OUTGOING_CHANGES_ICON + (( _POWERLEVEL9K_VCS_COMMITS_AHEAD_MAX_NUM != 1 )) && _p9k__ret+=$VCS_STATUS_COMMITS_AHEAD + _$0_fmt OUTGOING_CHANGES " $_p9k__ret" + fi + if [[ $VCS_STATUS_STASHES -gt 0 ]]; then + _p9k_get_icon prompt_vcs_$state VCS_STASH_ICON + _$0_fmt STASH " $_p9k__ret$VCS_STATUS_STASHES" + fi + fi + + _p9k_cache_ephemeral_set "prompt_vcs_$state" "${__p9k_vcs_states[$state]}" "$_p9k_color1" "$icon" 0 '' "$content" + fi + + _p9k_prompt_segment "$_p9k__cache_val[@]" + return 0 +} + +function _p9k_maybe_ignore_git_repo() { + if [[ $VCS_STATUS_RESULT == ok-* && $VCS_STATUS_WORKDIR == $~_POWERLEVEL9K_VCS_DISABLED_WORKDIR_PATTERN ]]; then + VCS_STATUS_RESULT=norepo${VCS_STATUS_RESULT#ok} + fi +} + +function _p9k_vcs_resume() { + eval "$__p9k_intro" + + _p9k_maybe_ignore_git_repo + + if [[ $VCS_STATUS_RESULT == ok-async ]]; then + local latency=$((EPOCHREALTIME - _p9k__gitstatus_start_time)) + if (( latency > _POWERLEVEL9K_VCS_MAX_SYNC_LATENCY_SECONDS )); then + _p9k_git_slow[${${_p9k__git_dir:+GIT_DIR:$_p9k__git_dir}:-$VCS_STATUS_WORKDIR}]=1 + elif (( $1 && latency < 0.8 * _POWERLEVEL9K_VCS_MAX_SYNC_LATENCY_SECONDS )); then # 0.8 to avoid flip-flopping + _p9k_git_slow[${${_p9k__git_dir:+GIT_DIR:$_p9k__git_dir}:-$VCS_STATUS_WORKDIR}]=0 + fi + _p9k_vcs_status_save + fi + + if [[ -z $_p9k__gitstatus_next_dir ]]; then + unset _p9k__gitstatus_next_dir + case $VCS_STATUS_RESULT in + norepo-async) (( $1 )) && _p9k_vcs_status_purge $_p9k__cwd_a;; + ok-async) (( $1 )) || _p9k__gitstatus_next_dir=$_p9k__cwd_a;; + esac + fi + + if [[ -n $_p9k__gitstatus_next_dir ]]; then + _p9k__git_dir=$GIT_DIR + if ! gitstatus_query_p9k_ -d $_p9k__gitstatus_next_dir -t 0 -c '_p9k_vcs_resume 1' POWERLEVEL9K; then + unset _p9k__gitstatus_next_dir + unset VCS_STATUS_RESULT + else + _p9k_maybe_ignore_git_repo + case $VCS_STATUS_RESULT in + tout) _p9k__gitstatus_next_dir=''; _p9k__gitstatus_start_time=$EPOCHREALTIME;; + norepo-sync) _p9k_vcs_status_purge $_p9k__gitstatus_next_dir; unset _p9k__gitstatus_next_dir;; + ok-sync) _p9k_vcs_status_save; unset _p9k__gitstatus_next_dir;; + esac + fi + fi + + if (( _p9k_vcs_index && $+GITSTATUS_DAEMON_PID_POWERLEVEL9K )); then + local _p9k__prompt _p9k__prompt_side=$_p9k_vcs_side _p9k__segment_name=vcs + local -i _p9k__has_upglob _p9k__segment_index=_p9k_vcs_index _p9k__line_index=_p9k_vcs_line_index + _p9k_vcs_render + typeset -g _p9k__vcs=$_p9k__prompt + else + _p9k__refresh_reason=gitstatus + _p9k_set_prompt + _p9k__refresh_reason='' + fi + _p9k_reset_prompt +} + +function _p9k_vcs_gitstatus() { + if [[ $_p9k__refresh_reason == precmd ]]; then + if (( $+_p9k__gitstatus_next_dir )); then + _p9k__gitstatus_next_dir=$_p9k__cwd_a + else + local -F timeout=_POWERLEVEL9K_VCS_MAX_SYNC_LATENCY_SECONDS + if ! _p9k_vcs_status_for_dir; then + _p9k__git_dir=$GIT_DIR + gitstatus_query_p9k_ -d $_p9k__cwd_a -t $timeout -p -c '_p9k_vcs_resume 0' POWERLEVEL9K || return 1 + _p9k_maybe_ignore_git_repo + case $VCS_STATUS_RESULT in + tout) _p9k__gitstatus_next_dir=''; _p9k__gitstatus_start_time=$EPOCHREALTIME; return 0;; + norepo-sync) return 0;; + ok-sync) _p9k_vcs_status_save;; + esac + else + if [[ -n $GIT_DIR ]]; then + [[ $_p9k_git_slow[GIT_DIR:$GIT_DIR] == 1 ]] && timeout=0 + else + local dir=$_p9k__cwd_a + while true; do + case $_p9k_git_slow[$dir] in + "") [[ $dir == / ]] && break; dir=${dir:h};; + 0) break;; + 1) timeout=0; break;; + esac + done + fi + fi + (( _p9k__prompt_idx == 1 )) && timeout=0 + _p9k__git_dir=$GIT_DIR + if (( _p9k_vcs_index && $+GITSTATUS_DAEMON_PID_POWERLEVEL9K )); then + if ! gitstatus_query_p9k_ -d $_p9k__cwd_a -t 0 -c '_p9k_vcs_resume 1' POWERLEVEL9K; then + unset VCS_STATUS_RESULT + return 1 + fi + typeset -gF _p9k__vcs_timeout=timeout + _p9k__gitstatus_next_dir='' + _p9k__gitstatus_start_time=$EPOCHREALTIME + return 0 + fi + if ! gitstatus_query_p9k_ -d $_p9k__cwd_a -t $timeout -c '_p9k_vcs_resume 1' POWERLEVEL9K; then + unset VCS_STATUS_RESULT + return 1 + fi + _p9k_maybe_ignore_git_repo + case $VCS_STATUS_RESULT in + tout) _p9k__gitstatus_next_dir=''; _p9k__gitstatus_start_time=$EPOCHREALTIME;; + norepo-sync) _p9k_vcs_status_purge $_p9k__cwd_a;; + ok-sync) _p9k_vcs_status_save;; + esac + fi + fi + return 0 +} + +################################################################ +# Segment to show VCS information + +prompt_vcs() { + if (( _p9k_vcs_index && $+GITSTATUS_DAEMON_PID_POWERLEVEL9K )); then + _p9k__prompt+='${(e)_p9k__vcs}' + return + fi + + local -a backends=($_POWERLEVEL9K_VCS_BACKENDS) + if (( ${backends[(I)git]} && $+GITSTATUS_DAEMON_PID_POWERLEVEL9K )) && _p9k_vcs_gitstatus; then + _p9k_vcs_render && return + backends=(${backends:#git}) + fi + if (( $#backends )); then + VCS_WORKDIR_DIRTY=false + VCS_WORKDIR_HALF_DIRTY=false + local current_state="" + # Actually invoke vcs_info manually to gather all information. + zstyle ':vcs_info:*' enable ${backends} + vcs_info + local vcs_prompt="${vcs_info_msg_0_}" + if [[ -n "$vcs_prompt" ]]; then + if [[ "$VCS_WORKDIR_DIRTY" == true ]]; then + # $vcs_visual_identifier gets set in +vi-vcs-detect-changes in functions/vcs.zsh, + # as we have there access to vcs_info internal hooks. + current_state='MODIFIED' + else + if [[ "$VCS_WORKDIR_HALF_DIRTY" == true ]]; then + current_state='UNTRACKED' + else + current_state='CLEAN' + fi + fi + _p9k_prompt_segment "${0}_${(U)current_state}" "${__p9k_vcs_states[$current_state]}" "$_p9k_color1" "$vcs_visual_identifier" 0 '' "$vcs_prompt" + fi + fi +} + +################################################################ +# Vi Mode: show editing mode (NORMAL|INSERT|VISUAL) +prompt_vi_mode() { + local -i len=$#_p9k__prompt _p9k__has_upglob + if (( __p9k_sh_glob )); then + if (( $+_POWERLEVEL9K_VI_OVERWRITE_MODE_STRING )); then + if [[ -n $_POWERLEVEL9K_VI_INSERT_MODE_STRING ]]; then + _p9k_prompt_segment $0_INSERT "$_p9k_color1" blue '' 0 '${${${${${${:-$_p9k__keymap.$_p9k__zle_state}:#vicmd.*}:#vivis.*}:#vivli.*}:#*.*overwrite*}}' "$_POWERLEVEL9K_VI_INSERT_MODE_STRING" + fi + _p9k_prompt_segment $0_OVERWRITE "$_p9k_color1" blue '' 0 '${${${${${${:-$_p9k__keymap.$_p9k__zle_state}:#vicmd.*}:#vivis.*}:#vivli.*}:#*.*insert*}}' "$_POWERLEVEL9K_VI_OVERWRITE_MODE_STRING" + else + if [[ -n $_POWERLEVEL9K_VI_INSERT_MODE_STRING ]]; then + _p9k_prompt_segment $0_INSERT "$_p9k_color1" blue '' 0 '${${${${_p9k__keymap:#vicmd}:#vivis}:#vivli}}' "$_POWERLEVEL9K_VI_INSERT_MODE_STRING" + fi + fi + + if (( $+_POWERLEVEL9K_VI_VISUAL_MODE_STRING )); then + _p9k_prompt_segment $0_NORMAL "$_p9k_color1" white '' 0 '${(M)${:-$_p9k__keymap$_p9k__region_active}:#vicmd0}' "$_POWERLEVEL9K_VI_COMMAND_MODE_STRING" + _p9k_prompt_segment $0_VISUAL "$_p9k_color1" white '' 0 '${$((! ${#${${${${:-$_p9k__keymap$_p9k__region_active}:#vicmd1}:#vivis?}:#vivli?}})):#0}' "$_POWERLEVEL9K_VI_VISUAL_MODE_STRING" + else + _p9k_prompt_segment $0_NORMAL "$_p9k_color1" white '' 0 '${$((! ${#${${${_p9k__keymap:#vicmd}:#vivis}:#vivli}})):#0}' "$_POWERLEVEL9K_VI_COMMAND_MODE_STRING" + fi + else + if (( $+_POWERLEVEL9K_VI_OVERWRITE_MODE_STRING )); then + if [[ -n $_POWERLEVEL9K_VI_INSERT_MODE_STRING ]]; then + _p9k_prompt_segment $0_INSERT "$_p9k_color1" blue '' 0 '${${:-$_p9k__keymap.$_p9k__zle_state}:#(vicmd.*|vivis.*|vivli.*|*.*overwrite*)}' "$_POWERLEVEL9K_VI_INSERT_MODE_STRING" + fi + _p9k_prompt_segment $0_OVERWRITE "$_p9k_color1" blue '' 0 '${${:-$_p9k__keymap.$_p9k__zle_state}:#(vicmd.*|vivis.*|vivli.*|*.*insert*)}' "$_POWERLEVEL9K_VI_OVERWRITE_MODE_STRING" + else + if [[ -n $_POWERLEVEL9K_VI_INSERT_MODE_STRING ]]; then + _p9k_prompt_segment $0_INSERT "$_p9k_color1" blue '' 0 '${_p9k__keymap:#(vicmd|vivis|vivli)}' "$_POWERLEVEL9K_VI_INSERT_MODE_STRING" + fi + fi + + if (( $+_POWERLEVEL9K_VI_VISUAL_MODE_STRING )); then + _p9k_prompt_segment $0_NORMAL "$_p9k_color1" white '' 0 '${(M)${:-$_p9k__keymap$_p9k__region_active}:#vicmd0}' "$_POWERLEVEL9K_VI_COMMAND_MODE_STRING" + _p9k_prompt_segment $0_VISUAL "$_p9k_color1" white '' 0 '${(M)${:-$_p9k__keymap$_p9k__region_active}:#(vicmd1|vivis?|vivli?)}' "$_POWERLEVEL9K_VI_VISUAL_MODE_STRING" + else + _p9k_prompt_segment $0_NORMAL "$_p9k_color1" white '' 0 '${(M)_p9k__keymap:#(vicmd|vivis|vivli)}' "$_POWERLEVEL9K_VI_COMMAND_MODE_STRING" + fi + fi + (( _p9k__has_upglob )) || typeset -g "_p9k__segment_val_${_p9k__prompt_side}[_p9k__segment_index]"=$_p9k__prompt[len+1,-1] +} + +instant_prompt_vi_mode() { + if [[ -n $_POWERLEVEL9K_VI_INSERT_MODE_STRING ]]; then + _p9k_prompt_segment prompt_vi_mode_INSERT "$_p9k_color1" blue '' 0 '' "$_POWERLEVEL9K_VI_INSERT_MODE_STRING" + fi +} + +################################################################ +# Virtualenv: current working virtualenv +# More information on virtualenv (Python): +# https://virtualenv.pypa.io/en/latest/ +prompt_virtualenv() { + local msg='' + if (( _POWERLEVEL9K_VIRTUALENV_SHOW_PYTHON_VERSION )) && _p9k_python_version; then + msg="${_p9k__ret//\%/%%} " + fi + local v=${VIRTUAL_ENV:t} + [[ $v == $~_POWERLEVEL9K_VIRTUALENV_GENERIC_NAMES ]] && v=${VIRTUAL_ENV:h:t} + msg+="$_POWERLEVEL9K_VIRTUALENV_LEFT_DELIMITER${v//\%/%%}$_POWERLEVEL9K_VIRTUALENV_RIGHT_DELIMITER" + if (( _POWERLEVEL9K_VIRTUALENV_SHOW_WITH_PYENV )); then + _p9k_prompt_segment "$0" "blue" "$_p9k_color1" 'PYTHON_ICON' 0 '' "$msg" + else + _p9k_prompt_segment "$0" "blue" "$_p9k_color1" 'PYTHON_ICON' 0 '${(M)${#P9K_PYENV_PYTHON_VERSION}:#0}' "$msg" + fi +} + +_p9k_prompt_virtualenv_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$VIRTUAL_ENV' +} + +# _p9k_read_pyenv_like_version_file <filepath> [prefix] +function _p9k_read_pyenv_like_version_file() { + local -a stat + zstat -A stat +mtime -- $1 2>/dev/null || stat=(-1) + local cached=$_p9k__read_pyenv_like_version_file_cache[$1:$2] + if [[ $cached == $stat[1]:* ]]; then + _p9k__ret=${cached#*:} + else + local fd content + { + { sysopen -r -u fd -- $1 && sysread -i $fd -s 1024 content } 2>/dev/null + } always { + [[ -n $fd ]] && exec {fd}>&- + } + local MATCH + local versions=(${(@)${(f)content}/(#m)*/${MATCH[(w)1]#$2}}) + _p9k__ret=${(j.:.)versions} + _p9k__read_pyenv_like_version_file_cache[$1:$2]=$stat[1]:$_p9k__ret + fi + [[ -n $_p9k__ret ]] +} + +function _p9k_pyenv_global_version() { + _p9k_read_pyenv_like_version_file ${PYENV_ROOT:-$HOME/.pyenv}/version python- || _p9k__ret=system +} + +################################################################ +# Segment to display pyenv information +# https://github.com/pyenv/pyenv#choosing-the-python-version +prompt_pyenv() { + unset P9K_PYENV_PYTHON_VERSION + + local v=${(j.:.)${(@)${(s.:.)PYENV_VERSION}#python-}} + if [[ -n $v ]]; then + (( ${_POWERLEVEL9K_PYENV_SOURCES[(I)shell]} )) || return + else + (( ${_POWERLEVEL9K_PYENV_SOURCES[(I)local|global]} )) || return + _p9k__ret= + if [[ $PYENV_DIR != (|.) ]]; then + [[ $PYENV_DIR == /* ]] && local dir=$PYENV_DIR || local dir="$_p9k__cwd_a/$PYENV_DIR" + dir=${dir:A} + if [[ $dir != $_p9k__cwd_a ]]; then + while true; do + if _p9k_read_pyenv_like_version_file $dir/.python-version python-; then + (( ${_POWERLEVEL9K_PYENV_SOURCES[(I)local]} )) || return + break + fi + [[ $dir == / ]] && break + dir=${dir:h} + done + fi + fi + if [[ -z $_p9k__ret ]]; then + _p9k_upglob .python-version + local -i idx=$? + if (( idx )) && _p9k_read_pyenv_like_version_file $_p9k__parent_dirs[idx]/.python-version python-; then + (( ${_POWERLEVEL9K_PYENV_SOURCES[(I)local]} )) || return + else + _p9k__ret= + fi + fi + if [[ -z $_p9k__ret ]]; then + (( _POWERLEVEL9K_PYENV_PROMPT_ALWAYS_SHOW )) || return + (( ${_POWERLEVEL9K_PYENV_SOURCES[(I)global]} )) || return + _p9k_pyenv_global_version + fi + v=$_p9k__ret + fi + + if (( !_POWERLEVEL9K_PYENV_PROMPT_ALWAYS_SHOW )); then + _p9k_pyenv_global_version + [[ $v == $_p9k__ret ]] && return + fi + + if (( !_POWERLEVEL9K_PYENV_SHOW_SYSTEM )); then + [[ $v == system ]] && return + fi + + local versions=${PYENV_ROOT:-$HOME/.pyenv}/versions + versions=${versions:A} + local version=$versions/$v + version=${version:A} + if [[ $version == (#b)$versions/([^/]##)* ]]; then + typeset -g P9K_PYENV_PYTHON_VERSION=$match[1] + fi + + _p9k_prompt_segment "$0" "blue" "$_p9k_color1" 'PYTHON_ICON' 0 '' "${v//\%/%%}" +} + +_p9k_prompt_pyenv_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${commands[pyenv]:-${${+functions[pyenv]}:#0}}' +} + +function _p9k_goenv_global_version() { + _p9k_read_pyenv_like_version_file ${GOENV_ROOT:-$HOME/.goenv}/version go- || _p9k__ret=system +} + +################################################################ +# Segment to display goenv information: https://github.com/syndbg/goenv +prompt_goenv() { + local v=${(j.:.)${(@)${(s.:.)GOENV_VERSION}#go-}} + if [[ -n $v ]]; then + (( ${_POWERLEVEL9K_GOENV_SOURCES[(I)shell]} )) || return + else + (( ${_POWERLEVEL9K_GOENV_SOURCES[(I)local|global]} )) || return + _p9k__ret= + if [[ $GOENV_DIR != (|.) ]]; then + [[ $GOENV_DIR == /* ]] && local dir=$GOENV_DIR || local dir="$_p9k__cwd_a/$GOENV_DIR" + dir=${dir:A} + if [[ $dir != $_p9k__cwd_a ]]; then + while true; do + if _p9k_read_pyenv_like_version_file $dir/.go-version go-; then + (( ${_POWERLEVEL9K_GOENV_SOURCES[(I)local]} )) || return + break + fi + [[ $dir == / ]] && break + dir=${dir:h} + done + fi + fi + if [[ -z $_p9k__ret ]]; then + _p9k_upglob .go-version + local -i idx=$? + if (( idx )) && _p9k_read_pyenv_like_version_file $_p9k__parent_dirs[idx]/.go-version go-; then + (( ${_POWERLEVEL9K_GOENV_SOURCES[(I)local]} )) || return + else + _p9k__ret= + fi + fi + if [[ -z $_p9k__ret ]]; then + (( _POWERLEVEL9K_GOENV_PROMPT_ALWAYS_SHOW )) || return + (( ${_POWERLEVEL9K_GOENV_SOURCES[(I)global]} )) || return + _p9k_goenv_global_version + fi + v=$_p9k__ret + fi + + if (( !_POWERLEVEL9K_GOENV_PROMPT_ALWAYS_SHOW )); then + _p9k_goenv_global_version + [[ $v == $_p9k__ret ]] && return + fi + + if (( !_POWERLEVEL9K_GOENV_SHOW_SYSTEM )); then + [[ $v == system ]] && return + fi + + _p9k_prompt_segment "$0" "blue" "$_p9k_color1" 'GO_ICON' 0 '' "${v//\%/%%}" +} + +_p9k_prompt_goenv_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${commands[goenv]:-${${+functions[goenv]}:#0}}' +} + +################################################################ +# Display openfoam information +prompt_openfoam() { + if [[ -z "$WM_FORK" ]] ; then + _p9k_prompt_segment "$0" "yellow" "$_p9k_color1" '' 0 '' "OF: ${${WM_PROJECT_VERSION:t}//\%/%%}" + else + _p9k_prompt_segment "$0" "yellow" "$_p9k_color1" '' 0 '' "F-X: ${${WM_PROJECT_VERSION:t}//\%/%%}" + fi +} + +_p9k_prompt_openfoam_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$WM_PROJECT_VERSION' +} + +################################################################ +# Segment to display Swift version +prompt_swift_version() { + _p9k_cached_cmd 0 swift --version || return + [[ $_p9k__ret == (#b)[^[:digit:]]#([[:digit:].]##)* ]] || return + _p9k_prompt_segment "$0" "magenta" "white" 'SWIFT_ICON' 0 '' "${match[1]//\%/%%}" +} + +_p9k_prompt_swift_version_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$commands[swift]' +} + +################################################################ +# dir_writable: Display information about the user's permission to write in the current directory +prompt_dir_writable() { + if [[ ! -w "$_p9k__cwd_a" ]]; then + _p9k_prompt_segment "$0_FORBIDDEN" "red" "yellow1" 'LOCK_ICON' 0 '' '' + fi +} + +instant_prompt_dir_writable() { prompt_dir_writable; } + +################################################################ +# Kubernetes Current Context/Namespace +prompt_kubecontext() { + if ! _p9k_cache_stat_get $0 ${(s.:.)${KUBECONFIG:-$HOME/.kube/config}}; then + local name namespace cluster user cloud_name cloud_account cloud_zone cloud_cluster text state + () { + local cfg && cfg=(${(f)"$(kubectl config view -o=yaml 2>/dev/null)"}) || return + local ctx=(${(@M)cfg:#current-context: [^\"\'\|\>]*}) + (( $#ctx == 1 )) || return + name=${ctx[1]#current-context: } + local -i pos=${cfg[(i)contexts:]} + (( pos <= $#cfg )) || return + shift $pos cfg + pos=${cfg[(i) name: $name]} + (( pos <= $#cfg )) || return + (( --pos )) + for ((; pos > 0; --pos)); do + local line=$cfg[pos] + if [[ $line == '- context:' ]]; then + return 0 + elif [[ $line == (#b)' cluster: '([^\"\'\|\>]*) ]]; then + cluster=$match[1] + elif [[ $line == (#b)' namespace: '([^\"\'\|\>]*) ]]; then + namespace=$match[1] + elif [[ $line == (#b)' user: '([^\"\'\|\>]*) ]]; then + user=$match[1] + fi + done + } + if [[ -n $name ]]; then + : ${namespace:=default} + # gke_my-account_us-east1-a_cluster-01 + # gke_my-account_us-east1_cluster-01 + if [[ $cluster == (#b)gke_(?*)_(asia|australia|europe|northamerica|southamerica|us)-([a-z]##<->)(-[a-z]|)_(?*) ]]; then + cloud_name=gke + cloud_account=$match[1] + cloud_zone=$match[2]-$match[3]-$match[4] + cloud_cluster=$match[5] + if (( ${_POWERLEVEL9K_KUBECONTEXT_SHORTEN[(I)gke]} )); then + text=$cloud_cluster + fi + # arn:aws:eks:us-east-1:123456789012:cluster/cluster-01 + elif [[ $cluster == (#b)arn:aws:eks:([[:alnum:]-]##):([[:digit:]]##):cluster/(?*) ]]; then + cloud_name=eks + cloud_zone=$match[1] + cloud_account=$match[2] + cloud_cluster=$match[3] + if (( ${_POWERLEVEL9K_KUBECONTEXT_SHORTEN[(I)eks]} )); then + text=$cloud_cluster + fi + fi + if [[ -z $text ]]; then + text=$name + if [[ $_POWERLEVEL9K_KUBECONTEXT_SHOW_DEFAULT_NAMESPACE == 1 || $namespace != (default|$name) ]]; then + text+="/$namespace" + fi + fi + local pat class + for pat class in "${_POWERLEVEL9K_KUBECONTEXT_CLASSES[@]}"; do + if [[ $text == ${~pat} ]]; then + [[ -n $class ]] && state=_${(U)class} + break + fi + done + fi + _p9k_cache_stat_set "$name" "$namespace" "$cluster" "$user" "$cloud_name" "$cloud_account" "$cloud_zone" "$cloud_cluster" "$text" "$state" + fi + + typeset -g P9K_KUBECONTEXT_NAME=$_p9k__cache_val[1] + typeset -g P9K_KUBECONTEXT_NAMESPACE=$_p9k__cache_val[2] + typeset -g P9K_KUBECONTEXT_CLUSTER=$_p9k__cache_val[3] + typeset -g P9K_KUBECONTEXT_USER=$_p9k__cache_val[4] + typeset -g P9K_KUBECONTEXT_CLOUD_NAME=$_p9k__cache_val[5] + typeset -g P9K_KUBECONTEXT_CLOUD_ACCOUNT=$_p9k__cache_val[6] + typeset -g P9K_KUBECONTEXT_CLOUD_ZONE=$_p9k__cache_val[7] + typeset -g P9K_KUBECONTEXT_CLOUD_CLUSTER=$_p9k__cache_val[8] + [[ -n $_p9k__cache_val[9] ]] || return + _p9k_prompt_segment $0$_p9k__cache_val[10] magenta white KUBERNETES_ICON 0 '' "${_p9k__cache_val[9]//\%/%%}" +} + +_p9k_prompt_kubecontext_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$commands[kubectl]' +} + +################################################################ +# Dropbox status +prompt_dropbox() { + # The first column is just the directory, so cut it + local dropbox_status="$(dropbox-cli filestatus . | cut -d\ -f2-)" + + # Only show if the folder is tracked and dropbox is running + if [[ "$dropbox_status" != 'unwatched' && "$dropbox_status" != "isn't running!" ]]; then + # If "up to date", only show the icon + if [[ "$dropbox_status" =~ 'up to date' ]]; then + dropbox_status="" + fi + + _p9k_prompt_segment "$0" "white" "blue" "DROPBOX_ICON" 0 '' "${dropbox_status//\%/%%}" + fi +} + +_p9k_prompt_dropbox_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$commands[dropbox-cli]' +} + +# print Java version number +prompt_java_version() { + if (( _POWERLEVEL9K_JAVA_VERSION_PROJECT_ONLY )); then + _p9k_upglob 'pom.xml|build.gradle.kts|build.sbt|deps.edn|project.clj|build.boot|*.(java|class|jar|gradle|clj|cljc)' && return + fi + + local java=$commands[java] + if ! _p9k_cache_stat_get $0 $java ${JAVA_HOME:+$JAVA_HOME/release}; then + local v + v="$(java -fullversion 2>&1)" || v= + v=${${v#*\"}%\"*} + (( _POWERLEVEL9K_JAVA_VERSION_FULL )) || v=${v%%-*} + _p9k_cache_stat_set "${v//\%/%%}" + fi + + [[ -n $_p9k__cache_val[1] ]] || return + _p9k_prompt_segment "$0" "red" "white" "JAVA_ICON" 0 '' $_p9k__cache_val[1] +} + +_p9k_prompt_java_version_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$commands[java]' +} + +prompt_azure() { + local cfg=${AZURE_CONFIG_DIR:-$HOME/.azure}/azureProfile.json + if ! _p9k_cache_stat_get $0 $cfg; then + local name + if (( $+commands[jq] )) && name="$(jq -r '[.subscriptions[]|select(.isDefault==true)|.name][]|strings' $cfg 2>/dev/null)"; then + name=${name%%$'\n'*} + elif ! name="$(az account show --query name --output tsv 2>/dev/null)"; then + name= + fi + _p9k_cache_stat_set "$name" + fi + [[ -n $_p9k__cache_val[1] ]] || return + _p9k_prompt_segment "$0" "blue" "white" "AZURE_ICON" 0 '' "${_p9k__cache_val[1]//\%/%%}" +} + +_p9k_prompt_azure_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$commands[az]' +} + +prompt_gcloud() { + local -i len=$#_p9k__prompt _p9k__has_upglob + _p9k_prompt_segment \ + $0_PARTIAL blue white GCLOUD_ICON 1 \ + '${${(M)${#P9K_GCLOUD_PROJECT_NAME}:#0}:+$P9K_GCLOUD_ACCOUNT$P9K_GCLOUD_PROJECT_ID}' \ + '${P9K_GCLOUD_ACCOUNT//\%/%%}:${P9K_GCLOUD_PROJECT_ID//\%/%%}' + _p9k_prompt_segment \ + $0_COMPLETE blue white GCLOUD_ICON 1 \ + '$P9K_GCLOUD_PROJECT_NAME' \ + '${P9K_GCLOUD_ACCOUNT//\%/%%}:${P9K_GCLOUD_PROJECT_ID//\%/%%}' + (( _p9k__has_upglob )) || typeset -g "_p9k__segment_val_${_p9k__prompt_side}[_p9k__segment_index]"=$_p9k__prompt[len+1,-1] +} + +_p9k_gcloud_prefetch() { + # P9K_GCLOUD_PROJECT is deprecated; it's always equal to P9K_GCLOUD_PROJECT_ID + unset P9K_GCLOUD_CONFIGURATION P9K_GCLOUD_ACCOUNT P9K_GCLOUD_PROJECT P9K_GCLOUD_PROJECT_ID P9K_GCLOUD_PROJECT_NAME + (( $+commands[gcloud] )) || return + _p9k_read_word ~/.config/gcloud/active_config || return + P9K_GCLOUD_CONFIGURATION=$_p9k__ret + if ! _p9k_cache_stat_get $0 ~/.config/gcloud/configurations/config_$P9K_GCLOUD_CONFIGURATION; then + local pair account project_id + pair="$(gcloud config configurations describe $P9K_GCLOUD_CONFIGURATION \ + --format=$'value[separator="\1"](properties.core.account,properties.core.project)')" + (( ! $? )) && IFS=$'\1' read account project_id <<<$pair + _p9k_cache_stat_set "$account" "$project_id" + fi + if [[ -n $_p9k__cache_val[1] ]]; then + P9K_GCLOUD_ACCOUNT=$_p9k__cache_val[1] + fi + if [[ -n $_p9k__cache_val[2] ]]; then + P9K_GCLOUD_PROJECT_ID=$_p9k__cache_val[2] + P9K_GCLOUD_PROJECT=$P9K_GCLOUD_PROJECT_ID # deprecated parameter; set for backward compatibility + fi + if [[ $P9K_GCLOUD_CONFIGURATION == $_p9k_gcloud_configuration && + $P9K_GCLOUD_ACCOUNT == $_p9k_gcloud_account && + $P9K_GCLOUD_PROJECT_ID == $_p9k_gcloud_project_id ]]; then + [[ -n $_p9k_gcloud_project_name ]] && P9K_GCLOUD_PROJECT_NAME=$_p9k_gcloud_project_name + if (( _POWERLEVEL9K_GCLOUD_REFRESH_PROJECT_NAME_SECONDS < 0 || + _p9k__gcloud_last_fetch_ts + _POWERLEVEL9K_GCLOUD_REFRESH_PROJECT_NAME_SECONDS > EPOCHREALTIME )); then + return + fi + else + _p9k_gcloud_configuration=$P9K_GCLOUD_CONFIGURATION + _p9k_gcloud_account=$P9K_GCLOUD_ACCOUNT + _p9k_gcloud_project_id=$P9K_GCLOUD_PROJECT_ID + _p9k_gcloud_project_name= + _p9k__state_dump_scheduled=1 + fi + [[ -n $P9K_GCLOUD_CONFIGURATION && -n $P9K_GCLOUD_ACCOUNT && -n $P9K_GCLOUD_PROJECT_ID ]] || return + _p9k__gcloud_last_fetch_ts=EPOCHREALTIME + _p9k_worker_invoke gcloud "_p9k_prompt_gcloud_compute ${(q)commands[gcloud]} ${(q)P9K_GCLOUD_CONFIGURATION} ${(q)P9K_GCLOUD_ACCOUNT} ${(q)P9K_GCLOUD_PROJECT_ID}" +} + +_p9k_prompt_gcloud_init() { + _p9k__async_segments_compute+=_p9k_gcloud_prefetch + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$commands[gcloud]' +} + +_p9k_prompt_gcloud_compute() { + local gcloud=$1 + P9K_GCLOUD_CONFIGURATION=$2 + P9K_GCLOUD_ACCOUNT=$3 + P9K_GCLOUD_PROJECT_ID=$4 + _p9k_worker_async "_p9k_prompt_gcloud_async ${(q)gcloud}" _p9k_prompt_gcloud_sync +} + +_p9k_prompt_gcloud_async() { + local gcloud=$1 + $gcloud projects describe $P9K_GCLOUD_PROJECT_ID --configuration=$P9K_GCLOUD_CONFIGURATION \ + --account=$P9K_GCLOUD_ACCOUNT --format='value(name)' +} + +_p9k_prompt_gcloud_sync() { + _p9k_worker_reply "_p9k_prompt_gcloud_update ${(q)P9K_GCLOUD_CONFIGURATION} ${(q)P9K_GCLOUD_ACCOUNT} ${(q)P9K_GCLOUD_PROJECT_ID} ${(q)REPLY%$'\n'}" +} + +_p9k_prompt_gcloud_update() { + [[ $1 == $P9K_GCLOUD_CONFIGURATION && + $2 == $P9K_GCLOUD_ACCOUNT && + $3 == $P9K_GCLOUD_PROJECT_ID && + $4 != $P9K_GCLOUD_PROJECT_NAME ]] || return + [[ -n $4 ]] && P9K_GCLOUD_PROJECT_NAME=$4 || unset P9K_GCLOUD_PROJECT_NAME + _p9k_gcloud_project_name=$P9K_GCLOUD_PROJECT_NAME + _p9k__state_dump_scheduled=1 + reset=1 +} + +prompt_google_app_cred() { + unset P9K_GOOGLE_APP_CRED_{TYPE,PROJECT_ID,CLIENT_EMAIL} + + if ! _p9k_cache_stat_get $0 $GOOGLE_APPLICATION_CREDENTIALS; then + local -a lines + local q='[.type//"", .project_id//"", .client_email//"", 0][]' + if lines=("${(@f)$(jq -r $q <$GOOGLE_APPLICATION_CREDENTIALS 2>/dev/null)}") && (( $#lines == 4 )); then + local text="${(j.:.)lines[1,-2]}" + local pat class state + for pat class in "${_POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES[@]}"; do + if [[ $text == ${~pat} ]]; then + [[ -n $class ]] && state=_${(U)class} + break + fi + done + _p9k_cache_stat_set 1 "${(@)lines[1,-2]}" "$text" "$state" + else + _p9k_cache_stat_set 0 + fi + fi + + (( _p9k__cache_val[1] )) || return + P9K_GOOGLE_APP_CRED_TYPE=$_p9k__cache_val[2] + P9K_GOOGLE_APP_CRED_PROJECT_ID=$_p9k__cache_val[3] + P9K_GOOGLE_APP_CRED_CLIENT_EMAIL=$_p9k__cache_val[4] + _p9k_prompt_segment "$0$_p9k__cache_val[6]" "blue" "white" "GCLOUD_ICON" 0 '' "$_p9k__cache_val[5]" +} + +_p9k_prompt_google_app_cred_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${GOOGLE_APPLICATION_CREDENTIALS:+$commands[jq]}' +} + +typeset -gra __p9k_nordvpn_tag=( + P9K_NORDVPN_STATUS + P9K_NORDVPN_TECHNOLOGY + P9K_NORDVPN_PROTOCOL + P9K_NORDVPN_IP_ADDRESS + P9K_NORDVPN_SERVER + P9K_NORDVPN_COUNTRY + P9K_NORDVPN_CITY +) + +function _p9k_fetch_nordvpn_status() { + setopt err_return + local REPLY + zsocket /run/nordvpnd.sock + local -i fd=$REPLY + { + >&$fd echo -nE - $'PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n\0\0\0\4\1\0\0\0\0\0\0N\1\4\0\0\0\1\203\206E\221bA\226\223\325\\k\337\31i=LnH\323j?A\223\266\243y\270\303\fYmLT{$\357]R.\203\223\257_\213\35u\320b\r&=LMedz\212\232\312\310\264\307`+\210K\203@\2te\206M\2035\5\261\37\0\0\5\0\1\0\0\0\1\0\0\0\0\0' + local tag len val + local -i n + { + IFS='' read -t 0.25 -r tag + tag=$'\n' + while true; do + tag=$((#tag)) + (( (tag >>= 3) && tag <= $#__p9k_nordvpn_tag )) || break + tag=$__p9k_nordvpn_tag[tag] + [[ -t $fd ]] || true # https://www.zsh.org/mla/workers/2020/msg00207.html + sysread -s 1 -t 0.25 len + len=$((#len)) + val= + while true; do + (( len )) || break + [[ -t $fd ]] || true # https://www.zsh.org/mla/workers/2020/msg00207.html + sysread -c n -s $len -t 0.25 'val[$#val+1]' + len+=-n + done + typeset -g $tag=$val + [[ -t $fd ]] || true # https://www.zsh.org/mla/workers/2020/msg00207.html + sysread -s 1 -t 0.25 tag + done + } <&$fd + } always { + exec {fd}>&- + } +} + +# Shows the state of NordVPN connection. Works only on Linux. Can be in the following 5 states. +# +# MISSING: NordVPN is not installed or nordvpnd is not running. By default the segment is not +# shown in this state. To make it visible, override POWERLEVEL9K_NORDVPN_MISSING_CONTENT_EXPANSION +# and/or POWERLEVEL9K_NORDVPN_MISSING_VISUAL_IDENTIFIER_EXPANSION. +# +# # Display this icon when NordVPN is not installed or nordvpnd is not running +# POWERLEVEL9K_NORDVPN_MISSING_VISUAL_IDENTIFIER_EXPANSION='⭐' +# +# CONNECTED: NordVPN is connected. By default shows NORDVPN_ICON as icon and country code as +# content. In addition, the following variables are set for the use by +# POWERLEVEL9K_NORDVPN_CONNECTED_VISUAL_IDENTIFIER_EXPANSION and +# POWERLEVEL9K_NORDVPN_CONNECTED_CONTENT_EXPANSION: +# +# - P9K_NORDVPN_STATUS +# - P9K_NORDVPN_PROTOCOL +# - P9K_NORDVPN_TECHNOLOGY +# - P9K_NORDVPN_IP_ADDRESS +# - P9K_NORDVPN_SERVER +# - P9K_NORDVPN_COUNTRY +# - P9K_NORDVPN_CITY +# - P9K_NORDVPN_COUNTRY_CODE +# +# The last variable is trivially derived from P9K_NORDVPN_SERVER. The rest correspond to the output +# lines of `nordvpn status` command. Example of using these variables: +# +# # Display the name of the city where VPN servers are located when connected to NordVPN. +# POWERLEVEL9K_NORDVPN_CONNECTED_CONTENT_EXPANSION='${P9K_NORDVPN_CITY}' +# +# DISCONNECTED, CONNECTING, DISCONNECTING: NordVPN is disconnected/connecting/disconnecting. By +# default shows NORDVPN_ICON as icon and FAIL_ICON as content. In state CONNECTING the same +# P9K_NORDVPN_* variables are set as in CONNECTED. In states DISCONNECTED and DISCONNECTING only +# P9K_NORDVPN_STATUS is set. Example customizations: +# +# # Hide NordVPN segment when disconnected (segments with no icon and no content are not shown). +# POWERLEVEL9K_NORDVPN_DISCONNECTED_CONTENT_EXPANSION= +# POWERLEVEL9K_NORDVPN_DISCONNECTED_VISUAL_IDENTIFIER_EXPANSION= +# +# # When NordVPN is connecting, show country code on cyan background. +# POWERLEVEL9K_NORDVPN_CONNECTING_CONTENT_EXPANSION='${P9K_NORDVPN_COUNTRY_CODE}' +# POWERLEVEL9K_NORDVPN_CONNECTING_BACKGROUND=cyan +function prompt_nordvpn() { + unset $__p9k_nordvpn_tag P9K_NORDVPN_COUNTRY_CODE + if [[ -e /run/nordvpnd.sock ]]; then + _p9k_fetch_nordvpn_status 2>/dev/null + if [[ $P9K_NORDVPN_SERVER == (#b)([[:alpha:]]##)[[:digit:]]##.nordvpn.com ]]; then + typeset -g P9K_NORDVPN_COUNTRY_CODE=${(U)match[1]} + fi + fi + case $P9K_NORDVPN_STATUS in + Connected) + _p9k_prompt_segment $0_CONNECTED blue white NORDVPN_ICON 0 '' "$P9K_NORDVPN_COUNTRY_CODE";; + Disconnected|Connecting|Disconnecting) + local state=${(U)P9K_NORDVPN_STATUS} + _p9k_get_icon $0_$state FAIL_ICON + _p9k_prompt_segment $0_$state yellow white NORDVPN_ICON 0 '' "$_p9k__ret";; + *) + _p9k_prompt_segment $0_MISSING blue white '' 0 '' '';; + esac +} + +_p9k_prompt_nordvpn_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$commands[nordvpn]' +} + +function prompt_ranger() { + _p9k_prompt_segment $0 $_p9k_color1 yellow RANGER_ICON 0 '' $RANGER_LEVEL +} + +_p9k_prompt_ranger_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$RANGER_LEVEL' +} + +function instant_prompt_ranger() { + _p9k_prompt_segment prompt_ranger $_p9k_color1 yellow RANGER_ICON 1 '$RANGER_LEVEL' '$RANGER_LEVEL' +} + +function prompt_midnight_commander() { + local -i len=$#_p9k__prompt _p9k__has_upglob + _p9k_prompt_segment $0 $_p9k_color1 yellow MIDNIGHT_COMMANDER_ICON 0 '' '' + (( _p9k__has_upglob )) || typeset -g "_p9k__segment_val_${_p9k__prompt_side}[_p9k__segment_index]"=$_p9k__prompt[len+1,-1] +} + +_p9k_prompt_midnight_commander_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$MC_TMPDIR' +} + +function instant_prompt_midnight_commander() { + _p9k_prompt_segment prompt_midnight_commander $_p9k_color1 yellow MIDNIGHT_COMMANDER_ICON 0 '$MC_TMPDIR' '' +} + +function prompt_nnn() { + _p9k_prompt_segment $0 6 $_p9k_color1 NNN_ICON 0 '' $NNNLVL +} + +_p9k_prompt_nnn_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${NNNLVL:#0}' +} + +function instant_prompt_nnn() { + _p9k_prompt_segment prompt_nnn 6 $_p9k_color1 NNN_ICON 1 '${NNNLVL:#0}' '$NNNLVL' +} + +function prompt_vim_shell() { + local -i len=$#_p9k__prompt _p9k__has_upglob + _p9k_prompt_segment $0 green $_p9k_color1 VIM_ICON 0 '' '' + (( _p9k__has_upglob )) || typeset -g "_p9k__segment_val_${_p9k__prompt_side}[_p9k__segment_index]"=$_p9k__prompt[len+1,-1] +} + +_p9k_prompt_vim_shell_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$VIMRUNTIME' +} + +function instant_prompt_vim_shell() { + _p9k_prompt_segment prompt_vim_shell green $_p9k_color1 VIM_ICON 0 '$VIMRUNTIME' '' +} + +function prompt_nix_shell() { + _p9k_prompt_segment $0 4 $_p9k_color1 NIX_SHELL_ICON 0 '' "${(M)IN_NIX_SHELL:#(pure|impure)}" +} + +_p9k_prompt_nix_shell_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${IN_NIX_SHELL:#0}' +} + +function instant_prompt_nix_shell() { + _p9k_prompt_segment prompt_nix_shell 4 $_p9k_color1 NIX_SHELL_ICON 1 '${IN_NIX_SHELL:#0}' '${(M)IN_NIX_SHELL:#(pure|impure)}' +} + +function prompt_terraform() { + local ws=$TF_WORKSPACE + if [[ -z $TF_WORKSPACE ]]; then + _p9k_read_word ${${TF_DATA_DIR:-.terraform}:A}/environment && ws=$_p9k__ret + fi + [[ $ws == (|default) ]] && return + local pat class + for pat class in "${_POWERLEVEL9K_TERRAFORM_CLASSES[@]}"; do + if [[ $ws == ${~pat} ]]; then + [[ -n $class ]] && state=_${(U)class} + break + fi + done + _p9k_prompt_segment "$0$state" $_p9k_color1 blue TERRAFORM_ICON 0 '' $ws +} + +_p9k_prompt_terraform_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$commands[terraform]' +} + +function prompt_proxy() { + local -U p=( + $all_proxy $http_proxy $https_proxy $ftp_proxy + $ALL_PROXY $HTTP_PROXY $HTTPS_PROXY $FTP_PROXY) + p=(${(@)${(@)${(@)p#*://}##*@}%%/*}) + (( $#p == 1 )) || p=("") + _p9k_prompt_segment $0 $_p9k_color1 blue PROXY_ICON 0 '' "$p[1]" +} + +_p9k_prompt_proxy_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$all_proxy$http_proxy$https_proxy$ftp_proxy$ALL_PROXY$HTTP_PROXY$HTTPS_PROXY$FTP_PROXY' +} + +function prompt_direnv() { + local -i len=$#_p9k__prompt _p9k__has_upglob + _p9k_prompt_segment $0 $_p9k_color1 yellow DIRENV_ICON 0 '$DIRENV_DIR' '' + (( _p9k__has_upglob )) || typeset -g "_p9k__segment_val_${_p9k__prompt_side}[_p9k__segment_index]"=$_p9k__prompt[len+1,-1] +} + +_p9k_prompt_direnv_init() { + # DIRENV_DIR is set in a precmd hook. If our hook isn't the last, DIRENV_DIR might + # still get set before prompt is expanded. + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${DIRENV_DIR:-${precmd_functions[-1]:#_p9k_precmd}}' +} + +function instant_prompt_direnv() { + if [[ -n $DIRENV_DIR && $precmd_functions[-1] == _p9k_precmd ]]; then + _p9k_prompt_segment prompt_direnv $_p9k_color1 yellow DIRENV_ICON 0 '' '' + fi +} + +function _p9k_timewarrior_clear() { + [[ -z $_p9k_timewarrior_dir ]] && return + _p9k_timewarrior_dir= + _p9k_timewarrior_dir_mtime=0 + _p9k_timewarrior_file_mtime=0 + _p9k_timewarrior_file_name= + unset _p9k_timewarrior_tags + _p9k__state_dump_scheduled=1 +} + +function prompt_timewarrior() { + local -a stat + local dir=${TIMEWARRIORDB:-~/.timewarrior}/data + [[ $dir == $_p9k_timewarrior_dir ]] || _p9k_timewarrior_clear + if [[ -n $_p9k_timewarrior_file_name ]]; then + zstat -A stat +mtime -- $dir $_p9k_timewarrior_file_name 2>/dev/null || stat=() + if [[ $stat[1] == $_p9k_timewarrior_dir_mtime && $stat[2] == $_p9k_timewarrior_file_mtime ]]; then + if (( $+_p9k_timewarrior_tags )); then + _p9k_prompt_segment $0 grey 255 TIMEWARRIOR_ICON 0 '' "${_p9k_timewarrior_tags//\%/%%}" + fi + return + fi + fi + if [[ ! -d $dir ]]; then + _p9k_timewarrior_clear + return + fi + _p9k_timewarrior_dir=$dir + if [[ $stat[1] != $_p9k_timewarrior_dir_mtime ]]; then + local -a files=($dir/<->-<->.data(.N)) + if (( ! $#files )); then + if (( $#stat )) || zstat -A stat +mtime -- $dir 2>/dev/null; then + _p9k_timewarrior_dir_mtime=$stat[1] + _p9k_timewarrior_file_mtime=$stat[1] + _p9k_timewarrior_file_name=$dir # sic + unset _p9k_timewarrior_tags + _p9k__state_dump_scheduled=1 + else + _p9k_timewarrior_clear + fi + return + fi + _p9k_timewarrior_file_name=${${(AO)files}[1]} + fi + if ! zstat -A stat +mtime -- $dir $_p9k_timewarrior_file_name 2>/dev/null; then + _p9k_timewarrior_clear + return + fi + _p9k_timewarrior_dir_mtime=$stat[1] + _p9k_timewarrior_file_mtime=$stat[2] + { local tail=${${(Af)"$(<$_p9k_timewarrior_file_name)"}[-1]} } 2>/dev/null + if [[ $tail == (#b)'inc '[^\ ]##(|\ #\#(*)) ]]; then + _p9k_timewarrior_tags=${${match[2]## #}%% #} + _p9k_prompt_segment $0 grey 255 TIMEWARRIOR_ICON 0 '' "${_p9k_timewarrior_tags//\%/%%}" + else + unset _p9k_timewarrior_tags + fi + _p9k__state_dump_scheduled=1 +} + +function _p9k_prompt_timewarrior_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$commands[timew]' +} + +function _p9k_taskwarrior_check_meta() { + [[ -n $_p9k_taskwarrior_meta_sig ]] || return + [[ -z $^_p9k_taskwarrior_meta_non_files(#qN) ]] || return + local -a stat + if (( $#_p9k_taskwarrior_meta_files )); then + zstat -A stat +mtime -- $_p9k_taskwarrior_meta_files 2>/dev/null || return + fi + [[ $_p9k_taskwarrior_meta_sig == ${(pj:\0:)stat}$'\0'$TASKRC$'\0'$TASKDATA ]] || return +} + +function _p9k_taskwarrior_init_meta() { + local last_sig=$_p9k_taskwarrior_meta_sig + { + local cfg + cfg="$(task show data.location </dev/null 2>/dev/null)" || return + local lines=(${(@M)${(f)cfg}:#data.location[[:space:]]##[^[:space:]]*}) + (( $#lines == 1 )) || return + local dir=${lines[1]##data.location[[:space:]]#} + : ${dir::=$~dir} # `task` can give us path with `~`` in it; expand it + + local -a stat files=(${TASKRC:-~/.taskrc}) + _p9k_taskwarrior_meta_files=($^files(N)) + _p9k_taskwarrior_meta_non_files=(${files:|_p9k_taskwarrior_meta_files}) + if (( $#_p9k_taskwarrior_meta_files )); then + zstat -A stat +mtime -- $_p9k_taskwarrior_meta_files 2>/dev/null || stat=(-1) + fi + _p9k_taskwarrior_meta_sig=${(pj:\0:)stat}$'\0'$TASKRC$'\0'$TASKDATA + _p9k_taskwarrior_data_dir=$dir + } always { + if (( $? == 0 )); then + _p9k__state_dump_scheduled=1 + return + fi + [[ -n $last_sig ]] && _p9k__state_dump_scheduled=1 + _p9k_taskwarrior_meta_files=() + _p9k_taskwarrior_meta_non_files=() + _p9k_taskwarrior_meta_sig= + _p9k_taskwarrior_data_dir= + _p9k__taskwarrior_functional= + } +} + +function _p9k_taskwarrior_check_data() { + [[ -n $_p9k_taskwarrior_data_sig ]] || return + [[ -z $^_p9k_taskwarrior_data_non_files(#qN) ]] || return + local -a stat + if (( $#_p9k_taskwarrior_data_files )); then + zstat -A stat +mtime -- $_p9k_taskwarrior_data_files 2>/dev/null || return + fi + [[ $_p9k_taskwarrior_data_sig == ${(pj:\0:)stat}$'\0'$TASKRC$'\0'$TASKDATA ]] || return +} + +function _p9k_taskwarrior_init_data() { + local -a stat files=($_p9k_taskwarrior_data_dir/{pending,completed}.data) + _p9k_taskwarrior_data_files=($^files(N)) + _p9k_taskwarrior_data_non_files=(${files:|_p9k_taskwarrior_data_files}) + if (( $#_p9k_taskwarrior_data_files )); then + zstat -A stat +mtime -- $_p9k_taskwarrior_data_files 2>/dev/null || stat=(-1) + _p9k_taskwarrior_data_sig=${(pj:\0:)stat}$'\0' + else + _p9k_taskwarrior_data_sig= + fi + + _p9k_taskwarrior_data_files+=($_p9k_taskwarrior_meta_files) + _p9k_taskwarrior_data_non_files+=($_p9k_taskwarrior_meta_non_files) + _p9k_taskwarrior_data_sig+=$_p9k_taskwarrior_meta_sig + + local name val + for name in PENDING OVERDUE; do + val="$(task +$name count </dev/null 2>/dev/null)" || continue + [[ $val == <1-> ]] || continue + _p9k_taskwarrior_counters[$name]=$val + done + + _p9k__state_dump_scheduled=1 +} + +function prompt_taskwarrior() { + unset P9K_TASKWARRIOR_PENDING_COUNT P9K_TASKWARRIOR_OVERDUE_COUNT + if ! _p9k_taskwarrior_check_data; then + _p9k_taskwarrior_data_files=() + _p9k_taskwarrior_data_non_files=() + _p9k_taskwarrior_data_sig= + _p9k_taskwarrior_counters=() + _p9k_taskwarrior_check_meta || _p9k_taskwarrior_init_meta || return + _p9k_taskwarrior_init_data + fi + (( $#_p9k_taskwarrior_counters )) || return + local text c=$_p9k_taskwarrior_counters[OVERDUE] + if [[ -n $c ]]; then + typeset -g P9K_TASKWARRIOR_OVERDUE_COUNT=$c + text+="!$c" + fi + c=$_p9k_taskwarrior_counters[PENDING] + if [[ -n $c ]]; then + typeset -g P9K_TASKWARRIOR_PENDING_COUNT=$c + [[ -n $text ]] && text+='/' + text+=$c + fi + [[ -n $text ]] || return + _p9k_prompt_segment $0 6 $_p9k_color1 TASKWARRIOR_ICON 0 '' $text +} + +function _p9k_prompt_taskwarrior_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${commands[task]:+$_p9k__taskwarrior_functional}' +} + +prompt_wifi() { + local -i len=$#_p9k__prompt _p9k__has_upglob + _p9k_prompt_segment $0 green $_p9k_color1 WIFI_ICON 1 '$_p9k__wifi_on' '$P9K_WIFI_LAST_TX_RATE Mbps' + (( _p9k__has_upglob )) || typeset -g "_p9k__segment_val_${_p9k__prompt_side}[_p9k__segment_index]"=$_p9k__prompt[len+1,-1] +} + +_p9k_prompt_wifi_init() { + if [[ -x /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport ]]; then + typeset -g _p9k__wifi_on= + typeset -g P9K_WIFI_LAST_TX_RATE= + typeset -g P9K_WIFI_SSID= + typeset -g P9K_WIFI_LINK_AUTH= + typeset -g P9K_WIFI_RSSI= + typeset -g P9K_WIFI_NOISE= + typeset -g P9K_WIFI_BARS= + _p9k__async_segments_compute+='_p9k_worker_invoke wifi _p9k_prompt_wifi_compute' + else + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${:-}' + fi +} + +_p9k_prompt_wifi_compute() { + _p9k_worker_async _p9k_prompt_wifi_async _p9k_prompt_wifi_sync +} + +_p9k_prompt_wifi_async() { + local airport=/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport + local last_tx_rate ssid link_auth rssi noise bars on out line v state + { + [[ -x $airport ]] || return 0 + out="$($airport -I)" || return 0 + for line in ${${${(f)out}##[[:space:]]#}%%[[:space:]]#}; do + v=${line#*: } + case $line[1,-$#v-3] in + agrCtlRSSI) rssi=$v;; + agrCtlNoise) noise=$v;; + state) state=$v;; + lastTxRate) last_tx_rate=$v;; + link\ auth) link_auth=$v;; + SSID) ssid=$v;; + esac + done + if [[ $state != running || $rssi != (0|-<->) || $noise != (0|-<->) ]]; then + rssi= + noise= + last_tx_rate= + link_auth= + ssid= + bars= + return 0 + fi + # https://www.speedguide.net/faq/how-to-read-rssisignal-and-snrnoise-ratings-440 + # http://www.wireless-nets.com/resources/tutorials/define_SNR_values.html + local -i snr_margin='rssi - noise' + if (( snr_margin >= 40 )); then + bars=4 + elif (( snr_margin >= 25 )); then + bars=3 + elif (( snr_margin >= 15 )); then + bars=2 + elif (( snr_margin >= 10 )); then + bars=1 + else + bars=0 + fi + on=1 + } always { + if [[ $_p9k__wifi_on != $on || + $P9K_WIFI_LAST_TX_RATE != $last_tx_rate || + $P9K_WIFI_SSID != $ssid || + $P9K_WIFI_LINK_AUTH != $link_auth || + $P9K_WIFI_RSSI != $rssi || + $P9K_WIFI_NOISE != $noise || + $P9K_WIFI_BARS != $bars ]]; then + _p9k__wifi_on=$on + P9K_WIFI_LAST_TX_RATE=$last_tx_rate + P9K_WIFI_SSID=$ssid + P9K_WIFI_LINK_AUTH=$link_auth + P9K_WIFI_RSSI=$rssi + P9K_WIFI_NOISE=$noise + P9K_WIFI_BARS=$bars + _p9k_print_params \ + _p9k__wifi_on \ + P9K_WIFI_LAST_TX_RATE \ + P9K_WIFI_SSID \ + P9K_WIFI_LINK_AUTH \ + P9K_WIFI_RSSI \ + P9K_WIFI_NOISE \ + P9K_WIFI_BARS + echo -E - 'reset=1' + fi + } +} + +_p9k_prompt_wifi_sync() { + if [[ -n $REPLY ]]; then + eval $REPLY + _p9k_worker_reply $REPLY + fi +} + +function _p9k_asdf_check_meta() { + [[ -n $_p9k_asdf_meta_sig ]] || return + [[ -z $^_p9k_asdf_meta_non_files(#qN) ]] || return + local -a stat + if (( $#_p9k_asdf_meta_files )); then + zstat -A stat +mtime -- $_p9k_asdf_meta_files 2>/dev/null || return + fi + [[ $_p9k_asdf_meta_sig == $ASDF_CONFIG_FILE$'\0'$ASDF_DATA_DIR$'\0'${(pj:\0:)stat} ]] || return +} + +function _p9k_asdf_init_meta() { + local last_sig=$_p9k_asdf_meta_sig + { + local -a files + local -i legacy_enabled + + _p9k_asdf_plugins=() + _p9k_asdf_file_info=() + + local cfg=${ASDF_CONFIG_FILE:-~/.asdfrc} + files+=$cfg + if [[ -f $cfg && -r $cfg ]]; then + # Config parser in adsf is very strange. + # + # This gives "yes": + # + # legacy_version_file = yes = no + # + # This gives "no": + # + # legacy_version_file = yes + # legacy_version_file = yes + # + # We do the same. + local lines=(${(@M)${(f)"$(<$cfg)"}:#[[:space:]]#legacy_version_file[[:space:]]#=*}) + if [[ $#lines == 1 && ${${(s:=:)lines[1]}[2]} == [[:space:]]#yes[[:space:]]# ]]; then + legacy_enabled=1 + fi + fi + + local root=${ASDF_DATA_DIR:-~/.asdf}/plugins + files+=$root + if [[ -d $root ]]; then + local plugin + for plugin in $root/[^[:space:]]##(N); do + _p9k_asdf_plugins+=${plugin:t} + (( legacy_enabled )) || continue + if [[ ! -e $plugin/bin ]]; then + files+=$plugin/bin + else + local list_names=$plugin/bin/list-legacy-filenames + files+=$list_names + if [[ -x $list_names ]]; then + local parse=$plugin/bin/parse-legacy-file + local -i has_parse=0 + files+=$parse + [[ -x $parse ]] && has_parse=1 + local name + for name in $($list_names 2>/dev/null); do + [[ $name == (*/*|.tool-versions) ]] && continue + _p9k_asdf_file_info[$name]+="${plugin:t} $has_parse " + done + fi + fi + done + fi + + _p9k_asdf_meta_files=($^files(N)) + _p9k_asdf_meta_non_files=(${files:|_p9k_asdf_meta_files}) + + local -a stat + if (( $#_p9k_asdf_meta_files )); then + zstat -A stat +mtime -- $_p9k_asdf_meta_files 2>/dev/null || return + fi + _p9k_asdf_meta_sig=$ASDF_CONFIG_FILE$'\0'$ASDF_DATA_DIR$'\0'${(pj:\0:)stat} + } always { + if (( $? == 0 )); then + _p9k__state_dump_scheduled=1 + return + fi + [[ -n $last_sig ]] && _p9k__state_dump_scheduled=1 + _p9k_asdf_meta_files=() + _p9k_asdf_meta_non_files=() + _p9k_asdf_meta_sig= + _p9k_asdf_plugins=() + _p9k_asdf_file_info=() + _p9k__asdf_dir2files=() + _p9k_asdf_file2versions=() + } +} + +# Usage: _p9k_asdf_parse_version_file <file> <is_legacy> +# +# Mutates `versions` on success. +function _p9k_asdf_parse_version_file() { + local file=$1 + local is_legacy=$2 + local -a stat + zstat -A stat +mtime $file 2>/dev/null || return + if (( is_legacy )); then + local plugin has_parse + for plugin has_parse in $=_p9k_asdf_file_info[$file:t]; do + local cached=$_p9k_asdf_file2versions[$plugin:$file] + if [[ $cached == $stat[1]:* ]]; then + local v=${cached#*:} + else + if (( has_parse )); then + local v=($(${ASDF_DATA_DIR:-~/.asdf}/plugins/$plugin/bin/parse-legacy-file $file 2>/dev/null)) + else + { local v=($(<$file)) } 2>/dev/null + fi + _p9k_asdf_file2versions[$plugin:$file]=$stat[1]:"$v" + _p9k__state_dump_scheduled=1 + fi + (( $#v )) && : ${versions[$plugin]="$v"} + done + else + local cached=$_p9k_asdf_file2versions[:$file] + if [[ $cached == $stat[1]:* ]]; then + local file_versions=(${(0)${cached#*:}}) + else + local file_versions=() + { local lines=(${(@)${(f)"$(<$file)"}/\#*}) } 2>/dev/null + local line + for line in $lines; do + local words=($=line) + (( $#words > 1 && $_p9k_asdf_plugins[(Ie)$words[1]] )) || continue + file_versions+=($words[1] "${words[2,-1]}") + done + _p9k_asdf_file2versions[:$file]=$stat[1]:${(pj:\0:)file_versions} + _p9k__state_dump_scheduled=1 + fi + local plugin version + for plugin version in $file_versions; do + : ${versions[$plugin]=$version} + done + fi + return 0 +} + +function prompt_asdf() { + _p9k_asdf_check_meta || _p9k_asdf_init_meta || return + + local -A versions + local -a stat + zstat -A stat +mtime ~ 2>/dev/null || return + local dirs=($_p9k__parent_dirs ~) + local mtimes=($_p9k__parent_mtimes $stat[1]) + local -i has_global + + local elem + for elem in ${(@)${:-{1..$#dirs}}/(#m)*/${${:-$MATCH:$_p9k__asdf_dir2files[$dirs[MATCH]]}#$MATCH:$mtimes[MATCH]:}}; do + if [[ $elem == *:* ]]; then + local dir=$dirs[${elem%%:*}] + zstat -A stat +mtime $dir 2>/dev/null || return + local files=($dir/.tool-versions(N) $dir/${(k)^_p9k_asdf_file_info}(N)) + _p9k__asdf_dir2files[$dir]=$stat[1]:${(pj:\0:)files} + else + local files=(${(0)elem}) + fi + if [[ ${files[1]:h} == ~ ]]; then + has_global=1 + local -A local_versions=(${(kv)versions}) + versions=() + fi + local file + for file in $files; do + [[ $file == */.tool-versions ]] + _p9k_asdf_parse_version_file $file $? || return + done + done + + if (( ! has_global )); then + has_global=1 + local -A local_versions=(${(kv)versions}) + versions=() + fi + + if [[ -r $ASDF_DEFAULT_TOOL_VERSIONS_FILENAME ]]; then + _p9k_asdf_parse_version_file $ASDF_DEFAULT_TOOL_VERSIONS_FILENAME 0 || return + fi + + local plugin + for plugin in $_p9k_asdf_plugins; do + local upper=${(U)plugin//-/_} + if (( $+parameters[_POWERLEVEL9K_ASDF_${upper}_SOURCES] )); then + local sources=(${(P)${:-_POWERLEVEL9K_ASDF_${upper}_SOURCES}}) + else + local sources=($_POWERLEVEL9K_ASDF_SOURCES) + fi + + local version="${(P)${:-ASDF_${upper}_VERSION}}" + if [[ -n $version ]]; then + (( $sources[(I)shell] )) || continue + else + version=$local_versions[$plugin] + if [[ -n $version ]]; then + (( $sources[(I)local] )) || continue + else + version=$versions[$plugin] + [[ -n $version ]] || continue + (( $sources[(I)global] )) || continue + fi + fi + + if [[ $version == $versions[$plugin] ]]; then + if (( $+parameters[_POWERLEVEL9K_ASDF_${upper}_PROMPT_ALWAYS_SHOW] )); then + (( _POWERLEVEL9K_ASDF_${upper}_PROMPT_ALWAYS_SHOW )) || continue + else + (( _POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW )) || continue + fi + fi + + if [[ $version == system ]]; then + if (( $+parameters[_POWERLEVEL9K_ASDF_${upper}_SHOW_SYSTEM] )); then + (( _POWERLEVEL9K_ASDF_${upper}_SHOW_SYSTEM )) || continue + else + (( _POWERLEVEL9K_ASDF_SHOW_SYSTEM )) || continue + fi + fi + + _p9k_get_icon $0_$upper ${upper}_ICON $plugin + _p9k_prompt_segment $0_$upper green $_p9k_color1 $'\1'$_p9k__ret 0 '' ${version//\%/%%} + done +} + +_p9k_prompt_asdf_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='${commands[asdf]:-${${+functions[asdf]}:#0}}' +} + +_p9k_haskell_stack_version() { + if ! _p9k_cache_stat_get $0 $1 ${STACK_ROOT:-~/.stack}/{pantry/pantry.sqlite3,stack.sqlite3}; then + local v + v="$(STACK_YAML=$1 stack \ + --silent \ + --no-install-ghc \ + --skip-ghc-check \ + --no-terminal \ + --color=never \ + --lock-file=read-only \ + query compiler actual)" || v= + _p9k_cache_stat_set "$v" + fi + _p9k__ret=$_p9k__cache_val[1] +} + +prompt_haskell_stack() { + if [[ -n $STACK_YAML ]]; then + (( ${_POWERLEVEL9K_HASKELL_STACK_SOURCES[(I)shell]} )) || return + _p9k_haskell_stack_version $STACK_YAML + else + (( ${_POWERLEVEL9K_HASKELL_STACK_SOURCES[(I)local|global]} )) || return + if _p9k_upglob stack.yaml; then + (( _POWERLEVEL9K_HASKELL_STACK_PROMPT_ALWAYS_SHOW )) || return + (( ${_POWERLEVEL9K_HASKELL_STACK_SOURCES[(I)global]} )) || return + _p9k_haskell_stack_version ${STACK_ROOT:-~/.stack}/global-project/stack.yaml + else + local -i idx=$? + (( ${_POWERLEVEL9K_HASKELL_STACK_SOURCES[(I)local]} )) || return + _p9k_haskell_stack_version $_p9k__parent_dirs[idx]/stack.yaml + fi + fi + + [[ -n $_p9k__ret ]] || return + + local v=$_p9k__ret + + if (( !_POWERLEVEL9K_HASKELL_STACK_PROMPT_ALWAYS_SHOW )); then + _p9k_haskell_stack_version ${STACK_ROOT:-~/.stack}/global-project/stack.yaml + [[ $v == $_p9k__ret ]] && return + fi + + _p9k_prompt_segment "$0" "yellow" "$_p9k_color1" 'HASKELL_ICON' 0 '' "${v//\%/%%}" +} + +_p9k_prompt_haskell_stack_init() { + typeset -g "_p9k__segment_cond_${_p9k__prompt_side}[_p9k__segment_index]"='$commands[stack]' +} + +# Use two preexec hooks to survive https://github.com/MichaelAquilina/zsh-you-should-use with +# YSU_HARDCORE=1. See https://github.com/romkatv/powerlevel10k/issues/427. +_p9k_preexec1() { + _p9k_restore_special_params + unset __p9k_trapint + trap - INT +} + +_p9k_preexec2() { + typeset -g _p9k__preexec_cmd=$2 + _p9k__timer_start=EPOCHREALTIME + P9K_TTY=old +} + +function _p9k_prompt_net_iface_init() { + typeset -g _p9k__public_ip_vpn= + typeset -g _p9k__public_ip_not_vpn= + typeset -g P9K_IP_IP= + typeset -g P9K_IP_INTERFACE= + typeset -g P9K_IP_TX_BYTES= + typeset -g P9K_IP_RX_BYTES= + typeset -g P9K_IP_TX_RATE= + typeset -g P9K_IP_RX_RATE= + typeset -g _p9__ip_timestamp= + typeset -g _p9k__vpn_ip_ips=() + [[ -z $_POWERLEVEL9K_PUBLIC_IP_VPN_INTERFACE ]] && _p9k__public_ip_not_vpn=1 + _p9k__async_segments_compute+='_p9k_worker_invoke net_iface _p9k_prompt_net_iface_compute' +} + +# reads `iface2ip` and sets `ifaces` and `ips` +function _p9k_prompt_net_iface_match() { + local iface_regex="^($1)\$" iface ip + ips=() + ifaces=() + for iface ip in "${(@)iface2ip}"; do + [[ $iface =~ $iface_regex ]] || continue + ifaces+=$iface + ips+=$ip + done + return $(($#ips == 0)) +} + +function _p9k_prompt_net_iface_compute() { + _p9k_worker_async _p9k_prompt_net_iface_async _p9k_prompt_net_iface_sync +} + +function _p9k_prompt_net_iface_async() { + # netstat -inbI en0 + local iface ip line var + typeset -a iface2ip ips ifaces + if (( $+commands[ifconfig] )); then + for line in ${(f)"$(command ifconfig 2>/dev/null)"}; do + if [[ $line == (#b)([^[:space:]]##):[[:space:]]##flags=(<->)'<'* ]]; then + [[ $match[2] == *[13579] ]] && iface=$match[1] || iface= + elif [[ -n $iface && $line == (#b)[[:space:]]##inet[[:space:]]##([0-9.]##)* ]]; then + iface2ip+=($iface $match[1]) + iface= + fi + done + elif (( $+commands[ip] )); then + for line in ${(f)"$(command ip -4 a show 2>/dev/null)"}; do + if [[ $line == (#b)<->:[[:space:]]##([^:]##):[[:space:]]##\<([^\>]#)\>* ]]; then + [[ ,$match[2], == *,UP,* ]] && iface=$match[1] || iface= + elif [[ -n $iface && $line == (#b)[[:space:]]##inet[[:space:]]##([0-9.]##)* ]]; then + iface2ip+=($iface $match[1]) + iface= + fi + done + fi + + if _p9k_prompt_net_iface_match $_POWERLEVEL9K_PUBLIC_IP_VPN_INTERFACE; then + local public_ip_vpn=1 + local public_ip_not_vpn= + else + local public_ip_vpn= + local public_ip_not_vpn=1 + fi + if _p9k_prompt_net_iface_match $_POWERLEVEL9K_IP_INTERFACE; then + local ip_ip=$ips[1] ip_interface=$ifaces[1] ip_timestamp=$EPOCHREALTIME + local ip_tx_bytes ip_rx_bytes ip_tx_rate ip_rx_rate + if [[ $_p9k_os == (Linux|Android) ]]; then + if [[ -r /sys/class/net/$ifaces[1]/statistics/tx_bytes && + -r /sys/class/net/$ifaces[1]/statistics/rx_bytes ]]; then + _p9k_read_file /sys/class/net/$ifaces[1]/statistics/tx_bytes && + [[ $_p9k__ret == <-> ]] && ip_tx_bytes=$_p9k__ret && + _p9k_read_file /sys/class/net/$ifaces[1]/statistics/rx_bytes && + [[ $_p9k__ret == <-> ]] && ip_rx_bytes=$_p9k__ret || { ip_tx_bytes=; ip_rx_bytes=; } + fi + elif [[ $_p9k_os == (BSD|OSX) && $+commands[netstat] == 1 ]]; then + local -a lines + if lines=(${(f)"$(netstat -inbI $ifaces[1])"}); then + local header=($=lines[1]) + local -i rx_idx=$header[(Ie)Ibytes] + local -i tx_idx=$header[(Ie)Obytes] + if (( rx_idx && tx_idx )); then + ip_tx_bytes=0 + ip_rx_bytes=0 + for line in ${lines:1}; do + (( ip_rx_bytes += ${line[(w)rx_idx]} )) + (( ip_tx_bytes += ${line[(w)tx_idx]} )) + done + fi + fi + fi + if [[ -n $ip_rx_bytes ]]; then + if [[ $ip_ip == $P9K_IP_IP && $ifaces[1] == $P9K_IP_INTERFACE ]]; then + local -F t='ip_timestamp - _p9__ip_timestamp' + if (( t <= 0 )); then + ip_tx_rate=${P9K_IP_TX_RATE:-0 B/s} + ip_rx_rate=${P9K_IP_RX_RATE:-0 B/s} + else + _p9k_human_readable_bytes $(((ip_tx_bytes - P9K_IP_TX_BYTES) / t)) + [[ $_p9k__ret == *B ]] && ip_tx_rate="$_p9k__ret[1,-2] B/s" || ip_tx_rate="$_p9k__ret[1,-2] $_p9k__ret[-1]iB/s" + _p9k_human_readable_bytes $(((ip_rx_bytes - P9K_IP_RX_BYTES) / t)) + [[ $_p9k__ret == *B ]] && ip_rx_rate="$_p9k__ret[1,-2] B/s" || ip_rx_rate="$_p9k__ret[1,-2] $_p9k__ret[-1]iB/s" + fi + else + ip_tx_rate='0 B/s' + ip_rx_rate='0 B/s' + fi + fi + else + local ip_ip= ip_interface= ip_tx_bytes= ip_rx_bytes= ip_tx_rate= ip_rx_rate= ip_timestamp= + fi + if _p9k_prompt_net_iface_match $_POWERLEVEL9K_VPN_IP_INTERFACE; then + if (( _POWERLEVEL9K_VPN_IP_SHOW_ALL )); then + local vpn_ip_ips=($ips) + else + local vpn_ip_ips=($ips[1]) + fi + else + local vpn_ip_ips=() + fi + [[ $_p9k__public_ip_vpn == $public_ip_vpn && + $_p9k__public_ip_not_vpn == $public_ip_not_vpn && + $P9K_IP_IP == $ip_ip && + $P9K_IP_INTERFACE == $ip_interface && + $P9K_IP_TX_BYTES == $ip_tx_bytes && + $P9K_IP_RX_BYTES == $ip_rx_bytes && + $P9K_IP_TX_RATE == $ip_tx_rate && + $P9K_IP_RX_RATE == $ip_rx_rate && + "$_p9k__vpn_ip_ips" == "$vpn_ip_ips" ]] && return 1 + if [[ "$_p9k__vpn_ip_ips" == "$vpn_ip_ips" ]]; then + echo -n 0 + else + echo -n 1 + fi + _p9k__public_ip_vpn=$public_ip_vpn + _p9k__public_ip_not_vpn=$public_ip_not_vpn + P9K_IP_IP=$ip_ip + P9K_IP_INTERFACE=$ip_interface + P9K_IP_TX_BYTES=$ip_tx_bytes + P9K_IP_RX_BYTES=$ip_rx_bytes + P9K_IP_TX_RATE=$ip_tx_rate + P9K_IP_RX_RATE=$ip_rx_rate + _p9__ip_timestamp=$ip_timestamp + _p9k__vpn_ip_ips=($vpn_ip_ips) + _p9k_print_params \ + _p9k__public_ip_vpn \ + _p9k__public_ip_not_vpn \ + P9K_IP_IP \ + P9K_IP_INTERFACE \ + P9K_IP_TX_BYTES \ + P9K_IP_RX_BYTES \ + P9K_IP_TX_RATE \ + P9K_IP_RX_RATE \ + _p9__ip_timestamp \ + _p9k__vpn_ip_ips + echo -E - 'reset=1' +} + +_p9k_prompt_net_iface_sync() { + local -i vpn_ip_changed=$REPLY[1] + REPLY[1]="" + eval $REPLY + (( vpn_ip_changed )) && REPLY+='; _p9k_vpn_ip_render' + _p9k_worker_reply $REPLY +} + +function _p9k_set_prompt() { + PROMPT= + RPROMPT= + [[ $1 == instant_ ]] || PROMPT+='${$((_p9k_on_expand()))+}' + PROMPT+=$_p9k_prompt_prefix_left + + local -i _p9k__has_upglob + + local -i left_idx=1 right_idx=1 num_lines=$#_p9k_line_segments_left + for _p9k__line_index in {1..$num_lines}; do + local right= + if (( !_POWERLEVEL9K_DISABLE_RPROMPT )); then + _p9k__dir= + _p9k__prompt= + _p9k__segment_index=right_idx + _p9k__prompt_side=right + if [[ $1 == instant_ ]]; then + for _p9k__segment_name in ${${(0)_p9k_line_segments_right[_p9k__line_index]}%_joined}; do + if (( $+functions[instant_prompt_$_p9k__segment_name] )); then + local disabled=_POWERLEVEL9K_${(U)_p9k__segment_name}_DISABLED_DIR_PATTERN + if [[ $_p9k__cwd != ${(P)~disabled} ]]; then + local -i len=$#_p9k__prompt + _p9k__non_hermetic_expansion=0 + instant_prompt_$_p9k__segment_name + if (( _p9k__non_hermetic_expansion )); then + _p9k__prompt[len+1,-1]= + fi + fi + fi + ((++_p9k__segment_index)) + done + else + for _p9k__segment_name in ${${(0)_p9k_line_segments_right[_p9k__line_index]}%_joined}; do + local cond=$_p9k__segment_cond_right[_p9k__segment_index] + if [[ -z $cond || -n ${(e)cond} ]]; then + local disabled=_POWERLEVEL9K_${(U)_p9k__segment_name}_DISABLED_DIR_PATTERN + if [[ $_p9k__cwd != ${(P)~disabled} ]]; then + local val=$_p9k__segment_val_right[_p9k__segment_index] + if [[ -n $val ]]; then + _p9k__prompt+=$val + else + if [[ $_p9k__segment_name == custom_* ]]; then + _p9k_custom_prompt $_p9k__segment_name[8,-1] + elif (( $+functions[prompt_$_p9k__segment_name] )); then + prompt_$_p9k__segment_name + fi + fi + fi + fi + ((++_p9k__segment_index)) + done + fi + _p9k__prompt=${${_p9k__prompt//$' %{\b'/'%{%G'}//$' \b'} + right_idx=_p9k__segment_index + if [[ -n $_p9k__prompt || $_p9k_line_never_empty_right[_p9k__line_index] == 1 ]]; then + right=$_p9k_line_prefix_right[_p9k__line_index]$_p9k__prompt$_p9k_line_suffix_right[_p9k__line_index] + fi + fi + unset _p9k__dir + _p9k__prompt=$_p9k_line_prefix_left[_p9k__line_index] + _p9k__segment_index=left_idx + _p9k__prompt_side=left + if [[ $1 == instant_ ]]; then + for _p9k__segment_name in ${${(0)_p9k_line_segments_left[_p9k__line_index]}%_joined}; do + if (( $+functions[instant_prompt_$_p9k__segment_name] )); then + local disabled=_POWERLEVEL9K_${(U)_p9k__segment_name}_DISABLED_DIR_PATTERN + if [[ $_p9k__cwd != ${(P)~disabled} ]]; then + local -i len=$#_p9k__prompt + _p9k__non_hermetic_expansion=0 + instant_prompt_$_p9k__segment_name + if (( _p9k__non_hermetic_expansion )); then + _p9k__prompt[len+1,-1]= + fi + fi + fi + ((++_p9k__segment_index)) + done + else + for _p9k__segment_name in ${${(0)_p9k_line_segments_left[_p9k__line_index]}%_joined}; do + local cond=$_p9k__segment_cond_left[_p9k__segment_index] + if [[ -z $cond || -n ${(e)cond} ]]; then + local disabled=_POWERLEVEL9K_${(U)_p9k__segment_name}_DISABLED_DIR_PATTERN + if [[ $_p9k__cwd != ${(P)~disabled} ]]; then + local val=$_p9k__segment_val_left[_p9k__segment_index] + if [[ -n $val ]]; then + _p9k__prompt+=$val + else + if [[ $_p9k__segment_name == custom_* ]]; then + _p9k_custom_prompt $_p9k__segment_name[8,-1] + elif (( $+functions[prompt_$_p9k__segment_name] )); then + prompt_$_p9k__segment_name + fi + fi + fi + fi + ((++_p9k__segment_index)) + done + fi + _p9k__prompt=${${_p9k__prompt//$' %{\b'/'%{%G'}//$' \b'} + left_idx=_p9k__segment_index + _p9k__prompt+=$_p9k_line_suffix_left[_p9k__line_index] + if (( $+_p9k__dir || (_p9k__line_index != num_lines && $#right) )); then + _p9k__prompt='${${:-${_p9k__d::=0}${_p9k__rprompt::='$right'}${_p9k__lprompt::='$_p9k__prompt'}}+}' + _p9k__prompt+=$_p9k_gap_pre + if (( $+_p9k__dir )); then + if (( _p9k__line_index == num_lines && (_POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS > 0 || _POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT > 0) )); then + local a=$_POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS + local f=$((0.01*_POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT))'*_p9k__clm' + _p9k__prompt+="\${\${_p9k__h::=$((($a<$f)*$f+($a>=$f)*$a))}+}" + else + _p9k__prompt+='${${_p9k__h::=0}+}' + fi + if [[ $_POWERLEVEL9K_DIR_MAX_LENGTH == <->('%'|) ]]; then + local lim= + if [[ $_POWERLEVEL9K_DIR_MAX_LENGTH[-1] == '%' ]]; then + lim="$_p9k__dir_len-$((0.01*$_POWERLEVEL9K_DIR_MAX_LENGTH[1,-2]))*_p9k__clm" + else + lim=$((_p9k__dir_len-_POWERLEVEL9K_DIR_MAX_LENGTH)) + ((lim <= 0)) && lim= + fi + if [[ -n $lim ]]; then + _p9k__prompt+='${${${$((_p9k__h<_p9k__m+'$lim')):#1}:-${_p9k__h::=$((_p9k__m+'$lim'))}}+}' + fi + fi + _p9k__prompt+='${${_p9k__d::=$((_p9k__m-_p9k__h))}+}' + _p9k__prompt+='${_p9k__lprompt/\%\{d\%\}*\%\{d\%\}/'$_p9k__dir'}' + _p9k__prompt+='${${_p9k__m::=$((_p9k__d+_p9k__h))}+}' + else + _p9k__prompt+='${_p9k__lprompt}' + fi + ((_p9k__line_index != num_lines && $#right)) && _p9k__prompt+=$_p9k_line_gap_post[_p9k__line_index] + fi + if (( _p9k__line_index == num_lines )); then + [[ -n $right ]] && RPROMPT=$_p9k_prompt_prefix_right$right$_p9k_prompt_suffix_right + _p9k__prompt='${_p9k__'$_p9k__line_index'-'$_p9k__prompt'}'$_p9k_prompt_suffix_left + [[ $1 == instant_ ]] || PROMPT+=$_p9k__prompt + else + [[ -n $right ]] || _p9k__prompt+=$'\n' + PROMPT+='${_p9k__'$_p9k__line_index'-'$_p9k__prompt'}' + fi + done + + _p9k__prompt_side= + (( $#_p9k_cache < _POWERLEVEL9K_MAX_CACHE_SIZE )) || _p9k_cache=() + (( $#_p9k__cache_ephemeral < _POWERLEVEL9K_MAX_CACHE_SIZE )) || _p9k__cache_ephemeral=() + + [[ -n $RPROMPT ]] || unset RPROMPT +} + +_p9k_set_instant_prompt() { + local saved_prompt=$PROMPT + local saved_rprompt=$RPROMPT + _p9k_set_prompt instant_ + typeset -g _p9k__instant_prompt=$PROMPT$'\x1f'$_p9k__prompt$'\x1f'$RPROMPT + PROMPT=$saved_prompt + RPROMPT=$saved_rprompt + [[ -n $RPROMPT ]] || unset RPROMPT +} + +typeset -gri __p9k_instant_prompt_version=26 + +_p9k_dump_instant_prompt() { + local user=${(%):-%n} + local root_dir=${__p9k_dump_file:h} + local prompt_dir=${root_dir}/p10k-$user + local root_file=$root_dir/p10k-instant-prompt-$user.zsh + local prompt_file=$prompt_dir/prompt-${#_p9k__cwd} + [[ -d $prompt_dir ]] || mkdir -p $prompt_dir || return + [[ -w $root_dir && -w $prompt_dir ]] || return + + if [[ ! -e $root_file ]]; then + local tmp=$root_file.tmp.$$ + local -i fd + sysopen -a -m 600 -o creat,trunc -u fd -- $tmp || return + { + [[ $TERM_PROGRAM == Hyper ]] && local hyper='==' || local hyper='!=' + local -a display_v=("${_p9k__display_v[@]}") + local -i i + for ((i = 6; i <= $#display_v; i+=2)); do display_v[i]=show; done + display_v[2]=hide + display_v[4]=hide + local gitstatus_dir=${${_POWERLEVEL9K_GITSTATUS_DIR:A}:-${__p9k_root_dir}/gitstatus} + local gitstatus_header + if [[ -r $gitstatus_dir/install.info ]]; then + IFS= read -r gitstatus_header <$gitstatus_dir/install.info || return + fi + >&$fd print -r -- "() { + $__p9k_intro_no_locale + (( ! \$+__p9k_instant_prompt_disabled )) || return + typeset -gi __p9k_instant_prompt_disabled=1 __p9k_instant_prompt_sourced=$__p9k_instant_prompt_version + [[ -t 0 && -t 1 && -t 2 && \$ZSH_VERSION == ${(q)ZSH_VERSION} && \$ZSH_PATCHLEVEL == ${(q)ZSH_PATCHLEVEL} && + \$TERM_PROGRAM $hyper 'Hyper' && \$+VTE_VERSION == $+VTE_VERSION && + \$POWERLEVEL9K_DISABLE_INSTANT_PROMPT != 'true' && + \$POWERLEVEL9K_INSTANT_PROMPT != 'off' ]] || { __p9k_instant_prompt_sourced=0; return 1; } + typeset -g __p9k_instant_prompt_param_sig=${(q+)_p9k__param_sig} + local gitstatus_dir=${(q)gitstatus_dir} + local gitstatus_header=${(q)gitstatus_header} + local -i ZLE_RPROMPT_INDENT=${ZLE_RPROMPT_INDENT:-1} + local PROMPT_EOL_MARK=${(q)PROMPT_EOL_MARK-%B%S%#%s%b} + [[ -n \$SSH_CLIENT || -n \$SSH_TTY || -n \$SSH_CONNECTION ]] && local ssh=1 || local ssh=0 + local cr=\$'\r' lf=\$'\n' esc=\$'\e[' rs=$'\x1e' us=$'\x1f' + local -i height=$_POWERLEVEL9K_INSTANT_PROMPT_COMMAND_LINES + local prompt_dir=${(q)prompt_dir}" + >&$fd print -r -- ' + local real_gitstatus_header + if [[ -r $gitstatus_dir/install.info ]]; then + IFS= read -r real_gitstatus_header <$gitstatus_dir/install.info || real_gitstatus_header=borked + fi + if [[ $real_gitstatus_header != $gitstatus_header ]]; then + __p9k_instant_prompt_sourced=0 + return 1 + fi + zmodload zsh/langinfo zsh/terminfo zsh/system || return + if [[ $langinfo[CODESET] != (utf|UTF)(-|)8 ]]; then + local loc_cmd=$commands[locale] + [[ -z $loc_cmd ]] && loc_cmd='${(q)commands[locale]}' + if [[ -x $loc_cmd ]]; then + local -a locs + if locs=(${(@M)$(locale -a 2>/dev/null):#*.(utf|UTF)(-|)8}) && (( $#locs )); then + local loc=${locs[(r)(#i)C.UTF(-|)8]:-${locs[(r)(#i)en_US.UTF(-|)8]:-$locs[1]}} + [[ -n $LC_ALL ]] && local LC_ALL=$loc || local LC_CTYPE=$loc + fi + fi + fi + (( $+terminfo[cuu] && $+terminfo[cuf] && $+terminfo[ed] && $+terminfo[sc] && $+terminfo[rc] )) || return + local pwd=${(%):-%/} + local prompt_file=$prompt_dir/prompt-${#pwd} + local key=$pwd:$ssh:${(%):-%#} + local content + { content="$(<$prompt_file)" } 2>/dev/null || return + local tail=${content##*$rs$key$us} + [[ ${#tail} != ${#content} ]] || return + local P9K_PROMPT=instant + if [[ $P9K_TTY != old ]]; then' + if (( _POWERLEVEL9K_NEW_TTY_MAX_AGE_SECONDS < 0 )); then + >&$fd print -r -- ' typeset -gx P9K_TTY=new' + else + >&$fd print -r -- ' + typeset -gx P9K_TTY=old + zmodload -F zsh/stat b:zstat || return + zmodload zsh/datetime || return + local -a stat + if zstat -A stat +ctime -- $TTY 2>/dev/null && + (( EPOCHREALTIME - stat[1] < '$_POWERLEVEL9K_NEW_TTY_MAX_AGE_SECONDS' )); then + P9K_TTY=new + fi' + fi + >&$fd print -r -- ' fi + local -i _p9k__empty_line_i=3 _p9k__ruler_i=3 + local -A _p9k_display_k=('${(j: :)${(@q)${(kv)_p9k_display_k}}}') + local -a _p9k__display_v=('${(j: :)${(@q)display_v}}') + function p10k() { + '$__p9k_intro' + [[ $1 == display ]] || return + shift + local -i k dump + local opt prev new pair list name var + while getopts ":ha" opt; do + case $opt in + a) dump=1;; + h) return 0;; + ?) return 1;; + esac + done + if (( dump )); then + reply=() + shift $((OPTIND-1)) + (( ARGC )) || set -- "*" + for opt; do + for k in ${(u@)_p9k_display_k[(I)$opt]:/(#m)*/$_p9k_display_k[$MATCH]}; do + reply+=($_p9k__display_v[k,k+1]) + done + done + return 0 + fi + for opt in "${@:$OPTIND}"; do + pair=(${(s:=:)opt}) + list=(${(s:,:)${pair[2]}}) + if [[ ${(b)pair[1]} == $pair[1] ]]; then + local ks=($_p9k_display_k[$pair[1]]) + else + local ks=(${(u@)_p9k_display_k[(I)$pair[1]]:/(#m)*/$_p9k_display_k[$MATCH]}) + fi + for k in $ks; do + if (( $#list == 1 )); then + [[ $_p9k__display_v[k+1] == $list[1] ]] && continue + new=$list[1] + else + new=${list[list[(I)$_p9k__display_v[k+1]]+1]:-$list[1]} + [[ $_p9k__display_v[k+1] == $new ]] && continue + fi + _p9k__display_v[k+1]=$new + name=$_p9k__display_v[k] + if [[ $name == (empty_line|ruler) ]]; then + var=_p9k__${name}_i + [[ $new == hide ]] && typeset -gi $var=3 || unset $var + elif [[ $name == (#b)(<->)(*) ]]; then + var=_p9k__${match[1]}${${${${match[2]//\/}/#left/l}/#right/r}/#gap/g} + [[ $new == hide ]] && typeset -g $var= || unset $var + fi + done + done + }' + if (( _POWERLEVEL9K_PROMPT_ADD_NEWLINE )); then + >&$fd print -r -- ' [[ $P9K_TTY == old ]] && { unset _p9k__empty_line_i; _p9k__display_v[2]=print }' + fi + if (( _POWERLEVEL9K_SHOW_RULER )); then + >&$fd print -r -- '[[ $P9K_TTY == old ]] && { unset _p9k__ruler_i; _p9k__display_v[4]=print }' + fi + if (( $+functions[p10k-on-init] )); then + >&$fd print -r -- ' + p10k-on-init() { '$functions[p10k-on-init]' }' + fi + if (( $+functions[p10k-on-pre-prompt] )); then + >&$fd print -r -- ' + p10k-on-pre-prompt() { '$functions[p10k-on-pre-prompt]' }' + fi + if (( $+functions[p10k-on-post-prompt] )); then + >&$fd print -r -- ' + p10k-on-post-prompt() { '$functions[p10k-on-post-prompt]' }' + fi + if (( $+functions[p10k-on-post-widget] )); then + >&$fd print -r -- ' + p10k-on-post-widget() { '$functions[p10k-on-post-widget]' }' + fi + if (( $+functions[p10k-on-init] )); then + >&$fd print -r -- ' + p10k-on-init' + fi + local pat idx var + for pat idx var in $_p9k_show_on_command; do + >&$fd print -r -- " + local $var= + _p9k__display_v[$idx]=hide" + done + if (( $+functions[p10k-on-pre-prompt] )); then + >&$fd print -r -- ' + p10k-on-pre-prompt' + fi + if (( $+functions[p10k-on-init] )); then + >&$fd print -r -- ' + unfunction p10k-on-init' + fi + if (( $+functions[p10k-on-pre-prompt] )); then + >&$fd print -r -- ' + unfunction p10k-on-pre-prompt' + fi + if (( $+functions[p10k-on-post-prompt] )); then + >&$fd print -r -- ' + unfunction p10k-on-post-prompt' + fi + if (( $+functions[p10k-on-post-widget] )); then + >&$fd print -r -- ' + unfunction p10k-on-post-widget' + fi + >&$fd print -r -- ' + trap "unset -m _p9k__\*; unfunction p10k" EXIT + local -a _p9k_t=("${(@ps:$us:)${tail%%$rs*}}")' + if [[ $+VTE_VERSION == 1 || $TERM_PROGRAM == Hyper ]]; then + if [[ $TERM_PROGRAM == Hyper ]]; then + local bad_lines=40 bad_columns=100 + else + local bad_lines=24 bad_columns=80 + fi + >&$fd print -r -- ' + if (( LINES == '$bad_lines' && COLUMNS == '$bad_columns' )); then + zmodload -F zsh/stat b:zstat || return + zmodload zsh/datetime || return + local -a tty_ctime + if ! zstat -A tty_ctime +ctime -- $TTY 2>/dev/null || (( tty_ctime[1] + 2 > EPOCHREALTIME )); then + local -F deadline=$((EPOCHREALTIME+0.025)) + local tty_size + while true; do + if (( EPOCHREALTIME > deadline )) || ! tty_size="$(/bin/stty size 2>/dev/null)" || [[ $tty_size != <->" "<-> ]]; then + (( $+_p9k__ruler_i )) || local -i _p9k__ruler_i=1 + local _p9k__g= _p9k__'$#_p9k_line_segments_right'r= _p9k__'$#_p9k_line_segments_right'r_frame= + break + fi + if [[ $tty_size != "'$bad_lines' '$bad_columns'" ]]; then + local lines_columns=(${=tty_size}) + local LINES=$lines_columns[1] + local COLUMNS=$lines_columns[2] + break + fi + done + fi + fi' + fi + (( __p9k_ksh_arrays )) && >&$fd print -r -- ' setopt ksh_arrays' + (( __p9k_sh_glob )) && >&$fd print -r -- ' setopt sh_glob' + >&$fd print -r -- ' typeset -ga __p9k_used_instant_prompt=("${(@e)_p9k_t[-3,-1]}")' + (( __p9k_ksh_arrays )) && >&$fd print -r -- ' unsetopt ksh_arrays' + (( __p9k_sh_glob )) && >&$fd print -r -- ' unsetopt sh_glob' + >&$fd print -r -- ' + (( height += ${#${__p9k_used_instant_prompt[1]//[^$lf]}} )) + local _p9k__ret + function _p9k_prompt_length() { + local COLUMNS=1024 + local -i x y=$#1 m + if (( y )); then + while (( ${${(%):-$1%$y(l.1.0)}[-1]} )); do + x=y + (( y *= 2 )); + done + local xy + while (( y > x + 1 )); do + m=$(( x + (y - x) / 2 )) + typeset ${${(%):-$1%$m(l.x.y)}[-1]}=$m + done + fi + _p9k__ret=$x + } + local out' + [[ $+VTE_VERSION == 1 || $TERM_PROGRAM == Hyper ]] && >&$fd print -r -- ' if (( ! $+_p9k__g )); then' + >&$fd print -r -- ' + local mark=${(e)PROMPT_EOL_MARK} + [[ $mark == "%B%S%#%s%b" ]] && _p9k__ret=1 || _p9k_prompt_length $mark + local -i fill=$((COLUMNS > _p9k__ret ? COLUMNS - _p9k__ret : 0)) + out+="${(%):-%b%k%f%s%u$mark${(pl.$fill.. .)}$cr%b%k%f%s%u%E}"' + [[ $+VTE_VERSION == 1 || $TERM_PROGRAM == Hyper ]] && >&$fd print -r -- ' fi' + >&$fd print -r -- ' + out+="${(pl.$height..$lf.)}$esc${height}A$terminfo[sc]" + out+=${(%):-"$__p9k_used_instant_prompt[1]$__p9k_used_instant_prompt[2]"} + if [[ -n $__p9k_used_instant_prompt[3] ]]; then + _p9k_prompt_length "$__p9k_used_instant_prompt[2]" + local -i left_len=_p9k__ret + _p9k_prompt_length "$__p9k_used_instant_prompt[3]" + local -i gap=$((COLUMNS - left_len - _p9k__ret - ZLE_RPROMPT_INDENT)) + if (( gap >= 40 )); then + out+="${(pl.$gap.. .)}${(%):-${__p9k_used_instant_prompt[3]}%b%k%f%s%u}$cr$esc${left_len}C" + fi + fi + typeset -g __p9k_instant_prompt_output=${TMPDIR:-/tmp}/p10k-instant-prompt-output-${(%):-%n}-$$ + { echo -n > $__p9k_instant_prompt_output } || return + print -rn -- "$out" || return + local fd_null + sysopen -ru fd_null /dev/null || return + exec {__p9k_fd_0}<&0 {__p9k_fd_1}>&1 {__p9k_fd_2}>&2 0<&$fd_null 1>$__p9k_instant_prompt_output + exec 2>&1 {fd_null}>&- + typeset -gi __p9k_instant_prompt_active=1 + typeset -g __p9k_instant_prompt_dump_file=${XDG_CACHE_HOME:-~/.cache}/p10k-dump-${(%):-%n}.zsh + if source $__p9k_instant_prompt_dump_file 2>/dev/null && (( $+functions[_p9k_preinit] )); then + _p9k_preinit + fi + function _p9k_instant_prompt_precmd_first() { + '$__p9k_intro' + function _p9k_instant_prompt_sched_last() { + (( $+__p9k_instant_prompt_active )) || return 0 + () { + '$__p9k_intro' + exec 0<&$__p9k_fd_0 1>&$__p9k_fd_1 2>&$__p9k_fd_2 {__p9k_fd_0}>&- {__p9k_fd_1}>&- {__p9k_fd_2}>&- + unset __p9k_fd_0 __p9k_fd_1 __p9k_fd_2 __p9k_instant_prompt_active + typeset -gi __p9k_instant_prompt_erased=1 + print -rn -- $terminfo[rc]${(%):-%b%k%f%s%u}$terminfo[ed] + if [[ -s $__p9k_instant_prompt_output ]]; then + cat $__p9k_instant_prompt_output 2>/dev/null + local _p9k__ret mark="${(e)${PROMPT_EOL_MARK-%B%S%#%s%b}}" + _p9k_prompt_length $mark + local -i fill=$((COLUMNS > _p9k__ret ? COLUMNS - _p9k__ret : 0)) + echo -nE - "${(%):-%b%k%f%s%u$mark${(pl.$fill.. .)}$cr%b%k%f%s%u%E}" + fi + zmodload -F zsh/files b:zf_rm || return + local user=${(%):-%n} + local root_dir=${__p9k_instant_prompt_dump_file:h} + zf_rm -f -- $__p9k_instant_prompt_output $__p9k_instant_prompt_dump_file{,.zwc} $root_dir/p10k-instant-prompt-$user.zsh{,.zwc} $root_dir/p10k-$user/prompt-*(N) 2>/dev/null + } + setopt no_local_options prompt_cr prompt_sp + } + zmodload zsh/sched + sched +0 _p9k_instant_prompt_sched_last + precmd_functions=(${(@)precmd_functions:#_p9k_instant_prompt_precmd_first}) + } + precmd_functions=(_p9k_instant_prompt_precmd_first $precmd_functions) + DISABLE_UPDATE_PROMPT=true +} && unsetopt prompt_cr prompt_sp || true' + } always { + exec {fd}>&- + } + { + (( ! $? )) || return + # `zf_mv -f src dst` fails on NTFS if `dst` is not writable, hence `zf_rm`. + zf_rm -f -- $root_file.zwc || return + zf_mv -f -- $tmp $root_file || return + zcompile -R -- $tmp.zwc $root_file || return + zf_mv -f -- $tmp.zwc $root_file.zwc || return + } always { + (( $? )) && zf_rm -f -- $tmp $tmp.zwc 2>/dev/null + } + fi + + local tmp=$prompt_file.tmp.$$ + zf_mv -f -- $prompt_file $tmp 2>/dev/null + if [[ "$(<$tmp)" == *$'\x1e'$_p9k__instant_prompt_sig$'\x1f'* ]] 2>/dev/null; then + echo -n >$tmp || return + fi + + local -i fd + sysopen -a -m 600 -o creat -u fd -- $tmp || return + { + { + print -rnu $fd -- $'\x1e'$_p9k__instant_prompt_sig$'\x1f'${(pj:\x1f:)_p9k_t}$'\x1f'$_p9k__instant_prompt || return + } always { + exec {fd}>&- + } + zf_mv -f -- $tmp $prompt_file || return + } always { + (( $? )) && zf_rm -f -- $tmp 2>/dev/null + } +} + +typeset -gi __p9k_sh_glob +typeset -gi __p9k_ksh_arrays +typeset -gi __p9k_new_status +typeset -ga __p9k_new_pipestatus + +_p9k_save_status() { + local -i pipe + if (( !$+_p9k__line_finished )); then + : # SIGINT + elif (( !$+_p9k__preexec_cmd )); then + # Empty line, comment or parse error. + # + # This case is handled incorrectly: + # + # true | false + # | + # + # Here status=1 and pipestatus=(0 1). Ideally we should ignore pipestatus but we won't. + # + # This works though (unless pipefail is set): + # + # false | true + # | + # + # We get status=1 and pipestatus=(1 0) and correctly ignore pipestatus. + (( _p9k__status == __p9k_new_status )) && return + elif (( $__p9k_new_pipestatus[(I)$__p9k_new_status] )); then # just in case + local cmd=(${(z)_p9k__preexec_cmd}) + if [[ $#cmd != 0 && $cmd[1] != '!' && ${(Q)cmd[1]} != coproc ]]; then + local arg + for arg in ${(z)_p9k__preexec_cmd}; do + # '()' is for functions, *';' is for complex commands. + if [[ $arg == ('()'|'&&'|'||'|'&'|'&|'|'&!'|*';') ]]; then + pipe=0 + break + elif [[ $arg == *('|'|'|&')* ]]; then + pipe=1 + fi + done + fi + fi + _p9k__status=$__p9k_new_status + if (( pipe )); then + _p9k__pipestatus=($__p9k_new_pipestatus) + else + _p9k__pipestatus=($_p9k__status) + fi +} + +function _p9k_dump_state() { + local dir=${__p9k_dump_file:h} + [[ -d $dir ]] || mkdir -p -- $dir || return + [[ -w $dir ]] || return + local tmp=$__p9k_dump_file.tmp.$$ + local -i fd + sysopen -a -m 600 -o creat,trunc -u fd -- $tmp || return + { + { + typeset -g __p9k_cached_param_pat=$_p9k__param_pat + typeset -g __p9k_cached_param_sig=$_p9k__param_sig + typeset -pm __p9k_cached_param_pat __p9k_cached_param_sig >&$fd || return + unset __p9k_cached_param_pat __p9k_cached_param_sig + (( $+_p9k_preinit )) && { print -r -- $_p9k_preinit >&$fd || return } + print -r -- '_p9k_restore_state_impl() {' >&$fd || return + typeset -pm '_POWERLEVEL9K_*|_p9k_[^_]*|icons|OS|DEFAULT_COLOR|DEFAULT_COLOR_INVERTED' >&$fd || return + print -r -- '}' >&$fd || return + } always { + exec {fd}>&- + } + # `zf_mv -f src dst` fails on NTFS if `dst` is not writable, hence `zf_rm`. + zf_rm -f -- $__p9k_dump_file.zwc || return + zf_mv -f -- $tmp $__p9k_dump_file || return + zcompile -R -- $tmp.zwc $__p9k_dump_file || return + zf_mv -f -- $tmp.zwc $__p9k_dump_file.zwc || return + } always { + (( $? )) && zf_rm -f -- $tmp $tmp.zwc 2>/dev/null + } +} + +function _p9k_delete_instant_prompt() { + local user=${(%):-%n} + local root_dir=${__p9k_dump_file:h} + zf_rm -f -- $root_dir/p10k-instant-prompt-$user.zsh{,.zwc} ${root_dir}/p10k-$user/prompt-*(N) 2>/dev/null +} + +function _p9k_restore_state() { + { + [[ $__p9k_cached_param_pat == $_p9k__param_pat && $__p9k_cached_param_sig == $_p9k__param_sig ]] || return + (( $+functions[_p9k_restore_state_impl] )) || return + _p9k_restore_state_impl + return 0 + } always { + if (( $? )); then + if (( $+functions[_p9k_preinit] )); then + unfunction _p9k_preinit + (( $+functions[gitstatus_stop_p9k_] )) && gitstatus_stop_p9k_ POWERLEVEL9K + fi + _p9k_delete_instant_prompt + zf_rm -f -- $__p9k_dump_file{,.zwc} 2>/dev/null + elif [[ $__p9k_instant_prompt_param_sig != $_p9k__param_sig ]]; then + _p9k_delete_instant_prompt + _p9k_dumped_instant_prompt_sigs=() + fi + unset __p9k_cached_param_sig + } +} + +function _p9k_clear_instant_prompt() { + if (( $+__p9k_fd_0 )); then + exec 0<&$__p9k_fd_0 {__p9k_fd_0}>&- + unset __p9k_fd_0 + fi + exec 1>&$__p9k_fd_1 2>&$__p9k_fd_2 {__p9k_fd_1}>&- {__p9k_fd_2}>&- + unset __p9k_fd_1 __p9k_fd_2 + if (( _p9k__can_hide_cursor )); then + echoti civis + _p9k__cursor_hidden=1 + fi + if [[ -s $__p9k_instant_prompt_output ]]; then + { + local content + [[ $_POWERLEVEL9K_INSTANT_PROMPT == verbose ]] && content="$(<$__p9k_instant_prompt_output)" + local mark="${(e)${PROMPT_EOL_MARK-%B%S%#%s%b}}" + _p9k_prompt_length $mark + local -i fill=$((COLUMNS > _p9k__ret ? COLUMNS - _p9k__ret : 0)) + local cr=$'\r' + local sp="${(%):-%b%k%f%s%u$mark${(pl.$fill.. .)}$cr%b%k%f%s%u%E}" + print -rn -- $terminfo[rc]${(%):-%b%k%f%s%u}$terminfo[ed] + local unexpected=${${${(S)content//$'\e'*($'\a'|$'\e\\')}//$'\e[?'<->'c'}//$'\e['<->' q'} + if [[ -n $unexpected ]]; then + local omz1='[Oh My Zsh] Would you like to update? [Y/n]: ' + local omz2='Updating Oh My Zsh' + local omz3='https://shop.planetargon.com/collections/oh-my-zsh' + local omz4='There was an error updating. Try again later?' + if [[ -n ${${unexpected/$omz1}/$omz2*($omz3|$omz4)[^$'\n']#($'\n'|)} ]]; then + echo -E - "" + echo -E - "${(%):-[%3FWARNING%f]: Console output during zsh initialization detected.}" + echo -E - "" + echo -E - "${(%):-When using Powerlevel10k with instant prompt, console output during zsh}" + echo -E - "${(%):-initialization may indicate issues.}" + echo -E - "" + echo -E - "${(%):-You can:}" + echo -E - "" + echo -E - "${(%):- - %BRecommended%b: Change %B$__p9k_zshrc_u%b so that it does not perform console I/O}" + echo -E - "${(%):- after the instant prompt preamble. See the link below for details.}" + echo -E - "" + echo -E - "${(%):- * You %Bwill not%b see this error message again.}" + echo -E - "${(%):- * Zsh will start %Bquickly%b and prompt will update %Bsmoothly%b.}" + echo -E - "" + echo -E - "${(%):- - Suppress this warning either by running %Bp10k configure%b or by manually}" + echo -E - "${(%):- defining the following parameter:}" + echo -E - "" + echo -E - "${(%):- %3Ftypeset%f -g POWERLEVEL9K_INSTANT_PROMPT=quiet}" + echo -E - "" + echo -E - "${(%):- * You %Bwill not%b see this error message again.}" + echo -E - "${(%):- * Zsh will start %Bquickly%b but prompt will %Bjump down%b after initialization.}" + echo -E - "" + echo -E - "${(%):- - Disable instant prompt either by running %Bp10k configure%b or by manually}" + echo -E - "${(%):- defining the following parameter:}" + echo -E - "" + echo -E - "${(%):- %3Ftypeset%f -g POWERLEVEL9K_INSTANT_PROMPT=off}" + echo -E - "" + echo -E - "${(%):- * You %Bwill not%b see this error message again.}" + echo -E - "${(%):- * Zsh will start %Bslowly%b.}" + echo -E - "" + echo -E - "${(%):- - Do nothing.}" + echo -E - "" + echo -E - "${(%):- * You %Bwill%b see this error message every time you start zsh.}" + echo -E - "${(%):- * Zsh will start %Bquickly%b but prompt will %Bjump down%b after initialization.}" + echo -E - "" + echo -E - "${(%):-For details, see:}" + if (( _p9k_term_has_href )); then + echo - "${(%):-\e]8;;https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt\ahttps://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt\e]8;;\a}" + else + echo - "${(%):-https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt}" + fi + echo -E - "" + echo - "${(%):-%3F-- console output produced during zsh initialization follows --%f}" + echo -E - "" + fi + fi + cat -- $__p9k_instant_prompt_output + echo -nE - $sp + zf_rm -f -- $__p9k_instant_prompt_output + } 2>/dev/null + else + zf_rm -f -- $__p9k_instant_prompt_output 2>/dev/null + print -rn -- $terminfo[rc]${(%):-%b%k%f%s%u}$terminfo[ed] + fi + prompt_opts=(percent subst sp cr) + if [[ $_POWERLEVEL9K_DISABLE_INSTANT_PROMPT == 0 && $__p9k_instant_prompt_active == 2 ]]; then + >&2 echo -E - "" + >&2 echo -E - "${(%):-[%1FERROR%f]: When using Powerlevel10k with instant prompt, %Bprompt_cr%b must be unset.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):-You can:}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- - %BRecommended%b: call %Bp10k finalize%b at the end of %B$__p9k_zshrc_u%b.}" + >&2 echo -E - "${(%):- You can do this by running the following command:}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- %2Fecho%f %3F'(( ! \${+functions[p10k]\} )) || p10k finalize'%f >>! $__p9k_zshrc_u}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- * You %Bwill not%b see this error message again.}" + >&2 echo -E - "${(%):- * Zsh will start %Bquickly%b and %Bwithout%b prompt flickering.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- - Find where %Bprompt_cr%b option gets sets in your zsh configs and stop setting it.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- * You %Bwill not%b see this error message again.}" + >&2 echo -E - "${(%):- * Zsh will start %Bquickly%b and %Bwithout%b prompt flickering.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- - Disable instant prompt either by running %Bp10k configure%b or by manually}" + >&2 echo -E - "${(%):- defining the following parameter:}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- %3Ftypeset%f -g POWERLEVEL9K_INSTANT_PROMPT=off}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- * You %Bwill not%b see this error message again.}" + >&2 echo -E - "${(%):- * Zsh will start %Bslowly%b.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- - Do nothing.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- * You %Bwill%b see this error message every time you start zsh.}" + >&2 echo -E - "${(%):- * Zsh will start %Bquckly%b but %Bwith%b prompt flickering.}" + >&2 echo -E - "" + fi +} + +function _p9k_do_dump() { + eval "$__p9k_intro" + zle -F $1 + exec {1}>&- + (( _p9k__state_dump_fd )) || return + if (( ! _p9k__instant_prompt_disabled )); then + _p9k__instant_prompt_sig=$_p9k__cwd:$P9K_SSH:${(%):-%#} + _p9k_set_instant_prompt + _p9k_dump_instant_prompt + _p9k_dumped_instant_prompt_sigs[$_p9k__instant_prompt_sig]=1 + fi + _p9k_dump_state + _p9k__state_dump_scheduled=0 + _p9k__state_dump_fd=0 +} + +function _p9k_should_dump() { + (( __p9k_dumps_enabled && ! _p9k__state_dump_fd )) || return + (( _p9k__state_dump_scheduled || _p9k__prompt_idx == 1 )) && return + _p9k__instant_prompt_sig=$_p9k__cwd:$P9K_SSH:${(%):-%#} + (( ! $+_p9k_dumped_instant_prompt_sigs[$_p9k__instant_prompt_sig] )) +} + +# Must not run under `eval "$__p9k_intro_locale"`. Safe to run with any options. +function _p9k_restore_special_params() { + (( ! ${+_p9k__real_zle_rprompt_indent} )) || { + [[ -n "$_p9k__real_zle_rprompt_indent" ]] && + ZLE_RPROMPT_INDENT="$_p9k__real_zle_rprompt_indent" || + unset ZLE_RPROMPT_INDENT + unset _p9k__real_zle_rprompt_indent + } + (( ! ${+_p9k__real_lc_ctype} )) || { + LC_CTYPE="$_p9k__real_lc_ctype" + unset _p9k__real_lc_ctype + } + (( ! ${+_p9k__real_lc_all} )) || { + LC_ALL="$_p9k__real_lc_all" + unset _p9k__real_lc_all + } +} + +function _p9k_on_expand() { + (( _p9k__expanded && ! ${+__p9k_instant_prompt_active} )) && [[ "${langinfo[CODESET]}" == (utf|UTF)(-|)8 ]] && return + + eval "$__p9k_intro_no_locale" + + if [[ $langinfo[CODESET] != (utf|UTF)(-|)8 ]]; then + _p9k_restore_special_params + if [[ $langinfo[CODESET] != (utf|UTF)(-|)8 ]] && _p9k_init_locale; then + if [[ -n $LC_ALL ]]; then + _p9k__real_lc_all=$LC_ALL + LC_ALL=$__p9k_locale + else + _p9k__real_lc_ctype=$LC_CTYPE + LC_CTYPE=$__p9k_locale + fi + fi + fi + + (( _p9k__expanded && ! $+__p9k_instant_prompt_active )) && return + + eval "$__p9k_intro_locale" + + if (( ! _p9k__expanded )); then + if _p9k_should_dump; then + sysopen -o cloexec -ru _p9k__state_dump_fd /dev/null + zle -F $_p9k__state_dump_fd _p9k_do_dump + fi + + if (( ! $+P9K_TTY )); then + typeset -gx P9K_TTY=old + if (( _POWERLEVEL9K_NEW_TTY_MAX_AGE_SECONDS < 0 )); then + P9K_TTY=new + else + local -a stat + if zstat -A stat +ctime -- $TTY 2>/dev/null && + (( EPOCHREALTIME - stat[1] < _POWERLEVEL9K_NEW_TTY_MAX_AGE_SECONDS )); then + P9K_TTY=new + fi + fi + fi + + __p9k_reset_state=1 + + if (( _POWERLEVEL9K_PROMPT_ADD_NEWLINE )); then + if [[ $P9K_TTY == new ]]; then + _p9k__empty_line_i=3 + _p9k__display_v[2]=hide + elif [[ -z $_p9k_transient_prompt && $+functions[p10k-on-post-prompt] == 0 ]]; then + _p9k__empty_line_i=3 + _p9k__display_v[2]=print + else + unset _p9k__empty_line_i + _p9k__display_v[2]=show + fi + fi + + if (( _POWERLEVEL9K_SHOW_RULER )); then + if [[ $P9K_TTY == new ]]; then + _p9k__ruler_i=3 + _p9k__display_v[4]=hide + elif [[ -z $_p9k_transient_prompt && $+functions[p10k-on-post-prompt] == 0 ]]; then + _p9k__ruler_i=3 + _p9k__display_v[4]=print + else + unset _p9k__ruler_i + _p9k__display_v[4]=show + fi + fi + + (( _p9k__fully_initialized )) || _p9k_wrap_widgets + fi + + if (( $+__p9k_instant_prompt_active )); then + _p9k_clear_instant_prompt + unset __p9k_instant_prompt_active + fi + + if (( ! _p9k__expanded )); then + _p9k__expanded=1 + + (( _p9k__fully_initialized || ! $+functions[p10k-on-init] )) || p10k-on-init + + local pat idx var + for pat idx var in $_p9k_show_on_command; do + _p9k_display_segment $idx $var hide + done + + (( $+functions[p10k-on-pre-prompt] )) && p10k-on-pre-prompt + + if zle; then + local -a P9K_COMMANDS=($_p9k__last_commands) + local pat idx var + for pat idx var in $_p9k_show_on_command; do + if (( $P9K_COMMANDS[(I)$pat] )); then + _p9k_display_segment $idx $var show + else + _p9k_display_segment $idx $var hide + fi + done + if (( $+functions[p10k-on-post-widget] )); then + local -h WIDGET + unset WIDGET + p10k-on-post-widget + fi + else + if [[ $_p9k__display_v[2] == print && -n $_p9k_t[_p9k_empty_line_idx] ]]; then + print -rnP -- '%b%k%f%E'$_p9k_t[_p9k_empty_line_idx] + fi + if [[ $_p9k__display_v[4] == print ]]; then + () { + local ruler=$_p9k_t[_p9k_ruler_idx] + local -i _p9k__clm=COLUMNS _p9k__ind=${ZLE_RPROMPT_INDENT:-1} + (( __p9k_ksh_arrays )) && setopt ksh_arrays + (( __p9k_sh_glob )) && setopt sh_glob + setopt prompt_subst + print -rnP -- '%b%k%f%E'$ruler + } + fi + fi + + __p9k_reset_state=0 + _p9k__fully_initialized=1 + fi +} +functions -M _p9k_on_expand + +_p9k_precmd_impl() { + eval "$__p9k_intro" + + (( __p9k_enabled )) || return + + if ! zle || [[ -z $_p9k__param_sig ]]; then + if zle; then + __p9k_new_status=0 + __p9k_new_pipestatus=(0) + else + _p9k__must_restore_prompt=0 + fi + + if _p9k_must_init; then + local -i instant_prompt_disabled + if (( !__p9k_configured )); then + __p9k_configured=1 + if [[ -z "${parameters[(I)POWERLEVEL9K_*~(POWERLEVEL9K_MODE|POWERLEVEL9K_CONFIG_FILE)]}" ]]; then + _p9k_can_configure -q + local -i ret=$? + if (( ret == 2 && $+__p9k_instant_prompt_active )); then + _p9k_clear_instant_prompt + unset __p9k_instant_prompt_active + _p9k_delete_instant_prompt + zf_rm -f -- $__p9k_dump_file{,.zwc} 2>/dev/null + () { + local key + while true; do + [[ -t 2 ]] + read -t0 -k key || break + done 2>/dev/null + } + _p9k_can_configure -q + ret=$? + fi + if (( ret == 0 )); then + ( + source "$__p9k_root_dir"/internal/wizard.zsh + ) + if (( $? )); then + instant_prompt_disabled=1 + else + source "$__p9k_cfg_path" + _p9k__force_must_init=1 + _p9k_must_init + fi + fi + fi + fi + typeset -gi _p9k__instant_prompt_disabled=instant_prompt_disabled + _p9k_init + fi + + if (( _p9k__timer_start )); then + typeset -gF P9K_COMMAND_DURATION_SECONDS=$((EPOCHREALTIME - _p9k__timer_start)) + else + unset P9K_COMMAND_DURATION_SECONDS + fi + _p9k_save_status + + if [[ $_p9k__preexec_cmd == [[:space:]]#(clear([[:space:]]##-(|x)(|T[a-zA-Z0-9-_\'\"]#))#|reset)[[:space:]]# && + $_p9k__status == 0 ]]; then + P9K_TTY=new + elif [[ $P9K_TTY == new && $_p9k__fully_initialized == 1 ]] && ! zle; then + P9K_TTY=old + fi + + _p9k__timer_start=0 + _p9k__region_active=0 + + unset _p9k__line_finished _p9k__preexec_cmd + _p9k__keymap=main + _p9k__zle_state=insert + + (( ++_p9k__prompt_idx )) + fi + + _p9k_fetch_cwd + + _p9k__refresh_reason=precmd + __p9k_reset_state=1 + + local -i fast_vcs + if (( _p9k_vcs_index && $+GITSTATUS_DAEMON_PID_POWERLEVEL9K )); then + if [[ $_p9k__cwd != $~_POWERLEVEL9K_VCS_DISABLED_DIR_PATTERN ]]; then + local -F start_time=EPOCHREALTIME + unset _p9k__vcs + unset _p9k__vcs_timeout + _p9k_vcs_gitstatus + local -i fast_vcs=1 + fi + fi + + (( $+functions[_p9k_async_segments_compute] )) && _p9k_async_segments_compute + + _p9k__expanded=0 + + _p9k_set_prompt + + _p9k__refresh_reason='' + + if [[ $precmd_functions[1] != _p9k_do_nothing && $precmd_functions[(I)_p9k_do_nothing] != 0 ]]; then + precmd_functions=(_p9k_do_nothing ${(@)precmd_functions:#_p9k_do_nothing}) + fi + if [[ $precmd_functions[-1] != _p9k_precmd && $precmd_functions[(I)_p9k_precmd] != 0 ]]; then + precmd_functions=(${(@)precmd_functions:#_p9k_precmd} _p9k_precmd) + fi + if [[ $preexec_functions[1] != _p9k_preexec1 && $preexec_functions[(I)_p9k_preexec1] != 0 ]]; then + preexec_functions=(_p9k_preexec1 ${(@)preexec_functions:#_p9k_preexec1}) + fi + if [[ $preexec_functions[-1] != _p9k_preexec2 && $preexec_functions[(I)_p9k_preexec2] != 0 ]]; then + preexec_functions=(${(@)preexec_functions:#_p9k_preexec2} _p9k_preexec2) + fi + + if (( fast_vcs && _p9k_vcs_index && $+GITSTATUS_DAEMON_PID_POWERLEVEL9K )); then + if (( $+_p9k__vcs_timeout )); then + (( _p9k__vcs_timeout = _POWERLEVEL9K_VCS_MAX_SYNC_LATENCY_SECONDS + start_time - EPOCHREALTIME )) + (( _p9k__vcs_timeout >= 0 )) || (( _p9k__vcs_timeout = 0 )) + gitstatus_process_results_p9k_ -t $_p9k__vcs_timeout POWERLEVEL9K + fi + if (( ! $+_p9k__vcs )); then + local _p9k__prompt _p9k__prompt_side=$_p9k_vcs_side _p9k__segment_name=vcs + local -i _p9k__has_upglob _p9k__segment_index=_p9k_vcs_index _p9k__line_index=_p9k_vcs_line_index + _p9k_vcs_render + typeset -g _p9k__vcs=$_p9k__prompt + fi + fi + + _p9k_worker_receive + __p9k_reset_state=0 +} + +_p9k_trapint() { + if (( __p9k_enabled )); then + eval "$__p9k_intro" + zle && _p9k_on_widget_zle-line-finish int + fi + return 0 +} + +_p9k_precmd() { + __p9k_new_status=$? + __p9k_new_pipestatus=($pipestatus) + + trap ":" INT + + [[ -o ksh_arrays ]] && __p9k_ksh_arrays=1 || __p9k_ksh_arrays=0 + [[ -o sh_glob ]] && __p9k_sh_glob=1 || __p9k_sh_glob=0 + _p9k_restore_special_params + + _p9k_precmd_impl + + [[ ${+__p9k_instant_prompt_active} == 0 || -o no_prompt_cr ]] || __p9k_instant_prompt_active=2 + setopt no_local_options no_prompt_bang prompt_percent prompt_subst prompt_cr prompt_sp + + # See https://www.zsh.org/mla/workers/2020/msg00612.html for the reason behind __p9k_trapint. + typeset -g __p9k_trapint='_p9k_trapint; return 130' + trap "$__p9k_trapint" INT +} + +function _p9k_reset_prompt() { + if (( __p9k_reset_state != 1 )) && zle && [[ -z $_p9k__line_finished ]]; then + __p9k_reset_state=0 + setopt prompt_subst + (( __p9k_ksh_arrays )) && setopt ksh_arrays + (( __p9k_sh_glob )) && setopt sh_glob + (( _p9k__can_hide_cursor )) && echoti civis + { + zle .reset-prompt + zle -R + } always { + (( _p9k__can_hide_cursor )) && echoti cnorm + _p9k__cursor_hidden=0 + } + fi +} + +# Does ZSH have a certain off-by-one bug that triggers when PROMPT overflows to a new line? +# +# Bug: https://github.com/zsh-users/zsh/commit/d8d9fee137a5aa2cf9bf8314b06895bfc2a05518. +# ZSH_PATCHLEVEL=zsh-5.4.2-159-gd8d9fee13. Released in 5.5. +# +# Fix: https://github.com/zsh-users/zsh/commit/64d13738357c9b9c212adbe17f271716abbcf6ea. +# ZSH_PATCHLEVEL=zsh-5.7.1-50-g64d137383. +# +# Test: PROMPT="${(pl:$((COLUMNS))::-:)}<%1(l.%2(l.FAIL.PASS).FAIL)> " zsh -dfis <<<exit +# Workaround: PROMPT="${(pl:$((COLUMNS))::-:)}%{%G%}<%1(l.%2(l.FAIL.PASS).FAIL)> " zsh -dfis <<<exit +function _p9k_prompt_overflow_bug() { + [[ $ZSH_PATCHLEVEL =~ '^zsh-5\.4\.2-([0-9]+)-' ]] && return $(( match[1] < 159 )) + [[ $ZSH_PATCHLEVEL =~ '^zsh-5\.7\.1-([0-9]+)-' ]] && return $(( match[1] >= 50 )) + is-at-least 5.5 && ! is-at-least 5.7.2 +} + +typeset -g _p9k__param_pat +typeset -g _p9k__param_sig + +_p9k_init_vars() { + typeset -gF _p9k__gcloud_last_fetch_ts + typeset -g _p9k_gcloud_configuration + typeset -g _p9k_gcloud_account + typeset -g _p9k_gcloud_project_id + typeset -g _p9k_gcloud_project_name + + typeset -gi _p9k_term_has_href + + typeset -gi _p9k_vcs_index + typeset -gi _p9k_vcs_line_index + typeset -g _p9k_vcs_side + + typeset -ga _p9k_taskwarrior_meta_files + typeset -ga _p9k_taskwarrior_meta_non_files + typeset -g _p9k_taskwarrior_meta_sig + typeset -g _p9k_taskwarrior_data_dir + typeset -g _p9k__taskwarrior_functional=1 + typeset -ga _p9k_taskwarrior_data_files + typeset -ga _p9k_taskwarrior_data_non_files + typeset -g _p9k_taskwarrior_data_sig + typeset -gA _p9k_taskwarrior_counters + + typeset -ga _p9k_asdf_meta_files + typeset -ga _p9k_asdf_meta_non_files + typeset -g _p9k_asdf_meta_sig + + # example: (ruby lua chubaka) + typeset -ga _p9k_asdf_plugins + + # example: (.ruby-version "ruby 1 chubaka 0") + # + # - "1" means parse-legacy-file is present + # - "chubaka" is another plugin that claims to be able to parse .ruby-version + typeset -gA _p9k_asdf_file_info + + # dir => mtime ':' ${(pj:\0:)files} + typeset -gA _p9k__asdf_dir2files + + # :file => mtime ':' ${(pj:\0:)tool_versions} + # plugin:file => mtime ':' version + typeset -gA _p9k_asdf_file2versions + + # filepath => mtime ':' word + typeset -gA _p9k__read_word_cache + # filepath:prefix => mtime ':' versions + typeset -gA _p9k__read_pyenv_like_version_file_cache + + # _p9k__parent_dirs and _p9k__parent_mtimes are parallel arrays. They are updated + # together with _p9k__cwd. _p9k__parent_mtimes[i] is mtime for _p9k__parent_dirs[i]. + # + # When _p9k__cwd is / or ~, both arrays are empty. When _p9k__cwd is ~/foo/bar, + # _p9k__parent_dirs is (/home/user/foo/bar /home/user/foo). When _p9k__cwd is + # /foo/bar, it's (/foo/bar /foo). + # + # $_p9k__parent_mtimes_i[i] == "$i:$_p9k__parent_mtimes[i]" + # $_p9k__parent_mtimes_s == "$_p9k__parent_mtimes_i". + typeset -ga _p9k__parent_dirs + typeset -ga _p9k__parent_mtimes + typeset -ga _p9k__parent_mtimes_i + typeset -g _p9k__parent_mtimes_s + + typeset -g _p9k__cwd + typeset -g _p9k__cwd_a + + # dir/pattern => dir mtime ':' num_matches + typeset -gA _p9k__glob_cache + + # dir/pattern => space-separated parent dir mtimes ' :' the first matching parent dir + # Note: ' :' is indeed the delimiter. + typeset -gA _p9k__upsearch_cache + + typeset -g _p9k_timewarrior_dir + typeset -gi _p9k_timewarrior_dir_mtime + typeset -gi _p9k_timewarrior_file_mtime + typeset -g _p9k_timewarrior_file_name + typeset -gA _p9k__prompt_char_saved + typeset -g _p9k__worker_pid + typeset -g _p9k__worker_req_fd + typeset -g _p9k__worker_resp_fd + typeset -g _p9k__worker_shell_pid + typeset -g _p9k__worker_file_prefix + typeset -gA _p9k__worker_request_map + typeset -ga _p9k__segment_cond_left + typeset -ga _p9k__segment_cond_right + typeset -ga _p9k__segment_val_left + typeset -ga _p9k__segment_val_right + typeset -ga _p9k_show_on_command + typeset -g _p9k__last_buffer + typeset -ga _p9k__last_commands + typeset -gi _p9k__fully_initialized + typeset -gi _p9k__must_restore_prompt + typeset -gi _p9k__restore_prompt_fd + typeset -gi _p9k__can_hide_cursor=$(( $+terminfo[civis] && $+terminfo[cnorm] )) + typeset -gi _p9k__cursor_hidden + typeset -gi _p9k__non_hermetic_expansion + typeset -g _p9k__time + typeset -g _p9k__date + typeset -gA _p9k_dumped_instant_prompt_sigs + typeset -g _p9k__instant_prompt_sig + typeset -g _p9k__instant_prompt + typeset -gi _p9k__state_dump_scheduled + typeset -gi _p9k__state_dump_fd + typeset -gi _p9k__prompt_idx + typeset -gi _p9k_reset_on_line_finish + typeset -gF _p9k__timer_start + typeset -gi _p9k__status + typeset -ga _p9k__pipestatus + typeset -g _p9k__ret + typeset -g _p9k__cache_key + typeset -ga _p9k__cache_val + typeset -g _p9k__cache_stat_meta + typeset -g _p9k__cache_stat_fprint + typeset -g _p9k__cache_fprint_key + typeset -gA _p9k_cache + typeset -gA _p9k__cache_ephemeral + typeset -ga _p9k_t + typeset -g _p9k__n + typeset -gi _p9k__i + typeset -g _p9k__bg + typeset -ga _p9k_left_join + typeset -ga _p9k_right_join + typeset -g _p9k__public_ip + typeset -g _p9k__todo_file + typeset -g _p9k__git_dir + # git workdir => 1 if gitstatus is slow on it, 0 if it's fast. + typeset -gA _p9k_git_slow + # git workdir => the last state we've seen for it + typeset -gA _p9k__gitstatus_last + typeset -gF _p9k__gitstatus_start_time + typeset -g _p9k__prompt + typeset -g _p9k__rprompt + typeset -g _p9k__lprompt + typeset -g _p9k__prompt_side + typeset -g _p9k__segment_name + typeset -gi _p9k__segment_index + typeset -gi _p9k__line_index + typeset -g _p9k__refresh_reason + typeset -gi _p9k__region_active + typeset -ga _p9k_line_segments_left + typeset -ga _p9k_line_segments_right + typeset -ga _p9k_line_prefix_left + typeset -ga _p9k_line_prefix_right + typeset -ga _p9k_line_suffix_left + typeset -ga _p9k_line_suffix_right + typeset -ga _p9k_line_never_empty_right + typeset -ga _p9k_line_gap_post + typeset -g _p9k__xy + typeset -g _p9k__clm + typeset -g _p9k__p + typeset -gi _p9k__x + typeset -gi _p9k__y + typeset -gi _p9k__m + typeset -gi _p9k__d + typeset -gi _p9k__h + typeset -gi _p9k__ind + typeset -g _p9k_gap_pre + typeset -gi _p9k__ruler_i=3 + typeset -gi _p9k_ruler_idx + typeset -gi _p9k__empty_line_i=3 + typeset -gi _p9k_empty_line_idx + typeset -g _p9k_prompt_prefix_left + typeset -g _p9k_prompt_prefix_right + typeset -g _p9k_prompt_suffix_left + typeset -g _p9k_prompt_suffix_right + typeset -gi _p9k_emulate_zero_rprompt_indent + typeset -gA _p9k_battery_states + typeset -g _p9k_os + typeset -g _p9k_os_icon + typeset -g _p9k_color1 + typeset -g _p9k_color2 + typeset -g _p9k__s + typeset -g _p9k__ss + typeset -g _p9k__sss + typeset -g _p9k__v + typeset -g _p9k__c + typeset -g _p9k__e + typeset -g _p9k__w + typeset -gi _p9k__dir_len + typeset -gi _p9k_num_cpus + typeset -g _p9k__keymap + typeset -g _p9k__zle_state + typeset -g _p9k_uname + typeset -g _p9k_uname_o + typeset -g _p9k_uname_m + typeset -g _p9k_transient_prompt + typeset -g _p9k__last_prompt_pwd + typeset -gA _p9k_display_k + typeset -ga _p9k__display_v + + typeset -gA _p9k__dotnet_stat_cache + typeset -gA _p9k__dir_stat_cache + typeset -gi _p9k__expanded + typeset -gi _p9k__force_must_init + + typeset -g P9K_VISUAL_IDENTIFIER + typeset -g P9K_CONTENT + typeset -g P9K_GAP + typeset -g P9K_PROMPT=regular +} + +_p9k_init_params() { + _p9k_declare -F POWERLEVEL9K_GCLOUD_REFRESH_PROJECT_NAME_SECONDS 60 + + # invarint: _POWERLEVEL9K_INSTANT_PROMPT == (verbose|quiet|off) + # invariant: [[ ($_POWERLEVEL9K_INSTANT_PROMPT == off) == $_POWERLEVEL9K_DISABLE_INSTANT_PROMPT ]] + _p9k_declare -s POWERLEVEL9K_INSTANT_PROMPT # verbose, quiet, off + if [[ $_POWERLEVEL9K_INSTANT_PROMPT == off ]]; then + typeset -gi _POWERLEVEL9K_DISABLE_INSTANT_PROMPT=1 + else + _p9k_declare -b POWERLEVEL9K_DISABLE_INSTANT_PROMPT 0 + if (( _POWERLEVEL9K_DISABLE_INSTANT_PROMPT )); then + _POWERLEVEL9K_INSTANT_PROMPT=off + elif [[ $_POWERLEVEL9K_INSTANT_PROMPT != quiet ]]; then + _POWERLEVEL9K_INSTANT_PROMPT=verbose + fi + fi + + (( _POWERLEVEL9K_DISABLE_INSTANT_PROMPT )) && _p9k__instant_prompt_disabled=1 + + _p9k_declare -s POWERLEVEL9K_TRANSIENT_PROMPT off + [[ $_POWERLEVEL9K_TRANSIENT_PROMPT == (off|always|same-dir) ]] || _POWERLEVEL9K_TRANSIENT_PROMPT=off + + _p9k_declare -s POWERLEVEL9K_WORKER_LOG_LEVEL + _p9k_declare -i POWERLEVEL9K_COMMANDS_MAX_TOKEN_COUNT 64 + _p9k_declare -a POWERLEVEL9K_HOOK_WIDGETS -- + _p9k_declare -b POWERLEVEL9K_TODO_HIDE_ZERO_TOTAL 0 + _p9k_declare -b POWERLEVEL9K_TODO_HIDE_ZERO_FILTERED 0 + _p9k_declare -b POWERLEVEL9K_DISABLE_HOT_RELOAD 0 + _p9k_declare -F POWERLEVEL9K_NEW_TTY_MAX_AGE_SECONDS 5 + _p9k_declare -i POWERLEVEL9K_INSTANT_PROMPT_COMMAND_LINES 1 + _p9k_declare -a POWERLEVEL9K_LEFT_PROMPT_ELEMENTS -- context dir vcs + _p9k_declare -a POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS -- status root_indicator background_jobs history time + _p9k_declare -b POWERLEVEL9K_DISABLE_RPROMPT 0 + _p9k_declare -b POWERLEVEL9K_PROMPT_ADD_NEWLINE 0 + _p9k_declare -b POWERLEVEL9K_PROMPT_ON_NEWLINE 0 + _p9k_declare -b POWERLEVEL9K_RPROMPT_ON_NEWLINE 0 + _p9k_declare -b POWERLEVEL9K_SHOW_RULER 0 + _p9k_declare -i POWERLEVEL9K_PROMPT_ADD_NEWLINE_COUNT 1 + _p9k_declare -s POWERLEVEL9K_COLOR_SCHEME dark + _p9k_declare -s POWERLEVEL9K_GITSTATUS_DIR "" + _p9k_declare -s POWERLEVEL9K_VCS_DISABLED_WORKDIR_PATTERN + _p9k_declare -b POWERLEVEL9K_VCS_SHOW_SUBMODULE_DIRTY 0 + _p9k_declare -i POWERLEVEL9K_VCS_SHORTEN_LENGTH + _p9k_declare -i POWERLEVEL9K_VCS_SHORTEN_MIN_LENGTH + _p9k_declare -s POWERLEVEL9K_VCS_SHORTEN_STRATEGY + if [[ $langinfo[CODESET] == (utf|UTF)(-|)8 ]]; then + _p9k_declare -e POWERLEVEL9K_VCS_SHORTEN_DELIMITER '\u2026' + else + _p9k_declare -e POWERLEVEL9K_VCS_SHORTEN_DELIMITER '..' + fi + _p9k_declare -b POWERLEVEL9K_VCS_CONFLICTED_STATE 0 + _p9k_declare -b POWERLEVEL9K_HIDE_BRANCH_ICON 0 + _p9k_declare -b POWERLEVEL9K_VCS_HIDE_TAGS 0 + _p9k_declare -i POWERLEVEL9K_CHANGESET_HASH_LENGTH 8 + # Specifies the maximum number of elements in the cache. When the cache grows over this limit, + # it gets cleared. This is meant to avoid memory leaks when a rogue prompt is filling the cache + # with data. + _p9k_declare -i POWERLEVEL9K_MAX_CACHE_SIZE 10000 + _p9k_declare -e POWERLEVEL9K_ANACONDA_LEFT_DELIMITER "(" + _p9k_declare -e POWERLEVEL9K_ANACONDA_RIGHT_DELIMITER ")" + _p9k_declare -b POWERLEVEL9K_ANACONDA_SHOW_PYTHON_VERSION 1 + _p9k_declare -b POWERLEVEL9K_BACKGROUND_JOBS_VERBOSE 1 + _p9k_declare -b POWERLEVEL9K_BACKGROUND_JOBS_VERBOSE_ALWAYS 0 + _p9k_declare -b POWERLEVEL9K_DISK_USAGE_ONLY_WARNING 0 + _p9k_declare -i POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL 90 + _p9k_declare -i POWERLEVEL9K_DISK_USAGE_CRITICAL_LEVEL 95 + _p9k_declare -i POWERLEVEL9K_BATTERY_LOW_THRESHOLD 10 + _p9k_declare -i POWERLEVEL9K_BATTERY_HIDE_ABOVE_THRESHOLD 999 + _p9k_declare -b POWERLEVEL9K_BATTERY_VERBOSE 1 + _p9k_declare -a POWERLEVEL9K_BATTERY_LEVEL_BACKGROUND -- + _p9k_declare -a POWERLEVEL9K_BATTERY_LEVEL_FOREGROUND -- + case $parameters[POWERLEVEL9K_BATTERY_STAGES] in + scalar*) typeset -ga _POWERLEVEL9K_BATTERY_STAGES=("${(@s::)${(g::)POWERLEVEL9K_BATTERY_STAGES}}");; + array*) typeset -ga _POWERLEVEL9K_BATTERY_STAGES=("${(@g::)POWERLEVEL9K_BATTERY_STAGES}");; + esac + local state + for state in CHARGED CHARGING LOW DISCONNECTED; do + local var=POWERLEVEL9K_BATTERY_${state}_STAGES + case $parameters[$var] in + scalar*) eval "typeset -ga _$var=(${(@qq)${(@s::)${(g::)${(P)var}}}})";; + array*) eval "typeset -ga _$var=(${(@qq)${(@g::)${(@P)var}}})";; + *) eval "typeset -ga _$var=(${(@qq)_POWERLEVEL9K_BATTERY_STAGES})";; + esac + local var=POWERLEVEL9K_BATTERY_${state}_LEVEL_BACKGROUND + case $parameters[$var] in + array*) eval "typeset -ga _$var=(${(@qq)${(@P)var}})";; + *) eval "typeset -ga _$var=(${(@qq)_POWERLEVEL9K_BATTERY_LEVEL_BACKGROUND})";; + esac + local var=POWERLEVEL9K_BATTERY_${state}_LEVEL_FOREGROUND + case $parameters[$var] in + array*) eval "typeset -ga _$var=(${(@qq)${(@P)var}})";; + *) eval "typeset -ga _$var=(${(@qq)_POWERLEVEL9K_BATTERY_LEVEL_FOREGROUND})";; + esac + done + _p9k_declare -F POWERLEVEL9K_PUBLIC_IP_TIMEOUT 300 + _p9k_declare -a POWERLEVEL9K_PUBLIC_IP_METHODS -- dig curl wget + _p9k_declare -e POWERLEVEL9K_PUBLIC_IP_NONE "" + _p9k_declare -s POWERLEVEL9K_PUBLIC_IP_HOST "https://v4.ident.me/" + _p9k_declare -s POWERLEVEL9K_PUBLIC_IP_VPN_INTERFACE "" + _p9k_segment_in_use public_ip || _POWERLEVEL9K_PUBLIC_IP_VPN_INTERFACE= + _p9k_declare -b POWERLEVEL9K_ALWAYS_SHOW_CONTEXT 0 + _p9k_declare -b POWERLEVEL9K_ALWAYS_SHOW_USER 0 + _p9k_declare -e POWERLEVEL9K_CONTEXT_TEMPLATE "%n@%m" + _p9k_declare -e POWERLEVEL9K_USER_TEMPLATE "%n" + _p9k_declare -e POWERLEVEL9K_HOST_TEMPLATE "%m" + _p9k_declare -F POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD 3 + _p9k_declare -i POWERLEVEL9K_COMMAND_EXECUTION_TIME_PRECISION 2 + # Other options: "d h m s". + _p9k_declare -s POWERLEVEL9K_COMMAND_EXECUTION_TIME_FORMAT "H:M:S" + _p9k_declare -e POWERLEVEL9K_HOME_FOLDER_ABBREVIATION "~" + _p9k_declare -b POWERLEVEL9K_DIR_PATH_ABSOLUTE 0 + _p9k_declare -s POWERLEVEL9K_DIR_SHOW_WRITABLE '' + case $_POWERLEVEL9K_DIR_SHOW_WRITABLE in + true) _POWERLEVEL9K_DIR_SHOW_WRITABLE=1;; + v2) _POWERLEVEL9K_DIR_SHOW_WRITABLE=2;; + *) _POWERLEVEL9K_DIR_SHOW_WRITABLE=0;; + esac + typeset -gi _POWERLEVEL9K_DIR_SHOW_WRITABLE + _p9k_declare -b POWERLEVEL9K_DIR_OMIT_FIRST_CHARACTER 0 + _p9k_declare -b POWERLEVEL9K_DIR_HYPERLINK 0 + _p9k_declare -s POWERLEVEL9K_SHORTEN_STRATEGY "" + local markers=( + .bzr + .citc + .git + .hg + .node-version + .python-version + .ruby-version + .shorten_folder_marker + .svn + .terraform + CVS + Cargo.toml + composer.json + go.mod + package.json + ) + _p9k_declare -s POWERLEVEL9K_SHORTEN_FOLDER_MARKER "(${(j:|:)markers})" + # Shorten directory if it's longer than this even if there is space for it. + # The value can be either absolute (e.g., '80') or a percentage of terminal + # width (e.g, '50%'). If empty, directory will be shortened only when prompt + # doesn't fit. Applies only when POWERLEVEL9K_SHORTEN_STRATEGY=truncate_to_unique. + _p9k_declare -s POWERLEVEL9K_DIR_MAX_LENGTH 0 + # Individual elements are patterns. They are expanded with the options set + # by `emulate zsh && setopt extended_glob`. + _p9k_declare -a POWERLEVEL9K_DIR_PACKAGE_FILES -- package.json composer.json + # When dir is on the last prompt line, try to shorten it enough to leave at least this many + # columns for typing commands. Applies only when POWERLEVEL9K_SHORTEN_STRATEGY=truncate_to_unique. + _p9k_declare -i POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS 40 + # When dir is on the last prompt line, try to shorten it enough to leave at least + # COLUMNS * POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT * 0.01 columns for typing commands. Applies + # only when POWERLEVEL9K_SHORTEN_STRATEGY=truncate_to_unique. + _p9k_declare -F POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT 50 + # POWERLEVEL9K_DIR_CLASSES allow you to specify custom styling and icons for different + # directories. + # + # POWERLEVEL9K_DIR_CLASSES must be an array with 3 * N elements. Each triplet consists of: + # + # 1. A pattern against which the current directory is matched. Matching is done with + # extended_glob option enabled. + # 2. Directory class for the purpose of styling. + # 3. Icon. + # + # Triplets are tried in order. The first triplet whose pattern matches $PWD wins. If there are no + # matches, there will be no icon and the styling is done according to POWERLEVEL9K_DIR_BACKGROUND, + # POWERLEVEL9K_DIR_FOREGROUND, etc. + # + # Example: + # + # POWERLEVEL9K_DIR_CLASSES=( + # '~/work(/*)#' WORK '(╯°□°)╯︵ ┻━┻' + # '~(/*)#' HOME '⌂' + # '*' DEFAULT '') + # + # POWERLEVEL9K_DIR_WORK_BACKGROUND=red + # POWERLEVEL9K_DIR_HOME_BACKGROUND=blue + # POWERLEVEL9K_DIR_DEFAULT_BACKGROUND=yellow + # + # With these settings, the current directory in the prompt may look like this: + # + # (╯°□°)╯︵ ┻━┻ ~/work/projects/important/urgent + # + # ⌂ ~/best/powerlevel10k + _p9k_declare -a POWERLEVEL9K_DIR_CLASSES + _p9k_declare -i POWERLEVEL9K_SHORTEN_DELIMITER_LENGTH + _p9k_declare -e POWERLEVEL9K_SHORTEN_DELIMITER + _p9k_declare -s POWERLEVEL9K_DIR_TRUNCATE_BEFORE_MARKER '' + case $_POWERLEVEL9K_DIR_TRUNCATE_BEFORE_MARKER in + first) ;; + last) ;; + true) _POWERLEVEL9K_DIR_TRUNCATE_BEFORE_MARKER=last;; + *) _POWERLEVEL9K_DIR_TRUNCATE_BEFORE_MARKER=;; + esac + [[ -z $_POWERLEVEL9K_SHORTEN_FOLDER_MARKER ]] && _POWERLEVEL9K_DIR_TRUNCATE_BEFORE_MARKER= + _p9k_declare -i POWERLEVEL9K_SHORTEN_DIR_LENGTH + _p9k_declare -s POWERLEVEL9K_IP_INTERFACE "" + : ${_POWERLEVEL9K_IP_INTERFACE:='.*'} + _p9k_segment_in_use ip || _POWERLEVEL9K_IP_INTERFACE= + _p9k_declare -s POWERLEVEL9K_VPN_IP_INTERFACE "(wg|(.*tun))[0-9]*" + : ${_POWERLEVEL9K_VPN_IP_INTERFACE:='.*'} + _p9k_segment_in_use vpn_ip || _POWERLEVEL9K_VPN_IP_INTERFACE= + _p9k_declare -b POWERLEVEL9K_VPN_IP_SHOW_ALL 0 + _p9k_declare -i POWERLEVEL9K_LOAD_WHICH 5 + case $_POWERLEVEL9K_LOAD_WHICH in + 1) _POWERLEVEL9K_LOAD_WHICH=1;; + 15) _POWERLEVEL9K_LOAD_WHICH=3;; + *) _POWERLEVEL9K_LOAD_WHICH=2;; + esac + _p9k_declare -b POWERLEVEL9K_NODE_VERSION_PROJECT_ONLY 0 + _p9k_declare -b POWERLEVEL9K_PHP_VERSION_PROJECT_ONLY 0 + _p9k_declare -b POWERLEVEL9K_DOTNET_VERSION_PROJECT_ONLY 1 + _p9k_declare -b POWERLEVEL9K_GO_VERSION_PROJECT_ONLY 1 + _p9k_declare -b POWERLEVEL9K_RUST_VERSION_PROJECT_ONLY 1 + _p9k_declare -b POWERLEVEL9K_JAVA_VERSION_PROJECT_ONLY 0 + _p9k_declare -b POWERLEVEL9K_NODENV_PROMPT_ALWAYS_SHOW 0 + _p9k_declare -a POWERLEVEL9K_NODENV_SOURCES -- shell local global + _p9k_declare -b POWERLEVEL9K_NODENV_SHOW_SYSTEM 1 + _p9k_declare -b POWERLEVEL9K_RBENV_PROMPT_ALWAYS_SHOW 0 + _p9k_declare -a POWERLEVEL9K_RBENV_SOURCES -- shell local global + _p9k_declare -b POWERLEVEL9K_RBENV_SHOW_SYSTEM 1 + _p9k_declare -b POWERLEVEL9K_PHPENV_PROMPT_ALWAYS_SHOW 0 + _p9k_declare -a POWERLEVEL9K_PHPENV_SOURCES -- shell local global + _p9k_declare -b POWERLEVEL9K_PHPENV_SHOW_SYSTEM 1 + _p9k_declare -b POWERLEVEL9K_LUAENV_PROMPT_ALWAYS_SHOW 0 + _p9k_declare -a POWERLEVEL9K_LUAENV_SOURCES -- shell local global + _p9k_declare -b POWERLEVEL9K_LUAENV_SHOW_SYSTEM 1 + _p9k_declare -b POWERLEVEL9K_JENV_PROMPT_ALWAYS_SHOW 0 + _p9k_declare -a POWERLEVEL9K_JENV_SOURCES -- shell local global + _p9k_declare -b POWERLEVEL9K_JENV_SHOW_SYSTEM 1 + _p9k_declare -b POWERLEVEL9K_PLENV_PROMPT_ALWAYS_SHOW 0 + _p9k_declare -a POWERLEVEL9K_PLENV_SOURCES -- shell local global + _p9k_declare -b POWERLEVEL9K_PLENV_SHOW_SYSTEM 1 + _p9k_declare -b POWERLEVEL9K_PYENV_PROMPT_ALWAYS_SHOW 0 + _p9k_declare -b POWERLEVEL9K_PYENV_SHOW_SYSTEM 1 + _p9k_declare -a POWERLEVEL9K_PYENV_SOURCES -- shell local global + _p9k_declare -b POWERLEVEL9K_GOENV_PROMPT_ALWAYS_SHOW 0 + _p9k_declare -a POWERLEVEL9K_GOENV_SOURCES -- shell local global + _p9k_declare -b POWERLEVEL9K_GOENV_SHOW_SYSTEM 1 + _p9k_declare -b POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW 0 + _p9k_declare -b POWERLEVEL9K_ASDF_SHOW_SYSTEM 1 + _p9k_declare -a POWERLEVEL9K_ASDF_SOURCES -- shell local global + local var + for var in ${parameters[(I)POWERLEVEL9K_ASDF_*_PROMPT_ALWAYS_SHOW]}; do + _p9k_declare -b $var $_POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW + done + for var in ${parameters[(I)POWERLEVEL9K_ASDF_*_SHOW_SYSTEM]}; do + _p9k_declare -b $var $_POWERLEVEL9K_ASDF_SHOW_SYSTEM + done + for var in ${parameters[(I)POWERLEVEL9K_ASDF_*_SOURCES]}; do + _p9k_declare -a $var -- $_POWERLEVEL9K_ASDF_SOURCES + done + _p9k_declare -b POWERLEVEL9K_HASKELL_STACK_PROMPT_ALWAYS_SHOW 1 + _p9k_declare -a POWERLEVEL9K_HASKELL_STACK_SOURCES -- shell local + _p9k_declare -b POWERLEVEL9K_RVM_SHOW_GEMSET 0 + _p9k_declare -b POWERLEVEL9K_RVM_SHOW_PREFIX 0 + _p9k_declare -b POWERLEVEL9K_CHRUBY_SHOW_VERSION 1 + _p9k_declare -b POWERLEVEL9K_CHRUBY_SHOW_ENGINE 1 + _p9k_declare -b POWERLEVEL9K_STATUS_CROSS 0 + _p9k_declare -b POWERLEVEL9K_STATUS_OK 1 + _p9k_declare -b POWERLEVEL9K_STATUS_OK_PIPE 1 + _p9k_declare -b POWERLEVEL9K_STATUS_ERROR 1 + _p9k_declare -b POWERLEVEL9K_STATUS_ERROR_PIPE 1 + _p9k_declare -b POWERLEVEL9K_STATUS_ERROR_SIGNAL 1 + _p9k_declare -b POWERLEVEL9K_STATUS_SHOW_PIPESTATUS 1 + _p9k_declare -b POWERLEVEL9K_STATUS_HIDE_SIGNAME 0 + _p9k_declare -b POWERLEVEL9K_STATUS_VERBOSE_SIGNAME 1 + _p9k_declare -b POWERLEVEL9K_STATUS_EXTENDED_STATES 0 + _p9k_declare -b POWERLEVEL9K_STATUS_VERBOSE 1 + _p9k_declare -b POWERLEVEL9K_STATUS_OK_IN_NON_VERBOSE 0 + _p9k_declare -e POWERLEVEL9K_DATE_FORMAT "%D{%d.%m.%y}" + _p9k_declare -s POWERLEVEL9K_VCS_ACTIONFORMAT_FOREGROUND 1 + _p9k_declare -b POWERLEVEL9K_SHOW_CHANGESET 0 + _p9k_declare -e POWERLEVEL9K_VCS_LOADING_TEXT loading + _p9k_declare -a POWERLEVEL9K_VCS_GIT_HOOKS -- vcs-detect-changes git-untracked git-aheadbehind git-stash git-remotebranch git-tagname + _p9k_declare -a POWERLEVEL9K_VCS_HG_HOOKS -- vcs-detect-changes + _p9k_declare -a POWERLEVEL9K_VCS_SVN_HOOKS -- vcs-detect-changes svn-detect-changes + # If it takes longer than this to fetch git repo status, display the prompt with a greyed out + # vcs segment and fix it asynchronously when the results come it. + _p9k_declare -F POWERLEVEL9K_VCS_MAX_SYNC_LATENCY_SECONDS 0.02 + (( POWERLEVEL9K_VCS_MAX_SYNC_LATENCY_SECONDS >= 0 )) || (( POWERLEVEL9K_VCS_MAX_SYNC_LATENCY_SECONDS = 0 )) + _p9k_declare -a POWERLEVEL9K_VCS_BACKENDS -- git + _p9k_declare -b POWERLEVEL9K_VCS_DISABLE_GITSTATUS_FORMATTING 0 + _p9k_declare -i POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY -1 + _p9k_declare -i POWERLEVEL9K_VCS_STAGED_MAX_NUM 1 + _p9k_declare -i POWERLEVEL9K_VCS_UNSTAGED_MAX_NUM 1 + _p9k_declare -i POWERLEVEL9K_VCS_UNTRACKED_MAX_NUM 1 + _p9k_declare -i POWERLEVEL9K_VCS_CONFLICTED_MAX_NUM 1 + _p9k_declare -i POWERLEVEL9K_VCS_COMMITS_AHEAD_MAX_NUM -1 + _p9k_declare -i POWERLEVEL9K_VCS_COMMITS_BEHIND_MAX_NUM -1 + _p9k_declare -b POWERLEVEL9K_VCS_RECURSE_UNTRACKED_DIRS 0 + _p9k_declare -b POWERLEVEL9K_DISABLE_GITSTATUS 0 + _p9k_declare -e POWERLEVEL9K_VI_INSERT_MODE_STRING "INSERT" + _p9k_declare -e POWERLEVEL9K_VI_COMMAND_MODE_STRING "NORMAL" + # VISUAL mode is shown as NORMAL unless POWERLEVEL9K_VI_VISUAL_MODE_STRING is explicitly set. + _p9k_declare -e POWERLEVEL9K_VI_VISUAL_MODE_STRING + # OVERWRITE mode is shown as INSERT unless POWERLEVEL9K_VI_OVERWRITE_MODE_STRING is explicitly set. + _p9k_declare -e POWERLEVEL9K_VI_OVERWRITE_MODE_STRING + _p9k_declare -b POWERLEVEL9K_VIRTUALENV_SHOW_WITH_PYENV 1 + _p9k_declare -b POWERLEVEL9K_VIRTUALENV_SHOW_PYTHON_VERSION 1 + _p9k_declare -e POWERLEVEL9K_VIRTUALENV_LEFT_DELIMITER "(" + _p9k_declare -e POWERLEVEL9K_VIRTUALENV_RIGHT_DELIMITER ")" + _p9k_declare -a POWERLEVEL9K_VIRTUALENV_GENERIC_NAMES -- virtualenv venv .venv env + _POWERLEVEL9K_VIRTUALENV_GENERIC_NAMES="${(j.|.)_POWERLEVEL9K_VIRTUALENV_GENERIC_NAMES}" + _p9k_declare -b POWERLEVEL9K_NODEENV_SHOW_NODE_VERSION 1 + _p9k_declare -e POWERLEVEL9K_NODEENV_LEFT_DELIMITER "[" + _p9k_declare -e POWERLEVEL9K_NODEENV_RIGHT_DELIMITER "]" + _p9k_declare -b POWERLEVEL9K_KUBECONTEXT_SHOW_DEFAULT_NAMESPACE 1 + _p9k_declare -a POWERLEVEL9K_KUBECONTEXT_SHORTEN -- + # Defines context classes for the purpose of applying different styling to different contexts. + # + # POWERLEVEL9K_KUBECONTEXT_CLASSES must be an array with even number of elements. The first + # element in each pair defines a pattern against which the current context (in the format it is + # displayed in the prompt) gets matched. The second element defines context class. Patterns are + # tried in order. The first match wins. + # + # If a non-empty class <C> is assigned to a context, the segment is styled with + # POWERLEVEL9K_KUBECONTEXT_<U>_BACKGROUND and POWERLEVEL9K_KUBECONTEXT_<U>_FOREGROUND where <U> is + # uppercased <C>. Otherwise with POWERLEVEL9K_KUBECONTEXT_BACKGROUND and + # POWERLEVEL9K_KUBECONTEXT_FOREGROUND. + # + # Example: Use red background for contexts containing "prod", green for "testing" and yellow for + # everything else. + # + # POWERLEVEL9K_KUBECONTEXT_CLASSES=( + # '*prod*' prod + # '*testing*' testing + # '*' other) + # + # POWERLEVEL9K_KUBECONTEXT_PROD_BACKGROUND=red + # POWERLEVEL9K_KUBECONTEXT_TESTING_BACKGROUND=green + # POWERLEVEL9K_KUBECONTEXT_OTHER_BACKGROUND=yellow + _p9k_declare -a POWERLEVEL9K_KUBECONTEXT_CLASSES -- + _p9k_declare -a POWERLEVEL9K_AWS_CLASSES -- + _p9k_declare -a POWERLEVEL9K_TERRAFORM_CLASSES -- + _p9k_declare -a POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES -- 'service_account:*' SERVICE_ACCOUNT + # Specifies the format of java version. + # + # POWERLEVEL9K_JAVA_VERSION_FULL=true => 1.8.0_212-8u212-b03-0ubuntu1.18.04.1-b03 + # POWERLEVEL9K_JAVA_VERSION_FULL=false => 1.8.0_212 + # + # These correspond to `java -fullversion` and `java -version` respectively. + _p9k_declare -b POWERLEVEL9K_JAVA_VERSION_FULL 1 + _p9k_declare -b POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE 0 + + # Format for the current time: 09:51:02. See `man 3 strftime`. + _p9k_declare -e POWERLEVEL9K_TIME_FORMAT "%D{%H:%M:%S}" + # If set to true, time will update when you hit enter. This way prompts for the past + # commands will contain the start times of their commands as opposed to the default + # behavior where they contain the end times of their preceding commands. + _p9k_declare -b POWERLEVEL9K_TIME_UPDATE_ON_COMMAND 0 + # If set to true, time will update every second. + _p9k_declare -b POWERLEVEL9K_EXPERIMENTAL_TIME_REALTIME 0 + + local -i i=1 + while (( i <= $#_POWERLEVEL9K_LEFT_PROMPT_ELEMENTS )); do + local segment=${(U)_POWERLEVEL9K_LEFT_PROMPT_ELEMENTS[i]} + local var=POWERLEVEL9K_${segment}_LEFT_DISABLED + (( $+parameters[$var] )) || var=POWERLEVEL9K_${segment}_DISABLED + if [[ ${(P)var} == true ]]; then + _POWERLEVEL9K_LEFT_PROMPT_ELEMENTS[i,i]=() + else + (( ++i )) + fi + done + + local -i i=1 + while (( i <= $#_POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS )); do + local segment=${(U)_POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS[i]} + local var=POWERLEVEL9K_${segment}_RIGHT_DISABLED + (( $+parameters[$var] )) || var=POWERLEVEL9K_${segment}_DISABLED + if [[ ${(P)var} == true ]]; then + _POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS[i,i]=() + else + (( ++i )) + fi + done + + local var + for var in ${(@)${parameters[(I)POWERLEVEL9K_*]}/(#m)*/${(M)${parameters[_$MATCH]-$MATCH}:#$MATCH}}; do + case $parameters[$var] in + (scalar|integer|float)*) typeset -g _$var=${(P)var};; + array*) eval 'typeset -ga '_$var'=("${'$var'[@]}")';; + esac + done +} + +function _p9k_on_widget_zle-keymap-select() { _p9k_check_visual_mode; __p9k_reset_state=2; } +function _p9k_on_widget_overwrite-mode() { _p9k_check_visual_mode; __p9k_reset_state=2; } +function _p9k_on_widget_vi-replace() { _p9k_check_visual_mode; __p9k_reset_state=2; } + +if is-at-least 5.3; then + function _p9k_check_visual_mode() { + [[ ${KEYMAP:-} == vicmd ]] || return 0 + local region=${${REGION_ACTIVE:-0}/2/1} + [[ $region != $_p9k__region_active ]] || return 0 + _p9k__region_active=$region + __p9k_reset_state=2 + } +else + function _p9k_check_visual_mode() {} +fi + +function _p9k_on_widget_visual-mode() { _p9k_check_visual_mode; } +function _p9k_on_widget_visual-line-mode() { _p9k_check_visual_mode; } +function _p9k_on_widget_deactivate-region() { _p9k_check_visual_mode; } + +function _p9k_on_widget_zle-line-init() { + (( _p9k__cursor_hidden )) || return 0 + _p9k__cursor_hidden=0 + echoti cnorm +} + +function _p9k_on_widget_zle-line-finish() { + (( $+_p9k__line_finished )) && return + + _p9k__line_finished= + (( _p9k_reset_on_line_finish )) && __p9k_reset_state=2 + (( $+functions[p10k-on-post-prompt] )) && p10k-on-post-prompt + + if [[ -n $_p9k_transient_prompt ]]; then + if [[ $_POWERLEVEL9K_TRANSIENT_PROMPT == always || $_p9k__cwd == $_p9k__last_prompt_pwd ]]; then + RPROMPT= + PROMPT=$_p9k_transient_prompt + __p9k_reset_state=2 + else + _p9k__last_prompt_pwd=$_p9k__cwd + fi + fi + + if (( __p9k_reset_state == 2 )); then + if [[ $1 == int ]]; then + _p9k__must_restore_prompt=1 + if (( !_p9k__restore_prompt_fd )); then + sysopen -o cloexec -ru _p9k__restore_prompt_fd /dev/null + zle -F $_p9k__restore_prompt_fd _p9k_restore_prompt + fi + fi + if (( $+termcap[up] )); then + (( _p9k__can_hide_cursor )) && local hide=$terminfo[civis] || local hide= + echo -nE - $hide$'\n'$termcap[up] + fi + _p9k_reset_prompt + fi + + _p9k__line_finished='%{%}' +} + +# Usage example: _p9k_display_segment 58 _p9k__1rkubecontext hide +function _p9k_display_segment() { + [[ $_p9k__display_v[$1] == $3 ]] && return + _p9k__display_v[$1]=$3 + [[ $3 == hide ]] && typeset -g $2= || unset $2 + __p9k_reset_state=2 +} + +function _p9k_widget_hook() { + if (( $+functions[p10k-on-post-widget] || $#_p9k_show_on_command )); then + local -a P9K_COMMANDS + if [[ "$_p9k__last_buffer" == "$PREBUFFER$BUFFER" ]]; then + P9K_COMMANDS=(${_p9k__last_commands[@]}) + else + _p9k__last_buffer="$PREBUFFER$BUFFER" + if [[ -n "$_p9k__last_buffer" ]]; then + # this must run with user options + _p9k_parse_buffer "$_p9k__last_buffer" $_POWERLEVEL9K_COMMANDS_MAX_TOKEN_COUNT + fi + _p9k__last_commands=(${P9K_COMMANDS[@]}) + fi + fi + + eval "$__p9k_intro" + (( _p9k__restore_prompt_fd )) && _p9k_restore_prompt $_p9k__restore_prompt_fd + if [[ $1 == clear-screen ]]; then + P9K_TTY=new + _p9k__expanded=0 + _p9k_reset_prompt + fi + __p9k_reset_state=1 + _p9k_check_visual_mode + local pat idx var + for pat idx var in $_p9k_show_on_command; do + if (( $P9K_COMMANDS[(I)$pat] )); then + _p9k_display_segment $idx $var show + else + _p9k_display_segment $idx $var hide + fi + done + (( $+functions[p10k-on-post-widget] )) && p10k-on-post-widget "${@:2}" + (( $+functions[_p9k_on_widget_$1] )) && _p9k_on_widget_$1 + (( __p9k_reset_state == 2 )) && _p9k_reset_prompt + __p9k_reset_state=0 +} + +function _p9k_widget() { + (( ! ${+widgets[._p9k_orig_$1]} )) || zle ._p9k_orig_$1 "${@:2}" + local res=$? + (( ! __p9k_enabled )) || [[ $CONTEXT != start ]] || _p9k_widget_hook "$@" + return res +} + +typeset -gi __p9k_widgets_wrapped=0 + +function _p9k_wrap_widgets() { + (( __p9k_widgets_wrapped )) && return + typeset -gir __p9k_widgets_wrapped=1 + local -a widget_list + if is-at-least 5.3; then + local -aU widget_list=( + zle-line-pre-redraw + zle-line-init + zle-line-finish + zle-keymap-select + overwrite-mode + vi-replace + visual-mode + visual-line-mode + deactivate-region + clear-screen + $_POWERLEVEL9K_HOOK_WIDGETS + ) + else + # There is no zle-line-pre-redraw in zsh < 5.3, so we have to wrap all widgets + # with key bindings. This costs extra 3ms: 1.5ms to fetch the list of widgets and + # another 1.5ms to wrap them. + local keymap tmp=${TMPDIR:-/tmp}/p10k.bindings.$sysparams[pid] + { + for keymap in $keymaps; do bindkey -M $keymap; done >$tmp + local -aU widget_list=( + zle-isearch-exit + zle-isearch-update + zle-line-init + zle-line-finish + zle-history-line-set + zle-keymap-select + $_POWERLEVEL9K_HOOK_WIDGETS + ${${${(f)"$(<$tmp)"}##* }:#(*\"|.*)} + ) + } always { + zf_rm -f -- $tmp + } + fi + local widget + for widget in $widget_list; do + functions[_p9k_widget_$widget]='_p9k_widget '${(q)widget}' "$@"' + # The leading dot is to work around bugs in zsh-syntax-highlighting. + zle -A $widget ._p9k_orig_$widget + zle -N $widget _p9k_widget_$widget + done 2>/dev/null # `zle -A` fails for inexisting widgets and complains to stderr +} + +function _p9k_restore_prompt() { + eval "$__p9k_intro" + zle -F $1 + exec {1}>&- + _p9k__restore_prompt_fd=0 + + (( _p9k__must_restore_prompt )) || return 0 + _p9k__must_restore_prompt=0 + + unset _p9k__line_finished + _p9k__refresh_reason=restore + _p9k_set_prompt + _p9k__refresh_reason= + + _p9k__expanded=0 + _p9k_reset_prompt +} + +prompt__p9k_internal_nothing() { _p9k__prompt+='${_p9k__sss::=}'; } +instant_prompt__p9k_internal_nothing() { prompt__p9k_internal_nothing; } + +# _p9k_build_gap_post line_number +_p9k_build_gap_post() { + [[ $1 == 1 ]] && local kind=first || local kind=newline + _p9k_get_icon '' MULTILINE_${(U)kind}_PROMPT_GAP_CHAR + local char=${_p9k__ret:- } + _p9k_prompt_length $char + if (( _p9k__ret != 1 || $#char != 1 )); then + >&2 print -rP -- "%F{red}WARNING!%f %BMULTILINE_${(U)kind}_PROMPT_GAP_CHAR%b is not one character long. Will use ' '." + >&2 print -rP -- "Either change the value of %BPOWERLEVEL9K_MULTILINE_${(U)kind}_PROMPT_GAP_CHAR%b or remove it." + char=' ' + fi + local style + _p9k_color prompt_multiline_${kind}_prompt_gap BACKGROUND "" + [[ -n $_p9k__ret ]] && _p9k_background $_p9k__ret + style+=$_p9k__ret + _p9k_color prompt_multiline_${kind}_prompt_gap FOREGROUND "" + [[ -n $_p9k__ret ]] && _p9k_foreground $_p9k__ret + style+=$_p9k__ret + _p9k_escape_style $style + style=$_p9k__ret + local exp=_POWERLEVEL9K_MULTILINE_${(U)kind}_PROMPT_GAP_EXPANSION + (( $+parameters[$exp] )) && exp=${(P)exp} || exp='${P9K_GAP}' + [[ $char == '.' ]] && local s=',' || local s='.' + _p9k__ret=$'${${_p9k__g+\n}:-'$style'${${${_p9k__m:#-*}:+' + _p9k__ret+='${${_p9k__'$1'g+${(pl.$((_p9k__m+1)).. .)}}:-' + if [[ $exp == '${P9K_GAP}' ]]; then + _p9k__ret+='${(pl'$s'$((_p9k__m+1))'$s$s$char$s')}' + else + _p9k__ret+='${${P9K_GAP::=${(pl'$s'$((_p9k__m+1))'$s$s$char$s')}}+}' + _p9k__ret+='${:-"'$exp'"}' + style=1 + fi + _p9k__ret+='}' + if (( __p9k_ksh_arrays )); then + _p9k__ret+=$'$_p9k__rprompt${_p9k_t[$((!_p9k__ind))]}}:-\n}' + else + _p9k__ret+=$'$_p9k__rprompt${_p9k_t[$((1+!_p9k__ind))]}}:-\n}' + fi + [[ -n $style ]] && _p9k__ret+='%b%k%f' + _p9k__ret+='}' +} + +_p9k_init_lines() { + local -a left_segments=($_POWERLEVEL9K_LEFT_PROMPT_ELEMENTS) + local -a right_segments=($_POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS) + + if (( _POWERLEVEL9K_PROMPT_ON_NEWLINE )); then + left_segments+=(newline _p9k_internal_nothing) + fi + + local -i num_left_lines=$((1 + ${#${(@M)left_segments:#newline}})) + local -i num_right_lines=$((1 + ${#${(@M)right_segments:#newline}})) + if (( num_right_lines > num_left_lines )); then + repeat $((num_right_lines - num_left_lines)) left_segments=(newline $left_segments) + local -i num_lines=num_right_lines + else + if (( _POWERLEVEL9K_RPROMPT_ON_NEWLINE )); then + repeat $((num_left_lines - num_right_lines)) right_segments=(newline $right_segments) + else + repeat $((num_left_lines - num_right_lines)) right_segments+=newline + fi + local -i num_lines=num_left_lines + fi + + local -i i + for i in {1..$num_lines}; do + local -i left_end=${left_segments[(i)newline]} + local -i right_end=${right_segments[(i)newline]} + _p9k_line_segments_left+="${(pj:\0:)left_segments[1,left_end-1]}" + _p9k_line_segments_right+="${(pj:\0:)right_segments[1,right_end-1]}" + (( left_end > $#left_segments )) && left_segments=() || shift left_end left_segments + (( right_end > $#right_segments )) && right_segments=() || shift right_end right_segments + + _p9k_get_icon '' LEFT_SEGMENT_SEPARATOR + _p9k_get_icon 'prompt_empty_line' LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL $_p9k__ret + _p9k_escape $_p9k__ret + _p9k_line_prefix_left+='${_p9k__'$i'l-${${:-${_p9k__bg::=NONE}${_p9k__i::=0}${_p9k__sss::=%f'$_p9k__ret'}}+}' + _p9k_line_suffix_left+='%b%k$_p9k__sss%b%k%f' + + _p9k_escape ${(g::)_POWERLEVEL9K_EMPTY_LINE_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL} + [[ -n $_p9k__ret ]] && _p9k_line_never_empty_right+=1 || _p9k_line_never_empty_right+=0 + _p9k_line_prefix_right+='${_p9k__'$i'r-${${:-${_p9k__bg::=NONE}${_p9k__i::=0}${_p9k__sss::='$_p9k__ret'}}+}' + _p9k_line_suffix_right+='$_p9k__sss%b%k%f}' # gets overridden for _p9k_emulate_zero_rprompt_indent + if (( i == num_lines )); then + # it's safe to use _p9k_prompt_length on the last line because it cannot have prompt connection + _p9k_prompt_length ${(e)_p9k__ret} + (( _p9k__ret )) || _p9k_line_never_empty_right[-1]=0 + fi + done + + _p9k_get_icon '' LEFT_SEGMENT_END_SEPARATOR + if [[ -n $_p9k__ret ]]; then + _p9k__ret+=%b%k%f + # Not escaped for historical reasons. + _p9k__ret='${:-"'$_p9k__ret'"}' + if (( _POWERLEVEL9K_PROMPT_ON_NEWLINE )); then + _p9k_line_suffix_left[-2]+=$_p9k__ret + else + _p9k_line_suffix_left[-1]+=$_p9k__ret + fi + fi + + for i in {1..$num_lines}; do _p9k_line_suffix_left[i]+='}'; done + + if (( num_lines > 1 )); then + for i in {1..$((num_lines-1))}; do + _p9k_build_gap_post $i + _p9k_line_gap_post+=$_p9k__ret + done + + if [[ $+_POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX == 1 || $_POWERLEVEL9K_PROMPT_ON_NEWLINE == 1 ]]; then + _p9k_get_icon '' MULTILINE_FIRST_PROMPT_PREFIX + if [[ -n $_p9k__ret ]]; then + [[ _p9k__ret == *%* ]] && _p9k__ret+=%b%k%f + # Not escaped for historical reasons. + _p9k__ret='${_p9k__1l_frame-"'$_p9k__ret'"}' + _p9k_line_prefix_left[1]=$_p9k__ret$_p9k_line_prefix_left[1] + fi + fi + + if [[ $+_POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX == 1 || $_POWERLEVEL9K_PROMPT_ON_NEWLINE == 1 ]]; then + _p9k_get_icon '' MULTILINE_LAST_PROMPT_PREFIX + if [[ -n $_p9k__ret ]]; then + [[ _p9k__ret == *%* ]] && _p9k__ret+=%b%k%f + # Not escaped for historical reasons. + _p9k__ret='${_p9k__'$num_lines'l_frame-"'$_p9k__ret'"}' + _p9k_line_prefix_left[-1]=$_p9k__ret$_p9k_line_prefix_left[-1] + fi + fi + + _p9k_get_icon '' MULTILINE_FIRST_PROMPT_SUFFIX + if [[ -n $_p9k__ret ]]; then + [[ _p9k__ret == *%* ]] && _p9k__ret+=%b%k%f + _p9k_line_suffix_right[1]+='${_p9k__1r_frame-'${(qqq)_p9k__ret}'}' + _p9k_line_never_empty_right[1]=1 + fi + + _p9k_get_icon '' MULTILINE_LAST_PROMPT_SUFFIX + if [[ -n $_p9k__ret ]]; then + [[ _p9k__ret == *%* ]] && _p9k__ret+=%b%k%f + _p9k_line_suffix_right[-1]+='${_p9k__'$num_lines'r_frame-'${(qqq)_p9k__ret}'}' + # it's safe to use _p9k_prompt_length on the last line because it cannot have prompt connection + _p9k_prompt_length $_p9k__ret + (( _p9k__ret )) && _p9k_line_never_empty_right[-1]=1 + fi + + if (( num_lines > 2 )); then + if [[ $+_POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_PREFIX == 1 || $_POWERLEVEL9K_PROMPT_ON_NEWLINE == 1 ]]; then + _p9k_get_icon '' MULTILINE_NEWLINE_PROMPT_PREFIX + if [[ -n $_p9k__ret ]]; then + [[ _p9k__ret == *%* ]] && _p9k__ret+=%b%k%f + for i in {2..$((num_lines-1))}; do + # Not escaped for historical reasons. + _p9k_line_prefix_left[i]='${_p9k__'$i'l_frame-"'$_p9k__ret'"}'$_p9k_line_prefix_left[i] + done + fi + fi + + _p9k_get_icon '' MULTILINE_NEWLINE_PROMPT_SUFFIX + if [[ -n $_p9k__ret ]]; then + [[ _p9k__ret == *%* ]] && _p9k__ret+=%b%k%f + for i in {2..$((num_lines-1))}; do + _p9k_line_suffix_right[i]+='${_p9k__'$i'r_frame-'${(qqq)_p9k__ret}'}' + done + _p9k_line_never_empty_right[2,-2]=${(@)_p9k_line_never_empty_right[2,-2]/0/1} + fi + fi + fi +} + +_p9k_all_params_eq() { + local key + for key in ${parameters[(I)${~1}]}; do + [[ ${(P)key} == $2 ]] || return + done +} + +_p9k_init_display() { + _p9k_display_k=(empty_line 1 ruler 3) + local -i n=3 i + local name + for i in {1..$#_p9k_line_segments_left}; do + local -i j=$((-$#_p9k_line_segments_left+i-1)) + _p9k_display_k+=( + $i $((n+=2)) $j $n + $i/left_frame $((n+=2)) $j/left_frame $n + $i/right_frame $((n+=2)) $j/right_frame $n + $i/left $((n+=2)) $j/left $n + $i/right $((n+=2)) $j/right $n + $i/gap $((n+=2)) $j/gap $n) + for name in ${${(@0)_p9k_line_segments_left[i]}%_joined}; do + _p9k_display_k+=($i/left/$name $((n+=2)) $j/left/$name $n) + done + for name in ${${(@0)_p9k_line_segments_right[i]}%_joined}; do + _p9k_display_k+=($i/right/$name $((n+=2)) $j/right/$name $n) + done + done +} + +_p9k_init_prompt() { + _p9k_t=($'\n' $'%{\n%}' '') + _p9k_prompt_overflow_bug && _p9k_t[2]=$'%{%G\n%}' + + _p9k_init_lines + + _p9k_gap_pre='${${:-${_p9k__x::=0}${_p9k__y::=1024}${_p9k__p::=$_p9k__lprompt$_p9k__rprompt}' + repeat 10; do + _p9k_gap_pre+='${_p9k__m::=$(((_p9k__x+_p9k__y)/2))}' + _p9k_gap_pre+='${_p9k__xy::=${${(%):-$_p9k__p%$_p9k__m(l./$_p9k__m;$_p9k__y./$_p9k__x;$_p9k__m)}##*/}}' + _p9k_gap_pre+='${_p9k__x::=${_p9k__xy%;*}}' + _p9k_gap_pre+='${_p9k__y::=${_p9k__xy#*;}}' + done + _p9k_gap_pre+='${_p9k__m::=$((_p9k__clm-_p9k__x-_p9k__ind-1))}' + _p9k_gap_pre+='}+}' + + _p9k_prompt_prefix_left='${${_p9k__clm::=$COLUMNS}+}${${COLUMNS::=1024}+}' + _p9k_prompt_prefix_right='${_p9k__'$#_p9k_line_segments_left'-${${_p9k__clm::=$COLUMNS}+}${${COLUMNS::=1024}+}' + _p9k_prompt_suffix_left='${${COLUMNS::=$_p9k__clm}+}' + _p9k_prompt_suffix_right='${${COLUMNS::=$_p9k__clm}+}}' + + if _p9k_segment_in_use vi_mode || _p9k_segment_in_use prompt_char; then + _p9k_prompt_prefix_left+='${${_p9k__keymap::=${KEYMAP:-$_p9k__keymap}}+}' + fi + if { _p9k_segment_in_use vi_mode && (( $+_POWERLEVEL9K_VI_OVERWRITE_MODE_STRING )) } || + { _p9k_segment_in_use prompt_char && (( _POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE )) }; then + _p9k_prompt_prefix_left+='${${_p9k__zle_state::=${ZLE_STATE:-$_p9k__zle_state}}+}' + fi + _p9k_prompt_prefix_left+='%b%k%f' + + # Bug fixed in: https://github.com/zsh-users/zsh/commit/3eea35d0853bddae13fa6f122669935a01618bf9. + # If affects most terminals when RPROMPT is non-empty and ZLE_RPROMPT_INDENT is zero. + # We can work around it as long as RPROMPT ends with a space. + if [[ -n $_p9k_line_segments_right[-1] && $_p9k_line_never_empty_right[-1] == 0 && + $ZLE_RPROMPT_INDENT == 0 ]] && + _p9k_all_params_eq '_POWERLEVEL9K_*WHITESPACE_BETWEEN_RIGHT_SEGMENTS' ' ' && + _p9k_all_params_eq '_POWERLEVEL9K_*RIGHT_RIGHT_WHITESPACE' ' ' && + _p9k_all_params_eq '_POWERLEVEL9K_*RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL' '' && + ! is-at-least 5.7.2; then + _p9k_emulate_zero_rprompt_indent=1 + _p9k_prompt_prefix_left+='${${:-${_p9k__real_zle_rprompt_indent:=$ZLE_RPROMPT_INDENT}${ZLE_RPROMPT_INDENT::=1}${_p9k__ind::=0}}+}' + _p9k_line_suffix_right[-1]='${_p9k__sss:+${_p9k__sss% }%E}}' + else + _p9k_emulate_zero_rprompt_indent=0 + _p9k_prompt_prefix_left+='${${_p9k__ind::=${${ZLE_RPROMPT_INDENT:-1}/#-*/0}}+}' + fi + + if [[ $ITERM_SHELL_INTEGRATION_INSTALLED == Yes ]]; then + _p9k_prompt_prefix_left+=$'%{\e]133;A\a%}' + _p9k_prompt_suffix_left+=$'%{\e]133;B\a%}' + fi + + if (( _POWERLEVEL9K_PROMPT_ADD_NEWLINE_COUNT > 0 )); then + _p9k_t+=${(pl.$_POWERLEVEL9K_PROMPT_ADD_NEWLINE_COUNT..\n.)} + else + _p9k_t+='' + fi + _p9k_empty_line_idx=$#_p9k_t + if (( __p9k_ksh_arrays )); then + _p9k_prompt_prefix_left+='${_p9k_t[${_p9k__empty_line_i:-'$#_p9k_t'}-1]}' + else + _p9k_prompt_prefix_left+='${_p9k_t[${_p9k__empty_line_i:-'$#_p9k_t'}]}' + fi + + _p9k_get_icon '' RULER_CHAR + local ruler_char=$_p9k__ret + _p9k_prompt_length $ruler_char + (( _p9k__ret == 1 && $#ruler_char == 1 )) || ruler_char=' ' + _p9k_color prompt_ruler BACKGROUND "" + if [[ -z $_p9k__ret && $ruler_char == ' ' ]]; then + local ruler=$'\n' + else + _p9k_background $_p9k__ret + local ruler=%b$_p9k__ret + _p9k_color prompt_ruler FOREGROUND "" + _p9k_foreground $_p9k__ret + ruler+=$_p9k__ret + [[ $ruler_char == '.' ]] && local sep=',' || local sep='.' + ruler+='${(pl'$sep'${$((_p9k__clm-_p9k__ind))/#-*/0}'$sep$sep$ruler_char$sep')}%k%f' + if (( __p9k_ksh_arrays )); then + ruler+='${_p9k_t[$((!_p9k__ind))]}' + else + ruler+='${_p9k_t[$((1+!_p9k__ind))]}' + fi + fi + _p9k_t+=$ruler + _p9k_ruler_idx=$#_p9k_t + if (( __p9k_ksh_arrays )); then + _p9k_prompt_prefix_left+='${(e)_p9k_t[${_p9k__ruler_i:-'$#_p9k_t'}-1]}' + else + _p9k_prompt_prefix_left+='${(e)_p9k_t[${_p9k__ruler_i:-'$#_p9k_t'}]}' + fi + + ( _p9k_segment_in_use time && (( _POWERLEVEL9K_TIME_UPDATE_ON_COMMAND )) ) + _p9k_reset_on_line_finish=$((!$?)) + + _p9k_t+=$_p9k_gap_pre + _p9k_gap_pre='${(e)_p9k_t['$(($#_p9k_t - __p9k_ksh_arrays))']}' + _p9k_t+=$_p9k_prompt_prefix_left + _p9k_prompt_prefix_left='${(e)_p9k_t['$(($#_p9k_t - __p9k_ksh_arrays))']}' +} + +_p9k_init_ssh() { + # The following code is based on Pure: + # https://github.com/sindresorhus/pure/blob/e8abf9d37185ec9b7b4398ca9c5eba555a1028eb/pure.zsh. + # + # License: https://github.com/sindresorhus/pure/blob/e8abf9d37185ec9b7b4398ca9c5eba555a1028eb/license. + + [[ -n $P9K_SSH ]] && return + typeset -gix P9K_SSH=0 + if [[ -n $SSH_CLIENT || -n $SSH_TTY || -n $SSH_CONNECTION ]]; then + P9K_SSH=1 + return 0 + fi + + # When changing user on a remote system, the $SSH_CONNECTION environment variable can be lost. + # Attempt detection via `who`. + (( $+commands[who] )) || return + + local ipv6='(([0-9a-fA-F]+:)|:){2,}[0-9a-fA-F]+' # Simplified, only checks partial pattern. + local ipv4='([0-9]{1,3}\.){3}[0-9]+' # Simplified, allows invalid ranges. + # Assume two non-consecutive periods represents a hostname. Matches `x.y.z`, but not `x.y`. + local hostname='([.][^. ]+){2}' + + local w + w="$(who -m 2>/dev/null)" || w=${(@M)${(f)"$(who 2>/dev/null)"}:#*[[:space:]]${TTY#/dev/}[[:space:]]*} + + # Usually the remote address is surrounded by parenthesis but not on all systems (e.g., Busybox). + [[ $w =~ "\(?($ipv4|$ipv6|$hostname)\)?\$" ]] && P9K_SSH=1 +} + +_p9k_must_init() { + (( _POWERLEVEL9K_DISABLE_HOT_RELOAD && !_p9k__force_must_init )) && return 1 + _p9k__force_must_init=0 + local IFS sig + if [[ -n $_p9k__param_sig ]]; then + IFS=$'\2' sig="${(e)_p9k__param_pat}" + [[ $sig == $_p9k__param_sig ]] && return 1 + _p9k_deinit + fi + _p9k__param_pat=$'v87\1'${ZSH_VERSION}$'\1'${ZSH_PATCHLEVEL}$'\1' + _p9k__param_pat+=$'${#parameters[(I)POWERLEVEL9K_*]}\1${(%):-%n%#}\1$GITSTATUS_LOG_LEVEL\1' + _p9k__param_pat+=$'$GITSTATUS_ENABLE_LOGGING\1$GITSTATUS_DAEMON\1$GITSTATUS_NUM_THREADS\1' + _p9k__param_pat+=$'$GITSTATUS_CACHE_DIR\1\1${ZLE_RPROMPT_INDENT:-1}\1$__p9k_ksh_arrays\1' + _p9k__param_pat+=$'$__p9k_sh_glob\1$ITERM_SHELL_INTEGRATION_INSTALLED\1$commands[uname]\1' + _p9k__param_pat+=$'${PROMPT_EOL_MARK-%B%S%#%s%b}\1$commands[locale]\1$langinfo[CODESET]\1' + _p9k__param_pat+=$'$VTE_VERSION\1$TERM_PROGRAM\1$DEFAULT_USER\1$P9K_SSH\1' + _p9k__param_pat+=$'$functions[p10k-on-init]$functions[p10k-on-pre-prompt]\1' + _p9k__param_pat+=$'$functions[p10k-on-post-widget]$functions[p10k-on-post-prompt]\1' + local MATCH + IFS=$'\1' _p9k__param_pat+="${(@)${(@o)parameters[(I)POWERLEVEL9K_*]}:/(#m)*/\${${(q)MATCH}-$IFS\}}" + IFS=$'\2' _p9k__param_sig="${(e)_p9k__param_pat}" +} + +function _p9k_set_os() { + _p9k_os=$1 + _p9k_get_icon prompt_os_icon $2 + _p9k_os_icon=$_p9k__ret +} + +function _p9k_init_cacheable() { + _p9k_init_icons + _p9k_init_params + _p9k_init_prompt + _p9k_init_display + + # https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda#backward-compatibility + if [[ $VTE_VERSION != (<1-4602>|4801) ]]; then + _p9k_term_has_href=1 + fi + + local elem func + local -i i=0 + + for i in {1..$#_p9k_line_segments_left}; do + for elem in ${${(@0)_p9k_line_segments_left[i]}%_joined}; do + local var=POWERLEVEL9K_${(U)elem}_SHOW_ON_COMMAND + (( $+parameters[$var] )) || continue + _p9k_show_on_command+=( + $'(|*[/\0])('${(j.|.)${(P)var}}')' + $((1+_p9k_display_k[$i/left/$elem])) + _p9k__${i}l$elem) + done + for elem in ${${(@0)_p9k_line_segments_right[i]}%_joined}; do + local var=POWERLEVEL9K_${(U)elem}_SHOW_ON_COMMAND + (( $+parameters[$var] )) || continue + local cmds=(${(P)var}) + _p9k_show_on_command+=( + $'(|*[/\0])('${(j.|.)${(P)var}}')' + $((1+$_p9k_display_k[$i/right/$elem])) + _p9k__${i}r$elem) + done + done + + if [[ $_POWERLEVEL9K_TRANSIENT_PROMPT != off ]]; then + _p9k_transient_prompt='%b%k%s%u%F{%(?.' + _p9k_color prompt_prompt_char_OK_VIINS FOREGROUND 76 + _p9k_transient_prompt+=$_p9k__ret'.' + _p9k_color prompt_prompt_char_ERROR_VIINS FOREGROUND 196 + _p9k_transient_prompt+=$_p9k__ret')}${${P9K_CONTENT::="❯"}+}' + _p9k_param prompt_prompt_char_OK_VIINS CONTENT_EXPANSION '${P9K_CONTENT}' + _p9k_transient_prompt+='${:-"'$_p9k__ret'"}%b%k%f%s%u ' + if [[ $ITERM_SHELL_INTEGRATION_INSTALLED == Yes ]]; then + _p9k_transient_prompt=$'%{\e]133;A\a%}'$_p9k_transient_prompt$'%{\e]133;B\a%}' + fi + fi + + _p9k_uname="$(uname)" + [[ $_p9k_uname == Linux ]] && _p9k_uname_o="$(uname -o 2>/dev/null)" + _p9k_uname_m="$(uname -m)" + + if [[ $_p9k_uname == Linux && $_p9k_uname_o == Android ]]; then + _p9k_set_os Android ANDROID_ICON + else + case $_p9k_uname in + SunOS) _p9k_set_os Solaris SUNOS_ICON;; + Darwin) _p9k_set_os OSX APPLE_ICON;; + CYGWIN_NT-* | MSYS_NT-*) _p9k_set_os Windows WINDOWS_ICON;; + FreeBSD|OpenBSD|DragonFly) _p9k_set_os BSD FREEBSD_ICON;; + Linux) + _p9k_os='Linux' + local os_release_id + if [[ -r /etc/os-release ]]; then + local lines=(${(f)"$(</etc/os-release)"}) + lines=(${(@M)lines:#ID=*}) + (( $#lines == 1 )) && os_release_id=${lines[1]#ID=} + fi + case $os_release_id in + *arch*) _p9k_set_os Linux LINUX_ARCH_ICON;; + *debian*) _p9k_set_os Linux LINUX_DEBIAN_ICON;; + *raspbian*) _p9k_set_os Linux LINUX_RASPBIAN_ICON;; + *ubuntu*) _p9k_set_os Linux LINUX_UBUNTU_ICON;; + *elementary*) _p9k_set_os Linux LINUX_ELEMENTARY_ICON;; + *fedora*) _p9k_set_os Linux LINUX_FEDORA_ICON;; + *coreos*) _p9k_set_os Linux LINUX_COREOS_ICON;; + *gentoo*) _p9k_set_os Linux LINUX_GENTOO_ICON;; + *mageia*) _p9k_set_os Linux LINUX_MAGEIA_ICON;; + *centos*) _p9k_set_os Linux LINUX_CENTOS_ICON;; + *opensuse*|*tumbleweed*) _p9k_set_os Linux LINUX_OPENSUSE_ICON;; + *sabayon*) _p9k_set_os Linux LINUX_SABAYON_ICON;; + *slackware*) _p9k_set_os Linux LINUX_SLACKWARE_ICON;; + *linuxmint*) _p9k_set_os Linux LINUX_MINT_ICON;; + *alpine*) _p9k_set_os Linux LINUX_ALPINE_ICON;; + *aosc*) _p9k_set_os Linux LINUX_AOSC_ICON;; + *nixos*) _p9k_set_os Linux LINUX_NIXOS_ICON;; + *devuan*) _p9k_set_os Linux LINUX_DEVUAN_ICON;; + *manjaro*) _p9k_set_os Linux LINUX_MANJARO_ICON;; + *void*) _p9k_set_os Linux LINUX_VOID_ICON;; + *) _p9k_set_os Linux LINUX_ICON;; + esac + ;; + esac + fi + + if [[ $_POWERLEVEL9K_COLOR_SCHEME == light ]]; then + _p9k_color1=7 + _p9k_color2=0 + else + _p9k_color1=0 + _p9k_color2=7 + fi + + # Someone might be using these. + typeset -g OS=$_p9k_os + typeset -g DEFAULT_COLOR=$_p9k_color1 + typeset -g DEFAULT_COLOR_INVERTED=$_p9k_color2 + + _p9k_battery_states=( + 'LOW' 'red' + 'CHARGING' 'yellow' + 'CHARGED' 'green' + 'DISCONNECTED' "$_p9k_color2" + ) + + # This simpler construct doesn't work on zsh-5.1 with multi-line prompt: + # + # ${(@0)_p9k_line_segments_left[@]} + local -a left_segments=(${(@0)${(pj:\0:)_p9k_line_segments_left}}) + _p9k_left_join=(1) + for ((i = 2; i <= $#left_segments; ++i)); do + elem=$left_segments[i] + if [[ $elem == *_joined ]]; then + _p9k_left_join+=$_p9k_left_join[((i-1))] + else + _p9k_left_join+=$i + fi + done + + local -a right_segments=(${(@0)${(pj:\0:)_p9k_line_segments_right}}) + _p9k_right_join=(1) + for ((i = 2; i <= $#right_segments; ++i)); do + elem=$right_segments[i] + if [[ $elem == *_joined ]]; then + _p9k_right_join+=$_p9k_right_join[((i-1))] + else + _p9k_right_join+=$i + fi + done + + case $_p9k_os in + OSX) (( $+commands[sysctl] )) && _p9k_num_cpus="$(sysctl -n hw.logicalcpu 2>/dev/null)";; + BSD) (( $+commands[sysctl] )) && _p9k_num_cpus="$(sysctl -n hw.ncpu 2>/dev/null)";; + *) (( $+commands[nproc] )) && _p9k_num_cpus="$(nproc 2>/dev/null)";; + esac + (( _p9k_num_cpus )) || _p9k_num_cpus=1 + + if _p9k_segment_in_use dir; then + if (( $+_POWERLEVEL9K_DIR_CLASSES )); then + local -i i=3 + for ((; i <= $#_POWERLEVEL9K_DIR_CLASSES; i+=3)); do + _POWERLEVEL9K_DIR_CLASSES[i]=${(g::)_POWERLEVEL9K_DIR_CLASSES[i]} + done + else + typeset -ga _POWERLEVEL9K_DIR_CLASSES=() + _p9k_get_icon prompt_dir_ETC ETC_ICON + _POWERLEVEL9K_DIR_CLASSES+=('/etc|/etc/*' ETC "$_p9k__ret") + _p9k_get_icon prompt_dir_HOME HOME_ICON + _POWERLEVEL9K_DIR_CLASSES+=('~' HOME "$_p9k__ret") + _p9k_get_icon prompt_dir_HOME_SUBFOLDER HOME_SUB_ICON + _POWERLEVEL9K_DIR_CLASSES+=('~/*' HOME_SUBFOLDER "$_p9k__ret") + _p9k_get_icon prompt_dir_DEFAULT FOLDER_ICON + _POWERLEVEL9K_DIR_CLASSES+=('*' DEFAULT "$_p9k__ret") + fi + fi + + if _p9k_segment_in_use status; then + typeset -g _p9k_exitcode2str=({0..255}) + local -i i=2 + if (( !_POWERLEVEL9K_STATUS_HIDE_SIGNAME )); then + for ((; i <= $#signals; ++i)); do + local sig=$signals[i] + (( _POWERLEVEL9K_STATUS_VERBOSE_SIGNAME )) && sig="SIG${sig}($((i-1)))" + _p9k_exitcode2str[$((128+i))]=$sig + done + fi + fi + + if [[ $#_POWERLEVEL9K_VCS_BACKENDS == 1 && $_POWERLEVEL9K_VCS_BACKENDS[1] == git ]]; then + local elem line + local -i i=0 line_idx=0 + for line in $_p9k_line_segments_left; do + (( ++line_idx )) + for elem in ${${(0)line}%_joined}; do + (( ++i )) + if [[ $elem == vcs ]]; then + if (( _p9k_vcs_index )); then + _p9k_vcs_index=-1 + else + _p9k_vcs_index=i + _p9k_vcs_line_index=line_idx + _p9k_vcs_side=left + fi + fi + done + done + i=0 + line_idx=0 + for line in $_p9k_line_segments_right; do + (( ++line_idx )) + for elem in ${${(0)line}%_joined}; do + (( ++i )) + if [[ $elem == vcs ]]; then + if (( _p9k_vcs_index )); then + _p9k_vcs_index=-1 + else + _p9k_vcs_index=i + _p9k_vcs_line_index=line_idx + _p9k_vcs_side=right + fi + fi + done + done + if (( _p9k_vcs_index > 0 )); then + local state + for state in ${(k)__p9k_vcs_states}; do + _p9k_param prompt_vcs_$state CONTENT_EXPANSION x + if [[ -z $_p9k__ret ]]; then + _p9k_vcs_index=-1 + break + fi + done + fi + if (( _p9k_vcs_index == -1 )); then + _p9k_vcs_index=0 + _p9k_vcs_line_index=0 + _p9k_vcs_side= + fi + fi +} + +_p9k_init_vcs() { + _p9k_segment_in_use vcs || return + _p9k_vcs_info_init + if (( $+functions[_p9k_preinit] )); then + if (( $+GITSTATUS_DAEMON_PID_POWERLEVEL9K )); then + () { + trap 'return 130' INT + { + gitstatus_start_p9k_ POWERLEVEL9K + } always { + trap ':' INT + } + } + fi + return 0 + fi + (( _POWERLEVEL9K_DISABLE_GITSTATUS )) && return + (( $_POWERLEVEL9K_VCS_BACKENDS[(I)git] )) || return + + local gitstatus_dir=${_POWERLEVEL9K_GITSTATUS_DIR:-${__p9k_root_dir}/gitstatus} + + typeset -g _p9k_preinit="function _p9k_preinit() { + [[ \$ZSH_VERSION == ${(q)ZSH_VERSION} ]] || return + [[ -r ${(q)gitstatus_dir}/gitstatus.plugin.zsh ]] || return + source ${(q)gitstatus_dir}/gitstatus.plugin.zsh _p9k_ || return + GITSTATUS_AUTO_INSTALL=${(q)GITSTATUS_AUTO_INSTALL} \ + GITSTATUS_DAEMON=${(q)GITSTATUS_DAEMON} \ + GITSTATUS_CACHE_DIR=${(q)GITSTATUS_CACHE_DIR} \ + GITSTATUS_NUM_THREADS=${(q)GITSTATUS_NUM_THREADS} \ + GITSTATUS_LOG_LEVEL=${(q)GITSTATUS_LOG_LEVEL} \ + GITSTATUS_ENABLE_LOGGING=${(q)GITSTATUS_ENABLE_LOGGING} \ + gitstatus_start_p9k_ \ + -s $_POWERLEVEL9K_VCS_STAGED_MAX_NUM \ + -u $_POWERLEVEL9K_VCS_UNSTAGED_MAX_NUM \ + -d $_POWERLEVEL9K_VCS_UNTRACKED_MAX_NUM \ + -c $_POWERLEVEL9K_VCS_CONFLICTED_MAX_NUM \ + -m $_POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY \ + ${${_POWERLEVEL9K_VCS_RECURSE_UNTRACKED_DIRS:#0}:+-e} \ + -a POWERLEVEL9K + }" + source $gitstatus_dir/gitstatus.plugin.zsh _p9k_ || return + () { + trap 'return 130' INT + { + gitstatus_start_p9k_ \ + -s $_POWERLEVEL9K_VCS_STAGED_MAX_NUM \ + -u $_POWERLEVEL9K_VCS_UNSTAGED_MAX_NUM \ + -d $_POWERLEVEL9K_VCS_UNTRACKED_MAX_NUM \ + -c $_POWERLEVEL9K_VCS_CONFLICTED_MAX_NUM \ + -m $_POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY \ + ${${_POWERLEVEL9K_VCS_RECURSE_UNTRACKED_DIRS:#0}:+-e} \ + POWERLEVEL9K + } always { + trap ':' INT + } + } +} + +_p9k_init() { + _p9k_init_vars + _p9k_restore_state || _p9k_init_cacheable + + typeset -g P9K_OS_ICON=$_p9k_os_icon + + local -a _p9k__async_segments_compute + + local -i i + local elem + + _p9k__prompt_side=left + _p9k__segment_index=1 + for i in {1..$#_p9k_line_segments_left}; do + for elem in ${${(@0)_p9k_line_segments_left[i]}%_joined}; do + local f_init=_p9k_prompt_${elem}_init + (( $+functions[$f_init] )) && $f_init + (( ++_p9k__segment_index )) + done + done + + _p9k__prompt_side=right + _p9k__segment_index=1 + for i in {1..$#_p9k_line_segments_right}; do + for elem in ${${(@0)_p9k_line_segments_right[i]}%_joined}; do + local f_init=_p9k_prompt_${elem}_init + (( $+functions[$f_init] )) && $f_init + (( ++_p9k__segment_index )) + done + done + + if [[ -n $_POWERLEVEL9K_PUBLIC_IP_VPN_INTERFACE || + -n $_POWERLEVEL9K_IP_INTERFACE || + -n $_POWERLEVEL9K_VPN_IP_INTERFACE ]]; then + _p9k_prompt_net_iface_init + fi + + if [[ -n $_p9k__async_segments_compute ]]; then + functions[_p9k_async_segments_compute]=${(pj:\n:)_p9k__async_segments_compute} + _p9k_worker_start + fi + + local k v + for k v in ${(kv)_p9k_display_k}; do + [[ $k == -* ]] && continue + _p9k__display_v[v]=$k + _p9k__display_v[v+1]=show + done + _p9k__display_v[2]=hide + _p9k__display_v[4]=hide + + if (( $+functions[iterm2_decorate_prompt] )); then + _p9k__iterm2_decorate_prompt=$functions[iterm2_decorate_prompt] + function iterm2_decorate_prompt() { + typeset -g ITERM2_PRECMD_PS1=$PROMPT + typeset -g ITERM2_SHOULD_DECORATE_PROMPT= + } + fi + if (( $+functions[iterm2_precmd] )); then + _p9k__iterm2_precmd=$functions[iterm2_precmd] + functions[iterm2_precmd]='local _p9k_status=$?; zle && return; () { return $_p9k_status; }; '$_p9k__iterm2_precmd + fi + + if _p9k_segment_in_use todo; then + local todo=$commands[todo.sh] + if [[ -n $todo ]]; then + local bash=${commands[bash]:-:} + _p9k__todo_file="$(exec -a $todo $bash 2>/dev/null -c " + [ -e \"\$TODOTXT_CFG_FILE\" ] || TODOTXT_CFG_FILE=\$HOME/.todo/config + [ -e \"\$TODOTXT_CFG_FILE\" ] || TODOTXT_CFG_FILE=\$HOME/todo.cfg + [ -e \"\$TODOTXT_CFG_FILE\" ] || TODOTXT_CFG_FILE=\$HOME/.todo.cfg + [ -e \"\$TODOTXT_CFG_FILE\" ] || TODOTXT_CFG_FILE=\${XDG_CONFIG_HOME:-\$HOME/.config}/todo/config + [ -e \"\$TODOTXT_CFG_FILE\" ] || TODOTXT_CFG_FILE=${(qqq)todo:h}/todo.cfg + [ -e \"\$TODOTXT_CFG_FILE\" ] || TODOTXT_CFG_FILE=\${TODOTXT_GLOBAL_CFG_FILE:-/etc/todo/config} + [ -r \"\$TODOTXT_CFG_FILE\" ] || exit + source \"\$TODOTXT_CFG_FILE\" &>/dev/null + echo \"\$TODO_FILE\"")" + fi + fi + + if _p9k_segment_in_use dir && + [[ $_POWERLEVEL9K_SHORTEN_STRATEGY == truncate_with_package_name && $+commands[jq] == 0 ]]; then + print -rP -- '%F{yellow}WARNING!%f %BPOWERLEVEL9K_SHORTEN_STRATEGY=truncate_with_package_name%b requires %F{green}jq%f.' + print -rP -- 'Either install %F{green}jq%f or change the value of %BPOWERLEVEL9K_SHORTEN_STRATEGY%b.' + fi + + _p9k_init_vcs + + if (( _p9k__instant_prompt_disabled )); then + unset __p9k_instant_prompt_erased + _p9k_delete_instant_prompt + _p9k_dumped_instant_prompt_sigs=() + fi + + if (( $+__p9k_instant_prompt_erased )); then + unset __p9k_instant_prompt_erased + >&2 echo -E - "" + >&2 echo -E - "${(%):-[%1FERROR%f]: When using instant prompt, Powerlevel10k must be loaded before the first prompt.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):-You can:}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- - %BRecommended%b: Change the way Powerlevel10k is loaded from %B$__p9k_zshrc_u%b.}" + if (( _p9k_term_has_href )); then + >&2 echo - "${(%):- See \e]8;;https://github.com/romkatv/powerlevel10k/blob/master/README.md#installation\ahttps://github.com/romkatv/powerlevel10k/blob/master/README.md#installation\e]8;;\a.}" + else + >&2 echo - "${(%):- See https://github.com/romkatv/powerlevel10k/blob/master/README.md#installation.}" + fi + if (( $+functins[zplugin] )); then + >&2 echo -E - "${(%):- NOTE: If using %2Fzplugin%f to load %3F'romkatv/powerlevel10k'%f, %Bdo not apply%b %1Fice wait%f.}" + fi + >&2 echo -E - "" + >&2 echo -E - "${(%):- * You %Bwill not%b see this error message again.}" + >&2 echo -E - "${(%):- * Zsh will start %Bquickly%b.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- - Disable instant prompt either by running %Bp10k configure%b or by manually}" + >&2 echo -E - "${(%):- defining the following parameter:}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- %3Ftypeset%f -g POWERLEVEL9K_INSTANT_PROMPT=off}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- * You %Bwill not%b see this error message again.}" + >&2 echo -E - "${(%):- * Zsh will start %Bslowly%b.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- - Do nothing.}" + >&2 echo -E - "" + >&2 echo -E - "${(%):- * You %Bwill%b see this error message every time you start zsh.}" + >&2 echo -E - "${(%):- * Zsh will start %Bslowly%b.}" + >&2 echo -E - "" + fi +} + +_p9k_deinit() { + (( $+functions[_p9k_preinit] )) && unfunction _p9k_preinit + (( $+functions[gitstatus_stop_p9k_] )) && gitstatus_stop_p9k_ POWERLEVEL9K + _p9k_worker_stop + (( _p9k__state_dump_fd )) && exec {_p9k__state_dump_fd}>&- + (( $+_p9k__iterm2_precmd )) && functions[iterm2_precmd]=$_p9k__iterm2_precmd + (( $+_p9k__iterm2_decorate_prompt )) && functions[iterm2_decorate_prompt]=$_p9k__iterm2_decorate_prompt + unset -m '(_POWERLEVEL9K_|P9K_|_p9k_)*~(P9K_SSH|P9K_TTY)' + [[ -n $__p9k_locale ]] || unset __p9k_locale +} + +typeset -gi __p9k_enabled=0 +typeset -gi __p9k_configured=0 +typeset -gri __p9k_instant_prompt_disabled=1 + +# `typeset -g` doesn't roundtrip in zsh prior to 5.4. +if is-at-least 5.4; then + typeset -gri __p9k_dumps_enabled=1 +else + typeset -gri __p9k_dumps_enabled=0 +fi + +_p9k_do_nothing() { true; } + +_p9k_setup() { + (( __p9k_enabled )) && return + + prompt_opts=(percent subst) + if (( ! $+__p9k_instant_prompt_active )); then + prompt_opts+=sp + prompt_opts+=cr + fi + + prompt_powerlevel9k_teardown + __p9k_enabled=1 + typeset -ga preexec_functions=(_p9k_preexec1 $preexec_functions _p9k_preexec2) + typeset -ga precmd_functions=(_p9k_do_nothing $precmd_functions _p9k_precmd) +} + +prompt_powerlevel9k_setup() { + _p9k_restore_special_params + eval "$__p9k_intro" + _p9k_setup +} + +prompt_powerlevel9k_teardown() { + _p9k_restore_special_params + eval "$__p9k_intro" + add-zsh-hook -D precmd '(_p9k_|powerlevel9k_)*' + add-zsh-hook -D preexec '(_p9k_|powerlevel9k_)*' + PROMPT='%m%# ' + RPROMPT= + if (( __p9k_enabled )); then + _p9k_deinit + __p9k_enabled=0 + fi +} + +typeset -gr __p9k_p10k_usage="Usage: %2Fp10k%f %Bcommand%b [options] + +Commands: + + %Bconfigure%b run interactive configuration wizard + %Breload%b reload configuration + %Bsegment%b print a user-defined prompt segment + %Bdisplay%b show, hide or toggle prompt parts + %Bhelp%b print this help message + +Print help for a specific command: + + %2Fp10k%f %Bhelp%b command" + +typeset -gr __p9k_p10k_segment_usage="Usage: %2Fp10k%f %Bsegment%b [-h] [{+|-}re] [-s state] [-b bg] [-f fg] [-i icon] [-c cond] [-t text] + +Print a user-defined prompt segment. Can be called only during prompt rendering. + +Options: + -t text segment's main content; will undergo prompt expansion: '%%F{blue}%%*%%f' will + show as %F{blue}%*%f; default is empty + -i icon segment's icon; default is empty + -r icon is a symbolic reference that needs to be resolved; for example, 'LOCK_ICON' + +r icon is already resolved and should be printed literally; for example, '⭐'; + this is the default; you can also use \$'\u2B50' if you don't want to have + non-ascii characters in source code + -b bg background color; for example, 'blue', '4', or '#0000ff'; empty value means + transparent background, as in '%%k'; default is black + -f fg foreground color; for example, 'blue', '4', or '#0000ff'; empty value means + default foreground color, as in '%%f'; default is empty + -s state segment's state for the purpose of applying styling options; if you want to + to be able to use POWERLEVEL9K parameters to specify different colors or icons + depending on some property, use different states for different values of that + property + -c condition; if empty after parameter expansion and process substitution, the + segment is hidden; this is an advanced feature, use with caution; default is '1' + -e segment's main content will undergo parameter expansion and process + substitution; the content will be surrounded with double quotes and thus + should quote its own double quotes; this is an advanced feature, use with + caution + +e segment's main content should not undergo parameter expansion and process + substitution; this is the default + -h print this help message + +Example: 'core' segment tells you if there is a file name 'core' in the current directory. + +- Segment's icon is '⭐'. +- Segment's text is the file's size in bytes. +- If you have permissions to delete the file, state is DELETABLE. If not, it's PROTECTED. + + zmodload -F zsh/stat b:zstat + + function prompt_core() { + local size=() + if ! zstat -A size +size core 2>/dev/null; then + # No 'core' file in the current directory. + return + fi + if [[ -w . ]]; then + local state=DELETABLE + else + local state=PROTECTED + fi + p10k segment -s \$state -i '⭐' -f blue -t \${size[1]}b + } + +To enable this segment, add 'core' to POWERLEVEL9K_LEFT_PROMPT_ELEMENTS or +POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS. + +Example customizations: + + # Override default foreground. + POWERLEVEL9K_CORE_FOREGROUND=red + + # Override foreground when DELETABLE. + POWERLEVEL9K_CORE_DELETABLE_BACKGROUND=green + + # Override icon when PROTECTED. + POWERLEVEL9K_CORE_PROTECTED_VISUAL_IDENTIFIER_EXPANSION='❎' + + # Don't show file size when PROTECTED. + POWERLEVEL9K_CORE_PROTECTED_CONTENT_EXPANSION=''" + +typeset -gr __p9k_p10k_configure_usage="Usage: %2Fp10k%f %Bconfigure%b + +Run interactive configuration wizard." + +typeset -gr __p9k_p10k_reload_usage="Usage: %2Fp10k%f %Breload%b + +Reload configuration." + +typeset -gr __p9k_p10k_finalize_usage="Usage: %2Fp10k%f %Bfinalize%b + +Perform the final stage of initialization. Must be called at the very end of zshrc." + +typeset -gr __p9k_p10k_display_usage="Usage: %2Fp10k%f %Bdisplay%b part-pattern=state-list... + +Show, hide or toggle prompt parts. If called from zle, the current +prompt is refreshed. + +Usage: %2Fp10k%f %Bdisplay%b -a [part-pattern]... + +Populate array \`reply\` with states of prompt parts matching the patterns. +If no patterns are supplied, assume \`*\`. + +Parts: + empty_line empty line (duh) + ruler ruler; if POWERLEVEL9K_RULER_CHAR=' ', it's essentially another + new_line + N prompt line number N, 1-based; counting from the top if positive, + from the bottom if negative + N/left_frame left frame on the Nth line + N/left left prompt on the Nth line + N/gap gap between left and right prompts on the Nth line + N/right right prompt on the Nth line + N/right_frame right frame on the Nth line + N/left/S segment S within N/left (dir, time, etc.) + N/right/S segment S within N/right (dir, time, etc.) + +Part States: + show the part is displayed + hide the part is not displayed + print the part is printed in precmd; only applicable to empty_line and + ruler; unlike show, the effects of print cannot be undone with hide; + print used to look better after \`clear\` but this is no longer the + case; it's best to avoid it unless you know what you are doing + +part-pattern is a glob pattern for parts. Examples: + + */kubecontext all kubecontext prompt segments, regardless of where + they are + 1/(right|right_frame) all prompt segments and frame from the right side of + the first line + +state-list is a comma-separated list of states. Must have at least one element. +If more than one, states will rotate. + +Example: Bind Ctrl+P to toggle right prompt. + + function toggle-right-prompt() { p10k display '*/right'=hide,show; } + zle -N toggle-right-prompt + bindkey '^P' toggle-right-prompt + +Example: Print the current state of all prompt parts: + + typeset -A reply + p10k display -a '*' + printf '%%-32s = %%q\n' \${(@kv)reply} | sort +" + +# 0 -- reset-prompt not blocked +# 1 -- reset-prompt blocked and not needed +# 2 -- reset-prompt blocked and needed +typeset -gi __p9k_reset_state + +function p10k() { + [[ $# != 1 || $1 != finalize ]] || { p10k-instant-prompt-finalize; return 0 } + + eval "$__p9k_intro_no_reply" + + if (( !ARGC )); then + print -rP -- $__p9k_p10k_usage >&2 + return 1 + fi + + case $1 in + segment) + local REPLY + local -a reply + shift + local -i OPTIND + local OPTARG opt state bg=0 fg icon cond text ref=0 expand=0 + while getopts ':s:b:f:i:c:t:reh' opt; do + case $opt in + s) state=$OPTARG;; + b) bg=$OPTARG;; + f) fg=$OPTARG;; + i) icon=$OPTARG;; + c) cond=${OPTARG:-'${:-}'};; + t) text=$OPTARG;; + r) ref=1;; + e) expand=1;; + +r) ref=0;; + +e) expand=0;; + h) print -rP -- $__p9k_p10k_segment_usage; return 0;; + ?) print -rP -- $__p9k_p10k_segment_usage >&2; return 1;; + esac + done + if (( OPTIND <= ARGC )); then + print -rP -- $__p9k_p10k_segment_usage >&2 + return 1 + fi + if [[ -z $_p9k__prompt_side ]]; then + print -rP -- "%1F[ERROR]%f %Bp10k segment%b: can be called only during prompt rendering." >&2 + if (( !ARGC )); then + print -rP -- "" + print -rP -- "For help, type:" >&2 + print -rP -- "" + print -rP -- " %2Fp10k%f %Bhelp%b %Bsegment%b" >&2 + fi + return 1 + fi + (( ref )) || icon=$'\1'$icon + typeset -i _p9k__has_upglob + "_p9k_${_p9k__prompt_side}_prompt_segment" "prompt_${_p9k__segment_name}${state:+_${(U)state}}" \ + "$bg" "${fg:-$_p9k_color1}" "$icon" "$expand" "$cond" "$text" + return 0 + ;; + display) + if (( ARGC == 1 )); then + print -rP -- $__p9k_p10k_display_usage >&2 + return 1 + fi + shift + local -i k dump + local opt prev new pair list name var + while getopts ':ha' opt; do + case $opt in + a) dump=1;; + h) print -rP -- $__p9k_p10k_display_usage; return 0;; + ?) print -rP -- $__p9k_p10k_display_usage >&2; return 1;; + esac + done + if (( dump )); then + reply=() + shift $((OPTIND-1)) + (( ARGC )) || set -- '*' + for opt; do + for k in ${(u@)_p9k_display_k[(I)$opt]:/(#m)*/$_p9k_display_k[$MATCH]}; do + reply+=($_p9k__display_v[k,k+1]) + done + done + return 0 + fi + local REPLY + local -a reply + for opt in "${@:$OPTIND}"; do + pair=(${(s:=:)opt}) + list=(${(s:,:)${pair[2]}}) + if [[ ${(b)pair[1]} == $pair[1] ]]; then # this branch is purely for optimization + local ks=($_p9k_display_k[$pair[1]]) + else + local ks=(${(u@)_p9k_display_k[(I)$pair[1]]:/(#m)*/$_p9k_display_k[$MATCH]}) + fi + for k in $ks; do + if (( $#list == 1 )); then # this branch is purely for optimization + [[ $_p9k__display_v[k+1] == $list[1] ]] && continue + new=$list[1] + else + new=${list[list[(I)$_p9k__display_v[k+1]]+1]:-$list[1]} + [[ $_p9k__display_v[k+1] == $new ]] && continue + fi + _p9k__display_v[k+1]=$new + name=$_p9k__display_v[k] + if [[ $name == (empty_line|ruler) ]]; then + var=_p9k__${name}_i + [[ $new == show ]] && unset $var || typeset -gi $var=3 + elif [[ $name == (#b)(<->)(*) ]]; then + var=_p9k__${match[1]}${${${${match[2]//\/}/#left/l}/#right/r}/#gap/g} + [[ $new == hide ]] && typeset -g $var= || unset $var + fi + if (( __p9k_reset_state > 0 )); then + __p9k_reset_state=2 + else + __p9k_reset_state=-1 + fi + done + done + if (( __p9k_reset_state == -1 )); then + _p9k_reset_prompt + fi + ;; + configure) + if (( ARGC > 1 )); then + print -rP -- $__p9k_p10k_configure_usage >&2 + return 1 + fi + local REPLY + local -a reply + p9k_configure "$@" || return + ;; + reload) + if (( ARGC > 1 )); then + print -rP -- $__p9k_p10k_reload_usage >&2 + return 1 + fi + (( $+_p9k__force_must_init )) || return 0 + _p9k__force_must_init=1 + ;; + help) + local var=__p9k_p10k_$2_usage + if (( $+parameters[$var] )); then + print -rP -- ${(P)var} + return 0 + elif (( ARGC == 1 )); then + print -rP -- $__p9k_p10k_usage + return 0 + else + print -rP -- $__p9k_p10k_usage >&2 + return 1 + fi + ;; + finalize) + print -rP -- $__p9k_p10k_finalize_usage >&2 + return 1 + ;; + clear-instant-prompt) + if (( $+__p9k_instant_prompt_active )); then + _p9k_clear_instant_prompt + unset __p9k_instant_prompt_active + fi + return 0 + ;; + *) + print -rP -- $__p9k_p10k_usage >&2 + return 1 + ;; + esac +} + +# Hook for zplugin. +powerlevel10k_plugin_unload() { prompt_powerlevel9k_teardown; } + +function p10k-instant-prompt-finalize() { + unsetopt local_options + (( ${+__p9k_instant_prompt_active} )) && unsetopt prompt_cr prompt_sp || setopt prompt_cr prompt_sp +} + +autoload -Uz add-zsh-hook + +zmodload zsh/datetime +zmodload zsh/mathfunc +zmodload zsh/parameter 2>/dev/null # https://github.com/romkatv/gitstatus/issues/58#issuecomment-553407177 +zmodload zsh/system +zmodload zsh/termcap +zmodload zsh/terminfo +zmodload zsh/zleparameter +zmodload -F zsh/stat b:zstat +zmodload -F zsh/net/socket b:zsocket +zmodload -F zsh/files b:zf_mv b:zf_rm + +if [[ $__p9k_dump_file != $__p9k_instant_prompt_dump_file && -n $__p9k_instant_prompt_dump_file ]]; then + _p9k_delete_instant_prompt + zf_rm -f -- $__p9k_dump_file{,.zwc} 2>/dev/null + zf_rm -f -- $__p9k_instant_prompt_dump_file{,.zwc} 2>/dev/null +fi + +if [[ $+__p9k_instant_prompt_sourced == 1 && $__p9k_instant_prompt_sourced != $__p9k_instant_prompt_version ]]; then + _p9k_delete_instant_prompt + zf_rm -f -- $__p9k_dump_file{,.zwc} 2>/dev/null +fi + +_p9k_init_ssh +prompt_powerlevel9k_setup diff --git a/internal/parser.zsh b/internal/parser.zsh new file mode 100644 index 00000000..dc2082de --- /dev/null +++ b/internal/parser.zsh @@ -0,0 +1,382 @@ +typeset -grA __p9k_pb_cmd_skip=( + '}' 'always' # handled specially + '{' '' + '{' '' + '|' '' + '||' '' + '&' '' + '&&' '' + '|&' '' + '&!' '' + '&|' '' + ')' '' + '(' '' + '()' '' + '!' '' + ';' '' + 'if' '' + 'fi' '' + 'elif' '' + 'else' '' + 'then' '' + 'while' '' + 'until' '' + 'do' '' + 'done' '' + 'esac' '' + 'end' '' + 'coproc' '' + 'nocorrect' '' + 'noglob' '' + 'time' '' + '[[' '\]\]' + '((' '\)\)' + 'case' '\)|esac' + ';;' '\)|esac' + ';&' '\)|esac' + ';|' '\)|esac' + 'foreach' '\(*\)' +) + +typeset -grA __p9k_pb_precommand=( + '-' '' + 'builtin' '' + 'command' '' + 'exec' '-[^a]#[a]' + 'nohup' '' + 'setsid' '' + 'eatmydata' '' + 'catchsegv' '' + 'pkexec' '--user' + 'doas' '-[^aCu]#[acU]' + 'nice' '-[^n]#[n]|--adjustment' + 'stdbuf' '-[^ioe]#[ioe]|--(input|output|error)' + 'sudo' '-[^aghpuUCcrtT]#[aghpuUCcrtT]|--(close-from|group|host|prompt|role|type|other-user|command-timeout|user)' + 'ssh-agent' '-[^aEPt]#[aEPt]' + 'tabbed' '-[^gnprtTuU]#[gnprtTuU]' + 'chronic' '' + 'ifne' '' +) + +typeset -grA __p9k_pb_redirect=( + '&>' '' + '>' '' + '>&' '' + '<' '' + '<&' '' + '<>' '' + '&>|' '' + '>|' '' + '&>>' '' + '>>' '' + '>>&' '' + '&>>|' '' + '>>|' '' + '<<<' '' +) + +typeset -grA __p9k_pb_term=( + '|' '' + '||' '' + ';' '' + '&' '' + '&&' '' + '|&' '' + '&!' '' + '&|' '' + ';;' '' + ';&' '' + ';|' '' + '(' '' + ')' '' + '()' '' # handled specially + '}' '' # handled specially +) + +typeset -grA __p9k_pb_term_skip=( + '(' '\)' + ';;' '\)|esac' + ';&' '\)|esac' + ';|' '\)|esac' +) + +# Usage: _p9k_parse_buffer <buffer> [token-limit] +# +# Parses the specified command line buffer and pupulates array P9K_COMMANDS +# with commands from it. Terminates early and returns 1 if there are more +# tokens than the specified limit. +# +# Broken: +# +# --------------- +# : $(x) +# --------------- +# : `x` +# --------------- +# ${x/} +# --------------- +# - -- x +# --------------- +# command -p -p x +# --------------- +# * +# --------------- +# x=$y; $x +# --------------- +# alias x=y; y +# --------------- +# x <<END +# ; END +# END +# --------------- +# Setup: +# setopt interactive_comments +# alias x='#' +# Punchline: +# x; y +# --------------- +# +# More brokenness with non-standard options (ignore_braces, ignore_close_braces, etc.). +function _p9k_parse_buffer() { + [[ ${2:-0} == <-> ]] || return 2 + + local rcquotes + [[ -o rcquotes ]] && rcquotes=rcquotes + + eval "$__p9k_intro" + setopt no_nomatch $rcquotes + + typeset -ga P9K_COMMANDS=() + + local -r id='(<->|[[:alpha:]_][[:IDENT:]]#)' + local -r var="\$$id|\${$id}|\"\$$id\"|\"\${$id}\"" + + local -i e ic c=${2:-'1 << 62'} + local skip n s r state cmd prev + local -a aln alp alf v + + if [[ -o interactive_comments ]]; then + ic=1 + local tokens=(${(Z+C+)1}) + else + local tokens=(${(z)1}) + fi + + { + while (( $#tokens )); do + (( e = $#state )) + + while (( $#tokens == alp[-1] )); do + aln[-1]=() + alp[-1]=() + if (( $#tokens == alf[-1] )); then + alf[-1]=() + (( e = 0 )) + fi + done + + while (( c-- > 0 )) || return; do + token=$tokens[1] + tokens[1]=() + if (( $+galiases[$token] )); then + (( $aln[(eI)p$token] )) && break + s=$galiases[$token] + n=p$token + elif (( e )); then + break + elif (( $+aliases[$token] )); then + (( $aln[(eI)p$token] )) && break + s=$aliases[$token] + n=p$token + elif [[ $token == ?*.?* ]] && (( $+saliases[${token##*.}] )); then + r=${token##*.} + (( $aln[(eI)s$r] )) && break + s=${saliases[$r]%% #} + n=s$r + else + break + fi + aln+=$n + alp+=$#tokens + [[ $s == *' ' ]] && alf+=$#tokens + (( ic )) && tokens[1,0]=(${(Z+C+)s}) || tokens[1,0]=(${(z)s}) + done + + case $token in + '<<'(|-)) + state=h + continue + ;; + *('`'|['<>=$']'(')*) + if [[ $token == ('`'[^'`']##'`'|'"`'[^'`']##'`"'|'$('[^')']##')'|'"$('[^')']##')"'|['<>=']'('[^')']##')') ]]; then + s=${${token##('"'|)(['$<>']|)?}%%?('"'|)} + (( ic )) && tokens+=(';' ${(Z+C+)s}) || tokens+=(';' ${(z)s}) + fi + ;; + esac + + case $state in + *r) + state[-1]= + continue + ;; + a) + if [[ $token == $skip ]]; then + if [[ $token == '{' ]]; then + P9K_COMMANDS+=$cmd + cmd= + state= + else + skip='{' + fi + continue + else + state=t + fi + ;& # fall through + t|p*) + if (( $+__p9k_pb_term[$token] )); then + if [[ $token == '()' ]]; then + state= + else + P9K_COMMANDS+=$cmd + if [[ $token == '}' ]]; then + state=a + skip=always + else + skip=$__p9k_pb_term_skip[$token] + state=${skip:+s} + fi + fi + cmd= + continue + elif [[ $state == t ]]; then + continue + elif [[ $state == *x ]]; then + if (( $+__p9k_pb_redirect[$token] )); then + prev= + state[-1]=r + continue + else + state[-1]= + fi + fi + ;; + s) + if [[ $token == $~skip ]]; then + state= + fi + continue + ;; + h) + while (( $#tokens )); do + (( e = ${tokens[(i)${(Q)token}]} )) + if [[ $tokens[e-1] == ';' && $tokens[e+1] == ';' ]]; then + tokens[1,e]=() + break + else + tokens[1,e]=() + fi + done + while (( $#alp && alp[-1] >= $#tokens )); do + aln[-1]=() + alp[-1]=() + done + state=t + continue + ;; + esac + + if (( $+__p9k_pb_redirect[${token#<0-255>}] )); then + state+=r + continue + fi + + if [[ $token == *'$'* ]]; then + if [[ $token == $~var ]]; then + n=${${token##[^[:IDENT:]]}%%[^[:IDENT:]]} + [[ $token == *'"' ]] && v=("${(P)n}") || v=(${(P)n}) + tokens[1,0]=(${(@qq)v}) + continue + fi + fi + + case $state in + '') + if (( $+__p9k_pb_cmd_skip[$token] )); then + skip=$__p9k_pb_cmd_skip[$token] + [[ $token == '}' ]] && state=a || state=${skip:+s} + continue + fi + if [[ $token == *=* ]]; then + v=${(S)token/#(<->|([[:alpha:]_][[:IDENT:]]#(|'['*[^\\](\\\\)#']')))(|'+')=} + if (( $#v < $#token )); then + if [[ $v == '(' ]]; then + state=s + skip='\)' + fi + continue + fi + fi + : ${token::=${(Q)${~token}}} + ;; + p2) + if [[ -n $prev ]]; then + prev= + else + : ${token::=${(Q)${~token}}} + if [[ $token == '{'$~id'}' ]]; then + state=p2x + prev=$token + else + state=p + fi + continue + fi + ;& # fall through + p) + if [[ -n $prev ]]; then + token=$prev + prev= + else + : ${token::=${(Q)${~token}}} + case $token in + '{'$~id'}') prev=$token; state=px; continue;; + [^-]*) ;; + --) state=p1; continue;; + $~skip) state=p2; continue;; + *) continue;; + esac + fi + ;; + p1) + if [[ -n $prev ]]; then + token=$prev + prev= + else + : ${token::=${(Q)${~token}}} + if [[ $token == '{'$~id'}' ]]; then + state=p1x + prev=$token + continue + fi + fi + ;; + esac + + if (( $+__p9k_pb_precommand[$token] )); then + prev= + state=p + skip=$__p9k_pb_precommand[$token] + cmd+=$token$'\0' + else + state=t + [[ $token == ('(('*'))'|'`'*'`'|'$'*|['<>=']'('*')'|*$'\0'*) ]] || cmd+=$token$'\0' + fi + done + } always { + [[ $state == (px|p1x) ]] && cmd+=$prev + P9K_COMMANDS+=$cmd + P9K_COMMANDS=(${(u)P9K_COMMANDS%$'\0'}) + } +} diff --git a/internal/wizard.zsh b/internal/wizard.zsh new file mode 100755 index 00000000..b72212d5 --- /dev/null +++ b/internal/wizard.zsh @@ -0,0 +1,2068 @@ +local -i force=0 + +local opt +while getopts 'f' opt; do + case $opt in + f) force=1;; + +f) force=0;; + \?) return 1;; + esac +done + +if (( OPTIND <= ARGC )); then + print -lr -- "wizard.zsh: invalid arguments: $@" >&2 + return 1 +fi + +if (( $+terminfo[smcup] && $+terminfo[rmcup] )) && echoti smcup 2>/dev/null; then + function restore_screen() { + echoti rmcup 2>/dev/null + function restore_screen() {} + } +else + function restore_screen() {} +fi + +local -i success=0 + +{ # always + +local -ri force + +local -r font_base_url='https://github.com/romkatv/powerlevel10k-media/raw/master' + +local -ri prompt_indent=2 + +local -rA pure_original=(grey 242 red 1 yellow 3 blue 4 magenta 5 cyan 6 white 7) +local -rA pure_snazzy=(grey 242 red '#FF5C57' yellow '#F3F99D' blue '#57C7FF' magenta '#FF6AC1' cyan '#9AEDFE' white '#F1F1F0') +local -ra bg_color=(240 238 236 234) +local -ra sep_color=(248 246 244 242) +local -ra prefix_color=(250 248 246 244) + +local -r left_circle='\uE0B6' +local -r right_circle='\uE0B4' +local -r left_arc='\uE0B7' +local -r right_arc='\uE0B5' +local -r left_triangle='\uE0B2' +local -r right_triangle='\uE0B0' +local -r left_angle='\uE0B3' +local -r right_angle='\uE0B1' +local -r fade_in='░▒▓' +local -r fade_out='▓▒░' +local -r vertical_bar='\u2502' + +local -r cursor='%1{\e[07m \e[27m%}' + +local -r time_24h='16:23:42' +local -r time_12h='04:23:42 PM' + +local -ra lean_left=( + '%$frame_color[$color]F╭─ ' '${extra_icons[1]:+%f$extra_icons[1] }%31F$extra_icons[2]%B%39F~%b%31F/%B%39Fsrc%b%f $prefixes[1]%76F$extra_icons[3]master%f ' + '%$frame_color[$color]F╰─' '%76F$prompt_char%f ${buffer:-$cursor}' +) + +local -ra lean_right=( + ' $prefixes[2]%101F$extra_icons[4]5s%f${time:+ $prefixes[3]%66F$extra_icons[5]$time%f}' ' %$frame_color[$color]F─╮%f' + '' ' %$frame_color[$color]F─╯%f' +) + +local -ra lean_8colors_left=( + '%$frame_color[$color]F╭─ ' '${extra_icons[1]:+%f$extra_icons[1] }%4F$extra_icons[2]%4F~/src%f $prefixes[1]%2F$extra_icons[3]master%f ' + '%$frame_color[$color]F╰─' '%2F$prompt_char%f ${buffer:-$cursor}' +) + +local -ra lean_8colors_right=( + ' $prefixes[2]%3F$extra_icons[4]5s%f${time:+ $prefixes[3]%6F$extra_icons[5]$time%f}' ' %$frame_color[$color]F─╮%f' + '' ' %$frame_color[$color]F─╯%f' +) + +local -ra classic_left=( + '%$frame_color[$color]F╭─' '%F{$bg_color[$color]}$left_tail%K{$bg_color[$color]} ${extra_icons[1]:+%255F$extra_icons[1] %$sep_color[$color]F$left_subsep%f }%31F$extra_icons[2]%B%39F~%b%K{$bg_color[$color]}%31F/%B%39Fsrc%b%K{$bg_color[$color]} %$sep_color[$color]F$left_subsep%f %$prefix_color[$color]F$prefixes[1]%76F$extra_icons[3]master %k%$bg_color[$color]F$left_head%f' + '%$frame_color[$color]F╰─' '%f ${buffer:-$cursor}' +) + +local -ra classic_right=( + '%$bg_color[$color]F$right_head%K{$bg_color[$color]}%f %$prefix_color[$color]F$prefixes[2]%101F5s $extra_icons[4]${time:+%$sep_color[$color]F$right_subsep %$prefix_color[$color]F$prefixes[3]%66F$time $extra_icons[5]}%k%F{$bg_color[$color]}$right_tail%f' '%$frame_color[$color]F─╮%f' + '' '%$frame_color[$color]F─╯%f' +) + +local -ra pure_left=( + '' '%F{$pure_color[blue]}~/src%f %F{$pure_color[grey]}master%f ${pure_use_rprompt-%F{$pure_color[yellow]\}5s%f }' + '' '%F{$pure_color[magenta]}$prompt_char%f ${buffer:-$cursor}' +) + +local -ra pure_right=( + '${pure_use_rprompt+%F{$pure_color[yellow]\}5s%f${time:+ }}${time:+%F{$pure_color[grey]\}$time%f}' '' + '' '' +) + +local -ra rainbow_left=( + '%$frame_color[$color]F╭─' '%F{${${extra_icons[1]:+7}:-4}}$left_tail${extra_icons[1]:+%K{7\}%232F $extra_icons[1] %K{4\}%7F$left_sep}%K{4}%254F $extra_icons[2]%B%255F~%b%K{4}%254F/%B%255Fsrc%b%K{4} %K{2}%4F$left_sep %0F$prefixes[1]$extra_icons[3]master %k%2F$left_head%f' + '%$frame_color[$color]F╰─' '%f ${buffer:-$cursor}' +) + +local -ra rainbow_right=( + '%3F$right_head%K{3} %0F$prefixes[2]5s $extra_icons[4]%3F${time:+%7F$right_sep%K{7\} %0F$prefixes[3]$time $extra_icons[5]%7F}%k$right_tail%f' '%$frame_color[$color]F─╮%f' + '' '%$frame_color[$color]F─╯%f' +) + +function prompt_length() { + local COLUMNS=1024 + local -i x y=$#1 m + if (( y )); then + while (( ${${(%):-$1%$y(l.1.0)}[-1]} )); do + x=y + (( y *= 2 )); + done + local xy + while (( y > x + 1 )); do + m=$(( x + (y - x) / 2 )) + typeset ${${(%):-$1%$m(l.x.y)}[-1]}=$m + done + fi + REPLY=$x +} + +function print_prompt() { + [[ $parameters[extra_icons] == scalar* ]] && eval "local -a extra_icons=$extra_icons" + [[ $parameters[pure_color] == scalar* ]] && eval "local -A pure_color=$pure_color" + [[ $parameters[prefixes] == scalar* ]] && eval "local -a prefixes=$prefixes" + + local left=${style}_left + local right=${style}_right + left=("${(@P)left}") + right=("${(@P)right}") + (( disable_rprompt )) && right=() + eval "left=(${(@)left:/(#b)(*)/\"$match[1]\"})" + eval "right=(${(@)right:/(#b)(*)/\"$match[1]\"})" + if (( num_lines == 1)); then + left=($left[2] $left[4]) + right=($right[1] $right[3]) + else + local c=76 + [[ $style == pure ]] && c=$pure_color[magenta] + [[ $style == lean_8colors ]] && c=2 + (( left_frame )) || left=('' $left[2] '' "%F{$c}$prompt_char%f ${buffer:-$cursor}") + (( right_frame )) || right=($right[1] '' '' '') + fi + local -i left_indent=prompt_indent + local -i right_indent=prompt_indent + prompt_length ${(g::):-$left[1]$left[2]$right[1]$right[2]} + local -i width=REPLY + while (( wizard_columns - width <= left_indent + right_indent )); do + if (( right_indent )); then + (( --right_indent )) + elif (( left_indent )); then + (( --left_indent )) + else + print -P ' [%3Fnot enough horizontal space to display this%f]' + return 0 + fi + done + local -i i + for ((i = 1; i < $#left; i+=2)); do + local l=${(g::):-$left[i]$left[i+1]} + local r=${(g::):-$right[i]$right[i+1]} + prompt_length $l$r + local -i gap=$((wizard_columns - left_indent - right_indent - REPLY)) + (( num_lines == 2 && i == 1 )) && local fill=$gap_char || local fill=' ' + print -n -- ${(pl:$left_indent:: :)} + print -nP -- $l + print -nP -- "%$frame_color[$color]F${(pl:$gap::$fill:)}%f" + print -P -- $r + done +} + +function href() { + local url=${${1//\%/%%}//\\/\\\\} + if (( _p9k_term_has_href )); then + print -r -- '%{\e]8;;'$url'\a%}'$url'%{\e]8;;\a%}' + else + print -r -- $url + fi +} + +function flowing() { + (( ${wizard_columns:-0} )) || local -i wizard_columns=COLUMNS + local opt + local -i centered indentation + while getopts 'ci:' opt; do + case $opt in + i) indentation=$OPTARG;; + c) centered=1;; + +c) centered=0;; + \?) exit 1;; + esac + done + shift $((OPTIND-1)) + local line word lines=() + for word in "$@"; do + prompt_length ${(g::):-"$line $word"} + if (( REPLY > wizard_columns )); then + [[ -z $line ]] || lines+=$line + line= + fi + if [[ -n $line ]]; then + line+=' ' + elif (( $#lines )); then + line=${(pl:$indentation:: :)} + fi + line+=$word + done + [[ -z $line ]] || lines+=$line + for line in $lines; do + prompt_length ${(g::)line} + (( centered && REPLY < wizard_columns )) && print -n -- ${(pl:$(((wizard_columns - REPLY) / 2)):: :)} + print -P -- $line + done +} + +function clear() { + if (( $+commands[clear] )) && command clear 2>/dev/null; then + return + fi + echoti clear 2>/dev/null + print -n -- "\e[H\e[2J\e[3J" +} + +function hide_cursor() { + (( $+terminfo[cnorm] )) || return + echoti civis 2>/dev/null +} + +function show_cursor() { + echoti cnorm 2>/dev/null +} + +function consume_input() { + local key + while true; do + [[ -t 2 ]] + read -t0 -k key || break + done 2>/dev/null +} + +function quit() { + consume_input + if [[ $1 == '-c' ]]; then + print -Pr -- '' + print -Pr -- '%b%k%f%u%s' + print -Pr -- '%F{3}--- stack trace (most recent call first) ---%f' + print -lr -- $funcfiletrace + print -Pr -- '%F{3}--- end of stack trace ---%f' + print -Pr -- '' + print -Pr -- 'Press %BENTER%b to continue.' + hide_cursor + read -s + fi + restore_screen + print + if (( force )); then + flowing Powerlevel10k configuration wizard has been aborted. To run it again, type: + print -P "" + print -P " %2Fp10k%f %Bconfigure%b" + print -P "" + else + flowing \ + Powerlevel10k configuration wizard has been aborted. It will run again \ + next time unless you define at least one Powerlevel10k configuration option. \ + To define an option that does nothing except for disabling Powerlevel10k \ + configuration wizard, type the following command: + print -P "" + print -P " %2Fecho%f %3F'POWERLEVEL9K_DISABLE_CONFIGURATION_WIZARD=true'%f >>! $__p9k_zshrc_u" + print -P "" + flowing To run Powerlevel10k configuration wizard right now, type: + print -P "" + print -P " %2Fp10k%f %Bconfigure%b" + print -P "" + fi + function quit() {} + exit 1 +} + +local screen_widgets=() +local -i prompt_idx +local choice + +function add_widget() { + local priority=$1 + shift + local render="${(j: :)${(@q)*}}" + screen_widgets+=("$priority" "$render") +} + +function render_screen_pass() { + local -i pass=$1 + local -i prev_pass cur_pass + local prev_render cur_render + for cur_pass cur_render in "${(@)screen_widgets}" 0 ''; do + if (( prev_pass <= pass && (cur_pass == 0 || cur_pass > pass) )); then + eval $prev_render + fi + prev_pass=cur_pass + prev_render=$cur_render + done +} + +function get_columns() { return 'COLUMNS > 88 ? 88 : COLUMNS' } +functions -M get_columns 0 0 + +function render_screen() { + { + hide_cursor + while true; do + while true; do + typeset -gi wizard_columns='get_columns()' + typeset -gi wizard_lines=LINES + if (( wizard_columns < __p9k_wizard_columns )); then + clear + flowing -c %1FNot enough horizontal space.%f + print + flowing Make terminal window %Bwider%b or press %BCtrl-C%b to abort Powerlevel10k configuration wizard. + elif (( wizard_lines < __p9k_wizard_lines )); then + clear + flowing -c %1FNot enough vertical space.%f + print + flowing Make terminal window %Btaller%b or press %BCtrl-C%b to abort Powerlevel10k configuration wizard. + else + break + fi + while (( (COLUMNS > 88 ? 88 : COLUMNS) == wizard_columns && LINES == wizard_lines )); do + sleep 1 + done + done + + local -a passes + () { + local -i pass + local render + for pass render in "${(@)screen_widgets}"; do + passes+=$pass + done + passes=(${(onu)passes}) + } + + local -i pass + for pass in $passes; do + local content="$(render_screen_pass $pass)" + local lines=("${(@f)content}") + (( $#lines > wizard_lines )) && continue + clear + print -rn -- $content + return 0 + done + + clear + flowing -c %1FNot enough vertical space.%f + print + flowing Make terminal window %Btaller%b or press %BCtrl-C%b to abort Powerlevel10k configuration wizard. + while (( (COLUMNS > 88 ? 88 : COLUMNS) == wizard_columns && LINES == wizard_lines )); do + sleep 1 + done + done + } always { + show_cursor + } +} + +function add_prompt_n() { + add_widget 0 "$@" print_prompt + local var + for var; do + eval "local ${(q)var}" + done + if (( num_lines == 2 )); then + add_widget $(( 100 - ++prompt_idx )) print -P ' [%3Fnot enough vertical space to display this%f]' + fi +} + +function add_prompt() { + add_widget 0 print + add_widget 1 + add_prompt_n "$@" + add_widget 0 print + add_widget 2 +} + +function ask() { + local choices=$1 + local -i lines columns wizard_lines wizard_columns + add_widget 0 print -P "(q) Quit and do nothing." + add_widget 0 print + add_widget 0 print -P "%BChoice [${choices}q]: %b" + while true; do + =true + if (( LINES != lines || get_columns() != columns )); then + render_screen + lines=wizard_lines + columns=wizard_columns + fi + typeset -g choice= + if read -t1 -k choice; then + if [[ $choice == q ]]; then + quit + fi + if [[ $choices == *$choice* ]]; then + screen_widgets=() + prompt_idx=0 + return + fi + fi + done +} + +local -i greeting_printed=0 + +function print_greeting() { + (( greeting_printed )) && return + if (( force )); then + flowing -c This is %4FPowerlevel10k configuration wizard%f. \ + It will ask you a few questions and configure your prompt. + else + flowing -c This is %4FPowerlevel10k configuration wizard%f. \ + You are seeing it because you haven\'t defined any \ + Powerlevel10k configuration options. It will ask \ + you a few questions and configure your prompt. + fi + print -P "" +} + +function iterm_get() { + /usr/libexec/PlistBuddy -c "Print :$1" ~/Library/Preferences/com.googlecode.iterm2.plist +} + +local terminal iterm2_font_size iterm2_old_font=0 can_install_font=0 + +() { + [[ $P9K_SSH == 0 ]] || return + if [[ "$(uname)" == Linux && "$(uname -o)" == Android ]]; then + (( $+commands[termux-reload-settings] )) || return + (( $+commands[curl] )) || return + if [[ -f ~/.termux/font.ttf ]]; then + [[ -r ~/.termux/font.ttf ]] || return + [[ -w ~/.termux/font.ttf ]] || return + ! grep -q 'MesloLGS NF' ~/.termux/font.ttf 2>/dev/null || return + fi + if [[ -f ~/.termux ]]; then + [[ -d ~/.termux && -w ~/.termux ]] || return + else + [[ -w ~ ]] || return + fi + terminal=Termux + return 0 + fi + if [[ "$(uname)" == Darwin && $TERM_PROGRAM == iTerm.app ]]; then + (( $+commands[curl] )) || return + [[ $TERM_PROGRAM_VERSION == [2-9]* ]] || return + if [[ -f ~/Library/Fonts ]]; then + [[ -d ~/Library/Fonts && -w ~/Library/Fonts ]] || return + else + [[ -d ~/Library && -w ~/Library ]] || return + fi + [[ -x /usr/libexec/PlistBuddy ]] || return + [[ -x /usr/bin/plutil ]] || return + [[ -x /usr/bin/defaults ]] || return + [[ -f ~/Library/Preferences/com.googlecode.iterm2.plist ]] || return + [[ -r ~/Library/Preferences/com.googlecode.iterm2.plist ]] || return + [[ -w ~/Library/Preferences/com.googlecode.iterm2.plist ]] || return + local guid1 && guid1="$(iterm_get '"Default Bookmark Guid"' 2>/dev/null)" || return + local guid2 && guid2="$(iterm_get '"New Bookmarks":0:"Guid"' 2>/dev/null)" || return + local font && font="$(iterm_get '"New Bookmarks":0:"Normal Font"' 2>/dev/null)" || return + [[ $guid1 == $guid2 ]] || return + [[ $font != 'MesloLGS-NF-Regular '<-> ]] || return + [[ $font == (#b)*' '(<->) ]] || return + [[ $font == 'MesloLGSNer-Regular '<-> ]] && iterm2_old_font=1 + iterm2_font_size=$match[1] + terminal=iTerm2 + return 0 + fi + return 1 +} && can_install_font=1 + +function run_command() { + local msg=$1 + shift + [[ -n $msg ]] && print -nP -- "$msg ..." + local err && err="$("$@" 2>&1)" || { + print -P " %1FERROR%f" + print -P "" + print -nP "%BCommand:%b " + print -r -- "${(@q)*}" + if [[ -n $err ]]; then + print -P "" + print -r -- $err + fi + quit -c + } + [[ -n $msg ]] && print -P " %2FOK%f" +} + +function install_font() { + clear + case $terminal in + Termux) + mkdir -p ~/.termux || quit -c + run_command "Downloading %BMesloLGS NF Regular.ttf%b" \ + curl -fsSL -o ~/.termux/font.ttf "$font_base_url/MesloLGS%20NF%20Regular.ttf" + run_command "Reloading %BTermux%b settings" termux-reload-settings + ;; + iTerm2) + mkdir -p ~/Library/Fonts || quit -c + local style + for style in Regular Bold Italic 'Bold Italic'; do + local file="MesloLGS NF ${style}.ttf" + run_command "Downloading %B$file%b" \ + curl -fsSL -o ~/Library/Fonts/$file.tmp "$font_base_url/${file// /%20}" + zf_mv -f -- ~/Library/Fonts/$file{.tmp,} || quit -c + done + print -nP -- "Changing %BiTerm2%b settings ..." + local size=$iterm2_font_size + [[ $size == 12 ]] && size=13 + local k t v settings=( + '"Normal Font"' string '"MesloLGS-NF-Regular '$size'"' + '"Terminal Type"' string '"xterm-256color"' + '"Horizontal Spacing"' real 1 + '"Vertical Spacing"' real 1 + '"Minimum Contrast"' real 0 + '"Use Bold Font"' bool 1 + '"Use Bright Bold"' bool 1 + '"Use Italic Font"' bool 1 + '"ASCII Anti Aliased"' bool 1 + '"Non-ASCII Anti Aliased"' bool 1 + '"Use Non-ASCII Font"' bool 0 + '"Ambiguous Double Width"' bool 0 + '"Draw Powerline Glyphs"' bool 1 + ) + for k t v in $settings; do + /usr/libexec/PlistBuddy -c "Set :\"New Bookmarks\":0:$k $v" \ + ~/Library/Preferences/com.googlecode.iterm2.plist && continue + run_command "" /usr/libexec/PlistBuddy -c \ + "Add :\"New Bookmarks\":0:$k $t $v" ~/Library/Preferences/com.googlecode.iterm2.plist + done + print -P " %2FOK%f" + print -nP "Updating %BiTerm2%b settings cache ..." + run_command "" /usr/bin/defaults read com.googlecode.iterm2 + sleep 3 + print -P " %2FOK%f" + sleep 1 + restore_screen + print + flowing +c "%2FMeslo Nerd Font%f" successfully installed. + print -P "" + flowing +c Please "%Brestart iTerm2%b" for the changes to take effect. + print -P "" + while true; do + flowing +c -i 5 " 1. Click" "%BiTerm2 → Quit iTerm2%b" or press "%B⌘ Q%b." + flowing +c -i 5 " 2. Open %BiTerm2%b." + print -P "" + local key= + read -k key${(%):-"?%BWill you restart iTerm2 before proceeding? [yN]: %b"} || quit -c + if [[ $key = (y|Y) ]]; then + print -P "" + print -P "" + exit 69 + fi + print -P "" + print -P "" + flowing +c "It's" important to "%Brestart iTerm2%b" for the changes to take effect. + print -P "" + done + ;; + esac + + return 0 +} + +function ask_font() { + (( can_install_font )) || return 0 + add_widget 0 print_greeting + if (( iterm2_old_font )); then + add_widget 0 flowing -c A new version of '%2FMeslo Nerd Font%f' is available. '%BInstall?%b' + else + add_widget 0 flowing -c %BInstall '%b%2FMeslo Nerd Font%f%B?%b' + fi + add_widget 0 print + add_widget 0 print -P "%B(y) Yes (recommended).%b" + add_widget 0 print + add_widget 1 + add_widget 0 print -P "%B(n) No. Use the current font.%b" + add_widget 0 print + add_widget 1 + ask yn + greeting_printed=1 + case $choice in + y) + ask_remove_font || return + install_font + ;; + n) ;; + esac + return 0 +} + +function print_file_path() { + local file=$1 + if (( ${(m)#file} > wizard_columns - 2 )); then + file[wizard_columns-4,-1]='...' + fi + add_widget 0 print -P " %B${file//\%/%%}%b" +} + +function ask_remove_font() { + local font + local -a fonts + local -i protected + for font in {,/System,~}/Library/Fonts/**/*[Mm]eslo*.(ttf|otf)(N:A); do + [[ -f $font && -r $font ]] || continue + [[ $font == ~/Library/Fonts/'MesloLGS NF '(Regular|Bold|Italic|Bold\ Italic).ttf ]] && continue + [[ "$(<$font)" == *"MesloLGS NF"$'\0'* ]] || continue + fonts+=$font + [[ -w ${font:h} ]] || protected=1 + done + (( $#fonts )) || return 0 + add_widget 0 flowing -c A variant of "%2FMeslo Nerd Font%f" is already installed. + add_widget 0 print -P "" + for font in $fonts; do + add_widget 0 print_file_path $font + done + add_widget 0 print -P "" + if (( protected )); then + if (( $#fonts == 1 )); then + add_widget 0 flowing Please %Bdelete%b this file and run '%2Fp10k%f %Bconfigure%b.' + else + add_widget 0 flowing Please %Bdelete%b these files and run '%2Fp10k%f %Bconfigure%b.' + fi + add_widget 0 print + restore_screen + local pass render + for pass render in "${(@)screen_widgets}"; do + (( pass == 0 )) && eval $render + done + exit 1 + fi + if (( $#fonts == 1 )); then + add_widget 0 flowing -c "%BDelete this file?%b" + else + add_widget 0 flowing -c "%BDelete these files?%b" + fi + add_widget 0 print -P "" + add_widget 0 print -P "%B(y) Yes (recommended).%b" + add_widget 0 print -P "" + add_widget 0 print -P "(r) Restart from the beginning." + ask yr + case $choice in + r) return 1;; + y) zf_rm -f -- $fonts || quit -c;; + esac + return 0 +} + +function ask_diamond() { + local extra + add_widget 0 print_greeting + add_widget 0 flowing -c %BDoes this look like a%b %2Fdiamond%f '%B(rotated square)?%b' + add_widget 0 flowing -c reference: "$(href https://graphemica.com/%E2%97%86)" + add_widget 0 print + add_widget 0 flowing -c -- "---> \uE0B2\uE0B0 <---" + add_widget 0 print + add_widget 1 + add_widget 0 print -P "%B(y) Yes.%b" + add_widget 0 print + add_widget 1 + add_widget 0 print -P "%B(n) No.%b" + add_widget 0 print + add_widget 1 + if (( can_install_font )); then + extra+=r + add_widget 0 print -P "(r) Restart from the beginning." + fi + ask yn$extra + greeting_printed=1 + case $choice in + r) return 1;; + y) cap_diamond=1;; + n) cap_diamond=0;; + esac + return 0 +} + +function ask_lock() { + [[ -n $2 ]] && add_widget 0 flowing -c "$2" + add_widget 0 flowing -c "%BDoes this look like a %b%2Flock%f%B?%b" + add_widget 0 flowing -c "reference: $(href https://fontawesome.com/icons/lock)" + add_widget 0 print + add_widget 0 flowing -c -- "---> $1 <---" + add_widget 0 print + add_widget 0 print -P "%B(y) Yes.%b" + add_widget 0 print + add_widget 0 print -P "%B(n) No.%b" + add_widget 0 print + add_widget 0 print -P "(r) Restart from the beginning." + ask ynr + case $choice in + r) return 1;; + y) cap_lock=1;; + n) cap_lock=0;; + esac + return 0 +} + +function ask_python() { + add_widget 0 flowing -c %BDoes this look like a "%b%2FPython logo%f%B?%b" + add_widget 0 flowing -c reference: "$(href https://fontawesome.com/icons/python)" + add_widget 0 print -P "" + add_widget 0 flowing -c -- "---> \uE63C <---" + add_widget 0 print -P "" + add_widget 0 print -P "%B(y) Yes.%b" + add_widget 0 print -P "" + add_widget 0 print -P "%B(n) No.%b" + add_widget 0 print -P "" + add_widget 0 print -P "(r) Restart from the beginning." + ask ynr + case $choice in + r) return 1;; + y) cap_python=1;; + n) cap_python=0;; + esac + return 0 +} + +function ask_arrow() { + add_widget 0 flowing -c %BDoes this look like%b "%2F><%f" %Bbut taller and "fatter?%b" + add_widget 0 print -P "" + add_widget 0 flowing -c -- "---> \u276F\u276E <---" + add_widget 0 print -P "" + add_widget 0 print -P "%B(y) Yes.%b" + add_widget 0 print -P "" + add_widget 0 print -P "%B(n) No.%b" + add_widget 0 print -P "" + add_widget 0 print -P "(r) Restart from the beginning." + ask ynr + case $choice in + r) return 1;; + y) cap_arrow=1;; + n) cap_arrow=0;; + esac + return 0 +} + +function ask_debian() { + add_widget 0 flowing -c %BDoes this look like a%b "%2FDebian logo%f" "%B(swirl/spiral)?%b" + add_widget 0 flowing -c reference: "$(href https://debian.org/logos/openlogo-nd.svg)" + add_widget 0 print -P "" + add_widget 0 flowing -c -- "---> \uF306 <---" + add_widget 0 print -P "" + add_widget 0 print -P "%B(y) Yes.%b" + add_widget 0 print -P "" + add_widget 0 print -P "%B(n) No.%b" + add_widget 0 print -P "" + add_widget 0 print -P "(r) Restart from the beginning." + ask ynr + case $choice in + r) return 1;; + y) cap_debian=1;; + n) cap_debian=0;; + esac + return 0 +} + +function ask_icon_padding() { + if [[ $POWERLEVEL9K_MODE == (powerline|compatible|ascii) ]]; then + POWERLEVEL9K_ICON_PADDING=none + return 0 + fi + + local text="X" + text+="%1F${icons[VCS_GIT_ICON]// }%fX" + text+="%2F${icons[VCS_GIT_GITHUB_ICON]// }%fX" + text+="%3F${icons[TIME_ICON]// }%fX" + text+="%4F${icons[RUBY_ICON]// }%fX" + text+="%5F${icons[HOME_ICON]// }%fX" + text+="%6F${icons[HOME_SUB_ICON]// }%fX" + text+="%1F${icons[FOLDER_ICON]// }%fX" + text+="%2F${icons[RAM_ICON]// }%fX" + + add_widget 0 flowing -c %BDo all these icons "%b%2Ffit between the crosses%f%B?%b" + add_widget 0 print -P "" + add_widget 0 flowing -c -- "---> $text <---" + add_widget 0 print -P "" + add_widget 0 flowing +c -i 5 "%B(y) Yes." Icons are very close to the crosses but there is "%b%2Fno overlap%f%B.%b" + add_widget 0 print -P "" + add_widget 0 flowing +c -i 5 "%B(n) No." Some icons "%b%2Foverlap%f%B" neighbouring crosses.%b + add_widget 0 print -P "" + add_widget 0 print -P "(r) Restart from the beginning." + ask ynr + case $choice in + r) return 1;; + y) + POWERLEVEL9K_ICON_PADDING=none + options+='small icons' + ;; + n) + POWERLEVEL9K_ICON_PADDING=moderate + options+='large icons' + up_triangle+=' ' + down_triangle+=' ' + slanted_bar='\uE0BD ' + ;; + esac + return 0 +} + +function ask_style() { + if (( terminfo[colors] < 256 )); then + style=lean_8colors + left_frame=0 + right_frame=0 + frame_color=(0 7 2 4) + color_name=(Black White Green Blue) + options+=lean_8colors + return 0 + fi + local extra + add_widget 0 flowing -c "%BPrompt Style%b" + add_widget 0 print + add_widget 1 + add_widget 0 print -P "%B(1) Lean.%b" + add_prompt style=lean left_frame=0 right_frame=0 + add_widget 0 print -P "%B(2) Classic.%b" + add_prompt style=classic + add_widget 0 print -P "%B(3) Rainbow.%b" + add_prompt style=rainbow + if [[ $POWERLEVEL9K_MODE != ascii ]]; then + extra+=4 + add_widget 0 print -P "%B(4) Pure.%b" + add_prompt style=pure + fi + add_widget 0 print -P "(r) Restart from the beginning." + ask 123${extra}r + case $choice in + r) return 1;; + 1) style=lean; left_frame=0; right_frame=0; options+=lean;; + 2) style=classic; options+=classic;; + 3) style=rainbow; options+=rainbow;; + 4) style=pure; empty_line=1; options+=pure;; + esac + return 0 +} + +function ask_charset() { + [[ $style == (lean*|classic|rainbow) && $POWERLEVEL9K_MODE != ascii ]] || return 0 + add_widget 0 flowing -c "%BCharacter Set%b" + add_widget 0 print -P "" + add_widget 1 + add_widget 0 print -P "%B(1) Unicode.%b" + add_prompt + add_widget 0 print -P "%B(2) ASCII.%b" + add_prompt \ + left_sep= \ + right_sep= \ + left_subsep='|' \ + right_subsep='|' \ + left_head= \ + right_head= \ + prompt_char='>' \ + left_frame=0 \ + right_frame=0 + add_widget 0 print -P "(r) Restart from the beginning." + ask 12r + case $choice in + r) return 1;; + 1) options+=unicode;; + 2) + options+=ascii + left_sep= + right_sep= + left_subsep='|' + right_subsep='|' + left_head= + right_head= + prompt_char='>' + left_frame=0 + right_frame=0 + POWERLEVEL9K_MODE=ascii + POWERLEVEL9K_ICON_PADDING=none + cap_diamond=0 + cap_python=0 + cap_debian=0 + cap_lock=0 + cap_arrow=0 + ;; + esac + return 0 +} + +function ask_color_scheme() { + (( terminfo[colors] < 256 )) && return + if [[ $style == lean ]]; then + add_widget 0 flowing -c "%BPrompt Colors%b" + add_widget 0 print -P "" + add_widget 1 + add_widget 0 print -P "%B(1) 256 colors.%b" + add_prompt style=lean + add_widget 0 print -P "%B(2) 8 colors.%b" + add_prompt style=lean_8colors + add_widget 0 print -P "(r) Restart from the beginning." + ask 12r + case $choice in + r) return 1;; + 1) style=lean;; + 2) + style=lean_8colors + frame_color=(0 7 2 4) + color_name=(Black White Green Blue) + ;; + esac + options=(${options:#lean} $style) + elif [[ $style == pure && $has_truecolor == 1 ]]; then + add_widget 0 flowing -c "%BPrompt Colors%b" + add_widget 0 print -P "" + add_widget 1 + add_widget 0 print -P "%B(1) Original.%b" + add_prompt "pure_color=(${(j: :)${(@q)${(@kv)pure_original}}})" + add_widget 0 print -P "%B(2) Snazzy.%b" + add_prompt "pure_color=(${(j: :)${(@q)${(@kv)pure_snazzy}}})" + add_widget 0 print -P "(r) Restart from the beginning." + ask 12r + case $choice in + r) return 1;; + 1) + pure_color=(${(kv)pure_original}) + options+=original + ;; + 2) + pure_color=(${(kv)pure_snazzy}) + options+=snazzy + ;; + esac + fi + return 0 +} + +function ask_color() { + [[ $style != classic ]] && return + add_widget 0 flowing -c "%BPrompt Color%b" + add_widget 0 print + add_widget 1 + add_widget 0 print -P "%B(1) $color_name[1].%b" + add_prompt color=1 + add_widget 0 print -P "%B(2) $color_name[2].%b" + add_prompt color=2 + add_widget 0 print -P "%B(3) $color_name[3].%b" + add_prompt color=3 + add_widget 0 print -P "%B(4) $color_name[4].%b" + add_prompt color=4 + add_widget 0 print -P "(r) Restart from the beginning." + ask 1234r + case $choice in + r) return 1;; + [1-4]) color=$choice;; + esac + options+=${(L)color_name[color]} + return 0 +} + +function ask_ornaments_color() { + [[ $style != (rainbow|lean*) || $num_lines == 1 ]] && return + [[ $gap_char == ' ' && $left_frame == 0 && $right_frame == 0 ]] && return + local ornaments=() + [[ $gap_char != ' ' ]] && ornaments+=Connection + (( left_frame || right_frame )) && ornaments+=Frame + add_widget 0 flowing -c "%B${(j: & :)ornaments} Color%b" + add_widget 0 print + add_widget 1 + add_widget 0 print -P "%B(1) $color_name[1].%b" + add_prompt color=1 + add_widget 0 print -P "%B(2) $color_name[2].%b" + add_prompt color=2 + add_widget 0 print -P "%B(3) $color_name[3].%b" + add_prompt color=3 + add_widget 0 print -P "%B(4) $color_name[4].%b" + add_prompt color=4 + add_widget 0 print -P "(r) Restart from the beginning." + ask 1234r + case $choice in + r) return 1;; + [1-4]) color=$choice;; + esac + options+=${(L)color_name[color]}-ornaments + return 0 +} + +function ask_time() { + local extra + add_widget 0 flowing -c "%BShow current time?%b" + add_widget 0 print + add_widget 1 + add_widget 0 print -P "%B(1) No.%b" + add_prompt time= + add_widget 0 print -P "%B(2) 24-hour format.%b" + add_prompt time=$time_24h + add_widget 0 print -P "%B(3) 12-hour format.%b" + add_prompt time=$time_12h + add_widget 0 print -P "(r) Restart from the beginning." + ask 123r + case $choice in + r) return 1;; + 1) time=;; + 2) time=$time_24h; options+='24h time';; + 3) time=$time_12h; options+='12h time';; + esac + return 0 +} + +function ask_use_rprompt() { + [[ $style != pure ]] && return + add_widget 0 flowing -c "%BNon-permanent content location%b" + add_widget 0 print + add_widget 1 + add_widget 0 print -P "%B(1) Left.%b" + add_prompt + add_widget 0 print -P "%B(2) Right.%b" + add_prompt pure_use_rprompt= + add_widget 0 print -P "(r) Restart from the beginning." + ask 12r + case $choice in + r) return 1;; + 1) ;; + 2) pure_use_rprompt=; options+=rpromt;; + esac + return 0 +} + +function os_icon_name() { + local uname="$(uname)" + if [[ $uname == Linux && "$(uname -o 2>/dev/null)" == Android ]]; then + echo ANDROID_ICON + else + case $uname in + SunOS) echo SUNOS_ICON;; + Darwin) echo APPLE_ICON;; + CYGWIN_NT-* | MSYS_NT-*) echo WINDOWS_ICON;; + FreeBSD|OpenBSD|DragonFly) echo FREEBSD_ICON;; + Linux) + local os_release_id + if [[ -r /etc/os-release ]]; then + local lines=(${(f)"$(</etc/os-release)"}) + lines=(${(@M)lines:#ID=*}) + (( $#lines == 1 )) && os_release_id=${lines[1]#ID=} + fi + case $os_release_id in + *arch*) echo LINUX_ARCH_ICON;; + *debian*) echo LINUX_DEBIAN_ICON;; + *raspbian*) echo LINUX_RASPBIAN_ICON;; + *ubuntu*) echo LINUX_UBUNTU_ICON;; + *elementary*) echo LINUX_ELEMENTARY_ICON;; + *fedora*) echo LINUX_FEDORA_ICON;; + *coreos*) echo LINUX_COREOS_ICON;; + *gentoo*) echo LINUX_GENTOO_ICON;; + *mageia*) echo LINUX_MAGEIA_ICON;; + *centos*) echo LINUX_CENTOS_ICON;; + *opensuse*|*tumbleweed*) echo LINUX_OPENSUSE_ICON;; + *sabayon*) echo LINUX_SABAYON_ICON;; + *slackware*) echo LINUX_SLACKWARE_ICON;; + *linuxmint*) echo LINUX_MINT_ICON;; + *alpine*) echo LINUX_ALPINE_ICON;; + *aosc*) echo LINUX_AOSC_ICON;; + *nixos*) echo LINUX_NIXOS_ICON;; + *devuan*) echo LINUX_DEVUAN_ICON;; + *manjaro*) echo LINUX_MANJARO_ICON;; + *void*) echo LINUX_VOID_ICON;; + *) echo LINUX_ICON;; + esac + ;; + esac + fi +} + +function ask_extra_icons() { + if [[ $style == pure || $POWERLEVEL9K_MODE == (powerline|compatible|ascii) ]]; then + return 0 + fi + local os_icon=${(g::)icons[$(os_icon_name)]} + local dir_icon=${(g::)icons[HOME_SUB_ICON]} + local vcs_icon=${(g::)icons[VCS_GIT_GITHUB_ICON]} + local branch_icon=${(g::)icons[VCS_BRANCH_ICON]} + local duration_icon=${(g::)icons[EXECUTION_TIME_ICON]} + local time_icon=${(g::)icons[TIME_ICON]} + branch_icon=${branch_icon// } + local few=('' '' '' '' '') + local many=("$os_icon" "$dir_icon " "$vcs_icon $branch_icon " "$duration_icon " "$time_icon ") + add_widget 0 flowing -c "%BIcons%b" + add_widget 0 print + add_widget 1 + add_widget 0 print -P "%B(1) Few icons.%b" + add_prompt "extra_icons=(${(j: :)${(@q)few}})" + add_widget 0 print -P "%B(2) Many icons.%b" + add_prompt "extra_icons=(${(j: :)${(@q)many}})" + add_widget 0 print -P "(r) Restart from the beginning." + ask 12r + case $choice in + r) return 1;; + 1) extra_icons=("$few[@]"); options+='few icons';; + 2) extra_icons=("$many[@]"); options+='many icons';; + esac + return 0 +} + +function ask_prefixes() { + if [[ $style == pure ]]; then + return 0 + fi + local concise=('' '' '') + local fluent=('on ' 'took ' 'at ') + add_widget 0 flowing -c "%BPrompt Flow%b" + add_widget 0 print + add_widget 1 + add_widget 0 print -P "%B(1) Concise.%b" + add_prompt "prefixes=(${(j: :)${(@q)concise}})" + add_widget 0 print -P "%B(2) Fluent.%b" + add_prompt "prefixes=(${(j: :)${(@q)fluent}})" + add_widget 0 print -P "(r) Restart from the beginning." + ask 12r + case $choice in + r) return 1;; + 1) prefixes=("$concise[@]"); options+=concise;; + 2) prefixes=("$fluent[@]"); options+=fluent;; + esac + return 0 +} + +function ask_separators() { + if [[ $style != (classic|rainbow) || $cap_diamond != 1 ]]; then + return 0 + fi + local extra + add_widget 0 flowing -c "%BPrompt Separators%b" + add_widget 0 print -Pl " separator" "%B(1) Angled.%b /" " /" + add_widget 3 print -P "%B(1) Angled.%b" + add_prompt_n left_sep=$right_triangle right_sep=$left_triangle left_subsep=$right_angle right_subsep=$left_angle + add_widget 0 print + add_widget 2 + add_widget 0 print -P "%B(2) Vertical.%b" + add_prompt left_sep='' right_sep='' left_subsep=$vertical_bar right_subsep=$vertical_bar + if [[ $POWERLEVEL9K_MODE == nerdfont-complete ]]; then + extra+=3 + add_widget 0 print -P "%B(3) Slanted.%b" + add_prompt left_sep=$down_triangle right_sep=$up_triangle left_subsep=$slanted_bar right_subsep=$slanted_bar + extra+=4 + add_widget 0 print -P "%B(4) Round.%b" + add_prompt left_sep=$right_circle right_sep=$left_circle left_subsep=$right_arc right_subsep=$left_arc + fi + add_widget 0 print -P "(r) Restart from the beginning." + ask 12${extra}r + case $choice in + r) return 1;; + 1) + left_sep=$right_triangle + right_sep=$left_triangle + left_subsep=$right_angle + right_subsep=$left_angle + options+='angled separators' + ;; + 2) + left_sep='' + right_sep='' + left_subsep=$vertical_bar + right_subsep=$vertical_bar + options+='vertical separators' + ;; + 3) + left_sep=$down_triangle + right_sep=$up_triangle + left_subsep=$slanted_bar + right_subsep=$slanted_bar + options+='slanted separators' + ;; + 4) + left_sep=$right_circle + right_sep=$left_circle + left_subsep=$right_arc + right_subsep=$left_arc + options+='round separators' + ;; + esac + return 0 +} + +function ask_heads() { + if [[ $style != (classic|rainbow) || $POWERLEVEL9K_MODE == ascii ]]; then + return 0 + fi + local extra + add_widget 0 flowing -c "%BPrompt Heads%b" + if (( cap_diamond )); then + add_widget 0 print -Pl " head" "%B(1) Sharp.%b |" " v" + add_widget 3 print -P "%B(1) Sharp.%b" + add_prompt_n left_head=$right_triangle right_head=$left_triangle + add_widget 0 print + add_widget 2 + else + add_widget 0 print + add_widget 1 + add_widget 0 print -P "%B(1) Flat.%b" + add_prompt left_head= right_head= + fi + add_widget 0 print -P "%B(2) Blurred.%b" + add_prompt left_head=$fade_out right_head=$fade_in + if [[ $POWERLEVEL9K_MODE == nerdfont-complete ]]; then + extra+=3 + add_widget 0 print -P "%B(3) Slanted.%b" + add_prompt left_head=$down_triangle right_head=$up_triangle + extra+=4 + add_widget 0 print -P "%B(4) Round.%b" + add_prompt left_head=$right_circle right_head=$left_circle + fi + add_widget 0 print -P "(r) Restart from the beginning." + ask 12${extra}r + case $choice in + r) return 1;; + 1) + if (( cap_diamond )); then + left_head=$right_triangle + right_head=$left_triangle + options+='sharp heads' + else + left_head= + right_head= + options+='flat heads' + fi + ;; + 2) + left_head=$fade_out + right_head=$fade_in + options+='blurred heads' + ;; + 3) + left_head=$down_triangle + right_head=$up_triangle + options+='slanted heads' + ;; + 4) + left_head=$right_circle + right_head=$left_circle + options+='round heads' + ;; + esac + return 0 +} + +function print_tail_marker() { + local label='(1) Flat.' + local -i n='wizard_columns - 7' + local -i m=$((n - $#label)) + print -P "${(l:$n:: :)}tail" + print -P "%B$label%b${(l:$m:: :)} |" + print -P "${(l:$n:: :)} v" +} + +function ask_tails() { + if [[ $style != (classic|rainbow) || $POWERLEVEL9K_MODE == ascii ]]; then + return 0 + fi + local extra + add_widget 0 flowing -c "%BPrompt Tails%b" + add_widget 0 print_tail_marker + add_widget 3 print -P "%B(1) Flat.%b" + add_prompt_n left_tail='' right_tail='' + add_widget 0 print + add_widget 2 + add_widget 0 print -P "%B(2) Blurred.%b" + add_prompt left_tail=$fade_in right_tail=$fade_out + if (( cap_diamond )); then + extra+=3 + add_widget 0 print -P "%B(3) Sharp.%b" + add_prompt left_tail=$left_triangle right_tail=$right_triangle + if [[ $POWERLEVEL9K_MODE == nerdfont-complete ]]; then + extra+=4 + add_widget 0 print -P "%B(4) Slanted.%b" + add_prompt left_tail=$up_triangle right_tail=$down_triangle + extra+=5 + add_widget 0 print -P "%B(5) Round.%b" + add_prompt left_tail=$left_circle right_tail=$right_circle + fi + fi + add_widget 0 print -P "(r) Restart from the beginning." + ask 12${extra}r + case $choice in + r) return 1;; + 1) left_tail=''; right_tail=''; options+='flat tails';; + 2) left_tail=$fade_in; right_tail=$fade_out; options+='blurred tails';; + 3) + left_tail=$left_triangle + right_tail=$right_triangle + options+='sharp tails' + ;; + 4) + left_tail=$up_triangle + right_tail=$down_triangle + options+='slanted tails' + ;; + 5) + left_tail=$left_circle + right_tail=$right_circle + options+='round tails' + ;; + esac + return 0 +} + +function ask_num_lines() { + add_widget 0 flowing -c "%BPrompt Height%b" + add_widget 0 print + add_widget 1 + add_widget 0 print -P "%B(1) One line.%b" + add_prompt num_lines=1 + add_widget 0 print -P "%B(2) Two lines.%b" + add_prompt num_lines=2 + add_widget 0 print -P "(r) Restart from the beginning." + ask 12r + case $choice in + r) return 1;; + 1) num_lines=1; options+='1 line';; + 2) num_lines=2; options+='2 lines';; + esac + return 0 +} + +function ask_gap_char() { + [[ $num_lines != 2 || $style == pure ]] && return + if [[ $POWERLEVEL9K_MODE == ascii ]]; then + local dot='.' + local dash='-' + else + local dot='·' + local dash='─' + fi + add_widget 0 flowing -c "%BPrompt Connection%b" + add_widget 0 print + add_widget 1 + add_widget 0 print -P "%B(1) Disconnected.%b" + add_prompt gap_char=" " + add_widget 0 print -P "%B(2) Dotted.%b" + add_prompt gap_char=$dot + add_widget 0 print -P "%B(3) Solid.%b" + add_prompt gap_char=$dash + add_widget 0 print -P "(r) Restart from the beginning." + ask 123r + case $choice in + r) return 1;; + 1) gap_char=" "; options+=disconnected;; + 2) gap_char=$dot; options+=dotted;; + 3) gap_char=$dash; options+=solid;; + esac + return 0 +} + +function ask_frame() { + if [[ $style != (classic|rainbow|lean*) || $num_lines != 2 || $POWERLEVEL9K_MODE == ascii ]]; then + return 0 + fi + add_widget 0 flowing -c "%BPrompt Frame%b" + add_widget 0 print + add_widget 1 + add_widget 0 print -P "%B(1) No frame.%b" + add_prompt left_frame=0 right_frame=0 + add_widget 0 print -P "%B(2) Left.%b" + add_prompt left_frame=1 right_frame=0 + add_widget 0 print -P "%B(3) Right.%b" + add_prompt left_frame=0 right_frame=1 + add_widget 0 print -P "%B(4) Full.%b" + add_prompt left_frame=1 right_frame=1 + add_widget 0 print -P "(r) Restart from the beginning." + ask 1234r + case $choice in + r) return 1;; + 1) left_frame=0; right_frame=0; options+='no frame';; + 2) left_frame=1; right_frame=0; options+='left frame';; + 3) left_frame=0; right_frame=1; options+='right frame';; + 4) left_frame=1; right_frame=1; options+='full frame';; + esac + return 0 +} + +function ask_empty_line() { + add_widget 0 flowing -c "%BPrompt Spacing%b" + add_widget 0 print + add_widget 1 + add_widget 0 print -P "%B(1) Compact.%b" + add_widget 0 print + add_widget 1 + add_widget 0 print_prompt + add_widget 0 print_prompt + add_widget 0 print + add_widget 2 + add_widget 0 print -P "%B(2) Sparse.%b" + add_widget 0 print + add_widget 1 + add_widget 0 print_prompt + add_widget 0 print + add_widget 0 print_prompt + add_widget 0 print + add_widget 2 + add_widget 0 print -P "(r) Restart from the beginning." + ask 12r + case $choice in + r) return 1;; + 1) empty_line=0; options+='compact';; + 2) empty_line=1; options+='sparse';; + esac + return 0 +} + +function print_instant_prompt_link() { + local link='https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt' + (( wizard_columns < $#link )) && return + print + flowing -c "$(href $link)" +} + +function ask_instant_prompt() { + if ! is-at-least 5.4; then + instant_prompt=off + return 0 + fi + add_widget 0 flowing -c "%BInstant Prompt Mode%b" + add_widget 0 print_instant_prompt_link + add_widget 1 + add_widget 0 print + add_widget 2 + add_widget 0 flowing +c -i 5 "%B(1) Off.%b" Disable instant prompt. Choose this if you\'ve \ + tried instant prompt and found it incompatible with your zsh configuration files. + add_widget 0 print + add_widget 1 + add_widget 0 flowing +c -i 5 "%B(2) Quiet.%b" Enable instant prompt and %Bdon\'t print \ + warnings%b when detecting console output during zsh initialization. Choose this if you\'ve \ + read and understood instant prompt documentation. + add_widget 0 print + add_widget 1 + add_widget 0 flowing +c -i 5 "%B(3) Verbose.%b" Enable instant prompt and %Bprint a warning%b \ + when detecting console output during zsh initialization. %BChoose this if you\'ve never tried \ + instant prompt, haven\'t seen the warning, or if you are unsure what this all means%b. + add_widget 0 print + add_widget 2 + add_widget 0 print -P "(r) Restart from the beginning." + ask 123r + case $choice in + r) return 1;; + 1) instant_prompt=off; options+=instant_prompt=off;; + 2) instant_prompt=quiet; options+=instant_prompt=quiet;; + 3) instant_prompt=verbose; options+=instant_prompt=verbose;; + esac + return 0 +} + +function ask_transient_prompt() { + local disable_rprompt=$((num_lines == 1)) + local p=76 + [[ $style == pure ]] && p=$pure_color[magenta] + [[ $style == lean_8colors ]] && p=2 + p="%F{$p}$prompt_char%f" + add_widget 0 flowing -c "%BEnable Transient Prompt?%b" + add_widget 0 print + add_widget 1 + add_widget 0 print -P "%B(y) Yes.%b" + add_widget 0 print + add_widget 1 + add_widget 0 print -P "${(pl:$prompt_indent:: :)}$p %2Fgit%f pull" + add_widget 3 + add_widget 0 print -P "${(pl:$prompt_indent:: :)}$p %2Fgit%f branch x" + (( empty_line )) && add_widget 0 print + add_prompt_n buffer="%2Fgit%f checkout x$cursor" + add_widget 0 print + add_widget 2 + add_widget 0 print -P "%B(n) No.%b" + add_widget 0 print + add_widget 1 + add_widget 0 buffer="%2Fgit%f pull" print_prompt + add_widget 3 + (( empty_line )) && { add_widget 0 print; add_widget 3 } + add_prompt_n buffer="%2Fgit%f branch x" + (( empty_line )) && add_widget 0 print + add_prompt_n buffer="%2Fgit%f checkout x$cursor" + add_widget 0 print + add_widget 2 + add_widget 0 print -P "(r) Restart from the beginning." + ask ynr + case $choice in + r) return 1;; + y) transient_prompt=1; options+=transient_prompt;; + n) transient_prompt=0;; + esac + return 0 +} + +function ask_config_overwrite() { + config_backup= + config_backup_u=0 + if [[ ! -e $__p9k_cfg_path ]]; then + return 0 + fi + add_widget 0 flowing -c Powerlevel10k config file already exists. + add_widget 0 flowing -c "%BOverwrite" "%b%2F${__p9k_cfg_path_u//\\/\\\\}%f%B?%b" + add_widget 0 print -P "" + add_widget 0 print -P "%B(y) Yes.%b" + add_widget 0 print -P "" + add_widget 0 print -P "(r) Restart from the beginning." + ask yr + case $choice in + r) return 1;; + y) + config_backup="$(mktemp ${TMPDIR:-/tmp}/$__p9k_cfg_basename.XXXXXXXXXX)" || quit -c + cp $__p9k_cfg_path $config_backup || quit -c + config_backup_u=${${TMPDIR:+\$TMPDIR}:-/tmp}/${(q-)config_backup:t} + ;; + esac + return 0 +} + +function ask_zshrc_edit() { + zshrc_content= + zshrc_backup= + zshrc_backup_u= + zshrc_has_cfg=0 + zshrc_has_instant_prompt=0 + write_zshrc=0 + + if (( $+functions[z4h] )); then + zshrc_has_cfg=1 + zshrc_has_instant_prompt=1 + fi + + [[ $instant_prompt == off ]] && zshrc_has_instant_prompt=1 + + if [[ -e $__p9k_zshrc ]]; then + zshrc_content="$(<$__p9k_zshrc)" || quit -c + local lines=(${(f)zshrc_content}) + local f0=$__p9k_cfg_path_o + local f1=${(q)f0} + local f2=${(q-)f0} + local f3=${(qq)f0} + local f4=${(qqq)f0} + local g1=${${(q)__p9k_cfg_path_o}/#(#b)${(q)HOME}\//'~/'} + local h0='${ZDOTDIR:-~}/.p10k.zsh' + local h1='${ZDOTDIR:-$HOME}/.p10k.zsh' + local h2='"${ZDOTDIR:-$HOME}/.p10k.zsh"' + local h3='"${ZDOTDIR:-$HOME}"/.p10k.zsh' + local h4='${ZDOTDIR}/.p10k.zsh' + local h5='"${ZDOTDIR}/.p10k.zsh"' + local h6='"${ZDOTDIR}"/.p10k.zsh' + local h7='$ZDOTDIR/.p10k.zsh' + local h8='"$ZDOTDIR/.p10k.zsh"' + local h9='"$ZDOTDIR"/.p10k.zsh' + if [[ -n ${(@M)lines:#(#b)[^#]#([^[:IDENT:]]|)source[[:space:]]##($f1|$f2|$f3|$f4|$g1|$h0|$h1|$h2|$h3|$h4|$h5|$h6|$h7|$h8|$h9)(|[[:space:]]*|'#'*)} ]]; then + zshrc_has_cfg=1 + fi + local pre='${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh' + if [[ -n ${(@M)lines:#(#b)[^#]#([^[:IDENT:]]|)source[[:space:]]##($pre|\"$pre\")(|[[:space:]]*|'#'*)} ]]; then + zshrc_has_instant_prompt=1 + fi + (( zshrc_has_cfg && zshrc_has_instant_prompt )) && return + fi + + add_widget 0 flowing -c %BApply changes to "%b%2F${__p9k_zshrc_u//\\/\\\\}%f%B?%b" + add_widget 0 print -P "" + add_widget 1 + local modifiable=y + if [[ -e $__p9k_zshrc && ! -w $__p9k_zshrc ]]; then + local -a stat + zstat -A stat +uid -- $__p9k_zshrc || quit -c + if (( stat[1] == EUID )); then + add_widget 0 flowing -c %3FNOTE:%f %2F${__p9k_zshrc_u//\\/\\\\}%f %3Fis readonly.%f + else + modifiable= + add_widget 0 flowing -c \ + %3FWARNING:%f %2F${__p9k_zshrc_u//\\/\\\\}%f %3Fis readonly and \ + not owned by the user. Cannot modify it.%f + fi + add_widget 0 print -P "" + fi + if [[ $modifiable == y ]]; then + add_widget 0 print -P "%B(y) Yes (recommended).%b" + else + add_widget 0 print -P "%1F(y) Yes (disabled).%f" + fi + add_widget 0 print -P "" + add_widget 0 flowing +c -i 5 "%B(n) No." I know which changes to apply and will do it myself.%b + add_widget 0 print -P "" + add_widget 0 print -P "(r) Restart from the beginning." + ask ${modifiable}nr + case $choice in + r) return 1;; + n) return 0;; + y) + write_zshrc=1 + if [[ -n $zshrc_content ]]; then + zshrc_backup="$(mktemp ${TMPDIR:-/tmp}/.zshrc.XXXXXXXXXX)" || quit -c + cp -p $__p9k_zshrc $zshrc_backup || quit -c + local -i writable=1 + if [[ ! -w $zshrc_backup ]]; then + chmod u+w -- $zshrc_backup || quit -c + writable=0 + fi + print -r -- $zshrc_content >$zshrc_backup || quit -c + (( writable )) || chmod u-w -- $zshrc_backup || quit -c + zshrc_backup_u=${${TMPDIR:+\$TMPDIR}:-/tmp}/${(q-)zshrc_backup:t} + fi + ;; + esac + return 0 +} + +function generate_config() { + local base && base="$(<$__p9k_root_dir/config/p10k-${style//_/-}.zsh)" || return + local lines=("${(@f)base}") + + function sub() { + lines=("${(@)lines/#(#b)([[:space:]]#)typeset -g POWERLEVEL9K_$1=*/$match[1]typeset -g POWERLEVEL9K_$1=$2}") + } + + function uncomment() { + lines=("${(@)lines/#(#b)([[:space:]]#)\# $1( |)/$match[1]$1$match[2]$match[2]}") + } + + function rep() { + lines=("${(@)lines//$1/$2}") + } + + if [[ $style == pure ]]; then + rep "local grey=242" "local grey='$pure_color[grey]'" + rep "local red=1" "local red='$pure_color[red]'" + rep "local yellow=3" "local yellow='$pure_color[yellow]'" + rep "local blue=4" "local blue='$pure_color[blue]'" + rep "local magenta=5" "local magenta='$pure_color[magenta]'" + rep "local cyan=6" "local cyan='$pure_color[cyan]'" + rep "local white=7" "local white='$pure_color[white]'" + else + sub MODE $POWERLEVEL9K_MODE + + sub ICON_PADDING $POWERLEVEL9K_ICON_PADDING + + if [[ $POWERLEVEL9K_MODE == compatible ]]; then + sub STATUS_ERROR_VISUAL_IDENTIFIER_EXPANSION "'х'" + sub STATUS_ERROR_SIGNAL_VISUAL_IDENTIFIER_EXPANSION "'х'" + sub STATUS_ERROR_PIPE_VISUAL_IDENTIFIER_EXPANSION "'х'" + fi + + if [[ $POWERLEVEL9K_MODE == (compatible|powerline) ]]; then + uncomment 'typeset -g POWERLEVEL9K_LOCK_ICON' + sub LOCK_ICON "'∅'" + uncomment 'typeset -g POWERLEVEL9K_NORDVPN_VISUAL_IDENTIFIER_EXPANSION' + sub NORDVPN_VISUAL_IDENTIFIER_EXPANSION "'nord'" + uncomment 'typeset -g POWERLEVEL9K_RANGER_VISUAL_IDENTIFIER_EXPANSION' + sub RANGER_VISUAL_IDENTIFIER_EXPANSION "'▲'" + uncomment 'typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_VISUAL_IDENTIFIER_EXPANSION' + sub KUBECONTEXT_DEFAULT_VISUAL_IDENTIFIER_EXPANSION "'○'" + uncomment 'typeset -g POWERLEVEL9K_AZURE_VISUAL_IDENTIFIER_EXPANSION' + sub AZURE_VISUAL_IDENTIFIER_EXPANSION "'az'" + uncomment 'typeset -g POWERLEVEL9K_AWS_EB_ENV_VISUAL_IDENTIFIER_EXPANSION' + sub AWS_EB_ENV_VISUAL_IDENTIFIER_EXPANSION "'eb'" + uncomment 'typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VISUAL_IDENTIFIER_EXPANSION' + sub BACKGROUND_JOBS_VISUAL_IDENTIFIER_EXPANSION "'≡'" + fi + + if [[ $POWERLEVEL9K_MODE == (awesome-patched|awesome-fontconfig) && $cap_python == 0 ]]; then + uncomment 'typeset -g POWERLEVEL9K_VIRTUALENV_VISUAL_IDENTIFIER_EXPANSION' + uncomment 'typeset -g POWERLEVEL9K_ANACONDA_VISUAL_IDENTIFIER_EXPANSION' + uncomment 'typeset -g POWERLEVEL9K_PYENV_VISUAL_IDENTIFIER_EXPANSION' + uncomment 'typeset -g POWERLEVEL9K_PYTHON_ICON' + sub VIRTUALENV_VISUAL_IDENTIFIER_EXPANSION "'🐍'" + sub ANACONDA_VISUAL_IDENTIFIER_EXPANSION "'🐍'" + sub PYENV_VISUAL_IDENTIFIER_EXPANSION "'🐍'" + sub PYTHON_ICON "'🐍'" + fi + + if [[ $POWERLEVEL9K_MODE == nerdfont-complete ]]; then + sub BATTERY_STAGES "'\uf58d\uf579\uf57a\uf57b\uf57c\uf57d\uf57e\uf57f\uf580\uf581\uf578'" + fi + + if [[ $style == (classic|rainbow) ]]; then + if [[ $style == classic ]]; then + sub BACKGROUND $bg_color[$color] + sub LEFT_SUBSEGMENT_SEPARATOR "'%$sep_color[$color]F$left_subsep'" + sub RIGHT_SUBSEGMENT_SEPARATOR "'%$sep_color[$color]F$right_subsep'" + sub VCS_LOADING_FOREGROUND $sep_color[$color] + rep '%248F' "%$prefix_color[$color]F" + else + sub LEFT_SUBSEGMENT_SEPARATOR "'$left_subsep'" + sub RIGHT_SUBSEGMENT_SEPARATOR "'$right_subsep'" + fi + sub RULER_FOREGROUND $frame_color[$color] + sub MULTILINE_FIRST_PROMPT_GAP_FOREGROUND $frame_color[$color] + sub MULTILINE_FIRST_PROMPT_PREFIX "'%$frame_color[$color]F╭─'" + sub MULTILINE_NEWLINE_PROMPT_PREFIX "'%$frame_color[$color]F├─'" + sub MULTILINE_LAST_PROMPT_PREFIX "'%$frame_color[$color]F╰─'" + sub MULTILINE_FIRST_PROMPT_SUFFIX "'%$frame_color[$color]F─╮'" + sub MULTILINE_NEWLINE_PROMPT_SUFFIX "'%$frame_color[$color]F─┤'" + sub MULTILINE_LAST_PROMPT_SUFFIX "'%$frame_color[$color]F─╯'" + sub LEFT_SEGMENT_SEPARATOR "'$left_sep'" + sub RIGHT_SEGMENT_SEPARATOR "'$right_sep'" + sub LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL "'$left_tail'" + sub LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL "'$left_head'" + sub RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL "'$right_head'" + sub RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL "'$right_tail'" + fi + + if [[ -n ${(j::)extra_icons} ]]; then + local branch_icon=${icons[VCS_BRANCH_ICON]// } + sub VCS_BRANCH_ICON "'$branch_icon '" + uncomment os_icon + else + uncomment 'typeset -g POWERLEVEL9K_DIR_CLASSES' + uncomment 'typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_EXPANSION' + uncomment 'typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_VISUAL_IDENTIFIER_EXPANSION' + uncomment 'typeset -g POWERLEVEL9K_TIME_VISUAL_IDENTIFIER_EXPANSION' + sub VCS_VISUAL_IDENTIFIER_EXPANSION '' + sub COMMAND_EXECUTION_TIME_VISUAL_IDENTIFIER_EXPANSION '' + sub TIME_VISUAL_IDENTIFIER_EXPANSION '' + fi + + if [[ -n ${(j::)prefixes} ]]; then + uncomment 'typeset -g POWERLEVEL9K_VCS_PREFIX' + uncomment 'typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PREFIX' + uncomment 'typeset -g POWERLEVEL9K_CONTEXT_PREFIX' + uncomment 'typeset -g POWERLEVEL9K_KUBECONTEXT_PREFIX' + uncomment 'typeset -g POWERLEVEL9K_TIME_PREFIX' + if [[ $style == (lean|classic) ]]; then + [[ $style == classic ]] && local fg="%$prefix_color[$color]F" || local fg="%f" + sub VCS_PREFIX "'${fg}on '" + sub COMMAND_EXECUTION_TIME_PREFIX "'${fg}took '" + sub CONTEXT_PREFIX "'${fg}with '" + sub KUBECONTEXT_PREFIX "'${fg}at '" + sub TIME_PREFIX "'${fg}at '" + fi + fi + + sub MULTILINE_FIRST_PROMPT_GAP_CHAR "'$gap_char'" + + if [[ $style == (classic|rainbow) && $num_lines == 2 ]]; then + if (( ! right_frame )); then + sub MULTILINE_FIRST_PROMPT_SUFFIX '' + sub MULTILINE_NEWLINE_PROMPT_SUFFIX '' + sub MULTILINE_LAST_PROMPT_SUFFIX '' + fi + if (( ! left_frame )); then + sub MULTILINE_FIRST_PROMPT_PREFIX '' + sub MULTILINE_NEWLINE_PROMPT_PREFIX '' + sub MULTILINE_LAST_PROMPT_PREFIX '' + sub STATUS_OK false + sub STATUS_ERROR false + fi + fi + + if [[ $style == lean* ]]; then + sub RULER_FOREGROUND $frame_color[$color] + sub MULTILINE_FIRST_PROMPT_GAP_FOREGROUND $frame_color[$color] + if (( right_frame )); then + sub MULTILINE_FIRST_PROMPT_SUFFIX "'%$frame_color[$color]F─╮'" + sub MULTILINE_NEWLINE_PROMPT_SUFFIX "'%$frame_color[$color]F─┤'" + sub MULTILINE_LAST_PROMPT_SUFFIX "'%$frame_color[$color]F─╯'" + sub RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL "' '" + fi + if (( left_frame )); then + sub MULTILINE_FIRST_PROMPT_PREFIX "'%$frame_color[$color]F╭─'" + sub MULTILINE_NEWLINE_PROMPT_PREFIX "'%$frame_color[$color]F├─'" + sub MULTILINE_LAST_PROMPT_PREFIX "'%$frame_color[$color]F╰─'" + sub LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL "' '" + fi + fi + + if [[ $style == (classic|rainbow) ]]; then + if (( num_lines == 2 && ! left_frame )); then + uncomment prompt_char + else + uncomment vi_mode + fi + fi + + if [[ $POWERLEVEL9K_MODE == ascii ]]; then + sub 'STATUS_OK_VISUAL_IDENTIFIER_EXPANSION' "'ok'" + sub 'STATUS_OK_PIPE_VISUAL_IDENTIFIER_EXPANSION' "'ok'" + sub 'STATUS_ERROR_VISUAL_IDENTIFIER_EXPANSION' "'err'" + sub 'STATUS_ERROR_SIGNAL_VISUAL_IDENTIFIER_EXPANSION' "" + sub 'STATUS_ERROR_PIPE_VISUAL_IDENTIFIER_EXPANSION' "'err'" + sub 'BATTERY_STAGES' "('battery')" + sub 'PROMPT_CHAR_{OK,ERROR}_VIINS_CONTENT_EXPANSION' "'>'" + sub 'PROMPT_CHAR_{OK,ERROR}_VICMD_CONTENT_EXPANSION' "'<'" + sub 'PROMPT_CHAR_{OK,ERROR}_VIVIS_CONTENT_EXPANSION' "'V'" + sub 'PROMPT_CHAR_{OK,ERROR}_VIOWR_CONTENT_EXPANSION' "'^'" + rep "-i '⭐'" "-i '*'" + rep '…' '..' + rep '⇣' '<' + rep '⇡' '>' + rep '⇠' '<-' + rep '⇢' '->' + rep '─' '-' + fi + fi + + if (( $+pure_use_rprompt )); then + local segment + for segment in command_execution_time virtualenv context; do + rep " $segment" " tmp_$segment" + uncomment $segment + rep " tmp_$segment " " # $segment" + done + fi + + if [[ -n $time ]]; then + uncomment time + if [[ $time == $time_12h ]]; then + sub TIME_FORMAT "'%D{%I:%M:%S %p}'" + fi + fi + + if (( num_lines == 1 )); then + local -a tmp + local line + for line in "$lines[@]"; do + [[ $line == (' newline'*|*'===[ Line #'*) ]] || tmp+=$line + done + lines=("$tmp[@]") + fi + + (( empty_line )) && sub PROMPT_ADD_NEWLINE true || sub PROMPT_ADD_NEWLINE false + + sub INSTANT_PROMPT $instant_prompt + (( transient_prompt )) && sub TRANSIENT_PROMPT always + + local header=${(%):-"# Generated by Powerlevel10k configuration wizard on %D{%Y-%m-%d at %H:%M %Z}."}$'\n' + header+="# Based on romkatv/powerlevel10k/config/p10k-${style//_/-}.zsh" + if [[ $commands[sum] == ('/bin'|'/usr/bin'|'/usr/local/bin')'/sum' ]]; then + local -a sum + if sum=($(sum <<<${base//$'\r\n'/$'\n'} 2>/dev/null)) && (( $#sum == 2 )); then + header+=", checksum $sum[1]" + fi + fi + header+=$'.\n' + local line="# Wizard options: $options[1]" + local opt + for opt in $options[2,-1]; do + if (( $#line + $#opt > 85 )); then + header+=$line + header+=$',\n' + line="# $opt" + else + line+=", $opt" + fi + done + header+=$line + header+=$'.\n# Type `p10k configure` to generate another config.\n#' + + if [[ -e $__p9k_cfg_path ]]; then + unlink $__p9k_cfg_path || return + fi + print -lr -- "$header" "$lines[@]" >$__p9k_cfg_path +} + +function change_zshrc() { + (( write_zshrc )) || return 0 + + local tmp=$__p9k_zshrc.${(%):-%n}.tmp.$$ + [[ ! -e $__p9k_zshrc ]] || cp -p $__p9k_zshrc $tmp || return + + { + local -i writable=1 + if [[ -e $tmp && ! -w $tmp ]]; then + chmod u+w -- $tmp || return + writable=0 + fi + + print -n >$tmp || return + + if (( !zshrc_has_instant_prompt )); then + >>$tmp print -r -- "# Enable Powerlevel10k instant prompt. Should stay close to the top of ${(%)__p9k_zshrc_u}. +# Initialization code that may require console input (password prompts, [y/n] +# confirmations, etc.) must go above this block; everything else may go below. +if [[ -r \"\${XDG_CACHE_HOME:-\$HOME/.cache}/p10k-instant-prompt-\${(%):-%n}.zsh\" ]]; then + source \"\${XDG_CACHE_HOME:-\$HOME/.cache}/p10k-instant-prompt-\${(%):-%n}.zsh\" +fi" || return + fi + if [[ -n $zshrc_content ]]; then + (( zshrc_has_instant_prompt )) || print >>$tmp || return + >>$tmp print -r -- $zshrc_content || return + fi + if (( !zshrc_has_cfg )); then + >>$tmp print -r -- " +# To customize prompt, run \`p10k configure\` or edit ${(%)__p9k_cfg_path_u}. +[[ ! -f ${(%)__p9k_cfg_path_u} ]] || source ${(%)__p9k_cfg_path_u}" || return + fi + (( writable )) || chmod u-w -- $tmp || return + zf_mv -f -- $tmp $__p9k_zshrc || return + } always { + zf_rm -f -- $tmp + } + + if [[ -n $zshrc_backup_u ]]; then + print -rP "" + flowing +c See "%B${__p9k_zshrc_u//\\/\\\\}%b" changes: + print -rP " + %2Fdiff%f %B$zshrc_backup_u%b %B$__p9k_zshrc_u%b" + fi + return 0 +} + +if (( force )); then + _p9k_can_configure || return +else + _p9k_can_configure -q || return +fi + +zmodload zsh/terminfo || return +autoload -Uz is-at-least || return + +if is-at-least 5.7.1 && [[ $COLORTERM == (24bit|truecolor) ]]; then + local -ir has_truecolor=1 +else + local -ir has_truecolor=0 +fi + +stty -echo 2>/dev/null + +while true; do + local instant_prompt=verbose zshrc_content= zshrc_backup= zshrc_backup_u= + local -i zshrc_has_cfg=0 zshrc_has_instant_prompt=0 write_zshrc=0 + local POWERLEVEL9K_MODE= POWERLEVEL9K_ICON_PADDING=moderate style= config_backup= config_backup_u= + local gap_char=' ' prompt_char='❯' down_triangle='\uE0BC' up_triangle='\uE0BA' slanted_bar='\u2571' + local left_subsep= right_subsep= left_tail= right_tail= left_head= right_head= time= + local -i num_lines=2 empty_line=0 color=2 left_frame=1 right_frame=1 transient_prompt=0 + local -i cap_diamond=0 cap_python=0 cap_debian=0 cap_lock=0 cap_arrow=0 + local -a extra_icons=('' '' '') + local -a frame_color=(244 242 240 238) + local -a color_name=(Lightest Light Dark Darkest) + local -a prefixes=('' '') + local -a options=() + if (( has_truecolor )); then + local -A pure_color=(${(kv)pure_snazzy}) + else + local -A pure_color=(${(kv)pure_original}) + fi + + unset pure_use_rprompt + + if [[ $langinfo[CODESET] == (utf|UTF)(-|)8 ]]; then + ask_font || continue + ask_diamond || continue + if [[ $AWESOME_GLYPHS_LOADED == 1 ]]; then + POWERLEVEL9K_MODE=awesome-mapped-fontconfig + else + ask_lock '\uF023' || continue + if (( ! cap_lock )); then + ask_lock '\uE138' "Let's try another one." || continue + if (( cap_lock )); then + if (( cap_diamond )); then + POWERLEVEL9K_MODE=awesome-patched + ask_python || continue + else + POWERLEVEL9K_MODE=flat + fi + else + if (( cap_diamond )); then + POWERLEVEL9K_MODE=powerline + else + ask_arrow || continue + (( cap_arrow )) && POWERLEVEL9K_MODE=compatible || POWERLEVEL9K_MODE=ascii + fi + fi + elif (( ! cap_diamond )); then + POWERLEVEL9K_MODE=awesome-fontconfig + else + ask_debian || continue + if (( cap_debian )); then + POWERLEVEL9K_MODE=nerdfont-complete + else + POWERLEVEL9K_MODE=awesome-fontconfig + ask_python || continue + fi + fi + fi + else + POWERLEVEL9K_MODE=ascii + fi + + if [[ $POWERLEVEL9K_MODE == powerline ]]; then + options+=powerline + elif (( cap_diamond )); then + options+="$POWERLEVEL9K_MODE + powerline" + else + options+="$POWERLEVEL9K_MODE" + fi + (( cap_python )) && options[-1]+=' + python' + if (( cap_diamond )); then + left_sep=$right_triangle + right_sep=$left_triangle + left_subsep=$right_angle + right_subsep=$left_angle + left_head=$right_triangle + right_head=$left_triangle + else + left_sep= + right_sep= + left_head= + right_head= + if [[ $POWERLEVEL9K_MODE == ascii ]]; then + left_subsep='|' + right_subsep='|' + prompt_char='>' + left_frame=0 + right_frame=0 + else + left_subsep=$vertical_bar + right_subsep=$vertical_bar + fi + fi + + _p9k_init_icons + ask_icon_padding || continue + _p9k_init_icons + + ask_style || continue + ask_charset || continue + ask_color_scheme || continue + ask_color || continue + ask_use_rprompt || continue + ask_time || continue + ask_separators || continue + ask_heads || continue + ask_tails || continue + ask_num_lines || continue + ask_gap_char || continue + ask_frame || continue + ask_ornaments_color || continue + ask_empty_line || continue + ask_extra_icons || continue + ask_prefixes || continue + ask_transient_prompt || continue + ask_instant_prompt || continue + ask_config_overwrite || continue + ask_zshrc_edit || continue + break +done + +restore_screen +print + +flowing +c New config: "%B${__p9k_cfg_path_u//\\/\\\\}%b." +if [[ -n $config_backup ]]; then + flowing +c Backup of the old config: "%B${config_backup_u//\\/\\\\}%b." +fi +if [[ -n $zshrc_backup ]]; then + flowing +c Backup of "%B${__p9k_zshrc_u//\\/\\\\}%b:" "%B${zshrc_backup_u//\\/\\\\}%b." +fi + +generate_config || return +change_zshrc || return + +print -rP "" +flowing +c File feature requests and bug reports at "$(href https://github.com/romkatv/powerlevel10k/issues)" +print -rP "" + +success=1 + +} always { + (( success )) || quit + consume_input + stty echo 2>/dev/null + show_cursor + restore_screen +} diff --git a/internal/worker.zsh b/internal/worker.zsh new file mode 100644 index 00000000..9e78bc15 --- /dev/null +++ b/internal/worker.zsh @@ -0,0 +1,210 @@ +# invoked in worker: _p9k_worker_main <pgid> +function _p9k_worker_main() { + mkfifo -- $_p9k__worker_file_prefix.fifo || return + echo -nE - s$_p9k_worker_pgid$'\x1e' || return + exec <$_p9k__worker_file_prefix.fifo || return + zf_rm -- $_p9k__worker_file_prefix.fifo || return + + local -i reset + local req fd + local -a ready + local _p9k_worker_request_id + local -A _p9k_worker_fds # fd => id$'\x1f'callback + local -A _p9k_worker_inflight # id => inflight count + + function _p9k_worker_reply() { + print -nr -- e${(pj:\n:)@}$'\x1e' || kill -- -$_p9k_worker_pgid + } + + # usage: _p9k_worker_async <work> <callback> + function _p9k_worker_async() { + local fd async=$1 + sysopen -r -o cloexec -u fd <(() { eval $async; } && print -n '\x1e') || return + (( ++_p9k_worker_inflight[$_p9k_worker_request_id] )) + _p9k_worker_fds[$fd]=$_p9k_worker_request_id$'\x1f'$2 + } + + trap '' PIPE + + { + while zselect -a ready 0 ${(k)_p9k_worker_fds}; do + [[ $ready[1] == -r ]] || return + for fd in ${ready:1}; do + if [[ $fd == 0 ]]; then + local buf= + [[ -t 0 ]] # https://www.zsh.org/mla/workers/2020/msg00207.html + if sysread -t 0 'buf[$#buf+1]'; then + while [[ $buf != *$'\x1e' ]]; do + sysread 'buf[$#buf+1]' || return + done + else + (( $? == 4 )) || return + fi + for req in ${(ps:\x1e:)buf}; do + _p9k_worker_request_id=${req%%$'\x1f'*} + () { eval $req[$#_p9k_worker_request_id+2,-1] } + (( $+_p9k_worker_inflight[$_p9k_worker_request_id] )) && continue + print -rn -- d$_p9k_worker_request_id$'\x1e' || return + done + else + local REPLY= + while true; do + if sysread -i $fd 'REPLY[$#REPLY+1]'; then + [[ $REPLY == *$'\x1e' ]] || continue + else + (( $? == 5 )) || return + break + fi + done + local cb=$_p9k_worker_fds[$fd] + _p9k_worker_request_id=${cb%%$'\x1f'*} + unset "_p9k_worker_fds[$fd]" + exec {fd}>&- + if [[ $REPLY == *$'\x1e' ]]; then + REPLY[-1]="" + () { eval $cb[$#_p9k_worker_request_id+2,-1] } + fi + if (( --_p9k_worker_inflight[$_p9k_worker_request_id] == 0 )); then + unset "_p9k_worker_inflight[$_p9k_worker_request_id]" + print -rn -- d$_p9k_worker_request_id$'\x1e' || return + fi + fi + done + done + } always { + kill -- -$_p9k_worker_pgid + } +} + +# invoked in master: _p9k_worker_invoke <request-id> <list> +function _p9k_worker_invoke() { + [[ -n $_p9k__worker_resp_fd ]] || return + local req=$1$'\x1f'$2$'\x1e' + if [[ -n $_p9k__worker_req_fd && $+_p9k__worker_request_map[$1] == 0 ]]; then + _p9k__worker_request_map[$1]= + print -rnu $_p9k__worker_req_fd -- $req + else + _p9k__worker_request_map[$1]=$req + fi +} + +function _p9k_worker_cleanup() { + eval "$__p9k_intro" + [[ $_p9k__worker_shell_pid == $sysparams[pid] ]] && _p9k_worker_stop + return 0 +} + +function _p9k_worker_stop() { + add-zsh-hook -D zshexit _p9k_worker_cleanup + [[ -n $_p9k__worker_resp_fd ]] && zle -F $_p9k__worker_resp_fd + [[ -n $_p9k__worker_resp_fd ]] && exec {_p9k__worker_resp_fd}>&- + [[ -n $_p9k__worker_req_fd ]] && exec {_p9k__worker_req_fd}>&- + [[ -n $_p9k__worker_pid ]] && kill -- -$_p9k__worker_pid 2>/dev/null + [[ -n $_p9k__worker_file_prefix ]] && zf_rm -f -- $_p9k__worker_file_prefix.fifo + _p9k__worker_pid= + _p9k__worker_req_fd= + _p9k__worker_resp_fd= + _p9k__worker_shell_pid= + _p9k__worker_request_map=() + return 0 +} + +function _p9k_worker_receive() { + eval "$__p9k_intro" + + [[ -z $_p9k__worker_resp_fd ]] && return + + { + (( $# <= 1 )) || return + + local buf resp + + [[ -t $_p9k__worker_resp_fd ]] # https://www.zsh.org/mla/workers/2020/msg00207.html + if sysread -i $_p9k__worker_resp_fd -t 0 'buf[$#buf+1]'; then + while [[ $buf == *[^$'\x05\x1e']$'\x05'# ]]; do + sysread -i $_p9k__worker_resp_fd 'buf[$#buf+1]' || return + done + else + (( $? == 4 )) || return + fi + + local -i reset max_reset + for resp in ${(ps:\x1e:)${buf//$'\x05'}}; do + local arg=$resp[2,-1] + case $resp[1] in + d) + local req=$_p9k__worker_request_map[$arg] + if [[ -n $req ]]; then + _p9k__worker_request_map[$arg]= + print -rnu $_p9k__worker_req_fd -- $req || return + else + unset "_p9k__worker_request_map[$arg]" + fi + ;; + e) + () { eval $arg } + (( reset > max_reset )) && max_reset=reset + ;; + s) + [[ -z $_p9k__worker_req_fd ]] || return + [[ $arg == <1-> ]] || return + _p9k__worker_pid=$arg + sysopen -w -o cloexec -u _p9k__worker_req_fd $_p9k__worker_file_prefix.fifo || return + local req= + for req in $_p9k__worker_request_map; do + print -rnu $_p9k__worker_req_fd -- $req || return + done + _p9k__worker_request_map=({${(k)^_p9k__worker_request_map},''}) + ;; + *) + return 1 + ;; + esac + done + + if (( max_reset == 2 )); then + _p9k__refresh_reason=worker + _p9k_set_prompt + _p9k__refresh_reason='' + fi + (( max_reset )) && _p9k_reset_prompt + return 0 + } always { + (( $? )) && _p9k_worker_stop + } +} + +function _p9k_worker_start() { + setopt monitor || return + { + [[ -n $_p9k__worker_resp_fd ]] && return + _p9k__worker_file_prefix=${TMPDIR:-/tmp}/p10k.worker.$EUID.$sysparams[pid].$EPOCHSECONDS + + sysopen -r -o cloexec -u _p9k__worker_resp_fd <( + exec 0</dev/null + if [[ -n $_POWERLEVEL9K_WORKER_LOG_LEVEL ]]; then + exec 2>$_p9k__worker_file_prefix.log + setopt xtrace + else + exec 2>/dev/null + fi + builtin cd -q / || return + zmodload zsh/zselect || return + ! { zselect -t0 || (( $? != 1 )) } || return + local _p9k_worker_pgid=$sysparams[pid] + _p9k_worker_main & + { + trap '' PIPE + while syswrite $'\x05'; do zselect -t 1000; done + zf_rm -f $_p9k__worker_file_prefix.fifo + kill -- -$_p9k_worker_pgid + } & + exec =true) || return + _p9k__worker_pid=$sysparams[procsubstpid] + zle -F $_p9k__worker_resp_fd _p9k_worker_receive + _p9k__worker_shell_pid=$sysparams[pid] + add-zsh-hook zshexit _p9k_worker_cleanup + } always { + (( $? )) && _p9k_worker_stop + } +} diff --git a/powerlevel10k.png b/powerlevel10k.png Binary files differnew file mode 100644 index 00000000..e52e1f7c --- /dev/null +++ b/powerlevel10k.png diff --git a/powerlevel10k.zsh-theme b/powerlevel10k.zsh-theme new file mode 100644 index 00000000..cd49dd4c --- /dev/null +++ b/powerlevel10k.zsh-theme @@ -0,0 +1,83 @@ +# vim:ft=zsh ts=2 sw=2 sts=2 et fenc=utf-8 +################################################################ +# Powerlevel10k Theme +# https://github.com/romkatv/powerlevel10k +# +# Forked from Powerlevel9k Theme +# https://github.com/bhilburn/powerlevel9k +# +# Which in turn was forked from Agnoster Theme +# https://github.com/robbyrussell/oh-my-zsh/blob/74177c5320b2a1b2f8c4c695c05984b57fd7c6ea/themes/agnoster.zsh-theme +################################################################ + +# Temporarily change options. +'builtin' 'local' '-a' '__p9k_src_opts' +[[ ! -o 'aliases' ]] || __p9k_src_opts+=('aliases') +[[ ! -o 'sh_glob' ]] || __p9k_src_opts+=('sh_glob') +[[ ! -o 'no_brace_expand' ]] || __p9k_src_opts+=('no_brace_expand') +'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand' + +(( $+__p9k_root_dir )) || typeset -gr __p9k_root_dir=${POWERLEVEL9K_INSTALLATION_DIR:-${${(%):-%x}:A:h}} +(( $+__p9k_intro )) || { + # Leading spaces before `local` are important. Otherwise Antigen will remove `local` (!!!). + # __p9k_trapint is to work around bugs in zsh: https://www.zsh.org/mla/workers/2020/msg00612.html. + # Likewise for `trap ":"` instead of the plain `trap ""`. + typeset -gr __p9k_intro_base='emulate -L zsh -o no_hist_expand -o extended_glob -o no_prompt_bang -o prompt_percent -o no_prompt_subst -o no_aliases -o no_bg_nice -o typeset_silent + (( $+__p9k_trapped )) || { local -i __p9k_trapped; trap : INT; trap "trap ${(q)__p9k_trapint:--} INT" EXIT } + local -a match mbegin mend + local -i MBEGIN MEND OPTIND + local MATCH OPTARG IFS=$'\'' \t\n\0'\' + typeset -gr __p9k_intro_locale='[[ $langinfo[CODESET] != (utf|UTF)(-|)8 ]] && _p9k_init_locale && { [[ -n $LC_ALL ]] && local LC_ALL=$__p9k_locale || local LC_CTYPE=$__p9k_locale }' + typeset -gr __p9k_intro_no_locale="${${__p9k_intro_base/ match / match reply }/ MATCH / MATCH REPLY }" + typeset -gr __p9k_intro_no_reply="$__p9k_intro_base; $__p9k_intro_locale" + typeset -gr __p9k_intro="$__p9k_intro_no_locale; $__p9k_intro_locale" +} + +zmodload zsh/langinfo + +function _p9k_init_locale() { + if (( ! $+__p9k_locale )); then + typeset -g __p9k_locale= + (( $+commands[locale] )) || return + local -a loc + loc=(${(@M)$(locale -a 2>/dev/null):#*.(utf|UTF)(-|)8}) || return + (( $#loc )) || return + typeset -g __p9k_locale=${loc[(r)(#i)C.UTF(-|)8]:-${loc[(r)(#i)en_US.UTF(-|)8]:-$loc[1]}} + fi + [[ -n $__p9k_locale ]] +} + +() { + eval "$__p9k_intro" + if (( $+__p9k_sourced )); then + (( $+functions[_p9k_setup] )) && _p9k_setup + return 0 + fi + typeset -gr __p9k_dump_file=${XDG_CACHE_HOME:-~/.cache}/p10k-dump-${(%):-%n}.zsh + if [[ $__p9k_dump_file != $__p9k_instant_prompt_dump_file ]] && (( ! $+functions[_p9k_preinit] )) && source $__p9k_dump_file 2>/dev/null && (( $+functions[_p9k_preinit] )); then + _p9k_preinit + fi + typeset -gr __p9k_sourced=12 + if [[ $ZSH_VERSION == (5.<1->*|<6->.*) ]]; then + if [[ -w $__p9k_root_dir && -w $__p9k_root_dir/internal && -w $__p9k_root_dir/gitstatus ]]; then + local f + for f in $__p9k_root_dir/{powerlevel9k.zsh-theme,powerlevel10k.zsh-theme,internal/p10k.zsh,internal/icons.zsh,internal/configure.zsh,internal/worker.zsh,internal/parser.zsh,gitstatus/gitstatus.plugin.zsh,gitstatus/install}; do + [[ $f.zwc -nt $f ]] && continue + zmodload -F zsh/files b:zf_mv b:zf_rm + local tmp=$f.tmp.$$.zwc + { + # `zf_mv -f src dst` fails on NTFS if `dst` is not writable, hence `zf_rm`. + zf_rm -f -- $f.zwc && zcompile -R -- $tmp $f && zf_mv -f -- $tmp $f.zwc + } always { + (( $? )) && zf_rm -f -- $tmp + } + done + fi + fi + source $__p9k_root_dir/internal/p10k.zsh || true +} + +(( $+__p9k_instant_prompt_active )) && unsetopt prompt_cr prompt_sp || setopt prompt_cr prompt_sp + +(( ${#__p9k_src_opts} )) && setopt ${__p9k_src_opts[@]} +'builtin' 'unset' '__p9k_src_opts' diff --git a/powerlevel9k.zsh-theme b/powerlevel9k.zsh-theme new file mode 100644 index 00000000..328cd838 --- /dev/null +++ b/powerlevel9k.zsh-theme @@ -0,0 +1 @@ +'builtin' 'source' "${POWERLEVEL9K_INSTALLATION_DIR:-${${(%):-%x}:A:h}}/powerlevel10k.zsh-theme" diff --git a/prompt_powerlevel10k_setup b/prompt_powerlevel10k_setup new file mode 100644 index 00000000..328cd838 --- /dev/null +++ b/prompt_powerlevel10k_setup @@ -0,0 +1 @@ +'builtin' 'source' "${POWERLEVEL9K_INSTALLATION_DIR:-${${(%):-%x}:A:h}}/powerlevel10k.zsh-theme" diff --git a/prompt_powerlevel9k_setup b/prompt_powerlevel9k_setup new file mode 100644 index 00000000..328cd838 --- /dev/null +++ b/prompt_powerlevel9k_setup @@ -0,0 +1 @@ +'builtin' 'source' "${POWERLEVEL9K_INSTALLATION_DIR:-${${(%):-%x}:A:h}}/powerlevel10k.zsh-theme" |