From 1f105ac9d16c94c326be0c4de0fe3f8c4b27d6a4 Mon Sep 17 00:00:00 2001 From: h7x4 Date: Mon, 7 Mar 2022 16:01:52 +0100 Subject: [PATCH] Initial commit --- common/colors.nix | 30 + flake.lock | 66 + flake.nix | 88 + home.nix | 122 ++ hosts/eisei/configuration.nix | 284 +++ hosts/eisei/hardware-configuration.nix | 37 + hosts/tsuki/configuration.nix | 237 +++ hosts/tsuki/hardware-configuration.nix | 36 + hosts/tsuki/services/calibre.todo.nix | 12 + hosts/tsuki/services/cron-backups/mail.nix | 0 hosts/tsuki/services/cron-backups/pixiv.nix | 0 hosts/tsuki/services/cron-backups/reddit.nix | 0 hosts/tsuki/services/cron-backups/youtube.nix | 0 hosts/tsuki/services/dokuwiki.todo.nix | 9 + hosts/tsuki/services/gitea.nix | 62 + hosts/tsuki/services/gitlab/default.nix | 94 + hosts/tsuki/services/gitlab/genfiles.sh | 25 + hosts/tsuki/services/gitlab/runner.nix | 51 + hosts/tsuki/services/grafana.nix | 76 + hosts/tsuki/services/hydra.nix | 9 + hosts/tsuki/services/jitsi.nix | 16 + hosts/tsuki/services/libvirt.todo.nix | 0 hosts/tsuki/services/matrix.nix | 134 ++ hosts/tsuki/services/minecraft.todo.nix | 64 + hosts/tsuki/services/nginx.nix | 143 ++ hosts/tsuki/services/openldap.todo.nix | 74 + hosts/tsuki/services/openvpn.nix | 53 + hosts/tsuki/services/plex.nix | 21 + hosts/tsuki/services/samba.todo.nix | 23 + hosts/tsuki/services/searx.nix | 61 + hosts/tsuki/services/syncthing.todo.nix | 0 misc/mimetypes.nix | 142 ++ misc/ssh/hosts/pvv.nix | 92 + overlays/lib/attrsets.nix | 49 + overlays/lib/default.nix | 10 + overlays/lib/lists.nix | 14 + overlays/lib/strings.nix | 40 + overlays/lib/termColors.nix | 49 + overlays/lib/trivial.nix | 7 + packages.nix | 118 ++ pluggables/collections/development.nix | 0 .../collections/extended-terminal-tools.nix | 0 pluggables/collections/games.nix | 0 pluggables/collections/japanese.nix | 0 pluggables/collections/multimedia.nix | 0 pluggables/collections/school.nix | 0 pluggables/server/torrent.nix | 26 + pluggables/tools/programming.nix | 34 + programs/alacritty.nix | 53 + programs/comma.nix | 16 + programs/emacs.nix | 25 + programs/gh.nix | 13 + programs/git.nix | 82 + programs/ncmpcpp.nix | 338 ++++ programs/neovim.nix | 105 ++ programs/newsboat.nix | 62 + programs/qutebrowser.nix | 12 + programs/rofi.nix | 35 + programs/tmux.nix | 106 ++ programs/vscode-extensions/noop-syslog.c | 1 + programs/vscode-extensions/vsliveshare.nix | 124 ++ programs/vscode.nix | 585 ++++++ programs/zathura.nix | 26 + programs/zsh/default.nix | 60 + programs/zsh/p10k.zsh | 1590 +++++++++++++++++ services/dunst.nix | 24 + services/mpd.nix | 10 + services/picom.nix | 37 + services/stalonetray.nix | 23 + services/sxhkd.nix | 79 + shellOptions.nix | 417 +++++ 71 files changed, 6231 insertions(+) create mode 100644 common/colors.nix create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 home.nix create mode 100644 hosts/eisei/configuration.nix create mode 100644 hosts/eisei/hardware-configuration.nix create mode 100644 hosts/tsuki/configuration.nix create mode 100644 hosts/tsuki/hardware-configuration.nix create mode 100644 hosts/tsuki/services/calibre.todo.nix create mode 100644 hosts/tsuki/services/cron-backups/mail.nix create mode 100644 hosts/tsuki/services/cron-backups/pixiv.nix create mode 100644 hosts/tsuki/services/cron-backups/reddit.nix create mode 100644 hosts/tsuki/services/cron-backups/youtube.nix create mode 100644 hosts/tsuki/services/dokuwiki.todo.nix create mode 100644 hosts/tsuki/services/gitea.nix create mode 100644 hosts/tsuki/services/gitlab/default.nix create mode 100755 hosts/tsuki/services/gitlab/genfiles.sh create mode 100644 hosts/tsuki/services/gitlab/runner.nix create mode 100644 hosts/tsuki/services/grafana.nix create mode 100644 hosts/tsuki/services/hydra.nix create mode 100644 hosts/tsuki/services/jitsi.nix create mode 100644 hosts/tsuki/services/libvirt.todo.nix create mode 100644 hosts/tsuki/services/matrix.nix create mode 100644 hosts/tsuki/services/minecraft.todo.nix create mode 100644 hosts/tsuki/services/nginx.nix create mode 100644 hosts/tsuki/services/openldap.todo.nix create mode 100644 hosts/tsuki/services/openvpn.nix create mode 100644 hosts/tsuki/services/plex.nix create mode 100644 hosts/tsuki/services/samba.todo.nix create mode 100644 hosts/tsuki/services/searx.nix create mode 100644 hosts/tsuki/services/syncthing.todo.nix create mode 100644 misc/mimetypes.nix create mode 100644 misc/ssh/hosts/pvv.nix create mode 100644 overlays/lib/attrsets.nix create mode 100644 overlays/lib/default.nix create mode 100644 overlays/lib/lists.nix create mode 100644 overlays/lib/strings.nix create mode 100644 overlays/lib/termColors.nix create mode 100644 overlays/lib/trivial.nix create mode 100644 packages.nix create mode 100644 pluggables/collections/development.nix create mode 100644 pluggables/collections/extended-terminal-tools.nix create mode 100644 pluggables/collections/games.nix create mode 100644 pluggables/collections/japanese.nix create mode 100644 pluggables/collections/multimedia.nix create mode 100644 pluggables/collections/school.nix create mode 100644 pluggables/server/torrent.nix create mode 100644 pluggables/tools/programming.nix create mode 100644 programs/alacritty.nix create mode 100644 programs/comma.nix create mode 100644 programs/emacs.nix create mode 100644 programs/gh.nix create mode 100644 programs/git.nix create mode 100644 programs/ncmpcpp.nix create mode 100644 programs/neovim.nix create mode 100644 programs/newsboat.nix create mode 100644 programs/qutebrowser.nix create mode 100644 programs/rofi.nix create mode 100644 programs/tmux.nix create mode 100644 programs/vscode-extensions/noop-syslog.c create mode 100644 programs/vscode-extensions/vsliveshare.nix create mode 100644 programs/vscode.nix create mode 100644 programs/zathura.nix create mode 100644 programs/zsh/default.nix create mode 100644 programs/zsh/p10k.zsh create mode 100644 services/dunst.nix create mode 100644 services/mpd.nix create mode 100644 services/picom.nix create mode 100644 services/stalonetray.nix create mode 100644 services/sxhkd.nix create mode 100644 shellOptions.nix diff --git a/common/colors.nix b/common/colors.nix new file mode 100644 index 0000000..11edaad --- /dev/null +++ b/common/colors.nix @@ -0,0 +1,30 @@ +rec { + monokai = { + foreground = monokai.white; + background = monokai.black; + black = "#272822"; + red = "#f92672"; + green = "#a6e22e"; + yellow = "#f4bf75"; + blue = "#66d9ef"; + magenta = "#ae81ff"; + cyan = "#a1efe4"; + white = "#f8f8f2"; + }; + + paper = { + background = "#f2e3bd"; + foreground = "#2f343f"; + black = "#222222"; + red = "#C30771"; + green = "#10A778"; + yellow = "#A89C14"; + blue = "#008ec4"; + magenta = "#523C79"; + cyan = "#20A5BA"; + white = "#f7f3ee"; + }; + + default = monokai; +} + diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..2f019e4 --- /dev/null +++ b/flake.lock @@ -0,0 +1,66 @@ +{ + "nodes": { + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1643933536, + "narHash": "sha256-yRmsWAG4DnLxLIUtlaZsl0kH7rN5xSoyNRlf0YZrcH4=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "2860d7e3bb350f18f7477858f3513f9798896831", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "release-21.11", + "repo": "home-manager", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1646406548, + "narHash": "sha256-xp+3f76ycZXNf9pG65Ef9KfDl1fas2UQu/cBe/pLd+c=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "47cd6702934434dd02bc53a67dbce3e5493e33a2", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-21.11", + "type": "indirect" + } + }, + "root": { + "inputs": { + "home-manager": "home-manager", + "nixpkgs": "nixpkgs", + "secrets": "secrets" + } + }, + "secrets": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1646662541, + "narHash": "sha256-v37mxxTONQqQY9NKMx5ngFCGaT0BfAaO2nT1KNXB1jM=", + "type": "git", + "url": "file:///home/h7x4/git/nix-secrets" + }, + "original": { + "type": "git", + "url": "file:///home/h7x4/git/nix-secrets" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..548d6d1 --- /dev/null +++ b/flake.nix @@ -0,0 +1,88 @@ +{ + description = "Mmmmmh, Spaghetti™"; + + inputs = { + nixpkgs.url = "nixpkgs/nixos-21.11"; + + home-manager = { + url = "github:nix-community/home-manager/release-21.11"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + # Nix expressions and keys (TODO: move keys to another solution like agenix) + # which should be kept from the main repo for privacy reasons. + # + # Includes stuff like usernames, emails, ports, other server users, ssh hosts, etc. + secrets = { + # TODO: Push this to a remote. + url = "git+file:///home/h7x4/git/nix-secrets"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { self, nixpkgs, home-manager, secrets, ... }: let + system = "x86_64-linux"; + + pkgs = import nixpkgs { + inherit system; + + config = { + allowUnfree = true; + android_sdk.accept_license = true; + }; + + overlays = [ (import ./overlays/lib) ]; + }; + + specialArgs = { + secrets = secrets.outputs.default; + colorTheme = import ./common/colors.nix; + }; + + in { + overlays = { + lib = import ./overlays/lib; + }; + + homeConfigurations = { + h7x4 = home-manager.lib.homeManagerConfiguration { + inherit system; + inherit pkgs; + + extraSpecialArgs = specialArgs; + username = "h7x4"; + homeDirectory = "/home/h7x4"; + stateVersion = "21.11"; + configuration = { + + imports = [ + ./home.nix + secrets.outputs.nixosModule + ]; + }; + }; + }; + + nixosConfigurations = let + # String -> AttrSet -> AttrSet + nixSys = + name: extraOpts: + nixpkgs.lib.nixosSystem { + inherit system; + inherit pkgs; + + lib = pkgs.lib; + inherit specialArgs; + + modules = [ + ./hosts/${name}/configuration.nix + ]; + } // extraOpts; + + in { + Tsuki = nixSys "tsuki" {}; + Eisei = nixSys "eisei" {}; + }; + + }; +} diff --git a/home.nix b/home.nix new file mode 100644 index 0000000..3e69943 --- /dev/null +++ b/home.nix @@ -0,0 +1,122 @@ +{ pkgs, ... } @ args: +{ + imports = [ + ./shellOptions.nix + ./packages.nix + + ./misc/mimetypes.nix + ./misc/ssh/hosts/pvv.nix + + ./programs/alacritty.nix + ./programs/comma.nix + ./programs/emacs.nix + ./programs/gh.nix + ./programs/git.nix + ./programs/ncmpcpp.nix + ./programs/neovim.nix + ./programs/newsboat.nix + ./programs/qutebrowser.nix + ./programs/rofi.nix + ./programs/tmux.nix + ./programs/vscode.nix + ./programs/zathura.nix + ./programs/zsh + + ./services/dunst.nix + ./services/mpd.nix + ./services/picom.nix + ./services/stalonetray.nix + ./services/sxhkd.nix + ]; + + home = { + stateVersion = "21.11"; + username = "h7x4"; + homeDirectory = "/home/h7x4"; + }; + + news.display = "silent"; + + fonts.fontconfig.enable = true; + + programs = { + home-manager.enable = true; + + bat.enable = true; + bottom.enable = true; + exa.enable = true; + feh.enable = true; + fzf = { + enable = true; + defaultCommand = "fd --type f"; + }; + gpg.enable = true; + irssi.enable = true; + kakoune.enable = true; + lazygit.enable = true; + man = { + enable = true; + generateCaches = true; + }; + mpv.enable = true; + obs-studio.enable = true; + ssh.enable = true; + skim = { + enable = true; + defaultCommand ="fd --type f"; + }; + texlive = { + enable = true; + # packageSet = pkgs.texlive.combined.scheme-medium; + }; + # xmobar.enable = true; + zoxide.enable = true; + }; + + services = { + gnome-keyring.enable = true; + dropbox.enable = true; + network-manager-applet.enable = true; + # redshift.enable = true; + }; + + manual = { + html.enable = true; + manpages.enable = true; + json.enable = true; + }; + + gtk = { + enable = true; + font = { + name = "Droid Sans"; + }; + iconTheme = { + package = pkgs.papirus-icon-theme; + name = "Papirus"; + }; + theme = { + package = pkgs.vimix-gtk-themes; + name = "VimixDark"; + }; + }; + + qt = { + enable = true; + platformTheme = "gtk"; + style = { + name = "adwaita-dark"; + package = pkgs.adwaita-qt; + }; + }; + + xdg.enable = true; + + xsession = { + pointerCursor = { + package = pkgs.capitaine-cursors; + name = "capitaine-cursors"; + size = 16; + }; + }; +} diff --git a/hosts/eisei/configuration.nix b/hosts/eisei/configuration.nix new file mode 100644 index 0000000..cb27532 --- /dev/null +++ b/hosts/eisei/configuration.nix @@ -0,0 +1,284 @@ +{ pkgs, config, ... }: let + # FIXME: lib should be imported directly as a module argument. + inherit (pkgs) lib; + +# TODO: Split this file +in { + imports = [ + ./hardware-configuration.nix + ../../pluggables/tools/programming.nix + ]; + + systemd.targets = { + sleep.enable = false; + suspend.enable = false; + hibernate.enable = false; + hybrid-sleep.enable = false; + }; + + boot.loader = { + efi.canTouchEfiVariables = false; + grub = { + enable = true; + device = "/dev/sda"; + version = 2; + }; + }; + + time.timeZone = "Europe/Oslo"; + + networking = { + hostName = "Eisei"; + networkmanager.enable = true; + useDHCP = false; + + interfaces = { + eno1.useDHCP = true; + wlo1.useDHCP = true; + }; + + # firewall = { + # enable = false; + # allowedTCPPorts = [ ... ]; + # allowedUDPPorts = [ ... ]; + # }; + }; + + i18n = { + defaultLocale = "en_US.UTF-8"; + + inputMethod = { + enabled = "fcitx"; + fcitx.engines = with pkgs.fcitx-engines; [ mozc ]; + }; + + # inputMethod = { + # enabled = "fcitx5"; + # fcitx5.addons = with pkgs; [ + # fcitx5-mozc + # fcitx5-gtk + # ]; + # }; + }; + + console = { + font = "Lat2-Terminus16"; + keyMap = "us"; + }; + + services = { + openssh.enable = true; + gnome.gnome-keyring.enable = true; + printing.enable = true; + dbus = { + enable = true; + packages = with pkgs; [ + gcr + gnome3.dconf + ]; + }; + cron = { + enable = true; + systemCronJobs = [ + # "*/5 * * * * root date >> /tmp/cron.log" + ]; + }; + + xserver = { + enable = true; + layout = "us"; + xkbOptions = "caps:escape"; + + libinput = { + enable = true; + touchpad.disableWhileTyping = true; + }; + + windowManager.xmonad = { + enable = true; + enableContribAndExtras = true; + }; + }; + }; + + sound.enable = true; + hardware.pulseaudio.enable = true; + + hardware.bluetooth.enable = true; + + nixpkgs.config = { + allowUnfree = true; + }; + + nix = { + distributedBuilds = true; + package = pkgs.nixFlakes; + binaryCaches = [ + "https://cache.nixos.org/" + ]; + extraOptions = '' + experimental-features = nix-command flakes + builders-use-substitutes = true + ''; + + buildMachines = [ + { + hostName = "Tsuki"; + system = "x86_64-linux"; + maxJobs = 1; + speedFactor = 3; + supportedFeatures = [ + "nixos-test" + "benchmark" + "big-paralell" + "kvm" + ]; + mandatoryFeatures = []; + } + ]; + + }; + + users.users.h7x4 = { + isNormalUser = true; + extraGroups = [ + "wheel" + "networkmanager" + "docker" + "disk" + "audio" + "video" + "libvirtd" + "input" + ]; + shell = pkgs.zsh; + }; + + environment = { + variables = { + EDITOR = "nvim"; + VISUAL = "nvim"; + }; + + systemPackages = with pkgs; [ + wget + haskellPackages.xmobar + ]; + + shells = with pkgs; [ + bashInteractive + zsh + dash + ]; + + etc = { + # TODO: move this out of etc, and reference it directly in sudo config. + sudoLecture = { + target = "sudo.lecture"; + text = lib.termColors.front.red "Be careful or something, idk...\n"; + }; + + currentSystemPackages = { + target = "current-system-packages"; + text = let + inherit (lib.strings) concatStringsSep; + inherit (lib.lists) sort; + inherit (lib.trivial) lessThan; + packages = map (p: "${p.name}") config.environment.systemPackages; + sortedUnique = sort lessThan (lib.unique packages); + in concatStringsSep "\n" sortedUnique; + }; + }; + }; + + fonts = { + enableDefaultFonts = true; + + fonts = with pkgs; [ + cm_unicode + dejavu_fonts + fira-code + fira-code-symbols + powerline-fonts + iosevka + symbola + corefonts + ipaexfont + ipafont + liberation_ttf + migmix + noto-fonts + noto-fonts-cjk + noto-fonts-emoji + open-sans + source-han-sans + source-sans + ubuntu_font_family + victor-mono + (nerdfonts.override { fonts = [ "FiraCode" "DroidSansMono" ]; }) + ]; + + fontconfig = { + defaultFonts = { + serif = [ "Droid Sans Serif" "Ubuntu" ]; + sansSerif = [ "Droid Sans" "Ubuntu" ]; + monospace = [ "Fira Code" "Ubuntu" ]; + emoji = [ "Noto Sans Emoji" ]; + }; + }; + }; + + programs = { + dconf.enable = true; + git.enable = true; + light.enable = true; + npm.enable = true; + tmux.enable = true; + neovim = { + enable = true; + defaultEditor = true; + viAlias = true; + vimAlias = true; + configure = { + packages.myVimPackage = with pkgs.vimPlugins; { + start = [ + direnv-vim + vim-nix + vim-polyglot + ]; + + opt = [ + vim-monokai + ]; + }; + + customRC = '' + set number relativenumber + set undofile + set undodir=~/.cache/vim/undodir + + packadd! vim-monokai + colorscheme monokai + ''; + }; + }; + + gnupg.agent = { + enable = true; + enableSSHSupport = true; + }; + }; + + security.sudo.extraConfig = '' + Defaults lecture = always + Defaults lecture_file = /etc/${config.environment.etc.sudoLecture.target} + ''; + + virtualisation = { + docker.enable = true; + libvirtd.enable = true; + }; + + system.stateVersion = "21.11"; +} + diff --git a/hosts/eisei/hardware-configuration.nix b/hosts/eisei/hardware-configuration.nix new file mode 100644 index 0000000..59f27d0 --- /dev/null +++ b/hosts/eisei/hardware-configuration.nix @@ -0,0 +1,37 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usb_storage" "sd_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/59d56b94-29f0-45be-81cc-16050c712902"; + fsType = "ext4"; + }; + + fileSystems."/home" = + { device = "/dev/disk/by-uuid/e66ad6d8-28d5-4411-8289-5ec47d60858b"; + fsType = "ext4"; + }; + + fileSystems."/home/h7x4/Dropbox" = + { device = "/dev/disk/by-uuid/b6b244ab-fdb2-4d90-8a38-b21b0932027b"; + fsType = "ext4"; + }; + + swapDevices = + [ { device = "/dev/disk/by-uuid/62738962-4764-4136-bdd3-348de09400d0"; } + ]; + + powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/tsuki/configuration.nix b/hosts/tsuki/configuration.nix new file mode 100644 index 0000000..d831c44 --- /dev/null +++ b/hosts/tsuki/configuration.nix @@ -0,0 +1,237 @@ +{ config, lib, pkgs, ... }: +{ + imports = + [ + ./hardware-configuration.nix + + ../../pluggables/tools/programming.nix + + ./services/nginx.nix + # ./services/dokuwiki.nix + # ./services/gitlab + ./services/gitea.nix + ./services/jitsi.nix + # ./services/openldap.nix + ./services/plex.nix + ./services/hydra.nix + ./services/matrix.nix + # ./services/libvirt.nix + ./services/grafana.nix + # ./services/calibre.nix + ./services/openvpn.nix + # ./services/samba.nix + ./services/searx.nix + # ./services/syncthing.nix + ]; + + systemd.targets = { + sleep.enable = false; + suspend.enable = false; + hibernate.enable = false; + hybrid-sleep.enable = false; + }; + + nix.package = pkgs.nixFlakes; + nix.extraOptions = '' + experimental-features = nix-command flakes + ''; + + # security.pam.services.login.unixAuth = true; + + boot.loader = { + grub = { + enable = true; + version = 2; + efiSupport = true; + fsIdentifier = "label"; + device = "nodev"; + efiInstallAsRemovable = true; + }; + # efi.efiSysMountPoint = "/boot/efi"; + # efi.canTouchEfiVariables = true; + }; + + time.timeZone = "Europe/Oslo"; + + networking = { + hostName = "Tsuki"; + networkmanager.enable = true; + useDHCP = false; + interfaces.ens18.useDHCP = true; + nameservers = [ + "1.1.1.1" + "8.8.8.8" + ]; + firewall.enable=true; + }; + + i18n.defaultLocale = "en_US.UTF-8"; + console = { + font = "Lat2-Terminus16"; + keyMap = "us"; + }; + + services = { + openssh = { + enable = true; + passwordAuthentication = false; + challengeResponseAuthentication = false; + permitRootLogin = "no"; + }; + printing.enable = true; + cron = { + enable = true; + systemCronJobs = [ + # "*/5 * * * * root date >> /tmp/cron.log" + ]; + }; + }; + + users.groups.media = {}; + + users.users = { + h7x4 = { + isNormalUser = true; + extraGroups = [ + "wheel" + "networkmanager" + "docker" + "disk" + "libvirtd" + "input" + ]; + shell = pkgs.zsh; + }; + media = { + isSystemUser = true; + group = "media"; + }; + }; + + environment = { + variables = { + EDITOR = "nvim"; + VISUAL = "nvim"; + }; + + systemPackages = with pkgs; [ + wget + ]; + + shells = with pkgs; [ + bashInteractive + zsh + dash + ]; + + etc = { + sudoLecture = { + target = "sudo.lecture"; + text = "Be careful or something, idk...\n"; + }; + + "resolv.conf" = with lib; with pkgs; { + source = writeText "resolv.conf" '' + ${concatStringsSep "\n" (map (ns: "nameserver ${ns}") config.networking.nameservers)} + options edns0 + ''; + }; + + currentSystemPackages = { + target = "current-system-packages"; + text = let + inherit (lib.strings) concatStringsSep; + inherit (lib.lists) sort; + inherit (lib.trivial) lessThan; + packages = map (p: "${p.name}") config.environment.systemPackages; + sortedUnique = sort lessThan (lib.unique packages); + in concatStringsSep "\n" sortedUnique; + }; + }; + }; + + fonts = { + enableDefaultFonts = true; + + fonts = with pkgs; [ + cm_unicode + dejavu_fonts + fira-code + fira-code-symbols + powerline-fonts + iosevka + symbola + corefonts + ipaexfont + ipafont + liberation_ttf + migmix + noto-fonts + noto-fonts-cjk + noto-fonts-emoji + open-sans + source-han-sans + source-sans + ubuntu_font_family + victor-mono + (nerdfonts.override { fonts = [ "FiraCode" "DroidSansMono" ]; }) + ]; + + fontconfig = { + defaultFonts = { + serif = [ "Droid Sans Serif" "Ubuntu" ]; + sansSerif = [ "Droid Sans" "Ubuntu" ]; + monospace = [ "Fira Code" "Ubuntu" ]; + emoji = [ "Noto Sans Emoji" ]; + }; + }; + }; + + programs = { + git.enable = true; + npm.enable = true; + tmux.enable = true; + neovim = { + enable = true; + defaultEditor = true; + viAlias = true; + vimAlias = true; + configure = { + packages.myVimPackage = with pkgs.vimPlugins; { + start = [ + direnv-vim + vim-nix + vim-polyglot + ]; + + opt = [ + vim-monokai + ]; + }; + + customRC = '' + set number relativenumber + set undofile + set undodir=~/.cache/vim/undodir + + packadd! vim-monokai + colorscheme monokai + ''; + }; + }; + }; + + security.sudo.extraConfig = '' + Defaults lecture = always + Defaults lecture_file = /etc/${config.environment.etc.sudoLecture.target} + ''; + + virtualisation = { + docker.enable = true; + libvirtd.enable = true; + }; + + system.stateVersion = "21.11"; +} + + diff --git a/hosts/tsuki/hardware-configuration.nix b/hosts/tsuki/hardware-configuration.nix new file mode 100644 index 0000000..5cc02f9 --- /dev/null +++ b/hosts/tsuki/hardware-configuration.nix @@ -0,0 +1,36 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/profiles/qemu-guest.nix") + ]; + + boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/54b9fd58-0df5-410c-ab87-766860967653"; + fsType = "btrfs"; + }; + + fileSystems."/boot" = + { device = "/dev/disk/by-uuid/0A60-2885"; + fsType = "vfat"; + }; + + fileSystems."/data" = + { device = "/dev/disk/by-uuid/87354b26-4f7f-4b94-96fd-4bbeb834a03b"; + fsType = "btrfs"; + }; + + swapDevices = + [ { device = "/dev/disk/by-uuid/92a1a33f-89a8-45de-a45e-6c303172cd7f"; } + ]; + + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/tsuki/services/calibre.todo.nix b/hosts/tsuki/services/calibre.todo.nix new file mode 100644 index 0000000..94f05fd --- /dev/null +++ b/hosts/tsuki/services/calibre.todo.nix @@ -0,0 +1,12 @@ +{ ... }: +{ + services.calibre-server = { + # user = "" + # group = "" + enable = true; + # libraries = [ + # /etc/abc + # ]; + # libraryDir = ???? + }; +} diff --git a/hosts/tsuki/services/cron-backups/mail.nix b/hosts/tsuki/services/cron-backups/mail.nix new file mode 100644 index 0000000..e69de29 diff --git a/hosts/tsuki/services/cron-backups/pixiv.nix b/hosts/tsuki/services/cron-backups/pixiv.nix new file mode 100644 index 0000000..e69de29 diff --git a/hosts/tsuki/services/cron-backups/reddit.nix b/hosts/tsuki/services/cron-backups/reddit.nix new file mode 100644 index 0000000..e69de29 diff --git a/hosts/tsuki/services/cron-backups/youtube.nix b/hosts/tsuki/services/cron-backups/youtube.nix new file mode 100644 index 0000000..e69de29 diff --git a/hosts/tsuki/services/dokuwiki.todo.nix b/hosts/tsuki/services/dokuwiki.todo.nix new file mode 100644 index 0000000..ae656f0 --- /dev/null +++ b/hosts/tsuki/services/dokuwiki.todo.nix @@ -0,0 +1,9 @@ +{ ... }: +{ + services.dokuwiki.sites = { + # TODO: research? + wiki = { + enable = false; + }; + }; +} diff --git a/hosts/tsuki/services/gitea.nix b/hosts/tsuki/services/gitea.nix new file mode 100644 index 0000000..eb24d40 --- /dev/null +++ b/hosts/tsuki/services/gitea.nix @@ -0,0 +1,62 @@ +{config, pkgs, lib, secrets, ...}: +{ + security.pam.services."gitea".unixAuth = true; + + users.users.git = { + description = "Gitea service"; + home = config.services.gitea.stateDir; + useDefaultShell = true; + group = "gitea"; + isSystemUser = true; + uid = config.ids.uids.git; + }; + + services.gitea = { + enable = true; + user = "git"; + appName = "Git Gud"; + cookieSecure = true; + rootUrl = "https://git.nani.wtf/"; + domain = "git.nani.wtf"; + # # TODO: move to secrets + httpPort = secrets.ports.gitea; + disableRegistration = true; + + database = { + user = "git"; + }; + + settings = { + server = { + BUILTIN_SSH_SERVER_USER="git"; + }; + + ui.DEFAULT_THEME = "arc-green"; + indexer.REPO_INDEXER_ENABLED = true; + mailer = { + ENABLED = true; + FROM = "gitea@nani.wtf"; + }; + + # markup = let + # docutils = pkgs.python37.withPackages (ps: with ps; [ + # docutils # Provides rendering of ReStructured Text files + # pygments # Provides syntax highlighting + # ]); + # in { + # restructuredtext = { + # ENABLED = true; + # FILE_EXTENSIONS = ".rst"; + # RENDER_COMMAND = "${docutils}/bin/rst2html.py"; + # IS_INPUT_FILE = false; + # }; + # asciidoc = { + # ENABLED = true; + # FILE_EXTENSIONS = ".adoc,.asciidoc"; + # RENDER_COMMAND = "${pkgs.asciidoctor}/bin/asciidoctor -e -a leveloffset=-1 --out-file=- -"; + # IS_INPUT_FILE = false; + # }; + # }; + }; + }; +} diff --git a/hosts/tsuki/services/gitlab/default.nix b/hosts/tsuki/services/gitlab/default.nix new file mode 100644 index 0000000..56b7c25 --- /dev/null +++ b/hosts/tsuki/services/gitlab/default.nix @@ -0,0 +1,94 @@ +{ pkgs, lib, config, secrets, ... }: +let + gitlab-port = secrets.ports.gitlab; + gitlab-host = "gitlab.nani.wtf"; + + # TODO: this should optimally be extracted out to nix-secrets completely. + gitlab-keydir = secrets.hosts.${config.networking.hostName}.keydir + "/gitlab"; +in +{ + # TODO: Set up gitlab-runner + # imports = [ ./runner.nix ]; + + services.gitlab = { + enable = false; + + host = gitlab-host; + port = gitlab-port + 1; + + user = "gitlab"; + group = "gitlab"; + + databaseUsername = "gitlab"; + + statePath = "${secrets.hosts.${config.networking.hostName}.dataStatePath}/gitlab"; + + # A file containing the initial password of the root gitlab-account. + # This file should be readable to the user defined in `services.gitlab.user`, + # optimally having only read write permissions for that user. + initialRootPasswordFile = secrets.keys.gitlab.root_password; + + secrets = { inherit (secrets.keys.gitlab) secretFile dbFile otpFile jwsFile; }; + + + # TODO: Activate GitLabs Prometheus service + # extraGitlabRb = '' + # prometheus['enabled'] = true + # prometheus['server_address'] = '0.0.0.0:10392' + # ''; + + smtp = { + tls = true; + # address = gitlab-host; + port = gitlab-port + 2; + }; + + # TODO: Set up registry + # registry = { + # enable = true; + # # host = gitlab-host; + # port = gitlab-port + 3; + # externalPort = gitlab-port + 3; + # certFile = /var/cert.pem; + # keyFile = /var/key.pem; + # }; + + pagesExtraArgs = [ + "-gitlab-server" "http://${gitlab-host}" + "-listen-proxy" "127.0.0.1:${toString (gitlab-port + 4)}" + "-log-format" "text" + ]; + + # https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/misc/gitlab.nix + # https://gitlab.com/gitlab-org/gitlab/blob/master/config/gitlab.yml.example + extraConfig = { + # gitlab = {}; + gravatar.enabled = false; + + # TODO: Fix pages API connection + # pages = { + # enabled = true; + # host = gitlab-host; + # secret_file = "${toString gitlab-keydir}/pages_secret"; + # local_store.enabled = true; + # }; + }; + + }; + + # TODO: Set up registry + # services.dockerRegistry = { + # enable = true; + # }; + + # TODO: Connect plantuml to gitlab + services.plantuml-server = { + enable = true; + listenPort = gitlab-port + 5; + }; + + # TODO: Make module for kroki, and connect to gitlab + # services.kroki = { + # + # }; +} diff --git a/hosts/tsuki/services/gitlab/genfiles.sh b/hosts/tsuki/services/gitlab/genfiles.sh new file mode 100755 index 0000000..6d470f9 --- /dev/null +++ b/hosts/tsuki/services/gitlab/genfiles.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +if [ "$EUID" -ne 0 ]; then + echo "Please run as root" + exit 1 +fi + +KEYDIR='/var/keys/gitlab' + +umask u=rwx,g=,o= + +mkdir -p $KEYDIR +chmod 755 '/var/keys' + +for FILE in secretFile dbFile otpFile pages_secret; do + tr -dc A-Za-z0-9 < /dev/random | head -c 128 > $KEYDIR/$FILE +done + +nix-shell -p openssl --run "openssl genrsa 2048 > $KEYDIR/jwsFile" +chmod 600 $KEYDIR/jwsFile + +read -s -p "Root password: " ROOTPASS +echo $ROOTPASS > $KEYDIR/root_password + +chown -R git:git $KEYDIR diff --git a/hosts/tsuki/services/gitlab/runner.nix b/hosts/tsuki/services/gitlab/runner.nix new file mode 100644 index 0000000..9d15b42 --- /dev/null +++ b/hosts/tsuki/services/gitlab/runner.nix @@ -0,0 +1,51 @@ +{ ... }: +{ + + # See https://nixos.wiki/wiki/Gitlab_runner + # boot.kernel.sysctl."net.ipv4.ip_forward" = true; # 1 + # virtualisation.docker.enable = true; + # services.gitlab-runner = { + # enable = true; + # services= { + # # runner for building in docker via host's nix-daemon + # # nix store will be readable in runner, might be insecure + # nix = with lib;{ + # # File should contain at least these two variables: + # # `CI_SERVER_URL` + # # `REGISTRATION_TOKEN` + # registrationConfigFile = toString ./path/to/ci-env; # 2 + # dockerImage = "alpine"; + # dockerVolumes = [ + # "/nix/store:/nix/store:ro" + # "/nix/var/nix/db:/nix/var/nix/db:ro" + # "/nix/var/nix/daemon-socket:/nix/var/nix/daemon-socket:ro" + # ]; + # dockerDisableCache = true; + # preBuildScript = pkgs.writeScript "setup-container" '' + # mkdir -p -m 0755 /nix/var/log/nix/drvs + # mkdir -p -m 0755 /nix/var/nix/gcroots + # mkdir -p -m 0755 /nix/var/nix/profiles + # mkdir -p -m 0755 /nix/var/nix/temproots + # mkdir -p -m 0755 /nix/var/nix/userpool + # mkdir -p -m 1777 /nix/var/nix/gcroots/per-user + # mkdir -p -m 1777 /nix/var/nix/profiles/per-user + # mkdir -p -m 0755 /nix/var/nix/profiles/per-user/root + # mkdir -p -m 0700 "$HOME/.nix-defexpr" + # . ${pkgs.nix}/etc/profile.d/nix.sh + # ${pkgs.nix}/bin/nix-channel --add https://nixos.org/channels/nixos-20.09 nixpkgs # 3 + # ${pkgs.nix}/bin/nix-channel --update nixpkgs + # ${pkgs.nix}/bin/nix-env -i ${concatStringsSep " " (with pkgs; [ nix cacert git openssh ])} + # ''; + # environmentVariables = { + # ENV = "/etc/profile"; + # USER = "root"; + # NIX_REMOTE = "daemon"; + # PATH = "/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/bin:/sbin:/usr/bin:/usr/sbin"; + # NIX_SSL_CERT_FILE = "/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"; + # }; + # tagList = [ "nix" ]; + # }; + # }; + # }; + +} diff --git a/hosts/tsuki/services/grafana.nix b/hosts/tsuki/services/grafana.nix new file mode 100644 index 0000000..5389925 --- /dev/null +++ b/hosts/tsuki/services/grafana.nix @@ -0,0 +1,76 @@ +{ config, lib, secrets, ... }: +{ + services.grafana = { + enable = true; + domain = "log.nani.wtf"; + port = secrets.ports.grafana; + addr = "0.0.0.0"; + }; + + # services.influxdb = { + # enable = true; + # dataDir = "/data/var/influxdb"; + # extraConfig = { + # udp = { + # enabled = true; + # bind-address = "0.0.0.0:8089"; + # database = "proxmox"; + # batch-size = 1000; + # batch-timeout = "1s"; + # }; + # }; + # }; + + services.prometheus = { + enable = true; + port = secrets.ports.prometheus; + + scrapeConfigs = [ + { + job_name = "synapse"; + scrape_interval = "15s"; + metrics_path = "/_synapse/metrics"; + static_configs = [ + { + targets = [ "localhost:${toString secrets.ports.matrix.listener}" ]; + } + ]; + } + { + job_name = "minecraft"; + # scrape_interval = "15s"; + # metrics_path = "/_synapse/metrics"; + static_configs = [ + { + targets = [ "${secrets.ips.crafty}:${toString secrets.ports.prometheus-crafty}" ]; + labels = { + server_name = "my-minecraft-server"; + }; + } + ]; + } + ]; + + exporters = { + jitsi.enable = true; + nginx.enable = true; + nginxlog.enable = true; + systemd.enable = true; + # postgres.enable = true; + }; + + # globalConfig = { + + # }; + + }; + + # services.loki = { + # enable = true; + # configFile = ./loki-local-config.yaml; + # config = { + + # }; + # }; + +} diff --git a/hosts/tsuki/services/hydra.nix b/hosts/tsuki/services/hydra.nix new file mode 100644 index 0000000..37c6b8a --- /dev/null +++ b/hosts/tsuki/services/hydra.nix @@ -0,0 +1,9 @@ +{ secrets, ... }: +{ + services.hydra = { + enable = true; + hydraURL = "http://hydra.nani.wtf"; + notificationSender = "hydra@nani.wtf"; + port = secrets.ports.hydra; + }; +} diff --git a/hosts/tsuki/services/jitsi.nix b/hosts/tsuki/services/jitsi.nix new file mode 100644 index 0000000..d33e787 --- /dev/null +++ b/hosts/tsuki/services/jitsi.nix @@ -0,0 +1,16 @@ +{ ... }: +{ + services.jitsi-meet = { + enable = true; + hostName = "jitsi.nani.wtf"; + config = { + enableWelcomePage = false; + prejoinPageEnabled = true; + defaultLang = "en"; + }; + interfaceConfig = { + SHOW_JITSI_WATERMARK = false; + SHOW_WATERMARK_FOR_GUESTS = false; + }; + }; +} diff --git a/hosts/tsuki/services/libvirt.todo.nix b/hosts/tsuki/services/libvirt.todo.nix new file mode 100644 index 0000000..e69de29 diff --git a/hosts/tsuki/services/matrix.nix b/hosts/tsuki/services/matrix.nix new file mode 100644 index 0000000..f3be0d2 --- /dev/null +++ b/hosts/tsuki/services/matrix.nix @@ -0,0 +1,134 @@ +{config, pkgs, lib, secrets, ...}: { + + # configure synapse to point users to coturn + services.matrix-synapse = { + enable = true; + turn_uris = let + inherit (config.services.coturn) realm; + p = toString secrets.ports.matrix.default; + in ["turn:${realm}:${p}?transport=udp" "turn:${realm}:${p}?transport=tcp"]; + turn_shared_secret = config.services.coturn.static-auth-secret; + turn_user_lifetime = "1h"; + + server_name = "nani.wtf"; + public_baseurl = "https://matrix.nani.wtf"; + + enable_metrics = true; + + listeners = [ + { + port = secrets.ports.matrix.listener; + bind_address = "::1"; + type = "http"; + tls = false; + x_forwarded = true; + resources = [ + { + names = [ "client" "federation" "metrics" ]; + compress = false; + } + ]; + } + ]; + + enable_registration = false; + + # password_config.enabled = lib.mkForce false; + + dataDir = "/data/var/matrix"; + + database_type = "psycopg2"; + database_args = { + password = "synapse"; + }; + + # redis.enabled = true; + + # settings = { + + + + # }; + }; + + services.redis.enable = true; + + # enable coturn + services.coturn = rec { + enable = true; + no-cli = true; + no-tcp-relay = true; + min-port = secrets.ports.matrix.min; + max-port = secrets.ports.matrix.max; + use-auth-secret = true; + static-auth-secret = secrets.keys.matrix.static-auth-secret; + realm = "turn.nani.wtf"; + cert = "${secrets.keys.certificates.server.crt}"; + pkey = "${secrets.keys.certificates.server.key}"; + extraConfig = '' + # for debugging + verbose + # ban private IP ranges + no-multicast-peers + denied-peer-ip=0.0.0.0-0.255.255.255 + denied-peer-ip=10.0.0.0-10.255.255.255 + denied-peer-ip=100.64.0.0-100.127.255.255 + denied-peer-ip=127.0.0.0-127.255.255.255 + denied-peer-ip=169.254.0.0-169.254.255.255 + denied-peer-ip=172.16.0.0-172.31.255.255 + denied-peer-ip=192.0.0.0-192.0.0.255 + denied-peer-ip=192.0.2.0-192.0.2.255 + denied-peer-ip=192.88.99.0-192.88.99.255 + denied-peer-ip=192.168.0.0-192.168.255.255 + denied-peer-ip=198.18.0.0-198.19.255.255 + denied-peer-ip=198.51.100.0-198.51.100.255 + denied-peer-ip=203.0.113.0-203.0.113.255 + denied-peer-ip=240.0.0.0-255.255.255.255 + denied-peer-ip=::1 + denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff + denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255 + denied-peer-ip=100::-100::ffff:ffff:ffff:ffff + denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff + denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff + denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff + denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff + ''; + }; + + services.postgresql = { + enable = true; + + ## postgresql user and db name remains in the + ## service.matrix-synapse.database_args setting which + ## by default is matrix-synapse + initialScript = pkgs.writeText "synapse-init.sql" '' + CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse'; + CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse" + TEMPLATE template0 + LC_COLLATE = "C" + LC_CTYPE = "C"; + ''; + }; + + # open the firewall + networking.firewall = { + interfaces.enp2s0 = let + range = with config.services.coturn; [ { + from = secrets.ports.matrix.min; + to = secrets.ports.matrix.max; + } ]; + in + { + allowedUDPPortRanges = range; + allowedUDPPorts = [ secrets.ports.matrix.default ]; + allowedTCPPortRanges = range; + allowedTCPPorts = [ secrets.ports.matrix.default ]; + }; + }; + # get a certificate + # security.acme.certs.${config.services.coturn.realm} = { + # /* insert here the right configuration to obtain a certificate */ + # postRun = "systemctl restart coturn.service"; + # group = "turnserver"; + # }; +} diff --git a/hosts/tsuki/services/minecraft.todo.nix b/hosts/tsuki/services/minecraft.todo.nix new file mode 100644 index 0000000..7514ab3 --- /dev/null +++ b/hosts/tsuki/services/minecraft.todo.nix @@ -0,0 +1,64 @@ +{ pkgs, lib, ... }: + +# See https://github.com/InfinityGhost/nixos-workstation/blob/master/minecraft-server.nix + +let + allocatedMemory = "4096M"; +in { + services.minecraft-server = let + version = "1.18.1"; + + spigot = pkgs.minecraft-server.overrideAttrs (old: { + src = pkgs.fetchurl { + url = "https://hub.spigotmc.org/jenkins/job/BuildTools/141/artifact/target/BuildTools.jar"; + sha1 = "?"; + }; + + buildPhase = '' + cat > minecraft-server << EOF + + #!${pkgs.bash}/bin/sh + exec ${pkgs.adoptopenjdk-jre-hotspot-bin-17}/bin/java \$@ -jar $out/bin/spigot-${version}.jar nogui + + java -jar $src --rev ${version} + ''; + + installPhase = '' + mkdir -p $out/bin $out/lib/minecraft + cp -v spigot-${version}.jar $out/lib/minecraft + cp -v minecraft-server $out/bin + + chmod +x $out/bin/minecraft-server + ''; + }); + in { + enable = true; + eula = true; + package = pkgs.spigot; + declarative = true; + dataDir = "/home/h7x4/minecraft"; + openFirewall = true; + + jvmOpts = lib.concatStringsSep " " [ + "-Xmx${allocatedMemory}" + "-Xms${allocatedMemory}" + "-XX:+UseG1GC" + "-XX:ParallelGCThreads=2" + "-XX:MinHeapFreeRatio=5" + "-XX:MaxHeapFreeRatio=10" + ]; + + serverProperties = { + motd = "NixOS Minecraft Server"; + server-port = 25565; + difficulty = 2; + gamemode = 0; + max-players = 5; + white-list = false; + enable-rcon = false; + allow-flight = true; + }; + + # whitelist = {}; + }; +} diff --git a/hosts/tsuki/services/nginx.nix b/hosts/tsuki/services/nginx.nix new file mode 100644 index 0000000..042778d --- /dev/null +++ b/hosts/tsuki/services/nginx.nix @@ -0,0 +1,143 @@ +{ pkgs, config, secrets, ... }: + let + # TODO: fix lib + lib = pkgs.lib; + + inherit (secrets) ips ports; + + s = toString; + in +{ + + security.acme = { + email = "h7x4abk3g@protonmail.com"; + acceptTerms = true; + }; + + services.nginx = let + generateServerAliases = + domains: subdomains: + lib.lists.flatten (map (s: map (d: "${s}.${d}") domains) subdomains); + in { + enable = true; + + statusPage = true; + + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + + virtualHosts = let + inherit (lib.attrsets) nameValuePair listToAttrs recursiveUpdate; + inherit (lib.lists) head drop; + inherit (secrets) domains keys; + + makeHost = + subdomains: extraSettings: + nameValuePair "${head subdomains}.${head domains}" (recursiveUpdate { + serverAliases = drop 1 (generateServerAliases domains subdomains); + forceSSL = true; + sslCertificate = keys.certificates.server.crt; + sslCertificateKey = keys.certificates.server.key; + } extraSettings); + + makeACMEHost = + subdomains: extraSettings: + nameValuePair "${head subdomains}.${head domains}" (recursiveUpdate { + serverAliases = drop 1 (generateServerAliases domains subdomains); + enableACME = true; + forceSSL = true; + } extraSettings); + + makeClientCertHost = + subdomains: extraSettings: + nameValuePair "${head subdomains}.${head domains}" (recursiveUpdate { + serverAliases = drop 1 (generateServerAliases domains subdomains); + enableACME = true; + forceSSL = true; + extraConfig = '' + ssl_client_certificate ${secrets.keys.certificates.CA.crt}; + ssl_verify_client optional; + ''; + locations."/".extraConfig = '' + if ($ssl_client_verify != SUCCESS) { + return 403; + } + ''; + } extraSettings); + + makeProxy = + subdomains: url: extraSettings: + makeHost subdomains (recursiveUpdate { locations."/".proxyPass = url; } extraSettings); + + makeACMEProxy = + subdomains: url: extraSettings: + makeACMEHost subdomains (recursiveUpdate { locations."/".proxyPass = url; } extraSettings); + + makeClientCertProxy = + subdomains: url: extraSettings: + makeClientCertHost subdomains (recursiveUpdate { locations."/".proxyPass = url; } extraSettings); + + in (listToAttrs [ + # (makeACMEProxy ["gitlab"] "http://unix:/run/gitlab/gitlab-workhorse.socket" {}) + (makeACMEProxy ["plex"] "http://localhost:${s ports.plex}" {}) + (makeACMEHost ["www"] { root = "/data/www"; }) + (makeACMEProxy ["matrix"] "http://localhost:${s ports.matrix.listener}" {}) + (makeACMEProxy ["git"] "http://localhost:${s ports.gitea}" {}) + (makeClientCertHost ["cache"] { root = "/var/lib/nix-cache"; }) + (makeClientCertProxy ["px1"] "https://${ips.px1}:${s ports.proxmox}" { + locations."/".proxyWebsockets = true; + }) + (makeClientCertProxy ["idrac"] "https://${ips.idrac}" {}) + (makeClientCertProxy ["searx"] "http://localhost:${s ports.searx}" {}) + (makeACMEProxy ["dyn"] "http://${ips.crafty}:${s ports.dynmap}" { + basicAuthFile = keys.htpasswds.default; + }) + (makeClientCertProxy ["log"] "http://localhost:${s ports.grafana}" { + locations."/".proxyWebsockets = true; + }) + # (makeProxy ["wiki"] "" {}) + # (makeHost ["vpn"] "" {}) + (makeClientCertProxy ["hydra"] "http://localhost:${s ports.hydra}" {}) + + # (makePassProxy ["sync" "drive"] "" {}) + # (makePassProxy ["music" "mpd"] "" {}) + ]) // { + ${config.services.jitsi-meet.hostName} = { + enableACME = true; + forceSSL = true; + }; + }; + + upstreams = {}; + + streamConfig = '' + upstream minecraft { + server ${ips.crafty}:${s ports.minecraft}; + } + + server { + listen 0.0.0.0:${s ports.minecraft}; + listen [::0]:${s ports.minecraft}; + proxy_pass minecraft; + } + ''; + # upstream openvpn { + # server localhost:${s ports.openvpn}; + # } + + # server { + # listen 0.0.0.0:${s ports.openvpn}; + # listen [::0]:${s ports.openvpn}; + # proxy_pass openvpn; + # } + }; + + networking.firewall.allowedTCPPorts = [ + 80 + 443 + # secrets.ports.openvpn + ports.minecraft + ]; +} diff --git a/hosts/tsuki/services/openldap.todo.nix b/hosts/tsuki/services/openldap.todo.nix new file mode 100644 index 0000000..ca6b591 --- /dev/null +++ b/hosts/tsuki/services/openldap.todo.nix @@ -0,0 +1,74 @@ +{ pkgs, ... }: +{ + services.openldap = { + enable = true; + # dataDir = "/data/var/openldap"; + urlList = [ "ldap:///" "ldapi:///" ]; # Add ldaps to this list to listen with SSL (requires configured certificates) + # suffix = "dc=nixos,dc=org"; + # rootdn = "cn=admin,dc=nixos,dc=org"; + # rootpwFile = "/var/keys/ldap/rootpw"; + # See https://www.openldap.org/doc/admin24/slapdconfig.html + # extraDatabaseConfig = '' + # access to dn.base="dc=nixos,dc=org" by * read + # # Add your own ACLs here… + + # # Drop everything that wasn't handled by previous ACLs: + # access to * by * none + + # index objectClass eq + # index uid eq + # index mail sub + # # Accelerates replication if you use it + # index entryCSN eq + # index entryUUID eq + # ''; + + settings = { + attrs.olcLogLevel = [ "stats" ]; + children = { + "cn=schema".includes = [ + "${pkgs.openldap}/etc/schema/core.ldif" + "${pkgs.openldap}/etc/schema/cosine.ldif" + "${pkgs.openldap}/etc/schema/inetorgperson.ldif" + ]; + "olcDatabase={-1}frontend" = { + attrs = { + objectClass = "olcDatabaseConfig"; + olcDatabase = "{-1}frontend"; + olcAccess = [ "{0}to * by dn.exact=uidNumber=0+gidNumber=0,cn=peercred,cn=external,cn=auth manage stop by * none stop" ]; + }; + }; + "olcDatabase={0}config" = { + attrs = { + objectClass = "olcDatabaseConfig"; + olcDatabase = "{0}config"; + olcAccess = [ "{0}to * by * none break" ]; + }; + }; + "olcDatabase={1}mdb" = { + attrs = { + objectClass = [ "olcDatabaseConfig" "olcMdbConfig" ]; + olcDatabase = "{1}mdb"; + olcDbDirectory = "/data/var/openldap/db"; + olcDbIndex = [ + "objectClass eq" + "cn pres,eq" + "uid pres,eq" + "sn pres,eq,subany" + ]; + olcSuffix = "dc=example,dc=com"; + olcAccess = [ "{0}to * by * read break" ]; + }; + }; + }; + }; + + # Setting this causes OpenLDAP to drop the entire database on startup and write the contents of + # of this LDIF string into the database. This ensures that only nix-managed content is found in the + # database. Note that if a lot of entries are created in conjunction with a lot of indexes, this might hurt + # startup performance. + # Also, you can set `readonly on` in `extraDatabaseConfig` to ensure nobody writes data that will be + # lost. + # declarativeContents = "…"; + }; +} diff --git a/hosts/tsuki/services/openvpn.nix b/hosts/tsuki/services/openvpn.nix new file mode 100644 index 0000000..ff3d7ae --- /dev/null +++ b/hosts/tsuki/services/openvpn.nix @@ -0,0 +1,53 @@ +{ config, pkgs, secrets, ... }: +let + inherit (secrets) ips ports; +in { + services = { + openvpn.servers = let + inherit (secrets.keys.certificates) openvpn CA server; + inherit (secrets.openvpn) ip-range; + in { + tsuki = { + config = '' + dev tap + server-bridge ${ips.tsuki} 255.255.255.0 ${ip-range.start} ${ip-range.end} + local 0.0.0.0 + port ${toString ports.openvpn} + user nobody + group nogroup + comp-lzo no + push 'comp-lzo no' + persist-key + persist-tun + keepalive 10 120 + topology subnet + push "dhcp-option DNS 1.1.1.1" + push "dhcp-option DNS 8.8.8.8" + dh none + ecdh-curve prime256v1 + tls-crypt ${openvpn.tls-crypt} + ca ${CA.crt} + cert ${server.crt} + key ${server.key} + auth SHA256 + cipher AES-128-GCM + ncp-ciphers AES-128-GCM + tls-server + tls-version-min 1.2 + tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 + status /var/openvpn/status.log + verb 3 + ''; + autoStart = false; + updateResolvConf = true; + }; + }; + }; + + networking.firewall = { + allowedUDPPorts = [ ports.openvpn ]; + allowedTCPPorts = [ ports.openvpn ]; + }; + + # networking.bridges.br0.interfaces = [ "tap0" "ens18" ]; +} diff --git a/hosts/tsuki/services/plex.nix b/hosts/tsuki/services/plex.nix new file mode 100644 index 0000000..3771ffa --- /dev/null +++ b/hosts/tsuki/services/plex.nix @@ -0,0 +1,21 @@ +{ secrets, ... }: +{ + services.plex = { + enable = true; + openFirewall = true; + dataDir = "/data/var/plex"; + }; + + # TODO: make default directories. + services.samba.shares.plex = { + path = "/data/media"; + browseable = "yes"; + "read only" = "no"; + "guest ok" = "no"; + "create mode" = 0664; + "directory mode" = 2775; + comment = "Movies, Series and other stuff for Plex"; + }; + + networking.firewall.allowedTCPPorts = [ secrets.ports.plex ]; +} diff --git a/hosts/tsuki/services/samba.todo.nix b/hosts/tsuki/services/samba.todo.nix new file mode 100644 index 0000000..dafc6bb --- /dev/null +++ b/hosts/tsuki/services/samba.todo.nix @@ -0,0 +1,23 @@ +{}: +{ + services.samba = { + enable = true; + + extraConfig = '' + ''; + + shares = { + plex = { + path = "/data/media"; + "read only" = false; + browseable = "yes"; + "guest ok" = "no"; + comment = "Pictures, music, videos, etc."; + }; + + # home = { + + # }; + }; + }; +} diff --git a/hosts/tsuki/services/searx.nix b/hosts/tsuki/services/searx.nix new file mode 100644 index 0000000..8aef721 --- /dev/null +++ b/hosts/tsuki/services/searx.nix @@ -0,0 +1,61 @@ +{ secrets, ... }: +{ + # TODO: Make secret keys. + services.searx = { + enable = true; + settings = { + + general = { + debug = false; + instance_name = "Searx"; + }; + + server = { + port = secrets.ports.searx; + bind_address = "0.0.0.0"; + secret_key = secrets.keys.searx.key; + }; + + ui = { + default_theme = "oscar"; + theme_args.oscar_style = "logicodev-dark"; + }; + + engines = [ + # { + # name = "YouTube"; + # shortcut = "yt"; + # engine = "youtube_api"; + # } + { + name = "fdroid"; + engine = "fdroid"; + } + { + name = "github"; + engine = "github"; + } + { + name = "ebay"; + engine = "ebay"; + } + # { + # name = "bandcamp"; + # engine = "bandcamp"; + # } + { + name = "arch_linux_wiki"; + shortcut = "aw"; + engine = "archlinux"; + } + ]; + }; + + # runInUwsgi = true; + # uwsgiConfig = { + # disable-logging = false; + # http = ":11000"; + # socket = "/run/searx/searx.sock"; + # }; + }; +} diff --git a/hosts/tsuki/services/syncthing.todo.nix b/hosts/tsuki/services/syncthing.todo.nix new file mode 100644 index 0000000..e69de29 diff --git a/misc/mimetypes.nix b/misc/mimetypes.nix new file mode 100644 index 0000000..5c4371b --- /dev/null +++ b/misc/mimetypes.nix @@ -0,0 +1,142 @@ +{ lib, ... }: + +let + + # Applications + google-chrome = "google-chrome.desktop"; + gimp = "gimp.desktop"; + inkscape = "org.inkscape.Inkscape.desktop"; + vscode = "code.desktop"; + mpv = "mpv.desktop"; + zathura = "org.pwmt.zathura.desktop"; + sxiv = "sxiv.desktop"; + font-viewer = "org.gnome.font-viewer.desktop"; + + # Formats + "3g2-audio" = "audio/3gpp"; + "3g2-video" = "video/3gpp"; + "3gp-audio" = "audio/3gpp"; + "3gp-video" = "video/3gpp"; + aac = "audio/aac"; + avi = "video/x-msvideo"; + bmp = "image/bmp"; + cbr = "application/vnd.comicbook+rar"; + cbrx = "application/x-cbr"; + cbz = "application/vnd.comicbook+zip"; + cbzx = "application/x-cbz"; + djvu = "image/vnd.djvu"; + epub = "application/epub+zip"; + flv = "video/x-flv"; + gif = "image/gif"; + html = "text/html"; + http = "x-scheme-handler/http"; + https = "x-scheme-handler/https"; + ico = "image/vnd.microsoft.icon"; + icox = "image/x-icon"; + ini = "application/x-wine-extension-ini"; + jpg = "image/jpeg"; + m4v = "video/x-m4v"; + mkv = "video/x-matroska"; + mov = "video/quicktime"; + mp3 = "audio/mpeg"; + mp4 = "video/mp4"; + mpeg = "video/mpeg"; + ogg = "audio/ogg"; + ogv = "video/ogg"; + opus = "audio/opus"; + otf = "font/otf"; + pdf = "application/pdf"; + pic = "image/x-pict"; + png = "image/png"; + psd = "image/vnd.adobe.photoshop"; + svg = "image/svg+xml"; + tiff = "image/tiff"; + ttf = "font/ttf"; + txt = "text/plain"; + url = "application/x-mswinurl"; + wav = "audio/wav"; + wavx = "audio/x-wav"; + webm-audio = "audio/webm"; + webm-video = "video/webm"; + webp = "image/webp"; + wmv = "video/x-ms-wmv"; + woff = "font/woff"; + woff2 = "font/woff2"; + xbm = "image/x-xbitmap"; + xcf = "image/x-xcf"; + xhtml = "application/xhtml+xml"; + xml = "text/xml"; + xpm = "image/x-xpixmap"; + + + # Generalizations + audio-player = mpv; + gui-text-editor = vscode; + image-viewer = sxiv; + pdf-viewer = zathura; + video-player = mpv; + web-browser = google-chrome; + +in { + + xdg.mimeApps = { + enable = true; + # associations.added = {}; + # associations.removed = {}; + defaultApplications = { + ${"3g2-audio"} = audio-player; + ${"3g2-video"} = video-player; + ${"3gp-audio"} = audio-player; + ${"3gp-video"} = video-player; + ${aac} = audio-player; + ${avi} = video-player; + ${bmp} = image-viewer; + ${cbrx} = zathura; + ${cbr} = zathura; + ${cbzx} = zathura; + ${cbz} = zathura; + ${djvu} = pdf-viewer; + ${epub} = zathura; + ${flv} = video-player; + ${gif} = image-viewer; + ${html} = web-browser; + ${https} = web-browser; + ${http} = web-browser; + ${icox} = image-viewer; + ${ico} = image-viewer; + ${jpg} = image-viewer; + ${m4v} = video-player; + ${mkv} = video-player; + ${mov} = video-player; + ${mp3} = audio-player; + ${mp4} = video-player; + ${mpeg} = video-player; + ${ogg} = audio-player; + ${ogv} = video-player; + ${opus} = audio-player; + ${otf} = font-viewer; + ${pdf} = pdf-viewer; + ${pic} = image-viewer; + ${png} = image-viewer; + ${psd} = gimp; + ${svg} = image-viewer; + ${tiff} = image-viewer; + ${ttf} = font-viewer; + ${txt} = gui-text-editor; + ${url} = web-browser; + ${wav} = audio-player; + ${webm-audio} = audio-player; + ${webm-video} = video-player; + ${webp} = image-viewer; + ${wmv} = video-player; + ${woff2} = font-viewer; + ${woff} = font-viewer; + ${xbm} = image-viewer; + ${xcf} = gimp; + ${xhtml} = web-browser; + ${xml} = gui-text-editor; + ${xpm} = image-viewer; + }; + }; +} + diff --git a/misc/ssh/hosts/pvv.nix b/misc/ssh/hosts/pvv.nix new file mode 100644 index 0000000..62ba497 --- /dev/null +++ b/misc/ssh/hosts/pvv.nix @@ -0,0 +1,92 @@ +{ pkgs, secrets, ... }: +let + inherit (pkgs) lib; + inherit (secrets.ssh.users.pvv) normalUser adminUser; + + # http://www.pvv.ntnu.no/pvv/Maskiner + normalMachines = [ + [ "hildring" "pvv-login" "pvv" ] + "demiurgen" + "eirin" + [ "jokum" "pvv-nix" ] + "isvegg" + [ "microbel" "pvv-users" "pvv-mail" ] + ]; + + rootMachines = [ + [ "knakelibrak" "pvv-databases" ] + [ "spikkjeposche" "pvv-web" "pvv-wiki" "pvv-webmail" ] + "sleipner" + "fenris" + "balduzius" + "joshua" + "skrotnisse" + "principal" + "tom" + "monty" + + { + names = ["dvask"]; + proxyJump = "monty"; + } + + [ "innovation" "pvv-minecraft" ] + ]; + + # Either( String [String] AttrSet{String} ) -> AttrSet{String} + normalizeValueType = let + inherit (lib.strings) isString; + inherit (lib.lists) isList; + inherit (lib.attrsets) filterAttrs; + in + machine: + if (isString machine) then { names = [machine]; } + else if (isList machine) then { names = machine; } + else machine; + + # [String] -> AttrSet + machineWithNames = let + inherit (lib.lists) head; + inherit (lib.strings) split; + in + names: { hostname = "${head names}.pvv.org"; }; + + # AttrSet -> AttrSet -> AttrSet + convertMachineWithDefaults = defaults: normalizedMachine: let + inherit (lib.attrsets) nameValuePair; + inherit (lib.strings) concatStringsSep; + inherit (normalizedMachine) names; + + name = concatStringsSep " " names; + value = + (machineWithNames names) + // defaults + // removeAttrs normalizedMachine ["names"]; + in + nameValuePair name value; + + # AttrSet -> AttrSet + convertNormalMachine = convertMachineWithDefaults { user = normalUser; }; + # AttrSet -> AttrSet + convertAdminMachine = + convertMachineWithDefaults { user = adminUser; proxyJump = "hildring"; }; + + # [ Either(String [String] AttrSet{String}) ] -> (AttrSet -> AttrSet) -> AttrSet + convertMachinesWith = convertMachineFunction: let + inherit (lib.attrsets) listToAttrs; + inherit (lib.trivial) pipe; + pipeline = [ + (map normalizeValueType) + (map convertMachineFunction) + listToAttrs + ]; + in + machines: pipe machines pipeline; + +in + { + programs.ssh.matchBlocks = lib.attrsets.concatAttrs [ + (convertMachinesWith convertNormalMachine normalMachines) + (convertMachinesWith convertAdminMachine rootMachines) + ]; + } diff --git a/overlays/lib/attrsets.nix b/overlays/lib/attrsets.nix new file mode 100644 index 0000000..454f1e3 --- /dev/null +++ b/overlays/lib/attrsets.nix @@ -0,0 +1,49 @@ +final: prev: +let + inherit (prev.lib.attrsets) mapAttrs isAttrs filterAttrs listToAttrs nameValuePair attrNames mapAttrsToList; + inherit (prev.lib.lists) foldr imap0 imap1; +in prev.lib.attrsets // rec { + # a -> [String] -> AttrSet{a} + mapToAttrsWithConst = constant: items: + listToAttrs (map (name: nameValuePair name constant) items); + + # [AttrSet] -> AttrSet + concatAttrs = foldr (a: b: a // b) {}; + + # (Int -> String -> a -> a) -> AttrSet -> AttrSet + imap0Attrs = f: set: + listToAttrs (imap0 (i: attr: nameValuePair attr (f i attr set.${attr})) (attrNames set)); + + # (Int -> String -> a -> a) -> AttrSet -> AttrSet + imap1Attrs = f: set: + listToAttrs (imap1 (i: attr: nameValuePair attr (f i attr set.${attr})) (attrNames set)); + + # (Int -> String -> a -> nameValuePair) -> AttrSet -> AttrSet + imap0Attrs' = f: set: + listToAttrs (imap0 (i: attr: f i attr set.${attr}) (attrNames set)); + + # (Int -> String -> a -> nameValuePair) -> AttrSet -> AttrSet + imap1Attrs' = f: set: + listToAttrs (imap1 (i: attr: f i attr set.${attr}) (attrNames set)); + + # AttrSet -> AttrSet + recursivelyFlatten = set: let + shouldRecurse = filterAttrs (n: v: isAttrs v) set; + shouldNotRecurse = filterAttrs (n: v: !(isAttrs v)) set; + recursedAttrs = mapAttrsToList (n: v: recursivelyFlatten v) shouldRecurse; + in + concatAttrs ([shouldNotRecurse] ++ recursedAttrs); + + # Takes in a predicate which decides whether or not to recurse further. (true -> recurse) + # This will let you recurse until you recurse until you hit attrsets with a special meaning + # that you would like to handle after flattening. + # It will also stop at everything other than an attribute set. + # + # (a -> Bool) -> AttrSet -> AttrSet + recursivelyFlattenUntil = pred: set: let + shouldRecurse = filterAttrs (n: v: isAttrs v && !(pred v)) set; + shouldNotRecurse = filterAttrs (n: v: !(isAttrs v) || pred v) set; + recursedAttrs = mapAttrsToList (n: v: recursivelyFlattenUntil pred v) shouldRecurse; + in + concatAttrs ([shouldNotRecurse] ++ recursedAttrs); +} diff --git a/overlays/lib/default.nix b/overlays/lib/default.nix new file mode 100644 index 0000000..3d356bc --- /dev/null +++ b/overlays/lib/default.nix @@ -0,0 +1,10 @@ +final: prev: +{ + lib = prev.lib // { + attrsets = (import ./attrsets.nix) final prev; + lists = (import ./lists.nix) final prev; + strings = (import ./strings.nix) final prev; + termColors = (import ./termColors.nix) final prev; + trivial = (import ./trivial.nix) final prev; + }; +} diff --git a/overlays/lib/lists.nix b/overlays/lib/lists.nix new file mode 100644 index 0000000..f5cd805 --- /dev/null +++ b/overlays/lib/lists.nix @@ -0,0 +1,14 @@ +final: prev: +let + inherit (prev.lib.trivial) const; + inherit (prev.lib.lists) range any all; +in prev.lib.lists // { + # a -> Int -> [a] + repeat = item: times: map (const item) (range 1 times); + + # [Bool] -> Bool + any' = any (boolean: boolean); + + # [Bool] -> Bool + all' = all (boolean: boolean); +} diff --git a/overlays/lib/strings.nix b/overlays/lib/strings.nix new file mode 100644 index 0000000..4891f45 --- /dev/null +++ b/overlays/lib/strings.nix @@ -0,0 +1,40 @@ +final: prev: +let + inherit (final.lib.lists) repeat length; + inherit (prev.lib.strings) concatStringsSep replaceStrings splitString; + # inherit (final.lib.strings) wrap; +in prev.lib.strings // rec { + # String -> [String] + lines = splitString "\n"; + + # String -> (String -> String) -> String -> String + splitMap = splitter: f: string: + concatStringsSep splitter (map f (splitString splitter string)); + + # (String -> String) -> String -> String + mapLines = splitMap "\n"; + + # String -> Int -> String + repeatString = string: times: concatStringsSep "" (repeat string times); + + # Replaces any occurences in a list of strings with a single replacement. + # NOTE: This function does not support regex patterns. + # + # [String] -> String -> String -> String + replaceStrings' = from: to: replaceStrings from (repeat to (length from)); + + # [String] -> String + unlines = concatStringsSep "\n"; + + # [String] -> String + unwords = concatStringsSep " "; + + # String -> [String] + words = builtins.split "\\s+"; + + # String -> String -> String -> String + wrap = start: end: string: start + string + end; + + # String -> String -> String + wrap' = wrapper: wrap wrapper wrapper; +} diff --git a/overlays/lib/termColors.nix b/overlays/lib/termColors.nix new file mode 100644 index 0000000..e04c653 --- /dev/null +++ b/overlays/lib/termColors.nix @@ -0,0 +1,49 @@ +final: prev: +let + inherit (final.lib.strings) wrap; + inherit (prev.lib.attrsets) mapAttrs' nameValuePair; + # inherit (final.lib.myStuff.termColors) escapeCharacter escapeColor resetCharacter wrapWithColor' colorMappings; +in rec { + # String + escapeCharacter = ""; + + # String -> String + escapeColor = color: "${escapeCharacter}[${color}m"; + + # String + resetCharacter = escapeColor "0"; + + # String -> String -> String + wrapWithColor = color: wrap color resetCharacter; + + # String -> String -> String + wrapWithColor' = color: wrap (escapeColor color) resetCharacter; + + # AttrSet{String} + colorMappings = { + "black" = "0"; + "red" = "1"; + "green" = "2"; + "yellow" = "3"; + "blue" = "4"; + "magenta" = "5"; + "cyan" = "6"; + "white" = "7"; + }; + + # AttrSet{(String -> String)} + front = let + # AttrSet{(String -> String)} + names = mapAttrs' (n: v: nameValuePair n (wrapWithColor' ("3" + v))) colorMappings; + + # AttrSet{(String -> String)} + numbers = mapAttrs' (n: v: nameValuePair v (wrapWithColor' ("3" + v))) colorMappings; + in names // numbers; + back = let + # AttrSet{(String -> String)} + names = mapAttrs' (n: v: nameValuePair n (wrapWithColor' ("4" + v))) colorMappings; + + # AttrSet{(String -> String)} + numbers = mapAttrs' (n: v: nameValuePair v (wrapWithColor' ("4" + v))) colorMappings; + in names // numbers; +} diff --git a/overlays/lib/trivial.nix b/overlays/lib/trivial.nix new file mode 100644 index 0000000..54c53b7 --- /dev/null +++ b/overlays/lib/trivial.nix @@ -0,0 +1,7 @@ +final: prev: +let +in prev.lib.trivial // { + # a -> b -> Either (a b) + withDefault = default: value: + if (value == null) then default else value; +} diff --git a/packages.nix b/packages.nix new file mode 100644 index 0000000..cde98b9 --- /dev/null +++ b/packages.nix @@ -0,0 +1,118 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ + ahoviewer + anki + asciidoctor + audacity + beets + biber + calibre + castnow + citra + cool-retro-term + copyq + czkawka + darktable + desmume + discord + diskonaut + diskus + docker + du-dust + fcitx + fd + ffmpeg + geogebra + gnome.gnome-font-viewer + google-chrome + # gpgtui + graphviz + # hck + hexyl + imagemagick + inkscape + insomnia + jq + kepubify + kid3 + koreader + krita + ktouch + lastpass-cli + lazydocker + libreoffice-fresh + light + lolcat + maim + manix + mdcat + mdp + mediainfo + megacmd + megasync + micro + minecraft + mkvtoolnix + mmv + mopidy + mopidy-mpd + mopidy-soundcloud + mopidy-spotify + mopidy-youtube + mpc_cli + mps-youtube + neofetch + nmap + nyxt + osu-lazer + ouch + pandoc + pulseaudio + pulsemixer + python3 + ripgrep + rsync + rust-motd + sc-im + scrcpy + slack + slack-term + # steam-tui + sxiv + tagainijisho + taisei + tealdeer + teams + # tenacity + # tv-renamer + toilet + tokei + touchegg + w3m + waifu2x-converter-cpp + wavemon + xcalib + xclip + xdotool + xfce.thunar + xfce.thunar-archive-plugin + xfce.thunar-dropbox-plugin + xfce.thunar-media-tags-plugin + xfce.thunar-volman + youtube-dl + # yuzu-mainline + zeal + zoom-us + zotero + + # Needed for VSCode liveshare + desktop-file-utils + krb5 + zlib + icu + openssl + xorg.xprop + ]; +} + diff --git a/pluggables/collections/development.nix b/pluggables/collections/development.nix new file mode 100644 index 0000000..e69de29 diff --git a/pluggables/collections/extended-terminal-tools.nix b/pluggables/collections/extended-terminal-tools.nix new file mode 100644 index 0000000..e69de29 diff --git a/pluggables/collections/games.nix b/pluggables/collections/games.nix new file mode 100644 index 0000000..e69de29 diff --git a/pluggables/collections/japanese.nix b/pluggables/collections/japanese.nix new file mode 100644 index 0000000..e69de29 diff --git a/pluggables/collections/multimedia.nix b/pluggables/collections/multimedia.nix new file mode 100644 index 0000000..e69de29 diff --git a/pluggables/collections/school.nix b/pluggables/collections/school.nix new file mode 100644 index 0000000..e69de29 diff --git a/pluggables/server/torrent.nix b/pluggables/server/torrent.nix new file mode 100644 index 0000000..205e789 --- /dev/null +++ b/pluggables/server/torrent.nix @@ -0,0 +1,26 @@ +{ pkgs }: +{ + services.deluge = { + enable = true; + user = "h7x4"; + + # https://git.deluge-torrent.org/deluge/tree/deluge/core/preferencesmanager.py#n41 + # config = { + # download_location = ""; + # share_ratio_limit = ""; + # daemon_port = ""; + # listen_ports = ""; + # }; + + openFirewall = true; + # authFile = + + declarative = true; + + web = { + enable = true; + # port = + openFirewall = true; + }; + }; +} diff --git a/pluggables/tools/programming.nix b/pluggables/tools/programming.nix new file mode 100644 index 0000000..f8987de --- /dev/null +++ b/pluggables/tools/programming.nix @@ -0,0 +1,34 @@ +{ pkgs, ... }: +{ + system.extraDependencies = with pkgs; [ + asciidoc + asciidoctor + cabal2nix + clang + dart + dotnet-sdk + dotnet-sdk_3 + dotnet-sdk_5 + dotnetPackages.Nuget + elm2nix + elmPackages.elm + flutter + gcc + ghc + ghcid + haskellPackages.Cabal_3_6_2_0 + maven + nodePackages.node2nix + nodePackages.npm + nodePackages.sass + nodePackages.typescript + nodePackages.yarn + nodejs + plantuml + python3 + rustc + rustc + rustup + ]; +} + diff --git a/programs/alacritty.nix b/programs/alacritty.nix new file mode 100644 index 0000000..28a8ff3 --- /dev/null +++ b/programs/alacritty.nix @@ -0,0 +1,53 @@ +{ lib, pkgs, colorTheme, ... }: +{ + programs.alacritty = { + enable = true; + settings = { + window.padding = { x = 15; y = 15; }; + + font = { + normal = { + family = "Fira Code"; + style = "Retina"; + }; + bold.family = "Fira Code"; + italic.family = "Fira Code"; + size = 12.0; + }; + + colors = + let + inherit (lib.attrsets) getAttrs filterAttrs; + inherit (lib.lists) any; + primaryColors = [ "foreground" "background" ]; + in + { + primary = getAttrs primaryColors colorTheme.default; + normal = let + removePrimaryColorAttrs = n: v: !(any (pc: n ? pc) primaryColors); + in filterAttrs removePrimaryColorAttrs colorTheme.default; + }; + + background_opacity = 1.0; + + cursor = { + style = "Block"; + blinking = "On"; + unfocused_hollow = true; + }; + + bell = { + animation = "EaseOutExpo"; + color = "0xffffff"; + duration = 20; + }; + + live_config_reload = true; + + shell = { + program = "${pkgs.zsh}/bin/zsh"; + args = [ "--login" ]; + }; + }; + }; +} diff --git a/programs/comma.nix b/programs/comma.nix new file mode 100644 index 0000000..e4c1595 --- /dev/null +++ b/programs/comma.nix @@ -0,0 +1,16 @@ +{ config, pkgs, ... }: +let + comma = import ( pkgs.fetchFromGitHub { + owner = "Shopify"; + repo = "comma"; + rev = "4a62ec17e20ce0e738a8e5126b4298a73903b468"; + sha256 = "0n5a3rnv9qnnsrl76kpi6dmaxmwj1mpdd2g0b4n1wfimqfaz6gi1"; + }) {}; +in +{ + # FIXME: this projects default.nix imports , which makes it very much not kosher + + # home.packages = with pkgs; [ + # comma + # ]; +} diff --git a/programs/emacs.nix b/programs/emacs.nix new file mode 100644 index 0000000..e5ea286 --- /dev/null +++ b/programs/emacs.nix @@ -0,0 +1,25 @@ +{ ... }: +{ + programs.emacs = { + enable = true; + # socketActivation.enable = true; + extraPackages = epkgs: with epkgs; [ + # package + use-package + evil + evil-collection + evil-nerd-commenter + # org + evil-org + monokai-theme + gruber-darker-theme + company + flycheck + projectile + yasnippet + magit + # recentf + which-key + ]; + }; +} diff --git a/programs/gh.nix b/programs/gh.nix new file mode 100644 index 0000000..31deb60 --- /dev/null +++ b/programs/gh.nix @@ -0,0 +1,13 @@ +{ ... }: +{ + programs.gh = { + enable = true; + settings = { + gitProtocol = "ssh"; + aliases = { + co = "pr checkout"; + pv = "pr view"; + }; + }; + }; +} diff --git a/programs/git.nix b/programs/git.nix new file mode 100644 index 0000000..62a44e5 --- /dev/null +++ b/programs/git.nix @@ -0,0 +1,82 @@ +{pkgs, ...}: +{ + programs.git = { + enable = true; + package = pkgs.gitFull; + + userName = "h7x4"; + userEmail = "h7x4abk3g@protonmail.com"; + + aliases = { + aliases = "!git config --get-regexp alias | sed -re 's/alias\\.(\\S*)\\s(.*)$/\\1 = \\2/g'"; + uncommit = "reset --soft HEAD^"; + rev = "checkout HEAD -- "; + revall = "checkout ."; + # unstage = "rm --cached "; + unstage = "restore --staged "; + delete-merged = "!git branch --merged | grep -v '\\*' | xargs -n 1 git branch -d"; + + mkbr = "checkout -b"; + mvbr = "branch -m"; + rmbr = "branch -d"; + rrmbr = "push origin --delete"; + + graph = "log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all"; + graphv = "log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an%C(reset)' --all"; + g = "!git graph"; + }; + + extraConfig = { + core = { + whitespace = "space-before-tab,-indent-with-non-tab,trailing-space"; + + precomposeunicode = false; + untrackedCache = true; + + editor = "nvim"; + pager = "less"; + }; + + "color \"branch\"".upstream = "cyan"; + color.ui = "auto"; + + init.defaultBranch = "main"; + fetch.prune = true; + pull.rebase = true; + push.default = "current"; + + merge = { + tool = "nvimdiff"; + conflictstyle = "diff3"; + colorMoved = "zebra"; + }; + + mergetool.keepBackup = false; + "mergetool \"nvimdiff\"".cmd = "nvim -d $BASE $LOCAL $REMOTE $MERGED -c '$wincmd w' -c 'wincmd J'"; + + diff = { + mnemonicPrefix = true; + renames = true; + tool = "nvimdiff"; + }; + + grep = { + break = true; + heading= true; + lineNumber = true; + extendedRegexp = true; + }; + + github.user = "h7x4abk3g"; + + web.browser = "google-chrome-stable"; + + "filter \"lfs\"" = { + required = true; + smudge = "git-lfs smudge -- %f"; + process = "git-lfs filter-process"; + clean = "git-lfs clean -- %f"; + }; + }; + }; +} diff --git a/programs/ncmpcpp.nix b/programs/ncmpcpp.nix new file mode 100644 index 0000000..c6f873c --- /dev/null +++ b/programs/ncmpcpp.nix @@ -0,0 +1,338 @@ +{pkgs, ...}: +{ + programs.ncmpcpp = { + enable = true; + package = pkgs.ncmpcpp.override { visualizerSupport = true; }; + + bindings = [ + # { key = "j"; command = "scroll_down"; } + { key = "mouse"; command = "mouse_event"; } + + { key = "up"; command = "scroll_up"; } + { key = "shift-up"; command = ["select_item" "scroll_up"]; } + + { key = "down"; command = "scroll_down"; } + { key = "shift-down"; command = ["select_item" "scroll_down"]; } + + { key = "["; command = "scroll_up_album"; } + { key = "]"; command = "scroll_down_album"; } + { key = "{"; command = "scroll_up_artist"; } + { key = "}"; command = "scroll_down_artist"; } + + { key = "page_up"; command = "page_up"; } + { key = "page_down"; command = "page_down"; } + + { key = "home"; command = "move_home"; } + { key = "end"; command = "move_end"; } + { key = "insert"; command = "select_item"; } + + { key = "enter"; command = "enter_directory"; } + { key = "enter"; command = "toggle_output"; } + { key = "enter"; command = "run_action"; } + { key = "enter"; command = "play_item"; } + + { key = "space"; command = "add_item_to_playlist"; } + { key = "space"; command = "toggle_lyrics_update_on_song_change"; } + { key = "space"; command = "toggle_visualization_type"; } + + #CHANGE + { key = "d"; command = "delete_playlist_items"; } + + { key = "delete"; command = "delete_browser_items"; } + { key = "delete"; command = "delete_stored_playlist"; } + + { key = "right"; command = "next_column"; } + { key = "right"; command = "slave_screen"; } + { key = "right"; command = "volume_up"; } + { key = "+"; command = "volume_up"; } + + { key = "left"; command = "previous_column"; } + { key = "left"; command = "master_screen"; } + { key = "left"; command = "volume_down"; } + { key = "-"; command = "volume_down"; } + + { key = ":"; command = "execute_command"; } + { key = "tab"; command = "next_screen"; } + { key = "shift-tab"; command = "previous_screen"; } + { key = "f1"; command = "show_help"; } + + { key = "1"; command = "show_playlist"; } + { key = "2"; command = "show_browser"; } + { key = "2"; command = "change_browse_mode"; } + { key = "3"; command = "show_search_engine"; } + { key = "3"; command = "reset_search_engine"; } + { key = "4"; command = "show_media_library"; } + { key = "4"; command = "toggle_media_library_columns_mode"; } + { key = "5"; command = "show_playlist_editor"; } + { key = "6"; command = "show_tag_editor"; } + { key = "7"; command = "show_outputs"; } + { key = "8"; command = "show_visualizer"; } + { key = "="; command = "show_clock"; } + { key = "@"; command = "show_server_info"; } + + { key = "s"; command = "stop"; } + { key = "p"; command = "pause"; } + { key = ">"; command = "next"; } + { key = "<"; command = "previous"; } + + { key = "ctrl-h"; command = "jump_to_parent_directory"; } + { key = "ctrl-h"; command = "replay_song"; } + { key = "backspace"; command = "jump_to_parent_directory"; } + { key = "backspace"; command = "replay_song"; } + + { key = "f"; command = "seek_forward"; } + { key = "b"; command = "seek_backward"; } + + { key = "r"; command = "toggle_repeat"; } + { key = "z"; command = "toggle_random"; } + { key = "y"; command = "save_tag_changes"; } + { key = "y"; command = "start_searching"; } + { key = "y"; command = "toggle_single"; } + { key = "R"; command = "toggle_consume"; } + { key = "Y"; command = "toggle_replay_gain_mode"; } + { key = "T"; command = "toggle_add_mode"; } + { key = "|"; command = "toggle_mouse"; } + { key = "#"; command = "toggle_bitrate_visibility"; } + { key = "Z"; command = "shuffle"; } + { key = "x"; command = "toggle_crossfade"; } + { key = "X"; command = "set_crossfade"; } + { key = "u"; command = "update_database"; } + { key = "ctrl-s"; command = "sort_playlist"; } + { key = "ctrl-s"; command = "toggle_browser_sort_mode"; } + { key = "ctrl-s"; command = "toggle_media_library_sort_mode"; } + { key = "ctrl-r"; command = "reverse_playlist"; } + { key = "ctrl-f"; command = "apply_filter"; } + { key = "ctrl-_"; command = "select_found_items"; } + { key = "/"; command = "find"; } + { key = "/"; command = "find_item_forward"; } + { key = "?"; command = "find"; } + { key = "?"; command = "find_item_backward"; } + { key = "."; command = "next_found_item"; } + { key = ","; command = "previous_found_item"; } + { key = "w"; command = "toggle_find_mode"; } + { key = "e"; command = "edit_song"; } + { key = "e"; command = "edit_library_tag"; } + { key = "e"; command = "edit_library_album"; } + { key = "e"; command = "edit_directory_name"; } + { key = "e"; command = "edit_playlist_name"; } + { key = "e"; command = "edit_lyrics"; } + { key = "i"; command = "show_song_info"; } + { key = "I"; command = "show_artist_info"; } + { key = "g"; command = "jump_to_position_in_song"; } + { key = "l"; command = "show_lyrics"; } + { key = "ctrl-v"; command = "select_range"; } + { key = "v"; command = "reverse_selection"; } + { key = "V"; command = "remove_selection"; } + { key = "B"; command = "select_album"; } + { key = "a"; command = "add_selected_items"; } + { key = "c"; command = "clear_playlist"; } + { key = "c"; command = "clear_main_playlist"; } + { key = "C"; command = "crop_playlist"; } + { key = "C"; command = "crop_main_playlist"; } + { key = "m"; command = "move_sort_order_up"; } + { key = "m"; command = "move_selected_items_up"; } + { key = "n"; command = "move_sort_order_down"; } + { key = "n"; command = "move_selected_items_down"; } + { key = "M"; command = "move_selected_items_to"; } + { key = "A"; command = "add"; } + { key = "S"; command = "save_playlist"; } + { key = "o"; command = "jump_to_playing_song"; } + { key = "G"; command = "jump_to_browser"; } + { key = "G"; command = "jump_to_playlist_editor"; } + { key = "~"; command = "jump_to_media_library"; } + { key = "E"; command = "jump_to_tag_editor"; } + { key = "U"; command = "toggle_playing_song_centering"; } + { key = "P"; command = "toggle_display_mode"; } + { key = "\\\\"; command = "toggle_interface"; } + { key = "!"; command = "toggle_separators_between_albums"; } + { key = "L"; command = "toggle_lyrics_fetcher"; } + { key = "F"; command = "fetch_lyrics_in_background"; } + { key = "alt-l"; command = "toggle_fetching_lyrics_in_background"; } + { key = "ctrl-l"; command = "toggle_screen_lock"; } + { key = "`"; command = "toggle_library_tag_type"; } + { key = "`"; command = "refetch_lyrics"; } + { key = "`"; command = "add_random_items"; } + { key = "ctrl-p"; command = "set_selected_items_priority"; } + { key = "q"; command = "quit"; } + + # the t key isn't used and it's easier to press than /, so lets use it + { key = "t"; command = "find"; } + { key = "t"; command = "find_item_forward"; } + + { key = "+"; command = "show_clock"; } + { key = "="; command = "volume_up"; } + + { key = "j"; command = "scroll_down"; } + { key = "k"; command = "scroll_up"; } + + { key = "ctrl-u"; command = "page_up"; } + #push_characters "kkkkkkkkkkkkkkk" + { key = "ctrl-d"; command = "page_down"; } + #push_characters "jjjjjjjjjjjjjjj" + + { key = "h"; command = "previous_column"; } + { key = "l"; command = "next_column"; } + + { key = "."; command = "show_lyrics"; } + + { key = "n"; command = "next_found_item"; } + { key = "N"; command = "previous_found_item"; } + + # not used but bound + { key = "J"; command = "move_sort_order_down"; } + { key = "K"; command = "move_sort_order_up"; } + ]; + + settings = { + lyrics_directory = "~/music/.lyrics"; + + playlist_disable_highlight_delay = 0; + message_delay_time = 5; + + # - 0 - default window color (discards all other colors) + # - 1 - black + # - 2 - red + # - 3 - green + # - 4 - yellow + # - 5 - blue + # - 6 - magenta + # - 7 - cyan + # - 8 - white + # - 9 - end of current color + # - b - bold text + # - u - underline text + # - r - reverse colors + # - a - use alternative character set + + song_list_format = "{%a - }{%t}|{$8%f$9}$R{$3(%l)$9}"; + song_status_format = "{{%a{ \"%b\"{ (%y)}} - }{%t}}|{%f}"; + song_library_format = "{%n - }{%t}|{%f}"; + alternative_header_first_line_format = "$b$1$aqqu$/a$9 {%t}|{%f} $1$atqq$/a$9$/b"; + alternative_header_second_line_format = "{{$4$b%a$/b$9}{ - $7%b$9}{ ($4%y$9)}}|{%D}"; + current_item_prefix = "$(yellow)$r"; + current_item_suffix = "$/r$(end)"; + current_item_inactive_column_prefix = "$(white)$r"; + current_item_inactive_column_suffix = "$/r$(end)"; + now_playing_prefix = "$b"; + now_playing_suffix = "$/b"; + browser_playlist_prefix = "$2playlist$9 "; + selected_item_prefix = "$6"; + selected_item_suffix = "$9"; + modified_item_prefix = "$3> $9"; + + song_window_title_format = "{%a - }{%t}|{%f}"; + + browser_sort_mode = "name"; + browser_sort_format = "{%a - }{%t}|{%f} {(%l)}"; + + song_columns_list_format = "(10)[green]{a} (50)[white]{t|f:Title} (20)[cyan]{b} (7f)[magenta]{l}"; + # song_columns_list_format = "(10)[green]{a} (50)[black]{t|f:Title} (20)[cyan]{b} (7f)[magenta]{l}"; + + execute_on_song_change = ""; + + execute_on_player_state_change = ""; + playlist_show_mpd_host = "no"; + playlist_show_remaining_time = "no"; + playlist_shorten_total_times = "no"; + playlist_separate_albums = "no"; + + playlist_display_mode = "columns"; + browser_display_mode = "classic"; + search_engine_display_mode = "classic"; + playlist_editor_display_mode = "classic"; + discard_colors_if_item_is_selected = "yes"; + show_duplicate_tags = "yes"; + incremental_seeking = "yes"; + seek_time = 1; + volume_change_step = 2; + autocenter_mode = "no"; + centered_cursor = "no"; + + progressbar_look = "─⊙╶"; + # progressbar_look = "◾◾◽"; + # progressbar_look = "=> "; + + default_place_to_search_in = "database"; + user_interface = "classic"; + data_fetching_delay = "yes"; + media_library_primary_tag = "artist"; + media_library_albums_split_by_date = "yes"; + default_find_mode = "wrapped"; + default_tag_editor_pattern = "%n - %t"; + header_visibility = "yes"; + statusbar_visibility = "yes"; + titles_visibility = "yes"; + header_text_scrolling = "yes"; + cyclic_scrolling = "no"; + lines_scrolled = 2; + + # lyrics_fetchers = "azlyrics, genius, sing365, lyricsmania, metrolyrics, justsomelyrics, jahlyrics, plyrics, tekstowo, internet"; + follow_now_playing_lyrics = "no"; + fetch_lyrics_for_current_song_in_background = "no"; + store_lyrics_in_song_dir = "no"; + generate_win32_compatible_filenames = "yes"; + allow_for_physical_item_deletion = "no"; + + lastfm_preferred_language = "en"; + space_add_mode = "add_remove"; + show_hidden_files_in_local_browser = "no"; + + screen_switcher_mode = "playlist, browser"; + startup_screen = "playlist"; + startup_slave_screen = ""; + startup_slave_screen_focus = "no"; + + locked_screen_width_part = "50"; + ask_for_locked_screen_width_part = "yes"; + jump_to_now_playing_song_at_start = "yes"; + ask_before_clearing_playlists = "yes"; + clock_display_seconds = "no"; + display_volume_level = "yes"; + display_bitrate = "yes"; + display_remaining_time = "no"; + + ignore_leading_the = "no"; + + ignore_diacritics = "no"; + block_search_constraints_change_if_items_found = "yes"; + mouse_support = "yes"; + mouse_list_scroll_whole_page = "yes"; + empty_tag_marker = ""; + tags_separator = " | "; + tag_editor_extended_numeration = "no"; + media_library_sort_by_mtime = "no"; + enable_window_title = "no"; + + search_engine_default_search_mode = 1; + external_editor = "vim"; + use_console_editor = "yes"; + + colors_enabled = "yes"; + empty_tag_color = "cyan"; + header_window_color = "cyan"; + volume_color = "red"; + state_line_color = "yellow"; + state_flags_color = "red"; + # This one is probably the one you're looking for + main_window_color = "white"; + # main_window_color = "black"; + color1 = "white"; + color2 = "green"; + progressbar_color = "yellow"; + progressbar_elapsed_color = "green:b"; + statusbar_color = "cyan"; + statusbar_time_color = "default:b"; + player_state_color = "default:b"; + alternative_ui_separator_color = "black:b"; + window_border_color = "green"; + active_window_border = "red"; + + # visualizer_fifo_path = "/tmp/mpd.fifo"; + # visualizer_output_name = "my_fifo"; + # visualizer_sync_interval = "30"; + # visualizer_in_stereo = "no"; + # visualizer_type = "spectrum"; # spectrum, ellipse, wave_filled, wave + # visualizer_look = "+█"; # wave | spectrum, ellipse, wave_filled + }; + }; +} diff --git a/programs/neovim.nix b/programs/neovim.nix new file mode 100644 index 0000000..da4d581 --- /dev/null +++ b/programs/neovim.nix @@ -0,0 +1,105 @@ +{ pkgs, home, ... }: +{ + programs.neovim = { + enable = true; + + viAlias = true; + vimAlias = true; + vimdiffAlias = true; + + plugins = with pkgs.vimPlugins; [ + direnv-vim + vim-commentary + vim-gitgutter + fzf-vim + vim-which-key + vim-nix + vim-surround + vim-fugitive + vim-css-color + semshi + { + plugin = goyo-vim; + + # TODO: The mapleader definition should be in extraConfig, but setting + # the mapleader before defining keymaps messes things up. + config = '' + let mapleader = " " + + let g:goyo_width = '90%' + let g:goyo_height = '85%' + let g:goyo_linenr = 1 + + function! s:goyo_enter() + if executable('tmux') && strlen($TMUX) + silent !tmux set status off + silent !tmux list-panes -F '\#F' | grep -q Z || tmux resize-pane -Z + endif + set noshowmode + set noshowcmd + set scrolloff=999 + Limelight + " ... + endfunction + + function! s:goyo_leave() + if executable('tmux') && strlen($TMUX) + silent !tmux set status on + silent !tmux list-panes -F '\#F' | grep -q Z && tmux resize-pane -Z + endif + set showmode + set showcmd + set scrolloff=5 + Limelight! + " ... + endfunction + + autocmd! User GoyoEnter nested call goyo_enter() + autocmd! User GoyoLeave nested call goyo_leave() + + nnoremap z :Goyo + ''; + } + limelight-vim + vim-tmux-navigator + vim-polyglot + lightline-vim + { + plugin = rainbow; + config = '' + let g:rainbow_active = 1 + ''; + } + { + plugin = vim-monokai; + config = '' + colorscheme monokai + autocmd ColorScheme * highlight Normal ctermbg=0 + autocmd ColorScheme * highlight LineNr ctermbg=0 + autocmd ColorScheme * highlight CursorLineNR ctermbg=0 ctermfg=208 + autocmd ColorScheme * highlight SignColumn ctermbg=0 + autocmd ColorScheme * highlight GitGutterAdd ctermbg=0 + autocmd ColorScheme * highlight GitGutterChange ctermbg=0 + autocmd ColorScheme * highlight GitGutterDelete ctermbg=0 + ''; + } + ]; + + extraConfig = '' + set clipboard+=unnamedplus + set number relativenumber + + set undofile + set undodir=~/.cache/vim/undodir + + nnoremap :m .+1== + nnoremap :m .-2== + inoremap :m .+1==gi + inoremap :m .-2==gi + vnoremap :m '>+1gv=gv + vnoremap :m '<-2gv=gv + ''; + }; + + home.sessionVariables = { EDITOR = "nvim"; }; +} diff --git a/programs/newsboat.nix b/programs/newsboat.nix new file mode 100644 index 0000000..541f846 --- /dev/null +++ b/programs/newsboat.nix @@ -0,0 +1,62 @@ +{ lib, ... }: +let + defaultBrowser = "google-chrome-stable %u"; + videoViewer = "mpv %u"; +in { + programs.newsboat = { + enable = true; + autoReload = true; + maxItems = 50; + browser = defaultBrowser; + extraConfig = lib.strings.concatStringsSep "\n" [ + '' + macro m set browser "${videoViewer}"; open-in-browser ; set browser "${defaultBrowser}" + macro l set browser "${defaultBrowser}"; open-in-browser ; set browser "${defaultBrowser}" + '' + + # Unbind keys + '' + unbind-key ENTER + unbind-key j + unbind-key k + unbind-key J + unbind-key K + '' + + # Bind keys - vim style + '' + bind-key j down + bind-key k up + bind-key l open + bind-key h quit + '' + + # Theme + '' + color background default default + color listnormal default default + color listnormal_unread default default + color listfocus black cyan + color listfocus_unread black cyan + color info default black + color article default default + '' + + # Highlights + '' + highlight all "---.*---" yellow + highlight feedlist ".*(0/0))" black + highlight article "(^Feed:.*|^Title:.*|^Author:.*)" cyan default bold + highlight article "(^Link:.*|^Date:.*)" default default + highlight article "https?://[^ ]+" green default + highlight article "^(Title):.*$" blue default + highlight article "\\[[0-9][0-9]*\\]" magenta default bold + highlight article "\\[image\\ [0-9]+\\]" green default bold + highlight article "\\[embedded flash: [0-9][0-9]*\\]" green default bold + highlight article ":.*\\(link\\)$" cyan default + highlight article ":.*\\(image\\)$" blue default + highlight article ":.*\\(embedded flash\\)$" magenta default + '' + ]; + }; +} diff --git a/programs/qutebrowser.nix b/programs/qutebrowser.nix new file mode 100644 index 0000000..a85fab1 --- /dev/null +++ b/programs/qutebrowser.nix @@ -0,0 +1,12 @@ +{ ... }: +{ + programs.qutebrowser = { + enable = true; + aliases = {}; + searchEngines = {}; + settings = {}; + keyBindings = {}; + # quickmarks = {}; + extraConfig = ''''; + }; +} diff --git a/programs/rofi.nix b/programs/rofi.nix new file mode 100644 index 0000000..18301b0 --- /dev/null +++ b/programs/rofi.nix @@ -0,0 +1,35 @@ +{pkgs, ...}: +{ + programs.rofi = { + enable = true; + + # plugins = with pkgs; [ + # rofi-emoji + # rofi-mpd + # rofi-pass + # rofi-calc + # rofi-systemd + # rofi-power-menu + # rofi-file-browser + # ]; + + font = "Droid Sans 12"; + theme = ../../general/.config/rofi/themes/blank.rasi; + + extraConfig = { + modi = "window,run,drun,ssh,windowcd"; + show-icons = true; + drun-display-format = "{name}"; + # fullscreen = false; + threads = 0; + matching = "fuzzy"; + scroll-method = 0; + disable-history = false; + window-thumbnail = true; + kb-row-up = "Up,Alt+k"; + kb-row-down = "Down,Alt+j"; + kb-row-left = "Alt+h"; + kb-row-right = "Alt+l"; + }; + }; +} diff --git a/programs/tmux.nix b/programs/tmux.nix new file mode 100644 index 0000000..60ec3fd --- /dev/null +++ b/programs/tmux.nix @@ -0,0 +1,106 @@ +{pkgs, ...}: +{ + programs.tmux = { + enable = true; + baseIndex = 1; + clock24 = true; + escapeTime = 0; + keyMode = "vi"; + prefix = "C-a"; + plugins = with pkgs.tmuxPlugins; [ + fingers + fpp + pain-control + prefix-highlight + sidebar + tmux-fzf + urlview + ]; + extraConfig = '' + # Don't rename windows automatically after rename with ',' + set-option -g allow-rename off + + set -g mouse on + set -q -g status-utf8 on + setw -q -g utf8 on + set-option -g default-terminal screen-256color + set -g base-index 1 # windows starts at 1 + setw -g monitor-activity on + set -g visual-activity on + + # Length of tmux status line + set -g status-left-length 30 + set -g status-right-length 150 + + set -g base-index 1 + set -g pane-base-index 0 + + ###################### + ######## KEYS ######## + ###################### + + # Split panes using $P-[gh] + bind h split-window -h -c "#{pane_current_path}" + bind g split-window -v -c "#{pane_current_path}" + unbind '"' # Unbind default vertical split + unbind % # Unbind default horizontal split + + # Reload config using $P-r + unbind r + bind r \ + source-file $XDG_CONFIG_HOME/tmux/tmux.conf\;\ + display-message 'Reloaded tmux.conf' + + # Switch panes using Alt-[hjkl] + bind -n C-h select-pane -L + bind -n C-j select-pane -D + bind -n C-k select-pane -U + bind -n C-l select-pane -R + + # Resize pane using Alt-Shift-[hjkl] + bind -n M-H resize-pane -L 5 + bind -n M-J resize-pane -D 5 + bind -n M-K resize-pane -U 5 + bind -n M-L resize-pane -R 5 + + # Fullscreen current pane using $P-Alt-z + unbind z + bind M-z resize-pane -Z + + # Kill pane using $P-Backspace + unbind & + bind BSpace killp + + # Swap clock-mode and new-window + # New tab: $P-t + # Clock mode: $P-c + unbind c + unbind t + bind c clock-mode + bind t new-window + + # Setup 'y' to yank (copy) + bind-key -T copy-mode-vi 'y' send -X copy-pipe-and-cancel "pbcopy" + bind-key -T copy-mode-vi 'V' send -X select-line + bind-key -T copy-mode-vi 'r' send -X rectangle-toggle + + ###################### + ### DESIGN CHANGES ### + ###################### + + set-option -g status-left '#{prefix_highlight} #[bg=blue]#[fg=black,bold] ###S #[bg=default] #[fg=green]#(~/.scripts/tmux/fcitx) #[fg=red]%H:%M ' + set-option -g status-right '#[fg=red]#(~/.scripts/tmux/mpd)' + set-window-option -g window-status-current-style fg=magenta + set-option -g status-style 'bg=black fg=default' + set-option -g default-shell '${pkgs.zsh}/bin/zsh' + + set -g status-position bottom + set -g status-interval 4 + set -g status-justify centre # center align window list + + setw -g status-bg default + setw -g window-status-format '#[bg=#888888]#[fg=black,bold] #I #[bg=default] #[fg=#888888]#W ' + setw -g window-status-current-format '#[fg=black,bold]#[bg=cyan] #I #[fg=cyan]#[bg=default] #W ' + ''; + }; +} diff --git a/programs/vscode-extensions/noop-syslog.c b/programs/vscode-extensions/noop-syslog.c new file mode 100644 index 0000000..c76ec57 --- /dev/null +++ b/programs/vscode-extensions/noop-syslog.c @@ -0,0 +1 @@ +void syslog(int priority, const char *format, ...) { } diff --git a/programs/vscode-extensions/vsliveshare.nix b/programs/vscode-extensions/vsliveshare.nix new file mode 100644 index 0000000..a67b003 --- /dev/null +++ b/programs/vscode-extensions/vsliveshare.nix @@ -0,0 +1,124 @@ +# Based on previous attempts: +# - +# - +{ lib, gccStdenv, vscode-utils +, jq, autoPatchelfHook, bash, makeWrapper +, dotnet-sdk_3, curl, gcc, icu, libkrb5, libsecret, libunwind, libX11, lttng-ust, openssl, util-linux, zlib +, desktop-file-utils, xprop, xsel +}: + +with lib; + +let + # https://docs.microsoft.com/en-us/visualstudio/liveshare/reference/linux#install-prerequisites-manually + libs = [ + # .NET Core + openssl + libkrb5 + zlib + icu + + # Credential Storage + libsecret + + # NodeJS + libX11 + + # https://github.com/flathub/com.visualstudio.code.oss/issues/11#issuecomment-392709170 + libunwind + lttng-ust + curl + + # General + gcc.cc.lib + util-linux # libuuid + ]; + +in ((vscode-utils.override { stdenv = gccStdenv; }).buildVscodeMarketplaceExtension { + mktplcRef = { + name = "vsliveshare"; + publisher = "ms-vsliveshare"; + version = "1.0.5090"; + sha256 = "gQ4tChmGxYIt+/izw9NvLCLHD8ypNO7pcWuLw4umhF0="; + }; +}).overrideAttrs({ nativeBuildInputs ? [], buildInputs ? [], ... }: { + nativeBuildInputs = nativeBuildInputs ++ [ + bash + jq + autoPatchelfHook + makeWrapper + ]; + buildInputs = buildInputs ++ libs; + + # Using a patch file won't work, because the file changes too often, causing the patch to fail on most updates. + # Rather than patching the calls to functions, we modify the functions to return what we want, + # which is less likely to break in the future. + postPatch = '' + sed -i \ + -e 's/updateExecutablePermissionsAsync() {/& return;/' \ + -e 's/isInstallCorrupt(traceSource, manifest) {/& return false;/' \ + out/prod/extension-prod.js + declare ext_unique_id + ext_unique_id="$(basename "$out")" + # Fix extension attempting to write to 'modifiedInternalSettings.json'. + # Move this write to the tmp directory indexed by the nix store basename. + substituteInPlace out/prod/extension-prod.js \ + --replace "path.resolve(constants_1.EXTENSION_ROOT_PATH, './modifiedInternalSettings.json')" \ + "path.join(os.tmpdir(), '$ext_unique_id-modifiedInternalSettings.json')" + # Fix extension attempting to write to 'vsls-agent.lock'. + # Move this write to the tmp directory indexed by the nix store basename. + substituteInPlace out/prod/extension-prod.js \ + --replace "path + '.lock'" \ + "__webpack_require__('path').join(__webpack_require__('os').tmpdir(), '$ext_unique_id-vsls-agent.lock')" + # Hardcode executable paths + echo '#!/bin/sh' >node_modules/@vsliveshare/vscode-launcher-linux/check-reqs.sh + substituteInPlace node_modules/@vsliveshare/vscode-launcher-linux/install.sh \ + --replace desktop-file-install ${desktop-file-utils}/bin/desktop-file-install + substituteInPlace node_modules/@vsliveshare/vscode-launcher-linux/uninstall.sh \ + --replace update-desktop-database ${desktop-file-utils}/bin/update-desktop-database + substituteInPlace node_modules/@vsliveshare/vscode-launcher-linux/vsls-launcher \ + --replace /bin/bash ${bash}/bin/bash + substituteInPlace out/prod/extension-prod.js \ + --replace xprop ${xprop}/bin/xprop \ + --replace "'xsel'" "'${xsel}/bin/xsel'" + ''; + + postInstall = '' + cd $out/share/vscode/extensions/ms-vsliveshare.vsliveshare + bash -s <~!@#$%^&*|+=[]{}`?-"; + wordWrap = "off"; + # "bracketPairColorization.enabled" = true; + }; + + zen = mapPrefixToSet "zenMode" { + centerLayout = true; + hideStatusBar = false; + hideLineNumbers = false; + hideTabs = false; + }; + + vim = mapPrefixToSet "vim" { + useSystemClipboard = true; + "statusBarColorControl" = true; + "statusBarColors.insert" = "#20ff00"; + "statusBarColors.normal" = "#1D1E20"; + "statusBarColors.visual" = "#00ffff"; + "statusBarColors.replace" = "#ff002b"; + handleKeys = { + "" = true; + "" = false; + "" = false; + "" = false; + "" = false; + "" = false; + "" = true; + }; + }; + + workbench = mapPrefixToSet "workbench" { + "settings.enableNaturalLanguageSearch" = false; + enableExperiments = false; + iconTheme = "material-icon-theme"; + colorTheme = "Monokai ST3"; + colorCustomizations = { + "statusBar.background" = "#1D1E20"; + "statusBar.noFolderBackground" = "#1D1E20"; + "statusBar.debuggingBackground" = "#1D1E20"; + "[Monokai ST3]" = { + "editor.foreground" = "#ffffff"; + }; + }; + editorAssociations = { + "*.pdf" = "default"; + "*.ipynb" = "jupyter.notebook.ipynb"; + }; + }; + + python = mapPrefixToSet "python" { + "analysis.completeFunctionParens" = true; + "formatting.provider" = "yapf"; + "formatting.yapfArgs" = [ + "--style={based_on_style: pep8, indent_width: 2}" + ]; + "autoComplete.addBrackets" = true; + languageServer = "Pylance"; + }; + + java = mapPrefixToSet "java" { + "configuration.checkProjectSettingsExclusions" = false; + "test.report.showAfterExecution" = "always"; + "test.report.position" = "currentView"; + "refactor.renameFromFileExplorer" = "preview"; + }; + + sync = mapPrefixToSet "sync" { + autoUpload = true; + autoDownload = true; + quietSync = true; + gist = "86e19852a95d31a278ad1a516b40556b"; + }; + + svg = mapPrefixToSet "svgviewer" { + transparencygrid = true; + enableautopreview = true; + previewcolumn = "Beside"; + showzoominout = true; + }; + + indentRainbow = mapPrefixToSet "indentRainbow" { + errorColor = "rgb(255, 0, 0)"; + colors = [ # http://colrd.com/palette/38436/ + "rgba(26, 19, 52, 0.1)" + "rgba(1, 84, 90, 0.1)" + "rgba(3, 195, 131, 0.1)" + "rgba(251, 191, 69, 0.1)" + "rgba(237, 3, 69, 0.1)" + "rgba(113, 1, 98, 0.1)" + "rgba(2, 44, 125, 0.1)" + "rgba(38, 41, 74, 0.1)" + "rgba(1, 115, 81, 0.1)" + "rgba(170, 217, 98, 0.1)" + "rgba(239, 106, 50, 0.1)" + "rgba(161, 42, 94, 0.1)" + ]; + ignoreErrorLanguages = [ + "markdown" + "haskell" + "elm" + "fsharp" + "java" + ]; + }; + + in + editor // + indentRainbow // + java // + python // + svg // + sync // + workbench // + vim // # This needs to come after workbench because of setting ordering + zen // + { + "extensions.autoCheckUpdates" = false; + "extensions.autoUpdate" = false; + "diffEditor.ignoreTrimWhitespace" = false; + "emmet.triggerExpansionOnTab" = true; + "explorer.confirmDragAndDrop" = false; + "git.allowForcePush" = true; + "git.autofetch" = true; + "telemetry.telemetryLevel" = "off"; + "terminal.integrated.fontSize" = 14; + "vsintellicode.modify.editor.suggestSelection" = "automaticallyOverrodeDefaultValue"; + "window.zoomLevel" = 2; + + # This setting does not support language overrides + "files.exclude" = { + # Java + "**/.classpath" = true; + "**/.project" = true; + "**/.settings" = true; + "**/.factorypath" = true; + }; + + # Extensions + + "bracket-pair-colorizer-2.colorMode" = "Consecutive"; + "bracket-pair-colorizer-2.forceIterationColorCycle" = true; + "bracket-pair-colorizer-2.colors" = [ + "#fff200" + "#3d33ff" + "#ff57d5" + "#00ff11" + "#ff8400" + "#ff0030" + ]; + "docker.showStartPage" = false; + + "errorLens.errorColor" = "rgba(240,0,0,0.1)"; + "errorLens.warningColor" = "rgba(180,180,0,0.1)"; + + "jupyter.askForKernelRestart" = false; + + "keyboard-quickfix.showActionNotification" = false; + + "latex-workshop.latex.autoBuild.run" = "onFileChange"; + "latex-workshop.view.pdf.viewer" = "tab"; + + "liveshare.presence" = true; + "liveshare.showInStatusBar" = "whileCollaborating"; + + "liveServer.settings.port" = 5500; + + "material-icon-theme.folders.associations" = { + ui = "layout"; + bloc = "controller"; + }; + + "redhat.telemetry.enabled" = false; + + "sonarlint.rules" = { + "java:S3358" = { + "level" = "off"; + }; + }; + + # Language overrides + + "dart.previewFlutterUiGuides" = true; + "dart.previewFlutterUiGuidesCustomTracking" = true; + "dart.previewLsp" = true; + + "[dart]" = { + "editor.defaultFormatter" = "Dart-Code.dart-code"; + }; + + "[html]" = { + "editor.formatOnSave" = false; + "editor.defaultFormatter" = "lonefy.vscode-JS-CSS-HTML-formatter"; + }; + + "[javascript]" = { + "editor.formatOnSave" = false; + "editor.defaultFormatter" = "vscode.typescript-language-features"; + }; + + "[json]" = { + "editor.formatOnSave" = true; + }; + + "[jsonc]" = { + "editor.defaultFormatter" = "vscode.json-language-features"; + }; + }; + + keybindings = [ + { + key = "ctrl+[Period]"; + command = "keyboard-quickfix.openQuickFix"; + when = "editorHasCodeActionsProvider && editorTextFocus && !editorReadonly"; + } + + { + key = "alt+k"; + command = "selectPrevSuggestion"; + when = "suggestWidgetMultipleSuggestions && suggestWidgetVisible && textInputFocus"; + } + + { + key = "alt+j"; + command = "selectNextSuggestion"; + when = "suggestWidgetMultipleSuggestions && suggestWidgetVisible && textInputFocus"; + } + + { + key = "alt+k"; + command = "editor.action.moveLinesUpAction"; + when = "editorTextFocus && !editorReadonly && !suggestWidgetVisible"; + } + + { + key = "alt+j"; + command = "editor.action.moveLinesDownAction"; + when = "editorTextFocus && !editorReadonly && !suggestWidgetVisible"; + } + + { + key = "alt+j"; + command = "workbench.action.quickOpenNavigateNext"; + when = "inQuickOpen"; + } + + { + key = "alt+k"; + command = "workbench.action.quickOpenNavigatePrevious"; + when = "inQuickOpen"; + } + + { + key = "alt+f"; + command = "editor.action.formatDocument"; + when = "editorTextFocus && !editorReadonly"; + } + + { + key = "alt+o"; + command = "editor.action.insertLineAfter"; + when = "textInputFocus && !editorReadonly"; + } + + { + key = "alt+shift+o"; + command = "editor.action.insertLineBefore"; + when = "textInputFocus && !editorReadonly"; + } + ]; + + extensions = with pkgs.vscode-extensions; [ + vs-liveshare + # ms-vsliveshare.vsliveshare + redhat.java + wholroyd.jinja + bbenoist.nix + # jock.svg + vscodevim.vim + haskell.haskell + justusadam.language-haskell + naumovs.color-highlight + # eamodio.gitlens + ms-python.python + mikestead.dotenv + redhat.vscode-yaml + # ms-toolsai.jupyter + # dotjoshjohnson.xml + usernamehw.errorlens + ibm.output-colorizer + gruntfuggly.todo-tree + mechatroner.rainbow-csv + ms-python.vscode-pylance + james-yu.latex-workshop + elmtooling.elm-ls-vscode + # WakaTime.vscode-wakatime + yzhang.markdown-all-in-one + pkief.material-icon-theme + # ms-vscode-remote.remote-ssh + # ms-azuretools.vscode-docker + justusadam.language-haskell + coenraads.bracket-pair-colorizer-2 + ] ++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [ + { + name = "path-intellisense"; + publisher = "christian-kohler"; + version = "2.4.2"; + sha256 = "1a4d1n4jpdlx4r2majirnhnwlj34jc94wzbxdrih615176hadxvc"; + } + { + name = "xml"; + publisher = "DotJoshJohnson"; + version = "2.5.1"; + sha256 = "1v4x6yhzny1f8f4jzm4g7vqmqg5bqchyx4n25mkgvw2xp6yls037"; + } + { + name = "vscode-html-css"; + publisher = "ecmel"; + version = "1.10.2"; + sha256 = "0qzh7fwgadcahxx8hz1sbfz9lzi81iv4xiidvfm3sahyl9s6pyg1"; + } + { + name = "elm-ls-vscode"; + publisher = "elmTooling"; + version = "2.3.0"; + sha256 = "1nxl3im5aqiggjx0va64bpjrwshb6fzxan78fqzs68iwn16vsa0b"; + } + { + name = "vscode-drawio"; + publisher = "hediet"; + version = "1.6.3"; + sha256 = "0r4qrw1l8s8sfgxj4wvkzamd3yc1h1l60r3kkc1g9afkikmnbr5w"; + } + { + name = "language-x86-64-assembly"; + publisher = "13xforever"; + version = "3.0.0"; + sha256 = "0lxg58hgdl4d96yjgrcy2dbacxsc3wz4navz23xaxcx1bgl1i2y0"; + } + { + name = "monokai-st3"; + publisher = "AndreyVolosovich"; + version = "0.2.0"; + sha256 = "1rvz5hlrfshy9laybxzvrdklx328s13j0lb8ljbda9zkadi3wcad"; + } + # { + # name = "nix-env-selector"; + # publisher = "arrterian"; + # version = "1.0.7"; + # sha256 = "0mralimyzhyp4x9q98x3ck64ifbjqdp8cxcami7clvdvkmf8hxhf"; + # } + { + name = "vscode-JS-CSS-HTML-formatter"; + publisher = "lonefy"; + version = "0.2.3"; + sha256 = "06vivclp58wzmqcx6s6pl8ndqina7p995dr59aj9fk65xihkaagy"; + } + { + name = "indent-rainbow"; + publisher = "oderwat"; + version = "8.2.2"; + sha256 = "1xxljwh66f21fzmhw8icrmxxmfww1s67kf5ja65a8qb1x1rhjjgf"; + } + { + name = "vscode-css-peek"; + publisher = "pranaygp"; + version = "4.2.0"; + sha256 = "0dpkp3xs8jd826h2aa9xlfilsj4yv8q6r9cs350ljrpcyj7wrlpq"; + } + { + name = "LiveServer"; + publisher = "ritwickdey"; + version = "5.6.1"; + sha256 = "077arf3hsn1yb8xdhlrax5gf93ljww78irv4gm8ffmsqvcr1kws0"; + } + { + name = "background"; + publisher = "shalldie"; + version = "1.1.29"; + sha256 = "1x3k8pmzp186bcgga3wg6y86waxrcsi5cnwaxfmifqgn87jp2vqq"; + } + { + name = "trailing-spaces"; + publisher = "shardulm94"; + version = "0.3.1"; + sha256 = "0h30zmg5rq7cv7kjdr5yzqkkc1bs20d72yz9rjqag32gwf46s8b8"; + } + { + name = "comment-divider"; + publisher = "stackbreak"; + version = "0.4.0"; + sha256 = "1qcj2lngcv1sc7jri70ilkkrcx34wn8f4sqwk4dlgrribw6nvj1g"; + } + { + name = "lorem-ipsum"; + publisher = "Tyriar"; + version = "1.3.0"; + sha256 = "03jas413ivahfpxrlc5qif35nd67m1nmwx8p8dj1fpv04s6fdigb"; + } + { + name = "asciidoctor-vscode"; + publisher = "asciidoctor"; + version = "2.8.10"; + sha256 = "1n293nsaid9c4lsfn5ns4899yay9vckfk7ld3l2cnd29s82d316i"; + } + { + name = "vscode-svgviewer"; + publisher = "cssho"; + version = "2.0.0"; + sha256 = "06swlqiv3gc7plcbmzz795y6zwpxsdhg79k1n3jj6qngfwnv2p6z"; + } + { + name = "arm"; + publisher = "dan-c-underwood"; + version = "1.5.2"; + sha256 = "0x31wmd6m1gzm0sfi5xjsa38jr043qq9kgykw3b52hcma7ww8ky3"; + } + { + name = "dart-code"; + publisher = "Dart-Code"; + version = "3.28.0"; + sha256 = "0ppzv0cs4b559m4nvbfik2m63hs10g5idrc5j3pkgdjm14n1jiwv"; + } + { + name = "comment-anchors"; + publisher = "ExodiusStudios"; + version = "1.9.6"; + sha256 = "1zgvgf6zq1ny3v8b9jjp4j3n27qmiz45g23ljaim92g6hni38wvv"; + } + { + name = "bloc"; + publisher = "FelixAngelov"; + version = "6.2.0"; + sha256 = "0rr00pfcpjk17plzmmaqr0znj3k1qd0m2rh15c9894fifdyy69fx"; + } + { + name = "vscode-test-explorer"; + publisher = "hbenl"; + version = "2.21.1"; + sha256 = "022lnkq278ic0h9ggpqcwb3x3ivpcqjimhgirixznq0zvwyrwz3w"; + } + { + name = "haskell-linter"; + publisher = "hoovercj"; + version = "0.0.6"; + sha256 = "0fb71cbjx1pyrjhi5ak29wj23b874b5hqjbh68njs61vkr3jlf1j"; + } + { + name = "plantuml"; + publisher = "jebbs"; + version = "2.16.1"; + sha256 = "17gkrai7fdhrq0q1zip4wn7j4qx9vbbirx3n68silb34wh0dbydk"; + } + { + name = "vscode-gutter-preview"; + publisher = "kisstkondoros"; + version = "0.29.0"; + sha256 = "00vibv9xmhwaqiqzp0y2c246pqiqfjsw4bqx4vcdd67pz1wnqhg1"; + } + { + name = "vscode-JS-CSS-HTML-formatter"; + publisher = "lonefy"; + version = "0.2.3"; + sha256 = "06vivclp58wzmqcx6s6pl8ndqina7p995dr59aj9fk65xihkaagy"; + } + { + name = "git-graph"; + publisher = "mhutchie"; + version = "1.30.0"; + sha256 = "000zhgzijf3h6abhv4p3cz99ykj6489wfn81j0s691prr8q9lxxh"; + } + { + name = "test-adapter-converter"; + publisher = "ms-vscode"; + version = "0.1.4"; + sha256 = "02b04756kfk640hri1xw0p6kwjxwp8d2hpmca0iysfivfcmm1bqn"; + } + { + name = "awesome-flutter-snippets"; + publisher = "Nash"; + version = "3.0.2"; + sha256 = "009z6k719w0sypzsk53wiard3j3d8bq9b0g9s82vw3wc4jvkc3hr"; + } + { + name = "indent-rainbow"; + publisher = "oderwat"; + version = "8.2.2"; + sha256 = "1xxljwh66f21fzmhw8icrmxxmfww1s67kf5ja65a8qb1x1rhjjgf"; + } + { + name = "vscode-xml"; + publisher = "redhat"; + version = "0.18.1"; + sha256 = "006fjcr8s3rsznqgpp13cmvw8k94cfpr24r3rp019jaj5as3l1ck"; + } + { + name = "comment-divider"; + publisher = "stackbreak"; + version = "0.4.0"; + sha256 = "1qcj2lngcv1sc7jri70ilkkrcx34wn8f4sqwk4dlgrribw6nvj1g"; + } + { + name = "addDocComments"; + publisher = "stevencl"; + version = "0.0.8"; + sha256 = "08572fhn6ilfbx8zwn849ab3npyfkh9m5mk2br6sii601s9k5vrk"; + } + { + name = "vscodeintellicode"; + publisher = "VisualStudioExptTeam"; + version = "1.2.14"; + sha256 = "1j72v6grwasqk34m1jy3d6w3fgrw0dnsv7v17wca8baxrvgqsm6g"; + } + { + name = "vscode-java-debug"; + publisher = "vscjava"; + version = "0.36.0"; + sha256 = "1p9mymbf8sn39k44350zf3zwl29fhcwxfsqxr7841ch1qz88w9r8"; + } + { + name = "vscode-java-dependency"; + publisher = "vscjava"; + version = "0.18.8"; + sha256 = "1yjzgf96kqm09qlhxpa249fqb2b5wpzw9k53sgr8jx8sfx5qn95b"; + } + { + name = "vscode-java-pack"; + publisher = "vscjava"; + version = "0.18.6"; + sha256 = "095jdvvv4m8s2ymnrsq0ay7afqff5brgn6waknjfyy97qb3mzxj8"; + } + { + name = "vscode-java-test"; + publisher = "vscjava"; + version = "0.32.0"; + sha256 = "0lq6daz228ipzls88y09zbdsv9n6backs5bddpdam628rs99qvn3"; + } + { + name = "vscode-maven"; + publisher = "vscjava"; + version = "0.34.1"; + sha256 = "1mnlvnl2lg8fijxx4a6rqjix9k2j82js8kn8da7kjf4wh0ksdgvd"; + } + { + name = "markdown-all-in-one"; + publisher = "yzhang"; + version = "3.4.0"; + sha256 = "0ihfrsg2sc8d441a2lkc453zbw1jcpadmmkbkaf42x9b9cipd5qb"; + } + ]; + }; +} diff --git a/programs/zathura.nix b/programs/zathura.nix new file mode 100644 index 0000000..bba7591 --- /dev/null +++ b/programs/zathura.nix @@ -0,0 +1,26 @@ +{ ... }: +{ + programs.zathura = { + enable = true; + options = { + selection-clipboard = "clipboard"; + + default-bg = "#f2e3bd"; + + completion-bg = "#f2e3bd"; + completion-fg = "#5fd7a7"; + + statusbar-bg = "#f2e3bd"; + statusbar-fg = "#008ec4"; + + inputbar-bg = "#f2e3bd"; + inputbar-fg = "#c30771"; + + recolor = true; + recolor-lightcolor = "#f2e3bd"; + # recolor-darkcolor = "#000000"; + recolor-darkcolor = "#101010"; + recolor-keephue = true; + }; + }; +} diff --git a/programs/zsh/default.nix b/programs/zsh/default.nix new file mode 100644 index 0000000..c2574f6 --- /dev/null +++ b/programs/zsh/default.nix @@ -0,0 +1,60 @@ +{ pkgs, lib, config, shellOptions, ... }: +{ + programs.zsh = rec { + enable = true; + dotDir = ".config/zsh"; + # enableSyntaxHighlighting = true; + defaultKeymap = "viins"; + + plugins = [ + # { + # name = "nix-zsh-shell-integration"; + # src = pkgs.nix-zsh-shell-integration; + # } + { + name = "zsh-fast-syntax-highlighting"; + src = pkgs.zsh-fast-syntax-highlighting; + } + { + name = "zsh-completions"; + src = pkgs.zsh-completions; + } + { + name = "zsh-you-should-use"; + src = pkgs.zsh-you-should-use; + } + { + name = "zsh-autosuggestions"; + src = pkgs.zsh-autosuggestions; + } + { + name = "powerlevel10k"; + src = pkgs.zsh-powerlevel10k; + file = "share/zsh-powerlevel10k/powerlevel10k.zsh-theme"; + } + ]; + + localVariables = shellOptions.variables; + + shellAliases = shellOptions.flattened.aliases; + + # initExtra = let + # functions = { + # # TODO: make 'join' available. + # md-to-pdf = join [ + # "pandoc \"$1\"" + # "-f gfm" + # "-V linkcolor:blue" + # "-V geometry:a4paper" + # "-V geometry:margin=2cm" + # "-V mainfont=\"Droid Sans\"" + # "--pdf-engine=xelatex" + # "-o \"$2\"" + # ]; + # }; + # in '' + initExtra = '' + source ${./p10k.zsh} + ''; + }; +} diff --git a/programs/zsh/p10k.zsh b/programs/zsh/p10k.zsh new file mode 100644 index 0000000..378729c --- /dev/null +++ b/programs/zsh/p10k.zsh @@ -0,0 +1,1590 @@ +# Generated by Powerlevel10k configuration wizard on 2021-10-24 at 01:07 CEST. +# Based on romkatv/powerlevel10k/config/p10k-lean.zsh, checksum 19275. +# Wizard options: nerdfont-complete + powerline, large icons, ascii, lean, 1 line, +# compact, concise, instant_prompt=verbose. +# Type `p10k configure` to generate another config. +# +# Config for Powerlevel10k with lean prompt style. Type `p10k configure` to generate +# your own config based on it. +# +# Tip: Looking for a nice color? Here's a one-liner to print colormap. +# +# for i in {0..255}; do print -Pn "%K{$i} %k%F{$i}${(l:3::0:)i}%f " ${${(M)$((i%6)):#3}:+$'\n'}; done + +# Temporarily change options. +'builtin' 'local' '-a' 'p10k_config_opts' +[[ ! -o 'aliases' ]] || p10k_config_opts+=('aliases') +[[ ! -o 'sh_glob' ]] || p10k_config_opts+=('sh_glob') +[[ ! -o 'no_brace_expand' ]] || p10k_config_opts+=('no_brace_expand') +'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand' + +() { + emulate -L zsh -o extended_glob + + # Unset all configuration options. This allows you to apply configuration changes without + # restarting zsh. Edit ~/.p10k.zsh and type `source ~/.p10k.zsh`. + unset -m '(POWERLEVEL9K_*|DEFAULT_USER)~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=( + # os_icon # os identifier + dir # current directory + vcs # git status + 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=( + 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) + aws # aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) + aws_eb_env # aws elastic beanstalk environment (https://aws.amazon.com/elasticbeanstalk/) + azure # azure account name (https://docs.microsoft.com/en-us/cli/azure) + gcloud # google cloud cli account and project (https://cloud.google.com/) + google_app_cred # google application credentials (https://cloud.google.com/docs/authentication/production) + context # user@hostname + nordvpn # nordvpn connection status, linux only (https://nordvpn.com/) + ranger # ranger shell (https://github.com/ranger/ranger) + nnn # nnn shell (https://github.com/jarun/nnn) + 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) + # 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 + # 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=ascii + # When set to `moderate`, some icons will have an extra space after them. This is meant to avoid + # icon overlap when using non-monospace fonts. When set to `none`, spaces are not added. + typeset -g POWERLEVEL9K_ICON_PADDING=none + + # Basic style options that define the overall look of your prompt. You probably don't want to + # change them. + typeset -g POWERLEVEL9K_BACKGROUND= # transparent background + typeset -g POWERLEVEL9K_{LEFT,RIGHT}_{LEFT,RIGHT}_WHITESPACE= # no surrounding whitespace + typeset -g POWERLEVEL9K_{LEFT,RIGHT}_SUBSEGMENT_SEPARATOR=' ' # separate segments with a space + typeset -g POWERLEVEL9K_{LEFT,RIGHT}_SEGMENT_SEPARATOR= # no end-of-line symbol + + # When set to true, icons appear before content on both sides of the prompt. When set + # to false, icons go after content. If empty or not set, icons go before content in the left + # prompt and after content in the right prompt. + # + # You can also override it for a specific segment: + # + # POWERLEVEL9K_STATUS_ICON_BEFORE_CONTENT=false + # + # Or for a specific segment in specific state: + # + # POWERLEVEL9K_DIR_NOT_WRITABLE_ICON_BEFORE_CONTENT=false + typeset -g POWERLEVEL9K_ICON_BEFORE_CONTENT=true + + # Add an empty line before each prompt. + typeset -g POWERLEVEL9K_PROMPT_ADD_NEWLINE=false + + # Connect left prompt lines with these symbols. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX= + typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_PREFIX= + typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX= + # Connect right prompt lines with these symbols. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_SUFFIX= + typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_SUFFIX= + typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_SUFFIX= + + # The left end of left prompt. + typeset -g POWERLEVEL9K_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL= + # The right end of right prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL= + + # Ruler, a.k.a. the horizontal line before each prompt. If you set it to true, you'll + # probably want to set POWERLEVEL9K_PROMPT_ADD_NEWLINE=false above and + # POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR=' ' below. + typeset -g POWERLEVEL9K_SHOW_RULER=false + typeset -g POWERLEVEL9K_RULER_CHAR='-' # reasonable alternative: '·' + typeset -g POWERLEVEL9K_RULER_FOREGROUND=242 + + # Filler between left and right prompt on the first prompt line. You can set it to '·' or '-' + # to make it easier to see the alignment between left and right prompt and to separate prompt + # from command output. It serves the same purpose as ruler (see above) without increasing + # the number of prompt lines. You'll probably want to set POWERLEVEL9K_SHOW_RULER=false + # if using this. You might also like POWERLEVEL9K_PROMPT_ADD_NEWLINE=false for more compact + # prompt. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR=' ' + if [[ $POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR != ' ' ]]; then + # The color of the filler. + typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_FOREGROUND=242 + # Add a space between the end of left prompt and the filler. + typeset -g POWERLEVEL9K_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL=' ' + # Add a space between the filler and the start of right prompt. + typeset -g POWERLEVEL9K_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL=' ' + # Start filler from the edge of the screen if there are no left segments on the first line. + typeset -g POWERLEVEL9K_EMPTY_LINE_LEFT_PROMPT_FIRST_SEGMENT_END_SYMBOL='%{%}' + # End filler on the edge of the screen if there are no right segments on the first line. + typeset -g POWERLEVEL9K_EMPTY_LINE_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL='%{%}' + fi + + #################################[ os_icon: os identifier ]################################## + # OS identifier color. + typeset -g POWERLEVEL9K_OS_ICON_FOREGROUND= + # Custom icon. + # typeset -g POWERLEVEL9K_OS_ICON_CONTENT_EXPANSION='⭐' + + ################################[ prompt_char: prompt symbol ]################################ + # Green prompt symbol if the last command succeeded. + typeset -g POWERLEVEL9K_PROMPT_CHAR_OK_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=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= + + ##################################[ dir: current directory ]################################## + # Default current directory color. + typeset -g POWERLEVEL9K_DIR_FOREGROUND=31 + # If directory is too long, shorten some of its segments to the shortest possible unique + # prefix. The shortened directory can be tab-completed to the original. + typeset -g POWERLEVEL9K_SHORTEN_STRATEGY=truncate_to_unique + # Replace removed segment suffixes with this symbol. + typeset -g POWERLEVEL9K_SHORTEN_DELIMITER= + # Color of the shortened directory segments. + typeset -g POWERLEVEL9K_DIR_SHORTENED_FOREGROUND=103 + # Color of the anchor directory segments. Anchor segments are never shortened. The first + # segment is always an anchor. + typeset -g POWERLEVEL9K_DIR_ANCHOR_FOREGROUND=39 + # Display anchor directory segments in bold. + typeset -g POWERLEVEL9K_DIR_ANCHOR_BOLD=true + # Don't shorten directories that contain any of these files. They are anchors. + local anchor_files=( + .bzr + .citc + .git + .hg + .node-version + .python-version + .go-version + .ruby-version + .lua-version + .java-version + .perl-version + .php-version + .tool-version + .shorten_folder_marker + .svn + .terraform + CVS + Cargo.toml + composer.json + go.mod + package.json + stack.yaml + ) + typeset -g POWERLEVEL9K_SHORTEN_FOLDER_MARKER="(${(j:|:)anchor_files})" + # If set to "first" ("last"), remove everything before the first (last) subdirectory that contains + # files matching $POWERLEVEL9K_SHORTEN_FOLDER_MARKER. For example, when the current directory is + # /foo/bar/git_repo/nested_git_repo/baz, prompt will display git_repo/nested_git_repo/baz (first) + # or nested_git_repo/baz (last). This assumes that git_repo and nested_git_repo contain markers + # and other directories don't. + # + # Optionally, "first" and "last" can be followed by ":" where 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_FOREGROUND=31 + # typeset -g POWERLEVEL9K_DIR_WORK_SHORTENED_FOREGROUND=103 + # typeset -g POWERLEVEL9K_DIR_WORK_ANCHOR_FOREGROUND=39 + # + # # Styling for WORK_NOT_WRITABLE. + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_FOREGROUND=31 + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_SHORTENED_FOREGROUND=103 + # typeset -g POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_ANCHOR_FOREGROUND=39 + # + # # Styling for WORK_NON_EXISTENT. + # typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_FOREGROUND=31 + # typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_SHORTENED_FOREGROUND=103 + # typeset -g POWERLEVEL9K_DIR_WORK_NON_EXISTENT_ANCHOR_FOREGROUND=39 + # + # If a styling parameter isn't explicitly defined for some class, it falls back to the classless + # parameter. For example, if POWERLEVEL9K_DIR_WORK_NOT_WRITABLE_FOREGROUND is not set, it falls + # back to POWERLEVEL9K_DIR_FOREGROUND. + # + typeset -g POWERLEVEL9K_DIR_CLASSES=() + + # Custom prefix. + # typeset -g POWERLEVEL9K_DIR_PREFIX='%fin ' + + #####################################[ vcs: git status ]###################################### + # Branch icon. Set this parameter to '\uF126 ' for the popular Powerline branch icon. + typeset -g POWERLEVEL9K_VCS_BRANCH_ICON= + + # Untracked files icon. It's really a question mark, your font isn't broken. + # Change the value of this parameter to show a different icon. + typeset -g POWERLEVEL9K_VCS_UNTRACKED_ICON='?' + + # Formatter for Git status. + # + # Example output: master 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 + + if (( $1 )); then + # Styling for up-to-date Git status. + local meta='%f' # default foreground + local clean='%76F' # green foreground + local modified='%178F' # yellow foreground + local untracked='%39F' # blue foreground + local conflicted='%196F' # red foreground + else + # Styling for incomplete and stale Git status. + local meta='%244F' # grey foreground + local clean='%244F' # grey foreground + local modified='%244F' # grey foreground + local untracked='%244F' # grey foreground + local conflicted='%244F' # grey foreground + fi + + local res + + 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(1)))+${my_git_format}}' + typeset -g POWERLEVEL9K_VCS_LOADING_CONTENT_EXPANSION='${$((my_git_formatter(0)))+${my_git_format}}' + # Enable counters for staged, unstaged, etc. + typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED,CONFLICTED,COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=-1 + + # Icon color. + typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_COLOR=76 + typeset -g POWERLEVEL9K_VCS_LOADING_VISUAL_IDENTIFIER_COLOR=244 + # Custom icon. + typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_EXPANSION= + # Custom prefix. + # typeset -g POWERLEVEL9K_VCS_PREFIX='%fon ' + + # Show status of repositories of these types. You can add svn and/or hg if you are + # using them. If you do, your prompt may become slow even when your current directory + # isn't in an svn or hg reposotiry. + typeset -g POWERLEVEL9K_VCS_BACKENDS=(git) + + # These settings are used for repositories other than Git or when gitstatusd fails and + # Powerlevel10k has to fall back to using vcs_info. + typeset -g POWERLEVEL9K_VCS_CLEAN_FOREGROUND=76 + typeset -g POWERLEVEL9K_VCS_UNTRACKED_FOREGROUND=76 + typeset -g POWERLEVEL9K_VCS_MODIFIED_FOREGROUND=178 + + ##########################[ status: exit code of the last command ]########################### + # Enable OK_PIPE, ERROR_PIPE and ERROR_SIGNAL status states to allow us to enable, disable and + # style them independently from the regular OK and ERROR state. + typeset -g POWERLEVEL9K_STATUS_EXTENDED_STATES=true + + # Status on success. No content, just an icon. No need to show it if prompt_char is enabled as + # it will signify success by turning green. + typeset -g POWERLEVEL9K_STATUS_OK=false + typeset -g POWERLEVEL9K_STATUS_OK_FOREGROUND=70 + typeset -g POWERLEVEL9K_STATUS_OK_VISUAL_IDENTIFIER_EXPANSION='ok' + + # Status when some part of a pipe command fails but the overall exit status is zero. It may look + # like this: 1|0. + typeset -g POWERLEVEL9K_STATUS_OK_PIPE=true + typeset -g POWERLEVEL9K_STATUS_OK_PIPE_FOREGROUND=70 + typeset -g POWERLEVEL9K_STATUS_OK_PIPE_VISUAL_IDENTIFIER_EXPANSION='ok' + + # Status when it's just an error code (e.g., '1'). No need to show it if prompt_char is enabled as + # it will signify error by turning red. + typeset -g POWERLEVEL9K_STATUS_ERROR=false + typeset -g POWERLEVEL9K_STATUS_ERROR_FOREGROUND=160 + typeset -g POWERLEVEL9K_STATUS_ERROR_VISUAL_IDENTIFIER_EXPANSION='err' + + # Status when the last command was terminated by a signal. + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL=true + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_FOREGROUND=160 + # Use terse signal names: "INT" instead of "SIGINT(2)". + typeset -g POWERLEVEL9K_STATUS_VERBOSE_SIGNAME=false + typeset -g POWERLEVEL9K_STATUS_ERROR_SIGNAL_VISUAL_IDENTIFIER_EXPANSION= + + # Status when some part of a pipe command fails and the overall exit status is also non-zero. + # It may look like this: 1|0. + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE=true + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_FOREGROUND=160 + typeset -g POWERLEVEL9K_STATUS_ERROR_PIPE_VISUAL_IDENTIFIER_EXPANSION='err' + + ###################[ command_execution_time: duration of the last command ]################### + # 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 + # Execution time color. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FOREGROUND=101 + # Duration format: 1d 2h 3m 4s. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_FORMAT='d h m s' + # Custom icon. + typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_VISUAL_IDENTIFIER_EXPANSION= + # Custom prefix. + # typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_PREFIX='%ftook ' + + #######################[ background_jobs: presence of background jobs ]####################### + # Don't show the number of background jobs. + typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VERBOSE=false + # Background jobs color. + typeset -g POWERLEVEL9K_BACKGROUND_JOBS_FOREGROUND=70 + # Custom icon. + # typeset -g POWERLEVEL9K_BACKGROUND_JOBS_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ direnv: direnv status (https://direnv.net/) ]######################## + # Direnv color. + typeset -g POWERLEVEL9K_DIRENV_FOREGROUND=178 + # Custom icon. + # typeset -g POWERLEVEL9K_DIRENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ asdf: asdf version manager (https://github.com/asdf-vm/asdf) ]############### + # Default asdf color. Only used to display tools for which there is no color override (see below). + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_FOREGROUND. + typeset -g POWERLEVEL9K_ASDF_FOREGROUND=66 + + # There are four parameters that can be used to hide asdf tools. Each parameter describes + # conditions under which a tool gets hidden. Parameters can hide tools but not unhide them. If at + # least one parameter decides to hide a tool, that tool gets hidden. If no parameter decides to + # hide a tool, it gets shown. + # + # Special note on the difference between POWERLEVEL9K_ASDF_SOURCES and + # POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW. Consider the effect of the following commands: + # + # asdf local python 3.8.1 + # asdf global python 3.8.1 + # + # After running both commands the current python version is 3.8.1 and its source is "local" as + # it takes precedence over "global". If POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW is set to false, + # it'll hide python version in this case because 3.8.1 is the same as the global version. + # POWERLEVEL9K_ASDF_SOURCES will hide python version only if the value of this parameter doesn't + # contain "local". + + # Hide tool versions that don't come from one of these sources. + # + # Available sources: + # + # - shell `asdf current` says "set by ASDF_${TOOL}_VERSION environment variable" + # - local `asdf current` says "set by /some/not/home/directory/file" + # - global `asdf current` says "set by /home/username/file" + # + # Note: If this parameter is set to (shell local global), it won't hide tools. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SOURCES. + typeset -g POWERLEVEL9K_ASDF_SOURCES=(shell local global) + + # If set to false, hide tool versions that are the same as global. + # + # Note: The name of this parameter doesn't reflect its meaning at all. + # Note: If this parameter is set to true, it won't hide tools. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_PROMPT_ALWAYS_SHOW. + typeset -g POWERLEVEL9K_ASDF_PROMPT_ALWAYS_SHOW=false + + # If set to false, hide tool versions that are equal to "system". + # + # Note: If this parameter is set to true, it won't hide tools. + # Tip: Override this parameter for ${TOOL} with POWERLEVEL9K_ASDF_${TOOL}_SHOW_SYSTEM. + typeset -g POWERLEVEL9K_ASDF_SHOW_SYSTEM=true + + # If set to non-empty value, hide tools unless there is a file matching the specified file pattern + # in the current directory, or its parent 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=168 + # typeset -g POWERLEVEL9K_ASDF_RUBY_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_RUBY_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Python version from asdf. + typeset -g POWERLEVEL9K_ASDF_PYTHON_FOREGROUND=37 + # typeset -g POWERLEVEL9K_ASDF_PYTHON_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_PYTHON_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Go version from asdf. + typeset -g POWERLEVEL9K_ASDF_GOLANG_FOREGROUND=37 + # typeset -g POWERLEVEL9K_ASDF_GOLANG_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_GOLANG_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Node.js version from asdf. + typeset -g POWERLEVEL9K_ASDF_NODEJS_FOREGROUND=70 + # typeset -g POWERLEVEL9K_ASDF_NODEJS_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_NODEJS_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Rust version from asdf. + typeset -g POWERLEVEL9K_ASDF_RUST_FOREGROUND=37 + # typeset -g POWERLEVEL9K_ASDF_RUST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_RUST_SHOW_ON_UPGLOB='*.foo|*.bar' + + # .NET Core version from asdf. + typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_FOREGROUND=134 + # typeset -g POWERLEVEL9K_ASDF_DOTNET_CORE_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_DOTNET_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Flutter version from asdf. + typeset -g POWERLEVEL9K_ASDF_FLUTTER_FOREGROUND=38 + # typeset -g POWERLEVEL9K_ASDF_FLUTTER_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_FLUTTER_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Lua version from asdf. + typeset -g POWERLEVEL9K_ASDF_LUA_FOREGROUND=32 + # typeset -g POWERLEVEL9K_ASDF_LUA_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_LUA_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Java version from asdf. + typeset -g POWERLEVEL9K_ASDF_JAVA_FOREGROUND=32 + # typeset -g POWERLEVEL9K_ASDF_JAVA_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_JAVA_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Perl version from asdf. + typeset -g POWERLEVEL9K_ASDF_PERL_FOREGROUND=67 + # typeset -g POWERLEVEL9K_ASDF_PERL_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_PERL_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Erlang version from asdf. + typeset -g POWERLEVEL9K_ASDF_ERLANG_FOREGROUND=125 + # typeset -g POWERLEVEL9K_ASDF_ERLANG_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_ERLANG_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Elixir version from asdf. + typeset -g POWERLEVEL9K_ASDF_ELIXIR_FOREGROUND=129 + # typeset -g POWERLEVEL9K_ASDF_ELIXIR_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_ELIXIR_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Postgres version from asdf. + typeset -g POWERLEVEL9K_ASDF_POSTGRES_FOREGROUND=31 + # typeset -g POWERLEVEL9K_ASDF_POSTGRES_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_POSTGRES_SHOW_ON_UPGLOB='*.foo|*.bar' + + # PHP version from asdf. + typeset -g POWERLEVEL9K_ASDF_PHP_FOREGROUND=99 + # typeset -g POWERLEVEL9K_ASDF_PHP_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_PHP_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Haskell version from asdf. + typeset -g POWERLEVEL9K_ASDF_HASKELL_FOREGROUND=172 + # typeset -g POWERLEVEL9K_ASDF_HASKELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_ASDF_HASKELL_SHOW_ON_UPGLOB='*.foo|*.bar' + + # Julia version from asdf. + typeset -g POWERLEVEL9K_ASDF_JULIA_FOREGROUND=70 + # 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=39 + # Hide NordVPN connection indicator when not connected. + typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_CONTENT_EXPANSION= + typeset -g POWERLEVEL9K_NORDVPN_{DISCONNECTED,CONNECTING,DISCONNECTING}_VISUAL_IDENTIFIER_EXPANSION= + # Custom icon. + # typeset -g POWERLEVEL9K_NORDVPN_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #################[ ranger: ranger shell (https://github.com/ranger/ranger) ]################## + # Ranger shell color. + typeset -g POWERLEVEL9K_RANGER_FOREGROUND=178 + # Custom icon. + # typeset -g POWERLEVEL9K_RANGER_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################[ nnn: nnn shell (https://github.com/jarun/nnn) ]####################### + # Nnn shell color. + typeset -g POWERLEVEL9K_NNN_FOREGROUND=72 + # Custom icon. + # typeset -g POWERLEVEL9K_NNN_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##################[ xplr: xplr shell (https://github.com/sayanarijit/xplr) ]################## + # xplr shell color. + typeset -g POWERLEVEL9K_XPLR_FOREGROUND=72 + # 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=34 + # Custom icon. + # typeset -g POWERLEVEL9K_VIM_SHELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######[ midnight_commander: midnight commander shell (https://midnight-commander.org/) ]###### + # Midnight Commander shell color. + typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_FOREGROUND=178 + # Custom icon. + # typeset -g POWERLEVEL9K_MIDNIGHT_COMMANDER_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ nix_shell: nix shell (https://nixos.org/nixos/nix-pills/developing-with-nix-shell.html) ]## + # Nix shell color. + typeset -g POWERLEVEL9K_NIX_SHELL_FOREGROUND=74 + + # Tip: If you want to see just the icon without "pure" and "impure", uncomment the next line. + # typeset -g POWERLEVEL9K_NIX_SHELL_CONTENT_EXPANSION= + + # Custom icon. + # typeset -g POWERLEVEL9K_NIX_SHELL_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##################################[ disk_usage: disk usage ]################################## + # Colors for different levels of disk usage. + typeset -g POWERLEVEL9K_DISK_USAGE_NORMAL_FOREGROUND=35 + typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_FOREGROUND=220 + typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_FOREGROUND=160 + # Thresholds for different levels of disk usage (percentage points). + typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL=90 + typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_LEVEL=95 + # If set to true, hide disk usage when below $POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL percent. + typeset -g POWERLEVEL9K_DISK_USAGE_ONLY_WARNING=false + # Custom icon. + # typeset -g POWERLEVEL9K_DISK_USAGE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################################[ ram: free RAM ]####################################### + # RAM color. + typeset -g POWERLEVEL9K_RAM_FOREGROUND=66 + # Custom icon. + # typeset -g POWERLEVEL9K_RAM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #####################################[ swap: used swap ]###################################### + # Swap color. + typeset -g POWERLEVEL9K_SWAP_FOREGROUND=96 + # Custom icon. + # typeset -g POWERLEVEL9K_SWAP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ######################################[ load: CPU load ]###################################### + # Show average CPU load over this many last minutes. Valid values are 1, 5 and 15. + typeset -g POWERLEVEL9K_LOAD_WHICH=5 + # Load color when load is under 50%. + typeset -g POWERLEVEL9K_LOAD_NORMAL_FOREGROUND=66 + # Load color when load is between 50% and 70%. + typeset -g POWERLEVEL9K_LOAD_WARNING_FOREGROUND=178 + # Load color when load is over 70%. + typeset -g POWERLEVEL9K_LOAD_CRITICAL_FOREGROUND=166 + # Custom icon. + # typeset -g POWERLEVEL9K_LOAD_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################[ todo: todo items (https://github.com/todotxt/todo.txt-cli) ]################ + # Todo color. + typeset -g POWERLEVEL9K_TODO_FOREGROUND=110 + # Hide todo when the total number of tasks is zero. + typeset -g POWERLEVEL9K_TODO_HIDE_ZERO_TOTAL=true + # Hide todo when the number of tasks after filtering is zero. + typeset -g POWERLEVEL9K_TODO_HIDE_ZERO_FILTERED=false + + # Todo format. The following parameters are available within the expansion. + # + # - P9K_TODO_TOTAL_TASK_COUNT The total number of tasks. + # - P9K_TODO_FILTERED_TASK_COUNT The number of tasks after filtering. + # + # These variables correspond to the last line of the output of `todo.sh -p ls`: + # + # TODO: 24 of 42 tasks shown + # + # Here 24 is P9K_TODO_FILTERED_TASK_COUNT and 42 is P9K_TODO_TOTAL_TASK_COUNT. + # + # typeset -g POWERLEVEL9K_TODO_CONTENT_EXPANSION='$P9K_TODO_FILTERED_TASK_COUNT' + + # Custom icon. + # typeset -g POWERLEVEL9K_TODO_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ timewarrior: timewarrior tracking status (https://timewarrior.net/) ]############ + # Timewarrior color. + typeset -g POWERLEVEL9K_TIMEWARRIOR_FOREGROUND=110 + # If the tracked task is longer than 24 characters, truncate and append "..". + # Tip: To always display tasks without truncation, delete the following parameter. + # Tip: To hide task names and display just the icon when time tracking is enabled, set the + # value of the following parameter to "". + typeset -g POWERLEVEL9K_TIMEWARRIOR_CONTENT_EXPANSION='${P9K_CONTENT:0:24}${${P9K_CONTENT:24}:+..}' + + # Custom icon. + # typeset -g POWERLEVEL9K_TIMEWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############[ taskwarrior: taskwarrior task count (https://taskwarrior.org/) ]############## + # Taskwarrior color. + typeset -g POWERLEVEL9K_TASKWARRIOR_FOREGROUND=74 + + # Taskwarrior segment format. The following parameters are available within the expansion. + # + # - P9K_TASKWARRIOR_PENDING_COUNT The number of pending tasks: `task +PENDING count`. + # - P9K_TASKWARRIOR_OVERDUE_COUNT The number of overdue tasks: `task +OVERDUE count`. + # + # Zero values are represented as empty parameters. + # + # The default format: + # + # '${P9K_TASKWARRIOR_OVERDUE_COUNT:+"!$P9K_TASKWARRIOR_OVERDUE_COUNT/"}$P9K_TASKWARRIOR_PENDING_COUNT' + # + # typeset -g POWERLEVEL9K_TASKWARRIOR_CONTENT_EXPANSION='$P9K_TASKWARRIOR_PENDING_COUNT' + + # Custom icon. + # typeset -g POWERLEVEL9K_TASKWARRIOR_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##################################[ context: user@hostname ]################################## + # Context color when running with privileges. + typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND=178 + # Context color in SSH without privileges. + typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_FOREGROUND=180 + # Default context color (no privileges, no SSH). + typeset -g POWERLEVEL9K_CONTEXT_FOREGROUND=180 + + # Context format when running with privileges: bold user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE='%B%n@%m' + # Context format when in SSH without privileges: user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_TEMPLATE='%n@%m' + # Default context format (no privileges, no SSH): user@hostname. + typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE='%n@%m' + + # Don't show context unless running with privileges or in SSH. + # Tip: Remove the next line to always show context. + typeset -g POWERLEVEL9K_CONTEXT_{DEFAULT,SUDO}_{CONTENT,VISUAL_IDENTIFIER}_EXPANSION= + + # Custom icon. + # typeset -g POWERLEVEL9K_CONTEXT_VISUAL_IDENTIFIER_EXPANSION='⭐' + # Custom prefix. + # typeset -g POWERLEVEL9K_CONTEXT_PREFIX='%fwith ' + + ###[ virtualenv: python virtual environment (https://docs.python.org/3/library/venv.html) ]### + # Python virtual environment color. + typeset -g POWERLEVEL9K_VIRTUALENV_FOREGROUND=37 + # Don't show Python version next to the virtual environment name. + typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_PYTHON_VERSION=false + # 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=37 + + # 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=37 + # Hide python version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_PYENV_SOURCES=(shell local global) + # If set to false, hide python version if it's the same as global: + # $(pyenv version-name) == $(pyenv global). + typeset -g POWERLEVEL9K_PYENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide python version if it's equal to "system". + typeset -g POWERLEVEL9K_PYENV_SHOW_SYSTEM=true + + # Pyenv segment format. The following parameters are available within the expansion. + # + # - P9K_CONTENT Current pyenv environment (pyenv version-name). + # - P9K_PYENV_PYTHON_VERSION Current python version (python --version). + # + # The default format has the following logic: + # + # 1. Display 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=37 + # Hide go version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_GOENV_SOURCES=(shell local global) + # If set to false, hide go version if it's the same as global: + # $(goenv version-name) == $(goenv global). + typeset -g POWERLEVEL9K_GOENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide go version if it's equal to "system". + typeset -g POWERLEVEL9K_GOENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_GOENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ nodenv: node.js version from nodenv (https://github.com/nodenv/nodenv) ]########## + # Nodenv color. + typeset -g POWERLEVEL9K_NODENV_FOREGROUND=70 + # Hide node version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_NODENV_SOURCES=(shell local global) + # If set to false, hide node version if it's the same as global: + # $(nodenv version-name) == $(nodenv global). + typeset -g POWERLEVEL9K_NODENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide node version if it's equal to "system". + typeset -g POWERLEVEL9K_NODENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_NODENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############[ nvm: node.js version from nvm (https://github.com/nvm-sh/nvm) ]############### + # Nvm color. + typeset -g POWERLEVEL9K_NVM_FOREGROUND=70 + # Custom icon. + # typeset -g POWERLEVEL9K_NVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ############[ nodeenv: node.js environment (https://github.com/ekalinin/nodeenv) ]############ + # Nodeenv color. + typeset -g POWERLEVEL9K_NODEENV_FOREGROUND=70 + # Don't show Node version next to the environment name. + typeset -g POWERLEVEL9K_NODEENV_SHOW_NODE_VERSION=false + # Separate environment name from Node version only with a space. + typeset -g POWERLEVEL9K_NODEENV_{LEFT,RIGHT}_DELIMITER= + # Custom icon. + # typeset -g POWERLEVEL9K_NODEENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##############################[ node_version: node.js version ]############################### + # Node version color. + typeset -g POWERLEVEL9K_NODE_VERSION_FOREGROUND=70 + # Show node version only when in a directory tree containing package.json. + typeset -g POWERLEVEL9K_NODE_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_NODE_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ go_version: go version (https://golang.org) ]######################## + # Go version color. + typeset -g POWERLEVEL9K_GO_VERSION_FOREGROUND=37 + # Show go version only when in a go project subdirectory. + typeset -g POWERLEVEL9K_GO_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_GO_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #################[ rust_version: rustc version (https://www.rust-lang.org) ]################## + # Rust version color. + typeset -g POWERLEVEL9K_RUST_VERSION_FOREGROUND=37 + # Show rust version only when in a rust project subdirectory. + typeset -g POWERLEVEL9K_RUST_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_RUST_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ dotnet_version: .NET version (https://dotnet.microsoft.com) ]################ + # .NET version color. + typeset -g POWERLEVEL9K_DOTNET_VERSION_FOREGROUND=134 + # Show .NET version only when in a .NET project subdirectory. + typeset -g POWERLEVEL9K_DOTNET_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_DOTNET_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #####################[ php_version: php version (https://www.php.net/) ]###################### + # PHP version color. + typeset -g POWERLEVEL9K_PHP_VERSION_FOREGROUND=99 + # Show PHP version only when in a PHP project subdirectory. + typeset -g POWERLEVEL9K_PHP_VERSION_PROJECT_ONLY=true + # Custom icon. + # typeset -g POWERLEVEL9K_PHP_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ laravel_version: laravel php framework version (https://laravel.com/) ]########### + # Laravel version color. + typeset -g POWERLEVEL9K_LARAVEL_VERSION_FOREGROUND=161 + # Custom icon. + # typeset -g POWERLEVEL9K_LARAVEL_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ####################[ java_version: java version (https://www.java.com/) ]#################### + # Java version color. + typeset -g POWERLEVEL9K_JAVA_VERSION_FOREGROUND=32 + # Show java version only when in a java project subdirectory. + typeset -g POWERLEVEL9K_JAVA_VERSION_PROJECT_ONLY=true + # Show brief version. + typeset -g POWERLEVEL9K_JAVA_VERSION_FULL=false + # Custom icon. + # typeset -g POWERLEVEL9K_JAVA_VERSION_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###[ package: name@version from package.json (https://docs.npmjs.com/files/package.json) ]#### + # Package color. + typeset -g POWERLEVEL9K_PACKAGE_FOREGROUND=117 + # Package format. The following parameters are available within the expansion. + # + # - P9K_PACKAGE_NAME The value of `name` field in package.json. + # - P9K_PACKAGE_VERSION The value of `version` field in package.json. + # + # typeset -g POWERLEVEL9K_PACKAGE_CONTENT_EXPANSION='${P9K_PACKAGE_NAME//\%/%%}@${P9K_PACKAGE_VERSION//\%/%%}' + # Custom icon. + # typeset -g POWERLEVEL9K_PACKAGE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #############[ rbenv: ruby version from rbenv (https://github.com/rbenv/rbenv) ]############## + # Rbenv color. + typeset -g POWERLEVEL9K_RBENV_FOREGROUND=168 + # Hide ruby version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_RBENV_SOURCES=(shell local global) + # If set to false, hide ruby version if it's the same as global: + # $(rbenv version-name) == $(rbenv global). + typeset -g POWERLEVEL9K_RBENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide ruby version if it's equal to "system". + typeset -g POWERLEVEL9K_RBENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_RBENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######################[ rvm: ruby version from rvm (https://rvm.io) ]######################## + # Rvm color. + typeset -g POWERLEVEL9K_RVM_FOREGROUND=168 + # Don't show @gemset at the end. + typeset -g POWERLEVEL9K_RVM_SHOW_GEMSET=false + # Don't show ruby- at the front. + typeset -g POWERLEVEL9K_RVM_SHOW_PREFIX=false + # Custom icon. + # typeset -g POWERLEVEL9K_RVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ fvm: flutter version management (https://github.com/leoafarias/fvm) ]############ + # Fvm color. + typeset -g POWERLEVEL9K_FVM_FOREGROUND=38 + # Custom icon. + # typeset -g POWERLEVEL9K_FVM_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ luaenv: lua version from luaenv (https://github.com/cehoffman/luaenv) ]########### + # Lua color. + typeset -g POWERLEVEL9K_LUAENV_FOREGROUND=32 + # Hide lua version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_LUAENV_SOURCES=(shell local global) + # If set to false, hide lua version if it's the same as global: + # $(luaenv version-name) == $(luaenv global). + typeset -g POWERLEVEL9K_LUAENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide lua version if it's equal to "system". + typeset -g POWERLEVEL9K_LUAENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_LUAENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###############[ jenv: java version from jenv (https://github.com/jenv/jenv) ]################ + # Java color. + typeset -g POWERLEVEL9K_JENV_FOREGROUND=32 + # Hide java version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_JENV_SOURCES=(shell local global) + # If set to false, hide java version if it's the same as global: + # $(jenv version-name) == $(jenv global). + typeset -g POWERLEVEL9K_JENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide java version if it's equal to "system". + typeset -g POWERLEVEL9K_JENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_JENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ###########[ plenv: perl version from plenv (https://github.com/tokuhirom/plenv) ]############ + # Perl color. + typeset -g POWERLEVEL9K_PLENV_FOREGROUND=67 + # Hide perl version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_PLENV_SOURCES=(shell local global) + # If set to false, hide perl version if it's the same as global: + # $(plenv version-name) == $(plenv global). + typeset -g POWERLEVEL9K_PLENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide perl version if it's equal to "system". + typeset -g POWERLEVEL9K_PLENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_PLENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ############[ phpenv: php version from phpenv (https://github.com/phpenv/phpenv) ]############ + # PHP color. + typeset -g POWERLEVEL9K_PHPENV_FOREGROUND=99 + # Hide php version if it doesn't come from one of these sources. + typeset -g POWERLEVEL9K_PHPENV_SOURCES=(shell local global) + # If set to false, hide php version if it's the same as global: + # $(phpenv version-name) == $(phpenv global). + typeset -g POWERLEVEL9K_PHPENV_PROMPT_ALWAYS_SHOW=false + # If set to false, hide php version if it's equal to "system". + typeset -g POWERLEVEL9K_PHPENV_SHOW_SYSTEM=true + # Custom icon. + # typeset -g POWERLEVEL9K_PHPENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #######[ scalaenv: scala version from scalaenv (https://github.com/scalaenv/scalaenv) ]####### + # Scala color. + typeset -g POWERLEVEL9K_SCALAENV_FOREGROUND=160 + # 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=172 + # Hide haskell version if it doesn't come from one of these sources. + # + # shell: version is set by STACK_YAML + # local: version is set by stack.yaml up the directory tree + # global: version is set by the implicit global project (~/.stack/global-project/stack.yaml) + typeset -g POWERLEVEL9K_HASKELL_STACK_SOURCES=(shell local) + # If set to false, hide haskell version if it's the same as in the implicit global project. + typeset -g POWERLEVEL9K_HASKELL_STACK_ALWAYS_SHOW=true + # Custom icon. + # typeset -g POWERLEVEL9K_HASKELL_STACK_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #############[ kubecontext: current kubernetes context (https://kubernetes.io/) ]############# + # Show kubecontext only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show kubecontext. + typeset -g POWERLEVEL9K_KUBECONTEXT_SHOW_ON_COMMAND='kubectl|helm|kubens|kubectx|oc|istioctl|kogito|k9s|helmfile|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=28 + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_KUBECONTEXT_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' + typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=( + # '*prod*' PROD # These values are examples that are unlikely + # '*test*' TEST # to match your needs. Customize them as needed. + '*' DEFAULT) + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_FOREGROUND=134 + # typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Use POWERLEVEL9K_KUBECONTEXT_CONTENT_EXPANSION to specify the content displayed by kubecontext + # segment. Parameter expansions are very flexible and fast, too. See reference: + # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion. + # + # Within the expansion the following parameters are always available: + # + # - P9K_CONTENT The content that would've been displayed if there was no content + # expansion defined. + # - P9K_KUBECONTEXT_NAME The current context's name. Corresponds to column NAME in the + # output of `kubectl config get-contexts`. + # - P9K_KUBECONTEXT_CLUSTER The current context's cluster. Corresponds to column CLUSTER in the + # output of `kubectl config get-contexts`. + # - P9K_KUBECONTEXT_NAMESPACE The current context's namespace. Corresponds to column NAMESPACE + # in the output of `kubectl config get-contexts`. If there is no + # namespace, the parameter is set to "default". + # - P9K_KUBECONTEXT_USER The current context's user. Corresponds to column AUTHINFO in the + # output of `kubectl config get-contexts`. + # + # If the context points to Google Kubernetes Engine (GKE) or Elastic Kubernetes Service (EKS), + # the following extra parameters are available: + # + # - P9K_KUBECONTEXT_CLOUD_NAME Either "gke" or "eks". + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT Account/project ID. + # - P9K_KUBECONTEXT_CLOUD_ZONE Availability zone. + # - P9K_KUBECONTEXT_CLOUD_CLUSTER Cluster. + # + # P9K_KUBECONTEXT_CLOUD_* parameters are derived from P9K_KUBECONTEXT_CLUSTER. For example, + # if P9K_KUBECONTEXT_CLUSTER is "gke_my-account_us-east1-a_my-cluster-01": + # + # - P9K_KUBECONTEXT_CLOUD_NAME=gke + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=my-account + # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east1-a + # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01 + # + # If P9K_KUBECONTEXT_CLUSTER is "arn:aws:eks:us-east-1:123456789012:cluster/my-cluster-01": + # + # - P9K_KUBECONTEXT_CLOUD_NAME=eks + # - P9K_KUBECONTEXT_CLOUD_ACCOUNT=123456789012 + # - P9K_KUBECONTEXT_CLOUD_ZONE=us-east-1 + # - P9K_KUBECONTEXT_CLOUD_CLUSTER=my-cluster-01 + typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION= + # Show P9K_KUBECONTEXT_CLOUD_CLUSTER if it's not empty and fall back to P9K_KUBECONTEXT_NAME. + POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${P9K_KUBECONTEXT_CLOUD_CLUSTER:-${P9K_KUBECONTEXT_NAME}}' + # Append the current context's namespace if it's not "default". + POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${${:-/$P9K_KUBECONTEXT_NAMESPACE}:#/default}' + + # Custom prefix. + # typeset -g POWERLEVEL9K_KUBECONTEXT_PREFIX='%fat ' + + ################[ terraform: terraform workspace (https://www.terraform.io) ]################# + # 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=28 + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_VISUAL_IDENTIFIER_EXPANSION='⭐' + # typeset -g POWERLEVEL9K_TERRAFORM_TEST_CONTENT_EXPANSION='> ${P9K_CONTENT} <' + typeset -g POWERLEVEL9K_TERRAFORM_CLASSES=( + # '*prod*' PROD # These values are examples that are unlikely + # '*test*' TEST # to match your needs. Customize them as needed. + '*' OTHER) + typeset -g POWERLEVEL9K_TERRAFORM_OTHER_FOREGROUND=38 + # typeset -g POWERLEVEL9K_TERRAFORM_OTHER_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #[ aws: aws profile (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) ]# + # Show aws only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show aws. + typeset -g POWERLEVEL9K_AWS_SHOW_ON_COMMAND='aws|awless|terraform|pulumi|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=208 + # 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=70 + # Custom icon. + # typeset -g POWERLEVEL9K_AWS_EB_ENV_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ azure: azure account name (https://docs.microsoft.com/en-us/cli/azure) ]########## + # Show azure only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show azure. + typeset -g POWERLEVEL9K_AZURE_SHOW_ON_COMMAND='az|terraform|pulumi|terragrunt' + # Azure account name color. + typeset -g POWERLEVEL9K_AZURE_FOREGROUND=32 + # Custom icon. + # typeset -g POWERLEVEL9K_AZURE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ##########[ gcloud: google cloud account and project (https://cloud.google.com/) ]########### + # Show gcloud only when the the command you are typing invokes one of these tools. + # Tip: Remove the next line to always show gcloud. + typeset -g POWERLEVEL9K_GCLOUD_SHOW_ON_COMMAND='gcloud|gcs' + # Google cloud color. + typeset -g POWERLEVEL9K_GCLOUD_FOREGROUND=32 + + # Google cloud format. Change the value of POWERLEVEL9K_GCLOUD_PARTIAL_CONTENT_EXPANSION and/or + # POWERLEVEL9K_GCLOUD_COMPLETE_CONTENT_EXPANSION if the default is too verbose or not informative + # enough. You can use the following parameters in the expansions. Each of them corresponds to the + # output of `gcloud` tool. + # + # Parameter | Source + # -------------------------|-------------------------------------------------------------------- + # P9K_GCLOUD_CONFIGURATION | gcloud config configurations list --format='value(name)' + # P9K_GCLOUD_ACCOUNT | gcloud config get-value account + # P9K_GCLOUD_PROJECT_ID | gcloud config get-value project + # P9K_GCLOUD_PROJECT_NAME | gcloud projects describe $P9K_GCLOUD_PROJECT_ID --format='value(name)' + # + # Note: ${VARIABLE//\%/%%} expands to ${VARIABLE} with all 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=32 + # typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Use POWERLEVEL9K_GOOGLE_APP_CRED_CONTENT_EXPANSION to specify the content displayed by + # google_app_cred segment. Parameter expansions are very flexible and fast, too. See reference: + # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion. + # + # You can use the following parameters in the expansion. Each of them corresponds to one of the + # fields in the JSON file pointed to by GOOGLE_APPLICATION_CREDENTIALS. + # + # Parameter | JSON key file field + # ---------------------------------+--------------- + # P9K_GOOGLE_APP_CRED_TYPE | type + # P9K_GOOGLE_APP_CRED_PROJECT_ID | project_id + # P9K_GOOGLE_APP_CRED_CLIENT_EMAIL | client_email + # + # Note: ${VARIABLE//\%/%%} expands to ${VARIABLE} with all occurrences of '%' replaced by '%%'. + typeset -g POWERLEVEL9K_GOOGLE_APP_CRED_DEFAULT_CONTENT_EXPANSION='${P9K_GOOGLE_APP_CRED_PROJECT_ID//\%/%%}' + + ###############################[ public_ip: public IP address ]############################### + # Public IP color. + typeset -g POWERLEVEL9K_PUBLIC_IP_FOREGROUND=94 + # Custom icon. + # typeset -g POWERLEVEL9K_PUBLIC_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ########################[ vpn_ip: virtual private network indicator ]######################### + # VPN IP color. + typeset -g POWERLEVEL9K_VPN_IP_FOREGROUND=81 + # When on VPN, show just an icon without the IP address. + # Tip: To display the private IP address when on VPN, remove the next line. + typeset -g POWERLEVEL9K_VPN_IP_CONTENT_EXPANSION= + # Regular expression for the VPN network interface. Run `ifconfig` or `ip -4 a show` while on VPN + # to see the name of the interface. + typeset -g POWERLEVEL9K_VPN_IP_INTERFACE='(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_FOREGROUND=38 + # The following parameters are accessible within the expansion: + # + # Parameter | Meaning + # ----------------------+------------------------------------------- + # P9K_IP_IP | IP address + # P9K_IP_INTERFACE | network interface + # P9K_IP_RX_BYTES | total number of bytes received + # P9K_IP_TX_BYTES | total number of bytes sent + # P9K_IP_RX_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_IP${P9K_IP_RX_RATE:+ %70F<$P9K_IP_RX_RATE}${P9K_IP_TX_RATE:+ %215F>$P9K_IP_TX_RATE}' + # Show information for the first network interface whose name matches this regular expression. + # Run `ifconfig` or `ip -4 a show` to see the names of all network interfaces. + typeset -g POWERLEVEL9K_IP_INTERFACE='[ew].*' + # Custom icon. + # typeset -g POWERLEVEL9K_IP_VISUAL_IDENTIFIER_EXPANSION='⭐' + + #########################[ proxy: system-wide http/https/ftp proxy ]########################## + # Proxy color. + typeset -g POWERLEVEL9K_PROXY_FOREGROUND=68 + # Custom icon. + # typeset -g POWERLEVEL9K_PROXY_VISUAL_IDENTIFIER_EXPANSION='⭐' + + ################################[ battery: internal battery ]################################# + # Show battery in red when it's below this level and not connected to power supply. + typeset -g POWERLEVEL9K_BATTERY_LOW_THRESHOLD=20 + typeset -g POWERLEVEL9K_BATTERY_LOW_FOREGROUND=160 + # Show battery in green when it's charging or fully charged. + typeset -g POWERLEVEL9K_BATTERY_{CHARGING,CHARGED}_FOREGROUND=70 + # Show battery in yellow when it's discharging. + typeset -g POWERLEVEL9K_BATTERY_DISCONNECTED_FOREGROUND=178 + # Battery pictograms going from low to high level of charge. + typeset -g POWERLEVEL9K_BATTERY_STAGES=('battery') + # Don't show the remaining time to charge/discharge. + typeset -g POWERLEVEL9K_BATTERY_VERBOSE=false + + #####################################[ wifi: wifi speed ]##################################### + # WiFi color. + typeset -g POWERLEVEL9K_WIFI_FOREGROUND=68 + # Custom icon. + # typeset -g POWERLEVEL9K_WIFI_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Use different colors and icons depending on signal strength ($P9K_WIFI_BARS). + # + # # Wifi colors and icons for different signal strength levels (low to high). + # typeset -g my_wifi_fg=(68 68 68 68 68) # <-- change these values + # typeset -g my_wifi_icon=('WiFi' 'WiFi' 'WiFi' 'WiFi' 'WiFi') # <-- change these values + # + # typeset -g POWERLEVEL9K_WIFI_CONTENT_EXPANSION='%F{${my_wifi_fg[P9K_WIFI_BARS+1]}}$P9K_WIFI_LAST_TX_RATE Mbps' + # typeset -g POWERLEVEL9K_WIFI_VISUAL_IDENTIFIER_EXPANSION='%F{${my_wifi_fg[P9K_WIFI_BARS+1]}}${my_wifi_icon[P9K_WIFI_BARS+1]}' + # + # The following parameters are accessible within the expansions: + # + # Parameter | Meaning + # ----------------------+--------------- + # P9K_WIFI_SSID | service set identifier, a.k.a. network name + # P9K_WIFI_LINK_AUTH | authentication protocol such as "wpa2-psk" or "none"; 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=66 + # Format for the current time: 09:51:02. See `man 3 strftime`. + typeset -g POWERLEVEL9K_TIME_FORMAT='%D{%H:%M:%S}' + # If set to true, time will update when you hit enter. This way prompts for the past + # commands will contain the start times of their commands as opposed to the default + # behavior where they contain the end times of their preceding commands. + typeset -g POWERLEVEL9K_TIME_UPDATE_ON_COMMAND=false + # Custom icon. + typeset -g POWERLEVEL9K_TIME_VISUAL_IDENTIFIER_EXPANSION= + # Custom prefix. + # typeset -g POWERLEVEL9K_TIME_PREFIX='%fat ' + + # Example of a user-defined prompt segment. Function prompt_example will be called on every + # prompt if `example` prompt segment is added to POWERLEVEL9K_LEFT_PROMPT_ELEMENTS or + # POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS. It displays an icon and orange text greeting the user. + # + # Type `p10k help segment` for documentation and a more sophisticated example. + function prompt_example() { + p10k segment -f 208 -i '*' -t 'hello, %n' + } + + # User-defined prompt segments may optionally provide an instant_prompt_* function. Its job + # is to generate the prompt segment for display in instant prompt. See + # https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt. + # + # Powerlevel10k will call instant_prompt_* at the same time as the regular prompt_* function + # and will record all `p10k segment` calls it makes. When displaying instant prompt, Powerlevel10k + # will replay these calls without actually calling instant_prompt_*. It is imperative that + # instant_prompt_* always makes the same `p10k segment` calls regardless of environment. If this + # rule is not observed, the content of instant prompt will be incorrect. + # + # Usually, you should either not define instant_prompt_* or simply call prompt_* from it. If + # instant_prompt_* is not defined for a segment, the segment won't be shown in instant prompt. + function instant_prompt_example() { + # Since prompt_example always makes the same `p10k segment` calls, we can call it from + # instant_prompt_example. This will give us the same `example` prompt segment in the instant + # and regular prompts. + prompt_example + } + + # User-defined prompt segments can be customized the same way as built-in segments. + # typeset -g POWERLEVEL9K_EXAMPLE_FOREGROUND=208 + # typeset -g POWERLEVEL9K_EXAMPLE_VISUAL_IDENTIFIER_EXPANSION='⭐' + + # Transient prompt works similarly to the builtin transient_rprompt option. It trims down prompt + # when accepting a command line. Supported values: + # + # - off: Don't change prompt when accepting a command line. + # - always: Trim down prompt when accepting a command line. + # - same-dir: Trim down prompt when accepting a command line unless this is the first command + # typed after changing current working directory. + typeset -g POWERLEVEL9K_TRANSIENT_PROMPT=off + + # Instant prompt mode. + # + # - off: Disable instant prompt. Choose this if you've tried instant prompt and found + # it incompatible with your zsh configuration files. + # - quiet: Enable instant prompt and don't print warnings when detecting console output + # during zsh initialization. Choose this if you've read and understood + # https://github.com/romkatv/powerlevel10k/blob/master/README.md#instant-prompt. + # - verbose: Enable instant prompt and print a warning when detecting console output during + # zsh initialization. Choose this if you've never tried instant prompt, haven't + # seen the warning, or if you are unsure what this all means. + typeset -g POWERLEVEL9K_INSTANT_PROMPT=verbose + + # Hot reload allows you to change POWERLEVEL9K options after Powerlevel10k has been initialized. + # For example, you can type POWERLEVEL9K_BACKGROUND=red and see your prompt turn red. Hot reload + # can slow down prompt by 1-2 milliseconds, so it's better to keep it turned off unless you + # really need it. + typeset -g POWERLEVEL9K_DISABLE_HOT_RELOAD=true + + # If p10k is already loaded, reload configuration. + # This works even with POWERLEVEL9K_DISABLE_HOT_RELOAD=true. + (( ! $+functions[p10k] )) || p10k reload +} + +# Tell `p10k configure` which file it should overwrite. +typeset -g POWERLEVEL9K_CONFIG_FILE=${${(%):-%x}:a} + +(( ${#p10k_config_opts} )) && setopt ${p10k_config_opts[@]} +'builtin' 'unset' 'p10k_config_opts' diff --git a/services/dunst.nix b/services/dunst.nix new file mode 100644 index 0000000..9ebbe21 --- /dev/null +++ b/services/dunst.nix @@ -0,0 +1,24 @@ +{ pkgs, ... }: +{ + services.dunst = { + enable = true; + iconTheme = { + package = pkgs.gnome.adwaita-icon-theme; + name = "Adwaita"; + size = "32x32"; + }; + settings = { + global = { + geometry = "300x5-30+50"; + transparency = 10; + frame_color = "#eceff1"; + font = "Droid Sans 9"; + }; + urgency_normal = { + background = "#37474f"; + foreground = "#eceff1"; + timeout = 10; + }; + }; + }; +} diff --git a/services/mpd.nix b/services/mpd.nix new file mode 100644 index 0000000..f206682 --- /dev/null +++ b/services/mpd.nix @@ -0,0 +1,10 @@ +{ config, ... }: +{ + services.mpd = rec { + enable = true; + musicDirectory = "${config.services.dropbox.path}/music/music"; + # musicDirectory = "${config.home.homeDirectory}/music"; + playlistDirectory = "${musicDirectory}/playlists/MPD"; + }; +} + diff --git a/services/picom.nix b/services/picom.nix new file mode 100644 index 0000000..e98d59c --- /dev/null +++ b/services/picom.nix @@ -0,0 +1,37 @@ +{ ... }: +{ + services.picom = { + enable = true; + + blur = true; + blurExclude = [ + "class_g = 'slop'" + "class_g = 'XAVA'" + "class_g = 'lattedock'" + "class_g = 'latte-dock'" + "window_type = 'dock'" + "window_type = 'desktop'" + "_GTK_FRAME_EXTENTS@:c" + ]; + + fade = true; + fadeSteps = [ "0.1" "0.1" ]; + fadeExclude = []; + + shadow = true; + shadowOffsets = [ (-7) (-7) ]; + shadowOpacity = "0.25"; + shadowExclude = [ + "class_g = 'XAVA'" + "class_g = 'stalonetray'" + "class_g = 'lattedock'" + "class_g = 'latte-dock'" + ]; + noDockShadow = true; + noDNDShadow = true; + + vSync = true; + + extraOptions = ''''; + }; +} diff --git a/services/stalonetray.nix b/services/stalonetray.nix new file mode 100644 index 0000000..584abfb --- /dev/null +++ b/services/stalonetray.nix @@ -0,0 +1,23 @@ +{ colorTheme, ... }: +{ + services.stalonetray = { + enable = true; + config = { + decorations = "none"; + transparent = false; + dockapp_mode = "none"; + geometry = "8x1-0+0"; + background = colorTheme.default.background; + kludges = "force_icons_size"; + grow_gravity = "NW"; + icon_gravity = "NW"; + icon_size = 30; + sticky = true; + window_type = "dock"; + window_layer = "bottom"; + no_shrink = true; + skip_taskbar = true; + slot_size = 40; + }; + }; +} diff --git a/services/sxhkd.nix b/services/sxhkd.nix new file mode 100644 index 0000000..99aeb2a --- /dev/null +++ b/services/sxhkd.nix @@ -0,0 +1,79 @@ +{ pkgs, ... }: +{ + services.sxhkd = { + enable = true; + keybindings = { + + # make sxhkd reload its configuration files: + "super + Escape" = "pkill -USR1 -x sxhkd && ${pkgs.libnotify}/bin/notify-send -t 3000 \"sxhkd configuration reloaded\""; + + # Applications + "super + w" = "${pkgs.emacs}/bin/emacs"; + + "super + e" = "$FILEBROWSER"; + + "super + s" = "$BROWSER"; + + "super + r" = "${pkgs.rofi}/bin/rofi -show drun"; + + # Volume + + "super + {@F7,@F8}" = "${pkgs.alsaUtils}/bin/amixer set Master 2%{-,+}"; + + "{XF86AudioLowerVolume,XF86AudioRaiseVolume}" = "${pkgs.alsaUtils}/bin/amixer set Master 2%{-,+}"; + + "XF86AudioMute" = "${pkgs.pulseaudio}/bin/pactl set-sink-mute @DEFAULT_SINK@ toggle"; + + # Music + + "super + p" = "${pkgs.mpc_cli}/bin/mpc toggle"; + + "XF86AudioPlay" = "${pkgs.mpc_cli}/bin/mpc toggle"; + "XF86AudioPrev" = "${pkgs.mpc_cli}/bin/mpc prev"; + "XF86AudioNext" = "${pkgs.mpc_cli}/bin/mpc next"; + + # Monitor + + "XF86MonBrightnessUp" = "${pkgs.light}/bin/light -A 5"; + "XF86MonBrightnessDown" = "${pkgs.light}/bin/light -U 5"; + + "@Print" = "${pkgs.maim}/bin/maim --hidecursor --nokeyboard --select | ${pkgs.xclip}/bin/xclip -selection clipboard -target image/png -in"; + + "shift + @Print" = "${pkgs.maim}/bin/maim --hidecursor --nokeyboard $SCREENSHOT_DIR/$(date +%s).png"; + + # TODO: Add boomer as package + # "super + @Print" = "boomer"; + + # Misc + + "super + a" = "${pkgs.copyq}/bin/copyq toggle"; + + # fcitx + "super + {b,n,m}" = "${pkgs.fcitx}/bin/fcitx-remote -s {mozc,fcitx-keyboard-no,fcitx-keyboard-us}"; + + # fcitx5 + # "super + {b,n,m}" = "${pkgs.fcitx5}/bin/fcitx5-remote -s {mozc,keyboard-no,keyboard-us}"; + + # TODO: fix + # "super + v" = "${pkgs.rofi}/bin/rofi -modi lpass:$HOME/.scripts/rofi/lpass/rofi-lpass -show lpass"; + + "super + minus" = "${pkgs.xcalib}/bin/xcalib -invert -alter"; + + # ¯\_(ツ)_/¯ + # "super + shift + s" + # sleep 0.3; \ + # ${pkgs.xdotool}/bin/xdotool key U00AF; \ + # ${pkgs.xdotool}/bin/xdotool key U005C; \ + # ${pkgs.xdotool}/bin/xdotool key U005F; \ + # ${pkgs.xdotool}/bin/xdotool key U0028; \ + # ${pkgs.xdotool}/bin/xdotool key U30C4; \ + # ${pkgs.xdotool}/bin/xdotool key U0029; \ + # ${pkgs.xdotool}/bin/xdotool key U005F; \ + # ${pkgs.xdotool}/bin/xdotool key U002F; \ + # ${pkgs.xdotool}/bin/xdotool key U00AF + + # é + "super + shift + e" = "sleep 0.3; ${pkgs.xdotool}/bin/xdotool key U00E9"; + }; + }; +} diff --git a/shellOptions.nix b/shellOptions.nix new file mode 100644 index 0000000..a1324a4 --- /dev/null +++ b/shellOptions.nix @@ -0,0 +1,417 @@ +{ pkgs, config, ... }: let + + # FIXME: lib should be imported directly as a module argument. + inherit (pkgs) lib; + + sedColor = + color: + inputPattern: + outputPattern: + "-e \"s|${inputPattern}|${outputPattern.before or ""}$(tput setaf ${toString color})${outputPattern.middle}$(tput op)${outputPattern.after or ""}|g\""; + + colorRed = sedColor 1; + + colorSlashes = colorRed "/" {middle = "/";}; + + # Context Functors + functors = let + inherit (lib.strings) concatStringsSep; + inherit (lib.termColors.front) blue; + genWrapper = type: value: { inherit type; inherit value; }; + in + { + shellPipe = { + wrap = genWrapper "shellPipe"; + apply = f: concatStringsSep " | " f.value; + stringify = f: concatStringsSep (blue "\n| ") f.value; + }; + shellAnd = { + wrap = genWrapper "shellAnd"; + apply = f: concatStringsSep " && " f.value; + stringify = f: concatStringsSep (blue "\n&& ") f.value; + }; + shellThen = { + wrap = genWrapper "shellThen"; + apply = f: concatStringsSep "; " f.value; + stringify = f: concatStringsSep (blue ";\n ") f.value; + }; + shellJoin = { + wrap = genWrapper "shellJoin"; + apply = f: concatStringsSep " " f.value; + stringify = f: concatStringsSep " \\\n " f.value; + }; + }; + + # AttrSet -> Bool + isFunctor = let + inherit (lib.lists) any; + inherit (lib.attrsets) attrValues; + in + attrset: + if !(attrset ? "type") + then false + else any (f: (f.wrap "").type == attrset.type) (attrValues functors); + +in rec { + _module.args.shellOptions = { + aliases = let + shellPipe = functors.shellPipe.wrap; + shellJoin = functors.shellJoin.wrap; + shellAnd = functors.shellAnd.wrap; + shellThen = functors.shellThen.wrap; + in with pkgs; { + + # ░█▀▄░█▀▀░█▀█░█░░░█▀█░█▀▀░█▀▀░█▄█░█▀▀░█▀█░▀█▀░█▀▀ + # ░█▀▄░█▀▀░█▀▀░█░░░█▀█░█░░░█▀▀░█░█░█▀▀░█░█░░█░░▀▀█ + # ░▀░▀░▀▀▀░▀░░░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀░▀░▀▀▀░▀░▀░░▀░░▀▀▀ + + # Replacing all of coreutils with rust, lol + + "System Tool Replacements" = { + + # Convention: if replaced tool is useful in some situations, let it be available + # as its own command with its first character doubled. + # + # Example: cp -> ccp + + cd = "z"; + + ccp = "${coreutils}/bin/cp"; + cp = "${rsync}/bin/rsync --progress --human-readable"; + cpr = "${rsync}/bin/rsync --progress --human-readable --recursive"; + + ccat = "${coreutils}/bin/cat"; + cat = "${bat}/bin/bat"; + + htop = "${bottom}/bin/btm"; + hhtop = "${htop}/bin/htop"; + + # This is potentially dangerous, as procs flags are totally different + ps = "${procs}/bin/procs"; + + # Find flags are so different that I've renamed fd to fin for time being + fin = "${fd}/bin/fd"; + + ag="${ripgrep}/bin/rg"; + + lls = "${coreutils}/bin/ls --color=always"; + ls = "${exa}/bin/exa"; + la = "${exa}/bin/exa -lah --changed --time-style long-iso --git --group"; + lsa = "la"; + + killall = "echo \"killall is dangerous on non-gnu platforms. Using 'pkill -x'\"; pkill -x"; + }; + + # ░█▀▀░█▀█░█░░░█▀█░█▀▄░▀█▀░▀▀█░█▀▀░█▀▄ + # ░█░░░█░█░█░░░█░█░█▀▄░░█░░▄▀░░█▀▀░█░█ + # ░▀▀▀░▀▀▀░▀▀▀░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░▀▀░ + + # Normal commands, just with colors. + + "Colorized" = { + ip = "ip --color=always"; + diff = "diff --color=auto"; + grep = "grep --color=always"; + # TODO: doesn't work + # make = "${colormake}/bin/colormake"; + }; + + # ░█▀▄░█▀▀░█▄█░▀█▀░█▀█░█▀▄░█▀▀░█▀▄░█▀▀ + # ░█▀▄░█▀▀░█░█░░█░░█░█░█░█░█▀▀░█▀▄░▀▀█ + # ░▀░▀░▀▀▀░▀░▀░▀▀▀░▀░▀░▀▀░░▀▀▀░▀░▀░▀▀▀ + + # Stuff that I constantly forget... + + "Reminders" = { + regex-escapechars = "echo \"[\\^$.|?*+()\""; + aliases = "${coreutils}/bin/cat $HOME/${config.xdg.dataFile.aliases.target}"; + }; + + # ░█▀█░▀█▀░█░█ + # ░█░█░░█░░▄▀▄ + # ░▀░▀░▀▀▀░▀░▀ + + # Nix related aliases + + "Nix Stuff" = { + + # FIXME: This for some reason uses an outdated version of home-manager and nixos-rebuild + # hs = "${pkgs.home-manager}/bin/home-manager switch"; + # nxr = "sudo ${nixos-rebuild}/bin/nixos-rebuild switch"; + + hms = "home-manager switch"; + nxr = "sudo nixos-rebuild switch"; + + nxc = "sudoedit /etc/nixos/configuration.nix"; + nxh = "vim ~/.config/nixpkgs/home.nix"; + ns = "nix-shell"; + }; + + # ░█▀▀░█▀█░█▀▀░▀█▀░█░█░█▀█░█▀▄░█▀▀ + # ░▀▀█░█░█░█▀▀░░█░░█▄█░█▀█░█▀▄░█▀▀ + # ░▀▀▀░▀▀▀░▀░░░░▀░░▀░▀░▀░▀░▀░▀░▀▀▀ + + # Aliases that are so long/piped that they could be considered new software. + + "Software" = { + + skusho = "${maim}/bin/maim --hidecursor --nokeyboard $(echo $SCREENSHOT_DIR)/$(date_%s).png"; + skushoclip = shellPipe [ + "${maim}/bin/maim --hidecursor --nokeyboard --select" + "${xclip}/bin/xclip -selection clipboard -target image/png -in" + ]; + + dp-check = shellPipe [ + "ls -l /proc/$(pidof dropbox)/fd" + "egrep -v 'pipe:|socket:|/dev'" + "grep \"${config.services.dropbox.path}/[^.]\"" + ]; + + subdirs-to-cbz = shellJoin [ + "for dir in \"./*\";" + " ${zip}/bin/zip -r \"$dir.cbz\" \"$d\";" + "done" + ]; + + connectedIps = shellPipe [ + "netstat -tn 2>/dev/null" + "grep :$1" + "awk '{print $5}'" + "cut -d: -f1" + "sort" + "uniq -c" + "sort -nr" + "head" + ]; + + path = "echo $PATH | sed -e 's/:/\\n/g' ${colorSlashes} | sort"; + + wowify = "${toilet}/bin/toilet -f pagga | ${lolcat}/bin/lolcat"; + + aliasc = let + colorAliasNames = colorRed "\\(^[^=]*\\)=" {middle = "\\1"; after = "\\t";}; + # The '[^]]' (character before /nix should not be ']') is there so that this + # alias definition won't be removed. + removeNixLinks = "-e 's|\\([^]]\\)/nix/store/.*/bin/|\\1|'"; + in + shellPipe [ + "alias" + "sed ${colorAliasNames} ${removeNixLinks}" + "column -ts $'\\t'" + ]; + + ports = let + colorFirstColumn = colorRed "(^[^ ]+)" {middle = "\\1";}; + in + shellPipe [ + "sudo netstat -tulpn" + "grep LISTEN" + "sed -r 's/\\s+/ /g'" + "cut -d' ' -f 4,7" + "column -t" + "sed -r ${colorFirstColumn} ${colorSlashes}" + ]; + }; + + # ░█▀█░█░░░▀█▀░█▀█░█▀▀░█▀▀░█▀▀ + # ░█▀█░█░░░░█░░█▀█░▀▀█░█▀▀░▀▀█ + # ░▀░▀░▀▀▀░▀▀▀░▀░▀░▀▀▀░▀▀▀░▀▀▀ + + # Normal commands that are just shortened. What would normally be considered + # the "technically correct definition" of an alias + + "Actual Aliases" = { + dp = "${dropbox-cli}/bin/dropbox"; + + # Having 'watch' with a space after as an alias, enables it to expand other aliases + watch = "${procps}/bin/watch "; + + concatPdfs = shellThen [ + "echo \"${lib.termColors.front.red "Concatenating all pdfs in current directory to 'out.pdf'"}\"" + "${poppler_utils}/bin/pdfunite *.pdf out.pdf" + ]; + + m = "${ncmpcpp}/bin/ncmpcpp"; + p = "${python39Packages.ipython}/bin/ipython"; + }; + + # ░█▄█░▀█▀░█▀▀░█▀▀ + # ░█░█░░█░░▀▀█░█░░ + # ░▀░▀░▀▀▀░▀▀▀░▀▀▀ + + # I didn't know where else to put these ¯\_(ツ)_/¯ + + "Misc" = { + youtube-dl-list = shellJoin [ + "${youtube-dl}/bin/youtube-dl" + "-f \"bestvideo[ext=mp4]+bestaudio[e=m4a]/bestvideo+bestaudio\"" + "-o \"%(playlist_index)s-%(title)s.%(ext)s\"" + ]; + + music-dl = "${youtube-dl}/bin/youtube-dl --extract-audio -f \"bestaudio[ext=m4a]/best\""; + music-dl-list = shellJoin [ + "${youtube-dl}/bin/youtube-dl" + "--extract-audio" + "-f \"bestaudio[ext=m4a]/best\"" + "-o \"%(playlist_index)s-%(title)s.%(ext)s\"" + ]; + + view-latex = "${texlive.combined.scheme-full}/bin/latexmk -pdf -pvc main.tex"; + + reload-tmux = "${tmux}/bin/tmux source $HOME/.config/tmux/tmux.conf"; + }; + + # ░█▀▀░█▀▀░█▀█░█▀▀░█▀▄░█▀█░▀█▀░█▀▀░█▀▄ + # ░█░█░█▀▀░█░█░█▀▀░█▀▄░█▀█░░█░░█▀▀░█░█ + # ░▀▀▀░▀▀▀░▀░▀░▀▀▀░▀░▀░▀░▀░░▀░░▀▀▀░▀▀░ + + # Code generated commands + + "Generated" = { + "cds" = let + inherit (lib.strings) concatStringsSep repeatString; + inherit (lib.lists) range flatten repeat; + inherit (lib.attrsets) nameValuePair listToAttrs; + + nthCds = n: [ + ("cd" + (repeatString "." (n + 1))) + ("cd." + toString n) + (repeatString "." (n + 1)) + ("." + toString n) + (".." + toString n) + ]; + realCommand = n: "cd " + (concatStringsSep "/" (repeat ".." n)); + + nthCdsAsNameValuePairs = n: map (cmd: nameValuePair cmd (realCommand n)) (nthCds n); + allCdNameValuePairs = flatten (map nthCdsAsNameValuePairs (range 1 9)); + in + listToAttrs allCdNameValuePairs; + + "Package Managers" = let + inherit (lib.attrsets) nameValuePair listToAttrs; + + packageManagers = [ + "apt" + "dpkg" + "flatpak" + "pacman" + "pamac" + "paru" + "rpm" + "snap" + "xbps" + "yay" + "yum" + ]; + + command = "${coreutils}/bin/cat $HOME/${config.xdg.dataFile.packageManagerLecture.target}"; + nameValuePairs = map (pm: nameValuePair pm command) packageManagers; + in listToAttrs nameValuePairs; + }; + }; + + # TODO: flatten functions + functions = { + all = { + md-to-pdf = functors.shellJoin.wrap [ + "pandoc \"$1\"" + "-f gfm" + "-V linkcolor:blue" + "-V geometry:a4paper" + "-V geometry:margin=2cm" + "-V mainfont=\"Droid Sans\"" + "--pdf-engine=xelatex" + "-o \"$2\"" + ]; + }; + }; + + variables = { + POWERLEVEL9K_LEFT_PROMPT_ELEMENTS = ["dir" "vcs"]; + # NIX_PATH = ''$HOME/.nix-defexpr/channels$\{NIX_PATH:+:}$NIX_PATH''; + }; + + flattened.aliases = let + inherit (lib.attrsets) mapAttrs attrValues filterAttrs isAttrs concatAttrs; + inherit (lib.strings) isString concatStringsSep; + + applyFunctor = attrset: functors.${attrset.type}.apply attrset; + + # TODO: better naming + allAttrValuesAreStrings = attrset: let + + # [ {String} ] + filteredAliases = [(filterAttrs (n: v: isString v) attrset)]; + + # [ {String} ] + remainingFunctors = let + functorSet = filterAttrs (n: v: isAttrs v && isFunctor v) attrset; + appliedFunctorSet = mapAttrs (n: v: applyFunctor v) functorSet; + in [ appliedFunctorSet ]; + + # [ {AttrSet} ] + remainingAliasSets = attrValues (filterAttrs (n: v: isAttrs v && !(isFunctor v)) attrset); + + # [ {String} ] + recursedAliasSets = filteredAliases + ++ (remainingFunctors) + ++ (map allAttrValuesAreStrings remainingAliasSets); + in concatAttrs recursedAliasSets; + + in + allAttrValuesAreStrings _module.args.shellOptions.aliases; + }; + + xdg.dataFile = { + aliases = { + text = let + inherit (lib.strings) unlines wrap' replaceStrings' stringLength repeatString; + inherit (lib.attrsets) attrValues mapAttrs isAttrs; + inherit (lib.lists) remove; + inherit (lib.trivial) mapNullable; + inherit (lib.termColors.front) red green blue; + + # int -> String -> AttrSet -> String + stringifyCategory = level: name: category: + unlines + (["${repeatString " " level}[${green name}]"] ++ + (attrValues (mapAttrs (n: v: let + # String + indent = repeatString " " level; + + # String -> String + removeNixLinks = text: let + maybeMatches = builtins.match "(|.*[^)])(/nix/store/.*/bin/).*" text; + matches = mapNullable (remove "") maybeMatches; + in + if (maybeMatches == null) + then text + else replaceStrings' matches "" text; + + applyFunctor = attrset: let + applied = functors.${attrset.type}.stringify attrset; + indent' = indent + (repeatString " " ((stringLength " -> \"") + (stringLength n))) + " "; + in + replaceStrings' ["\n"] ("\n" + indent') applied; + + recurse = stringifyCategory (level + 1) n v; + in + if !(isAttrs v) then "${indent} ${red n} -> ${wrap' (blue "\"") (removeNixLinks v)}" else + if isFunctor v then "${indent} ${red n} -> ${wrap' (blue "\"") (removeNixLinks (applyFunctor v))}" else + recurse) category))); + in + (stringifyCategory 0 "Aliases" _module.args.shellOptions.aliases) + "\n"; + }; + packageManagerLecture = { + target = "package-manager.lecture"; + text = let + inherit (lib.strings) unlines; + inherit (lib.termColors.front) red blue; + in unlines [ + ((red "This package manager is not installed on ") + (blue "NixOS") + (red ".")) + ((red "Either use ") + ("\"nix-env -i\"") + (red " or install it through a configuration file.")) + "" + ]; + }; + }; +}