Reputation: 879331
Is there an easy way to define a function which repeats itself when passed an argument?
For example, I've defined the following function
(defun swap-sign ()
(interactive)
(search-forward-regexp "[+-]")
(if (equal (match-string 0) "-")
(replace-match "+")
(replace-match "-"))
)
I'd like C-u swap-sign
to call swap-sign
four times.
I've tried
(defun swap-sign (&optional num)
(interactive)
(let ((counter 0)
(num (if num (string-to-number num) 0)))
(while (<= counter num)
(search-forward-regexp "[+-]")
(if (equal (match-string 0) "-")
(replace-match "+")
(replace-match "-"))
(setq counter (1+ counter)))))
but C-u swap-sign
still only runs swap-sign (or perhaps more precisely, the body of the while-loop) once. I'm guessing it is because if num
is not the right way to test if num
is an empty string.
Am I on the right track, or is there a better/easier way to extend swap-sign
?
Upvotes: 1
Views: 247
Reputation: 4975
You need to tell emacs to expect, and pass the parameter in, by adding a "p" as the parameter specification for interactive (M-x apropos interactive
to get the documentation). Here I've made the minimal change to your code to get it to work - note, however, that you don't need the let/while to do the iteration, and the arg doesn't need to be optional.
(defun swap-sign (&optional num)
(interactive "p")
(let ((counter 1))
(while (<= counter num)
(search-forward-regexp "[+-]")
(if (equal (match-string 0) "-")
(replace-match "+")
(replace-match "-"))
(setq counter (1+ counter)))))
Note that you don't need to convert the parameter from a string - using "p" tells emacs to do this for you.
Upvotes: 4
Reputation: 26529
(defun swap-sign (arg)
(interactive "p")
(dotimes (i arg)
(search-forward-regexp "[+-]")
(if (equal (match-string 0) "-")
(replace-match "+")
(replace-match "-"))))
See the documentation of the interactive
special form for more details:
C-h finteractive
RET.
Upvotes: 5