├── .gitignore ├── .gitmodules ├── README.md ├── dotfiles ├── R.nix ├── cachix.nix ├── cachix │ ├── digitallyinduced.nix │ └── miso-haskell.nix ├── colors-sway ├── config.nu ├── configuration.nix ├── emacs │ └── doom.d │ │ ├── config.el │ │ ├── init.el │ │ └── packages.el ├── env.nu ├── flake.lock ├── flake.nix ├── gnome.nix ├── hardware-configuration.nix ├── home.nix ├── hyprland.conf ├── niri.nix ├── nix-doom-emacs.nix ├── python.nix ├── waybar-style.css └── xmonad.hs └── scripts ├── aspell.en.pws ├── config.py ├── downloadBook.py ├── getBook.el ├── homepage ├── config.py ├── homepage.html ├── homepage.sh └── template-pandoc.html ├── notifications.sh ├── org-clock.hs ├── org-clock.sh ├── proverboj.txt ├── pywal-emacs.py ├── pywal-reload.sh ├── qutebrowser-userscripts ├── dict ├── org-link ├── org-link.hs ├── org-movie ├── qute-pass └── qutepass.py ├── setup.fish ├── sway-reload.sh ├── wikidata.el ├── wikidata.hs └── wikidata.py /.gitignore: -------------------------------------------------------------------------------- 1 | bak/ 2 | dotfiles/.vim/undo 3 | dotfiles/.vim/plugged/ 4 | dotfiles/.vim/spell/en.utf-8.spl 5 | dotfiles/.vim/spell/en.utf-8.sug 6 | dotfiles/.vim/init.vim 7 | dotfiles/.vim/.netrwhist 8 | dotfiles/.vim/swap/ 9 | dotfiles/.vim/backup/ 10 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "scripts/toggl-cli"] 2 | path = scripts/toggl-cli 3 | url = https://github.com/drobertadams/toggl-cli 4 | [submodule "scripts/scripts/toggl-cli"] 5 | path = scripts/scripts/toggl-cli 6 | url = https://github.com/drobertadams/toggl-cli 7 | [submodule "scripts/ewal"] 8 | path = scripts/ewal 9 | url = https://gitlab.com/jjzmajic/ewal.git 10 | [submodule "dynamic-wallpaper"] 11 | path = dynamic-wallpaper 12 | url = https://github.com/adi1090x/dynamic-wallpaper.git 13 | [submodule "scripts/nu_scripts"] 14 | path = scripts/nu_scripts 15 | url = https://github.com/nushell/nu_scripts 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dotfiles 2 | 3 | My personal config files for NixOS, doom-emacs, and so on. 4 | 5 | I wouldn't recommend using these files, unless you're me. 6 | 7 | # Installation 8 | 9 | ``` sh 10 | cd dotfiles 11 | nixos-rebuild --flake . 12 | ``` 13 | -------------------------------------------------------------------------------- /dotfiles/R.nix: -------------------------------------------------------------------------------- 1 | { config, lib, pkgs, ... }: 2 | 3 | let 4 | pmt = pkgs.rPackages.buildRPackage { 5 | name = "pmt"; 6 | src = pkgs.fetchFromGitHub { 7 | owner = "jbedo"; 8 | repo = "pmt"; 9 | rev = "f5af7ada6f419382415335f5ae283f8a4643f79c"; 10 | sha256 = "ODIRNRKsqBOqrOINQpOBOET5izKmhnp2F8DCVl4BOQI="; 11 | }; 12 | }; 13 | nominatim = pkgs.rPackages.buildRPackage { 14 | name = "nominatim"; 15 | src = pkgs.fetchFromGitHub { 16 | owner = "hrbrmstr"; 17 | repo = "nominatim"; 18 | rev = "5c2baa9da26bc81eb769c39f6eb64fa81db01d34"; 19 | sha256 = "mHkLo07mh1fgox7kfrUZg/IDSQQKimFmzDajyrBNmzw="; 20 | }; 21 | propagatedBuildInputs = with pkgs.rPackages; [ 22 | httr dplyr pbapply curl sp jsonlite 23 | ]; 24 | }; 25 | cdcfluview = pkgs.rPackages.buildRPackage { 26 | name = "cdcfluview"; 27 | src = pkgs.fetchFromGitHub { 28 | owner = "hrbrmstr"; 29 | repo = "cdcfluview"; 30 | rev = "cc1791b79b492d305a3619b97e416207ecfd2887"; 31 | sha256 = "DBwJD+DO7MZl7z4hbm9stL7FKubJX7Y7a6z/zXoJk2o="; 32 | }; 33 | propagatedBuildInputs = with pkgs.rPackages; [ 34 | httr 35 | progress 36 | dplyr 37 | tibble 38 | sf 39 | xml2 40 | purrr 41 | readr 42 | MMWRweek 43 | units 44 | sp 45 | jsonlite 46 | ]; 47 | }; 48 | 49 | ggcounty = pkgs.rPackages.buildRPackage { 50 | name = "ggcounty"; 51 | src = pkgs.fetchFromGitHub { 52 | owner = "hrbrmstr"; 53 | repo = "ggcounty"; 54 | rev = "3e63f81cc395b15632b68400808ffcdc441af70e"; 55 | sha256 = "3Xhx+RAKxaxK1DXCGdIn6zgXf0DIL/y4A3xiPfdaIOc="; 56 | }; 57 | propagatedBuildInputs = with pkgs.rPackages; [ 58 | ]; 59 | }; 60 | 61 | geospatial = pkgs.rPackages.buildRPackage { 62 | name = "geospatial"; 63 | src = pkgs.fetchFromGitHub { 64 | owner = "cwickham"; 65 | repo = "geospatial"; 66 | rev = "c5df470b558db7f812cdc9d9605107399dcf49af"; 67 | sha256 = "h2VTR0IKMlL1/0c5Vhi7zQau7SUHMrMEK1yH/cB/+uA="; 68 | }; 69 | propagatedBuildInputs = with pkgs.rPackages; [ 70 | ]; 71 | }; 72 | 73 | rnaturalearthhires = pkgs.rPackages.buildRPackage { 74 | name = "rnaturalearthhires"; 75 | src = pkgs.fetchFromGitHub { 76 | owner = "ropenscilabs"; 77 | repo = "rnaturalearthhires"; 78 | rev = "2ed7a937f3cca4f44b157098c472f6b3ae8cd9f3"; 79 | sha256 = "NNJwCXrYBvgt8IU2726uaYKP2kKdEh+i+Pb8J8GTknc="; 80 | }; 81 | propagatedBuildInputs = with pkgs.rPackages; [ 82 | sp 83 | ]; 84 | }; 85 | 86 | urbnmapr = pkgs.rPackages.buildRPackage { 87 | name = "urbnmapr"; 88 | src = pkgs.fetchFromGitHub { 89 | owner = "UrbanInstitute"; 90 | repo = "urbnmapr"; 91 | rev = "ef9f4488d6bc916a07746aafe5755e9fb9da19eb"; 92 | sha256 = "/nQQo9tLzvfMelZuLs3uKeCrFdwokfdVtNaziNXgoSc="; 93 | }; 94 | propagatedBuildInputs = with pkgs.rPackages; [ 95 | tibble mapproj sf 96 | ]; 97 | }; 98 | myRPackages = with pkgs.rPackages; 99 | [ 100 | DT 101 | RColorBrewer 102 | RCurl 103 | RJSONIO 104 | XML 105 | bindrcpp 106 | broom 107 | cdcfluview 108 | devtools 109 | dplyr 110 | gert 111 | ggcounty 112 | geospatial 113 | ggmap 114 | ggplot2 115 | ggthemes 116 | httr 117 | knitr 118 | mapproj 119 | maps 120 | maptools 121 | nominatim 122 | osmdata 123 | pmt 124 | raster 125 | readr 126 | readxl 127 | reshape2 128 | rgdal 129 | rgeos 130 | rnaturalearth 131 | rnaturalearthdata 132 | rnaturalearthhires 133 | rvest 134 | s2 135 | scales 136 | sf 137 | statebins 138 | stringr 139 | stylo 140 | tidyverse 141 | tmap 142 | tmaptools 143 | units 144 | urbnmapr 145 | xaringan 146 | xfun 147 | xml2 148 | ]; 149 | in { 150 | environment.systemPackages = with pkgs; [ 151 | (rWrapper.override { packages = myRPackages; } ) 152 | (rstudioWrapper.override { packages = myRPackages; } ) 153 | ]; 154 | } 155 | -------------------------------------------------------------------------------- /dotfiles/cachix.nix: -------------------------------------------------------------------------------- 1 | 2 | # WARN: this file will get overwritten by $ cachix use 3 | { pkgs, lib, ... }: 4 | 5 | let 6 | folder = ./cachix; 7 | toImport = name: value: folder + ("/" + name); 8 | filterCaches = key: value: value == "regular" && lib.hasSuffix ".nix" key; 9 | imports = lib.mapAttrsToList toImport (lib.filterAttrs filterCaches (builtins.readDir folder)); 10 | in { 11 | inherit imports; 12 | nix.binaryCaches = ["https://cache.nixos.org/"]; 13 | } 14 | -------------------------------------------------------------------------------- /dotfiles/cachix/digitallyinduced.nix: -------------------------------------------------------------------------------- 1 | 2 | { 3 | nix = { 4 | binaryCaches = [ 5 | "https://digitallyinduced.cachix.org" 6 | ]; 7 | binaryCachePublicKeys = [ 8 | "digitallyinduced.cachix.org-1:y+wQvrnxQ+PdEsCt91rmvv39qRCYzEgGQaldK26hCKE=" 9 | ]; 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /dotfiles/cachix/miso-haskell.nix: -------------------------------------------------------------------------------- 1 | 2 | { 3 | nix = { 4 | binaryCaches = [ 5 | "https://miso-haskell.cachix.org" 6 | ]; 7 | binaryCachePublicKeys = [ 8 | "miso-haskell.cachix.org-1:6N2DooyFlZOHUfJtAx1Q09H0P5XXYzoxxQYiwn6W1e8=" 9 | ]; 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /dotfiles/colors-sway: -------------------------------------------------------------------------------- 1 | set $wallpaper /home/jon/Bildujo/Ekranfonoj/yz6ggt7m18l41.png 2 | 3 | set $background #2E3440 4 | set $foreground #E5E9F0 5 | 6 | set $color0 #2E3440 7 | set $color1 #88C0D0 8 | set $color2 #BF616A 9 | set $color3 #5E81AC 10 | set $color4 #EBCB8B 11 | set $color5 #A3BE8C 12 | set $color6 #D08770 13 | set $color7 #E5E9F0 14 | set $color8 #4C566A 15 | set $color9 #88C0D0 16 | set $color10 #BF616A 17 | set $color11 #5E81AC 18 | set $color12 #EBCB8B 19 | set $color13 #A3BE8C 20 | set $color14 #D08770 21 | set $color15 #8FBCBB 22 | -------------------------------------------------------------------------------- /dotfiles/config.nu: -------------------------------------------------------------------------------- 1 | 2 | # spawn task to run in the background 3 | use ~/Agordoj/scripts/nu_scripts/modules/background_task/task.nu 4 | 5 | # Wallpaper management 6 | def wal-fav [] { 7 | open ~/.cache/wal/colors.json | get wallpaper | 8 | each { |it| echo $it (char newline)} | 9 | str join | save --append ~/.cache/wal/favs 10 | } 11 | 12 | def wal-fav-set [] { 13 | task spawn -i -l swaybg { 14 | ^pkill swaybg 15 | task kill 16 | let w = (open ~/.cache/wal/favs | lines | uniq | shuffle | first) 17 | echo $"Using ($w)" 18 | swaybg -i $w -m fill 19 | } 20 | } 21 | 22 | def wal-recent [] { 23 | wal -i (ls /run/media/jon/systemrestore/.systemrestore/Bildoj 24 | | sort-by modified -r 25 | | first 50 26 | | shuffle 27 | | first 28 | | get name) 29 | } 30 | 31 | def wal-backup [] { 32 | sudo rsync -a /home/systemrestore/Bildoj /run/media/jon/systemrestore/.systemrestore 33 | } 34 | 35 | # Project managemnt 36 | def proj [project] { 37 | open ~/Dotfiles/scripts/projects.yaml | where name == $project | select websites | each { |it| qutebrowser $it.websites }; 38 | open ~/Dotfiles/scripts/projects.yaml | where name == $project | select textFiles | each { emacsclient -c $it.textFiles & }; 39 | } 40 | 41 | def create_left_prompt [] { 42 | starship prompt --cmd-duration $env.CMD_DURATION_MS $'--status=($env.LAST_EXIT_CODE)' 43 | } 44 | 45 | # Handy aliases 46 | def em [f] { spawn { emacsclient -c $f } } 47 | -------------------------------------------------------------------------------- /dotfiles/configuration.nix: -------------------------------------------------------------------------------- 1 | # Edit this configuration file to define what should be installed on 2 | # your system. Help is available in the configuration.nix(5) man page 3 | # and in the NixOS manual (accessible by running ‘nixos-help’). 4 | 5 | { config, pkgs, options, lib, ... }: 6 | 7 | { 8 | imports = 9 | [ # Include the results of the hardware scan. 10 | #./cachix.nix 11 | ./gnome.nix 12 | ./hardware-configuration.nix 13 | ./python.nix 14 | # ./R.nix 15 | ]; 16 | 17 | # Use the systemd-boot EFI boot loader. 18 | boot = { 19 | # Enable magic sysrql (Alt+PrtSc) keys for recovery 20 | kernel.sysctl = { "kernel.sysrq" = 1; }; 21 | kernelPackages = pkgs.linuxPackages_latest; 22 | kernelModules = [ "btqca" "hci_qca" "hci_uart" "bluetooth" ]; 23 | blacklistedKernelModules = [ "psmouse" ]; 24 | tmp.cleanOnBoot = true; 25 | plymouth.enable = true; 26 | resumeDevice = "/dev/nvme0n1p3"; 27 | loader.systemd-boot.enable = true; 28 | loader.efi.canTouchEfiVariables = true; 29 | }; 30 | 31 | networking = { 32 | hostName = "jon-laptop"; # Define your hostname . 33 | networkmanager.enable = true; 34 | firewall.checkReversePath = "loose"; 35 | useDHCP = false; 36 | # interfaces.wlp0s20f3.useDHCP = true; 37 | interfaces.enp0s13f0u1u3u1.useDHCP = true; 38 | # firewall.allowedTCPPorts = [ 8000 ]; # For local agenda server 39 | }; 40 | 41 | nix = { 42 | # package = pkgs.nixFlakes; # For flakes 43 | extraOptions = '' 44 | experimental-features = nix-command flakes 45 | keep-outputs = true 46 | keep-derivations = true 47 | ''; 48 | }; 49 | 50 | nixpkgs = { 51 | config = { allowUnfree = true; 52 | allowBroken = true; 53 | }; 54 | overlays = [ 55 | # (import (builtins.fetchTarball { 56 | # url = https://github.com/nix-community/emacs-overlay/archive/master.tar.gz; 57 | # sha256 = "0i74f97f3ljr49jlhh60pglqsfj6vbwigyrl5q76sclirkzfyvr0"; 58 | # } 59 | # )) 60 | ]; 61 | }; 62 | 63 | 64 | console.useXkbConfig = true; 65 | 66 | # Select internationalisation properties. 67 | i18n = { 68 | defaultLocale = "eo.UTF-8"; 69 | supportedLocales = [ "eo/UTF-8" "en_US.UTF-8/UTF-8" ]; 70 | }; 71 | 72 | # Fonts! 73 | fonts.packages = with pkgs; [ 74 | fantasque-sans-mono 75 | font-awesome_5 76 | fira-code 77 | noto-fonts 78 | noto-fonts-cjk 79 | noto-fonts-emoji 80 | fira-code 81 | fira-code-symbols 82 | font-awesome 83 | libertine 84 | victor-mono 85 | emacs-all-the-icons-fonts 86 | # font-fonts 87 | # monoid 88 | kochi-substitute # Japanese 89 | iosevka-comfy.comfy 90 | ]; 91 | # Set your time zone. 92 | time.timeZone = "America/Los_Angeles"; 93 | 94 | # List packages installed in system profile. To search, run: 95 | # $ nix search wget 96 | environment.systemPackages = with pkgs; 97 | [ 98 | # Nix stuff 99 | nix-index # Indexing files for nix-locate 100 | nix-prefetch-git nix-prefetch-scripts # Help writing .nix files 101 | cabal2nix # pypi2nix 102 | nixfmt 103 | 104 | # Security 105 | # yubico-pam yubioath-desktop yubikey-personalization 106 | # yubikey-manager # Provides ykman 107 | # yubikey-personalization-gui 108 | 109 | megasync # Backups 110 | #megacmd 111 | keybase-gui # Also backups 112 | #logseq # Fancy notes 113 | 114 | # CLI 115 | fish # Shell 116 | vim # Text editors 117 | vale # Prose linting 118 | # aspell aspellDicts.en # Spell checker 119 | (aspellWithDicts (dicts: with dicts; [ en en-computers en-science eo fr ])) 120 | pass encfs # Passwords and encryption 121 | light # Brightness control 122 | networkmanager 123 | tailscale 124 | gcc gnumake libtool 125 | gnupg 126 | wget 127 | isync w3m # Mail 128 | protonmail-bridge 129 | 130 | gnutls # For mail auth 131 | protonvpn-cli # VPN 132 | pandoc 133 | zlib # For Pandoc development 134 | 135 | #direnv # Essential project management thingy 136 | graphviz # Simple charts 137 | xclip # Clipboard on the command line 138 | x11idle 139 | dict # Dictionary 140 | 141 | pywal 142 | wallust 143 | ranger 144 | 145 | # Building stuff 146 | cmake 147 | extra-cmake-modules 148 | 149 | # (emacsWithPackagesFromUsePackage { 150 | # config = ""; 151 | # package = pkgs.emacsPgtkNativeComp; 152 | # extraEmacsPackages = epkgs: [ 153 | # epkgs.pdf-tools 154 | # ]; 155 | # }) 156 | 157 | # (emacs.pkgs.withPackages (epkgs: with emacsPackages; [ 158 | # pdf-tools 159 | # ])) 160 | 161 | stack 162 | (haskellPackages.ghcWithPackages (ps: with ps; [ 163 | # pandoc-citeproc 164 | shake # Build tool 165 | hlint # Required for spacemacs haskell-mode 166 | apply-refact # Required for spacemacs haskell-mode 167 | hasktags # Required for spacemacs haskell-mode 168 | hoogle # Required for spacemacs haskell-mode 169 | lucid 170 | # stylish-haskell # Required for spacemacs haskell-mode 171 | # ^ marked as broken 172 | turtle # Scripting 173 | regex-compat 174 | #PyF 175 | HandsomeSoup 176 | tokenize 177 | # chatter 178 | ])) 179 | # ihaskell 180 | 181 | cabal-install 182 | texlive.combined.scheme-full 183 | git # Version control 184 | github-cli 185 | zip unzip # Archives 186 | 187 | texlive.combined.scheme-full 188 | git git-lfs # Version control 189 | unzip # Archives 190 | file # File properties 191 | imagemagick # Image manipulation 192 | libxml2 193 | sqlite sqlite-interactive # Sqlite 194 | 195 | # Elm 196 | elmPackages.elm 197 | # elmPackages.elm-review 198 | elmPackages.elm-format 199 | # Julia 200 | julia-stable-bin 201 | # Scala 202 | dotty 203 | metals 204 | coursier 205 | # ammonite 206 | # Minimal computing 207 | ranger highlight # File manager 208 | scrot # Screenshots 209 | tree # Show file hierarchies 210 | mpv # Minimalist video player 211 | #termite # Vim-like modal terminal 212 | feh # Display images 213 | libnotify # Notifications 214 | fzf # Fuzzy file finder 215 | ripgrep # Fast grep replacement 216 | bat # Cat replacement 217 | fd # Find replacement 218 | sd # Sed replacement 219 | bottom # Top replacement (system monitor) 220 | ncdu # Fancy disk usage analyzer 221 | neofetch # Fancy system information 222 | # GUI 223 | #qutebrowser # Web browser 224 | chromium # Another web browser 225 | firefox-wayland # Yes, a third 226 | nyxt # Why stop now? 227 | 228 | # Ugh 229 | zoom-us 230 | # calibre # Ebooks 231 | 232 | ntfs3g ntfsprogs # Windows drives compatibility 233 | 234 | # Sound 235 | alsa-tools 236 | #alsaPlugins 237 | alsa-utils 238 | alsa-firmware 239 | pavucontrol 240 | 241 | # Keyboard stuff 242 | plover.dev 243 | # xorg.libxcb 244 | # xorg.xcbutil 245 | # libsForQt5.qtstyleplugins 246 | waydroid 247 | 248 | # sway related 249 | swaybg 250 | wdisplays 251 | polkit 252 | wl-clipboard 253 | # autotiling 254 | 255 | # Hyprland 256 | hyprland 257 | 258 | # Web dev 259 | nodejs 260 | 261 | # Notetaking 262 | anytype 263 | 264 | # Editor 265 | vscode 266 | 267 | # Write books 268 | quarto 269 | #jupyter-book 270 | 271 | 272 | ]; 273 | 274 | environment.variables = { 275 | # Preferred applications 276 | EDITOR = "emacsclient -c"; 277 | BROWSER = "qutebrowser"; 278 | CM_LAUNCHER = "rofi"; # Clipmenu 279 | }; 280 | 281 | # Enable sound. 282 | sound.enable = true; 283 | hardware = { 284 | firmware = with pkgs; [ firmwareLinuxNonfree ]; 285 | pulseaudio = { 286 | enable = true; 287 | }; 288 | sensor.iio.enable = true; 289 | bluetooth.enable = true; 290 | }; 291 | # home-manager.users.jon = import ./home.nix; 292 | powerManagement = { 293 | enable = true; 294 | powertop.enable = true; 295 | }; 296 | 297 | services = { 298 | dictd = { 299 | enable = true; 300 | DBs = with pkgs.dictdDBs; [ wiktionary wordnet ]; 301 | }; 302 | flatpak.enable = true; 303 | fwupd.enable = true; # Firmware updates 304 | 305 | keybase.enable = true; 306 | kbfs = { 307 | enable = true; 308 | mountPoint = "%h/Keybase"; 309 | }; 310 | 311 | # localtime.enable = true; 312 | 313 | libinput = { 314 | enable = true; 315 | touchpad = { 316 | clickMethod = "clickfinger"; 317 | disableWhileTyping = true; 318 | }; 319 | }; 320 | 321 | # Power button invokes suspend, not shutdown. 322 | logind = { 323 | extraConfig = "HandlePowerKey=suspend"; 324 | lidSwitch = "suspend"; 325 | }; 326 | 327 | # Power management 328 | upower.enable = true; 329 | 330 | # Plex media server 331 | plex = { 332 | user = "systemrestore"; 333 | group = "users"; 334 | enable = false; 335 | openFirewall = true; 336 | }; 337 | 338 | # VPN 339 | tailscale.enable = true; 340 | 341 | # Security 342 | udev.packages = [ pkgs.yubikey-personalization pkgs.libu2f-host ]; 343 | pcscd.enable = true; 344 | mozillavpn = { 345 | enable = true; 346 | }; 347 | 348 | # X 349 | xserver = { 350 | enable = true; 351 | # Enable touchpad support. 352 | # Keyboard settings 353 | xkb = { 354 | layout = "us"; 355 | variant = "colemak"; 356 | }; 357 | desktopManager.session = [ 358 | { name = "home-manager"; 359 | start = ''${pkgs.stdenv.shell} $HOME/.xsession-hm 360 | & waitPID=$!''; 361 | } 362 | ]; 363 | # windowManager.exwm = { 364 | # enable = true; 365 | # enableDefaultConfig = true; 366 | # }; 367 | }; 368 | }; 369 | 370 | # Shell 371 | programs = { 372 | fish.enable = true; 373 | chromium = { 374 | enable = true; 375 | }; 376 | gnupg.agent = { enable = true; enableSSHSupport = true; }; 377 | # hyprland.enable = true; 378 | sway = { 379 | enable = true; 380 | wrapperFeatures.gtk = true; 381 | }; 382 | zsh.enable = true; 383 | }; 384 | 385 | users.users = { 386 | jon = 387 | { isNormalUser = true; 388 | home = "/home/jon"; 389 | shell = pkgs.zsh; 390 | description = "Jonathan Reeve"; 391 | extraGroups = [ "audio" "wheel" "networkmanager" "tty" "dialout" "input" "docker" "video"]; 392 | }; 393 | systemrestore = 394 | { isNormalUser = true; 395 | home = "/home/systemrestore"; 396 | shell = pkgs.fish; 397 | description = "System Restore"; 398 | extraGroups = [ "wheel" "networkmanager" ]; 399 | }; 400 | }; 401 | 402 | 403 | # Don't ask for my password *quite* as often. 404 | security = { 405 | sudo.extraConfig = "Defaults timestamp_timeout=60"; 406 | # pam.u2f = { 407 | # enable = true; 408 | # # control = "required"; 409 | # # cue = true; 410 | # # interactive = true; 411 | # }; 412 | }; 413 | 414 | # systemd.user.services.protonmail = { 415 | # description = "Protonmail Bridge"; 416 | # enable = true; 417 | # script = 418 | # "${pkgs.protonmail-bridge}/bin/protonmail-bridge --log-level debug"; 419 | # path = [ pkgs.gnome.gnome-keyring ]; # HACK: https://github.com/ProtonMail/proton-bridge/issues/176 420 | # wantedBy = [ "graphical-session.target" ]; 421 | # partOf = [ "graphical-session.target" ]; 422 | # }; 423 | # This value determines the NixOS release with which your system is to be 424 | # compatible, in order to avoid breaking some software such as database 425 | # servers. You should change this only after NixOS release notes say you 426 | # should. 427 | system.stateVersion = "23.11"; # Did you read the comment? 428 | 429 | # virtualisation.anbox.enable = true; 430 | virtualisation.docker.enable = true; 431 | virtualisation.libvirtd.enable = true; 432 | 433 | } 434 | -------------------------------------------------------------------------------- /dotfiles/emacs/doom.d/config.el: -------------------------------------------------------------------------------- 1 | ;;; .doom.d/config.el -*- lexical-binding: t; -*- 2 | 3 | ;; Place your private configuration here 4 | 5 | ;; Enables Nixos-installed packages to be loaded 6 | (require 'package) 7 | (setq package-enable-at-startup nil) 8 | (package-initialize) 9 | 10 | ;; Set location of custom.el 11 | (setq custom-file "~/.config/emacs/custom.el") 12 | 13 | (setq doom-font (font-spec :family "Victor Mono" :size 18)) 14 | (setq doom-themes-treemacs-enable-variable-pitch 'nil) 15 | 16 | (setq vc-follow-symlinks t) ;; Always follow symlinks. 17 | 18 | ;; Get system notifications through libnotify 19 | (setq alert-default-style 'libnotify) 20 | 21 | ;; Don't prompt when opening journal or other large files 22 | ;(setq large-file-warning-threshold 20000000) 23 | 24 | ;; Default spelling dictionary is English 25 | (setq ispell-dictionary "english") 26 | 27 | (after! spell-fu 28 | (add-hook 'spell-fu-mode-hook 29 | (lambda () 30 | (spell-fu-dictionary-add (spell-fu-get-ispell-dictionary "en")) 31 | (spell-fu-dictionary-add 32 | (spell-fu-get-personal-dictionary "en-personal" "/home/jon/Dotfiles/scripts/aspell.en.pws"))))) 33 | 34 | ;; Bibliography 35 | 36 | ;; Citar 37 | ;; See https://github.com/hlissner/doom-emacs/blob/4612b39695405f7238dd3da0d4fd6d3a5cdd93d6/modules/tools/biblio/README.org 38 | (setq! citar-bibliography '("~/Dokumentoj/Papers/library.bib" "~/Dokumentoj/Papers/library2.bib") 39 | citar-library-paths '("~/Dokumentoj/Papers/") 40 | citar-notes-paths '("~/Dokumentoj/Org/Roam/")) 41 | 42 | (setq! bibtex-completion-bibliography '("~/Dokumentoj/Papers/library.bib" "~/Dokumentoj/Papers/library2.bib") 43 | bibtex-completion-notes-path "~/Dokumentoj/Org/Roam/" 44 | bibtex-completion-library-path "~/Dokumentoj/Papers/") 45 | 46 | ;; Org Mode 47 | (after! org 48 | (org-indent-mode) 49 | (setq org-directory "~/Dokumentoj/Org" 50 | org-id-locations-file "~/Dokumentoj/Org/.orgids" 51 | org-startup-indented t 52 | org-startup-folded t 53 | evil-org-key-theme '(textobjects navigation additional insert todo) 54 | org-default-priority ?C 55 | org-lowest-priority ?G 56 | org-duration-format 'h:mm 57 | diary-file "~/Dokumentoj/Org/diary" 58 | org-agenda-include-diary t 59 | org-agenda-files (list "~/Dokumentoj/Org/Projects/") 60 | org-agenda-skip-scheduled-if-done t 61 | org-agenda-skip-deadline-if-done t 62 | org-todo-keywords '((sequence "TODO" "WAITING" "|" "DONE" "CANCELED")) 63 | org-todo-keywords-for-agenda '((sequence "TODO" "WAITING" "|" "DONE" "CANCELED")) 64 | ;; Put state changes into the LOGBOOK drawer, to clean up a bit 65 | org-log-into-drawer t 66 | ) 67 | (setq org-refile-targets '((nil :maxlevel . 9) 68 | (org-agenda-files :maxlevel . 9))) 69 | (setq org-outline-path-complete-in-steps nil) ; Refile in a single go 70 | (setq org-refile-use-outline-path t) ; Show full paths for refiling 71 | 72 | ;; Adapted from http://stackoverflow.com/a/12751732/584121 73 | ; (require 'org-protocol) 74 | (setq org-protocol-default-template-key "l") 75 | (setq org-capture-templates 76 | '(("t" "Todo" entry (file+headline "/home/jon/Dokumentoj/Org/notes.org" "Tasks") 77 | "* TODO %? %i\n %a") 78 | ("m" "Movie" entry (file+headline "/home/jon/Dokumentoj/Org/Roam/movies.org" "to watch") 79 | "* %a\n %?\n %i") 80 | ("l" "Link" entry (file+olp "/home/jon/Dokumentoj/Org/notes.org" "Web Links") 81 | "* %a\n %?\n %i") 82 | ("s" "Schedule" entry (file "/home/jon/Dokumentoj/Org/Projects/schedule.org") 83 | "* %?\n :PROPERTIES:\n :LOCATION:\n :END:\n %a\n %i") 84 | )) 85 | (setq org-modules '(org-habit org-protocol)) 86 | ;; Disable holidays. Is there an easier way of doing this? 87 | (setq holiday-christian-holidays nil 88 | holiday-islamic-holidays nil 89 | holiday-bahai-holidays nil 90 | holiday-oriental-holidays nil 91 | holiday-hebrew-holidays nil) 92 | (add-hook 'org-agenda-mode-hook 93 | (lambda () 94 | (calendar-set-date-style 'iso))) 95 | 96 | (defun org-journal-new-entry () 97 | "Inserts header with inactive timestamp, hours and minutes. 98 | A custom journal helper function." 99 | (interactive) 100 | (org-insert-heading) 101 | (org-insert-time-stamp (current-time) t t)) 102 | 103 | ;; Clock break time in pomodoro 104 | (setq org-pomodoro-clock-break t) 105 | (add-hook 'org-mode-hook 'visual-line-mode) 106 | 107 | (setq org-roam-directory "~/Dokumentoj/Org/Roam") 108 | (setq org-roam-dailies-directory "Daily/") 109 | (setq org-roam-db-location "~/Dokumentoj/Org/Roam/org-roam.db") 110 | ;; Get a timestamp for tomorrow 111 | (defun my/tomorrow () 112 | (format-time-string "%Y-%m-%d" (time-add 86400 (current-time)))) 113 | (setq org-roam-dailies-capture-templates 114 | '(("d" "default" entry 115 | "* %?" 116 | :target (file+head "%<%Y-%m-%d>.org" 117 | ":PROPERTIES: 118 | :DRINKS: 119 | :PHONE: 120 | :KETO: 121 | :EXERCISE: 122 | :MOOD: 123 | :END: 124 | #+title: %<%Y-%m-%d> 125 | 126 | #+BEGIN: clocktable :scope agenda :maxlevel 2 :step day :fileskip0 true :tstart \"%<%Y-%m-%d>\" :tend \"%(my/tomorrow)\" 127 | #+END: ")))) 128 | 129 | (setq org-roam-capture-templates 130 | '(("d" "default" plain "%?" :target 131 | (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n") 132 | :unnarrowed t) 133 | ("m" "movie" plain "** ${title}\n :PROPERTIES:\n :ID: %(org-id-uuid)\n :RATING:\n :END:\n%u\n" 134 | :target (file+olp "movies.org" ("watched") 135 | )))) 136 | (setq org-roam-capture-ref-templates 137 | '(("r" "ref" plain "%?" :target 138 | (file+head "${slug}.org" "#+title: ${title}") :unnarrowed t) 139 | ("m" "movie" plain "** ${title}\n :PROPERTIES:\n :ID: %(org-id-uuid)\n :RATING:\n :WIKIDATA: ${ref}\n :END:\n%u\n" 140 | :target (file+olp "movies.org" ("watched"))) 141 | ) 142 | ) 143 | 144 | 145 | (setq org-clock-idle-time 15) 146 | (setq org-clock-auto-clockout t) 147 | (setq org-clock-auto-clockout-timer 20) 148 | 149 | (require 'org-roam-bibtex) 150 | (use-package! org-roam-bibtex 151 | :when (featurep! :lang org +roam2) 152 | :after org 153 | :preface 154 | ;; if the user has not set a template mechanism set a reasonable one of them 155 | ;; The package already tests for nil itself so we define a dummy tester 156 | (defvar orb-preformat-keywords 157 | '("title" "url" "file" "author-or-editor" "keywords" "citekey" "pdf")) 158 | ;;:hook (org-roam-mode . org-roam-bibtex-mode) 159 | :custom 160 | (orb-note-actions-interface 'default) 161 | :config 162 | (setq orb-insert-interface 'generic) 163 | ;; (setq orb-roam-ref-format 'org-ref-v2) 164 | (setq orb-process-file-keyword t 165 | orb-file-field-extensions '("pdf")) 166 | 167 | (add-to-list 'org-roam-capture-templates 168 | '("b" "Bibliography note" plain 169 | "%? 170 | - keywords :: %^{keywords} 171 | - related :: 172 | 173 | * %^{title} 174 | :PROPERTIES: 175 | :Custom_ID: %^{citekey} 176 | :URL: %^{url} 177 | :AUTHOR: %^{author-or-editor} 178 | :NOTER_DOCUMENT: %^{file} 179 | :NOTER_PAGE: 180 | :END:\n\n" 181 | :if-new (file+head "${citekey}.org" ":PROPERTIES: 182 | :END: 183 | #+TITLE: ${citekey}: ${title}\n") 184 | :unnarrowed t)) 185 | (require 'org-ref)) 186 | (org-roam-bibtex-mode) 187 | 188 | (setq citar-templates 189 | '((main . "${author editor:30} ${date year issued:4} ${title:48}") 190 | (suffix . " ${=key= id:15} ${=type=:12} ${tags keywords keywords:*}") 191 | (preview . "${author editor} (${year issued date}) ${title}, ${journal journaltitle publisher container-title collection-title}.\n") 192 | (note . "#+title: ${author editor}, ${title}"))) 193 | 194 | ;; (setq citar-symbols 195 | ;; `((file ,(all-the-icons-faicon "file-o" :face 'all-the-icons-green :v-adjust -0.1) . " ") 196 | ;; (note ,(all-the-icons-material "speaker_notes" :face 'all-the-icons-blue :v-adjust -0.3) . " ") 197 | ;; (link ,(all-the-icons-octicon "link" :face 'all-the-icons-orange :v-adjust 0.01) . " "))) 198 | ;; (setq citar-symbol-separator " ") 199 | 200 | (setq citar-file-open-note-function 'orb-citar-edit-note) 201 | ;; (setq citar-file-open-note-function 'citar-file-open-notes-default-org) 202 | 203 | ;; Configure org-roam buffer display. 204 | ;; See https://www.orgroam.com/manual.html#Navigating-the-Org_002droam-Buffer 205 | (add-to-list 'display-buffer-alist 206 | '("\\*org-roam\\*" 207 | (display-buffer-in-direction) 208 | (direction . right) 209 | (window-width . 0.33) 210 | (window-height . fit-window-to-buffer))) 211 | 212 | (use-package! websocket 213 | :after org-roam) 214 | 215 | (use-package! org-roam-ui 216 | :after org-roam ;; or :after org 217 | ;; :hook 218 | ;; normally we'd recommend hooking orui after org-roam, but since org-roam does not have 219 | ;; a hookable mode anymore, you're advised to pick something yourself 220 | ;; if you don't care about startup time, use 221 | ;; :hook (after-init . org-roam-ui-mode) 222 | :config 223 | (setq org-roam-ui-sync-theme t 224 | org-roam-ui-follow t 225 | org-roam-ui-update-on-save t 226 | org-roam-ui-open-on-start nil) 227 | ) 228 | 229 | ;; Hide the mode line in the org-roam buffer, since it serves no purpose. This 230 | ;; makes it easier to distinguish from other org buffers. 231 | ;; (add-hook 'org-roam-buffer-prepare-hook #'hide-mode-line-mode) 232 | 233 | ;; Automatically assign the tag Project for project notes 234 | ;; Code: https://gist.github.com/d12frosted/a60e8ccb9aceba031af243dff0d19b2e 235 | ;; Original blog post: https://d12frosted.io/posts/2021-01-16-task-management-with-roam-vol5.html 236 | 237 | (defun vulpea-project-p () 238 | "Return non-nil if current buffer has any todo entry. 239 | 240 | TODO entries marked as done are ignored, meaning the this 241 | function returns nil if current buffer contains only completed 242 | tasks." 243 | (seq-find ; (3) 244 | (lambda (type) 245 | (eq type 'todo)) 246 | (org-element-map ; (2) 247 | (org-element-parse-buffer 'headline) ; (1) 248 | 'headline 249 | (lambda (h) 250 | (org-element-property :todo-type h))))) 251 | 252 | (defun vulpea-project-update-tag () 253 | "Update PROJECT tag in the current buffer." 254 | (when (and (not (active-minibuffer-window)) 255 | (vulpea-buffer-p)) 256 | (save-excursion 257 | (goto-char (point-min)) 258 | (let* ((tags (vulpea-buffer-tags-get)) 259 | (original-tags tags)) 260 | (if (vulpea-project-p) 261 | (setq tags (cons "project" tags)) 262 | (setq tags (remove "project" tags))) 263 | 264 | ;; cleanup duplicates 265 | (setq tags (seq-uniq tags)) 266 | 267 | ;; update tags if changed 268 | (when (or (seq-difference tags original-tags) 269 | (seq-difference original-tags tags)) 270 | (apply #'vulpea-buffer-tags-set tags)))))) 271 | 272 | (defun vulpea-buffer-p () 273 | "Return non-nil if the currently visited buffer is a note." 274 | (and buffer-file-name 275 | (string-prefix-p 276 | (expand-file-name (file-name-as-directory org-roam-directory)) 277 | (file-name-directory buffer-file-name)))) 278 | 279 | (defun vulpea-project-files () 280 | "Return a list of note files containing 'project' tag." ; 281 | (seq-uniq 282 | (seq-map 283 | #'car 284 | (org-roam-db-query 285 | [:select [nodes:file] 286 | :from tags 287 | :left-join nodes 288 | :on (= tags:node-id nodes:id) 289 | :where (like tag (quote "%\"project\"%"))])))) 290 | 291 | (defun vulpea-agenda-files-update (&rest _) 292 | "Update the value of `org-agenda-files'." 293 | (setq org-agenda-files (delete-dups (append org-agenda-files (vulpea-project-files))))) 294 | 295 | ;; (add-hook 'find-file-hook #'vulpea-project-update-tag) 296 | (add-hook 'before-save-hook #'vulpea-project-update-tag) 297 | (add-hook 'org-agenda-mode-hook #'vulpea-agenda-files-update) 298 | ;; (remove-hook 'org-agenda-mode-hook #'vulpea-agenda-files-update) 299 | 300 | ;; functions borrowed from `vulpea' library 301 | ;; https://github.com/d12frosted/vulpea/blob/6a735c34f1f64e1f70da77989e9ce8da7864e5ff/vulpea-buffer.el 302 | 303 | (defun vulpea-buffer-tags-get () 304 | "Return filetags value in current buffer." 305 | (vulpea-buffer-prop-get-list "filetags" "[ :]")) 306 | 307 | (defun vulpea-buffer-tags-set (&rest tags) 308 | "Set TAGS in current buffer. 309 | If filetags value is already set, replace it." 310 | (if tags 311 | (vulpea-buffer-prop-set 312 | "filetags" (concat ":" (string-join tags ":") ":")) 313 | (vulpea-buffer-prop-remove "filetags"))) 314 | 315 | (defun vulpea-buffer-tags-add (tag) 316 | "Add a TAG to filetags in current buffer." 317 | (let* ((tags (vulpea-buffer-tags-get)) 318 | (tags (append tags (list tag)))) 319 | (apply #'vulpea-buffer-tags-set tags))) 320 | 321 | (defun vulpea-buffer-tags-remove (tag) 322 | "Remove a TAG from filetags in current buffer." 323 | (let* ((tags (vulpea-buffer-tags-get)) 324 | (tags (delete tag tags))) 325 | (apply #'vulpea-buffer-tags-set tags))) 326 | 327 | (defun vulpea-buffer-prop-set (name value) 328 | "Set a file property called NAME to VALUE in buffer file. 329 | If the property is already set, replace its value." 330 | (setq name (downcase name)) 331 | (org-with-point-at 1 332 | (let ((case-fold-search t)) 333 | (if (re-search-forward (concat "^#\\+" name ":\\(.*\\)") 334 | (point-max) t) 335 | (replace-match (concat "#+" name ": " value) 'fixedcase) 336 | (while (and (not (eobp)) 337 | (looking-at "^[#:]")) 338 | (if (save-excursion (end-of-line) (eobp)) 339 | (progn 340 | (end-of-line) 341 | (insert "\n")) 342 | (forward-line) 343 | (beginning-of-line))) 344 | (insert "#+" name ": " value "\n"))))) 345 | 346 | (defun vulpea-buffer-prop-set-list (name values &optional separators) 347 | "Set a file property called NAME to VALUES in current buffer. 348 | VALUES are quoted and combined into single string using 349 | `combine-and-quote-strings'. 350 | If SEPARATORS is non-nil, it should be a regular expression 351 | matching text that separates, but is not part of, the substrings. 352 | If nil it defaults to `split-string-default-separators', normally 353 | \"[ \f\t\n\r\v]+\", and OMIT-NULLS is forced to t. 354 | If the property is already set, replace its value." 355 | (vulpea-buffer-prop-set 356 | name (combine-and-quote-strings values separators))) 357 | 358 | (defun vulpea-buffer-prop-get (name) 359 | "Get a buffer property called NAME as a string." 360 | (org-with-point-at 1 361 | (when (re-search-forward (concat "^#\\+" name ": \\(.*\\)") 362 | (point-max) t) 363 | (buffer-substring-no-properties 364 | (match-beginning 1) 365 | (match-end 1))))) 366 | 367 | (defun vulpea-buffer-prop-get-list (name &optional separators) 368 | "Get a buffer property NAME as a list using SEPARATORS. 369 | If SEPARATORS is non-nil, it should be a regular expression 370 | matching text that separates, but is not part of, the substrings. 371 | If nil it defaults to `split-string-default-separators', normally 372 | \"[ \f\t\n\r\v]+\", and OMIT-NULLS is forced to t." 373 | (let ((value (vulpea-buffer-prop-get name))) 374 | (when (and value (not (string-empty-p value))) 375 | (split-string-and-unquote value separators)))) 376 | 377 | ;; (add-to-list 'org-src-lang-modes (quote ("dot" . graphviz-dot))) 378 | 379 | ;; Org-projectile stuff 380 | ;; (require 'org-projectile) 381 | ;; (setq org-projectile-projects-file 382 | ;; "/your/path/to/an/org/file/for/storing/project/todos.org") 383 | ;; (push (org-projectile-project-todo-entry) org-capture-templates) 384 | ;; (setq org-agenda-files (append org-agenda-files (org-projectile-todo-files))) 385 | ;; (global-set-key (kbd "C-c c") 'org-capture) 386 | ;; (global-set-key (kbd "C-c n p") 'org-projectile-project-todo-completing-read) 387 | (setq org-link-abbrev-alist 388 | '(("wikidata" . "https://www.wikidata.org/wiki/"))) 389 | ;; Disable editing source code in dedicated buffer 390 | ;; https://emacs.stackexchange.com/questions/73986/how-do-i-stop-org-babel-from-trying-to-edit-a-source-block-in-a-dedicated-buffer/73988#73988 391 | (defun org-edit-src-code nil) 392 | 393 | ;; Org-attach stuff 394 | (setq org-attach-id-dir (concat org-directory "/.attach")) 395 | (setq org-attach-method 'mv) 396 | 397 | ;; Org-modern 398 | (global-org-modern-mode) 399 | (setq org-modern-label-border 1) 400 | 401 | (defun org-procrastinate () 402 | "Set the scheduled date on an Org agenda item to tomorrow." 403 | (interactive) 404 | (org-agenda-schedule nil "+1d")) 405 | 406 | (setq org-attach-store-link-p 'attached) 407 | 408 | (add-to-list 'org-latex-classes 409 | '("letter" 410 | "\\documentclass{letter}" 411 | ("\\section{%s}" . "\\section*{%s}") 412 | ("\\subsection{%s}" . "\\subsection*{%s}") 413 | ("\\subsubsection{%s}" . "\\subsubsection*{%s}"))) 414 | ) ;; End of Org block 415 | 416 | ;; (use-package! org-clock-reminder 417 | ;; :config 418 | ;; (org-clock-reminder-activate) 419 | ;; (setq org-clock-reminder-remind-inactivity 't)) 420 | 421 | ;;(setq org-agenda-window-setup 'only-window) 422 | 423 | ;; Prose linting 424 | ;; (require 'flycheck-vale) 425 | ;; (flycheck-vale-setup) 426 | 427 | ;; Markdown 428 | (add-hook 'markdown-mode 'visual-line-mode) 429 | 430 | ;; Mail 431 | (after! mu4e 432 | ;; (require 'org-mu4e) 433 | (setq read-mail-command 'mu4e) ;; Why is this not already set? 434 | ;; Respond to calendar invites. But is this even working? 435 | (require 'mu4e-icalendar) 436 | (mu4e-icalendar-setup) 437 | ;; Use password-store as authentication source 438 | (require 'auth-source-pass) 439 | (auth-source-pass-enable) 440 | (setq auth-sources '(password-store)) 441 | (set-email-account! "gmail" 442 | '((mu4e-sent-folder . "/gmail/[Gmail]/Sent Mail") 443 | (mu4e-drafts-folder . "/gmail/[Gmail]/Drafts") 444 | (smtpmail-smtp-user . "jon.reeve") 445 | (smtpmail-smtp-server . "smtp.gmail.com") 446 | (smtpmail-smtp-service . 587) 447 | (smtpmail-stream-type . starttls) 448 | (user-mail-address . "jon.reeve@gmail.com") 449 | (mu4e-compose-signature . "--\nJonathan Reeve\nhttps://jonreeve.com")) 450 | t) 451 | (set-email-account! "columbia" 452 | '((mu4e-sent-folder . "/columbia/[Gmail]/Sent Mail") 453 | (mu4e-drafts-folder . "/columbia/[Gmail]/Drafts") 454 | (smtpmail-smtp-user . "jpr2152@columbia.edu") 455 | (user-mail-address . "jpr2152@columbia.edu") 456 | (smtpmail-smtp-server . "smtp.gmail.com") 457 | (smtpmail-smtp-service . 587) 458 | (smtpmail-stream-type . starttls) 459 | (mu4e-compose-signature . "--\nJonathan Reeve\nPhD Candidate, Department of English and Comparative Literature\nhttps://jonreeve.com")) 460 | t) 461 | (set-email-account! "protonmail" 462 | '((mu4e-sent-folder . "/protonmail/Sent") 463 | (mu4e-drafts-folder . "/protonmail/Drafts") 464 | (smtpmail-smtp-user . "jonathan@jonreeve.com") 465 | (user-mail-address . "jonathan@jonreeve.com") 466 | (smtpmail-smtp-server . "127.0.0.1") 467 | (smtpmail-smtp-service . 1025) 468 | (smtpmail-stream-type . starttls) 469 | (mu4e-compose-signature . "--\nJonathan Reeve\nhttps://jonreeve.com")) 470 | t) 471 | (setq message-send-mail-function 'smtpmail-send-it) 472 | ;;(add-to-list 'gnutls-trustfiles "~/.config/protonmail/bridge/cert.pem") 473 | (setq mu4e-maildir "~/Retpoŝto" 474 | mu4e-trash-folder "/Trash" 475 | mu4e-refile-folder "/Archive" 476 | mu4e-view-show-addresses t 477 | mu4e-attachment-dir "~/Elŝutoj" 478 | mu4e-compose-dont-reply-to-self t 479 | mu4e-user-mail-address-list '("jon.reeve@gmail.com" "jonathan.reeve@columbia.edu" "jpr2152@columbia.edu")) 480 | (setq mu4e-bookmarks 481 | `(("flag:unread AND NOT flag:trashed" "Unread messages" ?u) 482 | ("date:7d..now NOT flag:trashed AND NOT flag:replied" "Last 7 days unreplied" ?w) 483 | ("maildir:/columbia/Inbox NOT flag:trashed AND NOT flag:replied" "Columbia" ?c) 484 | ("maildir:/columbia/Inbox OR maildir:/gmail/Inbox OR maildir:/personal/Inbox OR maildir:/protonmail/Inbox NOT flag:trashed" "All" ?a) 485 | ("maildir:/gmail/Inbox NOT flag:trashed AND NOT flag:replied" "Gmail" ?g) 486 | ("maildir:/gmail/Lists OR maildir:/protonmail/Lists NOT flag:trashed AND NOT flag:replied" "Lists" ?l) 487 | ("maildir:/personal/Inbox NOT flag:trashed AND NOT flag:replied" "Personal" ?p) 488 | ("maildir:/columbia/Homework NOT flag:trashed" "Homework" ?h) 489 | )) 490 | ;; Only alert interesting emails 491 | (setq mu4e-alert-interesting-mail-query "maildir:/columbia/Inbox OR maildir:/gmail/Inbox OR maildir:/personal/Inbox OR maildir:/protonmail/Inbox NOT flag:trashed") 492 | ;; (setq mu4e-headers-list-mark (cons "l" (+mu4e-normalised-icon "sitemap" :set "faicon")) 493 | ;; mu4e-headers-personal-mark (cons "p" (+mu4e-normalised-icon "user")) 494 | ;; mu4e-headers-calendar-mark (cons "c" (+mu4e-normalised-icon "calendar"))) 495 | ) 496 | ;; (add-hook 'mu4e-view-mode-hook 'visual-line-mode) 497 | ;; (setq mu4e-html2text-command "w3m -T text/html") 498 | 499 | (after! org-msg 500 | (setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil \\n:t" 501 | org-msg-startup "hidestars indent inlineimages" 502 | org-msg-greeting-fmt "\nHi%s,\n\n" 503 | org-msg-default-alternatives '((new . (text html)) 504 | (reply-to-html . (text html)) 505 | (reply-to-text . (text html)))) 506 | ;; (setq org-msg-convert-citation t 507 | ;; org-msg-signature " 508 | 509 | ;; Best, 510 | 511 | ;; Jonathan 512 | 513 | ;; #+begin_signature 514 | ;; -- 515 | ;; Jonathan Reeve 516 | ;; https://jonreeve.com 517 | ;; #+end_signature") 518 | ;; (setq message-citation-line-format "Je %a, %b %d %Y, %N skribis:\n") 519 | ;; (setq org-msg-posting-style nil) ; 520 | ) 521 | 522 | ;; Set browser 523 | (setq browse-url-browser-function 'browse-url-generic 524 | browse-url-generic-program "qutebrowser") 525 | 526 | ;; Better looking HTML mail 527 | (after! shr 528 | (setq shr-color-visible-luminance-min 80) 529 | (setq shr-use-colors nil) 530 | (setq shr-use-fonts nil) 531 | (define-advice mm-shr (:around (oldfn &rest handle) delete-trailing-whitespace) 532 | "Delete leading and trailing whitespace in Gnus article buffer." 533 | (if (derived-mode-p 'gnus-article-mode) 534 | (save-restriction 535 | (narrow-to-region (point) (point)) 536 | (apply oldfn handle) 537 | (delete-trailing-whitespace)) 538 | (apply oldfn handle))) 539 | '(progn (setq shr-width -1) 540 | (defun shr-fill-text (text) text) 541 | (defun shr-fill-lines (start end) nil) 542 | (defun shr-fill-line () nil))) 543 | 544 | (add-hook 'elfeed-show-mode-hook 'visual-line-mode) 545 | (setq rmh-elfeed-org-files '("/home/jon/Dokumentoj/Org/RSS.org")) 546 | 547 | ;; Unbind QWERTY, bind Colemak 548 | (map! :n "l" #'evil-insert 549 | :n "L" #'evil-insert-line 550 | :nvm "n" #'evil-next-visual-line 551 | :nvm "gn" #'evil-next-line 552 | :nvm "gN" #'evil-next-visual-line 553 | :nvm "e" #'evil-previous-visual-line 554 | :nvm "ge" #'evil-previous-line 555 | :nvm "i" #'evil-forward-char 556 | :nvm "j" #'evil-forward-word-end 557 | :nvm "J" #'evil-forward-WORD-end 558 | :nvm "gj" #'evil-backward-word-end 559 | :nvm "gJ" #'evil-backward-WORD-end 560 | :nvm "k" #'evil-ex-search-next 561 | :nvm "K" #'evil-ex-search-previous 562 | :nvm "f" #'evil-snipe-f 563 | :nvm "F" #'evil-snipe-F 564 | :nvm "t" #'evil-snipe-t 565 | :nvm "T" #'evil-snipe-T 566 | :nvm "s" #'evil-snipe-s 567 | :nvm "S" #'evil-snipe-S 568 | :nv "u" #'undo-tree-undo 569 | :nv "N" #'evil-join 570 | :nv "gN" #'evil-join-whitespace 571 | :g "C-h" #'evil-window-left 572 | :g "C-n" #'evil-window-down 573 | :g "C-e" #'evil-window-up 574 | :g "C-i" #'evil-window-right 575 | :g "" #'org-agenda-list 576 | :g "" #'org-todo-list 577 | ) 578 | 579 | (map! :map evil-org-agenda-mode-map "P" 'org-procrastinate) 580 | 581 | (map! :map evil-treemacs-state-map "n" 'treemacs-next-line 582 | "e" 'treemacs-previous-line) 583 | 584 | (map! :map evil-window-map "n" #'evil-window-down 585 | "N" 'evil-window-move-very-bottom 586 | "e" 'evil-window-up 587 | "E" 'evil-window-move-very-top 588 | "i" 'evil-window-right 589 | "I" 'evil-window-move-far-right 590 | "j" 'evil-window-new) 591 | 592 | (map! :n "SPC w c" 'evil-window-new) 593 | 594 | ;; Bind stuff 595 | (map! :after pdf-tools :map pdf-view-mode-map :n "C-i" 'org-noter-insert-precise-note 596 | :n "C-n" 'pdf-view-next-page 597 | :n "C-e" 'pdf-view-previous-page 598 | :n "n" 'pdf-view-scroll-up-or-next-page 599 | :n "e" 'pdf-view-scroll-down-or-previous-page) 600 | 601 | (map! :after ranger :map ranger-normal-mode-map 602 | :nvm "h" 'ranger-up-directory 603 | :nvm "n" 'ranger-next-file 604 | :nvm "e" 'ranger-prev-file 605 | :nvm "i" 'ranger-find-file 606 | :nvm "N" 'ranger-half-page-down 607 | :nvm "E" 'ranger-half-page-up 608 | ) 609 | 610 | ;; Epub 611 | (add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode)) 612 | (defun my-nov-font-setup () 613 | (face-remap-add-relative 'variable-pitch :family "Liberation Serif" 614 | :height 1.4)) 615 | (add-hook 'nov-mode-hook 'my-nov-font-setup) 616 | 617 | ;; Toggle transparency 618 | (defun toggle-transparency () 619 | (interactive) 620 | (let ((alpha (frame-parameter nil 'alpha))) 621 | (set-frame-parameter 622 | nil 'alpha 623 | (if (eql (cond ((numberp alpha) alpha) 624 | ((numberp (cdr alpha)) (cdr alpha)) 625 | ;; Also handle undocumented ( ) form. 626 | ((numberp (cadr alpha)) (cadr alpha))) 627 | 100) 628 | '(85 . 50) '(100 . 100))))) 629 | 630 | ;; Treat all themes as safe 631 | (setq custom-safe-themes t) 632 | 633 | ;; Fancy splash image 634 | (setq fancy-splash-image "/home/jon/Bildujo/typewriter1.jpg") 635 | 636 | ;; Stop autocompleting parentheses and quotation marks 637 | (remove-hook 'doom-first-buffer-hook #'smartparens-global-mode) 638 | 639 | (after! org-cite 640 | (require 'oc-csl-activate) 641 | (setq org-cite-activate-processor 'csl-activate) 642 | ) 643 | 644 | ;; (add-to-list 'auto-mode-alist '("\\.cljs\\.hl\\'" . clojurescript-mode) 645 | 646 | (defun rename-pdf () 647 | " Rename the most recently modified PDF in the /tmp dir with the latest bibtex key. " 648 | (interactive) 649 | (setq most-recent-pdf (string-trim-right (shell-command-to-string "ls -t /tmp/*.pdf | head -1"))) 650 | (setq dest-pdf-filename (string-trim-right (concat bibtex-completion-library-path (bibtex-completion-get-key-bibtex) ".pdf"))) 651 | (if (yes-or-no-p (concat "Rename " most-recent-pdf " to " dest-pdf-filename "?")) 652 | (rename-file most-recent-pdf dest-pdf-filename) 653 | (message "Aborted.") 654 | )) 655 | 656 | (defun rename-epub () 657 | " Rename the most recently modified Epub in the /tmp dir with the latest bibtex key. " 658 | (interactive) 659 | (setq most-recent-epub (string-trim-right (shell-command-to-string "ls -t /tmp/*.epub | head -1"))) 660 | (setq dest-epub-filename (string-trim-right (concat bibtex-completion-library-path (bibtex-completion-get-key-bibtex) ".epub"))) 661 | (if (yes-or-no-p (concat "Rename " most-recent-epub " to " dest-epub-filename "?")) 662 | (rename-file most-recent-epub dest-epub-filename) 663 | (message "Aborted.") 664 | )) 665 | ;; (use-package! notebook-mode) 666 | 667 | ;; (use-package! evil-colemak-basics 668 | ;; :after evil 669 | ;; :config 670 | ;; (setq evil-colemak-basics-rotate-t-f-j nil) 671 | ;; (global-evil-colemak-basics-mode) ; Enable colemak rebinds 672 | 673 | ;; ) 674 | 675 | ;; Workaround; see https://github.com/nnicandro/emacs-jupyter/issues/380#issuecomment-1014026589 676 | (after! ob-jupyter 677 | (defun jupyter-ansi-color-apply-on-region (begin end) 678 | (ansi-color-apply-on-region begin end t)) 679 | ) 680 | 681 | ;; Encryption 682 | (require 'epa-file) 683 | (epa-file-enable) 684 | 685 | ;; (setq system-uses-terminfo nil) 686 | (after! vterm 687 | (setq vterm-shell "nu") 688 | ) 689 | 690 | (set-locale-environment "eo.utf-8") 691 | 692 | ;; Scala 693 | ;; (add-to-list '+org-babel-mode-alist '(scala . ammonite)) 694 | 695 | ;; Word wrap issues; possible fix for https://github.com/doomemacs/doomemacs/issues/7133 696 | (setq +global-word-wrap-mode 'nil) 697 | (setq font-lock-global-modes '(not mu4e-compose-mode)) 698 | -------------------------------------------------------------------------------- /dotfiles/emacs/doom.d/init.el: -------------------------------------------------------------------------------- 1 | ;;; init.el -*- lexical-binding: t; -*- 2 | 3 | ;; Copy this file to ~/.doom.d/init.el or ~/.config/doom/init.el ('doom install' 4 | ;; will do this for you). The `doom!' block below controls what modules are 5 | ;; enabled and in what order they will be loaded. Remember to run 'doom refresh' 6 | ;; after modifying it. 7 | ;; 8 | ;; More information about these modules (and what flags they support) can be 9 | ;; found in modules/README.org. 10 | 11 | (doom! :input 12 | ;;chinese 13 | ;;japanese 14 | 15 | :completion 16 | company ; the ultimate code completion backend 17 | ;;helm ; the *other* search engine for love and life 18 | ;;ido ; the other *other* search engine... 19 | ;;ivy ; a search engine for love and life 20 | (vertico +icons) 21 | 22 | :ui 23 | ;;deft ; notational velocity for Emacs 24 | doom ; what makes DOOM look the way it does 25 | doom-dashboard ; a nifty splash screen for Emacs 26 | doom-quit ; DOOM quit-message prompts when you quit Emacs 27 | (emoji +unicode) 28 | ;;fill-column ; a `fill-column' indicator 29 | hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW 30 | ;;hydra 31 | ;;indent-guides ; highlighted indent columns 32 | ligatures ; replace bits of code with pretty symbols 33 | modeline ; snazzy, Atom-inspired modeline, plus API 34 | nav-flash ; blink the current line after jumping 35 | ;;neotree ; a project drawer, like NERDTree for vim 36 | ophints ; highlight the region an operation acts on 37 | (popup ; tame sudden yet inevitable temporary windows 38 | +all ; catch all popups that start with an asterix 39 | +defaults) ; default popup rules 40 | ;;tabs ; an tab bar for Emacs 41 | treemacs ; a project drawer, like neotree but cooler 42 | unicode ; extended unicode support for various languages 43 | vc-gutter ; vcs diff in the fringe 44 | vi-tilde-fringe ; fringe tildes to mark beyond EOB 45 | window-select ; visually switch windows 46 | workspaces ; tab emulation, persistence & separate workspaces 47 | zen ; distraction-free coding or writing 48 | 49 | :editor 50 | (evil +everywhere); come to the dark side, we have cookies 51 | file-templates ; auto-snippets for empty files 52 | fold ; (nigh) universal code folding 53 | ;;(format +onsave) ; automated prettiness 54 | ;;god ; run Emacs commands without modifier keys 55 | ;;lispy ; vim for lisp, for people who don't like vim 56 | multiple-cursors ; editing in many places at once 57 | ;;objed ; text object editing for the innocent 58 | ;;parinfer ; turn lisp into python, sort of 59 | rotate-text ; cycle region at point between text candidates 60 | snippets ; my elves. They type so I don't have to 61 | word-wrap ; soft wrapping with language-aware indent 62 | 63 | :emacs 64 | (dired +icons) ; making dired pretty [functional] 65 | electric ; smarter, keyword-based electric-indent 66 | ibuffer ; interactive buffer management 67 | vc ; version-control and Emacs, sitting in a tree 68 | (undo +tree) 69 | 70 | :term 71 | eshell ; a consistent, cross-platform shell (WIP) 72 | ;;shell ; a terminal REPL for Emacs 73 | term ; terminals in Emacs 74 | vterm ; another terminals in Emacs 75 | 76 | :checkers 77 | syntax 78 | spell 79 | 80 | :tools 81 | ;;ansible 82 | biblio 83 | ;;debugger ; FIXME stepping through code, to help you add bugs 84 | direnv 85 | ;;docker 86 | ;;editorconfig ; let someone else argue about tabs vs spaces 87 | ein ; tame Jupyter notebooks with emacs 88 | (eval +overlay) ; run code, run (also, repls) 89 | ;;gist ; interacting with github gists 90 | (lookup ; helps you navigate your code and documentation 91 | +docsets) ; ...or in Dash docsets locally 92 | lsp 93 | ;;macos ; MacOS-specific commands 94 | magit ; a git porcelain for Emacs 95 | ;;make ; run make tasks from Emacs 96 | (pass +auth) ; password manager for nerds 97 | pdf ; pdf enhancements 98 | ;;prodigy ; FIXME managing external services & code builders 99 | ;;rgb ; creating color strings 100 | ;;terraform ; infrastructure as code 101 | ;;tmux ; an API for interacting with tmux 102 | ;;upload ; map local to remote projects via ssh/ftp 103 | 104 | :lang 105 | ;;agda ; types of types of types of types... 106 | ;;assembly ; assembly for fun or debugging 107 | ;;cc ; C/C++/Obj-C madness 108 | (clojure +lsp) ; java with a lisp 109 | ;;common-lisp ; if you've seen one lisp, you've seen them all 110 | ;;coq ; proofs-as-programs 111 | ;;crystal ; ruby at the speed of c 112 | ;;csharp ; unity, .NET, and mono shenanigans 113 | data ; config/data formats 114 | ;;elixir ; erlang done right 115 | elm ; care for a cup of TEA? 116 | emacs-lisp ; drown in parentheses 117 | ;;erlang ; an elegant language for a more civilized age 118 | (ess +lsp) ; emacs speaks statistics 119 | ;;faust ; dsp, but you get to keep your soul 120 | ;;fsharp ; ML stands for Microsoft's Language 121 | ;;go ; the hipster dialect 122 | (haskell +lsp) ; a language that's lazier than I am 123 | ;;hy ; readability of scheme w/ speed of python 124 | ;;idris ; 125 | ;;(java +meghanada) ; the poster child for carpal tunnel syndrome 126 | ;;javascript ; all(hope(abandon(ye(who(enter(here)))))) 127 | julia ; a better, faster MATLAB 128 | ;;kotlin ; a better, slicker Java(Script) 129 | ;;latex ; writing papers in Emacs has never been so fun 130 | ;;lean 131 | ;;ledger ; an accounting system in Emacs 132 | ;;lua ; one-based indices? one-based indices 133 | markdown ; writing docs for people to ignore 134 | ;;nim ; python + lisp at the speed of c 135 | nix ; I hereby declare "nix geht mehr!" 136 | ;;ocaml ; an objective camel 137 | (org ; organize your plain life in plain text 138 | +dragndrop ; drag & drop files/images into org buffers 139 | +gnuplot ; graphs of tables 140 | +jupyter 141 | +pandoc ; export-with-pandoc support 142 | +pomodoro ; be fruitful with the tomato technique 143 | +roam2 ; zettelkesten 144 | +noter) 145 | ;;perl ; write code no one else can comprehend 146 | php ; perl's insecure younger brother 147 | ;;plantuml ; diagrams for confusing people more 148 | ;;purescript ; javascript, but functional 149 | (python +lsp) ; beautiful is better than ugly 150 | ;;qt ; the 'cutest' gui framework ever 151 | racket ; a DSL for DSLs 152 | ;;rest ; Emacs as a REST client 153 | ;;rst ; ReST in peace 154 | ;;ruby ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"} 155 | ;;rust ; Fe2O3.unwrap().unwrap().unwrap().unwrap() 156 | ;; (scala +lsp) ; java, but good 157 | ;;scheme ; a fully conniving family of lisps 158 | (sh +bash +fish) ; she sells {ba,z,fi}sh shells on the C xor 159 | ;;solidity ; do you need a blockchain? No. 160 | ;;swift ; who asked for emoji variables? 161 | ;;terra ; Earth and Moon in alignment for performance. 162 | yaml 163 | web ; the tubes 164 | 165 | :email 166 | (mu4e +gmail +org) 167 | ;;(wanderlust +gmail) 168 | 169 | :app 170 | ;;calendar 171 | ;;irc ; how neckbeards socialize 172 | (rss +org) ; emacs as an RSS reader 173 | ;;twitter ; twitter client https://twitter.com/vnought 174 | ;;write ; emacs for writers (fiction, notes, papers, etc.) 175 | 176 | :config 177 | ;;literate 178 | (default +bindings)) 179 | -------------------------------------------------------------------------------- /dotfiles/emacs/doom.d/packages.el: -------------------------------------------------------------------------------- 1 | ;; -*- no-byte-compile: t; -*- 2 | ;;; .doom.d/packages.el 3 | 4 | ;;; Examples: 5 | ;; (package! another-package :recipe (:host github :repo "username/repo")) 6 | ;; (package! builtin-package :disable t) 7 | 8 | (package! flycheck-vale) 9 | 10 | (package! pdf-tools :built-in 'prefer) 11 | 12 | ;; Read epubs 13 | (package! nov) 14 | 15 | ;; See https://github.com/fuxialexander/org-pdftools 16 | ;; (package! org-pdftools) 17 | 18 | ;; Use BibSonomy 19 | ;; (package! biblio-bibsonomy) 20 | 21 | ;; Change themes with PyWal 22 | (package! ewal-doom-themes) 23 | 24 | ;; Query Org files 25 | ;; (package! org-ql) 26 | 27 | ;; Make eshell better 28 | ;; (package! fish-completion) 29 | 30 | ;; Edit Turtle files 31 | ;; (package! ttl-mode) 32 | 33 | (package! websocket) 34 | (package! org-roam-ui :recipe (:host github :repo "org-roam/org-roam-ui" :files ("*.el" "out"))) 35 | 36 | (package! org-ref) 37 | (package! org-roam-bibtex 38 | :recipe (:host github :repo "org-roam/org-roam-bibtex")) 39 | 40 | ;; (package! org-cite-csl-activate :recipe (:host github :repo "andras-simonyi/org-cite-csl-activate" :files ("*.el"))) 41 | 42 | (package! org-clock-reminder 43 | :recipe (:host github :repo "inickey/org-clock-reminder")) 44 | 45 | ;; UI improvements for Org mode 46 | (package! org-modern) 47 | 48 | ;; (package! vulpea :recipe (:host github :repo "d12frosted/vulpea")) 49 | 50 | ;; (package! emacsql-sqlite) 51 | 52 | ;; Pollen, the document processing language for Racket 53 | (package! pollen-mode) 54 | 55 | ;; Scribble, the language Pollen is written in 56 | (package! scribble-mode) 57 | 58 | 59 | ;; Web scraping 60 | ;; (package! enlive) 61 | 62 | ;; Life in the danger zone! 63 | ;; (unpin! org-ref org-roam-bibtex) 64 | 65 | ;; (package! notebook-mode :recipe (:host github :repo "rougier/notebook-mode" :files ("*.el"))) 66 | 67 | ;; ~/.doom.d/packages.el 68 | ;; (package! evil-colemak-basics) ; colemak remaps 69 | 70 | (package! quarto-mode :recipe (:host github :repo "quarto-dev/quarto-emacs" )) 71 | -------------------------------------------------------------------------------- /dotfiles/env.nu: -------------------------------------------------------------------------------- 1 | let-env STARSHIP_SHELL = "nushell"; 2 | -------------------------------------------------------------------------------- /dotfiles/flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "base16": { 4 | "inputs": { 5 | "fromYaml": "fromYaml" 6 | }, 7 | "locked": { 8 | "lastModified": 1708890466, 9 | "narHash": "sha256-LlrC09LoPi8OPYOGPXegD72v+//VapgAqhbOFS3i8sc=", 10 | "owner": "SenchoPens", 11 | "repo": "base16.nix", 12 | "rev": "665b3c6748534eb766c777298721cece9453fdae", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "SenchoPens", 17 | "repo": "base16.nix", 18 | "type": "github" 19 | } 20 | }, 21 | "base16-fish": { 22 | "flake": false, 23 | "locked": { 24 | "lastModified": 1622559957, 25 | "narHash": "sha256-PebymhVYbL8trDVVXxCvZgc0S5VxI7I1Hv4RMSquTpA=", 26 | "owner": "tomyun", 27 | "repo": "base16-fish", 28 | "rev": "2f6dd973a9075dabccd26f1cded09508180bf5fe", 29 | "type": "github" 30 | }, 31 | "original": { 32 | "owner": "tomyun", 33 | "repo": "base16-fish", 34 | "type": "github" 35 | } 36 | }, 37 | "base16-foot": { 38 | "flake": false, 39 | "locked": { 40 | "lastModified": 1696725948, 41 | "narHash": "sha256-65bz2bUL/yzZ1c8/GQASnoiGwaF8DczlxJtzik1c0AU=", 42 | "owner": "tinted-theming", 43 | "repo": "base16-foot", 44 | "rev": "eedbcfa30de0a4baa03e99f5e3ceb5535c2755ce", 45 | "type": "github" 46 | }, 47 | "original": { 48 | "owner": "tinted-theming", 49 | "repo": "base16-foot", 50 | "type": "github" 51 | } 52 | }, 53 | "base16-helix": { 54 | "flake": false, 55 | "locked": { 56 | "lastModified": 1696727917, 57 | "narHash": "sha256-FVrbPk+NtMra0jtlC5oxyNchbm8FosmvXIatkRbYy1g=", 58 | "owner": "tinted-theming", 59 | "repo": "base16-helix", 60 | "rev": "dbe1480d99fe80f08df7970e471fac24c05f2ddb", 61 | "type": "github" 62 | }, 63 | "original": { 64 | "owner": "tinted-theming", 65 | "repo": "base16-helix", 66 | "type": "github" 67 | } 68 | }, 69 | "base16-kitty": { 70 | "flake": false, 71 | "locked": { 72 | "lastModified": 1665001328, 73 | "narHash": "sha256-aRaizTYPpuWEcvoYE9U+YRX+Wsc8+iG0guQJbvxEdJY=", 74 | "owner": "kdrag0n", 75 | "repo": "base16-kitty", 76 | "rev": "06bb401fa9a0ffb84365905ffbb959ae5bf40805", 77 | "type": "github" 78 | }, 79 | "original": { 80 | "owner": "kdrag0n", 81 | "repo": "base16-kitty", 82 | "type": "github" 83 | } 84 | }, 85 | "base16-tmux": { 86 | "flake": false, 87 | "locked": { 88 | "lastModified": 1696725902, 89 | "narHash": "sha256-wDPg5elZPcQpu7Df0lI5O8Jv4A3T6jUQIVg63KDU+3Q=", 90 | "owner": "tinted-theming", 91 | "repo": "base16-tmux", 92 | "rev": "c02050bebb60dbb20cb433cd4d8ce668ecc11ba7", 93 | "type": "github" 94 | }, 95 | "original": { 96 | "owner": "tinted-theming", 97 | "repo": "base16-tmux", 98 | "type": "github" 99 | } 100 | }, 101 | "base16-vim": { 102 | "flake": false, 103 | "locked": { 104 | "lastModified": 1663659192, 105 | "narHash": "sha256-uJvaYYDMXvoo0fhBZUhN8WBXeJ87SRgof6GEK2efFT0=", 106 | "owner": "chriskempson", 107 | "repo": "base16-vim", 108 | "rev": "3be3cd82cd31acfcab9a41bad853d9c68d30478d", 109 | "type": "github" 110 | }, 111 | "original": { 112 | "owner": "chriskempson", 113 | "repo": "base16-vim", 114 | "type": "github" 115 | } 116 | }, 117 | "cachix": { 118 | "inputs": { 119 | "devenv": [ 120 | "niri", 121 | "crate2nix" 122 | ], 123 | "flake-compat": [ 124 | "niri", 125 | "crate2nix" 126 | ], 127 | "nixpkgs": "nixpkgs", 128 | "pre-commit-hooks": [ 129 | "niri", 130 | "crate2nix" 131 | ] 132 | }, 133 | "locked": { 134 | "lastModified": 1709700175, 135 | "narHash": "sha256-A0/6ZjLmT9qdYzKHmevnEIC7G+GiZ4UCr8v0poRPzds=", 136 | "owner": "cachix", 137 | "repo": "cachix", 138 | "rev": "be97b37989f11b724197b5f4c7ffd78f12c8c4bf", 139 | "type": "github" 140 | }, 141 | "original": { 142 | "owner": "cachix", 143 | "ref": "latest", 144 | "repo": "cachix", 145 | "type": "github" 146 | } 147 | }, 148 | "crate2nix": { 149 | "inputs": { 150 | "cachix": "cachix", 151 | "crate2nix_stable": "crate2nix_stable", 152 | "devshell": "devshell", 153 | "flake-compat": "flake-compat", 154 | "flake-parts": "flake-parts", 155 | "nix-test-runner": "nix-test-runner", 156 | "nixpkgs": "nixpkgs_2", 157 | "pre-commit-hooks": "pre-commit-hooks" 158 | }, 159 | "locked": { 160 | "lastModified": 1712821856, 161 | "narHash": "sha256-rObTWSqfqt0qlOCokE2abesI11Ic8bCCkPNxlyk57Q0=", 162 | "owner": "nix-community", 163 | "repo": "crate2nix", 164 | "rev": "cf034861fdc4e091fc7c5f01d6c022dc46686cf1", 165 | "type": "github" 166 | }, 167 | "original": { 168 | "owner": "nix-community", 169 | "repo": "crate2nix", 170 | "type": "github" 171 | } 172 | }, 173 | "crate2nix_stable": { 174 | "inputs": { 175 | "flake-utils": "flake-utils" 176 | }, 177 | "locked": { 178 | "lastModified": 1702842982, 179 | "narHash": "sha256-A9AowkHIjsy1a4LuiPiVP88FMxyCWK41flZEZOUuwQM=", 180 | "owner": "nix-community", 181 | "repo": "crate2nix", 182 | "rev": "75ac2973affa6b9b4f661a7b592cba6e4f51d426", 183 | "type": "github" 184 | }, 185 | "original": { 186 | "owner": "nix-community", 187 | "ref": "0.12.0", 188 | "repo": "crate2nix", 189 | "type": "github" 190 | } 191 | }, 192 | "devshell": { 193 | "inputs": { 194 | "flake-utils": "flake-utils_2", 195 | "nixpkgs": [ 196 | "niri", 197 | "crate2nix", 198 | "nixpkgs" 199 | ] 200 | }, 201 | "locked": { 202 | "lastModified": 1711099426, 203 | "narHash": "sha256-HzpgM/wc3aqpnHJJ2oDqPBkNsqWbW0WfWUO8lKu8nGk=", 204 | "owner": "numtide", 205 | "repo": "devshell", 206 | "rev": "2d45b54ca4a183f2fdcf4b19c895b64fbf620ee8", 207 | "type": "github" 208 | }, 209 | "original": { 210 | "owner": "numtide", 211 | "repo": "devshell", 212 | "type": "github" 213 | } 214 | }, 215 | "flake-compat": { 216 | "locked": { 217 | "lastModified": 1696426674, 218 | "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", 219 | "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", 220 | "revCount": 57, 221 | "type": "tarball", 222 | "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz" 223 | }, 224 | "original": { 225 | "type": "tarball", 226 | "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz" 227 | } 228 | }, 229 | "flake-compat_2": { 230 | "flake": false, 231 | "locked": { 232 | "lastModified": 1673956053, 233 | "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", 234 | "owner": "edolstra", 235 | "repo": "flake-compat", 236 | "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", 237 | "type": "github" 238 | }, 239 | "original": { 240 | "owner": "edolstra", 241 | "repo": "flake-compat", 242 | "type": "github" 243 | } 244 | }, 245 | "flake-parts": { 246 | "inputs": { 247 | "nixpkgs-lib": [ 248 | "niri", 249 | "crate2nix", 250 | "nixpkgs" 251 | ] 252 | }, 253 | "locked": { 254 | "lastModified": 1712014858, 255 | "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", 256 | "owner": "hercules-ci", 257 | "repo": "flake-parts", 258 | "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", 259 | "type": "github" 260 | }, 261 | "original": { 262 | "owner": "hercules-ci", 263 | "repo": "flake-parts", 264 | "type": "github" 265 | } 266 | }, 267 | "flake-parts_2": { 268 | "inputs": { 269 | "nixpkgs-lib": "nixpkgs-lib" 270 | }, 271 | "locked": { 272 | "lastModified": 1715865404, 273 | "narHash": "sha256-/GJvTdTpuDjNn84j82cU6bXztE0MSkdnTWClUCRub78=", 274 | "owner": "hercules-ci", 275 | "repo": "flake-parts", 276 | "rev": "8dc45382d5206bd292f9c2768b8058a8fd8311d9", 277 | "type": "github" 278 | }, 279 | "original": { 280 | "owner": "hercules-ci", 281 | "repo": "flake-parts", 282 | "type": "github" 283 | } 284 | }, 285 | "flake-utils": { 286 | "inputs": { 287 | "systems": "systems" 288 | }, 289 | "locked": { 290 | "lastModified": 1694529238, 291 | "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", 292 | "owner": "numtide", 293 | "repo": "flake-utils", 294 | "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", 295 | "type": "github" 296 | }, 297 | "original": { 298 | "owner": "numtide", 299 | "repo": "flake-utils", 300 | "type": "github" 301 | } 302 | }, 303 | "flake-utils_2": { 304 | "inputs": { 305 | "systems": "systems_2" 306 | }, 307 | "locked": { 308 | "lastModified": 1701680307, 309 | "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", 310 | "owner": "numtide", 311 | "repo": "flake-utils", 312 | "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", 313 | "type": "github" 314 | }, 315 | "original": { 316 | "owner": "numtide", 317 | "repo": "flake-utils", 318 | "type": "github" 319 | } 320 | }, 321 | "flake-utils_3": { 322 | "inputs": { 323 | "systems": "systems_3" 324 | }, 325 | "locked": { 326 | "lastModified": 1710146030, 327 | "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", 328 | "owner": "numtide", 329 | "repo": "flake-utils", 330 | "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", 331 | "type": "github" 332 | }, 333 | "original": { 334 | "owner": "numtide", 335 | "repo": "flake-utils", 336 | "type": "github" 337 | } 338 | }, 339 | "fromYaml": { 340 | "flake": false, 341 | "locked": { 342 | "lastModified": 1689549921, 343 | "narHash": "sha256-iX0pk/uB019TdBGlaJEWvBCfydT6sRq+eDcGPifVsCM=", 344 | "owner": "SenchoPens", 345 | "repo": "fromYaml", 346 | "rev": "11fbbbfb32e3289d3c631e0134a23854e7865c84", 347 | "type": "github" 348 | }, 349 | "original": { 350 | "owner": "SenchoPens", 351 | "repo": "fromYaml", 352 | "type": "github" 353 | } 354 | }, 355 | "gitignore": { 356 | "inputs": { 357 | "nixpkgs": [ 358 | "niri", 359 | "crate2nix", 360 | "pre-commit-hooks", 361 | "nixpkgs" 362 | ] 363 | }, 364 | "locked": { 365 | "lastModified": 1709087332, 366 | "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", 367 | "owner": "hercules-ci", 368 | "repo": "gitignore.nix", 369 | "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", 370 | "type": "github" 371 | }, 372 | "original": { 373 | "owner": "hercules-ci", 374 | "repo": "gitignore.nix", 375 | "type": "github" 376 | } 377 | }, 378 | "gnome-shell": { 379 | "flake": false, 380 | "locked": { 381 | "lastModified": 1713702291, 382 | "narHash": "sha256-zYP1ehjtcV8fo+c+JFfkAqktZ384Y+y779fzmR9lQAU=", 383 | "owner": "GNOME", 384 | "repo": "gnome-shell", 385 | "rev": "0d0aadf013f78a7f7f1dc984d0d812971864b934", 386 | "type": "github" 387 | }, 388 | "original": { 389 | "owner": "GNOME", 390 | "ref": "46.1", 391 | "repo": "gnome-shell", 392 | "type": "github" 393 | } 394 | }, 395 | "home-manager": { 396 | "inputs": { 397 | "nixpkgs": [ 398 | "nixos" 399 | ] 400 | }, 401 | "locked": { 402 | "lastModified": 1716457508, 403 | "narHash": "sha256-ZxzffLuWRyuMrkVVq7wastNUqeO0HJL9xqfY1QsYaqo=", 404 | "owner": "nix-community", 405 | "repo": "home-manager", 406 | "rev": "850cb322046ef1a268449cf1ceda5fd24d930b05", 407 | "type": "github" 408 | }, 409 | "original": { 410 | "owner": "nix-community", 411 | "repo": "home-manager", 412 | "type": "github" 413 | } 414 | }, 415 | "home-manager_2": { 416 | "inputs": { 417 | "nixpkgs": [ 418 | "stylix", 419 | "nixpkgs" 420 | ] 421 | }, 422 | "locked": { 423 | "lastModified": 1714981474, 424 | "narHash": "sha256-b3/U21CJjCjJKmA9WqUbZGZgCvospO3ArOUTgJugkOY=", 425 | "owner": "nix-community", 426 | "repo": "home-manager", 427 | "rev": "6ebe7be2e67be7b9b54d61ce5704f6fb466c536f", 428 | "type": "github" 429 | }, 430 | "original": { 431 | "owner": "nix-community", 432 | "repo": "home-manager", 433 | "type": "github" 434 | } 435 | }, 436 | "niri": { 437 | "inputs": { 438 | "crate2nix": "crate2nix", 439 | "flake-parts": "flake-parts_2", 440 | "niri-stable": "niri-stable", 441 | "niri-unstable": "niri-unstable", 442 | "nixpkgs": "nixpkgs_3", 443 | "nixpkgs-stable": "nixpkgs-stable" 444 | }, 445 | "locked": { 446 | "lastModified": 1716640018, 447 | "narHash": "sha256-vty6GoIKET+rW+2sTcOImgSyQVa63BDczoGB0cdqF5U=", 448 | "owner": "sodiboo", 449 | "repo": "niri-flake", 450 | "rev": "c990e5121b157c6765be9b39e1045052d8abf29f", 451 | "type": "github" 452 | }, 453 | "original": { 454 | "owner": "sodiboo", 455 | "repo": "niri-flake", 456 | "type": "github" 457 | } 458 | }, 459 | "niri-stable": { 460 | "flake": false, 461 | "locked": { 462 | "lastModified": 1716030039, 463 | "narHash": "sha256-MJh0CR2YHJE0GNnxaTcElNMuZUEI0pe9fvC0mfy4484=", 464 | "owner": "YaLTeR", 465 | "repo": "niri", 466 | "rev": "d96a66ddff1a6b88dbe3e23b049f7075533b216f", 467 | "type": "github" 468 | }, 469 | "original": { 470 | "owner": "YaLTeR", 471 | "ref": "v0.1.6", 472 | "repo": "niri", 473 | "type": "github" 474 | } 475 | }, 476 | "niri-unstable": { 477 | "flake": false, 478 | "locked": { 479 | "lastModified": 1716554875, 480 | "narHash": "sha256-BBAiAeWPwoOJyeW9PAnxSxS9kAi2b/T8bh8ChIfAD5Q=", 481 | "owner": "YaLTeR", 482 | "repo": "niri", 483 | "rev": "2ac8d840343dc964981507353c9128c68361cb6f", 484 | "type": "github" 485 | }, 486 | "original": { 487 | "owner": "YaLTeR", 488 | "repo": "niri", 489 | "type": "github" 490 | } 491 | }, 492 | "nix-straight": { 493 | "flake": false, 494 | "locked": { 495 | "lastModified": 1696948727, 496 | "narHash": "sha256-6fQamWVIyeLoFSJl1WKcIl+LUdZluzFla4H+4Z5Cv2E=", 497 | "owner": "codingkoi", 498 | "repo": "nix-straight.el", 499 | "rev": "c64edbf49598453bd85dae1acef9a0f9d294185d", 500 | "type": "github" 501 | }, 502 | "original": { 503 | "owner": "codingkoi", 504 | "ref": "codingkoi/apply-librephoenixs-fix", 505 | "repo": "nix-straight.el", 506 | "type": "github" 507 | } 508 | }, 509 | "nix-test-runner": { 510 | "flake": false, 511 | "locked": { 512 | "lastModified": 1588761593, 513 | "narHash": "sha256-FKJykltAN/g3eIceJl4SfDnnyuH2jHImhMrXS2KvGIs=", 514 | "owner": "stoeffel", 515 | "repo": "nix-test-runner", 516 | "rev": "c45d45b11ecef3eb9d834c3b6304c05c49b06ca2", 517 | "type": "github" 518 | }, 519 | "original": { 520 | "owner": "stoeffel", 521 | "repo": "nix-test-runner", 522 | "type": "github" 523 | } 524 | }, 525 | "nixos": { 526 | "locked": { 527 | "lastModified": 1716509168, 528 | "narHash": "sha256-4zSIhSRRIoEBwjbPm3YiGtbd8HDWzFxJjw5DYSDy1n8=", 529 | "owner": "NixOS", 530 | "repo": "nixpkgs", 531 | "rev": "bfb7a882678e518398ce9a31a881538679f6f092", 532 | "type": "github" 533 | }, 534 | "original": { 535 | "id": "nixpkgs", 536 | "ref": "nixos-unstable", 537 | "type": "indirect" 538 | } 539 | }, 540 | "nixos-hardware": { 541 | "locked": { 542 | "lastModified": 1716173274, 543 | "narHash": "sha256-FC21Bn4m6ctajMjiUof30awPBH/7WjD0M5yqrWepZbY=", 544 | "owner": "NixOS", 545 | "repo": "nixos-hardware", 546 | "rev": "d9e0b26202fd500cf3e79f73653cce7f7d541191", 547 | "type": "github" 548 | }, 549 | "original": { 550 | "id": "nixos-hardware", 551 | "type": "indirect" 552 | } 553 | }, 554 | "nixos-old": { 555 | "locked": { 556 | "lastModified": 1716361217, 557 | "narHash": "sha256-mzZDr00WUiUXVm1ujBVv6A0qRd8okaITyUp4ezYRgc4=", 558 | "owner": "nixos", 559 | "repo": "nixpkgs", 560 | "rev": "46397778ef1f73414b03ed553a3368f0e7e33c2f", 561 | "type": "github" 562 | }, 563 | "original": { 564 | "owner": "nixos", 565 | "ref": "nixos-23.11", 566 | "repo": "nixpkgs", 567 | "type": "github" 568 | } 569 | }, 570 | "nixpkgs": { 571 | "locked": { 572 | "lastModified": 1700612854, 573 | "narHash": "sha256-yrQ8osMD+vDLGFX7pcwsY/Qr5PUd6OmDMYJZzZi0+zc=", 574 | "owner": "NixOS", 575 | "repo": "nixpkgs", 576 | "rev": "19cbff58383a4ae384dea4d1d0c823d72b49d614", 577 | "type": "github" 578 | }, 579 | "original": { 580 | "owner": "NixOS", 581 | "ref": "nixos-unstable", 582 | "repo": "nixpkgs", 583 | "type": "github" 584 | } 585 | }, 586 | "nixpkgs-lib": { 587 | "locked": { 588 | "lastModified": 1714640452, 589 | "narHash": "sha256-QBx10+k6JWz6u7VsohfSw8g8hjdBZEf8CFzXH1/1Z94=", 590 | "type": "tarball", 591 | "url": "https://github.com/NixOS/nixpkgs/archive/50eb7ecf4cd0a5756d7275c8ba36790e5bd53e33.tar.gz" 592 | }, 593 | "original": { 594 | "type": "tarball", 595 | "url": "https://github.com/NixOS/nixpkgs/archive/50eb7ecf4cd0a5756d7275c8ba36790e5bd53e33.tar.gz" 596 | } 597 | }, 598 | "nixpkgs-stable": { 599 | "locked": { 600 | "lastModified": 1716361217, 601 | "narHash": "sha256-mzZDr00WUiUXVm1ujBVv6A0qRd8okaITyUp4ezYRgc4=", 602 | "owner": "NixOS", 603 | "repo": "nixpkgs", 604 | "rev": "46397778ef1f73414b03ed553a3368f0e7e33c2f", 605 | "type": "github" 606 | }, 607 | "original": { 608 | "owner": "NixOS", 609 | "ref": "nixos-23.11", 610 | "repo": "nixpkgs", 611 | "type": "github" 612 | } 613 | }, 614 | "nixpkgs_2": { 615 | "locked": { 616 | "lastModified": 1712026416, 617 | "narHash": "sha256-N/3VR/9e1NlN49p7kCiATiEY6Tzdo+CbrAG8kqCQKcI=", 618 | "owner": "NixOS", 619 | "repo": "nixpkgs", 620 | "rev": "080a4a27f206d07724b88da096e27ef63401a504", 621 | "type": "github" 622 | }, 623 | "original": { 624 | "id": "nixpkgs", 625 | "type": "indirect" 626 | } 627 | }, 628 | "nixpkgs_3": { 629 | "locked": { 630 | "lastModified": 1716509168, 631 | "narHash": "sha256-4zSIhSRRIoEBwjbPm3YiGtbd8HDWzFxJjw5DYSDy1n8=", 632 | "owner": "NixOS", 633 | "repo": "nixpkgs", 634 | "rev": "bfb7a882678e518398ce9a31a881538679f6f092", 635 | "type": "github" 636 | }, 637 | "original": { 638 | "owner": "NixOS", 639 | "ref": "nixos-unstable", 640 | "repo": "nixpkgs", 641 | "type": "github" 642 | } 643 | }, 644 | "nixpkgs_4": { 645 | "locked": { 646 | "lastModified": 1714912032, 647 | "narHash": "sha256-clkcOIkg8G4xuJh+1onLG4HPMpbtzdLv4rHxFzgsH9c=", 648 | "owner": "NixOS", 649 | "repo": "nixpkgs", 650 | "rev": "ee4a6e0f566fe5ec79968c57a9c2c3c25f2cf41d", 651 | "type": "github" 652 | }, 653 | "original": { 654 | "owner": "NixOS", 655 | "ref": "nixpkgs-unstable", 656 | "repo": "nixpkgs", 657 | "type": "github" 658 | } 659 | }, 660 | "pre-commit-hooks": { 661 | "inputs": { 662 | "flake-compat": [ 663 | "niri", 664 | "crate2nix", 665 | "flake-compat" 666 | ], 667 | "flake-utils": "flake-utils_3", 668 | "gitignore": "gitignore", 669 | "nixpkgs": [ 670 | "niri", 671 | "crate2nix", 672 | "nixpkgs" 673 | ], 674 | "nixpkgs-stable": [ 675 | "niri", 676 | "crate2nix", 677 | "nixpkgs" 678 | ] 679 | }, 680 | "locked": { 681 | "lastModified": 1712055707, 682 | "narHash": "sha256-4XLvuSIDZJGS17xEwSrNuJLL7UjDYKGJSbK1WWX2AK8=", 683 | "owner": "cachix", 684 | "repo": "pre-commit-hooks.nix", 685 | "rev": "e35aed5fda3cc79f88ed7f1795021e559582093a", 686 | "type": "github" 687 | }, 688 | "original": { 689 | "owner": "cachix", 690 | "repo": "pre-commit-hooks.nix", 691 | "type": "github" 692 | } 693 | }, 694 | "root": { 695 | "inputs": { 696 | "home-manager": "home-manager", 697 | "niri": "niri", 698 | "nix-straight": "nix-straight", 699 | "nixos": "nixos", 700 | "nixos-hardware": "nixos-hardware", 701 | "nixos-old": "nixos-old", 702 | "stylix": "stylix" 703 | } 704 | }, 705 | "stylix": { 706 | "inputs": { 707 | "base16": "base16", 708 | "base16-fish": "base16-fish", 709 | "base16-foot": "base16-foot", 710 | "base16-helix": "base16-helix", 711 | "base16-kitty": "base16-kitty", 712 | "base16-tmux": "base16-tmux", 713 | "base16-vim": "base16-vim", 714 | "flake-compat": "flake-compat_2", 715 | "gnome-shell": "gnome-shell", 716 | "home-manager": "home-manager_2", 717 | "nixpkgs": "nixpkgs_4" 718 | }, 719 | "locked": { 720 | "lastModified": 1716456264, 721 | "narHash": "sha256-s9Tyj5pEivl/AsvrpkUkfR1Iu3zHfXpviPfe4HbPJ5I=", 722 | "owner": "danth", 723 | "repo": "stylix", 724 | "rev": "290c8aef476ce98fff9cefc059284429d561a085", 725 | "type": "github" 726 | }, 727 | "original": { 728 | "owner": "danth", 729 | "repo": "stylix", 730 | "type": "github" 731 | } 732 | }, 733 | "systems": { 734 | "locked": { 735 | "lastModified": 1681028828, 736 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 737 | "owner": "nix-systems", 738 | "repo": "default", 739 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 740 | "type": "github" 741 | }, 742 | "original": { 743 | "owner": "nix-systems", 744 | "repo": "default", 745 | "type": "github" 746 | } 747 | }, 748 | "systems_2": { 749 | "locked": { 750 | "lastModified": 1681028828, 751 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 752 | "owner": "nix-systems", 753 | "repo": "default", 754 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 755 | "type": "github" 756 | }, 757 | "original": { 758 | "owner": "nix-systems", 759 | "repo": "default", 760 | "type": "github" 761 | } 762 | }, 763 | "systems_3": { 764 | "locked": { 765 | "lastModified": 1681028828, 766 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 767 | "owner": "nix-systems", 768 | "repo": "default", 769 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 770 | "type": "github" 771 | }, 772 | "original": { 773 | "owner": "nix-systems", 774 | "repo": "default", 775 | "type": "github" 776 | } 777 | } 778 | }, 779 | "root": "root", 780 | "version": 7 781 | } 782 | -------------------------------------------------------------------------------- /dotfiles/flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "My NixOS configuration."; 3 | inputs = { 4 | home-manager = { 5 | url = "github:nix-community/home-manager"; 6 | # url = "/home/jon/Code/home-manager"; 7 | inputs.nixpkgs.follows = "nixos"; 8 | }; 9 | nix-straight = { 10 | url = "github:codingkoi/nix-straight.el?ref=codingkoi/apply-librephoenixs-fix"; 11 | flake = false; 12 | }; 13 | # nix-doom-emacs = { 14 | # url = "github:nix-community/nix-doom-emacs"; 15 | # inputs = { 16 | # nix-straight.follows = "nix-straight"; 17 | # }; 18 | # }; 19 | niri.url = "github:sodiboo/niri-flake"; 20 | # Re-enable this after https://github.com/nix-community/nix-doom-emacs/issues/409 is fixed 21 | # nix-doom-emacs.url = "github:nix-community/nix-doom-emacs"; 22 | nixos.url = "nixpkgs/nixos-unstable"; 23 | # nixos.url = "/home/jon/Code/nixpkgs"; 24 | # emacs-overlay.url = "github:nix-community/emacs-overlay"; 25 | nixos-old.url = "github:nixos/nixpkgs/nixos-23.11"; 26 | stylix.url = "github:danth/stylix"; 27 | 28 | }; 29 | outputs = { self, 30 | nixos, 31 | nixos-hardware, 32 | nixos-old, 33 | home-manager, 34 | nix-straight, 35 | # nix-doom-emacs, 36 | niri, 37 | stylix 38 | }: 39 | let overlays = [ 40 | # (final: prev: {mu = nixos-old.legacyPackages.${prev.system}.mu;}) 41 | ]; 42 | in { 43 | nixosConfigurations.jon-laptop = nixos.lib.nixosSystem { 44 | system = "x86_64-linux"; 45 | modules = [ ./configuration.nix 46 | # stylix.nixosModules.stylix 47 | # ./niri.nix 48 | # ({...}: { nixpkgs.overlays = [ (import self.inputs.emacs-overlay) ];}) 49 | ({...}: { nixpkgs.overlays = overlays;}) 50 | # ./cachix.nix 51 | nixos-hardware.nixosModules.framework-16-7040-amd 52 | 53 | home-manager.nixosModules.home-manager { 54 | home-manager.useGlobalPkgs = true; 55 | home-manager.useUserPackages = true; 56 | home-manager.backupFileExtension = "backup"; 57 | home-manager.users.jon = { pkgs, ... }: { 58 | imports = [ ./home.nix 59 | # ./niri.nix 60 | # ./nix-doom-emacs.nix 61 | # nix-doom-emacs.hmModule 62 | ]; 63 | }; 64 | } 65 | # homeConfigurations.jon = home-manager.lib.homeManagerConfiguration { 66 | # inherit pkgs; 67 | # modules = [ 68 | # niri.homeModules.config 69 | # { 70 | # programs.niri.settings = { 71 | # outputs."eDP-1".scale = 2.0; 72 | # }; 73 | # } 74 | # ]; 75 | # }; 76 | ]; 77 | }; 78 | }; 79 | } 80 | -------------------------------------------------------------------------------- /dotfiles/gnome.nix: -------------------------------------------------------------------------------- 1 | { config, lib, pkgs, ... }: 2 | 3 | { 4 | environment.systemPackages = with pkgs; [ 5 | deja-dup # Backups 6 | gthumb # Photos 7 | gnome.gnome-tweaks 8 | # gnome.gnome-boxes 9 | #gnomeExtensions.appindicator 10 | #gnomeExtensions.caffeine 11 | #gnomeExtensions.dash-to-dock 12 | #gnomeExtensions.gsconnect 13 | #gnomeExtensions.pop-shell 14 | foliate # Ebooks 15 | polkit_gnome 16 | 17 | # GTK Themes 18 | theme-vertex 19 | arc-theme 20 | theme-obsidian2 21 | plano-theme 22 | orchis-theme 23 | materia-theme 24 | equilux-theme 25 | numix-gtk-theme 26 | gnome.gnome-themes-extra 27 | arc-icon-theme 28 | tela-icon-theme 29 | faba-icon-theme 30 | vimix-icon-theme 31 | qogir-icon-theme 32 | flat-remix-icon-theme 33 | ]; 34 | services.gnome = { 35 | gnome-keyring.enable = true; 36 | gnome-online-accounts.enable = true; 37 | gnome-online-miners.enable = true; 38 | tracker.enable = true; 39 | tracker-miners.enable = true; 40 | }; 41 | services.xserver = { 42 | displayManager.gdm.enable = true; 43 | desktopManager.gnome.enable = true; 44 | }; 45 | programs = { 46 | gnome-terminal.enable = true; 47 | # gnome-documents.enable = true; 48 | kdeconnect = { 49 | enable = true; 50 | package = pkgs.gnomeExtensions.gsconnect; 51 | }; 52 | }; 53 | } 54 | -------------------------------------------------------------------------------- /dotfiles/hardware-configuration.nix: -------------------------------------------------------------------------------- 1 | # Do not modify this file! It was generated by ‘nixos-generate-config’ 2 | # and may be overwritten by future invocations. Please make changes 3 | # to /etc/nixos/configuration.nix instead. 4 | { config, lib, pkgs, modulesPath, ... }: 5 | 6 | { 7 | imports = 8 | [ (modulesPath + "/installer/scan/not-detected.nix") 9 | ]; 10 | 11 | boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "thunderbolt" "usb_storage" "usbhid" "uas" "sd_mod" ]; 12 | boot.initrd.kernelModules = [ ]; 13 | boot.kernelModules = [ "kvm-amd" ]; 14 | boot.extraModulePackages = [ ]; 15 | 16 | fileSystems."/" = 17 | { device = "/dev/disk/by-uuid/7fb63bf7-7337-4128-bb1a-2614b1e62989"; 18 | fsType = "ext4"; 19 | }; 20 | 21 | boot.initrd.luks.devices."nixos".device = "/dev/disk/by-uuid/16a1bc59-443b-4eb8-b0af-22a573106c8a"; 22 | 23 | fileSystems."/boot" = 24 | { device = "/dev/disk/by-uuid/A021-9D84"; 25 | fsType = "vfat"; 26 | options = [ "fmask=0022" "dmask=0022" ]; 27 | }; 28 | 29 | swapDevices = [ ]; 30 | 31 | # Enables DHCP on each ethernet and wireless interface. In case of scripted networking 32 | # (the default) this is the recommended approach. When using systemd-networkd it's 33 | # still possible to use this option, but it's recommended to use it in conjunction 34 | # with explicit per-interface declarations with `networking.interfaces..useDHCP`. 35 | networking.useDHCP = lib.mkDefault true; 36 | # networking.interfaces.wlp4s0.useDHCP = lib.mkDefault true; 37 | 38 | nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; 39 | hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; 40 | } 41 | -------------------------------------------------------------------------------- /dotfiles/home.nix: -------------------------------------------------------------------------------- 1 | {pkgs, lib, ...}: 2 | 3 | let 4 | # Personal Info 5 | name = "Jonathan Reeve"; 6 | email = "jon.reeve@gmail.com"; 7 | githubUsername = "JonathanReeve"; 8 | # Paths 9 | dots = "/home/jon/Agordoj/dotfiles"; 10 | dokumentoj = "/home/jon/Dokumentoj"; 11 | scripts = "/home/jon/Agordoj/scripts"; 12 | maildir = "/home/jon/Retpoŝto"; 13 | # Preferences 14 | font = "Victor Mono"; 15 | # font = "Nova Mono"; 16 | # font = "Fantasque Sans Mono"; 17 | backgroundColor = "#243442"; # Blue steel 18 | foregroundColor = "#deedf9"; # Light blue 19 | warningColor = "#e23131"; # Reddish 20 | lockCmd = "${pkgs.swaylock-fancy}/bin/swaylock-fancy -p -t ''"; 21 | brightnessctl = "${pkgs.brightnessctl}/bin/brightnessctl"; 22 | in 23 | { 24 | imports = [ 25 | # ./nix-doom-emacs.nix 26 | ]; 27 | # modules = [ 28 | # niri.homeModules.config { 29 | # programs.niri.settings = { 30 | # outputs."eDP-1".scale = 2.0; 31 | # }; 32 | # } 33 | # ]; 34 | 35 | accounts.email = { 36 | maildirBasePath = "${maildir}"; 37 | accounts = { 38 | gmail = { 39 | address = "${email}"; 40 | userName = "${email}"; 41 | flavor = "gmail.com"; 42 | passwordCommand = "${pkgs.pass}/bin/pass gmail"; 43 | primary = true; 44 | mu.enable = true; 45 | mbsync = { 46 | enable = true; 47 | create = "maildir"; 48 | expunge = "both"; 49 | patterns = [ "INBOX" "Lists" "[Gmail]/Sent Mail"]; 50 | extraConfig.channel = { 51 | MaxMessages = 2000; 52 | ExpireUnread = "yes"; 53 | }; 54 | }; 55 | realName = "${name}"; 56 | }; 57 | columbia = { 58 | address = "jonathan.reeve@columbia.edu"; 59 | userName = "jpr2152@columbia.edu"; 60 | flavor = "gmail.com"; 61 | passwordCommand = "${pkgs.pass}/bin/pass lionmail"; 62 | mu.enable = true; 63 | mbsync = { 64 | enable = true; 65 | create = "maildir"; 66 | expunge = "both"; 67 | patterns = [ "INBOX" "Homework" "Lists" "[Gmail]/Sent Mail"]; 68 | extraConfig.channel = { 69 | MaxMessages = 2000; 70 | ExpireUnread = "yes"; 71 | }; 72 | }; 73 | realName = "${name}"; 74 | }; 75 | protonmail = { 76 | address = "jonathan@jonreeve.com"; 77 | userName = "jonathan@jonreeve.com"; 78 | passwordCommand = "${pkgs.pass}/bin/pass show 127.0.0.1:1143/jonathan@jonreeve.com"; 79 | imap = { 80 | host = "127.0.0.1"; 81 | port = 1143; 82 | tls = { 83 | enable = true; 84 | useStartTls = true; 85 | certificatesFile = "/home/jon/.config/protonmail/bridge/cert.pem"; 86 | }; 87 | }; 88 | smtp = { 89 | host = "127.0.0.1"; 90 | port = 1025; 91 | tls = { 92 | enable = true; 93 | useStartTls = true; 94 | certificatesFile = "/home/jon/.config/protonmail/bridge/cert.pem"; 95 | }; 96 | }; 97 | mu.enable = true; 98 | mbsync = { 99 | enable = true; 100 | create = "maildir"; 101 | expunge = "both"; 102 | patterns = [ "INBOX" "Labels/Lists" "Sent" "Drafts" "Spam" ]; 103 | extraConfig.channel = { 104 | MaxMessages = 2000; 105 | ExpireUnread = "yes"; 106 | }; 107 | }; 108 | realName = "${name}"; 109 | }; 110 | }; 111 | }; 112 | programs = { 113 | alacritty = { 114 | enable = true; 115 | settings = { 116 | font.normal.family = "${font}"; 117 | font.size = 14; 118 | window.opacity = 0.9; 119 | colors.transparent_background_colors = true; 120 | shell = "nu"; 121 | }; 122 | }; 123 | bottom.enable = true; 124 | broot = { 125 | enable = true; 126 | enableFishIntegration = true; 127 | settings = { 128 | modal = true; 129 | }; 130 | }; 131 | emacs = { 132 | enable = true; 133 | extraPackages = epkgs: [ 134 | epkgs.mu4e 135 | ]; 136 | }; 137 | gnome-terminal = { 138 | profile.default = { 139 | allowBold = false; 140 | allowBell = false; 141 | font = "${font}"; 142 | transparencyPercent = 90; 143 | themeVariant = "dark"; 144 | }; 145 | }; 146 | # Have home-manager manage itself. 147 | home-manager = { 148 | enable = true; 149 | # path = "/home/jon/Code/home-manager"; 150 | }; 151 | direnv = { 152 | nix-direnv.enable = true; 153 | enable = true; 154 | enableZshIntegration = true; 155 | enableNushellIntegration = true; 156 | }; 157 | git = { 158 | enable = true; 159 | userName = "${name}"; 160 | userEmail = "${email}"; 161 | extraConfig = { 162 | pull.rebase = false; 163 | # url = { "git@github.com:" = { insteadOf = "https://github.com"; }; }; 164 | }; 165 | }; 166 | mbsync = { 167 | enable = true; 168 | }; 169 | mu = { 170 | enable = true; 171 | }; 172 | neovim = { 173 | enable = true; 174 | # package = pkgs.neovim; 175 | plugins = with pkgs.vimPlugins; [ spacevim ]; 176 | vimAlias = true; 177 | extraConfig = 178 | '' 179 | set mouse=a 180 | " Colemak some things 181 | nnoremap n j 182 | nnoremap j n 183 | nnoremap N J 184 | nnoremap J N 185 | nnoremap e k 186 | nnoremap k e 187 | nnoremap i l 188 | nnoremap l i 189 | ''; 190 | }; 191 | # niri = { 192 | # enable = true; 193 | # }; 194 | nix-index = { 195 | enable = true; 196 | enableFishIntegration = true; 197 | enableZshIntegration = true; 198 | }; 199 | fish = { 200 | enable = true; 201 | shellAbbrs = { 202 | # Git abbreviations 203 | "edit-home" = "$EDITOR ${dots}/home.nix"; 204 | "edit-conf" = "$EDITOR ${dots}/configuration.nix"; 205 | "ga" = "git add"; 206 | "gc" = "git commit"; 207 | "gcam" = "git commit -am"; 208 | "gcm" = "git commit -m"; 209 | "gco" = "git checkout"; 210 | "gcob" = "git checkout -b"; 211 | "gcom" = "git checkout master"; 212 | "gcod" = "git checkout develop"; 213 | "gd" = "git diff"; 214 | "gp" = "git push"; 215 | "gdc" = "git diff --cached"; 216 | "glg" = "git log --color --graph --pretty --oneline"; 217 | "glgb" = "git log --all --graph --decorate --oneline --simplify-by-decoration"; 218 | "gst" = "git status"; 219 | # Other abbreviations 220 | "em" = "emacsclient -c"; 221 | # "lock" = "${lockCmd}"; 222 | "new-session" = "dbus-send --system --type=method_call --print-reply --dest=org.freedesktop.DisplayManager $XDG_SEAT_PATH org.freedesktop.DisplayManager.Seat.SwitchToGreeter"; 223 | "portrait-monitor" = "xrandr --output DP-1 --rotate left --auto --right-of eDP-1"; 224 | "monitor" = "xrandr --output DP-1 --auto --above eDP-1"; 225 | "monitor-off" = "xrandr --output DP-1 --off"; 226 | }; 227 | shellAliases = { 228 | # Use vim as pager for manfiles, since it's prettier 229 | # "man" = "env PAGER=\"vim -R -c 'set ft=man'\" man"; 230 | }; 231 | functions = { 232 | vault="encfs $vaultloc $vaultmount"; 233 | unvault="fusermount -u $vaultmount"; 234 | jnl="vault; and emacsclient -c $vaultmount/Journal/jnl.org; and unvault"; 235 | upgrade='' 236 | nix flake update ${dots} 237 | sudo nixos-rebuild switch --flake ${dots} 238 | ''; 239 | clean = "nix-store --gc --print-roots; and sudo nix-collect-garbage --delete-older-than 5d"; 240 | # A function for renaming the most recent PDF, and putting it in my Papers dir. 241 | rename-pdf="mv (ls -t /tmp/*.pdf | head -n 1) ${dokumentoj}/Papers/$argv.pdf"; 242 | find-book="for engine in b c libgen ia; qutebrowser \":open -t $engine $argv\"; end"; 243 | # Search several search engines at once. `search b g l "search query"` 244 | search="for engine in $argv[1..-2]; qutebrowser \":open -t $engine $argv[-1]\"; end"; 245 | # Proverbs for greeting 246 | fish_greeting = "shuf -n 1 ${scripts}/proverboj.txt | ${pkgs.neo-cowsay}/bin/cowsay"; 247 | em = "emacsclient -c $argv &; disown"; 248 | }; 249 | interactiveShellInit = 250 | '' 251 | # Use Fisher for plugin management 252 | if not functions -q fisher 253 | set -q XDG_CONFIG_HOME; or set XDG_CONFIG_HOME ~/.config 254 | curl https://git.io/fisher --create-dirs -sLo $XDG_CONFIG_HOME/fish/functions/fisher.fish 255 | fish -c fisher 256 | end 257 | 258 | # Don't use vi keybindings in unknown terminals, 259 | # since weird things can happen. Also don't do colors. 260 | set acceptable_terms xterm-256color screen-256color xterm-termite 261 | if contains $TERM $acceptable_terms 262 | fish_vi_key_bindings 263 | # Load pywal colors 264 | cat ~/.cache/wal/sequences 265 | end 266 | 267 | set -U vaultmount ~/.private-mount 268 | set -U vaultloc ${dokumentoj}/Personal/.Vault_encfs 269 | 270 | # Disable the vim-mode indicator [I] and [N]. 271 | # Let the theme handle it instead. 272 | function fish_default_mode_prompt; true; end 273 | 274 | # This doesn't seem to work below for some reason. 275 | function fish_title; true; end 276 | 277 | # Emacs ansi-term support 278 | if test -n "$EMACS" 279 | set -x TERM eterm-color 280 | # Disable right prompt in emacs 281 | # function fish_right_prompt; true; end 282 | function fish_title; true; end 283 | end 284 | 285 | #eval (direnv hook fish) 286 | ''; 287 | # plugins = [ 288 | # { 289 | # name = "z"; 290 | # src = pkgs.fetchFromGitHub { 291 | # owner = "jethrokuan"; 292 | # repo = "z"; 293 | # rev = "45a9ff6d0932b0e9835cbeb60b9794ba706eef10"; 294 | # sha256 = "pWkEhjbcxXduyKz1mAFo90IuQdX7R8bLCQgb0R+hXs4="; 295 | # }; 296 | # } 297 | # { 298 | # name = "bang-bang"; 299 | # src = pkgs.fetchFromGitHub { 300 | # owner = "oh-my-fish"; 301 | # repo = "plugin-bang-bang"; 302 | # rev = "f969c618301163273d0a03d002614d9a81952c1e"; 303 | # sha256 = "A8ydBX4LORk+nutjHurqNNWFmW6LIiBPQcxS3x4nbeQ="; 304 | # }; 305 | # } 306 | # { 307 | # name = "fzf.fish"; 308 | # src = pkgs.fetchFromGitHub { 309 | # owner = "PatrickF1"; 310 | # repo = "fzf.fish"; 311 | # rev = "0dc2795255d6ac0759e6f1d572f64ea0768acefb"; 312 | # sha256 = "fl4/Pgtkojk5AE52wpGDnuLajQxHoVqyphE90IIPYFU="; 313 | # }; 314 | # } 315 | # { 316 | # name = "bass"; 317 | # src = pkgs.fetchFromGitHub { 318 | # owner = "edc"; 319 | # repo = "bass"; 320 | # rev = "2fd3d2157d5271ca3575b13daec975ca4c10577a"; 321 | # sha256 = "fl4/Pgtkojk5AE52wpGDnuLajQxHoVqyphE90IIPYFU="; 322 | # }; 323 | # } 324 | # ]; 325 | }; 326 | fzf = { 327 | enable = true; 328 | enableFishIntegration = true; 329 | enableZshIntegration = true; 330 | }; 331 | nushell = { 332 | enable = true; 333 | configFile.source = ./config.nu; 334 | environmentVariables = { 335 | PASSWORD_STORE_DIR = "${dokumentoj}/Personal/.password-store"; 336 | }; 337 | shellAliases = { 338 | upgrade = "nix flake update ${dots}; sudo nixos-rebuild switch --flake ${dots}"; 339 | }; 340 | }; 341 | starship = { 342 | enable = true; 343 | enableFishIntegration = true; 344 | enableNushellIntegration = true; 345 | enableZshIntegration = true; 346 | }; 347 | zsh = { 348 | enable = true; 349 | enableCompletion = true; 350 | enableVteIntegration = true; 351 | autosuggestion.enable = true; 352 | syntaxHighlighting.enable = true; 353 | }; 354 | zoxide = { 355 | enable = true; 356 | enableNushellIntegration = true; 357 | enableZshIntegration = true; 358 | }; 359 | termite = { 360 | enable = true; 361 | clickableUrl = true; 362 | # backgroundColor = "\${xrdb:background}"; 363 | backgroundColor = "rgba(32, 45, 56, 0.8)"; 364 | foregroundColor = "\${xrdb:foreground}"; 365 | font = "${font} 14"; 366 | }; 367 | rofi = { 368 | enable = true; 369 | theme = "~/.cache/wal/colors-rofi-dark.rasi"; 370 | font = "${font} 12"; 371 | package = pkgs.rofi-wayland; 372 | }; 373 | waybar = { 374 | enable = true; 375 | settings = [{ 376 | layer = "top"; 377 | height = 30; 378 | modules-left = [ "sway/workspaces" "sway/mode" "sway/window" ]; 379 | modules-center = [ "custom/clock" ]; 380 | modules-right = [ "custom/org-clock" "pulseaudio" "cpu" "memory" "network" "battery" "clock" ]; 381 | battery = { 382 | format = "{capacity}% {icon}"; 383 | format-icons = [ "" "" "" "" ""]; 384 | }; 385 | cpu = { 386 | format = "{usage}% "; 387 | tooltip = false; 388 | }; 389 | memory = { 390 | format = "{}% "; 391 | }; 392 | network = { 393 | format-wifi = "{essid} ({signalStrength}%) "; 394 | format-ethernet = "{ipaddr}/{cidr} "; 395 | tooltip-format = "{ifname} via {gwaddr} "; 396 | format-linked = "{ifname} (No IP) "; 397 | format-disconnected = "Disconnected ⚠"; 398 | format-alt = "{ifname}: {ipaddr}/{cidr}"; 399 | }; 400 | "custom/clock" = { 401 | interval = 10; 402 | exec = "date '+%a %d %b W%V-%u %R'"; 403 | format-alt = "{:%a, %d. %b %H:%M}"; 404 | }; 405 | "custom/org-clock" = { 406 | format = "{}"; 407 | max-length = 80; 408 | interval = 30; 409 | exec = "/run/current-system/sw/bin/env ${scripts}/org-clock.hs"; 410 | }; 411 | "pulseaudio" = { 412 | "scroll-step" = 1; 413 | "format" = "{volume}% {icon} {format_source}"; 414 | "format-bluetooth" = "{volume}% {icon} {format_source}"; 415 | "format-bluetooth-muted" = " {icon} {format_source}"; 416 | "format-muted" = " {format_source}"; 417 | "format-source" = "{volume}% "; 418 | "format-source-muted" = ""; 419 | "format-icons" = { 420 | "headphone" = ""; 421 | "hands-free" = ""; 422 | "headset" = ""; 423 | "phone" = ""; 424 | "portable" = ""; 425 | "car" = ""; 426 | "default" = ["" "" ""]; 427 | }; 428 | "on-click" = "pavucontrol"; 429 | }; 430 | }]; 431 | }; 432 | zathura = { 433 | enable = false; 434 | extraConfig = '' 435 | map n scroll down 436 | map e scroll up 437 | map h scroll left 438 | map i scroll right 439 | map j search next 440 | map J search previous 441 | set statusbar-v-padding 10 442 | ''; 443 | options = { 444 | font = "${font} 12"; 445 | }; 446 | }; 447 | password-store = { 448 | enable = true; 449 | settings = { 450 | PASSWORD_STORE_DIR = "${dokumentoj}/Personal/.password-store"; 451 | }; 452 | }; 453 | qutebrowser = { 454 | enable = true; 455 | extraConfig = '' 456 | c.statusbar.padding = {'top': 5, 'bottom': 5, 'left': 3, 'right': 3} 457 | c.tabs.padding = {'top': 2, 'bottom': 2, 'left': 2, 'right': 2} 458 | ''; 459 | keyBindings = { 460 | normal = { 461 | "N" = "tab-next"; 462 | "E" = "tab-prev"; 463 | "K" = "search-prev"; 464 | "l" = "mode-enter insert"; 465 | "n" = "scroll down"; 466 | "e" = "scroll up"; 467 | "i" = "scroll right"; 468 | "j" = "search-next"; 469 | "b" = "set-cmd-text -s :tab-select "; 470 | "gL" = "open javascript:location.href='org-protocol://capture?template=l&url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)+'&body='+encodeURIComponent(document.getSelection())"; 471 | "gM" = "open javascript:location.href='org-protocol://roam-ref?template=m&ref='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)+'&body='+encodeURIComponent(document.getSelection())"; 472 | "gR" = "open javascript:location.href='org-protocol://roam-ref?template=r&ref='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)"; 473 | "gB" = "spawn -m ${scripts}/downloadBook.py {url}"; 474 | "pf" = "spawn --userscript qute-pass"; 475 | "gz" = "jseval var d=document,s=d.createElement('script';;s.src='https://www.zotero.org/bookmarklet/loader.js';(d.body?d.body:d.documentElement;.appendChild(s;;void(0;;"; 476 | "t" = "set-cmd-text -s :open -t"; 477 | "Y" = "yank selection"; 478 | "O" = "set-cmd-text :open {url:pretty}"; 479 | "" = "back"; 480 | "" = "forward"; 481 | }; 482 | }; 483 | searchEngines = { 484 | "DEFAULT" = "https://duckduckgo.com/?q={}"; 485 | "g" = "https://www.google.com/search?q={}"; 486 | "l" = "https://www.google.com/search?hl=en&q={}&btnI=I"; 487 | "w" = "https://en.wikipedia.org/w/index.php?search={}"; 488 | "wd" = "https://www.wikidata.org/w/index.php?search={}"; 489 | "gs" = "https://scholar.google.com/scholar?q={}"; 490 | "b" = "https://www.google.com/search?tbm=bks&q={}"; 491 | "aw" = "https://wiki.archlinux.org/?search={}"; 492 | "o" = "https://search.nixos.org/options?channel=unstable&from=0&size=50&sort=relevance&query={}"; 493 | "p" = "https://search.nixos.org/packages?channel=unstable&from=0&size=50&sort=relevance&query={}"; 494 | "d" = "https://en.wiktionary.org/wiki/{}"; 495 | "v" = "https://eo.wiktionary.org/wiki/{}"; 496 | "melpa" = "https://melpa.org/#/?q={}"; 497 | "s" = "http://stackoverflow.com/search?q={}"; 498 | "ss" = "https://www.semanticscholar.org/search?q={}"; 499 | "m" = "https://maps.google.com/maps?q={}"; 500 | "c" = "https://clio.columbia.edu/quicksearch?q={}"; 501 | "gh" = "https://github.com/search?q={}&type=Repositories"; 502 | "h" = "https://hackage.haskell.org/packages/search?terms={}"; 503 | "ho" = "https://hoogle.haskell.org/?hoogle={}"; 504 | "libgen" = "https://libgen.is/search.php?req={}"; 505 | "viki" = "https://eo.wikipedia.org/w/index.php?search={}"; 506 | "ia" = "https://archive.org/details/texts?and%5B%5D={}&sin="; 507 | "mm" = "https://muse-jhu-edu.ezproxy.cul.columbia.edu/search?action=search&query=content:{}:and&limit=journal_id:131&min=1&max=10&t=search_journal_header"; 508 | }; 509 | settings = { 510 | content.local_content_can_access_remote_urls = true; 511 | content.headers.accept_language = "eo,en-US,en,fr"; 512 | colors = { 513 | completion.category.bg = "#333333"; 514 | tabs = { 515 | even.bg = "#222222"; 516 | odd.bg = "#222222"; 517 | selected.even.bg = "#285577"; 518 | selected.odd.bg = "#285577"; 519 | }; 520 | }; 521 | fonts = { 522 | completion.category = "11pt monospace"; 523 | default_family = "${font}"; 524 | default_size = "12pt"; 525 | }; 526 | hints.chars = "arstdhneio"; 527 | url.default_page = "${scripts}/homepage/homepage.html"; 528 | }; 529 | }; 530 | # vscode = { 531 | # enable = true; 532 | # extensions = with pkgs.vscode-extensions; [ 533 | # ms-python.python 534 | # vscodevim.vim 535 | # ]; 536 | # haskell = { 537 | # enable = true; 538 | # }; 539 | }; 540 | services = { 541 | # gnome-keyring.enable = true; 542 | gpg-agent.enable = true; 543 | clipmenu = { 544 | enable = true; 545 | launcher = "rofi"; 546 | }; 547 | dunst = { 548 | enable = true; 549 | settings = { 550 | global = { 551 | geometry = "950x80-30+70"; 552 | padding = 32; 553 | horizontal_padding = 30; 554 | # frame_width = 10; 555 | font = "${font} 12"; 556 | line_height = 4; 557 | markup = "full"; 558 | alignment = "left"; 559 | word_wrap = "true"; 560 | }; 561 | shortcuts = { 562 | close = "ctrl+space"; 563 | close_all = "ctrl+shift+space"; 564 | history = "ctrl+grave"; 565 | context = "ctrl+shift+period"; 566 | }; 567 | urgency_low = { 568 | timeout = 4; 569 | foreground = "${foregroundColor}"; 570 | background = "${backgroundColor}"; 571 | }; 572 | urgency_normal = { 573 | timeout = 8; 574 | foreground = "${foregroundColor}"; 575 | background = "${backgroundColor}"; 576 | }; 577 | urgency_critical = { 578 | timeout = 0; 579 | foreground = "${foregroundColor}"; 580 | background = "${warningColor}"; 581 | }; 582 | }; 583 | waylandDisplay = "eDP-1"; 584 | }; 585 | kanshi = { 586 | enable = true; 587 | profiles = { 588 | undocked = { 589 | outputs = [ 590 | { 591 | criteria = "eDP-1"; 592 | } 593 | ]; 594 | }; 595 | docked = { 596 | outputs = [ 597 | { criteria = "eDP-1"; 598 | position = "0,0"; 599 | } 600 | { 601 | criteria = "Samsung Electric Company SAMSUNG 0x00000F00"; 602 | position = "380,1440"; 603 | } 604 | ]; 605 | }; 606 | clamshell = { 607 | outputs = [ 608 | { criteria = "eDP-1"; 609 | status = "disable"; 610 | } 611 | { 612 | criteria = "Samsung Electric Company SAMSUNG 0x00000F00"; 613 | position = "0,0"; 614 | } 615 | ]; 616 | }; 617 | }; 618 | }; 619 | pueue = { 620 | enable = true; 621 | settings = { 622 | shared = { 623 | pueue_directory = "~/.local/share/pueue"; 624 | }; 625 | client = {}; 626 | daemon = { 627 | default_parallel_tasks = 2; 628 | }; 629 | }; 630 | }; 631 | screen-locker = { 632 | enable = false; 633 | lockCmd = "${lockCmd}"; 634 | }; 635 | swayidle = { 636 | enable = false; 637 | events = [{ 638 | event = "before-sleep"; 639 | command = "${lockCmd}"; 640 | }]; 641 | timeouts = [{ timeout = 900; command = "${lockCmd}"; }]; 642 | }; 643 | }; 644 | qt = { 645 | enable = true; 646 | style = { 647 | name = "adwaita-dark"; 648 | package = pkgs.adwaita-qt; 649 | }; 650 | platformTheme.name = "adwaita"; 651 | }; 652 | 653 | # Dotfiles for the home root, ~/ 654 | home = { 655 | # This should only be necessary with non-NixOS 656 | keyboard = { 657 | options = [ "caps:escape" "esperanto:colemak" ]; 658 | variant = "colemak"; 659 | }; 660 | pointerCursor = { 661 | name = "Vanilla-DMZ"; 662 | package = pkgs.vanilla-dmz; 663 | x11.enable = true; 664 | }; 665 | packages = with pkgs; [ 666 | # neovim-nightly 667 | # 668 | pkgs.pass # This is necessary for protonmail-bridge 669 | pkgs.gnome.gnome-keyring # Same 670 | ]; 671 | file = { 672 | ".config/doom" = { 673 | source = ./emacs/doom.d; 674 | recursive = true; 675 | onChange = "$HOME/.config/emacs/bin/doom sync"; 676 | }; 677 | ".local/share/applications/org-protocol.desktop".text = '' 678 | [Desktop Entry] 679 | Name=org-protocol 680 | Comment=Intercept calls from emacsclient to trigger custom actions 681 | Categories=Other; 682 | Keywords=org-protocol; 683 | Icon=emacs 684 | Type=Application 685 | Exec=emacsclient -- %u 686 | Terminal=false 687 | StartupWMClass=Emacs 688 | MimeType=x-scheme-handler/org-protocol;''; 689 | #".emacs.d/init.el".text = '' 690 | # (load "default.el") 691 | #''; 692 | 693 | # Vim all the things! 694 | ".inputrc".text = 695 | '' 696 | set editing-mode vi 697 | set keymap vi-command 698 | ''; 699 | ".stack/config.yaml".text = 700 | '' 701 | templates: 702 | params: 703 | author-name: ${name} 704 | author-email: ${email} 705 | copyright: ${name} 706 | github-username: ${githubUsername} 707 | nix: 708 | enable: true 709 | ''; 710 | }; 711 | language = { 712 | base = "eo"; 713 | }; 714 | # sessionVariables.LOCALE_ARCHIVE = "${pkgs.glibcLocales}/lib/locale/locale-archive"; 715 | # sessionVariables.LC_ALL = "eo.UTF-8"; 716 | username = "jon"; 717 | stateVersion = "22.05"; 718 | }; 719 | 720 | systemd.user = { 721 | services = { 722 | # Disabling this in favor of system-wide service? 723 | protonmail = { 724 | Unit = { Description = "Protonmail Bridge"; }; 725 | Service.ExecStart = "${pkgs.protonmail-bridge}/bin/protonmail-bridge --noninteractive"; 726 | Install.WantedBy = [ "default.target" ]; 727 | }; 728 | dwall = { 729 | Unit = { 730 | Description = "Set dynamic wallpaper using Dwall"; 731 | }; 732 | Service = { 733 | Type = "oneshot"; 734 | ExecStart = "${scripts}/dynamic-wallpaper/dwall.sh -p -s aurora"; 735 | }; 736 | Install = { 737 | WantedBy = ["multi-user.target"]; 738 | }; 739 | }; 740 | }; 741 | timers = { 742 | dwall = { 743 | Unit = { 744 | Description = "Set dynamic wallpaper using Dwall."; 745 | Requires = "dwall.service"; 746 | }; 747 | Timer = { 748 | Unit = "dwall.service"; 749 | OnCalendar="*-*-* *:00:00"; # Every hour 750 | }; 751 | Install = { 752 | WantedBy = ["timers.target"]; 753 | }; 754 | }; 755 | }; 756 | }; 757 | wayland.windowManager.sway = { 758 | enable = true; 759 | extraConfigEarly = ''include "${dots}/colors-sway"''; 760 | config = { 761 | bars = []; 762 | # colors = { 763 | # focused = { 764 | # background = "$color2"; 765 | # border = "$color2"; 766 | # text = "$foreground"; 767 | # indicator = "$color2"; 768 | # childBorder = "$color2"; 769 | # }; 770 | # focusedInactive = { 771 | # background = "$color1"; 772 | # text = "$foreground"; 773 | # border = "$color1"; 774 | # indicator = "$color1"; 775 | # childBorder = "$color1"; 776 | # }; 777 | # unfocused = { 778 | # background = "$color1"; 779 | # border = "$color2"; 780 | # text = "$foreground"; 781 | # indicator = "$color1"; 782 | # childBorder = "$color1"; 783 | # }; 784 | # }; 785 | fonts = { names = [ "Font Awesome" "${font}"]; size = 14.0;}; 786 | gaps = { outer = 10; inner = 10; }; 787 | input = { 788 | "type:keyboard" = { 789 | xkb_layout = "us"; 790 | xkb_variant = "colemak"; 791 | xkb_options = "caps:escape,esperanto:colemak"; 792 | }; 793 | "type:touchpad" = { 794 | click_method = "clickfinger"; 795 | }; 796 | }; 797 | output = { "eDP-1" = { 798 | # background = "$wallpaper fill"; 799 | }; }; 800 | left = "h"; 801 | down = "n"; 802 | up = "e"; 803 | right = "i"; 804 | modifier = "Mod4"; 805 | keybindings = 806 | { 807 | "Mod4+j" = "workspace 1"; 808 | "Mod4+l" = "workspace 2"; 809 | "Mod4+u" = "workspace 3"; 810 | "Mod4+y" = "workspace 4"; 811 | "Mod4+Shift+j" = "move container to workspace number 1"; 812 | "Mod4+Shift+l" = "move container to workspace number 2"; 813 | "Mod4+Shift+u" = "move container to workspace number 3"; 814 | "Mod4+Shift+y" = "move container to workspace number 4"; 815 | "Mod4+h" = "exec alacritty"; 816 | "Mod4+c" = "clipmenu"; 817 | "Mod4+Shift+c" = "kill"; 818 | "Mod4+space" = "exec ${pkgs.rofi}/bin/rofi -show drun"; 819 | # "Mod4+y" = "output eDP-1 disable"; 820 | # "Mod4+Shift+y" = "output eDP-1 enable"; 821 | "Mod4+n" = "workspace next"; 822 | "Mod4+e" = "workspace prev"; 823 | "Mod4+Shift+q" = "exit"; 824 | "Mod4+Shift+r" = "restart"; 825 | "Mod4+p" = "focus parent"; 826 | "Mod4+Shift+p" = "focus child"; 827 | "Mod1+h" = "focus left"; 828 | "Mod1+n" = "focus down"; 829 | "Mod1+e" = "focus up"; 830 | "Mod1+i" = "focus right"; 831 | "Mod4+r" = "mode resize"; 832 | "Mod4+o" = "exec emacsclient --eval '(org-clock-in-last)'"; 833 | "Mod4+Shift+o" = "exec emacsclient --eval '(org-clock-out)'"; 834 | "Mod4+Shift+e" = "exec emacsclient -c"; 835 | "Mod1+Shift+h" = "move left"; 836 | "Mod1+Shift+n" = "move down"; 837 | "Mod1+Shift+e" = "move up"; 838 | "Mod1+Shift+i" = "move right"; 839 | "Mod4+s" = "move scratchpad"; 840 | "Mod4+Shift+s" = "scratchpad show"; 841 | "Mod4+t" = "floating toggle"; 842 | "Mod4+x" = "layout toggle all"; 843 | "Mod4+v" = "split v"; 844 | "Mod4+Shift+v" = "split h"; 845 | "XF86MonBrightnessUp" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set '+10%'"; 846 | "XF86MonBrightnessDown" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set '10%-'"; 847 | "XF86AudioRaiseVolume" = "exec --no-startup-id ${pkgs.pulseaudio-ctl}/bin/pulseaudio-ctl up"; 848 | "XF86AudioLowerVolume" = "exec --no-startup-id ${pkgs.pulseaudio-ctl}/bin/pulseaudio-ctl down"; 849 | "XF86AudioMute" = "exec --no-startup-id ${pkgs.pulseaudio-ctl}/bin/pulseaudio-ctl mute"; 850 | # Open agenda with Super + A 851 | "Mod4+a" = "exec emacsclient -c -e '(org-agenda-list)(delete-other-windows)(org-agenda-day-view)'"; 852 | "Mod4+m" = "exec emacsclient -c -e '(mu4e)(mu4e-update-mail-and-index)'"; 853 | # lock screen with Super + L 854 | # "Mod4+l" = "exec ${lockCmd}"; 855 | # Change wallpaper 856 | "Mod4+w" = "exec ${pkgs.pywal}/bin/wal -e -t -i /home/jon/Bildujo/Ekranfonoj -o ${../scripts/pywal-reload.sh}"; 857 | "Mod4+Shift+w" = "exec ${pkgs.pywal}/bin/wal -e -t -i /run/media/jon/systemrestore/.systemrestore/Bildoj/ -o ${../scripts/pywal-reload.sh}"; 858 | }; 859 | modes = { 860 | resize = { 861 | h = "resize shrink width 10 px or 10 ppt"; 862 | n = "resize grow height 10 px or 10 ppt"; 863 | e = "resize shrink height 10 px or 10 ppt"; 864 | i = "resize grow width 10 px or 10 ppt"; 865 | Escape = "mode default"; 866 | }; 867 | }; 868 | startup = [ 869 | # Fix for slow GTK applications; see https://github.com/swaywm/sway/wiki#gtk-applications-take-20-seconds-to-start 870 | { command = "exec systemctl --user import-environment"; } 871 | # { command = "exec dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY SWAYSOCK"; } 872 | { command = "exec swaybg -i ~/Bildujo/Ekranfonoj/yz6ggt7m18l41.png -o '*' -m fill"; } 873 | { command = "exec ${pkgs.pywal}/bin/wal --theme base16-nord"; } 874 | { command = "exec megasync"; } 875 | { command = "exec waybar"; } 876 | { command = "exec ${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1"; } 877 | { command = "exec ${pkgs.autotiling}/bin/autotiling"; } 878 | ]; 879 | window.border = 10; 880 | }; 881 | extraConfig = '' 882 | # Clamshell mode 883 | set $laptop eDP-1 884 | bindswitch --reload --locked lid:on output $laptop disable 885 | bindswitch --reload --locked lid:off output $laptop enable 886 | exec_always ${scripts}/sway-reload.sh 887 | # Touchpad gestures 888 | bindgesture swipe:right workspace prev 889 | bindgesture swipe:left workspace next 890 | bindgesture pinch:inward+up move up 891 | bindgesture pinch:inward+down move down 892 | bindgesture pinch:inward+left move left 893 | bindgesture pinch:inward+right move right 894 | ''; 895 | }; 896 | # Dotfiles for ~/.config, ~/.local/share, etc. 897 | xdg = { 898 | enable = true; 899 | configFile = { 900 | "waybar/style.css" = { 901 | source = ./waybar-style.css; 902 | }; 903 | }; 904 | dataFile = { 905 | "qutebrowser/userscripts/" = { 906 | source = ../scripts/qutebrowser-userscripts; 907 | recursive = true; 908 | }; 909 | }; 910 | mimeApps = { 911 | enable = true; 912 | defaultApplications = { 913 | "application/pdf" = "org.gnome.Evince.desktop"; 914 | "text/html" = "org.qutebrowser.qutebrowser.desktop"; 915 | "x-scheme-handler/org-protocol" = "org-protocol.desktop"; 916 | "x-scheme-handler/http" = "org.qutebrowser.qutebrowser.desktop"; 917 | "x-scheme-handler/https" = "org.qutebrowser.qutebrowser.desktop"; 918 | "x-scheme-handler/about" = "org.qutebrowser.qutebrowser.desktop"; 919 | "x-scheme-handler/unknown" = "org.qutebrowser.qutebrowser.desktop"; 920 | }; 921 | }; 922 | }; 923 | } 924 | -------------------------------------------------------------------------------- /dotfiles/hyprland.conf: -------------------------------------------------------------------------------- 1 | 2 | autogenerated=0 # remove this line to get rid of the warning on top. 3 | 4 | monitor=,preferred,auto,1 5 | 6 | input { 7 | kb_layout=us 8 | kb_variant=colemak 9 | kb_model= 10 | kb_options= 11 | kb_rules= 12 | 13 | follow_mouse=1 14 | } 15 | 16 | general { 17 | sensitivity=1.0 # for mouse cursor 18 | main_mod=SUPER 19 | 20 | gaps_in=5 21 | gaps_out=20 22 | border_size=2 23 | col.active_border=0x66ee1111 24 | col.inactive_border=0x66333333 25 | 26 | apply_sens_to_raw=0 # whether to apply the sensitivity to raw input (e.g. used by games where you aim using your mouse) 27 | } 28 | 29 | decoration { 30 | rounding=10 31 | blur=1 32 | blur_size=3 # minimum 1 33 | blur_passes=1 # minimum 1, more passes = more resource intensive. 34 | # Your blur "amount" is blur_size * blur_passes, but high blur_size (over around 5-ish) will produce artifacts. 35 | # if you want heavy blur, you need to up the blur_passes. 36 | # the more passes, the more you can up the blur_size without noticing artifacts. 37 | } 38 | 39 | animations { 40 | # enabled = ye 41 | 42 | # Some default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more 43 | 44 | bezier = myBezier, 0.05, 0.9, 0.1, 1.05 45 | 46 | animation = windows, 1, 7, myBezier 47 | # animation = windowsOut, 1, 7, default, popin 80% 48 | # animation = border, 1, 10, default 49 | # animation = fade, 1, 7, default 50 | animation = workspaces, 1, 6, default 51 | } 52 | 53 | # example window rules 54 | # for windows named/classed as abc and xyz 55 | #windowrule=move 69 420,abc 56 | #windowrule=size 420 69,abc 57 | #windowrule=tile,xyz 58 | #windowrule=float,abc 59 | #windowrule=pseudo,abc 60 | #windowrule=monitor 0,xyz 61 | 62 | # example binds 63 | bind=SUPER,H,exec,alacritty 64 | bind=SUPER_SHIFT,C,killactive, 65 | bind=SUPER_SHIFT,Q,exit, 66 | bind=SUPER,E,exec,dolphin 67 | bind=SUPER_SHIFT,T,togglefloating, 68 | bind=SUPER,space,exec,rofi --show drun 69 | bind=SUPER,P,pseudo, 70 | 71 | bind=SUPER,H,movefocus,l 72 | bind=SUPER,I,movefocus,r 73 | bind=SUPER,E,movefocus,u 74 | bind=SUPER,N,movefocus,d 75 | 76 | bind=SUPER,J,workspace,1 77 | bind=SUPER,L,workspace,2 78 | bind=SUPER,U,workspace,3 79 | bind=SUPER,Y,workspace,4 80 | bind=SUPER,5,workspace,5 81 | bind=SUPER,6,workspace,6 82 | bind=SUPER,7,workspace,7 83 | bind=SUPER,8,workspace,8 84 | bind=SUPER,9,workspace,9 85 | bind=SUPER,0,workspace,10 86 | 87 | bind=SUPER_SHIFT,J,movetoworkspace,1 88 | bind=SUPER_SHIFT,L,movetoworkspace,2 89 | bind=SUPER_SHIFT,U,movetoworkspace,3 90 | bind=SUPER_SHIFT,Y,movetoworkspace,4 91 | bind=ALT,5,movetoworkspace,5 92 | bind=ALT,6,movetoworkspace,6 93 | bind=ALT,7,movetoworkspace,7 94 | bind=ALT,8,movetoworkspace,8 95 | bind=ALT,9,movetoworkspace,9 96 | bind=ALT,0,movetoworkspace,10 97 | -------------------------------------------------------------------------------- /dotfiles/niri.nix: -------------------------------------------------------------------------------- 1 | { config, pkgs, inputs, lib, ... }: { 2 | imports = [ inputs.niri.homeModules.niri ]; 3 | 4 | options.app.niri.enable = lib.mkEnableOption "niri"; 5 | 6 | config = lib.mkIf (config.app.niri.enable) { 7 | programs.niri = { 8 | enable = true; 9 | settings = { 10 | binds = with config.lib.niri.actions; let 11 | sh = spawn "sh" "-c"; 12 | in { 13 | # First Key Row 14 | "Super+Space".action = spawn "${pkgs.rofi-wayland}/bin/rofi" "-show" "drun"; 15 | "Super+W".action = spawn "${pkgs.kitty}/bin/kitty"; 16 | "Super+E".action = spawn "${pkgs.chromium}/bin/chromium"; 17 | "Super+R".action = close-window; 18 | 19 | # Quit Niri 20 | "Super+Shift+Q".action = quit; 21 | 22 | # # Lock Session 23 | # "Super+L".action = spawn "${pkgs.systemd}/bin/loginctl" "lock-session"; 24 | 25 | # Screenshotting 26 | "Print".action = screenshot; 27 | 28 | # Workspackes 29 | "Super+0".action = focus-workspace 0; 30 | "Super+1".action = focus-workspace 1; 31 | "Super+2".action = focus-workspace 2; 32 | "Super+3".action = focus-workspace 3; 33 | "Super+4".action = focus-workspace 4; 34 | "Super+5".action = focus-workspace 5; 35 | "Super+6".action = focus-workspace 6; 36 | "Super+7".action = focus-workspace 7; 37 | "Super+8".action = focus-workspace 8; 38 | "Super+9".action = focus-workspace 9; 39 | 40 | 41 | # Special Keys 42 | "XF86AudioRaiseVolume".action = sh "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.1+"; 43 | "XF86AudioLowerVolume".action = sh "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.1-"; 44 | "XF86AudioMute".action = sh "wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle"; 45 | }; 46 | }; 47 | }; 48 | }; 49 | } 50 | -------------------------------------------------------------------------------- /dotfiles/nix-doom-emacs.nix: -------------------------------------------------------------------------------- 1 | { config, lib, pkgs, nixos, ... }: 2 | 3 | { 4 | programs.doom-emacs = { 5 | enable = true; 6 | # dependencyOverrides = 7 | doomPrivateDir = ./emacs/doom.d; 8 | # emacsPackagesOverlay = self: super: { 9 | # # org-roam = super.org-roam.overrideAttrs (esuper: { 10 | # # src = pkgs.fetchFromGitHub { 11 | # # owner = "org-roam"; 12 | # # repo = "org-roam"; 13 | # # rev = "e9ae19c01cb1fac8256e404b3f9c06f4be5468e6"; 14 | # # sha256 = "4U75arstVrPA9mXNd6c4Jmjn1uEgFXPk7DhZo08v9Dg="; 15 | # # }; 16 | # # }); 17 | # # org-roam-bibtex = super.org-roam-bibtex.overrideAttrs (esuper: { 18 | # # src = pkgs.fetchFromGitHub { 19 | # # owner = "org-roam"; 20 | # # repo = "org-roam-bibtex"; 21 | # # rev = "c13a05b2c855ba1516241d8a1de33bf2c689d6e4"; 22 | # # sha256 = "PbF/oxaFDq1rc9g3yz2cwLJAyanNfBwxKTxWbhjINVQ="; 23 | # # }; 24 | # # }); 25 | # # org-roam-ui = pkgs.stdenv.mkDerivation { 26 | # # pname = "org-roam-ui"; 27 | # # version = "2020-08-14"; 28 | # # buildInputs = [ pkgs.emacs ]; 29 | # # src = pkgs.fetchFromGitHub { 30 | # # owner = "org-roam"; 31 | # # repo = "org-roam-ui"; 32 | # # rev = "b153f4fee99e36dec0fb56d987026d53bf97a0e8"; 33 | # # sha256 = "arstoxaFDq1rc9g3yz2cwLJAyanNfBwxKTxWbhjINVQ="; 34 | # # }; 35 | # # buildPhase = '' 36 | # # runHook preBuild 37 | # # emacs -L . --batch -f batch-byte-compile *.el 38 | # # runHook postBuild 39 | # # ''; 40 | # # installPhase = '' 41 | # # runHook preInstall 42 | # # install -d $out/share/emacs/site-lisp 43 | # # install *.el *.elc $out/share/emacs/site-lisp 44 | # # runHook postInstall 45 | # # ''; 46 | # # meta = { 47 | # # description = "Visualizations for Org-Roam"; 48 | # # homepage = "https://github.com/org-roam/org-roam-ui"; 49 | # # license = nixos.lib.licenses.gpl3Plus; 50 | # # maintainers = with nixos.lib.maintainers; [ JonathanReeve ]; 51 | # # }; 52 | # # }; 53 | # }; 54 | extraPackages = with pkgs; [ 55 | mu 56 | pass 57 | gnupg 58 | # aspell 59 | # aspellDicts.en 60 | (aspellWithDicts (dicts: with dicts; [ en en-computers en-science eo fr ])) 61 | ripgrep 62 | ]; 63 | extraConfig = '' 64 | (setq mu4e-mu-binary "${pkgs.mu}/bin/mu") 65 | (setq epg-gpg-program "${pkgs.gnupg}/bin/gpg") 66 | ''; 67 | }; 68 | } 69 | -------------------------------------------------------------------------------- /dotfiles/python.nix: -------------------------------------------------------------------------------- 1 | { config, lib, pkgs, ... }: 2 | 3 | { 4 | environment.systemPackages = with pkgs; [ 5 | # Python Development 6 | pipenv 7 | # poetry 8 | # mach-nix 9 | (python3.withPackages(ps: with ps; [ 10 | pandas 11 | matplotlib 12 | python-lsp-server # Emacs integration 13 | plotly 14 | flake8 # Syntax checking for emacs 15 | scikit-learn 16 | # altair 17 | # vega 18 | # vega_datasets 19 | jupyter 20 | jupyterlab 21 | # jupyter-book 22 | # jupytext 23 | # tensorflow 24 | nltk 25 | pip 26 | # poetry-dynamic-versioning 27 | numpy 28 | nose 29 | tldextract # required by qute-pass 30 | ])) 31 | ]; 32 | } 33 | -------------------------------------------------------------------------------- /dotfiles/waybar-style.css: -------------------------------------------------------------------------------- 1 | * { 2 | /* `otf-font-awesome` is required to be installed for icons */ 3 | font-family: Fantasque Sans Mono, FontAwesome, Roboto, Helvetica, Arial, sans-serif; 4 | font-size: 18px; 5 | } 6 | 7 | window#waybar { 8 | background-color: rgba(43, 48, 59, 0.5); 9 | border-bottom: 3px solid rgba(100, 114, 125, 0.5); 10 | color: @foreground; 11 | transition-property: background-color; 12 | transition-duration: .5s; 13 | } 14 | 15 | window#waybar.hidden { 16 | opacity: 0.2; 17 | } 18 | 19 | /* 20 | window#waybar.empty { 21 | background-color: transparent; 22 | } 23 | window#waybar.solo { 24 | background-color: @FOREGROUND; 25 | } 26 | */ 27 | 28 | window#waybar.termite { 29 | background-color: #3F3F3F; 30 | } 31 | 32 | window#waybar.chromium { 33 | background-color: #000000; 34 | border: none; 35 | } 36 | 37 | #workspaces button { 38 | padding: 0 5px; 39 | background-color: transparent; 40 | color: @foreground; 41 | /* Use box-shadow instead of border so the text isn't offset */ 42 | box-shadow: inset 0 -3px transparent; 43 | /* Avoid rounded borders under each workspace name */ 44 | border: none; 45 | border-radius: 0; 46 | } 47 | 48 | /* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */ 49 | #workspaces button:hover { 50 | background: rgba(0, 0, 0, 0.2); 51 | box-shadow: inset 0 -3px @foreground; 52 | } 53 | 54 | #workspaces button.focused { 55 | background-color: #64727D; 56 | box-shadow: inset 0 -3px @foreground; 57 | } 58 | 59 | #workspaces button.urgent { 60 | background-color: #eb4d4b; 61 | } 62 | 63 | #mode { 64 | background-color: #64727D; 65 | border-bottom: 3px solid @foreground; 66 | } 67 | 68 | #clock, 69 | #battery, 70 | #cpu, 71 | #memory, 72 | #disk, 73 | #temperature, 74 | #backlight, 75 | #network, 76 | #pulseaudio, 77 | #custom-media, 78 | #custom-org-clock, 79 | #tray, 80 | #mode, 81 | #idle_inhibitor, 82 | #mpd { 83 | padding: 0 10px; 84 | color: @foreground; 85 | } 86 | 87 | #window, 88 | #workspaces { 89 | margin: 0 4px; 90 | } 91 | 92 | /* If workspaces is the leftmost module, omit left margin */ 93 | .modules-left > widget:first-child > #workspaces { 94 | margin-left: 0; 95 | } 96 | 97 | /* If workspaces is the rightmost module, omit right margin */ 98 | .modules-right > widget:last-child > #workspaces { 99 | margin-right: 0; 100 | } 101 | 102 | #clock { 103 | background-color: @color2; 104 | } 105 | 106 | #battery { 107 | background-color: @color3; 108 | color: @foreground; 109 | } 110 | 111 | #battery.charging, #battery.plugged { 112 | color: @foreground; 113 | background-color: @color6; 114 | } 115 | 116 | @keyframes blink { 117 | to { 118 | background-color: @foreground; 119 | color: #000000; 120 | } 121 | } 122 | 123 | #battery.critical:not(.charging) { 124 | background-color: #f53c3c; 125 | color: @foreground; 126 | animation-name: blink; 127 | animation-duration: 0.5s; 128 | animation-timing-function: linear; 129 | animation-iteration-count: infinite; 130 | animation-direction: alternate; 131 | } 132 | 133 | label:focus { 134 | background-color: #000000; 135 | } 136 | 137 | #cpu { 138 | background-color: @color4; 139 | color: @foreground; 140 | } 141 | 142 | #memory { 143 | background-color: @color3; 144 | } 145 | 146 | #disk { 147 | background-color: @color2; 148 | } 149 | 150 | #backlight { 151 | background-color: #90b1b1; 152 | } 153 | 154 | #network { 155 | background-color: @color3; 156 | } 157 | 158 | #network.disconnected { 159 | background-color: #f53c3c; 160 | } 161 | 162 | #pulseaudio { 163 | background-color: #f1c40f; 164 | color: #000000; 165 | } 166 | 167 | #pulseaudio.muted { 168 | background-color: #90b1b1; 169 | color: #2a5c45; 170 | } 171 | 172 | #custom-media { 173 | background-color: #66cc99; 174 | color: #2a5c45; 175 | min-width: 100px; 176 | } 177 | 178 | #custom-media.custom-spotify { 179 | background-color: #66cc99; 180 | } 181 | 182 | #custom-media.custom-vlc { 183 | background-color: #ffa000; 184 | } 185 | 186 | #temperature { 187 | background-color: #f0932b; 188 | } 189 | 190 | #temperature.critical { 191 | background-color: #eb4d4b; 192 | } 193 | 194 | #tray { 195 | background-color: #2980b9; 196 | } 197 | 198 | #tray > .passive { 199 | -gtk-icon-effect: dim; 200 | } 201 | 202 | #tray > .needs-attention { 203 | -gtk-icon-effect: highlight; 204 | background-color: #eb4d4b; 205 | } 206 | 207 | #idle_inhibitor { 208 | background-color: #2d3436; 209 | } 210 | 211 | #idle_inhibitor.activated { 212 | background-color: #ecf0f1; 213 | color: #2d3436; 214 | } 215 | 216 | #mpd { 217 | background-color: #66cc99; 218 | color: #2a5c45; 219 | } 220 | 221 | #mpd.disconnected { 222 | background-color: #f53c3c; 223 | } 224 | 225 | #mpd.stopped { 226 | background-color: #90b1b1; 227 | } 228 | 229 | #mpd.paused { 230 | background-color: #51a37a; 231 | } 232 | 233 | #language { 234 | background: #00b093; 235 | color: #740864; 236 | padding: 0 5px; 237 | margin: 0 5px; 238 | min-width: 16px; 239 | } 240 | 241 | #keyboard-state { 242 | background: #97e1ad; 243 | color: #000000; 244 | padding: 0 0px; 245 | margin: 0 5px; 246 | min-width: 16px; 247 | } 248 | 249 | #keyboard-state > label { 250 | padding: 0 5px; 251 | } 252 | 253 | #keyboard-state > label.locked { 254 | background: rgba(0, 0, 0, 0.2); 255 | } 256 | 257 | #custom-org-clock.protocolu { 258 | background-color: #f53c3c; 259 | } 260 | #custom-org-clock.ensalutu { 261 | background-color: #f53c3c; 262 | } 263 | -------------------------------------------------------------------------------- /dotfiles/xmonad.hs: -------------------------------------------------------------------------------- 1 | import XMonad 2 | 3 | main = xmonad defaultConfig 4 | { terminal = "termite" 5 | , modMask = mod4Mask 6 | , borderWidth = 10 7 | } 8 | -------------------------------------------------------------------------------- /scripts/aspell.en.pws: -------------------------------------------------------------------------------- 1 | annotatable 2 | bigrams 3 | constructivism 4 | constructivist 5 | diachronic 6 | endnotes 7 | fetishization 8 | foci 9 | frazer 10 | fulcra 11 | hermeneut 12 | hermeneutics 13 | homomorphic 14 | hyperparameters 15 | hyponym 16 | hyponyms 17 | ideogrammatic 18 | ideographic 19 | imagisms 20 | imagists 21 | levenschtein 22 | literatures 23 | matcher 24 | materiality 25 | meronymy 26 | middlemarch 27 | newswire 28 | ontologically 29 | paraphilias 30 | phenomenologically 31 | proscripted 32 | pyrimedal 33 | recirculation 34 | sexualized 35 | spacy 36 | stemmer 37 | stopword 38 | stopwords 39 | todo 40 | trigrams 41 | visuality 42 | whitespace 43 | -------------------------------------------------------------------------------- /scripts/config.py: -------------------------------------------------------------------------------- 1 | 2 | c.colors.tabs.even.bg = "#2C33B0" 3 | c.colors.tabs.odd.bg = "#2C33B0" 4 | c.colors.tabs.selected.even.bg = "#710D95" 5 | c.colors.tabs.selected.odd.bg = "#710D95" 6 | 7 | -------------------------------------------------------------------------------- /scripts/downloadBook.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #!nix-shell -i python3 -p "python3.withPackages(ps: with ps; [ beautifulsoup4 requests isbnlib setuptools ])" 3 | 4 | 5 | """ Given a library.lol page, download the book and add to database. """ 6 | 7 | from bs4 import BeautifulSoup 8 | import requests 9 | from urllib.request import urlretrieve 10 | from sys import argv 11 | import subprocess 12 | import isbnlib 13 | 14 | papersDir = "/home/jon/Dokumentoj/Papers" 15 | destFile = f"{papersDir}/library2.bib" 16 | 17 | 18 | def findISBN(soup): 19 | allParas = soup.find_all("p") 20 | for para in allParas: 21 | text = para.get_text() 22 | if text.startswith('ISBN:'): 23 | isbn = text.split(',')[0][5:].strip() 24 | return isbn 25 | 26 | 27 | def findBookLink(soup): 28 | allAs = soup.find_all("a") 29 | for a in allAs: 30 | if 'href' in a.attrs: 31 | if a.attrs['href'].startswith('https://cloudflare-ipfs.com'): 32 | return a.attrs['href'] 33 | 34 | 35 | def isbnToBibtex(isbn): 36 | meta = isbnlib.meta(isbn) 37 | tobibtex = isbnlib.registry.bibformatters['bibtex'] 38 | return tobibtex(meta) 39 | 40 | 41 | def appendBibtex(bibtex, destFile=destFile): 42 | bibtex = f"\n{bibtex}\n" 43 | with open(destFile, 'a') as f: 44 | f.write(bibtex) 45 | 46 | 47 | def downloadBook(url, dest): 48 | urlretrieve(url, dest) 49 | print(f"Wrote {dest}") 50 | 51 | 52 | def getKey(bibtex): 53 | return bibtex.split('{')[1].split(',')[0] 54 | 55 | 56 | def openNotes(key): 57 | elisp = f'(bibtex-completion-edit-notes (list "{key}"))' 58 | subprocess.call(["emacsclient", "--eval", elisp]) 59 | 60 | 61 | def main(): 62 | print(f"Getting book from {argv[1]}") 63 | url = argv[1] 64 | resp = requests.get(url) 65 | webpage = resp.text 66 | soup = BeautifulSoup(webpage, features='html.parser') 67 | isbn = findISBN(soup) 68 | print(f"ISBN: {isbn}") 69 | bibtex = isbnToBibtex(isbn) 70 | key = getKey(bibtex) 71 | print(f"Key: {key}") 72 | appendBibtex(bibtex) 73 | bookLink = findBookLink(soup) 74 | pdfDest = f"{papersDir}/{key}.pdf" 75 | if bookLink.strip().endswith('pdf'): 76 | dest = f"{papersDir}/{key}.pdf" 77 | downloadBook(bookLink, dest) 78 | elif bookLink.strip().endswith('epub'): 79 | dest = f"{papersDir}/{key}.epub" 80 | downloadBook(bookLink, dest) 81 | else: 82 | exit(f"Can't download book with this extension.") 83 | openNotes(key) 84 | 85 | 86 | if __name__ == "__main__": 87 | main() 88 | # destFile = "/home/jon/Dokumentoj/Papers/library.bib" 89 | -------------------------------------------------------------------------------- /scripts/getBook.el: -------------------------------------------------------------------------------- 1 | ;;; getBook.el --- Description -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Copyright (C) 2021 Jonathan Reeve 4 | ;; 5 | ;; Author: Jonathan Reeve 6 | ;; Maintainer: Jonathan Reeve 7 | ;; Created: Majo 31, 2021 8 | ;; Modified: Majo 31, 2021 9 | ;; Version: 0.0.1 10 | ;; Keywords: Symbol’s value as variable is void: finder-known-keywords 11 | ;; Homepage: https://github.com/jon/getBook 12 | ;; Package-Requires: ((emacs "24.3")) 13 | ;; 14 | ;; This file is not part of GNU Emacs. 15 | ;; 16 | ;;; Commentary: 17 | ;;/home/jon/Dokumentoj/Papers/;; Description 18 | ;; 19 | ;;; Code: 20 | 21 | (require 'enlive) 22 | (require 'seq) 23 | (url-copy-file "http://google.com") 24 | 25 | ; asynchronously 26 | (defun print-url (url) 27 | (url-retrieve url 'print)) 28 | 29 | (print-url "http://www.gnu.org") 30 | 31 | ; synchronously 32 | (defun get-url (url) 33 | (with-current-buffer (url-retrieve-synchronously url) (buffer-string))) 34 | 35 | (print ) 36 | 37 | (setq data ) 38 | 39 | (with-temp-buffer (get-url "http://www.google.com")) 40 | 41 | 42 | (insert data) 43 | (defun getBook (query) 44 | "Get a book from a query. Add it to database." 45 | (interactive) 46 | 47 | (require 'url-util) 48 | 49 | (let ((queryURL (format "https://libgen.is/search.php?req=%s" (url-hexify-string query)))) 50 | 51 | (seq-filter 52 | (lambda (element) (enlive-attr element 'href)) 53 | (enlive-query-all (enlive-fetch queryURL) [td > a])) 54 | ;; (switch-to-buffer (url-retrieve-synchronously queryURL)) 55 | ) 56 | ) 57 | 58 | (insert (getBook "joy of clojure")) 59 | 60 | (message results) 61 | 62 | (provide 'getBook) 63 | ;;; getBook.el ends here 64 | -------------------------------------------------------------------------------- /scripts/homepage/config.py: -------------------------------------------------------------------------------- 1 | 2 | c.colors.tabs.even.bg = "#6A3D62" 3 | c.colors.tabs.odd.bg = "#6A3D62" 4 | c.colors.tabs.selected.even.bg = "#75455B" 5 | c.colors.tabs.selected.odd.bg = "#75455B" 6 | 7 | -------------------------------------------------------------------------------- /scripts/homepage/homepage.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Homepage 8 | 9 | 22 | 25 | 26 | 27 |
28 |

