summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Kost <alezost@gmail.com>2015-11-19 01:17:32 +0300
committerAlex Kost <alezost@gmail.com>2016-01-02 17:25:35 +0300
commitd9c9f9a51552dc208dde688e54e8268831031524 (patch)
treed6b8433809ff425e75688f8908d04f6b1d21cfd6
parent4ba476f94992247cd54541ac09b0a516660f20e5 (diff)
downloadguix-d9c9f9a51552dc208dde688e54e8268831031524.tar.gz
emacs: Add 'guix-alist-put'.
* emacs/guix-utils.el (guix-alist-put, guix-alist-put-1)
  (guix-alist-put!): New procedures.
-rw-r--r--emacs/guix-utils.el44
1 files changed, 43 insertions, 1 deletions
diff --git a/emacs/guix-utils.el b/emacs/guix-utils.el
index 3748350b87..fbe0a613da 100644
--- a/emacs/guix-utils.el
+++ b/emacs/guix-utils.el
@@ -307,7 +307,7 @@ Example:
        ,@body)))
 
 
-;;; Alist accessors
+;;; Alist procedures
 
 (defmacro guix-define-alist-accessor (name assoc-fun)
   "Define NAME function to access alist values using ASSOC-FUN."
@@ -325,6 +325,48 @@ accessed with KEYS."
 (guix-define-alist-accessor guix-assq-value assq)
 (guix-define-alist-accessor guix-assoc-value assoc)
 
+(defun guix-alist-put (value alist &rest keys)
+  "Put (add or replace if exists) VALUE to ALIST using KEYS.
+Return the new alist.
+
+ALIST is alist of alists of alists ... which can be consecutively
+accessed with KEYS.
+
+Example:
+
+  (guix-alist-put
+   'foo
+   '((one (a . 1) (b . 2))
+     (two (m . 7) (n . 8)))
+   'one 'b)
+
+  => ((one (a . 1) (b . foo))
+      (two (m . 7) (n . 8)))"
+  (or keys (error "Keys should be specified"))
+  (guix-alist-put-1 value alist keys))
+
+(defun guix-alist-put-1 (value alist keys)
+  "Subroutine of `guix-alist-put'."
+  (cond
+   ((null keys)
+    value)
+   ((null alist)
+    (list (cons (car keys)
+                (guix-alist-put-1 value nil (cdr keys)))))
+   ((eq (car keys) (caar alist))
+    (cons (cons (car keys)
+                (guix-alist-put-1 value (cdar alist) (cdr keys)))
+          (cdr alist)))
+   (t
+    (cons (car alist)
+          (guix-alist-put-1 value (cdr alist) keys)))))
+
+(defun guix-alist-put! (value variable &rest keys)
+  "Modify alist VARIABLE (symbol) by putting VALUE using KEYS.
+See `guix-alist-put' for details."
+  (set variable
+       (apply #'guix-alist-put value (symbol-value variable) keys)))
+
 
 ;;; Diff