[O] bug#23917: Please consider making Bug #23917 a blocker for 25.1 (was Re: org-capture: Capture template ‘g’: Match data clobbered by buffer modification hooks)
Stefan Monnier writes: >> Maybe there's a misunderstanding. What Noam suggested was just to >> move the code which adjusts search_regs.start[i] and .end[i] to before >> the call to replace_range. > > Oh, right, that's also an option. It might suffer from another problem, > which is that the match-data will be broken while the > before-change-functions are run, so if there's a save-match-data there > we're back to square one. Solution: adjust in between the before and after change functions. Patch below. I think there shouldn't be performance problems, although it does add yet another flag to replace_range (by the way, I noticed that the MARKERS flags is never 0, so it's redundant). I tested with the attached bug-23917-match-data-buffer-modhook.el. >From a8098080dff5f83f7cbcbec2bc263f9db3b45ad9 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Wed, 20 Jul 2016 20:15:14 -0400 Subject: [PATCH v1] Adjust match data before calling after-change-funs * src/insdel.c (replace_range): Add new parameter ADJUST_MATCH_DATA, if true. Update all callers except Freplace_match to pass 0 for the new parameter. * src/search.c (update_search_regs): New function, extracted from Freplace_match. (Freplace_match): Remove match data adjustment code, pass 1 for ADJUST_MATCH_DATA to replace_range instead. --- src/cmds.c| 2 +- src/editfns.c | 6 +++--- src/insdel.c | 10 -- src/lisp.h| 4 +++- src/search.c | 50 +- 5 files changed, 44 insertions(+), 28 deletions(-) diff --git a/src/cmds.c b/src/cmds.c index 1e44ddd..4003d8b 100644 --- a/src/cmds.c +++ b/src/cmds.c @@ -447,7 +447,7 @@ internal_self_insert (int c, EMACS_INT n) string = concat2 (string, tem); } - replace_range (PT, PT + chars_to_delete, string, 1, 1, 1); + replace_range (PT, PT + chars_to_delete, string, 1, 1, 1, 0); Fforward_char (make_number (n)); } else if (n > 1) diff --git a/src/editfns.c b/src/editfns.c index 412745d..32c8bec 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -3192,7 +3192,7 @@ DEFUN ("subst-char-in-region", Fsubst_char_in_region, /* replace_range is less efficient, because it moves the gap, but it handles combining correctly. */ replace_range (pos, pos + 1, string, - 0, 0, 1); + 0, 0, 1, 0); pos_byte_next = CHAR_TO_BYTE (pos); if (pos_byte_next > pos_byte) /* Before combining happened. We should not increment @@ -3405,7 +3405,7 @@ DEFUN ("translate-region-internal", Ftranslate_region_internal, /* This is less efficient, because it moves the gap, but it should handle multibyte characters correctly. */ string = make_multibyte_string ((char *) str, 1, str_len); - replace_range (pos, pos + 1, string, 1, 0, 1); + replace_range (pos, pos + 1, string, 1, 0, 1, 0); len = str_len; } else @@ -3446,7 +3446,7 @@ DEFUN ("translate-region-internal", Ftranslate_region_internal, { string = Fmake_string (make_number (1), val); } - replace_range (pos, pos + len, string, 1, 0, 1); + replace_range (pos, pos + len, string, 1, 0, 1, 0); pos_byte += SBYTES (string); pos += SCHARS (string); cnt += SCHARS (string); diff --git a/src/insdel.c b/src/insdel.c index 4ad1074..fc3f19f 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -1268,7 +1268,9 @@ adjust_after_insert (ptrdiff_t from, ptrdiff_t from_byte, /* Replace the text from character positions FROM to TO with NEW, If PREPARE, call prepare_to_modify_buffer. If INHERIT, the newly inserted text should inherit text properties - from the surrounding non-deleted text. */ + from the surrounding non-deleted text. + If ADJUST_MATCH_DATA, then adjust the match data before calling + signal_after_change. */ /* Note that this does not yet handle markers quite right. Also it needs to record a single undo-entry that does a replacement @@ -1279,7 +1281,8 @@ adjust_after_insert (ptrdiff_t from, ptrdiff_t from_byte, void replace_range (ptrdiff_t from, ptrdiff_t to, Lisp_Object new, - bool prepare, bool inherit, bool markers) + bool prepare, bool inherit, bool markers, + bool adjust_match_data) { ptrdiff_t inschars = SCHARS (new); ptrdiff_t insbytes = SBYTES (new); @@ -1426,6 +1429,9 @@ replace_range (ptrdiff_t from, ptrdiff_t to, Lisp_Object new, MODIFF++; CHARS_MODIFF = MODIFF; + if (adjust_match_data) +update_search_regs (from, to, from + SCHARS (new)); + signal_after_change (from, nchars_del, GPT - from); update_compositions (from, GPT, CHECK_BORDER); } diff --git a/src/lisp.h b/src/lisp.h index 6a98adb..25f811e 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3516,7 +3516,7 @@ extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t); extern void adjust_markers_for_delete (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t); -extern void replace_range
[O] bug#23917: Please consider making Bug #23917 a blocker for 25.1 (was Re: org-capture: Capture template ‘g’: Match data clobbered by buffer modification hooks)
Eli Zaretskii writes: >> From: Stefan Monnier >> Cc: rpl...@gmail.com, 23...@debbugs.gnu.org, alex.ben...@linaro.org, >> jwieg...@gmail.com, nljlistb...@gmail.com >> Date: Tue, 19 Jul 2016 00:48:19 -0400 >> >> > The more general problem is when there's at least one more >> > sub-expression, whose start and/or end are after the new EOB. >> > Those sub-expression's data will be completely bogus after the >> > adjustment, >> >> If they were after the EOB, they were already bogus to start with. > > I think we are mis-communicating. I mean the following scenario: > > Before call to replace_range in replace-match: > >|---|---|--|| >s1 e1 s2e2 EOB > > (s1, e1, etc. are the start and end of the corresponding > sub-expressions.) > > After the call to replace_range in replace-match: > >|-|---|--|| >s1 e1 s2e2 EOB > > IOW, the 1st sub-expression got replaced with a much shorter text, > which made EOB be smaller than the original beginning and end of the > 2nd sub-expression. There's nothing bogus with this, is there? The > user will expect to get match-data adjusted as shown in the second > diagram, and that's what she will really get -- unless there are > buffer-modification hooks that use save-match-data. In the latter > case, what the user will get instead is this: > >|-|---|--|| >s1 EOB > e1 > s2 > e2 > > and that is even before the adjustment code kicks in and makes > "adjustments" with an incorrect adjustment value, which is computed as > > newpoint = search_regs.start[sub] + SCHARS (newtext); > [...] > ptrdiff_t change = newpoint - search_regs.end[sub]; > > and so will use the new EOB as search_regs.end[sub], instead of the > correct original value of e1 from the first diagram above. > > IOW, the call to save-match-data in a buffer-modification hook > _disrupts_ the normal operation of replace-match in this case, by > indirectly sabotaging the adjustment of match data after the > replacement. Is it not possible to adjust the match data *before* calling buffer modification hooks? Seems to me the root of the problem is that buffer modification hooks get to see this invalid intermediate state where the match data is out of sync with the buffer.
[O] bug#23917: Please consider making Bug #23917 a blocker for 25.1 (was Re: org-capture: Capture template ‘g’: Match data clobbered by buffer modification hooks)
Eli Zaretskii writes: >> From: npost...@users.sourceforge.net >> Cc: Eli Zaretskii , 23...@debbugs.gnu.org, >> nljlistb...@gmail.com, jwieg...@gmail.com, rpl...@gmail.com, >> alex.ben...@linaro.org >> Date: Wed, 20 Jul 2016 20:56:28 -0400 >> >> >> Maybe there's a misunderstanding. What Noam suggested was just to >> >> move the code which adjusts search_regs.start[i] and .end[i] to before >> >> the call to replace_range. >> > >> > Oh, right, that's also an option. It might suffer from another problem, >> > which is that the match-data will be broken while the >> > before-change-functions are run, so if there's a save-match-data there >> > we're back to square one. >> >> Solution: adjust in between the before and after change functions. >> Patch below. I think there shouldn't be performance problems, although >> it does add yet another flag to replace_range (by the way, I noticed >> that the MARKERS flags is never 0, so it's redundant). I tested with >> the attached bug-23917-match-data-buffer-modhook.el. > > Thanks. > > Please also make sure bug#23869 is still fixed after this. Following the recipe in http://debbugs.gnu.org/cgi/bugreport.cgi?bug=23869#11 gives me 'Lisp error: (error "Match data clobbered by buffer modification hooks")', that indicates it's still fixed, right?
[O] bug#23917: Please consider making Bug #23917 a blocker for 25.1 (was Re: org-capture: Capture template ‘g’: Match data clobbered by buffer modification hooks)
Eli Zaretskii writes: >> From: npost...@users.sourceforge.net >> Cc: 23...@debbugs.gnu.org, nljlistb...@gmail.com, jwieg...@gmail.com, >> rpl...@gmail.com, monn...@iro.umontreal.ca, alex.ben...@linaro.org >> Date: Wed, 20 Jul 2016 23:00:59 -0400 >> >> > Please also make sure bug#23869 is still fixed after this. >> >> Following the recipe in >> http://debbugs.gnu.org/cgi/bugreport.cgi?bug=23869#11 gives me 'Lisp >> error: (error "Match data clobbered by buffer modification hooks")', >> that indicates it's still fixed, right? > > Yes, but I thought we want to remove the error-out code. Since we now > protect ourselves from clobbered data, we don't need that extra > protection, and I think leaving it in place will cause false positives > (as a few people already reported). That's because the adjustment of > the search registers in the new function you introduce will itself > trigger the error message, won't it? I made the same adjustments to the saved sub_start and sub_end variables, but I had a mistake in that adjustment which caused the false positives. Fixed in the attached v2 patch. We could just drop the check, though I've already found it useful to catch bugs (https://github.com/joaotavora/yasnippet/issues/720). If I drop the checks (see attached v3 patch), then after following the bug#23869 recipe, I get: ## -*- Octave -*- -module(bug). -export([identity/1, is_even/1, size/1, reverse/1]). >From 3e8f9b9f89108bcebf04e06e41a5ce2c719c6ad2 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Wed, 20 Jul 2016 20:15:14 -0400 Subject: [PATCH v2] Adjust match data before calling after-change-funs * src/insdel.c (replace_range): Add new parameter ADJUST_MATCH_DATA, if true call update_search_regs. Update all callers (except Freplace_match) to pass 0 for the new parameter. * src/search.c (update_search_regs): New function, extracted from Freplace_match. (Freplace_match): Remove match data adjustment code, pass 1 for ADJUST_MATCH_DATA to replace_range instead. --- src/cmds.c| 2 +- src/editfns.c | 6 +++--- src/insdel.c | 10 -- src/lisp.h| 4 +++- src/search.c | 52 ++-- 5 files changed, 45 insertions(+), 29 deletions(-) diff --git a/src/cmds.c b/src/cmds.c index 1e44ddd..4003d8b 100644 --- a/src/cmds.c +++ b/src/cmds.c @@ -447,7 +447,7 @@ internal_self_insert (int c, EMACS_INT n) string = concat2 (string, tem); } - replace_range (PT, PT + chars_to_delete, string, 1, 1, 1); + replace_range (PT, PT + chars_to_delete, string, 1, 1, 1, 0); Fforward_char (make_number (n)); } else if (n > 1) diff --git a/src/editfns.c b/src/editfns.c index 412745d..32c8bec 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -3192,7 +3192,7 @@ DEFUN ("subst-char-in-region", Fsubst_char_in_region, /* replace_range is less efficient, because it moves the gap, but it handles combining correctly. */ replace_range (pos, pos + 1, string, - 0, 0, 1); + 0, 0, 1, 0); pos_byte_next = CHAR_TO_BYTE (pos); if (pos_byte_next > pos_byte) /* Before combining happened. We should not increment @@ -3405,7 +3405,7 @@ DEFUN ("translate-region-internal", Ftranslate_region_internal, /* This is less efficient, because it moves the gap, but it should handle multibyte characters correctly. */ string = make_multibyte_string ((char *) str, 1, str_len); - replace_range (pos, pos + 1, string, 1, 0, 1); + replace_range (pos, pos + 1, string, 1, 0, 1, 0); len = str_len; } else @@ -3446,7 +3446,7 @@ DEFUN ("translate-region-internal", Ftranslate_region_internal, { string = Fmake_string (make_number (1), val); } - replace_range (pos, pos + len, string, 1, 0, 1); + replace_range (pos, pos + len, string, 1, 0, 1, 0); pos_byte += SBYTES (string); pos += SCHARS (string); cnt += SCHARS (string); diff --git a/src/insdel.c b/src/insdel.c index 4ad1074..fc3f19f 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -1268,7 +1268,9 @@ adjust_after_insert (ptrdiff_t from, ptrdiff_t from_byte, /* Replace the text from character positions FROM to TO with NEW, If PREPARE, call prepare_to_modify_buffer. If INHERIT, the newly inserted text should inherit text properties - from the surrounding non-deleted text. */ + from the surrounding non-deleted text. + If ADJUST_MATCH_DATA, then adjust the match data before calling + signal_after_change. */ /* Note that this does not yet handle markers quite right. Also it needs to record a single undo-entry that does a replacement @@ -1279,7 +1281,8 @@ adjust_after_insert (ptrdiff_t from, ptrdiff_t from_byte, void replace_range (ptrdiff_t from, ptrdiff_t to, Lisp_Object new, - bool prepare, bool inherit, bool markers) + bool prepare, bool inherit, bool markers, + bool adjust_match_data) { ptrdiff_t inschars = SCHA
[O] bug#23917: Please consider making Bug #23917 a blocker for 25.1 (was Re: org-capture: Capture template ‘g’: Match data clobbered by buffer modification hooks)
tags 23917 fixed close 23917 25.1 quit Eli Zaretskii writes: >> From: npost...@users.sourceforge.net >> Cc: 23...@debbugs.gnu.org, nljlistb...@gmail.com, jwieg...@gmail.com, >> rpl...@gmail.com, monn...@iro.umontreal.ca, alex.ben...@linaro.org >> Date: Thu, 21 Jul 2016 21:08:43 -0400 >> >> I made the same adjustments to the saved sub_start and sub_end >> variables, but I had a mistake in that adjustment which caused the false >> positives. Fixed in the attached v2 patch. We could just drop the >> check, though I've already found it useful to catch bugs >> (https://github.com/joaotavora/yasnippet/issues/720). >> >> If I drop the checks (see attached v3 patch), then after following the >> bug#23869 recipe, I get: >> >> ## -*- Octave -*- >> -module(bug). >> -export([identity/1, is_even/1, size/1, reverse/1]). > > OK, let's wait for a few days to give time to the people who were > affected by the issue to test the patch, and if no new issues come up, > please push the version with the error code to emacs-25. Since they've now reported that the new patch is working well, I've pushed it as e1def617.
[O] bug#25132: 26.0.50; emacs hangs when loading org file with python source blocks
tags 25132 confirmed quit The problem is that org updates its temporary fontification buffer from its fontify rules which are called by jit-lock-function, which means that inhibit-modification-hooks is bound to t. Therefore, when org-src-font-lock-fontify-block calls delete-region to remove leftover text from the previous source block fontification, the `before-change-functions' are not run. In this case `syntax-ppss-flush-cache' is the important function that doesn't get run, so `syntax-propertize--done' is still set from before and messes up python.el's fontification routines. org-src-font-lock-fontify-block(#("python" 0 6 (fontified t)) 19 65) org-fontify-meta-lines-and-blocks-1(172) org-fontify-meta-lines-and-blocks(172) font-lock-fontify-keywords-region(1 172 nil) font-lock-default-fontify-region(1 172 nil) font-lock-fontify-region(1 172) ... jit-lock--run-functions(1 172) jit-lock-fontify-now(1 501) jit-lock-function(1) redisplay_internal\ \(C\ function\)() redisplay() sit-for(2) execute-extended-command(nil "25132-test" "25") funcall-interactively(execute-extended-command nil "25132-test" "25") call-interactively(execute-extended-command nil nil) command-execute(execute-extended-command) (defun org-src-font-lock-fontify-block (lang start end) ... (with-current-buffer (get-buffer-create (concat " org-src-fontification:" (symbol-name lang-mode))) (delete-region (point-min) (point-max)) ;<-- `syntax-propertize--done' not reset here! (insert string " ") ;; so there's a final property change (unless (eq major-mode lang-mode) (funcall lang-mode)) (org-font-lock-ensure) ...) ...) (defun jit-lock-function (start) ... (jit-lock-fontify-now start (+ start jit-lock-chunk-size)) ...) (defun jit-lock-fontify-now (&optional start end) "Fontify current buffer from START to END. Defaults to the whole buffer. END can be out of bounds." (with-buffer-prepared-for-jit-lock ...)) (defmacro with-buffer-prepared-for-jit-lock (&rest body) "Execute BODY in current buffer, overriding several variables. Preserves the `buffer-modified-p' state of the current buffer." (declare (debug t)) `(let ((inhibit-point-motion-hooks t)) (with-silent-modifications ; <-- binds inhibit-modification-hooks to t ,@body)))
[O] bug#25132: 26.0.50; emacs hangs when loading org file with python source blocks
tags 25132 patch quit npost...@users.sourceforge.net writes: > The problem is that org updates its temporary fontification buffer from > its fontify rules which are called by jit-lock-function, which means > that inhibit-modification-hooks is bound to t. Therefore, when > org-src-font-lock-fontify-block calls delete-region to remove leftover text > from > the previous source block fontification, the `before-change-functions' > are not run. In this case `syntax-ppss-flush-cache' is the important > function that doesn't get run, so `syntax-propertize--done' is still set > from before and messes up python.el's fontification routines. I think with-silent-modifications should let-bind inhibit-modification-hooks buffer locally: >From da4f1c0338b2b98f97a553568c4b80872484ee97 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 7 Jan 2017 15:47:37 -0500 Subject: [PATCH v1] Inhibit modification hooks buffer locally `with-silent-modifications' let-binds `inhibit-modification-hooks' to t globally. So modifications to other buffers don't trigger modication hooks. This causes unexpected results when functions called from `jit-lock-function' use temporary buffers and modifies them (Bug#25132). * lisp/subr.el (with-silent-modifications): Bind inhibit-modification-hooks buffer locally. --- lisp/subr.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/subr.el b/lisp/subr.el index 5377416..fe20d68 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3298,7 +3298,8 @@ with-silent-modifications `(let* ((,modified (buffer-modified-p)) (buffer-undo-list t) (inhibit-read-only t) -(inhibit-modification-hooks t)) +(inhibit-modification-hooks + (progn (make-local-variable 'inhibit-modification-hooks) t))) (unwind-protect (progn ,@body) -- 2.9.3 Perhaps the other variables it binds should be buffer local as well? This bug is new in Emacs 25.1, but changing with-silent-modifications is a bit risky. Therefore, I propose the following for the emacs-25 branch: >From 338aa0c37eba0401616e8e02f0143a57edffd486 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 7 Jan 2017 16:05:19 -0500 Subject: [PATCH v1] Call modification hooks in org-src fontify buffers * lisp/org/org-src.el (org-src-font-lock-fontify-block): Let-bind `inhibit-modification-hooks' to nil, since this function can be called from jit-lock-function which binds that variable to t (Bug#25132). --- lisp/org/org-src.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lisp/org/org-src.el b/lisp/org/org-src.el index d01f108..9b66907 100644 --- a/lisp/org/org-src.el +++ b/lisp/org/org-src.el @@ -913,8 +913,9 @@ org-src-font-lock-fontify-block (with-current-buffer (get-buffer-create (concat " org-src-fontification:" (symbol-name lang-mode))) - (delete-region (point-min) (point-max)) - (insert string " ") ;; so there's a final property change + (let ((inhibit-modification-hooks nil)) ; Avoid Bug#25132. + (delete-region (point-min) (point-max)) + (insert string " ")) ;; so there's a final property change (unless (eq major-mode lang-mode) (funcall lang-mode)) (org-font-lock-ensure) (setq pos (point-min)) -- 2.9.3
[O] bug#25132: 26.0.50; emacs hangs when loading org file with python source blocks
Dmitry Gutov writes: > On 08.01.2017 00:20, npost...@users.sourceforge.net wrote: >> -(inhibit-modification-hooks t)) >> +(inhibit-modification-hooks >> + (progn (make-local-variable 'inhibit-modification-hooks) t))) > > Are we not worried that inhibit-modificaiton-hooks will become > buffer-local even after control flow leaves this let*? My feeling is that inhibit-modification-hooks should usually be buffer local anyway. > If we are not, why not make inhibit-modification-hooks always > buffer-local instead? It would have to be in addition to, because even after doing (make-variable-buffer-local 'var), (let ((var 'foo))...) still makes a global binding. `make-variable-buffer-local' only has effect for `setq', which I think will hardly ever happen for `inhibit-modification-hooks'. Actually, I just grepped for inhibit-modification-hooks and the only non-let I found is this: (defun read-passwd (prompt &optional confirm default) ... (minibuffer-with-setup-hook (lambda () ... (setq-local inhibit-modification-hooks nil) ;bug#15501. ...)) ...)
[O] bug#25132: 26.0.50; emacs hangs when loading org file with python source blocks
Clément Pit--Claudel writes: > On 2017-01-19 19:52, npost...@users.sourceforge.net wrote: >> because even after doing (make-variable-buffer-local 'var), (let >> ((var 'foo))...) still makes a global binding. >> `make-variable-buffer-local' only has effect for `setq', which I >> think will hardly ever happen for `inhibit-modification-hooks'. > > On 2017-01-19 19:52, npost...@users.sourceforge.net wrote: >> because even after doing (make-variable-buffer-local 'var), (let >> ((var 'foo))...) still makes a global binding. >> `make-variable-buffer-local' only has effect for `setq', which I >> think will hardly ever happen for `inhibit-modification-hooks'. > > Hi Noam, > > Can you explain a bit more? I'm not sure what you meant. > > I tried the following to illustrate your point: > > (defvar aa 0) > > (with-temp-buffer > (setq-local aa 1) > (let ((b1 (current-buffer))) > (with-temp-buffer > (let ((aa 2)) > (message "In b2: %S" aa) > (with-current-buffer b1 > (message "In b1: %S" aa)) My point was that the setq-local (or make-local-variable) is required and that defvar-local (or make-variable-buffer-local) is not enough. Compare: (defvar-local bb 0) (with-temp-buffer (let ((b1 (current-buffer))) (with-temp-buffer (let ((bb 2)) (message "In b2: %S" bb) (with-current-buffer b1 (message "In b1: %S" bb))
[O] bug#25132: 26.0.50; emacs hangs when loading org file with python source blocks
Dmitry Gutov writes: > On 20.01.2017 03:52, npost...@users.sourceforge.net wrote: > >> My feeling is that inhibit-modification-hooks should usually be buffer >> local anyway. > > Maybe you're right. > > inhibit-read-only, bound nearby, seems to be in the same situation. > >>> If we are not, why not make inhibit-modification-hooks always >>> buffer-local instead? >> >> It would have to be in addition to, because even after doing >> (make-variable-buffer-local 'var), (let ((var 'foo))...) still makes a >> global binding. `make-variable-buffer-local' only has effect for >> `setq', which I think will hardly ever happen for >> `inhibit-modification-hooks'. > > You're right, and that sounds a little too complicated for my taste. > > So, personally, I'd try to fix the particular instance > first. Switching buffers inside with-silent-modifications is not a > very common usage, I think. > > Maybe org-src should itself let-bind the aforementioned variable(s) > where it visits other buffers. Yeah, that works, and is my proposal for emacs-25, but I'm still leaning towards solving this more broadly in with-silent-modifications, probably also add a mention about this to the inhibit-modification-hooks docstring. I think doing the same to inhibit-read-only isn't worth the trouble because if it happens to be let-bound to t in a buffer where it wasn't "supposed" to be, the worst that happens is that an error *isn't* thrown.
[O] bug#25132: 26.0.50; emacs hangs when loading org file with python source blocks
tags 25132 fixed close 25132 25.2 quit npost...@users.sourceforge.net writes: > Dmitry Gutov writes: > >> So, personally, I'd try to fix the particular instance >> first. Switching buffers inside with-silent-modifications is not a >> very common usage, I think. >> >> Maybe org-src should itself let-bind the aforementioned variable(s) >> where it visits other buffers. > > Yeah, that works, and is my proposal for emacs-25, but I'm still leaning > towards solving this more broadly in with-silent-modifications, probably > also add a mention about this to the inhibit-modification-hooks > docstring. I changed my mind. Bug#25561 reminded me about the "Making local to while let-bound!" message. My change to `with-silent-modifications' would trigger that on any nested invocations of `with-silent-modifications' which seems more likely to happen than switching buffers. I've pushed the simpler let-bind in org-src solution [1: ae8264c] to emacs-25. 1: 2017-01-29 11:01:32 -0500 ae8264c5cccf19d5b25a340a605bf2f07de1577e Call modification hooks in org-src fontify buffers