Skip to content

Instantly share code, notes, and snippets.

@Zeitwaechter
Last active April 20, 2024 10:56
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Zeitwaechter/c2de35b21b826d0f261a55bad8b9ece4 to your computer and use it in GitHub Desktop.
Save Zeitwaechter/c2de35b21b826d0f261a55bad8b9ece4 to your computer and use it in GitHub Desktop.
Installing Arch Linux (Encrypted) on a device 2024 (with a few extras)

To backup your old system:

  • rsync -aAXhv --exclude={"/dev/*","/lost+found","/mnt/*","/media/*","/proc/*","/run/*","/sys/*","/tmp/*","*cache"} / /[TARGET]

If you want to remind yourself about how to install Arch Linux on a console that you can only access via serial console, checkout the official arch wiki article.

Or:

  • Add console=ttyS0,115200 after hitting TAB in Arch Linux Image Bootloader
  • Pay attention to your screen not pasting stuff up till/after the ,
  • Login as root into archiso

  • Do efivar --list
  • If you get any feedback, watch out for EFI specifics in this guide.
  • Warning: Some of the yay pacakges do take much time. You will at least spend an evening, installing all.

Due to SteamOS 3.0, folks are getting hotter with Wayland.. but even though it worked in between, it is now not working anymore.. sigh. Depending on the Efforts of Nvidia/QT/KDM team it might work out soon again. I'm guessing the setup is now like it should be, but it is best to still use X a bit longer.. will update posts soon TM.

GUI part tested with intel/amd cpu+nvidia gpu, rest not - all without warranty

Beware of values in []

  • Check for internet/ethernet: ip a
  • For Wifi connections:
    iwctl station list
    iwctl station station scan
    iwctl station station get-networks
    iwctl station station connect [network_name]
    

Alternative Workflow:

  • Start by python -m archinstall guided

Let's start

  • lsblk
  • dd if=/dev/zero of=/dev/[device] bs=4M status=progress oflag=sync
  • We need two partitions on our nvm/ssd/hdd
    • IF NOT EFI:
      • fdisk /dev/[device] --wipe always
        • +256M, Linux (boot enabled) partition, Hex code 8300
        • 100% rest, Linux partition, Hex code 8300
      • mkfs.ext4 -F -O metadata_csum,64bit /dev/[device]1
    • IF EFI:
      • gdisk /dev/[device]
        • +256M, EFI partition, Hex code ef00
        • 100% rest, Linux partition, Hex code 8300
      • mkfs.vfat -F32 -n EFI /dev/[device]1
  • LUKS
    • IF NOT EFI:
      • cryptsetup -v --cipher aes-xts-plain64 --key-size 512 --hash sha512 --iter-time 3000 --use-urandom --verify-passphrase --type luks1 luksFormat /dev/[device]2
    • IF EFI:
      • cryptsetup --type luks2 --cipher aes-xts-plain64 --hash sha512 --iter-time 3000 --key-size 512 --pbkdf pbkdf2 --use-urandom --verify-passphrase luksFormat /dev/[device]2
    • There might be performance differences in using aes-xts-plain64 on storages with <2TB disk size, you therefore might want to go with aes-xts-plain instead
  • cryptsetup luksOpen /dev/[device]2 [mapperName]
  • vgcreate [groupName] /dev/mapper/[mapperName]
  • lvcreate -L [RAM]GB -n [volumeName-swap] [groupName] (make it big, also due to hibernate)
  • lvcreate -l 100%FREE -n [volumeName-root] [groupName]
  • mkswap -L swap /dev/mapper/[groupName]-[volumeName-swap]
  • swapon /dev/mapper/[groupName]-[volumeName-swap]
  • mkfs.btrfs -L [partitionName] -n 16k /dev/mapper/[groupName]-[volumeName-root] -f
  • mount -o compress=lzo /dev/mapper/[groupName]-[volumeName-root] /mnt
  • btrfs fun basics
    • btrfs subvolume create /mnt/root
    • btrfs subvolume create /mnt/home
    • btrfs subvolume create /mnt/snapshots
    • mount -t btrfs -o subvol=root /dev/mapper/[groupName]-[volumeName-root] /mnt/root
    • mount -t btrfs -o subvol=home /dev/mapper/[groupName]-[volumeName-root] /mnt/home
    • mount -t btrfs -o subvol=snapshots /dev/mapper/[groupName]-[volumeName-root] /mnt/snapshots
  • BOOT
    • NOT EFI:
      • mkdir /mnt/boot
      • mount /dev/[device]1 /mnt/boot
    • EFI:
      • mkdir /mnt/boot/efi -p
      • mount /dev/[device]1 /mnt/boot/efi
  • mkdir /mnt/var/backup/cryptsetup -p
  • cryptsetup luksHeaderBackup /dev/[device]2 --header-backup-file /mnt/var/backup/cryptsetup/[file].img
  • cryptsetup -v --header /mnt/var/backup/cryptsetup/[file].img open /dev/[device]2 test
  • mkdir /mnt/hostrun
  • mount --bind /run /mnt/hostrun
  • blkid
  • pacstrap /mnt base base-devel nano grml-zsh-config python ansible cups docker clamav firejail firewalld fail2ban gdisk rsync btrfs-progs dosfstools etckeeper os-prober grub snapper git htop hwinfo reflector acpid cpupower ldns linux linux-firmware dhcpcd minikube mkinitcpio libpwquality lvm2 neofetch gnome-keyring mc networkmanager expat ntfs-3g powertop power-profiles-deamon sshfs subversion tinyssh tinyssh-convert polkit p7zip zip unrar unarchiver lzop lrzip elinks [cpu]-ucode
  • genfstab -pU /mnt >> /mnt/etc/fstab
  • nano /mnt/etc/fstab
    • compress=lzo (check on /)
    • tmpfs /tmp tmpfs defaults,noatime,mode=1777,size=32G 0 0
  • arch-chroot /mnt /bin/zsh

chroot

  • ln -s /usr/share/zoneinfo/[Region]/[City] /etc/localtime -f
  • hwclock --systohc --utc
  • timedatectl set-ntp true
  • nano /etc/locale.gen
    • en_US.UTF-8
  • echo LC_ALL=C.UTF-8 >> /etc/locale.conf
    • arch linux wiki says the .UTF-8 alteration won't override LANG=
  • echo LANG=en_US.UTF-8 >> /etc/locale.conf
  • echo LANGUAGE=en_US >> /etc/locale.conf
  • echo LC_ALL=C >> /etc/profile
  • Chose our own: echo KEYMAP=de-latin1-nodeadkeys >> /etc/vconsole.conf
  • echo FONT=lat9w-16 >> /etc/vconsole.conf
  • locale-gen
  • export LANG=en_US.UTF-8
  • export EDITOR=nano
  • echo '[hostname]' > /etc/hostname
  • echo '127.0.0.1 localhost' >> /etc/hosts
  • echo '::1 localhost' >> /etc/hosts
  • echo '127.0.1.1 [hostname].localdomain [hostname]' >> /etc/hosts
  • nano /etc/pacman.conf
    • Check configs + multilib (if not on ARM)
  • pacman -Sy
    • IF EFI: pacman -Sy efibootmgr
  • reflector -c Switzerland --latest 10 --protocol https --sort rate --save /etc/pacman.d/mirrorlist
    • Why Switzerland instead of Germany, even though GDPR+? Find it out yourself.
  • pacman -Syyy
  • passwd (for our current root user)
  • add how many you want/need
    • useradd -m -g users -G wheel,docker,storage,power,lp -s /bin/bash [user]
    • passwd [user]
    • if you want to change their languages, per user execute
      • nano ~/.config/locale.conf
      • add e.g. LANG=en_GB.UTF-8
  • nano /etc/sudoers.d/sudoers
    • [user] ALL=(ALL) ALL
      • add how many you want/need
  • dd bs=512 count=80 if=/dev/urandom of=/crypto_keyfile.bin iflag=fullblock
  • cryptsetup luksAddKey /dev/[device]2 /crypto_keyfile.bin

mkinitcpio

  • nano /etc/mkinitcpio.conf
    • MODULES=(ext4 btrfs)
      • Do not forget to also add amdgpu, (nvidia nvidia_modeset nvidia_uvm nvidia_drm) or i915, if present
      • GPU modules:
        • AMD: pacman -S xf86-video-amdgpu
        • NVIDIA: pacman -S nvidia
          • echo 'options nvidia-drm modeset=1' > /etc/modprobe.d/nvidia-drm-nomodeset.conf
        • Intel (i915): pacman -S xf86-video-intel
    • FILES=(/crypto_keyfile.bin)
    • HOOKS=(base systemd autodetect microcode modconf block keyboard keymap filesystems fsck sd-encrypt lvm2)
      • If SERIAL CONSOLE:
        • We will need to return to this at a later point, after we finish the initial setup (see 01-extras-arch-linux-2024.md file), using the AUR package mkinitcpio-systemd-extras and yay, our beloved AUR community package manager
  • mkinitcpio -p linux
    • If you got the issue that /boot/vmlinuz-linux is not found, when mkinicpio, after e.g. switching from NON UEFI to UEFI, just re-issue pacman -S linux

bootloader

  • chmod 600 /crypto_keyfile.bin
  • chmod 600 /boot/vmlinuz-linux
  • chmod 600 /boot/initramfs-linux*
  • chmod 600 /boot/*-ucode.img
  • chmod -R g-rxw,o-rwx /boot
  • cryptsetup luksDump /dev/[device]2
  • nano /etc/default/grub
    • Replace [device]xs/[enc_x]s with correct UUID (get from blkid)

    • GRUB_TIMEOUT=3
    • GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 console=tty0 console=ttyS0,115200n8 quiet"
      • IF NOT Serial Console: Remove console=tty0 console=ttyS0,115200n8 (don't forget to not set GRUB_TERMINAL and GRUB_SERIAL_COMMAND
      • IF NVIDIA GPUs you might want to add nvidia-drm.modeset=1 to GRUB_CMDLINE_LINUX_DEFAULT
    • GRUB_CMDLINE_LINUX="rd.luks.name=[uuid_device2]=arch2024 rd.luks.options=[uuid_device2]=discard,password-echo=no rd.lvm.lv=[groupName]/[groupName]-[volumeName-root] rd.lvm.lv=[groupName]/[groupName]-[volumeName-swap] resume=UUID=[enc_swap] root=UUID=[enc_root]"
      • for Intel (i915) GPUs you might want to add fsck.mode=force acpi_osi='!Windows 2012' i915.enable_psr=1 i915.enable_fbc=1 i915.lvds_downclock=1 to GRUB_CMDLINE_LINUX
        • See here for more about these params
      • Decryption via Key?
        • Amend to: rd.luks.options=[uuid_device2]=discard,password-echo=no,keyfile-timeout=10s
        • Add rd.luks.key=[uuid_device2]=/crypto_keyfile.bin, after rd.lvm.lv.... and rd.luks.options... parts, if you do not want to type twice
        • Next, if you want to specify a key on another (encrypted) device's storage, you need to use rd.luks.key=[uuid_disk2]=/crypto_keyfile.bin:UUID=[uuid_device], instead of just rd.luks.key=[uuid_disk2]=/crypto_keyfile.bin
          • Yes, the UUID set here needs to be the one of the /dev/mapper/[groupName]-[volumeName] one, not it's partition if it is another LUKS encrypted storage
        • Also, if you want to decrypt more than one device, it's enough to set at least their rd.luks.name= and it's rd.luks.options=
    • GRUB_PRELOAD_MODULES="part_gpt part_msdos cryptodisk luks2 lvm"
    • IF /boot is on a Full Disk Encyption/EFI setup uncomment:
      • GRUB_ENABLE_CRYPTODISK=y
    • IF Serial Console add:
      # Serial Console
      GRUB_TERMINAL=serial
      GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"
      
    • IF Serial Console add:
      • GRUB_TERMINAL_INPUT=console
    • IF GUI set a maximum (too high resolutions can emphasize heavy lagging):
      • GRUB_GFXMODE=1920x1080x24
  • Install to /boot:
    • IF NOT EFI: grub-install /dev/[device] --target=i386-pc --bootloader-id=arch_bios --recheck
    • IF EFI: grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=arch_uefi --recheck
      • Check with efibootmgr -v if your arch_uefi is now listed (you can name it whatever you want, basically - would not use spaces (_ instead :P) though
      • If you cannot trust it as well: efibootmgr -c -d /dev/[device]1 -p 1 -l /EFI/arch_uefi/grubx64.efi -L "arch_uefi"
      • Still doesn't work out for you? Check within Arch Linux Wiki, UEFI v2.2 Specification or:
        • Take a note of your UUID in the efibootmgr -v
        • Reboot to UEFI Shell (bundled with your Arch Linux Live USB.. maybe you need to enable USB Legacy Mode for it to show)
        • Take a look at the mountable's log / utilize map -b
        • Search for your matching UUID
        • Check current setup: bcfg boot dump -v
        • You need to use the next possible number (X) and your corresponding device ID (FSY):
          • bcfg boot add X FSY:\EFI\arch_uefi\grubx64.efi "Arch Linux"
        • New kids on the block (replace X): bcfg boot mv X 0
  • grub-mkconfig -o /boot/grub/grub.cfg

networking

  • Check Internet status:
    • ip a
    • systemctl enable systemd-networkd.service
    • networkctl list, take note of your interface
    • nano /etc/systemd/network/20-wired.network
      • Ethernet, with DHCP
        [Match]
        Name=[name_of_interface]
        
        [Network]
        DHCP=yes
        
      • Ethernet, without DHCP
        [Match]
        Name=[name_of_interface]
        
        [Network]
        Address=[host_ipaddress]/24
        Gateway=[router_ipaddress]
        DNS=[host_ipaddress_?]
        
      • WLAN, yuck, with DHCP (needs wpa_supplicant or iwd installed)
        [Match]
        Name=[name_of_wlan_interface]
        
        [Network]
        DHCP=yes
        IgnoreCarrierLoss=3s
        
      • WLAN, yuck, without DHCP (needs wpa_supplicant or iwd installed)
        [Match]
        Name=[name_of_wlan_interface]
        
        [Network]
        Address=[host_ipaddress]/24
        Gateway=[router_ipaddress]
        DNS=[host_ipaddress_?]
        IgnoreCarrierLoss=3s
        
    • systemctl restart systemd-networkd.service

Finalizing

  • systemctl enable cups.service
  • systemctl enable reflector.timer
  • IF SSD/NVM: systemctl enable fstrim.timer
  • IF EFI:
    • We need to patch the Grub Image:
    • Copy result of for [ID]: lsblk -no TYPE,UUID /dev/[device]2 | awk '$1=="part"{print $2}' | tr -d -
      • If it does not show any result, it's just the UUID of your /dev/[device]2, but without the - (dashes), which you got when you used your initial blkid
    • nano /boot/grub/grub-pre.cfg
    • Replace id and names here:
      set crypto_uuid=[ID]
      cryptomount -u $crypto_uuid
      set root=lvm/[groupName]-[volumeName-root]
      set prefix=($root)/boot/grub
      insmod normal
      normal
      
    • grub-mkimage -p /boot/grub -O x86_64-efi -c /boot/grub/grub-pre.cfg -o /tmp/grubx64.efi part_gpt part_msdos cryptodisk luks2 lvm gcry_rijndael pbkdf2 gcry_sha256 gcry_sha512 btrfs && install -v /tmp/grubx64.efi /boot/efi/EFI/arch_uefi/grubx64.efi
      • Guessing: If there is anybody who wants to try it for i386-pc, you probably need to go with core.img instead of grubx64.efi and just target /boot/grub instead of /boot/efi/efi/arch_uefi
  • exit
  • umount -R /mnt
  • swapoff -a
  • reboot now

--- Finished ---

Extras

tested but without warranty

Beware of values in []


Enable SSH-Server for Host

  • Login as Root
  • nano /etc/ssh/sshd_config
    • Change Port?
    • Uncomment HostKey /etc/ssh/ssh_host_ed25519_key
    • Uncomment and set it to 12 -MaxAuthTries 12
    • Uncomment PubkeyAuthentication yes
  • systemctl enable sshd.service
  • systemctl start sshd.service
  • AND systemctl restart sshd.service to set new ssh host key correctly
  • Now ssh-copy-id over any of your client's keys to this host if there are any:
    • To create one on your clients:
      • ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/id_[client_name] -C "comment@host"
    • ssh-copy-id -i ~/.ssh/[filename].pub -p [port] [username]@[ipv4address]
    • Afterwards, on our host, that we currently setup:
      • nano /etc/ssh/sshd_config
      • PasswordAuthentication no
      • systemctl restart sshd.service
    • Now you can only login via Public Key from any client to this host

Create SSH keys for Your Host

  • Create Local SSH keys for Root
    • ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/id_[NAME] -C "[COMMENT]"
      • Use strong Passphrase (256+ Chars; KeePassXC)
      • chmod 0644 ~/.ssh/id_*.pub
    • eval $(ssh-agent)
    • ssh-add ~/.ssh/id_[NAME]
      • Enter Passphrase
  • Login as Root > User
    • ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/id_[NAME] -C "[COMMENT]"
      • Use strong Passphrase (256+ Chars; KeePassXC)
      • chmod 0644 ~/.ssh/id_*.pub
    • eval $(ssh-agent)
    • ssh-add ~/.ssh/id_[NAME]
      • Enter Passphrase
  • Exit back to being Root

Store SSH Keys On First Usage

  • nano ~/.ssh/config
    • AddKeysToAgent yes

Setup yay

  • Login as Root > User
  • cd /tmp
    • git clone https://aur.archlinux.org/yay.git
    • cd yay
    • makepkg -si
    • cd ..

temporary files are stored in cd /home/[USER]/.cache/yay

Autojump Me Pls

  • yay -S autojump
  • echo '[[ -s /etc/profile.d/autojump.sh ]] && source /etc/profile.d/autojump.sh' >> ~/.bashrc

GRUB Themes

If you want to play around with "klickibunti":

  • grub-themes-solarized-dark-materialized Link
    • yay -S grub-themes-solarized-dark-materialized
    • sudo nano /etc/default/grub
      GRUB_THEME=/boot/grub/themes/solarized-dark-materialized/theme.txt
      
  • grub-theme-cyberre Link
    • yay -S grub-theme-cyberre
    • sudo cp -r /usr/share/grub/themes/CyberRe /boot/grub/themes/.
      GRUB_THEME=/boot/grub/themes/CyberRe/theme.txt
      
    • Do not forget to copy over changes, everytime the Theme gets an update... (why PKGBUILD of pkg...)
  • Last step: grub-mkconfig -o /boot/grub/grub.cfg

Enable Secure NTP

As long as the regular ntp package does (STILL) not support this:

  • yay -S ntpsec and replace the regular one at the end (conflict with old one)
    • A gpg key import is probably necessary
  • After installation enable the service: sudo systemctl enable ntpd.service
  • sudo systemctl start ntpd.service
  • Check that the service starts
  • Now let's amend the protocol:
  • sudo nano /etc/ntp.d/use-pool
    • Current approach:
      • Replace all (by default) pool X.arch.pool.ntp.org iburst naming scheme entries with one pool time.cloudflare.com nts entry
    • Future approach:
      • Search for pool and iburst
      • If you did not change your settings previously you will find about 4 entries in naming scheme pool X.arch.pool.ntp.org iburst
      • Switch iburst to nts
      • (You may want to change the server aswell if you know of any other trustworthy one, apublic domain on is X.pool.ntp.org)
  • sudo systemctl restart ntpd.service

There can also be found an extensive list thanks to @mutin-sa about multiple available public time servers.

Also there are more information about more official ntpSec servers on docs.ntpsec.org.

Notice: Using server time.cloudflare.com nts is currently(?) causing issues so better stick with the pool identifier in the front.

Enable remote ssh system drive decryption on Boot level

State of this article's partial: 2023-08

This time host is referring to other devices, those which want to connect to the device we just setup (this time called client).

This is also what the Serial Console setup partial up top was referring to, where we wanted to pick up stuff again, after the initial boot into Arch after the setup is finished.

Setup SSH On Boot

This setup will not feature you wanting to decrypt multiple devices.

For this you need to use /etc/crypttab + /etc/fstab in combination, example

HOST

Like already introduced above, let's create a new SSH key on your host, if you have not done so already:

  • ssh-copy-id -i ~/.ssh/[filename].pub -p [port] [username]@[ipv4address]
CLIENT

On the device we have just setup, let's continue where we left off after the boot into our encrypted Arch Linux that we have just setup.

While you need to login as "root", we will be able to provide other authorized keys within the authentication process on boot.

While doing this setup and test the functionallity afterwards, be sure to first test your login via Public Keys and, if that is working, temporarily comment out the PasswordAuthentication no for OpenSSH (should you be using it).

  • nano /etc/ssh/sshd_config

  • Login as Root > User

  • yay -Sy busybox tinyssh tinyssh-convert mkinitcpio-systemd-extras

  • exit to being Root again

    • We now need to edit the mkinitcpio hooks:
      • nano /etc/mkinitcpio.conf
      • Add sd-network sd-tinyssh before sd-encrypt:
        • HOOKS=(base systemd autodetect modconf block keyboard keymap filesystems fsck sd-network sd-tinyssh sd-encrypt lvm2)
      • Also add to the end of the file:
        • # Allow TinySSH Remote SSH Login On Boot
            SD_NETWORK_CONFIG=/etc/systemd/network-initramfs
          SD_TINYSSH_COMMAND="systemd-tty-ask-password-agent --query --watch"
            # change SSH port to something else
            SD_TINYSSH_PORT=222
            # use authorized keys of some other user, instead of root
            SD_TINYSSH_AUTHORIZED_KEYS="/home/[user]/.ssh/authorized_keys"				
          
      • mkdir /etc/systemd/network-initramfs
      • cp /etc/systemd/network/20-wired.network /etc/systemd/network-initramfs
      • nano /etc/systemd/network-initramfs/20-wired.network
        • Now, rename the network interface to match its name while booting, so not the one udev gives it
          • You can find that one out by issuing dmesg | grep renamed while your client is booted
    • Now, some user SSH key stuff:
      • As you should have authorized_keys for any of your (normal) users by now, all of those keys need to be copied over to the authorized_keys of root, if not already present/keys are differing:
        • cat /home/[username]/.ssh/authorized_keys >> ~/.ssh/authorized_keys
    • Then mkinitcpio -p linux

Do not forget to always mkinitcpio -p linux when you change stuff to your systemd-networkd configurations (/etc/systemd/network)!

Using SSH On Boot

You should want to directly test out your setup now.

We should have everything configured and installed correctly, for systemd-networkd to create a network connection (sd-network), tinyssh being presented on port 22 (sd-tinyssh) and just the luks/lvm passphrase dialogue being presented on a successful SSH connection (SD_TINYSSH_COMMAND).

Therefore, on your client, issue reboot now after you have finished up everything.

HOST

Wait for a bit (as long as you need to wait until you know your device is ready for your device decryption passphrase and before any timeout):

  • ssh root@[client-ipaddress]
  • Enter your device decryption passphrase
  • Wait until decryption + boot process are over
  • Login via your correct user + (openssh) port
Client

Do not forget to comment in PasswordAuthentication no again!

  • nano /etc/ssh/sshd_config

Disable Beep

As root:

  • echo "blacklist pcspkr" | tee /etc/modprobe.d/nobeep.conf

For good measure:

  • nano /etc/profile.d/disable-beep.sh
    • setterm -blength 0

Backlight Brightness

Under some circumstances there can be issues related to Notebooks with Intel/AMD iGPUs in relation to backlight brightness.

You can try to issue one of the following commands via terminal to higher the correct brightnes value to the max.

AMD iGPU

  • Check for max brightness
    • cat /sys/class/backlight/amdgpu_bl0/max_brightness
  • Set value
    • echo 255 > /sys/class/backlight/amdgpu_bl0/brightness

Intel iGPU

  • Check for max brightness
    • cat /sys/class/backlight/intel_backlight/max_brightness
  • Set value
    • echo 255 > /sys/class/backlight/intel_backlight/brightness

2FA

Authentication can be done via additional 2FA methods these days, thanks to systemd v248 back in 2021.

Two good reads might be these two articles:

Having said this, does it make stuff safer?

You may decide that for youself - or do you got an evil maid?

You need to get touchy with multiple of those USB tokens, so use a slot you can(not) reach easily for the (initial) setup

Let's start.

Nitrokey

nitrokey-app and nitrocli have done nothing for me to use the key, so I opted for the official Python package + Guide:

So, anyway.. we will cover this now as well.

This guide will use a Nitrokey 3 (Mini) (nk3) as an example, as it supports FIDO2 and it's basically (at the time of writing this part) the newest product.

  • pacman -S libfido2 python-pipx
  • You need to add ~/.local/bin to your SHELL
    • try pipx ensurepath
    • Alternatives:
      • Fish Shell:
        • You should add set PATH "$HOME/.local/bin:$PATH" >> ~/.config/fish/config.fish
    • Reload your shell/re-login
  • pipx install pynitrokey
  • Check if yours is getting found now (might need to reboot?)
    • UDev Rules are necessarry:
      • curl https://raw.githubusercontent.com/Nitrokey/libnitrokey/master/data/41-nitrokey.rules >> /etc/udev/rules.d/41-nitrokey.rules
      • udevadm control --reload-rules && udevadm trigger
      • Only NOW you should plugin your NitroKey (again)
    • systemd-cryptenroll --fido2-device=list
    • nitropy list (hmmmn...)
      • Firmware Update
        • Check: nitropy nk3 version
          • Use nitropy nk3 --path /dev/hidrawXY version if you have multiple Nitrokeys plugged in
        • Update: nitropy nk3 update
          • You need to TOUCH it (the metal part) :-D
        • try if key is back nitropy list
    • Now check your Nitrokey:
      • nitropy nk3 test
        • Time to get touchy again~ :-D
  • Now we can add a key to the LUKS Keys slot of our device:
    • systemd-cryptenroll --fido2-device=/path/to/fido2_device /dev/[device]2
      • Time to get touchy again~ :-D
        • Troubleshooting:
          • Failed to load LUKS2 superblock: Invalid argument
            • Like I wrote at the start of this section it needs to be a LUKS2 encrypted device, not a LUKS1 one

            • cryptsetup convert /dev/[device]2 --type luks2, but it shan't be mounted or unencrypted
              • BUT this might cause issues with GRUB, you have been warned :-)
    • Your Nitrokey FIDO2... key... will now be added to your LUKS Key Slots (see a "FIDO2 token enrolled as key slot XY"?)
    • If you want to unlock a device based on if your Nitrokey is present or not, you need to add fido2-device=auto to your rd.luks.options=[uuid_device2] options
      • Of course you could also use a specific device (fido2-device=/dev/hidrawXY) if you are absolutely certain it's always the same ID

GUI

tested but without warranty

Beware of values in []


If you ever want to add GUI, because you changed how you access the stoage medium inside your device, you might be inclined to start using Cinnamon. Also sddm might just be your thing.

This requires that 'xorg' is running fine on your device, obviously.

Also including Android additions.

Disable serial console access

First get to the point where you are logged in to your device.

  • nano /etc/default/grub
    • # Serial Console
      GRUB_TERMINAL=serial
      GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"
      
    • #GRUB_TERMINAL_INPUT=console
  • grub-mkconfig -o /boot/grub/grub.cfg

Install necessary (Login) GUI stuff

  • GPU
    • This expects you to have already installed all the necessary packages from back in the installation / mkinitcpio.conf step
    • pacman -S mesa lib32-mesa mesa-vdpau lib32-mesa-vdpau vdpauinfo lib32-libvdpau lib32-mesa-demos vulkan-mesa-layers
    • AMD: pacman -S opencl-mesa vulkan-radeon lib32-vulkan-radeon
    • NVIDIA: pacman -S nvidia-utils nvidia-settings egl-wayland opencl-nvidia lib32-opencl-nvidia
      • mkdir /etc/pacman.d/hooks
      • nano /etc/pacman.d/hooks/nvidia.hook
        [Trigger]
        Operation=Install
        Operation=Upgrade
        Operation=Remove
        Type=Package
        Target=nvidia
        Target=linux
        
        [Action]
        Description=Update Nvidia module in initcpio
        Depends=mkinitcpio
        When=PostTransaction
        NeedsTargets
        Exec=/bin/sh -c 'while read -r trg; do case $trg in linux) exit 0; esac; done; /usr/bin/mkinitcpio -P'
        
      • nano /etc/X11/xorg.conf.d/10-nvidia-drm-outputclass.conf
        Section "OutputClass"
            Identifier "intel"
            MatchDriver "i915"
            Driver "modesetting"
        EndSection
        
        Section "OutputClass"
            Identifier "nvidia"
            MatchDriver "nvidia-drm"
            Driver "nvidia"
            Option "AllowEmptyInitialConfiguration"
            Option "PrimaryGPU" "yes"
            ModulePath "/usr/lib/nvidia/xorg"
            ModulePath "/usr/lib/xorg/modules"
        EndSection
        
      • For each user: nano ~/.xinitrc
        xrandr --setprovideroutputsource modesetting NVIDIA-0
        xrandr --auto
        
    • Intel: pacman -S vulkan-intel lib32-vulkan-intel
  • DM
    • Cinnamon pacman -S cinnamon cinnamon-control-center cinnamon-desktop cinnamon-menus cinnamon-screensaver cinnamon-session cinnamon-settings-daemon cinnamon-translations cjs dconf-editor gnome-backgrounds gnome-common gnome-desktop gnome-disk-utility gnome-epub-thumbnailer gnome-font-viewer gnome-keyring gnome-screenshot gnome-settings-daemon gnome-terminal gnome-themes-extra gnome-tweaks muffin nemo nemo-fileroller nemo-image-converter nemo-preview nemo-python nemo-seahorse nemo-share nemo-terminal xorg
      • yay -S mintlocale (mintlocale results in timeout)
    • KDE pacman -S plasma plasma-wayland-session kde-applications
      • yay -S breath2-git
  • pacman -S sddm sddm-kcm udisks2 arc-gtk-theme arc-solid-gtk-theme gnome-icon-theme-extras adwaita-icon-theme breeze-icons gtk-update-icon-cache hicolor-icon-theme innoextract kemoticons kiconthemes oxygen-icons icoutils ttf-font-awesome gvfs gvfs-gphoto2 gvfs-mtp gvfs-nfs gvfs-smb libgphoto2 libcddb libmtp android-tools android-file-transfer mtpfs audacious firefox mplayer pinta thunderbird virtualbox virtualbox-guest-iso virtualbox-guest-utils vlc keepassxc xclip wl-clipboard brightnessctl vlc streamlink networkmanager nm-connection-editor network-manager-applet networkmanager-openconnect networkmanager-openvpn networkmanager-pptp network-manager-sstp system-config-printer
    • virtualbox does AFAIK currently not run on ARM, so remove them (there will be others though, until here)
    • systemctl enable sddm.service
  • yay -S maia-icon-theme plasma5-themes-maia sddm-maia-theme vertex-themes go-mtpfs-git jmtpfs
  • Take your pick:
    • yay -S jdownloader2 meowsql heidisql mpv-full-git tor-browser libappimage terminator terminology zeal nerd-fonts-meta android-sdk-build-tools android-studio autofs bluez-plugins bluez-utils etcher-bin exfat-utils filezilla flips fontforge g910-gkeys-git gitflow-avh gogglesmm gogh-git hdparm sdparm hlsdl httraqt inetutils inkscape insomnium-bin jfsutils k3b cdrdao cdrtools dvd+rw-tools kleopatra kubelet lazydocker libreoffice-fresh-en-gb man-pages mkcert mongodb mongodb-tools mongodb-compass mvt mysql-workbench netctl nfs-utils nmap nvtop otf-fira-sans otf-ipafont p7zip-gui pavucontrol phpstorm phpstorm-jre pince-git poedit profile-sync-daemon protontricks protonup-git pycharm-professional postman-bin podman-desktop opentofu-bin qmplay2 rclone redis screen session-desktop-bin sidewinderd skaffold-bin smbnetfs soundkonverter syncthing tcpdump timeshift ttf-delugia-code ttf-hanazono ttf-meslo ttf-sazanami ttf-tahoma ttf-vista-fonts ungoogled-chromium-bin ventoy vertex-themes vi virtualgl vpnfailsafe-git webstorm webstorm-jre wireframesketcher wireshark-qt xdelta3
    • You probably need to import key for tor-browser
    • Timeouts - before installing blindly, check latest packages versions:
      • automoc4 (dependency of gogh-git)
        • cd ~/.cache/yay/automoc4/src/
        • wget https://download.kde.org/stable/automoc4/0.9.88/automoc4-0.9.88.tar.bz2
      • httraqt
        • cd cd ~/.cache/yay/httraqt/src/
        • wget https://freefr.dl.sourceforge.net/project/httraqt/httraqt-1.4.9.tar.gz
      • ungoogled-chrome
        • cd ~/.cache/yay/ungoogled-chromium/src/
        • wget https://codeload.github.com/foutrelis/chromium-launcher/tar.gz/v8 && mv v8 chromium-launcher-8.tar.gz
      • wireframesketcher
        • cd ~/.cache/yay/wireframesketcher/src/
        • wget https://cdn.wireframesketcher.com/studio/dist/WireframeSketcher-6.3.3_amd64.deb
      • ttf-meslo
  • Disable automatically spawning speech dispatcher
    • nano /etc/speech-dispatcher/speechd.conf
      • Search for DisableAutoSpawn and uncomment

SDDM

  • mkdir /etc/sddm.conf.d
  • cp /usr/lib/sddm/sddm.conf.d/default.conf /etc/sddm.conf.d/00-custom.conf
  • nano /etc/sddm.conf.d/00-custom.conf
  • Amend:
    • Numlock=On
    • HideShells=bash
    • HideUsers=root,nginx,php,kubernetes,docker,www-data
    • If matching for your display:
      • EnableHiDPI=true
  • Define your own customs:
    • nano /etc/X11/xorg.conf.d/00-keyboard.conf
      Section "InputClass"
              Identifier "system-keyboard"
              MatchIsKeyboard "on"
              Option "XkbLayout" "de"
              Option "XkbModel" "pc104"
              Option "XkbVariant" "nodeadkeys"
      EndSection
      
    • IF NVIDIA GPU:
      • nano /usr/share/sddm/scripts/Xsetup
        # add
        xrandr --setprovideroutputsource modesetting NVIDIA-0
        xrandr --auto
        

Stream Twitch via VLC

  • streamlink -p vlc https://www.twitch.tv/[channel_name] 1080p60

GPG Keyserver

Maybe you want to set a specific Keyserver by default?

  • echo 'hkps://keys.openpgp.org' >> ~/.gnupg/dirmngr.conf

Stop GPG Agent Window forcing

Obv. only for your current user.

  • nano ~/.gnupg/pgp-agent.conf
    • default-cache-ttl 300
      max-cache-ttl 999999
      
      no-grab
      
      # PIN entry program
      # pinentry-program /usr/bin/pinentry-curses
      # pinentry-program /usr/bin/pinentry-qt4
      # pinentry-program /usr/bin/pinentry-kwallet
      
      pinentry-program /usr/bin/pinentry-gtk-2
      

JetBrains Products

If you are using and sintalling JetBrains products, like PhpStorm, WebStorm, Android Studio, PyCharm or [...] you might want to check out these commands if you are using e.g. fish shell, because of r/w issues.

Execute as your own user, not root (due to copying of files)

Example for webstorm:

  • sudo chown -R root:www-data /opt/phpstorm/plugins/terminal
  • sudo chmod 0775 -R /opt/phpstorm/plugins/terminal
  • cp -r ~/.config/fish/. /opt/phpstorm/plugins/terminal/fish/

Of course you could also ln -s instead of copying.. up to you :)

Settings I did apply:

webstorm-terminal-shell-integration-settings

Addendum

Force Password Quality

  • echo 'minlen = 32' >> /etc/security/pwquality.conf.d/00-custom.conf

LUKS PV Header Outdated With grub-mkconfig

If you ever run into some notice like PV /dev/mapper/luks-[UUID] in VG [xyz] is using an old PV header, modify the VG to update., just run vgck --updatemetadata [xyz] (replace [xyz] with the related name). Manpage for vgck(8).

I have not looked deeper into it, but do not forget, that SSDs shrink.

Databases

MariaDB

'cuz why would you ever go back to MySQL?

  • pacman -S mariadb
  • mariadb-install-db --user=mysql --basedir=/usr --datadir=/var/lib/mysql
  • As FS is btrfs: chattr +C /var/lib/mysql
  • systemctl enable mariadb.service
  • systemctl start mariadb.service
  • mysql -u root -p
    • Default password is empty
  • For more see Arch Linux Wiki - MariaDB

PostgreSQL

  • pacman -S postgresql postgresql-old-upgrade
  • chattr +C /var/lib/postgres/data
  • For more check Arch Linux Wiki

Docker Me Good

  • pacman -S docker-compose
  • systemctl enable docker.service
  • systemctl start docker.service

And yeah, that's already it - you should have already addded your User to the docker group earlier.

And like the Arch Linux Wiki says:
Do not forget that all users, that are part of the docker group, can use docker run --privileged.
You have been warned.

Minikube

  • minikube addons enable ingress

Don't ever forget (if used via e.g. podman-desktop):

  • eval $(minikube docker-env)

Also, when used via, e.g., podman-desktop, do not forget to append --profile=%profile_name%

Composer And PHP

You should prefer using a docker-only setup of PHP by now.

Stop doing this on bare metal..

  • yay -S composer php-cgi php-fpm php-gd php-imap php-mongodb php-pgsql php-phpdbg php-sodium php-sqlite php-tidy php-redis php-xsl php-intl php-odbc xdebug nginx

  • For v8.0 compatiblity options: yay -S php80-cgi php80-fpm php80-gd php80-imap php80-intl php80-pgsql php80-phpdbg php80-sodium php80-sqlite php80-tidy php80-redis php80-xsl php80-intl php80-odbc

  • For v7.4 compatiblity options: yay -S php7-cgi php7-fpm php7-gd php7-imap php7-intl php7-pgsql php7-phpdbg php7-sodium php7-sqlite php7-tidy php7-redis php7-xsl php7-intl php7-odbc

  • Shells:

    • Bash: echo 'export PATH="$PATH:$HOME/.config/composer/vendor/bin"' >> ~/.bashrc
    • Fish: echo 'set PATH "$HOME/.config/composer/vendor/bin:$PATH"' >> ~/.config/fish/config.fish
  • sudo groupadd www-data

  • sudo mkdir -p /var/{www/private,www/customers,vms}

  • sudo useradd -r -s /usr/bin/nologin www

  • sudo usermod -aG www-data www

    • Do not forget about adding you own user to the group as well
  • sudo chown -R root:www-data /var/vms

  • sudo chown -R root:www-data /var/www

  • sudo chmod 0775 -R /var/vms

  • sudo chmod 0775 -R /var/www (only do that on a system that is not online!)

  • sudo nano /etc/php/php-fpm.d/00-custom.conf

    ; /etc/php/php-fpm.d/00-custom.conf
    [global]
    pid = /run/php-fpm/php-fpm.pid
    error_log = /var/log/php-fpm/php-fpm_error.log
    log_level = notice
    emergency_restart_threshold = 5
    emergency_restart_interval = 360s
    [www] 
    listen = /var/run/php-fpm/php-fpm.sock  ; listen to unix socket
    ;listen = 9000                           ; listen to TCP 9000
    ;listen = 127.0.0.1:9000                 ; listen to port 9000 on 127.0.0.1
    listen.backlog = 65535
    listen.owner = www
    listen.group = www-data
    listen.mode = 0775                      ; never set this on a system that is online, duh
    listen.allowed_clients = 127.0.0.1
    pm = dynamic
    pm.max_children = 5
    pm.start_servers = 1
    pm.min_spare_servers = 1
    pm.max_spare_servers = 3
    
    • sudo mkdir /var/log/php-fpm
    • sudo chown -R root:www-data /var/log/php-fpm
    • sudo chmod 0775 -R /var/log/php-fpm
  • sudo nano /etc/php/conf.d/00-custom.ini

    ; /etc/php/conf.d/00-custom.ini
    [PHP]
    output_buffering = 4096
    max_execution_time = 360
    max_input_time = 360
    memory_limit = 2048M
    error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
    display_errors = On
    display_startup_errors = On
    log_errors = On
    log_errors_max_len = 8096
    ignore_repeated_errors = Off
    ignore_repeated_source = Off
    report_memleaks = On
    html_errors = On
    error_log = /var/log/php/php_errors.log
    post_max_size = 512M
    file_uploads = On
    upload_max_filesize = 512M
    max_file_uploads = 20
    allow_url_fopen = On
    default_socket_timeout = 360
    ; extensions
    extension=bcmath
    extension=bz2
    extension=calendar
    extension=iconv
    extension=intl
    extension=pdo_mysql
    extension=pdo_odbc
    extension=pdo_pgsql
    extension=pdo_sqlite
    extension=sockets
    extension=sodium
    extension=tidy
    extension=xsl
    [Date]
    date.timezone = Europe/Berlin
    
    • sudo mkdir /var/log/php
    • sudo chown -R root:www-data /var/log/php
    • sudo chmod 0775 -R /var/log/php
  • systemctl enable php-fpm.service

Laravel And Valet

  • yay -S xsel inotify-tools dnsmasq jq
  • composer global require laravel/installer
  • composer global require cpriego/valet-linux
  • valet install
  • nano ~/.valet/config.json
    • Change port to 8080 if 80 is in use and you cannot find out which process is using it / why
  • sudo nano /etc/nginx/sites-available/valet.conf
    • Change port to 8080 if 80 is in use and you cannot find out which process is using it / why
  • Checkout h5bp/server-configs-nginx
    • Love their nginx boilerplate
    • You might have issues with "double pid definitions".. maybe comment out the line within /etc/nginx/nginx.conf
    • If you use it, do not forget to change ports to 8080 within:
      • /etc/nginx/conf.d/no-ssl.default.conf
      • /etc/nginx/conf.d/templates/no-ssl.example.com.conf
    • You may have also issues with double bindings for the default server.
      • You need to choose if you want to take the definitions of /etc/nginx/sites-available/valet.conf or the one within /etc/nginx/conf.d/no-ssl.default.conf for port 80 as defaults.
  • sudo systemctl restart nginx.service
    • If you have forgotten something with port 80 and it is already bound, this will fail.

systemctl stop chimera-proxy.service if you have installed it (see further down below) or edit /etc/systemd/system/chimera-proxy.socket accordingly: ListenStream=8080

NPM And Packages

npm packages should already be within $PATH and executable after install if not, add "$HOME/.node/bin:$PATH" or so to your shell config file (look into it yourself, pls)

Be a normal user.

  • yay -S nvm
  • source /usr/share/nvm/init-nvm.sh
  • echo 'source /usr/share/nvm/init-nvm.sh' >> ~/.bashrc
  • "Reload" your shell
  • Check for versions:
    • nvm ls-remote
    • Maybe the latest:
      • nvm install latest
      • nvm use latest
    • Or just go with some LTS (v18.X):
      • nvm install lts/hydrogen
      • nvm use lts/hydrogen
    • echo 'latest' > ~/.nvmrc
  • npm create vue@latest
  • npm install -g @ionic/cli

Shell Me Good

We already opted for zsh in the installation, also because it comes with Arch Linux installation by default now, but I will also feature fish - as both are superb.

Do not forget that you need to replicate most of the steps per user. For example the fisher installs need to be done for every user, yay commands (obviously) not.

ZSH

  • yay -S oh-my-zsh-git k zsh-syntax-highlighting-git zsh-autocomplete-git zsh-theme-powerlevel10k-git

  • Config ~/.zshrc (mainly taken from Fernando Cejas' blog - not even sure if all plugins are present):

    # Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc.
    # Initialization code that may require console input (password prompts, [y/n]
    # confirmations, etc.) must go above this block; everything else may go below.
    if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
      source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
    fi
    
    # Path to your oh-my-zsh installation.
    ZSH=/usr/share/oh-my-zsh/
    
    export DEFAULT_USER="[USER]"
    export TERM="xterm-256color"
    export ZSH=/usr/share/oh-my-zsh
    export ZSH_POWER_LEVEL_THEME=/usr/share/zsh-theme-powerlevel10k
    
    source $ZSH_POWER_LEVEL_THEME/powerlevel10k.zsh-theme
    
    # oh-my-zsh plugins
    plugins=(archlinux
            bundler
            docker
            jsontools
            tig
            gitfast
            colored-man-pages
            colorize
            command-not-found
            composer
            laravel
            cp
            dirhistory
            autojump
            sudo)
    
    # other plugins
    source /usr/share/zsh/plugins/k/k.plugin.zsh
    
    source /usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.plugin.zsh
    source /usr/share/zsh/plugins/zsh-autocomplete/zsh-autocomplete.plugin.zsh
    # /!\ zsh-syntax-highlighting and then zsh-autosuggestions must be at the end
    
    source $ZSH/oh-my-zsh.sh
    
    # nvm - Node Version Manager
    source /usr/share/nvm/init-nvm.sh
    
    autoload -U add-zsh-hook
    load-nvmrc() {
      local node_version="$(nvm version)"
      local nvmrc_path="$(nvm_find_nvmrc)"
    
      if [ -n "$nvmrc_path" ]; then
        local nvmrc_node_version=$(nvm version "$(cat "${nvmrc_path}")")
    
        if [ "$nvmrc_node_version" = "N/A" ]; then
          nvm install
        elif [ "$nvmrc_node_version" != "$node_version" ]; then
          nvm use
        fi
      elif [ "$node_version" != "$(nvm version default)" ]; then
        echo "Reverting to nvm default version"
        nvm use default
      fi
    }
    add-zsh-hook chpwd load-nvmrc
    load-nvmrc
    
    # Uncomment the following line to disable bi-weekly auto-update checks.
    DISABLE_AUTO_UPDATE="true"
    
    ZSH_CACHE_DIR=$HOME/.cache/oh-my-zsh
    if [[ ! -d $ZSH_CACHE_DIR ]]; then
      mkdir $ZSH_CACHE_DIR
    fi
    
    source $ZSH/oh-my-zsh.sh
    
    # nvm - Node Version Manager
    source /usr/share/nvm/init-nvm.sh
    
    
    # To customize prompt, run `p10k configure` or edit ~/.p10k.zsh.
    [[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
    
    • Do not forget to overwrite [USER]

    • Also k, zsh-syntax-highlighting and zsh-autosuggestions seem not findable.. even through hard linking
  • zsh then p10k configure

  • Add your aliases (dotfiles)

  • chsh -s /usr/bin/zsh

Fish

  • cd /tmp
  • yay -S fisher fzf
  • If not in fish: fish
  • fisher install IlanCosman/tide jethrokuan/fzf jorgebucaran/fish-nvm sadanand-singh/fish-sodope edc/bass
  • If entered fish just now: exit
  • fish then tide configure
  • Add your aliases (dotfiles)
  • Add nvm use to e.g. your ~/.config/fish/config.fish
  • chsh -s /usr/bin/fish

Non Work Related

It's dangerous to walk alone, take these:

  • yay -S cemu ceserver chimera citra-git citra-qt-git desmume dolphin-emu-nogui-git fceux freetube-bin fusee-launcher-git gamemode higan lib32-gamemode libretro-beetle-psx-hw libretro-citra libretro-desmume libretro-gambatte libretro-mgba libretro-mupen64plus-next libretro-nestopia libretro-pcsx2 libretro-ppsspp libretro-flycast libretro-mame libretro-overlays libretro-scummvm libretro-shaders libretro-snes9x libretro-yabause lutris mumble proton-ge-custom-bin protonup-git python-magic qcma retroarch-assets-ozone retroarch-autoconfig-udev rpcs3-git ryujinx-ldn-bin steamos-compositor-plus vbam-wx yuzu-mainline-bin
    • Think there is something missing? Side packages load main, so no need to repeat, right?
    • NOT IN CHROOT - for steamos-compositor-plus:
      • Configration after first run can be found here: ~/.config/steamos-compositor-plus
    • NOT IN CHROOT - for Chimera:
      • sudo systemctl --user enable chimera.service && \
        sudo systemctl enable chimera-proxy.service && \
        sudo systemctl enable chimera-proxy.socket
        
      • Enable Patches: systemctl --user enable steam-patch
      • Later hit chimeraos.local in any Browser
      • Files are going to ~/.config/chimera/ and ~/.local/share/chimera

Custom Mounts

Depending on how you use custom mounts within your system:

  • mkdir /mnt/{backup,hdd,library,nas,usb}
  • chattr +C /mnt

Kwallet Set Up

No, this is a bit more tedious than with Gnome Keyring. Get your SSH Keys ready.

Don't be root, obviously.

  • Enable KWallet in KDE System Settings (access via e.g. Application Launcher / "Start Menu").
  • You may also look into Arch Linux Wiki about User Environment Variables to get a broader picture for it and deviate from the following approach.
  • Autostart script for KDE, adds all private SSH Keys
    • (remember password, when you asked for the first time)
    • nano ~/.config/autostart/ssh-add.desktop
      [Desktop Entry]
      Comment=
      Exec=zsh --extendedglob -c 'ssh-add -q ~/.ssh/id^*.pub < /dev/null'
      GenericName=
      MimeType=
      Name=ssh-add
      Path=
      StartupNotify=true
      Terminal=false
      TerminalOptions=
      Type=Application
      X-DBUS-ServiceName=
      X-DBUS-StartupType=
      X-KDE-AutostartScript=true
      X-KDE-SubstituteUID=false
      X-KDE-Username=
      
  • Autostart script to set SSH_ASKPASS (could also be done within e.g. ~/.pam_environment;
    • (GIT_ASKPASS inherits that value, don't bother with that)
    • nano ~/.config/plasma-workspace/env/sshaskpass.sh
      SSH_ASKPASS='/usr/bin/ksshaskpass'
      export SSH_ASKPASS
      
      • chmod +x ~/.config/plasma-workspace/env/sshaskpass.sh
  • Autostart script to set SSH_AUTH_SOCK (could also be done within e.g. ~/.pam_environment)
    • nano ~/.config/plasma-workspace/env/sshauthsocket.sh
      SSH_AUTH_SOCK=$XDG_RUNTIME_DIR/ssh-agent.socket
      export SSH_AUTH_SOCK
      
      • chmod +x ~/.config/plasma-workspace/env/sshauthsocket.sh
  • Setup your systemd user service that starts your agent on login
    • nano ~/.config/systemd/user/ssh-agent.service
      [Unit]
      Description=SSH key agent
      
      [Service]
      Type=simple
      Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
      ExecStart=/usr/bin/ssh-agent -D -a $SSH_AUTH_SOCK
      
      [Install]
      WantedBy=default.target
      
      • systemctl --user daemon-reload
      • systemctl enable --user ssh-agent.service
      • systemctl start --user ssh-agent.service
      • Check Status: systemctl status --user ssh-agent.service -l
  • You may change what does not seem appropriate for you, no?
  • Reboot, should work now (NON-CHROOT)

Clean Up Behind You

Outside Chroot

  • Every User: truncate -s 0 /mnt/home/[user]/.zsh_history
  • Every User: truncate -s 0 /mnt/home/[user]/.local/share/fish/fish_history
  • Every User: truncate -s 0 /mnt/home/[user]/.bash_history
  • truncate -s 0 /mnt/root/.zsh_history
  • truncate -s 0 /mnt/root/.local/share/fish/fish_history
  • truncate -s 0 /mnt/root/.bash_history

Inside Chroot

  • Every User: truncate -s 0 /home/[user]/.zsh_history
  • Every User: truncate -s 0 /home/[user]/.local/share/fish/fish_history
  • Every User: truncate -s 0 /home/[user]/.bash_history
  • truncate -s 0 /root/.zsh_history
  • truncate -s 0 /root/.local/share/fish/fish_history
  • truncate -s 0 /root/.bash_history

Fun Stuff

  • pacman -S catimg

Serial Console

Given that you might have a SoC Device that only is accessable via Serial Console, besides how to enable your Arch Linux on how to use this with tinyssh SSH + Enc on boot, we havn't handled how to access such a device via Serial Console yet.

  • Login as Root
  • usermod -aG uucp [username]
  • Logout/Reboot/Login if you were already logged in as that User
  • As that User
    • screen /dev/ttyUSB0 115200
      • (It depends on what speed you have setup, but it's the same number you have given within your GRUB setup)
  • You should now be greeted with whatever state your device is (already) in
  • Do not forget to ssh-copy-id your SSH Key to that device, before disabling password entries via PasswordAuthentication no within your /etc/ssh/sshd_config, if you want to securely login to it on Boot/SSH (tinyssh)

You can exit the screen bin/package via ctrl+a followed by ctrl+d, but you will need to remove/plugin again your USB serial console adapter if you want to connect again (or is there another trick?).

Troubleshooting

Limited Internet

You should go for this if you have not enabled/use NetworkManager.service or systemd-network.service.

If you do get limited internet (on LAN), try utilizing internet via enabling + starting the following service as root:

  • systemctl enable dhcpcd.service
  • systemctl start dhcpcd.servie

This might ultimately not be caused by your network's security settings or DHCP Server/Router.

# ~/.p10k.zsh
# Generated by Powerlevel10k configuration wizard on 2021-11-26 at 14:56 CET.
# Based on romkatv/powerlevel10k/config/p10k-rainbow.zsh, checksum 19497.
# Wizard options: nerdfont-complete + powerline, small icons, rainbow, unicode,
# 24h time, slanted separators, sharp heads, flat tails, 2 lines, solid, no frame,
# dark-ornaments, sparse, many icons, concise, transient_prompt, instant_prompt=quiet.
# Type `p10k configure` to generate another config.
#
# Config for Powerlevel10k with powerline prompt style with colorful background.
# Type `p10k configure` to generate your own config based on it.
#
# Tip: Looking for a nice color? Here's a one-liner to print colormap.
#
# for i in {0..255}; do print -Pn "%K{$i} %k%F{$i}${(l:3::0:)i}%f " ${${(M)$((i%6)):#3}:+$'\n'}; done
# Temporarily change options.
'builtin' 'local' '-a' 'p10k_config_opts'
[[ ! -o 'aliases' ]] || p10k_config_opts+=('aliases')
[[ ! -o 'sh_glob' ]] || p10k_config_opts+=('sh_glob')
[[ ! -o 'no_brace_expand' ]] || p10k_config_opts+=('no_brace_expand')
'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand'
() {
emulate -L zsh -o extended_glob
# Unset all configuration options. This allows you to apply configuration changes without
# restarting zsh. Edit ~/.p10k.zsh and type `source ~/.p10k.zsh`.
unset -m '(POWERLEVEL9K_*|DEFAULT_USER)~POWERLEVEL9K_GITSTATUS_DIR'
# Zsh >= 5.1 is required.
autoload -Uz is-at-least && is-at-least 5.1 || return
# The list of segments shown on the left. Fill it with the most important segments.
typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(
# =========================[ Line #1 ]=========================
os_icon # os identifier
dir # current directory
vcs # git status
# =========================[ Line #2 ]=========================
newline # \n
prompt_char # prompt symbol
)
# The list of segments shown on the right. Fill it with less important segments.
# Right prompt on the last prompt line (where you are typing your commands) gets
# automatically hidden when the input line reaches it. Right prompt above the
# last prompt line gets hidden if it would overlap with left prompt.
typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(
# =========================[ Line #1 ]=========================
status # exit code of the last command
command_execution_time # duration of the last command
background_jobs # presence of background jobs
direnv # direnv status (https://direnv.net/)
asdf # asdf version manager (https://github.com/asdf-vm/asdf)
virtualenv # python virtual environment (https://docs.python.org/3/library/venv.html)
anaconda # conda environment (https://conda.io/)
pyenv # python environment (https://github.com/pyenv/pyenv)
goenv # go environment (https://github.com/syndbg/goenv)
nodenv # node.js version from nodenv (https://github.com/nodenv/nodenv)
nvm # node.js version from nvm (https://github.com/nvm-sh/nvm)
nodeenv # node.js environment (https://github.com/ekalinin/nodeenv)
# node_version # node.js version
# go_version # go version (https://golang.org)
# rust_version # rustc version (https://www.rust-lang.org)
# dotnet_version # .NET version (https://dotnet.microsoft.com)
# php_version # php version (https://www.php.net/)
# laravel_version # laravel php framework version (https://laravel.com/)
# java_version # java version (https://www.java.com/)
# package # name@version from package.json (https://docs.npmjs.com/files/package.json)
rbenv # ruby version from rbenv (https://github.com/rbenv/rbenv)
rvm # ruby version from rvm (https://rvm.io)
fvm # flutter version management (https://github.com/leoafarias/fvm)
luaenv # lua version from luaenv (https://github.com/cehoffman/luaenv)
jenv # java version from jenv (https://github.com/jenv/jenv)
plenv # perl version from plenv (https://github.com/tokuhirom/plenv)
phpenv # php version from phpenv (https://github.com/phpenv/phpenv)
scalaenv # scala version from scalaenv (https://github.com/scalaenv/scalaenv)
haskell_stack # haskell version from stack (https://haskellstack.org/)
kubecontext # current kubernetes context (https://kubernetes.io/)
terraform # terraform workspace (https://www.terraform.io)
# terraform_version # terraform version (https://www.terraform.io)
aws # aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html)
aws_eb_env # aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/)
azure # azure account name (https://docs.microsoft.com/en-us/cli/azure)
gcloud # google cloud cli account and project (https://cloud.google.com/)
google_app_cred # google application credentials (https://cloud.google.com/docs/authentication/production)
toolbox # toolbox name (https://github.com/containers/toolbox)
context # user@hostname
nordvpn # nordvpn connection status, linux only (https://nordvpn.com/)
ranger # ranger shell (https://github.com/ranger/ranger)
nnn # nnn shell (https://github.com/jarun/nnn)
xplr # xplr shell (https://github.com/sayanarijit/xplr)
vim_shell # vim shell indicator (:sh)
midnight_commander # midnight commander shell (https://midnight-commander.org/)
nix_shell # nix shell (https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html)
# vi_mode # vi mode (you don't need this if you've enabled prompt_char)
# vpn_ip # virtual private network indicator
# load # CPU load
# disk_usage # disk usage
# ram # free RAM
# swap # used swap
todo # todo items (https://github.com/todotxt/todo.txt-cli)
timewarrior # timewarrior tracking status (https://timewarrior.net/)
taskwarrior # taskwarrior task count (https://taskwarrior.org/)
time # current time
# =========================[ Line #2 ]=========================
newline
# ip # ip address and bandwidth usage for a specified network interface
# public_ip # public IP address
# proxy # system-wide http/https/ftp proxy
# battery # internal battery
# wifi # wifi speed
# example # example user-defined segment (see prompt_example function below)
)
# Defines character set used by powerlevel10k. It's best to let `p10k configure` set it for you.
typeset -g POWERLEVEL9K_MODE=nerdfont-complete
# When set to `moderate`, some icons will have an extra space after them. This is meant to avoid
# icon overlap when using non-monospace fonts. When set to `none`, spaces are not added.
typeset -g POWERLEVEL9K_ICON_PADDING=none
# When set to true, icons appear before content on both sides of the prompt. When set
# to false, icons go after content. If empty or not set, icons go before content in the left
# prompt and after content in the right prompt.
#
# You can also override it for a specific segment:
#
# POWERLEVEL9K_STATUS_ICON_BEFORE_CONTENT=false
#
# Or for a specific segment in specific state:
#
# POWERLEVEL9K_DIR_NOT_WRITABLE_ICON_BEFORE_CONTENT=false
typeset -g POWERLEVEL9K_ICON_BEFORE_CONTENT=
# Add an empty line before each prompt.
typeset -g POWERLEVEL9K_PROMPT_ADD_NEWLINE=true
# Connect left prompt lines with these symbols. You'll probably want to use the same color
# as POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_FOREGROUND below.
typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX=
typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_PREFIX=
typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX=
# Connect right prompt lines with these symbols.
typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_SUFFIX=
typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_SUFFIX=
typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_SUFFIX=
# Filler between left and right prompt on the first prompt line. You can set it to ' ', '·' or
# '─'. The last two make it easier to see the alignment between left and right prompt and to
# separate prompt from command output. You might want to set POWERLEVEL9K_PROMPT_ADD_NEWLINE=false
# for more compact prompt if using using this option.
typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR='─'
typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_BACKGROUND=
typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_GAP_BACKGROUND=
if [[ $POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR != ' ' ]]; then
# The color of the filler. You'll probably want to match the color of POWERLEVEL9K_MULTILINE
# ornaments defined above.
typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_FOREGROUND=240
# Start filler from the edge of the screen if there are no left segments on the first line.
typeset -g POWERLEVEL9K_EMPTY_LINE_LEFT_PROMPT_FIRST_SEGMENT_END_SYMBOL='%{%}'
# End filler on the edge of the screen if there are no right segments on the first line.
typeset -g POWERLEVEL9K_EMPTY_LINE_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL='%{%}'
fi
# Separator between same-color segments on the left.
typeset -g POWERLEVEL9K_LEFT_SUBSEGMENT_SEPARATOR='\u2571'
# Separator between same-color segments on the right.
typeset -g POWERLEVEL9K_RIGHT_SUBSEGMENT_SEPARATOR='\u2571'
# Separator between different-color segments on the left.
typeset -g POWERLEVEL9K_LEFT_SEGMENT_SEPARATOR='\uE0BC'
# Separator between different-color segments on the right.
typeset -g POWERLEVEL9K_RIGHT_SEGMENT_SEPARATOR='\uE0BA'
# The right end of left prompt.
typeset -g POWERLEVEL9K_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL='\uE0B0'
# The left end of right prompt.
typeset -g POWERLEVEL9K_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL='\uE0B2'
# The left end of left prompt.
typeset -g POWERLEVEL9K_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL=''
# The right end of right prompt.
typeset -g POWERLEVEL9K_RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL=''
# Left prompt terminator for lines without any segments.
typeset -g POWERLEVEL9K_EMPTY_LINE_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL=
#################################[ os_icon: os identifier ]##################################
# OS identifier color.
typeset -g POWERLEVEL9K_OS_ICON_FOREGROUND=232
typeset -g POWERLEVEL9K_OS_ICON_BACKGROUND=7
# Custom icon.
# typeset -g POWERLEVEL9K_OS_ICON_CONTENT_EXPANSION='⭐'
################################[ prompt_char: prompt symbol ]################################
# Transparent background.
typeset -g POWERLEVEL9K_PROMPT_CHAR_BACKGROUND=
# Green prompt symbol if the last command succeeded.
typeset -g POWERLEVEL9K_PROMPT_CHAR_OK_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=76
# Red prompt symbol if the last command failed.
typeset -g POWERLEVEL9K_PROMPT_CHAR_ERROR_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=196
# Default prompt symbol.
typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIINS_CONTENT_EXPANSION='❯'
# Prompt symbol in command vi mode.
typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VICMD_CONTENT_EXPANSION='❮'
# Prompt symbol in visual vi mode.
typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIVIS_CONTENT_EXPANSION='V'
# Prompt symbol in overwrite vi mode.
typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIOWR_CONTENT_EXPANSION='▶'
typeset -g POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE=true
# No line terminator if prompt_char is the last segment.
typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL=
# No line introducer if prompt_char is the first segment.
typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL=
# No surrounding whitespace.
typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_{LEFT,RIGHT}_WHITESPACE=
##################################[ dir: current directory ]##################################
# Current directory background color.
typeset -g POWERLEVEL9K_DIR_BACKGROUND=4
# Default current directory foreground color.
typeset -g POWERLEVEL9K_DIR_FOREGROUND=254
# If directory is too long, shorten some of its segments to the shortest possible unique
# prefix. The shortened directory can be tab-completed to the original.
typeset -g POWERLEVEL9K_SHORTEN_STRATEGY=truncate_to_unique
# Replace removed segment suffixes with this symbol.
typeset -g POWERLEVEL9K_SHORTEN_DELIMITER=
# Color of the shortened directory segments.
typeset -g POWERLEVEL9K_DIR_SHORTENED_FOREGROUND=250
# Color of the anchor directory segments. Anchor segments are never shortened. The first
# segment is always an anchor.
typeset -g POWERLEVEL9K_DIR_ANCHOR_FOREGROUND=255
# Display anchor directory segments in bold.
typeset -g POWERLEVEL9K_DIR_ANCHOR_BOLD=true
# Don't shorten directories that contain any of these files. They are anchors.
local anchor_files=(
.bzr
.citc
.git
.hg
.node-version
.python-version
.go-version
.ruby-version
.lua-version
.java-version
.perl-version
.php-version
.tool-version
.shorten_folder_marker
.svn
.terraform
CVS
Cargo.toml
composer.json
go.mod
package.json
stack.yaml
)
typeset -g POWERLEVEL9K_SHORTEN_FOLDER_MARKER="(${(j:|:)anchor_files})"
# If set to "first" ("last"), remove everything before the first (last) subdirectory that contains
# files matching $POWERLEVEL9K_SHORTEN_FOLDER_MARKER. For example, when the current directory is
# /foo/bar/git_repo/nested_git_repo/baz, prompt will display git_repo/nested_git_repo/baz (first)
# or nested_git_repo/baz (last). This assumes that git_repo and nested_git_repo contain markers
# and other directories don't.
#
# Optionally, "first" and "last" can be followed by ":<offset>" where <offset> is an integer.
# This moves the truncation point to the right (positive offset) or to the left (negative offset)
# relative to the marker. Plain "first" and "last" are equivalent to "first:0" and "last:0"
# respectively.
typeset -g POWERLEVEL9K_DIR_TRUNCATE_BEFORE_MARKER=false
# Don't shorten this many last directory segments. They are anchors.
typeset -g POWERLEVEL9K_SHORTEN_DIR_LENGTH=1
# Shorten directory if it's longer than this even if there is space for it. The value can
# be either absolute (e.g., '80') or a percentage of terminal width (e.g, '50%'). If empty,
# directory will be shortened only when prompt doesn't fit or when other parameters demand it
# (see POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS and POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT below).
# If set to `0`, directory will always be shortened to its minimum length.
typeset -g POWERLEVEL9K_DIR_MAX_LENGTH=80
# When `dir` segment is on the last prompt line, try to shorten it enough to leave at least this
# many columns for typing commands.
typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS=40
# When `dir` segment is on the last prompt line, try to shorten it enough to leave at least
# COLUMNS * POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT * 0.01 columns for typing commands.
typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT=50
# If set to true, embed a hyperlink into the directory. Useful for quickly
# opening a directory in the file manager simply by clicking the link.
# Can also be handy when the directory is shortened, as it allows you to see
# the full directory that was used in previous commands.
typeset -g POWERLEVEL9K_DIR_HYPERLINK=false
# Enable special styling for non-writable and non-existent directories. See POWERLEVEL9K_LOCK_ICON
# and POWERLEVEL9K_DIR_CLASSES below.
typeset -g POWERLEVEL9K_DIR_SHOW_WRITABLE=v3
# The default icon shown next to non-writable and non-existent directories when
# POWERLEVEL9K_DIR_SHOW_WRITABLE is set to v3.
# typeset -g POWERLEVEL9K_LOCK_ICON='⭐'
# POWERLEVEL9K_DIR_CLASSES allows you to specify custom icons and colors for different
# directories. It must be an array with 3 * N elements. Each triplet consists of:
#
# 1. A pattern against which the current directory ($PWD) is matched. Matching is done with
# extended_glob option enabled.
# 2. Directory class for the purpose of styling.
# 3. An empty string.
#
# Triplets are tried in order. The first triplet whose pattern matches $PWD wins.
#
# If POWERLEVEL9K_DIR_SHOW_WRITABLE is set to v3, non-writable and non-existent directories
# acquire class suffix _NOT_WRITABLE and NON_EXISTENT respectively.
#
# For example, given these settings:
#
# typeset -g POWERLEVEL9K_DIR_CLASSES=(
# '~/work(|/*)' WORK ''
# '~(|/*)' HOME ''
# '*' DEFAULT '')
#
# Whenever the current directory is ~/work or a subdirectory of ~/work, it gets styled with one
# of the following classes depending on its writability and existence: WORK, WORK_NOT_WRITABLE or
# WORK_NON_EXISTENT.
#
# Simply assigning classes to directories doesn't have any visible effects. It merely gives you an
# option to define custom colors and icons for different directory classes.
#
# # Styling for WORK.
# typeset -g POWERLEVEL9K_DIR_WORK_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_DIR_WORK_BACKGROUND=4
# typeset -g POWERLEVEL9K_DIR_WORK_FOREGROUND=254
# typeset -g POWERLEVEL9K_DIR_WORK_SHORTENED_FOREGROUND=250
# typeset -g POWERLEVEL9K_DIR_WORK_ANCHOR_FOREGROUND=255
#
# # Styling for WORK_NOT_WRITABLE.
# typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_BACKGROUND=4
# typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_FOREGROUND=254
# typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_SHORTENED_FOREGROUND=250
# typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_ANCHOR_FOREGROUND=255
#
# # Styling for WORK_NON_EXISTENT.
# typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_BACKGROUND=4
# typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_FOREGROUND=254
# typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_SHORTENED_FOREGROUND=250
# typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_ANCHOR_FOREGROUND=255
#
# If a styling parameter isn't explicitly defined for some class, it falls back to the classless
# parameter. For example, if POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_FOREGROUND is not set, it falls
# back to POWERLEVEL9K_DIR_FOREGROUND.
#
# typeset -g POWERLEVEL9K_DIR_CLASSES=()
# Custom prefix.
# typeset -g POWERLEVEL9K_DIR_PREFIX='in '
#####################################[ vcs: git status ]######################################
# Version control system colors.
typeset -g POWERLEVEL9K_VCS_CLEAN_BACKGROUND=2
typeset -g POWERLEVEL9K_VCS_MODIFIED_BACKGROUND=3
typeset -g POWERLEVEL9K_VCS_UNTRACKED_BACKGROUND=2
typeset -g POWERLEVEL9K_VCS_CONFLICTED_BACKGROUND=3
typeset -g POWERLEVEL9K_VCS_LOADING_BACKGROUND=8
# Branch icon. Set this parameter to '\uF126 ' for the popular Powerline branch icon.
typeset -g POWERLEVEL9K_VCS_BRANCH_ICON='\uF126 '
# Untracked files icon. It's really a question mark, your font isn't broken.
# Change the value of this parameter to show a different icon.
typeset -g POWERLEVEL9K_VCS_UNTRACKED_ICON='?'
# Formatter for Git status.
#
# Example output: master wip ⇣42⇡42 *42 merge ~42 +42 !42 ?42.
#
# You can edit the function to customize how Git status looks.
#
# VCS_STATUS_* parameters are set by gitstatus plugin. See reference:
# https://github.com/romkatv/gitstatus/blob/master/gitstatus.plugin.zsh.
function my_git_formatter() {
emulate -L zsh
if [[ -n $P9K_CONTENT ]]; then
# If P9K_CONTENT is not empty, use it. It's either "loading" or from vcs_info (not from
# gitstatus plugin). VCS_STATUS_* parameters are not available in this case.
typeset -g my_git_format=$P9K_CONTENT
return
fi
# Styling for different parts of Git status.
local meta='%7F' # white foreground
local clean='%0F' # black foreground
local modified='%0F' # black foreground
local untracked='%0F' # black foreground
local conflicted='%1F' # red foreground
local res
if [[ -n $VCS_STATUS_LOCAL_BRANCH ]]; then
local branch=${(V)VCS_STATUS_LOCAL_BRANCH}
# If local branch name is at most 32 characters long, show it in full.
# Otherwise show the first 12 … the last 12.
# Tip: To always show local branch name in full without truncation, delete the next line.
(( $#branch > 32 )) && branch[13,-13]="…" # <-- this line
res+="${clean}${(g::)POWERLEVEL9K_VCS_BRANCH_ICON}${branch//\%/%%}"
fi
if [[ -n $VCS_STATUS_TAG
# Show tag only if not on a branch.
# Tip: To always show tag, delete the next line.
&& -z $VCS_STATUS_LOCAL_BRANCH # <-- this line
]]; then
local tag=${(V)VCS_STATUS_TAG}
# If tag name is at most 32 characters long, show it in full.
# Otherwise show the first 12 … the last 12.
# Tip: To always show tag name in full without truncation, delete the next line.
(( $#tag > 32 )) && tag[13,-13]="…" # <-- this line
res+="${meta}#${clean}${tag//\%/%%}"
fi
# Display the current Git commit if there is no branch and no tag.
# Tip: To always display the current Git commit, delete the next line.
[[ -z $VCS_STATUS_LOCAL_BRANCH && -z $VCS_STATUS_TAG ]] && # <-- this line
res+="${meta}@${clean}${VCS_STATUS_COMMIT[1,8]}"
# Show tracking branch name if it differs from local branch.
if [[ -n ${VCS_STATUS_REMOTE_BRANCH:#$VCS_STATUS_LOCAL_BRANCH} ]]; then
res+="${meta}:${clean}${(V)VCS_STATUS_REMOTE_BRANCH//\%/%%}"
fi
# Display "wip" if the latest commit's summary contains "wip" or "WIP".
if [[ $VCS_STATUS_COMMIT_SUMMARY == (|*[^[:alnum:]])(wip|WIP)(|[^[:alnum:]]*) ]]; then
res+=" ${modified}wip"
fi
# ⇣42 if behind the remote.
(( VCS_STATUS_COMMITS_BEHIND )) && res+=" ${clean}⇣${VCS_STATUS_COMMITS_BEHIND}"
# ⇡42 if ahead of the remote; no leading space if also behind the remote: ⇣42⇡42.
(( VCS_STATUS_COMMITS_AHEAD && !VCS_STATUS_COMMITS_BEHIND )) && res+=" "
(( VCS_STATUS_COMMITS_AHEAD )) && res+="${clean}⇡${VCS_STATUS_COMMITS_AHEAD}"
# ⇠42 if behind the push remote.
(( VCS_STATUS_PUSH_COMMITS_BEHIND )) && res+=" ${clean}⇠${VCS_STATUS_PUSH_COMMITS_BEHIND}"
(( VCS_STATUS_PUSH_COMMITS_AHEAD && !VCS_STATUS_PUSH_COMMITS_BEHIND )) && res+=" "
# ⇢42 if ahead of the push remote; no leading space if also behind: ⇠42⇢42.
(( VCS_STATUS_PUSH_COMMITS_AHEAD )) && res+="${clean}⇢${VCS_STATUS_PUSH_COMMITS_AHEAD}"
# *42 if have stashes.
(( VCS_STATUS_STASHES )) && res+=" ${clean}*${VCS_STATUS_STASHES}"
# 'merge' if the repo is in an unusual state.
[[ -n $VCS_STATUS_ACTION ]] && res+=" ${conflicted}${VCS_STATUS_ACTION}"
# ~42 if have merge conflicts.
(( VCS_STATUS_NUM_CONFLICTED )) && res+=" ${conflicted}~${VCS_STATUS_NUM_CONFLICTED}"
# +42 if have staged changes.
(( VCS_STATUS_NUM_STAGED )) && res+=" ${modified}+${VCS_STATUS_NUM_STAGED}"
# !42 if have unstaged changes.
(( VCS_STATUS_NUM_UNSTAGED )) && res+=" ${modified}!${VCS_STATUS_NUM_UNSTAGED}"
# ?42 if have untracked files. It's really a question mark, your font isn't broken.
# See POWERLEVEL9K_VCS_UNTRACKED_ICON above if you want to use a different icon.
# Remove the next line if you don't want to see untracked files at all.
(( VCS_STATUS_NUM_UNTRACKED )) && res+=" ${untracked}${(g::)POWERLEVEL9K_VCS_UNTRACKED_ICON}${VCS_STATUS_NUM_UNTRACKED}"
# "─" if the number of unstaged files is unknown. This can happen due to
# POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY (see below) being set to a non-negative number lower
# than the number of files in the Git index, or due to bash.showDirtyState being set to false
# in the repository config. The number of staged and untracked files may also be unknown
# in this case.
(( VCS_STATUS_HAS_UNSTAGED == -1 )) && res+=" ${modified}─"
typeset -g my_git_format=$res
}
functions -M my_git_formatter 2>/dev/null
# Don't count the number of unstaged, untracked and conflicted files in Git repositories with
# more than this many files in the index. Negative value means infinity.
#
# If you are working in Git repositories with tens of millions of files and seeing performance
# sagging, try setting POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY to a number lower than the output
# of `git ls-files | wc -l`. Alternatively, add `bash.showDirtyState = false` to the repository's
# config: `git config bash.showDirtyState false`.
typeset -g POWERLEVEL9K_VCS_MAX_INDEX_SIZE_DIRTY=-1
# Don't show Git status in prompt for repositories whose workdir matches this pattern.
# For example, if set to '~', the Git repository at $HOME/.git will be ignored.
# Multiple patterns can be combined with '|': '~(|/foo)|/bar/baz/*'.
typeset -g POWERLEVEL9K_VCS_DISABLED_WORKDIR_PATTERN='~'
# Disable the default Git status formatting.
typeset -g POWERLEVEL9K_VCS_DISABLE_GITSTATUS_FORMATTING=true
# Install our own Git status formatter.
typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION='${$((my_git_formatter()))+${my_git_format}}'
# Enable counters for staged, unstaged, etc.
typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED,CONFLICTED,COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=-1
# Custom icon.
# typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_EXPANSION='⭐'
# Custom prefix.
# typeset -g POWERLEVEL9K_VCS_PREFIX='on '
# Show status of repositories of these types. You can add svn and/or hg if you are
# using them. If you do, your prompt may become slow even when your current directory
# isn't in an svn or hg reposotiry.
typeset -g POWERLEVEL9K_VCS_BACKENDS=(git)
##########################[ status: exit code of the last command ]###########################
# Enable OK_PIPE, ERROR_PIPE and ERROR_SIGNAL status states to allow us to enable, disable and
# style them independently from the regular OK and ERROR state.
typeset -g POWERLEVEL9K_STATUS_EXTENDED_STATES=true
# Status on success. No content, just an icon. No need to show it if prompt_char is enabled as
# it will signify success by turning green.
typeset -g POWERLEVEL9K_STATUS_OK=false
typeset -g POWERLEVEL9K_STATUS_OK_VISUAL_IDENTIFIER_EXPANSION='✔'
typeset -g POWERLEVEL9K_STATUS_OK_FOREGROUND=2
typeset -g POWERLEVEL9K_STATUS_OK_BACKGROUND=0
# Status when some part of a pipe command fails but the overall exit status is zero. It may look
# like this: 1|0.
typeset -g POWERLEVEL9K_STATUS_OK_PIPE=true
typeset -g POWERLEVEL9K_STATUS_OK_PIPE_VISUAL_IDENTIFIER_EXPANSION='✔'
typeset -g POWERLEVEL9K_STATUS_OK_PIPE_FOREGROUND=2
typeset -g POWERLEVEL9K_STATUS_OK_PIPE_BACKGROUND=0
# Status when it's just an error code (e.g., '1'). No need to show it if prompt_char is enabled as
# it will signify error by turning red.
typeset -g POWERLEVEL9K_STATUS_ERROR=false
typeset -g POWERLEVEL9K_STATUS_ERROR_VISUAL_IDENTIFIER_EXPANSION='✘'
typeset -g POWERLEVEL9K_STATUS_ERROR_FOREGROUND=3
typeset -g POWERLEVEL9K_STATUS_ERROR_BACKGROUND=1
# Status when the last command was terminated by a signal.
typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL=true
# Use terse signal names: "INT" instead of "SIGINT(2)".
typeset -g POWERLEVEL9K_STATUS_VERBOSE_SIGNAME=false
typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_VISUAL_IDENTIFIER_EXPANSION='✘'
typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_FOREGROUND=3
typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_BACKGROUND=1
# Status when some part of a pipe command fails and the overall exit status is also non-zero.
# It may look like this: 1|0.
typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE=true
typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_VISUAL_IDENTIFIER_EXPANSION='✘'
typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_FOREGROUND=3
typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_BACKGROUND=1
###################[ command_execution_time: duration of the last command ]###################
# Execution time color.
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FOREGROUND=0
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_BACKGROUND=3
# Show duration of the last command if takes at least this many seconds.
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=3
# Show this many fractional digits. Zero means round to seconds.
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PRECISION=0
# Duration format: 1d 2h 3m 4s.
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FORMAT='d h m s'
# Custom icon.
# typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_VISUAL_IDENTIFIER_EXPANSION='⭐'
# Custom prefix.
# typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PREFIX='took '
#######################[ background_jobs: presence of background jobs ]#######################
# Background jobs color.
typeset -g POWERLEVEL9K_BACKGROUND_JOBS_FOREGROUND=6
typeset -g POWERLEVEL9K_BACKGROUND_JOBS_BACKGROUND=0
# Don't show the number of background jobs.
typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VERBOSE=false
# Custom icon.
# typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VISUAL_IDENTIFIER_EXPANSION='⭐'
#######################[ direnv: direnv status (https://direnv.net/) ]########################
# Direnv color.
typeset -g POWERLEVEL9K_DIRENV_FOREGROUND=3
typeset -g POWERLEVEL9K_DIRENV_BACKGROUND=0
# Custom icon.
# typeset -g POWERLEVEL9K_DIRENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
###############[ asdf: asdf version manager (https://github.com/asdf-vm/asdf) ]###############
# Default asdf color. Only used to display tools for which there is no color override (see below).
# Tip: Override these parameters for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_FOREGROUND and
# POWERLEVEL9K_ASDF_${TOOL}_BACKGROUND.
typeset -g POWERLEVEL9K_ASDF_FOREGROUND=0
typeset -g POWERLEVEL9K_ASDF_BACKGROUND=7
# There are four parameters that can be used to hide asdf tools. Each parameter describes
# conditions under which a tool gets hidden. Parameters can hide tools but not unhide them. If at
# least one parameter decides to hide a tool, that tool gets hidden. If no parameter decides to
# hide a tool, it gets shown.
#
# Special note on the difference between POWERLEVEL9K_ASDF_SOURCES and
# POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW. Consider the effect of the following commands:
#
# asdf local python 3.8.1
# asdf global python 3.8.1
#
# After running both commands the current python version is 3.8.1 and its source is "local" as
# it takes precedence over "global". If POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW is set to false,
# it'll hide python version in this case because 3.8.1 is the same as the global version.
# POWERLEVEL9K_ASDF_SOURCES will hide python version only if the value of this parameter doesn't
# contain "local".
# Hide tool versions that don't come from one of these sources.
#
# Available sources:
#
# - shell `asdf current` says "set by ASDF_${TOOL}_VERSION environment variable"
# - local `asdf current` says "set by /some/not/home/directory/file"
# - global `asdf current` says "set by /home/username/file"
#
# Note: If this parameter is set to (shell local global), it won't hide tools.
# Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SOURCES.
typeset -g POWERLEVEL9K_ASDF_SOURCES=(shell local global)
# If set to false, hide tool versions that are the same as global.
#
# Note: The name of this parameter doesn't reflect its meaning at all.
# Note: If this parameter is set to true, it won't hide tools.
# Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_PROMPT_ALWAYS_SHOW.
typeset -g POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW=false
# If set to false, hide tool versions that are equal to "system".
#
# Note: If this parameter is set to true, it won't hide tools.
# Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SHOW_SYSTEM.
typeset -g POWERLEVEL9K_ASDF_SHOW_SYSTEM=true
# If set to non-empty value, hide tools unless there is a file matching the specified file pattern
# in the current directory, or its parent directory, or its grandparent directory, and so on.
#
# Note: If this parameter is set to empty value, it won't hide tools.
# Note: SHOW_ON_UPGLOB isn't specific to asdf. It works with all prompt segments.
# Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SHOW_ON_UPGLOB.
#
# Example: Hide nodejs version when there is no package.json and no *.js files in the current
# directory, in `..`, in `../..` and so on.
#
# typeset -g POWERLEVEL9K_ASDF_NODEJS_SHOW_ON_UPGLOB='*.js|package.json'
typeset -g POWERLEVEL9K_ASDF_SHOW_ON_UPGLOB=
# Ruby version from asdf.
typeset -g POWERLEVEL9K_ASDF_RUBY_FOREGROUND=0
typeset -g POWERLEVEL9K_ASDF_RUBY_BACKGROUND=1
# typeset -g POWERLEVEL9K_ASDF_RUBY_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_ASDF_RUBY_SHOW_ON_UPGLOB='*.foo|*.bar'
# Python version from asdf.
typeset -g POWERLEVEL9K_ASDF_PYTHON_FOREGROUND=0
typeset -g POWERLEVEL9K_ASDF_PYTHON_BACKGROUND=4
# typeset -g POWERLEVEL9K_ASDF_PYTHON_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_ASDF_PYTHON_SHOW_ON_UPGLOB='*.foo|*.bar'
# Go version from asdf.
typeset -g POWERLEVEL9K_ASDF_GOLANG_FOREGROUND=0
typeset -g POWERLEVEL9K_ASDF_GOLANG_BACKGROUND=4
# typeset -g POWERLEVEL9K_ASDF_GOLANG_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_ASDF_GOLANG_SHOW_ON_UPGLOB='*.foo|*.bar'
# Node.js version from asdf.
typeset -g POWERLEVEL9K_ASDF_NODEJS_FOREGROUND=0
typeset -g POWERLEVEL9K_ASDF_NODEJS_BACKGROUND=2
# typeset -g POWERLEVEL9K_ASDF_NODEJS_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_ASDF_NODEJS_SHOW_ON_UPGLOB='*.foo|*.bar'
# Rust version from asdf.
typeset -g POWERLEVEL9K_ASDF_RUST_FOREGROUND=0
typeset -g POWERLEVEL9K_ASDF_RUST_BACKGROUND=208
# typeset -g POWERLEVEL9K_ASDF_RUST_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_ASDF_RUST_SHOW_ON_UPGLOB='*.foo|*.bar'
# .NET Core version from asdf.
typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_FOREGROUND=0
typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_BACKGROUND=5
# typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_SHOW_ON_UPGLOB='*.foo|*.bar'
# Flutter version from asdf.
typeset -g POWERLEVEL9K_ASDF_FLUTTER_FOREGROUND=0
typeset -g POWERLEVEL9K_ASDF_FLUTTER_BACKGROUND=4
# typeset -g POWERLEVEL9K_ASDF_FLUTTER_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_ASDF_FLUTTER_SHOW_ON_UPGLOB='*.foo|*.bar'
# Lua version from asdf.
typeset -g POWERLEVEL9K_ASDF_LUA_FOREGROUND=0
typeset -g POWERLEVEL9K_ASDF_LUA_BACKGROUND=4
# typeset -g POWERLEVEL9K_ASDF_LUA_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_ASDF_LUA_SHOW_ON_UPGLOB='*.foo|*.bar'
# Java version from asdf.
typeset -g POWERLEVEL9K_ASDF_JAVA_FOREGROUND=1
typeset -g POWERLEVEL9K_ASDF_JAVA_BACKGROUND=7
# typeset -g POWERLEVEL9K_ASDF_JAVA_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_ASDF_JAVA_SHOW_ON_UPGLOB='*.foo|*.bar'
# Perl version from asdf.
typeset -g POWERLEVEL9K_ASDF_PERL_FOREGROUND=0
typeset -g POWERLEVEL9K_ASDF_PERL_BACKGROUND=4
# typeset -g POWERLEVEL9K_ASDF_PERL_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_ASDF_PERL_SHOW_ON_UPGLOB='*.foo|*.bar'
# Erlang version from asdf.
typeset -g POWERLEVEL9K_ASDF_ERLANG_FOREGROUND=0
typeset -g POWERLEVEL9K_ASDF_ERLANG_BACKGROUND=1
# typeset -g POWERLEVEL9K_ASDF_ERLANG_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_ASDF_ERLANG_SHOW_ON_UPGLOB='*.foo|*.bar'
# Elixir version from asdf.
typeset -g POWERLEVEL9K_ASDF_ELIXIR_FOREGROUND=0
typeset -g POWERLEVEL9K_ASDF_ELIXIR_BACKGROUND=5
# typeset -g POWERLEVEL9K_ASDF_ELIXIR_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_ASDF_ELIXIR_SHOW_ON_UPGLOB='*.foo|*.bar'
# Postgres version from asdf.
typeset -g POWERLEVEL9K_ASDF_POSTGRES_FOREGROUND=0
typeset -g POWERLEVEL9K_ASDF_POSTGRES_BACKGROUND=6
# typeset -g POWERLEVEL9K_ASDF_POSTGRES_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_ASDF_POSTGRES_SHOW_ON_UPGLOB='*.foo|*.bar'
# PHP version from asdf.
typeset -g POWERLEVEL9K_ASDF_PHP_FOREGROUND=0
typeset -g POWERLEVEL9K_ASDF_PHP_BACKGROUND=5
# typeset -g POWERLEVEL9K_ASDF_PHP_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_ASDF_PHP_SHOW_ON_UPGLOB='*.foo|*.bar'
# Haskell version from asdf.
typeset -g POWERLEVEL9K_ASDF_HASKELL_FOREGROUND=0
typeset -g POWERLEVEL9K_ASDF_HASKELL_BACKGROUND=3
# typeset -g POWERLEVEL9K_ASDF_HASKELL_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_ASDF_HASKELL_SHOW_ON_UPGLOB='*.foo|*.bar'
# Julia version from asdf.
typeset -g POWERLEVEL9K_ASDF_JULIA_FOREGROUND=0
typeset -g POWERLEVEL9K_ASDF_JULIA_BACKGROUND=2
# typeset -g POWERLEVEL9K_ASDF_JULIA_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_ASDF_JULIA_SHOW_ON_UPGLOB='*.foo|*.bar'
##########[ nordvpn: nordvpn connection status, linux only (https://nordvpn.com/) ]###########
# NordVPN connection indicator color.
typeset -g POWERLEVEL9K_NORDVPN_FOREGROUND=7
typeset -g POWERLEVEL9K_NORDVPN_BACKGROUND=4
# Hide NordVPN connection indicator when not connected.
typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_CONTENT_EXPANSION=
typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_VISUAL_IDENTIFIER_EXPANSION=
# Custom icon.
# typeset -g POWERLEVEL9K_NORDVPN_VISUAL_IDENTIFIER_EXPANSION='⭐'
#################[ ranger: ranger shell (https://github.com/ranger/ranger) ]##################
# Ranger shell color.
typeset -g POWERLEVEL9K_RANGER_FOREGROUND=3
typeset -g POWERLEVEL9K_RANGER_BACKGROUND=0
# Custom icon.
# typeset -g POWERLEVEL9K_RANGER_VISUAL_IDENTIFIER_EXPANSION='⭐'
######################[ nnn: nnn shell (https://github.com/jarun/nnn) ]#######################
# Nnn shell color.
typeset -g POWERLEVEL9K_NNN_FOREGROUND=0
typeset -g POWERLEVEL9K_NNN_BACKGROUND=6
# Custom icon.
# typeset -g POWERLEVEL9K_NNN_VISUAL_IDENTIFIER_EXPANSION='⭐'
##################[ xplr: xplr shell (https://github.com/sayanarijit/xplr) ]##################
# xplr shell color.
typeset -g POWERLEVEL9K_XPLR_FOREGROUND=0
typeset -g POWERLEVEL9K_XPLR_BACKGROUND=6
# Custom icon.
# typeset -g POWERLEVEL9K_XPLR_VISUAL_IDENTIFIER_EXPANSION='⭐'
###########################[ vim_shell: vim shell indicator (:sh) ]###########################
# Vim shell indicator color.
typeset -g POWERLEVEL9K_VIM_SHELL_FOREGROUND=0
typeset -g POWERLEVEL9K_VIM_SHELL_BACKGROUND=2
# Custom icon.
# typeset -g POWERLEVEL9K_VIM_SHELL_VISUAL_IDENTIFIER_EXPANSION='⭐'
######[ midnight_commander: midnight commander shell (https://midnight-commander.org/) ]######
# Midnight Commander shell color.
typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_FOREGROUND=3
typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_BACKGROUND=0
# Custom icon.
# typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_VISUAL_IDENTIFIER_EXPANSION='⭐'
#[ nix_shell: nix shell (https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html) ]##
# Nix shell color.
typeset -g POWERLEVEL9K_NIX_SHELL_FOREGROUND=0
typeset -g POWERLEVEL9K_NIX_SHELL_BACKGROUND=4
# Tip: If you want to see just the icon without "pure" and "impure", uncomment the next line.
# typeset -g POWERLEVEL9K_NIX_SHELL_CONTENT_EXPANSION=
# Custom icon.
# typeset -g POWERLEVEL9K_NIX_SHELL_VISUAL_IDENTIFIER_EXPANSION='⭐'
##################################[ disk_usage: disk usage ]##################################
# Colors for different levels of disk usage.
typeset -g POWERLEVEL9K_DISK_USAGE_NORMAL_FOREGROUND=3
typeset -g POWERLEVEL9K_DISK_USAGE_NORMAL_BACKGROUND=0
typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_FOREGROUND=0
typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_BACKGROUND=3
typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_FOREGROUND=7
typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_BACKGROUND=1
# Thresholds for different levels of disk usage (percentage points).
typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL=90
typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_LEVEL=95
# If set to true, hide disk usage when below $POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL percent.
typeset -g POWERLEVEL9K_DISK_USAGE_ONLY_WARNING=false
# Custom icon.
# typeset -g POWERLEVEL9K_DISK_USAGE_VISUAL_IDENTIFIER_EXPANSION='⭐'
###########[ vi_mode: vi mode (you don't need this if you've enabled prompt_char) ]###########
# Foreground color.
typeset -g POWERLEVEL9K_VI_MODE_FOREGROUND=0
# Text and color for normal (a.k.a. command) vi mode.
typeset -g POWERLEVEL9K_VI_COMMAND_MODE_STRING=NORMAL
typeset -g POWERLEVEL9K_VI_MODE_NORMAL_BACKGROUND=2
# Text and color for visual vi mode.
typeset -g POWERLEVEL9K_VI_VISUAL_MODE_STRING=VISUAL
typeset -g POWERLEVEL9K_VI_MODE_VISUAL_BACKGROUND=4
# Text and color for overtype (a.k.a. overwrite and replace) vi mode.
typeset -g POWERLEVEL9K_VI_OVERWRITE_MODE_STRING=OVERTYPE
typeset -g POWERLEVEL9K_VI_MODE_OVERWRITE_BACKGROUND=3
# Text and color for insert vi mode.
typeset -g POWERLEVEL9K_VI_INSERT_MODE_STRING=
typeset -g POWERLEVEL9K_VI_MODE_INSERT_FOREGROUND=8
######################################[ ram: free RAM ]#######################################
# RAM color.
typeset -g POWERLEVEL9K_RAM_FOREGROUND=0
typeset -g POWERLEVEL9K_RAM_BACKGROUND=3
# Custom icon.
# typeset -g POWERLEVEL9K_RAM_VISUAL_IDENTIFIER_EXPANSION='⭐'
#####################################[ swap: used swap ]######################################
# Swap color.
typeset -g POWERLEVEL9K_SWAP_FOREGROUND=0
typeset -g POWERLEVEL9K_SWAP_BACKGROUND=3
# Custom icon.
# typeset -g POWERLEVEL9K_SWAP_VISUAL_IDENTIFIER_EXPANSION='⭐'
######################################[ load: CPU load ]######################################
# Show average CPU load over this many last minutes. Valid values are 1, 5 and 15.
typeset -g POWERLEVEL9K_LOAD_WHICH=5
# Load color when load is under 50%.
typeset -g POWERLEVEL9K_LOAD_NORMAL_FOREGROUND=0
typeset -g POWERLEVEL9K_LOAD_NORMAL_BACKGROUND=2
# Load color when load is between 50% and 70%.
typeset -g POWERLEVEL9K_LOAD_WARNING_FOREGROUND=0
typeset -g POWERLEVEL9K_LOAD_WARNING_BACKGROUND=3
# Load color when load is over 70%.
typeset -g POWERLEVEL9K_LOAD_CRITICAL_FOREGROUND=0
typeset -g POWERLEVEL9K_LOAD_CRITICAL_BACKGROUND=1
# Custom icon.
# typeset -g POWERLEVEL9K_LOAD_VISUAL_IDENTIFIER_EXPANSION='⭐'
################[ todo: todo items (https://github.com/todotxt/todo.txt-cli) ]################
# Todo color.
typeset -g POWERLEVEL9K_TODO_FOREGROUND=0
typeset -g POWERLEVEL9K_TODO_BACKGROUND=8
# Hide todo when the total number of tasks is zero.
typeset -g POWERLEVEL9K_TODO_HIDE_ZERO_TOTAL=true
# Hide todo when the number of tasks after filtering is zero.
typeset -g POWERLEVEL9K_TODO_HIDE_ZERO_FILTERED=false
# Todo format. The following parameters are available within the expansion.
#
# - P9K_TODO_TOTAL_TASK_COUNT The total number of tasks.
# - P9K_TODO_FILTERED_TASK_COUNT The number of tasks after filtering.
#
# These variables correspond to the last line of the output of `todo.sh -p ls`:
#
# TODO: 24 of 42 tasks shown
#
# Here 24 is P9K_TODO_FILTERED_TASK_COUNT and 42 is P9K_TODO_TOTAL_TASK_COUNT.
#
# typeset -g POWERLEVEL9K_TODO_CONTENT_EXPANSION='$P9K_TODO_FILTERED_TASK_COUNT'
# Custom icon.
# typeset -g POWERLEVEL9K_TODO_VISUAL_IDENTIFIER_EXPANSION='⭐'
###########[ timewarrior: timewarrior tracking status (https://timewarrior.net/) ]############
# Timewarrior color.
typeset -g POWERLEVEL9K_TIMEWARRIOR_FOREGROUND=255
typeset -g POWERLEVEL9K_TIMEWARRIOR_BACKGROUND=8
# If the tracked task is longer than 24 characters, truncate and append "…".
# Tip: To always display tasks without truncation, delete the following parameter.
# Tip: To hide task names and display just the icon when time tracking is enabled, set the
# value of the following parameter to "".
typeset -g POWERLEVEL9K_TIMEWARRIOR_CONTENT_EXPANSION='${P9K_CONTENT:0:24}${${P9K_CONTENT:24}:+…}'
# Custom icon.
# typeset -g POWERLEVEL9K_TIMEWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐'
##############[ taskwarrior: taskwarrior task count (https://taskwarrior.org/) ]##############
# Taskwarrior color.
typeset -g POWERLEVEL9K_TASKWARRIOR_FOREGROUND=0
typeset -g POWERLEVEL9K_TASKWARRIOR_BACKGROUND=6
# Taskwarrior segment format. The following parameters are available within the expansion.
#
# - P9K_TASKWARRIOR_PENDING_COUNT The number of pending tasks: `task +PENDING count`.
# - P9K_TASKWARRIOR_OVERDUE_COUNT The number of overdue tasks: `task +OVERDUE count`.
#
# Zero values are represented as empty parameters.
#
# The default format:
#
# '${P9K_TASKWARRIOR_OVERDUE_COUNT:+"!$P9K_TASKWARRIOR_OVERDUE_COUNT/"}$P9K_TASKWARRIOR_PENDING_COUNT'
#
# typeset -g POWERLEVEL9K_TASKWARRIOR_CONTENT_EXPANSION='$P9K_TASKWARRIOR_PENDING_COUNT'
# Custom icon.
# typeset -g POWERLEVEL9K_TASKWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐'
##################################[ context: user@hostname ]##################################
# Context color when running with privileges.
typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND=1
typeset -g POWERLEVEL9K_CONTEXT_ROOT_BACKGROUND=0
# Context color in SSH without privileges.
typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_FOREGROUND=3
typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_BACKGROUND=0
# Default context color (no privileges, no SSH).
typeset -g POWERLEVEL9K_CONTEXT_FOREGROUND=3
typeset -g POWERLEVEL9K_CONTEXT_BACKGROUND=0
# Context format when running with privileges: user@hostname.
typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE='%n@%m'
# Context format when in SSH without privileges: user@hostname.
typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_TEMPLATE='%n@%m'
# Default context format (no privileges, no SSH): user@hostname.
typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE='%n@%m'
# Don't show context unless running with privileges or in SSH.
# Tip: Remove the next line to always show context.
typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_{CONTENT,VISUAL_IDENTIFIER}_EXPANSION=
# Custom icon.
# typeset -g POWERLEVEL9K_CONTEXT_VISUAL_IDENTIFIER_EXPANSION='⭐'
# Custom prefix.
# typeset -g POWERLEVEL9K_CONTEXT_PREFIX='with '
###[ virtualenv: python virtual environment (https://docs.python.org/3/library/venv.html) ]###
# Python virtual environment color.
typeset -g POWERLEVEL9K_VIRTUALENV_FOREGROUND=0
typeset -g POWERLEVEL9K_VIRTUALENV_BACKGROUND=4
# Don't show Python version next to the virtual environment name.
typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_PYTHON_VERSION=false
# If set to "false", won't show virtualenv if pyenv is already shown.
# If set to "if-different", won't show virtualenv if it's the same as pyenv.
typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_WITH_PYENV=false
# Separate environment name from Python version only with a space.
typeset -g POWERLEVEL9K_VIRTUALENV_{LEFT,RIGHT}_DELIMITER=
# Custom icon.
# typeset -g POWERLEVEL9K_VIRTUALENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
#####################[ anaconda: conda environment (https://conda.io/) ]######################
# Anaconda environment color.
typeset -g POWERLEVEL9K_ANACONDA_FOREGROUND=0
typeset -g POWERLEVEL9K_ANACONDA_BACKGROUND=4
# Anaconda segment format. The following parameters are available within the expansion.
#
# - CONDA_PREFIX Absolute path to the active Anaconda/Miniconda environment.
# - CONDA_DEFAULT_ENV Name of the active Anaconda/Miniconda environment.
# - CONDA_PROMPT_MODIFIER Configurable prompt modifier (see below).
# - P9K_ANACONDA_PYTHON_VERSION Current python version (python --version).
#
# CONDA_PROMPT_MODIFIER can be configured with the following command:
#
# conda config --set env_prompt '({default_env}) '
#
# The last argument is a Python format string that can use the following variables:
#
# - prefix The same as CONDA_PREFIX.
# - default_env The same as CONDA_DEFAULT_ENV.
# - name The last segment of CONDA_PREFIX.
# - stacked_env Comma-separated list of names in the environment stack. The first element is
# always the same as default_env.
#
# Note: '({default_env}) ' is the default value of env_prompt.
#
# The default value of POWERLEVEL9K_ANACONDA_CONTENT_EXPANSION expands to $CONDA_PROMPT_MODIFIER
# without the surrounding parentheses, or to the last path component of CONDA_PREFIX if the former
# is empty.
typeset -g POWERLEVEL9K_ANACONDA_CONTENT_EXPANSION='${${${${CONDA_PROMPT_MODIFIER#\(}% }%\)}:-${CONDA_PREFIX:t}}'
# Custom icon.
# typeset -g POWERLEVEL9K_ANACONDA_VISUAL_IDENTIFIER_EXPANSION='⭐'
################[ pyenv: python environment (https://github.com/pyenv/pyenv) ]################
# Pyenv color.
typeset -g POWERLEVEL9K_PYENV_FOREGROUND=0
typeset -g POWERLEVEL9K_PYENV_BACKGROUND=4
# Hide python version if it doesn't come from one of these sources.
typeset -g POWERLEVEL9K_PYENV_SOURCES=(shell local global)
# If set to false, hide python version if it's the same as global:
# $(pyenv version-name) == $(pyenv global).
typeset -g POWERLEVEL9K_PYENV_PROMPT_ALWAYS_SHOW=false
# If set to false, hide python version if it's equal to "system".
typeset -g POWERLEVEL9K_PYENV_SHOW_SYSTEM=true
# Pyenv segment format. The following parameters are available within the expansion.
#
# - P9K_CONTENT Current pyenv environment (pyenv version-name).
# - P9K_PYENV_PYTHON_VERSION Current python version (python --version).
#
# The default format has the following logic:
#
# 1. Display just "$P9K_CONTENT" if it's equal to "$P9K_PYENV_PYTHON_VERSION" or
# starts with "$P9K_PYENV_PYTHON_VERSION/".
# 2. Otherwise display "$P9K_CONTENT $P9K_PYENV_PYTHON_VERSION".
typeset -g POWERLEVEL9K_PYENV_CONTENT_EXPANSION='${P9K_CONTENT}${${P9K_CONTENT:#$P9K_PYENV_PYTHON_VERSION(|/*)}:+ $P9K_PYENV_PYTHON_VERSION}'
# Custom icon.
# typeset -g POWERLEVEL9K_PYENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
################[ goenv: go environment (https://github.com/syndbg/goenv) ]################
# Goenv color.
typeset -g POWERLEVEL9K_GOENV_FOREGROUND=0
typeset -g POWERLEVEL9K_GOENV_BACKGROUND=4
# Hide go version if it doesn't come from one of these sources.
typeset -g POWERLEVEL9K_GOENV_SOURCES=(shell local global)
# If set to false, hide go version if it's the same as global:
# $(goenv version-name) == $(goenv global).
typeset -g POWERLEVEL9K_GOENV_PROMPT_ALWAYS_SHOW=false
# If set to false, hide go version if it's equal to "system".
typeset -g POWERLEVEL9K_GOENV_SHOW_SYSTEM=true
# Custom icon.
# typeset -g POWERLEVEL9K_GOENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
##########[ nodenv: node.js version from nodenv (https://github.com/nodenv/nodenv) ]##########
# Nodenv color.
typeset -g POWERLEVEL9K_NODENV_FOREGROUND=2
typeset -g POWERLEVEL9K_NODENV_BACKGROUND=0
# Hide node version if it doesn't come from one of these sources.
typeset -g POWERLEVEL9K_NODENV_SOURCES=(shell local global)
# If set to false, hide node version if it's the same as global:
# $(nodenv version-name) == $(nodenv global).
typeset -g POWERLEVEL9K_NODENV_PROMPT_ALWAYS_SHOW=false
# If set to false, hide node version if it's equal to "system".
typeset -g POWERLEVEL9K_NODENV_SHOW_SYSTEM=true
# Custom icon.
# typeset -g POWERLEVEL9K_NODENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
##############[ nvm: node.js version from nvm (https://github.com/nvm-sh/nvm) ]###############
# Nvm color.
typeset -g POWERLEVEL9K_NVM_FOREGROUND=0
typeset -g POWERLEVEL9K_NVM_BACKGROUND=5
# Custom icon.
# typeset -g POWERLEVEL9K_NVM_VISUAL_IDENTIFIER_EXPANSION='⭐'
############[ nodeenv: node.js environment (https://github.com/ekalinin/nodeenv) ]############
# Nodeenv color.
typeset -g POWERLEVEL9K_NODEENV_FOREGROUND=2
typeset -g POWERLEVEL9K_NODEENV_BACKGROUND=0
# Don't show Node version next to the environment name.
typeset -g POWERLEVEL9K_NODEENV_SHOW_NODE_VERSION=false
# Separate environment name from Node version only with a space.
typeset -g POWERLEVEL9K_NODEENV_{LEFT,RIGHT}_DELIMITER=
# Custom icon.
# typeset -g POWERLEVEL9K_NODEENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
##############################[ node_version: node.js version ]###############################
# Node version color.
typeset -g POWERLEVEL9K_NODE_VERSION_FOREGROUND=7
typeset -g POWERLEVEL9K_NODE_VERSION_BACKGROUND=2
# Show node version only when in a directory tree containing package.json.
typeset -g POWERLEVEL9K_NODE_VERSION_PROJECT_ONLY=true
# Custom icon.
# typeset -g POWERLEVEL9K_NODE_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
#######################[ go_version: go version (https://golang.org) ]########################
# Go version color.
typeset -g POWERLEVEL9K_GO_VERSION_FOREGROUND=255
typeset -g POWERLEVEL9K_GO_VERSION_BACKGROUND=2
# Show go version only when in a go project subdirectory.
typeset -g POWERLEVEL9K_GO_VERSION_PROJECT_ONLY=true
# Custom icon.
# typeset -g POWERLEVEL9K_GO_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
#################[ rust_version: rustc version (https://www.rust-lang.org) ]##################
# Rust version color.
typeset -g POWERLEVEL9K_RUST_VERSION_FOREGROUND=0
typeset -g POWERLEVEL9K_RUST_VERSION_BACKGROUND=208
# Show rust version only when in a rust project subdirectory.
typeset -g POWERLEVEL9K_RUST_VERSION_PROJECT_ONLY=true
# Custom icon.
# typeset -g POWERLEVEL9K_RUST_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
###############[ dotnet_version: .NET version (https://dotnet.microsoft.com) ]################
# .NET version color.
typeset -g POWERLEVEL9K_DOTNET_VERSION_FOREGROUND=7
typeset -g POWERLEVEL9K_DOTNET_VERSION_BACKGROUND=5
# Show .NET version only when in a .NET project subdirectory.
typeset -g POWERLEVEL9K_DOTNET_VERSION_PROJECT_ONLY=true
# Custom icon.
# typeset -g POWERLEVEL9K_DOTNET_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
#####################[ php_version: php version (https://www.php.net/) ]######################
# PHP version color.
typeset -g POWERLEVEL9K_PHP_VERSION_FOREGROUND=0
typeset -g POWERLEVEL9K_PHP_VERSION_BACKGROUND=5
# Show PHP version only when in a PHP project subdirectory.
typeset -g POWERLEVEL9K_PHP_VERSION_PROJECT_ONLY=true
# Custom icon.
# typeset -g POWERLEVEL9K_PHP_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
##########[ laravel_version: laravel php framework version (https://laravel.com/) ]###########
# Laravel version color.
typeset -g POWERLEVEL9K_LARAVEL_VERSION_FOREGROUND=1
typeset -g POWERLEVEL9K_LARAVEL_VERSION_BACKGROUND=7
# Custom icon.
# typeset -g POWERLEVEL9K_LARAVEL_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
#############[ rbenv: ruby version from rbenv (https://github.com/rbenv/rbenv) ]##############
# Rbenv color.
typeset -g POWERLEVEL9K_RBENV_FOREGROUND=0
typeset -g POWERLEVEL9K_RBENV_BACKGROUND=1
# Hide ruby version if it doesn't come from one of these sources.
typeset -g POWERLEVEL9K_RBENV_SOURCES=(shell local global)
# If set to false, hide ruby version if it's the same as global:
# $(rbenv version-name) == $(rbenv global).
typeset -g POWERLEVEL9K_RBENV_PROMPT_ALWAYS_SHOW=false
# If set to false, hide ruby version if it's equal to "system".
typeset -g POWERLEVEL9K_RBENV_SHOW_SYSTEM=true
# Custom icon.
# typeset -g POWERLEVEL9K_RBENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
####################[ java_version: java version (https://www.java.com/) ]####################
# Java version color.
typeset -g POWERLEVEL9K_JAVA_VERSION_FOREGROUND=1
typeset -g POWERLEVEL9K_JAVA_VERSION_BACKGROUND=7
# Show java version only when in a java project subdirectory.
typeset -g POWERLEVEL9K_JAVA_VERSION_PROJECT_ONLY=true
# Show brief version.
typeset -g POWERLEVEL9K_JAVA_VERSION_FULL=false
# Custom icon.
# typeset -g POWERLEVEL9K_JAVA_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
###[ package: name@version from package.json (https://docs.npmjs.com/files/package.json) ]####
# Package color.
typeset -g POWERLEVEL9K_PACKAGE_FOREGROUND=0
typeset -g POWERLEVEL9K_PACKAGE_BACKGROUND=6
# Package format. The following parameters are available within the expansion.
#
# - P9K_PACKAGE_NAME The value of `name` field in package.json.
# - P9K_PACKAGE_VERSION The value of `version` field in package.json.
#
# typeset -g POWERLEVEL9K_PACKAGE_CONTENT_EXPANSION='${P9K_PACKAGE_NAME//\%/%%}@${P9K_PACKAGE_VERSION//\%/%%}'
# Custom icon.
# typeset -g POWERLEVEL9K_PACKAGE_VISUAL_IDENTIFIER_EXPANSION='⭐'
#######################[ rvm: ruby version from rvm (https://rvm.io) ]########################
# Rvm color.
typeset -g POWERLEVEL9K_RVM_FOREGROUND=0
typeset -g POWERLEVEL9K_RVM_BACKGROUND=240
# Don't show @gemset at the end.
typeset -g POWERLEVEL9K_RVM_SHOW_GEMSET=false
# Don't show ruby- at the front.
typeset -g POWERLEVEL9K_RVM_SHOW_PREFIX=false
# Custom icon.
# typeset -g POWERLEVEL9K_RVM_VISUAL_IDENTIFIER_EXPANSION='⭐'
###########[ fvm: flutter version management (https://github.com/leoafarias/fvm) ]############
# Fvm color.
typeset -g POWERLEVEL9K_FVM_FOREGROUND=0
typeset -g POWERLEVEL9K_FVM_BACKGROUND=4
# Custom icon.
# typeset -g POWERLEVEL9K_FVM_VISUAL_IDENTIFIER_EXPANSION='⭐'
##########[ luaenv: lua version from luaenv (https://github.com/cehoffman/luaenv) ]###########
# Lua color.
typeset -g POWERLEVEL9K_LUAENV_FOREGROUND=0
typeset -g POWERLEVEL9K_LUAENV_BACKGROUND=4
# Hide lua version if it doesn't come from one of these sources.
typeset -g POWERLEVEL9K_LUAENV_SOURCES=(shell local global)
# If set to false, hide lua version if it's the same as global:
# $(luaenv version-name) == $(luaenv global).
typeset -g POWERLEVEL9K_LUAENV_PROMPT_ALWAYS_SHOW=false
# If set to false, hide lua version if it's equal to "system".
typeset -g POWERLEVEL9K_LUAENV_SHOW_SYSTEM=true
# Custom icon.
# typeset -g POWERLEVEL9K_LUAENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
###############[ jenv: java version from jenv (https://github.com/jenv/jenv) ]################
# Java color.
typeset -g POWERLEVEL9K_JENV_FOREGROUND=1
typeset -g POWERLEVEL9K_JENV_BACKGROUND=7
# Hide java version if it doesn't come from one of these sources.
typeset -g POWERLEVEL9K_JENV_SOURCES=(shell local global)
# If set to false, hide java version if it's the same as global:
# $(jenv version-name) == $(jenv global).
typeset -g POWERLEVEL9K_JENV_PROMPT_ALWAYS_SHOW=false
# If set to false, hide java version if it's equal to "system".
typeset -g POWERLEVEL9K_JENV_SHOW_SYSTEM=true
# Custom icon.
# typeset -g POWERLEVEL9K_JENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
###########[ plenv: perl version from plenv (https://github.com/tokuhirom/plenv) ]############
# Perl color.
typeset -g POWERLEVEL9K_PLENV_FOREGROUND=0
typeset -g POWERLEVEL9K_PLENV_BACKGROUND=4
# Hide perl version if it doesn't come from one of these sources.
typeset -g POWERLEVEL9K_PLENV_SOURCES=(shell local global)
# If set to false, hide perl version if it's the same as global:
# $(plenv version-name) == $(plenv global).
typeset -g POWERLEVEL9K_PLENV_PROMPT_ALWAYS_SHOW=false
# If set to false, hide perl version if it's equal to "system".
typeset -g POWERLEVEL9K_PLENV_SHOW_SYSTEM=true
# Custom icon.
# typeset -g POWERLEVEL9K_PLENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
############[ phpenv: php version from phpenv (https://github.com/phpenv/phpenv) ]############
# PHP color.
typeset -g POWERLEVEL9K_PHPENV_FOREGROUND=0
typeset -g POWERLEVEL9K_PHPENV_BACKGROUND=5
# Hide php version if it doesn't come from one of these sources.
typeset -g POWERLEVEL9K_PHPENV_SOURCES=(shell local global)
# If set to false, hide php version if it's the same as global:
# $(phpenv version-name) == $(phpenv global).
typeset -g POWERLEVEL9K_PHPENV_PROMPT_ALWAYS_SHOW=false
# If set to false, hide PHP version if it's equal to "system".
typeset -g POWERLEVEL9K_PHPENV_SHOW_SYSTEM=true
# Custom icon.
# typeset -g POWERLEVEL9K_PHPENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
#######[ scalaenv: scala version from scalaenv (https://github.com/scalaenv/scalaenv) ]#######
# Scala color.
typeset -g POWERLEVEL9K_SCALAENV_FOREGROUND=0
typeset -g POWERLEVEL9K_SCALAENV_BACKGROUND=1
# Hide scala version if it doesn't come from one of these sources.
typeset -g POWERLEVEL9K_SCALAENV_SOURCES=(shell local global)
# If set to false, hide scala version if it's the same as global:
# $(scalaenv version-name) == $(scalaenv global).
typeset -g POWERLEVEL9K_SCALAENV_PROMPT_ALWAYS_SHOW=false
# If set to false, hide scala version if it's equal to "system".
typeset -g POWERLEVEL9K_SCALAENV_SHOW_SYSTEM=true
# Custom icon.
# typeset -g POWERLEVEL9K_SCALAENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
##########[ haskell_stack: haskell version from stack (https://haskellstack.org/) ]###########
# Haskell color.
typeset -g POWERLEVEL9K_HASKELL_STACK_FOREGROUND=0
typeset -g POWERLEVEL9K_HASKELL_STACK_BACKGROUND=3
# Hide haskell version if it doesn't come from one of these sources.
#
# shell: version is set by STACK_YAML
# local: version is set by stack.yaml up the directory tree
# global: version is set by the implicit global project (~/.stack/global-project/stack.yaml)
typeset -g POWERLEVEL9K_HASKELL_STACK_SOURCES=(shell local)
# If set to false, hide haskell version if it's the same as in the implicit global project.
typeset -g POWERLEVEL9K_HASKELL_STACK_ALWAYS_SHOW=true
# Custom icon.
# typeset -g POWERLEVEL9K_HASKELL_STACK_VISUAL_IDENTIFIER_EXPANSION='⭐'
################[ terraform: terraform workspace (https://www.terraform.io) ]#################
# Don't show terraform workspace if it's literally "default".
typeset -g POWERLEVEL9K_TERRAFORM_SHOW_DEFAULT=false
# POWERLEVEL9K_TERRAFORM_CLASSES is an array with even number of elements. The first element
# in each pair defines a pattern against which the current terraform workspace gets matched.
# More specifically, it's P9K_CONTENT prior to the application of context expansion (see below)
# that gets matched. If you unset all POWERLEVEL9K_TERRAFORM_*CONTENT_EXPANSION parameters,
# you'll see this value in your prompt. The second element of each pair in
# POWERLEVEL9K_TERRAFORM_CLASSES defines the workspace class. Patterns are tried in order. The
# first match wins.
#
# For example, given these settings:
#
# typeset -g POWERLEVEL9K_TERRAFORM_CLASSES=(
# '*prod*' PROD
# '*test*' TEST
# '*' OTHER)
#
# If your current terraform workspace is "project_test", its class is TEST because "project_test"
# doesn't match the pattern '*prod*' but does match '*test*'.
#
# You can define different colors, icons and content expansions for different classes:
#
# typeset -g POWERLEVEL9K_TERRAFORM_TEST_FOREGROUND=2
# typeset -g POWERLEVEL9K_TERRAFORM_TEST_BACKGROUND=0
# typeset -g POWERLEVEL9K_TERRAFORM_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_TERRAFORM_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <'
typeset -g POWERLEVEL9K_TERRAFORM_CLASSES=(
# '*prod*' PROD # These values are examples that are unlikely
# '*test*' TEST # to match your needs. Customize them as needed.
'*' OTHER)
typeset -g POWERLEVEL9K_TERRAFORM_OTHER_FOREGROUND=4
typeset -g POWERLEVEL9K_TERRAFORM_OTHER_BACKGROUND=0
# typeset -g POWERLEVEL9K_TERRAFORM_OTHER_VISUAL_IDENTIFIER_EXPANSION='⭐'
#############[ terraform_version: terraform version (https://www.terraform.io) ]##############
# Terraform version color.
typeset -g POWERLEVEL9K_TERRAFORM_VERSION_FOREGROUND=4
typeset -g POWERLEVEL9K_TERRAFORM_VERSION_BACKGROUND=0
# Custom icon.
# typeset -g POWERLEVEL9K_TERRAFORM_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐'
################[ terraform_version: It shows active terraform version (https://www.terraform.io) ]#################
typeset -g POWERLEVEL9K_TERRAFORM_VERSION_SHOW_ON_COMMAND='terraform|tf'
#############[ kubecontext: current kubernetes context (https://kubernetes.io/) ]#############
# Show kubecontext only when the the command you are typing invokes one of these tools.
# Tip: Remove the next line to always show kubecontext.
typeset -g POWERLEVEL9K_KUBECONTEXT_SHOW_ON_COMMAND='kubectl|helm|kubens|kubectx|oc|istioctl|kogito|k9s|helmfile|flux|fluxctl|stern'
# Kubernetes context classes for the purpose of using different colors, icons and expansions with
# different contexts.
#
# POWERLEVEL9K_KUBECONTEXT_CLASSES is an array with even number of elements. The first element
# in each pair defines a pattern against which the current kubernetes context gets matched.
# More specifically, it's P9K_CONTENT prior to the application of context expansion (see below)
# that gets matched. If you unset all POWERLEVEL9K_KUBECONTEXT_*CONTENT_EXPANSION parameters,
# you'll see this value in your prompt. The second element of each pair in
# POWERLEVEL9K_KUBECONTEXT_CLASSES defines the context class. Patterns are tried in order. The
# first match wins.
#
# For example, given these settings:
#
# typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=(
# '*prod*' PROD
# '*test*' TEST
# '*' DEFAULT)
#
# If your current kubernetes context is "deathray-testing/default", its class is TEST
# because "deathray-testing/default" doesn't match the pattern '*prod*' but does match '*test*'.
#
# You can define different colors, icons and content expansions for different classes:
#
# typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_FOREGROUND=0
# typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_BACKGROUND=2
# typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <'
typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=(
# '*prod*' PROD # These values are examples that are unlikely
# '*test*' TEST # to match your needs. Customize them as needed.
'*' DEFAULT)
typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_FOREGROUND=7
typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_BACKGROUND=5
# typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐'
# Use POWERLEVEL9K_KUBECONTEXT_CONTENT_EXPANSION to specify the content displayed by kubecontext
# segment. Parameter expansions are very flexible and fast, too. See reference:
# http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion.
#
# Within the expansion the following parameters are always available:
#
# - P9K_CONTENT The content that would've been displayed if there was no content
# expansion defined.
# - P9K_KUBECONTEXT_NAME The current context's name. Corresponds to column NAME in the
# output of `kubectl config get-contexts`.
# - P9K_KUBECONTEXT_CLUSTER The current context's cluster. Corresponds to column CLUSTER in the
# output of `kubectl config get-contexts`.
# - P9K_KUBECONTEXT_NAMESPACE The current context's namespace. Corresponds to column NAMESPACE
# in the output of `kubectl config get-contexts`. If there is no
# namespace, the parameter is set to "default".
# - P9K_KUBECONTEXT_USER The current context's user. Corresponds to column AUTHINFO in the
# output of `kubectl config get-contexts`.
#
# If the context points to Google Kubernetes Engine (GKE) or Elastic Kubernetes Service (EKS),
# the following extra parameters are available:
#
# - P9K_KUBECONTEXT_CLOUD_NAME Either "gke" or "eks".
# - P9K_KUBECONTEXT_CLOUD_ACCOUNT Account/project ID.
# - P9K_KUBECONTEXT_CLOUD_ZONE Availability zone.
# - P9K_KUBECONTEXT_CLOUD_CLUSTER Cluster.
#
# P9K_KUBECONTEXT_CLOUD_* parameters are derived from P9K_KUBECONTEXT_CLUSTER. For example,
# if P9K_KUBECONTEXT_CLUSTER is "gke_my-account_us-east1-a_my-cluster-01":
#
# - P9K_KUBECONTEXT_CLOUD_NAME=gke
# - P9K_KUBECONTEXT_CLOUD_ACCOUNT=my-account
# - P9K_KUBECONTEXT_CLOUD_ZONE=us-east1-a
# - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01
#
# If P9K_KUBECONTEXT_CLUSTER is "arn:aws:eks:us-east-1:123456789012:cluster/my-cluster-01":
#
# - P9K_KUBECONTEXT_CLOUD_NAME=eks
# - P9K_KUBECONTEXT_CLOUD_ACCOUNT=123456789012
# - P9K_KUBECONTEXT_CLOUD_ZONE=us-east-1
# - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01
typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION=
# Show P9K_KUBECONTEXT_CLOUD_CLUSTER if it's not empty and fall back to P9K_KUBECONTEXT_NAME.
POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${P9K_KUBECONTEXT_CLOUD_CLUSTER:-${P9K_KUBECONTEXT_NAME}}'
# Append the current context's namespace if it's not "default".
POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${${:-/$P9K_KUBECONTEXT_NAMESPACE}:#/default}'
# Custom prefix.
# typeset -g POWERLEVEL9K_KUBECONTEXT_PREFIX='at '
#[ aws: aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) ]#
# Show aws only when the the command you are typing invokes one of these tools.
# Tip: Remove the next line to always show aws.
typeset -g POWERLEVEL9K_AWS_SHOW_ON_COMMAND='aws|awless|terraform|pulumi|terragrunt'
# POWERLEVEL9K_AWS_CLASSES is an array with even number of elements. The first element
# in each pair defines a pattern against which the current AWS profile gets matched.
# More specifically, it's P9K_CONTENT prior to the application of context expansion (see below)
# that gets matched. If you unset all POWERLEVEL9K_AWS_*CONTENT_EXPANSION parameters,
# you'll see this value in your prompt. The second element of each pair in
# POWERLEVEL9K_AWS_CLASSES defines the profile class. Patterns are tried in order. The
# first match wins.
#
# For example, given these settings:
#
# typeset -g POWERLEVEL9K_AWS_CLASSES=(
# '*prod*' PROD
# '*test*' TEST
# '*' DEFAULT)
#
# If your current AWS profile is "company_test", its class is TEST
# because "company_test" doesn't match the pattern '*prod*' but does match '*test*'.
#
# You can define different colors, icons and content expansions for different classes:
#
# typeset -g POWERLEVEL9K_AWS_TEST_FOREGROUND=28
# typeset -g POWERLEVEL9K_AWS_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_AWS_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <'
typeset -g POWERLEVEL9K_AWS_CLASSES=(
# '*prod*' PROD # These values are examples that are unlikely
# '*test*' TEST # to match your needs. Customize them as needed.
'*' DEFAULT)
typeset -g POWERLEVEL9K_AWS_DEFAULT_FOREGROUND=7
typeset -g POWERLEVEL9K_AWS_DEFAULT_BACKGROUND=1
# typeset -g POWERLEVEL9K_AWS_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐'
# AWS segment format. The following parameters are available within the expansion.
#
# - P9K_AWS_PROFILE The name of the current AWS profile.
# - P9K_AWS_REGION The region associated with the current AWS profile.
typeset -g POWERLEVEL9K_AWS_CONTENT_EXPANSION='${P9K_AWS_PROFILE//\%/%%}${P9K_AWS_REGION:+ ${P9K_AWS_REGION//\%/%%}}'
#[ aws_eb_env: aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) ]#
# AWS Elastic Beanstalk environment color.
typeset -g POWERLEVEL9K_AWS_EB_ENV_FOREGROUND=2
typeset -g POWERLEVEL9K_AWS_EB_ENV_BACKGROUND=0
# Custom icon.
# typeset -g POWERLEVEL9K_AWS_EB_ENV_VISUAL_IDENTIFIER_EXPANSION='⭐'
##########[ azure: azure account name (https://docs.microsoft.com/en-us/cli/azure) ]##########
# Show azure only when the the command you are typing invokes one of these tools.
# Tip: Remove the next line to always show azure.
typeset -g POWERLEVEL9K_AZURE_SHOW_ON_COMMAND='az|terraform|pulumi|terragrunt'
# Azure account name color.
typeset -g POWERLEVEL9K_AZURE_FOREGROUND=7
typeset -g POWERLEVEL9K_AZURE_BACKGROUND=4
# Custom icon.
# typeset -g POWERLEVEL9K_AZURE_VISUAL_IDENTIFIER_EXPANSION='⭐'
##########[ gcloud: google cloud account and project (https://cloud.google.com/) ]###########
# Show gcloud only when the the command you are typing invokes one of these tools.
# Tip: Remove the next line to always show gcloud.
typeset -g POWERLEVEL9K_GCLOUD_SHOW_ON_COMMAND='gcloud|gcs'
# Google cloud color.
typeset -g POWERLEVEL9K_GCLOUD_FOREGROUND=7
typeset -g POWERLEVEL9K_GCLOUD_BACKGROUND=4
# Google cloud format. Change the value of POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION and/or
# POWERLEVEL9K_GCLOUD_COMPLETE_CONTENT_EXPANSION if the default is too verbose or not informative
# enough. You can use the following parameters in the expansions. Each of them corresponds to the
# output of `gcloud` tool.
#
# Parameter | Source
# -------------------------|--------------------------------------------------------------------
# P9K_GCLOUD_CONFIGURATION | gcloud config configurations list --format='value(name)'
# P9K_GCLOUD_ACCOUNT | gcloud config get-value account
# P9K_GCLOUD_PROJECT_ID | gcloud config get-value project
# P9K_GCLOUD_PROJECT_NAME | gcloud projects describe $P9K_GCLOUD_PROJECT_ID --format='value(name)'
#
# Note: ${VARIABLE//\%/%%} expands to ${VARIABLE} with all occurrences of '%' replaced with '%%'.
#
# Obtaining project name requires sending a request to Google servers. This can take a long time
# and even fail. When project name is unknown, P9K_GCLOUD_PROJECT_NAME is not set and gcloud
# prompt segment is in state PARTIAL. When project name gets known, P9K_GCLOUD_PROJECT_NAME gets
# set and gcloud prompt segment transitions to state COMPLETE.
#
# You can customize the format, icon and colors of gcloud segment separately for states PARTIAL
# and COMPLETE. You can also hide gcloud in state PARTIAL by setting
# POWERLEVEL9K_GCLOUD_PARTIAL_VISUAL_IDENTIFIER_EXPANSION and
# POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION to empty.
typeset -g POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION='${P9K_GCLOUD_PROJECT_ID//\%/%%}'
typeset -g POWERLEVEL9K_GCLOUD_COMPLETE_CONTENT_EXPANSION='${P9K_GCLOUD_PROJECT_NAME//\%/%%}'
# Send a request to Google (by means of `gcloud projects describe ...`) to obtain project name
# this often. Negative value disables periodic polling. In this mode project name is retrieved
# only when the current configuration, account or project id changes.
typeset -g POWERLEVEL9K_GCLOUD_REFRESH_PROJECT_NAME_SECONDS=60
# Custom icon.
# typeset -g POWERLEVEL9K_GCLOUD_VISUAL_IDENTIFIER_EXPANSION='⭐'
#[ google_app_cred: google application credentials (https://cloud.google.com/docs/authentication/production) ]#
# Show google_app_cred only when the the command you are typing invokes one of these tools.
# Tip: Remove the next line to always show google_app_cred.
typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_SHOW_ON_COMMAND='terraform|pulumi|terragrunt'
# Google application credentials classes for the purpose of using different colors, icons and
# expansions with different credentials.
#
# POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES is an array with even number of elements. The first
# element in each pair defines a pattern against which the current kubernetes context gets
# matched. More specifically, it's P9K_CONTENT prior to the application of context expansion
# (see below) that gets matched. If you unset all POWERLEVEL9K_GOOGLE_APP_CRED_*CONTENT_EXPANSION
# parameters, you'll see this value in your prompt. The second element of each pair in
# POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES defines the context class. Patterns are tried in order.
# The first match wins.
#
# For example, given these settings:
#
# typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES=(
# '*:*prod*:*' PROD
# '*:*test*:*' TEST
# '*' DEFAULT)
#
# If your current Google application credentials is "service_account deathray-testing x@y.com",
# its class is TEST because it doesn't match the pattern '* *prod* *' but does match '* *test* *'.
#
# You can define different colors, icons and content expansions for different classes:
#
# typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_FOREGROUND=28
# typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐'
# typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_TEST_CONTENT_EXPANSION='$P9K_GOOGLE_APP_CRED_PROJECT_ID'
typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_CLASSES=(
# '*:*prod*:*' PROD # These values are examples that are unlikely
# '*:*test*:*' TEST # to match your needs. Customize them as needed.
'*' DEFAULT)
typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_FOREGROUND=7
typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_BACKGROUND=4
# typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐'
# Use POWERLEVEL9K_GOOGLE_APP_CRED_CONTENT_EXPANSION to specify the content displayed by
# google_app_cred segment. Parameter expansions are very flexible and fast, too. See reference:
# http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion.
#
# You can use the following parameters in the expansion. Each of them corresponds to one of the
# fields in the JSON file pointed to by GOOGLE_APPLICATION_CREDENTIALS.
#
# Parameter | JSON key file field
# ---------------------------------+---------------
# P9K_GOOGLE_APP_CRED_TYPE | type
# P9K_GOOGLE_APP_CRED_PROJECT_ID | project_id
# P9K_GOOGLE_APP_CRED_CLIENT_EMAIL | client_email
#
# Note: ${VARIABLE//\%/%%} expands to ${VARIABLE} with all occurrences of '%' replaced by '%%'.
typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_CONTENT_EXPANSION='${P9K_GOOGLE_APP_CRED_PROJECT_ID//\%/%%}'
##############[ toolbox: toolbox name (https://github.com/containers/toolbox) ]###############
# Toolbox color.
typeset -g POWERLEVEL9K_TOOLBOX_FOREGROUND=0
typeset -g POWERLEVEL9K_TOOLBOX_BACKGROUND=3
# Don't display the name of the toolbox if it matches fedora-toolbox-*.
typeset -g POWERLEVEL9K_TOOLBOX_CONTENT_EXPANSION='${P9K_TOOLBOX_NAME:#fedora-toolbox-*}'
# Custom icon.
# typeset -g POWERLEVEL9K_TOOLBOX_VISUAL_IDENTIFIER_EXPANSION='⭐'
# Custom prefix.
# typeset -g POWERLEVEL9K_TOOLBOX_PREFIX='in '
###############################[ public_ip: public IP address ]###############################
# Public IP color.
typeset -g POWERLEVEL9K_PUBLIC_IP_FOREGROUND=7
typeset -g POWERLEVEL9K_PUBLIC_IP_BACKGROUND=0
# Custom icon.
# typeset -g POWERLEVEL9K_PUBLIC_IP_VISUAL_IDENTIFIER_EXPANSION='⭐'
########################[ vpn_ip: virtual private network indicator ]#########################
# VPN IP color.
typeset -g POWERLEVEL9K_VPN_IP_FOREGROUND=0
typeset -g POWERLEVEL9K_VPN_IP_BACKGROUND=6
# When on VPN, show just an icon without the IP address.
# Tip: To display the private IP address when on VPN, remove the next line.
typeset -g POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION=
# Regular expression for the VPN network interface. Run `ifconfig` or `ip -4 a show` while on VPN
# to see the name of the interface.
typeset -g POWERLEVEL9K_VPN_IP_INTERFACE='(gpd|wg|(.*tun)|tailscale)[0-9]*'
# If set to true, show one segment per matching network interface. If set to false, show only
# one segment corresponding to the first matching network interface.
# Tip: If you set it to true, you'll probably want to unset POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION.
typeset -g POWERLEVEL9K_VPN_IP_SHOW_ALL=false
# Custom icon.
# typeset -g POWERLEVEL9K_VPN_IP_VISUAL_IDENTIFIER_EXPANSION='⭐'
###########[ ip: ip address and bandwidth usage for a specified network interface ]###########
# IP color.
typeset -g POWERLEVEL9K_IP_BACKGROUND=4
typeset -g POWERLEVEL9K_IP_FOREGROUND=0
# The following parameters are accessible within the expansion:
#
# Parameter | Meaning
# ----------------------+-------------------------------------------
# P9K_IP_IP | IP address
# P9K_IP_INTERFACE | network interface
# P9K_IP_RX_BYTES | total number of bytes received
# P9K_IP_TX_BYTES | total number of bytes sent
# P9K_IP_RX_BYTES_DELTA | number of bytes received since last prompt
# P9K_IP_TX_BYTES_DELTA | number of bytes sent since last prompt
# P9K_IP_RX_RATE | receive rate (since last prompt)
# P9K_IP_TX_RATE | send rate (since last prompt)
typeset -g POWERLEVEL9K_IP_CONTENT_EXPANSION='${P9K_IP_RX_RATE:+⇣$P9K_IP_RX_RATE }${P9K_IP_TX_RATE:+⇡$P9K_IP_TX_RATE }$P9K_IP_IP'
# Show information for the first network interface whose name matches this regular expression.
# Run `ifconfig` or `ip -4 a show` to see the names of all network interfaces.
typeset -g POWERLEVEL9K_IP_INTERFACE='[ew].*'
# Custom icon.
# typeset -g POWERLEVEL9K_IP_VISUAL_IDENTIFIER_EXPANSION='⭐'
#########################[ proxy: system-wide http/https/ftp proxy ]##########################
# Proxy color.
typeset -g POWERLEVEL9K_PROXY_FOREGROUND=4
typeset -g POWERLEVEL9K_PROXY_BACKGROUND=0
# Custom icon.
# typeset -g POWERLEVEL9K_PROXY_VISUAL_IDENTIFIER_EXPANSION='⭐'
################################[ battery: internal battery ]#################################
# Show battery in red when it's below this level and not connected to power supply.
typeset -g POWERLEVEL9K_BATTERY_LOW_THRESHOLD=20
typeset -g POWERLEVEL9K_BATTERY_LOW_FOREGROUND=1
# Show battery in green when it's charging or fully charged.
typeset -g POWERLEVEL9K_BATTERY_{CHARGING,CHARGED}_FOREGROUND=2
# Show battery in yellow when it's discharging.
typeset -g POWERLEVEL9K_BATTERY_DISCONNECTED_FOREGROUND=3
# Battery pictograms going from low to high level of charge.
typeset -g POWERLEVEL9K_BATTERY_STAGES='\uf58d\uf579\uf57a\uf57b\uf57c\uf57d\uf57e\uf57f\uf580\uf581\uf578'
# Don't show the remaining time to charge/discharge.
typeset -g POWERLEVEL9K_BATTERY_VERBOSE=false
typeset -g POWERLEVEL9K_BATTERY_BACKGROUND=0
#####################################[ wifi: wifi speed ]#####################################
# WiFi color.
typeset -g POWERLEVEL9K_WIFI_FOREGROUND=0
typeset -g POWERLEVEL9K_WIFI_BACKGROUND=4
# Custom icon.
# typeset -g POWERLEVEL9K_WIFI_VISUAL_IDENTIFIER_EXPANSION='⭐'
# Use different colors and icons depending on signal strength ($P9K_WIFI_BARS).
#
# # Wifi colors and icons for different signal strength levels (low to high).
# typeset -g my_wifi_fg=(0 0 0 0 0) # <-- change these values
# typeset -g my_wifi_icon=('WiFi' 'WiFi' 'WiFi' 'WiFi' 'WiFi') # <-- change these values
#
# typeset -g POWERLEVEL9K_WIFI_CONTENT_EXPANSION='%F{${my_wifi_fg[P9K_WIFI_BARS+1]}}$P9K_WIFI_LAST_TX_RATE Mbps'
# typeset -g POWERLEVEL9K_WIFI_VISUAL_IDENTIFIER_EXPANSION='%F{${my_wifi_fg[P9K_WIFI_BARS+1]}}${my_wifi_icon[P9K_WIFI_BARS+1]}'
#
# The following parameters are accessible within the expansions:
#
# Parameter | Meaning
# ----------------------+---------------
# P9K_WIFI_SSID | service set identifier, a.k.a. network name
# P9K_WIFI_LINK_AUTH | authentication protocol such as "wpa2-psk" or "none"; empty if unknown
# P9K_WIFI_LAST_TX_RATE | wireless transmit rate in megabits per second
# P9K_WIFI_RSSI | signal strength in dBm, from -120 to 0
# P9K_WIFI_NOISE | noise in dBm, from -120 to 0
# P9K_WIFI_BARS | signal strength in bars, from 0 to 4 (derived from P9K_WIFI_RSSI and P9K_WIFI_NOISE)
####################################[ time: current time ]####################################
# Current time color.
typeset -g POWERLEVEL9K_TIME_FOREGROUND=0
typeset -g POWERLEVEL9K_TIME_BACKGROUND=7
# Format for the current time: 09:51:02. See `man 3 strftime`.
typeset -g POWERLEVEL9K_TIME_FORMAT='%D{%H:%M:%S}'
# If set to true, time will update when you hit enter. This way prompts for the past
# commands will contain the start times of their commands as opposed to the default
# behavior where they contain the end times of their preceding commands.
typeset -g POWERLEVEL9K_TIME_UPDATE_ON_COMMAND=false
# Custom icon.
# typeset -g POWERLEVEL9K_TIME_VISUAL_IDENTIFIER_EXPANSION='⭐'
# Custom prefix.
# typeset -g POWERLEVEL9K_TIME_PREFIX='at '
# Example of a user-defined prompt segment. Function prompt_example will be called on every
# prompt if `example` prompt segment is added to POWERLEVEL9K_LEFT_PROMPT_ELEMENTS or
# POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS. It displays an icon and yellow text on red background
# greeting the user.
#
# Type `p10k help segment` for documentation and a more sophisticated example.
function prompt_example() {
p10k segment -b 1 -f 3 -i '⭐' -t 'hello, %n'
}
# User-defined prompt segments may optionally provide an instant_prompt_* function. Its job
# is to generate the prompt segment for display in instant prompt. See
# https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt.
#
# Powerlevel10k will call instant_prompt_* at the same time as the regular prompt_* function
# and will record all `p10k segment` calls it makes. When displaying instant prompt, Powerlevel10k
# will replay these calls without actually calling instant_prompt_*. It is imperative that
# instant_prompt_* always makes the same `p10k segment` calls regardless of environment. If this
# rule is not observed, the content of instant prompt will be incorrect.
#
# Usually, you should either not define instant_prompt_* or simply call prompt_* from it. If
# instant_prompt_* is not defined for a segment, the segment won't be shown in instant prompt.
function instant_prompt_example() {
# Since prompt_example always makes the same `p10k segment` calls, we can call it from
# instant_prompt_example. This will give us the same `example` prompt segment in the instant
# and regular prompts.
prompt_example
}
# User-defined prompt segments can be customized the same way as built-in segments.
typeset -g POWERLEVEL9K_EXAMPLE_FOREGROUND=3
typeset -g POWERLEVEL9K_EXAMPLE_BACKGROUND=1
# typeset -g POWERLEVEL9K_EXAMPLE_VISUAL_IDENTIFIER_EXPANSION='⭐'
# Transient prompt works similarly to the builtin transient_rprompt option. It trims down prompt
# when accepting a command line. Supported values:
#
# - off: Don't change prompt when accepting a command line.
# - always: Trim down prompt when accepting a command line.
# - same-dir: Trim down prompt when accepting a command line unless this is the first command
# typed after changing current working directory.
typeset -g POWERLEVEL9K_TRANSIENT_PROMPT=always
# Instant prompt mode.
#
# - off: Disable instant prompt. Choose this if you've tried instant prompt and found
# it incompatible with your zsh configuration files.
# - quiet: Enable instant prompt and don't print warnings when detecting console output
# during zsh initialization. Choose this if you've read and understood
# https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt.
# - verbose: Enable instant prompt and print a warning when detecting console output during
# zsh initialization. Choose this if you've never tried instant prompt, haven't
# seen the warning, or if you are unsure what this all means.
typeset -g POWERLEVEL9K_INSTANT_PROMPT=quiet
# Hot reload allows you to change POWERLEVEL9K options after Powerlevel10k has been initialized.
# For example, you can type POWERLEVEL9K_BACKGROUND=red and see your prompt turn red. Hot reload
# can slow down prompt by 1-2 milliseconds, so it's better to keep it turned off unless you
# really need it.
typeset -g POWERLEVEL9K_DISABLE_HOT_RELOAD=true
# If p10k is already loaded, reload configuration.
# This works even with POWERLEVEL9K_DISABLE_HOT_RELOAD=true.
(( ! $+functions[p10k] )) || p10k reload
}
# Tell `p10k configure` which file it should overwrite.
typeset -g POWERLEVEL9K_CONFIG_FILE=${${(%):-%x}:a}
(( ${#p10k_config_opts} )) && setopt ${p10k_config_opts[@]}
'builtin' 'unset' 'p10k_config_opts'

General

~/.config/fish/conf.d/editor.fish

set -Ux EDITOR nano

~/.config/fish/conf.d/c.fish

export LANG=en_US.UTF-8
export LC_ALL=C.UTF-8

~/.config/fish/conf.d/autojump.fish

[ -f /usr/share/autojump/autojump.fish ]; and source /usr/share/autojump/autojump.fish

~/.config/fish/conf.d/omf.fish

# Path to Oh My Fish install.
set -q XDG_DATA_HOME
  and set -gx OMF_PATH "$XDG_DATA_HOME/omf"
  or set -gx OMF_PATH "$HOME/.local/share/omf"

# Load Oh My Fish configuration.
source $OMF_PATH/init.fish

set -g theme_display_git yes
set -g theme_display_git_dirty yes
set -g theme_display_git_untracked yes
set -g theme_display_git_ahead_verbose yes
set -g theme_display_git_dirty_verbose yes
set -g theme_display_git_stashed_verbose yes
set -g theme_display_git_default_branch yes
set -g theme_git_default_branches master main
set -g theme_git_worktree_support yes
set -g theme_use_abbreviated_branch_name yes
set -g theme_display_vagrant yes
set -g theme_display_docker_machine no
set -g theme_display_k8s_context yes
set -g theme_display_hg yes
set -g theme_display_virtualenv no
set -g theme_display_nix no
set -g theme_display_ruby no
set -g theme_display_node yes
set -g theme_display_nvm yes
set -g theme_display_php yes
set -g theme_display_user ssh
set -g theme_display_hostname ssh
set -g theme_display_vi no
set -g theme_display_date yes
set -g theme_display_cmd_duration yes
set -g theme_title_display_process yes
set -g theme_title_display_path no
set -g theme_title_display_user yes
set -g theme_title_use_abbreviated_path no
set -g theme_date_format "+%a %H:%M"
set -g theme_date_timezone America/Los_Angeles
set -g theme_avoid_ambiguous_glyphs yes
set -g theme_powerline_fonts yes
set -g theme_nerd_fonts yes
set -g theme_show_exit_status yes
set -g theme_display_jobs_verbose yes
set -g default_user your_normal_user
set -g theme_color_scheme zenburn
set -g fish_prompt_pwd_dir_length 0
set -g theme_project_dir_length 1
set -g theme_newline_cursor yes
set -g theme_newline_prompt '> '

NVM

~/.config/fish/functions/nvm.fish

function nvm
  bass source ~/.nvm/nvm.sh --no-use ';' nvm $argv
end

~/.config/fish/functions/nvm_find_nvmrc.fish

function nvm_find_nvmrc
  bass source ~/.nvm/nvm.sh --no-use ';' nvm_find_nvmrc
end

~/.config/fish/functions/load_nvm.fish

function load_nvm --on-variable="PWD"
  set -l default_node_version (nvm version default)
  set -l node_version (nvm version)
  set -l nvmrc_path (nvm_find_nvmrc)
  if test -n "$nvmrc_path"
    set -l nvmrc_node_version (nvm version (cat $nvmrc_path))
    if test "$nvmrc_node_version" = "N/A"
      nvm install (cat $nvmrc_path)
    else if test nvmrc_node_version != node_version
      nvm use $nvmrc_node_version
    end
  else if test "$node_version" != "$default_node_version"
    echo "Reverting to default Node version"
    nvm use default
  end
end

~/.config/fish/conf.d/nvm.fish

#set --universal nvm_default_version node

# You must call it on initialization or listening to directory switching won't work
load_nvm

Upgrading Concerns

If you ever find yourself upgrading your old Arch Linux, from years ago, there might be some things you want to take into consideration.

These might be covered here.

PGP Keys

Without the latest keys you are nothing.

So never forget to first issue pacman -Sy archlinux-keyring before doing anything else

Kernel

I don't think there are any primary concerns here, that would need covering, but just in case, newest Kernel ^= best Kernel.

Don't care about displaylink packages and stuff.

Bootloader

GRUB

If you ever find yourself on a new GRUB version, diff the config files.

Also do not forget that you need to manually grub-install + grub-mkconfig your latest image - no warranties, though.

Initial Ramdisk

mkinitcpio

You might want to check if the hooks you use are still up to date.

You might find that the sd-lvm2 systemd hook has been renamed to just lvm2 since, what now, 2020?

Packages

Are your packages still configured the way they need to be?

Like with PHP, are your paths and custom configs still valid?

Docker

You might want to update the images/container you are using, no? :D

How To Install Arch Linux in 2024

Covers MBR (Legacy) and GPT (UEFI) installs.

Min-Max Edition, with "bleeding edge" usages (see GRUB).

This might not be for beginners, but I dunno.

Take your picks on going through it.

UEFI walkthrough also features full LUKS2 disk encryption. (Yes, including /boot - that's what full stands for, no? Internet advocates seem to have differing opinions.. looking at you, YouTubers!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment