Skip to content

Commit 58ca340

Browse files
author
José Valim
committed
Deprecate IO.ANSI.terminal? and tidy up colors
1 parent a592661 commit 58ca340

File tree

17 files changed

+51
-40
lines changed

17 files changed

+51
-40
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
* Deprecations
2323
* [IEx] IEx color configuration expects a list of atoms instead of a string with colors separated by comma
2424
* [Inspect] `Inspect.Algebra.pretty/2` is deprecated in favor of `Inspect.Algebra.format/2` that instead returns iodata. This function was used only by documentation examples and it is unlikely to affect actual code
25+
* [IO] `IO.ANSI.terminal?` is deprecated in favor of `IO.ANSI.enabled?`
2526
* [IO] `IO.ANSI.escape/2` and `IO.ANSI.escape_fragment/2` is deprecated in favor of `IO.ANSI.format/2` and `IO.ANSI.format_fragment/2`
2627
* [Kernel] Leading `0` for octals is deprecated in favor of `0o`
2728
* [Kernel] `0X` for hexadecimals is deprecated in favor of `0x`

lib/elixir/lib/io/ansi.ex

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,27 @@ defmodule IO.ANSI do
3232
@typep ansilist :: maybe_improper_list(char() | ansicode() | binary() | ansilist(), binary() | ansicode() | [])
3333
@type ansidata :: ansilist() | ansicode() | binary()
3434

35-
@doc """
36-
Checks whether the default I/O device is a terminal or a file.
37-
38-
Used to identify whether printing ANSI escape sequences will likely
39-
be displayed as intended. This is checked by sending a message to
40-
the group leader. In case the group leader does not support the message,
41-
it will likely lead to a timeout (and a slow down on execution time).
42-
"""
43-
@spec terminal? :: boolean
44-
@spec terminal?(:io.device) :: boolean
35+
@doc false
4536
def terminal?(device \\ :erlang.group_leader) do
4637
!match?({:win32, _}, :os.type()) and
4738
match?({:ok, _}, :io.columns(device))
4839
end
4940

41+
@doc """
42+
Checks if ANSI coloring is supported and enabled on this machine.
43+
44+
By default, ANSI is only enabled on UNIX machines. Enabling or
45+
disabling ANSI escapes can be done by configuring the
46+
`:ansi_enabled` value in the `:elixir` application.
47+
"""
48+
@spec enabled? :: boolean
49+
def enabled? do
50+
case Application.fetch_env(:elixir, :ansi_enabled) do
51+
{:ok, boolean} when is_boolean(boolean) -> boolean
52+
:error -> !match?({:win32, _}, :os.type())
53+
end
54+
end
55+
5056
@doc "Resets all attributes"
5157
defsequence :reset, 0
5258

@@ -157,16 +163,15 @@ defmodule IO.ANSI do
157163
158164
An optional boolean parameter can be passed to enable or disable
159165
emitting actual ANSI codes. When `false`, no ANSI codes will emitted.
160-
By default, standard output will be checked if it is a terminal capable
161-
of handling these sequences (using `terminal?/1` function)
166+
By default checks if ANSI is enabled using the `enabled?/0` function.
162167
163168
## Examples
164169
165170
iex> IO.ANSI.format(["Hello, ", :red, :bright, "world!"], true)
166171
[[[[[[], "Hello, "] | "\e[31m"] | "\e[1m"], "world!"] | "\e[0m"]
167172
168173
"""
169-
def format(chardata, emit \\ terminal?) when is_boolean(emit) do
174+
def format(chardata, emit \\ enabled?) when is_boolean(emit) do
170175
do_format(chardata, [], [], emit, :maybe)
171176
end
172177

@@ -178,16 +183,15 @@ defmodule IO.ANSI do
178183
179184
An optional boolean parameter can be passed to enable or disable
180185
emitting actual ANSI codes. When `false`, no ANSI codes will emitted.
181-
By default, standard output will be checked if it is a terminal capable
182-
of handling these sequences (using `terminal?/1` function)
186+
By default checks if ANSI is enabled using the `enabled?/0` function.
183187
184188
## Examples
185189
186190
iex> IO.ANSI.format_fragment([:bright, 'Word'], true)
187191
[[[[[[] | "\e[1m"], 87], 111], 114], 100]
188192
189193
"""
190-
def format_fragment(chardata, emit \\ terminal?) when is_boolean(emit) do
194+
def format_fragment(chardata, emit \\ enabled?) when is_boolean(emit) do
191195
do_format(chardata, [], [], emit, false)
192196
end
193197

