home.nix (34266B)
1 { 2 config, 3 lib, 4 pkgs, 5 inputs, 6 hostname, 7 ... 8 }: 9 10 let 11 colors = import ./colors.nix; 12 13 isync-oauth2 = 14 with pkgs; 15 buildEnv { 16 # takens from: 17 # https://github.com/wentasah/nix-conf/raw/master/modules/mail.nix 18 # https://github.com/NixOS/nixpkgs/issues/108480#issuecomment-1115108802 19 name = "isync"; 20 paths = [ pkgs.isync ]; 21 pathsToLink = [ "/bin" ]; 22 nativeBuildInputs = [ makeWrapper ]; 23 postBuild = '' 24 wrapProgram "$out/bin/mbsync" \ 25 --prefix SASL_PATH : "${cyrus_sasl}/lib/sasl2:${cyrus-sasl-xoauth2}/lib/sasl2" 26 ''; 27 }; 28 29 uvtools = 30 with pkgs; 31 appimageTools.wrapType2 rec { 32 pname = "UVtools"; 33 version = "5.0.6"; 34 src = fetchurl { 35 url = "https://github.com/sn4k3/${pname}/releases/download/v${version}/${pname}_linux-x64_v${version}.AppImage"; 36 hash = "sha256-T1E2+7YocWbspRrpWoexfLmm7LZSb4Nkw8WSBD6zTHs"; 37 }; 38 extraPkgs = pkgs: [ pkgs.icu ]; 39 }; 40 41 my-texlive = 42 with pkgs; 43 texlive.withPackages ( 44 texlivePackages: with texlivePackages; [ 45 scheme-small 46 latexmk 47 48 algorithm2e 49 amsmath 50 babel 51 biber 52 biblatex 53 biblatex-apa 54 biblatex-ieee 55 booktabs 56 caption 57 capt-of 58 circuitikz 59 cite 60 collection-fontsrecommended 61 ec 62 enumitem 63 esdiff 64 hyperref 65 ifoddpage 66 microtype 67 pgfplots 68 preview 69 pslatex 70 relsize 71 siunitx 72 url 73 wrapfig 74 xcolor 75 ] 76 ); 77 78 in 79 { 80 home = { 81 username = "vin"; 82 stateVersion = "24.05"; 83 84 packages = with pkgs; [ 85 # document writing and viewing 86 my-texlive 87 88 # messaging 89 profanity 90 vesktop 91 92 # email 93 muchsync 94 oauth2ms 95 96 # hardware 97 amdgpu_top 98 99 # encryption 100 age 101 oath-toolkit 102 # TODO actually use my yubikey? 103 #age-plugin-yubikey 104 #yubikey-agent 105 #yubikey-manager 106 107 # system utils 108 file 109 htop 110 mlocate 111 ncdu 112 nixfmt-rfc-style 113 ripgrep 114 unison 115 116 # X and desktop-related 117 scrot 118 sxiv 119 xclip 120 xwallpaper 121 122 # desktop-related 123 dmenu 124 scrot 125 xclip 126 xsel 127 128 # 3d printing 129 prusa-slicer 130 uvtools 131 ]; 132 133 preferXdgDirectories = true; 134 135 sessionPath = [ 136 "$HOME/bin" 137 "$HOME/.local/bin" 138 ]; 139 140 sessionVariables = { 141 EDITOR = "emacsclient -c"; 142 VISUAL = "emacsclient -t"; 143 PAGER = "less"; 144 LESS = "-iR"; 145 LESSHISTFILE = "/dev/null"; 146 BROWSER = "qutebrowser"; 147 148 GOPROXY = "direct"; 149 150 AGE_KEY = "$HOME/.ssh/id_ed25519"; 151 AGE_PUB = "$AGE_KEY.pub"; 152 KASI_DIR = if hostname == "demiurge" then "/data/kasi" else "/home/vin/.kasi"; 153 KASI_ENCRYPT = "age -R $AGE_PUB"; 154 KASI_DECRYPT = "age -d -i $AGE_KEY"; 155 KASI_EXT = "age"; 156 KASI_CLIPBOARD = "wl-copy -o"; 157 158 # w3m is only used for aerc html preview 159 W3M_DIR = "/var/empty"; 160 161 # backblaze on rclone 162 RCLONE_FAST_LIST = 1; 163 164 CRAWL_DIR = "$HOME/.local/share/crawl"; 165 166 MOZ_ACCELERATED = 1; 167 MOZ_WEBRENDER = 1; 168 169 # broken qt6.9 rendering 170 QTWEBENGINE_FORCE_USE_GBM = 0; 171 }; 172 173 shellAliases = { 174 # shortened commands 175 md = "mkdir -p"; 176 e = "$EDITOR"; 177 p = "$PAGER"; 178 m = "aerc"; 179 gc = "git clone"; 180 cbc = "wl-copy -c; wl-copy -cp"; 181 182 # default arguments to commands 183 ls = "ls -F --color=auto"; 184 rsync = "rsync --no-inc-recursive"; 185 mpv = "mpv --save-position-on-quit"; 186 wget = "wget --no-hsts"; 187 ytdl = "noglob yt-dlp"; 188 189 # shortened nix commands 190 # the `-c $SHELL` is there because it defaults to bash even if 191 # that's not my user shell 192 nd = "nix develop -c $SHELL"; 193 nr = "nix run"; 194 ns = "nix search"; 195 nsh = "nix shell"; 196 }; 197 }; 198 199 fonts.fontconfig = { 200 enable = true; 201 defaultFonts = { 202 emoji = [ ]; 203 monospace = [ "Comic Code" ]; 204 sansSerif = [ "Cantarell" ]; 205 serif = [ "CMU Serif" ]; 206 }; 207 }; 208 209 gtk = { 210 enable = true; 211 font.name = "monospace 11"; 212 iconTheme.name = "rose-pine"; 213 iconTheme.package = pkgs.rose-pine-icon-theme; 214 theme.name = "Everblush"; 215 theme.package = inputs.everblush-gtk.packages.x86_64-linux.default; 216 }; 217 218 dconf.settings = { 219 "org/virt-manager/virt-manager/connections" = { 220 autoconnect = [ "qemu:///system" ]; 221 uris = [ "qemu:///system" ]; 222 }; 223 }; 224 225 accounts.email = { 226 maildirBasePath = "/data/mail"; 227 228 accounts = { 229 university = { 230 address = "vsureshkumar3892@floridapoly.edu"; 231 realName = "Vineet Kumar"; 232 userName = "vsureshkumar3892@floridapoly.edu"; 233 passwordCommand = "oauth2ms"; 234 235 imap.host = "outlook.office365.com"; 236 smtp = { 237 host = "smtp-mail.outlook.com"; 238 port = 587; 239 tls.useStartTls = true; 240 }; 241 242 mbsync = { 243 enable = true; 244 create = "both"; 245 expunge = "both"; 246 remove = "both"; 247 patterns = [ 248 "*" 249 "!Calendar*" 250 "!Contacts*" 251 "!Conversation*" 252 "!Notes*" 253 "!Journal*" 254 "!Tasks*" 255 ]; 256 }; 257 258 msmtp = { 259 enable = true; 260 extraConfig.auth = "xoauth2"; 261 }; 262 263 notmuch.enable = true; 264 }; 265 266 vineetk = { 267 address = "me@vineetk.net"; 268 realName = "Vineet Kumar"; 269 userName = "me@vineetk.net"; 270 passwordCommand = "kasi pass email/vineetk"; 271 primary = true; 272 273 imap.host = "mail.vineetk.net"; 274 smtp.host = "mail.vineetk.net"; 275 276 mbsync = { 277 enable = true; 278 create = "both"; 279 expunge = "both"; 280 remove = "both"; 281 patterns = [ "*" ]; 282 }; 283 284 msmtp.enable = true; 285 notmuch.enable = true; 286 }; 287 288 thirteen = { 289 address = "me@13f0.net"; 290 realName = "Kar"; 291 userName = "me@13f0.net"; 292 passwordCommand = "kasi pass email/13f0"; 293 294 imap.host = "mail.vineetk.net"; 295 smtp.host = "mail.vineetk.net"; 296 297 mbsync = { 298 enable = true; 299 create = "both"; 300 expunge = "both"; 301 remove = "both"; 302 patterns = [ "*" ]; 303 }; 304 305 msmtp.enable = true; 306 notmuch.enable = true; 307 }; 308 }; 309 }; 310 311 programs = { 312 home-manager.enable = true; 313 314 emacs = { 315 enable = true; 316 extraPackages = 317 epkgs: with epkgs; [ 318 # profile startup of init.el 319 esup 320 321 # the theme I use 322 kaolin-themes 323 324 # fuzzy searching 325 orderless 326 # better vertical completion 327 vertico 328 329 # easy to identify scopes 330 rainbow-delimiters 331 # short descriptions of commands 332 marginalia 333 # like a collection of autocomplete commands 334 consult 335 # saves pressing C-x u a lot (before I found C-/) 336 undo-tree 337 338 # highlights TODO/BUG/FIXME/etc. keywords 339 hl-todo 340 # very good git 341 magit 342 magit-todos 343 344 # better latex mode 345 auctex 346 # better pdf viewer 347 pdf-tools 348 349 # I love org-mode 350 org 351 org-pdftools 352 org-present 353 org-roam 354 355 # rss reader 356 elfeed 357 # email reader 358 notmuch 359 # better llm frontend 360 gptel 361 362 # nix stuff 363 nix-mode 364 # ocaml formatting on save 365 ocamlformat 366 # rust stuff 367 rust-mode 368 369 # better terminal emulation 370 eat 371 372 # project tree templates 373 skeletor 374 ]; 375 }; 376 377 git = { 378 enable = true; 379 settings = { 380 user = { 381 email = "git@vineetk.net"; 382 name = "vin"; 383 signingkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEvM0xCLziR+ZT/SYE1aZM6dklbw4fEC17TWqbADIZRH kou@demiurge"; 384 }; 385 sendemail = { 386 suppresscc = "self"; 387 annotate = true; 388 }; 389 format.signOff = true; 390 pull.rebase = true; 391 init.defaultBranch = "master"; 392 http = { 393 version = "HTTP/1.1"; 394 postBuffer = 524288000; 395 }; 396 commit.gpgsign = false; 397 gpg.format = "ssh"; 398 "gpg \"ssh\"".allowedSignersFile = "/home/vin/.ssh/allowed_signers"; 399 credential = { 400 helper = "kasi"; 401 "https://git.overleaf.com/".username = "git"; 402 }; 403 }; 404 ignores = [ 405 "*~" 406 ".*~" 407 "*.swp" 408 ]; 409 }; 410 411 mbsync = { 412 enable = true; 413 package = isync-oauth2; 414 }; 415 416 msmtp.enable = true; 417 418 mpv = { 419 enable = true; 420 # package = pkgs.mpv.override { 421 # archiveSupport = false; 422 # bluraySupport = false; 423 # bs2bSupport = false; 424 # cacaSupport = false; 425 # cmsSupport = false; 426 # dvdnavSupport = false; 427 # javascriptSupport = false; 428 # pipewireSupport = true; 429 # pulseSupport = false; 430 # rubberbandSupport = false; 431 # waylandSupport = false; 432 # zimgSupport = false; 433 # }; 434 435 bindings = { 436 # I wish there was a more elegant way of setting Anime4K 437 438 "Ctrl+1" = 439 "no-osd change-list glsl-shaders set '~~/shaders/Anime4K_Clamp_Highlights.glsl:~~/shaders/Anime4K_Restore_CNN_VL.glsl:~~/shaders/Anime4K_Upscale_CNN_x2_VL.glsl:~~/shaders/Anime4K_AutoDownscalePre_x2.glsl:~~/shaders/Anime4K_AutoDownscalePre_x4.glsl:~~/shaders/Anime4K_Upscale_CNN_x2_M.glsl'; show-text 'Anime4K: Mode A (HQ)'"; 440 "Ctrl+2" = 441 "no-osd change-list glsl-shaders set '~~/shaders/Anime4K_Clamp_Highlights.glsl:~~/shaders/Anime4K_Restore_CNN_Soft_VL.glsl:~~/shaders/Anime4K_Upscale_CNN_x2_VL.glsl:~~/shaders/Anime4K_AutoDownscalePre_x2.glsl:~~/shaders/Anime4K_AutoDownscalePre_x4.glsl:~~/shaders/Anime4K_Upscale_CNN_x2_M.glsl'; show-text 'Anime4K: Mode B (HQ)'"; 442 "Ctrl+3" = 443 "no-osd change-list glsl-shaders set '~~/shaders/Anime4K_Clamp_Highlights.glsl:~~/shaders/Anime4K_Upscale_Denoise_CNN_x2_VL.glsl:~~/shaders/Anime4K_AutoDownscalePre_x2.glsl:~~/shaders/Anime4K_AutoDownscalePre_x4.glsl:~~/shaders/Anime4K_Upscale_CNN_x2_M.glsl'; show-text 'Anime4K: Mode C (HQ)'"; 444 "Ctrl+4" = 445 "no-osd change-list glsl-shaders set '~~/shaders/Anime4K_Clamp_Highlights.glsl:~~/shaders/Anime4K_Restore_CNN_VL.glsl:~~/shaders/Anime4K_Upscale_CNN_x2_VL.glsl:~~/shaders/Anime4K_Restore_CNN_M.glsl:~~/shaders/Anime4K_AutoDownscalePre_x2.glsl:~~/shaders/Anime4K_AutoDownscalePre_x4.glsl:~~/shaders/Anime4K_Upscale_CNN_x2_M.glsl'; show-text 'Anime4K: Mode A+A (HQ)'"; 446 "Ctrl+5" = 447 "no-osd change-list glsl-shaders set '~~/shaders/Anime4K_Clamp_Highlights.glsl:~~/shaders/Anime4K_Restore_CNN_Soft_VL.glsl:~~/shaders/Anime4K_Upscale_CNN_x2_VL.glsl:~~/shaders/Anime4K_AutoDownscalePre_x2.glsl:~~/shaders/Anime4K_AutoDownscalePre_x4.glsl:~~/shaders/Anime4K_Restore_CNN_Soft_M.glsl:~~/shaders/Anime4K_Upscale_CNN_x2_M.glsl'; show-text 'Anime4K: Mode B+B (HQ)'"; 448 "Ctrl+6" = 449 "no-osd change-list glsl-shaders set '~~/shaders/Anime4K_Clamp_Highlights.glsl:~~/shaders/Anime4K_Upscale_Denoise_CNN_x2_VL.glsl:~~/shaders/Anime4K_AutoDownscalePre_x2.glsl:~~/shaders/Anime4K_AutoDownscalePre_x4.glsl:~~/shaders/Anime4K_Restore_CNN_M.glsl:~~/shaders/Anime4K_Upscale_CNN_x2_M.glsl'; show-text 'Anime4K: Mode C+A (HQ)'"; 450 451 "Ctrl+0" = "no-osd change-list glsl-shaders clr ''; show-text 'GLSL shaders cleared'"; 452 }; 453 454 config = { 455 # sets default shaders to Anime4K Mode A (HQ). laptop's igpu doesn't like it though 456 glsl-shaders = "~~/shaders/Anime4K_Clamp_Highlights.glsl:~~/shaders/Anime4K_Restore_CNN_VL.glsl:~~/shaders/Anime4K_Upscale_CNN_x2_VL.glsl:~~/shaders/Anime4K_AutoDownscalePre_x2.glsl:~~/shaders/Anime4K_AutoDownscalePre_x4.glsl:~~/shaders/Anime4K_Upscale_CNN_x2_M.glsl"; 457 458 ytdl-format = "bestvideo[height<=?1440]+bestaudio/best"; 459 }; 460 }; 461 462 notmuch = { 463 enable = true; 464 extraConfig.user = { 465 name = "Vineet Kumar"; 466 primary_email = "me@vineetk.net"; 467 other_email = "vineet@vineetk.net;vsureshkumar3892@floridapoly.edu;kar@13f0.net"; 468 }; 469 hooks = { 470 postNew = '' 471 notmuch tag +13f0 -- tag:unread and to:"*@13f0.net" 472 notmuch tag +vineetk -- tag:unread and to:"*@vineetk.net" 473 notmuch tag +university -- tag:unread and to:vsureshkumar3892@floridapoly.edu 474 notmuch tag +openbsd_announce -inbox -- tag:unread and to:announce@openbsd.org 475 notmuch tag +openbsd_arm -inbox -- tag:unread and to:arm@openbsd.org 476 notmuch tag +gameoftrees -inbox -- tag:unread and to:gameoftrees@openbsd.org 477 notmuch tag +openbsd_misc -inbox -- tag:unread and to:misc@openbsd.org 478 notmuch tag +openbsd_ports -inbox -- tag:unread and to:ports@openbsd.org 479 notmuch tag +openbsd_tech -inbox -- tag:unread and to:tech@openbsd.org 480 notmuch tag +opensmtpd_misc -inbox -- tag:unread and to:misc@opensmtpd.org 481 notmuch tag +oss_security -inbox -- tag:unread and to:oss-security@lists.openwall.com 482 notmuch tag +tuhs -inbox -- tag:unread and to:tuhs@tuhs.org 483 ''; 484 #preNew = "mbsync -a"; 485 }; 486 }; 487 488 qutebrowser = { 489 enable = true; 490 491 quickmarks = { 492 canvas = "https://floridapolytechnic.instructure.com"; 493 cams = "https://cams.floridapoly.org/student/login.asp"; 494 entertrained = "https://entertrained.app/"; 495 burst = "https://www.burst-type.pro/"; 496 colemakcamp = "https://colemakcamp.github.io/"; 497 colony = "https://cmdr-nowski.github.io/scuffed/#DRmd5xEUGQMOIU5nCVEG"; 498 }; 499 500 searchEngines = { 501 DEFAULT = "https://searx.demiurge.epistemia/search?q={}"; 502 ddg = "https://lite.duckduckgo.com/?q={}"; 503 nw = "https://wiki.nixos.org/index.php?search={}"; 504 aw = "https://wiki.archlinux.org/?search={}"; 505 gw = "https://wiki.gentoo.org/?search={}"; 506 }; 507 508 settings = { 509 content.javascript.enabled = false; 510 511 url = { 512 default_page = "about:blank"; 513 start_pages = [ 514 "about:blank" 515 ]; 516 }; 517 518 colors.webpage = { 519 preferred_color_scheme = "dark"; 520 darkmode = { 521 enabled = true; 522 policy.images = "never"; 523 }; 524 }; 525 526 zoom.default = "133%"; 527 }; 528 529 extraConfig = '' 530 # javascript 531 config.set('content.javascript.enabled', True, 'chrome-devtools://*') 532 config.set('content.javascript.enabled', True, 'devtools://*') 533 config.set('content.javascript.enabled', True, 'chrome://*/*') 534 config.set('content.javascript.enabled', True, 'qute://*/*') 535 536 config.set('content.javascript.enabled', True, 'floridapolytechnic.instructure.com') 537 config.set('content.javascript.enabled', True, '*.floridapoly.edu') 538 config.set('content.javascript.enabled', True, 'login.microsoftonline.com') 539 config.set('content.javascript.enabled', True, 'www.microsoft365.com') 540 config.set('content.javascript.enabled', True, 'flpoly-my.sharepoint.com') 541 config.set('content.javascript.enabled', True, 'flpoly.sharepoint.com') 542 config.set('content.javascript.enabled', True, 'teams.microsoft.com') 543 config.set('content.javascript.enabled', True, 'ieeexplore.ieee.org') 544 545 config.set('content.javascript.enabled', True, 'gitlab.com') 546 config.set('content.javascript.enabled', True, 'cloud.binary.ninja') 547 config.set('content.javascript.enabled', True, 'console.hetzner.cloud') 548 config.set('content.javascript.enabled', True, '*.hetzner.com') 549 config.set('content.javascript.enabled', True, '*.digikey.com') 550 config.set('content.javascript.enabled', True, '*.demiurge.epistemia') 551 552 # Allow locally loaded documents to access remote URLs. 553 config.set('content.local_content_can_access_remote_urls', True, 'file:///home/vin/.local/share/qutebrowser/userscripts/*') 554 config.set('content.local_content_can_access_file_urls', False, 'file:///home/vin/.local/share/qutebrowser/userscripts/*') 555 556 # disable dark mode for some sites 557 config.set('colors.webpage.darkmode.enabled', False, 'flpoly-my.sharepoint.com') 558 config.set('colors.webpage.darkmode.enabled', False, 'flpoly.sharepoint.com') 559 config.set('colors.webpage.darkmode.enabled', False, 'teams.microsoft.com') 560 561 config.set('colors.webpage.darkmode.enabled', False, 'cloud.binary.ninja') 562 config.set('colors.webpage.darkmode.enabled', False, 'git.vineetk.net') 563 564 # prevent accidental exiting 565 config.unbind("<Ctrl+q>", mode="normal") 566 567 # source theme from nixos 568 config.source("theme.py") 569 570 # source redirectors 571 config.source("redirectors.py") 572 ''; 573 }; 574 575 yt-dlp = { 576 enable = true; 577 settings = { 578 format-sort = "res:1440,vcodec:vp9,acodec:opus"; 579 embed-metadata = true; 580 embed-subs = true; 581 embed-thumbnail = true; 582 merge-output-format = "mkv"; 583 sub-langs = "en,-livechat"; 584 no-windows-filenames = true; 585 sponsorblock-remove = "sponsor,selfpromo,music_offtopic,-filler,-preview"; 586 sponsorblock-mark = "filler,preview,intro,outro"; 587 }; 588 }; 589 590 zsh = { 591 enable = true; 592 enableCompletion = true; 593 defaultKeymap = "emacs"; 594 history = { 595 ignoreDups = true; 596 ignoreSpace = true; 597 save = 1000000; # 10k is inconvenient 598 }; 599 initContent = '' 600 # auto-correct commands 601 setopt correctall 602 603 # fix meta/ctrl-backspace 604 autoload -Uz select-word-style 605 select-word-style bash 606 ''; 607 syntaxHighlighting = { 608 enable = true; 609 highlighters = [ 610 "main" 611 "brackets" 612 "pattern" 613 ]; 614 patterns = { 615 "rm -rf *" = "fg=white,bold,bg=red"; 616 }; 617 }; 618 }; 619 }; 620 621 services = { 622 # batsignal 623 # borgmatic 624 # dunst? 625 # glance? 626 # gpg-agent with ssh? 627 # mpd and ncmpcpp? 628 # pass-secret-service? 629 # plan9port for plumbing? 630 # recoll? 631 # remmina? 632 # screen-locker 633 # unison 634 635 poweralertd.enable = true; 636 637 emacs = { 638 enable = true; 639 client.enable = true; 640 startWithUserSession = true; 641 }; 642 643 redshift = { 644 enable = false; 645 dawnTime = "07:00"; 646 duskTime = "00:00"; 647 temperature.day = 6500; 648 temperature.night = 4500; 649 }; 650 651 sxhkd = { 652 enable = true; 653 keybindings = { 654 # reload sxhkd 655 "super + Escape" = "pkill -USR1 -x sxhkd"; 656 657 # BSPWM 658 # quit/restart bspwm 659 "super + alt + shift + ctrl + {e,r}" = "bspc {quit,wm -r}"; 660 # close/kill window 661 "super + shift + {q,k}" = "bspc node -{c,k}"; 662 # toggle between tiled and monocle layout 663 "super + m" = "bspc desktop -l next"; 664 # send newest marked node to newest preselected node 665 "super + y" = "bspc node newest.marked.local -n newest.!automatic.local"; 666 # swap current and biggest window 667 "super + g" = "bspc node -s biggest.window"; 668 669 # STATE/FLAGS 670 # set the window state 671 "super + {t,shift + t,s,f}" = "bspc node -t {tiled,pseudo_tiled,floating,fullscreen}"; 672 # set the node flags 673 "super + ctrl + {m,x,y,z}" = "bspc node -g {marked,locked,sticky,private}"; 674 675 # FOCUS/SWAP 676 # focus the node in the given direction 677 "super + {_,shift + }{n,e,o,i}" = "bspc node -{f,s} {west,south,north,east}"; 678 # focus the node for the given path jump 679 "super + {p,b,comma,period}" = "bspc node -f @{parent,brother,first,second}"; 680 # focus the next/previous window in the current desktop 681 "super + {_,shift + }c" = "bspc node -f {next,prev}.local.!hidden.window"; 682 # focus the next/previous desktop in the current monitor 683 "super + bracket{left,right}" = "bspc desktop -f {prev,next}.local"; 684 # focus the last node/desktop 685 "super + {grave,Tab}" = "bspc {node,desktop} -f last"; 686 # focus or send to the given desktop 687 "super + {_,shift + }{1-9,0}" = "bspc {desktop -f,node -d} '^{1-9,10}'"; 688 689 # PRESELECT 690 # preselect the direction 691 "super + ctrl + {n,e,o,i}" = "bspc node -p {west,south,north,east}"; 692 # preselect the ratio 693 "super + ctrl + {1-9}" = "bspc node -o 0.{1-9}"; 694 # cancel the preselection for the focused node 695 "super + ctrl + space" = "bspc node -p cancel"; 696 # cancel the preselection for the focused desktop 697 "super + ctrl + shift + space" = "bspc query -N -d | xargs -I id -n 1 bspc node id -p cancel"; 698 699 # MOVE/RESIZE 700 # expand a window by moving one of its side outward 701 "super + alt + {n,e,o,i}" = "bspc node -z {left -20 0,bottom 0 20,top 0 -20,right 20 0}"; 702 # contract a window by moving one of its side inward 703 "super + alt + shift + {n,e,o,i}" = "bspc node -z {right -20 0,top 0 20,bottom 0 -20,left 20 0}"; 704 # move a floating window 705 "super + {Left,Down,Up,Right}" = "bspc node -v {-20 0,0 20,0 -20,20 0}"; 706 707 # program keybinds 708 "super + Return" = "emacsclient -c"; 709 "super + shift + Return" = "qutebrowser"; 710 "super + p" = "dmenu_run"; 711 "super + shift + b" = "kasimenu"; 712 "super + shift + u" = "kasimenu user"; 713 "super + shift + t" = "kasimenu_totp"; 714 }; 715 }; 716 717 syncthing = { 718 enable = true; 719 settings = { 720 devices = { 721 demiurge = { 722 addresses = [ 723 "tcp://192.168.1.2:22000" 724 "tcp://100.64.0.2:22000" 725 ]; 726 id = "Y2XNSCK-DQYYKWZ-DCKSCH2-QWRHQJV-5RLNTZF-RX2QOKL-RZ7J67Z-HGMK2Q2"; 727 }; 728 729 hastur = { 730 addresses = [ 731 "tcp://192.168.1.3:22000" 732 "tcp://100.64.0.3:22000" 733 ]; 734 id = "ZJ55XB6-VJ62N4F-5LTRNV3-JMIFI3G-TKAI2BZ-42QAFNJ-QDMVJ6I-O7KHQQ6"; 735 }; 736 737 iphonebob = { 738 addresses = [ 739 "tcp://192.168.1.4:22000" 740 "tcp://100.64.0.4:22000" 741 ]; 742 id = "ZD43FM5-WIZLODC-PR335XA-FQBSEQK-2ZZKWG3-UHTX57B-6VDVDCX-PPNI4AD"; 743 }; 744 }; 745 746 folders = { 747 "bin" = { 748 devices = [ 749 "demiurge" 750 "hastur" 751 ]; 752 path = if hostname == "demiurge" then "/data/bin" else "/home/vin/bin"; 753 }; 754 755 "docs" = { 756 devices = [ 757 "demiurge" 758 "hastur" 759 ]; 760 path = if hostname == "demiurge" then "/data/docs" else "/home/vin/docs"; 761 }; 762 763 "emacs.d" = { 764 devices = [ 765 "demiurge" 766 "hastur" 767 ]; 768 path = "/home/vin/.emacs.d"; 769 }; 770 771 "kasi" = { 772 devices = [ 773 "demiurge" 774 "hastur" 775 ]; 776 path = if hostname == "demiurge" then "/data/kasi" else "/home/vin/.kasi"; 777 }; 778 779 "lit" = { 780 devices = [ 781 "demiurge" 782 "hastur" 783 ]; 784 path = if hostname == "demiurge" then "/data_wd/lit" else "/home/vin/lit"; 785 }; 786 787 "pics" = { 788 devices = [ 789 "demiurge" 790 "hastur" 791 ]; 792 path = if hostname == "demiurge" then "/data_wd/pics" else "/home/vin/pics"; 793 }; 794 795 "iphone" = { 796 devices = [ 797 "demiurge" 798 "hastur" 799 "iphonebob" 800 ]; 801 path = if hostname == "demiurge" then "/data_wd/iphone" else "/home/vin/iphone"; 802 }; 803 }; 804 }; 805 }; 806 }; 807 808 xdg = { 809 enable = true; 810 811 configFile = { 812 "qutebrowser/theme.py".text = '' 813 # Colors. 814 bg0 = "${colors.current.primary.background}" 815 bg1 = "${colors.current.normal.black}" 816 bg2 = "${colors.current.bright.black}" 817 fg0 = "${colors.current.primary.foreground}" 818 fg1 = "${colors.current.normal.white}" 819 red = "${colors.current.normal.red}" 820 blue = "${colors.current.normal.blue}" 821 green = "${colors.current.normal.green}" 822 yellow = "${colors.current.normal.yellow}" 823 cyan = "${colors.current.normal.cyan}" 824 magenta = "${colors.current.normal.magenta}" 825 826 # --- Applying colors --- # 827 828 # Completion menu. 829 c.colors.completion.category.bg = bg0 830 c.colors.completion.category.border.top = bg0 831 c.colors.completion.category.border.bottom = bg0 832 c.colors.completion.category.fg = fg0 833 c.colors.completion.even.bg = bg0 834 c.colors.completion.odd.bg = bg0 835 c.colors.completion.item.selected.bg = bg1 836 c.colors.completion.item.selected.border.bottom = bg1 837 c.colors.completion.item.selected.border.top = bg1 838 c.colors.completion.item.selected.fg = blue 839 c.colors.completion.item.selected.match.fg = blue 840 c.colors.completion.match.fg = red 841 c.colors.completion.odd.bg = bg0 842 c.colors.completion.scrollbar.fg = fg0 843 c.colors.completion.scrollbar.bg = bg0 844 845 # Statusline. 846 c.colors.statusbar.caret.bg = bg0 847 c.colors.statusbar.caret.fg = magenta 848 c.colors.statusbar.caret.selection.bg = bg0 849 c.colors.statusbar.caret.selection.fg = red 850 c.colors.statusbar.command.bg = bg0 851 c.colors.statusbar.command.fg = fg0 852 c.colors.statusbar.insert.bg = bg0 853 c.colors.statusbar.insert.fg = green 854 c.colors.statusbar.normal.bg = bg0 855 c.colors.statusbar.normal.fg = fg0 856 c.colors.statusbar.passthrough.bg = bg0 857 c.colors.statusbar.passthrough.fg = blue 858 c.colors.statusbar.private.bg = bg0 859 c.colors.statusbar.private.fg = fg0 860 c.colors.statusbar.progress.bg = green 861 c.colors.statusbar.url.error.fg = red 862 c.colors.statusbar.url.fg = fg0 863 c.colors.statusbar.url.hover.fg = cyan 864 c.colors.statusbar.url.success.http.fg = green 865 c.colors.statusbar.url.success.https.fg = green 866 c.colors.statusbar.url.warn.fg = yellow 867 868 # Tabline. 869 c.colors.tabs.bar.bg = bg0 870 c.colors.tabs.even.bg = bg0 871 c.colors.tabs.even.fg = fg0 872 c.colors.tabs.indicator.error = red 873 c.colors.tabs.indicator.start = blue 874 c.colors.tabs.indicator.stop = green 875 c.colors.tabs.indicator.system = "rgb" 876 c.colors.tabs.odd.bg = bg0 877 c.colors.tabs.odd.fg = fg0 878 c.colors.tabs.pinned.even.bg = bg1 879 c.colors.tabs.pinned.even.fg = fg0 880 c.colors.tabs.pinned.odd.bg = bg1 881 c.colors.tabs.pinned.odd.fg = fg0 882 c.colors.tabs.pinned.selected.even.bg = bg0 883 c.colors.tabs.pinned.selected.even.fg = green 884 c.colors.tabs.pinned.selected.odd.bg = bg0 885 c.colors.tabs.pinned.selected.odd.fg = green 886 c.colors.tabs.pinned.selected.even.bg = bg0 887 c.colors.tabs.pinned.selected.even.fg = blue 888 c.colors.tabs.selected.odd.bg = bg0 889 c.colors.tabs.selected.odd.fg = fg1 890 c.colors.tabs.selected.even.bg = bg0 891 c.colors.tabs.selected.even.fg = fg1 892 893 # Hints. 894 c.colors.hints.bg = bg1 895 c.colors.hints.fg = fg0 896 c.colors.hints.match.fg = red 897 c.hints.border = "2px solid " + bg0 898 899 # Messages. 900 c.colors.messages.error.bg = bg0 901 c.colors.messages.error.border = bg0 902 c.colors.messages.error.fg = red 903 c.colors.messages.info.bg = bg0 904 c.colors.messages.info.border = bg0 905 c.colors.messages.info.fg = blue 906 c.colors.messages.warning.bg = bg0 907 c.colors.messages.warning.border = bg0 908 c.colors.messages.warning.fg = yellow 909 910 # Download bar. 911 c.colors.downloads.bar.bg = bg0 912 c.colors.downloads.error.bg = bg1 913 c.colors.downloads.error.fg = red 914 c.colors.downloads.start.bg = bg1 915 c.colors.downloads.start.fg = blue 916 c.colors.downloads.stop.bg = bg1 917 c.colors.downloads.stop.fg = green 918 919 # Keyhints. 920 c.colors.keyhint.bg = bg0 921 c.colors.keyhint.fg = fg0 922 c.colors.keyhint.suffix.fg = yellow 923 924 # Default color for about:blank pages (or if the css didn't specify) 925 #c.colors.webpage.bg = bg0 926 927 # Context menu. 928 c.colors.contextmenu.disabled.bg = bg0 929 c.colors.contextmenu.disabled.fg = fg0 930 c.colors.contextmenu.menu.bg = bg0 931 c.colors.contextmenu.menu.fg = fg0 932 c.colors.contextmenu.selected.bg = bg1 933 c.colors.contextmenu.selected.fg = blue 934 935 # Prompts. 936 c.colors.prompts.bg = bg0 937 c.colors.prompts.border = "2px solid " + bg0 938 c.colors.prompts.fg = fg0 939 c.colors.prompts.selected.bg = bg1 940 c.colors.prompts.selected.fg = blue 941 ''; 942 943 "qutebrowser/redirectors.py".text = '' 944 # I don't remember who I took this from. probably in qutebrowser m$hub issues 945 946 import operator, re, typing 947 from urllib.parse import urljoin 948 949 from qutebrowser.api import interceptor, message 950 from PyQt6.QtCore import QUrl 951 952 def _pastebin_redir(url: QUrl) -> bool: 953 p = url.path().strip('/') 954 if p.isalnum(): 955 url.setPath(urljoin("/raw/", p)) 956 return True 957 return False 958 959 # Any return value other than a literal 'False' means we redirected 960 REDIRECT_MAP = { 961 "new.reddit.com": operator.methodcaller('setHost', 'redlib.demiurge.epistemia'), 962 "np.reddit.com": operator.methodcaller('setHost', 'redlib.demiurge.epistemia'), 963 "old.reddit.com": operator.methodcaller('setHost', 'redlib.demiurge.epistemia'), 964 "reddit.com": operator.methodcaller('setHost', 'redlib.demiurge.epistemia'), 965 "www.reddit.com": operator.methodcaller('setHost', 'redlib.demiurge.epistemia'), 966 967 "www.youtube.com": operator.methodcaller('setHost', 'invidious.demiurge.epistemia'), 968 "youtube.com": operator.methodcaller('setHost', 'invidious.demiurge.epistemia'), 969 "youtu.be": operator.methodcaller('setHost', 'invidious.demiurge.epistemia'), 970 971 "imgur.com": operator.methodcaller('setHost', 'rimgo.bloat.cat'), 972 "i.imgur.com": operator.methodcaller('setHost', 'rimgo.bloat.cat'), 973 974 # Causes an infinite loop if the paste does not exist... 975 "pastebin.com": _pastebin_redir, 976 } # type: typing.Dict[str, typing.Callable[..., typing.Optional[bool]]] 977 978 def int_fn(info: interceptor.Request): 979 """Block the given request if necessary.""" 980 if (info.resource_type != interceptor.ResourceType.main_frame or 981 info.request_url.scheme() in {"data", "blob"}): 982 return 983 url = info.request_url 984 redir = REDIRECT_MAP.get(url.host()) 985 if redir is not None and redir(url) is not False: 986 message.info("Redirecting to " + url.toString()) 987 info.redirect(url) 988 989 interceptor.register(int_fn) 990 ''; 991 }; 992 993 mimeApps = { 994 enable = true; 995 defaultApplications = { 996 "application/pdf" = [ "zathura.desktop" ]; 997 "application/xhtml+xml" = [ 998 "qutebrowser.desktop" 999 "librewolf.desktop" 1000 ]; 1001 "text/html" = [ 1002 "qutebrowser.desktop" 1003 "librewolf.desktop" 1004 ]; 1005 "text/xml" = [ 1006 "qutebrowser.desktop" 1007 "librewolf.desktop" 1008 ]; 1009 }; 1010 }; 1011 1012 userDirs = { 1013 createDirectories = false; 1014 desktop = "$HOME/"; 1015 documents = "$HOME/docs"; 1016 download = "$HOME/tmp"; 1017 music = "$HOME/music"; 1018 pictures = "$HOME/pics"; 1019 publicShare = "$HOME/"; 1020 templates = "$HOME/"; 1021 videos = "$HOME/"; 1022 }; 1023 }; 1024 1025 xsession = { 1026 enable = true; 1027 profileExtra = '' 1028 export _JAVA_AWT_WM_NONREPARENTING=1 1029 ''; 1030 windowManager.bspwm = { 1031 enable = true; 1032 monitors = { 1033 DP-4 = [ 1034 "I" 1035 "II" 1036 "III" 1037 "IV" 1038 "V" 1039 "VI" 1040 "VII" 1041 "VIII" 1042 "IX" 1043 "X" 1044 ]; 1045 eDP-1 = [ 1046 "I" 1047 "II" 1048 "III" 1049 "IV" 1050 "V" 1051 "VI" 1052 "VII" 1053 "VIII" 1054 "IX" 1055 "X" 1056 ]; 1057 }; 1058 settings = { 1059 border_width = 2; 1060 window_gap = 0; 1061 gapless_monocle = true; 1062 split_ratio = 0.52; 1063 }; 1064 startupPrograms = [ 1065 "emacsclient -r" 1066 "qutebrowser" 1067 "xwallpaper --zoom ~/pics/wp/elite_milky_way_below2.png" 1068 "xsetwacom set \"Wacom One by Wacom S Pen stylus\" MapToOutput 2304x1440+560+0" 1069 ]; 1070 }; 1071 }; 1072 }