summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMasaya Tojo <masaya@tojo.tokyo>2025-05-01 09:16:09 +0900
committerMasaya Tojo <masaya@tojo.tokyo>2025-05-01 09:16:09 +0900
commit027b325b1c2e0d94b6172245c90b0a23a6876be6 (patch)
tree141d0303f1c4d4b345ed903b64fcb44a7ba5e756
fedora: AddHEADmain
-rw-r--r--fedora.org780
1 files changed, 780 insertions, 0 deletions
diff --git a/fedora.org b/fedora.org
new file mode 100644
index 0000000..24ba4ca
--- /dev/null
+++ b/fedora.org
@@ -0,0 +1,780 @@
+#+TITLE: Fedora 用の設定
+#+PROPERTY: header-args:scheme :scheme guile :noeval :tangle ./fedora/masaya/home-configuration.scm :mkdirp yes
+#+PROPERTY: header-args:emacs-lisp :noeval :tangle fedora.el
+
+* Guix の設定
+
+Guix on Fedora で運用する。
+運用方針としては、なるべく Fedora 環境を大切にし、破壊しないように注意する方針にする。
+特に GUI のソフトウェアのインストールを回避するのが大切。
+
+また、Emacs の設定では Guix を使わずに straight + use-package の運用にする。
+理由は、会社の macOS でもこの設定をそのまま使うため。
+非 Guix の環境でも問題なく動作するように環境構築を行う。
+
+以下のコマンドを実行して home configuration をシステムに反映する。
+
+#+begin_src shell :eval no
+ guix home reconfigure ~/org/config/fedora/masaya/home-configuration.scm
+#+end_src
+
+** Guix の home-configuration を生成するための準備
+
+*** 必要なモジュールをロードする
+
+#+begin_src scheme
+ (use-modules (gnu home)
+ (gnu packages)
+ (gnu packages gtk)
+ (gnu services)
+ (guix gexp)
+ (guix channels)
+ (guix profiles)
+ (gnu packages bash)
+ (gnu packages package-management)
+ (gnu home services)
+ (gnu home services shells)
+ (gnu home services guix)
+ (gnu home services ssh))
+#+end_src
+
+*** manifest を定義する DSL を作成する
+
+#+begin_src scheme
+ (define manifest '())
+ (define (adjoin x l)
+ (if (member x l)
+ l
+ (cons x l)))
+ (define-syntax-rule (install name)
+ (set! manifest (adjoin 'name manifest)))
+#+end_src
+
+*** service を追加する DSL を作成する
+
+#+begin_src scheme
+ (define service-list '())
+ (define-syntax-rule (add-service sexp)
+ (set! service-list (cons sexp service-list)))
+#+end_src
+
+*** bash の alias を追加する DSL を作成する
+
+#+begin_src scheme
+ (define bash-aliases '())
+ (define (add-alias alias-name cmd)
+ (set! bash-aliases
+ (cons (cons alias-name cmd) bash-aliases)))
+#+end_src
+
+*** bash の環境変数を追加する手続きを定義
+
+#+begin_src scheme
+ (define bash-environment-variables '())
+ (define (add-bash-environment-variable var val)
+ (set! bash-environment-variables
+ (cons (cons var val)
+ bash-environment-variables)))
+
+ (define (update-bash-environment-variable var f)
+ (assoc-set! bash-environment-variables var
+ (f (assoc-ref bash-environment-variables var))))
+#+end_src
+
+*** bash で定義する PATH に追加する DSL を作成する
+
+#+begin_src scheme
+ (add-bash-environment-variable "PATH" "$PATH")
+ (define (append-bash-path path)
+ (update-bash-environment-variable
+ "PATH"
+ (lambda (val) (string-append val ":" path))))
+ (define (prepend-bash-path path)
+ (update-bash-environment-variable
+ "PATH"
+ (lambda (val) (string-append path ":" val))))
+#+end_src
+
+*** bash で定義する LD_LIBRARY_PATH に追加する DSL を作成する
+
+#+begin_src scheme
+ (add-bash-environment-variable "LD_LIBRARY_PATH" "$LD_LIBRARY_PATH")
+ (define (append-bash-ld-library-paths path)
+ (update-bash-environment-variable
+ "LD_LIBRARY_PATH"
+ (lambda (val) (string-append path val ":" val))))
+#+end_src
+
+*** bash で定義する XDG_DATA_DIRS に追加する
+
+#+begin_src scheme
+ (add-bash-environment-variable "XDG_DATA_DIRS" "$XDG_DATA_DIRS")
+ (define (append-bash-xdg-data-dirs path)
+ (update-bash-environment-variable
+ "XDG_DATA_DIRS"
+ (lambda (val) (string-append path ":" val))))
+#+end_src
+
+*** bash で定義する bashrc ファイルを追加する
+
+#+begin_src scheme
+ (define bashrc-files '())
+
+ (define (append-bashrc-files files)
+ (set! bashrc-files
+ (append bashrc-files files)))
+#+end_src
+
+*** Guile の LOAD_PATH に追加する DSL を作成する
+
+#+begin_src scheme
+ (add-bash-environment-variable "GUILE_LOAD_PATH" "$GUILE_LOAD_PATH")
+ (define (prepend-bash-guile-load-path path)
+ (update-bash-environment-variable
+ "GUILE_LOAD_PATH"
+ (lambda (val) (string-append path ":" val))))
+#+end_src
+
+* Emacs固有の設定
+** package.el の無効化
+
+=straight.el= を使うため、Emacsに最初から入っているパッケージ機能を無効化する。
+
+#+begin_src emacs-lisp :tangle ~/.emacs.d/early-init.el
+ ;; Emacsのパッケージ機能を無効化
+ (setq package-enable-at-startup nil)
+#+end_src
+
+** straight.el を使う
+
+#+begin_src emacs-lisp
+ (defvar bootstrap-version)
+ (let ((bootstrap-file
+ (expand-file-name
+ "straight/repos/straight.el/bootstrap.el"
+ (or (bound-and-true-p straight-base-dir)
+ user-emacs-directory)))
+ (bootstrap-version 7))
+ (unless (file-exists-p bootstrap-file)
+ (with-current-buffer
+ (url-retrieve-synchronously
+ "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
+ 'silent 'inhibit-cookies)
+ (goto-char (point-max))
+ (eval-print-last-sexp)))
+ (load bootstrap-file nil 'nomessage))
+#+end_src
+
+** use-package を使う
+
+straight.el で =use-package= をインストールする。
+また、今後は use-package でパッケージ関連の設定を行うこととする。
+
+#+begin_src emacs-lisp
+ (straight-use-package 'use-package)
+ (setq straight-use-package-by-default t)
+#+end_src
+
+** 起動時に bash からパスを読み込む
+
+#+begin_src emacs-lisp
+ (use-package exec-path-from-shell
+ :if (memq window-system '(mac ns x pgtk))
+ :config
+ (setq exec-path-from-shell-variables '("PATH" "GUIX_PROFILE" "GUIX_LOCPATH"))
+ (exec-path-from-shell-initialize))
+#+end_src
+** 日本語設定
+
+#+begin_src emacs-lisp
+ (set-language-environment "Japanese")
+#+end_src
+
+** タブの設定
+
+#+begin_src emacs-lisp
+ (setq-default indent-tabs-mode nil)
+ (setq-default tab-width 4)
+#+end_src
+
+** fonts の設定
+
+#+begin_src emacs-lisp
+ (set-face-attribute 'default nil :family "Adwaita Mono" :height 112)
+ (set-fontset-font t 'han "Noto Sans Mono CJK JP" nil)
+ (set-fontset-font t 'kana "Noto Sans Mono CJK JP" nil)
+ (set-fontset-font t 'katakana-jisx0201 "Noto Sans Mono CJK JP" nil)
+ #+end_src
+
+valign-mode を使うため、表が崩れるかどうかは気にしない。
+
+** ベルを無効化する
+
+ベルが鳴らないようにします。
+
+#+begin_src emacs-lisp
+ (setq ring-bell-function 'ignore)
+#+end_src
+
+** テーマの設定
+
+#+begin_src emacs-lisp
+ (use-package adwaita-dark-theme
+ :config
+ (load-theme 'adwaita-dark t))
+#+end_src
+
+** project.el
+
+#+begin_src emacs-lisp
+ (use-package project)
+#+end_src
+
+** flymake
+
+#+begin_src emacs-lisp
+ (use-package flymake
+ :bind (("C-c ! l" . flymake-show-buffer-diagnostics)
+ ("C-c ! n" . flymake-goto-next-error)
+ ("C-c ! p" . flymake-goto-prev-error)))
+#+end_src
+
+
+** company-mode
+
+#+begin_src emacs-lisp
+ (use-package company
+ :hook ((prog-mode . company-mode)
+ (company-mode . (lambda ()
+ (local-set-key (kbd "<tab>")
+ #'company-indent-or-complete-common))))
+ :custom
+ (company-idle-delay 0.1))
+#+end_src
+
+#+begin_src emacs-lisp
+ (use-package company-box
+ :hook (company-mode . company-box-mode))
+#+end_src
+
+** paredit
+
+#+begin_src emacs-lisp
+ (use-package paredit
+ :hook
+ ((scheme-mode . enable-paredit-mode)
+ (lisp-mode . enable-paredit-mode)
+ (lisp-interaction-mode . enable-paredit-mode)
+ (emacs-lisp-mode . enable-paredit-mode)
+ (racket-mode . enable-paredit-mode)))
+#+end_src
+
+** restart-emacs
+
+#+begin_src emacs-lisp
+ (use-package restart-emacs)
+#+end_src
+
+** mastodon
+
+#+begin_src emacs-lisp
+ (use-package mastodon
+ :config
+ (mastodon-discover)
+ (setq mastodon-instance-url "https://mastodon.tojo.tokyo"
+ mastodon-active-user "tojoqk"))
+#+end_src
+
+** wich-key
+
+#+begin_src emacs-lisp
+ (use-package which-key
+ :init
+ (which-key-mode))
+#+end_src
+
+** helm
+
+#+begin_src emacs-lisp
+ (use-package helm
+ :init
+ (helm-mode t)
+ :bind (("M-x" . helm-M-x)
+ ("C-x C-f" . helm-find-files)
+ ("C-x b" . helm-mini))
+ :custom
+ (helm-command-prefix-key "C-c h")
+ (helm-autoresize-mode t)
+ (helm-autoresize-max-height 30)
+ (helm-autoresize-min-height 10))
+#+end_src
+
+#+RESULTS:
+: helm-mini
+
+** doom-modeline
+
+#+begin_src emacs-lisp
+ (use-package doom-modeline
+ :hook (after-init . doom-modeline-mode)
+ :custom
+ (doom-modeline-icon t)
+ (doom-modeline-buffer-file-name-style 'relative-from-project)
+ )
+
+#+end_src
+
+依存で nerd-icons が入るので、
+インストール後に M-x nerd-icons-install-fontsを実行する。
+
+** undo-tree-mode
+
+undo を木を辿るような感じでできるようにするものです。
+これが有効になっているだけ過去の編集履歴を失なうリスクがだいぶ下がるので少し安心できます。
+
+#+begin_src emacs-lisp
+ (use-package undo-tree
+ :custom
+ (undo-tree-auto-save-history nil)
+ :init
+ (global-undo-tree-mode))
+#+end_src
+
+** 見た目に関係する設定
+
+スクロールバー、メニューバー、タブバーがあると画面が狭くなるので消しています。
+ただメニュー機能は自体は割と有用なので迷ったときには F10
+でメニューを出せることを覚えておくと便利です。
+
+#+begin_src emacs-lisp
+ (scroll-bar-mode -1)
+ (tool-bar-mode -1)
+#+end_src
+
+** 文字コードの設定
+
+念のため明示的に文字コードは =utf-8-unix= を使用するように指定しています。
+
+#+begin_src emacs-lisp
+ (prefer-coding-system 'utf-8-unix)
+#+end_src
+
+** 半透明化のコマンド定義
+
+#+begin_src emacs-lisp
+ (defun set-alpha (alpha-num)
+ (interactive "nAlpha: ")
+ (set-frame-parameter nil 'alpha-background alpha-num))
+#+end_src
+
+** valign
+
+#+begin_src emacs-lisp
+ (use-package valign
+ :hook ((org-mode markdown-mode) . valign-mode)
+ :custom
+ (valign-fancy-bar t))
+#+end_src
+
+* Org-mode の設定
+
+メインの環境ではなくプライベートな情報を含めないために設定は少なめです。
+
+** スピードコマンドを有効にする
+
+=*= の上で簡単に操作できる。めっちゃ早い。ヘルプは =?= 。
+
+#+begin_src emacs-lisp
+ (setq org-use-speed-commands t)
+#+end_src
+
+** tag の空白
+
+#+begin_src emacs-lisp
+ (setq org-tags-column 0)
+#+end_src
+
+** HTML 系
+
+HTML を生成したときの =validation-link= は要らないので無効にします。
+
+#+begin_src emacs-lisp
+ (setq org-html-validation-link nil)
+#+end_src
+
+** org-refile
+
+*** ファイルを限定してリファイルを有効にする
+
+#+begin_src emacs-lisp
+ (setq org-refile-targets '((("notes.org" "issues.org" "yukamasa.org" "schedule.org" "jobs.org") :maxlevel . 1)))
+#+end_src
+
+*** 最後に追加するのではなくて先頭に追加する
+
+#+begin_src emacs-lisp
+ (setq org-reverse-note-order t)
+#+end_src
+
+** org-agenda
+
+*** org-directory 直下を org-agenda の対象にする
+
+#+begin_src emacs-lisp
+ (setq org-agenda-files "~/org/agenda-files")
+#+end_src
+
+キーバインドを設定します。
+#+begin_src emacs-lisp
+ (global-set-key (kbd "C-c a") 'org-agenda)
+#+end_src
+
+*** =TODO= のキーワードを設定
+
+- 未着手なタスクとは =TODO=
+- 待ち状態のタスクは =WAIT=
+- 進行中のやることは =IN-PROGRESS=
+- 保留中のやることは =HOLD=
+- 完了したタスクは =DONE=
+- やめることにしたタスクは =CANCELED=
+
+#+begin_src emacs-lisp
+ (setq org-todo-keywords
+ '((sequence "TODO(t)" "IN-PROGRESS(p)" "HOLD(h)" "WAIT(w)" "|" "DONE(d)" "CANCELED(c)")))
+#+end_src
+
+*** 週の最初から表示するのではなく今日から表示されるようにする
+
+週の最初から表示すると org-agenda のログを見たときに、
+過去のログが邪魔して今日のログを確認しずらくなるから。
+
+#+begin_src emacs-lisp
+ (setq org-agenda-start-on-weekday nil)
+#+end_src
+
+*** タスクをブロックする系の設定
+
+TODO
+は階層構造になることがありサブタスクが完了してからでないとタスクを完了できないようにしたり、
+順番にやらないといけないタスクなどでまだ始められないタスクの表示を灰色にしたりするための設定です。
+
+=org-enforce-todo-dependencies= を設定すると、
+子の TODO が全て終わりになってからでないと DONE にできなくなります。
+
+=org-agenda-dim-blocked-tasks= を設定すると、
+org-agenda でタスクを見たときにブロックされたタスクが暗く表示されます。
+
+=org-enforce-todo-checkbox-dependencies= は明示的にデフォルトと同じ =nil= に設定します。
+これは一見有効にしたくなる設定ですが、これが =t=
+だとチェックボックスが全てチェックされた状態にならないと、前述した
+=org-agenda-dim-blocked-tasks= の効果により実際にはやらなければならない
+TODO のタスクが灰色になってしまう問題が生じます。
+
+#+begin_src emacs-lisp
+ (setq org-enforce-todo-dependencies t)
+ (setq org-agenda-dim-blocked-tasks t)
+ (setq org-enforce-todo-checkbox-dependencies nil)
+#+end_src
+
+*** =DONE= したときの時刻を残す
+
+後からその日に何個のタスクを終了したかを記録するため。
+
+#+begin_src emacs-lisp
+ (setq org-log-done t)
+#+end_src
+
+*** 終了したタスクの締切は agenda に表示しない
+
+#+begin_src emacs-lisp
+ (setq org-agenda-skip-deadline-if-done t)
+#+end_src
+
+*** 締切を警告
+
+#+begin_src emacs-lisp
+ (setq org-deadline-warning-days 3)
+#+end_src
+
+*** org-clock の整合性検査
+
+家での記録であって仕事でないため、以下の点について考慮する。
+
+- max-duration: デフォルトと同じ10時間
+- min-duration: デフォルトと同じ
+- max-gap: 15分、タスクの合間にそれくらいの休憩をはさむため
+- gap-ok-around
+ - "04:00": 前日との間で gap の検査が行なわれないようにするため
+ - "13:30": だいたいこのあたりに昼食を食べるため
+ - "20:00": だいたいこのあたりに夕食を食べるため
+
+#+begin_src emacs-lisp
+ (setq org-agenda-clock-consistency-checks
+ (list :max-duration "10:00"
+ :min-duration 0
+ :max-gap 15
+ :gap-ok-around '("4:00" "13:30" "21:00")
+ :default-face '((:background "DarkRed")
+ (:foreground "white"))))
+#+end_src
+
+*** 日程とタスク
+
+#+begin_src emacs-lisp
+ (setq org-agenda-custom-commands
+ '(("d" "今日のタスク"
+ todo "TODO|IN-PROGRESS"
+ ((org-agenda-todo-ignore-scheduled 'future)))
+ ("h" "保留中" todo "HOLD|WAIT")
+ ("f" "対応予定タスク" todo "TODO|IN-PROGRESS")
+ ("n" "今日の日程"
+ ((agenda "")
+ (todo "TODO|IN-PROGRESS"))
+ ((org-agenda-span 'day)
+ (org-agenda-todo-ignore-scheduled 'future)
+ (org-deadline-warning-days 3)
+ (org-agenda-log-mode-items '(closed clock state))))
+ ("l" "ログを記録" tags "log")
+ ("c" "予定" agenda ""
+ ((org-agenda-span 'week)
+ (org-agenda-start-on-weekday nil)
+ (org-agenda-category-filter-preset '("-routines" "-diary" "-logs"))))
+ ("p" "ポリシーを確認" tags "policy" ((org-use-tag-inheritance nil)))
+ ("k" "ナレッジを確認" tags "knowledge" ((org-use-tag-inheritance nil)))))
+#+end_src
+
+** org-store-link
+
+Emacs の任意の場所のリンクを取得する機能です(正直あまり使いこなせてない…)。
+
+#+begin_src emacs-lisp
+ (global-set-key (kbd "C-c l") 'org-store-link)
+#+end_src
+
+** org-table
+
+=org-table-automatic-realign= を無効化しないと org-capture で表に追記したときに謎の空行が生じて表が破壊される現象を観測していて、
+これを防ぐために =nil= に設定しています。
+
+#+begin_src emacs-lisp
+ (setq org-table-automatic-realign nil)
+#+end_src
+
+** org-startup 系
+
+org-mode のファイルを開いたときにインデントされていてかつ折り畳まれた状態にします。
+
+#+begin_src emacs-lisp
+ (setq org-startup-indented t)
+ (setq org-startup-folded t)
+#+end_src
+
+** org-babel
+
+org-babel で使いたい言語を指定します。
+毎回、本当に実行していいか聞かれるとうっとうしいため
+=org-confirm-babel-evaluate= は =nil= に設定しています。
+
+#+begin_src emacs-lisp
+ (org-babel-do-load-languages
+ 'org-babel-load-languages
+ '((shell . t)
+ (emacs-lisp . t)
+ (scheme . t)
+ ;; (racket . t)
+ ;; (acl2 . t)
+ (python . t)
+ (perl . t)
+ (lisp . t)
+ (sql . t)
+ (dot . t)
+ ))
+ (setq org-confirm-babel-evaluate nil)
+#+end_src
+
+** org-archive
+
+org-mode のアーカイブ先を設定します。
+アーカイブ先の名前はデフォルトの "%s_archive" とします。
+
+#+begin_src emacs-lisp
+ (setq org-archive-location "%s_archive::")
+#+end_src
+
+** 今日の定義は変更しない
+
+深夜のタイムスタンプが正常に動作しなくなるため、明示的にデフォルトのままに設定する。
+
+#+begin_src emacs-lisp
+ (setq org-extend-today-until 0)
+#+end_src
+
+** org-clock
+
+*** org-clock-goto
+
+グローバルに org-clock-goto できるようにする
+
+#+begin_src emacs-lisp
+ (global-set-key (kbd "C-c g g") 'org-clock-goto)
+#+end_src
+
+
+*** 通知時間
+
+デフォルトだと通知の表示時間が3秒であまりに短かすぎるため長くしている。
+
+#+begin_src emacs-lisp
+ (setq org-show-notification-timeout 10)
+#+end_src
+
+** iCalendar
+
+#+begin_src emacs-lisp
+ (setq org-icalendar-timezone "Asia/Tokyo")
+ (setq org-icalendar-include-todo 'all
+ org-caldav-sync-todo t)
+ (setq org-icalendar-use-scheduled '(event-if-todo-not-done))
+ (setq org-icalendar-use-deadline '(event-if-todo-not-done))
+ (setq org-icalendar-categories '(local-tags category))
+ ;; GNOME Calendar のために TZID を明示的に指定する
+ (setq org-icalendar-date-time-format ";TZID=%Z:%Y%m%dT%H%M%S")
+#+end_src
+
+* Git
+** Emacs では magit から操作する
+
+#+begin_src emacs-lisp
+ (use-package magit)
+#+end_src
+
+project.el で C-x p m で magit を開けるようにするため、
+明示的に magit-extras を読み込む。
+
+#+begin_src emacs-lisp
+ (use-package magit-extras
+ :straight nil)
+#+end_src
+
+* pass
+
+#+begin_src emacs-lisp
+ (use-package pass)
+#+end_src
+
+#+begin_src scheme
+ (install password-store)
+ (install pass-otp)
+#+end_src
+
+* ag
+
+#+begin_src emacs-lisp
+ (use-package ag)
+#+end_src
+
+#+begin_src scheme
+ (install the-silver-searcher)
+#+end_src
+
+* OpenSSH
+
+#+begin_src text :tangle ~/.ssh/config
+ Host git.tojo.tokyo
+ HostName server.git.tojo.tokyo
+ AddressFamily inet
+ ForwardX11 no
+ ForwardX11Trusted no
+ ForwardAgent no
+ Compression no
+
+ Host www.tojo.tokyo
+ AddressFamily inet
+ ForwardX11 no
+ ForwardX11Trusted no
+ ForwardAgent no
+ Compression no
+
+ Host mastodon.tojo.tokyo
+ AddressFamily inet
+ ForwardX11 no
+ ForwardX11Trusted no
+ ForwardAgent no
+ Compression no
+#+end_src
+
+* Python
+
+#+begin_src emacs-lisp
+ (use-package lsp-pyright
+ :custom (lsp-pyright-langserver-command "basedpyright")
+ :hook (python-mode . (lambda ()
+ (require 'lsp-pyright)
+ (lsp))))
+ ;; (use-package eglot
+ ;; :config
+ ;; (add-to-list 'eglot-server-programs
+ ;; '((python-mode python-ts-mode)
+ ;; "basedpyright-langserver" "--stdio"))
+ ;; (setq-default
+ ;; eglot-workspace-configuration
+ ;; '(:basedpyright
+ ;; (:typeCheckingMode "recommended")
+ ;; :basedpyright.analysis
+ ;; (:diagnosticSeverityOverrides
+ ;; (:reportUnusedCallResult "none")
+ ;; :inlayHints (:callArgumentNames :json-false)))))
+
+ (use-package pyvenv
+ :config
+ (pyvenv-mode t))
+#+end_src
+
+* Guile
+
+Guile を Guix でインストールする
+
+#+begin_src scheme
+ (install guile)
+#+end_src
+
+** Geiser
+
+Emacs では Geiser を通して Guile のプログラムを扱う。
+
+#+begin_src emacs-lisp
+ (use-package geiser
+ :init
+ (setq geiser-active-implementations '(guile)))
+
+ (use-package geiser-guile)
+#+end_src
+
+* Racket
+
+Racket は GUI ソフトウェアとしての側面もあるため、
+Guix ではインストールせずに、Fedora の dnf でインストールした。
+
+** Emacs の設定
+
+#+begin_src emacs-lisp
+ (use-package racket-mode
+ :hook ((racket-mode . racket-xp-mode)))
+#+end_src
+
+* おわりに
+
+** Guix の home configuration を完成させる
+
+#+begin_src scheme
+ (add-service
+ (service home-bash-service-type
+ (home-bash-configuration
+ (aliases bash-aliases)
+ (bashrc bashrc-files)
+ (environment-variables bash-environment-variables))))
+
+ (home-environment
+ (packages (specifications->packages (map symbol->string manifest)))
+ (services service-list))
+#+end_src