Skip to content

Commit 467d95e

Browse files
authored
feat: implement textDocument/codeLens feature (pmizio#165)
1 parent f7c4576 commit 467d95e

22 files changed

+451
-66
lines changed

README.md

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,13 @@ require("typescript-tools").setup {
144144
-- mirror of VSCode's `typescript.suggest.completeFunctionCalls`
145145
complete_function_calls = false,
146146
include_completions_with_insert_text = true,
147+
-- CodeLens
148+
-- WARNING: Experimental feature also in VSCode, because it might hit performance of server.
149+
-- possible values: ("off"|"all"|"implementations_only"|"references_only")
150+
code_lens = "off",
151+
-- by default code lenses are displayed on all referencable values and for some of you it can
152+
-- be too much this option reduce count of them by removing member references from lenses
153+
disable_member_code_lens = true,
147154
},
148155
}
149156
```
@@ -241,36 +248,36 @@ This plugin provides several custom user commands (they are only applied to curr
241248

242249
## Supported LSP methods
243250

244-
| Status | Request |
245-
| ------ | ------------------------------------------------------------------------------------- |
246-
|| textDocument/completion |
247-
|| textDocument/hover |
248-
|| textDocument/rename |
249-
|| textDocument/publishDiagnostics |
250-
|| textDocument/signatureHelp |
251-
|| textDocument/references |
252-
|| textDocument/definition |
253-
|| textDocument/typeDefinition |
254-
|| textDocument/implementation |
255-
|| textDocument/documentSymbol |
256-
|| textDocument/documentHighlight |
257-
|| textDocument/codeAction |
258-
|| textDocument/formatting |
259-
|| textDocument/rangeFormatting |
260-
|| textDocument/foldingRange |
261-
|| textDocument/semanticTokens/full (supported from TS v4.1) |
262-
|| textDocument/inlayHint (supported from TS v4.4) |
263-
|| callHierarchy/incomingCalls |
264-
|| callHierarchy/outgoingCalls |
265-
| 🚧 | textDocument/codeLens([#39](https://github.com/pmizio/typescript-tools.nvim/pull/39)) |
266-
| 🚧 | textDocument/linkedEditingRange (planned) |
267-
|| workspace/symbol |
268-
|| workspace/willRenameFiles |
269-
|| workspace/applyEdit - N/A |
270-
|| textDocument/declaration - N/A |
271-
|| window/logMessage - N/A |
272-
|| window/showMessage - N/A |
273-
|| window/showMessageRequest - N/A |
251+
| Status | Request |
252+
| ------ | --------------------------------------------------------- |
253+
|| textDocument/completion |
254+
|| textDocument/hover |
255+
|| textDocument/rename |
256+
|| textDocument/publishDiagnostics |
257+
|| textDocument/signatureHelp |
258+
|| textDocument/references |
259+
|| textDocument/definition |
260+
|| textDocument/typeDefinition |
261+
|| textDocument/implementation |
262+
|| textDocument/documentSymbol |
263+
|| textDocument/documentHighlight |
264+
|| textDocument/codeAction |
265+
|| textDocument/formatting |
266+
|| textDocument/rangeFormatting |
267+
|| textDocument/foldingRange |
268+
|| textDocument/semanticTokens/full (supported from TS v4.1) |
269+
|| textDocument/inlayHint (supported from TS v4.4) |
270+
|| callHierarchy/incomingCalls |
271+
|| callHierarchy/outgoingCalls |
272+
| | textDocument/codeLens |
273+
| 🚧 | textDocument/linkedEditingRange (planned) |
274+
|| workspace/symbol |
275+
|| workspace/willRenameFiles |
276+
|| workspace/applyEdit - N/A |
277+
|| textDocument/declaration - N/A |
278+
|| window/logMessage - N/A |
279+
|| window/showMessage - N/A |
280+
|| window/showMessageRequest - N/A |
274281

275282
## 🚦 Roadmap
276283

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
local api = vim.api
2+
3+
local common = require "typescript-tools.autocommands.common"
4+
5+
local M = {}
6+
7+
function M.setup_code_lens_autocmds()
8+
local augroup = vim.api.nvim_create_augroup("TypescriptToolsCodeLensGroup", { clear = true })
9+
10+
common.create_lsp_attach_augcmd(function()
11+
pcall(vim.lsp.codelens.refresh)
12+
13+
api.nvim_create_autocmd({ "BufEnter", "InsertLeave", "CursorHold" }, {
14+
pattern = M.extensions_pattern,
15+
callback = function(e)
16+
---@type string
17+
local file = e.file
18+
19+
if file and file:find "%w+://.*" then
20+
return
21+
end
22+
23+
pcall(vim.lsp.codelens.refresh)
24+
end,
25+
group = augroup,
26+
})
27+
end, augroup)
28+
end
29+
30+
return M
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
local api = vim.api
2+
local plugin_config = require "typescript-tools.config"
3+
4+
local M = {}
5+
6+
M.extensions_pattern = { "*.js", "*.mjs", "*.jsx", "*.ts", "*.tsx", "*.mts" }
7+
8+
---@param callback function
9+
---@param augroup number
10+
function M.create_lsp_attach_augcmd(callback, augroup)
11+
local initialized = false
12+
13+
api.nvim_create_autocmd("LspAttach", {
14+
callback = function(e)
15+
local client = vim.lsp.get_client_by_id(e.data.client_id)
16+
17+
if (client and client.name ~= plugin_config.plugin_name) or initialized then
18+
return
19+
end
20+
21+
initialized = true
22+
23+
callback(e)
24+
end,
25+
group = augroup,
26+
})
27+
end
28+
29+
return M

lua/typescript-tools/autocommands/diagnostics.lua

Lines changed: 21 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ local plugin_config = require "typescript-tools.config"
55
local utils = require "typescript-tools.utils"
66
local plugin_api = require "typescript-tools.api"
77
local proto_utils = require "typescript-tools.protocol.utils"
8+
local common = require "typescript-tools.autocommands.common"
89

910
local publish_diagnostic_mode = plugin_config.publish_diagnostic_mode
1011

11-
local extensions_pattern = { "*.js", "*.mjs", "*.jsx", "*.ts", "*.tsx", "*.mts" }
12-
1312
local M = {}
1413

1514
local function request_diagnostics_api_wrapper()
@@ -19,9 +18,10 @@ end
1918
local request_diagnostics_throttled = utils.throttle(200, request_diagnostics_api_wrapper)
2019
local request_diagnostics_debounced = utils.debounce(200, request_diagnostics_api_wrapper)
2120

22-
---@param augroup number
2321
---@param dispatchers Dispatchers
24-
function M.setup_diagnostic_autocmds(augroup, dispatchers)
22+
function M.setup_diagnostic_autocmds(dispatchers)
23+
local augroup = vim.api.nvim_create_augroup("TypescriptToolsDiagnosticGroup", { clear = true })
24+
2525
if plugin_config.publish_diagnostic_on == publish_diagnostic_mode.change then
2626
api.nvim_create_autocmd("User", {
2727
pattern = {
@@ -33,37 +33,24 @@ function M.setup_diagnostic_autocmds(augroup, dispatchers)
3333
})
3434
end
3535

36-
local initialized = false
37-
3836
if plugin_config.publish_diagnostic_on == publish_diagnostic_mode.insert_leave then
39-
api.nvim_create_autocmd("LspAttach", {
40-
callback = function(lsp_event)
41-
local client = vim.lsp.get_client_by_id(lsp_event.data.client_id)
42-
43-
if (client and client.name ~= plugin_config.plugin_name) or initialized then
44-
return
45-
end
46-
47-
initialized = true
48-
49-
request_diagnostics_debounced()
50-
51-
api.nvim_create_autocmd("InsertEnter", {
52-
pattern = extensions_pattern,
53-
callback = function(e)
54-
proto_utils.publish_diagnostics(dispatchers, vim.uri_from_bufnr(e.buf), {})
55-
end,
56-
group = augroup,
57-
})
58-
59-
api.nvim_create_autocmd({ "BufEnter", "InsertLeave", "TextChanged" }, {
60-
pattern = extensions_pattern,
61-
callback = request_diagnostics_debounced,
62-
group = augroup,
63-
})
64-
end,
65-
group = augroup,
66-
})
37+
common.create_lsp_attach_augcmd(function()
38+
request_diagnostics_debounced()
39+
40+
api.nvim_create_autocmd("InsertEnter", {
41+
pattern = M.extensions_pattern,
42+
callback = function(e)
43+
proto_utils.publish_diagnostics(dispatchers, vim.uri_from_bufnr(e.buf), {})
44+
end,
45+
group = augroup,
46+
})
47+
48+
api.nvim_create_autocmd({ "BufEnter", "InsertLeave", "TextChanged" }, {
49+
pattern = M.extensions_pattern,
50+
callback = request_diagnostics_debounced,
51+
group = augroup,
52+
})
53+
end, augroup)
6754
end
6855
end
6956

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
local diagnostics = require "typescript-tools.autocommands.diagnostics"
2+
local code_lens = require "typescript-tools.autocommands.code_lens"
3+
local config = require "typescript-tools.config"
24

35
local M = {}
46

57
---@param dispatchers Dispatchers
68
function M.setup_autocommands(dispatchers)
7-
local group = vim.api.nvim_create_augroup("TypescriptToolsGroup", { clear = true })
9+
diagnostics.setup_diagnostic_autocmds(dispatchers)
810

9-
diagnostics.setup_diagnostic_autocmds(group, dispatchers)
11+
if config.code_lens ~= config.code_lens_mode.off then
12+
code_lens.setup_code_lens_autocmds()
13+
end
1014
end
1115

1216
return M

lua/typescript-tools/capabilities.lua

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ local lsp_protocol = require "vim.lsp.protocol"
22
local TsserverProvider = require "typescript-tools.tsserver_provider"
33
local utils = require "typescript-tools.utils"
44
local c = require "typescript-tools.protocol.constants"
5+
local config = require "typescript-tools.config"
56

67
local function make_capabilities()
78
local tsserver_provider = TsserverProvider.get_instance()
@@ -13,6 +14,8 @@ local function make_capabilities()
1314
commands = {
1415
c.InternalCommands.InvokeAdditionalRename,
1516
c.InternalCommands.CallApiFunction,
17+
c.InternalCommands.RequestReferences,
18+
c.InternalCommands.RequestImplementations,
1619
},
1720
},
1821
renameProvider = {
@@ -110,6 +113,11 @@ local function make_capabilities()
110113
documentRangeFormattingProvider = true,
111114
callHierarchyProvider = true,
112115
workspaceSymbolProvider = true,
116+
codeLensProvider = (config.code_lens == config.code_lens_mode.off or not vim.treesitter)
117+
and false
118+
or {
119+
resolveProvider = true,
120+
},
113121
}
114122
end
115123

lua/typescript-tools/config.lua

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
---@field complete_function_calls boolean
1212
---@field expose_as_code_action ("fix_all"| "add_missing_imports"| "remove_unused" | "remove_unused_imports")[]
1313
---@field include_completions_with_insert_text boolean
14+
---@field code_lens code_lens_mode
15+
---@field disable_member_code_lens boolean
1416
local M = {}
1517
local __store = {}
1618

@@ -78,6 +80,14 @@ M.publish_diagnostic_mode = {
7880
change = "change",
7981
}
8082

83+
---@enum code_lens_mode
84+
M.code_lens_mode = {
85+
all = "all",
86+
implementations_only = "implementations_only",
87+
references_only = "references_only",
88+
off = "off",
89+
}
90+
8191
M.plugin_name = "typescript-tools"
8292

8393
---@param settings table
@@ -119,6 +129,8 @@ function M.load_settings(settings)
119129
"boolean",
120130
true,
121131
},
132+
["settings.code_lens"] = { settings.code_lens, "string", true },
133+
["settings.disable_member_code_lens"] = { settings.disable_member_code_lens, "boolean", true },
122134
}
123135

124136
__store = vim.tbl_deep_extend("force", __store, settings)
@@ -162,6 +174,10 @@ function M.load_settings(settings)
162174
if not settings.include_completions_with_insert_text then
163175
__store.include_completions_with_insert_text = true
164176
end
177+
178+
if not M.code_lens_mode[settings.code_lens] then
179+
__store.code_lens = M.code_lens_mode.off
180+
end
165181
end
166182

167183
setmetatable(M, {

lua/typescript-tools/internal_commands.lua

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,12 @@ M[c.InternalCommands.CallApiFunction] = function(params)
4949
end
5050
end
5151

52+
M[c.InternalCommands.RequestReferences] = function(params)
53+
vim.lsp.buf_request(0, c.LspMethods.Reference, params.arguments)
54+
end
55+
56+
M[c.InternalCommands.RequestImplementations] = function(params)
57+
vim.lsp.buf_request(0, c.LspMethods.Implementation, params.arguments)
58+
end
59+
5260
return M

lua/typescript-tools/protocol/constants.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ return {
77
InternalCommands = {
88
InvokeAdditionalRename = "invoke_additional_rename",
99
CallApiFunction = "call_api_function",
10+
RequestReferences = "request_references",
11+
RequestImplementations = "request_implementations",
1012
},
1113
---@enum CommandTypes
1214
CommandTypes = {
@@ -226,6 +228,8 @@ return {
226228
ExecuteCommand = "workspace/executeCommand",
227229
WillRenameFiles = "workspace/willRenameFiles",
228230
CancelRequest = "$/cancelRequest",
231+
CodeLens = "textDocument/codeLens",
232+
CodeLensResolve = "codeLens/resolve",
229233
},
230234
---@enum CustomMethods
231235
CustomMethods = {

lua/typescript-tools/protocol/module_mapper.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ local remapped_methods = {
1010
[c.CustomMethods.OrganizeImports] = "text_document.organize_imports",
1111
[c.CustomMethods.Diagnostic] = "text_document.custom_diagnostic",
1212
[c.CustomMethods.BatchCodeActions] = "text_document.code_action.batch",
13+
[c.LspMethods.CodeLensResolve] = "text_document.code_lens.resolve",
1314
}
1415

1516
local noop_methods = { c.LspMethods.DidSave }

0 commit comments

Comments
 (0)