我用最简配置无法重现你说的问题:
$ emacs -Q --eval "\
(progn
(setq user-emacs-directory
(car (seq-filter
#'file-exists-p
(list (format \"~/.emacs.d/%s/\" emacs-version)
(format \"~/.emacs.d/%s/\" emacs-major-version)
\"~/.emacs.d/\"))))
(setq package-user-dir (concat user-emacs-directory \"elpa/\"))
(package-initialize)
(add-to-list 'load-path \"~/repos/emacs-lsp-bridge\")
(setq custom-safe-themes t)
(setq-default custom-enabled-themes '(tango))
(defun reapply-themes()
(load-theme 'tango))
(add-hook 'emacs-startup-hook 'reapply-themes)
(require 'yasnippet)
(yas-global-mode 1)
(require 'lsp-bridge)
(global-lsp-bridge-mode))"
可能你的最简配置并未如你期望那般”最简“。
我使用你的这个启动配置还是卡住了。你的是 emacs-mac 还是 emacs-plus?
虽然还是没有弄清原因,把 after-init-hook
改成 window-setup-hook
解决了。
的确放在 after-init-hook
会出错:
$ emacs --daemon
Debug on Error enabled globally
[yas] Prepared just-in-time loading of snippets successfully.
Debugger entered--Lisp error: (wrong-number-of-arguments (((alpha . 0.8) (c2 . "#000000") (c1 . "unspecified-bg") x-gtk-resize-child-frames t) (r g b) (format "#%02x%02x%02x" (ash r -8) (ash g -8) (ash b -8))) 0)
(closure ((alpha . 0.8) (c2 . "#000000") (c1 . "unspecified-bg") x-gtk-resize-child-frames t) (r g b) (format "#%02x%02x%02x" (ash r -8) (ash g -8) (ash b -8)))()
apply((closure ((alpha . 0.8) (c2 . "#000000") (c1 . "unspecified-bg") x-gtk-resize-child-frames t) (r g b) (format "#%02x%02x%02x" (ash r -8) (ash g -8) (ash b -8))) nil)
acm-color-blend("unspecified-bg" "#000000" 0.8)
(set-face-background 'acm-default-face (acm-color-blend (face-attribute 'default :background) blend-background (if is-dark-mode 0.8 0.9)))
(progn (set-face-background 'acm-default-face (acm-color-blend (face-attribute 'default :background) blend-background (if is-dark-mode 0.8 0.9))))
(if (or force (equal (face-attribute 'acm-default-face :background) 'unspecified)) (progn (set-face-background 'acm-default-face (acm-color-blend (face-attribute 'default :background) blend-background (if is-dark-mode 0.8 0.9)))))
(let* ((is-dark-mode (string-equal (acm-get-theme-mode) "dark")) (blend-background (if is-dark-mode "#000000" "#AAAAAA"))) (set-face-attribute 'acm-buffer-size-face nil :height (face-attribute 'default :height)) (if (or force (equal (face-attribute 'acm-default-face :background) 'unspecified)) (progn (set-face-background 'acm-default-face (acm-color-blend (face-attribute 'default :background) blend-background (if is-dark-mode 0.8 0.9))))) (if (or force (equal (face-attribute 'acm-select-face :background) 'unspecified)) (progn (set-face-background 'acm-select-face (acm-color-blend (face-attribute 'default :background) blend-background 0.6)))) (if (or force (equal (face-attribute 'acm-select-face :foreground) 'unspecified)) (progn (set-face-foreground 'acm-select-face (face-attribute 'font-lock-function-name-face :foreground)))))
acm-init-colors(t)
acm-reset-colors(tango)
apply(acm-reset-colors tango)
load-theme(tango)
reapply-themes()
run-hooks(after-init-hook delayed-warnings-hook)
command-line()
normal-top-level()
Error: server did not start correctly
我前面不用 after-init-hook
是因为 emacs -Q
会忽略它,所以改为 window-setup-hook
。
lsp-bridge
把 acm-reset-colors
放在 load-theme
之后执行,以确保设置/更改 theme 的时候生效:
(advice-add #'load-theme :after #'acm-reset-colors)
如果在 after-init-hook
的时候 load theme,就会因为参数 "unspecified-bg"
无法识别而卡住。这个问题其实我在 acm-terminal
解决过😂:
所以,问题来了,为什么会出现 "unspecified-bg"
?因为被当成终端模式了,为什么会被当作终端模式?因为 daemon 启动时,Emacs 处于一个混沌的状态,详见我这个帖子:Daemon 模式下的一个坑:window-system 变量从 nil 到有
所以,你的问题目前最简单的解决方案就是在 window-setup-hook
调用 load theme,因为该 hook 不会在 daemon 启动时执行,而是在 emacsclient 连接时执行,此时就可以明确 Emacs 处于 GUI 状态了,也就不会出现参数错误。(EDIT: 其实 emacsclient 启动时,在 window-setup-hook
中 load theme 仍然会出错,即依然无法判断是否 GUI,要等到 after-make-frame-functions
之后才能真正知道是否处于 GUI。但是在 client 中出错不影响 daemon,所以就蒙混过关了😂)
lsp-bridge
可以暂时不解决这个问题(本来目前就不支持终端嘛,何必去解决不存在的问题?),等我合并 acm-terminal
一并处理。 @manateelazycat
9 个赞
我又想了想,还是先提个补丁比较好,毕竟同时使用 GUI 和 Daemon 是很正常的,两者不矛盾。
daemon 的情况还是有点复杂,在 after-init-hook
中(即 daemon 初始化时),无法判断 GUI 还是 CLI。不能让用户放弃使用 after-init-hook
,先提交一个补丁保证 GUI 下正常初始化:
(if (daemonp)
(add-hook 'server-after-make-frame-hook
(lambda ()
(acm-reset-clors) ;; 错过 `after-init-hook`, 这里补调一次。
(advice-add #'load-theme :after #'acm-reset-colors)))
(advice-add #'load-theme :after #'acm-reset-colors))
-
daemon 方式启动,在 after-init-hook
中无法判断是否 GUI,推迟调用 acm-reset-colors
,直到 server-after-make-frame-hook
。
-
正常启动,在 after-init-hook
中可判断是否 GUI,立即调用 acm-reset-colors
。
lsp-bridge 的后端速度太快了, 在手速非常快的时候, 会存在竞争条件: 用户选择第二个候选词的时候 lsp-bridge 同时也返回最新的补全数据。
原来老的逻辑是, 返回新的候选词数据就会把光标强制选中到第一个, 遇到上面的竞争条件就会发生, 用户看到菜单是 candidate_a, 但是 lsp-bridge 太快就会导致补全那一瞬间补全的是 candidate_b (因为最新的补全数据 candidate_b 可能排第一位)。 这个bug仅存在于手速超快的时候。
今天想了想, 针对手速超快的情况, 每次更新候选词之前先记录一下上次选中的候选词内容, 更新补全菜单以后再次重新查找上次选中的候选词的新位置, 这样就可以解决手速快补全错误的bug.
因为这个bug太隐蔽, 会影响那些手速特别快的同学, 建议大家更新一下。
2 个赞
第一个问题是, Emacs29导致 frame 都慢, 这是 Emacs29 的bug, 日常生产不要用 Emacs29 这种开发版本, API不稳定, bug多, 外围插件不会跟这种版本
第二个问题是, acm-backend-lsp-candidate-max-length 这个弄长点就好了
第三个问题目前还没有做这么精细化, 每种语言和每个人的喜好不一样, 先收集大家意见, 现在的排序是按照 LSP Server 的推荐排序弄的, LSP Server 会分析你过往输入的代码来动态排序候选词, 不一定按照字母或者长度去排序
第一个问题,jvm改一下GC参数试试: -Xms8G -XX:+UseG1GC -XX:MaxGCPauseMillis=200
,看看能不能提升下jdtls的性能。
lookup documentation 的弹窗字体比较小,有什么办法可以改吗?
lsp-bridge-lookup-doc-tooltip-text-scale
这个问题彻底修复好了, 原因是我这几个月以来一直用的是一个十多年前的 markdown-mode.el (被我个人配置文件做了 shadow 覆盖), 我硬是没有测试出来。
1 个赞
更新后, 试一下 lsp-bridge-lookup-doc-tooltip-font-height 选项。
可以帮忙测试一下, 看看最新版还有问题吗?
我这边测试已经好了, 如果LSP服务器更新太快, 更新后菜单会选中更新前的候选词, 而不是第一个。