Zwabel’s Weblog

November 11, 2008

C++ Code Completion rethought: KDevelop4 in action

Filed under: Uncategorized — zwabel @ 3:25 am

From all the discussions I have had, I have learnt that there is two different types of users for Code Completion. For the first type, the code-completion is only there to speed up their typing. They think they don’t need to know what kind of items they are actually dealing with, because they think they know the library they’re working with. Then there is the second type: They want to use code-completion as a kind of inline documentation, for checking along the way that what they’re writing is actually correct, and additionally to speed up their writing.

I count myself to the second group. I want all the useful information I can get. If I’m not interested, I can still ignore it, but in most cases even if you’re knowing exactly what you’re working with, it’s still a better feeling to not only assume that what you’re writing is correct, but to know and see it.

KDevelop4 code-completion is here to fulfill these extended needs. Right when I started working on it more than a year ago, I had the vision: I want _all_ the information, wherever I am. When I’m watching something in the completion-list and wonder what that strange return-type is, I want to be able to find out easily, no rocks in my way please.

So one of the first things I did to the completion-list was allowing to embed arbitrary widgets into it, and to allow interacting with those widgets using the keyboard.
Additionally to that, the completion-list can always show some additional minimal information with each selected item. The place that information is shown follows the selection in a way that keeps the annoyance to a minimum, by never letting the item you’re currently focussing with your eye change its position.

Another advanced feature that I wanted to have was automatic matching of completion-items to the argument-hints. Using this, KDevelop should in many cases be able to predict what item the user is going to pick, and further speed up his writing. Since I had already implemented a C++ type-conversion framework based on the DUChain following the C++ standard in KDevelop, this mainly just needed a nice way of being presented. In the completion-widget each visible item in the completion-list is matched against each overloaded version of the called function, and the match-quality is indicated by blending the background-color between dark blue(worst) and light green(best). Additionally the list of best matches is shown at the top of the list.

But there’s more to kate’s completion-widget that have made it a really complicated yet powerful beast. When there is such an amount of information as you can show in C++ code completion, then you need a special way of presenting that information to get a usable result. Some items in the list are extremely long, some are very small. Still you want to be able to see all the information of all items. There was no way around making the completion-widget dynamically resizing itself and its columns, based on the currently presented content. This has been a problem for a long time, causing all kinds of flickering and uglyness.

During the last days I have taken an exact look at he actual code-completion again, trying to fix it’s most visible problems, give it some polish, and fixing pure bugs on it. Now I’d say that the code-completion is in a good shape, so here come the screenshots that might motivate you to try it out. :-)

In this screenshot you can see how the type-matching automatically suggests the values of an enum while calling a function that takes that enum. Above you see the overloads of the function currently called, and how well the item selected in the completion list matches each of them.
Code completion and enum suggestion

Next you can see another case of argument-matching. Since KUrl has a constructor that takes QString, QString values are highlighted in dark green, while KUrl values that don’t require a conversion are highlighted in light green. Here you can also see the embedded navigation-widget in action. To show it, just push the “shift” button while the completion-list is open. Then you can navigate within it using SHIFT+(left/right/up/down/return).
Operator matching and embedded widget

This is a new feature I’ve implemented in the last days, and it’s a real life-saver, although probably quite common in IDEs: Code-completion within a class-body shows all virtual functions of parent-classes that have not been overridden yet. When the item is executed, a full virtual function declaration is created.
Override

Here you see the previous feature’s brother in action. When code-completion is invoked within a file, and that file’s header-file contains function-declarations that don’t have a definition yet, “Implement …” actions are shown at top of the completion-list. If such an action is executed, a complete implementation body is inserted.
Implement

The code-completion is really feature-rich. It works well with templates, and since it’s built on the duchain, it shares an architecture that is going to be improved permanently, so it can only become better. It may still contain some bugs, but it’s already far ahead of what KDevelop3 or many other C++ IDEs can deliver. It also contains some special goodies that I might cover in another blog. :-)

Last but not least, since I told you earlier about the 2 user types, and to prevent bitching from purists, I’ve added an option a few days ago to get a “simple” completion, that approximately matches what you get from Qt Creator, here you see it in action:
Simple Completion
As you see the item currently selected in the completion-list is also highlighted in the document, which creates a visual connection between the list and the editor.

Btw. implementing this simple mode needed changing about 15 lines of code, so this is not a reason to create an own IDE. ;)

Notice: If you want to try out, use the most recent kdelibs and the most recent kdevplatform and kdevelop, since I checked in some important fixes right before writing this blog entry, after breaking some stuff yesterday.

About these ads

