Skip to content

Commit dc54829

Browse files
committed
feat: defmodule snippet infer module name
1 parent 4aa157f commit dc54829

File tree

4 files changed

+103
-16
lines changed

4 files changed

+103
-16
lines changed

lib/next_ls.ex

+1-1
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,7 @@ defmodule NextLS do
617617
documentation: docs
618618
}
619619

620-
case NextLS.Snippet.get(label, nil) do
620+
case NextLS.Snippet.get(label, nil, uri: uri) do
621621
nil -> [completion_item | results]
622622
%{} = snippet -> [Map.merge(completion_item, snippet) | results]
623623
end

lib/next_ls/helpers/ast_helpers/env.ex

+2
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ defmodule NextLS.ASTHelpers.Env do
113113
}
114114
end
115115

116+
def ascend(nil, acc, _callback), do: acc
117+
116118
def ascend(%Zipper{path: nil} = zipper, acc, callback), do: callback.(Zipper.node(zipper), zipper, acc)
117119

118120
def ascend(zipper, acc, callback) do

lib/next_ls/snippet.ex

+66-15
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,30 @@
11
defmodule NextLS.Snippet do
22
@moduledoc false
33

4-
def get("defmodule/2", nil) do
4+
def get(label, trigger_character, opts \\ [])
5+
6+
def get("defmodule/2", nil, opts) do
7+
uri = Keyword.get(opts, :uri)
8+
9+
modulename =
10+
if uri do
11+
infer_module_name(uri)
12+
else
13+
"ModuleName"
14+
end
15+
516
%{
617
kind: GenLSP.Enumerations.CompletionItemKind.snippet(),
718
insert_text_format: GenLSP.Enumerations.InsertTextFormat.snippet(),
819
insert_text: """
9-
defmodule ${1:ModuleName} do
20+
defmodule ${1:#{modulename}} do
1021
$0
1122
end
1223
"""
1324
}
1425
end
1526

16-
def get("defstruct/1", nil) do
27+
def get("defstruct/1", nil, _opts) do
1728
%{
1829
kind: GenLSP.Enumerations.CompletionItemKind.snippet(),
1930
insert_text_format: GenLSP.Enumerations.InsertTextFormat.snippet(),
@@ -23,7 +34,7 @@ defmodule NextLS.Snippet do
2334
}
2435
end
2536

26-
def get("defprotocol/2", nil) do
37+
def get("defprotocol/2", nil, _opts) do
2738
%{
2839
kind: GenLSP.Enumerations.CompletionItemKind.snippet(),
2940
insert_text_format: GenLSP.Enumerations.InsertTextFormat.snippet(),
@@ -35,7 +46,7 @@ defmodule NextLS.Snippet do
3546
}
3647
end
3748

38-
def get("defimpl/2", nil) do
49+
def get("defimpl/2", nil, _opts) do
3950
%{
4051
kind: GenLSP.Enumerations.CompletionItemKind.snippet(),
4152
insert_text_format: GenLSP.Enumerations.InsertTextFormat.snippet(),
@@ -49,7 +60,7 @@ defmodule NextLS.Snippet do
4960
}
5061
end
5162

52-
def get("defimpl/3", nil) do
63+
def get("defimpl/3", nil, _opts) do
5364
%{
5465
kind: GenLSP.Enumerations.CompletionItemKind.snippet(),
5566
insert_text_format: GenLSP.Enumerations.InsertTextFormat.snippet(),
@@ -63,7 +74,7 @@ defmodule NextLS.Snippet do
6374
}
6475
end
6576

66-
def get("def/" <> _, nil) do
77+
def get("def/" <> _, nil, _opts) do
6778
%{
6879
kind: GenLSP.Enumerations.CompletionItemKind.snippet(),
6980
insert_text_format: GenLSP.Enumerations.InsertTextFormat.snippet(),
@@ -75,7 +86,7 @@ defmodule NextLS.Snippet do
7586
}
7687
end
7788

78-
def get("defp/" <> _, nil) do
89+
def get("defp/" <> _, nil, _opts) do
7990
%{
8091
kind: GenLSP.Enumerations.CompletionItemKind.snippet(),
8192
insert_text_format: GenLSP.Enumerations.InsertTextFormat.snippet(),
@@ -87,7 +98,7 @@ defmodule NextLS.Snippet do
8798
}
8899
end
89100

