branch: externals/compat commit c81ff6a92f74a4ca47da05db46f6b3f69882271e Author: Daniel Mendler <m...@daniel-mendler.de> Commit: Daniel Mendler <m...@daniel-mendler.de>
compat-29: with-narrowing -> with-restriction, without-restriction --- NEWS.org | 2 ++ compat-29.el | 31 ++++++++++++++++++------- compat-tests.el | 22 ++++++++++++++---- compat.texi | 72 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 105 insertions(+), 22 deletions(-) diff --git a/NEWS.org b/NEWS.org index 530759cd63..7532f7cb71 100644 --- a/NEWS.org +++ b/NEWS.org @@ -3,6 +3,8 @@ * Development - compat-27: Drop obsolete ~compat-call dired-get-marked-files~. +- compat-29: Add ~with-restriction~ and ~without-restriction~. +- compat-29: Drop ~with-narrowing~. * Release of "Compat" Version 29.1.3.4 diff --git a/compat-29.el b/compat-29.el index 9cf4a76981..d394f0934c 100644 --- a/compat-29.el +++ b/compat-29.el @@ -294,22 +294,37 @@ in order to restore the state of the local variables set via this macro. "Delete the current line." (delete-region (pos-bol) (pos-bol 2))) -(compat-defmacro with-narrowing (start end &rest rest) ;; <compat-tests:with-narrowing> +(compat-defmacro with-restriction (start end &rest rest) ;; <compat-tests:with-restriction> "Execute BODY with restrictions set to START and END. The current restrictions, if any, are restored upon return. -With the optional :locked TAG argument, inside BODY, -`narrow-to-region' and `widen' can be used only within the START -and END limits, unless the restrictions are unlocked by calling -`narrowing-unlock' with TAG. See `narrowing-lock' for a more -detailed description. +When the optional :label LABEL argument is present, in which +LABEL is a symbol, inside BODY, `narrow-to-region' and `widen' +can be used only within the START and END limits. To gain access +to other portions of the buffer, use `without-restriction' with the +same LABEL argument. -\(fn START END [:locked TAG] BODY)" +\(fn START END [:label LABEL] BODY)" `(save-restriction (narrow-to-region ,start ,end) ;; Locking is ignored - ,@(if (eq (car rest) :locked) (cddr rest) rest))) + ,@(if (eq (car rest) :label) (cddr rest) rest))) + +(compat-defmacro without-restriction (&rest rest) ;; <compat-tests:without-restriction> + "Execute BODY without restrictions. + +The current restrictions, if any, are restored upon return. + +When the optional :label LABEL argument is present, the +restrictions set by `with-restriction' with the same LABEL argument +are lifted. + +\(fn [:label LABEL] BODY)" + `(save-restriction + (widen) + ;; Locking is ignored + ,@(if (eq (car rest) :label) (cddr rest) rest))) (compat-defmacro with-memoization (place &rest code) ;; <compat-tests:with-memoization> "Return the value of CODE and stash it in PLACE. diff --git a/compat-tests.el b/compat-tests.el index 8ea2ce89b7..ba6cec4263 100644 --- a/compat-tests.el +++ b/compat-tests.el @@ -237,16 +237,30 @@ (should-equal 'h (get-text-property 2 'help-echo)) (should-equal 'h (get-text-property 6 'help-echo)))) -(ert-deftest with-narrowing () + ;; TODO reenable if Emacs 29 nightly builds are updated +(compat-tests--if (< emacs-major-version 29) (progn +(ert-deftest with-restriction () (with-temp-buffer (insert "abc") - (with-narrowing 2 3 :locked 'foo + (with-restriction 2 3 :label 'foo (should-equal "b" (buffer-string))) (should-equal "abc" (buffer-string)) - (with-narrowing 2 3 - (should-equal "b" (buffer-string))) + (with-restriction 2 3 + (should-equal "b" (buffer-string))) (should-equal "abc" (buffer-string)))) +(ert-deftest without-restriction () + (with-temp-buffer + (insert "abc") + (narrow-to-region 2 3) + (without-restriction :label 'foo + (should-equal "abc" (buffer-string))) + (should-equal "b" (buffer-string)) + (without-restriction + (should-equal "abc" (buffer-string))) + (should-equal "b" (buffer-string)))) +)) + (ert-deftest with-memoization () (let ((x (cons nil nil)) y computed) (with-memoization (car x) diff --git a/compat.texi b/compat.texi index a15b3bd5fb..521ca1102b 100644 --- a/compat.texi +++ b/compat.texi @@ -2338,16 +2338,68 @@ evaluated and then stashed in @var{place}. If @var{place}'s value is non-@code{nil}, return that value instead of evaluating @var{code}. @end defmac -@c based on lisp/subr.el -@defmac with-narrowing start end [:locked tag] &rest body -Execute @var{body} with restrictions set to @var{start} and @var{end}. -The current restrictions, if any, are restored upon return. With the -optional :locked @var{tag} argument, inside @var{tag}, -@code{narrow-to-region} and @code{widen} can be used only within the -@var{start} and @var{end} limits, unless the restrictions are unlocked -by calling @code{narrowing-unlock} with @var{tag}. See -@code{narrowing-lock} for a more detailed description. -@end defmac +@c copied from lispref/positions.texi +@defspec with-restriction start end [:label label] body +This special form saves the current bounds of the accessible portion +of the buffer, sets the accessible portion to start at @var{start} and +end at @var{end}, evaluates the @var{body} forms, and restores the +saved bounds. In that case it is equivalent to + +@example +(save-restriction + (narrow-to-region start end) + body) +@end example + +@cindex labeled narrowing +When the optional argument @var{label}, a symbol, is present, the +narrowing is @dfn{labeled}. A labeled narrowing differs from a +non-labeled one in several ways: + +@itemize @bullet +@item +During the evaluation of the @var{body} form, @code{narrow-to-region} +and @code{widen} can be used only within the @var{start} and @var{end} +limits. + +@item +To lift the restriction introduced by @code{with-restriction} and gain +access to other portions of the buffer, use @code{without-restriction} +with the same @var{label} argument. (Another way to gain access to +other portions of the buffer is to use an indirect buffer +(@pxref{Indirect Buffers,,,elisp}).) + +@item +Labeled narrowings can be nested. + +@item +Labeled narrowings can only be used in Lisp programs: they are never +visible on display, and never interfere with narrowings set by the +user. +@end itemize + +If you use @code{with-restriction} with the optional @var{label} +argument, we recommend documenting the @var{label} in the doc strings +of the functions which use it, so that other Lisp programs your code +calls could lift the labeled narrowing if and when it needs. +@end defspec + +@c copied from lispref/positions.texi +@defspec without-restriction [:label label] body +This special form saves the current bounds of the accessible portion +of the buffer, widens the buffer, evaluates the @var{body} forms, and +restores the saved bounds. In that case it is equivalent to + +@example +(save-restriction + (widen) + body) +@end example + +When the optional argument @var{label} is present, the narrowing set +by @code{with-restriction} with the same @var{label} argument is +lifted. +@end defspec @c copied from lispref/positions.texi @defun pos-bol &optional count