谢谢。现在 windows 下能启动了。
各种小问题。后面在 msys2 中开 emacs 中,可以启动 lsp-bridge 了,但是好像路径又有点问题。
放弃了。
准备代码编辑在 Linux 下完成了。后面调试运行再在 Windows 上面整吧
谢谢。现在 windows 下能启动了。
各种小问题。后面在 msys2 中开 emacs 中,可以启动 lsp-bridge 了,但是好像路径又有点问题。
放弃了。
准备代码编辑在 Linux 下完成了。后面调试运行再在 Windows 上面整吧
谢谢大佬,之前那个错误确实是你提到的这个问题。
后面发现还需要设置一下 lsp-bridge-python-command
这一个好像 Windows 下挺乱的,我找的几个配置设置的都不太一样,最后是按我自己终端设置的。
终于搞定了。
求助,我使用 lsp-bridge 做补全,在 vue 文件里,写下 console ,它会自动给我插入这句话 import console from 'console';
,我是要在浏览器里运行的,这句话没必要,还会导致编译错误,我还需要手动删除
大佬,请问 lsp-bridge 中带的文件路径自动补全,是其它的插件,还是 lsp-bridge 自己写的?
我想自定义一些文件补全的功能(比如在指定的文件夹里面查找),但是水平差,定位不到相应的代码位置
@manateelazycat 我最近在看diagnostics列表打开后不自动更新的问题,lsp-bridge-references--popup
跟lsp-bridge-diagnostic--list
共享了lsp-bridge-ref-popup
不太好动啊。有什么实现推荐么?
现在每天启动emacs都要遇到一次lsp没补全的情况
lsp-bridge两个buffer都没东西,但是只要重启emacs再来一次就好了,不知道怎么确认问题在哪,pyright也在运行,每天都要来一次,但不知道是不是重启第一次会这样,暂时没法稳定重现,该怎么排查打开了日志,貌似是默认开启多服务器启用的ruff报错了,一个什么clone的报错,忘记截图了,但不是一定会报错,只能说有几率,暂时禁用多服务器,先看看还会不会出现该问题
大佬,补全菜单的图标可以自定义吗
在请教一下,在使用过程中,一段时间后编辑就会不跟手明显卡顿,重启又好了,这种怎么排查呢
emacs -Q排查自己的配置,看论坛的输入框内容
懒猫大大, 请问下, lsp-bridge的补全能用到aweshell里吗?
acm前端肯定能, 但是要写 shell 补全后端需要有人写。
我最近都超级忙, 最多谁愿意写, 我告诉他思路, 我自己没有时间满足大家所有的需求。
大佬共享一下思路吗?
大佬有空的话可以写下思路, 我试着弄一下
爬楼时看到现在已经可以在 org-source-block
中使用 lsp-bridge
了,不过有坛友提出这样就不能使用 capf
对 org-roam
进行标题补全了,对我来说这一个功能还是相当重要的。在网上以"lsp-bridge org-roam"为关键词搜索无果后我花了一点时间糊了一个简陋的 acm-backend-org-roam
,基本上实现了 org-roam-complete-link-at-point
。
我不太熟悉 elisp ,只是粗略地看了一下 acm.el
, 照着 acm-backend-tempel.el
等文件和之前的 commit 一通乱改实现的效果,可能存在隐藏的问题或者不合适的改动。现在有一些已知的功能没有实现,或者使用了非常 hacky 的方式,希望大佬们能够给出更加合理的解决方案。
代码如下:
acm-backend-org-roam.el
,可以放在 lsp-bridge/acm
下。
;;; acm-backend-org-roam.el -*- lexical-binding: t; no-byte-compile: t; -*-
(defgroup acm-backend-org-roam nil
"Org-roam backend for acm."
:group 'acm)
(defcustom acm-enable-org-roam nil
"Popup Org-roam completions when this option is turn on."
:type 'boolean
:group 'acm-backend-org-roam)
(defcustom acm-backend-org-roam-candidates-number 10
"Maximal number of Org-roam candidate of menu."
:type 'integer
:group 'acm-backend-org-roam)
(defun acm-backend-org-roam-candidates (keyword)
(when (and acm-enable-org-roam
(featurep 'org-roam))
(let* ((titles (org-roam--get-titles))
(match-titles (seq-filter (lambda (s) (acm-candidate-fuzzy-search keyword s)) titles)))
(acm-candidate-sort-by-prefix
keyword
(mapcar
(lambda (title)
(list :key title
:icon "ref"
:label title
:displayLabel title
:annotation "Org-Roam"
:backend "org-roam"))
(cl-subseq match-titles 0 (min (length match-titles) acm-backend-org-roam-candidates-number)))))))
(defun acm-backend-org-roam-candidate-expand (candidate-info bound-start)
(let (roam-p start end)
(when (org-in-regexp org-roam-bracket-completion-re 1)
(setq roam-p (not (or (org-in-src-block-p)
(string-blank-p (match-string 1))))
start (match-beginning 2)
end (match-end 2))
(delete-region bound-start (point))
(insert (if roam-p "" "roam:") (plist-get candidate-info :label))
(forward-char 2))))
(provide 'acm-backend-org-roam)
;;;acm-backend-org-roam.el ends here
修改 acm.el
。
diff --git a/acm/acm.el b/acm/acm.el
index 7c1f9d6..35cf936 100644
--- a/acm/acm.el
+++ b/acm/acm.el
@@ -106,6 +106,7 @@
(require 'acm-backend-ctags)
(require 'acm-backend-codeium)
(require 'acm-backend-copilot)
+(require 'acm-backend-org-roam)
(require 'acm-quick-access)
;;; Code:
@@ -247,6 +248,7 @@
(defvar acm-buffer " *acm-buffer*")
(defvar acm-menu-frame nil)
(defvar acm-menu-frame-popup-point nil)
+(defvar acm-menu-frame-popup-point-symbol nil)
(defvar acm-menu-frame-popup-position nil)
(defvar acm-menu-number-cache 0)
@@ -427,6 +429,8 @@ Only calculate template candidate when type last character."
(defun acm-update-candidates ()
(let* ((keyword (acm-get-input-prefix))
+ (keyword-symbol (let ((acm-input-bound-style "symbol"))
+ (acm-get-input-prefix)))
(char-before-keyword (save-excursion
(backward-char (length keyword))
(acm-char-before)))
@@ -448,7 +452,13 @@ Only calculate template candidate when type last character."
template-first-part-candidates
template-second-part-candidates
ctags-candidates
- citre-candidates)
+ citre-candidates
+ org-roam-candidates)
+ (when (and acm-enable-org-roam
+ (eq major-mode 'org-mode)
+ (org-in-regexp org-roam-bracket-completion-re 1)
+ (not (org-in-src-block-p))
+ (setq org-roam-candidates (acm-backend-org-roam-candidates keyword-symbol))))
(when acm-enable-tabnine
(setq tabnine-candidates (acm-backend-tabnine-candidates keyword)))
@@ -479,6 +489,7 @@ Only calculate template candidate when type last character."
lsp-candidates
ctags-candidates
citre-candidates
+ org-roam-candidates
(acm-backend-search-file-words-candidates keyword)
(acm-backend-telega-candidates keyword)))
@@ -572,7 +583,8 @@ The key of candidate will change between two LSP results."
(candidates (or candidate (acm-update-candidates)))
(menu-candidates (cl-subseq candidates 0 (min (length candidates) acm-menu-length)))
(current-select-candidate-index (cl-position previous-select-candidate (mapcar 'acm-menu-index-info menu-candidates) :test 'equal))
- (bounds (acm-get-input-prefix-bound)))
+ (bounds (acm-get-input-prefix-bound))
+ (bounds-symbol (bounds-of-thing-at-point 'symbol)))
(cond
;; Hide completion menu if user type first candidate completely, except when candidate annotation is `emmet' or `snippet'.
((and (equal (length candidates) 1)
@@ -623,6 +635,7 @@ The key of candidate will change between two LSP results."
;; Record menu popup position and buffer.
(setq acm-menu-frame-popup-point (or (car bounds) (point)))
+ (setq acm-menu-frame-popup-point-symbol (or (car bounds-symbol) (point)))
;; `posn-at-point' will failed in CI, add checker make sure CI can pass.
;; CI don't need popup completion menu.
@@ -698,8 +711,10 @@ The key of candidate will change between two LSP results."
(defun acm-complete (&optional not-hide)
(interactive)
(let* ((candidate-info (acm-menu-current-candidate))
- (bound-start acm-menu-frame-popup-point)
(backend (plist-get candidate-info :backend))
+ (bound-start (if (string-equal backend "org-roam")
+ acm-menu-frame-popup-point-symbol
+ acm-menu-frame-popup-point))
(candidate-expand (intern-soft (format "acm-backend-%s-candidate-expand" backend))))
(if (fboundp candidate-expand)
最后别忘了 (setq acm-enable-org-roam t)
启用该功能, acm-backend-org-roam-candidates-number
调整最大数量。
以下是已知的问题:
中文补全
acm-input-bound-style
默认值为 "ascii"
,为了尽可能不影响其他后端,我用一些比较 hacky 的方法实现中文补全。我定义了大量以 -symbol
结尾的变量作为一时之计,目前没有发现什么的问题,但是显然这不是最好的方案。
相关的变量和函数为 acm-input-bound-style
, acm-get-input-prefix-bound
, acm-get-input-prefix
。
acm-update-candidates
中的 keyword 匹配候选项,不修改无法匹配中文。
acm-update
中的 bounds 确认需要删除的已输入 keyword,不修改会重复输入。
其他格式的链接中补全
org-mode
支持 External Links,如 [[file:~/code/main.c::255]]
,在[[file:*]]
情况下:
org-roam
实现的 capf
中,指针在 *
处似乎是默认不补全的,一开始我以为 org-roam-completion-link-at-point
有特殊的处理,其实它直接把双中括号内的所有字符串发送给 capf
。因此,如果你有类似 file:foo
名字的 node capf
是会正常补全的,[[LINK][DESCRIPTION]]
同理。 org-roam-completion-link-at-point
仅仅防止重复输入 roam:
。
acm
以标点符号为间隔计算 keyword,相当于忽略了冒号及前面的内容。
因为不清楚怎么实现更好暂时搁置了这一功能。
性能问题
org-roam--get-titles
函数调用了数据库获得候选项,应该可以使用外部程序和缓存提高性能。不过我现在 node 数量较少感受不明显。
其他问题
icon、CI等。
思路:
这样就可以实现终端像IDE那样智能补全了。
首先感谢补丁, 回答一下问题:
acm-get-input-prefix 的问题, 可以考虑在函数 acm-get-input-prefix 中针对 org-roam 的环境进行判断, 如果是 org-roam 输入区域 (参考你上面写的 (org-in-regexp org-roam-bracket-completion-re 1) ), 可以自动把 acm-input-bound-style 修正为 symbol, 这样代码更干净一点
性能问题, org-roam–get-titles 如果是读取数据库的话, 建议像 sdcv 后端 lsp-bridge/core/search_sdcv_words.py at dfc5c3210ec1d6c421ef38e51e30f568ad4a3a54 · manateelazycat/lsp-bridge · GitHub 那样, 在 Python 多线程端读取数据库补全内容, 这样从 Python 多线程后端绕一圈的好处是, 永远不会因为手指头快过于数据库查询速度而卡住输入
图标问题: 从 Material Design Icons - Icon Library - Pictogrammers 找到合适的图标, 然后添加一个新的图标到 acm-icon-alist 中重启Emacs, 然后执行 acm-icon-fetch-all 会自动下载图标, 最后提交到 github 即可
欢迎提交PR到 github, 我合并补丁的速度还是很快的。
非常感谢懒猫的回复以及写的 lsp-bridge
,用了这个包之后,Emacs 变得非常流畅。
我已经根据意见修改了 acm-get-input-prefix
相关内容:
diff --git a/acm/acm.el b/acm/acm.el
index 7c1f9d6..cb38823 100644
--- a/acm/acm.el
+++ b/acm/acm.el
@@ -373,7 +374,13 @@ So we use `minor-mode-overriding-map-alist' to override key, make sure all keys
(defun acm-get-input-prefix ()
"Get user input prefix."
- (let ((bound (acm-get-input-prefix-bound)))
+ (let* ((acm-input-bound-style (if (and acm-enable-org-roam
+ (eq major-mode 'org-mode)
+ (not (org-in-src-block-p))
+ (org-in-regexp org-roam-bracket-completion-re 1))
+ "symbol"
+ "ascii"))
+ (bound (acm-get-input-prefix-bound)))
(if bound
(buffer-substring-no-properties (car bound) (cdr bound))
"")))
不确定这种写法是否标准,修改以后是可以正常获得补全,但是展开时仍存在问题,因为 acm-update
独立获取了 bounds,见最后一行:
(defun acm-update (&optional candidate)
(acm-quick-access-init)
(let* ( ;; variables...
(bounds (acm-get-input-prefix-bound))) ;; <- 这里
需要再修改 acm-update
中的代码,相当于把条件写了三处地方,如果封装成一个和 acm
核心功能无关的判断函数又感觉怪怪的。在进一步修改之前,我想再次征求一下意见。
目前我想到以下几种方案:
acm-get-input-prefix-bound
,需要考虑到代码中的其他部分,如 lsp-bridge-set-prefix-style。acm-update
和 acm-update-candidates
,比如在 acm-update
中获取 bounds,再传给 acm-update-candidates
。以上方案都存在一个问题:org-roam 中有另一个默认关闭的功能 org-roam-complete-everywhere
允许用户在链接外的任意位置补全(示例),也许会有用户想要这个功能。我看了一些回复和 commit,默认使用 symbol
会出现一些问题。 要解决这个问题,可以像之前的回复提到的让每一个后端自定义边界函数。
这是 org-roam 中 capf 的实现:
(defun org-roam-complete-link-at-point ()
(let (roam-p start end)
(when (org-in-regexp org-roam-bracket-completion-re 1)
(setq roam-p (not (or (org-in-src-block-p)
(string-blank-p (match-string 1))))
start (match-beginning 2)
end (match-end 2))
(list start end
(org-roam--get-titles)
:exit-function
;; body
))))
(add-hook 'completion-at-point-functions f nil t)
这一函数内部用正则获取边界后返回 (START END COLLECTION . PROPS)
,前两个参数就是所用的边界。对于最终用户来说,仍旧不需要进行额外的配置,而对于开发者来说,可以减少许多 workaround。
当然,实现这个想法会影响到许多代码,我自己用不到 org-roam-complete-everywhere
,暂时打算先用前面几种方案实现基础功能。
我自己写代码的速度还不够快 ,目前 fork 了仓库,想等功能稳定和充分测试后再提交 PR。