Subject: [PATCH 4/5] guix home: Add 'edit' sub-command.

From: Ludovic Courtès <[email-masked]>
Date: Wed, 1 Jun 2022 17:43:01 +0200

* guix/scripts/home/edit.scm: New file.
* Makefile.am (MODULES): Add it.
* guix/scripts/home.scm (show-help): Add "edit".
(process-command): Handle it.
(guix-home): Add it.
* po/guix/POTFILES.in: Add 'guix/scripts/home/edit.scm'.
* doc/guix.texi (Invoking guix home): Document it.
---
 Makefile.am                |  1 +
 doc/guix.texi              | 13 ++++++++
 guix/scripts/home.scm      |  7 +++-
 guix/scripts/home/edit.scm | 66 ++++++++++++++++++++++++++++++++++++++
 po/guix/POTFILES.in        |  1 +
 5 files changed, 87 insertions(+), 1 deletion(-)
 create mode 100644 guix/scripts/home/edit.scm

diff --git a/Makefile.am b/Makefile.am
index 89bc03c9a2..e8d4b7ef8a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -312,6 +312,7 @@ MODULES =					\
   guix/scripts/system/reconfigure.scm		\
   guix/scripts/system/search.scm		\
   guix/scripts/home.scm			\
+  guix/scripts/home/edit.scm			\
   guix/scripts/home/import.scm			\
   guix/scripts/lint.scm				\
   guix/scripts/challenge.scm			\
diff --git a/doc/guix.texi b/doc/guix.texi
index ecd99084ef..f85eaacdfa 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -39466,6 +39466,19 @@ guix home container config.scm -- herd status
 The command to run in the container must come after @code{--} (double
 hyphen).
 
+@cindex service type definition, editing
+@cindex editing, service type definition
+@item edit
+Edit or view the definition of the given Home service types.
+
+For example, the command below opens your editor, as specified by the
+@env{EDITOR} environment variable, on the definition of the
+@code{home-mcron} service type:
+
+@example
+guix home edit home-mcron
+@end example
+
 @item reconfigure
 Build the home environment described in @var{file}, and switch to it.
 Switching means that the activation script will be evaluated and (in
diff --git a/guix/scripts/home.scm b/guix/scripts/home.scm
index f43bf865a7..0f5c3388a1 100644
--- a/guix/scripts/home.scm
+++ b/guix/scripts/home.scm
@@ -60,6 +60,7 @@ (define-module (guix scripts home)
   #:autoload   (guix scripts pull) (channel-commit-hyperlink)
   #:autoload   (guix scripts system) (service-node-type
                                       shepherd-service-node-type)
+  #:autoload   (guix scripts home edit) (guix-home-edit)
   #:autoload   (guix scripts home import) (import-manifest)
   #:use-module ((guix status) #:select (with-status-verbosity))
   #:use-module ((guix build utils) #:select (mkdir-p))
@@ -93,6 +94,8 @@ (define (show-help)
   (newline)
   (display (G_ "\
    search             search for existing service types\n"))
+  (display (G_ "\
+   edit               edit the definition of an existing service type\n"))
   (display (G_ "
    container          run the home environment configuration in a container\n"))
   (display (G_ "\
@@ -539,6 +542,8 @@ (define-syntax-rule (with-store* store exp ...)
     ;; an home environment file.
     ((search)
      (apply search args))
+    ((edit)
+     (apply guix-home-edit args))
     ((import)
      (let* ((profiles (delete-duplicates
                        (match (filter-map (match-lambda
@@ -611,7 +616,7 @@ (define (parse-sub-command arg result)
               extension-graph shepherd-graph
               list-generations describe
               delete-generations roll-back
-              switch-generation search
+              switch-generation search edit
               import container)
              (alist-cons 'action action result))
             (else (leave (G_ "~a: unknown action~%") action))))))
diff --git a/guix/scripts/home/edit.scm b/guix/scripts/home/edit.scm
new file mode 100644
index 0000000000..a6c05675b3
--- /dev/null
+++ b/guix/scripts/home/edit.scm
@@ -0,0 +1,66 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2022 Ludovic Courtès <[email-masked]>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix scripts home edit)
+  #:use-module (guix diagnostics)
+  #:use-module (guix i18n)
+  #:use-module (guix ui)
+  #:autoload   (guix utils) (string-closest)
+  #:use-module (gnu services)
+  #:use-module (gnu home services)
+  #:use-module (srfi srfi-1)
+  #:use-module (ice-9 match)
+  #:autoload   (guix scripts edit) (spawn-editor)
+  #:export (guix-home-edit))
+
+(define (service-type-not-found type)
+  "Report an error about @var{type} not being found and exit."
+  (report-error (G_ "~a: no such service type~%") type)
+
+  (let* ((type      (symbol->string type))
+         (available (fold-home-service-types (lambda (type lst)
+                                               (cons (symbol->string
+                                                      (service-type-name type))
+                                                     lst))
+                                             '()))
+         (closest   (string-closest type available)))
+    (unless (or (not closest) (string=? closest type))
+      (display-hint (format #f (G_ "Did you mean @code{~a}?~%")
+                            closest))))
+
+  (exit 1))
+
+
+(define (guix-home-edit . args)
+  (when (null? args)
+    (leave (G_ "no service types specified, nothing to edit~%")))
+
+  (with-error-handling
+    (let* ((types (append-map (lambda (type)
+                                (let ((type (string->symbol type)))
+                                  (match (lookup-home-service-types type)
+                                    (() (service-type-not-found type))
+                                    ((one) (list one))
+                                    (lst
+                                     (warning (N_ "~a: ~a matching service type~%"
+                                                  "~a: ~a matching service types~%"
+                                                  (length lst))
+                                              type (length lst))
+                                     lst))))
+                              args)))
+      (spawn-editor (filter-map service-type-location types)))))
diff --git a/po/guix/POTFILES.in b/po/guix/POTFILES.in
index 5ad3c9f0a8..6b8bd92bb7 100644
--- a/po/guix/POTFILES.in
+++ b/po/guix/POTFILES.in
@@ -125,6 +125,7 @@ guix/scripts/archive.scm
 guix/scripts/build.scm
 guix/scripts/discover.scm
 guix/scripts/environment.scm
+guix/scripts/home/edit.scm
 guix/scripts/home/import.scm
 guix/scripts/home.scm
 guix/scripts/time-machine.scm
-- 
2.36.1