(define-module (tw home) #:use-module (ice-9 match) #:use-module (ice-9 string-fun) #:use-module (gnu) #:use-module (gnu home services) #:use-module (gnu home services desktop) #:use-module (gnu home services mail) #:use-module (gnu home services mcron) #:use-module (gnu home services shells) #:use-module (gnu home services shepherd) #:use-module (gnu home services ssh) #:use-module (gnu packages admin) #:use-module (gnu packages aidc) #:use-module (gnu packages android) #:use-module (gnu packages backup) #:use-module (gnu packages base) #:use-module (gnu packages bittorrent) #:use-module (gnu packages calendar) #:use-module (gnu packages check) #:use-module (gnu packages chromium) #:use-module (gnu packages cmake) #:use-module (gnu packages compression) #:use-module (gnu packages compton) #:use-module (gnu packages curl) #:use-module (gnu packages databases) #:use-module (gnu packages dav) #:use-module (gnu packages disk) #:use-module (gnu packages dns) #:use-module (gnu packages elf) #:use-module (gnu packages emacs) #:use-module (gnu packages emacs-xyz) #:use-module (gnu packages file) #:use-module (gnu packages finance) #:use-module (gnu packages fonts) #:use-module (gnu packages freedesktop) #:use-module (gnu packages games) #:use-module (gnu packages gcc) #:use-module (gnu packages gimp) #:use-module (gnu packages gl) #:use-module (gnu packages gnome) #:use-module (gnu packages gnome-xyz) #:use-module (gnu packages gnupg) #:use-module (gnu packages gnuzilla) #:use-module (gnu packages graphviz) #:use-module (gnu packages haskell-apps) #:use-module (gnu packages image-viewers) #:use-module (gnu packages imagemagick) #:use-module (gnu packages inkscape) #:use-module (gnu packages less) #:use-module (gnu packages libreoffice) #:use-module (gnu packages linux) #:use-module (gnu packages lisp) #:use-module (gnu packages llvm) #:use-module (gnu packages mail) #:use-module (gnu packages maths) #:use-module (gnu packages messaging) #:use-module (gnu packages music) #:use-module (gnu packages ncdu) #:use-module (gnu packages package-management) #:use-module (gnu packages password-utils) #:use-module (gnu packages pdf) #:use-module (gnu packages pretty-print) #:use-module (gnu packages pulseaudio) #:use-module (gnu packages pv) #:use-module (gnu packages python) #:use-module (gnu packages python-build) #:use-module (gnu packages python-check) #:use-module (gnu packages python-xyz) #:use-module (gnu packages rsync) #:use-module (gnu packages shells) #:use-module (gnu packages shellutils) #:use-module (gnu packages sqlite) #:use-module (gnu packages ssh) #:use-module (gnu packages syndication) #:use-module (gnu packages tcl) #:use-module (gnu packages terminals) #:use-module (gnu packages tex) #:use-module (gnu packages textutils) #:use-module (gnu packages tls) #:use-module (gnu packages tmux) #:use-module (gnu packages tree-sitter) #:use-module (gnu packages version-control) #:use-module (gnu packages video) #:use-module (gnu packages vim) #:use-module (gnu packages web) #:use-module (gnu packages web-browsers) #:use-module (gnu packages wm) #:use-module (gnu packages xdisorg) #:use-module (gnu packages xfce) #:use-module (gnu packages xorg) #:use-module (gnu services configuration) #:use-module (guix gexp) #:use-module (guix packages) #:use-module (guix records) #:use-module ((nongnu packages game-client) #:select (steam steam-nvidia)) #:use-module ((nongnu packages messaging) #:select (zoom signal-desktop)) #:use-module ((nongnu packages nvidia) #:select (nvda nvidia-system-monitor)) #:use-module (tw gexp) #:use-module (tw packages alice) #:use-module (tw packages catppuccin) #:use-module (tw packages ci) #:use-module (tw packages games) #:use-module (tw packages mail) #:use-module (tw packages scanner) #:use-module (tw packages xorg) #:use-module (tw services restic) #:use-module (tw system) #:use-module (tw theme)) (export tw-home-configuration) (define-configuration/no-serialization tw-home-configuration (x11-desktop? (boolean #t) "Install a full desktop and development environment. This is based on X11; a Wayland environment may be provided in future.") (gaming? (boolean #f) "Install games and other packages useful for gaming?") (nvidia-driver? (boolean #f) "Adapt the X11 desktop for the proprietary NVIDIA driver?") (pim? (boolean #t) "Install Personal Information Management (PIM) software like a calendar and mail reader?")) (define (home-packages config) "Install packages I use frequently." (match-record config (x11-desktop? gaming? nvidia-driver? pim?) (append ;; Basic packages to install everywhere, including servers. (list curl diffstat dos2unix fdupes file git gnupg gnuplot graphviz hledger imagemagick jq less lesspipe ncdu net-tools openssh openssl password-store pass-otp pv python python-ipython recutils restic rsync sbcl smartmontools source-highlight tmux tree xxd zip unzip adb fastboot beets cmus get-iplayer ffmpeg atomicparsley yt-dlp ;; Install only bind-utils like dig, not the full suite. (list isc-bind "utils") ;; Ranger can do code highlighting using python-pygments and ;; image previews in kitty using python-pillow. ranger python-pygments python-pillow mediainfo python-pdftotext ;; Shell zsh zsh-autosuggestions zsh-history-substring-search zsh-syntax-highlighting zsh-completions) (cond ;; Games are installed in ~/.guix-profile instead, to make updates of the ;; home environment faster. ;; 0ad flightgear freeciv simutrans/pak128 warzone2100 widelands pioneer ((and gaming? (not nvidia-driver?)) (list steam radeontop)) ((and gaming? nvidia-driver?) ;; nvidia-system-monitor: Qt; installs "qnvsm" binary, but no .desktop file (list steam-nvidia nvidia-system-monitor)) (else '())) (if x11-desktop? (list ;; CLI tools bsd-games powertop (list git "send-email") pdsh qrencode texlive-scheme-small texlive-latexmk ;; For CV: texlive-moderncv texlive-fontawesome5 texlive-multirow texlive-arydshln texlive-libertine texlive-inconsolata texlive-newtx texlive-babel texlive-csquotes texlive-siunitx ;; For org-mode export: texlive-minted texlive-svg texlive-hyperref texlive-capt-of texlive-ulem texlive-trimspaces texlive-transparent texlive-graphics texlive-tools texlive-wrapfig texlive-amsmath texlive-amsfonts texlive-libertine texlive-newtx texlive-txfonts texlive-inconsolata ;; Work s3cmd python-alibuild python-alidistlint actionlint modules python-tox python-setuptools-scm python-mypy hashicorp-levant-bin hashicorp-nomad-bin hashicorp-consul-bin hashicorp-vault-bin hashicorp-packer-bin ansible vinagre ;; i3 and Xorg. i3 itself must be installed system-wide for gdm to pick it up. ;; acpilight is a drop-in xbacklight replacement, as xbacklight doesn't work on my system. acpilight arandr dunst gimp hsetroot inkscape icecat imv kitty libreoffice mpv polybar pulsemixer rofi rofi-calc simple-scan/airscan transmission-remote-gtk tk xdg-utils xdot xclip xcwd xdotool xdpyinfo xev xfd xfontsel xinput xkill xprop xrandr xrdb xsel xset xwininfo xfce4-screenshooter zoom zathura zathura-ps zathura-pdf-poppler ungoogled-chromium ; needed e.g. for Interrail site & DRM video dconf dconf-editor ; required for config by blueman, cozy, ... ;; gnome-keyring ; installed system-wide; see system-configuration.scm ;; geoclue ; for redshift -- installed system-wide ;; Fonts font-hermit font-inconsolata font-fira-code font-fira-sans font-libertinus ;; Base Noto doesn't include CJK, so install those separately. font-google-noto font-google-noto-sans-cjk font-google-noto-serif-cjk font-google-noto-emoji font-openmoji ; for polybar ;; Theming papirus-icon-theme catppuccin-gtk-theme catppuccin-mocha-dark-cursors ;; Games (larger games installed in ~/.guix-profile to avoid frequent huge downloads). szio-solitaire ;; Development & language servers gnu-make python-lsp-server python-yamllint shellcheck gcc binutils patchelf elfutils clang ; for clangd glibc ; for ldd ;; Supported OotB by eglot, but not packaged by guix: ;; https://github.com/mads-hartmann/bash-language-server ;; https://github.com/regen100/cmake-language-server ;; https://github.com/hrsh7th/vscode-langservers-extracted ; {html,css,json}-languageserver ;; https://github.com/golang/tools/tree/master/gopls ; maybe? ;; https://github.com/artempyanykh/marksman ; Markdown ;; https://github.com/astoff/digestif ; (La)TeX ;; https://github.com/redhat-developer/yaml-language-server ;; Needs eglot config + not packaged (from lsp-mode): ;; https://github.com/graphql/graphiql/tree/main/packages/graphql-language-service-cli#readme ;; https://github.com/haskell/haskell-language-server / https://github.com/haskell/ghcide ;; https://github.com/eclipse/lemminx ;; Emacs general emacs ; for Wayland, switch to emacs-pgtk for better fractional scaling support emacs-use-package emacs-gcmh emacs-eglot emacs-counsel emacs-counsel-dash sqlite ; emacs-counsel-dash requires the sqlite3 binary emacs-ivy ;; emacs-company emacs-company-quickhelp emacs-company-posframe emacs-corfu emacs-corfu-doc emacs-undo-tree emacs-aggressive-indent emacs-which-key emacs-smart-mode-line emacs-diminish emacs-rainbow-mode emacs-form-feed emacs-guix ;; TODO: emacs-editorconfig emacs-sly emacs-sly-macrostep emacs-org ; emacs-org-modern theme? ;; Emacs Evil emacs-evil emacs-evil-collection emacs-evil-expat ; for :reverse, :remove, :rename, :colo, :g*, ... ex commands emacs-evil-surround ;; emacs-evil-owl ; tests failing emacs-evil-args emacs-evil-numbers emacs-evil-multiedit emacs-evil-goggles emacs-evil-traces emacs-evil-commentary emacs-evil-replace-with-register emacs-evil-cleverparens emacs-evil-org emacs-evil-markdown emacs-evil-tex emacs-evil-text-object-python ;; Emacs language modes emacs-flymake-collection emacs-geiser emacs-geiser-guile emacs-sly emacs-gnuplot emacs-graphviz-dot-mode emacs-haskell-mode emacs-hcl-mode emacs-ledger-mode emacs-mmm-mode emacs-puppet-mode emacs-rec-mode emacs-web-mode emacs-yaml-mode ;; Tree sitter libraries, for Emacs' built-in X-ts-modes. tree-sitter-bash tree-sitter-c tree-sitter-cmake tree-sitter-cpp tree-sitter-css tree-sitter-dockerfile tree-sitter-javascript tree-sitter-json tree-sitter-python tree-sitter-ruby) ;; In non-graphical environments, install vim as an editor. Neovim ;; might be better, but doesn't have an equivalent to `vim-surround' ;; packaged. (list vim vim-surround)) (if pim? (list nheko signal-desktop newsboat vdirsyncer khal khard aerc lynx mutt_oauth2.py) ; lynx for HTML mail '())))) (define (zshrc config) "Extend the home ZSH service to install my custom zshrc." ;; `home-zsh-configuration's are merged, so we can extend `home-zsh-service-type'. (home-zsh-extension (zshrc (list (local-file "home/files/zshrc") (local-file "home/files/prompt.zsh"))))) (define xfce4-screenshooter.conf (mixed-text-file "xfce4-screenshooter.conf" "\ app=" imv "/bin/imv custom_action_command=none last_user= last_extension=png screenshot_dir=file:/home/timo/pictures enable_imgur_upload=false show_in_folder=false action=1 delay=0 region=3 show_mouse=0 show_border=1 ")) (define (xdg-configs config) "Configuration files that follow the XDG basedir spec." (match-record config (x11-desktop? pim?) `(;; Basic configuration files. ("htop/htoprc" ,(local-file "home/files/htoprc")) ("lesskey" ,(local-file "home/files/lesskey")) ("ranger/rc.conf" ,(local-file "home/files/ranger.conf")) ("tmux/tmux.conf" ,(local-file "home/files/tmux.conf")) ("user-dirs.locale" ,(plain-file "user-dirs.locale" "C")) ; Not sure if this is needed. Arch has it. ("user-dirs.dirs" ,(local-file "home/files/user-dirs.dirs")) ,@(if x11-desktop? `(;; Configuration files for terminal-only programs in $XDG_CONFIG_HOME. ("alibuild/disable-analytics" ; All alibuild needs is an empty file. ,(plain-file "alibuild-disable-analytics" "")) ;; Emacs is only used in graphical sessions. ("emacs/include" ,(local-file "home/files/emacs-packages" #:recursive? #t)) ("emacs/init.el" ,(local-file "home/files/emacs-init.el")) ("emacs/catppuccin-theme.el" ,catppuccin-emacs) ;; X11 environment configuration. ("X11/XCompose" ,(local-file "home/files/XCompose")) ; see also: $XCOMPOSEFILE variable ("X11/Xresources" ,(local-file "home/files/Xresources")) ;; Configuration files for GUI programs in $XDG_CONFIG_HOME. Some ;; of these may also work under Wayland, but some are X11-specific. ("dunst/dunstrc" ,(local-file "home/files/dunstrc")) ("dunst/dunstrc.d/50-catppuccin.conf" ,catppuccin-dunstrc) ("gtk-2.0/gtkrc" ,(local-file "home/files/gtk2.ini")) ("gtk-3.0/settings.ini" ,(local-file "home/files/gtk3.ini")) ("i3/config" ,(local-file "home/files/i3.conf")) ;; TODO: "kdeglobals" works for some programs (e.g. kdeconnect-app), ;; but not for others (e.g. nheko, kdeconnect-settings)... ("kdeglobals" ,catppuccin-kdeglobals) ("kitty/diff.conf" ,(combined-text-file "kitty-diff.conf" (plain-file "kitty-diff-custom.conf" "pygments_style bw\n") catppuccin-kitty-diff)) ("kitty/kitty.conf" ,(combined-text-file "kitty.conf" (local-file "home/files/kitty.conf") catppuccin-kitty)) ("mimeapps.list" ,(local-file "home/files/mimeapps.list")) ("rofi/config.rasi" ,(local-file "home/files/rofi.rasi")) ("rofi/themes/catppuccin.rasi" ,catppuccin-rofi) ("xfce4/xfce4-screenshooter" ,xfce4-screenshooter.conf) ("zathura/zathurarc" ,(local-file "home/files/zathurarc")) ("zathura/catppuccin" ,catppuccin-zathura)) '()) ,@(if pim? `(("khal/config" ,(local-file "home/files/khal.conf")) ("khard/khard.conf" ,(local-file "home/files/khard.conf")) ("aerc/accounts.conf" ,(local-file "home/files/aerc/accounts.conf")) ("aerc/aerc.conf" ,(local-file "home/files/aerc/aerc.conf")) ("aerc/binds.conf" ,(local-file "home/files/aerc/binds.conf")) ("aerc/filters" ,(local-file "home/files/aerc/filters" #:recursive? #t)) ("aerc/stylesets" ,(local-file "home/files/aerc/stylesets" #:recursive? #t)) ("newsboat/config" ,(local-file "home/files/newsboat.conf")) ("newsboat/config.catppuccin" ,catppuccin-newsboat) ("vdirsyncer/config" ,(local-file "home/files/vdirsyncer.conf"))) '())))) (define (non-xdg-configs config) "Extra configuration files and binaries that don't follow the XDG spec." (match-record config (x11-desktop?) `((".infokey" ,(local-file "home/files/infokey")) (".local/bin/python" ,(file-append python "/bin/python3")) ;; With #:recursive? #t, Guix keeps the files' permission bits, i.e. makes them executable. (".local/bin/ppscm" ,(local-file "home/files/ppscm" #:recursive? #t)) ; pretty-print scheme files ,@(if x11-desktop? `((".icons/default/index.theme" ,(local-file "home/files/cursors.ini")) ;; https://sw.kovidgoyal.net/kitty/kittens/diff/ (".local/bin/kdiff" ; show a diff ,(program-file "kdiff" #~(apply execl #$(file-append kitty "/bin/kitty") "kitty" "+kitten" "diff" (cdr (command-line))))) (".local/bin/icat" ; kitty's "catimg" equivalent ,(program-file "icat" #~(apply execl #$(file-append kitty "/bin/kitty") "kitty" "+kitten" "icat" (cdr (command-line))))) (".local/bin/screenlock" ,(program-file "screenlock" #~(begin ; Wrapper around i3lock to turn off the screen and pause notifications. (system* #$(file-append dunst "/bin/dunstctl") "set-paused" "true") (system* #$(file-append xset "/bin/xset") "dpms" "0" "0" "5") ;; We mustn't use `file-append' here, as we have to pick up the ;; setuid binary for i3lock installed by the system config. (system* "i3lock" "-nc" #$catppuccin-background-color) (system* #$(file-append xset "/bin/xset") "dpms" "600" "600" "600") (system* #$(file-append dunst "/bin/dunstctl") "set-paused" "false")))) ;; With #:recursive? #t, Guix keeps the files' permission bits, i.e. makes them executable. (".local/bin/sessionmenu" ,(local-file "home/files/sessionmenu" #:recursive? #t)) (".local/bin/passmenu" ,(local-file "home/files/passmenu" #:recursive? #t)) (".local/bin/volume" ,(local-file "home/files/volume" #:recursive? #t)) (".local/bin/alienv.guix" ,(program-file "alienv.guix" #~(begin (setenv "TERM" "xterm-256color") ; "modules" gets confused if this is unset (apply execlp "guix" "guix" "shell" "--pure" "--container" "--emulate-fhs" "--preserve=^TERM$" "bash" "util-linux" "coreutils" ; basic shell utilities (also needed by alienv) "which" "sed" "grep" "findutils" "procps" "gawk" "modules" ; alienv requirements "openssl@3" ; some packages need openssl "xz" ; XRootD needs liblzma "python-alibuild" "--" "alienv" (cdr (command-line)))))) (".local/share/applications/emacsclient.desktop" ,(local-file "home/files/emacsclient.desktop"))) ;; In non-graphical environments, set up vim as my preferred editor. `((".vim/vimrc" ,(local-file "home/files/vimrc")) (".vim/catppuccin.vim" ,catppuccin-vim)))))) (define (environment-variables config) "Configure my shell environment." (match-record config (x11-desktop?) `(;; Work at ALICE: Nomad, Consul, Vault. ;; Tokens are not defined here as they are stored in pass(1). ;; Shell aliases to use tokens are defined in zshrc. ("NOMAD_ADDR" . "https://alinomad.cern.ch:443") ("NOMAD_CACERT" . "${XDG_CONFIG_HOME}/cern-ca-bundle.crt") ("NOMAD_CLIENT_CERT" . "${XDG_CONFIG_HOME}/grid-personal-cert.pem") ("NOMAD_CLIENT_KEY" . "${XDG_CONFIG_HOME}/grid-personal-key.pem") ("CONSUL_HTTP_ADDR" . "https://aliconsul.cern.ch:443") ("CONSUL_CACERT" . "${XDG_CONFIG_HOME}/cern-ca-bundle.crt") ("CONSUL_CLIENT_CERT" . "${XDG_CONFIG_HOME}/grid-personal-cert.pem") ("CONSUL_CLIENT_KEY" . "${XDG_CONFIG_HOME}/grid-personal-key.pem") ("VAULT_ADDR" . "https://alivault.cern.ch:443") ("VAULT_CACERT" . "${XDG_CONFIG_HOME}/cern-ca-bundle.crt") ("VAULT_CLIENT_CERT" . "${XDG_CONFIG_HOME}/grid-personal-cert.pem") ("VAULT_CLIENT_KEY" . "${XDG_CONFIG_HOME}/grid-personal-key.pem") ;; Common environment everywhere. ;; Prepend my own binaries to $PATH. These should probably all ;; be managed through `home-files-service-type'. ("PATH" . "$HOME/.local/bin${PATH:+:}$PATH") ;; Default terminal-related applications (except Emacs, which is separate). ("PAGER" . "less") ;; Guix force-overrides $LESS by default, so force-force it to do what I ;; want instead. `less' reads the `lesskey' file configured above. ("GUIX_PAGER" . "env -u LESS less") ;; To make LESS_TERMCAP_* variables (set in lesskey) apply to man pages in kitty. ("GROFF_NO_SGR" . "1") ;; Shell history -- primarily for zsh, but Emacs' eshell uses this too. ("HISTSIZE" . "10000000") ("LEDGER_FILE" . "$HOME/sync/ledger/ledger.journal") ("GTAGSLABEL" . "pygments") ;; Disable at-spi-dbus-launcher accessibility service. ("NO_AT_BRIDGE" . "1") ;; Auto-compilation is annoying and creates a bunch of files that are never cleaned up. ("GUILE_AUTO_COMPILE" . "0") ;; XDG basedir spec compliance for various programs. ;; See: https://wiki.archlinux.org/index.php/XDG_Base_Directory for a list of programs. ;; The `home-xdg-base-directories' service (enabled by default) sets $XDG_* variables for us. ("ANDROID_EMULATOR_HOME" . "$XDG_DATA_HOME/android-emulator") ("ASPELL_CONF" . "per-conf $XDG_CONFIG_HOME/aspell/aspell.conf; home-dir $XDG_DATA_HOME/aspell") ("BUP_DIR" . "$XDG_DATA_HOME/bup") ("CARGO_HOME" . "$XDG_DATA_HOME/cargo") ("ELECTRUMDIR" . "$XDG_DATA_HOME/electrum") ("FG_HOME" . "$XDG_DATA_HOME/fgfs") ("GETIPLAYERUSERPREFS" . "$XDG_DATA_HOME/get_iplayer") ("GTK2_RC_FILES" . "$XDG_CONFIG_HOME/gtk-2.0/gtkrc") ("ICEAUTHORITY" . "$XDG_CACHE_HOME/ICEauthority") ("INPUTRC" . "$XDG_CONFIG_HOME/readline/inputrc") ("IPYTHONDIR" . "$XDG_CONFIG_HOME/ipython") ("JUPYTER_CONFIG_DIR" . "$XDG_CONFIG_HOME/jupyter") ;; KONAN_DATA_DIR=~/.konan by default; grows to multiple GiB. ;; https://discuss.kotlinlang.org/t/change-konan-folder-location/18309 ("KONAN_DATA_DIR" . "$XDG_CACHE_HOME/konan") ("NPM_CONFIG_USERCONFIG" . "$XDG_CONFIG_HOME/npm/npmrc") ("PASSWORD_STORE_DIR" . "$XDG_DATA_HOME/password-store") ("PYLINTHOME" . "$XDG_CACHE_HOME/pylint") ("PYLINTRC" . "$XDG_CONFIG_HOME/pylint/pylintrc") ("RECOLL_CONFDIR" . "$XDG_CONFIG_HOME/recoll") ("RLWRAP_HOME" . "$XDG_DATA_HOME/rlwrap") ("STACK_ROOT" . "$XDG_DATA_HOME/stack") ("TMUX_TMPDIR" . "$XDG_RUNTIME_DIR") ("WEECHAT_HOME" . "$XDG_CONFIG_HOME/weechat") ("XCOMPOSECACHE" . "$XDG_CACHE_HOME/X11/XCompose") ("XCOMPOSEFILE" . "$XDG_CONFIG_HOME/X11/XCompose") ("ZDOTDIR" . "$XDG_CONFIG_HOME/zsh") ("_JAVA_OPTIONS" . ;; Merge _JAVA_OPTIONS declarations since Guix warns if a variable is ;; defined twice (even if the definitions would complement each other). ,(string-append "$_JAVA_OPTIONS${_JAVA_OPTIONS:+ }-Djava.util.prefs.userRoot=$XDG_CONFIG_HOME/java" (if x11-desktop? (string-append "-Dawt.useSystemAAFontSettings=on -Dswing.aatext=true " "-Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel " "-Dswing.crossplatformlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel") ""))) ,@(if x11-desktop? `(("TERMINAL" . "kitty") ("QT_X11_NO_MITSHM" . "1") ; fixes a Steam issue: https://gitlab.com/nonguix/nonguix/-/issues/267 ("GUIX_SANDBOX_EXTRA_SHARES" . ; mount savegame locations inside Steam container ,(string-join '("$HOME/savegames/banished=$HOME/.local/share/Steam/steamapps/compatdata/242920/pfx/drive_c/users/steamuser/Documents/Banished/Save" "$HOME/savegames/planetbase=$HOME/.local/share/Steam/steamapps/compatdata/403190/pfx/drive_c/users/steamuser/Documents/Planetbase" "$HOME/savegames/cities-skylines=$HOME/.local/share/Colossal Order/Cities_Skylines/Saves" "$HOME/savegames/surviving-mars=$HOME/.local/share/Surviving Mars/76561198130982912" "$HOME/savegames/colony-survival=$HOME/.local/share/Steam/steamapps/common/Colony Survival/gamedata/savegames" "$HOME/savegames/portal=$HOME/.local/share/Steam/steamapps/common/Portal/portal/save" "$HOME/savegames/spacechem=$HOME/.local/share/Zachtronics Industries/SpaceChem/save" "$HOME/savegames/tis-100=$HOME/.local/share/TIS-100/76561198130982912") ":")) ;; Smooth trackpad scrolling in Firefox/Icecat. ;; https://wiki.archlinux.org/index.php/Firefox/Tweaks#Pixel-perfect_trackpad_scrolling ("MOZ_USE_XINPUT2" . "1") ;; Set Emacs up as my preferred editor. ("EDITOR" . "emacsclient -qc") ;; Tell emacsclient to return immediately after opening the file. I ;; can't put this in $EDITOR as many programs expect $EDITOR to exit ;; only when the user is done editing. ("ASYNC_EDITOR" . "emacsclient -qcn")) ;; In non-graphical environments, set up vim as my preferred editor. '(("EDITOR" . "vim")))))) ; we define no ASYNC_EDITOR (define (shepherd-services config) "Run various daemons in my user profile." (match-record config (x11-desktop? nvidia-driver?) (if x11-desktop? (list (shepherd-service (documentation "Emacs server; connect using emacsclient.") (provision '(emacs)) (requirement '(x11-display)) (start #~(make-forkexec-constructor (list #$(file-append emacs "/bin/emacs") "--fg-daemon"))) (stop #~(make-kill-destructor))) (shepherd-service (documentation "NetworkManager applet; provides a GUI for network connections.") (provision '(nm-applet)) (requirement '(x11-display)) (start #~(make-forkexec-constructor (list #$(file-append network-manager-applet "/bin/nm-applet")))) (stop #~(make-kill-destructor))) (shepherd-service (documentation "Dunst notification daemon; displays desktop notifications.") (provision '(dunst)) (requirement '(x11-display)) (start #~(make-forkexec-constructor (list #$(file-append dunst "/bin/dunst")))) (stop #~(make-kill-destructor))) ;; Picom needs to use the proprietary nvidia driver's libgl if that ;; driver is used for Xorg; plain Mesa won't work then. (let ((grafter (if nvidia-driver? (package-input-rewriting `((,mesa . ,(package (inherit mesa) (replacement nvda))))) identity))) (shepherd-service (documentation "Picom compositor; enables transparent windows in X.") (provision '(picom)) (requirement '(x11-display)) (start #~(make-forkexec-constructor (list #$(file-append (grafter picom) "/bin/picom") "--config" #$(local-file "home/files/picom.conf")))) (stop #~(make-kill-destructor)))) (shepherd-service (documentation "Source Xresources on login.") (provision '(xrdb)) (requirement '(x11-display)) (one-shot? #t) (start #~(lambda _ (invoke #$(file-append xrdb "/bin/xrdb") "-merge" (string-append (getenv "XDG_CONFIG_HOME") "/X11/Xresources"))))) ;; By default, xdotool gets most of "#@\|~()<>[]{} wrong. Make ;; it use the correct keymap by re-setting the same one again. (shepherd-service (documentation "Fix X keyboard map on login; passmenu needs this.") (provision '(fix-xdotool)) (requirement '(x11-display)) (one-shot? #t) (start #~(lambda _ (use-modules (ice-9 rdelim) (ice-9 regex) (ice-9 popen)) (let ((port (open-pipe* OPEN_READ #$(file-append setxkbmap "/bin/setxkbmap") "-query"))) (let loop ((line (read-line port))) (unless (eof-object? line) (let ((mtch (string-match "^layout:[[:space:]]*" line))) (if mtch (system* #$(file-append setxkbmap "/bin/setxkbmap") (match:suffix mtch)) (loop (read-line port))))))))))) '()))) (define (cron-jobs config) "Periodic jobs to keep my home directory in sync." (match-record config (pim?) (if pim? ;; To avoid popping up a password prompt every time these run, ;; gpg-agent needs a long-enough default-cache-ttl. (list #~(job "15 */4 * * *" ; every four hours at HH:15 (string-append #$(file-append vdirsyncer "/bin/vdirsyncer") " metasync")) #~(job "0,30 * * * *" ; every half hour (string-append #$(file-append vdirsyncer "/bin/vdirsyncer") " sync"))) '()))) (define-public tw-home-service-type (service-type (name 'tw-home) (description "Set up a basic, uniform home environment for my machines.") (default-value (tw-home-configuration)) (extensions (list (service-extension home-profile-service-type home-packages) (service-extension home-zsh-service-type zshrc) (service-extension home-xdg-configuration-files-service-type xdg-configs) (service-extension home-files-service-type non-xdg-configs) (service-extension home-environment-variables-service-type environment-variables) (service-extension home-mcron-service-type cron-jobs) (service-extension home-shepherd-service-type shepherd-services) ;; The dbus service doesn't seem to be added automatically. ;; Always activate it, even in non-graphical environments, because the ;; `service-extension' itself can't depend on the `tw-home-configuration'. ;; It shouldn't be too much overhead, though. (service-extension home-dbus-service-type (const #t)))))) ;;; Restic backup helpers (define-public (restic-pass-key key) (restic-password-source (type 'pass) (name key))) (define-public (restic-vin.wg-repo path) (restic-rest-repository (username "timo") (password (restic-pass-key "computers/vin/restic-server/timo")) (hostname "vin.wg") (port 8181) (path path))) ;;; OpenSSH configuration ;; Since we specify the entire `home-openssh-configuration', we cannot make ;; this a service extension. (define (wireguardify host) (string-replace-substring host ".twilken.net" ".wg")) (define (make-own-ssh-host host port) (openssh-host (name host) (port port) (user "timo"))) (export tw-openssh-configuration) (define* (tw-openssh-configuration #:key (proxy-to-cern? #t)) (let ((no-proxy (list (proxy-jump (host-name "none"))))) (home-openssh-configuration (hosts ;; Earlier rules take precedence over later ones. `(,(openssh-host (name "*.srcf.net") (user "tw466")) ;; My own machines ,@(map make-own-ssh-host (map car %ssh-ports) (map cdr %ssh-ports)) ,@(map make-own-ssh-host (map (compose wireguardify car) %ssh-ports) (map cdr %ssh-ports)) ,(openssh-host (name "*.fritz.box") (proxy (list (proxy-jump (host-name "lud.twilken.net"))))) ;; Git hosts ,(openssh-host (name "git.twilken.net") (user "git") ;; git.twilken.net is a CNAME to lud.twilken.net. (port (assoc-ref %ssh-ports "lud.twilken.net"))) ,(openssh-host (name "github.com") (user "git")) ,(openssh-host (name "ssh.github.com") (user "git")) ,(openssh-host (name "gitlab.cern.ch") (user "git") (port 7999) (proxy no-proxy)) ;; BitBucket apparently only supports ssh-rsa. ,(openssh-host (name "bitbucket.org") (user "git") (host-key-algorithms '("+ssh-rsa")) (accepted-key-types '("+ssh-rsa"))) ;; CERN stuff ,(openssh-host (name "lxtunnel.cern.ch") (proxy no-proxy) ; avoid ProxyJump loops ;; Share a single connection to lxtunnel, to speed up subsequent ;; connections to the GPN. Keep it open for a few minutes after ;; the last user connection exits, in case we need it again. (extra-content "\ ControlMaster auto ControlPath ${XDG_RUNTIME_DIR}/ssh_mux_%h_%p_%r ControlPersist 5m ")) ,(openssh-host (name "lxplus*.cern.ch") ; also catch e.g. lxplus9 (proxy no-proxy) ; no jump needed (extra-content "GSSAPIDelegateCredentials yes")) ; needed for EOS home mount ,(openssh-host (name "aiadm.cern.ch") (proxy no-proxy) ; aiadm refuses connections via lxtunnel (extra-content "GSSAPIDelegateCredentials yes")) ; needed for EOS home mount ,(openssh-host (name "cvmfs-alice.cern.ch") (extra-content "GSSAPIDelegateCredentials yes")) ; needed for EOS home mount ,(openssh-host (name "alihlt-gw-prod.cern.ch") (port 2020)) ,(openssh-host (name "alieevee-wn-*.cern.ch") (user "root") (identity-file "~/.local/share/ssh-keys/cern_id_rsa")) ,(openssh-host (name "alieevee-wn-*.cern.ch !alieevee-wn-1.cern.ch") ; avoid proxy loops (proxy (list (proxy-jump (host-name "alieevee-wn-1.cern.ch"))))) ,(openssh-host (name "epn???") (user "pdp") (proxy (list (proxy-jump (host-name "alihlt-gw-prod.cern.ch") (port 2020)))) (identity-file "~/.local/share/ssh-keys/epn_id_rsa")) ,(openssh-host (name "twilkendesktop.cern.ch") (port 22022) (forward-x11? #t) (extra-content "GSSAPIDelegateCredentials yes")) ,@(map (lambda (spec) (openssh-host (name (car spec)) (user (cdr spec)) (identity-file "~/.local/share/ssh-keys/alicern_id_rsa"))) '(("alimonitor.cern.ch" . "monalisa") ("alinsure.cern.ch" . "alibuild") ("alibuildmac*.cern.ch" . "alibuild") ("aido*osx*.cern.ch" . "alibuild") ("alibuild*.cern.ch" . "root") ("alimetal*.cern.ch" . "root") ("alissandra*.cern.ch" . "root") ("alimesos*.cern.ch" . "root") ("alientest*.cern.ch" . "root") ("aliflow*.cern.ch" . "root") ("alijenkins*.cern.ch" . "root") ("arm-builder-*" . "centos"))) ,(openssh-host (name "*.cern.ch") (user "twilken") (identity-file "~/.local/share/ssh-keys/cern_id_rsa") (proxy (if proxy-to-cern? (list (proxy-jump (host-name "lxtunnel.cern.ch"))) no-proxy)) (extra-content "\ # Kerberos authentication GSSAPIAuthentication yes GSSAPIDelegateCredentials no PreferredAuthentications gssapi-keyex,gssapi-with-mic,publickey,password,keyboard-interactive ")) ;; Default SSH key. This isn't in ~/.ssh as `home-openssh-service-type' ;; manages that and might delete keys there. ,(openssh-host (name "*") (identity-file "~/.local/share/ssh-keys/id_ed25519") ;; Remote servers probably don't know about xterm-kitty. (extra-content "SetEnv TERM=xterm-256color")))))))