ginqi7
1
1. 背景
使用 deno-bridge 来扩展 Emacs 很好用。它的逻辑是:在 emacs 和 deno 两边都启动 websocket ,然后通过 websocket 通信。根据不同的消息来运行不同的命令。整个结构相当的简洁,并且很够用。
只是 deno 现有的包还是比较少。有一些需求难以找到现有的实现。
例如:我现在需要获取本地 chrome 已有的 cookie, deno 没有现有的包。但是 python 有很好用的 pycookiecheat。
本来打算使用 python-epc 来完成我的需求。但 epc 并没有 deno-bridge 简洁。因此看了一下 deno-bridge 的代码,应该可以很容易的移植到 python
epc 不足之处:
- 由于 epc 太老旧。新版的 Emacs 并不能直接使用,需要修改 epcs
- 每次写新的包,都需要在 emacs 和 python 端都启动 server 通信
- 使用、管理没有 deno-bridge 简洁。
由于 deno-bridge 的核心就只是 websocket 通信。因此可以抽象出一个 websocket-bridge ,emacs 端,启动一个 websocket server, 外部每一个插件都是一个 websocket connect 。 因此插件的实现可以是任何语言。
2. 实现
目前只实现了 python 版,理论上使用任何语言 + 对应 websocket-client 即可。
3. 插件
根据自己英文阅读,写作的需求。打算实现两个包:
-
websocket-bridge-grammarly 使用 grammarly sdk 进行英文写作的语法校验。
-
dictionary-overlay 使用词典、或者在线翻译对 buffer 中的生词进行翻译渲染展示。
3.1. dictionary-overlay
dictionary-overlay 已经初步可用。
在帖子 【讨论】一种提升英文阅读体验的可能性 - #52,来自 skywind3000 中有这个项目的一些细节讨论。
3.2. websocket-bridge-grammarly
websocket-bridge-grammarly 还在开发阶段。选择开发这个插件的原因是:已有的 lsp-grammarly、eglot-grammarly 不支持登录链接到 grammarly 的个人帐号。如果使用免费版本,其实使用 lsp-grammarly eglot-grammarly 应该已经很好用了。
16 个赞
哇, 大佬, 你要把Emacs英语学习的插件提升到全新的高度啊, 热烈期待, 抢沙发。
grammarly 针对个人使用是收费的吗? 还是注册一个个人账号就好了?
ginqi7
4
grammarly 不注册帐号应该也可以免费使用。这里有一个 lsp server
只是 emacs 版本的不能连接个人帐号。好像 vscode 的可以。
目前我还不确定收费帐号有没有什么高级功能。但淘宝先买了一个。
websocket-bridge
看起来是很通用的,我觉得这个思路很好。期待能有更多插件,能上melpa,甚至elpa
ginqi7
6
websocket-bridge.el 本身比较的简单。只是定义了 emacs 和外部应用的通信方式。上不上melpa,好像对用户的差别不大。
主要还是需要有更多可用的插件,这些插件的核心功能都不是 elisp 实现的,这就和 melpa 远了。
我个人是个 Java 开发。所以我最大的需求是:emacs 可以和 IntelliJ IDEA 进行通信,在 emacs 中运用到 idea 的高级功能,使用 lsp 进行 java 开发还是不太给力。(等什么时候研究一下idea的api,看看能否可行)
当年有一个大佬做过一个 idea 的lsp server,可惜不维护了。
2 个赞
核心上就行了,插件可以另外处理。或者带几个杀手级的插件一起发布。我是不是理想化了
赞!
选择只用一个websocket-server而不是可以启动多个的考虑是啥? 感觉每个插件如果能启动自己的server是不是更稳妥点?互相之间可以隔离,不至于一个server出问题,所有插件都不工作了。
不过我没看你的实现,对websocket也不怎么了解,就是凭空想的一个问题。
ginqi7
10
仅仅只是能简单点,便于管理而已。否则 process 里一堆 websocket-server 。
websocket-server 本身并不容易出问题,它的实现逻辑比较简单。理论上只有手动 kill 了进程才会消失。
使用一个emacs 长驻的 server 。后续的管理,都只需要管理 client 就可以。新增,重启,server 都可以不动。
我是赞同这个观点的,通讯机制或者每个插件一个websocket都不是太大事情。
因为RPC本身没有价值,应用代码才有价值。
每个插件的进程单独kill本身可能才是最佳实践。
其实用了很久的atomic-chrome就是用的websocket来实现的,还有实时预览markdown的插件、org-roam-ui也是这么做的。效率确实很高,也不容易出问题。
这个包有点类似。不过它没有提供 eval-code
这样万能的接口,而是通过 porthole-expose-function
明确哪些函数可以使用。
ginqi7
17
emacs 还有一个更老的rpc 包:GitHub - kiwanami/emacs-epc: A RPC stack for Emacs Lisp
功能上,epc 已经比较完善了。lsp-bridge 之类的在使用。只是由于包比较老,可能需要自己fork 根据需求改一些东西。
由于“太长不看”的原因,就借鉴deno-bridge 的模式,实现了一个理论上可以应用任何其他语言的版本。主要就是看重了,互相通信的简洁性。
我是觉得rpc 调用明确注册方法能够避免方法调用的滥用。不过为了简单,使用 eval-code 会比较方便。
其实 rpc 注册方法那个很容易被绕过, 你把 elisp eval 函数注册给外部语言, 外部语言就可以随意 eval 了。
实践证明, eval code 这种方法才是实用的。
1 个赞