Skip to content
This repository was archived by the owner on Oct 8, 2025. It is now read-only.

Commit 2d2cad1

Browse files
committed
feat: completions
wip
1 parent 0205bbf commit 2d2cad1

File tree

8 files changed

+1824
-6
lines changed

8 files changed

+1824
-6
lines changed

lib/next_ls.ex

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ defmodule NextLS do
1616
alias GenLSP.Notifications.WorkspaceDidChangeWorkspaceFolders
1717
alias GenLSP.Requests.Initialize
1818
alias GenLSP.Requests.Shutdown
19+
alias GenLSP.Requests.TextDocumentCompletion
1920
alias GenLSP.Requests.TextDocumentDefinition
2021
alias GenLSP.Requests.TextDocumentDocumentSymbol
2122
alias GenLSP.Requests.TextDocumentFormatting
@@ -117,6 +118,9 @@ defmodule NextLS do
117118
save: %SaveOptions{include_text: true},
118119
change: TextDocumentSyncKind.full()
119120
},
121+
completion_provider: %GenLSP.Structures.CompletionOptions{
122+
trigger_characters: [".", "@", "&", "%", "^", ":", "!", "-", "~"]
123+
},
120124
document_formatting_provider: true,
121125
hover_provider: true,
122126
workspace_symbol_provider: true,
@@ -504,6 +508,74 @@ defmodule NextLS do
504508
resp
505509
end
506510

511+
def handle_request(%TextDocumentCompletion{params: %{text_document: %{uri: uri}, position: position}}, lsp) do
512+
document = lsp.assigns.documents[uri]
513+
514+
document_slice =
515+
document
516+
|> Enum.take(position.line + 1)
517+
|> Enum.reverse()
518+
|> then(fn [last_line | rest] ->
519+
[String.slice(last_line, 1..(position.character + 1)) | rest]
520+
end)
521+
|> Enum.reverse()
522+
|> Enum.join("\n")
523+
524+
results =
525+
lsp.assigns.registry
526+
|> dispatch(:runtimes, fn entries ->
527+
[result] =
528+
for {runtime, %{uri: wuri}} <- entries, String.starts_with?(uri, wuri) do
529+
NextLS.Autocomplete.expand(document_slice |> String.to_charlist() |> Enum.reverse(), runtime)
530+
end
531+
532+
case result do
533+
{:yes, _, entries} -> entries
534+
_ -> []
535+
end
536+
end)
537+
|> Enum.map(fn %{name: name, kind: kind} = symbol ->
538+
{label, kind, docs} =
539+
case kind do
540+
:struct -> {name, GenLSP.Enumerations.CompletionItemKind.struct(), ""}
541+
:function -> {"#{name}/#{symbol.arity}", GenLSP.Enumerations.CompletionItemKind.function(), symbol.docs}
542+
:module -> {name, GenLSP.Enumerations.CompletionItemKind.module(), ""}
543+
:variable -> {name, GenLSP.Enumerations.CompletionItemKind.variable(), ""}
544+
_ -> {name, GenLSP.Enumerations.CompletionItemKind.text(), ""}
545+
end
546+
547+
%GenLSP.Structures.CompletionItem{
548+
label: label,
549+
kind: kind,
550+
insert_text: name,
551+
documentation: docs
552+
}
553+
end)
554+
555+
# results =
556+
# for snippet <- [
557+
# "defmodule",
558+
# "def",
559+
# "defp",
560+
# "defmacro",
561+
# "defmacrop",
562+
# "for",
563+
# "with",
564+
# "case",
565+
# "cond",
566+
# "defprotocol",
567+
# "defimpl",
568+
# "defexception",
569+
# "defstruct"
570+
# ],
571+
# item <- List.wrap(NextLS.Snippet.get(snippet, context.trigger_character)),
572+
# item do
573+
# item
574+
# end
575+
576+
{:reply, results, lsp}
577+
end
578+
507579
def handle_request(%Shutdown{}, lsp) do
508580
{:reply, nil, assign(lsp, exit_code: 0)}
509581
end

0 commit comments

Comments
 (0)