结合ivy来使用bm-bookmarks
我一直都在用 bm 来在多个buffer中的固定位置进行跳转。
最开始的时候,是直接使用bm提供的show,next等函数来进行跳转。
然后我发现了 helm-bm 可以利用helm来进行交互式的选择。
但是,我发现其实这样的效率也不是特别高。毕竟有时候,如果bm的bookmark太多时,只看那一行的内容是不太好确定跳转过去的是自己需要的位置。
然后我发现swiper-all这个函数,可以在搜索buffer的字符的时候,提供预览的功能。我感觉这个功能很实用。
网上搜了一下,在 reddit 上有人实现了一个简单的版本。 只是这个版本和helm-bm一样,没有提供预览的功能。于是我在它的基础上, 添加了update-fn ,这样就可以在选择的时候先查看一下是否需要跳到这里:
(defun bm-counsel-get-list (bookmark-overlays) (-map (lambda (bm) (with-current-buffer (overlay-buffer bm) (let* ((line (replace-regexp-in-string "\n$" "" (buffer-substring (overlay-start bm) (overlay-end bm)))) ;; line numbers start on 1 (line-num (+ 1 (count-lines (point-min) (overlay-start bm)))) (name (format "%s:%d - %s" (buffer-name) line-num line))) `(,name . ,bm)))) bookmark-overlays)) (defun counsel-bm-update-input () "Update fn for counsel-bm." (with-ivy-window (when (> (length (ivy-state-current ivy-last)) 0) (let* ((chosen (ivy-state-current ivy-last)) (bookmark (gethash chosen bm-hash-table))) (if chosen (save-restriction (with-ivy-window (switch-to-buffer (overlay-buffer bookmark)) (bm-goto bookmark))) nil))))) (defun counsel-bm (&optional initial-input) "Use ivy to select bm bookmarks. It has the ability to preview the bookmarks like `swiper-all'." (interactive) (let* ((bm-list (bm-counsel-get-list (bm-overlays-lifo-order t))) (bm-hash-table (make-hash-table :test 'equal)) (search-list (-map (lambda (bm) (car bm)) bm-list))) (-each bm-list (lambda (bm) (puthash (car bm) (cdr bm) bm-hash-table))) (if search-list (ivy-read "Find bookmark: " search-list :keymap counsel-describe-map :action (lambda (chosen) (let ((bookmark (gethash chosen bm-hash-table))) (switch-to-buffer (overlay-buffer bookmark)) (bm-goto bookmark))) :update-fn #'counsel-bm-update-input :initial-input initial-input :caller 'counsel-bm ) (message "%s" "No bookmark now.")))) (defun counsel-bm-from-isearch () "Invoke `counsel-bmr' from isearch." (interactive) (let ((query (if isearch-regexp isearch-string (regexp-quote isearch-string)))) (isearch-exit) (counsel-bm query))) (provide 'counsel-bm)
还有一个counsel-bm-from-isearch,可以在isearch搜索的时候,或者完成isearch搜索后调用。我是把它绑定到了isearch-mode-map上:
(define-key isearch-mode-map (kbd "<M-return>") 'counsel-bm-from-isearch)
设置好bm的bookmark后,直接使用counsel-bm就可以了。效果如下图:
如果你觉得本文不错,欢迎 donate