swiper提供新的swiper-isearch命令

如果一行中有多个命中,他就重复显示该行多次。功能上是比之前那个强了,但是显示效果就见仁见智了。

1 个赞

counsel-grep-or-swiper 一样弄一个swiper-or-isearch,文件超大时用swiper-isearch, 默认用swiper。这样是否就解决问题了?

话说,使用swiper,一行中有多个命中的情况下,如何移动光标到某一个命中,有什么好的办法?

文章里有提到:swiper-avy C-' swiper-isearch里直接C-s就行了。

1 个赞

我这里swiper-avy 也只能定位到行

哦,可以定位到行内的多个匹配。

试了一下 15MB+ 的文件,没有感觉到 swiper-isearchcounsel-grep-or-swiper 之间的差距。

就是说swiper-isearch达到了grep的性能水平了?

其实我感觉作者就是想用它来替代默认的isearch啦。所以专门做了一个不是line-base的swiper-isearch

这个就是swiper-isearch命令的由来。swiper是line-base的。达不到你想要的效果的。

swiper-iserach不是line-base的,所以这个命令才可以。

其实吧,我还是觉得搜buffer还是isearch最快。我一般是先isearch来搜。然后有

(defun swiper-from-isearch ()
  "Invoke `swiper' from isearch."
  (interactive)
  (let ((query (if isearch-regexp
                   isearch-string
                 (regexp-quote isearch-string))))
    (isearch-exit)
    (swiper query)))

这个函数,在isearch的时候我绑到 C-return

(define-key isearch-mode-map (kbd "<C-return>") 'swiper-isearch-from-isearch)

就可以方便使用swiper。

这下swiper-isearch出来,就照着封一个来用:

(defun swiper-isearch-from-isearch ()
  "Invoke `swiper-isearch' from isearch."
  (interactive)
  (let ((query (if isearch-regexp
                   isearch-string
                 (regexp-quote isearch-string))))
    (isearch-exit)
    (swiper-isearch query)))

然后我又为swiper封了一个这个函数:

(defvar my-last-swiper-to-counsel-rg-search ""
  "Save current swiper input for using in `swiper-toggle-counsel-rg'.")

(defun swiper-toggle-counsel-rg ()
  "Toggle `counsel-rg' with current swiper input."
  (interactive)
  (let ((text (replace-regexp-in-string
               "\n" ""
               (replace-regexp-in-string "^.*Swiper: " "" (thing-at-point 'line t)))))
    (setq my-last-swiper-to-counsel-rg-search text)
    (ivy-quit-and-run
      (counsel-rg my-last-swiper-to-counsel-rg-search default-directory))))

这样又可以在swiper中调counsel-rg来搜当前目录。

还有一个函数在swiper中调color-rg:

(defun swiper-toggle-color-rg ()
  "Toggle `color-rg' with current swiper input."
  (interactive)
  (let ((text (replace-regexp-in-string
               "\n" ""
               (replace-regexp-in-string "^.*Swiper: " "" (thing-at-point 'line t)))))
    (setq my-last-swiper-to-counsel-rg-search text)
    (ivy-quit-and-run
      (color-rg-search-input my-last-swiper-to-counsel-rg-search default-directory))))

最后绑定按键:

(define-key ivy-minibuffer-map (kbd "<M-return>") 'swiper-toggle-counsel-rg)
(define-key ivy-minibuffer-map (kbd "<C-return>") 'swiper-toggle-color-rg)

所以最开始,直接用isearch搜,很快,然后想看当前bufer的全部,就c-return调swiper-isearch-from-isearch。然后还想看当前目录的全部,就又C-return调swiper-toggle-color-rg或者M-return调swiper-toggle-counsel-rg。

感觉实际使用起来不错的。

2 个赞

就是有时搜索完发现后悔了,只想回到原来的位置,才用swiper。

2 个赞

swiper-isearch,很难忍受的一点是,见仁见智,一行多个命中,在mini buffer里会显示多行,感觉minibuffer已经不是一个命中摘要了

这是个这种方案吧,否则又无法显示一行中的多个命中,并跳转到其中一个了。

思路不错,有不少可借鉴之处。不过有个疑问,在我看来isearch 的唯一优势就是速度。但是绝大多数情况下都可能切换到 swiper 继续搜索,那岂不是多此一举,又多增加按键次数?

swiper 中调用counsel-rg 确实比较实用。我没有使用color-rg,用的是rg.el代替,功能更强悍,也可以按照你的思路集成。

搜索时其实还有一个痛点,尤其是isearch。就是在搜索时默认是什么都不显示的,但是大多数情况下其实我就是想搜索当前光标下的符号或者字符串。在我的配置中,我是这样处理的:启动 swiper,默认输入当前光标下的符号并显示为灰色;如果输入其他字符,灰色部分的默认输入会清除,只搜索重新输入的字符。后续再集成 counsel-rg 之类的就更合理了。

还是个人喜好吧。我觉得isearch快就是最大的优势。平时我还是用isearch最多。irc里面有些人不是把isearch当搜索的,感觉是把isearch是定位为光标移动。我就是不喜欢大buffer搜索的时候swiper卡卡的感觉,而如果由isearch再到swiper,由于isearch中肯定是输入了字符了,相当于过滤过了,这样swiper或者swiper-isearch在大的buffer里面也还行。哈哈。我总结过一份isearch的文章 一份isearch的使用总结 。其实isearch配置好了,真的是很好用。不过也得承认,swiper,把搜索变得更直观了,洋文是不是叫interactive? 这个完全是看个人爱好了,我曾经好几次把默认搜索都换成swiper了,还是不习惯,又改回来isearch :frowning:

rg.el我参考了很多它的代码,然后把它加到了color-rg中。相比而言,我现在更喜欢用color-rg了。更简单,重构更不易出错。当然,也可能是我对color-rg的代码比较熟悉 :slight_smile:

这个功能确实是很需要的。我用的xah-fly-keys,它有一个函数:

(defun xah-search-current-word ()
  "Call `isearch' on current word or text selection.
“word” here is A to Z, a to z, and hyphen 「-」 and underline 「_」, independent of syntax table.
URL `http://ergoemacs.org/emacs/modernization_isearch.html'
Version 2015-04-09"
  (interactive)
  (let ( $p1 $p2 )
    (if (use-region-p)
        (progn
          (setq $p1 (region-beginning))
          (setq $p2 (region-end)))
      (save-excursion
        (skip-chars-backward "-_A-Za-z0-9")
        (setq $p1 (point))
        (right-char)
        (skip-chars-forward "-_A-Za-z0-9")
        (setq $p2 (point))))
    (setq mark-active nil)
    (when (< $p1 (point))
      (goto-char $p1))
    (isearch-mode t)
    (isearch-yank-string (buffer-substring-no-properties $p1 $p2))))

默认是以当前光标的符号来isearch。它还支持选中,也就是说,如果你选中了一段字符,就直接以选中的这段字符为intial-input调用isearch。

1 个赞

嗯,很多其实就是习惯问题,只要自己用起来舒服效率高就好。

确实看到借鉴了很多rg.el的 feature,进步很明显。

这个逻辑确实好用,我也在 swiper 里也实现了,效果如下:

emacs

1 个赞

棒棒哒,哈哈哈

counsel的describe-function等等原版就是这样的,swiper没有,我也想要,求抄。

还不完全一样,counsel-describe-function只会选中而不会在prompt上显示candidate。

参考:

2 个赞