feat: create a record to represent fish abbreviations declaratively in a more featureful and readable way

pull/1/head
anemofilia 2023-09-23 12:02:32 -03:00
parent d2cec18208
commit 4e27f8533b
No known key found for this signature in database
GPG Key ID: 5A8F3D62C87A2B33
1 changed files with 206 additions and 0 deletions

View File

@ -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>
(fish-function name)
fish-function?
(name fish-function-name))
(define-record-type* <abbreviation>
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 | <fish-function>
(define list-of-abbreviations?
(list-of abbreviation?))
(define (serialize-fish-abbreviations field-name val)
#~(string-append
#$@(map (lambda (abbr)
(match-record abbr <abbreviation>
(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)))