Author Topic: Can code completion be made contextual?  (Read 16862 times)

Offline carra

  • Multiple posting newcomer
  • *
  • Posts: 117
Can code completion be made contextual?
« on: July 06, 2012, 09:57:37 am »
Code completion in C::B is really useful, but it seems to behave worse when there are big lists of candidates. This happens whenever you include big headers (such as <windows.h>), because the only critera for suggesting candidates seems to alphabetic sorting. Think, for instance, a Windows program where I have the following:

Code
    UniString U( const string& Text )
    {
        UniString Result = U( Text.c_str() );
        Result += '\0';
       
        return Re  <-- HERE
    }

For anyone seeing this code, it would be very obvious that I want to write "Result", however due to windows definitions Code Completion suggests the following:

Code
ReadClassStg
ReadClassStm
ReadConsole
ReadConsoleA
... (VERY long list)

All these Windows definitions have nothing to do with what I am writing. But the problem  is that, being THAT many, in many simple cases you end up having to write almost the whole word yourself to get the right suggestion. This is a clear indication that, when including big headers, a simple alphabetic sort is not the most useful criteria.

So my question here is if it would be feasible to change priorities in the suggestion list, so that local definitions are suggested first. In my experience I have found this would get the first suggestion right in a high percentage of cases, and would therefore save lots of times when programming.

What do you think about this?

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5910
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Can code completion be made contextual?
« Reply #1 on: July 07, 2012, 01:28:56 am »
I just review the code, and see that:
Code
int CodeCompletion::CodeComplete()
adding all the tokens to show, and sort the show items.

If a Token is a local variable(automatic variable), it will have Token->m_IsTemp==true.
So, maybe, we can firstly scan those tokens, and put them in the beginning of the codecompletion list.

I'm currently working on other part of CC, so it is great if you can help us. :)

Add to:
005252
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: Can code completion be made contextual?
« Reply #2 on: July 07, 2012, 02:11:33 pm »
Code
if (result.size() <= m_CCMaxMatches)

Is this line correct?
I think this is a massive bug, because if there are more matches than the limit the list with matches won't be shown at all.
Am I correct?
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9694
Re: Can code completion be made contextual?
« Reply #3 on: July 07, 2012, 02:31:26 pm »
Code
if (result.size() <= m_CCMaxMatches)
Is this line correct?
Yes - look below, the else tree will show a warning asking the user to increase the number of results. So not "nothing" is shown, but a warning.

Besides: The default number of results is really big - if this number is exceeded, it is more likely that something is seriously screwed.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: https://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: https://wiki.codeblocks.org/index.php?title=FAQ

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: Can code completion be made contextual?
« Reply #4 on: July 07, 2012, 02:45:09 pm »
I've set it to 200 in the UI, but this value is ignored, as "/max/matches" is only read, never set.
The config value set in the UI is "/max_matches" as far as I can see.

But again in my opinion this is broken, because the max_matches config variable should limit only the results shown in the listctrl, not the searching phaze.
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9694
Re: Can code completion be made contextual?
« Reply #5 on: July 07, 2012, 03:30:33 pm »
I've set it to 200 in the UI, but this value is ignored, as "/max/matches" is only read, never set.
The config value set in the UI is "/max_matches" as far as I can see.
If that is true, then this is really a bug. :P

But again in my opinion this is broken, because the max_matches config variable should limit only the results shown in the listctrl, not the searching phaze.
Well the point here is: How do you limit? The first, the last...?! Without an information provided to the user we will get a lot forum noise like "my function is not displayed" just because we silently strip the results. Here, instead, we show a warning so the user knows "There were many results, but we didn't know what to show.". I personally like this more... and that's why it is that way.

