Zwabel’s Weblog

June 21, 2009

KDevelop4 UI: Areas, Working Sets, etc.

Filed under: KDE,KDevelop — zwabel @ 9:58 pm
Tags: , , , , , ,

General Progress
A lot is happening in KDevelop4 these days. Now it’s nearly already 2 Months ago that we had our developer meeting in Ukraine. We had a lot of fun, although for me the trip started two days late. I didn’t get my passport in time, damn. But once there, I got quite productive. Since I have limited time these days, that hack sprint motivated me to touch the one big outstanding architectural issue yet existent in the duchain. I knew it was a painful mammooth task, that’s why I kept my fingers off it for a long time.

I have implemented a special reference-counting mechanism for the duchain that uses the standard convenient C++ way of achieving the thing: In the constructor of an object, increase a counter, and in the destructor of an object, decrease it again. Now finally _everything_ in the duchain is reference-counted, even extreme light-weight objects like “IndexedString”, which is nothing more than a wrapper around an integer representing a string.

That object is used everywhere, and since the reference-counts are disk-persistent, increasing them is not as cheap as usually. So here’s the clue: It is only done when the memory-area the constructed/destructed object is in is actually marked as a “disk persistent” area, that will be stored to disk later, or is already on-disk. That means that it has near-zero runtime overhead for most of the object usages. During shutdown the objects are all sweeped, and the ones without a persistent reference-count are cleared away. The most complicated task was getting all the already existing duchain storage schemes work nicely together with such reference-counted containted objects.

I got it ready about 1 week after I was home again. Two weeks later it actually was stable. Anyway, it was worth it. 🙂

Apart from this architectural thing, the focus is mainly on polishing now. Tons and tons of bugs and crashes were fixed.

Apart from bug-fixing, I’m trying to use my limited time to move KDevelop4 forward in some of the other areas that need it most. After all, a good C++ support alone is not enough of a selling point for an IDE, and I have some ideas about how KDevelop 4.0 should look. Also, I sometimes feel the intense need to do something “creative”.

Areas
Now KDevelop4 has a feature called “Areas”. From what I know it’s comparable to the Eclipse “Perspectives” feature with some slight differences.

Each area contains a distinct set of tool-views, and toolbars, tailored for a specific task (Currently we have “Test”, “Debug”, and “Code”). In difference to Eclipe Perspectives, areas may also contain different sets of files. We actually thought about renaming them to “Perspective” for consistency, but then again “Perspective” implies looking at the same thing just from a different direction, while an “Area” is actually a different working-space, like a different table, where you use different tools to work on different items. So we’ll probably stick with this terminology for now.

Before the hack sprint, there was a little dropdown list in the toolbar to switch areas. But in our opinion this was not very usable, given that we want areas to be a central part of our UI concept. You could never see what other areas there was, and you always needed one click too much to switch them. So we discussed different mechanisms for area-switching. My initial idea was quite simple: Use tabs. It’s the concept that fits best. Just some additional non-removable tabs somewhere at the top, and areas would be totally intuitive and logical to use. The others were a bit more in favor of using separate toolbuttons, and after I wasted a few hours trying to hack something together with tabs, I gave it up. Alexander Dymo then created area-switcher toolbuttons, probably similar to the way Eclipse does perspective switching.

However a few weeks after being home again, I started feeling that these toolbuttons don’t work. How is it intuitive that you click a toolbutton, and suddenly you have completely different files open? And how could we automatically switch the area when we start debugging, without making the user crazy? Also, toolbars are generally “optional”. And if we want to make Areas a central concept, we cannot make the area-switching optional. We shouldn’t give the user a chance to break his UI. 🙂

So I started again doing mockups about how the UI could look, here’s the evolution:
https://zwabel.files.wordpress.com/2009/05/mockup.png
https://zwabel.files.wordpress.com/2009/05/mockup.png
https://zwabel.files.wordpress.com/2009/05/mockup3.png
Niko:
http://www.vivid-planet.com/upload/vertical-tabs2.png
Me again:
https://zwabel.files.wordpress.com/2009/05/vertical-tabs3.png
And the final version:
Mockup
Just by the way you may be wondering why there suddenly is so few wasted space: On the hack sprint, Alexander Dymo removed both status-bars, moved the editor-information(line+column) into the file-tab line, and moved status indication in the bottom toolbar into the bottom dock switcher, so both status bars are gone.

If you’re wondering about the additional highlighting of the current area tab: We were a bit worried that tabs in the top-right would be somewhat out of user focus, the user might not notice when the area automatically changes, and that it might also be a bit confusing having multiple levels of tabs in the same user-interface. The highlighting moves the thing more into the user focus so changes are directly recognized, increases general awareness, and makes it generally look like a different widget then the document tabs, which reduces confusion.

Now after all the mocking, which I actually just did to start some discussion and gather some ideas+opinions, I suddenly found the hidden QMenuBar::setCornerWidget function, which actually allows implementing the last mockup in a relatively clean way. I sat down for an evening, and ended up with exactly what you see on the last mockup. It needed some additional hacking to get the added highlighting, to have the icons on the left side while having a general right-to-left layout, and to make the tab separator line fade out to the left, but it works, and it is solid. And at least my personal experience shows, that this is very usable and very intuitive, while not wasting a single pixel.

