projects/guix·blob python-team · refs

829 lines · 27.4 KiB

1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2021 Andrew Tropin <[email protected]>
3;;; Copyright © 2021 Xinglu Chen <[email protected]>
4;;; Copyright © 2023 Efraim Flashner <[email protected]>
5;;; Copyright © 2025 Ludovic Courtès <[email protected]>
6;;;
7;;; This file is part of GNU Guix.
8;;;
9;;; GNU Guix is free software; you can redistribute it and/or modify it
10;;; under the terms of the GNU General Public License as published by
11;;; the Free Software Foundation; either version 3 of the License, or (at
12;;; your option) any later version.
13;;;
14;;; GNU Guix is distributed in the hope that it will be useful, but
15;;; WITHOUT ANY WARRANTY; without even the implied warranty of
16;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;;; GNU General Public License for more details.
18;;;
19;;; You should have received a copy of the GNU General Public License
20;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
21
22;;; Commentary:
23;;;
24;;; This module contains shell related services like Zsh.
25;;;
26;;; Code:
27
28(define-module (gnu home services shells)
29 #:use-module (gnu services configuration)
30 #:use-module ((gnu services) #:select (%default-bash-aliases))
31 #:autoload (gnu system shadow) (%default-bashrc %default-zprofile)
32 #:use-module (gnu home services utils)
33 #:use-module (gnu home services)
34 #:use-module (gnu packages shells)
35 #:use-module (gnu packages bash)
36 #:use-module (guix gexp)
37 #:use-module (guix packages)
38 #:use-module (guix records)
39 #:use-module (srfi srfi-1)
40 #:use-module (srfi srfi-26)
41 #:use-module (ice-9 match)
42
43 #:export (home-shell-profile-service-type
44 home-shell-profile-configuration
45
46 home-bash-service-type
47 home-bash-configuration
48 home-bash-extension
49
50 home-zsh-service-type
51 home-zsh-configuration
52 home-zsh-extension
53
54 home-fish-service-type
55 home-fish-configuration
56 home-fish-extension
57
58 home-inputrc-service-type
59 home-inputrc-configuration))
60
61
62;;;
63;;; Shell profile.
64;;;
65
66(define path? string?)
67(define (serialize-path field-name val) val)
68
69(define-configuration home-shell-profile-configuration
70 (profile
71 (text-config '())
72 "\
73@code{home-shell-profile} is instantiated automatically by
74@code{home-environment}, DO NOT create this service manually, it can
75only be extended.
76
77@code{profile} is a list of file-like objects, which will go to
78@file{~/.profile}. By default @file{~/.profile} contains the
79initialization code, which have to be evaluated by login shell to make
80home-environment's profile available to the user, but other commands
81can be added to the file if it is really necessary.
82
83In most cases shell's configuration files are preferred places for
84user's customizations. Extend home-shell-profile service only if you
85really know what you do."))
86
87(define (add-shell-profile-file config)
88 `((".profile"
89 ,(mixed-text-file
90 "shell-profile"
91 "\
92HOME_ENVIRONMENT=$HOME/.guix-home
93. $HOME_ENVIRONMENT/setup-environment
94$HOME_ENVIRONMENT/on-first-login
95unset HOME_ENVIRONMENT\n"
96 (serialize-configuration
97 config
98 (filter-configuration-fields
99 home-shell-profile-configuration-fields '(profile)))))))
100
101(define (add-profile-extensions config extensions)
102 (home-shell-profile-configuration
103 (inherit config)
104 (profile
105 (append (home-shell-profile-configuration-profile config)
106 extensions))))
107
108(define home-shell-profile-service-type
109 (service-type (name 'home-shell-profile)
110 (extensions
111 (list (service-extension
112 home-files-service-type
113 add-shell-profile-file)))
114 (compose concatenate)
115 (extend add-profile-extensions)
116 (default-value (home-shell-profile-configuration))
117 (description "Create @file{~/.profile}, which is used
118for environment initialization of POSIX compliant login shells. This
119service type can be extended with a list of file-like objects.")))
120
121(define (serialize-boolean field-name val) "")
122(define (serialize-posix-env-vars field-name val)
123 (environment-variable-shell-definitions val))
124
125(define (serialize-shell-variables field value)
126 (shell-variable-definitions value))
127
128
129;;;
130;;; Zsh.
131;;;
132
133(define-configuration home-zsh-configuration
134 (package
135 (package zsh)
136 "The Zsh package to use.")
137 (xdg-flavor?
138 (boolean #t)
139 "Place all the configs to @file{$XDG_CONFIG_HOME/zsh}. Makes
140@file{~/.zshenv} to set @env{ZDOTDIR} to @file{$XDG_CONFIG_HOME/zsh}.
141Shell startup process will continue with
142@file{$XDG_CONFIG_HOME/zsh/.zshenv}.")
143 (environment-variables
144 (alist '())
145 "Association list of environment variables to set for the Zsh session."
146 (serializer serialize-posix-env-vars))
147 (zshenv
148 (text-config '())
149 "List of file-like objects, which will be added to @file{.zshenv}.
150Used for setting user's shell environment variables. Must not contain
151commands assuming the presence of tty or producing output. Will be
152read always. Will be read before any other file in @env{ZDOTDIR}.")
153 (zprofile
154 (text-config '())
155 "List of file-like objects, which will be added to @file{.zprofile}.
156Used for executing user's commands at start of login shell (In most
157cases the shell started on tty just after login). Will be read before
158@file{.zlogin}.")
159 (zshrc
160 (text-config '())
161 "List of file-like objects, which will be added to @file{.zshrc}.
162Used for executing user's commands at start of interactive shell (The
163shell for interactive usage started by typing @code{zsh} or by
164terminal app or any other program).")
165 (zlogin
166 (text-config '())
167 "List of file-like objects, which will be added to @file{.zlogin}.
168Used for executing user's commands at the end of starting process of
169login shell.")
170 (zlogout
171 (text-config '())
172 "List of file-like objects, which will be added to @file{.zlogout}.
173Used for executing user's commands at the exit of login shell. It
174won't be read in some cases (if the shell terminates by exec'ing
175another process for example)."))
176
177(define (zsh-filter-fields field)
178 (filter-configuration-fields home-zsh-configuration-fields (list field)))
179
180(define (zsh-serialize-field config field)
181 (serialize-configuration config (zsh-filter-fields field)))
182
183(define* (zsh-field-not-empty? config field)
184 (let ((file-name (symbol->string field))
185 (field-obj (car (zsh-filter-fields field))))
186 (not (null? ((configuration-field-getter field-obj) config)))))
187
188(define (zsh-file-zshenv config)
189 (mixed-text-file
190 "zshenv"
191 (zsh-serialize-field config 'zshenv)
192 (zsh-serialize-field config 'environment-variables)
193 "\
194if [ -n \"$SSH_CLIENT\" ]; then
195 if [[ -f $ZDOTDIR/.zprofile ]]; then
196 source $ZDOTDIR/.zprofile
197 else
198 source /etc/profile
199 fi
200fi
201"))
202
203(define (zsh-file-zprofile config)
204 (mixed-text-file
205 "zprofile"
206 (plain-file-content %default-zprofile)
207 "\
208# It's only necessary if zsh is a login shell, otherwise profiles will
209# be already sourced by bash
210"
211 (zsh-serialize-field config 'zprofile)))
212
213(define (zsh-file-by-field config field)
214 (match field
215 ('zshenv (zsh-file-zshenv config))
216 ('zprofile (zsh-file-zprofile config))
217 (e (mixed-text-file
218 (symbol->string field)
219 (zsh-serialize-field config field)))))
220
221(define (zsh-get-configuration-files config)
222 `((".zprofile" ,(zsh-file-by-field config 'zprofile)) ;; Always non-empty
223 (".zshenv" ,(zsh-file-by-field config 'zshenv)) ;; Always non-empty
224 ,@(if (zsh-field-not-empty? config 'zshrc)
225 `((".zshrc" ,(zsh-file-by-field config 'zshrc))) '())
226 ,@(if (zsh-field-not-empty? config 'zlogin)
227 `((".zlogin" ,(zsh-file-by-field config 'zlogin))) '())
228 ,@(if (zsh-field-not-empty? config 'zlogout)
229 `((".zlogout" ,(zsh-file-by-field config 'zlogout))) '())))
230
231(define (add-zsh-dot-configuration config)
232 (define zshenv-auxiliary-file
233 (mixed-text-file
234 "zshenv-auxiliary"
235 "export ZDOTDIR=${XDG_CONFIG_HOME:-$HOME/.config}/zsh\n"
236 "[[ -f $ZDOTDIR/.zshenv ]] && source $ZDOTDIR/.zshenv\n"))
237
238 (if (home-zsh-configuration-xdg-flavor? config)
239 `((".zshenv" ,zshenv-auxiliary-file))
240 (zsh-get-configuration-files config)))
241
242(define (add-zsh-xdg-configuration config)
243 (if (home-zsh-configuration-xdg-flavor? config)
244 (map
245 (lambda (lst)
246 (cons (string-append "zsh/" (car lst))
247 (cdr lst)))
248 (zsh-get-configuration-files config))
249 '()))
250
251(define (add-zsh-packages config)
252 (list (home-zsh-configuration-package config)))
253
254(define-configuration/no-serialization home-zsh-extension
255 (environment-variables
256 (alist '())
257 "Association list of environment variables to set.")
258 (zshrc
259 (text-config '())
260 "List of file-like objects.")
261 (zshenv
262 (text-config '())
263 "List of file-like objects.")
264 (zprofile
265 (text-config '())
266 "List of file-like objects.")
267 (zlogin
268 (text-config '())
269 "List of file-like objects.")
270 (zlogout
271 (text-config '())
272 "List of file-like objects."))
273
274(define (home-zsh-extensions original-config extension-configs)
275 (home-zsh-configuration
276 (inherit original-config)
277 (environment-variables
278 (append (home-zsh-configuration-environment-variables original-config)
279 (append-map
280 home-zsh-extension-environment-variables extension-configs)))
281 (zshrc
282 (append (home-zsh-configuration-zshrc original-config)
283 (append-map
284 home-zsh-extension-zshrc extension-configs)))
285 (zshenv
286 (append (home-zsh-configuration-zshenv original-config)
287 (append-map
288 home-zsh-extension-zshenv extension-configs)))
289 (zprofile
290 (append (home-zsh-configuration-zprofile original-config)
291 (append-map
292 home-zsh-extension-zprofile extension-configs)))
293 (zlogin
294 (append (home-zsh-configuration-zlogin original-config)
295 (append-map
296 home-zsh-extension-zlogin extension-configs)))
297 (zlogout
298 (append (home-zsh-configuration-zlogout original-config)
299 (append-map
300 home-zsh-extension-zlogout extension-configs)))))
301
302(define home-zsh-service-type
303 (service-type (name 'home-zsh)
304 (extensions
305 (list (service-extension
306 home-files-service-type
307 add-zsh-dot-configuration)
308 (service-extension
309 home-xdg-configuration-files-service-type
310 add-zsh-xdg-configuration)
311 (service-extension
312 home-profile-service-type
313 add-zsh-packages)))
314 (compose identity)
315 (extend home-zsh-extensions)
316 (default-value (home-zsh-configuration))
317 (description "Install and configure Zsh.")))
318
319
320;;;
321;;; Bash.
322;;;
323
324(define (bash-serialize-aliases field-name val)
325 (with-shell-quotation-bindings
326 #~(string-append
327 #$@(map
328 (match-lambda
329 ((key . #f)
330 "")
331 ((key . #t)
332 #~(string-append "alias " #$key "\n"))
333 ((key . (? literal-string? value))
334 #~(string-append "alias " #$key "="
335 (shell-single-quote
336 #$(literal-string-value value))
337 "\n"))
338 ((key . value)
339 #~(string-append "alias " #$key "="
340 (shell-double-quote #$value)
341 "\n")))
342 val))))
343
344(define-configuration home-bash-configuration
345 (package
346 (package bash)
347 "The Bash package to use.")
348 (guix-defaults?
349 ;; TODO: Set to #f when the target system is determined to be Guix System.
350 (boolean #t)
351 "Add sane defaults like setting @env{PS1}, @env{SHELL}, and ensuring
352@file{/etc/profile} is sourced for non-interactive SSH shells. If you use
353Guix System, is it safe to set this to @code{#f}, as in this case this is
354already taken care of by the globally installed @file{/etc/bashrc}.")
355 (environment-variables
356 (alist '())
357 "Association list of environment variables to set for the Bash session. The
358rules for the @code{home-environment-variables-service-type} apply
359here (@pxref{Essential Home Services}). The contents of this field will be
360added after the contents of the @code{bash-profile} field."
361 (serializer serialize-posix-env-vars))
362 (variables
363 (alist '())
364 "Bash variables (not to be confused with environment variables) to be set
365in @file{.bashrc} for use by interactive shells. A typical example of such
366variables is @code{HISTSIZE} and related history variables (@pxref{Bash
367Variables,,, bash, Bash Reference Manual})."
368 (serializer serialize-shell-variables))
369 (aliases
370 (alist %default-bash-aliases)
371 "Association list of aliases to set for the Bash session. The aliases will be
372defined after the contents of the @code{bashrc} field has been put in the
373@file{.bashrc} file. The alias will automatically be quoted, so something line
374this:
375
376@lisp
377'((\"ls\" . \"ls -alF\"))
378@end lisp
379
380turns into
381
382@example
383alias ls=\"ls -alF\"
384@end example"
385 (serializer bash-serialize-aliases))
386 (bash-profile
387 (text-config '())
388 "List of file-like objects, which will be added to @file{.bash_profile}.
389Used for executing user's commands at start of login shell (In most
390cases the shell started on tty just after login). @file{.bash_login}
391won't be ever read, because @file{.bash_profile} always present.")
392 (bashrc
393 (text-config '())
394 "List of file-like objects, which will be added to @file{.bashrc}.
395Used for executing user's commands at start of interactive shell (The
396shell for interactive usage started by typing @code{bash} or by
397terminal app or any other program).")
398 (bash-logout
399 (text-config '())
400 "List of file-like objects, which will be added to @file{.bash_logout}.
401Used for executing user's commands at the exit of login shell. It
402won't be read in some cases (if the shell terminates by exec'ing
403another process for example)."))
404
405(define (add-bash-configuration config)
406 (define (filter-fields field)
407 (filter-configuration-fields home-bash-configuration-fields
408 (list field)))
409
410 (define (serialize-field field)
411 (serialize-configuration
412 config
413 (filter-fields field)))
414
415 (define* (file-if-not-empty field #:optional (extra-content #f))
416 (let ((file-name (symbol->string field))
417 (field-obj (car (filter-fields field))))
418 (if (or extra-content
419 (not (null? ((configuration-field-getter field-obj) config))))
420 `(,(string-append "." (object->snake-case-string file-name))
421 ,(apply mixed-text-file
422 (object->snake-case-string file-name)
423 (append (or extra-content '())
424 (list (serialize-field field)))))
425 '())))
426
427 (filter
428 (negate null?)
429 `((".bash_profile"
430 ,(mixed-text-file
431 "bash_profile"
432 "\
433# Set up the system, user profile, and related variables.
434# /etc/profile will be sourced by bash automatically
435# Set up the home environment profile.
436if [ -f ~/.profile ]; then source ~/.profile; fi
437
438# Honor per-interactive-shell startup file
439if [ -f ~/.bashrc ]; then
440 # Taking care not to source it in the case of a non-interactive SSH
441 # shell, to avoid recursion.
442 [[ $- != *i* && -n $SSH_CLIENT ]] || . ~/.bashrc
443fi
444"
445
446 (serialize-field 'bash-profile)
447 (serialize-field 'environment-variables)))
448
449 ,@(list (file-if-not-empty
450 'bashrc
451 (let ((user-settings (list (serialize-field 'variables) "\n"
452 (serialize-field 'aliases))))
453 (if (home-bash-configuration-guix-defaults? config)
454 (cons* (plain-file-content %default-bashrc) "\n"
455 user-settings)
456 user-settings)))
457 (file-if-not-empty 'bash-logout)))))
458
459(define (add-bash-packages config)
460 (list (home-bash-configuration-package config)))
461
462(define-configuration/no-serialization home-bash-extension
463 (environment-variables
464 (alist '())
465 "Additional environment variables to set. These will be combined with the
466environment variables from other extensions and the base service to form one
467coherent block of environment variables.")
468 (variables
469 (alist '())
470 "Extra Bash variables (not to be confused with environment variables) to be
471set in @file{.bashrc} for use by interactive shells.")
472 (aliases
473 (alist '())
474 "Additional aliases to set. These will be combined with the aliases from
475other extensions and the base service.")
476 (bash-profile
477 (text-config '())
478 "Additional text blocks to add to @file{.bash_profile}, which will be combined
479with text blocks from other extensions and the base service.")
480 (bashrc
481 (text-config '())
482 "Additional text blocks to add to @file{.bashrc}, which will be combined
483with text blocks from other extensions and the base service.")
484 (bash-logout
485 (text-config '())
486 "Additional text blocks to add to @file{.bash_logout}, which will be combined
487with text blocks from other extensions and the base service."))
488
489(define (home-bash-extensions original-config extension-configs)
490 (match-record original-config <home-bash-configuration>
491 (environment-variables variables aliases bash-profile bashrc bash-logout)
492 (home-bash-configuration
493 (inherit original-config)
494 (environment-variables
495 (append environment-variables
496 (append-map
497 home-bash-extension-environment-variables extension-configs)))
498 (variables
499 (append variables
500 (append-map
501 home-bash-extension-variables extension-configs)))
502 (aliases
503 (append aliases
504 (append-map
505 home-bash-extension-aliases extension-configs)))
506 (bash-profile
507 (append bash-profile
508 (append-map
509 home-bash-extension-bash-profile extension-configs)))
510 (bashrc
511 (append bashrc
512 (append-map
513 home-bash-extension-bashrc extension-configs)))
514 (bash-logout
515 (append bash-logout
516 (append-map
517 home-bash-extension-bash-logout extension-configs))))))
518
519(define home-bash-service-type
520 (service-type (name 'home-bash)
521 (extensions
522 (list (service-extension
523 home-files-service-type
524 add-bash-configuration)
525 (service-extension
526 home-profile-service-type
527 add-bash-packages)))
528 (compose identity)
529 (extend home-bash-extensions)
530 (default-value (home-bash-configuration))
531 (description "Install and configure GNU Bash.")))
532
533
534;;;
535;;; Fish.
536;;;
537
538(define (serialize-fish-aliases field-name val)
539 #~(string-append
540 #$@(map (match-lambda
541 ((key . value)
542 #~(string-append "alias " #$key " \"" #$value "\"\n"))
543 (_ ""))
544 val)))
545
546(define (serialize-fish-abbreviations field-name val)
547 #~(string-append
548 #$@(map (match-lambda
549 ((key . value)
550 #~(string-append "abbr --add " #$key " " #$value "\n"))
551 (_ ""))
552 val)))
553
554(define (serialize-fish-env-vars field-name val)
555 #~(string-append
556 #$@(map (match-lambda
557 ((key . #f)
558 "")
559 ((key . #t)
560 #~(string-append "set -x " #$key "\n"))
561 ((key . value)
562 #~(string-append "set -x " #$key " " #$value "\n")))
563 val)))
564
565(define-configuration home-fish-configuration
566 (package
567 (package fish)
568 "The Fish package to use.")
569 (config
570 (text-config '())
571 "List of file-like objects, which will be added to
572@file{$XDG_CONFIG_HOME/fish/config.fish}.")
573 (environment-variables
574 (alist '())
575 "Association list of environment variables to set in Fish."
576 (serializer serialize-fish-env-vars))
577 (aliases
578 (alist '())
579 "Association list of aliases for Fish, both the key and the value
580should be a string. An alias is just a simple function that wraps a
581command, If you want something more akin to @dfn{aliases} in POSIX
582shells, see the @code{abbreviations} field."
583 (serializer serialize-fish-aliases))
584 (abbreviations
585 (alist '())
586 "Association list of abbreviations for Fish. These are words that,
587when typed in the shell, will automatically expand to the full text."
588 (serializer serialize-fish-abbreviations)))
589
590(define (fish-files-service config)
591 `(("fish/config.fish"
592 ,(mixed-text-file
593 "fish-config.fish"
594 #~(string-append "\
595# if we haven't sourced the login config, do it
596status --is-login; and not set -q __fish_login_config_sourced
597and begin
598
599 set --prepend fish_function_path "
600 #$fish-foreign-env
601 "/share/fish/functions
602 fenv source $HOME/.profile
603 set -e fish_function_path[1]
604
605 set -g __fish_login_config_sourced 1
606
607end\n\n")
608 (serialize-configuration
609 config
610 home-fish-configuration-fields)))))
611
612(define (fish-profile-service config)
613 (list (home-fish-configuration-package config)))
614
615(define-configuration/no-serialization home-fish-extension
616 (config
617 (text-config '())
618 "List of file-like objects for extending the Fish initialization file.")
619 (environment-variables
620 (alist '())
621 "Association list of environment variables to set.")
622 (aliases
623 (alist '())
624 "Association list of Fish aliases.")
625 (abbreviations
626 (alist '())
627 "Association list of Fish abbreviations."))
628
629(define (home-fish-extensions original-config extension-configs)
630 (home-fish-configuration
631 (inherit original-config)
632 (config
633 (append (home-fish-configuration-config original-config)
634 (append-map
635 home-fish-extension-config extension-configs)))
636 (environment-variables
637 (append (home-fish-configuration-environment-variables original-config)
638 (append-map
639 home-fish-extension-environment-variables extension-configs)))
640 (aliases
641 (append (home-fish-configuration-aliases original-config)
642 (append-map
643 home-fish-extension-aliases extension-configs)))
644 (abbreviations
645 (append (home-fish-configuration-abbreviations original-config)
646 (append-map
647 home-fish-extension-abbreviations extension-configs)))))
648
649;; TODO: Support for generating completion files
650;; TODO: Support for installing plugins
651(define home-fish-service-type
652 (service-type (name 'home-fish)
653 (extensions
654 (list (service-extension
655 home-xdg-configuration-files-service-type
656 fish-files-service)
657 (service-extension
658 home-profile-service-type
659 fish-profile-service)))
660 (compose identity)
661 (extend home-fish-extensions)
662 (default-value (home-fish-configuration))
663 (description "\
664Install and configure Fish, the friendly interactive shell.")))
665
666
667;;;
668;;; Readline.
669;;;
670
671(define (serialize-inputrc-key-bindings field-name val)
672 #~(string-append
673 #$@(map
674 (match-lambda
675 ((key . value)
676 #~(string-append #$key ": " #$value "\n")))
677 val)))
678
679(define (serialize-inputrc-variables field-name val)
680 #~(string-append
681 #$@(map
682 (match-lambda
683 ((key . #f)
684 #~(string-append "set " #$key " off\n"))
685 ((key . #t)
686 #~(string-append "set " #$key " on\n"))
687 ((key . value)
688 #~(string-append "set " #$key " " #$value "\n")))
689 val)))
690
691(define (serialize-inputrc-conditional-constructs field-name val)
692 #~(string-append
693 #$@(map
694 (match-lambda
695 (("$endif" . _)
696 "$endif\n")
697 (("$include" . value)
698 #~(string-append "$include " #$value "\n"))
699 ;; TODO: key can only be "$if" or "$else".
700 ((key . value)
701 #~(string-append #$key "\n"
702 #$(serialize-configuration
703 value
704 home-inputrc-configuration-fields))))
705 val)))
706
707(define (serialize-inputrc-extra-content field-name value)
708 #~(if (string=? #$value "") "" (string-append #$value "\n")))
709
710(define-configuration home-inputrc-configuration
711 (key-bindings
712 (alist '())
713 "Association list of readline key bindings to be added to the
714@code{~/.inputrc} file. This is where code like this:
715
716@lisp
717'((\"Control-l\" . \"clear-screen\"))
718@end lisp
719
720turns into
721
722@example
723Control-l: clear-screen
724@end example"
725 (serializer serialize-inputrc-key-bindings))
726 (variables
727 (alist '())
728 "Association list of readline variables to set. This is where configuration
729options like this:
730
731@lisp
732'((\"bell-style\" . \"visible\")
733 (\"colored-completion-prefix\" . #t))
734@end lisp
735
736turns into
737
738@example
739set bell-style visible
740set colored-completion-prefix on
741@end example"
742 (serializer serialize-inputrc-variables))
743 (conditional-constructs
744 (alist '())
745 "Association list of conditionals to add to the initialization file. This
746includes @command{$if}, @command{else}, @command{endif} and @command{include}
747and they receive a value of another @command{home-inputrc-configuration}.
748
749@lisp
750(conditional-constructs
751 `((\"$if mode=vi\" .
752 ,(home-inputrc-configuration
753 (variables
754 `((\"show-mode-in-prompt\" . #t)))))
755 (\"$else\" .
756 ,(home-inputrc-configuration
757 (key-bindings
758 `((\"Control-l\" . \"clear-screen\")))))
759 (\"$endif\" . #t)))
760@end lisp
761
762turns into
763
764@example
765$if mode=vi
766set show-mode-in-prompt on
767$else
768Control-l: clear-screen
769$endif
770@end example"
771 (serializer serialize-inputrc-conditional-constructs))
772 (extra-content
773 (string "")
774 "Extra content appended as-is to the configuration file. Run @command{man
775readline} for more information about all the configuration options."
776 (serializer serialize-inputrc-extra-content)))
777
778(define (home-inputrc-files config)
779 (list
780 `(".inputrc"
781 ,(mixed-text-file "inputrc"
782 (serialize-configuration
783 config
784 home-inputrc-configuration-fields)))))
785
786(define home-inputrc-service-type
787 (service-type (name 'inputrc)
788 (extensions
789 (list (service-extension home-files-service-type
790 home-inputrc-files)))
791 (default-value (home-inputrc-configuration))
792 (description "Configure readline in @code{.inputrc}.")))
793
794
795(define (generate-home-shell-profile-documentation)
796 (generate-documentation
797 `((home-shell-profile-configuration
798 ,home-shell-profile-configuration-fields))
799 'home-shell-profile-configuration))
800
801(define (generate-home-bash-documentation)
802 (string-append
803 (generate-documentation
804 `((home-bash-configuration
805 ,home-bash-configuration-fields))
806 'home-bash-configuration)
807 "\n\n"
808 (generate-documentation
809 `((home-bash-extension
810 ,home-bash-extension-fields))
811 'home-bash-extension)))
812
813(define (generate-home-zsh-documentation)
814 (generate-documentation
815 `((home-zsh-configuration
816 ,home-zsh-configuration-fields))
817 'home-zsh-configuration))
818
819(define (generate-home-fish-documentation)
820 (string-append
821 (generate-documentation
822 `((home-fish-configuration
823 ,home-fish-configuration-fields))
824 'home-fish-configuration)
825 "\n\n"
826 (generate-documentation
827 `((home-fish-extension
828 ,home-fish-extension-fields))
829 'home-fish-extension)))