This article was originally published as a blog at http://www.alweb.dk/blog/anders/autoindentation at 2004/11/02.
NOTE Mon Nov 1 16:49:03 CET 2004: revised versions of the variables for both perl and bash. Also update kdelibs/kate/part.
Some time ago, when I convinced Laurence Withers to contribute a XML auto-indenter to Kate, I got the idea that we should also have a more flexible indenter that could be configured using the document variable system. The other day while commenting on this bug I was reminded again. So in one of my usual streaks away from my overfilled TODO list, I sat down and implemented one last night..
The commit log in a friendly formatting looks like this:
This indenter matches a line and the first line with content above against
regular expressions to decide if a line should be [un]indented. When a newline
is entered, both the old and the new line is considered, and it can be triggered
to indent the current by typing one of a list of characters.
The regular expression patterns and trigger character list are read from document variables, which can be embedded directly in the document or read from a filetype configuration.
This should be usable for adding basic autoindentation to bash, lua, basic, perl...
Note that Kate's document variables currently can't contain a semicolon, (would be a common trigger char), I'm going to fix that.
I'd really appreciate it if some of you would like help me testing this! If you run cvs HEAD and write bash or perl code, please consider using the configurations below, and let me know how it works out. If you want to define variables for another language, don't hesitate to come into #kate at irc.freenode.net and ask me for help.
The general idea is to store the variables needed to define indentation for language X in a filetype configuration, but the variables can of cause be stored in any location from where kate will read them. So far, I have defined variables that seems to work with bash script and with perl. It looks like this:
# kate: indent-mode varindent;
# kate: var-indent-indent-after (\{(?![^\}]*\})|\b(then|elif|else)\b(?!.+fi)|\\bdo\b(?!.+done)|\bcase\s+.+\s+in\b(?!.*esac)|\[\[);
# kate: var-indent-indent \$\{.*\};
# kate: var-indent-unindent ([}]\s*$|\b(fi|elif|else)\b|\bdone\b|\besac\b|\]\]);
# kate: var-indent-triggerchars {};
The entry from ~/.kde/share/config/katefiletyperc looks like this (NOTE that the Variables property has been broken into several lines, the continued lines are indented. The double backslashes seems to be a KConfig thing.):
[Bash]
Mimetypes=application/x-shellscript
Section=Scripts
Variables=kate: indent-mode varindent;
var-indent-indent-after (\\{(?![^\\}]*\\})|\b(then|elif|else)\b(?!.+fi)\\bdo\b(?!.+done)|\\bcase\\s+\\s+in\\b(?!.*esac)|\\[\\[);
var-indent-indent \\$\\{.*\\};
var-indent-unindent (\\}|\\b(fi|elif|else)\\b|\\bdone\b|\\besac\\b|\\]\\]);
var-indent-triggerchars {};
Wildcards=*.sh
Explanation:
var-indent-indent-after variable matches any line that looks like an unfinished bash control loop, or like it has an opening curly brace or a double square bracket opening.var-indent-unindent variable matches any of the corresponding closing elements.var-indent-indent variable adds indentation if the line has variables enclosed in curly braces, in anticipation of the unindenter removing it again. This might seem a bit silly, but so far I haven't a better solution.var-indent-triggerchars variable causes immediate indentation when a curly brace is entered. (the textual closings will be unindented when/if a newline is entered.)(hey, who'd have thought that those would be simpler?)
# kate: indent-mode varindent;
# kate: var-indent-indent-after (?:\{(?![^}]*\})|\((?![^\)]*\)));
# kate: var-indent-indent (?:\{.*\}|\(.*\));
# kate: var-indent-unindent [})];
# kate: var-indent-triggerchars });
... and the corresponding filetyperc entry:
[Perl]
Mimetypes=text/x-perl
Section=Scripts
Variables=kate: indent-mode varindent;
var-indent-indent-after (?:\\{(?![^}]*\\})|\\((?![^\)]*\\)));
var-indent-indent (?:\\{.*\\}|\\(.*\\));
var-indent-unindent [})];
var-indent-triggerchars });
Wildcards=*.pl;*.pm
This works much like the bash configuration, but simpler, since all i care for is indenting [curly brace] blocks and multiline parens. For perl, a semicolon shoudl really cause reindenting, but kate can't read that from a variable yet :-\
...uhm.. I'm going to have to create a working configuration for CSS ASAP!
Comments
how to enter this info?
I’m curious on a new editor for perl and Kate looks very appealing with the file tabs and shell at the bottom etc
Forgive my ignorance, but how do I set up the Perl stuff above for my Kate? I see there’s 2 sections.
where do I put in:
# kate: indent-mode varindent; # kate: var-indent-indent-after (?:\{(?![^}]*\})|\((?![^\)]*\))); # kate: var-indent-indent (?:\{.*\}|\(.*\)); # kate: var-indent-unindent [})]; # kate: var-indent-triggerchars });I see there’s a “configure” button next to the dropdown menu for autoindent method in the configuration, but it’s greyed out…
About the corresponding file entry: The ~/.kde/share/config/katefiletyperc is non existant on my KDE 3.5.6 kubuntu system. Will just putting the stuff quoted in the article into a fresh file with that name work?
Cheers!
an idea
why not include the variables for this feature also in the XML highlighting settings, would be much more nice than the config imho.
Perl indenting in Kate 2.5.2
For Kate 2.5.2 (KDE 3.5.2) in Ubuntu 6.06.1 (under Gnome) the following gets basic curly braces and parentheses indent matching working.
[Perl] Mimetypes=text/x-perl Priority=1 Section=Scripts Variables=kate: indent-mode varindent; var-indent-indent-after ((\{(?![^}]\}))|((][)])));; var-indent-indent (\{.\}|\(.\)); var-indent-unindent [})]; var-indent-triggerchars }); Wildcards=.pl;.pm;
What is ?: - it's not listed in the regexp section of the book
What is ?: - it’s not listed in the regexp section of the Kate Handbook. Is it a new assertion? (?:… doesn’t mean anything to me, based on the regexps in the handbook.
Bug: if the first line in
Bug: if the first line in the file matches var-indent-indent-after, then this first line gets indented (regardless of a match to var-indent-indent).
Matlab Section
Here are the beginnings of a matlab block:
Starting a matlab section
Here’s the beginnings of a section for matlab code:
Here's a Ruby section for
Here’s a Ruby section for .kde/share/config/katefiletyperc. Please note that there’s just one Variables line and that you have to create the file if it doesn’t exist.
By Juan Ignacio Pumarino R. // jipumarino at gmail.com
Slightly different
I’m using a slightly modified version of your section:
There’s mostly support for “unless” blocks and a slightly refined match for ending a block. Otherwise, e.g. “render” would match the unindent expression. It’s still necessary to have it match only full tokens, since e.g.
has “endowment” match unindent (it starts with “end”) and thus unintents the second line. I’m not quite sure what kind of regular expressions is used by kate, and also the unindentation triggers while you type, so there’s probably no way around it. (It would have to unindent after “end”, and then reindent once the token doesn’t match anymore.)
Otherwise, it works pretty well, but creates a spurious indentation level if you’re starting a block on the first line in the file. As long as the first line doesn’t match the indent-after expression, it’s fine. My personal guess is that this is due to a bug in kate.
doesn't work for me
the perl settings work fine - but these Ruby settings do not. any suggestions?
Post new comment