Opened 9 years ago

Last modified 7 years ago

#14552 needs_info enhancement

Tab completer improvements

Reported by: vbraun Owned by: was
Priority: major Milestone: sage-6.4
Component: user interface Keywords:
Cc: Merged in:
Authors: Scott Mancuso Reviewers:
Report Upstream: N/A Work issues:
Branch: Commit:
Dependencies: Stopgaps:

Status badges

Description (last modified by vbraun)

Some desirable additions to the tab completer:

  1. include x.foo_bar in the completion of x.bar<tab> (search all words after splitting at underscore)
  2. Ditto for CamelCase: Include RealField in Field<tab>
  3. All-caps as shortcut for CamelCase: AMPD<tab> should yield AtkinModularPolynomialDatabase
  4. Turn on IPython's greedy completion (completion of lists): lst[0].<tab> shows the methods of lst[0]

Attachments (2)

trac_14552_tab_completer.patch (14.5 KB) - added by scmancuso 9 years ago.
trac_14552_tab_completer_cycle.patch (3.6 KB) - added by scmancuso 9 years ago.
Shows all possible completions and allows the user to tab-cycle through them. The first patch should be applied before this one.

Download all attachments as: .zip

Change History (25)

comment:1 Changed 9 years ago by scmancuso

  • Status changed from new to needs_info

I'd be happy to work on this, but I have a few questions before I start:

  • Are the suggested enhancements actually the behavior we want?
  • Are there any other enhancements that should be included?
  • Where would I go to find the relevant code? i.e. Where do I start making these changes?

I'm changing the status to 'needs_info'; is that the correct way to use this status?

comment:2 Changed 9 years ago by ppurka

I wouldn't want any of the first three. They simply pollute the completion space. The last one can be actually useful.

comment:3 Changed 9 years ago by vbraun

  • Description modified (diff)

Number 3 shouldn't cause any namespace issues. The first one was a request by David Roe on #14548 since English places adjectives first whereas you might use tab completion looking for the subsequent noun.

In any case, its hard to judge from the outset if it'll be too much. Perhaps the additional completions should only shown if the list of actual completions is very short. It would be nice to have a prototype implementation to try it out.

Number 4 you can do already on-the-fly with

sage: get_ipython().Completer.greedy = True

It just needs to be integrated into sage.misc.sage_extension.

For the others you should read the IPython/core/completer.py source. You'd probably have to write a derived class SageCompleter(Completer).

comment:4 Changed 9 years ago by scmancuso

Great, thanks! I'll work on it over the next few days and see if I can get a trial implementation out so we can play around and see how we like it.

comment:5 Changed 9 years ago by scmancuso

IPEP 11 proposes a change to the IPython completer that would make extending completion a lot easier to do and maintain. I've written to the author of that IPEP asking about the status of his proposal. If it will be available in the near future, I think it would be best to wait for that as the changes he is proposing will make a significant impact on how this ticket can be implemented. If he doesn't expect it to be available soon, I'll continue working on an implementation for what we currently have.

Changed 9 years ago by scmancuso

comment:6 Changed 9 years ago by scmancuso

  • Status changed from needs_info to needs_review

I never heard back from the author of the IPEP, so I've implemented the requested changes as IPython stands now. A few notes on the implementation:

  1. The new completions should work for any global names, attribute names, and modules. They do not work for filenames (seems unnecessary and difficult) or IPython magic functions (there are few enough and none of them really apply).
  2. In an effort to not overpollute the completion space, the new completions are only shown if there were no "traditional" completions available. This seems to work pretty well for me, but perhaps other people will find it too restrictive. Let me know how you like it.

I've tested the misc directory but not the entire Sage library. I wanted to get some feedback on the functionality before going through that whole process. I've also built the documentation, which seems fine.

The new functionality is not doctested because I have no idea how to go about testing tab completion. Does anyone have any ideas how this can be best done? I would guess that I can use the get_test_shell function in the interpreter module, but I don't know how to make that work.

Finally, I tried to use my best judgement on where things should be placed in the Sage library, but I'm not sure if everything is in an appropriate place, so if you could look at that too, that would be great.

comment:7 Changed 9 years ago by scmancuso

  • Authors set to Scott Mancuso

comment:8 Changed 9 years ago by ppurka

Some comments before you go on with this patch. It should be mentioned in the documentation that these enhanced completions (except the greedy one) make sense only in the notebook. In fact, they should perhaps be enabled only if we are indeed working in the notebook. For instance, look at this output in the terminal. There is no way I can continue with the completion on the terminal (unless the shell can tab through the separate options, like zsh).

sage: Double
ComplexDoubleElement     RealDoubleElement        is_ComplexDoubleElement  
ComplexDoubleField       RealDoubleField          is_RealDoubleElement     
sage: DoubleFie
ComplexDoubleField  RealDoubleField     
sage: DoubleFie
KeyboardInterrupt
sage: PR
CPRFanoToricVariety  PariRing             PolynomialRing       SetPartitionsPRk
sage: a = range(3)
sage: a[1].   # <----------- this is OK and useful in the terminal.
a[1].bit_length   a[1].conjugate    a[1].denominator  a[1].imag         a[1].numerator    a[1].real

Also, as you can see from the following output, not all the suggestions are being made. There is some stuff missing.

