简体   繁体   English

“re-replace-region:匹配缓冲区修改钩子破坏的数据”

[英]“re-replace-region: Match data clobbered by buffer modification hooks”

After upgrading to Aquamacs Version 3.3 (emacs 25.1.1), I'm getting the error mentioned in the title when running re-replace-region (as defined below), trying to change a string of 9s in a region (eg "99" or "999") to 0s. 升级到Aquamacs 3.3版(emacs 25.1.1)后,我在运行re-replace-region (如下定义)时遇到标题中提到的错误,尝试更改区域中的9s字符串(例如“99”) “或”999“)为0。 I've never had this problem with prior versions of Aquamacs (or emacs generally), and there is nothing I can think of, either in the emacs environment or the machine environment generally (Mac OS 10.9.5), that might be associated with the problem. 我以前从未遇到过Aquamacs(或者通常是emacs)的早期版本的问题,而且在emacs环境或一般的机器环境(Mac OS 10.9.5)中我无法想到任何可能与之相关的问题。问题。

In fact, I have an emacs executable (version 22.1.1) on the same machine, and after invoking it in the same environment (eg, same ~/.emacs etc), re-replace-region works as it should. 事实上,我在同一台机器上有一个emacs可执行文件(版本22.1.1),并且在相同的环境中调用它后(例如,相同的〜/ .emacs等), re-replace-region可以正常工作。

The only other clue I can offer is that when running re-replace-region on a region with say three 9s (999) in it, trying to change 9 to 0, the first 9 is altered before the error condition is raised. 我可以提供的唯一其他线索是,当在一个区域中运行重新替换区域时,如果在其中有三个9(999),尝试将9更改为0,则在引发错误条件之前更改前9个。

Here is the defun: 这是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)))))

I can tell you that this error message was introduced in July 2016, which explains why older versions of Emacs did not raise it: 我可以告诉你,这个错误消息是在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)

So I would firstly assume that the information in the error is correct , and try to confirm it. 所以我首先假设错误中的信息是正确的 ,并尝试确认它。 Check your values for the before-change-functions and after-change-functions variables (in the buffer in question), and establish whether one of the functions listed is responsible. 检查before-change-functionsafter-change-functions变量的值(在相关缓冲区中),并确定列出的其中一个函数是否负责。

Presumably one of them does indeed clobber the match data, and that should then be addressed as a bug for the function in question. 据推测其中一个确实破坏了匹配数据,然后应该将其作为相关功能的错误来解决。 If it's custom, you most likely just need to wrap a call to save-match-data around the relevant code. 如果是自定义的,您很可能只需要围绕相关代码打包save-match-data

The problem seems to arise because the variable before-change-functions is (aquamacs-undo--rec-region-when-buffer-changes) in the affected buffers. 这个问题似乎出现了,因为变量before-change-functions变量before-change-functions是受影响的缓冲区中的(aquamacs-undo--rec-region-when-buffer-changes)

A simple workaround is to use replace-regexp instead of re-replace-region . 一个简单的解决方法是使用replace-regexp而不是re-replace-region Indeed, it's better than a mere workaround, because when used as intended (ie, when used interactively), replace-regexp is called as follows: 实际上,它比单纯的解决方法更好,因为当按预期使用时(即交互使用时), replace-regexp的调用方式如下:

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

That is, if a region is defined, replace-regexp only affects the region -- which is of course the rationale for re-replace-region in the first place. 也就是说,如果定义了一个区域,则replace-regexp只影响该区域 - 这当然是首先re-replace-region的基本原理。

I'd still be interested to know more about (aquamacs-undo--rec-region-when-buffer-changes) . 我仍然有兴趣了解更多关于(aquamacs-undo--rec-region-when-buffer-changes) Meanwhile, thanks especially to @phils. 同时,尤其要感谢@phils。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM