基于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的能力,还难以实现这一功能,不过就是想想也不错!