branch: elpa/nix-mode
commit 3d4f24b2b6d19ee2a223188cebbc29a4e4a1a043
Author: Akira Komamura <[email protected]>
Commit: Akira Komamura <[email protected]>
nix-flake: Allow switching the flake inside nix-flake-dispatch
---
nix-flake.el | 77 +++++++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 56 insertions(+), 21 deletions(-)
diff --git a/nix-flake.el b/nix-flake.el
index 775eb3d846..011e2a2f8a 100644
--- a/nix-flake.el
+++ b/nix-flake.el
@@ -39,7 +39,8 @@ already registered in either the user or the global registry."
(defclass nix-flake-ref-variable (transient-variable)
((variable :initarg :variable)
- (constant-value :initarg :constant-value :initform nil)))
+ (constant-value :initarg :constant-value :initform nil)
+ (reader :initarg :reader :initform nil)))
(cl-defmethod transient-init-value ((obj nix-flake-ref-variable))
(unless (oref obj value)
@@ -50,7 +51,9 @@ already registered in either the user or the global registry."
(if (symbolp value)
(symbol-value value)
value)
- (nix-flake--select-flake nil (oref obj value))))
+ (if-let (reader (oref obj reader))
+ (funcall reader "Flake directory: " (oref obj value))
+ (nix-flake--select-flake nil (oref obj value)))))
(cl-defmethod transient-infix-set ((obj nix-flake-ref-variable) value)
(oset obj value value)
@@ -79,20 +82,34 @@ already registered in either the user or the global
registry."
(thread-last (nix--process-lines "registry" "list")
(mapcar #'split-entry))))
+(defun nix-flake--registry-refs ()
+ "Return a list of flake refs in the registry."
+ (thread-last (nix-flake--registry-list)
+ ;; I don't know if I should include flakes in the
+ ;; system registry. It's ugly to display full
+ ;; checksums, so I won't include them for now.
+ (cl-remove-if-not (pcase-lambda (`(,type . ,_))
+ (member type '("user" "global"))))
+ (mapcar (lambda (cells)
+ (list (nth 1 cells)
+ (nth 2 cells))))
+ (flatten-list)))
+
+(defun nix-flake--registry-add-1 (flake-ref)
+ "Add FLAKE-REF to the registry with a new name."
+ (let ((name (read-string (format-message "Enter the registry name for %s: "
+ flake-ref))))
+ (unless (or (not name)
+ (string-empty-p name))
+ (start-process "nix registry add" "*nix registry add*"
+ nix-executable
+ "registry" "add" name flake-ref))))
+
;; This argument complies the standard reader interface of transient
;; just in case, but it may not be necessary.
(defun nix-flake--select-flake (&optional prompt initial-input history)
"Select a flake from the registry."
- (let* ((registered-flakes (thread-last (nix-flake--registry-list)
- ;; I don't know if I should include flakes in the
- ;; system registry. It's ugly to display full
- ;; checksums, so I won't include them for now.
- (cl-remove-if-not (pcase-lambda (`(,type . ,_))
- (member type '("user"
"global"))))
- (mapcar (lambda (cells)
- (list (nth 1 cells)
- (nth 2 cells))))
- (flatten-list)))
+ (let* ((registered-flakes (nix-flake--registry-refs))
(input (string-trim
(completing-read (or prompt "Flake URL: ")
registered-flakes
@@ -100,13 +117,7 @@ already registered in either the user or the global
registry."
(prog1 input
(when (and nix-flake-add-to-registry
(not (member input registered-flakes)))
- (let ((name (read-string (format-message "Enter the registry name for
%s: "
- input))))
- (unless (or (not name)
- (string-empty-p name))
- (start-process "nix registry add" "*nix registry add*"
- nix-executable
- "registry" "add" name input)))))))
+ (nix-flake--registry-add-1 input)))))
;;;; nix-flake command
@@ -114,6 +125,28 @@ already registered in either the user or the global
registry."
(defvar nix-flake-ref nil)
+;;;;; Setting the flake
+(transient-define-infix nix-flake:from-registry ()
+ :class 'nix-flake-ref-variable
+ :variable 'nix-flake-ref
+ :description "Select a flake from the registry")
+
+(transient-define-infix nix-flake:flake-directory ()
+ :class 'nix-flake-ref-variable
+ :variable 'nix-flake-ref
+ :reader 'nix-flake--read-directory
+ :description "Select a directory")
+
+(defun nix-flake--read-directory (prompt &optional initial-input _history)
+ "Select a directory containing a flake."
+ (let ((input (read-directory-name prompt initial-input nil t)))
+ (prog1 (expand-file-name input)
+ (unless (file-exists-p (expand-file-name "flake.nix" input))
+ (user-error "The selected directory does not contain flake.nix"))
+ (when (and nix-flake-add-to-registry
+ (not (member input (nix-flake--registry-refs))))
+ (nix-flake--registry-add-1 input)))))
+
;;;;; --update-input
(defclass nix-flake:update-input (transient-option)
@@ -317,8 +350,10 @@ For ARGS and FLAKE-REF, see the documentation of
;;;###autoload (autoload 'nix-flake-dispatch "nix-flake" nil t)
(transient-define-prefix nix-flake-dispatch (flake-ref &optional remote)
"Run a command on a Nix flake."
- ;; TODO: Allow switching the flake
- [:description nix-flake--description]
+ [:description
+ nix-flake--description
+ ("=r" nix-flake:from-registry)
+ ("=d" nix-flake:flake-directory)]
["Arguments"
("-m" "Allow access to mutable paths and repositories" "--impure")
("-u" nix-flake-arg:update-input)