根据@juanleon 的建议玩了一下代码后,我得到了这个:
;; Execute after each update in isearch-mode
(setq isearch-update-post-hook 'show-whole-line)
(defun show-whole-line ()
"Scroll such that the whole line (which contains the point) will be visible."
;; If it is the top part which is truncated
(if (not (pos-visible-in-window-p (line-beginning-position)))
(let
((amount
;; the required number of lines to scroll
(ceiling (/
(- (window-start)
(line-beginning-position))
(float (window-body-width))))))
;; don't scroll at all if the search result will be scrolled out
(if (< amount (/
(- (window-end)
(point) )
(float (window-body-width))))
(scroll-down amount)))
;; Else
(if (not (pos-visible-in-window-p (line-end-position)))
(let
((amount
(min
;; the required number of lines to scroll
(ceiling (/
(-
(line-end-position)
(window-end (selected-window) t))
(float (window-body-width))) )
;; however not to scroll out the first line
(/ (- (line-beginning-position) (window-start)) (window-body-width)))))
(scroll-up amount)))))
几个解释:
- 设置
defadvice
为isearch-forward
不够 - 当您将字符添加到搜索字符串时,不会再次调用此函数。在快速查看 isearch.el.gz 包后,我决定建议isearch-update
运行。这也消除了为isearch-repeat-forward
等添加单独建议的需要。后来我注意到有一个预定义的钩子isearch-update
,因此这里不需要defadvice
。
show-whole-line
函数检查当前行的开头是否可见。如果没有,它会向下滚动以显示行的开头,除非这种滚动会导致隐藏搜索匹配本身。
- 如果行首可见,则
show-whole-line
检查行尾是否也可见。如果没有,它会向上滚动以显示行尾,除非这种滚动会导致隐藏行首。我更喜欢能够看到行的开头。
这个函数和一个钩子工作得很好,但是有一个烦人的事情:当你最初按 Cs 时调用这个函数(在你输入任何搜索字符串之前)。这意味着如果该点位于其开头或结尾超出窗口的行,则简单调用 Cs 将导致以某种方式滚动。
虽然一点都不重要,但我很高兴听到如何消除上述副作用的建议。