Hello!

29 |
30 |
31 |
32 |

Table of Contents

33 |
34 | 43 |
44 |
45 |
46 |

1. 47 | Communication

48 |
49 | 52 |
53 |
54 |
55 |

2. Apps

56 |
57 | 64 |
65 |
66 |
67 |

3. 68 | Esperanto

69 | 91 |
92 |
93 |

4. News

94 |
95 | 104 |
105 |
106 |
107 |

5. 108 | Entertainment

109 |
110 | 117 |
118 |
119 |
120 |

6. DH 121 | Scholarship

122 |
123 | 132 |
133 |
134 |
135 |

7. Coding

136 |
137 | 143 |
144 |
145 |
146 | 147 | 157 | 158 | -------------------------------------------------------------------------------- /scripts/homepage/homepage.sh: -------------------------------------------------------------------------------- 1 | #!/etc/profiles/per-user/jon/bin/fish 2 | set file "$HOME/Dokumentoj/Org/notes.org" 3 | set out "$HOME/Dokumentoj/Org/notes.html" 4 | set id "c8c13cd9-1ab1-4f48-afb6-9f48f0b38002" 5 | emacs --batch --eval "(progn (find-file \"$file\" )(org-id-goto \"$id\")(org-html-export-to-html nil t nil t))" 6 | set bg (head ~/.cache/wal/colors -n 1 | tail -n 1) 7 | set fg (head ~/.cache/wal/colors -n 2 | tail -n 1) 8 | pandoc -f html -t html --template=template-pandoc.html --metadata pagetitle="Homepage" -V fg=$fg -V bg=$bg -o $PWD/homepage.html $out 9 | -------------------------------------------------------------------------------- /scripts/homepage/template-pandoc.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | $for(author-meta)$ 8 | 9 | $endfor$ 10 | $if(date-meta)$ 11 | 12 | $endif$ 13 | $if(keywords)$ 14 | 15 | $endif$ 16 | $if(title-prefix)$$title-prefix$ – $endif$$pagetitle$ 17 | 18 | 34 | $if(highlighting-css)$ 35 | 38 | $endif$ 39 | $for(css)$ 40 | 41 | $endfor$ 42 | $if(math)$ 43 | $math$ 44 | $endif$ 45 | 48 | $for(header-includes)$ 49 | $header-includes$ 50 | $endfor$ 51 | 52 | 53 | $for(include-before)$ 54 | $include-before$ 55 | $endfor$ 56 | $if(title)$ 57 |
58 |

