Commit | Line | Data |
---|---|---|
9a2e9a61 AT |
1 | ;;; GNU Guix --- Functional package management for GNU |
2 | ;;; Copyright © 2021 Andrew Tropin <andrew@trop.in> | |
3 | ;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz> | |
4 | ;;; | |
5 | ;;; This file is part of GNU Guix. | |
6 | ;;; | |
7 | ;;; GNU Guix is free software; you can redistribute it and/or modify it | |
8 | ;;; under the terms of the GNU General Public License as published by | |
9 | ;;; the Free Software Foundation; either version 3 of the License, or (at | |
10 | ;;; your option) any later version. | |
11 | ;;; | |
12 | ;;; GNU Guix is distributed in the hope that it will be useful, but | |
13 | ;;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | ;;; GNU General Public License for more details. | |
16 | ;;; | |
17 | ;;; You should have received a copy of the GNU General Public License | |
18 | ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. | |
19 | ||
ba8ddb34 | 20 | (define-module (gnu home services shells) |
9a2e9a61 | 21 | #:use-module (gnu services configuration) |
ba8ddb34 | 22 | #:use-module (gnu home services utils) |
0e8d2df0 | 23 | #:use-module (gnu home services) |
9a2e9a61 AT |
24 | #:use-module (gnu packages shells) |
25 | #:use-module (gnu packages bash) | |
26 | #:use-module (guix gexp) | |
27 | #:use-module (guix packages) | |
28 | #:use-module (srfi srfi-1) | |
29 | #:use-module (srfi srfi-26) | |
30 | #:use-module (ice-9 match) | |
31 | ||
32 | #:export (home-shell-profile-service-type | |
33 | home-shell-profile-configuration | |
34 | ||
35 | home-bash-service-type | |
36 | home-bash-configuration | |
37 | home-bash-extension | |
38 | ||
39 | home-zsh-service-type | |
40 | home-zsh-configuration | |
41 | home-zsh-extension | |
42 | ||
43 | home-fish-service-type | |
44 | home-fish-configuration | |
45 | home-fish-extension)) | |
46 | ||
47 | ;;; Commentary: | |
48 | ;;; | |
49 | ;;; This module contains shell related services like Zsh. | |
50 | ;;; | |
51 | ;;; Code: | |
52 | ||
53 | \f | |
54 | ;;; | |
55 | ;;; Shell profile. | |
56 | ;;; | |
57 | ||
58 | (define path? string?) | |
59 | (define (serialize-path field-name val) val) | |
60 | ||
61 | (define-configuration home-shell-profile-configuration | |
62 | (profile | |
63 | (text-config '()) | |
64 | "\ | |
65 | @code{home-shell-profile} is instantiated automatically by | |
66 | @code{home-environment}, DO NOT create this service manually, it can | |
67 | only be extended. | |
68 | ||
ff20d392 | 69 | @code{profile} is a list of file-like objects, which will go to |
9a2e9a61 AT |
70 | @file{~/.profile}. By default @file{~/.profile} contains the |
71 | initialization code, which have to be evaluated by login shell to make | |
6edfcf3e | 72 | home-environment's profile available to the user, but other commands |
9a2e9a61 AT |
73 | can be added to the file if it is really necessary. |
74 | ||
75 | In most cases shell's configuration files are preferred places for | |
76 | user's customizations. Extend home-shell-profile service only if you | |
77 | really know what you do.")) | |
78 | ||
79 | (define (add-shell-profile-file config) | |
5832d9fb | 80 | `((".profile" |
9a2e9a61 AT |
81 | ,(mixed-text-file |
82 | "shell-profile" | |
83 | "\ | |
84 | HOME_ENVIRONMENT=$HOME/.guix-home | |
85 | . $HOME_ENVIRONMENT/setup-environment | |
86 | $HOME_ENVIRONMENT/on-first-login\n" | |
87 | (serialize-configuration | |
88 | config | |
89 | (filter-configuration-fields | |
90 | home-shell-profile-configuration-fields '(profile))))))) | |
91 | ||
92 | (define (add-profile-extensions config extensions) | |
93 | (home-shell-profile-configuration | |
94 | (inherit config) | |
95 | (profile | |
96 | (append (home-shell-profile-configuration-profile config) | |
97 | extensions)))) | |
98 | ||
99 | (define home-shell-profile-service-type | |
100 | (service-type (name 'home-shell-profile) | |
101 | (extensions | |
102 | (list (service-extension | |
103 | home-files-service-type | |
104 | add-shell-profile-file))) | |
105 | (compose concatenate) | |
106 | (extend add-profile-extensions) | |
107 | (default-value (home-shell-profile-configuration)) | |
108 | (description "Create @file{~/.profile}, which is used | |
109 | for environment initialization of POSIX compliant login shells. This | |
ff20d392 | 110 | service type can be extended with a list of file-like objects."))) |
9a2e9a61 AT |
111 | |
112 | (define (serialize-boolean field-name val) "") | |
113 | (define (serialize-posix-env-vars field-name val) | |
af4c1035 | 114 | (environment-variable-shell-definitions val)) |
9a2e9a61 AT |
115 | |
116 | \f | |
117 | ;;; | |
118 | ;;; Zsh. | |
119 | ;;; | |
120 | ||
121 | (define-configuration home-zsh-configuration | |
122 | (package | |
123 | (package zsh) | |
124 | "The Zsh package to use.") | |
125 | (xdg-flavor? | |
126 | (boolean #t) | |
127 | "Place all the configs to @file{$XDG_CONFIG_HOME/zsh}. Makes | |
128 | @file{~/.zshenv} to set @env{ZDOTDIR} to @file{$XDG_CONFIG_HOME/zsh}. | |
129 | Shell startup process will continue with | |
130 | @file{$XDG_CONFIG_HOME/zsh/.zshenv}.") | |
131 | (environment-variables | |
132 | (alist '()) | |
133 | "Association list of environment variables to set for the Zsh session." | |
134 | serialize-posix-env-vars) | |
135 | (zshenv | |
136 | (text-config '()) | |
ff20d392 | 137 | "List of file-like objects, which will be added to @file{.zshenv}. |
9a2e9a61 AT |
138 | Used for setting user's shell environment variables. Must not contain |
139 | commands assuming the presence of tty or producing output. Will be | |
140 | read always. Will be read before any other file in @env{ZDOTDIR}.") | |
141 | (zprofile | |
142 | (text-config '()) | |
ff20d392 | 143 | "List of file-like objects, which will be added to @file{.zprofile}. |
9a2e9a61 AT |
144 | Used for executing user's commands at start of login shell (In most |
145 | cases the shell started on tty just after login). Will be read before | |
146 | @file{.zlogin}.") | |
147 | (zshrc | |
148 | (text-config '()) | |
ff20d392 | 149 | "List of file-like objects, which will be added to @file{.zshrc}. |
9a2e9a61 AT |
150 | Used for executing user's commands at start of interactive shell (The |
151 | shell for interactive usage started by typing @code{zsh} or by | |
152 | terminal app or any other program).") | |
153 | (zlogin | |
154 | (text-config '()) | |
ff20d392 | 155 | "List of file-like objects, which will be added to @file{.zlogin}. |
9a2e9a61 AT |
156 | Used for executing user's commands at the end of starting process of |
157 | login shell.") | |
158 | (zlogout | |
159 | (text-config '()) | |
ff20d392 | 160 | "List of file-like objects, which will be added to @file{.zlogout}. |
9a2e9a61 AT |
161 | Used for executing user's commands at the exit of login shell. It |
162 | won't be read in some cases (if the shell terminates by exec'ing | |
163 | another process for example).")) | |
164 | ||
4935501f AT |
165 | (define (zsh-filter-fields field) |
166 | (filter-configuration-fields home-zsh-configuration-fields (list field))) | |
167 | ||
168 | (define (zsh-serialize-field config field) | |
169 | (serialize-configuration config (zsh-filter-fields field))) | |
170 | ||
171 | (define* (zsh-field-not-empty? config field) | |
172 | (let ((file-name (symbol->string field)) | |
173 | (field-obj (car (zsh-filter-fields field)))) | |
174 | (not (null? ((configuration-field-getter field-obj) config))))) | |
175 | ||
176 | (define (zsh-file-zshenv config) | |
177 | (mixed-text-file | |
178 | "zshenv" | |
179 | (zsh-serialize-field config 'zshenv) | |
180 | (zsh-serialize-field config 'environment-variables))) | |
181 | ||
182 | (define (zsh-file-zprofile config) | |
183 | (mixed-text-file | |
184 | "zprofile" | |
185 | "\ | |
9e4cbb30 | 186 | # Set up the system, user profile, and related variables. |
9a2e9a61 | 187 | source /etc/profile |
9e4cbb30 | 188 | # Set up the home environment profile. |
9a2e9a61 AT |
189 | source ~/.profile |
190 | ||
191 | # It's only necessary if zsh is a login shell, otherwise profiles will | |
192 | # be already sourced by bash | |
193 | " | |
4935501f AT |
194 | (zsh-serialize-field config 'zprofile))) |
195 | ||
196 | (define (zsh-file-by-field config field) | |
197 | (match field | |
198 | ('zshenv (zsh-file-zshenv config)) | |
199 | ('zprofile (zsh-file-zprofile config)) | |
200 | (e (mixed-text-file | |
201 | (symbol->string field) | |
202 | (zsh-serialize-field config field))))) | |
203 | ||
204 | (define (zsh-get-configuration-files config) | |
5832d9fb | 205 | `((".zprofile" ,(zsh-file-by-field config 'zprofile)) ;; Always non-empty |
032f2e26 BK |
206 | ,@(if (or (zsh-field-not-empty? config 'zshenv) |
207 | (zsh-field-not-empty? config 'environment-variables)) | |
5832d9fb | 208 | `((".zshenv" ,(zsh-file-by-field config 'zshenv))) '()) |
4935501f | 209 | ,@(if (zsh-field-not-empty? config 'zshrc) |
5832d9fb | 210 | `((".zshrc" ,(zsh-file-by-field config 'zshrc))) '()) |
4935501f | 211 | ,@(if (zsh-field-not-empty? config 'zlogin) |
5832d9fb | 212 | `((".zlogin" ,(zsh-file-by-field config 'zlogin))) '()) |
4935501f | 213 | ,@(if (zsh-field-not-empty? config 'zlogout) |
5832d9fb | 214 | `((".zlogout" ,(zsh-file-by-field config 'zlogout))) '()))) |
4935501f | 215 | |
ac8e987c | 216 | (define (add-zsh-dot-configuration config) |
4935501f AT |
217 | (define zshenv-auxiliary-file |
218 | (mixed-text-file | |
219 | "zshenv-auxiliary" | |
220 | "export ZDOTDIR=${XDG_CONFIG_HOME:-$HOME/.config}/zsh\n" | |
221 | "[[ -f $ZDOTDIR/.zshenv ]] && source $ZDOTDIR/.zshenv\n")) | |
222 | ||
223 | (if (home-zsh-configuration-xdg-flavor? config) | |
5832d9fb | 224 | `((".zshenv" ,zshenv-auxiliary-file)) |
4935501f AT |
225 | (zsh-get-configuration-files config))) |
226 | ||
ac8e987c | 227 | (define (add-zsh-xdg-configuration config) |
4935501f AT |
228 | (if (home-zsh-configuration-xdg-flavor? config) |
229 | (map | |
230 | (lambda (lst) | |
5832d9fb | 231 | (cons (string-append "zsh/" (car lst)) |
4935501f AT |
232 | (cdr lst))) |
233 | (zsh-get-configuration-files config)) | |
234 | '())) | |
9a2e9a61 AT |
235 | |
236 | (define (add-zsh-packages config) | |
237 | (list (home-zsh-configuration-package config))) | |
238 | ||
239 | (define-configuration/no-serialization home-zsh-extension | |
240 | (environment-variables | |
241 | (alist '()) | |
242 | "Association list of environment variables to set.") | |
243 | (zshrc | |
244 | (text-config '()) | |
ff20d392 | 245 | "List of file-like objects.") |
9a2e9a61 AT |
246 | (zshenv |
247 | (text-config '()) | |
ff20d392 | 248 | "List of file-like objects.") |
9a2e9a61 AT |
249 | (zprofile |
250 | (text-config '()) | |
ff20d392 | 251 | "List of file-like objects.") |
9a2e9a61 AT |
252 | (zlogin |
253 | (text-config '()) | |
ff20d392 | 254 | "List of file-like objects.") |
9a2e9a61 AT |
255 | (zlogout |
256 | (text-config '()) | |
ff20d392 | 257 | "List of file-like objects.")) |
9a2e9a61 AT |
258 | |
259 | (define (home-zsh-extensions original-config extension-configs) | |
260 | (home-zsh-configuration | |
261 | (inherit original-config) | |
262 | (environment-variables | |
263 | (append (home-zsh-configuration-environment-variables original-config) | |
264 | (append-map | |
265 | home-zsh-extension-environment-variables extension-configs))) | |
266 | (zshrc | |
267 | (append (home-zsh-configuration-zshrc original-config) | |
268 | (append-map | |
269 | home-zsh-extension-zshrc extension-configs))) | |
270 | (zshenv | |
271 | (append (home-zsh-configuration-zshenv original-config) | |
272 | (append-map | |
273 | home-zsh-extension-zshenv extension-configs))) | |
274 | (zprofile | |
275 | (append (home-zsh-configuration-zprofile original-config) | |
276 | (append-map | |
277 | home-zsh-extension-zprofile extension-configs))) | |
278 | (zlogin | |
279 | (append (home-zsh-configuration-zlogin original-config) | |
280 | (append-map | |
281 | home-zsh-extension-zlogin extension-configs))) | |
282 | (zlogout | |
283 | (append (home-zsh-configuration-zlogout original-config) | |
284 | (append-map | |
285 | home-zsh-extension-zlogout extension-configs))))) | |
286 | ||
287 | (define home-zsh-service-type | |
288 | (service-type (name 'home-zsh) | |
289 | (extensions | |
290 | (list (service-extension | |
291 | home-files-service-type | |
ac8e987c | 292 | add-zsh-dot-configuration) |
4935501f AT |
293 | (service-extension |
294 | home-xdg-configuration-files-service-type | |
ac8e987c | 295 | add-zsh-xdg-configuration) |
9a2e9a61 AT |
296 | (service-extension |
297 | home-profile-service-type | |
298 | add-zsh-packages))) | |
299 | (compose identity) | |
300 | (extend home-zsh-extensions) | |
301 | (default-value (home-zsh-configuration)) | |
302 | (description "Install and configure Zsh."))) | |
303 | ||
304 | \f | |
305 | ;;; | |
306 | ;;; Bash. | |
307 | ;;; | |
308 | ||
4b969982 XC |
309 | (define (bash-serialize-aliases field-name val) |
310 | #~(string-append | |
311 | #$@(map | |
312 | (match-lambda | |
313 | ((key . #f) | |
314 | "") | |
315 | ((key . #t) | |
316 | #~(string-append "alias " #$key "\n")) | |
317 | ((key . value) | |
318 | #~(string-append "alias " #$key "=\"" #$value "\"\n"))) | |
319 | val))) | |
320 | ||
9a2e9a61 AT |
321 | (define-configuration home-bash-configuration |
322 | (package | |
323 | (package bash) | |
324 | "The Bash package to use.") | |
325 | (guix-defaults? | |
326 | (boolean #t) | |
2f665d43 | 327 | "Add sane defaults like reading @file{/etc/bashrc} and coloring the output of |
3a91c925 | 328 | @command{ls} to the top of the @file{.bashrc} file.") |
9a2e9a61 AT |
329 | (environment-variables |
330 | (alist '()) | |
2f665d43 XC |
331 | "Association list of environment variables to set for the Bash session. The |
332 | rules for the @code{home-environment-variables-service-type} apply | |
333 | here (@pxref{Essential Home Services}). The contents of this field will be | |
334 | added after the contents of the @code{bash-profile} field." | |
9a2e9a61 | 335 | serialize-posix-env-vars) |
4b969982 XC |
336 | (aliases |
337 | (alist '()) | |
2f665d43 XC |
338 | "Association list of aliases to set for the Bash session. The aliases will be |
339 | defined after the contents of the @code{bashrc} field has been put in the | |
340 | @file{.bashrc} file. The alias will automatically be quoted, so something line | |
341 | this: | |
4b969982 XC |
342 | |
343 | @lisp | |
344 | '((\"ls\" . \"ls -alF\")) | |
345 | @end lisp | |
346 | ||
347 | turns into | |
348 | ||
349 | @example | |
350 | alias ls=\"ls -alF\" | |
351 | @end example" | |
352 | bash-serialize-aliases) | |
9a2e9a61 AT |
353 | (bash-profile |
354 | (text-config '()) | |
ff20d392 | 355 | "List of file-like objects, which will be added to @file{.bash_profile}. |
9a2e9a61 AT |
356 | Used for executing user's commands at start of login shell (In most |
357 | cases the shell started on tty just after login). @file{.bash_login} | |
358 | won't be ever read, because @file{.bash_profile} always present.") | |
359 | (bashrc | |
360 | (text-config '()) | |
ff20d392 | 361 | "List of file-like objects, which will be added to @file{.bashrc}. |
9a2e9a61 AT |
362 | Used for executing user's commands at start of interactive shell (The |
363 | shell for interactive usage started by typing @code{bash} or by | |
364 | terminal app or any other program).") | |
365 | (bash-logout | |
366 | (text-config '()) | |
ff20d392 | 367 | "List of file-like objects, which will be added to @file{.bash_logout}. |
9a2e9a61 AT |
368 | Used for executing user's commands at the exit of login shell. It |
369 | won't be read in some cases (if the shell terminates by exec'ing | |
370 | another process for example).")) | |
371 | ||
372 | ;; TODO: Use value from (gnu system shadow) | |
373 | (define guix-bashrc | |
374 | "\ | |
375 | # Bash initialization for interactive non-login shells and | |
376 | # for remote shells (info \"(bash) Bash Startup Files\"). | |
377 | ||
378 | # Export 'SHELL' to child processes. Programs such as 'screen' | |
379 | # honor it and otherwise use /bin/sh. | |
380 | export SHELL | |
381 | ||
382 | if [[ $- != *i* ]] | |
383 | then | |
384 | # We are being invoked from a non-interactive shell. If this | |
385 | # is an SSH session (as in \"ssh host command\"), source | |
386 | # /etc/profile so we get PATH and other essential variables. | |
387 | [[ -n \"$SSH_CLIENT\" ]] && source /etc/profile | |
388 | ||
389 | # Don't do anything else. | |
390 | return | |
391 | fi | |
392 | ||
393 | # Source the system-wide file. | |
a4cbd31c TGR |
394 | if [[ -e /etc/bashrc ]]; then |
395 | source /etc/bashrc | |
396 | fi | |
9a2e9a61 AT |
397 | |
398 | # Adjust the prompt depending on whether we're in 'guix environment'. | |
399 | if [ -n \"$GUIX_ENVIRONMENT\" ] | |
400 | then | |
401 | PS1='\\u@\\h \\w [env]\\$ ' | |
402 | else | |
403 | PS1='\\u@\\h \\w\\$ ' | |
404 | fi | |
405 | alias ls='ls -p --color=auto' | |
406 | alias ll='ls -l' | |
407 | alias grep='grep --color=auto'\n") | |
408 | ||
409 | (define (add-bash-configuration config) | |
410 | (define (filter-fields field) | |
411 | (filter-configuration-fields home-bash-configuration-fields | |
412 | (list field))) | |
413 | ||
414 | (define (serialize-field field) | |
415 | (serialize-configuration | |
416 | config | |
417 | (filter-fields field))) | |
418 | ||
419 | (define* (file-if-not-empty field #:optional (extra-content #f)) | |
420 | (let ((file-name (symbol->string field)) | |
421 | (field-obj (car (filter-fields field)))) | |
422 | (if (or extra-content | |
423 | (not (null? ((configuration-field-getter field-obj) config)))) | |
5832d9fb | 424 | `(,(string-append "." (object->snake-case-string file-name)) |
4b969982 | 425 | ,(apply mixed-text-file |
c322d978 LC |
426 | (object->snake-case-string file-name) |
427 | (append (or extra-content '()) | |
428 | (list (serialize-field field))))) | |
9a2e9a61 AT |
429 | '()))) |
430 | ||
431 | (filter | |
432 | (compose not null?) | |
5832d9fb | 433 | `((".bash_profile" |
9a2e9a61 AT |
434 | ,(mixed-text-file |
435 | "bash_profile" | |
436 | "\ | |
9e4cbb30 | 437 | # Set up the system, user profile, and related variables. |
9a2e9a61 | 438 | # /etc/profile will be sourced by bash automatically |
9e4cbb30 | 439 | # Set up the home environment profile. |
9a2e9a61 AT |
440 | if [ -f ~/.profile ]; then source ~/.profile; fi |
441 | ||
442 | # Honor per-interactive-shell startup file | |
443 | if [ -f ~/.bashrc ]; then source ~/.bashrc; fi | |
444 | " | |
445 | (serialize-field 'bash-profile) | |
446 | (serialize-field 'environment-variables))) | |
447 | ||
448 | ,@(list (file-if-not-empty | |
449 | 'bashrc | |
450 | (if (home-bash-configuration-guix-defaults? config) | |
4b969982 | 451 | (list (serialize-field 'aliases) guix-bashrc) |
3a91c925 | 452 | (list (serialize-field 'aliases)))) |
9a2e9a61 AT |
453 | (file-if-not-empty 'bash-logout))))) |
454 | ||
455 | (define (add-bash-packages config) | |
456 | (list (home-bash-configuration-package config))) | |
457 | ||
458 | (define-configuration/no-serialization home-bash-extension | |
459 | (environment-variables | |
460 | (alist '()) | |
2f665d43 XC |
461 | "Additional environment variables to set. These will be combined with the |
462 | environment variables from other extensions and the base service to form one | |
463 | coherent block of environment variables.") | |
4b969982 XC |
464 | (aliases |
465 | (alist '()) | |
2f665d43 XC |
466 | "Additional aliases to set. These will be combined with the aliases from |
467 | other extensions and the base service.") | |
9a2e9a61 AT |
468 | (bash-profile |
469 | (text-config '()) | |
2f665d43 XC |
470 | "Additional text blocks to add to @file{.bash_profile}, which will be combined |
471 | with text blocks from other extensions and the base service.") | |
9a2e9a61 AT |
472 | (bashrc |
473 | (text-config '()) | |
2f665d43 XC |
474 | "Additional text blocks to add to @file{.bashrc}, which will be combined |
475 | with text blocks from other extensions and the base service.") | |
9a2e9a61 AT |
476 | (bash-logout |
477 | (text-config '()) | |
2f665d43 XC |
478 | "Additional text blocks to add to @file{.bash_logout}, which will be combined |
479 | with text blocks from other extensions and the base service.")) | |
9a2e9a61 AT |
480 | |
481 | (define (home-bash-extensions original-config extension-configs) | |
4b969982 XC |
482 | (match original-config |
483 | (($ <home-bash-configuration> _ _ _ environment-variables aliases | |
484 | bash-profile bashrc bash-logout) | |
485 | (home-bash-configuration | |
486 | (inherit original-config) | |
487 | (environment-variables | |
488 | (append environment-variables | |
489 | (append-map | |
490 | home-bash-extension-environment-variables extension-configs))) | |
491 | (aliases | |
492 | (append aliases | |
493 | (append-map | |
494 | home-bash-extension-aliases extension-configs))) | |
495 | (bash-profile | |
496 | (append bash-profile | |
497 | (append-map | |
498 | home-bash-extension-bash-profile extension-configs))) | |
499 | (bashrc | |
500 | (append bashrc | |
501 | (append-map | |
502 | home-bash-extension-bashrc extension-configs))) | |
503 | (bash-logout | |
504 | (append bash-logout | |
505 | (append-map | |
506 | home-bash-extension-bash-logout extension-configs))))))) | |
9a2e9a61 AT |
507 | |
508 | (define home-bash-service-type | |
509 | (service-type (name 'home-bash) | |
510 | (extensions | |
511 | (list (service-extension | |
512 | home-files-service-type | |
513 | add-bash-configuration) | |
514 | (service-extension | |
515 | home-profile-service-type | |
516 | add-bash-packages))) | |
517 | (compose identity) | |
518 | (extend home-bash-extensions) | |
519 | (default-value (home-bash-configuration)) | |
520 | (description "Install and configure GNU Bash."))) | |
521 | ||
522 | \f | |
523 | ;;; | |
524 | ;;; Fish. | |
525 | ;;; | |
526 | ||
527 | (define (serialize-fish-aliases field-name val) | |
528 | #~(string-append | |
529 | #$@(map (match-lambda | |
530 | ((key . value) | |
531 | #~(string-append "alias " #$key " \"" #$value "\"\n")) | |
532 | (_ "")) | |
533 | val))) | |
534 | ||
535 | (define (serialize-fish-abbreviations field-name val) | |
536 | #~(string-append | |
537 | #$@(map (match-lambda | |
538 | ((key . value) | |
539 | #~(string-append "abbr --add " #$key " " #$value "\n")) | |
540 | (_ "")) | |
541 | val))) | |
542 | ||
543 | (define (serialize-fish-env-vars field-name val) | |
544 | #~(string-append | |
545 | #$@(map (match-lambda | |
546 | ((key . #f) | |
547 | "") | |
548 | ((key . #t) | |
75a520cc | 549 | #~(string-append "set -x " #$key "\n")) |
9a2e9a61 | 550 | ((key . value) |
75a520cc | 551 | #~(string-append "set -x " #$key " " #$value "\n"))) |
9a2e9a61 AT |
552 | val))) |
553 | ||
554 | (define-configuration home-fish-configuration | |
555 | (package | |
556 | (package fish) | |
557 | "The Fish package to use.") | |
558 | (config | |
559 | (text-config '()) | |
ff20d392 | 560 | "List of file-like objects, which will be added to |
9a2e9a61 AT |
561 | @file{$XDG_CONFIG_HOME/fish/config.fish}.") |
562 | (environment-variables | |
563 | (alist '()) | |
564 | "Association list of environment variables to set in Fish." | |
565 | serialize-fish-env-vars) | |
566 | (aliases | |
567 | (alist '()) | |
568 | "Association list of aliases for Fish, both the key and the value | |
569 | should be a string. An alias is just a simple function that wraps a | |
570 | command, If you want something more akin to @dfn{aliases} in POSIX | |
571 | shells, see the @code{abbreviations} field." | |
572 | serialize-fish-aliases) | |
573 | (abbreviations | |
574 | (alist '()) | |
575 | "Association list of abbreviations for Fish. These are words that, | |
576 | when typed in the shell, will automatically expand to the full text." | |
577 | serialize-fish-abbreviations)) | |
578 | ||
579 | (define (fish-files-service config) | |
2c408520 | 580 | `(("fish/config.fish" |
9a2e9a61 AT |
581 | ,(mixed-text-file |
582 | "fish-config.fish" | |
583 | #~(string-append "\ | |
584 | # if we haven't sourced the login config, do it | |
585 | status --is-login; and not set -q __fish_login_config_sourced | |
586 | and begin | |
587 | ||
588 | set --prepend fish_function_path " | |
589 | #$fish-foreign-env | |
590 | "/share/fish/functions | |
591 | fenv source $HOME/.profile | |
592 | set -e fish_function_path[1] | |
593 | ||
594 | set -g __fish_login_config_sourced 1 | |
595 | ||
596 | end\n\n") | |
597 | (serialize-configuration | |
598 | config | |
599 | home-fish-configuration-fields))))) | |
600 | ||
601 | (define (fish-profile-service config) | |
602 | (list (home-fish-configuration-package config))) | |
603 | ||
604 | (define-configuration/no-serialization home-fish-extension | |
605 | (config | |
606 | (text-config '()) | |
ff20d392 | 607 | "List of file-like objects for extending the Fish initialization file.") |
9a2e9a61 AT |
608 | (environment-variables |
609 | (alist '()) | |
610 | "Association list of environment variables to set.") | |
611 | (aliases | |
612 | (alist '()) | |
613 | "Association list of Fish aliases.") | |
614 | (abbreviations | |
615 | (alist '()) | |
616 | "Association list of Fish abbreviations.")) | |
617 | ||
618 | (define (home-fish-extensions original-config extension-configs) | |
619 | (home-fish-configuration | |
620 | (inherit original-config) | |
621 | (config | |
622 | (append (home-fish-configuration-config original-config) | |
623 | (append-map | |
624 | home-fish-extension-config extension-configs))) | |
625 | (environment-variables | |
626 | (append (home-fish-configuration-environment-variables original-config) | |
627 | (append-map | |
628 | home-fish-extension-environment-variables extension-configs))) | |
629 | (aliases | |
630 | (append (home-fish-configuration-aliases original-config) | |
631 | (append-map | |
632 | home-fish-extension-aliases extension-configs))) | |
633 | (abbreviations | |
634 | (append (home-fish-configuration-abbreviations original-config) | |
635 | (append-map | |
636 | home-fish-extension-abbreviations extension-configs))))) | |
637 | ||
638 | ;; TODO: Support for generating completion files | |
639 | ;; TODO: Support for installing plugins | |
640 | (define home-fish-service-type | |
641 | (service-type (name 'home-fish) | |
642 | (extensions | |
643 | (list (service-extension | |
2c408520 | 644 | home-xdg-configuration-files-service-type |
9a2e9a61 AT |
645 | fish-files-service) |
646 | (service-extension | |
647 | home-profile-service-type | |
648 | fish-profile-service))) | |
649 | (compose identity) | |
650 | (extend home-fish-extensions) | |
651 | (default-value (home-fish-configuration)) | |
652 | (description "\ | |
653 | Install and configure Fish, the friendly interactive shell."))) | |
654 | ||
655 | ||
656 | (define (generate-home-shell-profile-documentation) | |
657 | (generate-documentation | |
658 | `((home-shell-profile-configuration | |
659 | ,home-shell-profile-configuration-fields)) | |
660 | 'home-shell-profile-configuration)) | |
661 | ||
662 | (define (generate-home-bash-documentation) | |
2f665d43 XC |
663 | (string-append |
664 | (generate-documentation | |
665 | `((home-bash-configuration | |
666 | ,home-bash-configuration-fields)) | |
667 | 'home-bash-configuration) | |
668 | "\n\n" | |
669 | (generate-documentation | |
670 | `((home-bash-extension | |
671 | ,home-bash-extension-fields)) | |
672 | 'home-bash-extension))) | |
9a2e9a61 AT |
673 | |
674 | (define (generate-home-zsh-documentation) | |
675 | (generate-documentation | |
676 | `((home-zsh-configuration | |
677 | ,home-zsh-configuration-fields)) | |
678 | 'home-zsh-configuration)) | |
679 | ||
680 | (define (generate-home-fish-documentation) | |
681 | (string-append | |
682 | (generate-documentation | |
683 | `((home-fish-configuration | |
684 | ,home-fish-configuration-fields)) | |
685 | 'home-fish-configuration) | |
686 | "\n\n" | |
687 | (generate-documentation | |
688 | `((home-fish-extension | |
689 | ,home-fish-extension-fields)) | |
690 | 'home-fish-extension))) |