Tag Archives: planet

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++.

KatePart/KWrite arrives in the KDE Frameworks 5 world

After starting the “frameworks” branch in kate.git more than a week ago but doing not much beside an initial KTextEditor compile & link port I felt a big guilty ;)

Given a lot of people blog about the progress of programs X and Y for Qt 5.2 and KDE Frameworks 5 I guess it is time that KatePart joins this club.

Some hours later, a ‘working’ version of KatePart and KWrite have landed in the “frameworks” branch of kate.git. KWrite launches, loads the part and the open action even works (command line parsing is off-line btw. ATM).

From the let it run ;)   commit on, KWrite should at least launch and open files via file dialog and here is the mandatory screenshot (a KDE Frameworks 5 KWrite over an Kate 4.x window):

I marked all places where I commented stuff out or did a hack with “FIXME KF5″ in a comment or “#if 0″ region. Help welcome, Kate application still to be ported ;) But please mark your “hacks” in the same fashion, otherwise, we will never find them again.

To remember the history, the initial KatePart KDE 4 port happened more than 8 years ago, here a screenshots of that time (2005-05-15):

I think the first KDE Frameworks 5 version looks a bit better. Thanks a lot for all the people getting both the kdelibs frameworks branch in such good shape and all the contributors to Qt 5.x!

The Kate team will do its best to make the KDE Frameworks 5 version of Kate as popular as the 4.x variant is.

KDE Frameworks 5 & Kate, let the fun begin :)

After thinking some days about how to tackle the 4.x => 5.x transition in Kate (KTextEditor/Part/Application) and the nice “what we should do” blog by Dominik, I think the time for fun is there.

Therefore I started to port our stuff to KF5 in the “frameworks” branch.

The basic idea would be: get it compiling and running.

Then we can decide if the frameworks branch is a mere “hack to see if it works” experiment which can be later used to port master without a lot of work or if we say “ok, works kind of well” and we just switch development over for new features from master to frameworks and with that from 4.x to 5.x.

The KTextEditor interfaces compile now, KatePart should be the next thing to tackle.  Then KWrite and Kate.

Happy hacking ;)

(To get a working KF5 development environment, just follow this howto.)

Kate on 5: The Future of KTextEditor and Kate Part

Recently, there was a dot story about Frameworks 5: Started in spring of 2011, the KDE software stack is undergoing a heavy split. The idea is to modularize the KDE libraries into lots of rather small units. Each unit has well-defined dependencies, depending on whether it’s in the tier 1, tier 2, or tier 3 layer, and depending on whether it provides plain functionality, integration, or a solution. If you haven’t yet, please read the article on the dot for a better understanding.

With this modularization, the question arises about what will happen to the KTextEditor interfaces and its implementation Kate Part – and of course all the applications using Kate Part through the KTextEditor interfaces, namely Kate, KWrite, KDevelop, Kile, RKWard, and all the others… The purpose of this blog is to give an answer to these questions, and to start a discussion to get feedback.

A Bit of History (Funny Read Here)

Since not everyone is familiar with “Kate & friends” and its sources, let’s have a quick look at its software architecture:

From this figure, we can see that the software stack has 3 layers: the application layer, the interfaces layer and the backend layer. KTextEditor provides an interface to all functions of an advanced editor component: Documents, Views, etc. (see also the API documentation). However, KTextEditor itself does not implement the functionality. So it’s just a thin layer that is guaranteed to stay compatible for a long time (for the KDE 4 line, KTextEditor is compatible since  2007, so as of now 7 years). This compatibility, or better yet interface continuity is required, since applications in the Application layer use the KTextEditor interfaces to embed a text editor component. The implementation of the text editor itself is completely hidden in Kate Part. Think of a backend library implementing all the KTextEditor interfaces. When an application queries KDE for a KTextEditor component, KDE loads a Kate Part behind the scenes and returns a pointer to the respective KTextEditor classes. This has the advantage, that Kate Part itself can be change without breaking any applications, as long as the interfaces stay the same. Now, with KDE Frameworks 5, this principle will not change. However, interfaces will undergo a huge cleanup, as will be explained now. As a consequence, all nodes that point to or from the KTextEditor node, namely Kate Part on the backend layer as well as applications, will need to adapt to these interfaces.

Milestone 1: KTextEditor and Kate Part on 5

KTextEditor will be a separate unit in the frameworks split. Therefore, the KTextEditor interfaces will not come bundled with one monolithic ‘kdelibs’ as it was the case for that last 10 years. Instead, the KTextEditor interfaces are developed and provided in a separate git repository. This is already now the case: The KTextEditor interfaces exist as a copy in Kate’s git repository, and relevant changes were merged into kdelibs/interfaces/ktexteditor in the KDE 4.x line. For “KTextEditor on 5,” the first milestone will be to get KTextEditor compile with the libraries and tools from the frameworks 5 branch. Along with this port, the KTextEditor interfaces have a lot of places that are annotated with “KDE 5 todos.” That is, the KTextEditor interfaces will undergo a huge cleanup, providing an even better API for developers than before.

