1
0
mirror of https://github.com/kmein/niveum synced 2026-03-16 10:11:08 +01:00

1 Commits

Author SHA1 Message Date
2d25c1fc7b wip: add specus VPN 2023-04-14 08:43:23 +02:00
366 changed files with 11188 additions and 12224 deletions

38
.bin/256color Executable file
View File

@@ -0,0 +1,38 @@
#! /bin/sh
set -euf
pl() {
for i in $(seq $1 $(expr $2 - 1)); do
printf '\e[38;5;%sm%03i\e[m ' $i $i
done
printf '\e[38;5;%sm%03i\e[m\n' $2 $2
}
p() {
printf '\e[38;5;%sm%03i\e[m ' $1 $1
}
pn() {
printf '\e[38;5;%sm%03i\e[m\n' $1 $1
}
p6x6() {
for i in $(seq 0 5); do
for j in $(seq 0 5); do
p $(expr $1 + $i + $j \* 6)
done
echo
done
}
pl 0 7
pl 8 15
p6x6 16
p6x6 52
p6x6 88
p6x6 124
p6x6 160
p6x6 196
pl 232 243
pl 244 255

29
.bin/anki-poem.sh Executable file
View File

@@ -0,0 +1,29 @@
#!/bin/sh
file="${1?please supply a poetry file}"
[ -f "$file" ] || {
echo "'$file' is no file"
exit 1
}
poem="$(mktemp)"
clean () {
rm "$poem"
}
trap clean EXIT
sed '/^$/d' "$file" > "$poem"
htmlize() {
awk 'ORS="<br/>"' \
| head -c -5 # remove final <br/> characters
}
for line_number in $(seq 1 "$(wc -l "$poem" | cut -d' ' -f1)"); do
if [ "$line_number" -gt 3 ] && [ "$line_number" -gt 1 ]; then
sed -n "$((line_number - 3)),$((line_number - 1))p" "$poem"
else
sed -n "1,$((line_number - 1))p" "$poem"
fi | htmlize
printf '\t'
sed -n "${line_number},+1p" "$poem" | htmlize
printf '\n'
done

54
.bin/avesta.sed Executable file
View File

@@ -0,0 +1,54 @@
#!/usr/bin/env -S sed -f
s/ā̊/𐬃/g
s//𐬝/g
s/ṣ̌/𐬴/g
s/š́/𐬳/g
s/ą̄/𐬅/g
s/ŋᵛ/𐬤/g
s/ə̄/𐬇/g
s/ŋ́/𐬣/g
s//𐬒/g
s/xᵛ/𐬓/g
s/a/𐬀/g
s/ā/𐬁/g
s/å/𐬂/g
s/ą/𐬄/g
s/ə/𐬆/g
s/e/𐬈/g
s/ē/𐬉/g
s/o/𐬊/g
s/ō/𐬋/g
s/i/𐬌/g
s/ī/𐬍/g
s/u/𐬎/g
s/ū/𐬏/g
s/k/𐬐/g
s/x/𐬑/g
s/g/𐬔/g
s/ġ/𐬕/g
s/γ/𐬖/g
s/c/𐬗/g
s/j/𐬘/g
s/t/𐬙/g
s/θ/𐬚/g
s/d/𐬛/g
s/δ/𐬜/g
s/p/𐬞/g
s/f/𐬟/g
s/b/𐬠/g
s/β/𐬡/g
s/ŋ/𐬢/g
s/n/𐬥/g
s/ń/𐬦/g
s//𐬧/g
s/m/𐬨/g
s//𐬩/g
s//𐬫/g
s/y/𐬪/g
s/v/𐬬/g
s/r/𐬭/g
s/s/𐬯/g
s/z/𐬰/g
s/š/𐬱/g
s/ž/𐬲/g
s/h/𐬵/g

24
.bin/browser Executable file
View File

@@ -0,0 +1,24 @@
#!/bin/sh -e
#
# Usage: browser
# pipe html to a browser
# e.g.
# $ echo '<h1>hi mom!</h1>' | browser
# $ ron -5 man/rip.5.ron | browser
if [ -t 0 ]; then
if [ -n "$1" ]; then
open $1
else
cat <<usage
Usage: browser
pipe html to a browser
$ echo '<h1>hi mom!</h1>' | browser
$ ron -5 man/rip.5.ron | browser
usage
fi
else
f="/tmp/browser.$RANDOM.html"
cat /dev/stdin > $f
xdg-open $f
fi

46
.bin/bvg.sh Executable file
View File

@@ -0,0 +1,46 @@
#!/bin/sh
interesting="U6 N6 140 M46 184 N84"
curl -sSL 'https://www.bvg.de/disruption-reports/q' \
--data-raw '{"variables":{},"query":"{
allDisruptions {
disruptions {
meldungsId
linie
verkehrsmittel
__typename
... on Traffic {
datum
gueltigVonDatum
gueltigVonZeit
gueltigBisDatum
gueltigBisZeit
richtungName
richtungHafasId
beginnAbschnittName
beginnAbschnittHafasId
endeAbschnittName
endeAbschnittHafasId
textIntUrsache
sev
textIntAuswirkung
umfahrung
textWAPSMSUrsache
textWAPSMSAuswirkung
prioritaet
__typename
}
}
__typename
}
}"}' \
| jq --arg interesting "$interesting" '
.data.allDisruptions.disruptions
| map(select(
(.linie as $linie
| $interesting
| split(" ")
| index($linie))
and (.["__typename"] == "Traffic")
))
'

19
.bin/calendars.sh Executable file
View File

@@ -0,0 +1,19 @@
#!/bin/sh
directory="$(mktemp -d)"
trap clean EXIT
clean() {
rm -rf "$directory"
}
year=$(date +%Y)
output=/tmp/$year.pdf
for month in $(seq 1 12); do
printf "\r%d" "$month" 1>&2
astrolog -zN Berlin -qm "$month" "$year" -X -K -XA -Xr -Xm -Xb -Xo "$(printf "%s/%02d.bmp" "$directory" "$month")" -Xw 1080 720 2>/dev/null
done
printf "\r"
convert "$directory/*.bmp" "$output"
echo "$output"

25
.bin/candyman Executable file
View File

@@ -0,0 +1,25 @@
#!/bin/sh
set -efu
usage() {
echo >&2 "$0 add-{reddit,telegram,youtube,twitch,twitter} NAME"
exit 1
}
candyman() {
curl -fsSv http://news.r/api -H content-type:application/json -d "$(jq -n "
{
command: \"PRIVMSG\",
params: [\"#all\", \"candyman: $1 $2\"]
}
")"
}
[ $# -ge 2 ] || usage
case "$1" in
add-reddit|add-telegram|add-youtube|add-twitter|add-twitch)
candyman "$@"
;;
*) usage;;
esac

23
.bin/chunk-pdf Executable file
View File

@@ -0,0 +1,23 @@
#! /usr/bin/env nix-shell
#! nix-shell -i bash -p pdftk gnugrep
set -efu
INPUT_FILE="${2:?Pass the PDF path as second argument.}"
PAGES_PER_REPORT="${1:?Pass the chunk size as first argument.}"
if [ ! -f "$INPUT_FILE" ]; then
echo >&2 "File $INPUT_FILE does not exist."
exit 1
fi
TOTAL_PAGES="$(pdftk "$INPUT_FILE" dump_data | grep NumberOfPages | cut -f2 -d' ')"
RUNS=$((TOTAL_PAGES/PAGES_PER_REPORT))
for run in $(seq 0 "$((RUNS-1))"); do
start_page=$((run*PAGES_PER_REPORT+1))
end_page=$(((run+1)*PAGES_PER_REPORT))
output_file="chunk_$((run+1)).pdf"
echo "splitting $INPUT_FILE from $start_page to $end_page into $output_file"
pdftk "$INPUT_FILE" cat "$start_page-$end_page" output "$output_file"
done

13
.bin/countdown Executable file
View File

@@ -0,0 +1,13 @@
#!/usr/bin/env -S awk -f
function z() {
getline < "/proc/uptime"
close("/proc/uptime")
return $0
}
BEGIN {
x = z()
while (1) {
y = z()
printf "%02d:%05.2f\r", (y - x) / 60, (y - x) % 60
}
}

14
.bin/csv2json Executable file
View File

@@ -0,0 +1,14 @@
#!/usr/bin/env python3
import csv
import json
import sys
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--delimiter", "-d", default=",", help="CSV field separator")
args = parser.parse_args()
if __name__ == "__main__":
json.dump(list(csv.DictReader(sys.stdin, delimiter=args.delimiter)), sys.stdout)

43
.bin/dummy-alert Executable file
View File

@@ -0,0 +1,43 @@
#!/bin/bash
name=$RANDOM
url='http://localhost:9093/api/v1/alerts'
echo "firing up alert $name"
# change url o
curl -XPOST $url -d "[{
\"status\": \"firing\",
\"labels\": {
\"alertname\": \"$name\",
\"service\": \"my-service\",
\"severity\":\"warning\",
\"instance\": \"$name.example.net\"
},
\"annotations\": {
\"summary\": \"High latency is high!\"
},
\"generatorURL\": \"http://prometheus.int.example.net/<generating_expression>\"
}]"
echo ""
echo "press enter to resolve alert"
read
echo "sending resolve"
curl -XPOST $url -d "[{
\"status\": \"resolved\",
\"labels\": {
\"alertname\": \"$name\",
\"service\": \"my-service\",
\"severity\":\"warning\",
\"instance\": \"$name.example.net\"
},
\"annotations\": {
\"summary\": \"High latency is high!\"
},
\"generatorURL\": \"http://prometheus.int.example.net/<generating_expression>\"
}]"
echo ""

7
.bin/elm-publish-private Executable file
View File

@@ -0,0 +1,7 @@
#! /usr/bin/env nix-shell
#! nix-shell -p "(import <nixpkgs> { overlays = [ (import ~/work/fysiweb/engiadina-pwa/devops/pkgs) ]; }).elm-publish-private"
#! nix-shell -i bash
set -efux
exec elm-publish-private "$@"

34
.bin/horoscope.sh Normal file
View File

@@ -0,0 +1,34 @@
#!/bin/sh
set -efu
# Berlin: -d lodeg=13 -d lomin=22 -d losec=41 -d lodir=E -d ladeg=52 -d lamin=27 -d lasec=42 -d ladir=N -d usecoords=1 \
# Kassel: -d lodeg=9 -d lomin=32 -d losec=5 -d lodir=E -d ladeg=51 -d lamin=18 -d lasec=17 -d ladir=N -d usecoords=1 \
[ $# -eq 1 ] || {
echo >&2 Usage: "$0" TIMESTAMP
exit 1
}
export TZ=UTC
chart_path="$(mktemp /tmp/chart_XXX.pdf)"
timestamp="$1"
year="$(date -d "@$timestamp" +%Y)"
month="$(date -d "@$timestamp" +%m)"
day="$(date -d "@$timestamp" +%d)"
hour="$(date -d "@$timestamp" +%H)"
minute="$(date -d "@$timestamp" +%M)"
curl -sSL 'https://edifyingfellowship.org/astro/' \
-d lodeg=9 -d lomin=32 -d losec=5 -d lodir=E -d ladeg=51 -d lamin=18 -d lasec=17 -d ladir=N -d usecoords=1 \
-d ybyr="$year" -d ybmo="$month" -d ybdy="$day" -d ybhr="$hour" -d ybmi="$minute" -d ybsc=0 -d ybtz="$TZ" \
-d currenttime=0 \
-d title="$timestamp" \
-d options[]=VancouverWheel -d options[]=Arrow -d options[]=XBold -d options[]=HouseLabels -d options[]=Placidus \
-d options[]=Sun -d options[]=Moon -d options[]=Mercury -d options[]=Venus -d options[]=Mars -d options[]=Jupiter -d options[]=Saturn -d options[]=Uranus -d options[]=Neptune -d options[]=Pluto -d options[]=Ascendant -d options[]=MC -d options[]=Lilith -d options[]=MeanNode -d options[]=TrueNode \
-d aspectpct=100 -d format=PDF -d Submit= -o "$chart_path"
zathura "$chart_path"

24
.bin/json2csv Executable file
View File

@@ -0,0 +1,24 @@
#!/usr/bin/env python3
import csv
import json
import sys
if __name__ == "__main__":
json_list = json.load(sys.stdin)
if not isinstance(json_list, list):
print("JSON object is not a list.", file=sys.stderr)
sys.exit(1)
if len(json_list) == 0:
print("JSON list is empty.", file=sys.stderr)
sys.exit(1)
keys = set()
for element in json_list:
if isinstance(element, dict):
keys |= element.keys()
else:
print("Non-dict element:", element, file=sys.stderr)
sys.exit(1)
writer = csv.DictWriter(sys.stdout, fieldnames=list(keys))
writer.writeheader()
for element in json_list:
writer.writerow(element)

5
.bin/json2csv.jq Executable file
View File

@@ -0,0 +1,5 @@
#!/usr/bin/env -S jq -r -f
(map(keys) | add | unique) as $cols
| map(. as $row | $cols | map($row[.])) as $rows
| $cols, $rows[]
| @csv

15
.bin/libib.sh Executable file
View File

@@ -0,0 +1,15 @@
#!/usr/bin/env bash
session_id=7b638c194d9bda74f80043045018cc9e
declare -A libraries
libraries["Literatur"]=344428
libraries["Sprache"]=344160
libraries["Miscellanea"]=344427
libraries["Wissenschaft"]=344429
libraries["Relicta"]=565920
for library in ${!libraries[@]}
do
curl -sSL 'https://www.libib.com/library/functions/csv-export.php' -H "Cookie: PHPSESSID=$session_id" -d export="${libraries[$library]}" > "$library.csv"
done

81
.bin/lieferando.sh Normal file
View File

@@ -0,0 +1,81 @@
#!/bin/sh
set -efu
if echo "$1" | grep -Eq '[[:digit:]]{5}'; then
PLZ="$1"
else
echo >&2 "Usage: $0 PLZ"
exit 1
fi
lieferando_dir=/tmp/lieferando
mkdir -p "$lieferando_dir/$PLZ"
fetch_restaurants() {
cache_path="$lieferando_dir/$PLZ.json"
if [ -r "$cache_path" ]; then
cat "$cache_path"
else
w3m -dump_source "http://www.lieferando.de/$PLZ" \
| gunzip \
| sed -n '/var restaurants/,/];$/p' \
| sed 's/var restaurants =//;$s/;$//' \
| prettier --parser=json \
| jq '
map({
name: .[30] | .name,
category: .[30] |.categories | split(", "),
url: "http://lieferando.de\(.[30] | .url)",
minutes: .[19],
minimum: .[10],
delivery: .[14]
})' \
| tee "$cache_path"
fi
}
fetch_menu() {
[ $# -eq 1 ] || exit 1
slug="$(echo "$1" | sed 's!.*/!!')"
cache_path="$lieferando_dir/$PLZ/$slug.json"
if [ -r "$cache_path" ]; then
cat "$cache_path"
else
w3m -dump_source "$1" \
| gunzip \
| sed -n '/var MenucardProducts/,/\];/p' \
| sed 's/var MenucardProducts =//;s/;$//' \
| jq -r '
unique_by(.productId)
| group_by(.categoryId)
| flatten
' \
| tee "$cache_path"
fi
}
data="$(fetch_restaurants)"
# echo "$data" | jq -c '.[]' | while read -r restaurant; do
# fetch_menu "$(echo "$restaurant" | jq -r .url)"
# done
selected_categories="$(echo "$data" | jq -r 'map(.category) | flatten | unique | .[]' | fzf -m)"
selected_restaurant_url="$(echo "$selected_categories" | jq --argjson restaurants "$data" -sRr '
split("\n")[:-1] as $categories
| $restaurants[]
| select(.category - $categories != .category)
| "\(.name) [🚴\(.minutes)min 💰\(.minimum)€ + \(.delivery)€] (\(.url))"
' \
| fzf \
| sed 's/.*(//;s/)$//'
)"
fetch_menu "$selected_restaurant_url" \
| jq -r '.[] | "\(.price)\t\(.name)"' \
| fzf -m \
| awk '{print $0; sum += $1} END {print "-----"; print sum}'

17
.bin/lit.awk Normal file
View File

@@ -0,0 +1,17 @@
BEGIN {
if (!comment) comment = "--";
if (!begin) begin = "\\begin{code}";
if (!end) end = "\\end{code}";
}
{
if ($0 == begin) {
code = 1;
print comment, $0;
} else if ($0 == end) {
code = 0;
print comment, $0;
} else {
if (code) print $0;
else print comment, $0;
}
}

3
.bin/mail-current-part Executable file
View File

@@ -0,0 +1,3 @@
#! /bin/sh
set -efu
exec curl -fSs --unix-socket /tmp/much.api.sock http://localhost/current/part

View File

@@ -0,0 +1,27 @@
#! /bin/sh
# usage: mail-current-query-find-part-by-name NAME
set -efu
name=$1
query=$(mail-current-query)
result=$(notmuch show --entire-thread=false --format=json "$query")
part_id=$(printf %s "$result" | jq --arg name "$name" '
[
recurse |
select(type == "object") |
{ id, name: .filename } |
select(.id != null and .name != null)
] |
map(select(.name == $name))[0].id
')
if test "$part_id" = null; then
printf 'error: could not find part with name %s\n' \
"$name" \
>&2
exit 1
fi
exec notmuch show --part="$part_id" "$query"

View File

@@ -0,0 +1,39 @@
#! /bin/sh
# usage: mail-current-query-find-part-by-type TYPE
set -efu
type=$1
query=$(mail-current-query)
result=$(notmuch show --entire-thread=false --format=json "$query")
part_id=$(printf %s "$result" | jq --arg type "$type" '
#flatten|map(select(.!=null))[0].body[0] |
#
#if .["content-type"] == $type then
# .id
#elif .["content-type"] | test("^multipart/") then
# .content|map(select(.["content-type"]==$type))[0].id
#else
# null
#end
[
recurse |
select(type == "object") |
{ id, type: .["content-type"] } |
select(.id != null and .type != null)
] |
map(select(.type == $type))[0].id
')
if test "$part_id" = null; then
printf 'error: could not find part with type %s\n' \
"$type" \
>&2
exit 1
fi
exec notmuch show --part="$part_id" "$query"

1
.bin/mud.sh Executable file
View File

@@ -0,0 +1 @@
ssh mud@hotdog.r -t "MUD_NICKNAME=$LOGNAME mud"

6
.bin/mushakkil.sh Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/sh
curl -sSL 'https://diac.alsharekh.org/Diac/DiacText' \
-H "Content-Type: application/json" \
--data-raw "$(jq --raw-input '{word: ., type: 1}')" \
--compressed \
| jq -r .diacWord

93
.bin/nix-haddock-index Executable file
View File

@@ -0,0 +1,93 @@
#! /usr/bin/env nix-shell
#! nix-shell -i bash -p coreutils gnugrep gnused graphviz
#
# usage: nix-haddock-index
#
# Run this script in an environment where either NIX_GHC is set, or the ghc
# executable exists, to generate an HTML index file pointing to all Haddock
# files accessible to the respective ghc version.
#
# Additionally, an SVG dependency graph of all packages is linked at the
# bottom of the index file.
#
# Note: all files will be generated in /tmp, and won't be deleted automatically
#
set -efux
if test -z "${NIX_GHC-}"; then
NIX_GHC=$(readlink -f "$(type -P ghc)")
fi
if ! echo $NIX_GHC | grep -q '^/nix/store/'; then
printf '%s: error: unsupported GHC executable path (not in Nix store): %q\n' \
"$0" \
"$NIX_GHC" \
>&2
exit -1
fi
NIX_GHC_PREFIX=$(dirname "$(dirname "$NIX_GHC")")
NIX_GHC_DOCDIR=$NIX_GHC_PREFIX/share/doc/ghc/html
main() {
hash=$(echo $NIX_GHC_PREFIX | sed -n 's|^/nix/store/\([a-z0-9]\+\).*|\1|p')
title="Haddock index for $NIX_GHC_PREFIX"
header=$(
printf 'Haddock index for <a href="%s">%s</a>\n' \
$NIX_GHC_PREFIX \
$NIX_GHC_PREFIX \
)
suffix=${hash:+-$hash}
index_file=/tmp/haddock$suffix-index.html
svg_file=/tmp/haddock$suffix.svg
#if ! test -e $index_file; then
eval "$(
echo 'gen_index() {'
echo ' html_head'
"$NIX_GHC_PREFIX"/bin/ghc-pkg dump | sed -n '
s/^---$/ reset/p
s/^\(name\|version\):\s*\([-A-Za-z0-9_.]\+\)$/ \1=\2/p
s/^haddock-html:\s*\([-A-Za-z0-9_./]\+\)$/ haddock_html \1/p
'
echo ' html_foot'
echo '}'
)"
gen_index > $index_file
#fi
#if ! test -e $svg_file; then
"$NIX_GHC_PREFIX"/bin/ghc-pkg dot | tred | dot -Tsvg | sed '
s/<svg width="[0-9]\+pt" height="[0-9]\+pt"/<svg width="3600px" height="100%"/
' > $svg_file
#fi
echo $index_file
}
reset() {
unset name version
}
haddock_html() {
printf '<li>'
printf '<a href="%s/index.html">%s</a>' "$1" "$name-$version"
printf '</li>\n'
}
html_head() {
printf '<!doctype html>\n'
printf '<title>%s</title>\n' "$title"
printf '<link href="%s" rel="stylesheet" type="text/css">\n' \
"$NIX_GHC_DOCDIR/libraries/ocean.css"
printf '<h1>%s</h1>\n' "$header"
printf '<ul>\n'
}
html_foot() {
printf '</ul>\n'
printf '<a href="%s">graph</a>\n' "$svg_file"
}
main "$@"

15
.bin/notetags.sh Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
# inspired by https://github.com/connermcd/bin/blob/1d38cb98812906d8b95dc6e51e1149e29261617d/notetags
cd "$HOME/notes/" || exit
[ -f tags ] && rm tags
grep -r 'tags:' ./* | while read -r line; do
file=$(echo "$line" | cut -d: -f1)
unparsed_tags=$(echo "$line" | cut -d: -f3) #
tags=$(echo "$unparsed_tags" | sed -e 's/tags: *//g' -e 's/[][,]//g')
for tag in $tags; do
echo "$tag $file /^$unparsed_tags$/;" >> tags
done
done

23
.bin/pdf-ocr.sh Executable file
View File

@@ -0,0 +1,23 @@
#!/usr/bin/env nix-shell
#! nix-shell -i bash -p poppler_utils tesseract4
set -eu
pdf_path="$(realpath "$1")"
[ -f "$pdf_path" ] || {
echo "Usage: $0 FILE.pdf" >&2
exit 1
}
tmpdir="$(mktemp -d)"
trap 'rm -rf $tmpdir' EXIT
cd "$tmpdir"
pdftoppm -png "$pdf_path" pdf-ocr
for png in pdf-ocr*.png; do
tesseract "$png" "$png.txt" 2>/dev/null
done
cat pdf-ocr-*.txt

2
.bin/playlist_entries.sh Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/sh
youtube-dl -ij "$*" | jq -sr '.[] | .webpage_url'

65
.bin/prospekte.sh Executable file
View File

@@ -0,0 +1,65 @@
#!/bin/sh
lidl() {
echo LIDL
curl -sSL 'https://endpoints.lidl-flyer.com/v3/region-overview/lidl/de-DE/0.json' \
| jq -r '
.categories
| map(select(.name == "Filial-Angebote") | .subcategories | map(.flyers))
| flatten
| flatten
| .[]
| .pdfUrl
'
}
aldi_nord() {
echo ALDI nord
echo 'https://magazine.aldi-nord.de/aldi-nord/aldi-aktuell/GetPDF.ashx'
echo 'https://magazine.aldi-nord.de/aldi-nord/aldi-vorschau/GetPDF.ashx'
}
rewe_berlin() {(
store_id=662366923
publisher_id=1062
echo REWE
curl -sSL 'https://www.bonialserviceswidget.de/de/stores/'$store_id'/brochures?storeId='$store_id'&publisherId='$publisher_id | while read -r brochure_id; do
curl -sSL 'https://www.bonialserviceswidget.de/de/v5/brochureDetails/'"$brochure_id"'?publisherId='$publisher_id | jq -r .pdfUrl
done
)}
kaufland() {(
region_code=8920
echo KAUFLAND
curl -sSL https://filiale.kaufland.de/prospekte.html | htmlq --attribute href '.flyer a' | grep -Eo 'DE_de_KDZ[^/]*' | sed "s/_3000_/_${region_code}_/" | while read -r flyer_id; do
curl -sSL "https://endpoints.leaflets.kaufland.com/v3/$flyer_id/flyer.json?regionCode=$region_code" | jq -r .flyer.pdfUrl
done
)}
netto_schwarz() {
echo 'NETTO (schwarz)'
curl -sSL 'https://squid-api.tjek.com/v2/catalogs?dealer_ids=90f2VL&order_by=created' \
| jq -r '.[] | .id' \
| while read -r flyer_id; do
curl -sSL "https://squid-api.tjek.com/v2/catalogs/$flyer_id/download" \
| jq -r .pdf_url
done
}
dir="$(mktemp -d)"
trap clean EXIT
clean() {
rm -rf "$dir"
}
prospekt_url="$( (
lidl
aldi_nord
rewe_berlin
kaufland
netto_schwarz
) | fzf)"
curl -sSL "$prospekt_url" -o "$dir/prospekt.pdf"
zathura "$dir/prospekt.pdf"

