emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* [PATCH 0/8] Org mode macros, refactored
@ 2011-08-02  9:23 David Maus
  2011-08-02  9:23 ` [PATCH 1/7] New macro: Execute BODY in enviroment with uninterned SYMBOLS David Maus
                   ` (8 more replies)
  0 siblings, 9 replies; 18+ messages in thread
From: David Maus @ 2011-08-02  9:23 UTC (permalink / raw)
  To: emacs-orgmode; +Cc: David Maus

Following series of patches is product of some refactoring of
macro-usage in Org mode. It defines two new macros and applies those
macros in other macros in org-macs and batch-agenda functions.

Comments are welcome. I'll create a bundle for the patches in
patchwork. If there are no objections I would like to push these
changes at the end of the week.

Maybe the most conveniant macro for further development is

(org-with-uninterend SYMBOLS BODY)

This macro wraps BODY in a let binding form where each symbol in
SYMBOLS is bound to a new but uninterned symbol of the same name. This
way you can avoid leaking or, more precisely, capturing of symbols if
you write a macro that needs to bind its own control variables in the
macro expansion form.

E.g.

(defmacro org-preserve-lc (&rest body)
  `(let ((line (org-current-line))
         (col (current-column)))
     (unwind-protect
       (progn ,@body)
	 (org-goto-line line)
	 (org-move-to-column col))))

The let binding at the top of the expansion form shadows symbols with
the name line and cols if they are bound before BODY, and if BODY uses
symbols with the same name it would overwrite the symbols bound in the
let form.

Org-with-uninterned prevents this by creating new uninterned symbols
which are unreachable outside the expanded form and inside BODY.

(defmacro org-preserve-lc (&rest body)
  (org-with-uninterned (line col)
    `(let ((,line (org-current-line))
	   (,col (current-column)))
       (unwind-protect
	   (progn ,@body)
	 (org-goto-line ,line)
	 (org-move-to-column ,col)))))

Expands to:

