If you used Geany’s source editor, you’ve probably come across a poorly predictable behavior for standard auto-close parentheses and quotes. If not used - I recommend to try.
Geany is a great editor, but throughout its history, auto-close worked like this:
func())
or so:
')
func() { }}
It is time to put an end to the manual placement of brackets. Meet the new auto-close mode in Geany:

Preamble
In Geany, there is a “native” autocompletion mode and auto-close (not to be confused: auto-completion is for functions and methods, and auto-close is for paired brackets and quotes). It would seem that the essence of the algorithm is simple: we monitor the pressing of one character and insert the corresponding pair. However, there is a whole pile of pitfalls, diving into which you can fill a lot of cones.
Problem 1 : people got used to the notebook. Many automatically and immediately put the opening bracket and closing, the result does not take long:
f()) f();) f() {}} f("abc"");
Have you decided to remove the bracket with a backspace? Get:
f()) -> f))
This auto-close mode only does a disservice, so it's easier to turn it off immediately.
Problem 2 : brackets and quotes have different meanings in different languages. For example, in C ++, curly braces usually define block boundaries, and in Bash this may simply be part of a variable. Geany is a multilingual editor, and it would not hurt to take into account the features of each language separately.
Problem 3 : In many editors, when a piece of text is selected and a brace / quote is clicked, the selected text “turns” into this symbol. In Geany, this text is simply deleted.
Problem 4 : you may never have suspected this, but in Geany, while holding the Shift, the selection goes into block mode (Multiline Selection). Needless to say that auto-close in this mode is not supported in any way. And it is quite difficult to implement it, since block allocation captures “virtual” spaces:

And there is also a clipboard in the editor, an undo / redo clipboard, hotkeys and it all somehow has to work together ...
Decision
Since such problems are not at all to face the notepad of the 21st century, it was decided to implement auto-close
as an add-on to Geany . Fortunately, the API makes it easy to do. No sooner said than done, by a strong-willed decision, the plug-in was included in the geany-plugins project and will be available as an alternative auto-hide mode in the next version of Geany (for this, it will be enough to tick the plug-ins menu).
What is he able at the moment? And he can do quite a lot:
- of course, the completion of the characters {}, [], (), "", '', <>, ``
- turn off / turn off auto-completion within lines and comments
- smart termination: pair brackets are removed automatically, double closes are suppressed
- puts selected text in parentheses, preserving selection
- auto-terminate functions:
sin(|);
and structures / classes: struct {|};
- by pressing Tab, the cursor jumps to the pair symbol (as in Eclipse)
- pressing Shift + BackSpace removes the pair brace, and for curly braces, indentation is removed (as in the screenshot at the beginning of the article)
In addition, features of different languages are taken into account: for si-like, for example, it is enough to select a piece of text and press {so that a new block appears; for Bash, the auto-closeback quote is enabled; for HTML, <> characters and the like are completed. Also, auto-indents are greatly improved for C-like languages.
How does it work?
Geany is based on Scintilla, which provides a fairly diverse API in terms of working with text buffers. The idea as usual is simple: we monitor keystrokes and, depending on the circumstance, we react to the environment. But this was not the case: there was a
fatal flaw in Scintilla, due to which the API allows you to track all keystrokes, except for backspace. Trifle? And how would you like to track the event of deleting a symbol?
As a result, I had to spit and build an event handler, bypassing the Scintilla API and using pure GLib. The complexity of this crutch is that you need to correctly handle the opening and closing of the document (and there can be many tabs) so that you do not accidentally hook several handlers for one event or not hook there altogether. For example, a typical bug in the Addons plugin is that the handler is attached to the main window. Now plugin events are triggered everywhere - even in the terminal. In general, if you ever have to write a plugin for Geany, and the standard Scintilla API is not enough, you can always find a stable implementation of the crutch in the
Autoclose plugin.
The rest is a boring series of switches and conditions. From interesting - check on the validity of the pointer to the document - doc. There are a lot of plugins on this nuance: the developers unknowingly check the function argument like all normal people:
if(NULL == doc) return;
The problem with Geany is that doc can be strictly not NULL, but when you try to access it, it will be a segfolt. How so? It turns out that inside Geany actively reuses pointers. If the stars fail and at the time of the check the document will be closed, its pointer may become incorrect or even point to a completely different document. To avoid collisions, you need to check the document with the macro DOC_VALID.
It should be noted that Geany himself steps on his own rake: a mysterious segolt,
fortune-telling on an assembly dump, and the result is to
check doc for NULL in the most key document loading function.
How to install?
At the moment, the addition is in git head, that is, it has not yet been released with the release of Geany. The plugin will appear only in version 1.24, but you can use it now in one of the following ways:
- download an experimental, not yet released into the release of Geany 1.24 from the so-called "night builds" - everything is already there:
nightly.geany.org- download the plugin separately and try to build it under the old version
- try to take the autoclose library from nightly builds and slip it into 1.23, but no guarantees
Attention! The second method is for extremes only.- you need to download the source geany-plugins from the gita:
github.com/scriptum/geany-plugins- download source geany-plugins for version 1.23:
www.geany.org/Download/Releases- copy the autoclose plugin to version 1.23 and try to build the plugin inside the source 1.23
Immediately it will not be collected, because you need to register the plugin in all autotools-scripts that are not scattered in a very obvious way.
Do not be afraid of using the nightly build: all the changes in Geany are thoroughly tested and checked, moreover, a large number of bugs and leaks were fixed in 1.24, many useful features were added, I would say that it is much more stable than the “stable” 1.23. After installation, you will need to enable the Autoclose plugin in the plugin menu and into battle.
What's next?
The plugin is decided to leave the plugin. After baptism by release, it will be moved to Geany (Autoclose will remain a plugin, but will be part of Geany itself, not the geany-plugins project), after which the old functionality will most likely be removed directly from the editor. He does not solve the problem of auto-completion, this is a topic for a separate (and quite large) work, there are rumors in IRC that they are trying to fasten clang to Geany, but shhh ... :)
In the meantime, during the period of pre-release languor, I invite readers to report bugs or express wishes. In particular, there are no support for languages that I have very vague ideas about.