17
.bin/proxies.sh Normal file
View File

@@ -0,0 +1,17 @@
#!/bin/sh
curl -sSL https://www.netzwelt.de/proxy/index.html \
| pup ".tblc" \
| xml-to-json /dev/stdin \
| jq '
.div.table.tbody.tr
| map(
.td
| {
ip: .[0].a.value,
port: .[1],
country: .[2] | (if type == "string" then . else .a.value end),
security: .[3],
protocol: .[4]
}
)
'

4
.bin/readme Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
curl -sSL "https://raw.githubusercontent.com/$*/master/README.md" \
| pandoc -f gfm -t man -s \
| man -l -

6
.bin/sample-pdf.sh Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/sh
filepath="$(shuf --head-count=1)"
pages="$(pdfinfo "$filepath" | awk '/^Pages:/{print $2}')"
random_page="$(shuf --input-range="1-$pages" --head-count=1)"
zathura --page="$random_page" "$filepath"

16
.bin/screencap.sh Executable file
View File

@@ -0,0 +1,16 @@
#! /usr/bin/env nix-shell
#! nix-shell -i sh -p coreutils byzanz xorg.xwininfo gnused
# shellcheck shell=sh
# ref https://gist.github.com/aforemny/0994cb7f06ea30d56c8b9681ff5d2054
set -eux
eval "$(xwininfo | \
sed -n -e 's/^ \+Absolute upper-left X: \+\([0-9]\+\).*/x=\1/p' \
-e 's/^ \+Absolute upper-left Y: \+\([0-9]\+\).*/y=\1/p' \
-e 's/^ \+Width: \+\([0-9]\+\).*/w=\1/p' \
-e 's/^ \+Height: \+\([0-9]\+\).*/h=\1/p')"
trap "pkill -f 'sleep 360d'" INT
byzanz-record -e "sleep 360d" -c -x $x -y $y -w $w -h $h "$@"

49
.bin/space.py Normal file
View File

@@ -0,0 +1,49 @@
import ephem
from datetime import datetime, date, timedelta
now = datetime.now()
limit = now + timedelta(days=365)
def events_until(limit):
initial_date = ephem.Date(datetime.now())
events = {}
now = initial_date
while ephem.localtime(now) <= limit:
now = ephem.next_full_moon(now)
events[now] = "🌕"
now = initial_date
while ephem.localtime(now) <= limit:
now = ephem.next_new_moon(now)
events[now] = "🌑"
now = initial_date
while ephem.localtime(now) <= limit:
now = ephem.next_vernal_equinox(now)
events[now] = "spring equinox"
now = initial_date
while ephem.localtime(now) <= limit:
now = ephem.next_autumnal_equinox(now)
events[now] = "fall equinox"
now = initial_date
while ephem.localtime(now) <= limit:
now = ephem.next_winter_solstice(now)
events[now] = "winter solstice"
now = initial_date
while ephem.localtime(now) <= limit:
now = ephem.next_summer_solstice(now)
events[now] = "summer solstice"
return events
events = events_until(limit)
for date, event in sorted(events.items(), key=lambda x: x[0]):
if ephem.localtime(date) < limit:
print(ephem.localtime(date), event)

50
.bin/toposort.nix Normal file
View File

@@ -0,0 +1,50 @@
let
lib = import <nixpkgs/lib>;
in rec {
inherit lib;
input = [
{
x = ["pool" "zfs"];
y = ["mdadm" "raid1"];
}
{
x = ["pool" "zfs"];
y = ["disk" "sda"];
}
{
x = ["mdadm" "raid1"];
y = ["disk" "sdb"];
}
{
x = ["mdadm" "raid1"];
y = ["disk" "sdc"];
}
];
outNodes = node: graph:
lib.unique
(builtins.map (e: e.y)
(builtins.filter (v: v.x == node) graph));
vertices = graph:
lib.unique
(builtins.map (x: x.y) graph ++ builtins.map (x: x.x) graph);
deleteVertex = node: graph: (builtins.filter (v: v.x != node && v.y != node) graph);
findSink = graph:
lib.findFirst
(v: outNodes v graph == [])
(lib.trace graph (builtins.abort "No sink found"))
(vertices graph);
topSort = graph:
if graph == []
then []
else if builtins.length graph == 1
then let only = builtins.head graph; in [only.y only.x]
else let sink = findSink graph; in [sink] ++ topSort (deleteVertex sink graph);
output = topSort input;
}

18
.bin/ttrss-unread Executable file
View File

@@ -0,0 +1,18 @@
#/usr/bin/env -S deno run -A:q
set -x
session_cache="$HOME/.cache/tt-rss.session"
ttrss_endpoint=https://feed.kmein.de/api/
ttrss_user=k
ttrss_password=$(pass shared/tt-rss/password)
login() {
if [ -f "$session_cache" ]; then
session_id="$(cat "$session_cache")"
else
session_id="$(curl -d '{"op":"login","user":"'"$ttrss_user"'","password":"'"$ttrss_password"'"}' "$ttrss_endpoint" | jq -r .content.session_id)"
echo "$session_id" > "$session_cache"
fi
}
login
curl -d '{"sid":"'"$session_id"'","op":"getUnread"}' "$ttrss_endpoint" | jq .content

16
.bin/tuesday-1800 Executable file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
set -efux
expected_max_results=1024 # the upper bound on the number of restaurants
radius=250
echo '[out:json];node(id:260050809)->.cbase;
(
node(around.cbase:'$radius')[amenity=fast_food];
node(around.cbase:'$radius')[amenity=restaurant];
);out;' \
| curl -sSL -d @- -X POST http://overpass-api.de/api/interpreter \
| jq --argjson random "$(shuf -i 0-$expected_max_results -n 1)" '
.elements
| length as $length
| .[$random % $length]
'

8
.bin/unicode Normal file
View File

@@ -0,0 +1,8 @@
import sys
import unicodedata
for index, character in enumerate(sys.stdin.read().strip()):
try:
print(index, character, hex(ord(character)), unicodedata.category(character), unicodedata.name(character))
except:
print(index, character, hex(ord(character)))

26
.bin/watson2fdf.sh Executable file
View File

@@ -0,0 +1,26 @@
project=Filli
year=2022
for month in Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec; do
from="$(date +%F -d "$month 1, $year")"
to="$(date +%F -d "$month 1, $year + 1 month")"
watson report --json --from "$from" --to "$to" --project "$project"
done | jq --slurp '
def in_array($arr):
. as $value | any($arr[]; . == $value);
map(
["engadin-app","fysiweb","val-muestair","mia-engiadina","ol"] as $official_projects
| (.timespan.from | .[0:7]) as $timespan
| .projects | .[0]
| .time as $total_time
| .tags
| select(. != null)
| map(select(.name | in_array($official_projects)))
| (map(.time)|add) as $official_time
| map({key:.name, value:.time}) | from_entries
| .other |= ($total_time - $official_time)
| map_values(. / (60*60) | ceil)
| .month |= $timespan
)
'

View File

@@ -2,7 +2,7 @@ name: Update flake.lock
on:
workflow_dispatch: # allows manual triggering
schedule:
- cron: "0 0 * * 0" # runs weekly on Sunday at 00:00
- cron: '0 0 * * 0' # runs weekly on Sunday at 00:00
jobs:
lockfile:

View File

@@ -7,33 +7,8 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
system: [makanek, manakish, kabsa, zaatar, ful, fatteh]
system: [makanek,manakish,kabsa,zaatar,ful]
steps:
- uses: actions/checkout@v3
- name: Install QEMU (ARM)
run: |
sudo apt-get update
sudo apt-get install -y qemu-user-static
if: ${{ matrix.system == 'ful' }}
- name: Install Nix (ARM)
uses: cachix/install-nix-action@v16
if: ${{ matrix.system == 'ful' }}
with:
extra_nix_config: |
system = aarch64-linux
- name: Install Nix (x86_64)
uses: cachix/install-nix-action@v16
if: ${{ matrix.system != 'ful' }}
- name: nixos-rebuild dry-build
run: |
# remove secrets: ref https://stackoverflow.com/questions/1260748/how-do-i-remove-a-submodule/36593218
git submodule deinit -f secrets
rm -rf .git/modules/secrets
git rm -f secrets
# recreate secrets
mkdir secrets
cat secrets.txt | while read -r path; do touch $path; done
git add secrets
nix run nixpkgs#nixos-rebuild -- dry-build --flake $GITHUB_WORKSPACE#${{matrix.system}}
- uses: actions/checkout@v2
- uses: cachix/install-nix-action@v16
- run: nix run .?submodules=1#apps.nixinate.${{matrix.system}}-dry-run

View File

@@ -1,96 +0,0 @@
# niveum — Agent Notes
## What This Is
A NixOS flake managing ~9 machines (desktops, servers, family laptops) for one user (kmein/kfm).
Levantine food-themed hostnames: fatteh, kabsa, kibbeh, makanek, manakish, tabula, tahina, zaatar, ful.
## Repository Structure
```
flake.nix # ~670 lines — inputs, overlay, nixosConfigurations, apps, packages output
configs/ # ~50 NixOS config fragments imported by systems
default.nix # 200+ line mega-module for desktop machines (user, shell, gnupg, i18n, etc.)
graphical/ # Hyprland + home-manager config (415 lines in home-manager.nix)
packages.nix # ~250 lines of environment.systemPackages
bots/ # Telegram/Mastodon/Matrix bot configs
keyboard/ # XKB layouts (Coptic, Avestan, Gothic, etc.)
configs/*.nix # Individual concerns: bluetooth, sound, printing, ssh, fonts, etc.
modules/ # Proper NixOS modules with options (retiolum, telegram-bot, passport, power-action, etc.)
packages/ # ~107 package files (scripts, wrappers, small tools)
systems/<name>/ # Per-machine: configuration.nix + hardware-configuration.nix + extras
lib/ # default.nix (niveum helpers), machines.nix (IP/key inventory), panoptikon.nix
secrets/ # agenix-encrypted .age files (empty dir in checkout, tracked via secrets.txt)
```
## Key Relationships
- **niphas** (input): Provides shared "how I like things" config — nixosModules (shell, editor, git, desktop, nix, udiskie) and overlay (niphas-* packages). Used in `profiles.default` and `profiles.desktop`.
- **configs/default.nix**: The "big desktop profile" — imported by fatteh, kabsa, manakish (the main desktop machines). NOT imported by servers or family laptops.
- **profiles** (in flake.nix): `profiles.default`, `profiles.desktop`, `profiles.server` — lists of modules composed per machine.
- **lib.niveum**: Custom lib injected via overlay (`pkgs.lib.niveum`) — used everywhere for machine addresses, SSH port, helper functions.
## Coding Conventions
- Packages use `writers.writeDashBin`, `writers.writeBashBin`, or `writers.writePython3Bin`
- Dependencies are referenced via `lib.getExe pkg` (main executable) or `lib.getExe' pkg "name"` (specific binary)
- For packages needing many commands via PATH, use `lib.makeBinPath` instead (see `packages/prospekte.nix`)
- Overlay entries use `prev.callPackage packages/foo.nix { }` pattern
- Packages are exported via `inherit (pkgs) ...` in the `packages` output
## Known Bugs / Broken References
All previously broken references have been fixed (see commits `36132b04`, `e67d6d7d`).
Remaining issues:
- `modules/retiolum.nix` uses `<retiolum/hosts>` and `<system-secrets/...>` NIX_PATH lookups — breaks flake purity but works with current `NIX_PATH` setup
## Architectural Issues
### 1. configs/default.nix is a grab-bag (200+ lines, ~15 inline anonymous modules)
It's a list of `imports` mixing inline `{ ... }` blocks with file imports. Hard to find what's defined where.
### 2. Retiolum secret boilerplate repeated 9 times
Every system has a near-identical block:
```nix
age.secrets.retiolum-rsa = { file = ../../secrets/${hostname}-retiolum-privateKey-rsa.age; mode = "400"; owner = "tinc-retiolum"; ... };
age.secrets.retiolum-ed25519 = { ... same ... };
```
Could be a function or module parameterized by hostname.
### 3. Nginx + ACME boilerplate duplicated
ful and makanek have identical nginx recommended settings + ACME config.
### 4. niveum-* overlay aliases
`niveum-terminal`, `niveum-browser`, `niveum-filemanager` are aliases to niphas equivalents. Could be removed by updating ~6 references in configs/ to use niphas-* names directly.
### 5. The `pkgs.lib.niveum` pattern
Custom lib injected via overlay into `pkgs.lib`. Unconventional — only available where overlay is applied. A `specialArgs` approach or standalone lib would be cleaner.
### 6. Restic backup config scattered
`services.restic.backups.niveum` is configured in configs/backup.nix, configs/applicative.nix, and extended in 5+ system files. Hard to see what a given machine backs up.
### 7. configs/ vs modules/ distinction blurry
`configs/` has both stateless config fragments (spacetime.nix = timezone) and stateful ones (backup.nix, cloud.nix). `modules/` has proper option-declaring modules. Some configs/ files import from modules/.
## Machines Overview
| Machine | Role | Profile | Arch | Notes |
|-----------|--------------|------------------|---------|---------------------------------------|
| fatteh | Desktop | default+desktop | x86_64 | ThinkPad T480, CUDA, main daily |
| kabsa | Desktop | default+desktop | x86_64 | ThinkPad X220, constrained (2 jobs) |
| manakish | Desktop | default+desktop | x86_64 | ThinkPad X230 |
| kibbeh | Desktop | default+desktop | x86_64 | Pantheon DE, travel laptop |
| ful | Server | default+server | aarch64 | Oracle/Hetzner, nginx, web services |
| makanek | Server | default+server | x86_64 | Hetzner, gitea, nextcloud, weechat |
| zaatar | Server/Home | default+server | x86_64 | Home assistant, backup server |
| tabula | Family laptop| default | x86_64 | LXQt, user "xenos" |
| tahina | Family laptop| default | x86_64 | Pantheon, user "xenos", German |
## Remaining Improvement Ideas
1. **Extract retiolum secret boilerplate** into a function/module
2. **Break up configs/default.nix** into proper named files
3. **Extract nginx+ACME server profile**
4. **Replace niveum-* aliases** with direct niphas-* references
5. **Fix modules/retiolum.nix** NIX_PATH usage for flake purity

View File