Of course if you prove me wrong or find a more clever solution - I am open for it.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: https://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: https://wiki.codeblocks.org/index.php?title=FAQ

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: Can code completion be made contextual?
« Reply #6 on: July 07, 2012, 03:55:20 pm »
Of course if you prove me wrong or find a more clever solution - I am open for it.
We can always add an item at the end - "number of matches reached the limit, please increase it to see all matches" or something like this.
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9694
Re: Can code completion be made contextual?
« Reply #7 on: July 07, 2012, 04:52:39 pm »
Of course if you prove me wrong or find a more clever solution - I am open for it.
We can always add an item at the end - "number of matches reached the limit, please increase it to see all matches" or something like this.
You mean "at the end of 16000 items"? ::) Then you can also print it to the hidden debug log or the NullLogger... ;D
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: https://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: https://wiki.codeblocks.org/index.php?title=FAQ

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: Can code completion be made contextual?
« Reply #8 on: July 07, 2012, 05:05:31 pm »
No, at the 201-st item...
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline carra

  • Multiple posting newcomer
  • *
  • Posts: 117
Re: Can code completion be made contextual?
« Reply #9 on: July 07, 2012, 07:53:25 pm »
I just review the code, and see that:
Code
int CodeCompletion::CodeComplete()
adding all the tokens to show, and sort the show items.

If a Token is a local variable(automatic variable), it will have Token->m_IsTemp==true.
So, maybe, we can firstly scan those tokens, and put them in the beginning of the codecompletion list.

I'm currently working on other part of CC, so it is great if you can help us. :)

Add to:
005252
I've read that request description and the approach of presenting the last definitions first could also work. If I am thinking it correctly, the current function's variables are always going to be taken as the last in that context. And it would also be a pretty simple way of making big libraries (such as Windows, OpenGL, etc...) have low priority because they are commonly taken as a base to build custom code over them (and therefore are included BEFORE user definitions).

EDIT: Another possible approach could be to place first definitions parsed the active editor's file. This alternative could possibly be easier to implement (though, not as good).
« Last Edit: July 07, 2012, 09:37:40 pm by carra »

Offline Alpha

  • Developer
  • Lives here!
  • *****
  • Posts: 1513
Re: Can code completion be made contextual?
« Reply #10 on: March 08, 2013, 11:22:59 pm »
If a Token is a local variable(automatic variable), it will have Token->m_IsTemp==true.
So, maybe, we can firstly scan those tokens, and put them in the beginning of the codecompletion list.
This is possible, but requires modification to Scintilla (pending).

(I got distracted from my other work so...) Attached patch implements this.

Offline p2rkw

  • Almost regular
  • **
  • Posts: 142
Re: Can code completion be made contextual?
« Reply #11 on: March 09, 2013, 12:56:00 am »
I implemented such feature: http://forums.codeblocks.org/index.php/topic,17146.msg119037.html#msg119037
but oBFusCATed told me that should be in separated patch so I removed this functionality.

My main goal was to sort list by item token's type, and place items with same type as expected type at top of the list.
But I didn't know how to detect expected type, so I only add criteria that was easier to implement.
« Last Edit: March 09, 2013, 12:58:13 am by p2rkw »

Offline Alpha

  • Developer
  • Lives here!
  • *****
  • Posts: 1513
Re: Can code completion be made contextual?
« Reply #12 on: March 09, 2013, 10:02:59 pm »
Interesting; I must have missed that when it was last discussed.  When you tried sorting, did you also have to modify Scintilla to allow non-alphabetical ordering?

One potential issue with priority sorting, is that if there are too many categories, the user will not see the names of alphabetically similar items close to each other, and may assume they do not exist.

By the way, I have tried CC with your patch (in rev. 8901), and if you type
Code
wxString::app
you get 16 suggestions for append() (and Append()), one for each function overload.  Is this intended behaviour?

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9694
Re: Can code completion be made contextual?
« Reply #13 on: March 10, 2013, 12:52:25 pm »
Attached patch implements this.
I'm afraid the last CC commit broke this. :-(
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: https://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: https://wiki.codeblocks.org/index.php?title=FAQ

Offline Alpha

  • Developer
  • Lives here!
  • *****
  • Posts: 1513
