Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ defmodule ElixirLS.LanguageServer.Providers.ExecuteCommand.ApplySpec do
formatted =
try do
target_line_length =
case SourceFile.formatter_opts(uri) do
{:ok, opts} -> Keyword.get(opts, :line_length, @default_target_line_length)
case SourceFile.formatter_for(uri) do
{:ok, {_, opts}} -> Keyword.get(opts, :line_length, @default_target_line_length)
:error -> @default_target_line_length
end

Expand Down Expand Up @@ -94,3 +94,4 @@ defmodule ElixirLS.LanguageServer.Providers.ExecuteCommand.ApplySpec do
end
end
end

24 changes: 21 additions & 3 deletions apps/language_server/lib/language_server/providers/formatting.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@ defmodule ElixirLS.LanguageServer.Providers.Formatting do

def format(%SourceFile{} = source_file, uri, project_dir) when is_binary(project_dir) do
if can_format?(uri, project_dir) do
case SourceFile.formatter_opts(uri) do
case SourceFile.formatter_for(uri) do
{:ok, {formatter, opts}} ->
if should_format?(uri, project_dir, opts[:inputs]) do
do_format(source_file, formatter, opts)
else
{:ok, []}
end

{:ok, opts} ->
if should_format?(uri, project_dir, opts[:inputs]) do
do_format(source_file, opts)
Expand All @@ -29,8 +36,11 @@ defmodule ElixirLS.LanguageServer.Providers.Formatting do
do_format(source_file)
end

defp do_format(%SourceFile{text: text}, opts \\ []) do
formatted = IO.iodata_to_binary([Code.format_string!(text, opts), ?\n])

defp do_format(%SourceFile{} = source_file, opts \\ []), do: do_format(source_file, nil, opts)

defp do_format(%SourceFile{text: text}, formatter, opts) do
formatted = get_formatted(text, formatter, opts)

response =
text
Expand All @@ -43,6 +53,14 @@ defmodule ElixirLS.LanguageServer.Providers.Formatting do
{:error, :internal_error, "Unable to format due to syntax error"}
end

defp get_formatted(text, formatter, _) when is_function(formatter) do
formatter.(text)
end

defp get_formatted(text, _, opts) do
IO.iodata_to_binary([Code.format_string!(text, opts), ?\n])
end

# If in an umbrella project, the cwd might be set to a sub-app if it's being compiled. This is
# fine if the file we're trying to format is in that app. Otherwise, we return an error.
defp can_format?(file_uri = "file:" <> _, project_dir) do
Expand Down
5 changes: 3 additions & 2 deletions apps/language_server/lib/language_server/server.ex
Original file line number Diff line number Diff line change
Expand Up @@ -670,8 +670,8 @@ defmodule ElixirLS.LanguageServer.Server do
!!get_in(state.client_capabilities, ["textDocument", "signatureHelp"])

locals_without_parens =
case SourceFile.formatter_opts(uri) do
{:ok, opts} -> Keyword.get(opts, :locals_without_parens, [])
case SourceFile.formatter_for(uri) do
{:ok, {_, opts}} -> Keyword.get(opts, :locals_without_parens, [])
:error -> []
end
|> MapSet.new()
Expand Down Expand Up @@ -1258,3 +1258,4 @@ defmodule ElixirLS.LanguageServer.Server do
end)
end
end

17 changes: 9 additions & 8 deletions apps/language_server/lib/language_server/source_file.ex
Original file line number Diff line number Diff line change
Expand Up @@ -334,16 +334,16 @@ defmodule ElixirLS.LanguageServer.SourceFile do
"""
end

@spec formatter_opts(String.t()) :: {:ok, keyword()} | :error
def formatter_opts(uri = "file:" <> _) do
@spec formatter_for(String.t()) :: {:ok, keyword()} | :error
def formatter_for(uri = "file:" <> _) do
path = path_from_uri(uri)

try do
opts =
path
|> Mix.Tasks.Format.formatter_opts_for_file()

{:ok, opts}
if function_exported?(Mix.Tasks.Format, :formatter_for_file, 1) do
{:ok, Mix.Tasks.Format.formatter_for_file(path)}
else
{:ok, {nil, Mix.Tasks.Format.formatter_opts_for_file(path)}}
end
rescue
e ->
IO.warn(
Expand All @@ -354,7 +354,7 @@ defmodule ElixirLS.LanguageServer.SourceFile do
end
end

def formatter_opts(_), do: :error
def formatter_for(_), do: :error

defp format_code(code, opts) do
try do
Expand Down Expand Up @@ -431,3 +431,4 @@ defmodule ElixirLS.LanguageServer.SourceFile do
{elixir_line - 1, utf16_character}
end
end