branch: elpa/evil-numbers
commit e7adac70a076ae381c03960d9d669071c1177f3a
Author: Campbell Barton <[email protected]>
Commit: Campbell Barton <[email protected]>
Add option disable negative number support
Add `evil-numbers-negative' option (default t) that controls
whether the minus sign before a number is recognized. When set to nil,
-5 is treated as 5, allowing increment/decrement without sign handling.
This can be useful when dealing with date-ranges and numbers which tend
not be be negative.
---
README.org | 8 ++++++-
evil-numbers.el | 36 +++++++++++++++++++++-------
tests/evil-numbers-tests.el | 57 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 91 insertions(+), 10 deletions(-)
diff --git a/README.org b/README.org
index 8adf86e495c..96313548719 100644
--- a/README.org
+++ b/README.org
@@ -31,7 +31,7 @@
** Customization
- =evil-numbers-pad-default= ::
- Set to =t= if you want numbers to be padded with zeros (numbers with a
leading zero are always padded).
+ Set to =t= if you want numbers to be padded with zeros (numbers with a
leading zero are always padded).
If you want both behaviors, all commands take an optional argument
=padded=.
- =evil-numbers-separator-chars= ::
@@ -52,6 +52,12 @@
This is off by default as it doesn't follow VIM's behavior.
+ - =evil-numbers-negative= ::
+ Configure negative number support.
+
+ - =t= Support negative numbers (default).
+ - =nil= Numbers negative prefix is ignored, useful when numbers may be
date/year ranges.
+
** Key Bindings
Example key bindings:
diff --git a/evil-numbers.el b/evil-numbers.el
index 0ffdcd308d3..8c4d206d973 100644
--- a/evil-numbers.el
+++ b/evil-numbers.el
@@ -111,6 +111,11 @@ Set to nil to disable this functionality."
This doesn't match VIM's behavior."
:type 'boolean)
+(defcustom evil-numbers-negative t
+ "When non-nil, recognize and preserve negative numbers.
+When nil, the minus sign before a number is ignored, treating -5 as 5."
+ :type 'boolean)
+
;; ---------------------------------------------------------------------------
;; Internal Variables
@@ -446,7 +451,12 @@ replacing it by the result of NUMBER-XFORM-FN and return
non-nil."
(str-prev
(funcall decode-fn
(concat
- (match-string sign-group) (match-string num-group))))
+ (cond
+ (evil-numbers-negative
+ (match-string sign-group))
+ (t
+ ""))
+ (match-string num-group))))
(str-prev-strip
(cond
@@ -456,7 +466,14 @@ replacing it by the result of NUMBER-XFORM-FN and return
non-nil."
str-prev)))
(num-prev (string-to-number str-prev-strip base))
- (num-next (funcall number-xform-fn num-prev))
+ (num-next
+ (let ((result (funcall number-xform-fn num-prev)))
+ ;; When negative numbers are disabled, clamp to 0.
+ (cond
+ (evil-numbers-negative
+ result)
+ (t
+ (max 0 result)))))
(str-next
(evil-numbers--format
(abs num-next)
@@ -493,13 +510,14 @@ replacing it by the result of NUMBER-XFORM-FN and return
non-nil."
(replace-match (funcall encode-fn str-next) t t nil num-group)
;; Replace the sign (as needed).
- (cond
- ;; From negative to positive.
- ((and (< num-prev 0) (not (< num-next 0)))
- (replace-match "" t t nil sign-group))
- ;; From positive to negative.
- ((and (not (< num-prev 0)) (< num-next 0))
- (replace-match (funcall encode-fn "-") t t nil sign-group)))
+ (when evil-numbers-negative
+ (cond
+ ;; From negative to positive.
+ ((and (< num-prev 0) (not (< num-next 0)))
+ (replace-match "" t t nil sign-group))
+ ;; From positive to negative.
+ ((and (not (< num-prev 0)) (< num-next 0))
+ (replace-match (funcall encode-fn "-") t t nil sign-group))))
(goto-char (match-end num-group)))
diff --git a/tests/evil-numbers-tests.el b/tests/evil-numbers-tests.el
index b200ecfd45b..dc03671a2d9 100644
--- a/tests/evil-numbers-tests.el
+++ b/tests/evil-numbers-tests.el
@@ -770,5 +770,62 @@ should result in 08 (matching original width), not 8."
;; Number SHOULD be incremented (cursor ends at number).
(should (equal "foo(2|)" (buffer-string)))))))
+(ert-deftest simple-handle-negative-disabled ()
+ "Check `evil-numbers-negative' behavior when disabled.
+When disabled, the minus sign before a number is ignored."
+ ;; Test with option ENABLED (default behavior).
+ ;; Incrementing -5 should give -4.
+ (let ((evil-numbers-negative t)
+ (text-expected " -4| ")
+ (text-initial " -5 "))
+ (with-evil-numbers-test text-initial
+ (simulate-input
+ (kbd "C-a")
+ "a|")
+ (should (equal text-expected (buffer-string)))))
+
+ ;; Test with option DISABLED.
+ ;; The minus sign is ignored, so -5 is treated as 5.
+ ;; Incrementing 5 gives 6, result is -6 (minus untouched).
+ (let ((evil-numbers-negative nil)
+ (text-expected " -6| ")
+ (text-initial " -5 "))
+ (with-evil-numbers-test text-initial
+ (simulate-input
+ (kbd "C-a")
+ "a|")
+ (should (equal text-expected (buffer-string)))))
+
+ ;; Test decrement with option DISABLED.
+ ;; Decrementing 5 (ignoring the minus) gives 4, result is -4.
+ (let ((evil-numbers-negative nil)
+ (text-expected " -4| ")
+ (text-initial " -5 "))
+ (with-evil-numbers-test text-initial
+ (simulate-input
+ (kbd "C-x")
+ "a|")
+ (should (equal text-expected (buffer-string)))))
+
+ ;; Positive numbers should work normally with option disabled.
+ (let ((evil-numbers-negative nil)
+ (text-expected " 6| ")
+ (text-initial " 5 "))
+ (with-evil-numbers-test text-initial
+ (simulate-input
+ (kbd "C-a")
+ "a|")
+ (should (equal text-expected (buffer-string)))))
+
+ ;; Decrementing 0 with option disabled should clamp to 0.
+ (let ((evil-numbers-negative nil)
+ (text-expected " 0| ")
+ (text-initial " 0 "))
+ (with-evil-numbers-test text-initial
+ (simulate-input
+ (kbd "C-x")
+ "a|")
+ (should (equal text-expected (buffer-string))))))
+
(provide 'evil-numbers-tests)
;;; evil-numbers-tests.el ends here