Re: Can code completion be made contextual?
« Reply #14 on: March 10, 2013, 06:18:17 pm »
I'm afraid the last CC commit broke this. :-(
Updated.

By the way, I have tried CC with your patch (in rev. 8901), and if you type
Code
wxString::app
you get 16 suggestions for append() (and Append()), one for each function overload.  Is this intended behaviour?
src/plugins/codecompletion/codecompletion.cpp line 1012:
Code
                static const bool ignoreOverloads = false;
                if (ignoreOverloads)
                {
                    // check hashmap for unique_strings
                    if (unique_strings.find(tmp) != unique_strings.end())
                        continue;
                }
Was this supposed to be user configurable?

Offline p2rkw

  • Almost regular
  • **
  • Posts: 142
Re: Can code completion be made contextual?
« Reply #15 on: March 10, 2013, 10:29:49 pm »
Quote
When you tried sorting, did you also have to modify Scintilla to allow non-alphabetical ordering?
No, I didn't.
Take a look at CodeCompletion::CodeComplete: tokens' indices generated by m_NativeParser.MarkItemsByAI() are stored in separate list called m_AutocompNameIdx. In my implementation this list wasn't sorted only by tokens name but also by other token properties.

Quote
you get 16 suggestions for append() (and Append()), one for each function overload.  Is this intended behaviour?
Yes, it is. Overloaded functions can have different arguments, return value and documentation, so in my opinion they should be displayed as separated items.
But as you can see you can easily change this behaviour.

Wait a sec, I'll generate patch, so you will be able to test it.

Offline p2rkw

  • Almost regular
  • **
  • Posts: 142
Re: Can code completion be made contextual?
« Reply #16 on: March 10, 2013, 10:59:31 pm »
Attached patch is bit dirty because you can change sort criteria only in code, but you can see the idea.
I tell you more: you can even use different criteria in different cases, for example you can detect is autocomplete was opened in global scope and apply different criteria.

Offline Alpha

  • Developer
  • Lives here!
  • *****
  • Posts: 1513
Re: Can code completion be made contextual?
« Reply #17 on: March 13, 2013, 03:46:15 pm »
Overloaded functions can have different arguments, return value and documentation, so in my opinion they should be displayed as separated items.
Maybe a more optimal way would be to only show overloads as separate items if you are in global scope and function argument completion is enabled.
The documentation window could have a link to each of the overloads, and by default, show the overload with the most documentation first.

Quote
When you tried sorting, did you also have to modify Scintilla to allow non-alphabetical ordering?
No, I didn't.
I see.  The autocomp list jumps the selection as you type by searching the list for the given context with a binary search.  If the list is not alphabetized, the popup will often auto-cancel itself because it cannot find an entry (even though the entry exists).  (I had just been curious to see if you had come up with a cleaner solution than mine.)

Offline Alpha

  • Developer
  • Lives here!
  • *****
  • Posts: 1513
Re: Can code completion be made contextual?
« Reply #18 on: March 14, 2013, 01:59:12 am »
I'm afraid the last CC commit broke this. :-(
Updated.
Just thought I should mention, if you value a non-crashing Code::Blocks, do not apply this patch...

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5910
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Can code completion be made contextual?
« Reply #19 on: March 14, 2013, 02:19:49 am »
Quote
if you value a non-crashing Code::Blocks, do not apply this patch
Which do you think cause the crash issue? The concurrently access to the tokentree?
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline Alpha

  • Developer
  • Lives here!
  • *****
  • Posts: 1513
Re: Can code completion be made contextual?
« Reply #20 on: March 14, 2013, 02:29:08 am »
I tried to do some magic with dual purposing the same std::vector sorting it in a partitioned manor so the temp variables would end up first.  Unfortunately, std::sort() somehow (in a pattern I cannot predict) sends invalid wxStrings to static int SortCCList(const wxString& first, const wxString& second) when I do this.