From e8613514eb2f167278a3ba8c0f9ed16c0b098a28 Mon Sep 17 00:00:00 2001 From: Madeleine Date: Tue, 19 Dec 2023 19:08:55 +0000 Subject: [PATCH] initial commit (because syncthing) --- .gitignore | 2 + README.md | 15 + flake.lock | 67 +++ flake.nix | 81 +++ maddie/common/browser.nix | 8 + maddie/common/btop.nix | 12 + maddie/common/code.nix | 7 + maddie/common/editor.nix | 8 + maddie/common/emacs.nix | 18 + maddie/common/emacs/.#init 2.el | 1 + maddie/common/emacs/early-init.el | 0 maddie/common/emacs/emacs.png | Bin 0 -> 144778 bytes maddie/common/emacs/init.el | 238 ++++++++ maddie/common/esa.nix | 16 + maddie/common/fetch.nix | 9 + maddie/common/git.nix | 51 ++ maddie/common/git/git-sync.sh | 6 + maddie/common/helix.nix | 21 + maddie/common/htop.nix | 19 + maddie/common/java.nix | 7 + maddie/common/kakoune.nix | 77 +++ maddie/common/kakoune/colors/one-dark-16.kak | 93 ++++ maddie/common/kakoune/colors/one-dark.kak | 117 ++++ .../common/kakoune/colors/one-darker-16.kak | 101 ++++ maddie/common/kakoune/colors/one-darker.kak | 125 +++++ maddie/common/kakoune/colors/one-light-16.kak | 93 ++++ maddie/common/kakoune/colors/one-light.kak | 117 ++++ maddie/common/latex.nix | 8 + maddie/common/lf.nix | 26 + maddie/common/lf/icons | 93 ++++ maddie/common/lf/scope | 52 ++ maddie/common/lsp.nix | 14 + maddie/common/media.nix | 9 + maddie/common/mommy.nix | 12 + maddie/common/mommy/shell-mommy.sh | 77 +++ maddie/common/neovim.nix | 13 + maddie/common/neovim/.gitignore | 1 + maddie/common/neovim/LICENSE | 21 + maddie/common/neovim/README.md | 22 + maddie/common/neovim/init.lua | 253 +++++++++ maddie/common/neovim/lua/basics.lua | 36 ++ maddie/common/neovim/lua/colours.lua | 1 + maddie/common/neovim/lua/keymaps.lua | 59 ++ maddie/common/neovim/lua/plugins/cmp.lua | 117 ++++ maddie/common/neovim/spell/en.utf-8.add | 6 + maddie/common/neovim/spell/en.utf-8.add.spl | Bin 0 -> 111 bytes maddie/common/newsboat.nix | 19 + maddie/common/passwords.nix | 14 + maddie/common/processes.nix | 8 + maddie/common/python.nix | 24 + maddie/common/rust.nix | 15 + maddie/common/shell.nix | 62 +++ maddie/common/smart-home.nix | 7 + maddie/common/ssh.nix | 26 + maddie/common/ssh/maddie.pub | 3 + maddie/common/tmux.nix | 10 + maddie/common/xdg.nix | 21 + maddie/common/yt-dlp.nix | 13 + maddie/common/yt-dlp/ytdlp-music.sh | 25 + maddie/common/zsh.nix | 123 +++++ maddie/macos/home.nix | 10 + maddie/macos/iterm2.nix | 510 ++++++++++++++++++ maddie/macos/ssh.nix | 9 + maddie/macos/tower.nix | 33 ++ maddie/nixos/android.nix | 7 + maddie/nixos/audio.nix | 15 + maddie/nixos/audio/volume.sh | 24 + maddie/nixos/awesome.nix | 7 + maddie/nixos/bosskey.nix | 12 + maddie/nixos/bosskey/bosskey.sh | 39 ++ maddie/nixos/calculator.nix | 7 + maddie/nixos/chromium.nix | 29 + maddie/nixos/cider.nix | 7 + maddie/nixos/dmenu.nix | 16 + maddie/nixos/dmenu/dmenu-bluetooth | 317 +++++++++++ maddie/nixos/dmenu/dmenu-code | 3 + maddie/nixos/dmenu/dmenu-kdeconnect | 41 ++ maddie/nixos/dmenu/dmenu-man | 2 + maddie/nixos/dmenu/dmenu-mount | 67 +++ maddie/nixos/dmenu/dmenu-mpc | 14 + maddie/nixos/dmenu/dmenu-pass | 35 ++ maddie/nixos/dmenu/dmenu-power | 9 + maddie/nixos/dmenu/dmenu-unicode | 18 + maddie/nixos/drawterm.nix | 7 + maddie/nixos/dunst.nix | 44 ++ maddie/nixos/dwm.nix | 7 + maddie/nixos/files.nix | 8 + maddie/nixos/games.nix | 8 + maddie/nixos/gcolor2.nix | 7 + maddie/nixos/gtk.nix | 25 + maddie/nixos/home.nix | 10 + maddie/nixos/jetbrains.nix | 12 + maddie/nixos/kdeconnect.nix | 10 + maddie/nixos/librewolf.nix | 12 + maddie/nixos/messaging.nix | 12 + maddie/nixos/minecraft.nix | 9 + maddie/nixos/mpd.nix | 41 ++ maddie/nixos/mpv.nix | 10 + maddie/nixos/neovide.nix | 7 + maddie/nixos/nsxiv.nix | 16 + maddie/nixos/nsxiv/exec/key-handler | 14 + maddie/nixos/obs-studio.nix | 5 + maddie/nixos/office.nix | 12 + maddie/nixos/openrgb.nix | 18 + maddie/nixos/osu.nix | 7 + maddie/nixos/pcmanfm.nix | 11 + maddie/nixos/pcmanfm/default/pcmanfm.conf | 26 + maddie/nixos/picom.nix | 25 + maddie/nixos/popcorntime.nix | 7 + maddie/nixos/qt.nix | 19 + maddie/nixos/screenshot.nix | 13 + maddie/nixos/screenshot/sss.sh | 40 ++ maddie/nixos/secrets.nix | 13 + maddie/nixos/slstatus.nix | 21 + maddie/nixos/statusbar/sb-clock | 3 + maddie/nixos/statusbar/sb-cpu | 6 + maddie/nixos/statusbar/sb-disk | 7 + maddie/nixos/statusbar/sb-forecast | 35 ++ maddie/nixos/statusbar/sb-iplocate | 10 + maddie/nixos/statusbar/sb-kernel | 5 + maddie/nixos/statusbar/sb-memory | 7 + maddie/nixos/statusbar/sb-temp | 13 + maddie/nixos/statusbar/sb-uptime | 6 + maddie/nixos/statusbar/sb-volume | 15 + maddie/nixos/steam.nix | 13 + maddie/nixos/steam/steam-killer.sh | 9 + maddie/nixos/syncplay.nix | 7 + maddie/nixos/tabbed.nix | 16 + maddie/nixos/tabbed/tabbed-st | 3 + maddie/nixos/terminal.nix | 9 + maddie/nixos/tor.nix | 7 + maddie/nixos/uxplay.nix | 7 + maddie/nixos/virtualisation.nix | 9 + maddie/nixos/wezterm.nix | 14 + maddie/nixos/xdg.nix | 59 ++ maddie/nixos/xorg.nix | 68 +++ maddie/nixos/yubikey.nix | 7 + maddie/nixos/zathura.nix | 5 + overlays.nix | 68 +++ systems/mdesktop/android.nix | 5 + systems/mdesktop/audio.nix | 14 + systems/mdesktop/avahi.nix | 14 + systems/mdesktop/bluetooth.nix | 6 + systems/mdesktop/boot.nix | 37 ++ systems/mdesktop/cpu.nix | 6 + systems/mdesktop/disks.nix | 24 + systems/mdesktop/doas.nix | 13 + systems/mdesktop/firewall.nix | 6 + systems/mdesktop/fonts.nix | 13 + systems/mdesktop/gpg.nix | 10 + systems/mdesktop/locale.nix | 13 + systems/mdesktop/man.nix | 8 + systems/mdesktop/networking.nix | 17 + systems/mdesktop/nix-ld.nix | 5 + systems/mdesktop/nix.nix | 16 + systems/mdesktop/nixos.nix | 6 + systems/mdesktop/noise-supression.nix | 47 ++ systems/mdesktop/nvidia.nix | 23 + systems/mdesktop/openrazer.nix | 9 + systems/mdesktop/openrgb.nix | 8 + systems/mdesktop/packages.nix | 50 ++ systems/mdesktop/security.nix | 6 + systems/mdesktop/services.nix | 6 + systems/mdesktop/ssh.nix | 13 + systems/mdesktop/syncthing.nix | 48 ++ systems/mdesktop/systemd.nix | 8 + systems/mdesktop/users.nix | 11 + systems/mdesktop/virtualisation.nix | 6 + systems/mdesktop/xorg.nix | 17 + systems/mdesktop/yubikey.nix | 22 + systems/mdesktop/zsh.nix | 10 + systems/mmacbookpro/apps.nix | 73 +++ systems/mmacbookpro/dock.nix | 54 ++ systems/mmacbookpro/finder.nix | 15 + systems/mmacbookpro/fonts.nix | 10 + systems/mmacbookpro/gpg.nix | 11 + systems/mmacbookpro/keyboard.nix | 20 + systems/mmacbookpro/networking.nix | 8 + systems/mmacbookpro/nix.nix | 20 + systems/mmacbookpro/packages.nix | 26 + systems/mmacbookpro/setDock.nix | 68 +++ systems/mmacbookpro/settings.nix | 74 +++ systems/mmacbookpro/ssh.nix | 7 + systems/mmacbookpro/sudo.nix | 5 + systems/mmacbookpro/zsh.nix | 10 + utils/default.nix | 28 + utils/nixFilesIn.nix | 2 + utils/nixFilesInWithName.nix | 8 + 188 files changed, 5550 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 maddie/common/browser.nix create mode 100644 maddie/common/btop.nix create mode 100644 maddie/common/code.nix create mode 100644 maddie/common/editor.nix create mode 100644 maddie/common/emacs.nix create mode 120000 maddie/common/emacs/.#init 2.el create mode 100644 maddie/common/emacs/early-init.el create mode 100644 maddie/common/emacs/emacs.png create mode 100644 maddie/common/emacs/init.el create mode 100644 maddie/common/esa.nix create mode 100644 maddie/common/fetch.nix create mode 100644 maddie/common/git.nix create mode 100644 maddie/common/git/git-sync.sh create mode 100644 maddie/common/helix.nix create mode 100644 maddie/common/htop.nix create mode 100644 maddie/common/java.nix create mode 100644 maddie/common/kakoune.nix create mode 100644 maddie/common/kakoune/colors/one-dark-16.kak create mode 100644 maddie/common/kakoune/colors/one-dark.kak create mode 100644 maddie/common/kakoune/colors/one-darker-16.kak create mode 100644 maddie/common/kakoune/colors/one-darker.kak create mode 100644 maddie/common/kakoune/colors/one-light-16.kak create mode 100644 maddie/common/kakoune/colors/one-light.kak create mode 100644 maddie/common/latex.nix create mode 100644 maddie/common/lf.nix create mode 100644 maddie/common/lf/icons create mode 100644 maddie/common/lf/scope create mode 100644 maddie/common/lsp.nix create mode 100644 maddie/common/media.nix create mode 100644 maddie/common/mommy.nix create mode 100644 maddie/common/mommy/shell-mommy.sh create mode 100644 maddie/common/neovim.nix create mode 100644 maddie/common/neovim/.gitignore create mode 100644 maddie/common/neovim/LICENSE create mode 100644 maddie/common/neovim/README.md create mode 100644 maddie/common/neovim/init.lua create mode 100644 maddie/common/neovim/lua/basics.lua create mode 100644 maddie/common/neovim/lua/colours.lua create mode 100644 maddie/common/neovim/lua/keymaps.lua create mode 100644 maddie/common/neovim/lua/plugins/cmp.lua create mode 100644 maddie/common/neovim/spell/en.utf-8.add create mode 100644 maddie/common/neovim/spell/en.utf-8.add.spl create mode 100644 maddie/common/newsboat.nix create mode 100644 maddie/common/passwords.nix create mode 100644 maddie/common/processes.nix create mode 100644 maddie/common/python.nix create mode 100644 maddie/common/rust.nix create mode 100644 maddie/common/shell.nix create mode 100644 maddie/common/smart-home.nix create mode 100644 maddie/common/ssh.nix create mode 100644 maddie/common/ssh/maddie.pub create mode 100644 maddie/common/tmux.nix create mode 100644 maddie/common/xdg.nix create mode 100644 maddie/common/yt-dlp.nix create mode 100755 maddie/common/yt-dlp/ytdlp-music.sh create mode 100644 maddie/common/zsh.nix create mode 100644 maddie/macos/home.nix create mode 100644 maddie/macos/iterm2.nix create mode 100644 maddie/macos/ssh.nix create mode 100644 maddie/macos/tower.nix create mode 100644 maddie/nixos/android.nix create mode 100644 maddie/nixos/audio.nix create mode 100755 maddie/nixos/audio/volume.sh create mode 100644 maddie/nixos/awesome.nix create mode 100644 maddie/nixos/bosskey.nix create mode 100755 maddie/nixos/bosskey/bosskey.sh create mode 100644 maddie/nixos/calculator.nix create mode 100644 maddie/nixos/chromium.nix create mode 100644 maddie/nixos/cider.nix create mode 100644 maddie/nixos/dmenu.nix create mode 100755 maddie/nixos/dmenu/dmenu-bluetooth create mode 100755 maddie/nixos/dmenu/dmenu-code create mode 100755 maddie/nixos/dmenu/dmenu-kdeconnect create mode 100755 maddie/nixos/dmenu/dmenu-man create mode 100755 maddie/nixos/dmenu/dmenu-mount create mode 100755 maddie/nixos/dmenu/dmenu-mpc create mode 100755 maddie/nixos/dmenu/dmenu-pass create mode 100755 maddie/nixos/dmenu/dmenu-power create mode 100755 maddie/nixos/dmenu/dmenu-unicode create mode 100644 maddie/nixos/drawterm.nix create mode 100644 maddie/nixos/dunst.nix create mode 100644 maddie/nixos/dwm.nix create mode 100644 maddie/nixos/files.nix create mode 100644 maddie/nixos/games.nix create mode 100644 maddie/nixos/gcolor2.nix create mode 100644 maddie/nixos/gtk.nix create mode 100644 maddie/nixos/home.nix create mode 100644 maddie/nixos/jetbrains.nix create mode 100644 maddie/nixos/kdeconnect.nix create mode 100644 maddie/nixos/librewolf.nix create mode 100644 maddie/nixos/messaging.nix create mode 100644 maddie/nixos/minecraft.nix create mode 100644 maddie/nixos/mpd.nix create mode 100644 maddie/nixos/mpv.nix create mode 100644 maddie/nixos/neovide.nix create mode 100644 maddie/nixos/nsxiv.nix create mode 100755 maddie/nixos/nsxiv/exec/key-handler create mode 100644 maddie/nixos/obs-studio.nix create mode 100644 maddie/nixos/office.nix create mode 100644 maddie/nixos/openrgb.nix create mode 100644 maddie/nixos/osu.nix create mode 100644 maddie/nixos/pcmanfm.nix create mode 100644 maddie/nixos/pcmanfm/default/pcmanfm.conf create mode 100644 maddie/nixos/picom.nix create mode 100644 maddie/nixos/popcorntime.nix create mode 100644 maddie/nixos/qt.nix create mode 100644 maddie/nixos/screenshot.nix create mode 100755 maddie/nixos/screenshot/sss.sh create mode 100644 maddie/nixos/secrets.nix create mode 100644 maddie/nixos/slstatus.nix create mode 100755 maddie/nixos/statusbar/sb-clock create mode 100755 maddie/nixos/statusbar/sb-cpu create mode 100755 maddie/nixos/statusbar/sb-disk create mode 100755 maddie/nixos/statusbar/sb-forecast create mode 100755 maddie/nixos/statusbar/sb-iplocate create mode 100755 maddie/nixos/statusbar/sb-kernel create mode 100755 maddie/nixos/statusbar/sb-memory create mode 100755 maddie/nixos/statusbar/sb-temp create mode 100755 maddie/nixos/statusbar/sb-uptime create mode 100755 maddie/nixos/statusbar/sb-volume create mode 100644 maddie/nixos/steam.nix create mode 100755 maddie/nixos/steam/steam-killer.sh create mode 100644 maddie/nixos/syncplay.nix create mode 100644 maddie/nixos/tabbed.nix create mode 100755 maddie/nixos/tabbed/tabbed-st create mode 100644 maddie/nixos/terminal.nix create mode 100644 maddie/nixos/tor.nix create mode 100644 maddie/nixos/uxplay.nix create mode 100644 maddie/nixos/virtualisation.nix create mode 100644 maddie/nixos/wezterm.nix create mode 100644 maddie/nixos/xdg.nix create mode 100644 maddie/nixos/xorg.nix create mode 100644 maddie/nixos/yubikey.nix create mode 100644 maddie/nixos/zathura.nix create mode 100644 overlays.nix create mode 100644 systems/mdesktop/android.nix create mode 100644 systems/mdesktop/audio.nix create mode 100644 systems/mdesktop/avahi.nix create mode 100644 systems/mdesktop/bluetooth.nix create mode 100644 systems/mdesktop/boot.nix create mode 100644 systems/mdesktop/cpu.nix create mode 100644 systems/mdesktop/disks.nix create mode 100644 systems/mdesktop/doas.nix create mode 100644 systems/mdesktop/firewall.nix create mode 100644 systems/mdesktop/fonts.nix create mode 100644 systems/mdesktop/gpg.nix create mode 100644 systems/mdesktop/locale.nix create mode 100644 systems/mdesktop/man.nix create mode 100644 systems/mdesktop/networking.nix create mode 100644 systems/mdesktop/nix-ld.nix create mode 100644 systems/mdesktop/nix.nix create mode 100644 systems/mdesktop/nixos.nix create mode 100644 systems/mdesktop/noise-supression.nix create mode 100644 systems/mdesktop/nvidia.nix create mode 100644 systems/mdesktop/openrazer.nix create mode 100644 systems/mdesktop/openrgb.nix create mode 100644 systems/mdesktop/packages.nix create mode 100644 systems/mdesktop/security.nix create mode 100644 systems/mdesktop/services.nix create mode 100644 systems/mdesktop/ssh.nix create mode 100644 systems/mdesktop/syncthing.nix create mode 100644 systems/mdesktop/systemd.nix create mode 100644 systems/mdesktop/users.nix create mode 100644 systems/mdesktop/virtualisation.nix create mode 100644 systems/mdesktop/xorg.nix create mode 100644 systems/mdesktop/yubikey.nix create mode 100644 systems/mdesktop/zsh.nix create mode 100644 systems/mmacbookpro/apps.nix create mode 100644 systems/mmacbookpro/dock.nix create mode 100644 systems/mmacbookpro/finder.nix create mode 100644 systems/mmacbookpro/fonts.nix create mode 100644 systems/mmacbookpro/gpg.nix create mode 100644 systems/mmacbookpro/keyboard.nix create mode 100644 systems/mmacbookpro/networking.nix create mode 100644 systems/mmacbookpro/nix.nix create mode 100644 systems/mmacbookpro/packages.nix create mode 100644 systems/mmacbookpro/setDock.nix create mode 100644 systems/mmacbookpro/settings.nix create mode 100644 systems/mmacbookpro/ssh.nix create mode 100644 systems/mmacbookpro/sudo.nix create mode 100644 systems/mmacbookpro/zsh.nix create mode 100644 utils/default.nix create mode 100644 utils/nixFilesIn.nix create mode 100644 utils/nixFilesInWithName.nix diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..62d8881 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +result +*/result diff --git a/README.md b/README.md new file mode 100644 index 0000000..673a289 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# Maddie's NixFiles +A Nix flake for my system configuration - WIP. + +## Structure +- `./maddie` - A folder for my home-manager configs (aka my user) + - `./maddie/macos` - Specifically macOS (darwin) home configuration + - `./maddie/nixos` - Specifically NixOS home configuration + - `./maddie/common` - Home configuration available on all systems +- `./systems` - A folder for my system-wide configs + - `./systems/mmacbookpro/` - System configuration for my MacBook Pro (M.MacBookPro) + - `./systems/mdesktop` - System configuration for my desktop (M.Desktop) +- `overlays.nix` - A file for my nixpkgs overlays + +## Many thanks +- ❤️ Thanks to @Minion3665 who helped me make this config diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..e898a61 --- /dev/null +++ b/flake.lock @@ -0,0 +1,67 @@ +{ + "nodes": { + "darwin": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1700795494, + "narHash": "sha256-gzGLZSiOhf155FW7262kdHo2YDeugp3VuIFb4/GGng0=", + "owner": "LnL7", + "repo": "nix-darwin", + "rev": "4b9b83d5a92e8c1fbfd8eb27eda375908c11ec4d", + "type": "github" + }, + "original": { + "owner": "LnL7", + "repo": "nix-darwin", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1702110869, + "narHash": "sha256-hgbzPjIMLYJf3Ekq9qZCpDcIZn1BZmOp7d6PMkIWknU=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "7db6291d95693374d408f4877c265ec7481f222b", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1701693815, + "narHash": "sha256-7BkrXykVWfkn6+c1EhFA3ko4MLi3gVG0p9G96PNnKTM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "09ec6a0881e1a36c29d67497693a67a16f4da573", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "root": { + "inputs": { + "darwin": "darwin", + "home-manager": "home-manager", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..d0bbf6d --- /dev/null +++ b/flake.nix @@ -0,0 +1,81 @@ +{ + description = "Maddie's Nix configurations"; + + inputs = { + # Home manager + home-manager.url = "github:nix-community/home-manager"; + home-manager.inputs.nixpkgs.follows = "nixpkgs"; + + darwin.url = "github:LnL7/nix-darwin"; + darwin.inputs.nixpkgs.follows = "nixpkgs"; + }; + + outputs = { self, nixpkgs, home-manager, darwin }: + let + username = "maddie"; + utils = import ./utils nixpkgs; + + nixpkgs_x86_64 = import nixpkgs { + config.allowUnfree = true; + config.allowUnsupportedSystem = false; + config.allowBroken = false; + config.permittedInsecurePackages = [ + "libgcrypt-1.8.10" + "libxls-1.6.2" + ]; + overlays = import ./overlays.nix; + system = "x86_64-linux"; + }; + + nixpkgs_aarch64_darwin = import nixpkgs { + config.allowUnfree = true; + config.allowUnsupportedSystem = false; + config.allowBroken = false; + overlays = import ./overlays.nix; + system = "aarch64-darwin"; + }; + + nixpkgs_aarch64_linux = import nixpkgs { + config.allowUnfree = true; + config.allowUnsupportedSystem = false; + config.allowBroken = false; + overlays = import ./overlays.nix; + system = "aarch64-linux"; + }; + in + { + nixosConfigurations."MDesktop" = nixpkgs.lib.nixosSystem + { + specialArgs = { inherit username; }; + pkgs = nixpkgs_x86_64; + system = "x86_64-linux"; + modules = [ + home-manager.nixosModules.home-manager + { + home-manager.users.${username}.imports = utils.nixFilesIn ./maddie/common ++ utils.nixFilesIn ./maddie/nixos; + home-manager.extraSpecialArgs = { inherit username; pkgs = nixpkgs_x86_64; }; + } + ] ++ utils.nixFilesIn ./systems/mdesktop; + }; + + darwinConfigurations."MMacBookPro" = darwin.lib.darwinSystem + { + pkgs = nixpkgs_aarch64_darwin; + specialArgs = { inherit username; }; + system = "aarch64-darwin"; + modules = [ + home-manager.darwinModules.home-manager + { + home-manager.useUserPackages = true; + home-manager.users.${username}.imports = utils.nixFilesIn ./maddie/common ++ utils.nixFilesIn ./maddie/macos; + home-manager.extraSpecialArgs = { inherit username; pkgs = nixpkgs_aarch64_darwin; }; + } + ] ++ utils.nixFilesIn ./systems/mmacbookpro; + }; + + formatter.x86_64-linux = nixpkgs_x86_64.legacyPackages.x86_64-linux.nixpkgs-fmt; + formatter.aarch64-darwin = nixpkgs_aarch64_darwin.legacyPackages.aarch64-darwin.nixpkgs-fmt; + formatter.aarch64-linux = nixpkgs_aarch64_linux.legacyPackages.aarch64-linux.nixpkgs-fmt; + }; +} + diff --git a/maddie/common/browser.nix b/maddie/common/browser.nix new file mode 100644 index 0000000..21fd758 --- /dev/null +++ b/maddie/common/browser.nix @@ -0,0 +1,8 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + amfora + lynx + ]; +} diff --git a/maddie/common/btop.nix b/maddie/common/btop.nix new file mode 100644 index 0000000..4de9137 --- /dev/null +++ b/maddie/common/btop.nix @@ -0,0 +1,12 @@ +{ config, ... }: + +{ + programs.btop = { + enable = true; + settings = { + color_theme = "TTY"; + theme_background = false; + truecolor = true; + }; + }; +} diff --git a/maddie/common/code.nix b/maddie/common/code.nix new file mode 100644 index 0000000..049d6f6 --- /dev/null +++ b/maddie/common/code.nix @@ -0,0 +1,7 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + go # Go + ]; +} diff --git a/maddie/common/editor.nix b/maddie/common/editor.nix new file mode 100644 index 0000000..2781118 --- /dev/null +++ b/maddie/common/editor.nix @@ -0,0 +1,8 @@ +{ config, pkgs, ... }: + +{ + # Misc editors + home.packages = with pkgs; [ + vis + ]; +} diff --git a/maddie/common/emacs.nix b/maddie/common/emacs.nix new file mode 100644 index 0000000..2486e96 --- /dev/null +++ b/maddie/common/emacs.nix @@ -0,0 +1,18 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + tree-sitter + emacs29 + ]; + + xdg.configFile."emacs/init.el" = { + source = ./emacs/init.el; + }; + xdg.configFile."emacs/early-init.el" = { + source = ./emacs/early-init.el; + }; + xdg.configFile."emacs/emacs.png" = { + source = ./emacs/emacs.png; + }; +} diff --git a/maddie/common/emacs/.#init 2.el b/maddie/common/emacs/.#init 2.el new file mode 120000 index 0000000..ad3dac6 --- /dev/null +++ b/maddie/common/emacs/.#init 2.el @@ -0,0 +1 @@ +maddie@MMacBookPro.1240 \ No newline at end of file diff --git a/maddie/common/emacs/early-init.el b/maddie/common/emacs/early-init.el new file mode 100644 index 0000000..e69de29 diff --git a/maddie/common/emacs/emacs.png b/maddie/common/emacs/emacs.png new file mode 100644 index 0000000000000000000000000000000000000000..37f4bf2e421b50ae22647da6dc2ddd38a7090f90 GIT binary patch literal 144778 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 z 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 z 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 Ae*gdg literal 0 HcmV?d00001 diff --git a/maddie/common/emacs/init.el b/maddie/common/emacs/init.el new file mode 100644 index 0000000..de7f95c --- /dev/null +++ b/maddie/common/emacs/init.el @@ -0,0 +1,238 @@ +;; MELPA +(package-initialize) +(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/")) + +;; Evil +(use-package evil + :ensure t + :init + (setq evil-want-keybinding nil) + :config + (evil-set-undo-system 'undo-redo) + (evil-mode 1)) + +;; Evil collection +(use-package evil-collection + :ensure t + :after evil + :config + (setq evil-collection-mode-list '(dashboard dired)) + (evil-collection-init)) + +;; Dashboard +(use-package dashboard + :ensure t + :init ;; tweak dashboard config before loading it + (setq dashboard-set-heading-icons t) + (setq dashboard-set-file-icons t) + (setq dashboard-banner-logo-title "Welcome back to Emacs, Maddie!") + (setq dashboard-startup-banner 'logo) ;; use standard emacs logo as banner + ;;(setq dashboard-startup-banner "~/.config/emacs/emacs.png") ;; use custom image as banner + (setq dashboard-center-content nil) ;; set to 't' for centered content + (setq dashboard-items '((recents . 5) + (agenda . 5 ) + (bookmarks . 3) + ;; (projects . 3) + (registers . 3))) + :config + (dashboard-setup-startup-hook) + (dashboard-modify-heading-icons '((recents . "file-text") + (bookmarks . "book")))) + +;; Command completion +(use-package vertico + :ensure t + :config + (vertico-mode 1)) + +;; Rust +(use-package rust-mode + :ensure t) + +;; Nix +(use-package nix-mode + :ensure t) + +;; Git +(use-package magit + :ensure t + :bind (("C-x g" . magit-status) + ("C-x C-g" . magit-status))) + +;; Markdown mode +(use-package markdown-mode + :ensure t) + +;; Treemacs +(use-package treemacs + :ensure t + :defer t + :init + (with-eval-after-load 'winum + (define-key winum-keymap (kbd "M-0") #'treemacs-select-window)) + :config + (progn + (setq treemacs-collapse-dirs (if treemacs-python-executable 3 0) + treemacs-deferred-git-apply-delay 0.5 + treemacs-directory-name-transformer #'identity + treemacs-display-in-side-window t + treemacs-eldoc-display 'simple + treemacs-file-event-delay 2000 + treemacs-file-extension-regex treemacs-last-period-regex-value + treemacs-file-follow-delay 0.2 + treemacs-file-name-transformer #'identity + treemacs-follow-after-init t + treemacs-expand-after-init t + treemacs-find-workspace-method 'find-for-file-or-pick-first + treemacs-git-command-pipe "" + treemacs-goto-tag-strategy 'refetch-index + treemacs-header-scroll-indicators '(nil . "^^^^^^") + treemacs-hide-dot-git-directory t + treemacs-indentation 2 + treemacs-indentation-string " " + treemacs-is-never-other-window nil + treemacs-max-git-entries 5000 + treemacs-missing-project-action 'ask + treemacs-move-forward-on-expand nil + treemacs-no-png-images nil + treemacs-no-delete-other-windows t + treemacs-project-follow-cleanup nil + treemacs-persist-file (expand-file-name ".cache/treemacs-persist" user-emacs-directory) + treemacs-position 'left + treemacs-read-string-input 'from-child-frame + treemacs-recenter-distance 0.1 + treemacs-recenter-after-file-follow nil + treemacs-recenter-after-tag-follow nil + treemacs-recenter-after-project-jump 'always + treemacs-recenter-after-project-expand 'on-distance + treemacs-litter-directories '("/node_modules" "/.venv" "/.cask") + treemacs-project-follow-into-home nil + treemacs-show-cursor nil + treemacs-show-hidden-files t + treemacs-silent-filewatch nil + treemacs-silent-refresh nil + treemacs-sorting 'alphabetic-asc + treemacs-select-when-already-in-treemacs 'move-back + treemacs-space-between-root-nodes t + treemacs-tag-follow-cleanup t + treemacs-tag-follow-delay 1.5 + treemacs-text-scale nil + treemacs-user-mode-line-format nil + treemacs-user-header-line-format nil + treemacs-wide-toggle-width 70 + treemacs-width 35 + treemacs-width-increment 1 + treemacs-width-is-initially-locked t + treemacs-workspace-switch-cleanup nil) + + (treemacs-resize-icons 22) + (treemacs-follow-mode t) + (treemacs-filewatch-mode t) + (treemacs-fringe-indicator-mode 'always) + (when treemacs-python-executable + (treemacs-git-commit-diff-mode t)) + + (treemacs-hide-gitignored-files-mode nil)) + :bind + (:map global-map + ("M-0" . treemacs-select-window) + ("C-x t 1" . treemacs-delete-other-windows) + ("C-x t t" . treemacs) + ("C-x t d" . treemacs-select-directory) + ("C-x t B" . treemacs-bookmark) + ("C-x t C-t" . treemacs-find-file) + ("C-x t M-t" . treemacs-find-tag))) + +(use-package treemacs-evil + :after (treemacs evil) + :ensure t) + +;; Keybindings +(use-package general + :ensure t + :config + (general-evil-setup t)) + +(nvmap :prefix "SPC" + "b b" '(ibuffer :which-key "Ibuffer") + "b c" '(clone-indirect-buffer-other-window :which-key "Clone indirect buffer other window") + "b k" '(kill-current-buffer :which-key "Kill current buffer") + "b n" '(next-buffer :which-key "Next buffer") + "b p" '(previous-buffer :which-key "Previous buffer") + "b B" '(ibuffer-list-buffers :which-key "Ibuffer list buffers") + "b K" '(kill-buffer :which-key "Kill buffer")) + +;; Set backup and autosave directories +(setq backup-directory-alist + `(("." . "~/.local/share/emacs/backups"))) +(setq auto-save-file-name-transforms + `((".*" "~/.local/share/emacs/auto-save-list/" t))) + +;; Disable the bell +(setq visible-bell nil + ring-bell-function #'ignore) + +;; Font +(set-face-attribute 'default nil + :font "Iosevka Nerd Font" + :height 150 + :weight 'medium) +(add-to-list 'default-frame-alist '(font . "Iosevka Nerd Font-13")) + +;; UI +(menu-bar-mode -1) +(tool-bar-mode -1) +(scroll-bar-mode -1) +(column-number-mode 1) +(global-display-line-numbers-mode 1) +(setq display-line-numbers-type 'relative) +(setq inhibit-startup-screen t) +(setq dired-listing-switches "-alh") + +;; Editor +(setq scroll-preserve-screen-position nil) +(setq scroll-conservatively 101) +(setq default-tab-width 2) + +;; Themes +(use-package gruber-darker-theme + :ensure t) +(use-package atom-one-dark-theme + :ensure t) +(load-theme 'gruber-darker t) + +;; Setting garbage collection threshold +(setq gc-cons-threshold 402653184 + gc-cons-percentage 0.6) + +;; Profile emacs startup +(add-hook 'emacs-startup-hook + (lambda () + (message "*** Emacs loaded in %s with %d garbage collections." + (format "%.2f seconds" + (float-time + (time-subtract after-init-time before-init-time))) + gcs-done))) + +;; Silence compiler warnings as they can be pretty disruptive +(if (boundp 'comp-deferred-compilation) + (setq comp-deferred-compilation nil) + (setq native-comp-deferred-compilation nil)) +;; In noninteractive sessions, prioritize non-byte-compiled source files to +;; prevent the use of stale byte-code. Otherwise, it saves us a little IO time +;; to skip the mtime checks on every *.elc file. +(setq load-prefer-newer noninteractive) + +(custom-set-variables + ;; custom-set-variables was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + '(package-selected-packages + '(markdown-mode atom-one-dark-theme treemacs-evil treemacs gruber-darker-theme gruber-darker nix-mode vertico evil evil-collection dashboard general))) +(custom-set-faces + ;; custom-set-faces was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + ) diff --git a/maddie/common/esa.nix b/maddie/common/esa.nix new file mode 100644 index 0000000..7d4167b --- /dev/null +++ b/maddie/common/esa.nix @@ -0,0 +1,16 @@ +{ config, ... }: + +{ + programs.eza = { + enable = true; + enableAliases = true; + extraOptions = [ + "--group-directories-first" + "--time-style=long-iso" + "--git" + "-h" + "-g" + ]; + icons = true; + }; +} diff --git a/maddie/common/fetch.nix b/maddie/common/fetch.nix new file mode 100644 index 0000000..b32cf64 --- /dev/null +++ b/maddie/common/fetch.nix @@ -0,0 +1,9 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + pridefetch # System stats with pride flags + neofetch # Generic system stats + pfetch # Simple system stats + ]; +} diff --git a/maddie/common/git.nix b/maddie/common/git.nix new file mode 100644 index 0000000..9272d76 --- /dev/null +++ b/maddie/common/git.nix @@ -0,0 +1,51 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + gh + git-review + ]; + + home.file.".local/bin/git-sync" = { + source = ./git/git-sync.sh; + executable = true; + }; + + programs.git = { + enable = true; + lfs.enable = true; + + userName = "Madeleine"; + userEmail = "maddie@spyhoodle.me"; + signing = { + key = "FA50688B9EB6D8AA070C8241C296DE8C9053683F"; + signByDefault = true; + gpgPath = "/run/current-system/sw/bin/gpg"; + }; + + aliases = { + graph = "log --graph --oneline --decorate"; + unstage = "reset HEAD --"; + co = "checkout"; + br = "branch"; + ci = "commit"; + st = "status"; + ps = "push"; + }; + + extraConfig = { + init.defaultBranch = "development"; + pull.rebase = "merges"; + core.sshCommand = "/run/current-system/sw/bin/ssh"; + }; + + ignores = [ + "**/.DS_Store" + "**/._.DS_Store" + ".DS_Store" + "._.DS_Store" + "**/*.swp" + "*.swp" + ]; + }; +} diff --git a/maddie/common/git/git-sync.sh b/maddie/common/git/git-sync.sh new file mode 100644 index 0000000..14e18d8 --- /dev/null +++ b/maddie/common/git/git-sync.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env sh + +git add . +git commit -am "$(date -I)" +git pull +git push diff --git a/maddie/common/helix.nix b/maddie/common/helix.nix new file mode 100644 index 0000000..b67c29c --- /dev/null +++ b/maddie/common/helix.nix @@ -0,0 +1,21 @@ +{ config, ... }: + +{ + programs.helix = { + enable = true; + /* languages = [ + { + name = "rust"; + auto-format = true; + } + ]; */ + settings = { + theme = "onedark"; + keys.normal = { + space.space = "file_picker"; + space.w = ":w"; + space.q = ":q"; + }; + }; + }; +} diff --git a/maddie/common/htop.nix b/maddie/common/htop.nix new file mode 100644 index 0000000..729222c --- /dev/null +++ b/maddie/common/htop.nix @@ -0,0 +1,19 @@ +{ config, pkgs, ... }: + +{ + programs.htop = { + enable = true; + package = pkgs.htop-vim; + settings = { + hide_kernel_threads = 1; + hide_userland_threads = 1; + highlight_base_name = 1; + show_cpu_usage = 1; + show_cpu_frequency = 1; + show_cpu_temperature = 1; + degree_fahrenheit = 0; + enable_mouse = 1; + tree_view = 1; + }; + }; +} diff --git a/maddie/common/java.nix b/maddie/common/java.nix new file mode 100644 index 0000000..8780cc6 --- /dev/null +++ b/maddie/common/java.nix @@ -0,0 +1,7 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + jdk8 + ]; +} diff --git a/maddie/common/kakoune.nix b/maddie/common/kakoune.nix new file mode 100644 index 0000000..fbc26ec --- /dev/null +++ b/maddie/common/kakoune.nix @@ -0,0 +1,77 @@ +{ config, pkgs, ... }: + +{ + programs.kakoune = { + enable = true; + config = { + numberLines = { + enable = true; + relative = true; + + }; + scrollOff.lines = 3; + showWhitespace.enable = false; + tabStop = 4; + colorScheme = "one-dark"; + ui = { + statusLine = "top"; + assistant = "cat"; + enableMouse = true; + setTitle = true; + }; + hooks = [ + { + name = "WinSetOption"; + option = "filetype=nix"; + commands = '' + set-option window indentwidth 2 + set-option window formatcmd nixpkgs-fmt + ''; + } + ]; + }; + plugins = with pkgs.kakounePlugins; [ + kakoune-rainbow + powerline-kak + auto-pairs-kak + pkgs.kak-lsp + ]; + extraConfig = '' + # Tabs + hook global InsertChar \t %{ exec -draft h@ } + add-highlighter global/ show-whitespaces -tab '│' -tabpad '╌' + + # Kak-LSP + eval %sh{kak-lsp --kakoune -s $kak_session} + lsp-enable + + # Modeline + declare-option bool lsp_enabled false + declare-option -hidden str lsp_modeline_progress "" + define-command -hidden -params 6 -override lsp-handle-progress %{ + set-option global lsp_modeline_progress %sh{ + if ! "$6"; then + echo "$2\$\{5:+" ($5%)"}\$\{4:+": $4"}" + fi + } + } + + declare-option -hidden str modeline_git_branch + hook global WinDisplay .* %{ + set-option window modeline_git_branch %sh{ + branch=$(git -C "\$\{kak_buffile%/*}" rev-parse --abbrev-ref HEAD 2>/dev/null) + if [ -n "$branch" ]; then + printf "$branch " + fi + } + } + + set-option global modelinefmt '%opt{lsp_modeline_progress} {StatusLine}{string}%opt{modeline_git_branch}{type}%sh{ [ -n "$kak_opt_filetype" ] && echo "$kak_opt_filetype " }{default}%val{bufname}{{context_info}}{default} {{mode_info}} {meta}%val{cursor_line}:%val{cursor_char_column}' + ''; + }; + + xdg.configFile."kak/colors" = { + source = ./kakoune/colors; + recursive = true; + }; +} diff --git a/maddie/common/kakoune/colors/one-dark-16.kak b/maddie/common/kakoune/colors/one-dark-16.kak new file mode 100644 index 0000000..ec8da3d --- /dev/null +++ b/maddie/common/kakoune/colors/one-dark-16.kak @@ -0,0 +1,93 @@ +# CODE + +set-face global value yellow +set-face global type yellow +set-face global variable red +set-face global module yellow +set-face global function blue +set-face global string green +set-face global keyword magenta +set-face global operator white +set-face global attribute cyan +set-face global comment white+d +set-face global documentation white+d +set-face global meta cyan +set-face global builtin yellow + +# MARKUP + +set-face global title yellow +set-face global header green +set-face global mono cyan +set-face global block magenta +set-face global link blue +set-face global bullet yellow +set-face global list white + +# BUILTIN + +set-face global Default white +set-face global PrimarySelection black,blue +set-face global SecondarySelection black,green +set-face global PrimaryCursor black,white +set-face global SecondaryCursor black,cyan +set-face global PrimaryCursorEol black,red +set-face global SecondaryCursorEol black,red +set-face global LineNumbers white +set-face global LineNumberCursor yellow +set-face global LineNumbersWrapped black +set-face global MenuForeground blue +set-face global MenuBackground default +set-face global MenuInfo green +set-face global Information default +set-face global Error red +set-face global StatusLine default +set-face global StatusLineMode yellow +set-face global StatusLineInfo blue +set-face global StatusLineValue white +set-face global StatusCursor black,blue +set-face global Prompt blue +set-face global MatchingChar +bu +set-face global BufferPadding black +set-face global Whitespace white+d + +# PLUGINS + +# kak-lsp +set-face global InlayHint +d@type +set-face global parameter +i@variable +set-face global enum cyan +set-face global InlayDiagnosticError red +set-face global InlayDiagnosticWarning yellow +set-face global InlayDiagnosticInfo blue +set-face global InlayDiagnosticHint white +set-face global LineFlagError red +set-face global LineFlagWarning yellow +set-face global LineFlagInfo blue +set-face global LineFlagHint white +set-face global DiagnosticError +u +set-face global DiagnosticWarning +u +set-face global DiagnosticInfo +u +set-face global DiagnosticHint +u +# Infobox faces +set-face global InfoDefault Information +set-face global InfoBlock block +set-face global InfoBlockQuote block +set-face global InfoBullet bullet +set-face global InfoHeader header +set-face global InfoLink link +set-face global InfoLinkMono header +set-face global InfoMono mono +set-face global InfoRule comment +set-face global InfoDiagnosticError InlayDiagnosticError +set-face global InfoDiagnosticHint InlayDiagnosticHint +set-face global InfoDiagnosticInformation InlayDiagnosticInfo +set-face global InfoDiagnosticWarning InlayDiagnosticWarning + +# kak-rainbower +try %{ set-option global rainbow_colors yellow magenta blue } + +# For backwards compatibility +define-command -override -hidden one-enable-fancy-underlines %{ + echo -debug "one-enable-fancy-underlines is deprecated - curly underlines are enabled by default" +} diff --git a/maddie/common/kakoune/colors/one-dark.kak b/maddie/common/kakoune/colors/one-dark.kak new file mode 100644 index 0000000..f7e719e --- /dev/null +++ b/maddie/common/kakoune/colors/one-dark.kak @@ -0,0 +1,117 @@ +# One Dark + +declare-option str fg "abb2bf" +declare-option str bg "282c34" +declare-option str subbg "373c47" + +declare-option str lightred "e06c75" +declare-option str darkred "be5046" +declare-option str green "98c379" +declare-option str lightorange "e5c07b" +declare-option str darkorange "d19a66" +declare-option str blue "61afef" +declare-option str magenta "c678dd" +declare-option str cyan "56b6c2" + +declare-option str comment "5c6370" +declare-option str hint "ffffff" + +declare-option str cursoralpha "80" +declare-option str selectionalpha "40" + +# Menus do not support transparency, so we must hardcode the selection + sub bg colors +declare-option str menuselection "405770" + +# CODE + +set-face global value "rgb:%opt{darkorange}" +set-face global type "rgb:%opt{lightorange}" +set-face global variable "rgb:%opt{lightred}" +set-face global module "rgb:%opt{lightorange}" +set-face global function "rgb:%opt{blue}" +set-face global string "rgb:%opt{green}" +set-face global keyword "rgb:%opt{magenta}" +set-face global operator "rgb:%opt{fg}" +set-face global attribute "rgb:%opt{cyan}" +set-face global comment "rgb:%opt{comment}" +set-face global documentation "rgb:%opt{comment}" +set-face global meta "rgb:%opt{cyan}" +set-face global builtin "rgb:%opt{lightorange}" + +# MARKUP + +set-face global title "rgb:%opt{darkorange}" +set-face global header "rgb:%opt{green}" +set-face global mono "rgb:%opt{cyan}" +set-face global block "rgb:%opt{magenta}" +set-face global link "rgb:%opt{blue}" +set-face global bullet "rgb:%opt{lightorange}" +set-face global list "rgb:%opt{fg}" + +# BUILTIN + +set-face global Default "rgb:%opt{fg},rgb:%opt{bg}" +set-face global PrimarySelection "default,rgba:%opt{blue}%opt{selectionalpha}" +set-face global SecondarySelection "default,rgba:%opt{green}%opt{selectionalpha}" +set-face global PrimaryCursor "default,rgba:%opt{blue}%opt{cursoralpha}" +set-face global SecondaryCursor "default,rgba:%opt{green}%opt{cursoralpha}" +set-face global PrimaryCursorEol "default,rgba:%opt{lightred}%opt{cursoralpha}" +set-face global SecondaryCursorEol "default,rgba:%opt{darkorange}%opt{cursoralpha}" +set-face global LineNumbers "rgb:%opt{comment}" +set-face global LineNumberCursor "rgb:%opt{darkorange}" +set-face global LineNumbersWrapped "rgb:%opt{bg},rgb:%opt{bg}" +set-face global MenuForeground "rgb:%opt{fg},rgb:%opt{menuselection}" +set-face global MenuBackground "rgb:%opt{fg},rgb:%opt{subbg}" +set-face global MenuInfo "rgb:%opt{green}" +set-face global Information "rgb:%opt{fg},rgb:%opt{subbg}" +set-face global Error "rgb:%opt{lightred}" +set-face global StatusLine "rgb:%opt{fg},rgb:%opt{subbg}" +set-face global StatusLineMode "rgb:%opt{darkorange}" +set-face global StatusLineInfo "rgb:%opt{blue}" +set-face global StatusLineValue "rgb:%opt{fg}" +set-face global StatusCursor "default,rgba:%opt{blue}%opt{cursoralpha}" +set-face global Prompt "rgb:%opt{blue}" +set-face global MatchingChar "default,rgb:%opt{subbg}" +set-face global BufferPadding "rgb:%opt{bg},rgb:%opt{bg}" +set-face global Whitespace "rgb:%opt{comment}" + +# PLUGINS + +# kak-lsp +set-face global InlayHint "+d@type" +set-face global parameter "+i@variable" +set-face global enum "rgb:%opt{cyan}" +set-face global InlayDiagnosticError "rgb:%opt{lightred}" +set-face global InlayDiagnosticWarning "rgb:%opt{lightorange}" +set-face global InlayDiagnosticInfo "rgb:%opt{blue}" +set-face global InlayDiagnosticHint "rgb:%opt{hint}" +set-face global LineFlagError "rgb:%opt{lightred}" +set-face global LineFlagWarning "rgb:%opt{lightorange}" +set-face global LineFlagInfo "rgb:%opt{blue}" +set-face global LineFlagHint "rgb:%opt{hint}" +set-face global DiagnosticError ",,rgb:%opt{lightred}+c" +set-face global DiagnosticWarning ",,rgb:%opt{lightorange}+c" +set-face global DiagnosticInfo ",,rgb:%opt{blue}+c" +set-face global DiagnosticHint ",,rgb:%opt{hint}+u" +# Infobox faces +set-face global InfoDefault Information +set-face global InfoBlock block +set-face global InfoBlockQuote block +set-face global InfoBullet bullet +set-face global InfoHeader header +set-face global InfoLink link +set-face global InfoLinkMono header +set-face global InfoMono mono +set-face global InfoRule comment +set-face global InfoDiagnosticError InlayDiagnosticError +set-face global InfoDiagnosticHint InlayDiagnosticHint +set-face global InfoDiagnosticInformation InlayDiagnosticInfo +set-face global InfoDiagnosticWarning InlayDiagnosticWarning + +# kak-rainbower +try %{ set-option global rainbow_colors "rgb:%opt{lightorange}" "rgb:%opt{magenta}" "rgb:%opt{blue}" } + +# For backwards compatibility +define-command -override -hidden one-enable-fancy-underlines %{ + echo -debug "one-enable-fancy-underlines is deprecated - curly underlines are enabled by default" +} diff --git a/maddie/common/kakoune/colors/one-darker-16.kak b/maddie/common/kakoune/colors/one-darker-16.kak new file mode 100644 index 0000000..6d5dc56 --- /dev/null +++ b/maddie/common/kakoune/colors/one-darker-16.kak @@ -0,0 +1,101 @@ +# CODE + +set-face global value yellow +set-face global type yellow +set-face global variable white +set-face global module yellow +set-face global function blue +set-face global string green +set-face global keyword magenta +set-face global operator red +set-face global attribute cyan +set-face global comment white+d +set-face global documentation white+d +set-face global meta cyan +set-face global builtin yellow + +# MARKUP + +set-face global title yellow +set-face global header green +set-face global mono cyan +set-face global block magenta +set-face global link blue +set-face global bullet yellow +set-face global list white + +# BUILTIN + +set-face global Default white +set-face global PrimarySelection black,blue +set-face global SecondarySelection black,green +set-face global PrimaryCursor black,white +set-face global SecondaryCursor black,cyan +set-face global PrimaryCursorEol black,red +set-face global SecondaryCursorEol black,red +set-face global LineNumbers white +set-face global LineNumberCursor yellow +set-face global LineNumbersWrapped black +set-face global MenuForeground blue +set-face global MenuBackground default +set-face global MenuInfo green +set-face global Information default +set-face global Error red +set-face global StatusLine default +set-face global StatusLineMode yellow +set-face global StatusLineInfo blue +set-face global StatusLineValue white +set-face global StatusCursor black,blue +set-face global Prompt blue +set-face global MatchingChar +bu +set-face global BufferPadding black +set-face global Whitespace white+d + +# PLUGINS + +# kak-lsp +set-face global InlayHint +d@type +set-face global parameter +i@variable +set-face global enum cyan +set-face global InlayDiagnosticError red +set-face global InlayDiagnosticWarning yellow +set-face global InlayDiagnosticInfo blue +set-face global InlayDiagnosticHint white +set-face global LineFlagError red +set-face global LineFlagWarning yellow +set-face global LineFlagInfo blue +set-face global LineFlagHint white +set-face global DiagnosticError +u +set-face global DiagnosticWarning +u +set-face global DiagnosticInfo +u +set-face global DiagnosticHint +u +# Infobox faces +set-face global InfoDefault Information +set-face global InfoBlock block +set-face global InfoBlockQuote block +set-face global InfoBullet bullet +set-face global InfoHeader header +set-face global InfoLink link +set-face global InfoLinkMono header +set-face global InfoMono mono +set-face global InfoRule comment +set-face global InfoDiagnosticError InlayDiagnosticError +set-face global InfoDiagnosticHint InlayDiagnosticHint +set-face global InfoDiagnosticInformation InlayDiagnosticInfo +set-face global InfoDiagnosticWarning InlayDiagnosticWarning + +# kak-rainbower +try %{ set-option global rainbow_colors yellow magenta blue } + +# For backwards compatibility +define-command -override -hidden one-enable-fancy-underlines %{ + echo -debug "one-enable-fancy-underlines is deprecated - curly underlines are enabled by default" +} + +# Hardcoded selection + bg colors +# set-face global PrimarySelection default,rgb:2a3f53 +# set-face global SecondarySelection default,rgb:384435 +# set-face global PrimaryCursor default,rgb:3c6487 +# set-face global SecondaryCursor default,rgb:586e4c +# set-face global PrimaryCursorEol default,rgb:7c434a +# set-face global SecondaryCursorEol default,rgb:7c434a diff --git a/maddie/common/kakoune/colors/one-darker.kak b/maddie/common/kakoune/colors/one-darker.kak new file mode 100644 index 0000000..f92265b --- /dev/null +++ b/maddie/common/kakoune/colors/one-darker.kak @@ -0,0 +1,125 @@ +# One Darker +# This theme is a personalized implementation of One Dark. +# Changes include: +# - Darker background color +# - Variables are white instead of red +# - Operators are red instead of white +# - Comments are more visible + +# COLORS + +declare-option str fg "abb2bf" +declare-option str bg "181a1f" +declare-option str subbg "272b33" + +declare-option str lightred "e06c75" +declare-option str darkred "be5046" +declare-option str green "98c379" +declare-option str lightorange "e5c07b" +declare-option str darkorange "d19a66" +declare-option str blue "61afef" +declare-option str magenta "c678dd" +declare-option str cyan "56b6c2" + +declare-option str comment "70798a" +declare-option str hint "ffffff" + +declare-option str cursoralpha "80" +declare-option str selectionalpha "40" + +# Menus do not support transparency, so we must hardcode the selection + sub bg colors +declare-option str menuselection "344b61" + +# CODE + +set-face global value "rgb:%opt{darkorange}" +set-face global type "rgb:%opt{lightorange}" +set-face global variable "rgb:%opt{fg}" +set-face global module "rgb:%opt{lightorange}" +set-face global function "rgb:%opt{blue}" +set-face global string "rgb:%opt{green}" +set-face global keyword "rgb:%opt{magenta}" +set-face global operator "rgb:%opt{lightred}" +set-face global attribute "rgb:%opt{cyan}" +set-face global comment "rgb:%opt{comment}" +set-face global documentation "rgb:%opt{comment}" +set-face global meta "rgb:%opt{cyan}" +set-face global builtin "rgb:%opt{lightorange}" + +# MARKUP + +set-face global title "rgb:%opt{darkorange}" +set-face global header "rgb:%opt{green}" +set-face global mono "rgb:%opt{cyan}" +set-face global block "rgb:%opt{magenta}" +set-face global link "rgb:%opt{blue}" +set-face global bullet "rgb:%opt{lightorange}" +set-face global list "rgb:%opt{fg}" + +# BUILTIN + +set-face global Default "rgb:%opt{fg},rgb:%opt{bg}" +set-face global PrimarySelection "default,rgba:%opt{blue}%opt{selectionalpha}" +set-face global SecondarySelection "default,rgba:%opt{green}%opt{selectionalpha}" +set-face global PrimaryCursor "default,rgba:%opt{blue}%opt{cursoralpha}" +set-face global SecondaryCursor "default,rgba:%opt{green}%opt{cursoralpha}" +set-face global PrimaryCursorEol "default,rgba:%opt{lightred}%opt{cursoralpha}" +set-face global SecondaryCursorEol "default,rgba:%opt{darkorange}%opt{cursoralpha}" +set-face global LineNumbers "rgb:%opt{comment}" +set-face global LineNumberCursor "rgb:%opt{darkorange}" +set-face global LineNumbersWrapped "rgb:%opt{bg},rgb:%opt{bg}" +set-face global MenuForeground "rgb:%opt{fg},rgb:%opt{menuselection}" +set-face global MenuBackground "rgb:%opt{fg},rgb:%opt{subbg}" +set-face global MenuInfo "rgb:%opt{green}" +set-face global Information "rgb:%opt{fg},rgb:%opt{subbg}" +set-face global Error "rgb:%opt{lightred}" +set-face global StatusLine "rgb:%opt{fg},rgb:%opt{subbg}" +set-face global StatusLineMode "rgb:%opt{darkorange}" +set-face global StatusLineInfo "rgb:%opt{blue}" +set-face global StatusLineValue "rgb:%opt{fg}" +set-face global StatusCursor "default,rgba:%opt{blue}%opt{cursoralpha}" +set-face global Prompt "rgb:%opt{blue}" +set-face global MatchingChar "default,rgb:%opt{subbg}" +set-face global BufferPadding "rgb:%opt{bg},rgb:%opt{bg}" +set-face global Whitespace "rgb:%opt{comment}" + +# PLUGINS + +# kak-lsp +set-face global InlayHint "+d@type" +set-face global parameter "+i@variable" +set-face global enum "rgb:%opt{cyan}" +set-face global InlayDiagnosticError "rgb:%opt{lightred}" +set-face global InlayDiagnosticWarning "rgb:%opt{lightorange}" +set-face global InlayDiagnosticInfo "rgb:%opt{blue}" +set-face global InlayDiagnosticHint "rgb:%opt{hint}" +set-face global LineFlagError "rgb:%opt{lightred}" +set-face global LineFlagWarning "rgb:%opt{lightorange}" +set-face global LineFlagInfo "rgb:%opt{blue}" +set-face global LineFlagHint "rgb:%opt{hint}" +set-face global DiagnosticError ",,rgb:%opt{lightred}+c" +set-face global DiagnosticWarning ",,rgb:%opt{lightorange}+c" +set-face global DiagnosticInfo ",,rgb:%opt{blue}+c" +set-face global DiagnosticHint ",,rgb:%opt{hint}+u" +# Infobox faces +set-face global InfoDefault Information +set-face global InfoBlock block +set-face global InfoBlockQuote block +set-face global InfoBullet bullet +set-face global InfoHeader header +set-face global InfoLink link +set-face global InfoLinkMono header +set-face global InfoMono mono +set-face global InfoRule comment +set-face global InfoDiagnosticError InlayDiagnosticError +set-face global InfoDiagnosticHint InlayDiagnosticHint +set-face global InfoDiagnosticInformation InlayDiagnosticInfo +set-face global InfoDiagnosticWarning InlayDiagnosticWarning + +# kak-rainbower +try %{ set-option global rainbow_colors "rgb:%opt{lightorange}" "rgb:%opt{magenta}" "rgb:%opt{blue}" } + +# For backwards compatibility +define-command -override -hidden one-enable-fancy-underlines %{ + echo -debug "one-enable-fancy-underlines is deprecated - curly underlines are enabled by default" +} diff --git a/maddie/common/kakoune/colors/one-light-16.kak b/maddie/common/kakoune/colors/one-light-16.kak new file mode 100644 index 0000000..60e1689 --- /dev/null +++ b/maddie/common/kakoune/colors/one-light-16.kak @@ -0,0 +1,93 @@ +# CODE + +set-face global value yellow +set-face global type yellow +set-face global variable red +set-face global module yellow +set-face global function blue +set-face global string green +set-face global keyword magenta +set-face global operator black +set-face global attribute cyan +set-face global comment black+d +set-face global documentation black+d +set-face global meta cyan +set-face global builtin yellow + +# MARKUP + +set-face global title yellow +set-face global header green +set-face global mono cyan +set-face global block magenta +set-face global link blue +set-face global bullet yellow +set-face global list white + +# BUILTIN + +set-face global Default black +set-face global PrimarySelection black,blue +set-face global SecondarySelection black,green +set-face global PrimaryCursor black,white +set-face global SecondaryCursor black,cyan +set-face global PrimaryCursorEol black,red +set-face global SecondaryCursorEol black,red +set-face global LineNumbers black +set-face global LineNumberCursor yellow +set-face global LineNumbersWrapped white +set-face global MenuForeground blue +set-face global MenuBackground default +set-face global MenuInfo green +set-face global Information default +set-face global Error red +set-face global StatusLine default +set-face global StatusLineMode yellow +set-face global StatusLineInfo blue +set-face global StatusLineValue white +set-face global StatusCursor black,blue +set-face global Prompt blue +set-face global MatchingChar +bu +set-face global BufferPadding white +set-face global Whitespace black+d + +# PLUGINS + +# kak-lsp +set-face global InlayHint +d@type +set-face global parameter +i@variable +set-face global enum cyan +set-face global InlayDiagnosticError red +set-face global InlayDiagnosticWarning yellow +set-face global InlayDiagnosticInfo blue +set-face global InlayDiagnosticHint white +set-face global LineFlagError red +set-face global LineFlagWarning yellow +set-face global LineFlagInfo blue +set-face global LineFlagHint white +set-face global DiagnosticError +u +set-face global DiagnosticWarning +u +set-face global DiagnosticInfo +u +set-face global DiagnosticHint +u +# Infobox faces +set-face global InfoDefault Information +set-face global InfoBlock block +set-face global InfoBlockQuote block +set-face global InfoBullet bullet +set-face global InfoHeader header +set-face global InfoLink link +set-face global InfoLinkMono header +set-face global InfoMono mono +set-face global InfoRule comment +set-face global InfoDiagnosticError InlayDiagnosticError +set-face global InfoDiagnosticHint InlayDiagnosticHint +set-face global InfoDiagnosticInformation InlayDiagnosticInfo +set-face global InfoDiagnosticWarning InlayDiagnosticWarning + +# kak-rainbower +try %{ set-option global rainbow_colors yellow magenta blue } + +# For backwards compatibility +define-command -override -hidden one-enable-fancy-underlines %{ + echo -debug "one-enable-fancy-underlines is deprecated - curly underlines are enabled by default" +} diff --git a/maddie/common/kakoune/colors/one-light.kak b/maddie/common/kakoune/colors/one-light.kak new file mode 100644 index 0000000..79e6ca1 --- /dev/null +++ b/maddie/common/kakoune/colors/one-light.kak @@ -0,0 +1,117 @@ +# One Light + +declare-option str fg "4b4c54" +declare-option str bg "fafafa" +declare-option str subbg "e6e6e6" + +declare-option str lightred "e45649" +declare-option str darkred "ca1243" +declare-option str green "50a14f" +declare-option str lightorange "c18401" +declare-option str darkorange "986801" +declare-option str blue "4078f2" +declare-option str magenta "a626a4" +declare-option str cyan "0184bc" + +declare-option str comment "a0a1a7" +declare-option str hint "000000" + +declare-option str cursoralpha "80" +declare-option str selectionalpha "40" + +# Menus do not support transparency, so we must hardcode the selection + sub bg colors +declare-option str menuselection "bbc9e8" + +# CODE + +set-face global value "rgb:%opt{darkorange}" +set-face global type "rgb:%opt{lightorange}" +set-face global variable "rgb:%opt{lightred}" +set-face global module "rgb:%opt{lightorange}" +set-face global function "rgb:%opt{blue}" +set-face global string "rgb:%opt{green}" +set-face global keyword "rgb:%opt{magenta}" +set-face global operator "rgb:%opt{fg}" +set-face global attribute "rgb:%opt{cyan}" +set-face global comment "rgb:%opt{comment}" +set-face global documentation "rgb:%opt{comment}" +set-face global meta "rgb:%opt{cyan}" +set-face global builtin "rgb:%opt{lightorange}" + +# MARKUP + +set-face global title "rgb:%opt{darkorange}" +set-face global header "rgb:%opt{green}" +set-face global mono "rgb:%opt{cyan}" +set-face global block "rgb:%opt{magenta}" +set-face global link "rgb:%opt{blue}" +set-face global bullet "rgb:%opt{lightorange}" +set-face global list "rgb:%opt{fg}" + +# BUILTIN + +set-face global Default "rgb:%opt{fg},rgb:%opt{bg}" +set-face global PrimarySelection "default,rgba:%opt{blue}%opt{selectionalpha}" +set-face global SecondarySelection "default,rgba:%opt{green}%opt{selectionalpha}" +set-face global PrimaryCursor "default,rgba:%opt{blue}%opt{cursoralpha}" +set-face global SecondaryCursor "default,rgba:%opt{green}%opt{cursoralpha}" +set-face global PrimaryCursorEol "default,rgba:%opt{lightred}%opt{cursoralpha}" +set-face global SecondaryCursorEol "default,rgba:%opt{darkorange}%opt{cursoralpha}" +set-face global LineNumbers "rgb:%opt{comment}" +set-face global LineNumberCursor "rgb:%opt{darkorange}" +set-face global LineNumbersWrapped "rgb:%opt{bg},rgb:%opt{bg}" +set-face global MenuForeground "rgb:%opt{fg},rgb:%opt{menuselection}" +set-face global MenuBackground "rgb:%opt{fg},rgb:%opt{subbg}" +set-face global MenuInfo "rgb:%opt{green}" +set-face global Information "rgb:%opt{fg},rgb:%opt{subbg}" +set-face global Error "rgb:%opt{lightred}" +set-face global StatusLine "rgb:%opt{fg},rgb:%opt{subbg}" +set-face global StatusLineMode "rgb:%opt{darkorange}" +set-face global StatusLineInfo "rgb:%opt{blue}" +set-face global StatusLineValue "rgb:%opt{fg}" +set-face global StatusCursor "default,rgba:%opt{blue}%opt{cursoralpha}" +set-face global Prompt "rgb:%opt{blue}" +set-face global MatchingChar "default,rgb:%opt{subbg}" +set-face global BufferPadding "rgb:%opt{bg},rgb:%opt{bg}" +set-face global Whitespace "rgb:%opt{comment}" + +# PLUGINS + +# kak-lsp +set-face global InlayHint "+d@type" +set-face global parameter "+i@variable" +set-face global enum "rgb:%opt{cyan}" +set-face global InlayDiagnosticError "rgb:%opt{lightred}" +set-face global InlayDiagnosticWarning "rgb:%opt{lightorange}" +set-face global InlayDiagnosticInfo "rgb:%opt{blue}" +set-face global InlayDiagnosticHint "rgb:%opt{hint}" +set-face global LineFlagError "rgb:%opt{lightred}" +set-face global LineFlagWarning "rgb:%opt{lightorange}" +set-face global LineFlagInfo "rgb:%opt{blue}" +set-face global LineFlagHint "rgb:%opt{hint}" +set-face global DiagnosticError ",,rgb:%opt{lightred}+c" +set-face global DiagnosticWarning ",,rgb:%opt{lightorange}+c" +set-face global DiagnosticInfo ",,rgb:%opt{blue}+c" +set-face global DiagnosticHint ",,rgb:%opt{hint}+u" +# Infobox faces +set-face global InfoDefault Information +set-face global InfoBlock block +set-face global InfoBlockQuote block +set-face global InfoBullet bullet +set-face global InfoHeader header +set-face global InfoLink link +set-face global InfoLinkMono header +set-face global InfoMono mono +set-face global InfoRule comment +set-face global InfoDiagnosticError InlayDiagnosticError +set-face global InfoDiagnosticHint InlayDiagnosticHint +set-face global InfoDiagnosticInformation InlayDiagnosticInfo +set-face global InfoDiagnosticWarning InlayDiagnosticWarning + +# kak-rainbower +try %{ set-option global rainbow_colors "rgb:%opt{lightorange}" "rgb:%opt{magenta}" "rgb:%opt{blue}" } + +# For backwards compatibility +define-command -override -hidden one-enable-fancy-underlines %{ + echo -debug "one-enable-fancy-underlines is deprecated - curly underlines are enabled by default" +} diff --git a/maddie/common/latex.nix b/maddie/common/latex.nix new file mode 100644 index 0000000..938e7a7 --- /dev/null +++ b/maddie/common/latex.nix @@ -0,0 +1,8 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + #texliveFull + texlive.combined.scheme-full + ]; +} diff --git a/maddie/common/lf.nix b/maddie/common/lf.nix new file mode 100644 index 0000000..79bb0ee --- /dev/null +++ b/maddie/common/lf.nix @@ -0,0 +1,26 @@ +{ config, pkgs, ... }: + +{ + programs.lf = { + enable = true; + previewer.source = ./lf/scope; + settings = { + relativenumber = true; + number = true; + hidden = false; + preview = true; + icons = true; + }; + }; + + xdg.configFile = { + "lf/icons" = { + source = ./lf/icons; + }; + }; + + home.packages = with pkgs; [ + ueberzug + file + ]; +} diff --git a/maddie/common/lf/icons b/maddie/common/lf/icons new file mode 100644 index 0000000..82bcd50 --- /dev/null +++ b/maddie/common/lf/icons @@ -0,0 +1,93 @@ +di  +fi  +tw  +ow  +ln  +or  +ex  +*.txt  +*.mom  +*.me  +*.ms  +*.avif  +*.png  +*.webp  +*.ico  +*.gif  +*.tif  +*.tiff  +*.jpg  +*.jpe  +*.jpeg  +*.heif  +*.svg  +*.xcf  +*.gpg  +*.pdf  +*.djvu  +*.epub  +*.csv  +*.xlsx  +*.tex  +*.md  +*.mp3  +*.opus  +*.ogg  +*.m4a  +*.flac  +*.wav  +*.mkv  +*.mp4  +*.webm  +*.mpeg  +*.avi  +*.mov  +*.mpg  +*.wmv  +*.m4b  +*.flv  +*.zip  +*.rar  +*.7z  +*.tar  +*.gz  +*.z64 󰺷 +*.v64 󰺷 +*.n64 󰺷 +*.gdi 󰺷 +*.gba 󱎓 +*.nes 󰺶 +*.exe  +*.1  +*.nfo  +*.info  +*.log  +*.iso  +*.img  +*.bib  +*.part 󰋮 +*.torrent  +*.gitignore  +*.jar  +*.java  +*.r  +*.R  +*.rmd  +*.Rmd  +*.m  +*.rs  +*.go  +*.c  +*.cpp  +*.h  +*.py  +*.js  +*.json  +*.ts 󰛦 +*.sh  +*.html  +*.css  +*.xml  +*.php  +*.nix  +*.vim  diff --git a/maddie/common/lf/scope b/maddie/common/lf/scope new file mode 100644 index 0000000..c648d66 --- /dev/null +++ b/maddie/common/lf/scope @@ -0,0 +1,52 @@ +#!/usr/bin/env sh + +# File preview handler for lf. + +set -C -f +IFS="$(printf '%b_' '\n')"; IFS="${IFS%_}" + +image() { + if [ -f "$1" ] && [ -n "$DISPLAY" ] && [ -z "$WAYLAND_DISPLAY" ] && command -V ueberzug >/dev/null 2>&1; then + printf '{"action": "add", "identifier": "PREVIEW", "x": "%s", "y": "%s", "width": "%s", "height": "%s", "scaler": "contain", "path": "%s"}\n' "$4" "$5" "$(($2-1))" "$(($3-1))" "$1" > "$FIFO_UEBERZUG" + else + mediainfo "$6" + fi +} + +ifub() { + [ -n "$DISPLAY" ] && [ -z "$WAYLAND_DISPLAY" ] && command -V ueberzug >/dev/null 2>&1 +} + +# Note that the cache file name is a function of file information, meaning if +# an image appears in multiple places across the machine, it will not have to +# be regenerated once seen. + +case "$(file --dereference --brief --mime-type -- "$1")" in + image/avif) CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/lf/thumb.$(stat --printf '%n\0%i\0%F\0%s\0%W\0%Y' -- "$(readlink -f "$1")" | sha256sum | cut -d' ' -f1)" + [ ! -f "$CACHE" ] && convert "$1" "$CACHE.jpg" + image "$CACHE.jpg" "$2" "$3" "$4" "$5" "$1" ;; + image/*) image "$1" "$2" "$3" "$4" "$5" "$1" ;; + text/html) lynx -width="$4" -display_charset=utf-8 -dump "$1" ;; + text/troff) man ./ "$1" | col -b ;; + text/* | */xml | application/json) bat --terminal-width "$(($4-2))" -f "$1" ;; + audio/* | application/octet-stream) mediainfo "$1" || exit 1 ;; + video/* ) + CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/lf/thumb.$(stat --printf '%n\0%i\0%F\0%s\0%W\0%Y' -- "$(readlink -f "$1")" | sha256sum | cut -d' ' -f1)" + [ ! -f "$CACHE" ] && ffmpegthumbnailer -i "$1" -o "$CACHE" -s 0 + image "$CACHE" "$2" "$3" "$4" "$5" "$1" + ;; + */pdf) + CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/lf/thumb.$(stat --printf '%n\0%i\0%F\0%s\0%W\0%Y' -- "$(readlink -f "$1")" | sha256sum | cut -d' ' -f1)" + [ ! -f "$CACHE.jpg" ] && pdftoppm -jpeg -f 1 -singlefile "$1" "$CACHE" + image "$CACHE.jpg" "$2" "$3" "$4" "$5" "$1" + ;; + */epub+zip|*/mobi*) + CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/lf/thumb.$(stat --printf '%n\0%i\0%F\0%s\0%W\0%Y' -- "$(readlink -f "$1")" | sha256sum | cut -d' ' -f1)" + [ ! -f "$CACHE.jpg" ] && gnome-epub-thumbnailer "$1" "$CACHE.jpg" + image "$CACHE.jpg" "$2" "$3" "$4" "$5" "$1" + ;; + application/*zip) atool --list -- "$1" ;; + *opendocument*) odt2txt "$1" ;; + application/pgp-encrypted) gpg -d -- "$1" ;; +esac +exit 1 diff --git a/maddie/common/lsp.nix b/maddie/common/lsp.nix new file mode 100644 index 0000000..303b745 --- /dev/null +++ b/maddie/common/lsp.nix @@ -0,0 +1,14 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + nodejs + sumneko-lua-language-server + nodePackages.bash-language-server + nodePackages.vim-language-server + nodePackages.pyright + /* rust-analyzer */ + rnix-lsp + universal-ctags + ]; +} diff --git a/maddie/common/media.nix b/maddie/common/media.nix new file mode 100644 index 0000000..1d72376 --- /dev/null +++ b/maddie/common/media.nix @@ -0,0 +1,9 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + imagemagick # Manipulates images + libheif # Manage .heif files from phones + ffmpeg # Video manipulator + ]; +} diff --git a/maddie/common/mommy.nix b/maddie/common/mommy.nix new file mode 100644 index 0000000..d78da2a --- /dev/null +++ b/maddie/common/mommy.nix @@ -0,0 +1,12 @@ +{ config, ... }: + +{ + programs.zsh.initExtra = '' + precmd() { [ $? -ne 0 ] && $HOME/.local/bin/mommy -n } + ''; + + home.file.".local/bin/mommy" = { + source = ./mommy/shell-mommy.sh; + executable = true; + }; +} diff --git a/maddie/common/mommy/shell-mommy.sh b/maddie/common/mommy/shell-mommy.sh new file mode 100644 index 0000000..ac215eb --- /dev/null +++ b/maddie/common/mommy/shell-mommy.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env sh + +usage() { printf "usage: $0 [-pn]\n -p: positive response\n -n: negative response\n"; } +[ $# -eq 0 ] && usage && exit 0; + +[ -z "$MOMMYS_LITTLE" ] && MOMMYS_LITTLE="girl" +[ -z "$MOMMYS_PRONOUN" ] && MOMMYS_PRONOUN="her" +[ -z "$MOMMYS_ROLE" ] && MOMMYS_ROLE="mommy" +[ -z "$MOMMY_COLOR" ] && MOMMY_COLOR='\e[38;5;217m' +COLOR_RESET='\e[0m' + +negative() { + RESPONSES=( + "do you need $MOMMYS_ROLE's help~? ❤️" + "don't give up, my love~ ❤️" + "don't worry, $MOMMYS_ROLE is here to help you~ ❤️" + "I believe in you, my sweet $MOMMYS_LITTLE~ ❤️" + "it's okay to make mistakes, my dear~ ❤️" + "just a little further, sweetie~ ❤️" + "let's try again together, okay~? ❤️" + "$MOMMYS_ROLE believes in you, and knows you can overcome this~ ❤️" + "$MOMMYS_ROLE believes in you~ ❤️" + "$MOMMYS_ROLE is always here for you, no matter what~ ❤️" + "$MOMMYS_ROLE is here to help you through it~ ❤️" + "$MOMMYS_ROLE is proud of you for trying, no matter what the outcome~ ❤️" + "$MOMMYS_ROLE knows it's tough, but you can do it~ ❤️" + "$MOMMYS_ROLE knows $MOMMYS_PRONOUN little $MOMMYS_LITTLE can do better~ ❤️" + "$MOMMYS_ROLE knows you can do it, even if it's tough~ ❤️" + "$MOMMYS_ROLE knows you're feeling down, but you'll get through it~ ❤️" + "$MOMMYS_ROLE knows you're trying your best~ ❤️" + "$MOMMYS_ROLE loves you, and is here to support you~ ❤️" + "$MOMMYS_ROLE still loves you no matter what~ ❤️" + "you're doing your best, and that's all that matters to $MOMMYS_ROLE~ ❤️" + "$MOMMYS_ROLE is always here to encourage you~ ❤️" + ) +} + +positive() { + RESPONSES=( + "*pats your head*" + "awe, what a good $MOMMYS_LITTLE~\n$MOMMYS_ROLE knew you could do it~ ❤️" + "good $MOMMYS_LITTLE~\n$MOMMYS_ROLE's so proud of you~ ❤️" + "keep up the good work, my love~ ❤️" + "$MOMMYS_ROLE is proud of the progress you've made~ ❤️" + "$MOMMYS_ROLE is so grateful to have you as $MOMMYS_PRONOUN little $MOMMYS_LITTLE~ ❤️" + "I'm so proud of you, my love~ ❤️" + "$MOMMYS_ROLE is so proud of you~ ❤️" + "$MOMMYS_ROLE loves seeing $MOMMYS_PRONOUN little $MOMMYS_LITTLE succeed~ ❤️" + "$MOMMYS_ROLE thinks $MOMMYS_PRONOUN little $MOMMYS_LITTLE earned a big hug~ ❤️" + "that's a good $MOMMYS_LITTLE~ ❤️" + "you did an amazing job, my dear~ ❤️" + "you're such a smart cookie~ ❤️" + ) +} + +mommy_says() { + says=$1 + printf "$MOMMY_COLOR$says$COLOR_RESET\n" +} + +random() { + [ $1 == "positive" ] && positive + [ $1 == "negative" ] && negative + + index=$(($RANDOM % ${#RESPONSES[@]})) + response="${RESPONSES[$index]}" + + mommy_says "$response" +} + +while getopts "pn" options; do + case $options in + p) random "positive" ;; + n) random "negative" ;; + *) usage; exit 1 ;; + esac +done diff --git a/maddie/common/neovim.nix b/maddie/common/neovim.nix new file mode 100644 index 0000000..ef2b662 --- /dev/null +++ b/maddie/common/neovim.nix @@ -0,0 +1,13 @@ +{ config, pkgs, lib, ... }: + +{ + programs.neovim = { + enable = true; + defaultEditor = true; + }; + + xdg.configFile."nvim" = { + source = ./neovim; + recursive = true; + }; +} diff --git a/maddie/common/neovim/.gitignore b/maddie/common/neovim/.gitignore new file mode 100644 index 0000000..8cb205e --- /dev/null +++ b/maddie/common/neovim/.gitignore @@ -0,0 +1 @@ +plugin diff --git a/maddie/common/neovim/LICENSE b/maddie/common/neovim/LICENSE new file mode 100644 index 0000000..f608636 --- /dev/null +++ b/maddie/common/neovim/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 SpyHoodle + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/maddie/common/neovim/README.md b/maddie/common/neovim/README.md new file mode 100644 index 0000000..e509bf7 --- /dev/null +++ b/maddie/common/neovim/README.md @@ -0,0 +1,22 @@ +# Maddie's NeoVim config +A clean, fast, feature-rich IDE layer for my needs in [NeoVim](https://neovim.io/).
+Written in Lua, designed for NeoVim v0.7.0 or higher. + +## Some highlights + - Written entirely in Lua, making it clean and modern for NeoVim + - Uses [impatient.nvim](https://github.com/lewis6991/impatient.nvim) which greatly improves startup performance + - Uses the latest NeoVim LSP features & tree-sitter for highlighting + - Neat, small and structured files that are easy to read with some commenting + - Helpful features for programming such as highlighting indents & whitespaces + - Features for writing prose and taking notes, such as [vimwiki](https://github.com/vimwiki/vimwiki) and [orgmode](https://github.com/nvim-orgmode/orgmode) + - Extensible Lua written NeoVim specific package manager from [packer.nvim](https://github.com/wbthomason/packer.nvim) + - Modern standard Lua plugins such as [lualine.nvim](https://github.com/nvim-lualine/lualine.nvim) and [nvim-tree](https://github.com/kyazdani42/nvim-tree.lua) + - Fixed scrolling in terminals like st with patches and smooth scrolling + - Extra configuration for [Neovide](https://github.com/neovide/neovide), a graphical NeoVim client + - Shortcuts for tabs & splits with the leader key as space + - System clipboard, mouse and scrolling support + +## Work in progress! +I'm constantly updating and changing this configuration, by adding new plugins and settings.
+I likely won't make changes to make the config more acceptable and general to the public.
+Made with ❤️ and 🏳️‍⚧️. diff --git a/maddie/common/neovim/init.lua b/maddie/common/neovim/init.lua new file mode 100644 index 0000000..68daca1 --- /dev/null +++ b/maddie/common/neovim/init.lua @@ -0,0 +1,253 @@ +-- Basic vim config +require('basics') +require('keymaps') +require('colours') + +-- Packages +return require('packer').startup(function(use) + -- Neovim package manager + use 'wbthomason/packer.nvim' + + -- Atom's One Dark theme + use 'navarasu/onedark.nvim' + + -- Gruvbox theme + use 'ellisonleao/gruvbox.nvim' + + -- VSCode theme + use 'Mofiqul/vscode.nvim' + + -- Everforest theme + use 'sainnhe/everforest' + + -- Smooth scrolling + use 'psliwka/vim-smoothie' + + -- Comments in any language + use 'tpope/vim-commentary' + + -- Surrounding + use 'tpope/vim-surround' + + -- Repeating + use 'tpope/vim-repeat' + + -- Vim-wiki + use 'vimwiki/vimwiki' + + -- Rainbow brackets + use 'p00f/nvim-ts-rainbow' + + -- Git bindings + use 'tpope/vim-fugitive' + + -- Latex + use 'lervag/vimtex' + + -- Easy alignment + use 'junegunn/vim-easy-align' + + + -- Transparent background + use { + 'xiyaowong/nvim-transparent', + config = function() + vim.g.transparent_enabled = false + end + } + + -- Zen mode + use { + "folke/zen-mode.nvim", + config = function() + require('zen-mode').setup() + end + } + + -- Autosaving + use { + 'pocco81/auto-save.nvim', + config = function() + require('auto-save').setup({ + enabled = true, + execution_message = { + message = function() + return ('>w< autosaved at ' .. vim.fn.strftime('%H:%M:%S')) + end, + cleaning_interval = 1250 + }, + trigger_events = { 'InsertLeave', 'TextChanged' } + }) + end + } + + -- Git signs + use { + 'lewis6991/gitsigns.nvim', + config = function() + require('gitsigns').setup() + end + } + + -- Github Copilot + use { + 'zbirenbaum/copilot.lua', + event = { 'VimEnter' }, + config = function() + vim.defer_fn(function() + require('copilot').setup() + end, 100) + end + } + + -- Liveshare + use { + 'jbyuki/instant.nvim', + config = function() + vim.g.instant_username = "Maddie" + end + } + + -- Fuzzy finder + use { + 'nvim-telescope/telescope.nvim', + requires = { 'nvim-lua/plenary.nvim' } + } + + -- Auto-pairs + use { + 'windwp/nvim-autopairs', + config = function() + require('nvim-autopairs').setup() + end + } + + -- Highlight whitespaces + use { + 'ntpeters/vim-better-whitespace', + config = function() + vim.g.better_whitespace_filetypes_blacklist = { 'startify' } + end + } + + -- Highlight indents + use { + 'nathanaelkane/vim-indent-guides', + config = function() + vim.g.indent_guides_enable_on_vim_startup = 1 + vim.g.indent_guides_exclude_filetypes = { 'help', 'NvimTree', 'startify' } + end + } + + -- Color hex codes + use { + 'norcalli/nvim-colorizer.lua', + config = function() + require('colorizer').setup() + end + } + + -- Statusbar line + use { + 'nvim-lualine/lualine.nvim', + requires = { 'kyazdani42/nvim-web-devicons', opt = true }, + config = function() + require('lualine').setup() + end + } + + -- File browser + use { + 'kyazdani42/nvim-tree.lua', + requires = { 'kyazdani42/nvim-web-devicons' }, + config = function() + require('nvim-tree').setup() + end + } + + -- Org-mode + use { + 'nvim-orgmode/orgmode', + config = function() + require('orgmode').setup() + require('orgmode').setup_ts_grammar() + end + } + + -- Speedup neovim startup + use { + 'lewis6991/impatient.nvim', + config = function() + require('impatient') + end + } + + -- Rust tools + use 'neovim/nvim-lspconfig' + use { + 'simrat39/rust-tools.nvim', + config = function() + require('rust-tools').setup() + end + } + + + -- -- Language Server Protocol + -- use { + -- 'neovim/nvim-lspconfig', + -- config = function() + -- require('lspconfig').pyright.setup{} + -- require('lspconfig').rnix.setup{} + -- require('lspconfig').bashls.setup{} + -- require('lspconfig').vimls.setup{} + -- require('lspconfig').sumneko_lua.setup { + -- settings = { + -- Lua = { + -- diagnostics = { + -- globals = { 'vim' } + -- } + -- } + -- } + -- } + -- end + -- } + + -- Code completion + use 'L3MON4D3/LuaSnip' + use 'rafamadriz/friendly-snippets' + use 'zbirenbaum/copilot-cmp' + use 'hrsh7th/cmp-nvim-lsp' + use 'hrsh7th/cmp-nvim-lua' + use 'hrsh7th/cmp-buffer' + use 'hrsh7th/cmp-path' + use 'hrsh7th/cmp-cmdline' + use { + 'hrsh7th/nvim-cmp', + requires = { 'kyazdani42/nvim-web-devicons' }, + config = function() + require('plugins.cmp') + end + } + + -- Treesitter for highlighting + use { + 'nvim-treesitter/nvim-treesitter', + config = function() + require('nvim-treesitter.configs').setup { + ensure_installed = { 'cpp', 'lua', 'go', 'rust', 'python', 'nix', 'vim', 'markdown', 'html', 'css' }, + sync_install = true, + highlight = { + enable = true, + additional_vim_regex_highlighting = false, + }, + rainbow = { + enable = true, + extended_mode = true + }, + indent = { + enable = true; + } + } + end + } +end) diff --git a/maddie/common/neovim/lua/basics.lua b/maddie/common/neovim/lua/basics.lua new file mode 100644 index 0000000..56e9f2b --- /dev/null +++ b/maddie/common/neovim/lua/basics.lua @@ -0,0 +1,36 @@ +-- Vim settings +vim.g.mapleader = ' ' +vim.o.encoding = 'utf8' +vim.o.background = 'dark' +vim.o.relativenumber = true +vim.o.number = true +vim.o.wrap = false +vim.o.expandtab = true +vim.o.incsearch = true +vim.o.scrolloff = 5 +vim.o.tabstop = 2 +vim.o.shiftwidth = 2 +vim.o.cursorline = true +vim.o.ignorecase = true +vim.o.swapfile = false +vim.o.undofile = true +vim.o.splitbelow = true +vim.o.splitright = true +vim.o.errorbells = false +vim.o.termguicolors = true +vim.o.showmode = false +vim.o.showtabline = 1 +vim.o.signcolumn = 'auto' +vim.o.clipboard = 'unnamedplus' +vim.o.mouse = 'a' +vim.o.go = 'a' + +-- Netrw +vim.g["netrw_banner"] = 0 +vim.g["netrw_liststyle"] = 3 +vim.g["netrw_winsize"] = 25 + +-- Neovide +vim.o.guifont = 'JetBrainsMono Nerd Font:h12' +vim.g.neovide_cursor_vfx_mode = 'railgun' +vim.g.neovide_remember_window_size = true diff --git a/maddie/common/neovim/lua/colours.lua b/maddie/common/neovim/lua/colours.lua new file mode 100644 index 0000000..344eaf8 --- /dev/null +++ b/maddie/common/neovim/lua/colours.lua @@ -0,0 +1 @@ +vim.cmd([[colorscheme onedark]]) diff --git a/maddie/common/neovim/lua/keymaps.lua b/maddie/common/neovim/lua/keymaps.lua new file mode 100644 index 0000000..745fc15 --- /dev/null +++ b/maddie/common/neovim/lua/keymaps.lua @@ -0,0 +1,59 @@ +-- Neat variables +local opts = { noremap = true, silent = true } +local term_opts = { silent = true } +local keymap = vim.api.nvim_set_keymap + +-- Custom/special keymaps +keymap('n', 'c', ':sp :term :resize 20N i', term_opts) +keymap('n', 'r', ':luafile %:PackerSync', term_opts) +keymap('n', 'h', ':nohl', term_opts) +keymap('n', 'z', ':ZenMode:set wrap:set linebreak', term_opts) +keymap('n', 'Z', ':ZenMode:set nowrap:set nolinebreak', term_opts) +keymap('n', '', ':Telescope colorscheme', term_opts) +keymap('n', '', ':wqa', term_opts) +keymap('n', '', ':w', term_opts) +keymap('n', 'U', ':redo', term_opts) + +-- Window management +keymap('n', 'vs', ':vs', opts) +keymap('n', 'hs', ':sp', opts) +keymap('n', 'tn', ':tabnew', opts) +keymap('n', 'th', ':tabprev', opts) +keymap('n', 'tj', ':tabprev', opts) +keymap('n', 'tk', ':tabnext', opts) +keymap('n', 'tl', ':tabnext', opts) +keymap('n', 'to', ':tabo', opts) +keymap('n', 'tc', ':tabc', opts) + +-- Window navigation +keymap('n', '', 'w', opts) +keymap('n', '', 'h', opts) +keymap('n', '', 'j', opts) +keymap('n', '', 'k', opts) +keymap('n', '', 'l', opts) + +-- Buffer navigation +keymap('n', '', ':bnext', opts) +keymap('n', '', ':bprevious', opts) + +-- Stay in visual mode when indenting +keymap('v', '<', '', '>gv', opts) + +-- When moving up or down, move physical lines not file lines +keymap('n', 'j', 'gj', opts) +keymap('n', 'k', 'gk', opts) + +-- NvimTree +keymap('n', '', ':NvimTreeToggle', term_opts) + +-- Telescope +keymap('n', '', 'lua require("telescope.builtin").find_files()', opts) +keymap('n', 'ff', 'lua require("telescope.builtin").find_files()', opts) +keymap('n', 'fg', 'lua require("telescope.builtin").live_grep()', opts) +keymap('n', 'fb', 'lua require("telescope.builtin").buffers()', opts) +keymap('n', 'fh', 'lua require("telescope.builtin").help_tags()', opts) + +-- Easy alignment +keymap('n', 'ga', ':EasyAlign', opts) +keymap('v', 'ga', ':EasyAlign', opts) diff --git a/maddie/common/neovim/lua/plugins/cmp.lua b/maddie/common/neovim/lua/plugins/cmp.lua new file mode 100644 index 0000000..224eccb --- /dev/null +++ b/maddie/common/neovim/lua/plugins/cmp.lua @@ -0,0 +1,117 @@ +local cmp = require('cmp') +local luasnip = require('luasnip') +require('luasnip.loaders.from_vscode').lazy_load() + +local check_backspace = function() + local col = vim.fn.col "." - 1 + return col == 0 or vim.fn.getline("."):sub(col, col):match "%s" +end + +local kind_icons = { + Text = "", + Method = "m", + Function = "", + Constructor = "", + Field = "", + Variable = "", + Class = "", + Interface = "", + Module = "", + Property = "", + Unit = "", + Value = "", + Enum = "", + Keyword = "", + Snippet = "", + Color = "", + File = "", + Reference = "", + Folder = "", + EnumMember = "", + Constant = "", + Struct = "", + Event = "", + Operator = "", + TypeParameter = "", +} + +cmp.setup { + snippet = { + expand = function(args) + luasnip.lsp_expand(args.body) + end, + }, + mapping = { + [""] = cmp.mapping.select_prev_item(), + [""] = cmp.mapping.select_next_item(), + [""] = cmp.mapping(cmp.mapping.scroll_docs(-1), { "i", "c" }), + [""] = cmp.mapping(cmp.mapping.scroll_docs(1), { "i", "c" }), + [""] = cmp.mapping(cmp.mapping.complete(), { "i", "c" }), + [""] = cmp.config.disable, + [""] = cmp.mapping { + i = cmp.mapping.abort(), + c = cmp.mapping.close(), + }, + [""] = cmp.mapping.confirm { select = true }, + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() + elseif luasnip.expandable() then + luasnip.expand() + elseif luasnip.expand_or_jumpable() then + luasnip.expand_or_jump() + elseif check_backspace() then + fallback() + else + fallback() + end + end, { + "i", + "s", + }), + [""] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + elseif luasnip.jumpable(-1) then + luasnip.jump(-1) + else + fallback() + end + end, { + "i", + "s", + }), + }, + formatting = { + fields = { "kind", "abbr", "menu" }, + format = function(entry, vim_item) + vim_item.kind = string.format("%s", kind_icons[vim_item.kind]) + vim_item.menu = ({ + nvim_lsp = "[LSP]", + nvim_lua = "[NVIM_LUA]", + copilot = "[Copilot]", + luasnip = "[Snippet]", + buffer = "[Buffer]", + path = "[Path]", + })[entry.source.name] + return vim_item + end, + }, + sources = { + { name = "nvim_lsp" }, + { name = "nvim_lua" }, + { name = "copilot" }, + { name = "luasnip" }, + { name = "buffer" }, + { name = "path" }, + }, + confirm_opts = { + behavior = cmp.ConfirmBehavior.Replace, + select = false, + }, + experimental = { + ghost_text = false, + native_menu = false, + }, + cmp.config.window.bordered() +} diff --git a/maddie/common/neovim/spell/en.utf-8.add b/maddie/common/neovim/spell/en.utf-8.add new file mode 100644 index 0000000..6f1ee5d --- /dev/null +++ b/maddie/common/neovim/spell/en.utf-8.add @@ -0,0 +1,6 @@ +macOS +JS +add evelyne +evelyne +camhs +Vernova diff --git a/maddie/common/neovim/spell/en.utf-8.add.spl b/maddie/common/neovim/spell/en.utf-8.add.spl new file mode 100644 index 0000000000000000000000000000000000000000..44abfca3a3e482e4cd6390872f6a72b75a2e6077 GIT binary patch literal 111 zcmWIZ^erw(&B-zP&%nUo$d;I#nw49|m;!_fjEoEnlBtY|jJb>%jKz!$jAe|ej5&;z vjCmj#@l>D~6AMr}nK2*4Yyip@0p;?6>Jk~5n1JT-0JVbT{TYLSIzRvbGS(C5 literal 0 HcmV?d00001 diff --git a/maddie/common/newsboat.nix b/maddie/common/newsboat.nix new file mode 100644 index 0000000..55d3320 --- /dev/null +++ b/maddie/common/newsboat.nix @@ -0,0 +1,19 @@ +{ config, ...}: + +{ + programs.newsboat = { + enable = true; + urls = [ + { + title = "Gitea - Evelyne"; + tags = [ "git" ]; + url = "https://git.spyhoodle.me/evelyne.rss"; + } + { + title = "Gitea - Maddie"; + tags = [ "git" ]; + url = "https://git.spyhoodle.me/maddie.rss"; + } + ]; + }; +} diff --git a/maddie/common/passwords.nix b/maddie/common/passwords.nix new file mode 100644 index 0000000..c43e87d --- /dev/null +++ b/maddie/common/passwords.nix @@ -0,0 +1,14 @@ +{ config, ... }: + +{ + programs.password-store = { + enable = true; + settings = { + PASSWORD_STORE_DIR = "${config.xdg.dataHome}/password-store"; + }; + }; + + home.sessionVariables = { + PASSWORD_STORE_DIR = "${config.xdg.dataHome}/password-store"; + }; +} diff --git a/maddie/common/processes.nix b/maddie/common/processes.nix new file mode 100644 index 0000000..8ef33c9 --- /dev/null +++ b/maddie/common/processes.nix @@ -0,0 +1,8 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + xorg.xkill # Kill X11 programs with mouse + killall # Kill programs + ]; +} diff --git a/maddie/common/python.nix b/maddie/common/python.nix new file mode 100644 index 0000000..d1ef2f3 --- /dev/null +++ b/maddie/common/python.nix @@ -0,0 +1,24 @@ +{ config, pkgs, ... }: + +let + packages = ps: with ps; [ + numpy + matplotlib + tkinter + pillow + psycopg + passlib + pyotp + aiosmtplib + argon2_cffi + python-dotenv + python-lsp-server + openrgb-python + pdftotext + ]; +in +{ + home.packages = [ + (pkgs.python311.withPackages packages) + ]; +} diff --git a/maddie/common/rust.nix b/maddie/common/rust.nix new file mode 100644 index 0000000..e31bc39 --- /dev/null +++ b/maddie/common/rust.nix @@ -0,0 +1,15 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + rustup + ]; + + home = { + sessionVariables = { + CARGO_HOME = "${config.xdg.dataHome}/cargo"; + RUSTUP_HOME = "${config.xdg.dataHome}/rustup"; + }; + sessionPath = [ "${config.home.sessionVariables.CARGO_HOME}/bin" ]; + }; +} diff --git a/maddie/common/shell.nix b/maddie/common/shell.nix new file mode 100644 index 0000000..535e3af --- /dev/null +++ b/maddie/common/shell.nix @@ -0,0 +1,62 @@ +{ config, ... }: + +{ + home = { + # Aliases + shellAliases = { + # Core Programs + cp = "cp -iv"; + mv = "mv -iv"; + rm = "rm -vI"; + mkd = "mkdir -pv"; + c = "clear"; + e = "exit"; + + # CLI Shortcuts + v = "nvim"; + vi = "nvim"; + ka = "killall"; + xw = "xwallpaper"; + nf = "neofetch"; + tf = "pridefetch -f trans"; + pf = "pfetch"; + i = "inertia"; + + # System shortcuts + heif-convert-dir = "for file in *.heic; do heif-convert -q 100 $file \${file/%.heic/.jpg}; done"; + unfuck-wifi = "doas systemctl restart wpa_supplicant.service"; + search = "f=$(fzf) && cd \"$f\" 2>/dev/null || xdg-open \"$f\" >/dev/null 2>&1"; + cdt = "cd $(mktemp -d)"; + sx = "startx ~/.xprofile"; + sdn = "doas shutdown -h now"; + kys = "kill $(pidof '$@')"; + + # Nix system shortucts + nix-system-update = "nix flake update $NIXFILES && doas nixos-rebuild switch --flake $NIXFILES"; + + # For colour + btop = "btop --utf-force"; + grep = "grep --color=auto"; + diff = "diff --color=auto"; + }; + + # Environment variables + sessionVariables = { + # Locale + LANG = "en_GB.UTF-8"; + LC_ALL = "en_GB.UTF-8"; + + # Define nixfiles location + NIXFILES = "$HOME/Development/Personal/NixFiles"; + + # Java windows + _JAVA_AWT_WM_NONREPARENTING = 1; + }; + + # Default $PATH + sessionPath = [ + # Add ~/.local/bin to $PATH + "$HOME/.local/bin" + ]; + }; +} diff --git a/maddie/common/smart-home.nix b/maddie/common/smart-home.nix new file mode 100644 index 0000000..a13660e --- /dev/null +++ b/maddie/common/smart-home.nix @@ -0,0 +1,7 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + home-assistant-cli + ]; +} diff --git a/maddie/common/ssh.nix b/maddie/common/ssh.nix new file mode 100644 index 0000000..eb0e8a6 --- /dev/null +++ b/maddie/common/ssh.nix @@ -0,0 +1,26 @@ +{ config, pkgs, username, ... }: + +{ + # SSH + programs.ssh = { + enable = true; + matchBlocks = { + lambda = { + identityFile = "~/.ssh/id_ed25519_sk"; + hostname = "home.spyhoodle.me"; + user = "maddie"; + }; + pinea = { + identityFile = "~/.ssh/id_ed25519_sk"; + hostname = "ssh.pinea.dev"; + user = "maddie"; + }; + clicks = { + identityFile = "~/.ssh/clickscodes"; + hostname = "git.clicks.codes"; + port = 29418; + user = "maddie"; + }; + }; + }; +} diff --git a/maddie/common/ssh/maddie.pub b/maddie/common/ssh/maddie.pub new file mode 100644 index 0000000..5494a06 --- /dev/null +++ b/maddie/common/ssh/maddie.pub @@ -0,0 +1,3 @@ +sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIA1jTkcMhBQQoYqNVLofrNnTbB8RCyzSYmdsnPeoOineAAAABHNzaDo= spy@luna (yubikey) +ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBO9WsQUnglNetqekCoA6WT0wYNxpUVyNxuktPOHJPBCLJmU9P+YErE915vj4HlYcuOW9UhVajQzLQTcelgs/O8w= M.iPad (Termius) +ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBD44bc9OdsIxwNBkdIN5Ce+Wer2gWi+QRcFdOV7+ScIo1QS29wkQJxU90ItcKwqiv+oTBlipV2NSH/YroBSHhQI= M.iPad (Secure ShellFish) diff --git a/maddie/common/tmux.nix b/maddie/common/tmux.nix new file mode 100644 index 0000000..5324f76 --- /dev/null +++ b/maddie/common/tmux.nix @@ -0,0 +1,10 @@ +{ config, ... }: + +{ + programs.tmux = { + enable = true; + clock24 = true; + mouse = true; + terminal = "screen-256color"; + }; +} diff --git a/maddie/common/xdg.nix b/maddie/common/xdg.nix new file mode 100644 index 0000000..6506006 --- /dev/null +++ b/maddie/common/xdg.nix @@ -0,0 +1,21 @@ +{ config, ... }: + +{ + home = { + sessionVariables = { + # Force use of XDG Dir Spec + CUDA_CACHE_PATH = "${config.xdg.cacheHome}/nv"; + LESSHISTFILE = "${config.xdg.configHome}/less/history"; + LESSKEY = "${config.xdg.configHome}/less/keys"; + WINEPREFIX = "${config.xdg.dataHome}/wine"; + _JAVA_OPTIONS = "-Djava.util.prefs.userRoot=${config.xdg.configHome}/java"; + }; + + shellAliases = { + # Force use of XDG Dir Spec + wget = "wget --hsts-file='${config.xdg.dataHome}/wget-hsts'"; + rxrdb = "xrdb -load '${config.xdg.configHome}/.config/X11/xresources'"; + nvidia-settings = "nvidia-settings --config='${config.xdg.configHome}'/nvidia/settings"; + }; + }; +} diff --git a/maddie/common/yt-dlp.nix b/maddie/common/yt-dlp.nix new file mode 100644 index 0000000..f5d31ca --- /dev/null +++ b/maddie/common/yt-dlp.nix @@ -0,0 +1,13 @@ +{ config, pkgs, ... }: + +{ + programs.yt-dlp.enable = true; + home.packages = with pkgs; [ + flac + ]; + + home.file.".local/bin/ytdlp-music" = { + source = ./yt-dlp/ytdlp-music.sh; + executable = true; + }; +} diff --git a/maddie/common/yt-dlp/ytdlp-music.sh b/maddie/common/yt-dlp/ytdlp-music.sh new file mode 100755 index 0000000..d22fb3e --- /dev/null +++ b/maddie/common/yt-dlp/ytdlp-music.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env sh + +printf "YT URL: " && read url +printf "Title: " && read title +printf "Artist: " && read artist +printf "Album: " && read album + +# Download file from youtube +yt-dlp -x --no-playlist --embed-thumbnail --no-embed-metadata --audio-quality 0 --audio-format flac -o "$title.flac" "$url" + +# Set metadata flags +metaflac --set-tag="TITLE=$title" --set-tag="ARTIST=$artist" --set-tag="ALBUM=$album" "$title.flac" + +# Export thumbnail +metaflac --export-picture-to="$title.png" "$title.flac" + +# Convert png to jpg +mogrify -format jpg "$title.png" +rm -rf "$title.png" + +# Convert to square +convert "$title.jpg" -gravity center -crop 1:1 "$title.jpg" + +# Move the files to the correct directory +mv "$title.flac" "$title.jpg" $HOME/Music/Library/Liked diff --git a/maddie/common/zsh.nix b/maddie/common/zsh.nix new file mode 100644 index 0000000..3f48bf6 --- /dev/null +++ b/maddie/common/zsh.nix @@ -0,0 +1,123 @@ +{ config, pkgs, lib, ... }: + +{ + programs.zsh = { + # Use the zsh shell + enable = true; + + # Basic config settings + enableAutosuggestions = true; + enableCompletion = true; + syntaxHighlighting.enable = true; + autocd = true; + /* defaultKeymap = "vicmd"; */ + dotDir = ".config/zsh"; + history = { + size = 9999999; + expireDuplicatesFirst = true; + extended = true; + path = "${config.xdg.cacheHome}/zsh/history"; + }; + + # Zsh init extras + initExtra = '' + # Disable Ctrl-S to freeze terminal + stty stop undef + + # Tab completion + zstyle ':completion:*' menu select # Use a menu + _comp_options+=(globdots) # Include hidden files + + # Change cursor shape for different vi modes + export KEYTIMEOUT=1 + function zle-keymap-select () { + case $KEYMAP in + vicmd) echo -ne '\e[1 q';; # block + viins|main) echo -ne '\e[5 q';; # beam + esac + } + zle -N zle-keymap-select + zle-line-init() { + zle -K viins # initiate `vi insert` as keymap (can be removed if `bindkey -V` has been set elsewhere) + echo -ne "\e[5 q" + } + zle -N zle-line-init + echo -ne '\e[5 q' # Use beam shape cursor on startup. + preexec() { echo -ne '\e[5 q' ;} # Use beam shape cursor for each new prompt. + ''; + }; + + programs.starship = { + # Use the starship prompt + enable = true; + enableZshIntegration = true; + + settings = { + format = lib.concatStrings [ + # Directory + "$directory" + + # VCS + "$git_branch" + "$git_commit" + "$git_state" + "$git_metrics" + "$git_status" + "$hg_branch" + + # Languages + "$package" + "$c" + "$rust" + "$golang" + "$haskell" + "$python" + "$java" + "$kotlin" + "$lua" + "$dart" + "$nim" + "$nodejs" + "$swift" + "$zig" + "$nix_shell" + "$conda" + "$spack" + + # Prompt line + "$line_break" + "$username" + "$hostname" + "$localip" + "$cmd_duration" + "$memory_usage" + "$jobs" + "$character" + ]; + + # Prompt character + character = { + success_symbol = "-> [λ](bold purple)"; + error_symbol = "-> [λ](bold red)"; + vimcmd_symbol = "-> [λ](bold green)"; + }; + + # When in a deep directory or git repo + directory.truncation_symbol = ".../"; + + # Git widgets + git_metrics.disabled = false; + git_status = { + ahead = "->"; + behind = "<-"; + diverged = "<->"; + renamed = ">>"; + deleted = "x"; + }; + + # Enable other starship widgets + memory_usage.disabled = false; + localip.disabled = false; + }; + }; +} diff --git a/maddie/macos/home.nix b/maddie/macos/home.nix new file mode 100644 index 0000000..ea16015 --- /dev/null +++ b/maddie/macos/home.nix @@ -0,0 +1,10 @@ +{ config, username, pkgs, lib, ... }: + +{ + programs.home-manager.enable = true; + home = { + inherit username; + homeDirectory = lib.mkForce "/Users/${username}"; + stateVersion = "23.05"; + }; +} diff --git a/maddie/macos/iterm2.nix b/maddie/macos/iterm2.nix new file mode 100644 index 0000000..44dbc1f --- /dev/null +++ b/maddie/macos/iterm2.nix @@ -0,0 +1,510 @@ +{ config, username, ... }: + +{ + targets.darwin.defaults."com.googlecode.iterm2" = { + "PreventEscapeSequenceFromClearingHistory" = 0; + "NoSyncHaveExplainedHowToAddTouchbarControls" = 1; + "NoSyncTipsDisabled" = 1; + "SoundForEsc" = 0; + "VisualIndicatorForEsc" = 0; + "Custom Color Presets" = { + "One Dark" = { + "Ansi 0 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.168627455830574"; + "Color Space" = "sRGB"; + "Green Component" = "0.1450980454683304"; + "Red Component" = "0.1294117718935013"; + }; + "Ansi 1 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.4588235318660736"; + "Color Space" = "sRGB"; + "Green Component" = "0.4235294163227081"; + "Red Component" = "0.8784313797950745"; + }; + "Ansi 10 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.4745098054409027"; + "Color Space" = "sRGB"; + "Green Component" = "0.7647058963775635"; + "Red Component" = "0.5960784554481506"; + }; + "Ansi 11 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.4823529422283173"; + "Color Space" = "sRGB"; + "Green Component" = "0.7529411911964417"; + "Red Component" = "0.8980392217636108"; + }; + "Ansi 12 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.9372549057006836"; + "Color Space" = "sRGB"; + "Green Component" = "0.686274528503418"; + "Red Component" = "0.3803921639919281"; + }; + "Ansi 13 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.8666666746139526"; + "Color Space" = "sRGB"; + "Green Component" = "0.4705882370471954"; + "Red Component" = "0.7764706015586853"; + }; + "Ansi 14 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.7607843279838562"; + "Color Space" = "sRGB"; + "Green Component" = "0.7137255072593689"; + "Red Component" = "0.3372549116611481"; + }; + "Ansi 15 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.7490196228027344"; + "Color Space" = "sRGB"; + "Green Component" = "0.6980392336845398"; + "Red Component" = "0.6705882549285889"; + }; + "Ansi 2 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.4745098054409027"; + "Color Space" = "sRGB"; + "Green Component" = "0.7647058963775635"; + "Red Component" = "0.5960784554481506"; + }; + "Ansi 3 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.4823529422283173"; + "Color Space" = "sRGB"; + "Green Component" = "0.7529411911964417"; + "Red Component" = "0.8980392217636108"; + }; + "Ansi 4 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.9372549057006836"; + "Color Space" = "sRGB"; + "Green Component" = "0.686274528503418"; + "Red Component" = "0.3803921639919281"; + }; + "Ansi 5 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.8666666746139526"; + "Color Space" = "sRGB"; + "Green Component" = "0.4705882370471954"; + "Red Component" = "0.7764706015586853"; + }; + "Ansi 6 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.7607843279838562"; + "Color Space" = "sRGB"; + "Green Component" = "0.7137255072593689"; + "Red Component" = "0.3372549116611481"; + }; + "Ansi 7 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.7490196228027344"; + "Color Space" = "sRGB"; + "Green Component" = "0.6980392336845398"; + "Red Component" = "0.6705882549285889"; + }; + "Ansi 8 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.4627451002597809"; + "Color Space" = "sRGB"; + "Green Component" = "0.4627451002597809"; + "Red Component" = "0.4627451002597809"; + }; + "Ansi 9 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.4588235318660736"; + "Color Space" = "sRGB"; + "Green Component" = "0.4235294163227081"; + "Red Component" = "0.8784313797950745"; + }; + "Background Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.168627455830574"; + "Color Space" = "sRGB"; + "Green Component" = "0.1450980454683304"; + "Red Component" = "0.1294117718935013"; + }; + "Badge Color" = { + "Alpha Component" = "0.5"; + "Blue Component" = "0.4588235318660736"; + "Color Space" = "sRGB"; + "Green Component" = "0.4235294163227081"; + "Red Component" = "0.8784313797950745"; + }; + "Bold Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.7490196228027344"; + "Color Space" = "sRGB"; + "Green Component" = "0.6980392336845398"; + "Red Component" = "0.6705882549285889"; + }; + "Cursor Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.7490196228027344"; + "Color Space" = "sRGB"; + "Green Component" = "0.6980392336845398"; + "Red Component" = "0.6705882549285889"; + }; + "Cursor Guide Color" = { + "Alpha Component" = "0.1764705882352941"; + "Blue Component" = "0.7490196228027344"; + "Color Space" = "sRGB"; + "Green Component" = "0.6980392336845398"; + "Red Component" = "0.6705882549285889"; + }; + "Cursor Text Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.7490196228027344"; + "Color Space" = "sRGB"; + "Green Component" = "0.6980392336845398"; + "Red Component" = "0.6705882549285889"; + }; + "Foreground Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.7490196228027344"; + "Color Space" = "sRGB"; + "Green Component" = "0.6980392336845398"; + "Red Component" = "0.6705882549285889"; + }; + "Link Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.9372549057006836"; + "Color Space" = "sRGB"; + "Green Component" = "0.686274528503418"; + "Red Component" = "0.3803921639919281"; + }; + "Selected Text Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.7490196228027344"; + "Color Space" = "sRGB"; + "Green Component" = "0.6980392336845398"; + "Red Component" = "0.6705882549285889"; + }; + "Selection Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.2666666805744171"; + "Color Space" = "sRGB"; + "Green Component" = "0.2196078449487686"; + "Red Component" = "0.196078434586525"; + }; + }; + }; + "Default Bookmark Guid" = "B038731D-3A7A-44EC-A1C5-8777EB3270A7"; + GlobalTouchBarMap = { + "touchbar:0C8EAB5C-C453-4AEA-9DA6-05D596F01730" = { + Action = 12; + Label = "❄️"; + Text = "nix shell\\n"; + Version = 1; + }; + "touchbar:2DDE7A3B-26B0-4748-AED2-A453238DFF5C" = { + Action = 12; + Label = "🗑️"; + Text = "clear\\n"; + Version = 1; + }; + "touchbar:5527C3C6-A03F-4CA5-B7C1-A9B52CC89BED" = { + Action = 12; + Label = "⬆️"; + Text = "git push\\n"; + Version = 1; + }; + "touchbar:A34F65B2-B5FE-4B8F-904C-BFF3D76D352F" = { + Action = 12; + Label = "✍️"; + Text = "git add .; git commit\\n"; + Version = 1; + }; + "touchbar:B8063C42-FFC8-4735-9A1B-7B5F4D477D90" = { + Action = 12; + Label = "🧐"; + Text = "git status\\n"; + Version = 1; + }; + "touchbar:E6F32724-CABD-4079-BC0E-95C2BB50BEB7" = { + Action = 12; + Label = "⬇️"; + Text = "git pull\\n"; + Version = 1; + }; + "NSTouchBarConfig: full screen" = { + CurrentItems = [ + "touchbar:B8063C42-FFC8-4735-9A1B-7B5F4D477D90/v0" + "touchbar:A34F65B2-B5FE-4B8F-904C-BFF3D76D352F/v0" + "touchbar:5527C3C6-A03F-4CA5-B7C1-A9B52CC89BED/v0" + "touchbar:E6F32724-CABD-4079-BC0E-95C2BB50BEB7/v0" + "NSTouchBarItemIdentifierFlexibleSpace" + "touchbar:0C8EAB5C-C453-4AEA-9DA6-05D596F01730/v0" + "touchbar:2DDE7A3B-26B0-4748-AED2-A453238DFF5C/v0" + "NSTouchBarItemIdentifierOtherItemsProxy" + ]; + DefaultItems = [ + "iTermTouchBarIdentifierManPage" + "iTermTouchBarIdentifierColorPreset" + "iTermTouchBarIdentifierFunctionKeys" + "NSTouchBarItemIdentifierFlexibleSpace" + "NSTouchBarItemIdentifierOtherItemsProxy" + "iTermTouchBarIdentifierAddMark" + "iTermTouchBarIdentifierPreviousMark" + "iTermTouchBarIdentifierNextMark" + ]; + }; + "NSTouchBarConfig: regular" = { + CurrentItems = [ + "touchbar:B8063C42-FFC8-4735-9A1B-7B5F4D477D90/v0" + "touchbar:A34F65B2-B5FE-4B8F-904C-BFF3D76D352F/v0" + "touchbar:5527C3C6-A03F-4CA5-B7C1-A9B52CC89BED/v0" + "touchbar:E6F32724-CABD-4079-BC0E-95C2BB50BEB7/v0" + "NSTouchBarItemIdentifierFlexibleSpace" + "touchbar:0C8EAB5C-C453-4AEA-9DA6-05D596F01730/v0" + "touchbar:2DDE7A3B-26B0-4748-AED2-A453238DFF5C/v0" + "NSTouchBarItemIdentifierOtherItemsProxy" + ]; + DefaultItems = [ + "iTermTouchBarIdentifierManPage" + "iTermTouchBarIdentifierColorPreset" + "iTermTouchBarIdentifierFunctionKeys" + "NSTouchBarItemIdentifierFlexibleSpace" + "NSTouchBarItemIdentifierOtherItemsProxy" + "iTermTouchBarIdentifierAddMark" + "iTermTouchBarIdentifierPreviousMark" + "iTermTouchBarIdentifierNextMark" + ]; + }; + "New Bookmarks" = [{ + "Ansi 0 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.168627455830574"; + "Color Space" = "sRGB"; + "Green Component" = "0.1450980454683304"; + "Red Component" = "0.1294117718935013"; + }; + "Ansi 1 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.4588235318660736"; + "Color Space" = "sRGB"; + "Green Component" = "0.4235294163227081"; + "Red Component" = "0.8784313797950745"; + }; + "Ansi 10 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.4745098054409027"; + "Color Space" = "sRGB"; + "Green Component" = "0.7647058963775635"; + "Red Component" = "0.5960784554481506"; + }; + "Ansi 11 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.4823529422283173"; + "Color Space" = "sRGB"; + "Green Component" = "0.7529411911964417"; + "Red Component" = "0.8980392217636108"; + }; + "Ansi 12 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.9372549057006836"; + "Color Space" = "sRGB"; + "Green Component" = "0.686274528503418"; + "Red Component" = "0.3803921639919281"; + }; + "Ansi 13 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.8666666746139526"; + "Color Space" = "sRGB"; + "Green Component" = "0.4705882370471954"; + "Red Component" = "0.7764706015586853"; + }; + "Ansi 14 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.7607843279838562"; + "Color Space" = "sRGB"; + "Green Component" = "0.7137255072593689"; + "Red Component" = "0.3372549116611481"; + }; + "Ansi 15 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.7490196228027344"; + "Color Space" = "sRGB"; + "Green Component" = "0.6980392336845398"; + "Red Component" = "0.6705882549285889"; + }; + "Ansi 2 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.4745098054409027"; + "Color Space" = "sRGB"; + "Green Component" = "0.7647058963775635"; + "Red Component" = "0.5960784554481506"; + }; + "Ansi 3 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.4823529422283173"; + "Color Space" = "sRGB"; + "Green Component" = "0.7529411911964417"; + "Red Component" = "0.8980392217636108"; + }; + "Ansi 4 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.9372549057006836"; + "Color Space" = "sRGB"; + "Green Component" = "0.686274528503418"; + "Red Component" = "0.3803921639919281"; + }; + "Ansi 5 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.8666666746139526"; + "Color Space" = "sRGB"; + "Green Component" = "0.4705882370471954"; + "Red Component" = "0.7764706015586853"; + }; + "Ansi 6 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.7607843279838562"; + "Color Space" = "sRGB"; + "Green Component" = "0.7137255072593689"; + "Red Component" = "0.3372549116611481"; + }; + "Ansi 7 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.7490196228027344"; + "Color Space" = "sRGB"; + "Green Component" = "0.6980392336845398"; + "Red Component" = "0.6705882549285889"; + }; + "Ansi 8 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.4627451002597809"; + "Color Space" = "sRGB"; + "Green Component" = "0.4627451002597809"; + "Red Component" = "0.4627451002597809"; + }; + "Ansi 9 Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.4588235318660736"; + "Color Space" = "sRGB"; + "Green Component" = "0.4235294163227081"; + "Red Component" = "0.8784313797950745"; + }; + "BM Growl" = 1; + "Background Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.168627455830574"; + "Color Space" = "sRGB"; + "Green Component" = "0.1450980454683304"; + "Red Component" = "0.1294117718935013"; + }; + "Background Image Location" = ""; + "Badge Color" = { + "Alpha Component" = "0.5"; + "Blue Component" = "0.4588235318660736"; + "Color Space" = "sRGB"; + "Green Component" = "0.4235294163227081"; + "Red Component" = "0.8784313797950745"; + }; + "Blinking Cursor" = 0; + Blur = 1; + "Blur Radius" = "49.63241356382979"; + "Bold Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.7490196228027344"; + "Color Space" = "sRGB"; + "Green Component" = "0.6980392336845398"; + "Red Component" = "0.6705882549285889"; + }; + "Character Encoding" = 4; + "Close Sessions On End" = 1; + Columns = 80; + Command = ""; + "Cursor Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.7490196228027344"; + "Color Space" = "sRGB"; + "Green Component" = "0.6980392336845398"; + "Red Component" = "0.6705882549285889"; + }; + "Cursor Guide Color" = { + "Alpha Component" = "0.1764705882352941"; + "Blue Component" = "0.7490196228027344"; + "Color Space" = "sRGB"; + "Green Component" = "0.6980392336845398"; + "Red Component" = "0.6705882549285889"; + }; + "Cursor Text Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.7490196228027344"; + "Color Space" = "sRGB"; + "Green Component" = "0.6980392336845398"; + "Red Component" = "0.6705882549285889"; + }; + "Cursor Type" = 1; + "Custom Command" = "No"; + "Custom Directory" = "No"; + "Default Bookmark" = "No"; + "Description" = "Default"; + "Disable Window Resizing" = 1; + "Flashing Bell" = 0; + "Foreground Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.7490196228027344"; + "Color Space" = "sRGB"; + "Green Component" = "0.6980392336845398"; + "Red Component" = "0.6705882549285889"; + }; + "Guid" = "B038731D-3A7A-44EC-A1C5-8777EB3270A7"; + "Horizontal Spacing" = 1; + "Icon" = 0; + "Idle Code" = 0; + "Link Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.9372549057006836"; + "Color Space" = "sRGB"; + "Green Component" = "0.686274528503418"; + "Red Component" = "0.3803921639919281"; + }; + "Mouse Reporting" = 1; + "Name" = "Default"; + "Non Ascii Font" = "Monaco 12"; + "Non-ASCII Anti Aliased" = 1; + "Normal Font" = "JetBrainsMonoNerdFontComplete-Regular 12"; + "Option Key Sends" = 0; + "Prompt Before Closing 2" = 0; + "Right Option Key Sends" = 0; + "Rows" = 25; + "Screen" = "-1"; + "Scrollback Lines" = 1000; + "Selected Text Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.7490196228027344"; + "Color Space" = "sRGB"; + "Green Component" = "0.6980392336845398"; + "Red Component" = "0.6705882549285889"; + }; + "Selection Color" = { + "Alpha Component" = 1; + "Blue Component" = "0.2666666805744171"; + "Color Space" = "sRGB"; + "Green Component" = "0.2196078449487686"; + "Red Component" = "0.196078434586525"; + }; + "Send Code When Idle" = 0; + "Shortcut" = ""; + "Silence Bell" = 1; + "Sync Title" = 0; + "Terminal Type" = "xterm-256color"; + "Transparency" = "0.3756482712765958"; + "Unlimited Scrollback" = 0; + "Use Bold Font" = 1; + "Use Bright Bold" = 1; + "Use Italic Font" = 1; + "Use Non-ASCII Font" = 0; + "Vertical Spacing" = 1; + "Visual Bell" = 1; + "Window Type" = 0; + "Working Directory" = "/Users/${username}"; + }]; + }; + }; +} diff --git a/maddie/macos/ssh.nix b/maddie/macos/ssh.nix new file mode 100644 index 0000000..ce604c6 --- /dev/null +++ b/maddie/macos/ssh.nix @@ -0,0 +1,9 @@ +{ config, username, ... }: + +{ + # Use Secretive as the ssh IdentityAgent on all hosts + programs.ssh.extraConfig = '' + Host * + IdentityAgent /Users/${username}/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data/socket.ssh + ''; +} diff --git a/maddie/macos/tower.nix b/maddie/macos/tower.nix new file mode 100644 index 0000000..d32da96 --- /dev/null +++ b/maddie/macos/tower.nix @@ -0,0 +1,33 @@ +{ config, ... }: + +{ + targets.darwin.defaults."com.fournova.Tower3" = { + "GTUserDefaultsAppAppearance" = 0; + "GTUserDefaultsAutoFetchTimeInterval" = 0; + "GTUserDefaultsBodyLineWrappingMode" = "soft"; + "GTUserDefaultsCommitOptionSignOff" = 0; + "GTUserDefaultsDarkTheme" = "Default"; + "GTUserDefaultsDefaultTerminalApplication" = "com.googlecode.iterm2"; + "GTUserDefaultsDetailHeaderExpanded" = 1; + "GTUserDefaultsDialogueOptionPullUseRebase" = 0; + "GTUserDefaultsDiffWarningThreshold" = 20000; + "GTUserDefaultsGettingStartedPassed" = 1; + "GTUserDefaultsGitBinary" = "/usr/bin/git"; + "GTUserDefaultsHideWindowTitle" = 0; + "GTUserDefaultsHistoryVerifiesGPGSignatures" = 1; + "GTUserDefaultsHistoryVerifiesGPGSignaturesInitialActivation" = 1; + "GTUserDefaultsLastApplicationVersion" = 351; + "GTUserDefaultsLightTheme" = "Default"; + "GTUserDefaultsMigrationsAzureDevOpsServerHostURLMigration" = 1; + "GTUserDefaultsMigrationsCommitViewSizeMigration" = 1; + "GTUserDefaultsRepositoryFinderInitialized" = 1; + "GTUserDefaultsUpdatesReleaseChannel" = "stable"; + "GTUserDefaultsUpdatesReleaseChannelReset" = 1; + "GTUserDefaultsUserProfilesInitialized" = 1; + "MSAppCenter310AppCenterUserDefaultsMigratedKey" = 1; + "MSAppCenter310CrashesUserDefaultsMigratedKey" = 1; + "NSNavLastRootDirectory" = "~/Documents/Education/Notes"; + "NSNavPanelExpandedSizeForOpenMode" = "{800, 611}"; + "NSNavPanelMediaBrowserTypeForOpenModeKey" = 1; + }; +} diff --git a/maddie/nixos/android.nix b/maddie/nixos/android.nix new file mode 100644 index 0000000..e00eb5a --- /dev/null +++ b/maddie/nixos/android.nix @@ -0,0 +1,7 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + android-studio + ]; +} diff --git a/maddie/nixos/audio.nix b/maddie/nixos/audio.nix new file mode 100644 index 0000000..733995a --- /dev/null +++ b/maddie/nixos/audio.nix @@ -0,0 +1,15 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + pulsemixer # TUI sound mixer + playerctl # Manages media players + pamixer # CLI sound mixer + cava # Music visualiser + ]; + + home.file.".local/bin/volume" = { + source = ./audio/volume.sh; + executable = true; + }; +} diff --git a/maddie/nixos/audio/volume.sh b/maddie/nixos/audio/volume.sh new file mode 100755 index 0000000..0ed16d6 --- /dev/null +++ b/maddie/nixos/audio/volume.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env sh + +COMMAND="$@" +[ -z $COMMAND ] && echo "usage: volume [up|down|mute]" && exit 1 + +if [ $COMMAND = "up" ]; then + pamixer --allow-boost -i 5 +elif [ $COMMAND = "down" ]; then + pamixer --allow-boost -d 5 +elif [ $COMMAND = "mute" ]; then + pamixer -t +else + echo "volume: command not found" && exit 1 +fi + +MUTED="$(pamixer --get-mute)" +if [ $MUTED = "true" ]; then + MUTE_CHAR="!" +else + MUTE_CHAR="" +fi + +VOLUME=$(pamixer --get-volume) +echo "$VOLUME""$MUTE_CHAR" > /tmp/volume.fifo diff --git a/maddie/nixos/awesome.nix b/maddie/nixos/awesome.nix new file mode 100644 index 0000000..8ca6e2f --- /dev/null +++ b/maddie/nixos/awesome.nix @@ -0,0 +1,7 @@ +{ config, ... }: + +{ + xsession.windowManager.awesome = { + enable = true; + }; +} diff --git a/maddie/nixos/bosskey.nix b/maddie/nixos/bosskey.nix new file mode 100644 index 0000000..439baed --- /dev/null +++ b/maddie/nixos/bosskey.nix @@ -0,0 +1,12 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + slock + ]; + + home.file.".local/bin/bosskey" = { + source = ./bosskey/bosskey.sh; + executable = true; + }; +} diff --git a/maddie/nixos/bosskey/bosskey.sh b/maddie/nixos/bosskey/bosskey.sh new file mode 100755 index 0000000..3b16303 --- /dev/null +++ b/maddie/nixos/bosskey/bosskey.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +while getopts "lrpm:u:" options; do + case $options in + m) + devices=$OPTARG + if echo "$devices" | grep "mic" &>/dev/null; then + # Mute the microphone + pamixer --default-source --mute + fi + if echo "$devices" | grep "vol" &>/dev/null; then + # Mute the volume + pamixer --mute + fi + ;; + + u) + devices=$OPTARG + if echo "$devices"| grep "mic" &>/dev/null; then + # Mute the microphone + pamixer --default-source --unmute + fi + if echo "$devices" | grep "vol" &>/dev/null; then + # Unmute the volume + pamixer --unmute + fi + ;; + + p) + # Pause any playing media + playerctl pause + ;; + + l) + # Lock the screen using slock(1) + slock + ;; + esac +done diff --git a/maddie/nixos/calculator.nix b/maddie/nixos/calculator.nix new file mode 100644 index 0000000..fb1cf64 --- /dev/null +++ b/maddie/nixos/calculator.nix @@ -0,0 +1,7 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + nodePackages.insect + ]; +} diff --git a/maddie/nixos/chromium.nix b/maddie/nixos/chromium.nix new file mode 100644 index 0000000..30bc36a --- /dev/null +++ b/maddie/nixos/chromium.nix @@ -0,0 +1,29 @@ +{ config, ... }: + +{ + programs.chromium = { + enable = true; + commandLineArgs = [ + "--enable-logging=stderr" + "--ignore-gpu-blocklist" + ]; + extensions = [ + # Dark Reader + { id = "eimadpbcbfnmbkopoojfekhnkhdbieeh"; } + # uBlock Origin + { id = "cjpalhdlnbpafiamejdnhcphjbkeiagm"; } + # I still don't care about cookies + { id = "edibdbjcniadpccecjdfdjjppcpchdlm"; } + # NoScript + { id = "doojmbjmlfjjnbmnoijecmcbfeoakpjm"; } + # Reddit Enhancement Suite + { id = "kbmfpngjjgdllneeigpgjifpgocmfgmb"; } + # Old Reddit Redirect + { id = "dneaehbmnbhcippjikoajpoabadpodje"; } + # Return Youtube Dislike + { id = "gebbhagfogifgggkldgodflihgfeippi"; } + # Vimium + { id = "dbepggeogbaibhgnhhndojpepiihcmeb"; } + ]; + }; +} diff --git a/maddie/nixos/cider.nix b/maddie/nixos/cider.nix new file mode 100644 index 0000000..3f44907 --- /dev/null +++ b/maddie/nixos/cider.nix @@ -0,0 +1,7 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + cider + ]; +} diff --git a/maddie/nixos/dmenu.nix b/maddie/nixos/dmenu.nix new file mode 100644 index 0000000..7b06b42 --- /dev/null +++ b/maddie/nixos/dmenu.nix @@ -0,0 +1,16 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + dmenu + ]; + + home.file.".local/bin/dmenu" = { + source = ./dmenu; + executable = true; + }; + + home.sessionPath = [ + "$HOME/.local/bin/dmenu" + ]; +} diff --git a/maddie/nixos/dmenu/dmenu-bluetooth b/maddie/nixos/dmenu/dmenu-bluetooth new file mode 100755 index 0000000..0eb5a07 --- /dev/null +++ b/maddie/nixos/dmenu/dmenu-bluetooth @@ -0,0 +1,317 @@ +#!/bin/sh +# _ _ _ _ _ _ +# __| |_ __ ___ ___ _ __ _ _ | |__ | |_ _ ___| |_ ___ ___ | |_ | |__ +# / _` | '_ ` _ \ / _ \ '_ \| | | |_____| '_ \| | | | |/ _ \ __/ _ \ / _ \| __|| '_ \ +# | (_| | | | | | | __/ | | | |_| |_____| |_) | | |_| | __/ || (_) | (_) | |_ | | | | +# \__,_|_| |_| |_|\___|_| |_|\__,_| |_.__/|_|\__,_|\___|\__\___/ \___/ \__||_| |_| +# +# Author: Nick Clyde (clydedroid) +# dmenu support by: Layerex +# +# A script that generates a dmenu menu that uses bluetoothctl to +# connect to bluetooth devices and display status info. +# +# Inspired by networkmanager-dmenu (https://github.com/firecat53/networkmanager-dmenu) +# Thanks to x70b1 (https://github.com/polybar/polybar-scripts/tree/master/polybar-scripts/system-bluetooth-bluetoothctl) +# +# Depends on: +# Arch repositories: dmenu, bluez-utils (contains bluetoothctl) + +# Constants +divider="---------" +goback="Back" + +# Checks if bluetooth controller is powered on +power_on() { + if bluetoothctl show | grep -F -q "Powered: yes"; then + return 0 + else + return 1 + fi +} + +# Toggles power state +toggle_power() { + if power_on; then + bluetoothctl power off + show_menu + else + if rfkill list bluetooth | grep -F -q 'blocked: yes'; then + rfkill unblock bluetooth && sleep 3 + fi + bluetoothctl power on + show_menu + fi +} + +# Checks if controller is scanning for new devices +scan_on() { + if bluetoothctl show | grep -F -q "Discovering: yes"; then + echo "Scan: on" + return 0 + else + echo "Scan: off" + return 1 + fi +} + +# Toggles scanning state +toggle_scan() { + if scan_on; then + kill "$(pgrep -F -f "bluetoothctl scan on")" + bluetoothctl scan off + show_menu + else + bluetoothctl scan on & + echo "Scanning..." + sleep 5 + show_menu + fi +} + +# Checks if controller is able to pair to devices +pairable_on() { + if bluetoothctl show | grep -F -q "Pairable: yes"; then + echo "Pairable: on" + return 0 + else + echo "Pairable: off" + return 1 + fi +} + +# Toggles pairable state +toggle_pairable() { + if pairable_on; then + bluetoothctl pairable off + show_menu + else + bluetoothctl pairable on + show_menu + fi +} + +# Checks if controller is discoverable by other devices +discoverable_on() { + if bluetoothctl show | grep -F -q "Discoverable: yes"; then + echo "Discoverable: on" + return 0 + else + echo "Discoverable: off" + return 1 + fi +} + +# Toggles discoverable state +toggle_discoverable() { + if discoverable_on; then + bluetoothctl discoverable off + show_menu + else + bluetoothctl discoverable on + show_menu + fi +} + +# Checks if a device is connected +device_connected() { + device_info=$(bluetoothctl info "$1") + if echo "$device_info" | grep -F -q "Connected: yes"; then + return 0 + else + return 1 + fi +} + +# Toggles device connection +toggle_connection() { + if device_connected "$1"; then + bluetoothctl disconnect "$1" + # device_menu "$device" + else + bluetoothctl connect "$1" + # device_menu "$device" + fi +} + +# Checks if a device is paired +device_paired() { + device_info=$(bluetoothctl info "$1") + if echo "$device_info" | grep -F -q "Paired: yes"; then + echo "Paired: yes" + return 0 + else + echo "Paired: no" + return 1 + fi +} + +# Toggles device paired state +toggle_paired() { + if device_paired "$1"; then + bluetoothctl remove "$1" + device_menu "$device" + else + bluetoothctl pair "$1" + device_menu "$device" + fi +} + +# Checks if a device is trusted +device_trusted() { + device_info=$(bluetoothctl info "$1") + if echo "$device_info" | grep -F -q "Trusted: yes"; then + echo "Trusted: yes" + return 0 + else + echo "Trusted: no" + return 1 + fi +} + +# Toggles device connection +toggle_trust() { + if device_trusted "$1"; then + bluetoothctl untrust "$1" + device_menu "$device" + else + bluetoothctl trust "$1" + device_menu "$device" + fi +} + +# Prints a short string with the current bluetooth status +# Useful for status bars like polybar, etc. +print_status() { + if power_on; then + printf '' + + mapfile -t paired_devices < <(bluetoothctl paired-devices | grep -F Device | cut -d ' ' -f 2) + counter=0 + + for device in "${paired_devices[@]}"; do + if device_connected "$device"; then + device_alias="$(bluetoothctl info "$device" | grep -F "Alias" | cut -d ' ' -f 2-)" + + if [ $counter -gt 0 ]; then + printf ", %s" "$device_alias" + else + printf " %s" "$device_alias" + fi + + ((counter++)) + fi + done + printf "\n" + else + echo "" + fi +} + +# A submenu for a specific device that allows connecting, pairing, and trusting +device_menu() { + device=$1 + + # Get device name and mac address + device_name="$(echo "$device" | cut -d ' ' -f 3-)" + mac="$(echo "$device" | cut -d ' ' -f 2)" + + # Build options + if device_connected "$mac"; then + connected="Connected: yes" + else + connected="Connected: no" + fi + paired=$(device_paired "$mac") + trusted=$(device_trusted "$mac") + options="$connected\n$paired\n$trusted\n$divider\n$goback\nExit" + + # Open dmenu menu, read chosen option + chosen="$(echo -e "$options" | run_dmenu "$device_name")" + + # Match chosen option to command + case $chosen in + "" | "$divider") + echo "No option chosen." + ;; + "$connected") + toggle_connection "$mac" + ;; + "$paired") + toggle_paired "$mac" + ;; + "$trusted") + toggle_trust "$mac" + ;; + "$goback") + show_menu + ;; + esac +} + +# Opens a dmenu menu with current bluetooth status and options to connect +show_menu() { + # Get menu options + if power_on; then + power="Power: on" + + # Human-readable names of devices, one per line + # If scan is off, will only list paired devices + devices=$(bluetoothctl devices | grep -F Device | cut -d ' ' -f 3-) + + # Get controller flags + scan=$(scan_on) + pairable=$(pairable_on) + discoverable=$(discoverable_on) + + # Options passed to dmenu + options="$devices\n$divider\n$power\n$scan\n$pairable\n$discoverable\nExit" + else + power="Power: off" + options="$power\nExit" + fi + + # Open dmenu menu, read chosen option + chosen="$(echo -e "$options" | run_dmenu "Bluetooth")" + + # Match chosen option to command + case $chosen in + "" | "$divider") + echo "No option chosen." + ;; + "$power") + toggle_power + ;; + "$scan") + toggle_scan + ;; + "$discoverable") + toggle_discoverable + ;; + "$pairable") + toggle_pairable + ;; + *) + device=$(bluetoothctl devices | grep -F "$chosen") + # Open a submenu if a device is selected + if [[ $device ]]; then device_menu "$device"; fi + ;; + esac +} + +original_args=("$@") + +# dmenu command to pipe into. Extra arguments to dmenu-bluetooth are passed through to dmenu. This +# allows the user to set fonts, sizes, colours, etc. +run_dmenu() { + dmenu "${original_args[@]}" -i -p "$1" +} + +case "$1" in + --status) + print_status + ;; + *) + show_menu + ;; +esac diff --git a/maddie/nixos/dmenu/dmenu-code b/maddie/nixos/dmenu/dmenu-code new file mode 100755 index 0000000..7636af2 --- /dev/null +++ b/maddie/nixos/dmenu/dmenu-code @@ -0,0 +1,3 @@ +#!/bin/sh + +st -e 'zsh' -c 'cd ~/Documents/Code/"$(exa -lh --icons ~/Documents/Code | tail -n +2 | dmenu -l 30 | sed "s|.* ||")"; zsh' diff --git a/maddie/nixos/dmenu/dmenu-kdeconnect b/maddie/nixos/dmenu/dmenu-kdeconnect new file mode 100755 index 0000000..092b7e5 --- /dev/null +++ b/maddie/nixos/dmenu/dmenu-kdeconnect @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +NOTIFICATIONS_TITLE="KDE Connect" +NOTIFICATIONS_EXPIRE_TIME=1000 +notify-send "$NOTIFICATIONS_TITLE" "Getting devices..." --expire-time="$NOTIFICATIONS_EXPIRE_TIME" + +# Get available devices +devices="$(kdeconnect-cli -a)" +[ -z "$devices" ] && notify-send "$NOTIFICATIONS_TITLE" "No devices available" --expire-time="$NOTIFICATIONS_EXPIRE_TIME" && exit 1 + +# Let the user choose a device +device="$(echo "$devices" | sed 's/-\ //' | sed 's/:.*//' | dmenu -i -p "Devices:")" + +if [ $? -eq 0 ] +then + # Send files to a device + 📂File() { + file="$(zenity --file-selection)" + kdeconnect-cli -n "$device" --share "$file" + [ "$?" -eq 0 ] && notify-send "$NOTIFICATIONS_TITLE" "📂 Shared file: $file" --expire-time="$NOTIFICATIONS_EXPIRE_TIME" + [ "$?" -ne 0 ] && notify-send "$NOTIFICATIONS_TITLE" "📂 Failed to share file: $file" --expire-time="$NOTIFICATIONS_EXPIRE_TIME" && exit 1 + } + + # Ping a device + 📳Ping() { + kdeconnect-cli -n "$device" --ping + [ "$?" -eq 0 ] && notify-send "$NOTIFICATIONS_TITLE" "📳 Pinged device: $device" --expire-time="$NOTIFICATIONS_EXPIRE_TIME" + [ "$?" -ne 0 ] && notify-send "$NOTIFICATIONS_TITLE" "📳 Unable to ping device: $device" --expire-time="$NOTIFICATIONS_EXPIRE_TIME" && exit 1 + } + + # Make a device ring + ☎️Ring() { + kdeconnect-cli -n "$device" --ring + [ "$?" -eq 0 ] && notify-send "$NOTIFICATIONS_TITLE" "☎️ Ringed device: $device" --expire-time="$NOTIFICATIONS_EXPIRE_TIME" + [ "$?" -ne 0 ] && notify-send "$NOTIFICATIONS_TITLE" "☎️ Unable to ring device: $device" --expire-time="$NOTIFICATIONS_EXPIRE_TIME" && exit 1 + } + + # Show functions in dmenu and run the chosen function + func="$(declare -F | awk '{print $3}' | dmenu -i -p "$device":)" + [ -z "$func" ] || "$func" +fi diff --git a/maddie/nixos/dmenu/dmenu-man b/maddie/nixos/dmenu/dmenu-man new file mode 100755 index 0000000..33b3060 --- /dev/null +++ b/maddie/nixos/dmenu/dmenu-man @@ -0,0 +1,2 @@ +#!/bin/sh +man -t $(man -k . | dmenu -l 30 | awk '{print $1}') | ps2pdf - - | zathura - diff --git a/maddie/nixos/dmenu/dmenu-mount b/maddie/nixos/dmenu/dmenu-mount new file mode 100755 index 0000000..3cb1f81 --- /dev/null +++ b/maddie/nixos/dmenu/dmenu-mount @@ -0,0 +1,67 @@ +#!/bin/sh + +# Gives a dmenu prompt to mount unmounted drives and Android phones. If +# they're in /etc/fstab, they'll be mounted automatically. Otherwise, you'll +# be prompted to give a mountpoint from already existsing directories. If you +# input a novel directory, it will prompt you to create that directory. + +getmount() { \ + [ -z "$chosen" ] && exit 1 + # shellcheck disable=SC2086 + mp="$(find $1 2>/dev/null | dmenu -i -p "Type in mount point.")" || exit 1 + test -z "$mp" && exit 1 + if [ ! -d "$mp" ]; then + mkdiryn=$(printf "No\\nYes" | dmenu -i -p "$mp does not exist. Create it?") || exit 1 + [ "$mkdiryn" = "Yes" ] && (mkdir -p "$mp" || sudo -A mkdir -p "$mp") + fi + } + +mountusb() { \ + chosen="$(echo "$usbdrives" | dmenu -i -p "Mount which drive?")" || exit 1 + chosen="$(echo "$chosen" | awk '{print $1}')" + sudo -A mount "$chosen" 2>/dev/null && notify-send "💻 USB mounting" "$chosen mounted." && exit 0 + alreadymounted=$(lsblk -nrpo "name,type,mountpoint" | awk '$3!~/\/boot|\/home$|SWAP/&&length($3)>1{printf "-not ( -path *%s -prune ) ",$3}') + getmount "/mnt /media /mount /home -maxdepth 5 -type d $alreadymounted" + partitiontype="$(lsblk -no "fstype" "$chosen")" + case "$partitiontype" in + "vfat") sudo -A mount -t vfat "$chosen" "$mp" -o rw,umask=0000;; + "exfat") sudo -A mount "$chosen" "$mp" -o uid="$(id -u)",gid="$(id -g)";; + *) sudo -A mount "$chosen" "$mp"; user="$(whoami)"; ug="$(groups | awk '{print $1}')"; sudo -A chown "$user":"$ug" "$mp";; + esac + notify-send "💻 USB mounting" "$chosen mounted to $mp." + } + +mountandroid() { \ + chosen="$(echo "$anddrives" | dmenu -i -p "Which Android device?")" || exit 1 + chosen="$(echo "$chosen" | cut -d : -f 1)" + getmount "$HOME -maxdepth 3 -type d" + simple-mtpfs --device "$chosen" "$mp" + echo "OK" | dmenu -i -p "Tap Allow on your phone if it asks for permission and then press enter" || exit 1 + simple-mtpfs --device "$chosen" "$mp" + notify-send "🤖 Android Mounting" "Android device mounted to $mp." + } + +asktype() { \ + choice="$(printf "USB\\nAndroid" | dmenu -i -p "Mount a USB drive or Android device?")" || exit 1 + case $choice in + USB) mountusb ;; + Android) mountandroid ;; + esac + } + +anddrives=$(simple-mtpfs -l 2>/dev/null) +usbdrives="$(lsblk -rpo "name,type,size,mountpoint" | grep 'part\|rom' | awk '$4==""{printf "%s (%s)\n",$1,$3}')" + +if [ -z "$usbdrives" ]; then + [ -z "$anddrives" ] && echo "No USB drive or Android device detected" && exit + echo "Android device(s) detected." + mountandroid +else + if [ -z "$anddrives" ]; then + echo "USB drive(s) detected." + mountusb + else + echo "Mountable USB drive(s) and Android device(s) detected." + asktype + fi +fi diff --git a/maddie/nixos/dmenu/dmenu-mpc b/maddie/nixos/dmenu/dmenu-mpc new file mode 100755 index 0000000..5b7b3e9 --- /dev/null +++ b/maddie/nixos/dmenu/dmenu-mpc @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +playing=$(mpc current) +[ -z "$playing" ] && playing="Stopped" + +▶️play() { mpc play ;} +⏸️pause() { mpc pause ;} +⏭️next() { mpc next ;} +⏮️prev() { mpc prev ;} +⏹️stop() { mpc stop ;} +🔄update() { mpc update ;} + +func="$(declare -F | awk '{print $3}' | dmenu -i -p "$playing":)" +[ -z "$func" ] || "$func" diff --git a/maddie/nixos/dmenu/dmenu-pass b/maddie/nixos/dmenu/dmenu-pass new file mode 100755 index 0000000..76d92ab --- /dev/null +++ b/maddie/nixos/dmenu/dmenu-pass @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +shopt -s nullglob globstar + +typeit=0 +if [[ $1 == "--type" ]]; then + typeit=1 + shift +fi + +if [[ -n $WAYLAND_DISPLAY ]]; then + dmenu=dmenu-wl + xdotool="ydotool type --file -" +elif [[ -n $DISPLAY ]]; then + dmenu=dmenu + xdotool="xdotool type --clearmodifiers --file -" +else + echo "Error: No Wayland or X11 display detected" >&2 + exit 1 +fi + +prefix=${PASSWORD_STORE_DIR-~/.password-store} +password_files=( "$prefix"/**/*.gpg ) +password_files=( "${password_files[@]#"$prefix"/}" ) +password_files=( "${password_files[@]%.gpg}" ) + +password=$(printf '%s\n' "${password_files[@]}" | "$dmenu" "$@") + +[[ -n $password ]] || exit + +if [[ $typeit -eq 0 ]]; then + pass show -c "$password" 2>/dev/null +else + pass show "$password" | { IFS= read -r pass; printf %s "$pass"; } | $xdotool +fi diff --git a/maddie/nixos/dmenu/dmenu-power b/maddie/nixos/dmenu/dmenu-power new file mode 100755 index 0000000..64e3bdf --- /dev/null +++ b/maddie/nixos/dmenu/dmenu-power @@ -0,0 +1,9 @@ +#!/bin/sh + +poweroff() { systemctl shutdown ;} +restart() { killall -HUP dwm ;} +reboot() { system reboot ;} +lock() { bosskey ;} + +func="$(declare -F | awk '{print $3}' | dmenu -i -p "Power:")" +[ -z "$func" ] || "$func" diff --git a/maddie/nixos/dmenu/dmenu-unicode b/maddie/nixos/dmenu/dmenu-unicode new file mode 100755 index 0000000..18ee0a5 --- /dev/null +++ b/maddie/nixos/dmenu/dmenu-unicode @@ -0,0 +1,18 @@ +#!/bin/sh + +# The famous "get a menu of emojis to copy" script. + +# Get user selection via dmenu from emoji file. +chosen=$(cut -d ';' -f1 ~/.local/share/emoji-list | dmenu -i -l 30 | sed "s/ .*//") + +# Exit if none chosen. +[ -z "$chosen" ] && exit + +# If you run this command with an argument, it will automatically insert the +# character. Otherwise, show a message that the emoji has been copied. +if [ -n "$1" ]; then + xdotool type "$chosen" +else + printf "$chosen" | xclip -selection clipboard + notify-send "'$chosen' copied to clipboard." & +fi diff --git a/maddie/nixos/drawterm.nix b/maddie/nixos/drawterm.nix new file mode 100644 index 0000000..16ca2db --- /dev/null +++ b/maddie/nixos/drawterm.nix @@ -0,0 +1,7 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + drawterm + ]; +} diff --git a/maddie/nixos/dunst.nix b/maddie/nixos/dunst.nix new file mode 100644 index 0000000..05198be --- /dev/null +++ b/maddie/nixos/dunst.nix @@ -0,0 +1,44 @@ +{ config, pkgs, ... }: + +{ + services.dunst = { + enable = true; + settings = { + global = { + # Style + format = "%s\n%b"; + font = "Iosevka 10"; + width = 370; + height = 370; + offset = "0x50"; + padding = 5; + frame_width = 2; + + # Location + monitor = 0; + origin = "bottom-center"; + }; + + urgency_low = { + background = "#121317"; + foreground = "#D6DEEB"; + frame_color = "#2C323D"; + timeout = 3; + }; + + urgency_normal = { + background = "#121317"; + foreground = "#D6DEEB"; + frame_color = "#2C323D"; + timeout = 5; + }; + + urgency_critical = { + background = "#121317"; + foreground = "#D6DEEB"; + frame_color = "#E06C75"; + timeout = 10; + }; + }; + }; +} diff --git a/maddie/nixos/dwm.nix b/maddie/nixos/dwm.nix new file mode 100644 index 0000000..305b7cf --- /dev/null +++ b/maddie/nixos/dwm.nix @@ -0,0 +1,7 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + dwm # Suckless dynamic window manager + ]; +} diff --git a/maddie/nixos/files.nix b/maddie/nixos/files.nix new file mode 100644 index 0000000..cff192e --- /dev/null +++ b/maddie/nixos/files.nix @@ -0,0 +1,8 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + ncdu_2 # Disk space manager + clifm # TUI file manager + ]; +} diff --git a/maddie/nixos/games.nix b/maddie/nixos/games.nix new file mode 100644 index 0000000..a5f6f14 --- /dev/null +++ b/maddie/nixos/games.nix @@ -0,0 +1,8 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + gzdoom # Modern doom runner + pcsx2 # PS2 Emulator + ]; +} diff --git a/maddie/nixos/gcolor2.nix b/maddie/nixos/gcolor2.nix new file mode 100644 index 0000000..e6f1cb5 --- /dev/null +++ b/maddie/nixos/gcolor2.nix @@ -0,0 +1,7 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + gcolor2 # Color viewer and eyedropper + ]; +} diff --git a/maddie/nixos/gtk.nix b/maddie/nixos/gtk.nix new file mode 100644 index 0000000..3b68a35 --- /dev/null +++ b/maddie/nixos/gtk.nix @@ -0,0 +1,25 @@ +{ config, pkgs, ... }: + +{ + gtk = { + enable = true; + font = { + package = pkgs.iosevka; + name = "Iosevka"; + size = 10; + }; + theme = { + package = pkgs.lounge-gtk-theme; + name = "Lounge-night-compact"; + }; + iconTheme = { + package = pkgs.whitesur-icon-theme; + name = "WhiteSur-dark"; + }; + }; + + home.packages = with pkgs; [ + gnome.zenity + libsForQt5.breeze-gtk + ]; +} diff --git a/maddie/nixos/home.nix b/maddie/nixos/home.nix new file mode 100644 index 0000000..c70266e --- /dev/null +++ b/maddie/nixos/home.nix @@ -0,0 +1,10 @@ +{ config, username, ... }: + +{ + programs.home-manager.enable = true; + home = { + inherit username; + homeDirectory = "/home/${username}"; + stateVersion = "22.11"; + }; +} diff --git a/maddie/nixos/jetbrains.nix b/maddie/nixos/jetbrains.nix new file mode 100644 index 0000000..00ba844 --- /dev/null +++ b/maddie/nixos/jetbrains.nix @@ -0,0 +1,12 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + jetbrains.clion + jetbrains.goland + jetbrains.webstorm + jetbrains.datagrip + jetbrains.rust-rover + jetbrains.pycharm-professional + ]; +} diff --git a/maddie/nixos/kdeconnect.nix b/maddie/nixos/kdeconnect.nix new file mode 100644 index 0000000..32be6dc --- /dev/null +++ b/maddie/nixos/kdeconnect.nix @@ -0,0 +1,10 @@ +{ config, ... }: + +{ + services.kdeconnect.enable = true; + + home.file.".xprofile".text = '' + # Start kdeconnect when entering a graphical session + systemctl restart --user kdeconnect.service & + ''; +} diff --git a/maddie/nixos/librewolf.nix b/maddie/nixos/librewolf.nix new file mode 100644 index 0000000..b38aaed --- /dev/null +++ b/maddie/nixos/librewolf.nix @@ -0,0 +1,12 @@ +{ config, ... }: + +{ + programs.librewolf = { + enable = true; + settings = { + "browser.uidensity" = 1; + "webgl.disabled" = false; + "privacy.resistFingerprinting" = true; + }; + }; +} diff --git a/maddie/nixos/messaging.nix b/maddie/nixos/messaging.nix new file mode 100644 index 0000000..0a97090 --- /dev/null +++ b/maddie/nixos/messaging.nix @@ -0,0 +1,12 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + schildichat-desktop # Matrix client, fork of element + signal-desktop # Signal client + cinny-desktop # Pretty matrix client + discord-canary # Discord client + ripcord # Better discord client + nheko # Better matrix client + ]; +} diff --git a/maddie/nixos/minecraft.nix b/maddie/nixos/minecraft.nix new file mode 100644 index 0000000..8614dd9 --- /dev/null +++ b/maddie/nixos/minecraft.nix @@ -0,0 +1,9 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + prismlauncher # Minecraft launcher + minecraft # Actual minecraft + /*jdk # Needed for running minecraft servers */ + ]; +} diff --git a/maddie/nixos/mpd.nix b/maddie/nixos/mpd.nix new file mode 100644 index 0000000..03e84c5 --- /dev/null +++ b/maddie/nixos/mpd.nix @@ -0,0 +1,41 @@ +{ config, pkgs, username, ... }: + +{ + services.mpd = { + enable = true; + musicDirectory = "${config.home.homeDirectory}/Music"; + extraConfig = '' + auto_update "yes" + + audio_output { + type "pipewire" + name "PipeWire Sound Server" + } + + audio_output { + type "fifo" + name "Visualizer feed" + path "/tmp/mpd.fifo" + format "44100:16:2" + } + ''; + }; + + services.mpdris2 = { + enable = true; + multimediaKeys = true; + notifications = true; + }; + + home.packages = with pkgs; [ + mpc_cli + ]; + + programs.ncmpcpp = { + enable = true; + settings = { + ncmpcpp_directory = "${config.home.homeDirectory}/.local/share/ncmpcpp"; + lyrics_directory = "${config.home.homeDirectory}/.local/share/lyrics"; + }; + }; +} diff --git a/maddie/nixos/mpv.nix b/maddie/nixos/mpv.nix new file mode 100644 index 0000000..9841efd --- /dev/null +++ b/maddie/nixos/mpv.nix @@ -0,0 +1,10 @@ +{ config, ... }: + +{ + programs.mpv = { + enable = true; + config = { + loop-file = "inf"; + }; + }; +} diff --git a/maddie/nixos/neovide.nix b/maddie/nixos/neovide.nix new file mode 100644 index 0000000..e8e0759 --- /dev/null +++ b/maddie/nixos/neovide.nix @@ -0,0 +1,7 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + neovide + ]; +} diff --git a/maddie/nixos/nsxiv.nix b/maddie/nixos/nsxiv.nix new file mode 100644 index 0000000..8b538c9 --- /dev/null +++ b/maddie/nixos/nsxiv.nix @@ -0,0 +1,16 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + nsxiv + ]; + xdg.configFile."nsxiv" = { + source = ./nsxiv; + }; + xresources.properties = { + "Nsxiv.window.foreground" = "#D6DEEB"; + "Nsxiv.window.background" = "#1E2127"; + "Nsxiv.bar.background" = "#2C323D"; + "Nsxiv.bar.foreground" = "#D6DEEB"; + }; +} diff --git a/maddie/nixos/nsxiv/exec/key-handler b/maddie/nixos/nsxiv/exec/key-handler new file mode 100755 index 0000000..70c7593 --- /dev/null +++ b/maddie/nixos/nsxiv/exec/key-handler @@ -0,0 +1,14 @@ +#!/bin/sh +while read file +do + case "$1" in + "d") + rm -rf $file ;; + "r") + convert -rotate 90 "$file" "$file" ;; + "y") + echo -n "$file" | xclip -selection clipboard ;; + "w") + xwallpaper --zoom "$file" && kill $(pidof nsxiv);; + esac +done diff --git a/maddie/nixos/obs-studio.nix b/maddie/nixos/obs-studio.nix new file mode 100644 index 0000000..07f8a87 --- /dev/null +++ b/maddie/nixos/obs-studio.nix @@ -0,0 +1,5 @@ +{ config, ... }: + +{ + programs.obs-studio.enable = true; +} diff --git a/maddie/nixos/office.nix b/maddie/nixos/office.nix new file mode 100644 index 0000000..892c7b1 --- /dev/null +++ b/maddie/nixos/office.nix @@ -0,0 +1,12 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + texlive.combined.scheme-full # LaTeX + libreoffice # Documents suite + thunderbird # Email client + obsidian # Notes app + sc-im # TUI spreadsheet + anki # Flashcard app + ]; +} diff --git a/maddie/nixos/openrgb.nix b/maddie/nixos/openrgb.nix new file mode 100644 index 0000000..b783e0d --- /dev/null +++ b/maddie/nixos/openrgb.nix @@ -0,0 +1,18 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + openrgb-with-all-plugins + ]; + + home.file.".xprofile".text = '' + # Set RGB perhipherals to white + ${pkgs.openrgb}/bin/openrgb -c white -m static & + + # Set Razer Chroma HDK to white + ${pkgs.openrgb}/bin/openrgb --device 1 -c white & + + # Start my razer keyboard script + ${pkgs.python3Full}/bin/python ${config.home.homeDirectory}/Documents/Code/Razer/system.py & + ''; +} diff --git a/maddie/nixos/osu.nix b/maddie/nixos/osu.nix new file mode 100644 index 0000000..f7fedd5 --- /dev/null +++ b/maddie/nixos/osu.nix @@ -0,0 +1,7 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + osu-lazer-bin + ]; +} diff --git a/maddie/nixos/pcmanfm.nix b/maddie/nixos/pcmanfm.nix new file mode 100644 index 0000000..e235e38 --- /dev/null +++ b/maddie/nixos/pcmanfm.nix @@ -0,0 +1,11 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + pcmanfm + ]; + + xdg.configFile."pcmanfm" = { + source = ./pcmanfm; + }; +} diff --git a/maddie/nixos/pcmanfm/default/pcmanfm.conf b/maddie/nixos/pcmanfm/default/pcmanfm.conf new file mode 100644 index 0000000..79dfed0 --- /dev/null +++ b/maddie/nixos/pcmanfm/default/pcmanfm.conf @@ -0,0 +1,26 @@ +[config] +bm_open_method=0 + +[volume] +mount_on_startup=1 +mount_removable=1 +autorun=1 + +[ui] +always_show_tabs=0 +max_tab_chars=32 +win_width=1000 +win_height=696 +splitter_pos=189 +media_in_new_tab=0 +desktop_folder_new_win=0 +change_tab_on_drop=1 +close_on_unmount=1 +focus_previous=0 +side_pane_mode=places +view_mode=list +show_hidden=0 +sort=name;descending; +toolbar=newtab;navigation;home; +show_statusbar=1 +pathbar_mode_buttons=0 diff --git a/maddie/nixos/picom.nix b/maddie/nixos/picom.nix new file mode 100644 index 0000000..7f99365 --- /dev/null +++ b/maddie/nixos/picom.nix @@ -0,0 +1,25 @@ +{ config, pkgs, ... }: + +{ + home.file.".xprofile".text = '' + # Import xorg environment into systemd for the picom service to work + systemctl --user import-environment XAUTHORITY DISPLAY & + + # Restart picom after importing the xorg environment + systemctl --user restart picom & + ''; + services.picom = { + enable = true; + fade = true; + fadeSteps = [ + 0.1 + 0.1 + ]; + opacityRules = [ + "90:class_g = 'st-256color'" + "90:class_g = 'tabbed-trans'" + ]; + shadow = true; + vSync = true; + }; +} diff --git a/maddie/nixos/popcorntime.nix b/maddie/nixos/popcorntime.nix new file mode 100644 index 0000000..2bac960 --- /dev/null +++ b/maddie/nixos/popcorntime.nix @@ -0,0 +1,7 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + popcorntime + ]; +} diff --git a/maddie/nixos/qt.nix b/maddie/nixos/qt.nix new file mode 100644 index 0000000..4c695f2 --- /dev/null +++ b/maddie/nixos/qt.nix @@ -0,0 +1,19 @@ +{ config, pkgs, lib, ... }: + +{ + home.packages = with pkgs; [ + libsForQt5.breeze-qt5 + ]; + + qt = { + enable = true; + style = { + package = pkgs.libsForQt5.breeze-qt5; + name = "Breeze"; + }; + }; + + home.sessionVariables = { + QT_STYLE_OVERRIDE = "Breeze"; + }; +} diff --git a/maddie/nixos/screenshot.nix b/maddie/nixos/screenshot.nix new file mode 100644 index 0000000..31e3134 --- /dev/null +++ b/maddie/nixos/screenshot.nix @@ -0,0 +1,13 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + tesseract5 # Gets text from images + maim # X11 screenshot tool + ]; + + home.file.".local/bin/sss" = { + source = ./screenshot/sss.sh; + executable = true; + }; +} diff --git a/maddie/nixos/screenshot/sss.sh b/maddie/nixos/screenshot/sss.sh new file mode 100755 index 0000000..efe43ee --- /dev/null +++ b/maddie/nixos/screenshot/sss.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env sh + +# Configuration variables +SST_PIC_DIR="$HOME/Pictures/Screenshots" + +while getopts "sctd:" options; do + case $options in + s) + echo "sswm: save mode" + name=$(date --iso-8601=minutes) + maim -s -u -f png > $SST_PIC_DIR/$name.png + echo "sswm: imaged saved as $SST_PIC_DIR/$name.png" + ;; + c) + echo "sswm: copy mode" + maim -s -u -f png | xclip -selection clipboard -t image/png + echo "sswm: image copied to clipboard" + ;; + t) + echo "sswm: text mode" + maim -s -u -f png "$IMAGE" + [ $? -ne 0 ] && exit 1 + + tesseract "$IMAGE" "${TEXT//\.txt/}" 2> /dev/null + sed -i 's/\x0c//' "$TEXT" + + if [ $(wc -l < $TEXT) -eq 0 ]; then + echo "sswm: no text detected" + else + truncate -s -1 $TEXT + xclip -selection clipboard < "$TEXT" + echo "sswm: text copied to clipboard" + fi + ;; + d) + echo "sswm: delay "$OPTARG"s..." + sleep $OPTARG + ;; + esac +done diff --git a/maddie/nixos/secrets.nix b/maddie/nixos/secrets.nix new file mode 100644 index 0000000..fced800 --- /dev/null +++ b/maddie/nixos/secrets.nix @@ -0,0 +1,13 @@ +{ config, ... }: + +{ + services.pass-secret-service = { + enable = true; + storePath = "${config.xdg.dataHome}/password-store"; + }; + + home.file.".xprofile".text = '' + # Restart pass-secret-service as it tends to start failed + systemctl restart --user pass-secret-service.service & + ''; +} diff --git a/maddie/nixos/slstatus.nix b/maddie/nixos/slstatus.nix new file mode 100644 index 0000000..a5e9af4 --- /dev/null +++ b/maddie/nixos/slstatus.nix @@ -0,0 +1,21 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + slstatus + ]; + + home.file.".xprofile".text = '' + # Start slstatus + ${pkgs.slstatus}/bin/slstatus & + ''; + + home.file.".local/bin/statusbar" = { + source = ./statusbar; + executable = true; + }; + + home.sessionPath = [ + "$HOME/.local/bin/statusbar" + ]; +} diff --git a/maddie/nixos/statusbar/sb-clock b/maddie/nixos/statusbar/sb-clock new file mode 100755 index 0000000..d39f8db --- /dev/null +++ b/maddie/nixos/statusbar/sb-clock @@ -0,0 +1,3 @@ +#!/bin/sh + +echo " $(date "+%a %d %b")  $(date "+%I:%M:%S%p")" diff --git a/maddie/nixos/statusbar/sb-cpu b/maddie/nixos/statusbar/sb-cpu new file mode 100755 index 0000000..0e63fbb --- /dev/null +++ b/maddie/nixos/statusbar/sb-cpu @@ -0,0 +1,6 @@ +#!/bin/sh + +cpu=$(top -b -n2 -p 1 | fgrep "Cpu(s)" | tail -1 | awk -F'id,' '{ split($1, vs, ","); v=vs[length(vs)]; sub("%", "", v); printf "%s%.1f\n", prefix, 100 - v }' | awk '{print int($0)}') +icon="" + +echo "$icon $cpu%" diff --git a/maddie/nixos/statusbar/sb-disk b/maddie/nixos/statusbar/sb-disk new file mode 100755 index 0000000..9ae903d --- /dev/null +++ b/maddie/nixos/statusbar/sb-disk @@ -0,0 +1,7 @@ +#!/bin/sh + +disk=$(df -h "/" | awk ' /[0-9]/ {print $3 "/" $2}') +percent=$(df -h "/" | egrep -o '[0-9]+%' | awk '{print int($0)}') +icon="" + +echo "$icon $disk" diff --git a/maddie/nixos/statusbar/sb-forecast b/maddie/nixos/statusbar/sb-forecast new file mode 100755 index 0000000..685be80 --- /dev/null +++ b/maddie/nixos/statusbar/sb-forecast @@ -0,0 +1,35 @@ +#!/bin/sh + +# Displays todays precipication chance (☔) and daily low (🥶) and high (🌞). +# Usually intended for the statusbar. + +# If we have internet, get a weather report from wttr.in and store it locally. +# You could set up a shell alias to view the full file in a pager in the +# terminal if desired. This function will only be run once a day when needed. +weatherreport="${XDG_DATA_HOME:-$HOME/.local/share}/weatherreport" +getforecast() { curl -sf "wttr.in/$LOCATION" > "$weatherreport" || exit 1 ;} + +# Some very particular and terse stream manipulation. We get the maximum +# precipitation chance and the daily high and low from the downloaded file and +# display them with coresponding emojis. +showweather() { printf "%s" "$(sed '16q;d' "$weatherreport" | + grep -wo "[0-9]*%" | sort -rn | sed "s/^/☔/g;1q" | tr -d '\n')" +sed '13q;d' "$weatherreport" | grep -o "m\\([-+]\\)*[0-9]\\+" | sed 's/+//g' | sort -n -t 'm' -k 2n | sed -e 1b -e '$!d' | tr '\n|m' ' ' | awk '{print " 🥶" $1 "°","🌞" $2 "°"}' ;} + +case BLOCK_BUTTON in + 1) setsid -f "$TERMINAL" -e less -Srf "$weatherreport" ;; + 2) getforecast && showweather ;; + 3) notify-send "🌈 Weather module" "\- Left click for full forecast. +- Middle click to update forecast. +☔: Chance of rain/snow +🥶: Daily low +🌞: Daily high" ;; + 6) "$TERMINAL" -e "$EDITOR" "$0" ;; +esac + +# The test if our forcecast is updated to the day. If it isn't download a new +# weather report from wttr.in with the above function. +[ "$(stat -c %y "$weatherreport" 2>/dev/null | cut -d' ' -f1)" = "$(date '+%Y-%m-%d')" ] || + getforecast + +showweather diff --git a/maddie/nixos/statusbar/sb-iplocate b/maddie/nixos/statusbar/sb-iplocate new file mode 100755 index 0000000..02adab8 --- /dev/null +++ b/maddie/nixos/statusbar/sb-iplocate @@ -0,0 +1,10 @@ +#!/bin/sh + +# Gets your public ip address checks which country you are in and +# displays that information in the statusbar +# +# https://www.maketecheasier.com/ip-address-geolocation-lookups-linux/ + +ifinstalled "geoip" || exit +addr="$(curl ifconfig.me 2>/dev/null)" || exit +grep "flag: " "${XDG_DATA_HOME:-$HOME/.local/share}/larbs/emoji" | grep "$(geoiplookup "$addr" | sed 's/.*, //')" | sed "s/flag: //;s/;.*//" diff --git a/maddie/nixos/statusbar/sb-kernel b/maddie/nixos/statusbar/sb-kernel new file mode 100755 index 0000000..6619a05 --- /dev/null +++ b/maddie/nixos/statusbar/sb-kernel @@ -0,0 +1,5 @@ +#!/bin/sh + +kernel=$(uname -r) +icon="" +echo "$icon $kernel" diff --git a/maddie/nixos/statusbar/sb-memory b/maddie/nixos/statusbar/sb-memory new file mode 100755 index 0000000..2ff0c4e --- /dev/null +++ b/maddie/nixos/statusbar/sb-memory @@ -0,0 +1,7 @@ +#!/bin/sh + +mem=$(free --mebi | sed -n '2{p;q}' | awk '{printf ("%2.2f/%2.2f", ( $3 / 1024), ($2 / 1024))}') +percent=$(free -m | awk 'NR==2{printf "%.2f%%\t\t", $3*100/$2 }' | awk '{print int($0)}') +icon="" + +echo "$icon $mem""GB" diff --git a/maddie/nixos/statusbar/sb-temp b/maddie/nixos/statusbar/sb-temp new file mode 100755 index 0000000..bbbd63d --- /dev/null +++ b/maddie/nixos/statusbar/sb-temp @@ -0,0 +1,13 @@ +#!/bin/sh + +temp=$(sensors | awk '/Core 0/ {print $3}' | awk '{print int($0)}') + +if [ $temp -ge 70 ]; then + icon="" +elif [ $temp -ge 50 ]; then + icon="" +elif [ $temp -ge 0 ]; then + icon="" +fi + +echo "$icon $temp°C" diff --git a/maddie/nixos/statusbar/sb-uptime b/maddie/nixos/statusbar/sb-uptime new file mode 100755 index 0000000..28046d5 --- /dev/null +++ b/maddie/nixos/statusbar/sb-uptime @@ -0,0 +1,6 @@ +#!/bin/sh + +uptime=$(uptime | awk '{print $3}' | sed 's/,//') +icon="" + +echo "$icon $uptime" diff --git a/maddie/nixos/statusbar/sb-volume b/maddie/nixos/statusbar/sb-volume new file mode 100755 index 0000000..f75b83d --- /dev/null +++ b/maddie/nixos/statusbar/sb-volume @@ -0,0 +1,15 @@ +#!/bin/sh + +vol="$(pamixer --get-volume)" + +if [ $(pamixer --get-mute) = true ]; then + icon="" +elif [ "$vol" -ge "50" ]; then + icon="" +elif [ "$vol" -gt "0" ]; then + icon="" +elif [ "$vol" -eq "0" ]; then + icon="" +fi + +echo "$icon $vol%" diff --git a/maddie/nixos/steam.nix b/maddie/nixos/steam.nix new file mode 100644 index 0000000..0594128 --- /dev/null +++ b/maddie/nixos/steam.nix @@ -0,0 +1,13 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + steam + steam-run + ]; + + home.file.".local/bin/steam-killer" = { + source = ./steam/steam-killer.sh; + executable = true; + }; +} diff --git a/maddie/nixos/steam/steam-killer.sh b/maddie/nixos/steam/steam-killer.sh new file mode 100755 index 0000000..93b501b --- /dev/null +++ b/maddie/nixos/steam/steam-killer.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +while true +do + echo "[sk] killing steamwebhelper" + { kill $(pidof steamwebhelper) && echo "[fhs] killed!"; } || echo "[fhs] failed!" + echo "[sk] waiting 0.5 seconds..." + sleep 0.5 +done diff --git a/maddie/nixos/syncplay.nix b/maddie/nixos/syncplay.nix new file mode 100644 index 0000000..9d89535 --- /dev/null +++ b/maddie/nixos/syncplay.nix @@ -0,0 +1,7 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + #syncplay + ]; +} diff --git a/maddie/nixos/tabbed.nix b/maddie/nixos/tabbed.nix new file mode 100644 index 0000000..fc0f1fc --- /dev/null +++ b/maddie/nixos/tabbed.nix @@ -0,0 +1,16 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + tabbed + ]; + + home.file.".local/bin/tabbed" = { + source = ./tabbed; + executable = true; + }; + + home.sessionPath = [ + "$HOME/.local/bin/tabbed" + ]; +} diff --git a/maddie/nixos/tabbed/tabbed-st b/maddie/nixos/tabbed/tabbed-st new file mode 100755 index 0000000..0a751c8 --- /dev/null +++ b/maddie/nixos/tabbed/tabbed-st @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +picom-trans -w $(tabbed $@ -d -n "tabbed-trans" -r 2 st -w '') -o 90 diff --git a/maddie/nixos/terminal.nix b/maddie/nixos/terminal.nix new file mode 100644 index 0000000..aaa4690 --- /dev/null +++ b/maddie/nixos/terminal.nix @@ -0,0 +1,9 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + cool-retro-term # Retro-style terminal + kitty # Used for testing + st # Suckless terminal + ]; +} diff --git a/maddie/nixos/tor.nix b/maddie/nixos/tor.nix new file mode 100644 index 0000000..e2a7d4c --- /dev/null +++ b/maddie/nixos/tor.nix @@ -0,0 +1,7 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + tor-browser-bundle-bin + ]; +} diff --git a/maddie/nixos/uxplay.nix b/maddie/nixos/uxplay.nix new file mode 100644 index 0000000..4c7e6f9 --- /dev/null +++ b/maddie/nixos/uxplay.nix @@ -0,0 +1,7 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + uxplay + ]; +} diff --git a/maddie/nixos/virtualisation.nix b/maddie/nixos/virtualisation.nix new file mode 100644 index 0000000..68b90f2 --- /dev/null +++ b/maddie/nixos/virtualisation.nix @@ -0,0 +1,9 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + virt-manager # Manages QEMU virtual machines + bottles # GTK interface for wine + wine # Windows emulation + ]; +} diff --git a/maddie/nixos/wezterm.nix b/maddie/nixos/wezterm.nix new file mode 100644 index 0000000..fcb9406 --- /dev/null +++ b/maddie/nixos/wezterm.nix @@ -0,0 +1,14 @@ +{ config, pkgs, ... }: + +{ + programs.wezterm = { + enable = true; + extraConfig = '' + return { + color_scheme = 'OneDark (base16)', + hide_tab_bar_if_only_one_tab = true, + window_close_confirmation = 'NeverPrompt' + } + ''; + }; +} diff --git a/maddie/nixos/xdg.nix b/maddie/nixos/xdg.nix new file mode 100644 index 0000000..500e533 --- /dev/null +++ b/maddie/nixos/xdg.nix @@ -0,0 +1,59 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + xdg-utils + xdg-user-dirs + ]; + + xdg = { + enable = true; + userDirs.enable = true; + desktopEntries = { + "browser" = { + name = "Web Browser"; + type = "Application"; + exec = "${pkgs.librewolf}/bin/librewolf %f"; + }; + "image" = { + name = "Image Viewer"; + type = "Application"; + exec = "${pkgs.nsxiv}/bin/nsxiv -a %f"; + }; + "text" = { + name = "Text Editor"; + type = "Application"; + exec = "${pkgs.st}/bin/st -e ${pkgs.neovim}/bin/nvim %u"; + }; + "pdf" = { + name = "PDF Reader"; + type = "Application"; + exec = "${pkgs.zathura}/bin/zathura %u"; + }; + }; + mimeApps = { + enable = true; + defaultApplications = { + "application/pdf" = "pdf.desktop"; + "x-scheme-handler/http" = "browser.desktop"; + "x-scheme-handler/https" = "browser.desktop"; + "image/png" = "image.desktop"; + "image/jpeg" = "image.desktop"; + "image/jpg" = "image.desktop"; + "image/gif" = "image.desktop"; + "video/mp4" = "mpv.desktop"; + "text/plain" = "text.desktop"; + "text/html" = "browser.desktop"; + }; + }; + }; + + home = { + sessionVariables = { + # Default programs + EDITOR = "nvim"; + TERMINAL = "st"; + BROWSER = "librewolf"; + }; + }; +} diff --git a/maddie/nixos/xorg.nix b/maddie/nixos/xorg.nix new file mode 100644 index 0000000..7035e6e --- /dev/null +++ b/maddie/nixos/xorg.nix @@ -0,0 +1,68 @@ +{ config, pkgs, ... }: + +{ + # Run startx on tty1 + /* programs.zsh.profileExtra = '' + # If on /dev/tty1 then run startx automatically + if [ -z $DISPLAY ] && [ "$(tty)" = "/dev/tty1" ]; then + sleep 2 + exec ${pkgs.xorg.xinit}/bin/startx + fi + ''; */ + + # Attempt to set keyboard layout + home.keyboard = { + layout = "gb"; + options = [ + "caps:escape" + ]; + }; + + # Attempt to set cursor + home.pointerCursor = { + gtk.enable = true; + x11.enable = true; + package = pkgs.apple-cursor; + name = "macOS-BigSur"; + size = 24; + }; + + # Force use of XDG Dir Spec + home.sessionVariables = { + /* XAUTHORITY = "${config.xdg.runtimeDir}/Xauthority"; */ + XCOMPOSECACHE = "${config.xdg.cacheHome}/x11/xcompose"; + }; + + # Install notify-send + home.packages = with pkgs; [ + libnotify + ]; + + # Set global font + xresources.properties = { + "*.font" = "Iosevka:pixelsize=12:antialias=true:autohint=true"; + }; + + # Configure ~/.xprofile + programs.feh.enable = true; + home.file.".xprofile".text = '' + # Monitor configuration + # ${pkgs.xorg.xrandr}/bin/xrandr --output HDMI-0 --noprimary --mode 2560x1440 --pos 2560x0 --rotate right + # ${pkgs.xorg.xrandr}/bin/xrandr --output DP-0 --primary --mode 2560x1440 --pos 0x560 + + # Apply wallpaper + ${pkgs.feh}/bin/feh --no-fehbg --bg-fill "$HOME/Pictures/Wallpapers/NixOS/nix-wallpaper-waterfall.png" + + # Refresh xresources + ${pkgs.xorg.xrdb}/bin/xrdb "$HOME/.Xresources" + + # Speed up repeated keypresses + ${pkgs.xorg.xset}/bin/xset r rate 300 50 + + # Set keyboard map and remap caps to escape + ${pkgs.xorg.setxkbmap}/bin/setxkbmap -layout gb -option caps:escape + + # Start the window manager + ${pkgs.openssh}/bin/ssh-agent ${pkgs.dwm}/bin/dwm + ''; +} diff --git a/maddie/nixos/yubikey.nix b/maddie/nixos/yubikey.nix new file mode 100644 index 0000000..f898774 --- /dev/null +++ b/maddie/nixos/yubikey.nix @@ -0,0 +1,7 @@ +{ config, pkgs, ... }: + +{ + home.packages = with pkgs; [ + yubioath-flutter + ]; +} diff --git a/maddie/nixos/zathura.nix b/maddie/nixos/zathura.nix new file mode 100644 index 0000000..6430428 --- /dev/null +++ b/maddie/nixos/zathura.nix @@ -0,0 +1,5 @@ +{ config, ... }: + +{ + programs.zathura.enable = true; +} diff --git a/overlays.nix b/overlays.nix new file mode 100644 index 0000000..650b24c --- /dev/null +++ b/overlays.nix @@ -0,0 +1,68 @@ +[ + # My build of suckless dwm + (final: prev: { + dwm = prev.dwm.overrideAttrs (oldAttrs: { + src = final.fetchFromGitea { + domain = "git.spyhoodle.me"; + owner = "maddie"; + repo = "dwm"; + rev = "a06076bfb9324af6c4122d9cc5b0904778013350"; + sha256 = "sha256-KGqbff/i9fG0B/gMrdnwevRElL6r8lbYCloWp/NPx+0="; + }; + }); + st = prev.st.overrideAttrs (oldAttrs: { + src = final.fetchFromGitea { + domain = "git.spyhoodle.me"; + owner = "maddie"; + repo = "st"; + rev = "22e582e5acf6e4eb52c57df51f59f84bbb7d2f13"; + sha256 = "sha256-ko4be6N/igCMo28/as/AWKMYswm/jIH1ILeVoi2Gpx8="; + }; + buildInputs = oldAttrs.buildInputs ++ [ final.harfbuzz ]; + }); + dmenu = prev.dmenu.overrideAttrs (oldAttrs: { + src = final.fetchFromGitea { + domain = "git.spyhoodle.me"; + owner = "maddie"; + repo = "dmenu"; + rev = "1b12798a3762807697227e9e40be29408df59ee9"; + sha256 = "sha256-wnVNqNCUpJTqHXfst9DiBaq/gzVwhlq07VM9CixczRc="; + }; + }); + slstatus = prev.slstatus.overrideAttrs (oldAttrs: { + src = final.fetchFromGitea { + domain = "git.spyhoodle.me"; + owner = "maddie"; + repo = "slstatus"; + rev = "2546de2a4c5ab34d96fb31f75d3a8b7d6840005e"; + sha256 = "sha256-aoEd4GGA+jkoxvJlRlXqMiaxM8mZe4Jt5CtKKtnu+rQ="; + }; + }); + slock = prev.slock.overrideAttrs (oldAttrs: { + src = final.fetchFromGitea { + domain = "git.spyhoodle.me"; + owner = "maddie"; + repo = "slock"; + rev = "8c5d321b641961237f747d3e68f52b163d673634"; + sha256 = "sha256-y+6VU3jXbUOyhUcyPC7CDGjyWLSJcCkhYiHscVib7j4="; + }; + buildInputs = oldAttrs.buildInputs ++ [ final.xorg.libXpm ]; + }); + tabbed = prev.tabbed.overrideAttrs (oldAttrs: { + src = final.fetchFromGitea { + domain = "git.spyhoodle.me"; + owner = "maddie"; + repo = "tabbed"; + rev = "1001f193fd076cba12bd1ec9f113c144b37d8689"; + sha256 = "sha256-M5LrFplGfzCdhLTutsPNmox69brvAm2BlXnyza9kGxQ="; + }; + }); + ncmpcpp = prev.ncmpcpp.override { + visualizerSupport = true; + clockSupport = false; + }; + nerdfonts = prev.nerdfonts.override { + fonts = [ "Iosevka" "JetBrainsMono" "Terminus" ]; + }; + }) +] diff --git a/systems/mdesktop/android.nix b/systems/mdesktop/android.nix new file mode 100644 index 0000000..b9fd5f2 --- /dev/null +++ b/systems/mdesktop/android.nix @@ -0,0 +1,5 @@ +{ config, ... }: + +{ + programs.adb.enable = true; +} diff --git a/systems/mdesktop/audio.nix b/systems/mdesktop/audio.nix new file mode 100644 index 0000000..329fa97 --- /dev/null +++ b/systems/mdesktop/audio.nix @@ -0,0 +1,14 @@ +{ config, ... }: + +{ + sound.enable = true; + hardware.pulseaudio.enable = false; + security.rtkit.enable = true; + services.pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + jack.enable = true; + }; +} diff --git a/systems/mdesktop/avahi.nix b/systems/mdesktop/avahi.nix new file mode 100644 index 0000000..f28d394 --- /dev/null +++ b/systems/mdesktop/avahi.nix @@ -0,0 +1,14 @@ +{ config, ... }: + +{ + services.avahi = { + enable = true; + nssmdns = true; + publish = { + enable = true; + addresses = true; + workstation = true; + userServices = true; + }; + }; +} diff --git a/systems/mdesktop/bluetooth.nix b/systems/mdesktop/bluetooth.nix new file mode 100644 index 0000000..fae0e1d --- /dev/null +++ b/systems/mdesktop/bluetooth.nix @@ -0,0 +1,6 @@ +{ config, ... }: + +{ + hardware.bluetooth.enable = true; + services.blueman.enable = true; +} diff --git a/systems/mdesktop/boot.nix b/systems/mdesktop/boot.nix new file mode 100644 index 0000000..96a141a --- /dev/null +++ b/systems/mdesktop/boot.nix @@ -0,0 +1,37 @@ +{ config, pkgs, modulesPath, ... }: + +{ + imports = + [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + # Setup bootloader + boot.loader.systemd-boot = { + enable = true; + consoleMode = "max"; + }; + boot.loader.efi.canTouchEfiVariables = true; + boot.loader.efi.efiSysMountPoint = "/boot/efi"; + boot.initrd.systemd.enable = true; + + # Setup crypto keyfile + boot.initrd.secrets = { + "/crypto_keyfile.bin" = null; + }; + + # Enable LUKS boot devices + boot.initrd.luks.devices."luks-c180a121-376a-432e-a661-f4be3cc23dfa".device = "/dev/disk/by-uuid/c180a121-376a-432e-a661-f4be3cc23dfa"; + boot.initrd.luks.devices."luks-16dda63d-9dce-4ef2-9da6-ee458ba3c44c".device = "/dev/disk/by-uuid/16dda63d-9dce-4ef2-9da6-ee458ba3c44c"; + boot.initrd.luks.devices."luks-c180a121-376a-432e-a661-f4be3cc23dfa".keyFile = "/crypto_keyfile.bin"; + + # Kernel settings + boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usbhid" "sd_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.kernelParams = [ "video=2560x1440@180" ]; + boot.extraModulePackages = [ ]; + + # Use the linux-zen kernel + boot.kernelPackages = pkgs.linuxPackages_zen; +} diff --git a/systems/mdesktop/cpu.nix b/systems/mdesktop/cpu.nix new file mode 100644 index 0000000..dcb9255 --- /dev/null +++ b/systems/mdesktop/cpu.nix @@ -0,0 +1,6 @@ +{ config, lib, ... }: + +{ + powerManagement.cpuFreqGovernor = lib.mkDefault "powersave"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/systems/mdesktop/disks.nix b/systems/mdesktop/disks.nix new file mode 100644 index 0000000..b78af9a --- /dev/null +++ b/systems/mdesktop/disks.nix @@ -0,0 +1,24 @@ +{ config, ... }: + +{ + fileSystems."/" = + { + device = "/dev/disk/by-uuid/0eecf0db-00f9-48db-9d62-0ade3f3edd90"; + fsType = "ext4"; + }; + + fileSystems."/boot/efi" = + { + device = "/dev/disk/by-uuid/0042-9914"; + fsType = "vfat"; + }; + + fileSystems."/mnt/data" = + { + device = "/dev/disk/by-uuid/5c0f035b-fe9e-4c7f-a137-34b0168e1dde"; + fsType = "ext4"; + }; + + swapDevices = + [{ device = "/dev/disk/by-uuid/9be243bf-4f48-42e3-9827-bba2ef04ffa4"; }]; +} diff --git a/systems/mdesktop/doas.nix b/systems/mdesktop/doas.nix new file mode 100644 index 0000000..6aa5f72 --- /dev/null +++ b/systems/mdesktop/doas.nix @@ -0,0 +1,13 @@ +{ config, username, ... }: + +{ + security.sudo.enable = false; + security.doas = { + enable = true; + extraRules = [{ + users = [ "${username}" ]; + keepEnv = true; + persist = true; + }]; + }; +} diff --git a/systems/mdesktop/firewall.nix b/systems/mdesktop/firewall.nix new file mode 100644 index 0000000..1abda33 --- /dev/null +++ b/systems/mdesktop/firewall.nix @@ -0,0 +1,6 @@ +{ config, ... }: + +{ + # Disable the firewall altogether + networking.firewall.enable = false; +} diff --git a/systems/mdesktop/fonts.nix b/systems/mdesktop/fonts.nix new file mode 100644 index 0000000..e1b02f6 --- /dev/null +++ b/systems/mdesktop/fonts.nix @@ -0,0 +1,13 @@ +{ config, pkgs, ... }: + +{ + fonts.packages = with pkgs; [ + nerdfonts + font-awesome + source-sans + source-han-sans + source-han-serif + source-han-code-jp + terminus_font + ]; +} diff --git a/systems/mdesktop/gpg.nix b/systems/mdesktop/gpg.nix new file mode 100644 index 0000000..dd75311 --- /dev/null +++ b/systems/mdesktop/gpg.nix @@ -0,0 +1,10 @@ +{ config, pkgs, ... }: + +{ + # programs.gnupg.package = pkgs.gnupg22; + programs.gnupg.agent = { + enable = true; + enableSSHSupport = false; + pinentryFlavor = "gtk2"; + }; +} diff --git a/systems/mdesktop/locale.nix b/systems/mdesktop/locale.nix new file mode 100644 index 0000000..0b0581e --- /dev/null +++ b/systems/mdesktop/locale.nix @@ -0,0 +1,13 @@ +{ config, pkgs, ... }: + +{ + # Time zone + time.timeZone = "Europe/London"; + + # Internationalisation properties + i18n.defaultLocale = "en_GB.UTF-8"; + console = { + font = "${pkgs.terminus_font}/share/consolefonts/ter-v12n.psf.gz"; + keyMap = "uk"; + }; +} diff --git a/systems/mdesktop/man.nix b/systems/mdesktop/man.nix new file mode 100644 index 0000000..7e1051b --- /dev/null +++ b/systems/mdesktop/man.nix @@ -0,0 +1,8 @@ +{ config, ... }: + +{ + documentation.man = { + enable = true; + generateCaches = true; + }; +} diff --git a/systems/mdesktop/networking.nix b/systems/mdesktop/networking.nix new file mode 100644 index 0000000..43364f7 --- /dev/null +++ b/systems/mdesktop/networking.nix @@ -0,0 +1,17 @@ +{ config, lib, ... }: + +{ + # DHCP + networking.useDHCP = lib.mkDefault true; + + # Hostname + networking.hostName = "MDesktop"; + + # Enable wireless support & configuration + networking.wireless.enable = true; + networking.wireless.networks = { + "BT-C5CPMR_5GEXT" = { + psk = "hN3LtFrkp36bXc"; + }; + }; +} diff --git a/systems/mdesktop/nix-ld.nix b/systems/mdesktop/nix-ld.nix new file mode 100644 index 0000000..b5d5b9f --- /dev/null +++ b/systems/mdesktop/nix-ld.nix @@ -0,0 +1,5 @@ +{ config, ... }: + +{ + programs.nix-ld.enable = true; +} diff --git a/systems/mdesktop/nix.nix b/systems/mdesktop/nix.nix new file mode 100644 index 0000000..533f7e9 --- /dev/null +++ b/systems/mdesktop/nix.nix @@ -0,0 +1,16 @@ +{ config, pkgs, ... }: + +{ + # Enable flakes and nix-command + nix = { + package = pkgs.nixVersions.stable; + settings = { + experimental-features = [ "nix-command" "flakes" ]; + auto-optimise-store = true; + }; + gc = { + automatic = true; + options = "--delete-older-than 7d"; + }; + }; +} diff --git a/systems/mdesktop/nixos.nix b/systems/mdesktop/nixos.nix new file mode 100644 index 0000000..f9a9339 --- /dev/null +++ b/systems/mdesktop/nixos.nix @@ -0,0 +1,6 @@ +{ config, lib, ... }: + +{ + system.stateVersion = "23.05"; + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; +} diff --git a/systems/mdesktop/noise-supression.nix b/systems/mdesktop/noise-supression.nix new file mode 100644 index 0000000..c101b60 --- /dev/null +++ b/systems/mdesktop/noise-supression.nix @@ -0,0 +1,47 @@ +{ config, pkgs, ... }: + +let + json = pkgs.formats.json {}; + pw_rnnoise_config = { + "context.modules"= [ + { "name" = "libpipewire-module-filter-chain"; + "args" = { + "node.description" = "Noise Canceling source"; + "media.name" = "Noise Canceling source"; + "filter.graph" = { + "nodes" = [ + { + "type" = "ladspa"; + "name" = "rnnoise"; + "plugin" = "${pkgs.rnnoise-plugin}/lib/ladspa/librnnoise_ladspa.so"; + "label" = "noise_suppressor_stereo"; + "control" = { + "VAD Threshold (%)" = 50.0; + }; + } + ]; + }; + "audio.position" = [ "FL" "FR" ]; + "capture.props" = { + "node.name" = "effect_input.rnnoise"; + "node.passive" = true; + }; + "playback.props" = { + "node.name" = "effect_output.rnnoise"; + "media.class" = "Audio/Source"; + }; + }; + } + ]; + }; +in +{ + environment.systemPackages = with pkgs; [ + rnnoise + rnnoise-plugin + ]; + + environment.etc."pipewire/pipewire.conf.d/99-input-denoising.conf" = { + source = json.generate "99-input-denoising.conf" pw_rnnoise_config; + }; +} diff --git a/systems/mdesktop/nvidia.nix b/systems/mdesktop/nvidia.nix new file mode 100644 index 0000000..14bfe78 --- /dev/null +++ b/systems/mdesktop/nvidia.nix @@ -0,0 +1,23 @@ +{ config, pkgs, ... }: + +{ + hardware.opengl.enable = true; + hardware.opengl.driSupport = true; + hardware.opengl.driSupport32Bit = true; + hardware.nvidia.package = config.boot.kernelPackages.nvidiaPackages.stable; + hardware.nvidia.open = false; + hardware.nvidia.modesetting.enable = false; + services.xserver.videoDrivers = [ "nvidia" ]; + + # Fix tauri applications with nvidia drivers + environment.sessionVariables = { + "WEBKIT_DISABLE_COMPOSITING_MODE" = "1"; + }; + + hardware.opengl.extraPackages = [ + (pkgs.runCommand "nvidia-icd" { } '' + mkdir -p $out/share/vulkan/icd.d + cp ${pkgs.linuxPackages.nvidia_x11}/share/vulkan/icd.d/nvidia_icd.x86_64.json $out/share/vulkan/icd.d/nvidia_icd.json + '') + ]; +} diff --git a/systems/mdesktop/openrazer.nix b/systems/mdesktop/openrazer.nix new file mode 100644 index 0000000..4175987 --- /dev/null +++ b/systems/mdesktop/openrazer.nix @@ -0,0 +1,9 @@ +{ config, username, ... }: + +{ + hardware.openrazer = { + enable = true; + users = [ "${username}" ]; + devicesOffOnScreensaver = false; + }; +} diff --git a/systems/mdesktop/openrgb.nix b/systems/mdesktop/openrgb.nix new file mode 100644 index 0000000..d112498 --- /dev/null +++ b/systems/mdesktop/openrgb.nix @@ -0,0 +1,8 @@ +{ config, pkgs, ... }: + +{ + services.hardware.openrgb = { + enable = true; + package = pkgs.openrgb-with-all-plugins; + }; +} diff --git a/systems/mdesktop/packages.nix b/systems/mdesktop/packages.nix new file mode 100644 index 0000000..8562890 --- /dev/null +++ b/systems/mdesktop/packages.nix @@ -0,0 +1,50 @@ +{ config, pkgs, ... }: + +{ + # System-wide packages + # I want these available for all users at all times + environment.systemPackages = with pkgs; [ + # Xorg packages + xorg.xinit + xorg.xkill + xorg.xprop + xorg.xwininfo + xorg.xrandr + xdotool + xclip + + # Processes + killall + appimage-run + + # Filesystems + dosfstools + btrfs-progs + ntfs3g + exfatprogs + libimobiledevice + ifuse + + # Archives + zip + unrar + unzip + p7zip + + # Cli tools + ripgrep + wget + fzf + bat + + # XDG + xdg-utils + xdg-user-dirs + + # Git + git + + # Compiler + gcc + ]; +} diff --git a/systems/mdesktop/security.nix b/systems/mdesktop/security.nix new file mode 100644 index 0000000..65a4e9a --- /dev/null +++ b/systems/mdesktop/security.nix @@ -0,0 +1,6 @@ +{ config, pkgs, ... }: + +{ + programs.slock.enable = true; + security.wrappers.slock.source = "${pkgs.slock.out}/bin/slock"; +} diff --git a/systems/mdesktop/services.nix b/systems/mdesktop/services.nix new file mode 100644 index 0000000..291c999 --- /dev/null +++ b/systems/mdesktop/services.nix @@ -0,0 +1,6 @@ +{ config, ... }: + +{ + # Misc services + services.usbmuxd.enable = true; +} diff --git a/systems/mdesktop/ssh.nix b/systems/mdesktop/ssh.nix new file mode 100644 index 0000000..6727c8e --- /dev/null +++ b/systems/mdesktop/ssh.nix @@ -0,0 +1,13 @@ +{ config, ... }: + +{ + services.openssh = { + enable = true; + settings = { + PermitRootLogin = "no"; + PasswordAuthentication = false; + KbdInteractiveAuthentication = false; + }; + }; + programs.ssh.hostKeyAlgorithms = [ "sk-ssh-ed25519@openssh.com" "ssh-ed25519" "ecdsa-sha2-nistp256" ]; +} diff --git a/systems/mdesktop/syncthing.nix b/systems/mdesktop/syncthing.nix new file mode 100644 index 0000000..ab6dd0e --- /dev/null +++ b/systems/mdesktop/syncthing.nix @@ -0,0 +1,48 @@ +{ config, username, ... }: + +{ + services.syncthing = { + enable = true; + user = "${username}"; + group = "users"; + dataDir = "/home/${username}"; + configDir = "/home/${username}/.config/syncthing"; + guiAddress = "0.0.0.0:8384"; + overrideFolders = true; + overrideDevices = true; + settings = { + devices = { + "M.Phone.Pixel" = { id = "WMGWVOU-DFZQSZO-46XQJQA-Q5XD5ZB-NDXK5SP-LXNAADH-Z2KJN4P-4P4UXA5"; }; + "M.MacBookPro" = { id = "A5HRCSI-RWYZ6GG-SCBZ2OJ-PG6T7VP-WKDN2VP-CNXIQ3B-VCJ7ZHO-MTV63QP"; }; + "Lambda" = { id = "ZYNSFWR-F3ZNDDT-66TSJWB-PRP3KQK-IWTTABU-GGWT5DL-RWC7VAE-LI5AXQQ"; }; + }; + folders = { + "Documents" = { + path = "/home/${username}/Documents"; + devices = [ "M.Phone.Pixel" "M.MacBookPro" ]; + }; + "Pictures" = { + path = "/home/${username}/Pictures"; + devices = [ "M.Phone.Pixel" "M.MacBookPro" ]; + }; + "Videos" = { + path = "/home/${username}/Videos"; + devices = [ "M.Phone.Pixel" "M.MacBookPro" ]; + }; + "Music" = { + path = "/home/${username}/Music"; + devices = [ "M.Phone.Pixel" "M.MacBookPro" ]; + }; + "Android Camera" = { + id = "pixel_7_pro_2qyx-photos"; + path = "/home/${username}/Pictures/DCIM"; + devices = [ "M.Phone.Pixel" "M.MacBookPro" ]; + }; + ".Hidden" = { + path = "/home/${username}/.Hidden"; + devices = [ "M.Phone.Pixel" ]; + }; + }; + }; + }; +} diff --git a/systems/mdesktop/systemd.nix b/systems/mdesktop/systemd.nix new file mode 100644 index 0000000..93db17e --- /dev/null +++ b/systems/mdesktop/systemd.nix @@ -0,0 +1,8 @@ +{ config, ... }: + +{ + # Stop systemd from hanging for ages + systemd.extraConfig = '' + DefaultTimeoutStopSec=10s + ''; +} diff --git a/systems/mdesktop/users.nix b/systems/mdesktop/users.nix new file mode 100644 index 0000000..d7fe3bd --- /dev/null +++ b/systems/mdesktop/users.nix @@ -0,0 +1,11 @@ +{ config, pkgs, username, ... }: + +{ + users.users.${username} = { + isNormalUser = true; + shell = pkgs.zsh; + description = "Madeleine"; + extraGroups = [ "adbusers" "dialout" "libvirtd" "plugdev" ]; + openssh.authorizedKeys.keyFiles = [ ../../maddie/common/ssh/maddie.pub ]; + }; +} diff --git a/systems/mdesktop/virtualisation.nix b/systems/mdesktop/virtualisation.nix new file mode 100644 index 0000000..dad25d2 --- /dev/null +++ b/systems/mdesktop/virtualisation.nix @@ -0,0 +1,6 @@ +{ config, ... }: + +{ + virtualisation.libvirtd.enable = true; + programs.dconf.enable = true; +} diff --git a/systems/mdesktop/xorg.nix b/systems/mdesktop/xorg.nix new file mode 100644 index 0000000..186640b --- /dev/null +++ b/systems/mdesktop/xorg.nix @@ -0,0 +1,17 @@ +{ config, pkgs, ... }: + +{ + services.xserver = { + # Enable X11 windowing system + enable = true; + + # Set X11 keymap as GB + layout = "gb"; + xkbOptions = "eurosign:e"; + + displayManager = { + # Use startx for starting window managers + startx.enable = true; + }; + }; +} diff --git a/systems/mdesktop/yubikey.nix b/systems/mdesktop/yubikey.nix new file mode 100644 index 0000000..32d847a --- /dev/null +++ b/systems/mdesktop/yubikey.nix @@ -0,0 +1,22 @@ +{ config, pkgs, ... }: + +{ + services.pcscd.enable = true; + services.udev.packages = [ pkgs.yubikey-personalization pkgs.android-udev-rules ]; + security.pam = { + services = { + login.u2fAuth = true; + doas.u2fAuth = true; + }; + yubico = { + enable = true; + mode = "challenge-response"; + control = "optional"; + }; + }; + + /* environment.systemPackages = with pkgs; [ */ + /* yubioath-flutter */ + /* yubikey-personalization */ + /* ]; */ +} diff --git a/systems/mdesktop/zsh.nix b/systems/mdesktop/zsh.nix new file mode 100644 index 0000000..3aab6fb --- /dev/null +++ b/systems/mdesktop/zsh.nix @@ -0,0 +1,10 @@ +{ config, pkgs, ... }: + +{ + programs.zsh = { + enable = true; + autosuggestions.enable = true; + syntaxHighlighting.enable = true; + }; + users.defaultUserShell = pkgs.zsh; +} diff --git a/systems/mmacbookpro/apps.nix b/systems/mmacbookpro/apps.nix new file mode 100644 index 0000000..1e68e50 --- /dev/null +++ b/systems/mmacbookpro/apps.nix @@ -0,0 +1,73 @@ +{ config, ... }: + +{ + homebrew = { + enable = true; + onActivation = { + autoUpdate = true; + cleanup = "zap"; + }; + taps = [ + { + name = "kde-mac/kde"; + clone_target = "https://invent.kde.org/packaging/homebrew-kde.git"; + force_auto_update = true; + } + ]; + casks = [ + # Media + "syncplay" + "mpv" + + # Messaging + "signal" + "element" + + # Games + "minecraft" + "prismlauncher" + "tetrio" + "osu" + + # Design + "sketch" + + # Development + "pycharm" + "webstorm" + "clion" + "goland" + "datagrip" + "rustrover" + "fleet" + "tower" + "secretive" + "sf-symbols" + "iterm2" + "emacs" + + # Learning + "anki" + "obsidian" + + # Tools + "boop" + "syncthing" + "haptickey" + "kdeconnect" + "hazeover" + "yubico-authenticator" + ]; + masApps = { + "Codye" = 1516894961; + "Wireguard" = 1451685025; + "Xcode" = 497799835; + "One Thing" = 1604176982; + "Today" = 6443714928; + "Wipr" = 1320666476; + "Vinegar" = 1591303229; + "Noir" = 1592917505; + /* "Element X" = 1631335820; */ + }; + }; +} diff --git a/systems/mmacbookpro/dock.nix b/systems/mmacbookpro/dock.nix new file mode 100644 index 0000000..f1436b3 --- /dev/null +++ b/systems/mmacbookpro/dock.nix @@ -0,0 +1,54 @@ +{ config, pkgs, username, ... }: + +{ + system.defaults = { + dock = { + # Don't show recent applications + show-recents = false; + # Set the dock size + tilesize = 55; + # Bottom right hot corner - Quick Nnote + wvous-br-corner = 14; + # Disable these hot corners + wvous-bl-corner = 1; + wvous-tl-corner = 1; + wvous-tr-corner = 1; + }; + }; + + # Set the applications and folders on the dock + local.dock.entries = [ + # Applications + { path = "/System/Applications/Launchpad.app/"; } + { path = "/Applications/Things3.app/"; } + { path = "/Applications/RustRover.app/"; } + { path = "/Applications/PyCharm.app/"; } + { path = "/Applications/Emacs.app/"; } + { path = "/Applications/iTerm.app/"; } + { path = "/Applications/Obsidian.app/"; } + { path = "/Applications/Tower.app/"; } + { path = "/Applications/Sketch.app/"; } + { path = "/System/Volumes/Preboot/Cryptexes/App/System/Applications/Safari.app"; } + { path = "/System/Applications/Calendar.app/"; } + { path = "/System/Applications/Notes.app/"; } + { path = "/System/Applications/Freeform.app/"; } + { path = "/System/Applications/FindMy.app/"; } + { path = "/System/Applications/Music.app/"; } + { path = "/System/Applications/Mail.app/"; } + { path = "/System/Applications/Messages.app/"; } + { path = "/System/Applications/FaceTime.app/"; } + { path = "/Applications/Element.app/"; } + + # Folders + { + path = "/Users/${username}/Documents/"; + section = "others"; + options = "--sort name --display folder"; + } + { + path = "/Users/${username}/Downloads/"; + section = "others"; + options = "--sort dateadded"; + } + ]; +} diff --git a/systems/mmacbookpro/finder.nix b/systems/mmacbookpro/finder.nix new file mode 100644 index 0000000..27c6aca --- /dev/null +++ b/systems/mmacbookpro/finder.nix @@ -0,0 +1,15 @@ +{ config, ... }: + +{ + system.defaults = { + finder = { + AppleShowAllExtensions = true; + ShowPathbar = true; + ShowStatusBar = true; + FXDefaultSearchScope = "SCcf"; + FXPreferredViewStyle = "Nlsv"; + FXEnableExtensionChangeWarning = false; + }; + NSGlobalDomain.AppleShowAllExtensions = true; + }; +} diff --git a/systems/mmacbookpro/fonts.nix b/systems/mmacbookpro/fonts.nix new file mode 100644 index 0000000..3ad636f --- /dev/null +++ b/systems/mmacbookpro/fonts.nix @@ -0,0 +1,10 @@ +{ config, pkgs, ... }: + +{ + fonts.fonts = with pkgs; [ + font-awesome + nerdfonts + ]; + + fonts.fontDir.enable = true; +} diff --git a/systems/mmacbookpro/gpg.nix b/systems/mmacbookpro/gpg.nix new file mode 100644 index 0000000..238bdc5 --- /dev/null +++ b/systems/mmacbookpro/gpg.nix @@ -0,0 +1,11 @@ +{ config, pkgs, ... }: + +{ + programs.gnupg.agent = { + enable = true; + }; + + environment.systemPackages = with pkgs; [ + gnupg + ]; +} diff --git a/systems/mmacbookpro/keyboard.nix b/systems/mmacbookpro/keyboard.nix new file mode 100644 index 0000000..586b270 --- /dev/null +++ b/systems/mmacbookpro/keyboard.nix @@ -0,0 +1,20 @@ +{ config, ... }: + +{ + system.keyboard = { + enableKeyMapping = true; + remapCapsLockToEscape = true; + }; + + system.defaults.NSGlobalDomain = { + # Speed up key repeat + InitialKeyRepeat = 14; + KeyRepeat = 1; + # In general, have Apple not mess with our text + NSAutomaticCapitalizationEnabled = false; + NSAutomaticDashSubstitutionEnabled = false; + NSAutomaticPeriodSubstitutionEnabled = false; + NSAutomaticQuoteSubstitutionEnabled = null; + NSAutomaticSpellingCorrectionEnabled = false; + }; +} diff --git a/systems/mmacbookpro/networking.nix b/systems/mmacbookpro/networking.nix new file mode 100644 index 0000000..c938cc4 --- /dev/null +++ b/systems/mmacbookpro/networking.nix @@ -0,0 +1,8 @@ +{ config, ... }: + +{ + networking = { + computerName = "MacBook Pro"; + hostName = "MMacBookPro"; + }; +} diff --git a/systems/mmacbookpro/nix.nix b/systems/mmacbookpro/nix.nix new file mode 100644 index 0000000..45ba453 --- /dev/null +++ b/systems/mmacbookpro/nix.nix @@ -0,0 +1,20 @@ +{ config, pkgs, lib, ... }: + +{ + # Enable flakes and nix-command + nix = { + package = pkgs.nixVersions.stable; + settings = { + experimental-features = [ "nix-command" "flakes" ]; + auto-optimise-store = true; + }; + gc = { + automatic = true; + options = "--delete-older-than 7d"; + }; + extraOptions = lib.optionalString (pkgs.system == "aarch64-darwin") '' + extra-platforms = x86_64-darwin aarch64-darwin + ''; + }; + services.nix-daemon.enable = true; +} diff --git a/systems/mmacbookpro/packages.nix b/systems/mmacbookpro/packages.nix new file mode 100644 index 0000000..4405bf0 --- /dev/null +++ b/systems/mmacbookpro/packages.nix @@ -0,0 +1,26 @@ +{ config, pkgs, ... }: + +{ + environment.systemPackages = with pkgs; [ + # Processes + killall + + # Filesystems + dosfstools + + # Archives + zip + unzip + unrar + p7zip + + # Cli tools + ripgrep + wget + fzf + bat + + # Git + git + ]; +} diff --git a/systems/mmacbookpro/setDock.nix b/systems/mmacbookpro/setDock.nix new file mode 100644 index 0000000..3401be2 --- /dev/null +++ b/systems/mmacbookpro/setDock.nix @@ -0,0 +1,68 @@ +{ config, pkgs, lib, ... }: +with lib; +let + cfg = config.local.dock; + stdenv = pkgs.stdenv; + dockutil = pkgs.dockutil; +in +{ + options = { + local.dock.enable = mkOption { + description = "Enable dock"; + default = stdenv.isDarwin; + example = false; + }; + + local.dock.entries = mkOption + { + description = "Entries on the Dock"; + type = with types; listOf (submodule { + options = { + path = lib.mkOption { type = str; }; + section = lib.mkOption { + type = str; + default = "apps"; + }; + options = lib.mkOption { + type = str; + default = ""; + }; + }; + }); + readOnly = true; + }; + }; + + config = + mkIf (cfg.enable) + ( + let + normalize = path: if hasSuffix ".app" path then path + "/" else path; + entryURI = path: "file://" + (builtins.replaceStrings + [" " "!" "\"" "#" "$" "%" "&" "'" "(" ")"] + ["%20" "%21" "%22" "%23" "%24" "%25" "%26" "%27" "%28" "%29"] + (normalize path) + ); + wantURIs = concatMapStrings + (entry: "${entryURI entry.path}\n") + cfg.entries; + createEntries = concatMapStrings + (entry: "${dockutil}/bin/dockutil --no-restart --add '${entry.path}' --section ${entry.section} ${entry.options}\n") + cfg.entries; + in + { + system.activationScripts.postUserActivation.text = '' + echo >&2 "Setting up the Dock..." + haveURIs="$(${dockutil}/bin/dockutil --list | ${pkgs.coreutils}/bin/cut -f2)" + if ! diff -wu <(echo -n "$haveURIs") <(echo -n '${wantURIs}') >&2 ; then + echo >&2 "Resetting Dock." + ${dockutil}/bin/dockutil --no-restart --remove all + ${createEntries} + killall Dock + else + echo >&2 "Dock setup complete." + fi + ''; + } + ); +} diff --git a/systems/mmacbookpro/settings.nix b/systems/mmacbookpro/settings.nix new file mode 100644 index 0000000..aa595d5 --- /dev/null +++ b/systems/mmacbookpro/settings.nix @@ -0,0 +1,74 @@ +{ config, ... }: + +{ + system.defaults = { + CustomUserPreferences = { + NSGlobalDomain = { + # Set system accent and highlight color to purple + AppleAccentColor = 5; + AppleHighlightColor = "0.968627 0.831373 1.000000 Purple"; + # Make the menu bar always visible + AppleMenuBarVisibleInFullscreen = 1; + }; + "com.apple.desktopservices" = { + # Don't write .DS_Store files to network or usb drives + DSDontWriteNetworkStores = true; + DSDontWriteUSBStores = true; + }; + # Magic Mouse + "com.apple.AppleMultitouchMouse" = { + # Enable right click + MouseButtonMode = "TwoButton"; + # Enable horizontal scrolling + MouseHorizontalScroll = 1; + # Enable one finger double tap for smart zoom + MouseOneFingerDoubleTapGesture = 1; + # Enable two finger tap for mission control + MouseTwoFingerDoubleTapGesture = 3; + # Enable two finger swipe to pan spaces + MouseTwoFingerHorizSwipeGesture = 2; + }; + # Trackpad + "com.apple.AppleMultitouchTrackpad" = { + # Don't secondary click on the corner of the trackpad + TrackpadCornerSecondaryClick = 0; + # Four/Five finger pinch for launchpad + TrackpadFourFingerPinchGesture = 2; + TrackpadFiveFingerPinchGesture = 2; + # Three/Four fingers swipe horizontally to pan spaces + TrackpadThreeFingerHorizSwipeGesture = 2; + TrackpadFourFingerHorizSwipeGesture = 2; + # Three/Four finger swipe vertically to activate mission control and app expose + TrackpadThreeFingerVertSwipeGesture = 2; + TrackpadFourFingerVertSwipeGesture = 2; + # Swipe two fingers from the right edge to open notification centre + TrackpadTwoFingerFromRightEdgeSwipeGesture = 3; + }; + }; + }; + + system.defaults = { + NSGlobalDomain = { + # Automatically enable dark theme at night + AppleInterfaceStyleSwitchesAutomatically = true; + # Use the metric system throughout macOS + AppleMetricUnits = 1; + # Always start with save dialog panels expanded + NSNavPanelExpandedStateForSaveMode = true; + NSNavPanelExpandedStateForSaveMode2 = true; + }; + loginwindow = { + # Disable using a guest user account + GuestEnabled = false; + }; + menuExtraClock = { + # Show seconds and date on menu bar clock + ShowSeconds = true; + ShowDate = 1; + }; + }; + + # Enable Touch ID for sudo + security.pam.enableSudoTouchIdAuth = true; +} + diff --git a/systems/mmacbookpro/ssh.nix b/systems/mmacbookpro/ssh.nix new file mode 100644 index 0000000..5d08ff7 --- /dev/null +++ b/systems/mmacbookpro/ssh.nix @@ -0,0 +1,7 @@ +{ config, pkgs, ... }: + +{ + environment.systemPackages = with pkgs; [ + openssh + ]; +} diff --git a/systems/mmacbookpro/sudo.nix b/systems/mmacbookpro/sudo.nix new file mode 100644 index 0000000..d523187 --- /dev/null +++ b/systems/mmacbookpro/sudo.nix @@ -0,0 +1,5 @@ +{ config, ... }: + +{ + security.pam.enableSudoTouchIdAuth = true; +} diff --git a/systems/mmacbookpro/zsh.nix b/systems/mmacbookpro/zsh.nix new file mode 100644 index 0000000..2a5ba4c --- /dev/null +++ b/systems/mmacbookpro/zsh.nix @@ -0,0 +1,10 @@ +{ config, pkgs, ... }: + +{ + programs.zsh = { + enable = true; + enableSyntaxHighlighting = true; + enableCompletion = true; + }; + environment.loginShell = pkgs.zsh; +} diff --git a/utils/default.nix b/utils/default.nix new file mode 100644 index 0000000..04a7376 --- /dev/null +++ b/utils/default.nix @@ -0,0 +1,28 @@ +pkgs_or_lib: +let + is_pkgs = pkgs_or_lib ? lib; + lib = if is_pkgs then pkgs_or_lib.lib else pkgs_or_lib; + utils = lib.pipe ./. [ + (import ./nixFilesInWithName.nix lib) + (builtins.map (file: rec { + name = lib.removeSuffix ".nix" file.name; + func = import file.path; + accepts_pkgs = builtins.hasAttr "pkgs" (builtins.functionArgs func); + value = + if accepts_pkgs then + func + (builtins.intersectAttrs (builtins.functionArgs func) { + inherit + lib utils; pkgs = pkgs_or_lib; + }) + else if is_pkgs + then func lib + else + func pkgs_or_lib; + include = file.name != "default.nix" && (!accepts_pkgs || is_pkgs); + })) + (builtins.filter (utility: utility.include)) + builtins.listToAttrs + ]; +in +utils diff --git a/utils/nixFilesIn.nix b/utils/nixFilesIn.nix new file mode 100644 index 0000000..e85fa1c --- /dev/null +++ b/utils/nixFilesIn.nix @@ -0,0 +1,2 @@ +# Modified from http://chriswarbo.net/projects/nixos/useful_hacks.html +lib: dir: map (name: dir + "/${name}") (lib.attrNames (lib.filterAttrs (name: type: type == "regular" && lib.hasSuffix ".nix" name) (builtins.readDir dir))) diff --git a/utils/nixFilesInWithName.nix b/utils/nixFilesInWithName.nix new file mode 100644 index 0000000..760b7cf --- /dev/null +++ b/utils/nixFilesInWithName.nix @@ -0,0 +1,8 @@ +# Modified from http://chriswarbo.net/projects/nixos/useful_hacks.html +lib: dir: +map + (name: { + inherit name; + path = dir + "/${name}"; + }) + (lib.attrNames (lib.filterAttrs (name: type: lib.hasSuffix ".nix" name && type == "regular") (builtins.readDir dir)))