Category Archives: Users

Do you understand the word HTML?

During the Kate developer meeting we also thought about simplifying KWrite and how to make the decision whether KWrite should be launched in full featured mode or in a stripped version. …well, and we found a really funny idea:


Note, that this would even work, the question would be rather annoying, though :) The solution right now is to always start KWrite in a simple mode. Mostly only actions are hidden in the menus (@distributors: kdelibs/kate/data/katepartsimpleui.rc), but you can also change c++ code at Kate part level, as there are some functions:

  • bool KateDocument::simpleMode() (kate part internal), and
  • bool KTextEditor::Editor::simpleMode() (along with setSimpleMode())

This way config dialogs can be adapted depending on the mode as well. Ah, and if you want the normal mode back, go into the KWrite settings and enable [x] Enable Developer Mode. Then restart KWrite.

PS: Tackat, we came up with this image before our phone call. That’s why it was really funny when you said HTML is something that should not be removed. hehe… :)

Kate Highlighting Power

Kate’s highlighting capabilities are amazing. If you want you can highlight really complex syntax, without having to hardcode rules in C++. As an example, we’ll take a look at how Lua comments can be realized:

  • –[=[ starts a multiline comment (the '=' chars are optional)
  • ]=] ends the multiline comment
  • the number of ‘=’ chars in ]=] must match the number of –[=[

That means: When the highlighting processor matches the end of a multiline comment, it has to know how many '=' chars started the comment. Thanks to the concept of dynamic rules and contexts Kate is able to do that. The highlighting file looks like this. First comes the header

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd" >
<language name="Test" version="1.0" kateversion="2.4" section="Markup" extensions="" mimetype="">
  <highlighting>

Then the body with the contexts. We start in the first context called "Normal Text". When the regular expression --[(=*)[ matches it switches to the context Comment.

    <contexts>
      <context attribute="Normal Text" lineEndContext="#stay" name="Normal">
        <RegExpr attribute="Comment" context="Comment" String="--\[(=*)\[" dynamic="true"/>
      </context>

The part (=*) is now available as %1 in the rule below:

      <context name="Comment" attribute="Comment" lineEndContext="#stay" dynamic="true" >
        <RegExpr attribute="Comment" context="#pop" String="\]%1\]” dynamic=”true” />
      </context>
    </contexts>

The last part is the footer:

    <itemDatas>
      <itemData name="Normal Text" defStyleNum="dsNormal" />
      <itemData name="Comment"     defStyleNum="dsComment" />
    </itemDatas>
  </highlighting>
</language>

If you want to know more about Kate's highlighting, have a look at the documentation :) There are also lots of bug reports, so if you want to contribute you can fix them!

PS: As I don't know much about Lua, comments might work differently. That does not really matter, as the example still shows what you can do :)

Extending Kate by Scripts

We have seen how scripting basically works for indentation. It’s also possible to register commandline functions (The command line is bound to F7 by default, or invoke View > Switch to Command Line). We will consider a small example again: sort the selected text.

/* kate-script
 * name: unused
 * author: foo bar
 * license: LGPL
 * version: 1
 * kate-version: 3.0
 * functions: sorter
 */

function sorter ()
{
    if (view.hasSelection()) {
        var start = view.startOfSelection().line;
        var end = view.endOfSelection().line;

        var text = document.textRange(start, 0, end, document.lineLength(end));

        var lines = text.split(“\n”);
        lines.sort();
        text = lines.join(“\n”);

        view.clearSelection();

        document.editBegin();
        document.removeText(start, 0, end, document.lineLength(end));
        document.insertText(start, 0, text);
        document.editEnd();
    }
}

The header line functions: sorter makes Kate Part aware of the function in the script. A list of functions is supported, separated by white spaces. You can use the function by typing ‘sorter’ in the commandline.
Some todo items:

  • provide better JavaScript API. For example: document.textRange() takes 4 parameters. It would be more elegant to take one range or two cursors, just like we do in the KTextEditor interfaces in kdelibs/interfaces/ktexteditor
  • make is possible to bind scripts to shortcuts. This could be done by e.g. binding commandline functions to shortcuts or implementing a vim-like command-mode in Kate’s commandline. How to configure the shortcuts is unclear, though.
  • then, think about replacing the C++ implementations of ‘uppercase’, ‘lowercase’, ‘capitalize’ etc. with scripts
  • things I forgot…

If you are interested subscribe to kwrite-devel@kde.org and contribute :) We also need indentation scripts, of course!

Kate: More on Indentation Scripting

My last blog was about the theory of how indentation works by using javascripts. Now we will look at a concrete example: a LISP-style indenter. (LISP indentation is easy, that’s why it’s a good example).
The rules:

  • comments starting with ;;; always have indentation 0
  • comments starting with ;; should be aligned with the next line
  • comments starting with ; should only appear behind code, so they are simply ignored
  • every ‘(‘ indents and every ‘)’ unindents

lisp.js looks like this:

/** kate-script
* name: LISP
* license: LGPL
* author: foo bar
* version: 1
* kate-version: 3.0
* type: indentation
*/
// indent should be called when ; is pressed
triggerCharacters = ”;”;
function indent(line, indentWidth, ch)
{
// special rules: ;;; -> indent 0
//                ;;  -> align with next line, if possible
//                ;   -> usually on the same line as code -> ignore
textLine = document.line(line);
if (textLine.search(/^\s*;;;/) != -1) {
return 0;
} else if (textLine.search(/^\s*;;/) != -1) {
// try to align with the next line
nextLine = document.nextNonEmptyLine(line + 1);
if (nextLine != -1) {
return document.firstVirtualColumn(nextLine);
}
}

cursor = document.anchor(line, 0, ’(‘);
if (cursor) {
return document.toVirtualColumn(cursor.line, cursor.column) + indentWidth;
} else {
return 0;
}
}

The result:

;;; fib : number -> number
(define (fib n)
(if (< n 2)
1
(+ (fib (- n 1)) (fib (- n 2)))))

As this indenter is scripted, everybody can adapt the style to the own needs.