Class name completion

Hi All!

We have a number of requests filed against $subj. And it seems that we need
to rewrite it. Lets make a list of features you'd like to be implemented. By
now I know about the following:

-- Filter out classes after implements
-- Filter out current and final classes in extends

What else?

IK

IntelliJ Labs / JetBrains Inc.
http://www.intellij.com
"Develop with pleasure!"

23 comments

Those after throws and throw new (maybe it works already) ...

Tom


On Fri, 9 May 2003 01:06:25 +0400, Igor Kuralenok <ik@intellij.com> wrote:

Hi All!

>

We have a number of requests filed against $subj. And it seems that we
need
to rewrite it. Lets make a list of features you'd like to be implemented.
By
now I know about the following:

>

-- Filter out classes after implements
-- Filter out current and final classes in extends

>

What else?

>

IK

>

IntelliJ Labs / JetBrains Inc.
http://www.intellij.com
"Develop with pleasure!"

>


0

On Fri, 9 May 2003 01:06:25 +0400, Igor Kuralenok <ik@intellij.com>
wrote:

>Hi All!
>
>We have a number of requests filed against $subj. And it seems that we need
>to rewrite it. Lets make a list of features you'd like to be implemented. By
>now I know about the following:
>
>What else?

I find the 3 different "code completion" keys (Ctrl-Space,
Ctrl-Shift-Space, & Ctrl-Alt-Space) to be very confusing.

I would much prefer 1 "Super Code Completion" or "Do What I Mean" key
that just does the best job it can.

I have submitted
http://www.intellij.net/tracker/idea/viewSCR?publicId=12082 for this
request.

This is one place where IDEA forces me to think about the tool I'm
using rather than the code I'm writing.

Neil

0

Neil Galarneau wrote:

I find the 3 different "code completion" keys (Ctrl-Space,
Ctrl-Shift-Space, & Ctrl-Alt-Space) to be very confusing.


I agree that it's a bit confusing but I don't see how it could be made
different without mind reading.

Code completion should be able to complete any extended expression that
will eventually return a value of the expected type. In other words, if
there's a method processFoo(Foo something), and you just typed
processFoo(abc.|) where | is the caret, then you want to be able to
complete the method getBar() which returns a Bar that in turn has a
method getFoo(). Eventually you get processFoo(abc.getBar().getFoo()).
There must be a way for completion to do this, so clearly getBar()
should be part of the completion list. If it isn't, you'd have to type
getBar() manually.

But sometimes you know that abc has a method that returns a Foo directly
and that that is the method you want. So when you've typed
processFoo(abc.|) and you invoke code completion, you only want the
items that return a Foo directly. There must be a way for completion to
do this, so clearly getBar() should NOT be part of the completion list.
If it is, you'll get thousands of irrelevant completions in the list.

How do you reconcile these two different usage patterns without having
different keyboard shortcuts?


As for class name completion, you usually only want to use the classes
you have already imported. It would be extremely annoying not to have a
quick way to expand "FileI" to "FileInputStream" because some irrelevant
classes like com.sun.imageio.spi.FileImageOutputStreamSpi get in the
way, when you haven't imported them and you're not interested in them.

On the other hand, when you have not yet imported FileInputStream, it
would be quite annoying to have to type the entire name, wait for the
intention popup, and then let IDEA import it. Not to mention if you
can't remember exactly how the class name is spelled. So clearly there
are cases when you want all class names (in some sense, all global
identifiers) to be available in the list.

Again, this seems like it would be best solved by different keyboard
shortcuts.


I thought about what would happen if you let ctrl-space pop up the
"smart" completion list and then pressing it again would expand the list
to contain the larger non-smart completion list, but then you could not
auto-complete when the smart completion list only had one entry, so it
would not really work.


Although one inconsistency that could perhaps be addressed is that
ctrl-space does not always yield a superset of ctrl-shift-space.
Consider this simple class, where again | is the caret:

