branch: elpa/loopy
commit 07ff6c900fbe9fd218a5602974507e81c3165f6d
Author: okamsn <[email protected]>
Commit: GitHub <[email protected]>

    Separate the definitions of the `while` and `until` commands. (#267)
    
    - Separate the definition `loopy--parse-while-until-commands` into
      `loopy--parse-while-command` and `loopy--parse-until-command`.
      This fixes aliasing the commands.
    - Deprecate multiple conditions, like we did with `never` and `always`.
    - The definitions in the Org documentation did not need to be changed.
    - Update the README.
---
 CHANGELOG.md           |  9 +++++++++
 README.org             |  2 ++
 lisp/loopy-commands.el | 40 ++++++++++++++++++++++++++++++++++++++++
 lisp/loopy-vars.el     |  4 ++--
 tests/tests.el         | 19 +++++++++++++++++++
 5 files changed, 72 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 300cf3f122..20c75d03a1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -22,19 +22,28 @@ For Loopy Dash, see <https://github.com/okamsn/loopy-dash>.
   More specifically, keep the same order returned by `pcase` for the binding of
   those final variables.
 
+- `while` and `until` now correctly work when aliased ([#267]).
+
 ### Breaking Changes
 
 - Using accumulation commands with different initial values for the same
   variable now signals an error instead of a warning ([#169], [#254]).
+
 - Aliases made obsolete in version 0.14.0 of this package have been removed 
(see
   release notes for that version below) ([#256]).  They can still be added
   manually to `loopy-parsers`.
 
+- Passing multiple conditions to `while` and `until` now signals a warning
+  ([#267]).  To be consistent with `never` and `always`, in the future, the
+  `while` and `until` commands will only accept a single condition.  To keep 
the
+  old behavior, wrap multiple conditions in `and`.
+
 [#169]: https://github.com/okamsn/loopy/issues/169
 [#254]: https://github.com/okamsn/loopy/PR/254
 [#251]: https://github.com/okamsn/loopy/PR/251
 [#256]: https://github.com/okamsn/loopy/PR/256
 [#265]: https://github.com/okamsn/loopy/PR/265
+[#267]: https://github.com/okamsn/loopy/PR/267
 
 ## 0.15.0
 
diff --git a/README.org b/README.org
index c2a686a47a..9ae30adb71 100644
--- a/README.org
+++ b/README.org
@@ -40,6 +40,8 @@ please let me know.
      variable now signals an error instead of a warning.
    - Aliases made obsolete in version 0.14.0 have been removed.  They can still
      be added manually to ~loopy-parsers~.
+   - =while= and =until= now signal a warning when receiving multiple
+     conditions.  In the future, this will be an error.
  - Version 0.15.0:
    - Loopy now requires at least Emacs version 28.1, increased from version
      27.1.
diff --git a/lisp/loopy-commands.el b/lisp/loopy-commands.el
index 1b9c301585..e360cb068d 100644
--- a/lisp/loopy-commands.el
+++ b/lisp/loopy-commands.el
@@ -2909,6 +2909,46 @@ returned."
       (loopy--main-body (throw (quote ,tag-name) t)))))
 
 ;;;;;; While Until
+(cl-defun loopy--parse-while-command ((_name condition &rest conditions))
+  "Parse the `while' command as (while CONDITION).
+
+Stop the loop when CONDITION is nil.
+
+CONDITION is a required condition.  CONDITIONS is the remaining optional
+conditions."
+  (when conditions
+    (warn "`loopy': `while' will only support one argument in the future.
+To keep the old behavior, wrap multiple conditions with `and'."))
+  (let ((tag-name (loopy--produce-non-returning-exit-tag-name 
loopy--loop-name))
+        (condition (if (zerop (length conditions))
+                       condition
+                     `(and ,condition ,@conditions))))
+    `((loopy--non-returning-exit-used ,tag-name)
+      (loopy--main-body (if ,condition
+                            nil
+                          (throw (quote ,tag-name) t))))))
+
+(cl-defun loopy--parse-until-command ((_name condition &rest conditions))
+  "Parse the `until' command as (until CONDITION).
+
+Stop the loop when CONDITION is non-nil.
+
+CONDITION is a required condition.  CONDITIONS is the remaining optional
+conditions."
+  (when conditions
+    (warn "`loopy': `until' will only support one argument in the future.
+To keep the old behavior, wrap multiple conditions with `and'."))
+  (let ((tag-name (loopy--produce-non-returning-exit-tag-name 
loopy--loop-name))
+        (condition (if (zerop (length conditions))
+                       condition
+                     `(and ,condition ,@conditions))))
+    `((loopy--non-returning-exit-used ,tag-name)
+      (loopy--main-body (if ,condition
+                            (throw (quote ,tag-name) t))))))
+
+(make-obsolete 'loopy--parse-while-until-commands
+               "use `loopy--parse-while-command' or 
`loopy--parse-until-command'"
+               "2026-03")
 (cl-defun loopy--parse-while-until-commands ((name condition &rest conditions))
   "Parse the `while' and `until' commands.
 
diff --git a/lisp/loopy-vars.el b/lisp/loopy-vars.el
index 0e5367ce22..74dbdb5340 100644
--- a/lisp/loopy-vars.el
+++ b/lisp/loopy-vars.el
@@ -288,8 +288,8 @@ Definition must exist.  Neither argument need be quoted."
            vconcating        loopy--parse-vconcat-command
            unless            loopy--parse-unless-command
            when              loopy--parse-when-command
-           until             loopy--parse-while-until-commands
-           while             loopy--parse-while-until-commands
+           until             loopy--parse-until-command
+           while             loopy--parse-while-command
            loopy-iter        loopy-iter--parse-loopy-iter-command))
   "Map of symbols to parsing functions.
 
diff --git a/tests/tests.el b/tests/tests.el
index 6815a3c740..a6ee92a061 100644
--- a/tests/tests.el
+++ b/tests/tests.el
@@ -6488,6 +6488,16 @@ Not multiple of 3: 7"
   :iter-keyword (list while collect)
   :iter-bare nil)
 
+(loopy-deftest while-alias
+  :doc "Make sure aliases don't show up in `while' instead of the symbol 
`while'."
+  :result 1
+  :wrap ((x . `(let ((loopy-parsers
+                      (map-insert loopy-parsers 'w (map-elt loopy-parsers 
'while))))
+                 (eval (quote ,x) t))))
+  :body ((w nil)
+         (finally-return 1))
+  :loopy t)
+
 ;;;;; Until
 (loopy-deftest until
   :result '(1 2 3)
@@ -6498,6 +6508,15 @@ Not multiple of 3: 7"
   :iter-keyword (list until collect)
   :iter-bare nil)
 
+(loopy-deftest until-alias
+  :doc "Make sure aliases don't show up in `until' instead of the symbol 
`until'."
+  :result 1
+  :wrap ((x . `(let ((loopy-parsers
+                      (map-insert loopy-parsers 'u (map-elt loopy-parsers 
'until))))
+                 (eval (quote ,x) t))))
+  :body ((u t)
+         (finally-return 1))
+  :loopy t)
 
 ;;;;; Always
 (loopy-deftest always-pass

Reply via email to