基于 counsel 的超级好用的高亮搜索功能

发布于 2023-06-26 12:17:35 字数 3129 浏览 39 评论 0

abo-abo 写过一篇 博文,阐述了如何利用 counsel,ivy 以及 swiper 来搜索由 recoll(一种搜索工具)索引过的文件的内容。受此文的影响,我也尝试将之迁移到 Mac 上。下面是我的尝试说明。

使用 counsel 能够让我们以递增的方式更新搜索结果(该搜索结果由命令行工具 mdfind 返回)。选中一个文件后,emacs 会打开它,并且若该文件不是 pdf 的话,还会调用 swiper 来搜索该文件。

一切都很顺利。唯一的问题是,我想优先显示org文件,然后再是 tex 文件,但是不知道为何,我的排序函数在 ivy 中不太正常。我的 Lisp 水平不是很高,希望其他人可以帮忙看出问题所在。

UPDATE: 在问题在更新 ivy 和 counsel 后已经被修复了,下面的排序命令可以正常是用了。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; counsel-spotlight                                                      ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Incrementally search the Mac spotlight database and open matching
;; files with a swiper search on the query text.
;; Based on http://oremacs.com/2015/07/27/counsel-recoll/

(require 'counsel)

;; Function to be called by counsel-spotlight
;; The onlyin option limits results to my home directory
;; and directories below that
;; mdfind is the command-line interface to spotlight
(defun counsel-mdfind-function (string &rest _unused)
  "Issue mdfind for STRING."
  (if (< (length string) 4)
      (counsel-more-chars 4)
    (counsel--async-command
      (format "mdfind -onlyin ~/ '%s'" string))
    nil))

;; Main function
(defun counsel-spotlight (&optional initial-input)
  "Search for a string in the mdfind database.
You'll be given a list of files that match.
Selecting a file will launch `swiper' for that file.
INITIAL-INPUT can be given as the initial minibuffer input."
  (interactive)
  (ivy-read "spotlight: " 'counsel-mdfind-function
            :initial-input initial-input
            :dynamic-collection t
            :sort t
            :action (lambda (x)
                      (when (string-match "\\(\/.*\\)\\'" x)
                        (let ((file-name (match-string 1 x)))
                          (find-file file-name)
                          (unless (string-match "pdf$" x)
                            (swiper ivy-text)))))))

;; Define my sort function
(defun bjm-counsel-mdfind-sort-function (x y)
  "Compare two files X and Y. Prioritise org then tex."
  (if (string-match "org$" x)
      t
    (if (string-match "tex$" x)
        (if (string-match "org$" y)
            nil
          t)
      nil)))

;; Add to list of ivy sorting functions
(add-to-list 'ivy-sort-functions-alist
              '(counsel-mdfind-function . bjm-counsel-mdfind-sort-function))

在理想情况下,我希望能够实现用另一个 counsel 来减少 mdfind 搜索出文件名的匹配项,然后在第二个 counsel 中选中的文件会通过 swiper 搜索第一个 counsel 中的关键字。

举个例子,我希望能做到

  1. 执行 M-x counsel-spotlight 然后输入 caustic 会返回一堆内容中包含 caustic 的文件。
  2. 按下某个快捷键,会弹出一个新的counsel,输入 chandra 会搜索出文件名中包含 chandra 的那些文件。
  3. 选中文件后按下回车,Emacs会打开该文件,并用swiper搜索原始的那个搜索关键字 caustic

基于我目前 lisp 的能力,还难以实现这一功能,不过就是想想也不错。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

时光礼记

暂无简介

0 文章
0 评论
24 人气
更多

推荐作者

金兰素衣

文章 0 评论 0

ゃ人海孤独症

文章 0 评论 0

一枫情书

文章 0 评论 0

清晰传感

文章 0 评论 0

mb_XvqQsWhl

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文