@@ -9,6 +9,7 @@ local AgendaSearchView = require('orgmode.agenda.views.search')
9
9
local AgendaTodosView = require (' orgmode.agenda.views.todos' )
10
10
local AgendaTagsView = require (' orgmode.agenda.views.tags' )
11
11
local AgendaView = require (' orgmode.agenda.views.agenda' )
12
+ local Hyperlinks = require (' orgmode.org.hyperlinks' )
12
13
13
14
--- @class Agenda
14
15
--- @field content table[]
@@ -245,6 +246,71 @@ function Agenda:change_todo_state()
245
246
})
246
247
end
247
248
249
+ function Agenda :open_link ()
250
+ local link = Hyperlinks .get_link_under_cursor ()
251
+ if not link then
252
+ return
253
+ end
254
+ local parts = vim .split (link , ' ][' , true )
255
+ local url = parts [1 ]
256
+ local link_ctx = { base = url , skip_add_prefix = true }
257
+ -- file links
258
+ if url :find (' ^file:' ) then
259
+ if url :find (' +' , 1 , true ) then
260
+ parts = vim .split (url , ' +' , true )
261
+ url = parts [1 ]
262
+ local line_number = parts [2 ]
263
+ vim .cmd (string.format (' edit +%s %s' , line_number , url :sub (6 )))
264
+ vim .cmd ([[ normal! zv]] )
265
+ return
266
+ end
267
+
268
+ if url :find (' ^file:(.-)::' ) then
269
+ link_ctx .line = url
270
+ else
271
+ vim .cmd (string.format (' edit %s' , url :sub (6 )))
272
+ vim .cmd ([[ normal! zv]] )
273
+ return
274
+ end
275
+ end
276
+ -- web links
277
+ if url :find (' ^https?://' ) then
278
+ if not vim .g .loaded_netrwPlugin then
279
+ return utils .echo_warning (' Netrw plugin must be loaded in order to open urls.' )
280
+ end
281
+ return vim .fn [' netrw#BrowseX' ](url , vim .fn [' netrw#CheckIfRemote' ]())
282
+ end
283
+ -- fallback: filepath
284
+ local stat = vim .loop .fs_stat (url )
285
+ if stat and stat .type == ' file' then
286
+ return vim .cmd (string.format (' edit %s' , url ))
287
+ end
288
+ -- headline link
289
+ local headlines = Hyperlinks .find_matching_links (link_ctx )
290
+ if # headlines == 0 then
291
+ utils .echo_warning (' foobar' )
292
+ return
293
+ end
294
+ local headline = headlines [1 ]
295
+ if # headlines > 1 then
296
+ local longest_headline = utils .reduce (headlines , function (acc , h )
297
+ return math.max (acc , h .line :len ())
298
+ end , 0 )
299
+ local options = {}
300
+ for i , h in ipairs (headlines ) do
301
+ table.insert (options , string.format (' %d) %-' .. longest_headline .. ' s (%s)' , i , h .line , h .file ))
302
+ end
303
+ vim .cmd ([[ echo "Multiple targets found. Select target:"]] )
304
+ local choice = vim .fn .inputlist (options )
305
+ if choice < 1 or choice > # headlines then
306
+ return
307
+ end
308
+ headline = headlines [choice ]
309
+ end
310
+ vim .cmd (string.format (' edit %s' , headline .file ))
311
+ vim .fn .cursor (headline .range .start_line , 0 )
312
+ end
313
+
248
314
function Agenda :clock_in ()
249
315
return self :_remote_edit ({
250
316
action = ' clock.org_clock_in' ,
0 commit comments