整理一个能重现问题的最小配置。
$ emacs -Q --eval "(最小配置)"
整理一个能重现问题的最小配置。
$ emacs -Q --eval "(最小配置)"
我修改了你的标题:
- lsp-bridge怎么去掉不匹配的补全项? 现在不匹配的就一直在那,还挺多
+ lsp-bridge怎么去掉不匹配的补全项?
最小配置启动,只加载lsp相关的配置没问题的。 这个,我怎么排查呢要,,有哪些会影响lsp的补全?
还是有问题。不启动typescript-mode就看起来正常,lsp的补全不会赖着不消失。 启动后就全是Field Method 之类的不匹配的补全。
二分法:
(require 'cl)
(defun add-subdirs-to-load-path (search-dir)
(interactive)
(let* ((dir (file-name-as-directory search-dir)))
(dolist (subdir
;; 过滤出不必要的目录,提升Emacs启动速度
(cl-remove-if
#'(lambda (subdir)
(or
;; 不是目录的文件都移除
(not (file-directory-p (concat dir subdir)))
;; 父目录、 语言相关和版本控制目录都移除
(member subdir '("." ".."
"dist" "node_modules" "__pycache__"
"RCS" "CVS" "rcs" "cvs" ".git" ".github"))))
(directory-files dir)))
(let ((subdir-path (concat dir (file-name-as-directory subdir))))
;; 目录下有 .el .so .dll 文件的路径才添加到 `load-path' 中,提升Emacs启动速度
(when (cl-some #'(lambda (subdir-file)
(and (file-regular-p (concat subdir-path subdir-file))
;; .so .dll 文件指非Elisp语言编写的Emacs动态库
(member (file-name-extension subdir-file) '("el" "so" "dll"))))
(directory-files subdir-path))
;; 注意:`add-to-list' 函数的第三个参数必须为 t ,表示加到列表末尾
;; 这样Emacs会从父目录到子目录的顺序搜索Elisp插件,顺序反过来会导致Emacs无法正常启动
(add-to-list 'load-path subdir-path t))
;; 继续递归搜索子目录
(add-subdirs-to-load-path subdir-path)))))
(add-subdirs-to-load-path "~/.emacs.d/packages")
(require 'use-package)
(use-package yasnippet :ensure t)
(require 'lsp-bridge)
(require 'lsp-bridge-jdtls)
;;; Code:
(require 'typescript-mode)
(add-to-list 'auto-mode-alist '("\\.ts\\'" . typescript-mode))
(global-lsp-bridge-mode)
还是这个样子。
的确是有问题,不过你的最小配置和测试样例都太复杂了。我做了一些简化:
$ cat ~/Downloads/test.ts
interface User {
name: string;
id: number;
}
class UserAccount {
name: string;
id: number;
constructor(name: string, id: number) {
this.name = name;
this.id = id;
}
}
$ emacsq.sh -L ~/repos/emacs-lsp-bridge \
-L ~/repos/emacs-acm-terminal \
-P yasnippet,typescript-mode,lsp-bridge,acm-terminal --eval \
"(progn
(add-to-list 'auto-mode-alist '(\"\\.ts\\'\" . typescript-mode))
(global-lsp-bridge-mode))" -nw ~/Downloads/test.ts
@manateelazycat 我单步调试了一下发现 acm-backend-lsp-candidates
返回的条目数没有变化。
02.013秒
02.063
我录屏抓了一帧一闪而过的不同结果,不知道有没有关系。
你如果 emacs -Q 只加载 lsp-bridge 没有问题, 你就应该耐心的用二分注释法排查你配置的问题。
没有哪个人有能力看一眼截图就能猜测你复杂配置中哪一行配置有问题。
期望是 this.时补全里有id和name,输入i后,因为name里面没有id,所以补全里面就没有name这一项
试过了, 只加载lsp-bridge就上面回复的有问题结果,
好, 我知道了, 我看看
我看了一下 lsp-bridge 日志:
--- Send (notification): textDocument/didChange
{
"method": "textDocument/didChange",
"params": {
"textDocument": {
"uri": "file:///home/andy/test.ts",
"version": 14
},
"contentChanges": [
{
"range": {
"start": {
"line": 12,
"character": 11
},
"end": {
"line": 12,
"character": 11
}
},
"rangeLength": 0,
"text": "i"
}
]
},
"jsonrpc": "2.0"
}
Eval in Emacs: (lsp-bridge-search-file-words--record-items '())
--- Send (13176): textDocument/completion
{
"id": 13176,
"method": "textDocument/completion",
"params": {
"position": {
"line": 12,
"character": 12
},
"context": {
"triggerKind": 1
},
"textDocument": {
"uri": "file:///home/andy/test.ts"
}
},
"jsonrpc": "2.0"
}
--- Recv response typescript (13176): textDocument/completion
{
"jsonrpc": "2.0",
"id": 13176,
"result": [
{
"label": "id",
"kind": 5,
"sortText": "11",
"commitCharacters": [
".",
",",
"("
],
"data": {
"file": "/home/andy/test.ts",
"line": 13,
"offset": 13,
"entryNames": [
"id"
]
}
},
{
"label": "name",
"kind": 5,
"sortText": "11",
"commitCharacters": [
".",
",",
"("
],
"data": {
"file": "/home/andy/test.ts",
"line": 13,
"offset": 13,
"entryNames": [
"name"
]
}
}
]
}
上面日志就三句话, this. 以后输入 i
这个字符, 并发送 textDocument/didChange 和 textDocument/completion 请求, LSP Server 服务器返回的内容就包括 id
和 name
的补全列表。
按照道理来说, 输入 i
不应该返回 name
的, 但是 LSP Sever 返回了多余的 name, lsp-bridge 应该遵照协议显示 LSP Server 返回的所有补全项。
这个问题, 你需要研究一下 typescript-language-server 的配置, 或者给 typescript-language-server 报 bug, 这个问题不是 lsp-bridge 的 bug
this.base类型是any时
this.ba 补全 为this.base 然后输入点. 补全项就是tabnine而不是lsp的不匹配的东西
this.ba 继续输入base,没有使用lsp-bridge的补全来补全base时,输入点. 补全项就是lsp的奇怪东西。
这是不是我如果一直不使用lsp的补全,弹出的就一直还是最开头哪个this的补全项啊。。。。
用 lsp-mode
测了情况刚好相反,输入 i
之后就收不到 completion
返回了:
[Trace - 03:06:48 PM] Sending notification 'textDocument/didChange'.
Params: {
"textDocument": {
"uri": "file:///Users/gqj/Downloads/test.ts",
"version": 1
},
"contentChanges": [
{
"range": {
"start": {
"line": 10,
"character": 12
},
"end": {
"line": 10,
"character": 12
}
},
"rangeLength": 0,
"text": "."
}
]
}
[Trace - 03:06:48 PM] Sending request 'textDocument/completion - (22)'.
Params: {
"textDocument": {
"uri": "file:///Users/gqj/Downloads/test.ts"
},
"position": {
"line": 10,
"character": 13
},
"context": {
"triggerKind": 2,
"triggerCharacter": "."
}
}
[Trace - 03:06:48 PM] Received response 'textDocument/completion - (22)' in 50ms.
Result: {
"items": [
{
"label": "id",
"kind": 5,
"sortText": "11",
"commitCharacters": [
".",
",",
"("
],
"data": {
"file": "/Users/gqj/Downloads/test.ts",
"line": 11,
"offset": 14,
"entryNames": [
"id"
]
}
},
{
"label": "name",
"kind": 5,
"sortText": "11",
"commitCharacters": [
".",
",",
"("
],
"data": {
"file": "/Users/gqj/Downloads/test.ts",
"line": 11,
"offset": 14,
"entryNames": [
"name"
]
}
}
],
"isIncomplete": null
}
[Trace - 03:06:48 PM] Received notification 'textDocument/publishDiagnostics'.
Params: {
"uri": "file:///Users/gqj/Downloads/test.ts",
"diagnostics": [
{
"range": {
"start": {
"line": 11,
"character": 8
},
"end": {
"line": 11,
"character": 12
}
},
"message": "Property 'this' does not exist on type 'UserAccount'.",
"severity": 1,
"code": 2339,
"source": "typescript",
"tags": []
}
]
}
[Trace - 03:06:50 PM] Sending notification 'textDocument/didChange'.
Params: {
"textDocument": {
"uri": "file:///Users/gqj/Downloads/test.ts",
"version": 2
},
"contentChanges": [
{
"range": {
"start": {
"line": 10,
"character": 13
},
"end": {
"line": 10,
"character": 13
}
},
"rangeLength": 0,
"text": "i"
}
]
}
[Trace - 03:06:50 PM] Received notification 'textDocument/publishDiagnostics'.
Params: {
"uri": "file:///Users/gqj/Downloads/test.ts",
"diagnostics": [
{
"range": {
"start": {
"line": 10,
"character": 13
},
"end": {
"line": 10,
"character": 14
}
},
"message": "Property 'i' does not exist on type 'UserAccount'.",
"severity": 1,
"code": 2339,
"source": "typescript",
"tags": []
}
]
}
[Trace - 03:06:50 PM] Sending request 'textDocument/documentSymbol - (23)'.
Params: {
"textDocument": {
"uri": "file:///Users/gqj/Downloads/test.ts"
}
}
[Trace - 03:06:50 PM] Sending request 'textDocument/codeAction - (24)'.
Params: {
"textDocument": {
"uri": "file:///Users/gqj/Downloads/test.ts"
},
"range": {
"start": {
"line": 10,
"character": 14
},
"end": {
"line": 10,
"character": 14
}
},
"context": {
"diagnostics": [
{
"range": {
"start": {
"line": 10,
"character": 13
},
"end": {
"line": 10,
"character": 14
}
},
"message": "Property 'i' does not exist on type 'UserAccount'.",
"severity": 1,
"code": 2339,
"source": "typescript",
"tags": []
}
]
}
}
[Trace - 03:06:50 PM] Received response 'textDocument/documentSymbol - (23)' in 28ms.
Result: [
{
"name": "User",
"detail": "",
"kind": 11,
"range": {
"start": {
"line": 0,
"character": 0
},
"end": {
"line": 3,
"character": 1
}
},
"selectionRange": {
"start": {
"line": 0,
"character": 10
},
"end": {
"line": 0,
"character": 14
}
},
"children": [
{
"name": "id",
"detail": "",
"kind": 7,
"range": {
"start": {
"line": 2,
"character": 4
},
"end": {
"line": 2,
"character": 15
}
},
"selectionRange": {
"start": {
"line": 2,
"character": 4
},
"end": {
"line": 2,
"character": 6
}
},
"children": []
},
{
"name": "name",
"detail": "",
"kind": 7,
"range": {
"start": {
"line": 1,
"character": 4
},
"end": {
"line": 1,
"character": 17
}
},
"selectionRange": {
"start": {
"line": 1,
"character": 4
},
"end": {
"line": 1,
"character": 8
}
},
"children": []
}
]
},
{
"name": "UserAccount",
"detail": "",
"kind": 5,
"range": {
"start": {
"line": 5,
"character": 0
},
"end": {
"line": 14,
"character": 1
}
},
"selectionRange": {
"start": {
"line": 5,
"character": 6
},
"end": {
"line": 5,
"character": 17
}
},
"children": [
{
"name": "constructor",
"detail": "",
"kind": 9,
"range": {
"start": {
"line": 9,
"character": 4
},
"end": {
"line": 13,
"character": 5
}
},
"selectionRange": {
"start": {
"line": 9,
"character": 4
},
"end": {
"line": 13,
"character": 5
}
},
"children": []
},
{
"name": "id",
"detail": "",
"kind": 7,
"range": {
"start": {
"line": 7,
"character": 4
},
"end": {
"line": 7,
"character": 15
}
},
"selectionRange": {
"start": {
"line": 7,
"character": 4
},
"end": {
"line": 7,
"character": 6
}
},
"children": []
},
{
"name": "name",
"detail": "",
"kind": 7,
"range": {
"start": {
"line": 6,
"character": 4
},
"end": {
"line": 6,
"character": 17
}
},
"selectionRange": {
"start": {
"line": 6,
"character": 4
},
"end": {
"line": 6,
"character": 8
}
},
"children": []
}
]
}
]
[Trace - 03:06:50 PM] Received response 'textDocument/codeAction - (24)' in 28ms.
Result: []
[Trace - 03:07:16 PM] Sending request 'textDocument/codeAction - (25)'.
Params: {
"textDocument": {
"uri": "file:///Users/gqj/Downloads/test.ts"
},
"range": {
"start": {
"line": 10,
"character": 14
},
"end": {
"line": 10,
"character": 14
}
},
"context": {
"diagnostics": [
{
"range": {
"start": {
"line": 10,
"character": 13
},
"end": {
"line": 10,
"character": 14
}
},
"message": "Property 'i' does not exist on type 'UserAccount'.",
"severity": 1,
"code": 2339,
"source": "typescript",
"tags": []
}
]
}
}
[Trace - 03:07:16 PM] Received response 'textDocument/codeAction - (25)' in 5ms.
Result: []
[Trace - 03:07:17 PM] Sending notification 'textDocument/didChange'.
Params: {
"textDocument": {
"uri": "file:///Users/gqj/Downloads/test.ts",
"version": 3
},
"contentChanges": [
{
"range": {
"start": {
"line": 10,
"character": 13
},
"end": {
"line": 10,
"character": 14
}
},
"rangeLength": 1,
"text": ""
}
]
}
[Trace - 03:07:18 PM] Sending notification 'textDocument/didChange'.
Params: {
"textDocument": {
"uri": "file:///Users/gqj/Downloads/test.ts",
"version": 4
},
"contentChanges": [
{
"range": {
"start": {
"line": 10,
"character": 12
},
"end": {
"line": 10,
"character": 13
}
},
"rangeLength": 1,
"text": ""
}
]
}
[Trace - 03:07:18 PM] Received notification 'textDocument/publishDiagnostics'.
Params: {
"uri": "file:///Users/gqj/Downloads/test.ts",
"diagnostics": []
}
[Trace - 03:07:18 PM] Sending notification 'textDocument/didChange'.
Params: {
"textDocument": {
"uri": "file:///Users/gqj/Downloads/test.ts",
"version": 5
},
"contentChanges": [
{
"range": {
"start": {
"line": 10,
"character": 12
},
"end": {
"line": 10,
"character": 12
}
},
"rangeLength": 0,
"text": "."
}
]
}
[Trace - 03:07:18 PM] Received notification 'textDocument/publishDiagnostics'.
Params: {
"uri": "file:///Users/gqj/Downloads/test.ts",
"diagnostics": [
{
"range": {
"start": {
"line": 11,
"character": 8
},
"end": {
"line": 11,
"character": 12
}
},
"message": "Property 'this' does not exist on type 'UserAccount'.",
"severity": 1,
"code": 2339,
"source": "typescript",
"tags": []
}
]
}
[Trace - 03:07:19 PM] Sending notification 'textDocument/didChange'.
Params: {
"textDocument": {
"uri": "file:///Users/gqj/Downloads/test.ts",
"version": 6
},
"contentChanges": [
{
"range": {
"start": {
"line": 10,
"character": 13
},
"end": {
"line": 10,
"character": 13
}
},
"rangeLength": 0,
"text": "i"
}
]
}
[Trace - 03:07:20 PM] Received notification 'textDocument/publishDiagnostics'.
Params: {
"uri": "file:///Users/gqj/Downloads/test.ts",
"diagnostics": [
{
"range": {
"start": {
"line": 10,
"character": 13
},
"end": {
"line": 10,
"character": 14
}
},
"message": "Property 'i' does not exist on type 'UserAccount'.",
"severity": 1,
"code": 2339,
"source": "typescript",
"tags": []
}
]
}
[Trace - 03:07:20 PM] Sending request 'textDocument/documentSymbol - (26)'.
Params: {
"textDocument": {
"uri": "file:///Users/gqj/Downloads/test.ts"
}
}
[Trace - 03:07:20 PM] Sending request 'textDocument/codeAction - (27)'.
Params: {
"textDocument": {
"uri": "file:///Users/gqj/Downloads/test.ts"
},
"range": {
"start": {
"line": 10,
"character": 14
},
"end": {
"line": 10,
"character": 14
}
},
"context": {
"diagnostics": [
{
"range": {
"start": {
"line": 10,
"character": 13
},
"end": {
"line": 10,
"character": 14
}
},
"message": "Property 'i' does not exist on type 'UserAccount'.",
"severity": 1,
"code": 2339,
"source": "typescript",
"tags": []
}
]
}
}
[Trace - 03:07:20 PM] Received response 'textDocument/documentSymbol - (26)' in 27ms.
Result: [
{
"name": "User",
"detail": "",
"kind": 11,
"range": {
"start": {
"line": 0,
"character": 0
},
"end": {
"line": 3,
"character": 1
}
},
"selectionRange": {
"start": {
"line": 0,
"character": 10
},
"end": {
"line": 0,
"character": 14
}
},
"children": [
{
"name": "id",
"detail": "",
"kind": 7,
"range": {
"start": {
"line": 2,
"character": 4
},
"end": {
"line": 2,
"character": 15
}
},
"selectionRange": {
"start": {
"line": 2,
"character": 4
},
"end": {
"line": 2,
"character": 6
}
},
"children": []
},
{
"name": "name",
"detail": "",
"kind": 7,
"range": {
"start": {
"line": 1,
"character": 4
},
"end": {
"line": 1,
"character": 17
}
},
"selectionRange": {
"start": {
"line": 1,
"character": 4
},
"end": {
"line": 1,
"character": 8
}
},
"children": []
}
]
},
{
"name": "UserAccount",
"detail": "",
"kind": 5,
"range": {
"start": {
"line": 5,
"character": 0
},
"end": {
"line": 14,
"character": 1
}
},
"selectionRange": {
"start": {
"line": 5,
"character": 6
},
"end": {
"line": 5,
"character": 17
}
},
"children": [
{
"name": "constructor",
"detail": "",
"kind": 9,
"range": {
"start": {
"line": 9,
"character": 4
},
"end": {
"line": 13,
"character": 5
}
},
"selectionRange": {
"start": {
"line": 9,
"character": 4
},
"end": {
"line": 13,
"character": 5
}
},
"children": []
},
{
"name": "id",
"detail": "",
"kind": 7,
"range": {
"start": {
"line": 7,
"character": 4
},
"end": {
"line": 7,
"character": 15
}
},
"selectionRange": {
"start": {
"line": 7,
"character": 4
},
"end": {
"line": 7,
"character": 6
}
},
"children": []
},
{
"name": "name",
"detail": "",
"kind": 7,
"range": {
"start": {
"line": 6,
"character": 4
},
"end": {
"line": 6,
"character": 17
}
},
"selectionRange": {
"start": {
"line": 6,
"character": 4
},
"end": {
"line": 6,
"character": 8
}
},
"children": []
}
]
}
]
[Trace - 03:07:20 PM] Received response 'textDocument/codeAction - (27)' in 28ms.
Result: []
用 eglot
也是收到多余的项,但是 eglot 最终给用户的反馈却是正常的,不知它做了什么特别处理:
[client-notification] Thu Nov 3 19:41:39 2022:
(:jsonrpc "2.0" :method "textDocument/didChange" :params
(:textDocument
(:uri "file:///Volumes/HDD/Users/gqj/Downloads/test.ts" :version 15)
:contentChanges
[(:range
(:start
(:line 10 :character 13)
:end
(:line 10 :character 13))
:rangeLength 0 :text "i")]))
[client-request] (id:64) Thu Nov 3 19:41:39 2022:
(:jsonrpc "2.0" :id 64 :method "textDocument/completion" :params
(:textDocument
(:uri "file:///Volumes/HDD/Users/gqj/Downloads/test.ts")
:position
(:line 10 :character 14)
:context
(:triggerKind 1)))
[server-reply] (id:64) Thu Nov 3 19:41:39 2022:
(:jsonrpc "2.0" :id 64 :result
(:items
[(:label "id" :kind 5 :sortText "11" :commitCharacters
["." "," "("]
:data
(:file "/Volumes/HDD/Users/gqj/Downloads/test.ts" :line 11 :offset 15 :entryNames
["id"]))
(:label "name" :kind 5 :sortText "11" :commitCharacters
["." "," "("]
:data
(:file "/Volumes/HDD/Users/gqj/Downloads/test.ts" :line 11 :offset 15 :entryNames
["name"]))]
:isIncomplete :json-false))
[client-request] (id:65) Thu Nov 3 19:41:39 2022:
(:jsonrpc "2.0" :id 65 :method "completionItem/resolve" :params
(:label
#("id" 0 1
(eglot--lsp-item #1))
:kind 5 :sortText "11" :commitCharacters
["." "," "("]
:data
(:file "/Volumes/HDD/Users/gqj/Downloads/test.ts" :line 11 :offset 15 :entryNames
["id"])))
[server-reply] (id:65) Thu Nov 3 19:41:39 2022:
(:jsonrpc "2.0" :id 65 :result
(:label "id" :kind 5 :sortText "11" :commitCharacters
["." "," "("]
:data
(:file "/Volumes/HDD/Users/gqj/Downloads/test.ts" :line 11 :offset 15 :entryNames
["id"])
:detail "(property) UserAccount.id: number"))
[server-notification] Thu Nov 3 19:41:40 2022:
(:jsonrpc "2.0" :method "textDocument/publishDiagnostics" :params
(:uri "file:///Volumes/HDD/Users/gqj/Downloads/test.ts" :diagnostics
[(:range
(:start
(:line 10 :character 13)
:end
(:line 10 :character 14))
:message "Property 'i' does not exist on type 'UserAccount'." :severity 1 :code 2339 :source "typescript" :tags
[])]))
[client-request] (id:66) Thu Nov 3 19:41:40 2022:
(:jsonrpc "2.0" :id 66 :method "textDocument/signatureHelp" :params
(:textDocument
(:uri "file:///Volumes/HDD/Users/gqj/Downloads/test.ts")
:position
(:line 10 :character 14)))
[client-request] (id:67) Thu Nov 3 19:41:40 2022:
(:jsonrpc "2.0" :id 67 :method "textDocument/hover" :params
(:textDocument
(:uri "file:///Volumes/HDD/Users/gqj/Downloads/test.ts")
:position
(:line 10 :character 14)))
[client-request] (id:68) Thu Nov 3 19:41:40 2022:
(:jsonrpc "2.0" :id 68 :method "textDocument/documentHighlight" :params
(:textDocument
(:uri "file:///Volumes/HDD/Users/gqj/Downloads/test.ts")
:position
(:line 10 :character 14)))
[server-reply] (id:66) Thu Nov 3 19:41:40 2022:
(:jsonrpc "2.0" :id 66 :result nil)
[server-reply] (id:67) Thu Nov 3 19:41:40 2022:
(:jsonrpc "2.0" :id 67 :result
(:contents
(:kind "markdown" :value "\n```typescript\nany\n```\n")
:range
(:start
(:line 10 :character 13)
:end
(:line 10 :character 14))))
[server-reply] (id:68) Thu Nov 3 19:41:40 2022:
(:jsonrpc "2.0" :id 68 :result
[])
[client-notification] Thu Nov 3 19:41:48 2022:
(:jsonrpc "2.0" :method "textDocument/didChange" :params
(:textDocument
(:uri "file:///Volumes/HDD/Users/gqj/Downloads/test.ts" :version 17)
:contentChanges
[(:range
(:start
(:line 10 :character 13)
:end
(:line 10 :character 14))
:rangeLength 1 :text "")
(:range
(:start
(:line 10 :character 13)
:end
(:line 10 :character 13))
:rangeLength 0 :text "id")]))
[client-request] (id:69) Thu Nov 3 19:41:48 2022:
(:jsonrpc "2.0" :id 69 :method "textDocument/signatureHelp" :params
(:textDocument
(:uri "file:///Volumes/HDD/Users/gqj/Downloads/test.ts")
:position
(:line 10 :character 15)))
[client-request] (id:70) Thu Nov 3 19:41:48 2022:
(:jsonrpc "2.0" :id 70 :method "textDocument/hover" :params
(:textDocument
(:uri "file:///Volumes/HDD/Users/gqj/Downloads/test.ts")
:position
(:line 10 :character 15)))
[client-request] (id:71) Thu Nov 3 19:41:48 2022:
(:jsonrpc "2.0" :id 71 :method "textDocument/documentHighlight" :params
(:textDocument
(:uri "file:///Volumes/HDD/Users/gqj/Downloads/test.ts")
:position
(:line 10 :character 15)))
[server-reply] (id:69) Thu Nov 3 19:41:48 2022:
(:jsonrpc "2.0" :id 69 :result nil)
[server-reply] (id:70) Thu Nov 3 19:41:48 2022:
(:jsonrpc "2.0" :id 70 :result
(:contents
(:kind "markdown" :value "\n```typescript\n(property) UserAccount.id: number\n```\n")
:range
(:start
(:line 10 :character 13)
:end
(:line 10 :character 15))))
[server-reply] (id:71) Thu Nov 3 19:41:48 2022:
(:jsonrpc "2.0" :id 71 :result
[(:kind 2 :range
(:start
(:line 7 :character 4)
:end
(:line 7 :character 6)))
(:kind 2 :range
(:start
(:line 10 :character 13)
:end
(:line 10 :character 15)))
(:kind 2 :range
(:start
(:line 12 :character 13)
:end
(:line 12 :chara
那是补全前端按照前缀过滤了。
你要研究 typescript-language-server 的文档, 我不知道啊。