90-
def get("defmacro/" <> _, nil) do
101+
def get("defmacro/" <> _, nil, _opts) do
91102
%{
92103
kind: GenLSP.Enumerations.CompletionItemKind.snippet(),
93104
insert_text_format: GenLSP.Enumerations.InsertTextFormat.snippet(),
@@ -101,7 +112,7 @@ defmodule NextLS.Snippet do
101112
}
102113
end
103114

104-
def get("defmacrop/" <> _, nil) do
115+
def get("defmacrop/" <> _, nil, _opts) do
105116
%{
106117
kind: GenLSP.Enumerations.CompletionItemKind.snippet(),
107118
insert_text_format: GenLSP.Enumerations.InsertTextFormat.snippet(),
@@ -115,7 +126,7 @@ defmodule NextLS.Snippet do
115126
}
116127
end
117128

118-
def get("for/" <> _, nil) do
129+
def get("for/" <> _, nil, _opts) do
119130
%{
120131
kind: GenLSP.Enumerations.CompletionItemKind.snippet(),
121132
insert_text_format: GenLSP.Enumerations.InsertTextFormat.snippet(),
@@ -127,7 +138,7 @@ defmodule NextLS.Snippet do
127138
}
128139
end
129140

130-
def get("with/" <> _, nil) do
141+
def get("with/" <> _, nil, _opts) do
131142
%{
132143
kind: GenLSP.Enumerations.CompletionItemKind.snippet(),
133144
insert_text_format: GenLSP.Enumerations.InsertTextFormat.snippet(),
@@ -139,7 +150,7 @@ defmodule NextLS.Snippet do
139150
}
140151
end
141152

142-
def get("case/" <> _, nil) do
153+
def get("case/" <> _, nil, _opts) do
143154
%{
144155
kind: GenLSP.Enumerations.CompletionItemKind.snippet(),
145156
insert_text_format: GenLSP.Enumerations.InsertTextFormat.snippet(),
@@ -155,7 +166,7 @@ defmodule NextLS.Snippet do
155166
}
156167
end
157168

158-
def get("cond/" <> _, nil) do
169+
def get("cond/" <> _, nil, _opts) do
159170
%{
160171
kind: GenLSP.Enumerations.CompletionItemKind.snippet(),
161172
insert_text_format: GenLSP.Enumerations.InsertTextFormat.snippet(),
@@ -171,7 +182,47 @@ defmodule NextLS.Snippet do
171182
}
172183
end
173184

174-
def get(_label, _trigger_character) do
185+
def get(_label, _trigger_character, _opts) do
175186
nil
176187
end
188+
189+
defp infer_module_name(uri) do
190+
result =
191+
uri
192+
|> Path.split()
193+
|> Enum.reduce(false, fn
194+
"lib", _ ->
195+
{:lib, []}
196+
197+
"test", _ ->
198+
{:test, []}
199+
200+
"support", {:test, _} ->
201+
{:lib, []}
202+
203+
_, false ->
204+
false
205+
206+
element, {type, elements} ->
207+
camelized =
208+
element
209+
|> Path.rootname()
210+
|> Macro.camelize()
211+
212+
{type, [camelized | elements]}
213+
end)
214+
215+
case result do
216+
{_, parts} ->
217+
parts
218+
|> Enum.reverse()
219+
|> Enum.join(".")
220+
221+
false ->
222+
uri
223+
|> Path.basename()
224+
|> Path.rootname()
225+
|> Macro.camelize()
226+
end
227+
end
177228
end

test/next_ls/completions_test.exs

+34
Original file line numberDiff line numberDiff line change
@@ -300,4 +300,38 @@ defmodule NextLS.CompletionsTest do
300300
"label" => "next_ls/"
301301
} in results
302302
end
303+
304+
test "defmodule infer name", %{client: client, foo: foo} do
305+
uri = uri(foo)
306+
307+
did_open(client, foo, """
308+
defmod
309+
""")
310+
311+
request client, %{
312+
method: "textDocument/completion",
313+
id: 2,
314+
jsonrpc: "2.0",
315+
params: %{
316+
textDocument: %{
317+
uri: uri
318+
},
319+
position: %{
320+
line: 0,
321+
character: 6
322+
}
323+
}
324+
}
325+
326+
assert_result 2, [
327+
%{
328+
"data" => nil,
329+
"documentation" => _,
330+
"insertText" => "defmodule ${1:Foo} do\n $0\nend\n",
331+
"kind" => 15,
332+
"label" => "defmodule/2",
333+
"insertTextFormat" => 2
334+
}
335+
]
336+
end
303337
end

0 commit comments

Comments
 (0)