[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master a5b477a: Add let-alist macro and package.
From: |
Teodor Zlatanov |
Subject: |
[Emacs-diffs] master a5b477a: Add let-alist macro and package. |
Date: |
Wed, 10 Dec 2014 18:58:49 +0000 |
branch: master
commit a5b477aa92e4b76896efa57f9bd62912bd92dd02
Author: Artur Malabarba <address@hidden>
Commit: Ted Zlatanov <address@hidden>
Add let-alist macro and package.
* let-alist.el: Add new package and macro.
---
lisp/ChangeLog | 4 ++
lisp/let-alist.el | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 114 insertions(+), 0 deletions(-)
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index d5f2254..e65835c 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,7 @@
+2014-12-10 Artur Malabarba <address@hidden>
+
+ * let-alist.el: Add new package and macro.
+
2014-12-10 Eric S. Raymond <address@hidden>
* vc/vc-dispatcher.el, vc/vc-hooks.el, vc/vc-rcs.el,
diff --git a/lisp/let-alist.el b/lisp/let-alist.el
new file mode 100644
index 0000000..1cf5c27
--- /dev/null
+++ b/lisp/let-alist.el
@@ -0,0 +1,110 @@
+;;; let-alist.el --- Easily let-bind values of an assoc-list by their names.
+
+;; Copyright (C) 2014 Free Software Foundation, Inc.
+
+;; Author: Artur Malabarba <address@hidden>
+;; Maintainer: Artur Malabarba <address@hidden>
+;; Version: 1.0
+;; Keywords: extensions lisp
+;; Prefix: let-alist
+;; Separator: -
+
+;;; Commentary:
+;;
+;; This package offers a single macro, `let-alist'. This macro takes a
+;; first argument (whose value must be an alist) and a body.
+;;
+;; The macro expands to a let form containing body, where each dotted
+;; symbol inside body is let-bound to their cdrs in the alist. Dotted
+;; symbol is any symbol starting with a `.'. Only those present in
+;; the body are let-bound and this search is done at compile time.
+;;
+;; For instance, the following code
+;;
+;; (let-alist alist
+;; (if (and .title .body)
+;; .body
+;; .site))
+;;
+;; expands to
+;;
+;; (let ((.title (cdr (assq 'title alist)))
+;; (.body (cdr (assq 'body alist)))
+;; (.site (cdr (assq 'site alist))))
+;; (if (and .title .body)
+;; .body
+;; .site))
+;;
+;; Note that only one level is supported. If you nest `let-alist'
+;; invocations, the inner one can't access the variables of the outer
+;; one.
+
+;;; License:
+;;
+;; This file is part of GNU Emacs.
+;;
+;; GNU Emacs 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 Emacs 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 Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+
+(defun let-alist--deep-dot-search (data)
+ "Return alist of symbols inside DATA which start with a `.'.
+Perform a deep search and return an alist where each car is the
+symbol, and each cdr is the same symbol without the `.'."
+ (cond
+ ((symbolp data)
+ (let ((name (symbol-name data)))
+ (when (string-match "\\`\\." name)
+ ;; Return the cons cell inside a list, so it can be appended
+ ;; with other results in the clause below.
+ (list (cons data (intern (replace-match "" nil nil name)))))))
+ ((not (listp data)) nil)
+ (t (apply #'append
+ (remove nil (mapcar #'let-alist--deep-dot-search data))))))
+
+;;;###autoload
+(defmacro let-alist (alist &rest body)
+ "Let-bind dotted symbols to their cdrs in ALIST and execute BODY.
+Dotted symbol is any symbol starting with a `.'. Only those
+present in BODY are let-bound and this search is done at compile
+time.
+
+For instance, the following code
+
+ (let-alist alist
+ (if (and .title .body)
+ .body
+ .site))
+
+expands to
+
+ (let ((.title (cdr (assq 'title alist)))
+ (.body (cdr (assq 'body alist)))
+ (.site (cdr (assq 'site alist))))
+ (if (and .title .body)
+ .body
+ .site))"
+ (declare (indent 1) (debug t))
+ `(let ,(mapcar (lambda (x) `(,(car x) (cdr (assq ',(cdr x) ,alist))))
+ (delete-dups (let-alist--deep-dot-search body)))
+ ,@body))
+
+(provide 'let-alist)
+
+;; Local Variables:
+;; sentence-end-double-space: t
+;; End:
+
+;;; let-alist.el ends here
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] master a5b477a: Add let-alist macro and package.,
Teodor Zlatanov <=