From 8a821549ff875c97fdf12a4608fa2f253d026f80 Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Tue, 1 Jul 2014 08:52:34 -0500 Subject: [PATCH 1/2] Vector support --- evil-numbers.el | 65 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 17 deletions(-) diff --git a/evil-numbers.el b/evil-numbers.el index eb7c5db..adb106e 100644 --- a/evil-numbers.el +++ b/evil-numbers.el @@ -58,6 +58,25 @@ ;;; Code: +(defgroup evil-numbers nil + "Evil Numbers") + +(defcustom evil-numbers-dont-pad-matching-pairs-for-decimal-numbers + '(("[" "]") + ("(" ")")) + "If the decimal number is enclosed in these items, don't pad the item. +For example, x[10] will not be changed to x[09] and x(10) will not be changed to x(09)" + :type '(repeat + (list + (string :tag "Match at beginning: ") + (string :tag "Match at end: "))) + :group 'evil-numbers) + +(defcustom evil-numbers-dont-move-backward-to-match-vim nil + "Don't match vim's moving one character backward after replacement." + :type 'boolean + :group 'evil-numbers) + ;;;###autoload (defun evil-numbers/inc-at-pt (amount &optional no-region) "Increment the number at point or after point before end-of-line by `amount'. @@ -80,7 +99,8 @@ applying the regional features of `evil-numbers/inc-at-point'. (while (re-search-forward "\\(?:0\\(?:[Bb][01]+\\|[Oo][0-7]+\\|[Xx][0-9A-Fa-f]+\\)\\|-?[0-9]+\\)" re t) (evil-numbers/inc-at-pt amount 'no-region) ;; Undo vim compatability. - (forward-char 1))))) + (unless evil-numbers-dont-move-backward-to-match-vim + (forward-char 1)))))) (setq deactivate-mark t)) (t (save-match-data @@ -102,13 +122,23 @@ applying the regional features of `evil-numbers/inc-at-point'. (progn (skip-chars-backward "0123456789") (skip-chars-backward "-") - (when (looking-at "-?\\([0-9]+\\)") + (cond + ((and (looking-back (regexp-opt (mapcar (lambda(x) (nth 0 x)) evil-numbers-dont-pad-matching-pairs-for-decimal-numbers))) + (looking-at (concat "\\(-?[0-9]+\\)\\(" (regexp-quote (cadr (assoc (match-string 0) evil-numbers-dont-pad-matching-pairs-for-decimal-numbers))) "\\)"))) + (replace-match + (format "%s\\2" (+ amount (string-to-number (match-string 1) 10)))) + ;; Move point one position back to conform with Vim + (unless evil-numbers-dont-move-backward-to-match-vim + (forward-char (- 1 (length (match-string 2))))) + t) + ((looking-at "-?\\([0-9]+\\)") (replace-match (format (format "%%0%dd" (- (match-end 1) (match-beginning 1))) (+ amount (string-to-number (match-string 0) 10)))) ;; Moves point one position back to conform with Vim - (forward-char -1) - t)) + (unless evil-numbers-dont-move-backward-to-match-vim + (forward-char -1)) + t))) (error "No number at point or until end of line"))))))) ;;;###autoload @@ -135,21 +165,21 @@ decimal: [0-9]+, e.g. 42 or 23" (or ;; numbers or format specifier in front (looking-back (rx (or (+? digit) - (and "0" (or (and (in "bB") (*? (in "01"))) - (and (in "oO") (*? (in "0-7"))) - (and (in "xX") (*? (in digit "A-Fa-f")))))))) + (and "0" (or (and (in "bB") (*? (in "01"))) + (and (in "oO") (*? (in "0-7"))) + (and (in "xX") (*? (in digit "A-Fa-f")))))))) ;; search for number in rest of line ;; match 0 of specifier or digit, being in a literal and after specifier is ;; handled above (and - (re-search-forward "[[:digit:]]" (point-at-eol) t) - (or - (not (memq (char-after) '(?b ?B ?o ?O ?x ?X))) - (/= (char-before) ?0) - (and (> (point) 2) ; Should also take bofp into consideration - (not (looking-back "\\W0" 2))) - ;; skip format specifiers and interpret as bool - (<= 0 (skip-chars-forward "bBoOxX")))))) + (re-search-forward "[[:digit:]]" (point-at-eol) t) + (or + (not (memq (char-after) '(?b ?B ?o ?O ?x ?X))) + (/= (char-before) ?0) + (and (> (point) 2) ; Should also take bofp into consideration + (not (looking-back "\\W0" 2))) + ;; skip format specifiers and interpret as bool + (<= 0 (skip-chars-forward "bBoOxX")))))) (defun evil-numbers/search-and-replace (look-back skip-back search-forward inc base) "When looking back at `LOOK-BACK' skip chars `SKIP-BACK'backwards and replace number incremented by `INC' in `BASE' and return non-nil." @@ -159,8 +189,9 @@ decimal: [0-9]+, e.g. 42 or 23" (replace-match (evil-numbers/format (+ inc (string-to-number (match-string 1) base)) (length (match-string 1)) base)) - ;; Moves point one position back to conform with Vim - (forward-char -1) + ;; Moves point one position back to conform with Vim + (unless evil-numbers-dont-move-backward-to-match-vim + (forward-char -1)) t)) (defun evil-numbers/format (num width base) From 4931fd311c10a020bfa287be712a7e6bf670e21a Mon Sep 17 00:00:00 2001 From: "Matthew L. Fidler" Date: Tue, 1 Jul 2014 08:53:59 -0500 Subject: [PATCH 2/2] Update Readme.org --- README.org | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/README.org b/README.org index 253190e..23407bf 100644 --- a/README.org +++ b/README.org @@ -2,7 +2,9 @@ - Increment / Decrement binary, octal, decimal and hex literals - works like C-a/C-x in vim, i.e. searches for number up to eol and then - increments or decrements and keep zero padding up (unlike in vim) + increments or decrements and keep zero padding up (unlike in + vim), except for decimals in vectors like =x[10]= -> =x[9]=. The + pairs that define vectors can be customized with =evil-numbers-dont-pad-matching-pairs-for-decimal-numbers= - When a region is active, as in evil's visual mode, all the numbers within that region will be incremented/decremented (unlike @@ -29,7 +31,15 @@ #+END_SRC ** Usage - Position cursor on literal and play with your numbers! + Position cursor on literal and play with your numbers! + + If you don't like vim's behavior of moving a character backward + after replacement, then you can turn it off with + +#+BEGIN_SRC emacs-lisp + (setq evil-numbers-dont-move-backward-to-match-vim t) +#+END_SRC + ** Known Bugs See http://github.com/cofi/evil-numbers/issues