@@ -25,7 +25,9 @@ mapping them):
2525
2626local neorg = require (" neorg.core" )
2727local config , lib , log , modules , utils = neorg .config , neorg .lib , neorg .log , neorg .modules , neorg .utils
28- local links , dirman_utils
28+
29+ --- @type core.links , core.dirman.utils , core.dirman
30+ local links , dirman_utils , dirman
2931
3032local module = modules .create (" core.esupports.hop" )
3133
@@ -36,6 +38,7 @@ module.setup = function()
3638 " core.integrations.treesitter" ,
3739 " core.ui" ,
3840 " core.dirman.utils" ,
41+ " core.dirman" ,
3942 " core.links" ,
4043 },
4144 }
4447module .load = function ()
4548 links = module .required [" core.links" ]
4649 dirman_utils = module .required [" core.dirman.utils" ]
50+ dirman = module .required [" core.dirman" ]
4751 vim .keymap .set (" " , " <Plug>(neorg.esupports.hop.hop-link)" , module .public .hop_link )
4852 vim .keymap .set (" " , " <Plug>(neorg.esupports.hop.hop-link.vsplit)" , lib .wrap (module .public .hop_link , " vsplit" ))
4953 vim .keymap .set (" " , " <Plug>(neorg.esupports.hop.hop-link.drop)" , lib .wrap (module .public .hop_link , " drop" ))
110114--- @field node TSNode The node of the target.
111115--- @field type LinkTargetType The type of target that was located.
112116--- @field buffer number The buffer ID in which the target was found.
117+ --- @field path string ? file path where the target resides
118+ --- @field line number ?
119+ --- @field uri string ?
113120
114121--- @class (exact ) PotentialLinkFixes
115122--- @field similarity number The similarity of this candidate to the current title of the link.
@@ -183,7 +190,7 @@ module.public = {
183190 end
184191
185192 local function jump_to_line (line )
186- local status , _ = pcall (vim .api .nvim_win_set_cursor , 0 , { line , 1 })
193+ local status , _ = pcall (vim .api .nvim_win_set_cursor , 0 , { line , 0 })
187194
188195 if not status then
189196 log .error (" Failed to jump to line:" , line , " - make sure the line number exists!" )
@@ -197,14 +204,6 @@ module.public = {
197204 end
198205
199206 lib .match (located_link_information .type )({
200- -- Filter the currently unsupported link types and let the user know that they do not work
201- wiki = function ()
202- vim .notify (
203- " Neorg doesn't support wiki links yet, please use a more specific link type instead." ,
204- vim .log .levels .WARN
205- )
206- end ,
207-
208207 -- If we're dealing with a URI, simply open the URI in the user's preferred method
209208 external_app = function ()
210209 os_open_link (located_link_information .uri )
@@ -568,7 +567,7 @@ module.public = {
568567 --- @param parsed_link_information Link #A table returned by `parse_link()`
569568 --- @return LinkTarget #A table containing data about the link target
570569 locate_link_target = function (parsed_link_information )
571- --- A pointer to the target buffer we will be parsing.
570+ -- A pointer to the target buffer we will be parsing.
572571 -- This may change depending on the target file the user gave.
573572 local buf_pointer = vim .api .nvim_get_current_buf ()
574573
@@ -592,11 +591,6 @@ module.public = {
592591 end
593592
594593 return lib .match (parsed_link_information .link_type )({
595- -- Wiki links are currently unsupported, so we simply forward the link type
596- wiki = function ()
597- return { type = " wiki" }
598- end ,
599-
600594 url = function ()
601595 return { type = " external_app" , uri = parsed_link_information .link_location_text }
602596 end ,
@@ -663,15 +657,25 @@ module.public = {
663657 }
664658 end ,
665659
660+ -- wiki falls through to here
666661 _ = function ()
667- local query_str = links .get_link_target_query_string (parsed_link_information .link_type )
662+ local typ = parsed_link_information .link_type
663+ if typ == " wiki" then
664+ typ = " generic"
665+ end
666+ local query_str = links .get_link_target_query_string (typ )
668667 local document_root = module .required [" core.integrations.treesitter" ].get_document_root (buf_pointer )
669668
670669 if not document_root then
671670 return
672671 end
673672
674673 local query = utils .ts_parse_query (" norg" , query_str )
674+ local link_target = parsed_link_information .link_location_text
675+ if not link_target then
676+ return
677+ end
678+ local target = link_target :gsub (" [%s\\ ]" , " " ):lower ()
675679
676680 for id , node in query :iter_captures (document_root , buf_pointer ) do
677681 local capture = query .captures [id ]
@@ -682,9 +686,8 @@ module.public = {
682686
683687 if original_title then
684688 local title = original_title :gsub (" [%s\\ ]" , " " )
685- local target = parsed_link_information .link_location_text :gsub (" [%s\\ ]" , " " )
686689
687- if title :lower () == target : lower () then
690+ if title :lower () == target then
688691 return {
689692 type = " buffer" ,
690693 original_title = original_title ,
@@ -695,6 +698,34 @@ module.public = {
695698 end
696699 end
697700 end
701+
702+ -- if we didn't find in the current file, search every other file, doesn't matter
703+ -- which file wins.
704+ local target_regex = target :gsub (" " , " ?" ):lower ()
705+ local heading_regex = ([[ ^\*+ %s$]] ):format (target_regex )
706+ local workspace_path = dirman .get_current_workspace ()[2 ]
707+
708+ local res = vim .system (
709+ { " rg" , " -i" , " --column" , " -o" , heading_regex },
710+ { cwd = tostring (workspace_path ), text = true }
711+ ):wait ()
712+
713+ if res .code == 0 then
714+ local best = vim .iter (vim .split (res .stdout , " \n " , { trimempty = true })):map (function (line )
715+ return { line :match (" (.-):(%d+):(%d+)" ) }
716+ end ):fold ({}, function (acc , val )
717+ if acc [1 ] and acc [1 ]:len () < val [1 ]:len () then
718+ return acc
719+ end
720+ return val
721+ end )
722+ return {
723+ type = " buffer" ,
724+ buffer = vim .uri_to_bufnr ((workspace_path / best [1 ]):as_uri ()),
725+ line = tonumber (best [2 ]),
726+ column = tonumber (best [3 ]),
727+ }
728+ end
698729 end ,
699730 } --[[ @as table<string, fun(): LinkTarget?>]] )
700731 end ,
@@ -800,7 +831,7 @@ module.private = {
800831 --- @return PotentialLinkFixes[] ? #A table of similarities (fuzzed items)
801832 fix_link_strict = function (parsed_link_information )
802833 local query = lib .match (parsed_link_information .link_type )({
803- generic = [[
834+ [{ " generic" , " wiki " }] = [[
804835 [(_
805836 [(strong_carryover_set
806837 (strong_carryover
@@ -933,10 +964,13 @@ module.private = {
933964
934965 local range = module .required [" core.integrations.treesitter" ].get_node_range (link_node )
935966
936- local prefix = lib .when (
937- parsed_link_information .link_type == " generic" and not force_type ,
938- " #" ,
939- lib .match (most_similar .node :type ())({
967+ local prefix
968+ if parsed_link_information .link_type == " generic" and not force_type then
969+ prefix = " #"
970+ elseif parsed_link_information .link_type == " wiki" and not force_type then
971+ prefix = " ?"
972+ else
973+ prefix = lib .match (most_similar .node :type ())({
940974 heading1 = " *" ,
941975 heading2 = " **" ,
942976 heading3 = " ***" ,
@@ -949,7 +983,8 @@ module.private = {
949983 multi_footnote = " ^" ,
950984 _ = " #" ,
951985 })
952- ) .. " "
986+ end
987+ prefix = prefix .. " "
953988
954989 local function callback (replace )
955990 vim .api .nvim_buf_set_text (
@@ -963,19 +998,19 @@ module.private = {
963998 end
964999 callback (
9651000 " {"
966- .. lib .when (
967- parsed_link_information .link_file_text --[[ @as boolean]] ,
968- lib .lazy_string_concat (" :" , parsed_link_information .link_file_text , " :" ),
969- " "
970- )
971- .. prefix
972- .. most_similar .text
973- .. " }"
974- .. lib .when (
975- parsed_link_information .link_description --[[ @as boolean]] ,
976- lib .lazy_string_concat (" [" , parsed_link_information .link_description , " ]" ),
977- " "
978- )
1001+ .. lib .when (
1002+ parsed_link_information .link_file_text --[[ @as boolean]] ,
1003+ lib .lazy_string_concat (" :" , parsed_link_information .link_file_text , " :" ),
1004+ " "
1005+ )
1006+ .. prefix
1007+ .. most_similar .text
1008+ .. " }"
1009+ .. lib .when (
1010+ parsed_link_information .link_description --[[ @as boolean]] ,
1011+ lib .lazy_string_concat (" [" , parsed_link_information .link_description , " ]" ),
1012+ " "
1013+ )
9791014 )
9801015 end ,
9811016}
0 commit comments