Skip to content

Commit 37e4614

Browse files
author
neo451
committed
feat: anchor kinda working
1 parent 733209e commit 37e4614

File tree

1 file changed

+68
-66
lines changed

1 file changed

+68
-66
lines changed

lua/obsidian/lsp/handlers/completion.lua

Lines changed: 68 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,29 @@
44
local obsidian = require "obsidian"
55
local util = obsidian.util
66
local Search = obsidian.search
7+
local Note = obsidian.Note
78
local find, sub, lower = string.find, string.sub, string.lower
89

10+
-- util.BLOCK_PATTERN = "%^[%w%d][%w%d-]*"
11+
local anchor_trigger_pattern = {
12+
markdown = "%[%S+#(%w*)",
13+
}
14+
15+
local heading_trigger_pattern = "[##"
16+
17+
-- TODO:
18+
local CmpType = {
19+
ref = 1,
20+
tag = 2,
21+
anchor = 3,
22+
}
23+
24+
local RefPatterns = {
25+
[CmpType.ref] = "[[",
26+
[CmpType.tag] = "#",
27+
-- heading = "[[## "
28+
}
29+
930
-- TODO:
1031
local function insert_snippet_marker(text, style)
1132
if style == "markdown" then
@@ -165,55 +186,56 @@ local handle_bare_links = function(partial, range, handler)
165186
end
166187

167188
local function handle_anchor_links(partial, anchor_link, handler)
168-
local Note = require "obsidian.note"
169189
-- state.current_note = state.current_note or client:find_notes(partial)[2]
170190
-- TODO: calc current_note once
171191
-- TODO: handle two cases:
172192
-- 1. typing partial note name, no completeed text after cursor, insert the full link
173193
-- 2. jumped to heading, only insert anchor
174194
-- TODO: need to do more textEdit to insert additional #title to path so that app supports?
175195
local items = {}
176-
Search.find_notes(partial, function(notes)
177-
for _, note in ipairs(notes) do
178-
local title = note.title
179-
local pattern = vim.pesc(lower(partial))
180-
if title and find(lower(title), pattern) then
181-
local note2 = Note.from_file(note.path.filename, { collect_anchor_links = true })
182-
183-
local note_anchors = collect_matching_anchors(note2, anchor_link)
184-
if not note_anchors then
185-
return
186-
end
187-
for _, anchor in ipairs(note_anchors) do
188-
items[#items + 1] = {
189-
kind = 17,
190-
label = anchor.header,
191-
filterText = anchor.header,
192-
insertText = anchor.header,
193-
-- insertTextFormat = 2, -- is snippet
194-
-- textEdit = {
195-
-- range = {
196-
-- start = { line = line_num, character = insert_start },
197-
-- ["end"] = { line = line_num, character = insert_end },
198-
-- },
199-
-- newText = insert_snippet_marker(insert_text, style),
200-
-- },
201-
labelDetails = { description = "ObsidianAnchor" },
202-
data = {
203-
file = note.path.filename,
204-
kind = "anchor",
205-
},
206-
}
207-
end
196+
local notes = Search.resolve_note(partial)
197+
198+
for _, note in ipairs(notes) do
199+
local id = note.id
200+
local pattern = vim.pesc(lower(partial))
201+
if id and find(lower(id), pattern) then
202+
note = Note.from_file(note.path.filename, { collect_anchor_links = true })
203+
204+
local note_anchors = collect_matching_anchors(note, anchor_link)
205+
if not note_anchors then
206+
return
207+
end
208+
for _, anchor in ipairs(note_anchors) do
209+
items[#items + 1] = {
210+
kind = 17,
211+
label = anchor.header,
212+
filterText = anchor.header,
213+
insertText = anchor.header,
214+
-- textEdit = {
215+
-- range = {
216+
-- start = { line = line_num, character = insert_start },
217+
-- ["end"] = { line = line_num, character = insert_end },
218+
-- },
219+
-- newText = insert_snippet_marker(insert_text, style),
220+
-- },
221+
labelDetails = { description = "ObsidianAnchor" }, -- TODO: attach H1, H2
222+
data = {
223+
file = note.path.filename,
224+
kind = "anchor",
225+
},
226+
}
208227
end
209-
handler(nil, { items = items })
210228
end
211-
end)
229+
handler(nil, { items = items })
230+
end
212231
end
213232

233+
local function handle_block_links() end
234+
214235
local handlers = {}
215236

216-
handlers.tag = function(partial, handler)
237+
handlers[CmpType.tag] = function(partial, range, handler)
238+
vim.print(handler)
217239
local items = {}
218240
local tags = vim
219241
.iter(Search.find_tags("", {}))
@@ -230,49 +252,29 @@ handlers.tag = function(partial, handler)
230252
handler(nil, { items = items })
231253
end
232254

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)
255+
handlers[CmpType.ref] = function(prefix, range, handler)
256+
local anchor_link, block_link
257+
prefix, anchor_link = util.strip_anchor_links(prefix)
258+
prefix, block_link = util.strip_block_links(prefix)
259+
if anchor_link then
260+
handle_anchor_links(prefix, anchor_link, handler)
261+
elseif block_link then
262+
handle_block_links(prefix, block_link, handler)
241263
else
242-
handle_anchor_links(partial, anchor_link, handler)
264+
handle_bare_links(prefix, range, handler)
243265
end
244266
end
245267

246268
-- TODO: search.find_heading
247269
local function handle_heading(client) end
248270

249-
-- util.BLOCK_PATTERN = "%^[%w%d][%w%d-]*"
250-
local anchor_trigger_pattern = {
251-
markdown = "%[%S+#(%w*)",
252-
}
253-
254-
local heading_trigger_pattern = "[##"
255-
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-
269271
---@param text string
270272
---@param min_char integer
271273
---@return integer? cmp_type
272274
---@return string? prefix
273275
---@return integer? boundary 0-indexed
274276
local function get_cmp_type(text, min_char)
275-
for t, pattern in pairs(RefPatterns) do
277+
for t, pattern in vim.spairs(RefPatterns) do -- spairs make sure ref is first
276278
local st, ed = find(text, pattern, 1, true)
277279
if st and ed then
278280
local prefix = sub(text, ed + 1)

0 commit comments

Comments
 (0)