From 3f900442b4b3199f8601934ee1674b178858a412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Tue, 30 Sep 2025 11:08:13 +0200 Subject: [PATCH] home: services: bash: Support setting shell variables. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * gnu/home/services.scm (shell-variable-definitions): New procedure. * gnu/home/services/shells.scm (serialize-shell-variables): New procedure. (home-bash-configuration)[variables]: New field. (add-bash-configuration): Honor it. (home-bash-extension)[variables]: New field. (home-bash-extensions): Handle ‘variables’. * doc/guix.texi (Shells Home Services): Update. Change ‘PS1’ example to use ‘variables’, not ‘environment-variables’. * doc/he-config-bare-bones.scm: Use ‘variables’ instead of ‘bash-profile’. Change-Id: I29083d6313d10b1eb9d91eccacfb33efefe60d58 --- doc/guix.texi | 67 +++++++++++++++++++++++------------- doc/he-config-bare-bones.scm | 5 +-- gnu/home/services.scm | 24 ++++++++++++- gnu/home/services/shells.scm | 31 ++++++++++++++--- 4 files changed, 96 insertions(+), 31 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index b26e6296c35..5d6698ddf33 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -50319,6 +50319,8 @@ Extend home-shell-profile service only if you really know what you do. @subsubheading Bash Home Service @anchor{home-bash-configuration} +@c %start of fragment + @deftp {Data Type} home-bash-configuration Available @code{home-bash-configuration} fields are: @@ -50333,13 +50335,19 @@ use Guix System, is it safe to set this to @code{#f}, as in this case this is already taken care of by the globally installed @file{/etc/bashrc}. -@item @code{environment-variables} (default: @code{'()}) (type: alist) -Association list of environment variables to set for the Bash session. The -rules for the @code{home-environment-variables-service-type} apply -here (@pxref{Essential Home Services}). The contents of this field will be -added after the contents of the @code{bash-profile} field. +@item @code{environment-variables} (default: @code{()}) (type: alist) +Association list of environment variables to set for the Bash session. +The rules for the @code{home-environment-variables-service-type} apply +here (@pxref{Essential Home Services}). The contents of this field will +be added after the contents of the @code{bash-profile} field. -@item @code{aliases} (default: @code{%default-bash-aliases}) (type: alist) +@item @code{variables} (default: @code{()}) (type: alist) +Bash variables (not to be confused with environment variables) to be set +in @file{.bashrc} for use by interactive shells. A typical example of +such variables is @code{HISTSIZE} and related history variables +(@pxref{Bash Variables,,, bash,Bash Reference Manual}). + +@item @code{aliases} (type: alist) Association list of aliases to set for the Bash session. The aliases will be defined after the contents of the @code{bashrc} field has been put in the @file{.bashrc} file. The alias will automatically be quoted, @@ -50355,27 +50363,31 @@ turns into alias ls="ls -alF" @end example -@item @code{bash-profile} (default: @code{'()}) (type: text-config) +@item @code{bash-profile} (default: @code{()}) (type: text-config) List of file-like objects, which will be added to @file{.bash_profile}. Used for executing user's commands at start of login shell (In most cases the shell started on tty just after login). @file{.bash_login} won't be ever read, because @file{.bash_profile} always present. -@item @code{bashrc} (default: @code{'()}) (type: text-config) +@item @code{bashrc} (default: @code{()}) (type: text-config) List of file-like objects, which will be added to @file{.bashrc}. Used for executing user's commands at start of interactive shell (The shell for interactive usage started by typing @code{bash} or by terminal app or any other program). -@item @code{bash-logout} (default: @code{'()}) (type: text-config) +@item @code{bash-logout} (default: @code{()}) (type: text-config) List of file-like objects, which will be added to @file{.bash_logout}. 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). @end table + @end deftp + +@c %end of fragment + You can extend the Bash service by using the @code{home-bash-extension} configuration record, whose fields must mirror that of @code{home-bash-configuration} (@pxref{home-bash-configuration}). The @@ -50385,14 +50397,14 @@ Bash Reference Manual}. For example, here is how you would define a service that extends the Bash service such that @file{~/.bash_profile} defines an additional -environment variable, @env{PS1}: +shell variable, @env{PS1}: @lisp (define bash-fancy-prompt-service (simple-service 'bash-fancy-prompt home-bash-service-type (home-bash-extension - (environment-variables + (variables '(("PS1" . "\\u \\wλ ")))))) @end lisp @@ -50400,34 +50412,43 @@ You would then add @code{bash-fancy-prompt-service} to the list in the @code{services} field of your @code{home-environment}. The reference of @code{home-bash-extension} follows. +@c %start of fragment + @deftp {Data Type} home-bash-extension Available @code{home-bash-extension} fields are: @table @asis -@item @code{environment-variables} (default: @code{'()}) (type: alist) -Additional environment variables to set. These will be combined with the -environment variables from other extensions and the base service to form one -coherent block of environment variables. +@item @code{environment-variables} (default: @code{()}) (type: alist) +Additional environment variables to set. These will be combined with +the environment variables from other extensions and the base service to +form one coherent block of environment variables. -@item @code{aliases} (default: @code{'()}) (type: alist) +@item @code{variables} (default: @code{()}) (type: alist) +Extra Bash variables (not to be confused with environment variables) to +be set in @file{.bashrc} for use by interactive shells. + +@item @code{aliases} (default: @code{()}) (type: alist) Additional aliases to set. These will be combined with the aliases from other extensions and the base service. -@item @code{bash-profile} (default: @code{'()}) (type: text-config) -Additional text blocks to add to @file{.bash_profile}, which will be combined -with text blocks from other extensions and the base service. +@item @code{bash-profile} (default: @code{()}) (type: text-config) +Additional text blocks to add to @file{.bash_profile}, which will be +combined with text blocks from other extensions and the base service. -@item @code{bashrc} (default: @code{'()}) (type: text-config) +@item @code{bashrc} (default: @code{()}) (type: text-config) Additional text blocks to add to @file{.bashrc}, which will be combined with text blocks from other extensions and the base service. -@item @code{bash-logout} (default: @code{'()}) (type: text-config) -Additional text blocks to add to @file{.bash_logout}, which will be combined -with text blocks from other extensions and the base service. +@item @code{bash-logout} (default: @code{()}) (type: text-config) +Additional text blocks to add to @file{.bash_logout}, which will be +combined with text blocks from other extensions and the base service. @end table + @end deftp +@c %end of fragment + @subsubheading Zsh Home Service @deftp {Data Type} home-zsh-configuration diff --git a/doc/he-config-bare-bones.scm b/doc/he-config-bare-bones.scm index 844d666110f..d6a5121471d 100644 --- a/doc/he-config-bare-bones.scm +++ b/doc/he-config-bare-bones.scm @@ -13,8 +13,9 @@ (service home-bash-service-type (home-bash-configuration (guix-defaults? #t) - (bash-profile (list (plain-file "bash-profile" "\ -export HISTFILE=$XDG_CACHE_HOME/.bash_history"))))) + (variables + `(("HISTFILE" . "$XDG_CACHE_HOME/.bash_history") + ("HISTSIZE" . "50000"))))) (simple-service 'test-config home-xdg-configuration-files-service-type diff --git a/gnu/home/services.scm b/gnu/home/services.scm index d194d02fd4b..2e51a983cbd 100644 --- a/gnu/home/services.scm +++ b/gnu/home/services.scm @@ -1,7 +1,7 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2021-2023 Andrew Tropin ;;; Copyright © 2021 Xinglu Chen -;;; Copyright © 2022-2023 Ludovic Courtès +;;; Copyright © 2022-2023, 2025 Ludovic Courtès ;;; Copyright © 2023 Carlo Zancanaro ;;; ;;; This file is part of GNU Guix. @@ -58,6 +58,7 @@ with-shell-quotation-bindings environment-variable-shell-definitions + shell-variable-definitions home-files-directory xdg-configuration-files-directory xdg-data-files-directory @@ -241,6 +242,27 @@ ensures variable values are properly quoted." "\n"))) variables)))) +(define (shell-variable-definitions variables) + "Return a gexp that evaluates to a list of POSIX shell statements defining +VARIABLES, a list of variable name/value pairs, as shell variables (not +environment variables). The returned code ensures variable values are +properly quoted." + (with-shell-quotation-bindings + #~(string-append + #$@(map (match-lambda + ((key . (or (? string? value) + (? file-like? value) + (? gexp? value))) + #~(string-append #$key "=" + (shell-double-quote #$value) + "\n")) + ((key . (? literal-string? value)) + #~(string-append #$key "=" + (shell-single-quote + #$(literal-string-value value)) + "\n"))) + variables)))) + (define (environment-variables->setup-environment-script vars) "Return a file that can be sourced by a POSIX compliant shell which initializes the environment. The file will source the home diff --git a/gnu/home/services/shells.scm b/gnu/home/services/shells.scm index 969a3eb8dcf..a218fdb0a2d 100644 --- a/gnu/home/services/shells.scm +++ b/gnu/home/services/shells.scm @@ -2,6 +2,7 @@ ;;; Copyright © 2021 Andrew Tropin ;;; Copyright © 2021 Xinglu Chen ;;; Copyright © 2023 Efraim Flashner +;;; Copyright © 2025 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -121,6 +122,9 @@ service type can be extended with a list of file-like objects."))) (define (serialize-posix-env-vars field-name val) (environment-variable-shell-definitions val)) +(define (serialize-shell-variables field value) + (shell-variable-definitions value)) + ;;; ;;; Zsh. @@ -347,6 +351,13 @@ rules for the @code{home-environment-variables-service-type} apply here (@pxref{Essential Home Services}). The contents of this field will be added after the contents of the @code{bash-profile} field." (serializer serialize-posix-env-vars)) + (variables + (alist '()) + "Bash variables (not to be confused with environment variables) to be set +in @file{.bashrc} for use by interactive shells. A typical example of such +variables is @code{HISTSIZE} and related history variables (@pxref{Bash +Variables,,, bash, Bash Reference Manual})." + (serializer serialize-shell-variables)) (aliases (alist %default-bash-aliases) "Association list of aliases to set for the Bash session. The aliases will be @@ -425,10 +436,12 @@ if [ -f ~/.bashrc ]; then source ~/.bashrc; fi ,@(list (file-if-not-empty 'bashrc - (if (home-bash-configuration-guix-defaults? config) - (list (plain-file-content %default-bashrc) "\n" - (serialize-field 'aliases)) - (list (serialize-field 'aliases)))) + (let ((user-settings (list (serialize-field 'variables) "\n" + (serialize-field 'aliases)))) + (if (home-bash-configuration-guix-defaults? config) + (cons* (plain-file-content %default-bashrc) "\n" + user-settings) + user-settings))) (file-if-not-empty 'bash-logout))))) (define (add-bash-packages config) @@ -440,6 +453,10 @@ if [ -f ~/.bashrc ]; then source ~/.bashrc; fi "Additional environment variables to set. These will be combined with the environment variables from other extensions and the base service to form one coherent block of environment variables.") + (variables + (alist '()) + "Extra Bash variables (not to be confused with environment variables) to be +set in @file{.bashrc} for use by interactive shells.") (aliases (alist '()) "Additional aliases to set. These will be combined with the aliases from @@ -459,13 +476,17 @@ with text blocks from other extensions and the base service.")) (define (home-bash-extensions original-config extension-configs) (match-record original-config - (environment-variables aliases bash-profile bashrc bash-logout) + (environment-variables variables aliases bash-profile bashrc bash-logout) (home-bash-configuration (inherit original-config) (environment-variables (append environment-variables (append-map home-bash-extension-environment-variables extension-configs))) + (variables + (append variables + (append-map + home-bash-extension-variables extension-configs))) (aliases (append aliases (append-map