So far so good.

Working Sets
A few years ago, shortly after I joined the KDevelop project, there was a lengthy discussion about tabs in general, and whether/how they could be made useful. The problem: From a specific count of documents upwards, tabs are completely useless to get an overview. And due to the easy navigation in KDevelop, it easily happened (and still happens) that suddenly 20 documents were open, making tabs completely useless. At the beginning of KDevelop4, some developers were tired of the uselessness of tabs, and completely removed them in favor of a dropdown list. However me and some others couldn’t live with that. The problem: You replace something that sometimes becomes useless with something that is always useless. There has always also been a document list toolview, that shows all currently open documents. Those who don’t want tabs probably use that. However, as I know from using kate, even a document-list becomes nearly useless from a specific count of documents on.

So at that time, I had the idea that instead of trying to create an utopic widget that allows easily managing an infinite amount of open documents, just allowing the user better ways of managing the set of documents he is currently working on, so he can easily keep the count of open documents in a tab-manageable area. My idea of achieving this at that point was using working sets. A working set is a specific set of files, the files you really work on. For me, when the open document-count grows into an unmanageable area, that usually comes from either working on multiple problems at the same time, or from a lot of browsing through different documents. The core development activity is usually only focused on a relatively small set of documents. A working set allows grouping small lists of documents together, archiving and restoring them, easily merging, splitting, duplicating, and easy moving of files from one working-set into the other. Such a mechanism would allow keeping the count of files manageable: As soon as you start working on another task, just close the whole current working set, and start your new task with a clean list of documents. As soon as you want back one of the old files or the old working-set, just restore it. Paired with a good user-interface, this might well create a new and more efficient paradigm of working.

My idea was that each working-set would be represented by a unique icon somewhere in a permanently visible part of the UI, so you can easily access them.

However since I was very busy with C++ support, I never came back to this idea. But now suddenly, that I was doing that area-switching stuff, it came back into my mind:
– Areas have different sets of documents, so if they should be really easily usable, it should also be easy to transfer files from one area into the other.
– Due to the area-tabbar I have added, there suddenly is a perfect place where those working-sets could live: At the left side of it.
– KDevelop4 also supports multiple main-windows. How to synchronize or move documents between them? Working-sets would make it a breeze.

Combined with the advantages above, this just created too much temptation for me not to try it. So within the last weeks I piece by piece created full working-set support in KDevelop4.

The hardest part was adapting the background management part of KDevelop4’s UI framework, and until a few days ago it suffered from frequent crashes. But now it seems to finally be stable, so I can announce it for you to try out.

How the UI looks now:
kdev4_ui_working_sets
At the left side of the area-switcher, you see the icons for all existing working-sets. Currently that is only two. The icons are taken from several other KDE Applications. In long term, we need a unique set of icons that are totally association-free in the software world for usage in the working-sets. But for now, the most important thing is that each set has a different icon. The area-switcher itself shows the currently active working-set within the switcher, so you see which working set is active in which area. Also there’s an additional working set icon left to the document tabs, to make clear that they belong to each other, and make it yet a bit clearer and easier to use.

When you click onto one of those icons, the clicked working set is loaded into the current area, or it is closed if it is the current set, allowing you to create a new one by opening a new document.

kdev4_working_set
When you hover a working set icon, you get a very useful tooltip, showing you the contained documents, allowing you to load or unload single documents with one click, and to delete or close the entire working set.

kdev4_working_set_2

kdev4_working_set_3
This is how it looks when you’re in the debug area, with a different working set open than in the code area. Working-sets are fully synchronized, so if you activate the same working-set within both areas, the areas transform into Eclipse perspectives, as they both always contain the same documents.

KDevelop4 Beta4
On Monday KDevelop4 will go into a mini-freeze with only bugfixes allowed, before releasing the next beta middle of the week. We want to make sure to release a high-quality and stable beta. We have released beta3 just a week ago, but that was a bit premature, as it doesn’t contain some features that we want feedback about, and there were quite a few important last-minute bug-fixes that we would have liked to add, but the release process was already a bit too far at that point.

Advertisement

March 13, 2009

Really rapid C++ development with KDevelop4

Filed under: KDE,KDevelop — zwabel @ 8:52 pm

Code Assistants
When developing for a statically typed language like C++, there usually is quite a bit of redundancy during the development, especially when creating a completely new piece of code. A powerful IDE with deep code understandic theoretically could save a significant amount of the writing work. My goal with KDevelop4 is to allow the user only to concentrate on the “content” of the code, without wasting too much time with creating or adapting declarations in several different places.

To reach this goal, code-completion is not enough. Sometimes it is not possible to properly guess what the user wants to do during typing, but once a statement is completed, it becomes clear. Also the completion-list is not suitable as a user-interface for everything.