public class Foo {
public static void main(String[] args) {
foo(|);
}
static void foo(String[] x) {}
}

If you press ctrl-shift-space, "args" is auto-completed. If you press
ctrl-space, you get no completions at all. If this was changed so that
ctrl-space always showed all completions, even if the list happened to
be quite long, then you could consistently use ctrl-space and you would
be certain to get all the completions you could want (and possibly some
more, so you'll have to spend a little bit more time to read the list
and select one).

0

Jonas Kvarnstr?m wrote:

Neil Galarneau wrote:

>> I find the 3 different "code completion" keys (Ctrl-Space,
>> Ctrl-Shift-Space, & Ctrl-Alt-Space) to be very confusing.


I agree that it's a bit confusing but I don't see how it could be made
different without mind reading.

Code completion should be able to complete any extended expression that
will eventually return a value of the expected type. In other words, if
there's a method processFoo(Foo something), and you just typed
processFoo(abc.|) where | is the caret, then you want to be able to
complete the method getBar() which returns a Bar that in turn has a
method getFoo(). Eventually you get processFoo(abc.getBar().getFoo()).
There must be a way for completion to do this, so clearly getBar()
should be part of the completion list. If it isn't, you'd have to type
getBar() manually.

But sometimes you know that abc has a method that returns a Foo directly
and that that is the method you want. So when you've typed
processFoo(abc.|) and you invoke code completion, you only want the
items that return a Foo directly. There must be a way for completion to
do this, so clearly getBar() should NOT be part of the completion list.
If it is, you'll get thousands of irrelevant completions in the list.

How do you reconcile these two different usage patterns without having
different keyboard shortcuts?


Although you talk talk about cycling later, let me flesh it out more.
With a cycle on the broadness of completion. Let's say that tab is the
completion key. When you press it once, you get the most type-specific
matches. If you press it again, you'll get a broader list of
possibilities. Also, if there are no type specific matches, the first
tab should take you to the broad list. Repeated tabs should take you
back to the narrow list.

As for class name completion, you usually only want to use the classes
you have already imported. It would be extremely annoying not to have a
quick way to expand "FileI" to "FileInputStream" because some irrelevant
classes like com.sun.imageio.spi.FileImageOutputStreamSpi get in the
way, when you haven't imported them and you're not interested in them.

On the other hand, when you have not yet imported FileInputStream, it
would be quite annoying to have to type the entire name, wait for the
intention popup, and then let IDEA import it. Not to mention if you
can't remember exactly how the class name is spelled. So clearly there
are cases when you want all class names (in some sense, all global
identifiers) to be available in the list.

Again, this seems like it would be best solved by different keyboard
shortcuts.


Cycling from local to general could cover that as well.

I thought about what would happen if you let ctrl-space pop up the
"smart" completion list and then pressing it again would expand the list
to contain the larger non-smart completion list, but then you could not
auto-complete when the smart completion list only had one entry, so it
would not really work.


Shift-tab could work as you desire where you continue to hold down the
shift. If there is one match on the narrow version it will complete if
you let go of both on that single first match, but you could tab again
while still holding shift to go to the broader list.

Jon

0


This is getting off topic.

Although you talk talk about cycling later, let me flesh it out more.
With a cycle on the broadness of completion. Let's say that tab is the
completion key. When you press it once, you get the most type-specific
matches. If you press it again, you'll get a broader list of
possibilities. Also, if there are no type specific matches, the first
tab should take you to the broad list. Repeated tabs should take you
back to the narrow list.


I agree with this, and with using only one key for basic+smart type
completion:

It has become automatic pressing control-shift-space (or rather alt-space as
I remmapped it) followed by control-space.

But I wouldn't use the completion key - to error prone.

Using the invocation key is better:

control-space -> smart-type, again -> basic -> again -> classes
control-shift-space would navigate in teh reverse way.

Or maybe: control-space changes between smart-type/basic and
control-alt-space continues to be only class completion.


Also:

If a list is empty, automatically show the next broader list: if smart type
is chosen and no list is available automatically show the basic completion
list.

Shift-tab could work as you desire where you continue to hold down the
shift. If there is one match on the narrow version it will complete if
you let go of both on that single first match, but you could tab again
while still holding shift to go to the broader list.


No, Control-space or Control-shift-space again :)

Jon



Also:
Clarify exactly what each level of code completion does. My understanding
now (as it seems to not be the same everywhere) of what it should be:

Basic: visible names (imports + fields + locals + methods) .

Smart type: visible names filtered by appropriate
return/parameter/assignation type - almost forgotten: and smart live
tempates.

Class: every visible class in the system.


Carlos


0

And after new, if it's an assignment/parameter/...:

And after catch and throw

(again, maybe it works already)...

Those after throws and throw new (maybe it works already) ...

>

Tom

>
>

-- Filter out classes after implements
-- Filter out current and final classes in extends

>

What else?

>

IK



0

Carlos Costa e Silva wrote:
>>Although you talk talk about cycling later, let me flesh it out more.
>>With a cycle on the broadness of completion. Let's say that tab is the
>>completion key. When you press it once, you get the most type-specific
>>matches. If you press it again, you'll get a broader list of
>>possibilities. Also, if there are no type specific matches, the first
>>tab should take you to the broad list. Repeated tabs should take you
>>back to the narrow list.


I agree with this, and with using only one key for basic+smart type
completion:

It has become automatic pressing control-shift-space (or rather alt-space as
I remmapped it) followed by control-space.

But I wouldn't use the completion key - to error prone.
Using the invocation key is better:


It isn't important to me what key combo makes it happen.
FYI-- for anyone who missed it, you can vote for the as yet not
completely fleshed out feature at
http://www.intellij.net/tracker/idea/viewSCR?publicId=12082


control-space -> smart-type, again -> basic -> again -> classes
control-shift-space would navigate in teh reverse way.


The reversing option with a meta-key is new to me and a possibility.

Or maybe: control-space changes between smart-type/basic and
control-alt-space continues to be only class completion.


I'm not sure if I would have them separate or not. Doesn't it seem like
context could help decide? Maybe if the context called for a class or
interface, it would start with narrow class completion (already imported
and matching type if type narrow context), broader class completion,
then on to basic.

Also:

If a list is empty, automatically show the next broader list: if smart type
is chosen and no list is available automatically show the basic completion
list.


Yes.

>>Shift-tab could work as you desire where you continue to hold down the
>>shift. If there is one match on the narrow version it will complete if
>>you let go of both on that single first match, but you could tab again
>>while still holding shift to go to the broader list.


No, Control-space or Control-shift-space again :)


Sure.

Also:
Clarify exactly what each level of code completion does. My understanding
now (as it seems to not be the same everywhere) of what it should be:

Basic: visible names (imports + fields + locals + methods) .

Smart type: visible names filtered by appropriate
return/parameter/assignation type - almost forgotten: and smart live
tempates.

Class: every visible class in the system.


Agree on getting it all clarified. This would help to decide how it all
could fit together in a cycle and whether it should be cleaned up to
better support cycling.

Jon

0

Igor Kuralenok wrote:

Hi All!

We have a number of requests filed against $subj. And it seems that we need
to rewrite it. Lets make a list of features you'd like to be implemented. By
now I know about the following:

-- Filter out classes after implements


Filter out interfaces you already implement.
Filter out superinterfaces of interfaces you already implement.

-- Filter out current and final classes in extends


In extends for interfaces:
Filter out any interface(s) you already extend
Probably filter out superinterfaces of interfaces you already extend


What else?


Not sure I completely understand the question. Are you only asking about
where class/interface filtering can be inherently applied or are you
open to having a cycle on class name completion that has a narrow list
first time that is only already imported stuff and then a broader list
that includes all possibilities?

Thanks,
Jon

0

Jon Steelman wrote:

