* lisp/org.el (org-next-block): Ring the bell right before throwing a
user error for when no block is found, if called interactively.
* testing/lisp/test-org.el (test-org/next-block): Test that the bell
rings if and only if called interactively.
* etc/ORG-NEWS (~org-next-block~ rings the bell if no block is found):
Announce the change and give an example use-case.
---
etc/ORG-NEWS | 10 ++++++++++
lisp/org.el | 8 ++++++--
testing/lisp/test-org.el | 14 ++++++++++++++
3 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 5b5908629..e1ced84e5 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -676,6 +676,16 @@ will be defined as empty and not produce any metadata if
their
corresponding ~org-latex-with-author~, ~org-latex-with-title~, or
~org-latex-with-creator~ option is set to ~nil~.
+*** ~org-next-block~ rings the bell if no block is found
+
+It is now possible to call the ~org-next-block~ function interactively
+from a keyboard macro that runs until the bell rings. For example, if
+the user customizes ~org-edit-src-content-indentation~, they can run a
+keyboard macro that updates all source blocks in a file, without Emacs
+looping forever. The change affects ~org-next-block~ and its callers,
+including functions ~org-previous-block~, ~org-babel-next-src-block~,
+and ~org-babel-previous-src-block~.
+
* Version 9.7
** Important announcements and breaking changes
diff --git a/lisp/org.el b/lisp/org.el
index 21622523b..9d48cdd66 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -20170,7 +20170,9 @@ (defun org-next-block (arg &optional backward
block-regexp)
returns.
Return point at beginning of the opening line of found block.
-Throw an error if no block is found."
+
+Throw an error if no block is found. When called interactively,
+ring the bell before throwing."
(interactive "p")
(let ((re (or block-regexp "^[ \t]*#\\+BEGIN"))
(case-fold-search t)
@@ -20190,13 +20192,15 @@ (defun org-next-block (arg &optional backward
block-regexp)
example-block export-block quote-block
special-block src-block verse-block))
(<= (match-beginning 0)
- (org-element-post-affiliated element)))
+ (org-element-post-affiliated element)))
(setq last-element element)
(cl-decf count))))
(if (= count 0)
(prog1 (goto-char (org-element-post-affiliated last-element))
(save-match-data (org-fold-show-context)))
(goto-char origin)
+ (when (called-interactively-p 'any)
+ (ding))
(user-error "No %s code blocks" (if backward "previous" "further")))))
(defun org-previous-block (arg &optional block-regexp)
diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el
index 36dea35b7..cf3e0b40b 100644
--- a/testing/lisp/test-org.el
+++ b/testing/lisp/test-org.el
@@ -5652,6 +5652,20 @@ (ert-deftest test-org/next-block ()
(should-error
(org-test-with-temp-text "Paragraph"
(org-next-block 1)))
+ ;; Ring the bell when no block is found.
+ (should-error
+ (org-test-with-temp-text "Paragraph"
+ (define-error 'ding "Ring my bell!")
+ (cl-letf (((symbol-function 'ding)
+ (lambda () (signal 'ding nil))))
+ (funcall-interactively #'org-next-block 1)))
+ :type 'ding)
+ ;; Ring the bell only when called interactively.
+ (should-error
+ (org-test-with-temp-text "Paragraph"
+ (let ((ring-bell-function (lambda () (signal 'ding nil))))
+ (org-next-block 1)))
+ :type 'user-error)
;; With an argument, skip many blocks at once.
(should
(org-test-with-temp-text
--
2.50.1