From 4e27f8533b2236203efffdcc3eab0789f6f9fa58 Mon Sep 17 00:00:00 2001 From: anemofilia Date: Sat, 23 Sep 2023 12:02:32 -0300 Subject: [PATCH] feat: create a record to represent fish abbreviations declaratively in a more featureful and readable way --- modules/radix/home/services/shells.scm | 206 +++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 modules/radix/home/services/shells.scm diff --git a/modules/radix/home/services/shells.scm b/modules/radix/home/services/shells.scm new file mode 100644 index 0000000..61bc8a1 --- /dev/null +++ b/modules/radix/home/services/shells.scm @@ -0,0 +1,206 @@ +(define-module (radix home services shells) + #:use-module (gnu services configuration) + #:use-module (gnu home services utils) + #:use-module (gnu home services) + #:use-module (gnu packages shells) + #:use-module (guix gexp) + #:use-module (guix packages) + #:use-module (guix records) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-9) + #:use-module (srfi srfi-26) + #:use-module (ice-9 match) + + #:export (home-fish-service-type + home-fish-configuration + home-fish-extension + + abbreviation + abbreviation-expansion + abbreviation-marker + abbreviation-position + abbreviation-pattern + abbreviation-name + abbreviation? + + fish-function + fish-function-name + fish-function?)) + +;;; +;;; Fish. +;;; + +(define (serialize-fish-aliases field-name val) + #~(string-append + #$@(map (match-lambda + ((key . value) + #~(string-append "alias " #$key " \"" #$value "\"\n")) + (_ "")) + val))) + +(define-record-type + (fish-function name) + fish-function? + (name fish-function-name)) + +(define-record-type* + abbreviation make-abbreviation + abbreviation? + (name abbreviation-name) ; string + (pattern abbreviation-pattern ; string | #f + (default #f)) + (position abbreviation-position ; "command" | "anywhere" | #f + (default #f)) ; defaults to "command" -ยด + (marker abbreviation-marker ; char + (default #\%)) + (expansion abbreviation-expansion)) ; string | + +(define list-of-abbreviations? + (list-of abbreviation?)) + +(define (serialize-fish-abbreviations field-name val) + #~(string-append + #$@(map (lambda (abbr) + (match-record abbr + (name pattern position marker expansion) + #~((@@ (ice-9 format) format) #f + "abbr --add ~a ~ + ~@[--position ~a ~]~ + ~@[--regex ~a ~]~ + --set-cursor=~a ~ + ~a~%" + #$name + #$position + #$pattern + #$marker + #$(if (fish-function? expansion) + (format #f "--function ~a" + (fish-function-name expansion)) + (format #f "\"~a\"" expansion))))) + val))) + +(define (serialize-fish-env-vars field-name val) + #~(string-append + #$@(map (match-lambda + ((key . #f) + "") + ((key . #t) + #~(string-append "set -x " #$key "\n")) + ((key . value) + #~(string-append "set -x " #$key " " #$value "\n"))) + val))) + +(define-configuration home-fish-configuration + (package + (package fish) + "The Fish package to use.") + (config + (text-config '()) + "List of file-like objects, which will be added to +@file{$XDG_CONFIG_HOME/fish/config.fish}.") + (environment-variables + (alist '()) + "Association list of environment variables to set in Fish." + (serializer serialize-fish-env-vars)) + (aliases + (alist '()) + "Association list of aliases for Fish, both the key and the value +should be a string. An alias is just a simple function that wraps a +command, If you want something more akin to @dfn{aliases} in POSIX +shells, see the @code{abbreviations} field." + (serializer serialize-fish-aliases)) + (abbreviations + (list-of-abbreviations '()) + "List of abbreviations for Fish. These are words that, when +typed in the shell, will automatically expand to the full text." + (serializer serialize-fish-abbreviations))) + +(define (fish-files-service config) + `(("fish/config.fish" + ,(mixed-text-file + "fish-config.fish" + #~(string-append "\ +# if we haven't sourced the login config, do it +status --is-login; and not set -q __fish_login_config_sourced +and begin + + set --prepend fish_function_path " + #$fish-foreign-env + "/share/fish/functions + fenv source $HOME/.profile + set -e fish_function_path[1] + + set -g __fish_login_config_sourced 1 + +end\n\n") + (serialize-configuration + config + home-fish-configuration-fields))))) + +(define (fish-profile-service config) + (list (home-fish-configuration-package config))) + +(define-configuration/no-serialization home-fish-extension + (config + (text-config '()) + "List of file-like objects for extending the Fish initialization file.") + (environment-variables + (alist '()) + "Association list of environment variables to set.") + (aliases + (alist '()) + "Association list of Fish aliases.") + (abbreviations + (list-of-abbreviations '()) + "Association list of Fish abbreviations.")) + +(define (home-fish-extensions original-config extension-configs) + (home-fish-configuration + (inherit original-config) + (config + (append (home-fish-configuration-config original-config) + (append-map + home-fish-extension-config extension-configs))) + (environment-variables + (append (home-fish-configuration-environment-variables original-config) + (append-map + home-fish-extension-environment-variables extension-configs))) + (aliases + (append (home-fish-configuration-aliases original-config) + (append-map + home-fish-extension-aliases extension-configs))) + (abbreviations + (append (home-fish-configuration-abbreviations original-config) + (append-map + home-fish-extension-abbreviations extension-configs))))) + +;; TODO: Support for generating completion files +;; TODO: Support for installing plugins +(define home-fish-service-type + (service-type (name 'home-fish) + (extensions + (list (service-extension + home-xdg-configuration-files-service-type + fish-files-service) + (service-extension + home-profile-service-type + fish-profile-service))) + (compose identity) + (extend home-fish-extensions) + (default-value (home-fish-configuration)) + (description "\ +Install and configure Fish, the friendly interactive shell."))) + +(define (generate-home-fish-documentation) + (string-append + (generate-documentation + `((home-fish-configuration + ,home-fish-configuration-fields)) + 'home-fish-configuration) + "\n\n" + (generate-documentation + `((home-fish-extension + ,home-fish-extension-fields)) + 'home-fish-extension))) +