Skip to content

Commit 4a5624e

Browse files
committed
feat: add configs
1 parent 7e5ce7c commit 4a5624e

File tree

8 files changed

+373
-0
lines changed

8 files changed

+373
-0
lines changed

.stylua.toml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
indent_type = "Spaces"
2+
indent_width = 2
3+
column_width = 80
4+
call_parentheses = "NoSingleTable"

lua/dora/config/_types.lua

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---@class dora.config.Configuration<T>
2+
---@field public config T

lua/dora/config/init.lua

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---@class dora.config
2+
local M = {
3+
---@type dora.config.lsp
4+
lsp = require("dora.config.lsp"),
5+
}
6+
7+
---@class dora.config.SetupOptions
8+
---@field lsp? dora.config.lsp.SetupOptions
9+
10+
---@param opts dora.config.SetupOptions
11+
function M.setup(opts)
12+
M.lsp.setup(opts.lsp or {})
13+
end

lua/dora/config/lsp.lua

+283
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
---@class dora.config.lsp
2+
local M = {}
3+
4+
---@type dora.config.lsp.Config
5+
M.config = {}
6+
7+
---@class dora.config.lsp.SetupOptions
8+
---@field config? dora.config.lsp.Config
9+
---@field methods? dora.config.lsp.methods
10+
11+
---@param opts dora.config.lsp.SetupOptions
12+
function M.setup(opts)
13+
M.config = vim.tbl_deep_extend("force", M.config, opts.config) --[[@as dora.config.lsp.Config]]
14+
M.methods = vim.tbl_extend("force", M.methods, opts.methods) --[[@as dora.config.lsp.methods]]
15+
end
16+
17+
---@alias dora.config.lsp.config.Backend "native" | "telescope" | "glance" | "lspsaga"
18+
19+
---@class dora.config.lsp.config.BackendOptions
20+
---@field ["*"] dora.config.lsp.config.Backend|nil
21+
---@field definitions? dora.config.lsp.config.Backend
22+
---@field type_definitions? dora.config.lsp.config.Backend
23+
---@field implementations? dora.config.lsp.config.Backend
24+
---@field references? dora.config.lsp.config.Backend
25+
---@field code_action? dora.config.lsp.config.Backend
26+
27+
---@class dora.config.lsp.Config
28+
---@field backend dora.config.lsp.config.BackendOptions
29+
30+
---@type dora.config.lsp.Config
31+
local Config = {
32+
backend = {
33+
["*"] = "native",
34+
definitions = "glance",
35+
type_definitions = "glance",
36+
implementations = "glance",
37+
references = "glance",
38+
code_action = "lspsaga",
39+
},
40+
}
41+
M.config = Config
42+
43+
---@class dora.config.lsp.methods
44+
local Methods = {}
45+
M.methods = Methods
46+
47+
function Methods.declaration()
48+
if vim.g.vscode then
49+
require("vscode-neovim").call("editor.action.revealDeclaration")
50+
else
51+
vim.lsp.buf.declaration()
52+
end
53+
end
54+
55+
---@param method string
56+
---@return dora.config.lsp.config.Backend
57+
local function get_backend(method)
58+
---@type dora.lib
59+
local lib = require("dora.lib")
60+
return vim.F.if_nil(
61+
lib.tbl.optional_field(M.config, "backend", method),
62+
lib.tbl.optional_field(M.config, "backend", "*"),
63+
"native"
64+
)
65+
end
66+
67+
function Methods.definitions()
68+
local backend = get_backend("definitions")
69+
if vim.g.vscode then
70+
require("vscode-neovim").call("editor.action.revealDefinition")
71+
elseif backend == "native" then
72+
vim.lsp.buf.definition()
73+
elseif backend == "telescope" then
74+
require("telescope.builtin").lsp_definitions()
75+
elseif backend == "glance" then
76+
require("glance").open("definitions")
77+
else
78+
vim.notify(
79+
"Unknown backend for definitions: " .. backend,
80+
vim.log.levels.ERROR
81+
)
82+
end
83+
end
84+
85+
function Methods.type_definitions()
86+
local backend = get_backend("type_definitions")
87+
if vim.g.vscode then
88+
require("vscode-neovim").call("editor.action.goToTypeDefinition")
89+
elseif backend == "native" then
90+
vim.lsp.buf.type_definition()
91+
elseif backend == "telescope" then
92+
require("telescope.builtin").lsp_type_definitions()
93+
elseif backend == "glance" then
94+
require("glance").open("type_definitions")
95+
else
96+
vim.notify(
97+
"Unknown backend for type definitions: " .. backend,
98+
vim.log.levels.ERROR
99+
)
100+
end
101+
end
102+
103+
function Methods.implementations()
104+
local backend = get_backend("implementations")
105+
if vim.g.vscode then
106+
require("vscode-neovim").call("editor.action.goToImplementation")
107+
elseif backend == "native" then
108+
vim.lsp.buf.implementation()
109+
elseif backend == "telescope" then
110+
require("telescope.builtin").lsp_implementations()
111+
elseif backend == "glance" then
112+
require("glance").open("implementations")
113+
else
114+
vim.notify(
115+
"Unknown backend for implementations: " .. backend,
116+
vim.log.levels.ERROR
117+
)
118+
end
119+
end
120+
121+
function Methods.references()
122+
local backend = get_backend("references")
123+
if vim.g.vscode then
124+
require("vscode-neovim").call("references-view.findReferences")
125+
elseif backend == "native" then
126+
vim.lsp.buf.references()
127+
elseif backend == "telescope" then
128+
require("telescope.builtin").lsp_references()
129+
elseif backend == "glance" then
130+
require("glance").open("references")
131+
else
132+
vim.notify(
133+
"Unknown backend for references: " .. backend,
134+
vim.log.levels.ERROR
135+
)
136+
end
137+
end
138+
139+
function Methods.code_action()
140+
if vim.g.vscode then
141+
require("vscode-neovim").call("editor.action.quickFix")
142+
else
143+
vim.cmd("Lspsaga code_action")
144+
end
145+
end
146+
147+
function Methods.next_diagnostic()
148+
if vim.g.vscode then
149+
require("vscode-neovim").call("editor.action.marker.nextInFiles")
150+
else
151+
vim.lsp.diagnostic.goto_next()
152+
end
153+
end
154+
155+
function Methods.prev_diagnostic()
156+
if vim.g.vscode then
157+
require("vscode-neovim").call("editor.action.marker.prevInFiles")
158+
else
159+
vim.lsp.diagnostic.goto_prev()
160+
end
161+
end
162+
163+
local lsp_hover_group =
164+
vim.api.nvim_create_augroup("dora_lsp_hover", { clear = true })
165+
166+
function Methods.show_hover()
167+
if vim.g.vscode then
168+
require("vscode-neovim").call("editor.action.showHover")
169+
else
170+
vim.o.eventignore = "CursorHold"
171+
vim.api.nvim_exec_autocmds("User", {
172+
pattern = "DoraShowHover",
173+
})
174+
vim.lsp.buf.hover()
175+
vim.api.nvim_create_autocmd({ "CursorMoved" }, {
176+
group = lsp_hover_group,
177+
buffer = 0,
178+
command = 'set eventignore=""',
179+
once = true,
180+
})
181+
end
182+
end
183+
184+
local function close_preview_window(winnr, bufnrs)
185+
vim.schedule(function()
186+
-- exit if we are in one of ignored buffers
187+
if bufnrs and vim.list_contains(bufnrs, vim.api.nvim_get_current_buf()) then
188+
return
189+
end
190+
191+
local augroup = "preview_window_" .. winnr
192+
pcall(vim.api.nvim_del_augroup_by_name, augroup)
193+
pcall(vim.api.nvim_win_close, winnr, true)
194+
end)
195+
end
196+
197+
local function close_preview_autocmd(events, winnr, bufnrs)
198+
local augroup = vim.api.nvim_create_augroup("preview_window_" .. winnr, {
199+
clear = true,
200+
})
201+
202+
-- close the preview window when entered a buffer that is not
203+
-- the floating window buffer or the buffer that spawned it
204+
vim.api.nvim_create_autocmd("BufEnter", {
205+
group = augroup,
206+
callback = function()
207+
close_preview_window(winnr, bufnrs)
208+
end,
209+
})
210+
211+
if #events > 0 then
212+
local simple_events = {}
213+
local events_with_pattern = {}
214+
215+
for _, event in ipairs(events) do
216+
-- split event with space
217+
local parts = vim.split(event, " ", {
218+
trimempty = false,
219+
})
220+
if #parts == 1 then
221+
table.insert(simple_events, event)
222+
else
223+
local pattern = table.concat({ unpack(parts, 2) }, " ")
224+
table.insert(events_with_pattern, {
225+
event = parts[1],
226+
pattern = pattern,
227+
})
228+
end
229+
end
230+
231+
vim.api.nvim_create_autocmd(simple_events, {
232+
group = augroup,
233+
buffer = bufnrs[2],
234+
callback = function()
235+
close_preview_window(winnr)
236+
end,
237+
})
238+
for _, event in ipairs(events_with_pattern) do
239+
vim.api.nvim_create_autocmd(event.event, {
240+
group = augroup,
241+
buffer = bufnrs[2],
242+
callback = function(ev)
243+
if ev.match == event.pattern then
244+
close_preview_window(winnr)
245+
end
246+
end,
247+
})
248+
end
249+
end
250+
end
251+
252+
function Methods.open_diagnostic()
253+
local opts = {
254+
focusable = false,
255+
border = "solid",
256+
source = "if_many",
257+
prefix = " ",
258+
focus = false,
259+
scope = "cursor",
260+
}
261+
262+
local bufnr, win = vim.diagnostic.open_float(opts)
263+
264+
if bufnr == nil then
265+
return
266+
end
267+
268+
vim.api.nvim_set_option_value(
269+
"winhl",
270+
"FloatBorder:NormalFloat,Normal:NormalFloat",
271+
{ win = win }
272+
)
273+
274+
close_preview_autocmd({
275+
"CursorMoved",
276+
"InsertEnter",
277+
"User DoraShowHover",
278+
"BufLeave",
279+
"FocusLost",
280+
}, win, { bufnr, vim.api.nvim_get_current_buf() })
281+
end
282+
283+
return M

