Branch: refs/heads/master Author: Jiří Techet techet@gmail.com Committer: Jiří Techet techet@gmail.com Date: Sun, 30 Jun 2024 09:38:45 UTC Commit: 7a741bea339e74894ffdf537832d1ea9c039b34d https://github.com/geany/geany/commit/7a741bea339e74894ffdf537832d1ea9c039b3...
Log Message: ----------- Add interface used by plugins to replace some Geany functionality with their own implementation
Co-authored-by: Colomban Wendling ban@herbesfolles.org
Modified Paths: -------------- meson.build plugins/geanyplugin.h src/Makefile.am src/pluginextension.c src/pluginextension.h
Modified: meson.build 3 lines changed, 3 insertions(+), 0 deletions(-) =================================================================== @@ -759,6 +759,7 @@ install_headers( 'src/msgwindow.h', 'src/navqueue.h', 'src/plugindata.h', + 'src/pluginextension.h', 'src/pluginutils.h', 'src/prefs.h', 'src/project.h', @@ -820,6 +821,8 @@ libgeany = shared_library('geany', 'src/navqueue.h', 'src/notebook.c', 'src/notebook.h', + 'src/pluginextension.c', + 'src/pluginextension.h', 'src/plugins.c', 'src/plugins.h', 'src/pluginutils.c',
Modified: plugins/geanyplugin.h 1 lines changed, 1 insertions(+), 0 deletions(-) =================================================================== @@ -47,6 +47,7 @@ #include "msgwindow.h" #include "navqueue.h" #include "plugindata.h" +#include "pluginextension.h" #include "pluginutils.h" #include "prefs.h" #include "project.h"
Modified: src/Makefile.am 2 lines changed, 2 insertions(+), 0 deletions(-) =================================================================== @@ -51,6 +51,7 @@ geany_include_HEADERS = \ msgwindow.h \ navqueue.h \ plugindata.h \ + pluginextension.h \ pluginutils.h \ prefs.h \ project.h \ @@ -89,6 +90,7 @@ libgeany_la_SOURCES = \ msgwindow.c msgwindow.h \ navqueue.c navqueue.h \ notebook.c notebook.h \ + pluginextension.c pluginextension.h \ plugins.c plugins.h \ pluginutils.c pluginutils.h \ prefs.c prefs.h \
Modified: src/pluginextension.c 175 lines changed, 175 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,175 @@ +/* + * pluginextension.c - this file is part of Geany, a fast and lightweight IDE + * + * Copyright 2023 The Geany contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "pluginextension.h" + +#include "editor.h" + + +typedef struct +{ + PluginExtension *extension; + gpointer data; + gint priority; +} PluginExtensionEntry; + +static GList *all_extensions = NULL; + + +/* sort higher priorities first */ +static gint sort_extension_entries(gconstpointer a, gconstpointer b) +{ + const PluginExtensionEntry *entry_a = a; + const PluginExtensionEntry *entry_b = b; + + return entry_b->priority - entry_a->priority; +} + + +GEANY_API_SYMBOL +void plugin_extension_register(PluginExtension *extension, const gchar *ext_name, + gint priority, gpointer data) +{ + PluginExtensionEntry *entry; + + g_return_if_fail(ext_name != NULL); + + entry = g_malloc(sizeof *entry); + entry->extension = extension; + entry->data = data; + entry->priority = priority; + + all_extensions = g_list_insert_sorted(all_extensions, entry, sort_extension_entries); +} + + +GEANY_API_SYMBOL +void plugin_extension_unregister(PluginExtension *extension) +{ + for (GList *node = all_extensions; node; node = node->next) + { + PluginExtensionEntry *entry = node->data; + + if (entry->extension == extension) + { + g_free(entry); + all_extensions = g_list_delete_link(all_extensions, node); + break; + } + } +} + + +/* + * @brief Checks whether a feature is provided + * @param f The virtual function name + * @param doc The document to check the feature on + * @param ext A @c PluginExtension, or @c NULL + * @returns @c TRUE if the feature is provided, @c FALSE otherwise. If @p ext + * is @c NULL, it check whether any extension provides the feature; + * if it is an extension, it check whether it's this extension that + * provides the feature (taking into account possible overrides). + */ +#define CALL_PROVIDED(f, doc, ext) \ + G_STMT_START { \ + for (GList *node = all_extensions; node; node = node->next) \ + { \ + PluginExtensionEntry *entry = node->data; \ + \ + if (entry->extension->f && entry->extension->f(doc, entry->data)) \ + return (ext) ? entry->extension == (ext) : TRUE; \ + \ + if ((ext) && entry->extension == (ext)) \ + return FALSE; \ + } \ + return FALSE; \ + } G_STMT_END + +/* + * @brief Calls the extension implementation for f_provided/f_perform + * @param f_provided The name of the virtual function checking if the feature is provided + * @param doc The document to check the feature on + * @param f_perform The name of the virtual function implementing the feature + * @param args Arguments for @p f_perform. This should include @c entry->data as the last argument + * @param defret Return value if the feature is not implemented + * @returns The return value of @p f_perform or @p defret + */ +#define CALL_PERFORM(f_provided, doc, f_perform, args, defret) \ + G_STMT_START { \ + for (GList *node = all_extensions; node; node = node->next) \ + { \ + PluginExtensionEntry *entry = node->data; \ + \ + if (entry->extension->f_provided && \ + entry->extension->f_provided(doc, entry->data)) \ + { \ + if (entry->extension->f_perform) \ + return entry->extension->f_perform args; \ + break; \ + } \ + } \ + return defret; \ + } G_STMT_END + + +GEANY_API_SYMBOL +gboolean plugin_extension_autocomplete_provided(GeanyDocument *doc, PluginExtension *ext) +{ + CALL_PROVIDED(autocomplete_provided, doc, ext); +} + + +void plugin_extension_autocomplete_perform(GeanyDocument *doc, gboolean force) +{ + CALL_PERFORM(autocomplete_provided, doc, autocomplete_perform, (doc, force, entry->data), /* void */); +} + + +GEANY_API_SYMBOL +gboolean plugin_extension_calltips_provided(GeanyDocument *doc, PluginExtension *ext) +{ + CALL_PROVIDED(calltips_provided, doc, ext); +} + + +void plugin_extension_calltips_show(GeanyDocument *doc, gboolean force) +{ + CALL_PERFORM(calltips_provided, doc, calltips_show, (doc, force, entry->data), /* void */); +} + + +GEANY_API_SYMBOL +gboolean plugin_extension_goto_provided(GeanyDocument *doc, PluginExtension *ext) +{ + CALL_PROVIDED(goto_provided, doc, ext); +} + + +gboolean plugin_extension_goto_perform(GeanyDocument *doc, gint pos, gboolean definition) +{ + CALL_PERFORM(goto_provided, doc, goto_perform, (doc, pos, definition, entry->data), FALSE); +} + + +GEANY_API_SYMBOL +gboolean plugin_extension_symbol_highlight_provided(GeanyDocument *doc, PluginExtension *ext) +{ + CALL_PROVIDED(symbol_highlight_provided, doc, ext); +}
Modified: src/pluginextension.h 64 lines changed, 64 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,64 @@ +/* + * pluginextension.h - this file is part of Geany, a fast and lightweight IDE + * + * Copyright 2023 The Geany contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef GEANY_PLUGIN_EXTENSION_H +#define GEANY_PLUGIN_EXTENSION_H 1 + +#include "document.h" + + +G_BEGIN_DECLS + +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); + + void (*_dummy[100])(void); +} PluginExtension; + + +void plugin_extension_register(PluginExtension *extension, const gchar *ext_name, + gint priority, gpointer data); +void plugin_extension_unregister(PluginExtension *extension); + +gboolean plugin_extension_autocomplete_provided(GeanyDocument *doc, PluginExtension *ext); +gboolean plugin_extension_calltips_provided(GeanyDocument *doc, PluginExtension *ext); +gboolean plugin_extension_goto_provided(GeanyDocument *doc, PluginExtension *ext); +gboolean plugin_extension_symbol_highlight_provided(GeanyDocument *doc, PluginExtension *ext); + +#ifdef GEANY_PRIVATE + +void plugin_extension_autocomplete_perform(GeanyDocument *doc, gboolean force); +void plugin_extension_calltips_show(GeanyDocument *doc, gboolean force); +gboolean plugin_extension_goto_perform(GeanyDocument *doc, gint pos, gboolean definition); + +#endif /* GEANY_PRIVATE */ + +G_END_DECLS + +#endif /* GEANY_PLUGIN_EXTENSION_H */
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).