This issue is to track the design and implementation of filetype-specific plugin API to allow tighter integration and for plugins to provide advanced IDE functionality to replace or enhance functionality what Geany currently provides in a generic and basic form.
One of the key features of Geany is its lightweight, generally useful language-agnostic support (eg. TM/ctags, generic build commands, customizable default filetype configurations, etc) and it would not be good to start embedding deep knowledge of specific programming languages into the core, this is why it's crucial that such advanced (read: bloated) features remain completely contained in some kind of plugin. No user should pay the cost for such language support for languages they don't use. It's also important that Geany always provide at least its current baseline functionality. Some of the default functionality could indeed be moved into such a plugin, but it should always be the default/fallback and should work out-of-the-box.
Since, for better or worse, we're already tightly tied with the GObject framework (via GTK+) and a GObject-based plugin loader is in the works by @kugel, I propose we use GObject interfaces where appropriate to provide object oriented, language neutral extension points for some or all of the needed features. Some of these interfaces could take some cues from [GtkSourceView's APIs where a plugin implements a "provider" interface](https://developer.gnome.org/gtksourceview/stable/GtkSourceCompletionProvider...) if it wants to provide the particular feature.
I have experimented in the past at trying to integrate libclang into a plugin to provide some of this support for C/C++, but I assume much of it would transfer over to other languages such as using libpython to enhance Python support, or V8 engine to enhance JavaScript.
## Requirements
Though there are probably some things I have not thought of, some of the requirements I've come up while experimenting with implementing this kind of advanced language features and run into road-blocks with are as follows:
- [ ] Allow plugins to provide syntax highlight.
Remark: This could be in the form of providing the Scintilla lexer, either by allowing plugging in as "container lexers" or by allowing plugins to provide a lexer library loaded dynamically into Scintilla (already supported by Scintilla). Alternatively we could provide some kind of interface non-specific to Scintilla for this and have Geany deal with making the styles appear on the screen. This is to allow for advanced semantic highlighting and the likes.
- [ ] Allow plugins to provide the symbols for the tagbar tree, based on their own knowledge of the current document.
Remark: It has been suggested that TagManager (with appropriate enhancements) may be suitable as a means of providing this information to Geany. Some kind of hook/provider interface would still be required in all cases.
- [ ] Allow plugins to provide the auto-complete list, given the current location in the document and the part of the word already typed.
Remark: In the future this could be extended to allow plugins to provide information required to insert those templates where, for example, if a particular function is completed, it inserts a "template" of the prototype and the caret jumps to the first editable position, like the function argument name, or if no arguments into the body of the template where the user probably wants to start typing, when you press tab it keeps jumping to the next editable template placeholder. Some IDEs such as XCode provide this, and I believe Scintilla has some kind of builtin support for implementing this. Further research is required. This particular enhancement could be added afterwards and should not block this issue.
- [ ] Allow plugins to provide a list of calltips to be shown when Geany shows the calltips.
Remark: In the future this could be extended to support additional features like enhanced keyboard navigation, ability to display documentation comment text, etc. Such enhancements should not block this issue.
- [ ] Allow plugins to hook into the build system runner.
Remark: Plugins should be able to provide not only the default build commands, but to dynamically modify them based on user's input (eg. through some configuration dialog they provide). This would allow plugins to do stuff like generating a Makefile based on the user's choices/source code and to update the build commands to run the Makefile in some particular directory, environment, etc.
- [ ] Allow plugins to provide diagnostics when build commands are run.
Remark: This could include not just allowing them to add compiler messages (which is already kind of supported if the plugin inserts Make-like change-directory messages and such into the compiler tab view), but also a more specific than current API for displaying diagnostic messages such as adding those various coloured squiggly lines below errors, putting diagnostic icons (eg. warning, info, error, etc) into the margin for affected lines, and also providing Scintilla annotations or tooltips to give the user more detailed information about the error when hovering over the squigglied text or margin markers. It should also be possible for plugins to nest further information in the compiler messages tab's treeview, so that it can show more than one line, like perhaps in the case of multiple definitions, where the original location was or other such information which may not make sense as the main information line in the compiler tab but can still be useful for some kinds of errors.
## Development/Contribution Strategy
I propose that we create a branch on the main repo (eg. "ft-plugins") against which all pull requests are made. The branch should be kept up to date at regular intervals with the development branch (ie. master) to prevent it getting stale and unmergable. Although it's a significant additional overhead, it would be nice if we could, when merging any changes to master branch, merge them also to and ensure no conflicts with the "ft-plugins" (or whichever) branch.
Everyone who is able should feel free to edit this issue description, but please limit it to gramatical and formatting corrections, adding references/links or if obvious information is missing. Please do fix this description if you are able to improve what it conveys without changing the overall meaning.
Since the changes won't be made on the stable master branch, I propose that we are much more aggressive with making changes, and are much more laid back with what changes get merged, even if not 100% in agreement with them. Once a pull request is merged, it can always be improved, tweaked, or even reverted later. The most useful kind of contribution is actual pull requests/commits. It is often the case with changes to the master branch that discussion ends up defeating progress, so I propose rather than endless discussions we let the code do a lot of the talking. Code reviews are always welcome but should be accompanied by the appropriate patches/PRs/commits. If one is not able/willing to contribute patches/PRs/commits directly, I propose that they wait until the particular changes are ready to be merged back to the master branch to raise minor issues (who knows maybe the issue has been removed or fixed by then). Of course it's useful to discuss fundamental design flaws regardless if one is willing to contribute code or not (see below).
## Discussion Guidelines
Since Github comments are not an ideal discussion platform and can grow out of control, as well as to include more people, foster broader discussions (bikesheds), and in order to keep this issue nice and clean, I propose that we do all of the discussion on the development mailing list. This suggestion is only for this particular Github issue, and need not apply to all related PRs, of course. If nobody minds, I would like to delete extaneous comments on this Github Issue, and keep the comments limited to such stuff as progress reports, meta discussions about the Github issue iself (assignees, labels, milestones), notes about a related PR, etc.
If there is a particular item you wish to discuss, quote it in your mailing list message and provide your suggestions, comments, issues, etc. I propose we choose some unique kind of tag (eg. "FT-Plugins") to put in the subject line of each related mailing list thread to improve searchability. This way we can look back in the archives and easily find related discussions regardless whether they all happened to be nested under a single thread.
Please feel free to "add your reaction" (thumbs up or down) whether you like the overal proposal presented here, in principle, even if not some of the details.