lib/elixir/lib/io/ansi/docs.ex

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ defmodule IO.ANSI.Docs do
2121
comma-separated ANSI values.
2222
"""
2323
def default_options do
24-
[doc_code: [:cyan, :bright],
24+
[enabled: true,
25+
doc_code: [:cyan, :bright],
2526
doc_inline_code: [:cyan],
2627
doc_headings: [:yellow, :bright],
2728
doc_title: [:reverse, :yellow, :bright],
@@ -374,6 +375,6 @@ defmodule IO.ANSI.Docs do
374375
"they now must be a list of atoms, got #{inspect color} for #{inspect style}"
375376
color = String.split(color, ",") |> Enum.map(&String.to_atom/1)
376377
end
377-
IO.ANSI.format_fragment(color, true)
378+
IO.ANSI.format_fragment(color, !!colors[:enabled])
378379
end
379380
end

lib/elixir/src/elixir_dispatch.erl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,5 +527,7 @@ deprecation('Elixir.IO.ANSI', 'escape', _) ->
527527
"use the new API in IO.ANSI.format/2 instead";
528528
deprecation('Elixir.IO.ANSI', 'escape_fragment', _) ->
529529
"use the new API in IO.ANSI.format_fragment/2 instead";
530+
deprecation('Elixir.IO.ANSI', 'terminal?', _) ->
531+
"use IO.ANSI.enabled?/0 instead";
530532
deprecation(_, _, _) ->
531533
false.

lib/ex_unit/lib/ex_unit.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,8 @@ defmodule ExUnit do
158158
159159
ExUnit supports the following options:
160160
161-
* `:color` - when color should be used by specific formatters;
162-
defaults to the result of `IO.ANSI.terminal?/1`
161+
* `:colors` - a keyword list of colors to be used by some formatters.
162+
The only option so far is `[enabled: boolean]` which defaults to `IO.ANSI.enabled?/1`
163163
164164
* `:formatters` - the formatters that will print results;
165165
defaults to `[ExUnit.CLIFormatter]`

lib/ex_unit/lib/ex_unit/cli_formatter.ex

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ defmodule ExUnit.CLIFormatter do
1313
config = %{
1414
seed: opts[:seed],
1515
trace: opts[:trace],
16-
color: opts[:color],
16+
colors: Keyword.put_new(opts[:colors], :enabled, IO.ANSI.enabled?),
1717
width: get_terminal_width(),
1818
tests_counter: 0,
1919
failures_counter: 0,
@@ -166,10 +166,11 @@ defmodule ExUnit.CLIFormatter do
166166

167167
# Color styles
168168

169-
defp colorize(escape, string, %{color: color}) do
170-
[IO.ANSI.format_fragment(escape, color),
169+
defp colorize(escape, string, %{colors: colors}) do
170+
enabled = colors[:enabled]
171+
[IO.ANSI.format_fragment(escape, enabled),
171172
string,
172-
IO.ANSI.format_fragment(:reset, color)] |> IO.iodata_to_binary
173+
IO.ANSI.format_fragment(:reset, enabled)] |> IO.iodata_to_binary
173174
end
174175

175176
defp success(msg, config) do

lib/ex_unit/lib/ex_unit/runner.ex

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ defmodule ExUnit.Runner do
4646
opts
4747
|> Keyword.put(:exclude, exclude)
4848
|> Keyword.put(:include, include)
49-
|> Keyword.put_new(:color, IO.ANSI.terminal?)
5049
|> Keyword.put_new(:max_cases, :erlang.system_info(:schedulers_online))
5150
|> Keyword.put_new(:seed, :erlang.now |> elem(2))
5251
end

lib/ex_unit/mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ defmodule ExUnit.Mixfile do
1313
env: [
1414
# Calculated on demand
1515
# max_cases: :erlang.system_info(:schedulers_online),
16-
# color: IO.ANSI.terminal?,
1716
# seed: rand(),
1817

1918
autorun: true,
19+
colors: [],
2020
trace: false,
2121
formatters: [ExUnit.CLIFormatter],
2222
include: [],

lib/ex_unit/test/ex_unit/doc_test_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ defmodule ExUnit.DocTestTest do
204204
doctest ExUnit.DocTestTest.Invalid
205205
end
206206

207-
ExUnit.configure(seed: 0)
207+
ExUnit.configure(seed: 0, colors: [enabled: false])
208208
output = capture_io(fn -> ExUnit.run end)
209209

210210
assert output =~ """

lib/iex/lib/iex.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -473,8 +473,8 @@ defmodule IEx do
473473
{:ok, _} = Application.ensure_all_started(:iex)
474474
Application.put_env(:iex, :started, true)
475475

476-
colors = [enabled: IO.ANSI.terminal?] ++
477-
Application.get_env(:iex, :colors)
476+
colors = Application.get_env(:iex, :colors)
477+
|> Keyword.put_new(:enabled, IO.ANSI.enabled?)
478478
Application.put_env(:iex, :colors, colors)
479479
end
480480

0 commit comments

Comments
 (0)