commit 4636885
chld
·
2026-09-13 14:33:24 +0000 UTC
parent 41daf33
update
34 files changed,
+1805,
-127
M
bin/0x0
+1,
-1
1@@ -68,5 +68,5 @@ esac; done < "$dbg"
2 echo "$resp_expires $resp_token $file $resp" >> "$storefile"
3 [ "$delete" ] && exit 0
4
5-echo "$resp"|wl-copy
6+echo "$resp" 2>&1
7
+17,
-0
1@@ -0,0 +1,17 @@
2+#!/bin/guile
3+!#
4+(set! *random-state* (random-state-from-platform))
5+
6+(let main (
7+ (e '("O" "T" "^" "$" "U" ";" "X"))
8+ (m '("w" "~" "_" "." "o" "v" "u"))
9+
10+ (dr
11+ (lambda (b a)
12+ (format b "~a" (list-ref a (random (length a))))))
13+ )
14+
15+ (define i (dr #f e))
16+ (display i)(dr #t m)(display i)
17+ (newline)
18+ )
+7,
-0
1@@ -0,0 +1,7 @@
2+bdf2psf --fb \
3+ /share/fonts/scientifica/scientifica-11.bdf \
4+ /share/fonts/consolefonts/standard.equivalents \
5+ /share/fonts/consolefonts/ascii.set+/share/fonts/consolefonts/linux.set+/share/fonts/consolefonts/useful.set \
6+ 512 \
7+ sci.psf \
8+ sci.sfm
+19,
-0
1@@ -0,0 +1,19 @@
2+#!/bin/sh
3+[ "${TERM:-none}" = "linux" ] && \
4+ printf '%b' '\e]P0{color0.strip}
5+ \e]P1{color1.strip}
6+ \e]P2{color2.strip}
7+ \e]P3{color3.strip}
8+ \e]P4{color4.strip}
9+ \e]P5{color5.strip}
10+ \e]P6{color6.strip}
11+ \e]P7{color7.strip}
12+ \e]P8{color8.strip}
13+ \e]P9{color9.strip}
14+ \e]PA{color10.strip}
15+ \e]PB{color11.strip}
16+ \e]PC{color12.strip}
17+ \e]PD{color13.strip}
18+ \e]PE{color14.strip}
19+ \e]PF{color15.strip}
20+ \ec'
+1,
-1
1@@ -1,3 +1,3 @@
2 #!/bin/sh
3-token='MTQ0MjYwNjgyMzc1MTU0OTA1MA.GkhkrX.c7QcEQeLosZ8P6-vD0Mv4cEPBZgPpiPjJmWE74'
4+token="MTUyNjM2Mjk2MTAwODkxODY5OA.GHNOXd.bqeE3Nawp6kEVefTnvHcFs5R0vS4-Yim_Rb2aM"
5 DISCORDO_TOKEN=$token discordo
+6,
-0
1@@ -0,0 +1,6 @@
2+#!/bin/sh
3+
4+a=`$HOME/bin/scrot $HOME/fbshot/`
5+
6+doas $HOME/src/drmcat /dev/dri/card0 $HOME/fbshot/$a.ppm
7+ffmpeg -i $HOME/fbshot/$a.ppm $HOME/fbshot/$a.png && rm -f $HOME/fbshot/$a.ppm
A
bin/dtr~
+1481,
-0
1@@ -0,0 +1,1481 @@
2+#!/bin/sh -u
3+# dtr - ports manager
4+
5+readonly PROG_NAME="${0##*/}"
6+readonly PROG_VERSION="1.2.1"
7+
8+: "${DTR_DIR:=/ports}"
9+: "${DTR_VERBOSITY:=1}"
10+: "${DTR_MAKE:=dmake.sh}"
11+: "${DTR_NEW_MAKE:=ndmake.sh}"
12+: "${DTR_SKIP_CONFIRM:=0}"
13+: "${DTR_REMOTE:=origin}"
14+: "${DTR_BRANCH:=main}"
15+: "${DTR_CACHE:=/var/cache/dtr}"
16+: "${SPC_EXT:=tzst}"
17+: "${BUILDBASE:=/var/tmp/dtr}"
18+: "${TMPDIR:=/tmp}"
19+: "${NO_COLOR:=}"
20+
21+readonly DEFAULT_REPO="https://codeberg.org/derivelinux/ports"
22+readonly EXTENSION_DIRS="/share/dtr /usr/share/dtr"
23+readonly OVERLAY_FILE="overlay"
24+
25+# === FORMAT STRINGS ===
26+# highlight:
27+readonly _str_highlight_o="<ul><bold>"
28+readonly _str_highlight_c="</ul></bold>"
29+readonly _str_highlight_f="${_str_highlight_o}%s${_str_highlight_c}"
30+
31+# === LOGGING ===
32+strip_tags() { printf "$@" | sed 's/<[^>]*>//g'; }
33+
34+log_printf="strip_tags"
35+if [ -z "$NO_COLOR" ] && _cmd="$(command -v tmlf 2>/dev/null)"; then
36+ log_printf="$_cmd"
37+fi
38+
39+msg() {
40+ [ "$DTR_VERBOSITY" -lt 1 ] && return
41+ $log_printf '<green>==></green> %s\n' "$*" >&2
42+}
43+info() {
44+ [ "$DTR_VERBOSITY" -lt 1 ] && return
45+ $log_printf '<dim>)</dim> %s\n' "$*" >&2
46+}
47+die() { $log_printf '%s: <bg-red>error</bg-red>: %s\n' "$PROG_NAME" "$*" >&2; exit 1; }
48+warn() { $log_printf '%s: <bg-yellow>warning</bg-yellow>: %s\n' "$PROG_NAME" "$*" >&2; }
49+
50+# === UTILITIES ===
51+chill() { head -n 32 "$1" | tail -n 31 | sed 's/^#//'; }
52+confirm_action() {
53+ [ "$DTR_SKIP_CONFIRM" -eq 1 ] && return 0
54+ [ -t 0 ] && [ -t 1 ] || return 1
55+ $log_printf '%s [y/N] ' "$1"
56+ read -r ans </dev/tty
57+ case "$ans" in [Yy]*) return 0 ;; *) return 1 ;; esac
58+}
59+for_each_line() {
60+ while IFS= read -r line; do
61+ [ -n "$line" ] || continue
62+ "$@" "$line"
63+ done
64+}
65+tmp_file() { printf '%s/dtr-%s-%s' "$TMPDIR" "$1" "$$"; }
66+strip_md_link() { printf '%s' "$1" | sed 's/\[\([^]]*\)\]([^)]*)/\1/g'; }
67+
68+# === STRACE PARSING (LEGACY SUPPORT) ===
69+parse_strace() {
70+ awk '
71+ / = -1 / {next}
72+ function extract_path(line) {
73+ start = index(line, "<")
74+ if (start == 0) return ""
75+ rest = substr(line, start + 1)
76+ end = index(rest, ">")
77+ if (end == 0) return ""
78+ return substr(rest, 1, end - 1)
79+ }
80+ /(open|openat|creat)\(.*(O_CREAT|O_WRONLY)/ ||
81+ /(rename|renameat|renameat2|symlink|symlinkat|link|linkat)/ {
82+ if ($0 ~ /= [0-9]+</) {
83+ path = extract_path($0)
84+ # Only track typical system paths to avoid noise
85+ if (path ~ /^\/(usr|etc|lib|bin|var|opt|sbin)/) print path
86+ }
87+ }
88+ ' "$1" | sort -u
89+}
90+
91+# === PACKAGE DISCOVERY ===
92+find_package() {
93+ local res
94+ case "$1" in
95+ /*)
96+ if [ -d "$1" ] && [ -f "$1/$DTR_NEW_MAKE" ]; then
97+ printf '%s' "$1"
98+ return 0
99+ fi
100+ return 1
101+ ;;
102+ *)
103+ res=$(find "$DTR_DIR" -mindepth 2 -maxdepth 2 -type d -name "$1" -print -quit 2>/dev/null)
104+ if [ -n "$res" ] && [ -f "$res/$DTR_NEW_MAKE" ]; then
105+ printf '%s' "$res"
106+ return 0
107+ fi
108+ return 1
109+ ;;
110+ esac
111+}
112+
113+get_makefile() {
114+ local dir="$1"
115+ if [ -f "$dir/$DTR_NEW_MAKE" ]; then
116+ echo "$dir/$DTR_NEW_MAKE"
117+ else
118+ return 1
119+ fi
120+}
121+
122+resolve_package_arg() {
123+ case "$1" in
124+ /*) printf '%s' "$1"; return ;;
125+ esac
126+
127+ local found
128+ found=$(find_package "$1")
129+ if [ -n "$found" ]; then
130+ printf '%s' "$found"
131+ return
132+ fi
133+
134+ if [ -d "$1" ]; then
135+ cd "$1" && pwd
136+ return
137+ fi
138+
139+ printf '%s' "$1"
140+}
141+
142+# Check installed status via spc
143+is_installed() {
144+ spc info "${1##*/}" >/dev/null 2>&1
145+}
146+
147+# === METADATA ===
148+get_package_version() {
149+ local dir makefile
150+ dir=$(find_package "$1") || return 1
151+ makefile=$(get_makefile "$dir") || return 1
152+ grep '^VERSION=' "$makefile" 2>/dev/null |
153+ head -n1 | cut -d= -f2- | tr -d '"'
154+}
155+get_package_release() {
156+ local dir makefile
157+ dir=$(find_package "$1") || return 1
158+ makefile=$(get_makefile "$dir") || return 1
159+ local rel
160+ rel=$(grep '^RELEASE=' "$makefile" 2>/dev/null |
161+ head -n1 | cut -d= -f2- | tr -d '"')
162+ echo "${rel:-1}"
163+}
164+# Extract NAME explicitly, falling back to empty if not found
165+get_package_name_var() {
166+ local dir makefile
167+ dir=$(find_package "$1") || return 1
168+ makefile=$(get_makefile "$dir") || return 1
169+ grep '^NAME=' "$makefile" 2>/dev/null |
170+ head -n1 | cut -d= -f2- | tr -d '"'
171+}
172+get_package_commit() {
173+ local dir repo makefile
174+ dir=$(find_package "$1") || return 1
175+ makefile=$(get_makefile "$dir") || return 1
176+ repo=$(grep '^REPO=' "$makefile" 2>/dev/null |
177+ head -n1 | cut -d= -f2- | tr -d '"')
178+ [ -n "$repo" ] || return 1
179+ git ls-remote --quiet "$repo" HEAD 2>/dev/null | cut -f1
180+}
181+get_package_source() {
182+ local dir makefile
183+ dir=$(find_package "$1") || return 1
184+ makefile=$(get_makefile "$dir") || return 1
185+ awk '
186+ /^SOURCE=/{
187+ line=substr($0, index($0,"=")+1)
188+ while (line ~ /\\$/) {
189+ sub(/\\$/, "", line)
190+ if (getline > 0) {
191+ sub(/^[ \t]*/, "", $0)
192+ line=line $0
193+ } else {
194+ break
195+ }
196+ }
197+ sub(/^"/, "", line)
198+ sub(/"$/, "", line)
199+ print line
200+ exit
201+ }
202+ ' "$makefile"
203+}
204+get_package_git_url() {
205+ local src tok
206+ src=$(get_package_source "$1") || return 1
207+ for tok in $src; do
208+ tok="${tok%%::*}"
209+ case "$tok" in
210+ *git@*:*|git://*|*://*.git|*://*/.git)
211+ printf '%s\n' "$tok"
212+ return 0
213+ ;;
214+ esac
215+ done
216+ return 1
217+}
218+resolve_git_version() {
219+ local ver repo commit
220+ ver="$1"
221+ case "$ver" in
222+ git:*) printf '%s\n' "$ver"; return 0 ;;
223+ git)
224+ repo=$(get_package_git_url "$2" || true)
225+ if [ -n "$repo" ]; then
226+ commit=$(git ls-remote --quiet "$repo" HEAD 2>/dev/null | cut -f1)
227+ [ -n "$commit" ] && { printf 'git:%s\n' "$commit"; return 0; }
228+ fi
229+ ;;
230+ esac
231+ printf '%s\n' "$ver"
232+}
233+get_info_field() {
234+ local infofile="$1" field="$2"
235+ [ -f "$infofile" ] || return 1
236+ grep "^${field}:" "$infofile" | head -n1 | cut -d: -f2- | sed 's/^ *//'
237+}
238+format_package_info() {
239+ local pkg="$1" fmt="$2"
240+ local dir infofile name="" desc="" maint="" ver="" contributors=""
241+
242+ dir=$(find_package "$pkg")
243+ if [ -n "$dir" ]; then
244+ infofile="$dir/info"
245+ ver=$(get_package_version "$pkg")
246+ ver=$(resolve_git_version "$ver" "$pkg")
247+
248+ if [ -f "$infofile" ]; then
249+ name=$(get_info_field "$infofile" "name")
250+ desc=$(get_info_field "$infofile" "description")
251+ maint=$(get_info_field "$infofile" "maintainer")
252+ contributors=$(get_info_field "$infofile" "contributors")
253+
254+ [ -n "$maint" ] && maint=$(strip_md_link "$maint")
255+ [ -n "$contributors" ] && contributors=$(strip_md_link "$contributors")
256+ fi
257+ fi
258+
259+ [ -n "$ver" ] && ver="+$ver"
260+ [ -n "$maint" ] && maint=":$maint"
261+ [ -n "$desc" ] && desc=" - $desc"
262+
263+ eval "echo $fmt"
264+}
265+
266+# === DEPENDENCIES ===
267+parse_dep_name() {
268+ local dep
269+ dep=$(printf '%s' "$1" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
270+ case "$dep" in
271+ [/.]*) printf '%s' "${dep#?}" ;;
272+ \>*) printf '%s' "${dep#?}" ;;
273+ *) printf '%s' "$dep" ;;
274+ esac
275+}
276+parse_dep_type() {
277+ local dep
278+ dep=$(printf '%s' "$1" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
279+ case "$dep" in
280+ /*) printf 'link' ;;
281+ \>*) printf 'runtime' ;;
282+ .*) printf 'build' ;;
283+ *) printf 'link' ;;
284+ esac
285+}
286+read_deps_file() {
287+ local depsfile="$1" dep
288+ [ -f "$depsfile" ] || return
289+
290+ while IFS= read -r dep; do
291+ dep=$(printf '%s' "$dep" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
292+ case "$dep" in ''|\#*) continue ;; esac
293+ printf '%s\n' "$dep"
294+ done < "$depsfile"
295+}
296+
297+# VISUALIZATION
298+# print_dep_tree <pkg> [prefix] [is_last] [visited_file] [mode] [extra]
299+print_dep_tree() {
300+ local pkg="$1"
301+ local prefix="${2:-}"
302+ local is_last="${3:-1}" # 1 = yes, 0 = no
303+ local visited_file="${4:-}"
304+ local mode="${5:-fwd}"
305+ local extra="${6:-}"
306+
307+ local is_toplevel=0
308+ if [ -z "$visited_file" ]; then
309+ # Setup visited tracking
310+ visited_file=$(tmp_file "tree-visited")
311+ > "$visited_file"
312+ is_toplevel=1
313+ case "$mode" in
314+ upg) : ;;
315+ rem) $log_printf "<bold>%s</bold> [remove]\n" "${pkg##*/}" ;;
316+ *) $log_printf "<bold>%s</bold>\n" "$pkg" ;;
317+ esac
318+ [ "$mode" != "upg" ] && echo "${pkg##*/}" >> "$visited_file"
319+ fi
320+
321+ local children="" nl='
322+'
323+ case "$mode" in
324+ fwd)
325+ local dir depsfile
326+ dir=$(find_package "$pkg") || return
327+ depsfile="$dir/deps"
328+ [ -f "$depsfile" ] && children=$(read_deps_file "$depsfile")
329+ ;;
330+ rev)
331+ local ilist="/tmp/dtr-installed-$$"
332+ [ -f "$ilist" ] || spc list | cut -d'+' -f1 > "$ilist"
333+ local short_pkg="${pkg##*/}"
334+ while IFS= read -r rd; do
335+ [ -n "$rd" ] || continue
336+ local rdir; rdir=$(find_package "$rd") || continue
337+ local rdf="$rdir/deps"
338+ [ -f "$rdf" ] || continue
339+ local line; line=$(grep -E "^[/>.]?${short_pkg}$" "$rdf" | head -n1)
340+ if [ -n "$line" ]; then
341+ local type; type=$(parse_dep_type "$line")
342+ children="${children}${rd}|${type}${nl}"
343+ fi
344+ done < "$ilist"
345+ [ "$is_toplevel" -eq 1 ] && rm -f "$ilist"
346+ ;;
347+ upg)
348+ [ -f "$extra" ] && children=$(cat "$extra" | sort)
349+ ;;
350+ rem)
351+ local short_pkg="${pkg##*/}"
352+ local lds; lds=$(spc info "$short_pkg" 2>/dev/null | awk '/^deps:/{p=1;next}/^files:/{p=0}p&&NF{print}') || :
353+ for dl in $lds; do
354+ local dn; dn=$(parse_dep_name "$dl")
355+ local dt; dt=$(parse_dep_type "$dl")
356+ local rb; rb=$(spc info "$dn" 2>/dev/null | grep "^required-by:" | cut -d: -f2-)
357+ local isex=1
358+ for r in $rb; do
359+ if ! grep -qxF "$r" "$visited_file"; then
360+ isex=0; break
361+ fi
362+ done
363+ if [ "$isex" -eq 1 ]; then
364+ children="${children}${dn}|${dt}${nl}"
365+ fi
366+ done
367+ ;;
368+ esac
369+
370+ [ -n "$children" ] || return
371+ if [ "$mode" = "rev" ] || [ "$mode" = "rem" ]; then
372+ children=$(printf '%s' "$children" | sort)
373+ fi
374+
375+ local total; total=$(printf '%s' "$children" | grep -c . || echo 0)
376+ local count=0; local old_ifs="$IFS"; IFS="$nl"
377+ for info in $children; do
378+ IFS="$old_ifs"; [ -n "$info" ] || continue
379+ count=$((count + 1))
380+
381+ local connector="├─"; local new_prefix="${prefix}│ "
382+ [ "$count" -eq "$total" ] && { connector="└─"; new_prefix="${prefix} "; }
383+
384+ local c_name="" c_type="" label_main="" status="" recurse=1 next_mode="$mode"
385+ if [ "$mode" = "upg" ]; then
386+ local p t o n
387+ p=$(printf '%s' "$info" | cut -d'|' -f1); t=$(printf '%s' "$info" | cut -d'|' -f2)
388+ o=$(printf '%s' "$info" | cut -d'|' -f3); n=$(printf '%s' "$info" | cut -d'|' -f4)
389+ c_name="$p"; c_type="$t"
390+ if [ "$t" = "version" ]; then
391+ label_main="<bold>$p</bold> [$o -> $n]"
392+ else
393+ label_main=$(printf '<bold>%s</bold> [%.8s -> %.8s]' "$p" "$o" "$n")
394+ fi
395+ echo "$c_name" >> "$visited_file"; next_mode="rev"
396+ else
397+ if [ "$mode" = "fwd" ]; then
398+ c_name=$(parse_dep_name "$info"); c_type=$(parse_dep_type "$info")
399+ if grep -qxF "$c_name" "$visited_file"; then
400+ status=" <dim>(...)</dim>"; recurse=0
401+ else
402+ echo "$c_name" >> "$visited_file"
403+ if is_installed "$c_name"; then status=" <green>[installed]</green>"; else status=" <yellow>[new]</yellow>"; fi
404+ fi
405+ elif [ "$mode" = "rev" ]; then
406+ c_name=$(printf '%s' "$info" | cut -d'|' -f1); c_type=$(printf '%s' "$info" | cut -d'|' -f2)
407+ if grep -qxF "$c_name" "$visited_file"; then
408+ status=" <dim>(...)</dim>"; recurse=0
409+ else
410+ echo "$c_name" >> "$visited_file"; status=" <yellow>[rebuild]</yellow>"
411+ fi
412+ elif [ "$mode" = "rem" ]; then
413+ c_name=$(printf '%s' "$info" | cut -d'|' -f1); c_type=$(printf '%s' "$info" | cut -d'|' -f2)
414+ if grep -qxF "$c_name" "$visited_file"; then
415+ status=" <dim>(...)</dim>"; recurse=0
416+ else
417+ echo "$c_name" >> "$visited_file"; status=" <yellow>[orphan]</yellow>"
418+ fi
419+ fi
420+ label_main="<bold>$c_name</bold>"
421+ fi
422+
423+ local t_mk=""
424+ case "$c_type" in
425+ link) t_mk=" <dim>[link-time]</dim>" ;;
426+ runtime) t_mk=" <dim>[runtime]</dim>" ;;
427+ build) t_mk=" <dim>[build-time]</dim>" ;;
428+ esac
429+
430+ $log_printf "%s%s %s%s%s\n" "$prefix" "$connector" "$label_main" "$t_mk" "$status"
431+ [ "$recurse" -eq 1 ] && print_dep_tree "$c_name" "$new_prefix" 1 "$visited_file" "$next_mode"
432+ IFS="$nl"
433+ done
434+ IFS="$old_ifs"
435+ [ "$is_toplevel" -eq 1 ] && rm -f "$visited_file"
436+}
437+
438+build_ordered_deps() {
439+ local target="$1" seen order
440+ seen=$(tmp_file "seen")
441+ order=$(tmp_file "order")
442+
443+ > "$seen"
444+ > "$order"
445+ _build_deps_recursive "$target" "$seen" "$order"
446+ cat "$order"
447+ rm -f "$seen" "$order"
448+}
449+_build_deps_recursive() {
450+ local target="$1" seen="$2" order="$3" dir depsfile dep name
451+
452+ grep -qxF "$target" "$seen" 2>/dev/null && return
453+ printf '%s\n' "$target" >> "$seen"
454+
455+ dir=$(find_package "$target") || return 0
456+ depsfile="$dir/deps"
457+
458+ if [ -f "$depsfile" ]; then
459+ while IFS= read -r dep; do
460+ case "$dep" in ''|'#'*) continue ;; esac
461+ name=$(parse_dep_name "$dep")
462+ [ -n "$name" ] || continue
463+ _build_deps_recursive "$name" "$seen" "$order"
464+ done < "$depsfile"
465+ fi
466+
467+ # Add to build order if NOT installed
468+ is_installed "$target" || printf '%s\n' "$target" >> "$order"
469+}
470+
471+find_reverse_deps() {
472+ local target="$1" filter_type="${2:-}" pkg pkgdir depsfile dep name type
473+
474+ # Use spc to list all installed packages
475+ spc list | cut -d'+' -f1 | while IFS= read -r pkg; do
476+ pkgdir=$(find_package "$pkg") || continue
477+ depsfile="$pkgdir/deps"
478+
479+ read_deps_file "$depsfile" | while IFS= read -r dep; do
480+ name=$(parse_dep_name "$dep")
481+ [ "$name" = "$target" ] || continue
482+
483+ if [ -n "$filter_type" ]; then
484+ type=$(parse_dep_type "$dep")
485+ [ "$type" = "$filter_type" ] || continue
486+ fi
487+
488+ printf '%s\n' "$pkg"
489+ break
490+ done
491+ done
492+}
493+rebuild_dependents() {
494+ local target="$1" filter_type="${2:-}" rebuilt countf dep is_toplevel=0
495+ rebuilt=$(tmp_file "rebuilt")
496+ countf=$(tmp_file "count")
497+
498+ [ -f "$rebuilt" ] || { > "$rebuilt"; echo 0 > "$countf"; is_toplevel=1; }
499+ grep -qxF "$target" "$rebuilt" && { cat "$countf" 2>/dev/null || echo 0; return; }
500+
501+ printf '%s\n' "$target" >> "$rebuilt"
502+
503+ find_reverse_deps "$target" "$filter_type" | while IFS= read -r dep; do
504+ [ -n "$dep" ] || continue
505+
506+ msg "rebuilding dependent: $dep"
507+
508+ # clean first so cached source etc doesent cause skip
509+ clean_package "$dep" || die "failed to clean dependent: $dep"
510+
511+ # rebuild deps non-interactively, and die fast on fail.
512+ DTR_SKIP_CONFIRM=1 do_make "$dep" || die "failed to rebuild dependent: $dep"
513+ install_package "$dep" || die "failed to install rebuilt dependent: $dep"
514+
515+ local count
516+ count=$(cat "$countf")
517+ count=$((count + 1))
518+ echo "$count" > "$countf"
519+
520+ rebuild_dependents "$dep" "$filter_type" >/dev/null
521+ done
522+
523+ cat "$countf" 2>/dev/null || echo 0
524+ [ "$is_toplevel" -eq 1 ] && rm -f "$rebuilt" "$countf"
525+}
526+
527+# === BUILD & INSTALL ===
528+build_package() {
529+ local pkg="$1" dir makefile
530+
531+ [ -z "$pkg" ] && die "build_package called with empty package name"
532+
533+ dir=$(find_package "$pkg") || die "package $pkg not found"
534+ makefile=$(get_makefile "$dir") || die "no build script found for $pkg"
535+
536+ # CACHE INVALIDATION
537+ # If we are building, we must invalidate the cache to prevent 'install'
538+ # from picking up the old package instead of the new build artifacts.
539+ local pkgname ver rel pkg_archive
540+ pkgname=$(get_package_name_var "$pkg")
541+ [ -z "$pkgname" ] && pkgname="${dir##*/}"
542+ ver=$(get_package_version "$pkg")
543+ ver=$(resolve_git_version "$ver" "$pkg")
544+ rel=$(get_package_release "$pkg")
545+
546+ if [ -n "$ver" ]; then
547+ pkg_archive="${DTR_CACHE}/${pkgname}+${ver}-${rel}.spc.${SPC_EXT}"
548+ if [ -f "$pkg_archive" ]; then
549+ rm -f "$pkg_archive"
550+ info "invalidated cache for $pkgname"
551+ fi
552+ fi
553+
554+ msg "building $pkg"
555+ cd "$dir" || die "cannot cd to $dir"
556+ sh "$makefile" make || die "make failed for $pkg"
557+}
558+
559+check_cache_validity() {
560+ local pkg="$1" cache_file="$2"
561+ [ -f "$cache_file" ] || return 1
562+
563+ local dir depsfile
564+ dir=$(find_package "$pkg") || return 0
565+ depsfile="$dir/deps"
566+ [ -f "$depsfile" ] || return 0
567+
568+ local cache_mtime
569+ cache_mtime=$(stat -c %Y "$cache_file")
570+
571+ # Check link-time dependencies
572+ while IFS= read -r line; do
573+ [ -z "$line" ] && continue
574+ case "$line" in \#*) continue ;; esac
575+
576+ local type name
577+ type=$(parse_dep_type "$line")
578+ name=$(parse_dep_name "$line")
579+
580+ # Only care about link-time deps (default or /)
581+ if [ "$type" = "link" ]; then
582+ # Check installed lockfile timestamp
583+ local lockfile="/var/lib/spc/lock/${name}.lock"
584+ if [ -f "$lockfile" ]; then
585+ local lock_mtime
586+ lock_mtime=$(stat -c %Y "$lockfile")
587+ if [ "$lock_mtime" -gt "$cache_mtime" ]; then
588+ info "cache invalid: dependency $name is newer than cached $pkg"
589+ return 1
590+ fi
591+ fi
592+ fi
593+ done < "$depsfile"
594+ return 0
595+}
596+
597+install_package() {
598+ local pkg="$1" dir makefile pkgname ver_raw ver rel staging_dir pkg_archive is_legacy=0
599+ # Optional: space-separated list of packages that requested this install
600+ local required_by="${2:-}"
601+
602+ dir=$(find_package "$pkg") || die "package $pkg not found"
603+ makefile=$(get_makefile "$dir") || die "no build script found for $pkg"
604+
605+ if [ "${makefile##*/}" = "$DTR_MAKE" ]; then
606+ is_legacy=1
607+ fi
608+
609+ pkgname=$(get_package_name_var "$pkg")
610+ [ -z "$pkgname" ] && pkgname="${dir##*/}"
611+
612+ ver_raw=$(get_package_version "$pkg")
613+ ver=$(resolve_git_version "$ver_raw" "$pkg")
614+ rel=$(get_package_release "$pkg")
615+ [ -z "$ver_raw" ] && die "cannot determine version for $pkg"
616+
617+ pkg_archive="${DTR_CACHE}/${pkgname}+${ver}-${rel}.spc.${SPC_EXT}"
618+
619+ # CACHE CHECK
620+ if [ -f "$pkg_archive" ]; then
621+ if check_cache_validity "$pkgname" "$pkg_archive"; then
622+ msg "using cached package: $pkg_archive"
623+ msg "installing $pkgname via spc..."
624+ SPC_REQUIRED_BY="$required_by" spc install "$pkg_archive" || die "spc failed to install cached package"
625+ return 0
626+ else
627+ info "cache exists but is stale (dependency update detected)"
628+ rm -f "$pkg_archive"
629+ fi
630+ fi
631+
632+ if [ "$is_legacy" -eq 1 ]; then
633+ msg "installing $pkgname (legacy mode)..."
634+ local slog nfiles
635+ slog=$(tmp_file "strace-$pkgname")
636+ nfiles=$(tmp_file "nfiles-$pkgname")
637+ staging_dir="${BUILDBASE}/pkg-legacy-${pkgname}-${ver_raw}"
638+
639+ rm -rf "$staging_dir"
640+ mkdir -p "$staging_dir"
641+
642+ cd "$dir" || die "cannot cd to $dir"
643+
644+ if ! strace -f -y -qq \
645+ -e trace=open,openat,creat,rename,renameat,renameat2,symlink,symlinkat,link,linkat \
646+ -o "$slog" sh "$makefile" install; then
647+ rm -f "$slog" "$nfiles"
648+ die "legacy install failed for $pkg"
649+ fi
650+
651+ parse_strace "$slog" > "$nfiles"
652+
653+ msg "capturing legacy files..."
654+ while read -r f; do
655+ if [ -e "$f" ]; then
656+ mkdir -p "$staging_dir/$(dirname "$f")"
657+ cp -a "$f" "$staging_dir/$f"
658+ fi
659+ done < "$nfiles"
660+
661+ rm -f "$slog" "$nfiles"
662+
663+ msg "packaging legacy capture..."
664+ spc create "$staging_dir" "$pkg_archive" || die "spc failed to create package"
665+
666+ msg "registering $pkgname via spc..."
667+ SPC_REQUIRED_BY="$required_by" SPC_FORCE=1 spc install "$pkg_archive" || die "spc failed to register package"
668+
669+ rm -rf "$staging_dir"
670+
671+ else
672+ staging_dir="${BUILDBASE}/pkg-${pkgname}-${ver_raw}"
673+
674+ if [ ! -d "$staging_dir" ]; then
675+ die "staging directory not found: $staging_dir (build not run?)"
676+ fi
677+
678+ msg "packaging $pkgname..."
679+ spc create "$staging_dir" "$pkg_archive" || die "spc failed to create package"
680+
681+ msg "installing $pkgname via spc..."
682+ SPC_REQUIRED_BY="$required_by" spc install "$pkg_archive" || die "spc failed to install package"
683+ fi
684+}
685+
686+clean_package() {
687+ local pkg="$1" dir makefile
688+
689+ dir=$(find_package "$pkg") || die "package $pkg not found"
690+
691+ if makefile=$(get_makefile "$dir"); then
692+ msg "cleaning $pkg"
693+ cd "$dir" || die "cannot cd to $dir"
694+ sh "$makefile" clean || die "clean failed for $pkg"
695+ else
696+ die "no build script found for $pkg"
697+ fi
698+}
699+
700+remove_package() {
701+ local pkg="$1" n="${pkg##*/}"
702+ is_installed "$n" || die "package '$n' not installed"
703+ $log_printf "\n<bold>removal impact for %s:</bold>\n" "$n"
704+ print_dep_tree "$pkg" " " 1 "" "rem"
705+ $log_printf "\n"
706+ confirm_action "remove package $n?" || return 1
707+
708+ local dir pkgname makefile
709+ dir=$(find_package "$pkg") || die "package $pkg not found"
710+ pkgname=$(get_package_name_var "$pkg")
711+ [ -z "$pkgname" ] && pkgname="$n"
712+
713+ msg "removing $pkgname"
714+ spc remove "$pkgname" || die "spc failed to remove package"
715+
716+ if makefile=$(get_makefile "$dir"); then
717+ cd "$dir"
718+ sh "$makefile" clean >/dev/null 2>&1 || true
719+ fi
720+}
721+
722+purge_package() {
723+ local pkg="$1" n="${pkg##*/}" to_rem
724+ is_installed "$n" || die "package '$n' not installed"
725+ $log_printf "\n<bold>purge plan for %s (includes orphans):</bold>\n" "$n"
726+ to_rem=$(tmp_file "to-remove")
727+ > "$to_rem"
728+ _find_orphans_recursive "$pkg" "$to_rem"
729+ print_dep_tree "$pkg" " " 1 "" "rem"
730+ $log_printf "\n"
731+ confirm_action "remove package $n and dependencies?" || { rm -f "$to_rem"; return 1; }
732+
733+ tac "$to_rem" | while read -r p; do
734+ local pdir; pdir=$(find_package "$p") || continue
735+ msg "purging $p"
736+ spc purge "$p" || die "spc purge failed for $p"
737+ if makefile=$(get_makefile "$pdir"); then
738+ cd "$pdir"
739+ sh "$makefile" clean >/dev/null 2>&1 || true
740+ fi
741+ done
742+ rm -f "$to_rem"
743+}
744+
745+_find_orphans_recursive() {
746+ local pkg="$1" n="${pkg##*/}" out_file="$2"
747+ grep -qxF "$n" "$out_file" && return
748+ echo "$n" >> "$out_file"
749+ local lds; lds=$(spc info "$n" 2>/dev/null | awk '/^deps:/{p=1;next}/^files:/{p=0}p&&NF{print}') || :
750+ for dl in $lds; do
751+ local dn; dn=$(parse_dep_name "$dl")
752+ local rb; rb=$(spc info "$dn" 2>/dev/null | grep "^required-by:" | cut -d: -f2-)
753+ local isex=1
754+ for r in $rb; do
755+ if ! grep -qxF "$r" "$out_file"; then
756+ isex=0; break
757+ fi
758+ done
759+ [ "$isex" -eq 1 ] && _find_orphans_recursive "$dn" "$out_file"
760+ done
761+}
762+
763+do_make() {
764+ local pkg="$1" plan deps dep
765+
766+ # Check existence before proceeding
767+ if ! find_package "$pkg" >/dev/null; then
768+ die "package '$pkg' not found"
769+ fi
770+
771+ plan=$(tmp_file "plan")
772+ deps=$(build_ordered_deps "$pkg")
773+
774+ if [ -n "$deps" ]; then
775+ printf '%s\n' "$deps" > "$plan"
776+ else
777+ > "$plan"
778+ fi
779+
780+ if [ "$DTR_SKIP_CONFIRM" != "1" ]; then
781+ local is_reinstall=0
782+ local pname="${pkg##*/}"
783+ if is_installed "$pkg"; then
784+ is_reinstall=1
785+ fi
786+
787+ $log_printf '\n<bold>build plan for %s:</bold>\n' "$pname"
788+ print_dep_tree "$pkg" " " 1
789+ $log_printf "\n"
790+
791+ if [ "$is_reinstall" -eq 1 ]; then
792+ $log_printf "package ${_str_highlight_o}${pname}${_str_highlight_c} is already installed.\n"
793+ confirm_action "rebuild ${_str_highlight_o}${pname}${_str_highlight_c}?" || { rm -f "$plan"; return 1; }
794+ else
795+ confirm_action "proceed with build?" || { rm -f "$plan"; return 1; }
796+ fi
797+ fi
798+
799+ [ -f "$plan" ] && while IFS= read -r dep; do
800+ [ -n "$dep" ] && [ "$dep" != "$pkg" ] || continue
801+ is_installed "$dep" && continue
802+ msg "installing dependency: $dep"
803+ build_package "$dep"
804+ # Check how $pkg lists this dep. Build-time deps (.) are not needed
805+ # post-install so they don't generate a required-by relationship.
806+ local _req_by="${pkg##*/}"
807+ local _pkgdir
808+ _pkgdir=$(find_package "$pkg") || true
809+ if [ -n "$_pkgdir" ] && [ -f "$_pkgdir/deps" ]; then
810+ local _raw
811+ _raw=$(grep -xF ".$dep" "$_pkgdir/deps" 2>/dev/null || true)
812+ [ -n "$_raw" ] && _req_by=""
813+ fi
814+ install_package "$dep" "$_req_by"
815+ done < "$plan"
816+
817+ build_package "$pkg"
818+ rm -f "$plan"
819+}
820+
821+do_make_nodeps() {
822+ local pkg="$1"
823+
824+ # Check existence before proceeding
825+ if ! find_package "$pkg" >/dev/null; then
826+ die "package '$pkg' not found"
827+ fi
828+
829+ if [ "$DTR_SKIP_CONFIRM" != "1" ]; then
830+ local is_reinstall=0
831+ local pname="${pkg##*/}"
832+ if is_installed "$pkg"; then
833+ is_reinstall=1
834+ fi
835+
836+ $log_printf '\n<bold>building (no deps) %s:</bold>\n' "$pname"
837+
838+ if [ "$is_reinstall" -eq 1 ]; then
839+ $log_printf "package ${_str_highlight_o}${pname}${_str_highlight_c} is already installed.\n"
840+ confirm_action "rebuild ${_str_highlight_o}${pname}${_str_highlight_c}?" || return 1
841+ else
842+ confirm_action "proceed with build?" || return 1
843+ fi
844+ fi
845+
846+ build_package "$pkg"
847+}
848+
849+# === SYNC & UPGRADE ===
850+get_remote_branch() {
851+ local remote="${DTR_REMOTE}" branch="${DTR_BRANCH}" fallback="main"
852+
853+ if git show-ref --verify --quiet "refs/remotes/$remote/$branch"; then
854+ printf '%s/%s' "$remote" "$branch"
855+ elif git show-ref --verify --quiet "refs/remotes/$remote/$fallback"; then
856+ printf '%s/%s' "$remote" "$fallback"
857+ else
858+ die "neither $remote/$branch nor $remote/$fallback found"
859+ fi
860+}
861+
862+overlay_file() {
863+ printf '%s/%s' "$DTR_DIR" "$OVERLAY_FILE"
864+}
865+
866+overlay_cache() {
867+ printf '%s/overlays' "$DTR_CACHE"
868+}
869+
870+overlay_key() {
871+ printf '%s' "$1" | cksum | awk '{print $1}'
872+}
873+
874+overlay_dir() {
875+ local overlay_url="$1" key
876+ key=$(overlay_key "$overlay_url")
877+ printf '%s/%s' "$(overlay_cache)" "$key"
878+}
879+
880+valid_overlay_url() {
881+ case "$1" in
882+ http://*|https://*|git://*|ssh://*|git@*:*|*.git)
883+ return 0
884+ ;;
885+ *)
886+ return 1
887+ ;;
888+ esac
889+}
890+
891+sync_overlay_repo() {
892+ local overlay_url="$1" dir
893+ dir=$(overlay_dir "$overlay_url")
894+
895+ mkdir -p "$(overlay_cache)" || die "failed to create overlay cache directory"
896+ if [ -d "$dir/.git" ]; then
897+ msg "syncing overlay repo: $overlay_url"
898+ cd "$dir" || die "cannot cd to overlay repo cache: $dir"
899+ git fetch --quiet origin || die "overlay fetch failed: $overlay_url"
900+ local ref
901+ if git show-ref --verify --quiet refs/remotes/origin/main; then
902+ ref="origin/main"
903+ elif git show-ref --verify --quiet refs/remotes/origin/master; then
904+ ref="origin/master"
905+ else
906+ ref="origin/HEAD"
907+ fi
908+ git reset --hard "$ref" >/dev/null 2>&1 || die "overlay reset failed: $overlay_url"
909+ else
910+ rm -rf "$dir"
911+ msg "cloning overlay repo: $overlay_url"
912+ git clone --quiet "$overlay_url" "$dir" || die "failed to clone overlay repo: $overlay_url"
913+ fi
914+
915+ printf '%s\n' "$dir"
916+}
917+
918+apply_overlay() {
919+ local overlay_url="$1" dir cat port cat_name port_name target_cat target_port count
920+ [ -d "$DTR_DIR" ] || die "$DTR_DIR does not exist (run '$PROG_NAME s' first)"
921+
922+ dir=$(sync_overlay_repo "$overlay_url")
923+ count=0
924+
925+ for cat in "$dir"/*; do
926+ [ -d "$cat" ] || continue
927+ cat_name="${cat##*/}"
928+ case "$cat_name" in
929+ .*) continue ;;
930+ esac
931+
932+ for port in "$cat"/*; do
933+ [ -d "$port" ] || continue
934+ [ -f "$port/$DTR_NEW_MAKE" ] || continue
935+ port_name="${port##*/}"
936+ target_cat="$DTR_DIR/$cat_name"
937+ target_port="$target_cat/$port_name"
938+
939+ mkdir -p "$target_cat" || die "failed to create category directory: $target_cat"
940+ rm -rf "$target_port"
941+ cp -R "$port" "$target_port" || die "failed to overlay port: $cat_name/$port_name"
942+ count=$((count + 1))
943+ done
944+ done
945+
946+ msg "overlay applied from $overlay_url ($count ports)"
947+}
948+
949+overlay_add() {
950+ local overlay_url="$1" overlays_file tmp
951+ overlays_file=$(overlay_file)
952+ tmp=$(tmp_file "overlay")
953+
954+ mkdir -p "$DTR_DIR" || die "failed to create $DTR_DIR"
955+ touch "$overlays_file" || die "failed to create overlay file: $overlays_file"
956+
957+ if grep -Fxq "$overlay_url" "$overlays_file"; then
958+ return 0
959+ fi
960+
961+ cp "$overlays_file" "$tmp" 2>/dev/null || : > "$tmp"
962+ printf '%s\n' "$overlay_url" >> "$tmp"
963+ mv "$tmp" "$overlays_file" || die "failed to update overlay file: $overlays_file"
964+}
965+
966+sync_overlays() {
967+ local overlays_file line
968+ overlays_file=$(overlay_file)
969+ [ -f "$overlays_file" ] || return 0
970+
971+ msg "syncing active overlays"
972+ while IFS= read -r line; do
973+ [ -n "$line" ] || continue
974+ case "$line" in
975+ \#*) continue ;;
976+ esac
977+ apply_overlay "$line"
978+ done < "$overlays_file"
979+}
980+
981+add_overlay() {
982+ local overlay_url="$1"
983+ valid_overlay_url "$overlay_url" || die "invalid overlay repository URL: $overlay_url"
984+
985+ apply_overlay "$overlay_url"
986+ overlay_add "$overlay_url"
987+ msg "overlay registered in $(overlay_file)"
988+}
989+
990+sync_ports() {
991+ msg "syncing ports tree"
992+
993+ local current_remote
994+
995+ if [ -d "$DTR_DIR/.git" ]; then
996+ cd "$DTR_DIR" || die "cannot cd to $DTR_DIR"
997+ current_remote=$(git config "remote.$DTR_REMOTE.url" 2>/dev/null || true)
998+
999+ if [ -n "$current_remote" ] &&
1000+ [ "$current_remote" != "$DEFAULT_REPO" ] &&
1001+ [ "$current_remote" != "${DEFAULT_REPO}.git" ]; then
1002+ warn "current ports tree points to unexpected remote: $current_remote"
1003+ info "expected: $DEFAULT_REPO"
1004+ confirm_action "proceed with fetch/reset anyway?" || { msg "sync aborted"; return 1; }
1005+ fi
1006+
1007+ msg "fetching and resetting existing repository"
1008+ git fetch --quiet "$DTR_REMOTE" || die "git fetch failed"
1009+ local ref
1010+ ref=$(get_remote_branch)
1011+ git reset --hard "$ref" || die "git reset failed"
1012+ else
1013+ if [ -d "$DTR_DIR" ]; then
1014+ warn "directory $DTR_DIR exists but is not a git repository"
1015+ confirm_action "remove it and clone fresh repository?" || { msg "sync aborted"; return 1; }
1016+ rm -rf "$DTR_DIR" || die "failed to remove existing directory"
1017+ fi
1018+
1019+ msg "cloning fresh ports tree from $DEFAULT_REPO"
1020+ git clone --quiet "$DEFAULT_REPO" "$DTR_DIR" || die "clone failed"
1021+ fi
1022+
1023+ if [ -f "$DTR_DIR/dtr" ]; then
1024+ cp -f "$DTR_DIR/dtr" /bin/dtr || die "failed to copy $DTR_DIR/dtr to /bin/dtr"
1025+ else
1026+ warn "missing $DTR_DIR/dtr; skipping /bin/dtr update"
1027+ fi
1028+
1029+ if [ -f "$DTR_DIR/spc" ]; then
1030+ cp -f "$DTR_DIR/spc" /bin/spc || die "failed to copy $DTR_DIR/spc to /bin/spc"
1031+ else
1032+ warn "missing $DTR_DIR/spc; skipping /bin/spc update"
1033+ fi
1034+
1035+ sync_overlays
1036+
1037+ msg "ports tree synced"
1038+}
1039+check_package_update() {
1040+ local pkg="$1" outfile="$2" ver_new ver_old rel_new rel_old
1041+
1042+ ver_new=$(get_package_version "$pkg")
1043+ ver_new=$(resolve_git_version "$ver_new" "$pkg")
1044+ rel_new=$(get_package_release "$pkg")
1045+
1046+ # We query spc info for installed details
1047+ if is_installed "$pkg"; then
1048+ ver_old=$(spc info "$pkg" | grep "^version:" | cut -d: -f2- | sed 's/^ *//')
1049+ rel_old=$(spc info "$pkg" | grep "^release:" | cut -d: -f2- | sed 's/^ *//')
1050+ rel_old=${rel_old:-1}
1051+ else
1052+ ver_old=""
1053+ rel_old=""
1054+ fi
1055+
1056+ if [ -n "$ver_new" ] && [ -n "$ver_old" ] && [ "$ver_new" != "$ver_old" ]; then
1057+ printf '%s|version|%s|%s\n' "$pkg" "$ver_old" "$ver_new" >> "$outfile"
1058+ elif [ -n "$ver_new" ] && [ -n "$ver_old" ] &&
1059+ [ -n "$rel_new" ] && [ -n "$rel_old" ] && [ "$rel_new" != "$rel_old" ]; then
1060+ printf '%s|release|%s|%s\n' "$pkg" "$rel_old" "$rel_new" >> "$outfile"
1061+ fi
1062+}
1063+do_upgrade() {
1064+ spc list >/dev/null 2>&1 || { msg "no packages installed"; return 0; }
1065+ msg "checking for updates"
1066+ local upg; upg=$(tmp_file "upgrade"); > "$upg"
1067+ local targets; [ $# -gt 0 ] && targets="$@" || targets=$(spc list | cut -d'+' -f1)
1068+ for p in $targets; do [ -n "$p" ] || continue; check_package_update "$p" "$upg" & done; wait
1069+ if [ ! -s "$upg" ]; then msg "all packages up to date"; rm -f "$upg"; return 0; fi; sort -o "$upg" "$upg"
1070+
1071+ $log_printf '\n<bold>build plan for upgrade:</bold>\n'
1072+ _DTR_UPGRADE_IN_PROGRESS=1 print_dep_tree "" " " 1 "" "upg" "$upg"
1073+
1074+ local scope="link"
1075+ if [ "$DTR_SKIP_CONFIRM" != "1" ]; then
1076+ $log_printf '\n<bold>rebuild scope:</bold>\n [1] link-time dependents\n [2] all dependents\n [3] target package only\n [4] exit\nselect option [1]: '
1077+ local choice; read -r choice </dev/tty; [ -z "$choice" ] && choice=1
1078+ case "$choice" in 2) scope="" ;; 3) scope="none" ;; 4) rm -f "$upg"; return 0 ;; *) scope="link" ;; esac
1079+ fi
1080+
1081+ while IFS='|' read -r pkg t o n; do
1082+ msg "upgrading $pkg ($t)"
1083+ DTR_SKIP_CONFIRM=1 do_make "$pkg" && install_package "$pkg" && clean_package "$pkg"
1084+ [ "$scope" != "none" ] && rebuild_dependents "$pkg" "$scope" >/dev/null
1085+ done < "$upg"; rm -f "$upg"
1086+}
1087+
1088+# === LISTING & SEARCH ===
1089+# laf: List all from repo, enriched with spc data
1090+list_all_full() {
1091+ $log_printf 'available packages in %s:\n' "$DTR_DIR"
1092+
1093+ # Search for ndmake.sh only
1094+ find "$DTR_DIR" -mindepth 3 -maxdepth 3 -type f -name "$DTR_NEW_MAKE" -print |
1095+ for_each_line dirname | for_each_line basename | sort -u |
1096+ while read -r pkg; do
1097+ if is_installed "$pkg"; then
1098+ $log_printf ' [I] '
1099+ else
1100+ $log_printf ' [ ] '
1101+ fi
1102+ format_package_info "$pkg" '$pkg$ver$maint'
1103+ done
1104+}
1105+
1106+# lif: List installed via spc passthrough
1107+list_installed_full() {
1108+ spc list
1109+}
1110+
1111+list_deps() {
1112+ local pkg="$1" dir depsfile dep name type
1113+
1114+ dir=$(find_package "$pkg") || die "package $pkg not found"
1115+ depsfile="$dir/deps"
1116+
1117+ $log_printf 'dependencies for %s (/ = link-time, > = runtime, . = build-time):\n' "$pkg"
1118+
1119+ if [ -f "$depsfile" ] && grep -qv '^\s*#' "$depsfile" 2>/dev/null; then
1120+ read_deps_file "$depsfile" | while IFS= read -r dep; do
1121+ name=$(parse_dep_name "$dep")
1122+ type=$(parse_dep_type "$dep")
1123+ case "$type" in
1124+ link) $log_printf ' /%s\n' "$name" ;;
1125+ runtime) $log_printf ' >%s\n' "$name" ;;
1126+ build) $log_printf ' .%s\n' "$name" ;;
1127+ esac
1128+ done
1129+ else
1130+ $log_printf ' (none)\n'
1131+ fi
1132+}
1133+
1134+list_orphans() {
1135+ spc orphans
1136+}
1137+search_packages() {
1138+ local query="$1"
1139+ [ -z "$query" ] && die "search query required"
1140+
1141+ msg "searching for: $query"
1142+
1143+ find "$DTR_DIR" -mindepth 3 -maxdepth 3 -type f -name "info" |
1144+ while read -r infofile; do
1145+ if grep -Ei "^(name|description):.*$query" "$infofile" >/dev/null; then
1146+ local pkgdir
1147+ pkgdir=$(dirname "$infofile")
1148+ $log_printf ' '
1149+ format_package_info "${pkgdir##*/}" '$pkg$desc'
1150+ fi
1151+ done
1152+}
1153+
1154+# === INFO MANAGEMENT ===
1155+show_info() {
1156+ local pkg="$1" dir infofile
1157+
1158+ dir=$(find_package "$pkg") || die "package $pkg not found"
1159+ infofile="$dir/info"
1160+ [ -f "$infofile" ] || die "info file not found for $pkg"
1161+
1162+ cat "$infofile"
1163+ $log_printf '\n'
1164+}
1165+populate_info() {
1166+ [ -d "$DTR_DIR/.git" ] || die "$DTR_DIR is not a git repository"
1167+
1168+ msg "populating info fields from git history"
1169+ local authors_tmp
1170+ authors_tmp=$(tmp_file "authors")
1171+
1172+ find "$DTR_DIR" -mindepth 3 -maxdepth 3 -type f -name "$DTR_NEW_MAKE" |
1173+ while read -r makefile; do
1174+ local pkgdir pkgname infofile creator_raw maintainer_md contributors_md
1175+ local name desc license
1176+ pkgdir=$(dirname "$makefile")
1177+ pkgname="${pkgdir##*/}"
1178+ infofile="$pkgdir/info"
1179+
1180+ cd "$DTR_DIR" || continue
1181+
1182+ # Read existing fields
1183+ if [ -f "$infofile" ]; then
1184+ name=$(get_info_field "$infofile" "name")
1185+ desc=$(get_info_field "$infofile" "description")
1186+ license=$(get_info_field "$infofile" "license")
1187+ fi
1188+
1189+ # Determine creator (first committer to build script)
1190+ creator_raw=$(git log --reverse --format='%an <%ae>' -- "$makefile" | head -n 1)
1191+ [ -z "$creator_raw" ] && continue
1192+
1193+ # Get all contributors sorted by commit count
1194+ git log --format='%an <%ae>' -- "$makefile" |
1195+ sort | uniq -c | sort -rn > "$authors_tmp"
1196+
1197+ # Build markdown strings (sanitize names: spaces -> underscores)
1198+ maintainer_md=$(echo "$creator_raw" | sed 's/^\(.*\) <\(.*\)>$/[\1](\2)/' | sed 's/\[\([^]]*\)\]/[\1]/' | sed 's/\[\([^]]*\) /[\1_/g' | sed 's/ \([^]]*\)\]/_\1]/g')
1199+ contributors_md=""
1200+
1201+ # Filter creator from contributors, format others
1202+ local contrib_list
1203+ contrib_list=$(grep -vF "$creator_raw" "$authors_tmp" | sed -E 's/^[[:space:]]*[0-9]+[[:space:]]+//')
1204+
1205+ if [ -n "$contrib_list" ]; then
1206+ contributors_md=$(echo "$contrib_list" | sed 's/^\(.*\) <\(.*\)>$/[\1](\2)/' | sed 's/\[\([^]]*\)\]/[\1]/' | sed 's/\[\([^]]*\) /[\1_/g' | sed 's/ \([^]]*\)\]/_\1]/g' | paste -sd ',' - | sed 's/,/, /g')
1207+ fi
1208+
1209+ # Update info file (create if doesn't exist)
1210+ if [ ! -f "$infofile" ]; then
1211+ touch "$infofile"
1212+ fi
1213+
1214+ # Remove existing maintainer/contributors fields
1215+ sed -i '/^maintainer:/d' "$infofile"
1216+ sed -i '/^contributors:/d' "$infofile"
1217+
1218+ # Set proper name if empty
1219+ if [ -z "$name" ]; then
1220+ printf 'name: %s\n' "$pkgname" >> "$infofile"
1221+ fi
1222+
1223+ # Warn if description is empty
1224+ [ -z "$desc" ] && warn "package $pkgname: description field is empty"
1225+
1226+ # Warn if license is empty
1227+ [ -z "$license" ] && warn "package $pkgname: license field is empty"
1228+
1229+ # Append maintainer and contributors
1230+ printf 'maintainer: %s\n' "$maintainer_md" >> "$infofile"
1231+ if [ -n "$contributors_md" ]; then
1232+ printf 'contributors: %s\n' "$contributors_md" >> "$infofile"
1233+ fi
1234+
1235+ info "updated: $pkgname"
1236+ done
1237+
1238+ rm -f "$authors_tmp"
1239+ msg "info population complete"
1240+}
1241+generate_dmake_scripts() {
1242+ local dir="${1:-$DTR_DIR}"
1243+ [ -d "$dir" ] || die "directory $dir does not exist"
1244+
1245+ find "$dir" -mindepth 1 -maxdepth 1 -type d |
1246+ while read -r d; do
1247+ local makefile pkgname
1248+ makefile="$d/$DTR_NEW_MAKE"
1249+ [ -f "$makefile" ] && continue
1250+
1251+ pkgname="${d##*/}"
1252+ msg "creating $DTR_NEW_MAKE for $pkgname"
1253+
1254+ cat > "$makefile" <<'EOF'
1255+#!/bin/sh
1256+# ndmake.sh template for $pkgname
1257+
1258+case "${1:-}" in
1259+ make) ;;
1260+ install) ;;
1261+ clean) ;;
1262+ remove) ;;
1263+ *) echo "usage: $0 {make|install|clean|remove}"; exit 1 ;;
1264+esac
1265+EOF
1266+ chmod +x "$makefile"
1267+ done
1268+}
1269+
1270+# === EXTENSIONS ===
1271+find_extension() {
1272+ local ext="$1" dir
1273+
1274+ for dir in $EXTENSION_DIRS; do
1275+ if [ -d "$dir" ] && [ -f "$dir/$ext" ]; then
1276+ printf '%s' "$dir/$ext"
1277+ return 0
1278+ fi
1279+ done
1280+ return 1
1281+}
1282+
1283+call_extension() {
1284+ local ext="$1" ext_path
1285+ shift
1286+
1287+ ext_path=$(find_extension "$ext") || return 1
1288+ sh "$ext_path" "$@"
1289+}
1290+process_chain() {
1291+ local chain="$1" i=0 c next_c
1292+
1293+ while [ $i -lt ${#chain} ]; do
1294+ c=$(printf '%s' "$chain" | cut -c$((i + 1)))
1295+ i=$((i + 1))
1296+
1297+ case "$c" in
1298+ m) do_make "$pkg" || return ;;
1299+ d) do_make_nodeps "$pkg" || return ;;
1300+ i) install_package "$pkg" || return ;;
1301+ c) clean_package "$pkg" || return ;;
1302+ r) remove_package "$pkg" || return ;;
1303+ p) purge_package "$pkg" || return ;;
1304+ s) sync_ports || return ;;
1305+ u) do_upgrade || return ;;
1306+ o) add_overlay "$pkg" || return ;;
1307+ g) generate_dmake_scripts "$pkg" || return ;;
1308+ f) show_info "$pkg" || return ;;
1309+ l)
1310+ next_c=$(printf '%s' "$chain" | cut -c$((i + 1)))
1311+ case "$next_c" in
1312+ a) list_all_full; return ;;
1313+ i) list_installed_full; return ;;
1314+ d) [ -n "$pkg" ] && list_deps "$pkg"; return ;;
1315+ o) list_orphans; return ;;
1316+ *) die "invalid list command: l$next_c (use la, li, ld, or lo)" ;;
1317+ esac
1318+ i=$((i + 1))
1319+ ;;
1320+ *)
1321+ call_extension "$c" "$pkg" || die "unknown command character: $c (no '$c' extension found)"
1322+ ;;
1323+ esac
1324+ done
1325+}
1326+
1327+# === MAIN ===
1328+main() {
1329+ if [ $# -eq 0 ]; then
1330+ cat <<EOF
1331+usage: $PROG_NAME [y] <cmd> <pkgs>
1332+ $PROG_NAME m|i|c|r|p|d|g <pkgs>
1333+ $PROG_NAME o|overlay <overlay-git-repo>
1334+ $PROG_NAME la|li|laf|lif|ld|lo|sp|f <pkgs>
1335+ $PROG_NAME s|u|pi|se|ar|lo
1336+ $PROG_NAME mic|dic <pkgs> (build+install+clean; d=no deps)
1337+EOF
1338+ exit 0
1339+ fi
1340+
1341+ case "${1:-}" in
1342+ y|-y|--yes)
1343+ DTR_SKIP_CONFIRM=1
1344+ shift
1345+ ;;
1346+ esac
1347+
1348+ local cmd="$1"
1349+ case "$cmd" in
1350+ y*)
1351+ DTR_SKIP_CONFIRM=1
1352+ cmd="${cmd#y}"
1353+ ;;
1354+ esac
1355+ shift
1356+
1357+ case "$cmd" in
1358+ chill)
1359+ chill "$0" && exit 0
1360+ ;;
1361+ laf|la)
1362+ list_all_full && exit 0
1363+ ;;
1364+ lif|li)
1365+ list_installed_full && exit 0
1366+ ;;
1367+ lo)
1368+ list_orphans && exit 0
1369+ ;;
1370+ s|sync)
1371+ sync_ports && exit 0
1372+ ;;
1373+ u|upgrade)
1374+ do_upgrade && exit 0
1375+ ;;
1376+ ar|autoremove)
1377+ spc autoremove && exit 0
1378+ ;;
1379+ pi|populate-info)
1380+ populate_info && exit 0
1381+ ;;
1382+ se|search)
1383+ [ $# -eq 0 ] && die "search query required"
1384+ search_packages "$*" && exit 0
1385+ ;;
1386+ o|overlay)
1387+ [ $# -eq 0 ] && die "overlay repository URL required"
1388+ add_overlay "$1" && exit 0
1389+ ;;
1390+ esac
1391+
1392+ # Check if command is valid before requiring package
1393+ case "$cmd" in
1394+ ld|sp|f|g|gen|m|make|i|install|c|clean|r|remove|p|purge|d|o|overlay)
1395+ [ $# -eq 0 ] && die "package required for '$cmd'"
1396+ ;;
1397+ *)
1398+ # Check if it's an extension or valid chain command
1399+ local ext_path is_valid=0
1400+ ext_path=$(find_extension "$cmd") && is_valid=1
1401+
1402+ # Check if it's a valid chain (only contains valid command chars)
1403+ if [ "$is_valid" -eq 0 ]; then
1404+ local i=0 c
1405+ while [ $i -lt ${#cmd} ]; do
1406+ c=$(printf '%s' "$cmd" | cut -c$((i + 1)))
1407+ case "$c" in
1408+ m|i|c|r|p|s|u|g|f|l|d|o) is_valid=1 ;;
1409+ *)
1410+ # Could still be an extension for this char
1411+ find_extension "$c" >/dev/null 2>&1 && is_valid=1 || is_valid=0
1412+ [ "$is_valid" -eq 0 ] && break
1413+ ;;
1414+ esac
1415+ i=$((i + 1))
1416+ done
1417+ fi
1418+
1419+ if [ "$is_valid" -eq 0 ]; then
1420+ die "invalid command: '$cmd'"
1421+ fi
1422+
1423+ [ $# -eq 0 ] && die "package required for '$cmd'"
1424+ ;;
1425+ esac
1426+
1427+ for pkg in "$@"; do
1428+ pkg=$(resolve_package_arg "$pkg")
1429+
1430+ case "$cmd" in
1431+ ld)
1432+ list_deps "$pkg"
1433+ ;;
1434+ sp)
1435+ local found
1436+ found=$(find_package "$pkg")
1437+ if [ -n "$found" ]; then
1438+ printf '%s\n' "$found"
1439+ else
1440+ printf 'not found\n'
1441+ fi
1442+ ;;
1443+ f)
1444+ show_info "$pkg"
1445+ ;;
1446+ g|gen)
1447+ generate_dmake_scripts "$pkg"
1448+ ;;
1449+ m|make)
1450+ do_make "$pkg"
1451+ ;;
1452+ i|install)
1453+ install_package "$pkg"
1454+ ;;
1455+ c|clean)
1456+ clean_package "$pkg"
1457+ ;;
1458+ r|remove)
1459+ remove_package "$pkg"
1460+ ;;
1461+ p|purge)
1462+ purge_package "$pkg"
1463+ ;;
1464+ d)
1465+ do_make_nodeps "$pkg"
1466+ ;;
1467+ *)
1468+ local ext_path
1469+ ext_path=$(find_extension "$cmd")
1470+ if [ -n "$ext_path" ]; then
1471+ "$ext_path" "$pkg"
1472+ else
1473+ process_chain "$cmd"
1474+ fi
1475+ ;;
1476+ esac
1477+ done
1478+
1479+ exit 0
1480+}
1481+
1482+main "$@"
A
bin/dwm
+0,
-0
+0,
-0
+2,
-0
1@@ -0,0 +1,2 @@
2+#!/bin/sh
3+ffmpeg -f fbdev -framerate 60 -i /dev/fb0 $HOME/fbvideo/$1
M
bin/fcg
+1,
-1
1@@ -1,4 +1,4 @@
2-#!/usr/bin/env -S guile --no-auto-compile
3+#!/bin/guile
4 !#
5 (use-modules (ice-9 popen)
6 (ice-9 rdelim)
M
bin/fehs
+1,
-1
1@@ -1,2 +1,2 @@
2 #!/bin/sh -eu
3-wget $1 -O -|swayimg -
4+curl $1 -o -| mpv -
+13,
-22
1@@ -1,34 +1,25 @@
2-#!/bin/sh -eu
3+#!/bin/sh -e
4 set -x
5
6-python3 - <<'PY'
7+#python3 - <<'PY'
8+echo '
9 colors = [
10- (40, 40, 40), # bg0 #282828
11- (60, 56, 54), # bg1 #3c3836
12- (80, 73, 69), # bg2 #504945
13- (102, 92, 84), # bg3 #665c54
14- (251, 241, 199), # fg0 #fbf1c7
15- (235, 219, 178), # fg1 #ebdbb2
16- (213, 196, 161), # fg2 #d5c4a1
17- (189, 174, 147), # fg3 #bdae93
18- (204, 36, 29), # red
19- (152, 151, 26), # green
20- (215, 153, 33), # yellow
21- (69, 133, 136), # blue
22- (177, 98, 134), # purple
23- (104, 157, 106), # aqua
24- (214, 93, 14), # orange
25- (146, 131, 116), # gray
26+colors.ok
27 ]
28
29-with open("/mastergooner/t/gruvbox.ppm", "wb") as f:
30+with open("home.ok/t/gruvbox.ppm", "wb") as f:
31 f.write(b"P6\n16 16\n255\n")
32 for color in colors:
33 f.write(bytes(color) * 16)
34-PY
35+' | sed "s/colors.ok/`termgruv`/" | sed "s#home.ok#$HOME#"| python3 -
36+
37+
38+ffmpeg -y -i "$1" \
39+ "$1.new.png"
40+# -vf scale=1024:768 \
41
42 ffmpeg -y \
43- -i "$1" \
44+ -i "$1.new.png" \
45 -i "$HOME/t/gruvbox.ppm" \
46 -filter_complex "[0:v][1:v]paletteuse=dither=sierra2_4a" \
47- "$2"
48+ "$2" && rm "$1.new.png"
+33,
-0
1@@ -0,0 +1,33 @@
2+#!/bin/sh
3+# foot.ini pallete generator for kmscon
4+
5+set -x
6+R="${R:-/home/31/bin/hrgb}"
7+main(){
8+ cat $3 \
9+ | grep -E 'regular|bright' \
10+ | sed 's/=/ /g' \
11+ | awk '{print $2}' \
12+ | sed 's/#.*//g'
13+}
14+
15+cp $1 $2
16+n=-1
17+for i in `main $*`
18+do
19+ n=$((n+1))
20+ sed -i "s/{color$n.strip}/`$R $i`/g" $2
21+done
22+
23+pain(){
24+ cat $1 \
25+ | grep $2 \
26+ | sed 's/=/ /g' \
27+ | awk '{print $2}' \
28+ | sed 's/#.*//g' \
29+ | head -1
30+}
31+
32+
33+sed -i "s#{colorbg.strip}#$($R `pain $3 background`)#g" $2
34+sed -i "s#{colorfg.strip}#$($R `pain $3 foreground`)#g" $2
M
bin/gark
+1,
-1
1@@ -1,4 +1,4 @@
2-#!/usr/bin/env -S guile --no-auto-compile
3+#!/bin/guile
4 !#
5 (use-modules (ice-9 hash-table)
6 (ice-9 rdelim)
M
bin/hrgb
+12,
-9
1@@ -1,4 +1,4 @@
2-#!/usr/bin/env -S guile --no-auto-compile
3+#!/bin/guile
4 !#
5 (use-modules (ice-9 format))
6
7@@ -8,21 +8,24 @@
8 "888822"
9 ))
10
11+;; (display "(")
12+
13 (let main (
14 (i 0)
15 )
16- (format #t "\x1b[48;2;~a;~a;~am"
17-
18- (string->number (substring str 0 2)16)
19- (string->number (substring str 2 4)16)
20- (string->number (substring str 4 6)16)
21- )
22+;; (format #t "\x1b[48;2;~a;~a;~am"
23+;;
24+;; (string->number (substring str 0 2)16)
25+;; (string->number (substring str 2 4)16)
26+;; (string->number (substring str 4 6)16)
27+;; )
28 (when (not (= i 6))
29 (format #t "~d"
30 (string->number (substring str i (+ i 2))16)
31 )
32- (when (not (= i 4)) (format #t " "))
33+ (when (not (= i 4)) (format #t ", "))
34 (main (+ i 2))
35 )
36 )
37-(format #t "\x1b[m~%")
38+
39+;;(format #t "),~%")
+4,
-0
1@@ -0,0 +1,4 @@
2+#!/bin/sh
3+
4+sh $HOME/bin/bin2/bar.sh | /bin/mojito \
5+ -g 1024x25+0+0 -f 'Fixed' -B '#222' -F '#c9a554'
+4,
-0
1@@ -0,0 +1,4 @@
2+#!/bin/sh
3+
4+sh $HOME/bin/bin2/bar1.sh | /bin/mojito \
5+ -g 25x768+0+0 -f 'Fixed' -B '#222' -F '#c9a554'
+33,
-16
1@@ -1,20 +1,37 @@
2-#!/usr/bin/env -S guile --no-auto-compile
3+#!/bin/guile
4 !#
5-(do ((n 0 (+ n 1)))
6- ((>= n 8))
7- (begin (format #t " \x1b[m\x1b[~am \x1b[m " (+ n 100)))
8- )(newline)
9+(let a (
10+ (n 0)
11+ )
12+ (when (< n 8)
13+ (begin (format #t " \x1b[m\x1b[~am \x1b[m " (+ n 100))
14+ (a (+ n 1))
15+ )
16+ ))(newline)
17
18-(do ((n 0 (+ n 1)))
19- ((>= n 2))
20- (do ((m 0 (+ m 1)))
21- ((>= m 8))
22- (format #t " \x1b[m\x1b[~am \x1b[m\x1b[~am \x1b[m"
23- (+ m 100) (+ m 40))
24- )(newline))
25+(let b (
26+ (n 0)
27+ )
28+ (when (< n 1)
29+ (let c (
30+ (m 0)
31+ )
32+ (when (< m 8)
33+ (format #t " \x1b[m\x1b[~am \x1b[m\x1b[~am \x1b[m"
34+ (+ m 100) (+ m 40))
35+ (c (+ m 1))
36+ )
37+ )
38+ (newline)
39+ (b (+ n 1))
40+ )
41+ )
42
43-(do ((n 0 (+ n 1)))
44- ((>= n 8))
45- (begin (format #t " \x1b[m\x1b[~am \x1b[m" (+ n 40)))
46+(let d (
47+ (n 0)
48+ )
49+ (when (< n 8)
50+ (begin (format #t " \x1b[m\x1b[~am \x1b[m" (+ n 40)))
51+ (d (+ n 1))
52+ )
53 )(newline)
54-
+1,
-0
1@@ -0,0 +1 @@
2+$HOME/bin/conty.sh $HOME/media/qutebrowser-portable/qutebrowser/qutebrowser
+6,
-31
1@@ -1,31 +1,6 @@
2-#!/usr/bin/env -S guile --no-auto-compile
3-!#
4-(use-modules (ice-9 popen)
5- (ice-9 rdelim)
6- (ice-9 string-fun)
7- (ice-9 regex)
8- (srfi srfi-1))
9-
10-(define (system-output . a)
11- (let* ((p (apply open-pipe* OPEN_READ a))
12- (s (read-string p)))
13- (close-pipe p)s))
14-
15-(let* (
16- (o (format #f "~a/s" (getenv "HOME")))
17- (nn (system-output "ls" "-1" o))
18- (nl '())
19- (n 0)
20- )
21- (set! n (string-split (string-replace-substring nn ".png" "") #\newline))
22- (set! nl
23- (filter (lambda (s)
24- (string-match "^[0-9]+$" s))
25- n)
26- )
27- (system* "grim" "-o" (format #f "~a/~a.png" o (+ (last nl) 1)))
28-
29-;; sort -n | last
30-;; n=`echo ${nn%%.*}+1|bc`
31-;; /mastergooner/.guix-profile/bin/scrot $@ -f $o/$n.png
32-)
33+#!/bin/sh
34+o=$1
35+nn=`/bin/ls -1 $o|sort -n|tail -n 1`
36+n=`echo ${nn%%.*}+1|bc`
37+printf $n
38+# /usr/pkg/bin/scrot $@ -f $o/$n.png
+18,
-6
1@@ -1,4 +1,4 @@
2-#!/usr/bin/env -S guile --no-auto-compile
3+#!/bin/guile
4 !#
5 ;; from pascalecu
6 (set! *random-state* (random-state-from-platform))
7@@ -13,12 +13,24 @@
8 (close-pipe p)s))
9
10 (let main (
11- (s (system-output "ls" "-1" (format #f "~a/m/w/" (getenv "HOME"))))
12+ (s (system-output "ls" "-1" (format #f "~a/media/w/" (getenv "HOME"))))
13+ (lw (format #f "~a/.lastwall" (getenv "HOME")))
14 (sl '())
15+ (wall "nothing")
16 )
17 (set! sl (string-split s #\newline))
18-
19- (format #t "~a/m/w/~a~%" (getenv "HOME") (list-ref sl (random
20- (- (length sl) 1)
21- )))
22+
23+ (set! wall (format #f "~a/media/w/~a~%" (getenv "HOME") (list-ref sl (random (- (length sl) 1)))))
24+
25+;; random until lastwall isnt the new randomly picked wall
26+ (let c
27+ (
28+ (l (call-with-input-file lw (lambda (f) (read-string f))))
29+ )
30+ (when (string=? wall l)
31+ (set! wall (format #f "~a/media/w/~a~%" (getenv "HOME") (list-ref sl (random (- (length sl) 1)))))
32+ (c l)
33+ ))
34+ (display wall)
35+ (call-with-output-file lw (lambda (f) (display wall f)))
36 )
A
bin/st
+0,
-0
+10,
-0
1@@ -0,0 +1,10 @@
2+export DISPLAY=:1
3+
4+{
5+ sleep 0.5
6+ aw `setwall`
7+ st &
8+ dwm &
9+}&
10+
11+Xfbdev :1
+17,
-0
1@@ -0,0 +1,17 @@
2+#!/bin/sh -eu
3+set -x
4+out=$HOME/video
5+
6+/bin/swcsnap record \
7+ -n "$((${2:-30}*60))" | ffmpeg \
8+ -y \
9+ -f rawvideo \
10+ -video_size 1024x768 \
11+ -framerate 60 \
12+ -pix_fmt bgra \
13+ -i pipe:0 \
14+ -c:v libx264 \
15+ -preset slow \
16+ -crf 18 \
17+ -pix_fmt yuv420p \
18+ "${out}/$1"
+14,
-0
1@@ -0,0 +1,14 @@
2+#!/bin/sh -eu
3+set -x
4+
5+out=$HOME/shot
6+
7+/bin/swcsnap image \
8+ "${out}/${1%.*}.ppm"
9+
10+{
11+ ffmpeg -y \
12+ -i "${out}/${1%.*}.ppm" \
13+ "${out}/$1"
14+}
15+rm -f "${out}/${1%.*}.ppm"
+16,
-0
1@@ -0,0 +1,16 @@
2+#!/bin/sh -eu
3+set -x
4+
5+out=$HOME/shot
6+dim=`slurp -f %wx%h+%x+%y`
7+
8+/bin/swcsnap image \
9+ "${out}/${1%.*}.ppm"
10+
11+{
12+ ffmpeg -y \
13+ -i "${out}/${1%.*}.ppm" \
14+ "${out}/${1%.*}.uncropped.png"
15+ gm convert "${out}/${1%.*}.uncropped.png" -crop $dim "${out}/$1"
16+}
17+rm -f "${out}/${1%.*}.ppm" "${out}/${1%.*}.uncropped.png"
+18,
-0
1@@ -0,0 +1,18 @@
2+#!/bin/sh
3+
4+main(){
5+ cat ${FILE:-$HOME/.config/foot/foot.ini} \
6+ |grep -E 'regular|bright' \
7+ |sed 's/=/ /g' \
8+ |awk '{print $2}' \
9+ |sed 's/#.*//g'
10+}
11+
12+n=-1
13+for i in `main`
14+do
15+ n=$((n+1))
16+ printf '('
17+ hrgb $i
18+ printf '),\n'
19+done
+24,
-0
1@@ -0,0 +1,24 @@
2+#!/bin/sh -eu
3+case ${1##*.} in
4+ m4a|mp3|wav|ogg|mp4|giv)
5+ exec mpv "$@"
6+ ;;
7+ png|jpeg|jpg|PNG|JPG|JPEG)
8+ exec mpv "$@"
9+ ;;
10+ c|scm|sh)
11+ exec emacs "$@"
12+ ;;
13+ fbgrab)
14+ fbgrab $HOME/fbshot/`$HOME/bin/scrot $HOME/fbshot/`.png 2>/dev/null &
15+ ;;
16+ drmcat)
17+ drmcat 2>/dev/null &
18+ ;;
19+ swcscr)
20+ swcscr `$HOME/bin/scrot $HOME/shot/`.png 2>/dev/null &
21+ ;;
22+ *)
23+ exec emacs "$@"
24+ ;;
25+esac
+2,
-0
1@@ -0,0 +1,2 @@
2+#!/bin/sh
3+conty zenity $@
M
emacs
+13,
-18
1@@ -16,18 +16,16 @@
2 "57a29645c35ae5ce1660d5987d3da5869b048477a7801ce7ab57bfb25ce12d3e"
3 "d89e15a34261019eec9072575d8a924185c27d3da64899905f8548cbd9491a36"
4 default))
5- '(display-line-numbers-type nil)
6 '(fringe-mode 0 nil (fringe))
7- '(global-display-line-numbers-mode t)
8 '(line-number-mode t)
9 '(menu-bar-mode nil)
10 '(package-selected-packages
11 '(basic-mode circe gnu-elpa-keyring-update go-mode gruvbox-theme
12- markdown-mode vterm whitespace-cleanup-mode windresize
13- miasma-theme
14+ lisp-ts-mode markdown-mode markdown-ts-mode meson-mode
15+ miasma-theme paper-theme slime vterm
16+ whitespace-cleanup-mode windresize xterm-color
17 zig-mode))
18 '(scroll-bar-mode nil)
19- '(tool-bar-mode nil)
20 '(tooltip-mode nil)
21 '(warning-suppress-types '((native-compiler))))
22
23@@ -40,20 +38,18 @@
24 ;; VIEW VIEW VIEW VIEW VIEW
25
26 (defface my-paren-face
27- '((t (:foreground "#3f3f3f")))
28+ '((t (:foreground "#444444")))
29 "Face for parentheses.")
30
31 (font-lock-add-keywords
32 'scheme-mode
33 '(("(\\|)" 0 'my-paren-face prepend)))
34
35-(load-theme 'miasma :no-confirm)
36 (setq inhibit-startup-screen t)
37-(set-face-attribute 'default nil :family "Go Mono")
38-(set-face-attribute 'default nil :height 90)
39+;; (set-face-attribute 'default nil :family "Go Mono")
40+;; (set-face-attribute 'default nil :height 90)
41
42 (show-paren-mode 1)
43-
44 (set-face-attribute 'show-paren-match nil
45 :foreground "#fabd2f"
46 :background "#3c3836"
47@@ -85,8 +81,8 @@
48
49 (setq-default mode-line-format nil) ;; no modeline
50
51-(setq display-line-numbers-type 'relative)
52-(global-display-line-numbers-mode 0) ;; relative line numbers
53+(setq display-line-numbers-type 'absolute)
54+(global-display-line-numbers-mode t) ;; relative line numbers
55
56 ;; ________________________
57 ;; KEYBINDS KEYBINDS KEYBINDS
58@@ -108,9 +104,8 @@
59
60
61 (message "loaded config")
62-(custom-set-faces
63- ;; custom-set-faces was added by Custom.
64- ;; If you edit it by hand, you could mess it up, so be careful.
65- ;; Your init file should contain only one such instance.
66- ;; If there is more than one, they won't work right.
67- )
68+
69+;; alas,
70+;;(load-theme 'gruvbox-dark-hard :no-confirm)
71+(add-to-list 'custom-theme-load-path (concat user-emacs-directory "/nonpackaged/"))
72+(load-theme 'miasma :no-confirm)
M
foot.ini
+30,
-20
1@@ -1,25 +1,35 @@
2+# srcery
3 [main]
4-font=PxPlus IBM VGA 8x16:size=12:style=Regular
5+pad=0x0
6 initial-window-size-pixels=400x300
7-resize-by-cells=no
8+resize-by-cells=yes
9+font=Iosevka:size=9
10
11 [colors-dark]
12-background=282828
13-foreground=ebdbb2
14-regular0=282828
15-regular1=cc241d
16-regular2=98971a
17-regular3=d79921
18-regular4=458588
19-regular5=b16286
20-regular6=689d6a
21-regular7=a89984
22-bright0=928374
23-bright1=fb4934
24-bright2=b8bb26
25-bright3=fabd2f
26-bright4=83a598
27-bright5=d3869b
28-bright6=8ec07c
29-bright7=ebdbb2
30+alpha=0.85
31
32+[colors-light]
33+alpha=0.85
34+
35+# colors (miasma) https://github.com/xero/miasma.nvim
36+
37+# Normal colors
38+[colors-dark]
39+background=222222
40+foreground=d7c483
41+regular0=222222
42+regular1=685742
43+regular2=5f875f
44+regular3=b36d43
45+regular4=78824b
46+regular5=bb7744
47+regular6=c9a554
48+regular7=d7c483
49+bright0=666666
50+bright1=685742
51+bright2=5f875f
52+bright3=b36d43
53+bright4=78824b
54+bright5=bb7744
55+bright6=c9a554
56+bright7=d7c483