$title$

59 | $if(subtitle)$ 60 |

$subtitle$

61 | $endif$ 62 | $for(author)$ 63 |

$author$

64 | $endfor$ 65 | $if(date)$ 66 |

$date$

67 | $endif$ 68 |
69 | $endif$ 70 | $if(toc)$ 71 | 74 | $endif$ 75 |
76 |

Hello!

77 |
78 |
79 | $body$ 80 |
81 | $for(include-after)$ 82 | $include-after$ 83 | $endfor$ 84 | 85 | 95 | 96 | -------------------------------------------------------------------------------- /scripts/notifications.sh: -------------------------------------------------------------------------------- 1 | #!/run/current-system/sw/bin/sh 2 | 3 | . "${HOME}/.cache/wal/colors.sh" 4 | 5 | pkill dunst 6 | dunst -lb $background -nb $background -cb $color1 \ 7 | -lf $foreground -nf $foreground -cf $color1 \ 8 | -geom 600x80-30+70 -padding 30 -horizontal_padding 30 \ 9 | -word_wrap=true 10 | -------------------------------------------------------------------------------- /scripts/org-clock.hs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env runhaskell 2 | 3 | {-# LANGUAGE OverloadedStrings #-} 4 | 5 | import Turtle 6 | import qualified Data.Text as T 7 | import qualified Data.Text.IO as TIO 8 | import System.Posix.Env 9 | import Data.Maybe 10 | 11 | getClock :: Text 12 | getClock = "/run/current-system/sw/bin/emacsclient --eval '(if (org-clocking-p)(org-clock-get-clock-string) -1)'" 13 | 14 | out :: Shell Line 15 | out = inshell getClock empty 16 | 17 | main = do 18 | out <- shellStrict getClock empty 19 | -- TODO: make it so that this changes automatically depending on the desktop environment 20 | -- let red str = "" <> str <> "" 21 | currentDesktop <- getEnv "XDG_CURRENT_DESKTOP" 22 | let desktops = [ "GNOME", "KDE" ] :: [Text] 23 | let emptyString = "" :: String 24 | let emptyText = "" :: Text 25 | let thisDesktop = T.pack $ fromMaybe emptyString currentDesktop 26 | let red = if thisDesktop `elem` desktops then emptyText else "%{F#f00}" 27 | case out of 28 | -- Emacs is on, but returns "-1", which means that org-clock is not running. 29 | (ExitSuccess, "-1\n") -> TIO.putStrLn $ "Protocolu!\nProtocolu!\nprotocolu" 30 | -- Emacs is on and clocking. Print the clock value. 31 | (ExitSuccess, out) -> TIO.putStrLn $ clockstr <> "\n" <> clockstr <> "\nclock" where 32 | clockstr = T.drop 1 $ T.splitOn "\"" out !! 1 33 | -- Emacs is not on. 34 | (ExitFailure err, _) -> do 35 | TIO.putStrLn $ "Ensalutu!\nEnsalutu\nensalutu" -- <> repr err 36 | -- clockVal <- getEnv "clock" 37 | -- let clock = (read (fromMaybe "0" clockVal)) :: Int 38 | -- setEnv "clock" (show (clock + 1)) True 39 | -- clockVal <- getEnv "clock" 40 | -- let clock = (read (fromMaybe "0" clockVal)) :: Int 41 | -- print clock 42 | 43 | -- TODO: record how long I've been clocked out, 44 | -- and prompt me to log in if it's been too long 45 | -- let countFile = "/tmp/unclocked-count" 46 | -- -- count <- input countFile 47 | -- output countFile ((input countFile) + 1) 48 | -------------------------------------------------------------------------------- /scripts/org-clock.sh: -------------------------------------------------------------------------------- 1 | #!/run/current-system/sw/bin/bash 2 | 3 | export CLOCKSTRING=$(/run/current-system/sw/bin/emacsclient --eval '(if (org-clocking-p)(org-clock-get-clock-string) -1)' 2>&1 ) 4 | 5 | off=" Emacs off!" 6 | #noclock=' Off-clock!' 7 | noclock=' Off-clock!' 8 | 9 | case "$CLOCKSTRING" in 10 | *"can\'t find socket"*) 11 | echo $off ;; 12 | "-1") 13 | echo $off ;; 14 | *"server-start"*) 15 | echo $off ;; 16 | *"ERROR"*) 17 | echo $noclock ;; 18 | *"function definition"*) 19 | echo $noclock ;; 20 | *) 21 | echo ${CLOCKSTRING} > /tmp/errors ; 22 | esac 23 | 24 | # echo "---" 25 | # echo "Clock in last | bash='emacsclient --eval (org-clock-in-last)'" 26 | # echo "Stop clock | bash='emacsclient --eval (org-clock-out)'" 27 | -------------------------------------------------------------------------------- /scripts/pywal-emacs.py: -------------------------------------------------------------------------------- 1 | #!/run/current-system/sw/bin/python 2 | 3 | colors = open('/home/jon/.cache/wal/colors').read().split('\n')[:-1] 4 | 5 | template = """ 6 | (require 'base16-theme) 7 | 8 | ;; colours generated dynamically by wal 9 | (defun set-wal-colors () (setq base16-wal-colors 10 | '(:base00 "{}" 11 | :base01 "{}" 12 | :base02 "{}" 13 | :base03 "{}" 14 | :base04 "{}" 15 | :base05 "{}" 16 | :base06 "{}" 17 | :base07 "{}" 18 | :base08 "{}" 19 | :base09 "{}" 20 | :base0A "{}" 21 | :base0B "{}" 22 | :base0C "{}" 23 | :base0D "{}" 24 | :base0E "{}" 25 | :base0F "{}"))) 26 | 27 | (defvar base16-wal-colors nil "All colors for base16-wal are defined here.") 28 | (set-wal-colors) 29 | 30 | ;; Define the theme 31 | (deftheme base16-wal) 32 | 33 | ;; Add all the faces to the theme 34 | (base16-theme-define 'base16-wal base16-wal-colors) 35 | 36 | ;; Mark the theme as provided 37 | (provide-theme 'base16-wal) 38 | 39 | (provide 'base16-wal) 40 | """.format(*colors) 41 | 42 | open('/home/jon/.emacs.d/private/base16-wal-theme.el', 'w').write(template) 43 | -------------------------------------------------------------------------------- /scripts/pywal-reload.sh: -------------------------------------------------------------------------------- 1 | #!/run/current-system/sw/bin/bash 2 | 3 | # Source the colors. 4 | . "${HOME}/.cache/wal/colors.sh" 5 | 6 | # Set up qutebrowser. 7 | 8 | echo " 9 | c.colors.tabs.even.bg = \"$color1\" 10 | c.colors.tabs.odd.bg = \"$color1\" 11 | c.colors.tabs.selected.even.bg = \"$color2\" 12 | c.colors.tabs.selected.odd.bg = \"$color2\" 13 | " > /tmp/config.py 14 | 15 | # Waybar 16 | cat ~/.cache/wal/colors-waybar.css ~/.config/waybar/style.css > /tmp/waybar.css 17 | pkill waybar 18 | exec waybar -s /tmp/waybar.css & 19 | 20 | # Sway 21 | pkill swaybg 22 | exec swaybg -o '*' -m fill -i $wallpaper & 23 | 24 | running=`ps cax | grep qutebrowser | wc -l` 25 | if [ $running -gt 0 ]; then 26 | qutebrowser ":config-source /tmp/config.py" 27 | fi 28 | 29 | # Trigger homepage reload 30 | # ./homepage/homepage.sh 31 | 32 | # Workaround for pywal bug: https://github.com/dylanaraps/pywal/issues/624 33 | echo "element-text, element-icon {background-color: inherit; text-color: inherit;}" >> ~/.cache/wal/colors-rofi-dark.rasi 34 | 35 | # Trigger emacs reload 36 | emacsclient --eval "(load-theme 'ewal-doom-one)" 37 | -------------------------------------------------------------------------------- /scripts/qutebrowser-userscripts/dict: -------------------------------------------------------------------------------- 1 | #!/run/current-system/sw/bin/bash 2 | echo "open -t http://www.dict.cc/?s=$QUTE_SELECTED_TEXT" >> "$QUTE_FIFO" 3 | -------------------------------------------------------------------------------- /scripts/qutebrowser-userscripts/org-link: -------------------------------------------------------------------------------- 1 | #!/run/current-system/sw/bin/bash 2 | TITLE=`urlencode $QUTE_TITLE` 3 | emacsclient "org-protocol://capture?template=l&url=$QUTE_URL&title=$TITLE&body=$QUTE_SELECTED_TEXT" 4 | -------------------------------------------------------------------------------- /scripts/qutebrowser-userscripts/org-link.hs: -------------------------------------------------------------------------------- 1 | #!/run/current-system/sw/bin/runghc 2 | 3 | {-# LANGUAGE OverloadedStrings #-} 4 | 5 | import System.Environment (lookupEnv) 6 | import Network.HTTP.Base (urlEncode) 7 | import Turtle 8 | import Data.Text (concat, pack) 9 | import Data.Maybe (fromMaybe) 10 | 11 | encode str = case str of 12 | Nothing -> "" 13 | Just val -> urlEncode val 14 | 15 | main = do 16 | vars <- mapM lookupEnv ["QUTE_URL", "QUTE_TITLE", "QUTE_SELECTED_TEXT"] 17 | -- print vars 18 | let [_, title, selected] = map encode vars 19 | -- print encoded 20 | let url = fromMaybe "" $ head vars 21 | let out = "\"org-protocol://capture?template=l&url=" ++ url ++ "&title=" ++ title ++ "&body=" ++ selected ++ "\"" 22 | putStrLn out 23 | let command = Data.Text.concat ["emacsclient ", Data.Text.pack out] 24 | shell command empty 25 | -------------------------------------------------------------------------------- /scripts/qutebrowser-userscripts/org-movie: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | emacsclient "org-protocol://capture?template=m&url=$QUTE_URL&title=$QUTE_TITLE&body=$QUTE_SELECTED_TEXT" 3 | -------------------------------------------------------------------------------- /scripts/qutebrowser-userscripts/qute-pass: -------------------------------------------------------------------------------- 1 | #!/run/current-system/sw/bin/python 2 | 3 | # Copyright 2017 Chris Braun (cryzed) 4 | # 5 | # This file is part of qutebrowser. 6 | # 7 | # qutebrowser is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # qutebrowser is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with qutebrowser. If not, see . 19 | 20 | """ 21 | Insert login information using pass and a dmenu-compatible application (e.g. dmenu, rofi -dmenu, ...). A short 22 | demonstration can be seen here: https://i.imgur.com/KN3XuZP.gif. 23 | """ 24 | 25 | USAGE = """The domain of the site has to appear as a segment in the pass path, 26 | for example: "github.com/cryzed" or "websites/github.com". Alternatively the 27 | parameter `--unfiltered` may be used to get a list of all passwords. How the 28 | username and password are determined is freely configurable using the CLI 29 | arguments. As an example, if you instead store the username as part of the 30 | secret (and use a site's name as filename), instead of the default configuration, 31 | use `--username-target secret` and `--username-pattern "username: (.+)"`. 32 | 33 | The login information is inserted by emulating key events using qutebrowser's 34 | fake-key command in this manner: [USERNAME][PASSWORD], which is compatible 35 | with almost all login forms. 36 | 37 | If you use gopass with multiple mounts, use the CLI switch --mode gopass to switch to gopass mode. 38 | 39 | Suggested bindings similar to Uzbl's `formfiller` script: 40 | 41 | config.bind('', 'spawn --userscript qute-pass') 42 | config.bind('', 'spawn --userscript qute-pass --username-only') 43 | config.bind('

