Skip to content
This repository was archived by the owner on Jul 7, 2022. It is now read-only.

Commit a158ca9

Browse files
committed
Push for erikdotdev
1 parent bd3a8ed commit a158ca9

File tree

4 files changed

+158
-0
lines changed

4 files changed

+158
-0
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,10 @@
11
# lsp_extensions.nvim
2+
23
Repo to hold a bunch of info & extension callbacks for built-in LSP. Use at your own risk :wink:
4+
5+
6+
## Clips
7+
8+
- Showing Line Diagnostics: https://clips.twitch.tv/ProductiveBoxyPastaCoolStoryBro
9+
10+
- N E O V I M: https://clips.twitch.tv/SmoothGoodTurnipCmonBruh

lua/lsp_extensions/init.lua

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
--[[
3+
4+
Note to self:
5+
6+
Each extension should probably look like:
7+
8+
- get_callback(opts)
9+
-> opts configures how you would want this extension to run.
10+
11+
- get_params(opts)
12+
-> get the params you need to make the request
13+
14+
--]]
15+
local extensions = {}
16+
17+
18+
extensions.test = function(highlight)
19+
highlight = highlight or "Comment"
20+
21+
local inlay_hints = require('lsp_extensions.inlay_hints')
22+
vim.lsp.buf_request(0, 'rust-analyzer/inlayHints', inlay_hints.get_params(), inlay_hints.get_callback {
23+
only_current_line = false,
24+
aligned = true
25+
})
26+
end
27+
28+
return extensions

lua/lsp_extensions/inlay_hints.lua

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
--[[
2+
## Inlay Hints
3+
4+
**Method:** `rust-analyzer/inlayHints`
5+
6+
This request is send from client to server to render "inlay hints" -- virtual text inserted into editor to show things like inferred types.
7+
Generally, the client should re-query inlay hints after every modification.
8+
Note that we plan to move this request to `experimental/inlayHints`,
9+
as it is not really Rust-specific, but the current API is not necessary the right one.
10+
11+
**Request:**
12+
13+
```typescript
14+
interface InlayHintsParams {
15+
textDocument: TextDocumentIdentifier,
16+
}
17+
```
18+
19+
**Response:** `InlayHint[]`
20+
21+
```typescript
22+
interface InlayHint {
23+
kind: "TypeHint" | "ParameterHint" | "ChainingHint",
24+
range: Range,
25+
label: string,
26+
}
27+
```
28+
--]]
29+
30+
local inlay_hints = {}
31+
32+
local inlay_hints_ns = vim.api.nvim_create_namespace('lsp_extensions.inlay_hints')
33+
34+
-- vim.lsp.callbacks['rust-analyzer/inlayHints'] = callback
35+
-- vim.lsp.callbacks['experimental/inlayHints'] = callback
36+
37+
inlay_hints.get_callback = function(opts)
38+
opts = opts or {}
39+
40+
local highlight = opts.highlight or "Comment"
41+
local prefix = opts.prefix or " || "
42+
local aligned = opts.aligned or false
43+
44+
local only_current_line = opts.only_current_line
45+
if only_current_line == nil then
46+
only_current_line = false
47+
end
48+
49+
return function(_, _, result, _, bufnr)
50+
if not result then
51+
print("[lsp_extensions.inlay_hints] No inlay hints found")
52+
return
53+
end
54+
55+
vim.api.nvim_buf_clear_namespace(bufnr, inlay_hints_ns, 0, -1)
56+
57+
local hint_store = {}
58+
59+
local longest_line = -1
60+
61+
for _, hint in ipairs(result) do
62+
local finish = hint.range["end"].line
63+
if not hint_store[finish] or hint.kind == "ChainingHint" then
64+
hint_store[finish] = hint
65+
66+
if aligned then
67+
longest_line = math.max(longest_line, #vim.api.nvim_buf_get_lines(bufnr, finish, finish + 1, false)[1])
68+
end
69+
end
70+
end
71+
72+
local display_virt_text = function(hint)
73+
local end_line = hint.range["end"].line
74+
75+
-- Check for any existing / more important virtual text on the line.
76+
-- TODO: Figure out how stackable virtual text works? What happens if there is more than one??
77+
local existing_virt_text = vim.api.nvim_buf_get_virtual_text(bufnr, end_line)
78+
if not vim.tbl_isempty(existing_virt_text) then
79+
return
80+
end
81+
82+
local text
83+
if aligned then
84+
local line_length = #vim.api.nvim_buf_get_lines(bufnr, end_line, end_line + 1, false)[1]
85+
text = string.format("%s | %s", (" "):rep(longest_line - line_length), hint.label)
86+
else
87+
text = prefix .. hint.label
88+
end
89+
vim.api.nvim_buf_set_virtual_text(bufnr, inlay_hints_ns, end_line, { { text, highlight } }, {})
90+
end
91+
92+
if only_current_line then
93+
local hint = hint_store[vim.api.nvim_win_get_cursor(0)[1] - 1]
94+
95+
if not hint then
96+
print("[lsp_extensions.inlay_hints] No inlay hints for this line")
97+
return
98+
else
99+
display_virt_text(hint)
100+
end
101+
else
102+
for _, hint in pairs(hint_store) do
103+
display_virt_text(hint)
104+
end
105+
end
106+
end
107+
end
108+
109+
inlay_hints.get_params = function()
110+
return {
111+
textDocument = vim.lsp.util.make_text_document_params()
112+
}
113+
end
114+
115+
inlay_hints.clear = function()
116+
vim.api.nvim_buf_clear_namespace(0, inlay_hints_ns, 0, -1)
117+
end
118+
119+
120+
return inlay_hints

plugin/lsp_extensions.vim

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
nnoremap ,asdf :lua require('plenary.reload').reload_module('lsp_extensions'); require('lsp_extensions').test()<CR>

0 commit comments

Comments
 (0)