基于 counsel 的超级好用的高亮搜索功能
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 中的关键字。
举个例子,我希望能做到
- 执行
M-x counsel-spotlight
然后输入caustic
会返回一堆内容中包含caustic
的文件。 - 按下某个快捷键,会弹出一个新的counsel,输入
chandra
会搜索出文件名中包含chandra
的那些文件。 - 选中文件后按下回车,Emacs会打开该文件,并用swiper搜索原始的那个搜索关键字
caustic
。
基于我目前 lisp 的能力,还难以实现这一功能,不过就是想想也不错。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论