Skip to content

Commit 733209e

Browse files
author
neo451
committed
refactor: cleanup, handlers
1 parent 7e8240f commit 733209e

File tree

1 file changed

+74
-80
lines changed

1 file changed

+74
-80
lines changed

lua/obsidian/lsp/handlers/completion.lua

Lines changed: 74 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,6 @@ local util = obsidian.util
66
local Search = obsidian.search
77
local find, sub, lower = string.find, string.sub, string.lower
88

9-
-- TODO:
10-
local CmpType = {
11-
ref = 1,
12-
tag = 2,
13-
anchor = 3,
14-
}
15-
16-
---@return function
17-
local function get_format_func()
18-
local format_func
19-
local style = Obsidian.opts.preferred_link_style
20-
if style == "markdown" then
21-
format_func = Obsidian.opts.markdown_link_func
22-
elseif style == "wiki" then
23-
format_func = Obsidian.opts.wiki_link_func
24-
else
25-
error "unimplemented"
26-
end
27-
return format_func
28-
end
29-
309
-- TODO:
3110
local function insert_snippet_marker(text, style)
3211
if style == "markdown" then
@@ -61,10 +40,34 @@ local function collect_matching_anchors(note, anchor_link)
6140
return matching_anchors
6241
end
6342

43+
---@return function
44+
local function get_format_func()
45+
local format_func
46+
local style = Obsidian.opts.preferred_link_style
47+
if style == "markdown" then
48+
format_func = Obsidian.opts.markdown_link_func
49+
elseif style == "wiki" then
50+
format_func = Obsidian.opts.wiki_link_func
51+
else
52+
error "unimplemented"
53+
end
54+
return format_func
55+
end
56+
6457
-- A more generic pure function, don't require label to exist
65-
local function format_link(label, format_func)
58+
local function format_link(label)
6659
local path = util.urlencode(label) .. ".md"
6760
local opts = { label = label, path = path }
61+
62+
local format_func
63+
local style = Obsidian.opts.preferred_link_style
64+
if style == "markdown" then
65+
format_func = Obsidian.opts.markdown_link_func
66+
elseif style == "wiki" then
67+
format_func = Obsidian.opts.wiki_link_func
68+
else
69+
error "unimplemented link style"
70+
end
6871
return format_func(opts)
6972
end
7073

@@ -104,19 +107,18 @@ end
104107

