@@ -83,7 +83,7 @@ defmodule IEx.Helpers do
83
83
Shows the documentation for IEx.Helpers.
84
84
"""
85
85
def h ( ) do
86
- h ( IEx.Helpers , [ ] )
86
+ __help__ ( IEx.Helpers )
87
87
end
88
88
89
89
@ doc """
@@ -105,73 +105,37 @@ defmodule IEx.Helpers do
105
105
"""
106
106
defmacro h ( { :/ , _ , [ { { :. , _ , [ mod , fun ] } , _ , [ ] } , arity ] } ) do
107
107
quote do
108
- h ( unquote ( mod ) , unquote ( fun ) , unquote ( arity ) )
108
+ IEx.Helpers . __help__ ( unquote ( mod ) , unquote ( fun ) , unquote ( arity ) )
109
109
end
110
110
end
111
111
112
112
defmacro h ( { { :. , _ , [ mod , fun ] } , _ , [ ] } ) do
113
113
quote do
114
- h ( unquote ( mod ) , unquote ( fun ) )
114
+ IEx.Helpers . __help__ ( unquote ( mod ) , unquote ( fun ) )
115
115
end
116
116
end
117
117
118
118
defmacro h ( { :/ , _ , [ { fun , _ , args } , arity ] } ) when args == [ ] or is_atom ( args ) do
119
119
quote do
120
- h ( unquote ( fun ) , unquote ( arity ) )
120
+ IEx.Helpers . __help__ ( unquote ( fun ) , unquote ( arity ) )
121
121
end
122
122
end
123
123
124
124
defmacro h ( { name , _ , args } ) when args == [ ] or is_atom ( args ) do
125
125
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 ) )
137
127
end
138
128
end
139
129
140
130
defmacro h ( other ) do
141
131
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 ) )
158
133
end
159
134
end
160
135
136
+ # Handles documentation for modules
161
137
@ 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
175
139
case Code . ensure_loaded ( module ) do
176
140
{ :module , _ } ->
177
141
case module . __info__ ( :moduledoc ) do
@@ -188,46 +152,118 @@ defmodule IEx.Helpers do
188
152
end
189
153
end
190
154
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" )
196
182
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
199
203
else
200
- :not_found
204
+ :no_docs
201
205
end
202
206
end
203
207
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
207
221
end
208
222
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
212
242
doc =
213
243
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
217
247
end
218
248
219
249
if doc do
220
- IO . write "\n " <> print_signature ( doc )
250
+ print_doc ( doc )
251
+ :ok
221
252
else
222
- IO . puts IO.ANSI . escape ( "%{red}No docs for #{ inspect module } . #{ function } / #{ arity } have been found" )
253
+ :not_found
223
254
end
224
255
else
225
- IO . puts IO.ANSI . escape ( "%{red} #{ inspect module } was not compiled with docs" )
256
+ :no_docs
226
257
end
227
258
end
228
259
229
260
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
231
267
end
232
268
233
269
defp find_default_doc ( docs , function , min ) do
@@ -242,22 +278,17 @@ defmodule IEx.Helpers do
242
278
end
243
279
end
244
280
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 } " )
254
285
end
255
286
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 )
258
289
end
259
290
260
- defp signature_arg ( { var , _ , _ } ) do
291
+ defp print_doc_arg ( { var , _ , _ } ) do
261
292
atom_to_binary ( var )
262
293
end
263
294
0 commit comments