(let
    ((line
      (make-symbol
       (symbol-name 'line)))
     (col
      (make-symbol
       (symbol-name 'col))))
  `(let
       ((,line
	 (org-current-line))
	(,col
	 (current-column)))
     (unwind-protect
	 (progn ,@body)
       (org-goto-line ,line)
       (org-move-to-column ,col))))

This way ,line and ,col in the macro expansion refer to the new
uninterned symbols line and col created outside the expansion form.

Note: The usage of make-symbol works but has one drawback: The new
uninterned symbols have the same name as the maybe interned symbols in
BODY. Ideally we should use `gensym' instead, which creates a new
uninterned symbol with a unique name. But gensym is part of the
cl-package and thus not allowed to be called at runtime for a program
to be part of Emacs core.

David Maus (8):
  New macro: Execute BODY in enviroment with uninterned SYMBOLS.
  Use new macro org-with-uninterned
  New macro: Evaluate BODY in ENVIRONMENT
  New function: Substitute posix classes in regular expression
  Use macro org-with-uninterned
  New function: Turn a flat parameter list into an alist
  Use org-eval-in-environment, make macros functions
  Make org-batch-store-agenda-views a fun, use org-eval-in-environment

 lisp/org-agenda.el |   92 ++++++++++++++++-------------------
 lisp/org-macs.el   |  137 +++++++++++++++++++++++++++++++---------------------
 2 files changed, 123 insertions(+), 106 deletions(-)

-- 
1.7.2.5

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 1/7] New macro: Execute BODY in enviroment with uninterned SYMBOLS
  2011-08-02  9:23 [PATCH 0/8] Org mode macros, refactored David Maus
@ 2011-08-02  9:23 ` David Maus
  2011-08-02 13:48   ` David Maus
       [not found]   ` <CAJcAo8uv46JCx9cG0x_ip9DMQ-aN=buLRO_fONPoFuDkik6J1Q@mail.gmail.com>
  2011-08-02  9:23 ` [PATCH 2/7] New macro: Evaluate FORM in ENVIRONMENT David Maus
                   ` (7 subsequent siblings)
  8 siblings, 2 replies; 18+ messages in thread
From: David Maus @ 2011-08-02  9:23 UTC (permalink / raw)
  To: emacs-orgmode; +Cc: David Maus

* org-macs.el (org-with-uninterned): New macro. Execute BODY in
enviroment with uninterned SYMBOLS.
---
 lisp/org-macs.el |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/lisp/org-macs.el b/lisp/org-macs.el
index 906be61..53c60e5 100644
--- a/lisp/org-macs.el
+++ b/lisp/org-macs.el
@@ -370,6 +370,12 @@ The number of levels is controlled by `org-inlinetask-min-level'"
       (format-seconds string seconds)
     (format-time-string string (seconds-to-time seconds))))
 
+(defmacro org-with-uninterned (symbols &rest body)
+  `(let ,(mapcar (lambda (s)
+		   `(,s (make-symbol (symbol-name ',s)))) symbols)
+     ,@body))
+(put 'org-with-uninterned 'lisp-indent-function 1)
+
 (provide 'org-macs)
 
 ;; arch-tag: 7e6a73ce-aac9-4fc0-9b30-ce6f89dc6668
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 2/7] New macro: Evaluate FORM in ENVIRONMENT
  2011-08-02  9:23 [PATCH 0/8] Org mode macros, refactored David Maus
  2011-08-02  9:23 ` [PATCH 1/7] New macro: Execute BODY in enviroment with uninterned SYMBOLS David Maus
@ 2011-08-02  9:23 ` David Maus
  2011-08-02 10:50   ` Štěpán Němec
  2011-08-02 13:49   ` David Maus
  2011-08-02  9:23 ` [PATCH 3/7] Use new macro org-with-uninterned David Maus
                   ` (6 subsequent siblings)
  8 siblings, 2 replies; 18+ messages in thread
From: David Maus @ 2011-08-02  9:23 UTC (permalink / raw)
  To: emacs-orgmode; +Cc: David Maus

* org-macs.el (org-eval-in-environment): New macro. Evaluate
FORM in ENVIRONMENT.
(org-with-uninterned): Move to top of file.
---
 lisp/org-macs.el |   23 ++++++++++++++++++-----
 1 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/lisp/org-macs.el b/lisp/org-macs.el
index 53c60e5..7a0cc60 100644
--- a/lisp/org-macs.el
+++ b/lisp/org-macs.el
@@ -47,6 +47,12 @@
 (declare-function org-add-props "org-compat" (string plist &rest props))
 (declare-function org-string-match-p "org-compat" (&rest args))
 
+(defmacro org-with-uninterned (symbols &rest body)
+  `(let ,(mapcar (lambda (s)
+		   `(,s (make-symbol (symbol-name ',s)))) symbols)
+     ,@body))
+(put 'org-with-uninterned 'lisp-indent-function 1)
+
 (defmacro org-called-interactively-p (&optional kind)
   (if (featurep 'xemacs)
        `(interactive-p)
@@ -370,11 +376,18 @@ The number of levels is controlled by `org-inlinetask-min-level'"
       (format-seconds string seconds)
     (format-time-string string (seconds-to-time seconds))))
 
-(defmacro org-with-uninterned (symbols &rest body)
-  `(let ,(mapcar (lambda (s)
-		   `(,s (make-symbol (symbol-name ',s)))) symbols)
-     ,@body))
-(put 'org-with-uninterned 'lisp-indent-function 1)
+(defun org-make-parameter-alist (flat)
+  "Return alist based on FLAT.
+FLAT is a list with alternating symbol names and values. The
+returned alist is a list of lists with the symbol name in car and
+the value in cdr."
+  (when flat
+    (cons (list (car flat) (cadr flat))
+	  (org-make-parameter-alist (cddr flat)))))
+
+(defmacro org-eval-in-environment (environment form)
+  `(eval '(let ,environment ,form)))
+(put 'org-eval-in-environment 'lisp-indent-function 1)
 
 (provide 'org-macs)
 
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 3/7] Use new macro org-with-uninterned
  2011-08-02  9:23 [PATCH 0/8] Org mode macros, refactored David Maus
  2011-08-02  9:23 ` [PATCH 1/7] New macro: Execute BODY in enviroment with uninterned SYMBOLS David Maus
  2011-08-02  9:23 ` [PATCH 2/7] New macro: Evaluate FORM in ENVIRONMENT David Maus
@ 2011-08-02  9:23 ` David Maus
  2011-08-02  9:23 ` [PATCH 4/7] New function: Substitute posix classes in regular expression David Maus
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 18+ messages in thread
From: David Maus @ 2011-08-02  9:23 UTC (permalink / raw)
  To: emacs-orgmode; +Cc: David Maus

* org-macs.el (org-preserve-lc, org-with-point-at)
(org-with-remote-undo, org-save-outline-visibility): Use new macro
org-with-uninterned.
---
 lisp/org-macs.el |   90 ++++++++++++++++++++++++++++--------------------------
 1 files changed, 47 insertions(+), 43 deletions(-)

diff --git a/lisp/org-macs.el b/lisp/org-macs.el
index 7a0cc60..ab21ef7 100644
--- a/lisp/org-macs.el
+++ b/lisp/org-macs.el
@@ -110,12 +110,13 @@ Also, do not record undo information."
     s))
 
 (defmacro org-preserve-lc (&rest body)
-  `(let ((_line (org-current-line))
-	 (_col (current-column)))
-     (unwind-protect
-	 (progn ,@body)
-       (org-goto-line _line)
-       (org-move-to-column _col))))
+  (org-with-uninterned (line col)
+    `(let ((,line (org-current-line))
+	   (,col (current-column)))
+       (unwind-protect
+	   (progn ,@body)
+	 (org-goto-line ,line)
+	 (org-move-to-column ,col)))))
 
 (defmacro org-without-partial-completion (&rest body)
   `(if (and (boundp 'partial-completion-mode)
@@ -142,12 +143,13 @@ We use a macro so that the test can happen at compilation time."
 
 (defmacro org-with-point-at (pom &rest body)
   "Move to buffer and point of point-or-marker POM for the duration of BODY."
-  `(let ((pom ,pom))
-     (save-excursion
-       (if (markerp pom) (set-buffer (marker-buffer pom)))
+  (org-with-uninterned (mpom)
+    `(let ((,mpom ,pom))
        (save-excursion
-	 (goto-char (or pom (point)))
-	 ,@body))))
+	 (if (markerp ,mpom) (set-buffer (marker-buffer ,mpom)))
+	 (save-excursion
+	   (goto-char (or ,mpom (point)))
+	   ,@body)))))
 (put 'org-with-point-at 'lisp-indent-function 1)
 
 (defmacro org-no-warnings (&rest body)
@@ -180,26 +182,27 @@ We use a macro so that the test can happen at compilation time."
 
 (defmacro org-with-remote-undo (_buffer &rest _body)
   "Execute BODY while recording undo information in two buffers."
-  `(let ((_cline (org-current-line))
-	 (_cmd this-command)
-	 (_buf1 (current-buffer))
-	 (_buf2 ,_buffer)
-	 (_undo1 buffer-undo-list)
-	 (_undo2 (with-current-buffer ,_buffer buffer-undo-list))
-	 _c1 _c2)
-     ,@_body
-     (when org-agenda-allow-remote-undo
-       (setq _c1 (org-verify-change-for-undo
-		  _undo1 (with-current-buffer _buf1 buffer-undo-list))
-	     _c2 (org-verify-change-for-undo
-		  _undo2 (with-current-buffer _buf2 buffer-undo-list)))
-       (when (or _c1 _c2)
-	 ;; make sure there are undo boundaries
-	 (and _c1 (with-current-buffer _buf1 (undo-boundary)))
-	 (and _c2 (with-current-buffer _buf2 (undo-boundary)))
-	 ;; remember which buffer to undo
-	 (push (list _cmd _cline _buf1 _c1 _buf2 _c2)
-	       org-agenda-undo-list)))))
+  (org-with-uninterned (cline cmd buf1 buf2 undo1 undo2 c1 c2)
+    `(let ((,cline (org-current-line))
+	   (,cmd this-command)
+	   (,buf1 (current-buffer))
+	   (,buf2 ,_buffer)
+	   (,undo1 buffer-undo-list)
+	   (,undo2 (with-current-buffer ,_buffer buffer-undo-list))
+	   ,c1 ,c2)
+       ,@_body
+       (when org-agenda-allow-remote-undo
+	 (setq ,c1 (org-verify-change-for-undo
+		    ,undo1 (with-current-buffer ,buf1 buffer-undo-list))
+	       ,c2 (org-verify-change-for-undo
+		    ,undo2 (with-current-buffer ,buf2 buffer-undo-list)))
+	 (when (or ,c1 ,c2)
+	   ;; make sure there are undo boundaries
+	   (and ,c1 (with-current-buffer ,buf1 (undo-boundary)))
+	   (and ,c2 (with-current-buffer ,buf2 (undo-boundary)))
+	   ;; remember which buffer to undo
+	   (push (list ,cmd ,cline ,buf1 ,c1 ,buf2 ,c2)
+		 org-agenda-undo-list))))))
 (put 'org-with-remote-undo 'lisp-indent-function 1)
 
 (defmacro org-no-read-only (&rest body)
@@ -331,18 +334,19 @@ but it also means that the buffer should stay alive
 during the operation, because otherwise all these markers will
 point nowhere."
   (declare (indent 1))
-  `(let ((data (org-outline-overlay-data ,use-markers))
-	 rtn)
-     (unwind-protect
-	 (progn
-	   (setq rtn (progn ,@body))
-	   (org-set-outline-overlay-data data))
-       (when ,use-markers
-	 (mapc (lambda (c)
-		 (and (markerp (car c)) (move-marker (car c) nil))
-		 (and (markerp (cdr c)) (move-marker (cdr c) nil)))
-	       data)))
-     rtn))
+  (org-with-uninterned (data rtn)
+    `(let ((,data (org-outline-overlay-data ,use-markers))
+	   ,rtn)
+       (unwind-protect
+	   (progn
+	     (setq ,rtn (progn ,@body))
+	     (org-set-outline-overlay-data ,data))
+	 (when ,use-markers
+	   (mapc (lambda (c)
+		   (and (markerp (car c)) (move-marker (car c) nil))
+		   (and (markerp (cdr c)) (move-marker (cdr c) nil)))
+		 ,data)))
+       ,rtn)))
 
 (defmacro org-with-wide-buffer (&rest body)
  "Execute body while temporarily widening the buffer."
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 4/7] New function: Substitute posix classes in regular expression
  2011-08-02  9:23 [PATCH 0/8] Org mode macros, refactored David Maus
                   ` (2 preceding siblings ...)
  2011-08-02  9:23 ` [PATCH 3/7] Use new macro org-with-uninterned David Maus
@ 2011-08-02  9:23 ` David Maus
  2011-08-02  9:23 ` [PATCH 5/7] Use macro org-with-uninterned David Maus
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 18+ messages in thread
From: David Maus @ 2011-08-02  9:23 UTC (permalink / raw)
  To: emacs-orgmode; +Cc: David Maus

* org-macs.el (org-substitute-posix-classes): New function. Substitute
posix classes in regular expression.
(org-re): Rewritten to use new function.
---
 lisp/org-macs.el |   28 +++++++++++++++-------------
 1 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/lisp/org-macs.el b/lisp/org-macs.el
index ab21ef7..198d210 100644
--- a/lisp/org-macs.el
+++ b/lisp/org-macs.el
@@ -93,21 +93,23 @@ Also, do not record undo information."
 	    before-change-functions after-change-functions)
 	,@body))))
 
+(defun org-substitute-posix-classes (re)
+  "Substitute posix classes in regular expression RE."
+  (let ((ss re))
+    (save-match-data
+      (while (string-match "\\[:alnum:\\]" ss)
+	(setq ss (replace-match "a-zA-Z0-9" t t ss)))
+      (while (string-match "\\[:word:\\]" ss)
+	(setq ss (replace-match "a-zA-Z0-9" t t ss)))
+      (while (string-match "\\[:alpha:\\]" ss)
+	(setq ss (replace-match "a-zA-Z" t t ss)))
+      (while (string-match "\\[:punct:\\]" ss)
+	(setq ss (replace-match "\001-@[-`{-~" t t ss)))
+      ss)))
+
 (defmacro org-re (s)
   "Replace posix classes in regular expression."
-  (if (featurep 'xemacs)
-      (let ((ss s))
-	(save-match-data
-	  (while (string-match "\\[:alnum:\\]" ss)
-	    (setq ss (replace-match "a-zA-Z0-9" t t ss)))
-	  (while (string-match "\\[:word:\\]" ss)
-	    (setq ss (replace-match "a-zA-Z0-9" t t ss)))
-	  (while (string-match "\\[:alpha:\\]" ss)
-	    (setq ss (replace-match "a-zA-Z" t t ss)))
-	  (while (string-match "\\[:punct:\\]" ss)
-	    (setq ss (replace-match "\001-@[-`{-~" t t ss)))
-	  ss))
-    s))
+  (if (featurep 'xemacs) `(org-substitute-posix-classes ,s) s))
 
 (defmacro org-preserve-lc (&rest body)
   (org-with-uninterned (line col)
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 5/7] Use macro org-with-uninterned
  2011-08-02  9:23 [PATCH 0/8] Org mode macros, refactored David Maus
                   ` (3 preceding siblings ...)
  2011-08-02  9:23 ` [PATCH 4/7] New function: Substitute posix classes in regular expression David Maus
@ 2011-08-02  9:23 ` David Maus
  2011-08-02  9:23 ` [PATCH 6/7] Use org-eval-in-environment, make macros functions David Maus
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 18+ messages in thread
From: David Maus @ 2011-08-02  9:23 UTC (permalink / raw)
  To: emacs-orgmode; +Cc: David Maus

* org-agenda.el (org-agenda-with-point-at-orig-entry): Use macro
org-with-uninterned.
---
 lisp/org-agenda.el |   13 +++++++------
 1 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el
index d47013b..25a556e 100644
--- a/lisp/org-agenda.el
+++ b/lisp/org-agenda.el
@@ -1714,12 +1714,13 @@ Note that functions in this alist don't need to be quoted."
 If STRING is non-nil, the text property will be fetched from position 0
 in that string.  If STRING is nil, it will be fetched from the beginning
 of the current line."
-  `(let ((marker (get-text-property (if string 0 (point-at-bol))
-				    'org-hd-marker string)))
-     (with-current-buffer (marker-buffer marker)
-       (save-excursion
-	 (goto-char marker)
-	 ,@body))))
+  (org-with-uninterned (marker)
+    `(let ((,marker (get-text-property (if string 0 (point-at-bol))
+				       'org-hd-marker string)))
+       (with-current-buffer (marker-buffer ,marker)
+	 (save-excursion
+	   (goto-char ,marker)
+	   ,@body)))))
 
 (defun org-add-agenda-custom-command (entry)
   "Replace or add a command in `org-agenda-custom-commands'.
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 6/7] Use org-eval-in-environment, make macros functions
  2011-08-02  9:23 [PATCH 0/8] Org mode macros, refactored David Maus
                   ` (4 preceding siblings ...)
  2011-08-02  9:23 ` [PATCH 5/7] Use macro org-with-uninterned David Maus
@ 2011-08-02  9:23 ` David Maus
  2011-08-02  9:23 ` [PATCH 7/7] Make org-batch-store-agenda-views a fun, use org-eval-in-environment David Maus
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 18+ messages in thread
From: David Maus @ 2011-08-02  9:23 UTC (permalink / raw)
  To: emacs-orgmode; +Cc: David Maus

* org-agenda.el (org-batch-agenda, org-batch-agenda-csv): Make
a function, use org-eval-in-environment.
---
 lisp/org-agenda.el |   59 ++++++++++++++++++++++-----------------------------
 1 files changed, 26 insertions(+), 33 deletions(-)

diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el
index 25a556e..6079377 100644
--- a/lisp/org-agenda.el
+++ b/lisp/org-agenda.el
@@ -2569,22 +2569,19 @@ s   Search for keywords                 C   Configure custom agenda commands
   (org-let (nth 1 series) '(org-finalize-agenda)))
 
 ;;;###autoload
-(defmacro org-batch-agenda (cmd-key &rest parameters)
+(defun org-batch-agenda (cmd-key &rest parameters)
   "Run an agenda command in batch mode and send the result to STDOUT.
 If CMD-KEY is a string of length 1, it is used as a key in
 `org-agenda-custom-commands' and triggers this command.  If it is a
 longer string it is used as a tags/todo match string.
 Parameters are alternating variable names and values that will be bound
 before running the agenda command."
-  (let (pars)
-    (while parameters
-      (push (list (pop parameters) (if parameters (pop parameters))) pars))
+  (org-eval-in-environment (org-make-parameter-alist parameters)
     (if (> (length cmd-key) 2)
-	(eval (list 'let (nreverse pars)
-		    (list 'org-tags-view nil cmd-key)))
-      (eval (list 'let (nreverse pars) (list 'org-agenda nil cmd-key))))
-    (set-buffer org-agenda-buffer-name)
-    (princ (org-encode-for-stdout (buffer-string)))))
+	(org-tags-view nil cmd-key)
+      (org-agenda nil cmd-key)))
+  (set-buffer org-agenda-buffer-name)
+  (princ (org-encode-for-stdout (buffer-string))))
 
 ;(defun org-encode-for-stdout (string)
 ;  (if (fboundp 'encode-coding-string)
@@ -2597,7 +2594,7 @@ before running the agenda command."
 (defvar org-agenda-info nil)
 
 ;;;###autoload
-(defmacro org-batch-agenda-csv (cmd-key &rest parameters)
+(defun org-batch-agenda-csv (cmd-key &rest parameters)
   "Run an agenda command in batch mode and send the result to STDOUT.
 If CMD-KEY is a string of length 1, it is used as a key in
 `org-agenda-custom-commands' and triggers this command.  If it is a
@@ -2631,30 +2628,26 @@ extra        Sting with extra planning info
 priority-l   The priority letter if any was given
 priority-n   The computed numerical priority
 agenda-day   The day in the agenda where this is listed"
-
-  (let (pars)
-    (while parameters
-      (push (list (pop parameters) (if parameters (pop parameters))) pars))
-    (push (list 'org-agenda-remove-tags t) pars)
+  (org-eval-in-environment (append (org-agenda-remove-tags t)
+				   (org-make-parameter-alist parameters))
     (if (> (length cmd-key) 2)
-	(eval (list 'let (nreverse pars)
-		    (list 'org-tags-view nil cmd-key)))
-      (eval (list 'let (nreverse pars) (list 'org-agenda nil cmd-key))))
-    (set-buffer org-agenda-buffer-name)
-    (let* ((lines (org-split-string (buffer-string) "\n"))
-	   line)
-      (while (setq line (pop lines))
-	(catch 'next
-	  (if (not (get-text-property 0 'org-category line)) (throw 'next nil))
-	  (setq org-agenda-info
-		(org-fix-agenda-info (text-properties-at 0 line)))
-	  (princ
-	   (org-encode-for-stdout
-	    (mapconcat 'org-agenda-export-csv-mapper
-		       '(org-category txt type todo tags date time extra
-				      priority-letter priority agenda-day)
-		      ",")))
-	  (princ "\n"))))))
+	(org-tags-view nil cmd-key)
+      (org-agenda nil cmd-key)))
+  (set-buffer org-agenda-buffer-name)
+  (let* ((lines (org-split-string (buffer-string) "\n"))
+	 line)
+    (while (setq line (pop lines))
+      (catch 'next
+	(if (not (get-text-property 0 'org-category line)) (throw 'next nil))
+	(setq org-agenda-info
+	      (org-fix-agenda-info (text-properties-at 0 line)))
+	(princ
+	 (org-encode-for-stdout
+	  (mapconcat 'org-agenda-export-csv-mapper
+		     '(org-category txt type todo tags date time extra
+				    priority-letter priority agenda-day)
+		     ",")))
+	(princ "\n")))))
 
 (defun org-fix-agenda-info (props)
   "Make sure all properties on an agenda item have a canonical form.
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 7/7] Make org-batch-store-agenda-views a fun, use org-eval-in-environment
  2011-08-02  9:23 [PATCH 0/8] Org mode macros, refactored David Maus
                   ` (5 preceding siblings ...)
  2011-08-02  9:23 ` [PATCH 6/7] Use org-eval-in-environment, make macros functions David Maus
@ 2011-08-02  9:23 ` David Maus
  2011-08-02  9:34 ` [PATCH 0/8] Org mode macros, refactored David Maus
  2011-08-02 10:44 ` Štěpán Němec
  8 siblings, 0 replies; 18+ messages in thread
From: David Maus @ 2011-08-02  9:23 UTC (permalink / raw)
  To: emacs-orgmode; +Cc: David Maus

* org-agenda.el (org-batch-store-agenda-views): Make it a function,
use org-eval-in-environment.
---
 lisp/org-agenda.el |   20 +++++++++-----------
 1 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el
index 6079377..9215d2a 100644
--- a/lisp/org-agenda.el
+++ b/lisp/org-agenda.el
@@ -2697,17 +2697,14 @@ This ensures the export commands can easily use it."
   (interactive)
   (eval (list 'org-batch-store-agenda-views)))
 
-;; FIXME, why is this a macro?????
 ;;;###autoload
-(defmacro org-batch-store-agenda-views (&rest parameters)
+(defun org-batch-store-agenda-views (&rest parameters)
   "Run all custom agenda commands that have a file argument."
   (let ((cmds (org-agenda-normalize-custom-commands org-agenda-custom-commands))
 	(pop-up-frames nil)
 	(dir default-directory)
-	pars cmd thiscmdkey files opts cmd-or-set)
-    (while parameters
-      (push (list (pop parameters) (if parameters (pop parameters))) pars))
-    (setq pars (reverse pars))
+	(pars (org-make-parameter-alist parameters))
+	cmd thiscmdkey files opts cmd-or-set)
     (save-window-excursion
       (while cmds
 	(setq cmd (pop cmds)
@@ -2717,13 +2714,14 @@ This ensures the export commands can easily use it."
 	      files (nth (if (listp cmd-or-set) 4 5) cmd))
 	(if (stringp files) (setq files (list files)))
 	(when files
-	  (eval (list 'let (append org-agenda-exporter-settings opts pars)
-		      (list 'org-agenda nil thiscmdkey)))
+	  (org-eval-in-environment (append org-agenda-exporter-settings
+					   opts pars)
+	    (org-agenda nil thiscmdkey))
 	  (set-buffer org-agenda-buffer-name)
 	  (while files
-	    (eval (list 'let (append org-agenda-exporter-settings opts pars)
-			(list 'org-write-agenda
-			      (expand-file-name (pop files) dir) nil t))))
+	    (org-eval-in-environment (append org-agenda-exporter-settings
+					     opts pars)
+	      (org-write-agenda (expand-file-name (pop files) dir) nil t)))
 	  (and (get-buffer org-agenda-buffer-name)
 	       (kill-buffer org-agenda-buffer-name)))))))
 
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 0/8] Org mode macros, refactored
  2011-08-02  9:23 [PATCH 0/8] Org mode macros, refactored David Maus
                   ` (6 preceding siblings ...)
  2011-08-02  9:23 ` [PATCH 7/7] Make org-batch-store-agenda-views a fun, use org-eval-in-environment David Maus
@ 2011-08-02  9:34 ` David Maus
  2011-08-02 10:44 ` Štěpán Němec
  8 siblings, 0 replies; 18+ messages in thread
From: David Maus @ 2011-08-02  9:34 UTC (permalink / raw)
  To: David Maus; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 291 bytes --]

*sigh*

These patches should apply to current master but I somehow messed up
 my development tree. Two separate commits where squashed to 2/7 --
 will post a follow up this afternoon.

Best,
  -- David
--
OpenPGP... 0x99ADB83B5A4478E6
Jabber.... dmjena@jabber.org
Email..... dmaus@ictsoc.de

[-- Attachment #2: Type: application/pgp-signature, Size: 230 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 0/8] Org mode macros, refactored
  2011-08-02  9:23 [PATCH 0/8] Org mode macros, refactored David Maus
                   ` (7 preceding siblings ...)
  2011-08-02  9:34 ` [PATCH 0/8] Org mode macros, refactored David Maus
@ 2011-08-02 10:44 ` Štěpán Němec
  8 siblings, 0 replies; 18+ messages in thread
From: Štěpán Němec @ 2011-08-02 10:44 UTC (permalink / raw)
  To: David Maus; +Cc: emacs-orgmode

On Tue, 02 Aug 2011 11:23:33 +0200
David Maus wrote:

> Note: The usage of make-symbol works but has one drawback: The new
> uninterned symbols have the same name as the maybe interned symbols in
> BODY.

An oft-used workaround (also occuring in the Emacs core code) is to add
some line-noise (e.g. --symbol--) to the created symbol names so they
are at least visually distinguishable.

-- 
Štěpán

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2/7] New macro: Evaluate FORM in ENVIRONMENT
  2011-08-02  9:23 ` [PATCH 2/7] New macro: Evaluate FORM in ENVIRONMENT David Maus
@ 2011-08-02 10:50   ` Štěpán Němec
  2011-08-02 13:25     ` David Maus
  2011-08-02 13:49   ` David Maus
  1 sibling, 1 reply; 18+ messages in thread
From: Štěpán Němec @ 2011-08-02 10:50 UTC (permalink / raw)
  To: David Maus; +Cc: emacs-orgmode

On Tue, 02 Aug 2011 11:23:35 +0200
David Maus wrote:

> * org-macs.el (org-eval-in-environment): New macro. Evaluate
> FORM in ENVIRONMENT.
> (org-with-uninterned): Move to top of file.
> ---
>  lisp/org-macs.el |   23 ++++++++++++++++++-----
>  1 files changed, 18 insertions(+), 5 deletions(-)
>
> diff --git a/lisp/org-macs.el b/lisp/org-macs.el
> index 53c60e5..7a0cc60 100644
> --- a/lisp/org-macs.el
> +++ b/lisp/org-macs.el
> @@ -47,6 +47,12 @@
>  (declare-function org-add-props "org-compat" (string plist &rest props))
>  (declare-function org-string-match-p "org-compat" (&rest args))
>  
> +(defmacro org-with-uninterned (symbols &rest body)
> +  `(let ,(mapcar (lambda (s)
> +		   `(,s (make-symbol (symbol-name ',s)))) symbols)
> +     ,@body))
> +(put 'org-with-uninterned 'lisp-indent-function 1)
> +

So in the previous commit you added this macro, in the next commit you
move it to the top of the file? Why didn't you put it into the right
place to begin with?

[...]

> +(defun org-make-parameter-alist (flat)
> +  "Return alist based on FLAT.
> +FLAT is a list with alternating symbol names and values. The
> +returned alist is a list of lists with the symbol name in car and
> +the value in cdr."
> +  (when flat
> +    (cons (list (car flat) (cadr flat))
> +	  (org-make-parameter-alist (cddr flat)))))

This new function is not mentioned anywhere in the commit message.

-- 
Štěpán

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2/7] New macro: Evaluate FORM in ENVIRONMENT
  2011-08-02 10:50   ` Štěpán Němec
@ 2011-08-02 13:25     ` David Maus
  0 siblings, 0 replies; 18+ messages in thread
From: David Maus @ 2011-08-02 13:25 UTC (permalink / raw)
  To: Štěpán Němec; +Cc: David Maus, emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 1755 bytes --]

At Tue, 02 Aug 2011 12:50:05 +0200,
Štěpán Němec wrote:
> 
> On Tue, 02 Aug 2011 11:23:35 +0200
> David Maus wrote:
> 
> > * org-macs.el (org-eval-in-environment): New macro. Evaluate
> > FORM in ENVIRONMENT.
> > (org-with-uninterned): Move to top of file.
> > ---
> >  lisp/org-macs.el |   23 ++++++++++++++++++-----
> >  1 files changed, 18 insertions(+), 5 deletions(-)
> >
> > diff --git a/lisp/org-macs.el b/lisp/org-macs.el
> > index 53c60e5..7a0cc60 100644
> > --- a/lisp/org-macs.el
> > +++ b/lisp/org-macs.el
> > @@ -47,6 +47,12 @@
> >  (declare-function org-add-props "org-compat" (string plist &rest props))
> >  (declare-function org-string-match-p "org-compat" (&rest args))
> >  
> > +(defmacro org-with-uninterned (symbols &rest body)
> > +  `(let ,(mapcar (lambda (s)
> > +		   `(,s (make-symbol (symbol-name ',s)))) symbols)
> > +     ,@body))
> > +(put 'org-with-uninterned 'lisp-indent-function 1)
> > +
> 
> So in the previous commit you added this macro, in the next commit you
> move it to the top of the file? Why didn't you put it into the right
> place to begin with?
> 
> [...]
> 
> > +(defun org-make-parameter-alist (flat)
> > +  "Return alist based on FLAT.
> > +FLAT is a list with alternating symbol names and values. The
> > +returned alist is a list of lists with the symbol name in car and
> > +the value in cdr."
> > +  (when flat
> > +    (cons (list (car flat) (cadr flat))
> > +	  (org-make-parameter-alist (cddr flat)))))
> 
> This new function is not mentioned anywhere in the commit message.

Yepp. I messed up the branch, correction is on its way.

Best,
  -- David
-- 
OpenPGP... 0x99ADB83B5A4478E6
Jabber.... dmjena@jabber.org
Email..... dmaus@ictsoc.de

[-- Attachment #2: Type: application/pgp-signature, Size: 230 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/7] New macro: Execute BODY in enviroment with uninterned SYMBOLS
  2011-08-02  9:23 ` [PATCH 1/7] New macro: Execute BODY in enviroment with uninterned SYMBOLS David Maus
@ 2011-08-02 13:48   ` David Maus
       [not found]   ` <CAJcAo8uv46JCx9cG0x_ip9DMQ-aN=buLRO_fONPoFuDkik6J1Q@mail.gmail.com>
  1 sibling, 0 replies; 18+ messages in thread
From: David Maus @ 2011-08-02 13:48 UTC (permalink / raw)
  To: David Maus; +Cc: emacs-orgmode


[-- Attachment #1.1: Type: text/plain, Size: 50 bytes --]

Supersedes 1/7: Define macro at top of the file.


[-- Attachment #1.2: 0001-New-macro-Execute-BODY-in-enviroment-with-uninterned.patch --]
[-- Type: text/plain, Size: 1019 bytes --]

From 3a97836940b18ea2f50d53218e51fa81d617e788 Mon Sep 17 00:00:00 2001
From: David Maus <dmaus@ictsoc.de>
Date: Tue, 2 Aug 2011 15:39:49 +0200
Subject: [PATCH] New macro: Execute BODY in enviroment with uninterned SYMBOLS

* org-macs.el (org-with-uninterned): New macro. Execute BODY in
enviroment with uninterned SYMBOLS.
---
 lisp/org-macs.el |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/lisp/org-macs.el b/lisp/org-macs.el
index 906be61..1d31744 100644
--- a/lisp/org-macs.el
+++ b/lisp/org-macs.el
@@ -47,6 +47,12 @@
 (declare-function org-add-props "org-compat" (string plist &rest props))
 (declare-function org-string-match-p "org-compat" (&rest args))
 
+(defmacro org-with-uninterned (symbols &rest body)
+  `(let ,(mapcar (lambda (s)
+		   `(,s (make-symbol (symbol-name ',s)))) symbols)
+     ,@body))
+(put 'org-with-uninterned 'lisp-indent-function 1)
+
 (defmacro org-called-interactively-p (&optional kind)
   (if (featurep 'xemacs)
        `(interactive-p)
-- 
1.7.2.5


[-- Attachment #2: Type: application/pgp-signature, Size: 230 bytes --]

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 2/7] New macro: Evaluate FORM in ENVIRONMENT
  2011-08-02  9:23 ` [PATCH 2/7] New macro: Evaluate FORM in ENVIRONMENT David Maus
  2011-08-02 10:50   ` Štěpán Němec
@ 2011-08-02 13:49   ` David Maus
  1 sibling, 0 replies; 18+ messages in thread
From: David Maus @ 2011-08-02 13:49 UTC (permalink / raw)
  To: David Maus; +Cc: emacs-orgmode


[-- Attachment #1.1: Type: text/plain, Size: 47 bytes --]

Fix smashed up commits: these two replace 2/7


[-- Attachment #1.2: 0001-New-macro-Evaluate-FORM-in-ENVIRONMENT.patch --]
[-- Type: text/plain, Size: 919 bytes --]

From d55980b50dea594912b38bd7d9b96989c6a54129 Mon Sep 17 00:00:00 2001
From: David Maus <dmaus@ictsoc.de>
Date: Tue, 2 Aug 2011 15:41:36 +0200
Subject: [PATCH] New macro: Evaluate FORM in ENVIRONMENT

* org-macs.el (org-eval-in-environment): New macro. Evaluate FORM in
ENVIRONMENT.
---
 lisp/org-macs.el |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/lisp/org-macs.el b/lisp/org-macs.el
index 1d31744..4062f07 100644
--- a/lisp/org-macs.el
+++ b/lisp/org-macs.el
@@ -376,6 +376,10 @@ The number of levels is controlled by `org-inlinetask-min-level'"
       (format-seconds string seconds)
     (format-time-string string (seconds-to-time seconds))))
 
+(defmacro org-eval-in-environment (environment form)
+  `(eval '(let ,environment ,form)))
+(put 'org-eval-in-environment 'lisp-indent-function 1)
+
 (provide 'org-macs)
 
 ;; arch-tag: 7e6a73ce-aac9-4fc0-9b30-ce6f89dc6668
-- 
1.7.2.5


[-- Attachment #1.3: 0001-New-function-Return-alist-of-parameters-based-on-fla.patch --]
[-- Type: text/plain, Size: 1213 bytes --]

From 04a3f7c9c69faa59f1d9c6343dbb22b3faad3d52 Mon Sep 17 00:00:00 2001
From: David Maus <dmaus@ictsoc.de>
Date: Tue, 2 Aug 2011 15:43:15 +0200
Subject: [PATCH] New function: Return alist of parameters based on flat list

* org-macs.el (org-make-parameter-alist): New function. Return alist
of parameters based on flat list.
---
 lisp/org-macs.el |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/lisp/org-macs.el b/lisp/org-macs.el
index 4062f07..7a0cc60 100644
--- a/lisp/org-macs.el
+++ b/lisp/org-macs.el
@@ -376,6 +376,15 @@ The number of levels is controlled by `org-inlinetask-min-level'"
       (format-seconds string seconds)
     (format-time-string string (seconds-to-time seconds))))
 
+(defun org-make-parameter-alist (flat)
+  "Return alist based on FLAT.
+FLAT is a list with alternating symbol names and values. The
+returned alist is a list of lists with the symbol name in car and
+the value in cdr."
+  (when flat
+    (cons (list (car flat) (cadr flat))
+	  (org-make-parameter-alist (cddr flat)))))
+
 (defmacro org-eval-in-environment (environment form)
   `(eval '(let ,environment ,form)))
 (put 'org-eval-in-environment 'lisp-indent-function 1)
-- 
1.7.2.5


[-- Attachment #2: Type: application/pgp-signature, Size: 230 bytes --]

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/7] New macro: Execute BODY in enviroment with uninterned SYMBOLS
       [not found]   ` <CAJcAo8uv46JCx9cG0x_ip9DMQ-aN=buLRO_fONPoFuDkik6J1Q@mail.gmail.com>
@ 2011-08-10  7:43     ` David Maus
  2011-08-16 16:34       ` Bastien
  0 siblings, 1 reply; 18+ messages in thread
From: David Maus @ 2011-08-10  7:43 UTC (permalink / raw)
  To: Samuel Wales, Štěpán Němec, emacs-orgmode; +Cc: David Maus

[-- Attachment #1: Type: text/plain, Size: 384 bytes --]

Hi Samuel,
Hi Štěpán,

Thanks for the feedback on org-with-uninterned. I'm preparing the
patches for master and decided to use the 'add-noise' approach
suggested by Štěpán but renamed the macro to `org-with-gensyms'. Thus
we can change the implementation.

Best,
  -- David
-- 
OpenPGP... 0x99ADB83B5A4478E6
Jabber.... dmjena@jabber.org
Email..... dmaus@ictsoc.de

[-- Attachment #2: Type: application/pgp-signature, Size: 230 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/7] New macro: Execute BODY in enviroment with uninterned SYMBOLS
  2011-08-10  7:43     ` David Maus
@ 2011-08-16 16:34       ` Bastien
  2011-08-16 17:08         ` David Maus
  0 siblings, 1 reply; 18+ messages in thread
From: Bastien @ 2011-08-16 16:34 UTC (permalink / raw)
  To: David Maus; +Cc: emacs-orgmode, Štěpán Němec

Hi David,

David Maus <dmaus@ictsoc.de> writes:

> Thanks for the feedback on org-with-uninterned. I'm preparing the
> patches for master and decided to use the 'add-noise' approach
> suggested by Štěpán but renamed the macro to `org-with-gensyms'. Thus
> we can change the implementation.

I see you have applied the serie of patches -- thanks a bunch for that!

Let me know if there is code in this area I need to double-check or to
learn from.

Best,

-- 
 Bastien

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/7] New macro: Execute BODY in enviroment with uninterned SYMBOLS
  2011-08-16 16:34       ` Bastien
@ 2011-08-16 17:08         ` David Maus
  2011-08-16 17:30           ` Bastien
  0 siblings, 1 reply; 18+ messages in thread
From: David Maus @ 2011-08-16 17:08 UTC (permalink / raw)
  To: Bastien; +Cc: David Maus, emacs-orgmode, Štěpán Němec

[-- Attachment #1: Type: text/plain, Size: 901 bytes --]

At Tue, 16 Aug 2011 18:34:04 +0200,
Bastien wrote:
> 
> Hi David,
> 
> David Maus <dmaus@ictsoc.de> writes:
> 
> > Thanks for the feedback on org-with-uninterned. I'm preparing the
> > patches for master and decided to use the 'add-noise' approach
> > suggested by Štěpán but renamed the macro to `org-with-gensyms'. Thus
> > we can change the implementation.
> 
> I see you have applied the serie of patches -- thanks a bunch for that!
> 
> Let me know if there is code in this area I need to double-check or to
> learn from.

Well: Defining edebug specifications for macros is something really
useful for debugging those buggers. Maybe this could be something like
an informal policy: No macro without edebug spec, especially if the
macro wraps around a body.

Best,
  -- David
-- 
OpenPGP... 0x99ADB83B5A4478E6
Jabber.... dmjena@jabber.org
Email..... dmaus@ictsoc.de

[-- Attachment #2: Type: application/pgp-signature, Size: 230 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/7] New macro: Execute BODY in enviroment with uninterned SYMBOLS
  2011-08-16 17:08         ` David Maus
@ 2011-08-16 17:30           ` Bastien
  0 siblings, 0 replies; 18+ messages in thread
From: Bastien @ 2011-08-16 17:30 UTC (permalink / raw)
  To: David Maus; +Cc: emacs-orgmode, Štěpán Němec

David Maus <dmaus@ictsoc.de> writes:

> Well: Defining edebug specifications for macros is something really
> useful for debugging those buggers. Maybe this could be something like
> an informal policy: No macro without edebug spec, especially if the
> macro wraps around a body.

Agreed.  Let's try to stick to this policy.

-- 
 Bastien

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2011-08-16 17:30 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-02  9:23 [PATCH 0/8] Org mode macros, refactored David Maus
2011-08-02  9:23 ` [PATCH 1/7] New macro: Execute BODY in enviroment with uninterned SYMBOLS David Maus
2011-08-02 13:48   ` David Maus
     [not found]   ` <CAJcAo8uv46JCx9cG0x_ip9DMQ-aN=buLRO_fONPoFuDkik6J1Q@mail.gmail.com>
2011-08-10  7:43     ` David Maus
2011-08-16 16:34       ` Bastien
2011-08-16 17:08         ` David Maus
2011-08-16 17:30           ` Bastien
2011-08-02  9:23 ` [PATCH 2/7] New macro: Evaluate FORM in ENVIRONMENT David Maus
2011-08-02 10:50   ` Štěpán Němec
2011-08-02 13:25     ` David Maus
2011-08-02 13:49   ` David Maus
2011-08-02  9:23 ` [PATCH 3/7] Use new macro org-with-uninterned David Maus
2011-08-02  9:23 ` [PATCH 4/7] New function: Substitute posix classes in regular expression David Maus
2011-08-02  9:23 ` [PATCH 5/7] Use macro org-with-uninterned David Maus
2011-08-02  9:23 ` [PATCH 6/7] Use org-eval-in-environment, make macros functions David Maus
2011-08-02  9:23 ` [PATCH 7/7] Make org-batch-store-agenda-views a fun, use org-eval-in-environment David Maus
2011-08-02  9:34 ` [PATCH 0/8] Org mode macros, refactored David Maus
2011-08-02 10:44 ` Štěpán Němec

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).