├── .envrc
├── .git-crypt
├── .gitattributes
└── keys
│ └── default
│ └── 0
│ └── 0D34C387EDA03AD69B856664AFF8C0623B1CE493.gpg
├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── bin
├── colorid
├── get-vscode-extension-hash
├── hey
├── hot
├── incfilewatchers
├── loc
├── max_perf_pct
├── mouse
├── mouseon
├── myip
├── rgt
├── rm-submodule
├── search
├── snow
├── spawn
├── unmount
├── weather
├── webcam
├── wifi
└── wl
├── config
├── alacritty
│ └── alacritty.toml
├── direnv
│ └── direnvrc
├── firefox
│ └── userChrome.css
├── foot
│ └── foot.ini
├── gh
│ └── config.yml
├── gimp
│ └── menurc
├── git
│ ├── config
│ └── ignore
├── inkscape
│ └── default-template.svg
├── joshuto
│ ├── joshuto.toml
│ ├── mimetype.toml
│ └── preview_file.sh
├── kanshi
│ └── config
├── mailcap
├── ncmpcpp
│ ├── bindings
│ └── config
├── newsboat
│ └── config
├── nushell
│ ├── config.nu
│ ├── env.nu
│ └── login.nu
├── starship
│ └── starship.toml
├── sway
│ └── config
├── tmux
│ ├── config
│ ├── swap-pane.sh
│ └── tmux.conf
├── tree-sitter
│ └── config.json
├── vscode
│ ├── settings.json
│ └── tasks.json
├── waybar
│ ├── config
│ └── style.css
├── wayfire
│ └── config
└── xdg
│ └── user-dirs.dirs
├── default.nix
├── etc
└── test-screencast.py
├── flake.lock
├── flake.nix
├── hosts
├── README.org
├── iso-install
│ └── default.nix
├── personal.nix
├── vultr
│ ├── default.nix
│ └── hardware-configuration.nix
├── work
│ ├── default.nix
│ └── hardware-configuration.nix
└── xps
│ ├── default.nix
│ └── hardware-configuration.nix
├── keys
└── jake.asc
├── lib
├── attrs.nix
├── default.nix
├── generators.nix
├── makeSimpleWebApp.nix
├── modules.nix
├── nixos.nix
├── options.nix
├── paths.nix
└── secrets.nix
├── modules
├── browsers
│ ├── brave.nix
│ ├── chrome.nix
│ ├── chromium-help.nix
│ ├── default.nix
│ ├── firefox.nix
│ └── netsurf.nix
├── desktop
│ ├── README.org
│ ├── default.nix
│ ├── gnome.nix
│ ├── sway.nix
│ └── wayfire.nix
├── dev
│ ├── android.nix
│ ├── cc.nix
│ ├── clojure.nix
│ ├── lua.nix
│ ├── node.nix
│ ├── python.nix
│ └── rust.nix
├── editors
│ ├── default.nix
│ ├── emacs.nix
│ ├── tree-sitter.nix
│ ├── vim.nix
│ └── vscode.nix
├── gaming
│ └── emulators.nix
├── hardware
│ ├── audio.nix
│ ├── bluetooth.nix
│ ├── extraHosts.nix
│ ├── fs.nix
│ ├── printer.nix
│ ├── remarkable.nix
│ └── scanner.nix
├── media
│ ├── daw.nix
│ ├── documents.nix
│ ├── graphics.nix
│ ├── mpv.nix
│ ├── ncmpcpp.nix
│ ├── recording.nix
│ └── spotify.nix
├── messengers
│ ├── deltachat.nix
│ ├── discord.nix
│ ├── email.nix
│ ├── matrix.nix
│ ├── rss.nix
│ ├── signal.nix
│ ├── slack.nix
│ └── weechat.nix
├── options.nix
├── security.nix
├── services
│ ├── acme.nix
│ ├── avahi.nix
│ ├── backup.nix
│ ├── bitwarden.nix
│ ├── cal.nix
│ ├── calibre.nix
│ ├── dnsmasq.nix
│ ├── docker.nix
│ ├── gitea.nix
│ ├── jellyfin.nix
│ ├── jitsi.nix
│ ├── mailserver.nix
│ ├── matrix.nix
│ ├── nginx.nix
│ ├── ssh.nix
│ ├── syncthing.nix
│ ├── teamviewer.nix
│ └── transmission.nix
├── shell
│ ├── bitwarden.nix
│ ├── direnv.nix
│ ├── file.nix
│ ├── fish.nix
│ ├── git.nix
│ ├── gnupg.nix
│ ├── nushell.nix
│ └── tmux.nix
├── term
│ ├── alacritty.nix
│ ├── default.nix
│ └── foot.nix
├── themes
│ ├── default.nix
│ └── stilla
│ │ └── default.nix
├── vm
│ ├── lxd.nix
│ ├── qemu.nix
│ └── virtualbox.nix
├── wayland
│ ├── default.nix
│ ├── kanshi.nix
│ ├── mako.nix
│ ├── swaylock.nix
│ ├── waybar.nix
│ └── wofi.nix
└── xdg.nix
├── overlays
└── x-clipboard.nix
├── packages
└── .git-keep
├── shell.nix
└── templates
└── flake
├── .envrc
├── flake.nix
└── shell.nix
/.envrc:
--------------------------------------------------------------------------------
1 | if has nix; then
2 | use nix
3 | fi
4 |
--------------------------------------------------------------------------------
/.git-crypt/.gitattributes:
--------------------------------------------------------------------------------
1 | # Do not edit this file. To specify the files to encrypt, create your own
2 | # .gitattributes file in the directory where your files are.
3 | * !filter !diff
4 | *.gpg binary
5 |
--------------------------------------------------------------------------------
/.git-crypt/keys/default/0/0D34C387EDA03AD69B856664AFF8C0623B1CE493.gpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakeisnt/nixcfg/e9230d4f90a855a290882a6e7862c593a114cf5e/.git-crypt/keys/default/0/0D34C387EDA03AD69B856664AFF8C0623B1CE493.gpg
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | lib/secrets.nix filter=git-crypt diff=git-crypt
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | result
2 |
3 | .direnv/*
4 | !.direnv/.git-keep
5 | # lib/secrets.nix
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016-2020 Henrik Lissner.
4 | Copyright (c) 2020-2021 Jacob Chvatal.
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | "Software"), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be
15 | included in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/hlissner/doom-emacs)
2 | [](https://nixos.org)
3 |
4 | Started as a fork of [hlissner's dotfiles](https://github.com/hlissner/dotfiles), but different design decisions have been made to differentiate the two since.
5 |
6 | ## Screenshots
7 | ### Full Configuration
8 |
9 |
10 |
11 |
12 | ### Minimal Configuration
13 |
14 |
15 |
16 | Feel free to poke around. Contact me if you have any questions!
17 |
18 | ## Installation
19 |
20 | First, snag a copy of the newest version of NixOS by building it off of a previous machine from source.
21 |
22 | This configuration offers `usb`, a CLI-based live USB configuration with some nice utilities for getting started.
23 |
24 | If you'd like to use that system, load the ISO onto a USB with the following commands from an existing Nix system with Nix Flakes enabled:
25 |
26 | ``` sh
27 | nix build .#nixosConfigurations.iso-install.config.system.build.isoImage --impure
28 | sudo cp /path/to/iso/in/nix/store /dev/sda-usb-device-name
29 | sudo sync
30 | ```
31 |
32 | It's often the case that older version of Linux don't have support for utilities you want,
33 | and it's nice to have access to a graphical installer for most of the process - which none of the nightly NixOS ISOs support.
34 |
35 | Move that ISO to a flash drive (`mv path/to/firmware.iso drive-address`) and make sure to `sync` afterwards.
36 |
37 | After following the default NixOS install instructions off of that flash drive:
38 |
39 | 1. Enter a shell with the necessary dependencies.
40 |
41 | ``` sh
42 | nix-shell -p git nixFlakes
43 | ```
44 |
45 | 2. Clone this repository into the configuration folder.
46 |
47 | ``` sh
48 | chown -R nixos /mnt/boot/nixos
49 | git clone https://github.com/jakeisnt/nixcfg /mnt/boot/nixos
50 | ```
51 | 3. Generate a configuration for this machine (ensure that you've mounted swap space)
52 |
53 | ``` sh
54 | nixos-generate-config --root /mnt
55 | mv configuration.nix hosts/$HOSTNAME/default.nix
56 | mv hardware-configuration.nix hosts/$HOSTNAME/
57 | ```
58 |
59 | 4. Reference previous configurations when rewriting `default.nix` to use the desired format.
60 | Do not mess this up; make sure you give yourself things like a window manager and internet access. remember to import `../personal.nix` from `default.nix` in addition to the hardware configuration.
61 |
62 | 5. Install the configuration.
63 | ``` sh
64 |
65 | nixos-install --root /mnt --impure --flake .#$HOSTNAME
66 | ```
67 |
68 | You should be set! Reboot into the machine you've just configured.
69 | Make sure to commit to this repository with that machine's configuration.
70 |
--------------------------------------------------------------------------------
/bin/colorid:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env nix-shell
2 | #!nix-shell -i bash -p grim slurp
3 |
4 | # identify a color on ur screen by clicking on it (i think this works?)
5 | # Requires 'slurp' and 'grim' executables
6 |
7 | grim -g "$(slurp -p)" -t ppm - | convert - -format '%[pixel:p{0:0}]' txt:-
8 |
--------------------------------------------------------------------------------
/bin/get-vscode-extension-hash:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | # format:
4 | # first argument is publisher
5 | # second argument is name
6 | # third argument is version
7 |
8 | wget "https://$1.gallery.vsassets.io/_apis/public/gallery/publisher/$1/extension/$2/$3/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage"
9 |
10 | mv ./Microsoft.VisualStudio.Services.VSIXPackage "./$1-$2.zip"
11 |
12 | nix-hash --flat --base32 --type sha256 "./$1-$2.zip"
13 | rm "./$1-$2.zip"
14 |
--------------------------------------------------------------------------------
/bin/hey:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env nu
2 |
3 | # Collect garbage from the nix store
4 | def "main gc" [] {
5 | nix-collect-garbage -d
6 | }
7 |
8 | # Rebuild the NixOS system
9 | def "main rebuild" [] {
10 | sudo nixos-rebuild switch --flake /etc/nixos --option pure-eval no
11 | }
12 |
13 | # find a package with the given name. currently slow
14 | def "main find" [
15 | package_name: string # the name of the package to locate
16 | ] {
17 | nix search nixos $package_name
18 | }
19 |
20 | # TODO: support updating a flake input: https://github.com/NixOS/nix/issues/5110
21 |
22 | # Upgrade the system's NixOS flake
23 | def "main upgrade" [] {
24 | nix flake update /etc/nixos --impure
25 | main rebuild
26 | }
27 |
28 | # Look into bou.ke shell magic and `nix run`
29 |
30 | # Rebuild for and deploy to a remote server. Not sure if this works
31 | def "main deploy" [] {
32 | nix run nixpkgs#nixos-reubild -- --fast --target-host jake@isnt.online --build-host jake@isnt.online .#vultr --use-remote-sudo switch
33 | }
34 |
35 | # A cli program for interacting with the nix store
36 | def main [] {
37 | help main
38 | }
39 |
--------------------------------------------------------------------------------
/bin/hot:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # "Hot reload": Invoke a command whenenver specified file(s) change
4 | # inspired by https://stackoverflow.com/questions/42049983/bash-based-hot-reload-implementation
5 |
6 | function hot {
7 | if (( $# < 2 )); then
8 | echo 'USAGE: hot [ ... ]'
9 | echo ' will be run once when any of the files listed is changed (i.e. ls -l has its output changed)'
10 | else
11 | script=$1
12 | shift
13 | a='';
14 | while true; do
15 | b=`ls -l $*`
16 | [[ $a != $b ]] && a=$b && eval $script;
17 | sleep .5;
18 | done
19 | fi
20 | }
21 |
22 | hot $@
23 |
--------------------------------------------------------------------------------
/bin/incfilewatchers:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
3 |
--------------------------------------------------------------------------------
/bin/loc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env nu
2 |
3 | # Geolocate yourself
4 | def main [
5 | --json (-j): bool # display the data in json format (default: nushell table)
6 | ] {
7 | let curIp = (curl --silent https://ipinfo.io/ip)
8 | let locationJson = (curl --silent $'https://ipinfo.io/($curIp)')
9 | if $json {
10 | $locationJson
11 | } else {
12 | $locationJson | from json
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/bin/max_perf_pct:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Manipulate Intel P-state "max_perf_pct" sysfs parameter at runtime!
3 | #
4 | # Author: Bjørn Forsman
5 | # Source: https://github.com/bjornfor/nixos-config/blob/master/pkgs/max_perf_pct/max_perf_pct
6 |
7 | usage()
8 | {
9 | cat << EOF
10 | Manipulate Intel P-state "max_perf_pct" sysfs parameter.
11 | Usage: $progname [ num_0_to_100 | + | - ]
12 | Examples:
13 | $progname # print current value
14 | $progname num_0_to_100 # set given value
15 | $progname + # increment by $increment and print new value
16 | $progname - # decrement by $increment and print new value
17 | To reduce fan noise (and performance, of course), try "$progname 70".
18 | EOF
19 | }
20 |
21 | if [ "$UID" -eq 0 ]; then
22 | maybe_sudo=
23 | else
24 | maybe_sudo=sudo
25 | fi
26 |
27 | # Since kernel X.Y(?) we have to use powersave governor to be able to change
28 | # max_perf_pct. (Otherwise, the default governor ("performance") simply ignores
29 | # our writes to max_perf_pct.)
30 | setup()
31 | {
32 | echo powersave | $maybe_sudo tee /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor >/dev/null
33 | }
34 |
35 | set_val()
36 | {
37 | val="$1"
38 | test "$val" -lt 0 && val=0
39 | test "$val" -gt 100 && val=100
40 | setup
41 | echo "$val" | $maybe_sudo tee "$max_perf_pct" >/dev/null
42 | }
43 |
44 | print_val()
45 | {
46 | cat "$max_perf_pct"
47 | }
48 |
49 | max_perf_pct=/sys/devices/system/cpu/intel_pstate/max_perf_pct
50 | increment=5
51 | progname="$(basename "$0")"
52 |
53 | for arg in "$@"; do
54 | case "$arg" in
55 | -h|--help) usage; exit 0;;
56 | "") usage; exit 1;;
57 | esac
58 | done
59 |
60 | arg="$1"
61 | cur_val=$(cat "$max_perf_pct")
62 |
63 | case "$arg" in
64 | +) set_val $(($cur_val + $increment)); print_val;;
65 | -) set_val $(($cur_val - $increment)); print_val;;
66 | "") print_val;;
67 | *) set_val "$arg";;
68 | esac
69 |
--------------------------------------------------------------------------------
/bin/mouse:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # disable mouse
4 | swaymsg input 2362:628:PIXA3854:00_093A:0274_Mouse events disabled
5 | swaymsg input 2362:628:PIXA3854:00_093A:0274_Touchpad events disabled
6 |
--------------------------------------------------------------------------------
/bin/mouseon:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # enable mouse
4 | swaymsg input 2362:628:PIXA3854:00_093A:0274_Mouse events enabled
5 | swaymsg input 2362:628:PIXA3854:00_093A:0274_Touchpad events enabled
6 |
--------------------------------------------------------------------------------
/bin/myip:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Echos your local or WAN IP
3 |
4 | if [[ $1 == -w ]]; then
5 | wan=1
6 | shift
7 | fi
8 |
9 | if [[ -n $wan ]]; then
10 | dig +short myip.opendns.com @resolver1.opendns.com
11 | else
12 | IF=$(netstat -rn | awk '/^0.0.0.0/ {thif=substr($0,74,10); print thif;} /^default.*UG/ {thif=substr($0,65,10); print thif;}')
13 | if command -v ifconfig >/dev/null; then
14 | ifconfig ${NET_IF} | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'
15 | elif command -v ip >/dev/null; then
16 | ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/'
17 | else
18 | >&2 echo "No easy way to grab your IP"
19 | exit 1
20 | fi
21 | fi
22 |
--------------------------------------------------------------------------------
/bin/rgt:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env nix-shell
2 | #! nix-shell -p babashka -i "bb -i"
3 |
4 | ;; ripgrep for variable names!
5 |
6 | ;; if the term matches one of these patterns:
7 | ;; replicate it as the others and make lots of ripgrep requests for them
8 |
9 | ;; patterns:
10 | ;; UpperCamelCase
11 | ;; camelCaseRegular
12 | ;; kebab-case-i-think
13 | ;; snake_case_apparently
14 | ;; SCREAMING_SNAKE_CASE
15 |
16 | ;; TODO:
17 | ;; - fix recognition of some of these terms in some patterns
18 | ;; - figure out why `cmd` is hanging in all cases
19 |
20 | (ns rgt
21 | (:require [clojure.tools.cli :refer [parse-opts]]
22 | [babashka.process :as p]
23 | [clojure.core.match :refer [match]]
24 | [clojure.string :as str]
25 | [clojure.java.io :as io]))
26 |
27 | ;; --- utils ---
28 | (defn cmd
29 | "Run a command with a custom printer and sane defaults provided to the process"
30 | [args & [settings]]
31 | (let
32 | [proc (p/process args (merge {:out :inherit :err :inherit :shutdown p/destroy-tree} (or settings nil)))]
33 | (with-open [rdr (io/reader (:out proc))]
34 | (binding [*in* rdr] @proc nil))))
35 |
36 |
37 | ;; --- recognizers ---
38 | (def camel-regex #"[a-z0-9]+[A-Z0-9][a-z0-9]+")
39 | (def upper-camel-regex #"[A-Z0-9][a-z0-9]+")
40 | (def kebab-regex #"[a-z0-9][a-z0-9-]+[a-z0-9]")
41 | (def snake-regex #"[a-z0-9][a-z0-9_]+[a-z0-9]")
42 | (def screaming-snake-regex #"[A-Z0-9][A-Z0-9_]+[A-Z0-9]")
43 |
44 | ;; --- split-on patterns ---
45 | (def camel-split #"(?=[A-Z])")
46 | (def kebab-split #"-")
47 | (def snake-split #"_")
48 |
49 | ;; --- make cases ---
50 | ;; a 'term' is a seq of lowercase strings
51 | (defn make-camel [term]
52 | (str/join (cons (first term) (map str/capitalize (rest term)))))
53 |
54 | (defn make-upper-camel [term]
55 | (str/join (map str/capitalize term)))
56 |
57 | (defn make-kebab [term]
58 | (str/join "-" term))
59 |
60 | (defn make-snake [term]
61 | (str/join "_" term))
62 |
63 | (defn make-screaming-snake [term]
64 | (str/join "_" (map str/upper-case term)))
65 |
66 | ;; --- case map ---
67 | (def cases {:camel-case {:regex camel-regex :gen make-camel}
68 | :upper-camel-case {:regex upper-camel-regex :gen make-upper-camel}
69 | :kebab-case {:regex kebab-regex :gen make-kebab}
70 | :snake-case {:regex snake-regex :gen make-snake}
71 | :screaming-snake-case {:regex screaming-snake-regex :gen make-screaming-snake}})
72 |
73 | (defn str->term
74 | "Convert a variable name string into a seq of lowercase strings"
75 | [arg term-type]
76 | (map str/lower-case
77 | (str/split
78 | arg
79 | (match term-type
80 | (:or :snake-case :screaming-snake-case) snake-split
81 | (:or :camel-case :upper-camel-case) camel-split
82 | :kebab-case kebab-split))))
83 |
84 | (defn permute-term
85 | "Permute term into forms aside from the one provided to exclude"
86 | [term to-exclude]
87 | (let
88 | [rem-map (dissoc cases to-exclude)
89 | case-keys (keys rem-map)]
90 | (map
91 | (fn [case-key] ((:gen (case-key rem-map)) term))
92 | case-keys)))
93 |
94 | (defn rg
95 | "Invoke `ripgrep` with the provided argument"
96 | [arg]
97 | (println "`rg` " arg)
98 | (cmd ["rg" arg]))
99 |
100 | (defn search-all-but
101 | "Search all terms but the term configured to be excluded."
102 | [arg term-type]
103 | (let
104 | [term-str (str->term arg term-type)
105 | permuted-term (permute-term term-str term-type)]
106 | (println "Invoking rg for the terms " permuted-term)
107 | (map rg permuted-term)))
108 |
109 | (defn main [args]
110 | (let
111 | [arg (str/join #" " args)]
112 | (cond
113 | (re-matches camel-regex arg) (search-all-but arg :camel-case)
114 | (re-matches upper-camel-regex arg) (search-all-but arg :upper-camel-case)
115 | (re-matches kebab-regex arg) (search-all-but arg :kebab-case)
116 | (re-matches snake-regex arg) (search-all-but arg :snake-case)
117 | (re-matches screaming-snake-regex arg) (search-all-but arg :screaming-snake-case)
118 | ;; fall back to a trivial ripgrep search with everything to search for
119 | :else (do
120 | (println "Term not recognized; falling back to trivial ripgrep search")
121 | (rg arg)))))
122 |
123 | (main *command-line-args*)
124 |
125 | ;; vi: ft=clojure
126 |
--------------------------------------------------------------------------------
/bin/rm-submodule:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | # assume running from home directory and submodule name is $1
4 | # also assume that git is installed
5 |
6 | # i hope you don't have anything named "active =" in your .git/config..."
7 |
8 | # remove the submodule from gitmodules
9 | sed -i '/'$1'/d' .gitmodules
10 |
11 | git add .gitmodules
12 |
13 | # remove from .git/config
14 | sed -i '/'$1'/d' .git/config
15 | # this could be dangerous!!!! be careful.
16 | sed -i '/active = /d' .git/config
17 |
18 | # remove from cached
19 | git rm --cached $1/
20 |
21 | echo "Committing removal of submodule "$1
22 | git commit -m "Removed submodule "$1
23 |
24 | rm -rf $1/
25 |
--------------------------------------------------------------------------------
/bin/search:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | # If a query is provided, search duckduckgo for that query.
4 | # If not, visit the duckduckgo website.
5 |
6 | # In the future support more options for searches;
7 | # passing the flag '-p' followed with the platform name or an abbreviation
8 | # (arguments 1 and 2) should make the third argument come up with the search.
9 |
10 | set -e
11 |
12 | firefox https://duckduckgo.com/$1
13 |
--------------------------------------------------------------------------------
/bin/snow:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # https://gist.github.com/sontek/1505483
4 | LINES=$(tput lines)
5 | COLUMNS=$(tput cols)
6 |
7 | declare -A snowflakes
8 | declare -A lastflakes
9 |
10 | clear
11 |
12 | function move_flake() {
13 | i="$1"
14 |
15 | if [ "${snowflakes[$i]}" = "" ] || [ "${snowflakes[$i]}" = "$LINES" ]; then
16 | snowflakes[$i]=0
17 | else
18 | if [ "${lastflakes[$i]}" != "" ]; then
19 | printf "\033[%s;%sH \033[1;1H " ${lastflakes[$i]} $i
20 | fi
21 | fi
22 |
23 | printf "\033[%s;%sH\u274$[($RANDOM%6)+3]\033[1;1H" ${snowflakes[$i]} $i
24 |
25 | lastflakes[$i]=${snowflakes[$i]}
26 | snowflakes[$i]=$((${snowflakes[$i]}+1))
27 | }
28 |
29 | while :
30 | do
31 | i=$(($RANDOM % $COLUMNS))
32 |
33 | move_flake $i
34 |
35 | for x in "${!lastflakes[@]}"
36 | do
37 | move_flake "$x"
38 | done
39 |
40 | sleep 0.1
41 | done
42 |
--------------------------------------------------------------------------------
/bin/spawn:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # TODO: support working directory flag
3 | # TODO: run command to make sure it's valid? then run in another terminal?
4 | alacritty --hold -e bash -c "$@" & disown
5 |
--------------------------------------------------------------------------------
/bin/unmount:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # unmount sd card, assuming it's mounted at this point
4 | umount /run/media/jake/disk
5 |
--------------------------------------------------------------------------------
/bin/weather:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env nu
2 |
3 | def "main commit" [] {
4 | echo $"*\n\n(weather)\n\ntemperature:(weather --simple)" | git commit -F -
5 | }
6 |
7 | def main [
8 | -l --location: string # the location to search for
9 | -s --simple: bool # just the temperature
10 | ] {
11 | if ($location != '') {
12 | if ($simple) {
13 | (curl -s $"wttr.in/($location)?format=1")
14 | } else {
15 | (curl -s $"wttr.in/($location)") | head -7 | tail -7
16 | }
17 | } else {
18 | if ($simple) {
19 | (curl -s "wttr.in/?format=1")
20 | } else {
21 |
22 | (curl -s "wttr.in") | head -7 | tail -7
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/bin/webcam:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env nix-shell
2 | #!nix-shell -i bash -p gphoto2 ffmpeg
3 |
4 | # use a DSLR as a webcam via USB
5 | gphoto2 --stdout --capture-movie | ffmpeg -i - -vf format=yuv420p -f v4l2 /dev/video8
6 | # -threads 0
7 | # make sure the camera is plugged into your device and has a consistent power source (the USB bus may not be enough)
8 |
9 | # if having issues:
10 | # - make sure that the camera has adequete power - USB bus power might not be enough
11 | # run gphoto2 --auto-detect to make sure that your camera can be seen. can retrieve logs with another gphoto2 tag as well
12 | #
13 | # streaming setup:
14 | # - obs studio
15 | # - install ffplay with ffmpeg-full package
16 | # - start this script
17 | # - start ffplay at /dev/video8 to pick up rawvideo off fuji and have separate window
18 | #
19 | # join twitch chat with irc:
20 | # - open weechat window, /connect twitch, /join #jakeissnt
21 |
--------------------------------------------------------------------------------
/bin/wifi:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env nix-shell
2 | #! nix-shell -p ruby rubyPackages.thor captive-browser -i "ruby"
3 |
4 | # TODO: better integrate nushell tables with fzf: https://github.com/nushell/nushell/issues/5785
5 | # really i want a command where i can say
6 | # x list | x parse | fzf | x action
7 | # for any x program that can both list options and select one of them.
8 | # the `wl` script does this pretty well in the meantime!
9 |
10 | # Easy-to-use wrapper CLI script for wifi.
11 | # Ideally this uses a nushell-compatible interface : )
12 | # TODO: `captive-browser` doesn't work, and either needs to be configured or re-coded.
13 |
14 | require 'bundler/inline'
15 |
16 | gemfile do
17 | source 'https://rubygems.org'
18 | gem 'cli-ui'
19 | end
20 |
21 | require 'cli/ui'
22 |
23 | # Redirect STDOUT to /dev/null to run the command.
24 | def quiet
25 | old_stdout = $stdout.dup
26 | $stdout = File.new( '/dev/null', 'w' )
27 | yield
28 | ensure
29 | $stdout = STDOUT
30 | end
31 |
32 | # Attempt to establish a wifi connection with the provided network
33 | def connect_to_wifi(network)
34 | puts `nmcli device wifi connect #{network} --ask`
35 |
36 | # TODO: Check if the network has a captive portal with `captive-browser`.
37 | quiet { `captive-browser` }
38 | if $?.exitstatus != 0
39 | puts "No captive portal detected. You should be good."
40 | else
41 | puts "Captive portal detected. Browser should have opened."
42 | end
43 | end
44 |
45 |
46 | require 'thor'
47 |
48 | class WifiCLI < Thor
49 | class_option :verbose, :type => :boolean, :aliases => "-v"
50 |
51 | # TODO: Display an interactive list of networks to connect to.
52 | # Update the list as more networks become available.
53 | # Pressing 'enter' on a network should connect to it, effectively running `connect ...`.
54 | desc "pick", "Pick and connect to a wifi network"
55 | def list
56 | networks = `nmcli device wifi list`.split("\n")[1..].map { |line| # remove current networks
57 | v = line.split(" ").filter { |x| x != "Mbit/s" }
58 | if v[0] == "*"
59 | v = v[1..]
60 | end
61 |
62 | Hash[[:bssid, :ssid, :mode, :chan, :rate, :signal, :bars, :security].zip(v)]
63 | }.filter { |v| v[:ssid] != "--" } # ensure there are no blank networks
64 |
65 |
66 | if networks.length > 0
67 | CLI::UI.ask('Pick a network to connect to') do |handler|
68 | networks.each do |network|
69 | handler.option([network[:ssid], network[:rate] + " Mbit/s", network[:signal], network[:bars]].join(" ")) { connect_to_wifi(network[1]) }
70 | end
71 | end
72 | else
73 | puts 'No wifi networks available. Sorry!'
74 | end
75 | end
76 |
77 | # Connect to a wifi network, prompting for a password if necessary.
78 | # If a wifi network has a portal, this should open the portal in a browser.
79 | desc "connect NETWORK", "Connect to the specified network"
80 | def connect(network)
81 | connect_to_wifi(network)
82 | end
83 |
84 | # Restart the wifi system. Not sure if this is the best way to approach it or solve slow wifi issues.
85 | desc "reset", "Reset the wifi connection"
86 | def reset
87 | puts `systemctl restart NetworkManager`
88 | end
89 |
90 | # List all of the currently connected wifi devices.
91 | desc "devices", "List all available wifi devices"
92 | def devices
93 | puts `nmcli device`
94 | end
95 |
96 | # List all of the currently connected wifi devices.
97 | desc "hotspot", "Create a wifi hotspot connection"
98 | def devices
99 | puts `nmcli device wifi hotspot`
100 | end
101 |
102 | no_commands {
103 | def exit_on_failure?
104 | true
105 | end
106 | }
107 | end
108 |
109 | WifiCLI.start(ARGV)
110 |
111 | # NOTE: `nmcli device wifi list | lines | str replace 'Mbit\/s' '' | str trim -r | str replace -a '\s+' ',' | split column "," | headers`
112 | # ^ is the command in nushell to get the wifi list as a table. Not sure how to make it interactive!
113 | #
114 | # IDEA: nushell wifi list ->
115 |
116 | # vi: ft=ruby
117 |
--------------------------------------------------------------------------------
/bin/wl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | nmcli device wifi rescan > /dev/null
4 | ssid=$(nmcli device wifi list | tail -n +2 | grep -v '^ *\B--\B' | fzf -m | sed 's/^ *\*//' | awk '{print $1}')
5 |
6 | if [ "x$ssid" != "x" ]; then
7 | # check if the SSID has already a connection setup
8 | conn=$(nmcli con | grep "$ssid" | awk '{print $1}' | uniq)
9 | if [ "x$conn" = "x$ssid" ]; then
10 | echo "Please wait while switching to known network $ssid…"
11 | # if yes, bring up that connection
12 | nmcli con up id "$conn"
13 | else
14 | echo "Please wait while connecting to new network $ssid…"
15 | # if not connect to it and ask for the password
16 | nmcli device wifi connect "$ssid"
17 | fi
18 | fi
19 |
--------------------------------------------------------------------------------
/config/alacritty/alacritty.toml:
--------------------------------------------------------------------------------
1 | [colors]
2 | draw_bold_text_with_bright_colors = false
3 |
4 | [colors.bright]
5 | black = "#4C566A"
6 | blue = "#ADB2BA"
7 | cyan = "#8FBCBB"
8 | green = "#A19C9A"
9 | magenta = "#CD96B3"
10 | red = "#BA8082"
11 | white = "#FAF5EF"
12 | yellow = "#E9B872"
13 |
14 | [colors.cursor]
15 | cursor = "#F2F2F2"
16 | text = "#0D0D0D"
17 |
18 | [colors.dim]
19 | black = "#373e4d"
20 | blue = "#68809a"
21 | cyan = "#6d96a5"
22 | green = "#809575"
23 | magenta = "#8c738c"
24 | red = "#94545d"
25 | white = "#aeb3bb"
26 | yellow = "#b29e75"
27 |
28 | [colors.normal]
29 | black = "#121414"
30 | blue = "#ADB2BA"
31 | cyan = "#88B6D0"
32 | green = "#A19C9A"
33 | magenta = "#CD96B3"
34 | red = "#BA8082"
35 | white = "#FAFAFA"
36 | yellow = "#E9B872"
37 |
38 | [colors.primary]
39 | background = "#0D0D0D"
40 | dim_foreground = "#4C566A"
41 | foreground = "#F2F2F2"
42 |
43 | [colors.search.matches]
44 | background = "#88B6D0"
45 | foreground = "CellBackground"
46 |
47 | [colors.selection]
48 | background = "#4C566A"
49 | text = "CellForeground"
50 |
51 | [colors.vi_mode_cursor]
52 | cursor = "#F2F2F2"
53 | text = "#0D0D0D"
54 |
55 | [cursor]
56 | style = "Block"
57 | unfocused_hollow = true
58 |
59 | [scrolling]
60 | history = 100000
61 | multiplier = 3
62 |
63 | [selection]
64 | save_to_clipboard = false
65 | semantic_escape_chars = ",│`|:\"' ()[]{}<>\t"
66 |
67 | [window]
68 | decorations = "full"
69 | dynamic_padding = false
70 | opacity = 1
71 | title = "Alacritty"
72 |
73 | [window.dimensions]
74 | columns = 0
75 | lines = 0
76 |
77 | [window.padding]
78 | x = 11
79 | y = 10
80 |
--------------------------------------------------------------------------------
/config/direnv/direnvrc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakeisnt/nixcfg/e9230d4f90a855a290882a6e7862c593a114cf5e/config/direnv/direnvrc
--------------------------------------------------------------------------------
/config/firefox/userChrome.css:
--------------------------------------------------------------------------------
1 | /* @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); */
2 |
3 | @-moz-document url(chrome://browser/content/browser.xul),
4 | url(chrome://browser/content/browser.xhtml)
5 | {
6 | /*** TAB BAR ***/
7 | /* Ensure tab doesn't show through auto-completion popup */
8 | .tabbrowser-tab { z-index: 0 !important; }
9 | /* Ensure tab "spacers" don't show through the completion window */
10 | #tabbrowser-arrowscrollbox > spacer { z-index: -1 !important; }
11 | #mainPopupSet { z-index: 9999 !important; }
12 |
13 | /* Hide tabbar if only one tab */
14 | @import url(./css/tabs-hide-if-only-one.css);
15 |
16 | /* Remove the colored overline on the focused tab */
17 | .tabbrowser-tab .tab-line { background: none !important; }
18 |
19 | /* Replace favicon on tabs with close button on mouse hover */
20 | .tabbrowser-tab:not(:hover) .tab-close-button,
21 | .tabbrowser-tab:not([pinned]):hover .tab-icon-image { display: none !important; }
22 | .tabbrowser-tab:not([pinned]):hover .tab-close-button { display:block !important; }
23 |
24 | .tabbrowser-tab:hover .tab-throbber,
25 | .tabbrowser-tab:hover .tab-icon-image,
26 | .tabbrowser-tab:hover .tab-sharing-icon-overlay,
27 | .tabbrowser-tab:hover .tab-icon-overlay,
28 | .tabbrowser-tab:hover .tab-label-container,
29 | .tabbrowser-tab:hover .tab-icon-sound {
30 | -moz-box-ordinal-group: 2 !important;
31 | }
32 |
33 | .tabbrowser-tab .tab-close-button {
34 | margin-left: -2px !important;
35 | margin-right: 4px !important;
36 | }
37 |
38 | .tab-close-button:hover {
39 | fill-opacity: 0 !important;
40 | }
41 |
42 | .tabbrowser-tab::after,
43 | .tabbrowser-tab::before {
44 | border-left: none !important;
45 | border-right: none !important;
46 | }
47 |
48 | .scrollbutton-up[orient="horizontal"]~spacer { border-width: 0px; opacity: 0 }
49 |
50 | scrollbar {
51 | -moz-appearance: none !important;
52 | display: none !important;
53 | }
54 |
55 | /*** NAV BAR ***/
56 | /* Hide urlbar */
57 | #nav-bar {
58 | position: relative !important;
59 | z-index: 2 !important;
60 | height: 2px !important;
61 | min-height: 2px !important;
62 | margin-bottom: -2px !important;
63 | opacity: 0 !important;
64 | border: none !important;
65 | }
66 |
67 | /* But unfocus it when we invoke it with ctrl+L */
68 | #nav-bar:focus-within {
69 | height: auto !important;
70 | margin-bottom: 0px !important;
71 | opacity: 1 !important;
72 | overflow: show !important;
73 | }
74 |
75 | #urlbar-container {
76 | min-height: 0 !important;
77 | }
78 |
79 | #urlbar {
80 | top: 0 !important;
81 | }
82 |
83 | #urlbar-input-container {
84 | height: 28px !important;
85 | }
86 |
87 | .tab-background {
88 | border-radius: 0px !important;
89 | margin-block: 1px 0 !important;
90 | }
91 |
92 | /*** Load local overrides ***/
93 | @import url(./userChrome.local.css);
94 | }
95 |
--------------------------------------------------------------------------------
/config/foot/foot.ini:
--------------------------------------------------------------------------------
1 | # -*- conf -*-
2 |
3 | # shell=$SHELL (if set, otherwise user's default shell from /etc/passwd)
4 | # term=foot (or xterm-256color if built with -Dterminfo=disabled)
5 | # login-shell=no
6 |
7 | # app-id=foot # globally set wayland app-id. Default values are "foot" and "footclient" for desktop and server mode
8 | # title=foot
9 | # locked-title=no
10 |
11 | font=Berkeley Mono:size=11
12 | # font-bold=
13 | # font-italic=
14 | # font-bold-italic=
15 | # font-size-adjustment=0.5
16 | # line-height=
17 | # letter-spacing=0
18 | # horizontal-letter-offset=0
19 | # vertical-letter-offset=0
20 | # underline-offset=
21 | # underline-thickness=
22 | # box-drawings-uses-font-glyphs=no
23 | # dpi-aware=auto
24 |
25 | # initial-window-size-pixels=700x500 # Or,
26 | # initial-window-size-chars=
27 | # initial-window-mode=windowed
28 | pad=10x10 # optionally append 'center'
29 | # resize-delay-ms=100
30 |
31 | # notify=notify-send -a ${app-id} -i ${app-id} ${title} ${body}
32 |
33 | # bold-text-in-bright=no
34 | # word-delimiters=,│`|:"'()[]{}<>
35 | # selection-target=primary
36 | # workers=
37 | # utmp-helper=/usr/lib/utempter/utempter # When utmp backend is ‘libutempter’ (Linux)
38 | # utmp-helper=/usr/libexec/ulog-helper # When utmp backend is ‘ulog’ (FreeBSD)
39 |
40 | [environment]
41 | # name=value
42 |
43 | [bell]
44 | # urgent=no
45 | # notify=no
46 | # command=
47 | # command-focused=no
48 |
49 | [scrollback]
50 | # lines=1000
51 | # multiplier=3.0
52 | # indicator-position=relative
53 | # indicator-format=""
54 |
55 | [url]
56 | # launch=xdg-open ${url}
57 | # label-letters=sadfjklewcmpgh
58 | # osc8-underline=url-mode
59 | # protocols=http, https, ftp, ftps, file, gemini, gopher
60 | # uri-characters=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.,~:;/?#@!$&%*+="'()[]
61 |
62 | [cursor]
63 | # style=block
64 | # color=
65 | # blink=no
66 | # beam-thickness=1.5
67 | # underline-thickness=
68 |
69 | [mouse]
70 | # hide-when-typing=no
71 | # alternate-scroll-mode=yes
72 |
73 | [csd]
74 | # preferred=server
75 | # size=26
76 | # font=
77 | # color=
78 | # hide-when-typing=no
79 | # border-width=0
80 | # border-color=
81 | # button-width=26
82 | # button-color=
83 | # button-minimize-color=
84 | # button-maximize-color=
85 | # button-close-color=
86 |
87 | [key-bindings]
88 | # scrollback-up-page=Shift+Page_Up
89 | # scrollback-up-half-page=none
90 | # scrollback-up-line=none
91 | # scrollback-down-page=Shift+Page_Down
92 | # scrollback-down-half-page=none
93 | # scrollback-down-line=none
94 | # clipboard-copy=Control+Shift+c XF86Copy
95 | # clipboard-paste=Control+Shift+v XF86Paste
96 | # primary-paste=Shift+Insert
97 | # search-start=Control+Shift+r
98 | # font-increase=Control+plus Control+equal Control+KP_Add
99 | # font-decrease=Control+minus Control+KP_Subtract
100 | # font-reset=Control+0 Control+KP_0
101 | # spawn-terminal=Control+Shift+n
102 | # minimize=none
103 | # maximize=none
104 | # fullscreen=none
105 | # pipe-visible=[sh -c "xurls | fuzzel | xargs -r firefox"] none
106 | # pipe-scrollback=[sh -c "xurls | fuzzel | xargs -r firefox"] none
107 | # pipe-selected=[xargs -r firefox] none
108 | # show-urls-launch=Control+Shift+u
109 | # show-urls-copy=none
110 | # show-urls-persistent=none
111 | # prompt-prev=Control+Shift+z
112 | # prompt-next=Control+Shift+x
113 | # unicode-input=none
114 | # noop=none
115 |
116 | [search-bindings]
117 | # cancel=Control+g Control+c Escape
118 | # commit=Return
119 | # find-prev=Control+r
120 | # find-next=Control+s
121 | # cursor-left=Left Control+b
122 | # cursor-left-word=Control+Left Mod1+b
123 | # cursor-right=Right Control+f
124 | # cursor-right-word=Control+Right Mod1+f
125 | # cursor-home=Home Control+a
126 | # cursor-end=End Control+e
127 | # delete-prev=BackSpace
128 | # delete-prev-word=Mod1+BackSpace Control+BackSpace
129 | # delete-next=Delete
130 | # delete-next-word=Mod1+d Control+Delete
131 | # extend-to-word-boundary=Control+w
132 | # extend-to-next-whitespace=Control+Shift+w
133 | # clipboard-paste=Control+v Control+Shift+v Control+y XF86Paste
134 | # primary-paste=Shift+Insert
135 | # unicode-input=none
136 |
137 | [url-bindings]
138 | # cancel=Control+g Control+c Control+d Escape
139 | # toggle-url-visible=t
140 |
141 | [text-bindings]
142 | # \x03=Mod4+c # Map Super+c -> Ctrl+c
143 |
144 | [mouse-bindings]
145 | # selection-override-modifiers=Shift
146 | # primary-paste=BTN_MIDDLE
147 | # select-begin=BTN_LEFT
148 | # select-begin-block=Control+BTN_LEFT
149 | # select-extend=BTN_RIGHT
150 | # select-extend-character-wise=Control+BTN_RIGHT
151 | # select-word=BTN_LEFT-2
152 | # select-word-whitespace=Control+BTN_LEFT-2
153 | # select-row=BTN_LEFT-3
154 |
155 | # vim: ft=dosini
156 |
--------------------------------------------------------------------------------
/config/gh/config.yml:
--------------------------------------------------------------------------------
1 | # What protocol to use when performing git operations. Supported values: ssh, https
2 | git_protocol: https
3 | # What editor gh should run when creating issues, pull requests, etc. If blank, will refer to environment.
4 | editor:
5 | # When to interactively prompt. This is a global config that cannot be overridden by hostname. Supported values: enabled, disabled
6 | prompt: enabled
7 | # A pager program to send command output to, e.g. "less". Set the value to "cat" to disable the pager.
8 | pager:
9 | # Aliases allow you to create nicknames for gh commands
10 | aliases:
11 | co: pr checkout
12 |
--------------------------------------------------------------------------------
/config/git/config:
--------------------------------------------------------------------------------
1 | [user]
2 | name = Jacob Chvatal
3 | email = jake@isnt.online
4 | signingkey = 1EB278CFEE0A2F49
5 | [gpg]
6 | program = gpg2
7 | [commit]
8 | gpgsign = true
9 | [init]
10 | defaultBranch = main
11 | [core]
12 | whitespace = trailing-space
13 | pager = delta
14 | [pager]
15 | difftool = true
16 | [interactive]
17 | diffFilter = delta --color-only
18 | [delta]
19 | features = side-by-side line-numbers
20 | hunk-header-style = omit
21 | whitespace-error-style = blue purple
22 | [github]
23 | user = jakeisnt
24 | [gitlab]
25 | user = jakeisnt
26 | [rebase]
27 | autosquash = true
28 | [pull]
29 | rebase = true
30 | [push]
31 | default = current
32 | [alias]
33 | amend = commit --amend
34 | exec = "!exec "
35 | lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --
36 | ls = ls-files
37 | orphan = checkout --orphan
38 | unadd = reset HEAD
39 | undo-commit = reset --soft "HEAD^"
40 | rm-submodule = rm-submodule # this should really be git only
41 | # data analysis
42 | ranked-authors = !git authors | sort | uniq -c | sort -n
43 | emails = !git log --format="%aE" | sort -u
44 | email-domains = !git log --format="%aE" | awk -F'@' '{print $2}' | sort -u
45 | count-lines = !git ls-files | xargs wc -l
46 | # fzf-based rebase
47 | # frbi = "!f() { git rebase -i $(git log --pretty=oneline --color=always) | fzf --ansi | cut -d ' ' -f1; }; f"
48 | [diff]
49 | tool = difftastic
50 | colorMoved = default
51 |
52 | [difftool]
53 | prompt = false
54 | [difftool "difftastic"]
55 | cmd = difft "$LOCAL" "$REMOTE"
56 |
57 | [filter "lfs"]
58 | required = true
59 | smudge = git-lfs smudge -- %f
60 | process = git-lfs filter-process
61 | clean = git-lfs clean -- %f
62 | [sendemail]
63 | smtpserver = mail.isnt.online
64 | smtpencryption = tls
65 | smtpserverport= 587
66 | smtpuser = jake@isnt.online
67 | [transfer]
68 | fsckObjects = true
69 | [fetch]
70 | fsckObjects = true
71 | [receive]
72 | fsckObjects = true
73 | [url "https://github.com/"]
74 | insteadOf = gh:
75 | [url "git@github.com:jakeisnt/"]
76 | insteadOf = gh:/
77 | [url "https://gitlab.com/"]
78 | insteadOf = gl:
79 | [url "https://gist.github.com/"]
80 | insteadOf = gist:
81 | [url "https://bitbucket.org/"]
82 | insteadOf = bb:
83 | [url "https://git.v0.com"]
84 | insteadOf = v0:
85 |
--------------------------------------------------------------------------------
/config/git/ignore:
--------------------------------------------------------------------------------
1 | # For emacs:
2 | *~
3 | *.*~
4 | \#*
5 | .\#*
6 |
7 | # For vim:
8 | *.swp
9 | .*.sw[a-z]
10 | *.un~
11 | Session.vim
12 | .netrwhist
13 |
14 | # Ignore tags (from etags and ctags)
15 | TAGS
16 | !TAGS/
17 | tags
18 | !tags/
19 |
20 | # Logs and databases #
21 | ######################
22 | *.log
23 | *.cache
24 |
25 | # OS generated files #
26 | ######################
27 | .DS_Store?
28 | .DS_Store
29 | .CFUserTextEncoding
30 | .Trash
31 | .Xauthority
32 | thumbs.db
33 | Icon?
34 | Thumbs.db
35 | .cache
36 | .pid
37 | .sock
38 |
39 | # Code stuffs #
40 | ###############
41 | .svn
42 | .git
43 | .swp
44 | .idea
45 | .*.swp
46 | *~
47 | .tags
48 | tags
49 | .sass-cache
50 | tmp
51 | .codekit-cache
52 | config.codekit
53 |
54 | # Compiled thangs #
55 | ###################
56 | *.class
57 | *.exe
58 | *.o
59 | *.so
60 | *.dll
61 | *.pyc
62 |
--------------------------------------------------------------------------------
/config/inkscape/default-template.svg:
--------------------------------------------------------------------------------
1 |
2 |
76 |
--------------------------------------------------------------------------------
/config/joshuto/joshuto.toml:
--------------------------------------------------------------------------------
1 | numbered_command = false
2 |
3 | use_trash = true
4 | watch_files = true
5 | xdg_open = false
6 | xdg_open_fork = false
7 |
8 |
9 | [display]
10 | # default, hsplit
11 | mode = "default"
12 |
13 | automatically_count_files = false
14 | collapse_preview = true
15 | # ratios for parent view (optional), current view and preview
16 | column_ratio = [1, 4, 4]
17 | scroll_offset = 6
18 | show_borders = true
19 | show_hidden = false
20 | show_icons = true
21 | tilde_in_titlebar = true
22 | # none, absolute, relative
23 | line_number_style = "none"
24 |
25 | [display.sort]
26 | # lexical, mtime, natural
27 | method = "natural"
28 | case_sensitive = false
29 | directories_first = true
30 | reverse = false
31 |
32 | [preview]
33 | max_preview_size = 2097152 # 2MB
34 | preview_script = "~/.config/joshuto/preview_file.sh"
35 |
36 | [tab]
37 | # inherit, home, root
38 | home_page = "home"
39 |
--------------------------------------------------------------------------------
/config/joshuto/preview_file.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | test -z "$joshuto_wrap_id" && exit 1;
4 |
5 | path="$1" # Full path of the previewed file
6 | x="$2" # x coordinate of upper left cell of preview area
7 | # y="$3" # y coordinate of upper left cell of preview area
8 | width="$4" # Width of the preview pane (number of fitting characters)
9 | height="$5" # Height of the preview pane (number of fitting characters)
10 | let y="$height"/5
11 |
12 | # Find out mimetype and extension
13 | mimetype=$(file --mime-type -Lb "$path")
14 | extension=$(/bin/echo "${path##*.}" | awk '{print tolower($0)}')
15 |
16 | case "$mimetype" in
17 | image/png | image/jpeg)
18 | show_image "$path" $x $y $width $height
19 | ;;
20 | video/*)
21 | ffmpegthumbnailer -i "$path" -f -m -c png -s 0 -o /tmp/vid.png 2>/dev/null
22 | show_image /tmp/vid.png $x $y $width $height
23 | sleep 5 && rm -f /tmp/vid.png
24 | ;;
25 | *)
26 | remove_image
27 | esac
28 |
--------------------------------------------------------------------------------
/config/kanshi/config:
--------------------------------------------------------------------------------
1 | profile workdesk {
2 | output eDP-1 enable scale 2 mode 3840x2160 position 0,0
3 | output DP-2 enable scale 1.5
4 | }
5 |
6 | profile laptop {
7 | output eDP-1 enable mode 3840x2160 position 0,0
8 | }
9 |
--------------------------------------------------------------------------------
/config/mailcap:
--------------------------------------------------------------------------------
1 | application/pdf;gv '%s'; test=test -n "$DISPLAY"
2 | application/pdf;pdfcat '%s'; copiousoutput
3 | text/html; firefox '%s'; edit=emacs -c '%s'; test=test -n "$DISPLAY"
4 | text/html; w3m -T text/html '%s'; needsterminal
5 | text/html; w3m -T text/html -dump '%s'; copiousoutput
6 |
7 |
8 |
--------------------------------------------------------------------------------
/config/ncmpcpp/config:
--------------------------------------------------------------------------------
1 | ncmpcpp_directory = ~/.config/ncmpcpp
2 | mpd_host = localhost
3 | mpd_port = 6600
4 | mpd_crossfade_time = 2
5 | song_list_format = "{{%a - %t}|{%f}}{$R%l}"
6 | song_status_format = "{{%a{ $2//$9 %b{, %y}} $2//$9 }{%t$/b}}|{$b%f$/b}"
7 | song_library_format = {{%a - %t} (%b)}|{%f}
8 | #alternative_header_first_line_format = $b$1$aqqu$/a$9 {%t}|{%f} $1$atqq$/a$9$/b
9 | #alternative_header_second_line_format = {{$4$b%a$/b$9}{ - $7%b$9}{ ($4%y$9)}}|{%D}
10 | now_playing_prefix = "$b$5"
11 | now_playing_suffix = "$/b$9"
12 | #browser_playlist_prefix = "$2playlist$9 "
13 | #selected_item_prefix = $6
14 | #selected_item_suffix = $9
15 | #modified_item_prefix = $3> $9
16 | #song_window_title_format = {%a - }{%t}|{%f}
17 | #browser_sort_mode = name
18 | #browser_sort_format = {%a - }{%t}|{%f} {(%l)}
19 | #song_columns_list_format = (20)[]{a} (6f)[green]{NE} (50)[white]{t|f:Title} (20)[red]{b} (7f)[magenta]{l}
20 | #playlist_show_mpd_host = no
21 | #playlist_show_remaining_time = no
22 | #playlist_shorten_total_times = no
23 | #playlist_separate_albums = no
24 | playlist_display_mode = classic
25 | #browser_display_mode = classic
26 | #search_engine_display_mode = classic
27 | #playlist_editor_display_mode = classic
28 | #discard_colors_if_item_is_selected = yes
29 | #incremental_seeking = yes
30 | #seek_time = 1
31 | #volume_change_step = 2
32 | autocenter_mode = yes
33 | #centered_cursor = no
34 | progressbar_look = "──"
35 | #progressbar_boldness = yes
36 | #default_place_to_search_in = database
37 | #user_interface = classic
38 | #data_fetching_delay = yes
39 | #media_library_primary_tag = artist
40 | #default_find_mode = wrapped
41 | #default_tag_editor_pattern = %n - %t
42 | header_visibility = no
43 | statusbar_visibility = no
44 | titles_visibility = no
45 | #header_text_scrolling = yes
46 | #cyclic_scrolling = no
47 | #lines_scrolled = 2
48 | follow_now_playing_lyrics = no
49 | #fetch_lyrics_for_current_song_in_background = no
50 | #store_lyrics_in_song_dir = no
51 | #generate_win32_compatible_filenames = yes
52 | #allow_for_physical_item_deletion = no
53 | #lastfm_preferred_language = en
54 | #show_hidden_files_in_local_browser = no
55 | #screen_switcher_mode = playlist, browser
56 | startup_screen = playlist
57 | #startup_slave_screen = ""
58 | #startup_slave_screen_focus = no
59 | #locked_screen_width_part = 50
60 | #ask_for_locked_screen_width_part = yes
61 | jump_to_now_playing_song_at_start = yes
62 | #ask_before_clearing_playlists = yes
63 | #clock_display_seconds = no
64 | #display_volume_level = yes
65 | #display_bitrate = no
66 | #display_remaining_time = no
67 | #regular_expressions = perl
68 | #block_search_constraints_change_if_items_found = yes
69 | #mouse_support = yes
70 | #mouse_list_scroll_whole_page = yes
71 | #empty_tag_marker =
72 | #tags_separator = " | "
73 | #tag_editor_extended_numeration = no
74 | #media_library_sort_by_mtime = no
75 | # enable_window_title = no
76 | external_editor = nvim
77 | colors_enabled = yes
78 | empty_tag_color = red
79 | header_window_color = yellow
80 | volume_color = yellow
81 | state_line_color = red
82 | state_flags_color = yellow
83 | main_window_color = default
84 | color1 = red
85 | color2 = red
86 | progressbar_color = black
87 | progressbar_elapsed_color = red
88 | statusbar_color = default
89 | alternative_ui_separator_color = magenta
90 | window_border_color = yellow
91 |
92 | ## you have dunst? use this
93 | # execute_on_song_change = $XDG_CONFIG_DIR/ncmpcpp/art-dark.sh && notify-send "Now Playing ♫" "$(mpc current)"
94 |
95 | ## you don't have dunst? maybe another notification daemon would work. doesn't work? use this to disable sending notification attemps
96 | # execute_on_song_change = ~/.config/ncmpcpp/art-dark.sh
97 |
--------------------------------------------------------------------------------
/config/newsboat/config:
--------------------------------------------------------------------------------
1 | # By default, old articles are cached and have to be fetched manually with R
2 | # This configures newsboat to download feeds automatically
3 | auto-reload yes
4 | refresh-on-startup yes
5 | show-read-articles yes
6 | cleanup-on-quit yes
7 |
8 | # Vim bindings
9 | unbind-key h
10 | unbind-key j
11 | unbind-key k
12 | unbind-key l
13 |
14 | bind-key h quit
15 | bind-key j next
16 | bind-key k prev
17 | bind-key l open
18 |
19 | unbind-key J
20 | unbind-key K
21 |
22 | bind-key J next-feed
23 | bind-key K prev-feed
24 |
25 | unbind-key d
26 | unbind-key u
27 | bind-key d pagedown
28 | bind-key u pageup
29 |
30 | unbind-key n
31 | unbind-key N
32 | bind-key n next-unread
33 | bind-key N prev-unread
34 |
35 | unbind-key r
36 | unbind-key x
37 | bind-key r toggle-article-read
38 | bind-key x pb-delete
39 |
40 | browser linkhandler
41 | macro v set browser "setsid -f mpv"; open-in-browser ; set browser linkhandler
42 | macro p set browser "setsid -f feh"; open-in-browser ; set browser linkhandler
43 | macro c set browser "xsel -b <<<"; open-in-browser ; set browser linkhandler
44 |
45 | # color scheme and format
46 | articlelist-format "%4i %f %D %?T?|%-17T| ?%t"
47 |
48 | highlight article "(^Feed:.*|^Title:.*|^Author:.*)" red default
49 | highlight article "(^Link:.*|^Date:.*)" white default
50 | highlight article "^Podcast Download URL:.*" cyan default
51 | highlight article "^Links:" magenta black underline
52 | highlight article "https?://[^ ]+" green default
53 | highlight article "^(Title):.*$" blue default
54 | highlight article "\\[[0-9][0-9]*\\]" magenta default bold
55 | highlight article "\\[image\\ [0-9]+\\]" green default bold
56 | highlight article "\\[embedded flash: [0-9][0-9]*\\]" green default bold
57 | highlight article ":.*\\(link\\)$" cyan default
58 | highlight article ":.*\\(image\\)$" blue default
59 | highlight article ":.*\\(embedded flash\\)$" magenta default
60 |
61 | color background default default
62 | color listnormal default default
63 | color listfocus magenta default
64 | color info blue black
65 | color article default default
66 | color listnormal_unread white default
67 | color listfocus_unread color255 red
68 |
69 | # urls-source "ttrss"
70 | # ttrss-url "https://rss.chvatal.com/"
71 | # ttrss-login "jake"
72 | # ttrss-passwordfile "~/.newsboat/password"
73 |
74 | # ttrss-flag-star "s"
75 | # ttrss-flag-publish "p"
76 |
--------------------------------------------------------------------------------
/config/nushell/config.nu:
--------------------------------------------------------------------------------
1 | $env.config = {
2 | show_banner: false
3 | table: {
4 | mode: none
5 | }
6 | hooks: {
7 | pre_prompt: [{
8 | let direnv = (direnv export json | from json | default {})
9 | if ($direnv | is-empty) {
10 | return
11 | }
12 | $direnv
13 | | items {|key, value|
14 | {
15 | key: $key
16 | value: (if $key in $env.ENV_CONVERSIONS {
17 | do ($env.ENV_CONVERSIONS | get $key | get from_string) $value
18 | } else {
19 | $value
20 | })
21 | }
22 | } | transpose -ird | load-env
23 | }]
24 | }
25 | }
26 |
27 | source ~/.cache/starship/init.nu
28 |
--------------------------------------------------------------------------------
/config/nushell/env.nu:
--------------------------------------------------------------------------------
1 | # Specifies how environment variables are:
2 | # - converted from a string to a value on Nushell startup (from_string)
3 | # - converted from a value back to a string when running external commands (to_string)
4 | # Note: The conversions happen *after* config.nu is loaded
5 |
6 | # gnupghome is only defined in bash? redefine it
7 | $env.GNUPGHOME = $'($env.XDG_CONFIG_HOME)/gnupg'
8 |
9 | $env.ENV_CONVERSIONS = {
10 | "PATH": {
11 | from_string: { |s| $s | split row (char esep) }
12 | to_string: { |v| $v | str join (char esep) }
13 | }
14 | "Path": {
15 | from_string: { |s| $s | split row (char esep) }
16 | to_string: { |v| $v | str join (char esep) }
17 | }
18 | }
19 |
20 | # Directories to search for scripts when calling source or use
21 | # By default, /scripts is added
22 | $env.NU_LIB_DIRS = [
23 | ($nu.config-path | path dirname | path join 'scripts')
24 | ]
25 |
26 | # Directories to search for plugin binaries when calling register
27 | # By default, /plugins is added
28 | $env.NU_PLUGIN_DIRS = [
29 | ($nu.config-path | path dirname | path join 'plugins')
30 | ]
31 |
32 | # Add /bin to path
33 | $env.PATH = ($env.PATH | split row (char esep) | prepend '/etc/nixos/bin')
34 | $env.PATH = ($env.PATH | split row (char esep) | prepend $'($env.HOME)/.emacs.d/bin')
35 |
36 | # TODO: incorporate this throughout
37 | $env.EDITOR = 'emacsclient -c';
38 |
39 | $env.GDK_BACKEND = 'wayland';
40 |
41 | alias js = joshuto
42 | alias cat = bat
43 | alias e = emacsclient -c
44 | # TODO: is there a better wifi testing tool?
45 | alias ct = ping google.com
46 |
47 | alias v = nvim -u ~/.config/nvim/init.lua
48 | alias vi = nvim -u ~/.config/nvim/init.lua
49 | alias vim = nvim -u ~/.config/nvim/init.lua
50 | alias nvim = nvim -u ~/.config/nvim/init.lua
51 |
52 | # TODO: Remove once shell aliases are ported to nushell
53 |
54 | alias gbc = git checkout (git branch --all | fzf | str replace '(\*)' '' | str trim);
55 | alias gop = git open
56 | alias ga = git add
57 | alias gc = git commit
58 | alias gcm = git commit -m
59 | alias gcl = git clone
60 |
61 | alias gap = git add --patch
62 | # need to pass this the commit after `resolve` ...
63 | alias gre = git revert --strategy resolve
64 | alias gb = git branch -av
65 | alias gbl = git blame
66 | alias gca = git commit --amend
67 | alias gcf = git commit --fixup
68 | alias gf = git fetch
69 | alias gi = git init
70 | alias gl = git log --graph --pretty="format:%C(yellow)%h%Creset %C(red)%G?%Creset%C(green)%d%Creset %s %Cblue(%cr) %C(bold blue)<%aN>%Creset"
71 | alias gll = git log --pretty="format:%C(yellow)%h%Creset %C(red)%G?%Creset%C(green)%d%Creset %s %Cblue(%cr) %C(bold blue)<%aN>%Creset"
72 | alias gL = gl --stat
73 | alias gp = git push
74 | alias gpl = git pull --rebase --autostash
75 | alias gs = git status --short .
76 | alias gss = git status
77 | alias gst = git stash
78 | alias gr = git reset HEAD
79 | alias grv = git rev-parse
80 |
81 | mkdir ~/.cache/starship
82 | starship init nu | save -f ~/.cache/starship/init.nu
83 |
--------------------------------------------------------------------------------
/config/nushell/login.nu:
--------------------------------------------------------------------------------
1 | if (echo (tty)) == /dev/tty1 {
2 | exec sway
3 | }
4 |
--------------------------------------------------------------------------------
/config/starship/starship.toml:
--------------------------------------------------------------------------------
1 | format = """$character"""
2 | right_format = """$all"""
3 | add_newline = false
4 |
5 | [nix_shell]
6 | format = 'via [$symbol$name]($style) '
7 |
--------------------------------------------------------------------------------
/config/tmux/config:
--------------------------------------------------------------------------------
1 | # tmux.conf
2 | # By Henrik Lissner
3 | # https://github.com/hlissner/dotfiles
4 | ########################################
5 |
6 | set -g default-terminal "xterm-256color"
7 |
8 | new-session # spawn session if attaching when none are running
9 |
10 | setw -g automatic-rename on # rename window after current program
11 | set -g renumber-windows on # renumber windows when one is closed
12 | # Zero-based indexing is fine in programming languages, but not so much in a
13 | # multiplexer when zero is on the other side of the keyboard.
14 | set -g base-index 1
15 | setw -g pane-base-index 1
16 | # display tmux messages longer
17 | set -g display-time 1500
18 | set -g display-panes-time 800
19 | # Address vim-mode switching delay (http://superuser.com/a/252717/65504)
20 | set -s escape-time 0
21 | set -sg repeat-time 600
22 | set -g history-limit 10000
23 | # Rather than constraining window size to the maximum size of any client
24 | # connected to the *session*, constrain window size to the maximum size of any
25 | # client connected to *that window*. Much more reasonable.
26 | setw -g aggressive-resize off
27 | # For terminals that support them, propagate these events to programs that
28 | # understand them.
29 | set -s focus-events on
30 | # Enable mouse + mouse wheel
31 | set -g mouse on
32 |
33 | ########################################
34 | # Keybinds #
35 | ########################################
36 |
37 | # Rebind prefix to C-c. Press twice to send literal C-c.
38 | unbind C-b
39 | set -g prefix C-c
40 | bind C-c send-prefix
41 |
42 | # Vi-style keybinds
43 | set -g status-keys vi
44 | set -g mode-keys vi
45 |
46 | bind c new-window -c "#{pane_current_path}"
47 | bind v split-window -h -c "#{pane_current_path}"
48 | bind s split-window -v -c "#{pane_current_path}"
49 |
50 | bind h select-pane -L
51 | bind j select-pane -D
52 | bind k select-pane -U
53 | bind l select-pane -R
54 | bind H run '$TMUX_HOME/swap-pane.sh left'
55 | bind J run '$TMUX_HOME/swap-pane.sh down'
56 | bind K run '$TMUX_HOME/swap-pane.sh up'
57 | bind L run '$TMUX_HOME/swap-pane.sh right'
58 | bind M run '$TMUX_HOME/swap-pane.sh master'
59 |
60 | bind o resize-pane -Z
61 | bind S choose-session
62 | bind W choose-window
63 | bind / choose-session
64 | bind . choose-window
65 |
66 | # bind = select-layout tiled
67 | bind | select-layout even-horizontal
68 | bind _ select-layout even-vertical
69 |
70 | # Disable confirmation
71 | bind x kill-pane
72 | bind X kill-window
73 | bind q kill-session
74 | bind Q kill-server
75 |
76 | # Smart pane switching with awareness of vim splits
77 | # See: https://github.com/christoomey/vim-tmux-navigator
78 | is_vim='echo "#{pane_current_command}" | grep -iqE "(^|\/)g?(view|n?vim?x?)(diff)?$"'
79 | bind -n C-h if-shell "$is_vim" "send-keys C-h" "select-pane -L"
80 | bind -n C-j if-shell "$is_vim" "send-keys C-j" "select-pane -D"
81 | bind -n C-k if-shell "$is_vim" "send-keys C-k" "select-pane -U"
82 | bind -n C-l if-shell "$is_vim" "send-keys C-l" "select-pane -R"
83 | bind -n C-\\ if-shell "$is_vim" "send-keys C-\\" "select-pane -l"
84 | bind C-w last-pane
85 | bind C-n next-window
86 | bind C-p previous-window
87 |
88 | # break pane into a window
89 | bind = select-layout even-vertical
90 | bind + select-layout even-horizontal
91 | bind - break-pane
92 | bind _ join-pane
93 |
94 | # reload config without killing server
95 | bind r source-file $DOTFILES/config/tmux/config \; display-message " Config reloaded..".
96 | bind ^r refresh-client
97 |
98 |
99 | ########################################
100 | # Copy mode #
101 | ########################################
102 |
103 | bind Enter copy-mode # enter copy mode
104 | bind b list-buffers # list paster buffers
105 | bind B choose-buffer # choose which buffer to paste from
106 | bind p paste-buffer # paste from the top paste buffer
107 | bind P run "xclip -selection clipboard -o | tmux load-buffer - ; tmux paste-buffer"
108 |
109 | bind -T copy-mode-vi v send-keys -X begin-selection
110 | bind -T copy-mode-vi C-v send-keys -X rectangle-toggle
111 | bind -T copy-mode-vi Escape send-keys -X cancel
112 | bind -T copy-mode-vi C-g send-keys -X cancel
113 | bind -T copy-mode-vi H send-keys -X start-of-line
114 | bind -T copy-mode-vi L send-keys -X end-of-line
115 |
116 |
117 | ########################################
118 | # Local config #
119 | ########################################
120 | set -g @open-editor 'C-e'
121 | set -g @open-S 'https://www.duckduckgo.com/'
122 |
123 | source $TMUX_HOME/extraInit
124 | if '[ -f ~/.tmux.conf ]' 'source ~/.tmux.conf'
125 |
--------------------------------------------------------------------------------
/config/tmux/swap-pane.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | CONF="$TMUX_PLUGINS_PATH/lastpane"
3 | swap() { tmux swap-pane -s"$1" -t"$2"; }
4 |
5 | target=
6 | case $1 in
7 | up) target="U" ;;
8 | down) target="D" ;;
9 | left) target="L" ;;
10 | right) target="R" ;;
11 | master) target="M" ;;
12 | *) exit 1 ;;
13 | esac
14 |
15 | src_pane=$(tmux display-message -p "#P")
16 | tmux select-pane -${target}
17 |
18 | dst_pane=$(tmux display-message -p "#P")
19 | tmux select-pane -${src_pane}
20 |
21 | [[ "$target" == M ]] && dst_pane=0
22 | swap "$src_pane" "$dst_pane"
23 | tmux select-pane -t"$dst_pane"
24 |
--------------------------------------------------------------------------------
/config/tmux/tmux.conf:
--------------------------------------------------------------------------------
1 | # -- THEME -------------------------------
2 |
3 | # The statusbar
4 | set -g status-position bottom
5 | set -g status-justify centre
6 | set -g status-bg default
7 | set -g status-fg colour15
8 | set -g status-interval 10
9 | # set -g status-attr dim
10 | # set -g status-left '#[fg=colour236]_________________________'
11 | set -g status-left '#{prefix_highlight}#[fg=colour236]|―――――――――――――――――――|'
12 | # set -g status-left "#[fg=colour236]#{prefix_highlight} #[fg=colour5] #S #[fg=colour236]──"
13 | # set -g status-right '#[fg=colour236]_________________________'
14 | set -g status-right '#[fg=colour236]|―――――――――――――――――――――――――|'
15 | set -g status-right-length 30
16 | set -g status-left-length 30
17 |
18 | # The messages
19 | set -g message-style fg=magenta,bg=colour236
20 | set -g message-command-style fg=blue,bg=black
21 |
22 | # loud or quiet?
23 | set-option -g visual-activity off
24 | set-option -g visual-bell off
25 | set-option -g visual-silence off
26 | set-window-option -g monitor-activity on
27 | set-option -g bell-action none
28 |
29 | # The modes
30 | setw -g clock-mode-colour colour135
31 | # setw -g mode-attr bold
32 | # setw -g mode-fg colour196
33 | # setw -g mode-bg colour238
34 |
35 | # The panes
36 | set -g pane-border-style fg=colour235
37 | set -g pane-active-border-style fg=colour5
38 |
39 | # setw -g window-status-current-fg colour2
40 | # setw -g window-status-current-bg default
41 | # setw -g window-status-current-attr none
42 | # setw -g window-status-current-format ' #W '
43 |
44 | # setw -g window-status-fg colour236
45 | # setw -g window-status-bg default
46 | # setw -g window-status-attr none
47 | # setw -g window-status-format '#[fg=colour8] #I #[fg=default]#W '
48 | setw -g window-status-format ' #W '
49 |
50 | # setw -g window-status-activity-bg default
51 | # setw -g window-status-activity-fg colour240
52 | # setw -g window-status-activity-attr none
53 |
54 | # setw -g window-status-bell-attr bold
55 | # setw -g window-status-bell-fg colour255
56 | # setw -g window-status-bell-bg colour1
57 |
58 |
59 | # -- PLUGINS -----------------------------
60 |
61 | # tmux-prefix-highlight
62 | set -g @prefix_highlight_empty_prompt '-----'
63 | set -g @prefix_highlight_prefix_prompt ' C^c #[bg=colour8]'
64 | set -g @prefix_highlight_show_copy_mode 'on'
65 |
--------------------------------------------------------------------------------
/config/tree-sitter/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "parser-directories": [
3 | "/home/jake/.tree-sitter"
4 | ],
5 | "theme": {
6 | "function": 26,
7 | "string": 28,
8 | "constant": 94,
9 | "punctuation.bracket": 239,
10 | "constant.builtin": {
11 | "color": 94,
12 | "bold": true
13 | },
14 | "punctuation.delimiter": 239,
15 | "property": 124,
16 | "number": {
17 | "color": 94,
18 | "bold": true
19 | },
20 | "string.special": 30,
21 | "operator": {
22 | "bold": true,
23 | "color": 239
24 | },
25 | "type": 23,
26 | "comment": {
27 | "color": 245,
28 | "italic": true
29 | },
30 | "constructor": 136,
31 | "type.builtin": {
32 | "color": 23,
33 | "bold": true
34 | },
35 | "variable.parameter": {
36 | "underline": true
37 | },
38 | "keyword": 56,
39 | "embedded": null,
40 | "attribute": {
41 | "italic": true,
42 | "color": 124
43 | },
44 | "function.builtin": {
45 | "bold": true,
46 | "color": 26
47 | },
48 | "variable.builtin": {
49 | "bold": true
50 | },
51 | "module": 136,
52 | "tag": 18
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/config/vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "window.menuBarVisibility": "hidden",
3 | "keyboard.dispatch": "keyCode",
4 | "editor.lineNumbers": "relative" ,
5 | "editor.minimap.enable": false,
6 | "update.mode": "none",
7 | "editor.scrollbar.horizontal": "hidden",
8 | "editor.scrollbar.vertical": "hidden",
9 | "workbench.colorTheme": "Nord",
10 | "workbench.startupEditor": "newUntitledFile"
11 |
12 | "editor.tabSize": 4,
13 | "editor.formatOnSave": true,
14 | "editor.autoIndent": "full",
15 | "editor.quickSuggestions": true,
16 | "editor.mouseWheelZoom": true,
17 | "editor.semanticHighlighting.enabled": true,
18 | "editor.fontLigatures": true,
19 | "editor.wordBasedSuggestions": true,
20 | "editor.suggest.localityBonus": true,
21 | "editor.snippetSuggestions": "bottom",
22 | "editor.quickSuggestionsDelay": 0,
23 | "files.exclude": {
24 | "**/.git": true,
25 | "**/.DS_Store": true
26 | },
27 | "editor.rulers": [
28 | { "column": 80, "color": "#ffffff10" },
29 | { "column": 120, "color": "#6666668e" }
30 | ],
31 | "editor.codeActionsOnSave": {
32 | "source.fixAll": true
33 | },
34 | "prettier.tabWidth": 4,
35 | "prettier.useTabs": true
36 | }
37 |
--------------------------------------------------------------------------------
/config/vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | // See https://go.microsoft.com/fwlink/? LinkId=733558
3 | // for the documentation about the tasks.json format
4 | "version": "2.0.0",
5 | "tasks": []
6 | }
7 |
--------------------------------------------------------------------------------
/config/waybar/config:
--------------------------------------------------------------------------------
1 | {
2 | "layer": "top",
3 | "output": ["eDP-1"],
4 | "modules-left": ["sway/workspaces", "sway/mode"],
5 | "modules-center": ["network"],
6 | "modules-right": ["pulseaudio", "battery", "clock"],
7 | "sway/workspaces": {
8 | "disable-scroll": true
9 | },
10 | "mpd": {
11 | "tooltip": false,
12 | "format": "{stateIcon} {artist} - {album} - {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S})",
13 | "format-disconnected": "ﳌ",
14 | "format-stopped": "",
15 | "state-icons": {
16 | "playing": "",
17 | "paused": ""
18 | }
19 | },
20 | "pulseaudio": {
21 | "tooltip": false,
22 | "scroll-step": 5,
23 | "format": "{icon} {format_source} {volume}%",
24 | "format-bluetooth": "{icon} {format_source} {volume}% ",
25 | "format-bluetooth-muted": "{icon} {format_source}",
26 | "format-muted": "🔇{format_source}",
27 | "format-source": " {volume}%",
28 | "format-source-muted": "",
29 | "format-icons": {
30 | "headphones": "",
31 | "handsfree": "",
32 | "headset": "",
33 | "phone": "",
34 | "portable": "",
35 | "car": "",
36 | "default": ["奄", "奔", "墳"]
37 | }
38 | },
39 | "network": {
40 | "tooltip": false,
41 | "format-wifi": " {essid} {ipaddr}",
42 | "format-ethernet": " {ipaddr}"
43 | },
44 | "cpu": {
45 | "tooltip": false,
46 | "format": " {}%"
47 | },
48 | "memory": {
49 | "tooltip": false,
50 | "format": " {}%"
51 | },
52 | "battery": {
53 | "states": {
54 | "warning": 30,
55 | "critical": 15
56 | },
57 | "format": "{icon} {capacity}%",
58 | "format-icons": ["", "", "", "", ""],
59 | "max-length": 25
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/config/waybar/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | font-family: monospace;
3 | font-size: 12px;
4 | min-height: 16px;
5 | }
6 |
7 | window#waybar {
8 | border-bottom: 2px solid @bgalt;
9 | background-color: @background;
10 | }
11 |
12 | window#waybar.hidden {
13 | opacity: 0.2;
14 | }
15 |
16 | #workspaces, #mode, #window, #mpd, #network, #pulseaudio, #temperature, #cpu, #memory, #battery, #clock {
17 | margin: 4px 3px;
18 | margin-top: 0;
19 | margin-bottom: 2px;
20 | padding: 0 8px;
21 | padding-top: 0;
22 | transition: none;
23 | color: @fgalt;
24 | }
25 |
26 | #window {
27 | color: transparent;
28 | background: transparent;
29 | }
30 |
31 | #workspaces {
32 | /* as the leftmost element, this needs extra padding */
33 | padding: 0;
34 | }
35 |
36 | #workspaces button {
37 | transition: none;
38 | color: @foreground;
39 | margin: 0 4px;
40 | padding: 0 6px;
41 | background: transparent;
42 | font-size: 16px;
43 | }
44 |
45 | #workspaces button.focused {
46 | color: @blue;
47 | }
48 |
49 | #workspaces button:hover {
50 | transition: none;
51 | box-shadow: inherit;
52 | text-shadow: inherit;
53 | color: @buttonhover;
54 | }
55 |
56 | #clock {
57 | /* As the last element, this needs right margin */
58 | padding-right: 16px;
59 | }
60 |
--------------------------------------------------------------------------------
/config/xdg/user-dirs.dirs:
--------------------------------------------------------------------------------
1 | # This file is written by xdg-user-dirs-update
2 | # If you want to change or add directories, just edit the line you're
3 | # interested in. All local changes will be retained on the next run.
4 | # Format is XDG_xxx_DIR="$HOME/yyy", where yyy is a shell-escaped
5 | # homedir-relative path, or XDG_xxx_DIR="/yyy", where /yyy is an
6 | # absolute path. No other format is supported.
7 | #
8 |
9 | XDG_DESKTOP_DIR="$HOME/"
10 | XDG_DOWNLOAD_DIR="$HOME/"
11 | XDG_TEMPLATES_DIR="$HOME/"
12 | XDG_PUBLICSHARE_DIR="$HOME/"
13 | XDG_DOCUMENTS_DIR="$HOME/"
14 | XDG_MUSIC_DIR="$HOME/"
15 | XDG_PICTURES_DIR="$HOME/pics/"
16 | XDG_VIDEOS_DIR="$HOME/"
17 |
--------------------------------------------------------------------------------
/default.nix:
--------------------------------------------------------------------------------
1 | { inputs, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | with inputs; {
6 | imports =
7 | [
8 | home-manager.nixosModules.home-manager
9 | simple-nixos-mailserver.nixosModules.mailserver
10 | ]
11 | ++ (mapModulesRec' (toString ./modules) import);
12 |
13 | # Common config for all nixos machines to ensure the flake operates soundly
14 | environment.variables = {
15 | DOTFILES = dotFilesDir;
16 | NIXPKGS_ALLOW_UNFREE = "1";
17 | };
18 |
19 | nix = {
20 | package = pkgs.nixFlakes;
21 | extraOptions = ''
22 | experimental-features = nix-command flakes
23 | '';
24 |
25 | nixPath = (mapAttrsToList (n: v: "${n}=${v}") inputs) ++ [
26 | "nixpkgs-overlays=${dotFilesDir}/overlays"
27 | "dotfiles=${dotFilesDir}"
28 | ];
29 |
30 | settings.substituters = [
31 | "https://cache.nixos.org/"
32 | "https://nix-community.cachix.org"
33 | ];
34 |
35 | settings.trusted-public-keys = [
36 | "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
37 | ];
38 |
39 | # TODO: I had conflicting values here,
40 | # so had to update. Makes sense -- but what do each of these do?
41 | registry = {
42 | nixos.flake = nixpkgs;
43 | nixpkgs.flake = nixpkgs; # nixpkgs-unstable;
44 | };
45 |
46 | settings.sandbox = true;
47 | settings.trusted-users = [ username ];
48 | gc.automatic = false; # never automatically garbage collect
49 | };
50 | system.configurationRevision = mkIf (self ? rev) self.rev;
51 | system.stateVersion = "20.09";
52 |
53 | # allow users to store fonts easily
54 | fonts.fontDir.enable = true;
55 |
56 | ## Some reasonable, global defaults
57 | # This is here to appease 'nix flake check' for generic hosts with no
58 | # hardware-configuration.nix or fileSystem config.
59 | fileSystems."/".device = mkDefault "/dev/disk/by-label/nixos";
60 |
61 | # Use the latest kernel
62 | # boot.kernelPackages = pkgs.linuxPackages_latest;
63 |
64 | boot.loader = {
65 | efi.canTouchEfiVariables = true;
66 | systemd-boot.configurationLimit = 10;
67 | systemd-boot.enable = mkDefault true;
68 | };
69 |
70 | environment.systemPackages = with pkgs; [
71 | coreutils
72 | wget
73 | unzip
74 | ];
75 | }
76 |
--------------------------------------------------------------------------------
/etc/test-screencast.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # Test screensharing with Linux + Wayland + PipeWire
4 | # https://gitlab.gnome.org/-/snippets/19
5 |
6 | import re
7 | import signal
8 | import dbus
9 | from gi.repository import GLib
10 | from dbus.mainloop.glib import DBusGMainLoop
11 |
12 | import gi
13 | gi.require_version('Gst', '1.0')
14 | from gi.repository import GObject, Gst
15 |
16 | DBusGMainLoop(set_as_default=True)
17 | Gst.init(None)
18 |
19 | loop = GLib.MainLoop()
20 |
21 | bus = dbus.SessionBus()
22 | request_iface = 'org.freedesktop.portal.Request'
23 | screen_cast_iface = 'org.freedesktop.portal.ScreenCast'
24 |
25 | pipeline = None
26 |
27 | def terminate():
28 | if pipeline is not None:
29 | self.player.set_state(Gst.State.NULL)
30 | loop.quit()
31 |
32 | request_token_counter = 0
33 | session_token_counter = 0
34 | sender_name = re.sub(r'\.', r'_', bus.get_unique_name()[1:])
35 |
36 | def new_request_path():
37 | global request_token_counter
38 | request_token_counter = request_token_counter + 1
39 | token = 'u%d'%request_token_counter
40 | path = '/org/freedesktop/portal/desktop/request/%s/%s'%(sender_name, token)
41 | return (path, token)
42 |
43 | def new_session_path():
44 | global session_token_counter
45 | session_token_counter = session_token_counter + 1
46 | token = 'u%d'%session_token_counter
47 | path = '/org/freedesktop/portal/desktop/session/%s/%s'%(sender_name, token)
48 | return (path, token)
49 |
50 | def screen_cast_call(method, callback, *args, options={}):
51 | (request_path, request_token) = new_request_path()
52 | bus.add_signal_receiver(callback,
53 | 'Response',
54 | request_iface,
55 | 'org.freedesktop.portal.Desktop',
56 | request_path)
57 | options['handle_token'] = request_token
58 | method(*(args + (options, )),
59 | dbus_interface=screen_cast_iface)
60 |
61 | def on_gst_message(bus, message):
62 | type = message.type
63 | if type == Gst.MessageType.EOS or type == Gst.MessageType.ERROR:
64 | terminate()
65 |
66 | def play_pipewire_stream(node_id):
67 | empty_dict = dbus.Dictionary(signature="sv")
68 | fd_object = portal.OpenPipeWireRemote(session, empty_dict,
69 | dbus_interface=screen_cast_iface)
70 | fd = fd_object.take()
71 | pipeline = Gst.parse_launch('pipewiresrc fd=%d path=%u ! videoconvert ! xvimagesink'%(fd, node_id))
72 | pipeline.set_state(Gst.State.PLAYING)
73 | pipeline.get_bus().connect('message', on_gst_message)
74 |
75 | def on_start_response(response, results):
76 | if response != 0:
77 | print("Failed to start: %s"%response)
78 | terminate()
79 | return
80 |
81 | print("streams:")
82 | for (node_id, stream_properties) in results['streams']:
83 | print("stream {}".format(node_id))
84 | play_pipewire_stream(node_id)
85 |
86 | def on_select_sources_response(response, results):
87 | if response != 0:
88 | print("Failed to select sources: %d"%response)
89 | terminate()
90 | return
91 |
92 | print("sources selected")
93 | global session
94 | screen_cast_call(portal.Start, on_start_response,
95 | session, '')
96 |
97 | def on_create_session_response(response, results):
98 | if response != 0:
99 | print("Failed to create session: %d"%response)
100 | terminate()
101 | return
102 |
103 | global session
104 | session = results['session_handle']
105 | print("session %s created"%session)
106 |
107 | screen_cast_call(portal.SelectSources, on_select_sources_response,
108 | session,
109 | options={ 'multiple': False,
110 | 'types': dbus.UInt32(1|2) })
111 |
112 | portal = bus.get_object('org.freedesktop.portal.Desktop',
113 | '/org/freedesktop/portal/desktop')
114 |
115 | (session_path, session_token) = new_session_path()
116 | screen_cast_call(portal.CreateSession, on_create_session_response,
117 | options={ 'session_handle_token': session_token })
118 |
119 | try:
120 | loop.run()
121 | except KeyboardInterrupt:
122 | terminate()
123 |
--------------------------------------------------------------------------------
/flake.nix:
--------------------------------------------------------------------------------
1 | # flake.nix --- the heart of my dotfiles #
2 | # Author: Henrik Lissner ++ Jake Chvatal
3 | # URL: https://github.com/jakeisnt/nixcfg
4 | # License: MIT
5 |
6 | {
7 | description = "jakeisnt's nix configuration";
8 |
9 | inputs = {
10 | # Two inputs so I can track them separately at different rates.
11 | nixpkgs.url = "nixpkgs/nixos-24.05";
12 | nixpkgs-unstable.url = "nixpkgs/master";
13 |
14 | home-manager = {
15 | url = "github:nix-community/home-manager/release-24.05";
16 | inputs.nixpkgs.follows = "nixpkgs";
17 | };
18 |
19 | nur = {
20 | url = "github:nix-community/NUR/master";
21 | # inputs.nixpkgs.follows = "nixpkgs";
22 | };
23 |
24 | emacs-overlay = {
25 | url = "github:nix-community/emacs-overlay";
26 | inputs.nixpkgs.follows = "nixpkgs";
27 | };
28 |
29 | nixos-hardware = {
30 | url = "github:nixos/nixos-hardware";
31 | # inputs.nixpkgs.follows = "nixpkgs";
32 | };
33 |
34 | simple-nixos-mailserver = {
35 | url = "gitlab:simple-nixos-mailserver/nixos-mailserver";
36 | inputs.nixpkgs.follows = "nixpkgs";
37 | };
38 |
39 | spicetify-nix = {
40 | url = "github:jakeisnt/spicetify-nix";
41 | inputs.nixpkgs.follows = "nixpkgs";
42 | };
43 |
44 | nix-remarkable = {
45 | url = "github:siraben/nix-remarkable";
46 | inputs.nixpkgs.follows = "nixpkgs";
47 | };
48 |
49 | # Pin Doom Emacs version
50 | doom-emacs = {
51 | url = "github:doomemacs/doomemacs/master";
52 | flake = false;
53 | # inputs.nixpkgs.follows = "nixpkgs";
54 | };
55 |
56 | # Used for compatible `nix build` commands if the system doesn't yet have flakes enabled`
57 | flake-compat = {
58 | url = github:edolstra/flake-compat;
59 | flake = false;
60 | # inputs.nixpkgs.follows = "nixpkgs";
61 | };
62 | };
63 |
64 | outputs = inputs@{ self, nixpkgs, nixpkgs-unstable, spicetify-nix, doom-emacs, ... }:
65 | let
66 | inherit (lib) attrValues;
67 | inherit (lib.my) mapModules mapModulesRec mapHosts;
68 |
69 | system = "x86_64-linux";
70 |
71 | mkPkgs = pkgs: extraOverlays:
72 | import pkgs {
73 | inherit system;
74 | config = {
75 | android_sdk.accept_license = true;
76 | allowUnfree = true;
77 | };
78 | overlays = extraOverlays ++ (attrValues self.overlays);
79 | };
80 |
81 | uPkgs = mkPkgs nixpkgs-unstable [
82 | self.overlay
83 | (self: super: { doomEmacsRevision = doom-emacs.rev; })
84 | ];
85 |
86 | pkgs = mkPkgs nixpkgs [
87 | self.overlay
88 | (self: super: {
89 | doomEmacsRevision = doom-emacs.rev;
90 | unstable = uPkgs;
91 | })
92 | ];
93 |
94 |
95 | lib = nixpkgs.lib.extend (
96 | self: super: {
97 | my =
98 | import ./lib {
99 | inherit pkgs inputs;
100 | lib = self;
101 | };
102 | }
103 | );
104 | in
105 | {
106 | overlay = final: prev: {
107 | unstable = uPkgs;
108 | my = self.packages."${system}";
109 | extras = { inherit spicetify-nix; };
110 | };
111 |
112 | overlays = mapModules ./overlays import;
113 |
114 | packages."${system}" = mapModules ./packages (p: pkgs.callPackage p {});
115 |
116 | nixosModules = {
117 | dotfiles = import ./.;
118 | } // mapModulesRec ./modules import;
119 |
120 | nixosConfigurations = mapHosts ./hosts { inherit system; };
121 |
122 | devShell."${system}" = pkgs.mkShell {
123 | name = "nixos-config";
124 | };
125 |
126 | templates = {
127 | full = {
128 | path = ./.;
129 | description = "A grossly incandescent nixos config";
130 | };
131 | flake = {
132 | path = ./templates/flake;
133 | description = "A simple Nix flake starter project.";
134 | };
135 | };
136 |
137 | defaultTemplate = self.templates.flake;
138 |
139 | defaultApp."${system}" = {
140 | type = "app";
141 | program = ./bin/hey;
142 | };
143 | };
144 | }
145 |
--------------------------------------------------------------------------------
/hosts/README.org:
--------------------------------------------------------------------------------
1 | #+TITLE: Host Configurations
2 |
3 | * Systems
4 | + kuro
5 | + shiro
6 | + ao
7 | + aka
8 | + aijiro
9 | + unlisted: 100+ linodes, 7 VMs
10 |
--------------------------------------------------------------------------------
/hosts/iso-install/default.nix:
--------------------------------------------------------------------------------
1 | # Minimal config built to run off of a live USB.
2 | # Provides a TUI with configured emacs, git and fish.
3 | # Used for bootstrapping other configurations!
4 |
5 | { config, lib, pkgs, ... }:
6 | let hostname = "usb";
7 | in
8 |
9 | {
10 | imports = [
11 | ../personal.nix
12 |
13 | ];
14 |
15 | isoImage = {
16 | # if i don't want this to be an install disk:
17 | # makeEfiBootable = true;
18 | # makeUsbBootable = true;
19 | volumeID = lib.mkForce hostname;
20 | isoName = lib.mkForce "${hostname}.iso";
21 | };
22 |
23 | networking = {
24 | networkmanager.enable = true;
25 | wireless.enable = lib.mkForce false;
26 | };
27 |
28 | security.polkit.extraConfig = ''
29 | polkit.addRule(function(action, subject) {
30 | if (subject.isInGroup("wheel")) {
31 | return polkit.Result.YES;
32 | }
33 | });
34 | '';
35 |
36 | modules = {
37 | editors = {
38 | default = "emacs";
39 | emacs.enable = true;
40 | };
41 | shell = {
42 | git.enable = true;
43 | file.enable = true;
44 | fish.enable = true;
45 | };
46 | };
47 | }
48 |
--------------------------------------------------------------------------------
/hosts/personal.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, inputs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | {
6 | time.timeZone = mkDefault "America/New_York";
7 | i18n.defaultLocale = mkDefault "en_US.UTF-8";
8 |
9 | console = {
10 | earlySetup = true;
11 | keyMap = "us";
12 | };
13 |
14 | # Only allow user creation through Nix
15 | users.mutableUsers = false;
16 |
17 | users.users.root.password = "jake";
18 | users.users.${username}.password = "jake";
19 |
20 | user.extraGroups = [
21 | "networkmanager"
22 | ];
23 |
24 | location = (if config.time.timeZone == "America/Los_Angeles" then {
25 | latitude = 43.70011;
26 | longitude = -79.4163;
27 | } else if config.time.timeZone == "Europe/Stockholm" then {
28 | latitude = 55.88;
29 | longitude = 12.5;
30 | } else
31 | { });
32 | }
33 |
--------------------------------------------------------------------------------
/hosts/vultr/default.nix:
--------------------------------------------------------------------------------
1 | { config, pkgs, lib, ... }:
2 |
3 | # Deprecated:
4 | # This was a custom managed Vultr server.
5 | # It's no longer operating - I've moved to trusting cloud providers and other hosted services.
6 | # I might revisit this in the future when I have a permanent home and physical server infrastructure.
7 |
8 | with lib.my; {
9 | imports = [ ./hardware-configuration.nix ../personal.nix ];
10 |
11 | networking.hostName = "vultr";
12 |
13 | modules = {
14 | # just use nano
15 | # editors = {
16 | # default = "nvim";
17 | # vim.enable = true;
18 | # };
19 | shell = {
20 | git.enable = true;
21 | file.enable = true;
22 | fish.enable = true; # TODO need a simple shell to use without rust things, but not zsh - too heavy
23 | gnupg.enable = true;
24 | direnv.enable = true;
25 | };
26 | services = {
27 | acme.enable = true;
28 | mailserver.enable = false;
29 | ssh.enable = true;
30 | matrix = {
31 | enable = false;
32 | registration = false;
33 | element = false;
34 | };
35 | bitwarden = {
36 | enable = false;
37 | registration = false;
38 | mail = false;
39 | };
40 | cal.enable = false;
41 | nginx.enable = true;
42 | };
43 | };
44 |
45 | boot.loader.systemd-boot.enable = false;
46 |
47 | boot.loader.grub = {
48 | enable = true;
49 | version = 2;
50 | device = "/dev/vda";
51 | };
52 |
53 | networking = {
54 | domain = "isnt.online";
55 | # The ports are configured in their respective services,
56 | # but the system should individually decide whether to enable the firewall
57 | firewall.enable = true;
58 |
59 | # Enable the OpenSSH daemon.
60 | useDHCP = false;
61 | interfaces.ens3.useDHCP = true;
62 | };
63 |
64 | # isntweb-home.enable = true;
65 | services.nginx.virtualHosts = {
66 | "isnt.online" = {
67 | forceSSL = true;
68 | enableACME = true;
69 | locations = {
70 | "/" = {
71 | proxyPass = "http://127.0.0.1:6200/";
72 | proxyWebsockets = true;
73 | };
74 | };
75 | };
76 | };
77 | }
78 |
--------------------------------------------------------------------------------
/hosts/vultr/hardware-configuration.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, modulesPath, ... }:
2 |
3 | {
4 | imports =
5 | [ (modulesPath + "/profiles/qemu-guest.nix")
6 | ];
7 |
8 | boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "sr_mod" "virtio_blk" ];
9 | boot.initrd.kernelModules = [ ];
10 | boot.kernelModules = [ ];
11 | boot.extraModulePackages = [ ];
12 |
13 | fileSystems."/" =
14 | { device = "/dev/disk/by-label/nixos";
15 | fsType = "btrfs";
16 | };
17 |
18 | swapDevices = [ ];
19 | }
20 |
--------------------------------------------------------------------------------
/hosts/work/default.nix:
--------------------------------------------------------------------------------
1 | # Framework laptop!
2 | { config, pkgs, inputs, lib, ... }:
3 |
4 | {
5 | imports = [./hardware-configuration.nix ../personal.nix];
6 |
7 | networking.hostName = "work";
8 | services.getty.autologinUser = "jake";
9 |
10 | boot.loader = {
11 | systemd-boot.enable = true;
12 | efi.canTouchEfiVariables = true;
13 | };
14 |
15 | time.timeZone = "Europe/Stockholm";
16 |
17 | user.packages = with pkgs; [
18 | ripgrep
19 | fzf
20 | nil
21 | ];
22 |
23 | # automount storage devices
24 | services.devmon.enable = true;
25 | user.extraGroups = [
26 | # unprivileged access to storage devices
27 | "storage"
28 | # for scanner
29 | "scanner"
30 | ];
31 |
32 | networking = {
33 | extraHosts = lib.my.secrets.aliasDomains;
34 | useDHCP = false;
35 | interfaces.wlp170s0.useDHCP = true;
36 | networkmanager = {
37 | enable = true;
38 | wifi = {
39 | powersave = false; # no wifi lag
40 | };
41 | };
42 | };
43 |
44 | services.libinput.enable = true;
45 | services.openssh.startWhenNeeded = true;
46 | services.gnome.gnome-keyring.enable = true;
47 |
48 | programs.ssh = {
49 | startAgent = true;
50 | forwardX11 = true;
51 | };
52 |
53 | modules = {
54 | desktop.sway = {
55 | enable = true;
56 | fancy = true;
57 | scale = 1.0;
58 | };
59 | browsers = {
60 | default = "firefox";
61 | firefox.enable = true;
62 | # chrome.enable = true;
63 | };
64 | term = {
65 | default = "alacritty";
66 | alacritty.enable = true;
67 | foot.enable = true;
68 | };
69 | editors = {
70 | default = "emacsclient -c";
71 | vim.enable = true;
72 | emacs = {
73 | enable = false;
74 | };
75 | };
76 | hardware = {
77 | audio.enable = true;
78 | # bluetooth.enable = true;
79 | };
80 | # messengers.email.enable = true;
81 | media = {
82 | ncmpcpp.enable = true;
83 | recording.enable = true;
84 | # TODO: These options require python2.
85 | # graphics.enable = true;
86 | # graphics.photo.enable = true;
87 | };
88 | shell = {
89 | git.enable = true;
90 | file.enable = true;
91 | nushell.enable = true;
92 | gnupg = {
93 | enable = true;
94 | gui = true;
95 | cacheTTL = 60480000;
96 | };
97 | direnv = {
98 | enable = true;
99 | preventGC = true;
100 | };
101 | };
102 | };
103 | }
104 |
--------------------------------------------------------------------------------
/hosts/work/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 | # used to fix bluetooth
12 | # TODO: remove this when we figure out bluetooth
13 | # boot.kernelPackages = pkgs.linuxPackagesFor (pkgs.linux_latest.override {
14 | # argsOverride = rec {
15 | # src = pkgs.fetchurl {
16 | # url = "mirror://kernel/linux/kernel/v5.x/linux-${version}.tar.xz";
17 | # sha256 = "1j0lnrsj5y2bsmmym8pjc5wk4wb11y336zr9gad1nmxcr0rwvz9j";
18 | # };
19 | # version = "5.15.1";
20 | # modDirVersion = "5.15.1";
21 | # };
22 | # });
23 |
24 | boot.kernelPackages = pkgs.linuxPackages_latest;
25 |
26 | hardware.bluetooth.enable = true;
27 | networking.networkmanager.enable = true;
28 | security.rtkit.enable = true;
29 |
30 | boot = {
31 | initrd = {
32 | availableKernelModules = [ "xhci_pci" "btusb" "thunderbolt" "nvme" "usb_storage" "sd_mod" ];
33 | kernelModules = [ ];
34 | };
35 |
36 | kernelModules = [ "kvm-intel" ];
37 | extraModulePackages = [ ];
38 |
39 | kernelParams = [
40 | # fix crashing on sleep behavior< save battery
41 | "mem_sleep_default=deep"
42 | ];
43 | };
44 |
45 | fileSystems."/" =
46 | { device = "/dev/disk/by-label/nixos";
47 | fsType = "ext4";
48 | };
49 |
50 | fileSystems."/boot" =
51 | { device = "/dev/disk/by-label/boot";
52 | fsType = "vfat";
53 | };
54 |
55 | swapDevices =
56 | [ { device = "/dev/disk/by-label/swap"; }
57 | ];
58 |
59 | powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
60 | hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
61 | }
62 |
--------------------------------------------------------------------------------
/hosts/xps/default.nix:
--------------------------------------------------------------------------------
1 | # My Dell XPS 9370: 4K monitor, malfunctioning screen and trackpad
2 | { config, pkgs, lib, ... }:
3 |
4 | with lib;
5 | with lib.my;
6 | {
7 | imports = [ ./hardware-configuration.nix ../personal.nix ];
8 |
9 | networking.hostName = "xps";
10 |
11 | users.users.jake.packages = with pkgs; [ thunderbird openssl ];
12 | services.fwupd.enable = true;
13 | services.xserver.libinput.enable = true;
14 |
15 | programs.ssh = {
16 | startAgent = true;
17 | forwardX11 = true;
18 | };
19 |
20 | services.openssh.startWhenNeeded = true;
21 | services.getty.autologinUser = "jake";
22 |
23 | networking = {
24 | networkmanager = {
25 | enable = true;
26 | wifi = {
27 | powersave = false; # wifi beast mode
28 | };
29 | };
30 | };
31 |
32 | modules = {
33 | theme.active = "stilla";
34 | desktop.sway = {
35 | enable = true;
36 | fancy = true;
37 | disable-touch = true;
38 | scale = 2.0;
39 | };
40 | browsers = {
41 | default = "firefox";
42 | firefox.enable = true;
43 | };
44 | media = {
45 | documents.enable = true;
46 | graphics = {
47 | vector.enable = false;
48 | sprites.enable = false;
49 | enable = true;
50 | };
51 | recording.enable = true;
52 | spotify.enable = true;
53 | };
54 | term = {
55 | default = "alacritty";
56 | alacritty.enable = true;
57 | };
58 | media = {
59 | mpv.enable = true;
60 | # ncmpcpp.enable = true; needs fixing, not used
61 | };
62 | messengers = {
63 | rss.enable = true;
64 | matrix.enable = true;
65 | signal.enable = true;
66 | # email.enable = true;
67 | weechat.enable = true;
68 | };
69 | editors = {
70 | default = "emacsclient -c";
71 | emacs = {
72 | enable = true;
73 | daemon = true;
74 | };
75 | vim.enable = false;
76 | vscode.enable = true;
77 | };
78 |
79 | # TODO consider deleting
80 | dev = {
81 | node.enable = true;
82 | cc.enable = false;
83 | rust.enable = false; # should be project local
84 | };
85 |
86 | hardware = {
87 | remarkable.enable = true;
88 | extraHosts = {
89 | enable = true;
90 | allowSocial = true;
91 | };
92 | audio.enable = true;
93 | bluetooth.enable = true;
94 | scanner.enable = true;
95 | printer.enable = true;
96 | fs = {
97 | enable = true;
98 | ssd.enable = true;
99 | };
100 | };
101 | shell = {
102 | git.enable = true;
103 | gnupg = {
104 | enable = true;
105 | gui = true;
106 | cacheTTL = 60480000;
107 | };
108 | direnv = {
109 | enable = true;
110 | preventGC = true;
111 | };
112 | file.enable = true;
113 | fish.enable = true;
114 | };
115 | services = {
116 | docker.enable = true;
117 | syncthing.enable = true;
118 | ssh.enable = true;
119 | backup.enable = true;
120 | dnsmasq.enable = true;
121 | };
122 | };
123 | }
124 |
--------------------------------------------------------------------------------
/hosts/xps/hardware-configuration.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, inputs, modulesPath, ... }:
2 |
3 | {
4 | imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
5 | # https://github.com/yegortimoshenko/yegortimoshenko-flake/blob/master/profiles/hardware/dell-xps/9380/default.nix
6 | boot = {
7 | consoleLogLevel = 1;
8 | initrd = {
9 | availableKernelModules =
10 | [ "xhci_pci" "nvme" "rtsx_pci_sdmmc" "usb_storage" ];
11 | kernelModules = [ "dm-snapshot" "i915" ];
12 | checkJournalingFS = true;
13 | };
14 |
15 | kernelModules = [
16 | "kvm-intel"
17 | "dm-snapshot"
18 | "i915"
19 | "xboxdrv"
20 | "vboxnetadp"
21 | "vboxnetflt"
22 |
23 | # enable v4l2loopback to stream from camera
24 | "dslr-webcam"
25 | "v4l2loopback"
26 | ];
27 | kernel.sysctl = {
28 | # enable ipv6 privacy extensions and prefer using temp addresses
29 | "net.ipv6.conf.all.use_tempaddr" = 2;
30 | "fs.inotify.max_user_instances" = 8192;
31 | "fs.inotify.max_user_watches" = 16834;
32 | };
33 | kernelParams = [
34 | # disable spectre and meltdown fixes
35 | "mitigations=off"
36 | # 4k video config
37 | "video=eDP-1:3840x2160@60"
38 | # fast quiet boot
39 | "quiet"
40 | "splash"
41 | "vga=current"
42 | "i915.fastboot=1"
43 | "loglevel=3"
44 | "systemd.show_status=auto"
45 | "udev.log_priority=3"
46 | # force power savings when possible
47 | "iwlwifi.power_save=Y"
48 | "pcie_aspm=force"
49 | # Optimize xps battery; causes framebuffer issues on some devices
50 | "i915.semaphores=1"
51 | "i915.enable_fbc=1"
52 | "i915.enable_psr=2"
53 | "i915.enable_rc6=7"
54 | "i915.lvds_downclock=1"
55 | "dev.i915.perf_stream_paranoid=0"
56 |
57 | # significant amount of usb issues without this
58 | "usbcore.autosuspend=-1"
59 |
60 | # v4l2lopback settings
61 | # "vl42loopback.exclusive_caps=1"
62 | # "v4l2loopback.card_label=GPhoto2Webcam"
63 | ];
64 |
65 | extraModulePackages = [
66 | pkgs.linuxKernel.packages.linux_5_10.virtualbox
67 | # Allows for the creation of virtual video devices generated by other applications
68 | # that act like real video devices
69 | (config.boot.kernelPackages.v4l2loopback.overrideAttrs ({ ... }: {
70 | src = pkgs.fetchFromGitHub {
71 | owner = "umlaeute";
72 | repo = "v4l2loopback";
73 | rev = "10b1c7e6bda4255fdfaa187ce2b3be13433416d2";
74 | sha256 = "0xsn4yzj7lwdg0n7q3rnqpz07i9i011k2pwn06hasd45313zf8j2";
75 | };
76 | }))
77 | ];
78 |
79 | # create video device
80 | extraModprobeConfig = ''
81 | alias dslr-webcam v4l2loopback
82 | options v4l2loopback exclusive_caps=1 card_label=\"GPhoto2 Webcam\" max_buffers=2 video_nr=8,9
83 | '';
84 | };
85 |
86 | # scanning
87 | hardware = {
88 | sane.enable = true;
89 | keyboard.zsa.enable = true;
90 | opengl = {
91 | enable = true;
92 | extraPackages = with pkgs; [ vaapiIntel vaapiVdpau libvdpau-va-gl ];
93 | };
94 | # enable machine check exception error logs
95 | # mcelog.enable = true;
96 | };
97 |
98 | # CPU
99 | nix.maxJobs = lib.mkDefault 8;
100 | # "powersave" for the obvious
101 | powerManagement.cpuFreqGovernor = lib.mkDefault "performance";
102 | hardware.cpu.intel.updateMicrocode = true;
103 |
104 | # Power management
105 | environment.systemPackages = [ pkgs.acpi ];
106 | powerManagement.powertop.enable = true;
107 | # Monitor backlight control
108 | user.extraGroups = [
109 | # ZSA keyboard support without root
110 | "plugdev"
111 | ];
112 |
113 | fileSystems."/" = {
114 | device = "/dev/disk/by-label/nixos";
115 | fsType = "ext4";
116 | # keep file system from recording on file visit
117 | options = [ "noatime" ];
118 | };
119 |
120 | fileSystems."/home" = {
121 | device = "/dev/disk/by-label/home";
122 | fsType = "ext4";
123 | options = [ "noatime" ];
124 | };
125 |
126 | fileSystems."/boot" = {
127 | device = "/dev/disk/by-label/BOOT";
128 | fsType = "vfat";
129 | };
130 |
131 | swapDevices =
132 | [{ device = "/dev/disk/by-uuid/786f7e92-74b5-4327-873a-89905a173f86"; }];
133 |
134 | # Undervolt
135 |
136 | # Note that this is incredibly device specific.
137 | # If you're copying this config, there is no guarantee
138 | # that you'll be able to get away with these values.
139 | services.undervolt = {
140 | enable = true;
141 | coreOffset = -80;
142 | gpuOffset = -80;
143 | uncoreOffset = -80;
144 | };
145 |
146 | services = {
147 | # https://github.com/NixOS/nixos-hardware/pull/127
148 | throttled.enable = lib.mkDefault true;
149 | # https://wiki.archlinux.org/index.php/Dell_XPS_13_(9370)#Thermal_Throttling
150 | thermald.enable = lib.mkDefault true;
151 | };
152 | }
153 |
--------------------------------------------------------------------------------
/keys/jake.asc:
--------------------------------------------------------------------------------
1 | -----BEGIN PGP PUBLIC KEY BLOCK-----
2 |
3 | xsFNBAAAAAABEACtB3BbMTx18grI1xxJ+mvjO8jzYoUIWh6l230DiXmQ7w7+3ZJp
4 | PEh21UphqZvm/k5FwsPU5Tb+vuwofEjPZfvx0ERL1XNvrFg/2rQmGl2ccsupclMz
5 | 2uxwP47APW5amJzhVRUejTOhv9Xo7kaZGqeh3L5hbyNSfC3Ci2LpZpV1nwuOgqmC
6 | m58d68G05YrW/LIM7zPVpWRa7/1Jyplu2AYViCB5z3jt1q1s7UP2oXAh5bH5QQ5v
7 | lqdsU9GEpn0HSF0CjQdGx7PDfyeocDoI0Dy0coUCWsMDrPqURnZWzQL0eARKkaYd
8 | LHcJ2N8I3dwU1z8I/8VJ+jxm9jmOxhuwlIluXdz6VUbh+eNOmEczVwjAtTdpiyBG
9 | 2ku0labQ4TMN0G0GdV3USxC4sEfBYfzF1m2NERRAm9ySkjxbLqQ5b/85mvLUtuJ4
10 | q5hMla6gGDRRKUAWGrDlVe8G3NACARqqDIQOE36Je/u/f3HjOFtczEf5pfAUW4Ky
11 | 7tyOJYzaxErPK/zc1g2qRdVtDclgdI1IHuSFywQPeAkz0l0vTqe60+RUZT0kyQXN
12 | zvZeEZ9U8ia8kO07HfxGAu3cdW7AJI/5eZv1LXI6Xa0GYN+9BSARz6RKHjNIM9wY
13 | AqGrDExgo56UOLrHqiDRRt6ZaqBPXzBdIp6D6HHuh7oggexINXoRvHaMWwARAQAB
14 | zSlyb290IChJbXBvcnRlZCBmcm9tIFNTSCkgPHJvb3RAbG9jYWxob3N0PsLBYgQT
15 | AQgAFgUCAAAAAAkQ3FAML6jGwAsCGw8CGQEAAEGWEAAodNwAx+N2CpzdHSo9nOQl
16 | O/bf3chrqukWc26e8Q/0TtlOhO6YzkWM+h5sBfmYrH7qCzjN9h8flryzewCJ9Utu
17 | rgTrt3MVoe6cM5Rw9GiTTTVXEc2z4ieVcvCdqr5XlPAfDqyN7x4naj9W/MzM3On9
18 | LnSXt5/PJxYsqVnUCDcVkN3UwgZBuI9qNZltC7Iii2YGU2j8S9dobWTvnhdc1A4S
19 | L5j04OCDT/biVeMZUAzLqLFotsjx0VHkzsZbczXnlW/qNX/SR0ltzGbOrwFp9tlG
20 | RZ6H+i7BTL/kT82xiypJftgiI97pj7sH5kzRajK9IoexVZ/ICzXFYuQ2K0+W1uGV
21 | vbk/CbzTf4a7vB2V3cAxj5B2vVhQ9M6lEt50QhOCV9KH/9aP2H1vEa5VzxX3XoKz
22 | 0OU/uecCYSudTLUX5d23ScGokLNJ0kLSz3AOiFIbYuCYyedIW6iu0OmZIW2EQLjv
23 | XxBDnlPJZ/jLzUNRN9bKXDWXWIBKWLFb48cBpkK+jDXJRDcpLe/1AbnZiFhl9KL+
24 | 11C6r8ahLQUMHlbDGW6Tlm36QeOOrQn4WT5X5MwWL/X5z0ejux/L2uK6QDi+x5R5
25 | Y/645q/4gwsXa7hggYAX6wNY5WflNuOZcmmrIG36URAxx+iT/Csg4ATwvmzsVK2R
26 | 5XYg3Q7a/7mlpcSgH43xOQ==
27 | =snLB
28 | -----END PGP PUBLIC KEY BLOCK-----
--------------------------------------------------------------------------------
/lib/attrs.nix:
--------------------------------------------------------------------------------
1 | { lib, ... }:
2 |
3 | with builtins;
4 | with lib;
5 |
6 | rec {
7 | # attrsToList
8 | attrsToList = attrs:
9 | mapAttrsToList (name: value: { inherit name value; }) attrs;
10 |
11 | # mapFilterAttrs ::
12 | # (name -> value -> bool)
13 | # (name -> value -> { name = any; value = any; })
14 | # attrs
15 | mapFilterAttrs = pred: f: attrs: filterAttrs pred (mapAttrs' f attrs);
16 |
17 | # Generate an attribute set by mapping a function over a list of values.
18 | genAttrs' = values: f: listToAttrs (map f values);
19 |
20 | # anyAttrs :: (name -> value -> bool) attrs
21 | anyAttrs = pred: attrs:
22 | any (attr: pred attr.name attr.value) (attrsToList attrs);
23 |
24 | # countAttrs :: (name -> value -> bool) attrs
25 | countAttrs = pred: attrs:
26 | count (attr: pred attr.name attr.value) (attrsToList attrs);
27 | }
28 |
--------------------------------------------------------------------------------
/lib/default.nix:
--------------------------------------------------------------------------------
1 | { inputs, lib, pkgs, ... }:
2 |
3 | let
4 | inherit (lib) makeExtensible attrValues foldr;
5 | inherit (modules) mapModules;
6 |
7 | modules = import ./modules.nix {
8 | inherit lib;
9 | self.attrs = import ./attrs.nix { inherit lib; self = {}; };
10 | };
11 |
12 | mylib = makeExtensible (self:
13 | with self; (mapModules ./.
14 | (file: import file { inherit self lib pkgs inputs modules; })));
15 |
16 | in
17 | mylib.extend
18 | (self: super:
19 | foldr (a: b: a // b) {} (attrValues super))
20 |
--------------------------------------------------------------------------------
/lib/generators.nix:
--------------------------------------------------------------------------------
1 | { lib, pkgs, ... }:
2 |
3 | with builtins;
4 | with lib;
5 | {
6 | toCSSFile = file:
7 | let fileName = baseNameOf file;
8 | compiledStyles =
9 | pkgs.runCommand "compileScssFile"
10 | { buildInputs = [ sass ]; } ''
11 | mkdir "$out"
12 | scss --sourcekkmap=none \
13 | --no-cache \
14 | --style compressed \
15 | --default-encoding utf-8 \
16 | "${file}" \
17 | >>"$out/${fileName}.css"
18 | '';
19 | in "${compiledStyles}/${fileName}";
20 |
21 | toFilteredImage = imageFile: options:
22 | let result = "result.png";
23 | filteredImage =
24 | pkgs.runCommand "filterWallpaper"
25 | { buildInputs = [ pkgs.imagemagick ]; } ''
26 | mkdir "$out"
27 | convert ${options} ${imageFile} $out/${result}
28 | '';
29 | in "${filteredImage}/${result}";
30 | }
31 |
--------------------------------------------------------------------------------
/lib/makeSimpleWebApp.nix:
--------------------------------------------------------------------------------
1 | { pkgs, ... }:
2 |
3 | # Source: https://github.com/bjornfor/nixos-config/blob/master/lib/default.nix
4 |
5 | {
6 | makeSimpleWebApp = { server, icon ? null, comment ? null
7 | , desktopName ? comment, categories ? null, browser ? "chromium-browser" }:
8 | pkgs.makeDesktopItem ({
9 | name = server;
10 | exec = "${browser} --app=https://${server}/";
11 | extraEntries = ''
12 | StartupWMClass=${server}
13 | '';
14 | } // (if icon != null then { inherit icon; } else { })
15 | // (if comment != null then { inherit comment; } else { })
16 | // (if desktopName != null then { inherit desktopName; } else { })
17 | // (if categories != null then { inherit categories; } else { }));
18 | }
19 |
--------------------------------------------------------------------------------
/lib/modules.nix:
--------------------------------------------------------------------------------
1 | { self, lib, ... }:
2 |
3 | let
4 | inherit (builtins) attrValues readDir pathExists concatLists;
5 | inherit (lib) id mapAttrsToList filterAttrs hasPrefix hasSuffix nameValuePair removeSuffix;
6 | inherit (self.attrs) mapFilterAttrs;
7 | in
8 | rec {
9 | mapModules = dir: fn:
10 | mapFilterAttrs
11 | (n: v:
12 | v != null &&
13 | !(hasPrefix "_" n))
14 | (n: v:
15 | let path = "${toString dir}/${n}"; in
16 | if v == "directory" && pathExists "${path}/default.nix"
17 | then nameValuePair n (fn path)
18 | else if v == "regular" &&
19 | n != "default.nix" &&
20 | hasSuffix ".nix" n
21 | then nameValuePair (removeSuffix ".nix" n) (fn path)
22 | else nameValuePair "" null)
23 | (readDir dir);
24 |
25 | mapModules' = dir: fn:
26 | attrValues (mapModules dir fn);
27 |
28 | mapModulesRec = dir: fn:
29 | mapFilterAttrs
30 | (n: v:
31 | v != null &&
32 | !(hasPrefix "_" n))
33 | (n: v:
34 | let path = "${toString dir}/${n}"; in
35 | if v == "directory"
36 | then nameValuePair n (mapModulesRec path fn)
37 | else if v == "regular" && n != "default.nix" && hasSuffix ".nix" n
38 | then nameValuePair (removeSuffix ".nix" n) (fn path)
39 | else nameValuePair "" null)
40 | (readDir dir);
41 |
42 | mapModulesRec' = dir: fn:
43 | let
44 | dirs =
45 | mapAttrsToList
46 | (k: _: "${dir}/${k}")
47 | (filterAttrs
48 | (n: v: v == "directory" && !(hasPrefix "_" n))
49 | (readDir dir));
50 | files = attrValues (mapModules dir id);
51 | paths = files ++ concatLists (map (d: mapModulesRec' d id) dirs);
52 | in map fn paths;
53 | }
54 |
--------------------------------------------------------------------------------
/lib/nixos.nix:
--------------------------------------------------------------------------------
1 | { inputs, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let system = "x86_64-linux";
6 | in {
7 | mkHost = path: attrs @ { system ? system, ... }:
8 | let hostname = (removeSuffix ".nix" (baseNameOf path)); in
9 | nixosSystem {
10 | inherit system;
11 | specialArgs = { inherit lib inputs; };
12 | modules = [
13 | {
14 | nixpkgs.pkgs = pkgs;
15 | networking.hostName = mkDefault hostname;
16 | }
17 | (filterAttrs (n: v: !elem n [ "system" ]) attrs)
18 | ../.
19 | (import path)
20 | ];
21 | };
22 |
23 | mapHosts = dir: attrs @ { system ? system, ... }:
24 | mapModules dir
25 | (hostPath: mkHost hostPath attrs);
26 | }
27 |
--------------------------------------------------------------------------------
/lib/options.nix:
--------------------------------------------------------------------------------
1 | { lib, ... }:
2 |
3 | let
4 | inherit (lib) mkOption types;
5 | in
6 | rec {
7 | mkOpt = type: default:
8 | mkOption { inherit type default; };
9 |
10 | mkOpt' = type: default: description:
11 | mkOption { inherit type default description; };
12 |
13 | mkBoolOpt = default: mkOption {
14 | inherit default;
15 | type = types.bool;
16 | example = true;
17 | };
18 | }
19 |
--------------------------------------------------------------------------------
/lib/paths.nix:
--------------------------------------------------------------------------------
1 | { self, lib, modules, ... }:
2 |
3 | with builtins;
4 | with lib; rec {
5 | # ...
6 | dotFilesDir = toString ../.;
7 | modulesDir = "${dotFilesDir}/modules";
8 | configDir = "${dotFilesDir}/config";
9 | binDir = "${dotFilesDir}/bin";
10 | themesDir = "${modulesDir}/themes";
11 | username = "jake";
12 | homeDir = "/home/${
13 | let
14 | name = getEnv "USERNAME";
15 | in
16 | if elem name [ username "root" ] then username
17 | else
18 | name
19 | }";
20 |
21 | secrets = import ./secrets.nix { inherit lib; };
22 | }
23 |
--------------------------------------------------------------------------------
/lib/secrets.nix:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakeisnt/nixcfg/e9230d4f90a855a290882a6e7862c593a114cf5e/lib/secrets.nix
--------------------------------------------------------------------------------
/modules/browsers/brave.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.browsers.brave;
6 | in {
7 | options.modules.browsers.brave = { enable = mkBoolOpt false; };
8 | config = mkIf cfg.enable {
9 | modules.browsers.chromium-help.enable = true;
10 | user.packages = with pkgs; [ brave ];
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/modules/browsers/chrome.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.browsers.chrome;
6 | chrome = pkgs.google-chrome;
7 | chrome-improvin = pkgs.writeShellScriptBin "chrome-improvin" ''
8 | exec ${chrome}/bin/google-chrome-unstable --profile-directory="Profile 2" &
9 | '';
10 | chrome-default = pkgs.writeShellScriptBin "chrome-default" ''
11 | exec ${chrome}/bin/google-chrome-unstable --profile-directory="Default" &
12 | '';
13 | in {
14 | options.modules.browsers.chrome = { enable = mkBoolOpt false; };
15 | config = mkIf cfg.enable {
16 | modules.browsers.chromium-help.enable = true;
17 | # The profiles here correspond to profiles created dynamically when opening Chrome and signing in.
18 | user.packages = with pkgs; [
19 | chrome
20 | chrome-improvin
21 | chrome-default
22 | (makeDesktopItem {
23 | name = "chrome-improvin";
24 | desktopName = "Chrome (Improvin)";
25 | genericName = "Open a Chrome window to the Improvin workspace";
26 | icon = "google-chrome-unstable";
27 | exec = "${chrome-improvin}/bin/chrome-improvin";
28 | categories = ["Network"];
29 | })
30 | (makeDesktopItem {
31 | name = "chrome-default";
32 | desktopName = "Chrome (Default)";
33 | genericName = "Open a Chrome window to the default workspace";
34 | icon = "google-chrome-unstable";
35 | exec = "${chrome-default}/bin/chrome-default";
36 | categories = ["Network"];
37 | })
38 | ];
39 | };
40 | }
41 |
--------------------------------------------------------------------------------
/modules/browsers/chromium-help.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 |
3 | # settings for all chromium browsers.
4 |
5 | with lib;
6 | with lib.my;
7 | let cfg = config.modules.browsers.chromium-help;
8 | in {
9 | options.modules.browsers.chromium-help = {
10 | enable = mkBoolOpt false;
11 | };
12 |
13 | config = mkIf cfg.enable {
14 | # TODO: Enable wayland for chromium. Currently this is a saved browser setting, but it might not carry over.
15 | programs.chromium = {
16 | enable = true;
17 | # TODO: change to something more secure than google
18 | defaultSearchProviderSearchURL =
19 | "https://encrypted.google.com/search?q={searchTerms}&{google:RLZ}{google:originalQueryForSuggestion}{google:assistedQueryStats}{google:searchFieldtrialParameter}{google:searchClient}{google:sourceId}{google:instantExtendedEnabledParameter}ie={inputEncoding}";
20 | defaultSearchProviderSuggestURL =
21 | "https://encrypted.google.com/complete/search?output=chrome&q={searchTerms}";
22 | homepageLocation = "https://github.com";
23 | extensions = [
24 | "cjpalhdlnbpafiamejdnhcphjbkeiagm" # ublock origin
25 | "kkkjlfejijcjgjllecmnejhogpbcigdc" # org-capture
26 | "dbepggeogbaibhgnhhndojpepiihcmeb" # vimium
27 | "ddehdnnhjimbggeeenghijehnpakijod" # remove scrollbar
28 | # "ikdgincnppajmpmnhfheflannaiapmlm" # ampie: social interaction with webpages
29 | # ^ cool, but it always gets in the way!
30 | # custom css;
31 | # ::-webkit-scrollbar {
32 | # display: none;
33 | # }
34 | # must be added to Rescroller extension
35 | # also sign into lastfm scrobbler
36 | ];
37 |
38 | extraOpts = {
39 | # I like having my information synced across browser sessions,
40 | # and I'm okay with surrendering some information to Google to do so.
41 | # The other settings may not work without managed browser control, though.
42 |
43 | # "BrowserSignin" = 0;
44 | # "SyncDisabled" = true;
45 |
46 | # Definitely want to turn off these though.
47 | "PasswordManagerEnabled" = false;
48 | "CloudReportingEnabled" = false;
49 | "SafeBrowsingEnabled" = false;
50 | "ReportSafeBrowsingData" = false;
51 | "AllowDinosaurEasterEgg" = false; # : (
52 | "AllowOutdatedPlugins" = true;
53 | "DefaultBrowserSettingEnabled" = false;
54 |
55 | # voice assistant
56 | "VoiceInteractionContextEnabled" = false;
57 | "VoiceInteractionHotwordEnabled" = false;
58 | "VoiceInteractionQuickAnswersEnabled" = false;
59 | };
60 | };
61 | };
62 | }
63 |
--------------------------------------------------------------------------------
/modules/browsers/default.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.browsers;
6 | in {
7 | options.modules.browsers = {
8 | default = mkOpt (with types; nullOr str) null;
9 | };
10 |
11 | config = mkIf (cfg.default != null) {
12 | env.BROWSER = cfg.default;
13 | };
14 | }
15 |
--------------------------------------------------------------------------------
/modules/browsers/netsurf.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | # a JavaScript-free web browser.
4 | with lib;
5 | with lib.my;
6 | let cfg = config.modules.browsers.netsurf;
7 | in {
8 | options.modules.browsers.netsurf = { enable = mkBoolOpt false; };
9 | config = mkIf cfg.enable { user.packages = with pkgs; [ netsurf-browser ]; };
10 | }
11 |
--------------------------------------------------------------------------------
/modules/desktop/README.org:
--------------------------------------------------------------------------------
1 | #+TITLE: Desktop
2 |
3 | Utilities only relevant to the desktop (only usable as a GUI).
4 |
--------------------------------------------------------------------------------
/modules/desktop/default.nix:
--------------------------------------------------------------------------------
1 | { config, options, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.desktop;
6 | in {
7 | config = mkIf config.modules.desktop.sway.enable {
8 | user.packages = with pkgs; [ feh ];
9 |
10 | fonts = {
11 | fontDir.enable = true;
12 | enableGhostscriptFonts = true;
13 | packages = with pkgs; [ nerdfonts noto-fonts ];
14 | };
15 |
16 | ## Apps/Services
17 | # Try really hard to get QT to respect my GTK theme.
18 | env.GTK_DATA_PREFIX = [ "${config.system.path}" ];
19 | env.QT_QPA_PLATFORMTHEME = "gtk2";
20 | qt = {
21 | style = "gtk2";
22 | platformTheme = "gtk2";
23 | };
24 |
25 | services.xserver.displayManager.sessionCommands = ''
26 | # GTK2_RC_FILES must be available to the display manager.
27 | export GTK2_RC_FILES="$XDG_CONFIG_HOME/gtk-2.0/gtkrc"
28 | '';
29 |
30 | # set user dirs
31 | home.configFile = {
32 | "user-dirs.dirs".source = "${configDir}/xdg/user-dirs.dirs";
33 | };
34 | };
35 | }
36 |
--------------------------------------------------------------------------------
/modules/desktop/gnome.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let
6 | cfg = config.modules.desktop.gnome;
7 | colors = config.modules.theme.color;
8 | in {
9 | options.modules.desktop.gnome = { enable = mkBoolOpt false; };
10 |
11 | config = mkIf cfg.enable {
12 | # security.pam.services.gdm.enableGnomeKeyring = true;
13 | # security.pam.services = with pkgs.gnome3; [{
14 | # name = "gnome_keyring";
15 | # text = ''
16 | # auth optional ${gnome_keyring}/lib/security/pam_gnome_keyring.so
17 | # session optional ${gnome_keyring}/lib/security/pam_gnome_keyring.so auto_start
18 | # password optional ${gnome_keyring}/lib/security/pam_gnome_keyring.so
19 | # '';
20 | # }];
21 | services = {
22 | # gnome keyring is not available anymore?
23 | # gnome3.gnome-keyring.enable = true;
24 | xserver = {
25 | enable = true;
26 | xkbOptions = "caps:swapescape";
27 | displayManager.gdm.enable = true;
28 | # desktopManager.gnome3.enable = true;
29 |
30 | # todo: device-specific
31 | # monitorSection = ''
32 | # DisplaySize 508 285
33 | # '';
34 | };
35 | };
36 | };
37 | }
38 |
--------------------------------------------------------------------------------
/modules/desktop/wayfire.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let
6 | cfg = config.modules.desktop.wayfire;
7 | colors = config.modules.theme.color;
8 | startwf = (pkgs.writeTextFile {
9 | name = "startwf";
10 | destination = "/bin/startwf";
11 | executable = true;
12 | text = ''
13 | #! ${pkgs.bash}/bin/bash
14 |
15 | # first import environment variables from the login manager
16 | systemctl --user import-environment
17 | # then start the service
18 | exec systemctl --user start wf.service
19 | '';
20 | });
21 | in {
22 | options.modules.desktop.wayfire = { enable = mkBoolOpt false; };
23 |
24 | config = mkIf cfg.enable {
25 | modules.wayland.enable = true;
26 | modules.wayland.mako.enable = true;
27 | modules.wayland.swaylock.enable = true;
28 | modules.wayland.waybar.enable = true;
29 | modules.wayland.kanshi.enable = true;
30 |
31 | user.packages = with pkgs; [ wayfire ];
32 |
33 | env.XDG_CURRENT_DESKTOP = "wayfire";
34 |
35 | systemd.user.targets.wayfire-session = {
36 | enable = true;
37 | description = "Wayfire compositor session";
38 | documentation = [ "man:systemd.special(7)" ];
39 |
40 | bindsTo = [ "graphical-session.target" ];
41 | wants = [ "graphical-session-pre.target" ];
42 | after = [ "graphical-session-pre.target" ];
43 | requiredBy =
44 | [ "graphical-session.target" "graphical-session-pre.target" ];
45 | };
46 |
47 | systemd.user.services.wf = {
48 | enable = true;
49 | description = "Wayfire - Wayland window manager";
50 | bindsTo = [ "graphical-session.target" ];
51 | wants = [ "graphical-session-pre.target" ];
52 | after = [ "graphical-session-pre.target" ];
53 | # We explicitly unset PATH here, as we want it to be set by
54 | # systemctl --user import-environment in startsway
55 | environment.PATH = lib.mkForce null;
56 | serviceConfig = {
57 | Type = "simple";
58 | ExecStart =
59 | "${pkgs.dbus}/bin/dbus-run-session ${pkgs.wayfire}/bin/wayfire";
60 | Restart = "on-failure";
61 | RestartSec = 1;
62 | TimeoutStopSec = 10;
63 | };
64 | };
65 |
66 | modules.shell.fish.loginInit = ''
67 | if status is-login
68 | if test -z "$DISPLAY" -a "$XDG_VTNR" = 1
69 | sway
70 | end
71 | end
72 | '';
73 |
74 | home.configFile = {
75 | "wayfire/config" = { source = "${configDir}/wayfire/config"; };
76 | };
77 | };
78 | }
79 |
--------------------------------------------------------------------------------
/modules/dev/android.nix:
--------------------------------------------------------------------------------
1 | { config, options, lib, pkgs, ... }:
2 | # https://nixos.wiki/wiki/Android
3 | with lib;
4 | with lib.my;
5 | let
6 | cfg = config.modules.dev.android;
7 | androidSdk = pkgs.androidenv.androidPkgs_9_0.androidsdk;
8 | platformTools = pkgs.androidenv.androidPkgs_9_0.platform-tools;
9 | in {
10 | options.modules.dev.android = { enable = mkBoolOpt false; };
11 |
12 | config = mkIf cfg.enable {
13 | user.packages = with pkgs; [
14 | # use the development version of android-studio (needed for StreetComplete)
15 | androidStudioPackages.dev
16 | androidSdk
17 | platformTools
18 | glibc
19 | openjdk8
20 | ];
21 | programs.adb.enable = true;
22 | user.extraGroups = [ "adbusers" ];
23 | services.udev.packages = [ pkgs.android-udev-rules ];
24 |
25 | environment.variables = {
26 | ANDROID_JAVA_HOME = "${pkgs.openjdk8.home}";
27 | ANDROID_SDK_ROOT = "${androidSdk}";
28 | GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${androidSdk}/libexec/android-sdk/build-tools/28.0.3/aapt2";
29 | # Increase max memory sizes for gradle builds
30 | JAVA_OPTIONS = "-Xms1024m -Xmx4096m";
31 | # https://github.com/swaywm/sway/issues/595
32 | _JAVA_AWT_WM_NONREPARENTING = "1";
33 | };
34 |
35 | # TODO: Redundant?
36 | env = {
37 | ANDROID_JAVA_HOME = "${pkgs.openjdk8.home}";
38 | ANDROID_SDK_ROOT = "${androidSdk}";
39 |
40 | # override the aapt2 that gradle uses with the nix-shipped version
41 | GRADLE_OPTS =
42 | "-Dorg.gradle.project.android.aapt2FromMavenOverride=${androidSdk}/libexec/android-sdk/build-tools/28.0.3/aapt2";
43 | };
44 | };
45 | }
46 |
--------------------------------------------------------------------------------
/modules/dev/cc.nix:
--------------------------------------------------------------------------------
1 | # modules/dev/cc.nix --- C & C++
2 | #
3 | # I love C. I tolerate C++. I adore C with a few choice C++ features tacked on.
4 | # Liking C/C++ seems to be an unpopular opinion. It's my guilty secret, so don't
5 | # tell anyone pls.
6 |
7 | { config, options, lib, pkgs, ... }:
8 |
9 | with lib;
10 | with lib.my;
11 | let cfg = config.modules.dev.cc;
12 | in {
13 | options.modules.dev.cc = { enable = mkBoolOpt false; };
14 |
15 | config = mkIf cfg.enable {
16 | user.packages = with pkgs; [
17 | clang
18 | gcc
19 | bear
20 | gdb
21 | cmake
22 | llvmPackages.libcxx
23 |
24 | # :lang cc
25 | ccls
26 | ];
27 | };
28 | }
29 |
--------------------------------------------------------------------------------
/modules/dev/clojure.nix:
--------------------------------------------------------------------------------
1 | # modules/dev/clojure.nix --- https://clojure.org/
2 | #
3 | # I use clojure now > : )
4 |
5 | { config, options, lib, pkgs, my, ... }:
6 |
7 | with lib;
8 | with lib.my;
9 | let cfg = config.modules.dev.clojure;
10 | in {
11 | options.modules.dev.clojure = { enable = mkBoolOpt false; };
12 |
13 | config = mkIf cfg.enable {
14 | user.packages = with pkgs; [ jdk17 clojure-lsp clojure joker leiningen ];
15 | };
16 | }
17 |
--------------------------------------------------------------------------------
/modules/dev/lua.nix:
--------------------------------------------------------------------------------
1 | # modules/dev/lua.nix --- https://www.lua.org/
2 | #
3 | # I use lua for modding, awesomewm or Love2D for rapid gamedev prototyping (when
4 | # godot is overkill and I have the luxury of avoiding JS). I write my Love games
5 | # in moonscript to get around lua's idiosynchrosies. That said, I install love2d
6 | # on a per-project basis.
7 |
8 | { config, options, lib, pkgs, ... }:
9 |
10 | with lib;
11 | with lib.my;
12 | let
13 | cfg = config.modules.dev.lua;
14 | in
15 | {
16 | options.modules.dev.lua = {
17 | enable = mkBoolOpt false;
18 | love2D.enable = mkBoolOpt false;
19 | };
20 |
21 | config = mkIf cfg.enable {
22 | user.packages = with pkgs; [
23 | lua
24 | luaPackages.moonscript
25 | (mkIf cfg.love2D.enable love2d)
26 | ];
27 | };
28 | }
29 |
--------------------------------------------------------------------------------
/modules/dev/node.nix:
--------------------------------------------------------------------------------
1 | # modules/dev/node.nix --- https://nodejs.org/en/
2 | #
3 | # JS is one of those "when it's good, it's alright, when it's bad, it's a
4 | # disaster" languages.
5 |
6 | { config, options, lib, pkgs, ... }:
7 |
8 | with lib;
9 | with lib.my;
10 | let cfg = config.modules.dev.node;
11 | in {
12 | options.modules.dev.node = { enable = mkBoolOpt false; };
13 |
14 | config = mkIf cfg.enable {
15 | user.packages = with pkgs; [
16 | nodejs
17 | yarn
18 |
19 | # :lang javascript
20 | nodePackages.typescript-language-server
21 | ];
22 |
23 | env.NPM_CONFIG_USERCONFIG = "$XDG_CONFIG_HOME/npm/config";
24 | env.NPM_CONFIG_CACHE = "$XDG_CACHE_HOME/npm";
25 | env.NPM_CONFIG_TMP = "$XDG_RUNTIME_DIR/npm";
26 | env.NPM_CONFIG_PREFIX = "$XDG_CACHE_HOME/npm";
27 | env.NODE_REPL_HISTORY = "$XDG_CACHE_HOME/node/repl_history";
28 | env.PATH = [ "$(yarn global bin)" ];
29 |
30 | # Run locally installed bin-script, e.g. n coffee file.coffee
31 | environment.shellAliases = {
32 | n = ''PATH="$(npm bin):$PATH"'';
33 | ya = "yarn";
34 | };
35 |
36 | home.configFile."npm/config".text = ''
37 | cache=$XDG_CACHE_HOME/npm
38 | prefix=$XDG_DATA_HOME/npm
39 | '';
40 | };
41 | }
42 |
--------------------------------------------------------------------------------
/modules/dev/python.nix:
--------------------------------------------------------------------------------
1 | # modules/dev/python.nix --- https://godotengine.org/
2 | #
3 | # Python's ecosystem repulses me. The list of environment "managers" exhausts
4 | # me. The Py2->3 transition make trainwrecks jealous. But SciPy, NumPy, iPython
5 | # and Jupyter can have my babies. Every single one.
6 |
7 | { config, options, lib, pkgs, my, ... }:
8 |
9 | with lib;
10 | with lib.my;
11 | let cfg = config.modules.dev.python;
12 | in {
13 | options.modules.dev.python = {
14 | enable = mkBoolOpt false;
15 | };
16 |
17 | config = mkIf cfg.enable {
18 | user.packages = with pkgs; [
19 | python37
20 | python37Packages.pip
21 | python37Packages.ipython
22 | python37Packages.black
23 | python37Packages.setuptools
24 | python37Packages.pylint
25 | python37Packages.poetry
26 | ];
27 |
28 | env.IPYTHONDIR = "$XDG_CONFIG_HOME/ipython";
29 | env.PIP_CONFIG_FILE = "$XDG_CONFIG_HOME/pip/pip.conf";
30 | env.PIP_LOG_FILE = "$XDG_DATA_HOME/pip/log";
31 | env.PYLINTHOME = "$XDG_DATA_HOME/pylint";
32 | env.PYLINTRC = "$XDG_CONFIG_HOME/pylint/pylintrc";
33 | env.PYTHONSTARTUP = "$XDG_CONFIG_HOME/python/pythonrc";
34 | env.PYTHON_EGG_CACHE = "$XDG_CACHE_HOME/python-eggs";
35 | env.JUPYTER_CONFIG_DIR = "$XDG_CONFIG_HOME/jupyter";
36 |
37 | environment.shellAliases = {
38 | py = "python";
39 | py3 = "python3";
40 | po = "poetry";
41 | ipy = "ipython --no-banner";
42 | ipylab = "ipython --pylab=qt5 --no-banner";
43 | };
44 | };
45 | }
46 |
--------------------------------------------------------------------------------
/modules/dev/rust.nix:
--------------------------------------------------------------------------------
1 | # modules/dev/rust.nix --- https://rust-lang.org
2 | #
3 | # Oh Rust. The light of my life, fire of my loins. Years of C++ has conditioned
4 | # me to believe there was no hope left, but the gods have heard us. Sure, you're
5 | # not going to replace C/C++. Sure, your starlight popularity has been
6 | # overblown. Sure, macros aren't namespaced, cargo bypasses crates.io, and there
7 | # is no formal proof of your claims for safety, but who said you have to solve
8 | # all the world's problems to be wonderful?
9 |
10 | { config, options, lib, pkgs, ... }:
11 |
12 | with lib;
13 | with lib.my;
14 | let cfg = config.modules.dev.rust;
15 | in {
16 | options.modules.dev.rust = { enable = mkBoolOpt false; };
17 |
18 | config = mkIf cfg.enable {
19 | user.packages = with pkgs; [ rustup rustfmt unstable.rust-analyzer ];
20 |
21 | env.RUSTUP_HOME = "$XDG_DATA_HOME/rustup";
22 | env.CARGO_HOME = "$XDG_DATA_HOME/cargo";
23 | env.PATH = [ "$CARGO_HOME/bin" ];
24 |
25 | environment.shellAliases = {
26 | rs = "rustc";
27 | rsp = "rustup";
28 | ca = "cargo";
29 | };
30 | };
31 | }
32 |
--------------------------------------------------------------------------------
/modules/editors/default.nix:
--------------------------------------------------------------------------------
1 | { config, options, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.editors;
6 | secrets = lib.my.secrets;
7 | in {
8 | options.modules.editors = { default = mkOpt types.str "emacsclient -c"; };
9 |
10 | config = {
11 | env.EDITOR = cfg.default;
12 | user.packages = with pkgs; [wakatime];
13 |
14 | environment.shellAliases = {
15 | wakatime-cli =
16 | "${pkgs.wakatime}/bin/wakatime-cli --key ${secrets.wakatime.apiKey}";
17 | wakatime =
18 | "${pkgs.wakatime}/bin/wakatime-cli --key ${secrets.wakatime.apiKey}";
19 | };
20 | };
21 | }
22 |
--------------------------------------------------------------------------------
/modules/editors/emacs.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, inputs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | # emacs (~pgtk~) + native-comp
6 | # this was `29.2`, but the emacs interface keeps changing in backwards-incompatible ways
7 | let
8 | myemacs0 = pkgs.emacs29-pgtk;
9 | emacsWPkgs = (pkgs.emacsPackagesFor myemacs0).emacsWithPackages;
10 | myemacs = emacsWPkgs (epkgs: (with epkgs; [ vterm pdf-tools org-pdftools ]));
11 |
12 | cfg = config.modules.editors.emacs;
13 | # Install Doom Emacs if not already configured, placing the correct things in the system path.
14 | daemonScript = pkgs.writeScriptBin "emacs" ''
15 | #!${pkgs.bash}/bin/bash -l
16 | export PATH=$PATH:${lib.makeBinPath [ pkgs.git pkgs.sqlite pkgs.unzip ]}
17 | export SHELL=${pkgs.bash}/bin/bash
18 | if [ ! -d $HOME/.emacs.d/.git ]; then
19 | mkdir -p $HOME/.emacs.d
20 | git -C $HOME/.emacs.d init
21 | fi
22 | if [ ! -d $HOME/.config/doom ]; then
23 | git clone git@github.com:jakeisnt/doom.d.git $HOME/.config/doom
24 | fi
25 | if [ $(git -C $HOME/.emacs.d rev-parse HEAD) != ${pkgs.doomEmacsRevision} ]; then
26 | git -C $HOME/.emacs.d fetch https://github.com/hlissner/doom-emacs.git || true
27 | git -C $HOME/.emacs.d checkout ${pkgs.doomEmacsRevision} || true
28 | $HOME/.emacs.d/bin/doom sync || true
29 | YES=1 FORCE=1 $HOME/.emacs.d/bin/doom sync -u &
30 | fi
31 |
32 | exec ${myemacs}/bin/emacs --daemon
33 | '';
34 |
35 | in {
36 | options.modules.editors.emacs = {
37 | enable = mkBoolOpt false;
38 | daemon = mkBoolOpt false;
39 | doom = {
40 | enable = mkBoolOpt true;
41 | fromSSH = mkBoolOpt false;
42 | };
43 | };
44 |
45 | config = mkIf cfg.enable {
46 | nixpkgs.overlays = [
47 | inputs.emacs-overlay.overlay
48 | inputs.nur.overlay
49 | ];
50 |
51 | # enable tree sitter grammars
52 | modules.editors.tree-sitter.enable = true;
53 |
54 | services.emacs = mkIf cfg.daemon {
55 | enable = true;
56 | install = false;
57 | package = daemonScript;
58 | defaultEditor = true;
59 | };
60 |
61 | user.packages = with pkgs; [
62 | binutils # native-comp needs 'as', provided by this
63 | myemacs
64 | daemonScript
65 | direnv # required for nix dev envintegration
66 |
67 | ## Doom dependencies
68 | git
69 | (ripgrep.override { withPCRE2 = true; })
70 | gnutls # for TLS connectivity
71 |
72 | ## Optional dependencies
73 | fd # faster projectile indexing
74 | imagemagick # for image-dired
75 | (mkIf (config.programs.gnupg.agent.enable)
76 | pinentry-emacs) # in-emacs gnupg prompts
77 | zstd # for undo-fu-session/undo-tree compression
78 |
79 | ## Module dependencies
80 | # :checkers spell
81 | (aspellWithDicts (ds: with ds; [ en en-computers en-science ]))
82 | # :checkers grammar
83 | languagetool
84 | # :tools editorconfig
85 | editorconfig-core-c # per-project style config
86 | # :tools lookup & :lang org +roam
87 | sqlite
88 | # :lang latex & :lang org (latex previews)
89 | texlive.combined.scheme-medium
90 | # :lang rust
91 | # org +gnuplot
92 | gnuplot
93 | # org +pandoc
94 | pandoc
95 | # graphviz
96 | graphviz
97 |
98 | # for vterm
99 | libvterm
100 | libtool
101 |
102 | # for org-roam graph
103 | graphviz
104 |
105 | # presumably to build emacs
106 | gcc
107 |
108 | # copilot
109 | nodejs
110 |
111 | # other project searching
112 | fzf
113 | ];
114 |
115 | env.PATH = [ "$XDG_CONFIG_HOME/emacs/bin" ];
116 | fonts.packages = [ pkgs.emacs-all-the-icons-fonts ];
117 | };
118 | }
119 |
--------------------------------------------------------------------------------
/modules/editors/tree-sitter.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, inputs, ... }:
2 |
3 | # Fetch and compile tree-sitter grammars ahead of time rather than with a stateful configuration.
4 | # Inspired by https://github.com/Mic92/dotfiles.
5 |
6 | with lib;
7 | with lib.my;
8 |
9 | let
10 | treeSitterGrammars = pkgs.runCommandLocal "grammars" {} ''
11 | mkdir -p $out/bin
12 | ${lib.concatStringsSep "\n"
13 | (lib.mapAttrsToList (name: src: "ln -s ${src}/parser $out/bin/${name}.so") pkgs.tree-sitter.builtGrammars)}
14 | '';
15 | langs = [
16 | "bash"
17 | "c"
18 | "c-sharp"
19 | "css"
20 | "go"
21 | "html"
22 | "java"
23 | "javascript"
24 | "jsdoc"
25 | "json"
26 | "ocaml"
27 | "python"
28 | "ruby"
29 | "rust"
30 | "scala"
31 | "typescript"
32 | "org-nvim"
33 | "clojure"
34 | "commonlisp"
35 | ];
36 |
37 | grammars = lib.getAttrs (map (lang: "tree-sitter-${lang}") langs) pkgs.tree-sitter.builtGrammars;
38 | cfg = config.modules.editors.tree-sitter;
39 |
40 | in {
41 | options.modules.editors.tree-sitter = {
42 | enable = mkBoolOpt false;
43 | };
44 |
45 | config = mkIf cfg.enable {
46 | user.packages = with pkgs; [ tree-sitter ];
47 | home.file.".tree-sitter".source = treeSitterGrammars;
48 | home.configFile."tree-sitter" = {
49 | source = "${configDir}/tree-sitter";
50 | recursive = true; # include all utils, config files, etc...
51 | };
52 | };
53 | }
54 |
--------------------------------------------------------------------------------
/modules/editors/vim.nix:
--------------------------------------------------------------------------------
1 | { config, options, lib, pkgs, uPkgs, inputs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let
6 | cfg = config.modules.editors.vim;
7 | launchNvim = "nvim -u ~/.config/nvim/init.lua";
8 | in
9 | {
10 | options.modules.editors.vim = { enable = mkBoolOpt false; };
11 |
12 | config = mkIf cfg.enable {
13 | programs.neovim = {
14 | package = pkgs.unstable.neovim-unwrapped; # switch from (neovim-nightly)
15 | enable = true;
16 | defaultEditor = false; # this is configured by me elsewhere
17 | };
18 |
19 | user.packages = with pkgs; [
20 | sqlite # for coq nvim completion
21 | universal-ctags # for coq nvim completion
22 | python310 # for coq setup
23 | python310Packages.virtualenv
24 | # lua lsp for vim config
25 | sumneko-lua-language-server
26 | # for nvim
27 | gcc
28 | # for copilot (and others?)
29 | nodejs
30 | ];
31 |
32 | modules.editors.tree-sitter.enable = true;
33 |
34 | # env.VIMINIT = "let \\$MYVIMRC='\\$XDG_CONFIG_HOME/nvim/init.lua' | source \\$MYVIMRC";
35 |
36 | environment.shellAliases = {
37 | nvim = launchNvim;
38 | vim = launchNvim;
39 | vi = launchNvim;
40 | v = launchNvim;
41 | };
42 | };
43 | }
44 |
--------------------------------------------------------------------------------
/modules/editors/vscode.nix:
--------------------------------------------------------------------------------
1 | # I don't actively use VSCode, but it's good to have a configuration handy
2 | # because it's become the industry standard for text editors.
3 | #
4 | # It was a pain to get these hashes working.
5 | # I retrieved the real URL from https://github.com/NixOS/nixpkgs/blob/master/pkgs/misc/vscode-extensions/mktplcExtRefToFetchArgs.nix
6 | # and wrote a quick bash script to fetch the hash provided the url - go check it out in the bin/ folder
7 |
8 | { config, options, lib, pkgs, ... }:
9 |
10 | with lib;
11 | with lib.my;
12 | let
13 | cfg = config.modules.editors.vscode;
14 | extensions = with pkgs.vscode-extensions;
15 | (
16 | [ bbenoist.nix vscodevim.vim eugleo.magic-racket ]
17 | ++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [
18 | {
19 | name = "vscode-wakatime";
20 | publisher = "WakaTime";
21 | version = "5.0.1";
22 | sha256 = "0wahh7kmrdzcrcp2lj71qxsxbmgdq97k60aw2jxxqlmdfy407nnh";
23 | }
24 | {
25 | name = "stilla";
26 | publisher = "jakeisnt";
27 | version = "0.0.1";
28 | sha256 = "1hwmv2545qmdx7s6mf3ba0qf6217xssws1w2018s6s75sbcxmga4";
29 | }
30 | {
31 | name = "vscode-direnv";
32 | publisher = "Rubymaniac";
33 | version = "0.0.2";
34 | sha256 = "1gml41bc77qlydnvk1rkaiv95rwprzqgj895kxllqy4ps8ly6nsd";
35 | }
36 | {
37 | name = "leadermode";
38 | publisher = "michaelgriscom";
39 | version = "0.2.0";
40 | sha256 = "184b8g0rgfasippvfvr6bslaxfm34bqa2mgzr0y0dphj26fyw2wn";
41 | }
42 | ] ++ (
43 | if config.modules.dev.node.enable then
44 | pkgs.vscode-utils.extensionsFromVscodeMarketplace [
45 | {
46 | name = "vscode-eslint";
47 | publisher = "dbaeumer";
48 | version = "2.1.14";
49 | sha256 = "113w2iis4zi4z3sqc3vd2apyrh52hbh2gvmxjr5yvjpmrsksclbd";
50 | }
51 | ]
52 | else
53 | []
54 | ) ++ (
55 | if config.modules.dev.cc.enable then [
56 | xaver.clang-format
57 | ms-vscode.cpptools
58 | ] else
59 | []
60 | ) ++ (
61 | if config.modules.dev.rust.enable then
62 | [ matklad.rust-analyzer ]
63 | else
64 | []
65 | )
66 | ) ++ pkgs.vscode-utils.extensionsFromVscodeMarketplace [
67 | {
68 | name = "remote-ssh-edit";
69 | publisher = "ms-vscode-remote";
70 | version = "0.47.2";
71 | sha256 = "1hp6gjh4xp2m1xlm1jsdzxw9d8frkiidhph6nvl24d0h8z34w49g";
72 | }
73 | ];
74 | vscodium-with-extensions = pkgs.vscode-with-extensions.override {
75 | vscode = pkgs.vscodium;
76 | vscodeExtensions = extensions;
77 | };
78 | in
79 | {
80 | options.modules.editors.vscode = { enable = mkBoolOpt false; };
81 |
82 | config = mkIf cfg.enable {
83 | user.packages = with pkgs; [ vscodium-with-extensions ];
84 | home.configFile = {
85 | "VSCodium/User" = {
86 | source = "${configDir}/vscode";
87 | recursive = true;
88 | };
89 | };
90 | };
91 | }
92 |
--------------------------------------------------------------------------------
/modules/gaming/emulators.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.gaming.emulators;
6 | in {
7 | options.modules.gaming.emulators = {
8 | psx.enable = mkBoolOpt false; # Playstation
9 | ds.enable = mkBoolOpt false; # Nintendo DS
10 | gb.enable = mkBoolOpt false; # GameBoy + GameBoy Color
11 | gba.enable = mkBoolOpt false; # GameBoy Advance
12 | snes.enable = mkBoolOpt false; # Super Nintendo
13 | };
14 |
15 | config = {
16 | user.packages = with pkgs; [
17 | # (mkIf cfg.psx.enable epsxe)
18 | # (mkIf cfg.ds.enable desmume)
19 | # (mkIf (cfg.gba.enable || cfg.gb.enable || cfg.snes.enable) higan)
20 | ];
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/modules/hardware/audio.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.hardware.audio;
6 | in {
7 | options.modules.hardware.audio = { enable = mkBoolOpt false; };
8 |
9 | config = mkIf cfg.enable {
10 | # DEPRECATED: Can be removed!
11 | # sound.enable = true;
12 | xdg.portal = mkIf config.modules.desktop.sway.enable {
13 | enable = true;
14 | extraPortals = with pkgs; [
15 | xdg-desktop-portal-wlr
16 | xdg-desktop-portal-gtk
17 | ];
18 | };
19 |
20 | # control audio utilities
21 | user.extraGroups = [
22 | "audio"
23 | ];
24 |
25 | hardware.pulseaudio.enable = mkForce false;
26 |
27 | services.pipewire = {
28 | enable = true;
29 | alsa.enable = true;
30 | pulse.enable = true;
31 | jack.enable = true;
32 | };
33 |
34 | user.packages = with pkgs; [
35 | # communicate with pipewire via `pactl`
36 | pulseaudio
37 | # dynamically linked to; supports camera connection
38 | libcamera
39 | ];
40 | };
41 | }
42 |
--------------------------------------------------------------------------------
/modules/hardware/bluetooth.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let
6 | hwCfg = config.modules.hardware;
7 | cfg = hwCfg.bluetooth;
8 | in {
9 | options.modules.hardware.bluetooth = {
10 | enable = mkBoolOpt false;
11 | audio.enable = mkBoolOpt false;
12 | };
13 |
14 |
15 | config = mkIf cfg.enable (mkMerge [
16 | {
17 | hardware.bluetooth = {
18 | enable = true;
19 | package = pkgs.bluezFull;
20 | };
21 | services.blueman.enable = true;
22 | user.extraGroups = [ "bluetooth" "lp"];
23 | }
24 | (mkIf cfg.audio.enable {
25 | systemd.user.services.mpris-proxy = {
26 | Unit.Description = "Mpris proxy";
27 | Unit.After = [ "network.target" "sound.target" ];
28 | Service.ExecStart = "${pkgs.bluez}/bin/mpris-proxy";
29 | Install.WantedBy = [ "default.target" ];
30 | };
31 |
32 | hardware.bluetooth.settings = {
33 | General = {
34 | Enable = "Source,Sink,Media,Socket";
35 | # ControllerMode = "bredr"; # disable Bluetooth LE
36 | };
37 | };
38 | })
39 | ]);
40 | }
41 |
--------------------------------------------------------------------------------
/modules/hardware/extraHosts.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let
6 | cfg = config.modules.hardware.extraHosts;
7 | src = builtins.fetchTarball {
8 | url = "https://github.com/StevenBlack/hosts/archive/3.3.4.tar.gz";
9 | sha256 = "15474wjzwldfrbacvnwii7wjil83lh1wykq0h1sf59fq4fv75inj";
10 | };
11 | blockAllButSocial = "${src}/alternates/fakenews-gambling-porn/hosts";
12 | blockAll = "${src}/alternates/fakenews-gambling-porn-social/hosts";
13 | in {
14 | options.modules.hardware.extraHosts = {
15 | enable = mkBoolOpt false;
16 | allowSocial = mkBoolOpt true;
17 | };
18 |
19 | config = mkIf cfg.enable {
20 | networking.extraHosts =
21 | readFile (if cfg.allowSocial then blockAllButSocial else blockAll);
22 | };
23 | }
24 |
--------------------------------------------------------------------------------
/modules/hardware/fs.nix:
--------------------------------------------------------------------------------
1 | { config, options, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.hardware.fs;
6 | in {
7 | options.modules.hardware.fs = {
8 | enable = mkBoolOpt false;
9 | zfs.enable = mkBoolOpt false;
10 | ssd.enable = mkBoolOpt false;
11 | };
12 |
13 | config = mkIf cfg.enable (mkMerge [
14 | {
15 | programs.udevil.enable = true;
16 |
17 | # Support for more filesystems, mostly to support external drives
18 | environment.systemPackages = with pkgs; [
19 | sshfs
20 | exfat # Windows drives
21 | ntfs3g # Windows drives
22 | hfsprogs # MacOS drives
23 | ];
24 | }
25 |
26 | (mkIf (!cfg.zfs.enable && cfg.ssd.enable) {
27 | services.fstrim = {
28 | enable = true;
29 | interval = "daily";
30 | };
31 | })
32 |
33 | (mkIf cfg.zfs.enable (mkMerge [
34 | {
35 | boot.loader.grub.copyKernels = true;
36 | boot.supportedFilesystems = [ "zfs" ];
37 | boot.zfs.devNodes = "/dev/disk/by-partuuid";
38 | services.zfs.autoScrub.enable = true;
39 | }
40 |
41 | (mkIf cfg.ssd.enable {
42 | # Will only TRIM SSDs; skips over HDDs
43 | services.fstrim.enable = false;
44 | services.zfs.trim.enable = true;
45 | })
46 | ]))
47 | ]);
48 | }
49 |
--------------------------------------------------------------------------------
/modules/hardware/printer.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.hardware.printer;
6 | in {
7 | options.modules.hardware.printer = { enable = mkBoolOpt false; };
8 |
9 | config = mkIf cfg.enable {
10 | services.printing = {
11 | enable = true;
12 | drivers = [ ];
13 | };
14 |
15 | modules.services.avahi.enable = true;
16 |
17 | user.extraGroups = [ "scanner" "lp" ];
18 | };
19 | }
20 |
--------------------------------------------------------------------------------
/modules/hardware/remarkable.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.hardware.remarkable;
6 | in {
7 | options.modules.hardware.remarkable = { enable = mkBoolOpt false; };
8 | config = mkIf cfg.enable {
9 | user.packages = with pkgs; [ rmapi ];
10 |
11 |
12 | programs.ssh.knownHosts = {
13 | # alias for ReMarkable IP!
14 | "remarkable" = {
15 | hostNames = ["10.110.139.108"];
16 | publicKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCY05XsAsq0wgBJvVQcT9MOh+U/rTlk0s7MHDZkFEwQiGuiGme3+96D8IrNGbtYwwWKDLZafxy9aAGLrTiT/UMTRC/7rO1aRRRCnpBbLfLiKX0JqWWL0ZzHdNNI3tPgIWUNw502GzcELbHjvw2SSgxvUF/Prqv6/CUrEN3tWG2ch/jjmXGlLkOcev/hHp6HR3J8OcSTTVlc9MZhYkrrfifi3nCtNOtbWWQfEx1KnAQ2L4t4LLfeATBqzVkNsmk3p8IZ97tZJdWFajEb44jROBpvei0JG+VTSW6CcolwluYx4vkk2mVOt+e520T7gjNQQnFjxeXJOy/5FxJfq9OFn7/T root@reMarkable";
17 | };
18 | };
19 |
20 | };
21 | }
22 |
--------------------------------------------------------------------------------
/modules/hardware/scanner.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.hardware.scanner;
6 | in {
7 | options.modules.hardware.scanner = { enable = mkBoolOpt false; };
8 |
9 | config = mkIf cfg.enable {
10 | hardware.sane = {
11 | enable = true;
12 | # needed to support epson
13 | extraBackends = with pkgs; [ epkowa ];
14 | };
15 | user.extraGroups = [ "scanner" "lp" ];
16 | };
17 | }
18 |
--------------------------------------------------------------------------------
/modules/media/daw.nix:
--------------------------------------------------------------------------------
1 | # modules/desktop/media/daw.nix
2 |
3 | # off of Fruityloops. When I'm in the mood for a quicky I fire up sunvox
4 | # instead. It runs absolutely anywhere, even on my ipad and phone. As if I'd
5 | # ever need to.
6 |
7 | { config, options, lib, pkgs, ... }:
8 |
9 | with lib;
10 | with lib.my;
11 | let
12 | cfg = config.modules.media.daw;
13 | in
14 | {
15 | options.modules.media.daw = { enable = mkBoolOpt false; };
16 |
17 | config = mkIf cfg.enable {
18 | user.packages = with pkgs; [
19 | ardour
20 | # audacity # for recording and remastering audio
21 | calf # nice open source audio plugins and synths!!
22 | vcv-rack # rack simulation thing (start it by running Rack!)
23 | # sunvox # chill synth for making music (where LMMS is overkill)
24 | # orca-c # powers sunvox
25 | ];
26 | };
27 | }
28 |
--------------------------------------------------------------------------------
/modules/media/documents.nix:
--------------------------------------------------------------------------------
1 | # modules/desktop/media/docs.nix
2 |
3 | { options, config, lib, pkgs, ... }:
4 |
5 | with lib;
6 | with lib.my;
7 | let cfg = config.modules.media.documents;
8 | in {
9 | options.modules.media.documents = {
10 | enable = mkBoolOpt false;
11 | pdf.enable = mkBoolOpt false;
12 | ebook.enable = mkBoolOpt false;
13 | };
14 |
15 | config = mkIf cfg.enable {
16 | user.packages = with pkgs; [
17 | (mkIf cfg.ebook.enable calibre)
18 | (mkIf cfg.pdf.enable evince)
19 | zathura
20 | ];
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/modules/media/graphics.nix:
--------------------------------------------------------------------------------
1 | # modules/desktop/media/graphics.nix
2 | #
3 | # No Adobe allowed.
4 |
5 | { config, options, lib, pkgs, ... }:
6 |
7 | with builtins;
8 | with lib;
9 | with lib.my;
10 | let
11 | cfg = config.modules.media.graphics;
12 | # username = let name = getEnv "username";
13 | # in if elem name [ "" "root" ] then username else name;
14 | in {
15 | options.modules.media.graphics = {
16 | enable = mkBoolOpt false;
17 | tools.enable = mkBoolOpt true;
18 | raster.enable = mkBoolOpt true;
19 | vector.enable = mkBoolOpt true;
20 | sprites.enable = mkBoolOpt true;
21 | photo.enable = mkBoolOpt true;
22 | };
23 |
24 | config = mkIf cfg.enable {
25 | user.packages = with pkgs;
26 | [ vlc ] ++ (if cfg.tools.enable then [
27 | font-manager # so many damned fonts...
28 | imagemagick # for image manipulation from the shell
29 | ] else
30 | [ ]) ++
31 |
32 | # replaces illustrator & indesign
33 | (if cfg.vector.enable then [ inkscape ] else [ ]) ++
34 |
35 | # Replaces photoshop
36 | (if cfg.raster.enable then [
37 | # krita
38 | gimp
39 | # gimpPlugins.resynthesizer2 # content-aware scaling in gimp
40 | ] else
41 | [ ]) ++
42 |
43 | # replaces lightroom
44 | (if cfg.photo.enable then [ darktable ] else [ ]) ++
45 |
46 | # Sprite sheets & animation
47 | (if cfg.sprites.enable then [ aseprite-unfree ] else [ ]);
48 |
49 | home.configFile = mkMerge [
50 | (mkIf cfg.raster.enable {
51 | "GIMP/2.10" = {
52 | source = "${configDir}/gimp";
53 | recursive = true;
54 | };
55 | })
56 | (mkIf cfg.vector.enable {
57 | "inkscape/templates/default.svg".source = "${configDir}/inkscape/default-template.svg";
58 | })
59 | ];
60 |
61 | environment.variables.PICTURES_FOLDER = "/home/${username}/pics";
62 | };
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/modules/media/mpv.nix:
--------------------------------------------------------------------------------
1 | { config, options, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.media.mpv;
6 | in {
7 | options.modules.media.mpv = { enable = mkBoolOpt false; };
8 |
9 | config = mkIf cfg.enable {
10 | user.packages = with pkgs; [
11 | # image viewer
12 | imv
13 | mpv-with-scripts
14 | mpvc # CLI controller for mpv
15 | (mkIf config.programs.sway.enable celluloid) # nice GTK GUI for mpv
16 | ];
17 | };
18 | }
19 |
--------------------------------------------------------------------------------
/modules/media/recording.nix:
--------------------------------------------------------------------------------
1 | # modules/desktop/media/recording.nix
2 | #
3 | # OBS to capture footage/stream, audacity for audio, handbrake to encode it all.
4 | # This, paired with DaVinci Resolve for video editing (on my Windows system) and
5 | # I have what I need for youtube videos and streaming.
6 |
7 | { config, options, lib, pkgs, ... }:
8 |
9 | with lib;
10 | with lib.my;
11 | let
12 | cfg = config.modules.media.recording;
13 | in
14 | {
15 | options.modules.media.recording = {
16 | enable = mkBoolOpt false;
17 | audio.enable = mkBoolOpt true;
18 | video.enable = mkBoolOpt true;
19 | };
20 |
21 | config = mkIf cfg.enable {
22 | user.packages = with pkgs;
23 | # for recording and remastering audio
24 | (
25 | if cfg.audio.enable then [
26 | # audacity
27 | ] else []
28 | ) ++ # for longer term streaming/recording the screen
29 | (if cfg.video.enable then [(wrapOBS {
30 | plugins = with obs-studio-plugins; [
31 | wlrobs
32 | ];
33 | }) handbrake ] else []);
34 | };
35 | }
36 |
--------------------------------------------------------------------------------
/modules/messengers/deltachat.nix:
--------------------------------------------------------------------------------
1 | { config, options, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.messengers.deltachat;
6 | in {
7 | options.modules.messengers.deltachat = { enable = mkBoolOpt false; };
8 |
9 | config = mkIf cfg.enable {
10 | user.packages = with pkgs;
11 | (if config.programs.sway.enable then [ deltachat-electron ] else [ ]);
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/modules/messengers/discord.nix:
--------------------------------------------------------------------------------
1 | { config, options, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.messengers.discord;
6 | in {
7 | options.modules.messengers.discord = { enable = mkBoolOpt false; };
8 |
9 | config = mkIf cfg.enable {
10 | user.packages = with pkgs;
11 | [
12 | # If not installed from the bleeding edge, Discord will sometimes
13 | # soft-lock itself on a "there's an update for discord" screen.
14 | ] ++ (if config.programs.sway.enable then
15 | [ unstable.discord ]
16 | else
17 | [ cordless ]);
18 | };
19 | }
20 |
--------------------------------------------------------------------------------
/modules/messengers/matrix.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.messengers.matrix;
6 | in {
7 | options.modules.messengers.matrix = { enable = mkBoolOpt false; };
8 |
9 | config = mkIf cfg.enable { user.packages = with pkgs; [ gomuks ]; };
10 | }
11 |
--------------------------------------------------------------------------------
/modules/messengers/rss.nix:
--------------------------------------------------------------------------------
1 | { config, options, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.messengers.rss;
6 | in {
7 | options.modules.messengers.rss = { enable = mkBoolOpt false; };
8 | config = mkIf cfg.enable {
9 | # 'liferea' provides a nice GUI for RSS if I need images and html at some point
10 | user.packages = with pkgs; [ newsboat ];
11 | # TODO: consider tt-rss server (or mimic the protocol with another service?)
12 | # we want to be able to tweak .config/newsboat/urls without rebuild, so it's not included here.
13 | home.configFile = {
14 | "newsboat/config".source = "${configDir}/newsboat/config";
15 | };
16 | };
17 | }
18 |
--------------------------------------------------------------------------------
/modules/messengers/signal.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.messengers.signal;
6 | in {
7 | options.modules.messengers.signal = { enable = mkBoolOpt false; };
8 |
9 | config = mkIf cfg.enable {
10 | user.packages = with pkgs;
11 | [ ] ++ (if config.programs.sway.enable then
12 | [ signal-desktop ]
13 | else
14 | [ signal-cli ]);
15 | };
16 | }
17 |
--------------------------------------------------------------------------------
/modules/messengers/slack.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.messengers.slack;
6 | in {
7 | options.modules.messengers.slack = { enable = mkBoolOpt false; };
8 |
9 | config = mkIf cfg.enable {
10 | user.packages = with pkgs;
11 | [ ]
12 | ++ (if config.programs.sway.enable then [ slack ] else [ slack-term ]);
13 | };
14 | }
15 |
--------------------------------------------------------------------------------
/modules/messengers/weechat.nix:
--------------------------------------------------------------------------------
1 | { config, options, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.messengers.weechat;
6 | in {
7 | options.modules.messengers.weechat = { enable = mkBoolOpt false; };
8 |
9 | config = mkIf cfg.enable {
10 | user.packages = with pkgs; [ weechat ];
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/modules/security.nix:
--------------------------------------------------------------------------------
1 | { ... }:
2 |
3 | {
4 | ## System security tweaks
5 | boot.tmp.useTmpfs = true;
6 | boot.tmp.tmpfsSize = "16G";
7 | boot.tmp.cleanOnBoot = true;
8 |
9 | security.protectKernelImage = true;
10 |
11 | # Fix a security hole in place for backwards compatibility. See desc in
12 | # nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix
13 | boot.loader.systemd-boot.editor = false;
14 | }
15 |
--------------------------------------------------------------------------------
/modules/services/acme.nix:
--------------------------------------------------------------------------------
1 | { config, options, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.services.acme;
6 | in {
7 | options.modules.services.acme = {
8 | enable = mkBoolOpt false;
9 | };
10 |
11 | config = mkIf cfg.enable {
12 | security.acme = {
13 | defaults.email = "${secrets.gmail.user}";
14 | email = "${secrets.gmail.user}";
15 | acceptTerms = true;
16 | };
17 | };
18 | }
19 |
--------------------------------------------------------------------------------
/modules/services/avahi.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | # Make systems discoverable to one another over local networks.
4 |
5 | with lib;
6 | with lib.my;
7 | let cfg = config.modules.services.avahi;
8 | in {
9 | options.modules.services.avahi = { enable = mkBoolOpt false; };
10 |
11 | config = mkIf cfg.enable {
12 | services.avahi = {
13 | enable = true;
14 | nssmdns = true;
15 | publish.enable = true;
16 | publish.addresses = true;
17 | publish.workstation = true;
18 | };
19 | };
20 | }
21 |
--------------------------------------------------------------------------------
/modules/services/backup.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 |
3 | # This service backs up to the cloud and to a physical device, somehow.
4 | with lib;
5 | with lib.my;
6 | let
7 | cfg = config.modules.services.backup;
8 | domain = config.networking.domain;
9 | in {
10 | options.modules.services.backup = {
11 | enable = mkBoolOpt false;
12 | registration = mkBoolOpt false;
13 | mail = mkBoolOpt false;
14 | yubikey = mkBoolOpt false;
15 | };
16 |
17 |
18 | config = mkIf cfg.enable {
19 | users.users.duplicati.isNormalUser = true;
20 | services.duplicati = {
21 | enable = true;
22 | user = "jake";
23 | };
24 | };
25 | }
26 |
--------------------------------------------------------------------------------
/modules/services/bitwarden.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let
6 | cfg = config.modules.services.bitwarden;
7 | domain = config.networking.domain;
8 | in {
9 | options.modules.services.bitwarden = {
10 | enable = mkBoolOpt false;
11 | registration = mkBoolOpt false;
12 | mail = mkBoolOpt false;
13 | };
14 |
15 | config = mkIf cfg.enable {
16 | modules.services.acme.enable = true;
17 | modules.services.nginx.enable = true;
18 |
19 | services = {
20 | vaultwarden = {
21 | enable = true;
22 | config = mkMerge [
23 | {
24 | signupsAllowed = cfg.registration;
25 | invitationsAllowed = cfg.registration;
26 | domain = "https://bitwarden.${domain}";
27 | logFile = "/var/log/bitwarden";
28 | websocketEnabled = true;
29 | websocketAddress = "0.0.0.0";
30 | websocketPort = 3012;
31 | signupsVerify = true;
32 | adminToken = secrets.bitwarden.adminToken;
33 | rocketPort = 8812;
34 | }
35 | (mkIf cfg.mail {
36 | smtpHost = "localhost";
37 | smtpFrom = "admin@${domain}";
38 | smtpFromName = "Admin";
39 | smtpPort = 587;
40 | smtpSsl = true;
41 | smtpUsername = "admin@${domain}";
42 | smtpPassword = secrets.email.hashedPassword;
43 | smtpTimeout = 15;
44 | })
45 | ];
46 | };
47 |
48 | nginx = {
49 | virtualHosts."bitwarden.${domain}" = {
50 | forceSSL = true;
51 | enableACME = true;
52 | root = "/srv/www/bitwarden.${domain}";
53 | locations = {
54 | "/".proxyPass =
55 | "http://localhost:8812"; # changed the default rocket port due to some conflict
56 | "/notifications/hub".proxyWebsockets = true;
57 | "/notifications/hub/negotiate".proxyWebsockets = true;
58 | };
59 | };
60 | };
61 | };
62 |
63 | user.extraGroups = [ "vaultwarden" ];
64 | };
65 | }
66 |
--------------------------------------------------------------------------------
/modules/services/cal.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 |
3 | # Calendar and contacts sync server
4 | # Largely from https://nixos-mailserver.readthedocs.io/en/latest/howto-add-radicale.html
5 | with lib;
6 | with lib.my;
7 | let
8 | cfg = config.modules.services.cal;
9 | domain = config.networking.domain;
10 | mailAccounts = config.mailserver.loginAccounts;
11 | htpasswd = pkgs.writeText "radicale.users" (concatStrings
12 | (flip mapAttrsToList mailAccounts
13 | (mail: user: mail + ":" + secrets.email.hashedPassword + "\n")));
14 | in {
15 | options.modules.services.cal = { enable = mkBoolOpt false; };
16 |
17 | config = mkIf cfg.enable {
18 | services.radicale = {
19 | enable = true;
20 | settings = {
21 | auth = {
22 | type = "htpasswd";
23 | htpasswd_filename = "${htpasswd}";
24 | htpasswd_encryption = "bcrypt";
25 | };
26 | };
27 | };
28 |
29 | services.nginx = {
30 | enable = true;
31 | virtualHosts = {
32 | "cal.${domain}" = {
33 | forceSSL = true;
34 | enableACME = true;
35 | root = "/srv/www/cal.${domain}";
36 | locations."/" = {
37 | proxyPass = "http://localhost:5232/";
38 | extraConfig = ''
39 | proxy_set_header X-Script-Name /;
40 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
41 | proxy_pass_header Authorization;
42 | '';
43 | };
44 | };
45 | };
46 | };
47 | };
48 | }
49 |
--------------------------------------------------------------------------------
/modules/services/calibre.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.services.calibre;
6 | in {
7 | options.modules.services.calibre = {
8 | enable = mkBoolOpt false;
9 | };
10 |
11 | config = mkIf cfg.enable {
12 | services.calibre-server.enable = true;
13 |
14 | networking.firewall.allowedTCPPorts = [ 8080 ];
15 | };
16 | }
17 |
--------------------------------------------------------------------------------
/modules/services/dnsmasq.nix:
--------------------------------------------------------------------------------
1 | { config, options, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.services.dnsmasq;
6 | in {
7 | options.modules.services.dnsmasq = { enable = mkBoolOpt false; };
8 |
9 | config = mkIf cfg.enable {
10 | # use dnsmasq to cache dns
11 | services.dnsmasq = {
12 | enable = true;
13 | servers = [ "8.8.8.8" "8.8.4.4" ];
14 |
15 | extraConfig = ''
16 | interface=lo
17 | bind-interfaces
18 | listen-address=127.0.0.1
19 | cache-size=1000
20 | no-negcache
21 | '';
22 | };
23 | };
24 | }
25 |
--------------------------------------------------------------------------------
/modules/services/docker.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.services.docker;
6 | in {
7 | options.modules.services.docker = {
8 | enable = mkBoolOpt false;
9 | podman = mkBoolOpt false;
10 | kubernetes = mkBoolOpt false;
11 | };
12 |
13 | config = mkIf cfg.enable {
14 | user.packages = with pkgs; ([
15 | docker-client
16 | docker-compose
17 | ] ++ (if cfg.kubernetes then [ kubectl k3s ] else []));
18 |
19 | env.DOCKER_CONFIG = "$XDG_CONFIG_HOME/docker";
20 | env.MACHINE_STORAGE_PATH = "$XDG_DATA_HOME/docker/machine";
21 |
22 | user.extraGroups = [ "docker" ];
23 |
24 | environment.shellAliases = {
25 | "dk" = "docker";
26 | "dkc" = "docker-compose";
27 | "dkl" = "dk logs";
28 | "dkcl" = "dkc logs";
29 | "dkclr" = "dk stop (docker ps -a -q) && dk rm (docker ps -a -q)";
30 | };
31 |
32 | # a nixos kubernetes service running in userspace (I hope
33 | # TODO: This doesn't work.
34 | # services.kubernetes = mkIf cfg.kubernetes {
35 | # roles = ["master" "node"];
36 | # masterAddress = "localhost";
37 | # apiserver.enable = true;
38 | # controllerManager.enable = true;
39 | # scheduler.enable = true;
40 | # addonManager.enable = true;
41 | # proxy.enable = true;
42 | # flannel.enable = true;
43 | # };
44 |
45 | virtualisation = {
46 | podman = {
47 | enable = cfg.podman;
48 | dockerCompat = true;
49 | dockerSocket.enable = true;
50 | };
51 | docker = {
52 | enable = !cfg.podman;
53 | # autoPrune.enable = true;
54 | enableOnBoot = true;
55 | # listenOptions = [];
56 | };
57 | };
58 | users.users.jake.extraGroups = [ "podman" ];
59 | };
60 | }
61 |
--------------------------------------------------------------------------------
/modules/services/gitea.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let
6 | cfg = config.modules.services.gitea;
7 | domain = config.networking.domain;
8 | in {
9 | options.modules.services.gitea = {
10 | enable = mkBoolOpt false;
11 | registration = mkBoolOpt false;
12 | mail = mkBoolOpt false;
13 | };
14 |
15 | config = mkIf cfg.enable {
16 | modules.services.nginx.enable = true;
17 |
18 | # I prefer git@... ssh addresses over gitea@...
19 | users.users.git = {
20 | useDefaultShell = true;
21 | home = "/var/lib/gitea";
22 | group = "gitea";
23 | };
24 |
25 | services = {
26 | gitea = {
27 | enable = true;
28 | domain = "git.${domain}";
29 | appName = "git.${domain}";
30 |
31 | user = "git";
32 | database = {
33 | user = "git";
34 | type = "postgres";
35 | createDatabase = true;
36 | };
37 |
38 | ssh = {
39 | enable = true;
40 | clonePort = 2222;
41 | };
42 |
43 | dump.enable = true;
44 | disableRegistration = cfg.registration;
45 | httpPort = 3000;
46 |
47 | # We're assuming SSL-only connectivity
48 | cookieSecure = true;
49 |
50 | log.level = "Error";
51 | settings.server.DISABLE_ROUTER_LOG = true;
52 | settings.mailer = mkIf cfg.mail {
53 | ENABLED = true;
54 | FROM = "admin@${domain}";
55 | MAILER_TYPE = "smtp";
56 | HOST = "localhost:587";
57 | IS_TLS_ENABLED = true;
58 | USER = "admin@${domain}";
59 | PASSWD = secrets.email.hashedPassword;
60 | };
61 | };
62 |
63 | nginx = {
64 | virtualHosts = {
65 | "git.${domain}" = {
66 | forceSSL = true;
67 | enableACME = true;
68 | root = "/srv/www/git.${domain}";
69 | locations."/" = { proxyPass = "http://127.0.0.1:3000"; };
70 | };
71 | };
72 | };
73 | };
74 |
75 | user.extraGroups = [ "gitea" ];
76 | };
77 | }
78 |
--------------------------------------------------------------------------------
/modules/services/jellyfin.nix:
--------------------------------------------------------------------------------
1 | # Finally, a decent open alternative to Plex!
2 |
3 | { options, config, lib, pkgs, ... }:
4 |
5 | with lib;
6 | with lib.my;
7 | let cfg = config.modules.services.jellyfin;
8 | in {
9 | options.modules.services.jellyfin = {
10 | enable = mkBoolOpt false;
11 | };
12 |
13 | config = mkIf cfg.enable {
14 | services.jellyfin.enable = true;
15 |
16 | networking.firewall = {
17 | allowedTCPPorts = [ 8096 ];
18 | allowedUDPPorts = [ 8096 ];
19 | };
20 |
21 | user.extraGroups = [ "jellyfin" ];
22 | };
23 | }
24 |
--------------------------------------------------------------------------------
/modules/services/jitsi.nix:
--------------------------------------------------------------------------------
1 | # Finally, a decent open alternative to Plex!
2 |
3 | { options, config, lib, pkgs, ... }:
4 |
5 | with lib;
6 | with lib.my;
7 | let
8 | cfg = config.modules.services.jitsi;
9 | domain = config.networking.domain;
10 | in {
11 | options.modules.services.jitsi = { enable = mkBoolOpt false; };
12 |
13 | config = mkIf cfg.enable {
14 | services = {
15 | jitsi-meet = {
16 | enable = true;
17 | hostName = "jitsi.${domain}";
18 | config = {
19 | enableWelcomePage = false;
20 | prejoinPageEnabled = true;
21 | };
22 | interfaceConfig = {
23 | SHOW_JITSI_WATERMARK = false;
24 | SHOW_WATERMARK_FOR_GUESTS = false;
25 | };
26 | };
27 |
28 | jitsi-videobridge.openFirewall = true;
29 | };
30 |
31 | networking.firewall = {
32 | allowedTCPPorts = [ 5349 5350 ];
33 | allowedUDPPorts = [ 80 443 3478 3479 ];
34 | };
35 | };
36 | }
37 |
--------------------------------------------------------------------------------
/modules/services/mailserver.nix:
--------------------------------------------------------------------------------
1 | { lib, config, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let
6 | cfg = config.modules.services.mailserver;
7 | domain = config.networking.domain;
8 | in {
9 | options.modules.services.mailserver = { enable = mkBoolOpt false; };
10 |
11 | config = mkIf cfg.enable {
12 | modules.services.acme.enable = true;
13 | networking.firewall.allowedTCPPorts = [
14 | # Email
15 | 25 # SMTP
16 | 465 # Submission TLS
17 | 587 # Submission StartTLS
18 | 993 # IMAP with TLS
19 | 995 # POP3 with TLS
20 | 143 # IMAP with StartTLS
21 | 110 # POP3 with StartTLS
22 |
23 | # roundcube
24 | 80
25 | 443
26 | ];
27 |
28 | services.nginx.enable = true;
29 |
30 | services.roundcube = {
31 | enable = true;
32 | hostName = "mail.${domain}";
33 | extraConfig = ''
34 | # starttls needed for authentication, so the fqdn required to match
35 | # the certificate
36 | $config['smtp_server'] = "tls://${config.mailserver.fqdn}";
37 | $config['smtp_user'] = "%u";
38 | $config['smtp_pass'] = "%p";
39 | '';
40 | };
41 |
42 | mailserver = {
43 | enable = true;
44 | fqdn = "mail.${domain}";
45 | domains = [ domain ];
46 |
47 | loginAccounts = {
48 | "jake@${domain}" = {
49 | hashedPassword = secrets.email.hashedPassword;
50 | # aliases = [ ];
51 | catchAll = [ domain ];
52 | };
53 |
54 | "tommy@${domain}" = {
55 | hashedPassword = secrets.email.hashedPasswordT;
56 | # aliases = [ ];
57 | catchAll = [ domain ];
58 | };
59 |
60 | "admin@${domain}" = {
61 | hashedPassword = secrets.email.hashedPassword;
62 | # aliases = [ ];
63 | };
64 | "phoebe@${domain}" = {
65 | hashedPassword = secrets.email.hashedPasswordP;
66 | aliases = [ "pheebs" ];
67 | };
68 | };
69 |
70 | # Use Let's Encrypt certificates. Note that this needs to set up a stripped
71 | # down nginx and opens port 80.
72 | certificateScheme = 3;
73 |
74 | # Enable IMAP and POP3
75 | enableImap = true; enablePop3 = true; enableImapSsl = true;
76 | enablePop3Ssl = true;
77 |
78 | # Enable the ManageSieve protocol
79 | enableManageSieve = true;
80 |
81 | # whether to scan inbound emails for viruses (note that this requires at least
82 | # 1 Gb RAM for the server. Without virus scanning 256 MB RAM should be plenty)
83 | virusScanning = false;
84 | };
85 | };
86 | }
87 |
--------------------------------------------------------------------------------
/modules/services/matrix.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let
6 | cfg = config.modules.services.matrix;
7 | domain = config.networking.domain;
8 | in {
9 | options.modules.services.matrix = {
10 | enable = mkBoolOpt false;
11 | registration = mkBoolOpt false;
12 | element = mkBoolOpt false;
13 | };
14 |
15 | config = mkIf cfg.enable {
16 | modules.services.acme.enable = true;
17 | modules.services.nginx.enable = true;
18 |
19 | networking.firewall.allowedTCPPorts = [
20 | 8448 # Matrix federation
21 | ];
22 |
23 | services = mkMerge [
24 | (mkIf cfg.element {
25 | nginx.virtualHosts."element.${domain}" = {
26 | enableACME = true;
27 | forceSSL = true;
28 | root = pkgs.element-web.override {
29 | conf = {
30 | default_server_config."m.homeserver" = {
31 | "base_url" = "https://matrix.${domain}";
32 | "server_name" = "${domain}";
33 | };
34 |
35 | jitsi.preferredDomain =
36 | mkIf config.modules.services.jitsi.enable "jitsi.${domain}";
37 | };
38 | };
39 | };
40 | })
41 | {
42 | matrix-synapse = {
43 | enable = true;
44 | server_name = domain;
45 | enable_registration = cfg.registration;
46 | registration_shared_secret = secrets.matrix.password;
47 |
48 | public_baseurl = "https://matrix.${domain}";
49 | # tls_certificate_path = "/var/lib/acme/matrix.isnt.online/fullchain.pem";
50 | # tls_private_key_path = "/var/lib/acme/matrix.isnt.online/key.pem";
51 |
52 | database_type = "psycopg2";
53 | database_args = { database = "matrix-synapse"; };
54 |
55 | listeners = [{ # federation
56 | bind_address = "::1";
57 | port = 8008;
58 | resources = [{
59 | compress = true;
60 | names = [ "client" "federation" ];
61 | }];
62 |
63 | tls = false;
64 | type = "http";
65 | x_forwarded = false;
66 | }];
67 |
68 | extraConfig = ''
69 | max_upload_size: "100M"
70 | '';
71 | };
72 |
73 | postgresql = {
74 | enable = true;
75 | initialScript = pkgs.writeText "synapse-init.sql" ''
76 | CREATE USER "matrix-synapse";
77 |
78 | CREATE DATABASE "matrix-synapse"
79 | ENCODING 'UTF8'
80 | LC_COLLATE='C'
81 | LC_CTYPE='C'
82 | template=template0
83 | OWNER "matrix-synapse";
84 | '';
85 | };
86 |
87 | nginx = {
88 | virtualHosts = {
89 | "${domain}" = {
90 | locations."= /.well-known/matrix/server".extraConfig = let
91 | # use 443 instead of the default 8448 port
92 | server = { "m.server" = "matrix.${domain}:443"; };
93 | in ''
94 | add_header Content-Type application/json;
95 | return 200 '${builtins.toJSON server}';
96 | '';
97 | locations."= /.well-known/matrix/client".extraConfig = let
98 | client = {
99 | "m.homeserver" = { "base_url" = "https://matrix.${domain}"; };
100 | "m.identity_server" = { "base_url" = "https://vector.im"; };
101 | };
102 | in ''
103 | add_header Content-Type application/json;
104 | add_header Access-Control-Allow-Origin *;
105 | return 200 '${builtins.toJSON client}';
106 | '';
107 | };
108 |
109 | "matrix.${domain}" = {
110 | enableACME = true;
111 | forceSSL = true;
112 |
113 | locations."/".extraConfig = ''
114 | return 404;
115 | '';
116 |
117 | locations."/_matrix" = { proxyPass = "http://[::1]:8008"; };
118 | };
119 | };
120 | };
121 |
122 | }
123 | ];
124 | };
125 | }
126 |
--------------------------------------------------------------------------------
/modules/services/nginx.nix:
--------------------------------------------------------------------------------
1 | { config, options, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.services.nginx;
6 | in {
7 | options.modules.services.nginx = { enable = mkBoolOpt false; };
8 |
9 | config = mkIf cfg.enable {
10 | networking.firewall.allowedTCPPorts = [ 80 443 ];
11 |
12 | services.nginx = {
13 | enable = true;
14 |
15 | # Use recommended settings
16 | recommendedGzipSettings = true;
17 | recommendedOptimisation = true;
18 | recommendedProxySettings = true;
19 | recommendedTlsSettings = true;
20 | };
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/modules/services/ssh.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let
6 | cfg = config.modules.services.ssh;
7 | add = "/run/current-system/sw/bin/ssh-add";
8 | keygen = "/run/current-system/sw/bin/ssh-keygen";
9 | ssh-agent = "/run/current-system/sw/bin/ssh-agent";
10 | xpsKey =
11 | "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCtB3BbMTx18grI1xxJ+mvjO8jzYoUIWh6l230DiXmQ7w7+3ZJpPEh21UphqZvm/k5FwsPU5Tb+vuwofEjPZfvx0ERL1XNvrFg/2rQmGl2ccsupclMz2uxwP47APW5amJzhVRUejTOhv9Xo7kaZGqeh3L5hbyNSfC3Ci2LpZpV1nwuOgqmCm58d68G05YrW/LIM7zPVpWRa7/1Jyplu2AYViCB5z3jt1q1s7UP2oXAh5bH5QQ5vlqdsU9GEpn0HSF0CjQdGx7PDfyeocDoI0Dy0coUCWsMDrPqURnZWzQL0eARKkaYdLHcJ2N8I3dwU1z8I/8VJ+jxm9jmOxhuwlIluXdz6VUbh+eNOmEczVwjAtTdpiyBG2ku0labQ4TMN0G0GdV3USxC4sEfBYfzF1m2NERRAm9ySkjxbLqQ5b/85mvLUtuJ4q5hMla6gGDRRKUAWGrDlVe8G3NACARqqDIQOE36Je/u/f3HjOFtczEf5pfAUW4Ky7tyOJYzaxErPK/zc1g2qRdVtDclgdI1IHuSFywQPeAkz0l0vTqe60+RUZT0kyQXNzvZeEZ9U8ia8kO07HfxGAu3cdW7AJI/5eZv1LXI6Xa0GYN+9BSARz6RKHjNIM9wYAqGrDExgo56UOLrHqiDRRt6ZaqBPXzBdIp6D6HHuh7oggexINXoRvHaMWw== jake@isnt.online";
12 | in {
13 | options.modules.services.ssh = { enable = mkBoolOpt false; };
14 |
15 | config = mkIf cfg.enable {
16 | services.openssh = {
17 | enable = true;
18 | forwardX11 = true;
19 | kbdInteractiveAuthentication = false;
20 | passwordAuthentication = false;
21 | };
22 |
23 | # Allow SSHing through firewall
24 | networking.firewall.allowedTCPPorts = [ 22 ];
25 | user.openssh.authorizedKeys.keys = [ xpsKey ];
26 |
27 | # user.packages = with pkgs;
28 | # TODO restore
29 | # [
30 | # (writeScriptBin "ssh-key" ''
31 | # #!${stdenv.shell}
32 | # # Create SSH key
33 | # ${keygen} -t rsa -b 4096 -C "${username}@${secrets.domain}"
34 | # eval $(${ssh-agent} -s)
35 | # ${add} $HOME/.ssh/id_rsa
36 | # '')
37 | # ];
38 | };
39 | }
40 |
--------------------------------------------------------------------------------
/modules/services/syncthing.nix:
--------------------------------------------------------------------------------
1 | { config, options, pkgs, lib, ... }:
2 | with builtins;
3 | with lib;
4 | with lib.my;
5 | let
6 | cfg = config.modules.services.syncthing;
7 | username = let name = getEnv "username";
8 | in if elem name [ "" "root" ] then "jake" else name;
9 |
10 | domain = config.networking.domain;
11 | in {
12 | options.modules.services.syncthing = {
13 | enable = mkBoolOpt false;
14 | server = mkBoolOpt false;
15 | };
16 |
17 | config = mkIf cfg.enable {
18 | modules.services = mkIf cfg.server {
19 | acme.enable = true;
20 | nginx.enable = true;
21 | };
22 |
23 | services.nginx = mkIf cfg.server {
24 | virtualHosts = {
25 | "syncthing.${domain}" = {
26 | forceSSL = true;
27 | enableACME = true;
28 | root = "/srv/www/syncthing.${domain}";
29 | locations."/" = {
30 | proxyPass = "http://localhost:8384";
31 | proxyWebsockets = true;
32 | };
33 | };
34 | };
35 | };
36 |
37 | services.syncthing = {
38 | enable = true;
39 | guiAddress = mkIf cfg.server "syncthing.${domain}";
40 | user = username;
41 | openDefaultPorts = true;
42 | configDir = "/home/${username}/.config/syncthing";
43 | dataDir = "/home/${username}/.local/share/syncthing";
44 |
45 | folders = let
46 | deviceEnabled = devices: lib.elem config.networking.hostName devices;
47 | deviceType = devices:
48 | if deviceEnabled devices then "sendreceive" else "receiveonly";
49 | in {
50 | work = rec {
51 | devices = [ "phone" "xps" "vultr" ];
52 | path = "/home/${username}/work";
53 | watch = true;
54 | rescanInterval = 3600 * 6;
55 | type = deviceType [ "xps" ];
56 | enable = deviceEnabled devices;
57 | };
58 | pics = rec {
59 | devices = [ "phone" "xps" "vultr" ];
60 | path = "/home/${username}/pics";
61 | watch = true;
62 | rescanInterval = 3600 * 6;
63 | type = deviceType [ "xps" ];
64 | enable = deviceEnabled devices;
65 | };
66 | };
67 |
68 | devices = {
69 | xps.id =
70 | "M4GBTEM-N55HKKV-KLP4G5H-JFMMPUD-REYTNI6-EE4L2WS-S7KJES6-TK6Y4Q5";
71 | phone.id =
72 | "KYKZF7Z-TD62SOX-5A6LEWA-URNMNF7-CSNWD2E-ALNXGIC-P4PXDSI-4N6EHAV";
73 | vultr.id =
74 | "JRGIZAD-VHMLCCH-PFONWDZ-JEHKFAS-QG2ODRM-L7CWZBZ-SYD3LJF-DXZC3QI";
75 | };
76 | };
77 | };
78 | }
79 |
--------------------------------------------------------------------------------
/modules/services/teamviewer.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.services.teamviewer;
6 | in {
7 | options.modules.services.teamviewer = {
8 | enable = mkBoolOpt false;
9 | };
10 |
11 | config = mkIf cfg.enable {
12 | services.teamviewer.enable = true;
13 | };
14 | }
15 |
--------------------------------------------------------------------------------
/modules/services/transmission.nix:
--------------------------------------------------------------------------------
1 | { config, options, pkgs, lib, my, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.services.transmission;
6 | in {
7 | options.modules.services.transmission = {
8 | enable = mkBoolOpt false;
9 | };
10 |
11 | config = mkIf cfg.enable {
12 | services.transmission = {
13 | enable = true;
14 | home = "${homeDir}/torrents";
15 | settings = {
16 | incomplete-dir-enabled = true;
17 | rpc-whitelist = "127.0.0.1,192.168.*.*";
18 | rpc-host-whitelist = "*";
19 | rpc-host-whitelist-enabled = true;
20 | ratio-limit = 0;
21 | ratio-limit-enabled = true;
22 | };
23 | };
24 |
25 | networking.firewall = {
26 | allowedTCPPorts = [ 51413 ];
27 | allowedUDPPorts = [ 51413 ];
28 | };
29 |
30 | user.extraGroups = [ "transmission" ];
31 | };
32 | }
33 |
--------------------------------------------------------------------------------
/modules/shell/bitwarden.nix:
--------------------------------------------------------------------------------
1 | { config, options, pkgs, lib, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.shell.bitwarden;
6 | in {
7 | options.modules.shell.bitwarden = with types; {
8 | enable = mkBoolOpt false;
9 | config = mkOpt attrs { };
10 | };
11 |
12 | config = mkIf cfg.enable {
13 | user.packages = with pkgs; [ bitwarden-cli ];
14 |
15 | system.userActivationScripts = mkIf (cfg.config != { }) {
16 | initBitwarden = ''
17 | ${concatStringsSep "\n"
18 | (mapAttrsToList (n: v: "bw config ${n} ${v}") cfg.config)}
19 | '';
20 | };
21 | };
22 | }
23 |
--------------------------------------------------------------------------------
/modules/shell/direnv.nix:
--------------------------------------------------------------------------------
1 | { config, options, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.shell.direnv;
6 | in {
7 | options.modules.shell.direnv = {
8 | enable = mkBoolOpt false;
9 | preventGC = mkBoolOpt false;
10 | };
11 |
12 | config = mkIf cfg.enable {
13 | user.packages = with pkgs; [ direnv nix-direnv ];
14 | nix.extraOptions = mkIf cfg.preventGC ''
15 | keep-outputs = true
16 | keep-derivations = true
17 | '';
18 |
19 | environment.pathsToLink = [ "/share/nix-direnv" ];
20 | home.configFile = {
21 | "direnv/config".text =
22 | "source /run/current-system/sw/share/nix-direnv/direnvrc";
23 | };
24 |
25 | modules.shell.fish.rcInit = ''direnv hook fish | source'';
26 |
27 | home.configFile = {
28 | "direnv" = {
29 | source = "${configDir}/direnv";
30 | recursive = true;
31 | };
32 | };
33 | };
34 | }
35 |
--------------------------------------------------------------------------------
/modules/shell/file.nix:
--------------------------------------------------------------------------------
1 | # fast terminal browsing
2 | { config, options, lib, pkgs, ... }:
3 |
4 | with lib;
5 | with lib.my;
6 | let cfg = config.modules.shell.file;
7 |
8 | # convenient interaction and support for lots of different types of files
9 | in {
10 | options.modules.shell.file = { enable = mkBoolOpt false; };
11 |
12 | config = mkIf cfg.enable {
13 | user.packages = with pkgs; [
14 | joshuto # tui file browser
15 | poppler_utils # pdf preview
16 | ffmpegthumbnailer # video thumbnails
17 | xdg_utils # xdg-open is used a lot
18 | feh # image viewer
19 | zathura # pdf viewer
20 | bat # text file viewer
21 | mediainfo # image and video metadata viewer
22 | mpv # video and audio player
23 | ];
24 |
25 | home.configFile = {
26 | "joshuto" = {
27 | source = "${configDir}/joshuto";
28 | recursive = true; # include all utils, config files, etc...
29 | };
30 | };
31 | };
32 | }
33 |
--------------------------------------------------------------------------------
/modules/shell/fish.nix:
--------------------------------------------------------------------------------
1 | { config, options, pkgs, lib, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.shell.fish;
6 | loginInit = config.modules.shell.loginInit;
7 | in {
8 | options.modules.shell.fish = with types; {
9 | enable = mkBoolOpt false;
10 |
11 | aliases = mkOpt (attrsOf (either str path)) { };
12 |
13 | rcInit = mkOpt' lines "" ''
14 | Fish commands to be run when fish starts up.
15 | '';
16 | loginInit = mkOpt' lines "" ''
17 | Other fish commands to be run before fish starts up. It's worth noting that these run before 'rcInit' commands.
18 | '';
19 |
20 | rcFiles = mkOpt (listOf (either str path)) [ ];
21 | envFiles = mkOpt (listOf (either str path)) [ ];
22 | };
23 |
24 | config = mkIf cfg.enable {
25 | users.defaultUserShell = pkgs.fish;
26 |
27 | programs.fish = {
28 | enable = true;
29 | promptInit = with pkgs; ''
30 | set fish_greeting
31 | function fish_mode_prompt; end
32 | function fish_prompt; end
33 |
34 | function postexec_test --on-event fish_postexec
35 | echo
36 | end
37 |
38 | fish_add_path /etc/nixos/bin
39 | ${starship}/bin/starship init fish | source
40 | ${zoxide}/bin/zoxide init fish | source
41 | ${cfg.loginInit}
42 | ${cfg.rcInit}
43 | '';
44 |
45 | loginShellInit = loginInit;
46 |
47 | shellAliases = with pkgs; {
48 | # use the souped-up rust stuff!
49 | "ls" = "${exa}/bin/exa";
50 | "cat" = "${bat}/bin/bat";
51 | "find" = "${fd}/bin/fd";
52 | "ps" = "${procs}/bin/procs";
53 | "grep" = "${ripgrep}/bin/rg";
54 |
55 | # other sane shell reconfigurations
56 | "q" = "exit";
57 | "cp" = "cp -i";
58 | "mv" = "mv -i";
59 | "rm" = "rm -i";
60 | "mkdir" = "mkdir -p";
61 | "sc" = "systemctl";
62 | "ssc" = "sudo systemctl";
63 |
64 | # cool idea: remind me later!
65 | # r() {
66 | # local time=$1; shift
67 | # sched "$time" "notify-send --urgency=critical 'Reminder' '$@'; ding";
68 | # }; compdef r=sched
69 | };
70 | };
71 |
72 | user.packages = with pkgs; [
73 | starship
74 | bat
75 | exa
76 | fd
77 | procs
78 | ripgrep
79 | tokei
80 | tealdeer # tldr
81 | fzf
82 | zoxide
83 | ];
84 |
85 | home.configFile = {
86 | "starship.toml".text = (concatMapStringsSep "\n" readFile [ "${configDir}/starship/starship.toml" ]);
87 | };
88 | };
89 | }
90 |
--------------------------------------------------------------------------------
/modules/shell/git.nix:
--------------------------------------------------------------------------------
1 | { config, options, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.shell.git;
6 | in {
7 | options.modules.shell.git = { enable = mkBoolOpt false; };
8 |
9 | config = mkIf cfg.enable {
10 | user.packages = with pkgs; [
11 | git
12 | gitflow
13 | gitAndTools.gh
14 | gitAndTools.git-open
15 | gitAndTools.diff-so-fancy
16 | gitAndTools.git-absorb
17 | (mkIf config.modules.shell.gnupg.enable gitAndTools.git-crypt)
18 | # semantic diff!
19 | difftastic
20 | # good diff page viewer
21 | delta
22 | ];
23 |
24 | environment.shellAliases = with pkgs; {
25 | "ga" = "${git}/bin/git add";
26 | "gap" = "${git}/bin/git add --patch";
27 | "gb" = "${git}/bin/git branch -av";
28 | "gop" = "${git}/bin/git open";
29 | "gbl"="${git}/bin/git blame";
30 | "gc"="${git}/bin/git commit";
31 | "gcm"="${git}/bin/git commit -m";
32 | "gca"="${git}/bin/git commit --amend";
33 | "gcf"="${git}/bin/git commit --fixup";
34 | "gcl"="${git}/bin/git clone";
35 | "gco"="${git}/bin/git checkout";
36 | "gcoo"="${git}/bin/git checkout --";
37 | "gf"="${git}/bin/git fetch";
38 | "gi"="${git}/bin/git init";
39 | "gl"="${git}/bin/git log --graph --pretty=\"format:%C(yellow)%h%Creset %C(red)%G?%Creset%C(green)%d%Creset %s %Cblue(%cr) %C(bold blue)<%aN>%Creset\"";
40 | "gll"="${git}/bin/git log --pretty=\"format:%C(yellow)%h%Creset %C(red)%G?%Creset%C(green)%d%Creset %s %Cblue(%cr) %C(bold blue)<%aN>%Creset\"";
41 | "gL"="gl --stat";
42 | "gp"="${git}/bin/git push";
43 | "gpl"="${git}/bin/git pull --rebase --autostash";
44 | "gs"="${git}/bin/git status --short .";
45 | "gss"="${git}/bin/git status";
46 | "gst"="${git}/bin/git stash";
47 | "gr"="${git}/bin/git reset HEAD";
48 | "grv"="${git}/bin/git rev-parse";
49 | };
50 |
51 | home.configFile = {
52 | "git/config".source = "${configDir}/git/config";
53 | "git/ignore".source = "${configDir}/git/ignore";
54 | "gh/config.yml".source = "${configDir}/gh/config.yml";
55 | };
56 | };
57 | }
58 |
--------------------------------------------------------------------------------
/modules/shell/gnupg.nix:
--------------------------------------------------------------------------------
1 | { config, options, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.shell.gnupg;
6 | in {
7 | options.modules.shell.gnupg = with types; {
8 | enable = mkBoolOpt false;
9 | gui = mkBoolOpt false;
10 | cacheTTL = mkOpt int 3600; # 1hr
11 | };
12 |
13 | config = mkIf cfg.enable {
14 | environment.variables.GNUPGHOME = "$XDG_CONFIG_HOME/gnupg";
15 | programs.gnupg.agent.enable = true;
16 | user.packages = with pkgs; [
17 | tomb
18 | # all three are necessary for some reason
19 | pinentry.curses
20 | # pinentry-gnome
21 | pinentry-emacs
22 | ];
23 |
24 | # HACK Without this config file you get "No pinentry program" on 20.03.
25 | # programs.gnupg.agent.pinentryFlavor doesn't appear to work, and this
26 | # is cleaner than overriding the systemd unit.
27 | # pinentry-program ${pkgs.pinentry.curses}/bin/pinentry
28 | # TODO: this may not line up with emacs
29 | programs.gnupg.agent.pinentryPackage = pkgs.emacs;
30 | home.configFile."gnupg/gpg.conf" = {
31 | text = ''
32 | pinentry-mode loopback
33 | '';
34 | };
35 | home.configFile."gnupg/gpg-agent.conf" = {
36 | text = ''
37 | allow-emacs-pinentry
38 | allow-loopback-pinentry
39 | enable-ssh-support
40 | pinentry-program ${if true then pkgs.pinentry-emacs else (if cfg.gui then pkgs.pinentry-gnome else pkgs.pinentry-curses)}/bin/pinentry
41 | default-cache-ttl ${toString cfg.cacheTTL}
42 | max-cache-ttl ${toString cfg.cacheTTL}
43 | '';
44 | };
45 | };
46 | }
47 |
--------------------------------------------------------------------------------
/modules/shell/nushell.nix:
--------------------------------------------------------------------------------
1 | { config, options, pkgs, lib, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.shell.nushell;
6 | loginInit = config.modules.shell.loginInit;
7 | in {
8 | options.modules.shell.loginInit = with types; mkOpt' lines "" ''
9 | Shell commands to be run before the shell starts up. Assume POSIX-compatibility here.
10 | '';
11 |
12 | options.modules.shell.nushell = with types; {
13 | enable = mkBoolOpt false;
14 | };
15 |
16 | config = mkIf cfg.enable {
17 | users.defaultUserShell = pkgs.nushell;
18 |
19 | user.packages = with pkgs; [
20 | nushell
21 | starship
22 | bat
23 | ];
24 |
25 | environment.variables.ANTHROPIC_API_KEY = secrets.llm.ANTHROPIC_API_KEY;
26 |
27 | home.configFile = {
28 | "starship.toml".text = (concatMapStringsSep "\n" readFile [ "${configDir}/starship/starship.toml" ]);
29 | "nushell/config.nu".text = (concatMapStringsSep "\n" readFile [ "${configDir}/nushell/config.nu" ]);
30 | "nushell/login.nu".text = (concatMapStringsSep "\n" readFile [ "${configDir}/nushell/login.nu" ]);
31 | "nushell/env.nu".text = (concatMapStringsSep "\n" readFile [ "${configDir}/nushell/env.nu" ]);
32 | };
33 | };
34 | }
35 |
--------------------------------------------------------------------------------
/modules/shell/tmux.nix:
--------------------------------------------------------------------------------
1 | { config, options, pkgs, lib, stdenv, ... }:
2 |
3 |
4 | # if you're using tmux again,
5 | # revisit all of the former zsh aliases to find some useful commands
6 | # that might be worth revisiting!
7 |
8 | with lib;
9 | with lib.my;
10 | let
11 | cfg = config.modules.shell.tmux;
12 | # Despite tmux/tmux#142, tmux will support XDG in 3.2. Sadly, only 3.0 is
13 | # available on nixpkgs, and 3.1b on master (tmux/tmux@15d7e56), so I
14 | # implement it myself:
15 | tmux = (pkgs.writeScriptBin "tmux" ''
16 | #!${pkgs.stdenv.shell}
17 | exec ${pkgs.tmux}/bin/tmux -f "$TMUX_HOME/config" "$@"
18 | '');
19 | in {
20 | options.modules.shell.tmux = with types; {
21 | enable = mkBoolOpt false;
22 | rcFiles = mkOpt (listOf (either str path)) [ ];
23 | };
24 |
25 | config = mkIf cfg.enable {
26 | user.packages = [ tmux ];
27 |
28 | modules.theme.onReload.tmux =
29 | "${tmux}/bin/tmux source-file $XDG_CONFIG_HOME/tmux/extraInit";
30 |
31 | home.configFile = {
32 | "tmux" = {
33 | source = "${configDir}/tmux";
34 | recursive = true;
35 | };
36 | "tmux/extraInit".text = ''
37 | # This file is auto-generated by nixos, don't edit by hand!
38 | run-shell ${pkgs.tmuxPlugins.copycat}/share/tmux-plugins/copycat/copycat.tmux
39 | run-shell ${pkgs.tmuxPlugins.prefix-highlight}/share/tmux-plugins/prefix-highlight/prefix_highlight.tmux
40 | run-shell ${pkgs.tmuxPlugins.yank}/share/tmux-plugins/yank/yank.tmux
41 | # run-shell ${pkgs.tmuxPlugins.nord}/share/tmux-plugins/nord-tmux/nord.tmux
42 |
43 | ${concatMapStrings (path: ''
44 | source '${path}'
45 | '') cfg.rcFiles}
46 | '';
47 | };
48 |
49 | env = {
50 | PATH = [ "$TMUXIFIER/bin" ];
51 | TMUX_HOME = "$XDG_CONFIG_HOME/tmux";
52 | TMUXIFIER = "$XDG_DATA_HOME/tmuxifier";
53 | TMUXIFIER_LAYOUT_PATH = "$XDG_DATA_HOME/tmuxifier";
54 | };
55 | };
56 | }
57 |
--------------------------------------------------------------------------------
/modules/term/alacritty.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let
6 | cfg = config.modules.term.alacritty;
7 | colors = config.modules.theme.color;
8 | in {
9 | options.modules.term.alacritty = { enable = mkBoolOpt false; };
10 | config = mkIf cfg.enable {
11 | user.packages = with pkgs; [ alacritty ];
12 | home.configFile = {
13 | "alacritty/alacritty.toml".text = with colors;
14 | concatStrings [
15 | (concatMapStringsSep "\n" readFile
16 | [ "${configDir}/alacritty/alacritty.toml" ])
17 | ];
18 | };
19 | };
20 | }
21 |
--------------------------------------------------------------------------------
/modules/term/default.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.term;
6 | in {
7 | options.modules.term = {
8 | default = mkOpt types.str "xterm";
9 | };
10 |
11 | config = {
12 | services.xserver.desktopManager.xterm.enable = mkDefault (cfg.default == "xterm");
13 |
14 | env.TERMINAL = cfg.default;
15 | };
16 | }
17 |
--------------------------------------------------------------------------------
/modules/term/foot.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let
6 | cfg = config.modules.term.foot;
7 | colors = config.modules.theme.color;
8 | in {
9 | options.modules.term.foot = { enable = mkBoolOpt false; };
10 | config = mkIf cfg.enable {
11 | user.packages = with pkgs; [ foot ];
12 | home.configFile = {
13 | "foot/foot.ini".text = with colors;
14 | concatStrings [
15 | (concatMapStringsSep "\n" readFile
16 | [ "${configDir}/foot/foot.ini" ])
17 | (''
18 | [colors]
19 | alpha=1.0
20 | background=${background}
21 | foreground=${foreground}
22 |
23 | ## Normal/regular colors (color palette 0-7)
24 | regular0=${color0} # black
25 | regular1=${color1} # red
26 | regular2=${color2} # green
27 | regular3=${color3} # yellow
28 | regular4=${color4} # blue
29 | regular5=${color5} # magenta
30 | regular6=${color6} # cyan
31 | regular7=${color7} # white
32 |
33 | ## Bright colors (color palette 8-15)
34 | bright0=${color8} # bright black
35 | bright1=${color9} # bright red
36 | bright2=${color10} # bright green
37 | bright3=${color11} # bright yellow
38 | bright4=${color12} # bright blue
39 | bright5=${color13} # bright magenta
40 | bright6=${color14} # bright cyan
41 | bright7=${color15} # bright white
42 |
43 | ## dimmed colors (see foot.ini(5) man page)
44 | dim0=${dim.black}
45 | dim1=${dim.red}
46 | dim2=${dim.green}
47 | dim3=${dim.yellow}
48 | dim4=${dim.blue}
49 | dim5=${dim.magenta}
50 | dim6=${dim.cyan}
51 | dim7=${dim.white}
52 |
53 | ## The remaining 256-color palette
54 | # 16 = <256-color palette #16>
55 | # ...
56 | # 255 = <256-color palette #255>
57 |
58 | ## Misc colors
59 | # selection-foreground=
60 | # selection-background=
61 | # jump-labels= # black-on-yellow
62 | # scrollback-indicator= # black-on-bright-blue
63 | # search-box-no-match= # black-on-red
64 | # search-box-match= # black-on-yellow
65 | # urls=
66 | '')
67 | ];
68 | };
69 | };
70 | }
71 |
--------------------------------------------------------------------------------
/modules/themes/stilla/default.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let
6 | cfg = config.modules.theme;
7 | colorscheme = {
8 | stilla0 = "0D0D0D";
9 | stilla1 = "121414";
10 | stilla2 = "1A1C1C";
11 | stilla3 = "4C566A";
12 | stilla4 = "F2F2F2";
13 | stilla5 = "FAFAFA";
14 | stilla6 = "FAF5EF";
15 | stilla7 = "8FBCBB";
16 | stilla8 = "88B6D0";
17 | stilla9 = "ADB2BA";
18 | stilla10 = "5E81AC";
19 | stilla11 = "BA8082";
20 | stilla12 = "d99962";
21 | stilla13 = "E9B872";
22 | stilla14 = "A19C9A";
23 | stilla15 = "CD96B3";
24 | };
25 | in {
26 | config = mkIf (cfg.active == "stilla") (mkMerge [
27 | # Desktop-agnostic configuration
28 | {
29 | modules = {
30 | theme = {
31 | gtk = {
32 | theme = "Yaru";
33 | iconTheme = "Zafiro-icons";
34 | cursorTheme = "openzone-cursors";
35 | };
36 | color = with colorscheme; {
37 | foreground = stilla4;
38 | background = stilla0;
39 | fadeColor = stilla3;
40 | fgAlt = stilla6;
41 | bgAlt = stilla1;
42 | bgAlt2 = stilla2;
43 | color0 = stilla1;
44 | color1 = stilla11;
45 | color2 = stilla14;
46 | color3 = stilla13;
47 | color4 = stilla9;
48 | color5 = stilla15;
49 | color6 = stilla8;
50 | color7 = stilla5;
51 | color8 = stilla3;
52 | color9 = stilla11;
53 | color10 = stilla14;
54 | color11 = stilla13;
55 | color12 = stilla9;
56 | color13 = stilla15;
57 | color14 = stilla7;
58 | color15 = stilla6;
59 | normal = {
60 | black = stilla1;
61 | red = stilla11;
62 | green = stilla14;
63 | yellow = stilla13;
64 | blue = stilla9;
65 | magenta = stilla15;
66 | cyan = stilla8;
67 | white = stilla5;
68 | };
69 | alt = {
70 | black = stilla3;
71 | red = stilla11;
72 | green = stilla14;
73 | yellow = stilla13;
74 | blue = stilla9;
75 | magenta = stilla15;
76 | cyan = stilla7;
77 | white = stilla6;
78 | };
79 | dim = {
80 | black = "373e4d";
81 | red = "94545d";
82 | green = "809575";
83 | yellow = "b29e75";
84 | blue = "68809a";
85 | magenta = "8c738c";
86 | cyan = "6d96a5";
87 | white = "aeb3bb";
88 | };
89 | urgent = "FF5555";
90 | };
91 | };
92 | shell.tmux.rcFiles = [ ./config/tmux.conf ];
93 | browsers = {
94 | firefox.userChrome = concatMapStringsSep "\n" readFile
95 | [ ./config/firefox/userChrome.css ];
96 | };
97 | };
98 | }
99 |
100 | # Desktop theming
101 | {
102 | user.packages = with pkgs;
103 | [ yaru-theme zafiro-icons openzone-cursors ];
104 | # ++ (if config.modules.media.spotify.enable then
105 | # [ extras.spicetify-nix.packages.x86_64-linux.stilla ]
106 | # else
107 | # [ ]);
108 | fonts = {
109 | packages = with pkgs; [
110 | fira-code
111 | fira-code-symbols
112 | jetbrains-mono
113 | siji
114 | font-awesome
115 | roboto-mono
116 | ibm-plex
117 | ];
118 | fontconfig.defaultFonts = {
119 | sansSerif = [ "Fira Sans" ];
120 | monospace = [ "Berkeley Mono" ]; # was fira code
121 | };
122 | };
123 |
124 | home.configFile = mkIf config.modules.editors.vim.enable {
125 | "nvim/theme.vim" = { text = "colorscheme stilla"; };
126 | };
127 | }
128 | ]);
129 | }
130 |
--------------------------------------------------------------------------------
/modules/vm/lxd.nix:
--------------------------------------------------------------------------------
1 | # Inspired by https://www.srid.ca/2012301.html
2 |
3 | { options, config, lib, pkgs, ... }:
4 |
5 | with lib;
6 | with lib.my;
7 | let cfg = config.modules.vm.lxd;
8 | in {
9 | options.modules.vm.lxd = {
10 | enable = mkBoolOpt false;
11 | };
12 |
13 | config = mkIf cfg.enable {
14 | virtualisation.lxd.enable = true;
15 |
16 | user.packages = [
17 | (pkgs.writeScriptBin "lxc-build-nixos-image" ''
18 | #!/usr/bin/env nix-shell
19 | #!nix-shell -i bash -p nixos-generators
20 | set -xe
21 | config=$1
22 | metaimg=`nixos-generate -f lxc-metadata \
23 | | xargs -r cat \
24 | | awk '{print $3}'`
25 | img=`nixos-generate -c $config -f lxc \
26 | | xargs -r cat \
27 | | awk '{print $3}'`
28 | lxc image import --alias nixos $metaimg $img
29 | '')
30 | ];
31 | };
32 | }
33 |
--------------------------------------------------------------------------------
/modules/vm/qemu.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let cfg = config.modules.vm.qemu;
6 | in {
7 | options.modules.vm.qemu = {
8 | enable = mkBoolOpt false;
9 | };
10 |
11 | config = mkIf cfg.enable {
12 | environment.systemPackages = with pkgs; [
13 | qemu
14 | ];
15 | };
16 | }
17 |
18 | # Creating an image:
19 | # qemu-img create -f qcow2 disk.img
20 | # Creating a snapshot (don't tamper with disk.img):
21 | # qemu-img create -f qcow2 -b disk.img snapshot.img
22 |
--------------------------------------------------------------------------------
/modules/vm/virtualbox.nix:
--------------------------------------------------------------------------------
1 | # modules/desktop/vm/virtualbox.nix
2 | #
3 | # For testing or building software on other OSes. If I find out how to get macOS
4 | # on qemu/libvirt I'd be happy to leave virtualbox behind.
5 |
6 | { options, config, lib, pkgs, ... }:
7 |
8 | with lib;
9 | with lib.my;
10 | let cfg = config.modules.vm.virtualbox;
11 | in {
12 | options.modules.vm.virtualbox = {
13 | enable = mkBoolOpt false;
14 | };
15 |
16 | config = mkIf cfg.enable {
17 | virtualisation.virtualbox.host = {
18 | enable = true;
19 | # urg, takes so long to build, but needed for macOS guest
20 | enableExtensionPack = true;
21 | };
22 |
23 | users.extraGroups.vboxusers.members = [ "jake" ];
24 | user.extraGroups = [ "vboxusers" ];
25 | };
26 | }
27 |
--------------------------------------------------------------------------------
/modules/wayland/default.nix:
--------------------------------------------------------------------------------
1 | # Nice-to-haves for all Wayland compositors.
2 |
3 | { config, lib, pkgs, ... }:
4 |
5 | with lib;
6 | with lib.my;
7 | let cfg = config.modules.wayland;
8 | in {
9 |
10 | options.modules.wayland = { enable = mkBoolOpt false; };
11 | config = mkIf cfg.enable {
12 | env.XDG_SESSION_TYPE = "wayland";
13 |
14 | modules.wayland.wofi.enable = true;
15 |
16 | user.extraGroups = [
17 | # control video utilities
18 | "video"
19 | ];
20 |
21 | programs.light.enable = true;
22 |
23 | user.packages = with pkgs; [
24 | xwayland
25 | qt5.qtwayland
26 | wl-clipboard
27 | sway-contrib.grimshot
28 | wf-recorder
29 | # due to overlay these are now wayland clipboard interoperable
30 | xclip
31 | xsel
32 | # versatile audio control
33 | playerctl
34 | ];
35 | };
36 | }
37 |
--------------------------------------------------------------------------------
/modules/wayland/kanshi.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 | # notifications for wayland
3 |
4 | with lib;
5 | with lib.my;
6 | let
7 | colors = config.modules.theme.color;
8 | cfg = config.modules.wayland.kanshi;
9 | in {
10 | options.modules.wayland.kanshi = { enable = mkBoolOpt false; };
11 |
12 | config = mkIf cfg.enable {
13 | user.packages = with pkgs; [ kanshi ];
14 | systemd.user.services.kanshi = {
15 | description = "Kanshi output autoconfig ";
16 | wantedBy = [ "graphical-session.target" ];
17 | partOf = [ "graphical-session.target" ];
18 | serviceConfig = {
19 | # kanshi doesn't have an option to specifiy config file yet, so it looks
20 | # at .config/kanshi/config
21 | ExecStart = ''
22 | ${pkgs.kanshi}/bin/kanshi
23 | '';
24 | RestartSec = 5;
25 | Restart = "always";
26 | };
27 | };
28 | home.configFile = {
29 | "kanshi/config" = { source = "${configDir}/kanshi/config"; };
30 | };
31 | };
32 | }
33 |
--------------------------------------------------------------------------------
/modules/wayland/mako.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 | # notifications for wayland
3 |
4 | with lib;
5 | with lib.my;
6 | let
7 | colors = config.modules.theme.color;
8 | cfg = config.modules.wayland.mako;
9 | in {
10 | options.modules.wayland.mako = { enable = mkBoolOpt false; };
11 |
12 | config = mkIf cfg.enable {
13 | user.packages = with pkgs; [ mako ];
14 | home.configFile = {
15 | "mako/config".text = with colors; ''
16 | sort=-time
17 | layer=overlay
18 | max-visible=-1
19 | background-color=#${background}
20 | border-color=#${color0}
21 | text-color=#${foreground}
22 | width=300
23 | height=110
24 | border-size=1
25 | default-timeout=5000
26 | ignore-timeout=1
27 | margin=10,12
28 |
29 | [urgency=low]
30 | background-color=#${background}
31 | border-color=#${color0}
32 |
33 | [urgency=normal]
34 | background-color=#${background}
35 | border-color=#${color0}
36 |
37 | [urgency=high]
38 | background-color=#${urgent}
39 | border-color=#${urgent}
40 | default-timeout=0
41 |
42 | [category=mpd]
43 | default-timeout=2000
44 | group-by=category
45 |
46 | [category=spotify]
47 | default-timeout=2000
48 | group-by=category
49 | '';
50 | };
51 | };
52 | }
53 |
--------------------------------------------------------------------------------
/modules/wayland/swaylock.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 | # lock for wayland
3 |
4 | with lib;
5 | with lib.my;
6 | let
7 | colors = config.modules.theme.color;
8 | cfg = config.modules.wayland.swaylock;
9 | lock = with pkgs; (writeScriptBin "lock" ''
10 | #!${stdenv.shell}
11 | ${playerctl}/bin/playerctl pause &
12 | ${swaylock-effects}/bin/swaylock
13 | '');
14 | screenOff = with pkgs; (writeScriptBin "screenOff" ''
15 | #!${stdenv.shell}
16 | swaymsg "output * dpms off"
17 | '');
18 | screenOn = with pkgs; (writeScriptBin "screenOn" ''
19 | #!${stdenv.shell}
20 | swaymsg "output * dpms off"
21 | '');
22 | in {
23 | options.modules.wayland.swaylock = {
24 | enable = mkBoolOpt false;
25 | };
26 |
27 | config = mkIf cfg.enable {
28 | systemd.user.services.swayidle = {
29 | enable = true;
30 | description = "Idle Manager for Wayland";
31 | documentation = [ "man:swayidle(1)" ];
32 | wantedBy = [ "sway-session.target" ];
33 | partOf = [ "graphical-session.target" ];
34 | serviceConfig = {
35 | ExecStart = ''
36 | ${pkgs.swayidle}/bin/swayidle \
37 | timeout 300 '${lock}/bin/lock' \
38 | timeout 600 '${screenOff}/bin/screenOff' \
39 | resume '${screenOn}/bin/screenOn' \
40 | before-sleep '${lock}/bin/lock'
41 | '';
42 | };
43 | };
44 |
45 | user.packages = with pkgs; [ lock swayidle screenOff screenOn ];
46 | home.configFile = {
47 | "swaylock/config".text = (with colors; ''
48 | line-color=${colors.background}
49 | inside-color=${colors.background}
50 | ring-color=${background}
51 | separator-color=${colors.foreground}
52 | key-hl-color=${colors.foreground}
53 |
54 | line-wrong-color=${colors.background}
55 | inside-wrong-color=${colors.urgent}
56 | ring-wrong-color=${colors.urgent}
57 |
58 | line-ver-color=${colors.background}
59 | inside-ver-color=${colors.background}
60 | ring-ver-color=${colors.background}
61 |
62 | grace=30
63 | screenshots
64 | fade-in=0.15
65 | effect-pixelate=20
66 | indicator-radius=50
67 | '');
68 | };
69 | };
70 | }
71 |
--------------------------------------------------------------------------------
/modules/wayland/waybar.nix:
--------------------------------------------------------------------------------
1 | { config, lib, pkgs, ... }:
2 | # notifications for wayland
3 |
4 | with lib;
5 | with lib.my;
6 | let
7 | colors = config.modules.theme.color;
8 | cfg = config.modules.wayland.waybar;
9 | in {
10 | options.modules.wayland.waybar = { enable = mkBoolOpt false; };
11 |
12 | config = mkIf cfg.enable {
13 | user.packages = with pkgs;
14 | [
15 | (if config.modules.hardware.audio.enable then
16 | waybar.override { pulseSupport = true; }
17 | else
18 | waybar)
19 | ];
20 | home.configFile = {
21 | "waybar/config" = { source = "${configDir}/waybar/config"; };
22 |
23 | # waybar inspiration credit goes to github.com/jakehamilton!
24 | "waybar/style.css".text = (with colors;
25 | concatStrings [
26 | ''
27 | @define-color foreground #${fgAlt};
28 | @define-color background #${background};
29 | @define-color buttonhover #${urgent};
30 | @define-color fgalt #${fgAlt};
31 | @define-color bgalt #${bgAlt2};
32 | @define-color cyan #${normal.cyan};
33 | @define-color green #${normal.green};
34 | @define-color yellow #${normal.yellow};
35 | @define-color blue #${normal.blue};
36 | @define-color purple #${normal.magenta};
37 | @define-color cyanalt #${dim.cyan};
38 | @define-color greenalt #${dim.green};
39 | @define-color yellowalt #${dim.yellow};
40 | @define-color bluealt #${dim.blue};
41 | @define-color purplealt #${dim.magenta};
42 | ''
43 | (concatMapStringsSep "\n" readFile
44 | [ "${configDir}/waybar/style.css" ])
45 | ]);
46 | };
47 | };
48 | }
49 |
--------------------------------------------------------------------------------
/modules/wayland/wofi.nix:
--------------------------------------------------------------------------------
1 | { options, config, lib, pkgs, ... }:
2 |
3 | with lib;
4 | with lib.my;
5 | let
6 | cfg = config.modules.wayland.wofi;
7 | colors = config.modules.theme.color;
8 | in {
9 | options.modules.wayland.wofi = { enable = mkBoolOpt false; };
10 |
11 | config = mkIf cfg.enable {
12 | user.packages = with pkgs; [
13 | wofi
14 | (writeScriptBin "launch" ''
15 | #!${stdenv.shell}
16 | exec ${wofi}/bin/wofi --show drun
17 | '')
18 | ];
19 |
20 | home.configFile = {
21 | "wofi/config".text = ''
22 | width=15%
23 | lines=5
24 | allow_images=false
25 | insensitive=true
26 | mode=drun
27 | '';
28 | "wofi/style.css".text = with colors; ''
29 | window {
30 | margin: 0px;
31 | border-width: 0px;
32 | border-radius: 0px;
33 | }
34 |
35 | #input {
36 | color: #${color4};
37 | padding: 8px;
38 | background-color: #${background};
39 | border-width: 1px 1px 1px 1px;
40 | border-color: #${color10};
41 | }
42 |
43 | #inner-box {
44 | border-color: #${color10};
45 | border-width: 0px 1px 1px 1px;
46 | background-color: #${background};
47 | }
48 |
49 | #outer-box {
50 | border-width: 0px 1px 1px 1px;
51 | background-color: #${background};
52 | }
53 |
54 | #scroll {
55 | margin: 0px;
56 | border: none;
57 | }
58 |
59 | #text {
60 | color: #${color4};
61 | padding: 5px;
62 | border: none;
63 | }
64 |
65 | button {
66 | padding: 6px;
67 | color: #${foreground};
68 | border-width: 2px 0px 2px 2px;
69 | border-color: #${foreground};
70 | }
71 |
72 | button selected normal {
73 | border-width: 0;
74 | }
75 | '';
76 | };
77 | };
78 | }
79 |
--------------------------------------------------------------------------------
/modules/xdg.nix:
--------------------------------------------------------------------------------
1 | # xdg.nix
2 | #
3 | # Set up and enforce XDG compliance. Other modules will take care of their own,
4 | # but this takes care of the general cases.
5 | { config, home-manager, ... }: {
6 | ### A tidy $HOME is a tidy mind
7 | home-manager.users.${config.user.name}.xdg.enable = true;
8 |
9 | environment = {
10 | sessionVariables = {
11 | # These are the defaults, and xdg.enable does set them, but due to load
12 | # order, they're not set before environment.variables are set, which could
13 | # cause race conditions.
14 | XDG_CACHE_HOME = "$HOME/.cache";
15 | XDG_CONFIG_HOME = "$HOME/.config";
16 | XDG_DATA_HOME = "$HOME/.local/share";
17 | XDG_BIN_HOME = "$HOME/.local/bin";
18 |
19 | # Prevent auto-creation of ~/Desktop. The trailing slash is necessary; see
20 | # https://bugzilla.mozilla.org/show_bug.cgi?id=1082717
21 | XDG_DESKTOP_DIR = "$HOME/";
22 | XDG_DOWNLOAD_DIR = "$HOME/";
23 | XDG_DOWNLOADS_DIR = "$HOME/";
24 | XDG_PICTURES_DIR = "$HOME/pics/";
25 | XDG_MUSIC_DIR = "$HOME/music/";
26 | };
27 | variables = {
28 | # Conform more programs to XDG conventions. The rest are handled by their
29 | # respective modules.
30 | __GL_SHADER_DISK_CACHE_PATH = "$XDG_CACHE_HOME/nv";
31 | ASPELL_CONF = ''
32 | per-conf $XDG_CONFIG_HOME/aspell/aspell.conf;
33 | personal $XDG_CONFIG_HOME/aspell/en_US.pws;
34 | repl $XDG_CONFIG_HOME/aspell/en.prepl;
35 | '';
36 | CUDA_CACHE_PATH = "$XDG_CACHE_HOME/nv";
37 | HISTFILE = "$XDG_DATA_HOME/bash/history";
38 | INPUTRC = "$XDG_CONFIG_HOME/readline/inputrc";
39 | LESSHISTFILE = "$XDG_CACHE_HOME/lesshst";
40 | # WGETRC = "$XDG_CONFIG_HOME/wgetrc"; -- I don't use this
41 |
42 | # Tools I don't use
43 | # SUBVERSION_HOME = "$XDG_CONFIG_HOME/subversion";
44 | # BZRPATH = "$XDG_CONFIG_HOME/bazaar";
45 | # BZR_PLUGIN_PATH = "$XDG_DATA_HOME/bazaar";
46 | # BZR_HOME = "$XDG_CACHE_HOME/bazaar";
47 | # ICEAUTHORITY = "$XDG_CACHE_HOME/ICEauthority";
48 | };
49 |
50 | # Move ~/.Xauthority out of $HOME (setting XAUTHORITY early isn't enough)
51 | extraInit = ''
52 | export XAUTHORITY=/tmp/Xauthority
53 | [ -e ~/.Xauthority ] && mv -f ~/.Xauthority "$XAUTHORITY"
54 | '';
55 |
56 | };
57 | }
58 |
--------------------------------------------------------------------------------
/overlays/x-clipboard.nix:
--------------------------------------------------------------------------------
1 | final: prev: {
2 | wl-clipboard-x11 = prev.stdenv.mkDerivation rec {
3 | pname = "wl-clipboard-x11";
4 | version = "5";
5 |
6 | src = prev.fetchFromGitHub {
7 | owner = "brunelli";
8 | repo = "wl-clipboard-x11";
9 | rev = "v${version}";
10 | sha256 = "1y7jv7rps0sdzmm859wn2l8q4pg2x35smcrm7mbfxn5vrga0bslb";
11 | };
12 |
13 | dontBuild = true;
14 | dontConfigure = true;
15 | propagatedBuildInputs = [ prev.wl-clipboard ];
16 | makeFlags = [ "PREFIX=$(out)" ];
17 | };
18 |
19 | xsel = final.wl-clipboard-x11;
20 | xclip = final.wl-clipboard-x11;
21 | }
22 |
--------------------------------------------------------------------------------
/packages/.git-keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jakeisnt/nixcfg/e9230d4f90a855a290882a6e7862c593a114cf5e/packages/.git-keep
--------------------------------------------------------------------------------
/shell.nix:
--------------------------------------------------------------------------------
1 | (import
2 | (
3 | let
4 | flake-compat = (builtins.fromJSON (builtins.readFile ./flake.lock)).nodes.flake-compat;
5 | in
6 | fetchTarball {
7 | url = "https://github.com/edolstra/flake-compat/archive/${flake-compat.locked.rev}.tar.gz";
8 | sha256 = flake-compat.locked.narHash;
9 | }
10 | )
11 | {src = ./.;})
12 | .shellNix
13 |
--------------------------------------------------------------------------------
/templates/flake/.envrc:
--------------------------------------------------------------------------------
1 | if has nix; then
2 | use nix
3 | fi
4 |
--------------------------------------------------------------------------------
/templates/flake/flake.nix:
--------------------------------------------------------------------------------
1 | {
2 | description = "An empty project";
3 |
4 | inputs = {
5 | nixpkgs.url = "github:nixos/nixpkgs/release-24.05";
6 | flake-utils.url = "github:numtide/flake-utils";
7 | zig.url = "github:mitchellh/zig-overlay";
8 |
9 | # Used for shell.nix
10 | flake-compat = {
11 | url = github:edolstra/flake-compat;
12 | flake = false;
13 | };
14 | };
15 |
16 | outputs = {
17 | self,
18 | nixpkgs,
19 | flake-utils,
20 | ...
21 | } @ inputs: let
22 | overlays = [ ];
23 | in
24 | flake-utils.lib.eachDefaultSystem (
25 | system: let
26 | pkgs = import nixpkgs {inherit overlays system;};
27 | in rec {
28 | devShells.default = pkgs.mkShell {
29 | nativeBuildInputs = with pkgs; [
30 | ];
31 | };
32 |
33 | # For compatibility with older versions of the `nix` binary
34 | devShell = self.devShells.${system}.default;
35 | }
36 | );
37 | }
38 |
--------------------------------------------------------------------------------
/templates/flake/shell.nix:
--------------------------------------------------------------------------------
1 | (import
2 | (
3 | let
4 | flake-compat = (builtins.fromJSON (builtins.readFile ./flake.lock)).nodes.flake-compat;
5 | in
6 | fetchTarball {
7 | url = "https://github.com/edolstra/flake-compat/archive/${flake-compat.locked.rev}.tar.gz";
8 | sha256 = flake-compat.locked.narHash;
9 | }
10 | )
11 | {src = ./.;})
12 | .shellNix
13 |
--------------------------------------------------------------------------------