Fanael / edit-indirect

Edit regions in separate buffers
99 stars 23 forks source link

Buffer-local hooks on edit-indirect-after-creation-hook are run twice #16

Closed dsedivec closed 4 years ago

dsedivec commented 4 years ago

Buffer-local hooks added to edit-indirect-after-creation-hook are run twice. I think this reproduces the issue:

;; testcase.el
(require 'edit-indirect)

(defun test-hook ()
  (message "`test-hook' is being run"))

(with-temp-buffer
  (add-hook 'edit-indirect-after-creation-hook #'test-hook nil t)
  (edit-indirect-region (point-min) (point-max)))
~/.emacs.d/elpa/edit-indirect-20191103.1013 $ emacs --batch -L $PWD --load testcase.el
‘test-hook’ is being run
‘test-hook’ is being run

I suspect the problem is here in edit-indirect--create-indirect-buffer: https://github.com/Fanael/edit-indirect/blob/935ded353b9ed3da67bc61abf245c21b58d88864/edit-indirect.el#L295-L298

I think what's happening is that you're let-binding the global value of edit-indirect-after-creation-hook, which has t as its last element in my case. run-hooks then encounters the t so it runs the global value of edit-indirect-after-creation-hook again—without noticing that the local value is the global value since you've let-bound it there (important bits from Emacs C source). This is arguably a bug in run-hooks, or at least an oversight, given that it tries to ignore t in the global value for a hook variable.

I'm not sure I have a great suggestion for how to solve this! Maybe copy the parent buffer's buffer-local edit-indirect-after-creation-hook to the indirect buffer—if and only if the parent buffer has a buffer-local value? That's probably simplest. Then you can just run-hooks in the indirect buffer without having to let-bind edit-indirect-after-creation-hook. run-hooks will then see the correct buffer-local and global values.


Thanks for this module! It's super-helpful. In case you're wondering, what I'm doing is removing the indent from a fenced code block in Markdown buffer before I edit the source within via edit-indirect. In markdown-mode buffers I add buffer-local edit-indirect hooks in markdown-mode-hook. Let me know if you want to see the code (which is much longer than the example above).

Fanael commented 4 years ago

Nice catch, thanks! Should be fixed now.