Skip to content

Commit

Permalink
Fuzzy goto (#1559)
Browse files Browse the repository at this point in the history
If we don't have a precise match, try to find a close match for goto definition, e.g. if we have a(q,w,e) but only a/4 defined jump there.

Fixes #1250 .
  • Loading branch information
plux authored Oct 7, 2024
1 parent fd26c04 commit 04a32dd
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 4 deletions.
11 changes: 8 additions & 3 deletions apps/els_lsp/src/els_code_navigation.erl
Original file line number Diff line number Diff line change
Expand Up @@ -204,11 +204,15 @@ find_in_document([Uri | Uris0], Document, Kind, Data, AlreadyVisited) ->
Defs = [POI || #{id := Id} = POI <- POIs, Id =:= Data],
{AllDefs, MultipleDefs} =
case Data of
{_, any_arity} when Kind =:= function ->
{_, any_arity} when
Kind =:= function;
Kind =:= define;
Kind =:= type_definition
->
%% Including defs with any arity
AnyArity = [
POI
|| #{id := {F, _}} = POI <- POIs, Kind =:= function, Data =:= {F, any_arity}
|| #{id := {F, _}} = POI <- POIs, Data =:= {F, any_arity}
],
{AnyArity, true};
_ ->
Expand All @@ -232,7 +236,8 @@ find_in_document([Uri | Uris0], Document, Kind, Data, AlreadyVisited) ->
case MultipleDefs of
true ->
%% This will be the case only when the user tries to
%% navigate to the definition of an atom
%% navigate to the definition of an atom or a
%% function/type/macro of wrong arity.
[{Uri, POI} || POI <- SortedDefs];
false ->
%% In the general case, we return only one def
Expand Down
57 changes: 56 additions & 1 deletion apps/els_lsp/src/els_definition_provider.erl
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,69 @@ handle_request({definition, Params}) ->
IncompletePOIs = match_incomplete(Text, {Line, Character}),
case goto_definition(Uri, IncompletePOIs) of
null ->
els_references_provider:handle_request({references, Params});
FuzzyPOIs = make_fuzzy(POIs),
case goto_definition(Uri, FuzzyPOIs) of
null ->
els_references_provider:handle_request({references, Params});
GoTo ->
{response, GoTo}
end;
GoTo ->
{response, GoTo}
end;
GoTo ->
{response, GoTo}
end.

-spec make_fuzzy([els_poi:poi()]) -> [els_poi:poi()].
make_fuzzy(POIs) ->
lists:flatmap(
fun
(#{kind := application, id := {M, F, _A}} = POI) ->
[
POI#{id => {M, F, any_arity}, kind => application},
POI#{id => {M, F, any_arity}, kind => type_application}
];
(#{kind := type_application, id := {M, F, _A}} = POI) ->
[
POI#{id => {M, F, any_arity}, kind => type_application},
POI#{id => {M, F, any_arity}, kind => application}
];
(#{kind := application, id := {F, _A}} = POI) ->
[
POI#{id => {F, any_arity}, kind => application},
POI#{id => {F, any_arity}, kind => type_application},
POI#{id => {F, any_arity}, kind => macro},
POI#{id => F, kind => macro}
];
(#{kind := type_application, id := {F, _A}} = POI) ->
[
POI#{id => {F, any_arity}, kind => type_application},
POI#{id => {F, any_arity}, kind => application},
POI#{id => {F, any_arity}, kind => macro},
POI#{id => F, kind => macro}
];
(#{kind := macro, id := {M, _A}} = POI) ->
[
POI#{id => M},
POI#{id => {M, any_arity}}
];
(#{kind := macro, id := M} = POI) ->
[
POI#{id => {M, any_arity}}
];
(#{kind := atom, id := Id} = POI) ->
[
POI#{id => {Id, any_arity}, kind => application},
POI#{id => {Id, any_arity}, kind => type_application},
POI#{id => Id, kind => macro}
];
(_POI) ->
[]
end,
POIs
).

-spec goto_definition(uri(), [els_poi:poi()]) -> [map()] | null.
goto_definition(_Uri, []) ->
null;
Expand Down

0 comments on commit 04a32dd

Please sign in to comment.