@@ -62,12 +62,53 @@ local function range_contains(r_out, r_in)
62
62
and xy_le (r_in .row_end , r_in .column_end , r_out .row_end , r_out .column_end )
63
63
end
64
64
65
+ --- @alias LinkType
66
+ --- | " url"
67
+ --- | " generic"
68
+ --- | " external_file"
69
+ --- | " definition"
70
+ --- | " timestamp"
71
+ --- | " footnote"
72
+ --- | " heading1"
73
+ --- | " heading2"
74
+ --- | " heading3"
75
+ --- | " heading4"
76
+ --- | " heading5"
77
+ --- | " heading6"
78
+ --- | " line_number"
79
+ --- | " wiki"
80
+
81
+ --- @class (exact ) Link
82
+ --- @field link_node TSNode The treesitter node of the link.
83
+ --- @field link_file_text string ? A provided path , if any.
84
+ --- @field link_type LinkType ? The type of link that was provided.
85
+ --- @field link_location_text string ? The target title /URL of the link.
86
+ --- @field link_description string ? The description of the link , if provided.
87
+
88
+ --- @alias LinkTargetType
89
+ --- |"buffer"
90
+ --- |"external_app"
91
+ --- |"external_file"
92
+ --- |"wiki"
93
+ --- |"calendar"
94
+
95
+ --- @class LinkTarget
96
+ --- @field original_title string The title of the link that points to this target.
97
+ --- @field node TSNode The node of the target.
98
+ --- @field type LinkTargetType The type of target that was located.
99
+ --- @field buffer number The buffer ID in which the target was found.
100
+
101
+ --- @class (exact ) PotentialLinkFixes
102
+ --- @field similarity number The similarity of this candidate to the current title of the link.
103
+ --- @field text string The title of the candidate link title (will replace the existing link target ).
104
+ --- @field node TSNode The node the fixed link points to.
105
+
65
106
--- @class core.esupports.hop
66
107
module .public = {
67
108
--- Follow link from a specific node
68
- --- @param node table
69
- --- @param open_mode string | nil if not nil, will open a new split with the split mode defined (vsplitr... ) or new tab (mode =" tab" ) or with external app (mode =" external" )
70
- --- @param parsed_link table a table of link information gathered from parse_link ()
109
+ --- @param node TSNode
110
+ --- @param open_mode string ? if not nil , will open a new split with the split mode defined (vsplitr... ) or new tab (mode =" tab" ) or with external app (mode =" external" )
111
+ --- @param parsed_link Link A table of link information gathered from parse_link ()
71
112
follow_link = function (node , open_mode , parsed_link )
72
113
if node :type () == " anchor_declaration" then
73
114
local located_anchor_declaration = module .public .locate_anchor_declaration_target (node )
@@ -85,7 +126,7 @@ module.public = {
85
126
end
86
127
87
128
if not parsed_link then
88
- log .warn (" Please parse your link before calling this function" )
129
+ log .warn (" Please parse your link before calling this function. " )
89
130
return
90
131
end
91
132
@@ -281,7 +322,7 @@ module.public = {
281
322
end ,
282
323
283
324
--- Locate a `link` or `anchor` node under the cursor
284
- --- @return userdata | nil #A `link` or `anchor` node if present under the cursor, else `nil`
325
+ --- @return TSNode ? #A `link` or `anchor` node if present under the cursor, else `nil`
285
326
extract_link_node = function ()
286
327
local ts_utils = module .required [" core.integrations.treesitter" ].get_ts_utils ()
287
328
@@ -303,7 +344,7 @@ module.public = {
303
344
end ,
304
345
305
346
--- Attempts to locate a `link` or `anchor` node after the cursor on the same line
306
- --- @return userdata | nil #A `link` or `anchor` node if present on the current line, else `nil`
347
+ --- @return TSNode ? #A `link` or `anchor` node if present on the current line, else `nil`
307
348
lookahead_link_node = function ()
308
349
local ts_utils = module .required [" core.integrations.treesitter" ].get_ts_utils ()
309
350
@@ -346,7 +387,8 @@ module.public = {
346
387
end ,
347
388
348
389
--- Locates the node that an anchor is pointing to
349
- --- @param anchor_decl_node table #A valid anchod declaration node
390
+ --- @param anchor_decl_node TSNode #A valid anchor declaration node
391
+ --- @return LinkTarget ? #The target of the link if it was found.
350
392
locate_anchor_declaration_target = function (anchor_decl_node )
351
393
if not anchor_decl_node :named_child (0 ) then
352
394
return
@@ -355,7 +397,7 @@ module.public = {
355
397
local target = module
356
398
.required
357
399
[" core.integrations.treesitter" ]
358
- .get_node_text (anchor_decl_node :named_child (0 ):named_child (0 )) --- @diagnostic disable-line -- TODO : type error workaround < pysan3 >
400
+ .get_node_text (anchor_decl_node :named_child (0 ):named_child (0 ))
359
401
:gsub (" [%s\\ ]" , " " )
360
402
361
403
local query_str = [[
@@ -392,12 +434,13 @@ module.public = {
392
434
end ,
393
435
394
436
--- Converts a link node into a table of data related to the link
395
- --- @param link_node userdata #The link node that was found by e.g. `extract_link_node()`
437
+ --- @param link_node TSNode #The link node that was found by e.g. `extract_link_node()`
396
438
--- @param buf number #The buffer to parse the link in
397
- --- @return table ? #A table of data about the link
439
+ --- @return Link ? #A table of data about the link
398
440
parse_link = function (link_node , buf )
399
441
buf = buf or 0
400
- if not link_node or not vim .tbl_contains ({ " link" , " anchor_definition" }, link_node :type ()) then --- @diagnostic disable-line -- TODO : type error workaround <pysan3 >
442
+
443
+ if not link_node or not vim .tbl_contains ({ " link" , " anchor_definition" }, link_node :type ()) then
401
444
return
402
445
end
403
446
@@ -459,15 +502,18 @@ module.public = {
459
502
]
460
503
]]
461
504
505
+ --- @type TSNode ?
462
506
local document_root = module .required [" core.integrations.treesitter" ].get_document_root (buf )
463
507
464
508
if not document_root then
465
509
return
466
510
end
467
511
512
+ --- @type vim.treesitter.Query
468
513
local query = utils .ts_parse_query (" norg" , query_text )
469
514
local range = module .required [" core.integrations.treesitter" ].get_node_range (link_node )
470
515
516
+ --- @type Link
471
517
local parsed_link_information = {
472
518
link_node = link_node ,
473
519
}
@@ -500,8 +546,8 @@ module.public = {
500
546
end ,
501
547
502
548
--- Locate the target that a link points to
503
- --- @param parsed_link_information table #A table returned by `parse_link()`
504
- --- @return table #A table containing data about the link target
549
+ --- @param parsed_link_information Link #A table returned by `parse_link()`
550
+ --- @return LinkTarget #A table containing data about the link target
505
551
locate_link_target = function (parsed_link_information )
506
552
--- A pointer to the target buffer we will be parsing.
507
553
-- This may change depending on the target file the user gave.
@@ -537,7 +583,9 @@ module.public = {
537
583
end ,
538
584
539
585
external_file = function ()
540
- local destination = parsed_link_information .link_location_text
586
+ -- There has to be a link location present for a link to be recognized as an external file,
587
+ -- therefore we can safely assert here.
588
+ local destination = assert (parsed_link_information .link_location_text )
541
589
local path , line = string.match (destination , " ^(.*):(%d+)$" )
542
590
if line then
543
591
destination = path
@@ -550,11 +598,11 @@ module.public = {
550
598
return lib .match (vim .fn .fnamemodify (destination , " :e" ))({
551
599
[{ " jpg" , " jpeg" , " png" , " pdf" }] = {
552
600
type = " external_app" ,
553
- uri = vim .uri_from_fname (vim .fn .expand (destination )), --- @diagnostic disable-line -- TODO : type error workaround < pysan3 >
601
+ uri = vim .uri_from_fname (vim .fn .expand (destination )),
554
602
},
555
603
[module .config .public .external_filetypes ] = {
556
604
type = " external_app" ,
557
- uri = vim .uri_from_fname (vim .fn .expand (destination )), --- @diagnostic disable-line -- TODO : type error workaround < pysan3 >
605
+ uri = vim .uri_from_fname (vim .fn .expand (destination )),
558
606
},
559
607
_ = function ()
560
608
return {
@@ -629,7 +677,7 @@ module.public = {
629
677
end
630
678
end
631
679
end ,
632
- })
680
+ } --[[ @as table<string, fun(): LinkTarget?> ]] )
633
681
end ,
634
682
}
635
683
@@ -692,8 +740,8 @@ module.private = {
692
740
end ,
693
741
694
742
--- Fuzzy fixes a link with a loose type checking query
695
- --- @param parsed_link_information table #A table as returned by `parse_link()`
696
- --- @return table #A table of similarities (fuzzed items)
743
+ --- @param parsed_link_information Link #A table as returned by `parse_link()`
744
+ --- @return PotentialLinkFixes[] ? #A table of similarities (fuzzed items)
697
745
fix_link_loose = function (parsed_link_information )
698
746
local generic_query = [[
699
747
[(_
@@ -716,8 +764,8 @@ module.private = {
716
764
end ,
717
765
718
766
--- Fuzzy fixes a link with a strict type checking query
719
- --- @param parsed_link_information table #A table as returned by `parse_link()`
720
- --- @return table #A table of similarities (fuzzed items)
767
+ --- @param parsed_link_information Link #A table as returned by `parse_link()`
768
+ --- @return PotentialLinkFixes[] ? #A table of similarities (fuzzed items)
721
769
fix_link_strict = function (parsed_link_information )
722
770
local query = lib .match (parsed_link_information .link_type )({
723
771
generic = [[
@@ -790,7 +838,7 @@ module.private = {
790
838
--- Query all similar targets that a link could be pointing to
791
839
--- @param parsed_link_information table #A table as returned by `parse_link()`
792
840
--- @param query_str string #The query to be used during the search
793
- --- @return table #A table of similarities (fuzzed items)
841
+ --- @return PotentialLinkFixes[] ? #A table of similarities (fuzzed items)
794
842
fix_link = function (parsed_link_information , query_str )
795
843
local buffer = vim .api .nvim_get_current_buf ()
796
844
@@ -808,12 +856,11 @@ module.private = {
808
856
local document_root = module .required [" core.integrations.treesitter" ].get_document_root (buffer )
809
857
810
858
if not document_root then
811
- return --- @diagnostic disable-line -- TODO : type error workaround < pysan3 >
859
+ return
812
860
end
813
861
814
- local similarities = {
815
- -- Example: { 0.6, "title", node }
816
- }
862
+ --- @type PotentialLinkFixes[]
863
+ local similarities = {}
817
864
818
865
for id , node in query :iter_captures (document_root , buffer ) do
819
866
local capture_name = query .captures [id ]
@@ -841,9 +888,9 @@ module.private = {
841
888
end ,
842
889
843
890
--- Writes a link that was fixed through fuzzing into the buffer
844
- --- @param link_node userdata #The treesitter node of the link, extracted by e.g. `extract_link_node()`
845
- --- @param parsed_link_information table #A table as returned by `parse_link()`
846
- --- @param similarities table #The table of similarities as returned by `fix_link_*()`
891
+ --- @param link_node TSNode #The treesitter node of the link, extracted by e.g. `extract_link_node()`
892
+ --- @param parsed_link_information Link #A table as returned by `parse_link()`
893
+ --- @param similarities PotentialLinkFixes[] #The table of similarities as returned by `fix_link_*()`
847
894
--- @param force_type boolean #If true will forcefully overwrite the link type to the target type as well (e.g. would convert `#` -> `*`)
848
895
write_fixed_link = function (link_node , parsed_link_information , similarities , force_type )
849
896
local most_similar = similarities [1 ]
@@ -882,19 +929,18 @@ module.private = {
882
929
{ replace }
883
930
)
884
931
end
885
-
886
932
callback (
887
933
" {"
888
934
.. lib .when (
889
- parsed_link_information .link_file_text ,
935
+ parsed_link_information .link_file_text --[[ @as boolean ]] ,
890
936
lib .lazy_string_concat (" :" , parsed_link_information .link_file_text , " :" ),
891
937
" "
892
938
)
893
939
.. prefix
894
940
.. most_similar .text
895
941
.. " }"
896
942
.. lib .when (
897
- parsed_link_information .link_description ,
943
+ parsed_link_information .link_description --[[ @as boolean ]] ,
898
944
lib .lazy_string_concat (" [" , parsed_link_information .link_description , " ]" ),
899
945
" "
900
946
)
@@ -906,17 +952,16 @@ module.on_event = function(event)
906
952
if event .split_type [2 ] == " core.esupports.hop.hop-link" then
907
953
local split_mode = event .content [1 ]
908
954
909
- -- Get link node at cursor
910
955
local link_node_at_cursor = module .public .extract_link_node ()
911
956
912
957
if not link_node_at_cursor then
913
958
log .trace (" No link under cursor." )
914
959
return
915
960
end
916
961
917
- local parsed_link = module .public .parse_link (link_node_at_cursor ) --- @diagnostic disable-line -- TODO : type error workaround < pysan3 >
962
+ local parsed_link = module .public .parse_link (link_node_at_cursor )
918
963
919
- module .public .follow_link (link_node_at_cursor , split_mode , parsed_link ) --- @diagnostic disable-line -- TODO : type error workaround < pysan3 >
964
+ module .public .follow_link (link_node_at_cursor , split_mode , parsed_link )
920
965
end
921
966
end
922
967
0 commit comments