During the last weeks I have implement an Assistant architecture within KDevelop. In general it is kind of similar to the bulbs or paperclips known from several office applications, with the main difference of actually bein useful. 🙂 An assistant can watch the happenings in the editor, duchain, etc., and pop up a non-intrusive popup with some keyboard-accessible options as soon as the assistant thinks it can do something useful for the user.

Declarations/Definitions
The first assistant I implemented already more than a week ago was one that could automatically adapt changed function-signatures of declarations and definitions. Personally I hate having to do exactly the same thing twice, thus this thing compes very handy. As soon as you significantly change a definition- or declaration-signature, you will see this:
signature_assistant_11
At the bottom you see the assistant popup. Every popup has an associated action with a number, and you can execute the action using the ALT+Number combination. So you will get this effect:
signature_assistant_2
This is already a quite useful assistant, since it saves you from a part of C++ that I personally sometimes find a bit frustrating. But not any more. 🙂

Automatic Declaration Creation
There is other much more significant types of redundancy when programming for statically typed languages. One such example is iterator names. Why do I always have to write out their name completely? Even with code-completion, it sucks, since the iterator variable type is logically completely determined alone by the value you assign to it. Now with KDevelop, you can save a lot of this. If the type of the variable is determined by the assignment, just don’t write the type by yourself, but let the IDE do it for you:
local_declaration_assistant_1
Just push ALT+1 and get this:
local_declaration_assistant_21

Now when you’re designing an algorithm, you can just write as if you were writing python, and let KDevelop create the variable declarations for you:
variable_declaration_assistant_1
The assistant gives you this:
variable_declaration_assistant_2
But it gets even more interesting. If you try calling a function that does not exist yet, you will get this option:
function_declaration_assistant_1
And the assistant will give you this, notice that even the return-type has been correctly matched to the context:
function_declaration_assistant_2

This also works within the local class:
local_function_declaration_assistant_1
Here the result, notice that the return-type is automatically a reference when you assign something to it in the call:
local_function_declaration_assistant_2
Together with all the other conveniences of KDevelop4, like automatic adding of includes, automatic creation of function-definitions, a class-wizard that correctly places all the includes and writes added files into the CMakeLists.txt, the Qt Documentation Integration, Code-Browsing, etc., KDevelop is a really productive IDE.

Development Update
This is one of the few large features that I yet wanted to implement before a release, now there’s not many major features left on my todo list. Although I’m quite sure I will get some more ideas, the next major task is improving the usability, killing all the little bugs, and improving the performance and scalability of the duchain store so it doesn’t get slow once some size has reached.

The other parts of KDevelop are doing ok, but unfortunately the debugger still hasn’t made it into a usable state, it’s the one big gap that’s still there in KDevelops functionality.

March 6, 2009

Typedefs in Templates, and Code-Completion

Filed under: KDE,KDevelop — zwabel @ 2:28 pm

Sometimes you have to decide between being “correct”, and being user-friendly.

Also, sometimes you have to do one painful change with many regressions, to reach an ultimately better state.

I hope I had to do the last such step before the stable KDevelop release(Though you never know). I have changed the internal representation of the C++ DUChain, so typedefs spawn custom types, instead of being just pointers to the targets. This is not exactly what the C++ standard says, but this means that KDevelop will no more replace std::string with “std::basic_string<blah bla>” if you implement a function or do other simple refactoring stuff.

There is some problems with generally doing this though, because for example in a template container like “std::list”, you want the types in the completion-list not to show “std::list::reference_type”, which also is a typedef, but instead the type you gave to the container. So how should this be done to be most userfriendly, while still staying correct enough?

I’ve implemented this simple logic for the completion-list: If the typedefs target type recursively contains less template parameters, show that one, else show the typedef type. I’m quite sure you can construct a case where this does not work as expected, but for 99% of all cases, it should show the nicest thing that could be shown.

But there is other problems with representing typedef types as real types. The C++ standard explicitly states that typedef types given as template parameters, spawn exactly the same template instantiation as the typedefs real type. For that reason, a typedef has to be resolved before doing any template stuff. If this would be done, you as well be back to “std::basic_string<bla bla>” as return-types in “std::list<std::string>”, so a decision had to be done here.

I have decided to spawn different templates for typedef types, so that the user will see the nices possible representations.

And here the glorious results:
typedef_1

typedef_2

Unbelievable that such a simple-looking thing can be so painful. 🙂
The good thing is: After some time of finding all the regressions, KDevelop is better than ever!

February 13, 2009

KDevelop4: Creating a Qt slot, the cool way

Filed under: KDE,KDevelop — zwabel @ 10:52 pm

In an earlier blog-post I’ve already written about automatic signal/slot matching and completion(See this). The code-completion box shows you the appropriate connectable signals and slots, and also shows exactly what signals match what slots. Now what if you have a signal, and you know want to connect to it, but you don’t have a matching slot yet? In the last days, I’ve implemented a new feature, that allows automatically creating a matching slot with the typed name, exactly matching the signature of the connected signal.

See this example:
signal_slot_completion

