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