Skip to content

Commit 1d950d8

Browse files
committed
feat: initial try at implementing rename
1 parent 8afd653 commit 1d950d8

File tree

1 file changed

+141
-3
lines changed

1 file changed

+141
-3
lines changed

lua/obsidian/lsp/handlers/rename.lua

Lines changed: 141 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,146 @@
11
-- TODO: move to the idea of textEdits
22

3-
---@param obsidian_client obsidian.Client
3+
local lsp = vim.lsp
4+
local ms = lsp.protocol.Methods
5+
6+
---@type lsp.WorkspaceEdit
7+
local edits = {
8+
documentChanges = {
9+
{
10+
kind = "rename",
11+
oldUri = vim.uri_from_bufnr(vim.api.nvim_get_current_buf()),
12+
newUri = vim.uri_from_fname "/home/n451/test3.lua",
13+
},
14+
},
15+
}
16+
17+
-- lsp.util.apply_workspace_edit(edits, "utf-8")
18+
19+
-- local function rename()
20+
-- lsp.buf_request(0, ms.workspace_didRenameFiles, params, function(...)
21+
-- vim.print(...)
22+
-- end)
23+
-- end
24+
25+
-- Search notes on disk for any references to `cur_note_id`.
26+
-- We look for the following forms of references:
27+
-- * '[[cur_note_id]]'
28+
-- * '[[cur_note_id|ALIAS]]'
29+
-- * '[[cur_note_id\|ALIAS]]' (a wiki link within a table)
30+
-- * '[ALIAS](cur_note_id)'
31+
-- And all of the above with relative paths (from the vault root) to the note instead of just the note ID,
32+
-- with and without the ".md" suffix.
33+
-- Another possible form is [[ALIAS]], but we don't change the note's aliases when renaming
34+
-- so those links will still be valid.
35+
---@param ref_link string
36+
---@return string[]
37+
local function get_ref_forms(ref_link)
38+
return {
39+
"[[" .. ref_link .. "]]",
40+
"[[" .. ref_link .. "|",
41+
"[[" .. ref_link .. "\\|",
42+
"[[" .. ref_link .. "#",
43+
"](" .. ref_link .. ")",
44+
"](" .. ref_link .. "#",
45+
}
46+
end
47+
48+
local function rename_file(old_uri, new_uri)
49+
---@type lsp.WorkspaceEdit
50+
local edit = {
51+
documentChanges = {
52+
{
53+
kind = "rename",
54+
oldUri = old_uri,
55+
newUri = new_uri,
56+
},
57+
},
58+
}
59+
60+
vim.lsp.util.apply_workspace_edit(edit, "utf-8")
61+
end
62+
63+
local Path = require "obsidian.path"
64+
local Note = require "obsidian.note"
65+
local search = require "obsidian.search"
66+
67+
---@param client obsidian.Client
68+
---@param params table
69+
local function rename_current_note(client, params)
70+
local new_note_id = params.newName
71+
local uri = params.textDocument.uri
72+
local current_file = vim.uri_to_fname(uri)
73+
local dirname = vim.fs.dirname(current_file)
74+
75+
local new_path = vim.fs.joinpath(dirname, new_note_id) .. ".md"
76+
local new_note_path = Path.new(new_path)
77+
78+
local cur_note_bufnr = vim.uri_to_bufnr(uri)
79+
local cur_note_path = Path.buffer(cur_note_bufnr)
80+
local cur_note = Note.from_file(cur_note_path)
81+
local cur_note_id = tostring(cur_note.id)
82+
83+
local cur_note_rel_path = tostring(client:vault_relative_path(cur_note_path, { strict = true }))
84+
local new_note_rel_path = tostring(client:vault_relative_path(new_note_path, { strict = true }))
85+
86+
local pats = {
87+
"[[%s]]", -- wiki
88+
"[[%s|", -- wiki with display
89+
"[[%s\\|", -- ?
90+
"[[%s#", -- wiki with heading
91+
"](%s)", -- markdown
92+
"](%s#", -- markdown with heading
93+
}
94+
95+
local replace_lookup = {}
96+
97+
for _, pat in ipairs(pats) do
98+
replace_lookup[pat:format(cur_note_id)] = pat:format(new_note_id)
99+
replace_lookup[pat:format(cur_note_rel_path)] = pat:format(new_note_rel_path)
100+
replace_lookup[pat:format(cur_note_rel_path:sub(1, -4))] = pat:format(new_note_rel_path:sub(1, -4))
101+
end
102+
103+
local reference_forms = vim.tbl_keys(replace_lookup)
104+
105+
-- search.search_async(
106+
-- client.dir,
107+
-- reference_forms,
108+
-- search.SearchOpts.from_tbl { fixed_strings = true, max_count_per_file = 1 },
109+
-- function(match)
110+
-- local file = match.path.text
111+
-- local line = match.line_number
112+
-- local start, _end = match.submatches[1].start, match.submatches[1]["end"]
113+
-- local matched = match.submatches[1].match.text
114+
--
115+
-- handler(nil, {
116+
-- changes = {
117+
-- [vim.uri_from_fname(file)] = {
118+
-- range = {
119+
-- start = { line = line, character = start },
120+
-- ["end"] = { line = line, character = _end },
121+
-- },
122+
-- newText = replace_lookup[matched],
123+
-- },
124+
-- },
125+
-- })
126+
-- end,
127+
-- function(_)
128+
-- -- all_tasks_submitted = true
129+
-- end
130+
-- )
131+
132+
rename_file(uri, vim.uri_from_fname(new_path))
133+
end
134+
135+
local function rename_note_at_cursor(params) end
136+
137+
---@param client obsidian.Client
4138
---@param params table
5139
---@param handler function
6-
return function(obsidian_client, params, handler, _)
7-
require "obsidian.commands.rename"(obsidian_client, { args = params.newName })
140+
return function(client, params, handler, _)
141+
local position = params.position
142+
143+
rename_current_note(client, params)
144+
145+
-- require "obsidian.commands.rename"(obsidian_client, { args = params.newName })
8146
end

0 commit comments

Comments
 (0)