Currently, the KTextEditor and therewith also its implementation Kate Part use the KParts component model. The KParts model allows to easily embed Kate Part in other applications along with Kate Part’s actions and menus. Further, Kate Part internally uses KIO to load and save files to support network transparent text editing. KParts itself and KIO are both Tier 3 solutions. This implies that KTextEditor along with its implementation Kate Part are a Tier 3 solution.

In other words, a straight port and cleanup of KTextEditor and Kate Part will depend on a lot of high level frameworks. This solution will provide all the features the KTextEditor interfaces provides right now in the KDE SC 4.x line.

Currently, we plan one major change in the KTextEditor on 5: We will remove KTextEditor plugins. Over the last 10 years, we got close to no contributions to the KTextEditor plugins. Existing KTextEditor plugins partly clash with code in Kate Part (for instance the Auto Brackets with the Autobrace plugin), and merging the plugin’s xml gui into the KTextEditor::Views always requires some hacks to avoid flickering and make it work correctly. Besides, if the KTextEditor plugins are removed, for instance the Kate config dialog only shows one “Plugins” item instead of two. This is much cleaner to the user. Existing functionality, like for instance the “Highlight Selected Text” plugin, will be included into Kate Part directly. The same holds true for the HTML export feature. This is a bold change. So if you want to discuss this, please write to our mailing list kwrite-devel@kde.org.

The time frame for the KTextEditor port & cleanup is rather short: We want to provide rather stable KTextEditor interfaces so that other applications can rely on it. Therefore, we will probably create a frameworks branch in the Kate git repository in December (current proposal on kwrite-devel). Binary and source incompatible changes will be allowed until other applications like KDevelop or Kile are ported to Frameworks 5. Then, the KTextEditor interfaces will again stay binary compatible for years.

Milestone 2: KWrite and Kate on 5

KWrite is just a thin wrapper around the KTextEditor interfaces and therewith Kate Part. Therefore, KWrite will mostly support just the same functionality as it provides now. The same holds true for Kate. However, Kate itself provides quite a lot of advanced features, for instance to have multiple main windows (View > New Window), or sessions, and a good plugin infrastructure. Of course, Kate itself will also undergo cleanups: i) cleanups due to changes in the KTextEditor interfaces, and ii) cleanups like for instance moving the Projects plugin Kate itself, making it more easily accessible to other plugins like the Search & Replace or Build plugin. We will also remove support for multiple main windows through “View > New Window.” This is due to the fact, that many Kate plugin developers were not aware of this feature, and therefore completely messing up their code by not separating the logic from the view, resulting in crashes or broken behavior when using multiple main windows. Removing the support for multiple main windows, we will loose this feature. However, we get simpler and more maintainable code.

There are other small details that will change. For instance, as it looks right now, the Python pate host plugin in Kate on 5 will only support Python 3 (current discussion on kwrite-devel). Python developers, you are welcome to contribute here, as always! :-)

Milestone 3: More Modularization in the KTextEditor Interfaces?

Milestone 1 & milestone 2 will happen rather sooner than later (fixed dates will follow once we’re sure we can satisfy them). Since the transition to Frameworks 5 allows us to change KTextEditor interfaces, it is the right time to think how we can improve the KTextEditor interfaces and its implementation Kate Part even further. For instance, on the mailing list, the idea was raised to make the KParts model optional. This could be achieved for instance by deriving KTextEditor::Document from QObject directly, and create a thin KParts wrapper, say KTextEditor::DocumentPart that wraps KTextEditor::Document. This would be a major change, though, and possibly require a lot of changes in applications using the KTextEditor interfaces. As of now, it is unclear whether such a solution is feasible.

Another idea was raised at this year’s Akademy in Bilbao: Split Kate Part’s highlighting into a separate library. This way, other applications could use the Kate Part’s highlighting system. Think of a command line tool to create highlighted html pages, or a syntax highlighter for QTextEdits. The highlighting engine right now is mostly internal to Kate Part, so such a split could happen also later after the initial release of KTextEditor on 5.

Join Us!

The Kate text editor only exists thanks to all its contributors. Moving to frameworks, it is the perfect time to follow and contribute to the development of Kate. In fact, you can learn a lot (!) in contributing. In case you are interested, have ideas or want to discuss with us, please join our mailing list kwrite-devel@kde.org.