Current section

20 Versions

Jump to

Compare versions

6 files changed
+143 additions
-40 deletions
  @@ -9,7 +9,7 @@ In order to install it via hex, add the reference to this package into the `deps
9 9 ```elixir
10 10 defp deps do
11 11 [
12 - {:apex, "~>0.5.2"}
12 + {:apex, "~>0.6.0"}
13 13 ]
14 14 end
15 15 ```
  @@ -64,8 +64,46 @@ If the numbering is not for you, you can turn it off via `Apex.ap(data, numbers:
64 64
65 65 `Apex` uses a protocol internally to format a given value. If there's something not yet in the box, you can extend the protocol `Apex.Format`.
66 66
67 + ### Color customizations
68 + You can customize the `Apex` colors on a per project or global basis. For project
69 + specific color configuration, you can specify the color table in your `config/config.ex`
70 +
71 + ```elixir
72 + use Mix.Config
73 +
74 + config :apex, :colors, %{
75 + binary: :red
76 + }
77 + ```
78 +
79 + This can alternatively also be done at runtime by using the `Application.put_env/3` function.
80 +
81 + Please note, that you only have to specify the colors you actively want to change here. For
82 + the rest `Apex` will fallback to the defaults.
83 +
84 + If you want to apply the same settings across multiple elixir projects, you can drop a `.apexrc`
85 + file into your home directory in order do the same thing. The configuration is an `Elixir` Map.
86 +
87 + ```elixir
88 + %{
89 + colors: %{
90 + binary: :yellow,
91 + true: [:green, :bright]
92 + }
93 + }
94 + ```
95 +
96 + __IMPORTANT:__ the global configuration will get compiled into your `Apex` version when
97 + you compile your app. You need to recompile `Apex` via `mix deps.compile apex` when
98 + you want to apply changes to the `.apexrc` file.
99 +
100 + __PRECEDENCE:__ When both project specific and global configuration
101 + are present, project specific configuration will take precedence.
102 +
103 + For a full list of all available customizations, please take a look at the result of `Apex.Format.Color.default_colors/0)`.
104 +
67 105 ### Awesome def aka adef
68 - Inspired by [@sasajuric](https://github.com/sasa1977)'s [awesome blog post series about macros](http://www.theerlangelist.com/search/label/metaprogramming), Apex also contains an Apex flavored version of his `deftracable` macro. By using `adef` instead of `def`
106 + Inspired by [@sasajuric](https://github.com/sasa1977)'s [awesome blog post series about macros](http://www.theerlangelist.com/search/label/metaprogramming), Apex also contains an Apex flavored version of his `deftracable` macro. By using `adef` instead of `def`
69 107
70 108 ```elixir
71 109 import Apex.AwesomeDef
  @@ -101,7 +139,7 @@ Result:
101 139 * Add tests for it, making sure $ mix test is all green.
102 140 * Do not rebase other commits than your own
103 141 * Do not change the version in the mix file
104 - * Commit
142 + * Commit
105 143 * Send me a pull request
106 144
107 145 ### License ###
  @@ -12,4 +12,4 @@
12 12 {<<"maintainers">>,[<<"Bjoern Rochel">>]}.
13 13 {<<"name">>,<<"apex">>}.
14 14 {<<"requirements">>,[]}.
15 - {<<"version">>,<<"0.5.2">>}.
15 + {<<"version">>,<<"0.6.0">>}.
  @@ -1,6 +1,5 @@
1 1 defmodule Apex.AwesomeDef do
2 2 import Apex.Format.Utils
3 - import Apex.Format.Color
4 3
5 4 defmacro adef(head, body) do
6 5 {fun_name, args_ast} = name_and_args(head)
  @@ -1,30 +1,95 @@
1 1 defmodule Apex.Format.Color do
2 - def colorize(text, data, options \\ []) do
3 - cond do
4 - options[:color] == false -> text
5 - color = color(data) -> escape(text, color)
6 - true -> text
2 + def id(data)
3 + def id(data) when is_binary(data), do: {:ok, :binary}
4 + def id(data) when is_tuple(data), do: {:ok, :tuple}
5 + def id(data) when data in [true, false, nil], do: {:ok, data}
6 + def id(data) when is_atom(data), do: {:ok, :atom}
7 + def id(data) when is_float(data), do: {:ok, :float}
8 + def id(data) when is_integer(data), do: {:ok, :integer}
9 + def id(data) when is_function(data), do: {:ok, :function}
10 + def id(data) when is_list(data), do: {:ok, :list}
11 + def id(data) when is_pid(data), do: {:ok, :pid}
12 + def id(data) when is_port(data), do: {:ok, :port}
13 + def id({Range, _, _}), do: {:ok, :range}
14 + def id({HashSet, _, _}), do: {:ok, :hash_set}
15 + def id({HashDict, _, _}), do: {:ok, :hash_dict}
16 + def id(_), do: :unknown
17 +
18 + @default_colors %{
19 + binary: :yellow,
20 + tuple: :blue,
21 + true: [:green, :bright],
22 + false: [:red, :bright],
23 + nil: :red,
24 + atom: :cyan,
25 + float: :blue,
26 + integer: :blue,
27 + function: :magenta,
28 + list: :white,
29 + pid: :yellow,
30 + port: [:green, :bright],
31 + range: :green,
32 + hash_set: :white,
33 + hash_dict: :white
34 + }
35 +
36 + def default_colors do
37 + @default_colors
38 + end
39 +
40 + def default_color(id) do
41 + Map.get(default_colors, id)
42 + end
43 +
44 + def customization_file do
45 + Path.expand("~/.apexrc")
46 + end
47 +
48 + def load_color_customizations_from_apexrc do
49 + with {:ok, contents } <- File.read(customization_file),
50 + {%{colors: colors}, _} when is_map(colors) <- Code.eval_string(contents, [], __ENV__) do
51 + colors
52 + else
53 + _ -> %{}
54 + end
55 + end
56 +
57 + defmacro __using__(_) do
58 + user_defined_colors_from_apexrc = __MODULE__.load_color_customizations_from_apexrc
59 +
60 + quote do
61 + import unquote(__MODULE__)
62 +
63 + def colorize(text, data, opts \\ []) do
64 + data
65 + |> id
66 + |> do_colorize(text, opts[:color])
67 + end
68 +
69 + def escape(text, color) do
70 + [color, text]
71 + |> IO.ANSI.format(true)
72 + |> IO.chardata_to_string
73 + end
74 +
75 + defp do_colorize(id, text, should_color)
76 + defp do_colorize(_id, text, false), do: text
77 + defp do_colorize(:unknown, text, _), do: text
78 + defp do_colorize({:ok, id}, text, _) do
79 + color = user_defined_color_app_config(id) || user_defined_color_apexrc(id) || default_color(id)
80 + escape(text, color)
81 + end
82 +
83 + @user_defined_colors_from_apexrc unquote(Macro.escape(user_defined_colors_from_apexrc))
84 + defp user_defined_color_apexrc(id) do
85 + Map.get(@user_defined_colors_from_apexrc, id)
86 + end
87 +
88 + defp user_defined_color_app_config(id) do
89 + :apex
90 + |> Application.get_env(:colors, %{})
91 + |> Map.get(id)
92 + end
7 93 end
8 94 end
9 -
10 - def escape(text, color) do
11 - IO.ANSI.format([color, text], true) |> IO.chardata_to_string
12 - end
13 -
14 - defp color(data) when is_binary(data), do: :yellow
15 - defp color(data) when is_tuple(data), do: :blue
16 - defp color(true), do: [:green, :bright]
17 - defp color(false), do: [:red, :bright]
18 - defp color(nil), do: :red
19 - defp color(data) when is_atom(data), do: :cyan
20 - defp color(data) when is_float(data), do: :blue
21 - defp color(data) when is_integer(data), do: :blue
22 - defp color(data) when is_function(data), do: :magenta
23 - defp color(data) when is_list(data), do: :white
24 - defp color(data) when is_pid(data), do: :yellow
25 - defp color(data) when is_port(data), do: [:green, :bright]
26 - defp color({Range, _, _}), do: :green
27 - defp color({HashSet, _, _}), do: :white
28 - defp color({HashDict, _, _}), do: :white
29 - defp color(_), do: nil
30 95 end
  @@ -1,20 +1,19 @@
1 1 defmodule Apex.Format.Utils do
2 + use Apex.Format.Color
3 +
2 4 @default_indent 2
3 5 @default_level 0
4 6
5 7 def new_line, do: "\n"
6 8
7 - def colorize(str, data, options \\ []) do
8 - Apex.Format.Color.colorize(str, data, options)
9 - end
10 -
11 9 def separator_line(str, length \\ 100) do
12 - String.duplicate(str, length)
13 - |> Apex.Format.Color.escape(:yellow)
10 + str
11 + |> String.duplicate(length)
12 + |> escape(:yellow)
14 13 end
15 14
16 15 def next_indent_level(options) do
17 - Keyword.update(options, :indent_level, 1, &( &1 + 1))
16 + Keyword.update(options, :indent_level, 1, &(&1 + 1))
18 17 end
19 18
20 19 def indent(options) do
Loading more files…