sage: Fiel  # <--------- Where are the RealField, ComplexField, RealLazyField, etc?
Field         FieldElement  Fields

Now, some documentation changes :)

  1. Use :trac:`14552` instead of http://trac.sagemath.org/sage_trac/ticket/14552. The URL will be automatically generated.
  2. Don't break the :class:`~IPython.frontend.terminal.interactiveshell.TerminalInteractiveShell` into two lines. It looks a bit weird when rendered:
       This method is basically copied from the method it overrides in "
       TerminalInteractiveShell", but using "SageCompleter" as the
       completer instead. This was done to address
    

comment:9 Changed 9 years ago by vbraun

I don't quite agree, the sage: Double<tab> example shows that its is still better to have the expansion (and discover RealDoubleField and ComplexDoubleField) than the current behavior of not returning anything at all. Its still an improvement, even if you are forced to go to the beginning of the line to complete the word. Of course it would be ideal to tab-cycle through choices, or display a drop-down dialog in an enhanced terminal.

comment:10 Changed 9 years ago by scmancuso

I'm hoping to upload a revised patch later today or tomorrow. I will look into tab cycling and see if I can feasibly implement it. If not, I agree with Volker that it is still useful to see what options are available, even if you have to go back to the beginning of the line (which you would have to do anyway if no completions were shown).

The omission of some suggestions is intentional, for now. I was trying to not pollute the completion space too much, so I've designed the new completions to only be shown if there are no traditional completions. I'm not sure that this is the best way, so I appreciate any feedback you might have about which is more useful.

comment:11 Changed 9 years ago by ppurka

Well, if you don't show everything that could be shown, then it will feel broken. That was my first impression about the completion - that it was not working as it should.

comment:12 Changed 9 years ago by ppurka

Maybe you can return something like this?

sage: Fiel
Field         FieldElement  Fields   RealField   ComplexField
... and 49 more matches.

comment:13 Changed 9 years ago by scmancuso

Well, the way the tab completion works, you just return a list of all possible completions and then the IPython completer handles actually displaying it to the screen, automatically completing, etc., so the easiest thing would be to just display everything. My revised patch will have it display everything and we can decide if that is too much.

Changed 9 years ago by scmancuso

Shows all possible completions and allows the user to tab-cycle through them. The first patch should be applied before this one.

comment:14 Changed 9 years ago by scmancuso

The patch I uploaded has some bugs. I was working on fixing them, but as I was working with it, I just found that there were far too many completions to cycle through in most cases. For example,

sage: Fie<tab>
AlgebraicField                     ResidueField
AlgebraicRealField                 UniversalCyclotomicField
...
RealIntervalField                  is_pAdicField
RealLazyField                      pAdicField
sage: AlgebraicField

gives sixty possible completions, and, most annoyingly, automatically fills in with the first one (AlgebraicField), requiring that you tab-cycle through them to find the one you want. Obviously this is unacceptable. If we enable tab-cycling, then I think we should go back to the way I first implemented it, where the traditional completions are used if there are any, and the new completions are used only if there were no traditional completions.

The other option is to not have any tab-cycling, and then we could show all completions (traditional and new), or the way I originally implemented it.

comment:15 Changed 9 years ago by ppurka

I suggest disabling tab cycling. In the notebook one can use the arrow keys to select the appropriate option. The current sage command prompt also doesn't do tab cycling so if you disable tab cycling no one will know any better ;)

comment:16 Changed 8 years ago by jdemeyer

  • Milestone changed from sage-5.11 to sage-5.12

comment:17 Changed 8 years ago by vbraun_spam

  • Milestone changed from sage-6.1 to sage-6.2

comment:18 Changed 8 years ago by vbraun_spam

  • Milestone changed from sage-6.2 to sage-6.3

comment:19 Changed 7 years ago by vbraun_spam

  • Milestone changed from sage-6.3 to sage-6.4

comment:20 follow-up: Changed 7 years ago by kcrisman

  • Status changed from needs_review to needs_info

This would still be awesome but there isn't a branch and it seems that the things discussed in comment:14 weren't quite resolved... I wonder if William implemented something like this in SMC.

comment:21 in reply to: ↑ 20 ; follow-ups: Changed 7 years ago by was

Replying to kcrisman:

This would still be awesome but there isn't a branch and it seems that the things discussed in comment:14 weren't quite resolved... I wonder if William implemented something like this in SMC.

It seems like 1 is already standard. I don't want 2 or 3. And yes, of course I already implemented 4 in SMC two years ago... :-)

comment:22 in reply to: ↑ 21 Changed 7 years ago by kcrisman

It seems like 1 is already standard.

Ok.

I don't want 2 or 3.

Hmm. I guess we could keep this ticket for those, in case someone wanted to make this a 'switch'.

And yes, of course I already implemented 4 in SMC two years ago... :-)

So where is the "regular Sage" branch for this, eh? :-)

comment:23 in reply to: ↑ 21 Changed 7 years ago by jhpalmieri

Replying to was:

Replying to kcrisman:

This would still be awesome but there isn't a branch and it seems that the things discussed in comment:14 weren't quite resolved... I wonder if William implemented something like this in SMC.

It seems like 1 is already standard.

It is? If I type x.constant[TAB], I don't see x.is_constant.

Note: See TracTickets for help on using tickets.