83static void pm_show_dialog(GtkMenuItem *menuitem, gpointer user_data);
145 proxy = proxy->
proxy;
146 }
while (proxy !=
NULL);
157 proxy = proxy->
proxy;
158 }
while (proxy !=
NULL);
167 gchar *basename_module, *basename_loaded;
170 basename_module = g_path_get_basename(plugin->
filename);
173 basename_loaded = g_path_get_basename(((
Plugin*)item->data)->filename);
177 g_free(basename_loaded);
178 g_free(basename_module);
181 g_free(basename_loaded);
190 basename_loaded = g_path_get_basename(((
Plugin*)item->data)->filename);
194 g_free(basename_loaded);
195 g_free(basename_module);
198 g_free(basename_loaded);
200 g_free(basename_module);
209 g_return_val_if_fail(
filename, FALSE);
222#define PLUGIN_VERSION_CODE(api, abi) ((abi) != GEANY_ABI_VERSION ? -1 : (api))
228 if (plugin_version_code < 0)
232 "release of Geany - please recompile it."),
name);
233 geany_debug(
"Plugin \"%s\" is not binary compatible with this "
234 "release of Geany - recompile it.",
name);
241 geany_debug(
"Plugin \"%s\" requires a newer version of Geany (API >= v%d).",
242 name, plugin_version_code);
258 cb = &callbacks[len];
266 for (i = 0; i < len; i++)
283 g_module_symbol(module,
"plugin_key_group_info", (
void *) &p_key_info);
284 g_module_symbol(module,
"plugin_key_group", (
void *) &p_key_group);
285 if (p_key_info && p_key_group)
290 geany_debug(
"Ignoring plugin_key_group symbol for plugin '%s' - "
291 "use plugin_set_key_group() instead to allocate keybindings dynamically.",
300 *p_key_group = key_group;
303 geany_debug(
"Ignoring plugin_key_group_info symbol for plugin '%s' - "
304 "count field is zero. Maybe use plugin_set_key_group() instead?",
308 else if (p_key_info || p_key_group)
309 geany_debug(
"Ignoring only one of plugin_key_group[_info] symbols defined for plugin '%s'. "
310 "Maybe use plugin_set_key_group() instead?",
359 g_return_val_if_fail(plugin !=
NULL, FALSE);
374 cbs->
init ?
"cleanup" :
"init");
423 gint abi_version, gpointer pdata, GDestroyNotify free_func)
440 GtkWidget* (*configure) (GtkDialog *
dialog);
482 gint (*p_version_check) (gint abi_version);
488#define CHECK_FUNC(__x) \
489 if (! g_module_symbol(module, "plugin_" #__x, (void *) (&p_##__x))) \
491 geany_debug("Plugin \"%s\" has no plugin_" #__x "() function - ignoring plugin!", \
492 g_module_name(module)); \
509 g_module_symbol(module,
"geany_data", (
void *) &p_geany_data);
513 p_set_info(&plugin->
info);
517 g_module_symbol(module,
"plugin_configure", (
void *) &h->
configure);
518 g_module_symbol(module,
"plugin_configure_single", (
void *) &plugin->
configure_single);
519 g_module_symbol(module,
"plugin_help", (
void *) &h->
help);
520 g_module_symbol(module,
"plugin_cleanup", (
void *) &h->
cleanup);
522 g_module_symbol(module,
"plugin_callbacks", (
void *) &plugin->
cbs.
callbacks);
526 g_warning(
"Plugin '%s' implements plugin_configure_single() unnecessarily - "
527 "only plugin_configure() will be used!",
530 g_warning(
"Plugin '%s' has no plugin_cleanup() function - there may be memory leaks!",
547 gboolean init_ok = TRUE;
558 g_module_symbol(module,
"geany_plugin", (
void *) &p_geany_plugin);
560 *p_geany_plugin = &plugin->
public;
561 g_module_symbol(module,
"plugin_info", (
void *) &p_info);
563 *p_info = &plugin->
info;
564 g_module_symbol(module,
"plugin_fields", (
void *) &
plugin_fields);
606 g_return_val_if_fail(g_module_supported(),
NULL);
613 module = g_module_open(fname, G_MODULE_BIND_LOCAL);
616 geany_debug(
"Can't load plugin: %s", g_module_error());
621 g_module_symbol(module,
"geany_load_module", (
void *) &p_geany_load_module);
622 if (p_geany_load_module)
633 p_geany_load_module(subplugin);
648 GModule *module = (GModule *) load_data;
650 g_return_if_fail(module !=
NULL);
652 if (! g_module_close(module))
653 g_warning(
"%s: %s", subplugin->
priv->
filename, g_module_error());
667 g_return_val_if_fail(fname,
NULL);
668 g_return_val_if_fail(proxy,
NULL);
675 geany_debug(
"Plugin \"%s\" already loaded.", fname);
687 plugin = g_new0(
Plugin, 1);
689 plugin->
proxy = proxy;
699 geany_debug(
"Plugin \"%s\" already loaded.", fname);
709 geany_debug(
"Failed to load \"%s\" - ignoring plugin!", fname);
717 geany_debug(
"No plugin name set for \"%s\" - ignoring plugin!", fname);
726 geany_debug(
"Proxy of plugin \"%s\" specified invalid data - ignoring plugin!", fname);
735 geany_debug(
"Plugin failed to initialize \"%s\" - ignoring plugin!", fname);
760 g_return_if_fail(plugin && plugin->
signal_ids);
766 if (sc->
object == old_ptr)
768 g_array_remove_index_fast(plugin->
signal_ids, i);
791 if (signal_ids ==
NULL)
800 g_array_free(signal_ids, TRUE);
811 GList *next = item->next;
813 g_source_destroy(item->data);
829 g_warning(
"Skipping g_module_make_resident() for non-native plugin");
841 if (g_module_symbol(plugin->
proxy_data, sym, &symbol))
844 g_warning(
"Failed to locate signal handler for '%s': %s",
845 sym, g_module_error());
848 g_warning(
"Failed to locate signal handler for '%s': Not supported for non-native plugins",
863 const gchar *key = g_quark_to_string(key_id);
864 if (g_str_has_prefix(key, doc_data->
prefix))
907 gtk_widget_destroy(widget);
932 GList *next = g_list_next(item);
946 gboolean is_proxy = FALSE;
973 g_return_if_fail(plugin);
974 g_return_if_fail(plugin->
proxy);
977 proxy = plugin->
proxy;
1001 const gchar *plugin_path_system)
1003 gchar *plugin_path_custom;
1016 g_free(plugin_path_custom);
1019 return plugin_path_custom;
1027 gchar *plugin_path_config;
1028 gchar *plugin_path_system;
1029 gchar *plugin_path_custom;
1030 gboolean ret = FALSE;
1033 if (g_str_has_prefix(fname, plugin_path_config))
1037 if (g_str_has_prefix(fname, plugin_path_system))
1041 if (plugin_path_custom)
1043 if (g_str_has_prefix(fname, plugin_path_custom))
1046 g_free(plugin_path_custom);
1048 g_free(plugin_path_config);
1049 g_free(plugin_path_system);
1062 ext = (
const gchar *)strrchr(file,
'.');
1066 else if (strchr(ext, G_DIR_SEPARATOR) !=
NULL)
1091 g_warning(
"Ignoring bogus return value '%d' from "
1092 "proxy plugin '%s' probe() function!", ret,
1106 guint i, len, proxies;
1117 for (i = 0; i < len; i++)
1124 while ((p = strchr(p,
'/')) !=
NULL)
1125 *p = G_DIR_SEPARATOR;
1128 if (!
EMPTY(fname) && g_file_test(fname, G_FILE_TEST_EXISTS))
1144 GSList *
list, *item;
1149 for (item =
list; item !=
NULL; item = g_slist_next(item))
1151 gchar *fname = g_build_filename(path, item->data,
NULL);
1160 g_slist_foreach(
list, (GFunc) g_free,
NULL);
1199 gchar *plugin_path_config;
1200 gchar *plugin_path_system;
1201 gchar *plugin_path_custom;
1211 if (plugin_path_custom)
1214 g_free(plugin_path_custom);
1227 g_free(plugin_path_config);
1228 g_free(plugin_path_system);
1234 GList *item, *
list = gtk_container_get_children(GTK_CONTAINER(menu_item));
1236 gboolean have_plugin_menu_items = FALSE;
1238 for (item =
list; item !=
NULL; item = g_list_next(item))
1242 if (i < g_list_length(
list) - 1)
1244 have_plugin_menu_items = TRUE;
1265 widget = gtk_separator_menu_item_new();
1266 gtk_widget_show(widget);
1269 widget = gtk_menu_item_new_with_mnemonic(
_(
"_Plugin Manager"));
1271 gtk_widget_show(widget);
1315 const gchar *fname =
list->data;
1338 "load_plugins", TRUE,
"check_plugins");
1340 "custom_plugin_path",
"",
"extra_plugin_path_entry");
1385 Plugin *plugin = item->data;
1428 gboolean has_configure = FALSE;
1429 gboolean has_help = FALSE;
1430 gboolean has_keybindings = FALSE;
1452 GtkTreeModel *model;
1455 if (gtk_tree_selection_get_selected(selection, &model, &iter))
1470 for (valid = gtk_tree_model_get_iter_first(model, iter);
1472 valid = gtk_tree_model_iter_next(model, iter))
1488 gboolean old_state, state;
1491 GtkTreeIter store_iter;
1492 GtkTreePath *path = gtk_tree_path_new_from_string(pth);
1493 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(
pm_widgets.
tree));
1496 guint prev_num_proxies;
1498 gtk_tree_model_get_iter(model, &iter, path);
1500 gtk_tree_model_get(model, &iter,
1507 gtk_tree_path_free(path);
1511 gtk_tree_model_filter_convert_iter_to_child_iter(
1512 GTK_TREE_MODEL_FILTER(model), &store_iter, &iter);
1514 state = ! old_state;
1532 p =
plugin_new(proxy, file_name, state, TRUE);
1556 gboolean can_uncheck;
1557 GtkTreePath *store_path = gtk_tree_model_filter_convert_path_to_child_path(
1558 GTK_TREE_MODEL_FILTER(model), path);
1560 g_warn_if_fail(store_path !=
NULL);
1561 if (gtk_tree_path_up(store_path))
1563 gtk_tree_model_get_iter(GTK_TREE_MODEL(
pm_widgets.
store), &parent, store_path);
1566 can_uncheck = FALSE;
1573 gtk_tree_path_free(store_path);
1586 gtk_tree_view_expand_row(GTK_TREE_VIEW(
pm_widgets.
tree), path, FALSE);
1589 gtk_tree_path_free(path);
1598 gtk_tree_store_clear(store);
1602 gtk_tree_store_append(store, &iter,
NULL);
1615 gtk_tree_store_append(store, &iter, &parent);
1617 gtk_tree_store_append(store, &iter,
NULL);
1619 gtk_tree_store_set(store, &iter,
1629 gboolean keyboard_mode, GtkTooltip *tooltip, gpointer user_data)
1631 GtkTreeModel *model;
1635 gboolean can_uncheck = TRUE;
1637 if (! gtk_tree_view_get_tooltip_context(GTK_TREE_VIEW(widget), &x, &y, keyboard_mode,
1638 &model, &path, &iter))
1644 gchar *prefix, *suffix, *details, *markup;
1647 uchk = can_uncheck ?
1648 "" :
_(
"\n<i>Other plugins depend on this. Disable them first to allow deactivation.</i>\n");
1650 details = g_strdup_printf(
_(
"Version:\t%s\nAuthor(s):\t%s\nFilename:\t%s"),
1653 suffix = g_markup_printf_escaped(
"<small><i>\n%s</i></small>", details);
1654 markup = g_strconcat(prefix, uchk, suffix,
NULL);
1656 gtk_tooltip_set_markup(tooltip, markup);
1657 gtk_tree_view_set_tooltip_row(GTK_TREE_VIEW(widget), tooltip, path);
1664 gtk_tree_path_free(path);
1671 GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
1678 g_object_set(cell,
"text",
_(
"No plugins available."),
NULL);
1683 g_object_set(cell,
"markup", markup,
NULL);
1690 G_GNUC_UNUSED gpointer user_data)
1692 if (event->button == 3)
1695 event->button, event->time);
1718 gchar *normalized_string =
NULL;
1719 gchar *normalized_key =
NULL;
1720 gchar *case_normalized_string =
NULL;
1721 gchar *case_normalized_key =
NULL;
1722 gboolean matched = TRUE;
1724 normalized_string = g_utf8_normalize(haystack, -1, G_NORMALIZE_ALL);
1725 normalized_key = g_utf8_normalize(key, -1, G_NORMALIZE_ALL);
1727 if (normalized_string !=
NULL && normalized_key !=
NULL)
1729 GString *stripped_key;
1730 gchar **subkey, **subkeys;
1732 case_normalized_string = g_utf8_casefold(normalized_string, -1);
1733 case_normalized_key = g_utf8_casefold(normalized_key, -1);
1734 stripped_key = g_string_new(case_normalized_key);
1736 subkeys = g_strsplit(stripped_key->str,
" ", -1);
1737 g_string_free(stripped_key, TRUE);
1740 if (
strstr(case_normalized_string, *subkey) ==
NULL)
1746 g_strfreev(subkeys);
1749 g_free(normalized_key);
1750 g_free(normalized_string);
1751 g_free(case_normalized_key);
1752 g_free(case_normalized_string);
1784 GtkTreeModel *filter_model = gtk_tree_view_get_model(GTK_TREE_VIEW(
pm_widgets.
tree));
1785 gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(filter_model));
1790 GdkEvent *event, gpointer user_data)
1792 if (event->button.button == 1 && icon_pos == GTK_ENTRY_ICON_PRIMARY)
1799 GtkCellRenderer *text_renderer, *checkbox_renderer;
1800 GtkTreeViewColumn *column;
1801 GtkTreeModel *filter_model;
1802 GtkTreeSelection *sel;
1805 gtk_widget_set_has_tooltip(tree, TRUE);
1806 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree), FALSE);
1808 checkbox_renderer = gtk_cell_renderer_toggle_new();
1809 column = gtk_tree_view_column_new_with_attributes(
1810 _(
"Active"), checkbox_renderer,
1812 gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
1815 text_renderer = gtk_cell_renderer_text_new();
1816 g_object_set(text_renderer,
"ellipsize", PANGO_ELLIPSIZE_END,
NULL);
1817 column = gtk_tree_view_column_new_with_attributes(
_(
"Plugin"), text_renderer,
NULL);
1818 gtk_tree_view_column_set_cell_data_func(column, text_renderer,
1820 gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
1822 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(tree), TRUE);
1823 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(tree), FALSE);
1826 gtk_tree_sortable_set_sort_column_id(
1830 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
1831 gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
1837 filter_model = gtk_tree_model_filter_new(GTK_TREE_MODEL(store),
NULL);
1838 gtk_tree_model_filter_set_visible_func(
1842 gtk_tree_view_set_model(GTK_TREE_VIEW(tree), filter_model);
1843 g_object_unref(filter_model);
1851 GtkTreeModel *model;
1852 GtkTreeSelection *selection;
1856 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(
pm_widgets.
tree));
1857 if (gtk_tree_selection_get_selected(selection, &model, &iter))
1896 case GTK_RESPONSE_CLOSE:
1897 case GTK_RESPONSE_DELETE_EVENT:
1905 gtk_widget_destroy(GTK_WIDGET(
dialog));
1940 gtk_box_set_spacing(GTK_BOX(vbox), 6);
1950 gtk_dialog_add_button(GTK_DIALOG(
pm_widgets.
dialog), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
1951 gtk_dialog_set_default_response(GTK_DIALOG(
pm_widgets.
dialog), GTK_RESPONSE_CLOSE);
1955 gtk_entry_set_icon_from_stock(GTK_ENTRY(
filter_entry), GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_FIND);
1969 swin = gtk_scrolled_window_new(
NULL,
NULL);
1970 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin),
1971 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1972 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swin), GTK_SHADOW_IN);
1980 menu_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_PREFERENCES,
NULL);
1982 g_signal_connect(menu_item,
"activate",
1986 menu_item = gtk_image_menu_item_new_with_mnemonic(
_(
"Keybindings"));
1988 g_signal_connect(menu_item,
"activate",
1992 menu_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_HELP,
NULL);
1994 g_signal_connect(menu_item,
"activate",
1999 vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
2000 gtk_box_pack_start(GTK_BOX(vbox2),
label, FALSE, FALSE, 0);
2001 gtk_box_pack_start(GTK_BOX(vbox2),
filter_entry, FALSE, FALSE, 0);
2002 gtk_box_pack_start(GTK_BOX(vbox2), swin, TRUE, TRUE, 0);
2006 gtk_box_pack_start(GTK_BOX(vbox), vbox2, TRUE, TRUE, 0);
2049 g_return_val_if_fail(plugin !=
NULL, FALSE);
2050 g_return_val_if_fail(extensions !=
NULL, FALSE);
2051 g_return_val_if_fail(*extensions !=
NULL, FALSE);
2061 g_return_val_if_fail(p != proxy->
plugin, FALSE);
2068 g_warning(
_(
"Proxy plugin '%s' extension '%s' starts with a dot. "
2069 "Please fix your proxy plugin."), p->
info.
name, *ext);
File related dialogs, miscellaneous dialogs, font dialog.
GeanyFilePrefs file_prefs
GPtrArray * documents_array
#define DOC_VALID(doc_ptr)
Null-safe way to check GeanyDocument::is_valid.
GeanyEditorPrefs editor_prefs
Encoding conversion and Byte Order Mark (BOM) handling.
static GtkWidget * filter_entry
GtkWidget * geany_wrap_label_new(const gchar *text)
Syntax highlighting for the different filetypes, using the Scintilla lexers.
void keybindings_free_group(GeanyKeyGroup *group)
void keybindings_load_keyfile(void)
Reloads keybinding settings from configuration file.
void keybindings_write_to_file(void)
void keybindings_dialog_show_prefs_scroll(const gchar *name)
void configuration_save(void)
void configuration_add_pref_group(struct StashGroup *group, gboolean for_prefs_dialog)
void geany_debug(gchar const *format,...)
Main program-related commands.
void msgwin_status_add(const gchar *format,...)
Logs a formatted status message without setting the status bar.
Message window functions (status, compiler, messages windows).
This file defines the plugin API, the interface between Geany and its plugins.
#define GEANY_API_VERSION
The Application Programming Interface (API) version, incremented whenever any plugin data types are m...
void geany_plugin_set_data(GeanyPlugin *plugin, gpointer data, GDestroyNotify free_func)
Add additional data that corresponds to the plugin.
@ PLUGIN_IS_DOCUMENT_SENSITIVE
Whether a plugin's menu item should be disabled when there are no open documents.
@ GEANY_PROXY_IGNORE
The proxy is not responsible at all, and Geany or other plugins are free to probe it.
@ GEANY_PROXY_RELATED
The proxy is does not directly load it, but it's still tied to the proxy.
@ GEANY_PROXY_MATCH
The proxy is responsible for this file, and creates a plugin for it.
#define GEANY_ABI_VERSION
The Application Binary Interface (ABI) version, incremented whenever existing fields in the plugin da...
#define PLUGIN_LOADED_OK(p)
#define PLUGIN_HAS_LOAD_DATA(p)
#define PLUGIN_IS_LEGACY(p)
static gboolean check_plugin_path(const gchar *fname)
static gboolean pm_treeview_query_tooltip(GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, gpointer user_data)
static void pm_show_dialog(GtkMenuItem *menuitem, gpointer user_data)
static void pm_on_plugin_button_clicked(G_GNUC_UNUSED GtkButton *button, gpointer user_data)
static gboolean pm_tree_search(const gchar *key, const gchar *haystack)
static GList * plugin_list
static gboolean legacy_init(GeanyPlugin *plugin, gpointer pdata)
static void pm_update_buttons(Plugin *p)
static void free_non_active_plugin(gpointer data, gpointer user_data)
static void remove_callbacks(Plugin *plugin)
static void load_plugins_from_path(const gchar *path)
static Plugin * plugin_new(Plugin *proxy, const gchar *fname, gboolean load_plugin, gboolean add_to_list)
static void plugin_cleanup(Plugin *plugin)
void plugins_finalize(void)
void plugin_watch_object(Plugin *plugin, gpointer object)
static void plugin_free(Plugin *plugin)
static void on_tools_menu_show(GtkWidget *menu_item, G_GNUC_UNUSED gpointer user_data)
gpointer plugin_get_module_symbol(Plugin *plugin, const gchar *sym)
static void register_legacy_plugin(Plugin *plugin, GModule *module)
void plugin_make_resident(Plugin *plugin)
static gboolean find_iter_for_plugin(Plugin *p, GtkTreeModel *model, GtkTreeIter *iter)
static void load_all_plugins(void)
static gint cmp_plugin_by_proxy(gconstpointer a, gconstpointer b)
static void proxied_count_dec(Plugin *proxy)
static gboolean pm_treeview_button_press_cb(GtkWidget *widget, GdkEventButton *event, G_GNUC_UNUSED gpointer user_data)
static gint pm_tree_sort_func(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
static void proxied_count_inc(Plugin *proxy)
static void pm_dialog_response(GtkDialog *dialog, gint response, gpointer user_data)
static gboolean plugin_check_version(Plugin *plugin, int plugin_version_code)
static gpointer plugin_load_gmodule(GeanyPlugin *proxy, GeanyPlugin *plugin, const gchar *filename, gpointer pdata)
static void pm_prepare_treeview(GtkWidget *tree, GtkTreeStore *store)
static void free_subplugins(Plugin *proxy)
static void free_legacy_cbs(gpointer data)
static void on_object_weak_notify(gpointer data, GObject *old_ptr)
gboolean geany_plugin_register_full(GeanyPlugin *plugin, gint api_version, gint min_api_version, gint abi_version, gpointer pdata, GDestroyNotify free_func)
Register a plugin to Geany, with plugin-defined data.
@ PLUGIN_COLUMN_CAN_UNCHECK
static void update_active_plugins_pref(void)
static void pm_selection_changed(GtkTreeSelection *selection, gpointer user_data)
static PluginProxy builtin_so_proxy
static void pm_populate(GtkTreeStore *store)
static void remove_each_doc_data(GQuark key_id, gpointer data, gpointer user_data)
static void read_key_group(Plugin *plugin)
static gboolean unregister_proxy(Plugin *proxy)
static void geany_data_init(void)
static gboolean want_plugins
static void remove_doc_data(Plugin *plugin)
static void remove_sources(Plugin *plugin)
static gboolean pm_tree_filter_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
static gchar ** active_plugins_pref
static GeanyData geany_data
static gchar * get_custom_plugin_path(const gchar *plugin_path_config, const gchar *plugin_path_system)
static gchar * get_plugin_path(void)
static GQueue active_proxies
GList * active_plugin_list
gboolean geany_plugin_register(GeanyPlugin *plugin, gint api_version, gint min_api_version, gint abi_version)
Register a plugin to Geany.
static void pm_plugin_toggled(GtkCellRendererToggle *cell, gchar *pth, gpointer data)
static gboolean plugin_loaded(Plugin *plugin)
static void load_active_plugins(void)
static void legacy_help(GeanyPlugin *plugin, gpointer pdata)
static void plugin_free_leaf(Plugin *p)
static void add_callbacks(Plugin *plugin, PluginCallback *callbacks)
#define PLUGIN_VERSION_CODE(api, abi)
static GList * failed_plugins_list
void plugins_load_active(void)
gboolean plugins_have_preferences(void)
static void plugin_unload_gmodule(GeanyPlugin *proxy, GeanyPlugin *plugin, gpointer load_data, gpointer pdata)
static void on_pm_tree_filter_entry_icon_release_cb(GtkEntry *entry, GtkEntryIconPosition icon_pos, GdkEvent *event, gpointer user_data)
static void pm_treeview_text_cell_data_func(GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
static GtkWidget * menu_separator
static void on_pm_tree_filter_entry_changed_cb(GtkEntry *entry, gpointer user_data)
static gint cmp_plugin_names(gconstpointer a, gconstpointer b)
static PluginManagerWidgets pm_widgets
static gboolean plugin_load(Plugin *plugin)
static gboolean is_active_plugin(Plugin *plugin)
static Plugin * find_active_plugin_by_name(const gchar *filename)
static GtkWidget * legacy_configure(GeanyPlugin *plugin, GtkDialog *parent, gpointer pdata)
static void legacy_cleanup(GeanyPlugin *plugin, gpointer pdata)
static PluginProxy * is_plugin(const gchar *file)
static Plugin builtin_so_proxy_plugin
gboolean geany_plugin_register_proxy(GeanyPlugin *plugin, const gchar **extensions)
Register the plugin as a proxy for other plugins.
PluginFields * plugin_fields
Plugin owned fields, including flags.
void plugin_show_configure(GeanyPlugin *plugin)
Shows the plugin's configure dialog.
GeanyKeyGroup * plugin_set_key_group(GeanyPlugin *plugin, const gchar *section_name, gsize count, GeanyKeyGroupCallback callback)
<simplesect kind="geany:skip"></simplesect> Sets up or resizes a keybinding group for the plugin.
void plugin_signal_connect(GeanyPlugin *plugin, GObject *object, const gchar *signal_name, gboolean after, GCallback callback, gpointer user_data)
<simplesect kind="geany:skip"></simplesect> Connects a signal which will be disconnected on unloading...
Plugin utility functions.
GeanyToolPrefs tool_prefs
char * strstr(const char *str, const char *substr)
Wrapper functions for the Scintilla editor widget SCI_* messages.
GeanySearchPrefs search_prefs
GSList * filetypes_by_title
GPtrArray * filetypes_array
stash_group_add_toggle_button(group, &want_handle, "handle", TRUE, "check_handle")
gtk_container_add(GTK_CONTAINER(dialog->vbox), check_button)
gtk_widget_show_all(dialog)
void stash_group_add_string_vector(StashGroup *group, gchar ***setting, const gchar *key_name, const gchar **default_value)
Adds string vector setting (array of strings).
StashGroup * stash_group_new(const gchar *name)
Creates a new group.
void stash_group_add_entry(StashGroup *group, gchar **setting, const gchar *key_name, const gchar *default_value, StashWidgetID widget_id)
Adds a GtkEntry widget pref.
Lightweight library for reading/writing GKeyFile settings and synchronizing widgets with C variables.
gchar * configdir
User configuration directory, usually ~/.config/geany.
gboolean debug_mode
TRUE if debug messages should be printed.
This contains pointers to global variables owned by Geany for plugins to use.
Structure for representing an open tab with all its properties.
struct GeanyDocumentPrivate * priv
const gchar * name
Group name used in the configuration file, such as "html_chars".
gsize count
The number of keybindings the group will hold.
GtkWidget * window
Main window.
GtkWidget * tools_menu
Most plugins add menu items to the Tools menu.
Callback functions that need to be implemented for every plugin.
gboolean(* init)(GeanyPlugin *plugin, gpointer pdata)
Called to initialize the plugin, when the user activates it (must not be NULL)
GtkWidget *(* configure)(GeanyPlugin *plugin, GtkDialog *dialog, gpointer pdata)
plugins configure dialog, optional (can be NULL)
PluginCallback * callbacks
Array of plugin-provided signal handlers.
void(* help)(GeanyPlugin *plugin, gpointer pdata)
Called when the plugin should show some help, optional (can be NULL)
void(* cleanup)(GeanyPlugin *plugin, gpointer pdata)
Called when the plugin is disabled or when Geany exits (must not be NULL)
GeanyKeyGroup * key_group
void(* configure_single)(GtkWidget *parent)
GeanyProxyFuncs proxy_cbs
GeanyAutoSeparator toolbar_separator
GDestroyNotify cb_data_destroy
Basic information for the plugin and identification.
GeanyData * geany_data
Pointer to global GeanyData intance.
PluginInfo * info
Fields set in plugin_set_info().
GeanyProxyFuncs * proxy_funcs
Hooks implemented by the plugin if it wants to act as a proxy Must be set prior to calling geany_plug...
struct GeanyPluginPrivate * priv
GeanyPluginFuncs * funcs
Functions implemented by the plugin, set in geany_load_module()
gchar * custom_plugin_path
void(* unload)(GeanyPlugin *proxy, GeanyPlugin *subplugin, gpointer load_data, gpointer pdata)
Called when the user initiates unloading of a plugin, e.g.
gint(* probe)(GeanyPlugin *proxy, const gchar *filename, gpointer pdata)
Called to determine whether the proxy is truly responsible for the requested plugin.
gpointer(* load)(GeanyPlugin *proxy, GeanyPlugin *subplugin, const gchar *filename, gpointer pdata)
Called after probe(), to perform the actual job of loading the plugin.
GtkWidget *(* configure)(GtkDialog *dialog)
void(* init)(GeanyData *data)
Callback array entry type used with the plugin_callbacks symbol.
gpointer user_data
The user data passed to the signal handler.
GCallback callback
A callback function which is called when the signal is emitted.
gboolean after
Set to TRUE to connect your handler with g_signal_connect_after().
const gchar * signal_name
The name of signal, must be an existing signal.
PluginFlags flags
Bitmask of PluginFlags.
GtkWidget * menu_item
Pointer to a plugin's menu item which will be automatically enabled/disabled when there are no open d...
Basic information about a plugin available to Geany without loading the plugin.
const gchar * version
The version of the plugin.
const gchar * description
The description of the plugin.
const gchar * name
The name of the plugin.
const gchar * author
The author of the plugin.
Defines internationalization macros.
GeanyTemplatePrefs template_prefs
void ui_widget_show_hide(GtkWidget *widget, gboolean show)
void ui_add_document_sensitive(GtkWidget *widget)
Adds a widget to the list of widgets that should be set sensitive/insensitive when some documents are...
GtkWidget * ui_dialog_vbox_new(GtkDialog *dialog)
Makes a fixed border for dialogs without increasing the button box border.
GeanyMainWidgets main_widgets
void ui_entry_add_clear_icon(GtkEntry *entry)
Adds a small clear icon to the right end of the passed entry.
GeanyInterfacePrefs interface_prefs
User Interface general utility functions.
gint utils_str_casecmp(const gchar *s1, const gchar *s2)
A replacement function for g_strncasecmp() to compare strings case-insensitive.
guint utils_string_replace_all(GString *haystack, const gchar *needle, const gchar *replace)
Replaces all occurrences of needle in haystack with replace.
GSList * utils_get_file_list(const gchar *path, guint *length, GError **error)
Gets a sorted list of files from the specified directory.
void utils_tidy_path(gchar *filename)
const gchar * utils_resource_dir(GeanyResourceDirType type)
gboolean utils_str_equal(const gchar *a, const gchar *b)
NULL-safe string comparison.
gchar * utils_get_locale_from_utf8(const gchar *utf8_text)
Converts the given UTF-8 encoded string into locale encoding.
General utility functions, non-GTK related.
#define foreach_list(node, list)
Iterates all the nodes in list.
#define foreach_strv(str_ptr, strv)
Iterates a null-terminated string vector.
#define EMPTY(ptr)
Returns TRUE if ptr is NULL or *ptr is FALSE.
#define foreach_array(type, item, array)
Iterates all items in array.
#define foreach_list_safe(node, list)