@@ -6,27 +6,6 @@ local util = obsidian.util
66local Search = obsidian .search
77local 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:
3110local 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
6241end
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 )
6972end
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 },
128130
129131local 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 })
165165end
166166
167167local function handle_anchor_links (partial , anchor_link , handler )
@@ -211,19 +211,9 @@ local function handle_anchor_links(partial, anchor_link, handler)
211211 end )
212212end
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 })
241231end
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
245244end
246245
246+ -- TODO: search.find_heading
247+ local function handle_heading (client ) end
248+
247249-- util.BLOCK_PATTERN = "%^[%w%d][%w%d-]*"
248250local anchor_trigger_pattern = {
249251 markdown = " %[%S+#(%w*)" ,
250252}
251253
252254local 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
281284end
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 ))
311305end
0 commit comments