A signal is being connected, but there is no perfectly matching slot(Or maybe you want another one). Now you can just continue typing, and you will see this item in the list:
signal_slot_completion_creation
Now when you execute this completion-item, KDevelop will automatically create the slot within the declaration of the local class, and will nicely complete the current connect(..) call, pointing a the new slot:
signal_slot_completion_creation_ready
Here you see the declaration that was created within the header-file:
signal_slot_completion_creation_ready_declaration

Together with the implementation-helpers, this will allow really rapid programming: Just pick your signal from somewhere, let KDevelop create the declaration and finish the connect(..), go to the place in the source-file where you want to implement the slot, and let the implementation-helper create a stub declaration for you. 🙂

Development update
Except for this, I’ve mainly done smaller bug- and crash-fixes since my last blog.
One interesting development is that Hamish Rodda has started fixing up our old version of the integrated debugger, which is nearly a straight port from KDevelop3, so we might have a usable debugger soon. He’s doing it in a branch. The debugger that is in trunk has some additional interesting features like hover-tooltips, and internal refactoring has happened since the original maintainer considers the code of the old debugger a mess, but suffers from the fact that it doesn’t properly work, and seems to be quite a bit away from it, at least that’s what those who tried to fix it found out.

February 4, 2009

KDevelop4: Automatic include-directives and forward-declarations

Filed under: KDE,KDevelop — zwabel @ 1:09 am
Tags: , , , , , ,

Missing Include Completion
C++ is a great and powerful programming-language. Yet it has the downside against some other languages, that you always have to deal with include-directives or forward-declarations before you can use a class.

This is a factor that often motivates me not to create too many different source-files, although design-wise that would make sense. Wouldn’t it be nice if you could just start hacking without caring about the whole visibility stuff? Especially when you have to do the same includes again and again, and already know the library you’re using and it’s classes, this is nothing more than an annoyance.

I had implemented a feature to automatically add include-directives within KDevelop 4 about a year ago, but it wasn’t as comfortable and useful as it could be. During the last days, I’ve taken the time to polish up this feature so it’s worth a blog-post.

The whole thing is based on the DUChain, and it respects all declarations from within the global duchain store. This means that from the moment on that KDevelop has processed a source-file, you can start just using the declarations from within that file from anywhere. Whenever you type something and the completion-list does not offer any completions, which means it’s not visible, then the missing-include completion will start searching the duchain store for matching declarations, and when it finds some, it will offer you right within the completion-list to automatically add an include-directive for you.

This works in many different situations: If you try calling a function or constructing a class, template-instantiate a class, if you try to access the contents of a class that is either unresolved or has only been forward-declared, or if you just type in the name of an arbitrary declaration.

Sometimes however when writing header files, you do not need the whole class-definition but rather just a forward-declaration. From today on, the very same list will show you an entry to automatically add a forward-declaration for the typed class for you. This even works with template-classes, and it correctly respects namespaces, creating namespace declarations around the forward-declarations as needed.

Together, under the circumstance that KDevelop already knows the classes you are working with, this frees you of one annoying part of the hacking.

Examples

This is what happens when you try calling a known function that has not been included yet:
missing_include_completion_function_call

And this is the effect you will have when you push the up-arrow and execute the “Add #include …” action:
missing_include_completion_function_call_result

This is what happens when you simply type the name of a known class:
missing_include_normal_completion1

And this is what you’ll get when you pick the “Add forward-declaration” action. A fully valid forward-declaration was inserted. Well, apart from the fact that std::allocator is not defined. 😉
missing_include_normal_completion_result

Now std::vector is forward-declared. But what if you actually try using it? KDevelop will notice it, and will offer you including the correct header for being able to use it:
missing_include_member_completion

And this is what happens when you try to instantiate a known but not included template. Notice that it does offer to include the forwarding-header “QMap”, and not only the header that really contains the class which is “qmap.h”:
missing_include_template_completion

And now a little demonstration how this can help you using most any library:
icore_1

See that ICore has a lot of members that again return pointers to other classes, that of course were only forward-declared. This usually means that before you can use the result of activeSession(), you have to find out where KDevelop::ISession is defined, and include it manually:
icore_2

With KDevelop4, the content is only one key-press away:
icore_3

Disclaimer
This is a feature for experienced users who know what they are doing. It always has to be reviewed, and KDevelop does NOT do any programming for you. 😉

Development Update
Although I don’t have that much time any more, I did find enough time to do quite some polishing during the last weeks. Many crashes and bugs were fixed, and I even found time to imlement some smaller features.
Here the most important points:
– The implementation-helper and signal/slot completions now are shown within separate groups in the completion-list, that are shown in an appropriate place(usually right at the top)
– Access-rights is now fully respected by the completion-list, including friend-declarations.
– Not found declarations can be highlighted with an error-underline now(There’s a new “highlight semantic problems” option in the configuration)
– Added context-sensitive code-completion for builtin C++ keywords
– Full code-completion, use-building and refactoring for namespace names
– Less annoying automatic completion, because it auto-hides when an item in the list is matched
– Workaround a multi-threading problem within kdelibs and ksycoca that caused KDevelop to crash very often
– Fix a repository-locking problem that made kdevelop reproducably crash under special circumstances

