emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* asynchronous exporter and babel confirmation
@ 2013-03-06  9:30 Alan Schmitt
  2013-03-06 10:10 ` Nicolas Goaziou
  0 siblings, 1 reply; 13+ messages in thread
From: Alan Schmitt @ 2013-03-06  9:30 UTC (permalink / raw)
  To: Org-mode List

Hello,

Is the asynchronous exporter supposed to work when a request to evaluate
a code block needs to be answered? I was wondering why the exporter was
getting stuck, and found a buffer where the question was asked but I had
no way to answer it.

Thanks,

Alan

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

* Re: asynchronous exporter and babel confirmation
  2013-03-06  9:30 asynchronous exporter and babel confirmation Alan Schmitt
@ 2013-03-06 10:10 ` Nicolas Goaziou
  2013-03-06 12:34   ` Achim Gratz
  0 siblings, 1 reply; 13+ messages in thread
From: Nicolas Goaziou @ 2013-03-06 10:10 UTC (permalink / raw)
  To: Alan Schmitt; +Cc: Org-mode List, Eric Schulte

Hello,

Alan Schmitt <alan.schmitt@polytechnique.org> writes:

> Is the asynchronous exporter supposed to work when a request to evaluate
> a code block needs to be answered?

Well, no, but its somewhat difficult to prevent it. Besides security
considerations, even if we set `org-confirm-babel-evaluate' to nil
during an asynchronous export, this won't handle the case of the user
explicitly uses a :query keyword in a source block header.

A very ugly hack would be to use:

 (defalias 'yes-or-no-p 'ignore)


Eric, what do you think?


Regards,

-- 
Nicolas Goaziou

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

* Re: asynchronous exporter and babel confirmation
  2013-03-06 10:10 ` Nicolas Goaziou
@ 2013-03-06 12:34   ` Achim Gratz
  2013-03-06 12:52     ` Nicolas Goaziou
  2013-03-06 13:04     ` Alan Schmitt
  0 siblings, 2 replies; 13+ messages in thread
From: Achim Gratz @ 2013-03-06 12:34 UTC (permalink / raw)
  To: emacs-orgmode

Nicolas Goaziou <n.goaziou <at> gmail.com> writes:
> Well, no, but its somewhat difficult to prevent it. Besides security
> considerations, even if we set `org-confirm-babel-evaluate' to nil
> during an asynchronous export, this won't handle the case of the user
> explicitly uses a :query keyword in a source block header.

Right.

> A very ugly hack would be to use:
> 
>  (defalias 'yes-or-no-p 'ignore)

Ugh.  I hope this won't be necessary.

I've recently refactored the evaluation check so it determines first whether the
code-block should be run and only in the affirmative checks if it should query
the user.  So it should be much easier now to have another dynamic binding for
preventing the question _and_ not run the block (as if the user had answered
"no", which is the only sensible choice when skipping the query).  It already
skips the query when the cached result is not stale (since it doesn't actually
run any code in this case).  


Regards,
Achim.

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

* Re: asynchronous exporter and babel confirmation
  2013-03-06 12:34   ` Achim Gratz
@ 2013-03-06 12:52     ` Nicolas Goaziou
  2013-03-06 19:47       ` Achim Gratz
  2013-03-06 13:04     ` Alan Schmitt
  1 sibling, 1 reply; 13+ messages in thread
From: Nicolas Goaziou @ 2013-03-06 12:52 UTC (permalink / raw)
  To: Achim Gratz; +Cc: emacs-orgmode

Hello,

Achim Gratz <Stromeko@NexGo.DE> writes:

>> A very ugly hack would be to use:
>> 
>>  (defalias 'yes-or-no-p 'ignore)
>
> Ugh.  I hope this won't be necessary.

I hope too.

> I've recently refactored the evaluation check so it determines first whether the
> code-block should be run and only in the affirmative checks if it should query
> the user.  So it should be much easier now to have another dynamic binding for
> preventing the question _and_ not run the block (as if the user had answered
> "no", which is the only sensible choice when skipping the query).  It already
> skips the query when the cached result is not stale (since it doesn't actually
> run any code in this case).

From the export framework POV, this variable should be set to an
appropriate value (i.e. so no question is asked) from
`org-export-async-start'.

I can take care of it once the new variable is defined (maybe in
ob-exp.el?).


Regards,

-- 
Nicolas Goaziou

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

* Re: asynchronous exporter and babel confirmation
  2013-03-06 12:34   ` Achim Gratz
  2013-03-06 12:52     ` Nicolas Goaziou
@ 2013-03-06 13:04     ` Alan Schmitt
  1 sibling, 0 replies; 13+ messages in thread
From: Alan Schmitt @ 2013-03-06 13:04 UTC (permalink / raw)
  To: Achim Gratz; +Cc: emacs-orgmode

Achim Gratz writes:

> I've recently refactored the evaluation check so it determines first whether the
> code-block should be run and only in the affirmative checks if it should query
> the user.  So it should be much easier now to have another dynamic binding for
> preventing the question _and_ not run the block (as if the user had answered
> "no", which is the only sensible choice when skipping the query).  It already
> skips the query when the cached result is not stale (since it doesn't actually
> run any code in this case).  

This sounds reasonable.

Thanks,

Alan

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

* Re: asynchronous exporter and babel confirmation
  2013-03-06 12:52     ` Nicolas Goaziou
@ 2013-03-06 19:47       ` Achim Gratz
  2013-03-06 20:25         ` Nicolas Goaziou
  0 siblings, 1 reply; 13+ messages in thread
