~hutzdog/guix-dotfiles

eba3455013bccded48e8d89c75031f8f3a277a72 — Danielle Hutzley 10 months ago 249e475 master
pre-init: add user shell, terminal, and basic Wayland compositor support
A :w => :w +32 -0
@@ 0,0 1,32 @@
; Terminal emulator support
(define-module (hutzdog guix services home terminals)
               #:use-module (gnu home services)
               #:use-module (gnu packages base)
               #:use-module (gnu services configuration)
               #:use-module (guix gexp)
               #:use-module (guix packages)
               #:use-module (guix records)
               #:use-module (hutzdog guix lib)
               #:use-module (ice-9 match)
               #:export (home-foot-configuration
                         home-foot-service-type))

(define-syntax define-foot-serializer
 (lambda (x)
  (syntax-case x ()
   ((_ typ) #`(define (#,(symbol-append 'serialize- typ) key val) (string-append key "=" (#,(symbol-append typ '->string) val)))))))

(define-maybe file-like)

(define-configuration home-foot-configuration
  (package (package foot) "The Foot terminal package to use")
  (shell maybe-file-like "The shell to use with Foot")
  (config (text-config '()) "List of file-like objects to configure Foot"))

(define (home-foot-config cfg)
 (computed-file "foot-config.ini"
  #~(let (())
     (with-output-to-file "foot-config.ini"
      (if #$(maybe-value-set (home-foot-configuration-shell cfg))
       (display "shell="#$(home-foot-configuration-shell cfg)))
      (display (serialize-configuration )))))

M Makefile => Makefile +51 -7
@@ 12,13 12,21 @@ define COMPILE_OS
endef
export COMPILE_OS

_fill-compile-os-template:
	@echo "$$COMPILE_OS" \
		| sed -e "s/<GUIX_CONFIG>/$(GUIX_CONFIG)/"

build-system: export EXPR = $(shell $(MAKE) -s _fill-compile-os-template)
build-system: tangle
	./scripts/guix-wrapped.sh system build -v $(VERBOSE) -e \
		"$$(echo "$$COMPILE_OS" | sed -e "s/<GUIX_CONFIG>/$(GUIX_CONFIG)/")"
	./scripts/guix-wrapped.sh system build -v $(VERBOSE) -e "$$EXPR"

build-system-vm: export EXPR = $(shell $(MAKE) -s _fill-compile-os-template)
build-system-vm: tangle
	./scripts/guix-wrapped.sh system vm -v $(VERBOSE) -e \
		"$$(echo "$$COMPILE_OS" | sed -e "s/<GUIX_CONFIG>/$(GUIX_CONFIG)/")"
	./scripts/guix-wrapped.sh system vm -v $(VERBOSE) -e "$$EXPR"

reconfigure-system: export EXPR = $(shell $(MAKE) -s _fill-compile-os-template)
reconfigure-system: tangle
	./scripts/guix-wrapped.sh system reconfigure -v $(VERBOSE) -e "$$EXPR"

define COMPILE_USER
(begin


@@ 30,13 38,49 @@ define COMPILE_USER
endef
export COMPILE_USER

_fill-compile-user-template:
	@echo "$$COMPILE_USER" \
		| sed -e "s/<GUIX_CONFIG>/$(GUIX_CONFIG)/" \
		| sed -e "s/<USER_NAME>/$(USER)/"

define LIST_USERS
(begin
	(use-modules (hutzdog guix lib))
	(for-each display
		(composed-system-user-list (load "<PWD>/out/configs/<GUIX_CONFIG>.scm"))))
endef
export LIST_USERS

_fill-list-users-template:
	echo "$$LIST_USERS" \
		| sed -e "s/<GUIX_CONFIG>/$(GUIX_CONFIG)/" \
		| sed -e "s|<PWD>|$(PWD)|"

build-user: export EXPR = $(shell $(MAKE) -s _fill-compile-user-template)
build-user: tangle
	./scripts/guix-wrapped.sh home build -v $(VERBOSE) -e \
		"$$(echo "$$COMPILE_USER" | sed -e "s/<GUIX_CONFIG>/$(GUIX_CONFIG)/" | sed -e "s/<USER_NAME>/$(USER)/")"
	./scripts/guix-wrapped.sh home build -v $(VERBOSE) -e "$$EXPR"

container-user: export EXPR = $(shell $(MAKE) -s _fill-compile-user-template)
container-user: tangle
	./scripts/guix-wrapped.sh home container -v $(VERBOSE) -e "$$EXPR"

reconfigure-user: export EXPR = $(shell $(MAKE) -s _fill-compile-user-template)
reconfigure-user: tangle
	./scripts/guix-wrapped.sh home reconfigure -v $(VERBOSE) -e "$$EXPR"

list-users: export TMPFILE := $(shell mktemp)
list-users: export EXPR = $(shell $(MAKE) -s _fill-list-users-template)
list-users: tangle
	@echo "$$EXPR" > "$(TMPFILE)"
	@./scripts/guix-wrapped.sh repl -- "$(TMPFILE)" 2>/dev/null
	@rm "$(TMPFILE)"

~/.config/guix/channels.scm: tangle
	mkdir -p `dirname $@`
	cp out/channels.scm $@

install: ~/.config/guix/channels.scm
install: export USERS = $(shell $(MAKE) -s list-users 2>/dev/null)
install: tangle ~/.config/guix/channels.scm reconfigure-system
	for USER in $USERS; do; \
		su --preserve-environment -c "$(MAKE) reconfigure-user USER=$$USER"; \
	done

M modules/hutzdog/guix/services/home/shells.scm => modules/hutzdog/guix/services/home/shells.scm +36 -26
@@ 1,5 1,6 @@
(define-module (hutzdog guix services home shells)
               #:use-module (gnu home services)
               #:use-module (gnu packages base)
               #:use-module (gnu packages shells)
               #:use-module (gnu services configuration)
               #:use-module (guix gexp)


@@ 24,8 25,8 @@
(define-configuration home-rc-configuration
  (package (package rc)
           "The Plan 9 RC package to use")
  (posix-sh-package (package dash)
                    "The POSIX compliant shell used to load Guix environment info")
  (posix-sh (file-like (file-append dash "/bin/dash"))
            "The POSIX compliant shell used to load Guix environment info")
  (guix-defaults? (boolean #t)
                  "Use sane defaults (tries to be equivalent to the Bash counterpart)")
  (environment-variables (alist '())


@@ 33,33 34,32 @@
                         (serializer rc-serialize-environment-variables))
  (profile (text-config '())
           "List of file-like objects to load exclusively on login.
            Loaded by the rc-init wrapper script, roughly equivalent to .bash-profile")
            Loaded by the rc-init wrapper script, and can be used to spawn the window manager")
  (rcrc (text-config '())
        "List of file-like objects to load at shell startup, roughly equivalent to .bashrc"))
        "List of file-like objects to load at shell startup, roughly equivalent to .bashrc
         NOTE: this assumes either the use of the @command{rc-login} wrapper script or the use of @command{rc -l}"))


(define serialize-rc-configuration-field
 (make-configuration-serializer home-rc-configuration-fields))

(define (rc-file-rcrc cfg)
  (mixed-text-file "rcrc" "\
if (~ $RC_INIT 1) {
  if (~ $rc_guix_env_sourced) {
    rc_guix_env_sourced=1
    exec "(home-rc-configuration-posix-sh-package cfg)"/bin/sh -lc '"(home-rc-configuration-package cfg)"/bin/rc -l '^$\"*
  }
  "(serialize-rc-configuration-field cfg 'profile)"
}
"
(if (home-rc-configuration-guix-defaults? cfg) "\
(define %rc-defaults
 (mixed-text-file "rcrc-defaults" "\
fn set_prompt {
  env=local ()
  if (~ $GUIX_ENVIRONMENT) {
    env=' '$GUIX_ENVIRONMENT' [env] '
  if (~ $GUIX_ENVIRONMENT ?*) {
    guix_env=$GUIX_ENVIRONMENT' [env] '
  }

  if (test -f /etc/hostname) {
    hostname=`{cat /etc/hostname}
  } else {
    hostname=localhost
  }

  prompt=`{whoami}@{hostname}: {pwd | sed -e 's|/home/$USER|~|'}$env%`
  prompt=(`{"coreutils"/bin/whoami}^' @ '^$hostname^': '^`{pwd}^$guix_env^' % ' '> ')
}
set_prompt

fn cd {
  builtin cd $*


@@ 68,24 68,34 @@ fn cd {

fn ls {
  env ls -lh --color $*
}"))

(define (rc-file-rcrc cfg)
 (mixed-text-file "rcrc" "\
if (~ $rc_guix_env_sourced) {
  rc_guix_env_sourced=1
  exec "(home-rc-configuration-posix-sh cfg)" -lc '"(home-rc-configuration-package cfg)"/bin/rc -l '^$\"*
}
")"
"(if (home-rc-configuration-guix-defaults? cfg) ". ")"\
"(if (home-rc-configuration-guix-defaults? cfg) %rc-defaults)"

"
(serialize-rc-configuration-field cfg 'environment)
(serialize-rc-configuration-field cfg 'rcrc)))
"(serialize-rc-configuration-field cfg 'environment)"
"(serialize-rc-configuration-field cfg 'rcrc)"
if (~ $RC_INIT 1) {
  "(serialize-rc-configuration-field cfg 'profile)"
}
"))

(define (rc-files-sv cfg)
(define (rc-config-files-sv cfg)
  `((".rcrc" ,(rc-file-rcrc cfg))))

(define (rc-packages-sv cfg)
  (list (home-rc-configuration-package cfg)
        (home-rc-configuration-posix-sh-package cfg)))
  (list (home-rc-configuration-package cfg)))

(define home-rc-service-type
 (service-type (name 'home-rc)
               (extensions
                (list (service-extension home-files-service-type rc-files-sv)
                (list (service-extension home-files-service-type rc-config-files-sv)
                      (service-extension home-profile-service-type rc-packages-sv)))
               (default-value (home-rc-configuration))
               (description "Install and configure RC, the Plan 9 shell")))

A modules/hutzdog/guix/services/home/terminals.scm => modules/hutzdog/guix/services/home/terminals.scm +45 -0
@@ 0,0 1,45 @@
; Terminal emulator support
(define-module (hutzdog guix services home terminals)
               #:use-module (gnu home services)
               #:use-module (gnu packages base)
               #:use-module (gnu packages terminals)
               #:use-module (gnu services configuration)
               #:use-module (guix gexp)
               #:use-module (guix packages)
               #:use-module (guix records)
               #:use-module (hutzdog guix lib)
               #:use-module (ice-9 match)
               #:export (home-foot-configuration
                         home-foot-service-type))

(define-maybe file-like)

(define-configuration home-foot-configuration
  (package (package foot) "The Foot terminal package to use")
  (shell maybe-file-like "The shell to use with Foot")
  (config (text-config '()) "List of file-like objects to configure Foot"))

(define (foot-file-foot.ini cfg)
 (computed-file "foot.ini"
  (let ((shell (home-foot-configuration-shell cfg))
        (config (home-foot-configuration-config cfg)))
     #~(with-output-to-file #$output
        (lambda ()
         (when #$(maybe-value-set? shell)
          (display "shell="#$shell))

         (display #$(serialize-text-config "config" config)))))))

(define (foot-config-files-sv cfg)
 `(("foot/foot.ini" ,(foot-file-foot.ini cfg))))

(define (foot-packages-sv cfg)
  (list (home-foot-configuration-package cfg)))

(define home-foot-service-type
 (service-type (name 'home-foot)
               (extensions
                (list (service-extension home-xdg-configuration-files-service-type foot-config-files-sv)
                      (service-extension home-profile-service-type foot-packages-sv)))
               (default-value (home-foot-configuration))
               (description "Install and configure the Foot terminal emulator")))

A modules/hutzdog/guix/services/home/waybar.scm => modules/hutzdog/guix/services/home/waybar.scm +39 -0
@@ 0,0 1,39 @@
(define-module (hutzdog guix services home waybar)
               #:use-module (gnu home services)
               #:use-module (gnu packages base)
               #:use-module (gnu packages guile)
               #:use-module (gnu packages wm)
               #:use-module (gnu services configuration)
               #:use-module (guix gexp)
               #:use-module (guix packages)
               #:use-module (guix records)
               #:use-module (hutzdog guix lib)
               #:export (home-waybar-configuration
                         home-waybar-service-type))

(define-configuration/no-serialization home-waybar-configuration
 (package (package waybar) "The waybar package to use")
 (config (gexp #~'()) "The JSON configuration to use (in G-expression form)"))

(define (waybar-file-config cfg)
 (let ((config-file (home-waybar-configuration-config cfg)))
  (with-extensions (list guile-json-4)
   (computed-file "config"
    #~(begin
       (use-modules (json))
       (with-output-to-file #$output
        (lambda () (scm->json #$config-file))))))))

(define (waybar-config-files-sv cfg)
 `(("waybar/config" ,(waybar-file-config cfg))))

(define (waybar-packages-sv cfg)
  (list (home-waybar-configuration-package cfg)))

(define home-waybar-service-type
 (service-type (name 'home-waybar)
               (extensions
                (list (service-extension home-xdg-configuration-files-service-type waybar-config-files-sv)
                      (service-extension home-profile-service-type waybar-packages-sv)))
               (default-value (home-waybar-configuration))
               (description "Install and configure waybar")))

M modules/hutzdog/guix/services/home/wm.scm => modules/hutzdog/guix/services/home/wm.scm +3 -7
@@ 14,18 14,14 @@
 (list-of package?))
(define (serialize-package-list name val) "")

(define-configuration home-river-configuration
(define-configuration/no-serialization home-river-configuration
 (package (package river) "The River package to use")
 (extra-packages (package-list '())
                 "Additional packages to install (e.g. script interpreter)")
 (config (text-config '()) "The file to use as an init script"))

(define serialize-river-configuration-fields
 (make-configuration-serializer home-river-configuration-fields))
 (config (gexp #~()) "The G-expression to use as an init script"))

(define (river-file-init cfg)
 (mixed-text-file "river-init"
  (serialize-river-configuration-fields cfg '(config))))
 (program-file "river-init" (home-river-configuration-config cfg)))

(define (river-files-sv cfg)
 `(("river/init" ,(river-file-init cfg))))

A modules/hutzdog/guix/themes/lib.scm => modules/hutzdog/guix/themes/lib.scm +71 -0
@@ 0,0 1,71 @@
(define-module (hutzdog guix themes lib)
               #:use-module (guix records)
               #:use-module (ice-9 match)
               #:export (base16-theme
                         make-base16-theme
                         base16-theme?
                         theme-base00
                         theme-base01
                         theme-base02
                         theme-base03
                         theme-base04
                         theme-base05
                         theme-base06
                         theme-base07
                         theme-base08
                         theme-base09
                         theme-base0A
                         theme-base0B
                         theme-base0C
                         theme-base0D
                         theme-base0E
                         theme-base0F
                         theme-background
                         theme-foreground
                         theme-accent))

(define-record-type* <base16-theme> base16-theme
  make-base16-theme
  base16-theme?
  (base00 theme-base00)
  (base01 theme-base01)
  (base02 theme-base02)
  (base03 theme-base03)
  (base04 theme-base04)
  (base05 theme-base05)
  (base06 theme-base06)
  (base07 theme-base07)
  (base08 theme-base08)
  (base09 theme-base09)
  (base0A theme-base0A)
  (base0B theme-base0B)
  (base0C theme-base0C)
  (base0D theme-base0D)
  (base0E theme-base0E)
  (base0F theme-base0F))

(define* (theme-background theme #:key (modifier 'dark))
 (let ((fun (match modifier
                   ('dark theme-base00)
                   ('lighter theme-base01)
                   ('light theme-base07)
                   ('selection theme-base02))))
   (fun theme)))

(define* (theme-foreground theme #:key (modifier 'default))
 (let ((fun (match modifier
                   ('dark theme-base04)
                   ('default theme-base05)
                   ('light theme-base06))))
   (fun theme)))

(define (theme-accent theme acc)
 (let ((fun (match acc ((or 'text 'variable) theme-base08)
                       ((or 'link 'number) theme-base09)
                       ((or 'bold 'class) theme-base0A)
                       ((or 'code 'string) theme-base0B)
                       ((or 'quotation 'regex) theme-base0C)
                       ((or 'heading 'function) theme-base0D)
                       ((or 'italic 'keyword) theme-base0E)
                       ((or 'embedded-tag 'deprecated) theme-base0E))))
   (fun theme)))

A modules/hutzdog/guix/themes/nord.scm => modules/hutzdog/guix/themes/nord.scm +8 -0
@@ 0,0 1,8 @@
(define-module (hutzdog guix themes nord)
               #:use-module (hutzdog guix themes lib)
               #:export (nord-theme))

(define nord-theme
 (make-base16-theme
  "2E3440" "3B4252" "434C5E" "4C566A" "D8DEE9" "E5E9F0" "ECEFF4" "8FBCBB"
  "BF616A" "D08770" "EBCB8B" "A3BE8C" "88C0D0" "81A1C1" "B48EAD" "5E81AC"))

M out/modules/hutzdog/guix/services/home/shells.scm => out/modules/hutzdog/guix/services/home/shells.scm +36 -26
@@ 1,5 1,6 @@
(define-module (hutzdog guix services home shells)
               #:use-module (gnu home services)
               #:use-module (gnu packages base)
               #:use-module (gnu packages shells)
               #:use-module (gnu services configuration)
               #:use-module (guix gexp)


@@ 24,8 25,8 @@
(define-configuration home-rc-configuration
  (package (package rc)
           "The Plan 9 RC package to use")
  (posix-sh-package (package dash)
                    "The POSIX compliant shell used to load Guix environment info")
  (posix-sh (file-like (file-append dash "/bin/dash"))
            "The POSIX compliant shell used to load Guix environment info")
  (guix-defaults? (boolean #t)
                  "Use sane defaults (tries to be equivalent to the Bash counterpart)")
  (environment-variables (alist '())


@@ 33,33 34,32 @@
                         (serializer rc-serialize-environment-variables))
  (profile (text-config '())
           "List of file-like objects to load exclusively on login.
            Loaded by the rc-init wrapper script, roughly equivalent to .bash-profile")
            Loaded by the rc-init wrapper script, and can be used to spawn the window manager")
  (rcrc (text-config '())
        "List of file-like objects to load at shell startup, roughly equivalent to .bashrc"))
        "List of file-like objects to load at shell startup, roughly equivalent to .bashrc
         NOTE: this assumes either the use of the @command{rc-login} wrapper script or the use of @command{rc -l}"))


(define serialize-rc-configuration-field
 (make-configuration-serializer home-rc-configuration-fields))

(define (rc-file-rcrc cfg)
  (mixed-text-file "rcrc" "\
if (~ $RC_INIT 1) {
  if (~ $rc_guix_env_sourced) {
    rc_guix_env_sourced=1
    exec "(home-rc-configuration-posix-sh-package cfg)"/bin/sh -lc '"(home-rc-configuration-package cfg)"/bin/rc -l '^$\"*
  }
  "(serialize-rc-configuration-field cfg 'profile)"
}
"
(if (home-rc-configuration-guix-defaults? cfg) "\
(define %rc-defaults
 (mixed-text-file "rcrc-defaults" "\
fn set_prompt {
  env=local ()
  if (~ $GUIX_ENVIRONMENT) {
    env=' '$GUIX_ENVIRONMENT' [env] '
  if (~ $GUIX_ENVIRONMENT ?*) {
    guix_env=$GUIX_ENVIRONMENT' [env] '
  }

  if (test -f /etc/hostname) {
    hostname=`{cat /etc/hostname}
  } else {
    hostname=localhost
  }

  prompt=`{whoami}@{hostname}: {pwd | sed -e 's|/home/$USER|~|'}$env%`
  prompt=(`{"coreutils"/bin/whoami}^' @ '^$hostname^': '^`{pwd}^$guix_env^' % ' '> ')
}
set_prompt

fn cd {
  builtin cd $*


@@ 68,24 68,34 @@ fn cd {

fn ls {
  env ls -lh --color $*
}"))

(define (rc-file-rcrc cfg)
 (mixed-text-file "rcrc" "\
if (~ $rc_guix_env_sourced) {
  rc_guix_env_sourced=1
  exec "(home-rc-configuration-posix-sh cfg)" -lc '"(home-rc-configuration-package cfg)"/bin/rc -l '^$\"*
}
")"
"(if (home-rc-configuration-guix-defaults? cfg) ". ")"\
"(if (home-rc-configuration-guix-defaults? cfg) %rc-defaults)"

"
(serialize-rc-configuration-field cfg 'environment)
(serialize-rc-configuration-field cfg 'rcrc)))
"(serialize-rc-configuration-field cfg 'environment)"
"(serialize-rc-configuration-field cfg 'rcrc)"
if (~ $RC_INIT 1) {
  "(serialize-rc-configuration-field cfg 'profile)"
}
"))

(define (rc-files-sv cfg)
(define (rc-config-files-sv cfg)
  `((".rcrc" ,(rc-file-rcrc cfg))))

(define (rc-packages-sv cfg)
  (list (home-rc-configuration-package cfg)
        (home-rc-configuration-posix-sh-package cfg)))
  (list (home-rc-configuration-package cfg)))

(define home-rc-service-type
 (service-type (name 'home-rc)
               (extensions
                (list (service-extension home-files-service-type rc-files-sv)
                (list (service-extension home-files-service-type rc-config-files-sv)
                      (service-extension home-profile-service-type rc-packages-sv)))
               (default-value (home-rc-configuration))
               (description "Install and configure RC, the Plan 9 shell")))

A out/modules/hutzdog/guix/services/home/terminals.scm => out/modules/hutzdog/guix/services/home/terminals.scm +45 -0
@@ 0,0 1,45 @@
; Terminal emulator support
(define-module (hutzdog guix services home terminals)
               #:use-module (gnu home services)
               #:use-module (gnu packages base)
               #:use-module (gnu packages terminals)
               #:use-module (gnu services configuration)
               #:use-module (guix gexp)
               #:use-module (guix packages)
               #:use-module (guix records)
               #:use-module (hutzdog guix lib)
               #:use-module (ice-9 match)
               #:export (home-foot-configuration
                         home-foot-service-type))

(define-maybe file-like)

(define-configuration home-foot-configuration
  (package (package foot) "The Foot terminal package to use")
  (shell maybe-file-like "The shell to use with Foot")
  (config (text-config '()) "List of file-like objects to configure Foot"))

(define (foot-file-foot.ini cfg)
 (computed-file "foot.ini"
  (let ((shell (home-foot-configuration-shell cfg))
        (config (home-foot-configuration-config cfg)))
     #~(with-output-to-file #$output
        (lambda ()
         (when #$(maybe-value-set? shell)
          (display "shell="#$shell))

         (display #$(serialize-text-config "config" config)))))))

(define (foot-config-files-sv cfg)
 `(("foot/foot.ini" ,(foot-file-foot.ini cfg))))

(define (foot-packages-sv cfg)
  (list (home-foot-configuration-package cfg)))

(define home-foot-service-type
 (service-type (name 'home-foot)
               (extensions
                (list (service-extension home-xdg-configuration-files-service-type foot-config-files-sv)
                      (service-extension home-profile-service-type foot-packages-sv)))
               (default-value (home-foot-configuration))
               (description "Install and configure the Foot terminal emulator")))

A out/modules/hutzdog/guix/services/home/waybar.scm => out/modules/hutzdog/guix/services/home/waybar.scm +39 -0
@@ 0,0 1,39 @@
(define-module (hutzdog guix services home waybar)
               #:use-module (gnu home services)
               #:use-module (gnu packages base)
               #:use-module (gnu packages guile)
               #:use-module (gnu packages wm)
               #:use-module (gnu services configuration)
               #:use-module (guix gexp)
               #:use-module (guix packages)
               #:use-module (guix records)
               #:use-module (hutzdog guix lib)
               #:export (home-waybar-configuration
                         home-waybar-service-type))

(define-configuration/no-serialization home-waybar-configuration
 (package (package waybar) "The waybar package to use")
 (config (gexp #~'()) "The JSON configuration to use (in G-expression form)"))

(define (waybar-file-config cfg)
 (let ((config-file (home-waybar-configuration-config cfg)))
  (with-extensions (list guile-json-4)
   (computed-file "config"
    #~(begin
       (use-modules (json))
       (with-output-to-file #$output
        (lambda () (scm->json #$config-file))))))))

(define (waybar-config-files-sv cfg)
 `(("waybar/config" ,(waybar-file-config cfg))))

(define (waybar-packages-sv cfg)
  (list (home-waybar-configuration-package cfg)))

(define home-waybar-service-type
 (service-type (name 'home-waybar)
               (extensions
                (list (service-extension home-xdg-configuration-files-service-type waybar-config-files-sv)
                      (service-extension home-profile-service-type waybar-packages-sv)))
               (default-value (home-waybar-configuration))
               (description "Install and configure waybar")))

M out/modules/hutzdog/guix/services/home/wm.scm => out/modules/hutzdog/guix/services/home/wm.scm +3 -7
@@ 14,18 14,14 @@
 (list-of package?))
(define (serialize-package-list name val) "")

(define-configuration home-river-configuration
(define-configuration/no-serialization home-river-configuration
 (package (package river) "The River package to use")
 (extra-packages (package-list '())
                 "Additional packages to install (e.g. script interpreter)")
 (config (text-config '()) "The file to use as an init script"))

(define serialize-river-configuration-fields
 (make-configuration-serializer home-river-configuration-fields))
 (config (gexp #~()) "The G-expression to use as an init script"))

(define (river-file-init cfg)
 (mixed-text-file "river-init"
  (serialize-river-configuration-fields cfg '(config))))
 (program-file "river-init" (home-river-configuration-config cfg)))

(define (river-files-sv cfg)
 `(("river/init" ,(river-file-init cfg))))

A out/modules/hutzdog/guix/themes/lib.scm => out/modules/hutzdog/guix/themes/lib.scm +71 -0
@@ 0,0 1,71 @@
(define-module (hutzdog guix themes lib)
               #:use-module (guix records)
               #:use-module (ice-9 match)
               #:export (base16-theme
                         make-base16-theme
                         base16-theme?
                         theme-base00
                         theme-base01
                         theme-base02
                         theme-base03
                         theme-base04
                         theme-base05
                         theme-base06
                         theme-base07
                         theme-base08
                         theme-base09
                         theme-base0A
                         theme-base0B
                         theme-base0C
                         theme-base0D
                         theme-base0E
                         theme-base0F
                         theme-background
                         theme-foreground
                         theme-accent))

(define-record-type* <base16-theme> base16-theme
  make-base16-theme
  base16-theme?
  (base00 theme-base00)
  (base01 theme-base01)
  (base02 theme-base02)
  (base03 theme-base03)
  (base04 theme-base04)
  (base05 theme-base05)
  (base06 theme-base06)
  (base07 theme-base07)
  (base08 theme-base08)
  (base09 theme-base09)
  (base0A theme-base0A)
  (base0B theme-base0B)
  (base0C theme-base0C)
  (base0D theme-base0D)
  (base0E theme-base0E)
  (base0F theme-base0F))

(define* (theme-background theme #:key (modifier 'dark))
 (let ((fun (match modifier
                   ('dark theme-base00)
                   ('lighter theme-base01)
                   ('light theme-base07)
                   ('selection theme-base02))))
   (fun theme)))

(define* (theme-foreground theme #:key (modifier 'default))
 (let ((fun (match modifier
                   ('dark theme-base04)
                   ('default theme-base05)
                   ('light theme-base06))))
   (fun theme)))

(define (theme-accent theme acc)
 (let ((fun (match acc ((or 'text 'variable) theme-base08)
                       ((or 'link 'number) theme-base09)
                       ((or 'bold 'class) theme-base0A)
                       ((or 'code 'string) theme-base0B)
                       ((or 'quotation 'regex) theme-base0C)
                       ((or 'heading 'function) theme-base0D)
                       ((or 'italic 'keyword) theme-base0E)
                       ((or 'embedded-tag 'deprecated) theme-base0E))))
   (fun theme)))

A out/modules/hutzdog/guix/themes/nord.scm => out/modules/hutzdog/guix/themes/nord.scm +8 -0
@@ 0,0 1,8 @@
(define-module (hutzdog guix themes nord)
               #:use-module (hutzdog guix themes lib)
               #:export (nord-theme))

(define nord-theme
 (make-base16-theme
  "2E3440" "3B4252" "434C5E" "4C566A" "D8DEE9" "E5E9F0" "ECEFF4" "8FBCBB"
  "BF616A" "D08770" "EBCB8B" "A3BE8C" "88C0D0" "81A1C1" "B48EAD" "5E81AC"))

M out/users/enderger.scm => out/users/enderger.scm +193 -7
@@ 2,13 2,22 @@
 (srfi srfi-1)
 (gnu)
 (gnu home)
 (gnu packages linux)
 (gnu packages shells)
 (gnu packages terminals)
 (gnu packages wm)
 (hutzdog guix packages wrappers)
 (hutzdog guix packages wm)
 (hutzdog guix services home shells)
 (hutzdog guix services home terminals)
 (hutzdog guix services home waybar)
 (hutzdog guix services home wm)
 (hutzdog guix themes lib)
 (hutzdog guix themes nord)
 (hutzdog guix lib))

(define %user-theme nord-theme)

(define %user-packages '())
(define* (add-user-packages! #:rest pkgs)
  (set! %user-packages (append pkgs %user-packages)))


@@ 17,14 26,135 @@
  (name "enderger")
  (group "enderger")
  (shell (file-append rc-login "/bin/rc-login"))))
(define %rc-profile
 (mixed-text-file "rc_profile"
  (file-append river "/bin/river")))

(define %river-spawn-scratchpad
 (program-file "spawn-scratchpad"
  #~(let* ((riverctl #$(file-append river "/bin/riverctl"))
           (scratch (cadr (command-line)))
           (command (cddr (command-line)))
           (tag-mask (ash #b1 (+ (string->number scratch) 9))))
     (display scratch)
     ; Send terminal to scratchpad
     (system* riverctl "set-view-tags" (number->string tag-mask))

     ; Spawn the command on the current tag
     (apply system* command)

     ; Grab scratchpad window and move it back to the main tag
     (system* riverctl "set-focused-tags" (number->string tag-mask))
     (system* riverctl "focus-view" "next")
     (system* riverctl "send-to-previous-tags")
     (system* riverctl "focus-previous-tags"))))

(define %rc-config
 (mixed-text-file "rcrc" "\

fn river_swallow {
  sp=()

  current=1
  while(~ $current [1-9] && ~ $sp ()){
    if (~ `{pgrep -c -f '"%river-spawn-scratchpad" '^$current} 0) {
      sp=$current
    }
    current=$current+1
  }

  if (~ $sp ()) {
    status='Error: no available scratchpad found'
  } else {
    "%river-spawn-scratchpad" $sp $*
  }
}"))

(define %rc-sv
 (service home-rc-service-type))
 (service home-rc-service-type
  (home-rc-configuration
   (profile (list %rc-profile))
   (rcrc (list %rc-config)))))

(add-user-packages! coreutils procps sed)
; TODO: make colour scheme a direct option in the module
(define %foot-config
 (mixed-text-file "foot.ini" "\
[colors]
background="(theme-background %user-theme)"
foreground="(theme-foreground %user-theme)"
selection-background="(theme-background %user-theme #:modifier 'selection)"
selection-foreground="(theme-foreground %user-theme)"

regular0="(theme-base00 %user-theme)"
regular1="(theme-base08 %user-theme)"
regular2="(theme-base0B %user-theme)"
regular3="(theme-base0A %user-theme)"
regular4="(theme-base0D %user-theme)"
regular5="(theme-base0E %user-theme)"
regular6="(theme-base0C %user-theme)"
regular7="(theme-base05 %user-theme)"

bright0="(theme-base03 %user-theme)"
bright1="(theme-base08 %user-theme)"
bright2="(theme-base0B %user-theme)"
bright3="(theme-base0A %user-theme)"
bright4="(theme-base0D %user-theme)"
bright5="(theme-base0E %user-theme)"
bright6="(theme-base0C %user-theme)"
bright7="(theme-base07 %user-theme)"

16="(theme-base09 %user-theme)"
17="(theme-base0F %user-theme)"
18="(theme-base01 %user-theme)"
19="(theme-base02 %user-theme)"
20="(theme-base04 %user-theme)"
21="(theme-base06 %user-theme)"
"))

(define %foot-package foot)

(define %foot-sv
 (service home-foot-service-type
  (home-foot-configuration
   (package %foot-package)
   (config (list %foot-config)))))
(define %waybar-config
  #~'(("layer" . "top")
      ("modules-left" . #("river/tags"))
      ("modules-right" . #("river/mode" "clock" "tray"))

     ("river/tags" .
      (("num-tags" . 9)))

     ("river/mode" .
      (("format" . "{}")))

     ("clock" .
      (("interval" . 60)
       ("format" . "{:%H:%M}")
       ("max-length" . 25)))

     ("tray" .
      (("icon-size" . 21)
       ("spacing" . 10)))))

(define %waybar-package waybar)

(define %waybar-sv
 (service home-waybar-service-type
  (home-waybar-configuration
   (package %waybar-package)
   (config %waybar-config))))
(define %river-package river)

(add-user-packages! foot rc)
(define %river-config
 #~(begin
    (define* (riverctl #:rest args)
     (apply system* (cons "riverctl" args)))
     (apply system* (cons #$(file-append %river-package "/bin/riverctl") args)))

    (define (flags->binding flags)
     (string-join flags " "))

    (define (river-map mode modifiers key action)
     (riverctl "map" (symbol->string mode) modifier (symbol->string key) action))


@@ 34,16 164,72 @@
     (let ((pre (if key (string-append "+" (symbol->string key)) ""))
      (string-append (symbol->string mod) key))))

    (river-map 'normal (modifier) 'Return "spawn foot")
    (define* (river-spawn-flags programme #:rest arguments)
     (cons "spawn" (flags->binding (cons programme arguments))))

    (define* (river-keyboard-layout-flags layout #:key (rules #f) (model #f) (variant #f) (options #f))
     (let ((flag (lambda* (flag #:rest value) (if (car value) (cons flag value) '()))))
      (append '("keyboard-layout")
              (flag "-rules" rules)
              (flag "-model" model)
              (flag "-variant" variant)
              (flag "-options" options)
              layout)))

    (define* (river-keyboard-layout layout #:key (flags #f) (model #f) (variant #f) (options #f))
     (apply riverctl (river-keyboard-layout-flags layout #:flags flags #:model model #:variant variant #:options options)))

    (define (river-declare-mode mode)
     (riverctl "declare-mode" (symbol->string mode)))

    ; Layout
    (riverctl "focus-follows-cursor" "normal")
    (riverctl "default-layout" "rivertile")
    (spawn #$(file-append %river-package "/bin/rivertile") '("rivertile" "-view-padding" "6" "-outer-padding" "6"))

    ; Theme
    (riverctl "background-color" #$(theme-background %user-theme))
    (riverctl "border-color-focused" #$(theme-foreground %user-theme))
    (riverctl "border-color-unfocused" #$(theme-foreground %user-theme #:modifier 'dark))

    ; Keymap
    (river-map 'normal (modifier) 'Return (string-append (river-spawn-flags #$(file-append %foot-package "/bin/foot"))))
    (river-map 'normal (modifier 'Shift) 'C "close")
    (river-map 'normal (modifier 'Shift) 'Q "exit")))
    (river-map 'normal (modifier 'Shift) 'Q "exit")

    (river-map 'normal (modifier) 'J "focus-view next")
    (river-map 'normal (modifier) 'K "focus-view previous")
    (river-map 'normal (modifier 'Shift) 'J "swap next")
    (river-map 'normal (modifier 'Shift) 'K "swap previous")

    (river-map 'normal (modifier) 'N "focus-output next")
    (river-map 'normal (modifier) 'P "focus-output previous")
    (river-map 'normal (modifier 'Shift) 'N "send-to-output next")
    (river-map 'normal (modifier 'Shift) 'P "send-to-output previous")

    ; Keyboards
    (define %keyboard-options '("grp:win_space_toggle" "compose:caps"))

    (river-declare-mode 'layout)
    (river-map 'normal (modifier 'Shift) 'K "enter-mode layout")
    (river-map 'layout 'None 'Escape "enter-mode normal")

    (define %qwerty-layout-flags (river-keyboard-layout-flags "us" #:options %keyboard-options))
    (river-map 'layout 'None 'Q (flags->binding %qwerty-layout-flags))

    (define %colemak-layout-flags (river-keyboard-layout-flags "us" #:variant "colemak" #:options %keyboard-options))
    (river-map 'layout 'None 'C (flags->binding %colemak-layout-flags))

    ; Startup
    (spawn #$(file-append %waybar-package "/bin/waybar") '("waybar"))))

(define %river-sv
 (service home-river-service-type
  (home-river-configuration
   (config (list (program-file "river-init" %river-config))))))
   (package %river-package)
   (config  %river-config))))
(make-user
 %user-account
 (home-environment
  (services (list %rc-sv %river-sv))
  (services (list %foot-sv %rc-sv %river-sv %waybar-sv))
  (packages %user-packages)))
\ No newline at end of file

M users/enderger.norg => users/enderger.norg +201 -7
@@ 9,13 9,22 @@ tangle: ./enderger.scm
   (srfi srfi-1)
   (gnu)
   (gnu home)
   (gnu packages linux)
   (gnu packages shells)
   (gnu packages terminals)
   (gnu packages wm)
   (hutzdog guix packages wrappers)
   (hutzdog guix packages wm)
   (hutzdog guix services home shells)
   (hutzdog guix services home terminals)
   (hutzdog guix services home waybar)
   (hutzdog guix services home wm)
   (hutzdog guix themes lib)
   (hutzdog guix themes nord)
   (hutzdog guix lib))

  (define %user-theme nord-theme)

  (define %user-packages '())
  (define* (add-user-packages! #:rest pkgs)
    (set! %user-packages (append pkgs %user-packages)))


@@ 32,18 41,147 @@ tangle: ./enderger.scm

* Shell
  @code scheme
  (define %rc-profile
   (mixed-text-file "rc_profile"
    (file-append river "/bin/river")))

  (define %river-spawn-scratchpad
   (program-file "spawn-scratchpad"
    #~(let* ((riverctl #$(file-append river "/bin/riverctl"))
             (scratch (cadr (command-line)))
             (command (cddr (command-line)))
             (tag-mask (ash #b1 (+ (string->number scratch) 9))))
       (display scratch)
       ; Send terminal to scratchpad
       (system* riverctl "set-view-tags" (number->string tag-mask))

       ; Spawn the command on the current tag
       (apply system* command)

       ; Grab scratchpad window and move it back to the main tag
       (system* riverctl "set-focused-tags" (number->string tag-mask))
       (system* riverctl "focus-view" "next")
       (system* riverctl "send-to-previous-tags")
       (system* riverctl "focus-previous-tags"))))

  (define %rc-config
   (mixed-text-file "rcrc" "\

  fn river_swallow {
    sp=()

    current=1
    while(~ $current [1-9] && ~ $sp ()){
      if (~ `{pgrep -c -f '"%river-spawn-scratchpad" '^$current} 0) {
        sp=$current
      }
      current=$current+1
    }

    if (~ $sp ()) {
      status='Error: no available scratchpad found'
    } else {
      "%river-spawn-scratchpad" $sp $*
    }
  }"))

  (define %rc-sv
   (service home-rc-service-type))
   (service home-rc-service-type
    (home-rc-configuration
     (profile (list %rc-profile))
     (rcrc (list %rc-config)))))

  (add-user-packages! coreutils procps sed)
  @end

* Terminal
  @code scheme
  ; TODO: make colour scheme a direct option in the module
  (define %foot-config
   (mixed-text-file "foot.ini" "\
  [colors]
  background="(theme-background %user-theme)"
  foreground="(theme-foreground %user-theme)"
  selection-background="(theme-background %user-theme #:modifier 'selection)"
  selection-foreground="(theme-foreground %user-theme)"

  regular0="(theme-base00 %user-theme)"
  regular1="(theme-base08 %user-theme)"
  regular2="(theme-base0B %user-theme)"
  regular3="(theme-base0A %user-theme)"
  regular4="(theme-base0D %user-theme)"
  regular5="(theme-base0E %user-theme)"
  regular6="(theme-base0C %user-theme)"
  regular7="(theme-base05 %user-theme)"

  bright0="(theme-base03 %user-theme)"
  bright1="(theme-base08 %user-theme)"
  bright2="(theme-base0B %user-theme)"
  bright3="(theme-base0A %user-theme)"
  bright4="(theme-base0D %user-theme)"
  bright5="(theme-base0E %user-theme)"
  bright6="(theme-base0C %user-theme)"
  bright7="(theme-base07 %user-theme)"

  16="(theme-base09 %user-theme)"
  17="(theme-base0F %user-theme)"
  18="(theme-base01 %user-theme)"
  19="(theme-base02 %user-theme)"
  20="(theme-base04 %user-theme)"
  21="(theme-base06 %user-theme)"
  "))

  (define %foot-package foot)
'
  (define %foot-sv
   (service home-foot-service-type
    (home-foot-configuration
     (package %foot-package)
     (config (list %foot-config)))))
  @end

* Status Bar
  @code scheme
  (define %waybar-config
    #~'(("layer" . "top")
        ("modules-left" . #("river/tags"))
        ("modules-right" . #("river/mode" "clock" "tray"))

  (add-user-packages! foot rc)
       ("river/tags" .
        (("num-tags" . 9)))

       ("river/mode" .
        (("format" . "{}")))

       ("clock" .
        (("interval" . 60)
         ("format" . "{:%H:%M}")
         ("max-length" . 25)))

       ("tray" .
        (("icon-size" . 21)
         ("spacing" . 10)))))

  (define %waybar-package waybar)

  (define %waybar-sv
   (service home-waybar-service-type
    (home-waybar-configuration
     (package %waybar-package)
     (config %waybar-config))))
  @end

* Window Manager
  @code scheme
  (define %river-package river)

  (define %river-config
   #~(begin
      (define* (riverctl #:rest args)
       (apply system* (cons "riverctl" args)))
       (apply system* (cons #$(file-append %river-package "/bin/riverctl") args)))

      (define (flags->binding flags)
       (string-join flags " "))

      (define (river-map mode modifiers key action)
       (riverctl "map" (symbol->string mode) modifier (symbol->string key) action))


@@ 53,14 191,70 @@ tangle: ./enderger.scm
       (let ((pre (if key (string-append "+" (symbol->string key)) ""))
        (string-append (symbol->string mod) key))))

      (river-map 'normal (modifier) 'Return "spawn foot")
      (define* (river-spawn-flags programme #:rest arguments)
       (cons "spawn" (flags->binding (cons programme arguments))))

      (define* (river-keyboard-layout-flags layout #:key (rules #f) (model #f) (variant #f) (options #f))
       (let ((flag (lambda* (flag #:rest value) (if (car value) (cons flag value) '()))))
        (append '("keyboard-layout")
                (flag "-rules" rules)
                (flag "-model" model)
                (flag "-variant" variant)
                (flag "-options" options)
                layout)))

      (define* (river-keyboard-layout layout #:key (flags #f) (model #f) (variant #f) (options #f))
       (apply riverctl (river-keyboard-layout-flags layout #:flags flags #:model model #:variant variant #:options options)))

      (define (river-declare-mode mode)
       (riverctl "declare-mode" (symbol->string mode)))

      ; Layout
      (riverctl "focus-follows-cursor" "normal")
      (riverctl "default-layout" "rivertile")
      (spawn #$(file-append %river-package "/bin/rivertile") '("rivertile" "-view-padding" "6" "-outer-padding" "6"))

      ; Theme
      (riverctl "background-color" #$(theme-background %user-theme))
      (riverctl "border-color-focused" #$(theme-foreground %user-theme))
      (riverctl "border-color-unfocused" #$(theme-foreground %user-theme #:modifier 'dark))

      ; Keymap
      (river-map 'normal (modifier) 'Return (string-append (river-spawn-flags #$(file-append %foot-package "/bin/foot"))))
      (river-map 'normal (modifier 'Shift) 'C "close")
      (river-map 'normal (modifier 'Shift) 'Q "exit")))
      (river-map 'normal (modifier 'Shift) 'Q "exit")

      (river-map 'normal (modifier) 'J "focus-view next")
      (river-map 'normal (modifier) 'K "focus-view previous")
      (river-map 'normal (modifier 'Shift) 'J "swap next")
      (river-map 'normal (modifier 'Shift) 'K "swap previous")

      (river-map 'normal (modifier) 'N "focus-output next")
      (river-map 'normal (modifier) 'P "focus-output previous")
      (river-map 'normal (modifier 'Shift) 'N "send-to-output next")
      (river-map 'normal (modifier 'Shift) 'P "send-to-output previous")

      ; Keyboards
      (define %keyboard-options '("grp:win_space_toggle" "compose:caps"))

      (river-declare-mode 'layout)
      (river-map 'normal (modifier 'Shift) 'K "enter-mode layout")
      (river-map 'layout 'None 'Escape "enter-mode normal")

      (define %qwerty-layout-flags (river-keyboard-layout-flags "us" #:options %keyboard-options))
      (river-map 'layout 'None 'Q (flags->binding %qwerty-layout-flags))

      (define %colemak-layout-flags (river-keyboard-layout-flags "us" #:variant "colemak" #:options %keyboard-options))
      (river-map 'layout 'None 'C (flags->binding %colemak-layout-flags))

      ; Startup
      (spawn #$(file-append %waybar-package "/bin/waybar") '("waybar"))))

  (define %river-sv
   (service home-river-service-type
    (home-river-configuration
     (config (list (program-file "river-init" %river-config))))))
     (package %river-package)
     (config  %river-config))))
  @end

* Implementation


@@ 68,6 262,6 @@ tangle: ./enderger.scm
  (make-user
   %user-account
   (home-environment
    (services (list %rc-sv %river-sv))
    (services (list %foot-sv %rc-sv %river-sv %waybar-sv))
    (packages %user-packages)))
  @end