summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--accounts/gkleen@sif.nix1
-rw-r--r--accounts/gkleen@sif/autorandr-profiles/bstr.nix21
-rw-r--r--accounts/gkleen@sif/autorandr-profiles/default.nix13
-rw-r--r--accounts/gkleen@sif/backup-patterns24
-rw-r--r--accounts/gkleen@sif/default.nix181
-rw-r--r--accounts/gkleen@sif/dunst-settings.nix64
-rw-r--r--accounts/gkleen@sif/emacs.el99
-rw-r--r--accounts/gkleen@sif/firefox-chrome.css25
-rw-r--r--accounts/gkleen@sif/firefox-content.css12
-rw-r--r--accounts/gkleen@sif/ssh-hosts.nix190
-rw-r--r--accounts/gkleen@sif/xmonad/.gitignore4
-rw-r--r--accounts/gkleen@sif/xmonad/default.nix7
-rw-r--r--accounts/gkleen@sif/xmonad/lib/XMonad/Mpv.hs127
-rw-r--r--accounts/gkleen@sif/xmonad/lib/XMonad/Prompt/MyPass.hs94
-rw-r--r--accounts/gkleen@sif/xmonad/lib/XMonad/Prompt/MyShell.hs105
-rw-r--r--accounts/gkleen@sif/xmonad/lib/XMonad/Prompt/MySsh.hs243
-rw-r--r--accounts/gkleen@sif/xmonad/package.yaml30
-rw-r--r--accounts/gkleen@sif/xmonad/stack.nix17
-rw-r--r--accounts/gkleen@sif/xmonad/stack.yaml10
-rw-r--r--accounts/gkleen@sif/xmonad/xmonad-yggdrasil.nix21
-rw-r--r--accounts/gkleen@sif/xmonad/xmonad.hs898
-rw-r--r--accounts/gkleen@sif/xresources.nix46
-rw-r--r--overlays/nerdfonts.nix5
-rw-r--r--overlays/pidgin.nix20
-rw-r--r--overlays/urxvt/52-osc.pl41
-rw-r--r--overlays/urxvt/default.nix21
-rw-r--r--user-profiles/mpv/default.nix83
-rw-r--r--user-profiles/tmux/default.nix26
-rw-r--r--user-profiles/tmux/tmux.conf25
-rw-r--r--user-profiles/utils.nix22
-rw-r--r--user-profiles/zsh/default.nix30
-rw-r--r--user-profiles/zsh/p10k.zsh1548
-rw-r--r--users/gkleen/default.nix34
-rw-r--r--users/root.nix29
34 files changed, 4111 insertions, 5 deletions
diff --git a/accounts/gkleen@sif.nix b/accounts/gkleen@sif.nix
deleted file mode 100644
index c157af78..00000000
--- a/accounts/gkleen@sif.nix
+++ /dev/null
@@ -1 +0,0 @@
1{ ... }: {}
diff --git a/accounts/gkleen@sif/autorandr-profiles/bstr.nix b/accounts/gkleen@sif/autorandr-profiles/bstr.nix
new file mode 100644
index 00000000..527f8321
--- /dev/null
+++ b/accounts/gkleen@sif/autorandr-profiles/bstr.nix
@@ -0,0 +1,21 @@
1{
2 fingerprint = {
3 "eDP-1-1" = "00ffffffffffff004c83414100000000131d0104b5221378029491ae513eb7240b505400000001010101010101010101010101010101f0d40040f17018803020440058c21000001bf0d40040f17018803020440058c21000001b0000000f00ff093cff093c2c800000000000000000fe0041544e413536575230382d3020011502030f00e3058000e6060501736d0700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab";
4 "DP-1.3" = "00ffffffffffff000469a3289bdd00000b190104a53e22783a1cb5a3574fa0270d5054bfef00d1c0814081809500b300714f81c0010122cc0050f0703e80181035006d552100001a04740030f2705a80b0588a006d552100001a000000fd001e5018a03c041100f0f838f03c000000fc0041535553205042323837510a2001a8020327714f0102031112130414051f900e0f1d1e23091707830100006a030c0010000078200000565e00a0a0a02950302035006d552100001ee26800a0a0402e60302036006d552100001a011d00bc52d01e20b82855406d552100001e8c0ad090204031200c4055006d55210000180000000000000000000000000000000064";
5 };
6 config = {
7 "DP-1.3" = {
8 enable = true;
9 primary = true;
10 position = "3840x0";
11 rate = "60";
12 mode = "3840x2160";
13 };
14 eDP-1-1 = {
15 enable = true;
16 primary = false;
17 position = "0x0";
18 mode = "3840x2160";
19 };
20 };
21}
diff --git a/accounts/gkleen@sif/autorandr-profiles/default.nix b/accounts/gkleen@sif/autorandr-profiles/default.nix
new file mode 100644
index 00000000..304b4afe
--- /dev/null
+++ b/accounts/gkleen@sif/autorandr-profiles/default.nix
@@ -0,0 +1,13 @@
1{
2 fingerprint = {
3 eDP-1-1 = "00ffffffffffff004c83414100000000131d0104b5221378029491ae513eb7240b505400000001010101010101010101010101010101f0d40040f17018803020440058c21000001bf0d40040f17018803020440058c21000001b0000000f00ff093cff093c2c800000000000000000fe0041544e413536575230382d3020011502030f00e3058000e6060501736d0700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab";
4 };
5 config = {
6 eDP-1-1 = {
7 enable = true;
8 primary = true;
9 position = "0x0";
10 mode = "3840x2160";
11 };
12 };
13}
diff --git a/accounts/gkleen@sif/backup-patterns b/accounts/gkleen@sif/backup-patterns
new file mode 100644
index 00000000..d9d12f5b
--- /dev/null
+++ b/accounts/gkleen@sif/backup-patterns
@@ -0,0 +1,24 @@
1R .
2
3- pp:.cache
4- pp:.antigen
5+ pf:.cabal/config
6- pp:.cabal
7+ pf:.stack/config.yaml
8- pp:.stack
9- pp:.nox
10- pp:.local/share/Steam
11- sh:**/.stack-work
12- sh:**/.~lock.*
13- sh:**/.gup
14+ pf:.config/pulse/default.pa
15- pp:.config/pulse
16- pp:.zplug/log
17- pp:.zplug/cache
18- pp:.compose-cache
19- pp:.undo-tree
20- pp:.saves
21- pp:.mozilla
22- pp:Downloads/tmp
23- pp:secret
24- pp:mail \ No newline at end of file
diff --git a/accounts/gkleen@sif/default.nix b/accounts/gkleen@sif/default.nix
new file mode 100644
index 00000000..9f2df668
--- /dev/null
+++ b/accounts/gkleen@sif/default.nix
@@ -0,0 +1,181 @@
1{ flake, userName, pkgs, customUtils, lib, config, ... }:
2let
3 cfg = config.home-manager.users.${userName};
4 xmonad = import ./xmonad pkgs.haskellPackages;
5in {
6 imports = with flake.nixosModules.userProfiles.${userName}; [
7 mpv
8 ];
9
10 home-manager.users.${userName} = {
11 programs = {
12 ssh = {
13 matchBlocks = import ./ssh-hosts.nix; # customUtils.recImport { dir = ./ssh-hosts; };
14 extraConfig = ''
15 Match host uniworx3.ifi.lmu.de,uniworx4.ifi.lmu.de,uni2workgw.ifi.lmu.de,blackbeard.tcs.ifi.lmu.de,gitlab2.rz.ifi.lmu.de,oregon.tcs.ifi.lmu.de !exec "nc -z -w 1 %h %p &>/dev/null"
16 ProxyJump gate
17 '';
18 };
19
20 emacs = {
21 enable = true;
22 extraPackages = epkgs: with epkgs; [
23 evil evil-dvorak evil-magit undo-tree magit haskell-mode
24 nix-mode yaml-mode json-mode shakespeare-mode
25 smart-mode-line highlight-parentheses highlight-symbol
26 notmuch ag sass-mode lua-mode
27 ];
28 };
29 firefox = {
30 enable = true;
31 profiles.default = {
32 settings = {
33 "layout.css.devPixelsPerPx" = "1.75";
34 "browser.tabs.drawInTitlebar" = false;
35 "toolkit.legacyUserProfileCustomizations.stylesheets" = true;
36 };
37 };
38 };
39
40 urxvt = {
41 enable = true;
42 package = pkgs.rxvt_unicode-with-plugins;
43 fonts = [ "xft:Fira Mono for Powerline:style=Medium:pixelsize=20" ];
44 scroll = {
45 lines = 0;
46 bar.enable = false;
47 };
48 extraConfig = {
49 urgentOnBell = false;
50 print-pipe = "cat >/dev/null";
51 perl-ext-common = "52-osc,url-select";
52 "url-select.launcher" = "firefox";
53 "url-select.underline" = true;
54 };
55 keybindings = {
56 "M-u" = "perl:url-select:select_next";
57 };
58 };
59
60 zathura = {
61 enable = true;
62 package = pkgs.zathura.override { useMupdf = false; };
63 };
64
65 mpv.config = {
66 demuxer-max-bytes = 1073741824;
67 demuxer-max-back-bytes = 268435456;
68 };
69
70 autorandr = {
71 enable = true;
72 hooks.postswitch = {
73 # "restart-compton" = "${pkgs.systemd}/bin/systemctl --user try-restart picom";
74 "restart-trays" = ''
75 ${pkgs.coreutils}/bin/sleep 5
76 ${pkgs.systemd}/bin/systemctl --user try-restart trayer xmobar
77 '';
78 };
79 profiles = customUtils.recImport { dir = ./autorandr-profiles; };
80 };
81 };
82
83 services = {
84 dunst = {
85 settings = import ./dunst-settings.nix;
86 iconTheme = cfg.gtk.iconTheme;
87 enable = true;
88 };
89 emacs.enable = true;
90 gpg-agent = {
91 enable = true;
92 enableSshSupport = true;
93 extraConfig = ''
94 pinentry-program ${pkgs.pinentry-gtk2}/bin/pinentry
95 grab
96 '';
97 };
98 pasystray.enable = true;
99 udiskie = {
100 enable = true;
101 automount = false;
102 };
103 unclutter = {
104 enable = true;
105 timeout = 5;
106 };
107 network-manager-applet.enable = true;
108 blueman-applet.enable = true;
109
110 sxhkd = {
111 enable = true;
112 keybindings = {
113 "button8" = "pacmd set-source-mute @DEFAULT_SOURCE@ 0";
114 "@button8" = "pacmd set-source-mute @DEFAULT_SOURCE@ 1";
115 "button9" = "pacmd set-sink-mute @DEFAULT_SINK@ 1";
116 "@button9" = "pacmd set-sink-mute @DEFAULT_SINK@ 0";
117 };
118 };
119 };
120
121 gtk = {
122 enable = true;
123 font.name = "DejaVu Sans 6";
124 theme = {
125 package = pkgs.equilux-theme;
126 name = "Equilux-compact";
127 };
128 iconTheme = {
129 package = pkgs.paper-icon-theme;
130 name = "Paper";
131 };
132 };
133
134 xsession = {
135 enable = true;
136
137 windowManager.command = "${xmonad}/bin/xmonad";
138
139 initExtra = let
140 lockScript = pkgs.writeScript "lock" ''
141 #!${pkgs.stdenv.shell}
142 ${pkgs.playerctl}/bin/playerctl -a pause
143 exec ${pkgs.xsecurelock}/bin/xsecurelock
144 '';
145 in ''
146 ${pkgs.coreutils}/bin/env XSECURELOCK_WANT_FIRST_KEYPRESS=1 XSECURELOCK_DIM_ALPHA=1 ${pkgs.xss-lock}/bin/xss-lock -l -n ${pkgs.xsecurelock}/libexec/xsecurelock/dimmer -- ${lockScript} &
147 ${pkgs.xorg.xinput}/bin/xinput disable 'SynPS/2 Synaptics TouchPad' # Synaptics TM3512-010
148 ${pkgs.xorg.xset}/bin/xset s 590 10
149 '';
150 };
151
152 xresources.properties = import ./xresources.nix;
153
154 home = {
155 packages = with pkgs; [
156 fira-code powerline-fonts nerdfonts pavucontrol keepassxc
157 youtube-dl sxiv xclip mumble pulseaudio-ctl libnotify synergy
158 xorg.xbacklight screen-message pidgin-with-plugins
159 google-play-music-desktop-player qt5ct playerctl evince
160 thunderbird zulip zoom-us steam steam-run wireshark skype
161 virt-manager rclone cached-nix-shell xournal discord xmonad
162 ];
163
164 file = {
165 ".emacs".source = ./emacs.el;
166 ".backup-munin".source = ./backup-patterns;
167 ".mozilla/firefox/default/chrome/userChrome.css".source = ./firefox-chrome.css;
168 ".mozilla/firefox/default/chrome/userContent.css".source = ./firefox-content.css;
169 };
170
171 sessionVariables = {
172 GDK_SCALE = 96.0 / 282.0;
173 XDG_DATA_DIRS = "${pkgs.gsettings-desktop-schemas}/share/gsettings-schemas/${pkgs.gsettings-desktop-schemas.name}:${pkgs.gtk3}/share/gsettings-schemas/${pkgs.gtk3.name}:$XDG_DATA_DIRS";
174 QT_AUTO_SCREEN_SCALE_FACTOR = 1;
175 QT_QPA_PLATFORMTHEME = "qt5ct";
176 };
177
178 stateVersion = "20.03";
179 };
180 };
181}
diff --git a/accounts/gkleen@sif/dunst-settings.nix b/accounts/gkleen@sif/dunst-settings.nix
new file mode 100644
index 00000000..8319da03
--- /dev/null
+++ b/accounts/gkleen@sif/dunst-settings.nix
@@ -0,0 +1,64 @@
1{
2 global = {
3 font = "Monospace 6";
4 markup = "full";
5 format = "<i>%s</i> %p\\n%b";
6 alignment = "left";
7 geometry = "1216x10-32+64";
8 shrink = true;
9 monitor = 0;
10 follow = "none";
11 padding = 6;
12 horizontal_padding = 6;
13 separator_height = 1;
14 separator_color = "frame";
15 idle_threshold = 0;
16
17 transparency = 10;
18
19 frame_width = 1;
20 frame_color = "#999999";
21
22 word_wrap = true;
23 show_age_threshold = 15;
24 show_indicators = false;
25 icon_position = "right";
26 sort = false;
27 sticky_history = false;
28 };
29 shortcuts = {
30 close = "ctrl+space";
31 close_all = "ctrl+shift+space";
32 history = "ctrl+comma";
33 context = "ctrl+period";
34 };
35 urgency_low = {
36 background = "#000000";
37 foreground = "#999999";
38 timeout = 5;
39 };
40 urgency_normal = {
41 background = "#000000";
42 foreground = "#ffffff";
43 timeout = 15;
44 };
45 urgency_critical = {
46 background = "#900000";
47 foreground = "#ffffff";
48 timeout = 0;
49 };
50 pulseaudio-ctl = {
51 summary = "Volume *";
52 body = "Current is *";
53 set_stack_tag = "volume";
54 history_ignore = true;
55 };
56 mail = {
57 appname = "notmuch";
58 timeout = 0;
59 };
60 zulip = {
61 appname = "Zulip";
62 timeout = 0;
63 };
64}
diff --git a/accounts/gkleen@sif/emacs.el b/accounts/gkleen@sif/emacs.el
new file mode 100644
index 00000000..7bfd5c18
--- /dev/null
+++ b/accounts/gkleen@sif/emacs.el
@@ -0,0 +1,99 @@
1(menu-bar-mode -1)
2(scroll-bar-mode -1)
3(tool-bar-mode -1)
4
5(set-face-attribute 'default nil :height 50)
6
7(require 'evil)
8(evil-mode 1)
9
10(global-subword-mode)
11(global-undo-tree-mode)
12
13(global-set-key (kbd "RET") 'newline-and-indent)
14(global-set-key (kbd "M-g") 'magit-status)
15(global-set-key (kbd "M-?") 'vc-git-grep)
16
17(setq backup-directory-alist `(("." . "~/.saves")))
18(setq delete-old-versions t
19 kept-new-versions 6
20 kept-old-versions 2
21 version-control t)
22
23(add-hook 'haskell-mode-hook 'haskell-indentation-mode)
24(add-hook 'haskell-mode-hook 'subword-mode)
25(add-hook 'haskell-mode-hook 'highlight-symbol-mode)
26(add-hook 'haskell-mode-hook 'highlight-paretheses-mode)
27
28(add-hook 'js-mode-hook 'highlight-symbol-mode)
29(add-hook 'js-mode-hook 'highlight-parentheses-mode)
30(defun my-js-mode-hook ()
31 "Custom `js-mode' behaviours."
32 (setq js-indent-level 2)
33 )
34(add-hook 'js-mode-hook 'my-js-mode-hook)
35
36(setq notmuch-address-internal-completion '(received nil))
37(setq notmuch-always-prompt-for-sender t)
38(setq notmuch-command "notmuch-ssh")
39(setq notmuch-crypto-process-mime t)
40(setq notmuch-draft-tags '("+draft" "-inbox"))
41(setq notmuch-fcc-dirs nil)
42(setq notmuch-hello-sections '(notmuch-hello-insert-header notmuch-hello-insert-saved-searches))
43(setq notmuch-hello-thousands-separator " ")
44(setq notmuch-identities '("gkleen@yggdrasil.li" "g@141.li" "kleen@cip.ifi.lmu.de" "Gregor.Kleen@stud.ifi.lmu.de" "G.Kleen@campus.lmu.de" "G.Kleen@lmu.de" "gregor.kleen@ifi.lmu.de" "uni2work@ifi.lmu.de" "gregor@kleen.li"))
45(setq notmuch-message-headers '("Subject" "To" "Cc" "Date"))
46(setq notmuch-message-replied-tags '("+replied" "-unread" "-inbox"))
47(setq notmuch-saved-searches
48 (quote
49 ((:name "inbox" :query "tag:inbox" :key "i")
50 (:name "unread" :query "tag:unread AND tag:inbox" :key "u")
51 (:name "drafts" :query "tag:draft" :key "d")
52 (:name "all mail" :query "date:month.." :key "a" :count-query "*")
53 (:name "sent" :query "is:sent" :key "s" :count-query "is:sent")
54 )))
55(setq notmuch-search-oldest-first nil)
56(setq notmuch-show-all-tags-list t)
57(setq notmuch-show-logo nil)
58
59(setq send-mail-function 'sendmail-send-it)
60(setq mail-envelope-from 'header)
61(setq mail-specify-envelope-from 't)
62(setq mail-default-headers nil)
63(setq message-default-headers "")
64(setq message-default-mail-headers "")
65(setq message-sendmail-envelope-from 'header)
66
67(setq highlight-symbol-idle-delay 0)
68
69(setq indent-tabs-mode nil)
70
71(setq ido-enable-flex-matching t)
72(setq ido-everywhere t)
73(ido-mode 1)
74
75(setq mail-host-address "sif.midgard.yggdrasil")
76(setq user-full-name "Gregor Kleen")
77
78(defun tell-emacsclients-for-buffer-to-die ()
79 "Sends error exit command to every client for the current buffer."
80 (interactive)
81 (dolist (proc server-buffer-clients)
82 (server-send-string proc "-error die")))
83
84(defun kill-buffer-with-special-emacsclient-handling ()
85 "Wrapper around kill-buffer that ensures tell-emacsclients-for-buffer-to-die is on the hooks"
86 (interactive)
87 (add-hook 'kill-buffer-hook 'tell-emacsclients-for-buffer-to-die nil t)
88 (kill-buffer))
89
90;; (global-set-key (kbd "C-x k") 'kill-buffer)
91
92(defun install-emacsclient-wrapped-kill-buffer ()
93 "Installs wrapped kill-buffer with special emacsclient handling.
94Best not to install it unconditionally because the server is not
95necessarily running."
96 (interactive)
97 (global-set-key (kbd "C-x k") 'kill-buffer-with-special-emacsclient-handling))
98
99(add-hook 'server-switch-hook 'install-emacsclient-wrapped-kill-buffer)
diff --git a/accounts/gkleen@sif/firefox-chrome.css b/accounts/gkleen@sif/firefox-chrome.css
new file mode 100644
index 00000000..2d359771
--- /dev/null
+++ b/accounts/gkleen@sif/firefox-chrome.css
@@ -0,0 +1,25 @@
1@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
2
3* {
4 font-size:12px;
5}
6
7#sidebar {
8 min-width:20em !important;
9 max-width:20em !important;
10 border-right:1px solid rgba(30,30,30) !important;
11}
12
13#sidebar-header:nth-last-child(2) > *:last-child {
14 visibility: collapse;
15}
16
17#sidebar-splitter {
18 visibility: collapse;
19}
20
21#toolbar-menubar[inactive="true"] + #TabsToolbar {
22 visibility: collapse !important;
23}
24
25#sidebar-box[sidebarcommand="tabcenter-reborn_ariasuni-sidebar-action"] #sidebar-header { visibility: collapse !important; }
diff --git a/accounts/gkleen@sif/firefox-content.css b/accounts/gkleen@sif/firefox-content.css
new file mode 100644
index 00000000..3ac53a9d
--- /dev/null
+++ b/accounts/gkleen@sif/firefox-content.css
@@ -0,0 +1,12 @@
1@-moz-document url("about:blank") {
2 html {
3 background-color: rgb(40,40,40);
4 }
5}
6
7@-moz-document url(about:newtab) {
8 body, #newtab-customize-overlay {
9 background-color: rgb(40,40,40) !important;
10 color: rgb(166,166,166) !important;
11 }
12}
diff --git a/accounts/gkleen@sif/ssh-hosts.nix b/accounts/gkleen@sif/ssh-hosts.nix
new file mode 100644
index 00000000..ffbd8c00
--- /dev/null
+++ b/accounts/gkleen@sif/ssh-hosts.nix
@@ -0,0 +1,190 @@
1{
2 "git.ymir" =
3 { hostname = "ymir.yggdrasil.li";
4 user = "gitolite";
5 identityFile = "~/.ssh/gkleen@sif.midgard.yggdrasil";
6 };
7 "git.yggdrasil.li" =
8 { user = "gitolite";
9 identityFile = "~/.ssh/gkleen@sif.midgard.yggdrasil";
10 };
11 "git.rheperire.org" =
12 { user = "gitolite";
13 identityFile = "~/.ssh/gkleen@sif.midgard.yggdrasil";
14 };
15 "borg.munin" =
16 { hostname = "u120515.your-storagebox.de";
17 user = "u120515";
18 identityFile = "~/.ssh/borg.munin";
19 port = 23;
20 };
21 "munin" =
22 { hostname = "u120515.your-storagebox.de";
23 user = "u120515";
24 identityFile = "~/.ssh/munin";
25 };
26 "ymir" =
27 { hostname = "ymir.yggdrasil.li";
28 identityFile = "~/.ssh/gkleen@sif.midgard.yggdrasil";
29 };
30 "odin" =
31 { hostname = "odin.asgard.yggdrasil";
32 identityFile = "~/.ssh/gkleen@sif.midgard.yggdrasil";
33 };
34 "init.odin" =
35 { hostname = "odin.asgard.yggdrasil";
36 user = "root";
37 identityFile = "~/.ssh/rsa.gkleen@hel.midgard.yggdrasil";
38 extraOptions = {
39 StrictHostKeyChecking = "off";
40 };
41 };
42 "heimdallr" =
43 { hostname = "heimdallr.asgard.yggdrasil";
44 user = "root";
45 identityFile = "~/.ssh/gkleen@sif.midgard.yggdrasil";
46 };
47 "gitlab2.rz.ifi.lmu.de" =
48 { user = "git";
49 identityFile = "~/.ssh/gkleen@gitlab2.rz.ifi.lmu.de";
50 };
51 "gitlab2.cip.ifi.lmu.de" =
52 { user = "git";
53 identityFile = "~/.ssh/gkleen@sif.midgard.yggdrasil";
54 };
55 "hel".hostname = "hel.midgard.yggdrasil";
56 "blackbeard" =
57 { hostname = "blackbeard.tcs.ifi.lmu.de";
58 user = "pi";
59 identityFile = "~/.ssh/blackbeard";
60 };
61 "github.com" =
62 { user = "git";
63 identityFile = "~/.ssh/gkleen@github.com";
64 };
65 "ullr.playat.ch" =
66 { hostname = "ullr.playat.ch";
67 user = "minecraft";
68 identityFile = "~/.ssh/minecraft@ullr.playat.ch";
69 };
70 "ullr" =
71 { hostname = "185.170.112.70";
72 identityFile = "~/.ssh/gkleen@sif.midgard.yggdrasil";
73 };
74 "testworx" =
75 { hostname = "testworx.tcs.ifi.lmu.de";
76 user = "root";
77 port = 30363;
78 identityFile = "~/.ssh/testworx";
79 };
80 "remote.cip.ifi.lmu.de".user = "kleen";
81 "uniworx3" =
82 { hostname = "uniworx3.ifi.lmu.de";
83 user = "root";
84 identityFile = "~/.ssh/uni2work";
85 };
86 "uniworx4" =
87 { hostname = "uniworx4.ifi.lmu.de";
88 user = "root";
89 identityFile = "~/.ssh/uni2work";
90 };
91 "uni2workgw" =
92 { hostname = "uni2workgw.ifi.lmu.de";
93 user = "root";
94 identityFile = "~/.ssh/uni2work";
95 };
96 "uniworxdb" =
97 { hostname = "uniworxdb";
98 proxyJump = "uniworx4";
99 user = "root";
100 identityFile = "~/.ssh/uni2work";
101 };
102 "uniworxdb2" =
103 { hostname = "uniworxdb2";
104 proxyJump = "uniworx4";
105 user = "root";
106 identityFile = "~/.ssh/uni2work";
107 };
108 "gate2" =
109 { hostname = "gate2.tcs.ifi.lmu.de";
110 user = "gkleen";
111 identityFile = "~/.ssh/tcs";
112 };
113 "proxy.gate2" =
114 { hostname = "gate2.tcs.ifi.lmu.de";
115 user = "gkleen";
116 identityFile = "~/.ssh/proxy.gkleen@tcs.ifi.lmu.de";
117 dynamicForwards = [ { port = 8118; } ];
118 extraOptions = {
119 ExitOnForwardFailure = "yes";
120 };
121 };
122 "jump.gate2" =
123 { hostname = "gate2.tcs.ifi.lmu.de";
124 user = "gkleen";
125 identityFile = "~/.ssh/proxy.gkleen@tcs.ifi.lmu.de";
126 extraOptions = {
127 ExitOnForwardFailure = "yes";
128 };
129 };
130 "gate" =
131 { hostname = "gate.tcs.ifi.lmu.de";
132 user = "gkleen";
133 identityFile = "~/.ssh/tcs";
134 };
135 "proxy.gate" =
136 { hostname = "gate.tcs.ifi.lmu.de";
137 user = "gkleen";
138 identityFile = "~/.ssh/proxy.gkleen@tcs.ifi.lmu.de";
139 dynamicForwards = [ { port = 8118; } ];
140 extraOptions = {
141 ExitOnForwardFailure = "yes";
142 };
143 };
144 "jump.gate" =
145 { hostname = "gate.tcs.ifi.lmu.de";
146 user = "gkleen";
147 identityFile = "~/.ssh/proxy.gkleen@tcs.ifi.lmu.de";
148 extraOptions = {
149 ExitOnForwardFailure = "yes";
150 };
151 };
152 "oregon" =
153 { hostname = "oregon.tcs.ifi.lmu.de";
154 user = "root";
155 identityFile = "~/.ssh/tcs";
156 };
157 "witbank" =
158 { hostname = "witbank.tcs.ifi.lmu.de";
159 user = "uni2work";
160 identityFile = "~/.ssh/letz";
161 };
162 "git.odin" =
163 { hostname = "odin.asgard.yggdrasil";
164 user = "gitolite";
165 };
166 "notmuch.odin" =
167 { hostname = "odin.asgard.yggdrasil";
168 identityFile = "~/.ssh/notmuch.odin.asgard.yggdrasil";
169 };
170 "status.odin" =
171 { hostname = "odin.asgard.yggdrasil";
172 identityFile = "~/.ssh/status.odin.asgard.yggdrasil";
173 extraOptions.ControlPath = "~/.ssh/status-%r@%n:%p";
174 };
175 "moden" =
176 { hostname = "oristano.tcs.ifi.lmu.de";
177 user = "gkleen";
178 port = 30363;
179 identityFile = "~/.ssh/gkleen@oristano.tcs.ifi.lmu.de";
180 };
181 "ubuntu1804" =
182 { hostname = "192.168.122.30";
183 identityFile = "~/.ssh/gkleen@sif.midgard.yggdrasil";
184 forwardAgent = true;
185 };
186 "gitlab.haskell.org" =
187 { hostname = "gitlab.haskell.org";
188 identityFile = "~/.ssh/gkleen@gitlab.haskell.org";
189 };
190}
diff --git a/accounts/gkleen@sif/xmonad/.gitignore b/accounts/gkleen@sif/xmonad/.gitignore
new file mode 100644
index 00000000..c11891cd
--- /dev/null
+++ b/accounts/gkleen@sif/xmonad/.gitignore
@@ -0,0 +1,4 @@
1**/#*#
2**/.stack-work/
3/stack.yaml.lock
4/*.cabal
diff --git a/accounts/gkleen@sif/xmonad/default.nix b/accounts/gkleen@sif/xmonad/default.nix
new file mode 100644
index 00000000..8790c12f
--- /dev/null
+++ b/accounts/gkleen@sif/xmonad/default.nix
@@ -0,0 +1,7 @@
1argumentPackages@{ ... }:
2
3let
4 # defaultPackages = (import ./stackage.nix {});
5 # haskellPackages = defaultPackages // argumentPackages;
6 haskellPackages = argumentPackages;
7in haskellPackages.callPackage ./xmonad-yggdrasil.nix {}
diff --git a/accounts/gkleen@sif/xmonad/lib/XMonad/Mpv.hs b/accounts/gkleen@sif/xmonad/lib/XMonad/Mpv.hs
new file mode 100644
index 00000000..e6accdcc
--- /dev/null
+++ b/accounts/gkleen@sif/xmonad/lib/XMonad/Mpv.hs
@@ -0,0 +1,127 @@
1{-# LANGUAGE DeriveGeneric, OverloadedLists, OverloadedStrings, ViewPatterns, ExistentialQuantification, MultiWayIf #-}
2
3module XMonad.Mpv
4 ( MpvCommand(..), MpvResponse(..), MpvException(..)
5 , mpv
6 , mpvDir
7 , mpvAll, mpvOne
8 , mpvResponse
9 ) where
10
11import Data.Aeson
12
13import Data.Monoid
14
15import Network.Socket hiding (recv)
16import Network.Socket.ByteString
17
18import qualified Data.ByteString as BS
19import qualified Data.ByteString.Char8 as CBS
20import qualified Data.ByteString.Lazy as LBS
21
22import GHC.Generics (Generic)
23import Data.Typeable (Typeable)
24import Data.String (IsString(..))
25
26import Control.Exception
27
28import System.IO.Temp (getCanonicalTemporaryDirectory)
29
30import Control.Monad
31import Control.Exception (bracket)
32import Control.Monad.IO.Class (MonadIO(..))
33
34import System.FilePath
35import System.Directory (getDirectoryContents)
36
37import Data.List
38import Data.Either
39import Data.Maybe
40
41import Debug.Trace
42
43
44data MpvCommand
45 = forall a. ToJSON a => MpvSetProperty String a
46 | MpvGetProperty String
47data MpvResponse
48 = MpvError String
49 | MpvSuccess (Maybe Value)
50 deriving (Read, Show, Generic, Eq)
51data MpvException = MpvException String
52 | MpvNoValue
53 | MpvNoParse String
54 deriving (Generic, Typeable, Read, Show)
55instance Exception MpvException
56
57
58instance ToJSON MpvCommand where
59 toJSON (MpvSetProperty name val) = Array ["set_property", fromString name, toJSON val]
60 toJSON (MpvGetProperty name) = Array ["get_property", fromString name]
61
62instance FromJSON MpvResponse where
63 parseJSON = withObject "response object" $ \obj -> do
64 mval <- obj .:? "data"
65 err <- obj .: "error"
66
67 let ret
68 | err == "success" = MpvSuccess mval
69 | otherwise = MpvError err
70
71 return ret
72
73mpvSocket :: FilePath -> (Socket -> IO a) -> IO a
74mpvSocket sockPath = withSocketsDo . bracket mkSock close
75 where
76 mkSock = do
77 sock <- socket AF_UNIX Stream defaultProtocol
78 connect sock $ SockAddrUnix (traceId sockPath)
79 return sock
80
81mpvResponse :: FromJSON v => MpvResponse -> IO v
82mpvResponse (MpvError str) = throwIO $ MpvException str
83mpvResponse (MpvSuccess Nothing) = throwIO MpvNoValue
84mpvResponse (MpvSuccess (Just v)) = case fromJSON v of
85 Success v' -> return v'
86 Error str -> throwIO $ MpvNoParse str
87
88mpv :: FilePath -> MpvCommand -> IO MpvResponse
89mpv sockPath cmd = mpvSocket sockPath $ \sock -> do
90 let message = (`BS.append` "\n") . LBS.toStrict . encode $ Object [("command", toJSON cmd)]
91 traceIO $ show message
92 sendAll sock message
93 let recvAll = do
94 prefix <- recv sock 4096
95 if
96 | (prefix', rest) <- CBS.break (== '\n') prefix
97 , not (BS.null rest) -> return prefix'
98 | BS.null prefix -> return prefix
99 | otherwise -> BS.append prefix <$> recvAll
100 response <- recvAll
101 traceIO $ show response
102 either (ioError . userError) return . traceShowId $ eitherDecodeStrict' response
103
104mpvDir :: Exception e => FilePath -> (FilePath -> [(FilePath, Either e MpvResponse)] -> Maybe MpvCommand) -> IO [(FilePath, Either e MpvResponse)]
105mpvDir dir step = do
106 socks <- filter (".sock" `isSuffixOf`) <$> getDirectoryContents dir
107 go [] socks
108 where
109 go acc [] = return acc
110 go acc (sock:socks)
111 | Just cmd <- step sock acc = do
112 res <- try $ mpv (dir </> sock) cmd
113 go ((sock, res) : acc) socks
114 | otherwise =
115 go acc socks
116
117mpvAll :: FilePath -> MpvCommand -> IO [MpvResponse]
118mpvAll dir cmd = do
119 results <- map snd <$> (mpvDir dir (\_ _ -> Just cmd) :: IO [(FilePath, Either SomeException MpvResponse)])
120 mapM (either throwIO return) results
121
122mpvOne :: FilePath -> MpvCommand -> IO (Maybe MpvResponse)
123mpvOne dir cmd = listToMaybe . snd . partitionEithers . map snd <$> (mpvDir dir step :: IO [(FilePath, Either SomeException MpvResponse)])
124 where
125 step _ results
126 | any (isRight . snd) results = Nothing
127 | otherwise = Just cmd
diff --git a/accounts/gkleen@sif/xmonad/lib/XMonad/Prompt/MyPass.hs b/accounts/gkleen@sif/xmonad/lib/XMonad/Prompt/MyPass.hs
new file mode 100644
index 00000000..1caefae5
--- /dev/null
+++ b/accounts/gkleen@sif/xmonad/lib/XMonad/Prompt/MyPass.hs
@@ -0,0 +1,94 @@
1module XMonad.Prompt.MyPass
2 (
3 -- * Usages
4 -- $usages
5 mkPassPrompt
6 ) where
7
8import Control.Monad (liftM)
9import XMonad.Core
10import XMonad.Prompt ( XPrompt
11 , showXPrompt
12 , commandToComplete
13 , nextCompletion
14 , getNextCompletion
15 , XPConfig
16 , mkXPrompt
17 , searchPredicate)
18import System.Directory (getHomeDirectory)
19import System.FilePath (takeExtension, dropExtension, combine)
20import System.Posix.Env (getEnv)
21import XMonad.Util.Run (runProcessWithInput)
22
23-- $usages
24-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
25--
26-- > import XMonad.Prompt.Pass
27--
28-- Then add a keybinding for 'passPrompt', 'passGeneratePrompt' or 'passRemovePrompt':
29--
30-- > , ((modMask x , xK_p) , passPrompt xpconfig)
31-- > , ((modMask x .|. controlMask, xK_p) , passGeneratePrompt xpconfig)
32-- > , ((modMask x .|. controlMask .|. shiftMask, xK_p), passRemovePrompt xpconfig)
33--
34-- For detailed instructions on:
35--
36-- - editing your key bindings, see "XMonad.Doc.Extending#Editing_key_bindings".
37--
38-- - how to setup the password storage, see <http://git.zx2c4.com/password-store/about/>
39--
40
41type Predicate = String -> String -> Bool
42
43getPassCompl :: [String] -> Predicate -> String -> IO [String]
44getPassCompl compls p s
45 | length s <= minL
46 , all ((> minL) . length) compls = return []
47 | otherwise = do return $ filter (p s) compls
48 where
49 minL = 3
50
51type PromptLabel = String
52
53data Pass = Pass PromptLabel
54
55instance XPrompt Pass where
56 showXPrompt (Pass prompt) = prompt ++ ": "
57 commandToComplete _ c = c
58 nextCompletion _ = getNextCompletion
59
60-- | Default password store folder in $HOME/.password-store
61--
62passwordStoreFolderDefault :: String -> String
63passwordStoreFolderDefault home = combine home ".password-store"
64
65-- | Compute the password store's location.
66-- Use the PASSWORD_STORE_DIR environment variable to set the password store.
67-- If empty, return the password store located in user's home.
68--
69passwordStoreFolder :: IO String
70passwordStoreFolder =
71 getEnv "PASSWORD_STORE_DIR" >>= computePasswordStoreDir
72 where computePasswordStoreDir Nothing = liftM passwordStoreFolderDefault getHomeDirectory
73 computePasswordStoreDir (Just storeDir) = return storeDir
74
75-- | A pass prompt factory
76--
77mkPassPrompt :: PromptLabel -> (String -> X ()) -> XPConfig -> X ()
78mkPassPrompt promptLabel passwordFunction xpconfig = do
79 passwords <- io (passwordStoreFolder >>= getPasswords)
80 mkXPrompt (Pass promptLabel) xpconfig (getPassCompl passwords $ searchPredicate xpconfig) passwordFunction
81
82-- | Retrieve the list of passwords from the password storage 'passwordStoreDir
83getPasswords :: FilePath -> IO [String]
84getPasswords passwordStoreDir = do
85 files <- runProcessWithInput "find" [
86 passwordStoreDir,
87 "-type", "f",
88 "-name", "*.gpg",
89 "-printf", "%P\n"] []
90 return $ map removeGpgExtension $ lines files
91
92removeGpgExtension :: String -> String
93removeGpgExtension file | takeExtension file == ".gpg" = dropExtension file
94 | otherwise = file
diff --git a/accounts/gkleen@sif/xmonad/lib/XMonad/Prompt/MyShell.hs b/accounts/gkleen@sif/xmonad/lib/XMonad/Prompt/MyShell.hs
new file mode 100644
index 00000000..c268f87d
--- /dev/null
+++ b/accounts/gkleen@sif/xmonad/lib/XMonad/Prompt/MyShell.hs
@@ -0,0 +1,105 @@
1module XMonad.Prompt.MyShell
2 ( Shell (..)
3 , shellPrompt
4 , prompt
5 , safePrompt
6 , unsafePrompt
7 , getCommands
8 , getShellCompl
9 , split
10 ) where
11
12import Codec.Binary.UTF8.String (encodeString)
13import Control.Exception as E
14import Control.Monad (forM)
15import Data.List (isPrefixOf)
16import System.Directory (doesDirectoryExist, getDirectoryContents)
17import System.Environment (getEnv)
18import System.Posix.Files (getFileStatus, isDirectory)
19
20import XMonad hiding (config)
21import XMonad.Prompt
22import XMonad.Util.Run
23
24econst :: Monad m => a -> IOException -> m a
25econst = const . return
26
27data Shell = Shell String
28
29instance XPrompt Shell where
30 showXPrompt (Shell q) = q
31 completionToCommand _ = escape
32
33shellPrompt :: String -> XPConfig -> X ()
34shellPrompt q c = do
35 cmds <- io getCommands
36 mkXPrompt (Shell q) c (getShellCompl cmds) spawn
37
38{- $spawns
39 See safe and unsafeSpawn in "XMonad.Util.Run".
40 prompt is an alias for safePrompt;
41 safePrompt and unsafePrompt work on the same principles, but will use
42 XPrompt to interactively query the user for input; the appearance is
43 set by passing an XPConfig as the second argument. The first argument
44 is the program to be run with the interactive input.
45 You would use these like this:
46
47 > , ((modm, xK_b), safePrompt "firefox" greenXPConfig)
48 > , ((modm .|. shiftMask, xK_c), prompt ("xterm" ++ " -e") greenXPConfig)
49
50 Note that you want to use safePrompt for Firefox input, as Firefox
51 wants URLs, and unsafePrompt for the XTerm example because this allows
52 you to easily start a terminal executing an arbitrary command, like
53 'top'. -}
54
55prompt, unsafePrompt, safePrompt :: String -> FilePath -> XPConfig -> X ()
56prompt = unsafePrompt
57safePrompt q c config = mkXPrompt (Shell q) config (getShellCompl [c]) run
58 where run = safeSpawn c . return
59unsafePrompt q c config = mkXPrompt (Shell q) config (getShellCompl [c]) run
60 where run a = unsafeSpawn $ c ++ " " ++ a
61
62getShellCompl :: [String] -> String -> IO [String]
63getShellCompl cmds s | s == "" || last s == ' ' = return []
64 | otherwise = do
65 f <- fmap lines $ runProcessWithInput "bash" [] ("compgen -A file -- "
66 ++ s ++ "\n")
67 files <- case f of
68 [x] -> do fs <- getFileStatus (encodeString x)
69 if isDirectory fs then return [x ++ "/"]
70 else return [x]
71 _ -> return f
72 return . uniqSort $ files ++ commandCompletionFunction cmds s
73
74commandCompletionFunction :: [String] -> String -> [String]
75commandCompletionFunction cmds str | '/' `elem` str = []
76 | otherwise = filter (isPrefixOf str) cmds
77
78getCommands :: IO [String]
79getCommands = do
80 p <- getEnv "PATH" `E.catch` econst []
81 let ds = filter (/= "") $ split ':' p
82 es <- forM ds $ \d -> do
83 exists <- doesDirectoryExist d
84 if exists
85 then getDirectoryContents d
86 else return []
87 return . uniqSort . filter ((/= '.') . head) . concat $ es
88
89split :: Eq a => a -> [a] -> [[a]]
90split _ [] = []
91split e l =
92 f : split e (rest ls)
93 where
94 (f,ls) = span (/=e) l
95 rest s | s == [] = []
96 | otherwise = tail s
97
98escape :: String -> String
99escape [] = ""
100escape (x:xs)
101 | isSpecialChar x = '\\' : x : escape xs
102 | otherwise = x : escape xs
103
104isSpecialChar :: Char -> Bool
105isSpecialChar = flip elem " &\\@\"'#?$*()[]{};"
diff --git a/accounts/gkleen@sif/xmonad/lib/XMonad/Prompt/MySsh.hs b/accounts/gkleen@sif/xmonad/lib/XMonad/Prompt/MySsh.hs
new file mode 100644
index 00000000..c85d0f92
--- /dev/null
+++ b/accounts/gkleen@sif/xmonad/lib/XMonad/Prompt/MySsh.hs
@@ -0,0 +1,243 @@
1module XMonad.Prompt.MySsh
2 ( -- * Usage
3 -- $usage
4 sshPrompt,
5 Ssh,
6 Override (..),
7 mkOverride,
8 Conn (..),
9 moshCmd,
10 moshCmd',
11 sshCmd,
12 inTmux,
13 withEnv
14 ) where
15
16import XMonad
17import XMonad.Util.Run
18import XMonad.Prompt
19
20import System.Directory
21import System.Environment
22import qualified Control.Exception as E
23
24import Control.Monad
25import Data.Maybe
26
27import Text.Parsec.String
28import Text.Parsec
29import Data.Char (isSpace)
30
31econst :: Monad m => a -> E.IOException -> m a
32econst = const . return
33
34-- $usage
35-- 1. In your @~\/.xmonad\/xmonad.hs@:
36--
37-- > import XMonad.Prompt
38-- > import XMonad.Prompt.Ssh
39--
40-- 2. In your keybindings add something like:
41--
42-- > , ((modm .|. controlMask, xK_s), sshPrompt defaultXPConfig)
43--
44-- Keep in mind, that if you want to use the completion you have to
45-- disable the "HashKnownHosts" option in your ssh_config
46--
47-- For detailed instruction on editing the key binding see
48-- "XMonad.Doc.Extending#Editing_key_bindings".
49
50data Override = Override
51 { oUser :: Maybe String
52 , oHost :: String
53 , oPort :: Maybe Int
54 , oCommand :: Conn -> String
55 }
56
57mkOverride = Override { oUser = Nothing, oHost = "", oPort = Nothing, oCommand = sshCmd }
58sshCmd c = concat
59 [ "ssh -t "
60 , if isJust $ cUser c then (fromJust $ cUser c) ++ "@" else ""
61 , cHost c
62 , if isJust $ cPort c then " -p " ++ (show $ fromJust $ cPort c) else ""
63 , " -- "
64 , cCommand c
65 ]
66moshCmd c = concat
67 [ "mosh "
68 , if isJust $ cUser c then (fromJust $ cUser c) ++ "@" else ""
69 , cHost c
70 , if isJust $ cPort c then " --ssh=\"ssh -p " ++ (show $ fromJust $ cPort c) ++ "\"" else ""
71 , " -- "
72 , cCommand c
73 ]
74moshCmd' p c = concat
75 [ "mosh "
76 , "--server=" ++ p ++ " "
77 , if isJust $ cUser c then (fromJust $ cUser c) ++ "@" else ""
78 , cHost c
79 , if isJust $ cPort c then " --ssh=\"ssh -p " ++ (show $ fromJust $ cPort c) ++ "\"" else ""
80 , " -- "
81 , cCommand c
82 ]
83inTmux c
84 | null $ cCommand c = c { cCommand = "tmux new-session" }
85 | otherwise = c { cCommand = "tmux new-session \"" ++ (cCommand c) ++ "\"" }
86withEnv :: [(String, String)] -> Conn -> Conn
87withEnv envs c = c { cCommand = "env" ++ (concat $ map (\(n, v) -> ' ' : (n ++ "=" ++ v)) envs) ++ " " ++ (cCommand c) }
88
89data Conn = Conn
90 { cUser :: Maybe String
91 , cHost :: String
92 , cPort :: Maybe Int
93 , cCommand :: String
94 } deriving (Eq, Show, Read)
95
96data Ssh = Ssh
97
98instance XPrompt Ssh where
99 showXPrompt Ssh = "SSH to: "
100 commandToComplete _ c = c
101 nextCompletion _ = getNextCompletion
102
103toConn :: String -> Maybe Conn
104toConn = toConn' . parse connParser "(unknown)"
105toConn' :: Either ParseError Conn -> Maybe Conn
106toConn' (Left _) = Nothing
107toConn' (Right a) = Just a
108
109connParser :: Parser Conn
110connParser = do
111 spaces
112 user' <- optionMaybe $ try $ do
113 str <- many1 $ satisfy (\c -> (not $ isSpace c) && (c /= '@'))
114 char '@'
115 return str
116 host' <- many1 $ satisfy (not . isSpace)
117 port' <- optionMaybe $ try $ do
118 space
119 string "-p"
120 spaces
121 int <- many1 digit
122 (space >> return ()) <|> eof
123 return $ (read int :: Int)
124 spaces
125 command' <- many anyChar
126 eof
127 return $ Conn
128 { cHost = host'
129 , cUser = user'
130 , cPort = port'
131 , cCommand = command'
132 }
133
134sshPrompt :: [Override] -> XPConfig -> X ()
135sshPrompt o c = do
136 sc <- io sshComplList
137 mkXPrompt Ssh c (mkComplFunFromList sc) $ ssh o
138
139ssh :: [Override] -> String -> X ()
140ssh overrides str = do
141 let cmd = applyOverrides overrides str
142 liftIO $ putStr "SSH Command: "
143 liftIO $ putStrLn cmd
144 runInTerm "" cmd
145
146applyOverrides :: [Override] -> String -> String
147applyOverrides [] str = "ssh " ++ str
148applyOverrides (o:os) str = case (applyOverride o str) of
149 Just str -> str
150 Nothing -> applyOverrides os str
151
152applyOverride :: Override -> String -> Maybe String
153applyOverride o str = let
154 conn = toConn str
155 in
156 if isNothing conn then Nothing else
157 case (fromJust conn) `matches` o of
158 True -> Just $ (oCommand o) (fromJust conn)
159 False -> Nothing
160
161matches :: Conn -> Override -> Bool
162a `matches` b = and
163 [ justBool (cUser a) (oUser b) (==)
164 , (cHost a) == (oHost b)
165 , justBool (cPort a) (oPort b) (==)
166 ]
167
168justBool :: Eq a => Maybe a -> Maybe a -> (a -> a -> Bool) -> Bool
169justBool Nothing _ _ = True
170justBool _ Nothing _ = True
171justBool (Just a) (Just b) match = a `match` b
172
173sshComplList :: IO [String]
174sshComplList = uniqSort `fmap` liftM2 (++) sshComplListLocal sshComplListGlobal
175
176sshComplListLocal :: IO [String]
177sshComplListLocal = do
178 h <- getEnv "HOME"
179 s1 <- sshComplListFile $ h ++ "/.ssh/known_hosts"
180 s2 <- sshComplListConf $ h ++ "/.ssh/config"
181 return $ s1 ++ s2
182
183sshComplListGlobal :: IO [String]
184sshComplListGlobal = do
185 env <- getEnv "SSH_KNOWN_HOSTS" `E.catch` econst "/nonexistent"
186 fs <- mapM fileExists [ env
187 , "/usr/local/etc/ssh/ssh_known_hosts"
188 , "/usr/local/etc/ssh_known_hosts"
189 , "/etc/ssh/ssh_known_hosts"
190 , "/etc/ssh_known_hosts"
191 ]
192 case catMaybes fs of
193 [] -> return []
194 (f:_) -> sshComplListFile' f
195
196sshComplListFile :: String -> IO [String]
197sshComplListFile kh = do
198 f <- doesFileExist kh
199 if f then sshComplListFile' kh
200 else return []
201
202sshComplListFile' :: String -> IO [String]
203sshComplListFile' kh = do
204 l <- readFile kh
205 return $ map (getWithPort . takeWhile (/= ',') . concat . take 1 . words)
206 $ filter nonComment
207 $ lines l
208
209sshComplListConf :: String -> IO [String]
210sshComplListConf kh = do
211 f <- doesFileExist kh
212 if f then sshComplListConf' kh
213 else return []
214
215sshComplListConf' :: String -> IO [String]
216sshComplListConf' kh = do
217 l <- readFile kh
218 return $ map (!!1)
219 $ filter isHost
220 $ map words
221 $ lines l
222 where
223 isHost ws = take 1 ws == ["Host"] && length ws > 1
224
225fileExists :: String -> IO (Maybe String)
226fileExists kh = do
227 f <- doesFileExist kh
228 if f then return $ Just kh
229 else return Nothing
230
231nonComment :: String -> Bool
232nonComment [] = False
233nonComment ('#':_) = False
234nonComment ('|':_) = False -- hashed, undecodeable
235nonComment _ = True
236
237getWithPort :: String -> String
238getWithPort ('[':str) = host ++ " -p " ++ port
239 where (host,p) = break (==']') str
240 port = case p of
241 ']':':':x -> x
242 _ -> "22"
243getWithPort str = str
diff --git a/accounts/gkleen@sif/xmonad/package.yaml b/accounts/gkleen@sif/xmonad/package.yaml
new file mode 100644
index 00000000..48de1a53
--- /dev/null
+++ b/accounts/gkleen@sif/xmonad/package.yaml
@@ -0,0 +1,30 @@
1name: xmonad-yggdrasil
2
3executables:
4 xmonad:
5 dependencies:
6 - base
7 - xmonad
8 - xmonad-contrib
9 - aeson
10 - bytestring
11 - text
12 - temporary
13 - filepath
14 - directory
15 - network
16 - unix
17 - utf8-string
18 - parsec
19 - process
20 - mtl
21 - X11
22 - transformers
23 - containers
24 - hostname
25 - libnotify
26
27 main: xmonad.hs
28 source-dirs:
29 - .
30 - lib
diff --git a/accounts/gkleen@sif/xmonad/stack.nix b/accounts/gkleen@sif/xmonad/stack.nix
new file mode 100644
index 00000000..17a49e04
--- /dev/null
+++ b/accounts/gkleen@sif/xmonad/stack.nix
@@ -0,0 +1,17 @@
1{ ghc, nixpkgs ? import ./nixpkgs.nix {} }:
2
3let
4 haskellPackages = import ./stackage.nix { inherit nixpkgs; };
5 inherit (nixpkgs {}) pkgs;
6in pkgs.haskell.lib.buildStackProject {
7 inherit ghc;
8 inherit (haskellPackages) stack;
9 name = "stackenv";
10 buildInputs = (with pkgs;
11 [ xorg.libX11 xorg.libXrandr xorg.libXinerama xorg.libXScrnSaver xorg.libXext xorg.libXft
12 cairo
13 glib
14 ]) ++ (with haskellPackages;
15 [
16 ]);
17}
diff --git a/accounts/gkleen@sif/xmonad/stack.yaml b/accounts/gkleen@sif/xmonad/stack.yaml
new file mode 100644
index 00000000..b8ed1147
--- /dev/null
+++ b/accounts/gkleen@sif/xmonad/stack.yaml
@@ -0,0 +1,10 @@
1nix:
2 enable: true
3 shell-file: stack.nix
4
5resolver: lts-13.21
6
7packages:
8 - .
9
10extra-deps: []
diff --git a/accounts/gkleen@sif/xmonad/xmonad-yggdrasil.nix b/accounts/gkleen@sif/xmonad/xmonad-yggdrasil.nix
new file mode 100644
index 00000000..e8786d35
--- /dev/null
+++ b/accounts/gkleen@sif/xmonad/xmonad-yggdrasil.nix
@@ -0,0 +1,21 @@
1{ mkDerivation, aeson, base, bytestring, containers, directory
2, filepath, hostname, hpack, mtl, network, parsec, process, stdenv
3, temporary, transformers, unix, utf8-string, X11, xmonad
4, xmonad-contrib, libnotify
5}:
6mkDerivation {
7 pname = "xmonad-yggdrasil";
8 version = "0.0.0";
9 src = ./.;
10 isLibrary = false;
11 isExecutable = true;
12 libraryToolDepends = [ hpack ];
13 executableHaskellDepends = [
14 aeson base bytestring containers directory filepath hostname mtl
15 network parsec process temporary transformers unix utf8-string X11
16 xmonad xmonad-contrib libnotify
17 ];
18 preConfigure = "hpack";
19 license = "unknown";
20 hydraPlatforms = stdenv.lib.platforms.none;
21}
diff --git a/accounts/gkleen@sif/xmonad/xmonad.hs b/accounts/gkleen@sif/xmonad/xmonad.hs
new file mode 100644
index 00000000..f3a59f34
--- /dev/null
+++ b/accounts/gkleen@sif/xmonad/xmonad.hs
@@ -0,0 +1,898 @@
1{-# LANGUAGE TupleSections, ViewPatterns, OverloadedStrings, FlexibleInstances, UndecidableInstances, MultiWayIf #-}
2
3import XMonad
4import XMonad.Hooks.DynamicLog
5import XMonad.Hooks.ManageDocks
6import XMonad.Util.Run
7import XMonad.Util.Loggers
8import XMonad.Util.EZConfig(additionalKeys)
9import System.IO
10import System.IO.Error
11import System.Environment
12import Data.Map (Map)
13import qualified Data.Map as Map
14import qualified XMonad.StackSet as W
15import System.Exit
16import Control.Monad.State (get)
17-- import XMonad.Layout.Spiral
18import Data.Ratio
19import Data.List
20import Data.Char
21import Data.Maybe (fromMaybe, listToMaybe, maybeToList, catMaybes, isJust)
22import XMonad.Layout.Tabbed
23import XMonad.Prompt
24import XMonad.Prompt.Input
25import XMonad.Util.Scratchpad
26import XMonad.Util.NamedScratchpad
27import Control.Monad (sequence, liftM, liftM2, join, void)
28import XMonad.Util.WorkspaceCompare
29import XMonad.Layout.NoBorders
30import XMonad.Layout.PerWorkspace
31import XMonad.Layout.SimplestFloat
32import XMonad.Layout.Renamed
33import XMonad.Layout.Reflect
34import XMonad.Layout.OnHost
35import XMonad.Layout.Combo
36import XMonad.Layout.ComboP
37import XMonad.Layout.Column
38import XMonad.Layout.TwoPane
39import XMonad.Layout.IfMax
40import XMonad.Layout.LayoutBuilder
41import XMonad.Layout.WindowNavigation
42import XMonad.Layout.Dwindle
43import XMonad.Layout.TrackFloating
44import System.Process
45import System.Directory (removeFile)
46import System.Posix.Files
47import System.FilePath ((</>))
48import Control.Concurrent
49import System.Posix.Process (getProcessID)
50import System.IO.Error
51import System.IO
52import XMonad.Hooks.ManageHelpers hiding (CW)
53import XMonad.Hooks.UrgencyHook as U
54import XMonad.Hooks.EwmhDesktops
55import XMonad.StackSet (RationalRect (..))
56import Control.Monad (when, filterM, (<=<))
57import Graphics.X11.ExtraTypes.XF86
58import XMonad.Util.Cursor
59import XMonad.Actions.Warp
60import XMonad.Actions.FloatKeys
61import XMonad.Util.SpawnOnce
62import System.Directory
63import System.FilePath
64import XMonad.Actions.CopyWindow
65import XMonad.Hooks.ServerMode
66import XMonad.Actions.Commands
67import XMonad.Actions.CycleWS
68import XMonad.Actions.RotSlaves
69import XMonad.Actions.UpdatePointer
70import XMonad.Prompt.Window
71import Data.IORef
72import Data.Monoid
73import Data.String
74import qualified XMonad.Actions.PhysicalScreens as P
75
76import XMonad.Layout.IM
77
78import XMonad.Prompt.MyShell
79import XMonad.Prompt.MyPass
80import XMonad.Prompt.MySsh
81
82import XMonad.Mpv
83
84import Network.HostName
85
86import Control.Applicative ((<$>))
87
88import Libnotify as Notify hiding (appName)
89import qualified Libnotify as Notify (appName)
90import Libnotify (Notification)
91-- import System.Information.Battery
92
93import Data.Int (Int32)
94
95import System.Posix.Process
96import System.Posix.Signals
97import System.Posix.IO as Posix
98import Control.Exception
99
100import System.IO.Unsafe
101
102import Control.Monad.Trans.Class
103import Control.Monad.Trans.Maybe
104
105import Data.Fixed (Micro)
106
107import qualified Data.Text as Text
108import Data.Ord (comparing)
109import Debug.Trace
110
111instance MonadIO m => IsString (m ()) where
112 fromString = spawn
113
114type KeyMap = Map (ButtonMask, KeySym) (X ())
115
116data Host = Host
117 { hName :: HostName
118 , hManageHook :: ManageHook
119 , hWsp :: Integer -> WorkspaceId
120 , hCoWsp :: String -> Maybe WorkspaceId
121 , hKeysMod :: XConfig Layout -> (KeyMap -> KeyMap)
122 , hScreens :: [P.PhysicalScreen]
123 , hKbLayouts :: [(String, Maybe String)]
124 , hCmds :: X [(String, X ())]
125 , hKeyUpKeys :: XConfig Layout -> KeyMap
126 }
127
128defaultHost = Host { hName = "unkown"
129 , hManageHook = composeOne [manageScratchTerm]
130 , hWsp = show
131 , hCoWsp = const Nothing
132 , hKeysMod = const id
133 , hScreens = [0,1..]
134 , hKbLayouts = [ ("us", Just "dvp")
135 , ("us", Nothing)
136 , ("de", Nothing)
137 ]
138 , hCmds = return []
139 , hKeyUpKeys = const Map.empty
140 }
141
142browser :: String
143browser = "env MOZ_USE_XINPUT2=1 firefox"
144
145hostFromName :: HostName -> Host
146hostFromName h@("vali") = defaultHost { hName = h
147 , hManageHook = composeOne $ catMaybes [ Just manageScratchTerm
148 , assign "web" $ className =? ".dwb-wrapped"
149 , assign "web" $ className =? "Chromium"
150 , assign "work" $ className =? "Emacs"
151 , assign "media" $ className =? "mpv"
152 ]
153 , hWsp = hWsp
154 , hCoWsp = hCoWsp
155 , hKeysMod = \conf -> Map.union $ (Map.fromList $ join $ map (spawnBindings conf) [ (xK_d, ["chromium", "chromium $(xclip -o)"])
156 , (xK_e, ["emacsclient -c"])
157 ])
158 `Map.union`
159 ( Map.fromList [ ((XMonad.modMask conf .|. controlMask, xK_Return), scratchpadSpawnActionCustom $ (XMonad.terminal conf) ++ " -name scratchpad -title scratchpad -e tmux new-session -D -s scratch")
160 ] )
161 , hScreens = hScreens defaultHost
162 }
163 where
164 workspaceNames = Map.fromList [ (2, "web")
165 , (3, "work")
166 , (10, "media")
167 ]
168 hWsp = wspFromMap workspaceNames
169 hCoWsp = coWspFromMap workspaceNames
170 assign wsp test = (\wsp -> test -?> doShift wsp) <$> hCoWsp wsp
171hostFromName h
172 | h `elem` ["hel", "sif"] = defaultHost { hName = h
173 , hManageHook = namedScratchpadManageHook scratchpads <+> composeOne (catMaybes
174 [ assign "mpv" $ className =? "mpv"
175 , assign "mpv" $ (className =? "URxvt" <&&> title =? "irssi")
176 , assign "mpv" $ (className =? "URxvt" <&&> resource =? "presentation")
177 , assign "mpv" $ stringProperty "WM_WINDOW_ROLE" =? "presentation"
178 , assign "read" $ stringProperty "WM_WINDOW_ROLE" =? "presenter"
179 , assign "mpv" $ className =? "factorio"
180 , assign "web" $ className =? "chromium-browser"
181 , assign "web" $ className =? "Google-chrome"
182 , assign "work" $ (appName =? "Devtools" <&&> className =? "Firefox")
183 , assign "work" $ className =? "Postman"
184 , assign "web" $ className =? "Firefox"
185 , assign "comm" $ (className =? "URxvt" <&&> resource =? "comm")
186 , assign "comm" $ (className =? "Emacs" <&&> title =? "Mail")
187 , assign "comm" $ className =? "Zulip"
188 , assign "comm" $ className =? "Discord"
189 , assign "media" $ (className =? "URxvt" <&&> resource =? "media")
190 , assign "media" $ (className =? "URxvt" <&&> title =? "streamlink")
191 , assign "media" $ (className =? "URxvt" <&&> title =? "mpv")
192 , assign "monitor" $ (className =? "URxvt" <&&> fmap ("monitor" `isInfixOf`) title)
193 , assign "monitor" $ className =? "Grafana"
194 , Just $ (className =? "URxvt" <&&> resource =? "htop") -?> centerFloat
195 , Just $ (className =? "Scp-dbus-service.py") -?> centerFloat
196 , Just $ (className =? "URxvt" <&&> resource =? "log") -?> centerFloat
197 , assign "work" $ className =? "URxvt"
198 , assign' ["work", "uni"] $ (className =? "Emacs" <&&> appName /=? "Edit_with_Emacs_FRAME")
199 , assign' ["work", "uni"] $ className =? "jetbrains-idea-ce"
200 , assign "read" $ className =? "llpp"
201 , assign "read" $ className =? "Evince"
202 , assign "read" $ fmap ("zathura" `isInfixOf`) title
203 , assign "read" $ className =? "MuPDF"
204 , assign "read" $ className =? "Xournal"
205 , assign "read" $ appName =? "com-trollworks-gcs-app-GCS"
206 , assign "read" $ appName =? "Tux.py"
207 , assign "read" $ className =? "Gnucash"
208 , assign "comm" $ className =? "Skype"
209 , assign "comm" $ className =? "Daily"
210 , assign "comm" $ className =? "Pidgin"
211 , assign "comm" $ className =? "Slack"
212 , Just $ (resource =? "xvkbd") -?> doRectFloat $ RationalRect (1 % 8) (3 % 8) (6 % 8) (4 % 8)
213 , Just $ (stringProperty "_NET_WM_WINDOW_TYPE" =? "_NET_WM_WINDOW_TYPE_DIALOG") -?> doFloat
214 , Just $ (className =? "Dunst") -?> doFloat
215 , Just $ (className =? "Xmessage") -?> doCenterFloat
216 , Just $ (className =? "Nm-openconnect-auth-dialog") -?> centerFloat
217 , Just $ (className =? "Pinentry") -?> doCenterFloat
218 , Just $ (className =? "pinentry") -?> doCenterFloat
219 , Just $ (appName =? "Edit_with_Emacs_FRAME") -?> centerFloat
220 , Just $ (stringProperty "WM_WINDOW_ROLE" =? "GtkFileChooseDialog") -?> centerFloatSmall
221 , Just $ (className =? "Nvidia-settings") -?> doCenterFloat
222 , Just $ fmap ("Minetest" `isInfixOf`) title -?> doIgnore
223 , Just $ fmap ("Automachef" `isInfixOf`) title -?> doIgnore
224 ])
225 , hWsp = hWsp
226 , hCoWsp = hCoWsp
227 , hKeysMod = \conf -> Map.union $ (Map.fromList $ join $ map (spawnBindings conf) [ (xK_e, ["emacsclient -c"])
228 , (xK_d, [fromString browser, fromString $ browser ++ " $(xclip -o)", fromString $ "notmuch-links"])
229 , (xK_f, ["urxvtc -name comm -title Feeds -e mosh odin -- tmux new-session -ADs comm"])
230 , (xK_c, [ inputPrompt xPConfig "dc" ?+ dc ])
231 , (xK_g, ["pidgin"])
232 , (xK_s, ["skype"])
233 -- , (xK_p, [mkPassPrompt "Type password" pwType xPConfig, mkPassPrompt "Show password" pwShow xPConfig, mkPassPrompt "Copy password" pwClip xPConfig])
234 , (xK_w, ["sudo rewacom"])
235 , (xK_y, [ "tmux new-window -dt media /var/media/link.hs $(xclip -o)"
236 , "urxvtc -name media -e tmuxp load /var/media"
237 ])
238 , (xK_l, [ "tmux new-window -dt media mpv $(xclip -o)"
239 , "tmux new-window -dt media streamlink --retry-open 10 $(xclip -o)"
240 ])
241 , (xK_m, [ "emacsclient -c -F \"'(title . \\\"Mail\\\")\" -e '(notmuch)'"
242 , "emacsclient -c -F \"'(title . \\\"Mail\\\")\" -e '(notmuch-mua-new-mail)'"
243 , "emacsclient -c -F \"'(title . \\\"Mail\\\")\" -e \"(browse-url-mail \"$(xclip -o)\")\""
244 ])
245 , (xK_Return, ["keynav start,windowzoom", "keynav start"])
246 , (xK_t, [inputPrompt xPConfig "fuzzytime timer" ?+ fuzzytime, fuzzytime "unset", work_fuzzytime])
247 , (xK_a, [inputPrompt xPConfig "adjmix" ?+ adjmix])
248 , (xK_s, [ inputPromptWithCompl xPConfig "start synergy" synergyCompl ?+ synergyStart
249 , inputPromptWithCompl xPConfig "stop synergy" synergyCompl ?+ synergyStop
250 ])
251 , (xK_h, [ "urxvtc -name htop -e htop"
252 , "urxvtc -name log -e journalctl -xef"
253 ])
254 , (xK_x, [ "autorandr -c"
255 , "autorandr -fl default"
256 ])
257 , (xK_z, [ "zulip -- --force-device-scale-factor=2"
258 ])
259 ])
260 `Map.union`
261 ( Map.fromList [ ((XMonad.modMask conf .|. controlMask, xK_Return), namedScratchpadAction scratchpads "term")
262 , ((XMonad.modMask conf .|. controlMask, xK_a), namedScratchpadAction scratchpads "pavucontrol")
263 , ((XMonad.modMask conf .|. controlMask, xK_w), namedScratchpadAction scratchpads "alarms")
264 , ((XMonad.modMask conf .|. controlMask, xK_b), namedScratchpadAction scratchpads "blueman")
265 , ((XMonad.modMask conf .|. controlMask, xK_p), namedScratchpadAction scratchpads "keepassxc")
266 , ((XMonad.modMask conf .|. controlMask, xK_t), namedScratchpadAction scratchpads "toggl")
267 , ((XMonad.modMask conf .|. controlMask, xK_e), namedScratchpadAction scratchpads "emacs")
268 , ((XMonad.modMask conf .|. controlMask, xK_m), namedScratchpadAction scratchpads "calendar")
269 , ((XMonad.modMask conf .|. controlMask, xK_f), namedScratchpadAction scratchpads "music")
270 , ((XMonad.modMask conf .|. mod1Mask, xK_Up), rotate U)
271 , ((XMonad.modMask conf .|. mod1Mask, xK_Down), rotate D)
272 , ((XMonad.modMask conf .|. mod1Mask, xK_Left), rotate L)
273 , ((XMonad.modMask conf .|. mod1Mask, xK_Right), rotate R)
274 -- , ((XMonad.modMask conf .|. shiftMask, xK_a), startMute "hel")
275 ] )
276 , hKeyUpKeys = \conf -> Map.fromList [ -- ((XMonad.modMask conf .|. shiftMask, xK_a), stopMute "hel")
277 ]
278 , hScreens = hScreens defaultHost
279 , hCmds = return [ ("prev-workspace", prevWS)
280 , ("next-workspace", nextWS)
281 , ("prev-window", rotAllDown)
282 , ("next-window", rotAllUp)
283 , ("banish", banishScreen LowerRight)
284 , ("update-gpg-tty", safeSpawn "gpg-connect-agent" ["UPDATESTARTUPTTY", "/bye"])
285 , ("rescreen", rescreen)
286 , ("repanel", do
287 spawn "nm-applet"
288 spawn "blueman-applet"
289 spawn "pasystray"
290 spawn "kdeconnect-indicator"
291 spawn "dunst -print"
292 spawn "udiskie"
293 spawn "autocutsel -s PRIMARY"
294 spawn "autocutsel -s CLIPBOARD"
295 )
296 , ("pause", mediaMpv $ MpvSetProperty "pause" True)
297 , ("unpause", mediaMpv $ MpvSetProperty "pause" False)
298 , ("exit", io $ exitWith ExitSuccess)
299 ]
300 }
301 where
302 withGdkScale act = void . xfork $ setEnv "GDK_SCALE" "2" >> act
303 workspaceNames = Map.fromList [ (1, "comm")
304 , (2, "web")
305 , (3, "work")
306 , (4, "read")
307 , (5, "monitor")
308 , (6, "uni")
309 , (9, "media")
310 , (10, "mpv")
311 ]
312 scratchpads = [ NS "term" "urxvtc -name scratchpad -title scratchpad -e tmux new-session -AD -s scratch" (resource =? "scratchpad") centerFloat
313 , NS "pavucontrol" "pavucontrol" (resource =? "pavucontrol") centerFloat
314 , NS "alarms" "alarm-clock-applet" (className =? "Alarm-clock-applet" <&&> title =? "Alarms") centerFloat
315 , NS "blueman" "blueman-manager" (className =? ".blueman-manager-wrapped") centerFloat
316 , NS "keepassxc" "keepassxc" (className =? "KeePassXC") centerFloat
317 , NS "toggl" "toggldesktop" (className =? "Toggl Desktop") centerFloat
318 , NS "calendar" "minetime -- --force-device-scale-factor=1.6" (className =? "MineTime") centerFloat
319 , NS "emacs" "emacsclient -c -F \"'(title . \\\"Scratchpad\\\")\"" (className =? "Emacs" <&&> title =? "Scratchpad") centerFloat
320 , NS "music" "google-play-music-desktop-player --force-device-scale-factor=1.6" (className =? "Google Play Music Desktop Player") centerFloat
321 ]
322 centerFloat = customFloating $ RationalRect (1 % 16) (1 % 16) (7 % 8) (7 % 8)
323 centerFloatSmall = customFloating $ RationalRect (1 % 4) (1 % 4) (1 % 2) (1 % 2)
324 hWsp = wspFromMap workspaceNames
325 hCoWsp = coWspFromMap workspaceNames
326 assign wsp test = (\wsp -> test -?> doShift wsp) <$> hCoWsp wsp
327 assign' :: [String] -> Query Bool -> Maybe MaybeManageHook
328 assign' wsps test = do
329 wsIds <- mapM hCoWsp wsps
330 return $ test -?> go wsIds
331 where
332 go :: [WorkspaceId] -> ManageHook
333 go wsps = do
334 visWsps <- liftX $ (\wset -> W.tag . W.workspace <$> W.current wset : W.visible wset) <$> gets windowset
335 case (filter (`elem` visWsps) wsps, wsps) of
336 (wsp : _, _) -> doShift wsp
337 (_, wsp : _) -> doShift wsp
338 ([], []) -> return mempty
339 rotate rot = do
340 safeSpawn "xrandr" ["--output", "eDP-1", "--rotate", xrandrDir]
341 mapM_ rotTouch touchscreens
342 where
343 xrandrDir = case rot of
344 U -> "normal"
345 L -> "left"
346 R -> "right"
347 D -> "inverted"
348 matrix = case rot of
349 U -> [ [ 1, 0, 0]
350 , [ 0, 1, 0]
351 , [ 0, 0, 1]
352 ]
353 L -> [ [ 0, -1, 1]
354 , [ 1, 0, 0]
355 , [ 0, 0, 1]
356 ]
357 R -> [ [ 0, 1, 0]
358 , [-1, 0, 1]
359 , [ 0, 0, 1]
360 ]
361 D -> [ [-1, 0, 1]
362 , [ 0, -1, 1]
363 , [ 0, 0, 1]
364 ]
365 touchscreens = [ "Wacom Co.,Ltd. Pen and multitouch sensor Finger touch"
366 , "Wacom Co.,Ltd. Pen and multitouch sensor Pen stylus"
367 , "Wacom Co.,Ltd. Pen and multitouch sensor Pen eraser"
368 ]
369 rotTouch screen = do
370 safeSpawn "xinput" $ ["set-prop", screen, "Coordinate Transformation Matrix"] ++ map (\n -> show n ++ ",") (concat matrix)
371 safeSpawn "xinput" ["map-to-output", screen, "eDP-1"]
372 withPw f label = io . void . forkProcess $ do
373 uninstallSignalHandlers
374 void $ createSession
375 (dropWhileEnd isSpace -> pw) <- readCreateProcess (proc "pass" ["show", label]) ""
376 void $ f pw
377 pwType :: String -> X ()
378 pwType = withPw $ readCreateProcess (proc "xdotool" ["type", "--clearmodifiers", "--file", "-"])
379 pwClip label = safeSpawn "pass" ["show", "--clip", label]
380 pwShow :: String -> X ()
381 pwShow = withPw $ \pw -> do
382 xmessage <- fromMaybe "xmessage" <$> liftIO (lookupEnv "XMONAD_XMESSAGE")
383 readCreateProcess (proc xmessage ["-file", "-"]) pw
384 fuzzytime str = safeSpawn "fuzzytime" $ "timer" : words str
385 work_fuzzytime = io . void . forkProcess $ do
386 readCreateProcess (proc "worktime" []) "" >>= safeSpawn "fuzzytime" . ("timer" : ) . pure
387 adjmix str = safeSpawn "adjmix" $ words str
388 dc expr = void . xfork $ do
389 result <- readProcess "dc" [] $ expr ++ "f"
390 let
391 (first : rest) = filter (not . null) $ lines result
392 notification = Notify.summary first <> Notify.body (unlines rest) <> Notify.timeout Infinite <> Notify.urgency Normal <> Notify.appName "dc"
393 void $ Notify.display notification
394 synergyCompl = mkComplFunFromList' ["mathw86"]
395 synergyStart host = safeSpawn "systemctl" ["--user", "start", "synergy-rtunnel@" ++ host ++ ".service"]
396 synergyStop host = safeSpawn "systemctl" ["--user", "stop", "synergy-rtunnel@" ++ host ++ ".service"]
397
398hostFromName _ = defaultHost
399
400-- muteRef :: IORef (Maybe (String, Notification))
401-- {-# NOINLINE muteRef #-}
402-- muteRef = unsafePerformIO $ newIORef Nothing
403
404-- startMute, stopMute :: String -> X ()
405-- startMute sink = liftIO $ do
406-- muted <- isJust <$> readIORef muteRef
407-- when (not muted) $ do
408-- let
409-- notification = Notify.summary "Muted" <> Notify.timeout Infinite <> Notify.urgency Normal
410-- level = "0.0dB"
411-- -- level <- runProcessWithInput "ssh" ["bragi", "cat", "/dev/shm/mix/" ++ sink ++ "/level"] ""
412-- -- callProcess "ssh" ["bragi", "adjmix", "-t", sink, "-o", "0"]
413-- hPutStrLn stderr "Mute"
414-- writeIORef muteRef . Just . (level, ) =<< Notify.display notification
415-- stopMute sink = liftIO $ do
416-- let
417-- unmute (Just (level, notification)) = do
418-- hPutStrLn stderr "Unmute"
419-- -- callProcess "ssh" ["bragi", "adjmix", "-t", sink, "-o", level]
420-- Notify.close notification
421-- unmute Nothing = return ()
422-- muted <- isJust <$> readIORef muteRef
423-- when muted . join . atomicModifyIORef muteRef $ (Nothing, ) . unmute
424
425wspFromMap workspaceNames = \i -> case Map.lookup i workspaceNames of
426 Just str -> show i ++ " " ++ str
427 Nothing -> show i
428
429coWspFromMap workspaceNames = \str -> case filter ((== str) . snd) $ Map.toList workspaceNames of
430 [] -> Nothing
431 [(i, _)] -> Just $ wspFromMap workspaceNames i
432 _ -> Nothing
433
434spawnModifiers = [0, controlMask, shiftMask .|. controlMask]
435spawnBindings :: XConfig layout -> (KeySym, [X ()]) -> [((KeyMask, KeySym), X ())]
436spawnBindings conf (k, cmds) = zipWith (\m cmd -> ((modm .|. mod1Mask .|. m, k), cmd)) spawnModifiers cmds
437 where
438 modm = XMonad.modMask conf
439
440manageScratchTerm = (resource =? "scratchpad" <||> resource =? "keysetup") -?> doRectFloat $ RationalRect (1 % 16) (1 % 16) (7 % 8) (7 % 8)
441
442tabbedLayout t = renamed [Replace "Tabbed"] $ reflectHoriz $ t CustomShrink $ tabbedTheme
443tabbedLayoutHoriz t = renamed [Replace "Tabbed Horiz"] $ reflectVert $ t CustomShrink $ tabbedTheme
444tabbedTheme = def
445 { activeColor = "black"
446 , inactiveColor = "black"
447 , urgentColor = "black"
448 , activeBorderColor = "grey"
449 , inactiveBorderColor = "#202020"
450 , urgentBorderColor = "#bb0000"
451 , activeTextColor = "grey"
452 , inactiveTextColor = "grey"
453 , urgentTextColor = "grey"
454 , decoHeight = 32
455 , fontName = "xft:Fira Mono for Powerline:style=Medium:pixelsize=22.5"
456 }
457
458main :: IO ()
459main = do
460 arguments <- either (const []) id <$> tryIOError getArgs
461 case arguments of
462 ["--command", s] -> do
463 d <- openDisplay ""
464 rw <- rootWindow d $ defaultScreen d
465 a <- internAtom d "XMONAD_COMMAND" False
466 m <- internAtom d s False
467 allocaXEvent $ \e -> do
468 setEventType e clientMessage
469 setClientMessageEvent e rw a 32 m currentTime
470 sendEvent d rw False structureNotifyMask e
471 sync d False
472 _ -> do
473 -- batteryMon <- xfork $ monitorBattery Nothing Nothing
474 hostname <- getHostName
475 let
476 host = hostFromName hostname
477 setEnv "HOST" hostname
478 let myConfig = withHostUrgency . ewmh $ docks def
479 { manageHook = hManageHook host
480 , terminal = "urxvtc"
481 , layoutHook = smartBorders . avoidStruts $ windowNavigation layout'
482 , logHook = do
483 dynamicLogString xmobarPP' >>= writeProps
484 updatePointer (99 % 100, 98 % 100) (0, 0)
485 , modMask = mod4Mask
486 , keys = \conf -> hKeysMod host conf $ myKeys' conf host
487 , workspaces = take (length numKeys) $ map wsp [1..]
488 , startupHook = setDefaultCursor xC_left_ptr
489 , normalBorderColor = "#202020"
490 , focusedBorderColor = "grey"
491 , handleEventHook = fullscreenEventHook <+> (serverModeEventHookCmd' $ hCmds host) <+> keyUpEventHook
492 }
493 writeProps str = do
494 let encodeCChar = map $ fromIntegral . fromEnum
495 atoms = [ "_XMONAD_WORKSPACES"
496 , "_XMONAD_LAYOUT"
497 , "_XMONAD_TITLE"
498 ]
499 (flip mapM_) (zip atoms (lines str)) $ \(atom', content) -> do
500 ustring <- getAtom "UTF8_STRING"
501 atom <- getAtom atom'
502 withDisplay $ \dpy -> io $ do
503 root <- rootWindow dpy $ defaultScreen dpy
504 changeProperty8 dpy root atom ustring propModeReplace $ encodeCChar content
505 sync dpy True
506 wsp = hWsp host
507 -- We can´t define per-host layout modifiers because we lack dependent types
508 layout' = onHost "skadhi" ( onWorkspace (wsp 1) (Full ||| withIM (1%5) (Title "Buddy List") tabbedLayout') $
509 onWorkspace (wsp 10) Full $
510 onWorkspace (wsp 2) (Full ||| tabbedLayout') $
511 onWorkspace (wsp 5) tabbedLayout' $
512 onWorkspace (wsp 8) (withIM (1%5) (Title "Friends") tabbedLayout') $
513 defaultLayouts
514 ) $
515 onHost "vali" ( onWorkspace (wsp 2) (Full ||| tabbedLayout' ||| combineTwo (TwoPane 0.01 0.57) Full tabbedLayout') $
516 onWorkspace (wsp 3) workLayouts $
517 defaultLayouts
518 ) $
519 onHost "hel" ( onWorkspace (wsp 1) (withIM (1 % 8) (Title "Buddy List") $ trackFloating tabbedLayout') $
520 onWorkspace (wsp 2) (tabbedLayout''' ||| Dwindle R CW 1 (5 % 100)) $
521 onWorkspace (wsp 3) workLayouts $
522 onWorkspace (wsp 6) workLayouts $
523 onWorkspace (wsp 4) (tabbedLayout' ||| tabbedLayoutHoriz' ||| Dwindle R CW 1 (5 % 100)) $
524 onWorkspace (wsp 5) (tabbedLayout''' ||| Dwindle R CW 1 (5 % 100)) $
525 onWorkspace (wsp 10) (tabbedLayout''' ||| combineTwoP (TwoPane (1 % 100) (3 % 4)) tabbedLayout''' tabbedLayout''' (ClassName "mpv") ||| Dwindle R CW 1 (5 % 100)) $
526 defaultLayouts
527 ) $
528 onHost "sif" ( onWorkspace (wsp 1) (withIM (1 % 8) (Title "Buddy List") $ trackFloating tabbedLayout') $
529 onWorkspace (wsp 2) (tabbedLayout''' ||| Dwindle R CW 1 (5 % 100)) $
530 onWorkspace (wsp 3) workLayouts $
531 onWorkspace (wsp 6) workLayouts $
532 onWorkspace (wsp 4) (tabbedLayout' ||| tabbedLayoutHoriz' ||| Dwindle R CW 1 (5 % 100)) $
533 onWorkspace (wsp 5) (tabbedLayout''' ||| Dwindle R CW 1 (5 % 100)) $
534 onWorkspace (wsp 10) (tabbedLayout''' ||| combineTwoP (TwoPane (1 % 100) (3 % 4)) tabbedLayout''' tabbedLayout''' (ClassName "mpv") ||| Dwindle R CW 1 (5 % 100)) $
535 defaultLayouts
536 ) $
537 defaultLayouts
538 -- tabbedLayout''' = renamed [Replace "Tabbed'"] $ IfMax 1 (noBorders Full) (tabbedLayout tabbedBottomAlways)
539 tabbedLayout''' = tabbedLayout tabbedBottom
540 tabbedLayout' = tabbedLayout tabbedBottomAlways
541 tabbedLayoutHoriz' = tabbedLayoutHoriz tabbedLeftAlways
542 defaultLayouts = {- spiralWithDir East CW (1 % 2) -} Dwindle R CW 1 (5 % 100) ||| tabbedLayout' ||| Full
543 -- workLayouts = {- spiralWithDir East CW (1 % 2) -} Dwindle R CW (2 % 1) (5 % 100) ||| tabbedLayout' ||| Full
544 workLayouts = tabbedLayout' ||| (renamed [Replace "Combined"] $ combineTwoP (TwoPane (1 % 100) (1891 % 2560)) tabbedLayout''' (Column 1.6) (ClassName "Postman" `Or` ClassName "Emacs" `Or` ClassName "jetbrains-idea-ce" `Or` (Resource "Devtools" `And` ClassName "Firefox"))) ||| Full ||| Dwindle R CW 1 (5 % 100)
545 sqrtTwo = approxRational (sqrt 2) (1 / 2560)
546 xmobarPP' = xmobarPP { ppTitle = shorten 80
547 , ppSort = (liftM2 (.)) getSortByIndex $ return scratchpadFilterOutWorkspace
548 , ppUrgent = wrap "(" ")" . xmobarColor "red" ""
549 , ppHiddenNoWindows = xmobarColor "#202020" "" . wrap "(" ")"
550 , ppVisible = wrap "(" ")" . xmobarColor "yellow" ""
551 , ppCurrent = wrap "(" ")" . xmobarColor "green" ""
552 , ppHidden = wrap "(" ")"
553 , ppWsSep = " "
554 , ppSep = "\n"
555 }
556 withHostUrgency = case hostname of
557 "hel" -> withUrgencyHookC urgencyHook' $ urgencyConfig { suppressWhen = U.Never, remindWhen = Dont }
558 "sif" -> withUrgencyHookC urgencyHook' $ urgencyConfig { suppressWhen = U.Never, remindWhen = Dont }
559 _ -> id
560 urgencyHook' window = do
561 runQuery ((resource =? "comm" <||> resource =? "Pidgin" <||> className =? "Gajim" <||> className =? "Skype") --> safeSpawn "thinklight" ["Blink", "100"]) window
562 urgencyHook (BorderUrgencyHook { urgencyBorderColor = "#bb0000" }) window
563 shutdown :: SomeException -> IO a
564 shutdown e = do
565 let pids = [ -- batteryMon
566 ]
567 mapM_ (signalProcess sigTERM) pids
568 mapM_ (getProcessStatus False False) pids
569 throw e
570 keyUpEventHook :: Event -> X All
571 keyUpEventHook event = handle event >> return (All True)
572 where
573 handle (KeyEvent { ev_event_type = t, ev_state = m, ev_keycode = code })
574 | t == keyRelease = withDisplay $ \dpy -> do
575 s <- io $ keycodeToKeysym dpy code 0
576 mClean <- cleanMask m
577 ks <- asks $ hKeyUpKeys host . config
578 userCodeDef () $ whenJust (Map.lookup (mClean, s) ks) id
579 | otherwise = return ()
580 handle _ = return ()
581 handle shutdown $ launch myConfig
582
583secs :: Int -> Int
584secs = (* 1000000)
585
586-- monitorBattery :: Maybe BatteryContext -> Maybe Notification -> IO ()
587-- monitorBattery Nothing n = do
588-- ctx <- batteryContextNew
589-- case ctx of
590-- Nothing -> threadDelay (secs 10) >> monitorBattery Nothing n
591-- Just _ -> monitorBattery ctx n
592-- monitorBattery ctx@(Just ctx') n = do
593-- batInfo <- getBatteryInfo ctx'
594-- case batInfo of
595-- Nothing -> threadDelay (secs 1) >> monitorBattery ctx n
596-- Just batInfo -> do
597-- let n'
598-- | batteryState batInfo == BatteryStateDischarging
599-- , timeLeft <= 1200
600-- , timeLeft > 0 = Just $ summary "Discharging" <> hint "value" percentage <> urgency u <> body (duz timeLeft ++ "left")
601-- | otherwise = Nothing
602-- u
603-- | timeLeft <= 600 = Critical
604-- | timeLeft <= 1800 = Normal
605-- | otherwise = Low
606-- timeLeft = batteryTimeToEmpty batInfo
607-- percentage :: Int32
608-- percentage = round $ batteryPercentage batInfo
609-- ts = [("s", 60), ("m", 60), ("h", 24), ("d", 365), ("y", 1)]
610-- duz ms = ss
611-- where (ss, _) = foldl (\(ss, x) (s, y) -> ((if rem x y > 0 then show (rem x y) ++ s ++ " " else "") ++ ss , quot x y)) ("", ms) ts
612-- case n' of
613-- Just n' -> Notify.display (maybe mempty reuse n <> Notify.appName "monitorBattery" <> n') >>= (\n -> threadDelay (secs 2) >> monitorBattery ctx (Just n))
614-- Nothing -> threadDelay (secs 30) >> monitorBattery ctx n
615
616disableTouchpad, disableTrackpoint, enableTrackpoint, enableTouchpad :: X ()
617enableTouchpad = safeSpawn "xinput" ["enable", "SynPS/2 Synaptics TouchPad"]
618disableTouchpad = safeSpawn "xinput" ["disable", "SynPS/2 Synaptics TouchPad"]
619enableTrackpoint = safeSpawn "xinput" ["enable", "TPPS/2 IBM TrackPoint"]
620disableTrackpoint = safeSpawn "xinput" ["disable", "TPPS/2 IBM TrackPoint"]
621
622isDisabled :: String -> X Bool
623isDisabled str = do
624 out <- runProcessWithInput "xinput" ["list", str] ""
625 return $ "disabled" `isInfixOf` out
626
627
628spawnKeychain :: X ()
629spawnKeychain = do
630 home <- liftIO getHomeDirectory
631 let keys = (map ((home </>) . (".ssh/" ++)) ["id", "id-rsa"]) ++ ["6B13AA67"]
632 liftIO (maybe (return ()) (setEnv "SSH_ASKPASS") =<< findAskpass)
633 safeSpawn "keychain" . (["--agents", "gpg,ssh"] ++)=<< liftIO (filterM doesFileExist keys)
634 where
635 findAskpass = filter `liftM` readFile "/etc/zshrc"
636 filter = listToMaybe . catMaybes . map (stripPrefix "export SSH_ASKPASS=") . lines
637
638assimilateKeychain :: X ()
639assimilateKeychain = liftIO $ assimilateKeychain' >> return ()
640assimilateKeychain' = tryIOError $ do
641 -- pid <- getProcessID
642 -- tmpDir <- lookupEnv "TMPDIR"
643 -- let tmpDir' = fromMaybe "/tmp" tmpDir
644 -- tmpFile = tmpDir' </> "xmonad-keychain" ++ (show pid) ++ ".env"
645 env <- runProcessWithInput "sh" ["-c", "eval $(keychain --eval --noask --agents gpg,ssh); env"] "" -- > " ++ tmpFile] ""
646 -- env <- readFile tmpFile
647 let envVars = Map.fromList $ map (\(k, v) -> (k, tail' v)) $ map (span (/= '=')) $ envLines
648 envVars' = Map.filterWithKey (\k _ -> k `elem` transfer) envVars
649 transfer = ["SSH_AUTH_SOCK", "SSH_AGENT_PID", "GPG_AGENT_INFO"]
650 envLines = filter (elem '=') $ lines env :: [String]
651 sequence $ map (\(k, c) -> setEnv k c) $ Map.toList envVars'
652 -- removeFile tmpFile
653 where
654 tail' [] = []
655 tail' (x:xs) = xs
656
657
658numKeys = [xK_parenleft, xK_parenright, xK_braceright, xK_plus, xK_braceleft, xK_bracketright, xK_bracketleft, xK_exclam, xK_equal, xK_asterisk]
659
660instance Shrinker CustomShrink where
661 shrinkIt _ "" = [""]
662 shrinkIt s cs
663 | length cs >= 4 = cs : shrinkIt s ((reverse . drop 4 . reverse $ cs) ++ "...")
664 | otherwise = cs : shrinkIt s (init cs)
665
666xPConfig :: XPConfig
667xPConfig = def
668 { font = "xft:Fira Mono for Powerline:style=Medium:pixelsize=22.5"
669 , height = 32
670 , bgColor = "black"
671 , fgColor = "grey"
672 , fgHLight = "green"
673 , bgHLight = "black"
674 , borderColor = "grey"
675 , searchPredicate = (\needle haystack -> all (`isInfixOf` map toLower haystack) . map (map toLower) $ words needle)
676 , position = Top
677 }
678
679sshOverrides = map (\h -> mkOverride { oHost = h, oCommand = moshCmd . inTmux } )
680 [
681 "odin", "odin.asgard.yggdrasil"
682 , "ymir", "ymir.yggdrasil.li", "ymir.niflheim.yggdrasil"
683 , "surtr", "yggdrasil.li", "surtr.yggdrasil.li", "praseodym.org", "surtr.praseodym.org", "surtr.141.li", "141.li"
684 , "vindler", "vindler.alfheim.yggdrasil"
685 , "ullr"
686 , "heimdallr", "heimdallr.asgard.yggdrasil"
687 , "testworx"
688 ]
689 ++
690 map (\h -> mkOverride { oHost = h, oCommand = moshCmd' "/run/current-system/sw/bin/mosh-server" . withEnv [("TERM", "xterm")] . inTmux} )
691 [ "bragi", "bragi.asgard.yggdrasil"
692 ]
693 ++
694 map (\h -> mkOverride { oHost = h, oCommand = sshCmd . withEnv [("TERM", "xterm")] . inTmux } )
695 [ "remote.cip.ifi.lmu.de"
696 , "uniworx3", "uniworx4", "uniworxdb"
697 ]
698
699backlight :: (Rational -> Rational) -> X ()
700backlight f = void . xfork . liftIO $ do
701 [ _device
702 , _class
703 , read . Text.unpack -> currentBright
704 , _currentPercentage
705 , read . Text.unpack -> maximumBright
706 ] <- Text.splitOn "," . Text.pack <$> readProcess "brightnessctl" ["-m"] ""
707 let current = currentBright % maximumBright
708 new' = f current * fromIntegral maximumBright
709 new :: Integer
710 new | floor new' < 0 = 0
711 | ceiling new' > maximumBright = maximumBright
712 | new' >= maximumBright % 2 = ceiling new'
713 | otherwise = floor new'
714 callProcess "brightnessctl" ["-m", "s", show new]
715
716cycleThrough :: [Rational] -> (Rational -> Rational)
717cycleThrough opts current = fromMaybe currentOpt $ listToMaybe next'
718 where currentOpt = minimumBy (comparing $ abs . subtract current) opts
719 (_, _ : next') = break (== currentOpt) opts
720
721cycleKbLayout :: [(String, Maybe String)] -> X ()
722cycleKbLayout [] = return ()
723cycleKbLayout layouts = liftIO $ do
724 next <- (getNext . extract) `liftM` runProcessWithInput "setxkbmap" ["-query"] ""
725 let
726 args = case next of
727 (l, Just v) -> [l, v]
728 (l, Nothing) -> [l]
729 safeSpawn "setxkbmap" args
730 where
731 extract :: String -> Maybe (String, Maybe String)
732 extract str = listToMaybe $ do
733 ["layout:", l] <- str'
734 [(l, Just v) | ["variant:", v] <- str'] ++ pure (l, Nothing)
735 where
736 str' = map words $ lines str
737 getNext :: Maybe (String, Maybe String) -> (String, Maybe String)
738 getNext = maybe (head layouts) getNext'
739 getNext' x = case elemIndex x layouts of
740 Nothing -> getNext Nothing
741 Just i -> layouts !! ((i + 1) `mod` length layouts)
742
743mpvAll' :: MpvCommand -> IO [MpvResponse]
744mpvAll' = mpvAll "/var/media/.mpv-ipc"
745
746mpvOne' :: MpvCommand -> IO (Maybe MpvResponse)
747mpvOne' = mpvOne "/var/media/.mpv-ipc"
748
749mediaMpv :: MpvCommand -> X ()
750mediaMpv cmd = void . xfork $ print =<< mpvAll' cmd
751
752mediaMpvTogglePause :: X ()
753mediaMpvTogglePause = void . xfork $ do
754 paused <- mapM mpvResponse <=< mpvAll' $ MpvGetProperty "pause"
755 if
756 | and paused -> print <=< mpvAll' $ MpvSetProperty "pause" False
757 | otherwise -> print <=< mpvOne' $ MpvSetProperty "pause" True
758
759myKeys' conf host = Map.fromList $
760 -- launch a terminal
761 [ ((modm, xK_Return), spawn $ (XMonad.terminal conf) ++ " -e tmux")
762 , ((modm .|. shiftMask, xK_Return), spawn $ XMonad.terminal conf)
763
764 -- launch dmenu
765 --, ((modm, xK_d ), spawn "exe=`dmenu_path | dmenu` && eval \"exec $exe\"")
766 , ((modm, xK_d ), shellPrompt "Run: " xPConfig)
767 , ((modm .|. shiftMask, xK_d ), prompt "Run in Terminal: " ("urxvtc" ++ " -e") xPConfig)
768 , ((modm, xK_at ), sshPrompt sshOverrides xPConfig)
769
770 -- close focused window
771 , ((modm .|. shiftMask, xK_q ), kill)
772 , ((modm .|. controlMask .|. shiftMask, xK_q ), spawn "xkill")
773
774 -- Rotate through the available layout algorithms
775 , ((modm, xK_space ), sendMessage NextLayout)
776
777 -- Reset the layouts on the current workspace to default
778 , ((modm .|. controlMask, xK_r ), (setLayout $ XMonad.layoutHook conf) >> refresh)
779
780 -- Resize viewed windows to the correct size
781 , ((modm, xK_r ), refresh)
782
783 -- Move focus to the next window
784 , ((modm, xK_t ), windows W.focusDown)
785
786 -- Move focus to the previous window
787 , ((modm, xK_n ), windows W.focusUp )
788
789 -- Move focus to the master window
790 , ((modm, xK_m ), windows W.focusMaster )
791
792 -- Swap the focused window and the master window
793 , ((modm .|. shiftMask, xK_m ), windows W.swapMaster)
794
795 -- Swap the focused window with the next window
796 , ((modm .|. shiftMask, xK_t ), windows W.swapDown )
797
798 -- Swap the focused window with the previous window
799 , ((modm .|. shiftMask, xK_n ), windows W.swapUp )
800
801 -- Swap the focused window with the previous window
802 , ((modm .|. shiftMask .|. controlMask, xK_m), sendMessage SwapWindow)
803
804 , ((modm, xK_Right), sendMessage $ Go R)
805 , ((modm, xK_Left ), sendMessage $ Go L)
806 , ((modm, xK_Up ), sendMessage $ Go U)
807 , ((modm, xK_Down ), sendMessage $ Go D)
808 , ((modm .|. shiftMask , xK_Right), sendMessage $ Move R)
809 , ((modm .|. shiftMask , xK_Left ), sendMessage $ Move L)
810 , ((modm .|. shiftMask , xK_Up ), sendMessage $ Move U)
811 , ((modm .|. shiftMask , xK_Down ), sendMessage $ Move D)
812 -- , ((modm .|. controlMask, xK_Right), withFocused $ keysMoveWindow (10, 0))
813 -- , ((modm .|. controlMask, xK_Left ), withFocused $ keysMoveWindow (-10, 0))
814 -- , ((modm .|. controlMask, xK_Up ), withFocused $ keysMoveWindow (0, -10))
815 -- , ((modm .|. controlMask, xK_Down ), withFocused $ keysMoveWindow (0, 10))
816 -- Shrink the master area
817 , ((modm, xK_h ), sendMessage Shrink)
818
819 -- Expand the master area
820 , ((modm, xK_s ), sendMessage Expand)
821
822 -- Push window back into tiling
823 , ((modm .|. shiftMask, xK_space ), withFocused $ windows . W.sink)
824 , ((modm, xK_BackSpace), focusUrgent)
825 , ((modm .|. shiftMask, xK_BackSpace), clearUrgents)
826
827 -- Increment the number of windows in the master area
828 , ((modm , xK_comma ), sendMessage (IncMasterN 1))
829
830 -- Deincrement the number of windows in the master area
831 , ((modm , xK_period), sendMessage (IncMasterN (-1)))
832
833 , ((0, xF86XK_AudioRaiseVolume), safeSpawn "pulseaudio-ctl" ["up", "2"])
834 , ((0, xF86XK_AudioLowerVolume), safeSpawn "pulseaudio-ctl" ["down", "2"])
835 , ((0, xF86XK_AudioMute), safeSpawn "pulseaudio-ctl" ["mute"])
836 , ((0, xF86XK_AudioPause), mediaMpv $ MpvSetProperty "pause" False)
837 , ((0, {-xF86XK_AudioMicMute-} 269025202), safeSpawn "pulseaudio-ctl" ["mute-input"])
838 , ((0, xF86XK_AudioPlay), mediaMpvTogglePause)
839 , ((modm .|. mod1Mask, xK_space), mediaMpvTogglePause)
840
841 , ((0, xF86XK_MonBrightnessDown), backlight (subtract 5))
842 , ((0, xF86XK_MonBrightnessUp), backlight (+ 5))
843
844 , ((modm , xK_Escape), cycleKbLayout (hKbLayouts host))
845 , ((modm .|. controlMask, xK_Escape), safeSpawn "setxkbmap" $ fst (head $ hKbLayouts host) : maybeToList (snd . head $ hKbLayouts host))
846
847 -- Toggle the status bar gap
848 -- Use this binding with avoidStruts from Hooks.ManageDocks.
849 -- See also the statusBar function from Hooks.DynamicLog.
850 --
851 , ((modm , xK_b ), sendMessage ToggleStruts)
852
853 , ((modm .|. shiftMask, xK_p ), safeSpawn "playerctl" ["-a", "pause"])
854
855 -- Quit xmonad
856 , ((modm .|. shiftMask, xK_e ), io (exitWith ExitSuccess))
857
858 -- Restart xmonad
859 -- , ((modm .|. shiftMask .|. controlMask, xK_r ), void . xfork $ recompile False >>= flip when (safeSpawn "xmonad" ["--restart"]))
860 , ((modm .|. shiftMask, xK_r ), void . liftIO $ executeFile "xmonad" True [] Nothing)
861 , ((modm .|. shiftMask, xK_l ), void . xfork $ do
862 sessId <- getEnv "XDG_SESSION_ID"
863 safeSpawn "loginctl" ["lock-session", sessId]
864 )
865 , ((modm .|. shiftMask, xK_s ), safeSpawn "systemctl" ["suspend"])
866 , ((modm .|. shiftMask, xK_h ), safeSpawn "systemctl" ["hibernate"])
867 , ((modm .|. shiftMask, xK_b ), backlight $ cycleThrough [1, 3 % 4, 1 % 2, 1 % 4, 1 % 10, 1 % 100, 0]
868 )
869 , ((modm .|. shiftMask .|. controlMask, xK_b), backlight $ cycleThrough [0, 1 % 100, 1 % 10, 1 % 4, 1 % 2, 3 % 4, 1]
870 )
871 , ((modm, xK_v ), windows copyToAll) -- @@ Make focused window always visible
872 , ((modm .|. shiftMask, xK_v ), killAllOtherCopies) -- @@ Toggle window state back
873 , ((modm .|. shiftMask, xK_g ), windowPrompt xPConfig Goto wsWindows)
874 , ((modm .|. shiftMask .|. controlMask, xK_g ), windowPrompt xPConfig Bring allWindows)
875 ]
876 ++
877
878 --
879 -- mod-[1..9], Switch to workspace N
880 --
881 -- mod-[1..9], Switch to workspace N
882 -- mod-shift-[1..9], Move client to workspace N
883 --
884 [((m .|. modm, k), windows $ f i)
885 | (i, k) <- zip (XMonad.workspaces conf) $ numKeys
886 , (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)]
887 ]
888 ++
889 [((m .|. modm .|. controlMask, k), void . runMaybeT $
890 MaybeT (P.getScreen def i) >>= MaybeT . screenWorkspace >>= lift . windows . f
891 )
892 | (i, k) <- zip (hScreens host) [xK_g, xK_c, xK_r, xK_l]
893 , (f, m) <- [(W.view, 0), (W.shift, shiftMask)]
894 ]
895 where
896 modm = XMonad.modMask conf
897
898
diff --git a/accounts/gkleen@sif/xresources.nix b/accounts/gkleen@sif/xresources.nix
new file mode 100644
index 00000000..3bd9af2c
--- /dev/null
+++ b/accounts/gkleen@sif/xresources.nix
@@ -0,0 +1,46 @@
1{
2 "Xft.dpi" = 282;
3 "Xft.autohint" = false;
4 "Xft.lcdfilter" = "lcddefault";
5 "Xft.hintstyle" = "hintfull";
6 "Xft.hinting" = true;
7 "Xft.antialias" = true;
8 "Xft.rgba" = "rgb";
9
10 # special
11 "*.foreground" = "#d9d9d9";
12 "*.background" = "#000000";
13 "*.cursorColor" = "#d9d9d9";
14
15 # black
16 "*.color0" = "#000000";
17 "*.color8" = "#757a80";
18
19 # red
20 "*.color1" = "#bf4949";
21 "*.color9" = "#e66e6e";
22
23 # green
24 "*.color2" = "#9fb346";
25 "*.color10" = "#cbd676";
26
27 # yellow
28 "*.color3" = "#e69650";
29 "*.color11" = "#ffa74f";
30
31 # blue
32 "*.color4" = "#759fbf";
33 "*.color12" = "#98b8d9";
34
35 # magenta
36 "*.color5" = "#9b79a6";
37 "*.color13" = "#ceadd9";
38
39 # cyan
40 "*.color6" = "#79a69b";
41 "*.color14" = "#a3d9ce";
42
43 # white
44 "*.color7" = "#d9d9d9";
45 "*.color15" = "#ffffff";
46} \ No newline at end of file
diff --git a/overlays/nerdfonts.nix b/overlays/nerdfonts.nix
new file mode 100644
index 00000000..28581d72
--- /dev/null
+++ b/overlays/nerdfonts.nix
@@ -0,0 +1,5 @@
1final: prev: {
2 nerdfonts = prev.nerdfonts.override {
3 fonts = ["FiraMono" "FiraCode"];
4 };
5}
diff --git a/overlays/pidgin.nix b/overlays/pidgin.nix
new file mode 100644
index 00000000..09103ade
--- /dev/null
+++ b/overlays/pidgin.nix
@@ -0,0 +1,20 @@
1final: prev:
2prev.lib.composeManyExtensions [
3 (final: prev:
4 let
5 mucHistory = prev.fetchpatch {
6 url = "https://developer.pidgin.im/raw-attachment/ticket/16524/0001-only-request-unseed-chat-history-from-jabber-group-c.patch";
7 sha256 = "083wvmq7417xz55fxxhllqwql1hgjvin2sak08844121yw1jvc44";
8 };
9 in {
10 pidgin = prev.pidgin.overrideAttrs (oldAttrs: {
11 patches = (oldAttrs.patches or []) ++ [mucHistory];
12 });
13 })
14 (final: prev: {
15 pidgin-with-plugins = import (/. + prev.path + "/pkgs/applications/networking/instant-messengers/pidgin/wrapper.nix") {
16 inherit (prev) makeWrapper symlinkJoin pidgin;
17 plugins = with final; [ purple-lurch pidgin-carbons pidgin-opensteamworks pidgin-xmpp-receipts ];
18 };
19 })
20] final prev
diff --git a/overlays/urxvt/52-osc.pl b/overlays/urxvt/52-osc.pl
new file mode 100644
index 00000000..3292e8c4
--- /dev/null
+++ b/overlays/urxvt/52-osc.pl
@@ -0,0 +1,41 @@
1#! perl
2
3=head1 NAME
4
552-osc - Implement OSC 32 ; Interact with X11 clipboard
6
7=head1 SYNOPSIS
8
9 urxvt -pe 52-osc
10
11=head1 DESCRIPTION
12
13This extension implements OSC 52 for interacting with system clipboard
14
15Most code stolen from:
16http://ailin.tucana.uberspace.de/static/nei/*/Code/urxvt/
17
18=cut
19
20use MIME::Base64;
21use Encode;
22
23sub on_osc_seq {
24 my ($term, $op, $args) = @_;
25 return () unless $op eq 52;
26
27 my ($clip, $data) = split ';', $args, 2;
28 if ($data eq '?') {
29 # my $data_free = $term->selection();
30 # Encode::_utf8_off($data_free); # XXX
31 # $term->tt_write("\e]52;$clip;".encode_base64($data_free, '')."\a");
32 }
33 else {
34 my $data_decoded = decode_base64($data);
35 Encode::_utf8_on($data_decoded); # XXX
36 $term->selection($data_decoded, $clip =~ /c|^$/);
37 $term->selection_grab(urxvt::CurrentTime, $clip =~ /c|^$/);
38 }
39
40 ()
41}
diff --git a/overlays/urxvt/default.nix b/overlays/urxvt/default.nix
new file mode 100644
index 00000000..3c57d000
--- /dev/null
+++ b/overlays/urxvt/default.nix
@@ -0,0 +1,21 @@
1final: prev: {
2 rxvt_unicode-with-plugins = prev.rxvt-unicode.override {
3 configure = { availablePlugins, ... }: {
4 plugins = [ final.urxvt_osc_52 ] ++ builtins.attrValues availablePlugins;
5 };
6 };
7 urxvt_osc_52 = prev.stdenv.mkDerivation {
8 name = "rxvt_unicode-osc_52-0";
9 src = ./52-osc.pl;
10 unpackPhase = ''
11 cp $src 52-osc
12 '';
13 buildPhase = ''
14 sed -i 's|#! perl|#! ${final.perl}/bin/perl|g' 52-osc
15 '';
16 installPhase = ''
17 mkdir -p $out/lib/urxvt/perl
18 cp 52-osc $out/lib/urxvt/perl
19 '';
20 };
21}
diff --git a/user-profiles/mpv/default.nix b/user-profiles/mpv/default.nix
new file mode 100644
index 00000000..ae791668
--- /dev/null
+++ b/user-profiles/mpv/default.nix
@@ -0,0 +1,83 @@
1{ userName, pkgs, ... }:
2{
3 home-manager.users.${userName}.programs.mpv = {
4 enable = true;
5 bindings = {
6 "CTRL+n" = "af toggle \"lavfi=[dynaudnorm=f=100:g=31:s=20.0]\"";
7 };
8 config = {
9 ytdl = true;
10 ytdl-format = "bestvideo[width<=2560][height<=1440][fps<=60][protocol!=http_dash_segments]+bestaudio[protocol!=http_dash_segments]/best[width<=2560][height<=1440][fps<=60][protocol!=http_dash_segments]/best[protocol!=http_dash_segments]";
11 ytdl-raw-options = "netrc=,mark-watched=";
12 sub = false;
13 osd-font = "DejaVu Sans";
14 vo = "gpu";
15 hwdec = "auto";
16 force-window = "yes";
17 script-opts = "osc-layout=topbar,vidscale=no,deadzonesize=0.9";
18 af = "lavfi=[dynaudnorm=f=100:g=31:s=20.0]";
19 };
20 scripts = let
21 reload = pkgs.stdenv.mkDerivation rec {
22 version = "2b8a719f";
23 pname = "reload";
24 name = "${pname}-${version}";
25
26 src = pkgs.fetchFromGitHub {
27 owner = "4e6";
28 repo = "mpv-reload";
29 rev = "2b8a719fe166d6d42b5f1dd64761f97997b54a86";
30 sha256 = "19ycvnwzf8vgv0g63d4k1ll6hlfrd92is9gl8hzfic7w32ycphbg";
31 };
32
33 installPhase = ''
34 install -d $out/share/mpv/scripts
35 install -m 0644 reload.lua $out/share/mpv/scripts/${passthru.scriptName}
36 '';
37
38 passthru.scriptName = "reload.lua";
39 };
40 autosave = pkgs.stdenv.mkDerivation rec {
41 version = "0bv9wjrq";
42 pname = "autosave";
43 name = "${pname}-${version}.lua";
44
45 src = pkgs.fetchzip {
46 url = "https://gist.github.com/Hakkin/5489e511bd6c8068a0fc09304c9c5a82/archive/7a19f7cdb6dd0b1c6878b41e13b244e2503c15fc.zip";
47 sha256 = "0bv9wjrqm2ragd7rp8vw768bja2ghascwlljd6rzzf2ybi10fxs2";
48 };
49
50 installPhase = ''
51 install -d $out/share/mpv/scripts
52 install -m 0644 autosave.lua $out/share/mpv/scripts/${passthru.scriptName}
53 '';
54
55 passthru.scriptName = "autosave.lua";
56 };
57 mpris = pkgs.stdenv.mkDerivation rec {
58 version = "0.4";
59 pname = "mpv-mpris";
60 name = "${pname}-${version}.so";
61
62 src = pkgs.fetchFromGitHub {
63 owner = "hoyon";
64 repo = "mpv-mpris";
65 rev = version;
66 sha256 = "1fr3jvja8s2gdpx8qyk9r17977flms3qpm8zci62nd9r5wjdvr5i";
67 };
68
69 installPhase = ''
70 install -d $out/share/mpv/scripts
71 install -m 0644 mpris.so $out/share/mpv/scripts/${passthru.scriptName}
72 '';
73
74 nativeBuildInputs = with pkgs; [ pkgconfig glib mpv ];
75
76 passthru.scriptName = "mpris.so";
77 };
78 in [ reload
79 autosave
80 mpris
81 ];
82 };
83}
diff --git a/user-profiles/tmux/default.nix b/user-profiles/tmux/default.nix
new file mode 100644
index 00000000..9e66cadd
--- /dev/null
+++ b/user-profiles/tmux/default.nix
@@ -0,0 +1,26 @@
1{ userName, pkgs, lib, ... }:
2{
3 home-manager.users.${userName} = {
4 programs.tmux = {
5 enable = true;
6 clock24 = true;
7 historyLimit = 50000;
8 extraConfig = lib.readFile (pkgs.stdenv.mkDerivation {
9 name = "tmux.conf";
10 src = ./tmux.conf;
11
12 buildInputs = with pkgs; [ makeWrapper ];
13
14 phases = [ "installPhase" ];
15
16 inherit (pkgs) zsh;
17 mandb = pkgs.man-db;
18
19 installPhase = ''
20 substituteAll $src $out
21 '';
22 });
23 tmuxp.enable = true;
24 };
25 };
26}
diff --git a/user-profiles/tmux/tmux.conf b/user-profiles/tmux/tmux.conf
new file mode 100644
index 00000000..1403698d
--- /dev/null
+++ b/user-profiles/tmux/tmux.conf
@@ -0,0 +1,25 @@
1set-option -g history-limit 50000
2set-option -g status-bg black
3set-option -g status-fg white
4set-option -g clock-mode-colour white
5set-option -g clock-mode-style 24
6set-option -g bell-action any
7set-option -g default-shell @zsh@/bin/zsh
8set-option -g update-environment 'DISPLAY SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID SSH_CONNECTION WINDOWID XAUTHORITY PROMPT_INFO PATH PGHOST PGLOG'
9set-option -g mouse on
10set-option -g set-clipboard on
11set-option -g terminal-overrides 'rxvt-uni*:XT:Ms=\E]52;%p1%s;%p2%s\007'
12
13## determine if we should enable 256-colour support
14if "[[ ''${TERM} =~ 256color || ''${TERM} == fbterm ]]" 'set -g default-terminal tmux-256color'
15
16set-option -g status-right ""
17
18bind / command-prompt "split-window -h 'exec @mandb@/bin/man %%'"
19bind C clock-mode
20bind r respawn-pane -k
21
22bind -n M-Left select-pane -L
23bind -n M-Right select-pane -R
24bind -n M-Up select-pane -U
25bind -n M-Down select-pane -D \ No newline at end of file
diff --git a/user-profiles/utils.nix b/user-profiles/utils.nix
new file mode 100644
index 00000000..1de9e4eb
--- /dev/null
+++ b/user-profiles/utils.nix
@@ -0,0 +1,22 @@
1{ userName, pkgs, ... }:
2{
3 home-manager.users.${userName} = {
4 programs = {
5 htop = {
6 enable = true;
7 delay = 5;
8 highlightBaseName = true;
9 treeView = true;
10 };
11
12 jq.enable = true;
13 };
14
15 home.packages = with pkgs; [
16 autossh usbutils pciutils exa ag pwgen unzip magic-wormhole
17 qrencode tty-clock dnsutils openssl sshfs psmisc mosh tree
18 vnstat file pv bc fast-cli zip nmap aspell aspellDicts.de
19 aspellDicts.en borgbackup man-pages rsync socat telnet yq
20 ];
21 };
22}
diff --git a/user-profiles/zsh/default.nix b/user-profiles/zsh/default.nix
new file mode 100644
index 00000000..58fa0376
--- /dev/null
+++ b/user-profiles/zsh/default.nix
@@ -0,0 +1,30 @@
1{ userName, pkgs, customUtils, lib, config, ... }:
2let
3 dotDir = ".config/zsh";
4 p10kZsh = "${dotDir}/.p10k.zsh";
5 cfg = config.home-manager.users.${userName};
6in {
7 home-manager.users.${userName} = {
8 programs.zsh = {
9 inherit dotDir;
10 enable = true;
11 autocd = true;
12 enableCompletion = true;
13
14 plugins = [
15 { name = "powerlevel10k";
16 file = "share/zsh-powerlevel10k/powerlevel10k.zsh-theme";
17 src = pkgs.zsh-powerlevel10k;
18 }
19 ];
20 initExtraBeforeCompInit = ''
21 source "${cfg.home.homeDirectory}/${p10kZsh}"
22 '';
23 initExtra = lib.mkAfter ''
24 source "${pkgs.zsh-syntax-highlighting}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
25 '';
26 };
27
28 home.file.${p10kZsh}.source = ./p10k.zsh;
29 };
30}
diff --git a/user-profiles/zsh/p10k.zsh b/user-profiles/zsh/p10k.zsh
new file mode 100644
index 00000000..517b6a9b
--- /dev/null
+++ b/user-profiles/zsh/p10k.zsh
@@ -0,0 +1,1548 @@
1# Generated by Powerlevel10k configuration wizard on 2020-10-15 at 12:01 UTC.
2# Based on romkatv/powerlevel10k/config/p10k-lean.zsh.
3# Wizard options: nerdfont-complete + powerline, small icons, unicode, lean, 24h time,
4# 2 lines, solid, no frame, dark-ornaments, sparse, many icons, concise,
5# transient_prompt, instant_prompt=off.
6# Type `p10k configure` to generate another config.
7#
8# Config for Powerlevel10k with lean prompt style. Type `p10k configure` to generate
9# your own config based on it.
10#
11# Tip: Looking for a nice color? Here's a one-liner to print colormap.
12#
13# for i in {0..255}; do print -Pn "%K{$i} %k%F{$i}${(l:3::0:)i}%f " ${${(M)$((i%6)):#3}:+$'\n'}; done
14
15# Temporarily change options.
16'builtin' 'local' '-a' 'p10k_config_opts'
17[[ ! -o 'aliases' ]] || p10k_config_opts+=('aliases')
18[[ ! -o 'sh_glob' ]] || p10k_config_opts+=('sh_glob')
19[[ ! -o 'no_brace_expand' ]] || p10k_config_opts+=('no_brace_expand')
20'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand'
21
22() {
23 emulate -L zsh -o extended_glob
24
25 # Unset all configuration options. This allows you to apply configuration changes without
26 # restarting zsh. Edit ~/.p10k.zsh and type `source ~/.p10k.zsh`.
27 unset -m '(POWERLEVEL9K_*|DEFAULT_USER)~POWERLEVEL9K_GITSTATUS_DIR'
28
29 # Zsh >= 5.1 is required.
30 autoload -Uz is-at-least && is-at-least 5.1 || return
31
32 # The list of segments shown on the left. Fill it with the most important segments.
33 typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(
34 # =========================[ Line #1 ]=========================
35 os_icon # os identifier
36 dir # current directory
37 vcs # git status
38 # =========================[ Line #2 ]=========================
39 newline # \n
40 prompt_char # prompt symbol
41 )
42
43 # The list of segments shown on the right. Fill it with less important segments.
44 # Right prompt on the last prompt line (where you are typing your commands) gets
45 # automatically hidden when the input line reaches it. Right prompt above the
46 # last prompt line gets hidden if it would overlap with left prompt.
47 typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(
48 # =========================[ Line #1 ]=========================
49 status # exit code of the last command
50 command_execution_time # duration of the last command
51 background_jobs # presence of background jobs
52 direnv # direnv status (https://direnv.net/)
53 asdf # asdf version manager (https://github.com/asdf-vm/asdf)
54 virtualenv # python virtual environment (https://docs.python.org/3/library/venv.html)
55 anaconda # conda environment (https://conda.io/)
56 pyenv # python environment (https://github.com/pyenv/pyenv)
57 goenv # go environment (https://github.com/syndbg/goenv)
58 nodenv # node.js version from nodenv (https://github.com/nodenv/nodenv)
59 nvm # node.js version from nvm (https://github.com/nvm-sh/nvm)
60 nodeenv # node.js environment (https://github.com/ekalinin/nodeenv)
61 # node_version # node.js version
62 # go_version # go version (https://golang.org)
63 # rust_version # rustc version (https://www.rust-lang.org)
64 # dotnet_version # .NET version (https://dotnet.microsoft.com)
65 # php_version # php version (https://www.php.net/)
66 # laravel_version # laravel php framework version (https://laravel.com/)
67 # java_version # java version (https://www.java.com/)
68 # package # name@version from package.json (https://docs.npmjs.com/files/package.json)
69 rbenv # ruby version from rbenv (https://github.com/rbenv/rbenv)
70 rvm # ruby version from rvm (https://rvm.io)
71 fvm # flutter version management (https://github.com/leoafarias/fvm)
72 luaenv # lua version from luaenv (https://github.com/cehoffman/luaenv)
73 jenv # java version from jenv (https://github.com/jenv/jenv)
74 plenv # perl version from plenv (https://github.com/tokuhirom/plenv)
75 phpenv # php version from phpenv (https://github.com/phpenv/phpenv)
76 haskell_stack # haskell version from stack (https://haskellstack.org/)
77 kubecontext # current kubernetes context (https://kubernetes.io/)
78 terraform # terraform workspace (https://www.terraform.io)
79 aws # aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html)
80 aws_eb_env # aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/)
81 azure # azure account name (https://docs.microsoft.com/en-us/cli/azure)
82 gcloud # google cloud cli account and project (https://cloud.google.com/)
83 google_app_cred # google application credentials (https://cloud.google.com/docs/authentication/production)
84 context # user@hostname
85 nordvpn # nordvpn connection status, linux only (https://nordvpn.com/)
86 ranger # ranger shell (https://github.com/ranger/ranger)
87 nnn # nnn shell (https://github.com/jarun/nnn)
88 vim_shell # vim shell indicator (:sh)
89 midnight_commander # midnight commander shell (https://midnight-commander.org/)
90 nix_shell # nix shell (https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html)
91 # vpn_ip # virtual private network indicator
92 # load # CPU load
93 # disk_usage # disk usage
94 # ram # free RAM
95 # swap # used swap
96 todo # todo items (https://github.com/todotxt/todo.txt-cli)
97 timewarrior # timewarrior tracking status (https://timewarrior.net/)
98 taskwarrior # taskwarrior task count (https://taskwarrior.org/)
99 time # current time
100 # =========================[ Line #2 ]=========================
101 newline
102 # ip # ip address and bandwidth usage for a specified network interface
103 # public_ip # public IP address
104 # proxy # system-wide http/https/ftp proxy
105 # battery # internal battery
106 # wifi # wifi speed
107 # example # example user-defined segment (see prompt_example function below)
108 )
109
110 # Defines character set used by powerlevel10k. It's best to let `p10k configure` set it for you.
111 typeset -g POWERLEVEL9K_MODE=nerdfont-complete
112 # When set to `moderate`, some icons will have an extra space after them. This is meant to avoid
113 # icon overlap when using non-monospace fonts. When set to `none`, spaces are not added.
114 typeset -g POWERLEVEL9K_ICON_PADDING=none
115
116 # Basic style options that define the overall look of your prompt. You probably don't want to
117 # change them.
118 typeset -g POWERLEVEL9K_BACKGROUND= # transparent background
119 typeset -g POWERLEVEL9K_{LEFT,RIGHT}_{LEFT,RIGHT}_WHITESPACE= # no surrounding whitespace
120 typeset -g POWERLEVEL9K_{LEFT,RIGHT}_SUBSEGMENT_SEPARATOR=' ' # separate segments with a space
121 typeset -g POWERLEVEL9K_{LEFT,RIGHT}_SEGMENT_SEPARATOR= # no end-of-line symbol
122
123 # When set to true, icons appear before content on both sides of the prompt. When set
124 # to false, icons go after content. If empty or not set, icons go before content in the left
125 # prompt and after content in the right prompt.
126 #
127 # You can also override it for a specific segment:
128 #
129 # POWERLEVEL9K_STATUS_ICON_BEFORE_CONTENT=false
130 #
131 # Or for a specific segment in specific state:
132 #
133 # POWERLEVEL9K_DIR_NOT_WRITABLE_ICON_BEFORE_CONTENT=false
134 typeset -g POWERLEVEL9K_ICON_BEFORE_CONTENT=true
135
136 # Add an empty line before each prompt.
137 typeset -g POWERLEVEL9K_PROMPT_ADD_NEWLINE=true
138
139 # Connect left prompt lines with these symbols.
140 typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX=
141 typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_PREFIX=
142 typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX=
143 # Connect right prompt lines with these symbols.
144 typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_SUFFIX=
145 typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_SUFFIX=
146 typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_SUFFIX=
147
148 # The left end of left prompt.
149 typeset -g POWERLEVEL9K_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL=
150 # The right end of right prompt.
151 typeset -g POWERLEVEL9K_RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL=
152
153 # Ruler, a.k.a. the horizontal line before each prompt. If you set it to true, you'll
154 # probably want to set POWERLEVEL9K_PROMPT_ADD_NEWLINE=false above and
155 # POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR=' ' below.
156 typeset -g POWERLEVEL9K_SHOW_RULER=false
157 typeset -g POWERLEVEL9K_RULER_CHAR='─' # reasonable alternative: '·'
158 typeset -g POWERLEVEL9K_RULER_FOREGROUND=240
159
160 # Filler between left and right prompt on the first prompt line. You can set it to '·' or '─'
161 # to make it easier to see the alignment between left and right prompt and to separate prompt
162 # from command output. It serves the same purpose as ruler (see above) without increasing
163 # the number of prompt lines. You'll probably want to set POWERLEVEL9K_SHOW_RULER=false
164 # if using this. You might also like POWERLEVEL9K_PROMPT_ADD_NEWLINE=false for more compact
165 # prompt.
166 typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR='─'
167 if [[ $POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR != ' ' ]]; then
168 # The color of the filler.
169 typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_FOREGROUND=240
170 # Add a space between the end of left prompt and the filler.
171 typeset -g POWERLEVEL9K_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL=' '
172 # Add a space between the filler and the start of right prompt.
173 typeset -g POWERLEVEL9K_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL=' '
174 # Start filler from the edge of the screen if there are no left segments on the first line.
175 typeset -g POWERLEVEL9K_EMPTY_LINE_LEFT_PROMPT_FIRST_SEGMENT_END_SYMBOL='%{%}'
176 # End filler on the edge of the screen if there are no right segments on the first line.
177 typeset -g POWERLEVEL9K_EMPTY_LINE_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL='%{%}'
178 fi
179
180 #################################[ os_icon: os identifier ]##################################
181 # OS identifier color.
182 typeset -g POWERLEVEL9K_OS_ICON_FOREGROUND=
183 # Make the icon bold.
184 typeset -g POWERLEVEL9K_OS_ICON_CONTENT_EXPANSION='${P9K_CONTENT}'
185
186 ################################[ prompt_char: prompt symbol ]################################
187 # Green prompt symbol if the last command succeeded.
188 typeset -g POWERLEVEL9K_PROMPT_CHAR_OK_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=76
189 # Red prompt symbol if the last command failed.
190 typeset -g POWERLEVEL9K_PROMPT_CHAR_ERROR_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=196
191 # Default prompt symbol.
192 typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIINS_CONTENT_EXPANSION='❯'
193 # Prompt symbol in command vi mode.
194 typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VICMD_CONTENT_EXPANSION='❮'
195 # Prompt symbol in visual vi mode.
196 typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIVIS_CONTENT_EXPANSION='V'
197 # Prompt symbol in overwrite vi mode.
198 typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIOWR_CONTENT_EXPANSION='▶'
199 typeset -g POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE=true
200 # No line terminator if prompt_char is the last segment.
201 typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL=''
202 # No line introducer if prompt_char is the first segment.
203 typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL=
204
205 ##################################[ dir: current directory ]##################################
206 # Default current directory color.
207 typeset -g POWERLEVEL9K_DIR_FOREGROUND=31
208 # If directory is too long, shorten some of its segments to the shortest possible unique
209 # prefix. The shortened directory can be tab-completed to the original.
210 typeset -g POWERLEVEL9K_SHORTEN_STRATEGY=truncate_to_unique
211 # Replace removed segment suffixes with this symbol.
212 typeset -g POWERLEVEL9K_SHORTEN_DELIMITER=
213 # Color of the shortened directory segments.
214 typeset -g POWERLEVEL9K_DIR_SHORTENED_FOREGROUND=103
215 # Color of the anchor directory segments. Anchor segments are never shortened. The first
216 # segment is always an anchor.
217 typeset -g POWERLEVEL9K_DIR_ANCHOR_FOREGROUND=39
218 # Display anchor directory segments in bold.
219 typeset -g POWERLEVEL9K_DIR_ANCHOR_BOLD=true
220 # Don't shorten directories that contain any of these files. They are anchors.
221 local anchor_files=(
222 .bzr
223 .citc
224 .git
225 .hg
226 .node-version
227 .python-version
228 .go-version
229 .ruby-version
230 .lua-version
231 .java-version
232 .perl-version
233 .php-version
234 .tool-version
235 .shorten_folder_marker
236 .svn
237 .terraform
238 CVS
239 Cargo.toml
240 composer.json
241 go.mod
242 package.json
243 stack.yaml
244 )
245 typeset -g POWERLEVEL9K_SHORTEN_FOLDER_MARKER="(${(j:|:)anchor_files})"
246 # If set to "first" ("last"), remove everything before the first (last) subdirectory that contains
247 # files matching $POWERLEVEL9K_SHORTEN_FOLDER_MARKER. For example, when the current directory is
248 # /foo/bar/git_repo/nested_git_repo/baz, prompt will display git_repo/nested_git_repo/baz (first)
249 # or nested_git_repo/baz (last). This assumes that git_repo and nested_git_repo contain markers
250 # and other directories don't.
251 typeset -g POWERLEVEL9K_DIR_TRUNCATE_BEFORE_MARKER=false
252 # Don't shorten this many last directory segments. They are anchors.
253 typeset -g POWERLEVEL9K_SHORTEN_DIR_LENGTH=1
254 # Shorten directory if it's longer than this even if there is space for it. The value can
255 # be either absolute (e.g., '80') or a percentage of terminal width (e.g, '50%'). If empty,
256 # directory will be shortened only when prompt doesn't fit or when other parameters demand it
257 # (see POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS and POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT below).
258 # If set to `0`, directory will always be shortened to its minimum length.
259 typeset -g POWERLEVEL9K_DIR_MAX_LENGTH=80
260 # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least this
261 # many columns for typing commands.
262 typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS=40
263 # When `dir` segment is on the last prompt line, try to shorten it enough to leave at least
264 # COLUMNS * POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT * 0.01 columns for typing commands.
265 typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT=50
266 # If set to true, embed a hyperlink into the directory. Useful for quickly
267 # opening a directory in the file manager simply by clicking the link.
268 # Can also be handy when the directory is shortened, as it allows you to see
269 # the full directory that was used in previous commands.
270 typeset -g POWERLEVEL9K_DIR_HYPERLINK=false
271
272 # Enable special styling for non-writable directories. See POWERLEVEL9K_LOCK_ICON and
273 # POWERLEVEL9K_DIR_CLASSES below.
274 typeset -g POWERLEVEL9K_DIR_SHOW_WRITABLE=v2
275
276 # The default icon shown next to non-writable directories when POWERLEVEL9K_DIR_SHOW_WRITABLE is
277 # set to v2.
278 # typeset -g POWERLEVEL9K_LOCK_ICON='⭐'
279
280 # POWERLEVEL9K_DIR_CLASSES allows you to specify custom icons and colors for different
281 # directories. It must be an array with 3 * N elements. Each triplet consists of:
282 #
283 # 1. A pattern against which the current directory ($PWD) is matched. Matching is done with
284 # extended_glob option enabled.
285 # 2. Directory class for the purpose of styling.
286 # 3. An empty string.
287 #
288 # Triplets are tried in order. The first triplet whose pattern matches $PWD wins.
289 #
290 # If POWERLEVEL9K_DIR_SHOW_WRITABLE is set to v2 and the current directory is not writable,
291 # its class gets suffix _NOT_WRITABLE.
292 #
293 # For example, given these settings:
294 #
295 # typeset -g POWERLEVEL9K_DIR_CLASSES=(
296 # '~/work(|/*)' WORK ''
297 # '~(|/*)' HOME ''
298 # '*' DEFAULT '')
299 #
300 # Whenever the current directory is ~/work or a subdirectory of ~/work, it gets styled with class
301 # WORK or WORK_NOT_WRITABLE.
302 #
303 # Simply assigning classes to directories don't have any visible effects. It merely gives you an
304 # option to define custom colors and icons for different directory classes.
305 #
306 # # Styling for WORK.
307 # typeset -g POWERLEVEL9K_DIR_WORK_VISUAL_IDENTIFIER_EXPANSION='⭐'
308 # typeset -g POWERLEVEL9K_DIR_WORK_FOREGROUND=31
309 # typeset -g POWERLEVEL9K_DIR_WORK_SHORTENED_FOREGROUND=103
310 # typeset -g POWERLEVEL9K_DIR_WORK_ANCHOR_FOREGROUND=39
311 #
312 # # Styling for WORK_NOT_WRITABLE.
313 # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_VISUAL_IDENTIFIER_EXPANSION='⭐'
314 # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_FOREGROUND=31
315 # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_SHORTENED_FOREGROUND=103
316 # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_ANCHOR_FOREGROUND=39
317 #
318 # If a styling parameter isn't explicitly defined for some class, it falls back to the classless
319 # parameter. For example, if POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_FOREGROUND is not set, it falls
320 # back to POWERLEVEL9K_DIR_FOREGROUND.
321 #
322 # typeset -g POWERLEVEL9K_DIR_CLASSES=()
323
324 # Custom prefix.
325 # typeset -g POWERLEVEL9K_DIR_PREFIX='%fin '
326
327 #####################################[ vcs: git status ]######################################
328 # Branch icon. Set this parameter to '\uF126 ' for the popular Powerline branch icon.
329 typeset -g POWERLEVEL9K_VCS_BRANCH_ICON='\uF126 '
330
331 # Untracked files icon. It's really a question mark, your font isn't broken.
332 # Change the value of this parameter to show a different icon.
333 typeset -g POWERLEVEL9K_VCS_UNTRACKED_ICON='?'
334
335 # Formatter for Git status.
336 #
337 # Example output: master ⇣42⇡42 *42 merge ~42 +42 !42 ?42.
338 #
339 # You can edit the function to customize how Git status looks.
340 #
341 # VCS_STATUS_* parameters are set by gitstatus plugin. See reference:
342 # https://github.com/romkatv/gitstatus/blob/master/gitstatus.plugin.zsh.
343 function my_git_formatter() {
344 emulate -L zsh
345
346 if [[ -n $P9K_CONTENT ]]; then
347 # If P9K_CONTENT is not empty, use it. It's either "loading" or from vcs_info (not from
348 # gitstatus plugin). VCS_STATUS_* parameters are not available in this case.
349 typeset -g my_git_format=$P9K_CONTENT
350 return
351 fi
352
353 if (( $1 )); then
354 # Styling for up-to-date Git status.
355 local meta='%f' # default foreground
356 local clean='%76F' # green foreground
357 local modified='%178F' # yellow foreground
358 local untracked='%39F' # blue foreground
359 local conflicted='%196F' # red foreground
360 else
361 # Styling for incomplete and stale Git status.
362 local meta='%244F' # grey foreground
363 local clean='%244F' # grey foreground
364 local modified='%244F' # grey foreground
365 local untracked='%244F' # grey foreground
366 local conflicted='%244F' # grey foreground
367 fi
368
369 local res
370 local where # branch or tag
371 if [[ -n $VCS_STATUS_LOCAL_BRANCH ]]; then
372 res+="${clean}${(g::)POWERLEVEL9K_VCS_BRANCH_ICON}"
373 where=${(V)VCS_STATUS_LOCAL_BRANCH}
374 elif [[ -n $VCS_STATUS_TAG ]]; then
375 res+="${meta}#"
376 where=${(V)VCS_STATUS_TAG}
377 fi
378
379 # If local branch name or tag is at most 32 characters long, show it in full.
380 # Otherwise show the first 12 … the last 12.
381 # Tip: To always show local branch name in full without truncation, delete the next line.
382 (( $#where > 32 )) && where[13,-13]="…"
383 res+="${clean}${where//\%/%%}" # escape %
384
385 # Display the current Git commit if there is no branch or tag.
386 # Tip: To always display the current Git commit, remove `[[ -z $where ]] &&` from the next line.
387 [[ -z $where ]] && res+="${meta}@${clean}${VCS_STATUS_COMMIT[1,8]}"
388
389 # Show tracking branch name if it differs from local branch.
390 if [[ -n ${VCS_STATUS_REMOTE_BRANCH:#$VCS_STATUS_LOCAL_BRANCH} ]]; then
391 res+="${meta}:${clean}${(V)VCS_STATUS_REMOTE_BRANCH//\%/%%}" # escape %
392 fi
393
394 # ⇣42 if behind the remote.
395 (( VCS_STATUS_COMMITS_BEHIND )) && res+=" ${clean}⇣${VCS_STATUS_COMMITS_BEHIND}"
396 # ⇡42 if ahead of the remote; no leading space if also behind the remote: ⇣42⇡42.
397 (( VCS_STATUS_COMMITS_AHEAD && !VCS_STATUS_COMMITS_BEHIND )) && res+=" "
398 (( VCS_STATUS_COMMITS_AHEAD )) && res+="${clean}⇡${VCS_STATUS_COMMITS_AHEAD}"
399 # ⇠42 if behind the push remote.
400 (( VCS_STATUS_PUSH_COMMITS_BEHIND )) && res+=" ${clean}⇠${VCS_STATUS_PUSH_COMMITS_BEHIND}"
401 (( VCS_STATUS_PUSH_COMMITS_AHEAD && !VCS_STATUS_PUSH_COMMITS_BEHIND )) && res+=" "
402 # ⇢42 if ahead of the push remote; no leading space if also behind: ⇠42⇢42.
403 (( VCS_STATUS_PUSH_COMMITS_AHEAD )) && res+="${clean}⇢${VCS_STATUS_PUSH_COMMITS_AHEAD}"
404 # *42 if have stashes.
405 (( VCS_STATUS_STASHES )) && res+=" ${clean}*${VCS_STATUS_STASHES}"
406 # 'merge' if the repo is in an unusual state.
407 [[ -n $VCS_STATUS_ACTION ]] && res+=" ${conflicted}${VCS_STATUS_ACTION}"
408 # ~42 if have merge conflicts.
409 (( VCS_STATUS_NUM_CONFLICTED )) && res+=" ${conflicted}~${VCS_STATUS_NUM_CONFLICTED}"
410 # +42 if have staged changes.
411 (( VCS_STATUS_NUM_STAGED )) && res+=" ${modified}+${VCS_STATUS_NUM_STAGED}"
412 # !42 if have unstaged changes.
413 (( VCS_STATUS_NUM_UNSTAGED )) && res+=" ${modified}!${VCS_STATUS_NUM_UNSTAGED}"
414 # ?42 if have untracked files. It's really a question mark, your font isn't broken.
415 # See POWERLEVEL9K_VCS_UNTRACKED_ICON above if you want to use a different icon.
416 # Remove the next line if you don't want to see untracked files at all.
417 (( VCS_STATUS_NUM_UNTRACKED )) && res+=" ${untracked}${(g::)POWERLEVEL9K_VCS_UNTRACKED_ICON}${VCS_STATUS_NUM_UNTRACKED}"
418 # "─" if the number of unstaged files is unknown. This can happen due to
419 # POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY (see below) being set to a non-negative number lower
420 # than the number of files in the Git index, or due to bash.showDirtyState being set to false
421 # in the repository config. The number of staged and untracked files may also be unknown
422 # in this case.
423 (( VCS_STATUS_HAS_UNSTAGED == -1 )) && res+=" ${modified}─"
424
425 typeset -g my_git_format=$res
426 }
427 functions -M my_git_formatter 2>/dev/null
428
429 # Don't count the number of unstaged, untracked and conflicted files in Git repositories with
430 # more than this many files in the index. Negative value means infinity.
431 #
432 # If you are working in Git repositories with tens of millions of files and seeing performance
433 # sagging, try setting POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY to a number lower than the output
434 # of `git ls-files | wc -l`. Alternatively, add `bash.showDirtyState = false` to the repository's
435 # config: `git config bash.showDirtyState false`.
436 typeset -g POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY=-1
437
438 # Don't show Git status in prompt for repositories whose workdir matches this pattern.
439 # For example, if set to '~', the Git repository at $HOME/.git will be ignored.
440 # Multiple patterns can be combined with '|': '~(|/foo)|/bar/baz/*'.
441 typeset -g POWERLEVEL9K_VCS_DISABLED_WORKDIR_PATTERN='~'
442
443 # Disable the default Git status formatting.
444 typeset -g POWERLEVEL9K_VCS_DISABLE_GITSTATUS_FORMATTING=true
445 # Install our own Git status formatter.
446 typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION='${$((my_git_formatter(1)))+${my_git_format}}'
447 typeset -g POWERLEVEL9K_VCS_LOADING_CONTENT_EXPANSION='${$((my_git_formatter(0)))+${my_git_format}}'
448 # Enable counters for staged, unstaged, etc.
449 typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED,CONFLICTED,COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=-1
450
451 # Icon color.
452 typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_COLOR=76
453 typeset -g POWERLEVEL9K_VCS_LOADING_VISUAL_IDENTIFIER_COLOR=244
454 # Custom icon.
455 # typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_EXPANSION='⭐'
456 # Custom prefix.
457 # typeset -g POWERLEVEL9K_VCS_PREFIX='%fon '
458
459 # Show status of repositories of these types. You can add svn and/or hg if you are
460 # using them. If you do, your prompt may become slow even when your current directory
461 # isn't in an svn or hg reposotiry.
462 typeset -g POWERLEVEL9K_VCS_BACKENDS=(git)
463
464 # These settings are used for repositories other than Git or when gitstatusd fails and
465 # Powerlevel10k has to fall back to using vcs_info.
466 typeset -g POWERLEVEL9K_VCS_CLEAN_FOREGROUND=76
467 typeset -g POWERLEVEL9K_VCS_UNTRACKED_FOREGROUND=76
468 typeset -g POWERLEVEL9K_VCS_MODIFIED_FOREGROUND=178
469
470 ##########################[ status: exit code of the last command ]###########################
471 # Enable OK_PIPE, ERROR_PIPE and ERROR_SIGNAL status states to allow us to enable, disable and
472 # style them independently from the regular OK and ERROR state.
473 typeset -g POWERLEVEL9K_STATUS_EXTENDED_STATES=true
474
475 # Status on success. No content, just an icon. No need to show it if prompt_char is enabled as
476 # it will signify success by turning green.
477 typeset -g POWERLEVEL9K_STATUS_OK=false
478 typeset -g POWERLEVEL9K_STATUS_OK_FOREGROUND=70
479 typeset -g POWERLEVEL9K_STATUS_OK_VISUAL_IDENTIFIER_EXPANSION='✔'
480
481 # Status when some part of a pipe command fails but the overall exit status is zero. It may look
482 # like this: 1|0.
483 typeset -g POWERLEVEL9K_STATUS_OK_PIPE=true
484 typeset -g POWERLEVEL9K_STATUS_OK_PIPE_FOREGROUND=70
485 typeset -g POWERLEVEL9K_STATUS_OK_PIPE_VISUAL_IDENTIFIER_EXPANSION='✔'
486
487 # Status when it's just an error code (e.g., '1'). No need to show it if prompt_char is enabled as
488 # it will signify error by turning red.
489 typeset -g POWERLEVEL9K_STATUS_ERROR=false
490 typeset -g POWERLEVEL9K_STATUS_ERROR_FOREGROUND=160
491 typeset -g POWERLEVEL9K_STATUS_ERROR_VISUAL_IDENTIFIER_EXPANSION='✘'
492
493 # Status when the last command was terminated by a signal.
494 typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL=true
495 typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_FOREGROUND=160
496 # Use terse signal names: "INT" instead of "SIGINT(2)".
497 typeset -g POWERLEVEL9K_STATUS_VERBOSE_SIGNAME=false
498 typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_VISUAL_IDENTIFIER_EXPANSION='✘'
499
500 # Status when some part of a pipe command fails and the overall exit status is also non-zero.
501 # It may look like this: 1|0.
502 typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE=true
503 typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_FOREGROUND=160
504 typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_VISUAL_IDENTIFIER_EXPANSION='✘'
505
506 ###################[ command_execution_time: duration of the last command ]###################
507 # Show duration of the last command if takes longer than this many seconds.
508 typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=3
509 # Show this many fractional digits. Zero means round to seconds.
510 typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PRECISION=0
511 # Execution time color.
512 typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FOREGROUND=101
513 # Duration format: 1d 2h 3m 4s.
514 typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FORMAT='d h m s'
515 # Custom icon.
516 # typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_VISUAL_IDENTIFIER_EXPANSION='⭐'
517 # Custom prefix.
518 # typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PREFIX='%ftook '
519
520 #######################[ background_jobs: presence of background jobs ]#######################
521 # Don't show the number of background jobs.
522 typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VERBOSE=false
523 # Background jobs color.
524 typeset -g POWERLEVEL9K_BACKGROUND_JOBS_FOREGROUND=70
525 # Custom icon.
526 # typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VISUAL_IDENTIFIER_EXPANSION='⭐'
527
528 #######################[ direnv: direnv status (https://direnv.net/) ]########################
529 # Direnv color.
530 typeset -g POWERLEVEL9K_DIRENV_FOREGROUND=178
531 # Custom icon.
532 # typeset -g POWERLEVEL9K_DIRENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
533
534 ###############[ asdf: asdf version manager (https://github.com/asdf-vm/asdf) ]###############
535 # Default asdf color. Only used to display tools for which there is no color override (see below).
536 # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_FOREGROUND.
537 typeset -g POWERLEVEL9K_ASDF_FOREGROUND=66
538
539 # There are four parameters that can be used to hide asdf tools. Each parameter describes
540 # conditions under which a tool gets hidden. Parameters can hide tools but not unhide them. If at
541 # least one parameter decides to hide a tool, that tool gets hidden. If no parameter decides to
542 # hide a tool, it gets shown.
543 #
544 # Special note on the difference between POWERLEVEL9K_ASDF_SOURCES and
545 # POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW. Consider the effect of the following commands:
546 #
547 # asdf local python 3.8.1
548 # asdf global python 3.8.1
549 #
550 # After running both commands the current python version is 3.8.1 and its source is "local" as
551 # it takes precedence over "global". If POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW is set to false,
552 # it'll hide python version in this case because 3.8.1 is the same as the global version.
553 # POWERLEVEL9K_ASDF_SOURCES will hide python version only if the value of this parameter doesn't
554 # contain "local".
555
556 # Hide tool versions that don't come from one of these sources.
557 #
558 # Available sources:
559 #
560 # - shell `asdf current` says "set by ASDF_${TOOL}_VERSION environment variable"
561 # - local `asdf current` says "set by /some/not/home/directory/file"
562 # - global `asdf current` says "set by /home/username/file"
563 #
564 # Note: If this parameter is set to (shell local global), it won't hide tools.
565 # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SOURCES.
566 typeset -g POWERLEVEL9K_ASDF_SOURCES=(shell local global)
567
568 # If set to false, hide tool versions that are the same as global.
569 #
570 # Note: The name of this parameter doesn't reflect its meaning at all.
571 # Note: If this parameter is set to true, it won't hide tools.
572 # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_PROMPT_ALWAYS_SHOW.
573 typeset -g POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW=false
574
575 # If set to false, hide tool versions that are equal to "system".
576 #
577 # Note: If this parameter is set to true, it won't hide tools.
578 # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SHOW_SYSTEM.
579 typeset -g POWERLEVEL9K_ASDF_SHOW_SYSTEM=true
580
581 # If set to non-empty value, hide tools unless there is a file matching the specified file pattern
582 # in the current directory, or its parent diretory, or its grandparent directory, and so on.
583 #
584 # Note: If this parameter is set to empty value, it won't hide tools.
585 # Note: SHOW_ON_UPGLOB isn't specific to asdf. It works with all prompt segments.
586 # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SHOW_ON_UPGLOB.
587 #
588 # Example: Hide nodejs version when there is no package.json and no *.js files in the current
589 # directory, in `..`, in `../..` and so on.
590 #
591 # typeset -g POWERLEVEL9K_ASDF_NODEJS_SHOW_ON_UPGLOB='*.js|package.json'
592 typeset -g POWERLEVEL9K_ASDF_SHOW_ON_UPGLOB=
593
594 # Ruby version from asdf.
595 typeset -g POWERLEVEL9K_ASDF_RUBY_FOREGROUND=168
596 # typeset -g POWERLEVEL9K_ASDF_RUBY_VISUAL_IDENTIFIER_EXPANSION='⭐'
597 # typeset -g POWERLEVEL9K_ASDF_RUBY_SHOW_ON_UPGLOB='*.foo|*.bar'
598
599 # Python version from asdf.
600 typeset -g POWERLEVEL9K_ASDF_PYTHON_FOREGROUND=37
601 # typeset -g POWERLEVEL9K_ASDF_PYTHON_VISUAL_IDENTIFIER_EXPANSION='⭐'
602 # typeset -g POWERLEVEL9K_ASDF_PYTHON_SHOW_ON_UPGLOB='*.foo|*.bar'
603
604 # Go version from asdf.
605 typeset -g POWERLEVEL9K_ASDF_GOLANG_FOREGROUND=37
606 # typeset -g POWERLEVEL9K_ASDF_GOLANG_VISUAL_IDENTIFIER_EXPANSION='⭐'
607 # typeset -g POWERLEVEL9K_ASDF_GOLANG_SHOW_ON_UPGLOB='*.foo|*.bar'
608
609 # Node.js version from asdf.
610 typeset -g POWERLEVEL9K_ASDF_NODEJS_FOREGROUND=70
611 # typeset -g POWERLEVEL9K_ASDF_NODEJS_VISUAL_IDENTIFIER_EXPANSION='⭐'
612 # typeset -g POWERLEVEL9K_ASDF_NODEJS_SHOW_ON_UPGLOB='*.foo|*.bar'
613
614 # Rust version from asdf.
615 typeset -g POWERLEVEL9K_ASDF_RUST_FOREGROUND=37
616 # typeset -g POWERLEVEL9K_ASDF_RUST_VISUAL_IDENTIFIER_EXPANSION='⭐'
617 # typeset -g POWERLEVEL9K_ASDF_RUST_SHOW_ON_UPGLOB='*.foo|*.bar'
618
619 # .NET Core version from asdf.
620 typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_FOREGROUND=134
621 # typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_VISUAL_IDENTIFIER_EXPANSION='⭐'
622 # typeset -g POWERLEVEL9K_ASDF_DOTNET_SHOW_ON_UPGLOB='*.foo|*.bar'
623
624 # Flutter version from asdf.
625 typeset -g POWERLEVEL9K_ASDF_FLUTTER_FOREGROUND=38
626 # typeset -g POWERLEVEL9K_ASDF_FLUTTER_VISUAL_IDENTIFIER_EXPANSION='⭐'
627 # typeset -g POWERLEVEL9K_ASDF_FLUTTER_SHOW_ON_UPGLOB='*.foo|*.bar'
628
629 # Lua version from asdf.
630 typeset -g POWERLEVEL9K_ASDF_LUA_FOREGROUND=32
631 # typeset -g POWERLEVEL9K_ASDF_LUA_VISUAL_IDENTIFIER_EXPANSION='⭐'
632 # typeset -g POWERLEVEL9K_ASDF_LUA_SHOW_ON_UPGLOB='*.foo|*.bar'
633
634 # Java version from asdf.
635 typeset -g POWERLEVEL9K_ASDF_JAVA_FOREGROUND=32
636 # typeset -g POWERLEVEL9K_ASDF_JAVA_VISUAL_IDENTIFIER_EXPANSION='⭐'
637 # typeset -g POWERLEVEL9K_ASDF_JAVA_SHOW_ON_UPGLOB='*.foo|*.bar'
638
639 # Perl version from asdf.
640 typeset -g POWERLEVEL9K_ASDF_PERL_FOREGROUND=67
641 # typeset -g POWERLEVEL9K_ASDF_PERL_VISUAL_IDENTIFIER_EXPANSION='⭐'
642 # typeset -g POWERLEVEL9K_ASDF_PERL_SHOW_ON_UPGLOB='*.foo|*.bar'
643
644 # Erlang version from asdf.
645 typeset -g POWERLEVEL9K_ASDF_ERLANG_FOREGROUND=125
646 # typeset -g POWERLEVEL9K_ASDF_ERLANG_VISUAL_IDENTIFIER_EXPANSION='⭐'
647 # typeset -g POWERLEVEL9K_ASDF_ERLANG_SHOW_ON_UPGLOB='*.foo|*.bar'
648
649 # Elixir version from asdf.
650 typeset -g POWERLEVEL9K_ASDF_ELIXIR_FOREGROUND=129
651 # typeset -g POWERLEVEL9K_ASDF_ELIXIR_VISUAL_IDENTIFIER_EXPANSION='⭐'
652 # typeset -g POWERLEVEL9K_ASDF_ELIXIR_SHOW_ON_UPGLOB='*.foo|*.bar'
653
654 # Postgres version from asdf.
655 typeset -g POWERLEVEL9K_ASDF_POSTGRES_FOREGROUND=31
656 # typeset -g POWERLEVEL9K_ASDF_POSTGRES_VISUAL_IDENTIFIER_EXPANSION='⭐'
657 # typeset -g POWERLEVEL9K_ASDF_POSTGRES_SHOW_ON_UPGLOB='*.foo|*.bar'
658
659 # PHP version from asdf.
660 typeset -g POWERLEVEL9K_ASDF_PHP_FOREGROUND=99
661 # typeset -g POWERLEVEL9K_ASDF_PHP_VISUAL_IDENTIFIER_EXPANSION='⭐'
662 # typeset -g POWERLEVEL9K_ASDF_PHP_SHOW_ON_UPGLOB='*.foo|*.bar'
663
664 # Haskell version from asdf.
665 typeset -g POWERLEVEL9K_ASDF_HASKELL_FOREGROUND=172
666 # typeset -g POWERLEVEL9K_ASDF_HASKELL_VISUAL_IDENTIFIER_EXPANSION='⭐'
667 # typeset -g POWERLEVEL9K_ASDF_HASKELL_SHOW_ON_UPGLOB='*.foo|*.bar'
668
669 # Julia version from asdf.
670 typeset -g POWERLEVEL9K_ASDF_JULIA_FOREGROUND=70
671 # typeset -g POWERLEVEL9K_ASDF_JULIA_VISUAL_IDENTIFIER_EXPANSION='⭐'
672 # typeset -g POWERLEVEL9K_ASDF_JULIA_SHOW_ON_UPGLOB='*.foo|*.bar'
673
674 ##########[ nordvpn: nordvpn connection status, linux only (https://nordvpn.com/) ]###########
675 # NordVPN connection indicator color.
676 typeset -g POWERLEVEL9K_NORDVPN_FOREGROUND=39
677 # Hide NordVPN connection indicator when not connected.
678 typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_CONTENT_EXPANSION=
679 typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_VISUAL_IDENTIFIER_EXPANSION=
680 # Custom icon.
681 # typeset -g POWERLEVEL9K_NORDVPN_VISUAL_IDENTIFIER_EXPANSION='⭐'
682
683 #################[ ranger: ranger shell (https://github.com/ranger/ranger) ]##################
684 # Ranger shell color.
685 typeset -g POWERLEVEL9K_RANGER_FOREGROUND=178
686 # Custom icon.
687 # typeset -g POWERLEVEL9K_RANGER_VISUAL_IDENTIFIER_EXPANSION='⭐'
688
689 ######################[ nnn: nnn shell (https://github.com/jarun/nnn) ]#######################
690 # Nnn shell color.
691 typeset -g POWERLEVEL9K_NNN_FOREGROUND=72
692 # Custom icon.
693 # typeset -g POWERLEVEL9K_NNN_VISUAL_IDENTIFIER_EXPANSION='⭐'
694
695 ###########################[ vim_shell: vim shell indicator (:sh) ]###########################
696 # Vim shell indicator color.
697 typeset -g POWERLEVEL9K_VIM_SHELL_FOREGROUND=34
698 # Custom icon.
699 # typeset -g POWERLEVEL9K_VIM_SHELL_VISUAL_IDENTIFIER_EXPANSION='⭐'
700
701 ######[ midnight_commander: midnight commander shell (https://midnight-commander.org/) ]######
702 # Midnight Commander shell color.
703 typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_FOREGROUND=178
704 # Custom icon.
705 # typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_VISUAL_IDENTIFIER_EXPANSION='⭐'
706
707 #[ nix_shell: nix shell (https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html) ]##
708 # Nix shell color.
709 typeset -g POWERLEVEL9K_NIX_SHELL_FOREGROUND=74
710
711 # Tip: If you want to see just the icon without "pure" and "impure", uncomment the next line.
712 # typeset -g POWERLEVEL9K_NIX_SHELL_CONTENT_EXPANSION=
713
714 # Custom icon.
715 # typeset -g POWERLEVEL9K_NIX_SHELL_VISUAL_IDENTIFIER_EXPANSION='⭐'
716
717 ##################################[ disk_usage: disk usage ]##################################
718 # Colors for different levels of disk usage.
719 typeset -g POWERLEVEL9K_DISK_USAGE_NORMAL_FOREGROUND=35
720 typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_FOREGROUND=220
721 typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_FOREGROUND=160
722 # Thresholds for different levels of disk usage (percentage points).
723 typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL=90
724 typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_LEVEL=95
725 # If set to true, hide disk usage when below $POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL percent.
726 typeset -g POWERLEVEL9K_DISK_USAGE_ONLY_WARNING=false
727 # Custom icon.
728 # typeset -g POWERLEVEL9K_DISK_USAGE_VISUAL_IDENTIFIER_EXPANSION='⭐'
729
730 ######################################[ ram: free RAM ]#######################################
731 # RAM color.
732 typeset -g POWERLEVEL9K_RAM_FOREGROUND=66
733 # Custom icon.
734 # typeset -g POWERLEVEL9K_RAM_VISUAL_IDENTIFIER_EXPANSION='⭐'
735
736 #####################################[ swap: used swap ]######################################
737 # Swap color.
738 typeset -g POWERLEVEL9K_SWAP_FOREGROUND=96
739 # Custom icon.
740 # typeset -g POWERLEVEL9K_SWAP_VISUAL_IDENTIFIER_EXPANSION='⭐'
741
742 ######################################[ load: CPU load ]######################################
743 # Show average CPU load over this many last minutes. Valid values are 1, 5 and 15.
744 typeset -g POWERLEVEL9K_LOAD_WHICH=5
745 # Load color when load is under 50%.
746 typeset -g POWERLEVEL9K_LOAD_NORMAL_FOREGROUND=66
747 # Load color when load is between 50% and 70%.
748 typeset -g POWERLEVEL9K_LOAD_WARNING_FOREGROUND=178
749 # Load color when load is over 70%.
750 typeset -g POWERLEVEL9K_LOAD_CRITICAL_FOREGROUND=166
751 # Custom icon.
752 # typeset -g POWERLEVEL9K_LOAD_VISUAL_IDENTIFIER_EXPANSION='⭐'
753
754 ################[ todo: todo items (https://github.com/todotxt/todo.txt-cli) ]################
755 # Todo color.
756 typeset -g POWERLEVEL9K_TODO_FOREGROUND=110
757 # Hide todo when the total number of tasks is zero.
758 typeset -g POWERLEVEL9K_TODO_HIDE_ZERO_TOTAL=true
759 # Hide todo when the number of tasks after filtering is zero.
760 typeset -g POWERLEVEL9K_TODO_HIDE_ZERO_FILTERED=false
761
762 # Todo format. The following parameters are available within the expansion.
763 #
764 # - P9K_TODO_TOTAL_TASK_COUNT The total number of tasks.
765 # - P9K_TODO_FILTERED_TASK_COUNT The number of tasks after filtering.
766 #
767 # These variables correspond to the last line of the output of `todo.sh -p ls`:
768 #
769 # TODO: 24 of 42 tasks shown
770 #
771 # Here 24 is P9K_TODO_FILTERED_TASK_COUNT and 42 is P9K_TODO_TOTAL_TASK_COUNT.
772 #
773 # typeset -g POWERLEVEL9K_TODO_CONTENT_EXPANSION='$P9K_TODO_FILTERED_TASK_COUNT'
774
775 # Custom icon.
776 # typeset -g POWERLEVEL9K_TODO_VISUAL_IDENTIFIER_EXPANSION='⭐'
777
778 ###########[ timewarrior: timewarrior tracking status (https://timewarrior.net/) ]############
779 # Timewarrior color.
780 typeset -g POWERLEVEL9K_TIMEWARRIOR_FOREGROUND=110
781 # If the tracked task is longer than 24 characters, truncate and append "…".
782 # Tip: To always display tasks without truncation, delete the following parameter.
783 # Tip: To hide task names and display just the icon when time tracking is enabled, set the
784 # value of the following parameter to "".
785 typeset -g POWERLEVEL9K_TIMEWARRIOR_CONTENT_EXPANSION='${P9K_CONTENT:0:24}${${P9K_CONTENT:24}:+…}'
786
787 # Custom icon.
788 # typeset -g POWERLEVEL9K_TIMEWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐'
789
790 ##############[ taskwarrior: taskwarrior task count (https://taskwarrior.org/) ]##############
791 # Taskwarrior color.
792 typeset -g POWERLEVEL9K_TASKWARRIOR_FOREGROUND=74
793
794 # Taskwarrior segment format. The following parameters are available within the expansion.
795 #
796 # - P9K_TASKWARRIOR_PENDING_COUNT The number of pending tasks: `task +PENDING count`.
797 # - P9K_TASKWARRIOR_OVERDUE_COUNT The number of overdue tasks: `task +OVERDUE count`.
798 #
799 # Zero values are represented as empty parameters.
800 #
801 # The default format:
802 #
803 # '${P9K_TASKWARRIOR_OVERDUE_COUNT:+"!$P9K_TASKWARRIOR_OVERDUE_COUNT/"}$P9K_TASKWARRIOR_PENDING_COUNT'
804 #
805 # typeset -g POWERLEVEL9K_TASKWARRIOR_CONTENT_EXPANSION='$P9K_TASKWARRIOR_PENDING_COUNT'
806
807 # Custom icon.
808 # typeset -g POWERLEVEL9K_TASKWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐'
809
810 ##################################[ context: user@hostname ]##################################
811 # Context color when running with privileges.
812 typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND=178
813 # Context color in SSH without privileges.
814 typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_FOREGROUND=180
815 # Default context color (no privileges, no SSH).
816 typeset -g POWERLEVEL9K_CONTEXT_FOREGROUND=180
817
818 # Context format when running with privileges: bold user@hostname.
819 typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE='%B%n@%m'
820 # Context format when in SSH without privileges: user@hostname.
821 typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_TEMPLATE='%n@%m'
822 # Default context format (no privileges, no SSH): user@hostname.
823 typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE='%n@%m'
824
825 # Don't show context unless running with privileges or in SSH.
826 # Tip: Remove the next line to always show context.
827 typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_{CONTENT,VISUAL_IDENTIFIER}_EXPANSION=
828
829 # Custom icon.
830 # typeset -g POWERLEVEL9K_CONTEXT_VISUAL_IDENTIFIER_EXPANSION='⭐'
831 # Custom prefix.
832 # typeset -g POWERLEVEL9K_CONTEXT_PREFIX='%fwith '
833
834 ###[ virtualenv: python virtual environment (https://docs.python.org/3/library/venv.html) ]###
835 # Python virtual environment color.
836 typeset -g POWERLEVEL9K_VIRTUALENV_FOREGROUND=37
837 # Don't show Python version next to the virtual environment name.
838 typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_PYTHON_VERSION=false
839 # Don't show virtualenv if pyenv is already shown.
840 typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_WITH_PYENV=false
841 # Separate environment name from Python version only with a space.
842 typeset -g POWERLEVEL9K_VIRTUALENV_{LEFT,RIGHT}_DELIMITER=
843 # Custom icon.
844 # typeset -g POWERLEVEL9K_VIRTUALENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
845
846 #####################[ anaconda: conda environment (https://conda.io/) ]######################
847 # Anaconda environment color.
848 typeset -g POWERLEVEL9K_ANACONDA_FOREGROUND=37
849
850 # Anaconda segment format. The following parameters are available within the expansion.
851 #
852 # - CONDA_PREFIX Absolute path to the active Anaconda/Miniconda environment.
853 # - CONDA_DEFAULT_ENV Name of the active Anaconda/Miniconda environment.
854 # - CONDA_PROMPT_MODIFIER Configurable prompt modifier (see below).
855 # - P9K_ANACONDA_PYTHON_VERSION Current python version (python --version).
856 #
857 # CONDA_PROMPT_MODIFIER can be configured with the following command:
858 #
859 # conda config --set env_prompt '({default_env}) '
860 #
861 # The last argument is a Python format string that can use the following variables:
862 #
863 # - prefix The same as CONDA_PREFIX.
864 # - default_env The same as CONDA_DEFAULT_ENV.
865 # - name The last segment of CONDA_PREFIX.
866 # - stacked_env Comma-separated list of names in the environment stack. The first element is
867 # always the same as default_env.
868 #
869 # Note: '({default_env}) ' is the default value of env_prompt.
870 #
871 # The default value of POWERLEVEL9K_ANACONDA_CONTENT_EXPANSION expands to $CONDA_PROMPT_MODIFIER
872 # without the surrounding parentheses, or to the last path component of CONDA_PREFIX if the former
873 # is empty.
874 typeset -g POWERLEVEL9K_ANACONDA_CONTENT_EXPANSION='${${${${CONDA_PROMPT_MODIFIER#\(}% }%\)}:-${CONDA_PREFIX:t}}'
875
876 # Custom icon.
877 # typeset -g POWERLEVEL9K_ANACONDA_VISUAL_IDENTIFIER_EXPANSION='⭐'
878
879 ################[ pyenv: python environment (https://github.com/pyenv/pyenv) ]################
880 # Pyenv color.
881 typeset -g POWERLEVEL9K_PYENV_FOREGROUND=37
882 # Hide python version if it doesn't come from one of these sources.
883 typeset -g POWERLEVEL9K_PYENV_SOURCES=(shell local global)
884 # If set to false, hide python version if it's the same as global:
885 # $(pyenv version-name) == $(pyenv global).
886 typeset -g POWERLEVEL9K_PYENV_PROMPT_ALWAYS_SHOW=false
887 # If set to false, hide python version if it's equal to "system".
888 typeset -g POWERLEVEL9K_PYENV_SHOW_SYSTEM=true
889
890 # Pyenv segment format. The following parameters are available within the expansion.
891 #
892 # - P9K_CONTENT Current pyenv environment (pyenv version-name).
893 # - P9K_PYENV_PYTHON_VERSION Current python version (python --version).
894 #
895 # The default format has the following logic:
896 #
897 # 1. Display "$P9K_CONTENT $P9K_PYENV_PYTHON_VERSION" if $P9K_PYENV_PYTHON_VERSION is not
898 # empty and unequal to $P9K_CONTENT.
899 # 2. Otherwise display just "$P9K_CONTENT".
900 typeset -g POWERLEVEL9K_PYENV_CONTENT_EXPANSION='${P9K_CONTENT}${${P9K_PYENV_PYTHON_VERSION:#$P9K_CONTENT}:+ $P9K_PYENV_PYTHON_VERSION}'
901
902 # Custom icon.
903 # typeset -g POWERLEVEL9K_PYENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
904
905 ################[ goenv: go environment (https://github.com/syndbg/goenv) ]################
906 # Goenv color.
907 typeset -g POWERLEVEL9K_GOENV_FOREGROUND=37
908 # Hide go version if it doesn't come from one of these sources.
909 typeset -g POWERLEVEL9K_GOENV_SOURCES=(shell local global)
910 # If set to false, hide go version if it's the same as global:
911 # $(goenv version-name) == $(goenv global).
912 typeset -g POWERLEVEL9K_GOENV_PROMPT_ALWAYS_SHOW=false
913 # If set to false, hide go version if it's equal to "system".
914 typeset -g POWERLEVEL9K_GOENV_SHOW_SYSTEM=true
915 # Custom icon.
916 # typeset -g POWERLEVEL9K_GOENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
917
918 ##########[ nodenv: node.js version from nodenv (https://github.com/nodenv/nodenv) ]##########
919 # Nodenv color.
920 typeset -g POWERLEVEL9K_NODENV_FOREGROUND=70
921 # Hide node version if it doesn't come from one of these sources.
922 typeset -g POWERLEVEL9K_NODENV_SOURCES=(shell local global)
923 # If set to false, hide node version if it's the same as global:
924 # $(nodenv version-name) == $(nodenv global).
925 typeset -g POWERLEVEL9K_NODENV_PROMPT_ALWAYS_SHOW=false
926 # If set to false, hide node version if it's equal to "system".
927 typeset -g POWERLEVEL9K_NODENV_SHOW_SYSTEM=true
928 # Custom icon.
929 # typeset -g POWERLEVEL9K_NODENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
930
931 ##############[ nvm: node.js version from nvm (https://github.com/nvm-sh/nvm) ]###############
932 # Nvm color.
933 typeset -g POWERLEVEL9K_NVM_FOREGROUND=70
934 # Custom icon.
935 # typeset -g POWERLEVEL9K_NVM_VISUAL_IDENTIFIER_EXPANSION='⭐'
936
937 ############[ nodeenv: node.js environment (https://github.com/ekalinin/nodeenv) ]############
938 # Nodeenv color.
939 typeset -g POWERLEVEL9K_NODEENV_FOREGROUND=70
940 # Don't show Node version next to the environment name.
941 typeset -g POWERLEVEL9K_NODEENV_SHOW_NODE_VERSION=false
942 # Separate environment name from Node version only with a space.
943 typeset -g POWERLEVEL9K_NODEENV_{LEFT,RIGHT}_DELIMITER=
944 # Custom icon.
945 # typeset -g POWERLEVEL9K_NODEENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
946
947 ##############################[ node_version: node.js version ]###############################
948 # Node version color.
949 typeset -g POWERLEVEL9K_NODE_VERSION_FOREGROUND=70
950 # Show node version only when in a directory tree containing package.json.
951 typeset -g POWERLEVEL9K_NODE_VERSION_PROJECT_ONLY=true
952 # Custom icon.
953 # typeset -g POWERLEVEL9K_NODE_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
954
955 #######################[ go_version: go version (https://golang.org) ]########################
956 # Go version color.
957 typeset -g POWERLEVEL9K_GO_VERSION_FOREGROUND=37
958 # Show go version only when in a go project subdirectory.
959 typeset -g POWERLEVEL9K_GO_VERSION_PROJECT_ONLY=true
960 # Custom icon.
961 # typeset -g POWERLEVEL9K_GO_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
962
963 #################[ rust_version: rustc version (https://www.rust-lang.org) ]##################
964 # Rust version color.
965 typeset -g POWERLEVEL9K_RUST_VERSION_FOREGROUND=37
966 # Show rust version only when in a rust project subdirectory.
967 typeset -g POWERLEVEL9K_RUST_VERSION_PROJECT_ONLY=true
968 # Custom icon.
969 # typeset -g POWERLEVEL9K_RUST_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
970
971 ###############[ dotnet_version: .NET version (https://dotnet.microsoft.com) ]################
972 # .NET version color.
973 typeset -g POWERLEVEL9K_DOTNET_VERSION_FOREGROUND=134
974 # Show .NET version only when in a .NET project subdirectory.
975 typeset -g POWERLEVEL9K_DOTNET_VERSION_PROJECT_ONLY=true
976 # Custom icon.
977 # typeset -g POWERLEVEL9K_DOTNET_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
978
979 #####################[ php_version: php version (https://www.php.net/) ]######################
980 # PHP version color.
981 typeset -g POWERLEVEL9K_PHP_VERSION_FOREGROUND=99
982 # Show PHP version only when in a PHP project subdirectory.
983 typeset -g POWERLEVEL9K_PHP_VERSION_PROJECT_ONLY=true
984 # Custom icon.
985 # typeset -g POWERLEVEL9K_PHP_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
986
987 ##########[ laravel_version: laravel php framework version (https://laravel.com/) ]###########
988 # Laravel version color.
989 typeset -g POWERLEVEL9K_LARAVEL_VERSION_FOREGROUND=161
990 # Custom icon.
991 # typeset -g POWERLEVEL9K_LARAVEL_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
992
993 ####################[ java_version: java version (https://www.java.com/) ]####################
994 # Java version color.
995 typeset -g POWERLEVEL9K_JAVA_VERSION_FOREGROUND=32
996 # Show java version only when in a java project subdirectory.
997 typeset -g POWERLEVEL9K_JAVA_VERSION_PROJECT_ONLY=true
998 # Show brief version.
999 typeset -g POWERLEVEL9K_JAVA_VERSION_FULL=false
1000 # Custom icon.
1001 # typeset -g POWERLEVEL9K_JAVA_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
1002
1003 ###[ package: name@version from package.json (https://docs.npmjs.com/files/package.json) ]####
1004 # Package color.
1005 typeset -g POWERLEVEL9K_PACKAGE_FOREGROUND=117
1006 # Package format. The following parameters are available within the expansion.
1007 #
1008 # - P9K_PACKAGE_NAME The value of `name` field in package.json.
1009 # - P9K_PACKAGE_VERSION The value of `version` field in package.json.
1010 #
1011 # typeset -g POWERLEVEL9K_PACKAGE_CONTENT_EXPANSION='${P9K_PACKAGE_NAME//\%/%%}@${P9K_PACKAGE_VERSION//\%/%%}'
1012 # Custom icon.
1013 # typeset -g POWERLEVEL9K_PACKAGE_VISUAL_IDENTIFIER_EXPANSION='⭐'
1014
1015 #############[ rbenv: ruby version from rbenv (https://github.com/rbenv/rbenv) ]##############
1016 # Rbenv color.
1017 typeset -g POWERLEVEL9K_RBENV_FOREGROUND=168
1018 # Hide ruby version if it doesn't come from one of these sources.
1019 typeset -g POWERLEVEL9K_RBENV_SOURCES=(shell local global)
1020 # If set to false, hide ruby version if it's the same as global:
1021 # $(rbenv version-name) == $(rbenv global).
1022 typeset -g POWERLEVEL9K_RBENV_PROMPT_ALWAYS_SHOW=false
1023 # If set to false, hide ruby version if it's equal to "system".
1024 typeset -g POWERLEVEL9K_RBENV_SHOW_SYSTEM=true
1025 # Custom icon.
1026 # typeset -g POWERLEVEL9K_RBENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
1027
1028 #######################[ rvm: ruby version from rvm (https://rvm.io) ]########################
1029 # Rvm color.
1030 typeset -g POWERLEVEL9K_RVM_FOREGROUND=168
1031 # Don't show @gemset at the end.
1032 typeset -g POWERLEVEL9K_RVM_SHOW_GEMSET=false
1033 # Don't show ruby- at the front.
1034 typeset -g POWERLEVEL9K_RVM_SHOW_PREFIX=false
1035 # Custom icon.
1036 # typeset -g POWERLEVEL9K_RVM_VISUAL_IDENTIFIER_EXPANSION='⭐'
1037
1038 ###########[ fvm: flutter version management (https://github.com/leoafarias/fvm) ]############
1039 # Fvm color.
1040 typeset -g POWERLEVEL9K_FVM_FOREGROUND=38
1041 # Custom icon.
1042 # typeset -g POWERLEVEL9K_FVM_VISUAL_IDENTIFIER_EXPANSION='⭐'
1043
1044 ##########[ luaenv: lua version from luaenv (https://github.com/cehoffman/luaenv) ]###########
1045 # Lua color.
1046 typeset -g POWERLEVEL9K_LUAENV_FOREGROUND=32
1047 # Hide lua version if it doesn't come from one of these sources.
1048 typeset -g POWERLEVEL9K_LUAENV_SOURCES=(shell local global)
1049 # If set to false, hide lua version if it's the same as global:
1050 # $(luaenv version-name) == $(luaenv global).
1051 typeset -g POWERLEVEL9K_LUAENV_PROMPT_ALWAYS_SHOW=false
1052 # If set to false, hide lua version if it's equal to "system".
1053 typeset -g POWERLEVEL9K_LUAENV_SHOW_SYSTEM=true
1054 # Custom icon.
1055 # typeset -g POWERLEVEL9K_LUAENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
1056
1057 ###############[ jenv: java version from jenv (https://github.com/jenv/jenv) ]################
1058 # Java color.
1059 typeset -g POWERLEVEL9K_JENV_FOREGROUND=32
1060 # Hide java version if it doesn't come from one of these sources.
1061 typeset -g POWERLEVEL9K_JENV_SOURCES=(shell local global)
1062 # If set to false, hide java version if it's the same as global:
1063 # $(jenv version-name) == $(jenv global).
1064 typeset -g POWERLEVEL9K_JENV_PROMPT_ALWAYS_SHOW=false
1065 # If set to false, hide java version if it's equal to "system".
1066 typeset -g POWERLEVEL9K_JENV_SHOW_SYSTEM=true
1067 # Custom icon.
1068 # typeset -g POWERLEVEL9K_JENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
1069
1070 ###########[ plenv: perl version from plenv (https://github.com/tokuhirom/plenv) ]############
1071 # Perl color.
1072 typeset -g POWERLEVEL9K_PLENV_FOREGROUND=67
1073 # Hide perl version if it doesn't come from one of these sources.
1074 typeset -g POWERLEVEL9K_PLENV_SOURCES=(shell local global)
1075 # If set to false, hide perl version if it's the same as global:
1076 # $(plenv version-name) == $(plenv global).
1077 typeset -g POWERLEVEL9K_PLENV_PROMPT_ALWAYS_SHOW=false
1078 # If set to false, hide perl version if it's equal to "system".
1079 typeset -g POWERLEVEL9K_PLENV_SHOW_SYSTEM=true
1080 # Custom icon.
1081 # typeset -g POWERLEVEL9K_PLENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
1082
1083 ############[ phpenv: php version from phpenv (https://github.com/phpenv/phpenv) ]############
1084 # PHP color.
1085 typeset -g POWERLEVEL9K_PHPENV_FOREGROUND=99
1086 # Hide php version if it doesn't come from one of these sources.
1087 typeset -g POWERLEVEL9K_PHPENV_SOURCES=(shell local global)
1088 # If set to false, hide php version if it's the same as global:
1089 # $(phpenv version-name) == $(phpenv global).
1090 typeset -g POWERLEVEL9K_PHPENV_PROMPT_ALWAYS_SHOW=false
1091 # If set to false, hide php version if it's equal to "system".
1092 typeset -g POWERLEVEL9K_PHPENV_SHOW_SYSTEM=true
1093 # Custom icon.
1094 # typeset -g POWERLEVEL9K_PHPENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
1095
1096 ##########[ haskell_stack: haskell version from stack (https://haskellstack.org/) ]###########
1097 # Haskell color.
1098 typeset -g POWERLEVEL9K_HASKELL_STACK_FOREGROUND=172
1099 # Hide haskell version if it doesn't come from one of these sources.
1100 #
1101 # shell: version is set by STACK_YAML
1102 # local: version is set by stack.yaml up the directory tree
1103 # global: version is set by the implicit global project (~/.stack/global-project/stack.yaml)
1104 typeset -g POWERLEVEL9K_HASKELL_STACK_SOURCES=(shell local)
1105 # If set to false, hide haskell version if it's the same as in the implicit global project.
1106 typeset -g POWERLEVEL9K_HASKELL_STACK_ALWAYS_SHOW=true
1107 # Custom icon.
1108 # typeset -g POWERLEVEL9K_HASKELL_STACK_VISUAL_IDENTIFIER_EXPANSION='⭐'
1109
1110 #############[ kubecontext: current kubernetes context (https://kubernetes.io/) ]#############
1111 # Show kubecontext only when the the command you are typing invokes one of these tools.
1112 # Tip: Remove the next line to always show kubecontext.
1113 typeset -g POWERLEVEL9K_KUBECONTEXT_SHOW_ON_COMMAND='kubectl|helm|kubens|kubectx|oc|istioctl|kogito'
1114
1115 # Kubernetes context classes for the purpose of using different colors, icons and expansions with
1116 # different contexts.
1117 #
1118 # POWERLEVEL9K_KUBECONTEXT_CLASSES is an array with even number of elements. The first element
1119 # in each pair defines a pattern against which the current kubernetes context gets matched.
1120 # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below)
1121 # that gets matched. If you unset all POWERLEVEL9K_KUBECONTEXT_*CONTENT_EXPANSION parameters,
1122 # you'll see this value in your prompt. The second element of each pair in
1123 # POWERLEVEL9K_KUBECONTEXT_CLASSES defines the context class. Patterns are tried in order. The
1124 # first match wins.
1125 #
1126 # For example, given these settings:
1127 #
1128 # typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=(
1129 # '*prod*' PROD
1130 # '*test*' TEST
1131 # '*' DEFAULT)
1132 #
1133 # If your current kubernetes context is "deathray-testing/default", its class is TEST
1134 # because "deathray-testing/default" doesn't match the pattern '*prod*' but does match '*test*'.
1135 #
1136 # You can define different colors, icons and content expansions for different classes:
1137 #
1138 # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_FOREGROUND=28
1139 # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐'
1140 # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <'
1141 typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=(
1142 # '*prod*' PROD # These values are examples that are unlikely
1143 # '*test*' TEST # to match your needs. Customize them as needed.
1144 '*' DEFAULT)
1145 typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_FOREGROUND=134
1146 # typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐'
1147
1148 # Use POWERLEVEL9K_KUBECONTEXT_CONTENT_EXPANSION to specify the content displayed by kubecontext
1149 # segment. Parameter expansions are very flexible and fast, too. See reference:
1150 # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion.
1151 #
1152 # Within the expansion the following parameters are always available:
1153 #
1154 # - P9K_CONTENT The content that would've been displayed if there was no content
1155 # expansion defined.
1156 # - P9K_KUBECONTEXT_NAME The current context's name. Corresponds to column NAME in the
1157 # output of `kubectl config get-contexts`.
1158 # - P9K_KUBECONTEXT_CLUSTER The current context's cluster. Corresponds to column CLUSTER in the
1159 # output of `kubectl config get-contexts`.
1160 # - P9K_KUBECONTEXT_NAMESPACE The current context's namespace. Corresponds to column NAMESPACE
1161 # in the output of `kubectl config get-contexts`. If there is no
1162 # namespace, the parameter is set to "default".
1163 # - P9K_KUBECONTEXT_USER The current context's user. Corresponds to column AUTHINFO in the
1164 # output of `kubectl config get-contexts`.
1165 #
1166 # If the context points to Google Kubernetes Engine (GKE) or Elastic Kubernetes Service (EKS),
1167 # the following extra parameters are available:
1168 #
1169 # - P9K_KUBECONTEXT_CLOUD_NAME Either "gke" or "eks".
1170 # - P9K_KUBECONTEXT_CLOUD_ACCOUNT Account/project ID.
1171 # - P9K_KUBECONTEXT_CLOUD_ZONE Availability zone.
1172 # - P9K_KUBECONTEXT_CLOUD_CLUSTER Cluster.
1173 #
1174 # P9K_KUBECONTEXT_CLOUD_* parameters are derived from P9K_KUBECONTEXT_CLUSTER. For example,
1175 # if P9K_KUBECONTEXT_CLUSTER is "gke_my-account_us-east1-a_my-cluster-01":
1176 #
1177 # - P9K_KUBECONTEXT_CLOUD_NAME=gke
1178 # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=my-account
1179 # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east1-a
1180 # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01
1181 #
1182 # If P9K_KUBECONTEXT_CLUSTER is "arn:aws:eks:us-east-1:123456789012:cluster/my-cluster-01":
1183 #
1184 # - P9K_KUBECONTEXT_CLOUD_NAME=eks
1185 # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=123456789012
1186 # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east-1
1187 # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01
1188 typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION=
1189 # Show P9K_KUBECONTEXT_CLOUD_CLUSTER if it's not empty and fall back to P9K_KUBECONTEXT_NAME.
1190 POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${P9K_KUBECONTEXT_CLOUD_CLUSTER:-${P9K_KUBECONTEXT_NAME}}'
1191 # Append the current context's namespace if it's not "default".
1192 POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${${:-/$P9K_KUBECONTEXT_NAMESPACE}:#/default}'
1193
1194 # Custom prefix.
1195 # typeset -g POWERLEVEL9K_KUBECONTEXT_PREFIX='%fat '
1196
1197 ################[ terraform: terraform workspace (https://www.terraform.io) ]#################
1198 # Don't show terraform workspace if it's literally "default".
1199 typeset -g POWERLEVEL9K_TERRAFORM_SHOW_DEFAULT=false
1200 # POWERLEVEL9K_TERRAFORM_CLASSES is an array with even number of elements. The first element
1201 # in each pair defines a pattern against which the current terraform workspace gets matched.
1202 # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below)
1203 # that gets matched. If you unset all POWERLEVEL9K_TERRAFORM_*CONTENT_EXPANSION parameters,
1204 # you'll see this value in your prompt. The second element of each pair in
1205 # POWERLEVEL9K_TERRAFORM_CLASSES defines the workspace class. Patterns are tried in order. The
1206 # first match wins.
1207 #
1208 # For example, given these settings:
1209 #
1210 # typeset -g POWERLEVEL9K_TERRAFORM_CLASSES=(
1211 # '*prod*' PROD
1212 # '*test*' TEST
1213 # '*' OTHER)
1214 #
1215 # If your current terraform workspace is "project_test", its class is TEST because "project_test"
1216 # doesn't match the pattern '*prod*' but does match '*test*'.
1217 #
1218 # You can define different colors, icons and content expansions for different classes:
1219 #
1220 # typeset -g POWERLEVEL9K_TERRAFORM_TEST_FOREGROUND=28
1221 # typeset -g POWERLEVEL9K_TERRAFORM_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐'
1222 # typeset -g POWERLEVEL9K_TERRAFORM_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <'
1223 typeset -g POWERLEVEL9K_TERRAFORM_CLASSES=(
1224 # '*prod*' PROD # These values are examples that are unlikely
1225 # '*test*' TEST # to match your needs. Customize them as needed.
1226 '*' OTHER)
1227 typeset -g POWERLEVEL9K_TERRAFORM_OTHER_FOREGROUND=38
1228 # typeset -g POWERLEVEL9K_TERRAFORM_OTHER_VISUAL_IDENTIFIER_EXPANSION='⭐'
1229
1230 #[ aws: aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) ]#
1231 # Show aws only when the the command you are typing invokes one of these tools.
1232 # Tip: Remove the next line to always show aws.
1233 typeset -g POWERLEVEL9K_AWS_SHOW_ON_COMMAND='aws|awless|terraform|pulumi'
1234
1235 # POWERLEVEL9K_AWS_CLASSES is an array with even number of elements. The first element
1236 # in each pair defines a pattern against which the current AWS profile gets matched.
1237 # More specifically, it's P9K_CONTENT prior to the application of context expansion (see below)
1238 # that gets matched. If you unset all POWERLEVEL9K_AWS_*CONTENT_EXPANSION parameters,
1239 # you'll see this value in your prompt. The second element of each pair in
1240 # POWERLEVEL9K_AWS_CLASSES defines the profile class. Patterns are tried in order. The
1241 # first match wins.
1242 #
1243 # For example, given these settings:
1244 #
1245 # typeset -g POWERLEVEL9K_AWS_CLASSES=(
1246 # '*prod*' PROD
1247 # '*test*' TEST
1248 # '*' DEFAULT)
1249 #
1250 # If your current AWS profile is "company_test", its class is TEST
1251 # because "company_test" doesn't match the pattern '*prod*' but does match '*test*'.
1252 #
1253 # You can define different colors, icons and content expansions for different classes:
1254 #
1255 # typeset -g POWERLEVEL9K_AWS_TEST_FOREGROUND=28
1256 # typeset -g POWERLEVEL9K_AWS_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐'
1257 # typeset -g POWERLEVEL9K_AWS_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <'
1258 typeset -g POWERLEVEL9K_AWS_CLASSES=(
1259 # '*prod*' PROD # These values are examples that are unlikely
1260 # '*test*' TEST # to match your needs. Customize them as needed.
1261 '*' DEFAULT)
1262 typeset -g POWERLEVEL9K_AWS_DEFAULT_FOREGROUND=208
1263 # typeset -g POWERLEVEL9K_AWS_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐'
1264
1265 #[ aws_eb_env: aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) ]#
1266 # AWS Elastic Beanstalk environment color.
1267 typeset -g POWERLEVEL9K_AWS_EB_ENV_FOREGROUND=70
1268 # Custom icon.
1269 # typeset -g POWERLEVEL9K_AWS_EB_ENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
1270
1271 ##########[ azure: azure account name (https://docs.microsoft.com/en-us/cli/azure) ]##########
1272 # Show azure only when the the command you are typing invokes one of these tools.
1273 # Tip: Remove the next line to always show azure.
1274 typeset -g POWERLEVEL9K_AZURE_SHOW_ON_COMMAND='az|terraform|pulumi'
1275 # Azure account name color.
1276 typeset -g POWERLEVEL9K_AZURE_FOREGROUND=32
1277 # Custom icon.
1278 # typeset -g POWERLEVEL9K_AZURE_VISUAL_IDENTIFIER_EXPANSION='⭐'
1279
1280 ##########[ gcloud: google cloud account and project (https://cloud.google.com/) ]###########
1281 # Show gcloud only when the the command you are typing invokes one of these tools.
1282 # Tip: Remove the next line to always show gcloud.
1283 typeset -g POWERLEVEL9K_GCLOUD_SHOW_ON_COMMAND='gcloud|gcs'
1284 # Google cloud color.
1285 typeset -g POWERLEVEL9K_GCLOUD_FOREGROUND=32
1286
1287 # Google cloud format. Change the value of POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION and/or
1288 # POWERLEVEL9K_GCLOUD_COMPLETE_CONTENT_EXPANSION if the default is too verbose or not informative
1289 # enough. You can use the following parameters in the expansions. Each of them corresponds to the
1290 # output of `gcloud` tool.
1291 #
1292 # Parameter | Source
1293 # -------------------------|--------------------------------------------------------------------
1294 # P9K_GCLOUD_CONFIGURATION | gcloud config configurations list --format='value(name)'
1295 # P9K_GCLOUD_ACCOUNT | gcloud config get-value account
1296 # P9K_GCLOUD_PROJECT_ID | gcloud config get-value project
1297 # P9K_GCLOUD_PROJECT_NAME | gcloud projects describe $P9K_GCLOUD_PROJECT_ID --format='value(name)'
1298 #
1299 # Note: ${VARIABLE//\%/%%} expands to ${VARIABLE} with all occurences of '%' replaced with '%%'.
1300 #
1301 # Obtaining project name requires sending a request to Google servers. This can take a long time
1302 # and even fail. When project name is unknown, P9K_GCLOUD_PROJECT_NAME is not set and gcloud
1303 # prompt segment is in state PARTIAL. When project name gets known, P9K_GCLOUD_PROJECT_NAME gets
1304 # set and gcloud prompt segment transitions to state COMPLETE.
1305 #
1306 # You can customize the format, icon and colors of gcloud segment separately for states PARTIAL
1307 # and COMPLETE. You can also hide gcloud in state PARTIAL by setting
1308 # POWERLEVEL9K_GCLOUD_PARTIAL_VISUAL_IDENTIFIER_EXPANSION and
1309 # POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION to empty.
1310 typeset -g POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION='${P9K_GCLOUD_PROJECT_ID//\%/%%}'
1311 typeset -g POWERLEVEL9K_GCLOUD_COMPLETE_CONTENT_EXPANSION='${P9K_GCLOUD_PROJECT_NAME//\%/%%}'
1312
1313 # Send a request to Google (by means of `gcloud projects describe ...`) to obtain project name
1314 # this often. Negative value disables periodic polling. In this mode project name is retrieved
1315 # only when the current configuration, account or project id changes.
1316 typeset -g POWERLEVEL9K_GCLOUD_REFRESH_PROJECT_NAME_SECONDS=60
1317
1318 # Custom icon.
1319 # typeset -g POWERLEVEL9K_GCLOUD_VISUAL_IDENTIFIER_EXPANSION='⭐'
1320
1321 #[ google_app_cred: google application credentials (https://cloud.google.com/docs/authentication/production) ]#
1322 # Show google_app_cred only when the the command you are typing invokes one of these tools.
1323 # Tip: Remove the next line to always show google_app_cred.
1324 typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_SHOW_ON_COMMAND='terraform|pulumi'
1325
1326 # Google application credentials classes for the purpose of using different colors, icons and
1327 # expansions with different credentials.
1328 #
1329 # POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES is an array with even number of elements. The first
1330 # element in each pair defines a pattern against which the current kubernetes context gets
1331 # matched. More specifically, it's P9K_CONTENT prior to the application of context expansion
1332 # (see below) that gets matched. If you unset all POWERLEVEL9K_GOOGLE_APP_CRED_*CONTENT_EXPANSION
1333 # parameters, you'll see this value in your prompt. The second element of each pair in
1334 # POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES defines the context class. Patterns are tried in order.
1335 # The first match wins.
1336 #
1337 # For example, given these settings:
1338 #
1339 # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES=(
1340 # '*:*prod*:*' PROD
1341 # '*:*test*:*' TEST
1342 # '*' DEFAULT)
1343 #
1344 # If your current Google application credentials is "service_account deathray-testing x@y.com",
1345 # its class is TEST because it doesn't match the pattern '* *prod* *' but does match '* *test* *'.
1346 #
1347 # You can define different colors, icons and content expansions for different classes:
1348 #
1349 # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_FOREGROUND=28
1350 # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐'
1351 # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_CONTENT_EXPANSION='$P9K_GOOGLE_APP_CRED_PROJECT_ID'
1352 typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES=(
1353 # '*:*prod*:*' PROD # These values are examples that are unlikely
1354 # '*:*test*:*' TEST # to match your needs. Customize them as needed.
1355 '*' DEFAULT)
1356 typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_FOREGROUND=32
1357 # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐'
1358
1359 # Use POWERLEVEL9K_GOOGLE_APP_CRED_CONTENT_EXPANSION to specify the content displayed by
1360 # google_app_cred segment. Parameter expansions are very flexible and fast, too. See reference:
1361 # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion.
1362 #
1363 # You can use the following parameters in the expansion. Each of them corresponds to one of the
1364 # fields in the JSON file pointed to by GOOGLE_APPLICATION_CREDENTIALS.
1365 #
1366 # Parameter | JSON key file field
1367 # ---------------------------------+---------------
1368 # P9K_GOOGLE_APP_CRED_TYPE | type
1369 # P9K_GOOGLE_APP_CRED_PROJECT_ID | project_id
1370 # P9K_GOOGLE_APP_CRED_CLIENT_EMAIL | client_email
1371 #
1372 # Note: ${VARIABLE//\%/%%} expands to ${VARIABLE} with all occurences of '%' replaced by '%%'.
1373 typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_CONTENT_EXPANSION='${P9K_GOOGLE_APP_CRED_PROJECT_ID//\%/%%}'
1374
1375 ###############################[ public_ip: public IP address ]###############################
1376 # Public IP color.
1377 typeset -g POWERLEVEL9K_PUBLIC_IP_FOREGROUND=94
1378 # Custom icon.
1379 # typeset -g POWERLEVEL9K_PUBLIC_IP_VISUAL_IDENTIFIER_EXPANSION='⭐'
1380
1381 ########################[ vpn_ip: virtual private network indicator ]#########################
1382 # VPN IP color.
1383 typeset -g POWERLEVEL9K_VPN_IP_FOREGROUND=81
1384 # When on VPN, show just an icon without the IP address.
1385 # Tip: To display the private IP address when on VPN, remove the next line.
1386 typeset -g POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION=
1387 # Regular expression for the VPN network interface. Run `ifconfig` or `ip -4 a show` while on VPN
1388 # to see the name of the interface.
1389 typeset -g POWERLEVEL9K_VPN_IP_INTERFACE='(wg|(.*tun))[0-9]*'
1390 # If set to true, show one segment per matching network interface. If set to false, show only
1391 # one segment corresponding to the first matching network interface.
1392 # Tip: If you set it to true, you'll probably want to unset POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION.
1393 typeset -g POWERLEVEL9K_VPN_IP_SHOW_ALL=false
1394 # Custom icon.
1395 # typeset -g POWERLEVEL9K_VPN_IP_VISUAL_IDENTIFIER_EXPANSION='⭐'
1396
1397 ###########[ ip: ip address and bandwidth usage for a specified network interface ]###########
1398 # IP color.
1399 typeset -g POWERLEVEL9K_IP_FOREGROUND=38
1400 # The following parameters are accessible within the expansion:
1401 #
1402 # Parameter | Meaning
1403 # ----------------------+---------------
1404 # P9K_IP_IP | IP address
1405 # P9K_IP_INTERFACE | network interface
1406 # P9K_IP_RX_BYTES | total number of bytes received
1407 # P9K_IP_TX_BYTES | total number of bytes sent
1408 # P9K_IP_RX_RATE | receive rate (since last prompt)
1409 # P9K_IP_TX_RATE | send rate (since last prompt)
1410 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}'
1411 # Show information for the first network interface whose name matches this regular expression.
1412 # Run `ifconfig` or `ip -4 a show` to see the names of all network interfaces.
1413 typeset -g POWERLEVEL9K_IP_INTERFACE='e.*'
1414 # Custom icon.
1415 # typeset -g POWERLEVEL9K_IP_VISUAL_IDENTIFIER_EXPANSION='⭐'
1416
1417 #########################[ proxy: system-wide http/https/ftp proxy ]##########################
1418 # Proxy color.
1419 typeset -g POWERLEVEL9K_PROXY_FOREGROUND=68
1420 # Custom icon.
1421 # typeset -g POWERLEVEL9K_PROXY_VISUAL_IDENTIFIER_EXPANSION='⭐'
1422
1423 ################################[ battery: internal battery ]#################################
1424 # Show battery in red when it's below this level and not connected to power supply.
1425 typeset -g POWERLEVEL9K_BATTERY_LOW_THRESHOLD=20
1426 typeset -g POWERLEVEL9K_BATTERY_LOW_FOREGROUND=160
1427 # Show battery in green when it's charging or fully charged.
1428 typeset -g POWERLEVEL9K_BATTERY_{CHARGING,CHARGED}_FOREGROUND=70
1429 # Show battery in yellow when it's discharging.
1430 typeset -g POWERLEVEL9K_BATTERY_DISCONNECTED_FOREGROUND=178
1431 # Battery pictograms going from low to high level of charge.
1432 typeset -g POWERLEVEL9K_BATTERY_STAGES='\uf58d\uf579\uf57a\uf57b\uf57c\uf57d\uf57e\uf57f\uf580\uf581\uf578'
1433 # Don't show the remaining time to charge/discharge.
1434 typeset -g POWERLEVEL9K_BATTERY_VERBOSE=false
1435
1436 #####################################[ wifi: wifi speed ]#####################################
1437 # WiFi color.
1438 typeset -g POWERLEVEL9K_WIFI_FOREGROUND=68
1439 # Custom icon.
1440 # typeset -g POWERLEVEL9K_WIFI_VISUAL_IDENTIFIER_EXPANSION='⭐'
1441
1442 # Use different colors and icons depending on signal strength ($P9K_WIFI_BARS).
1443 #
1444 # # Wifi colors and icons for different signal strength levels (low to high).
1445 # typeset -g my_wifi_fg=(68 68 68 68 68) # <-- change these values
1446 # typeset -g my_wifi_icon=('WiFi' 'WiFi' 'WiFi' 'WiFi' 'WiFi') # <-- change these values
1447 #
1448 # typeset -g POWERLEVEL9K_WIFI_CONTENT_EXPANSION='%F{${my_wifi_fg[P9K_WIFI_BARS+1]}}$P9K_WIFI_LAST_TX_RATE Mbps'
1449 # typeset -g POWERLEVEL9K_WIFI_VISUAL_IDENTIFIER_EXPANSION='%F{${my_wifi_fg[P9K_WIFI_BARS+1]}}${my_wifi_icon[P9K_WIFI_BARS+1]}'
1450 #
1451 # The following parameters are accessible within the expansions:
1452 #
1453 # Parameter | Meaning
1454 # ----------------------+---------------
1455 # P9K_WIFI_SSID | service set identifier, a.k.a. network name
1456 # P9K_WIFI_LINK_AUTH | authentication protocol such as "wpa2-psk" or "none"
1457 # P9K_WIFI_LAST_TX_RATE | wireless transmit rate in megabits per second
1458 # P9K_WIFI_RSSI | signal strength in dBm, from -120 to 0
1459 # P9K_WIFI_NOISE | noise in dBm, from -120 to 0
1460 # P9K_WIFI_BARS | signal strength in bars, from 0 to 4 (derived from P9K_WIFI_RSSI and P9K_WIFI_NOISE)
1461 #
1462 # All parameters except P9K_WIFI_BARS are extracted from the output of the following command:
1463 #
1464 # /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I
1465
1466 ####################################[ time: current time ]####################################
1467 # Current time color.
1468 typeset -g POWERLEVEL9K_TIME_FOREGROUND=66
1469 # Format for the current time: 09:51:02. See `man 3 strftime`.
1470 typeset -g POWERLEVEL9K_TIME_FORMAT='%D{%H:%M:%S}'
1471 # If set to true, time will update when you hit enter. This way prompts for the past
1472 # commands will contain the start times of their commands as opposed to the default
1473 # behavior where they contain the end times of their preceding commands.
1474 typeset -g POWERLEVEL9K_TIME_UPDATE_ON_COMMAND=false
1475 # Custom icon.
1476 # typeset -g POWERLEVEL9K_TIME_VISUAL_IDENTIFIER_EXPANSION='⭐'
1477 # Custom prefix.
1478 # typeset -g POWERLEVEL9K_TIME_PREFIX='%fat '
1479
1480 # Example of a user-defined prompt segment. Function prompt_example will be called on every
1481 # prompt if `example` prompt segment is added to POWERLEVEL9K_LEFT_PROMPT_ELEMENTS or
1482 # POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS. It displays an icon and orange text greeting the user.
1483 #
1484 # Type `p10k help segment` for documentation and a more sophisticated example.
1485 function prompt_example() {
1486 p10k segment -f 208 -i '⭐' -t 'hello, %n'
1487 }
1488
1489 # User-defined prompt segments may optionally provide an instant_prompt_* function. Its job
1490 # is to generate the prompt segment for display in instant prompt. See
1491 # https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt.
1492 #
1493 # Powerlevel10k will call instant_prompt_* at the same time as the regular prompt_* function
1494 # and will record all `p10k segment` calls it makes. When displaying instant prompt, Powerlevel10k
1495 # will replay these calls without actually calling instant_prompt_*. It is imperative that
1496 # instant_prompt_* always makes the same `p10k segment` calls regardless of environment. If this
1497 # rule is not observed, the content of instant prompt will be incorrect.
1498 #
1499 # Usually, you should either not define instant_prompt_* or simply call prompt_* from it. If
1500 # instant_prompt_* is not defined for a segment, the segment won't be shown in instant prompt.
1501 function instant_prompt_example() {
1502 # Since prompt_example always makes the same `p10k segment` calls, we can call it from
1503 # instant_prompt_example. This will give us the same `example` prompt segment in the instant
1504 # and regular prompts.
1505 prompt_example
1506 }
1507
1508 # User-defined prompt segments can be customized the same way as built-in segments.
1509 # typeset -g POWERLEVEL9K_EXAMPLE_FOREGROUND=208
1510 # typeset -g POWERLEVEL9K_EXAMPLE_VISUAL_IDENTIFIER_EXPANSION='⭐'
1511
1512 # Transient prompt works similarly to the builtin transient_rprompt option. It trims down prompt
1513 # when accepting a command line. Supported values:
1514 #
1515 # - off: Don't change prompt when accepting a command line.
1516 # - always: Trim down prompt when accepting a command line.
1517 # - same-dir: Trim down prompt when accepting a command line unless this is the first command
1518 # typed after changing current working directory.
1519 typeset -g POWERLEVEL9K_TRANSIENT_PROMPT=always
1520
1521 # Instant prompt mode.
1522 #
1523 # - off: Disable instant prompt. Choose this if you've tried instant prompt and found
1524 # it incompatible with your zsh configuration files.
1525 # - quiet: Enable instant prompt and don't print warnings when detecting console output
1526 # during zsh initialization. Choose this if you've read and understood
1527 # https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt.
1528 # - verbose: Enable instant prompt and print a warning when detecting console output during
1529 # zsh initialization. Choose this if you've never tried instant prompt, haven't
1530 # seen the warning, or if you are unsure what this all means.
1531 typeset -g POWERLEVEL9K_INSTANT_PROMPT=off
1532
1533 # Hot reload allows you to change POWERLEVEL9K options after Powerlevel10k has been initialized.
1534 # For example, you can type POWERLEVEL9K_BACKGROUND=red and see your prompt turn red. Hot reload
1535 # can slow down prompt by 1-2 milliseconds, so it's better to keep it turned off unless you
1536 # really need it.
1537 typeset -g POWERLEVEL9K_DISABLE_HOT_RELOAD=true
1538
1539 # If p10k is already loaded, reload configuration.
1540 # This works even with POWERLEVEL9K_DISABLE_HOT_RELOAD=true.
1541 (( ! $+functions[p10k] )) || p10k reload
1542}
1543
1544# Tell `p10k configure` which file it should overwrite.
1545typeset -g POWERLEVEL9K_CONFIG_FILE=${${(%):-%x}:a}
1546
1547(( ${#p10k_config_opts} )) && setopt ${p10k_config_opts[@]}
1548'builtin' 'unset' 'p10k_config_opts'
diff --git a/users/gkleen/default.nix b/users/gkleen/default.nix
index f74701a5..26f7a1d4 100644
--- a/users/gkleen/default.nix
+++ b/users/gkleen/default.nix
@@ -1,5 +1,9 @@
1{ userName, pkgs, customUtils, lib, ... }: 1{ flake, userName, pkgs, customUtils, lib, ... }:
2{ 2{
3 imports = with flake.nixosModules.userProfiles.${userName}; [
4 zsh tmux utils
5 ];
6
3 users.users.${userName} = { 7 users.users.${userName} = {
4 description = "Gregor Kleen"; 8 description = "Gregor Kleen";
5 extraGroups = [ "wheel" "networkmanager" "lp" "dialout" "audio" "video" "xmpp" "mail" "ssh" "vboxusers" "libvirtd" "wireshark" "games"]; 9 extraGroups = [ "wheel" "networkmanager" "lp" "dialout" "audio" "video" "xmpp" "mail" "ssh" "vboxusers" "libvirtd" "wireshark" "games"];
@@ -12,4 +16,32 @@
12 openssh.authorizedKeys.keyFiles = lib.attrValues (customUtils.recImport rec { dir = ./authorized-keys; _import = name: _base: dir + "/${name}"; }); 16 openssh.authorizedKeys.keyFiles = lib.attrValues (customUtils.recImport rec { dir = ./authorized-keys; _import = name: _base: dir + "/${name}"; });
13 hashedPassword = "$6$rounds=500000$dOMgCU7DAk$yQFYGOURTEt12387LIYBnFKSWmtwXMUk1LJWnV0m7OFt.y2TnxQn2abdGA5dhwG9EmMB5wZGXf4J5F71c746C/"; 17 hashedPassword = "$6$rounds=500000$dOMgCU7DAk$yQFYGOURTEt12387LIYBnFKSWmtwXMUk1LJWnV0m7OFt.y2TnxQn2abdGA5dhwG9EmMB5wZGXf4J5F71c746C/";
14 }; 18 };
19
20 home-manager.users.${userName} = {
21 programs = {
22 git = {
23 enable = true;
24 userEmail = "gkleen@yggdrasil.li";
25 userName = "Gregor Kleen";
26 delta.enable = true;
27 extraConfig = {
28 pull.rebase = false;
29 };
30 };
31
32 ssh = {
33 enable = true;
34 controlMaster = "auto";
35 controlPersist = "30m";
36 serverAliveInterval = 6;
37 hashKnownHosts = true;
38 extraConfig = ''
39 IdentitiesOnly true
40 ServerAliveCountMax 10
41 '';
42 };
43
44 gpg.enable = true;
45 };
46 };
15} 47}
diff --git a/users/root.nix b/users/root.nix
index 95fe37c4..c6e7d712 100644
--- a/users/root.nix
+++ b/users/root.nix
@@ -1,7 +1,30 @@
1{ flake, lib, config, hostName, ... }: 1{ flake, lib, config, hostName, userName, pkgs, ... }:
2{ 2let
3 users.users.root = lib.mkIf (flake.nixosModules.accounts ? "gkleen@${hostName}") { 3 haveGKleen = flake.nixosModules.accounts ? "gkleen@${hostName}";
4in {
5 imports = with flake.nixosModules.userProfiles.${userName}; [
6 zsh tmux utils
7 ];
8
9 users.users.${userName} = lib.mkIf haveGKleen {
4 inherit (config.users.users."gkleen") hashedPassword shell; 10 inherit (config.users.users."gkleen") hashedPassword shell;
5 openssh.authorizedKeys.keyFiles = config.users.users."gkleen".openssh.authorizedKeys.keyFiles; 11 openssh.authorizedKeys.keyFiles = config.users.users."gkleen".openssh.authorizedKeys.keyFiles;
6 }; 12 };
13
14 home-manager.users.${userName} = {
15 programs = lib.mkIf haveGKleen {
16 inherit (config.home-manager.users.gkleen.programs) git ssh gpg;
17 };
18
19 services = {
20 gpg-agent = {
21 enable = true;
22 enableSshSupport = true;
23 extraConfig = ''
24 pinentry-program ${pkgs.pinentry-curses}/bin/pinentry
25 grab
26 '';
27 };
28 };
29 };
7} 30}