简体   繁体   English

“1中的n”结果用于Emacs搜索

[英]“1 of n” result for Emacs search

When I use incremental search in emacs I can't know where I am in whole matches. 当我在emacs中使用增量搜索时,我无法知道我在整场比赛中的位置。 In Chrome browser it says location using "2 of 30". 在Chrome浏览器中,它使用“2 of 30”表示位置。 How can I do that in Emacs? 我怎么能在Emacs中做到这一点?

Here's my first attempt to implement this. 这是我第一次尝试实现这一点。

It uses the lazy highlighting that isearch implements, and forces the highlighting to cover the entire buffer (not just the visible portions) - which can slow down the search on large buffers. 它使用isearch实现的延迟突出显示,并强制突出显示覆盖整个缓冲区(不仅仅是可见部分) - 这会减慢对大缓冲区的搜索速度。 It then updates the display to include a current position (of total) relative to the highlighted search results. 然后,它更新显示以包括相对于突出显示的搜索结果的当前位置(总计)。

This has the drawback that it is dependent on the entire buffer being searched and highlighted. 这具有以下缺点:它依赖于被搜索和突出显示的整个缓冲区。 And, sometimes when you Cs to the next match, the display changes to (0 of 1) even though the highlights are clearly still present. 并且,有时当您将Cs转到下一场比赛时,即使高光显然仍然存在,显示也会变为(0 of 1)

But, it seems to be a reasonable first cut. 但是,它似乎是一个合理的第一次削减。

Prepare for big cut/paste: 准备大切/粘贴:

(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)))))))))

I saw this the other day: 前几天我看到了这个:

https://github.com/syohex/emacs-anzu https://github.com/syohex/emacs-anzu

anzu.el is an Emacs port of anzu.vim. anzu.el是anzu.vim的Emacs端口。 anzu.el provides a minor mode which displays current match and total matches information in the mode-line in various search modes. anzu.el提供了一种次要模式,它在各种搜索模式下以模式行显示当前匹配和总匹配信息。

The screenshot on the github page is a gif animation of its functionality. github页面上的屏幕截图是其功能的gif动画。

开箱即用,你可以在isearching时使用Ms o至少看到匹配的总数(即使遗憾的是它不够聪明,无法跟踪你在原始缓冲区中的匹配)。

Add the following to your emacs init file. 将以下内容添加到emacs init文件中。 Despite the use of count-matches, it works very fast on my laptop. 尽管使用了计数匹配,它在我的笔记本电脑上工作得非常快。 I have not tried it with very large files. 我没有尝试过非常大的文件。

(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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM