Skip to content

Commit e0944a5

Browse files
committed
feat: create note item
1 parent c1c4ebb commit e0944a5

File tree

6 files changed

+100
-35
lines changed

6 files changed

+100
-35
lines changed

lua/obsidian/client.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2150,6 +2150,7 @@ Client.lsp_start = function(self)
21502150
handlers[method](self, params, handler, _)
21512151
end,
21522152
notify = function(method, params, handler, _)
2153+
print(method)
21532154
handlers[method](self, params, handler, _)
21542155
end,
21552156
is_closing = function() end,

lua/obsidian/init.lua

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,23 @@ obsidian.setup = function(opts)
150150

151151
local client_id = client:lsp_start()
152152

153+
vim.keymap.set("n", "<leader>ii", function()
154+
local lsp_client = assert(vim.lsp.get_client_by_id(client_id))
155+
156+
vim.ui.input({}, function(input)
157+
if not input then
158+
return
159+
end
160+
lsp_client:exec_cmd({
161+
arguments = {
162+
input,
163+
},
164+
title = "create note",
165+
command = "createNote",
166+
}, { bufnr = ev.buf })
167+
end, { buffer = ev.buf })
168+
end)
169+
153170
-- place holders
154171
vim.keymap.set("n", "<leader>cH", function()
155172
local lsp_client = assert(vim.lsp.get_client_by_id(client_id))
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---@param client obsidian.Client
2+
return function(client, params)
3+
local name = params.arguments[1]
4+
print("creating note " .. name)
5+
return client:create_note { title = name }
6+
end

lua/obsidian/lsp/handlers/completion.lua

Lines changed: 73 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
-- TODO: completion for anchor, blocks
2-
-- TODO: create item
32
-- TODO: memoize?
43

54
local ref_trigger_pattern = {
@@ -11,6 +10,7 @@ local util = require "obsidian.util"
1110

1211
local find, sub, lower = string.find, string.sub, string.lower
1312

13+
-- TODO:
1414
local function insert_snippet_marker(text, style)
1515
if style == "markdown" then
1616
local pos = text:find "]"
@@ -19,33 +19,6 @@ local function insert_snippet_marker(text, style)
1919
end
2020
end
2121

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-
4922
local state = {
5023
---@type obsidian.Note
5124
current_note = nil,
@@ -76,6 +49,60 @@ local function collect_matching_anchors(note, anchor_link)
7649
return matching_anchors
7750
end
7851

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+
79106
---@client obsidian.Client
80107
local function handle_ref(client, partial, ref_start, cursor_col, line_num, handler)
81108
---@type string|?
@@ -85,23 +112,35 @@ local function handle_ref(client, partial, ref_start, cursor_col, line_num, hand
85112
---@type string|?
86113
local anchor_link
87114
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
89128

90-
local items = {}
91129
if not anchor_link then
92130
client:find_notes_async(
93131
partial,
94132
vim.schedule_wrap(function(notes)
95-
for _, note in ipairs(notes) do
133+
local items = {}
134+
for _, note in ipairs(notes or {}) do
96135
local title = note.title
97136
local pattern = vim.pesc(lower(partial))
98137
if title and find(lower(title), pattern) then
99138
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)
102140
end
103-
handler(nil, { items = items })
104141
end
142+
items[#items + 1] = gen_create_item(partial, range, format_func)
143+
handler(nil, { items = items })
105144
end)
106145
)
107146
else
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
---@param client obsidian.Client
22
---@param params table
33
return function(client, params)
4-
return require "obsidian.lsp.handlers.commands.toggleCheckbox"(client, params)
4+
-- return require "obsidian.lsp.handlers.commands.toggleCheckbox"(client, params)
5+
return require "obsidian.lsp.handlers.commands.createNote"(client, params)
56
end

lua/obsidian/lsp/handlers/initialize.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ local initializeResult = {
3939
executeCommandProvider = {
4040
commands = {
4141
"toggleCheckbox",
42+
"createNote",
4243
},
4344
},
4445
completionProvider = completion_options,

0 commit comments

Comments
 (0)