otp icon indicating copy to clipboard operation
otp copied to clipboard

stdlib: enhances the shell completion

Open frazze-jobb opened this issue 2 years ago • 2 comments

Have all functionality more or less in place, but I need to do some refactoring, and there are already 3 bugs that I know of.

I need to deal with c:memory/1 which have two type specs, I can use my fold function but the fold function doesn't work. It can be seen in the new failing edlin_expand_SUITE testcases. I also need to handle fun Mod:Fun/X, properly.

Please evaluate and see if the completions are helpful. I am thinking if a shell keyboard shortcut could show the whole type spec. Instead of just the current parameter of interest. Also file:open("/filename", just gives ... because the suggestion is so long, file:open("/filename", [ will work. We need to decide on some heuristics when to print all the concrete types and when to print an abstract type.

frazze-jobb avatar Apr 22 '22 08:04 frazze-jobb

CT Test Results

       8 files     318 suites   3h 31m 28s :stopwatch: 4 905 tests 4 661 :heavy_check_mark: 243 :zzz: 1 :x: 5 848 runs  5 538 :heavy_check_mark: 309 :zzz: 1 :x:

For more details on these failures, see this check.

Results for commit 542d97c4.

:recycle: This comment has been updated with latest results.

To speed up review, make sure that you have read Contributing to Erlang/OTP and that all checks pass.

See the TESTING and DEVELOPMENT HowTo guides for details about how to run test locally.

Artifacts

// Erlang/OTP Github Action Bot

github-actions[bot] avatar Apr 22 '22 08:04 github-actions[bot]

CLA assistant check
All committers have signed the CLA.

CLAassistant avatar Apr 22 '22 08:04 CLAassistant

Lots of great stuff in here now. Some details to polish though. For example:

No completions

If I type:

1> lists:ab<TAB>
functions

It prints an empty functions heading. I think it should not print anything as that is what it does when it cannot find a module that matches. Possibly the same thing applies when it does not find an argument type that matches. Right now it prints the slogan of the function, but should it print nothing?

I agree that it should not show the section title if we would erase the last letter and get completions for that, then I think it could be easy to miss that you have typos on your prompt

Or maybe both of these should print the first suggestion that appears by erasing the characters before the cursor one by one? That is lists:ab would show the suggestions for lists:a and lists:all([{ would show the suggestions for lists:all(? Though I suppose that could potentially be very expensive to compute...

Multiple clauses

The completion for ssh:connect(<TAB> is not very intuitive:


16> ssh:connect(<TAB>
ssh:connect(Host, Port, Options, NegotiationTimeout)
ssh:connect(Var1, Var2, Var3)
ssh:host() :: {0..255, ...}      {0..65535, ...}    loopback           string()
ssh:connect(OpenTcpSocket, Options)
ssh:connect(Var1, Var2, Var3)
ssh:open_socket() :: {'$inet', ...}    port()

Where is the Var1 etc coming from? ssl:connect(<TAB> looks much better.


ssl:connect(Host, Port, TLSOptions)
ssl:connect(Host, Port, TLSOptions, Timeout)
ssh:host() :: {0..255, ...}      {0..65535, ...}    loopback           string()
ssl:connect(TCPSocket, TLSOptions)
ssl:connect(TCPSocket, TLSOptions, Timeout)
ssl:socket() :: {'$inet', ...}    port()

regarding multple clauses, the 'Var's appears if you have 'type()' in your function parameters in the spec, the reason I decided to it this way is because I expand the types, and putting the expanded types inside the function parameters would be nasty. But I could probably put the non expanded type in the function parameter somehow.

-spec connect(open_socket(), client_options(), timeout()) ->
                     {ok, connection_ref()} | {error, term()}
           ; (host(), inet:port_number(), client_options()) ->
                     {ok, connection_ref()} | {error, term()}.

so it would become:

ssh:connect(Host, Port, Options, NegotiationTimeout)
ssh:connect(host(), inet:port_number(), client_options())
ssh:host() :: {0..255, ...}      {0..65535, ...}    loopback           string()
ssh:connect(OpenTcpSocket, Options)
ssh:connect(open_socket(), client_options(), timeout())
ssh:open_socket() :: {'$inet', ...}    port()

system_info

erlang:system_info is one of the most complex functions we have to document, so I played around with it and found some bugs in the completion code.

1. `erlang:system_info(<TAB>` prints `erlang:system_info(info)`, i.e. the wrong `info` is highlighted.

I will have a look if I can make a smarter highlighting algorithm

2. `erlang:system_info({allocator,<TAB>` should show `atom()` as only possible completions, but shows a lot of other options as well.

This is the purpose of edlin_expand:match_argument function, however, when the term is not completed (in this case an uncompleted tuple), then everything can match, but I agree it should filter the others out.

3. `erlang:system_info(dist_<TAB>` shows this:
    ```
   modules
   dist_ac:     dist_util:
   erlang:system_info(dist_buf_busy_limit)
   erlang:system_info(dist_ctrl)
   ```
     
   I wonder if we should not show modules when there are matching function arguments? Should function name completion have its own header?

I can make a section title for that. I don't know about your first idea, sometimes you want to have the possibility to get modules. I thought about if you could have a special keybind for module expansion vs the rest expansion. But not sure if its worth it. Often times module names do 'collide' with atoms and keywords.

External fun completion

If I type [fun ssl:connect/<TAB> the autocompletion is 2, 3, 4,. Why is there a comma at the end? I could want to use any of ,, ] or | at that position.

You could, my thought was that most of the time I want a comma when I specify my list and if I would want something else I would just erase and put the correct char. With the keybind for closing we could maybe erase the last comma and put the ]. But I don't have a good idea regarding '|'.

Fun completion

If I type fun(a) when<TAB> it completes as when, however it should not give any completions. If I type fun(A) -<TAB> I get a bunch of incorrect completions. If I type fun(A) -> <TAB> I get the same completions as above, should I really get any completions at all here?

I agree, no completions

frazze-jobb avatar Aug 30 '22 15:08 frazze-jobb

After discussion offline with @garazdawi , we concluded that list elements should never autocomplete with , | or ] and maps should not complete with , or }. With trailing comma support there might be a possibility that we revisit this. For now it's easier to just type , instead of tab.

frazze-jobb avatar Aug 31 '22 18:08 frazze-jobb