Skip to content

Commit ae16051

Browse files
authored
Do not crash if unable to get formatter options (#319)
Fixes #318
1 parent 767e174 commit ae16051

File tree

4 files changed

+41
-23
lines changed

4 files changed

+41
-23
lines changed

apps/language_server/lib/language_server/providers/execute_command.ex

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ defmodule ElixirLS.LanguageServer.Providers.ExecuteCommand do
66
alias ElixirLS.LanguageServer.{JsonRpc, SourceFile}
77
import ElixirLS.LanguageServer.Protocol
88

9+
@default_target_line_length 98
10+
911
def execute("spec:" <> _, args, source_files) do
1012
[
1113
%{
@@ -47,9 +49,10 @@ defmodule ElixirLS.LanguageServer.Providers.ExecuteCommand do
4749
formatted =
4850
try do
4951
target_line_length =
50-
uri
51-
|> SourceFile.formatter_opts()
52-
|> Keyword.get(:line_length, 98)
52+
case SourceFile.formatter_opts(uri) do
53+
{:ok, opts} -> Keyword.get(opts, :line_length, @default_target_line_length)
54+
:error -> @default_target_line_length
55+
end
5356

5457
target_line_length = target_line_length - String.length(indentation)
5558

apps/language_server/lib/language_server/providers/formatting.ex

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,23 @@ defmodule ElixirLS.LanguageServer.Providers.Formatting do
88

99
def format(source_file, uri, project_dir) do
1010
if can_format?(uri, project_dir) do
11-
opts = SourceFile.formatter_opts(uri)
12-
13-
if should_format?(uri, project_dir, opts[:inputs]) do
14-
formatted = IO.iodata_to_binary([Code.format_string!(source_file.text, opts), ?\n])
15-
16-
response =
17-
source_file.text
18-
|> String.myers_difference(formatted)
19-
|> myers_diff_to_text_edits()
20-
21-
{:ok, response}
22-
else
23-
{:ok, []}
11+
case SourceFile.formatter_opts(uri) do
12+
{:ok, opts} ->
13+
if should_format?(uri, project_dir, opts[:inputs]) do
14+
formatted = IO.iodata_to_binary([Code.format_string!(source_file.text, opts), ?\n])
15+
16+
response =
17+
source_file.text
18+
|> String.myers_difference(formatted)
19+
|> myers_diff_to_text_edits()
20+
21+
{:ok, response}
22+
else
23+
{:ok, []}
24+
end
25+
26+
:error ->
27+
{:error, :internal_error, "Unable to fetch formatter options"}
2428
end
2529
else
2630
msg =

apps/language_server/lib/language_server/server.ex

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -483,9 +483,10 @@ defmodule ElixirLS.LanguageServer.Server do
483483
!!get_in(state.client_capabilities, ["textDocument", "signatureHelp"])
484484

485485
locals_without_parens =
486-
uri
487-
|> SourceFile.formatter_opts()
488-
|> Keyword.get(:locals_without_parens, [])
486+
case SourceFile.formatter_opts(uri) do
487+
{:ok, opts} -> Keyword.get(opts, :locals_without_parens, [])
488+
:error -> []
489+
end
489490
|> MapSet.new()
490491

491492
fun = fn ->

apps/language_server/lib/language_server/source_file.ex

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,11 +211,21 @@ defmodule ElixirLS.LanguageServer.SourceFile do
211211
"""
212212
end
213213

214-
@spec formatter_opts(String.t()) :: keyword()
214+
@spec formatter_opts(String.t()) :: {:ok, keyword()} | :error
215215
def formatter_opts(uri) do
216-
uri
217-
|> path_from_uri()
218-
|> Mix.Tasks.Format.formatter_opts_for_file()
216+
path = path_from_uri(uri)
217+
218+
try do
219+
opts =
220+
path
221+
|> Mix.Tasks.Format.formatter_opts_for_file()
222+
223+
{:ok, opts}
224+
rescue
225+
e in Mix.Error ->
226+
IO.warn("Unable to get formatter options for #{path}: #{e.message}")
227+
:error
228+
end
219229
end
220230

221231
defp format_code(code, opts) do

0 commit comments

Comments
 (0)