From: Achim Gratz @ 2013-03-06 19:47 UTC (permalink / raw)
  To: emacs-orgmode

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

Hi Nicolas,

I'm still waiting for feedback from Karl Voit over in the other thread,
but here's the amended patch for you to review:


[-- Attachment #2: 0001-ob-core-do-not-ask-for-confirmation-if-cached-result.patch --]
[-- Type: text/x-patch, Size: 12131 bytes --]

From c49b4ab5afda4d223cbcf97cb8c7ac0f9cc8e39b Mon Sep 17 00:00:00 2001
From: Achim Gratz <Stromeko@Stromeko.DE>
Date: Wed, 27 Feb 2013 22:55:26 +0100
Subject: [PATCH] ob-core: do not ask for confirmation if cached result is
 current
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* lisp/ob-core.el (org-babel-confirm-evaluate): Refactor this internal
  function.
* lisp/ob-core.el (org-babel--suppress-confirm-evaluate-answer-no):
  Dynamically scoped variable, if bound non-nil the confirmation
  dialog will not be initiated and it is assumed the user answered
  with "no".
* lisp/ob-core.el (org-babel--check-confirm-evaluate): New macro to
  ensure that the initial let-bindings for `org-babel--check-evaluate´
  and `org-babel--confirm-evaluate´ are consistent.
* lisp/ob-core.el (org-babel--check-evaluate): First part of
  `org-babel-confirm-evaluate´, check whether this source block
  evaluation is enabled.
* lisp/ob-core.el (org-babel--confirm-evaluate): Second part of
  `org-babel-confirm-evaluate´, let the user confirm evaluation.
* lisp/ob-core.el (org-babel-execute-src-block): Do not ask for
  confirmation if the cached result is current.

  The call to `org-babel--check-evaluate´ will indicate if the block
  should be evaluated.  If yes, determine whether the cached result
  block is current (since `org-babel-process-params´ might trigger
  expensive operations this has to be deferred).  If `cache-current-p´
  is t, evaluate the source block without asking.  In case the cache
  is current the evaluation will not actually do anything but return
  the cached value, so this is safe.  Otherwise ask permission from
  the user by calling `org-babel--confirm-evaluate´ and act depending
  on the answer.

  The new variable `org-babel--suppress-confirm-evaluate-answer-no´
  can be bound to suppress the user interaction as is needed for async
  export, as discussed in
  http://thread.gmane.org/gmane.emacs.orgmode/67719
---
 lisp/ob-core.el | 207 ++++++++++++++++++++++++++++++--------------------------
 1 file changed, 110 insertions(+), 97 deletions(-)

diff --git a/lisp/ob-core.el b/lisp/ob-core.el
index 3b7c463..af245ed 100644
--- a/lisp/ob-core.el
+++ b/lisp/ob-core.el
@@ -1,4 +1,4 @@
-;;; ob-core.el --- working with code blocks in org-mode
+;; ob-core.el --- working with code blocks in org-mode
 
 ;; Copyright (C) 2009-2012  Free Software Foundation, Inc.
 
@@ -284,7 +284,27 @@ (defun org-babel-get-src-block-info (&optional light)
     (when info (append info (list name indent)))))
 
 (defvar org-current-export-file) ; dynamically bound
-(defun org-babel-confirm-evaluate (info)
+(defmacro org-babel--check-confirm-evaluate (info &rest body)
+  "Pull some information from code block INFO and evaluate BODY.
+"
+  (declare (indent defun))
+  `(let* ((eval (or (cdr (assoc :eval (nth 2 ,info)))
+		   (when (assoc :noeval (nth 2 ,info)) "no")))
+	 (code-block (if info (format " %s " (nth 0 ,info)) " "))
+	 (block-name (if (nth 4 ,info) (format " (%s) " (nth 4 ,info)) " ")))
+     ,@body))
+(defun org-babel--check-evaluate (info)
+  "Check whether the code block INFO should be evaluated.
+"
+  (org-babel--check-confirm-evaluate info
+    (if (or (equal eval "never") (equal eval "no")
+	    (and (boundp 'org-current-export-file) org-current-export-file
+		 (or (equal eval "no-export") (equal eval "never-export"))))
+	(prog1 nil (message (format "Evaluation of this%scode block%sis disabled."
+				    code-block block-name)))
+      t)))
+(defvar org-babel--suppress-confirm-evaluate-answer-no) ;; dynamically scoped
+(defun org-babel--confirm-evaluate (info)
   "Confirm evaluation of the code block INFO.
 This behavior can be suppressed by setting the value of
 `org-confirm-babel-evaluate' to nil, in which case all future
@@ -293,33 +313,23 @@ (defun org-babel-confirm-evaluate (info)
 
 Note disabling confirmation may result in accidental evaluation
 of potentially harmful code."
-  (let* ((eval (or (cdr (assoc :eval (nth 2 info)))
-		   (when (assoc :noeval (nth 2 info)) "no")))
-         (query (cond ((equal eval "query") t)
-		      ((and (boundp 'org-current-export-file)
-			    org-current-export-file
-			    (equal eval "query-export")) t)
-                      ((functionp org-confirm-babel-evaluate)
-                       (funcall org-confirm-babel-evaluate
-                                (nth 0 info) (nth 1 info)))
-                      (t org-confirm-babel-evaluate))))
-    (if (or (equal eval "never") (equal eval "no")
-	    (and (boundp 'org-current-export-file)
-		 org-current-export-file
-		 (or (equal eval "no-export")
-		     (equal eval "never-export")))
-	    (and query
-		 (not (yes-or-no-p
-		       (format "Evaluate this%scode block%son your system? "
-			       (if info (format " %s " (nth 0 info)) " ")
-			       (if (nth 4 info)
-				   (format " (%s) " (nth 4 info)) " "))))))
-	(prog1 nil (message "Evaluation %s"
-			    (if (or (equal eval "never") (equal eval "no")
-				    (equal eval "no-export")
-				    (equal eval "never-export"))
-				"Disabled" "Aborted")))
-      t)))
+  (org-babel--check-confirm-evaluate info
+    (let* ((query (cond ((equal eval "query") t)
+			((and (boundp 'org-current-export-file) org-current-export-file
+			      (equal eval "query-export")) t)
+			((functionp org-confirm-babel-evaluate)
+			 (funcall org-confirm-babel-evaluate
+				  (nth 0 info) (nth 1 info)))
+			(t org-confirm-babel-evaluate))))
+      (if (and query
+	       (or (null org-babel--suppress-confirm-evaluate-answer-no)
+		   (not (yes-or-no-p
+			 (format "Evaluate this%scode block%son your system? "
+				 code-block block-name)))))
+	  (prog1 nil (message
+		      (format "Evaluation of%scode-block%snot confirmed."
+			      code-block block-name)))
+	t))))
 
 ;;;###autoload
 (defun org-babel-execute-safely-maybe ()
@@ -525,80 +535,83 @@ (defun org-babel-execute-src-block (&optional arg info params)
   (interactive)
   (let* ((info (or info (org-babel-get-src-block-info)))
 	 (merged-params (org-babel-merge-params (nth 2 info) params)))
-    (when (org-babel-confirm-evaluate
+    (when (org-babel--check-evaluate
 	   (let ((i info)) (setf (nth 2 i) merged-params) i))
-      (let* ((lang (nth 0 info))
-	     (params (if params
+      (let* ((params (if params
 			 (org-babel-process-params merged-params)
 		       (nth 2 info)))
 	     (cache-p (and (not arg) (cdr (assoc :cache params))
-			  (string= "yes" (cdr (assoc :cache params)))))
-	     (result-params (cdr (assoc :result-params params)))
+			   (string= "yes" (cdr (assoc :cache params)))))
 	     (new-hash (when cache-p (org-babel-sha1-hash info)))
 	     (old-hash (when cache-p (org-babel-current-result-hash)))
-	     (cache-current-p (and (not arg) new-hash (equal new-hash old-hash)))
-	     (body (setf (nth 1 info)
-			 (if (org-babel-noweb-p params :eval)
-			     (org-babel-expand-noweb-references info)
-			   (nth 1 info))))
-	     (dir (cdr (assoc :dir params)))
-	     (default-directory
-	       (or (and dir (file-name-as-directory (expand-file-name dir)))
-		   default-directory))
-	     (org-babel-call-process-region-original
-	      (if (boundp 'org-babel-call-process-region-original)
-		  org-babel-call-process-region-original
-		(symbol-function 'call-process-region)))
-	     (indent (car (last info)))
-	     result cmd)
-	(unwind-protect
-	    (let ((call-process-region
-		   (lambda (&rest args)
-		     (apply 'org-babel-tramp-handle-call-process-region args))))
-	      (let ((lang-check (lambda (f)
-				  (let ((f (intern (concat "org-babel-execute:" f))))
-				    (when (fboundp f) f)))))
-		(setq cmd
-		      (or (funcall lang-check lang)
-			  (funcall lang-check (symbol-name
-					       (cdr (assoc lang org-src-lang-modes))))
-			  (error "No org-babel-execute function for %s!" lang))))
-	      (if cache-current-p
-		  (save-excursion ;; return cached result
-		    (goto-char (org-babel-where-is-src-block-result nil info))
-		    (end-of-line 1) (forward-char 1)
-		    (setq result (org-babel-read-result))
-		    (message (replace-regexp-in-string
-			      "%" "%%" (format "%S" result))) result)
-		(message "executing %s code block%s..."
-			 (capitalize lang)
-			 (if (nth 4 info) (format " (%s)" (nth 4 info)) ""))
-		(if (member "none" result-params)
-		    (progn
-		      (funcall cmd body params)
-		      (message "result silenced"))
-		(setq result
-		      ((lambda (result)
-			 (if (and (eq (cdr (assoc :result-type params)) 'value)
-				  (or (member "vector" result-params)
-				      (member "table" result-params))
-				  (not (listp result)))
-			     (list (list result)) result))
-		       (funcall cmd body params)))
-		;; if non-empty result and :file then write to :file
-		(when (cdr (assoc :file params))
-		  (when result
-		    (with-temp-file (cdr (assoc :file params))
-		      (insert
-		       (org-babel-format-result
-			result (cdr (assoc :sep (nth 2 info)))))))
-		  (setq result (cdr (assoc :file params))))
-		(org-babel-insert-result
-		 result result-params info new-hash indent lang)
-		(run-hooks 'org-babel-after-execute-hook)
-		result
-		)))
-	  (setq call-process-region 'org-babel-call-process-region-original))))))
+	     (cache-current-p (and (not arg) new-hash (equal new-hash old-hash))))
+	(when (or cache-current-p
+		  (org-babel--confirm-evaluate
+		   (let ((i info)) (setf (nth 2 i) merged-params) i)))
+	  (let* ((lang (nth 0 info))
+		 (result-params (cdr (assoc :result-params params)))
+		 (body (setf (nth 1 info)
+			     (if (org-babel-noweb-p params :eval)
+				 (org-babel-expand-noweb-references info)
+			       (nth 1 info))))
+		 (dir (cdr (assoc :dir params)))
+		 (default-directory
+		   (or (and dir (file-name-as-directory (expand-file-name dir)))
+		       default-directory))
+		 (org-babel-call-process-region-original
+		  (if (boundp 'org-babel-call-process-region-original)
+		      org-babel-call-process-region-original
+		    (symbol-function 'call-process-region)))
+		 (indent (car (last info)))
+		 result cmd)
+	    (unwind-protect
+		(let ((call-process-region
+		       (lambda (&rest args)
+			 (apply 'org-babel-tramp-handle-call-process-region args))))
+		  (let ((lang-check (lambda (f)
+				      (let ((f (intern (concat "org-babel-execute:" f))))
+					(when (fboundp f) f)))))
+		    (setq cmd
+			  (or (funcall lang-check lang)
+			      (funcall lang-check (symbol-name
+						   (cdr (assoc lang org-src-lang-modes))))
+			      (error "No org-babel-execute function for %s!" lang))))
+		  (if cache-current-p
+		      (save-excursion ;; return cached result
+			(goto-char (org-babel-where-is-src-block-result nil info))
+			(end-of-line 1) (forward-char 1)
+			(setq result (org-babel-read-result))
+			(message (replace-regexp-in-string
+				  "%" "%%" (format "%S" result))) result)
+		    (message "executing %s code block%s..."
+			     (capitalize lang)
+			     (if (nth 4 info) (format " (%s)" (nth 4 info)) ""))
+		    (if (member "none" result-params)
+			(progn
+			  (funcall cmd body params)
+			  (message "result silenced"))
+		      (setq result
+			    ((lambda (result)
+			       (if (and (eq (cdr (assoc :result-type params)) 'value)
+					(or (member "vector" result-params)
+					    (member "table" result-params))
+					(not (listp result)))
+				   (list (list result)) result))
+			     (funcall cmd body params)))
+		      ;; if non-empty result and :file then write to :file
+		      (when (cdr (assoc :file params))
+			(when result
+			  (with-temp-file (cdr (assoc :file params))
+			    (insert
+			     (org-babel-format-result
+			      result (cdr (assoc :sep (nth 2 info)))))))
+			(setq result (cdr (assoc :file params))))
+		      (org-babel-insert-result
+		       result result-params info new-hash indent lang)
+		      (run-hooks 'org-babel-after-execute-hook)
+		      result
+		      )))
+	      (setq call-process-region 'org-babel-call-process-region-original))))))))
 
 (defun org-babel-expand-body:generic (body params &optional var-lines)
   "Expand BODY with PARAMS.
-- 
1.8.1.4


[-- Attachment #3: Type: text/plain, Size: 201 bytes --]



Regards,
Achim.
-- 
+<[Q+ Matrix-12 WAVE#46+305 Neuron microQkb Andromeda XTk Blofeld]>+

Waldorf MIDI Implementation & additional documentation:
http://Synth.Stromeko.net/Downloads.html#WaldorfDocs

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

* Re: asynchronous exporter and babel confirmation
  2013-03-06 19:47       ` Achim Gratz
@ 2013-03-06 20:25         ` Nicolas Goaziou
  2013-03-06 22:17           ` Achim Gratz
  0 siblings, 1 reply; 13+ messages in thread
From: Nicolas Goaziou @ 2013-03-06 20:25 UTC (permalink / raw)
  To: Achim Gratz; +Cc: emacs-orgmode

Achim Gratz <Stromeko@nexgo.de> writes:

> I'm still waiting for feedback from Karl Voit over in the other thread,
> but here's the amended patch for you to review:

Thanks. I haven't much to say wrt to the internals since the only thing
needed to make use of this patch is to set
`org-babel--suppress-confirm-evaluate-answer-no' to t from
`org-export-async-start'. I would suggest a shorter variable name,
though, as: °org-babel--no-confirm-force-no'. But that doesn't really
matter.

I'll just focus on cosmetics.

> * lisp/ob-core.el (org-babel-confirm-evaluate): Refactor this internal
>   function.

You should mention explicitly that you removed this function. This is
not a refactoring.

> -;;; ob-core.el --- working with code blocks in org-mode
> +;; ob-core.el --- working with code blocks in org-mode

You should leave 3 semicolons. This is standard elisp library starter.

> +(defmacro org-babel--check-confirm-evaluate (info &rest body)
> +  "Pull some information from code block INFO and evaluate BODY.
> +"

Spurious blank line.

> +(defun org-babel--check-evaluate (info)
> +  "Check whether the code block INFO should be evaluated.
> +"

Ditto.

> +  (org-babel--check-confirm-evaluate info
> +    (if (or (equal eval "never") (equal eval "no")
> +	    (and (boundp 'org-current-export-file) org-current-export-file
> +		 (or (equal eval "no-export") (equal eval "never-export"))))
> +	(prog1 nil (message (format "Evaluation of this%scode block%sis disabled."
> +				    code-block block-name)))
> +      t)))

I would refactor it like the following:

  (org-babel--check-confirm-evaluate info
    (or (equal eval "never") (equal eval "no")
        (and (org-bound-and-true-p org-current-export-file)
             (or (equal eval "no-export") (equal eval "never-export")))
        (prog1 nil (message (format "Evaluation of this%scode block%sis disabled."
                                    code-block block-name)))))

> +  (org-babel--check-confirm-evaluate info
> +    (let* ((query (cond ((equal eval "query") t)
> +			((and (boundp 'org-current-export-file) org-current-export-file

  (org-bound-and-true-p org-current-export-file)

> +      (if (and query
> +	       (or (null org-babel--suppress-confirm-evaluate-answer-no)
> +		   (not (yes-or-no-p
> +			 (format "Evaluate this%scode block%son your system? "
> +				 code-block block-name)))))
> +	  (prog1 nil (message
> +		      (format "Evaluation of%scode-block%snot confirmed."
> +			      code-block block-name)))
> +	t))))

  (and query
       (or (not org-babel--suppress-confirm-evaluate-answer-no)
           (not (yes-or-no-p (format "Evaluate this%scode block%son your system? "
                                     code-block block-name)))
           (prog1 nil (message (format "Evaluation of%scode-block%snot confirmed."
                                       code-block block-name)))))

> +		  (if (boundp 'org-babel-call-process-region-original)
> +		      org-babel-call-process-region-original
> +		    (symbol-function 'call-process-region)))

  (or (org-bound-and-true-p org-babel-call-process-region-original)
      (symbol-function 'call-process-region))


[...]

> +		      (org-babel-insert-result
> +		       result result-params info new-hash indent lang)
> +		      (run-hooks 'org-babel-after-execute-hook)
> +		      result
> +		      )))

Dangling parens.


Regards,

-- 
Nicolas Goaziou

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

* Re: asynchronous exporter and babel confirmation
  2013-03-06 20:25         ` Nicolas Goaziou
@ 2013-03-06 22:17           ` Achim Gratz
  2013-03-06 22:38             ` Nicolas Goaziou
  0 siblings, 1 reply; 13+ messages in thread
From: Achim Gratz @ 2013-03-06 22:17 UTC (permalink / raw)
  To: emacs-orgmode

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

Nicolas Goaziou writes:
> `org-babel--suppress-confirm-evaluate-answer-no' to t from
> `org-export-async-start'. I would suggest a shorter variable name,

I've dropped the "suppress-" as it is redundant, but kept the
"confirm-evaluate".

>> -;;; ob-core.el --- working with code blocks in org-mode
>> +;; ob-core.el --- working with code blocks in org-mode
>
> You should leave 3 semicolons. This is standard elisp library starter.

That was an accident.

> I would refactor it like the following:
>
>   (org-babel--check-confirm-evaluate info
>     (or (equal eval "never") (equal eval "no")
>         (and (org-bound-and-true-p org-current-export-file)
>              (or (equal eval "no-export") (equal eval "never-export")))
>         (prog1 nil (message (format "Evaluation of this%scode block%sis disabled."
>                                     code-block block-name)))))

I wouldn't, it reverses the logic of that function.  Most of the code
was copied from the original function and I had originally intended to
adhere closely to that so Eric has an easier time to tell whether this
is good or not.  Anyway, I've had a go at this, not sure if it is much
better than the original.  The logic in these functions is a bit
convoluted, after all.


[-- Attachment #2: 0001-ob-core-do-not-ask-for-confirmation-if-cached-result.patch --]
[-- Type: text/x-patch, Size: 12317 bytes --]

From 85ab6e8a2c81aad038b55350d6996035aaca3763 Mon Sep 17 00:00:00 2001
From: Achim Gratz <Stromeko@Stromeko.DE>
Date: Wed, 27 Feb 2013 22:55:26 +0100
Subject: [PATCH] ob-core: do not ask for confirmation if cached result is
 current
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* lisp/ob-core.el (org-babel-confirm-evaluate): Remove this internal
  function and replace with `org-babel--check-evaluate´ and
  `org-babel--confirm-evaluate´.
* lisp/ob-core.el (org-babel--check-confirm-evaluate): New macro to
  ensure that the initial let-bindings for `org-babel--check-evaluate´
  and `org-babel--confirm-evaluate´ are consistent.
* lisp/ob-core.el (org-babel--check-evaluate): First part of the
  original `org-babel-confirm-evaluate´, check whether this source
  block evaluation is enabled.
* lisp/ob-core.el (org-babel--confirm-evaluate-answer-no): Dynamically
  scoped variable, if bound non-nil the confirmation dialog will not
  be initiated denial of evaluation is assumed.
* lisp/ob-core.el (org-babel--confirm-evaluate): Second part of the
  original `org-babel-confirm-evaluate´, check if the user needs to be
  queried. If not, affirm evaluation, else check if evaluation should
  be auto-denied and lastly ask the user.
* lisp/ob-core.el (org-babel-execute-src-block): Do not ask for
  confirmation if the cached result is current.

  The call to `org-babel--check-evaluate´ will indicate if the block
  should be evaluated.  If yes, determine whether the cached result
  block is current (since `org-babel-process-params´ might trigger
  expensive operations this has to be deferred).  If `cache-current-p´
  is t, evaluate the source block without asking.  In case the cache
  is current the evaluation will not actually do anything but return
  the cached value, so this is safe.  Otherwise ask permission from
  the user by calling `org-babel--confirm-evaluate´ and act depending
  on the answer.

  The new variable `org-babel--confirm-evaluate-answer-no´ can be
  bound to suppress the user interaction as is needed for async
  export, as discussed in
  http://thread.gmane.org/gmane.emacs.orgmode/67719
---
 lisp/ob-core.el | 204 +++++++++++++++++++++++++++++---------------------------
 1 file changed, 106 insertions(+), 98 deletions(-)

diff --git a/lisp/ob-core.el b/lisp/ob-core.el
index 3b7c463..7ac423b 100644
--- a/lisp/ob-core.el
+++ b/lisp/ob-core.el
@@ -283,43 +283,50 @@ (defun org-babel-get-src-block-info (&optional light)
       (setf (nth 2 info) (org-babel-process-params (nth 2 info))))
     (when info (append info (list name indent)))))
 
-(defvar org-current-export-file) ; dynamically bound
-(defun org-babel-confirm-evaluate (info)
+(defvar org-current-export-file) ; dynamically scoped
+(defmacro org-babel--check-confirm-evaluate (info &rest body)
+  "Pull some information from code block INFO and evaluate BODY."
+  (declare (indent defun))
+  `(let* ((eval (or (cdr (assoc :eval (nth 2 ,info)))
+		   (when (assoc :noeval (nth 2 ,info)) "no")))
+	 (code-block (if info (format " %s " (nth 0 ,info)) " "))
+	 (block-name (if (nth 4 ,info) (format " (%s) " (nth 4 ,info)) " ")))
+     ,@body))
+(defun org-babel--check-evaluate (info)
+  "Check whether the code block INFO should be evaluated."
+  (org-babel--check-confirm-evaluate info
+    (not (when (or (equal eval "never") (equal eval "no")
+		   (and (org-bound-and-true-p org-current-export-file)
+			(or (equal eval "no-export") (equal eval "never-export"))))
+	   (message (format "Evaluation of this%scode block%sis disabled."
+			    code-block block-name))))))
+(defvar org-babel--confirm-evaluate-answer-no) ;; dynamically scoped
+(defun org-babel--confirm-evaluate (info)
   "Confirm evaluation of the code block INFO.
-This behavior can be suppressed by setting the value of
+
+If the variable `org-babel--confirm-evaluate-answer-no´ is bound
+to a non-nil value, auto-answer with \"no\".
+
+This query can also be suppressed by setting the value of
 `org-confirm-babel-evaluate' to nil, in which case all future
 interactive code block evaluations will proceed without any
 confirmation from the user.
 
 Note disabling confirmation may result in accidental evaluation
 of potentially harmful code."
-  (let* ((eval (or (cdr (assoc :eval (nth 2 info)))
-		   (when (assoc :noeval (nth 2 info)) "no")))
-         (query (cond ((equal eval "query") t)
-		      ((and (boundp 'org-current-export-file)
-			    org-current-export-file
-			    (equal eval "query-export")) t)
-                      ((functionp org-confirm-babel-evaluate)
-                       (funcall org-confirm-babel-evaluate
-                                (nth 0 info) (nth 1 info)))
-                      (t org-confirm-babel-evaluate))))
-    (if (or (equal eval "never") (equal eval "no")
-	    (and (boundp 'org-current-export-file)
-		 org-current-export-file
-		 (or (equal eval "no-export")
-		     (equal eval "never-export")))
-	    (and query
-		 (not (yes-or-no-p
-		       (format "Evaluate this%scode block%son your system? "
-			       (if info (format " %s " (nth 0 info)) " ")
-			       (if (nth 4 info)
-				   (format " (%s) " (nth 4 info)) " "))))))
-	(prog1 nil (message "Evaluation %s"
-			    (if (or (equal eval "never") (equal eval "no")
-				    (equal eval "no-export")
-				    (equal eval "never-export"))
-				"Disabled" "Aborted")))
-      t)))
+  (org-babel--check-confirm-evaluate info
+    (not (when (cond ((equal eval "query") t)
+			 ((and (org-bound-and-true-p org-current-export-file)
+			       (equal eval "query-export")) t)
+			 ((functionp org-confirm-babel-evaluate)
+			  (funcall org-confirm-babel-evaluate
+				   (nth 0 info) (nth 1 info)))
+			 (t org-confirm-babel-evaluate))
+	   (or (org-bound-and-true-p org-babel--confirm-evaluate-answer-no)
+	       (not (yes-or-no-p (format "Evaluate this%scode block%son your system? "
+				      code-block block-name)))
+	       (message (format "Evaluation of%scode-block%snot confirmed."
+				code-block block-name)))))))
 
 ;;;###autoload
 (defun org-babel-execute-safely-maybe ()
@@ -525,80 +532,81 @@ (defun org-babel-execute-src-block (&optional arg info params)
   (interactive)
   (let* ((info (or info (org-babel-get-src-block-info)))
 	 (merged-params (org-babel-merge-params (nth 2 info) params)))
-    (when (org-babel-confirm-evaluate
+    (when (org-babel--check-evaluate
 	   (let ((i info)) (setf (nth 2 i) merged-params) i))
-      (let* ((lang (nth 0 info))
-	     (params (if params
+      (let* ((params (if params
 			 (org-babel-process-params merged-params)
 		       (nth 2 info)))
 	     (cache-p (and (not arg) (cdr (assoc :cache params))
-			  (string= "yes" (cdr (assoc :cache params)))))
-	     (result-params (cdr (assoc :result-params params)))
+			   (string= "yes" (cdr (assoc :cache params)))))
 	     (new-hash (when cache-p (org-babel-sha1-hash info)))
 	     (old-hash (when cache-p (org-babel-current-result-hash)))
-	     (cache-current-p (and (not arg) new-hash (equal new-hash old-hash)))
-	     (body (setf (nth 1 info)
-			 (if (org-babel-noweb-p params :eval)
-			     (org-babel-expand-noweb-references info)
-			   (nth 1 info))))
-	     (dir (cdr (assoc :dir params)))
-	     (default-directory
-	       (or (and dir (file-name-as-directory (expand-file-name dir)))
-		   default-directory))
-	     (org-babel-call-process-region-original
-	      (if (boundp 'org-babel-call-process-region-original)
-		  org-babel-call-process-region-original
-		(symbol-function 'call-process-region)))
-	     (indent (car (last info)))
-	     result cmd)
-	(unwind-protect
-	    (let ((call-process-region
-		   (lambda (&rest args)
-		     (apply 'org-babel-tramp-handle-call-process-region args))))
-	      (let ((lang-check (lambda (f)
-				  (let ((f (intern (concat "org-babel-execute:" f))))
-				    (when (fboundp f) f)))))
-		(setq cmd
-		      (or (funcall lang-check lang)
-			  (funcall lang-check (symbol-name
-					       (cdr (assoc lang org-src-lang-modes))))
-			  (error "No org-babel-execute function for %s!" lang))))
-	      (if cache-current-p
-		  (save-excursion ;; return cached result
-		    (goto-char (org-babel-where-is-src-block-result nil info))
-		    (end-of-line 1) (forward-char 1)
-		    (setq result (org-babel-read-result))
-		    (message (replace-regexp-in-string
-			      "%" "%%" (format "%S" result))) result)
-		(message "executing %s code block%s..."
-			 (capitalize lang)
-			 (if (nth 4 info) (format " (%s)" (nth 4 info)) ""))
-		(if (member "none" result-params)
-		    (progn
-		      (funcall cmd body params)
-		      (message "result silenced"))
-		(setq result
-		      ((lambda (result)
-			 (if (and (eq (cdr (assoc :result-type params)) 'value)
-				  (or (member "vector" result-params)
-				      (member "table" result-params))
-				  (not (listp result)))
-			     (list (list result)) result))
-		       (funcall cmd body params)))
-		;; if non-empty result and :file then write to :file
-		(when (cdr (assoc :file params))
-		  (when result
-		    (with-temp-file (cdr (assoc :file params))
-		      (insert
-		       (org-babel-format-result
-			result (cdr (assoc :sep (nth 2 info)))))))
-		  (setq result (cdr (assoc :file params))))
-		(org-babel-insert-result
-		 result result-params info new-hash indent lang)
-		(run-hooks 'org-babel-after-execute-hook)
-		result
-		)))
-	  (setq call-process-region 'org-babel-call-process-region-original))))))
+	     (cache-current-p (and (not arg) new-hash (equal new-hash old-hash))))
+	(when (or cache-current-p
+		  (org-babel--confirm-evaluate
+		   (let ((i info)) (setf (nth 2 i) merged-params) i)))
+	  (let* ((lang (nth 0 info))
+		 (result-params (cdr (assoc :result-params params)))
+		 (body (setf (nth 1 info)
+			     (if (org-babel-noweb-p params :eval)
+				 (org-babel-expand-noweb-references info)
+			       (nth 1 info))))
+		 (dir (cdr (assoc :dir params)))
+		 (default-directory
+		   (or (and dir (file-name-as-directory (expand-file-name dir)))
+		       default-directory))
+		 (org-babel-call-process-region-original
+		  (if (org-bound-and-true-p org-babel-call-process-region-original)
+		      (symbol-function 'call-process-region)))
+		 (indent (car (last info)))
+		 result cmd)
+	    (unwind-protect
+		(let ((call-process-region
+		       (lambda (&rest args)
+			 (apply 'org-babel-tramp-handle-call-process-region args))))
+		  (let ((lang-check (lambda (f)
+				      (let ((f (intern (concat "org-babel-execute:" f))))
+					(when (fboundp f) f)))))
+		    (setq cmd
+			  (or (funcall lang-check lang)
+			      (funcall lang-check (symbol-name
+						   (cdr (assoc lang org-src-lang-modes))))
+			      (error "No org-babel-execute function for %s!" lang))))
+		  (if cache-current-p
+		      (save-excursion ;; return cached result
+			(goto-char (org-babel-where-is-src-block-result nil info))
+			(end-of-line 1) (forward-char 1)
+			(setq result (org-babel-read-result))
+			(message (replace-regexp-in-string
+				  "%" "%%" (format "%S" result))) result)
+		    (message "executing %s code block%s..."
+			     (capitalize lang)
+			     (if (nth 4 info) (format " (%s)" (nth 4 info)) ""))
+		    (if (member "none" result-params)
+			(progn
+			  (funcall cmd body params)
+			  (message "result silenced"))
+		      (setq result
+			    ((lambda (result)
+			       (if (and (eq (cdr (assoc :result-type params)) 'value)
+					(or (member "vector" result-params)
+					    (member "table" result-params))
+					(not (listp result)))
+				   (list (list result)) result))
+			     (funcall cmd body params)))
+		      ;; if non-empty result and :file then write to :file
+		      (when (cdr (assoc :file params))
+			(when result
+			  (with-temp-file (cdr (assoc :file params))
+			    (insert
+			     (org-babel-format-result
+			      result (cdr (assoc :sep (nth 2 info)))))))
+			(setq result (cdr (assoc :file params))))
+		      (org-babel-insert-result
+		       result result-params info new-hash indent lang)
+		      (run-hooks 'org-babel-after-execute-hook)
+		      result)))
+	      (setq call-process-region 'org-babel-call-process-region-original))))))))
 
 (defun org-babel-expand-body:generic (body params &optional var-lines)
   "Expand BODY with PARAMS.
-- 
1.8.1.4


[-- Attachment #3: Type: text/plain, Size: 209 bytes --]




Regards,
Achim.
-- 
+<[Q+ Matrix-12 WAVE#46+305 Neuron microQkb Andromeda XTk Blofeld]>+

Factory and User Sound Singles for Waldorf Q+, Q and microQ:
http://Synth.Stromeko.net/Downloads.html#WaldorfSounds

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

* Re: asynchronous exporter and babel confirmation
  2013-03-06 22:17           ` Achim Gratz
@ 2013-03-06 22:38             ` Nicolas Goaziou
  2013-03-06 22:44               ` Achim Gratz
  2013-03-09 22:20               ` Achim Gratz
  0 siblings, 2 replies; 13+ messages in thread
From: Nicolas Goaziou @ 2013-03-06 22:38 UTC (permalink / raw)
  To: Achim Gratz; +Cc: emacs-orgmode

Thanks for considering the changes.

Achim Gratz <Stromeko@nexgo.de> writes:

> +		 (org-babel-call-process-region-original
> +		  (if (org-bound-and-true-p org-babel-call-process-region-original)
> +		      (symbol-function 'call-process-region)))

I think you mean (or (....) (....))


I will wait for this patch to be committed.

Regards,

-- 
Nicolas Goaziou

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

* Re: asynchronous exporter and babel confirmation
  2013-03-06 22:38             ` Nicolas Goaziou
@ 2013-03-06 22:44               ` Achim Gratz
  2013-03-09 22:20               ` Achim Gratz
  1 sibling, 0 replies; 13+ messages in thread
From: Achim Gratz @ 2013-03-06 22:44 UTC (permalink / raw)
  To: emacs-orgmode

Nicolas Goaziou writes:
> I think you mean (or (....) (....))

Yes of course, thanks for catching that.  This also means that the
testsuite isn't picking upon that.

> I will wait for this patch to be committed.

When and if Eric chimes in and Karl confirms that his earlier problem
with this change is solved.


Regards,
Achim.
-- 
+<[Q+ Matrix-12 WAVE#46+305 Neuron microQkb Andromeda XTk Blofeld]>+

Samples for the Waldorf Blofeld:
http://Synth.Stromeko.net/Downloads.html#BlofeldSamplesExtra

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

* Re: asynchronous exporter and babel confirmation
  2013-03-06 22:38             ` Nicolas Goaziou
  2013-03-06 22:44               ` Achim Gratz
@ 2013-03-09 22:20               ` Achim Gratz
  2013-03-09 23:19                 ` Nicolas Goaziou
  1 sibling, 1 reply; 13+ messages in thread
From: Achim Gratz @ 2013-03-09 22:20 UTC (permalink / raw)
  To: emacs-orgmode

Nicolas Goaziou writes:
> I will wait for this patch to be committed.

Done in commit 4f7d514f13.  The double hyphens have been omitted based
on a discussion with Eric Schulte.


Regards,
Achim.
-- 
+<[Q+ Matrix-12 WAVE#46+305 Neuron microQkb Andromeda XTk Blofeld]>+

Factory and User Sound Singles for Waldorf Blofeld:
http://Synth.Stromeko.net/Downloads.html#WaldorfSounds

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

* Re: asynchronous exporter and babel confirmation
  2013-03-09 22:20               ` Achim Gratz
@ 2013-03-09 23:19                 ` Nicolas Goaziou
  2013-03-10 15:38                   ` Alan Schmitt
  0 siblings, 1 reply; 13+ messages in thread
From: Nicolas Goaziou @ 2013-03-09 23:19 UTC (permalink / raw)
  To: Achim Gratz; +Cc: emacs-orgmode

Hello,

Achim Gratz <Stromeko@nexgo.de> writes:

> Done in commit 4f7d514f13.  The double hyphens have been omitted based
> on a discussion with Eric Schulte.

Applied to ox.el in commit 69c617c.

Thank you.


Regards,

-- 
Nicolas Goaziou

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

* Re: asynchronous exporter and babel confirmation
  2013-03-09 23:19                 ` Nicolas Goaziou
@ 2013-03-10 15:38                   ` Alan Schmitt
  0 siblings, 0 replies; 13+ messages in thread
From: Alan Schmitt @ 2013-03-10 15:38 UTC (permalink / raw)
  To: Nicolas Goaziou; +Cc: Achim Gratz, emacs-orgmode

Nicolas Goaziou writes:

> Hello,
>
> Achim Gratz <Stromeko@nexgo.de> writes:
>
>> Done in commit 4f7d514f13.  The double hyphens have been omitted based
>> on a discussion with Eric Schulte.
>
> Applied to ox.el in commit 69c617c.

Thanks a lot!

Alan

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

end of thread, other threads:[~2013-03-10 15:38 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-06  9:30 asynchronous exporter and babel confirmation Alan Schmitt
2013-03-06 10:10 ` Nicolas Goaziou
2013-03-06 12:34   ` Achim Gratz
2013-03-06 12:52     ` Nicolas Goaziou
2013-03-06 19:47       ` Achim Gratz
2013-03-06 20:25         ` Nicolas Goaziou
2013-03-06 22:17           ` Achim Gratz
2013-03-06 22:38             ` Nicolas Goaziou
2013-03-06 22:44               ` Achim Gratz
2013-03-09 22:20               ` Achim Gratz
2013-03-09 23:19                 ` Nicolas Goaziou
2013-03-10 15:38                   ` Alan Schmitt
2013-03-06 13:04     ` Alan Schmitt

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).