加载ivy-xref.el,执行xref-find-{definitions,references}
后,我经常按M-SPC c
启用calling mode,按j k
自动跳转到上一个/下一个xref item。有没有办法自动启用calling mode?感觉这样有些时候会比lsp-ui-peek-find-{definitions,references}
好用。
lsp-ui-peek用于workspace/symbol效果不好,因为它会根据文件名归类xref items,但language server返回的结果通常已经是按相关度排序过的
(defun ivy-xref-show-xrefs (xrefs _alist)
(minibuffer-with-setup-hook #'ivy-toggle-calling
(ivy-read "xref: " (ivy-xref-make-collection xrefs)
:require-match t
:action #'ivy-xref-select)))
(setq xref-show-xrefs-function #'ivy-xref-show-xrefs)
感謝。用了這個
(with-eval-after-load 'ivy-xref
(defun ivy-xref-show-xrefs (xrefs alist)
(minibuffer-with-setup-hook #'hydra-ivy/body
(minibuffer-with-setup-hook #'ivy-toggle-calling
(ivy-read "xref: " (ivy-xref-make-collection xrefs)
:require-match t
:sort t
:action #'(lambda (candidate)
(xref--show-location (cdr candidate) 'quit)))))))
@tumashu 用了上面這個(setq xref-show-xrefs-function #'ivy-xref-show-xrefs)
,ivy-posframe在跳轉時會閃爍,有解嗎?
个人觉得swiper/xref这种不适合用ivy-posframe,因为会挡住正文
嗯。套了個 dynamic scope (elisp真好)
(with-eval-after-load 'ivy-xref
(defun ivy-xref-show-xrefs (xrefs alist)
(let (ivy-display-function)
(minibuffer-with-setup-hook #'hydra-ivy/body
(minibuffer-with-setup-hook #'ivy-toggle-calling
(ivy-read "xref: " (ivy-xref-make-collection xrefs)
:require-match t
:action #'(lambda (candidate)
(xref--show-location (cdr candidate) 'quit))))))))
@amosbird ivy-xref-select
不知道哪裏定義的
(希望有人改進我的暴力實現 https://github.com/emacs-lsp/lsp-ui/blob/master/lsp-ui.el#L135)
ivy 可以设置什么命令用ivy-posframe的
@MaskRay oops, 忘记粘贴了。那个函数和你的lambda差不多
ivy-display-functions-alist
ivy-posframe的主页有写😂
我直接把ivy-xref-show-xrefs
或xref-find-references
放進去是不行的。
等amosbird折騰出來,我再抄了
(defun xref--find-xrefs (input kind arg display-action)
(let ((xrefs (funcall (intern (format "xref-backend-%s" kind))
(xref-find-backend)
arg)))
(unless xrefs
(user-error "No %s found for: %s" (symbol-name kind) input))
(ivy-read "Find References: " (ivy-xref-make-collection xrefs)
:action (lambda (x)
(let ((location (cdr x)))
(let* ((marker (xref-location-marker location))
(buf (marker-buffer marker))
(xref-buffer (current-buffer)))
(if (not (eq buf xref-buffer))
(switch-to-buffer buf))
(goto-char marker)))))))
我改成了这样 ivy-call在退出的时候依然不能jump回起点,不知道swiper是咋做到的
终于可以了
(defun xref--find-xrefs (input kind arg display-action)
(let ((xrefs (funcall (intern (format "xref-backend-%s" kind))
(xref-find-backend)
arg)))
(unless xrefs
(user-error "No %s found for: %s" (symbol-name kind) input))
(let ((xref-pos (point))
(xref-buffer (current-buffer))
(success nil))
(ivy-read "Find References: " (ivy-xref-make-collection xrefs)
:unwind (lambda ()
(unless success
(switch-to-buffer xref-buffer)
(goto-char xref-pos)
(recenter))
:action (lambda (x)
(let ((location (cdr x)))
(let* ((marker (xref-location-marker location))
(buf (marker-buffer marker)))
(if (not (eq buf xref-buffer))
(switch-to-buffer buf))
(with-ivy-window
(goto-char marker)
(recenter))
(unless (eq 'ivy-call this-command)
(setq success t)))))))))