105108
---@param label string
106109
---@param range lsp.Range
107-
---@param format_func function
108110
---@return lsp.CompletionItem
109-
local function gen_create_item(label, range, format_func)
111+
local function gen_create_item(label, range)
110112
return {
111113
kind = 17,
112114
label = label .. " (create)",
113115
filterText = label,
114116
textEdit = {
115117
range = range,
116-
newText = format_link(label, format_func),
118+
newText = format_link(label),
117119
},
118120
labelDetails = { description = "Obsidian" },
119-
command = { -- runs after accept
121+
command = {
120122
command = "create_note",
121123
arguments = { label },
122124
},
@@ -128,7 +130,7 @@ end
128130

129131
local handle_bare_links = function(partial, range, handler)
130132
local items = {}
131-
items[#items + 1] = gen_create_item(partial, range, get_format_func())
133+
items[#items + 1] = gen_create_item(partial, range)
132134

133135
local pattern = vim.pesc(lower(partial))
134136
local notes = Search.find_notes(pattern)
@@ -159,9 +161,7 @@ local handle_bare_links = function(partial, range, handler)
159161
end
160162
end
161163

162-
handler(nil, {
163-
items = items,
164-
})
164+
handler(nil, { items = items })
165165
end
166166

167167
local function handle_anchor_links(partial, anchor_link, handler)
@@ -211,19 +211,9 @@ local function handle_anchor_links(partial, anchor_link, handler)
211211
end)
212212
end
213213

214-
local function handle_ref(partial, range, handler)
215-
---@type string|?
216-
local anchor_link
217-
partial, anchor_link = util.strip_anchor_links(partial)
218-
219-
if not anchor_link then
220-
handle_bare_links(partial, range, handler)
221-
else
222-
handle_anchor_links(partial, anchor_link, handler)
223-
end
224-
end
214+
local handlers = {}
225215

226-
local function handle_tag(partial, handler)
216+
handlers.tag = function(partial, handler)
227217
local items = {}
228218
local tags = vim
229219
.iter(Search.find_tags("", {}))
@@ -240,49 +230,62 @@ local function handle_tag(partial, handler)
240230
handler(nil, { items = items })
241231
end
242232

243-
local function handle_heading(client)
244-
-- TODO: search.find_heading
233+
-- local function handle_ref(partial, range, handler)
234+
handlers.ref = function(partial, range, handler)
235+
---@type string|?
236+
local anchor_link
237+
partial, anchor_link = util.strip_anchor_links(partial)
238+
239+
if not anchor_link then
240+
handle_bare_links(partial, range, handler)
241+
else
242+
handle_anchor_links(partial, anchor_link, handler)
243+
end
245244
end
246245

246+
-- TODO: search.find_heading
247+
local function handle_heading(client) end
248+
247249
-- util.BLOCK_PATTERN = "%^[%w%d][%w%d-]*"
248250
local anchor_trigger_pattern = {
249251
markdown = "%[%S+#(%w*)",
250252
}
251253

252254
local heading_trigger_pattern = "[##"
253255

256+
-- TODO:
257+
local CmpType = {
258+
ref = 1,
259+
tag = 2,
260+
anchor = 3,
261+
}
262+
263+
local RefPatterns = {
264+
[CmpType.ref] = "[[",
265+
[CmpType.tag] = "#",
266+
-- heading = "[[## "
267+
}
268+
254269
---@param text string
255-
---@param style obsidian.config.LinkStyle
256270
---@param min_char integer
257-
---@return integer?
258-
---@return string?
259-
---@return integer?
260-
local function get_type(text, min_char)
261-
local ref_start = find(text, "[[", 1, true)
262-
local tag_start = find(text, "#", 1, true)
263-
-- local heading_start = find(text, heading_trigger_pattern, 1, true)
264-
265-
if ref_start then
266-
local partial = sub(text, ref_start + 2)
267-
if #partial >= min_char then
268-
return CmpType.ref, partial, ref_start
269-
end
270-
elseif tag_start then
271-
local partial = sub(text, tag_start + 1)
272-
if #partial >= min_char then
273-
return CmpType.tag, partial, tag_start
271+
---@return integer? cmp_type
272+
---@return string? prefix
273+
---@return integer? boundary 0-indexed
274+
local function get_cmp_type(text, min_char)
275+
for t, pattern in pairs(RefPatterns) do
276+
local st, ed = find(text, pattern, 1, true)
277+
if st and ed then
278+
local prefix = sub(text, ed + 1)
279+
if #prefix >= min_char then -- TODO: unicode
280+
return t, prefix, st - 1
281+
end
274282
end
275-
-- elseif heading_start then
276-
-- local partial = sub(text, heading_start + #heading_trigger_pattern)
277-
-- if #partial >= min_char then
278-
-- return CmpType.anchor, partial, heading_start
279-
-- end
280283
end
281284
end
282285

283286
---@param params lsp.CompletionParams
284-
---@param handler function
285-
return function(params, handler, _)
287+
---@param callback function
288+
return function(params, callback, _)
286289
local min_chars = Obsidian.opts.completion.min_chars
287290
---@cast min_chars -nil
288291

@@ -291,21 +294,12 @@ return function(params, handler, _)
291294

292295
local line_text = vim.api.nvim_buf_get_lines(0, line_num, line_num + 1, false)[1]
293296
local text_before = sub(line_text, 1, cursor_col)
294-
local t, partial, start = get_type(text_before, min_chars)
295-
296-
local ref_start = start and start - 1
297+
local t, prefix, ref_start = get_cmp_type(text_before, min_chars)
297298

298299
local range = {
299300
start = { line = line_num, character = ref_start },
300301
["end"] = { line = line_num, character = cursor_col }, -- if auto parired
301302
}
302303

303-
handler = vim.schedule_wrap(handler)
304-
305-
if t == CmpType.ref then
306-
handle_ref(partial, range, handler)
307-
elseif t == CmpType.tag then
308-
handle_tag(partial, handler)
309-
elseif t == CmpType.anchor then
310-
end
304+
handlers[t](prefix, range, vim.schedule_wrap(callback))
311305
end

0 commit comments

Comments
 (0)