Branch: refs/heads/master Author: Alex M mam214@lehigh.edu Committer: Frank Lanitz frank@frank.uvena.de Date: Mon, 23 Jan 2012 08:38:24 Commit: e14283c7e0172043fe05e1038c65440ff6a48c89 https://github.com/geany/geany-plugins/commit/e14283c7e0172043fe05e1038c6544...
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).
plugins-commits@lists.geany.org