Sophie

Sophie

distrib > Fedora > 20 > x86_64 > by-pkgid > 21bc725ca4faa732906c46b99f5ed600 > files > 10

kate-part-4.14.3-5.fc20.x86_64.rpm

#
# Indentation for Dummies
#

This file should is aimed to describe how the KatePart in KDE 4 is designed to allow
flexible indentation based on JavaScripts.

As references, a good read is the way VIM handles this all, Emacs is out of scope I think,
as it's just to mangled together there with the mighty lisp engine.

VIM seems to have a fairly simple way to integrate indentation scripts, I guess a similar
approach is no bad idea...

What tell the VIM docs about indentation?
http://www.vim.org/htmldoc/indent.html

Some little HOWTO showing a simple Pascal indenter:
http://psy.swan.ac.uk/staff/carter/unix/vim_indent.htm

In short, how does scripted indentation work in VIM?

 - you must write a functions which returns for a given line the wanted indentation level.
 - you specify some keywords/char which trigger indentation, inserting a linebreak always triggers it
 - if indentation is triggered, VIM evaluates the function for the line and reindents the line to the
   returned level or keeps the current indentation level if -1 is returned
   
This sounds fairly simple, but seems to be enough for normal world usage, given that VIM is
very popular....

KatePart's current indentation scripts work similar, but are triggered on each keystroke.
I guess only calling them for linebreaks + special chars would increase performance already
a lot. Next part is that the scripts atm indent theirself, I guess letting them just return the
needed level and let the C++ code really indent the line would be faster and easier for the script
writers, too.

One bad thing with the VIM way is that mixed indentation won't work correct, you can't return in one
int that the first 4 chars can be replaced with tabs, if tab indentation is enabled but the remaining 4
chars should stay single spaces, as it is useful in this example (given tabwidth is 4):

int test ()
{
    if (hello ||
        muhh) // this line should be indented with tab + 4 spaces
        return 1; // this line should be indented with 2 tabs

    return 0;
}

I think we should have a interface in which the script indicates which normal indentation is wanted
and which further amount of spaces should be inserted to align with other words/keywords whatever...

As it shows up, if we want to support both mixed-indentation and alignment, indent/unindent functions can't
be generic, as there is no way to tell, if for example 8 spaces are actually one tab, as they are 2 indent levels
or just one indent level + 4 alignment spaces. Therefor will take the vim way of things, where alignment is not
possible...

#
# Built-in indenters
#
Right now we removed all built-in indenters due to refactoring and new indentation system. If it turns
out that js indentation for complex stuff like c/c++ is too slow, we maybe have to reintroduce the
built-in indenters. Interesting reference might be in vim, see: vim/src/misc1.c, function get_c_indent.

#
# Idea: Extending itemData (=attribute information)
#
Scripts would benefit if they could access highlighting information in a -reliable- way, i.e. -not-
what we have now in KateNormalIndent::updateConfig().

Possible solution: extend itemData to have another attribute 'type'.
Example: <itemData defStyleNum="dsNormal" ... type="default"/>
What types do indentation scripts need? C/C++ like languages need:
 * default = everything that is not of the following types
 * comment = single and multiline comments, and #if 0ed code
 * string  = "..." and '...' strings
 * pp      = all preprocessor macros (#ifdef etc.)
 * symbol  = characters like: {}[](),; (and more)

This is actually everything we need for C like languages. Though, some further thoughts:
 * number  = all kind of numbers: int, double, float
 * keyword = keywords like: void, int, while, class
Those two maybe would be a nice addon, but they are not necessarily needed for indentation.

Shortcomings:
We need a good set of 'types', as they will be hard coded in the Kate Part.
-> Todo: Think of other languages, what types do we need?

In what way are those types useful?
Indenters (and scripts) can for example query doc.findOfType("{", "symbol");
This will skip all { in comments and strings.
Indenters can check 'where are we?': if (doc.typeAt(cursor) == "comment") ...
-> Todo: Find good API.

How to make it work with our .xml files?
To be backward compatible, the default type would be "default", if not defined otherwise.
To make it work with our .xml files, we would need to adapt C++/Java/Php/... files to set the types
correctly.
Implementation: Extend KateExtendedAttribute to contain the type (besides the defaultStyle). To make
it fast, use an integer (enum) just like the defaultStyles.

Another approach: Instead of putting a type into a KateExtendedAttribute, we also can put the type
into the KTextEditor::Attribute. Then overlay highlighting like it probably will be done by KDevelop
can also provide the needed type information (otherwise indentation might not work).

Thoughts welcome.