Losing cursor location with save-excursion after replace-match
In this answer, I use a regular expression search/replace to convert from one type of ruby block to another. However, after the function ruby-flip-containing-block-type
is done, the point is moved to the beginning of the replaced text, even though there is a save-excursion
around the function.
I even tried saving the point to a register and jumping back to it after the flip. The saved point is relocated to the beginning of my changes. After some google searches, I think the problem lies with the fact that the replace-match call updates the buffer contents at the original point.
Any ideas on how I can preserve/restore 开发者_JS百科the original location of the point in this situation?
When text is replaced, the old text is removed, and the new text inserted. So let's say the buffer looks like this, where -!-
indicates the position of point:
abcdefghijklm-!-nopqrstuvwxyz
Suppose you replace jklmnop
with jlkMnop
. First the jklmnop
is removed:
abcdefghi-!-qrstuvwxyz
and then the jlkMnop
is inserted:
abcdefghi-!-jklMnopqrstuvwxyz
You can see that the effect is as if point was moved.
The way to preserve point is to be much more careful about how you go about replacing the text. Instead of replacing big blocks (which might well contain point), replace only the small sections that actually change. In the answer you link to, instead of replacing do\(.*\)end
with {\1}
, replace the do
with {
and the end
with }
in separate replacements.
This doesn't have to be ugly. Perhaps something like this, using the fifth (subexp
) argument to replace-match
:
(when (re-search-forward "\\(do\\).*\\(?:\n.*\\)\\(end\\)" nil t)
(replace-match "}" t t nil 2)
(replace-match "{" t t nil 1))
I had a similar issue. Mine seemed to be resolved by saving (point)
to variable p
before replacing, then calling (goto-char p)
at the end of the function.
You can use (copy-marker (point) t), which will keep a pointer with the property that when something is inserted at its position, it moves to after the new text, rather than staying before the new text.
精彩评论