-
Notifications
You must be signed in to change notification settings - Fork 609
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Possible plugin extension interface for symbol tree #3910
base: master
Are you sure you want to change the base?
Conversation
If it has a refcount, why not make it a |
I just copied what was in |
Would need to check in detail. Have you looked the gtkdoc that's generated from the new interfaces? |
What should I look for exactly? My main worry is typedef struct
{
gboolean (*autocomplete_provided)(GeanyDocument *doc, gpointer data);
void (*autocomplete_perform)(GeanyDocument *doc, gboolean force, gpointer data);
gboolean (*calltips_provided)(GeanyDocument *doc, gpointer data);
void (*calltips_show)(GeanyDocument *doc, gboolean force, gpointer data);
gboolean (*goto_provided)(GeanyDocument *doc, gpointer data);
gboolean (*goto_perform)(GeanyDocument *doc, gint pos, gboolean definition, gpointer data);
gboolean (*symbol_highlight_provided)(GeanyDocument *doc, gpointer data);
} PluginExtension; which in C you would use this way: static gboolean autocomplete_provided(GeanyDocument *doc, gpointer user_data)
{
}
static void autocomplete_perform(GeanyDocument *doc, gboolean force, gpointer user_data)
{
}
static PluginExtension extension = {
.autocomplete_provided = autocomplete_provided,
.autocomplete_perform = autocomplete_perform
};
void plugin_init(G_GNUC_UNUSED GeanyData * data)
{
plugin_extension_register(&extension, 100, NULL);
} PluginExtension can also be allocated dynamically which would probably be necessary for other languages. Is such an interface OK for other languages? |
Generally speaking, non-C is supported well only for GObject-based interfaces. A python plugin can easily define a GObject-derived type purely implemented in Python. For anything else you need at least some supporting C code around. This is essentially what the "lib"-part of peasy does. It defines GObject-derived wrappers around existing Geany interfaces so that plugins make instances and inherit properly. Not all Geany interfaces need wrappers. We declare some of them as "GBoxed" such that the gobject-introspection magic makes them available to non-C languages automatically. We feed the gobject-introspection machinery mostly by converting the doxygen output to gtkdoc, and then have it generate the typelib from that. So for I asked specifically for |
(no time for this right now, but…) And for |
GBoxed works for non-C. You just have to add a non-C-friendly allocation/constructor because there's no generic |
That's a good point, it should be cheap because for the symbol tree code, all the typedef struct GeanySymbol
{
ExternalSymbol *ext;
TMTag *tag;
gint refcount;
} GeanySymbol; where
For GeanySymbol, this is hidden behind the two constructors: GeanySymbol *geany_symbol_new_from_tag(TMTag *tag);
GeanySymbol *geany_symbol_new(gchar *name, gchar *detail, gchar *scope, gchar *file,
TMParserType lang, glong kind, gulong line, gulong pos, guint icon); so I believe it should be satisfied already. |
This is one more attempt on unifying
TMTag
s and externally provided symbols for the symbol tree before giving up and making the plugins create the symbol tree by themselves (which leads to quite a significant code duplication). This time (unlike the previous attempts) I'm quite happy with the result though. I called the new structureGeanySymbol
- could be renamed to something else if someone has better idea.The idea is to make
GeanySymbol
operate in two modes:TMTag
and created usingGeanySymbol *geany_symbol_new_from_tag(TMTag *tag)
The corresponding structure looks this way:
where either
tag != NULL
when usinggeany_symbol_new_from_tag()
, ortag == NULL
forgeany_symbol_new()
.The important part is that the members of
GeanySymbol
cannot be accessed directly from other files but only using getters that either use thetag
or the member ofGeanySymbol
such asBy this interface, all callers like the symbol tree implementation are completely shielded from the details of where the symbol comes from. The bulk of the diffs inside
symbols.c
is pretty much just using this interface instead of usingTMTag
directly and renamingtag
tosymbol
.get_symbol_name()
andget_symbol_tooltip()
were moved toGeanySymbol
implementation, and also (previously inlined)geany_symbol_get_name_with_scope()
was moved there too.The additional
PluginExtension
interface for using these symbols would be more or less identical to what I proposed in #3850, i.e.and
void (*doc_symbols_request)(GeanyDocument *doc, GCallback on_done);
in this interface making Geany request the extension for symbols (asynchronously)symbol_tree_reload()
function the plugin could call which would make Geany re-request symbols usingdoc_symbols_get()
after the plugin gets them e.g. from the LSP server@b4n How does something like this sound? The implementation here is incomplete (only tested with the
TMTag
"backend" ofGeanySymbol
) but I don't want to continue in case you have some reservations regarding this approach.