2016-12-30 78 views
1

升级到Aquamacs版本3.3(emacs 25.1.1)后,运行re-replace-region(如下定义)时出现标题中提到的错误,试图将区域中的9个字符串(例如“99”或“999”)更改为0。我从来没有在Aquamacs的早期版本(或emacs通常)中遇到过这个问题,并且在emacs环境或一般机器环境(Mac OS 10.9.5)中没有任何我能想到的问题,它们可能与问题。“re-replace-region:通过缓冲区修改挂钩匹配数据”

事实上,我在同一台机器上有一个emacs可执行文件(版本22.1.1),并且在相同的环境(例如,相同的〜/ .emacs等)中调用它之后,re-replace-region就像它应该那样工作。

我唯一可以提供的另一个线索是,当在一个区域中运行重新替换区域时,如果在其中指定了三个9(999),试图将9更改为0,则第一个9在错误条件之前被更改上调。

这里是defun定义:

;;; RE-REPLACE-REGION replaces OLD (a regular expression) with NEW 
;;; throughout the region indicated by BEGIN and END. 
;;; For example, to insert a prefix ">" at the beginning of each line 
;;; in the region: 
;;; M-x re-replace-regionRET^RET>RET 
;;; I don't know who wrote this function! 
(defun re-replace-region (begin end old new) 
"Replace occurrences of REGEXP with TO-STRING in region." 
    (interactive "*r\nsReplace string: \nswith: ") 
    (save-excursion 
    (save-restriction 
     (narrow-to-region begin end) 
     (goto-char (point-min)) 
     (while (re-search-forward old (point-max) t) 
     (replace-match new nil nil))))) 
+0

请从'emacs -Q'(无init文件)开始,提供一步一步的重现问题的方法。显示你使用的命令和输入等等。如果你或者这里的人可以告诉你没有做错什么,那么考虑将这个行为报告为一个错误,或者给Aquamacs维护者或者使用'Mx report-emacs-bug',if你认为它不涉及Aquamacs。 – Drew

回答

1

这个问题似乎是因为在受影响的缓冲区中变量before-change-functions(aquamacs-undo--rec-region-when-buffer-changes)而引起的。

一个简单的解决方法是使用replace-regexp而不是re-replace-region。事实上,因为当你有意它比单纯的解决方法更好,(即交互式使用时),replace-regexp被称为如下:

(replace-regexp REGEX TOSTRING nil 
    (if (use-region-p) (region-beginning)) 
    (if (use-region-p) (region-end)) nil) 

也就是说,如果一个区域被定义,replace-regexp仅影响该地区 - - 这首先是re-replace-region的理由。

我还想知道更多关于(aquamacs-undo--rec-region-when-buffer-changes)的信息。同时,特别感谢@phils。

+0

这听起来像你应该与aquamacs维护人员一起记录错误报告。 – phils

+0

可惜我一直没能验证该问题是关系到在─或离职后转换功能。事实上,我现在有一个缓冲区,其中(a)他们都是零; (b)重新置换区域失败,如上所述; (c)replace-regexp成功。恐怕似乎是重新替代区域更好的选择的存在正开始压倒我的好奇心:-( – peak

1

我可以告诉你,这个错误消息是在2016年7月出台,这也解释了为什么旧版本的Emacs没有提出它:

commit 3a9d6296b35e5317c497674d5725eb52699bd3b8 
Author: Eli Zaretskii 
Date: Mon Jul 4 18:34:40 2016 +0300 

Avoid crashes when buffer modification hooks clobber match data 

* src/search.c (Freplace_match): Error out if buffer modification 
hooks triggered by buffer changes in replace_range, upcase-region, 
and upcase-initials-region clobber the match data needed to be 
adjusted for the replacement. (Bug#23869) 

所以我首先假设错误中的信息是正确的,并尝试确认它。检查before-change-functionsafter-change-functions变量(在相关缓冲区中)的值,并确定列出的功能之一是否有责任。

想必其中的一个确实会破坏匹配数据,然后应该将其作为相关函数的错误处理。如果它是自定义的,你很可能只需要在相关代码周围打电话给save-match-data

+1

n.b. @peak提出了使用'replace-regexp'的解决方法,但这并不理想 - 使用're-search-forward'和'replace-match'是elisp代码的正确*方法(和'replace- regexp' docstring甚至指出了这一点),所以我不建议采用该解决方法,如果你可以避免它。 – phils

+1

我有同样的错误消息,但我做了一些不同于@peaks的东西。我把'before-change-functions','after-change-functions','pre-command-hook','post-command-hook'设置为空,并且仍然有错误。我已经放弃了一段时间,但今天才发现我没有检查'first-change-hook'。那竟然是我的罪魁祸首。 – amitp