当我在 emacs 中使用增量搜索时,我不知道我在整个匹配项中的位置。在 Chrome 浏览器中,它使用“2 of 30”表示位置。我怎样才能在 Emacs 中做到这一点?
问问题
887 次
4 回答
7
这是我第一次尝试实现这一点。
它使用isearch
实现的惰性突出显示,并强制突出显示覆盖整个缓冲区(不仅仅是可见部分)——这会减慢对大缓冲区的搜索。然后它更新显示以包括相对于突出显示的搜索结果的当前位置(总计)。
这样做的缺点是它依赖于被搜索和突出显示的整个缓冲区。而且,有时当您进行下一场比赛时,即使亮点仍然明显存在C-s,显示也会更改。(0 of 1)
但是,这似乎是一个合理的第一次削减。
准备大切割/粘贴:
(require 'isearch)
(defun lazy-highlight-cleanup (&optional force)
"Stop lazy highlighting and remove extra highlighting from current buffer.
FORCE non-nil means do it whether or not `lazy-highlight-cleanup'
is nil. This function is called when exiting an incremental search if
`lazy-highlight-cleanup' is non-nil."
(interactive '(t))
(if (or force lazy-highlight-cleanup)
(while isearch-lazy-highlight-overlays
(delete-overlay (car isearch-lazy-highlight-overlays))
(setq isearch-lazy-highlight-overlays
(cdr isearch-lazy-highlight-overlays))))
(when isearch-lazy-highlight-timer
(cancel-timer isearch-lazy-highlight-timer)
(setq isearch-message-suffix-add "")
(setq isearch-lazy-highlight-timer nil)))
(defun isearch-lazy-highlight-search ()
"Search ahead for the next or previous match, for lazy highlighting.
Attempt to do the search exactly the way the pending Isearch would."
(condition-case nil
(let ((case-fold-search isearch-lazy-highlight-case-fold-search)
(isearch-regexp isearch-lazy-highlight-regexp)
(search-spaces-regexp isearch-lazy-highlight-space-regexp)
(isearch-word isearch-lazy-highlight-word)
(search-invisible nil) ; don't match invisible text
(retry t)
(success nil)
(isearch-forward isearch-lazy-highlight-forward)
(bound (if isearch-lazy-highlight-forward
(min (or isearch-lazy-highlight-end-limit (point-max))
(if isearch-lazy-highlight-wrapped
isearch-lazy-highlight-start
(isearch-window-end)))
(max (or isearch-lazy-highlight-start-limit (point-min))
(if isearch-lazy-highlight-wrapped
isearch-lazy-highlight-end
(isearch-window-start))))))
;; Use a loop like in `isearch-search'.
(while retry
(setq success (isearch-search-string
isearch-lazy-highlight-last-string bound t))
;; Clear RETRY unless the search predicate says
;; to skip this search hit.
(if (or (not success)
(= (point) bound) ; like (bobp) (eobp) in `isearch-search'.
(= (match-beginning 0) (match-end 0))
(funcall isearch-filter-predicate
(match-beginning 0) (match-end 0)))
(setq retry nil)))
success)
(error nil)))
(defun isearch-find-current-overlay ()
(let ((total 0)
(count 1)
(olist isearch-lazy-highlight-overlays))
(while olist
(setq total (1+ total))
(if (< (overlay-end (car olist)) (point))
(setq count (1+ count)))
(setq olist
(cdr olist)))
(cons count total)))
(add-hook 'isearch-update-post-hook 'isearch-count-message)
(defun isearch-count-message ()
(let ((counts (isearch-find-current-overlay)))
(setq isearch-message-suffix-add (format " (%d of %d)" (car counts) (cdr counts)))))
(defun isearch-window-start ()
"force highlight entire buffer"
(point-min))
(defun isearch-window-end ()
"force highlight entire buffer"
(point-max))
(defun isearch-lazy-highlight-update ()
"Update highlighting of other matches for current search."
(let ((max lazy-highlight-max-at-a-time)
(looping t)
nomore)
(with-local-quit
(save-selected-window
(if (and (window-live-p isearch-lazy-highlight-window)
(not (eq (selected-window) isearch-lazy-highlight-window)))
(select-window isearch-lazy-highlight-window))
(save-excursion
(save-match-data
(goto-char (if isearch-lazy-highlight-forward
isearch-lazy-highlight-end
isearch-lazy-highlight-start))
(while looping
(let ((found (isearch-lazy-highlight-search)))
(when max
(setq max (1- max))
(if (<= max 0)
(setq looping nil)))
(if found
(let ((mb (match-beginning 0))
(me (match-end 0)))
(if (= mb me) ;zero-length match
(if isearch-lazy-highlight-forward
(if (= mb (if isearch-lazy-highlight-wrapped
isearch-lazy-highlight-start
(isearch-window-end)))
(setq found nil)
(forward-char 1))
(if (= mb (if isearch-lazy-highlight-wrapped
isearch-lazy-highlight-end
(isearch-window-start)))
(setq found nil)
(forward-char -1)))
;; non-zero-length match
(let ((ov (make-overlay mb me)))
(push ov isearch-lazy-highlight-overlays)
;; 1000 is higher than ediff's 100+,
;; but lower than isearch main overlay's 1001
(overlay-put ov 'priority 1000)
(overlay-put ov 'face lazy-highlight-face)
(overlay-put ov 'window (selected-window))))
(if isearch-lazy-highlight-forward
(setq isearch-lazy-highlight-end (point))
(setq isearch-lazy-highlight-start (point)))))
;; not found or zero-length match at the search bound
(if (not found)
(if isearch-lazy-highlight-wrapped
(setq looping nil
nomore t)
(setq isearch-lazy-highlight-wrapped t)
(if isearch-lazy-highlight-forward
(progn
(setq isearch-lazy-highlight-end (isearch-window-start))
(goto-char (max (or isearch-lazy-highlight-start-limit (point-min))
(isearch-window-start))))
(setq isearch-lazy-highlight-start (isearch-window-end))
(goto-char (min (or isearch-lazy-highlight-end-limit (point-max))
(isearch-window-end))))))))
(unless nomore
(setq isearch-lazy-highlight-timer
(run-at-time lazy-highlight-interval nil
'isearch-lazy-highlight-update)))))))))
于 2013-02-08T06:59:33.580 回答
7
前几天我看到了这个:
https://github.com/syohex/emacs-anzu
anzu.el 是 anzu.vim 的 Emacs 端口。anzu.el 提供了一种次要模式,该模式在各种搜索模式下的模式行中显示当前匹配和总匹配信息。
github页面上的截图是其功能的gif动画。
于 2014-08-31T10:29:39.747 回答
2
开箱即用,您可以使用M-sowhile isearch 来至少查看匹配的总数(即使不幸的是它还不够聪明,无法跟踪您在原始缓冲区中的匹配)。
于 2013-02-08T05:41:00.623 回答
1
将以下内容添加到您的 emacs 初始化文件中。尽管使用了计数匹配,但它在我的笔记本电脑上运行得非常快。我还没有尝试过非常大的文件。
(defun my-isearch-update-post-hook()
(let (suffix num-before num-after num-total)
(setq num-before (count-matches isearch-string (point-min) (point)))
(setq num-after (count-matches isearch-string (point) (point-max)))
(setq num-total (+ num-before num-after))
(setq suffix (if (= num-total 0)
""
(format " [%d of %d]" num-before num-total)))
(setq isearch-message-suffix-add suffix)
(isearch-message)))
(add-hook 'isearch-update-post-hook 'my-isearch-update-post-hook)
于 2016-03-30T00:10:03.477 回答