summaryrefslogtreecommitdiff
path: root/gnu/home-services/xdg.scm
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/home-services/xdg.scm')
-rw-r--r--gnu/home-services/xdg.scm478
1 files changed, 0 insertions, 478 deletions
diff --git a/gnu/home-services/xdg.scm b/gnu/home-services/xdg.scm
deleted file mode 100644
index 94275f3b65..0000000000
--- a/gnu/home-services/xdg.scm
+++ /dev/null
@@ -1,478 +0,0 @@
-;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2021 Andrew Tropin <andrew@trop.in>
-;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
-;;;
-;;; 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 xdg)
- #:use-module (gnu services configuration)
- #:use-module (gnu home-services configuration)
- #:use-module (gnu home-services)
- #:use-module (gnu packages freedesktop)
- #:use-module (gnu home-services utils)
- #:use-module (guix gexp)
- #:use-module (guix records)
- #:use-module (guix i18n)
- #:use-module (guix diagnostics)
-
- #:use-module (ice-9 match)
- #:use-module (srfi srfi-1)
- #:use-module (rnrs enums)
-
- #:export (home-xdg-base-directories-service-type
- home-xdg-base-directories-configuration
- home-xdg-base-directories-configuration?
-
- home-xdg-user-directories-service-type
- home-xdg-user-directories-configuration
- home-xdg-user-directories-configuration?
-
- xdg-desktop-action
- xdg-desktop-entry
- home-xdg-mime-applications-service-type
- home-xdg-mime-applications-configuration))
-
-;;; Commentary:
-;;
-;; This module contains services related to XDG directories and
-;; applications.
-;;
-;; - XDG base directories
-;; - XDG user directories
-;; - XDG MIME applications
-;;
-;;; Code:
-
-
-;;;
-;;; XDG base directories.
-;;;
-
-(define (serialize-path field-name val) "")
-(define path? string?)
-
-(define-configuration home-xdg-base-directories-configuration
- (cache-home
- (path "$HOME/.cache")
- "Base directory for programs to store user-specific non-essential
-(cached) data. Files in this directory can be deleted anytime without
-loss of important data.")
- (config-home
- (path "$HOME/.config")
- "Base directory for programs to store configuration files.
-Some programs store here log or state files, but it's not desired,
-this directory should contain static configurations.")
- (data-home
- (path "$HOME/.local/share")
- "Base directory for programs to store architecture independent
-read-only shared data, analogus to @file{/usr/share}, but for user.")
- (runtime-dir
- (path "${XDG_RUNTIME_DIR:-/run/user/$UID}")
- "Base directory for programs to store user-specific runtime files,
-like sockets.")
- (log-home
- (path "$HOME/.local/var/log")
- "Base directory for programs to store log files, analogus to
-@file{/var/log}, but for user. It is not a part of XDG Base Directory
-Specification, but helps to make implementation of home services more
-consistent.")
- (state-home
- (path "$HOME/.local/var/lib")
- "Base directory for programs to store state files, like databases,
-analogus to @file{/var/lib}, but for user. It is not a part of XDG
-Base Directory Specification, but helps to make implementation of home
-services more consistent."))
-
-(define (home-xdg-base-directories-environment-variables-service config)
- (map
- (lambda (field)
- (cons (format
- #f "XDG_~a"
- (object->snake-case-string (configuration-field-name field) 'upper))
- ((configuration-field-getter field) config)))
- home-xdg-base-directories-configuration-fields))
-
-(define (ensure-xdg-base-dirs-on-activation config)
- #~(map (lambda (xdg-base-dir-variable)
- ((@@ (guix build utils) mkdir-p)
- (getenv
- xdg-base-dir-variable)))
- '#$(map (lambda (field)
- (format
- #f "XDG_~a"
- (object->snake-case-string
- (configuration-field-name field) 'upper)))
- home-xdg-base-directories-configuration-fields)))
-
-(define (last-extension-or-cfg config extensions)
- "Picks configuration value from last provided extension. If there
-are no extensions use configuration instead."
- (or (and (not (null? extensions)) (last extensions)) config))
-
-(define home-xdg-base-directories-service-type
- (service-type (name 'home-xdg-base-directories)
- (extensions
- (list (service-extension
- home-environment-variables-service-type
- home-xdg-base-directories-environment-variables-service)
- (service-extension
- home-activation-service-type
- ensure-xdg-base-dirs-on-activation)))
- (default-value (home-xdg-base-directories-configuration))
- (compose identity)
- (extend last-extension-or-cfg)
- (description "Configure XDG base directories. This
-service introduces two additional variables @env{XDG_STATE_HOME},
-@env{XDG_LOG_HOME}. They are not a part of XDG specification, at
-least yet, but are convinient to have, it improves the consistency
-between different home services. The services of this service-type is
-instantiated by default, to provide non-default value, extend the
-service-type (using @code{simple-service} for example).")))
-
-(define (generate-home-xdg-base-directories-documentation)
- (generate-documentation
- `((home-xdg-base-directories-configuration
- ,home-xdg-base-directories-configuration-fields))
- 'home-xdg-base-directories-configuration))
-
-
-;;;
-;;; XDG user directories.
-;;;
-
-(define (serialize-string field-name val)
- ;; The path has to be quoted
- (format #f "XDG_~a_DIR=\"~a\"\n"
- (object->snake-case-string field-name 'upper) val))
-
-(define-configuration home-xdg-user-directories-configuration
- (desktop
- (string "$HOME/Desktop")
- "Default ``desktop'' directory, this is what you see on your
-desktop when using a desktop environment,
-e.g. GNOME (@pxref{XWindow,,,guix.info}).")
- (documents
- (string "$HOME/Documents")
- "Default directory to put documents like PDFs.")
- (download
- (string "$HOME/Downloads")
- "Default directory downloaded files, this is where your Web-broser
-will put downloaded files in.")
- (music
- (string "$HOME/Music")
- "Default directory for audio files.")
- (pictures
- (string "$HOME/Pictures")
- "Default directory for pictures and images.")
- (publicshare
- (string "$HOME/Public")
- "Default directory for shared files, which can be accessed by other
-users on local machine or via network.")
- (templates
- (string "$HOME/Templates")
- "Default directory for templates. They can be used by graphical
-file manager or other apps for creating new files with some
-pre-populated content.")
- (videos
- (string "$HOME/Videos")
- "Default directory for videos."))
-
-(define (home-xdg-user-directories-files-service config)
- `(("config/user-dirs.conf"
- ,(mixed-text-file
- "user-dirs.conf"
- "enabled=False\n"))
- ("config/user-dirs.dirs"
- ,(mixed-text-file
- "user-dirs.dirs"
- (serialize-configuration
- config
- home-xdg-user-directories-configuration-fields)))))
-
-(define (home-xdg-user-directories-activation-service config)
- (let ((dirs (map (lambda (field)
- ((configuration-field-getter field) config))
- home-xdg-user-directories-configuration-fields)))
- #~(let ((ensure-dir
- (lambda (path)
- (mkdir-p
- ((@@ (ice-9 string-fun) string-replace-substring)
- path "$HOME" (getenv "HOME"))))))
- (display "Creating XDG user directories...")
- (map ensure-dir '#$dirs)
- (display " done\n"))))
-
-(define home-xdg-user-directories-service-type
- (service-type (name 'home-xdg-user-directories)
- (extensions
- (list (service-extension
- home-files-service-type
- home-xdg-user-directories-files-service)
- (service-extension
- home-activation-service-type
- home-xdg-user-directories-activation-service)))
- (default-value (home-xdg-user-directories-configuration))
- (description "Configure XDG user directories. To
-disable a directory, point it to the $HOME.")))
-
-(define (generate-home-xdg-user-directories-documentation)
- (generate-documentation
- `((home-xdg-user-directories-configuration
- ,home-xdg-user-directories-configuration-fields))
- 'home-xdg-user-directories-configuration))
-
-
-;;;
-;;; XDG MIME applications.
-;;;
-
-;; Example config
-;;
-;; (home-xdg-mime-applications-configuration
-;; (added '((x-scheme-handler/magnet . torrent.desktop)))
-;; (default '((inode/directory . file.desktop)))
-;; (removed '((inode/directory . thunar.desktop)))
-;; (desktop-entries
-;; (list (xdg-desktop-entry
-;; (file "file")
-;; (name "File manager")
-;; (type 'application)
-;; (config
-;; '((exec . "emacsclient -c -a emacs %u"))))
-;; (xdg-desktop-entry
-;; (file "text")
-;; (name "Text editor")
-;; (type 'application)
-;; (config
-;; '((exec . "emacsclient -c -a emacs %u")))
-;; (actions
-;; (list (xdg-desktop-action
-;; (action 'create)
-;; (name "Create an action")
-;; (config
-;; '((exec . "echo hi"))))))))))
-
-;; See
-;; <https://specifications.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html>
-;; <https://specifications.freedesktop.org/mime-apps-spec/mime-apps-spec-latest.html>
-
-(define (serialize-alist field-name val)
- (define (serialize-mimelist-entry key val)
- (let ((val (cond
- ((list? val)
- (string-join (map maybe-object->string val) ";"))
- ((or (string? val) (symbol? val))
- val)
- (else (raise (formatted-message
- (G_ "\
-The value of an XDG MIME entry must be a list, string or symbol, was given ~a")
- val))))))
- (format #f "~a=~a\n" key val)))
-
- (define (merge-duplicates alist acc)
- "Merge values that have the same key.
-
-@example
-(merge-duplicates '((key1 . value1)
- (key2 . value2)
- (key1 . value3)
- (key1 . value4)) '())
-
-@result{} ((key1 . (value4 value3 value1)) (key2 . value2))
-@end example"
- (cond
- ((null? alist) acc)
- (else (let* ((head (first alist))
- (tail (cdr alist))
- (key (first head))
- (value (cdr head))
- (duplicate? (assoc key acc))
- (ensure-list (lambda (x)
- (if (list? x) x (list x)))))
- (if duplicate?
- ;; XXX: This will change the order of things,
- ;; though, it shouldn't be a problem for XDG MIME.
- (merge-duplicates
- tail
- (alist-cons key
- (cons value (ensure-list (cdr duplicate?)))
- (alist-delete key acc)))
- (merge-duplicates tail (cons head acc)))))))
-
- (string-append (if (equal? field-name 'default)
- "\n[Default Applications]\n"
- (format #f "\n[~a Associations]\n"
- (string-capitalize (symbol->string field-name))))
- (generic-serialize-alist string-append
- serialize-mimelist-entry
- (merge-duplicates val '()))))
-
-(define xdg-desktop-types (make-enumeration
- '(application
- link
- directory)))
-
-(define (xdg-desktop-type? type)
- (unless (enum-set-member? type xdg-desktop-types)
- (raise (formatted-message
- (G_ "XDG desktop type must be of of ~a, was given: ~a")
- (list->human-readable-list (enum-set->list xdg-desktop-types))
- type))))
-
-;; TODO: Add proper docs for this
-;; XXX: 'define-configuration' require that fields have a default
-;; value.
-(define-record-type* <xdg-desktop-action>
- xdg-desktop-action make-xdg-desktop-action
- xdg-desktop-action?
- (action xdg-desktop-action-action) ; symbol
- (name xdg-desktop-action-name) ; string
- (config xdg-desktop-action-config ; alist
- (default '())))
-
-(define-record-type* <xdg-desktop-entry>
- xdg-desktop-entry make-xdg-desktop-entry
- xdg-desktop-entry?
- ;; ".desktop" will automatically be added
- (file xdg-desktop-entry-file) ; string
- (name xdg-desktop-entry-name) ; string
- (type xdg-desktop-entry-type) ; xdg-desktop-type
- (config xdg-desktop-entry-config ; alist
- (default '()))
- (actions xdg-desktop-entry-actions ; list of <xdg-desktop-action>
- (default '())))
-
-(define desktop-entries? (list-of xdg-desktop-entry?))
-(define (serialize-desktop-entries field-name val) "")
-
-(define (serialize-xdg-desktop-entry entry)
- "Return a tuple of the file name for ENTRY and the serialized
-configuration."
- (define (format-config key val)
- (let ((val (cond
- ((list? val)
- (string-join (map maybe-object->string val) ";"))
- ((boolean? val)
- (if val "true" "false"))
- (else val)))
- (key (string-capitalize (maybe-object->string key))))
- (list (if (string-suffix? key "?")
- (string-drop-right key (- (string-length key) 1))
- key)
- "=" val "\n")))
-
- (define (serialize-alist config)
- (generic-serialize-alist identity format-config config))
-
- (define (serialize-xdg-desktop-action action)
- (match action
- (($ <xdg-desktop-action> action name config)
- `(,(format #f "[Desktop Action ~a]\n"
- (string-capitalize (maybe-object->string action)))
- ,(format #f "Name=~a\n" name)
- ,@(serialize-alist config)))))
-
- (match entry
- (($ <xdg-desktop-entry> file name type config actions)
- (list (if (string-suffix? file ".desktop")
- file
- (string-append file ".desktop"))
- `("[Desktop Entry]\n"
- ,(format #f "Name=~a\n" name)
- ,(format #f "Type=~a\n"
- (string-capitalize (symbol->string type)))
- ,@(serialize-alist config)
- ,@(append-map serialize-xdg-desktop-action actions))))))
-
-(define-configuration home-xdg-mime-applications-configuration
- (added
- (alist '())
- "An association list of MIME types and desktop entries which indicate
-that the application should used to open the specified MIME type. The
-value has to be string, symbol, or list of strings or symbols, this
-applies to the `@code{default}', and `@code{removed}' fields as well.")
- (default
- (alist '())
- "An association list of MIME types and desktop entries which indicate
-that the application should be the default for opening the specified
-MIME type.")
- (removed
- (alist '())
- "An association list of MIME types and desktop entries which indicate
-that the application cannot open the specified MIME type.")
- (desktop-entries
- (desktop-entries '())
- "A list of XDG desktop entries to create. See
-@code{xdg-desktop-entry}."))
-
-(define (home-xdg-mime-applications-files-service config)
- (define (add-xdg-desktop-entry-file entry)
- (let ((file (first entry))
- (config (second entry)))
- (list (format #f "local/share/applications/~a" file)
- (apply mixed-text-file
- (format #f "xdg-desktop-~a-entry" file)
- 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-extension old-config extension-configs)
- (define (extract-fields config)
- ;; return '(added default removed desktop-entries)
- (list (home-xdg-mime-applications-configuration-added config)
- (home-xdg-mime-applications-configuration-default config)
- (home-xdg-mime-applications-configuration-removed config)
- (home-xdg-mime-applications-configuration-desktop-entries config)))
-
- (define (append-configs elem acc)
- (list (append (first elem) (first acc))
- (append (second elem) (second acc))
- (append (third elem) (third acc))
- (append (fourth elem) (fourth acc))))
-
- ;; TODO: Implement procedure to check for duplicates without
- ;; sacrificing performance.
- ;;
- ;; Combine all the alists from 'added', 'default' and 'removed'
- ;; into one big alist.
- (let ((folded-configs (fold append-configs
- (extract-fields old-config)
- (map extract-fields extension-configs))))
- (home-xdg-mime-applications-configuration
- (added (first folded-configs))
- (default (second folded-configs))
- (removed (third folded-configs))
- (desktop-entries (fourth folded-configs)))))
-
-(define home-xdg-mime-applications-service-type
- (service-type (name 'home-xdg-mime-applications)
- (extensions
- (list (service-extension
- home-files-service-type
- home-xdg-mime-applications-files-service)))
- (compose identity)
- (extend home-xdg-mime-applications-extension)
- (default-value (home-xdg-mime-applications-configuration))
- (description
- "Configure XDG MIME applications, and XDG desktop entries.")))