10

Thank you very much in advance for helping.

In Emacs, I like to use iseach-forward (C-s) but I'd like it ever more if the highlighted fount words would be centered in the middle of the screen instead of at the very bottom.

I find myself doing this continuously:

C-s foo C-s C-s C-s... oh! that's the 'foo' I was looking for! C-l

Is there a way to center the search results in the middle of the screen?

Cheers

RafaelGP
  • 1,749
  • 6
  • 20
  • 35

6 Answers6

6

Best approach would probably be to add the following hook:

(add-hook 'isearch-mode-end-hook 'recenter-top-bottom)

This will execute the recenter-top-bottom command at the completion of every successful incremental search.

Edit: I've investigated a bit, and the functions that are executed on repeated searches for the same string (i.e., with successive input of C-s or C-r during an active search) appear to be isearch-repeat-forward and/or isearch-repeat-backward. Hence, if you wish to recenter on every repeat as well, you need to advise said functions in addition to defining the above hook, like so:

(defadvice
  isearch-repeat-forward
  (after isearch-repeat-forward-recenter activate)
  (recenter-top-bottom))

(defadvice
  isearch-repeat-backward
  (after isearch-repeat-backward-recenter activate)
  (recenter-top-bottom))

(ad-activate 'isearch-repeat-forward)
(ad-activate 'isearch-repeat-backward)

Personally, I find the resulting behavior to be extremely annoying and disorienting, but de gustibus non est disputandum. Perhaps reserving recenter-top-bottom for use in the initial isearch-mode-end-hook and using recenter alone in the advice to the repeat functions would be less obnoxious.

Advising isearch-forward by itself is equivalent to adding the hook I originally suggested above and seemingly has no effect on repeat searches. Adding the hook is simpler and I think more idiomatic, so it should probably be preferred over advising the function.

Greg E.
  • 2,722
  • 1
  • 16
  • 22
4

Thank you Nicolas and Greg.

Your suggestions pointed me to the right direction. This is the code to accomplish what I was asking for:

(defadvice
    evil-search-forward
    (after evil-search-forward-recenter activate)
    (recenter))
(ad-activate 'evil-search-forward)

(defadvice
    evil-search-next
    (after evil-search-next-recenter activate)
    (recenter))
(ad-activate 'evil-search-next)

(defadvice
    evil-search-previous
    (after evil-search-previous-recenter activate)
    (recenter))
(ad-activate 'evil-search-previous)

Explanation:

I didn't want to get things more complicated adding that I use Evil (vim mode in Emacs), so I omitted that in my question.

I use defadvice to search forward, to move to the next searched item and to move to the previous searched item.

Something worth to mention is that I didn't use (recenter-top-bottom) function. The behaviour was crazy as it centered the first searched item in the middle of the screen, centered the second one to the top, and the third one to the bottom. I just used the function 'recenter' to center it always to the middle of the screen.

For not Evil users the code would look like this: (Not tested!)

(defadvice
    isearch-forward
    (after isearch-forward-recenter activate)
    (recenter))
(ad-activate 'isearch-forward)

(defadvice
    isearch-repeat-forward
    (after isearch-repeat-forward-recenter activate)
    (recenter))
(ad-activate 'isearch-repeat-forward)

(defadvice
    isearch-repeat-backward
    (after isearch-repeat-backward-recenter activate)
    (recenter))
(ad-activate 'isearch-repeat-backward)

Cheers!

RafaelGP
  • 1,749
  • 6
  • 20
  • 35
  • Good, but DOES NOT center the very first search result if the search string is pasted in (C-y). It DOES center if the search string is typed in. Ideas? – Kirill Yunussov May 14 '19 at 16:51
1

You could use defadvice to run recenter-top-bottom after isearch-forward.

Nicolas Dudebout
  • 9,172
  • 2
  • 34
  • 43
1

For other folks like me who came here looking to configure their spacemacs, @RafaelGP's answer worked for me, with a slight modification: all of the evil functions have -ex- in them, like this:

 (defadvice
      evil-ex-search-forward
      (after evil-search-forward-recenter activate)
    (recenter))
  (ad-activate 'evil-ex-search-forward)

  (defadvice
      evil-ex-search-next
      (after evil-search-next-recenter activate)
    (recenter))
  (ad-activate 'evil-ex-search-next)

  (defadvice
      evil-ex-search-previous
      (after evil-search-previous-recenter activate)
    (recenter))
  (ad-activate 'evil-ex-search-previous)
0

Setting scroll-margin to a huge value (so that it's greater than half the maximum possible window height), say 250, and maximum-scroll-margin to 0.5 achieves the desired effect. Both are found in customize group "Windows".

However, this obviously does not only affect isearch. So in practice, you might want to set more reasonable values of 10 and 0.25, for example. This approximates recentering, but is not too awkward for general scrolling.

EndlosSchleife
  • 515
  • 7
  • 19
0

Since some of the most voted answers are dated, here is another one. Advices should always be the last resort when there is no hook to add functions to. Even then, the newer way to add an advice is advice-add. However, in this case we do have a hook.

C-h f isearch-update:

[snip]

This is called after every isearch command to update the display.
The second last thing it does is to run ‘isearch-update-post-hook’.
The last thing is to trigger a new round of lazy highlighting.

[snip]

So simply adding recenter to isearch-update-post-hook should be enough. Here is my use-package configuration for it.

;; isearch
(use-package isearch
  :custom (isearch-wrap-pause 'no)
  :config
    (defun post-isearch ()
      (unless (isearch-fail-pos) (recenter)))
  :hook (isearch-update-post . post-isearch)
  :bind (:map isearch-mode-map ("C-v" . isearch-yank-kill)))
scribe
  • 673
  • 2
  • 6
  • 17