@@ -1,18 +1,10 @@
# niveum
> I must Create a System, or be enslav'd by another Man's. —William Blake
> [nĭvĕus](https://logeion.uchicago.edu/niveus), a, um, adj. [nix], _of_ or _from snow, snowy, snow-_ (poet.)
>
> 1. Lit.: aggeribus niveis informis, Verg. G. 3, 354: aqua, _cooled with snow_, Mart. 12, 17, 6; cf. id. 14, 104 and 117: mons, _covered with snow_, Cat. 64, 240.—
>
> 2. Transf., _snow-white, snowy_ (mostly poet.): a similitudine sic: Corpore niveum candorem, aspectu igneum ardorem assequebatur, Auct. Her. 4, 33, 44: lacerti, Verg. A. 8, 387: lac, id. E. 2, 20: hanc si capite niveae agnae exorari judicas, Sen. Q. N. 2, 36: Briseis niveo colore, Hor. C. 2, 4, 3: vestis, Ov. M. 10, 432: candidior nivei folio, Galatea, ligustri, id. ib. 13, 789: dens, id. H. 18, 18: quā notam duxit niveus videri, Hor. C. 4, 2, 59: panis, Juv. 5, 70: flumen, _clear, pellucid_, Sen. Hippol. 504: undae, Mart. 7, 32, 11: tribuni, _clothed in white togas_, Calp. Ecl. 7, 29; so, Quirites, Juv. 10, 45.
## Pressestimmen
> das ist ja pure poesie —[riotbib](https://github.com/riotbib/)
> Deine Configs sind wunderschön <3 —[flxai](https://github.com/flxai/)
## To do
🦗
> das ist ja pure poesie —[xkey](https://github.com/riotbib)

View File

@@ -3,17 +3,29 @@
config,
lib,
...
}:
{
}: let
defaults = {
aerc.enable = true;
realName = "Kierán Meinhardt";
folders.inbox = "INBOX";
};
hu-defaults = {
imap.host = "mailbox.cms.hu-berlin.de";
imap.port = 993;
smtp.host = "mailhost.cms.hu-berlin.de";
smtp.port = 25;
smtp.tls.useStartTls = true;
};
in {
age.secrets = {
email-password-ical-ephemeris = {
file = ../secrets/email-password-ical-ephemeris.age;
email-password-cock = {
file = ../secrets/email-password-cock.age;
owner = config.users.users.me.name;
group = config.users.users.me.group;
mode = "400";
};
email-password-cock = {
file = ../secrets/email-password-cock.age;
email-password-fysi = {
file = ../secrets/email-password-fysi.age;
owner = config.users.users.me.name;
group = config.users.users.me.group;
mode = "400";
@@ -24,11 +36,33 @@
group = config.users.users.me.group;
mode = "400";
};
email-password-meinhark = {
file = ../secrets/email-password-meinhark.age;
owner = config.users.users.me.name;
group = config.users.users.me.group;
mode = "400";
};
email-password-meinhaki = {
file = ../secrets/email-password-meinhaki.age;
owner = config.users.users.me.name;
group = config.users.users.me.group;
mode = "400";
};
email-password-dslalewa = {
file = ../secrets/email-password-dslalewa.age;
owner = config.users.users.me.name;
group = config.users.users.me.group;
mode = "400";
};
email-password-fsklassp = {
file = ../secrets/email-password-fsklassp.age;
owner = config.users.users.me.name;
group = config.users.users.me.group;
mode = "400";
};
};
home-manager.users.me = {
accounts.email.maildirBasePath = "${config.users.users.me.home}/state/Maildir";
services.mbsync = {
enable = true;
frequency = "daily";
@@ -41,15 +75,14 @@
extraConfig = {
database.path = config.home-manager.users.me.accounts.email.maildirBasePath;
new.tags = "";
user.name = pkgs.lib.niveum.email.defaults.realName;
user.name = defaults.realName;
user.primary_email = config.home-manager.users.me.accounts.email.accounts.posteo.address;
};
};
programs.mbsync = {
enable = true;
extraConfig = lib.concatStringsSep "\n\n" (
lib.mapAttrsToList (name: account: ''
extraConfig = lib.concatStringsSep "\n\n" (lib.mapAttrsToList (name: account: ''
IMAPAccount ${name}
CertificateFile /etc/ssl/certs/ca-certificates.crt
Host ${account.imap.host}
@@ -73,85 +106,119 @@
Patterns *
Remove None
SyncState *
'') config.home-manager.users.me.accounts.email.accounts
);
'')
config.home-manager.users.me.accounts.email.accounts);
};
accounts.email.accounts = {
accounts.email.accounts = rec {
hu-student =
lib.recursiveUpdate defaults
(lib.recursiveUpdate hu-defaults
rec {
userName = "meinhark";
address = "kieran.felix.meinhardt@hu-berlin.de";
aliases = ["${userName}@hu-berlin.de"];
passwordCommand = "${pkgs.coreutils}/bin/cat ${config.age.secrets.email-password-meinhark.path}";
});
hu-student-cs =
lib.recursiveUpdate defaults
(lib.recursiveUpdate hu-defaults
rec {
userName = "meinhark";
address = "kieran.felix.meinhardt@informatik.hu-berlin.de";
aliases = ["${userName}@informatik.hu-berlin.de"];
imap.host = "mailbox.informatik.hu-berlin.de";
smtp.host = "mailhost.informatik.hu-berlin.de";
passwordCommand = "${pkgs.coreutils}/bin/cat ${config.age.secrets.email-password-meinhark.path}";
});
hu-employee =
lib.recursiveUpdate defaults
(lib.recursiveUpdate hu-defaults
rec {
userName = "meinhaki";
address = "kieran.meinhardt@hu-berlin.de";
aliases = ["${userName}@hu-berlin.de"];
passwordCommand = "${pkgs.coreutils}/bin/cat ${config.age.secrets.email-password-meinhaki.path}";
aerc.extraAccounts.signature-file = toString (pkgs.writeText "signature" signature.text);
signature = {
showSignature = "append";
text = ''
${defaults.realName}
Studentische Hilfskraft / Administrator ALEW
Humboldt-Universität zu Berlin
Telefon: +49 (0)30 2093 9634
Raum 3.212, Dorotheenstraße 24, 10117 Berlin-Mitte
https://alew.hu-berlin.de
'';
};
});
hu-admin =
lib.recursiveUpdate defaults
(lib.recursiveUpdate hu-defaults
rec {
userName = "dslalewa";
address = "admin.alew.vglsprwi@hu-berlin.de";
aliases = ["${userName}@hu-berlin.de"];
passwordCommand = "${pkgs.coreutils}/bin/cat ${config.age.secrets.email-password-dslalewa.path}";
inherit (hu-employee) signature;
aerc.extraAccounts.signature-file = toString (pkgs.writeText "signature" signature.text);
});
hu-fsi =
lib.recursiveUpdate defaults
(lib.recursiveUpdate hu-defaults
rec {
userName = "fsklassp";
passwordCommand = "${pkgs.coreutils}/bin/cat ${config.age.secrets.email-password-fsklassp.path}";
address = "${userName}@hu-berlin.de";
realName = "FSI Klassische Philologie";
aerc.extraAccounts.signature-file = toString (pkgs.writeText "signature" signature.text);
signature = {
showSignature = "append";
text = ''
Fachschafts-Initiative
Humboldt-Universität zu Berlin
Sprach- und literaturwissenschaftliche Fakultät
Institut für klassische Philologie
Unter den Linden 6
10099 Berlin
'';
};
});
fysi =
lib.recursiveUpdate defaults
rec {
address = "kieran@fysi.tech";
userName = address;
passwordCommand = "${pkgs.coreutils}/bin/cat ${config.age.secrets.email-password-fysi.path}";
flavor = "fastmail.com";
};
cock =
let
mailhost = "mail.cock.li";
lib.recursiveUpdate defaults
rec {
address = "2210@cock.li";
in
lib.recursiveUpdate pkgs.lib.niveum.email.defaults {
address = address;
userName = address;
passwordCommand = "${pkgs.coreutils}/bin/cat ${config.age.secrets.email-password-cock.path}";
realName = "2210";
imap.host = mailhost;
imap.port = 993;
smtp.host = mailhost;
smtp.port = 587;
smtp.tls.useStartTls = true;
};
ical-ephemeris =
let
address = "ical.ephemeris@web.de";
in
lib.recursiveUpdate pkgs.lib.niveum.email.defaults {
userName = address;
realName = "Kieran from iCal Ephemeris";
address = address;
passwordCommand = "${pkgs.coreutils}/bin/cat ${config.age.secrets.email-password-ical-ephemeris.path}";
imap.host = "imap.web.de";
imap.port = 993;
smtp.host = "smtp.web.de";
smtp.port = 587;
smtp.tls.useStartTls = true;
realName = "";
imap.host = "mail.cock.li";
smtp.host = imap.host;
};
posteo =
let
mailhost = "posteo.de";
lib.recursiveUpdate defaults
rec {
address = "kieran.meinhardt@posteo.net";
in
lib.recursiveUpdate pkgs.lib.niveum.email.defaults {
address = address;
aliases = [ "kmein@posteo.de" ];
aliases = ["kmein@posteo.de"];
userName = address;
imap.host = mailhost;
imap.port = 993;
imap.tls.enable = true;
smtp.host = mailhost;
smtp.port = 465;
smtp.tls.enable = true;
imap.host = "posteo.de";
smtp.host = imap.host;
primary = true;
passwordCommand = "${pkgs.coreutils}/bin/cat ${config.age.secrets.email-password-posteo.path}";
himalaya = {
enable = true;
};
aerc.extraAccounts.pgp-key-id = "9EDE82CC72A343A95266D0F444857074A3ACC8B7";
# himalaya = { enable = true; backend = "imap"; sender = "smtp"; };
};
};
programs.himalaya.enable = true;
programs.thunderbird = {
enable = true;
settings = {
};
profiles.${pkgs.lib.niveum.email.thunderbirdProfile} = {
isDefault = true;
settings = {
"mail.default_send_format" = 1;
"msgcompose.default_colors" = false;
"msgcompose.text_color" = config.lib.stylix.colors.withHashtag.base00;
"msgcompose.background_color" = config.lib.stylix.colors.withHashtag.base05;
};
userChrome = '''';
userContent = '''';
withExternalGnupg = false;
};
};
# programs.himalaya.enable = true;
programs.aerc = {
enable = true;
@@ -210,7 +277,6 @@
"*" = ":filter -x Flagged<Enter>";
};
view = {
tr = ":pipe ${pkgs.trans}/bin/trans -show-original n -b -no-autocorrect<Enter>"; # https://man.sr.ht/~rjarry/aerc/integrations/translator.md
"/" = ":toggle-key-passthrough <Enter> /";
q = ":close<Enter>";
O = ":open<Enter>";
@@ -283,45 +349,41 @@
ui.spinner = ". , .";
general.unsafe-accounts-conf = true;
general.pgp-provider = "gpg";
viewer = {
pager = "${pkgs.less}/bin/less -R";
};
viewer = {pager = "${pkgs.less}/bin/less -R";};
compose = {
# address-book-cmd = "khard email --remove-first-line --parsable '%s'";
no-attachment-warning = "(attach|attached|attachments?|anbei|Anhang|angehängt|beigefügt)";
address-book-cmd = "khard email --remove-first-line --parsable '%s'";
no-attachment-warning = "(attach|attached|attachments?|anbei|Anhang|angehängt)";
};
filters = {
"text/plain" = "${pkgs.aerc}/libexec/aerc/filters/colorize";
"text/calendar" = "${pkgs.aerc}/libexec/aerc/filters/calendar";
"text/html" = "${pkgs.aerc}/libexec/aerc/filters/html"; # Requires w3m, dante
"text/plain" = "${pkgs.gawk}/bin/awk -f ${pkgs.aerc}/share/aerc/filters/colorize";
"text/calendar" = "${pkgs.gawk}/bin/awk -f ${pkgs.aerc}/share/aerc/filters/calendar";
"text/html" = "${pkgs.aerc}/share/aerc/filters/html"; # Requires w3m, dante
# "text/html" =
# "${pkgs.aerc}/share/aerc/filters/html | ${pkgs.aerc}/share/aerc/filters/colorize";
# "text/*" =
# ''${pkgs.bat}/bin/bat -fP --theme=ansi --file-name="$AERC_FILENAME "'';
"message/delivery-status" = "${pkgs.aerc}/libexec/aerc/filters/colorize";
"message/rfc822" = "${pkgs.aerc}/libexec/aerc/filters/colorize";
# ''${pkgs.bat}/bin/bat -fP --file-name="$AERC_FILENAME "'';
"message/delivery-status" = "${pkgs.gawk}/bin/awk -f ${pkgs.aerc}/share/aerc/filters/colorize";
"message/rfc822" = "${pkgs.gawk}/bin/awk -f ${pkgs.aerc}/share/aerc/filters/colorize";
"application/x-sh" = "${pkgs.bat}/bin/bat -fP -l sh";
};
openers =
let
as-pdf = pkgs.writers.writeDash "as-pdf" ''
d=$(mktemp -p "$XDG_RUNTIME_DIR" -d)
trap clean EXIT
clean() {
rm -rf "$d"
}
${pkgs.libreoffice}/bin/libreoffice --headless --convert-to pdf "$1" --outdir "$d"
${pkgs.zathura}/bin/zathura "$d"/*.pdf
'';
in
{
"image/*" = "${pkgs.nsxiv}/bin/nsxiv";
"application/pdf" = "${pkgs.zathura}/bin/zathura";
"application/vnd.openxmlformats-officedocument.wordprocessingml.document" = toString as-pdf;
"application/vnd.oasis.opendocument.text" = toString as-pdf;
"video/*" = "${pkgs.mpv}/bin/mpv";
"audio/*" = "${pkgs.mpv}/bin/mpv";
};
openers = let
as-pdf = pkgs.writers.writeDash "as-pdf" ''
d=$(mktemp -d)
trap clean EXIT
clean() {
rm -rf "$d"
}
${pkgs.libreoffice}/bin/libreoffice --headless --convert-to pdf "$1" --outdir "$d"
${pkgs.zathura}/bin/zathura "$d"/*.pdf
'';
in {
"image/*" = "${pkgs.nsxiv}/bin/nsxiv";
"application/pdf" = "${pkgs.zathura}/bin/zathura";
"application/vnd.openxmlformats-officedocument.wordprocessingml.document" = toString as-pdf;
"application/vnd.oasis.opendocument.text" = toString as-pdf;
"video/*" = "${pkgs.mpv}/bin/mpv";
"audio/*" = "${pkgs.mpv}/bin/mpv";
};
};
templates = {

View File

@@ -1,7 +1,68 @@
{
home-manager.users.me = {
programs.alacritty = {
enable = true;
pkgs,
lib,
config,
...
}: let
alacritty-cfg = theme:
(pkgs.formats.yaml {}).generate "alacritty.yml" {
window.opacity = 0.99;
bell = {
animation = "EaseOut";
duration = 100;
color = "#ffffff";
};
font = {
normal.family = "Monospace";
size = 6;
};
live_config_reload = true;
key_bindings = [
{
key = "Plus";
mods = "Control";
action = "IncreaseFontSize";
}
{
key = "Minus";
mods = "Control";
action = "DecreaseFontSize";
}
{
key = "Key0";
mods = "Control";
action = "ResetFontSize";
}
];
colors = let
colourNames = ["black" "red" "green" "yellow" "blue" "magenta" "cyan" "white"];
colourPairs = lib.getAttrs colourNames theme;
in {
primary = {inherit (theme) background foreground;};
cursor = {inherit (theme) cursor;};
normal = lib.mapAttrs (_: colour: colour.dark) colourPairs;
bright = lib.mapAttrs (_: colour: colour.bright) colourPairs;
};
};
alacritty-pkg = pkgs.symlinkJoin {
name = "alacritty";
paths = [
(pkgs.writers.writeDashBin "alacritty" ''
${pkgs.alacritty}/bin/alacritty --config-file /var/theme/config/alacritty.yml msg create-window "$@" ||
${pkgs.alacritty}/bin/alacritty --config-file /var/theme/config/alacritty.yml "$@"
'')
pkgs.alacritty
];
};
in {
environment.variables.TERMINAL = "alacritty";
environment.systemPackages = [
alacritty-pkg
];
environment.etc = {
"themes/dark/alacritty.yml".source = alacritty-cfg (import ../lib/colours/owickstrom-dark.nix);
"themes/light/alacritty.yml".source = alacritty-cfg (import ../lib/colours/owickstrom-light.nix);
};
}

View File

@@ -1,5 +0,0 @@
{
programs.adb.enable = true;
users.users.me.extraGroups = [ "adbusers" ];
}

View File

@@ -1,58 +0,0 @@
{
config,
pkgs,
lib,
...
}:
{
users.users.applicative = {
name = "asg";
description = "Applicative Systems";
hashedPasswordFile = config.age.secrets.kfm-password.path;
home = "/home/applicative";
uid = 1001;
isNormalUser = true;
extraGroups = [
"pipewire"
"audio"
];
};
nixpkgs.overlays = [
(final: prev: {
niphas-wallpaper = prev.callPackage ../packages/applicative-wallpaper.nix {
inherit (config.lib.stylix) colors;
};
})
];
services.getty.autologinOnce = lib.mkForce false;
# to run nspawn in nix sandbox
nix.settings = {
auto-allocate-uids = true;
system-features = [ "uid-range" ];
experimental-features = [
"auto-allocate-uids"
"cgroups"
];
trusted-users = [ config.users.users.applicative.name ];
};
services.restic.backups.niveum = {
extraBackupArgs = [
"--exclude=${config.users.users.applicative.home}/src/nixpkgs/.git"
];
paths = [
config.users.users.applicative.home
];
};
security.sudo.extraRules = [
{
# still required for systemd-nspawn
users = [ config.users.users.applicative.name ];
commands = [ "ALL" ];
}
];
}

View File

@@ -1,31 +1,32 @@
{
pkgs,
config,
lib,
...
}:
{
}: let
inherit (import ../lib) restic;
in {
services.restic.backups.niveum = {
initialize = true;
repository = pkgs.lib.niveum.restic.repository;
inherit (restic) repository;
timerConfig = {
OnCalendar = "8:00";
RandomizedDelaySec = "1h";
};
passwordFile = config.age.secrets.restic.path;
extraBackupArgs = [
"--exclude=/home/kfm/sync/src/nixpkgs/.git"
"--exclude=/home/kfm/projects/nixpkgs/.git"
"--exclude=node_modules"
"--exclude=.parcel-cache"
];
paths = [
"/home/kfm/sync"
"/home/kfm/state"
"/home/kfm/work"
"/home/kfm/projects"
"/home/kfm/notes"
"/home/kfm/Maildir"
"/home/kfm/cloud"
"/home/kfm/mobile"
"/home/kfm/.gnupg"
"/home/kfm/.electrum"
"/home/kfm/.ssh"
"/mnt/sd-card/music"
"/mnt/sd-card/Books"
];
};
@@ -38,15 +39,15 @@
environment.systemPackages = [
(pkgs.writers.writeDashBin "restic-niveum" ''
${pkgs.restic}/bin/restic -r ${pkgs.lib.niveum.restic.repository} -p ${config.age.secrets.restic.path} "$@"
${pkgs.restic}/bin/restic -r ${restic.repository} -p ${config.age.secrets.restic.path} "$@"
'')
(pkgs.writers.writeDashBin "restic-mount" ''
mountdir=$(mktemp -p "$XDG_RUNTIME_DIR" -d "restic-mount-XXXXXXX")
mountdir=$(mktemp -d)
trap clean EXIT
clean() {
rm -r "$mountdir"
}
${pkgs.restic}/bin/restic -r ${pkgs.lib.niveum.restic.repository} -p ${config.age.secrets.restic.path} mount "$mountdir"
${pkgs.restic}/bin/restic -r ${restic.repository} -p ${config.age.secrets.restic.path} mount "$mountdir"
'')
];
}

10
configs/bash.nix Normal file
View File

@@ -0,0 +1,10 @@
{
programs.bash = {
promptInit = ''
PS1="$(tput bold)\w \$([[ \$? == 0 ]] && echo \"\[\033[1;32m\]\" || echo \"\[\033[1;31m\]\")\$$(tput sgr0) "'';
interactiveShellInit = ''
set -o vi
'';
enableCompletion = true;
};
}

View File

@@ -2,23 +2,16 @@
config,
pkgs,
...
}:
{
}: {
boot.extraModulePackages = with config.boot.kernelPackages; [
tp_smapi
acpi_call
];
boot.kernelModules = [
"tp_smapi"
"acpi_call"
];
environment.systemPackages = [
pkgs.tpacpi-bat
pkgs.powertop
];
boot.kernelModules = ["tp_smapi" "acpi_call"];
environment.systemPackages = [pkgs.tpacpi-bat pkgs.powertop];
services.tlp = {
enable = false;
enable = true;
settings = {
START_CHARGE_THRESH_BAT0 = 80;
STOP_CHARGE_THRESH_BAT0 = 95;

14
configs/beets.nix Normal file
View File

@@ -0,0 +1,14 @@
{
lib,
pkgs,
...
}: {
environment.systemPackages = [pkgs.beets];
home-manager.users.me.xdg.configFile = {
"beets/config.yaml".source = (pkgs.formats.yaml {}).generate "config.yaml" {
directory = "~/cloud/syncthing/music";
library = "~/cloud/syncthing/common/music.db";
plugins = toString ["fetchart" "lastgenre"];
};
};
}

View File

@@ -1,11 +1,17 @@
{ pkgs, ... }:
{
pkgs,
lib,
...
}: {
hardware.bluetooth = {
enable = true;
settings.general = {
enable = "Source,Sink,Media,Socket";
};
settings.General.Enable =
lib.concatStringsSep "," ["Source" "Sink" "Media" "Socket"];
};
environment.systemPackages = [ pkgs.bluetuith ];
services.blueman.enable = true;
# environment.systemPackages = [pkgs.blueman];
home-manager.users.me = {services.blueman-applet.enable = true;};
}

View File

@@ -1,26 +0,0 @@
{
config,
pkgs,
...
}:
{
niveum.bots.autorenkalender = {
enable = true;
time = "07:00";
telegram = {
enable = true;
tokenFile = config.age.secrets.telegram-token-kmein.path;
chatIds = [ "@autorenkalender" ];
parseMode = "Markdown";
};
command = "${pkgs.autorenkalender}/bin/autorenkalender";
};
niveum.passport.services = [
{
title = "Autorenkalender";
description = "sends <a href=\"https://www.projekt-gutenberg.org/\">Projekt Gutenberg</a>'s anniversary information to Telegram.";
link = "https://t.me/Autorenkalender";
}
];
}

View File

@@ -1,84 +0,0 @@
{
pkgs,
lib,
config,
...
}:
{
niveum.bots.celan = {
enable = true;
time = "08:00";
telegram = {
enable = true;
tokenFile = config.age.secrets.telegram-token-kmein.path;
chatIds = [ "@PaulCelan" ];
};
mastodon = {
enable = true;
tokenFile = config.age.secrets.mastodon-token-celan.path;
language = "de";
};
command = toString (
pkgs.writers.writePython3 "random-celan.py" { libraries = [ pkgs.python3Packages.lxml ]; } ''
from lxml import etree
import random
def xml_text(elements):
return "".join("".join(t.itertext()) for t in elements).strip()
tree = etree.parse('${
pkgs.fetchurl {
url = "http://c.krebsco.de/celan.tei.xml";
hash = "sha256-HgNmJYfhuwyfm+FcNtnnYWpJpIIU1ElHLeLiIFjF9mE=";
}
}')
root = tree.getroot()
tei = {"tei": "http://www.tei-c.org/ns/1.0"}
poems = root.xpath(".//tei:lg[@type='poem']", namespaces=tei)
poem = random.choice(poems)
for stanza in poem.xpath("./tei:lg[@type='stanza']", namespaces=tei):
for line in stanza.xpath('./tei:l', namespaces=tei):
if line.text:
print(line.text.strip())
print()
current_element = poem
while current_element is not None:
if current_element.tag == "{http://www.tei-c.org/ns/1.0}text":
text_element = current_element
title = xml_text(text_element.xpath("./tei:front/tei:docTitle",
namespaces=tei))
print(f"Aus: #{title.replace(" ", "_")}", end=" ")
if date := xml_text(text_element.xpath("./tei:front/tei:docDate",
namespaces=tei)):
print(f"({date})")
break
current_element = current_element.getparent()
print("\n\n#PaulCelan #Celan #Lyrik #poetry")
''
);
};
age.secrets = {
mastodon-token-celan.file = ../../secrets/mastodon-token-celan.age;
};
systemd.timers.bot-celan.timerConfig.RandomizedDelaySec = "10h";
niveum.passport.services = [
{
title = "Paul Celan Bot";
description = "sends a random poem by Paul Celan to Telegram.";
link = "https://t.me/PaulCelan";
}
];
}

View File

@@ -1,36 +0,0 @@
{
pkgs,
config,
...
}:
{
niveum.bots.hesychius = {
enable = true;
time = "08:00";
mastodon = {
enable = true;
language = "el";
tokenFile = config.age.secrets.mastodon-token-hesychius.path;
};
telegram = {
enable = true;
tokenFile = config.age.secrets.telegram-token-kmein.path;
chatIds = [ "@HesychiosAlexandreus" ];
};
command = "${pkgs.coreutils}/bin/shuf -n1 ${pkgs.hesychius}";
};
systemd.timers.bot-hesychius.timerConfig.RandomizedDelaySec = "10h";
age.secrets = {
mastodon-token-hesychius.file = ../../secrets/mastodon-token-hesychius.age;
};
niveum.passport.services = [
{
title = "Hesychius of Alexandria Bot";
description = "sends a random word from Hesychius of Alexandria's lexicon to Telegram.";
link = "https://t.me/HesychiosAlexandreus";
}
];
}

View File

@@ -1,37 +0,0 @@
{
pkgs,
config,
...
}:
{
niveum.bots.logotheca = {
enable = true;
time = "08/6:00";
telegram = {
enable = true;
tokenFile = config.age.secrets.telegram-token-kmein.path;
chatIds = [ "-1001760262519" ];
parseMode = "Markdown";
};
matrix = {
enable = true;
homeserver = "matrix.4d2.org";
tokenFile = config.age.secrets.matrix-token-lakai.path;
chatIds = [
"!zlwCuPiCNMSxDviFzA:4d2.org"
];
};
command = "${pkgs.literature-quote}/bin/literature-quote";
};
age.secrets = {
matrix-token-lakai.file = ../../secrets/matrix-token-lakai.age;
};
niveum.passport.services = [
{
title = "Literature quote bot";
description = "sends me and my friends three <a href=\"https://logotheca.xn--kiern-0qa.de/\">logotheca</a> quotes a day.";
}
];
}

View File

@@ -1,53 +0,0 @@
{
pkgs,
config,
lib,
...
}:
let
nachtischsatan-bot =
{ tokenFile }:
pkgs.writers.writePython3 "nachtischsatan-bot"
{
libraries = [ pkgs.python3Packages.python-telegram-bot ];
}
''
from telegram.ext import Application, ContextTypes, MessageHandler, filters
from telegram import Update
import random
import time
async def flubber(update: Update, context: ContextTypes.DEFAULT_TYPE):
time.sleep(random.randrange(4000) / 1000)
await update.message.reply_text("*flubberflubber*")
with open('${tokenFile}', 'r') as tokenFile:
token = tokenFile.read().strip()
application = Application.builder().token(token).build()
application.add_handler(MessageHandler(filters.ALL, flubber))
application.run_polling()
'';
in
{
systemd.services.telegram-nachtischsatan = {
wantedBy = [ "multi-user.target" ];
description = "*flubberflubber*";
enable = true;
script = toString (nachtischsatan-bot {
tokenFile = config.age.secrets.telegram-token-nachtischsatan.path;
});
serviceConfig.Restart = "always";
};
age.secrets.telegram-token-nachtischsatan.file = ../../secrets/telegram-token-nachtischsatan.age;
niveum.passport.services = [
{
title = "Nachtischsatan-Bot";
link = "https://t.me/NachtischsatanBot";
description = "*flubberflubber*";
}
];
}

View File

@@ -1,33 +0,0 @@
{
config,
pkgs,
...
}:
{
niveum.bots.nietzsche = {
enable = true;
time = "08:00";
mastodon = {
enable = true;
tokenFile = config.age.secrets.mastodon-token-nietzsche.path;
language = "de";
};
command = toString (
pkgs.writers.writeBash "random-nietzsche" ''
set -efu
random_number=$(( ($RANDOM % 10) + 1 ))
if [ "$random_number" -eq 1 ]; then
${pkgs.random-zeno}/bin/random-zeno "/Literatur/M/Nietzsche,+Friedrich"
else
${pkgs.random-zeno}/bin/random-zeno "/Philosophie/M/Nietzsche,+Friedrich"
fi
''
);
};
systemd.timers.bot-nietzsche.timerConfig.RandomizedDelaySec = "10h";
age.secrets = {
mastodon-token-nietzsche.file = ../../secrets/mastodon-token-nietzsche.age;
};
}

View File

@@ -1,72 +0,0 @@
{
config,
pkgs,
lib,
...
}:
{
niveum.bots.smyth = {
enable = true;
time = "08:00";
mastodon = {
enable = true;
tokenFile = config.age.secrets.mastodon-token-smyth.path;
language = "en";
};
telegram = {
enable = true;
tokenFile = config.age.secrets.telegram-token-kmein.path;
chatIds = [ "@HerbertWeirSmyth" ];
};
command = toString (
pkgs.writers.writeDash "random-smyth" ''
set -efu
good_curl() {
${pkgs.curl}/bin/curl "$@" \
--compressed \
-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
-H 'Accept-Language: en-US,en;q=0.5' \
-H 'DNT: 1' \
-H 'Connection: keep-alive' \
-H 'Upgrade-Insecure-Requests: 1' \
-H 'Sec-Fetch-Dest: document' \
-H 'Sec-Fetch-Mode: navigate' \
-H 'Sec-Fetch-Site: cross-site' \
-H 'Priority: u=0, i' \
-H 'Pragma: no-cache' \
-H 'Cache-Control: no-cache'
}
RANDOM_SECTION=$(
good_curl -sSL http://www.perseus.tufts.edu/hopper/xmltoc?doc=Perseus%3Atext%3A1999.04.0007%3Asmythp%3D1 \
| ${pkgs.gnugrep}/bin/grep -o 'ref="[^"]*"' \
| ${pkgs.coreutils}/bin/shuf -n1 \
| ${pkgs.gnused}/bin/sed 's/^ref="//;s/"$//'
)
url="http://www.perseus.tufts.edu/hopper/text?doc=$RANDOM_SECTION"
good_curl -sSL "$url"\
| ${pkgs.htmlq}/bin/htmlq '#text_main' \
| ${pkgs.gnused}/bin/sed 's/<\/\?hr>//g' \
| ${pkgs.pandoc}/bin/pandoc -f html -t plain --wrap=none
printf '\n%s\n\n#AncientGreek' "$url"
''
);
};
systemd.timers.bot-smyth.timerConfig.RandomizedDelaySec = "10h";
age.secrets = {
mastodon-token-smyth.file = ../../secrets/mastodon-token-smyth.age;
};
niveum.passport.services = [
{
title = "Herbert Weir Smyth Bot";
description = "sends a random section from Smyth's Ancient Greek grammar to Telegram.";
link = "https://t.me/HerbertWeirSmyth";
}
];
}

View File

@@ -1,176 +0,0 @@
{
pkgs,
config,
...
}:
let
mastodonEndpoint = "https://social.krebsco.de";
in
{
systemd.services.bot-tlg-wotd = {
# TODO reenable
# once https://github.com/NixOS/nixpkgs/pull/462893 is in stable NixOS
enable = true;
wants = [ "network-online.target" ];
startAt = "9:30";
path = [
pkgs.jq
pkgs.curl
pkgs.recode
pkgs.deno
pkgs.imagemagick
pkgs.gawk
pkgs.gnugrep
pkgs.coreutils
];
environment = {
NPM_CONFIG_CACHE = "/tmp";
CLTK_DATA = "/tmp";
};
script = ''
set -efux
chat_id=@tlgwotd
export TELEGRAM_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/telegram-token")"
export MASTODON_TOKEN="$(cat "$CREDENTIALS_DIRECTORY/mastodon-token")"
json_data=$(curl -sSL http://stephanus.tlg.uci.edu/Iris/Wotd | recode html..utf8)
word=$(echo "$json_data" | jq -r '.word')
compact_word=$(echo "$word" | sed 's/,.*$//')
definition=$(echo "$json_data" | jq -r '.definition | sub("<.*>"; "") | rtrimstr(" ")')
first_occurrence=$(echo "$json_data" | jq -r '.firstOccurrence')
total_occurrences=$(echo "$json_data" | jq -r '.totalOccurrences')
telegram_caption="*$word* $definition
First occurrence (century): $first_occurrence
Number of occurrences (in all Ancient Greek texts): $total_occurrences"
mastodon_caption="$word $definition
First occurrence (century): $first_occurrence
Number of occurrences (in all Ancient Greek texts): $total_occurrences"
#ancientgreek #classics #wotd #wordoftheday
transliteration=$(${
pkgs.writers.writePython3 "translit.py"
{
libraries = py: [ py.cltk ];
}
''
import sys
from cltk.phonology.grc.transcription import Transcriber
probert = Transcriber("Attic", "Probert")
text = " ".join(sys.argv[1:])
ipa = probert.transcribe(text)
print(ipa)
''
} "$compact_word")
photo_path=/tmp/output.png
hex_to_rgb() {
hex="$1"
r=$(printf "%d" "0x$(echo "$hex" | cut -c2-3)")
g=$(printf "%d" "0x$(echo "$hex" | cut -c4-5)")
b=$(printf "%d" "0x$(echo "$hex" | cut -c6-7)")
echo "$r $g $b"
}
calculate_luminance() {
r="$1"
g="$2"
b="$3"
r_l=$(echo "$r" | awk '{print ($1 / 255 <= 0.03928) ? $1 / 255 / 12.92 : (($1 / 255 + 0.055) / 1.055)^2.4}')
g_l=$(echo "$g" | awk '{print ($1 / 255 <= 0.03928) ? $1 / 255 / 12.92 : (($1 / 255 + 0.055) / 1.055)^2.4}')
b_l=$(echo "$b" | awk '{print ($1 / 255 <= 0.03928) ? $1 / 255 / 12.92 : (($1 / 255 + 0.055) / 1.055)^2.4}')
echo "$r_l $g_l $b_l" | awk '{print 0.2126*$1 + 0.7152*$2 + 0.0722*$3}'
}
hex_color="#$(echo "$compact_word" | md5sum | cut -c 1-6)"
if echo "$hex_color" | grep -qE '^#[0-9A-Fa-f]{6}$'; then
set -- $(hex_to_rgb "$hex_color")
r="$1"
g="$2"
b="$3"
fi
luminance=$(calculate_luminance "$r" "$g" "$b")
threshold="0.1"
echo "$r $g $b"
if [ "$(echo "$luminance" | awk -v threshold="$threshold" '{print ($1 > threshold)}')" -eq 1 ]; then
color1="black"
color2="#333"
else
color1="white"
color2=lightgrey
fi
magick -size 1400x846 \
xc:"$hex_color" \
-font "${pkgs.gentium}/share/fonts/truetype/GentiumBookPlus-Bold.ttf" \
-fill "$color1" \
-pointsize 150 -gravity west \
-annotate +100-160 "$compact_word" \
-font "${pkgs.gentium}/share/fonts/truetype/GentiumBookPlus-Regular.ttf" \
-fill "$color2" \
-pointsize 60 -gravity west \
-annotate +100+00 "$transliteration" \
-fill "$color1" \
-annotate +100+120 "$definition" \
-fill "$color2" \
-pointsize 40 -gravity southwest \
-annotate +100+60 "attested $total_occurrences times" \
-pointsize 40 -gravity southeast \
-annotate +100+60 "$(date -I)" \
"$photo_path"
curl -X POST "https://api.telegram.org/bot$TELEGRAM_TOKEN/sendPhoto" \
-F "chat_id=\"$chat_id\"" \
-F "photo=@$photo_path" \
-F parse_mode=Markdown \
-F caption="$telegram_caption"
mastodon_upload_response=$(curl -X POST "${mastodonEndpoint}/api/v2/media" \
-H "Authorization: Bearer $MASTODON_TOKEN" \
-F "file=@$photo_path" \
-F "description=$word $definition")
mastodon_image_id=$(echo $mastodon_upload_response | jq -r .id)
curl -X POST "${mastodonEndpoint}/api/v1/statuses" \
-H "Authorization: Bearer $MASTODON_TOKEN" \
-d "status=$mastodon_caption" \
-d "visibility=public" \
-d "media_ids[]=$mastodon_image_id"
'';
serviceConfig = {
Type = "oneshot";
DynamicUser = true;
StateDirectory = "tlgwotd";
PrivateTmp = true;
LoadCredential = [
"telegram-token:${config.age.secrets.telegram-token-kmein.path}"
"mastodon-token:${config.age.secrets.mastodon-token-tlgwotd.path}"
];
};
};
age.secrets = {
mastodon-token-tlgwotd.file = ../../secrets/mastodon-token-tlgwotd.age;
};
niveum.passport.services = [
{
title = "Thesaurus Linguae Graecae Word of the Day";
description = "sends <a href=\"https://stephanus.tlg.uci.edu/\">TLG</a>'s word of the day to Telegram.";
link = "https://t.me/tlgwotd";
}
];
}

View File

@@ -1,92 +0,0 @@
{
config,
pkgs,
...
}:
{
environment.systemPackages = [
pkgs.cro
pkgs.tor-browser
pkgs.firefox
pkgs.brave
];
home-manager.users.me = {
programs.firefox = {
enable = true;
profiles =
let
defaultSettings = {
"beacon.enabled" = false;
"browser.bookmarks.showMobileBookmarks" = true;
"browser.newtab.preload" = false;
"browser.search.isUS" = false;
"browser.search.region" = "DE";
"browser.send_pings" = false;
"browser.shell.checkDefaultBrowser" = false;
"browser.startup.homepage" = "chrome://browser/content/blanktab.html";
"browser.uidensity" = 1;
"browser.urlbar.placeholderName" = "Search";
"datareporting.healthreport.service.enabled" = false;
"datareporting.healthreport.uploadEnabled" = false;
"datareporting.policy.dataSubmissionEnabled" = false;
"datareporting.sessions.current.clean" = true;
"distribution.searchplugins.defaultLocale" = "de-DE";
"general.smoothScroll" = true;
"identity.fxaccounts.account.device.name" = config.networking.hostName;
"network.cookie.cookieBehavior" = 1;
"privacy.donottrackheader.enabled" = true;
"privacy.trackingprotection.enabled" = true;
"privacy.trackingprotection.pbmode.enabled" = true;
"privacy.trackingprotection.socialtracking.enabled" = true;
"services.sync.declinedEngines" = "passwords";
"services.sync.engine.passwords" = false;
"signon.autofillForms" = false;
"signon.rememberSignons" = false;
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
"toolkit.telemetry.archive.enabled" = false;
"toolkit.telemetry.bhrPing.enabled" = false;
"toolkit.telemetry.cachedClientID" = "";
"toolkit.telemetry.enabled" = false;
"toolkit.telemetry.firstShutdownPing.enabled" = false;
"toolkit.telemetry.hybridContent.enabled" = false;
"toolkit.telemetry.newProfilePing.enabled" = false;
"toolkit.telemetry.prompted" = 2;
"toolkit.telemetry.rejected" = true;
"toolkit.telemetry.server" = "";
"toolkit.telemetry.shutdownPingSender.enabled" = false;
"toolkit.telemetry.unified" = false;
"toolkit.telemetry.unifiedIsOptIn" = false;
"toolkit.telemetry.updatePing.enabled" = false;
"ui.prefersReducedMotion" = 1;
};
in
{
default = {
id = 0;
isDefault = true;
settings = defaultSettings;
# extensions = with pkgs.nur.repos.rycee.firefox-addons; [
# ublock-origin
# darkreader
# sponsorblock
# consent-o-matic
# i-dont-care-about-cookies
# # auto-tab-discard TODO what is this
# ];
userChrome = ''
#TabsToolbar {
visibility: collapse !important;
}
'';
};
};
};
};
home-manager.users.me = {
stylix.targets.firefox.profileNames = [ "default" ];
};
environment.variables.BROWSER = "firefox";
}

View File

@@ -1,38 +1,28 @@
{ pkgs, ... }:
{
networking.networkmanager.ensureProfiles.profiles = {
"39C3" = {
connection = {
id = "39C3";
type = "wifi";
};
wifi = {
mode = "infrastructure";
ssid = "39C3";
};
wifi-security = {
auth-alg = "open";
key-mgmt = "wpa-eap";
};
"802-1x" = {
anonymous-identity = "39C3";
eap = "ttls;";
identity = "39C3";
password = "39C3";
phase2-auth = "pap";
altsubject-matches = "DNS:radius.c3noc.net";
ca-cert = "${builtins.fetchurl {
url = "https://letsencrypt.org/certs/isrgrootx1.pem";
sha256 = "sha256:1la36n2f31j9s03v847ig6ny9lr875q3g7smnq33dcsmf2i5gd92";
}}";
};
ipv4 = {
method = "auto";
};
ipv6 = {
addr-gen-mode = "default";
method = "auto";
};
};
{pkgs, ...}:
# https://paste.sr.ht/~erictapen/11716989e489b600f237041b6d657fdf0ee17b34
let
certificate = pkgs.stdenv.mkDerivation rec {
name = "dst-root-ca-x3.pem";
src = builtins.toFile "${name}.sed" ''
1,/DST Root CA X3/d
1,/-----END CERTIFICATE-----/p
'';
nativeBuildInputs = with pkgs; [cacert gnused];
phases = "installPhase";
installPhase = ''
${pkgs.gnused}/bin/sed -n -f $src ${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt > $out
'';
};
in {
networking.wireless.networks."36C3" = {
auth = ''
key_mgmt=WPA-EAP
eap=TTLS
identity="kmein"
password=" "
ca_cert="${certificate}"
altsubject_match="DNS:radius.c3noc.net"
phase2="auth=PAP"
'';
};
}

97
configs/chromium.nix Normal file
View File

@@ -0,0 +1,97 @@
{
pkgs,
config,
...
}: {
programs.chromium = {
enable = true;
extensions = [
# "ihlenndgcmojhcghmfjfneahoeklbjjh" # cVim
# "fpnmgdkabkmnadcjpehmlllkndpkmiak" # Wayback Machine
"cjpalhdlnbpafiamejdnhcphjbkeiagm" # uBlock Origin
"pjjgklgkfeoeiebjogplpnibpfnffkng" # undistracted
"nhdogjmejiglipccpnnnanhbledajbpd" # vuejs devtools
"eimadpbcbfnmbkopoojfekhnkhdbieeh" # dark reader
];
};
home-manager.users.me = {
programs.firefox = {
enable = true;
package = pkgs.firefox.override {
cfg = {
enableTridactylNative = true;
};
};
profiles = let
defaultSettings = {
"beacon.enabled" = false;
"browser.bookmarks.showMobileBookmarks" = true;
"browser.newtab.preload" = false;
"browser.search.isUS" = false;
"browser.search.region" = "DE";
"browser.send_pings" = false;
"browser.shell.checkDefaultBrowser" = false;
"browser.startup.homepage" = "chrome://browser/content/blanktab.html";
"browser.uidensity" = 1;
"browser.urlbar.placeholderName" = "Search";
"datareporting.healthreport.service.enabled" = false;
"datareporting.healthreport.uploadEnabled" = false;
"datareporting.policy.dataSubmissionEnabled" = false;
"datareporting.sessions.current.clean" = true;
"distribution.searchplugins.defaultLocale" = "de-DE";
"general.smoothScroll" = true;
"identity.fxaccounts.account.device.name" = config.networking.hostName;
"network.cookie.cookieBehavior" = 1;
"privacy.donottrackheader.enabled" = true;
"privacy.trackingprotection.enabled" = true;
"privacy.trackingprotection.pbmode.enabled" = true;
"privacy.trackingprotection.socialtracking.enabled" = true;
"services.sync.declinedEngines" = "passwords";
"services.sync.engine.passwords" = false;
"signon.autofillForms" = false;
"signon.rememberSignons" = false;
"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
"toolkit.telemetry.archive.enabled" = false;
"toolkit.telemetry.bhrPing.enabled" = false;
"toolkit.telemetry.cachedClientID" = "";
"toolkit.telemetry.enabled" = false;
"toolkit.telemetry.firstShutdownPing.enabled" = false;
"toolkit.telemetry.hybridContent.enabled" = false;
"toolkit.telemetry.newProfilePing.enabled" = false;
"toolkit.telemetry.prompted" = 2;
"toolkit.telemetry.rejected" = true;
"toolkit.telemetry.server" = "";
"toolkit.telemetry.shutdownPingSender.enabled" = false;
"toolkit.telemetry.unified" = false;
"toolkit.telemetry.unifiedIsOptIn" = false;
"toolkit.telemetry.updatePing.enabled" = false;
"ui.prefersReducedMotion" = 1;
};
in {
default = {
id = 0;
isDefault = true;
settings = defaultSettings;
# extensions = with pkgs.nur.repos.rycee.firefox-addons; [
# ublock-origin
# darkreader
# sponsorblock
# consent-o-matic
# i-dont-care-about-cookies
# # auto-tab-discard TODO what is this
# ];
userChrome = ''
#TabsToolbar {
visibility: collapse !important;
}
'';
};
};
};
};
environment.systemPackages = [pkgs.brave];
environment.variables.BROWSER = "brave";
}

View File

@@ -2,7 +2,6 @@
config,
pkgs,
...
}:
{
}: {
services.clipmenu.enable = true;
}

View File

@@ -3,81 +3,58 @@
lib,
pkgs,
...
}:
{
systemd.user.services.systemd-tmpfiles-clean = {
enable = true;
wantedBy = [ "default.target" ];
startAt = "daily";
script = "systemd-tmpfiles --user --clean";
serviceConfig = {
Type = "oneshot";
};
};
systemd.user.tmpfiles.users.me.rules =
map pkgs.lib.niveum.tmpfilesConfig [
{
type = "d";
mode = "0755";
age = "7d";
path = "${config.users.users.me.home}/sync/Downloads";
}
{
type = "d";
mode = "0755";
age = "7d";
path = "${config.users.users.me.home}/cloud/nextcloud/tmp";
}
]
++
map
(
path:
pkgs.lib.niveum.tmpfilesConfig {
type = "L+";
user = config.users.users.me.name;
group = config.users.users.me.group;
mode = "0755";
argument = "${config.users.users.me.home}/sync/${path}";
path = "${config.users.users.me.home}/${path}";
}
)
[
".ssh"
".gnupg"
".pki"
".local/share/aerc"
];
services.gnome.gnome-keyring.enable = true;
security.pam.services.lightdm.enableGnomeKeyring = true;
}: let
inherit (import ../lib) tmpfilesConfig;
in {
systemd.tmpfiles.rules = map tmpfilesConfig [
{
type = "L+";
user = config.users.users.me.name;
group = "users";
mode = "0755";
argument = "${config.users.users.me.home}/cloud/Seafile/Uni";
path = "${config.users.users.me.home}/uni";
}
{
type = "L+";
user = config.users.users.me.name;
group = "users";
mode = "0755";
argument = "${config.users.users.me.home}/cloud/syncthing/common/mahlzeit";
path = "${config.users.users.me.home}/mahlzeit";
}
];
home-manager.users.me = {
services.gnome-keyring.enable = false;
services.nextcloud-client = {
enable = true;
enable = false;
startInBackground = true;
};
systemd.user.services.nextcloud-client = {
Unit = {
Wants = ["gnome-keyring.service"];
After = ["gnome-keyring.service"];
};
};
};
systemd.user.services.nextcloud-syncer = {
enable = false;
wants = [ "network-online.target" ];
wantedBy = [ "default.target" ];
enable = true;
wants = ["network-online.target"];
wantedBy = ["default.target"];
startAt = "*:00/10";
script =
let
kieran = {
user = "kieran";
passwordFile = config.age.secrets.nextcloud-password-kieran.path;
endpoint = "https://cloud.kmein.de";
target = "${config.users.users.me.home}/notes";
};
in
''
mkdir -p ${lib.escapeShellArg kieran.target}
${pkgs.nextcloud-client}/bin/nextcloudcmd --non-interactive --user ${kieran.user} --password "$(cat ${kieran.passwordFile})" --path /Notes ${lib.escapeShellArg kieran.target} ${kieran.endpoint}
'';
script = let
kieran = {
user = "kieran";
passwordFile = config.age.secrets.nextcloud-password-kieran.path;
endpoint = "https://cloud.xn--kiern-0qa.de";
target = "${config.users.users.me.home}/notes";
};
in ''
mkdir -p ${lib.escapeShellArg kieran.target}
${pkgs.nextcloud-client}/bin/nextcloudcmd --non-interactive --user ${kieran.user} --password "$(cat ${kieran.passwordFile})" --path /Notes ${lib.escapeShellArg kieran.target} ${kieran.endpoint}
'';
serviceConfig = {
Type = "oneshot";
Restart = "on-failure";
@@ -89,26 +66,23 @@
set -efu
book="$({
${pkgs.findutils}/bin/find ${config.users.users.me.home}/cloud/syncthing/library -type f
${pkgs.findutils}/bin/find ${config.users.users.me.home}/cloud/nextcloud/Books -type f
${pkgs.findutils}/bin/find ${config.users.users.me.home}/cloud/Seafile/Books -type f
} | ${pkgs.fzf}/bin/fzf)"
exec ${pkgs.zathura}/bin/zathura "$book"
'')
(
let
kieran = {
user = "kieran.meinhardt@gmail.com";
passwordFile = config.age.secrets.mega-password.path;
};
megatools =
command:
''${pkgs.megatools}/bin/megatools ${command} --username ${lib.escapeShellArg kieran.user} --password "$(cat ${kieran.passwordFile})"'';
in
(let
kieran = {
user = "kieran.meinhardt@gmail.com";
passwordFile = config.age.secrets.mega-password.path;
};
megatools = command: ''${pkgs.megatools}/bin/megatools ${command} --username ${lib.escapeShellArg kieran.user} --password "$(cat ${kieran.passwordFile})"'';
in
pkgs.writers.writeDashBin "book-mega" ''
set -efu
selection="$(${megatools "ls"} | ${pkgs.fzf}/bin/fzf)"
test -n "$selection" || exit 1
tmpdir="$(mktemp -p "$XDG_RUNTIME_DIR" -d)"
tmpdir="$(mktemp -d)"
trap clean EXIT
clean() {
rm -rf "$tmpdir"
@@ -119,8 +93,7 @@
${megatools "get"} "$selection"
exec ${pkgs.zathura}/bin/zathura "$(basename "$selection")"
)
''
)
'')
];
age.secrets.mega-password = {
@@ -130,7 +103,17 @@
mode = "400";
};
services.syncthing = {
fileSystems."/media/moodle" = {
device = "zaatar.r:/moodle";
fsType = "nfs";
options = [
"x-systemd.idle-timeout=600"
"noauto"
"x-systemd.automount"
];
};
services.syncthing = rec {
enable = true;
user = "kfm";
openDefaultPorts = true;
@@ -138,31 +121,16 @@
dataDir = "/home/kfm/.config/syncthing";
cert = config.age.secrets.syncthing-cert.path;
key = config.age.secrets.syncthing-key.path;
settings = {
devices = pkgs.lib.niveum.syncthingIds;
folders = {
"${config.users.users.me.home}/sync" = {
devices = [
"kabsa"
"manakish"
"fatteh"
];
label = "sync";
versioning.type = "trashcan";
versioning.params.cleanoutDays = 100;
};
"${config.users.users.me.home}/mobile" = {
devices = [
"kabsa"
"manakish"
"fatteh"
"kibbeh"
];
id = "mobile";
label = "mobile";
versioning.type = "trashcan";
versioning.params.cleanoutDays = 100;
};
inherit ((import ../lib).syncthing) devices;
folders = let
cloud-dir = "${config.users.users.me.home}/cloud";
in {
"${cloud-dir}/syncthing/common".devices = ["kabsa" "manakish"];
"${cloud-dir}/syncthing/library".devices = ["kabsa" "manakish" "heym"];
"${cloud-dir}/syncthing/mundoiu".devices = ["kabsa" "manakish" "heym"];
"${cloud-dir}/syncthing/music" = {
devices = ["kabsa" "manakish" "heym" "zaatar"];
id = "music";
};
};
};

View File

@@ -2,27 +2,36 @@
pkgs,
lib,
config,
niveumPackages,
inputs,
...
}:
let
}: let
inherit (lib.strings) makeBinPath;
in
{
inherit (import ../lib) localAddresses kieran;
defaultApplications = (import ../lib).defaultApplications {inherit pkgs;};
in {
imports = [
inputs.self.nixosModules.system-dependent
inputs.self.nixosModules.traadfri
inputs.self.nixosModules.power-action
{
boot.supportedFilesystems = [ "ntfs" ];
boot.supportedFilesystems = ["ntfs"];
}
{
nixpkgs = {
config = {
allowUnfree = true;
packageOverrides = pkgs: {
dmenu = pkgs.writers.writeDashBin "dmenu" ''exec ${pkgs.rofi}/bin/rofi -dmenu "$@"'';
};
permittedInsecurePackages = [
"qtwebkit-5.212.0-alpha4"
];
};
};
}
{
boot.tmp.cleanOnBoot = true;
boot.cleanTmpDir = true;
boot.loader.timeout = 1;
}
{
@@ -31,7 +40,7 @@ in
file = ../secrets/di-fm-key.age;
owner = config.users.users.me.name;
group = config.users.users.me.group;
mode = "440";
mode = "400";
};
restic = {
file = ../secrets/restic.age;
@@ -47,6 +56,7 @@ in
enable = true;
options = {
selection-clipboard = "clipboard";
recolor-keephue = true;
# first-page-column = "1:1"; # makes side-by-side mode start on the left side
};
};
@@ -59,72 +69,117 @@ in
users.users.me = {
name = "kfm";
description = pkgs.lib.niveum.kieran.name;
hashedPasswordFile = config.age.secrets.kfm-password.path;
description = kieran.name;
hashedPassword = "$6$w9hXyGFl/.IZBXk$5OiWzS1G.5hImhh1YQmZiCXYNAJhi3X6Y3uSLupJNYYXPLMsQpx2fwF4Xr2uYzGMV8Foqh8TgUavx1APD9rcb/";
isNormalUser = true;
uid = 1000;
extraGroups = [
"pipewire"
"audio"
"lp"
"scanner"
];
};
nix.settings.trusted-users = [ config.users.users.me.name ];
age.secrets = {
kfm-password.file = ../secrets/kfm-password.age;
};
home-manager.users.me.xdg.enable = true;
}
{
environment.interactiveShellInit = "export PATH=$PATH";
environment.shellAliases =
let
swallow = command: "${pkgs.swallow}/bin/swallow ${command}";
in
{
sxiv = swallow "${pkgs.nsxiv}/bin/nsxiv";
zathura = swallow "${pkgs.zathura}/bin/zathura";
im = "${pkgs.openssh}/bin/ssh weechat@makanek -t screen -x weechat";
yt = "${pkgs.yt-dlp}/bin/yt-dlp --add-metadata -ic"; # Download video link
yta = "${pkgs.yt-dlp}/bin/yt-dlp --add-metadata --audio-format mp3 --audio-quality 0 -xic"; # Download with audio
};
environment.interactiveShellInit = "export PATH=$PATH:$HOME/projects/niveum";
environment.shellAliases = let
wcd = pkgs.writers.writeDash "wcd" ''
cd "$(readlink "$(${pkgs.which}/bin/which --skip-alias "$1")" | xargs dirname)/.."
'';
where = pkgs.writers.writeDash "where" ''
readlink "$(${pkgs.which}/bin/which --skip-alias "$1")" | xargs dirname
'';
take = pkgs.writers.writeDash "take" ''
mkdir "$1" && cd "$1"
'';
cdt = pkgs.writers.writeDash "cdt" ''
cd "$(mktemp -d)"
pwd
'';
swallow = command: "${niveumPackages.swallow}/bin/swallow ${command}";
in {
"ß" = "${pkgs.util-linux}/bin/setsid";
cat = "${pkgs.bat}/bin/bat --style=plain";
chromium-incognito = "chromium --user-data-dir=$(mktemp -d /tmp/chr.XXXXXX) --no-first-run --incognito";
cp = "cp --interactive";
ip = "${pkgs.iproute2}/bin/ip -c";
l = "ls --color=auto --time-style=long-iso --almost-all";
ls = "ls --color=auto --time-style=long-iso";
ll = "ls --color=auto --time-style=long-iso -l";
la = "ls --color=auto --time-style=long-iso --almost-all -l";
mv = "mv --interactive";
nixi = "nix repl '<nixpkgs>'";
ns = "nix-shell --run zsh";
o = "${pkgs.xdg-utils}/bin/xdg-open";
pbcopy = "${pkgs.xclip}/bin/xclip -selection clipboard -in";
pbpaste = "${pkgs.xclip}/bin/xclip -selection clipboard -out";
rm = "rm --interactive";
s = "${pkgs.systemd}/bin/systemctl";
take = "source ${take}";
cdt = "source ${cdt}";
vit = "$EDITOR $(mktemp)";
tmux = "${pkgs.tmux}/bin/tmux -2";
sxiv = swallow "${pkgs.nsxiv}/bin/nsxiv";
zathura = swallow "${pkgs.zathura}/bin/zathura";
us = "${pkgs.systemd}/bin/systemctl --user";
wcd = "source ${wcd}";
im = "${pkgs.openssh}/bin/ssh weechat@makanek -t tmux attach-session -t IM";
where = "source ${where}";
yt = "${pkgs.yt-dlp}/bin/yt-dlp --add-metadata -ic"; # Download video link
yta = "${pkgs.yt-dlp}/bin/yt-dlp --add-metadata -xic"; # Download with audio
};
}
{
i18n = {
defaultLocale = "en_DK.UTF-8";
supportedLocales = [ "all" ];
supportedLocales = ["all"];
};
}
{
services.power-profiles-daemon.enable = true;
services.xserver = {
enable = true;
displayManager = {
autoLogin = {
enable = true;
user = config.users.users.me.name;
};
lightdm = {
enable = true;
greeters.gtk = {
enable = true;
indicators = ["~spacer" "~host" "~spacer" "~session" "~power"];
};
};
};
};
}
{
programs.gnupg = {
agent = {
security.wrappers = {
pmount = {
setuid = true;
owner = "root";
group = "root";
source = "${pkgs.pmount}/bin/pmount";
};
pumount = {
setuid = true;
owner = "root";
group = "root";
source = "${pkgs.pmount}/bin/pumount";
};
};
}
{programs.command-not-found.enable = true;}
{
home-manager.users.me = {
services.gpg-agent = rec {
enable = true;
pinentryPackage = pkgs.pinentry-qt;
settings =
let
defaultCacheTtl = 2 * 60 * 60;
in
{
default-cache-ttl = defaultCacheTtl;
max-cache-ttl = 4 * defaultCacheTtl;
};
enableZshIntegration = true;
defaultCacheTtl = 2 * 60 * 60;
maxCacheTtl = 4 * defaultCacheTtl;
};
};
environment.systemPackages = [
pkgs.gnupg
(pkgs.pass.withExtensions (e: [
e.pass-otp
e.pass-import
e.pass-genphrase
]))
(pkgs.pass.withExtensions (e: [e.pass-otp e.pass-import e.pass-genphrase]))
];
}
{
@@ -132,94 +187,95 @@ in
}
{
services.getty = {
greetingLine = lib.mkForce "As-salamu alaykum wa rahmatullahi wa barakatuh!";
greetingLine = lib.mkForce "";
helpLine = lib.mkForce "";
};
}
{
networking.hosts = lib.mapAttrs' (name: address: {
name = address;
value = [ "${name}.local" ];
}) pkgs.lib.niveum.localAddresses;
networking.hosts =
lib.mapAttrs' (name: address: {
name = address;
value = ["${name}.local"];
})
localAddresses;
}
{
home-manager.users.me.home.stateVersion = "22.05";
home-manager.backupFileExtension = "bak";
}
{
systemd.user.services.udiskie = {
after = ["udisks2.service"];
wants = ["udisks2.service"];
wantedBy = ["graphical-session.target"];
serviceConfig = {
ExecStart = "${pkgs.udiskie}/bin/udiskie --verbose --no-config --notify";
};
};
services.udisks2.enable = true;
programs.dconf.enable = true;
home-manager.users.me = {
dconf.enable = true;
dconf.settings = {
# Change the default terminal for Nemo
"org/cinnamon/desktop/applications/terminal".exec = lib.getExe pkgs.niphas-terminal;
"org/cinnamon/desktop/applications/terminal".exec = defaultApplications.terminal;
};
};
}
./android.nix
./stylix.nix
./alacritty.nix
./backup.nix
./bash.nix
./beets.nix
./bluetooth.nix
./aerc.nix
./ccc.nix
./khal.nix
./browser.nix
./chromium.nix
./clipboard.nix
./cloud.nix
./direnv.nix
./docker.nix
./dunst.nix
./flix.nix
./fonts.nix
./fzf.nix
./git.nix
./hledger.nix
./htop.nix
./lix.nix
./uni.nix
# ./i3.nix
./graphical
./keyboard
./kdeconnect.nix
{ services.upower.enable = true; }
./hu-berlin.nix
./i3.nix
./keyboard.nix
./lb.nix
./mpv.nix
./mime.nix
./editor.nix
./neovim.nix
./nix.nix
./newsboat.nix
./flameshot.nix
./packages.nix
./virtualization.nix
./picom.nix
./stardict.nix
./polkit.nix
./power-action.nix
./printing.nix
# ./openweathermap.nix
./wallpaper.nix
./redshift.nix
./retiolum.nix
./rofi.nix
./spacetime.nix
./seafile.nix
./ssh.nix
./sshd.nix
./sound.nix
./sudo.nix
./themes.nix
./tmux.nix
./traadfri.nix
./unclutter.nix
./vscode.nix
./wallpaper.nix
{
home-manager.users.me.home.file.".zshrc".text = ''
# nothing to see here
'';
}
{
programs.zsh.interactiveShellInit = ''
hash -d nixos=/etc/nixos niveum=${config.users.users.me.home}/sync/src/niveum
'';
home-manager.users.me = {
xdg.userDirs =
let
pictures = "${config.users.users.me.home}/cloud/nextcloud/Bilder";
in
{
enable = true;
documents = "${config.users.users.me.home}/cloud/nextcloud/Documents";
desktop = "/tmp";
download = "${config.users.users.me.home}/sync/Downloads";
music = "${config.users.users.me.home}/mobile/audio";
publicShare = "${config.users.users.me.home}/cloud/nextcloud/tmp";
videos = pictures;
pictures = pictures;
};
};
}
./watson.nix
./zsh.nix
./tor.nix
./mastodon-bot.nix
];
}

37
configs/direnv.nix Normal file
View File

@@ -0,0 +1,37 @@
{pkgs, ...}: let
nixify = pkgs.writers.writeDashBin "nixify" ''
set -efuC
if [ ! -e ./.envrc ]; then
echo use_nix > .envrc
direnv allow
fi
if [ ! -e shell.nix ]; then
cat > shell.nix <<'EOF'
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
packages = [];
}
EOF
''${EDITOR:-vim} shell.nix
fi
'';
in {
environment.systemPackages = [pkgs.direnv nixify];
home-manager.users.me.programs.direnv = {
enable = true;
stdlib = builtins.readFile "${
pkgs.fetchFromGitHub {
owner = "Mic92";
repo = "dotfiles";
rev = "a0a9b7e358fa70a85cd468f8ca1fbb02ae0a91df";
sha256 = "1y9h5s1lf59sczsm0ksq2x1yhl98ba9lwk5yil3q53rg7n4574pg";
}
}/home/.direnvrc";
};
programs.zsh.interactiveShellInit = ''
eval "$(${pkgs.direnv}/bin/direnv hook zsh)"
'';
}

15
configs/distrobump.nix Normal file
View File

@@ -0,0 +1,15 @@
{
lib,
config,
pkgs,
...
}: {
imports = [
(import <stockholm/makefu/3modules/bump-distrowatch.nix> {
inherit lib config;
pkgs = pkgs // {writeDash = pkgs.writers.writeDash;};
})
];
makefu.distrobump.enable = false;
}

16
configs/docker.nix Normal file
View File

@@ -0,0 +1,16 @@
{
lib,
pkgs,
...
}: {
virtualisation.docker = {
enable = true;
# for ICE wifi, ref https://gist.github.com/sunsided/7840e89ff4e11b64a2d7503fafa0290c
extraOptions = lib.concatStringsSep " " [
"--bip=172.39.1.5/24"
"--fixed-cidr=172.39.1.0/25"
];
};
users.users.me.extraGroups = ["docker"];
environment.systemPackages = [pkgs.docker pkgs.docker-compose];
}

66
configs/dunst.nix Normal file
View File

@@ -0,0 +1,66 @@
{
config,
pkgs,
...
}: let
inherit (import ../lib) defaultApplications colours theme;
in {
home-manager.users.me.services.dunst = {
enable = true;
iconTheme = (theme pkgs).icon;
settings = {
global = {
transparency = 10;
font = "Monospace 8";
geometry = "200x5-30+20";
frame_color = colours.foreground;
follow = "mouse";
indicate_hidden = true;
notification_height = 0;
separator_height = 2;
padding = 8;
horizontal_padding = 8;
separator_color = "auto";
sort = true;
markup = "full";
format = "%a\\n<b>%s</b>\\n%b";
alignment = "left";
show_age_threshold = 60;
bounce_freq = 0;
word_wrap = true;
ellipsize = "middle";
ignore_newline = false;
stack_duplicates = true;
hide_duplicate_count = false;
max_icon_size = 32;
sticky_history = true;
history_length = 20;
dmenu = "${pkgs.rofi}/bin/rofi -display-run dunst -show run";
browser = (defaultApplications pkgs).browser;
verbosity = "mesg";
corner_radius = 0;
mouse_left_click = "do_action";
mouse_right_click = "close_current";
mouse_middle_click = "close_all";
};
urgency_low = rec {
frame_color = background;
background = colours.foreground;
foreground = colours.background;
timeout = 5;
};
urgency_normal = rec {
frame_color = background;
background = colours.foreground;
foreground = colours.background;
timeout = 10;
};
urgency_critical = rec {
frame_color = background;
background = colours.red.dark;
foreground = colours.background;
timeout = 0;
};
};
};
}

View File

@@ -1,51 +0,0 @@
{
pkgs,
lib,
config,
...
}:
{
home-manager.users.me = {
editorconfig = {
enable = true;
settings = {
"*" = {
charset = "utf-8";
end_of_line = "lf";
trim_trailing_whitespace = true;
insert_final_newline = true;
indent_style = "space";
indent_size = 2;
};
"*.py" = {
indent_size = 4;
};
Makefile = {
indent_style = "tab";
};
"*.md" = {
trim_trailing_whitespace = false;
};
};
};
};
environment.systemPackages = [
pkgs.vim-typewriter
pkgs.dawn-editor
# language servers
pkgs.pyright
pkgs.haskellPackages.haskell-language-server
pkgs.texlab
pkgs.gopls
pkgs.nixfmt-rfc-style
pkgs.rust-analyzer
pkgs.nodePackages.typescript-language-server
pkgs.lua-language-server
pkgs.nodePackages.vscode-langservers-extracted
pkgs.lemminx # XML LSP
pkgs.jq-lsp
pkgs.dhall-lsp-server
];
}

View File

@@ -2,8 +2,7 @@
lib,
pkgs,
...
}:
{
}: {
home-manager.users.me = {
services.flameshot = {
enable = true;
@@ -11,12 +10,13 @@
autoCloseIdleDaemon = true;
drawColor = "#ff0000";
drawThickness = 2;
checkForUpdates = false;
showDesktopNotification = true;
disabledTrayIcon = true;
showHelp = false;
squareMagnifier = true;
uploadWithoutConfirmation = true;
# buttons = ''@Variant(\0\0\0\x7f\0\0\0\vQList<int>\0\0\0\0\x10\0\0\0\x2\0\0\0\x5\0\0\0\x13\0\0\0\xa\0\0\0\x1\0\0\0\xc\0\0\0\xd\0\0\0\x6\0\0\0\x8\0\0\0\0\0\0\0\xf\0\0\0\x4\0\0\0\xb\0\0\0\x3\0\0\0\x12\0\0\0\x9)'';
buttons = ''@Variant(\0\0\0\x7f\0\0\0\vQList<int>\0\0\0\0\x10\0\0\0\x2\0\0\0\x5\0\0\0\x13\0\0\0\xa\0\0\0\x1\0\0\0\xc\0\0\0\xd\0\0\0\x6\0\0\0\x8\0\0\0\0\0\0\0\xf\0\0\0\x4\0\0\0\xb\0\0\0\x3\0\0\0\x12\0\0\0\x9)'';
};
};
};

98
configs/flix.nix Normal file
View File

@@ -0,0 +1,98 @@
{
config,
pkgs,
...
}: let
flixLocation = "/media/flix";
flixLocationNew = "/media/flix-new";
cacheLocation = "/var/cache/flix";
indexFilename = "index";
indexFilenameNew = "index-new";
flixUser = "flix";
flixGroup = "users";
inherit (import ../lib) tmpfilesConfig;
in {
fileSystems.${flixLocation} = {
device = "prism.r:/export/download";
fsType = "nfs";
options = [
"noauto"
"noatime"
"nodiratime"
"x-systemd.automount"
"x-systemd.device-timeout=1"
"x-systemd.idle-timeout=1min"
"x-systemd.requires=tinc.retiolum.service"
"user"
"_netdev"
];
};
fileSystems.${flixLocationNew} = {
device = "//yellow.r/public";
fsType = "cifs";
options = [
"guest"
"nofail"
"noauto"
"ro"
"x-systemd.automount"
"x-systemd.device-timeout=1"
"x-systemd.idle-timeout=1min"
];
};
systemd.tmpfiles.rules = [
(tmpfilesConfig {
type = "d";
path = cacheLocation;
mode = "0750";
user = flixUser;
group = flixGroup;
})
];
systemd.services.flix-index = {
description = "Flix indexing service";
wants = ["network-online.target"];
script = ''
cp ${flixLocation}/index ./${indexFilename}
cp ${flixLocationNew}/index ./${indexFilenameNew}
'';
startAt = "hourly";
serviceConfig = {
Type = "oneshot";
User = flixUser;
Group = flixGroup;
WorkingDirectory = cacheLocation;
};
};
users.extraUsers.${flixUser} = {
isSystemUser = true;
createHome = true;
home = cacheLocation;
group = flixGroup;
};
environment.systemPackages = [
(pkgs.writers.writeDashBin "mpv-simpsons" ''
set -efu
cd "${flixLocation}/download"
[ -f "${cacheLocation}/${indexFilename}" ] || exit 1
cat "${cacheLocation}/${indexFilename}" \
| ${pkgs.gnugrep}/bin/grep -i 'simpsons.*mkv' \
| shuf \
| ${pkgs.findutils}/bin/xargs -d '\n' ${pkgs.mpv}/bin/mpv
'')
(pkgs.writers.writeDashBin "flixmenu" ''
set -efu
(
${pkgs.gnused}/bin/sed 's#^\.#${flixLocation}#' ${cacheLocation}/${indexFilename}
${pkgs.gnused}/bin/sed 's#^\.#${flixLocationNew}#' ${cacheLocation}/${indexFilenameNew}
) | ${pkgs.dmenu}/bin/dmenu -i -p flix -l 5 "$@" \
| ${pkgs.findutils}/bin/xargs -I '{}' ${pkgs.util-linux}/bin/setsid ${pkgs.xdg-utils}/bin/xdg-open '{}'
'')
];
}

View File

@@ -1,32 +1,28 @@
{
pkgs,
niveumPackages,
...
}:
let
zip-font =
name: arguments:
let
directory = pkgs.fetchzip arguments;
in
pkgs.runCommand name { } ''
}: let
zip-font = name: arguments: let
directory = pkgs.fetchzip arguments;
in
pkgs.runCommand name {} ''
mkdir -p $out/share/fonts/{truetype,opentype,woff}
${pkgs.findutils}/bin/find ${directory} -name '*.ttf' -exec install '{}' $out/share/fonts/truetype \;
${pkgs.findutils}/bin/find ${directory} -name '*.otf' -exec install '{}' $out/share/fonts/opentype \;
${pkgs.findutils}/bin/find ${directory} -name '*.woff' -exec install '{}' $out/share/fonts/woff \;
'';
simple-ttf =
name: arguments:
let
file = pkgs.fetchurl arguments;
in
pkgs.runCommand name { } ''
simple-ttf = name: arguments: let
file = pkgs.fetchurl arguments;
in
pkgs.runCommand name {} ''
mkdir -p $out/share/fonts/truetype
install ${file} $out/share/fonts/truetype
'';
egyptianHiero = zip-font "EgyptianHiero" {
url = "https://github.com/MKilani/Djehuty/archive/master.zip";
sha256 = "sha256-S3vZxdeBj57KJsF+zaZw7sQw8T+z1aVC2CnpnZ0/x2c=";
sha256 = "sha256-KbY4vedm757NWfDlgmNhslbZd+2Vs+o5PjtMMGDt61Y=";
};
antinoou = zip-font "Antinoou" {
url = "https://www.evertype.com/fonts/coptic/AntinoouFont.zip";
@@ -35,9 +31,13 @@ let
};
newGardiner = zip-font "NewGardiner" {
url = "https://mjn.host.cs.st-andrews.ac.uk/egyptian/fonts/NewGardiner.zip";
hash = "sha256-nP0y4ILt+0mlkDRdCNSeO2Gequ8wyix/qQdmujTNw3Y=";
sha256 = "1jd0qa6shh9pqqyig2w43m9l9rv1i50l73jzkhb6g6mqxbhb1mip";
stripRoot = false;
};
junicode2 = zip-font "JunicodeTwo" {
url = "https://github.com/psb1558/Junicode-font/archive/48bf476db278c844c67542b04d1e0e4c71f139d2.zip";
sha256 = "1ryicc155vkvgv3315ddliigwa01afwyb4c4f6pnqcns03af001i";
};
newAthenaUnicode = zip-font "NewAthenaUnicode" {
url = "https://classicalstudies.org/sites/default/files/userfiles/files/NAU5_005.zip";
sha256 = "1g7qk9gl4nq2dz41bvck1nzilhin44j8691cxax3dlp77bbn9bxr";
@@ -46,28 +46,15 @@ let
url = "http://files.qenherkhopeshef.org/jsesh/JSeshFont.ttf";
sha256 = "1203jrk2xzvgckcc5hx88kja1i3h8gm1wiyla5j6gspc0hbv56ry";
};
egyptianTextBeta = simple-ttf "EgyptianText-1.0beta" {
egyptianText = simple-ttf "EgyptianText-1.0beta" {
url = "http://c.krebsco.de/EgyptianText-v1.0-beta.ttf";
sha256 = "0cfjbk7xxnxhlp6v922psm5j1xzrv6wfk226ji2wz2yfrnkbcbsv";
};
coranica = simple-ttf "Coranica" {
url = "https://corpuscoranicum.de/fonts/coranica_1164.ttf";
sha256 = "0igi8q8b2p38x9jq8c98afsl7bf8rj32zj2052yyjgj9r88y4yi5";
};
koineGreek = simple-ttf "KoineGreek.ttf" {
url = "https://github.com/Center-for-New-Testament-Restoration/font/raw/af83eed50105344edaa5e5eddaf87696e271468c/KoineGreek.ttf";
hash = "sha256-YtC+nj7+Jl8k00rqAAqySYc8iTAOL7PixXc+LfSmnS0=";
};
egyptianText = simple-ttf "EgyptianText" {
url = "https://github.com/microsoft/font-tools/raw/1092cb23520967830001a0807eb21d6a44dda522/EgyptianOpenType/font/eot.ttf";
sha256 = "1n294vhcx90270pnsw1dbk6izd61fjvbnjrh4hcf98ff3s540x0c";
};
in
{
in {
fonts = {
enableDefaultPackages = true;
enableDefaultFonts = true;
fontDir.enable = true;
packages = with pkgs; [
fonts = with pkgs; [
alegreya
alegreya-sans
amiri
@@ -78,26 +65,22 @@ in
charis-sil
doulos-sil
newAthenaUnicode
coranica
corefonts
crimson
eb-garamond
ipaexfont
jsesh
egyptianHiero
egyptianText
egyptianTextBeta
font-awesome_6
etBook
newGardiner
junicode
koineGreek
# brill
junicode2
ezra-sil
fira
font-awesome
galatia-sil
gentium
niveumPackages.gfs-fonts
gyre-fonts
ibm-plex
jetbrains-mono
@@ -106,45 +89,28 @@ in
lmodern
merriweather
ocr-a
montserrat
roboto
roboto-mono
noto-fonts
noto-fonts-cjk-sans
noto-fonts-color-emoji
noto-fonts-cjk
noto-fonts-emoji
roboto-slab
scheherazade-new
source-code-pro
source-sans-pro
source-serif-pro
theano
tocharian-font
vista-fonts
niveumPackages.tocharian-font
vistafonts
vollkorn
zilla-slab
]; # google-fonts league-of-moveable-type
fontconfig.defaultFonts =
let
emoji = [ "Noto Color Emoji" ];
in
{
monospace = [ "Noto Sans Mono" ] ++ emoji;
serif = [
"Noto Serif"
"Noto Naskh Arabic"
"Noto Serif Devanagari"
];
sansSerif = [
"Noto Sans Display"
"Noto Naskh Arabic"
"Noto Sans Hebrew"
"Noto Sans Devanagari"
"Noto Sans CJK JP"
"Noto Sans Coptic"
"Noto Sans Syriac Western"
];
inherit emoji;
};
fontconfig.defaultFonts = rec {
monospace = ["Noto Sans Mono"] ++ emoji;
serif = ["Noto Serif" "Noto Naskh Arabic" "Noto Serif Devanagari"];
sansSerif = ["Noto Sans Display" "Noto Kufi Arabic" "Noto Sans Devanagari" "Noto Sans CJK JP"];
emoji = ["Noto Color Emoji"];
};
# xelatex fails with woff files
# ref https://tex.stackexchange.com/questions/392144/xelatex-and-fontspec-crash-trying-to-find-woff-file-for-some-fonts-but-not-other
fontconfig.localConf = ''

37
configs/fzf.nix Normal file
View File

@@ -0,0 +1,37 @@
{
pkgs,
lib,
...
}: {
environment = {
systemPackages = [pkgs.fzf];
variables = rec {
FZF_DEFAULT_COMMAND = "${pkgs.fd}/bin/fd --type f --strip-cwd-prefix --follow --no-ignore-vcs --exclude .git";
FZF_DEFAULT_OPTS =
lib.escapeShellArgs ["--height=40%"];
FZF_ALT_C_COMMAND = "${pkgs.fd}/bin/fd --type d";
FZF_ALT_C_OPTS = lib.escapeShellArgs [
"--preview='${pkgs.tree}/bin/tree -L 1 \"{}\"'"
"--bind=space:toggle-preview"
"--preview-window=hidden"
];
FZF_CTRL_T_COMMAND = FZF_DEFAULT_COMMAND;
FZF_CTRL_T_OPTS =
lib.escapeShellArgs ["--preview='head -$LINES {}'"];
};
};
programs.zsh.interactiveShellInit = ''
if [[ $options[zle] = on ]]; then
. ${pkgs.fzf}/share/fzf/completion.zsh
. ${pkgs.fzf}/share/fzf/key-bindings.zsh
fi
'';
programs.bash.interactiveShellInit = ''
if [[ :$SHELLOPTS: =~ :(vi|emacs): ]]; then
. ${pkgs.fzf}/share/fzf/completion.bash
. ${pkgs.fzf}/share/fzf/key-bindings.bash
fi
'';
}

View File

@@ -1,23 +0,0 @@
{ pkgs, ... }:
{
environment.systemPackages = [
pkgs.zeroad
pkgs.mari0
pkgs.luanti # fka minetest
# pkgs.openarena
# pkgs.teeworlds
pkgs.nethack
# pkgs.freeciv
# pkgs.lincity-ng
# pkgs.superTuxKart
pkgs.morris
pkgs.gnome-chess
pkgs.gnuchess
];
networking.firewall = {
# for 0ad multiplayer
allowedTCPPorts = [ 20595 ];
allowedUDPPorts = [ 20595 ];
};
}

64
configs/git.nix Normal file
View File

@@ -0,0 +1,64 @@
{
pkgs,
config,
lib,
inputs,
...
}: let
inherit (import ../lib) kieran ignorePaths;
in {
environment.systemPackages = [
pkgs.mr
pkgs.git
pkgs.git-crypt
pkgs.gitAndTools.gitflow
pkgs.gitAndTools.gh
pkgs.gitAndTools.git-extras
pkgs.gitAndTools.git-trim
pkgs.gitAndTools.git-absorb
pkgs.gitstats
pkgs.patch
pkgs.patchutils
inputs.self.packages.x86_64-linux.git-preview
];
environment.shellAliases = {
gf = "git-flow";
g = "git";
};
home-manager.users.me = {
programs.git = {
enable = true;
package = pkgs.gitAndTools.gitFull;
userName = kieran.name;
userEmail = kieran.email;
aliases = {
br = "branch";
co = "checkout";
ci = "commit";
cm = "commit -m";
amend = "commit --amend";
st = "status -s";
unstage = "reset HEAD --";
diffs = "diff --staged";
last = "log -1 HEAD";
logs = "log --pretty=oneline";
graph = "log --graph --abbrev-commit --decorate --date=relative --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all";
};
ignores = ignorePaths;
extraConfig = {
pull.ff = "only";
rebase.autoStash = true;
merge.autoStash = true;
# # ref https://github.com/dandavison/delta
# core.pager = "${pkgs.delta}/bin/delta";
# interactive.diffFilter = "${pkgs.delta}/bin/delta --color-only";
# delta.navigate = true;
# merge.conflictStyle = "diff3";
# diff.colorMoved = "default";
};
};
};
}

View File

@@ -1,5 +0,0 @@
{
services.xserver.enable = true;
services.xserver.displayManager.lightdm.enable = true;
services.xserver.desktopManager.gnome.enable = true;
}

View File

@@ -1,44 +0,0 @@
{
pkgs,
lib,
config,
...
}:
{
programs.hyprland = {
enable = true;
withUWSM = true;
xwayland.enable = true;
package = pkgs.hyprland;
portalPackage = pkgs.xdg-desktop-portal-hyprland;
};
programs.ydotool.enable = true;
xdg.portal = {
enable = true;
extraPortals = [
pkgs.xdg-desktop-portal-hyprland
pkgs.xdg-desktop-portal-gtk
];
config.common.default = "*";
};
services.dbus = {
implementation = "broker";
# needed for GNOME services outside of GNOME (?)
packages = [ pkgs.gcr ];
};
environment.systemPackages = [
pkgs.xdg-desktop-portal
pkgs.xdg-desktop-portal-hyprland
];
services.getty.autologinOnce = true;
services.getty.autologinUser = config.users.users.me.name;
home-manager.users.me = import ./home-manager.nix {
inherit lib pkgs config;
};
}

View File

@@ -1,415 +0,0 @@
{
lib,
pkgs,
config,
...
}:
let
klem = pkgs.klem.override {
options.dmenu = "${pkgs.dmenu}/bin/dmenu -i -p klem";
options.scripts = {
"p.r paste" = pkgs.writers.writeDash "p.r" ''
${pkgs.curl}/bin/curl -fSs http://p.r --data-binary @- \
| ${pkgs.coreutils}/bin/tail --lines=1 \
| ${pkgs.gnused}/bin/sed 's/\\<r\\>/krebsco.de/'
'';
"envs.sh paste" = pkgs.writers.writeDash "envs-host" ''
${pkgs.curl}/bin/curl -F "file=@-" https://envs.sh
'';
# this segfaults
# "envs.sh mirror" = pkgs.writers.writeDash "envs-mirror" ''
# ${pkgs.curl}/bin/curl -F "url=$(${pkgs.coreutils}/bin/cat)" https://envs.sh
# '';
"envs.sh shorten" = pkgs.writers.writeDash "envs-shorten" ''
${pkgs.curl}/bin/curl -F "shorten=$(${pkgs.coreutils}/bin/cat)" https://envs.sh
'';
"go.r shorten" = pkgs.writers.writeDash "go.r" ''
${pkgs.curl}/bin/curl -fSs http://go.r -F "uri=$(${pkgs.coreutils}/bin/cat)"
'';
"4d2.org paste" = pkgs.writers.writeDash "4d2-paste" ''
${pkgs.curl}/bin/curl -F "file=@-" https://depot.4d2.org/
'';
"0x0.st shorten" = pkgs.writers.writeDash "0x0.st" ''
${pkgs.curl}/bin/curl -fSs https://0x0.st -F "shorten=$(${pkgs.coreutils}/bin/cat)"
'';
"rot13" = pkgs.writers.writeDash "rot13" ''
${pkgs.coreutils}/bin/tr '[A-Za-z]' '[N-ZA-Mn-za-m]'
'';
"ipa" = pkgs.writers.writeDash "ipa" ''
${pkgs.ipa}/bin/ipa
'';
"betacode" = pkgs.writers.writeDash "betacode" ''
${pkgs.betacode}/bin/betacode
'';
"curl" = pkgs.writers.writeDash "curl" ''
${pkgs.curl}/bin/curl -fSs "$(${pkgs.coreutils}/bin/cat)"
'';
ocr = pkgs.writers.writeDash "ocr" ''
${pkgs.tesseract4}/bin/tesseract -l eng+deu - stdout
'';
emojai = pkgs.writers.writeDash "emojai" ''
${pkgs.curl}/bin/curl https://www.emojai.app/api/generate -X POST -H 'Content-Type: application/json' --data-raw "$(${pkgs.jq}/bin/jq -sR '{emoji:.}')" | ${pkgs.jq}/bin/jq -r .result
'';
};
};
arabic.workspaces = [
"١"
"٢"
"٣"
"٤"
"٥"
"٦"
"٧"
"٨"
"٩"
"١٠"
];
arabic.music = "الموسيقى";
arabic.obsidian = "السبج";
hindi.workspaces = [
""
""
""
""
""
""
""
""
""
""
];
hindi.music = "";
hindi.obsidian = "ि";
hebrew.workspaces = [
"א"
"ב"
"ג"
"ד"
"ה"
"ו"
"ז"
"ח"
"ט"
"י"
];
hebrew.music = "מוסיקה";
hebrew.obsidian = "אובסידיאן";
latin.workspaces = [
""
""
""
""
""
""
""
""
""
""
];
latin.music = "MVSICA";
latin.obsidian = "NOSCENDA";
greek.workspaces = [
"Α"
"Β"
"Γ"
"Δ"
"Ε"
"Ϛ"
"Ζ"
"Η"
"Θ"
"Ι"
];
greek.music = "ΜΟΥΣΙΚΗ";
greek.obsidian = "ΥΠΟΜΝΗΜΑΤΑ";
language = greek;
in
{
services.mako = {
enable = true;
settings.default-timeout = 10 * 1000;
};
programs.ashell = {
enable = true;
settings = {
# position = "bottom";
modules = {
left = [
"Workspaces"
[
"WindowTitle"
]
];
center = [ "Clock" ];
right = [
"KeyboardLayout"
[
"Tray"
"SystemInfo"
"Settings"
]
];
};
workspaces = {
enable_workspace_filling = false;
disable_special_workspaces = true;
visibility_mode = "MonitorSpecific";
workspace_names = language.workspaces;
};
keyboard_layout.labels = {
"de" = "🇩🇪";
};
window_title = {
mode = "Title";
truncate_title_after_length = 75;
};
media_player = {
max_title_length = 40;
};
system_info.indicators = [
"Cpu"
"Memory"
{ Disk = "/"; }
];
clock.format = "%Y-%m-%d (%j %a %W) %H:%M";
settings.indicators = [
"IdleInhibitor"
"PowerProfile"
"Audio"
"Bluetooth"
"Network"
"Vpn"
"Battery"
];
appearance = {
font_name = config.stylix.fonts.sansSerif.name;
backdrop = 0.3;
scale_factor = 0.85;
# style = "Solid";
};
};
};
services.hypridle = {
enable = true;
settings = {
general = {
after_sleep_cmd = "hyprctl dispatch dpms on";
ignore_dbus_inhibit = false;
lock_cmd = "hyprlock";
};
listener = [
{
timeout = 900;
on-timeout = "hyprlock";
}
{
timeout = 1200;
on-timeout = "hyprctl dispatch dpms off";
on-resume = "hyprctl dispatch dpms on";
}
];
};
};
programs.hyprlock = {
enable = true;
settings = {
animations.enabled = false;
general = {
hide_cursor = true;
ignore_empty_input = true;
};
};
};
gtk = {
enable = true;
iconTheme = {
name = "Adwaita";
package = pkgs.adwaita-icon-theme;
};
};
wayland.windowManager.hyprland =
let
mod = "SUPER";
in
{
enable = true;
systemd.enable = false;
systemd.variables = [ "--all" ];
settings = {
env = [
"XCURSOR_SIZE,${toString config.stylix.cursor.size}" # TODO
"HYPRCURSOR_SIZE,${toString config.stylix.cursor.size}" # TODO
"HYPRCURSOR_THEME,${config.stylix.cursor.name}"
"QT_QPA_PLATFORM=wayland"
"GDK_BACKEND=wayland"
"NIXOS_OZONE_WL=1"
];
permission = [
"${pkgs.xdg-desktop-portal-hyprland}/libexec/.xdg-desktop-portal-hyprland-wrapped, screencopy, allow"
];
monitor = [
"eDP-1, 1920x1080, 0x0, 1" # fatteh's display
"desc:Samsung Electric Company C27F390 HTQH602129, 1920x1080, 0x-1080, 1" # home
"desc:Dell Inc. DELL P2419HC 8L0FL03, 1920x1080, 0x-1080, 1" # amo
", preferred, auto, 1"
];
exec-once = [
(lib.getExe pkgs.ashell)
"hyprctl dispatch exec \"[workspace special:${language.obsidian} silent] obsidian\""
"${lib.getExe' pkgs.wl-clipboard "wl-paste"} -t text --watch ${lib.getExe pkgs.clipman} store"
(lib.getExe pkgs.hyprsunset)
(lib.getExe pkgs.hyprpaper)
];
device = [
{
name = "elan-touchscreen";
enabled = false;
}
];
general = {
gaps_in = 2;
gaps_out = 2;
border_size = 2;
resize_on_border = true;
allow_tearing = false;
layout = "dwindle";
};
decoration = {
rounding = 0;
rounding_power = 0;
active_opacity = 1.0;
inactive_opacity = 1.0;
shadow = {
enabled = false;
range = 4;
render_power = 3;
};
blur = {
enabled = false;
size = 3;
passes = 1;
vibrancy = 0.17;
};
};
animations = {
enabled = true;
animation = [
"global, 1, 2, default"
];
};
dwindle = {
preserve_split = true;
};
master.new_status = "master";
gesture = [
"3, horizontal, workspace"
];
input = {
kb_layout = "de";
kb_variant = "T3";
kb_options = "compose:caps,grp:ctrls_toggle";
follow_mouse = 1;
sensitivity = 0;
touchpad.natural_scroll = false;
};
bindm = [
"${mod}, mouse:272, movewindow"
"${mod}, mouse:273, resizewindow"
];
bindel = [
",XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+"
",XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"
",XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
",XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"
",XF86MonBrightnessUp, exec, brightnessctl -e4 -n2 set 5%+"
",XF86MonBrightnessDown, exec, brightnessctl -e4 -n2 set 5%-"
", Print, exec, ${lib.getExe pkgs.niphas-screenshot} -m region --clipboard-only"
];
bindl = [
", XF86AudioNext, exec, playerctl next"
", XF86AudioPause, exec, playerctl play-pause"
", XF86AudioPlay, exec, playerctl play-pause"
", XF86AudioPrev, exec, playerctl previous"
];
bind = [
"${mod}, Return, exec, ${lib.getExe pkgs.niphas-terminal}"
"${mod} SHIFT, Q, killactive,"
"${mod} SHIFT, R, exit,"
"${mod}, t, exec, ${lib.getExe pkgs.niphas-file-browser}"
"${mod}, Y, exec, ${lib.getExe pkgs.niphas-web-browser}"
"${mod}, Q, exec, ${lib.getExe pkgs.clipman} pick --tool=rofi"
"${mod}, u, exec, ${lib.getExe pkgs.unicodmenu}"
"${mod}, p, exec, ${lib.getExe pkgs.rofi-pass-wayland}"
"${mod} SHIFT, Z, togglefloating,"
"${mod}, D, exec, ${lib.getExe pkgs.rofi} -show run"
"${mod}, E, togglesplit," # dwindle
"${mod}, F, fullscreen"
"${mod}, G, moveoutofgroup"
"${mod} SHIFT, G, togglegroup"
"${mod}, h, movefocus, l"
"${mod}, l, movefocus, r"
"${mod}, k, movefocus, u"
"${mod}, j, movefocus, d"
"${mod}, F12, exec, ${klem}/bin/klem"
"${mod} SHIFT, W, exec, hyprlock"
"${mod} SHIFT, H, movewindow, l"
"${mod} SHIFT, L, movewindow, r"
"${mod} SHIFT, K, movewindow, u"
"${mod} SHIFT, J, movewindow, d"
"${mod}, S, togglespecialworkspace, ${language.music}"
"${mod} SHIFT, S, movetoworkspace, special:${language.music}"
"${mod}, O, togglespecialworkspace, ${language.obsidian}"
"${mod} SHIFT, O, movetoworkspace, special:${language.obsidian}"
]
++ lib.concatMap (
i:
let
key = lib.mod i 10;
in
[
"${mod}, ${toString key}, workspace, ${toString i}"
"${mod} SHIFT, ${toString key}, movetoworkspace, ${toString i}"
]
) (lib.range 1 10);
windowrule = [
"suppressevent maximize, class:.*" # ignore maximize requests from apps
"nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0" # fix some dragging issues with wayyland
"float,title:^(Picture-in-Picture)$"
"pin,title:^(Picture-in-Picture)$"
"size 640 360,title:^(Picture-in-Picture)$"
"move 100%-640 100%-360,title:^(Picture-in-Picture)$"
];
};
extraConfig = ''
bind = ${mod}, R, submap, resize
submap = resize
binde = , l, resizeactive, 50 0
binde = , h, resizeactive, -50 0
binde = , k, resizeactive, 0 -50
binde = , j, resizeactive, 0 50
bind = , escape, submap, reset
submap = reset
'';
};
}

View File

@@ -1,28 +1,39 @@
{
config,
pkgs,
...
}:
let
ledgerDirectory = "/home/kfm/sync/src/ledger";
in
{
environment.systemPackages =
let
git = "${pkgs.git}/bin/git -C ${ledgerDirectory}";
in
[
pkgs.hledger
(pkgs.writers.writeDashBin "hledger-git" ''
if [ "$1" = entry ]; then
${pkgs.hledger}/bin/hledger balance -V > "${ledgerDirectory}/balance.txt"
${git} add balance.txt
${git} commit --all --message="$(date -Im)"
else
${git} $*
fi
'')
(pkgs.writers.writeDashBin "hledger-edit" ''
$EDITOR ${ledgerDirectory}/current.journal
'')
];
}: {
environment.systemPackages = let
ledgerDirectory = "$HOME/projects/ledger";
timeLedger = "${ledgerDirectory}/time.timeclock";
git = "${pkgs.git}/bin/git -C ${ledgerDirectory}";
in [
pkgs.hledger
(pkgs.writers.writeDashBin "hora-edit" ''
$EDITOR + "${timeLedger}" && ${pkgs.git}/bin/git -C "$(${pkgs.coreutils}/bin/dirname ${timeLedger})" commit --all --message "$(${pkgs.coreutils}/bin/date -Im)"
'')
(pkgs.writers.writeDashBin "hora" ''
${pkgs.hledger}/bin/hledger -f "${timeLedger}" "$@"
'')
(pkgs.writers.writeDashBin "hora-filli" ''
${pkgs.hledger}/bin/hledger -f "${timeLedger}" register fillidefilla -O csv \
-b "$(date -d "$(date +%Y-%m)-20 last month" +%Y-%m-%d)" \
-e "$(date -d "$(date +%Y-%m)-20" +%Y-%m-%d)" \
| sed 's/(fillidefilla:\(.*\))/\1/g' \
| xsv select date,amount,total,account,description
'')
(pkgs.writers.writeDashBin "hledger-git" ''
if [ "$1" = entry ]; then
${pkgs.hledger}/bin/hledger balance -V > "${ledgerDirectory}/balance.txt"
${git} add balance.txt
${git} commit --all --message="$(date -Im)"
else
${git} $*
fi
'')
(pkgs.writers.writeDashBin "hledger-edit" ''
$EDITOR ${ledgerDirectory}/current.journal
'')
];
}

View File

@@ -20,20 +20,10 @@
show_thread_names = false;
sort_descending = true;
sort_key = "PERCENT_CPU";
tree_view = false;
tree_view = true;
update_process_names = false;
right_meters = [
"Uptime"
"Tasks"
"LoadAverage"
"Battery"
];
left_meters = [
"LeftCPUs2"
"RightCPUs2"
"Memory"
"Swap"
];
right_meters = ["Uptime" "Tasks" "LoadAverage" "Battery"];
left_meters = ["LeftCPUs2" "RightCPUs2" "Memory" "Swap"];
};
};
};

86
configs/hu-berlin.nix Normal file
View File

@@ -0,0 +1,86 @@
{
config,
pkgs,
lib,
...
}: let
inherit (lib.strings) fileContents;
inherit (import ../lib) sshPort;
eduroam = {
identity = fileContents <secrets/eduroam/identity>;
password = fileContents <secrets/eduroam/password>;
};
hu-berlin-cifs-options = [
"uid=${toString config.users.users.me.uid}"
"gid=${toString config.users.groups.users.gid}"
"sec=ntlmv2"
"workgroup=german"
"credentials=${config.age.secrets.cifs-credentials-hu-berlin.path}"
"noauto"
# "x-systemd.requires=hu-vpn.service"
"x-systemd.automount"
"x-systemd.device-timeout=1"
"x-systemd.idle-timeout=1min"
];
in {
fileSystems."/media/hu-berlin/germpro2" = {
device = "//hugerm31c.user.hu-berlin.de/germpro2/ling";
fsType = "cifs";
options = hu-berlin-cifs-options;
};
fileSystems."/media/hu-berlin/germhome" = {
device = "//hugerm31c.user.hu-berlin.de/germhome/ling/meinhaki";
fsType = "cifs";
options = hu-berlin-cifs-options;
};
age.secrets.cifs-credentials-hu-berlin.file = ../secrets/cifs-credentials-hu-berlin.age;
home-manager.users.me.programs.ssh = {
matchBlocks = {
"alew.hu-berlin.de" = {
user = "centos";
hostname = "141.20.187.219";
};
};
};
environment.systemPackages = [
(pkgs.writers.writeDashBin "hu-ip" ''
${pkgs.w3m}/bin/w3m -dump meineip.hu-berlin.de | head --lines=-4 | tail --lines=+3
'')
(
pkgs.writers.writePython3Bin "hu-eduroam-install"
{
libraries = with pkgs.python3Packages; [distro pyopenssl dbus-python];
flakeIgnore = ["E501" "E123" "W504" "E722" "F821" "E226" "E126" "E265" "W291"];
}
(builtins.readFile (builtins.fetchurl {
url = "https://www.cms.hu-berlin.de/de/dl/netze/wlan/config/eduroam/linux-installer/eduroam-linux-hub.py";
sha256 = "19x2kvwxx13265b2hj5fjf53g0liw6dw7xf9j9cav67cswmz60kf";
}))
)
];
systemd.services.hu-vpn = {
enable = true;
wants = ["network-online.target"];
serviceConfig.LoadCredential = "password:${config.age.secrets.email-password-meinhark.path}";
script = ''
if ${pkgs.wirelesstools}/bin/iwgetid | ${pkgs.gnugrep}/bin/grep --invert-match eduroam
then
${pkgs.openfortivpn}/bin/openfortivpn \
--password="$(cat "$CREDENTIALS_DIRECTORY/password")" \
--config=${
pkgs.writeText "hu-berlin.config" ''
host = forti-ssl.vpn.hu-berlin.de
port = 443
username = meinhark
trusted-cert = 9e5dea8e077970d245900839f437ef7fb9551559501c7defd70af70ea568573d
''
}
fi
'';
};
}

View File

@@ -2,44 +2,44 @@
config,
pkgs,
lib,
niveumPackages,
...
}:
let
klem = pkgs.klem.override {
options.dmenu = "${pkgs.dmenu}/bin/dmenu -i -p klem";
options.scripts = {
"p.r paste" = pkgs.writers.writeDash "p.r" ''
}: let
inherit (import ../lib) defaultApplications colours;
klem = niveumPackages.klem.override {
config.dmenu = "${pkgs.dmenu}/bin/dmenu -i -p klem";
config.scripts = {
"p.r" = pkgs.writers.writeDash "p.r" ''
${pkgs.curl}/bin/curl -fSs http://p.r --data-binary @- \
| ${pkgs.coreutils}/bin/tail --lines=1 \
| ${pkgs.gnused}/bin/sed 's/\\<r\\>/krebsco.de/'
'';
"envs.sh paste" = pkgs.writers.writeDash "envs-host" ''
${pkgs.curl}/bin/curl -F "file=@-" https://envs.sh
'';
# this segfaults
# "envs.sh mirror" = pkgs.writers.writeDash "envs-mirror" ''
# ${pkgs.curl}/bin/curl -F "url=$(${pkgs.coreutils}/bin/cat)" https://envs.sh
# "envs.sh host" = pkgs.writers.writeDash "envs-host" ''
# ${pkgs.curl}/bin/curl -F "file=$(${pkgs.coreutils}/bin/cat)" https://envs.sh
# '';
"envs.sh mirror" = pkgs.writers.writeDash "envs-mirror" ''
${pkgs.curl}/bin/curl -F "url=$(${pkgs.coreutils}/bin/cat)" https://envs.sh
'';
"envs.sh shorten" = pkgs.writers.writeDash "envs-shorten" ''
${pkgs.curl}/bin/curl -F "shorten=$(${pkgs.coreutils}/bin/cat)" https://envs.sh
'';
"go.r shorten" = pkgs.writers.writeDash "go.r" ''
"ix.io" = pkgs.writers.writeDash "ix.io" ''
${pkgs.curl}/bin/curl -fSs -F 'f:1=<-' ix.io
'';
"go.r" = pkgs.writers.writeDash "go.r" ''
${pkgs.curl}/bin/curl -fSs http://go.r -F "uri=$(${pkgs.coreutils}/bin/cat)"
'';
"4d2.org paste" = pkgs.writers.writeDash "4d2-paste" ''
${pkgs.curl}/bin/curl -F "file=@-" https://depot.4d2.org/
'';
"0x0.st shorten" = pkgs.writers.writeDash "0x0.st" ''
"0x0.st" = pkgs.writers.writeDash "0x0.st" ''
${pkgs.curl}/bin/curl -fSs https://0x0.st -F "shorten=$(${pkgs.coreutils}/bin/cat)"
'';
"rot13" = pkgs.writers.writeDash "rot13" ''
${pkgs.coreutils}/bin/tr '[A-Za-z]' '[N-ZA-Mn-za-m]'
'';
"ipa" = pkgs.writers.writeDash "ipa" ''
${pkgs.ipa}/bin/ipa
${niveumPackages.ipa}/bin/ipa
'';
"betacode" = pkgs.writers.writeDash "betacode" ''
${pkgs.betacode}/bin/betacode
${niveumPackages.betacode}/bin/betacode
'';
"curl" = pkgs.writers.writeDash "curl" ''
${pkgs.curl}/bin/curl -fSs "$(${pkgs.coreutils}/bin/cat)"
@@ -52,8 +52,14 @@ let
'';
};
};
in
{
new-workspace = pkgs.writers.writeDash "new-workspace" ''
i3-msg workspace $(($(i3-msg -t get_workspaces | tr , '\n' | grep '"num":' | cut -d : -f 2 | sort -rn | head -1) + 1))
'';
move-to-new-workspace = pkgs.writers.writeDash "new-workspace" ''
i3-msg move container to workspace $(($(i3-msg -t get_workspaces | tr , '\n' | grep '"num":' | cut -d : -f 2 | sort -rn | head -1) + 1))
'';
in {
age.secrets = {
github-token-i3status-rust = {
file = ../secrets/github-token-i3status-rust.age;
@@ -67,28 +73,14 @@ in
group = config.users.users.me.group;
mode = "400";
};
miniflux-api-token = {
file = ../secrets/miniflux-api-token.age;
owner = config.users.users.me.name;
group = config.users.users.me.group;
mode = "400";
};
};
environment.systemPackages = [
pkgs.xsecurelock
];
environment.sessionVariables = {
XSECURELOCK_NO_COMPOSITE = "1";
XSECURELOCK_BACKGROUND_COLOR = "navy";
XSECURELOCK_PASSWORD_PROMPT = "time_hex";
};
programs.slock.enable = true;
services.displayManager.defaultSession = "none+i3";
services.xserver = {
displayManager.defaultSession = "none+i3";
windowManager.i3 = {
enable = true;
package = pkgs.i3;
};
};
@@ -107,76 +99,38 @@ in
'';
};
home-manager.users.me =
let
modifier = "Mod4";
infoWorkspace = "";
messageWorkspace = "";
modes.resize = {
"Escape" = ''mode "default"'';
"Return" = ''mode "default"'';
"h" = "resize shrink width 10 px or 5 ppt";
"j" = "resize grow height 10 px or 5 ppt";
"k" = "resize shrink height 10 px or 5 ppt";
"l" = "resize grow width 10 px or 5 ppt";
home-manager.users.me.xsession.windowManager.i3 = let
modifier = "Mod4";
in {
enable = true;
extraConfig = ''
bindsym --release ${modifier}+Shift+w exec /run/wrappers/bin/slock
'';
config = rec {
fonts = {
names = ["Sans"];
size = 10.0;
};
gaps.inner = 4;
floating = {
titlebar = false;
border = 1;
};
bars =
let
position = "bottom";
in
[
(lib.recursiveUpdate config.home-manager.users.me.stylix.targets.i3.exportedBarConfig {
workspaceButtons = true;
mode = "hide"; # "dock";
inherit position;
statusCommand = toString (
pkgs.writers.writeDash "i3status-rust" ''
export I3RS_GITHUB_TOKEN="$(cat ${config.age.secrets.github-token-i3status-rust.path})"
export OPENWEATHERMAP_API_KEY="$(cat ${config.age.secrets.openweathermap-api-key.path})"
exec ${config.home-manager.users.me.programs.i3status-rust.package}/bin/i3status-rs ${config.home-manager.users.me.home.homeDirectory}/.config/i3status-rust/config-${position}.toml
''
);
fonts = {
names = [
"${config.stylix.fonts.sansSerif.name}"
"FontAwesome 6 Free"
];
size = config.stylix.fonts.sizes.desktop * 0.8;
};
})
];
inherit modifier;
window = {
titlebar = false;
border = 2;
border = 1;
hideEdgeBorders = "smart";
commands = [
{
criteria = {
class = "floating";
};
criteria = {class = "floating";};
command = "floating enable";
}
{
criteria = {
class = "fzfmenu";
};
criteria = {class = "fzfmenu";};
command = "floating enable";
}
{
criteria = {
class = ".*";
};
criteria = {class = ".*";};
command = "border pixel 2";
}
{
criteria = {
class = "mpv";
};
criteria = {class = "mpv";};
command = lib.strings.concatStringsSep ", " [
"floating enable"
"sticky enable"
@@ -187,144 +141,196 @@ in
}
];
};
colors =
let
background = config.lib.stylix.colors.withHashtag.base00;
in
floating = {
titlebar = false;
border = 1;
};
colors = let
scheme = {
background = colours.background;
text = colours.foreground;
};
in rec {
focused =
scheme
// {
border = colours.blue.bright;
indicator = colours.blue.bright;
childBorder = colours.blue.bright;
};
unfocused =
scheme
// {
border = colours.background;
indicator = colours.background;
childBorder = colours.background;
};
focusedInactive = unfocused;
urgent =
scheme
// {
border = colours.red.bright;
indicator = colours.red.bright;
childBorder = colours.red.bright;
};
placeholder =
scheme
// {
border = colours.green.bright;
indicator = colours.green.bright;
childBorder = colours.green.bright;
};
};
bars = [
{
unfocused = {
border = lib.mkForce background;
childBorder = lib.mkForce background;
workspaceButtons = false;
fonts = {
names = ["Monospace" "Font Awesome 6 Free"];
size = 8.0;
};
};
keybindings =
lib.listToAttrs (
map (
x: lib.nameValuePair "${modifier}+Shift+${toString x}" "move container to workspace ${toString x}"
) (lib.range 1 9)
)
// lib.listToAttrs (
map (x: lib.nameValuePair "${modifier}+${toString x}" "workspace ${toString x}") (lib.range 1 9)
)
// {
"${modifier}+i" = "workspace ${infoWorkspace}";
"${modifier}+m" = "workspace ${messageWorkspace}";
mode = "dock"; # "hide";
position = "bottom";
colors = rec {
background = colours.background;
separator = background;
statusline = colours.foreground;
bindingMode = {
background = colours.red.bright;
border = colours.background;
text = colours.foreground;
};
};
statusCommand = toString (pkgs.writers.writeDash "i3status-rust" ''
export I3RS_GITHUB_TOKEN="$(cat ${config.age.secrets.github-token-i3status-rust.path})"
export OPENWEATHERMAP_API_KEY="$(cat ${config.age.secrets.openweathermap-api-key.path})"
${pkgs.i3status-rust}/bin/i3status-rs ${
(pkgs.formats.toml {}).generate "i3status-rust.toml" (import ../lib/i3status-rust.nix {
inherit (config.niveum) batteryName wirelessInterface;
inherit (config.home-manager.users.me.accounts.email) accounts;
inherit colours;
inherit pkgs;
})
}'');
}
];
modes.resize = {
"Escape" = ''mode "default"'';
"Return" = ''mode "default"'';
"h" = "resize shrink width 10 px or 5 ppt";
"j" = "resize grow height 10 px or 5 ppt";
"k" = "resize shrink height 10 px or 5 ppt";
"l" = "resize grow width 10 px or 5 ppt";
};
keybindings = {
"${modifier}+Shift+h" = "move left 25 px";
"${modifier}+Shift+j" = "move down 25 px";
"${modifier}+Shift+k" = "move up 25 px";
"${modifier}+Shift+l" = "move right 25 px";
"${modifier}+h" = "focus left";
"${modifier}+j" = "focus down";
"${modifier}+k" = "focus up";
"${modifier}+l" = "focus right";
"${modifier}+Shift+h" = "move left 25 px";
"${modifier}+Shift+j" = "move down 25 px";
"${modifier}+Shift+k" = "move up 25 px";
"${modifier}+Shift+l" = "move right 25 px";
"${modifier}+h" = "focus left";
"${modifier}+j" = "focus down";
"${modifier}+k" = "focus up";
"${modifier}+l" = "focus right";
"${modifier}+Shift+b" = "move window to workspace prev";
"${modifier}+Shift+n" = "move window to workspace next";
"${modifier}+Shift+x" = "exec ${move-to-new-workspace}";
"${modifier}+b" = "workspace prev";
"${modifier}+n" = "workspace next";
"${modifier}+x" = "exec ${new-workspace}";
# "${modifier}+Shift+b" = "move container to workspace prev";
# "${modifier}+Shift+n" = "move container to workspace next";
# "${modifier}+b" = "workspace prev";
# "${modifier}+n" = "workspace next";
"${modifier}+Shift+c" = "reload";
"${modifier}+Shift+q" = "kill";
"${modifier}+Shift+r" = "restart";
"${modifier}+Shift+c" = "reload";
"${modifier}+Shift+q" = "kill";
"${modifier}+Shift+r" = "restart";
"${modifier}+z" = "sticky toggle";
"${modifier}+Shift+z" = "floating toggle";
"${modifier}+z" = "sticky toggle";
"${modifier}+Shift+z" = "floating toggle";
"${modifier}+s" = "scratchpad show";
"${modifier}+Shift+s" = "move scratchpad";
"${modifier}+Shift+s" = "move scratchpad";
"${modifier}+s" = ''[class="^(?i)(?!obsidian).*"] scratchpad show'';
"${modifier}+o" = ''[class="obsidian"] scratchpad show'';
"${modifier}+c" = "split h";
"${modifier}+e" = "layout toggle split";
"${modifier}+f" = "fullscreen toggle";
"${modifier}+r" = "mode resize";
"${modifier}+v" = "split v";
"${modifier}+w" = "layout tabbed";
"${modifier}+q" = "exec ${pkgs.writers.writeDash "newsboat-sync" ''
notify-send --app-name="newsboat" "Updating ..."
newsboat -x reload
notify-send --app-name="newsboat" "Finished updating."
''}";
"${modifier}+c" = "split h";
"${modifier}+e" = "layout toggle split";
"${modifier}+f" = "fullscreen toggle";
"${modifier}+r" = "mode resize";
"${modifier}+v" = "split v";
"${modifier}+w" = "layout tabbed";
"${modifier}+q" = "exec ${config.services.clipmenu.package}/bin/clipmenu";
# "${modifier}+Shift+y" = "exec ${pkgs.qutebrowser}/bin/qutebrowser";
"${modifier}+Return" = "exec ${(defaultApplications pkgs).terminal}";
"${modifier}+t" = "exec ${(defaultApplications pkgs).fileManager}";
"${modifier}+y" = "exec ${(defaultApplications pkgs).browser}";
"${modifier}+0" = "exec ${niveumPackages.menu-calc}/bin/=";
"${modifier}+Return" = "exec ${lib.getExe pkgs.niphas-terminal}";
"${modifier}+t" = "exec ${lib.getExe pkgs.niphas-file-browser}";
"${modifier}+y" = "exec ${lib.getExe pkgs.niphas-web-browser}";
"${modifier}+d" = "exec ${pkgs.writers.writeDash "run" ''exec rofi -modi run,ssh,window -show run''}";
"${modifier}+Shift+d" = "exec ${
pkgs.writers.writeDash "notemenu" ''
set -efu
PATH=$PATH:${
lib.makeBinPath [pkgs.rofi pkgs.findutils pkgs.coreutils]
}
"${modifier}+d" =
"exec ${pkgs.writers.writeDash "run" ''exec rofi -modi run,ssh,window -show run''}";
"${modifier}+Shift+d" = "exec ${lib.getExe pkgs.notemenu}";
"${modifier}+p" = "exec rofi-pass";
"${modifier}+Shift+p" = "exec rofi-pass --insert";
"${modifier}+u" = "exec ${lib.getExe pkgs.unicodmenu}";
"${modifier}+Shift+u" =
"exec ${pkgs.writers.writeDash "last-unicode" ''${pkgs.xdotool}/bin/xdotool type --delay 1000 "$(${pkgs.gawk}/bin/awk 'END{print $1}' ~/.cache/unicodmenu)"''}";
"${modifier}+F7" = "exec ${pkgs.writers.writeDash "showkeys-toggle" ''
if ${pkgs.procps}/bin/pgrep screenkey; then
exec ${pkgs.procps}/bin/pkill screenkey
else
exec ${pkgs.screenkey}/bin/screenkey
cd ~/notes
note_file=$({
echo diary/$(date -I).md
echo diary/$(date -I -d yesterday).md
find . ! -name '.*' -type f -printf "%T@ %p\n" | sort --reverse --numeric-sort | cut --delimiter=" " --fields=2-
} | rofi -dmenu -i -p 'notes')
if test "$note_file"
then
alacritty --working-directory ~/notes -e "$EDITOR" "$note_file"
fi
''}";
"${modifier}+F12" = "exec ${klem}/bin/klem";
"XF86AudioLowerVolume" = "exec ${lib.getExe pkgs.pamixer} -d 5";
"XF86AudioMute" = "exec ${lib.getExe pkgs.pamixer} -t";
"XF86AudioRaiseVolume" = "exec ${pkgs.pamixer}/bin/pamixer -i 5";
"XF86Calculator" = "exec ${lib.getExe pkgs.st} -c floating -e ${pkgs.bc}/bin/bc";
"XF86AudioPause" = "exec ${lib.getExe pkgs.playerctl} play-pause";
"XF86AudioPlay" = "exec ${lib.getExe pkgs.playerctl} play-pause";
"XF86AudioNext" = "exec ${lib.getExe pkgs.playerctl} next";
"XF86AudioPrev" = "exec ${lib.getExe pkgs.playerctl} previous";
"XF86AudioStop" = "exec ${lib.getExe pkgs.playerctl} stop";
''
}";
"${modifier}+p" = "exec rofi-pass";
"${modifier}+Shift+p" = "exec rofi-pass --insert";
"${modifier}+u" = "exec ${niveumPackages.unicodmenu}/bin/unicodmenu";
# key names detected with xorg.xev:
# XF86WakeUp (fn twice)
# XF86Battery (fn f3)
# XF86Sleep (fn f4) - actually suspends
# XF86WLAN
# XF86WebCam (fn f6)
# XF86TouchpadToggle (fn f8)
# XF86Suspend (fn f12) - actually suspends to disk
# Num_Lock (fn Roll) - numlocks
# XF86Audio{Prev,Next,Mute,Play,Stop}
# XF86Forward
# XF86Back
# XF86Launch1 (thinkvantage)
};
in
{
stylix.targets.i3.enable = true;
"${modifier}+F6" = "exec ${pkgs.xorg.xkill}/bin/xkill";
"${modifier}+F7" = "exec ${pkgs.writers.writeDash "showkeys-toggle" ''
if ${pkgs.procps}/bin/pgrep screenkey; then
exec ${pkgs.procps}/bin/pkill screenkey
else
exec ${pkgs.screenkey}/bin/screenkey
fi
''}";
"${modifier}+F8" = "exec switch-theme toggle";
"${modifier}+F9" = "exec ${pkgs.redshift}/bin/redshift -O 4000 -b 0.85";
"${modifier}+F10" = "exec ${pkgs.redshift}/bin/redshift -x";
"${modifier}+F11" = "exec ${pkgs.xcalib}/bin/xcalib -invert -alter";
"${modifier}+F12" = "exec ${klem}/bin/klem";
"Print" = "exec flameshot gui";
"XF86AudioLowerVolume" = "exec ${pkgs.pamixer}/bin/pamixer -d 5";
"XF86AudioMute" = "exec ${pkgs.pamixer}/bin/pamixer -t";
"XF86AudioRaiseVolume" = "exec ${pkgs.pamixer}/bin/pamixer -i 5";
"XF86Calculator" = "exec ${pkgs.st}/bin/st -c floating -e ${pkgs.bc}/bin/bc";
"XF86AudioPause" = "exec ${pkgs.playerctl}/bin/playerctl pause";
"XF86AudioPlay" = "exec ${pkgs.playerctl}/bin/playerctl play-pause";
"XF86AudioNext" = "exec ${pkgs.playerctl}/bin/playerctl next";
"XF86AudioPrev" = "exec ${pkgs.playerctl}/bin/playerctl previous";
"XF86AudioStop" = "exec ${pkgs.playerctl}/bin/playerctl stop";
"XF86ScreenSaver" = "exec ${niveumPackages.k-lock}/bin/k-lock";
xsession.windowManager.i3 = {
enable = true;
extraConfig = ''
bindsym --release ${modifier}+Shift+w exec xsecurelock
"XF86Display" = "exec ${niveumPackages.dmenu-randr}/bin/dmenu-randr";
exec "${lib.getExe pkgs.obsidian}"
for_window [class="obsidian"] , move scratchpad
assign [class="message"] ${messageWorkspace}
exec "${pkgs.writers.writeDash "irc" "exec ${lib.getExe pkgs.alacritty} --class message -e ssh weechat@makanek -t tmux attach-session -t IM"}"
exec "${pkgs.writers.writeDash "email" "exec ${lib.getExe pkgs.alacritty} --class message -e aerc"}"
exec --no-startup-id ${pkgs.xss-lock}/bin/xss-lock -- xsecurelock
'';
config = {
inherit
modifier
gaps
modes
bars
floating
window
colors
;
keybindings = keybindings // {
"${modifier}+F9" = "exec ${pkgs.redshift}/bin/redshift -O 4000 -b 0.85";
"${modifier}+F10" = "exec ${pkgs.redshift}/bin/redshift -x";
"Print" = "exec flameshot gui";
# "${modifier}+Shift+x" = "exec ${move-to-new-workspace}";
# "${modifier}+x" = "exec ${new-workspace}";
"XF86Display" = "exec ${lib.getExe pkgs.dmenu-randr}";
};
};
# key names detected with xorg.xev:
# XF86WakeUp (fn twice)
# XF86Battery (fn f3)
# XF86Sleep (fn f4) - actually suspends
# XF86WLAN
# XF86WebCam (fn f6)
# XF86TouchpadToggle (fn f8)
# XF86Suspend (fn f12) - actually suspends to disk
# Num_Lock (fn Roll) - numlocks
# XF86Audio{Prev,Next,Mute,Play,Stop}
# XF86Forward
# XF86Back
# XF86Launch1 (thinkvantage)
};
};
};
}

75
configs/keyboard.nix Normal file
View File

@@ -0,0 +1,75 @@
{
pkgs,
lib,
...
}: let
commaSep = builtins.concatStringsSep ",";
xkbOptions = ["compose:caps" "terminate:ctrl_alt_bksp" "grp:ctrls_toggle"];
languages = {
de = "T3";
gr = "polytonic";
ru = "phonetic";
ara = "buckwalter";
cop = "";
ave = "";
"in" = "san-kagapa";
il = "phonetic";
};
defaultLanguage = "de";
in {
# man 7 xkeyboard-config
services.xserver = {
layout = "de";
# T3: https://upload.wikimedia.org/wikipedia/commons/a/a9/German-Keyboard-Layout-T3-Version1-large.png
# buckwalter: http://www.qamus.org/transliteration.htm
xkbVariant = "T3";
xkbOptions = commaSep xkbOptions;
libinput.enable = true;
xkbDir = pkgs.symlinkJoin {
name = "x-keyboard-directory";
paths = [
"${pkgs.xkeyboard_config}/etc/X11/xkb"
(pkgs.linkFarm "custom-x-keyboards" [
{
name = "symbols/cop";
path = pkgs.fetchurl {
url = "http://www.moheb.de/download/cop";
sha256 = "1l0h6aq536hyinrh0i0ia355y229bjrlibii0sya5bmqh46vycia";
};
}
{
name = "symbols/ave";
path = pkgs.fetchurl {
url = "https://blog.simos.info/wp-content/uploads/2010/06/avestan.txt";
sha256 = "192zmmm3gxyhim39dsax7r87gsay2w5v2xkhwmvsfipjb60hwp5g";
};
}
])
];
};
};
console.keyMap = "de";
environment.systemPackages =
lib.mapAttrsToList
(language: variant:
pkgs.writers.writeDashBin "kb-${language}" ''
${pkgs.xorg.setxkbmap}/bin/setxkbmap ${defaultLanguage},${language} ${languages.${defaultLanguage}},${variant} ${toString (map (option: "-option ${option}") xkbOptions)}
'')
languages;
# improve held key rate
services.xserver.displayManager.sessionCommands = "${pkgs.xorg.xset}/bin/xset r rate 300 50";
systemd.user.services.gxkb = {
wantedBy = ["graphical-session.target"];
serviceConfig = {
SyslogIdentifier = "gxkb";
ExecStart = "${pkgs.gxkb}/bin/gxkb";
Restart = "always";
RestartSec = "15s";
StartLimitBurst = 0;
};
};
}

View File

@@ -1,34 +0,0 @@
# Import default rules from the system Compose file
include "%L"
# Custom definitions
<Multi_key> <U0634> <U0634> : "ژ" U0698 # ز + ز = ژ
<Multi_key> <U063A> <U063A> : "گ" U06AF # غ + غ = گ
<Multi_key> <U0641> <U0641> : "ڤ" U06A4 # ف + ف = ڤ
<Multi_key> <U062C> <U062C> : "چ" U0686 # ج + ج = چ
<Multi_key> <U0628> <U0628> : "پ" U067E # ب + ب = پ
<Multi_key> <U0643> <U0643> : "ک" U06A9 # ك + ك = ک
<Multi_key> <U064A> <U064A> : "ی" U06CC # ي + ي = ی
<Multi_key> <U0647> <U064A> : "ۀ" U06C0 # ه + ي = ۀ
<Multi_key> <E> <E> : "ɛ" U025B
<Multi_key> <O> <O> : "ɔ" U0254
<Multi_key> <s> <h> : "ʃ" U0283
<Multi_key> <g> <h> : "ɣ" U0283
<Multi_key> <b> <h> : "β" U0283
<Multi_key> <p> <h> : "ɸ" U0283
<Multi_key> <z> <h> : "ʒ" U0292
<Multi_key> <e> <i> : "ɪ" U026A
<Multi_key> <e> <u> : "ʊ" U028A
<Multi_key> <colon> <colon> : "ː" U02D0
<Multi_key> <question> <period> : "ʔ" U0294
<Multi_key> <period> <question> : "ʕ" U0295
<Multi_key> <apostrophe> <period> : "ˈ" U02C8
<Multi_key> <period> <apostrophe> : "ˌ" U02CC
<dead_belowring> <nobreakspace> : "̥" U0325 # COMBINING RING BELOW
<dead_belowbreve> <nobreakspace> : "̮" U032E # COMBINING BREVE BELOW
<dead_invertedbreve> <nobreakspace> : "̑" U0311 # COMBINING INVERTED BREVE
<dead_belowmacron> <nobreakspace> : "̱" U0331 # COMBINING MACRON BELOW
<dead_belowcircumflex> <nobreakspace> : "̯" U032F # COMBINING INVERTED BREVE BELOW
<dead_circumflex> <Multi_key> <underscore> <e> : "ᵊ" U1D4A
# TODO zwnj

View File

@@ -1,60 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Generated keyboard layout file with the Keyboard Layout Editor.
// For more about the software, see http://code.google.com/p/keyboardlayouteditor
//
// Version 0.2, changed AD09.
partial default alphanumeric_keys
xkb_symbols "avestan"
{
name[Group1] = "Iran - Avestan";
key <AB01> { [ U10B30, U10B32 ] }; // 𐬰 𐬲
key <AB02> { [ U10B11, U10B12 ] }; // 𐬑 𐬒
key <AB03> { [ U10B17, UE102 ] }; // 𐬗 
key <AB04> { [ U10B2C, U10B13 ] }; // 𐬬 𐬓
key <AB05> { [ U10B20, U10B21 ] }; // 𐬠𐬡
key <AB06> { [ U10B25, U10B27 ] }; // 𐬥 𐬧
key <AB07> { [ U10B28, U10B29 ] }; // 𐬨 𐬩
key <AB08> { [ U10B3C, U10B39 ] }; // 𐬼 𐬹
key <AB09> { [ U10B3E, U10B3D ] }; // 𐬾 𐬽
key <AB10> { [ U10B3F, periodcentered ] }; // 𐬿 ·
key <AC01> { [ U10B00, U10B01 ] }; // 𐬀 𐬁
key <AC02> { [ U10B2F, U10B31 ] }; // 𐬯 𐬱
key <AC03> { [ U10B1B, U10B1C ] }; // 𐬛 𐬜
key <AC04> { [ U10B1F, U10B16 ] }; // 𐬟 𐬖
key <AC05> { [ U10B14, U10B15 ] }; // 𐬔 𐬕
key <AC06> { [ U10B35, UE100 ] }; // 𐬵 
key <AC07> { [ U10B18, U10B24 ] }; // 𐬘 𐬤
key <AC08> { [ U10B10, UE101 ] }; // 𐬐 
key <AC09> { [ U10B2E, UE103 ] }; // 𐬮 
key <AC10> { [ U10B3B, U10B3A ] }; // 𐬻 𐬺
key <AC11> { [ U10B1D ] }; // 𐬝
key <AD01> { [ U10B22, U10B23 ] }; // 𐬢 𐬣
key <AD02> { [ U10B33, U10B34 ] }; // 𐬳 𐬴
key <AD03> { [ U10B08, U10B09 ] }; // 𐬈 𐬉
key <AD04> { [ U10B2D, U10B26 ] }; // 𐬭 𐬦
key <AD05> { [ U10B19, U10B1A ] }; // 𐬙 𐬚
key <AD06> { [ U10B2B, U10B2A ] }; // 𐬫 𐬪
key <AD07> { [ U10B0E, U10B0F ] }; // 𐬎 𐬏
key <AD08> { [ U10B0C, U10B0D ] }; // 𐬌 𐬍
key <AD09> { [ U10B0A, U10B0B ] }; // 𐬊 𐬋
key <AD10> { [ U10B1E ] }; // 𐬞
key <AD11> { [ U10B06, U10B07 ] }; // 𐬆 𐬇
key <AD12> { [ U10B02, U10B03 ] }; // 𐬂 𐬃
key <AE01> { [ U10B78 ] }; // 𐭸
key <AE02> { [ U10B79 ] }; // 𐭹
key <AE03> { [ U10B7A ] }; // 𐭺
key <AE04> { [ U10B7B ] }; // 𐭻
key <AE05> { [ U10B7C ] }; // 𐭼
key <AE06> { [ U10B7D ] }; // 𐭽
key <AE07> { [ U10B7E ] }; // 𐭾
key <AE08> { [ U10B7F ] }; // 𐭿
key <BKSL> { [ U10B04, U10B05 ] }; // 𐬄 𐬅
key <LSGT> { [ U10B04, U10B05 ] }; // 𐬄 𐬅
};

View File

@@ -1,79 +0,0 @@
// Coptic keyboard symbols for XKB and PC keyboard
// based on the mapping of logos
// (C) 2006 Moheb Mekhaiel <mohebm@gmx.de>
//
// Permission is granted to anyone to use, distribute and modify
// this file in any way, provided that the above copyright notice
// is left intact and the author of the modification summarizes
// the changes in this header.
//
// This file is distributed without any expressed or implied warranty.
partial default alphanumeric_keys
xkb_symbols "basic" {
name[Group1]= "Coptic";
key <TLDE> { [ U0308, U0311, U0361, U2CE5 ] };
key <AE01> { type[Group1] = "FOUR_LEVEL",
[ 1, U0304, VoidSymbol, U2CE6 ] };
key <AE02> { [ 2, U0306, U2CFD, U2CE7 ] };
key <AE03> { [ 3, U0374, U2056, U2CE8 ] };
key <AE04> { [ 4, U0375, U2058, U2CE9 ] };
key <AE05> { [ 5, U0307, U2059, U2CEA ] };
key <AE06> { [ 6, U0323, U2C8B, U2C8A ] };
key <AE07> { [ 7, U2CE4 ] };
key <AE08> { [ 8, U002A, U2026 ] };
key <AE09> { [ 9, parenleft, U201C, plusminus ] };
key <AE10> { [ 0, parenright, U201D, degree ] };
key <AE11> { [ U00B7, underscore, U2013, U2014 ] };
key <AE12> { [ U2E17, U0305, U033F ] };
key <BKSL> { [ U0300, U007C, backslash, U007C ] };
key <AD01> { [ U2C91, U2C90 ] };
key <AD02> { [ U2CB1, U2CB0 ] };
key <AD03> { [ U2C89, U2C88 ] };
key <AD04> { [ U2CA3, U2CA2 ] };
key <AD05> { [ U2CA7, U2CA6, U03EF, U03EE ] };
key <AD06> { [ U2CAF, U2CAE ] };
key <AD07> { [ U2CA9, U2CA8 ] };
key <AD08> { [ U2C93, U2C92 ] };
key <AD09> { [ U2C9F, U2C9E ] };
key <AD10> { [ U2CA1, U2CA0 ] };
key <AD11> { [ bracketleft,braceleft, U2018 ] };
key <AD12> { [ bracketright,braceright,U2019 ] };
key <AC01> { [ U2C81, U2C80 ] };
key <AC02> { [ U2CA5, U2CA4, U03E3, U03E2 ] };
key <AC03> { [ U2C87, U2C86, U03EF, U03EE ] };
key <AC04> { [ U2CAB, U2CAA, U03E5, U03E4 ] };
key <AC05> { [ U2C85, U2C84, U03EB, U03EA ] };
key <AC06> { [ U2C8F, U2C8E, U03E9, U03E8 ] };
key <AC07> { [ U03EB, U03EA, U03EB, U03EA ] };
key <AC08> { [ U2C95, U2C94, U03E7, U03E6 ] };
key <AC09> { [ U2C97, U2C96 ] };
key <AC10> { [ semicolon, colon, U2053, dead_doubleacute ] };
key <AC11> { [ apostrophe, U2CFF, U0022 ] };
key <AB01> { [ U2C8D, U2C8C ] };
key <AB02> { [ U2C9D, U2C9C ] };
key <AB03> { [ U2CAD, U2CAC, U03ED, U03EC ] };
key <AB04> { [ U03E3, U03E2, U03E3, U03E2 ] };
key <AB05> { [ U2C83, U2C82 ] };
key <AB06> { [ U2C9B, U2C9A ] };
key <AB07> { [ U2C99, U2C98 ] };
key <AB08> { [ comma, less, U00AB, U2039 ] };
key <AB09> { [ period, greater, U00BB, U203A ] };
key <AB10> { [ U0301, U2CFE, slash, question ] };
key <RALT> { type[Group1]="TWO_LEVEL",
[ ISO_Level3_Shift, Multi_key ] };
modifier_map Mod5 { <RALT> };
//include "level3(ralt_switch_multikey)"
// End alphanumeric section
};

View File

@@ -1,143 +0,0 @@
{
config,
pkgs,
lib,
...
}:
let
commaSep = builtins.concatStringsSep ",";
xkbOptions = [
"compose:caps"
"terminate:ctrl_alt_bksp"
"grp:ctrls_toggle"
];
languages = {
deutsch = {
code = "de";
variant = "T3";
};
greek = {
code = "gr";
variant = "polytonic";
};
russian = {
code = "ru";
variant = "phonetic";
};
arabic = {
code = "ara";
variant = "buckwalter";
};
coptic = ./coptic;
avestan = ./avestan;
gothic = ./gothic;
farsi = {
code = "ir";
variant = "qwerty";
};
syriac = {
code = "sy";
variant = "syc_phonetic";
};
sanskrit = {
code = "in";
variant = "san-kagapa";
};
gujarati = {
code = "in";
variant = "guj-kagapa";
};
urdu = {
code = "in";
variant = "urd-phonetic";
};
hebrew = {
code = "il";
variant = "phonetic";
};
};
defaultLanguage = languages.deutsch;
in
{
services.libinput.enable = true;
# man 7 xkeyboard-config
services.xserver = {
exportConfiguration = lib.mkForce true; # link /usr/share/X11 properly
xkb.layout = defaultLanguage.code;
# T3: https://upload.wikimedia.org/wikipedia/commons/a/a9/German-Keyboard-Layout-T3-Version1-large.png
# buckwalter: http://www.qamus.org/transliteration.htm
xkb.variant = defaultLanguage.variant;
xkb.options = commaSep xkbOptions;
xkb.extraLayouts = {
coptic = {
languages = [ "cop" ];
description = "Coptic is the latest stage of the Egyptian language and was used by Egyptian Christians. The Coptic script is based on the Greek alphabet with some letters borrowed from Demotic Egyptian.";
symbolsFile = ./coptic;
};
avestan = {
languages = [ "ave" ];
description = "Avestan is an ancient Iranian language known primarily from its use in the sacred texts of Zoroastrianism, the Avesta. It is an Indo-Iranian language that was spoken in ancient Persia.";
symbolsFile = ./avestan;
};
gothic = {
languages = [ "got" ];
description = "Gothic is an extinct East Germanic language that was spoken by the Goths. It is known primarily from the Codex Argenteus, a 6th-century manuscript containing a translation of the Bible into Gothic.";
symbolsFile = ./gothic;
};
farsi = {
languages = [ "fas" ];
description = "Farsi, also known as Persian, is an Indo-Iranian language spoken primarily in Iran, Afghanistan (where it is known as Dari), and Tajikistan (where it is called Tajik). It has a rich literary tradition and is written in a modified Arabic script.";
symbolsFile = ./farsi;
};
};
};
environment.etc."x11-locale".source = toString pkgs.xorg.libX11 + "share/X11/locale";
home-manager.users.me = {
home.file = {
".XCompose".source = ./XCompose;
};
};
console.keyMap = "de";
environment.systemPackages = lib.mapAttrsToList (
language: settings:
let
code = if settings ? "code" then settings.code else language;
variant = if settings ? "variant" then settings.variant else "";
in
pkgs.writers.writeDashBin "kb-${language}" ''
if [ -n "$SWAYSOCK" ]; then
swaymsg -s $SWAYSOCK 'input * xkb_layout "${defaultLanguage.code},${code}"'
swaymsg -s $SWAYSOCK 'input * xkb_variant "${defaultLanguage.variant},${variant}"'
swaymsg -s $SWAYSOCK 'input * xkb_options "${lib.concatStringsSep "," xkbOptions}"'
elif [ -n "$HYPRLAND_INSTANCE_SIGNATURE" ]; then
hyprctl keyword input:kb_variant "" # otherwise we end up with an invalid combination for a short while
hyprctl keyword input:kb_layout "${defaultLanguage.code},${code}"
hyprctl keyword input:kb_variant "${defaultLanguage.variant},${variant}"
elif [ -n "$DISPLAY" ]; then
${pkgs.xorg.setxkbmap}/bin/setxkbmap ${defaultLanguage.code},${code} ${defaultLanguage.variant},${variant} ${
toString (map (option: "-option ${option}") xkbOptions)
}
fi
''
) (languages // config.services.xserver.xkb.extraLayouts);
# improve held key rate
services.xserver.displayManager.sessionCommands = "${pkgs.xorg.xset}/bin/xset r rate 300 50";
systemd.user.services.gxkb = {
wantedBy = [ "graphical-session.target" ];
serviceConfig = {
SyslogIdentifier = "gxkb";
ExecStart = "${pkgs.gxkb}/bin/gxkb";
Restart = "always";
RestartSec = "15s";
StartLimitBurst = 0;
};
};
}

View File

@@ -1,114 +0,0 @@
// https://github.com/gpuminingir/Farsi-Phonetic-Keyboard-Linux
// by @gpuminingir
partial alphanumeric_keys
xkb_symbols "qwerty" {
// Classic Finnish keyboard layout without dead keys and {[]} on asdf + AltG
name[Group1]="Persian (QWERTY)";
include "ir(pesq_part_basic)"
include "ir(pesq_part_ext)"
include "ir(pesq_part_keypad)"
include "nbsp(zwnj2nb3nnb4)"
include "level3(ralt_switch)"
};
hidden partial alphanumeric_keys
xkb_symbols "pesq_part_basic" {
// Persian digits
key <AE01> { [ Arabic_1, exclam, exclam ] }; // ١ ! !
key <AE02> { [ Arabic_2, at, at ] }; // ٢ @ @
key <AE03> { [ Arabic_3, numbersign, numbersign ] }; // ٣ # #
key <AE04> { [ Farsi_4, dollar, dollar ] }; // ۴ $ $
key <AE05> { [ Farsi_5, percent, percent ] }; // ۵ % %
key <AE06> { [ Farsi_6, asciicircum, asciicircum ] }; // ۶ ^ ^
key <AE07> { [ Arabic_7, ampersand, ampersand ] }; // ٧ & &
key <AE08> { [ Arabic_8, KP_Multiply, KP_Multiply ] }; // ٨ * *
key <AE09> { [ Arabic_9, Armenian_parenright, Armenian_parenright, Armenian_parenleft ] }; // ٩ ) ) (
key <AE10> { [ Farsi_0, Armenian_parenleft, Armenian_parenleft ] }; // ۰ ( (
key <AE11> { [ underbar, KP_Subtract, KP_Subtract ] }; // _
key <AE12> { [ KP_Equal, KP_Add, KP_Add ] }; // = + +
// Persian letters and symbols
key <AD01> { [ Arabic_qaf, Arabic_ghain ] }; // ق غ
key <AD02> { [ Arabic_sheen ] }; // ش
key <AD03> { [ Arabic_ain ] }; // ع
key <AD04> { [ Arabic_ra ] }; // ر
key <AD05> { [ Arabic_teh, Arabic_tah ] }; // ت ط
key <AD06> { [ Farsi_yeh ] }; // ى
key <AD07> { [ Arabic_waw ] }; // و
key <AD08> { [ Farsi_yeh ] }; // ى
key <AD09> { [ Arabic_waw ] }; // و
key <AD10> { [ Arabic_peh ] }; // پ
key <AD11> { [ bracketright, braceleft ] }; // ] } {
key <AD12> { [ bracketleft, braceright ] }; // [ { }
key <AC01> { [ Arabic_alef, Arabic_maddaonalef, Arabic_maddaonalef ] }; // ا آ آ
key <AC02> { [ Arabic_seen, Arabic_sad, Arabic_sheen, Arabic_sheen ] }; // س ص ش
key <AC03> { [ Arabic_dal, Arabic_thal ] }; // د ذ ذ
key <AC04> { [ Arabic_feh ] }; // ف
key <AC05> { [ Arabic_gaf, Arabic_ghain ] }; // گ
key <AC06> { [ Arabic_heh, Arabic_hah ] }; // ە ح ه
key <AC07> { [ Arabic_jeem, Arabic_jeh ] }; // ج ژ ژ
key <AC08> { [ Arabic_keheh ] }; // ک
key <AC09> { [ Arabic_lam ] }; // ل
key <AC10> { [ Arabic_semicolon, colon ] }; // ؛ : ։
key <AC11> { [ Arabic_comma, quotedbl, quotedbl ] }; // ، ” ”
key <AB01> { [ Arabic_zain, Arabic_dad, Arabic_zah, Arabic_zah ] }; // ض ض ز خ
key <AB02> { [ Arabic_khah, Arabic_zah ] }; // ظ خ
key <AB03> { [ Arabic_theh, Arabic_tcheh ] }; // چ ث
key <AB04> { [ Arabic_hamza, Arabic_waw ] }; // و
key <AB05> { [ Arabic_beh ] }; // ب
key <AB06> { [ Arabic_noon ] }; // ن
key <AB07> { [ Arabic_meem ] }; // م
key <AB08> { [ Arabic_comma, rightcaret, leftcaret ] }; // , > <
key <AB09> { [ period, leftcaret, rightcaret ] }; // . < >
key <AB10> { [ slash, Arabic_question_mark, question ] }; // / ?
key <AE11> { [ minus, underscore ] };
key <AE12> { [ equal, plus, 0x1002212 ] };
key <BKSL> { [ backslash, bar, 0x1002010 ] };
key <TLDE> { [ U02DC, UFDFC, UFDF2 ] }; // ˜ ﷼ ﷲ
};
hidden partial alphanumeric_keys
xkb_symbols "pesq_part_ext" {
// Persian and ASCII digits
key <AE01> { [ Farsi_1, exclam, grave, 1 ] };
key <AE02> { [ Farsi_2, 0x100066c, at, 2 ] };
key <AE03> { [ Farsi_3, 0x100066b, numbersign, 3 ] };
key <AE04> { [ Farsi_4, 0x100fdfc, dollar, 4 ] };
key <AE05> { [ Farsi_5, 0x100066a, percent, 5 ] };
key <AE06> { [ Farsi_6, multiply, asciicircum, 6 ] };
key <AE07> { [ Farsi_7, Arabic_comma, ampersand, 7 ] };
key <AE08> { [ Farsi_8, asterisk, enfilledcircbullet, 8 ] };
key <AE09> { [ Farsi_9, parenright, 0x100200e, 9 ] };
key <AE10> { [ Farsi_0, parenleft, 0x100200f, 0 ] };
};
hidden partial alphanumeric_keys
xkb_symbols "pesq_part_keypad" {
// Persian digits and Mathematical operators
key <KPDV> { [ division, XF86_Ungrab ] };
key <KPMU> { [ multiply, XF86_ClearGrab ] };
key <KPSU> { [ 0x1002212, XF86_Prev_VMode ] };
key <KPAD> { [ plus, XF86_Next_VMode ] };
key <KPEN> { [ KP_Enter ] };
key <KPEQ> { [ equal ] };
key <KP7> { [ KP_Home, Farsi_7 ] };
key <KP8> { [ KP_Up, Farsi_8 ] };
key <KP9> { [ KP_Prior, Farsi_9 ] };
key <KP4> { [ KP_Left, Farsi_4 ] };
key <KP5> { [ KP_Begin, Farsi_5 ] };
key <KP6> { [ KP_Right, Farsi_6 ] };
key <KP1> { [ KP_End, Farsi_1 ] };
key <KP2> { [ KP_Down, Farsi_2 ] };
key <KP3> { [ KP_Next, Farsi_3 ] };
key <KP0> { [ KP_Insert, Farsi_0 ] };
key <KPDL> { [ KP_Delete, 0x100066b ] };
};

View File

@@ -1,69 +0,0 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Generated keyboard layout file with the Keyboard Layout Editor.
// For more about the software, see http://code.google.com/p/keyboardlayouteditor
//
// Version 0.2, changed AD09.
partial default alphanumeric_keys
xkb_symbols "Gothic"
{
name[Group1] = "Gothic";
key <AB01> { [ U10336, U10336 ] }; // Z: 𐌶
key <AB02> { [ U10347, U10347 ] }; // X: 𐍇
key <AB03> { [ U10343, U10343 ] }; // C: 𐍃
key <AB04> { [ U10338, U10338 ] }; // V: 𐌸
key <AB05> { [ U10331, U10331 ] }; // B: 𐌱
key <AB06> { [ U1033D, U10341 ] }; // n: 𐌽 N: 𐍁
key <AB07> { [ U1033C, U1033C ] }; // M: 𐌼
key <AB08> { [ U10B3C, U10B39 ] };
key <AB09> { [ U10349, U10349 ] };
key <AB10> { [ U10B3F, periodcentered ] };
key <AC01> { [ U10330, U10330 ] }; // A: 𐌰
key <AC02> { [ U10343, U10343 ] }; // S: 𐍃
key <AC03> { [ U10333, U10338 ] }; // d: 𐌳 D: 𐌸
key <AC04> { [ U10346, U10346 ] }; // F: 𐍆
key <AC05> { [ U10332, U10332 ] }; // G: 𐌲
key <AC06> { [ U10337, U10337 ] }; // H: 𐌷
key <AC07> { [ U1033E, U1033E ] }; // J: 𐌾
key <AC08> { [ U1033A, U1033A ] }; // K: 𐌺
key <AC09> { [ U1033B, U1033B ] }; // L: 𐌻
key <AC10> { [ semicolon, colon ] };
key <AC11> { [ apostrophe, quotedbl ] };
key <AD01> { [ U10335, U10335 ] }; // Q: 𐌵
key <AD02> { [ U10345, U10345 ] }; // W: 𐍅
key <AD03> { [ U10334, U10334 ] }; // E: 𐌴
key <AD04> { [ U10342, U10342 ] }; // R: 𐍂
key <AD05> { [ U10344, U10338 ] }; // t: 𐍄 T: 𐌸
key <AD06> { [ U10348, U1034A ] }; // y: 𐍈 Y: 𐍊
key <AD07> { [ U1033F, U1033F ] }; // U: 𐌿
key <AD08> { [ U10339, U10339 ] }; // I: 𐌹
key <AD09> { [ U10349, U10349 ] }; // O: 𐍉
key <AD10> { [ U10340, U10340 ] }; // P: 𐍀
key <AD11> { [ bracketleft, braceleft ] };
key <AD12> { [ bracketright, braceright ] };
key <TLDE> { [ grave, asciitilde ] };
key <AE01> { [ 1, exclam ] };
key <AE02> { [ 2, at ] };
key <AE03> { [ 3, numbersign ] };
key <AE04> { [ 4, dollar ] };
key <AE05> { [ 5, percent ] };
key <AE06> { [ 6, asciicircum ] };
key <AE07> { [ 7, ampersand ] };
key <AE08> { [ 8, asterisk ] };
key <AE09> { [ 9, parenleft ] };
key <AE10> { [ 0, parenright ] };
key <AE11> { [ minus, underscore ] };
key <AE12> { [ equal, plus ] };
key <AB08> { [ comma, less ] };
key <AB09> { [ period, greater ] };
key <AB10> { [ slash, question ] };
key <BKSL> { [ U10B04, U10B05 ] };
key <LSGT> { [ U10B04, U10B05 ] };
};

View File

@@ -3,16 +3,19 @@
pkgs,
lib,
...
}:
let
}: let
davHome = "~/.local/share/dav";
kmeinCloud = {
davEndpoint = "https://cloud.kmein.de/remote.php/dav";
davEndpoint = "https://cloud.xn--kiern-0qa.de/remote.php/dav";
username = "kieran";
passwordFile = config.age.secrets.nextcloud-password-kieran.path;
};
in
{
fysiCloud = {
davEndpoint = "https://nextcloud.fysi.dev/remote.php/dav";
username = "kmein";
passwordFile = config.age.secrets.nextcloud-password-fysi.path;
};
in {
age.secrets = {
nextcloud-password-kieran = {
file = ../secrets/nextcloud-password-kieran.age;
@@ -20,6 +23,12 @@ in
group = config.users.users.me.group;
mode = "400";
};
nextcloud-password-fysi = {
file = ../secrets/nextcloud-password-fysi.age;
owner = config.users.users.me.name;
group = config.users.users.me.group;
mode = "400";
};
};
environment.systemPackages = [
@@ -41,11 +50,12 @@ in
systemd.user.services.vdirsyncer = {
enable = true;
wants = [ "network-online.target" ];
wantedBy = [ "default.target" ];
wants = ["network-online.target"];
wantedBy = ["default.target"];
startAt = "*:00/10";
script = ''
${pkgs.vdirsyncer}/bin/vdirsyncer sync && ${pkgs.khal}/bin/khal printcalendars # https://lostpackets.de/khal/configure.html#syncing
${pkgs.vdirsyncer}/bin/vdirsyncer sync
${pkgs.khal}/bin/khal printcalendars # https://lostpackets.de/khal/configure.html#syncing
'';
serviceConfig = {
Type = "oneshot";
@@ -94,9 +104,30 @@ in
"khal/config".text = ''
[calendars]
[[kalender_local]]
path = ${davHome}/calendar/*
type = discover
[[alew]]
path = ${davHome}/calendar/alew
color = "light gray"
[[personal]]
path = ${davHome}/calendar/personal
color = "light cyan"
[[uni]]
path = ${davHome}/calendar/uni-1
color = "yellow"
[[fysi]]
path = ${davHome}/calendar/fysi-1
color = "light magenta"
[[fysi_team]]
path = ${davHome}/calendar/personal_shared_by_fdf
color = "light red"
[[birthdays]]
path = ${davHome}/contacts/contacts
type = birthdays
color = "light green"
[default]
highlight_event_days = True
@@ -128,7 +159,13 @@ in
[pair kalender]
a = "kalender_local"
b = "kalender_cloud"
collections = ["from b"]
collections = ["personal", "alew", "uni-1"]
conflict_resolution = "b wins"
[pair fysi]
a = "kalender_local"
b = "fysi_cloud"
collections = ["fysi-1", "personal_shared_by_fdf"]
conflict_resolution = "b wins"
[storage kontakte_local]
@@ -152,6 +189,12 @@ in
url = "${kmeinCloud.davEndpoint}/calendars/${kmeinCloud.username}/"
username = "${kmeinCloud.username}"
password.fetch = ["command", "cat", "${kmeinCloud.passwordFile}"]
[storage fysi_cloud]
type = "caldav"
url = "${fysiCloud.davEndpoint}/calendars/${fysiCloud.username}/"
username = "${fysiCloud.username}"
password.fetch = ["command", "cat", "${fysiCloud.passwordFile}"]
'';
};
};

View File

@@ -2,15 +2,14 @@
lib,
pkgs,
...
}:
{
}: {
systemd.services.lb-subscription = {
enable = true;
wants = [ "network-online.target" ];
wants = ["network-online.target"];
startAt = "weekly";
serviceConfig = {
user = "kfm";
WorkingDirectory = "/home/kfm/cloud/nextcloud/Books/Germanistik/LB";
WorkingDirectory = "/home/kfm/cloud/Seafile/Books/Germanistik/LB";
};
script = ''
first_year=2019

View File

@@ -1,11 +0,0 @@
{
pkgs,
lib,
...
}:
{
nix = {
package = lib.mkForce pkgs.lix;
settings.experimental-features = [ "nix-command" "flakes" ];
};
}

19
configs/mastodon-bot.nix Normal file
View File

@@ -0,0 +1,19 @@
{pkgs, ...}: {
systemd.services.imaginary-illuminations = {
enable = false;
wants = ["network-online.target"];
serviceConfig = {
User = "kfm";
Group = "users";
WorkingDirectory = "/home/kfm/cloud/Seafile/Documents/Media/imaginary-illuminations";
Restart = "on-failure";
RestartSec = "15s";
};
startAt = "7:00";
script = ''
${pkgs.deno}/bin/deno run -A post.ts
'';
};
systemd.timers.imaginary-illuminations.timerConfig.RandomizedDelaySec = "14h";
}

View File

@@ -2,13 +2,6 @@
home-manager.users.me = {
xdg.mimeApps = {
enable = true;
associations = {
added = {
"x-scheme-handler/tg" = "org.telegram.desktop.desktop";
};
removed = {
};
};
defaultApplications = {
"application/epub+zip" = "org.pwmt.zathura.desktop";
"application/pdf" = "org.pwmt.zathura.desktop";
@@ -26,7 +19,7 @@
"x-scheme-handler/mailto" = "firefox.desktop";
"x-scheme-handler/unknown" = "firefox.desktop";
"x-scheme-handler/webcal" = "firefox.desktop";
"x-scheme-handler/tg" = "org.telegram.desktop.desktop";
"inode/directory" = "pcmanfm.desktop";
};
};
};

View File

@@ -2,8 +2,7 @@
config,
pkgs,
...
}:
{
}: {
services.nginx.virtualHosts.default = {
locations."= /stub_status".extraConfig = "stub_status;";
};
@@ -42,12 +41,12 @@
systemd.services.promtail = {
description = "Promtail service for Loki";
wantedBy = [ "multi-user.target" ];
wantedBy = ["multi-user.target"];
serviceConfig = {
ExecStart = ''
${pkgs.grafana-loki}/bin/promtail --config.file ${
(pkgs.formats.yaml { }).generate "promtail.yaml" {
(pkgs.formats.yaml {}).generate "promtail.yaml" {
server = {
http_listen_port = 28183;
grpc_listen_port = 0;
@@ -56,7 +55,9 @@
clients = [
{
url = "http://${
if config.networking.hostName == "makanek" then "127.0.0.1" else "makanek.r"
if config.networking.hostName == "makanek"
then "127.0.0.1"
else "makanek.r"
}:3100/loki/api/v1/push";
}
];
@@ -70,7 +71,7 @@
};
relabel_configs = [
{
source_labels = [ "__journal__systemd_unit" ];
source_labels = ["__journal__systemd_unit"];
target_label = "unit";
}
];

View File

@@ -1,42 +1,44 @@
{
pkgs,
lib,
self,
config,
niveumPackages,
...
}:
let
swallow = command: "${pkgs.swallow}/bin/swallow ${command}";
myMpv =
pkgs:
self.inputs.wrappers.wrapperModules.mpv.apply {
inherit pkgs;
scripts = [
pkgs.mpvScripts.visualizer
];
"mpv.conf".content = "";
"mpv.input".content = ''
Alt+- add video-zoom -0.25
Alt+= add video-zoom 0.25
Alt+LEFT add video-rotate -90
Alt+RIGHT add video-rotate 90
Alt+h add video-pan-x 0.05
Alt+j add video-pan-y -0.05
Alt+k add video-pan-y 0.05
Alt+l add video-pan-x -0.05
'';
};
in
{
}: let
swallow = command: "${niveumPackages.swallow}/bin/swallow ${command}";
in {
environment.shellAliases.smpv = swallow "mpv";
nixpkgs.overlays = [
(final: prev: {
mpv = (myMpv prev).wrapper;
(self: super: {
mpv = config.home-manager.users.me.programs.mpv.finalPackage;
})
];
environment.systemPackages = [
((myMpv pkgs).wrapper)
];
home-manager.users.me = {
programs.mpv = {
enable = true;
config = {
ytdl-format = "bestvideo[height<=?720][fps<=?30][vcodec!=?vp9]+bestaudio/best";
ytdl-raw-options = lib.concatStringsSep "," [''sub-lang="de,en"'' "write-sub=" "write-auto-sub="];
screenshot-template = "%F-%wH%wM%wS-%#04n";
script-opts = "ytdl_hook-ytdl_path=${pkgs.yt-dlp}/bin/yt-dlp";
ao = "pulse"; # no pipewire for me :(
};
bindings = {
"Alt+RIGHT" = "add video-rotate 90";
"Alt+LEFT" = "add video-rotate -90";
"Alt+-" = "add video-zoom -0.25";
"Alt+=" = "add video-zoom 0.25";
"Alt+l" = "add video-pan-x -0.05";
"Alt+h" = "add video-pan-x 0.05";
"Alt+k" = "add video-pan-y 0.05";
"Alt+j" = "add video-pan-y -0.05";
};
scripts = [
pkgs.mpvScripts.youtube-quality
niveumPackages.mpv-visualizer
];
};
};
}

View File

@@ -1,12 +0,0 @@
{ lib, pkgs, ... }:
{
services.mycelium = {
enable = true;
openFirewall = true;
};
networking.hosts = lib.mapAttrs' (name: address: {
name = address;
value = [ "${name}.m" ];
}) pkgs.lib.niveum.myceliumAddresses;
}

73
configs/neovim.nix Normal file
View File

@@ -0,0 +1,73 @@
{
pkgs,
niveumPackages,
...
}: {
environment.variables.EDITOR = pkgs.lib.mkForce "nvim";
environment.shellAliases.vi = "nvim";
environment.shellAliases.vim = "nvim";
environment.shellAliases.view = "nvim -R";
environment.systemPackages = [
(pkgs.writers.writeDashBin "vim" ''neovim "$@"'')
(pkgs.neovim.override {
configure = {
customRC = ''
source ${../lib/vim/init.vim}
luafile ${../lib/vim/init.lua}
'';
packages.nvim = with pkgs.vimPlugins; {
start = [
ale
fzf-vim
fzfWrapper
supertab
undotree
tabular
# vimwiki
niveumPackages.vimPlugins-vim-colors-paramount
nvim-lspconfig
vim-commentary
vim-css-color
vim-eunuch
niveumPackages.vimPlugins-vim-fetch
vim-fugitive
vim-gitgutter
vim-repeat
vim-sensible
vim-surround
(pkgs.vimUtils.buildVimPlugin rec {
pname = "vim-dim";
version = "1.1.0";
name = "${pname}-${version}";
src = pkgs.fetchFromGitHub {
owner = "jeffkreeftmeijer";
repo = pname;
rev = version;
sha256 = "sha256-lyTZUgqUEEJRrzGo1FD8/t8KBioPrtB3MmGvPeEVI/g=";
};
})
];
opt = [
csv
elm-vim
emmet-vim
haskell-vim
niveumPackages.vimPlugins-icalendar-vim
niveumPackages.vimPlugins-jq-vim
rust-vim
typescript-vim
vim-javascript
vim-ledger
vim-nix
vimtex
vim-pandoc
vim-pandoc-syntax
niveumPackages.vimPlugins-vim-256noir
];
};
};
})
];
}

View File

@@ -1,8 +1,47 @@
{
lib,
pkgs,
...
}:
{
}: let
profile = name: custom:
lib.recursiveUpdate {
connection.id = name;
connection.type = "wifi";
connection.interface-name = "wlp3s0";
connection.permissions = "";
wifi.mac-address-blacklist = "";
wifi.ssid = name;
wifi.mode = "infrastructure";
ipv4.dns-search = "";
ipv4.method = "auto";
ipv6.addr-gen-mode = "stable-privacy";
ipv6.dns-search = "";
ipv6.method = "auto";
proxy = {};
}
custom;
eduroamProfile = {
connection.uuid = "eae9fee6-a7d2-4120-a609-440b457d6fcf";
wifi-security = {
group = "ccmp;tkip;";
key-mgmt = "wpa-eap";
pairwise = "ccmp;";
proto = "rsn;";
};
"802-1x" = {
altsubject-matches = "DNS:srv1-radius.cms.hu-berlin.de;DNS:srv2-radius.cms.hu-berlin.de;";
anonymous-identity = "anonymous@wlan.hu-berlin.de";
ca-cert = pkgs.fetchurl {
url = "https://www.cms.hu-berlin.de/de/dl/netze/wlan/config/eduroam/t-telesec_globalroot_class_2.pem";
sha256 = "0if8aqd06sid7a0vw009zpa087wxcgdd2x6z2zs4pis5kvyqj2dk";
};
eap = "ttls;";
identity = lib.strings.fileContents <secrets/eduroam/identity>;
password = lib.strings.fileContents <secrets/eduroam/password>;
phase2-auth = "pap";
};
};
in {
programs.nm-applet.enable = true;
networking.networkmanager = {
@@ -13,10 +52,10 @@
];
wifi.macAddress = "random";
ethernet.macAddress = "random";
unmanaged = [ "docker*" ];
unmanaged = ["docker*"];
};
users.users.me.extraGroups = [ "networkmanager" ];
users.users.me.extraGroups = ["networkmanager"];
environment.systemPackages = [
pkgs.speedtest-cli

Some files were not shown because too many files have changed in this diff Show More