Branch: refs/heads/master
Author: Thomas Martitz <kugel(a)rockbox.org>
Committer: Thomas Martitz <kugel(a)rockbox.org>
Date: Mon, 05 Oct 2015 20:11:12 UTC
Commit: 3ccf959013edb6744ab58f6953a2b44dfb1abef3
https://github.com/geany/geany/commit/3ccf959013edb6744ab58f6953a2b44dfb1ab…
Log Message:
-----------
plugins: introduce probe() for proxy plugins
When a file extension alone is ambigious as to whether a potential plugin is
really handled then the proxy should use the probe hook to find out. This can
be especially helpful when two pluxies work on the same file extension.
The proxy's probe() should return PROXY_IGNORED or PROXY_MATCHED accordingly.
A special flag value, PROXY_NOLOAD, can be or'ed into PROXY_MATCHED to say
that the file belongs to the proxy, but isn't directly loaded and should not
be handled by any other proxy or geany itself.
Example for PROXY_IGNORED:
geanypy only supports python2 at the moment. So, scripts written
for python3 aren't handled by it and should be skipped for the PM dialog.
Or perhaps they are handled by another proxy that supports python3.
Example for PROXY_NOLOAD:
A pluxy registers for the metadata file extension (.plugin) where author etc
is in. The actual implmentation is in a python script (.py). The .py file
is tied to the .plugin and should not be processed by other pluxies. Thus,
the pluxy also registers for the .py extension but returns
PROXY_MATCHED|PROXY_NOLOAD for it (if it would return only PROXY_MATCHED
the sub-plugin would show up twice in the PM dialog).
Modified Paths:
--------------
src/plugindata.h
src/plugins.c
Modified: src/plugindata.h
10 lines changed, 10 insertions(+), 0 deletions(-)
===================================================================
@@ -347,9 +347,19 @@ void geany_plugin_set_data(GeanyPlugin *plugin, gpointer data, GDestroyNotify fr
geany_plugin_register_full((plugin), GEANY_API_VERSION, \
(min_api_version), GEANY_ABI_VERSION, (pdata), (free_func))
+typedef enum
+{
+ PROXY_IGNORED,
+ PROXY_MATCHED,
+
+ PROXY_NOLOAD = 0x100,
+}
+GeanyProxyProbeResults;
+
/* Hooks that need to be implemented for every proxy */
typedef struct _GeanyProxyFuncs
{
+ gint (*probe) (GeanyPlugin *proxy, const gchar *filename, gpointer pdata);
gpointer (*load) (GeanyPlugin *proxy, GeanyPlugin *subplugin, const gchar *filename, gpointer pdata);
void (*unload) (GeanyPlugin *proxy, GeanyPlugin *subplugin, gpointer load_data, gpointer pdata);
}
Modified: src/plugins.c
17 lines changed, 16 insertions(+), 1 deletions(-)
===================================================================
@@ -953,7 +953,22 @@ static PluginProxy* is_plugin(const gchar *file)
{
if (utils_str_casecmp(ext, proxy->extension) == 0)
{
- return proxy;
+ Plugin *p = proxy->plugin;
+ gint ret = PROXY_MATCHED;
+
+ if (p->proxy_cbs.probe)
+ ret = p->proxy_cbs.probe(&p->public, file, p->cb_data);
+ switch (ret)
+ {
+ case PROXY_MATCHED:
+ return proxy;
+ case PROXY_MATCHED|PROXY_NOLOAD:
+ return NULL;
+ default:
+ if (ret != PROXY_IGNORED)
+ g_warning("Ignoring bogus return from proxy probe!\n");
+ continue;
+ }
}
}
return NULL;
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
Branch: refs/heads/master
Author: Thomas Martitz <kugel(a)rockbox.org>
Committer: Thomas Martitz <kugel(a)rockbox.org>
Date: Mon, 05 Oct 2015 20:11:12 UTC
Commit: 8ac9d56fff28a6a8b296bfde3f7c047bc8762e61
https://github.com/geany/geany/commit/8ac9d56fff28a6a8b296bfde3f7c047bc8762…
Log Message:
-----------
plugins: reselect when toggling the current plugin
When enabling/disabling pluxys in the PM dialog the list of available
plugins might change. If plugins before the pluxy go/come then the wrong
plugin becomes selected (the selected row number stays the same). Re-apply
the selection to the current one in the toggle callback to overcome this issue.
Modified Paths:
--------------
src/plugins.c
Modified: src/plugins.c
53 lines changed, 53 insertions(+), 0 deletions(-)
===================================================================
@@ -1301,6 +1301,41 @@ static void pm_selection_changed(GtkTreeSelection *selection, gpointer user_data
}
+static gboolean find_iter_for_plugin(Plugin *p, GtkTreeModel *model, GtkTreeIter *iter)
+{
+ Plugin *pp;
+ gboolean valid;
+
+ for (valid = gtk_tree_model_get_iter_first(model, iter);
+ valid;
+ valid = gtk_tree_model_iter_next(model, iter))
+ {
+ gtk_tree_model_get(model, iter, PLUGIN_COLUMN_PLUGIN, &pp, -1);
+ if (p == pp)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static gboolean select_plugin(gpointer data)
+{
+ GtkTreeIter iter;
+ Plugin *p = data;
+ GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(pm_widgets.tree));
+
+ /* restore selection */
+ if (find_iter_for_plugin(p, model, &iter))
+ {
+ GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(pm_widgets.tree));
+ gtk_tree_selection_select_iter(sel, &iter);
+ }
+
+ return G_SOURCE_REMOVE;
+}
+
+
static void pm_populate(GtkListStore *store);
@@ -1314,6 +1349,7 @@ static void pm_plugin_toggled(GtkCellRendererToggle *cell, gchar *pth, gpointer
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(pm_widgets.tree));
Plugin *p;
Plugin *proxy;
+ guint prev_num_proxies;
gtk_tree_model_get_iter(model, &iter, path);
gtk_tree_path_free(path);
@@ -1334,6 +1370,7 @@ static void pm_plugin_toggled(GtkCellRendererToggle *cell, gchar *pth, gpointer
/* save the filename and proxy of the plugin */
file_name = g_strdup(p->filename);
proxy = p->proxy;
+ prev_num_proxies = active_proxies->len;
/* unload plugin module */
if (!state)
@@ -1362,6 +1399,19 @@ static void pm_plugin_toggled(GtkCellRendererToggle *cell, gchar *pth, gpointer
/* set again the sensitiveness of the configure and help buttons */
pm_update_buttons(p);
}
+ /* We need to find out if a proxy was added or removed because that affects the plugin list
+ * presented by the plugin manager. The current solution counts active_proxies twice,
+ * this suboptimal from an algorithmic POV, however most efficient for the extremely small
+ * number (at most 3) of pluxies we expect users to load */
+ if (prev_num_proxies != active_proxies->len)
+ {
+ /* Rescan the plugin list as we now support more */
+ if (prev_num_proxies < active_proxies->len)
+ load_all_plugins();
+ pm_populate(pm_widgets.store);
+ /* restore selection. doesn't work if it's done immediately (same row keeps selected) */
+ g_idle_add(select_plugin, p);
+ }
g_free(file_name);
}
@@ -1524,6 +1574,9 @@ static gboolean pm_tree_filter_func(GtkTreeModel *model, GtkTreeIter *iter, gpoi
gchar *haystack, *filename;
gtk_tree_model_get(model, iter, PLUGIN_COLUMN_PLUGIN, &plugin, -1);
+
+ if (!plugin)
+ return FALSE;
key = gtk_entry_get_text(GTK_ENTRY(pm_widgets.filter_entry));
filename = g_path_get_basename(plugin->filename);
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
Branch: refs/heads/master
Author: Thomas Martitz <kugel(a)rockbox.org>
Committer: Thomas Martitz <kugel(a)rockbox.org>
Date: Mon, 05 Oct 2015 20:09:36 UTC
Commit: d008675b1bb1360f32360c98f54175783c5f0f2f
https://github.com/geany/geany/commit/d008675b1bb1360f32360c98f54175783c5f0…
Log Message:
-----------
plugins: introduce load and unload functions for plugins
Currently they encapsulate loading and unloading of standard plugins. In
the future plugins can provide such functions to load their types of plugins.
Such a dummy proxy plugin is implemented now to load standard plugins so
that these aren't going to be specially handled.
Modified Paths:
--------------
src/plugindata.h
src/pluginprivate.h
src/plugins.c
Modified: src/plugindata.h
9 lines changed, 9 insertions(+), 0 deletions(-)
===================================================================
@@ -347,6 +347,15 @@ void geany_plugin_set_data(GeanyPlugin *plugin, gpointer data, GDestroyNotify fr
geany_plugin_register_full((plugin), GEANY_API_VERSION, \
(min_api_version), GEANY_ABI_VERSION, (pdata), (free_func))
+/* Hooks that need to be implemented for every proxy */
+typedef struct _GeanyProxyFuncs
+{
+ void (*load) (GeanyPlugin *proxy, GeanyPlugin *subplugins, const gchar *filename, gpointer pdata);
+ void (*unload) (GeanyPlugin *proxy, GeanyPlugin *subplugins, gpointer pdata);
+}
+GeanyProxyFuncs;
+
+
/* Deprecated aliases */
#ifndef GEANY_DISABLE_DEPRECATED
Modified: src/pluginprivate.h
9 lines changed, 6 insertions(+), 3 deletions(-)
===================================================================
@@ -46,6 +46,8 @@ typedef enum _LoadedFlags {
}
LoadedFlags;
+typedef struct GeanyPluginPrivate Plugin; /* shorter alias */
+
typedef struct GeanyPluginPrivate
{
GModule *module;
@@ -66,6 +68,10 @@ typedef struct GeanyPluginPrivate
gpointer cb_data; /* user data passed back to functions in GeanyPluginFuncs */
GDestroyNotify cb_data_destroy; /* called when the plugin is unloaded, for cb_data */
LoadedFlags flags; /* bit-or of LoadedFlags */
+
+ /* proxy plugin support */
+ GeanyProxyFuncs proxy_cbs;
+ Plugin *proxy; /* The proxy that handles this plugin */
}
GeanyPluginPrivate;
@@ -73,9 +79,6 @@ GeanyPluginPrivate;
#define PLUGIN_IS_LEGACY(p) (((p)->flags & IS_LEGACY) != 0)
#define PLUGIN_HAS_LOAD_DATA(p) (((p)->flags & LOAD_DATA) != 0)
-typedef GeanyPluginPrivate Plugin; /* shorter alias */
-
-
void plugin_watch_object(Plugin *plugin, gpointer object);
G_END_DECLS
Modified: src/plugins.c
237 lines changed, 162 insertions(+), 75 deletions(-)
===================================================================
@@ -75,8 +75,31 @@ static GtkWidget *menu_separator = NULL;
static gchar *get_plugin_path(void);
static void pm_show_dialog(GtkMenuItem *menuitem, gpointer user_data);
-static GeanyData geany_data;
+typedef struct {
+ gchar extension[8];
+ Plugin *plugin; /* &builtin_so_proxy_plugin for native plugins */
+} PluginProxy;
+
+
+static void plugin_load_gmodule(GeanyPlugin *proxy, GeanyPlugin *plugin, const gchar *filename, gpointer pdata);
+static void plugin_unload_gmodule(GeanyPlugin *proxy, GeanyPlugin *plugin, gpointer pdata);
+
+static Plugin builtin_so_proxy_plugin = {
+ .proxy_cbs = {
+ .load = plugin_load_gmodule,
+ .unload = plugin_unload_gmodule,
+ },
+ /* rest of Plugin can be NULL/0 */
+};
+
+static PluginProxy builtin_so_proxy = {
+ .extension = G_MODULE_SUFFIX,
+ .plugin = &builtin_so_proxy_plugin,
+};
+static GPtrArray *active_proxies = NULL;
+
+static GeanyData geany_data;
static void
geany_data_init(void)
@@ -105,16 +128,15 @@ geany_data_init(void)
/* Prevent the same plugin filename being loaded more than once.
* Note: g_module_name always returns the .so name, even when Plugin::filename is a .la file. */
static gboolean
-plugin_loaded(GModule *module)
+plugin_loaded(Plugin *plugin)
{
gchar *basename_module, *basename_loaded;
GList *item;
- basename_module = g_path_get_basename(g_module_name(module));
+ basename_module = g_path_get_basename(plugin->filename);
for (item = plugin_list; item != NULL; item = g_list_next(item))
{
- basename_loaded = g_path_get_basename(
- g_module_name(((Plugin*)item->data)->module));
+ basename_loaded = g_path_get_basename(((Plugin*)item->data)->filename);
if (utils_str_equal(basename_module, basename_loaded))
{
@@ -131,7 +153,7 @@ plugin_loaded(GModule *module)
* would cause a crash. */
for (item = active_plugin_list; item != NULL; item = g_list_next(item))
{
- basename_loaded = g_path_get_basename(g_module_name(((Plugin*)item->data)->module));
+ basename_loaded = g_path_get_basename(((Plugin*)item->data)->filename);
if (utils_str_equal(basename_module, basename_loaded))
{
@@ -168,19 +190,19 @@ static Plugin *find_active_plugin_by_name(const gchar *filename)
static gboolean
plugin_check_version(Plugin *plugin, int plugin_version_code)
{
- GModule *module = plugin->module;
+ const gchar *name = g_module_name(plugin->module);
if (plugin_version_code < 0)
{
msgwin_status_add(_("The plugin \"%s\" is not binary compatible with this "
- "release of Geany - please recompile it."), g_module_name(module));
+ "release of Geany - please recompile it."), name);
geany_debug("Plugin \"%s\" is not binary compatible with this "
- "release of Geany - recompile it.", g_module_name(module));
+ "release of Geany - recompile it.", name);
return FALSE;
}
- if (plugin_version_code > GEANY_API_VERSION)
+ else if (plugin_version_code > GEANY_API_VERSION)
{
geany_debug("Plugin \"%s\" requires a newer version of Geany (API >= v%d).",
- g_module_name(module), plugin_version_code);
+ name, plugin_version_code);
return FALSE;
}
return TRUE;
@@ -425,7 +447,7 @@ static void register_legacy_plugin(Plugin *plugin, GModule *module)
if (! g_module_symbol(module, "plugin_" #__x, (void *) (&p_##__x))) \
{ \
geany_debug("Plugin \"%s\" has no plugin_" #__x "() function - ignoring plugin!", \
- g_module_name(plugin->module)); \
+ g_module_name(module)); \
return; \
}
CHECK_FUNC(version_check);
@@ -481,8 +503,9 @@ static gboolean
plugin_load(Plugin *plugin)
{
gboolean init_ok = TRUE;
+
/* Start the plugin. Legacy plugins require additional cruft. */
- if (PLUGIN_IS_LEGACY(plugin))
+ if (PLUGIN_IS_LEGACY(plugin) && plugin->proxy == &builtin_so_proxy_plugin)
{
GeanyPlugin **p_geany_plugin;
PluginInfo **p_info;
@@ -531,20 +554,70 @@ plugin_load(Plugin *plugin)
}
+static void plugin_load_gmodule(GeanyPlugin *proxy, GeanyPlugin *subplugin, const gchar *fname, gpointer pdata)
+{
+ GModule *module;
+ void (*p_geany_load_module)(GeanyPlugin *);
+
+ g_return_val_if_fail(g_module_supported(), NULL);
+ /* Don't use G_MODULE_BIND_LAZY otherwise we can get unresolved symbols at runtime,
+ * causing a segfault. Without that flag the module will safely fail to load.
+ * G_MODULE_BIND_LOCAL also helps find undefined symbols e.g. app when it would
+ * otherwise not be detected due to the shadowing of Geany's app variable.
+ * Also without G_MODULE_BIND_LOCAL calling public functions e.g. the old info()
+ * function from a plugin will be shadowed. */
+ module = g_module_open(fname, G_MODULE_BIND_LOCAL);
+ if (!module)
+ {
+ geany_debug("Can't load plugin: %s", g_module_error());
+ return;
+ }
+
+ subplugin->priv->module = module;
+ /*geany_debug("Initializing plugin '%s'", plugin->info.name);*/
+ g_module_symbol(module, "geany_load_module", (void *) &p_geany_load_module);
+ if (p_geany_load_module)
+ {
+ /* This is a new style plugin. It should fill in plugin->info and then call
+ * geany_plugin_register() in its geany_load_module() to successfully load.
+ * The ABI and API checks are performed by geany_plugin_register() (i.e. by us).
+ * We check the LOADED_OK flag separately to protect us against buggy plugins
+ * who ignore the result of geany_plugin_register() and register anyway */
+ p_geany_load_module(subplugin);
+ }
+ else
+ {
+ /* This is the legacy / deprecated code path. It does roughly the same as
+ * geany_load_module() and geany_plugin_register() together for the new ones */
+ register_legacy_plugin(subplugin->priv, module);
+ }
+ /* We actually check the LOADED_OK flag later */
+}
+
+
+static void plugin_unload_gmodule(GeanyPlugin *proxy, GeanyPlugin *subplugin, gpointer pdata)
+{
+ GModule *module = subplugin->priv->module;
+
+ g_return_if_fail(module);
+
+ if (! g_module_close(module))
+ g_warning("%s: %s", subplugin->priv->filename, g_module_error());
+}
+
+
/* Load and optionally init a plugin.
* load_plugin decides whether the plugin's plugin_init() function should be called or not. If it is
* called, the plugin will be started, if not the plugin will be read only (for the list of
* available plugins in the plugin manager).
* When add_to_list is set, the plugin will be added to the plugin manager's plugin_list. */
static Plugin*
-plugin_new(const gchar *fname, gboolean load_plugin, gboolean add_to_list)
+plugin_new(Plugin *proxy, const gchar *fname, gboolean load_plugin, gboolean add_to_list)
{
Plugin *plugin;
- GModule *module;
- void (*p_geany_load_module)(GeanyPlugin *);
g_return_val_if_fail(fname, NULL);
- g_return_val_if_fail(g_module_supported(), NULL);
+ g_return_val_if_fail(proxy, NULL);
/* find the plugin in the list of already loaded, active plugins and use it, otherwise
* load the module */
@@ -563,64 +636,37 @@ plugin_new(const gchar *fname, gboolean load_plugin, gboolean add_to_list)
return plugin;
}
- /* Don't use G_MODULE_BIND_LAZY otherwise we can get unresolved symbols at runtime,
- * causing a segfault. Without that flag the module will safely fail to load.
- * G_MODULE_BIND_LOCAL also helps find undefined symbols e.g. app when it would
- * otherwise not be detected due to the shadowing of Geany's app variable.
- * Also without G_MODULE_BIND_LOCAL calling public functions e.g. the old info()
- * function from a plugin will be shadowed. */
- module = g_module_open(fname, G_MODULE_BIND_LOCAL);
- if (! module)
- {
- geany_debug("Can't load plugin: %s", g_module_error());
- return NULL;
- }
-
- if (plugin_loaded(module))
- {
- geany_debug("Plugin \"%s\" already loaded.", fname);
-
- if (! g_module_close(module))
- g_warning("%s: %s", fname, g_module_error());
- return NULL;
- }
-
plugin = g_new0(Plugin, 1);
- plugin->module = module;
plugin->filename = g_strdup(fname);
+ plugin->proxy = proxy;
plugin->public.geany_data = &geany_data;
plugin->public.priv = plugin;
/* Fields of plugin->info/funcs must to be initialized by the plugin */
plugin->public.info = &plugin->info;
plugin->public.funcs = &plugin->cbs;
- g_module_symbol(module, "geany_load_module", (void *) &p_geany_load_module);
- if (p_geany_load_module)
- {
- /* This is a new style plugin. It should fill in plugin->info and then call
- * geany_plugin_register() in its geany_load_module() to successfully load.
- * The ABI and API checks are performed by geany_plugin_register() (i.e. by us).
- * We check the LOADED_OK flag separately to protect us against buggy plugins
- * who ignore the result of geany_plugin_register() and register anyway */
- p_geany_load_module(&plugin->public);
- }
- else
+ if (plugin_loaded(plugin))
{
- /* This is the legacy / deprecated code path. It does roughly the same as
- * geany_load_module() and geany_plugin_register() together for the new ones */
- register_legacy_plugin(plugin, module);
+ geany_debug("Plugin \"%s\" already loaded.", fname);
+ goto err;
}
+ /* Load plugin, this should read its name etc. It must also call
+ * geany_plugin_register() for the following PLUGIN_LOADED_OK condition */
+ proxy->proxy_cbs.load(&proxy->public, &plugin->public, fname, proxy->cb_data);
+
if (! PLUGIN_LOADED_OK(plugin))
{
geany_debug("Failed to load \"%s\" - ignoring plugin!", fname);
goto err;
}
+ /* The proxy assumes success, therefore we have to call unload from here
+ * on in case of errors */
if (EMPTY(plugin->info.name))
{
geany_debug("No plugin name set for \"%s\" - ignoring plugin!", fname);
- goto err;
+ goto err_unload;
}
if (load_plugin && !plugin_load(plugin))
@@ -628,7 +674,7 @@ plugin_new(const gchar *fname, gboolean load_plugin, gboolean add_to_list)
/* Handle failing init same as failing to load for now. In future we
* could present a informational UI or something */
geany_debug("Plugin failed to initialize \"%s\" - ignoring plugin!", fname);
- goto err;
+ goto err_unload;
}
if (add_to_list)
@@ -636,11 +682,11 @@ plugin_new(const gchar *fname, gboolean load_plugin, gboolean add_to_list)
return plugin;
-err:
+err_unload:
if (plugin->cb_data_destroy)
plugin->cb_data_destroy(plugin->cb_data);
- if (! g_module_close(module))
- g_warning("%s: %s", fname, g_module_error());
+ proxy->proxy_cbs.unload(&proxy->public, &plugin->public, proxy->cb_data);
+err:
g_free(plugin->filename);
g_free(plugin);
return NULL;
@@ -754,21 +800,19 @@ plugin_cleanup(Plugin *plugin)
static void
plugin_free(Plugin *plugin)
{
+ Plugin *proxy;
+
g_return_if_fail(plugin);
- g_return_if_fail(plugin->module);
+ g_return_if_fail(plugin->proxy);
+ proxy = plugin->proxy;
if (is_active_plugin(plugin))
plugin_cleanup(plugin);
active_plugin_list = g_list_remove(active_plugin_list, plugin);
plugin_list = g_list_remove(plugin_list, plugin);
- /* cb_data_destroy might be plugin code and must be called before unloading the module */
- if (plugin->cb_data_destroy)
- plugin->cb_data_destroy(plugin->cb_data);
-
- if (! g_module_close(plugin->module))
- g_warning("%s: %s", plugin->filename, g_module_error());
+ proxy->proxy_cbs.unload(&proxy->public, &plugin->public, proxy->cb_data);
g_free(plugin->filename);
g_free(plugin);
@@ -830,6 +874,36 @@ static gboolean check_plugin_path(const gchar *fname)
}
+/* Retuns NULL if this ain't a plugin,
+ * otherwise it returns the appropriate PluginProxy instance to load it */
+static PluginProxy* is_plugin(const gchar *file)
+{
+ PluginProxy *proxy;
+ const gchar *ext;
+ guint i;
+
+ /* extract file extension to avoid g_str_has_suffix() in the loop */
+ ext = (const gchar *)strrchr(file, '.');
+ if (ext == NULL)
+ return FALSE;
+ /* ensure the dot is really part of the filename */
+ else if (strchr(ext, G_DIR_SEPARATOR) != NULL)
+ return FALSE;
+
+ ext += 1;
+ /* O(n*m), (m being extensions per proxy) doesn't scale very well in theory
+ * but not a problem in practice yet */
+ foreach_ptr_array(proxy, i, active_proxies)
+ {
+ if (utils_str_casecmp(ext, proxy->extension) == 0)
+ {
+ return proxy;
+ }
+ }
+ return NULL;
+}
+
+
/* load active plugins at startup */
static void
load_active_plugins(void)
@@ -843,9 +917,19 @@ load_active_plugins(void)
{
const gchar *fname = active_plugins_pref[i];
+#ifdef G_OS_WIN32
+ /* ensure we have canonical paths */
+ gchar *p = fname;
+ while ((p = strchr(p, '/')) != NULL)
+ *p = G_DIR_SEPARATOR;
+#endif
+
if (!EMPTY(fname) && g_file_test(fname, G_FILE_TEST_EXISTS))
{
- if (!check_plugin_path(fname) || plugin_new(fname, TRUE, FALSE) == NULL)
+ PluginProxy *proxy = NULL;
+ if (check_plugin_path(fname))
+ proxy = is_plugin(fname);
+ if (proxy == NULL || plugin_new(proxy->plugin, fname, TRUE, FALSE) == NULL)
failed_plugins_list = g_list_prepend(failed_plugins_list, g_strdup(fname));
}
}
@@ -856,20 +940,18 @@ static void
load_plugins_from_path(const gchar *path)
{
GSList *list, *item;
- gchar *fname, *tmp;
gint count = 0;
list = utils_get_file_list(path, NULL, NULL);
for (item = list; item != NULL; item = g_slist_next(item))
{
- tmp = strrchr(item->data, '.');
- if (tmp == NULL || utils_str_casecmp(tmp, "." G_MODULE_SUFFIX) != 0)
- continue;
+ gchar *fname = g_build_filename(path, item->data, NULL);
+ PluginProxy *proxy = is_plugin(fname);
- fname = g_build_filename(path, item->data, NULL);
- if (plugin_new(fname, FALSE, TRUE))
+ if (proxy != NULL && plugin_new(proxy->plugin, fname, FALSE, TRUE))
count++;
+
g_free(fname);
}
@@ -1028,6 +1110,9 @@ void plugins_init(void)
g_signal_connect(geany_object, "save-settings", G_CALLBACK(update_active_plugins_pref), NULL);
stash_group_add_string_vector(group, &active_plugins_pref, "active_plugins", NULL);
+
+ active_proxies = g_ptr_array_sized_new(1);
+ g_ptr_array_add(active_proxies, &builtin_so_proxy);
}
@@ -1146,6 +1231,7 @@ static void pm_plugin_toggled(GtkCellRendererToggle *cell, gchar *pth, gpointer
GtkTreePath *path = gtk_tree_path_new_from_string(pth);
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(pm_widgets.tree));
Plugin *p;
+ Plugin *proxy;
gtk_tree_model_get_iter(model, &iter, path);
gtk_tree_path_free(path);
@@ -1163,8 +1249,9 @@ static void pm_plugin_toggled(GtkCellRendererToggle *cell, gchar *pth, gpointer
state = ! old_state; /* toggle the state */
- /* save the filename of the plugin */
+ /* save the filename and proxy of the plugin */
file_name = g_strdup(p->filename);
+ proxy = p->proxy;
/* unload plugin module */
if (!state)
@@ -1174,7 +1261,7 @@ static void pm_plugin_toggled(GtkCellRendererToggle *cell, gchar *pth, gpointer
plugin_free(p);
/* reload plugin module and initialize it if item is checked */
- p = plugin_new(file_name, state, TRUE);
+ p = plugin_new(proxy, file_name, state, TRUE);
if (!p)
{
/* plugin file may no longer be on disk, or is now incompatible */
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
Branch: refs/heads/master
Author: Frank Lanitz <frank(a)frank.uvena.de>
Committer: Frank Lanitz <frank(a)frank.uvena.de>
Date: Sun, 04 Oct 2015 12:54:13 UTC
Commit: 2b69a0cde688cc5ce679facd420261c19e680346
https://github.com/geany/talks/commit/2b69a0cde688cc5ce679facd420261c19e680…
Log Message:
-----------
Adding short README on how to get reveal.js into tree
Modified Paths:
--------------
en/A_short_introduction/README.md
Modified: en/A_short_introduction/README.md
6 lines changed, 6 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,6 @@
+To get revel.js you will have to get the submodule. Do:
+
+$ git submodule init
+$ git submodule update
+
+for it. Done.
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
Branch: refs/heads/master
Author: Frank Lanitz <frank(a)frank.uvena.de>
Committer: Frank Lanitz <frank(a)frank.uvena.de>
Date: Sun, 04 Oct 2015 12:50:55 UTC
Commit: 6bc60f2a5226ed215ebdb37ad91a8535309ce3bd
https://github.com/geany/talks/commit/6bc60f2a5226ed215ebdb37ad91a8535309ce…
Log Message:
-----------
EN: Change used theme and put some content into structure
Modified Paths:
--------------
en/A_short_introduction/index.html
Modified: en/A_short_introduction/index.html
73 lines changed, 72 insertions(+), 1 deletions(-)
===================================================================
@@ -15,7 +15,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
<link rel="stylesheet" href="reveal.js/css/reveal.css">
- <link rel="stylesheet" href="reveal.js/css/theme/black.css" id="theme">
+ <link rel="stylesheet" href="reveal.js/css/theme/moon.css" id="theme">
<!-- Code syntax highlighting -->
<link rel="stylesheet" href="reveal.js/lib/css/zenburn.css">
@@ -95,24 +95,65 @@
<section>
<section>
<h1>Features</h1>
+ <p>This is just a selection</p>
</section>
<section>
<h3>Syntaxhighlighting</h3>
+ <ul>
+ <li>More than 60 file types</li>
+ <li>Based upon Scintilla-Projekt</li>
+ <li>Done with C++ classes -- so called Lexxer</li>
+ <li>Automatic detection and manual set-able</li>
+ <li>Self-defined file types (using shippid Lexxer)</li>
+ </ul>
</section>
<section>
<h3>Build menu</h3>
+ <ul>
+ <li>Consists of: <ul>
+ <li>File type depending entries</li>
+ <li>Generic entries</li>
+ <li>Project based commands</li>
+ </ul></li>
+ <li>Can be adjusted for personal needs</li>
+ </ul>
+ <p><img src="../../de/img/build_menu.svg" alt="LaTeX-Build menu of Genay"></p>
</section>
<section>
<h3>Keyboard shortcuts</h3>
+ <ul>
+ <li>Many functions can be controlled via keybaord short cur</li>
+ <li>Can be reconfigured either via config file or via dialog</li>
+ <li>Pluings can register own keyboard shortcuts</li>
+ </ul>
</section>
<section>
<h3>Templates</h3>
+ <ul>
+ <li>Saves a lot of typing work</li>
+ <li>Most can be extended/overwritten by user</li>
+ <li>Differrent kind of templates: <ul>
+ <li>New files / file templates</li>
+ <li>Placeholder for common stubs like GPL/BSD licence notification</li>
+ <li>Code snippets</li>
+ </ul>
</section>
<section>
<h3>File-Templates</h3>
+ <ul>
+ <li>Useful for often used tasks</li>
+ <li>Might include placeholders like it's own filename</li>
+ <li>Geany is offering a basic collection; own templates below <code>~/.config/geany/templates/files</code></li>
+ </ul>
</section>
<section>
<h3>Snippets</h3>
+ <ul>
+ <li>Reoccuring text passages can be replaces with a "shortcut"</li>
+ <li>Geany is offering a list of generic and file type specific ones</li>
+ <li>Can be extended by user</li>
+ <li>Many examples inside <a href="http://wiki.geany.org/snippets/start">Wiki</a></li>
+ </ul>
</section>
<section>
<h3>Example RegEx</h3>
@@ -126,12 +167,42 @@
</section>
<section>
<h3>Autocompletion</h3>
+ <ul>
+ <li>Hybrid of static approach & information of current session</li>
+ <li>Configurable:<ul>
+ <li>... how many letters to start showing suggestions</li>
+ <li>... shall often used words be included (useful for LaTeX, HTML)</li>
+ </ul></li>
+ <li>Static "Tages" are loaded from files</li>
+ <li>File type specific</li>
+ <li>Tag files are listed inside the <a href="http://wiki.geany.org/tags/start">Wiki</a> </li>
+ <li>Tag-files can be generated by Geany from e.g. project</li>
+ </ul>
</section>
<section>
<h3>Symbol browser & document browser</h3>
+ <ul>
+ <li>Located on side bar</li>
+ <li>Fast access to symboles (variable defintion, functions ...) with mouse</li>
+ <li>Fast access to open documents</li>
+ </ul>
</section>
<section>
<h3>Plugin interface</h3>
+ <ul>
+ <li>Huge number of plugins</li>
+ <li>API/Binding for C, Python and Lua</li>
+ <li>Examples: <ul>
+ <li>GeanyVC</li>
+ <li>git-changebar</li>
+ <li>Projectorganizer</li>
+ <li>Addons</li>
+ <li>DevHelp</li>
+ <li>Webhelper</li>
+ <li>Scope & Debugger</li>
+ </ul></li>
+ <li>More bindings coming soon</li>
+ </ul>
</section>
</section>
<section>
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
Branch: refs/heads/master
Author: Frank Lanitz <frank(a)frank.uvena.de>
Committer: Frank Lanitz <frank(a)frank.uvena.de>
Date: Sun, 04 Oct 2015 11:04:41 UTC
Commit: 1aed5bb821217974449ec9d6f220db862eb0861a
https://github.com/geany/talks/commit/1aed5bb821217974449ec9d6f220db862eb08…
Log Message:
-----------
EN: Adding generel and meta information
Modified Paths:
--------------
en/A_short_introduction/index.html
Modified: en/A_short_introduction/index.html
34 lines changed, 34 insertions(+), 0 deletions(-)
===================================================================
@@ -60,6 +60,40 @@
<li>Meta</li>
</ol>
</section>
+ <section>
+ <h3>About me</h3>
+ <ul>
+ <li>Professional nerd with background in economics working for a Operations-as-a-Service-company</li>
+ <li>10 years user of Geany</li>
+ <li>Maintainer of geany-plugins</li>
+ <li>Coordinator of translation work</li>
+ </ul>
+ </section>
+ </section>
+ <section>
+ <section>
+ <h1>General overview</h1>
+ </section>
+ <section>
+ <h3>About Geany</h3>
+ <ul>
+ <li>Editor with features of an IDE</li>
+ <li>Under development since 2005</li>
+ <li>Current version 1.25 released summer 2015</li>
+ <li>Main goals
+ <ul>
+ <li>Low system requirements (running on Raspberry)</li>
+ <li>Low further dependencies</li>
+ </ul>
+ </li>
+ <li>Written in C and C++</li>
+ <li>Based upon Scintilla and GTK2</li>
+ <li>Licence: GPLv2+</li>
+ </ul>
+ </section>
+ </section>
+ <section>
+ <h1>The End</h1>
</section>
</div>
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).