28 Comments »

  1. Just amazing!!. I’ve always wanted to have something like this! I’m a very forgetful person so I have to switch from the derived class to the parent over and over to see what I’m still missing.
    I already downloaded KDevelop’s src, in order to use it, say with KOffice ;), I should import the Project right? But I get no completition (may be i need to let it parse), what should i do?.

    Comment by Carlos Licea — November 11, 2008 @ 4:39 am

  2. I forgot to mention that I think the colors should be changed to something a little darker, because the current colors might be a little tiring to work all day long, other than that wonderfull.

    Comment by Carlos Licea — November 11, 2008 @ 4:49 am

  3. Really impressive David! – You’ve been slaving away at this for a long time, I bet its nice to see all the pieces come together.

    Comment by Robert Knight — November 11, 2008 @ 7:56 am

  4. Awesome stuff.
    Minor suggestion: please use a style arrow (PE_IndicatorArrowRight, PE_IndicatorArrowDown) instead of the go-{right,down} icons, as those icons have another meaning that doesn’t apply here. (And in this context, the style arrows should also look better than the icons.)

    http://doc.trolltech.com/latest/qstyle.html#PrimitiveElement-enum

    Comment by Jakob Petsovits — November 11, 2008 @ 8:08 am

  5. Nevermind I was able to found the option (d’oh) to build the whole project on opening… seems that is not saved though (!)… is like reompiling all KOffice (or at least half the work since no code is generated nor optimision are made) every time I open KDevelop(!!).

    Comment by Carlos Licea — November 11, 2008 @ 8:21 am

  6. It’s really cool to see you blog this often! And your posts are very interesting. Keep it up

    I have to second the first comment from Carlos. When I import a project in eclipse-cdt4, I have code completion out of the box for every dependency included. In kdevelop I always had to go to the project settings, enable databases and such which is from a users perspective a bit of a hassle

    Comment by Benjamin Schindler — November 11, 2008 @ 9:05 am

  7. Looks great, is it fast though? Features like autocompletion are really dependent on speed, if it takes >1 second for this thing to come up that would significantly reduce its usability..

    Comment by bsander — November 11, 2008 @ 9:39 am

  8. This really looks excellent and I can’t wait to start using it! Does the completion information (DUChain?) understand boost::shared_ptr references, eg. for “shared_ptr a;”, will it complete the methods of A on “a->”?

    Comment by Rob — November 11, 2008 @ 12:27 pm

  9. @Carlos Licea: You don’t need to let kdevelop process the complete project just to get code-completion, that should work anyway. The important thing is that it finds the headers.

    It doesn’t re-build the whole information on each startup, unless it crashed in a bad state while KDevelop was run before. Else it just checks whether the information is still up to date. This updating still takes way too long for big projects, it hasn’t seen any optimization yet.

    Yes the colors maybe should be a bit more passive, we’ll see.

    Comment by zwabel — November 11, 2008 @ 12:32 pm

  10. @Robert: You bet, that’s exactly how I feel. :)

    Comment by zwabel — November 11, 2008 @ 12:33 pm

  11. …that should be “shared_ptr&ltA&gt a;” (missed the escape codes)

    Comment by Rob — November 11, 2008 @ 12:34 pm

  12. @Benjamin Schindler: KDevelop4 doesn’t have much in common with KDevelop3. Especially the language-support is a complete rewrite. I too hated having to set up completion databases. KDevelop4 automatically processes all the included headers, and gives code-completion right out of the box.

    Comment by zwabel — November 11, 2008 @ 12:35 pm

  13. @bsander: I’ve worked hard on making it faster, and now it’s down to about 500 ms on my not highend machine. Imo it’s still too slow, but very usable already.

    @Rob: Of course, that shouldn’t be a problem at all.

    Comment by zwabel — November 11, 2008 @ 12:36 pm

  14. That’s great, especially as Doxygen can’t handle shared_ptr.

    Comment by Rob — November 11, 2008 @ 12:39 pm

  15. I’m not yet a KDevelop user, but this looks awesome. What’s the state of automatic refactoring of C++ in KDevelop? Can one rename methods, types etc. across a project safely, without a blunt search/replace? If so, what facility is the KDevelop using to parse C++ into a symbolic representation?

    Comment by Tom — November 11, 2008 @ 1:15 pm

  16. @Tom see my both earlier blogs ;)

    Comment by zwabel — November 11, 2008 @ 1:24 pm

  17. Ah, awesome! The ability to do basic but reliable refactoring in C++ is something I really need for some ugly code I’ve taken charge of. Very excited — now I’m just hoping that the Vim-mode for Kate is actually happening. Any idea on that?

    Comment by Tom — November 11, 2008 @ 5:40 pm

  18. This is amazing. After being a long-standing Vim user, I started a job requiring me to use Visual Studio. Intellisense made my life so much easier, and when going back to Vim to hack on KDE I really missed it. But this looks an order of magnitude better than Intellisense.

    Comment by randomguy3 — November 11, 2008 @ 6:19 pm

  19. [...] C++ Code Completion rethought: KDevelop4 in action From all the discussions I have had, I have learnt that there is two different types of users for Code Completion. For [...] [...]

    Pingback by Top Posts « WordPress.com — November 12, 2008 @ 12:28 am

  20. It’s me yet again! I just can’t stop poking KDevelop completition, it’s so fun!. Ok, I have another question, I work for, say, project Foo. Foo depends on kdelibs, of course kdelibs is installed and it’s source is mantained in another directory, hence the includes cannot be found as they are resolved by CMake and then handled at compile time (guess, correct me if i’m wrong please)… so how do I let KDevelop know that my project depends on that kdelibs in that folder outside my Foo folder?.

    Comment by Carlos Licea — November 12, 2008 @ 8:07 am

  21. nice work. though the presentation still needs some improvement. colors where allready said – just remember to make them configurable. some people like dark backgrounds when programming, so one solution for all will not work.
    what about the huge arrow icon? i think it should be changed to either the treeview [+]-widget, or to the kate code folding mark (the triangle you see in the background).
    having a such dominant icon on each row makes it much more cluttered than it realy is.

    Comment by AC — November 12, 2008 @ 9:05 am

  22. @Carlos Licea:
    Are the includes not found? Generally, KDevelops CMake support is supposed to resolve the include-paths. Sometimes though it fails at doing that, then setting up a build-directory can help, which will cause an additional fallback using “make” to be used.
    Mapping between installed and source-files is not implemented yet…

    @AC: I don’t think the colors should be configurable, kate already has enough configuration options. Rather I think the background-color should just be “tinted” in a way that it becomes “more green” or “more blue”. That’s not done yet though.
    I agree about the icon.

    Comment by zwabel — November 12, 2008 @ 10:13 am

  23. Hey,

    I’ve been using KDevelop for some weeks now and just updated the newest from trunk and recompiled it.

    I have a class Rasterizer

    template
    class Rasterizer { ….

    that implements a bunch of virtual functions. Then i have (among others) a specialized class LineRasterizer that derives from Rasterizer

    template
    class LineRasterizer : public Rasterizer { …

    and which defines all of these virtual functions. Then i also have a class TriangleLineRasterizer that derives from LineRasterizer

    template
    class TriangleLineRasterizer : public LineRasterizer {

    and which redefines a few of the functions responsible of the backend logic for a LineRasterizer so it acts as expected for a TriangleLineRasterizer, but 99,9% of the code is the same for the 2 classes.

    When i some where use these 2 specialized Rasterizers

    TriangleLineRasterizer* triangle_line_rasterizer;
    LineRasterizer* line_rasterizer;

    triangle_line_rasterizer = new TriangleLineRasterizer();
    line_rasterizer = new LineRasterizer();

    and type “triangle_line_rasterizer.” it is correctly changed to “triangle_line_rasterizer->” (as it is a pointer) but the code completion doen’t have a clue about what member functions and types this object has. Though if i write “line_rasterizer.” it becomes “line_rasterizer->” and the code completion is full of information about this object.

    I admit to not knowing if this is total misuse of c++ but it compiles and most of the code is handed out so i can’t do much about it.
    But as far as I see this is an error and the code completion should show all the function definitions of “base” class Rasterizer and all the extra functions exposed by the derived class LineRasterizer and also all the functions exposed by the derived class TriangleLineRasterizer?

    Comment by Jesper R. — November 21, 2008 @ 4:36 pm

  24. Another small thing i have noticed. A habit from other IDE’s is that I keep typing the name of an object while i wait for the code completion to popup. But here i have to stop and wait a few seconds before it show itself and then i can make my selections.

    I recon this is a style of choice but unless you have a good argument why it shouldn’t just show itself as soon as “manageble” (maybe after the first 3 letters so there is a small “contraint” on the number of things to be shown, as it is obviously faster to show a list of 10 items than 1.000 items.) then I think you should at some point look at this.

    Comment by Jesper R. — November 21, 2008 @ 6:26 pm

  25. Cool with the new? feature, where the code completion suggests that a file be added to the include lists when trying to access members of a class not already “known”/included from some point.

    Comment by Jesper R. — December 14, 2008 @ 2:00 pm

  26. Wow, I am absolutely _amazed_!

    This certainly blows every other IDE out of the water, MSVC will have a run for it’s money.

    This is awesome, I will run trunk now just to use this feature, I hope it’s somewhat stable. Not to mention, it uses the kde4 scheme, so it really beats kdev3. I was using kate to do kde programming, but I have to say, if this is as good as it sounds (stability, especially), I will love it.

    Especially since all I really need is the code completion and the text editing, since I usually just use Konsole for building/updating svn.

    Comment by Shaun Reich — January 25, 2009 @ 3:06 am

  27. Thanks for your article, but but could you the next time just upload your screenshots to WordPress instead of Imageshack? Those “Accept cookie from http://img219.imageshack.us?” questions are nasty.

    Comment by Markus — May 3, 2010 @ 8:55 pm

  28. [...] 4 (changed recently, check out some time soon: Link ). source: http://www.kdevelop.org/mediawiki/index.php/FAQ#Code_Completion_FAQs How to enable it: A [...]

    Pingback by C++ code completion for KDevelop 4 and Emacs » Philipp Klaus's Computing Blog — February 8, 2011 @ 7:33 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Rubric Theme. Create a free website or blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: