diff options
Diffstat (limited to 'gnu/home/services')
-rw-r--r-- | gnu/home/services/desktop.scm | 174 | ||||
-rw-r--r-- | gnu/home/services/fontutils.scm | 4 | ||||
-rw-r--r-- | gnu/home/services/shells.scm | 126 | ||||
-rw-r--r-- | gnu/home/services/shepherd.scm | 21 | ||||
-rw-r--r-- | gnu/home/services/symlink-manager.scm | 387 | ||||
-rw-r--r-- | gnu/home/services/xdg.scm | 33 |
6 files changed, 464 insertions, 281 deletions
diff --git a/gnu/home/services/desktop.scm b/gnu/home/services/desktop.scm new file mode 100644 index 0000000000..cbb9cf76da --- /dev/null +++ b/gnu/home/services/desktop.scm @@ -0,0 +1,174 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2022 Ludovic Courtès <ludo@gnu.org> +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. + +(define-module (gnu home services desktop) + #:use-module (gnu home services) + #:use-module (gnu home services shepherd) + #:use-module (gnu services configuration) + #:autoload (gnu packages xdisorg) (redshift) + #:use-module (guix records) + #:use-module (guix gexp) + #:use-module (srfi srfi-1) + #:use-module (ice-9 match) + #:export (home-redshift-configuration + home-redshift-configuration? + + home-redshift-service-type)) + + +;;; +;;; Redshift. +;;; + +(define (serialize-integer field value) + (string-append (match field + ('daytime-temperature "temp-day") + ('nighttime-temperature "temp-night") + ('daytime-brightness "brightness-day") + ('nighttime-brightness "brightness-night") + ('latitude "lat") + ('longitude "lon") + (_ (symbol->string field))) + "=" (number->string value) "\n")) + +(define (serialize-symbol field value) + (string-append (symbol->string field) + "=" (symbol->string value) "\n")) + +(define (serialize-string field value) + (string-append (symbol->string field) + "=" value "\n")) + +(define serialize-inexact-number serialize-integer) + +(define (inexact-number? n) + (and (number? n) (inexact? n))) +(define-maybe inexact-number) +(define-maybe string) + +(define (serialize-raw-configuration-string field value) + value) +(define raw-configuration-string? string?) + +(define-configuration home-redshift-configuration + (redshift + (file-like redshift) + "Redshift package to use.") + + (location-provider + (symbol 'geoclue2) + "Geolocation provider---@code{'manual} or @code{'geoclue2}. + +In the former case, you must also specify the @code{latitude} and +@code{longitude} fields so Redshift can determine daytime at your place. In +the latter case, the Geoclue system service must be running; it will be +queried for location information.") + (adjustment-method + (symbol 'randr) + "Color adjustment method.") + + ;; Default values from redshift(1). + (daytime-temperature + (integer 6500) + "Daytime color temperature (kelvins).") + (nighttime-temperature + (integer 4500) + "Nighttime color temperature (kelvins).") + + (daytime-brightness + (maybe-inexact-number 'disabled) + "Daytime screen brightness, between 0.1 and 1.0.") + (nighttime-brightness + (maybe-inexact-number 'disabled) + "Nighttime screen brightness, between 0.1 and 1.0.") + + (latitude + (maybe-inexact-number 'disabled) + "Latitude, when @code{location-provider} is @code{'manual}.") + (longitude + (maybe-inexact-number 'disabled) + "Longitude, when @code{location-provider} is @code{'manual}.") + + (dawn-time + (maybe-string 'disabled) + "Custom time for the transition from night to day in the +morning---@code{\"HH:MM\"} format. When specified, solar elevation is not +used to determine the daytime/nighttime period.") + (dusk-time + (maybe-string 'disabled) + "Likewise, custom time for the transition from day to night in the +evening.") + + (extra-content + (raw-configuration-string "") + "Extra content appended as-is to the Redshift configuration file. Run +@command{man redshift} for more information about the configuration file +format.")) + +(define (serialize-redshift-configuration config) + (define location-fields + '(latitude longitude)) + + (define (location-field? field) + (memq (configuration-field-name field) location-fields)) + + (define (secondary-field? field) + (or (location-field? field) + (memq (configuration-field-name field) + '(redshift extra-content)))) + + #~(string-append + "[redshift]\n" + #$(serialize-configuration config + (remove secondary-field? + home-redshift-configuration-fields)) + + #$(home-redshift-configuration-extra-content config) + + "\n[manual]\n" + #$(serialize-configuration config + (filter location-field? + home-redshift-configuration-fields)))) + +(define (redshift-shepherd-service config) + (define config-file + (computed-file "redshift.conf" + #~(call-with-output-file #$output + (lambda (port) + (display #$(serialize-redshift-configuration config) + port))))) + + (list (shepherd-service + (documentation "Redshift program.") + (provision '(redshift)) + ;; FIXME: This fails to start if Home is first activated from a + ;; non-X11 session. + (start #~(make-forkexec-constructor + (list #$(file-append redshift "/bin/redshift") + "-c" #$config-file))) + (stop #~(make-kill-destructor))))) + +(define home-redshift-service-type + (service-type + (name 'home-redshift) + (extensions (list (service-extension home-shepherd-service-type + redshift-shepherd-service))) + (default-value (home-redshift-configuration)) + (description + "Run Redshift, a program that adjusts the color temperature of display +according to time of day."))) diff --git a/gnu/home/services/fontutils.scm b/gnu/home/services/fontutils.scm index 772904367d..6062eaed6a 100644 --- a/gnu/home/services/fontutils.scm +++ b/gnu/home/services/fontutils.scm @@ -34,7 +34,7 @@ ;;; Code: (define (add-fontconfig-config-file he-symlink-path) - `(("config/fontconfig/fonts.conf" + `(("fontconfig/fonts.conf" ,(mixed-text-file "fonts.conf" "<?xml version='1.0'?> @@ -51,7 +51,7 @@ (service-type (name 'home-fontconfig) (extensions (list (service-extension - home-files-service-type + home-xdg-configuration-files-service-type add-fontconfig-config-file) (service-extension home-run-on-change-service-type diff --git a/gnu/home/services/shells.scm b/gnu/home/services/shells.scm index ca7f4ac0ad..7b9769bcf3 100644 --- a/gnu/home/services/shells.scm +++ b/gnu/home/services/shells.scm @@ -171,56 +171,27 @@ Used for executing user's commands at the exit of login shell. It won't be read in some cases (if the shell terminates by exec'ing another process for example).")) -(define (add-zsh-configuration config) - (let* ((xdg-flavor? (home-zsh-configuration-xdg-flavor? config))) - - (define prefix-file - (cut string-append - (if xdg-flavor? - "config/zsh/." - "") <>)) - - (define (filter-fields field) - (filter-configuration-fields home-zsh-configuration-fields - (list field))) - - (define (serialize-field field) - (serialize-configuration - config - (filter-fields field))) - - (define (file-if-not-empty field) - (let ((file-name (symbol->string field)) - (field-obj (car (filter-fields field)))) - (if (not (null? ((configuration-field-getter field-obj) config))) - `(,(prefix-file file-name) - ,(mixed-text-file - file-name - (serialize-field field))) - '()))) - - (filter - (compose not null?) - `(,(if xdg-flavor? - `("zshenv" - ,(mixed-text-file - "auxiliary-zshenv" - (if xdg-flavor? - "source ${XDG_CONFIG_HOME:-$HOME/.config}/zsh/.zshenv\n" - ""))) - '()) - (,(prefix-file "zshenv") - ,(mixed-text-file - "zshenv" - (if xdg-flavor? - "export ZDOTDIR=${XDG_CONFIG_HOME:-$HOME/.config}/zsh\n" - "") - (serialize-field 'zshenv) - (serialize-field 'environment-variables))) - (,(prefix-file "zprofile") - ,(mixed-text-file - "zprofile" - "\ +(define (zsh-filter-fields field) + (filter-configuration-fields home-zsh-configuration-fields (list field))) + +(define (zsh-serialize-field config field) + (serialize-configuration config (zsh-filter-fields field))) + +(define* (zsh-field-not-empty? config field) + (let ((file-name (symbol->string field)) + (field-obj (car (zsh-filter-fields field)))) + (not (null? ((configuration-field-getter field-obj) config))))) + +(define (zsh-file-zshenv config) + (mixed-text-file + "zshenv" + (zsh-serialize-field config 'zshenv) + (zsh-serialize-field config 'environment-variables))) + +(define (zsh-file-zprofile config) + (mixed-text-file + "zprofile" + "\ # Setups system and user profiles and related variables source /etc/profile # Setups home environment profile @@ -229,11 +200,47 @@ source ~/.profile # It's only necessary if zsh is a login shell, otherwise profiles will # be already sourced by bash " - (serialize-field 'zprofile))) - - ,@(list (file-if-not-empty 'zshrc) - (file-if-not-empty 'zlogin) - (file-if-not-empty 'zlogout)))))) + (zsh-serialize-field config 'zprofile))) + +(define (zsh-file-by-field config field) + (match field + ('zshenv (zsh-file-zshenv config)) + ('zprofile (zsh-file-zprofile config)) + (e (mixed-text-file + (symbol->string field) + (zsh-serialize-field config field))))) + +(define (zsh-get-configuration-files config) + `(("zprofile" ,(zsh-file-by-field config 'zprofile)) ;; Always non-empty + ,@(if (and (zsh-field-not-empty? config 'zshenv) + (zsh-field-not-empty? config 'environment-variables)) + `(("zshenv" ,(zsh-file-by-field config 'zshenv))) '()) + ,@(if (zsh-field-not-empty? config 'zshrc) + `(("zshrc" ,(zsh-file-by-field config 'zshrc))) '()) + ,@(if (zsh-field-not-empty? config 'zlogin) + `(("zlogin" ,(zsh-file-by-field config 'zlogin))) '()) + ,@(if (zsh-field-not-empty? config 'zlogout) + `(("zlogout" ,(zsh-file-by-field config 'zlogout))) '()))) + +(define (zsh-home-files config) + (define zshenv-auxiliary-file + (mixed-text-file + "zshenv-auxiliary" + "export ZDOTDIR=${XDG_CONFIG_HOME:-$HOME/.config}/zsh\n" + "[[ -f $ZDOTDIR/.zshenv ]] && source $ZDOTDIR/.zshenv\n")) + + (if (home-zsh-configuration-xdg-flavor? config) + `(("zshenv" ,zshenv-auxiliary-file)) + (zsh-get-configuration-files config))) + +(define (zsh-xdg-configuration-files config) + (if (home-zsh-configuration-xdg-flavor? config) + (map + (lambda (lst) + (cons (string-append "zsh/." (car lst)) + (cdr lst))) + (zsh-get-configuration-files config)) + '())) (define (add-zsh-packages config) (list (home-zsh-configuration-package config))) @@ -291,7 +298,10 @@ source ~/.profile (extensions (list (service-extension home-files-service-type - add-zsh-configuration) + zsh-home-files) + (service-extension + home-xdg-configuration-files-service-type + zsh-xdg-configuration-files) (service-extension home-profile-service-type add-zsh-packages))) @@ -324,7 +334,7 @@ source ~/.profile (guix-defaults? (boolean #t) "Add sane defaults like reading @file{/etc/bashrc} and coloring the output of -@command{ls} to the end of the @file{.bashrc} file.") +@command{ls} to the top of the @file{.bashrc} file.") (environment-variables (alist '()) "Association list of environment variables to set for the Bash session. The @@ -448,7 +458,7 @@ if [ -f ~/.bashrc ]; then source ~/.bashrc; fi 'bashrc (if (home-bash-configuration-guix-defaults? config) (list (serialize-field 'aliases) guix-bashrc) - (list (serialize-field 'alises)))) + (list (serialize-field 'aliases)))) (file-if-not-empty 'bash-logout))))) (define (add-bash-packages config) diff --git a/gnu/home/services/shepherd.scm b/gnu/home/services/shepherd.scm index 7a9cc064bb..feff130259 100644 --- a/gnu/home/services/shepherd.scm +++ b/gnu/home/services/shepherd.scm @@ -24,12 +24,27 @@ #:use-module (guix sets) #:use-module (guix gexp) #:use-module (guix records) - #:use-module (srfi srfi-1) - #:export (home-shepherd-service-type - home-shepherd-configuration) + + home-shepherd-configuration + home-shepherd-configuration? + home-shepherd-configuration-shepherd + home-shepherd-configuration-auto-start? + home-shepherd-configuration-services) #:re-export (shepherd-service + shepherd-service? + shepherd-service-documentation + shepherd-service-provision + shepherd-service-canonical-name + shepherd-service-requirement + shepherd-service-one-shot? + shepherd-service-respawn? + shepherd-service-start + shepherd-service-stop + shepherd-service-auto-start? + shepherd-service-modules + shepherd-action)) (define-record-type* <home-shepherd-configuration> diff --git a/gnu/home/services/symlink-manager.scm b/gnu/home/services/symlink-manager.scm index 314da3ba3e..3b851229f3 100644 --- a/gnu/home/services/symlink-manager.scm +++ b/gnu/home/services/symlink-manager.scm @@ -1,6 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2021 Andrew Tropin <andrew@trop.in> ;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz> +;;; Copyright © 2022 Ludovic Courtès <ludo@gnu.org> ;;; ;;; This file is part of GNU Guix. ;;; @@ -20,219 +21,199 @@ (define-module (gnu home services symlink-manager) #:use-module (gnu home services) #:use-module (guix gexp) - + #:use-module (guix modules) #:export (home-symlink-manager-service-type)) ;;; Comment: ;;; -;;; symlink-manager cares about configuration files: it backs up files -;;; created by user, removes symlinks and directories created by a -;;; previous generation, and creates new directories and symlinks to -;;; configuration files according to the content of files/ directory -;;; (created by home-files-service) of the current home environment -;;; generation. +;;; symlink-manager cares about xdg configurations and other files: it backs +;;; up files created by user, removes symlinks and directories created by a +;;; previous generation, and creates new directories and symlinks to files +;;; according to the content of directories (created by home-files-service) of +;;; the current home environment generation. ;;; ;;; Code: (define (update-symlinks-script) (program-file "update-symlinks" - #~(begin - (use-modules (ice-9 ftw) - (ice-9 curried-definitions) - (ice-9 match) - (srfi srfi-1) - (guix i18n)) - #$%initialize-gettext - (define ((simplify-file-tree parent) file) - "Convert the result produced by `file-system-tree' to less -verbose and more suitable for further processing format. - -Extract dir/file info from stat and compose a relative path to the -root of the file tree. - -Sample output: - -((dir . \".\") - ((dir . \"config\") - ((dir . \"config/fontconfig\") - (file . \"config/fontconfig/fonts.conf\")) - ((dir . \"config/isync\") - (file . \"config/isync/mbsyncrc\")))) -" - (match file - ((name stat) `(file . ,(string-append parent name))) - ((name stat children ...) - (cons `(dir . ,(string-append parent name)) - (map (simplify-file-tree - (if (equal? name ".") - "" - (string-append parent name "/"))) - children))))) - - (define ((file-tree-traverse preordering) node) - "Traverses the file tree in different orders, depending on PREORDERING. - -if PREORDERING is @code{#t} resulting list will contain directories -before files located in those directories, otherwise directory will -appear only after all nested items already listed." - (let ((prepend (lambda (a b) (append b a)))) - (match node - (('file . path) (list node)) - ((('dir . path) . rest) - ((if preordering append prepend) - (list (cons 'dir path)) - (append-map (file-tree-traverse preordering) rest)))))) - - (use-modules (guix build utils)) - - (let* ((config-home (or (getenv "XDG_CONFIG_HOME") - (string-append (getenv "HOME") "/.config"))) - - (he-path (string-append (getenv "HOME") "/.guix-home")) - (new-he-path (string-append he-path ".new")) - (new-home (getenv "GUIX_NEW_HOME")) - (old-home (getenv "GUIX_OLD_HOME")) - - (new-files-path (string-append new-home "/files")) - ;; Trailing dot is required, because files itself is symlink and - ;; to make file-system-tree works it should be a directory. - (new-files-dir-path (string-append new-files-path "/.")) - - (home-path (getenv "HOME")) - (backup-dir (string-append home-path "/" - (number->string (current-time)) - "-guix-home-legacy-configs-backup")) - - (old-tree (if old-home - ((simplify-file-tree "") - (file-system-tree - (string-append old-home "/files/."))) - #f)) - (new-tree ((simplify-file-tree "") - (file-system-tree new-files-dir-path))) - - (get-source-path - (lambda (path) - (readlink (string-append new-files-path "/" path)))) - - (get-target-path - (lambda (path) - (string-append home-path "/." path))) - - (get-backup-path - (lambda (path) - (string-append backup-dir "/." path))) - - (directory? - (lambda (path) - (equal? (stat:type (stat path)) 'directory))) - - (empty-directory? - (lambda (dir) - (equal? (scandir dir) '("." "..")))) - - (symlink-to-store? - (lambda (path) - (and - (equal? (stat:type (lstat path)) 'symlink) - (store-file-name? (readlink path))))) - - (backup-file - (lambda (path) - (mkdir-p backup-dir) - (format #t (G_ "Backing up ~a...") (get-target-path path)) - (mkdir-p (dirname (get-backup-path path))) - (rename-file (get-target-path path) (get-backup-path path)) - (display (G_ " done\n")))) - - (cleanup-symlinks - (lambda () - (let ((to-delete ((file-tree-traverse #f) old-tree))) - (display - (G_ - "Cleaning up symlinks from previous home-environment.\n\n")) - (map - (match-lambda - (('dir . ".") - (display (G_ "Cleanup finished.\n\n"))) - - (('dir . path) - (if (and - (file-exists? (get-target-path path)) - (directory? (get-target-path path)) - (empty-directory? (get-target-path path))) - (begin - (format #t (G_ "Removing ~a...") - (get-target-path path)) - (rmdir (get-target-path path)) - (display (G_ " done\n"))) - (format - #t - (G_ "Skipping ~a (not an empty directory)... done\n") - (get-target-path path)))) - - (('file . path) - (when (file-exists? (get-target-path path)) - ;; DO NOT remove the file if it is no longer - ;; a symlink to the store, it will be backed - ;; up later during create-symlinks phase. - (if (symlink-to-store? (get-target-path path)) - (begin - (format #t (G_ "Removing ~a...") (get-target-path path)) - (delete-file (get-target-path path)) - (display (G_ " done\n"))) - (format - #t - (G_ "Skipping ~a (not a symlink to store)... done\n") - (get-target-path path)))))) - to-delete)))) - - (create-symlinks - (lambda () - (let ((to-create ((file-tree-traverse #t) new-tree))) - (map - (match-lambda - (('dir . ".") - (display - (G_ "New symlinks to home-environment will be created soon.\n")) - (format - #t (G_ "All conflicting files will go to ~a.\n\n") backup-dir)) - - (('dir . path) - (let ((target-path (get-target-path path))) - (when (and (file-exists? target-path) - (not (directory? target-path))) - (backup-file path)) - - (if (file-exists? target-path) - (format - #t (G_ "Skipping ~a (directory already exists)... done\n") - target-path) - (begin - (format #t (G_ "Creating ~a...") target-path) - (mkdir target-path) - (display (G_ " done\n")))))) - - (('file . path) - (when (file-exists? (get-target-path path)) - (backup-file path)) - (format #t (G_ "Symlinking ~a -> ~a...") - (get-target-path path) (get-source-path path)) - (symlink (get-source-path path) (get-target-path path)) - (display (G_ " done\n")))) - to-create))))) - - (when old-tree - (cleanup-symlinks)) - - (create-symlinks) - - (symlink new-home new-he-path) - (rename-file new-he-path he-path) - - (display (G_" done\nFinished updating symlinks.\n\n")))))) - + (with-imported-modules (source-module-closure + '((guix build utils) + (guix i18n))) + #~(begin + (use-modules (ice-9 ftw) + (ice-9 match) + (srfi srfi-1) + (guix i18n) + (guix build utils)) + + (define home-directory + (getenv "HOME")) + + (define xdg-config-home + (or (getenv "XDG_CONFIG_HOME") + (string-append (getenv "HOME") "/.config"))) + + (define backup-directory + (string-append home-directory "/" (number->string (current-time)) + "-guix-home-legacy-configs-backup")) + + (define (preprocess-file file) + "If file is in XDG-CONFIGURATION-FILES-DIRECTORY use +subdirectory from XDG_CONFIG_HOME to generate a target path." + (if (string-prefix? #$xdg-configuration-files-directory file) + (string-append + (substring xdg-config-home + (1+ (string-length home-directory))) + (substring file + (string-length #$xdg-configuration-files-directory))) + (string-append "." file))) + + (define (target-file file) + ;; Return the target of FILE, a config file name sans leading dot + ;; such as "config/fontconfig/fonts.conf" or "bashrc". + (string-append home-directory "/" (preprocess-file file))) + + (define (symlink-to-store? file) + (catch 'system-error + (lambda () + (store-file-name? (readlink file))) + (lambda args + (if (= EINVAL (system-error-errno args)) + #f + (apply throw args))))) + + (define (backup-file file) + (define backup + (string-append backup-directory "/" (preprocess-file file))) + + (mkdir-p backup-directory) + (format #t (G_ "Backing up ~a...") (target-file file)) + (mkdir-p (dirname backup)) + (rename-file (target-file file) backup) + (display (G_ " done\n"))) + + (define (cleanup-symlinks home-generation) + ;; Delete from $HOME files that originate in HOME-GENERATION, the + ;; store item containing a home generation. + (define config-file-directory + ;; Note: Trailing slash is needed because "files" is a symlink. + (string-append home-generation "/" #$home-files-directory "/")) + + (define (strip file) + (string-drop file + (+ 1 (string-length config-file-directory)))) + + (format #t (G_ "Cleaning up symlinks from previous home at ~a.~%") + home-generation) + (newline) + + (file-system-fold + (const #t) + (lambda (file stat _) ;leaf + (let ((file (target-file (strip file)))) + (when (file-exists? file) + ;; DO NOT remove the file if it is no longer a symlink to + ;; the store, it will be backed up later during + ;; create-symlinks phase. + (if (symlink-to-store? file) + (begin + (format #t (G_ "Removing ~a...") file) + (delete-file file) + (display (G_ " done\n"))) + (format + #t + (G_ "Skipping ~a (not a symlink to store)... done\n") + file))))) + + (const #t) ;down + (lambda (directory stat _) ;up + (unless (string=? directory config-file-directory) + (let ((directory (target-file (strip directory)))) + (catch 'system-error + (lambda () + (rmdir directory) + (format #t (G_ "Removed ~a.\n") directory)) + (lambda args + (let ((errno (system-error-errno args))) + (cond + ((= ENOTEMPTY errno) + (format + #t + (G_ "Skipping ~a (not an empty directory)... done\n") + directory)) + ((= ENOTDIR errno) #t) + (else + (apply throw args))))))))) + (const #t) ;skip + (const #t) ;error + #t ;init + config-file-directory + lstat) + + (display (G_ "Cleanup finished.\n\n"))) + + (define (create-symlinks home-generation) + ;; Create in $HOME symlinks for the files in HOME-GENERATION. + (define config-file-directory + ;; Note: Trailing slash is needed because "files" is a symlink. + (string-append home-generation "/" #$home-files-directory "/")) + + (define (strip file) + (string-drop file + (+ 1 (string-length config-file-directory)))) + + (define (source-file file) + (readlink (string-append config-file-directory file))) + + (file-system-fold + (const #t) ;enter? + (lambda (file stat result) ;leaf + (let ((source (source-file (strip file))) + (target (target-file (strip file)))) + (when (file-exists? target) + (backup-file (strip file))) + (format #t (G_ "Symlinking ~a -> ~a...") + target source) + (symlink source target) + (display (G_ " done\n")))) + (lambda (directory stat result) ;down + (unless (string=? directory config-file-directory) + (let ((target (target-file (strip directory)))) + (when (and (file-exists? target) + (not (file-is-directory? target))) + (backup-file (strip directory))) + + (catch 'system-error + (lambda () + (mkdir target)) + (lambda args + (let ((errno (system-error-errno args))) + (unless (= EEXIST errno) + (format #t (G_ "failed to create directory ~a: ~s~%") + target (strerror errno)) + (apply throw args)))))))) + (const #t) ;up + (const #t) ;skip + (const #t) ;error + #t ;init + config-file-directory)) + + #$%initialize-gettext + + (let* ((home (string-append home-directory "/.guix-home")) + (pivot (string-append home ".new")) + (new-home (getenv "GUIX_NEW_HOME")) + (old-home (getenv "GUIX_OLD_HOME"))) + (when old-home + (cleanup-symlinks old-home)) + + (create-symlinks new-home) + + (symlink new-home pivot) + (rename-file pivot home) + + (display (G_" done\nFinished updating symlinks.\n\n"))))))) (define (update-symlinks-gexp _) #~(primitive-load #$(update-symlinks-script))) diff --git a/gnu/home/services/xdg.scm b/gnu/home/services/xdg.scm index d230dd7665..361a2a6148 100644 --- a/gnu/home/services/xdg.scm +++ b/gnu/home/services/xdg.scm @@ -190,11 +190,11 @@ pre-populated content.") "Default directory for videos.")) (define (home-xdg-user-directories-files-service config) - `(("config/user-dirs.conf" + `(("user-dirs.conf" ,(mixed-text-file "user-dirs.conf" "enabled=False\n")) - ("config/user-dirs.dirs" + ("user-dirs.dirs" ,(mixed-text-file "user-dirs.dirs" (serialize-configuration @@ -218,7 +218,7 @@ pre-populated content.") (service-type (name 'home-xdg-user-directories) (extensions (list (service-extension - home-files-service-type + home-xdg-configuration-files-service-type home-xdg-user-directories-files-service) (service-extension home-activation-service-type @@ -374,7 +374,7 @@ configuration." "=" val "\n"))) (define (serialize-alist config) - (generic-serialize-alist identity format-config config)) + (generic-serialize-alist append format-config config)) (define (serialize-xdg-desktop-action action) (match action @@ -417,7 +417,7 @@ that the application cannot open the specified MIME type.") "A list of XDG desktop entries to create. See @code{xdg-desktop-entry}.")) -(define (home-xdg-mime-applications-files-service config) +(define (home-xdg-mime-applications-files config) (define (add-xdg-desktop-entry-file entry) (let ((file (first entry)) (config (second entry))) @@ -425,16 +425,16 @@ that the application cannot open the specified MIME type.") (apply mixed-text-file (format #f "xdg-desktop-~a-entry" file) config)))) + (map (compose add-xdg-desktop-entry-file serialize-xdg-desktop-entry) + (home-xdg-mime-applications-configuration-desktop-entries config))) - (append - `(("config/mimeapps.list" - ,(mixed-text-file - "xdg-mime-appplications" - (serialize-configuration - config - home-xdg-mime-applications-configuration-fields)))) - (map (compose add-xdg-desktop-entry-file serialize-xdg-desktop-entry) - (home-xdg-mime-applications-configuration-desktop-entries config)))) +(define (home-xdg-mime-applications-xdg-files config) + `(("mimeapps.list" + ,(mixed-text-file + "xdg-mime-appplications" + (serialize-configuration + config + home-xdg-mime-applications-configuration-fields))))) (define (home-xdg-mime-applications-extension old-config extension-configs) (define (extract-fields config) @@ -469,7 +469,10 @@ that the application cannot open the specified MIME type.") (extensions (list (service-extension home-files-service-type - home-xdg-mime-applications-files-service))) + home-xdg-mime-applications-files) + (service-extension + home-xdg-configuration-files-service-type + home-xdg-mime-applications-xdg-files))) (compose identity) (extend home-xdg-mime-applications-extension) (default-value (home-xdg-mime-applications-configuration)) |