All posts by Dominik

Dominik is a PhD student at the Control Theory and Robotics Lab, TU Darmstadt, as part of the Research Training Group GKMM (GRK1362). My research focuses on state estimation in distributed systems. As hobby, I contribute to the KDE project and work on the Kate application and editor component.

KTextEditor on Frameworks 5: Timing is everything

This is a follow-up to Aaron’s blog Frameworks 5: Timing is everything, put into the perspective of Kate and the KTextEditor interfaces. In short, Aaron suggests application developers the following:

When Frameworks 5 has a firm release schedule, then it makes sense to start coordinating application releases targets with that and syncing up development cycles.

I agree with this entirely, provided it’s really about applications. In the context of Kate, this is not the case, since the term ‘Kate’ usually also refers to the ‘KTextEditor’ interfaces along with its implementation ‘Kate Part’.

In essence, the KTextEditor interfaces together with Kate Part provide a text editor in a library that can be used by applications, or more to the point, KTextEditor+Kate Part build a framework.

In fact, about a week ago, the KTextEditor interfaces and Kate Part were split out of the kate.git repository. So from now on, kate.git contains the Kate and KWrite applications. The ktexteditor.git module contains the KTextEditor interfaces and Kate Part.

ktexteditor.git is is a tier3 framework and meanwhile officially part of the frameworks initiative: if you want so, KDE now provides 58 frameworks instead of the previously announced 57!

Why timing is everything

Now what about timing? Started on November 28th 2013, Christoph pushed the first compiling version of Kate into the frameworks branch. This was very good timing, since the split of kdelibs into all the frameworks was more or less just finished at that time. Or to put it the other way round: Christoph started porting Kate pretty much as early as the KF5 initialive allowed us – cool!

Around that time by coincidence, Michal started to work on Kate in the master branch and committed lots of cool features. However, since Kate was already rudimentary ported to Qt5 and KF5, the code base diverged more and more, so merging got more complicated. Therefore, Michal started to work in Kate’s frameworks branch. And within only a week (!), Kate, KWrite, the KTextEditor interfaces and Kate Part build without a single warning, meaning that the code was completely free of Qt4 and kde4support – wow! :-)

Again, a month before would have been too early – so this was perfect timing. The result was a pretty stable and mostly bug-free Kate in mid of December.

Well, not completely free of porting bugs. For instance, file saving did not work correctly, ending up in data corruption. It turned out that this was an issue in the framework karchive, which David Faure was able to reproduce and fix. This is good timing in the sense that without Kate’s usage of karchive, the bug would have probably ended up in the technical preview TP1. But it didn’t – yay! :-)

Last but not least, the Kate and KDevelop developers planned already months ago to have a joint Kate/KDevelop sprint from 18th to 26th of January, 2014. Given the current state of Kate and KTextEditor, this again is perfect timing, since most of the KTextEditor cleanup are already done. So the Kate developers can focus on the needs of e.g. KDevelop, on fine-tuning and implementing interfaces, etc. So in about two weeks, when our developer sprint will have ended, Kate will most probably shine as it never did before. And this is the case already now, even before a firm release date of Plasma 2 exists.

This is great news for Kate and all applications that use the KTextEditor interfaces, as Kate/KTextEditor already now reached a maturity that they never had before.

And this is so awesome! I cannot think of better timing :-) Thanks to all who made this happen!

Kate in 4.12

Since the KDE SC 4.12 release a month ago, it’s about time to look at the changes of Kate in 4.12:

What comes next?

Kate will get more polishing in the next 4.x releases, for instance, in KDE SC 4.13 Kate optionally supports animated bracket matching.

However, as already mentioned in Kate in 4.11the main efforts are put into making Kate on Qt5 and Frameworks 5 rock solid. Already now Kate, KWrite and Kate Part are fully ported, i.e. all are free of KDE4support libraries. A preview (already one month old!) can be found here.

Besides that, Kate and KDevelop again join forces and there is a developer meeting from 18th to 25th of January 2014. So expect quite some blogs about Kate on 5 then!

Current State of Kate on 5

Just a quick update on the frameworks 5 port: KTextEditor,  Kate Part and KWrite build and run. Kate is not yet ported and does not compile. These changes were already committed:

  • made KTE::Cursor and KTE::Range non-virtual for maximum speed
  • removed KTE::EditorChooser, since Kate Part is the only implementation since over 10 years. Just use KTE::Editor* editor = KTE::editor(); to get KatePart.
  • new signal KTE::Document::readWriteChanged()
  • removed KTE::LoadSaveFilterCheckPlugin, was unused since years
  • removed all KTE::Smart* classes in favor of KTE::Moving* classes
  • merged KTE::CoordinatesToCursorInterface into KTE::View
  • new: KTE::Range KTE::Document::wordRangeAt(KTE::Cursor)
  • new: QString KTE::Document::wordAt(KTE::Cursor)
  • new: KTE::DocumentCursor
  • ported lots of KSharedPtr to QSharedData
  • updated Mainpage.dox to reflect porting notes
  • some small interface cleanups and additions

Please feel free to join the porting fun. Just follow the Frameworks compile guide and checkout the git branch “frameworks” in the Kate git module.

Kate: “C++/boost Style” Indenter

Greetings from the Kate land again. This time, Alex Turbov will spend a few words about his “C++/boost Style” indenter that is part of Kate Part for several releases.

The Initial Motivation

