emacs-lsp-proxy 0.1.1 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +232 -0
- package/package.json +11 -7
package/README.md
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# LSP-PROXY (formerly LSP-COPILOT)
|
|
2
|
+
|
|
3
|
+
*This project has been renamed from lsp-copilot to lsp-proxy to better reflect its core functionality as a communication proxy and aggregator between Emacs and multiple LSP servers. The name change does not affect the project's features or goals.*
|
|
4
|
+
|
|
5
|
+
## Introduction
|
|
6
|
+
Lsp-Proxy is an LSP (Language Server Protocol) client for Emacs, implemented in Rust and inspired by [lsp-bridge](https://github.com/manateelazycat/lsp-bridge). It uses `jsonrpc.el` to facilitate communication between Emacs and the Lsp-Proxy Server. The Lsp-Proxy Server acts as an intermediary between Emacs and various language servers, handling communication with the language servers, processing the responses, and returning them to Emacs.
|
|
7
|
+
|
|
8
|
+
The features it supports are:
|
|
9
|
+
- find definitions/references/implementatoins/type-definition/declaration (as a xref backend)
|
|
10
|
+
- completion (as a capf function) support snippet and auto import, reuse requests that are already being processed, while caching the results to improve response speed, before returning all the completion candidates, the server will do fuzzy matching and filter out entries with no match.
|
|
11
|
+
- diagnostics (as a flycheck backend default or flymake) process diagnostics when idle.
|
|
12
|
+
- hover (triggered by `lsp-proxy-describe-thing-at-point`)
|
|
13
|
+
- code action (triggered by `lsp-proxy-execute-code-action`)
|
|
14
|
+
- rename (triggered by `lsp-proxy-rename`)
|
|
15
|
+
- format buffer (triggered by `lsp-proxy-format-buffer`)
|
|
16
|
+
- workspace command, such as `typescript.restartTsServer(vtsls)` 、 `reloadWorkspace(rust-analyzer)` (triggered by `lsp-proxy-execute-command`)
|
|
17
|
+
- inlay hints (triggered by `lsp-proxy-inlay-hints-mode`)
|
|
18
|
+
- documentHighlight/signature (baesd on `eldoc`)
|
|
19
|
+
- documentSymbols (triggered by `imenu`)
|
|
20
|
+
|
|
21
|
+

|
|
22
|
+
|
|
23
|
+
## Prerequisites
|
|
24
|
+
### Emacs30.1 or 29 + eglot@latest (Reused some capabilities of eglot to reduce code duplication.)
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
### Via npm (Recommended)
|
|
28
|
+
LSP-PROXY is now available via npm with prebuilt binaries for all major platforms:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install -g emacs-lsp-proxy
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
This will automatically install the appropriate binary for your platform (Linux x64/ARM64, macOS x64/ARM64, Windows x64) and make the `emacs-lsp-proxy` command available in your PATH.
|
|
35
|
+
|
|
36
|
+
### Manually
|
|
37
|
+
Before installing LSP-PROXY manually, you should install rust and cargo first.
|
|
38
|
+
```bash
|
|
39
|
+
git clone https://github.com/jadestrong/emacs-lsp-proxy.git ./your-directory
|
|
40
|
+
cd ./your-directory
|
|
41
|
+
cargo build --release
|
|
42
|
+
# delete old file if exist
|
|
43
|
+
rm emacs-lsp-proxy
|
|
44
|
+
# cp ./target/release/emacs-lsp-proxy.exe ./
|
|
45
|
+
cp ./target/release/emacs-lsp-proxy ./
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Download prebuilt binary
|
|
49
|
+
You can download the prebuilt binary from [releases](https://github.com/jadestrong/lsp-copilot/releases). For MacOS users, you should allow this binary to run first time, like this:
|
|
50
|
+
> The application cannot be opened because it is from an unidentified developer. You can allow this app to run by going to System Settings > Privacy & Security and selecting 'Allow Anyway' for this app.
|
|
51
|
+
|
|
52
|
+
## How to use
|
|
53
|
+
```emacs-lisp
|
|
54
|
+
(use-package lsp-proxy
|
|
55
|
+
;; :load-path "/path/to/lsp-proxy"
|
|
56
|
+
:config
|
|
57
|
+
(add-hook 'tsx-ts-mode-hook #'lsp-proxy-mode)
|
|
58
|
+
(add-hook 'js-ts-mode-hook #'lsp-proxy-mode)
|
|
59
|
+
(add-hook 'typescript-mode-hook #'lsp-proxy-mode)
|
|
60
|
+
(add-hook 'typescript-ts-mode-hook #'lsp-proxy-mode))
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
```elisp
|
|
64
|
+
;; Doom Emacs
|
|
65
|
+
(package! lsp-proxy :recipe (:host github :repo "jadestrong/lsp-proxy"
|
|
66
|
+
:files ("lsp-proxy.el" "emacs-lsp-proxy")
|
|
67
|
+
:pre-build (("cargo" "build" "--release") ("cp" "./target/release/emacs-lsp-proxy" "./"))))
|
|
68
|
+
|
|
69
|
+
(set-lookup-handlers! 'lsp-proxy-mode
|
|
70
|
+
:definition '(lsp-proxy-find-definition :async t)
|
|
71
|
+
:references '(lsp-proxy-find-references :async t)
|
|
72
|
+
:implementations '(lsp-proxy-find-implementations :async t)
|
|
73
|
+
:type-definition '(lsp-proxy-find-type-definition :async t)
|
|
74
|
+
:documentation '(lsp-proxy-describe-thing-at-point :async t))
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Add a new language
|
|
78
|
+
Performed simple tests on Windows 11 and Arch Linux, it works properly. I have tested it on macOS and use it for daily development in JavaScript, Rust, etc. Therefore, tools like vtsls, typescript-language-server, eslint, tailwindcss, css, and others work fine
|
|
79
|
+
- JavaScript/Typescript: [vtsls](https://github.com/yioneko/vtsls) (built-in)、[typescript-language-server](https://github.com/typescript-language-server/typescript-language-server)
|
|
80
|
+
- eslint、html、css、html: [vscode-langservers-extracted](https://github.com/hrsh7th/vscode-langservers-extracted) +the latest vscode-eslint has removed the publishDiagnostics method and only supports the pullDiagnostics method, so currently we can only use `vscode-langservers-extracted@4.8`+.
|
|
81
|
+
- tailwindcss: [@tailwindcss/language-server](https://www.npmjs.com/package/@tailwindcss/language-server)
|
|
82
|
+
|
|
83
|
+
The configuration for a new language can refer to the [Helix configuration](https://github.com/helix-editor/helix/blob/master/languages.toml). Supported fields are based on [the built-in configuration file](https://github.com/jadestrong/lsp-copilot/blob/main/languages.toml), and only LSP-related fields are supported.
|
|
84
|
+
Open custom language config file by `lsp-proxy-open-config-file` and add your config, then execute `lsp-proxy-restart`.
|
|
85
|
+
|
|
86
|
+
The configuration fields for adding language support are: `name、roots、language-id、file-types、language-servers` . Other fields in the Helix configuration are not supported.
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
- Vue2:
|
|
90
|
+
```toml
|
|
91
|
+
[languge-server.vls]
|
|
92
|
+
command = "vls"
|
|
93
|
+
args = ["--stdio"]
|
|
94
|
+
|
|
95
|
+
[[language]]
|
|
96
|
+
name = "vue"
|
|
97
|
+
roots = ["package.json"]
|
|
98
|
+
language-id = "vue"
|
|
99
|
+
file-types = ["vue"]
|
|
100
|
+
language-servers = ["vls"]
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
- Vue3
|
|
104
|
+
```sh
|
|
105
|
+
yarn global add @vue/language-server @vue/typescript-plugin
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
```toml
|
|
109
|
+
[language-server.typescript-language-server]
|
|
110
|
+
config.plugins = [
|
|
111
|
+
{ name = "@vue/typescript-plugin", location = "${your-path}/node_modules/@vue/typescript-plugin", languages = ["vue"]}
|
|
112
|
+
]
|
|
113
|
+
|
|
114
|
+
[language-server.vue-language-server]
|
|
115
|
+
command = "vue-language-server"
|
|
116
|
+
args = ["--stdio"]
|
|
117
|
+
config.typescript = { tsdk = "${your-path}/node_modules/typescript/lib" }
|
|
118
|
+
config.vue = { hybridMode = false }
|
|
119
|
+
|
|
120
|
+
[[language]]
|
|
121
|
+
name = "vue"
|
|
122
|
+
roots = ["package.json"]
|
|
123
|
+
language-id = "vue"
|
|
124
|
+
file-types = ["vue", "ts"]
|
|
125
|
+
language-servers = ["vue-language-server", "typescript-language-server"]
|
|
126
|
+
|
|
127
|
+
# Override the build-in config. The built-in configuration uses vtsls, but it seems incompatible with vue-language-server. It could also be that my configuration is incorrect.
|
|
128
|
+
# Others, such as JavaScript and TSX, can be added as needed.
|
|
129
|
+
[[language]]
|
|
130
|
+
name = "typescript"
|
|
131
|
+
language-id = "typescript"
|
|
132
|
+
file-types = ["ts", "mts", "cts"]
|
|
133
|
+
roots = ["package.json"]
|
|
134
|
+
language-servers = [
|
|
135
|
+
{ name = "typescript-language-server", except-features = [
|
|
136
|
+
"format",
|
|
137
|
+
] },
|
|
138
|
+
{ name = "eslint", support-workspace = true, config-files = [".eslintrc.js", ".eslintrc.cjs", ".eslintrc.yaml", ".eslintrc.yml", ".eslintrc", ".eslintrc.json", , "eslint.config.js", "eslint.config.mjs", "eslint.config.cjs", "eslint.config.ts", "eslint.config.mts", "eslint.config.cts"] },
|
|
139
|
+
]
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
- `except-features` can disable server's feature, view the [supported features](https://github.com/jadestrong/lsp-copilot/blob/c3d314d9bc1778b35c6ad2a046fa8b76cad94db4/src/syntax.rs#L150-L168).
|
|
143
|
+
|
|
144
|
+
## Debug
|
|
145
|
+
### Server bug
|
|
146
|
+
- `(setq lsp-proxy-log-level 3)`
|
|
147
|
+
- M-x `lsp-proxy-restart`
|
|
148
|
+
- M-x `lsp-proxy-open-log-file`
|
|
149
|
+
### Server crash
|
|
150
|
+
- Open `*lsp-proxy-events*` buffer
|
|
151
|
+
### Lsp server message
|
|
152
|
+
- Open `*lsp-proxy-log*`
|
|
153
|
+
|
|
154
|
+
## Commands
|
|
155
|
+
- `lsp-proxy-find-definition`
|
|
156
|
+
- `lsp-proxy-find-references`
|
|
157
|
+
- `lsp-proxy-find-declaration`
|
|
158
|
+
- `lsp-proxy-find-type-definition`
|
|
159
|
+
- `lsp-proxy-find-implementations`
|
|
160
|
+
- `lsp-proxy-format-buffer`
|
|
161
|
+
- `lsp-proxy-rename`
|
|
162
|
+
- `lsp-proxy-execute-code-action`
|
|
163
|
+
- `lsp-proxy-execute-command`
|
|
164
|
+
- `lsp-proxy-describe-thing-at-point`
|
|
165
|
+
- `lsp-proxy-show-project-diagnostics`
|
|
166
|
+
|
|
167
|
+
-----
|
|
168
|
+
- lsp-proxy-open-log-file
|
|
169
|
+
- lsp-proxy-open-config-file
|
|
170
|
+
- lsp-proxy-restart: Restart the server
|
|
171
|
+
- lsp-proxy-workspace-restart: Restart the LSP server for the current project
|
|
172
|
+
|
|
173
|
+
## Customization
|
|
174
|
+
| Variable | Default | Description |
|
|
175
|
+
| lsp-proxy-user-languages-config | `user-emacs-directory/lsp-proxy/languages.toml` | Where custom language server configurations are stored |
|
|
176
|
+
| lsp-proxy-log-file-directory | temporary-file-directory | Log file storage directory |
|
|
177
|
+
| lsp-proxy-log-level | 1 | A number indicating the log level. Defaults to 1. Warn = 0, Info = 1, Debug = 2, Trace = 3 |
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
## Recommend config
|
|
181
|
+
### Company and Corfu
|
|
182
|
+
```elisp
|
|
183
|
+
;; company
|
|
184
|
+
(setq company-idle-delay 0)
|
|
185
|
+
;; If you encounter issues when typing Vue directives (e.g., v-), you can try setting it to 1. I'm not sure if it's a problem with Volar.
|
|
186
|
+
(setq company-minimum-prefix-length 2)
|
|
187
|
+
(setq company-tooltip-idle-delay 0)
|
|
188
|
+
|
|
189
|
+
;; corfu
|
|
190
|
+
(setq corfu-auto-delay 0)
|
|
191
|
+
(setq corfu-popupinfo-delay '(0.1 . 0.1))
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### company-box
|
|
195
|
+
```elisp
|
|
196
|
+
(defun company-box-icons--lsp-proxy (candidate)
|
|
197
|
+
(-when-let* ((proxy-item (get-text-property 0 'lsp-proxy--item candidate))
|
|
198
|
+
(lsp-item (plist-get proxy-item :item))
|
|
199
|
+
(kind-num (plist-get lsp-item :kind)))
|
|
200
|
+
(alist-get kind-num company-box-icons--lsp-alist)))
|
|
201
|
+
|
|
202
|
+
(setq company-box-icons-functions
|
|
203
|
+
(cons #'company-box-icons--lsp-proxy company-box-icons-functions))
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### tabnine
|
|
207
|
+
Install [tabnine](https://github.com/shuxiao9058/tabnine) package first, then add the following configuration to your config:
|
|
208
|
+
```elisp
|
|
209
|
+
(when (fboundp #'tabnine-completion-at-point)
|
|
210
|
+
(add-hook 'lsp-proxy-mode-hook
|
|
211
|
+
(defun lsp-proxy-capf ()
|
|
212
|
+
(remove-hook 'completion-at-point-functions #'lsp-proxy-completion-at-point t)
|
|
213
|
+
(add-hook 'completion-at-point-functions
|
|
214
|
+
(cape-capf-super
|
|
215
|
+
#'lsp-proxy-completion-at-point
|
|
216
|
+
#'tabnine-completion-at-point) nil t))))
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### flycheck / flymake
|
|
220
|
+
Flycheck enabled default if flycheck-mode is installed. You can also select *flymake* by:
|
|
221
|
+
```elisp
|
|
222
|
+
(setq lsp-proxy-diagnostics-provider :flymake)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Acknowledgements
|
|
226
|
+
Thanks to [Helix](https://github.com/helix-editor/helix), the architecture of Lsp-Proxy Server is entirely based on Helix's implementation. Language configuration and communication with different language servers are all dependent on Helix. As a Rust beginner, I've gained a lot from this approach during the implementation.
|
|
227
|
+
|
|
228
|
+
Regarding the communication between Emacs and Lsp-Proxy, I would like to especially thank [copilot.el](https://github.com/copilot-emacs/copilot.el) and [rust-analyzer](https://github.com/rust-lang/rust-analyzer). The usage of jsonrpc.el was learned from copilot.el, while the approach to receiving and handling Emacs requests was inspired by the implementation in rust-analyzer.
|
|
229
|
+
|
|
230
|
+
The various methods used to implement LSP-related functionality on the Emacs side were learned from [lsp-mode](https://github.com/emacs-lsp/lsp-mode) and [eglot](https://github.com/joaotavora/eglot). Without their guidance, many of these features would have been difficult to implement.
|
|
231
|
+
|
|
232
|
+
Regarding the communication data format between Emacs and Lsp-Proxy, I would like to especially thank [emacs-lsp-booster](https://github.com/blahgeek/emacs-lsp-booster). The project integrates the implementation of emacs-lsp-booster, which encodes the JSON data returned to Emacs, further reducing the load on Emacs.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "emacs-lsp-proxy",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"postinstall": "node ./install.js"
|
|
6
6
|
},
|
|
@@ -10,14 +10,18 @@
|
|
|
10
10
|
"publicConfig": {
|
|
11
11
|
"access": "public"
|
|
12
12
|
},
|
|
13
|
-
"keywords": [
|
|
13
|
+
"keywords": [
|
|
14
|
+
"emacs",
|
|
15
|
+
"lsp",
|
|
16
|
+
"rust"
|
|
17
|
+
],
|
|
14
18
|
"author": "jadestrong",
|
|
15
19
|
"optionalDependencies": {
|
|
16
|
-
"@emacs-lsp-proxy/darwin-x64": "0.
|
|
17
|
-
"@emacs-lsp-proxy/darwin-arm64": "0.
|
|
18
|
-
"@emacs-lsp-proxy/linux-x64": "0.
|
|
19
|
-
"@emacs-lsp-proxy/linux-arm64": "0.
|
|
20
|
-
"@emacs-lsp-proxy/win32-x64": "0.
|
|
20
|
+
"@emacs-lsp-proxy/darwin-x64": "0.5.3",
|
|
21
|
+
"@emacs-lsp-proxy/darwin-arm64": "0.5.3",
|
|
22
|
+
"@emacs-lsp-proxy/linux-x64": "0.5.3",
|
|
23
|
+
"@emacs-lsp-proxy/linux-arm64": "0.5.3",
|
|
24
|
+
"@emacs-lsp-proxy/win32-x64": "0.5.3"
|
|
21
25
|
},
|
|
22
26
|
"license": "ISC",
|
|
23
27
|
"description": "An LSP client for Emacs implemented in Rust."
|