Reputation: 4343
I needed to go through an XML file looking for certain tags whose contents were human-recognizable but not regex-recognizable and to work on those tags. I put together a keyboard macro that did the work I needed, then tried to use the following elisp to let me step through the file and just press y or n for each tag instead of going back and forth between movement commands and macro executions.
(while t
(progn
(search-forward "<Name>")
(move-beginning-of-line nil)
(if (y-or-n-p "Problem? ")
(call-last-kbd-macro)
(next-line)
)))
However, when I M-: evaluated this, it got to y-or-n-p
and then emacs became unresponsive. I am using emacs on an OS X 10.7 machine. In Activity Monitor, emacs was taking up the normal amount of RAM and CPU time, not making escalating resource requests, so I don't think I ran into an infinite loop. Emacs simply stopped responding to typing and clicks altogether, including things like repeatedly hitting Escape or C-g. An additional detail: the one y-or-n-p
interaction I got was a dialog box, not in the minibuffer, which was strange - I clicked Yes on it and the dialog box went away, which was the last interaction I was able to get with emacs before it disappeared into deep space.
Is there something in the above elisp code that's inherently dangerous? My thought was that the (search-forward)
would fail at the end of the buffer, signal an error, and the loop would end.
Upvotes: 1
Views: 172
Reputation: 11316
Try this so that the search fails the loop terminates. This code could still loop forever if the call-last-kbd-macro moves point back before the previous search.
(while (search-forward "<Name>" nil t)
(progn
(move-beginning-of-line nil)
(if (y-or-n-p "Problem? ")
(call-last-kbd-macro)
(next-line))))
Upvotes: 1