This indenter (initially) was designed to help code typing in a “boost::mpl” style (i.e. with leading comma in formatted (template) parameters list). One may read the rationale of such approach in the “C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond” by David Abrahams and Aleksey Gurtovoy. It is really easy to miss a comma when invoke metafunctions and it usually leads to a lot of complicated compile errors. The indenting technique should help to visualize the control syntax and prevent stupid errors like missed commas.

Small example:

typedef typename boost::mpl::fold<
    typename boost::mpl::transform_view<
        Seq
      , boost::remove_pointer
      >::type
  , boost::mpl::long_
  , boost::mpl::eval_if<
        boost::mpl::less
      , boost::mpl::_2
      , boost::mpl::_1
      >
  >::type type;

In practice I’ve noticed that this style can be used to format long function calls or even `for` statements. Actually everything that can be split into several lines could be formatted that way. And yes, it is convenient to have a delimiter (comma, semicolon, whatever) as a leading character to make it visually noticeable.

// Inheritance list formatting
struct sample
  : public base_1
  , public base_2
  , ...
  , public base_N
{
    // Parameter list formatting
    void foo(
        const std::string& param_1                      ///< A string parameter
      , double param_2                                  ///< A double parameter
      , ...
      , const some_type& param_N                        ///< An user defined type parameter
      )
    {
        // Split `for` parts into few shorter lines
        for (
            auto first = std::begin(param_1)
          , last = std::end(param_1)
          ; it != last && !is_found && !is_exit_requested
          ; ++it
          )
        {
            auto val = check_some_condition()
              ? get_then_value()
              : get_else_value()
              ;
        }
    }
};

It looks unusual for awhile :) but later it becomes (quite) normal and easy to read and edit :) Really! When you want to add one more parameter to a function declaration it takes less typing if compare to a “traditional” way :) (especially if you have some help from an editor, like move/duplicate the current line or a selected block up/down by a hot-key or having an indenter like this :)

Next improvements was designed to simplify typing C++ code, using most common syntactic rules, like:

  • add spaces around operators and after a comma
  • add space after control keywords, but not after a function name in a call expression
  • etc.

Further improvements bring to the indenter some cute features and nowadays I’d prefer to consider it similar to a T9 (input method) for C++ coding, but not as a “real indenter” in contrast to others, shipped with kate out of the box :) Particularly this indenter “exploit” can see “impossible” syntax and (try to) transform it to something “reasonable” — i.e. just like T9 it tries to be a predictive.

For example, if you have autobrackets plugin turned ON, when typing `some(nested(` gives you `some(nested(|))` w/ `|` indicating a current cursor position. If you press `,` at this position, it gives you the following snippet `some(nested(), |)` supposing that you want to add one more parameter to a `some()` call. While typing `;` looks like you’ve done with that nested calls and gives you the `some(nested());|` snippet. Both cases help you to avoid couple of redundant key presses ;)

… but do not even try to use this indenter to (re)format blocks of code! :) It can do some really simple/primitive formatting, but far from good — as I’ve mentioned above: this “not quite indenter”™ designed to help you to __”do little more with less typing”__ for C++ ;)

Some of the Features

  • to start a C-style comment block type `/*` and press ENTER key — it gives you
    /*
     * |
     */

    to start `doxygen` comment block use `/**` + ENTER. Every following ENTER just extend the current block.

  • to start C++ style comment just type `//` it will add a one space after ;)
  • I prefer to have on-line-comments (i.e. C++-style comments after some expression) to be aligned at 60th position. So typing `//` will automatically move comment to that position if there was some code before. Moreover the indenter tries to keep that comments when you use ENTER key to break some complex expressions into a few lines
    // Before pressing ENTER at position marked by '|'
    some_call_with_long parameters_list(|param1, ..., paramN);  // Comment starts here...
    // After pressing ENTER: keep comment at the original line
    some_call_with_long parameters_list(                        // Comment starts here...
        |param1, ..., paramN);

    Also try to use _ENTER_ in the middle of a comment text ;-)

  • typing `///` gives you `/// ` (with a space) or `///< ` depending on presence of code at the current line
  • from time to time I use grouping in a doxygen documentation, so typing `//@` gives you:
    //@{
    |
    //@}
  • always add a space after `,` character — simple, but really convenient! really soon you’ve stopped typing a space after any comma and feel yourself inconvenient with other indenters ;)
  • typing `<` without a space after some identifier adds a closing angle bracket (like notorious autobrackets plugin do for other bracket types), because template instantiation guessed. So typing `std::vector<|` gives you `std::vector<|>`. But `std::cout<|>` turns into `std::cout << |` after pressing one more `<` ;-)
  • a lot punctuation characters being typed withing parenthesis is a some operator (or at least part of), so will be moved out of parenthesis (most likely call expression). Try to type various punctuators at marked position in the following snippet `some(|)`…
  • typing a backslash in on a line of a long `MACRO` definition cause realign all others to fit to a longest line:
    #define PP_FORM_A_ROW(State, Data, Elem)    \
      {                                         \
        {                                       \
            field_path(                         \
                BOOST_PP_TUPLE_ELEM(2, 0, Data) \
              , BOOST_PP_TUPLE_ELEM(2, 1, Data) \
              , BOOST_PP_TUPLE_ELEM(2, 0, Elem) \
              )                                 \
          , BOOST_PP_TUPLE_ELEM(2, 1, Elem)     \
        }                                       \
      , manage_config_keys::action::GET         \
      },
  • * typing `R”` will initiate a raw string literal

This advanced indenter  has some other (smaller) features to reduce typing. Hope, you’ll like them if found! ;)

PS: The other things I’ve found useful when typing C++ code can be plugged with some Python plugins dedicated to C++.