目的: 用 acm 来代替之前配置中的 company 来作为 SLY 的补全提示.
参考 @manateelazycat 大佬在论坛中 completion buffer有没有可能像lsp-bridge、company那种方式显示? 的回复, 发现要修改的内容比较多 (?)
这里给出一个穷人实现, 不清楚是否可靠.
省流版: 核心代码是 acm-update-candidates-append-sly-results
, 用 (advice-add 'acm-update-candidates :around ...)
的方式给原本的函数行为进行一个 “修正”.
问题: 空格没法触发 acm-hide
(?) , 不清楚是不是只改了一个函数的缘故.
;; use acm as SLY completion front end
;; currently is only for patching
;; from https://github.com/joaotavora/sly/blob/ba40c8f054ec3b7040a6c36a1ef3e9596b936421/lib/sly-completion.el#L323C9-L335C36
;; and see `acm-icon-alist' for the icon mapping
;; from https://github.com/manateelazycat/lsp-bridge/blob/49b5497243873b1bddea09a4a988e3573ed7cc3e/acm/acm-icon.el#L94
(defun acm-backend-sly-candidate-type (candidate)
(pcase (get-text-property 0 'sly--classification candidate)
("fn" "function")
("generic-fn" "method")
("generic-fn,cla" "method")
("cla,type" "class")
("cla" "class")
("special-op" "operator")
("type" "class")
("constant" "constant")
("var" "variable")
("pak" "package")
("pak,constant" "package")
("macro" "macro")
(_ "unknown")))
(defun acm-backend-sly-candidates (keyword)
(mapcar (lambda (candidate)
(let ((type (acm-backend-sly-candidate-type candidate)))
(list :key candidate
:icon type
:label candidate
:displayLabel candidate
:annotation (capitalize candidate)
:backend "sly")))
(ignore-errors
(car (funcall sly-complete-symbol-function keyword)))))
;; poor man's lisp doc
(defun acm-backend-sly-candidate-doc (candidate)
(when (sly-connected-p)
(let ((type (plist-get candidate :icon))
(key (plist-get candidate :key)))
(pcase type
((or "function" "method" "operator")
(sly-eval `(slynk:describe-function ,key)))
(_ (sly-eval `(slynk:describe-symbol ,key)))))))
(defun acm-update-candidates-append-sly-results (fn)
(if (and (derived-mode-p 'lisp-mode)
(sly-connected-p))
(let* ((keyword (acm-get-input-prefix))
(sly-res (acm-backend-sly-candidates keyword)))
(append sly-res (funcall fn)))
(funcall fn)))
(advice-add 'acm-update-candidates
:around #'acm-update-candidates-append-sly-results)
(add-hook 'lisp-mode-hook #'lsp-bridge-mode)
(add-hook 'sly-mrepl-mode-hook #'lsp-bridge-mode)