Skip to content
This repository was archived by the owner on Oct 8, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 59 additions & 3 deletions lib/next_ls.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ defmodule NextLS do
alias GenLSP.Notifications.TextDocumentDidChange
alias GenLSP.Notifications.TextDocumentDidOpen
alias GenLSP.Notifications.TextDocumentDidSave
alias GenLSP.Notifications.WorkspaceDidChangeWorkspaceFolders
alias GenLSP.Requests.Initialize
alias GenLSP.Requests.Shutdown
alias GenLSP.Requests.TextDocumentDefinition
alias GenLSP.Requests.TextDocumentDocumentSymbol
alias GenLSP.Requests.TextDocumentFormatting
alias GenLSP.Requests.WorkspaceSymbol
alias GenLSP.Structures.DidChangeWorkspaceFoldersParams
alias GenLSP.Structures.DidOpenTextDocumentParams
alias GenLSP.Structures.InitializeParams
alias GenLSP.Structures.InitializeResult
Expand All @@ -28,6 +30,7 @@ defmodule NextLS do
alias GenLSP.Structures.TextDocumentItem
alias GenLSP.Structures.TextDocumentSyncOptions
alias GenLSP.Structures.TextEdit
alias GenLSP.Structures.WorkspaceFoldersChangeEvent
alias NextLS.Definition
alias NextLS.DiagnosticCache
alias NextLS.Progress
Expand Down Expand Up @@ -288,7 +291,7 @@ defmodule NextLS do
parent = self()
working_dir = URI.parse(uri).path

{:ok, runtime} =
{:ok, _} =
DynamicSupervisor.start_child(
lsp.assigns.dynamic_supervisor,
{NextLS.Runtime.Supervisor,
Expand All @@ -312,8 +315,6 @@ defmodule NextLS do
logger: lsp.assigns.logger
]}
)

{name, %{uri: uri, runtime: runtime}}
end

{:noreply, lsp}
Expand Down Expand Up @@ -379,6 +380,61 @@ defmodule NextLS do
{:noreply, put_in(lsp.assigns.documents[uri], String.split(text, "\n"))}
end

def handle_notification(
%WorkspaceDidChangeWorkspaceFolders{
params: %DidChangeWorkspaceFoldersParams{event: %WorkspaceFoldersChangeEvent{added: added, removed: removed}}
},
lsp
) do
dispatch(lsp.assigns.registry, :runtime_supervisors, fn entries ->
names = Enum.map(entries, fn {_, %{name: name}} -> name end)

for %{name: name, uri: uri} <- added, name not in names do
GenLSP.log(lsp, "[NextLS] Adding workspace folder #{name}")
token = token()
Progress.start(lsp, token, "Initializing NextLS runtime for folder #{name}...")
parent = self()
working_dir = URI.parse(uri).path

# TODO: probably extract this to the Runtime module
{:ok, _} =
DynamicSupervisor.start_child(
lsp.assigns.dynamic_supervisor,
{NextLS.Runtime.Supervisor,
path: Path.join(working_dir, ".elixir-tools"),
name: name,
registry: lsp.assigns.registry,
runtime: [
task_supervisor: lsp.assigns.runtime_task_supervisor,
working_dir: working_dir,
uri: uri,
on_initialized: fn status ->
if status == :ready do
Progress.stop(lsp, token, "NextLS runtime for folder #{name} has initialized!")
GenLSP.log(lsp, "[NextLS] Runtime for folder #{name} is ready...")
send(parent, {:runtime_ready, name, self()})
else
Progress.stop(lsp, token)
GenLSP.error(lsp, "[NextLS] Runtime for folder #{name} failed to initialize")
end
end,
logger: lsp.assigns.logger
]}
)
end

names = Enum.map(removed, & &1.name)

for {pid, %{name: name}} <- entries, name in names do
GenLSP.log(lsp, "[NextLS] Removing workspace folder #{name}")
# TODO: probably extract this to the Runtime module
DynamicSupervisor.terminate_child(lsp.assigns.dynamic_supervisor, pid)
end
end)

{:noreply, lsp}
end

def handle_notification(%Exit{}, lsp) do
System.halt(lsp.assigns.exit_code)

Expand Down
10 changes: 8 additions & 2 deletions lib/next_ls/runtime.ex
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,14 @@ defmodule NextLS.Runtime do
ref = Process.monitor(me)

receive do
{:DOWN, ^ref, :process, ^me, _reason} ->
NextLS.Logger.error(logger, "[NextLS] The runtime for #{name} has crashed")
{:DOWN, ^ref, :process, ^me, reason} ->
case reason do
:shutdown ->
NextLS.Logger.log(logger, "The runtime for #{name} has successfully shutdown.")

reason ->
NextLS.Logger.error(logger, "The runtime for #{name} has crashed with reason: #{reason}.")
end
end
end)

Expand Down
2 changes: 2 additions & 0 deletions lib/next_ls/runtime/supervisor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ defmodule NextLS.Runtime.Supervisor do
symbol_table_name = :"symbol-table-#{name}"
sidecar_name = :"sidecar-#{name}"

Registry.register(registry, :runtime_supervisors, %{name: name})

children = [
{NextLS.SymbolTable, workspace: name, path: hidden_folder, registry: registry, name: symbol_table_name},
{NextLS.Runtime.Sidecar, name: sidecar_name, symbol_table: symbol_table_name},
Expand Down
Loading