diff --git a/apps/debug_adapter/lib/debug_adapter/protocol.ex b/apps/debug_adapter/lib/debug_adapter/protocol.ex index e1c25cae1..cecca5b94 100644 --- a/apps/debug_adapter/lib/debug_adapter/protocol.ex +++ b/apps/debug_adapter/lib/debug_adapter/protocol.ex @@ -38,6 +38,12 @@ defmodule ElixirLS.DebugAdapter.Protocol do end end + defmacro source_req(seq, args) do + quote do + request(unquote(seq), "source", unquote(args)) + end + end + defmacro set_breakpoints_req(seq, source, breakpoints) do quote do request(unquote(seq), "setBreakpoints", %{ diff --git a/apps/debug_adapter/lib/debug_adapter/server.ex b/apps/debug_adapter/lib/debug_adapter/server.ex index 0e00c6682..2e0af4f85 100644 --- a/apps/debug_adapter/lib/debug_adapter/server.ex +++ b/apps/debug_adapter/lib/debug_adapter/server.ex @@ -885,6 +885,24 @@ defmodule ElixirLS.DebugAdapter.Server do {%{}, %{state | config: config}} end + defp handle_request( + source_req(_, args), + state = %__MODULE__{} + ) do + path = args["source"]["path"] + + content = + if path == "replinput" do + # this is a special path that VSCode uses for debugger console + # return an empty string as we do not need anything there + "" + else + File.read!(path) + end + + {%{"content" => content}, state} + end + defp handle_request( set_breakpoints_req(_, %{"path" => _path}, _breakpoints), %__MODULE__{config: %{"noDebug" => true}} diff --git a/apps/debug_adapter/test/debugger_test.exs b/apps/debug_adapter/test/debugger_test.exs index 24692cc74..6dc5395c4 100644 --- a/apps/debug_adapter/test/debugger_test.exs +++ b/apps/debug_adapter/test/debugger_test.exs @@ -3865,4 +3865,43 @@ defmodule ElixirLS.DebugAdapter.ServerTest do assert Process.alive?(server) end) end + + test "source", %{server: server} do + in_fixture(__DIR__, "mix_project", fn -> + Server.receive_packet(server, initialize_req(1, %{})) + assert_receive(response(_, 1, "initialize", _)) + + Server.receive_packet( + server, + %{ + "arguments" => %{ + "sourceReference" => 0, + "source" => %{"path" => "lib/crash.ex"} + }, + "command" => "source", + "seq" => 1, + "type" => "request" + } + ) + + assert_receive(%{"body" => %{"content" => "defmodule MixProject.Crash do" <> _}}, 10000) + + Server.receive_packet( + server, + %{ + "arguments" => %{ + "sourceReference" => 0, + "source" => %{"path" => "replinput"} + }, + "command" => "source", + "seq" => 1, + "type" => "request" + } + ) + + assert_receive(%{"body" => %{"content" => ""}}, 10000) + + assert Process.alive?(server) + end) + end end