Although we do not have all the features we want together, we will be releasing a beta-version of KDevelop4 soon, because we believe it’s already a useful application. Aleix Pol Gonzales has started working on the much needed documentation integration, and Hamish Rodda has today started some new discussion on the debugger, and is planning to bring it into a usable state.

January 8, 2009

C++ IDE Evolution: From Syntax Highlighting to Semantic Highlighting

Filed under: KDE,KDevelop — zwabel @ 3:19 am

Most of us developers are so acccustomed to syntax highlighting, that we couldn’t live without it. Within the last years, it happened to me a few times that I had to look at C++ code with an editor that does not have it. Every single time my initial feeling was that I was looking at a large unstructured text-blob, totally unreadable. Putting some additional cognitional energy into the task, I was able to solve the problem in the end, but there is no doubt that syntax highlighting does increase productivity, it is not just eyecandy.

Syntax Highlighting
Now the first interesting question is: What exactly is it about syntax highlighting that makes the text easier to work with?

When trying to understand what the code does, we usually first try to recognize its coarse structure. For that, we need a fast overview of the code. With that overview, we can decide where we want to continue concentrating on. Now the problem is, while building this overview, really many words have to be scanend. Actually reading all of them would take a long time, and would be very annoying. Highlighting specific words in deterministic colors helps us reducing that load, by giving us familiar orientation points and patterns that our eyes can “hook” on, and allows us finding the specific position we’re searching faster.

So syntax highlighting helps us keeping an overview or finding the place we’re searching for. However it can _not_ help us actually understanding the code, because by the pure definition of “syntax”, it can only highlight by what the code looks like, not by what the code means, since that requires wider knowledge.

Semantic Highlighting
To overcome that limitation, deeper knowlege of the code is required. Right from the beginning, the DUChain in KDevelop was designed to represent exactly that knowledge, and more advanced code-highlighting was one of the basic motivation points behind creating it at all.

So how can it help? There is a few points to this:
1. Additional structure. Due to a now much wider applied highlighting, the code has a lot more colorful structure, which might lead to the same benefits syntax highlighting in general brings. However this is arguable. To some, the additional structure might even seem chaotic, since it’s just too much structure for them. It is definitely something you need to get used to.

Example: Look at this piece of code without semantic highlighting. It optically contains 2 big blobs of code, that to me, already being used to semantic highlighting, look quite unreadable.
semantic_highlighting3
Now look at the same thing with semantic highlighting. The additional structure splits the code-blobs up, and makes them perfectly readable.
semantic_highlighting2

