@@ -75,4 +75,61 @@ OrgLspHandlers[methods.textDocument_completion] = function(params)
7575 }
7676end
7777
78+ OrgLspHandlers [methods .textDocument_references ] = function (params )
79+ local org = require (' orgmode' )
80+ local headline =
81+ org .files :get (vim .uri_to_fname (params .textDocument .uri )):get_closest_headline ({ params .position .line + 1 , 0 })
82+ local custom_id = headline :get_property (' CUSTOM_ID' , false )
83+ local title = headline :get_title ()
84+
85+ if not headline then
86+ return {}
87+ end
88+
89+ local function is_valid_target (target )
90+ if target == ' *' .. title or target == title then
91+ return true
92+ end
93+
94+ if custom_id and target == ' #' .. custom_id then
95+ return true
96+ end
97+
98+ return false
99+ end
100+
101+ --- @type lsp.Location[]
102+ local locations = {}
103+
104+ for _ , orgfile in ipairs (org .files :all ()) do
105+ for _ , link in ipairs (orgfile :get_links ()) do
106+ local file_path = link .url :get_file_path ()
107+ local target_or_path = link .url :get_target () or link .url :get_path ()
108+ local target = link .url :get_target ()
109+
110+ local location = {
111+ uri = vim .uri_from_fname (orgfile .filename ),
112+ range = link .range :to_lsp (),
113+ }
114+
115+ -- is a file headline link
116+ if file_path and vim .fs .normalize (file_path ) == vim .fs .normalize (headline .file .filename ) then
117+ if not target or is_valid_target (target ) then
118+ table.insert (locations , location )
119+ end
120+ goto continue
121+ end
122+
123+ -- is local link
124+ if orgfile .filename == headline .file .filename and is_valid_target (target_or_path ) then
125+ table.insert (locations , location )
126+ end
127+
128+ :: continue::
129+ end
130+ end
131+
132+ return locations
133+ end
134+
78135return OrgLspHandlers
0 commit comments