', 'spawn --userscript qute-pass --password-only') 44 | config.bind('', 'spawn --userscript qute-pass --otp-only') 45 | """ 46 | 47 | EPILOG = """Dependencies: tldextract (Python 3 module), pass, pass-otp (optional). 48 | For issues and feedback please use: https://github.com/cryzed/qutebrowser-userscripts. 49 | 50 | WARNING: The login details are viewable as plaintext in qutebrowser's debug log (qute://log) and might be shared if 51 | you decide to submit a crash report!""" 52 | 53 | import argparse 54 | import enum 55 | import fnmatch 56 | import functools 57 | import os 58 | import re 59 | import shlex 60 | import subprocess 61 | import sys 62 | 63 | import tldextract 64 | 65 | 66 | def expanded_path(path): 67 | # Expand potential ~ in paths, since this script won't be called from a shell that does it for us 68 | expanded = os.path.expanduser(path) 69 | # Add trailing slash if not present 70 | return os.path.join(expanded, '') 71 | 72 | 73 | argument_parser = argparse.ArgumentParser(description=__doc__, usage=USAGE, epilog=EPILOG) 74 | argument_parser.add_argument('url', nargs='?', default=os.getenv('QUTE_URL')) 75 | argument_parser.add_argument('--password-store', '-p', 76 | default=expanded_path(os.getenv('PASSWORD_STORE_DIR', default='~/.password-store')), 77 | help='Path to your pass password-store (only used in pass-mode)', type=expanded_path) 78 | argument_parser.add_argument('--mode', '-M', choices=['pass', 'gopass'], default="pass", 79 | help='Select mode [gopass] to use gopass instead of the standard pass.') 80 | argument_parser.add_argument('--prefix', type=str, 81 | help='Search only the given subfolder of the store (only used in gopass-mode)') 82 | argument_parser.add_argument('--username-pattern', '-u', default=r'.*/(.+)', 83 | help='Regular expression that matches the username') 84 | argument_parser.add_argument('--username-target', '-U', choices=['path', 'secret'], default='path', 85 | help='The target for the username regular expression') 86 | argument_parser.add_argument('--password-pattern', '-P', default=r'(.*)', 87 | help='Regular expression that matches the password') 88 | argument_parser.add_argument('--dmenu-invocation', '-d', default='rofi -dmenu', 89 | help='Invocation used to execute a dmenu-provider') 90 | argument_parser.add_argument('--no-insert-mode', '-n', dest='insert_mode', action='store_false', 91 | help="Don't automatically enter insert mode") 92 | argument_parser.add_argument('--io-encoding', '-i', default='UTF-8', 93 | help='Encoding used to communicate with subprocesses') 94 | argument_parser.add_argument('--merge-candidates', '-m', action='store_true', 95 | help='Merge pass candidates for fully-qualified and registered domain name') 96 | argument_parser.add_argument('--extra-url-suffixes', '-s', default='', 97 | help='Comma-separated string containing extra suffixes (e.g local)') 98 | argument_parser.add_argument('--unfiltered', dest='unfiltered', action='store_true', 99 | help='Show an unfiltered selection of all passwords in the store') 100 | argument_parser.add_argument('--always-show-selection', dest='always_show_selection', action='store_true', 101 | help='Always show selection, even if there is only a single match') 102 | group = argument_parser.add_mutually_exclusive_group() 103 | group.add_argument('--username-only', '-e', action='store_true', help='Only insert username') 104 | group.add_argument('--password-only', '-w', action='store_true', help='Only insert password') 105 | group.add_argument('--otp-only', '-o', action='store_true', help='Only insert OTP code') 106 | 107 | stderr = functools.partial(print, file=sys.stderr) 108 | 109 | 110 | class ExitCodes(enum.IntEnum): 111 | SUCCESS = 0 112 | FAILURE = 1 113 | # 1 is automatically used if Python throws an exception 114 | NO_PASS_CANDIDATES = 2 115 | COULD_NOT_MATCH_USERNAME = 3 116 | COULD_NOT_MATCH_PASSWORD = 4 117 | 118 | 119 | class CouldNotMatchUsername(Exception): 120 | pass 121 | 122 | 123 | class CouldNotMatchPassword(Exception): 124 | pass 125 | 126 | 127 | def qute_command(command): 128 | with open(os.environ['QUTE_FIFO'], 'w') as fifo: 129 | fifo.write(command + '\n') 130 | fifo.flush() 131 | 132 | 133 | def find_pass_candidates(domain, unfiltered=False): 134 | candidates = [] 135 | 136 | if arguments.mode == "gopass": 137 | gopass_args = ["gopass", "list", "--flat"] 138 | if arguments.prefix: 139 | gopass_args.append(arguments.prefix) 140 | all_passwords = subprocess.run(gopass_args, stdout=subprocess.PIPE).stdout.decode("UTF-8").splitlines() 141 | 142 | for password in all_passwords: 143 | if unfiltered or domain in password: 144 | candidates.append(password) 145 | else: 146 | for path, directories, file_names in os.walk(arguments.password_store, followlinks=True): 147 | secrets = fnmatch.filter(file_names, '*.gpg') 148 | if not secrets: 149 | continue 150 | 151 | # Strip password store path prefix to get the relative pass path 152 | pass_path = path[len(arguments.password_store):] 153 | split_path = pass_path.split(os.path.sep) 154 | for secret in secrets: 155 | secret_base = os.path.splitext(secret)[0] 156 | if not unfiltered and domain not in (split_path + [secret_base]): 157 | continue 158 | 159 | candidates.append(os.path.join(pass_path, secret_base)) 160 | return candidates 161 | 162 | 163 | def _run_pass(pass_arguments): 164 | # The executable is conveniently named after it's mode [pass|gopass]. 165 | pass_command = [arguments.mode] 166 | env = os.environ.copy() 167 | env['PASSWORD_STORE_DIR'] = arguments.password_store 168 | process = subprocess.run(pass_command + pass_arguments, env=env, stdout=subprocess.PIPE) 169 | return process.stdout.decode(arguments.io_encoding).strip() 170 | 171 | 172 | def pass_(path): 173 | return _run_pass(['show', path]) 174 | 175 | 176 | def pass_otp(path): 177 | if arguments.mode == "gopass": 178 | return _run_pass(['otp', '-o', path]) 179 | return _run_pass(['otp', path]) 180 | 181 | 182 | def dmenu(items, invocation): 183 | command = shlex.split(invocation) 184 | process = subprocess.run(command, input='\n'.join(items).encode(arguments.io_encoding), stdout=subprocess.PIPE) 185 | return process.stdout.decode(arguments.io_encoding).strip() 186 | 187 | 188 | def fake_key_raw(text): 189 | for character in text: 190 | # Escape all characters by default, space requires special handling 191 | sequence = '" "' if character == ' ' else r'\{}'.format(character) 192 | qute_command('fake-key {}'.format(sequence)) 193 | 194 | 195 | def extract_password(secret, pattern): 196 | match = re.match(pattern, secret) 197 | if not match: 198 | raise CouldNotMatchPassword("Pattern did not match target") 199 | try: 200 | return match.group(1) 201 | except IndexError: 202 | raise CouldNotMatchPassword("Pattern did not contain capture group, please use capture group. Example: (.*)") 203 | 204 | 205 | def extract_username(target, pattern): 206 | match = re.search(pattern, target, re.MULTILINE) 207 | if not match: 208 | raise CouldNotMatchUsername("Pattern did not match target") 209 | try: 210 | return match.group(1) 211 | except IndexError: 212 | raise CouldNotMatchUsername("Pattern did not contain capture group, please use capture group. Example: (.*)") 213 | 214 | 215 | def main(arguments): 216 | if not arguments.url: 217 | argument_parser.print_help() 218 | return ExitCodes.FAILURE 219 | 220 | extractor = tldextract.TLDExtract(extra_suffixes=arguments.extra_url_suffixes.split(',')) 221 | extract_result = extractor(arguments.url) 222 | 223 | # Try to find candidates using targets in the following order: fully-qualified domain name (includes subdomains), 224 | # the registered domain name, the IPv4 address if that's what the URL represents and finally the private domain 225 | # (if a non-public suffix was used). 226 | candidates = set() 227 | attempted_targets = [] 228 | 229 | private_domain = '' 230 | if not extract_result.suffix: 231 | private_domain = ('.'.join((extract_result.subdomain, extract_result.domain)) 232 | if extract_result.subdomain else extract_result.domain) 233 | 234 | for target in filter(None, [extract_result.fqdn, extract_result.registered_domain, extract_result.ipv4, private_domain]): 235 | attempted_targets.append(target) 236 | target_candidates = find_pass_candidates(target, unfiltered=arguments.unfiltered) 237 | if not target_candidates: 238 | continue 239 | 240 | candidates.update(target_candidates) 241 | if not arguments.merge_candidates: 242 | break 243 | else: 244 | if not candidates: 245 | stderr('No pass candidates for URL {!r} found! (I tried {!r})'.format(arguments.url, attempted_targets)) 246 | return ExitCodes.NO_PASS_CANDIDATES 247 | 248 | if len(candidates) == 1 and not arguments.always_show_selection: 249 | selection = candidates.pop() 250 | else: 251 | selection = dmenu(sorted(candidates), arguments.dmenu_invocation) 252 | 253 | # Nothing was selected, simply return 254 | if not selection: 255 | return ExitCodes.SUCCESS 256 | 257 | # If username-target is path and user asked for username-only, we don't need to run pass. 258 | # Or if using otp-only, it will run pass on its own. 259 | secret = None 260 | if not (arguments.username_target == 'path' and arguments.username_only) and not arguments.otp_only: 261 | secret = pass_(selection) 262 | username_target = selection if arguments.username_target == 'path' else secret 263 | try: 264 | if arguments.username_only: 265 | fake_key_raw(extract_username(username_target, arguments.username_pattern)) 266 | elif arguments.password_only: 267 | fake_key_raw(extract_password(secret, arguments.password_pattern)) 268 | elif arguments.otp_only: 269 | otp = pass_otp(selection) 270 | fake_key_raw(otp) 271 | else: 272 | # Enter username and password using fake-key and (which seems to work almost universally), then switch 273 | # back into insert-mode, so the form can be directly submitted by hitting enter afterwards 274 | fake_key_raw(extract_username(username_target, arguments.username_pattern)) 275 | qute_command('fake-key ') 276 | fake_key_raw(extract_password(secret, arguments.password_pattern)) 277 | except CouldNotMatchPassword as e: 278 | stderr('Failed to match password, target: secret, error: {}'.format(e)) 279 | return ExitCodes.COULD_NOT_MATCH_PASSWORD 280 | except CouldNotMatchUsername as e: 281 | stderr('Failed to match username, target: {}, error: {}'.format(arguments.username_target, e)) 282 | return ExitCodes.COULD_NOT_MATCH_USERNAME 283 | 284 | if arguments.insert_mode: 285 | qute_command('mode-enter insert') 286 | 287 | return ExitCodes.SUCCESS 288 | 289 | 290 | if __name__ == '__main__': 291 | arguments = argument_parser.parse_args() 292 | sys.exit(main(arguments)) 293 | -------------------------------------------------------------------------------- /scripts/qutebrowser-userscripts/qutepass.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright 2017 Chris Braun (cryzed) 4 | # 5 | # This file is part of qutebrowser. 6 | # 7 | # qutebrowser is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # qutebrowser is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with qutebrowser. If not, see . 19 | 20 | """ 21 | Insert login information using pass and a dmenu-compatible application (e.g. dmenu, rofi -dmenu, ...). A short 22 | demonstration can be seen here: https://i.imgur.com/KN3XuZP.gif. 23 | """ 24 | 25 | USAGE = """The domain of the site has to appear as a segment in the pass path, 26 | for example: "github.com/cryzed" or "websites/github.com". How the username and 27 | password are determined is freely configurable using the CLI arguments. As an 28 | example, if you instead store the username as part of the secret (and use a 29 | site's name as filename), instead of the default configuration, use 30 | `--username-target secret` and `--username-pattern "username: (.+)"`. 31 | 32 | The login information is inserted by emulating key events using qutebrowser's 33 | fake-key command in this manner: [USERNAME][PASSWORD], which is compatible 34 | with almost all login forms. 35 | 36 | If you use gopass with multiple mounts, use the CLI switch --mode gopass to switch to gopass mode. 37 | 38 | Suggested bindings similar to Uzbl's `formfiller` script: 39 | 40 | config.bind('', 'spawn --userscript qute-pass') 41 | config.bind('', 'spawn --userscript qute-pass --username-only') 42 | config.bind('

', 'spawn --userscript qute-pass --password-only') 43 | config.bind('', 'spawn --userscript qute-pass --otp-only') 44 | """ 45 | 46 | EPILOG = """Dependencies: tldextract (Python 3 module), pass, pass-otp (optional). 47 | For issues and feedback please use: https://github.com/cryzed/qutebrowser-userscripts. 48 | 49 | WARNING: The login details are viewable as plaintext in qutebrowser's debug log (qute://log) and might be shared if 50 | you decide to submit a crash report!""" 51 | 52 | import argparse 53 | import enum 54 | import fnmatch 55 | import functools 56 | import os 57 | import re 58 | import shlex 59 | import subprocess 60 | import sys 61 | 62 | import tldextract 63 | 64 | 65 | def expanded_path(path): 66 | # Expand potential ~ in paths, since this script won't be called from a shell that does it for us 67 | expanded = os.path.expanduser(path) 68 | # Add trailing slash if not present 69 | return os.path.join(expanded, '') 70 | 71 | 72 | argument_parser = argparse.ArgumentParser(description=__doc__, usage=USAGE, epilog=EPILOG) 73 | argument_parser.add_argument('url', nargs='?', default=os.getenv('QUTE_URL')) 74 | argument_parser.add_argument('--password-store', '-p', 75 | default=expanded_path(os.getenv('PASSWORD_STORE_DIR', default='~/.password-store')), 76 | help='Path to your pass password-store (only used in pass-mode)', type=expanded_path) 77 | argument_parser.add_argument('--mode', '-M', choices=['pass', 'gopass'], default="pass", 78 | help='Select mode [gopass] to use gopass instead of the standard pass.') 79 | argument_parser.add_argument('--username-pattern', '-u', default=r'.*/(.+)', 80 | help='Regular expression that matches the username') 81 | argument_parser.add_argument('--username-target', '-U', choices=['path', 'secret'], default='path', 82 | help='The target for the username regular expression') 83 | argument_parser.add_argument('--password-pattern', '-P', default=r'(.*)', 84 | help='Regular expression that matches the password') 85 | argument_parser.add_argument('--dmenu-invocation', '-d', default='rofi -dmenu', 86 | help='Invocation used to execute a dmenu-provider') 87 | argument_parser.add_argument('--no-insert-mode', '-n', dest='insert_mode', action='store_false', 88 | help="Don't automatically enter insert mode") 89 | argument_parser.add_argument('--io-encoding', '-i', default='UTF-8', 90 | help='Encoding used to communicate with subprocesses') 91 | argument_parser.add_argument('--merge-candidates', '-m', action='store_true', 92 | help='Merge pass candidates for fully-qualified and registered domain name') 93 | argument_parser.add_argument('--extra-url-suffixes', '-s', default='', 94 | help='Comma-separated string containing extra suffixes (e.g local)') 95 | group = argument_parser.add_mutually_exclusive_group() 96 | group.add_argument('--username-only', '-e', action='store_true', help='Only insert username') 97 | group.add_argument('--password-only', '-w', action='store_true', help='Only insert password') 98 | group.add_argument('--otp-only', '-o', action='store_true', help='Only insert OTP code') 99 | 100 | stderr = functools.partial(print, file=sys.stderr) 101 | 102 | 103 | class ExitCodes(enum.IntEnum): 104 | SUCCESS = 0 105 | FAILURE = 1 106 | # 1 is automatically used if Python throws an exception 107 | NO_PASS_CANDIDATES = 2 108 | COULD_NOT_MATCH_USERNAME = 3 109 | COULD_NOT_MATCH_PASSWORD = 4 110 | 111 | 112 | def qute_command(command): 113 | with open(os.environ['QUTE_FIFO'], 'w') as fifo: 114 | fifo.write(command + '\n') 115 | fifo.flush() 116 | 117 | 118 | def find_pass_candidates(domain): 119 | candidates = [] 120 | 121 | if arguments.mode == "gopass": 122 | all_passwords = subprocess.run(["gopass", "list", "--flat" ], stdout=subprocess.PIPE).stdout.decode("UTF-8").splitlines() 123 | 124 | for password in all_passwords: 125 | if domain in password: 126 | candidates.append(password) 127 | else: 128 | for path, directories, file_names in os.walk(arguments.password_store, followlinks=True): 129 | secrets = fnmatch.filter(file_names, '*.gpg') 130 | if not secrets: 131 | continue 132 | 133 | # Strip password store path prefix to get the relative pass path 134 | pass_path = path[len(arguments.password_store):] 135 | split_path = pass_path.split(os.path.sep) 136 | for secret in secrets: 137 | secret_base = os.path.splitext(secret)[0] 138 | if domain not in (split_path + [secret_base]): 139 | continue 140 | 141 | candidates.append(os.path.join(pass_path, secret_base)) 142 | return candidates 143 | 144 | 145 | def _run_pass(pass_arguments): 146 | # The executable is conveniently named after it's mode [pass|gopass]. 147 | pass_command = [arguments.mode] 148 | env = os.environ.copy() 149 | env['PASSWORD_STORE_DIR'] = arguments.password_store 150 | process = subprocess.run(pass_command + pass_arguments, env=env, stdout=subprocess.PIPE) 151 | return process.stdout.decode(arguments.io_encoding).strip() 152 | 153 | 154 | def pass_(path): 155 | return _run_pass(['show', path]) 156 | 157 | 158 | def pass_otp(path): 159 | return _run_pass(['otp', path]) 160 | 161 | 162 | def dmenu(items, invocation): 163 | command = shlex.split(invocation) 164 | process = subprocess.run(command, input='\n'.join(items).encode(arguments.io_encoding), stdout=subprocess.PIPE) 165 | return process.stdout.decode(arguments.io_encoding).strip() 166 | 167 | 168 | def fake_key_raw(text): 169 | for character in text: 170 | # Escape all characters by default, space requires special handling 171 | sequence = '" "' if character == ' ' else '\{}'.format(character) 172 | qute_command('fake-key {}'.format(sequence)) 173 | 174 | 175 | def main(arguments): 176 | if not arguments.url: 177 | argument_parser.print_help() 178 | return ExitCodes.FAILURE 179 | 180 | extractor = tldextract.TLDExtract(extra_suffixes=arguments.extra_url_suffixes.split(',')) 181 | extract_result = extractor(arguments.url) 182 | 183 | # Try to find candidates using targets in the following order: fully-qualified domain name (includes subdomains), 184 | # the registered domain name, the IPv4 address if that's what the URL represents and finally the private domain 185 | # (if a non-public suffix was used). 186 | candidates = set() 187 | attempted_targets = [] 188 | 189 | private_domain = '' 190 | if not extract_result.suffix: 191 | private_domain = ('.'.join((extract_result.subdomain, extract_result.domain)) 192 | if extract_result.subdomain else extract_result.domain) 193 | 194 | for target in filter(None, [extract_result.fqdn, extract_result.registered_domain, extract_result.ipv4, private_domain]): 195 | attempted_targets.append(target) 196 | target_candidates = find_pass_candidates(target) 197 | if not target_candidates: 198 | continue 199 | 200 | candidates.update(target_candidates) 201 | if not arguments.merge_candidates: 202 | break 203 | else: 204 | if not candidates: 205 | stderr('No pass candidates for URL {!r} found! (I tried {!r})'.format(arguments.url, attempted_targets)) 206 | return ExitCodes.NO_PASS_CANDIDATES 207 | 208 | selection = candidates.pop() if len(candidates) == 1 else dmenu(sorted(candidates), arguments.dmenu_invocation) 209 | # Nothing was selected, simply return 210 | if not selection: 211 | return ExitCodes.SUCCESS 212 | 213 | # If username-target is path and user asked for username-only, we don't need to run pass 214 | secret = None 215 | if not (arguments.username_target == 'path' and arguments.username_only): 216 | secret = pass_(selection) 217 | 218 | # Match password 219 | match = re.match(arguments.password_pattern, secret) 220 | if not match: 221 | stderr('Failed to match password pattern on secret!') 222 | return ExitCodes.COULD_NOT_MATCH_PASSWORD 223 | password = match.group(1) 224 | 225 | # Match username 226 | target = selection if arguments.username_target == 'path' else secret 227 | match = re.search(arguments.username_pattern, target, re.MULTILINE) 228 | if not match: 229 | stderr('Failed to match username pattern on {}!'.format(arguments.username_target)) 230 | return ExitCodes.COULD_NOT_MATCH_USERNAME 231 | username = match.group(1) 232 | 233 | if arguments.username_only: 234 | fake_key_raw(username) 235 | elif arguments.password_only: 236 | fake_key_raw(password) 237 | elif arguments.otp_only: 238 | otp = pass_otp(selection) 239 | fake_key_raw(otp) 240 | else: 241 | # Enter username and password using fake-key and (which seems to work almost universally), then switch 242 | # back into insert-mode, so the form can be directly submitted by hitting enter afterwards 243 | fake_key_raw(username) 244 | qute_command('fake-key ') 245 | fake_key_raw(password) 246 | 247 | if arguments.insert_mode: 248 | qute_command('enter-mode insert') 249 | 250 | return ExitCodes.SUCCESS 251 | 252 | 253 | if __name__ == '__main__': 254 | arguments = argument_parser.parse_args() 255 | sys.exit(main(arguments)) 256 | -------------------------------------------------------------------------------- /scripts/setup.fish: -------------------------------------------------------------------------------- 1 | # This is my setup script for NixOS and Nix's home-manager. 2 | # It first puts my NixOS configs in the right place using symlinks, 3 | # then sets up fish shell functions and aliases that only need to be 4 | # set up once. 5 | 6 | set dots "/home/jon/Dotfiles/dotfiles" 7 | set XDG_CONFIG_HOME /home/jon/.config 8 | mkdir -p "$HOME/.config/nixpkgs" 9 | ln -sf "$dots/home.nix" "$XDG_CONFIG_HOME/nixpkgs/home.nix" 10 | sudo ln -sf "$dots/configuration.nix" "/etc/nixos" 11 | sudo ln -sf "$dots/hardware-configuration.nix" "/etc/nixos" 12 | ln -sf "/home/jon/Dotfiles/scripts/org-clock.hs" "$XDG_CONFIG_HOME/argos/clock.30s.hs" 13 | -------------------------------------------------------------------------------- /scripts/sway-reload.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if grep -q open /proc/acpi/button/lid/LID0/state; then 4 | swaymsg output eDP-1 enable 5 | else 6 | swaymsg output eDP-1 disable 7 | fi 8 | -------------------------------------------------------------------------------- /scripts/wikidata.el: -------------------------------------------------------------------------------- 1 | ;;; wikidata.el -*- lexical-binding: t; -*- 2 | ;; 3 | ;; Copyright (C) 2021 Jonathan Reeve 4 | ;; 5 | ;; Author: Jonathan Reeve 6 | ;; Maintainer: Jonathan Reeve 7 | ;; Created: Aprilo 17, 2021 8 | ;; Modified: Aprilo 17, 2021 9 | ;; Version: 0.0.1 10 | ;; Keywords: Symbol’s value as variable is void: finder-known-keywords 11 | ;; Homepage: https://github.com/jon/wikidata 12 | ;; Package-Requires: ((emacs "24.3")) 13 | ;; 14 | ;; This file is not part of GNU Emacs. 15 | ;; 16 | ;;; Commentary: 17 | ;; 18 | ;; 19 | ;; 20 | ;;; Code: 21 | 22 | (require 'request) 23 | 24 | (request 25 | "http://httpbin.org/get" 26 | :params '(("key" . "value") ("key2" . "value2")) 27 | :parser 'json-read 28 | :success (cl-function 29 | (lambda (&key data &allow-other-keys) 30 | (setq json data))) 31 | ) 32 | 33 | (message json) 34 | 35 | (provide 'wikidata) 36 | 37 | ;;; wikidata.el ends here 38 | -------------------------------------------------------------------------------- /scripts/wikidata.hs: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell -i runhaskell -p "haskellPackages.ghcWithPackages (ps: with ps; [http-conduit http-client-tls yaml])" 3 | 4 | {-# LANGUAGE OverloadedStrings #-} 5 | import Data.Aeson (Value, Array, Object, (.:)) 6 | import qualified Data.ByteString.Char8 as L8 7 | import Data.ByteString.Internal as BS 8 | import Network.HTTP.Simple 9 | import System.Environment 10 | -- import qualified Data.Yaml as Yaml 11 | 12 | 13 | 14 | main :: IO () 15 | main = do 16 | args <- getArgs 17 | let query = Just $ BS.packChars $ head args 18 | let request 19 | = setRequestQueryString [("action", Just "wbsearchentities") 20 | ,("search", query) 21 | ,("language", Just "en") 22 | ,("format", Just "json")] 23 | "https://www.wikidata.org/w/api.php" 24 | response <- httpJSON request 25 | let body = (getResponseBody response) :: Object 26 | let result = body .: "search" 27 | print result 28 | -- L8.putStrLn $ Yaml.encode result 29 | -------------------------------------------------------------------------------- /scripts/wikidata.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env nix-shell 2 | #! nix-shell -i python -p "python38.withPackages(ps: with ps; [ requests ])"" 3 | 4 | import json 5 | import requests 6 | import sys 7 | from subprocess import run, PIPE 8 | 9 | query = sys.argv[1] 10 | baseURL = "https://www.wikidata.org/w/api.php" 11 | params = {"action": "wbsearchentities", 12 | "search": query, 13 | "language": "en", 14 | "format": "json"} 15 | response = requests.get(baseURL, params=params) 16 | 17 | if response.ok: 18 | decoded = json.loads(response.text) 19 | # print(decoded['search'][0]) 20 | itemsWithDescriptions = '\n'.join(['\t'.join(["http:"+item.get('url'), item.get('label', ''), item.get('descriptions', '')]) 21 | for item in decoded['search']]) 22 | out = run(['rofi', '-dmenu'], input=itemsWithDescriptions, encoding='ascii', capture_output=True) 23 | print('#+wikidata: '+out.stdout.split('\t')[0]) 24 | else: 25 | print("Something went wrong.") 26 | print(response) 27 | --------------------------------------------------------------------------------