# # 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: 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.