Use save-excursion to remember position when updating dblocks

Magnus Henoch writes:

> This patch has been sitting in my tree for a while...  It's a fix to
> org-map-dblocks, to make it use save-excursion instead of remembering
> position values.  I need this since I have a dblock function that
> asynchronously updates dblocks from HTTP responses, and some dblocks
> ended up getting updated twice or thrice.

[...]

> My dblock-write function calls url-retrieve, to asynchronously retrieve an
> HTML page.  The callback function I pass to url-retrieve will then fill
> in the information I need into the dynamic block.
>
> So in the following case:
>
> * Find start of dblock 1, store as pos
> * Make HTTP request for dblock 1
> * Go back to pos
> * Find end of dblock 1
> * Find start of dblock 2, store as pos
> * Make HTTP request for dblock 2
> * Asynchronous event: HTTP response for dblock 1 arrives, insert lots of
>  data in dblock 1
> * Go back to pos
> * Find end of dblock 2
>
> the last step will actually find the end of dblock 1, if the amount of
> data inserted in dblock 1 is great enough that pos suddenly points
> inside it.  (Then it will of course find dblock 2 again, request its HTML
> page again, and thus insert the data twice.)
>
> An equivalent fix would be to make pos a marker instead.
This commit is contained in:
Carsten Dominik 2010-03-24 22:25:35 +01:00
parent 80d0b06fbf
commit 93af0ec925
2 changed files with 9 additions and 7 deletions

View File

@ -1,5 +1,8 @@
2010-03-24 Carsten Dominik <carsten.dominik@gmail.com>
* org.el (org-map-dblocks): Use save-excursion to remember the
position.
* org-attach.el (org-attach-commit): Remove dependence on xargs.
(org-attach-delete-one): Commit after deleting a file.

View File

@ -9689,16 +9689,15 @@ the property list including an extra property :name with the block name."
(defun org-map-dblocks (&optional command)
"Apply COMMAND to all dynamic blocks in the current buffer.
If COMMAND is not given, use `org-update-dblock'."
(let ((cmd (or command 'org-update-dblock))
pos)
(let ((cmd (or command 'org-update-dblock)))
(save-excursion
(goto-char (point-min))
(while (re-search-forward org-dblock-start-re nil t)
(goto-char (setq pos (match-beginning 0)))
(condition-case nil
(funcall cmd)
(error (message "Error during update of dynamic block")))
(goto-char pos)
(goto-char (match-beginning 0))
(save-excursion
(condition-case nil
(funcall cmd)
(error (message "Error during update of dynamic block"))))
(unless (re-search-forward org-dblock-end-re nil t)
(error "Dynamic block not terminated"))))))