@@ -83,7 +83,7 @@ defmodule IEx.Helpers do
8383 Shows the documentation for IEx.Helpers.
8484 """
8585 def h ( ) do
86- h ( IEx.Helpers , [ ] )
86+ __help__ ( IEx.Helpers )
8787 end
8888
8989 @ doc """
@@ -105,73 +105,37 @@ defmodule IEx.Helpers do
105105 """
106106 defmacro h ( { :/ , _ , [ { { :. , _ , [ mod , fun ] } , _ , [ ] } , arity ] } ) do
107107 quote do
108- h ( unquote ( mod ) , unquote ( fun ) , unquote ( arity ) )
108+ IEx.Helpers . __help__ ( unquote ( mod ) , unquote ( fun ) , unquote ( arity ) )
109109 end
110110 end
111111
112112 defmacro h ( { { :. , _ , [ mod , fun ] } , _ , [ ] } ) do
113113 quote do
114- h ( unquote ( mod ) , unquote ( fun ) )
114+ IEx.Helpers . __help__ ( unquote ( mod ) , unquote ( fun ) )
115115 end
116116 end
117117
118118 defmacro h ( { :/ , _ , [ { fun , _ , args } , arity ] } ) when args == [ ] or is_atom ( args ) do
119119 quote do
120- h ( unquote ( fun ) , unquote ( arity ) )
120+ IEx.Helpers . __help__ ( unquote ( fun ) , unquote ( arity ) )
121121 end
122122 end
123123
124124 defmacro h ( { name , _ , args } ) when args == [ ] or is_atom ( args ) do
125125 quote do
126- candidates = [ unquote ( __MODULE__ ) , Kernel , Kernel.SpecialForms ]
127-
128- # If we got at least one :ok, final result will be :ok
129- Enum . reduce candidates , :not_found , fn ( mod , flag ) ->
130- ret = h ( mod , unquote ( name ) )
131- if flag == :ok do
132- :ok
133- else
134- ret
135- end
136- end
126+ IEx.Helpers . __help__ ( [ unquote ( __MODULE__ ) , Kernel , Kernel.SpecialForms ] , unquote ( name ) )
137127 end
138128 end
139129
140130 defmacro h ( other ) do
141131 quote do
142- h ( unquote ( other ) , [ ] )
143- end
144- end
145-
146- defmacrop mfa_exported? ( module , function , arity ) do
147- quote do
148- function_exported? ( unquote ( module ) , unquote ( function ) , unquote ( arity ) ) or
149- macro_exported? ( unquote ( module ) , unquote ( function ) , unquote ( arity ) )
150- end
151- end
152-
153- defp h_kernel ( function , arity ) do
154- if mfa_exported? ( Kernel , function , arity ) do
155- h ( Kernel , function , arity )
156- else
157- h ( Kernel.SpecialForms , function , arity )
132+ IEx.Helpers . __help__ ( unquote ( other ) )
158133 end
159134 end
160135
136+ # Handles documentation for modules
161137 @ doc false
162- def h ( :h , 1 ) do
163- h ( __MODULE__ , :h , 1 )
164- end
165-
166- def h ( function , arity ) when is_atom ( function ) and is_integer ( arity ) do
167- if mfa_exported? ( __MODULE__ , function , arity ) do
168- h ( __MODULE__ , function , arity )
169- else
170- h_kernel ( function , arity )
171- end
172- end
173-
174- def h ( module , [ ] ) when is_atom ( module ) do
138+ def __help__ ( module ) when is_atom ( module ) do
175139 case Code . ensure_loaded ( module ) do
176140 { :module , _ } ->
177141 case module . __info__ ( :moduledoc ) do
@@ -188,46 +152,118 @@ defmodule IEx.Helpers do
188152 end
189153 end
190154
191- def h ( module , function ) when is_atom ( module ) and is_atom ( function ) do
192- result = lc { { f , arity } , _line , _type , _args , doc } in list module . __info__ ( :docs ) ,
193- f == function and doc != false do
194- h ( module , function , arity )
195- IO . puts ""
155+ def __help__ ( _ ) do
156+ IO . puts IO.ANSI . escape ( "%{red}Invalid arguments for h helper" )
157+ end
158+
159+ # Help for function+arity or module+function
160+ @ doc false
161+ def __help__ ( modules , function ) when is_list ( modules ) and is_atom ( function ) do
162+ result =
163+ Enum . reduce modules , :not_found , fn
164+ module , :not_found -> help_mod_fun ( module , function )
165+ _module , acc -> acc
166+ end
167+
168+ unless result == :ok , do:
169+ IO . puts IO.ANSI . escape ( "%{red}No docs for #{ function } have been found" )
170+
171+ :ok
172+ end
173+
174+ def __help__ ( module , function ) when is_atom ( module ) and is_atom ( function ) do
175+ case help_mod_fun ( module , function ) do
176+ :ok ->
177+ :ok
178+ :no_docs ->
179+ IO . puts IO.ANSI . escape ( "%{red}#{ inspect module } was not compiled with docs" )
180+ :not_found ->
181+ IO . puts IO.ANSI . escape ( "%{red}No docs for #{ inspect module } .#{ function } have been found" )
196182 end
197- if result != [ ] do
198- :ok
183+
184+ :ok
185+ end
186+
187+ def __help__ ( function , arity ) when is_atom ( function ) and is_integer ( arity ) do
188+ __help__ ( [ __MODULE__ , Kernel , Kernel.SpecialForms ] , function , arity )
189+ end
190+
191+ def __help__ ( _ , _ ) do
192+ IO . puts IO.ANSI . escape ( "%{red}Invalid arguments for h helper" )
193+ end
194+
195+ defp help_mod_fun ( mod , fun ) when is_atom ( mod ) and is_atom ( fun ) do
196+ if docs = mod . __info__ ( :docs ) do
197+ result = lc { { f , arity } , _line , _type , _args , doc } in list docs , fun == f , doc != false do
198+ __help__ ( mod , fun , arity )
199+ IO . puts ""
200+ end
201+
202+ if result != [ ] , do: :ok , else: :not_found
199203 else
200- :not_found
204+ :no_docs
201205 end
202206 end
203207
204- def h ( _ , _ ) do
205- IO . puts IO.ANSI . escape ( "%{red}Invalid h helper argument" )
206- h ( )
208+ # Help for module+function+arity
209+ @ doc false
210+ def __help__ ( modules , function , arity ) when is_list ( modules ) and is_atom ( function ) and is_integer ( arity ) do
211+ result =
212+ Enum . reduce modules , :not_found , fn
213+ module , :not_found -> help_mod_fun_arity ( module , function , arity )
214+ _module , acc -> acc
215+ end
216+
217+ unless result == :ok , do:
218+ IO . puts IO.ANSI . escape ( "%{red}No docs for #{ function } /#{ arity } have been found" )
219+
220+ :ok
207221 end
208222
209- @ doc false
210- def h ( module , function , arity ) when is_atom ( module ) and is_atom ( function ) and is_integer ( arity ) do
211- if docs = module . __info__ ( :docs ) do
223+ def __help__ ( module , function , arity ) when is_atom ( module ) and is_atom ( function ) and is_integer ( arity ) do
224+ case help_mod_fun_arity ( module , function , arity ) do
225+ :ok ->
226+ :ok
227+ :no_docs ->
228+ IO . puts IO.ANSI . escape ( "%{red}#{ inspect module } was not compiled with docs" )
229+ :not_found ->
230+ IO . puts IO.ANSI . escape ( "%{red}No docs for #{ inspect module } .#{ function } /#{ arity } have been found" )
231+ end
232+
233+ :ok
234+ end
235+
236+ def __help__ ( _ , _ , _ ) do
237+ IO . puts IO.ANSI . escape ( "%{red}Invalid arguments for h helper" )
238+ end
239+
240+ defp help_mod_fun_arity ( mod , fun , arity ) when is_atom ( mod ) and is_atom ( fun ) and is_integer ( arity ) do
241+ if docs = mod . __info__ ( :docs ) do
212242 doc =
213243 cond do
214- d = find_doc ( docs , function , arity ) -> d
215- d = find_default_doc ( docs , function , arity ) -> d
216- true -> nil
244+ d = find_doc ( docs , fun , arity ) -> d
245+ d = find_default_doc ( docs , fun , arity ) -> d
246+ true -> nil
217247 end
218248
219249 if doc do
220- IO . write "\n " <> print_signature ( doc )
250+ print_doc ( doc )
251+ :ok
221252 else
222- IO . puts IO.ANSI . escape ( "%{red}No docs for #{ inspect module } . #{ function } / #{ arity } have been found" )
253+ :not_found
223254 end
224255 else
225- IO . puts IO.ANSI . escape ( "%{red} #{ inspect module } was not compiled with docs" )
256+ :no_docs
226257 end
227258 end
228259
229260 defp find_doc ( docs , function , arity ) do
230- List . keyfind ( docs , { function , arity } , 0 )
261+ if doc = List . keyfind ( docs , { function , arity } , 0 ) do
262+ case elem ( doc , 4 ) do
263+ false -> nil
264+ _ -> doc
265+ end
266+ end
231267 end
232268
233269 defp find_default_doc ( docs , function , min ) do
@@ -242,22 +278,17 @@ defmodule IEx.Helpers do
242278 end
243279 end
244280
245- # Get the full signature from a function.
246- defp print_signature ( { _info , _line , _kind , _args , false } ) do
247- false
248- end
249-
250- defp print_signature ( { { name , _arity } , _line , kind , args , docs } ) do
251- args = Enum . map_join ( args , ", " , signature_arg ( & 1 ) )
252- IO . puts IO.ANSI . escape ( "%{yellow}* #{ kind } #{ name } (#{ args } )" )
253- IO.ANSI . escape ( "%{yellow}#{ docs } " ) || ""
281+ defp print_doc ( { { fun , _ } , _line , kind , args , doc } ) do
282+ args = Enum . map_join ( args , ", " , print_doc_arg ( & 1 ) )
283+ IO . puts IO.ANSI . escape ( "%{yellow}* #{ kind } #{ fun } (#{ args } )\n " )
284+ IO . write IO.ANSI . escape ( "%{yellow}#{ doc } " )
254285 end
255286
256- defp signature_arg ( { :// , _ , [ left , right ] } ) do
257- signature_arg ( left ) <> " // " <> Macro . to_binary ( right )
287+ defp print_doc_arg ( { :// , _ , [ left , right ] } ) do
288+ print_doc_arg ( left ) <> " // " <> Macro . to_binary ( right )
258289 end
259290
260- defp signature_arg ( { var , _ , _ } ) do
291+ defp print_doc_arg ( { var , _ , _ } ) do
261292 atom_to_binary ( var )
262293 end
263294
0 commit comments