Skip to content

Commit b9f55cc

Browse files
authored
Remove support for query prefixes in WorkspaceSymbolsProvider (#396)
Closes #392
1 parent 7418065 commit b9f55cc

File tree

3 files changed

+107
-209
lines changed

3 files changed

+107
-209
lines changed

README.md

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -196,25 +196,7 @@ The completions include:
196196

197197
## Workspace Symbols
198198

199-
With Dialyzer integration enabled ElixirLS will build an index of symbols (modules, functions, types and callbacks). The symbols are taken from the current workspace, all dependencies and stdlib (Elixir and erlang). This feature enables quick navigation to symbol definitions. However due to sheer number of different symbols and fuzzy search utilized by the provider, ElixirLS uses query prefixes to improve search results relevance.
200-
201-
Use the following rules when navigating to workspace symbols:
202-
* no prefix - search for modules
203-
* `:erl`
204-
* `Enu`
205-
* `f ` prefix - search for functions
206-
* `f inse`
207-
* `f :ets.inse`
208-
* `f Enum.cou`
209-
* `f count/0`
210-
* `t ` prefix - search for types
211-
* `t t/0`
212-
* `t :erlang.time_u`
213-
* `t DateTime.`
214-
* `c ` prefix - search for callbacks
215-
* `c handle_info`
216-
* `c GenServer.in`
217-
* `c :gen_statem`
199+
With Dialyzer integration enabled ElixirLS will build an index of symbols (modules, functions, types and callbacks). The symbols are taken from the current workspace, all dependencies and stdlib (Elixir and erlang). This feature enables quick navigation to symbol definitions.
218200

219201
## Troubleshooting
220202

apps/language_server/lib/language_server/providers/workspace_symbols.ex

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,7 @@ defmodule ElixirLS.LanguageServer.Providers.WorkspaceSymbols do
5454

5555
@spec symbols(String.t()) :: {:ok, [symbol_information_t]}
5656
def symbols(query, server \\ __MODULE__) do
57-
results =
58-
case query do
59-
"f " <> fun_query ->
60-
query(:functions, fun_query, server)
61-
62-
"t " <> type_query ->
63-
query(:types, type_query, server)
64-
65-
"c " <> callback_query ->
66-
query(:callbacks, callback_query, server)
67-
68-
module_query ->
69-
query(:modules, module_query, server)
70-
end
57+
results = query(query, server)
7158

7259
{:ok, results}
7360
end
@@ -109,10 +96,10 @@ defmodule ElixirLS.LanguageServer.Providers.WorkspaceSymbols do
10996
end
11097

11198
@impl GenServer
112-
def handle_call({:query, key, query}, from, state) do
99+
def handle_call({:query, query}, from, state) do
113100
{:ok, _pid} =
114101
Task.start_link(fn ->
115-
results = get_results(state, key, query)
102+
results = get_results(state, query)
116103
GenServer.reply(from, results)
117104
end)
118105

@@ -356,13 +343,13 @@ defmodule ElixirLS.LanguageServer.Providers.WorkspaceSymbols do
356343
|> elem(0)
357344
end
358345

359-
defp query(kind, query, server) do
346+
defp query(query, server) do
360347
case String.trim(query) do
361348
"" ->
362349
[]
363350

364351
trimmed ->
365-
GenServer.call(server, {:query, kind, trimmed})
352+
GenServer.call(server, {:query, trimmed})
366353
end
367354
end
368355

@@ -446,14 +433,13 @@ defmodule ElixirLS.LanguageServer.Providers.WorkspaceSymbols do
446433
:ok
447434
end
448435

449-
@spec get_results(state_t, key_t, String.t()) :: [symbol_information_t]
450-
defp get_results(state, key, query) do
436+
@spec get_results(state_t, String.t()) :: [symbol_information_t]
437+
defp get_results(state, query) do
451438
query_downcase = String.downcase(query)
452439
query_length = String.length(query)
453440
arity_suffix = Regex.run(@arity_suffix_regex, query)
454441

455-
state
456-
|> Map.fetch!(key)
442+
(state.modules ++ state.functions ++ state.types ++ state.callbacks)
457443
|> process_chunked(fn chunk ->
458444
chunk
459445
|> Enum.map(&{&1, get_score(&1.name, query, query_downcase, query_length, arity_suffix)})
@@ -509,15 +495,15 @@ defmodule ElixirLS.LanguageServer.Providers.WorkspaceSymbols do
509495
end
510496

511497
defp symbol_name(:functions, {module, function, arity}) do
512-
"f #{inspect(module)}.#{function}/#{arity}"
498+
"#{inspect(module)}.#{function}/#{arity}"
513499
end
514500

515501
defp symbol_name(:types, {module, type, arity}) do
516-
"t #{inspect(module)}.#{type}/#{arity}"
502+
"#{inspect(module)}.#{type}/#{arity}"
517503
end
518504

519505
defp symbol_name(:callbacks, {module, callback, arity}) do
520-
"c #{inspect(module)}.#{callback}/#{arity}"
506+
"#{inspect(module)}.#{callback}/#{arity}"
521507
end
522508

523509
@spec build_range(nil | non_neg_integer) :: range_t

apps/language_server/test/providers/workspace_symbols_test.exs

Lines changed: 95 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -44,180 +44,110 @@ defmodule ElixirLS.LanguageServer.Providers.WorkspaceSymbolsTest do
4444
end
4545

4646
test "returns modules", %{server: server} do
47-
assert {:ok,
48-
[
49-
%{
50-
kind: 2,
51-
location: %{
52-
range: %{end: %{character: 0, line: 1}, start: %{character: 0, line: 0}},
53-
uri: uri
54-
},
55-
name: "ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols"
56-
}
57-
]} = WorkspaceSymbols.symbols("ElixirLS.LanguageServer.Fixtures.", server)
58-
59-
assert uri |> String.ends_with?("test/support/fixtures/workspace_symbols.ex")
60-
61-
assert {:ok,
62-
[
63-
%{
64-
kind: 2,
65-
location: %{
66-
range: %{end: %{character: 0, line: 1}, start: %{character: 0, line: 0}},
67-
uri: uri
68-
},
69-
name: "ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols"
70-
}
71-
]} = WorkspaceSymbols.symbols("work", server)
72-
73-
assert uri |> String.ends_with?("test/support/fixtures/workspace_symbols.ex")
47+
assert {:ok, list} = WorkspaceSymbols.symbols("ElixirLS.LanguageServer.Fixtures.", server)
48+
49+
assert module =
50+
Enum.find(list, &(&1.name == "ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols"))
51+
52+
assert module.kind == 2
53+
assert module.location.uri |> String.ends_with?("test/support/fixtures/workspace_symbols.ex")
54+
55+
assert module.location.range == %{
56+
end: %{character: 0, line: 1},
57+
start: %{character: 0, line: 0}
58+
}
59+
60+
assert WorkspaceSymbols.symbols("work", server)
61+
|> elem(1)
62+
|> Enum.any?(&(&1.name == "ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols"))
7463
end
7564

7665
test "returns functions", %{server: server} do
77-
assert {
78-
:ok,
79-
[
80-
%{
81-
kind: 12,
82-
location: %{
83-
range: %{end: %{character: 0, line: 1}, start: %{character: 0, line: 0}},
84-
uri: uri
85-
},
86-
name: "f ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.module_info/1"
87-
},
88-
%{
89-
kind: 12,
90-
location: %{
91-
range: %{end: %{character: 0, line: 1}, start: %{character: 0, line: 0}}
92-
},
93-
name: "f ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.module_info/0"
94-
},
95-
%{
96-
kind: 12,
97-
location: %{
98-
range: %{end: %{character: 0, line: 1}, start: %{character: 0, line: 0}}
99-
},
100-
name: "f ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.behaviour_info/1"
101-
},
102-
%{
103-
kind: 12,
104-
location: %{
105-
range: %{end: %{character: 0, line: 3}, start: %{character: 0, line: 2}}
106-
},
107-
name: "f ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.some_macro/1"
108-
},
109-
%{
110-
kind: 12,
111-
location: %{
112-
range: %{end: %{character: 0, line: 2}, start: %{character: 0, line: 1}}
113-
},
114-
name: "f ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.some_function/1"
115-
},
116-
%{
117-
kind: 12,
118-
location: %{
119-
range: %{end: %{character: 0, line: 1}, start: %{character: 0, line: 0}}
120-
},
121-
name: "f ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.__info__/1"
122-
}
123-
]
124-
} = WorkspaceSymbols.symbols("f ElixirLS.LanguageServer.Fixtures.", server)
125-
126-
assert uri |> String.ends_with?("test/support/fixtures/workspace_symbols.ex")
127-
128-
assert {:ok,
129-
[
130-
%{
131-
kind: 12,
132-
location: %{
133-
range: %{end: %{character: 0, line: 2}, start: %{character: 0, line: 1}},
134-
uri: uri
135-
},
136-
name: "f ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.some_function/1"
137-
}
138-
]} = WorkspaceSymbols.symbols("f fun", server)
139-
140-
assert uri |> String.ends_with?("test/support/fixtures/workspace_symbols.ex")
66+
assert {:ok, list} = WorkspaceSymbols.symbols("ElixirLS.LanguageServer.Fixtures.", server)
67+
68+
assert some_function =
69+
Enum.find(
70+
list,
71+
&(&1.name == "ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.some_function/1")
72+
)
73+
74+
assert some_function.kind == 12
75+
76+
assert some_function.location.uri
77+
|> String.ends_with?("test/support/fixtures/workspace_symbols.ex")
78+
79+
assert some_function.location.range == %{
80+
end: %{character: 0, line: 2},
81+
start: %{character: 0, line: 1}
82+
}
83+
84+
assert WorkspaceSymbols.symbols("fun", server)
85+
|> elem(1)
86+
|> Enum.any?(
87+
&(&1.name == "ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.some_function/1")
88+
)
14189
end
14290

14391
test "returns types", %{server: server} do
144-
assert {
145-
:ok,
146-
[
147-
%{
148-
kind: 5,
149-
location: %{
150-
range: %{end: %{character: 0, line: 8}, start: %{character: 0, line: 7}},
151-
uri: uri
152-
},
153-
name: "t ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.some_type/0"
154-
},
155-
%{
156-
kind: 5,
157-
location: %{
158-
range: %{end: %{character: 0, line: 9}, start: %{character: 0, line: 8}}
159-
},
160-
name: "t ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.some_opaque_type/0"
161-
}
162-
]
163-
} = WorkspaceSymbols.symbols("t ElixirLS.LanguageServer.Fixtures.", server)
164-
165-
assert uri |> String.ends_with?("test/support/fixtures/workspace_symbols.ex")
166-
167-
assert {
168-
:ok,
169-
[
170-
%{
171-
kind: 5,
172-
location: %{
173-
range: %{end: %{character: 0, line: 9}, start: %{character: 0, line: 8}},
174-
uri: uri
175-
},
176-
name: "t ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.some_opaque_type/0"
177-
}
178-
]
179-
} = WorkspaceSymbols.symbols("t opa", server)
180-
181-
assert uri |> String.ends_with?("test/support/fixtures/workspace_symbols.ex")
92+
assert {:ok, list} = WorkspaceSymbols.symbols("ElixirLS.LanguageServer.Fixtures.", server)
93+
94+
assert some_type =
95+
Enum.find(
96+
list,
97+
&(&1.name == "ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.some_type/0")
98+
)
99+
100+
assert some_type.kind == 5
101+
102+
assert some_type.location.uri
103+
|> String.ends_with?("test/support/fixtures/workspace_symbols.ex")
104+
105+
assert some_type.location.range == %{
106+
end: %{character: 0, line: 8},
107+
start: %{character: 0, line: 7}
108+
}
109+
110+
assert Enum.any?(
111+
list,
112+
&(&1.name == "ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.some_opaque_type/0")
113+
)
114+
115+
assert WorkspaceSymbols.symbols("opa", server)
116+
|> elem(1)
117+
|> Enum.any?(
118+
&(&1.name == "ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.some_opaque_type/0")
119+
)
182120
end
183121

184122
test "returns callbacks", %{server: server} do
185-
assert {
186-
:ok,
187-
[
188-
%{
189-
kind: 24,
190-
location: %{
191-
range: %{end: %{character: 0, line: 5}, start: %{character: 0, line: 4}},
192-
uri: uri
193-
},
194-
name: "c ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.some_callback/1"
195-
},
196-
%{
197-
kind: 24,
198-
location: %{
199-
range: %{end: %{character: 0, line: 6}, start: %{character: 0, line: 5}}
200-
},
201-
name: "c ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.some_macrocallback/1"
202-
}
203-
]
204-
} = WorkspaceSymbols.symbols("c ElixirLS.LanguageServer.Fixtures.", server)
205-
206-
assert uri |> String.ends_with?("test/support/fixtures/workspace_symbols.ex")
207-
208-
assert {:ok,
209-
[
210-
%{
211-
kind: 24,
212-
location: %{
213-
range: %{end: %{character: 0, line: 6}, start: %{character: 0, line: 5}},
214-
uri: uri
215-
},
216-
name: "c ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.some_macrocallback/1"
217-
}
218-
]} = WorkspaceSymbols.symbols("c macr", server)
219-
220-
assert uri |> String.ends_with?("test/support/fixtures/workspace_symbols.ex")
123+
assert {:ok, list} = WorkspaceSymbols.symbols("ElixirLS.LanguageServer.Fixtures.", server)
124+
125+
assert some_callback =
126+
Enum.find(
127+
list,
128+
&(&1.name == "ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.some_callback/1")
129+
)
130+
131+
assert some_callback.kind == 24
132+
133+
assert some_callback.location.uri
134+
|> String.ends_with?("test/support/fixtures/workspace_symbols.ex")
135+
136+
assert some_callback.location.range == %{
137+
end: %{character: 0, line: 5},
138+
start: %{character: 0, line: 4}
139+
}
140+
141+
assert Enum.any?(
142+
list,
143+
&(&1.name == "ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.some_macrocallback/1")
144+
)
145+
146+
assert WorkspaceSymbols.symbols("macr", server)
147+
|> elem(1)
148+
|> Enum.any?(
149+
&(&1.name == "ElixirLS.LanguageServer.Fixtures.WorkspaceSymbols.some_macrocallback/1")
150+
)
221151
end
222152

223153
defp wait_until_indexed(pid) do

0 commit comments

Comments
 (0)