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.

Advertisements

November 5, 2008

KDevelop4: Now with refactoring!

Filed under: Uncategorized — zwabel @ 3:48 am

When I started hacking on KDevelop4 one and a half years ago the goal was clear: Use the duchain architecture, together with my previous code-completion programming experience, to build excellent C++ code-completion in KDevelop4. At that point I thought the duchain was a good representation of the C++ code, and only the user-interface part was missing. I didn’t know that it was still far away from that.

So after some time, it showed that all these goals were very ambitious:
1. Code-completion
2. Intelligent code-highlighting
3. Make it efficient, make the editor usable while the parser is working(A hard task in its own)
4. Simple local refactoring
5. Real Project-wide quickopen
6. Project-wide refactoring

The problem is that the duchain is a very detailed and expensive to compute code-representation. Just a year ago, if you would have let KDevelop4 parse the whole KDevplatform project into duchain, you would have had at a memory-usage of about 3 GB, and it would have taken a sheer endless amount of time. During this year’s summer of code project I tried changing that. The basic “theoretical” structure and API have stayed similar, but the whole backend is nearly rewritten in a way that now allows the duchain to at some point become more efficient than what we had in KDevelop3, and much more efficient than anything a java-IDE like Eclipse could ever get. 🙂

Anyway, given the fact that together with KDevelop4’s C++ support, an overwhelmingly big architecture had to be pulled, my plan for KDevelop release 4.0 was at least finishing goal 1, 2, 3, and 4. Due to the computational expense of the duchain, I thought 5 and 6 were just not realistic. Those were ment for KDevelop 4.1 at best.

During the last months or even just weeks, things have changed dramatically. The key was the idea to allow different processing-levels in the duchain. With a very low processing level, KDevelop will not process anything that is within a function-body, which takes away a large part of the complexity. Interested entities can now just tell the duchain that they want the data for specific files at a specific processing level, and the duchain will check whether the data is available, up-to-data, etc., if it’s not lets the background-parser crunch through the data once again using the correct processing level, and notifies the entity of the completely processed data. Since even in the lowest processing level, we always have the both way #include structure available, this enabled KDevelop to do complex use-searching or refactoring, based on a project that was only processed with the lowest processing level. The refactoring component just needs to walk the inclusion-path back to see all files from where the declarations are visible, then requests the duchain to return all those files in the highest processing-level which includes uses, and then perform whatever action is desired on those.

A few days ago I presented you the use-searching component, which was the first part that profitted from that architecture. Today I’ve spent my whole day creating a duchain based project-wide declaration rename functionality. This is a great feeling, because right from the beginning, this has always been the point farthest away. It requires a high level of precision and reliability from the duchain, which it finally actually seems to deliver. Don’t expect it to be perfect yet, since it’s largely untested, but expect it to be there. 🙂 One great thing about this is that this whole thing is language-independent, so it may work with any language that builds a DUChain, although we aren’t planning to ship anything else than C++ in the near future.

So here we go:
The functionality is accessibe through the context-menu, or through any other many that handles a Declaration. Just right-click the name of a Declaration in the editor window, and click “Rename …”.

pic1

pic2

pic3

Now you see a dialog that has two tabs. In the left tab, you see the uses-widget that I’ve presented last time, somewhat polished using ideas from a mockup posted as a comment to my last blog entry. It allows you getting an overview of the actions that will be performed, since it exactly shows the places that will be changed. In the second-tab there’s a html navigation-widget, that allows you seeing and navigating all kinds of informations about the declaration you are just renaming. At the top you see a line-edit, into which you can just write the new name, hit “replace”, and KDevelop gets going.

Currently you should not try this on your most central classes, because the computation may become very slow.

So now the most demanding tasks on C++ support are finally done. In the next time I’m going to try making it faster, fix bugs, and add a few yet missing smal code-completion features. So this area is on target for the 4.0 release.

