替换匹配后丢失光标位置并保存偏移

时间:2011-07-22 08:55:28

标签: emacs elisp

this answer中,我使用正则表达式搜索/替换将一种类型的ruby块转换为另一种。但是,在完成函数ruby-flip-containing-block-type之后,即使函数周围有save-excursion,该点也会移动到替换文本的开头。

我甚至尝试将点保存到寄存器并在翻转后跳回到它。保存的点将重新定位到我的更改开头。经过一些谷歌搜索,我认为问题在于,替换匹配调用更新了原始点的缓冲区内容。

关于如何在这种情况下保留/恢复该点的原始位置的任何想法?

3 个答案:

答案 0 :(得分:4)

替换文本后,将删除旧文本,并插入新文本。所以假设缓冲区看起来像这样,其中-!-表示点的位置:

abcdefghijklm-!-nopqrstuvwxyz

假设您将jklmnop替换为jlkMnop。首先删除jklmnop

abcdefghi-!-qrstuvwxyz

然后插入jlkMnop

abcdefghi-!-jklMnopqrstuvwxyz

您可以看到效果就像点被移动一样。

保留点的方法是更加小心如何更换文本。而不是替换大块(可能包含点),只替换实际更改的小部分。在您链接的答案中,不是将do\(.*\)end替换为{\1},而是将do替换为{,将end替换为}替代品。


这不一定是丑陋的。也许是这样的,使用replace-match的第五个(subexp)参数:

(when (re-search-forward "\\(do\\).*\\(?:\n.*\\)\\(end\\)" nil t)
  (replace-match "}" t t nil 2)
  (replace-match "{" t t nil 1))

答案 1 :(得分:1)

我有类似的问题。在替换之前将(point)保存到变量p,然后在函数末尾调用(goto-char p),似乎解决了我的问题。

答案 2 :(得分:0)

你可以使用(复制标记(点)t),这将保留一个指针,其属性是当在其位置插入某些东西时,它会移动到之后新文本,而不是在新文本之前