Context: I want to create a command that can increment a number or character contained within an arbitrary area of a buffer. I've reduced the problem to calling some function to set the text of a narrowed buffer, a la replace-region-contents, with the following additional properties:
- markers that start on either end of the region (including mark and point themselves) stay on either end of the replaced text
- markers that start within the region are bounded by the region (they stay within the region or at either end)
- the positions taken as parameters to the command are not treated specially, and the command does not explicitly set point or mark
- the command does not print any messages
No method I know of so far has all the above properties.
- The best by far is
replace-region-contentsitself, and when the original and resulting strings are similar, it is perfect. But otherwise, the first property is not upheld replace-regexpseems to be appropriate except that it prints messages on every operation- manually deleting and inserting does not respect markers at all
- I thought maybe manually inserting then deleting would be better, but it is not
Is there any function that does what I want? If not, how would I do this myself?
Edit: Prompted by @phils, I tried to reproduce the trouble I was having earlier with replace-region-contents
As requested, here is a recipe / test showing that markers are not preserved by replace-region-contents in the way I'd like for this case:
(progn 'original ; < this symbol will be replaced (setq mark1 (copy-marker 10)) (setq mark2 (copy-marker 19)) (setq replacement "'replacement") ; < with this (replace-region-contents mark1 mark2 (lambda () replacement)) (set-mark mark1) (goto-char mark2) (setq deactivate-mark nil) ;; and I want for markers that surrounded the text before replacement ;; to surround the new text after replacement (cl-assert (eq (marker-position mark1) 10) :show) (cl-assert (eq (marker-position mark2) (+ mark1 (length replacement))) :show) ) second edit: my test was flawed, and my description of the constraints were inaccurate. I have now updated both the conditions and the test.
Having typed all this out, though, I suspect that a "solution" could end up being a bit of a hack, and my approach may be over-engineered. I might just reduce the problem to working with only mark and point, not caring about where other markers end up.
replace-region-contents? Markers outside the region (and I'm assuming that "just outside the region" is what you mean) ought to retain their relative positions. If they don't, pleaseM-x report-emacs-bug. Markers inside the region are subject to the text changes.