On 13-11-10 11:18 PM, Lex Trotman wrote:
Hi All,
Recently there have been a number of proposals for significant changes in Geany, different languages, GObjectification and other various changes.
As good or bad as the individual suggestions may be, they have made it clear to me that there is no plan for the future of Geany that allows them to be evaluated effectively.
So I am starting this thread to try to get ideas on where Geany should be headed.
To start the ball rolling, here are some of the things I see Geany should aspire to:
- An architecture that allows multi-threading to be used for non-GUI
tasks. The most obvious of course is parsing. At the moment none of the parsers support symbols in anything other than the global scope, and adding them would significantly increase the parsing effort, but doing it in a background thread would make the performance hit less obvious. But there needs to be a careful design of the passing of data from the edit buffer to the parser and back to the symbol tables to minimise overhead, latency and ensure its non blocking. With such an architecture other complex functionality can then also happen in the background without impacting Geany's responsive feel.
Another (perhaps more obvious) candidate here is file loading/saving, which is *way* easier than the parsing stuff since we don't have to contend with TM/CTags that uses global state like mad, and because Scintilla and GIO make this quite easy (probably wouldn't even require threads but just mainloop/async stuff).
- Language specific assistance, such as indentation, or dynamic error
marking and intelligent autocompletes. I consider that these hang off the previous capability of better parsing/analysis of the program. Matthew has demonstrated a prototype that provides some of these facilities using libclang (for the clang languages only C, C++, Obj-c). But the current Geany architecture does not support plugging such things in easily, and with the number of languages that Geany supports, I would suggest that its small, light and fast tag would be severely threatened if assistance for all languages were plugged in at once.
A way for plugins to "handle" certain filetypes so that plugins can be loaded/unloaded as a filetype is used in a document and unload when no documents currently use it or something. This could include ability to disable or augment certain built-in filetype-specific stuff that can't easily be done currently.
- Proper portability. At the moment Geany is really a Linux application
that has some limited (and buggy) support for Windows. The main editing widget that Geany uses is available for many platforms and toolkits. If Geany had an architecture that separated the target specific parts into a "backend" the way Scintilla does, then it would be possible to support multiple targets more easily, making Geany less at the mercy of one toolkit's direction (that means you deprecating GTK) and better able to support different platforms like OSX and Windows. Work such as that Dimitar is doing for spawning on Windows naturally then falls into such a backend.
I agree that's a good way to do it, like Chrome, Firefox, LibreOffice, etc. to have own wrapper over various toolkits for internal use depending on the platform, but IMO, it's vastly too much work for Geany, and GTK+ isn't actually all that bad (despite their sometimes confounding API changes/deprecations).
The other way we could go is to just strive to be a proper, modern GTK+ application. By this I mean using stuff like GtkApplication, GtkApplicationWindow, GSettings, etc. The GTK+ stack has lots of cool stuff to make doing applications easier/better that we don't use because of the ever-present restriction about needing to be able to support LTS distros with old GTK2 and not wanting to "GObjectify" and/or make large changes to the code.
- Multiple top level windows. As monitors are cheaper, being able to
spread views of files to optimally utilise the screen space available adds to the users effectiveness. Most languages support multiple modules in different files and many use multiple files for related parts, such as C/C++ header and body. Looking at and editing several places/files at once has many uses. As useful as splitwindows one and two are (especially together) they still assume a single rectangular top level is available for subdivision. But different desktop menu layouts or having other applications visible at the same time can limit the contiguous rectangular space available. Multiple top levels can make better use of non-rectangular space.
As with with my comment in #3, if the application was structured as the GUI toolkit is designed to be used, using some of the more modern GTK+ APIs, this is ridiculously easy, especially when used with the #5 I'm going to add:
5. Drop Scintilla and use GtkSourceView. I'll just enumerate the reasons that come to mind, in no particular order:
* Scintilla is a big fat not-really-GTK+ C++ library * We have to keep a fork up-to-date in our source tree * It provides one of worst APIs known to man, and causes us to have all kinds of wrappers to make the API normal and to have our code still littered with unsafe SSM() calls that make the code really weird. * Limited functionality to support plugins participating in the buffer/view; for example there's only a really small number of indicators, markers, pixmaps, etc. It's not really built with arbitrary extension (ex. by plugins) in mind. * It makes simple things like MVC hard to do with the way its user API is so view-centric. * While it supports background loading, it doesn't support background/async lexing, and so completely blocks the UI for huge documents. * Writing lexers is beyond complicated. Having to write C++ code to add/customize syntax highlighting is insane from a user POV. * Has no builtin support for colour schemes making us have to have a whole, kind of confusing, configuration file system to provide it ourselves. * Reduce Geany's binary size since the editor component would be linked dynamically, and not statically like Scintilla is. I don't know if this actually matters but I think Scintilla with all the lexers and stuff I think it can end up as several MB in the binary. * As with above, and the one about updating the fork; using a dynamically linked version allows the system admin to upgrade their libraries and they'll automatically be used by Geany. * Drop dependency on a C++ compiler. This isn't a big deal really. And of course replace with a new dependency on gtksourceview library. * GtkSourceView provides convenient features like SourceCompletion and SourceMarks and such that would make doing stuff from plugins quite straightforward. * GtkSourceView completely integrates into our GUI toolkit, using native (not custom drawn like Scintilla) widgets inside and interacts properly with stuff like scrolling, focus, DnD, key-bindings, etc. * If we ever do use GObject stuff more and/or make the plugin API automatically bindable with GObject-Introspection, GtkSourceView already provides the .gir stuff needed. * I think GtkSourceView is installed by default usually with at least GNOME and XFCE (via Gedit and Mousepad using it and being the "default" text editors).
And I since we're mentioning huge changes :) ...
6. Automatically-bindable plugin API that we officially support for multiple languages. Writing plugins in C is crap, IMO. Writing a GeanyPy or GeanyLua plugin is kind of crap, because they depend on other plugins, and you can't make a "real" first-class plugin with them. LibPeas and Gobject-Introspection are the obvious possibility here, but would require to "GObjectify" the code pretty much.
These are all big changes that don't fall into the current Geany mode of "light maintenance and extra features as someone implements them". For big changes like those above however, a clear design and a planned process is needed to ensure that the big changes don't clash with each other and that they are not derailed by interim smaller changes.
I would suggest the process to be:
- gather other major ideas for capabilities that Geany should plan to
support
I just plopped #5 and #6 on to the list, wherever it ends up :)
- develop a design that supports these (or at least the most useful ones)
- look at how that design can be implemented, can the existing design be
mutated to it, or is it a clean framework that large parts of the existing functionality can plug into, or is it a whole clean implementation. This also includes issues like languages to use (C, C++, Vala, Haskell etc). 4. depending on the outcome from 3. use a new repository organisation or at least a new branch in the existing Geany repo to ensure that the existing Geany is not destabilised by major changes as they take place.
Yeah, some are quite huge changes, we couldn't be tip-toeing around trying not to touch too many lines of code or breaking config file or plugin APIs and stuff in the main branch as usual :) I think a separate branch on the main repository, as mentioned, would make the most sense.
This is something very different to the way Geany is currently operating, and I don't know if the community wants to consider such a more structured approach. If its felt that its worthwhile then I suggest that steps one and two are best achieved using the wiki and I will volunteer to set up and maintain page(s) for those phases at least.
So to summarise, what capabilities should Geany aspire to support, and what is the process to develop the best software architecture to support those capabilities.
I'm in/+1, if in doing so we fully adopt GObject/GTK+ and the normal/common/modern ways to do stuff using them. I'm not really interested to turn Geany into a non-GTK+ app or maintain separate backends or continue using painful old non-GObject C stuff, always having to avoid a lot of good APIs just for the sake of old supported build platforms and library versions. I'm willing to volunteer a considerable amount of time to helping out with it in the above case, and at least see where it goes, otherwise I'll just be a good tester of the re-design/branch :)
Cheers, Matthew Brush