On 11 November 2013 20:31, Matthew Brush <mbrush@codebrainz.ca> wrote:
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

To start the ball rolling, here are some of the things I see Geany should
aspire to:

1. 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).

Yes, it should be added to the list, even though it only occurs once.

2. 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.

Yes, augmenting the plugin interface to support extra functionality is one way to do it.

3. 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

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.

Yes, restricting Geany is also one of the possible solutions to put on the list too.

4. 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).

Yes, all suitable libraries should be examined and the implications that has on the rest of the design considered.
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.

Yes you are right, the plugin interface design should be examined as part of the process.


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:

1. gather other major ideas for capabilities that Geany should plan to

I just plopped #5 and #6 on to the list, wherever it ends up :)

Yes, thats the idea, the more ideas the better :).

2. develop a design that supports these (or at least the most useful ones)
3. 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.

Yes, at the very least a long term branch.

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

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 :)

Yes, and I'll keep those comments to be input to the step 2./3. phase.


Matthew Brush
Devel mailing list