Hi All,
Related to my previous mail, and assuming it is somewhat reasonable, I would like to propose a list of initial features that will be useful to allow plugins to provide, in no particular order:
----
Syntax Highlighting -------------------
Most likely using an API based on/similar to Scintilla's "container lexers".
At the minimum, it could have a callback something like:
gboolean (*highlight)(GeanyPlugin*, GeanyDocument*, guint start_pos, guint end_pos, gpointer user_data);
As with Scintilla's "container lexer", it would just tell the provider what and where to highlight. It might be pointless providing `end_pos` it could probably just highlight a whole line at time (maybe like Scintilla's 'style-needed' notification).
If the providers are to setup their own colour schemes and such, then it may be required to add a callback such as:
gboolean (*init_styles)(GeanyPlugin*, GeanyDocument*, gpointer user_data);
for the plugin to configure all the Scintilla styles as it wishes. This will probably require some kind of conflict avoidance scheme if it is to support multiple providers providing the same feature. Perhaps it could also pass the start style ID the provider can use, and it could tell Geany the maximum style that it ended up using.
Sidebar Symbol Tree -------------------
Could provide some API functions to populate the tree by plugins providing the needed information. The nesting could be handled by passing a scope path similar to GtkTreePath or TagManager's `::` delimited scope string, which would be parsed/expanded to apply to the right tree node.
The callback function for the provider might be like:
gboolean (*populate_symbols_tree)(GeanyPlugin*, GeanyDocument*, guint cursor_pos, gchar **current_node_path /* out */, gpointer user_data);
When the providers are called in to, they could use a function something like this:
void tagbar_add_node(const gchar *name, guint line, const gchar *signature, const gchar *scope_path, GeanySidebarIcon icon);
I haven't looked closely at the existing sidebar/symbols code yet, maybe it already provides such a function that could be used. It has also been mentioned that this could be done using the TagManager API. Plugins would walk their own internal ASTs or tag lists and build up the TM tag array, and Geany would use it for updating the symbols tree as it currently does (IIUC). I don't know much about TM so I can't really give an example callback for such an API.
Auto-Completion/Intellisense ----------------------------
This could be triggered at the exact same time in the same way it is now (and re-using the same preferences). It could call a callback function in the ft-plugins like:
gboolean (*complete_at)(GeanyPlugin *, GeanyDocument *, guint position, const gchar *partial_word, GPtrArray completion_list /* out */, gpointer user_data);
The `completion_list` would be filled in with whatever the provider thinks could be completed at `position`. It could be made more advanced in the future like allowing plugins to give icons, argument lists, documentation comment text, etc. For now it could just give strings to directly populate Scintilla's auto-complete listbox.
Calltips --------
To provide calltips, a provider could be called into like:
gboolean (*provide_calltips)(GeanyPlugin*, GeanyDocument*, guint position, const gchar *symbol, GPtrArray *overloads /* out */, gpointer user_data);
The `overloads` array would populated by the provider with the various overloads for the given `symbol` (function). As with auto-completion, at first this could just be a list of overloads represented as strings which directly populate Scintilla's calltip infos. This could be enhanced in the future to provide documentation comment text and placeholder insertion points into the editor in the future, but for now should be kept simple (see GtkSourceView, XCode, etc).
Go To Declaration/Definition ----------------------------
This could be either single callback passing a parameter to tell whether declaration or definition, or two separate callbacks. An example of the callbacks could be:
struct SourceLocation { gchar *filename; guint position; };
gboolean (*get_declaration_location)(GeanyPlugin*, GeanyDocument*, guint position, const gchar *symbol, GPtrArray *results, gpointer user_data);
and likewise for `get_definition_location`. The `results` array could be populated with `SourceLocation`s for each possible definition/declaration. For example there might be multiple declarations in different `#if` blocks you could jump to, for C-like languages. Geany already provides a UI popup list to pick where to jump, this should be re-used.
Build/Run Support -----------------
I haven't thought much on this yet, but in general there should be a way for ft-plugins to get called into when a the build/run features are activated.
Diagnostics -----------
I also haven't thought much on this yet. It needs to be possible for ft-plugins, after getting notified of build/run events, to be able to update diagnostics information.
Some of the diagnostics display might include:
- Scintilla marker margin icons, indicating the type of diagnostic info present for each line (could be more than one per line). - Scintilla indicators (little coloured squigglies) showing the specific range(s) of code where the diagnostics apply. - Scintilla annotations giving further details on request. - Tooltip messages when hovering over the marker margins or squigglied text giving further details. - Putting lines of diagnostics info in the msgwin compiler tab (already supported to some extent IIUC).
Refactoring -----------
This is just an idea that is probably long in the future, but ft-plugins could provide some common re-factorings (ex. rename, generate definition code, etc). I haven't thought on this much at all yet.
----
Almost surely I have left some out. What do you think?
Cheers, Matthew Brush