Skip to content

Commit 04a32dd

Browse files
authored
Fuzzy goto (#1559)
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 .
1 parent fd26c04 commit 04a32dd

File tree

2 files changed

+64
-4
lines changed

2 files changed

+64
-4
lines changed

apps/els_lsp/src/els_code_navigation.erl

+8-3
Original file line numberDiff line numberDiff line change
@@ -204,11 +204,15 @@ find_in_document([Uri | Uris0], Document, Kind, Data, AlreadyVisited) ->
204204
Defs = [POI || #{id := Id} = POI <- POIs, Id =:= Data],
205205
{AllDefs, MultipleDefs} =
206206
case Data of
207-
{_, any_arity} when Kind =:= function ->
207+
{_, any_arity} when
208+
Kind =:= function;
209+
Kind =:= define;
210+
Kind =:= type_definition
211+
->
208212
%% Including defs with any arity
209213
AnyArity = [
210214
POI
211-
|| #{id := {F, _}} = POI <- POIs, Kind =:= function, Data =:= {F, any_arity}
215+
|| #{id := {F, _}} = POI <- POIs, Data =:= {F, any_arity}
212216
],
213217
{AnyArity, true};
214218
_ ->
@@ -232,7 +236,8 @@ find_in_document([Uri | Uris0], Document, Kind, Data, AlreadyVisited) ->
232236
case MultipleDefs of
233237
true ->
234238
%% This will be the case only when the user tries to
235-
%% navigate to the definition of an atom
239+
%% navigate to the definition of an atom or a
240+
%% function/type/macro of wrong arity.
236241
[{Uri, POI} || POI <- SortedDefs];
237242
false ->
238243
%% In the general case, we return only one def

apps/els_lsp/src/els_definition_provider.erl

+56-1
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,69 @@ handle_request({definition, Params}) ->
2828
IncompletePOIs = match_incomplete(Text, {Line, Character}),
2929
case goto_definition(Uri, IncompletePOIs) of
3030
null ->
31-
els_references_provider:handle_request({references, Params});
31+
FuzzyPOIs = make_fuzzy(POIs),
32+
case goto_definition(Uri, FuzzyPOIs) of
33+
null ->
34+
els_references_provider:handle_request({references, Params});
35+
GoTo ->
36+
{response, GoTo}
37+
end;
3238
GoTo ->
3339
{response, GoTo}
3440
end;
3541
GoTo ->
3642
{response, GoTo}
3743
end.
3844

45+
-spec make_fuzzy([els_poi:poi()]) -> [els_poi:poi()].
46+
make_fuzzy(POIs) ->
47+
lists:flatmap(
48+
fun
49+
(#{kind := application, id := {M, F, _A}} = POI) ->
50+
[
51+
POI#{id => {M, F, any_arity}, kind => application},
52+
POI#{id => {M, F, any_arity}, kind => type_application}
53+
];
54+
(#{kind := type_application, id := {M, F, _A}} = POI) ->
55+
[
56+
POI#{id => {M, F, any_arity}, kind => type_application},
57+
POI#{id => {M, F, any_arity}, kind => application}
58+
];
59+
(#{kind := application, id := {F, _A}} = POI) ->
60+
[
61+
POI#{id => {F, any_arity}, kind => application},
62+
POI#{id => {F, any_arity}, kind => type_application},
63+
POI#{id => {F, any_arity}, kind => macro},
64+
POI#{id => F, kind => macro}
65+
];
66+
(#{kind := type_application, id := {F, _A}} = POI) ->
67+
[
68+
POI#{id => {F, any_arity}, kind => type_application},
69+
POI#{id => {F, any_arity}, kind => application},
70+
POI#{id => {F, any_arity}, kind => macro},
71+
POI#{id => F, kind => macro}
72+
];
73+
(#{kind := macro, id := {M, _A}} = POI) ->
74+
[
75+
POI#{id => M},
76+
POI#{id => {M, any_arity}}
77+
];
78+
(#{kind := macro, id := M} = POI) ->
79+
[
80+
POI#{id => {M, any_arity}}
81+
];
82+
(#{kind := atom, id := Id} = POI) ->
83+
[
84+
POI#{id => {Id, any_arity}, kind => application},
85+
POI#{id => {Id, any_arity}, kind => type_application},
86+
POI#{id => Id, kind => macro}
87+
];
88+
(_POI) ->
89+
[]
90+
end,
91+
POIs
92+
).
93+
3994
-spec goto_definition(uri(), [els_poi:poi()]) -> [map()] | null.
4095
goto_definition(_Uri, []) ->
4196
null;

0 commit comments

Comments
 (0)