forked from Powerlevel9k/powerlevel9k
-
Notifications
You must be signed in to change notification settings - Fork 0
/
powerlevel9k.zsh-theme
executable file
·975 lines (846 loc) · 34.3 KB
/
powerlevel9k.zsh-theme
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
# vim:ft=zsh ts=2 sw=2 sts=2 et fenc=utf-8
################################################################
# powerlevel9k Theme
# https://github.com/bhilburn/powerlevel9k
#
# This theme was inspired by agnoster's Theme:
# https://gist.github.com/3712874
################################################################
################################################################
# Please see the README file located in the source repository for full docs.
# There are a lot of easy ways you can customize your prompt segments and
# theming with simple variables defined in your `~/.zshrc`.
################################################################
## Turn on for Debugging
#zstyle ':vcs_info:*+*:*' debug true
#set -o xtrace
################################################################
# Icons
################################################################
# These characters require the Powerline fonts to work properly. If you see
# boxes or bizarre characters below, your fonts are not correctly installed. If
# you do not want to install a special font, you can set `POWERLEVEL9K_MODE` to
# `compatible`. This shows all icons in regular symbols.
# Initialize the icon list according to the user's `POWERLEVEL9K_MODE`.
typeset -gAH icons
case $POWERLEVEL9K_MODE in
'flat'|'awesome-patched')
# Awesome-Patched Font required! See:
# https://github.com/gabrielelana/awesome-terminal-fonts/tree/patching-strategy/patched
# Set the right locale to protect special characters
local LC_ALL="" LC_CTYPE="en_US.UTF-8"
icons=(
LEFT_SEGMENT_SEPARATOR $'\UE0B0' #
RIGHT_SEGMENT_SEPARATOR $'\UE0B2' #
LEFT_SUBSEGMENT_SEPARATOR $'\UE0B1' #
RIGHT_SUBSEGMENT_SEPARATOR $'\UE0B3' #
CARRIAGE_RETURN_ICON $'\U21B5' # ↵
ROOT_ICON $'\UE801' #
RUBY_ICON $'\UE847' #
AWS_ICON $'\UE895' #
BACKGROUND_JOBS_ICON $'\UE82F ' #
TEST_ICON $'\UE891' #
OK_ICON $'\U2713' # ✓
FAIL_ICON $'\U2718' # ✘
SYMFONY_ICON 'SF'
NODE_ICON $'\U2B22' # ⬢
MULTILINE_FIRST_PROMPT_PREFIX $'\U256D'$'\U2500'
MULTILINE_SECOND_PROMPT_PREFIX $'\U2570'$'\U2500 '
APPLE_ICON $'\UE26E' #
FREEBSD_ICON $'\U1F608 ' # 😈
LINUX_ICON $'\UE271' #
SUNOS_ICON $'\U1F31E ' # 🌞
HOME_ICON $'\UE12C ' #
NETWORK_ICON $'\UE1AD ' #
LOAD_ICON $'\UE190 ' #
#RAM_ICON $'\UE87D' #
RAM_ICON $'\UE1E2 ' #
VCS_UNTRACKED_ICON $'\UE16C' #
VCS_UNSTAGED_ICON $'\UE17C' #
VCS_STAGED_ICON $'\UE168' #
VCS_STASH_ICON $'\UE133 ' #
#VCS_INCOMING_CHANGES_ICON $'\UE1EB ' #
#VCS_INCOMING_CHANGES_ICON $'\UE80D ' #
VCS_INCOMING_CHANGES_ICON $'\UE131 ' #
#VCS_OUTGOING_CHANGES_ICON $'\UE1EC ' #
#VCS_OUTGOING_CHANGES_ICON $'\UE80E ' #
VCS_OUTGOING_CHANGES_ICON $'\UE132 ' #
VCS_TAG_ICON $'\UE817 ' #
VCS_BOOKMARK_ICON $'\UE87B' #
VCS_COMMIT_ICON $'\UE821 ' #
VCS_BRANCH_ICON $'\UE220' #
VCS_REMOTE_BRANCH_ICON ' '$'\UE804 ' #
VCS_GIT_ICON $'\UE20E ' #
VCS_HG_ICON $'\UE1C3 ' #
)
;;
'awesome-fontconfig')
# fontconfig with awesome-font required! See
# https://github.com/gabrielelana/awesome-terminal-fonts
icons=(
LEFT_SEGMENT_SEPARATOR $'\UE0B0' #
RIGHT_SEGMENT_SEPARATOR $'\UE0B2' #
LEFT_SUBSEGMENT_SEPARATOR $'\UE0B1' #
RIGHT_SUBSEGMENT_SEPARATOR $'\UE0B3' #
CARRIAGE_RETURN_ICON $'\U21B5' # ↵
ROOT_ICON $'\uF201' #
RUBY_ICON $'\UF247' #
AWS_ICON $'\UF296' #
BACKGROUND_JOBS_ICON $'\UF013 ' #
TEST_ICON $'\UF291' #
OK_ICON $'\UF23A' #
FAIL_ICON $'\UF281' #
SYMFONY_ICON 'SF'
NODE_ICON $'\U2B22' # ⬢
MULTILINE_FIRST_PROMPT_PREFIX $'\U256D'$'\U2500' # ╭─
MULTILINE_SECOND_PROMPT_PREFIX $'\U2570'$'\U2500 ' # ╰─
APPLE_ICON $'\UF179' #
FREEBSD_ICON $'\U1F608 ' # 😈
LINUX_ICON $'\UF17C' #
SUNOS_ICON $'\UF185 ' #
HOME_ICON $'\UF015 ' #
NETWORK_ICON $'\UF09E ' #
LOAD_ICON $'\UF080 ' #
RAM_ICON $'\UF0E4' #
VCS_UNTRACKED_ICON $'\UF059' #
VCS_UNSTAGED_ICON $'\UF06A' #
VCS_STAGED_ICON $'\UF055' #
VCS_STASH_ICON $'\UF01C ' #
VCS_INCOMING_CHANGES_ICON $'\UF01A ' #
VCS_OUTGOING_CHANGES_ICON $'\UF01B ' #
VCS_TAG_ICON $'\UF217 ' #
VCS_BOOKMARK_ICON $'\UF27B' #
VCS_COMMIT_ICON $'\UF221 ' #
VCS_BRANCH_ICON $'\UF126' #
VCS_REMOTE_BRANCH_ICON ' '$'\UF204 ' #
VCS_GIT_ICON $'\UF113 ' #
VCS_HG_ICON $'\UF0C3 ' #
)
;;
*)
# Powerline-Patched Font required!
# See https://github.com/Lokaltog/powerline-fonts
icons=(
LEFT_SEGMENT_SEPARATOR $'\uE0B0' #
RIGHT_SEGMENT_SEPARATOR $'\uE0B2' #
LEFT_SUBSEGMENT_SEPARATOR $'\UE0B1' #
RIGHT_SUBSEGMENT_SEPARATOR $'\UE0B3' #
CARRIAGE_RETURN_ICON $'\U21B5' # ↵
ROOT_ICON $'\u26A1' # ⚡
RUBY_ICON ''
AWS_ICON 'AWS:'
BACKGROUND_JOBS_ICON $'\u2699' # ⚙
TEST_ICON ''
OK_ICON $'\u2713' # ✓
FAIL_ICON $'\u2718' # ✘
SYMFONY_ICON 'SF'
NODE_ICON $'\u2B22' # ⬢
MULTILINE_FIRST_PROMPT_PREFIX $'\u256D'$'\u2500'
MULTILINE_SECOND_PROMPT_PREFIX $'\u2570'$'\u2500 '
APPLE_ICON 'OSX'
FREEBSD_ICON 'BSD'
LINUX_ICON 'Lx'
SUNOS_ICON 'Sun'
HOME_ICON ''
NETWORK_ICON 'IP'
LOAD_ICON 'L'
RAM_ICON 'RAM'
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_GIT_ICON ''
VCS_HG_ICON ''
)
;;
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')
# Set the right locale to protect special characters
local LC_ALL="" LC_CTYPE="en_US.UTF-8"
icons[LEFT_SEGMENT_SEPARATOR]=$'\u2B80' # ⮀
icons[RIGHT_SEGMENT_SEPARATOR]=$'\u2B82' # ⮂
icons[VCS_BRANCH_ICON]='@'
;;
esac
if [[ "$POWERLEVEL9K_HIDE_BRANCH_ICON" == true ]]; then
icons[VCS_BRANCH_ICON]=''
fi
################################################################
# Utility functions
################################################################
# Exits with 0 if a variable has been previously defined (even if empty)
# Takes the name of a variable that should be checked.
function defined() {
local varname="$1"
typeset -p "$varname" > /dev/null 2>&1
}
# Given the name of a variable and a default value, sets the variable
# value to the default only if it has not been defined.
#
# Typeset cannot set the value for an array, so this will only work
# for scalar values.
function set_default() {
local varname="$1"
local default_value="$2"
defined "$varname" || typeset -g "$varname"="$default_value"
}
# Safety function for printing icons
# Prints the named icon, or if that icon is undefined, the string name.
function print_icon() {
local icon_name=$1
local ICON_USER_VARIABLE=POWERLEVEL9K_${icon_name}
local USER_ICON=${(P)ICON_USER_VARIABLE}
if defined "$ICON_USER_VARIABLE"; then
echo -n "$USER_ICON"
else
echo -n "${icons[$icon_name]}"
fi
}
# Converts large memory values into a human-readable unit (e.g., bytes --> GB)
printSizeHumanReadable() {
local size=$1
local extension
extension=('B' 'K' 'M' 'G' 'T' 'P' 'E' 'Z' 'Y')
local index=1
# if the base is not Bytes
if [[ -n $2 ]]; then
for idx in "${extension[@]}"; do
if [[ "$2" == "$idx" ]]; then
break
fi
index=$(( index + 1 ))
done
fi
while (( (size / 1024) > 0 )); do
size=$(( size / 1024 ))
index=$(( index + 1 ))
done
echo "$size${extension[$index]}"
}
# Gets the first value out of a list of items that is not empty.
# The items are examined by a callback-function.
# Takes two arguments:
# * $list - A list of items
# * $callback - A callback function to examine if the item is
# worthy. The callback function has access to
# the inner variable $item.
function getRelevantItem() {
setopt shwordsplit # We need to split the words in $interfaces
local list callback
list=$1
callback=$2
for item in $list; do
# The first non-empty item wins
try=$(eval "$callback")
if [[ -n "$try" ]]; then
echo "$try"
break;
fi
done
}
get_icon_names() {
for key in ${(@k)icons}; do
echo "POWERLEVEL9K_$key: ${icons[$key]}"
done
}
# OS detection for the `os_icon` segment
case $(uname) in
Darwin)
OS='OSX'
OS_ICON=$(print_icon 'APPLE_ICON')
;;
FreeBSD)
OS='BSD'
OS_ICON=$(print_icon 'FREEBSD_ICON')
;;
OpenBSD)
OS='BSD'
OS_ICON=$(print_icon 'FREEBSD_ICON')
;;
DragonFly)
OS='BSD'
OS_ICON=$(print_icon 'FREEBSD_ICON')
;;
Linux)
OS='Linux'
OS_ICON=$(print_icon 'LINUX_ICON')
;;
SunOS)
OS='Solaris'
OS_ICON=$(print_icon 'SUNOS_ICON')
;;
*)
OS=''
OS_ICON=''
;;
esac
# Determine the correct sed parameter.
#
# `sed` is unfortunately not consistent across OSes when it comes to flags.
SED_EXTENDED_REGEX_PARAMETER="-r"
if [[ "$OS" == 'OSX' ]]; then
local IS_BSD_SED="$(sed --version &>> /dev/null || echo "BSD sed")"
if [[ -n "$IS_BSD_SED" ]]; then
SED_EXTENDED_REGEX_PARAMETER="-E"
fi
fi
################################################################
# Color Scheme
################################################################
if [[ "$POWERLEVEL9K_COLOR_SCHEME" == "light" ]]; then
DEFAULT_COLOR=white
DEFAULT_COLOR_INVERTED=black
DEFAULT_COLOR_DARK="252"
else
DEFAULT_COLOR=black
DEFAULT_COLOR_INVERTED=white
DEFAULT_COLOR_DARK="236"
fi
set_default POWERLEVEL9K_VCS_FOREGROUND "$DEFAULT_COLOR"
set_default POWERLEVEL9K_VCS_DARK_FOREGROUND "$DEFAULT_COLOR_DARK"
################################################################
# VCS Information Settings
################################################################
setopt prompt_subst
autoload -Uz vcs_info
VCS_WORKDIR_DIRTY=false
VCS_CHANGESET_PREFIX=''
if [[ "$POWERLEVEL9K_SHOW_CHANGESET" == true ]]; then
# Default: Just display the first 12 characters of our changeset-ID.
local VCS_CHANGESET_HASH_LENGTH=12
if [[ -n "$POWERLEVEL9K_CHANGESET_HASH_LENGTH" ]]; then
VCS_CHANGESET_HASH_LENGTH="$POWERLEVEL9K_CHANGESET_HASH_LENGTH"
fi
VCS_CHANGESET_PREFIX="%F{$POWERLEVEL9K_VCS_DARK_FOREGROUND}$(print_icon 'VCS_COMMIT_ICON')%0.$VCS_CHANGESET_HASH_LENGTH""i%f "
fi
zstyle ':vcs_info:*' enable git hg
zstyle ':vcs_info:*' check-for-changes true
VCS_DEFAULT_FORMAT="$VCS_CHANGESET_PREFIX%F{$POWERLEVEL9K_VCS_FOREGROUND}%b%c%u%m%f"
zstyle ':vcs_info:git*:*' formats "%F{$POWERLEVEL9K_VCS_FOREGROUND}$(print_icon 'VCS_GIT_ICON')%f$VCS_DEFAULT_FORMAT"
zstyle ':vcs_info:hg*:*' formats "%F{$POWERLEVEL9K_VCS_FOREGROUND}$(print_icon 'VCS_HG_ICON')%f$VCS_DEFAULT_FORMAT"
zstyle ':vcs_info:*' actionformats "%b %F{red}| %a%f"
zstyle ':vcs_info:*' stagedstr " %F{$POWERLEVEL9K_VCS_FOREGROUND}$(print_icon 'VCS_STAGED_ICON')%f"
zstyle ':vcs_info:*' unstagedstr " %F{$POWERLEVEL9K_VCS_FOREGROUND}$(print_icon 'VCS_UNSTAGED_ICON')%f"
zstyle ':vcs_info:git*+set-message:*' hooks vcs-detect-changes git-untracked git-aheadbehind git-stash git-remotebranch git-tagname
zstyle ':vcs_info:hg*+set-message:*' hooks vcs-detect-changes
# For Hg, only show the branch name
zstyle ':vcs_info:hg*:*' branchformat "$(print_icon 'VCS_BRANCH_ICON')%b"
# The `get-revision` function must be turned on for dirty-check to work for Hg
zstyle ':vcs_info:hg*:*' get-revision true
zstyle ':vcs_info:hg*:*' get-bookmarks true
zstyle ':vcs_info:hg*+gen-hg-bookmark-string:*' hooks hg-bookmarks
if [[ "$POWERLEVEL9K_SHOW_CHANGESET" == true ]]; then
zstyle ':vcs_info:*' get-revision true
fi
################################################################
# Prompt Segment Constructors
#
# Methodology behind user-defined variables overwriting colors:
# The first parameter to the segment constructors is the calling function's
# name. From this function name, we strip the "prompt_"-prefix and
# uppercase it. This is then prefixed with "POWERLEVEL9K_" and suffixed
# with either "_BACKGROUND" or "_FOREGROUND", thus giving us the variable
# name. So each new segment is user-overwritable by a variable following
# this naming convention.
################################################################
# The `CURRENT_BG` variable is used to remember what the last BG color used was
# when building the left-hand prompt. Because the RPROMPT is created from
# right-left but reads the opposite, this isn't necessary for the other side.
CURRENT_BG='NONE'
# Begin a left prompt segment
# Takes four arguments:
# * $1: Name of the function that was orginally invoked (mandatory).
# Necessary, to make the dynamic color-overwrite mechanism work.
# * $2: Background color
# * $3: Foreground color
# * $4: The segment content
# The latter three can be omitted,
left_prompt_segment() {
# Overwrite given background-color by user defined variable for this segment.
local BACKGROUND_USER_VARIABLE=POWERLEVEL9K_${(U)1#prompt_}_BACKGROUND
local BG_COLOR_MODIFIER=${(P)BACKGROUND_USER_VARIABLE}
[[ -n $BG_COLOR_MODIFIER ]] && 2="$BG_COLOR_MODIFIER"
# Overwrite given foreground-color by user defined variable for this segment.
local FOREGROUND_USER_VARIABLE=POWERLEVEL9K_${(U)1#prompt_}_FOREGROUND
local FG_COLOR_MODIFIER=${(P)FOREGROUND_USER_VARIABLE}
[[ -n $FG_COLOR_MODIFIER ]] && 3="$FG_COLOR_MODIFIER"
local bg fg
[[ -n $2 ]] && bg="%K{$2}" || bg="%k"
[[ -n $3 ]] && fg="%F{$3}" || fg="%f"
if [[ $CURRENT_BG != 'NONE' ]] && [[ "$2" != "$CURRENT_BG" ]]; then
# Middle segment
echo -n "%{$bg%F{$CURRENT_BG}%}$(print_icon 'LEFT_SEGMENT_SEPARATOR')%{$fg%} "
elif [[ "$CURRENT_BG" == "$2" ]]; then
# Middle segment with same color as previous segment
# We take the current foreground color as color for our
# subsegment (or the default color). This should have
# enough contrast.
local complement
[[ -n $3 ]] && complement=$3 || complement=$DEFAULT_COLOR
echo -n "%{$bg%F{$complement}%}$(print_icon 'LEFT_SUBSEGMENT_SEPARATOR')%{$fg%} "
else
# First segment
echo -n "%{$bg%}%{$fg%} "
fi
CURRENT_BG=$2
[[ -n $4 ]] && echo -n "$4 "
}
# End the left prompt, closes the final segment.
left_prompt_end() {
if [[ -n $CURRENT_BG ]]; then
echo -n "%{%k%F{$CURRENT_BG}%}$(print_icon 'LEFT_SEGMENT_SEPARATOR')"
else
echo -n "%{%k%}"
fi
echo -n "%{%f%} "
CURRENT_BG=''
}
CURRENT_RIGHT_BG='NONE'
# Begin a right prompt segment
# Takes four arguments:
# * $1: Name of the function that was orginally invoked (mandatory).
# Necessary, to make the dynamic color-overwrite mechanism work.
# * $2: Background color
# * $3: Foreground color
# * $4: The segment content
# No ending for the right prompt segment is needed (unlike the left prompt, above).
right_prompt_segment() {
# Overwrite given background-color by user defined variable for this segment.
local BACKGROUND_USER_VARIABLE=POWERLEVEL9K_${(U)1#prompt_}_BACKGROUND
local BG_COLOR_MODIFIER=${(P)BACKGROUND_USER_VARIABLE}
[[ -n $BG_COLOR_MODIFIER ]] && 2="$BG_COLOR_MODIFIER"
# Overwrite given foreground-color by user defined variable for this segment.
local FOREGROUND_USER_VARIABLE=POWERLEVEL9K_${(U)1#prompt_}_FOREGROUND
local FG_COLOR_MODIFIER=${(P)FOREGROUND_USER_VARIABLE}
[[ -n $FG_COLOR_MODIFIER ]] && 3="$FG_COLOR_MODIFIER"
local bg fg
[[ -n $2 ]] && bg="%K{$2}" || bg="%k"
[[ -n $3 ]] && fg="%F{$3}" || fg="%f"
if [[ "$CURRENT_RIGHT_BG" == "$2" ]]; then
# Middle segment with same color as previous segment
# We take the current foreground color as color for our
# subsegment (or the default color). This should have
# enough contrast.
local complement
[[ -n $3 ]] && complement=$3 || complement=$DEFAULT_COLOR
echo -n "%F{$complement}$(print_icon 'RIGHT_SUBSEGMENT_SEPARATOR')%f%{$bg%}%{$fg%} "
else
echo -n "%F{$2}$(print_icon 'RIGHT_SEGMENT_SEPARATOR')%f%{$bg%}%{$fg%} "
fi
[[ -n $4 ]] && echo -n "$4 %f"
CURRENT_RIGHT_BG=$2
}
################################################################
# The `vcs` Segment and VCS_INFO hooks / helper functions
################################################################
prompt_vcs() {
local vcs_prompt="${vcs_info_msg_0_}"
if [[ -n "$vcs_prompt" ]]; then
if [[ "$VCS_WORKDIR_DIRTY" == true ]]; then
"$1_prompt_segment" "$0_MODIFIED" "yellow" "$DEFAULT_COLOR"
else
"$1_prompt_segment" "$0" "green" "$DEFAULT_COLOR"
fi
echo -n "$vcs_prompt "
fi
}
function +vi-git-untracked() {
if [[ $(git rev-parse --is-inside-work-tree 2> /dev/null) == 'true' && \
-n $(git ls-files --others --exclude-standard | sed q) ]]; then
hook_com[unstaged]+=" %F{$POWERLEVEL9K_VCS_FOREGROUND}$(print_icon 'VCS_UNTRACKED_ICON')%f"
fi
}
function +vi-git-aheadbehind() {
local ahead behind branch_name
local -a gitstatus
branch_name=$(git symbolic-ref --short HEAD 2>/dev/null)
# for git prior to 1.7
# ahead=$(git rev-list origin/${branch_name}..HEAD | wc -l)
ahead=$(git rev-list "${branch_name}"@{upstream}..HEAD 2>/dev/null | wc -l)
(( ahead )) && gitstatus+=( " %F{$POWERLEVEL9K_VCS_FOREGROUND}$(print_icon 'VCS_OUTGOING_CHANGES_ICON')${ahead// /}%f" )
# for git prior to 1.7
# behind=$(git rev-list HEAD..origin/${branch_name} | wc -l)
behind=$(git rev-list HEAD.."${branch_name}"@{upstream} 2>/dev/null | wc -l)
(( behind )) && gitstatus+=( " %F{$POWERLEVEL9K_VCS_FOREGROUND}$(print_icon 'VCS_INCOMING_CHANGES_ICON')${behind// /}%f" )
hook_com[misc]+=${(j::)gitstatus}
}
function +vi-git-remotebranch() {
local remote branch_name
# Are we on a remote-tracking branch?
remote=${$(git rev-parse --verify HEAD@{upstream} --symbolic-full-name 2>/dev/null)/refs\/(remotes|heads)\/}
branch_name=$(git symbolic-ref --short HEAD 2>/dev/null)
hook_com[branch]="%F{$POWERLEVEL9K_VCS_FOREGROUND}$(print_icon 'VCS_BRANCH_ICON')${hook_com[branch]}%f"
# Always show the remote
#if [[ -n ${remote} ]] ; then
# Only show the remote if it differs from the local
if [[ -n ${remote} ]] && [[ "${remote#*/}" != "${branch_name}" ]] ; then
hook_com[branch]+="%F{$POWERLEVEL9K_VCS_FOREGROUND}$(print_icon 'VCS_REMOTE_BRANCH_ICON')%f%F{$POWERLEVEL9K_VCS_FOREGROUND}${remote// /}%f"
fi
}
function +vi-git-tagname() {
local tag
tag=$(git describe --tags --exact-match HEAD 2>/dev/null)
[[ -n "${tag}" ]] && hook_com[branch]=" %F{$POWERLEVEL9K_VCS_FOREGROUND}$(print_icon 'VCS_TAG_ICON')${tag}%f"
}
# Show count of stashed changes
# Port from https://github.com/whiteinge/dotfiles/blob/5dfd08d30f7f2749cfc60bc55564c6ea239624d9/.zsh_shouse_prompt#L268
function +vi-git-stash() {
local -a stashes
if [[ -s $(git rev-parse --git-dir)/refs/stash ]] ; then
stashes=$(git stash list 2>/dev/null | wc -l)
hook_com[misc]+=" %F{$POWERLEVEL9K_VCS_FOREGROUND}$(print_icon 'VCS_STASH_ICON')${stashes// /}%f"
fi
}
function +vi-hg-bookmarks() {
if [[ -n "${hgbmarks[@]}" ]]; then
hook_com[hg-bookmark-string]=" %F{$POWERLEVEL9K_VCS_FOREGROUND}$(print_icon 'VCS_BOOKMARK_ICON')${hgbmarks[@]}%f"
# 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 [[ -n "${hook_com[staged]}" ]] || [[ -n "${hook_com[unstaged]}" ]]; then
VCS_WORKDIR_DIRTY=true
else
VCS_WORKDIR_DIRTY=false
fi
}
################################################################
# Prompt Segment Definitions
################################################################
# The `CURRENT_BG` variable is used to remember what the last BG color used was
# when building the left-hand prompt. Because the RPROMPT is created from
# right-left but reads the opposite, this isn't necessary for the other side.
CURRENT_BG='NONE'
# AWS Profile
prompt_aws() {
local aws_profile="$AWS_DEFAULT_PROFILE"
if [[ -n "$aws_profile" ]];
then
"$1_prompt_segment" "$0" red white "$(print_icon 'AWS_ICON') $aws_profile"
fi
}
# Context: user@hostname (who am I and where am I)
# Note that if $DEFAULT_USER is not set, this prompt segment will always print
prompt_context() {
if [[ "$USER" != "$DEFAULT_USER" || -n "$SSH_CLIENT" ]]; then
if [[ $(print -P "%#") == '#' ]]; then
# Shell runs as root
"$1_prompt_segment" "$0_ROOT" "$DEFAULT_COLOR" "yellow" "$USER@%m"
else
"$1_prompt_segment" "$0_DEFAULT" "$DEFAULT_COLOR" "011" "$USER@%m"
fi
fi
}
# Dir: current working directory
prompt_dir() {
local current_path='%~'
if [[ -n "$POWERLEVEL9K_SHORTEN_DIR_LENGTH" ]]; then
case "$POWERLEVEL9K_SHORTEN_STRATEGY" in
truncate_middle)
current_path=$(pwd | sed -e "s,^$HOME,~," | sed $SED_EXTENDED_REGEX_PARAMETER "s/([^/]{$POWERLEVEL9K_SHORTEN_DIR_LENGTH})[^/]+([^/]{$POWERLEVEL9K_SHORTEN_DIR_LENGTH})\//\1\.\.\2\//g")
;;
truncate_from_right)
current_path=$(pwd | sed -e "s,^$HOME,~," | sed $SED_EXTENDED_REGEX_PARAMETER "s/([^/]{$POWERLEVEL9K_SHORTEN_DIR_LENGTH})[^/]+\//\1..\//g")
;;
*)
current_path="%$((POWERLEVEL9K_SHORTEN_DIR_LENGTH+1))(c:.../:)%${POWERLEVEL9K_SHORTEN_DIR_LENGTH}c"
;;
esac
fi
"$1_prompt_segment" "$0" "blue" "$DEFAULT_COLOR" "$(print_icon 'HOME_ICON')$current_path"
}
# Command number (in local history)
prompt_history() {
"$1_prompt_segment" "$0" "244" "$DEFAULT_COLOR" '%h'
}
prompt_icons_test() {
for key in ${(@k)icons}; do
# The lower color spectrum in ZSH makes big steps. Choosing
# the next color has enough contrast to read.
local random_color=$((RANDOM % 8))
local next_color=$((random_color+1))
"$1_prompt_segment" "$0" "$random_color" "$next_color" "$key: ${icons[$key]}"
done
}
prompt_ip() {
if [[ "$OS" == "OSX" ]]; then
if defined POWERLEVEL9K_IP_INTERFACE; then
# Get the IP address of the specified interface.
ip=$(ipconfig getifaddr "$POWERLEVEL9K_IP_INTERFACE")
else
local interfaces callback
# Get network interface names ordered by service precedence.
interfaces=$(networksetup -listnetworkserviceorder | grep -o "Device:\s*[a-z0-9]*" | grep -o -E '[a-z0-9]*$')
callback='ipconfig getifaddr $item'
ip=$(getRelevantItem "$interfaces" "$callback")
fi
else
if defined POWERLEVEL9K_IP_INTERFACE; then
# Get the IP address of the specified interface.
ip=$(ip -4 a show "$POWERLEVEL9K_IP_INTERFACE" | grep -o "inet\s*[0-9.]*" | grep -o "[0-9.]*")
else
local interfaces callback
# Get all network interface names that are up
interfaces=$(ip link ls up | grep -o -E ":\s+[a-z0-9]+:" | grep -v "lo" | grep -o "[a-z0-9]*")
callback='ip -4 a show $item | grep -o "inet\s*[0-9.]*" | grep -o "[0-9.]*"'
ip=$(getRelevantItem "$interfaces" "$callback")
fi
fi
"$1_prompt_segment" "$0" "cyan" "$DEFAULT_COLOR" "$(print_icon 'NETWORK_ICON') $ip"
}
set_default POWERLEVEL9K_LOAD_SHOW_FREE_RAM true
prompt_load() {
if [[ "$OS" == "OSX" ]]; then
load_avg_5min=$(sysctl vm.loadavg | grep -o -E '[0-9]+(\.|,)[0-9]+' | head -n 1)
if [[ "$POWERLEVEL9K_LOAD_SHOW_FREE_RAM" == true ]]; then
ramfree=$(vm_stat | grep "Pages free" | grep -o -E '[0-9]+')
# Convert pages into Bytes
ramfree=$(( ramfree * 4096 ))
base=''
fi
else
load_avg_5min=$(grep -o "[0-9.]*" /proc/loadavg | head -n 1)
if [[ "$POWERLEVEL9K_LOAD_SHOW_FREE_RAM" == true ]]; then
ramfree=$(grep -o -E "MemFree:\s+[0-9]+" /proc/meminfo | grep -o "[0-9]*")
base=K
fi
fi
# Replace comma
load_avg_5min=${load_avg_5min//,/.}
if [[ "$load_avg_5min" -gt 10 ]]; then
BACKGROUND_COLOR="red"
FUNCTION_SUFFIX="_CRITICAL"
elif [[ "$load_avg_5min" -gt 3 ]]; then
BACKGROUND_COLOR="yellow"
FUNCTION_SUFFIX="_WARNING"
else
BACKGROUND_COLOR="green"
FUNCTION_SUFFIX="_NORMAL"
fi
"$1_prompt_segment" "$0$FUNCTION_SUFFIX" "$BACKGROUND_COLOR" "$DEFAULT_COLOR" "$(print_icon 'LOAD_ICON') $load_avg_5min"
if [[ "$POWERLEVEL9K_LOAD_SHOW_FREE_RAM" == true ]]; then
echo -n "$(print_icon 'RAM_ICON') $(printSizeHumanReadable "$ramfree" $base) "
fi
}
# Node version
prompt_node_version() {
local nvm_prompt
nvm_prompt=$(node -v 2>/dev/null)
[[ -z "${nvm_prompt}" ]] && return
"$1_prompt_segment" "$0" "green" "white" "${nvm_prompt:1} $(print_icon 'NODE_ICON')"
}
# print a little OS icon
prompt_os_icon() {
"$1_prompt_segment" "$0" "black" "255" "$OS_ICON"
}
# print PHP version number
prompt_php_version() {
local php_version
php_version=$(php -v 2>&1 | grep -oe "^PHP\s*[0-9.]*")
if [[ -n "$php_version" ]]; then
"$1_prompt_segment" "$0" "013" "255" "$php_version"
fi
}
# rbenv information
prompt_rbenv() {
if [[ -n "$RBENV_VERSION" ]]; then
"$1_prompt_segment" "$0" "red" "$DEFAULT_COLOR" "$RBENV_VERSION"
fi
}
# RSpec test ratio
prompt_rspec_stats() {
if [[ (-d app && -d spec) ]]; then
local code_amount tests_amount
code_amount=$(ls -1 app/**/*.rb | wc -l)
tests_amount=$(ls -1 spec/**/*.rb | wc -l)
build_test_stats "$1" "$0" "$code_amount" "$tests_amount" "RSpec $(print_icon 'TEST_ICON')"
fi
}
# Ruby Version Manager information
prompt_rvm() {
local rvm_prompt
rvm_prompt=$(rvm-prompt)
if [ "$rvm_prompt" != "" ]; then
"$1_prompt_segment" "$0" "240" "$DEFAULT_COLOR" "$rvm_prompt $(print_icon 'RUBY_ICON') "
fi
}
# Status: (return code, root status, background jobs)
set_default POWERLEVEL9K_STATUS_VERBOSE true
prompt_status() {
local symbols bg
symbols=()
if [[ "$POWERLEVEL9K_STATUS_VERBOSE" == true ]]; then
if [[ "$RETVAL" -ne 0 ]]; then
symbols+="%F{226}$RETVAL $(print_icon 'CARRIAGE_RETURN_ICON')%f"
bg="red"
else
symbols+="%F{046}$(print_icon 'OK_ICON')%f"
bg="black"
fi
else
[[ "$RETVAL" -ne 0 ]] && symbols+="%{%F{red}%}$(print_icon 'FAIL_ICON')%f"
bg="$DEFAULT_COLOR"
fi
[[ "$UID" -eq 0 ]] && symbols+="%{%F{yellow}%} $(print_icon 'ROOT_ICON')%f"
[[ $(jobs -l | wc -l) -gt 0 ]] && symbols+="%{%F{cyan}%}$(print_icon 'BACKGROUND_JOBS_ICON')%f"
[[ -n "$symbols" ]] && "$1_prompt_segment" "$0" "$bg" "white" "$symbols"
}
# Symfony2-PHPUnit test ratio
prompt_symfony2_tests() {
if [[ (-d src && -d app && -f app/AppKernel.php) ]]; then
local code_amount tests_amount
code_amount=$(ls -1 src/**/*.php | grep -vc Tests)
tests_amount=$(ls -1 src/**/*.php | grep -c Tests)
build_test_stats "$1" "$0" "$code_amount" "$tests_amount" "SF2 $(print_icon 'TEST_ICON')"
fi
}
# Symfony2-Version
prompt_symfony2_version() {
if [[ -f app/bootstrap.php.cache ]]; then
local symfony2_version
symfony2_version=$(grep " VERSION " app/bootstrap.php.cache | sed -e 's/[^.0-9]*//g')
"$1_prompt_segment" "$0" "240" "$DEFAULT_COLOR" "$(print_icon 'SYMFONY_ICON') $symfony2_version"
fi
}
# Show a ratio of tests vs code
build_test_stats() {
local code_amount="$3"
local tests_amount="$4"+0.00001
local headline="$5"
# Set float precision to 2 digits:
typeset -F 2 ratio
local ratio=$(( (tests_amount/code_amount) * 100 ))
(( ratio >= 75 )) && "$1_prompt_segment" "${2}_GOOD" "cyan" "$DEFAULT_COLOR" "$headline: $ratio%%"
(( ratio >= 50 && ratio < 75 )) && "$1_prompt_segment" "$2_AVG" "yellow" "$DEFAULT_COLOR" "$headline: $ratio%%"
(( ratio < 50 )) && "$1_prompt_segment" "$2_BAD" "red" "$DEFAULT_COLOR" "$headline: $ratio%%"
}
# System time
prompt_time() {
local time_format="%D{%H:%M:%S}"
if [[ -n "$POWERLEVEL9K_TIME_FORMAT" ]]; then
time_format="$POWERLEVEL9K_TIME_FORMAT"
fi
"$1_prompt_segment" "$0" "$DEFAULT_COLOR_INVERTED" "$DEFAULT_COLOR" "$time_format"
}
# Vi Mode: show editing mode (NORMAL|INSERT)
prompt_vi_mode() {
case ${KEYMAP} in
main|viins)
"$1_prompt_segment" "$0_INSERT" "$DEFAULT_COLOR" "blue" "INSERT"
;;
vicmd)
"$1_prompt_segment" "$0_NORMAL" "$DEFAULT_COLOR" "default" "NORMAL"
;;
esac
}
# Virtualenv: current working virtualenv
# More information on virtualenv (Python):
# https://virtualenv.pypa.io/en/latest/
prompt_virtualenv() {
local virtualenv_path="$VIRTUAL_ENV"
if [[ -n "$virtualenv_path" && -n "$VIRTUAL_ENV_DISABLE_PROMPT" ]]; then
"$1_prompt_segment" "$0" "blue" "$DEFAULT_COLOR" "($(basename "$virtualenv_path"))"
fi
}
################################################################
# Prompt processing and drawing
################################################################
# Main prompt
build_left_prompt() {
defined POWERLEVEL9K_LEFT_PROMPT_ELEMENTS || POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(context dir rbenv vcs)
for element in "${POWERLEVEL9K_LEFT_PROMPT_ELEMENTS[@]}"; do
"prompt_$element" "left"
done
left_prompt_end
}
# Right prompt
build_right_prompt() {
defined POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS || POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(status history time)
for element in "${POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS[@]}"; do
"prompt_$element" "right"
done
}
powerlevel9k_prepare_prompts() {
RETVAL=$?
if [[ "$POWERLEVEL9K_PROMPT_ON_NEWLINE" == true ]]; then
PROMPT="$(print_icon 'MULTILINE_FIRST_PROMPT_PREFIX')%{%f%b%k%}$(build_left_prompt)
$(print_icon 'MULTILINE_SECOND_PROMPT_PREFIX')"
# The right prompt should be on the same line as the first line of the left
# prompt. To do so, there is just a quite ugly workaround: Before zsh draws
# the RPROMPT, we advise it, to go one line up. At the end of RPROMPT, we
# advise it to go one line down. See:
# http://superuser.com/questions/357107/zsh-right-justify-in-ps1
local LC_ALL="" LC_CTYPE="en_US.UTF-8" # Set the right locale to protect special characters
RPROMPT_PREFIX='%{'$'\e[1A''%}' # one line up
RPROMPT_SUFFIX='%{'$'\e[1B''%}' # one line down
else
PROMPT="%{%f%b%k%}$(build_left_prompt)"
RPROMPT_PREFIX=''
RPROMPT_SUFFIX=''
fi
if [[ "$POWERLEVEL9K_DISABLE_RPROMPT" != true ]]; then
RPROMPT="$RPROMPT_PREFIX%{%f%b%k%}$(build_right_prompt)%{$reset_color%}$RPROMPT_SUFFIX"
fi
}
function zle-line-init {
powerlevel9k_prepare_prompts
if (( ${+terminfo[smkx]} )); then
printf '%s' ${terminfo[smkx]}
fi
zle reset-prompt
zle -R
}
function zle-line-finish {
powerlevel9k_prepare_prompts
if (( ${+terminfo[rmkx]} )); then
printf '%s' ${terminfo[rmkx]}
fi
zle reset-prompt
zle -R
}
function zle-keymap-select {
powerlevel9k_prepare_prompts
zle reset-prompt
zle -R
}
powerlevel9k_init() {
# Display a warning if the terminal does not support 256 colors
local term_colors
term_colors=$(echotc Co)
if (( term_colors < 256 )); then
print -P "%F{red}WARNING!%f Your terminal supports less than 256 colors!"
print -P "You should put: %F{blue}export TERM=\"xterm-256color\"%f in your \~\/.zshrc"
fi
setopt LOCAL_OPTIONS
unsetopt XTRACE KSH_ARRAYS
setopt PROMPT_CR PROMPT_PERCENT PROMPT_SUBST MULTIBYTE
# initialize colors
autoload -U colors && colors
# initialize VCS
autoload -Uz add-zsh-hook
add-zsh-hook precmd vcs_info
# prepare prompts
add-zsh-hook precmd powerlevel9k_prepare_prompts
zle -N zle-line-init
zle -N zle-line-finish
zle -N zle-keymap-select
}
powerlevel9k_init "$@"