;;;
;;; Guix automation.
;;;
(defun guix-package-name-at-point ()
  "Return the name of package at point, as a string"
  (save-excursion
    (beginning-of-defun)
    (forward-char)                      ;skip (
    (forward-sexp)                      ;define-public
    (forward-comment (point-max))
    (symbol-name (symbol-at-point))))

(defun guix-package-sexp-at-point ()
  "Return the package at point, as a string."
  (save-mark-and-excursion
    (mark-defun)
    (buffer-substring-no-properties
     (region-beginning)
     (region-end))))

(defun guix-build-package-at-point ()
  "Evaluate sexp at point and build it in Geiser."
  (interactive)
  (let ((name (guix-package-name-at-point))
        (sexp-string (guix-package-sexp-at-point)))
    ;; Evaluate the package.
    (geiser-mode-switch-to-repl-and-enter) ;start geiser/load module
    (geiser-repl-switch)                ;switch back to scheme buffer
    (guix-geiser-eval sexp-string)

    ;; Build the package.
    (guix-geiser-eval "(use-modules (guix))")
    (guix-geiser-eval-in-repl (format ",build %s" name))

    ;; Inspect log file if the build failed.
    (let ((repl-text (save-mark-and-excursion
                       (buffer-substring-no-properties
                        (region-beginning)
                        (region-end)))))
      (when (string-match (rx "View build log at '" (group (+ graphic)) "'.")
                          repl-text)
        (guix-build-log-find-file (match-string 1 repl-text))))))

;;; Bind it to F7.
(with-eval-after-load 'scheme
  (define-key scheme-mode-map
              (kbd "<f7>")
              #'guix-build-package-at-point))

(defun guix-commit-package-at-point ()
  "Commit a new package NAME at point."
  (interactive)
  (save-buffer)
  (save-window-excursion
    (save-mark-and-excursion
      (let* ((name (guix-package-name-at-point))
             (package-text (guix-package-sexp-at-point))
             (diff-text (replace-regexp-in-string
                         "^" "+" (string-trim-left package-text)))
             (magit-save-repository-buffers 'dontask))
        ;; Find and select change.
        (magit-diff-unstaged)
        (beginning-of-buffer)
        (let* ((end (search-forward diff-text))
               (beg (- end (length diff-text))))
          (set-mark end)
          (goto-char beg))
        ;; Stage it.
        (magit-stage)
        ;; Commit it.
        (let ((commit-message (format "gnu: Add %s.

* %s (%s): New variable." name (car (magit-staged-files)) name)))
          (magit-call-git "commit" "-m" commit-message))
        (magit-refresh))))
  ;; Refresh buffer, to update areas highlighted with diff-hl-mode.
  (revert-buffer t t))

;;; Bind it to F8.
(with-eval-after-load 'scheme
  (define-key scheme-mode-map
              (kbd "<f8>")
              #'guix-commit-package-at-point))

Generated by apteryx using scpaste at Sun Jun 7 08:11:47 2026. JST. (original)