7

If I have a long document that I run query-replace (or any other number of commands) in, as I'm saying y or n to replace that match or not, the current potential item to be replaced is always at the bottom of the window.

I'd like to be able to see more of what's below this match, to see the context a little more easily --- effectively, hitting C-l after each match update.

I could probably find some specific hooks that run at the point a new match is found to do this for me, but is there a more generic way of doing things, not involving writing a hook for each function that has this behaviour? (It seems pretty general.)

3 Answers 3

5

Set the variable scroll-margin to some value such as 5 or 10, then the point where the current replace candidate is will always be at least this number of lines from the bottom of the screen. By default the value is 0, which allows the point to sit on the final line of the screen.

From the documentation:

scroll-margin

...

Number of lines of margin at the top and bottom of a window. Recenter the window whenever point gets within this many lines of the top or bottom of the window.

You can set a temporary value of scroll-margin for most of the interactive replace functions by advising perform-replace:

(defun afs/scroll-margin-perform-replace (orig-function from-string replacements
                        query-flag regexp-flag delimited-flag
                        &optional repeat-count map start end backward)
  "Set scroll-margin temporarily while running perform-replace"
  (let ((scroll-margin 5))
    (apply orig-function from-string replacements
                        query-flag regexp-flag delimited-flag
                        repeat-count map start end backward)))

(advice-add 'perform-replace :around #'afs/scroll-margin-perform-replace)
1
  • Thanks, this variable is new to me. As Drew says, it might be do more than I want, but I'll try it. For those following at home, I'm adding to my emacs config: (setq scroll-margin 3). Apr 25, 2015 at 9:47
3

I see nothing in the code that would help with this, out of the box.

I would say that you should consider filing an enhancement request (M-x report-emacs-bug).

  • Consider requesting a hook to be run after point is moved to the next search hit and before reading your input char.

  • Another possibility is to request that recenter be called at that time, with users having the possibility of customizing which member of recenter-positions to start with (so that C-l would then move to the next member).


As @AndrewSwann says, you can also customize scroll-margin, but that seems like overkill. You could also write your own wrapper command for each query-replace command, in which you bind scroll-margin to what you want for query-replacing. That would not affect the global value of the option.

3
  • Thanks; that's what I was thinking about (and/or defadvice), but scroll-margin is new to me, and might just be what I want. I notice that when I scroll anyway (with C-n, Mac, 24.5.1), point never gets close to the bottom of the window anyway: seems to stay a good 7 lines or so away from it before scrolling. I will try a small value of scroll-margin and see how it goes. Apr 25, 2015 at 9:44
  • Whether scroll-margin gives you what you need in this case is really orthogonal to the benefit of the enhancement requests I suggested. IOW, it might give you what you request, and if so then it answers the question you posed. But a hook or automatic recentering might be useful generally.
    – Drew
    Apr 25, 2015 at 14:37
  • Very true Drew; I'll file an enhancement request. Apr 26, 2015 at 8:57
1

When Emacs 25.1 is released, this will be as simple as just (add-hook 'replace-update-post-hook 'recenter)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.