2. Recognizing errors: When specific elements are always colorized in the same way, for example global items, enumerators, items in the local class, etc., then you will at some point expect them to be highlighted that way, and you will notice errors much earlier in cases the highlighting conflicts what you expect.
Example: See all the items beginning with “m_”, they are highlighted in brown. All class-local items are highlighted in that color. If for example m_quickOpenDataProvider was actually a global object, then it would be highlighted differently, and you’d notice the problem right away(This is most useful with function-calls).
semantic_highlighting1

  • 3. Understand code: The real facility that helps you understanding global code-structure is the navigation-tooltip or the code-browser. However those are not very useful to understand local algorithms. The following picture illustrates my favorite part of the semantic highlighting: Local Variable Colorization. That colorization assigns a semi-unique color to each variable in a local context. This allows much easier distinguishing those variables, largely without reading their full name at all. By freeing you of actually having to read all the variable names, this allows grokking local code relations faster, and has already helped me fixing quite a few very stupid bugs right away. 🙂
    semantic_highlighting

    And the best thing about it: You don’t have to use it at all. Today I’ve added the option to completely disable semantic highlighting or local variable colorization all together. Although if you do it, be assured that you will re-enable it after a short time anyway. 😉

    Development Update
    I’ve fixed tons of bugs, implemented a lot of new code-completion features, improved the internal template-support in general so it once gain works correctly with recent versions of the STL iterators, and most importantly, I’ve done a quite large change to the internal environment-management that makes parsing of large projects much more efficient, and scale a lot better disk-space wise.

    All together, I think I’ve pushed KDevelop4 far enough to be able to use it effectively on my upcoming Diploma Thesis, which gives me a very good feeling, and which represents a kind of milestone, since I won’t be able to put a similar amount of time into KDevelop4 in the next time as I did in the past.

    The C++ support now seems nearly feature complete, and very stable. I really haven’t encountered a non-temporary C++-support/duchain crash for a long time.

    Now we just need to push the debugger and the other lacking parts of KDevelop to come up to the expectations, and we’ll be heading for a very good release. As always, if you want to see this stuff in a stable release soon, consider helping, since some of those other parts really need some love.

  • December 18, 2008

    C++ Meta-Programming in KDevelop4: Another Milestone

    Filed under: KDE,KDevelop — zwabel @ 5:12 am
    Tags: , , , ,

    Templates are one of the extremely powerful features of C++ that set it apart from most other languages. You can do most everything with them, from extremly complicated compile-time meta-programming like binary self-balanced trees, down to simple shared pointers or generic container classes.

    When I switched to Linux a few years ago, I found KDevelop3 and liked it. However I noticed that it didn’t support code-completion for even the simplest C++ templates like for example a reference-counter pointer. That was my entry into KDevelop development. I implemented template support in KDevelop3 that had most of the needed features, and worked quite well when the needed libraries were processed. However the quality it could reach had some upper bounds, since there was no powerful backing structure like the DUChain, but rather just a flat completely string-based code-model.

    Actually it was quite hard making the static DUChain structure compatible with dynamic templates, where a new declaration can be created with every use of a class. However I finally succeeded, and today I’ve reached a milestone that is far above of what KDevelop3, and probably even most other IDEs can reach: Full support for C++ template specialization instantiations.

    Explicit Template Specializations
    What basically motivated me to finish this was that even though the template support was already quite mature, the code-completion for __gnu_cxx::normal_iterator, the iterator used by std::vector, did not work correctly. The problem: It uses the template-class iterator_traits to compute its used types, which looks something like this:


    template<class T>
    struct Traits {
    typedef T Type;
    };

    template<class T>
    struct Traits<T*> {
    typedef T Type;
    };

    This means that, depending one the template-parameter given, another class with different content is instantiated. This case is relatively easy, but this whole principle allows implementing most any algorithm statically, and thus can become arbitrarily complex. The good thing is that I already implemented a framework for the matching of implicit template-parameters to template-functions, that could partially be re-used to do the actual matching.

    So the result of the last days is: Full code-completion for all stdc++ functions/classes that use iterator_traits, which is mainly the iterators, and well, also code-completion for any other C++ classes that use explicit specialization. And important: Without any hacks, it’s based on pure language understanding. 🙂 Technically this means that the internal C++ engine is now, apart from bugs and slowness, mostly feature-complete.

    Meta Programming
    As said above, explicit template specialization can not only be used to form new types, but also to compute numerical stuff statically. While this is not very useful in the form I’m going to present, it does serve as a utility to create really efficient code in practice. Today I’ve pushed the C++ engine in KDevelop4 so far, that it can actually evaluate such meta programs right within KDevelop. So here we go:
    prime_meta
    What you see on the screenshot is mainly a simple meta-program I found on the internet that can compute whether a number is a prime-number. I tuned it a little so the results can nicely be visualized graphically be KDevelop’s declaration highlighting: At the bottom, you see all the lines highlighted that were computed as prime numbers.

    Useful Stuff
    What I’ve presented until now is mainly backend features, that will be very helpful in practice without you noticing it, because they will make code-completion, use-building, etc. for more complex template-code “just work”.

    There is also some annoying stuff about templates though. One of the main problem: They are not nice to write. You never know what types you’re actually dealing with. Even if the types are supposed to fit into some pattern, most IDEs cannot give you any code-completion while you’re writing a template class.

    There is a feature in KDevelop4 to recover you from that misery though. So consider the following screenshot:
    completion_within_template_1
    You see a very simple template class called TemplateClass. Within its member function, you can not have any code-completion for the template type T, because it is unknown. However if you put the cursor above one of the instantiations at the bottom, in our case above “TemplateClass<Struct1>”, and push the shortcut to jump to its declaration, then KDevelop will remember that you’re interested in that specific instantiation, and will give you total correct code-completion for that instantiation within that class:
    completion_within_template_2

    Development Status
    Apart from those features, I’ve worked a bit more on the backend, and fixed a lot of thread-safety and stability issues. This went so far that now, after a very long single-threaded time, I have enabled multi-threaded parsing again. This also leads to faster reparsing and re-highlighting while editing the document, because one parsing-thread is reserved only for parsing triggered by user-input.

    December 10, 2008

    Code-Navigation in KDevelop4: Meet the Magic Modifier!

    Today I’m going to blog about the various duchain based navigation and browsing features available in KDevelop4. So let’s start right from the beginning. Consider you have just opened your project. Where to start? Graphically browsing project-trees is ok to get an overview, but it’s horribly inefficient if you need to do it to reach a place you know.

    Quick Open
    The Quick Open feature is the answer to that problem. KDevelop3 already had it, and IMO it was one of it’s most productivity-boosting features. Strangely it was/is not very well known among the users I talked to.

    In short, the Quick Open feature is a simple list of all files, classes, and/or functions within your whole project. By typing into a line-edit you can filter that list.

    I have re-implemented Quick Open for KDevelop4 in a much more flexible way, with several different data providers, probably similar to plasmas runner design. The data-providers are split up by “Scopes” and “Items”, allowing everything to be shown within the same list, or showing only specific parts. For the feature to work best, full-project parsing should be enabled, so classes/functions from within all open projects can be listed. Here you see it in action:
    Quick Open

    So now you’ve got a way to jump into arbitrary locations and get going. But what if you don’t want jump to an arbitrary location, but rather one in the same file? For this, there is an additional “Outline Quick Open”, based on the same framework, but only showing interesting items in the current file. The list can be filtered as well, but as additional gimmick the function/class you’re currently in is always pre-selected, which means you can comfortably use it repeatedly jump from one neighbour function to the next.

    Local Navigation
    When the duchain is working correctly, and the uses are built, nearly every symbol in a source-file is referencing a declaration in another place. That information is not only used for the highlighting, which will be the subject of another blog post, but also for direct navigation. Pushing CTRL+’.’ or CTRL+’,’ allows jumping directly to that declaration respectively definition.

    One of the most useful local navigation features though is the following one. As you see in the following screenshot, all uses of the declaration under the cursor are automatically highlighted in yellow.
    Highlighting
    Since these highlighted uses are real “spots of interest”, it makes quite sense that the user might want to jump directly to one of them. So the shortcuts “Next Use” and “Previous Use” allow you directly cycling through them, jumping from one to the next, even across file boundaries. In my experience, since often your current interest is bound to a specific variable or function, this allows you getting where you want a lot faster.

    The switch declaration/definition shortcut which allows jumping directly from within a definition to the related declaration and back, perfectly complements the team.

    Navigation History
    When it’s easy to jump to a random location, it should also be easy to get back. The code-browser implements an intelligent editor navigation history, that only inserts one history-entry for each function/class you’ve visited. Thanks to this, every really interesting place is in the history once, without too many useless jumps in between.

    The Code Browser
    In my opinion a really good C++ IDE should make a tool like Doxygen unnecessary. The IDE should know all the relevant information, it can update it dynamically, and it can present it to the user precisely where needed. That’s why I implemented the so called navigation-widget right when I started working on KDevelop4 C++ code completion. It is a html text-view containing some nicely formatted text, similar to the output of doxygen. The widget matured together with the duchain, being able to show more and more useful information with time, and at some point it was far enough to be really useful. In the end it found its permanent home in the Code Browser, visible at bottom in the following screenshot:
    Code Browser
    Listing all the information this widget shows would not fit into this blog post. It really shows nearly anything interesting about the shown item, and especially it allows jumping to related items from return-types, template-parameters, inheriters, base-classes, overriders, it allows showing the preprocessed text of macro invocations, showing all declarations from include files, jumping to direct source-locations, searching uses, and so on. When full-project parsing is enabled, this mostly surpasses the quality of what doxygen shows, since it can deal with C++ specifics like templates or macros really well.

    The Code Browser always shows informations about the item currently under the mouse- or text-cursor in the document, unless the little lock at the top right is activated, which preserves the view.

    Since a real developer hates using the mouse when in hacking mode, the navigation widget is completely keyboard accessible.

    The Magic Modifier
    Now thanks to the navigation widget, we do have a lot of keyboard-accessible information to show. Wouldn’t it be great if exactly that information was available from everywhere, with a consistent accessibility scheme? This is where the Magic Modifier(A marketing-name invented by me 😉 ) comes into play. The Magic Modifier allows you peeking from the sketchy code-realm into the semantic one, seeing the connections behind the code. Currently it is hard-coded to the “ALT” key, so that’s actually all you need to remember. This is how it works:
    – By pressing the ALT key, you will in some way get presented a navigation-widget. While you keep it pressed, you can navigate within it using the arrow-keys and the enter-key. Once you release ALT again, it will again disappear, unless you push and release it really fast, which equals a “toggle”.
    Completion Expanded
    On this screenshot you see how the first item in the completion-list was expanded because ALT is pressed. The same thing is possible within all quickopen lists. This also works directly within the editor. When the code-browser is visible, you can always navigate within it using ALT+Arrows. When the code-browser is not visible and ALT is pressed, the following keyboard-accessible tooltip is popped up, and disappears once ALT is released again.
    Tooltip

    So thanks to the Magic Modifier, you’re always just a single keypress away from the semantic information behind your code.

    Html-Like Browsing
    Sometimes when not in hacking-mode, it is comfortable to browse through the code comfortably without any keyboard-interaction. One way to achieve this is by using the new navigation tooltip I have added the last days, or the code-browser, by first pointing at the interesting item. However due to the duchain structure, the complete document could be interpreted as a single hyperlinked document, where each use is a link to its declaration.

    While pressing either CTRL or the Magic Modifier, you can click onto uses directly in the document, and it will bring you directly to the used declaration. The mouse-cursor will change to a hyperlink-style pointing hand when this is possible. For even more comfort without any keyboard interaction, it’s possible to go into a permanent “browsing” state, by clicking the little green lamp toolbutton in the code browser.

    So now you have a lot of navigation tools at hand, which all together allow really efficient working and browsing. I recomment every KDevelop user to memorize all of them, so you have the right tool at Hand in the right moment.

    Development Status
    In the last weeks I’ve once again spent quite some time on the duchain backend. Parsing and especially update-checking is a lot more efficient now, somewhat less disk-space is consumed, several consistency and crash problems have been fixed.

    Also tons of bugs in code-completion and general C++ support were fixed, the shown items in the completion-list are now intelligently shortened when they are too long by leaving away template-parameters. The completion-list in general looks better now with less colors and lighter icons, I’ve implemented the consistent “Magic Modifier” navigation, and tons of other stuff that I don’t remember.

    Just by the way if you’re wondering why my development speed is so fast at the moment: Soon I will begin working on my Diploma Thesis, which will leave a lot less time for KDevelop. I will be working on a C++ project though, and of course I will be using KDevelop4, which 1. means that I will definitely not lose KDevelop out of focus, and which 2. means that I want KDevelop to be in a good state until then.

    What makes me a bit sad is that the rest of KDevelop is not really taking off. Debugger, project-management, documentation-integration, etc. all still need quite some work before a 4.0 release. One interesting thing is that Aleix Pol Gonzales has been improving the cmake duchain support, which means that many of the described features will also be available while working on cmake files at some point.

    November 27, 2008

    ++codeCompletion, and Signals/Slots in KDevelop4

    Filed under: KDevelop — zwabel @ 2:27 am

    It’s quite a while since my last blog now. I’m still planning to present all the essential C++ support features in KDevelop4, but my plan is to polish each feature up a bit before I actually blog about it. This also serves as a nice motivation. 🙂

    In the last weeks, I have mainly worked on DUChain backend stuff, especially making it more efficient. Some important coneceptual scalability problems have been solved, although I have yet quite a few tricks in line to make the actual parsing faster. Temporarily I lost my motivation a little on this boring backend stuff, but in the last days I regained it, and implemented some long planned nice features that I’m going to present to you now. 🙂

    Signals/Slots
    Most Qt programmers love the signals and slots, since they allow getting stuff up and running really fast. But there is also some annoying things about them. For example that they are managed through simple strings, where Qt doesn’t even know about the real scope of the involved types, which leads to simple string-matching instead of comparing the real types. Also you need to write the complete function signature whenever you use a singal/slot, and me personally, I tend to do little mistakes while doing that, which can lead to really annoying little bugs, that aren’t catched by the compiler. It becomes even worse when you try to do refactoring like renaming signals, slots, or some of the involved types. Since the SIGNAL and SLOT macros translate the signatures to strings, grep is until now the only thing that can be of assistance here.

    Now, KDevelop4 is coming to rescue. 🙂

    The first thing needed was additionally recording the signatures of signals/slots in exactly the same way Qt sees them. This way, we can theoretically do exactly the same matching Qt does. But then there’s the problem of the SIGNAL/SLOT macros. With a correctly working preprocessor, those will leave relatively useless strings to the C++ parser. I have completely blocked these macros and internally replaced them with new macros, a new token, and some new structures in the parsing infrastructure, to _not_ do the same thing the compiler does. Instead, our C++ parser now completely processes the signature, and allows building uses for all involved types, and of course for the signals/slots themselves.

    Together with these uses, now KDevelop4 allows you to see all places where a signal/slot is connected, intelligently rename it, and to intelligently rename any types involved in the signature. Of course, the uses are only built if a signal/slot with the given exact signature actually exists. Together with highlighting, this already now gives you an excellent tool to detect broken connections.

    Essentially, this makes signal/slot connections a real well-understood first-class citizen of the DUChain.

    Since people like screenshots, here you see how the uses of a slot are shown, and can be renamed.
    Renaming

    Signal/Slot Completion
    Now the duchain integration allows excellent tracking of already existing connections. But the annoyance of actually writing the connections remains. In KDevelop3, there already was a quite cool code-completion for signals/slots, that inserted the correct complete signature four you, and thus saved you from typing. In KDevelop4 I had this thing on my list for a long time, and now finally I’ve implemented it. However since KDevelop4 is aiming a lot higher then the earlier version, this feature of course needed to be improved as well. 🙂

    So here you see the new Signal/Slot completion, with complete realistic signature-matching, which helps you conveniently connecting only fitting signals/slots to each other. As you see I’ve also worked a bit on the completion-widget. The highlighting colors are much softer now. This picture doesn’t show the interesting “matching” part yet, since every signal matches the connect(..) function.
    signal completion

    In this picture, you see how the correct signature was inserted, and a new completion-list was opened, this time asking for the slot that he signal should be connected to. As you see, the only 2 perfectly matching slots are shown directly at the top. Since you can connect signals to slots with less arguments, the argument-less slots are shown as matches too, although with lower match-quality.
    slot completion

    That’s it with signals/slots for now.

    Builtin Operator Completion
    One more thing that has been on my list for a long time, and that I’ve finally implemented, is completion for all builtin operators in C++, not only the overloaded ones. By completion I mean mainly getting the match-quality highlighted, and getting the “Best Matches” list at top. You will be wondering how often you use some kind of builtin operator, from my experience this saves from a _lot_ of typing, since in many cases the wanted item is right at the top.

    Builtin operator completion

    Also I have added argument-hinting for the “return” keyword, which means you can also get best matches when returning a value from a function:
    return completion

    And that’s it for today. Hope you like the stuff, and as always, if you want KDevelop4 to get ready faster, consider getting your hands dirty. 😉

    Create a free website or blog at WordPress.com.