Skip to content

Commit 87da773

Browse files
committed
Support workspace/project shims with elixir_exec option
Relates to #334 IDEs like to work with shims rather than tools that alter path (such as `mise`/`rtx`). As a result, one must launch their IDE manually from a terminal session with all the `PATH` loaded in order to properly find the `elixir` executable. This works fine, but switching between projects/workspaces that have varying Elixir/OTP versions will most likely be using the version loaded when launching the program from terminal. One resolve might be to include shims in the `PATH` globally. However, that negates some of the reasoning to move to alternate tools like `mise. Instead, this allows setting the `elixir_exec` option to point directly at a shim. When used in workspace directories, that should also be able to load the correct versions defined in the tool version files. This also allows keeping the need for a shim isolated to the LS tool rather than global use
1 parent 8cf06cb commit 87da773

File tree

3 files changed

+47
-1
lines changed

3 files changed

+47
-1
lines changed

lib/next_ls.ex

+3
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,7 @@ defmodule NextLS do
661661
uri: uri,
662662
mix_env: lsp.assigns.init_opts.mix_env,
663663
mix_target: lsp.assigns.init_opts.mix_target,
664+
elixir_exec: lsp.assigns.init_opts.elixir_exec,
664665
on_initialized: fn status ->
665666
if status == :ready do
666667
Progress.stop(lsp, token, "NextLS runtime for folder #{name} has initialized!")
@@ -1117,6 +1118,7 @@ defmodule NextLS do
11171118

11181119
defstruct mix_target: "host",
11191120
mix_env: "dev",
1121+
elixir_exec: nil,
11201122
experimental: %NextLS.InitOpts.Experimental{},
11211123
extensions: %NextLS.InitOpts.Extensions{}
11221124

@@ -1126,6 +1128,7 @@ defmodule NextLS do
11261128
schema(__MODULE__, %{
11271129
optional(:mix_target) => str(),
11281130
optional(:mix_env) => str(),
1131+
optional(:elixir_exec) => str(),
11291132
optional(:experimental) =>
11301133
schema(NextLS.InitOpts.Experimental, %{
11311134
optional(:completions) =>

lib/next_ls/runtime.ex

+13-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ defmodule NextLS.Runtime do
111111
new_path = String.replace(path, bindir <> ":", "")
112112

113113
with dir when is_list(dir) <- :code.priv_dir(:next_ls),
114-
elixir_exe when is_binary(elixir_exe) <- System.find_executable("elixir") do
114+
elixir_exe when is_binary(elixir_exe) <- use_or_find_elixir_exec(opts) do
115115
exe =
116116
dir
117117
|> Path.join("cmd")
@@ -348,4 +348,16 @@ defmodule NextLS.Runtime do
348348
true
349349
end
350350
end
351+
352+
defp use_or_find_elixir_exec(opts) do
353+
with path when is_binary(path) <- opts[:elixir_exec],
354+
exec = Path.expand(path),
355+
true <- File.exists?(exec),
356+
{_, 0} <- System.cmd(exec, ["--version"]) do
357+
exec
358+
else
359+
_ ->
360+
System.find_executable("elixir")
361+
end
362+
end
351363
end

test/next_ls/runtime_test.exs

+31
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,37 @@ defmodule NextLs.RuntimeTest do
253253
end
254254
end
255255

256+
test "supports using custom elixir_exec path", %{logger: logger, cwd: cwd, on_init: on_init} do
257+
start_supervised!({Registry, keys: :duplicate, name: RuntimeTest.Registry})
258+
tvisor = start_supervised!(Task.Supervisor)
259+
260+
# Create local Elixir shim
261+
elixir_exec = Path.join(cwd, "elixir")
262+
File.ln_s!(System.find_executable("elixir"), elixir_exec)
263+
assert {_, 0} = System.cmd(elixir_exec, ["--version"])
264+
265+
pid =
266+
start_supervised!(
267+
{Runtime,
268+
name: "my_proj",
269+
on_initialized: on_init,
270+
task_supervisor: tvisor,
271+
working_dir: cwd,
272+
uri: "file://#{cwd}",
273+
parent: self(),
274+
logger: logger,
275+
db: :some_db,
276+
mix_env: "dev",
277+
mix_target: "host",
278+
elixir_exec: elixir_exec,
279+
registry: RuntimeTest.Registry}
280+
)
281+
282+
Process.link(pid)
283+
284+
assert_receive :ready
285+
end
286+
256287
defp flush_messages do
257288
receive do
258289
_ -> flush_messages()

0 commit comments

Comments
 (0)