lua/dora/config/ui.lua

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---@class dora.config.ui
2+
local M = {}
3+
4+
---@alias dora.config.ui.DashboardHeader string[]
5+
6+
7+
8+
return M

lua/dora/lib/func.lua

+31
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,35 @@ function M.call_once(fun)
8888
end
8989
end
9090

91+
---@generic T
92+
---@param name string
93+
---@param callback fun(module): T
94+
---@return T?
95+
function M.require_then(name, callback)
96+
local has_module, module = pcall(require, name)
97+
if has_module then
98+
return callback(module)
99+
end
100+
end
101+
102+
---@param callback string|fun(): any
103+
---@param feedkeys? boolean
104+
---@return fun(): any
105+
function M.normalize_callback(callback, feedkeys)
106+
if type(callback) == "string" then
107+
if feedkeys == true then
108+
return function()
109+
local key = vim.api.nvim_replace_termcodes(callback .. "<Ignore>", true, false, true)
110+
vim.api.nvim_feedkeys(key, "t", false)
111+
end
112+
else
113+
return function()
114+
vim.api.nvim_command(callback)
115+
end
116+
end
117+
else
118+
return callback
119+
end
120+
end
121+
91122
return M

lua/dora/lib/init.lua

+3
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,7 @@ M.func = require("dora.lib.func")
1313
---@type dora.lib.vim
1414
M.vim = require("dora.lib.vim")
1515

16+
---@type dora.lib.tbl
17+
M.tbl = require("dora.lib.tbl")
18+
1619
return M

lua/dora/lib/tbl.lua

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---@class dora.lib.tbl
2+
local M = {}
3+
4+
---@param t table
5+
---@param ... string
6+
function M.optional_field(t, ...)
7+
local keys = { ... }
8+
local now = t
9+
for _, key in ipairs(keys) do
10+
if now[key] == nil then
11+
return nil
12+
end
13+
now = now[key]
14+
end
15+
return now
16+
end
17+
18+
---Reverse given list-like table in place.
19+
---NOTE: this mutates the given table.
20+
---@generic T
21+
---@param lst T[]
22+
function M.list_reverse(lst)
23+
for i = 1, math.floor(#lst / 2) do
24+
local j = #lst - i + 1
25+
lst[i], lst[j] = lst[j], lst[i]
26+
end
27+
end
28+
29+
return M

0 commit comments

Comments
 (0)