Shift-tab could work as you desire where you continue to hold down the
shift. If there is one match on the narrow version it will complete if
you let go of both on that single first match, but you could tab again
while still holding shift to go to the broader list.


Yes, I suppose it could. Actually I started writing that message
convinced that there was no way of improving the current completion keys
and then I partially changed my mind while writing it. Now you've
changed it even further :)

It's a bit hard to judge how well it would work "in theory", so it would
be very interesting to see something like this implemented in an EAP
release so that we could test it in practice.

0

Neil Galarneau wrote:
Code completion should be able to complete any extended expression
that will eventually return a value of the expected type. In other
words, if there's a method processFoo(Foo something), and you just
typed processFoo(abc.|) where | is the caret, then you want to be
able to complete the method getBar() which returns a Bar that in turn
has a method getFoo(). Eventually you get
processFoo(abc.getBar().getFoo()). There must be a way for
completion to do this, so clearly getBar() should be part of the
completion list. If it isn't, you'd have to type getBar() manually.

>

But sometimes you know that abc has a method that returns a Foo
directly and that that is the method you want. So when you've typed
processFoo(abc.|) and you invoke code completion, you only want the
items that return a Foo directly. There must be a way for completion
to do this, so clearly getBar() should NOT be part of the completion
list. If it is, you'll get thousands of irrelevant completions in
the list.

>

How do you reconcile these two different usage patterns without having
different keyboard shortcuts?

Do what (I think) JBuilder used to do. Include getBar() in the list, but
sort the list for relevance - members of the type or descendants of the type
required come first, so that getFoo() is before getBar() (and is probably
preselected too), but getBar() is still accessible from that list.

Incidentally, JBuilder only had one key for smart complete and it was
sufficient, however JBuilder did not include Class Completion for
non-imported classes. When the Amis chaps implemented this with
Productivity, they added another key stroke for that, which I think is right
as it's a quite seperate action. So 3 different strokes is too many, but 2
are definately needed.

N.


0

Jonas Kvarnstr?m wrote:

Jon Steelman wrote:

>> Shift-tab could work as you desire where you continue to hold down the
>> shift. If there is one match on the narrow version it will complete if
>> you let go of both on that single first match, but you could tab again
>> while still holding shift to go to the broader list.


Yes, I suppose it could. Actually I started writing that message
convinced that there was no way of improving the current completion keys
and then I partially changed my mind while writing it. Now you've
changed it even further :)

It's a bit hard to judge how well it would work "in theory", so it would
be very interesting to see something like this implemented in an EAP
release so that we could test it in practice.


Agreed on needing to see it in EAP. Say, does the openapi have enough
power to implement this on top of all the current code completion
features or would IntelliJ folks have to do it?

Jon

0

Hi Guys!

sorry for a long silence. I'll comment your suggestions in separate mail. Here I just want to answer the only question:

Agreed on needing to see it in EAP. Say, does the
openapi have enough
power to implement this on top of all the current
code completion
features or would IntelliJ folks have to do it?


No. I think not. I think we should extend access to completion features in OpenAPI but this is my personal opinion and we need to discuss this with other members of our team first.

IK

0

Hi All!

-- Filter out classes after implements


Filter out interfaces you already implement.
Filter out superinterfaces of interfaces you already
implement.

-- Filter out current and final classes in extends


In extends for interfaces:
Filter out any interface(s) you already extend
Probably filter out superinterfaces of interfaces you
already extend

Ok. I agree with this features.

Not sure I completely understand the question. Are
you only asking about
where class/interface filtering can be inherently
applied or are you
open to having a cycle on class name completion that
has a narrow list
first time that is only already imported stuff and
then a broader list
that includes all possibilities?


When I wrote that letter I was thinking on possible class name completion features. But if we started such an active discussion on possible completion improvements in general I think it's not a good idea to ignore your brilliant suggestions even if they are a little out of topic :). I'll try to summarize features you've proposed and describe problems that could cause these features

Summarizing the discussion:

It'd be nice to have:
-- Shortcut that cycle through all completions.
-- A key that extends/narrows a lookup list in completion.

Good things:

-- One shortcut for all kind of completion

Bad things:

-- No "completion on one keystroke" what kind of completion should we choose?
-- More complicated navigation for newbies (this is arguable but this is just my point of view :)).

I have the following idea for completion enhancement:

All shortcuts will stay the same except one thing: in normal completion lookup on left/right key the completion type will be changed.

Agree?

Thanks,

IK

0

Forgot the filter after "instanceof":
- When the left type is a class, filter only subclasses or interfaces, that
are implemented by subclasses.
- When the left type is an interface, all classes and subclasses of this
interface should be filtered out.

Tom

0

I have the following idea for completion enhancement:

>

All shortcuts will stay the same except one thing: in normal completion

lookup on left/right key the completion type will be changed.
>

Agree?


I'd see subsequent CtrlSpace (CtrlShift+Space) commands as being more
intuitive (limiting the number of key combinations one has to remember as
well), but that's just me. If you go with the arrow keys could we have the
key binding exposed so we can re-map it?

Thx.
Andrei


0

Ok. This will be assignable inside completion settings.

0

Please ensure, that one can map the completion to the ]]> key.

Tom

0

The completion shortcuts and their binding remain the same. I think that's reasonable to have a separate binding inside completion settings for changing completion type inside lookup.

IK

0

Thomas Singer wrote:

Please ensure, that one can map the completion to the <Tab> key.


I would like that too, but this makes it a little more complicated if
you also want live templates to work into the mix. For example, where do
we want live templates to go to the completion cycle?

Jon

0

Igor Kuralenok wrote:

When I wrote that letter I was thinking on possible class name completion features.

> But if we started such an active discussion on possible completion
improvements in general I think it's not a good idea
> to ignore your brilliant suggestions even if they are a little out of
topic :). I'll try to summarize features you've proposed and describe
problems that could cause these features


Summarizing the discussion:

It'd be nice to have:
-- Shortcut that cycle through all completions.
-- A key that extends/narrows a lookup list in completion.

Good things:

-- One shortcut for all kind of completion


Yes.

Bad things:

-- No "completion on one keystroke" what kind of completion should we choose?


Depending on the keys involved, I think you can still do the one
keystroke completion when the first, narrowest lookup list has exactly
one match. For example, if a meta key like Shift is involved, they just
let go of the keys and that accepts the completion on one keystroke.
However, if they want to cycle to broader, they would keep holding down
the Shift then strike the other key(s) that originally invoked
completion. A single key completion with something like tab that has no
meta-key might not be able to work this way unless you did a timer than
waited for another tab within a limited period to represent cycling.

I have the following idea for completion enhancement:

All shortcuts will stay the same except one thing: in normal completion lookup on left/right key the completion type will be changed.

Agree?


This would be good in that a power user can start the completion where
they want it but still be able to cycle. In addition to this, however, I
was imagining a completion system that did it's best to figure out the
most appropriate completion (possibly including live templates) given
the context. So, in addition to all the existing specific completion
entry points you're proposing, it would be nice if there were a general
completion key sequence that selects the most likely narrowest list and
allows you to cycle out and back around from there. The universal
completion would clearly need added intelligence to figure out which
list to select to start.

Thanks,
Jon

0

I would like that too, but this makes it a little more complicated if you
also want live templates to work into the mix. For example, where do we
want live templates to go to the completion cycle?


Hmm, did not thought about live templates. Does really somebody ]]> and
]]> to invoke different live templates? Maybe there could be one
(customizable) shortcut to invoke them?

Tom

0

I have the following idea for completion enhancement:

>

All shortcuts will stay the same except one thing: in normal completion

lookup on left/right key the completion type will be changed.
>

Agree?


Yes.

Also, if the a completion is empty automatically show the "next" one. I
really dislike control-shift enter resulting in no completion list.


0

Please sign in to leave a comment.