     end
   end
 
-  def h(module, function) when is_atom(module) and is_atom(function) do
-    result = lc {{f, arity}, _line, _type, _args, doc } inlist module.__info__(:docs),
-       f == function and doc != false do
-      h(module, function, arity)
-      IO.puts ""
-    end
-    if result != [] do
-      :ok
+  def __help__(_) do
+    IO.puts IO.ANSI.escape("%{red}Invalid arguments for h helper")
+  end
+
+  # Help for function+arity or module+function
+  @doc false
+  def __help__(modules, function) when is_list(modules) and is_atom(function) do
+    result =
+      Enum.reduce modules, :not_found, fn
+        module, :not_found -> help_mod_fun(module, function)
+        _module, acc -> acc
+      end
+
+    unless result == :ok, do:
+      IO.puts IO.ANSI.escape("%{red}No docs for #{function} have been found")
+
+    :ok
+  end
+
+  def __help__(module, function) when is_atom(module) and is_atom(function) do
+    case help_mod_fun(module, function) do
+      :ok ->
+        :ok
+      :no_docs ->
+        IO.puts IO.ANSI.escape("%{red}#{inspect module} was not compiled with docs")
+      :not_found ->
+        IO.puts IO.ANSI.escape("%{red}No docs for #{inspect module}.#{function} have been found")
+    end
+
+    :ok
+  end
+
+  def __help__(function, arity) when is_atom(function) and is_integer(arity) do
+    __help__([__MODULE__, Kernel, Kernel.SpecialForms], function, arity)
+  end
+
+  def __help__(_, _) do
+    IO.puts IO.ANSI.escape("%{red}Invalid arguments for h helper")
+  end
+
+  defp help_mod_fun(mod, fun) when is_atom(mod) and is_atom(fun) do
+    if docs = mod.__info__(:docs) do
+      result = lc { {f, arity}, _line, _type, _args, doc } inlist docs, fun == f, doc != false do
+        __help__(mod, fun, arity)
+        IO.puts ""
+      end
+
+      if result != [], do: :ok, else: :not_found
     else
-      :not_found
-    end
-  end
-
-  def h(_, _) do
-    IO.puts IO.ANSI.escape("%{red}Invalid h helper argument")
-    h()
-  end
-
-  @doc false
-  def h(module, function, arity) when is_atom(module) and is_atom(function) and is_integer(arity) do
-    if docs = module.__info__(:docs) do
+      :no_docs
+    end
+  end
+
+  # Help for module+function+arity
+  @doc false
+  def __help__(modules, function, arity) when is_list(modules) and is_atom(function) and is_integer(arity) do
+    result =
+      Enum.reduce modules, :not_found, fn
+        module, :not_found -> help_mod_fun_arity(module, function, arity)
+        _module, acc -> acc
+      end
+
+    unless result == :ok, do:
+      IO.puts IO.ANSI.escape("%{red}No docs for #{function}/#{arity} have been found")
+
+    :ok
+  end
+
+  def __help__(module, function, arity) when is_atom(module) and is_atom(function) and is_integer(arity) do
+    case help_mod_fun_arity(module, function, arity) do
+      :ok ->
+        :ok
+      :no_docs ->
+        IO.puts IO.ANSI.escape("%{red}#{inspect module} was not compiled with docs")
+      :not_found ->
+        IO.puts IO.ANSI.escape("%{red}No docs for #{inspect module}.#{function}/#{arity} have been found")
+    end
+
+    :ok
+  end
+
+  def __help__(_, _, _) do
+    IO.puts IO.ANSI.escape("%{red}Invalid arguments for h helper")
+  end
+
+  defp help_mod_fun_arity(mod, fun, arity) when is_atom(mod) and is_atom(fun) and is_integer(arity) do
+    if docs = mod.__info__(:docs) do
       doc =
         cond do
-          d = find_doc(docs, function, arity)         -> d
-          d = find_default_doc(docs, function, arity) -> d
-          true                                        -> nil
+          d = find_doc(docs, fun, arity)         -> d
+          d = find_default_doc(docs, fun, arity) -> d
+          true                                   -> nil
         end
 
       if doc do
-        IO.write "\n" <> print_signature(doc)
+        print_doc(doc)
+        :ok
       else
-        IO.puts IO.ANSI.escape("%{red}No docs for #{inspect module}.#{function}/#{arity} have been found")
+        :not_found
       end
     else
-      IO.puts IO.ANSI.escape("%{red}#{inspect module} was not compiled with docs")
+      :no_docs
     end
   end
 
   defp find_doc(docs, function, arity) do
-    List.keyfind(docs, { function, arity }, 0)
+    if doc = List.keyfind(docs, { function, arity }, 0) do
+      case elem(doc, 4) do
+        false -> nil
+        _ -> doc
+      end
+    end
   end
 
   defp find_default_doc(docs, function, min) do

    end
  end

  # Get the full signature from a function.
  defp print_signature({ _info, _line, _kind, _args, false }) do
    false
  end

  defp print_signature({ { name, _arity }, _line, kind, args, docs }) do
    args = Enum.map_join(args, ", ", signature_arg(&1))
    IO.puts IO.ANSI.escape("%{yellow}* #{kind} #{name}(#{args})")
    IO.ANSI.escape("%{yellow}#{docs}") || ""
  end

  defp signature_arg({ ://, _, [left, right] }) do
    signature_arg(left) <> " // " <> Macro.to_binary(right)
  end

  defp signature_arg({ var, _, _ }) do
    atom_to_binary(var)
  end


  Shows the documentation for IEx.Helpers.
  """
  def h() do
    __help__(IEx.Helpers)
  end

  @doc """