Since my last blog touched off a lot of discussions about the UI, I’ve got enough of that, so please no comments about that area. Just one thing: We will try find a balance between feature discoverability, feature richness, and simpleness. Be sure that the count of menu-entries will be lower than on the screenshot, the count of default docks will probably be about the same. Now the real problems we still have to fix is project-management, building, debugging, etc. so if anyone wants to help, jump right on board. 🙂

In my next blogs, I will present more C++ features that are available in KDevelop4, and that I could not live without. 🙂

November 3, 2008

KDevelop4: Find all uses of “…”

Filed under: Uncategorized — zwabel @ 4:11 am

Hi planet! I’ve been registered a long time ago, but sadly this is my first post here. I’ve been too busy with getting “real” stuff done on KDevelop.

One short statement about Qt Creator: Imo they seem to have nearly the same goals KDevelop4 has: Modularized, platform-independent, light-weight, C++ oriented, with good Qt support.. why do they have to re-invent everything? I would have preferred them putting some resources into KDevelop4 instead. One thing is for sure: Their app may be stable, but feature-wise they are far behind, although I am biased to see this mainly from a C++ support perspective.

But now to KDevelop:

In KDevelop4, we have a language-independent structure for abstract code-representation called Definition-Use-Chain, that has been invented by Hamish Rodda a few years ago. When I started hacking on it soon 2 years ago for my Google Summer of Code project, he had stopped hacking on it for quite some time, and it was in a state you can call “experimental” at best. Nearly 2 years of hacking have passed, which were really hard years of instability, without the target visible on the horizon, without even knowing whether this stuff I’m working on even just “can” work out. Hamish came back about a year ago, and since then has been a pushing force on KDevelop4 again, also helping me with the kate problems that I really didn’t have any insight to. Anyway it was a monster-task. I often had to work on 3 places at the same time: kate, kdevplatform(duchain), and kdevelop(C++ support), all with tons of code that was until then exclusively used by KDevelop’s until then unfunctional C++ support, which means that lots of this code was unfinished and unstable.

The good news: All the pain is starting to pay off. 🙂 This April we had our Developer meeting in Munich, and since then the development has heated up, and I think we’re on track to get a stable release out within the next half year.

I have very high demands in the C++ support, and now they are starting to be satisfied. KDevelop4 has reached a state now, that I actually finally can suggest interested people to try it out. It’s important that you have recent kdelibs + kdevplatform + kdevelop, because all of them have seen some quite important changes in this area in the last weeks.

Since we got new competition from a direction from where I actually would have expected support instead, I feel motivated now to present you some of the nice features KDevelop4 has, so we don’t lose too much of the public interest.

The last days I have worked hard on finishing the basics for refactoring and use-searching, aka “find all calls of this function”, and got that ready. I’ve put it into a re-usable base-class, so functionalities that need this backward-searching are very easy to implement now. What mainly comes into mind is intelligent renaming/refactoring and call-graphs, which is just a matter of writing a user-interface for it with this in place.

Also I’ve continued polishing the widget to show this information.
Here you’ve got a nice screenshot:
Screenshot of KDevelop4 with the uses-widget

At the top you see the editor-window, and at the bottom the code-browser which currently shows the uses of KDevelop::DUContext. The buttons are used to expand/unexpand the uses in the file. Then each file is split up into “Contexts”, which are functions or class-declarations. This allows you to get a fast overview in what place the use occurs. A tooltip over the line shows also the surrounding lines of eeach use, and clicking on the link on the left side jumps to the use directly in the editor window.

Next time I’m going to present you another nice feature of KDevelop4. 🙂

November 12, 2007

Hello world!

Filed under: Uncategorized — zwabel @ 3:56 pm

I’m a 25 years old student of Computer Sciences at RWTH Aachen, and a big Linux and KDE Fan + Developer. You will most probably know me from the commit-logs. It will soon be 2 Years that I’m working on KDevelop, and in future I will share my thoughts and ideas using this channel.

Blog at WordPress.com.