[geany/geany-plugins] e14283: Adds word wrapping feature to Addons plugin.

Alex M git-noreply at xxxxx
Mon Jan 23 08:38:24 UTC 2012


Branch:      refs/heads/master
Author:      Alex M <mam214 at lehigh.edu>
Committer:   Frank Lanitz <frank at frank.uvena.de>
Date:        Mon, 23 Jan 2012 08:38:24
Commit:      e14283c7e0172043fe05e1038c65440ff6a48c89
             https://github.com/geany/geany-plugins/commit/e14283c7e0172043fe05e1038c65440ff6a48c89

Log Message:
-----------
Adds word wrapping feature to Addons plugin.

Gives two methods for selecting text and wrapping it with characters
(such as parenthesis).  Both are enabled/disabled via the standard
Addon plugin preferences.


Modified Paths:
--------------
    addons/README
    addons/src/Makefile.am
    addons/src/addons.c
    addons/src/ao_wrapwords.c
    addons/src/ao_wrapwords.h
    po/POTFILES.in

Modified: addons/README
13 files changed, 13 insertions(+), 0 deletions(-)
===================================================================
@@ -26,6 +26,7 @@ Features
  * Highlighting all occurrences of a word when double-clicking it
  * Strip trailing blank lines when saving
  * XMLtagging
+ * Wrap selected text with characters
 
 Usage
 -----
@@ -79,6 +80,17 @@ XML tagging allows to easy tag a selected text, by checking for a
 selection, offering a little dialog for inserting a tag and
 replacing a selection.
 
+*Wrapping selected text*
+^^^^^^^^^^^^^^^^^^^^^^^^
+Provides two methods for wrapping selected text in characters.  If the 'Wrap
+selection automatically' option is checked in Preferences, selected text will
+be surrounded when certain characters are pressed (e.g. highlight a string and 
+press ", the string will be surrounded in double quotes).  Also allows you to 
+define up to eight of your own opening and closing character pairs, which can 
+then be linked to a keybinding (e.g. set [ and ] to be Wrap Pair 1 and the
+keybinding to ctrl+[ , highlight some text and press ctrl+[ to surround the 
+selected text in brackets).
+
 Requirements
 ------------
 
@@ -89,3 +101,4 @@ Contact developers
 ------------------
 
 #geany IRC channel on FreeNode
+


Modified: addons/src/Makefile.am
4 files changed, 3 insertions(+), 1 deletions(-)
===================================================================
@@ -16,6 +16,7 @@ addons_la_SOURCES = \
 	ao_markword.h \
 	ao_tasks.h \
 	ao_xmltagging.h \
+	ao_wrapwords.h \
 	addons.c \
 	ao_blanklines.c \
 	ao_doclist.c \
@@ -24,7 +25,8 @@ addons_la_SOURCES = \
 	ao_bookmarklist.c \
 	ao_markword.c \
 	ao_tasks.c \
-	ao_xmltagging.c
+	ao_xmltagging.c \
+	ao_wrapwords.c
 
 addons_la_LIBADD = $(COMMONLIBS)
 


Modified: addons/src/addons.c
47 files changed, 45 insertions(+), 2 deletions(-)
===================================================================
@@ -37,7 +37,7 @@
 #include "ao_markword.h"
 #include "ao_tasks.h"
 #include "ao_xmltagging.h"
-
+#include "ao_wrapwords.h"
 
 
 GeanyPlugin		*geany_plugin;
@@ -77,6 +77,8 @@ enum
 	gboolean enable_bookmarklist;
 	gboolean enable_markword;
 	gboolean enable_xmltagging;
+	gboolean enable_wrapwords;
+	gboolean enable_wrapwords_auto;
 	gboolean strip_trailing_blank_lines;
 
 	gchar *tasks_token_list;
@@ -271,6 +273,10 @@ void plugin_init(GeanyData *data)
 		"addons", "strip_trailing_blank_lines", FALSE);
 	ao_info->enable_xmltagging = utils_get_setting_boolean(config, "addons",
 		"enable_xmltagging", FALSE);
+	ao_info->enable_wrapwords = utils_get_setting_boolean(config, "addons",
+		"enable_wrapwords", FALSE);
+	ao_info->enable_wrapwords_auto = utils_get_setting_boolean(config, "addons",
+		"enable_wrapwords_auto", FALSE);
 
 	plugin_module_make_resident(geany_plugin);
 
@@ -285,7 +291,7 @@ void plugin_init(GeanyData *data)
 	ao_blanklines_set_enable(ao_info->strip_trailing_blank_lines);
 
 	/* setup keybindings */
-	key_group = plugin_set_key_group(geany_plugin, "addons", KB_COUNT, NULL);
+	key_group = plugin_set_key_group(geany_plugin, "addons", KB_COUNT+8, NULL);
 	keybindings_set_item(key_group, KB_FOCUS_BOOKMARK_LIST, kb_bmlist_activate,
 		0, 0, "focus_bookmark_list", _("Focus Bookmark List"), NULL);
 	keybindings_set_item(key_group, KB_FOCUS_TASKS, kb_tasks_activate,
@@ -295,6 +301,9 @@ void plugin_init(GeanyData *data)
 	keybindings_set_item(key_group, KB_XMLTAGGING, kb_ao_xmltagging,
 		0, 0, "xml_tagging", _("Run XML tagging"), NULL);
 
+	ao_wrapwords_init(ao_info->config_file, key_group);
+	ao_wrapwords_set_enabled (ao_info->enable_wrapwords, ao_info->enable_wrapwords_auto);
+
 	g_key_file_free(config);
 }
 
@@ -359,6 +368,12 @@ static void ao_configure_response_cb(GtkDialog *dialog, gint response, gpointer
 			g_object_get_data(G_OBJECT(dialog), "check_blanklines"))));
 		ao_info->enable_xmltagging = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
 			g_object_get_data(G_OBJECT(dialog), "check_xmltagging"))));
+		ao_info->enable_wrapwords = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
+			g_object_get_data(G_OBJECT(dialog), "check_wrapwords"))));
+		ao_info->enable_wrapwords_auto = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
+			g_object_get_data(G_OBJECT(dialog), "check_wrapwords_auto"))));
+
+		ao_wrapwords_set_enabled (ao_info->enable_wrapwords, ao_info->enable_wrapwords_auto);
 
 		g_key_file_load_from_file(config, ao_info->config_file, G_KEY_FILE_NONE, NULL);
 		g_key_file_set_boolean(config, "addons",
@@ -377,6 +392,10 @@ static void ao_configure_response_cb(GtkDialog *dialog, gint response, gpointer
 		  ao_info->strip_trailing_blank_lines);
 		g_key_file_set_boolean(config, "addons", "enable_xmltagging",
 			ao_info->enable_xmltagging);
+		g_key_file_set_boolean(config, "addons", "enable_wrapwords",
+			ao_info->enable_wrapwords);
+		g_key_file_set_boolean(config, "addons", "enable_wrapwords_auto",
+			ao_info->enable_wrapwords_auto);
 
 		g_object_set(ao_info->doclist, "enable-doclist", ao_info->enable_doclist, NULL);
 		g_object_set(ao_info->doclist, "sort-mode", ao_info->doclist_sort_mode, NULL);
@@ -418,6 +437,7 @@ static void ao_configure_response_cb(GtkDialog *dialog, gint response, gpointer
 	GtkWidget *check_bookmarklist, *check_markword, *frame_tasks, *vbox_tasks;
 	GtkWidget *check_tasks_scan_mode, *entry_tasks_tokens, *label_tasks_tokens, *tokens_hbox;
 	GtkWidget *check_blanklines, *check_xmltagging;
+	GtkWidget *check_wrapwords, *check_wrapwords_auto, *wrapwords_config_button, *wrapwords_hbox;
 
 	vbox = gtk_vbox_new(FALSE, 6);
 
@@ -537,6 +557,25 @@ static void ao_configure_response_cb(GtkDialog *dialog, gint response, gpointer
 		ao_info->enable_xmltagging);
 	gtk_box_pack_start(GTK_BOX(vbox), check_xmltagging, FALSE, FALSE, 3);
 
+	check_wrapwords = gtk_check_button_new_with_label(
+		_("Wrap selection on configurable keybindings"));
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_wrapwords),
+		ao_info->enable_wrapwords);
+
+	wrapwords_config_button = gtk_button_new_with_label ("Configure wrap pairs");
+	g_signal_connect(wrapwords_config_button, "clicked", G_CALLBACK(ao_wrapwords_config), dialog);
+	wrapwords_hbox = gtk_hbox_new(FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(wrapwords_hbox), check_wrapwords, FALSE, FALSE, 3);
+	gtk_box_pack_start(GTK_BOX(wrapwords_hbox), wrapwords_config_button, TRUE, TRUE, 3);
+	gtk_box_pack_start(GTK_BOX(vbox), wrapwords_hbox, FALSE, FALSE, 3);
+
+	check_wrapwords_auto = gtk_check_button_new_with_label(
+		_("Wrap selection automatically (without having to press a keybinding)"));
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_wrapwords_auto),
+		ao_info->enable_wrapwords_auto);
+	gtk_box_pack_start(GTK_BOX(vbox), check_wrapwords_auto, FALSE, FALSE, 3);
+
+
 	g_object_set_data(G_OBJECT(dialog), "check_doclist", check_doclist);
 	g_object_set_data(G_OBJECT(dialog), "radio_doclist_name", radio_doclist_name);
 	g_object_set_data(G_OBJECT(dialog), "radio_doclist_tab_order", radio_doclist_tab_order);
