1
1
-- TODO: completion for anchor, blocks
2
- -- TODO: create item
3
2
-- TODO: memoize?
4
3
5
4
local ref_trigger_pattern = {
@@ -11,6 +10,7 @@ local util = require "obsidian.util"
11
10
12
11
local find , sub , lower = string.find , string.sub , string.lower
13
12
13
+ -- TODO:
14
14
local function insert_snippet_marker (text , style )
15
15
if style == " markdown" then
16
16
local pos = text :find " ]"
@@ -19,33 +19,6 @@ local function insert_snippet_marker(text, style)
19
19
end
20
20
end
21
21
22
- --- @param note obsidian.Note
23
- --- @param insert_text string
24
- --- @param insert_start integer
25
- --- @param insert_end integer
26
- --- @param line_num integer
27
- --- @return lsp.CompletionItem
28
- local function calc_ref_item (note , insert_text , insert_start , insert_end , line_num , style )
29
- return {
30
- kind = 17 ,
31
- label = note .title ,
32
- filterText = note .title ,
33
- insertTextFormat = 2 , -- is snippet
34
- textEdit = {
35
- range = {
36
- start = { line = line_num , character = insert_start },
37
- [" end" ] = { line = line_num , character = insert_end },
38
- },
39
- newText = insert_snippet_marker (insert_text , style ),
40
- },
41
- labelDetails = { description = " Obsidian" },
42
- data = {
43
- file = note .path .filename ,
44
- kind = " ref" ,
45
- },
46
- }
47
- end
48
-
49
22
local state = {
50
23
--- @type obsidian.Note
51
24
current_note = nil ,
@@ -76,6 +49,60 @@ local function collect_matching_anchors(note, anchor_link)
76
49
return matching_anchors
77
50
end
78
51
52
+ -- A more generic pure function, don't require label to exist
53
+ local function format_link (label , format_func )
54
+ local path = util .urlencode (label ) .. " .md"
55
+ local opts = { label = label , path = path }
56
+ return format_func (opts )
57
+ end
58
+
59
+ --- @param label string
60
+ --- @param path string
61
+ --- @param new_text string
62
+ --- @param range lsp.Range
63
+ --- @return lsp.CompletionItem
64
+ local function gen_ref_item (label , path , new_text , range , style , is_snippet )
65
+ return {
66
+ kind = 17 ,
67
+ label = label ,
68
+ filterText = label ,
69
+ insertTextFormat = 2 , -- is snippet TODO: extract to config option
70
+ textEdit = {
71
+ range = range ,
72
+ newText = insert_snippet_marker (new_text , style ),
73
+ },
74
+ labelDetails = { description = " Obsidian" },
75
+ data = {
76
+ file = path ,
77
+ kind = " ref" ,
78
+ },
79
+ }
80
+ end
81
+
82
+ --- @param label string
83
+ --- @param range lsp.Range
84
+ --- @param format_func function
85
+ --- @return lsp.CompletionItem
86
+ local function gen_create_item (label , range , format_func )
87
+ return {
88
+ kind = 17 ,
89
+ label = label .. " (create)" ,
90
+ filterText = label ,
91
+ textEdit = {
92
+ range = range ,
93
+ newText = format_link (label , format_func ),
94
+ },
95
+ labelDetails = { description = " Obsidian" },
96
+ command = { -- runs after accept
97
+ command = " createNote" ,
98
+ arguments = { label },
99
+ },
100
+ data = {
101
+ kind = " ref_create" , -- TODO: resolve to a tooltip window
102
+ },
103
+ }
104
+ end
105
+
79
106
--- @client obsidian.Client
80
107
local function handle_ref (client , partial , ref_start , cursor_col , line_num , handler )
81
108
--- @type string |?
@@ -85,23 +112,35 @@ local function handle_ref(client, partial, ref_start, cursor_col, line_num, hand
85
112
--- @type string |?
86
113
local anchor_link
87
114
partial , anchor_link = util .strip_anchor_links (partial )
88
- print (partial )
115
+ local style = client .opts .preferred_link_style
116
+
117
+ local range = {
118
+ start = { line = line_num , character = ref_start },
119
+ [" end" ] = { line = line_num , character = cursor_col }, -- if auto parired
120
+ }
121
+
122
+ local format_func
123
+ if style == " markdown" then
124
+ format_func = client .opts .markdown_link_func
125
+ else
126
+ format_func = client .opts .wiki_link_func
127
+ end
89
128
90
- local items = {}
91
129
if not anchor_link then
92
130
client :find_notes_async (
93
131
partial ,
94
132
vim .schedule_wrap (function (notes )
95
- for _ , note in ipairs (notes ) do
133
+ local items = {}
134
+ for _ , note in ipairs (notes or {}) do
96
135
local title = note .title
97
136
local pattern = vim .pesc (lower (partial ))
98
137
if title and find (lower (title ), pattern ) then
99
138
local link_text = client :format_link (note )
100
- local style = client .opts .preferred_link_style
101
- items [# items + 1 ] = calc_ref_item (note , link_text , ref_start , cursor_col , line_num , style )
139
+ items [# items + 1 ] = gen_ref_item (note .title , note .path .filename , link_text , range , style )
102
140
end
103
- handler (nil , { items = items })
104
141
end
142
+ items [# items + 1 ] = gen_create_item (partial , range , format_func )
143
+ handler (nil , { items = items })
105
144
end )
106
145
)
107
146
else
0 commit comments