Extend iex to allow additional helpers

146 views
Skip to first unread message

Booker Bense

unread,
Jun 19, 2015, 10:05:12 AM6/19/15
to elixir-l...@googlegroups.com
I've been playing around with creating a command that does h style lookups for erlang functions and modules 
by doing a lot of messing around in man pages. 

I'm not sure this will ever be reliable enough for inclusion in the standard elixir shell, but it would be nice to
have a way to add "helpers" in a similar way that you can add mix tasks to a project. 

Thoughts? 

- Booker C. Bense 

José Valim

unread,
Jun 19, 2015, 4:42:40 PM6/19/15
to elixir-l...@googlegroups.com
Unfortunately there is no easy way. We have a discussion on Elixir issues tracker to make it easier but it would be future Elixir versions.



José Valim
Skype: jv.ptec
Founder and Director of R&D

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/a21b2ea8-8ca0-4867-93c6-b82ccd50204c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Booker Bense

unread,
Jun 23, 2015, 1:45:56 PM6/23/15
to elixir-l...@googlegroups.com, jose....@plataformatec.com.br

How reasonable is this proposal? 

The h command uses two underlying library calls to get data. 

Code.get_docs(module, :moduledoc)  -> { line_number, markdown_moduledoc } 

Code.get_docs(mod, :docs)  -> list of function doc tuples. [1]

What if we put those two signatures into a Behaviour called "ExternalDocs" and 
allowed a configuration setup in .iex to point to a Module that implemented these
behaviours? 

The simplest thing possible would simply to return a URL to the Erlang doc site for 
everything. 

I can imagine a module that opens that URL for people or finds the corresponding
html on the local disk. Or one that parse man pages into markdown...  

The part that probably can't be easily solved is Erlang modules that are not part of
the standard library. But there is so much in the Erlang standard library that even 
exposing just that would be of benefit. 

- Booker C. Bense

[1]- You can "fake" most of Code.get_docs using module.module_info(:exports)
you have to lie a bit about the line numbers and signatures, but those aren't used
by the h command anyway.  

José Valim

unread,
Jun 24, 2015, 5:04:13 AM6/24/15
to elixir-l...@googlegroups.com
I wouldn't couple them. If we want to improve Erlang support, I would have two modules, one that works with Elixir modules and another that works with Erlang ones. Then instead of adding if/else to different places, we would detect which kind of module we have in one place and call the callback module.

Then it should be easy to replace them and make them configurable and we wouldn't need to abide to the Code API.

José Valim
Skype: jv.ptec
Founder and Director of R&D

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.

Booker Bense

unread,
Jun 24, 2015, 3:21:39 PM6/24/15
to elixir-l...@googlegroups.com, jose....@plataformatec.com.br


On Wednesday, June 24, 2015 at 2:04:13 AM UTC-7, José Valim wrote:
I wouldn't couple them. If we want to improve Erlang support, I would have two modules, one that works with Elixir modules and another that works with Erlang ones. Then instead of adding if/else to different places, we would detect which kind of module we have in one place and call the callback module.



I really thought that was what I was suggesting, but in a way that required the minimal changes to the structure
of iex/lib/introspection.ex. The if/else's are already there, it's just a question of including the callbacks on the else
branch rather than returning an "doc not found" message. 

We could abstract out the interface into "return the markdown for this module/function" , rather than the direct results
of Code.get_docs. That would allow plugins for both kinds of modules. I know I'd write one that did a Dash search for
elixir functions. 

- Booker C. Bense  

José Valim

unread,
Jun 24, 2015, 3:24:23 PM6/24/15
to Booker Bense, elixir-l...@googlegroups.com
I really thought that was what I was suggesting, but in a way that required the minimal changes to the structure
of iex/lib/introspection.ex. The if/else's are already there, it's just a question of including the callbacks on the else
branch rather than returning an "doc not found" message. 

Yes. I want to get rid of those if/else though and move them to one single place. :) 

We could abstract out the interface into "return the markdown for this module/function" , rather than the direct results
of Code.get_docs. That would allow plugins for both kinds of modules. I know I'd write one that did a Dash search for
elixir functions. 

Yup, sounds excellent.

Booker Bense

unread,
Jun 29, 2015, 11:20:32 PM6/29/15
to elixir-l...@googlegroups.com, jose....@plataformatec.com.br


On Wednesday, June 24, 2015 at 12:24:23 PM UTC-7, José Valim wrote:
I really thought that was what I was suggesting, but in a way that required the minimal changes to the structure
of iex/lib/introspection.ex. The if/else's are already there, it's just a question of including the callbacks on the else
branch rather than returning an "doc not found" message. 

Yes. I want to get rid of those if/else though and move them to one single place. :) 


Well, I kind of moved the ifs to 3 different places, but each kind of Doc helper answers yes, no, can't help. This is the design I came up with 

The h command uses a list of Helper Modules to find documentation. 
 Each module implements a behavour that returns one of the following tuples for
any document request.

  {:found, doc_list }              -  Documentation found, doc_list is a list of {header,doc} tuples in markdown format.

  {:not_found, doc_list }       - Documentation not found, but could have been found by module if
                                              it existed. doc_list contains error message

  {:can_not_help, doc_list } - Module does not know how to find documentation for arguments. doc_list contains
                                             message that might allow help in future. 

  The intent is that helpers can be stacked and the iex command can do either `:first` or `:all`
  (i.e. attempt to get help using the first helper that returns either :found or :not_found, or
   use all the helpers regardless of return status.)

There is some example code that implements this at 


It's in a very rough state, but I wanted to see if I was on the right track before I put more effort into this. 

- Booker C. Bense 

José Valim

unread,
Jun 30, 2015, 4:10:02 AM6/30/15
to Booker Bense, elixir-l...@googlegroups.com
Nice work, I really like this! It is more flexible than what I had in mind. I would just replace :can_not_help with :unknown (i.e. you don't know about that module at all).



José Valim
Skype: jv.ptec
Founder and Director of R&D

Reply all
Reply to author
Forward
0 new messages