@@ -551,6 +590,9 @@ static void ao_configure_response_cb(GtkDialog *dialog, gint response, gpointer
 	g_object_set_data(G_OBJECT(dialog), "check_markword", check_markword);
 	g_object_set_data(G_OBJECT(dialog), "check_blanklines", check_blanklines);
 	g_object_set_data(G_OBJECT(dialog), "check_xmltagging", check_xmltagging);
+	g_object_set_data(G_OBJECT(dialog), "check_wrapwords", check_wrapwords);
+	g_object_set_data(G_OBJECT(dialog), "check_wrapwords_auto", check_wrapwords_auto);
+	g_object_set_data(G_OBJECT(dialog), "wrapwords_config_button", wrapwords_config_button);
 	g_signal_connect(dialog, "response", G_CALLBACK(ao_configure_response_cb), NULL);
 
 	ao_configure_tasks_toggled_cb(GTK_TOGGLE_BUTTON(check_tasks), dialog);
@@ -581,3 +623,4 @@ void plugin_cleanup(void)
 	g_free(ao_info->config_file);
 	g_free(ao_info);
 }
+


Modified: addons/src/ao_wrapwords.c
299 files changed, 299 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,299 @@
+/*
+ *			ao_wrapwords.c - this file is part of Addons, a Geany plugin
+ *
+ *			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 "geanyplugin.h"
+
+#include "addons.h"
+#include "ao_wrapwords.h"
+
+enum
+{
+	COLUMN_TITLE,
+	COLUMN_PRIOR_CHAR,
+	COLUMN_END_CHAR,
+	NUM_COLUMNS
+};
+
+void wrap_text_action (guint);
+gboolean on_key_press (GtkWidget *, GdkEventKey *, gpointer);
+void configure_response (GtkDialog *, gint, gpointer);
+void wrap_chars_changed (GtkCellRendererText *, gchar *, gchar *, gpointer);
+
+gchar *wrap_chars [8];
+gboolean auto_enabled = FALSE;
+gboolean wrap_enabled = FALSE;
+gchar *config_file;
+GtkListStore *chars_list;
+
+/*
+ * Called when a keybinding associated with the plugin is pressed.  Wraps the selected text in
+ * the characters associated with this keybinding.
+ */
+
+void wrap_text_action (guint key_id)
+{
+	if (!wrap_enabled)
+		return;
+
+	gint selection_end;
+	gchar insert_chars [2] = {0, 0};
+	ScintillaObject *sci_obj = document_get_current ()->editor->sci;
+
+	if (sci_get_selected_text_length (sci_obj) < 2)
+		return;
+
+	key_id -= 4;
+	selection_end = sci_get_selection_end (sci_obj);
+
+	sci_start_undo_action (sci_obj);
+	insert_chars [0] = *wrap_chars [key_id];
+	sci_insert_text (sci_obj, sci_get_selection_start (sci_obj), insert_chars);
+	insert_chars [0] = *(wrap_chars [key_id] + 1);
+	sci_insert_text (sci_obj, selection_end + 1, insert_chars);
+	sci_set_current_position (sci_obj, selection_end + 2, TRUE);
+	sci_end_undo_action (sci_obj);
+}
+
+/*
+ * Captures keypresses, if auto-wrapping automatically wraps selected text when certain
+ * characters are pressed.
+ */
+
+gboolean on_key_press (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
+{
+	gint selection_end;
+	gchar insert_chars [4] = {0, 0, 0, 0};
+	ScintillaObject *sci_obj;
+
+	if (!auto_enabled)
+		return FALSE;
+
+	sci_obj = document_get_current ()->editor->sci;
+
+	if (sci_get_selected_text_length (sci_obj) < 2)
+		return FALSE;
+
+	switch (event->keyval)
+	{
+		case '(':
+			insert_chars [0] = '(';
+			insert_chars [2] = ')';
+			break;
+		case '[':
+			insert_chars [0] = '[';
+			insert_chars [2] = ']';
+			break;
+		case '{':
+			insert_chars [0] = '{';
+			insert_chars [2] = '}';
+			break;
+		case '\'':
+			insert_chars [0] = '\'';
+			insert_chars [2] = '\'';
+			break;
+		case '\"':
+			insert_chars [0] = '\"';
+			insert_chars [2] = '\"';
+			break;
+        case '`':
+            insert_chars [0] = '`';
+            insert_chars [2] = '`';
+			break;
+		default:
+			return FALSE;
+	}
+
+	selection_end = sci_get_selection_end (sci_obj);
+
+	sci_start_undo_action (sci_obj);
+	sci_insert_text (sci_obj, sci_get_selection_start (sci_obj), insert_chars);
+	sci_insert_text (sci_obj, selection_end + 1, insert_chars+2);
+	sci_set_current_position (sci_obj, selection_end + 2, TRUE);
+	sci_end_undo_action (sci_obj);
+
+	return TRUE;
+}
+
+/*
+ * Loads the wrapping characters from the config file and sets keybindings.
+ */
+
+void ao_wrapwords_init (gchar *config_file_name, GeanyKeyGroup *key_group)
+{
+	GKeyFile *config = g_key_file_new();
+	gchar *key_name = g_malloc0 (6);
+	gint i;
+
+	config_file = g_strdup (config_file_name);
+	g_key_file_load_from_file(config, config_file, G_KEY_FILE_NONE, NULL);
+
+	g_stpcpy (key_name, "Wrap_x");
+
+	for (i = 0; i < 8; i++)
+	{
+		key_name [5] = (gchar) (i + '0');
+		wrap_chars [i] = utils_get_setting_string (config, "addons", key_name, "  ");
+		key_name [5] = (gchar) ((i + 1) + '0');
+		keybindings_set_item (key_group, i+4, (GeanyKeyCallback) wrap_text_action, 0, 0, key_name,
+			key_name, NULL);
+
+	}
+
+	plugin_signal_connect(geany_plugin, G_OBJECT(geany->main_widgets->window), "key-press-event",
+			FALSE, G_CALLBACK(on_key_press), NULL);
+
+	g_free (key_name);
+}
+
+void ao_wrapwords_set_enabled (gboolean enabled_w, gboolean enabled_a)
+{
+	auto_enabled = enabled_a;
+	wrap_enabled = enabled_w;
+}
+
+/*
+ * Called when the user closes the plugin preferences dialog.  If the user accepted or ok'd,
+ * update the array of wrapping characters and config file with the new wrapping characters
+ */
+
+void configure_response (GtkDialog *dialog, gint response, gpointer char_tree_view)
+{
+	GtkTreeIter char_iter;
+	GKeyFile *config = g_key_file_new();
+	gchar *config_data = NULL;
+	gchar *prior_char_str, *end_char_str;
+	gchar *key_name = g_malloc0 (6);
+	gint i;
+
+	if (response != GTK_RESPONSE_OK && response != GTK_RESPONSE_ACCEPT) {
+		g_free (key_name);
+		return;
+	}
+
+	gtk_tree_model_get_iter_first (GTK_TREE_MODEL(chars_list), &char_iter);
+
+	g_key_file_load_from_file(config, config_file, G_KEY_FILE_NONE, NULL);
+
+	g_stpcpy (key_name, "Wrap_x");
+
+	for (i = 0; i < 8; i++)
+	{
+		key_name [5] = (gchar) (i + '0');
+
+		gtk_tree_model_get (GTK_TREE_MODEL(chars_list), &char_iter,
+			COLUMN_PRIOR_CHAR, &prior_char_str, COLUMN_END_CHAR, &end_char_str, -1);
+		*wrap_chars [i] = prior_char_str [0];
+		*(wrap_chars [i] + 1) = end_char_str [0];
+		gtk_tree_model_iter_next (GTK_TREE_MODEL(chars_list), &char_iter);
+
+		g_key_file_set_string (config, "addons", key_name, wrap_chars [i]);
+	}
+
+	config_data = g_key_file_to_data (config, NULL, NULL);
+	utils_write_file (config_file, config_data);
+
+	g_free (prior_char_str);
+	g_free (end_char_str);
+	g_free (config_data);
+	g_free (key_name);
+	g_key_file_free(config);
+}
+
+/*
+ * When the user changes an entry in the preferences dialog, this updates the list of
+ * wrapping characters with the new entry
+ */
+
+void wrap_chars_changed (GtkCellRendererText *renderer, gchar *path, gchar *new_char_str,
+	gpointer column_num)
+{
+	GtkTreeIter chars_iter;
+	gchar new_chars [2] = {0, 0};
+	new_chars [0] = new_char_str [0];
+	gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (chars_list), &chars_iter, path);
+	gtk_list_store_set (chars_list, &chars_iter, GPOINTER_TO_INT (column_num), new_chars, -1);
+}
+
+/*
+ * Dialog box for setting wrap characters
+ */
+
+void ao_wrapwords_config (GtkButton *button, GtkWidget *config_window)
+{
+	GtkWidget *dialog;
+	GtkWidget *vbox;
+	GtkTreeIter chars_iter;
+	GtkCellRenderer *renderer;
+	GtkTreeViewColumn *label_column, *char_one_column, *char_two_column;
+	GtkTreeView *chars_tree_view;
+	gchar insert_chars [2] = {0, 0};
+	gchar *title;
+	gint i;
+
+	dialog = gtk_dialog_new_with_buttons(_("Plugins"), GTK_WINDOW(config_window),
+						GTK_DIALOG_DESTROY_WITH_PARENT, "Accept", GTK_RESPONSE_ACCEPT,
+						"Cancel", GTK_RESPONSE_CANCEL, "OK", GTK_RESPONSE_OK, NULL);
+
+	vbox = ui_dialog_vbox_new (GTK_DIALOG (dialog));
+	chars_list = gtk_list_store_new (NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+	renderer = gtk_cell_renderer_text_new ();
+	chars_tree_view = (GtkTreeView *) gtk_tree_view_new ();
+
+	for (i = 0; i < 8; i++)
+	{
+		gtk_list_store_append (chars_list, &chars_iter);
+		title = g_strdup_printf (_("Wrap combo %d"), i + 1);
+		gtk_list_store_set (chars_list, &chars_iter, COLUMN_TITLE, title, -1);
+		insert_chars [0] = *wrap_chars [i];
+		gtk_list_store_set (chars_list, &chars_iter, COLUMN_PRIOR_CHAR, insert_chars, -1);
+		insert_chars [0] = *(wrap_chars [i] + 1);
+		gtk_list_store_set (chars_list, &chars_iter, COLUMN_END_CHAR, insert_chars, -1);
+	}
+
+	label_column = gtk_tree_view_column_new_with_attributes ("", renderer, "text", 0, NULL);
+
+	renderer = gtk_cell_renderer_text_new ();
+	g_object_set (renderer, "editable", TRUE, NULL);
+	char_one_column = gtk_tree_view_column_new_with_attributes (_("Opening Character"), renderer,
+		"text", COLUMN_PRIOR_CHAR, NULL);
+	g_signal_connect (renderer, "edited", G_CALLBACK (wrap_chars_changed),
+		GINT_TO_POINTER (COLUMN_PRIOR_CHAR));
+
+	renderer = gtk_cell_renderer_text_new ();
+	g_object_set (renderer, "editable", TRUE, NULL);
+	char_two_column = gtk_tree_view_column_new_with_attributes (_("Closing Character"), renderer,
+		"text", COLUMN_END_CHAR, NULL);
+	g_signal_connect (renderer, "edited", G_CALLBACK (wrap_chars_changed),
+		GINT_TO_POINTER (COLUMN_END_CHAR));
+
+	gtk_tree_view_append_column (chars_tree_view, label_column);
+	gtk_tree_view_append_column (chars_tree_view, char_one_column);
+	gtk_tree_view_append_column (chars_tree_view, char_two_column);
+
+	gtk_tree_view_set_model (chars_tree_view, GTK_TREE_MODEL (chars_list));
+	gtk_box_pack_start(GTK_BOX(vbox), (GtkWidget *) chars_tree_view, FALSE, FALSE, 3);
+
+	gtk_widget_show_all (vbox);
+	g_signal_connect (dialog, "response", G_CALLBACK (configure_response), NULL);
+	while (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT);
+	gtk_widget_destroy (GTK_WIDGET (dialog));
+
+	g_free (title);
+}
+


Modified: addons/src/ao_wrapwords.h
29 files changed, 29 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,29 @@
+/*
+ *			ao_wrapwords.h - this file is part of Addons, a Geany plugin
+ *
+ *			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 __AO_WRAPWORDS_H__
+#define __AO_WRAPWORDS_H__
+
+
+void ao_wrapwords_init(gchar *, GeanyKeyGroup *);
+void ao_wrapwords_config(GtkButton *, GtkWidget *);
+void ao_wrapwords_set_enabled(gboolean, gboolean);
+
+#endif
+


Modified: po/POTFILES.in
2 files changed, 2 insertions(+), 0 deletions(-)
===================================================================
@@ -8,6 +8,7 @@ addons/src/ao_blanklines.c
 addons/src/ao_markword.c
 addons/src/ao_xmltagging.c
 addons/src/ao_openuri.c
+addons/src/ao_wrapwords.c
 addons/src/ao_doclist.c
 addons/src/addons.c
 
@@ -204,3 +205,4 @@ xmlsnippets/src/plugin.c
 xmlsnippets/src/xmlsnippets.c
 xmlsnippets/src/tests.c
 xmlsnippets/src/test-stubs.c
+



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: TBD).



More information about the Plugins-Commits mailing list